本人的專案中需要大量使用HOOK功能,每個HOOK點對應一個裸函式,如下所示:
// 111
void _declspec(naked) Hook111Result()
{
__asm {
pushad
pushfd
push edi
call gHook111.disposeCall
popfd
popad
call gHook111.originCall
jmp gHook111.nextOrderAddress
}
}
// 222
void _declspec(naked) Hook222Notify()
{
__asm {
pushad
pushfd
push esi
call gHook222.disposeCall
popfd
popad
call gHook222.originCall
jmp gHook222.nextOrderAddress
}
}
每增加一個HOOK點都需要把上面的代碼重復寫一次,然后更換全域的 自定義處理函式地址和跳轉地址。
這樣維護起來比較麻煩,現在就是想通過C++模板來指定一個裸函式模板,看看是否可行,大致如下:
// 定義
template<DWORD MSG_TYPE, DWORD ORIGIN_CALL, DWORD NEXT_ARRRESS, void(*FUNC_PTR)(DWORD type, ...)>
void __declspec(naked) HookTest() {
__asm {
pushad
pushfd
mov eax, MSG_TYPE
push eax
mov eax, esp
push eax
call FUNC_PTR
popfd
popad
call ORIGIN_CALL
jmp NEXT_ARRRESS
}
}
// 測驗呼叫
void main()
{
auto test_block = [](DWORD t, ...) {
std::cout << "dd";
};
// 這里只是測驗呼叫,實際情況是需要注入到軟體的某個模塊,使用HOOK技術替換相關代碼的
// 另外實際專案中肯定是使用全域函式代替lambda的
HookTest<0x0, 0x1, 0x2, test_block >();
}
以上代碼可以編譯通過,但是在運行的時候會崩潰,除錯下發現所有的引數均變成了 *(0), 如下所示:

請問下有沒有辦法實作匯編中訪問模板引數值呢
uj5u.com熱心網友回復:
用#define宏不好使嗎?uj5u.com熱心網友回復:
不行!這個裸函式最終得用它替換HOOK點的指令,比如 hook 點的指令本來是 call 0x38204252 【5個位元組】
現在要替換成 jmp HookTest 【也是5個位元組】
用宏的話不能實作吧
uj5u.com熱心網友回復:
宏不能的話,用代碼生成技術。
代碼生成技術參考下面:
//codegen.c
// 輸入一組字串,比如
// aa ss ddd dd 33 dd
// 然后自動生成一個函式 int A(const char*);
// 實作A("aa")回傳0 A("ss")回傳1 依次類推
#include <stdio.h>
int main(int argc,char **argv) {
int i;
if (argc<2) {
printf("%s p1 [p2 ...] [>result.c]\nGenerate code int A(const char *a); 0==A(\"p1\") 1==A(\"p2\") ...",argv[0]);
return 1;
}
//printf("#include <string.h>\n");
printf("int A(const char *a) {\n");
for (i=0;i<argc-1;i++) {
printf(" if (0==strcmp(a,\"%s\")) return %d;\n",argv[i+1],i);
}
printf(" return -1;\n");
printf("}\n");
return 0;
}
//C:\test\Debug>codegen.exe
//codegen.exe p1 [p2 ...] [>result.c]
//Generate code int A(const char *a); 0==A("p1") 1==A("p2") ...
//C:\test\Debug>codegen.exe aa ss ddd dd 33 dd
//int A(const char *a) {
// if (0==strcmp(a,"aa")) return 0;
// if (0==strcmp(a,"ss")) return 1;
// if (0==strcmp(a,"ddd")) return 2;
// if (0==strcmp(a,"dd")) return 3;
// if (0==strcmp(a,"33")) return 4;
// if (0==strcmp(a,"dd")) return 5;
// return -1;
//}
//
//c:\test\Debug>codegen.exe aa ss ddd dd 33 dd >result.c
//
//c:\test\Debug>type result.c
//int A(const char *a) {
// if (0==strcmp(a,"aa")) return 0;
// if (0==strcmp(a,"ss")) return 1;
// if (0==strcmp(a,"ddd")) return 2;
// if (0==strcmp(a,"dd")) return 3;
// if (0==strcmp(a,"33")) return 4;
// if (0==strcmp(a,"dd")) return 5;
// return -1;
//}
//
uj5u.com熱心網友回復:
用一個結構資料管理不行嗎?注入hook時遍歷陣列全部呼叫一次就可以了,模板函式類把函式指標又封裝了一層,應該是不同的。vector <hook_struct> hook_list;
addhooklist();//全域管理
hook_start();
區別不是很大吧,自己封裝一下就可以了
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/263503.html
標籤:C++ 語言
