Demo代码
新建一个jni工程, demo的代码很简单, 就是一个加法1
2
3
4
5
6
7
8
9
10
11
12
13
14JNIEXPORT int nativeAdd(int a, int b)
{
return a + b;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_mario_testunicorn_MainActivity_myAdd(
JNIEnv* env,
jobject /*this*/,
int a,
int b){
return nativeAdd(a,b);
}
emu代码
注释写的很详细, 具体看代码吧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
63import logging
import posixpath
import sys
from unicorn import UcError, UC_HOOK_CODE, UC_HOOK_MEM_UNMAPPED
from unicorn.arm_const import *
from androidemu.emulator import Emulator
import debug_utils
# 配置日志
logging.basicConfig(
stream=sys.stdout,
level=logging.DEBUG,
format="%(asctime)s %(levelname)7s %(name)34s | %(message)s"
)
logger = logging.getLogger(__name__)
# 初始化模拟器
emulator = Emulator(
vfp_inst_set=True,
vfs_root=posixpath.join(posixpath.dirname(__file__), "vfs")
)
# 加载依赖的动态库
emulator.load_library("example_binaries/libdl.so")
emulator.load_library("example_binaries/libc.so", do_init=False)
emulator.load_library("example_binaries/libstdc++.so")
emulator.load_library("example_binaries/libm.so")
lib_module = emulator.load_library("example_binaries/libmytest.so")
# 当前已经load的so
logger.info("Loaded modules:")
for module in emulator.modules:
logger.info("=> 0x%08x - %s" % (module.base, module.filename))
try:
# 运行jni onload 这里没有, 但不影响执行
emulator.call_symbol(lib_module, 'JNI_OnLoad', emulator.java_vm.address_ptr, 0x00)
#直接调用符号1, 计算1+2
emulator.call_symbol(lib_module, '_Z9nativeAddii', 1, 2)
print("_Z9nativeAddii result call: %i" % emulator.mu.reg_read(UC_ARM_REG_R0))
#直接调用符号2, 计算1000 + 1000
emulator.call_symbol(lib_module, 'Java_com_mario_testunicorn_MainActivity_myAdd', 0, 0, 1000, 1000)
print("myAdd result call: %i" % emulator.mu.reg_read(UC_ARM_REG_R0))
#执行完成, 退出虚拟机
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
RuntimeError: Unhandled syscall x (x) at 解决
这个错误是因为没有实现对应syscall导致的, 缺少什么函数, 自己写一个函数绑定一下, 返回给他需要的值就可以了, 比如getpid, 那么自己写的函数随便返回一个整形就可以了
在syscall_hooks.py文件里, 可以看到作者已经实现的函数1
2
3
4
5
6
7
8
9
10
11self._syscall_handler.set_handler(0x4E, "gettimeofday", 2, self._handle_gettimeofday)
self._syscall_handler.set_handler(0xAC, "prctl", 5, self._handle_prctl)
self._syscall_handler.set_handler(0xF0, "futex", 6, self._handle_futex)
self._syscall_handler.set_handler(0x107, "clock_gettime", 2, self._handle_clock_gettime)
self._syscall_handler.set_handler(0x119, "socket", 3, self._socket)
self._syscall_handler.set_handler(0x11b, "connect", 3, self._connect)
self._syscall_handler.set_handler(0x159, "getcpu", 3, self._getcpu)
self._syscall_handler.set_handler(0x14e, "faccessat", 4, self._faccessat)
self._syscall_handler.set_handler(0x14, "getpid", 0, self._getpid)
self._syscall_handler.set_handler(0xe0, "gettid", 0, self._gettid)
self._syscall_handler.set_handler(0x180,"null1",0, self._null)
1 | set_handler函数参数: |