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

原创 2004年09月21日 22:52:00

还是没弄会,,连日记也没心情写,,看了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);
}
//------------------------------------------------------------------------------

RMQ问题——ST算法

比赛当中,常会出现RMQ问题,即求区间最大(小)值。我们该怎样解决呢? 主要方法有线段树、ST、树状数组、splay。例题题目描述2008年9月25日21点10分,酒泉卫星发射中心指控大厅里,随着指...
  • A1847225889
  • A1847225889
  • 2017年08月26日 15:34
  • 101

【专题】RMQ

RMQ是英文Range Maximum(Minimum) Query的缩写,顾名思义是用来求某个区间内的最大值或最小值,通常用在要多次询问一些区间的最值的问题中。 RMQ的原理实际上是动态规划,...
  • cdy1206473601
  • cdy1206473601
  • 2017年01月17日 15:34
  • 153

RMQ问题之ST算法

转自 点击打开链接 ST算法的基本原理百度一下就可以知道   RMQ(Range Minimum/Maximum Query)问题是求区间最值问题。可以写一个线段树,但是预处理和查询的...
  • qq_16843991
  • qq_16843991
  • 2014年12月16日 16:11
  • 305

针对RMQ问题的ST算法

RMQ问题,即求区间最大最小值的问题:对于长度为N的数列,询问若干次RMQ(A,I,J)(I   我们可以采取朴素的直接搜的算法,如果数据非常大的话,直接搜就会爆时间爆的很惨。然后我们可以采取二...
  • fqh1379
  • fqh1379
  • 2015年02月08日 08:43
  • 326

郁闷的一天~

     最近总觉得很倒霉,工作不是很顺利,程序测试出了很多BUG,而且老是些旧问题。5.1节估计又要泡汤了,工作没完成不加班才怪。感觉好累啊~真有点不想上班了,什么时候才能轻松的休息一下啊!...
  • zoujing520
  • zoujing520
  • 2008年04月28日 20:35
  • 127

9月23日 星期日 阴

今天还是感冒了。待在寝室里休息,没有别处可去。就花些时间,把CSDN上的BLOG调整下,主要的是细化了分类。一直用不少网站的BLOG,可是似乎感觉都不是很好。也许更适合在技术BLOG上写东西。这个月出...
  • adousen
  • adousen
  • 2007年09月23日 11:19
  • 506

9月21日

我主要看动态规划,这几天看的是状态压缩部分,首先状态压缩适合用的题目是,具有DP问题的特性,但是状态中所包含的信息过多,如果要用数组来保存状态的话需要四维以上的数组。于是,我们就需要通过状态压缩来保存...
  • qq_37808579
  • qq_37808579
  • 2017年09月21日 22:28
  • 26

总结(9月21日)

到目前为止,项目没接到前,只能靠毅力去做了,每天只有5小时的有效时间,通过这两周看,同时完成很多东西是基本上不可能的,所以,捡着重点去干,也就是说,对于每周25小时有个合理安排,按照师兄说的去做吧,起...
  • directx3d_beginner
  • directx3d_beginner
  • 2013年09月21日 09:44
  • 365

2017年9月3日周记

回顾:      开学的第一周的第一个周末,回顾这一周感觉时间过得非常快,课程第一周都比较少,早上总是赖床,上课还是一如既往的坐在第一排,但是有了专接本的和我们一起上课感觉上课前课堂变得嘈杂了,不是很...
  • wjf1997
  • wjf1997
  • 2017年09月03日 17:32
  • 230

郁闷了一天的hibernate

项目在pc上运行的很好。今天安装到pad上却不行。搞了一天,差点搞死了。 郁闷的是,为什么同样的代码,在pc上运行的很好,在pad上却不行呢。 要放弃的时候才发现是hibernate3的原因。可能...
  • naughty610
  • naughty610
  • 2012年01月12日 21:11
  • 427
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:9月21日,,郁闷了一天,,该死的hook
举报原因:
原因补充:

(最多只允许输入30个字)