2012-05-03 52 views
1

我最近一直在研究繞行功能(只在Linux中),到目前爲止我已經取得了巨大的成功。直到找到this,我纔開發自己的繞路班。我對代碼進行了現代化處理,並將其轉換爲C++(作爲課程的一部分)。該代碼就像任何其他的繞行實現一樣,它用JMP將原始函數地址替換爲我自己指定的「鉤子」函數。它還爲原始功能創建了一個「蹦牀」。迂迴並使用_thiscall作爲鉤子(GCC調用約定)

一切都完美無瑕,但我想做一個簡單的調整。我使用純C++編程,我沒有使用全局函數,所有東西都包含在類中(就像Java/C#一樣)。問題是這種繞行方法打破了我的模式。 「鉤子」函數需要爲靜態/非類函數。

我想要做的是實現對_thiscall鉤子的支持(這應該是非常簡單的GCC _thiscall約定)。我沒有成功修改此代碼以使用_thiscall鉤子。我想作爲最終結果的東西就像這樣簡單; PatchAddress(void * target, void * hook, void * class);。我沒有要求任何人爲我做這件事,但我想知道如何解決/處理我的問題?

從我所知道的,我應該只需要增加'補丁'的大小(即現在是5個字節,我應該需要額外的5個字節?),然後在我使用JMP調用之前函數),我把我的'this'指針放到堆棧上(這應該就像我把它稱爲成員函數一樣)。舉例說明:

push 'my class pointer' 
jmp <my hook function> 

而不是直接/只有'jmp'調用。這是正確的方法還是有其他東西需要考慮(注意:我不關心對VC++ _thiscall的支持)?

注:這裏的是我的執行上述代碼:headersource,使用libudis86

+0

你稱之爲「純C++」是有爭議的。在C++中封裝所有類都沒有意義。純C++正確使用模塊。 –

+0

@KonradRudolph我想起了舊的口號「用於編寫更好的C的C++」,但將C替換爲Java。 :)但我確實贊同這個問題(pl1) – Orwellophile

回答

1

我嘗試了幾種不同的方法和中間有JIT編譯(使用libjit),這證明是成功的,但該方法沒有提供足夠的性能使其可用。相反,我轉向libffi,它用於在運行時動態調用函數。 libffi庫有一個關閉API(ffi_prep_closure_loc),它使我能夠爲生成的每個閉包提供我的'this'指針。所以我使用了一個靜態回調函數並將void指針轉換爲我的對象類型,從那裏我可以調用任何我希望的非靜態函數!

+0

棒極了,我只是嘗試使用lambda封閉自動化生成70個鉤子(我掛鉤了回調註冊函數),但被告知它不起作用。我的下一步也是libjit,但我會看看你的解決方案能否幫助我。 我們沒有爲我們的鉤子使用類,但是我們確實使用了一個名稱空間來保持它的半組織性,讓你像鉤子一樣鉤住絕對瘋狂的想法(如果你沒有做到這一點,我會說工作)。 – Orwellophile