专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »Delphi教程 » apihook技术:APIHOOK技术(二) »正文

apihook技术:APIHOOK技术(二)

来源: 发布时间:星期四, 2009年2月12日 浏览:78次 评论:0


在这里我将要实现转跳有人说修改内存内容要进入Ring 0 才可以可是Windows本身提供了个写内存指令WriteProcessMemory有了这把利器我们几乎无所不能如游戏修改等在这里我们只谈APIHOOK
function RepoFunction(OldFunc, NewFunc: Poer): Integer;
var
IsDone: TList;
function RepoAddrInModule(hModule: THandle; OldFunc, NewFunc: Poer): Integer;
var
Dos: PImageDosHeader;
NT: PImageNTHeaders;
ImportDesc: PImage_Import_Entry;
RVA: DWORD;
Func: ^Poer;
DLL: ;
f: Poer;
written: DWORD;
begin
Result := 0;
Dos := Poer(hModule);
IsDone.IndexOf(Dos) >= 0 then exit;
IsDone.Add(Dos); OldFunc := LocateFunctionAddress(OldFunc);

IsBadReadPtr(Dos, SizeOf(TImageDosHeader)) then exit;
Dos.e_magic <> IMAGE_DOS_SIGNATURE then exit;
NT := Poer(Integer(Dos) + dos._lfa);

RVA := NT^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
.VirtualAddress;

RVA = 0 then exit;
ImportDesc := poer(eger(Dos) + RVA);
while (ImportDesc^.Name <> 0) do
begin
DLL := PChar(Integer(Dos) + ImportDesc^.Name);
RepoAddrInModule(GetModuleHandle(PChar(DLL)), OldFunc, NewFunc);
Func := Poer(Integer(DOS) + ImportDesc.LookupTable);
while Func^ <> nil do
begin
f := LocateFunctionAddress(Func^);
f = OldFunc then
begin
WriteProcessMemory(GetCurrentProcess, Func, @NewFunc, 4, written);
Written > 0 then Inc(Result);
end;
Inc(Func);
end;
Inc(ImportDesc);
end;
end;

begin
IsDone := TList.Create;
try
Result := RepoAddrInModule(GetModuleHandle(nil), OldFunc, NewFunc);
finally
IsDone.Free;
end;
end;
有了这两个我们几乎可以更改任何API
我们可以先写个DLL文件我这里以修改Text相关为例:
先定义几个:
type
TTextOutA = function(DC: HDC; X, Y: Integer; Str: PAnsiChar; Count: Integer): BOOL; stdcall;
TTextOutW = function(DC: HDC; X, Y: Integer; Str: PWideChar; Count: Integer): BOOL; stdcall;
TTextOut = function(DC: HDC; X, Y: Integer; Str: PChar; Count: Integer): BOOL; stdcall;
TDrawTextA = function(hDC: HDC; lpString: PAnsiChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
TDrawTextW = function(hDC: HDC; lpString: PWideChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
TDrawText = function(hDC: HDC; lpString: PChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
var
OldTextOutA: TTextOutA;
OldTextOutW: TTextOutW;
OldTextOut: TTextOut;
OldDrawTextA: TDrawTextA;
OldDrawTextW: TDrawTextW;
OldDrawText: TDrawText;
......
function MyTextOutA(DC: HDC; X, Y: Integer; Str: PAnsiChar; Count: Integer): BOOL; stdcall;
begin
OldTextOutA(DC, X, Y, \'ABC\', length(\'ABC\'));
end;

function MyTextOutW(DC: HDC; X, Y: Integer; Str: PWideChar; Count: Integer): BOOL; stdcall;
begin
OldTextOutW(DC, X, Y, \'ABC\', length(\'ABC\'));
end;

function MyTextOut(DC: HDC; X, Y: Integer; Str: PChar; Count: Integer): BOOL; stdcall;
begin
OldTextOut(DC, X, Y, \'ABC\', length(\'ABC\'));


end;

function MyDrawTextA(hDC: HDC; lpString: PAnsiChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
begin
OldDrawTextA(hDC, \'ABC\', length(\'ABC\'), lpRect, uFormat);
end;

function MyDrawTextW(hDC: HDC; lpString: PWideChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
begin
OldDrawTextW(hDC, \'ABC\', length(\'ABC\'), lpRect, uFormat);
end;

function MyDrawText(hDC: HDC; lpString: PChar; nCount: Integer; var lpRect: TRect; uFormat: UINT): Integer; stdcall;
begin
OldDrawText(hDC, \'ABC\', length(\'ABC\'), lpRect, uFormat);
end;

时我们要把原来地址保存下来:
@OldTextOutA = nil then
@OldTextOutA := LocateFunctionAddress(@TextOutA);
@OldTextOutW = nil then
@OldTextOutW := LocateFunctionAddress(@TextOutW);
@OldTextOut = nil then
@OldTextOut := LocateFunctionAddress(@TextOut);
@OldDrawTextA = nil then
@OldDrawTextA := LocateFunctionAddress(@DrawTextA);
@OldDrawTextW = nil then
@OldDrawTextW := LocateFunctionAddress(@DrawTextW);
@OldDrawText = nil then
@OldDrawText := LocateFunctionAddress(@DrawText);
然后很顺其自然用自己替换掉原来
RepoFunction(@OldTextOutA, @MyTextOutA);
RepoFunction(@OldTextOutW, @MyTextOutW);
RepoFunction(@OldTextOut, @MyTextOut);
RepoFunction(@OldDrawTextA, @MyDrawTextA);
RepoFunction(@OldDrawTextW, @MyDrawTextW);
RepoFunction(@OldDrawText, @MyDrawText);
在结束时不要忘记恢复原来入口要不然你会死得很难看哟!好了我们在写个Demo你会说如何文字没有变成ABC呀?是呀你要刷新下才行最小化然后在最大化看看变了没有
要不然你就写代码刷新下好了至于去拦截其他进程API那就用SetWindowsHookEx写个其他钩子将DLL映射进去就行了我就不再浪费口水了
掌握了该思路方法你几乎无所不能你可以修改其它你可以拦截Createwindow等窗口改变其他窗口形状、你还可以入侵其它你还可以......嘿嘿


0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: