资源描述
unit HookAPIUnit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
ListBox1: TListBox;
Label1: TLabel;
Button3: TButton;
Button4: TButton;
Button5: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
function MyMessageBox(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT):Integer; stdcall;
procedure EnableDebugPriviledge();
/////// EnableDebugPriviledge();函数在实验成功后已显多余,当时纯粹是考虑了可能出现的权限不足的情况
implementation
var
oldAddressEntry:array[1..5]of Byte;
newAddressEntry:array[1..5]of Byte=($E9,$00,$00,$00,$00); ///////////修改前5字节JMP
RelativeAddress:DWord;
padressOfMessageBoxA:Pointer;
oldPageAttrib:cardinal;
pByte:^Byte;
NumberOfBytesBeenRead,NumberOfBytesWriten:DWord;
procedure ChangePageAttribToReadWrite(pBaseAddress:Pointer);
begin
if VirtualProtect(pBaseAddress,8,PAGE_READWRITE,oldPageAttrib)=false then
begin
showMessage('failed to ChangePageAttribToReadWrite');
end;
end;
function MyMessageBox(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT):Integer; stdcall;
begin
Form1.ListBox1.Items.Add('Hooked MessageBox Function!!');
if lpCaption='Notifation' then ////实验证明,如果Hook成功,MessageBox的所有参数都会传递给这个自定义的拦截函数。在这里可以判断比较传递来的参数,再决定如果进行下面的操作。
begin
Form1.ListBox1.Items.Add('param of the MessageBox Function was replaced!!');
end;
end;
procedure EnableDebugPriviledge();
var
hToken:Thandle;
returnLength:Cardinal;
Lid:int64;
NewTokenPriviledge,OldTokenPriviledge:_TOKEN_PRIVILEGES;
begin
if OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,hToken)=false then
begin
showMessage('failed to OpenProcessToken!');
end;
if LookupPrivilegeValue(nil,'SeDebugPrivilege',Lid)=false then
begin
showMessage('failed to LookupPrivilegeValue!');
end;
NewTokenPriviledge.PrivilegeCount:=1;
NewTokenPriviledge.Privileges[0].Luid:=Lid;
NewTokenPriviledge.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;
if AdjustTokenPrivileges(hToken,false,NewTokenPriviledge,sizeof(_TOKEN_PRIVILEGES),OldTokenPriviledge,returnLength)=false then
begin
showMessage('failed to AdjustTokenPrivileges!');
end;
end;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
MessageBox(form1.Handle,'Using MessageBox Function','Notifation',MB_OK);
end;
procedure TForm1.Button2Click(Sender: TObject);
var
dllHandle:THandle;
i:integer;
begin
EnableDebugPriviledge();
if OpenProcess(PROCESS_ALL_ACCESS ,true,getCurrentProcessID())=NULL then
begin
ListBox1.Items.Add('failed to OpenProcess!');
end;
///////经实验,进程内Hook,以上EnableDebugPriviledge与OpenProcess函数可以去掉。
如果出现因权限不够引起的错误,可调用OpenProcess 获得PROCESS_VM_OPERATION或PROCESS_VM_WRITE权限,或者调用VirtualProtect函数修改虚拟内存空间的读写属性。
dllHandle:=loadLibrary('user32.dll');
if dllHandle=0 then
begin
ListBox1.Items.Add('failed to loadLibrary!');
end
else
ListBox1.Items.Add('succeeded to loadLibrary!'+' '+'user32.dll Module handle value is '+inttostr(cardinal(dllHandle)));
padressOfMessageBoxA:=GetProcAddress(dllHandle,Pchar('MessageBoxA'));
if padressOfMessageBoxA=nil then
begin
ListBox1.Items.Add('failed to GetProcAddress!');
end
else
ListBox1.Items.Add('succeeded to GetProcAddress!'' '+'MessageBoxA adress is'+inttostr(cardinal(padressOfMessageBoxA)));
if ReadProcessMemory(getCurrentProcess(),padressOfMessageBoxA,@oldAddressEntry,5,NumberOfBytesBeenRead)=false then
begin
ListBox1.Items.Add('failed to ReadProcessMemory!');
end
else
ListBox1.Items.Add('succeeded to ReadProcessMemory!');
////以上显示错误与成功信息有利于排除调用API函数后可能出现的错误
RelativeAddress:=DWord(@MyMessageBox)-DWord(padressOfMessageBoxA)-5;
////上条语句为偏移地址的计算
pByte:=@RelativeAddress; ////请特别注意:JMP XXXXX 的地址是一个相对地址!!!!
for i := 2 to 5 do
begin
newAddressEntry[i]:=pByte^;
inc(pByte) ;
end;
if WriteProcessMemory(getCurrentProcess(),padressOfMessageBoxA,@newAddressEntry,5,NumberOfBytesWriten)=false then
begin
ListBox1.Items.Add('failed to WriteProcessMemory!'+' '+'Error Code'+' '+inttostr(getLastError()));
end
else
ListBox1.Items.Add('succeeded to WriteProcessMemory!');
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Label1.Width:=300;
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
WriteProcessMemory(getCurrentProcess(),padressOfMessageBoxA,@oldAddressEntry,5,NumberOfBytesWriten);
end;
end.
执行后的实际情况如上图所示。
本进程内的HOOk成功之后,进程外的hook也变得相对容易,所以进程外HookAPI不再赘述
经实验,如果要拦截CreateProcess函数,需要拦截CreateProcessW,而不是CreateProcessA
进程注入explorer进程出错的问题因为自定义拦截函数如MyCreateProcessW的参数不能与原函数严格匹配造成的,在delphi里要使参数尽量匹配才会少出错。
展开阅读全文