我所遇到的問題是,我想給乙個flash中的某個函式加鉤子,我知道這個函式的位址,但是它是乙個c++的類成員函式。detours的安裝目錄下的samples\member就是乙個如何對c++的類成員函式加hook的例子。
假設原來的函式宣告是:
class cmember ;
一般來說,類成員函式都是遵守__thiscall。但是我們不能強行給乙個全域性函式加上__thiscall的修飾符。所以,首先,必須得先寫乙個虛假的類,然後重新宣告這個函式。
class cdetour ;
然後我做了一點小技巧,把以前的函式宣告成__stdcall
typedef void (__stdcall *pfunc)(const char* str);
pfunc oldfunc=(pfunc)000401040;
然後還是按以前那樣attach,但是此時成員函式指標的轉換很巧妙
detourattach( &(pvoid &)oldfunc,(pvoid)(&(pvoid&) a::func));
你不能把乙個成員函式轉換成void*,但是你可以把它轉換成void*&。
順便今天發現乙個技巧,這樣輸出的結果是乙個index,如0、1、2
void cmember::target(const char* str)
但是這樣輸出的就是函式位址:
void cmember::target(const char* str)
嗯,繼續說,mine_target的實現
我想到的第乙個方法是,利用__stdcall模擬__thiscall。
先儲存ecx,並用this給ecx賦值。p.s.如果不是this,而是乙個棧變數,mov就要換成lea。
__asm
然後呼叫以前的函式:
oldfunc(str);
然後恢復ecx:
__asm
這裡利用的原理就是,__stdcall和__thiscall的區別僅在於後者多傳乙個ecx。但是這種方法有時候不成功。因為在呼叫oldfunc的時候,需要傳遞引數,此時有可能會利用ecx作臨時暫存器,先把引數mov到ecx中,然後push。
我最後的辦法是用__fastcall來模擬__thiscall,這種方法很優雅,不需要內聯彙編。原來的函式定義就變成了
typedef char (__fastcall *pfunc)(void* pthis,int dummy,const char *str);
按照__fastcall的規範,最前面2個引數應該通過ecx,edx傳遞,後面的從右向左依次push。相當於我多傳遞了乙個edx,無所謂啦。
作者 changming
c 類成員函式
c 的兩大特色是多型和模板。其中多型是通過繼承和虛函式來實現的,其中虛函式是通過每個物件裡面的虛表來實現的。如果這個物件的類有虛函式,那麼這個類就有一張虛表,存的是每個虛函式的入口位址,而這個類的每個物件,都會有乙個4位元組的指標,指向這張虛表,這個就是虛指標。上面一段話很多人都知道,但是如果問普通...
c 類成員函式
類成員函式是類的乙個成員,它可以操作類的任意物件,可以訪問物件中的所有成員。定義類box,使用成員函式來訪問類的成員,而不是直接訪問這些類的成員 class box class box double box getvolume void 在這裡,需要強調一點,在 運算子之前必須使用類名。呼叫成員函式...
c 類成員函式
靜態型別 表示式在編譯時型別是已知的,它是變數宣告時和表示式生成的型別 動態型別 表達是表示式在記憶體中的型別 如果表示式不是指標或引用,則它的靜態型別和動態型別永遠一樣。person的靜態型別是person,它的動態型別可能是student,teacher.string job person.jo...