readelf --syms libcms.so
或readelf --dyn-syms libcms.so
找到该函数,因为libcms.so被剥离并且该功能未包含在符号表中。如何找到函数的十六进制位置?#1 楼
可以使用两种广泛的方法来声明JNI
函数。 第一个是更明显的方法,其中
JNI
函数必须遵循特定的命名约定,例如JNIEXPORT void JNICALL Java_com_app_foo_bar
。您可以使用readelf
轻松识别此类功能。另一种不太明显的方法是使用
RegisterNatives
。在这里,您的函数可以具有任何签名,并且进一步,它们不需要从共享库中导出。通常,您可以从RegisterNatives
调用JNI_OnLoad
将本机函数注册到Java运行时。对于二进制
libcms.so
,它使用第二种方法。以下原型jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint Methods);
如果分析
RegisterNatives
的代码,则会遇到类似下面的JNI_OnLoad
调用。 />第三个参数指向一个声明为typedef struct {
char *name;
char *signature;
void *fnPtr;
} JNINativeMethod;
的
RegisterNatives
结构数组。但是,对于您而言,所有名称和签名都是加密的。JNINativeMethod
部分包含指向这些解密器功能的指针,这意味着它们将在启动时被调用。但是,还不是全部。二进制文件在整个过程中还采用了“控制流扁平化”混淆,因此执行路径可能不容易看出,如下所示。使用诸如Frida之类的工具进行动态分析技术。
进一步阅读:
https://developer.android.com/training/articles/perf- jni#native-libraries
在JNI_OnLoad的汇编代码中查找RegisterNatives函数调用
https://stackoverflow.com/questions/13509961/which-method-eventually-calls-jni-onload
https://stackoverflow.com/questions/51811348/find-manually-registered-obfuscated-native-function-address
https://stackoverflow.com/questions/1010645/what-does-the-registernatives-method -do
如何恢复存储在.ctors节中的信息?
评论
我不明白,是否可以动态加载它以获得该功能?还是我错过了重点?
–杜松子酒
19-10-10在4:16
@GinMay若要解密函数名称,您可以运行/模拟.datadiv_decode系列函数。
– 0xec
19-10-13在7:51