首页
社区
课程
招聘
[原创]妙不可言――挂接ExitWindowsEx
发表于: 2005-6-15 13:19 16900

[原创]妙不可言――挂接ExitWindowsEx

2005-6-15 13:19
16900

这篇文章在今年《黑客防线》第5期上发表过。 大虾就不必看了,浪费时间   看这个版人气不旺,就帖出来充充数
不过现在用户态下的API HOOK已经很普遍,没什么稀奇的了,有空的话下次写些底层东东的吧。

===========================================
Author:xyzreg[E.S.T]
URL:www.xyzreg.net
E-mail:xyzreg@163.com
=============================================

   随着安全意识的不断提高,许多软件都增强的自我保护性,结束其进程时将会调用ExitWindowsEx函数关机或者重启。这种技术在收费管理系统、病毒木马、加壳软件、反破解领域里很常见,因而采用APIHOOK技术挂接ExitWindowsEx函数使其失效,对与我们查杀病毒以及软件破解是很有用的。当然还能运用它免费上网呢!不可思议吧?现在许多收费软件都采取会员制,下机时点结帐下机按钮后,客户端就发送数据报给主机,告知用户已下机从而停止记费,同时重新启动或关闭计算机。我们挂接ExitWindowsEx后就可以让机子不重启,怎么样?免费上网还可以这么搞,嘿嘿,你没想到吧?(俺正得意,突然面前飞来小李飞刀,我闪,好险啦!)
   
      记得去年第12期的黑防上有篇关于APIHOOK的文章, 那篇所采用的方法是陷阱法(改写内存地址jmp法),我这里就用另外一种方法吧――改写IAT(引入表)法。这种方法的优点是较稳定,不要担心线程同步的问题。
APIHOOK技术应用广泛,常用于屏幕取词、网络防火墙、病毒木马、加壳软件、串口红外通信、游戏外挂、Internet通信等领域。HOOK的中文意思就是钩子,APIHOOK就是钩住API,对API进行预处理,先执行我们的函数。这类思路是不是在我们中华民族文化瑰宝《三十六计》中有所体现啦!俺们先辈实在太伟大了,敬佩中。其实HOOK是黑客领域里的一种不可或缺的思想。是不是有点跑题了?言归正传。

       改写IAT表法实现APIHOOK的思路如下:根据PE文件格式穷举模块中的image_impot_desciptor引入函数数组, 检查进程空间里是否有要HOOK的API的所在的DLL,如果有则通过WiteProcessMemory、VirtualProtect等函数改写IAT中的目标API函数地址,将其改为我们自定义函数的地址。由于地址不能跨进程引用,所以我们可以使用Windows消息钩子将我们APIHOOK所在的DLL注入到其他进程里, 为了取得较好的效果,推荐使用WH_GETMESSAGE类性的钩子。

现在就来解析核心代码:
void WINAPI HookOneAPI(LPCTSTR pszCalleeModuleName, PROC pfnOriginApiAddress, PROC pfnDummyFuncAddress, HMODULE hModCallerModule)
//对于挂接ExitWindowsEx函数而言,pszCalleeModuleName为user32.dll, pfnOriginApiAddress为ExitWindowsEx,pfnDummyFuncAddress 为MyExitWindowsEx
{
ULONG size;

//获取指向PE文件中的Import中IMAGE_DIRECTORY_DESCRIPTOR数组的指针

PIMAGE_IMPORT_DESCRIPTOR  pImportDesc=
(PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hModCallerModule,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&size);
  //查找记录,查找是否存在目标API函数ExitWindwosEx所在的user32.dll
for (;pImportDesc->Name;pImportDesc++)
{
  LPSTR pszDllName = (LPSTR)((PBYTE)hModCallerModule+pImportDesc->Name);
  if (lstrcmpiA(pszDllName,pszCalleeModuleName) == 0)
   break;
}
//寻找我们所要HOOK的ExitWindwosEx函数
PIMAGE_THUNK_DATA pThunk =  
(PIMAGE_THUNK_DATA)((PBYTE)hModCallerModule+pImportDesc->FirstThunk);
for (;pThunk->u1.Function;pThunk++)
{
  //ppfn记录了与IAT项相应的函数的地址
  PROC * ppfn= (PROC *)&pThunk->u1.Function;   
  if (*ppfn == pfnOriginApiAddress)  
  {
   //如果地址相同,就说明找到了我们要HOOK的函数,进行改写,将其指向我们所
定义的函数
   WriteProcessMemory(GetCurrentProcess(),ppfn,&(pfnDummyFuncAddress),
    sizeof(pfnDummyFuncAddress),NULL);
   return;
  }
}
}

若想HOOK所有模块对目标API函数的调用,则需要使用ToolHelp函数枚举所有模块,然后逐一调用HookOneAPI函数。关键代码如下:
BOOL WINAPI HookAllAPI(LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress,
        PROC pfnDummyFuncAddress,HMODULE hModCallerModule)
{
  if (hModCallerModule == NULL)
{
  MEMORY_BASIC_INFORMATION mInfo;
  HMODULE hModHookDLL;
  HANDLE hSnapshot;
  MODULEENTRY32 me = {sizeof(MODULEENTRY32)};
  //MODULEENTRY32:存放被指定进程所应用的模块信息的结构
  VirtualQuery(HookOneAPI,&mInfo,sizeof(mInfo));
  hModHookDLL=(HMODULE)mInfo.AllocationBase;   
  hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0);
  BOOL bOk = Module32First(hSnapshot,&me);
  while (bOk)
  {
   if (me.hModule != hModHookDLL)
   {
    hModCallerModule = me.hModule;//赋值
    //对每一个模块进行HOOK
    HookOneAPI(pszCalleeModuleName,pfnOriginApiAddress,
     pfnDummyFuncAddress,hModCallerModule);
   }
   bOk = Module32Next(hSnapshot,&me);
  }
  return TRUE;   
}
}

接着就要调用调用SetWindowsHookEx来安装WH_GETMESSAGE 类型的钩子把APIHOOK的DLL映射到其它进程空间里:SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)GetMsgProc,hmodDll,dwThreadId)。 GetMsgProc函数里只要写上return CallNextHookEx(hHook,code,wParam,lParam);即可,实现循环。

现在就剩下自定义ExitWindowsEx函数了,我们只需注意参数格式和原函数一样即可,自定义的MyExitWindowsEx函数什么都不做,这样就实现的取消关机的功能了。
另外还有一点要注意一下,对于winlogon.exe,我们要提升权限至调试权限,代码如下:
if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
{
  LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&luid);
  tp.PrivilegeCount=1;
  tp.Privileges[0].Luid=luid;
  tp.Privileges[0].Attributes=bUp?SE_PRIVILEGE_ENABLED:0;
  if(!AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL))
  {
   MessageBox(NULL,"提升权限失败!","",0);
   return;
  }
}

整个框架就是这样了,由于篇幅原因,具体的不再细说了。光盘内收有网上留传的完整的程序代码,具体细节大家可参阅。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 8
支持
分享
最新回复 (12)
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
2
支持一下。

不足之处是只对当前已经加载的模块实现HOOK API,
而对新加载的模块则忽略。
2005-6-15 17:33
0
雪    币: 126
活跃值: (61)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
最初由 北极星2003 发布
支持一下。

不足之处是只对当前已经加载的模块实现HOOK API,
而对新加载的模块则忽略。


恩,那次写这篇文章主要是为了说明挂接ExitWindowsEx的妙处,HOOK就没有深写。但只要梢加修改,比如挂接CsrCreateProcess以及LoadLibrary就可以了对新加载的HOOK了

其实,如果NT平台下真正要做什么的话,还是hook native api好……   
2005-6-15 21:13
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
我来顶一下笔头,顶顶顶。
2005-6-16 03:25
0
雪    币: 519
活跃值: (1223)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
5
支持一下,另外当代码比较复杂的时候,建议大家发帖时把代码用[code]标签括起来,这样缩进,换行什么的会更清楚一些.
2005-6-16 09:35
0
雪    币: 328
活跃值: (925)
能力值: ( LV9,RANK:1010 )
在线值:
发帖
回帖
粉丝
6
支持一下!
2005-6-16 11:42
0
雪    币: 229
活跃值: (168)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
7
最初由 xyzreg 发布


恩,那次写这篇文章主要是为了说明挂接ExitWindowsEx的妙处,HOOK就没有深写。但只要梢加修改,比如挂接CsrCreateProcess以及LoadLibrary就可以了对新加载的HOOK了

其实,如果NT平台下真正要做什么的话,还是hook native api好……

CsrCreateProcess是什么函数?没听过,能解释一下吗?
2005-6-16 14:12
0
雪    币: 126
活跃值: (61)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
最初由 落叶树 发布
我来顶一下笔头,顶顶顶。

THX
2005-6-17 15:36
0
雪    币: 126
活跃值: (61)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
最初由 RoBa 发布
支持一下,另外当代码比较复杂的时候,建议大家发帖时把代码用[code]标签括起来,这样缩进,换行什么的会更清楚一些.

好的
2005-6-17 15:39
0
雪    币: 126
活跃值: (61)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
最初由 hangj 发布

CsrCreateProcess是什么函数?没听过,能解释一下吗?

CsrCreateProcess是Csrss里的函数,所有进程的创建都要触发Csrss中的CsrCreateProcess。yythac的几个程序都有运用,老兄有兴趣可以看看。
2005-6-17 15:55
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
不错!支持!
2005-6-23 18:06
0
雪    币: 229
活跃值: (168)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
12
最初由 xyzreg 发布

CsrCreateProcess是Csrss里的函数,所有进程的创建都要触发Csrss中的CsrCreateProcess。yythac的几个程序都有运用,老兄有兴趣可以看看。


非常感谢!!
2005-6-24 14:22
0
雪    币: 538
活跃值: (32)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
恩,的确是看过了....很感情趣的说
2005-6-25 20:34
0
游客
登录 | 注册 方可回帖
返回
//