Сообщений: 856
Тем: 9
Зарегистрирован: Jul 2011
Репутация:
2,852
Собственно через ольгу посмотрел адрес и прочитал сколько нужно, тут вроде всё понятно.
[SRC="c++"]ReadProcessMemory(int hProcess, int lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);[/SRC]
Но после перезапуска приложения адрес меняется, чекать каждый раз руками не вариант, как быть?
Aka Stels
Сообщений: 2,455
Тем: 53
Зарегистрирован: Apr 2010
Репутация:
19,728
Никак. Память читается по виртуальным адресам, а не физическим. В каждом новом процессе месторасположение нужных данных - будет меняться.
Можно сканировать память процесса на наличие нужных бинарных паттернов и таким образом определять требуемый адрес.
Как пример, но для посикса (когда-то давно писал, тащемта, в винде даже удобнее должно быть, без всяких ptrace):
Код: void processScanMemory(pid_t pid, address_t ** addresses, int count) {
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL)) {
perror("Failed attach to process");
return;
}
uint8_t bPattern[] = {
0x48, 0x89, 0x97, 0x00, 0x00, 0x00, 0x00, //mov [rdi+offset], rdx
0x0f, 0x84, 0x00, 0x00, 0x00, 0x00, //je adr
0xf3, 0xc3, 0x00, 0x00 //repz ret
};
uint8_t bMask[] = {
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00
};
#define patternSize 4*sizeof(uint32_t)
#define dataSize patternSize+sizeof(uint32_t)
for (int i = 0; i < count; i++) {
address_t * adr = addresses[i];
long int start = adr->start;
long int end = adr->end;
#ifdef DUMP_X
char filename[128];
sprintf(filename, "./%ld_%lx-%lx.dump", (long int)pid, start, end);
FILE * dumpFd = fopen(filename, "w");
#endif
fprintf(stdout, "Scanning 0x%lx ... 0%lx\n", adr->start, adr->end);
uint8_t data[dataSize] = {0};
for (long int current = start; current < end; current += sizeof(int)) {
uint32_t word = ptrace(PTRACE_PEEKDATA, pid, (void *) current, NULL);
memmove(data, data + sizeof(uint32_t), dataSize - sizeof(uint32_t));
*((uint32_t *)&(data[dataSize - sizeof(uint32_t)])) = word;
int finded = -1;
for(int j = 0; j < sizeof(uint32_t); j++) {
int sub = 1;
for(int k = 0; k < patternSize; k++) {
if ((data[k + j] & bMask[k]) != bPattern[k]) {
sub = 0;
break;
}
}
if(sub) {
finded = j;
break;
}
}
if (finded != -1) {
for (int a = 0; a < dataSize; a++) {
fprintf(stdout, "%02x ", data[a] & 0xff);
}
fprintf(stdout, "\n");
fprintf(stdout, "Finded pattern on: 0x%lx (phy offset: 0x%lx)", current, current - start - dataSize - finded);
}
#ifdef DUMP_X
fwrite(&word, sizeof(uint32_t), 1, dumpFd);
#endif
}
#ifdef DUMP_X
fclose(dumpFd);
#endif
}
if(ptrace(PTRACE_DETACH, pid, NULL, NULL)) {
perror("Failed deattach from process\n");
}
}
m0nster.art - clear client patches, linkz to utils & code.
Гадаю по капче.
Сообщений: 17
Тем: 6
Зарегистрирован: Jul 2013
Репутация:
466
Смотря какое значение, если это к примеру деньги в игре, они находятся в какой-то структуре, эта структура создается кем-то. Можно найти статический адресс и от него отталкиватся, чтобы менять значение денег. К примеру:
PHP код: <?php
LPDWORD gameAddr = (LPDWORD)0x12345678;
LPDWORD playerAddr = (LPDWORD)((LPDWORD)*(gameAddr + 3));
LPDWORD moneyAddr = (LPDWORD)((LPDWORD)(*playerAddr) + 8);
*moneyAddr = 5000;
Но лучше всё это делать с помощью структур. Чтобы не запутаться.
|