首页 > 解决方案 > 为什么我可以读取取消引用的指针,但不能用 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++cpointerswinapi

解决方案


事情不在 C 或 C++ 中,而是关于页面保护。所以这个错误本身就很具有描述性。

在这个令人困惑的尝试和祈祷序列之后,我决定再次查找我的 C++ 代码,我发现我的原始 C++ 代码在另一个文件中有 VirtualProtect 调用,在询问之前我肯定没有检查过。但是,虽然我发布了错误的信息是一种糟糕的感觉,但我确实了解到 WriteProcessMemory 忽略了页面保护,并且还对我的 C 代码进行了一些调整,这更像是对我的旧代码的 C++ 改编。应该先检查所有内容两次。非常感谢大家,也有点抱歉。

作为确认说明,与 C 和 C++ 相比,一切工作方式相同。我已经从头开始重写了两个版本,它们的行为完全一样,没有保护覆盖它们崩溃,并且覆盖它们都完成了工作。


推荐阅读