refactoring
This commit is contained in:
parent
61d5276b38
commit
a0156c7c23
@ -1,11 +1,3 @@
|
|||||||
import sys
|
|
||||||
import frida
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
APP_NAME = 'com.app.sample'
|
|
||||||
MODULE_NAME = 'libfoo.so'
|
|
||||||
|
|
||||||
|
|
||||||
def on_message(m, _data):
|
def on_message(m, _data):
|
||||||
if m['type'] == 'send':
|
if m['type'] == 'send':
|
||||||
print(m['payload'])
|
print(m['payload'])
|
||||||
@ -14,20 +6,55 @@ def on_message(m, _data):
|
|||||||
|
|
||||||
|
|
||||||
def switch(argument_key, idx):
|
def switch(argument_key, idx):
|
||||||
|
"""
|
||||||
|
# TODO handle other arguments, [long, longlong..]
|
||||||
|
:param argument_key: variable type
|
||||||
|
:param idx: index in symbols array
|
||||||
|
:return: javascript to read the type of variable
|
||||||
|
"""
|
||||||
argument_key = argument_key.replace(' ', '')
|
argument_key = argument_key.replace(' ', '')
|
||||||
return '%d: %s' % (idx, {
|
return '%d: %s' % (idx, {
|
||||||
'unsignedint': 'args[%d].toInt32(),',
|
|
||||||
'int': 'args[%d].toInt32(),',
|
'int': 'args[%d].toInt32(),',
|
||||||
|
'unsignedint': 'args[%d].toInt32(),',
|
||||||
'std::string': 'Memory.readUtf8String(Memory.readPointer(args[%d])),',
|
'std::string': 'Memory.readUtf8String(Memory.readPointer(args[%d])),',
|
||||||
'bool': 'Boolean(args[%d]),' # TODO handle other arguments, [long, longlong..]
|
'bool': 'Boolean(args[%d]),'
|
||||||
}[argument_key] % idx)
|
}[argument_key] % idx)
|
||||||
|
|
||||||
|
|
||||||
js_script = """
|
def main(app_id, module_id):
|
||||||
var moduleName = "{{moduleName}}",
|
import subprocess
|
||||||
|
output = subprocess.getoutput('nm --demangle --dynamic %s' % module_id)
|
||||||
|
|
||||||
|
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(',')
|
||||||
|
if len(argument_list) > 0: # ignore methods without arguments
|
||||||
|
symbols.append({
|
||||||
|
'address': split[0],
|
||||||
|
'type': split[1], # @see Symbol Type Table
|
||||||
|
'name': split[2][:split[2].index('(')], # method name
|
||||||
|
'args': argument_list
|
||||||
|
})
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
for idx, symbol in enumerate(symbols):
|
||||||
|
print("%4d) %s (%d)" % (idx, symbol['name'], 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'])
|
||||||
|
|
||||||
|
js_script = """
|
||||||
|
var moduleName = "{{moduleName}}",
|
||||||
nativeFuncAddr = {{methodAddress}};
|
nativeFuncAddr = {{methodAddress}};
|
||||||
|
|
||||||
Interceptor.attach(Module.findExportByName(null, "dlopen"), {
|
Interceptor.attach(Module.findExportByName(null, "dlopen"), {
|
||||||
onEnter: function(args) {
|
onEnter: function(args) {
|
||||||
this.lib = Memory.readUtf8String(args[0]);
|
this.lib = Memory.readUtf8String(args[0]);
|
||||||
console.log("[*] dlopen called with: " + this.lib);
|
console.log("[*] dlopen called with: " + this.lib);
|
||||||
@ -41,51 +68,41 @@ Interceptor.attach(Module.findExportByName(null, "dlopen"), {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
"""
|
"""
|
||||||
output = subprocess.getoutput('nm --demangle --dynamic %s' % MODULE_NAME)
|
replace_map = {
|
||||||
|
'{{moduleName}}': module_id,
|
||||||
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' + method['address'],
|
'{{methodAddress}}': '0x' + method['address'],
|
||||||
'{{arguments}}': '{' + ''.join([switch(method['args'][i], i + 1) for i in range(len(method['args']))]) + '}'
|
'{{arguments}}': '{' + ''.join([switch(method['args'][i], i + 1) for i in range(len(method['args']))]) + '}'
|
||||||
}.items():
|
}
|
||||||
|
for k, v in replace_map.items():
|
||||||
js_script = js_script.replace(k, v)
|
js_script = js_script.replace(k, v)
|
||||||
print('[+] JS Script:\n', js_script)
|
print('[+] JS Script:\n', js_script)
|
||||||
|
|
||||||
|
import frida
|
||||||
|
device = frida.get_usb_device()
|
||||||
|
pid = device.spawn([app_id])
|
||||||
|
session = device.attach(pid)
|
||||||
|
script = session.create_script(js_script)
|
||||||
|
script.on('message', on_message)
|
||||||
|
script.load()
|
||||||
|
device.resume(app_id)
|
||||||
|
|
||||||
|
import sys
|
||||||
|
sys.stdin.read()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import argparse
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('--app', help='app identifier "com.company.app"')
|
||||||
|
parser.add_argument('--module', help='loaded module name "libfoo.2.so"')
|
||||||
|
args = parser.parse_args()
|
||||||
|
main(args.app, args.module)
|
||||||
|
|
||||||
device = frida.get_usb_device()
|
|
||||||
pid = device.spawn([APP_NAME])
|
|
||||||
session = device.attach(pid)
|
|
||||||
script = session.create_script(js_script)
|
|
||||||
script.on('message', on_message)
|
|
||||||
script.load()
|
|
||||||
device.resume(APP_NAME)
|
|
||||||
sys.stdin.read()
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Symbol Type:
|
Symbol Type Table:
|
||||||
"A" The symbol's value is absolute, and will not be changed by further linking.
|
"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).
|
"B" The symbol is in the uninitialized data section (known as BSS).
|
||||||
"C" The symbol is common. Common symbols are uninitialized data.
|
"C" The symbol is common. Common symbols are uninitialized data.
|
||||||
|
Loading…
Reference in New Issue
Block a user