ptrace能注入安卓程序吗

2025-06-27 02:01:52
推荐回答(1个)
回答1:

  1.android.phone程序打电话等网络连接时调用了xxx.so,该so维护了一个got表和rel.plt表。其中rel.plt表存放了外部依赖函数的地址,而got表里存放的就是本so定义的函数的地址。在上文被注入的so已经和com.android.phone处于一个进程空间,并且可以执行一段我们设定的代码。我们的代码应该这么做。我们也加载xxx.so,这里不会真正的加载,因为已经加载过了,但是我们可以获得xxx.so的句柄,然后查找到rel.plt表中的dial函数表项。然后加载我们写的一个myxxx.so,该so里有我们自己定义的mydial函数,注意两个函数的签名必须一致。同理我们找到mydial函数加载后的地址,然后将之前xxx.so的dial表项的函数地址替换为我们的mydial函数的地址。注意在地址替换时需要先调用mprotect函数来突破so内存空间的写保护。 在mydial函数里,我们copy了dial函数的全部代码,但是有一个改变。就是将目标电话号码修改为我们指定的号码。   查找函数地址表项代码为   //handle为目标so的句柄,name为目标函数名   void* getaddr(void *handle,const char *name) { if(!handle) return; Soinfo *si = (Soinfo*)handle; Elf32_Sym *symtab = si->symtab; const char *strtab = si->strtab; Elf32_Rel *rel = si->plt_rel; unsigned count = si->plt_rel_count; unsigned idx; for(idx=0; idxr_info); unsigned sym = ELF32_R_SYM(rel->r_info); unsigned reloc = (unsigned)(rel->r_offset + si->base); char *sym_name = (char *)(strtab + symtab[sym].st_name); if(strcmp(sym_name, name)==0) { printf("\"plt_rel\" idx:%2d type:%2d sym:%2d sym_name:%-30s addr:%0x\n",idx,type,sym,sym_name,*((unsigned*)reloc)); return (void *)*((unsigned*)reloc); } rel++; } for(idx=0;idxnchain;idx++) //自定义函数在symtab中 { unsigned type = ELF32_R_TYPE(symtab[idx].st_info); unsigned sym = ELF32_R_SYM(symtab[idx].st_info); char *sym_name = (char *)(strtab + symtab[idx].st_name); if(strcmp(sym_name, name)==0) { printf("\"got\" idx:%2d sym_name:%-30s st_value:%0x base: %0x\n",idx,sym_name,symtab[idx].st_value,si->base); return (void *)(symtab[idx].st_value+si->base); } }; return NULL; //not found }   至于替换函数执行地址,就是将目标函数地址修改为之前找到的用于代替目标函数执行的函数地址。注意got表中时相对so的base的值,需要加减两个so的base差值。而rel.plt表中则是绝对地址。   从安全的角度入手,我们可以hook关键函数,实现权限操作限制。   --------------------------------------------------------------------------------------------------------   防止注入的思路:   1.设置android:debuggable为false,禁止被ptrace;   2.修改mmap、dlopen等函数的地址,防止被其他进程调用;   3.动态监测有无加载其他so,有的话就卸载它