inline-hook的本質是加跳轉指令,在x86下實現比較簡單,一般用push $addr; ret即可
這條指定的含義是: 將指定的位址壓棧,然後返回到該位址,從而實現hook
然後在指定函式內的hook,需要維持堆疊平衡,因為假設hooked之後想要跳回函式執行,但當前的上下文已經改變,這時候若跳回去,可能會引發crash
這裡假設有下面這樣的**:
#include "test.h"
#include #include #define libc_path "/lib/i386-linux-gnu/libc.so.6"
static int do_add(int a, int b)
static void *g_handle;
int add(int a, int b)
printf("in add handle = %p\n",(void *)handle);
long addr;
__asm__("movl %%esp,%0"::"g"(addr));
printf("esp = 0x%lx\n",addr);
printf("hello,world\n");
int ret = do_add(a, b);
printf("on ret = %d\n", ret);
return ret;
}
假設我們比較關心handle的值,想將它匯出到外面使用。預設在c的語義下,你是沒辦法獲取到該指標的,但是inline-hook可以。
我們的思路是,找到dlopen呼叫之後的指令: call dlopen@plt
將其強制跳轉到指定函式:比如test。 然後從eax中拿出返回值,然後將上下文儲存下來,再跳回到原先中斷的指令,具體test方法的**如下:
.text
.global test
test:
pushl %eax
pushl %ebx
movl %eax,%ebx
movl %ebx,handle
pusha
pushf
call copy
popf
popa
popl %ebx
popl %eax
jmp *next_call_dlopen_addr
那麼如何找到call dlopen@這個位址呢?
我們需要解析elf檔案結構了,很顯然,dlopen是屬於libc.so下的,那麼我們遍歷plt結構即可:
static elf32_addr get_func_plt_addr(const char *lib_path, const char *func_name)
if (fstat(fd, &st) < 0)
mem = mmap(null, st.st_size, prot_read, map_private, fd, 0);
if (mem == map_failed)
if (mem[0] != 0x7f && strcmp(&mem[1], "elf"))
ehdr = (elf32_ehdr *)mem;
shdr = (elf32_shdr *)(mem + ehdr->e_shoff);
phdr = (elf32_phdr *)(mem + ehdr->e_phoff);
const char *shstrtab = (const char *)&mem[shdr[ehdr->e_shstrndx].sh_offset];
elf32_sym *symtab;
const char *strtab;
elf32_addr plt_addr;
elf32_off dlopen_off;
elf32_rel *rel;
int k;
const char *sh_name;
int rel_index;
for (i = 0; i < ehdr->e_shnum; i++)
if (strcmp(sh_name,".rel.plt") == 0)
relp++;
}} if (shdr[i].sh_type == sht_symtab || shdr[i].sh_type == sht_dynsym)
symtab++;
}} }
elf32_addr result = (rel_index + 1) * 16 + plt_addr; // 注意: 每個plt 16位元組且加上plt0
return result + lib_base_addr;
}
我們知道call指令佔5個位元組,而call的實際編碼為e8 (當前指令的位址 + 5)- dlopen@plt的位址,這樣,就可以寫出下列搜尋**:
long search(long start_addr,long call_path)
} ++i;
} return start_addr + i;
}
最後完整的**見:
Python 獲取類的成員變數及臨時變數
利用python反射機制,從 塊中靜態獲取引數 co argcount 普通引數的總數,不包括引數和 引數。co names 所有的引數名 包括引數和 引數 和區域性變數名的元組。co varnames 所有的區域性變數名的元組。co filename 源 所在的檔名。co flags 這是乙個數值...
OpenMP的環境變數及庫函式
openmp的環境變數 環境變數 描述 示例 omp schedule 控制for迴圈任務分配結構的排程 omp schedule guided,2 omp num threads 設定預設執行緒的個數 omp schedule 4 openmp的庫函式 函式名稱 描述int omp get num...
openmp環境變數和庫函式
openmp的環境變數 環境變數 描述 示例omp schedule 控制for迴圈任務分配結構的排程 omp schedule guided,2 omp num threads 設定預設執行緒的個數 omp schedule 4 openmp的庫函式 函式名稱 描述 int omp get num...