【问题标题】:Hook and unhook one file DLL挂钩和取消挂钩一个文件 DLL
【发布时间】:2018-11-06 07:42:37
【问题描述】:

我尝试将文件 DLL 挂钩到控制台应用程序。这段代码

#include "pch.h"
#include <vector>
#include <string>
#include <windows.h>
#include <Tlhelp32.h>

using std::vector;
using std::string;

int main(void)
{
while (true)
{
    vector<string>processNames;
    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(PROCESSENTRY32);
    HANDLE hTool32 = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
    BOOL bProcess = Process32First(hTool32, &pe32);
    if (bProcess == TRUE)
    {
        while ((Process32Next(hTool32, &pe32)) == TRUE)
        {
            processNames.push_back(pe32.szExeFile);
            if (strcmp(pe32.szExeFile, "ConsoleApplication4.exe") == 0)
            {
                char* DirPath = new char[MAX_PATH];
                char* FullPath = new char[MAX_PATH];
                GetCurrentDirectory(MAX_PATH, DirPath);
                sprintf_s(FullPath, MAX_PATH, "%s\\..\\ConsoleApplication1\\ConsoleApplication1.dll", DirPath);

                FILE *pFile;
                if (fopen_s(&pFile, FullPath, "r") || !pFile)
                {
                    OutputDebugString("[Hook] File name or file does not exist");
                    OutputDebugString(FullPath);
                    return -1;
                }
                fclose(pFile);

                HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
                if (!hProcess)
                {
                    OutputDebugString("[Hook] Open process fail");
                    return -1;
                }

                //attach
                LPVOID LoadLibraryAddr = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
                if (!LoadLibraryAddr)
                {
                    OutputDebugString("[Hook] Load LoadLibraryA fail");
                    return -1;
                }

                LPVOID LLParam = (LPVOID)VirtualAllocEx(hProcess, NULL, strlen(FullPath), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

                if (!WriteProcessMemory(hProcess, LLParam, FullPath, strlen(FullPath), NULL))
                {
                    OutputDebugString("[Hook] Write process fail");
                    return -1;
                }

                HANDLE hHandle = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibraryAddr, LLParam, NULL, NULL);
                if (!hHandle)
                {
                    OutputDebugString("[Hook] Hooked fail");
                    return -1;
                }

                system("pause");

                //detach
                LoadLibraryAddr = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "FreeLibrary");
                if (!LoadLibraryAddr)
                {
                    OutputDebugString("[Hook] Load FreeLibrary fail");
                    return -1;
                }

                hHandle = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibraryAddr, LLParam, NULL, NULL);
                if (!hHandle)
                {
                    OutputDebugString("[Hook] detach fail");
                    return -1;
                }

                CloseHandle(hProcess);
                delete[] DirPath;
                delete[] FullPath;

                system("pause");

                return 0;
            }
        }
    }
    CloseHandle(hTool32);
}
return 0;
}

我对此有一些疑问: - 为什么这段代码不能分离文件 dll? - 为什么我更改 LoadLibraryA -> LoadLibrary:加载 LoadLibrary 失败? - 为什么我更改 LoadLibraryA -> LoadLibraryW:文件 dll 没有附加? - Mutibyte 运行的代码很好,但是转换为 Unicode,文件 dll 没有附加?

谢谢,

【问题讨论】:

  • 代码写了一个 char[] 所以需要 LoadLibraryA 来正确解释字符串。现在它是偶然工作的,strlen(FullPath) 是一个错误的错误,因为它忘记了编写零终止符。降低 wchar_t[] 和 LoadLibraryW 起作用的几率。
  • 我尝试转换为 Unicode 并同时使用 LoadLibraryA 和 LoadLibraryW 但文件 DLL 没有附加。
  • 嗨,先生,这行得通。我更改 char* FullPath -> wchar_t FullPath[] 和 strlen(FullPath)->sizeof(FullPath),LoadLibraryW 工作。谢谢
  • 我错过了:DWORD hLibModule; GetExitCodeThread(hThread, &hLibModule); CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibraryAddr, (void*)hLibModule, NULL, NULL); Dll 是分离的

标签: c++ hook


【解决方案1】:

这适用于多字节但不能使用 unicode 字符集编译的原因是因为您传递的是一个常规的 c 字符串,它是一个常规的 char 数组。当您将构建类型设置为使用多字节 LoadLibrary() 时,将解析为 LoadLibraryA() 的 ansi 版本。如果您想在项目属性中使用 Unicode,它将解析为 LoadLibraryW(),并且您需要传递一个 unicode char 数组,通常是 wchar_t[]。

即使在 unicode 模式下编译,您仍然可以调用 LoadLibraryA() 并传递一个 c 字符串,但您必须专门调用该函数的 A (ansi) 版本,而不是依赖 #ifdef 预处理器语句为您解析它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多