unit Unit1;
interface
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
{ Private declarations }
procedure ShowMsg(s: string);
public
{ Public declarations }
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 eax
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 on
asm 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
{asm
call 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.
======
Unit1里有很多垃圾代码,因为这个防hook的程序只是一个副产品。
有用代码写成dll注入其他进程就可以防hook了,已经试过没问题。
代码风格比较差,不过不知道怎么改的更好(如将FakeCode部分放到单独过程中)。
如果你改好了希望能发给我一份。
MLDE32Unit代码来自29A第七期,作者忘记了,不好意思。
本文地址:http://com.8s8s.com/it/it4347.htm