首页
论坛
专栏
课程

[推荐]跨平台调so函数的框架

2019-7-12 11:04 4603

[推荐]跨平台调so函数的框架

2019-7-12 11:04
4603

最近在翻unicorn showcase的时候发现了一套不错的代码,能够非常好的模拟Android Native调用。 于是就瞎改了其代码,使其可以支持跑测试so(x音),并翻译了一份README。
初始化有点慢,log有点慢,大黑阔们们别把初始化搞到任务循环里了~~

 

https://github.com/P4nda0s/AndroidNativeEmu/

 

fork from : https://github.com/AeonLucid/AndroidNativeEmu

AndroidNativeEmu

AndroidNativeEmu 让你能够跨平台模拟Android Native库函数,比如JNI_OnLoad、Java_XXX_XX等函数。
fork from : https://github.com/AeonLucid/AndroidNativeEmu

特性

  • 模拟 JNI Invocation API so JNI_OnLoad can be called properly.
  • 模拟 memory、malloc、memcpy
  • 支持拦截系统调用(SVC #0)
  • 通过符号Hook
  • 所有 JavaVM, JNIEnv 和 hooked functions 都可以用python来处理
  • 支持 VFP
  • 支持文件系统(也就是说你可以模拟maps、status等文件)

本人瞎改

小弟不才,修改了一些代码,使其能够运行libcms的leviathan.

  • 添加 自动调用InitArray初始化代码,基于重定位表解析。
  • 添加 修改对象引用的值
  • 实现 getcpu() 系统调用
  • 实现 setByteArrayRegion
  • JNI中动态注册Native函数失败将不再报错(libcms中注册了大量不需要的函数)

使用方法

运行环境:python 3.7 必须!

  1. Clone the repository
  2. Run pip install -r requirements.txt
  3. Run python example.py

Windows上可以跑,自行尝试。

依赖库

初始化模拟器

# Initialize emulator
emulator = Emulator(
    vfp_inst_set=True,
    vfs_root=posixpath.join(posixpath.dirname(__file__), "vfs")
)

如何定义Java类呢?

Jni 中会调用到的类

注意看看各项参数的定义

class java_lang_System(metaclass=JavaClassDef, jvm_name='java/lang/System'):
        def __init__(self):
            pass

        @java_method_def(name='getProperty', args_list=["jstring"] ,signature='(Ljava/lang/String;)Ljava/lang/String;', native=False)
        def getProperty(self, *args, **kwargs):
            print (args[0].value)
            return "2.1.0"

我们的目标类

class XGorgen(metaclass=JavaClassDef, jvm_name='com/ss/sys/ces/a'):
    def __init__(self):
        pass

    @java_method_def(name='leviathan', signature='(I[B)[B', native=True)
    def leviathan(self, mu):
        pass

    def test(self):
        pass

模拟stacktrace的类

class java_lang_Thread(metaclass=JavaClassDef, jvm_name='java/lang/Thread'):
    def __init__(self):
        pass

    @java_method_def(name="currentThread", signature='()Ljava/lang/Thread;', native=False)
    def currentThread(self, *args, **kwargs):
        return java_lang_Thread()

    @java_method_def(name="getStackTrace", signature='()[Ljava/lang/StackTraceElement;', native=False)
    def getStackTrace(self, *args, **kwargs):
        return  [java_lang_StackTraceElement("dalvik.system.VMStack"),
                 java_lang_StackTraceElement("java.lang.Thread"),
                 java_lang_StackTraceElement("com.ss.sys.ces.a"),
                 java_lang_StackTraceElement("com.yf.douyintool.MainActivity"),
                 java_lang_StackTraceElement("java.lang.reflect.Method"),
                 java_lang_StackTraceElement("java.lang.reflect.Method"),
                 java_lang_StackTraceElement("android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener"),
                 java_lang_StackTraceElement("android.view.View"),
                 java_lang_StackTraceElement("android.os.Handler"),
                 java_lang_StackTraceElement("android.os.Handler"),
                 java_lang_StackTraceElement("android.os.Looper"),
                 java_lang_StackTraceElement("android.app.ActivityThread"),
                 java_lang_StackTraceElement("java.lang.reflect.Method"),
                 java_lang_StackTraceElement("java.lang.reflect.Method"),
                 java_lang_StackTraceElement("com.android.internal.os.ZygoteInit$MethodAndArgsCaller"),
                 java_lang_StackTraceElement("com.android.internal.os.ZygoteInit"),
                 java_lang_StackTraceElement("dalvik.system.NativeStart")
                 ]

更多的类请见example

注册类

emulator.java_classloader.add_class(XGorgen)
emulator.java_classloader.add_class(java_lang_System)
emulator.java_classloader.add_class(java_lang_Thread)
emulator.java_classloader.add_class(java_lang_StackTraceElement)

调用JNI_OnLoad

init array 已经自动调用了,SO如果有加密也没关系。

# 添加依赖库
emulator.load_library("samples/example_binaries/libdl.so")
emulator.load_library("samples/example_binaries/libc.so")
emulator.load_library("samples/example_binaries/libstdc++.so")
emulator.load_library("samples/example_binaries/libm.so")

lib_module = emulator.load_library("samples/example_binaries/libcms.so")

#   JNI_OnLoad will call 'RegisterNatives'.
emulator.call_symbol(lib_module, 'JNI_OnLoad', emulator.java_vm.address_ptr, 0x00)

调用native 方法

x = XGorgen()
data = 'acde74a94e6b493a3399fac83c7c08b35D58B21D9582AF77647FC9902E36AE70f9c001e9334e6e94916682224fbe4e5f00000000000000000000000000000000'
data = bytearray(bytes.fromhex(data))
result = x.leviathan(emulator, 1562848170, data)


[公告]安全服务和外包项目请将项目需求发到看雪企服平台:https://qifu.kanxue.com

最后于 2019-8-5 13:02 被无名侠编辑 ,原因:
最新回复 (19)
流星暴雨 2019-7-12 11:22
2
0
前排支持
bengou 2019-7-12 11:34
3
0
不错,谢谢。
爱吃菠菜 1 2019-7-12 22:00
4
0
仿真器无敌了
上海刘一刀 2 2019-7-14 23:18
5
0
没看懂  先收藏膜拜一波
奔跑的阿狸 1 2019-7-15 09:55
6
0
前排支持
cqzhou 2019-7-15 10:29
7
0
win7 不成功啊
bujianshi 2019-7-18 14:19
8
0
收藏膜拜,无名侠tql
endlif 1 2019-7-19 12:44
9
0
    # bypass douyin checks
    with open("app_process32", 'rb') as ap:
        data = ap.read()
        len1 = len(data) + 1024 - (len(data) % 1024)
        emulator.mu.mem_map(0xab006000, len1)
        emulator.mu.mem_write(0xab006000, data)
这段代码的含义是啥?
菜年richor 2019-7-19 16:48
10
0
膜拜大佬,安装keystone的时候出现问题,能不能帮我看一下,pip是最新版的
endlif 1 2019-7-19 18:38
11
0
菜年richor 膜拜大佬,安装keystone的时候出现问题,能不能帮我看一下,pip是最新版的
error: can't copy 'src/build/llvm/lib/libkeystone.dylib': doesn't exist or not a regular file
我在mac上的时候也遇到类似的这个问题  是因为平台不支持32bit 
需要下载keystone-engine-0.9.1-3 源码
在 src/make-common.sh 中删除i386
最后于 2019-7-19 18:55 被endlif编辑 ,原因:
菜年richor 2019-7-22 09:04
12
0
endlif 菜年richor 膜拜大佬,安装keystone的时候出现问题,能不能帮我看一下,pip是最新版的 error: can't& ...
谢谢师兄,我试一下
菜年richor 2019-7-24 16:15
13
0
好像计算的xgon有误,也不知道问题出在哪里
通过hook得到的参数是:
copyLove: s=5e17c1a25e40f2fc6d8305967f254c2d00000000000000000000000000000000d760a91c971b53507a536ff2da44d80900000000000000000000000000000000
xgon=03006cc0000001f5e81da76ab90577cdef8d7b81af152ccb76af
通过大佬调用后的计算结果是:
03000000000047a0d83f4f61076af53deea6c36eade7f1811710
明显不一致啊
无名侠 10 2019-7-25 17:02
14
0
菜年richor 好像计算的xgon有误,也不知道问题出在哪里 通过hook得到的参数是: copyLove: s=5e17c1a25e40f2fc6d8305967f254c2d00000000000000000 ...
仅做参考,已被和谐
菜年richor 2019-7-25 17:25
15
0
无名侠 仅做参考,已被和谐
近距离膜拜大佬,看你的视频入门的,受益匪浅,感谢
YoHooo 2019-9-3 11:14
16
0
<删除>
最后于 2019-9-3 14:21 被YoHooo编辑 ,原因:
breaklink 2019-9-3 12:23
17
0
YoHooo zhoudeMacBook-Pro:samples zhou$ python3 example.py 2019-09-03 11:09:59,484 DEBUG androide ...
启用vfs试试?
# Initialize emulator
emulator = Emulator(
    vfp_inst_set=True,
    vfs_root=posixpath.join(posixpath.dirname(__file__), "vfs")
)
YoHooo 2019-9-3 12:36
18
0
breaklink 启用vfs试试? # Initialize emulator emulator = Emulator( vfp_inst_set=True, vfs_root=posixpat ...
找到问题了https://github.com/AeonLucid/AndroidNativeEmu/issues/8
YoHooo 2019-9-3 15:21
19
0
又遇到了一个问题。。

Traceback (most recent call last):
  File "samples/example_douyin.py", line 152, in <module>
    result = x.leviathan(emulator, 1562848170, data)
  File "/Users/Desktop/AndroidNativeEmu-master/androidemu/java/java_method_def.py", line 24, in native_wrapper
    *argv  # Extra args.
  File "/Users/Desktop/AndroidNativeEmu-master/androidemu/emulator.py", line 143, in call_native
    self.mu.emu_start(addr, stop_pos - 1)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/unicorn/unicorn.py", line 286, in emu_start
    status = _uc.uc_emu_start(self._uch, begin, until, timeout, count)
ctypes.ArgumentError: argument 2: <class 'TypeError'>: wrong type
最后于 2019-9-3 15:21 被YoHooo编辑 ,原因:
bwmaples 2019-9-3 18:44
20
0
YoHooo 又遇到了一个问题。。Traceback&nbsp;(most&nbsp;recent&nbsp;call&nbsp;last):&nbsp;&nbsp; ...
同遇到了这个问题,这个开源项目跑的我好难受……
猜测有可能是抖音更新了,这个方法在JNI_Onload里不再注册导致了该函数的地址变成了None?
还请大佬解答!
最后于 2019-9-4 16:03 被bwmaples编辑 ,原因:
游客
登录 | 注册 方可回帖
返回