c++ - 为什么我可以读取取消引用的指针,但不能用 C 编写,但可以用 C++ 编写?
问题描述
我需要修补程序,所以我制作了一个可以注入的 dll,并在注入时修补了指令的一个字节。代码很简单,只是出于好奇,这次我想用 C 而不是 C++ 编写它。但是当我加载我的 dll 时,它是线程崩溃而不是写入该指针。如果您使用 WriteProcessMemory 执行此操作,则指针为 100% 并且可以工作,但由于某种原因,不能从 dll 直接从进程写入。目标可执行文件是 x86,dll 是用 gcc 编译的。编译参数如下所示: gcc -shared mypatch.c -o mypatch.dll
#include <Windows.h>
#include <stdio.h>
#include <TlHelp32.h>
void main()
{
AllocConsole(); // Made a console so I can try to read the data, I thought maybe I was getting the wrong address, but I didn't.
FILE* consoleFile;
freopen_s(&consoleFile, "CONIN$", "r", stdin);
freopen_s(&consoleFile, "CONOUT$", "w", stderr);
freopen_s(&consoleFile, "CONOUT$", "w", stdout);
DWORD relAddr = 0x123456; // My address
DWORD addr = (DWORD)GetModuleHandle(NULL) + relAddr; // Adress is relative to the main executable.
printf("%X", *(byte*)(addr)); // Can read the real byte
*(byte*)(addr) = 0x90; // Can't write, crash.
printf("%X", *(byte*)(addr)); // Can't see, crashed.
}
BOOL WINAPI DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
if(dwReason == DLL_PROCESS_ATTACH)
{
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)main, 0, 0, 0);
}
return 1;
}
错误信息:
Unhandled exception at 0x70D41355 in SuperCoolApp.exe: 0xC0000005: Access violation writing location 0x123456. occurred
解决方案
事情不在 C 或 C++ 中,而是关于页面保护。所以这个错误本身就很具有描述性。
在这个令人困惑的尝试和祈祷序列之后,我决定再次查找我的 C++ 代码,我发现我的原始 C++ 代码在另一个文件中有 VirtualProtect 调用,在询问之前我肯定没有检查过。但是,虽然我发布了错误的信息是一种糟糕的感觉,但我确实了解到 WriteProcessMemory 忽略了页面保护,并且还对我的 C 代码进行了一些调整,这更像是对我的旧代码的 C++ 改编。应该先检查所有内容两次。非常感谢大家,也有点抱歉。
作为确认说明,与 C 和 C++ 相比,一切工作方式相同。我已经从头开始重写了两个版本,它们的行为完全一样,没有保护覆盖它们崩溃,并且覆盖它们都完成了工作。
推荐阅读
- sql - 用 group by 和 count 计算行数(postgres)
- python - 构建失败的 Python Flask 应用程序中缺少什么?
- android - 在 DebugView 中看不到设备和事件日志
- flutter - 按钮 onPressed 不运行该功能
- javascript - 由于 Memoize,React 组件不会在状态更改时重新渲染
- javascript - 必填输入字段 + Onlick 按钮请求
- r - 如何将“im”像素图像转换为光栅?
- reactjs - 容器组件没有获得道具
- apache - ProxyPassReverse 在重定向时不保持正确的协议
- c# - 输入不显示