9月24日,,哈哈,郁闷多日,终于明白啦,,,总结hook!!

来源:互联网 发布:linux使用代理上网 编辑:程序博客网 时间:2024/05/10 14:40

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

 


 

原创粉丝点击