From 6fe08f607c5aca4dc459b1011f861eeaf2d7427b Mon Sep 17 00:00:00 2001 From: iddoeldor Date: Wed, 4 Nov 2020 11:10:19 +0200 Subject: [PATCH] JEB Java method hook generator #formatting --- README.md | 159 ++---------------------------------------------------- 1 file changed, 4 insertions(+), 155 deletions(-) diff --git a/README.md b/README.md index 927b6a7..749aaf7 100644 --- a/README.md +++ b/README.md @@ -117,165 +117,14 @@ ab fridadescribe console.log(Object.getOwnPropertyNames(Java.use('$').__proto__)
JEB -Java method hook generator with keyboard shortcut +Java method hook generator using keyboard shortcut -1. Create Python file with the following code @ `~/$JEB$/scripts` -2. Place cursor at Java method's signature and -3. Press `Ctrl+Shift+F` +1. `curl -o ~/$JEB$/scripts/FridaCodeGenerator.py https://raw.githubusercontent.com/iddoeldor/frida-snippets/master/scripts/FridaCodeGenerator.py` +2. Place cursor at Java method's signature +3. Press `Ctrl+Shift+Z` 4. Code is copied to system clipboard (using `xclip`) -```python -#?shortcut=Mod1+Shift+F -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -from com.pnfsoftware.jeb.client.api import IScript -from com.pnfsoftware.jeb.core import RuntimeProjectUtil -from com.pnfsoftware.jeb.core.units.code.android import IDexUnit -from subprocess import Popen, PIPE - - -def arg_format(i): - return 'arg_%d' % i - - -def generate_body_code(types, retval, method_name, orig_method_name, class_name): - body_code = "\n\tconsole.log('[{}#{}] ' + JSON.strigify({{\n\t".format( - FridaCodeGenerator.to_canonical_name(class_name), method_name) - for i, typ in enumerate(types): - body_code += '\t{}: {}, // {}\n\t'.format('a%d' % i, arg_format(i), typ) - - if retval != 'void': - body_code = '\n\tvar retval = this.{}.apply(this, arguments);{}\tretv: retval\n\t}});'.format( - orig_method_name, body_code) - else: - body_code += '}});\n\tthis.{}.apply(this, arguments);'.format(method_name) - - return body_code + '\n' - - -class JavaMethod(object): - def __init__(self): - self.class_name = None - self.class_orig_name = None - self.name = None - self.orig_name = None - self.arg = [] - self.retType = None - - def get_parameters(self): - return self.arg - - def get_return_type(self): - return self.retType - - def get_name(self): - return self.name - - def get_orig_name(self): - return self.orig_name - - def get_class_orig_name(self): - return self.class_orig_name - - def get_class_name(self): - return self.class_name - - def __str__(self): - return 'JavaMethod[name: %s, orig_name: %s, args: %s, return type: %s]' % ( - self.name, self.orig_name, self.arg, self.retType) - - -class FridaCodeGenerator(IScript): - - @staticmethod - def to_canonical_name(mname): - mname = mname.replace('/', '.') - return { - 'C': 'char', - 'I': 'int', - 'B': 'byte', - 'Z': 'boolean', - 'F': 'float', - 'D': 'double', - 'S': 'short', - 'J': 'long', - 'V': 'void', - 'L': mname[1:-1], - '[': mname - }[mname[0]] - - def run(self, ctx): - project = ctx.getEnginesContext().getProjects()[0] # Get current project(IRuntimeProject) - self.dexunit = RuntimeProjectUtil.findUnitsByType(project, IDexUnit, False)[0] # Get dex context, needs >=V2.2.1 - try: - self.current_unit = ctx.getFocusedView().getActiveFragment().getUnit() # Get current Source Tab in Focus - java_class = self.current_unit.getClassElement().getName() - current_addr = ctx.getFocusedView().getActiveFragment().getActiveAddress() - m = FridaCodeGenerator.get_decompiled_method(self.dexunit, current_addr, java_class) - method_name = m.get_name() - class_name = FridaCodeGenerator.to_canonical_name(m.get_class_orig_name()) - return_type = FridaCodeGenerator.to_canonical_name(str(m.get_return_type())) - if method_name == '': - raise Exception('Class initializer') - args_code = ', '.join([arg_format(i) for i in range(len(m.get_parameters()))]) - - if method_name == '': method_name = '$init' - - types = [FridaCodeGenerator.to_canonical_name(param) for param in m.get_parameters()] - # TODO get original type class names - type_code = ', '.join(["'{0}'".format(t) for t in types]) - body_code = generate_body_code(types, return_type, method_name, m.get_orig_name(), m.get_class_name()) - hook = "Java.use('{class_name}').{method}.overload({sig}).implementation = function({args}) {{{body}}}".format( - class_name=class_name, - method=m.get_orig_name() if method_name != '$init' else method_name, - sig=type_code, - args=args_code, - body=body_code - ) - print(hook) - # copy to system's clipboard - Popen(['xclip', '-sel', 'c', '-i'], stdin=PIPE).communicate(input=(hook.encode())) - except Exception as e: - print(e) - ctx.displayMessageBox(None, 'Place the cursor in the function you want to generate the Frida code', None, None) - - @staticmethod - def get_decompiled_method(dex, addr, class_orig_name): - method_info = JavaMethod() - method_info.orig_name = dex.getMethod(addr).getName(False) - msig = addr.split('+')[0] - infos = str(msig).split('->') - if len(infos) == 2: - method_info.class_name = infos[0] - method_info.class_orig_name = class_orig_name - if len(infos[1].split('(')) == 2: - method_info.name = infos[1].split('(')[0] - if len(infos[1].split(')')) == 2: - method_info.retType = infos[1].split(')')[1] - if len(infos[1].split('(')) == 2 and len(infos[1].split(')')) == 2: - args = infos[1].split('(')[-1].split(')')[0] - while args: - if args[0] in ['C', 'I', 'B', 'Z', 'F', 'D', 'S', 'J', 'V']: - method_info.arg.append(str(args[0])) - args = args[1:] - elif args[0] == '[': - if args[1] == 'L': - offset = args.find(';') - method_info.arg.append(str(args[0:offset + 1])) - args = args[offset + 1:] - else: - method_info.arg.append(str(args[0:2])) - args = args[2:] - elif args[0] == 'L': - offset = args.find(";") - method_info.arg.append(str(args[0:offset + 1])) - args = args[offset + 1:] - print(method_info) - return method_info -``` -