============form1.dfm==============
object
Form1: TForm1
Left = 192
Top = 107
Width = 396
Height = 261
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
OnDestroy = FormDestroy
PixelsPerInch = 96
TextHeight = 13
object
Button1: TButton
Left = 0 Top = 152
Width = 89
Height = 25
Caption = 'Load'
TabOrder = 0
OnClick = Button1Click
end object
Memo1: TMemo
Left = 0
Top = 0
Width = 385
Height = 145
ScrollBars = ssBoth
TabOrder = 1
end
object
Button2: TButton
Left = 0
Top = 184
Width = 89
Height = 25
Caption = 'Button2'
TabOrder = 2
OnClick = Button2Click
end
object
Button3: TButton
Left = 120
Top = 184
Width = 89
Height = 25
Caption = 'Button3'
TabOrder = 3
OnClick = Button3Click
end
end
unit Unit1;
interfaceuses
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
procedure ShowMsg(s: string);
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses MLDE32Unit;
const
DesPath = 'C:\Program Files\Borland\Delphi6\Projects\Adv APIHOOK\Test\vt.exe';
Func2Hook = 'FreeLibrary';
var //must be a globle variable
PtrReal: Pointer;
cbStolen: Cardinal;
NtDllBase, NtDllLength: integer;
p: pointer;
h:dword;
procedure TForm1.ShowMsg(s: string);
begin
Memo1.Lines.Add(s);
end;
procedure TForm1.Button1Click(Sender: TObject);
label FakeCode, RtnCode;
var
// si: STARTUPINFO;
// pi: PROCESS_INFORMATION;
OriginalBytes: Array [0..4] of Char;
HookJmp: PChar; Rtn: Cardinal;
Bytes: Array [0..4] of Char;
tmp: Cardinal;
peb, ldr, flink: pointer;
bs: DWORD;
begin
PtrReal := nil;
NtDllLength := 0;
NtDllBase := GetModuleHandle('ntdll.dll');
asm mov eax,fs:[$30] mov peb,eax end;
ldr := pointer(dword(pointer(dword(peb)+12)^));
flink := pointer(dword(pointer(dword(ldr)+12)^));
p := flink;
repeat bs := DWORD(pointer(dword(p)+$18)^);
if bs = NtDllBase then
begin
NtDllLength := DWORD(pointer(dword(p)+$20)^);
break;
end;
p := pointer(dword(p^));
until dword(flink) = dword(p^);
if NtDllLength = 0 then ShowMsg('Can''t get ntdll.dll image size!');
{ ShowMsg('Creating suspended process ...');
ZeroMemory(@si, sizeof(STARTUPINFO));
si.cb := sizeof(STARTUPINFO);
CreateProcess(DesPath, nil, nil, nil, False, CREATE_SUSPENDED, nil, nil, si, pi); }
ShowMsg('Preparing HOOK ' + Func2Hook + ' ...');
PtrReal := GetProcAddress(GetModuleHandle('Kernel32.dll'), Func2Hook); if Assigned(PtrReal) then ShowMsg('Real ' + Func2Hook + ' Addr: ' + inttohex(DWORD(PtrReal), 8)) else begin ShowMsg(' Addr: ' + Func2Hook + ' is unreadable! Exit!');
// ResumeThread(pi.hThread);
Exit;
end;
ReadProcessMemory(GetCurrentProcess, PtrReal, @Bytes, 5, Rtn);
// ReadProcessMemory(pi.hProcess, PtrReal, @Bytes, 5, Rtn);
if Bytes[0] <> Chr($E9) then
begin
CopyMemory(@OriginalBytes, @Bytes, 5); ShowMsg(Func2Hook + ' havn''t been hooked!'); end else begin ShowMsg(Func2Hook + ' have been hooked! Exit!');// ResumeThread(pi.hThread); exit; end; cbStolen :=0; while cbStolen < 5 do cbStolen := cbStolen + LDE32(Pointer(DWORD(PtrReal) + cbStolen)); ShowMsg('Let''s steal the first ' + inttostr(cbStolen) + ' bytes :)');
ShowMsg('But make it writable first ...');
if VirtualProtect(PtrReal ,cbStolen , PAGE_EXECUTE_READWRITE, @tmp) then
ShowMsg('Make ' + inttohex(DWORD(PtrReal), 8) + ' writable succeed!')
else
begin
ShowMsg('Hoops! Make ' + inttohex(DWORD(PtrReal), 8) + ' writable failed! Exit!!');
// ResumeThread(pi.hThread);
exit;
end;
ShowMsg('Assemble Jmp codes & hook ' + Func2Hook + '...');
GetMem(HookJmp, 5);
try HookJmp[0] := Chr($E9);
asm
push ea
lea eax, FakeCode
mov tmp, eax
pop eax
end;
tmp := tmp - DWORD(PtrReal) - 5;
CopyMemory(@HookJmp[1], @tmp, 4);
asm
push eax
lea eax, RtnCode
mov tmp, eax
pop eax
end;
VirtualProtect(Pointer(tmp) ,cbStolen , PAGE_EXECUTE_READWRITE, @Rtn);
CopyMemory(Pointer(tmp), PtrReal, cbStolen);
WriteProcessMemory(GetCurrentProcess, PtrReal, HookJmp, 5, Rtn);
// WriteProcessMemory(pi.hProcess, PtrReal, HookJmp, 5, Rtn);
ShowMsg('Hook ' + Func2Hook + ' succeed! Resume thread!');
finally
Freemem(HookJmp);
// ResumeThread(pi.hThread);
end;
exit;
FakeCode:
//No strings from here onasm int 3
end;
asm
push eax
lea eax, [esp+4]
mov p, eax
pop eax
end;
if dword(p^) - ntdllbase < NtDllLength then
asm
pop p
pop eax
pop eax
pop eax
mov eax, 0
jmp p
// push p
// ret
end;
//messagebox(0,pchar(p),'',0);
RtnCode:
asm
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
mov eax, PtrReal
add eax, cbStolen
jmp eax
end;
end;
var
Ptr, ppp: Pointer;
procedure TForm1.Button2Click(Sender: TObject);
begin
{asmcall ppp;end;exit; }
Button3Click(nil);
Ptr := VirtualAlloc(nil, 1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if not Assigned(Ptr) then
Memo1.Lines.Add('Fatal Error: VirtualAlloc failed!')
else
Memo1.Lines.Add('VirtualAlloc succeed! Ptr = ' + inttohex(DWORD(Ptr), 8));
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Button3Click(nil);
UnmapViewOfFile(ppp);
CloseHandle(h);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
if Assigned(Ptr) then VirtualFree(Ptr, 0, MEM_RELEASE);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
h := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE or SEC_COMMIT, 0, 1, 'pe');
ppp := MapViewOfFile(h,FILE_MAP_ALL_ACCESS,0,0,0);
caption := inttohex(dword(ppp),8);
char(ppp^) := Chr($C3);
end;
end.
unit MLDE32Unit;
//Micro Length Disassembler Engineinterface
function LDE32(Opcode: pointer): integer;
implementation
function LDE32(Opcode: pointer): integer;
const
//**************** //* Opcode types * //****************
O_UNIQUE = 0;
O_PREFIX = 1;
O_IMM8 = 2;
O_IMM16 = 3;
O_IMM24 = 4;
O_IMM32 = 5;
O_IMM48 = 6;
O_MODRM = 7;
O_MODRM8 = 8;
O_MODRM32 = 9;
O_EXTENDED = 10;
O_WEIRD = 11;
O_ERROR = 12;
function MLDE32(Opcode:Pointer): integer;
asm
pushad
cld
xor edx, edx
mov esi, [esp+(8*4)+4]
mov ebp, esp
// 256 bytes, index-compressed opcode type table
push 01097F71Ch
push 0F71C6780h
push 017389718h
push 0101CB718h
push 017302C17h
push 018173017h
push 0F715F547h
push 04C103748h
push 0272CE7F7h
push 0F7AC6087h
push 01C121C52h
push 07C10871Ch
push 0201C701Ch
push 04767602Bh
push 020211011h
push 040121625h
push 082872022h
push 047201220h
push 013101419h
push 018271013h
push 028858260h
push 015124045h
push 05016A0C7h
push 028191812h
push 0F2401812h
push 019154127h
push 050F0F011h
mov ecx, 015124710h
push ecx
push 011151247h
push 010111512h
push 047101115h
mov eax, 012472015h
push eax
push eax
push 012471A10h
add cl, 10h
push ecx
sub cl, 20h
push ecx
xor ecx, ecx
dec ecx
// code starts
@@ps:
inc ecx
mov edi, esp
@@go:
lodsb
mov bh, al
@@ft:
mov ah, [edi]
inc edi
shr ah, 4
sub al, ah
jnc @@ft
mov al, [edi-1]
and al, 0Fh
cmp al, O_ERROR
jnz @@i7
pop edx
not edx
@@i7:
inc edx
cmp al, O_UNIQUE
jz @@t_exit
cmp al, O_PREFIX
jz @@ps
add edi, 51h
//(@@_ettbl - @@_ttbl)
cmp al, O_EXTENDED
jz @@go
mov edi, [ebp+(8*4)+4]
@@i6:
inc edx
cmp al, O_IMM8
jz @@t_exit
cmp al, O_MODRM
jz @@t_modrm
cmp al, O_WEIRD
jz @@t_weird
@@i5:
inc edx
cmp al, O_IMM16
jz @@t_exit
cmp al, O_MODRM8
jz @@t_modrm
@@i4:
inc edx
cmp al, O_IMM24
jz @@t_exit
@@i3:
inc edx
@@i2:
inc edx
pushad
mov al, 66h
repnz scasb
popad
jnz @@c32
@@d2:
dec edx
dec edx
@@c32:
cmp al, O_MODRM32
jz @@t_modrm
sub al, O_IMM32
jz @@t_imm32
@@i1:
inc edx
@@t_exit:
mov esp, ebp
mov [esp+(7*4)], edx
popad
ret
//*********************************
//* PROCESS THE MOD/RM BYTE *
//* * //* 7 6 5 3 2 0 *
//* | MOD | Reg/Opcode | R/M | *
//*********************************
@@t_modrm:
lodsb
mov ah, al
shr al, 7
jb @@prmk
jz @@prm
add dl, 4
pushad
mov al, 67h
repnz scasb
popad
jnz @@prm
@@d3:
sub dl, 3
dec al
@@prmk:
jnz @@t_exit
inc edx
inc eax
@@prm:
and ah, 00000111b
pushad
mov al, 67h
repnz scasb
popad
jz @@prm67chk
cmp ah, 04h
jz @@prmsib
cmp ah, 05h
jnz @@t_exit
@@prm5chk:
dec al
jz @@t_exit
@@i42:
add dl, 4
jmp @@t_exit
@@prm67chk:
cmp ax, 0600h
jnz @@t_exit
inc edx
jmp @@i1
@@prmsib:
cmp al, 00h
jnz @@i1
lodsb
and al, 00000111b
sub al, 05h
jnz @@i1
inc edx
jmp @@i42
//****************************
//* PROCESS WEIRD OPCODES *
//* Fucking test (F6h/F7h) *
//****************************
@@t_weird:
test byte ptr [esi], 00111000b
jnz @@t_modrm mov
al, O_MODRM8
shr bh, 1
adc al, 0
jmp @@i5
//*********************************
//* PROCESS SOME OTHER SHIT *
//* Fucking mov (A0h/A1h/A2h/A3h) *
//*********************************
@@t_imm32:
sub bh, 0A0h
cmp bh, 04h
jae @@d2
pushad
mov al, 67h
repnz scasb
popad
jnz @@chk66t
@@d4:
dec edx
dec edx
@@chk66t:
pushad
mov al, 66h
repnz scasb
popad
jz @@i1
jnz @@d2
end;
begin
asm
push Opcode
call MLDE32
add esp, 4
end;
end;
end.
评论