CSDN博客

img uuty

9月21日,,郁闷了一天,,该死的hook

发表于2004/9/21 22:52:00  878人阅读

分类: 日记

还是没弄会,,连日记也没心情写,,看了pe的文章,,<<箴言>>里的程序都没注释,,梁这不是打自己嘴巴子么?也不替我们这样的新手考虑考虑,,写书干嘛呀,,难道就让我知道这些你早逗会了??  哎,,发啥牢骚啊,,毕竟自己从梁大哥那里学了不少 :)  今天hook还是没成功,,已经是第2中方法了,,把他的程序给做了遍注释,,程序倒是理解了,,可不成功的原因没找到,,,估计自己还算不上理解 :(


#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;

BOOL _SetApiHookUp(PAPIHOOK32_ENTRY phk)
{
 PIMAGE_THUNK_DATA pThunk;
 ULONG    size;
 
//每个IMAGE_IMPORT_DESCRIPTOR代表一个DLL,这里的 pImportDesc 为NULL是表示遍历了所有的引入的DLL
 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++){
  //这里不理解,,为什么要把pImportDesc->NAme和phk->hModCAllerModule加起来
  //IMAGE_DESCRIPTOR中的NAme是一个RVA指向一个ASCII字符串,是dll的名字,,那下面这句就更不理解了
  PSTR pszDllNAme = (LPSTR)((PBYTE)phk->hModCAllerModule + pImportDesc->Name );////哈哈,,单步时这里果然和我想的一样,,加上基址后变为虚拟地址,,然后,,比如这次把 其值就是 0x77ebcd79 "NTDLL.DLL"
  //这样比较肯定不相等了啊
  //找到相等的后 :(
  if (strcmp(pszDllNAme,phk->pszCAllerModuleNAme )==0) break;
 }
//看是否真的找到了
 if (pImportDesc->Name == NULL){
  return FALSE;
 }
//IMAGE_IMPORT_DESCRIPTOR结构里的FirstThunk指向一个DWORD数组,每个DWORD都是一个RVA,是输入函数的入口地址,这个数组可以叫输入地址表
 //现在关键是弄清楚phk->hModCAllerModule到底是个什么???????????????????????????
 //大概是这样吧,,phk->hModCAllerModule是个HMODULE类型,,也许是通过它把RVA变成真实的虚拟地址吧,,它起了个加载基址的作用,,
 //哎 不知道对不对,,看看它的值才知道
 pThunk = (PIMAGE_THUNK_DATA)((PBYTE)phk->hModCAllerModule + pImportDesc->FirstThunk );//IAT

//现在开始是第2层循环  IMAGE_THUNK_DATA 结构如下
//* typedef struct _IMAGE_THUNK_DATA32 {
//*    union {
//*        PBYTE  ForwarderString;
//*        PDWORD Function;
//*        DWORD Ordinal;
//*        PIMAGE_IMPORT_BY_NAME  AddressOfData;
//*    } u1;
//* } IMAGE_THUNK_DATA32;
//*typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;
 //这里不懂,,PThunk指向一个DWORD数组,在遍历时应该用pThunk++吗?好象也可以,,但自己不清楚,,
 //因为pThunk里面就一个u1,pThunk->u1.Function++等于pThunk++吗??????????
 for (;pThunk->u1 .Function ;pThunk++){

  PROC* ppfn = (PROC*)&pThunk->u1 .Function ;
//做比较,,看是否是要找的函数,,如果是,,就把地址改写
  if(*ppfn == phk->pfnOriginApiAddress ){
   WriteProcessMemory(GetCurrentProcess(),
        ppfn,
        &(phk->pfnDummyFuncAddress),
        sizeof(phk->pfnDummyFuncAddress ),
        NULL);
   return TRUE;
  }
 }
 return TRUE;
}
//------------------------------------------------------------------------------
BOOL SetWindowsAPIHook(PAPIHOOK32_ENTRY phk)
{
 //The MEMORY_BASIC_INFORMATION structure contains information about a range of pages
 //in the virtual address space of a process. The VirtualQuery and VirtualQueryEx
 // functions use this structure  :)

//*typedef struct _MEMORY_BASIC_INFORMATION { // mbi
//*    PVOID BaseAddress;            // base address of region
//*    PVOID AllocationBase;         // allocation base address
//*    DWORD AllocationProtect;      // initial access protection
//*    DWORD RegionSize;             // size, in bytes, of region
//*    DWORD State;                  // committed, reserved, free
//*    DWORD Protect;                // current access protection
//*    DWORD Type;                   // type of pages
//*} MEMORY_BASIC_INFORMATION;
//*typedef MEMORY_BASIC_INFORMATION *PMEMORY_BASIC_INFORMATION;
 MEMORY_BASIC_INFORMATION mInfo;

 HMODULE  hModHookDll;
 HANDLE  hSnApShot;
 BOOL  bOk;

//Describes an entry from a list that enumerates the modules used by a specified process.
//*typedef struct tagMODULEENTRY32 {
//*    DWORD   dwSize;
//*    DWORD   th32ModuleID;
//*    DWORD   th32ProcessID;
//*    DWORD   GlblcntUsage;
//*    DWORD   ProccntUsage;
//*    BYTE  * modBaseAddr;
//*    DWORD   modBaseSize;
//*    HMODULE hModule;
//*    char    szModule[MAX_MODULE_NAME32 + 1];
//*    char    szExePath[MAX_PATH];
//*} MODULEENTRY32;
//*typedef MODULEENTRY32 *  PMODULEENTRY32;
//*typedef MODULEENTRY32 *  LPMODULEENTRY32;
 MODULEENTRY32 me = {sizeof(MODULEENTRY32)};

 if (phk->pszAPINAme == NULL||phk->pszCAllerModuleNAme == NULL
  ||phk->pfnOriginApiAddress == NULL){
  return FALSE;
 }
//如果phk->hModCAllerModule 是 NULL 的话,,表示hook自己??还得往下看才知道 :)
 if (phk->hModCAllerModule == NULL){

  //取得从_SetApiHookUp地址开始的一个页面的信息
  VirtualQuery(_SetApiHookUp,&mInfo,sizeof(mInfo));
  //得到函数_SetApiHookUp的地址
  hModHookDll = (HMODULE)mInfo.AllocationBase ;///我靠! 没错,,逗是基址 单步的时候看到这里是0x00400000
//快照,,以前在pslist里用过的 :)
  //TH32CS_SNAPMODULE Includes the module list of the specified process in the snapshot.
  //还好,,:) 是在指定进程内的
  hSnApShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0);
  //找到一个了 :)
  //这个循环看上去很疯狂啊
  //只要不是自己所在的MODULE,全都给_SetApiHookUp一遍,,但全是本进程的
  //me.hModule是Handle to the module in the context of the owning process.
  //那它是不是地址呢???????如果不是的话,,那上边的那个问题怎么解决???
  //(pThunk = (PIMAGE_THUNK_DATA)((PBYTE)phk->hModCAllerModule + pImportDesc->FirstThunk );)
  bOk = Module32First(hSnApShot,&me);////单步时,,me.hModule是0x00400000 恩,,基址,,没错
  while(bOk){
   if (me.hModule != hModHookDll){  ////单步时 第一次me.hModule和hModHookDll都是0x00400000可能这时是同一个Module,第2次就不一样了,,开始是本进程中的其他Module了 :)
    phk->hModCAllerModule = me.hModule ;
    _SetApiHookUp(phk);
   }
   bOk = Module32Next(hSnApShot,&me);
  }
  phk->hModCAllerModule = NULL;
  return FALSE;
 }else{
  //如果指定了phk->hModCAllerModule的话,,就不会随便_SetApiHookUp
  return _SetApiHookUp(phk);
 }
 return FALSE;
}
//------------------------------------------------------------------------------
BOOL UnhookWindowsAPIHooks(PAPIHOOK32_ENTRY lpHk)
{
 //整个一个逆过程 :) pfnOriginApiAddress 和 pfnDummyFuncAddress调个个儿
 PROC temp;
 temp = lpHk->pfnOriginApiAddress ;
 lpHk->pfnOriginApiAddress = lpHk->pfnDummyFuncAddress ;
 lpHk->pfnDummyFuncAddress = temp;
 return SetWindowsAPIHook(lpHk);
}
//------------------------------------------------------------------------------
//保存原地址
PROC lpAdder = MessageBoxA;
int WINAPI MyMessAgeBoxA(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCAption,UINT uType)
{
 return lpAdder(NULL,"new","new",MB_OK);
}
//------------------------------------------------------------------------------
int main(void)
{
 //哈哈 终于开始啦
 APIHOOK32_ENTRY pe;
 pe.pszAPINAme    = "MessageBoxA";
 pe.pszCAllerModuleNAme  = "USER32.DLL";//区分大小写
 pe.pfnOriginApiAddress  = MessageBoxA;
 pe.pfnDummyFuncAddress  = MyMessAgeBoxA;
 pe.hModCAllerModule   = NULL;

 //lpAdder = MessageBoxA;

 SetWindowsAPIHook(&pe);
 MessageBox(NULL,"old","old",MB_OK);

 UnhookWindowsAPIHooks(&pe);
 MessageBox(NULL,"old","old",MB_OK);
}
//------------------------------------------------------------------------------

0 0

相关博文

我的热门文章

img
取 消
img