-
-
Save azliabdullah/5bf3d645b7d3fd4a9fc6632c51521d33 to your computer and use it in GitHub Desktop.
Revisions
-
dnaroma revised this gist
Apr 30, 2020 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,3 @@ This is the code rewritten in Python 3 from the original code of esterTion's [PHP version](https://gist.github.com/esterTion/768c646a83a089af9e5fbb83b77a59fc). **Only works with blobs from Android apk!!!** `genProto.py` for old versions, `genProto.py` for new versions with arm64 blobs. -
dnaroma revised this gist
Apr 30, 2020 . 1 changed file with 3 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1 +1,3 @@ This is the code rewritten in Python 3 from the original code of esterTion's [PHP version](https://gist.github.com/esterTion/768c646a83a089af9e5fbb83b77a59fc) `genProto.py` for old versions, `genProto.py` for new versions with arm64 blobs. -
dnaroma renamed this gist
Apr 30, 2020 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
dnaroma revised this gist
Mar 16, 2020 . 1 changed file with 137 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,137 @@ from struct import unpack import re import sys dumpcs = open('dump.cs', encoding="utf8").read() prog = open('libil2cpp.so', 'rb') definedClass = [] targetClass = sys.argv[1] #'SuiteMasterGetResponse' # change to get different classes outputPath = './{}.proto'.format(targetClass) outputFile = open(outputPath, 'w') # write first line outputFile.write('syntax = "proto2";\n') # outputFile.write('package bang;\n') typeMap = { 'uint': 'uint32', 'string': 'string', 'ulong': 'uint32', 'float': 'float', 'int': 'int32', 'double': 'double', 'bool': 'bool', 'long': 'int32' } def getTag(address): offset = address & 0xFFFFFFFF prog.seek(offset) inst = prog.read(4) inst = int.from_bytes(inst, byteorder='little', signed=False) if inst == 0xf9400408: prog.seek(offset + 4) inst = int.from_bytes(prog.read(4), 'little', signed=False) elif inst == 0xf81e0ff3: prog.seek(offset + 16) inst = int.from_bytes(prog.read(4), 'little', signed=False) else: print(hex(inst), hex(address)) return None if inst >> 24 == 0x52: return (inst >> 5) & 0xFFFF elif inst >> 24 == 0x32: retnum = (inst >> 8) & 0xFFFF immr = (retnum >> 8) & 0x3F imms = (retnum >> 2) & 0x3F clz = lambda x: "{:032b}".format(x).index("1") _len = 31 - clz((0 << 6) | (~imms & 0x3F)) _size = 1 << _len R = immr & (_size - 1) S = imms & (_size - 1) ret = (1 << (S+1)) - 1 for i in range(immr): ret = rotr(ret, 32) return ret def rotr(num, bits): num &= (2**bits-1) bit = num & 1 num >>= 1 if(bit): num |= (1 << (bits-1)) return num def writeMessage(target, message): outputFile.write('message {} {{\n'.format(target)) for item, info in message.items(): typ = info[0] if type(info[1]).__name__ == 'str': tag = getTag(int(info[1], 16)) else: tag = info[1] hint = info[2] comment = info[3] if hint == 'map': outputFile.write(' {}{} {} = {};\n'.format(hint, typ, item, tag)) else: outputFile.write(' {} {} {} = {};\n'.format(hint, typ, item, tag)) outputFile.write('}\n') def readClass(level, target): try: definedClass.index(target) shownClass = True except ValueError: definedClass.append(target) shownClass = False message = {} classDef = re.search('\[ProtoContractAttribute\].*?\n.*?class ' + target + ' [^\{\}]*?\{((.*\n)*?)?\s+(//\s+Properties(.*\n)*?)?\s+(//\s+Methods(.*\n)*?)?\}\s*?', dumpcs) if not classDef: print('{} not found'.format(target)) else: propList = re.findall('(\[ProtoMemberAttribute\] //.*Offset: 0x([0-9A-F]+).+?\n \w+ ([^\ \<]+(\<(.*?)\>)?) ([^\ ;]+))', classDef[0]) for prop in propList: typ = jumpTyp(level, prop[2], prop[5]) message[typ[0]] = [typ[1], prop[1], typ[2], typ[3]] if not shownClass: # print('{} \n'.format(target)) writeMessage(target, message) def jumpTyp(level, typ, name): if typ[-2:] == '[]': sub = jumpTyp(level + 2, typ[0:-2], 'entry') return [name, sub[1], 'repeated', 'array'] elif typ[0:10] == 'Dictionary': subType = re.search('<(\w+), (\w+)>', typ) readClass(level + 1, subType[2]) return [name, '<{}, {}>'.format(typeMap.get(subType[1], subType[1]), typeMap.get(subType[2], subType[2])), 'map', 'dictionary'] elif typ[0:4] == 'List': subType = re.search('<(\w+)>', typ) sub = jumpTyp(level + 1, subType[1], 'entry') return [name, sub[1], 'repeated', 'list'] elif typ[0:8] == 'Nullable': subType = re.search('<(\w+)>', typ) sub = jumpTyp(level, subType[1], name) sub[3] = 'nullable' return sub else: expectTyp = ['uint','string','ulong','float','int','double', 'bool','long'] try: expectTyp.index(typ) isType = True except ValueError: expectTyp.append(typ) isType = False if isType: return [name, typeMap[typ], 'optional', 'normal type'] else: readClass(level + 1, typ) return [name, typ, 'optional', 'sub class'] readClass(0, targetClass) -
DNARoma revised this gist
Apr 5, 2019 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -15,12 +15,12 @@ typeMap = { 'uint': 'uint32', 'string': 'string', 'ulong': 'uint64', 'float': 'float', 'int': 'int32', 'double': 'double', 'bool': 'bool', 'long': 'int64' } def getTag(address): -
DNARoma revised this gist
Mar 15, 2019 . 1 changed file with 22 additions and 48 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,7 +7,7 @@ definedClass = [] targetClass = sys.argv[1] #'SuiteMasterGetResponse' # change to get different classes outputPath = './{}.proto'.format(targetClass) outputFile = open(outputPath, 'w') # write first line outputFile.write('syntax = "proto2";\n') @@ -31,71 +31,45 @@ def getTag(address): inst = int.from_bytes(inst, byteorder='little', signed=False) if inst == 0xe5900004: #0x080440f9: prog.seek(offset + 4) retnum = int.from_bytes(prog.read(2), 'little', signed=False) rotate_flag = int.from_bytes(prog.read(1), 'little', signed=False) if rotate_flag == 0xA0: # rotate tag number rotate_num = (retnum >> 8) & 0xF tag = retnum & 0xFF for i in range(rotate_num * 2): tag = rotr(tag, 32) return tag return retnum & 0xfff elif inst == 0xe92d4c10: prog.seek(offset + 12) return int.from_bytes(prog.read(2), 'little', signed=False) & 0xfff else: print(hex(inst), hex(address)) def rotr(num, bits): num &= (2**bits-1) bit = num & 1 num >>= 1 if(bit): num |= (1 << (bits-1)) return num def writeMessage(target, message): outputFile.write('message {} {{\n'.format(target)) for item, info in message.items(): typ = info[0] if type(info[1]).__name__ == 'str': tag = getTag(int(info[1], 16)) else: tag = info[1] hint = info[2] comment = info[3] if hint == 'map': outputFile.write(' {}{} {} = {};\n'.format(hint, typ, item, tag)) else: outputFile.write(' {} {} {} = {};\n'.format(hint, typ, item, tag)) outputFile.write('}\n') def readClass(level, target): @@ -111,12 +85,12 @@ def readClass(level, target): if not classDef: print('{} not found'.format(target)) else: propList = re.findall('(\[ProtoMemberAttribute\] //.*Offset: 0x([0-9A-F]+)\n \w+ ([^\ \<]+(\<(.*?)\>)?) ([^\ ;]+))', classDef[0]) for prop in propList: typ = jumpTyp(level, prop[2], prop[5]) message[typ[0]] = [typ[1], prop[1], typ[2], typ[3]] if not shownClass: # print('{} \n'.format(target)) writeMessage(target, message) def jumpTyp(level, typ, name): -
DNARoma revised this gist
Oct 11, 2018 . 1 changed file with 5 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,12 +1,13 @@ from struct import unpack import re import sys dumpcs = open('dump.cs').read() prog = open('libil2cpp.so', 'rb') definedClass = [] targetClass = sys.argv[1] #'SuiteMasterGetResponse' # change to get different classes outputPath = './jp/{}.proto'.format(targetClass) outputFile = open(outputPath, 'w') # write first line outputFile.write('syntax = "proto2";\n') @@ -28,7 +29,7 @@ def getTag(address): prog.seek(offset) inst = prog.read(4) inst = int.from_bytes(inst, byteorder='little', signed=False) if inst == 0xe5900004: #0x080440f9: prog.seek(offset + 4) return int.from_bytes(prog.read(2), 'little', signed=False) & 0xfff elif inst == 0xe92d4c10: @@ -98,7 +99,6 @@ def writeMessage(target, message): outputFile.write('}\n') def readClass(level, target): try: definedClass.index(target) shownClass = True @@ -107,13 +107,12 @@ def readClass(level, target): shownClass = False message = {} classDef = re.search('\[ProtoContractAttribute\].*?\n.*?class ' + target + ' [^\{\}]*?\{((.*\n)*?)?\s+(//\s+Properties(.*\n)*?)?\s+(//\s+Methods(.*\n)*?)?\}\s*?', dumpcs) if not classDef: print('{} not found'.format(target)) else: propList = re.findall('(\[ProtoMemberAttribute\] // 0x([0-9A-F]+)\n \w+ ([^\ \<]+(\<(.*?)\>)?) ([^\ ;]+))', classDef[0]) for prop in propList: typ = jumpTyp(level, prop[2], prop[5]) message[typ[0]] = [typ[1], prop[1], typ[2], typ[3]] if not shownClass: -
dnaroma created this gist
Sep 15, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1 @@ This is the code rewritten in Python 3 from the original code of esterTion's [PHP version](https://gist.github.com/esterTion/768c646a83a089af9e5fbb83b77a59fc) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,170 @@ from struct import unpack import re dumpcs = open('dump.cs').read() prog = open('libil2cpp.so', 'rb') definedClass = [] targetClass = 'SuiteMasterGetResponse' # change to get different classes outputPath = './{}_gen.proto'.format(targetClass) outputFile = open(outputPath, 'w') # write first line outputFile.write('syntax = "proto2";\n') typeMap = { 'uint': 'uint32', 'string': 'string', 'ulong': 'uint32', 'float': 'float', 'int': 'int32', 'double': 'double', 'bool': 'bool', 'long': 'int32' } def getTag(address): offset = address & 0xFFFFFFFF prog.seek(offset) inst = prog.read(4) inst = int.from_bytes(inst, byteorder='little', signed=False) if inst == 0xe5900004: prog.seek(offset + 4) return int.from_bytes(prog.read(2), 'little', signed=False) & 0xfff elif inst == 0xe92d4c10: prog.seek(offset + 12) return int.from_bytes(prog.read(2), 'little', signed=False) & 0xfff else: print(hex(inst), hex(address)) return readInst(inst) def readInst(inst): chk = inst & 0x6f800000 if chk == 0x42800000: imme = (inst & 0x1fffe0) >> 5 dest = inst & 0x1f return imme elif chk == 0x22000000: N = (inst & 0x400000) != 0 immr = (inst & 0x3f0000) >> 16 imms = (inst & 0xfc00) >> 10 dest = inst & 0x1f if N: size = 64 else: size = 32 mask = 0x20 while size > 1: if (imms & mask) == 0: break size /= 2 mask /= 2 S = imms + 1 pattern = int((('1' * S).ljust(size, '0')) * (32 / size)) imme = rotate(pattern, immr) return imme else: print('Not found inst=' + inst) def rotate(pattern, rotate): result = pattern while rotate > 0: low = result & 1 result >>= 1 rotate -= 1 if low == 1: result |= 0x80000000 return result def writeMessage(target, message): outputFile.write('message {} {{\n'.format(target)) for item, info in message.items(): typ = info[0] if type(info[1]).__name__ == 'str': tag = getTag(int(info[1], 16)) if tag == 0xf4b: tag = 0x12c else: tag = info[1] hint = info[2] comment = info[3] if hint == 'map': outputFile.write(' {}{} {} = {}; // {}\n'.format(hint, typ, item, tag, comment)) else: outputFile.write(' {} {} {} = {}; // {}\n'.format(hint, typ, item, tag, comment)) outputFile.write('}\n') def readClass(level, target): print(target) try: definedClass.index(target) shownClass = True except ValueError: definedClass.append(target) shownClass = False message = {} classDef = re.search('class ' + target + ' [^\{\}]*?\{((.*\n)*?)?\s+(//\s+Properties(.*\n)*?)?\s+(//\s+Methods(.*\n)*?)?\}\s*?', dumpcs) if not classDef: print('{} not found'.format(target)) else: propList = re.findall('(\[ProtoMemberAttribute\] // 0x([0-9A-F]+)\n \w+ ([^\ \<]+(\<(.*?)\>)?) ([^\ ;]+))', classDef[0]) for prop in propList: print(prop) typ = jumpTyp(level, prop[2], prop[5]) message[typ[0]] = [typ[1], prop[1], typ[2], typ[3]] if not shownClass: print('{} \n'.format(target)) writeMessage(target, message) def jumpTyp(level, typ, name): if typ[-2:] == '[]': sub = jumpTyp(level + 2, typ[0:-2], 'entry') return [name, sub[1], 'repeated', 'array'] elif typ[0:11] == 'Dictionary`': subType = re.search('<(\w+), (\w+)>', typ) readClass(level + 1, subType[2]) # prefix = '{}_{}'.format(subType[1], subType[2]) # try: # definedClass.index(prefix) # shownClass = True # except ValueError: # definedClass.append(prefix) # shownClass = False # message = {} # sub = jumpTyp(level + 1, subType[1], '{}_key'.format(prefix)) # message[sub[0]] = [sub[1], 1, sub[2], sub[3]] # sub = jumpTyp(level + 1, subType[2], '{}_value'.format(prefix)) # message[sub[0]] = [sub[1], 2, sub[2], sub[3]] # if not shownClass: # writeMessage(prefix, message) return [name, '<{}, {}>'.format(typeMap.get(subType[1], subType[1]), typeMap.get(subType[2], subType[2])), 'map', 'dictionary'] elif typ[0:5] == 'List`': subType = re.search('<(\w+)>', typ) sub = jumpTyp(level + 1, subType[1], 'entry') return [name, sub[1], 'repeated', 'list'] elif typ[0:9] == 'Nullable`': subType = re.search('<(\w+)>', typ) sub = jumpTyp(level, subType[1], name) sub[3] = 'nullable' return sub else: expectTyp = ['uint','string','ulong','float','int','double', 'bool','long'] try: expectTyp.index(typ) isType = True except ValueError: expectTyp.append(typ) isType = False if isType: return [name, typeMap[typ], 'optional', 'normal type'] else: readClass(level + 1, typ) return [name, typ, 'optional', 'sub class'] readClass(0, targetClass)