在本文中,我将讨论如何使用AndHook框架将函数调用重定向到本机库。您可以直接截获公共(导出的函数)和非公共的调用。您可以在此处和框架页面上阅读有关重定向的更多信息。
作为示例,我们将考虑其库的实现情况。但是,此框架还允许您进行工作,而无需使用xposed重新构建应用程序。
在本文中,我将使用Windows的Visual Studio和BatchApkTool。可以使用Android Studio代替Visual Studio,甚至可以通过gcc或clang(高级选项)对其进行编译。可以使用apktool代替BatchApkTool。我不会停止详细介绍使用BatchApkTool,因为 处理程序中的工作并不困难。
首先,您需要使用BatchApkTool或apktool解析APK。
现在,从项目页面下载库和头文件,为此,您需要单击此链接和此链接,然后下载适用于您平台的库。(我没有发现Compat的版本与普通版本之间的区别,我个人使用的是普通版本。也许他们会在注释中说明)
设置Visual Studio以使用NDKVisual Studio Installer :

.
在Visual Studio中创建一个新项目, , , .
" (Android)", .
:

. : , : < >, API 14 ARM X86, ARM64 X64 21 .
.
-> , :
, , , , .
. .
. .
, .cpp
#include "AndHook.h"
让我们创建JNI_OnLoad函数,在其中注册钩子。JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env = NULL;
jint result = -1;
LOGD("JNI_OnLoad start!");
if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
LOGE("JNI_OnLoad! GetEnv failed");
return -1;
}
RegisterHooks();
result = JNI_VERSION_1_4;
LOGD("JNI_OnLoad! finished!");
return result;
}
RegisterHooks函数本身:
#ifdef __arm__
#define Test_Offset 0x1234
#elif __aarch64__
#define Test_Offset 0x1235
#elif __i386__
#define Test_Offset 0x1236
#elif __x86_64__
#define Test_Offset 0x1237
#endif
void (*Old_Test)();
void Test()
{
LOGD("Test!");
Old_Test();
}
void (*Old_Test2)();
void Test2()
{
LOGD("Test2!");
Old_Test2();
}
void RegisterHooks() {
const void* libil2cpp = AKGetImageByName("libil2cpp.so");
if (libil2cpp == NULL) {
LOGW("AKGetImageByName return null!");
return;
}
AKHookFunction(AKFindAnonymity(libil2cpp, Test_Offset), reinterpret_cast<void*>(&Test), reinterpret_cast<void**>(&Old_Test));
AKHookFunction(AKFindSymbol(libil2cpp, "Test2"), reinterpret_cast<void*>(&Test2), reinterpret_cast<void**>(&Old_Test2));
void (*Test3)();
Test3 = reinterpret_cast<void (*)()>(AKFindAnonymity(libil2cpp, 0x12345));
Test3();
const uint8_t data[] = { 0x00, 0xF0, 0x20, 0xE3 };
AKPatchMemory(reinterpret_cast<const void*>(AKFindAnonymity(libil2cpp, 0x123456)), reinterpret_cast<const void*>(&data), 4);
AKCloseImage(libil2cpp);
}
同样,对于几种架构下的补丁,使用#define也很方便
例#ifdef __arm__
#define Patch_Offset 0x1234
#define Patch_Data { 0x00, 0xF0, 0x20, 0xE3 }
#elif __aarch64__
#define Patch_Offset 0x1234
#define Patch_Data { 0x1F, 0x20, 0x03, 0xD5 }
#endif
const uint8_t data[] = Patch_Data;
const size_t len = sizeof(data) / sizeof(uint8_t);
AKPatchMemory(reinterpret_cast<const void*>(AKFindAnonymity(libil2cpp, Patch_Offset)), reinterpret_cast<const void*>(&data), len);
完成代码编写后,必须对其进行编译。
为此,您需要:
如果有多个平台,请重复步骤1-2。
AndHook lib . ( ).
. MainActivity . onCreate MainActivity :
const-string v0, "SharedObject1"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
SharedObject1 lib .so
il2cpp- MainActivity onCreate smali/com/unity3d/player/UnityPlayerActivity.smali.
.
:
https://github.com/asLody/AndHook/
http://armconverter.com/
http://armconverter.com/hextoarm/