WINAPI ReadProcessMemory sempre o mesmo endereço
-
12-12-2019 - |
Pergunta
Eu li alguns dados a partir de um processo (endereço:0x58F03C) usando a função WINAPI ReadProcessMemory
:
DWORD proc_id;
GetWindowThreadProcessId(hwnd, &proc_id);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proc_id);
int value=0;
while (1)
{
ReadProcessMemory(hProcess, (LPVOID)0x58F03C, &value, sizeof(value), 0);
cout << "val: " << value << endl;
}
Desde o endereço muda a cada vez que eu reiniciar o processo gostaria de saber se existe uma maneira de obter sempre o mesmo endereço?Deve ser porque eu vejo um monte de "Treinador-Programas" que são capazes de fazer isso.Como fazem para obter o endereço certo valor para ler / escrever?
Atualmente eu obtê-lo por meio da digitalização para um valor com a CheatEngine
e executar uma verificação seguinte para o valor alterado.
Obrigado.
Solução
Você está encontrando alocação dinâmica de memória.No CheatEngine mundo, estes são chamados de 'ponteiros'.
Considere alguns dados (por exemplo, um uint32_t
/DWORD
) dentro de uma memória que foi malloc
'd.Se você encontrar o endereço dos dados, não há nenhuma garantia de que a próxima vez que você iniciar o processo, o endereço será o mesmo.Isto é porque a memória retornada pelo malloc
poderia ser com base em um ponto diferente na memória.
O truque usado para derrotar alocação dinâmica de memória é encontrar uma pilha estática de endereços que pode levá-lo para o endereço do valor que você está interessado.O CheatEngine tutorial mostra como isso é feito.O mesmo se aplica para multi-nível de ponteiros.Em um nível superior, isto corresponde a memória alocada dinamicamente que contém um ponteiro para alguma outra memória alocada dinamicamente, e assim por diante.
O método utilizado no CheatEngine para obter ponteiros funciona aproximadamente como este:
- Definir um acesso ponto de interrupção de hardware, no endereço do valor de dados que você está interessado
- Quando o código de acessa-lo, a ponto de interrupção de hardware irá mostrar-lhe o que o código se parece com
O código será normalmente algo parecido com isso:
mov eax, 0x1234ABCD
dec dword ptr ds:[eax+0x85]
Isso pode corresponder a algum código que diminui o HP quando atingido por um inimigo.0x1234ABCD é o ponteiro, neste caso, e 0x85 o deslocamento.No código C, isso pode ter acontecido:
struct some_struct* blah = malloc(...);
...
blah->HP--;
0x1234ABCD gostaria de ser o endereço do blah
.A HP valor vive em algum lugar no interior do bloco apontado por blah
.O deslocamento para o bloco de memória é 0x85.Então se você fosse escrever um treinador, você iria ler o DWORD
(QWORD
se 64 bits) em 0x1234ABCD e adicionar 0x85 para o valor.Isto dar-lhe o endereço da HP valor.
Outras dicas
Isto irá funcionar se o endereço está no executável parte da seção de dados onde as variáveis pré-alocado ao vivo (não é adequado para a pilha e heap)...
Dê uma olhada no "A enumeração de Todos os Módulos De um Processo de" exemplo do MSDN.
Ele usa EnumProcessModules() para obter o módulo de alças.Essas são imagens da base de dados de endereços.
Você pode obter o endereço base da imagem para o executável e ajustar o seu endereço por ele.