· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.WIN32 —› Поиск переменной в памяти

Посл.отвђт Сообщен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

Вот эти две проги...

_1827186607__samples.zip


Дата: Июн 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