Windows2000下Api函数的拦截分析

来源:网络 作者: 查看:[大字体 中字体 小字体] 编辑:napl

  简介:

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

Windows2000下Api函数的拦截分析相关推荐

  1. c语言win api函数,Win2K下的Api函数的拦截

    这么多高手在这里,哎,小弟愿意向各位高手学习. Api拦截并不是一个新的技术,很多商业软件都采用这种技术.对windows的Api函数的拦截,不外乎两种方法,第一种是Mr. Jeffrey Richt ...

  2. linux如何拿到文件的返回值,linux 下read函数返回值分析

    原文出处:http://blog.chinaunix.net/space.php?uid=20558494&do=blog&id=2803003 read函数是Linux下不带缓存的文 ...

  3. MediaInfo源代码分析 2:API函数

    ===================================================== MediaInfo源代码分析系列文章列表: MediaInfo源代码分析 1:整体结构 Me ...

  4. windows 下实现函数打桩:拦截API方式

    windows 下实现函数打桩:拦截API方式 近期由于工作须要,開始研究函数打桩的方法. 由于不想对project做过多的改动,于是放弃了使用Google gmock的想法. 可是也足足困扰另外我一 ...

  5. window下键盘监控api函数详解

    在实际应用中,键盘监控是一种很常见的技术,它包括按键的记录.按键的过滤.按键的修改(映射)等.比方说,我们想统计用户的击键情况,这个就是按键的记录:我们想屏蔽某些系统键(例如Alt键.Win键),这个 ...

  6. 【Android 逆向】函数拦截 ( ARM 架构下的插桩拦截 | 完整代码示例 )

    文章目录 一.ARM 架构下的插桩拦截 二.完整代码示例 一.ARM 架构下的插桩拦截 ARM 架构下的跳转指令 : 下面的二进制数都是十六进制数 ; 323232 位指令 ; 04 F0 1F E5 ...

  7. GPIO子系统下的API函数

    GPIO子系统下的API函数 1.GPIO子系统下的API函数 1.1.gpio_request 函数 1.2. gpio_free 函数 1.3. gpio_direction_input 函数 1 ...

  8. mysql c api 函数 linux下 mysql_query_Linux C 调用MYSQL API 函数mysql_escape_string()转义插入数据...

    标签: Title:Linux C 调用MYSQL API 函数mysql_escape_string()转义插入数据 --2013-10-11 11:57 #include #include #in ...

  9. 文本输出API函数:TextOut,ExtTextOut,DrawText,DrawTextEx,PolyTextOut,TabbedTextOut

    前阵子由于做一个软件需要用Detour库HOOK其它程序的文本输出,以实现对第三方程序文字的监控. 对这六个文本输出API函数:TextOut,ExtTextOut,DrawText,DrawText ...

最新文章

  1. LFS、BLFS、ALFS、HLFS的区别
  2. C++之const修饰得到是谁
  3. Python从数据库读取大量数据批量写入文件的方法
  4. POJ3764 The xor-longest Path(Trie树)
  5. “玲珑杯”线上赛 Round #15 河南专场 F 咸鱼文章
  6. scala 获取数组中元素_从Scala中的元素列表中获取随机元素
  7. 新UI云开发壁纸小程序源码(新修复版带编译教程)
  8. srand和rand函数_了解C ++ rand()和srand()函数
  9. 最小标示法模板 poj1509
  10. 如何在Linux上安装Oracle客户端连接工具sqlplus
  11. 干货!技术分享:如何写好一篇论文
  12. C语言12进制逆序输出,C语言将整数以二进制逆序
  13. 局域网即时通讯软件应该怎么选择
  14. cocos2d实现语音_【Cocos Creator与C++知识分享】Creator接入呀呀语音SDK
  15. 那曲虫草价目表2022
  16. 用VUE实现一个具有登陆、注册等功能的网站【详细步骤】
  17. OPS and So on.
  18. 一个普通玩家眼中的网博会
  19. 汉语编程工具易语言即学即用教程pdf
  20. 微信小程序图片的加载

热门文章

  1. 理解Flex itemRenderer(5)--效率
  2. MSDN Magazine推出Custom Report Item示例ProgressTracker CRI
  3. HD_2092整数解
  4. poj 1451(Trie)
  5. System.Object 是 .NET 中所有类型的根吗?
  6. EasyNVR支持的摄像机、NVR设备接入类型以及关于国标设备是否支持接入EasyNVR无插件流媒体服务器...
  7. 【bzoj2460】[BeiJing2011]元素 贪心+高斯消元求线性基
  8. 紫书动规 例题9-10 UVA - 1626 Brackets sequence 区间dp
  9. iOS学习 plist读取和写入文件
  10. The Art of Unix Programming