VB 源码VC 源码ASP源码JSP源码PHP源码CGI源码FLASH源码素材模板C 源程序常用软件文档中心其他程序

Win2000/NT

注册表
经验技巧
Linux
Win9x/ME
Win2000/NT
WinXP/Server

本类阅读TOP10

·Windows 2000不能启动时
·Windows 2000 系统服务设置(建议配置)
·Windows2000系统如何找回丢失的管理员密码
·Windows 2003 激活和优化大全
·Windows 2000 设置与操作技巧之性能提高篇
·解读多重启动引导文件——BOOT.INI
·Windows 2000自带传真软件使用攻略
·Win 2000如何安装配置防火墙
·Windows 2000 的IP路由
·Windows 2000安全设置手册

精品推荐
Win2K下的Api函数的拦截

作者:佚名 来源:月光软件站 加入时间:2005-3-1 月光软件站


这么多高手在这里,哎,小弟愿意向各位高手学习
  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;
}



相关文章
  • PHP与MySQL数据库操作函数详解
  • ASP.NET提供文件下载函数
  • asp常用函数
  • ASP脚本变量、函数,过程和条件语句
  • 相关软件

  • 混音函数演示程序  
  • 封装有关注册表操作的函数  
  • 常用的4个文件函数  
  • 数字处理函数包  
  • 编写可变参数的函数  
  • 使用一个简单的函数调用  
  • TC 函数库  
  • GNU系统 MS-DOS 函数据库  
  • C 语言函数库  
  • 测试复杂指令系统的函数的执行时间  



  • 月光软件程序下载编程文档电脑教程网站设计网址导航网络文学游戏天地幽默笑话生活休闲写作范文安妮宝贝
    电脑技术编程开发网络专区谈天说地情感世界游戏元素分类游戏热门游戏体育运动手机专区业余爱好影视沙龙
    音乐天地数码广场教育园地科学大观古今纵横谈股论金人文艺术医学保健动漫图酷二手专区地方风情各行各业

    月光软件站·版权所有