古詩詞大全網 - 藝術簽名 - 如何hook android framwork api

如何hook android framwork api

1.向目標進程註入代碼(註入so,並調用該so裏的壹個函數)。首先調用ptrace函數,調試com.android.browser進程,在這裏我們需要遍歷該進程加載的libc.so,這裏有我們需要的dlopen,dlsym等函數的地址,我們先中斷com.android.phone,修改其寄存器,壓入參數如我們的so路徑,並將之前找到的dlopen地址壓入寄存器,直接操作blx,就可以讓目標進程調用dlopen加載我們的so,同理dlsym調用我們的so裏的函數。

下面就是我做的工作,重定向函數實現hook。

2.com.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; idx<count; idx++) //外部依賴函數在rel_plt中

{

unsigned type = ELF32_R_TYPE(rel->r_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;idx<si->nchain;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,有的話就卸載它