【发布时间】:2017-09-28 04:10:42
【问题描述】:
我使用了多个 Hooking 库,例如Microsoft Detours Express、Mhook 等钩住 NtWriteVirtualMemory API 调用。我编写了以下代码来挂钩 API:
#include <string>
#include <fstream>
#include <process.h>
#include <Windows.h>
#include <detours.h>
#pragma comment(lib, "detours.lib")
using namespace std;
#define MAX_SIZE 10000
char tempPath[MAX_SIZE];
typedef LONG(NTAPI * oNtWriteVirtualMemory)(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN PVOID Buffer,
IN ULONG NumberOfBytesToWrite,
OUT PULONG NumberOfBytesWritten OPTIONAL);
oNtWriteVirtualMemory pNtWriteVirtualMemory = (oNtWriteVirtualMemory)GetProcAddress(GetModuleHandle(L"Ntdll.dll"), "NtWriteVirtualMemory");
BOOL WINAPI MyNtWriteVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN PVOID Buffer,
IN ULONG NumberOfBytesToWrite,
OUT PULONG NumberOfBytesWritten OPTIONAL
)
{
DWORD pidSource = GetCurrentProcessId();
DWORD pidDestination = GetProcessId(ProcessHandle);
if (pidSource != pidDestination)
{
FILE * f1 = fopen(tempPath, "a+");
fprintf(f1, "inter-process write from %d to %d!\n", pidSource, pidDestination);
fclose(f1);
}
return pNtWriteVirtualMemory(ProcessHandle, BaseAddress, Buffer,umberOfBytesToWrite, NumberOfBytesWritten OPTIONAL);
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
strcpy(tempPath, "C:\\Windows\\Temp\\log.txt");
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
try
{
DisableThreadLibraryCalls(hModule);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)pNtWriteVirtualMemory, MyNtWriteVirtualMemory);
DetourTransactionCommit();
}
catch (int e)
{ }
break;
case DLL_THREAD_ATTACH:
try
{
DisableThreadLibraryCalls(hModule);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)pNtWriteVirtualMemory, MyNtWriteVirtualMemory);
DetourTransactionCommit();
}
catch (int e)
{
}
break;
case DLL_PROCESS_DETACH:
try
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)pNtWriteVirtualMemory, MyNtWriteVirtualMemory);
DetourTransactionCommit();
}
catch (int e)
{
}
break;
case DLL_THREAD_DETACH:
try
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)pNtWriteVirtualMemory, MyNtWriteVirtualMemory);
DetourTransactionCommit();
}
catch (int e)
{
}
break;
}
return TRUE;
}
但是,它仅适用于某些特定情况。例如,当 API Monitor 程序将其监控 DLL 写入目标进程以监控进程的行为时,我的钩子代码运行良好,并像往常一样钩住 API Monitor 程序的 NtWriteVritualMemory 调用。此外,代码很好地挂钩了 Visual Studio 中的 API。当 Visual Studio 开始构建项目时,它会调用 NtWriteVirtualMemory 进行一些进程间写入,我可以在我的临时日志文件中看到这些调用的日志!
但是,当我编写自己的代码或构建另一个代码(例如Reflective DLL Injection)来调用 NtWriteVirtualMemory API 时,钩子根本没有检测到它。我使用 Visual Studio 2015 构建这些代码来调用 API 或挂钩它。此外,我使用AppInit_DLLs Infrastructure 使我的挂钩 DLL 成为全局用户级挂钩。
任何线索将不胜感激。
【问题讨论】:
-
你的意思是它不是一个可靠的方法来挂钩一个 API?你为用户级挂钩提供什么?
-
(a) 我不明白这个问题。 (b) 你试过调试吗? (c) 您能否提供一个完整的工作示例? (这个东西叫“MCVE”。)
-
A) 更具体地说,在某些进程中,挂钩库不起作用,尽管它已经加载到进程中。 B)不,我没有。它是否提供了一个全球系统范围的用户级挂钩?你能解释更多吗? C) 我已将代码示例更新为完整的。
-
单步执行挂钩代码。查看您正在挂钩的任何内容(导入表、函数开头等)的内存。变了吗?
标签: c++ winapi windows-10 hook internals