【问题标题】:Inconsistent data with ReadProcessMemory C++与 ReadProcessMemory C++ 不一致的数据
【发布时间】:2014-12-09 03:22:12
【问题描述】:

这是独家新闻,我创建了一个休眠 30 秒的程序..仅此而已。在免疫调试器中,它看起来像这样:

0x00061000 >/$ 68 30750000    PUSH 7530; /Timeout = 30000. ms

这个程序的代码是:

#include <windows.h>
void main()
{
    Sleep(30000);
    return 0;
}

我正在尝试使用 C++ 程序来阅读这一行。这是该过程的代码:

const char *procName = "blank.exe";
HANDLE hProc = GetProcHandle(procName);
if (hProc == NULL){
    cout << "Error Proccess Handle == NULL!!! Can not continue...";
    getch();
    return 1;
}
//Handle aquired continue.... //

cout << "Handle has been Aquired!\n";
LPVOID RMEM[100];
ReadProcessMemory(hProc, (LPVOID)(0x00061000), &RMEM, sizeof(RMEM), 0);
cout << "Read Memory:" << RMEM;

getch();
return 0;

问题是每次我运行程序都会得到不同的结果。示例 3 三个运行的结果(00FBFC3C、0086F9C4、007CF5EO)。我希望能够读取 sleep 的值,然后在完善之后我想用一个新值覆盖它,例如:PUSH EA60;到底是怎么回事?我已经阅读了我尝试查看 ReadProMem 给我的值的 msdn 页面,并且主模块中没有这样的偏移量。我完全失去了0.o 任何帮助和提示都会很棒。

【问题讨论】:

  • 投反对票有什么原因吗?
  • 不确定还有谁投了反对票,但我的将是因为没有检查ReadProcessMemory 的返回码,即使它可能没有失败(如果你检查过它并缩短了你的代码可读性,值得注意)。另外,您可能想查看Address Space Randomisation 是否在起作用 - 这取决于您的编译器设置和版本以及操作系统版本......
  • 为什么没有提供测试程序的代码?由于问题依赖于此,因此将其排除似乎很鲁莽。
  • 我将编辑代码。和托尼 D 它正在阅读记忆,从我不知道的。 - 请注意,我对此很陌生!我认为通过指出所有空白 exe 所做的都是 Sleep(30000) 它已经提供...
  • 如果你必须给我投反对票,但我要为这里有时不太友好的社区道歉。他们很有帮助,但举止和善意有时会转瞬即逝。

标签: c++ winapi memory


【解决方案1】:

ReadProcessMemory 的调用很可能失败。由于您不检查错误,因此您无法知道这一点。文档说:

返回值

如果函数成功,则返回值非零。

如果函数失败,则返回值为 0(零)。要获取扩展的错误信息,请调用 GetLastError。

您的错误检查可能如下所示:

if (!ReadProcessMemory(...))
{
    DWORD err = GetLastError();
    // report error, bail out, etc. 
}

我的猜测是ReadProcessMemory 失败是因为你传递的地址在目标进程中无效。然后,当您输出 RMEM 时,您只是在输出未初始化的值。

您的第一步是修复错误处理。完成后,您将知道哪个 API 调用失败以及失败的原因。那么您可能只需要提供一个有效的地址。

【讨论】:

  • 看起来像:= 中的小帕斯卡 :)
【解决方案2】:

在这里工作得很好,使用 win7 pro 和 32 位编译程序。两个程序都是用 Mingw 和 Code::Blocks 构建的,目标内存地址是用 OllyDbg 确定的。

我可以确认延迟已成功更改。这就是 getchar() 的目的——它是为了确保当我们改变目标程序的内存时延迟还没有开始。

1。目标程序源码——main.c(hackMe.exe)

#include <windows.h>

void main()
{
    getchar();
    Sleep(30000);
    return 0;
}

2。目标程序的目标区域(使用ollydbg)

CPU Disasm
Address   Hex dump          Command                                  Comments
00401334  /$  8D4C24 04     LEA ECX,[ARG.1]
00401338  |.  83E4 F0       AND ESP,FFFFFFF0                         ; DQWORD (16.-byte) stack alignment
0040133B  |.  FF71 FC       PUSH DWORD PTR DS:[ECX-4]
0040133E  |.  55            PUSH EBP
0040133F  |.  89E5          MOV EBP,ESP
00401341  |.  51            PUSH ECX
00401342  |.  83EC 14       SUB ESP,14
00401345  |.  E8 D6050000   CALL 00401920
0040134A  |.  E8 41080000   CALL <JMP.&msvcrt.getchar>               ; [MSVCRT.getchar
0040134F  |.  C70424 307500 MOV DWORD PTR SS:[LOCAL.7],7530          ; /Time => 30000. ms
00401356  |.  E8 8D080000   CALL <JMP.&KERNEL32.Sleep>               ; \KERNEL32.Sleep
0040135B  |.  83EC 04       SUB ESP,4
0040135E  |.  90            NOP
0040135F  |.  8B4D FC       MOV ECX,DWORD PTR SS:[LOCAL.2]
00401362  |.  C9            LEAVE
00401363  |.  8D61 FC       LEA ESP,[ECX-4]
00401366  \.  C3            RETN

3. 控制程序 - main.c

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <tlhelp32.h>
unsigned long GetProcessId( char* szProcName )
{
    PROCESSENTRY32 pe32;
    HANDLE hHandle;

    hHandle = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
    pe32.dwSize = sizeof( PROCESSENTRY32 );

    if( !Process32First( hHandle, &pe32 ) )
        return 0;

    while( Process32Next( hHandle, &pe32 ) )
    {
        if( stricmp( szProcName, pe32.szExeFile ) == 0 )
        {
            CloseHandle( hHandle );
            return pe32.th32ProcessID;
        }
    }
    CloseHandle( hHandle );
    return 0;
}

// reads a chunk of memory from a running program's memory space
// Buffer must already be allocaed and hold space for length bytes
BOOL readMemBlock(char *szProgName, unsigned long dwMemAddr, unsigned long length, void *Buffer)
{
    HANDLE hHandle;
    SYSTEM_INFO sysInfo;
    MEMORY_BASIC_INFORMATION mbi;
    BOOL resCode;
    DWORD lastErrCode;

    printf("%s, 0x%x, %d\n", szProgName, dwMemAddr, length);

    hHandle = OpenProcess( STANDARD_RIGHTS_REQUIRED|PROCESS_VM_READ, FALSE, GetProcessId( szProgName ) );

    if( hHandle == INVALID_HANDLE_VALUE || hHandle == NULL )
    {
        printf("Error opening process\n");
        if (!hHandle)
            printf("hHandle == NULL\n");
        else
            printf("INVALID_HANDLE_VALUE");
        return FALSE;
    }
    resCode = ReadProcessMemory( hHandle, (unsigned long*)dwMemAddr, Buffer, length, NULL );
    CloseHandle(hHandle);
    return resCode;
}

// reads a chunk of memory from a running program's memory space
// Buffer must already be allocaed and hold space for length bytes
BOOL writeMemBlock(char *szProgName, unsigned long dwMemAddr, unsigned long length, void *Buffer)
{
    HANDLE hHandle;
    SYSTEM_INFO sysInfo;
    MEMORY_BASIC_INFORMATION mbi;
    BOOL resCode;

    hHandle = OpenProcess( PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_WRITE, FALSE, GetProcessId( szProgName ) );
    if( hHandle == INVALID_HANDLE_VALUE || hHandle == NULL )
        return FALSE;

    resCode = WriteProcessMemory( hHandle, (unsigned long*)dwMemAddr, Buffer, length, NULL );
    CloseHandle(hHandle);
    return resCode;
}

int main()
{
    unsigned long pId = GetProcessId("hackMe.exe");
    if (!pId)
    {
        printf("Proc handle NOT FOUND\n");
        return;
    }

    printf("Proc handle aquired\n");
    unsigned char buffer[50];
    readMemBlock("hackMe.exe", 0x401334, 50, buffer); //unsigned long length, void *Buffer)
    int i;
    for (i=0; i<50; i++)
    {
        unsigned int curElem = buffer[i];
        printf("%02X ", (unsigned int)curElem);
        if ((i+1)%16 == 0)
            printf("\n");
    }
    /* output
        Proc handle aquired
        hackMe.exe, 0x401334, 50
        8D 4C 24 04 83 E4 F0 FF 71 FC 55 89 E5 51 83 EC
        14 E8 D6 05 00 00 E8 41 08 00 00 C7 04 24 30 75  <-- want these 2 bytes 0x30, 0x75
        00 00 E8 8D 08 00 00 83 EC 04 90 8B 4D FC C9 8D
        61 FC
    */

    // change delay to 2.5 seconds (originally 30 secs)
    short newDelayValue = 2500;
    writeMemBlock("hackMe.exe", 0x401352, 2, &newDelayValue);

    return 0;
}

【讨论】:

  • 是你写的吗?
  • 我为这个问题写的main,其余的都是从一个十年前在XP上播放WinMine.exe(扫雷)的项目中复制和粘贴的。
  • 我要下载ming。我认为这与visual studio 2013有关......
  • 无论如何感谢您的宝贵时间。我将不得不检查这段代码并尝试从中学习一些东西。
  • 不,和 VS 一点关系都没有。当所有编译器编译时,您的代码将以相同的方式失败。这个问题中的代码与您的代码犯了同样的错误,因为没有检查错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
  • 2018-08-30
  • 2020-06-25
  • 1970-01-01
  • 2018-02-08
  • 2021-05-08
  • 2012-06-26
相关资源
最近更新 更多