Skip to content

Commit

Permalink
binaryninja: fix invalid JNI method signatures in .plt/.text for cpp …
Browse files Browse the repository at this point in the history
…libraries
  • Loading branch information
evilpan committed Oct 22, 2024
1 parent 0412316 commit 16a4211
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 4 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,10 @@ Before | After

see [Binary Ninja](./binary_ninja).

Before | After
:----------:|:------------:
![b2][b2] | ![b4][b4]
Type | Image
:-----:|:------------:
Before | ![b2][b2]
After | ![b4][b4]

## Radare2 Plugin

Expand Down
37 changes: 36 additions & 1 deletion binary_ninja/jni_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,48 @@ class JNIHelper:

def __init__(self):
self.jni_header = ""
self.pr = None

def start(self):
if not self.init_header():
return
self.apply_signatures()
self.fix_cpp_symbols()

def fix_cpp_symbols(self):
"""
fix incorrect signatures for `_JNIEnv::` in PLT,
for example `_JNIEnv::CallObjectMethod`
"""
if not self.pr:
return
funcs = []
for fn in bv.functions:
name = fn.symbol.short_name
if name.startswith("_JNIEnv::"):
funcs.append(fn)
if not funcs:
log("not cpp library, skip")
return
# load correct signatures
sigmap = {}
for iface in self.pr.types:
if iface.name == 'JNINativeInterface_':
break
for member in iface.type.members[4:]:
sigmap[member.name] = member.type.children[0]
log("loaded {} JNI interface".format(len(sigmap)))
for fn in funcs:
name = fn.symbol.short_name[9:]
vtype = sigmap.get(name)
if vtype is None:
log(f"WARN: no signature for {name}")
continue
fn.type = vtype
log(f"cpp fix 0x{fn.start:x} {fn.symbol.short_name}")


def init_header(self):
options = ["-fdeclspec"]
jni_file = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "headers", "jni.h")
if not os.path.exists(jni_file):
jni_file = self.choose_file("jni.h not found, choose one")
Expand Down Expand Up @@ -80,6 +114,7 @@ def apply_signatures(self):
pr = self.parse_source(jni_ext, "jni_ext.h")
if pr is None:
return
self.pr = pr
for pt in pr.types:
bv.define_user_type(pt.name, pt.type)
for pf in pr.functions:
Expand Down

0 comments on commit 16a4211

Please sign in to comment.