简体   繁体   English

为什么我可以读取取消引用的指针,但不能用 C 编写它,但可以用 C++ 编写?

[英]Why can I read a dereferenced pointer, but can't write it in C, but can in C++?

I needed to patch a program, so I made a dll that I can inject and on inject it patches one byte of the instruction.我需要修补一个程序,所以我制作了一个可以注入的 dll,并在注入它时修补指令的一个字节。 The code is pretty simple, the only thing that this time I wanted to write it in C, instead of C++, just of curiosity.代码很简单,这次我唯一想用C而不是C++来写的,只是出于好奇。 But when I load my dll it's thread crashes in place of writing to that pointer.但是当我加载我的 dll 时,它的线程崩溃而不是写入该指针。 The pointer is 100% and works if you do it with WriteProcessMemory, but by some reason can't be written from a dll, directly from a process.指针是 100% 并且如果你使用 WriteProcessMemory 来工作,但由于某种原因不能从 dll 直接从进程写入。 The target executable is x86 and the dll is compiled with gcc.目标可执行文件是 x86,dll 是用 gcc 编译的。 The compilation params look like this: gcc -shared mypatch.c -o mypatch.dll编译参数如下所示: 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;
}

Error message:错误信息:

Unhandled exception at 0x70D41355 in SuperCoolApp.exe: 0xC0000005: Access violation writing location 0x123456. occurred

The thing wasn't in the C or C++, it was about page protection.问题不在 C 或 C++ 中,而是关于页面保护。 So the error was pretty descriptive at itself.所以这个错误本身就非常具有描述性。

After this confusing try and pray sequence I've decided to look up my C++ code once again and I had found out that my original C++ code had VirtualProtect calls in the other file, which I surely haven't checked before asking.在这个令人困惑的尝试和祈祷序列之后,我决定再次查找我的 C++ 代码,我发现我的原始 C++ 代码在另一个文件中有 VirtualProtect 调用,我在询问之前肯定没有检查过。 But although this is kind of a shit feeling that I've posted wrong info, I did learn that WriteProcessMemory ignores page protection, and also some tweaks to my C code, which was more of a C++ adaptation from my old code.但是,尽管我发布了错误信息的感觉有点糟糕,但我确实了解到 WriteProcessMemory 忽略了页面保护,并且还对我的 C 代码进行了一些调整,这更像是对我旧代码的 C++ 改编。 Should've checked everything first twice.应该先检查所有东西两次。 Very thankful to everyone, and kind of sorry.非常感谢大家,有点抱歉。

Just as a confirmation note, everything works identically compared to C and C++.就像确认说明一样,与 C 和 C++ 相比,一切都相同。 I've rewritten both versions from scratch and they behave totally the same, without the protection override they crash, and with override they both get the job done.我从头开始重写了这两个版本,它们的行为完全相同,没有保护覆盖它们会崩溃,并且通过覆盖它们都可以完成工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM