Без проблем. 
LIBRARY HookDamage; 
{!INFO 
MODULENAME = 'Damage' 
VERSION = '1.0' 
AUTHOR = 'Sav' 
} 
 
USES Win, Utils, SysUtils, VPUtils; 
 
CONST    (* HookCode constants *)    C_HOOKTYPE_JUMP = FALSE;    C_HOOKTYPE_CALL = TRUE;    C_OPCODE_JUMP = $E9;    C_OPCODE_CALL = $E8;    C_UNIHOOK_SIZE = 5; 
 
TYPE 
THookRec = RECORD    Opcode: BYTE;    Ofs: INTEGER; 
END; 
 
VAR 
Temp: INTEGER; 
 
PROCEDURE WriteAtCode(P: POINTER; Buf: POINTER; Count: INTEGER); 
BEGIN    Win.VirtualProtect(P, Count, PAGE_READWRITE, @Temp);    Win.CopyMemory(P, Buf, Count);    Win.VirtualProtect(P, Count, Temp, NIL); 
END; 
 
PROCEDURE HookCode(P: POINTER; NewAddr: POINTER; UseCall: BOOLEAN); 
VAR    HookRec: THookRec; 
BEGIN    IF UseCall THEN BEGIN     HookRec.Opcode:=C_OPCODE_CALL;    END // .if    ELSE BEGIN     HookRec.Opcode:=C_OPCODE_JUMP;    END; // .else    HookRec.Ofs:=INTEGER(NewAddr)-INTEGER(P)-C_UNIHOOK_SIZE;    WriteAtCode(P, @HookRec, 5); 
END; 
 
 
 
//Модификация удара с флагом бить всех вокруг. 
//Вместо вычисления 8-ми атакованных позиций, проверяется каждый из 42 стеков на необходимость атаки по нему (записанную в v-переменных). 
//$890AD8 - v9501 - номера целевых стеков атакующего (побитно), $890ADC - v9502 - номера целевых стеков защищающегося (побитно). 
 
//Модификация условия выполнения прохода цикла (в функции $440030). 
//Запись 0 (что значит - все позиции вокруг могут быть атакованы). 
//Без модификации значение - начение - смежные позиций побитно от правой нижней против часовой стрелки (0 - доступна). 
PROCEDURE Damage_ability; ASSEMBLER; {$FRAME-} 
ASM    //Если 32-й бит в v9501 = 1, модифицируем.    PUSH EAX    MOV EAX, DWORD PTR DS:[$890AD8]    SHR EAX, 31    TEST EAX, EAX    POP EAX    JNZ @@Modify        //Восстановление изначального кода: получение всех позиций рядом, на которых кто-то стоит побитно (Запись в ECX).    MOV ECX, [EBP+8]    JMP @@Exit        //Модифицирование кода: запись 0 (будто на всех клетках рядом кто-то стоит) в возвращаемый результат.    @@Modify:    MOV ECX, 0        @@Exit:    TEST ECX, EAX//Восстанавливаем испорченную команду.    PUSH $440057 
END; 
 
//Модификация вызова функции, вычисляющей позицию текущего атакованного (в функции $440030). 
//Автоматическое возвращение 1 (легальной позиции) (в EAX), т. к. позиция может быть вычислена неправильно, если будет больше 8 атакованных. 
PROCEDURE Damage_position; ASSEMBLER; {$FRAME-} 
ASM    //Если 32-й бит в v9501 = 1, модифицируем.    MOV EAX, DWORD PTR DS:[$890AD8]    SHR EAX, 31    TEST EAX, EAX    JNZ @@Modify        //Восстановление изначального кода: вызов функции, вычисляющей позицию текущего атакованного (Запись в EAX).    MOV EAX, $5242E0    CALL EAX//Внутри функции используется ESP - нельзя использовать PUSH перед ней.    JMP @@Exit        //Модифицирование кода: запись 1 (легальной позиции) в возвращаемый результат.    @@Modify:    MOV EAX, 1        @@Exit:    PUSH $440069 
END; 
 
//Модификация вызова функции вычисления адреса конструкций для атакованного на определённой позиции (в функции $440030). 
//Вместо вычисления стека по позиции, смотрим в бите v-переменной, надо ли атаковать текущий проверяемый стек. 
//Если надо, возвращаем (в EAX) $699420 + 1352*номер стека + 21708, иначе 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; 
 
//Модификация условия выхода из цикла (в функции $440030). 
//42 прохода (для каждого стека) вместо стандартных 8 (для каждой возможной позиции около атакующего). 
PROCEDURE Damage_target; ASSEMBLER; {$FRAME-} 
ASM    PUSH EAX        //Если 32-й бит в v9501 = 1, модифицируем.    MOV EAX, DWORD PTR DS:[$890AD8]    SHR EAX, 31    TEST EAX, EAX    JNZ @@Modify        //Восстановление изначального кода: сравнивание номера текущего атакованного с 8.    CMP EBX, 8    JMP @@Exit        //Модифицирование кода: сравнивание номера текущего атакованного с 42.    @@Modify:    CMP EBX, 42        @@Exit:    POP EAX    MOV [EBP-12], EBX//Восстанавливаем испорченную команду.    PUSH $44019A 
END; 
 
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. 
Ошибка по адресу 0x004417A4 (MOV EAX, [ESI+34h]) - попытка прочесть память по адресу 34h. 
Ещё - отклонение, вызвавшее, скорее всего, эту ошибку - неправильная работа функции sub_5242E0, вызванной по адресу 0x00440064. Там идёт работа со стеком напрямую и извлекается неверное значение (по адресу 0x0052430F (MOV EBX, [EBP+arg_0]; arg_0 = 8])).
 
Но фишка-то в том, что всё это только при отладке. Просто в игре ничего такого нет.
 P.S. Без включенного режима немодифицируемости (отключить - 32-й бит переменной v9501 = 1) ошибка будет в любом случае (правда, разная в игре и отладчике), но с этим я как-нибудь сам разберусь.
			  
			
			
			
				
(This post was last modified: 14.11.2010 23:33 by Sav.)
 
			 
		 |