gpt4 book ai didi

c++ - IAT Hook - 无法 Hook ExitProcess

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:03:21 25 4
gpt4 key购买 nike

我可以 Hook 任何其他函数,但不能 Hook ExitProcess。

下面是演示这个的代码:

#include <iostream>
#include <cstdlib>

#include <Windows.h>
#include <Psapi.h>

void __stdcall NewSleep(DWORD milliseconds)
{
std::cout << "Sleep." << std::endl;

std::cin.get();
}

void __stdcall NewExitProcess(UINT exitCode)
{
std::cout << "ExitProcess." << std::endl;

std::cin.get();
}

FARPROC f1 = NULL;
FARPROC f2 = NULL;

int main()
{
HMODULE kernel32Module = GetModuleHandle("KERNEL32.dll");
f1 = GetProcAddress(kernel32Module, "Sleep");
f2 = GetProcAddress(kernel32Module, "ExitProcess");

std::cout << f1 << std::endl;

unsigned char* baseAddress = (unsigned char*)GetModuleHandle(NULL);

IMAGE_DOS_HEADER* idh = (IMAGE_DOS_HEADER*)baseAddress;
IMAGE_NT_HEADERS* inh = (IMAGE_NT_HEADERS*)(baseAddress + idh->e_lfanew);
IMAGE_IMPORT_DESCRIPTOR* iid = (IMAGE_IMPORT_DESCRIPTOR*)(baseAddress + inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

for (IMAGE_IMPORT_DESCRIPTOR* i = iid; i->Name != 0; ++i)
{
std::string moduleName = (char*)(baseAddress + i->Name);

if (moduleName == "KERNEL32.dll")
{
IMAGE_THUNK_DATA* itd = (IMAGE_THUNK_DATA*)(baseAddress + i->FirstThunk);

for (IMAGE_THUNK_DATA* j = itd; j->u1.Function != 0; ++j)
{
if ((FARPROC)j->u1.Function == f1)
{
DWORD oldProtect = 0;
VirtualProtect(&j->u1.Function, sizeof(DWORD), PAGE_READWRITE, &oldProtect);
j->u1.Function = (DWORD)&NewSleep;
VirtualProtect(&j->u1.Function, sizeof(DWORD), oldProtect, &oldProtect);
}

if ((FARPROC)j->u1.Function == f2)
{
DWORD oldProtect = 0;
VirtualProtect(&j->u1.Function, sizeof(DWORD), PAGE_READWRITE, &oldProtect);
j->u1.Function = (DWORD)&NewExitProcess;
VirtualProtect(&j->u1.Function, sizeof(DWORD), oldProtect, &oldProtect);
}
}

break;
}
}

Sleep(0);
Sleep(0);

ExitProcess(0);
//Crash.

std::cin.sync();
std::cin.get();
return EXIT_SUCCESS;
}

它调用了钩子(Hook)函数,但是当 NewExitProcess 返回时我遇到了访问冲突。对 Sleep 的调用没有问题,就像除 ExitProcess 之外的任何 Hook 函数一样。

编辑:虽然 Hook ExitThread 时我遇到了同样的问题。

最佳答案

在查找 ExitProcess 的函数声明时,您会发现如下内容:

WINBASEAPI
DECLSPEC_NORETURN
VOID
WINAPI
ExitProcess(
_In_ UINT uExitCode
);

有趣的部分是 DECLSPEC_NORETURN,它被定义为 __declspec(noreturn)。它也是 ExitThread 函数使用的一个属性,它也导致了您的崩溃。 Looking up on the docs ,我们发现:

This __declspec attribute tells the compiler that a function does not return. As a consequence, the compiler knows that the code following a call to a __declspec(noreturn) function is unreachable.

根据您的发现,它不仅用于禁用编译器警告,还用于优化。这也解释了为什么它会在 Debug模式下工作。

我想不出一个好的解决方案,因为你正在与优化器作斗争。你在评论中写的解决方案对我不起作用(VS2013, Release模式,/O2)。我想到了一些有点傻的东西,但它似乎对我有用:

int *ptr = (int*)&ExitProcess;
ptr++;
ptr--;
((VOID (WINAPI*)(UINT))ptr)(0);

一般来说, Hook 另一个未知程序的ExitProcess应该总是退出当前线程,因为它可能被编译为没有任何代码可以返回。

关于c++ - IAT Hook - 无法 Hook ExitProcess,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21231784/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com