Advertisement
Guest User

Enum Message Hooks

a guest
Apr 24th, 2016
623
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <Windows.h>
  3. #include "DrvCtrl.h"
  4.  
  5. bool EnableDebugPrivilege()
  6. {
  7.     HANDLE hToken;
  8.     LUID sedebugnameValue;
  9.     TOKEN_PRIVILEGES tkp;
  10.     if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
  11.     {
  12.         return   FALSE;
  13.     }
  14.     if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue))
  15.     {
  16.         CloseHandle(hToken);
  17.         return false;
  18.     }
  19.     tkp.PrivilegeCount = 1;
  20.     tkp.Privileges[0].Luid = sedebugnameValue;
  21.     tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  22.     if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL))
  23.     {
  24.         CloseHandle(hToken);
  25.         return false;
  26.     }
  27.     return true;
  28. }
  29.  
  30. typedef struct _MEMORY_CHUNKS {
  31.     UINT Address;      //内核内存地址指针(要读的数据)
  32.     UINT pData;         //用户层内存地址指针(存放读出的数据)
  33.     UINT Length;      //读取的长度
  34. }MEMORY_CHUNKS, *PMEMORY_CHUNKS;
  35.  
  36. typedef enum _SYSDBG_COMMAND {
  37.     //以下5个在Windows NT各个版本上都有
  38.     SysDbgGetTraceInformation = 1,
  39.     SysDbgSetInternalBreakpoint = 2,
  40.     SysDbgSetSpecialCall = 3,
  41.     SysDbgClearSpecialCalls = 4,
  42.     SysDbgQuerySpecialCalls = 5,
  43.  
  44.     // 以下是NT 5.1 新增的
  45.     SysDbgDbgBreakPointWithStatus = 6,
  46.  
  47.     //获取KdVersionBlock
  48.     SysDbgSysGetVersion = 7,
  49.  
  50.     //从内核空间拷贝到用户空间,或者从用户空间拷贝到用户空间
  51.     //但是不能从用户空间拷贝到内核空间
  52.     SysDbgCopyMemoryChunks_0 = 8,
  53.     //SysDbgReadVirtualMemory = 8,
  54.  
  55.     //从用户空间拷贝到内核空间,或者从用户空间拷贝到用户空间
  56.     //但是不能从内核空间拷贝到用户空间
  57.     SysDbgCopyMemoryChunks_1 = 9,
  58.     //SysDbgWriteVirtualMemory = 9,
  59.  
  60.     //从物理地址拷贝到用户空间,不能写到内核空间
  61.     SysDbgCopyMemoryChunks_2 = 10,
  62.     //SysDbgReadVirtualMemory = 10,
  63.  
  64.     //从用户空间拷贝到物理地址,不能读取内核空间
  65.     SysDbgCopyMemoryChunks_3 = 11,
  66.     //SysDbgWriteVirtualMemory = 11,
  67.  
  68.     //读写处理器相关控制块
  69.     SysDbgSysReadControlSpace = 12,
  70.     SysDbgSysWriteControlSpace = 13,
  71.  
  72.     //读写端口
  73.     SysDbgSysReadIoSpace = 14,
  74.     SysDbgSysWriteIoSpace = 15,
  75.  
  76.     //分别调用RDMSR@4和_WRMSR@12
  77.     SysDbgSysReadMsr = 16,
  78.     SysDbgSysWriteMsr = 17,
  79.  
  80.     //读写总线数据
  81.     SysDbgSysReadBusData = 18,
  82.     SysDbgSysWriteBusData = 19,
  83.  
  84.     SysDbgSysCheckLowMemory = 20,
  85.  
  86.     // 以下是NT 5.2 新增的
  87.  
  88.     //分别调用_KdEnableDebugger@0和_KdDisableDebugger@0
  89.     SysDbgEnableDebugger = 21,
  90.     SysDbgDisableDebugger = 22,
  91.  
  92.     //获取和设置一些调试相关的变量
  93.     SysDbgGetAutoEnableOnEvent = 23,
  94.     SysDbgSetAutoEnableOnEvent = 24,
  95.     SysDbgGetPitchDebugger = 25,
  96.     SysDbgSetDbgPrintBufferSize = 26,
  97.     SysDbgGetIgnoreUmExceptions = 27,
  98.     SysDbgSetIgnoreUmExceptions = 28
  99. } SYSDBG_COMMAND, *PSYSDBG_COMMAND;
  100. //定义ZwSystemDebugControl函数指针类型
  101. typedef DWORD(WINAPI *ZWSYSTEMDEBUGCONTROL)(DWORD, PVOID,
  102.     DWORD, PVOID, DWORD, PVOID);
  103.  
  104. BOOL GetKernelMemory(PVOID pKernelAddr, PBYTE pBuffer, ULONG uLength)
  105. {
  106.     MEMORY_CHUNKS mc;
  107.     ULONG uReaded = 0;
  108.     mc.Address = (UINT)pKernelAddr;  //Kernel Memory Address - input
  109.     mc.pData = (UINT)pBuffer;//User Mode Memory Address  - output
  110.     mc.Length = (UINT)uLength;       //length  
  111.     ULONG st = -1;
  112.     ZWSYSTEMDEBUGCONTROL ZwSystemDebugControl = (ZWSYSTEMDEBUGCONTROL)GetProcAddress(
  113.         GetModuleHandleA("ntdll.dll"), "NtSystemDebugControl");
  114.     st = ZwSystemDebugControl(SysDbgCopyMemoryChunks_0, &mc, sizeof(MEMORY_CHUNKS), 0, 0, &uReaded);
  115.     return st == 0;
  116. }
  117.  
  118. void RKM(UINT64 Address, PVOID Buffer, SIZE_T Length)
  119. {
  120.     /*
  121.     IoControl(hMyDrv ,CTL_CODE_GEN(0x809), &Address, 8, NULL, 0);       //address
  122.     IoControl(hMyDrv ,CTL_CODE_GEN(0x80A), &Length, 8, NULL, 0);        //length
  123.     IoControl(hMyDrv ,CTL_CODE_GEN(0x804), NULL, 0, Buffer, Length);    //get buffer
  124.     */
  125.     GetKernelMemory((PVOID)Address, (PBYTE)Buffer, Length);
  126. }
  127.  
  128. void WKM(UINT64 Address, PVOID Buffer, SIZE_T Length)
  129. {
  130.     IoControl(hMyDrv ,CTL_CODE_GEN(0x809), &Address, 8, NULL, 0);       //address
  131.     IoControl(hMyDrv ,CTL_CODE_GEN(0x80A), &Length, 8, NULL, 0);        //length
  132.     IoControl(hMyDrv ,CTL_CODE_GEN(0x805), Buffer, Length, NULL, 0);    //set buffer
  133. }
  134.  
  135. UINT64 GetQWORD(UINT64 address)
  136. {
  137.     UINT64 y=0;
  138.     RKM(address,&y,8);
  139.     return y;
  140. }
  141.  
  142. UINT32 GetDWORD(UINT64 address)
  143. {
  144.     UINT32 y=0;
  145.     RKM(address,&y,4);
  146.     return y;
  147. }
  148.  
  149. PUCHAR GetPNbyET(UINT64 ethread)
  150. {
  151.     PUCHAR y = (PUCHAR)malloc(16);
  152.     IoControl(hMyDrv ,CTL_CODE_GEN(0x7FF), &ethread, 8, y, 16);
  153.     return y;
  154. }
  155.  
  156. /*
  157. lkd> dt win32k!tagsharedinfo
  158.    +0x000 psi              : Ptr64 tagSERVERINFO
  159.    +0x008 aheList          : Ptr64 _HANDLEENTRY
  160.    +0x010 HeEntrySize      : Uint4B
  161.    +0x018 pDispInfo        : Ptr64 tagDISPLAYINFO
  162.    +0x020 ulSharedDelta    : Uint8B
  163.    +0x028 awmControl       : [31] _WNDMSG
  164.    +0x218 DefWindowMsgs    : _WNDMSG
  165.    +0x228 DefWindowSpecMsgs : _WNDMSG
  166.  
  167. lkd> dt win32k!tagSERVERINFO
  168.    +0x000 dwSRVIFlags      : Uint4B
  169.    +0x008 cHandleEntries   : Uint8B
  170.    +0x010 mpFnidPfn        : [32] Ptr64     int64
  171.    +0x110 aStoCidPfn       : [7] Ptr64     int64
  172.    [省略......]
  173. */
  174.  
  175. /*win32k!_HANDLEENTRY
  176.    +0x000 phead            : Ptr64 _HEAD
  177.    +0x008 pOwner           : Ptr64 Void
  178.    +0x010 bType            : UChar
  179.    +0x011 bFlags           : UChar
  180.    +0x012 wUniq            : Uint2B*/
  181.  
  182. typedef struct _HANDLEENTRY
  183. {
  184.     UINT64  phead;
  185.     UINT64  pOwner;
  186.     UCHAR   bType;
  187.     UCHAR   bFlags;
  188.     USHORT  wUniq;
  189. }HANDLEENTRY,*PHANDLEENTRY;
  190.  
  191. /*
  192. lkd> dt win32k!taghook
  193.    +0x000 head             : _THRDESKHEAD
  194.    +0x028 phkNext          : Ptr64 tagHOOK
  195.    +0x030 iHook            : Int4B
  196.    +0x038 offPfn           : Uint8B
  197.    +0x040 flags            : Uint4B
  198.    +0x044 ihmod            : Int4B
  199.    +0x048 ptiHooked        : Ptr64 tagTHREADINFO
  200.    +0x050 rpdesk           : Ptr64 tagDESKTOP
  201.    +0x058 nTimeout         : Pos 0, 7 Bits
  202.    +0x058 fLastHookHung    : Pos 7, 1 Bit
  203. lkd> dt_THRDESKHEAD
  204. win32k!_THRDESKHEAD
  205.    +0x000 h                : Ptr64 Void
  206.    +0x008 cLockObj         : Uint4B
  207.    +0x010 pti              : Ptr64 tagTHREADINFO
  208.    +0x018 rpdesk           : Ptr64 tagDESKTOP
  209.    +0x020 pSelf            : Ptr64 UChar
  210. */
  211.  
  212. typedef struct _HOOK_INFO
  213. {
  214.     HANDLE       hHandle;                    //钩子的句柄   句柄是全局的 可以UnhookWindowsHookEx  把钩子卸掉
  215.     int          Unknown1;
  216.     PVOID        Win32Thread;                 //一个指向 win32k!_W32THREAD 结构体的指针
  217.     PVOID        Unknown2;
  218.     PVOID        SelfHook;                   //指向结构体的首地址
  219.     PVOID        NextHook;                   //指向下一个钩子结构体
  220.     int          iHookType;                 //钩子的类型, winuser.h 中有定义
  221.     PVOID        OffPfn;                    //钩子函数的地址偏移,相对于所在模块的偏移
  222.     int          iHookFlags;
  223.     int          iMod;                      //钩子函数做在模块的索引号码,通过查询 WowProcess 结构可以得到模块的基地址。
  224.     PVOID        Win32ThreadHooked;         // ???被钩的线程的结构指针,不知道
  225.     //下面还有,省略。。。
  226. } HOOK_INFO,*PHOOK_INFO;
  227.  
  228. char *GetHookType(int Id)
  229. {
  230.     switch(Id)
  231.     {
  232.         case -1:
  233.         {
  234.             return "WH_MSGFILTER";
  235.         }
  236.         case 0:
  237.         {
  238.             return "WH_JOURNALRECORD";
  239.         }
  240.         case 1:
  241.         {
  242.             return "WH_JOURNALPLAYBACK";
  243.         }
  244.         case 2:
  245.         {
  246.             return "WH_KEYBOARD";
  247.         }
  248.         case 3:
  249.         {
  250.             return "WH_GETMESSAGE";
  251.         }
  252.         case 4:
  253.         {
  254.             return "WH_CALLWNDPROC";
  255.         }
  256.         case 5:
  257.         {
  258.             return "WH_CBT";
  259.         }
  260.         case 6:
  261.         {
  262.             return "WH_SYSMSGFILTER";
  263.         }
  264.         case 7:
  265.         {
  266.             return "WH_MOUSE";
  267.         }
  268.         case 8:
  269.         {
  270.             return "WH_HARDWARE";
  271.         }
  272.         case 9:
  273.         {
  274.             return "WH_DEBUG";
  275.         }
  276.         case 10:
  277.         {
  278.             return "WH_SHELL";
  279.         }
  280.         case 11:
  281.         {
  282.             return "WH_FOREGROUNDIDLE";
  283.         }
  284.         case 12:
  285.         {
  286.             return "WH_CALLWNDPROCRET";
  287.         }
  288.         case 13:
  289.         {
  290.             return "WH_KEYBOARD_LL";
  291.         }
  292.         case 14:
  293.         {
  294.             return "WH_MOUSE_LL";
  295.         }
  296.         default:
  297.         {
  298.             return "????";
  299.         }
  300.     }
  301. }
  302.  
  303. char *GetHookFlagString(int Flag)
  304. {
  305.     if(Flag==1 || Flag==3)
  306.         return "Global";
  307.     else
  308.         return "Local";
  309. }
  310.  
  311. void EnumMsgHook()
  312. {
  313.     int i = 0;
  314.     UINT64 pgSharedInfo = (UINT64)GetProcAddress(GetModuleHandleA("user32.dll"), "gSharedInfo");
  315.     UINT64 phe = *(UINT64*)(pgSharedInfo + 8);  //+0x008 aheList          : Ptr64 _HANDLEENTRY
  316.     UINT64 count = *(UINT64*)(*(UINT64*)(pgSharedInfo) + 8);
  317.     HANDLEENTRY heStruct = {0};
  318.     HOOK_INFO Hook = {0};
  319.     for(i = 0; i < count; i ++)
  320.     {
  321.         memcpy(&heStruct, (PVOID)(phe + i * sizeof(HANDLEENTRY)), sizeof(HANDLEENTRY));
  322.         if(heStruct.bType == 5)
  323.         {
  324.             GetKernelMemory((PVOID)heStruct.phead, (PBYTE)&Hook, sizeof(HOOK_INFO));
  325.             printf("hHandle:     0x%llx\n",Hook.hHandle);
  326.             printf("iHookFlags:  %s\n",    GetHookFlagString(Hook.iHookFlags));
  327.             printf("iHookType:   %s\n",    GetHookType(Hook.iHookType));
  328.             printf("OffPfn:      0x%llx\n",Hook.OffPfn);
  329.             printf("ETHREAD:     0x%llx\n",GetQWORD((UINT64)(Hook.Win32Thread)));
  330.             printf("ProcessName: %s\n\n",  GetPNbyET(GetQWORD((UINT64)(Hook.Win32Thread))));
  331.         }
  332.     }
  333. }
  334.  
  335. int main()
  336. {
  337.     printf("%d\n", EnableDebugPrivilege());
  338.     EnumMsgHook();
  339.     getchar();
  340. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement