我靠,,這回可是我進段時間來鬱悶最長的時間了,,不知道幾天了,天天連著看,,連著找,,連著問,,到是強迫自己對pe格式和彙編有了進一些的認識,,,也是件好事 :) 最後終於還是自己沒能解決,,是vchelp裡的一個叫啞巴英語的大哥幫的忙,,改了程式,,感謝他!!!
自己目前對Module的概念還是不清楚,,
現在回頭來看梁肇新書中和windows核心編程中的程式,,windows核心編程的意思是,,先用CreAteToolhelp32SnApshot(TH32CS_SNAPMODULE,0)來獲得所有的Module,,每個Module裡又有不少用到的dll,,然後用那段hook的程式去掛接這些dll中的USER32.dll中的MessAgeBoxA,,把其他Module的IAT中的MessAgeBoxA的Thunk項給改成指向自己的MyMessAgeBox,,並且他把一個dll插了進去(插哪了,怎麼插的,還等學習),,MyMessAgeBox就在其中.這樣當其他的進程調用MessAgeBoxA的時候,就會被轉到插入的那個dll中MyMessAgeBox,實現了hook,,但程式他沒有hook自己的Module,,也就是說,自己調用MessAgeBoxA是不受影響的,,
而梁的書中的意思卻不是這樣(我把書還了,,具體的記不清了),很顯然他是抄的,,似乎還沒理解,,(天那,這是真的嗎?),,他和windows核心編程中的程式重要部分幾乎一樣,,他也掛了其他所有Module的MessAgeBoxA,,沒掛自己的,,然後卻以為自己再用MessAgeBoxA的時候會轉向MyMessAgeBox,,我向他是這個意思吧,,因為他在那個程式裡好象沒有提插入dll的事,,而且說要先用PROC lpAdder=MessAgeBoxA;的形式先儲存函數的地址,,免的以後自己的程式用的時候出現一個迴圈,,,其實這樣做是沒用的,, 沒有該自己Module的IAT, MessAgeBoxA的入口地址永遠都不會變!!! 當然我也主要鬱悶在這裡,,因為,我單步的時候明顯看到WriteProcessMemory函數成功執行了,,並且指向Thunk的那塊地址的內容被改成了自己的MyMessAgeBox的地址,,但我不清楚那個Module不是我的,,單從地址的數值上就看出來了,,,我的Module的IAT大概在0x00040000左右,,而被改的卻是0x77******什麼的,,因為那些的Module的BAseAddress就是0x77*******什麼的,,很明顯不是本程式的IAT所以在自己的程式裡用MessAgeBoxA是根本不受影響,,但其他Module的IAT確實被改了,,,哈,,錯就在這裡了,,明白了這個,,程式就可以按自己的想法來執行了
兩份程式全貼出來
對了,,向這樣的
__imp__MessageBoxA@16:
00425324 05 10 40 00 32 add eax,32004010h
00425329 12 E1 adc ah,cl
0042532B 77 00 ja USER32_NULL_THUNK_DATA+1 (0042532d)
0042532D 00 00 add byte ptr [eax],al
不要以為它真的是彙編語句,,根本就不通,,起作用只是那些16進位數,,後面的彙編語句是vc自做主章的給翻譯的,,開始還讓他給蒙了,,,現在自己不懂編譯原理,,但想象大概是把pe整個程式全都載入到虛擬空間了吧
另外自己的c功底差的可憐,,幾個指標下來,我就暈了,,,這部分一定要過關!!!!!!!!!!!!!!!!!!
#include "stdio.h"
#include "windows.h"
#include "imagehlp.h"
#include "tlhelp32.h"
#pragma comment(lib,"imagehlp.lib")
#pragma comment(lib,"kernel32.lib")
typedef struct _APIHOOK32_ENTRY
{
LPCTSTR pszAPINAme;
LPCTSTR pszCAllerModuleNAme;
PROC pfnOriginApiAddress;
PROC pfnDummyFuncAddress;
HMODULE hModCAllerModule;
}APIHOOK32_ENTRY,*PAPIHOOK32_ENTRY;
typedef int (WINAPI *PFNMSGA)(HWND,LPCTSTR,LPCTSTR,UINT);
BOOL _SetApiHookUp(PAPIHOOK32_ENTRY phk)
{
PIMAGE_THUNK_DATA pThunk,pThunk1;
ULONG size;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(
phk->hModCAllerModule ,
TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT,
&size);
if (pImportDesc == NULL){
return FALSE;
}
//遍曆DLL,,第一層迴圈
for(;pImportDesc->Name ;pImportDesc++){
PSTR pszDllNAme = (LPSTR)((PBYTE)phk->hModCAllerModule + pImportDesc->Name );
if (lstrcmpA(pszDllNAme,phk->pszCAllerModuleNAme )==0) break; //found
}
if (pImportDesc->Name == 0){
return FALSE;
}
printf("***********************************************/n");/////////////
pThunk = (PIMAGE_THUNK_DATA)((PBYTE)phk->hModCAllerModule + pImportDesc->FirstThunk );//IAT
pThunk1 = (PIMAGE_THUNK_DATA)((PBYTE)phk->hModCAllerModule + pImportDesc->OriginalFirstThunk );//INT
for(;pThunk1->u1 .Function ;pThunk1++){
PROC* ppfn1 = (PROC*)((DWORD)phk->hModCAllerModule+(DWORD)pThunk1->u1 .Function+2);
printf("%s/n",ppfn1); //Hint 是個WORD 所以+2
}
for (;pThunk->u1 .Function ;pThunk++){
PROC lp;
PROC* ppfn = (PROC*)&pThunk->u1 .Function ;
printf("%x/n",pThunk->u1 .Function);////////////
printf("%x/n",phk->hModCAllerModule);
//做比較,,看是否是要找的函數,,如果是,,就把地址改寫
if(*ppfn == phk->pfnOriginApiAddress ){
WriteProcessMemory(GetCurrentProcess(),
ppfn,
&(phk->pfnDummyFuncAddress),
sizeof(phk->pfnDummyFuncAddress ),
NULL);
lp = MessageBoxA;
return TRUE;
}
}
printf("/n/n");/////////////
return TRUE;
}
//------------------------------------------------------------------------------
BOOL SetWindowsAPIHook(PAPIHOOK32_ENTRY phk)
{
MEMORY_BASIC_INFORMATION mInfo;
HMODULE hModHookDll;
HANDLE hSnApShot;
BOOL bOk;
MODULEENTRY32 me = {sizeof(MODULEENTRY32)};
if (phk->pszAPINAme == NULL||phk->pszCAllerModuleNAme == NULL
||phk->pfnOriginApiAddress == NULL){
return FALSE;
}
_SetApiHookUp(phk);
return FALSE;
}
//------------------------------------------------------------------------------
BOOL UnhookWindowsAPIHooks(PAPIHOOK32_ENTRY lpHk)
{
PROC temp;
temp = lpHk->pfnOriginApiAddress ;
lpHk->pfnOriginApiAddress = lpHk->pfnDummyFuncAddress ;
lpHk->pfnDummyFuncAddress = temp;
return SetWindowsAPIHook(lpHk);
}
//------------------------------------------------------------------------------
//儲存原地址
PROC lpAdder;
//PROC lpAdder1;
int WINAPI MyMessAgeBoxA(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCAption,UINT uType)
{
return ((PFNMSGA)lpAdder)(NULL,"new","new",MB_OK);
}
//------------------------------------------------------------------------------
int main(void)
{
APIHOOK32_ENTRY pe;
lpAdder = (PROC)MessageBoxA;
//lpAdder = GetProcAddress(GetModuleHandle("USER32.DLL"),"MessageBoxA");
//printf("%x %x/n",lpAdder1,lpAdder);
pe.pszAPINAme = "MessageBoxA";
pe.pszCAllerModuleNAme = "USER32.dll";//區分大小寫
pe.pfnOriginApiAddress = lpAdder;
pe.pfnDummyFuncAddress = (PROC)MyMessAgeBoxA;
pe.hModCAllerModule = GetModuleHandle(NULL);
//MessageBoxW(NULL,L"hi",L"hi",MB_OK);
SetWindowsAPIHook(&pe);
MessageBoxA(NULL,"old","old",MB_OK);
UnhookWindowsAPIHooks(&pe);
MessageBoxA(NULL,"old","old",MB_OK);
}
這個是改好的,,hook自己,,逗自己玩的 SetWindowsAPIHook 幾乎是沒用的,,裡面的東西對hook自己的程式沒有用
#include "stdio.h"
#include "windows.h"
#include "imagehlp.h"
#include "tlhelp32.h"
#pragma comment(lib,"imagehlp.lib")
#pragma comment(lib,"kernel32.lib")
PROC lpAdder;
typedef struct _APIHOOK32_ENTRY
{
LPCTSTR pszAPINAme;
LPCTSTR pszCAllerModuleNAme;
PROC pfnOriginApiAddress;
PROC pfnDummyFuncAddress;
HMODULE hModCAllerModule;
}APIHOOK32_ENTRY,*PAPIHOOK32_ENTRY;
BOOL _SetApiHookUp(PAPIHOOK32_ENTRY phk)
{
PIMAGE_THUNK_DATA pThunk,pThunk1;
ULONG size;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(
phk->hModCAllerModule ,
TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT,
&size);
if (pImportDesc == NULL){
return FALSE;
}
//遍曆DLL,,第一層迴圈
for(;pImportDesc->Name ;pImportDesc++){
PSTR pszDllNAme = (LPSTR)((PBYTE)phk->hModCAllerModule + pImportDesc->Name );
// if (lstrcmpA(pszDllNAme,phk->pszCAllerModuleNAme )==0) break; //found
// }
if (pImportDesc->Name == 0){
return FALSE;
}
printf("***********************************************/n");/////////////
pThunk = (PIMAGE_THUNK_DATA)((PBYTE)phk->hModCAllerModule + pImportDesc->FirstThunk );//IAT
pThunk1 = (PIMAGE_THUNK_DATA)((PBYTE)phk->hModCAllerModule + pImportDesc->OriginalFirstThunk );//INT
// for(;pThunk1->u1 .Function ;pThunk1++){
// PROC* ppfn1 = (PROC*)((DWORD)phk->hModCAllerModule+(DWORD)pThunk1->u1 .Function+2);
// if(strcmp((char*)ppfn1,"MessageBoxW" )==0){
// printf("%s/n",ppfn1);
// printf("%s/n",pszDllNAme );
// }
// }
for (;pThunk->u1 .Function ;pThunk++){
PROC* ppfn = (PROC*)&pThunk->u1 .Function ;
PROC* ppfn1 = (PROC*)((DWORD)phk->hModCAllerModule+(DWORD)pThunk1->u1 .Function+2);
if(1){//strcmp((char*)ppfn1,"MessageBoxW" )==0){
printf("%s/n",ppfn1);
printf("%s/n",pszDllNAme );
printf("%x/n",phk->hModCAllerModule );
}
pThunk1++;
// printf("%x/n",pThunk->u1 .Function);////////////
//做比較,,看是否是要找的函數,,如果是,,就把地址改寫
if((DWORD)pThunk->u1 .Function == (DWORD)lpAdder){
PROC lp;
WriteProcessMemory(GetCurrentProcess(),
ppfn,
&(phk->pfnDummyFuncAddress),
sizeof(phk->pfnDummyFuncAddress ),
NULL);
lp=MessageBoxW;
return TRUE;
}
}
printf("/n/n");/////////////
}///////////////////
return TRUE;
}
//------------------------------------------------------------------------------
BOOL SetWindowsAPIHook(PAPIHOOK32_ENTRY phk)
{
MEMORY_BASIC_INFORMATION mInfo;
HMODULE hModHookDll;
HANDLE hSnApShot;
BOOL bOk;
MODULEENTRY32 me = {sizeof(MODULEENTRY32)};
if (phk->pszAPINAme == NULL||phk->pszCAllerModuleNAme == NULL
||phk->pfnOriginApiAddress == NULL){
return FALSE;
}
if (phk->hModCAllerModule == NULL){
//取得從_SetApiHookUp地址開始的一個頁面的資訊
VirtualQuery(_SetApiHookUp,&mInfo,sizeof(mInfo));
hModHookDll = (HMODULE)mInfo.AllocationBase ;
hSnApShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0);
bOk = Module32First(hSnApShot,&me);
while(bOk){
if (me.hModule != hModHookDll){
phk->hModCAllerModule = me.hModule ;
_SetApiHookUp(phk);
}
bOk = Module32Next(hSnApShot,&me);
}
phk->hModCAllerModule = NULL;
return FALSE;
}else{
return _SetApiHookUp(phk);
}
return FALSE;
}
//------------------------------------------------------------------------------
BOOL UnhookWindowsAPIHooks(PAPIHOOK32_ENTRY lpHk)
{
// PROC temp;
// temp = lpHk->pfnOriginApiAddress ;
// lpHk->pfnOriginApiAddress = lpHk->pfnDummyFuncAddress ;
// lpHk->pfnDummyFuncAddress = temp;
return SetWindowsAPIHook(lpHk);
}
//------------------------------------------------------------------------------
//儲存原地址
//PROC lpAdder1;
int WINAPI MyMessAgeBoxA(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCAption,UINT uType)
{
return lpAdder(NULL,"new","new",MB_OK);
}
//------------------------------------------------------------------------------
int main(void)
{
APIHOOK32_ENTRY pe;
lpAdder = MessageBoxW;
//lpAdder = GetProcAddress(GetModuleHandle("USER32.DLL"),"MessageBoxA");
//printf("%x %x/n",lpAdder1,lpAdder);
pe.pszAPINAme = "MessageBoxW";
pe.pszCAllerModuleNAme = "USER32.DLL";//區分大小寫
pe.pfnOriginApiAddress = lpAdder;
pe.pfnDummyFuncAddress = MyMessAgeBoxA;
pe.hModCAllerModule = GetModuleHandle(NULL);
//printf("%x/n",pe.hModCAllerModule ); //400000
SetWindowsAPIHook(&pe);
MessageBoxA(NULL,"old","old",MB_OK);
UnhookWindowsAPIHooks(&pe);
MessageBoxA(NULL,"old","old",MB_OK);
}
//------------------------------------------------------------------------------
這個是原來的,,稍稍改一下就可以hook所有的hook了 :)