-2

我正在尝试将 DLL 挂接到记事本进程上,然后将其取消挂接。挂钩时,每当用户单击“另存为”时,DLL 应使记事本创建一个隐藏文件(此代码未显示)。脱钩时,情况不应该如此。

但是,由于某种原因,当我收到消息“DLL unhooking from process”时,DLL 仍然没有从记事本进程中解除挂钩,我知道这一点,因为记事本仍然会在不应该这样做的时候创建附加文件。

返回值上没有任何错误消息(至少我不知道),所以我删除了大多数返回值检查。

HANDLE hThread;
char * pid = argv[1];
DWORD user_pid = atoi(pid);
LPCSTR Dllpath = "C:\\Users\\xxx\\Desktop....\\MyDll.dll"
LPVOID pDllPath; // Address in remote process where Dllpath will be copied to.
HMODULE hKernel32 = GetModuleHandle("Kernel32");

HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, user_pid);

char * command = argv[2];

if (strcmp(command,"hook") == 0){

    SIZE_T bytesWritten = 0;

    //Allocate memory to target process, and write dll to the allocated memory.
    pDllPath = VirtualAllocEx(hProcess, NULL,strlen(DllPath)+1, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);

    // Write DLL hook name
    WriteProcessMemory(hProcess, pDllPath, (LPCVOID)DllPath, strlen(Dllpath)+1,&bytesWritten);

    // Load Dll to remote process
    hThread = CreateRemoteThread(hProcess, NULL,0,(LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32, "LoadLibraryA"), pDllPath,0,NULL);

    WaitForSingleObject(hThread, INFINITE);

    //Clean up
   CloseHandle(hThread);
   VirtualFreeEx(hProcess, pDllPath, strlen(DllPath+1, MEM_RELEASE);

else if (strcmp(command,"unhook")==0){
    InlineUnhook(); //Call unhook inside the dll itself
}

}

取消挂钩(在 dll 本身内部)

HANDLE __stdcall InlineUnhook(){

HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
LoadLibrary("C:\\Users\\xxx\\Desktop...\\MyDll.dll);
HMODULE hLibModule = GetModuleHandleA ("C:\\Users\\xxx\\Desktop...\\MyDll.dll);

HANDLE hThread = CreateRemoteThread(hProcess, NULL,0,(LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32, "FreeLibraryAndExitThread"), (void *)(hLibModule,0),0,NULL);

if (hThread == NULL){
    OutputDebugStringA("CreateRemoteThread failed.");
    return -1;
}

else{
    WaitForSingleObject(hThread, INFINITE);

    //Clean up
    CloseHandle(hThread);
    OutputDebugStringA("DLL unhooking from process...");

    return 0;
}
}
4

2 回答 2

3

您的注入器直接调用InlineUnhook(),因此它将作用于注入器进程中加载​​的 DLL 实例,而不是挂钩进程。

FreeLibraryAndExitThread()与 不兼容CreateRemoteThread(),因此您不能使用远程线程直接调用它,就像您可以使用LoadLibraryA().

在 DLL 本身内部,它不需要调用OpenProcess()LoadLibrary()CreateRemoteThread()自己。DLL 可以FreeLibraryAndExitThread()像任何其他本地函数一样直接调用。

HINSTANCE hThisInst;

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
    hThisInst = hinstDLL;
    ...
    return 1;
}

void __stdcall InlineUnhook()
{
    FreeLibraryAndExitThread(hThisInst, 0);
}

您的注入器必须使用远程线程InlineUnhook()在挂钩进程的上下文中调用,而不是直接调用它。这意味着您需要:

  • InlineUnhook()从 DLL导出。

  • 在挂钩的进程中找到加载的 DLL 的地址。如果您的 DLL 是 32 位的,正在加载到 32 位目标进程中,则可以GetExitCodeThread()CreateRemoteThread()调用LoadLibraryA(). 否则,您将不得不在之后寻找加载的地址,例如 byEnumProcessModules()CreateToolhelp32Snapshot(TH32CS_SNAPMODULE)

  • InlineUnhook()在挂钩的进程中找到导出的地址。在注入器内部使用LoadLibrary()andGetProcAddress()计算InlineUnhook()DLL 内的偏移量,然后将该偏移量应用于被钩子进程中加载​​的 DLL 的地址。

  • 用于CreateRemoteThread()调用InlineUnhook()该计算的地址。您必须更改 的签名InlineUnhook()以与 兼容CreateRemoteThread(),例如:

DWORD __stdcall InlineUnhook(LPVOID)
{
    FreeLibraryAndExitThread(hThisInst, 0);
    return 1;
}
于 2020-09-14T18:54:59.707 回答
1

那是因为您InlineUnhook上面的调用调用了加载到注入进程中的 dll 副本,而不是目标进程中的那个。

于 2020-09-14T16:39:30.703 回答