2013-04-10 62 views
0

我試圖掛鉤一個Linux程序的功能。 基本上搜索使用mprotect取消保護功能,然後將jmp放入原來的函數地址中,重新指向我的函數鉤子。內存複製功能

但是我想複製原始函數,以便在不需要修改函數時可以調用它。 我有一種勾這樣

int CallHookedFunctionFoobar(int param1, int param2) 
{ 
     if (g_somevariable) 
      Foobar_original(param1, param2); 
     else 
      Foobar_modified(param1, param2); 
} 

所以我的問題是...我怎麼能知道一個函數的大小,以字節爲單位,這樣我就可以memcpy的()是動態分配的緩衝區執行它?我想過也許嵌入一個小長度的反彙編器並解析操作碼,直到找到RETN optocode,但我不確定它是否可以在絕對所有情況下工作(例如,如果多個RETN駐留在同一個函數中: [)

,因爲我想這樣做,是因爲同樣的功能可以被其他圖書館迷上另一個原因..

+0

可能是重複的http://stackoverflow.com/questions/4546071/copy-a-function-in-memory-and-execute-it – jbr 2013-04-10 18:52:34

回答

3

首先,如果這是Linux特有,那麼最有可能你的可執行文件是ELF二進制文件。因此,您可以解析ELF標頭(例如使用libelf)來查找/計算函數的長度。

但是,我不明白你爲什麼需要這個。我能想到的一個更簡單的方法是即時修補該功能,將其前幾條指令替換爲鉤子函數JMPCALL,同時保存這些被覆蓋的指令以便稍後打補丁。喜歡的東西:

void call_hooked(void (*fn)(), unsigned char *ctx, size_t *n) 
{ 
    unsigned char hook_patch[] = { 0x15, 0x20, 0x7f, 0x48 }; // I bluffed 
    *n = sizeof(hook_patch); 
    memcpy(ctx, fn, sizeof(hook_patch)); 
    memcpy(fn, hook_patch, sizeof(hook_patch)); 
    fn(); 
} 

void call_orig(void (*fn)(), unsigned char *ctx, size_t n) 
{ 
    memcpy(fn, ctx, n); 
    fn(); 
} 
+1

,或者,更容易 - 覆蓋PLT條目當然如果符號沒有隱藏。 – 2013-04-10 19:06:26

+0

@VladLazarenko對,特別是考慮到這將與動態庫一起使用的事實。 – 2013-04-10 19:07:47

+0

感謝您的信息。 的確我可以將信息保存在一個數組中並重新打補丁。儘管如此,我主要是爲了學習的目的,並認爲我可以去做父親。 你能否提供更多有關ELF分析的信息?看起來很有趣。我如何檢查ELF中的函數長度? 通過排序.symtab中的syms偏移量和下一個或...的func偏移量?請原諒我的無知。 你能提供一些基本的示例代碼嗎?謝謝,100萬次。 – Yannick 2013-04-11 09:39:09