diff --git a/.gitignore b/.gitignore index 1187508..95fd390 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ cache/ config/ *.bak *.bak.js +*.dev diff --git a/README.md b/README.md index a21d00d..06190dc 100644 --- a/README.md +++ b/README.md @@ -36,8 +36,11 @@ By default, House binds to http://127.0.0.1:8000. To get an overview of House capabilities, you can visit [user's manual](https://github.com/nccgroup/house/wiki/Overview) for details. ## News -- House now runs on **python3**, as python2 will retire in 2019. -- Added Monitor tab, inspired by [Inspeckage](https://github.com/ac-pm/Inspeckage). +- Added dynamic dex/jar hooking, House now can hook functions in dynamically loaded dex/jar files +![hook.gif](./gifs/dyload.gif) +- Added Mini Script option for Hooks +![hook.gif](./gifs/dyload_mini.gif) +- ClassLoader Enum ## Example Usage @@ -89,6 +92,12 @@ following command: `frida-ps -U`. - *Scripts rendering and Function Tracing* ![hook.gif](./gifs/hook.gif) +- *Hooks for functions in dynamically loaded dex/jar files* + ![hook.gif](./gifs/dyload.gif) + +- *Mini Script option* + ![hook.gif](./gifs/dyload_mini.gif) + - *History Scripts management* ![hook_history_script.gif](./gifs/hook_history_script.gif) diff --git a/app.py b/app.py index ec46227..b2a24c8 100644 --- a/app.py +++ b/app.py @@ -124,7 +124,6 @@ def hook(): class_name = str(request.form.get('classname')) method_name = str(request.form.get('methodname')) if (method_name != 'None') & (class_name != 'None'): - # TODO: use jinja to render script dynamically hook_dict = {"classname": class_name, "methodname": method_name} house_global.hooks_list.append(hook_dict) update_conf() diff --git a/gifs/dyload.gif b/gifs/dyload.gif new file mode 100644 index 0000000..78989d7 Binary files /dev/null and b/gifs/dyload.gif differ diff --git a/gifs/dyload_mini.gif b/gifs/dyload_mini.gif new file mode 100644 index 0000000..8d23914 Binary files /dev/null and b/gifs/dyload_mini.gif differ diff --git a/houseStatic.py b/houseStatic.py index c223c24..00685d5 100644 --- a/houseStatic.py +++ b/houseStatic.py @@ -21,6 +21,7 @@ # SOFTWARE. import colored +from enum import Enum from colored import stylize import frida @@ -40,4 +41,9 @@ linebreak = "h0us3l1nebr3ak" codeblock = "h0us3bl0ck" -delimiter = "h4oar3ud0ing" \ No newline at end of file +delimiter = "h4oar3ud0ing" + +class dynamicHookOption(Enum): + only_new = "new" + only_existing = "existing" + both = "all" \ No newline at end of file diff --git a/houseUtil.py b/houseUtil.py index e02eb4a..bc18c06 100644 --- a/houseUtil.py +++ b/houseUtil.py @@ -21,32 +21,35 @@ # SOFTWARE. from houseStatic import * -from houseGlobal import house_global,socketio, random_token +from houseGlobal import house_global, socketio, random_token # from plugin import log_r_value # from houseGlobal import env_html, enum_html, intercepts_html, preload_html, hooks_html, monitor_html from _frida import ProcessNotFoundError import traceback, IPython + def init_conf(): if not (os.path.exists('config')): os.makedirs('./config') if not (os.path.isfile("./config/hook_conf.json")): - with open("./config/hook_conf.json",'w') as f: + with open("./config/hook_conf.json", 'w') as f: f.write('{"packagename": "", "hooks_list": []}') if not (os.path.isfile("./config/enum_conf.json")): - with open("./config/enum_conf.json",'w') as f: + with open("./config/enum_conf.json", 'w') as f: f.write('{"packagename": "", "enum_option": "", "class_pattern": "", "class_to_find": ""}') if not (os.path.isfile("./config/intercept_conf.json")): - with open("./config/intercept_conf.json",'w') as f: + with open("./config/intercept_conf.json", 'w') as f: f.write('{"classname": "", "packagename": "", "methodname": "", "overloadIndex": 0}') if not (os.path.isfile("./config/env_conf.json")): - with open("./config/env_conf.json",'w') as f: - f.write('{"filesDirectory": "", "cacheDirectory": "", "externalCacheDirectory": "", "codeCacheDirectory": "", "packageCodePath": ""}') + with open("./config/env_conf.json", 'w') as f: + f.write( + '{"filesDirectory": "", "cacheDirectory": "", "externalCacheDirectory": "", "codeCacheDirectory": "", "packageCodePath": ""}') if not (os.path.isfile("./config/monitor_conf.json")): - with open("./config/monitor_conf.json",'w') as f: - f.write('{"SWITCH_FILEIO": 0, "SWITCH_HTTP": 0, "SWITCH_MISC": 0, "SWITCH_WEBVIEW": 0, "SWITCH_SQL": 0, "SWITCH_IPC": 0}') + with open("./config/monitor_conf.json", 'w') as f: + f.write( + '{"SWITCH_FILEIO": 0, "SWITCH_HTTP": 0, "SWITCH_MISC": 0, "SWITCH_WEBVIEW": 0, "SWITCH_SQL": 0, "SWITCH_IPC": 0}') if not (os.path.isfile("./config/preload_conf.json")): - with open("./config/preload_conf.json",'w') as f: + with open("./config/preload_conf.json", 'w') as f: f.write('{"PRELOAD_STETHO": 0, "PRELOAD_SSLSTRIP": 1, "PRELOAD_SETPROXY": 0}') @@ -63,26 +66,25 @@ def init_cache(): os.makedirs('./cache/log') if not (os.path.isfile("./cache/current/enum_script.js")): - with open('./cache/current/enum_script.js','w') as f: + with open('./cache/current/enum_script.js', 'w') as f: f.write('') if not (os.path.isfile("./cache/current/hook_script.js")): - with open('./cache/current/hook_script.js','w') as f: + with open('./cache/current/hook_script.js', 'w') as f: f.write('') if not (os.path.isfile("./cache/log/message.json")): - with open("./cache/log/message.json",'w') as f: + with open("./cache/log/message.json", 'w') as f: f.write('') if not (os.path.isfile("./cache/log/monitor.json")): - with open("./cache/log/monitor.json",'w') as f: + with open("./cache/log/monitor.json", 'w') as f: f.write('') - - def make_tree(path, option): tree = dict(name=os.path.basename(path), children=[]) - try: lst = os.listdir(path) + try: + lst = os.listdir(path) except OSError: - pass #ignore errors + pass # ignore errors else: for name in lst: fn = os.path.join(path, name) @@ -91,7 +93,7 @@ def make_tree(path, option): def get_apk_path(): - with open("./config/env_conf.json",'r') as f: + with open("./config/env_conf.json", 'r') as f: house_global.env_conf = f.read() try: j_env_conf = json.loads(house_global.env_conf) @@ -100,8 +102,9 @@ def get_apk_path(): return None raise e + def get_application_name(): - with open("./config/env_conf.json",'r') as f: + with open("./config/env_conf.json", 'r') as f: house_global.env_conf = f.read() try: j_env_conf = json.loads(house_global.env_conf) @@ -110,6 +113,7 @@ def get_application_name(): return None raise e + def update_conf(): house_global.hook_conf["packagename"] = house_global.packagename @@ -120,22 +124,23 @@ def update_conf(): house_global.enum_conf["enum_option"] = house_global.enum_option house_global.hook_conf['hooks_list'] = house_global.hooks_list - with open('./config/hook_conf.json','w') as f: + with open('./config/hook_conf.json', 'w') as f: # IPython.embed() f.write(json.dumps(house_global.hook_conf)) - with open('./config/enum_conf.json','w') as f: + with open('./config/enum_conf.json', 'w') as f: f.write(json.dumps(house_global.enum_conf)) - with open('./config/intercept_conf.json','w') as f: + with open('./config/intercept_conf.json', 'w') as f: # print stylize("[+] Updating intercept_conf with {}".format(json.dumps(house_global.inspect_conf)),Info) f.write(json.dumps(house_global.inspect_conf)) - with open('./config/monitor_conf.json','w') as f: + with open('./config/monitor_conf.json', 'w') as f: f.write(json.dumps(house_global.monitor_conf)) - with open('./config/preload_conf.json','w') as f: + with open('./config/preload_conf.json', 'w') as f: f.write(json.dumps(house_global.preload_conf)) + def init_settings(): try: house_global.packagename = house_global.hook_conf["packagename"] @@ -144,71 +149,78 @@ def init_settings(): except Exception as e: pass + def cache_script(option, script): if option == "enum_cache": - with open('./cache/current/enum_script.js','w') as f: + with open('./cache/current/enum_script.js', 'w') as f: f.write(script) elif option == "env_cache": - with open('./cache/current/env_script.js','w') as f: + with open('./cache/current/env_script.js', 'w') as f: f.write(script) elif option == "hooks_cache": - with open('./cache/current/hook_script.js','w') as f: + with open('./cache/current/hook_script.js', 'w') as f: f.write(script) elif option == "hooks_cache_mini": - with open('./cache/current/hook_script_mini.js','w') as f: + with open('./cache/current/hook_script_mini.js', 'w') as f: f.write(script) elif option == "intercept_cache": - with open('./cache/current/intercept_script.js','w') as f: + with open('./cache/current/intercept_script.js', 'w') as f: f.write(script) elif option == "monitor_cache": - with open('./cache/current/monitor_script.js','w') as f: + with open('./cache/current/monitor_script.js', 'w') as f: f.write(script) elif option == "preload_cache": - with open('./cache/current/preload_script.js','w') as f: + with open('./cache/current/preload_script.js', 'w') as f: f.write(script) else: - print (stylize("[!] Invalid cache script type", Error)) + print(stylize("[!] Invalid cache script type", Error)) + def clear_hook_msg(): house_global.messages = [] socketio.emit("clear_hook_msg") + def cache_inspect_html(): - with open('./config/inspect_cache.html','w') as f: + with open('./config/inspect_cache.html', 'w') as f: f.write(house_global.inspect_result) + def checkok(): if (house_global.packagename != "") & (house_global.hooks_list != []): return True else: return False + def getPackage(): return house_global.hook_conf['packagename'] + def setPackage(pkgname): house_global.packagename = pkgname house_global.inspect_conf["classname"] = "" house_global.inspect_conf["methodname"] = "" house_global.inspect_conf["overloadIndex"] = 0 - with open('./config/inspect_cache.html','w') as f: + with open('./config/inspect_cache.html', 'w') as f: f.write(" ") update_conf() - + + def setDevice(id): house_global.device = house_global.device_manager.get_device(id) - print (stylize("[+]Changing Device with id {}".format(id), MightBeImportant)) + print(stylize("[+]Changing Device with id {}".format(id), MightBeImportant)) try: socketio.emit('show_selected_device', - {'device_list': json.dumps(house_global.device_dict), 'selection': str(house_global.device.id)}, - namespace='/eventBus') + {'device_list': json.dumps(house_global.device_dict), 'selection': str(house_global.device.id)}, + namespace='/eventBus') except Exception as e: raise e - + def getDevice(): try: - print (stylize("[+] Trying to get device..", Info)) + print(stylize("[+] Trying to get device..", Info)) house_global.device_dict = {} house_global.device_manager = frida.get_device_manager() device_list = house_global.device_manager.enumerate_devices() @@ -219,52 +231,54 @@ def getDevice(): remote_device_list.append(dv) if len(remote_device_list) == 1: house_global.device = remote_device_list[0] - socketio.emit('update_device', - {'data': cgi.escape(str(house_global.device))}, - namespace='/eventBus') + socketio.emit('update_device', + {'data': cgi.escape(str(house_global.device))}, + namespace='/eventBus') elif len(remote_device_list) > 1: for dv in remote_device_list: house_global.device_dict[str(dv.id)] = str(dv) # Interact with user to select device if house_global.device == None: socketio.emit('select_device', - {'device_list': json.dumps(house_global.device_dict)}, - namespace='/eventBus') + {'device_list': json.dumps(house_global.device_dict)}, + namespace='/eventBus') else: socketio.emit('show_selected_device', - {'device_list': json.dumps(house_global.device_dict), 'selection': str(house_global.device.id)}, - namespace='/eventBus') + {'device_list': json.dumps(house_global.device_dict), + 'selection': str(house_global.device.id)}, + namespace='/eventBus') else: raise Exception("No device Found!") # return str(house_global.device) except Exception as e: house_global.device = None - socketio.emit('update_device', - {'data': cgi.escape(str(house_global.device))}, - namespace='/eventBus') - print (stylize(str(e), Error)) + socketio.emit('update_device', + {'data': cgi.escape(str(house_global.device))}, + namespace='/eventBus') + print(stylize(str(e), Error)) # raise e -def onMonitorMessage(message,data): + +def onMonitorMessage(message, data): house_global.onMessageException = '' if message['type'] == 'send': - if(message.get('payload') != None): + if (message.get('payload') != None): monitor_log = str(message.get('payload')) # monitor_log = u''.join(monitor_log).encode('utf-8').strip() else: monitor_log = "No message payload.." elif message['type'] == 'error': - if(message.get('description') != None): + if (message.get('description') != None): house_global.onMessageException = cgi.escape(message.get('description')) else: house_global.onMessageException = 'No description' - print (stylize("[!]Monitor Error: {}".format(house_global.onMessageException), Error)) + print(stylize("[!]Monitor Error: {}".format(house_global.onMessageException), Error)) socketio.emit('new_error_message', - {'data': "[!] {}".format(house_global.onMessageException)}, - namespace='/eventBus') + {'data': "[!] {}".format(house_global.onMessageException)}, + namespace='/eventBus') monitor_log = message.get('payload') if message.get('payload') else '' - + j_monitor_log = json.loads(monitor_log) mon_type = j_monitor_log.get("monitor_type") @@ -272,71 +286,71 @@ def onMonitorMessage(message,data): method = j_monitor_log.get("method_info") retval = j_monitor_log.get("retval_dump") if args != None: - args = cgi.escape(args).replace(linebreak,'
') + args = cgi.escape(args).replace(linebreak, '
') if method != None: - method = cgi.escape(method).replace(linebreak,'
') + method = cgi.escape(method).replace(linebreak, '
') if retval != None: - retval = cgi.escape(retval).replace(linebreak,'
') - monitor_entry = {"methodname":method,"args":args,"retval":retval} + retval = cgi.escape(retval).replace(linebreak, '
') + monitor_entry = {"methodname": method, "args": args, "retval": retval} # "types" : ["fileIO", "HTTP", "WEBVIEW", "SQL", "IPC", "MISC", "IGNORE"] if (mon_type != None) & (mon_type != "IGNORE"): if mon_type == "fileIO": - house_global.monitor_message['FILEIO'].insert(0,monitor_entry) + house_global.monitor_message['FILEIO'].insert(0, monitor_entry) elif mon_type == "SHAREDPREFERENCES": - house_global.monitor_message['SHAREDPREFERENCES'].insert(0,monitor_entry) + house_global.monitor_message['SHAREDPREFERENCES'].insert(0, monitor_entry) elif mon_type == "HTTP": - house_global.monitor_message['HTTP'].insert(0,monitor_entry) + house_global.monitor_message['HTTP'].insert(0, monitor_entry) elif mon_type == "WEBVIEW": - house_global.monitor_message['WEBVIEW'].insert(0,monitor_entry) + house_global.monitor_message['WEBVIEW'].insert(0, monitor_entry) elif mon_type == "SQL": - house_global.monitor_message['SQL'].insert(0,monitor_entry) + house_global.monitor_message['SQL'].insert(0, monitor_entry) elif mon_type == "IPC": - house_global.monitor_message['IPC'].insert(0,monitor_entry) - else: # misc + house_global.monitor_message['IPC'].insert(0, monitor_entry) + else: # misc mon_type = "MISC" - house_global.monitor_message['MISC'].insert(0,monitor_entry) + house_global.monitor_message['MISC'].insert(0, monitor_entry) # socketio.emit('update_monitor_message', {'mon_type': mon_type.upper(), 'monitor_message': house_global.monitor_message},namespace='/eventBus') house_global.monitor_queue.add(mon_type.upper()) -def onMessage(message,data): +def onMessage(message, data): house_global.onMessageException = '' if message['type'] == 'send': - if(message.get('payload') != None): + if (message.get('payload') != None): info = str(message.get('payload')) # info = str(u''.join(info).encode('utf-8').strip()) else: info = "No message payload.." elif message['type'] == 'error': - if(message.get('description') != None): + if (message.get('description') != None): house_global.onMessageException = cgi.escape(message.get('description')) else: house_global.onMessageException = 'No description' - print (stylize("[!]Error: {}".format(house_global.onMessageException), Error)) + print(stylize("[!]Error: {}".format(house_global.onMessageException), Error)) socketio.emit('new_error_message', - {'data': "[!] {}".format(house_global.onMessageException)}, - namespace='/eventBus') + {'data': "[!] {}".format(house_global.onMessageException)}, + namespace='/eventBus') info = message.get('payload') if message.get('payload') else '' # IPython.embed() if "t3llm3mor3ab0ut1t" in info: - env_info = info.replace("t3llm3mor3ab0ut1t",'') + env_info = info.replace("t3llm3mor3ab0ut1t", '') # print (env_info) # IPython.embed() j_env_info = json.loads(env_info) if j_env_info.get("packageCodePath") != None: - with open("./config/env_conf.json",'w') as f: - json.dump(j_env_info,f) + with open("./config/env_conf.json", 'w') as f: + json.dump(j_env_info, f) socketio.emit('update_env_info', - {'data': env_info}, - namespace='/eventBus') + {'data': env_info}, + namespace='/eventBus') # env stuff if "-hoo00ook-" in info: - info = info.replace("-hoo00ook-",'') - + info = info.replace("-hoo00ook-", '') + j_info = json.loads(info) args = j_info.get("arg_dump") method = j_info.get("method_info") @@ -344,29 +358,29 @@ def onMessage(message,data): # special_instruction = j_info.get("special_inst") # experimental if args != None: - args = cgi.escape(args).replace(linebreak,'
') + args = cgi.escape(args).replace(linebreak, '
') if method != None: - method = cgi.escape(method).replace(linebreak,'
') + method = cgi.escape(method).replace(linebreak, '
') if retval != None: - retval = cgi.escape(retval).replace(linebreak,'
') + retval = cgi.escape(retval).replace(linebreak, '
') - info_dict = {"methodname":method,"args":args,"retval":retval} + info_dict = {"methodname": method, "args": args, "retval": retval} - house_global.messages.insert(0,info_dict) + house_global.messages.insert(0, info_dict) # if special_instruction != None: # experimental # log_r_value(special_instruction) socketio.emit('new_hook_message', - {'data': json.dumps(info_dict)}, - namespace='/eventBus') + {'data': json.dumps(info_dict)}, + namespace='/eventBus') if "-enumMmMmMmMm-" in info: - enum_msg = info.replace('undefined','').replace("-enumMmMmMmMm-",'') + enum_msg = info.replace('undefined', '').replace("-enumMmMmMmMm-", '') house_global.enum_messages.insert(0, enum_msg) - socketio.emit("update_enum_messages",namespace='/eventBus') + socketio.emit("update_enum_messages", namespace='/eventBus') if "-t1m3f0rm1tm-" in info: - intercept_msg = info.replace("-t1m3f0rm1tm-",'') + intercept_msg = info.replace("-t1m3f0rm1tm-", '') if "-what1sth3t1m3n0w-" in intercept_msg: house_global.new_intercept_msg = intercept_msg.split("-what1sth3t1m3n0w-")[0] @@ -374,10 +388,12 @@ def onMessage(message,data): else: house_global.new_intercept_msg = intercept_msg - socketio.emit('new_intercept', {'data': house_global.new_intercept_msg, 'time': house_global.new_intercept_time}, namespace='/eventBus') + socketio.emit('new_intercept', + {'data': house_global.new_intercept_msg, 'time': house_global.new_intercept_time}, + namespace='/eventBus') if "-whatisth1smeth0d-" in info: - inspect_info = info.replace("-whatisth1smeth0d-",'') + inspect_info = info.replace("-whatisth1smeth0d-", '') j_inspect = json.loads(inspect_info) overload_info = j_inspect['methodInfo'] @@ -387,9 +403,10 @@ def onMessage(message,data): inspect_class_name = house_global.inspect_conf["classname"] inspect_method_name = house_global.inspect_conf["methodname"] html_output = "" - + if overload_count > 1: - html_output = "

{}

".format(cgi.escape(inspect_class_name) + '.' + cgi.escape(inspect_method_name)) + html_output = "

{}

".format( + cgi.escape(inspect_class_name) + '.' + cgi.escape(inspect_method_name)) html_output += """
@@ -400,7 +417,7 @@ def onMessage(message,data): for i in range(0, overload_count): html_output += """ - """.format(str(i),cgi.escape(str(json.dumps(overload_info[i]))).replace("\\\"","")) + """.format(str(i), cgi.escape(str(json.dumps(overload_info[i]))).replace("\\\"", "")) html_output += """ @@ -429,17 +446,17 @@ def onMessage(message,data): house_global.inspect_result = html_output cache_inspect_html() - update_inspect_result = {'classname': house_global.inspect_conf["classname"], 'methodname' : house_global.inspect_conf["methodname"], 'inspect_result': house_global.inspect_result} + update_inspect_result = {'classname': house_global.inspect_conf["classname"], + 'methodname': house_global.inspect_conf["methodname"], + 'inspect_result': house_global.inspect_result} socketio.emit('update_inspect_result', update_inspect_result, namespace='/eventBus') - if "-can1hav3ash3ll-" in info: - house_global.new_repl_msg = info.replace("-can1hav3ash3ll-",'') + house_global.new_repl_msg = info.replace("-can1hav3ash3ll-", '') socketio.emit('new_repl', {'data': house_global.new_repl_msg, 'time': house_global.new_repl_time}, - namespace='/eventBus') + namespace='/eventBus') - def render(tpl_path, context): path, filename = os.path.split(tpl_path) @@ -447,69 +464,95 @@ def render(tpl_path, context): loader=jinja2.FileSystemLoader(path or './') ).get_template(filename).render(context) -def prepare_script_fragment(clazz_name, method_name,script_type,overloadIndex=0,overload_type=None,instruction=None): + +def prepare_script_fragment(clazz_name, method_name, script_type, overloadIndex=0, overload_type=None, + instruction=None, is_dynamic=False): context = { - 'clazz_name' : '', - 'method_name' : '', - 'clazz_hook' : '', - 'method_hook' : '', - 'overloadIndex' : str(overloadIndex), - 'overload_type' : overload_type, - 'instruction' : '' + 'clazz_name': '', + 'method_name': '', + 'clazz_hook': '', + 'method_hook': '', + 'overloadIndex': str(overloadIndex), + 'overload_type': overload_type, + 'instruction': '', + 'is_dynamic' : is_dynamic } - if(clazz_name != None) & (clazz_name != '') & (method_name != None) & (method_name != ''): + if (clazz_name != None) & (clazz_name != '') & (method_name != None) & (method_name != ''): context['clazz_name'] = clazz_name context['method_name'] = method_name context['clazz_hook'] = str(clazz_name.split('.')[-1]) + '_hook' - context['method_hook'] = str(method_name.replace('.','_')) + '_hook' + context['method_hook'] = str(method_name.replace('.', '_')) + '_hook' if script_type == "inspect": - result = render('./scripts/intercept/inspect.js',context) + result = render('./scripts/intercept/inspect.js', context) elif script_type == "intercept": - result = render('./scripts/intercept/intercept.js',context) + result = render('./scripts/intercept/intercept.js', context) elif script_type == "hookmini": - result = render('./scripts/hook/hook_mini_frag.js',context) + result = render('./scripts/hook/hook_mini_frag.js', context) else: - result = render('./scripts/hook/hook_frag.js',context) + result = render('./scripts/hook/hook_frag.js', context) return result else: - print (stylize("[!]prepare_script_fragment Error with {} - {} - {} ".format(clazz_name, method_name,script_type),Error)) + print( + stylize("[!]prepare_script_fragment Error with {} - {} - {} ".format(clazz_name, method_name, script_type), + Error)) return '' -def prepare_monitor_fragment(clazz_name, method_name, monitor_type='misc', instruction = None): + +def prepare_monitor_fragment(clazz_name, method_name, monitor_type='misc', instruction=None): context = { - 'clazz_name' : '', - 'method_name' : '', - 'clazz_hook' : '', - 'method_hook' : '', - 'monitor_type': '', - 'instruction' : instruction + 'clazz_name': '', + 'method_name': '', + 'clazz_hook': '', + 'method_hook': '', + 'monitor_type': '', + 'instruction': instruction } result = '' - if(clazz_name != None) & (clazz_name != '') & (method_name != None) & (method_name != ''): + if (clazz_name != None) & (clazz_name != '') & (method_name != None) & (method_name != ''): context['clazz_name'] = clazz_name context['method_name'] = method_name context['clazz_hook'] = str(clazz_name.split('.')[-1]) + '_hook' - context['method_hook'] = str(method_name.replace('.','_')) + '_hook' + context['method_hook'] = str(method_name.replace('.', '_')) + '_hook' context['monitor_type'] = monitor_type - result = render('./scripts/monitor/monitor_frag.js',context) + result = render('./scripts/monitor/monitor_frag.js', context) return result def prepare_native_script_fragment(so_name, method_name): context = { - 'so_name' : '', - 'method_name' : '', + 'so_name': '', + 'method_name': '', } - if(so_name != None) & (so_name != '') & (method_name != None) & (method_name != ''): + if (so_name != None) & (so_name != '') & (method_name != None) & (method_name != ''): context['so_name'] = so_name context['method_name'] = method_name - result = render('./scripts/hook/native_hook_frag.js',context) + result = render('./scripts/hook/native_hook_frag.js', context) return result else: - print (stylize("[!]prepare_native_script_fragment Error with {} - {} ".format(so_name, method_name),Error)) + print(stylize("[!]prepare_native_script_fragment Error with {} - {} ".format(so_name, method_name), Error)) return '' +def build_dyload_script(dy_dic, is_mini = False): + # dy_dic: {dyload_path: [[clazz_name, method_name, overload_type, instruction, dyload_loadClassFlag]]} + hook_frag_script = "" + dyload_script = "" + for dyload_path, target_array in dy_dic.items(): + for target in target_array: + clazz_name = target[0] + method_name = target[1] + overload_type = target[2] + instruction = target[3] + # dynamicHookOption = True + dynamicHookOption = target[4] + + hook_frag_script += prepare_script_fragment(clazz_name, method_name, ("hookmini" if is_mini else "hook"), overload_type=overload_type, is_dynamic = True) + context = {'dyload_path': dyload_path, 'hook_frag_script': hook_frag_script, 'dynamicHookOption': dynamicHookOption} + if not is_mini: + dyload_script += render(("scripts/hook/hook_dyload_frag.js"), context) + else: + dyload_script += render(("scripts/hook/hook_dyload_frag_mini.js"), context) + return dyload_script def refresh(): with open('./templates/env.html') as f: @@ -524,56 +567,83 @@ def refresh(): preload_html = f.read() with open('./templates/monitor.html') as f: monitor_html = f.read() - return render_template('index.html', uuid=str(random_token), env = env_html, enum = enum_html, hooks = hooks_html, intercepts = intercepts_html, preload = preload_html, monitor = monitor_html); + return render_template('index.html', uuid=str(random_token), env=env_html, enum=enum_html, hooks=hooks_html, + intercepts=intercepts_html, preload=preload_html, monitor=monitor_html) + def build_hook_script(): hooks_list = house_global.hook_conf['hooks_list'] - hooks_number = len(hooks_list) - - realscript = "" + basicscript = "" nativescript = "" + dy_dic = {} + dyloadscript = "" - # for i in xrange(hooks_number): for entry in hooks_list: - # entry = hooks_list[i] clazz_name = entry['classname'] method_name = entry['methodname'] overload_type = entry.get('overload_type') instruction = entry.get('instruction') + dyload_path = entry.get('dyload_path') + dynamicHookOption = entry.get('dynamicHookOption') # IPython.embed() - if ".so" not in clazz_name: - realscript += prepare_script_fragment(clazz_name, method_name, "hook", overload_type = overload_type) - else: + if ".so" in clazz_name: nativescript += prepare_native_script_fragment(clazz_name, method_name) - context = {'scripts': realscript, 'native_scripts': nativescript} + elif dyload_path is not None: + d = dy_dic.get(dyload_path) + if d == None: + dy_dic[dyload_path] = [[clazz_name, method_name, overload_type, instruction, dynamicHookOption]] + elif type(d) == list: + dy_dic[dyload_path].append([clazz_name, method_name, overload_type, instruction, dynamicHookOption]) + else: + raise ValueError("dy_dic[dyload_path] is not a list!") + + else: + basicscript += prepare_script_fragment(clazz_name, method_name, "hook", overload_type=overload_type) + + if len(dy_dic) > 0: + dyloadscript = build_dyload_script(dy_dic) - result = render('./scripts/hook/hook_tpl.js',context) + context = {'scripts': basicscript, 'native_scripts': nativescript, "dyloadscript": dyloadscript} + # print(context) + result = render('./scripts/hook/hook_tpl.js', context) house_global.hook_script = result cache_script("hooks_cache", house_global.hook_script) + def build_hook_mini_script(): hooks_list = house_global.hook_conf['hooks_list'] - hooks_number = len(hooks_list) - - realscript = "" + basicscript = "" nativescript = "" + dyloadscript = "" + dy_dic = {} - # for i in xrange(hooks_number): for entry in hooks_list: # entry = hooks_list[i] clazz_name = entry['classname'] method_name = entry['methodname'] overload_type = entry.get('overload_type') instruction = entry.get('instruction') - # IPython.embed() - if ".so" not in clazz_name: - realscript += prepare_script_fragment(clazz_name, method_name, "hookmini", overload_type = overload_type) - else: + dyload_path = entry.get('dyload_path') + dynamicHookOption = entry.get('dynamicHookOption') + if ".so" in clazz_name: nativescript += prepare_native_script_fragment(clazz_name, method_name) - context = {'scripts': realscript, 'native_scripts': nativescript} + elif dyload_path is not None: + d = dy_dic.get(dyload_path) + if d == None: + dy_dic[dyload_path] = [[clazz_name, method_name, overload_type, instruction, dynamicHookOption]] + elif type(d) == list: + dy_dic[dyload_path].append([clazz_name, method_name, overload_type, instruction, dynamicHookOption]) + else: + raise ValueError("dy_dic[dyload_path] is not a list!") + else: + # java hook + basicscript += prepare_script_fragment(clazz_name, method_name, "hookmini", overload_type=overload_type) + if len(dy_dic) > 0: + dyloadscript = build_dyload_script(dy_dic, is_mini= True) + context = {'scripts': basicscript, 'native_scripts': nativescript, 'dyloadscript': dyloadscript} - result = render('./scripts/hook/hook_tpl_mini.js',context) + result = render('./scripts/hook/hook_tpl_mini.js', context) house_global.hook_script_mini = result cache_script("hooks_cache_mini", house_global.hook_script_mini) @@ -587,6 +657,7 @@ def build_env_script(): cache_script("env_cache", result) return result + def build_monitor_script(): with open("./scripts/monitor/monitor_hook.json") as monitor_list_conf: monitor_list_conf_rd = monitor_list_conf.read() @@ -603,9 +674,8 @@ def build_monitor_script(): render_monitor_list.append(file_monitor_list_entry) except Exception as e: raise e - + monitorscript_fragment = "" - for render_monitor_list_entry in render_monitor_list: clazz_name = render_monitor_list_entry['classname'] @@ -613,20 +683,22 @@ def build_monitor_script(): monitor_type = render_monitor_list_entry['type'] instruction = render_monitor_list_entry.get('instruction') - monitorscript_fragment += prepare_monitor_fragment(clazz_name, method_name,monitor_type, instruction) + monitorscript_fragment += prepare_monitor_fragment(clazz_name, method_name, monitor_type, instruction) context = {'scripts': monitorscript_fragment} - result = render('./scripts/monitor/monitor_tpl.js',context) + result = render('./scripts/monitor/monitor_tpl.js', context) house_global.monitor_script = result cache_script("monitor_cache", house_global.monitor_script) + def build_enum_script(option, class_to_find, class_pattern): if (class_to_find != None) & (".so" in class_to_find) & (option == "enumClassMethods"): option = "enumLibSo" - context = {'option': option, 'class_to_find': class_to_find, 'class_pattern': class_pattern, 'apk_path': get_apk_path()} + context = {'option': option, 'class_to_find': class_to_find, 'class_pattern': class_pattern, + 'apk_path': get_apk_path()} - result = render('./scripts/enum/enum_skl.js',context) + result = render('./scripts/enum/enum_skl.js', context) house_global.enum_script_to_load = result @@ -637,16 +709,16 @@ def preload_stetho_script(): # IPython.embed() unload_script("stetho") try: - print (stylize("[!] Have to reload to preload, trying to spawn it..", MightBeImportant)) + print(stylize("[!] Have to reload to preload, trying to spawn it..", MightBeImportant)) pid = house_global.device.spawn([house_global.packagename]) house_global.session = house_global.device.attach(pid) pending = True if get_application_name() == None: - print (stylize("[!] What is the application name? Try refresh House", Error)) + print(stylize("[!] What is the application name? Try refresh House", Error)) return else: - jscode = render('./scripts/misc/sideload_stetho.js',{"application_name":get_application_name()}) + jscode = render('./scripts/misc/sideload_stetho.js', {"application_name": get_application_name()}) process = house_global.device.attach(house_global.packagename) house_global.stetho_script_object = process.create_script(jscode) print('[*] Running Stetho') @@ -655,18 +727,19 @@ def preload_stetho_script(): # print (stylize('[+] Loading the new script..{} {}'.format(str(house_global.device), str(house_global.packagename)), Info)) - if pending: + if pending: # IPython.embed() house_global.device.resume(pid) except Exception as e: - print (stylize("[!]sideload_script Exception: {}".format(str(e)), Error)) + print(stylize("[!]sideload_script Exception: {}".format(str(e)), Error)) traceback.print_exc(file=sys.stdout) raise e - + else: - print (stylize('[!]Please tell me what you want!', Error)) + print(stylize('[!]Please tell me what you want!', Error)) raise Exception(" Failed to load script") + def run_preload_script(): global Info getDevice() @@ -679,19 +752,19 @@ def run_preload_script(): "PRELOAD_SSLSTRIP": "", "PRELOAD_SETPROXY": "" } - if (house_global.preload_conf.get('PRELOAD_STETHO') == 1):preload_context['PRELOAD_STETHO'] = 'yes' - if (house_global.preload_conf.get('PRELOAD_SSLSTRIP') == 1):preload_context['PRELOAD_SSLSTRIP'] = 'yes' - if (house_global.preload_conf.get('PRELOAD_SETPROXY') == 1):preload_context['PRELOAD_SETPROXY'] = 'yes' + if (house_global.preload_conf.get('PRELOAD_STETHO') == 1): preload_context['PRELOAD_STETHO'] = 'yes' + if (house_global.preload_conf.get('PRELOAD_SSLSTRIP') == 1): preload_context['PRELOAD_SSLSTRIP'] = 'yes' + if (house_global.preload_conf.get('PRELOAD_SETPROXY') == 1): preload_context['PRELOAD_SETPROXY'] = 'yes' try: if (house_global.preload_conf.get('PRELOAD_STETHO') == 1): - print (stylize("[!] Have to reload to preload, trying to spawn it..", MightBeImportant)) + print(stylize("[!] Have to reload to preload, trying to spawn it..", MightBeImportant)) pid = house_global.device.spawn([house_global.packagename]) house_global.session = house_global.device.attach(pid) pending = True else: - print (stylize("[!] No need to reload..", MightBeImportant)) + print(stylize("[!] No need to reload..", MightBeImportant)) try: pid = house_global.device.get_process(house_global.packagename).pid house_global.session = house_global.device.attach(house_global.packagename) @@ -702,11 +775,11 @@ def run_preload_script(): pending = True if get_application_name() == None: - print (stylize("[!] What is the application name? Try refresh House", Error)) + print(stylize("[!] What is the application name? Try refresh House", Error)) return else: preload_context['application_name'] = get_application_name() - house_global.preload_script = render('./scripts/misc/preload.js',preload_context) + house_global.preload_script = render('./scripts/misc/preload.js', preload_context) print(preload_context) cache_script("preload_cache", house_global.preload_script) process = house_global.device.attach(house_global.packagename) @@ -717,96 +790,100 @@ def run_preload_script(): # print (stylize('[+] Loading the new script..{} {}'.format(str(house_global.device), str(house_global.packagename)), Info)) - if pending: + if pending: # IPython.embed() house_global.device.resume(pid) except Exception as e: - print (stylize("[!]run_preload_script Exception: {}".format(str(e)), Error)) + print(stylize("[!]run_preload_script Exception: {}".format(str(e)), Error)) traceback.print_exc(file=sys.stdout) raise e - + else: - print (stylize('[!]Please tell me what you want!', Error)) + print(stylize('[!]Please tell me what you want!', Error)) raise Exception(" Failed to load script") + def on_spawned(spawn): print('on_spawned:', spawn) if spawn.identifier is not None and spawn.identifier.startswith('xxx'): print('Instrumenting:', spawn) house_global.session = house_global.device.attach(spawn.pid) - + house_global.script = house_global.session.create_script(house_global.script_to_load) - # IPython.embed() - - house_global.script.on('message',onMessage) + # IPython.embed() + + house_global.script.on('message', onMessage) house_global.script.load() # print (stylize('[+] Loading the new script..{} {}'.format(str(house_global.device), str(house_global.packagename)), Info)) house_global.device.resume(spawn.pid) # print('Processed:', spawn) + def load_script(): global Info getDevice() if ((house_global.script_to_load != '') & (house_global.packagename != '') & (house_global.device != None)): - + unload_script() + print("Loading script...") try: pending = False - try: + try: pid = house_global.device.get_process(house_global.packagename).pid house_global.session = house_global.device.attach(house_global.packagename) except ProcessNotFoundError as e: - if(house_global.gating_option): + if (house_global.gating_option): house_global.device.enable_spawn_gating() - print (stylize("[!] Process not found, trying spawn-gating it..", MightBeImportant)) + print(stylize("[!] Process not found, trying spawn-gating it..", MightBeImportant)) house_global.device.on('spawn-added', on_spawned) return else: - print (stylize("[!] Process not found, trying to spawn it..", MightBeImportant)) + print(stylize("[!] Process not found, trying to spawn it..", MightBeImportant)) pid = house_global.device.spawn([house_global.packagename]) house_global.session = house_global.device.attach(pid) pending = True house_global.script = house_global.session.create_script(house_global.script_to_load) # IPython.embed() - - house_global.script.on('message',onMessage) + + house_global.script.on('message', onMessage) house_global.script.load() # print (stylize('[+] Loading the new script..{} {}'.format(str(house_global.device), str(house_global.packagename)), Info)) - if pending: + if pending: # IPython.embed() house_global.device.resume(pid) except Exception as e: - print (stylize("[!]load_script Exception: {}".format(str(e)), Error)) + print(stylize("[!]load_script Exception: {}".format(str(e)), Error)) traceback.print_exc(file=sys.stdout) raise e - + else: - print (stylize('[!]Please tell me what you want!', Error)) + print(stylize('[!]Please tell me what you want!', Error)) raise Exception(" Failed to load script") + def loadMonitor(): global Info getDevice() try: unload_script("monitor") except Exception as e: - print (stylize(str(e), MightBeImportant)) - - print (stylize("[!]Trying to load monitor script..", Info)) + print(stylize(str(e), MightBeImportant)) + + print(stylize("[!]Trying to load monitor script..", Info)) build_monitor_script() if ((house_global.monitor_script != '') & (house_global.packagename != '') & (house_global.device != None)): try: pending = False - try: + try: pid = house_global.device.get_process(house_global.packagename).pid house_global.session = house_global.device.attach(house_global.packagename) except ProcessNotFoundError as e: - print (stylize("[!] Process not found, trying to spawn it..", MightBeImportant)) + print(stylize("[!] Process not found, trying to spawn it..", MightBeImportant)) pid = house_global.device.spawn([house_global.packagename]) house_global.session = house_global.device.attach(pid) pending = True @@ -814,32 +891,32 @@ def loadMonitor(): house_global.monitor_script_object = house_global.session.create_script(house_global.monitor_script) # print house_global.monitor_script # IPython.embed() - - house_global.monitor_script_object.on('message',onMonitorMessage) + + house_global.monitor_script_object.on('message', onMonitorMessage) house_global.monitor_script_object.load() - print (stylize('[+] Loading the monitor script..{} {}'.format(str(house_global.device), str(house_global.packagename)), Info)) + print(stylize( + '[+] Loading the monitor script..{} {}'.format(str(house_global.device), str(house_global.packagename)), + Info)) - if pending: + if pending: # IPython.embed() house_global.device.resume(pid) except Exception as e: - print (stylize("[!]loadMonitor Exception: {}".format(str(e)), Error)) + print(stylize("[!]loadMonitor Exception: {}".format(str(e)), Error)) traceback.print_exc(file=sys.stdout) raise e - def quitRepl(): if (house_global.script): house_global.script.post({'type': 'input', 'payload': 'exit', 'option': "terminate"}) else: - print (stylize("No repl to terminate", MightBeImportant)) + print(stylize("No repl to terminate", MightBeImportant)) -def unload_script(type = "main"): - if(house_global.session): - +def unload_script(type="main"): + if (house_global.session): try: - print (stylize('[-] Unload the ' + type + ' script..', Info)) + print(stylize('[-] Unload the ' + type + ' script..', Info)) if type == "stetho": house_global.stetho_script_object.unload() elif type == "monitor": @@ -852,8 +929,6 @@ def unload_script(type = "main"): house_global.script.unload() # house_global.session.detach() except Exception as e: - print (stylize('[!] unload_script: looks like {}'.format(str(e)), MightBeImportant)) + print(stylize('[!] unload_script: looks like {}'.format(str(e)), MightBeImportant)) else: - print (stylize("[-] No script exists", MightBeImportant)) - - + print(stylize("[-] No script exists", MightBeImportant)) diff --git a/scripts/enum/enum_skl.js b/scripts/enum/enum_skl.js index 27efd25..32d66bb 100644 --- a/scripts/enum/enum_skl.js +++ b/scripts/enum/enum_skl.js @@ -5,7 +5,6 @@ function enumAllClasses() { classes.forEach(function(aClass) { try { - // var className = aClass.match(/[L](.*);/)[1].replace(/\//g, "."); var className = aClass.replace(/\//g, "."); } catch (err) {} allClasses.push(className); @@ -14,6 +13,17 @@ function enumAllClasses() { return allClasses; } +function enumClassLoaders(){ + var allClassLoaders = [] + var classLoaders = Java.enumerateClassLoadersSync() + + classLoaders.forEach(function(cl) { + allClassLoaders.push(cl); + }); + + return allClassLoaders; +} + function enumDexClasses(apk_path) { BaseDexClassLoader = Java.use("dalvik.system.BaseDexClassLoader"); DexFile = Java.use("dalvik.system.DexFile"); @@ -57,16 +67,7 @@ function enumLibSo(lib_name){ for(i=0; i
`); - setTimeout(function() { $("#err_msg").empty() }, 20000) + setTimeout(function () { + $("#err_msg").empty() + }, 20000) unload_script() } @@ -213,7 +235,7 @@ function clear_hookMessage() { function clear_monitorMessage(type) { $("#" + type + 'monitorBody').empty(); clear_notification(type.toUpperCase()) - socket.emit("clear_monitorMessage", { "monitor_type": type }) + socket.emit("clear_monitorMessage", {"monitor_type": type}) } @@ -273,7 +295,7 @@ function getTime() { return x } -window.onload = function() { +window.onload = function () { function getMessages() { $.get('http://' + location.host + '/messages', (data) => { data = JSON.parse(data); @@ -308,13 +330,13 @@ window.onload = function() { console.log("Exception : " + data.exception) } else { // $("#filemonitorOutput").empty(); - FILEIO_message.forEach(addMonitorMessages, { type: "FILEIO" }); - SHAREDPREFERENCES_message.forEach(addMonitorMessages, { type: "SHAREDPREFERENCES" }); - HTTP_message.forEach(addMonitorMessages, { type: "HTTP" }); - MISC_message.forEach(addMonitorMessages, { type: "MISC" }); - IPC_message.forEach(addMonitorMessages, { type: "IPC" }); - WEBVIEW_message.forEach(addMonitorMessages, { type: "WEBVIEW" }); - SQL_message.forEach(addMonitorMessages, { type: "SQL" }); + FILEIO_message.forEach(addMonitorMessages, {type: "FILEIO"}); + SHAREDPREFERENCES_message.forEach(addMonitorMessages, {type: "SHAREDPREFERENCES"}); + HTTP_message.forEach(addMonitorMessages, {type: "HTTP"}); + MISC_message.forEach(addMonitorMessages, {type: "MISC"}); + IPC_message.forEach(addMonitorMessages, {type: "IPC"}); + WEBVIEW_message.forEach(addMonitorMessages, {type: "WEBVIEW"}); + SQL_message.forEach(addMonitorMessages, {type: "SQL"}); } }) } @@ -338,13 +360,13 @@ window.onload = function() { console.log("Exception : " + data.exception) } else { clear_monitorUI() - FILEIO_message.forEach(addMonitorMessages, { type: "FILEIO" }); - SHAREDPREFERENCES_message.forEach(addMonitorMessages, { type: "SHAREDPREFERENCES" }); - HTTP_message.forEach(addMonitorMessages, { type: "HTTP" }); - MISC_message.forEach(addMonitorMessages, { type: "MISC" }); - IPC_message.forEach(addMonitorMessages, { type: "IPC" }); - WEBVIEW_message.forEach(addMonitorMessages, { type: "WEBVIEW" }); - SQL_message.forEach(addMonitorMessages, { type: "SQL" }); + FILEIO_message.forEach(addMonitorMessages, {type: "FILEIO"}); + SHAREDPREFERENCES_message.forEach(addMonitorMessages, {type: "SHAREDPREFERENCES"}); + HTTP_message.forEach(addMonitorMessages, {type: "HTTP"}); + MISC_message.forEach(addMonitorMessages, {type: "MISC"}); + IPC_message.forEach(addMonitorMessages, {type: "IPC"}); + WEBVIEW_message.forEach(addMonitorMessages, {type: "WEBVIEW"}); + SQL_message.forEach(addMonitorMessages, {type: "SQL"}); } } @@ -564,7 +586,7 @@ window.onload = function() { $(() => { - socket.emit('authentication', { uuid: get_uuid() }); + socket.emit('authentication', {uuid: get_uuid()}); var current_intercept_time = null refresh_device() getPackages() @@ -584,11 +606,11 @@ window.onload = function() { socket.emit('fetchInspect'); // socket.emit('check_monitor_running'); - socket.on('log', function(msg) { + socket.on('log', function (msg) { console.log(("[+]Log: " + msg.data)) }); - socket.on('monitor_running_status', function(msg) { + socket.on('monitor_running_status', function (msg) { if (msg.running == 1) { $("#monitor_running").text("Running"); } else { @@ -596,30 +618,29 @@ window.onload = function() { } }); - socket.on('select_device', function(msg) { + socket.on('select_device', function (msg) { dl = msg.device_list; select_device_html = '
' if (dl != null && dl != "None") { json_dl = JSON.parse(dl) - jQuery.each(json_dl, function(id, val) { + jQuery.each(json_dl, function (id, val) { select_device_html += `
" }); select_device_html += `
` $("#device_info_tab").html(select_device_html) - console.log(select_device_html) } }); - socket.on('show_selected_device', function(msg) { + socket.on('show_selected_device', function (msg) { dl = msg.device_list; id = msg.selection select_device_html = '
' if (dl != null && dl != "None") { json_dl = JSON.parse(dl) - jQuery.each(json_dl, function(id, val) { + jQuery.each(json_dl, function (id, val) { select_device_html += `
" }); @@ -633,7 +654,7 @@ window.onload = function() { }); - socket.on('update_device', function(msg) { + socket.on('update_device', function (msg) { device = msg.data; if (device != null && device != "None") { device_html = `
@@ -649,30 +670,30 @@ window.onload = function() { }) - socket.on('update_package', function(msg) { + socket.on('update_package', function (msg) { getPackages() doEnv() }) - socket.on('update_env_info', function(msg) { + socket.on('update_env_info', function (msg) { if (msg.error) { $("#env_result").html("" + msg.error + "
") } else { j_data = JSON.parse(msg.data) var result = "" - jQuery.each(j_data, function(i, val) { + jQuery.each(j_data, function (i, val) { result += i + " : " + "" + val + "
" }); $("#env_result").html(result) } }); - socket.on('update_enum_messages', function() { + socket.on('update_enum_messages', function () { getEnumMessages(); }); - socket.on('new_hook_message', function(msg) { + socket.on('new_hook_message', function (msg) { getMessages() }); @@ -683,13 +704,17 @@ window.onload = function() { // // getMonitorMessages() // }); - socket.on('update_monitor_message', function(msg) { + socket.on('update_monitor_message', function (msg) { // $('#NOTI_' + msg.mon_type).text("New"); // console.log(msg.monitor_new.length) if (msg.monitor_new.length != 0) { // lazy refreshing for (i in msg.monitor_new) { - if (msg.monitor_new[i] == null) { break; } else { $('#NOTI_' + msg.monitor_new[i]).text("New"); } + if (msg.monitor_new[i] == null) { + break; + } else { + $('#NOTI_' + msg.monitor_new[i]).text("New"); + } } monitor_messages = msg.monitor_message; renderMonitorMessages(monitor_messages) @@ -699,13 +724,12 @@ window.onload = function() { }); - - socket.on('new_intercept', function(msg) { + socket.on('new_intercept', function (msg) { editor5.setValue(msg.data) current_intercept_time = msg.time }); - socket.on('new_repl', function(msg) { + socket.on('new_repl', function (msg) { try { j_eval_packet = JSON.parse(msg.data) eval_display = "[" + j_eval_packet.eval_time + "]" + '\n-> ' + j_eval_packet.eval_input + '\n' + j_eval_packet.eval_output + '\n' @@ -717,22 +741,22 @@ window.onload = function() { } }); - socket.on('update_hooks', function() { + socket.on('update_hooks', function () { getHookConfig() getHookScript() // overwrite() }); - socket.on('update_hooks_mini', function() { + socket.on('update_hooks_mini', function () { getHookConfig() getHookScriptMini() }); - - socket.on('clear_hook_msg', function() { + + socket.on('clear_hook_msg', function () { clear_hookMessage() }); - socket.on('refresh_history_script', function(msg) { + socket.on('refresh_history_script', function (msg) { switch (msg.option) { case "enum": get_enum_history() @@ -749,19 +773,19 @@ window.onload = function() { } }); - socket.on('update_enum_history', function(msg) { + socket.on('update_enum_history', function (msg) { $("#dir_enum_lst").html(msg.data) }); - socket.on('update_hooks_history', function(msg) { + socket.on('update_hooks_history', function (msg) { $("#dir_hooks_lst").html(msg.data) }); - socket.on('update_intercept_history', function(msg) { + socket.on('update_intercept_history', function (msg) { $("#dir_int_lst").html(msg.data) }); - socket.on('update_script_content', function(msg) { + socket.on('update_script_content', function (msg) { switch (msg.option) { case "enum": editor_enum_history.setValue(msg.script); @@ -779,7 +803,7 @@ window.onload = function() { // editor_hook_history.setValue(msg.script) }); - socket.on('update_inspect_result', function(msg) { + socket.on('update_inspect_result', function (msg) { $("#inspect_classname").val(msg.classname) $("#inspect_method").val(msg.methodname) $("#inspect_result").html(msg.inspect_result) @@ -789,16 +813,16 @@ window.onload = function() { } }); - socket.on('update_intercept_script', function(msg) { + socket.on('update_intercept_script', function (msg) { intercepts_script_editor.setValue(msg.script) }); - socket.on('new_error_message', function(msg) { + socket.on('new_error_message', function (msg) { push_err_msg(msg.data); }); - socket.on('EnumConfigDone', function() { + socket.on('EnumConfigDone', function () { $.get('http://' + location.host + '/enum_script', (data) => { editor3.setValue(data); }) @@ -814,7 +838,7 @@ window.onload = function() { }) $("#find_class").click(() => { - var enum_config = { class_to_find: $("#class_to_find").val(), option: 'enumClassMethods' } + var enum_config = {class_to_find: $("#class_to_find").val(), option: 'enumClassMethods'} socket.emit("setEnumConfig", enum_config) }) @@ -834,9 +858,8 @@ window.onload = function() { }) - $("#postPackage").click(() => { - var pkg = { packagename: $("#packagename").val() } + var pkg = {packagename: $("#packagename").val()} postPackage(pkg) location.reload(); }) @@ -850,12 +873,29 @@ window.onload = function() { }) $("#add_hook").click(() => { - var hook_message = { classname: $("#classname").val(), methodname: $("#method").val(), overload_type: $("#overload_type").val() } + var dyload_path = $("#dyload_path").val() + var hook_message = {} + if (dyload_path == "") { + hook_message = { + classname: $("#classname").val(), + methodname: $("#method").val(), + overload_type: $("#overload_type").val() + } + } else { + hook_message = { + dyload_path : dyload_path, + classname: $("#classname").val(), + methodname: $("#method").val(), + overload_type: $("#overload_type").val(), + dynamicHookOption: "new" + } + } + $("#classname").val('') $("#method").val('') $("#overload_type").val('') + $("#dyload_path").val('') appendLn(editor, JSON.stringify(hook_message)) - }) $("#hook_clear").click(() => { @@ -871,13 +911,12 @@ window.onload = function() { $("#gen_script").click(() => { var hooks_data = editor.getValue().split('\n') - var hooks_list = { hooks_list: [] } + var hooks_list = {hooks_list: []} for (var index = 0; index < hooks_data.length; index++) { try { var hook_val = JSON.parse(hooks_data[index]) hooks_list.hooks_list.push(hook_val) - } catch (e) { console.log("Is this JSON: " + hooks_data[index]) } @@ -887,28 +926,26 @@ window.onload = function() { $("#gen_script_mini").click(() => { var hooks_data = editor.getValue().split('\n') - var hooks_list = { hooks_list: [] } + var hooks_list = {hooks_list: []} for (var index = 0; index < hooks_data.length; index++) { try { var hook_val = JSON.parse(hooks_data[index]) hooks_list.hooks_list.push(hook_val) - - } catch (e) { console.log("Is this JSON: " + hooks_data[index]) } } socket.emit("gen_script_mini", hooks_list) }) - + $("#load_script").click(() => { - var script_to_load = { script: editor2.getValue() } + var script_to_load = {script: editor2.getValue()} socket.emit("loadHookScript", script_to_load) // overwrite() }) $("#load_script_enum").click(() => { - var script_to_load = { script: editor3.getValue() } + var script_to_load = {script: editor3.getValue()} socket.emit("loadEnumScript", script_to_load) editor4.setValue("Waiting for response..") }) @@ -917,7 +954,7 @@ window.onload = function() { var classname = $("#inspect_classname").val() var methodname = $("#inspect_method").val() if ((classname) && (methodname)) { - var inspect_input = { ins_classname: classname, ins_methodname: methodname } + var inspect_input = {ins_classname: classname, ins_methodname: methodname} socket.emit("doInspect", inspect_input) $("#inspect_result").html("

Loading...

") @@ -928,25 +965,28 @@ window.onload = function() { }) $("#load_intercept_script").click(() => { - data = { script: intercepts_script_editor.getValue() }; + data = {script: intercepts_script_editor.getValue()}; socket.emit("load_intercept_script", data) }); $("#intercept_send").click(() => { var param = editor5.getValue(); var j_param = JSON.parse(param) - j_sendback = { data: param, time: current_intercept_time } - socket.emit('intercept_param', { data: JSON.stringify(param), time: JSON.stringify(current_intercept_time), option: "intercept_param" }); + j_sendback = {data: param, time: current_intercept_time} + socket.emit('intercept_param', { + data: JSON.stringify(param), + time: JSON.stringify(current_intercept_time), + option: "intercept_param" + }); editor5.setValue("Sent..") editor6.setValue("") }) - $("#repl_send").click(() => { var cmd = editor6.getValue(); - j_sendback = { data: cmd } - socket.emit('intercept_param', { data: cmd, time: getTime(), option: "intercept_repl" }); + j_sendback = {data: cmd} + socket.emit('intercept_param', {data: cmd, time: getTime(), option: "intercept_repl"}); }) $("#repl_clear").click(() => { @@ -954,25 +994,24 @@ window.onload = function() { }) - // Some toggle settings $("#wrapper").toggleClass("toggled"); - $("#menu-toggle").click(function(e) { + $("#menu-toggle").click(function (e) { e.preventDefault(); $("#wrapper").toggleClass("toggled"); }); - $("#info-toggle").click(function(e) { + $("#info-toggle").click(function (e) { e.preventDefault(); $("#hook-info-div").toggle(); }) - $("#check_device").click(function(e) { + $("#check_device").click(function (e) { e.preventDefault(); $("#device_info").toggle(); }) - $("#toggle_intercept_repl").click(function(e) { + $("#toggle_intercept_repl").click(function (e) { var link = $(this); - $("#intercept-repl-div").slideToggle('slow', function() { + $("#intercept-repl-div").slideToggle('slow', function () { if ($(this).is(':visible')) { link.text('Hide Intercept Repl'); } else { @@ -981,14 +1020,14 @@ window.onload = function() { }); }) - $("#select_pkg").click(function(e) { + $("#select_pkg").click(function (e) { e.preventDefault(); $("#pkg_info").toggle(); }) - $("#toggle_hook_info").click(function(e) { + $("#toggle_hook_info").click(function (e) { var link = $(this); - $("#hook-info-div").slideToggle('slow', function() { + $("#hook-info-div").slideToggle('slow', function () { if ($(this).is(':visible')) { link.html('Hooks '); } else { @@ -997,9 +1036,9 @@ window.onload = function() { }); }) - $("#toggle_inspect_info").click(function(e) { + $("#toggle_inspect_info").click(function (e) { var link = $(this); - $("#inspect-div").slideToggle('slow', function() { + $("#inspect-div").slideToggle('slow', function () { if ($(this).is(':visible')) { link.html('Inspect '); } else { @@ -1008,9 +1047,9 @@ window.onload = function() { }); }) - $("#toggle_repl").click(function(e) { + $("#toggle_repl").click(function (e) { var link = $(this); - $("#intercept-repl-div").slideToggle('slow', function() { + $("#intercept-repl-div").slideToggle('slow', function () { if ($(this).is(':visible')) { link.html('REPL '); } else { diff --git a/static/src-min/ext-beautify.js b/static/src-min/ext-beautify.js index 9ddd2d9..46d84c1 100644 --- a/static/src-min/ext-beautify.js +++ b/static/src-min/ext-beautify.js @@ -1,5 +1,127 @@ -define("ace/ext/beautify/php_rules",["require","exports","module","ace/token_iterator"],function(e,t,n){"use strict";var r=e("ace/token_iterator").TokenIterator;t.newLines=[{type:"support.php_tag",value:""},{type:"paren.lparen",value:"{",indent:!0},{type:"paren.rparen",breakBefore:!0,value:"}",indent:!1},{type:"paren.rparen",breakBefore:!0,value:"})",indent:!1,dontBreak:!0},{type:"comment"},{type:"text",value:";"},{type:"text",value:":",context:"php"},{type:"keyword",value:"case",indent:!0,dontBreak:!0},{type:"keyword",value:"default",indent:!0,dontBreak:!0},{type:"keyword",value:"break",indent:!1,dontBreak:!0},{type:"punctuation.doctype.end",value:">"},{type:"meta.tag.punctuation.end",value:">"},{type:"meta.tag.punctuation.begin",value:"<",blockTag:!0,indent:!0,dontBreak:!0},{type:"meta.tag.punctuation.begin",value:""?r="php":i.type=="support.php_tag"&&i.value=="?>"?r="html":i.type=="meta.tag.name.style"&&r!="css"?r="css":i.type=="meta.tag.name.style"&&r=="css"?r="html":i.type=="meta.tag.name.script"&&r!="js"?r="js":i.type=="meta.tag.name.script"&&r=="js"&&(r="html"),v=e.stepForward(),v&&v.type.indexOf("meta.tag.name")==0&&(d=v.value),p.type=="support.php_tag"&&p.value==""&&(l=!1),h=c,p=i,i=v;if(i===null)break}return a}}),define("ace/ext/beautify",["require","exports","module","ace/token_iterator","ace/ext/beautify/php_rules"],function(e,t,n){"use strict";var r=e("ace/token_iterator").TokenIterator,i=e("./beautify/php_rules").transform;t.beautify=function(e){var t=new r(e,0,0),n=t.getCurrentToken(),s=e.$modeId.split("/").pop(),o=i(t,s);e.doc.setValue(o)},t.commands=[{name:"beautify",exec:function(e){t.beautify(e.session)},bindKey:"Ctrl-Shift-B"}]}); - (function() { - window.require(["ace/ext/beautify"], function() {}); - })(); +define("ace/ext/beautify/php_rules", ["require", "exports", "module", "ace/token_iterator"], function (e, t, n) { + "use strict"; + var r = e("ace/token_iterator").TokenIterator; + t.newLines = [{type: "support.php_tag", value: ""}, {type: "paren.lparen", value: "{", indent: !0}, { + type: "paren.rparen", + breakBefore: !0, + value: "}", + indent: !1 + }, { + type: "paren.rparen", + breakBefore: !0, + value: "})", + indent: !1, + dontBreak: !0 + }, {type: "comment"}, {type: "text", value: ";"}, {type: "text", value: ":", context: "php"}, { + type: "keyword", + value: "case", + indent: !0, + dontBreak: !0 + }, {type: "keyword", value: "default", indent: !0, dontBreak: !0}, { + type: "keyword", + value: "break", + indent: !1, + dontBreak: !0 + }, {type: "punctuation.doctype.end", value: ">"}, { + type: "meta.tag.punctuation.end", + value: ">" + }, { + type: "meta.tag.punctuation.begin", + value: "<", + blockTag: !0, + indent: !0, + dontBreak: !0 + }, { + type: "meta.tag.punctuation.begin", + value: "" ? r = "php" : i.type == "support.php_tag" && i.value == "?>" ? r = "html" : i.type == "meta.tag.name.style" && r != "css" ? r = "css" : i.type == "meta.tag.name.style" && r == "css" ? r = "html" : i.type == "meta.tag.name.script" && r != "js" ? r = "js" : i.type == "meta.tag.name.script" && r == "js" && (r = "html"), v = e.stepForward(), v && v.type.indexOf("meta.tag.name") == 0 && (d = v.value), p.type == "support.php_tag" && p.value == "" && (l = !1), h = c, p = i, i = v; + if (i === null) break + } + return a + } +}), define("ace/ext/beautify", ["require", "exports", "module", "ace/token_iterator", "ace/ext/beautify/php_rules"], function (e, t, n) { + "use strict"; + var r = e("ace/token_iterator").TokenIterator, i = e("./beautify/php_rules").transform; + t.beautify = function (e) { + var t = new r(e, 0, 0), n = t.getCurrentToken(), s = e.$modeId.split("/").pop(), o = i(t, s); + e.doc.setValue(o) + }, t.commands = [{ + name: "beautify", exec: function (e) { + t.beautify(e.session) + }, bindKey: "Ctrl-Shift-B" + }] +}); +(function () { + window.require(["ace/ext/beautify"], function () { + }); +})(); \ No newline at end of file diff --git a/templates/enum.html b/templates/enum.html index 38f2528..4e3417b 100644 --- a/templates/enum.html +++ b/templates/enum.html @@ -3,6 +3,7 @@