Android将共享对象文件功能与另一个共享对象挂钩

时间:2020-05-15 18:39:50

标签: android linux arm hook reverse-engineering

我修改了android应用,以将我的lib与其已经加载的其他库一起加载。

...
System.loadLibrary("libONE");
System.loadLibrary("libTWO");

说,'libONE'有一些函数,我需要'钩子'-替换它们的调用以从我的库'libTWO'中调用我的函数,并将执行传递回'libONE'中的原始函数。 由于两个库都加载到相同的内存空间中,因此知道函数与基本库地址的偏移量,因此我可以替换函数序言以分支到我的代码,然后在代码内部做一些事情然后分支回去。那就是我要在这里做的:

void hook(unsigned int address, unsigned int function) {
unsigned char hookProc[] = {
0xFA, 0x46,
0xF0, 0x00, 0xF8, 0x5F,
0x00, 0x00, 0x00, 0x00
};
//  THUMB mode!
//  First 2 bytes are 'mov r10, pc' - to know where to jump back from hooked function.
//  Next 4 bytes are 'ldr pc, [pc, #-4] - essentialy jump to address specified in next 4 bytes after this
*(unsigned int*)&hookProc[6] = function;  //  Replace dummy bytes with actual jump address.
mprotect((void*)(address & 0x0xFFFFF000), sizeof(hookProc), PROT_READ | PROT_WRITE);
//  'Unprotect' memory address with size of hook procedure.
memcpy((void*)address, (void*)hookProc, sizeof(hookProc));
//  Copy actual hook bytes instead function's prologue.
__builtin___clear_cache((char*)address, (char*)(address + sizeof(hookProc)));
//  Use android's implementation of 'clear cache'. It supposed to clear instruction and data cache.
mprotect((void*)(address & 0x0xFFFFF000), sizeof(hookProc), PROT_READ | PROT_EXEC);
//  Change memory protection back to how it used to be.
}

此代码运行良好,但是由于某些奇怪的原因,分支操作码不会被我的代码覆盖,而其他操作码却被覆盖。我的意思是:

push {r0, lr}
blx 0x...
pop {r0, lr}

替换为:

mov r10, pc
blx 0x...
<address>

因此,所有代码都将替换为分支指令之外的。我搜索了ARM信息中心,并查看了如何实现清晰的缓存。本质上,它使用ISB和其他手臂高速缓存维护操作码来使高速缓存无效并使系统从“脏”高速缓存中获取指令。如您所见,它可以工作,但是由于某些原因-分支指令不会被替换。 这就是问题:为什么会这样?该怎么办?

快速说明:我很清楚必须事先保存序言,在此将其跳过。词汇错误(如果有的话)不是故意的,并且代码可以编译并很好地工作。不,我不想使用FRIDA或其他繁重的库来执行此任务。

0 个答案:

没有答案
相关问题