Работа с памятью игры, exe
|
|
walk | Дата: Суббота, 28.05.2011, 09:48 | Сообщение # 196 |
Группа: Проверенные
Сообщений: 96
Статус: Offline
| Vital, это я знаю, просто мне надо без использования сцм, я уже столько не занимался скриптингом, что абсолютно всё по забывал
|
|
| |
DK22Pac | Дата: Суббота, 28.05.2011, 14:47 | Сообщение # 197 |
$player_actor
Группа: Проверенные
Сообщений: 559
Статус: Offline
| Денис, я попытался привентить код с созданием проекции в CAutomobile_preRender, но игра вылетает когда начинает создаватся автомобиль (т.е. когда выйти на "улицу"). Может, надо как-то очищать стек после вызова функции? Писали ведь, что только методы сами за собой "чистят". Оффсеты проверял уже несколько раз. Если просто делать прыжок в асм, выполнение команд, которые были "утеряны" для того, чтобы вписать команду "прыжка": Code 8B 46 14 // mov eax, dword ptr ds:[esi+14h] 8B CE // mov ecx, esi И "выпрыгнуть" назад, то всё работает. С регистрами тоже, вроде бы, всё нормально. В esi с самого начала записан car_struct. Ещё есть вероятность, что я неправильно записываю указатель на RwV3D.Добавлено (28.05.2011, 14:47) ---------------------------------------------
Code {$CLEO .cs} 0@ = 0x707390 0AC6: 1@ = label @_call__sub_707390h offset inc(1@, 4) var 0@: int 1@: int end 0@ -= 1@ 0AC6: 1@ = label @_call__sub_707390h offset 0A8C: 1@ 4 0@ 0 // sub_707390h 0@ = 0x6ABCB8 0AC6: 1@ = label @_jmp__6ABCB8h offset inc(1@, 4) var 0@: int 1@: int end 0@ -= 1@ 0AC6: 1@ = label @_jmp__6ABCB8h offset 0A8C: 1@ 4 0@ 0 // 6ABCB9h 0A8C: 0x6ABCB3 1 0xE9 1 // jmp 0AC6: 0@ = label @__asm offset 0@ -= 0x6ABCB8 0A8C: 0x6ABCB4 4 0@ 1 // @__asm while true wait 500 end
:__asm hex 8B CE // mov ecx, esi 83 C1 14 // add ecx, 14h 8B 01 // mov eax, dword ptr ds:[ecx] 83 C0 30 // add eax, 30h // *RwV3D 6A 00 // push 0 6A 00 // push 0 68 00 00 C0 3F // push 3FC00000h 6A 00 // push 0 68 00 00 70 41 // push 41700000h 6A FF // push FFh 6A 00 // push 0 6A 00 // push 0 6A FF // push FFh 68 00 00 C0 3F // push 3FC00000h 68 00 00 80 3F // push 3F800000h 68 00 00 80 3F // push 3F800000h 68 00 00 C0 3F // push 3FC00000h 50 // push eax 68 D0 26 87 00 // push offset aShad_exp 6A 02 // push 2 E8 // call sub_707390 end :_call__sub_707390h hex 00 00 00 00 // @_call__sub_707390h 83 C4 40 // add esp, 40h 8B 46 14 // mov eax, dword ptr ds:[esi+14h] 8B CE // mov ecx, esi E9 // jmp 6ABCB9h end :_jmp__6ABCB8h hex 00 00 00 00 // @_jmp__6ABCB9h end
|
|
| |
Den_spb | Дата: Суббота, 28.05.2011, 16:19 | Сообщение # 198 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
| Quote (DK22Pac) Может, надо как-то очищать стек после вызова функции? Писали ведь, что только методы сами за собой "чистят". Для хранения указателя на вершину стека используется регистр esp. Стек растёт "сверху вниз", поэтому при добавлении на стек новых данных командой push, указатель уменьшается, а при извлечении данных (команда pop), указатель увеличивается. Для чистки стека используется команда add esp, "поднимающая" указатель на вершину на прежнюю "высоту". Если имеем дело с функцией, то add esp выполняется после вызова этой функции (команда стоит в коде вызывающей функции), а если имеем дело с методом, то add esp выполняется в конце кода самого метода. Поэтому и говорят, что метод сам чистит за собой стек (в отличие от функции). В твоём случае очистка осуществляется здесь:Code 00 00 00 00 // @_call__sub_707390h 83 C4 40 // add esp, 40h Кстати, команда вызова функции недописана - она должна начинаться с опкода (ненулевой байт).
|
|
| |
DK22Pac | Дата: Суббота, 28.05.2011, 16:39 | Сообщение # 199 |
$player_actor
Группа: Проверенные
Сообщений: 559
Статус: Offline
| Quote (Den_spb) В твоём случае очистка осуществляется здесь: Понятно, а то я её просто так приписал, как раз думал, что она необходима (она и в оригинале стоит там) Спасибо что подсказал. Quote (Den_spb) Кстати, команда вызова функции недописана - она должна начинаться с опкода (ненулевой байт). Это? Quote (DK22Pac) E8 // call sub_707390
|
|
| |
Den_spb | Дата: Суббота, 28.05.2011, 16:41 | Сообщение # 200 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
| Да. И здесь опкода нет:Code 00 00 00 00 // @_jmp__6ABCB9h А в чём вообще смысл скрипта?
|
|
| |
DK22Pac | Дата: Суббота, 28.05.2011, 17:47 | Сообщение # 201 |
$player_actor
Группа: Проверенные
Сообщений: 559
Статус: Offline
| Там есть опкод, я просто разделил опкод и параметр, чтобы легче оффсет находить и не добавлять никаких смещений. Смысл кода состоит в том, чтобы рисовать проекцию сразу в preRender. PS Занопил вызов sub_707390 из этого асм-инжектора, и игра не вылетает. Значит, проблема именно в её вызове. (т.е. не в оффсетах или чём-либо другом)Добавлено (28.05.2011, 17:15) ---------------------------------------------
Что означает параметр 40h? Может надо другой параметр?Добавлено (28.05.2011, 17:47) --------------------------------------------- Как всегда... Полдня потратил на написание кода и опять всё в никуда...
|
|
| |
Den_spb | Дата: Воскресенье, 29.05.2011, 00:30 | Сообщение # 202 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
| Quote (DK22Pac) Что означает параметр 40h? Может надо другой параметр? Значение, на которое увеличивается указатель вершины стека. Пример - структура переменных некой функции выглядит следующим образом:Quote Create_rope proc near
var_38= dword ptr -38h var_34= dword ptr -34h var_30= dword ptr -30h var_2C= dword ptr -2Ch var_28= dword ptr -28h var_24= dword ptr -24h var_20= dword ptr -20h var_1C= dword ptr -1Ch var_18= dword ptr -18h var_14= dword ptr -14h var_10= dword ptr -10h var_C= dword ptr -0Ch var_8= dword ptr -8 var_4= dword ptr -4 arg_0= dword ptr 4 arg_4= byte ptr 8 arg_8= dword ptr 0Ch arg_C= dword ptr 10h arg_10= dword ptr 14h arg_14= byte ptr 18h arg_18= byte ptr 1Ch arg_1C= byte ptr 20h arg_20= dword ptr 24h arg_24= dword ptr 28h Первый из передаваемых параметров имеет смещение +0x28 от точки возврата. Тогда вызов данной функции и чистка стека осуществляется следующим образом:Quote .text:006C7849 064 push eax ; point .text:006C784A 068 push edx ; m .text:006C784B 06C lea edx, [esp+6Ch+outPoint] ; Load Effective Address .text:006C784F 06C push edx ; outPoint .text:006C7850 070 call _transformPoint ; outPoint = m*point; .text:006C7855 070 mov edx, [eax] .text:006C7857 070 add esp, 0Ch ; Add .text:006C785A 064 push 4E20h .text:006C785F 068 push 0 .text:006C7861 06C push 0 .text:006C7863 070 push 0 .text:006C7865 074 push 0 .text:006C7867 078 sub esp, 0Ch ; Integer Subtraction .text:006C786A 084 mov ecx, esp .text:006C786C 084 mov [ecx], edx .text:006C786E 084 mov edx, [eax+4] .text:006C7871 084 mov eax, [eax+8] .text:006C7874 084 lea ebx, [edi-9BAh] ; Load Effective Address .text:006C787A 084 mov [ecx+4], edx .text:006C787D 084 push 8 .text:006C787F 088 push ebx .text:006C7880 08C mov [ecx+8], eax .text:006C7883 08C call Create_rope ; Call Procedure вызов функции .text:006C7888 08C mov al, [edi] .text:006C788A 08C add esp, 28h ; Add чистка стека Несложно понять, что значение в команде add esp должно быть изменено в том случае, если в код функции были добавлены команды push, pop или другие команды, меняющие значение esp.
|
|
| |
DK22Pac | Дата: Воскресенье, 29.05.2011, 01:11 | Сообщение # 203 |
$player_actor
Группа: Проверенные
Сообщений: 559
Статус: Offline
| Я сделал всё, как и в оригинальной функции. Но по-прежнему вылетает. Добавлено (29.05.2011, 00:52) ---------------------------------------------
Code :__asm hex 8B CE // mov ecx, esi 83 C1 14 // add ecx, 14h 8B 01 // mov eax, dword ptr ds:[ecx] 83 C0 30 // add eax, 30h // *RwV3D 6A 00 // push 0 byte 6A 00 00 00 00 // push 0 dword 68 00 00 C0 3F // push 3FC00000h dword 6A 00 // push 0 byte 68 00 00 70 41 // push 41700000h dword 6A FF // push FFh byte 6A 00 // push 0 byte 6A 00 // push 0 byte 6A FF 00 00 00 // push FFh word 68 00 00 C0 3F // push 3FC00000h dword 68 00 00 00 00 // push 0 dword 68 00 00 00 00 // push 0 dword 68 00 00 C0 3F // push 3FC00000h dword 50 // push eax dword 68 D0 26 87 00 // push offset aShad_exp dword 6A 02 // push 1 byte E8 // call sub_707390 end :_call__sub_707390h hex 00 00 00 00 // @_call__sub_707390h 83 C4 40 // add esp, 40h 8B 46 14 // mov eax, dword ptr ds:[esi+14h] 8B CE // mov ecx, esi E9 // jmp 6ABCB9h end :_jmp__6ABCB8h hex 00 00 00 00 // @_jmp__6ABCB9h end Добавлено (29.05.2011, 01:11) --------------------------------------------- PS Эту кодину я вставляю перед тем местом, где рисуются проекции передних фар.
|
|
| |
walk | Дата: Воскресенье, 29.05.2011, 05:59 | Сообщение # 204 |
Группа: Проверенные
Сообщений: 96
Статус: Offline
| DK22Pac, помнится ты писал где-то, как сделать нех буфер, для записи туда различных значений, вместо переменных. Можешь привести пример, как им пользоваться. Заранее спасибо
|
|
| |
DK22Pac | Дата: Пятница, 03.06.2011, 21:33 | Сообщение # 205 |
$player_actor
Группа: Проверенные
Сообщений: 559
Статус: Offline
| Запись в буффер координат игрока: Code {$CLEO .cs} 0000: while not player.Defined(0) wait 0 end actor.StorePos($player_actor, 0@, 1@, 2@) 0AC6: 3@ = label @buffer offset // Получаем глобальный адресс нашего буффера 0A8C: write_memory 3@ size 4 value 0@ virtual_protect 0 3@ += 4 // + 4 байта 0A8C: write_memory 3@ size 4 value 1@ virtual_protect 0 3@ += 4 // + 4 байта 0A8C: write_memory 3@ size 4 value 2@ virtual_protect 0 0A93:
:buffer hex 00 00 00 00 // 4 байта ; место для хранения X-координаты 00 00 00 00 // 4 байта ; место для хранения Y-координаты 00 00 00 00 // 4 байта ; место для хранения Z-координаты end Для записи float надо выделять 4 байта. 00 - это один байт. Получив адресс метки buffer, мы уже получили адресс первого байта. Далее мы записываем значение X-координаты по полученному адрессу, и прибавляем 4 байта, чтобы перейти на адресс, предназначеный для записи Y-координаты.Добавлено (03.06.2011, 21:33) --------------------------------------------- Денис, а можно каким-то макаром сделать горизонтальные проекции? Т.е. чтобы на стене были видны.
|
|
| |
Den_spb | Дата: Пятница, 03.06.2011, 23:31 | Сообщение # 206 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
| Думаю что можно, но как это сделать - не знаю.
|
|
| |
DK22Pac | Дата: Воскресенье, 05.06.2011, 19:12 | Сообщение # 207 |
$player_actor
Группа: Проверенные
Сообщений: 559
Статус: Offline
| Денис, мне вот надо впихнуть в ексе свой инжектор. Но куда именно его впихнуть, если я хочу, чтобы мой инжектор работал постоянно? (Т.е. чтобы код выполнялся с каждым оборотом ексешного кода)
|
|
| |
Den_spb | Дата: Воскресенье, 05.06.2011, 20:47 | Сообщение # 208 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
| К примеру в базе есть такие функции: CGame__Process (0x0053BEE0) CGameLogic__update (0x00442AD0) Но не легче ли вызывать код скриптом?
|
|
| |
DK22Pac | Дата: Воскресенье, 05.06.2011, 22:06 | Сообщение # 209 |
$player_actor
Группа: Проверенные
Сообщений: 559
Статус: Offline
| Денис, я думаю, "отставание" можно избежать, избавившись от wait 0. Может и ошибаюсь... Да и ещё, как я заметил, в игре, проекции отстают от машин NPC и не отстают от авто ГГ, что ввело меня в ступор.
|
|
| |
Den_spb | Дата: Воскресенье, 05.06.2011, 23:11 | Сообщение # 210 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
| Quote (DK22Pac) избавившись от wait 0. Когда я решал подобную задачу с коронами, у меня тоже были подобные версии, но секрет фокуса оказался другой - одним из параметров, передаваемых в функцию создания короны, является указатель на структуру объекта. Что касается wait 0 - убрать его нельзя, да и смысла в этом нет, т.к. эта команда приостанавливает работу текущего скрипта, дав возмость отработать другим скриптам и нескриптовым процессам exe. Quote (DK22Pac) Да и ещё, как я заметил, в игре, проекции отстают от машин NPC и не отстают от авто ГГ, что ввело меня в ступор. В одной из процедур цепочки CAutomobile__preRender -> 0x707390 осуществляется проверка - является ли машина транспортом игрокаCode .text:0070C6F8 01C call _getPlayerVehicle ; CPed * ped = getPlayerPed (_a0); return ped && ped->_f46C & 0x100 ? (_a4 && players[currentPlayer]._fB0 ? players[currentPlayer]._fB0 : ped->_f58C) : NULL; .text:0070C6FD 01C mov ecx, [esp+1Ch+arg_28] .text:0070C701 01C mov edx, [esp+1Ch+arg_24] .text:0070C705 01C cmp esi, eax Может дело в этом, а может быть и ещё в чём. Хорошо бы определить назначение параметров каждой из процедур CAutomobile__preRender -> 0x707390. Если всё-таки задачу решить не получится (а может она и не решаема?), то на крайний случай можно создавать проекции опкодом, прибавляя к оффсетам поправку, зависящую от текущей скорости машины.
|
|
| |