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
相关文章读者评论发表评论 |
|