diff --git a/print_native_method_arguments.py b/print_native_method_arguments.py index 5c028b4..aa8712e 100644 --- a/print_native_method_arguments.py +++ b/print_native_method_arguments.py @@ -1,10 +1,9 @@ -import frida import sys +import frida import subprocess +APP_NAME = 'com.app.sample' MODULE_NAME = 'libfoo.so' -FULL_METHOD_NAME = 'SomeCppClass::someMethod(' -APP_NAME = 'com.app.name' def on_message(m, _data): @@ -20,7 +19,7 @@ def switch(argument_key, idx): 'unsignedint': 'args[%d].toInt32(),', 'int': 'args[%d].toInt32(),', 'std::string': 'Memory.readUtf8String(Memory.readPointer(args[%d])),', - 'bool': 'Boolean(args[%d]),' + 'bool': 'Boolean(args[%d]),' # TODO handle other arguments, [long, longlong..] }[argument_key] % idx) @@ -44,15 +43,34 @@ Interceptor.attach(Module.findExportByName(null, "dlopen"), { } }); """ -output = subprocess.getoutput('nm --demangle --dynamic %s | grep "%s"' % (MODULE_NAME, FULL_METHOD_NAME)) -print('[+] nm output:', output) -# extract the arguments which are inside parenthesis in `nm -DC` stdout -method_args = re.search(r'\((.*?)\)', output).group(1).split(',') -print('[+] Method arguments:', method_args) +output = subprocess.getoutput('nm --demangle --dynamic %s' % MODULE_NAME) + +symbols = [] +for line in output.splitlines(): + try: + split = line.split() + raw_arguments = line[line.index('(') + 1:-1] + argument_list = [] if len(raw_arguments) is 0 else raw_arguments.split(',') + symbols.append({ + 'address': split[0], + 'type': split[1], + 'name': split[2][:split[2].index('(')], + 'args': argument_list + }) + except ValueError: + pass + +for idx, symbol in enumerate(symbols): + print("{}) {} ".format(idx, symbol['name'] + ' ' + str(len(symbol['args'])))) +selection_idx = input("Enter symbol number: ") +method = symbols[int(selection_idx)] +print('[+] Selected method: %s' % method['name']) +print('[+] Method arguments: %s' % method['args']) + for k, v in { '{{moduleName}}': MODULE_NAME, - '{{methodAddress}}': '0x' + output.split()[0], - '{{arguments}}': '{' + ''.join([switch(method_args[i], i + 1) for i in range(len(method_args))]) + '}' + '{{methodAddress}}': '0x' + method['address'], + '{{arguments}}': '{' + ''.join([switch(method['args'][i], i + 1) for i in range(len(method['args']))]) + '}' }.items(): js_script = js_script.replace(k, v) print('[+] JS Script:\n', js_script) @@ -66,5 +84,42 @@ script.load() device.resume(APP_NAME) sys.stdin.read() -# TODO if no arguments > print no arguments -# TODO handle other arguments, [long, longlong..] +""" +Symbol Type: + "A" The symbol's value is absolute, and will not be changed by further linking. + "B" The symbol is in the uninitialized data section (known as BSS). + "C" The symbol is common. Common symbols are uninitialized data. + When linking, multiple common symbols may appear with the same + name. If the symbol is defined anywhere, the common symbols + are treated as undefined references. + "D" The symbol is in the initialized data section. + "G" The symbol is in an initialized data section for small objects. + Some object file formats permit more efficient access to small + data objects, such as a global int variable as opposed to a + large global array. + "I" The symbol is an indirect reference to another symbol. + This is a GNU extension to the a.out object file format which is rarely used. + "N" The symbol is a debugging symbol. + "R" The symbol is in a read only data section. + "S" The symbol is in an uninitialized data section for small objects. + "T" The symbol is in the text (code) section. + "U" The symbol is undefined. + "V" The symbol is a weak object. When a weak defined symbol is + linked with a normal defined symbol, the normal defined symbol + is used with no error. When a weak undefined symbol is linked + and the symbol is not defined, the value of the weak symbol + becomes zero with no error. + "W" The symbol is a weak symbol that has not been specifically + tagged as a weak object symbol. When a weak defined symbol is + linked with a normal defined symbol, the normal defined symbol + is used with no error. When a weak undefined symbol is linked + and the symbol is not defined, the value of the symbol is + determined in a system-specific manner without error. On some + systems, uppercase indicates that a default value has been + specified. + "-" The symbol is a stabs symbol in an a.out object file. In this + case, the next values printed are the stabs other field, the + stabs desc field, and the stab type. Stabs symbols are used to + hold debugging information. + "?" The symbol type is unknown, or object file format specific. +"""