如果獲取庫函式的臨時變數?

2021-07-25 15:17:01 字數 2583 閱讀 6659

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...