簡體   English   中英

如何繞過 Linux 上的 function?

[英]How to detour a function on Linux?

我做了一個 32 位測試程序,我試圖繞過這個 function(內部):

void Function(int number)
{
    std::cout << "Your number is: " << number << std::endl;
}

使用我制作的這個繞道 function(它在 memcpy 上引發 SIGSEV 分段錯誤,即使 memory 是有效的並且受執行/讀/寫保護):

bool Detour(byte_t* src, byte_t* dst, size_t size)
{
    if(size < HOOK_MIN_SIZE) return false;
    mprotect(src, size, PROT_EXEC | PROT_READ | PROT_WRITE);
    mem_t jmpAddr = ((mem_t)dst - (mem_t)src) - HOOK_MIN_SIZE;
    byte_t CodeCave[] = { JMP, 0x0, 0x0, 0x0, 0x0 };
    *(mem_t*)((mem_t)CodeCave + sizeof(JMP)) = jmpAddr;
    memcpy(src, CodeCave, sizeof(CodeCave));
    return true;
}

它是這樣調用的:

Detour((byte_t*)&Function, (byte_t*)&hkFunction, HOOK_SIZE);

HOOK_MIN_SIZE 等於 5,以適應程序集跳轉 (0xE9 0x00 0x00 0x00 0x00) 並且 HOOK_SIZE 等於 7,因為它必須適應所有覆蓋的指令(對於蹦床,但在這種情況下並不重要):

Dump of assembler code for function Function(int):
   0x5655631d <+0>:    push   ebp
   0x5655631e <+1>:    mov    ebp,esp
   0x56556320 <+3>:    push   ebx
   0x56556321 <+4>:    sub    esp,0x4
   0x56556324 <+7>:    call   0x56556220 <__x86.get_pc_thunk.bx>

GDB 錯誤:

Program received signal SIGSEGV, Segmentation fault.
0x565564c9 in Detour (
    src=0x5655631d <Function(int)> "U\211\345S\203\354\004\350\367\376\377\377\201\303\367+",
    dst=0x56556372 <hkFunction(int)> "U\211\345S\203\354\004\350\242\376\377\377\201â+", size=7) at main.cpp:51
51        memcpy(src, CodeCave, sizeof(CodeCave));

類型定義:

typedef unsigned int mem_t;
typedef unsigned char byte_t;

這個繞道function有什么問題? 我已經成功地在 Windows 上為 32 位和 64 位制作了自己的,但在 Linux 上似乎有所不同。

我讓它工作了,問題是地址不是系統頁面的倍數:我可以使用這個 function 而不是 mprotect 來修復它:

int ProtectMemory(mem_t address, size_t size, int protection)
{
    long pagesize = sysconf(_SC_PAGE_SIZE);
    address = address - (address % pagesize);
    return mprotect((void*)address, size, protection);
}

Detour function 現在看起來像這樣:

bool Detour(byte_t* src, byte_t* dst, size_t size)
{
    if(size < HOOK_MIN_SIZE) return false;
    //mprotect(src, size, PROT_EXEC | PROT_READ | PROT_WRITE);
    int out = ProtectMemory((mem_t)src, size, PROT_EXEC | PROT_READ | PROT_WRITE);
    //std::cout << out << std::endl;
    mem_t jmpAddr = ((mem_t)dst - (mem_t)src) - HOOK_MIN_SIZE;
    byte_t CodeCave[] = { JMP, 0x0, 0x0, 0x0, 0x0 };
    *(mem_t*)((mem_t)CodeCave + sizeof(JMP)) = jmpAddr;
    memcpy(src, CodeCave, sizeof(CodeCave));
    return true;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM