forked from maiyao1988/ExAndroidNativeEmu
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexample_jni.py
123 lines (94 loc) · 3.58 KB
/
example_jni.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import logging
import posixpath
import sys
import os
import time
from unicorn import *
from unicorn.arm_const import *
from androidemu.emulator import Emulator
from androidemu.java.java_class_def import JavaClassDef
from androidemu.java.java_method_def import java_method_def
import androidemu.utils.debug_utils
from androidemu.utils.chain_log import ChainLogger
import capstone
import traceback
def cur_ts():
return round(time.time() * 1000)
g_cfd = ChainLogger(sys.stdout, "./ins-jni.txt")
g_inst_count=0
g_inst_start_ts = cur_ts()
# Add debugging.
def hook_code(mu, address, size, user_data):
try:
emu = user_data
if (not emu.memory.check_addr(address, UC_PROT_EXEC)):
logger.error("addr 0x%08X out of range"%(address,))
sys.exit(-1)
#androidemu.utils.debug_utils.dump_registers(emu, sys.stdout)
androidemu.utils.debug_utils.dump_code(emu, address, size, g_cfd, androidemu.utils.debug_utils.DUMP_REG_WRITE)
global g_inst_count
g_inst_count += 1
except Exception as e:
logger.exception("exception in hook_code")
sys.exit(-1)
#
#
def hook_mem_read(uc, access, address, size, value, user_data):
pc = uc.reg_read(UC_ARM_REG_PC)
if (address == 0xCBC80640):
logger.debug("read mutex")
data = uc.mem_read(address, size)
v = int.from_bytes(data, byteorder='little', signed=False)
logger.debug(">>> Memory READ at 0x%08X, data size = %u, data value = 0x%08X, pc: 0x%08X," % (address, size, v, pc))
#
#
def hook_mem_write(uc, access, address, size, value, user_data):
pc = uc.reg_read(UC_ARM_REG_PC)
if (address == 0xCBC80640):
logger.debug("write mutex")
logger.debug(">>> Memory WRITE at 0x%08X, data size = %u, data value = 0x%08X, pc: 0x%08X" % (address, size, value, pc))
#
#
class MainActivity(metaclass=JavaClassDef, jvm_name='local/myapp/testnativeapp/MainActivity'):
def __init__(self):
pass
@java_method_def(name='stringFromJNI', signature='()Ljava/lang/String;', native=True)
def string_from_jni(self, mu):
pass
def test(self):
pass
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG, format='%(message)s')
# Initialize emulator
emulator = Emulator(
vfs_root=posixpath.join(posixpath.dirname(__file__), "vfs")
)
# Register Java class.
emulator.java_classloader.add_class(MainActivity)
emulator.mu.hook_add(UC_HOOK_CODE, hook_code, emulator)
emulator.mu.hook_add(UC_HOOK_MEM_WRITE, hook_mem_write)
emulator.mu.hook_add(UC_HOOK_MEM_READ, hook_mem_read)
# Load all libraries.
lib_module = emulator.load_library("tests/bin/libnative-lib_jni.so")
#androidemu.utils.debug_utils.dump_symbols(emulator, sys.stdout)
#logger.setLevel(5)
# Show loaded modules.
logger.info("Loaded modules:")
for module in emulator.modules:
logger.info("=> 0x%08x - %s" % (module.base, module.filename))
try:
# Run JNI_OnLoad.
# JNI_OnLoad will call 'RegisterNatives'.
g_inst_start_ts = cur_ts()
emulator.call_symbol(lib_module, 'JNI_OnLoad', emulator.java_vm.address_ptr, 0x00)
spent_ts = cur_ts() - g_inst_start_ts
print("***** %d instruction spent %fms, %d inst/s" % (g_inst_count, spent_ts, g_inst_count * 1000 / spent_ts))
# Do native stuff.
main_activity = MainActivity()
logger.info("Response from JNI call: %s" % main_activity.string_from_jni(emulator))
# Dump natives found.
logger.info("Exited EMU.")
logger.info("Native methods registered to MainActivity:")
except UcError as e:
print("Exit at %x" % emulator.mu.reg_read(UC_ARM_REG_PC))
raise