Api Hook 问题(附:源代码)(200分)

  • 主题发起人 主题发起人 iNFRARED
  • 开始时间 开始时间
I

iNFRARED

Unregistered / Unconfirmed
GUEST, unregistred user!
我用改写Jump的方法写了个APIHOOK程序,可是发现不能拦截被压缩的程序<br>(如ASPack压缩过的程序),请高手指点怎么解决。(自己用Delphi写的程序和记事本等<br>程序都能拦截)<br><br>源程序如下:<br><br>DLL部分<br>===================================<br>library HOOK;<br><br>uses<br>&nbsp; Windows,<br>&nbsp; WinSock,<br>&nbsp; SysUtils,<br>&nbsp; Classes,<br>&nbsp; PERecord in 'PERecord.pas';<br><br>{$R *.res}<br><br>type<br>&nbsp; &nbsp;TMessageBoxA=function(hwn:hwnd;iptext:pchar;ipcaption:pchar;utype:cardinal):integer;stdcall;<br>&nbsp; &nbsp;TMessageBoxW=function(hwn:hwnd;iptext:pchar;ipcaption:pchar;utype:cardinal):integer;stdcall;<br>var<br>&nbsp; &nbsp;HookHandle: THandle;<br>&nbsp; &nbsp;OldMessageBoxA:TMessageBoxA;<br>&nbsp; &nbsp;OldMessageBoxW:TMessageBoxW;<br><br>function LocateFunctionAddress(Code:Pointer):Pointer;<br>var<br>&nbsp; &nbsp;func:PImportCode;<br>begin<br>&nbsp; &nbsp;Result:=Code;<br>&nbsp; &nbsp;if Code=nil then exit;<br>&nbsp; &nbsp;try<br>&nbsp; &nbsp; &nbsp; func:=Code;<br>&nbsp; &nbsp; &nbsp; if(func.JumpInstruction=$25FF) then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; Result:=func.AddressOfPointerToFunction^;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp;except<br>&nbsp; &nbsp; &nbsp; Result:=nil;<br>&nbsp; &nbsp;end;<br>end;<br><br>function RepointFunction(OldFunc, NewFunc: Pointer): Integer;<br>var<br>&nbsp; &nbsp;IsDone: TList;<br>&nbsp; &nbsp;function RepointAddrInModule(hModule: THandle; OldFunc, NewFunc: Pointer): Integer;<br>&nbsp; &nbsp;var<br>&nbsp; &nbsp; &nbsp; Dos: PImageDosHeader;<br>&nbsp; &nbsp; &nbsp; NT: PImageNTHeaders;<br>&nbsp; &nbsp; &nbsp; ImportDesc: PImage_Import_Entry;<br>&nbsp; &nbsp; &nbsp; RVA: DWORD;<br>&nbsp; &nbsp; &nbsp; Func: ^Pointer;<br>&nbsp; &nbsp; &nbsp; DLL: string;<br>&nbsp; &nbsp; &nbsp; f: Pointer;<br>&nbsp; &nbsp; &nbsp; written: DWORD;<br>&nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp; Result := 0;<br>&nbsp; &nbsp; &nbsp; Dos := Pointer(hModule);<br>&nbsp; &nbsp; &nbsp; if IsDone.IndexOf(Dos) &gt;= 0 then exit;<br>&nbsp; &nbsp; &nbsp; IsDone.Add(Dos);<br><br>&nbsp; &nbsp; &nbsp; OldFunc := LocateFunctionAddress(OldFunc);<br><br>&nbsp; &nbsp; &nbsp; if IsBadReadPtr(Dos, SizeOf(TImageDosHeader)) then exit;<br>&nbsp; &nbsp; &nbsp; if Dos.e_magic &lt;&gt; IMAGE_DOS_SIGNATURE then exit;<br>&nbsp; &nbsp; &nbsp; NT := Pointer(Integer(Dos) + dos._lfanew);<br><br>&nbsp; &nbsp; &nbsp; RVA := NT^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.VirtualAddress;<br><br>&nbsp; &nbsp; &nbsp; if RVA = 0 then exit;<br>&nbsp; &nbsp; &nbsp; ImportDesc := pointer(integer(Dos) + RVA);<br>&nbsp; &nbsp; &nbsp; while (ImportDesc^.Name &lt;&gt; 0) do<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DLL := PChar(Integer(Dos) + ImportDesc^.Name);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;RepointAddrInModule(GetModuleHandle(PChar(DLL)), OldFunc, NewFunc);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Func := Pointer(Integer(DOS) + ImportDesc.LookupTable);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;while Func^ &lt;&gt; nil do<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; f := LocateFunctionAddress(Func^);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if f = OldFunc then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;WriteProcessMemory(GetCurrentProcess, Func, @NewFunc, 4, written);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if Written &gt; 0 then Inc(Result);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Inc(Func);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Inc(ImportDesc);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp;end;<br><br>begin<br>&nbsp; &nbsp;IsDone := TList.Create;<br>&nbsp; &nbsp;try<br>&nbsp; &nbsp; &nbsp; Result := RepointAddrInModule(GetModuleHandle(nil), OldFunc, NewFunc);<br>&nbsp; &nbsp;finally<br>&nbsp; &nbsp; &nbsp; IsDone.Free;<br>&nbsp; &nbsp;end;<br>end;<br><br><br>function MyMessageBoxA(hwn:hwnd;iptext:pchar;ipcaption:pchar;utype:cardinal):integer;stdcall;<br>begin<br>&nbsp; Result:=OldMessageBoxA(hwn,'ok','ok',MB_OK);<br>end;<br><br>function MyMessageBoxW(hwn:hwnd;iptext:pchar;ipcaption:pchar;utype:cardinal):integer;stdcall;<br>begin<br>&nbsp; Result:=OldMessageBoxW(hwn,'ok','ok',MB_OK);<br>end;<br><br>function GetMsgProc(code: integer; removal: integer; msg: Pointer): Integer; stdcall;<br>begin<br>&nbsp; if @OldMessageBoxA=nil then<br>&nbsp; &nbsp; &nbsp;@OldMessageBoxA:=LocateFunctionAddress(@MessageBoxA);<br>&nbsp; if @OldMessageBoxW=nil then<br>&nbsp; &nbsp; &nbsp;@OldMessageBoxW:=LocateFunctionAddress(@MessageBoxW);<br>&nbsp; RepointFunction(@OldMessageBoxA,@MyMessageBoxA);<br>&nbsp; RepointFunction(@OldMessageBoxW,@MyMessageBoxW);<br>end;<br><br>procedure StartHook(dwThreadId:DWORD); stdcall;<br>var<br>&nbsp; &nbsp;dwThreadIdMy:DWORD;<br>begin<br>&nbsp; &nbsp;//dwThreadIdMy:=GetcurrentThreadId();<br>&nbsp; &nbsp;HookHandle:=SetWindowsHookEx(WH_GETMESSAGE, @GetMsgProc, HInstance, dwThreadId);<br>end;<br><br>procedure StopHook; stdcall;<br>begin<br>&nbsp; UnhookWindowsHookEx(HookHandle);<br>&nbsp; if @OldMessageBoxA &lt;&gt; nil then<br>&nbsp; begin<br>&nbsp; &nbsp; &nbsp;RepointFunction(@MyMessageBoxA,@OldMessageBoxA);<br>&nbsp; &nbsp; &nbsp;RepointFunction(@MyMessageBoxW,@OldMessageBoxW);<br>&nbsp; end;<br>end;<br><br>exports StartHook, StopHook;<br><br>begin<br>end.<br>============================<br><br>结构定义部分<br>===========================<br>unit PERecord;<br><br>interface<br>uses Windows;<br><br>type<br>&nbsp; TImportCode = packed record<br>&nbsp; &nbsp; &nbsp;JumpInstruction:WORD;<br>&nbsp; &nbsp; &nbsp;AddressOfPointerToFunction:^Pointer;<br>&nbsp; end;<br>&nbsp; PImportCode=^TImportCode;<br>&nbsp; <br>type<br>&nbsp; PImageDosHeader = ^TImageDosHeader;<br>&nbsp; _IMAGE_DOS_HEADER = packed record<br>&nbsp; &nbsp; &nbsp; e_magic: Word;<br>&nbsp; &nbsp; &nbsp; e_cblp: Word;<br>&nbsp; &nbsp; &nbsp; e_cp: Word;<br>&nbsp; &nbsp; &nbsp; e_crlc: Word;<br>&nbsp; &nbsp; &nbsp; e_cparhdr: Word;<br>&nbsp; &nbsp; &nbsp; e_minalloc: Word;<br>&nbsp; &nbsp; &nbsp; e_maxalloc: Word;<br>&nbsp; &nbsp; &nbsp; e_ss: Word;<br>&nbsp; &nbsp; &nbsp; e_sp: Word;<br>&nbsp; &nbsp; &nbsp; e_csum: Word;<br>&nbsp; &nbsp; &nbsp; e_ip: Word;<br>&nbsp; &nbsp; &nbsp; e_cs: Word;<br>&nbsp; &nbsp; &nbsp; e_lfarlc: Word;<br>&nbsp; &nbsp; &nbsp; e_ovno: Word;<br>&nbsp; &nbsp; &nbsp; e_res: array [0..3] of Word;<br>&nbsp; &nbsp; &nbsp; e_oemid: Word;<br>&nbsp; &nbsp; &nbsp; e_oeminfo: Word;<br>&nbsp; &nbsp; &nbsp; e_res2: array [0..9] of Word;<br>&nbsp; &nbsp; &nbsp; _lfanew: LongInt;<br>&nbsp; end;<br>&nbsp; TImageDosHeader = _IMAGE_DOS_HEADER;<br><br>&nbsp; PIMAGE_FILE_HEADER = ^IMAGE_FILE_HEADER;<br>&nbsp; IMAGE_FILE_HEADER = packed record<br>&nbsp; &nbsp; Machine &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: WORD;<br>&nbsp; &nbsp; NumberOfSections &nbsp; &nbsp;: WORD;<br>&nbsp; &nbsp; TimeDateStamp &nbsp; &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; PointerToSymbolTable : DWORD;<br>&nbsp; &nbsp; NumberOfSymbols &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; SizeOfOptionalHeader : WORD;<br>&nbsp; &nbsp; Characteristics &nbsp; &nbsp; &nbsp;: WORD;<br>&nbsp; end;<br><br>&nbsp; PIMAGE_DATA_DIRECTORY = ^IMAGE_DATA_DIRECTORY;<br>&nbsp; IMAGE_DATA_DIRECTORY = packed record<br>&nbsp; &nbsp; VirtualAddress &nbsp;: DWORD;<br>&nbsp; &nbsp; Size &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; end;<br><br>&nbsp; PIMAGE_SECTION_HEADER = ^IMAGE_SECTION_HEADER;<br>&nbsp; IMAGE_SECTION_HEADER = packed record<br>&nbsp; &nbsp; Name &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: packed array [0..IMAGE_SIZEOF_SHORT_NAME-1] of Char;<br>&nbsp; &nbsp; VirtualSize : DWORD;<br>&nbsp; &nbsp; VirtualAddress &nbsp;: DWORD;<br>&nbsp; &nbsp; SizeOfRawData &nbsp;: DWORD;<br>&nbsp; &nbsp; PointerToRawData : DWORD;<br>&nbsp; &nbsp; PointerToRelocations : DWORD;<br>&nbsp; &nbsp; PointerToLinenumbers : DWORD;<br>&nbsp; &nbsp; NumberOfRelocations : WORD;<br>&nbsp; &nbsp; NumberOfLinenumbers : WORD;<br>&nbsp; &nbsp; Characteristics : DWORD;<br>&nbsp; end;<br><br>&nbsp; PIMAGE_OPTIONAL_HEADER = ^IMAGE_OPTIONAL_HEADER;<br>&nbsp; IMAGE_OPTIONAL_HEADER = packed record<br>&nbsp; { Standard fields. }<br>&nbsp; &nbsp; Magic &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: WORD;<br>&nbsp; &nbsp; MajorLinkerVersion : Byte;<br>&nbsp; &nbsp; MinorLinkerVersion : Byte;<br>&nbsp; &nbsp; SizeOfCode &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; SizeOfInitializedData : DWORD;<br>&nbsp; &nbsp; SizeOfUninitializedData : DWORD;<br>&nbsp; &nbsp; AddressOfEntryPoint : DWORD;<br>&nbsp; &nbsp; BaseOfCode &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; BaseOfData &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; { NT additional fields. }<br>&nbsp; &nbsp; ImageBase &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; SectionAlignment : DWORD;<br>&nbsp; &nbsp; FileAlignment &nbsp;: DWORD;<br>&nbsp; &nbsp; MajorOperatingSystemVersion : WORD;<br>&nbsp; &nbsp; MinorOperatingSystemVersion : WORD;<br>&nbsp; &nbsp; MajorImageVersion : WORD;<br>&nbsp; &nbsp; MinorImageVersion : WORD;<br>&nbsp; &nbsp; MajorSubsystemVersion : WORD;<br>&nbsp; &nbsp; MinorSubsystemVersion : WORD;<br>&nbsp; &nbsp; Reserved1 &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; SizeOfImage &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; SizeOfHeaders &nbsp;: DWORD;<br>&nbsp; &nbsp; CheckSum &nbsp; &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; Subsystem &nbsp; &nbsp; &nbsp;: WORD;<br>&nbsp; &nbsp; DllCharacteristics : WORD;<br>&nbsp; &nbsp; SizeOfStackReserve : DWORD;<br>&nbsp; &nbsp; SizeOfStackCommit : DWORD;<br>&nbsp; &nbsp; SizeOfHeapReserve : DWORD;<br>&nbsp; &nbsp; SizeOfHeapCommit : DWORD;<br>&nbsp; &nbsp; LoaderFlags &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; NumberOfRvaAndSizes : DWORD;<br>&nbsp; &nbsp; DataDirectory &nbsp;: packed array [0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES-1] of IMAGE_DATA_DIRECTORY;<br>&nbsp; &nbsp; Sections: packed array [0..9999] of IMAGE_SECTION_HEADER;<br>&nbsp; end;<br><br>&nbsp; PIMAGE_NT_HEADERS = ^IMAGE_NT_HEADERS;<br>&nbsp; IMAGE_NT_HEADERS = packed record<br>&nbsp; &nbsp; Signature &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; FileHeader &nbsp; &nbsp; &nbsp;: IMAGE_FILE_HEADER;<br>&nbsp; &nbsp; OptionalHeader &nbsp;: IMAGE_OPTIONAL_HEADER;<br>&nbsp; end;<br>&nbsp; PImageNtHeaders = PIMAGE_NT_HEADERS;<br>&nbsp; TImageNtHeaders = IMAGE_NT_HEADERS;<br><br>&nbsp; PIMAGE_IMPORT_DESCRIPTOR = ^IMAGE_IMPORT_DESCRIPTOR;<br>&nbsp; IMAGE_IMPORT_DESCRIPTOR = packed record<br>&nbsp; &nbsp; Characteristics: DWORD;<br>&nbsp; &nbsp; Name: DWORD;<br>&nbsp; &nbsp; FirstThunk: DWORD;<br>&nbsp; &nbsp; ForwarderChain: DWORD;<br>&nbsp; end;<br>&nbsp; TImageImportDescriptor = IMAGE_IMPORT_DESCRIPTOR;<br>&nbsp; PImageImportDescriptor = PIMAGE_IMPORT_DESCRIPTOR;<br><br>&nbsp; PIMAGE_IMPORT_BY_NAME = ^IMAGE_IMPORT_BY_NAME;<br>&nbsp; IMAGE_IMPORT_BY_NAME = record<br>&nbsp; &nbsp; Hint: Word;<br>&nbsp; &nbsp; Name: Array[0..0] of Char;<br>&nbsp; end;<br><br>&nbsp; PIMAGE_THUNK_DATA = ^IMAGE_THUNK_DATA;<br>&nbsp; IMAGE_THUNK_DATA = record<br>&nbsp; &nbsp; Whatever: DWORD;<br>&nbsp; end;<br><br>&nbsp; PImage_Import_Entry = ^Image_Import_Entry;<br>&nbsp; Image_Import_Entry = record<br>&nbsp; &nbsp; Characteristics: DWORD;<br>&nbsp; &nbsp; TimeDateStamp: DWORD;<br>&nbsp; &nbsp; MajorVersion: Word;<br>&nbsp; &nbsp; MinorVersion: Word;<br>&nbsp; &nbsp; Name: DWORD;<br>&nbsp; &nbsp; LookupTable: DWORD;<br>&nbsp; end;<br><br><br>const<br>IMAGE_DOS_SIGNATURE &nbsp; &nbsp;= &nbsp;$5A4D; &nbsp; &nbsp; &nbsp;// MZ<br>IMAGE_OS2_SIGNATURE &nbsp; &nbsp;= &nbsp;$454E; &nbsp; &nbsp; &nbsp;// NE<br>IMAGE_OS2_SIGNATURE_LE &nbsp;= &nbsp;$454C; &nbsp; &nbsp; &nbsp;// LE<br>IMAGE_VXD_SIGNATURE &nbsp; &nbsp;= &nbsp;$454C; &nbsp; &nbsp; &nbsp;// LE<br>IMAGE_NT_SIGNATURE &nbsp; &nbsp; &nbsp;= &nbsp;$00004550; &nbsp;// PE00<br><br>implementation<br><br>end.<br>====================<br><br>测试程序部分<br>====================<br>unit Unit1;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>&nbsp; Dialogs, StdCtrls;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; Button2: TButton;<br>&nbsp; &nbsp; Button3: TButton;<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; &nbsp; procedure Button2Click(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>implementation<br><br>{$R *.dfm}<br>procedure StartHook(dwThreadId:DWORD); stdcall; external 'HOOK.DLL';<br>procedure StopHook; stdcall; external 'HOOK.DLL';<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>Var<br>&nbsp;my:DWORD;<br>&nbsp;hwn:hwnd;<br>begin<br>&nbsp; &nbsp;hwn:=FindWindow('','XXX');<br>&nbsp; &nbsp;StartHook(GetWindowThreadProcessId(hwn));<br>end;<br><br>procedure TForm1.Button2Click(Sender: TObject);<br>begin<br>&nbsp; &nbsp;StopHook;<br>end;<br><br>end.<br><br>========================
 
核心程序没多少,:)
 
上面的代码好象没有成功拦截 API ??!!
 
有个方法能解决就是挂接GetProcAddress API,不过要在被HOOK程序开始运行的时候就要挂接,<br>可以用CreateProcess的方法实现,不过要用ASM写部分代码,我不会,呵呵。<br>
 
晕死,没人懂吗?
 
你用的是过时的方法<br>建议你看一本书<br>《windows核心编程》
 
建议使用下函数<br>上面的代码有一大半是可以去掉的<br><br>The ImageDirectoryEntryToData function obtains access to image-specific data.<br><br>PVOID ImageDirectoryEntryToData(<br><br>&nbsp; &nbsp; IN LPVOID Base, <br>&nbsp; &nbsp; IN BOOLEAN MappedAsImage, <br>&nbsp; &nbsp; IN USHORT DirectoryEntry, <br>&nbsp; &nbsp; OUT PULONG Size <br>&nbsp; &nbsp;);<br><br>还有,使用Writeprocessmemory之前<br>要用VirtualProtect修改页面access protection<br>前面提到的书中这里有误<br>我试过的
 
你的目标函数地址是用遍历PE文件ImportTable的方式来取得,但是一些经过EXE文件的ImportTable<br>经过压缩或加壳后被做了手脚,这样的你RepointFunction函数就无法得到正常的结果了.
 
windows核心编程看过了,就是不会改写成delphi程序,呵呵。
 
据我所知,到目前为止,用delphi做的hookapi只能hook部分api.比如能够hook messagebox<br>但不能hook recv或者只能hook某些程序的recv,大富翁上找了很久,还没有哪位朋友能解决的<br>为此我已经打出了2000多分,但一无所获。大富翁的高手,舍你其谁呀!!
 
拦截的目标不同,所用的“钩子函数”是不同的。<br>但与拦截对象是否压缩、加密等无关,除非你想实现特殊功能。<br>1)到目前为止,WINDOWS环境下(WINDOWS9X/ME/NT/2K/XP)还没有不能拦截的;<br>2)拦截与实现被拦截对象的处理,比如解密、再加密、分析数据内容或其它需要编写<br>自己的API。<br>toyzn2002@yahoo.com.cn
 
可用在api前插入jump指令的方法实现。不要用import hook.因为压缩过的程序的import表是<br>壳的函数的import.你那种方法hook不了用getproceaddressa引入的api
 
I also study.
 

Similar threads

后退
顶部