📄 afxcodehook.pas
字号:
{
Delphi Hooking Library by Aphex
http://www.iamaphex.cjb.net/
unremote@knology.net
}
unit afxCodeHook;
{$IMAGEBASE $13140000}
interface
uses
Windows;
function SizeOfCode(Code: pointer): dword;
function SizeOfProc(Proc: pointer): dword;
function InjectString(Process: LongWord; Text: pchar): pchar;
function InjectMemory(Process: LongWord; Memory: pointer; Len: dword): pointer;
function InjectThread(Process: dword; Thread: pointer; Info: pointer; InfoLen: dword; Results: boolean): THandle;
function InjectLibrary(Process: LongWord; ModulePath: string): boolean; overload;
function InjectLibrary(Process: LongWord; Src: pointer): boolean; overload;
function InjectExe(Process: LongWord; EntryPoint: pointer): boolean;
function UninjectLibrary(Process: LongWord; ModulePath: string): boolean;
function CreateProcessEx(lpApplicationName: pchar; lpCommandLine: pchar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles: boolean; dwCreationFlags: longword; lpEnvironment: pointer; lpCurrentDirectory: pchar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation; ModulePath: string): boolean; overload;
function CreateProcessEx(lpApplicationName: pchar; lpCommandLine: pchar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles: boolean; dwCreationFlags: longword; lpEnvironment: pointer; lpCurrentDirectory: pchar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation; Src: pointer): boolean; overload;
function HookCode(TargetModule, TargetProc: string; NewProc: pointer; var OldProc: pointer): boolean;
function UnhookCode(OldProc: pointer): boolean;
function DeleteFileEx(FilePath: pchar): boolean;
function DisableSFC: boolean;
implementation
type
TModuleList = array of cardinal;
PImageImportDescriptor = ^TImageImportDescriptor;
TImageImportDescriptor = packed record
OriginalFirstThunk: longword;
TimeDateStamp: longword;
ForwarderChain: longword;
Name: longword;
FirstThunk: longword;
end;
PImageBaseRelocation = ^TImageBaseRelocation;
TImageBaseRelocation = packed record
VirtualAddress: cardinal;
SizeOfBlock: cardinal;
end;
TDllEntryProc = function(hinstDLL: HMODULE; dwReason: longword; lpvReserved: pointer): boolean; stdcall;
TStringArray = array of string;
TLibInfo = record
ImageBase: pointer;
ImageSize: longint;
DllProc: TDllEntryProc;
DllProcAddress: pointer;
LibsUsed: TStringArray;
end;
PLibInfo = ^TLibInfo;
Ppointer = ^pointer;
TSections = array [0..0] of TImageSectionHeader;
const
IMPORTED_NAME_OFFSET = $00000002;
IMAGE_ORDINAL_FLAG32 = $80000000;
IMAGE_ORDINAL_MASK32 = $0000FFFF;
Opcodes1: array [0..255] of word =
(
(16913),(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),
(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),
(17124),(8209),(8420),(33793),(35906),(0),(32768),(16913),(17124),(8209),(8420),(33793),(35906),(0),(32768),(16913),
(17124),(8209),(8420),(33793),(35906),(0),(32768),(529),(740),(17),(228),(1025),(3138),(0),(32768),(24645),
(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(69),
(69),(69),(69),(69),(69),(69),(69),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(0),
(32768),(228),(16922),(0),(0),(0),(0),(3072),(11492),(1024),(9444),(0),(0),(0),(0),(5120),
(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(1296),
(3488),(1296),(1440),(529),(740),(41489),(41700),(16913),(17124),(8209),(8420),(17123),(8420),(227),(416),(0),
(57414),(57414),(57414),(57414),(57414),(57414),(57414),(32768),(0),(0),(0),(0),(0),(0),(32768),(33025),
(33090),(769),(834),(0),(0),(0),(0),(1025),(3138),(0),(0),(32768),(32768),(0),(0),(25604),
(25604),(25604),(25604),(25604),(25604),(25604),(25604),(27717),(27717),(27717),(27717),(27717),(27717),(27717),(27717),(17680),
(17824),(2048),(0),(8420),(8420),(17680),(19872),(0),(0),(2048),(0),(0),(1024),(0),(0),(16656),
(16800),(16656),(16800),(33792),(33792),(0),(32768),(8),(8),(8),(8),(8),(8),(8),(8),(5120),
(5120),(5120),(5120),(33793),(33858),(1537),(1602),(7168),(7168),(0),(5120),(32775),(32839),(519),(583),(0),
(0),(0),(0),(0),(0),(8),(8),(0),(0),(0),(0),(0),(0),(16656),(416)
);
Opcodes2: array [0..255] of word =
(
(280),(288),(8420),(8420),(65535),(0),(0),(0),(0),(0),(65535),(65535),(65535),(272),(0),(1325),(63),
(575),(63),(575),(63),(63),(63),(575),(272),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(16419),
(16419),(547),(547),(65535),(65535),(65535),(65535),(63),(575),(47),(575),(61),(61),(63),(63),(0),
(32768),(32768),(32768),(0),(0),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(8420),
(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(16935),
(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(237),
(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(101),(237),(1261),
(1192),(1192),(1192),(237),(237),(237),(0),(65535),(65535),(65535),(65535),(65535),(65535),(613),(749),(7168),
(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(16656),
(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(0),
(0),(32768),(740),(18404),(17380),(49681),(49892),(0),(0),(0),(17124),(18404),(17380),(32),(8420),(49681),
(49892),(8420),(17124),(8420),(8932),(8532),(8476),(65535),(65535),(1440),(17124),(8420),(8420),(8532),(8476),(41489),
(41700),(1087),(548),(1125),(9388),(1087),(33064),(24581),(24581),(24581),(24581),(24581),(24581),(24581),(24581),(65535),
(237),(237),(237),(237),(237),(749),(8364),(237),(237),(237),(237),(237),(237),(237),(237),(237),
(237),(237),(237),(237),(237),(63),(749),(237),(237),(237),(237),(237),(237),(237),(237),(65535),
(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(0)
);
Opcodes3: array [0..9] of array [0..15] of word =
(
((1296),(65535),(16656),(16656),(33040),(33040),(33040),(33040),(1296),(65535),(16656),(16656),(33040),(33040),(33040),(33040)),
((3488),(65535),(16800),(16800),(33184),(33184),(33184),(33184),(3488),(65535),(16800),(16800),(33184),(33184),(33184),(33184)),
((288),(288),(288),(288),(288),(288),(288),(288),(54),(54),(48),(48),(54),(54),(54),(54)),
((288),(65535),(288),(288),(272),(280),(272),(280),(48),(48),(0),(48),(0),(0),(0),(0)),
((288),(288),(288),(288),(288),(288),(288),(288),(54),(54),(54),(54),(65535),(0),(65535),(65535)),
((288),(65535),(288),(288),(65535),(304),(65535),(304),(54),(54),(54),(54),(0),(54),(54),(0)),
((296),(296),(296),(296),(296),(296),(296),(296),(566),(566),(48),(48),(566),(566),(566),(566)),
((296),(65535),(296),(296),(272),(65535),(272),(280),(48),(48),(48),(48),(48),(48),(65535),(65535)),
((280),(280),(280),(280),(280),(280),(280),(280),(566),(566),(48),(566),(566),(566),(566),(566)),
((280),(65535),(280),(280),(304),(296),(304),(296),(48),(48),(48),(48),(0),(54),(54),(65535))
);
function SaveOldFunction(Proc: pointer; Old: pointer): longword; forward;
function GetProcAddressEx(Process: LongWord; lpModuleName, lpProcName: pchar): pointer; forward;
function MapLibrary(Process: LongWord; Dest, Src: pointer): TLibInfo; forward;
function SizeOfCode(Code: pointer): longword;
var
Opcode: word;
Modrm: byte;
Fixed, AddressOveride: boolean;
Last, OperandOveride, Flags, Rm, Size, Extend: longword;
begin
try
Last := longword(Code);
if Code <> nil then
begin
AddressOveride := False;
Fixed := False;
OperandOveride := 4;
Extend := 0;
repeat
Opcode := byte(Code^);
Code := pointer(longword(Code) + 1);
if Opcode = $66 then
begin
OperandOveride := 2;
end
else if Opcode = $67 then
begin
AddressOveride := True;
end
else
begin
if not ((Opcode and $E7) = $26) then
begin
if not (Opcode in [$64..$65]) then
begin
Fixed := True;
end;
end;
end;
until Fixed;
if Opcode = $0f then
begin
Opcode := byte(Code^);
Flags := Opcodes2[Opcode];
Opcode := Opcode + $0f00;
Code := pointer(longword(Code) + 1);
end
else
begin
Flags := Opcodes1[Opcode];
end;
if ((Flags and $0038) <> 0) then
begin
Modrm := byte(Code^);
Rm := Modrm and $7;
Code := pointer(longword(Code) + 1);
case (Modrm and $c0) of
$40: Size := 1;
$80:
begin
if AddressOveride then
begin
Size := 2;
end
else
Size := 4;
end;
else
begin
Size := 0;
end;
end;
if not (((Modrm and $c0) <> $c0) and AddressOveride) then
begin
if (Rm = 4) and ((Modrm and $c0) <> $c0) then
begin
Rm := byte(Code^) and $7;
end;
if ((Modrm and $c0 = 0) and (Rm = 5)) then
begin
Size := 4;
end;
Code := pointer(longword(Code) + Size);
end;
if ((Flags and $0038) = $0008) then
begin
case Opcode of
$f6: Extend := 0;
$f7: Extend := 1;
$d8: Extend := 2;
$d9: Extend := 3;
$da: Extend := 4;
$db: Extend := 5;
$dc: Extend := 6;
$dd: Extend := 7;
$de: Extend := 8;
$df: Extend := 9;
end;
if ((Modrm and $c0) <> $c0) then
begin
Flags := Opcodes3[Extend][(Modrm shr 3) and $7];
end
else
begin
Flags := Opcodes3[Extend][((Modrm shr 3) and $7) + 8];
end;
end;
end;
case (Flags and $0C00) of
$0400: Code := pointer(longword(Code) + 1);
$0800: Code := pointer(longword(Code) + 2);
$0C00: Code := pointer(longword(Code) + OperandOveride);
else
begin
case Opcode of
$9a, $ea: Code := pointer(longword(Code) + OperandOveride + 2);
$c8: Code := pointer(longword(Code) + 3);
$a0..$a3:
begin
if AddressOveride then
begin
Code := pointer(longword(Code) + 2)
end
else
begin
Code := pointer(longword(Code) + 4);
end;
end;
end;
end;
end;
end;
Result := longword(Code) - Last;
except
Result := 0;
end;
end;
function SizeOfProc(Proc: pointer): longword;
var
Length: longword;
begin
Result := 0;
repeat
Length := SizeOfCode(Proc);
Inc(Result, Length);
if ((Length = 1) and (byte(Proc^) = $C3)) then Break;
Proc := pointer(longword(Proc) + Length);
until Length = 0;
end;
function InjectString(Process: LongWord; Text: pchar): pchar;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -