我靠,,这回可是我进段时间来郁闷最长的时间了,,不知道几天了,天天连着看,,连着找,,连着问,,到是强迫自己对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了 :)