|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Июн 9, 2004 23:26:11 Допустим, есть игра - CS. Включаем её, смотрим - у нас 800 денег. Вопрос: как (т.е. по каким адресам) мне необходимо искать это значение с пом. ReadProcessMmory(), как мне идентифицировать именно его, что бы потом, например, поменять на другое знаечение? |
|
|
Дата: Июн 9, 2004 23:57:40 Вы не пробовали просмотреть в ручную содержимое памяти??? ЗЫ :) |
|
|
Дата: Июн 10, 2004 01:17:23 Идея стара как мир, но можно. 1)VirtualQueryEx 2)HeapWalk Получаешь адреса на куски памяти, ну а дальше сам знаешь... и в бой... Медленно, тупо, да и помогает против тупых прог. Самые первые игры чисел не скрывали/не шифровали. А шаз уже не времена ArtMoney... |
|
|
Дата: Июн 10, 2004 13:00:29 · Поправил: Flip Если интересно, то у меня есть небольшая програмка которая: Два модуля exe и dll. EXE внедряет DLL в нужный процесс. DLL содержит в себе GUI интерфейс, с HEX редактором памяти, Viewer-ом распеределения памяти в процессе (где какие страницы, хипы, dll ...), и поисковиком для постепенного поиска числа, т.е. сначало например ищеш все числа 800 затем тратишь немного и ищешь скажем 750 ... в конце остаются только те адреса в которых хранится кол-во денег и с помощью hex редактора их правишь. Проверял на Diablo 1.10, Вьетконг, Half-Life и т.п. ... всё вроде работало. Могу дать исходники этой проги, но написанна она мной давно на VC++ с различными изратами типа template, сейчас у меня их нет(исходников), т.к. валяются дома в архивах и прислать смогу не раньше чем завтра. |
|
|
Дата: Июн 11, 2004 12:08:35 Эти переменные должны хранится в какойто секции - верно? Для того что бы сократить диапазон перебора - необходимо знать в какой именно! Это верно? Допустим перебором я нашел это значение (допустим, что я нашел именно его), то после его изменения с пом. ReadProcessMeory() оно должно сразу поменяться на экране? И еще 1 дополн. вопрос: если я нашел смещение этой переменной в файле, могу ли я пересчитать (преобразовать) это значенеи в "адрес" по которому будет находится эта "переменная" в АП моего процеса, короче в памяти? |
|
|
Дата: Июн 11, 2004 12:40:00 > Эти переменные должны хранится в какойто секции - верно? Если переменная глобальная то конечно будет храниться в секции данных. Но это частный случай, я такого в играх почти не встречал(только в самых простых). Обычно такая переменная находится в хипе(могут быть и др. более экзотичные места типа стека и т.п.). >Для того что бы сократить диапазон перебора - необходимо знать в какой именно! Это верно? Искать её надо во всех страницах памяти помеченных как RW. (Имеет смысл в этот момент тормознуть все потоки того процесса в котором происходит поиск). >то после его изменения с пом. ReadProcessMeory() оно должно сразу поменяться на экране? На экране это значение обычно в играх меняется сразу, т.к. как правило его обновляют на каждом кадре из памяти(например Дьябло), но иногда его могут где-то закешировать и тогда только при каких-нибудь действиях напишется истинное значение (например в Героях). >если я нашел смещение этой переменной в файле, могу ли я пересчитать (преобразовать) это значенеи в "адрес" по которому будет находится эта "переменная" в АП моего процеса, короче в памяти? Если переменная глобальная и на файле не использовались никакие упаковщики, крипторы ..., короче если образ файла ничем не искажен то да. |
|
|
Дата: Июн 11, 2004 12:44:01 HeeS Эти переменные должны хранится в какойто секции - верно? конечно не в 100% случаях, но в большинстве они будут внутри секции (т.к. никто не мешает сделать PLAYER_STATUS * plStatus = new PLAYER_STATUS[..];// и т.п. и данные будут лежать уже не в диапазоне секций) необходимо знать в какой именно! Это верно? ну вряд ли в секции с кодом, в .data такое будет лежать но имена - это вещь не надежная. а если еще и упаковано чем-нибудь... то после его изменения с пом. ReadProcessMeory() оно должно сразу поменяться на экране? после изменения с помощью WriteProcessMemory а на счет мгновенного отражение на экране твоих действие - это уже от игры зависит, смотря как там происходит считывание данных игрока. если я нашел смещение этой переменной в файле, могу ли я пересчитать (преобразовать) это значенеи в "адрес" по которому будет находится эта "переменная" в АП моего процеса, короче в памяти? можешь, открой каким-нибудь PE редактором таблицу секций, и найди ту секцию, в которой лежит твоё смещение (ищи в диапазоне RawOffset...RawOffset+RawSize), потом к VirtualOffset этой секции прибавь (твоё_смещение_в_файле-RawOffset).. а чтобы проще, можешь взять HIEW, прыгнуть на заданное смещение в файле (F5, набрать смещение, ENTER) и HIEW тебе сам покажет соответствующее виртуальное смещение, если таковое имеется |
|
|
Дата: Июн 11, 2004 14:54:07 Вот что я проделал, поглядите: 1. Создал тестовую прогу: [Delphi] Глобально объявил 2 переменные. var i: Word; d: DWORD; i - нужна для испытаний, а d - для того что бы было легче найти i. Далее, по клику на кнопку: d := $F1F2F3F4; //все равно что!!! i := 800; (320h) И тут же просто вывожу некоторые данные об i:
Memo1.Lines.Add('i=800');
Memo1.Lines.Add('@i='+inttostr(DWORD(@i)))
В этой же проге сделал еще одну кнопочку, для того что бы просмотреть что находится в переменно i после того, как я проведу её изменение с пом. WriteProcessMemory. Вот что происходит по нажатию этой кнопы: ShowMessage(inttostr(i)); 2. Сделал дамп памяти 1ой проги. 3. Сделал 2ую прогу, которая и будет делать все преващения. Она делает: находит окно, получает Process ID, ну и открывает со всеми правами - dwProc := OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID); Далее, используя Hiew, я поглядел, в каком промежутке находится переменная i (320h), причем, она (это значение в памяти) встречалась не один раз - нужную я нашел, по близоси расоложенно d ($F1F2F3F4 = F4 F3 F2 F1 - в памятти). Потом, в небольшом цикле я искал байт "03" (20 03), просто для примера. var pbuf: byte; for dwCount := $4542E9 to $4542F5 do begin // эти адреса из Hiew'а ReadProcessMemory(dwProc, ptr(dwCount), @pbuf, 1, dwI); if (pbuf = byte(03)) then Memo1.Lines.Add(inttostr(dwCount)); end; Нужный адрес нашелся и вывелся в Memo: if (pbuf = byte(03)) then Memo1.Lines.Add(inttostr(dwCount)); Я взял этот адрес и дописал еще 2 строки после цикла: pbuf := byte(04); WriteProcessMemory(dwProc, ptr(4539120), @pbuf, 1, dwI); //4539120 - полученный адрес байта "03" Этими инструкциями я меняю "03" на "04" в итоге должно получится в памяти "04 20" 4. Включил 1ую прогу, нажал на 1ую кнопку - произошло присвоение к переменной i. Нажал на вторую кнопку - поглядел результат - i =800 - вроде все ок! Запустил 2ую прогу, нажал на кнопочку - пропатчился 1 байт 03 на 04. (имхо) Решил поглядеть точно ли пропатчился. Нажал на 2ую кнопку в 1ой проге, мне показалось число 800, а не 1056, как должно, вроде, быть. Нажал на 1ую кнопу, т.е. опять присвоил i:=800. Нажал на 2ую кнопу, т.е. просмотр переменно i - смотрю, опа, i = 1056. Как так, я же только что присвоил этой переменной, по новой, число 800? И как же мне в играх искать переменные? Может у кого есть пример, может на VC?! |
|
|
Дата: Июн 11, 2004 15:02:46 дизассемблер и отладчик тебе в помощь... или дай эти 2 проги |
|
|
Дата: Июн 11, 2004 15:20:54 |
|
|
Дата: Июн 11, 2004 15:24:15 у меня Delphi нету, кинь бинарники, funbit(at)funbit.орг |
|
|
Дата: Июн 11, 2004 16:51:21 |
|
|
Дата: Июн 11, 2004 18:48:03 ssx Что в нём такое? |
|
|
Дата: Июн 11, 2004 19:42:08 классно, мне понравилось :)) начнем с того, зачем ты делаешь вот это: for dwCount := $4542E9 to $4542F5 do begin
ReadProcessMemory(dwProc, ptr({dwImageBase + }dwCount), @pbuf, 1, dwI);
во-первых, ImageBase .ехе, в принципе, можно не получать, он будет 0x400000. а во-вторых, в этом коде ты прибавляешь к ImageBase адрес, в котором уже есть ImageBase. тобишь 0x4542E9 - это 0x400000+0x42E9. Нажал на 1ую кнопу, т.е. опять присвоил i:=800. Нажал на 2ую кнопу, т.е. просмотр переменно i - смотрю, опа, i = 1056. Как так, я же только что присвоил этой переменной, по новой, число 800? :) если посмотреть на эту строчку в коде: WriteProcessMemory(dwProc, ptr(4539120), @pbuf, 1, dwI); где 4539120 = 0x4542F0, а в hiew (хватит даже его) глянуть, что находится по этому адресу, то можно увидеть, что это адрес в секции кода: 004542E8 66C7054C6C45002003 mov word ptr [$00456C4C], $0320 т.е. ты меняешь КОНСТАНТУ_В_КОДЕ. не удивительно, что 1056 появляется после очередного нажания на первый батон. странно, зачем ты пишешь по этому адресу, когда тебе в листбокс и так добавился: @i=4549708 где 4549708 = 0x456C4C, что и является адресом в памяти, где лежит значение переменной i (смотри дизассемблерную строчку выше). в общем, если ты изменишь адрес в WriteProcessMemory на этот, все будет работать. |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.046 |