在破解应用时, 常常是某个函数返回 true 代表激活或注册了.那个我们可以修改汇编指令为 B0 01 或 B8 01 00 00 00,来返回 true,达到破解的目的.
但是有些应用返回字符串来表示是不是注册或激活了, C string 还好处理.C++的 std::string 就不好破解了.
我们也常常 hook 库函数,来达到破解的目的.
但有些 APP, 函数在自己包里.就不能 hook 了.
今天我们介绍一种 hookAPP 自己包里的 C 函数,非 OBJC 的.
我们通过修改 C 函数入口处的汇编指令为 JMP 强制跳转到我们的函数,此处关键得是计算跳转的相对地址.
以下是实例代码,供大家参考研究.
希望能抛砖引玉.有意见问题均可留言.
//开发环境 MAC OSX, XCODE
#import <dlfcn.h>
#import <mach-o/dyld.h>
#include <string>
#include <stdio.h>
#include <mach/vm_map.h>
//用于 hook C/C++ 函数
const char * userName() {
return "doorxp";
}
static void handler(const struct mach_header *header, intptr_t slide) {
Dl_info image_info;
int result = dladdr(header, &image_info);
if (result == 0) {
NSLog(@"load mach_header failed");
return;
}
//判断要 hook 的执行文件或库.
if (strcmp("/Applications/XXXXXX.app/Contents/MacOS/XXXXXX", image_info.dli_fname) == 0 ||
strcmp("/Applications/XXXXXX.app/Contents/MacOS/./XXXXXX", image_info.dli_fname) == 0) {
intptr_t addr = slide + 0x1008f8710;//要 hook 的 binary 中的地址,地址用 hopper /IDA 查看,直接复制就可以.
char * const b = (char *)addr;
//计算跳转地址
intptr_t diff = (const char*)userName - (const char*)addr - 5;//5 个字节是跳转指令的汇编码长度.
//允许修改加载在的代码
if (vm_protect(mach_task_self(), (vm_address_t)b, 10, 0, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY) != KERN_SUCCESS)
{
NSLog(@"failed!!");
}
b[0]=0xE9;//跳转汇编指令
//地址,低端在前面
for(int i=1;i<5;i++){
char r = diff & 0xff;
b[i] = r;
diff>>=8;
}
//让修改后的代码可以执行
if (vm_protect(mach_task_self(), (vm_address_t)b, 10, 0, VM_PROT_READ|VM_PROT_EXECUTE) != KERN_SUCCESS)
{
NSLog(@"failed!!");
}
}
}
static void __attribute__((constructor)) ___init____(){
_dyld_register_func_for_add_image(handler);
}敬请转载.注明来源:http://doorxp.com/?id=118