Я проходил эту игру и с читами и без, так, что отложим моральную сторону, а будем делать маааленький реверс инжинеринг и можно будет посмотреть как вообще работают читы.
Для начала загружаем игру в OllyDbg и смотрим на состояние денег в игре, нам нужно найти количество перевести его в 16чный формат и поискать в памяти. Изначально денег 10000 прикупив пару вещей доводим его до 6750, так будет проще искать.
Переводим это число в 16чный формат и получаем 1A 5E. Это число и будем искать в памяти, единственное, не забываем, что в x86 числа хранятся наоборот, тоесть искать надо будет 5E 1A. Но таких числе в памяти 2 вязанки, по этому необходимо сузить поиск, предположим, что число хранится в DWORD и значит перед числом будет 2 нуля. Итоговое значение которое ищем получается 00 00 5E 1A.
Переключаем OllyDBG в раздел памяти, нажимая по кнопочке M в верхней панели. По правой кнопки мыши вызываем панель поиска.
Вбиваем предполагаемое число и находим только одну похожу ячейку памяти. Смотрим на скрин ниже.
Очень похоже, что это именно то, что мы ищем. Меняем значение на FF FF FF FF и переключаемся в игру. В игре должно показываться что то типа такого:
Ага, это то что нам нужно, запоминаем адрес где лежит эта ячейка, в моей версии Tyrian она находится по адресу: 004E879E
Ну а теперь нада написать свой чит, который будет работать без правок руками.
Немного говнокода:
start: mov eax, sizeof lprocentry ; вычисляем размер PROCESSENTRY32 mov lprocentry.dwSize, eax ; записываем его в PROCESSENTRY32.dwSize invoke CreateToolhelp32Snapshot,TH32CS_SNAPPROCESS OR TH32CS_SNAPMODULE, NULL ; получаем снапшот списка процессов .if eax == NULL jmp errorExit ; если 0, то получить не удалось и выходим .endif mov hSnap, eax invoke Process32First, hSnap, offset lprocentry ; получаем название первого процесса .if eax == NULL jmp errorExit ; если 0, то получить не удалось и выходим .endif mainsearch: ; так как касперский посчитал что использование lstrcmp - это троян, изобретаем свой велосипед с дамами и бриджем mov ecx, sizeof processname ; записываем длину имени поцесса mov edi, offset lprocentry.szExeFile ; записываем указатель название процесса который в структуре PROCESSENTRY32 mov esi, offset processname ; записываем указатель название процесса который ищем nextsimb: mov al, BYTE PTR [esi] ; копируем первый байт из названия процесса в al .if al != BYTE PTR [edi] ; сравниваем с первым байтом в найденом процессе jmp nextproc ; ежели не совпадает идем к следующему процессу .endif inc esi ; сдвигаем курсор на 1 в названии процесса inc edi ; сдвигаем курсор на 1 в найденом процессе loop nextsimb ; повторять пока все символы не сойдутся или не кончится строка mov eax, lprocentry.th32ProcessID ; записываем PID найденого процесса в eax mov pid, eax ; а его собственно в переменную pid jmp processfound ; уходим на обработку Pid nextproc: invoke Process32Next, hSnap, offset lprocentry ; обрабатываем следующий процесс .if eax == NULL jmp errorExit ; если 0, то получить не удалось и выходим .endif jmp mainsearch ; повторяем основной цикл processfound: invoke OpenProcess, PROCESS_VM_OPERATION OR PROCESS_VM_WRITE, FALSE, pid ; открываем процесс на запись .if eax == NULL jmp errorExit ; если 0, то открыть не удалось и выходим .endif invoke WriteProcessMemory, eax, moneycell, offset buf, sizeof buf, NULL ; записываем FF FF FF FF в ячейку памяти .if eax == NULL jmp errorExit ; если 0, то записать не удалось и выходим .endif invoke MessageBox, NULL, offset wCheatOk, offset wTitle,MB_OK ; выводим сообщение что чит активирован jmp normalExit ; выходим errorExit: invoke MessageBox, NULL, offset wCheatErr, offset wTitle,MB_ICONERROR ; выводим сообщение что чит активировать не удалось normalExit: invoke ExitProcess,0 end start
Ну собсно и целиковый код на пастебине - http://pastebin.com/ZNDPLUJN
На сегодня все. :)
Комментариев нет:
Отправить комментарий