IAT挂钩 - 无法钩住ExitProcess
IAT hooking - unable to 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;
}
它调用挂钩函数,但是当newexitprocess返回时,我会违反访问。就像ExitProcess以外的任何挂钩功能一样,睡眠的电话都很好。
编辑:挂接出口时我会遇到同样的问题。
查找exitprocess的函数声明时,您会发现这样的东西:
WINBASEAPI
DECLSPEC_NORETURN
VOID
WINAPI
ExitProcess(
_In_ UINT uExitCode
);
有趣的部分是DECLSPEC_NORETURN
,其定义为__declspec(noreturn)
。这也是ExitThread
函数使用的属性,它也为您造成崩溃。抬头看文档,我们发现了这一点:
此__declSpec属性告诉编译器函数不会返回。结果,编译器知道呼叫__declSpec(Noreturn)函数的代码是无法实现的。
根据您的发现,它不仅用于禁用编译器警告,而且还用于优化。这也解释了为什么它会在调试模式下工作。
我想到的是一个很好的解决方案,因为您正在与优化器进行战斗。您在评论中写的解决方案对我不起作用(VS2013,发布模式,/o2)。我想出了一些愚蠢的事情,但似乎为我完成了工作:
int *ptr = (int*)&ExitProcess;
ptr++;
ptr--;
((VOID (WINAPI*)(UINT))ptr)(0);
一般而言,另一个未知程序的挂钩应始终退出当前线程,因为它可以编译为没有任何代码可以返回。
相关文章:
- WinAPI挂钩鼠标
- 如何在鼠标挂钩过程中检测拖动
- 在挂钩启动新线程时解除挂钩进程
- 覆盖应用程序的低级别键盘挂钩问题
- C++键盘挂钩 CTRL 键卡住
- 除非使用某些寄存器,否则函数挂钩会崩溃
- 使用 MS 绕道挂钩在调用钩子函数时崩溃C++
- 无法将 ncurses 函数与LD_PRELOAD挂钩
- 与节俭挂钩
- 如何在使用CreateProcess创建的进程上安装挂钩
- 如何挂钩延迟导入
- 从 SetClipboardData 挂钩获取文件名
- 父进程中的挂钩 api 调用
- 挂钩创建文件抛出异常:读取访问冲突
- 全局挂钩 DLL 仅在 C# 主窗口处于活动状态/前台时调用 C# 回调方法
- 哪些消息可以传递给低级鼠标挂钩回调函数
- 任何挂钩功能的单一接口
- 什么可能导致低级鼠标挂钩错过按钮启动事件?
- 挂钩 winapi 函数显示我 dllimport 错误
- IAT挂钩 - 无法钩住ExitProcess