Skip to content

Commit

Permalink
Fix/various dproxy issues (#132)
Browse files Browse the repository at this point in the history
primitive dictionary now supports string types
nskeyedarchiver can now decode int64 values
nskeyedarchiver supports more classes:
- xcttestidentifier
- nsvalue
- DTTapStatusMessage
  • Loading branch information
danielpaulus authored Apr 24, 2022
1 parent d9adfb1 commit 4f33e4d
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 2 deletions.
16 changes: 15 additions & 1 deletion ios/dtx_codec/dtxprimitivedictionary.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ func (d PrimitiveDictionary) String() string {
result += fmt.Sprintf("{t:%s, v:%s},", toString(v), prettyString)
continue
}
if v == t_string{
result += d.values[i].(string)
}
if v == t_uint32 {
result += fmt.Sprintf("{t:%s, v:%d},", toString(v), d.values[i])
continue
Expand Down Expand Up @@ -184,9 +187,13 @@ func readEntry(auxBytes []byte) (uint32, interface{}, []byte) {
if readType == t_int64 {
return t_int64, binary.LittleEndian.Uint64(auxBytes[4:12]), auxBytes[12:]
}

if hasLength(readType) {
length := binary.LittleEndian.Uint32(auxBytes[4:])
data := auxBytes[8 : 8+length]
if readType==t_string{
return readType, string(data), auxBytes[8+length:]
}
return readType, data, auxBytes[8+length:]
}
panic(fmt.Sprintf("Unknown DtxPrimitiveDictionaryType: %d rawbytes:%x", readType, auxBytes))
Expand All @@ -206,6 +213,8 @@ func toString(t uint32) string {
return "null"
case t_bytearray:
return "binary"
case t_string:
return "string"
case t_uint32:
return "uint32"
case t_int64:
Expand All @@ -216,7 +225,7 @@ func toString(t uint32) string {
}

func hasLength(typeCode uint32) bool {
return typeCode == t_bytearray
return typeCode == t_bytearray || typeCode == t_string
}

type AuxiliaryEncoder struct {
Expand Down Expand Up @@ -245,6 +254,11 @@ func (a *AuxiliaryEncoder) writeEntry(entryType uint32, object interface{}) {
binary.Write(&a.buf, binary.LittleEndian, int32(len(object.([]byte))))
a.buf.Write(object.([]byte))

}
if entryType == t_string {
binary.Write(&a.buf, binary.LittleEndian, int32(len(object.([]byte))))
a.buf.Write([]byte(object.(string)))

}
panic(fmt.Sprintf("Unknown DtxPrimitiveDictionaryType: %d", entryType))

Expand Down
3 changes: 3 additions & 0 deletions ios/instruments/metrics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package instruments


51 changes: 51 additions & 0 deletions ios/nskeyedarchiver/archiver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,44 @@ func TestNSUUID(t *testing.T) {
log.Info(unarchivedObject)
}

func TestXCTestIdentifier(t *testing.T) {
nskeyedBytes, err := ioutil.ReadFile("fixtures/xctestidentifier.bin")

if err != nil {
log.Error(err)
t.Fatal()
}

unarchivedObject, err := archiver.Unarchive(nskeyedBytes)
assert.NoError(t, err)
log.Info(unarchivedObject)
}

func TestNSValue(t *testing.T) {
nskeyedBytes, err := ioutil.ReadFile("fixtures/nsvalue.bin")

if err != nil {
log.Error(err)
t.Fatal()
}
unarchivedObject, err := archiver.Unarchive(nskeyedBytes)
assert.NoError(t, err)
log.Info(unarchivedObject)
}

func TestWTF(t *testing.T) {
nskeyedBytes, err := ioutil.ReadFile("fixtures/int64-value-in-nskeyedarchive.bin")

if err != nil {
log.Error(err)
t.Fatal()
}

unarchivedObject, err := archiver.Unarchive(nskeyedBytes)
assert.NoError(t, err)
log.Info(unarchivedObject)
}

func TestXCActivityRecord(t *testing.T) {
nskeyedBytes, err := ioutil.ReadFile("fixtures/XCActivityRecord.bin")

Expand All @@ -96,6 +134,19 @@ func TestDTTapHeartbeatMessage(t *testing.T) {
log.Info(unarchivedObject)
}

func TestDTTapstatusmessage(t *testing.T) {
nskeyedBytes, err := ioutil.ReadFile("fixtures/dttapstatusmessage.bin")

if err != nil {
log.Error(err)
t.Fatal()
}

unarchivedObject, err := archiver.Unarchive(nskeyedBytes)
assert.NoError(t, err)
log.Info(unarchivedObject)
}

//TODO currently uint64 dicts are decoded by converting the keys to strings, might wanna fix this later
func TestIntKeyDictionary(t *testing.T) {

Expand Down
Binary file added ios/nskeyedarchiver/fixtures/dttapstatusmessage.bin
Binary file not shown.
Binary file not shown.
Binary file added ios/nskeyedarchiver/fixtures/nsvalue.bin
Binary file not shown.
Binary file added ios/nskeyedarchiver/fixtures/xctestidentifier.bin
Binary file not shown.
59 changes: 59 additions & 0 deletions ios/nskeyedarchiver/objectivec_classes.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ func SetupDecoders() {
"XCTCapabilities": NewXCTCapabilities,
"NSUUID": NewNSUUIDFromBytes,
"XCActivityRecord": DecodeXCActivityRecord,
"DTKTraceTapMessage": NewDTKTraceTapMessage,
"NSValue": NewNSValue,
"XCTTestIdentifier": NewXCTTestIdentifier,
"DTTapStatusMessage": NewDTTapStatusMessage,
}
}
}
Expand Down Expand Up @@ -249,6 +253,51 @@ func NewDTActivityTraceTapMessage(object map[string]interface{}, objects []inter
return DTActivityTraceTapMessage{DTTapMessagePlist: plist}
}

type DTKTraceTapMessage struct {
DTTapMessagePlist map[string]interface{}
}
func NewDTKTraceTapMessage(object map[string]interface{}, objects []interface{}) interface{} {
ref := object["DTTapMessagePlist"].(plist.UID)
plist, _ := extractDictionary(objects[ref].(map[string]interface{}), objects)
return DTKTraceTapMessage{DTTapMessagePlist: plist}
}


type NSValue struct {
NSSpecial uint64
NSRectval string
}
func NewNSValue(object map[string]interface{}, objects []interface{}) interface{} {
ref := object["NS.rectval"].(plist.UID)
rectval, _ := objects[ref].(string)
special := object["NS.special"].(uint64)
return NSValue{NSRectval: rectval, NSSpecial: special}
}

type XCTTestIdentifier struct {
O uint64
C []string
}

func (x XCTTestIdentifier) String() string{
return fmt.Sprintf("XCTTestIdentifier{o:%d , c:%v}", x.O, x.C)
}
func NewXCTTestIdentifier(object map[string]interface{}, objects []interface{}) interface{} {
ref := object["c"].(plist.UID)
//plist, _ := extractObjects(objects[ref].(map[string]interface{}), objects)
fd := objects[ref].(map[string] interface{})
extractObjects,_ := extractObjects(toUidList(fd[nsObjects].([]interface{})), objects)
stringarray := make([]string, len(extractObjects))
for i, v := range extractObjects{
stringarray[i] = v.(string)
}
o := object["o"].(uint64)
return XCTTestIdentifier{
O: o,
C: stringarray,
}
}

//TODO: make this nice, partially extracting objects is not really cool
type PartiallyExtractedXcTestConfig struct {
values map[string]interface{}
Expand Down Expand Up @@ -312,6 +361,16 @@ func NewDTTapHeartbeatMessage(object map[string]interface{}, objects []interface
return DTTapHeartbeatMessage{DTTapMessagePlist: plist}
}

type DTTapStatusMessage struct {
DTTapMessagePlist map[string]interface{}
}

func NewDTTapStatusMessage(object map[string]interface{}, objects []interface{}) interface{} {
ref := object["DTTapMessagePlist"].(plist.UID)
plist, _ := extractDictionary(objects[ref].(map[string]interface{}), objects)
return DTTapStatusMessage{DTTapMessagePlist: plist}
}

func NewNSDate(object map[string]interface{}, objects []interface{}) interface{} {
value := object["NS.time"].(float64)
milliesFloat := (1000*value + nsReferenceDate)
Expand Down
8 changes: 7 additions & 1 deletion ios/nskeyedarchiver/unarchiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ func extractObjects(objectRefs []plist.UID, objects []interface{}) ([]interface{
continue
}
//if this crashes, I forgot a primitive type
nonPrimitiveObjectRef := objectRef.(map[string]interface{})
nonPrimitiveObjectRef,ok := objectRef.(map[string]interface{})
if !ok{
return []interface{}{}, fmt.Errorf("object not a dictionary: %+v", objectRef)
}
if object, ok := isArrayObject(nonPrimitiveObjectRef, objects); ok {
extractObjects, err := extractObjects(toUidList(object[nsObjects].([]interface{})), objects)
if err != nil {
Expand Down Expand Up @@ -211,5 +214,8 @@ func isPrimitiveObject(object interface{}) (interface{}, bool) {
if v, ok := object.([]uint8); ok {
return v, ok
}
if v, ok := object.(int64); ok {
return v, ok
}
return object, false
}

0 comments on commit 4f33e4d

Please sign in to comment.