-
-
[转帖]再贴关于madCodeHook的文章3篇
-
发表于: 2006-12-22 08:43 10351
-
希望大家能慷慨解囊,把自己手上的关于madCodeHook编程的资料贴出来,谢谢!
一。用madCodeHook写的Hooking KiFastSystemCall
program KiFastSystemCall;
uses
Windows, madCodeHook, SysUtils;
var
realKiFastSystemCall: procedure;
dwIndexPVM: DWORD;
function hookZwProtectVirtualMemory(hProcess: THandle; lpAddress: Pointer; dwSize, flNewProtect: DWORD; lpflOldProtect: Pointer): DWORD; stdcall;
var
Stack1, Stack2: DWORD;
begin
Result := 0;
MessageBoxA(0, PChar(IntToHex(DWORD(lpAddress), 8)), 'ZwProtectVirtualMemory', 0);
asm
pop eax
mov [Stack1], eax
pop eax
mov [Stack2], eax
mov eax, [dwIndexPVM]
call realKiFastSystemCall
mov [Result], eax
push [Stack2]
push [Stack1]
end;
end;
procedure hookKiFastSystemCall; assembler;
label
CallPVM;
begin
asm
cmp eax, [dwIndexPVM]
je @CallPVM
jmp realKiFastSystemCall
@CallPVM:
pop eax
jmp hookZwProtectVirtualMemory
end;
end;
begin
MessageBoxA(0, 'You need to call me once before you install the hook, otherwise I don''t initialize properly.', 'MessageBoxA Bug Fix', 0);
dwIndexPVM := PDWORD(DWORD(GetProcAddress(GetModuleHandle('ntdll.dll'), 'ZwProtectVirtualMemory'))+1)^;
HookAPI('ntdll.dll', 'KiFastSystemCall', @hookKiFastSystemCall, @realKiFastSystemCall);
end.
二。用madCodeHook重新设定指定Label的内容
{
程序名 : 重新设定指定Label的内容
说明 : 无
作者 : JJony
QQ : 254706028
博客 : http://blog.csdn.net/jzj_jony
空间 : http://jonychen,ys168.com
测试环境 : WinXPSP2+Delphi7+MadCodeHook控件
}
程序说明:
程序通过钩子重新设定指定Label的显示内容。
使用说明:
运行主程序,输入你要改变的Label所属进程PID,点“注入dll”按钮,
然后输入你要改的Label的原内容,再输入你想改的内容,点“设置”按钮,
最小化目标程序再还原,你就可以看到效果了。
声明:
你可以任意使用或转载程序,但请注明作者,谢谢。
今天在大富翁看到一个帖子,说是不知道怎么重新设定其他程序中Label的内容,我起初拿来一看
感觉就是太容易了嘛!结果我错了,因为Label没有句柄,没有句柄当然就无法设置了,经过我的研究
发现,Label并不是用CreateWindow建立的窗体,而是直接用TextOut或DrawText直接在窗体上画出的,
这也是为什么我在使用说明中说“最小化目标程序再还原”的原因了,因为这两个API是在窗体重画时
才调用的,你也可以用别的窗口把他挡住然后在移开,也会看到同样效果的。知道了问题关键就好解决
了,既然是用TextOut或DrawText那我们就挂钩这两个API就好了,马上动手。
//Hook.dll的源代码
library Hook;
uses
windows,
SysUtils,
Classes,
madcodehook;//很强大的组件HookAPI用,可以从http://madshi.net下载
{$R Ver.RES}
//内存共享结构
type
PShareMem = ^TShareMem;
TShareMem = record
OldCaption: array[0..255] of char;//原始Label的Caption
NewCaption: array[0..255] of char;//想要显示的Caption
end;
var
PShare: PShareMem;
MapHandle: THandle;
var //定义相关API,分ANSI和UNICODE版本
TextOutANext:function(DC: HDC; X, Y: Integer; Str: PAnsiChar; Count: Integer): BOOL; stdcall;
TextOutWNext:function(DC: HDC; X, Y: Integer; Str: PWideChar; Count: Integer): BOOL; stdcall;
DrawTextANext:function(hDC: HDC; lpString: PAnsiChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
DrawTextWNext:function(hDC: HDC; lpString: PWideChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
function TextOutACallBack(DC: HDC; X, Y: Integer; Str: PAnsiChar; Count: Integer): BOOL; stdcall;
begin
if strpas(str)=strpas(PShare^.OldCaption) then
begin
result:=TextOutANext(DC, X, Y, PShare^.NewCaption, sizeof(PShare^.NewCaption));
end
else
result:=TextOutANext(DC, X, Y, str, Count);
end;
function TextOutWCallBack(DC: HDC; X, Y: Integer; Str: PWideChar; Count: Integer): BOOL; stdcall;
var
np:widestring;
begin
np:=strpas(PShare^.NewCaption);
if widechartostring(str)=strpas(PShare^.OldCaption) then
result:=TextOutWNext(DC, X, Y,Pwidechar(np), length(np))
else
result:=TextOutWNext(DC, X, Y,str, Count);
end;
function DrawTextACallBack(hDC: HDC; lpString: PAnsiChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer;
stdcall;
begin
if strpas(lpString)=strpas(PShare^.OldCaption) then
result:=DrawTextANext(hDC, PShare^.NewCaption, sizeof(PShare^.NewCaption), lpRect, uFormat)
else
result:=DrawTextANext(hDC, lpString, ncount, lpRect, uFormat)
end;
function DrawTextWCallBack(hDC: HDC; lpString: PWideChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer;
stdcall;
var
np:widestring;
begin
np:=strpas(PShare^.NewCaption);
if widechartostring( lpString)=strpas(PShare^.OldCaption) then
result:=DrawTextWNext(hDC, pwidechar(np), length(np), lpRect, uFormat)
else
result:=DrawTextWNext(hDC,lpString, nCount, lpRect, uFormat)
end;
begin
MapHandle := OpenFileMapping(FILE_MAP_WRITE, //打开内存映射为了与主程序共享数据
False,
pchar('MyShareMem'));
PShare := PShareMem(MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0));
if PShare = nil then
begin
CloseHandle(MapHandle);
exit;
end;
FillChar(PShare^, SizeOf(TShareMem), 0);
//以下为Hook相关API,分ASNI和UNICODE版本
HookAPI('Gdi32.dll','TextOutA',@TextOutACallBack,@TextOutANext);
HookAPI('Gdi32.dll','TextOutW',@TextOutWCallBack,@TextOutWNext);
HookAPI('User32.dll','DrawTextA',@DrawTextACallBack,@DrawTextANext);
HookAPI('User32.dll','DrawTextW',@DrawTextWCallBack,@DrawTextWNext);
end.
以下是主程序testu.pas的代码:
{
testu.frm包含控件有3个button,4个Label,3个Edit.
}
unit testu;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,madcodehook;
type
PShareMem = ^TShareMem;
TShareMem = record
OldCaption: array[0..255] of char;
NewCaption: array[0..255] of char;
end;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Button2: TButton;
Button3: TButton;
Edit1: TEdit;
Button4: TButton;
Edit2: TEdit;
Edit3: TEdit;
Label3: TLabel;
Label4: TLabel;
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure Button4Click(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
HookFileA:pchar;
HookFileW:pwidechar;
PShare: PShareMem;
isInject:boolean;
h:thandle;
implementation
{$R *.dfm}
var
HMapping: THandle;
HMapMutex: THandle;
const
MAPFILESIZE = 1000;
REQUEST_TIMEOUT = 1000;
procedure OpenMap;
begin
HMapping := CreateFileMapping(
$FFFFFFFF,
nil,
PAGE_READWRITE,
0,
SizeOf(TShareMem),
pchar('MyShareMem')
);
if (hMapping = 0) then
begin
ShowMessage('不能创建内存映射文件');
Application.Terminate;
exit;
end;
{将文件数据映射到进程的地址空间}
{当创建了一个文件映射对象之后,仍然必须让系统为文件的数据保留
一个地址空间区域,并将文件的数据作为映射到该区域的物理存储器进行提交。
}
PShare := PShareMem(MapViewOfFile(HMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0));
if PShare = nil then
begin
CloseHandle(HMapping);
ShowMessage('Can''t View Memory Map');
Application.Terminate;
exit;
end;
end;
procedure CloseMap;
begin
if PShare <> nil then
UnMapViewOfFile(PShare);
if HMapping <> 0 then
CloseHandle(HMapping);
end;
function LockMap: Boolean;
begin
Result := true;
HMapMutex := CreateMutex(nil, false,
pchar('MY MUTEX NAME GOES HERE'));
if HMapMutex = 0 then
begin
ShowMessage('不能创建互斥对象');
Result := false;
end else begin
if WaitForSingleObject(HMapMutex, REQUEST_TIMEOUT)
= WAIT_FAILED then
begin
ShowMessage('不能对互斥对象加锁!');
Result := false;
end
end
end;
procedure UnlockMap;
begin
ReleaseMutex(HMapMutex);
CloseHandle(HMapMutex);
end;
function EnableDebugPrivilege(PName:pchar):Boolean;
var
TokenHandle:THandle;
DebugNameValue:TLargeInteger;
Privileges:TOKEN_PRIVILEGES;
RetLen:Cardinal;
begin
Result:=False;
if not OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,TokenHandle) then Exit;
if not LookupPrivilegeValue(nil,PName,DebugNameValue) then
begin
CloseHandle(TokenHandle);
Exit;
end;
Privileges.PrivilegeCount:=1;
Privileges.Privileges[0].Luid:=DebugNameValue;
Privileges.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;
Result:=AdjustTokenPrivileges(TokenHandle,False,Privileges,SizeOf(Privileges),nil,RetLen);
CloseHandle(TokenHandle);
end;
procedure TForm1.Button2Click(Sender: TObject);
var
b1:boolean;
pid:integer;
begin
EnableDebugPrivilege('SeDebugPrivilege');
PID:=strtoint(edit3.Text);
h:=openprocess(PROCESS_ALL_ACCESS,false,PID);
if GetVersion and $80000000 <> 0 then begin
b1:= InjectLibraryA(h ,HookFileA)
end else
b1 := InjectLibraryW(h,HookFileW);
if not b1 then
MessageBox(0, '只有 administrator权限才可以注入dlls',
'提示...', MB_ICONINFORMATION);
if b1 then
isInject:=true
else
isInject:=false;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
HookFileA:='hook.dll';
HookFileW:='hook.dll';
OpenMap;
LockMap;
isInject:=false;
end;
procedure TForm1.Button3Click(Sender: TObject);
var
b1:boolean;
begin
if GetVersion and $80000000 <> 0 then begin
b1 := UninjectLibraryA(h, HookFileA)
end else
b1 := UninjectLibraryW(h, HookFileW);
if (not b1) and (GetLastError = ERROR_ACCESS_DENIED) then
MessageBox(0, '只有administrator权限才能卸载Dll',
'提示...', MB_ICONINFORMATION);
if b1 then
isInject:=false
else
isInject:=true;
end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
b1:boolean;
begin
if GetVersion and $80000000 <> 0 then begin
b1 := UninjectLibraryA(CURRENT_SESSION or CURRENT_PROCESS, HookFileA)
end else
b1 := UninjectLibraryW(CURRENT_SESSION or CURRENT_PROCESS, HookFileW);
if (not b1) and (GetLastError = ERROR_ACCESS_DENIED) then
MessageBox(0, '只有administrator权限才能卸载Dll',
'提示...', MB_ICONINFORMATION);
UnlockMap;
CloseMap;
end;
procedure TForm1.Button4Click(Sender: TObject);
var
str1: pchar;
str2: pchar;
begin
if not isInject then
begin
MessageBoxA(handle,'请先注入Dll到指定进程','提示',mb_ok);
exit;
end;
str1 := pchar(edit1.Text);
str2 := pchar(edit2.Text);
CopyMemory(@(pShare^.OldCaption), Str1, Length(str1));
CopyMemory(@(pShare^.NewCaption), Str2, Length(str2));
end;
procedure TForm1.FormShow(Sender: TObject);
begin
Label4.Caption:='作者: JJony '#13#10'QQ: 254706028'#13#10+
'Blog: http://blog.csdn.net/jzj_jony'#13#10+
'空间: http://jonychen.ys168.com';
end;
end.
三。用madCodeHook写的HookAPI源代码
interface
uses
SysUtils,Windows,Winsock,Graphics,tlHelp32,madCodeHook;
type
//要HOOK的API函数定义
TSockSendProc = function (s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
TSockRecvProc = function (s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
TMsgBoxProc = function(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;
//--------------------函数声明---------------------------
function Sun_Send(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
function Sun_Recv(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
function Sun_Box(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;
procedure Hook;stdcall;export;
procedure UnHook;stdcall;export;
var
//用来保存原来函数的地址
sunSend: TSockSendProc;
sunRecv: TSockRecvProc;
sunMsg: TMsgBoxProc;
i: Integer;
implementation
function Sun_Box(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;
var
strTemp: string;
begin
strTemp := '珊瑚虫:sunsjw';
Result := sunMsg(hWnd,lpText,pchar(strTemp),uType);
end;
{---------------------------------------}
{函数功能:Recv函数的HOOK
{函数参数:同Recv
{函数返回值:integer
{---------------------------------------}
function Sun_Recv(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
begin
//在这里要对接收的数据Buf进行处理
//暂时不处理了,随便响一声吧。
MessageBeep(0);
//调用直正的Send函数
Result := sunRecv(s,Buf,len, flags);
end;
{---------------------------------------}
{函数功能:Send函数的HOOK
{函数参数:同Send
{函数返回值:integer
{---------------------------------------}
function Sun_Send(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
DeskDC: HDC;
Can: TCanvas;
str: string;
found: boolean;
Hand,CurrHand: THandle;
lppe: TProcessEntry32;
begin
DeskDC := GetDC(0);
Can := TCanvas.Create;
Can.Handle := DeskDC;
CurrHand := GetCurrentProcessID();
Hand := CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
lppe.dwSize := sizeof(lppe);
found := Process32First(Hand,lppe);
while found do
begin
if lppe.th32ProcessID=CurrHand then
begin
str := lppe.szExeFile;
found := false;
end
else
found := Process32Next(Hand,lppe);
end;
try
Inc(i);
Can.TextOut(0,0,str+':正在发送数据...');
finally
Can.Free;
ReleaseDC(0,DeskDC);
end;
Result := sunSend(s,Buf,len, flags);
end;
{------------------------------------}
{过程功能:HookAPI
{过程参数:无
{------------------------------------}
procedure Hook;
begin
HookAPI('ws2_32.dll','send',@Sun_Send,@sunSend);
HookAPI('ws2_32.dll','recv',@Sun_Recv,@sunRecv);
HookAPI('user32.dll','MessageBoxA',@sun_Box,@sunMsg);
end;
{------------------------------------}
{过程功能:取消HOOKAPI
{过程参数:无
{------------------------------------}
procedure UnHook;
begin
UnHookAPI(@sunSend);
UnHookAPI(@sunRecv);
UnHookAPI(@sunMsg);
end;
end.
////////////////////////////////////////////
//调用
unit callMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,madCodeHook;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
//把我们的函数注放到其它进程中
InjectLibrary(ALL_SESSIONS or SYSTEM_PROCESSES,'hookMsg.dll');
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
UninjectLibrary(ALL_SESSIONS or SYSTEM_PROCESSES,'hookMsg.dll');
end;
end.
一。用madCodeHook写的Hooking KiFastSystemCall
program KiFastSystemCall;
uses
Windows, madCodeHook, SysUtils;
var
realKiFastSystemCall: procedure;
dwIndexPVM: DWORD;
function hookZwProtectVirtualMemory(hProcess: THandle; lpAddress: Pointer; dwSize, flNewProtect: DWORD; lpflOldProtect: Pointer): DWORD; stdcall;
var
Stack1, Stack2: DWORD;
begin
Result := 0;
MessageBoxA(0, PChar(IntToHex(DWORD(lpAddress), 8)), 'ZwProtectVirtualMemory', 0);
asm
pop eax
mov [Stack1], eax
pop eax
mov [Stack2], eax
mov eax, [dwIndexPVM]
call realKiFastSystemCall
mov [Result], eax
push [Stack2]
push [Stack1]
end;
end;
procedure hookKiFastSystemCall; assembler;
label
CallPVM;
begin
asm
cmp eax, [dwIndexPVM]
je @CallPVM
jmp realKiFastSystemCall
@CallPVM:
pop eax
jmp hookZwProtectVirtualMemory
end;
end;
begin
MessageBoxA(0, 'You need to call me once before you install the hook, otherwise I don''t initialize properly.', 'MessageBoxA Bug Fix', 0);
dwIndexPVM := PDWORD(DWORD(GetProcAddress(GetModuleHandle('ntdll.dll'), 'ZwProtectVirtualMemory'))+1)^;
HookAPI('ntdll.dll', 'KiFastSystemCall', @hookKiFastSystemCall, @realKiFastSystemCall);
end.
二。用madCodeHook重新设定指定Label的内容
{
程序名 : 重新设定指定Label的内容
说明 : 无
作者 : JJony
QQ : 254706028
博客 : http://blog.csdn.net/jzj_jony
空间 : http://jonychen,ys168.com
测试环境 : WinXPSP2+Delphi7+MadCodeHook控件
}
程序说明:
程序通过钩子重新设定指定Label的显示内容。
使用说明:
运行主程序,输入你要改变的Label所属进程PID,点“注入dll”按钮,
然后输入你要改的Label的原内容,再输入你想改的内容,点“设置”按钮,
最小化目标程序再还原,你就可以看到效果了。
声明:
你可以任意使用或转载程序,但请注明作者,谢谢。
今天在大富翁看到一个帖子,说是不知道怎么重新设定其他程序中Label的内容,我起初拿来一看
感觉就是太容易了嘛!结果我错了,因为Label没有句柄,没有句柄当然就无法设置了,经过我的研究
发现,Label并不是用CreateWindow建立的窗体,而是直接用TextOut或DrawText直接在窗体上画出的,
这也是为什么我在使用说明中说“最小化目标程序再还原”的原因了,因为这两个API是在窗体重画时
才调用的,你也可以用别的窗口把他挡住然后在移开,也会看到同样效果的。知道了问题关键就好解决
了,既然是用TextOut或DrawText那我们就挂钩这两个API就好了,马上动手。
//Hook.dll的源代码
library Hook;
uses
windows,
SysUtils,
Classes,
madcodehook;//很强大的组件HookAPI用,可以从http://madshi.net下载
{$R Ver.RES}
//内存共享结构
type
PShareMem = ^TShareMem;
TShareMem = record
OldCaption: array[0..255] of char;//原始Label的Caption
NewCaption: array[0..255] of char;//想要显示的Caption
end;
var
PShare: PShareMem;
MapHandle: THandle;
var //定义相关API,分ANSI和UNICODE版本
TextOutANext:function(DC: HDC; X, Y: Integer; Str: PAnsiChar; Count: Integer): BOOL; stdcall;
TextOutWNext:function(DC: HDC; X, Y: Integer; Str: PWideChar; Count: Integer): BOOL; stdcall;
DrawTextANext:function(hDC: HDC; lpString: PAnsiChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
DrawTextWNext:function(hDC: HDC; lpString: PWideChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
function TextOutACallBack(DC: HDC; X, Y: Integer; Str: PAnsiChar; Count: Integer): BOOL; stdcall;
begin
if strpas(str)=strpas(PShare^.OldCaption) then
begin
result:=TextOutANext(DC, X, Y, PShare^.NewCaption, sizeof(PShare^.NewCaption));
end
else
result:=TextOutANext(DC, X, Y, str, Count);
end;
function TextOutWCallBack(DC: HDC; X, Y: Integer; Str: PWideChar; Count: Integer): BOOL; stdcall;
var
np:widestring;
begin
np:=strpas(PShare^.NewCaption);
if widechartostring(str)=strpas(PShare^.OldCaption) then
result:=TextOutWNext(DC, X, Y,Pwidechar(np), length(np))
else
result:=TextOutWNext(DC, X, Y,str, Count);
end;
function DrawTextACallBack(hDC: HDC; lpString: PAnsiChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer;
stdcall;
begin
if strpas(lpString)=strpas(PShare^.OldCaption) then
result:=DrawTextANext(hDC, PShare^.NewCaption, sizeof(PShare^.NewCaption), lpRect, uFormat)
else
result:=DrawTextANext(hDC, lpString, ncount, lpRect, uFormat)
end;
function DrawTextWCallBack(hDC: HDC; lpString: PWideChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer;
stdcall;
var
np:widestring;
begin
np:=strpas(PShare^.NewCaption);
if widechartostring( lpString)=strpas(PShare^.OldCaption) then
result:=DrawTextWNext(hDC, pwidechar(np), length(np), lpRect, uFormat)
else
result:=DrawTextWNext(hDC,lpString, nCount, lpRect, uFormat)
end;
begin
MapHandle := OpenFileMapping(FILE_MAP_WRITE, //打开内存映射为了与主程序共享数据
False,
pchar('MyShareMem'));
PShare := PShareMem(MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0));
if PShare = nil then
begin
CloseHandle(MapHandle);
exit;
end;
FillChar(PShare^, SizeOf(TShareMem), 0);
//以下为Hook相关API,分ASNI和UNICODE版本
HookAPI('Gdi32.dll','TextOutA',@TextOutACallBack,@TextOutANext);
HookAPI('Gdi32.dll','TextOutW',@TextOutWCallBack,@TextOutWNext);
HookAPI('User32.dll','DrawTextA',@DrawTextACallBack,@DrawTextANext);
HookAPI('User32.dll','DrawTextW',@DrawTextWCallBack,@DrawTextWNext);
end.
以下是主程序testu.pas的代码:
{
testu.frm包含控件有3个button,4个Label,3个Edit.
}
unit testu;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,madcodehook;
type
PShareMem = ^TShareMem;
TShareMem = record
OldCaption: array[0..255] of char;
NewCaption: array[0..255] of char;
end;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Button2: TButton;
Button3: TButton;
Edit1: TEdit;
Button4: TButton;
Edit2: TEdit;
Edit3: TEdit;
Label3: TLabel;
Label4: TLabel;
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure Button4Click(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
HookFileA:pchar;
HookFileW:pwidechar;
PShare: PShareMem;
isInject:boolean;
h:thandle;
implementation
{$R *.dfm}
var
HMapping: THandle;
HMapMutex: THandle;
const
MAPFILESIZE = 1000;
REQUEST_TIMEOUT = 1000;
procedure OpenMap;
begin
HMapping := CreateFileMapping(
$FFFFFFFF,
nil,
PAGE_READWRITE,
0,
SizeOf(TShareMem),
pchar('MyShareMem')
);
if (hMapping = 0) then
begin
ShowMessage('不能创建内存映射文件');
Application.Terminate;
exit;
end;
{将文件数据映射到进程的地址空间}
{当创建了一个文件映射对象之后,仍然必须让系统为文件的数据保留
一个地址空间区域,并将文件的数据作为映射到该区域的物理存储器进行提交。
}
PShare := PShareMem(MapViewOfFile(HMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0));
if PShare = nil then
begin
CloseHandle(HMapping);
ShowMessage('Can''t View Memory Map');
Application.Terminate;
exit;
end;
end;
procedure CloseMap;
begin
if PShare <> nil then
UnMapViewOfFile(PShare);
if HMapping <> 0 then
CloseHandle(HMapping);
end;
function LockMap: Boolean;
begin
Result := true;
HMapMutex := CreateMutex(nil, false,
pchar('MY MUTEX NAME GOES HERE'));
if HMapMutex = 0 then
begin
ShowMessage('不能创建互斥对象');
Result := false;
end else begin
if WaitForSingleObject(HMapMutex, REQUEST_TIMEOUT)
= WAIT_FAILED then
begin
ShowMessage('不能对互斥对象加锁!');
Result := false;
end
end
end;
procedure UnlockMap;
begin
ReleaseMutex(HMapMutex);
CloseHandle(HMapMutex);
end;
function EnableDebugPrivilege(PName:pchar):Boolean;
var
TokenHandle:THandle;
DebugNameValue:TLargeInteger;
Privileges:TOKEN_PRIVILEGES;
RetLen:Cardinal;
begin
Result:=False;
if not OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,TokenHandle) then Exit;
if not LookupPrivilegeValue(nil,PName,DebugNameValue) then
begin
CloseHandle(TokenHandle);
Exit;
end;
Privileges.PrivilegeCount:=1;
Privileges.Privileges[0].Luid:=DebugNameValue;
Privileges.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;
Result:=AdjustTokenPrivileges(TokenHandle,False,Privileges,SizeOf(Privileges),nil,RetLen);
CloseHandle(TokenHandle);
end;
procedure TForm1.Button2Click(Sender: TObject);
var
b1:boolean;
pid:integer;
begin
EnableDebugPrivilege('SeDebugPrivilege');
PID:=strtoint(edit3.Text);
h:=openprocess(PROCESS_ALL_ACCESS,false,PID);
if GetVersion and $80000000 <> 0 then begin
b1:= InjectLibraryA(h ,HookFileA)
end else
b1 := InjectLibraryW(h,HookFileW);
if not b1 then
MessageBox(0, '只有 administrator权限才可以注入dlls',
'提示...', MB_ICONINFORMATION);
if b1 then
isInject:=true
else
isInject:=false;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
HookFileA:='hook.dll';
HookFileW:='hook.dll';
OpenMap;
LockMap;
isInject:=false;
end;
procedure TForm1.Button3Click(Sender: TObject);
var
b1:boolean;
begin
if GetVersion and $80000000 <> 0 then begin
b1 := UninjectLibraryA(h, HookFileA)
end else
b1 := UninjectLibraryW(h, HookFileW);
if (not b1) and (GetLastError = ERROR_ACCESS_DENIED) then
MessageBox(0, '只有administrator权限才能卸载Dll',
'提示...', MB_ICONINFORMATION);
if b1 then
isInject:=false
else
isInject:=true;
end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
b1:boolean;
begin
if GetVersion and $80000000 <> 0 then begin
b1 := UninjectLibraryA(CURRENT_SESSION or CURRENT_PROCESS, HookFileA)
end else
b1 := UninjectLibraryW(CURRENT_SESSION or CURRENT_PROCESS, HookFileW);
if (not b1) and (GetLastError = ERROR_ACCESS_DENIED) then
MessageBox(0, '只有administrator权限才能卸载Dll',
'提示...', MB_ICONINFORMATION);
UnlockMap;
CloseMap;
end;
procedure TForm1.Button4Click(Sender: TObject);
var
str1: pchar;
str2: pchar;
begin
if not isInject then
begin
MessageBoxA(handle,'请先注入Dll到指定进程','提示',mb_ok);
exit;
end;
str1 := pchar(edit1.Text);
str2 := pchar(edit2.Text);
CopyMemory(@(pShare^.OldCaption), Str1, Length(str1));
CopyMemory(@(pShare^.NewCaption), Str2, Length(str2));
end;
procedure TForm1.FormShow(Sender: TObject);
begin
Label4.Caption:='作者: JJony '#13#10'QQ: 254706028'#13#10+
'Blog: http://blog.csdn.net/jzj_jony'#13#10+
'空间: http://jonychen.ys168.com';
end;
end.
三。用madCodeHook写的HookAPI源代码
interface
uses
SysUtils,Windows,Winsock,Graphics,tlHelp32,madCodeHook;
type
//要HOOK的API函数定义
TSockSendProc = function (s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
TSockRecvProc = function (s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
TMsgBoxProc = function(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;
//--------------------函数声明---------------------------
function Sun_Send(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
function Sun_Recv(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
function Sun_Box(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;
procedure Hook;stdcall;export;
procedure UnHook;stdcall;export;
var
//用来保存原来函数的地址
sunSend: TSockSendProc;
sunRecv: TSockRecvProc;
sunMsg: TMsgBoxProc;
i: Integer;
implementation
function Sun_Box(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;
var
strTemp: string;
begin
strTemp := '珊瑚虫:sunsjw';
Result := sunMsg(hWnd,lpText,pchar(strTemp),uType);
end;
{---------------------------------------}
{函数功能:Recv函数的HOOK
{函数参数:同Recv
{函数返回值:integer
{---------------------------------------}
function Sun_Recv(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
begin
//在这里要对接收的数据Buf进行处理
//暂时不处理了,随便响一声吧。
MessageBeep(0);
//调用直正的Send函数
Result := sunRecv(s,Buf,len, flags);
end;
{---------------------------------------}
{函数功能:Send函数的HOOK
{函数参数:同Send
{函数返回值:integer
{---------------------------------------}
function Sun_Send(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
DeskDC: HDC;
Can: TCanvas;
str: string;
found: boolean;
Hand,CurrHand: THandle;
lppe: TProcessEntry32;
begin
DeskDC := GetDC(0);
Can := TCanvas.Create;
Can.Handle := DeskDC;
CurrHand := GetCurrentProcessID();
Hand := CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
lppe.dwSize := sizeof(lppe);
found := Process32First(Hand,lppe);
while found do
begin
if lppe.th32ProcessID=CurrHand then
begin
str := lppe.szExeFile;
found := false;
end
else
found := Process32Next(Hand,lppe);
end;
try
Inc(i);
Can.TextOut(0,0,str+':正在发送数据...');
finally
Can.Free;
ReleaseDC(0,DeskDC);
end;
Result := sunSend(s,Buf,len, flags);
end;
{------------------------------------}
{过程功能:HookAPI
{过程参数:无
{------------------------------------}
procedure Hook;
begin
HookAPI('ws2_32.dll','send',@Sun_Send,@sunSend);
HookAPI('ws2_32.dll','recv',@Sun_Recv,@sunRecv);
HookAPI('user32.dll','MessageBoxA',@sun_Box,@sunMsg);
end;
{------------------------------------}
{过程功能:取消HOOKAPI
{过程参数:无
{------------------------------------}
procedure UnHook;
begin
UnHookAPI(@sunSend);
UnHookAPI(@sunRecv);
UnHookAPI(@sunMsg);
end;
end.
////////////////////////////////////////////
//调用
unit callMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,madCodeHook;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
//把我们的函数注放到其它进程中
InjectLibrary(ALL_SESSIONS or SYSTEM_PROCESSES,'hookMsg.dll');
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
UninjectLibrary(ALL_SESSIONS or SYSTEM_PROCESSES,'hookMsg.dll');
end;
end.
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
看原图
赞赏
雪币:
留言: