此本机代码是否可以进行进一步的静态分析?

Is this native code possible for further static analysis?

我试图在 android 应用程序中对本机库代码进行逆向工程。 .so 包含许多功能。但是 Java 代码中引用了函数 sUQWWyTBEs()。我很好奇这个功能是如何工作的。

这个函数 returns 一个像这样的字符串 47fjlkj843h9asjklj94kljfsad93j4l2715943hasd... 但我想要的是这个值是如何生成或返回的。

Ghidra反编译函数sUQWWyTBEs()的代码:

*************************************************************
                             *                           FUNCTION                          
                             *************************************************************
                             undefined  __cdecl  Myapp_sUQWWyTBEs()
             undefined         w0:1           <RETURN>
             longlong *        x0:8           param_1
                             Myapp_sUQWWyTBEs XREF[2]:     Entry Point (*) , 00101350   
        00100e44 08  00  40  f9    ldr        x8, [param_1 ]
        00100e48 01  00  00  b0    adrp       x1, s_c7a584936712f32773d3d0a_00101000           ; = "c7a584936712f32773d3d0a"
        00100e4c 21  60  08  91    add        x1, x1, #0x218
        00100e50 02  9d  42  f9    ldr        x2, [x8, #0x538 ]
        00100e54 40  00  1f  d6    br         x2

根据我的理解,我做了如下静态分析:

00100e44 08 00 40 f9 ldr x8, [param_1 ]

将内存地址 param_1 处的值加载到寄存器 x8。

0100e48 01 00 00 b0 adrp x1, s_c7a584936712f32773d3d0a_00101000

将寄存器 x1 设置为 0x101000。

00100e4c 21 60 08 91 add x1, x1, #0x218

将 0x218 添加到 x1,因此将 x1 设置为 0x101218。

00100e50 02 9d 42 f9 ldr x2, [x8, #0x538 ]

将 x8 + 0x538 处的值加载到 x2。

00100e54 40 00 1f d6 br x2

最后分支到x2中存储的地址。

话虽这么说,这里我不知道地址为 x2 的内存,显然它最初取决于 param_1 持有的值。有什么办法或者我怎样才能参考 param_1 的初始化位置?我不太了解 Ghidra 或其他逆向工程工具的用法。任何人都可能提供帮助,我们将不胜感激。

假设此函数在 Java 端声明为 native 函数,param_1JNIEnv*Android JNI documentation states:

JNI defines two key data structures, "JavaVM" and "JNIEnv". Both of these are essentially pointers to pointers to function tables.

因此,您显示的代码基本上是在偏移量 0x538 处调用函数 table 中的函数。假设你正在展示一个 64 位 Android 程序,函数指针是 8 个字节,所以你需要找出第 167 个函数指针(从 0 开始)。

获取 jni.h 的副本并提取 struct JNINativeInterface 的成员,从 0 开始编号:

0:     void*       reserved0;
1:     void*       reserved1;
2:     void*       reserved2;
3:     void*       reserved3;
4:     jint        (*GetVersion)(JNIEnv *);
...
167:     jstring     (*NewStringUTF)(JNIEnv*, const char*);

因此,假设我没有犯任何错误,您显示的代码调用 env->NewStringUTF 并使用 s_c7a584936712f32773d3d0a_00101000+0x218 作为参数。

我认为您可以让 Ghidra 解析 jni.h 以使这些类型可用。如果您随后更改 param_1 的类型,这可能足以让 Ghidra 为您执行此映射并生成对 C/C++.

的合理反编译。