Win2K下的Api函数的拦截

该博客主要讲述了Win2K系统下对Api函数的拦截相关内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Win2K下的Api函数的拦截
2007-01-01 17:09
Api拦截并不是一个新的技术,很多商业软件都采用这种技术。对windows的Api函数的拦截,不外乎两种方法,第一种是Mr. Jeffrey Richter 的修改exe文件的模块输入节,种方法,很安全,但很复杂,而且有些exe文件,没有Dll的输入符号的列表,有可能出现拦截不到的情况。第二种方法就是常用的JMP XXX的方法,虽然很古老,却很简单实用。 
   本文一介绍第二种方法在Win2k下的使用。第二种方法,Win98/me 下因为进入Ring0级的方法很多,有LDT,IDT,Vxd等方法,很容易在内存中动态修改代码,但在Win2k下,这些方法都不能用,写WDM太过复杂,表面上看来很难实现, 
其实不然。Win2k为我们提供了一个强大的内存Api操作函数---VirtualProtectEx,WriteProcessMemeory,ReadProcessMemeory,有了它们我们就能在内存中动态修改代码了,其原型为: 
  BOOL VirtualProtectEx( 
  HANDLE hProcess,  // 要修改内存的进程句柄 
  LPVOID lpAddress, // 要修改内存的起始地址 
  DWORD dwSize, // 修改内存的字节 
  DWORD flNewProtect, // 修改后的内存属性 
  PDWORD lpflOldProtect // 修改前的内存属性的地址 
   ); 
   BOOL WriteProcessMemory( 
  HANDLE hProcess, // 要写进程的句柄 
  LPVOID lpBaseAddress, // 写内存的起始地址 
  LPVOID lpBuffer, // 写入数据的地址 
  DWORD nSize, // 要写的字节数 
  LPDWORD lpNumberOfBytesWritten // 实际写入的子节数 
  ); 
  BOOL ReadProcessMemory( 
  HANDLE hProcess, // 要读进程的句柄 
  LPCVOID lpBaseAddress,  // 读内存的起始地址 
  LPVOID lpBuffer, // 读入数据的地址 
  DWORD nSize, // 要读入的字节数 
  LPDWORD lpNumberOfBytesRead // 实际读入的子节数 
   ); 
具体的参数请参看MSDN帮助。在Win2k下因为Dll和所属进程在同一地址空间,这点又和Win9x/me存在所有进程存在共享的地址空间不同, 
因此,必须通过钩子函数和远程注入进程的方法,现以一个简单采用钩子函数对MessageBoxA进行拦截例子来说明: 
其中Dll文件为: 
   HHOOK g_hHook; 
   HINSTANCE g_hinstDll; 
   FARPROC pfMessageBoxA; 
   int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText,LPCTSTR lpCaption,UINT uType); 
   BYTE OldMessageBoxACode[5],NewMessageBoxACode[5]; 
   HMODULE hModule ; 
   DWORD dwIdOld,dwIdNew; 
   BOOL bHook=false; 
   void HookOn(); 
   void HookOff(); 
   BOOL init(); 
LRESULT WINAPI MousHook(int nCode,WPARAM wParam,LPARAM lParam); 
BOOL APIENTRY DllMain( HANDLE hModule, 
  DWORD ul_reason_for_call, 
  LPVOID lpReserved 
  ) 

   switch (ul_reason_for_call) 
   { 
   case DLL_PROCESS_ATTACH: 
   if(!init()) 
   { 
   MessageBoxA(NULL,"Init","ERROR",MB_OK); 
   return(false); 
   } 
   case DLL_THREAD_ATTACH: 
   case DLL_THREAD_DETACH: 
   case DLL_PROCESS_DETACH: 
   if(bHook) UnintallHook();  
   break; 
   } 
   return TRUE; 

LRESULT WINAPI Hook(int nCode,WPARAM wParam,LPARAM lParam)//空的钩子函数 

   
   return(CallNextHookEx(g_hHook,nCode,wParam,lParam)); 

HOOKAPI2_API BOOL InstallHook()//输出安装空的钩子函数 
{  
  g_hinstDll=LoadLibrary("HookApi2.dll"); 
  g_hHook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)Hook,g_hinstDll,0); 
  if (!g_hHook) 
  { 
   MessageBoxA(NULL,"SET ERROR","ERROR",MB_OK); 
   return(false); 
  } 
  
   
  return(true); 

HOOKAPI2_API BOOL UninstallHook()//输出御在钩子函数 

  
   return(UnhookWindowsHookEx(g_hHook)); 


BOOL init()//初始化得到MessageBoxA的地址,并生成Jmp XXX(MyMessageBoxA)的跳转指令 

   hModule=LoadLibrary("user32.dll"); 
   pfMessageBoxA=GetProcAddress(hModule,"MessageBoxA"); 
   if(pfMessageBoxA==NULL) 
   return false; 
   _asm 
   { 
   lea edi,OldMessageBoxACode 
   mov esi,pfMessageBoxA 
   cld 
   movsd 
   movsb 
   } 
   NewMessageBoxACode[0]=0xe9;//jmp MyMessageBoxA的相对地址的指令 
   _asm 
   { 
   lea eax,MyMessageBoxA 
   mov ebx,pfMessageBoxA 
   sub eax,ebx 
   sub eax,5 
   mov dword ptr [NewMessageBoxACode+1],eax 
   } 
   dwIdNew=GetCurrentProcessId(); //得到所属进程的ID 
   dwIdOld=dwIdNew; 
   HookOn();//开始拦截 
   return(true); 


int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText,LPCTSTR lpCaption, UINT uType )//首先关闭拦截,然后才能调用被拦截的Api 函数 
{  
   int nReturn=0; 
   HookOff(); 
   nReturn=MessageBoxA(hWnd,"Hook",lpCaption,uType); 
   HookOn(); 
   return(nReturn); 

void HookOn() 

   HANDLE hProc; 
   dwIdOld=dwIdNew; 
   hProc=OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld);//得到所属进程的句柄 
   VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld);//修改所属进程中MessageBoxA的前5个字节的属性为可写 
   WriteProcessMemory(hProc,pfMessageBoxA,NewMessageBoxACode,5,0);//将所属进程中MessageBoxA的前5个字节改为JMP 到MyMessageBoxA 
   VirtualProtectEx(hProc,pfMessageBoxA,5,dwIdOld,&dwIdOld);//修改所属进程中MessageBoxA的前5个字节的属性为原来的属性 
   bHook=true; 

void HookOff()//将所属进程中JMP MyMessageBoxA的代码改为Jmp MessageBoxA 

   HANDLE hProc; 
   dwIdOld=dwIdNew; 
   hProc=OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld); 
   VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld); 
   WriteProcessMemory(hProc,pfMessageBoxA,OldMessageBoxACode,5,0); 
   VirtualProtectEx(hProc,pfMessageBoxA,5,dwIdOld,&dwIdOld); 
   bHook=false; 

//测试文件: 
int APIENTRY WinMain(HINSTANCE hInstance, 
  HINSTANCE hPrevInstance, 
  LPSTR  lpCmdLine, 
  int  nCmdShow) 

   
   if(!InstallHook()) 
   { 
   MessageBoxA(NULL,"Hook Error!","Hook",MB_OK); 
   return 1; 
   } 
  MessageBoxA(NULL,"TEST","TEST",MB_OK);//可以看见Test变成了Hook,也可以在其他进程中看见 
   if(!UninstallHook()) 
   { 
   MessageBoxA(NULL,"Uninstall Error!","Hook",MB_OK); 
   return 1; 
   } 
   return 0; 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值