2014-12-09 2 views
-4

Вот совок, я создал программу, которая спит в течение 30 секунд. Больше ничего. В невосприимчивости отладчике это выглядит так:Несогласованные данные с ReadProcessMemory C++

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). Я хочу, чтобы иметь возможность читать значение сна, а затем, после того, как это усовершенствовано, я хочу перезаписать его новым значением, например: PUSH EA60; Что происходит? Я прочитал страницу msdn, которую я пробовал, глядя на значения, которые дает ReadProMem, и в этом модуле нет такого смещения. Я полностью потерял 0.o Любая помощь и советы были бы потрясающими.

+0

Есть ли причина для downvote? –

+0

Не уверен, что кто-то еще ниспровергнут, но мой будет за неспособность проверить код возврата «ReadProcessMemory», хотя он может и не потерпеть неудачу (если вы проверили его и укоротили свой код для удобочитаемости, это стоит отметить). Отдельно, вы можете захотеть увидеть, будет ли [Address Space Randomisation] (http://en.wikipedia.org/wiki/Address_space_layout_randomization) играть - что зависит от ваших настроек и версии компилятора, а также от версии ОС .... –

+0

Почему вы не предоставили код тестовой программы? Поскольку вопрос основан на этом, его исключение кажется безрассудным. – enhzflep

ответ

0

Хорошо работает здесь, используя win7 pro и 32-битные скомпилированные программы. Обе программы были созданы с помощью Mingw и Code :: Blocks, адрес целевой памяти был определен с использованием OllyDbg.

Я могу подтвердить, что задержка успешно изменена. Это цель getchar() - это значит, что задержка еще не началась, когда мы изменяем память целевой программы.

. Источник Целевая программа - main.c (hackMe.exe)

#include <windows.h> 

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

. Целевая область целевой программы (используя 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; 
} 
+0

Вы только что пишете это? –

+0

'main' Я написал для этого вопроса, остальные были скопированы и вставлены из десятилетнего проекта, который воспроизводил WinMine.exe (теневик) на XP. – enhzflep

+0

Я собираюсь скачать ming. Я предполагаю, что это как-то связано с визуальной студией 2013 года ... –

2

Скорее всего, призыв к ReadProcessMemory не удается. Поскольку вы не проверяете наличие ошибок, вы не можете этого знать. В документации сказано:

Возвращаемое значение

Если функция завершается успешно, возвращаемое значение равно нулю.

Если функция не работает, возвращаемое значение равно 0 (ноль). Чтобы получить расширенную информацию об ошибке, вызовите GetLastError.

Ваша проверка ошибок может выглядеть следующим образом:

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

Я думаю, что ReadProcessMemory терпит неудачу, потому что адрес вы передаете не является действительным в целевом процессе. И затем, когда вы выходите RMEM, вы просто выводите неинициализированные значения.

Первым шагом для вас является исправление обработки ошибок. Как только вы это сделаете, вы узнаете, какой вызов API завершился неудачно и почему он не работает. Тогда, скорее всего, вам просто нужно будет указать действительный адрес.

+1

Похоже, что маленький паскаль проскользнул туда с ': =' :) –

+0

@retired thanks –