11.09.2010, 18:23
Улучшил dll.
Выкладываю только исходник.
Добавлено:
Теперь при вызове функции в x1 заносится номер атакующего стека (Upd: на самом деле не правильно заносится.) (его, кстати, нельзя получить в !?MF1;), что, скорее всего, позволит очень сильно упростить скрипт горыныча.
Выкладываю только исходник.
Spoiler (Click to View)
LIBRARY HookAfterDamage;
{!INFO
MODULENAME = 'AfterDamage'
VERSION = '1.0'
AUTHOR = 'Sav'
}
USES Win, Utils, SysUtils, VPUtils;
//PROCEDURE HookCode(P: POINTER; NewAddr: POINTER; UseCall: BOOLEAN); external 'angel' name 'HookCode';
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; // .record THookRec
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 WriteAtCode
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; // .procedure HookCode
PROCEDURE Hook_AfterDamage; ASSEMBLER; {$FRAME-}
ASM
PUSHAD
SUB ECX, $4463CEC
MOV EDX, 0
MOV EAX, ECX
MOV BX, $548
DIV BX
MOV [$91DA38], AX
PUSH 9500//номер ERM-функции.
MOV EAX, $74CE30
CALL EAX//вызываем C_FUNC_ZVS_CALLFU
ADD ESP, 4
POPAD
PUSH EBX
MOV EBX, $7C8554
MOV EAX, CS:[EBX]
POP EBX
CALL EAX
PUSH $756E41
END;
BEGIN
HookCode(POINTER($756E3B), @Hook_AfterDamage, C_HOOKTYPE_JUMP);
END.
{!INFO
MODULENAME = 'AfterDamage'
VERSION = '1.0'
AUTHOR = 'Sav'
}
USES Win, Utils, SysUtils, VPUtils;
//PROCEDURE HookCode(P: POINTER; NewAddr: POINTER; UseCall: BOOLEAN); external 'angel' name 'HookCode';
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; // .record THookRec
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 WriteAtCode
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; // .procedure HookCode
PROCEDURE Hook_AfterDamage; ASSEMBLER; {$FRAME-}
ASM
PUSHAD
SUB ECX, $4463CEC
MOV EDX, 0
MOV EAX, ECX
MOV BX, $548
DIV BX
MOV [$91DA38], AX
PUSH 9500//номер ERM-функции.
MOV EAX, $74CE30
CALL EAX//вызываем C_FUNC_ZVS_CALLFU
ADD ESP, 4
POPAD
PUSH EBX
MOV EBX, $7C8554
MOV EAX, CS:[EBX]
POP EBX
CALL EAX
PUSH $756E41
END;
BEGIN
HookCode(POINTER($756E3B), @Hook_AfterDamage, C_HOOKTYPE_JUMP);
END.
Добавлено:
Теперь при вызове функции в x1 заносится номер атакующего стека (Upd: на самом деле не правильно заносится.) (его, кстати, нельзя получить в !?MF1;), что, скорее всего, позволит очень сильно упростить скрипт горыныча.