Wake of Gods Forum | Форум Во Имя Богов

Full Version: Исследование героев
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Без проблем.

Ошибка по адресу 0x004417A4 (MOV EAX, [ESI+34h]) - попытка прочесть память по адресу 34h.
Ещё - отклонение, вызвавшее, скорее всего, эту ошибку - неправильная работа функции sub_5242E0, вызванной по адресу 0x00440064. Там идёт работа со стеком напрямую и извлекается неверное значение (по адресу 0x0052430F (MOV EBX, [EBP+arg_0]; arg_0 = 8])).

Но фишка-то в том, что всё это только при отладке. Просто в игре ничего такого нет.

P.S. Без включенного режима немодифицируемости (отключить - 32-й бит переменной v9501 = 1) ошибка будет в любом случае (правда, разная в игре и отладчике), но с этим я как-нибудь сам разберусь.
@@Exit:
    TEST ECX, EAX//Восстанавливаем испорченную команду.
    PUSH $440057

Духи говорят, что чего-то здесь не хватает.
А чего именно, они не говорят?
Говорят ))))

00440052 |. 8B4D 08 |MOV ECX,DWORD PTR SS:[ARG.1]
...
    JNZ @@Modify

    //Восстановление изначального кода: получение всех позиций рядом, на которых кто-то стоит побитно (Запись в ECX).
    MOV ECX, [EBP+8]
    JMP @@Exit
   
    //Модифицирование кода: запись 0 (будто на всех клетках рядом кто-то стоит) в возвращаемый результат.
    @@Modify:
    MOV ECX, 0
   
    @@Exit:
...

Эта функция, для того и нужна, чтобы либо выполнить MOV ECX,DWORD PTR SS:[ARG.1], что, как я понял равно MOV ECX, [EBP+8], либо поместить в ECX 0.
В моём случае она всегда выполняет первое.
А данная проца тоже мутная

PROCEDURE Damage_stack; ASSEMBLER; {$FRAME-}
ASM
    //Если 32-й бит в v9501 = 1, модифицируем.
    MOV EAX, DWORD PTR DS:[$890AD8]
    SHR EAX, 31
    TEST EAX, EAX
    JNZ @@Modify
   
    //Восстановление изначального кода: вызов функции, вычисляющей адрес конструкций для атакованного на определённой позиции (запись в EAX).
    MOV EAX, $4E7230
    CALL EAX
    JMP @@Exit
   
    //Модифицирование кода: проверка, надо ли атаковать текущий стек и запись адреса его конструкций или 0 в EAX.
    @@Modify:
    //Проверяем, какой стороне принадлежит проверяемый стек.
    CMP EBX, 21
    JAE @@Def_st
   
    //Если стек принадлежит атакующей стороне, помещаем в EAX соответствующий стеку бит из v9501.
    MOV EAX, DWORD PTR DS:[$890AD8]
    MOV CL, BL
    SHR EAX, CL
    JMP @@All_st
   
    //Если стек принадлежит защищающейся стороне, помещаем в EAX соответствующий стеку бит из v9502.
    @@Def_st:
    MOV EAX, DWORD PTR DS:[$890ADC]
    SUB EBX, 21
    MOV CL, BL
    SHR EAX, CL
    ADD EBX, 21

    //Оставляем в EAX 0 или помещаем в него адрес конструкций стека (в зависимости от начального значкния EAX, т. е. бита v-переменной).
    @@All_st:
    AND EAX, 1
    JZ @@Exit
    //EAX = $699420 + 1352*EBX + 21708.
    LEA ECX, DS:0[EBX*8]
    SUB ECX, EBX
    LEA EDX, [ECX+ECX*2]
    MOV ECX, DWORD PTR DS:[$699420]
    LEA EAX, [EBX+EDX*8]
    LEA EAX, [ECX+EAX*8+21708]
   
    @@Exit:
    PUSH $44009A
END;

Затирается вызов процедуры. Если переходим по JNZ @@Modify то там черт ногу сломит. Однозначно могу сказать только одно: если что-то не работает после твоего вмешательства, значит сам виноват. Проверяй код отладчиком.
Всё, что в modify сейчас не важно (на самом деле там выполняестся часть затёртой функции, но номер стека берётся не от адреса инфы о гексе, а из EBX), там действительно, возможно, есть ошибки, но на данном этапе всегда выполняется то, что не modify.


Проблема в том, что если я запущу игру с этой dll-кой, то всё будет работать. А при отладке - выдавать ошибку.
Короче, попробую отлаживать в Olly.
Без отладчика может работать, имея скрытые дефекты, нарушения целостности структур. А под отладчиком диапазон выделяемых адресов сдвигается и лажа даёт о себе знать.
Berserker Wrote:А под
отладчиком диапазон выделяемых адресов
сдвигается
Это как?
BEGIN
    HookCode(POINTER($440052), @Damage_ability, C_HOOKTYPE_JUMP);
    HookCode(POINTER($440064), @Damage_position, C_HOOKTYPE_JUMP);
    HookCode(POINTER($440095), @Damage_stack, C_HOOKTYPE_JUMP);
    HookCode(POINTER($440194), @Damage_target, C_HOOKTYPE_JUMP);
END.

Из всех врезок оставляй по одной и смотри при какой вылетает, а потом мудри.
Да, это мне стоило сделать с самого начала.Sm
Quote:Это как?
Отладчик выделяет память в процессе для своих нужд. Динамическую. То есть если без отладчика Angel.dll грузилась по адресу $3000000, то с отладчикаом запросто может по $300F000.
На участке кода:
Code:
.text:0044008E                 lea     ecx, [ecx+edx+1C4h]
.text:00440095                 call    sub_4E7230
.text:0044009A
.text:0044009A loc_44009A:
.text:0044009A
.text:0044009A                 mov     esi, eax
не должно меняться ESP.

Если же я делаю так:
то ESP послее выполнения выходит уменьшенным на 4. Почему?
На вид всё корректно. В упор не вижу ошибки. Попробуй трассировать по шагам.
SHR EAX, 31
    TEST EAX, EAX
    JNZ @@Modify

=>
    TEST EAX, EAX
    JS @@Modify

А вообще, мне не нравится, когда в одной процедуре стоят PUSH'и без POP'ов. Зачем так сделали?
Reference URL's