Current time: 25.11.2024, 11:49 Hello There, Guest! (LoginRegister)
Language: english | russian  

Post Reply 
Threaded Mode | Linear Mode
Исследование героев
» туториал(ы)
Author Message
GhostManSD Offline

Posts: 1054
Post: #286

В курсе. Но стандартный метод вроде такой:
1. При срабатывании хука - PUSHAD.
2. Далее прописать вызов функции.
3. POPAD.
4. Выполнить затертые команды.

Может, проблема в том, что у меня выполняется больше команд, чем я затираю?


Κακῆς ἀπ' ἀρχῆς γίγνεται τέλος κακόν.
04.02.2011 04:00
Visit this user's website Find all posts by this user Quote this message in a reply
Sav Offline

Posts: 2180
Post: #287

Затёртые команды и push адреса должны выполняться в любом случае (т. е. стоять в конце кода после всех меток). У тебя же не так.
04.02.2011 12:17
Find all posts by this user Quote this message in a reply
etoprostoya Offline

Posts: 1809
Post: #288

(04.02.2011 04:00)GhostManSD Wrote:  В курсе.
Тогда ты должен быть в курсе, что такие конструкции, как у тебя:
Code:
CMP DWORD [$887668], -1
    JNZ @@Change
    PUSH ECX
    PUSH $5CCEDF
    @@Change:
    MOV EAX, DW
    ...
    MOV REG, [ESP+OFFSET]
Будут работать совершенно по-разному, в зависимости от первого CMP. В одном случае возьмётся одно значение из стека, а в другом - другое. И так для всего кода программы, то есть ты делаешь ВЕСЬ код неправильным.
Нужно сделать так, чтобы ESP на метке @@Change был одинаков, независимо от проверки.
04.02.2011 12:24
Find all posts by this user Quote this message in a reply
GhostManSD Offline

Posts: 1054
Post: #289

Как? MOV EBP, ESP; затем в нужном месте (после метки) - MOV ESP, EBP?


Κακῆς ἀπ' ἀρχῆς γίγνεται τέλος κακόν.
04.02.2011 14:40
Visit this user's website Find all posts by this user Quote this message in a reply
Sav Offline

Posts: 2180
Post: #290

ESP - регистр, отвечающий за заполненность стека.
Чтобы он не сбивался, надо, чтобы push было столько же, сколько и pop вне зависимости от, того, как будет выполняться код.
Как-то так, хотя я не понимаю, что делает push 800 в таоём коде.

PROCEDURE HOOK_MageGuildEnter; ASSEMBLER; {$FRAME-}
    ASM
    PUSHAD // Push all registers
    PUSH 90003 // Push function number
    MOV EAX, $74CE30 // Move $74CE30 to EAX
    CALL EAX // Call ERM-function
    ADD ESP, 4 // Add 4 to ESP
    POPAD // Restore all registers
    MOV EDX, DWORD [$69954C]
    PUSH 800
    MOV ECX, DWORD [EDX+$38]
    MOVSX EDX, BYTE [ECX+4]
    CMP DWORD [$887668], -1
    JE @@L
    MOV EAX, DWORD [$887668]
    MOV ECX, DWORD [EAX*4+$68A36C]
    @@L:
    PUSH ECX
    PUSH $5CCEDF
END; // .PROCEDURE HOOK_MageGuildEnter
04.02.2011 15:08
Find all posts by this user Quote this message in a reply
MOP Offline
Moderators

Posts: 1468
Post: #291

(13.09.2010 21:00)Sav Wrote:  Прошу прощения за тупой вопрос: динамический адрес может меняться при нескольких запусках программы на одном компьютере или только на разных компьютерах? И вообще, может кто-нибудь дать мне точное определение этого понятия?
Что-то никто не дал нормальный ответ. Теперь попробую я.
Для этого маленького исследования потребуется (из прог, которые мне знакомы):
либо PE Explorer,
либо не так давно найденная мной замечательная и очень компактная программка LordPE,
либо супермаленькая прога Икзелиона, некогда выложенная Дьяконом в приложение к одному из туториалов,
да почти любой дизасм.
В любом случае, нужна программа, позволяющая посмотреть сегментацию экзешника, его деление на секции. В принципе, подходит та же IDA, только там почему-то не видна секция .rsrc (видимо, за ненадобностью).
Мне лично нравится отображение секций в PE Explorer. Поэтому приведу скрин с него:
Image: 7d6cfc22c277.jpg
Size of Raw Data – размер секции непосредственно в файле.
Virtual Size – размер секции во время работы приложения. Включает в себя Raw Size.
Virtual Adress – адрес начала секции в запущенном приложении.
Pointer of Raw Data – адрес начала секции в файле.
Нетрудно заметить, что для сод-секций Virtual Adress = Pointer of Raw Data + 400000h, а для вог-секций Virtual Adress = Pointer of Raw Data + 465000h.
Для записи/чтения требуется знать только статическое виртуальное пространство, подходящее для этих целей. Достаточно нескольких минут, чтобы понять, что есть три НЕподходящих области:
1. < 401000h. В этих адресах работает система, поддерживая работу запущенного приложения. Также там находится стек. Запись/чтение там просто бесполезны и могут убить приложение.
2. >=6AD000/<701000. Иначе говоря, вся секция .rsrc. Этой секции просто не выставлены флаги Readable/Writeable, поэтому никаких операций с ней не выйдет и всё закончится вылетом (хотя можно выставить флаги и юзать, но лучше уж добавить новую секцию). Львиную долю её занимают иконки экзешника, также там информация о файле, менюшка, доступная в оконном режиме, и прочее.
3. >=293512Ch (21AE12C + 787000). Основная динамическая память. Сюда подгружаются библиотеки, здесь создаёт свои аллоки экзешник.
Существует закономерность: чем больше размер буфера, выделяемого в динамической памяти, тем больше шансов, что его адрес будет более статичен. Отюда многие заблуждения и принятие динамических адресов за статические. Достаточно запустить игру под отладчиком, подгрузить дополнительную длл или ресурс, запустить exe на другой системе или машине – и адрес окажется вовсе не таким.

Вот и всё.
Дополнения и уточнения принимаются, так как этот пост написан на основе личного практического знания.


Circle of destruction, hammer comes crushing
Powerhouse of energy
Whipping up a fury, dominating flurry
We create the battery
04.02.2011 15:29
Find all posts by this user Quote this message in a reply
GhostManSD Offline

Posts: 1054
Post: #292

(04.02.2011 15:08)Sav Wrote:  Как-то так, хотя я не понимаю, что делает push 800 в таоём коде.
Code:
MOV EDX, DWORD [$69954C]
    PUSH 800
    MOV ECX, DWORD [EDX+$38]
    MOVSX EDX, BYTE [ECX+4]
Эти строки - оригинальный код. В т.ч. PUSH 800.
Попробовал твой код, Sav. Тоже вылет, только ошибка другая. А причина одна - безблагодатность. Ab Прикладываю crashlog.


Κακῆς ἀπ' ἀρχῆς γίγνεται τέλος κακόν.
04.02.2011 16:09
Visit this user's website Find all posts by this user Quote this message in a reply
Sav Offline

Posts: 2180
Post: #293

Если у тебя хук на 5CCDD7, то эти строчки не затираются, а значит - убери их. Лишний mov может и не страшно, а вот лишний push - страшно почти всегда.
04.02.2011 17:29
Find all posts by this user Quote this message in a reply
Дьякон Offline

Posts: 395
Post: #294

MOP, динамическая память - это память выделенная в процессе выполнения программы, такими функциями как GlobalAlloc, VirtualAlloc и др. Все секции exe являются статическими.


Страус труп (с) Бьерн
05.02.2011 00:23
Find all posts by this user Quote this message in a reply
Дьякон Offline

Posts: 395
Post: #295

MOV DWORD [$5CCED7], $8B0C85 // Change opcode
    MOV DWORD [$5CCED8], $68A36C // Change parameter

ты меняешь смещение на 1 байт а записываешь по 4 байта - определись.


Страус труп (с) Бьерн
05.02.2011 00:34
Find all posts by this user Quote this message in a reply
GhostManSD Offline

Posts: 1054
Post: #296

Дьякон, спасибо!
Теперь новый вопрос (скорее всего, к Берсу). В коде делаю вот так...

MOV EAX, DWORD [Адрес]
MOV DWORD [EventsParam], EAX

...и, по идее, код

!?FU90003;
!!SN:X?v1;
!!IF:M^%V1^;

должен выдавать сохраненное значение. Но ни фига, выдает какую-то постороннюю чушь. А если занести то же в v1...

MOV EAX, DWORD [Адрес]
MOV DWORD [$887668]

...и код прописать вот такой...

!?FU90003;
!!IF:M^%V1^;

...все выдается верно. Что я делаю не так?


Κακῆς ἀπ' ἀρχῆς γίγνεται τέλος κακόν.
05.02.2011 18:17
Visit this user's website Find all posts by this user Quote this message in a reply
Berserker Offline
Administrators

Posts: 16657
Post: #297

Code:
TYPE
    PEventParams    =    ^TEventParams;
    TEventParams    =    ARRAY[0..63] OF INTEGER;

VAR
  EventParams:        PEventParams;

BEGIN
    EventParams    :=    Win.GetProcAddr(Win.GetModuleHandle('Angel.dll'), 'EventParams');
END.
Не забыл про это?

MOV EAX, [Адрес]
MOV ECX, [EventParams]
MOV [ECX], EAX

EventParams - только указатель на массив, а не сам массив.


Скачать Герои 3 Эра и всё, что с ней связано / ERA 2.46f для старых модов
Поддержать проект
05.02.2011 18:43
Find all posts by this user Quote this message in a reply
MOP Offline
Moderators

Posts: 1468
Post: #298

(05.02.2011 00:23)Дьякон Wrote:  MOP, динамическая память - это память выделенная в процессе выполнения программы, такими функциями как GlobalAlloc, VirtualAlloc и др. Все секции exe являются статическими.
А я что-то другое написал?


Circle of destruction, hammer comes crushing
Powerhouse of energy
Whipping up a fury, dominating flurry
We create the battery
05.02.2011 19:16
Find all posts by this user Quote this message in a reply
GhostManSD Offline

Posts: 1054
Post: #299

Берс, спасибо огромное! Тысячный раз уже выручаешь! Вот только есть одна такая вот нехорошая штука... Как быть, если мне нужно поместить значение в X1 в одном хуке, а считывать - с другого? Например, в одном из адресов вычисляется что-то и заносится в EAX.
Hook1
    mov ecx, [EventParams]
    mov [ecx], eax
.Hook1

Hook2
    [моя функция]
.Hook2

При попытке считать SN:X он выдает всякую хрень. Как быть? В хуке 1 сохранять в левый адрес (типа v1) значение параметра, а в хуке 2 - передавать из этого адреса?


Κακῆς ἀπ' ἀρχῆς γίγνεται τέλος κακόν.
05.02.2011 21:56
Visit this user's website Find all posts by this user Quote this message in a reply
Berserker Offline
Administrators

Posts: 16657
Post: #300

Считывание:
mov ecx, [EventParams]
mov eax, [ecx] // eax = X1


Скачать Герои 3 Эра и всё, что с ней связано / ERA 2.46f для старых модов
Поддержать проект
05.02.2011 22:19
Find all posts by this user Quote this message in a reply
« Next Oldest | Next Newest »
Post Reply 


Forum Jump:

Powered by MyBB Copyright © 2002-2024 MyBB Group