MinHook库的使用 64位下,过滤LoadLibraryExW

Posted ibinary

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MinHook库的使用 64位下,过滤LoadLibraryExW相关的知识,希望对你有一定的参考价值。

  • MinHook库的使用 x64

一丶简介

minHook库是一个支持x64跟x86HOOK的库.Detours也支持x64.不过是收费的所以在x64下使用minHook也是一个不错的选择.

1.minHook库的下载以及安装.

MinHook 我已经打包了一份.可以在我的百度网盘中下载

链接:https://pan.baidu.com/s/1QJcf5_Q9naL2Y48IN2Y5MQ
提取码:ndmq

当然也可以在Github下载.
库源文件:
https://github.com/m417z/minhook

解压之后:
技术图片
有4个文件目录
build
dll_resources
include
src

我们打开build目录
技术图片
可以看到从 VC9 - VC15 这个代表VS编译器的版本号.
比如我用的是VS2013.其版本号就是VC12.我们进入文件目录

技术图片

打开后缀名为.sln或者.vcxproj都可以.
技术图片

打开之后如上所示.
一个libMinHook
一个MinHOOK

libMinHook是生成 lib供我们使用的.
MinHook工程是生成DLL供我们使用的.

x86编译跟x64编译
比如我们要HOOK的程序是x64程序的话.我这里选择的是生成lib库.
你需要将你的VS配置管理器改成x64.来生成libMinHook的库.
这样你的程序引用x64的lib库.就可以Hookx64程序了.

二丶使用MinHook库,过滤LoadLibraryExW

2.1编写X64测试程序.

既然我们要使用Hook.那么就编写一个X64程序.这个程序就是加载DLL
代码如下:

#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>

int main()
{

    HMODULE hDll;
    
    hDll = LoadLibraryExW(TEXT("x64Hook.dll"), NULL, 0); //加载HOOK的DLL
    hDll = LoadLibraryExW(TEXT("kernel32.dll"),NULL,NULL);//判断是否被HOOK

    system("pause");
    return 0;
}

2.2使用MinHook库

在使用之前.我们有必要介绍一下 Minhook.h头文件中提供给我的函数声明

  MH_STATUS WINAPI MH_Initialize(VOID);   //初始化HOOK引擎

  MH_STATUS WINAPI MH_Uninitialize(VOID); //反初始化

  MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal);//创建HOOK跳板

  MH_STATUS WINAPI MH_CreateHookApi(                                                 //创建APIhook跳板
        LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal);

  MH_STATUS WINAPI MH_CreateHookApiEx(                                              //扩展
        LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal, LPVOID *ppTarget);

  MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget);                                  //删除HOOK

  MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget);                                  //启动HOOK

  MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget);                                 //结束HOOK
 
  MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget);

  MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget);
 
  MH_STATUS WINAPI MH_ApplyQueued(VOID);
 
  const char * WINAPI MH_StatusToString(MH_STATUS status);

如果我们要写成HOOK总共步骤如下;
1.初始化HOOK引擎
2.创建HOOK跳板函数
3.启用HOOK
4.结束HOOK
5.删除HOOK
6.反初始化HOOK引擎

特别注意创建HOOK跳板函数.我们可以用的接口有 MB_CreateHook MB_CreateHookApi MB_CreateHookApiEx
以第一个为例: 参数1: 你要HOOK的函数的函数指针(&LoadLibraryExW) 参数2:你自定义的函数 (&MyLoadLibraryExW) 参数3:跳板函数指针

参数3的意思就是 我们的函数内部调用参数3.相当于调用原函数.

2.3完整HOOK代码

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include "MinHook.h"
#include <tchar.h>
#include <windows.h>

#if defined _M_X64
#pragma comment(lib, "libMinHook.x64.lib")
#elif defined _M_IX86
#pragma comment(lib, "libMinHook.x86.lib")
#endif


typedef HMODULE (WINAPI *PFNloadLibraryExw)(LPCSTR lpLibFileName, HANDLE hFile, DWORD  dwFlags);  //函数的定义

PFNloadLibraryExw pfnLoadLibraryExW = NULL;

BOOL  HOOK();
BOOL UnHOOK();



void __cdecl MyOutputDebugStrig(const _TCHAR* pszFormat, ...)
{
    _TCHAR buf[1024] = { 0 };
    // ZeroMemory( buf, 1024*sizeof(TCHAR ) );
    swprintf_s(buf, 1024, _T("线程ID = [%lu]"), GetCurrentThreadId());
    va_list arglist;
    va_start(arglist, pszFormat);
    int nBuffSize = _tcslen(buf);
    vswprintf_s(&buf[nBuffSize], 1024 - nBuffSize, pszFormat, arglist);
    va_end(arglist);
    nBuffSize = _tcslen(buf);
    _tcscat_s(buf, 1024 - nBuffSize, _T("\\n"));
    OutputDebugString(buf);
}

HMODULE WINAPI MyLoadLibraryExW(
    LPCSTR lpLibFileName,
    HANDLE hFile,
    DWORD  dwFlags
    )
{

    MyOutputDebugStrig(TEXT("已经HOOK过了 LoadLibraryExW函数"));
    return pfnLoadLibraryExW(lpLibFileName,hFile,dwFlags);
}
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        HOOK();
        break;
    case DLL_THREAD_ATTACH:
        break;

    case DLL_THREAD_DETACH:
        break;

    case DLL_PROCESS_DETACH:
        UnHOOK();
        break;
    }
    return TRUE;
}

BOOL  HOOK()
{
    //初始化MinHOOK HOOK他的函数
    if (MH_Initialize() != MH_OK)
    {
        MyOutputDebugStrig(TEXT("MH_Initialize Error"));
        return FALSE;
    }

    // Create a hook for MessageBoxW, in disabled state.

    if (MH_CreateHook(&LoadLibraryExW, &MyLoadLibraryExW,        //创建HOOK

        reinterpret_cast<void**>(&pfnLoadLibraryExW)) != MH_OK)
    {
        MyOutputDebugStrig(TEXT("MH_CreateHook Error"));

        return FALSE;
    }

    // Enable the hook for MessageBoxW.

    if (MH_EnableHook(&LoadLibraryExW) != MH_OK)            //启动HOOK
    {
        MyOutputDebugStrig(TEXT("MH_EnableHook Error"));

        return FALSE;
    }

    
    return TRUE;
    
}


BOOL UnHOOK()
{

    // Disable the hook for MessageBoxW.
    if (MH_DisableHook(&MessageBoxW) != MH_OK)
    {


        MyOutputDebugStrig(TEXT("MH_DisableHook Error"));
        return FALSE;
    }

    // Expected to tell "Not hooked...".


    // Uninitialize MinHook.
    if (MH_Uninitialize() != MH_OK)
    {

        MyOutputDebugStrig(TEXT("MH_Uninitialize Error"));
        return FALSE;
    }


}

注意这个dll 是64的.我们要HOOK的是测试程序中的LoadLibraryExW函数.

结果:

技术图片

这样说明我们的DLL已经起作用了.我们的测试程序加载我们的x64HookDLL.而我们的X64HookDLL则会进行HOOK.

代码链接:

链接:https://pan.baidu.com/s/1A-eyJ_CxvptYeerqKKHHyg
提取码:iayb

以上是关于MinHook库的使用 64位下,过滤LoadLibraryExW的主要内容,如果未能解决你的问题,请参考以下文章

使用 MSYS 复制 System32 DLL 会破坏库的 64 位存在

[原创]MinHook测试与分析(x64下 E9,EB,CALL指令测试,且逆推测试微软热补丁)

无法链接MinHook库

如何使 WinHttpCrackUrl 在 64 位下工作

64位下pwntools中dynELF函数的使用

win8 64位+Oracle 11g 64位下使用PL/SQL Developer 的解决办法