2k + sp4测试通过。<br>因为看到你的帖子才作的这个东西,所以代码很乱,许多东西都是从以前的代码东拼西凑出来的,有很大的优化空间。<br>因为你会做这类的东西,所以也没写注释,凑活看吧。<br>下面代码还不能hook仅导出Ordinal的函数,需要的话自己加吧,位置已经留出来了。<br>==============Unit1.pas(Hookdll Loader)==============<br>unit Unit1;<br><br>interface<br><br>uses<br> Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> Dialogs, StdCtrls;<br><br>type<br> TForm1 = class(TForm)<br> Button1: TButton; // only a button<br> procedure Button1Click(Sender: TObject);<br> private<br> public<br> end;<br><br>var<br> Form1: TForm1;<br><br>implementation<br><br>{$R *.dfm}<br><br>const<br> VictimExe = 'c:/winnt/system32/cmd.exe';//'C:/Program Files/Borland/Delphi6/Projects/APIHOOK/test/test.exe';<br> HookDll = 'NewHook.dll';<br><br>var<br> si: STARTUPINFO;<br> pi: PROCESS_INFORMATION;<br><br>function EnabledDebugPrivilege(const bEnabled: Boolean):Boolean;<br>var<br> hToken: THandle;<br> tp: TOKEN_PRIVILEGES;<br> a: DWORD;<br>const<br> SE_DEBUG_NAME = 'SeDebugPrivilege';<br>begin<br> Result:=False;<br> if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, hToken)) then<br> begin<br> tp.PrivilegeCount :=1;<br> LookupPrivilegeValue(nil,SE_DEBUG_NAME ,tp.Privileges[0].Luid);<br> if bEnabled then<br> tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED<br> else<br> tp.Privileges[0].Attributes := 0;<br> a:=0;<br> AdjustTokenPrivileges(hToken,False,tp,SizeOf(tp),nil,a);<br> Result:= GetLastError = ERROR_SUCCESS;<br> CloseHandle(hToken);<br> end;<br>end;<br><br>function InjectDll(hProc:Cardinal; Dll:string):Cardinal;<br>var<br> wDllPath
wideChar;<br> pRemote
ointer;<br> cbSize:cardinal;<br> TempVar:Cardinal;<br>begin<br> result:=0;<br> if hProc=0 then exit;<br> EnabledDebugPrivilege(true);<br> cbSize:= length(Dll) * 2 + 21;<br> GetMem(wDllPath,cbSize);<br> StringToWideChar(Dll,wDllPath,cbSize);<br> try<br> pRemote:=VirtualAllocEx( hProc, nil, cbSize, MEM_COMMIT, PAGE_READWRITE);<br> if WriteProcessMemory(hProc,pRemote, wDllPath, cbSize, TempVar) then<br> begin<br> TempVar:=0;<br> Result := CreateRemoteThread(hProc, nil, 0,<br> GetProcAddress(GetModuleHandle('Kernel32'),<br> 'LoadLibraryW'), pRemote, 0, TempVar);<br> VirtualFreeEx(hProc, pRemote, 0, MEM_DECOMMIT or MEM_RELEASE);<br> end;<br> finally<br> FreeMem(wDllPath);<br> end;<br>end;<br><br>procedure CreateVictimProcess(Path: String);<br>begin <br> ZeroMemory(@si, sizeof(STARTUPINFO));<br> si.cb := sizeof(STARTUPINFO);<br> if not CreateProcess(PChar(Path), nil, nil, nil, False, CREATE_SUSPENDED or CREATE_DEFAULT_ERROR_MODE, nil, nil, si, pi) then<br> begin<br> ShowMessage('CreateProcess failed!');<br> exit;<br> end;<br>end;<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br> CreateVictimProcess(VictimExe);<br> InjectDll(pi.hProcess, HookDll);<br> Sleep(20);<br> ResumeThread(pi.hThread);<br>end;<br><br>end.<br>============NewHook.dpr(NewHook.dll)=============<br>library NewHook;<br><br>uses<br> JwaWinType,<br> JwaWinNt,<br> JwaWinUser,<br> JwaWinBase,<br> JwaWinGdi,<br> Classes,<br> SysUtils;<br><br>const<br> Func2Hook = 'CreateFileW';<br> FuncInDll = 'Kernel32.dll';<br><br>var<br> pFunc: Pointer = nil;<br> pOriginFunc: Pointer;<br><br>function NewCreateFileW(lpFileName: LPCWSTR; dwDesiredAccess, dwShareMode: DWORD;<br> lpSecurityAttributes: LPSECURITY_ATTRIBUTES; dwCreationDisposition: DWORD;<br> dwFlagsAndAttributes: DWORD; hTemplateFile: HANDLE): HANDLE; stdcall;<br>var<br>oc: function (lpFileName: LPCWSTR; dwDesiredAccess, dwShareMode: DWORD;<br> lpSecurityAttributes: LPSECURITY_ATTRIBUTES; dwCreationDisposition: DWORD;<br> dwFlagsAndAttributes: DWORD; hTemplateFile: HANDLE): HANDLE; stdcall;<br>dc:hdc;<br>begin<br> dc := getdc(0);<br> textout(dc, 20, 20, 'CreateFileW!', 12);<br> releasedc(0, dc);<br> oc := pOriginFunc;<br> oc(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition,<br> dwFlagsAndAttributes, hTemplateFile);<br>end;<br><br>function NewMessageBoxA(AWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;<br>var<br> ofunc: function (AWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;<br>begin<br> ofunc := pOriginFunc;<br> result := ofunc(AWnd, PChar('Hooked!!! ' + lpText), lpCaption, uType);<br>end;<br><br>function FuncInImage: Cardinal; //Return ImageBase<br>var<br> peb, ldr, flink, p, bs,ep
DWORD;<br>begin<br> result := 0;<br> asm<br> mov eax,fs:[$30]<br> mov peb,eax<br> end;<br> ldr:=pointer(dword(pointer(dword(peb)+12)^));<br> flink:=pointer(dword(pointer(dword(ldr)+12)^));<br> p:=flink;<br> repeat<br> bs:=pointer(pointer(dword(p)+$18)^); // Base address<br> ep:=pointer(pointer(dword(p)+$20)^); // Size of image<br> if (DWORD(pFunc) > DWORD(bs)) and (DWORD(pFunc) < DWORD(bs) + DWORD(ep)) then<br> begin<br> result := DWORD(bs);<br> Break;<br> end;<br> p:=pointer(dword(p^));<br> until dword(flink)=dword(p^);<br>end;<br><br>procedure FixExport(ImageBase: Cardinal);<br>var<br> PFileHeader: PImageFileHeader;<br> POptionalHeader32: PImageOptionalHeader32;<br> PExportDirectory: PImageExportDirectory;<br> PDataDirectory: PImageDataDirectory;<br><br> ExpCount: integer;<br> pAddr: PDWORD;<br> pName0, pName1: PDWORD;<br> pOrdinal0, pOrdinal1: PWORD;<br> ExpFound: Boolean;<br> i, j: Cardinal;<br>begin<br> PFileHeader := PImageFileHeader(ImageBase + PImageDosHeader(ImageBase)^.e_lfanew + 4);<br> POptionalHeader32 := PImageOptionalHeader32(DWORD(PFileHeader) + IMAGE_SIZEOF_FILE_HEADER);<br> PDataDirectory := PImageDataDirectory(@POptionalHeader32^.DataDirectory[0]);<br> inc(PDataDirectory, IMAGE_DIRECTORY_ENTRY_EXPORT);<br> PExportDirectory := PImageExportDirectory(ImageBase +PDataDirectory^.VirtualAddress);<br><br> ExpCount := PExportDirectory^.NumberOfFunctions;<br> pAddr := Pointer(ImageBase + PExportDirectory^.AddressOfFunctions);<br> pName0 := Pointer(ImageBase + PExportDirectory^.AddressOfNames);<br> pOrdinal0 := Pointer(ImageBase + PExportDirectory^.AddressOfNameOrdinals);<br><br> for i := 0 to ExpCount - 1 do<br> begin<br> if pAddr^ <> 0 then<br> begin<br> ExpFound := false;<br> pName1 := pName0;<br> pOrdinal1 := pOrdinal0;<br> for j := 0 to PExportDirectory^.NumberOfNames - 1 do <br> begin<br> if pOrdinal1^ = i then<br> begin<br> if PChar(ImageBase + pName1^) = Func2Hook then<br> begin<br> ExpFound := true;<br> pOriginFunc := Pointer(ImageBase + pAddr^);<br> break;<br> end;<br> end;<br> inc(pOrdinal1);<br> inc(pName1);<br> end; // for j<br> if ExpFound then<br> begin<br> Break;<br>// tmpExp^.Orindal := pOrdinal1^ + ExpPtr^.Base;<br> end;<br>// else<br>// tmpExp^.Orindal := i + ExpPtr^.Base;<br><br> end; //if pAddr^ <> 0<br> inc(pAddr);<br> end; // for i<br> virtualprotect(pAddr, 4, $40, @i);<br> pAddr^ := DWORD(@NewCreateFileW) - ImageBase;<br>end;<br><br>function FuncUsed(ImageBase: Cardinal): Pointer;<br>var<br> PFileHeader: PImageFileHeader;<br> POptionalHeader32: PImageOptionalHeader32;<br> PImportDecriptor: PImageImportDecriptor;<br> PDataDirectory: PImageDataDirectory;<br> i, j: integer;<br>begin<br> result := nil;<br> PFileHeader := PImageFileHeader(ImageBase + PImageDosHeader(ImageBase)^.e_lfanew + 4);<br> POptionalHeader32 := PImageOptionalHeader32(DWORD(PFileHeader) + IMAGE_SIZEOF_FILE_HEADER);<br> PDataDirectory := PImageDataDirectory(@POptionalHeader32^.DataDirectory[0]);<br> inc(PDataDirectory, IMAGE_DIRECTORY_ENTRY_IMPORT);<br> if PDataDirectory^.Size = 0 then<br> exit;<br> PImportDecriptor := PImageImportDecriptor(ImageBase +PDataDirectory^.VirtualAddress);<br><br> while (PImportDecriptor^.Union.OriginalFirstThunk <> 0) or (PImportDecriptor^.TimeDateStamp <> 0) or<br> (PImportDecriptor^.ForwarderChain <> 0) or (PImportDecriptor^.Name <> 0) or (PImportDecriptor^.FirstThunk <> 0) do<br> begin<br> if CompareText(PChar(ImageBase + PImportDecriptor^.Name), FuncInDll)=0 then<br> begin<br>// if PImportDecriptor^.Union.OriginalFirstThunk <> 0 then<br>// j := ImageBase + PImportDecriptor^.Union.OriginalFirstThunk<br>// else<br> j := ImageBase + PImportDecriptor^.FirstThunk;<br> while PDWORD(j)^ <> 0 do<br> begin<br> if PDWORD(j)^ and IMAGE_ORDINAL_FLAG32 = 0 then<br> begin<br> if PDWORD(j)^ = DWORD(pOriginFunc) then<br> begin<br>// asm int 3 end;<br> virtualprotect(Pointer(j), 4, $40, @i);<br> PDWORD(j)^ := DWORD(@NewCreateFileW);<br> end;<br> //<br> // Ordinal only support here<br> //<br> end;<br> inc(j, 4);<br> end;<br> end;<br> inc(PImportDecriptor);<br> end;<br>end;<br><br>procedure FixImport;<br>var<br> peb, ldr, flink, p, bs
DWORD;<br>begin<br> asm<br> mov eax,fs:[$30]<br> mov peb,eax<br> end;<br> ldr:=pointer(dword(pointer(dword(peb)+12)^));<br> flink:=pointer(dword(pointer(dword(ldr)+12)^));<br> p:=flink;<br> repeat<br> bs:=pointer(pointer(dword(p)+$18)^); // Base address<br> FuncUsed(DWORD(bs));<br> p:=pointer(dword(p^));<br> until dword(flink)=dword(p^);<br>end;<br><br>procedure EntryPointProc(Reason: Integer);<br>var<br> ExpImageBase: Cardinal;<br>begin <br> if Reason <> DLL_PROCESS_ATTACH then<br> exit;<br> pFunc := GetProcAddress(GetModuleHandle(FuncInDll), Func2Hook);<br> ExpImageBase := FuncInImage;<br> if ExpImageBase <> GetModuleHandle(nil) then<br> FixExport(ExpImageBase);<br> FixImport;<br>end;<br><br>begin <br> DllProc := @EntryPointProc;<br> EntryPointProc(DLL_PROCESS_ATTACH);<br>end.