zoukankan      html  css  js  c++  java
  • 枚举和卸载消息钩子[转]

    Copy code
    #include <stdio.h>
    #include <windows.h>
    typedef enum _DEBUG_CONTROL_CODE {
    SysDbgReadVirtualMemory = 8
    } DEBUG_CONTROL_CODE, *PDEBUG_CONTROL_CODE;
    typedef struct _MEMORY_CHUNKS {
    ULONG Address;
    PVOID Data;
    ULONG Length;
    } MEMORY_CHUNKS, *PMEMORY_CHUNKS;
    typedef DWORD (WINAPI *ZWSYSTEMDEBUGCONTROL)(DWORD,PVOID,DWORD,PVOID,DWORD,PVOID);
    ZWSYSTEMDEBUGCONTROL ZwSystemDebugControl;
    typedef struct tagSERVERINFO
    {
    WORD wRIPFlags;
    WORD wSRVIFlags;
    WORD wRIPPID;
    WORD wRIPError;
    DWORD cHandleEntries; //句柄数目
    }SERVERINFO,*PSERVERINFO;
    typedef struct tagSHAREDINFO {
    struct tagSERVERINFO *psi;
    struct _HANDLEENTRY *aheList; // handle table pointer
    struct tagDISPLAYINFO *pDispInfo; // global displayinfo
    ULONG ulSharedDelta; // delta between client and kernel mapping of ...
    LPWSTR pszDllList;
    } SHAREDINFO, *PSHAREDINFO;
    typedef struct
    {
    HANDLE hHandle; //钩子的句柄
    DWORD Unknown1;
    PVOID Win32Thread; //一个指向 win32k!_W32THREAD 结构体的指针
    PVOID Unknown2;
    PVOID SelfHook; //指向结构体的首地址
    PVOID NextHook; //指向下一个钩子结构体
    int iHookType; //钩子的类型, winuser.h 中有定义
    DWORD OffPfn; //钩子函数的地址偏移,相对于所在模块的偏移
    int iHookFlags;
    int iMod; //钩子函数做在模块的索引号码,通过查询 WowProcess 结构可以得到模块的基地址。
    PVOID Win32ThreadHooked; // ???被钩的线程的结构指针,不知道
    } HOOK_INFO,*PHOOK_INFO;
    typedef struct _HEAD
    {
    DWORD hObject;
    DWORD cLockObj;
    }HEAD,*PHEAD;
    typedef struct _HANDLEENTRY {
    PHOOK_INFO phead; /* pointer to the real object *///也就是下面的 HOOK_INFO 结构
    PVOID pOwner; /* pointer to owning entity (pti or ppi) */
    BYTE bType; /* type of object */
    BYTE bFlags; /* flags - like destroy flag */
    WORD wUniq; /* uniqueness count */
    } HANDLEENTRY, *PHANDLE_ENTRY;
    typedef struct _CLIENT_ID
    {
    DWORD PID;
    DWORD TID;
    }CLIENTID,*PCLIENTID;
    typedef struct _W32THREAD
    {
    ULONG pEThread;
    }W32THREAD,*PW32THREAD;
    void showInfo(PVOID pWin32Thread)
    {
    MEMORY_CHUNKS QueryBuff;
    DWORD* pEThread = new DWORD;
    QueryBuff.Address = (DWORD)pWin32Thread;
    QueryBuff.Data = pEThread;
    QueryBuff.Length = sizeof(DWORD);
    DWORD RetLen;
    ZwSystemDebugControl(
    SysDbgReadVirtualMemory,
    &QueryBuff,
    sizeof(MEMORY_CHUNKS),
    NULL,
    0,
    &RetLen);
    //已经获取了ETHREAD的地址,偏移加上0x1ec,是CLIENTID内容
    DWORD pClientID = (DWORD)(*pEThread) + 0x1ec;
    PCLIENTID pClientBuf = new CLIENTID;
    QueryBuff.Address = (DWORD)pClientID;
    QueryBuff.Data = pClientBuf;
    QueryBuff.Length = sizeof(CLIENTID);
    ZwSystemDebugControl(
    SysDbgReadVirtualMemory,
    &QueryBuff,
    sizeof(MEMORY_CHUNKS),
    NULL,
    0,
    &RetLen);
    printf("PID:%d\tTID:%d",pClientBuf->PID,pClientBuf->TID);
    }
    PSHAREDINFO shareinfo;
    PHANDLE_ENTRY phandle_entry;
    DWORD handleCount;
    int main()
    {
    //提升Debug权限
    HANDLE hT;
    OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hT);
    TOKEN_PRIVILEGES tp;
    tp.PrivilegeCount=1;
    LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tp.Privileges[0].Luid);
    tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(hT,FALSE,&tp,sizeof(tp),NULL,NULL);
    //初始化函数地址
    ZwSystemDebugControl = (ZWSYSTEMDEBUGCONTROL)GetProcAddress(
    GetModuleHandle("ntdll.dll"), "ZwSystemDebugControl" );
    HMODULE hLibModule = LoadLibrary("user32.dll");
    DWORD MyProcAddress = (DWORD)GetProcAddress(hLibModule,"UserRegisterWowHandlers");
    MyProcAddress = (DWORD)GetProcAddress(hLibModule, "UserClientDllInitialize");
    printf("LibAddr:0x%x\tProcAddress:0x%x\n",hLibModule,MyProcAddress);
    //获取gsharedInfo地址
    DWORD UserRegisterWowHandlers = (ULONG)GetProcAddress(GetModuleHandle("user32.dll"), "UserRegisterWowHandlers");
    DWORD i =0;
    for(i=UserRegisterWowHandlers; i<UserRegisterWowHandlers+0x256; i++)
    {
    //这种特征码的寻找方式 先看Nt4代码 再看dll反汇编的代码 测试特征值
    if((*(USHORT*)i==0x40c7)&&(*(BYTE*)(i+7)==0xb8))
    {
    shareinfo=(PSHAREDINFO)(*(ULONG*)(i+8));
    printf("\n0x%x\n",shareinfo);
    phandle_entry=(PHANDLE_ENTRY)shareinfo->aheList;
    handleCount = shareinfo->psi->cHandleEntries;
    printf("\n0x%x\n",phandle_entry);
    printf("\n0x%x\n\n\n",phandle_entry->phead);
    // printf("\n%ws\n\n\n",shareinfo->pszDllList);
    break;
    }
    }
    // scanf("%d",0);
    //return 0;
    DWORD count = 0;
    for(i=0;i<handleCount;i++)
    {
    if(phandle_entry[i].bType == 5)
    {
    MEMORY_CHUNKS QueryBuff;
    PHOOK_INFO pHookInfo = new HOOK_INFO;
    QueryBuff.Address = (DWORD)phandle_entry[i].phead;
    QueryBuff.Data = pHookInfo;
    QueryBuff.Length = sizeof(HOOK_INFO);
    DWORD RetLen;
    ZwSystemDebugControl(
    SysDbgReadVirtualMemory,
    &QueryBuff,
    sizeof(MEMORY_CHUNKS),
    NULL,
    0,
    &RetLen);
    printf("\nhandle:0x%x\toffset:%x\t",pHookInfo->hHandle,pHookInfo->OffPfn);
    printf("%d",UnhookWindowsHookEx((HHOOK)pHookInfo->hHandle));//卸载消息钩子
    showInfo(pHookInfo->Win32Thread);
    //printf("%d\t",i);
    //printf("%x\t",phandle_entry[i].bFlags); //alltime 0
    //printf("%x\t",phandle_entry[i].bType);
    //printf("%x\t",phandle_entry[i].phead);
    //printf("%x\t",phandle_entry[i].pOwner);
    //printf("%x\n",phandle_entry[i].wUniq);
    count++;
    delete pHookInfo;
    }
    }
    printf("%d",count);
    getchar();
    return 0;
    }
  • 相关阅读:
    Mysql 从库的备份中恢复一张表
    my.cnf 配置文件参数解释
    利用mvn deploy命令上传包(转)
    IntelliJ IDEA 项目文件旁边都有0%classes,0% lines covered
    idea启动java Maven项目,出现" java: 程序包xxxx不存在"
    org/apache/poi/POIXMLTypeLoader或者java.lang.NoSuchFieldError: RETURN_NULL_AND_BLANK
    elasticsearch,kibana,logstash.下载
    idea显示 RunDashboard ,多个启动项时列表显示
    写for循环快捷生成方式
    Could not transfer artifact xxx from/to xxx解决方案
  • 原文地址:https://www.cnblogs.com/delphi7456/p/1888464.html
Copyright © 2011-2022 走看看