D dreamfly1024 Unregistered / Unconfirmed GUEST, unregistred user! 2006-09-30 #61 或者你要求用户声明的函数多一个参数,放在最前面或者最后面都行,用户的函数对这个参数进行修改,你根据修改的结果判断是否继续执行被 hook 的函数,或者进行其他操作,岂不是两全其美?
F FSNM Unregistered / Unconfirmed GUEST, unregistred user! 2006-09-30 #62 祝贺啊,能不能发一份给我学习一下呢?<br><br>394089feng@163.com
E errorcode Unregistered / Unconfirmed GUEST, unregistred user! 2006-10-01 #64 写个回调函数吧<br><br>我最烦OCX了。
白 白河愁 Unregistered / Unconfirmed GUEST, unregistred user! 2006-10-01 #65 dll写了半天搞不好,能不能写个例子,反而ocx快写好了
C cqwty Unregistered / Unconfirmed GUEST, unregistred user! 2006-10-01 #66 老白,恭喜哦,哈哈,对了,你给我说的加<br>asm<br> int 3<br>end;<br>这个代码加入到dll中,不能调试了。
白 白河愁 Unregistered / Unconfirmed GUEST, unregistred user! 2006-10-02 #67 为什么不能调试了 ?
X xxzs2006 Unregistered / Unconfirmed GUEST, unregistred user! 2006-10-02 #68 xiling_221@126.com 谢谢分享!
E errorcode Unregistered / Unconfirmed GUEST, unregistred user! 2006-10-02 #69 定义一个回调函数,函数原型声明要写出来,别人才能使用。<br><br>如:<br>TOnAPIHookProc = function HookAPIAPIHookProc(AParam: PDWORD; AParamCount: Integer; AData: Pointer): DWORD; stdcall;<br><br>然后AParam是你的参数,通过指针递增进行访问其它值,AData是调用者自定参数<br>for I := 0 to AParamCount - 1 do<br>begin<br> ShowMessage(IntToStr(AParam^));<br> Inc(AParam);<br>end;<br><br>像你上面的调用:<br> ...<br> AA.API.OnAPIHookProc:= @MyAPIHookProc; //API 执行后发生的回调<br> AA.API.Data := SomeData;<br><br>function MyAPIHookProc(AParam: PDWORD; AParamCount: Integer; AData: Pointer): DWORD; stdcall;<br>begin<br> ....<br>end;<br><br><br>你原代码使用事件的,调用:<br>AA.API.OnAPIHookProc(...)<br>变成这样:<br>AA.API.OnAPIHookProc(@AParam[1], High(AParam) - Low(AParam), AA.API.Data);<br>大概这样吧
定义一个回调函数,函数原型声明要写出来,别人才能使用。<br><br>如:<br>TOnAPIHookProc = function HookAPIAPIHookProc(AParam: PDWORD; AParamCount: Integer; AData: Pointer): DWORD; stdcall;<br><br>然后AParam是你的参数,通过指针递增进行访问其它值,AData是调用者自定参数<br>for I := 0 to AParamCount - 1 do<br>begin<br> ShowMessage(IntToStr(AParam^));<br> Inc(AParam);<br>end;<br><br>像你上面的调用:<br> ...<br> AA.API.OnAPIHookProc:= @MyAPIHookProc; //API 执行后发生的回调<br> AA.API.Data := SomeData;<br><br>function MyAPIHookProc(AParam: PDWORD; AParamCount: Integer; AData: Pointer): DWORD; stdcall;<br>begin<br> ....<br>end;<br><br><br>你原代码使用事件的,调用:<br>AA.API.OnAPIHookProc(...)<br>变成这样:<br>AA.API.OnAPIHookProc(@AParam[1], High(AParam) - Low(AParam), AA.API.Data);<br>大概这样吧
E errorcode Unregistered / Unconfirmed GUEST, unregistred user! 2006-10-02 #70 AA.API.OnAPIHookProc(@AParam[Low(AParam)], High(AParam) - Low(AParam), AA.API.Data);<br><br>是这样,错了
K kk2000 Unregistered / Unconfirmed GUEST, unregistred user! 2006-10-02 #71 //请白河愁 解释一下这段汇编好吗?<br>procedure ThreadPro;<br>var<br>VarList: TThreadProVarList;<br>begin<br>asm<br>mov eax, $FFFFFFFF {到$FFFFFFFF的偏移是7} <br>mov VarList.SendMessage, eax // 这里是把$FFFFFFFF 赋值给VarList.SendMessage这个变量吗? 为什么要赋这个值啊? <br>mov eax, $FFFFFFFF {这个$FFFFFFFF是在上一个偏移位置加8}<br>mov VarList.WndHandle, eax<br>mov eax, $FFFFFFFF<br>mov VarList.ExitProcess, eax<br>mov eax, $FFFFFFFF<br>mov VarList.ExitThread, eax<br>push 0 //lParam = 0<br>push 0 //Wparam = 0<br>push 4245 {4245就是自定义的WM_HOOKED} <br>push VarList.WndHandle //窗口句柄<br>call VarList.SendMessage //调用发送消息过程<br>push 0 //提供给ExitThread的参数为0 , <br>call VarList.ExitThread <br>end;<br>end;<br>//这句<br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+7), @SendPro, SizeOf(DWORD), WriteCount);<br>//下面不就是对ThreadPro VarList.SendMessage的变量写入了发送消息涵数的地址吗?为什么要开始mov eax, $FFFFFFFF {到$FFFFFFFF的偏移是7} <br>mov VarList.SendMessage, eax // 这里是把$FFFFFFFF 赋值给VarList.SendMessage这个变量吗? 为什么要赋这个值啊? 搞不懂?? <br>TmpHandle := Self.Handle;<br>//这个是写入窗口句柄<br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+15), @TmpHandle, SizeOf(DWORD), WriteCount);<br>//这个是写入ExitProcess<br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+23), @ExitPro, SizeOf(DWORD), WriteCount);<br>//这个是写入ExitThread<br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+31), @ExitTPro, SizeOf(DWORD), WriteCount);
//请白河愁 解释一下这段汇编好吗?<br>procedure ThreadPro;<br>var<br>VarList: TThreadProVarList;<br>begin<br>asm<br>mov eax, $FFFFFFFF {到$FFFFFFFF的偏移是7} <br>mov VarList.SendMessage, eax // 这里是把$FFFFFFFF 赋值给VarList.SendMessage这个变量吗? 为什么要赋这个值啊? <br>mov eax, $FFFFFFFF {这个$FFFFFFFF是在上一个偏移位置加8}<br>mov VarList.WndHandle, eax<br>mov eax, $FFFFFFFF<br>mov VarList.ExitProcess, eax<br>mov eax, $FFFFFFFF<br>mov VarList.ExitThread, eax<br>push 0 //lParam = 0<br>push 0 //Wparam = 0<br>push 4245 {4245就是自定义的WM_HOOKED} <br>push VarList.WndHandle //窗口句柄<br>call VarList.SendMessage //调用发送消息过程<br>push 0 //提供给ExitThread的参数为0 , <br>call VarList.ExitThread <br>end;<br>end;<br>//这句<br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+7), @SendPro, SizeOf(DWORD), WriteCount);<br>//下面不就是对ThreadPro VarList.SendMessage的变量写入了发送消息涵数的地址吗?为什么要开始mov eax, $FFFFFFFF {到$FFFFFFFF的偏移是7} <br>mov VarList.SendMessage, eax // 这里是把$FFFFFFFF 赋值给VarList.SendMessage这个变量吗? 为什么要赋这个值啊? 搞不懂?? <br>TmpHandle := Self.Handle;<br>//这个是写入窗口句柄<br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+15), @TmpHandle, SizeOf(DWORD), WriteCount);<br>//这个是写入ExitProcess<br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+23), @ExitPro, SizeOf(DWORD), WriteCount);<br>//这个是写入ExitThread<br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+31), @ExitTPro, SizeOf(DWORD), WriteCount);
L leun Unregistered / Unconfirmed GUEST, unregistred user! 2006-10-03 #73 {<br> Delphi Hooking Library by Aphex<br> http://www.iamaphex.cjb.net/<br> unremote@knology.net<br>}<br>unit afxCodeHook;<br><br>{$IMAGEBASE $13140000}<br><br>interface<br><br>uses<br> Windows;<br><br>function SizeOfCode(Code: pointer): dword;<br>function SizeOfProc(Proc: pointer): dword;<br><br>function InjectString(Process: LongWord; Text: pchar): pchar;<br>function InjectMemory(Process: LongWord; Memory: pointer; Len: dword): pointer;<br>function InjectThread(Process: dword; Thread: pointer; Info: pointer; InfoLen: dword; Results: boolean): THandle;<br>function InjectLibrary(Process: LongWord; ModulePath: string): boolean; overload;<br>function InjectLibrary(Process: LongWord; Src: pointer): boolean; overload;<br>function InjectExe(Process: LongWord; EntryPoint: pointer): boolean;<br>function UninjectLibrary(Process: LongWord; ModulePath: string): boolean;<br><br>function CreateProcessEx(lpApplicationName: pchar; lpCommandLine: pchar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles: boolean; dwCreationFlags: longword; lpEnvironment: pointer; lpCurrentDirectory: pchar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation; ModulePath: string): boolean; overload;<br>function CreateProcessEx(lpApplicationName: pchar; lpCommandLine: pchar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles: boolean; dwCreationFlags: longword; lpEnvironment: pointer; lpCurrentDirectory: pchar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation; Src: pointer): boolean; overload;<br><br>function HookCode(TargetModule, TargetProc: string; NewProc: pointer; var OldProc: pointer): boolean;<br>function UnhookCode(OldProc: pointer): boolean;<br><br>function DeleteFileEx(FilePath: pchar): boolean;<br>function DisableSFC: boolean;<br><br>implementation<br><br>type<br> TModuleList = array of cardinal;<br><br> PImageImportDescriptor = ^TImageImportDescriptor;<br> TImageImportDescriptor = packed record<br> OriginalFirstThunk: longword;<br> TimeDateStamp: longword;<br> ForwarderChain: longword;<br> Name: longword;<br> FirstThunk: longword;<br> end;<br><br> PImageBaseRelocation = ^TImageBaseRelocation;<br> TImageBaseRelocation = packed record<br> VirtualAddress: cardinal;<br> SizeOfBlock: cardinal;<br> end;<br><br> TDllEntryProc = function(hinstDLL: HMODULE; dwReason: longword; lpvReserved: pointer): boolean; stdcall;<br><br> TStringArray = array of string;<br><br> TLibInfo = record<br> ImageBase: pointer;<br> ImageSize: longint;<br> DllProc: TDllEntryProc;<br> DllProcAddress: pointer;<br> LibsUsed: TStringArray;<br> end;<br><br> PLibInfo = ^TLibInfo;<br> Ppointer = ^pointer;<br><br> TSections = array [0..0] of TImageSectionHeader;<br><br>const<br> IMPORTED_NAME_OFFSET = $00000002;<br> IMAGE_ORDINAL_FLAG32 = $80000000;<br> IMAGE_ORDINAL_MASK32 = $0000FFFF;<br><br> Opcodes1: array [0..255] of word =<br> (<br> (16913),(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),<br> (17124),(8209),(8420),(33793),(35906),(0),(0),(16913),(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),<br> (17124),(8209),(8420),(33793),(35906),(0),(32768),(16913),(17124),(8209),(8420),(33793),(35906),(0),(32768),(16913),<br> (17124),(8209),(8420),(33793),(35906),(0),(32768),(529),(740),(17),(228),(1025),(3138),(0),(32768),(24645),<br> (24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(69),<br> (69),(69),(69),(69),(69),(69),(69),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(0),<br> (32768),(228),(16922),(0),(0),(0),(0),(3072),(11492),(1024),(9444),(0),(0),(0),(0),(5120),<br> (5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(1296),<br> (3488),(1296),(1440),(529),(740),(41489),(41700),(16913),(17124),(8209),(8420),(17123),(8420),(227),(416),(0),<br> (57414),(57414),(57414),(57414),(57414),(57414),(57414),(32768),(0),(0),(0),(0),(0),(0),(32768),(33025),<br> (33090),(769),(834),(0),(0),(0),(0),(1025),(3138),(0),(0),(32768),(32768),(0),(0),(25604),<br> (25604),(25604),(25604),(25604),(25604),(25604),(25604),(27717),(27717),(27717),(27717),(27717),(27717),(27717),(27717),(17680),<br> (17824),(2048),(0),(8420),(8420),(17680),(19872),(0),(0),(2048),(0),(0),(1024),(0),(0),(16656),<br> (16800),(16656),(16800),(33792),(33792),(0),(32768),(8),(8),(8),(8),(8),(8),(8),(8),(5120),<br> (5120),(5120),(5120),(33793),(33858),(1537),(1602),(7168),(7168),(0),(5120),(32775),(32839),(519),(583),(0),<br> (0),(0),(0),(0),(0),(8),(8),(0),(0),(0),(0),(0),(0),(16656),(416)<br> <br><br> Opcodes2: array [0..255] of word =<br> (<br> (280),(288),(8420),(8420),(65535),(0),(0),(0),(0),(0),(65535),(65535),(65535),(272),(0),(1325),(63),<br> (575),(63),(575),(63),(63),(63),(575),(272),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(16419),<br> (16419),(547),(547),(65535),(65535),(65535),(65535),(63),(575),(47),(575),(61),(61),(63),(63),(0),<br> (32768),(32768),(32768),(0),(0),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(8420),<br> (8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(16935),<br> (63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(237),<br> (237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(101),(237),(1261),<br> (1192),(1192),(1192),(237),(237),(237),(0),(65535),(65535),(65535),(65535),(65535),(65535),(613),(749),(7168),<br> (7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(16656),<br> (16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(0),<br> (0),(32768),(740),(18404),(17380),(49681),(49892),(0),(0),(0),(17124),(18404),(17380),(32),(8420),(49681),<br> (49892),(8420),(17124),(8420),(8932),(8532),(8476),(65535),(65535),(1440),(17124),(8420),(8420),(8532),(8476),(41489),<br> (41700),(1087),(548),(1125),(9388),(1087),(33064),(24581),(24581),(24581),(24581),(24581),(24581),(24581),(24581),(65535),<br> (237),(237),(237),(237),(237),(749),(8364),(237),(237),(237),(237),(237),(237),(237),(237),(237),<br> (237),(237),(237),(237),(237),(63),(749),(237),(237),(237),(237),(237),(237),(237),(237),(65535),<br> (237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(0)<br> <br><br> Opcodes3: array [0..9] of array [0..15] of word =<br> (<br> ((1296),(65535),(16656),(16656),(33040),(33040),(33040),(33040),(1296),(65535),(16656),(16656),(33040),(33040),(33040),(33040)),<br> ((3488),(65535),(16800),(16800),(33184),(33184),(33184),(33184),(3488),(65535),(16800),(16800),(33184),(33184),(33184),(33184)),<br> ((288),(288),(288),(288),(288),(288),(288),(288),(54),(54),(48),(48),(54),(54),(54),(54)),<br> ((288),(65535),(288),(288),(272),(280),(272),(280),(48),(48),(0),(48),(0),(0),(0),(0)),<br> ((288),(288),(288),(288),(288),(288),(288),(288),(54),(54),(54),(54),(65535),(0),(65535),(65535)),<br> ((288),(65535),(288),(288),(65535),(304),(65535),(304),(54),(54),(54),(54),(0),(54),(54),(0)),<br> ((296),(296),(296),(296),(296),(296),(296),(296),(566),(566),(48),(48),(566),(566),(566),(566)),<br> ((296),(65535),(296),(296),(272),(65535),(272),(280),(48),(48),(48),(48),(48),(48),(65535),(65535)),<br> ((280),(280),(280),(280),(280),(280),(280),(280),(566),(566),(48),(566),(566),(566),(566),(566)),<br> ((280),(65535),(280),(280),(304),(296),(304),(296),(48),(48),(48),(48),(0),(54),(54),(65535))<br> <br><br>function SaveOldFunction(Proc: pointer; Old: pointer): longword; forward;<br>function GetProcAddressEx(Process: LongWord; lpModuleName, lpProcName: pchar): pointer; forward;<br>function MapLibrary(Process: LongWord; Dest, Src: pointer): TLibInfo; forward;<br><br>function SizeOfCode(Code: pointer): longword;<br>var<br> Opcode: word;<br> Modrm: byte;<br> Fixed, AddressOveride: boolean;<br> Last, OperandOveride, Flags, Rm, Size, Extend: longword;<br>begin<br> try<br> Last := longword(Code);<br> if Code <> nil then<br> begin<br> AddressOveride := False;<br> Fixed := False;<br> OperandOveride := 4;<br> Extend := 0;<br> repeat<br> Opcode := byte(Code^);<br> Code := pointer(longword(Code) + 1);<br> if Opcode = $66 then<br> begin<br> OperandOveride := 2;<br> end<br> else if Opcode = $67 then<br> begin<br> AddressOveride := True;<br> end<br> else<br> begin<br> if not ((Opcode and $E7) = $26) then<br> begin<br> if not (Opcode in [$64..$65]) then<br> begin<br> Fixed := True;<br> end;<br> end;<br> end;<br> until Fixed;<br> if Opcode = $0f then<br> begin<br> Opcode := byte(Code^);<br> Flags := Opcodes2[Opcode];<br> Opcode := Opcode + $0f00;<br> Code := pointer(longword(Code) + 1);<br> end<br> else<br> begin<br> Flags := Opcodes1[Opcode];<br> end;<br> if ((Flags and $0038) <> 0) then<br> begin<br> Modrm := byte(Code^);<br> Rm := Modrm and $7;<br> Code := pointer(longword(Code) + 1);<br> case (Modrm and $c0) of<br> $40: Size := 1;<br> $80:<br> begin<br> if AddressOveride then<br> begin<br> Size := 2;<br> end<br> else<br> Size := 4;<br> end;<br> else<br> begin<br> Size := 0;<br> end;<br> end;<br> if not (((Modrm and $c0) <> $c0) and AddressOveride) then<br> begin<br> if (Rm = 4) and ((Modrm and $c0) <> $c0) then<br> begin<br> Rm := byte(Code^) and $7;<br> end;<br> if ((Modrm and $c0 = 0) and (Rm = 5)) then<br> begin<br> Size := 4;<br> end;<br> Code := pointer(longword(Code) + Size);<br> end;<br> if ((Flags and $0038) = $0008) then<br> begin<br> case Opcode of<br> $f6: Extend := 0;<br> $f7: Extend := 1;<br> $d8: Extend := 2;<br> $d9: Extend := 3;<br> $da: Extend := 4;<br> $db: Extend := 5;<br> $dc: Extend := 6;<br> $dd: Extend := 7;<br> $de: Extend := 8;<br> $df: Extend := 9;<br> end;<br> if ((Modrm and $c0) <> $c0) then<br> begin<br> Flags := Opcodes3[Extend][(Modrm shr 3) and $7];<br> end<br> else<br> begin<br> Flags := Opcodes3[Extend][((Modrm shr 3) and $7) + 8];<br> end;<br> end;<br> end;<br> case (Flags and $0C00) of<br> $0400: Code := pointer(longword(Code) + 1);<br> $0800: Code := pointer(longword(Code) + 2);<br> $0C00: Code := pointer(longword(Code) + OperandOveride);<br> else<br> begin<br> case Opcode of<br> $9a, $ea: Code := pointer(longword(Code) + OperandOveride + 2);<br> $c8: Code := pointer(longword(Code) + 3);<br> $a0..$a3:<br> begin<br> if AddressOveride then<br> begin<br> Code := pointer(longword(Code) + 2)<br> end<br> else<br> begin<br> Code := pointer(longword(Code) + 4);<br> end;<br> end;<br> end;<br> end;<br> end;<br> end;<br> Result := longword(Code) - Last;<br> except<br> Result := 0;<br> end;<br>end;<br><br>function SizeOfProc(Proc: pointer): longword;<br>var<br> Length: longword;<br>begin<br> Result := 0;<br> repeat<br> Length := SizeOfCode(Proc);<br> Inc(Result, Length);<br> if ((Length = 1) and (byte(Proc^) = $C3)) then Break;<br> Proc := pointer(longword(Proc) + Length);<br> until Length = 0;<br>end;<br><br>function InjectString(Process: LongWord; Text: pchar): pchar;<br>var<br> BytesWritten: longword;<br>begin<br> Result := VirtualAllocEx(Process, nil, Length(Text) + 1, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);<br> WriteProcessMemory(Process, Result, Text, Length(Text) + 1, BytesWritten);<br>end;<br><br>function InjectMemory(Process: LongWord; Memory: pointer; Len: longword): pointer;<br>var<br> BytesWritten: longword;<br>begin<br> Result := VirtualAllocEx(Process, nil, Len, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);<br> WriteProcessMemory(Process, Result, Memory, Len, BytesWritten);<br>end;<br><br>function InjectThread(Process: longword; Thread: pointer; Info: pointer; InfoLen: longword; Results: boolean): THandle;<br>var<br> pThread, pInfo: pointer;<br> BytesRead, TID: longword;<br>begin<br> pInfo := InjectMemory(Process, Info, InfoLen);<br> pThread := InjectMemory(Process, Thread, SizeOfProc(Thread));<br> Result := CreateRemoteThread(Process, nil, 0, pThread, pInfo, 0, TID);<br> if Results then<br> begin<br> WaitForSingleObject(Result, INFINITE);<br> ReadProcessMemory(Process, pInfo, Info, InfoLen, BytesRead);<br> end;<br>end;<br><br>function InjectLibrary(Process: LongWord; ModulePath: string): boolean;<br>type<br> TInjectLibraryInfo = record<br> pLoadLibrary: pointer;<br> lpModuleName: pointer;<br> pSleep: pointer;<br> end;<br>var<br> InjectLibraryInfo: TInjectLibraryInfo;<br> Thread: THandle;<br><br> procedure InjectLibraryThread(lpParameter: pointer); stdcall;<br> var<br> InjectLibraryInfo: TInjectLibraryInfo;<br> begin<br> InjectLibraryInfo := TInjectLibraryInfo(lpParameter^);<br> asm<br> push InjectLibraryInfo.lpModuleName<br> call InjectLibraryInfo.pLoadLibrary<br> @noret:<br> mov eax, $FFFFFFFF<br> push eax<br> call InjectLibraryInfo.pSleep<br> jmp @noret<br> end;<br> end;<br><br>begin<br> Result := False;<br> InjectLibraryInfo.pSleep := GetProcAddress(GetModuleHandle('kernel32'), 'Sleep');<br> InjectLibraryInfo.pLoadLibrary := GetProcAddress(GetModuleHandle('kernel32'), 'LoadLibraryA');<br> InjectLibraryInfo.lpModuleName := InjectString(Process, pchar(ModulePath));<br> Thread := InjectThread(Process, @InjectLibraryThread, @InjectLibraryInfo, SizeOf(TInjectLibraryInfo), False);<br> if Thread = 0 then Exit;<br> CloseHandle(Thread);<br> Result := True;<br>end;<br><br>function InjectLibrary(Process: LongWord; Src: pointer): boolean;<br>type<br> TDllLoadInfo = record<br> Module: pointer;<br> EntryPoint: pointer;<br> end;<br>var<br> Lib: TLibInfo;<br> DllLoadInfo: TDllLoadInfo;<br> BytesWritten: longword;<br> ImageNtHeaders: PImageNtHeaders;<br> pModule: pointer;<br> Offset: longword;<br><br> procedure DllEntryPoint(lpParameter: pointer); stdcall;<br> var<br> LoadInfo: TDllLoadInfo;<br> begin<br> LoadInfo := TDllLoadInfo(lpParameter^);<br> asm<br> xor eax, eax<br> push eax<br> push DLL_PROCESS_ATTACH<br> push LoadInfo.Module<br> call LoadInfo.EntryPoint<br> end;<br> end;<br><br>begin<br> Result := False;<br> ImageNtHeaders := pointer(int64(cardinal(Src)) + PImageDosHeader(Src)._lfanew);<br> Offset := $10000000;<br> repeat<br> Inc(Offset, $10000);<br> pModule := VirtualAlloc(pointer(ImageNtHeaders.OptionalHeader.ImageBase + Offset), ImageNtHeaders.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);<br> if pModule <> nil then<br> begin<br> VirtualFree(pModule, 0, MEM_RELEASE);<br> pModule := VirtualAllocEx(Process, pointer(ImageNtHeaders.OptionalHeader.ImageBase + Offset), ImageNtHeaders.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);<br> end;<br> until ((pModule <> nil) or (Offset > $30000000));<br> Lib := MapLibrary(Process, pModule, Src);<br> if Lib.ImageBase = nil then Exit;<br> DllLoadInfo.Module := Lib.ImageBase;<br> DllLoadInfo.EntryPoint := Lib.DllProcAddress;<br> WriteProcessMemory(Process, pModule, Lib.ImageBase, Lib.ImageSize, BytesWritten);<br> if InjectThread(Process, @DllEntryPoint, @DllLoadInfo, SizeOf(TDllLoadInfo), False) <> 0 then Result := True<br>end;<br><br>function InjectExe(Process: LongWord; EntryPoint: pointer): boolean;<br>var<br> Module, NewModule: pointer;<br> Size, TID: longword;<br>begin<br> Result := False;<br> Module := pointer(GetModuleHandle(nil));<br> Size := PImageOptionalHeader(pointer(integer(Module) + PImageDosHeader(Module)._lfanew + SizeOf(longword) + SizeOf(TImageFileHeader))).SizeOfImage;<br> VirtualFreeEx(Process, Module, 0, MEM_RELEASE);<br> NewModule := InjectMemory(Process, Module, Size);<br> if CreateRemoteThread(Process, nil, 0, EntryPoint, NewModule, 0, TID) <> 0 then Result := True;<br>end;<br><br>function UninjectLibrary(Process: LongWord; ModulePath: string): boolean;<br>type<br> TUninjectLibraryInfo = record<br> pFreeLibrary: pointer;<br> pGetModuleHandle: pointer;<br> lpModuleName: pointer;<br> pExitThread: pointer;<br> end;<br>var<br> UninjectLibraryInfo: TUninjectLibraryInfo;<br> Thread: THandle;<br><br> procedure UninjectLibraryThread(lpParameter: pointer); stdcall;<br> var<br> UninjectLibraryInfo: TUninjectLibraryInfo;<br> begin<br> UninjectLibraryInfo := TUninjectLibraryInfo(lpParameter^);<br> asm<br> @1:<br> inc ecx<br> push UninjectLibraryInfo.lpModuleName<br> call UninjectLibraryInfo.pGetModuleHandle<br> cmp eax, 0<br> je @2<br> push eax<br> call UninjectLibraryInfo.pFreeLibrary<br> jmp @1<br> @2:<br> push eax<br> call UninjectLibraryInfo.pExitThread<br> end;<br> end;<br><br>begin<br> Result := False;<br> UninjectLibraryInfo.pGetModuleHandle := GetProcAddress(GetModuleHandle('kernel32'), 'GetModuleHandleA');<br> UninjectLibraryInfo.pFreeLibrary := GetProcAddress(GetModuleHandle('kernel32'), 'FreeLibrary');<br> UninjectLibraryInfo.pExitThread := GetProcAddress(GetModuleHandle('kernel32'), 'ExitThread');<br> UninjectLibraryInfo.lpModuleName := InjectString(Process, pchar(ModulePath));<br> Thread := InjectThread(Process, @UninjectLibraryThread, @UninjectLibraryInfo, SizeOf(TUninjectLibraryInfo), False);<br> if Thread = 0 then Exit;<br> CloseHandle(Thread);<br> Result := True;<br>end;<br><br>function CreateProcessEx(lpApplicationName: pchar; lpCommandLine: pchar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles: boolean; dwCreationFlags: longword; lpEnvironment: pointer; lpCurrentDirectory: pchar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation; ModulePath: string): boolean;<br>begin<br> Result := False;<br> if not CreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags or CREATE_SUSPENDED, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation) then Exit;<br> Result := InjectLibrary(lpProcessInformation.hProcess, ModulePath);<br> ResumeThread(lpProcessInformation.hThread);<br>end;<br><br>function CreateProcessEx(lpApplicationName: pchar; lpCommandLine: pchar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles: boolean; dwCreationFlags: longword; lpEnvironment: pointer; lpCurrentDirectory: pchar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation; Src: pointer): boolean;<br>begin<br> Result := False;<br> if not CreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags or CREATE_SUSPENDED, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation) then Exit;<br> Result := InjectLibrary(lpProcessInformation.hProcess, Src);<br> ResumeThread(lpProcessInformation.hThread);<br>end;<br><br>function HookCode(TargetModule, TargetProc: string; NewProc: pointer; var OldProc: pointer): boolean;<br>var<br> Address: longword;<br> OldProtect: longword;<br> OldFunction: pointer;<br> Proc: pointer;<br> hModule: longword;<br>begin<br> Result := False;<br> try<br> hModule := LoadLibrary(pchar(TargetModule));<br> Proc := GetProcAddress(hModule, pchar(TargetProc));<br> Address := longword(NewProc) - longword(Proc) - 5;<br> VirtualProtect(Proc, 5, PAGE_EXECUTE_READWRITE, OldProtect);<br> GetMem(OldFunction, 255);<br> longword(OldFunction^) := longword(Proc);<br> byte(pointer(longword(OldFunction) + 4)^) := SaveOldFunction(Proc, pointer(longword(OldFunction) + 5));<br> byte(pointer(Proc)^) := $e9;<br> longword(pointer(longword(Proc) + 1)^) := Address;<br> VirtualProtect(Proc, 5, OldProtect, OldProtect);<br> OldProc := pointer(longword(OldFunction) + 5);<br> FreeLibrary(hModule);<br> except<br> Exit;<br> end;<br> Result := True;<br>end;<br><br>function UnhookCode(OldProc: pointer): boolean;<br>var<br> OldProtect: longword;<br> Proc: pointer;<br> SaveSize: longword;<br>begin<br> Result := True;<br> try<br> Proc := pointer(longword(pointer(longword(OldProc) - 5)^));<br> SaveSize := byte(pointer(longword(OldProc) - 1)^);<br> VirtualProtect(Proc, 5, PAGE_EXECUTE_READWRITE, OldProtect);<br> CopyMemory(Proc, OldProc, SaveSize);<br> VirtualProtect(Proc, 5, OldProtect, OldProtect);<br> FreeMem(pointer(longword(OldProc) - 5));<br> except<br> Result := False;<br> end;<br>end;<br><br>function DeleteFileEx(FilePath: pchar): boolean;<br>type<br> TDeleteFileExInfo = record<br> pSleep: pointer;<br> lpModuleName: pointer;<br> pDeleteFile: pointer;<br> pExitThread: pointer;<br> end;<br>var<br> DeleteFileExInfo: TDeleteFileExInfo;<br> Thread: THandle;<br> Process: longword;<br> PID: longword;<br><br><br> procedure DeleteFileExThread(lpParameter: pointer); stdcall;<br> var<br> DeleteFileExInfo: TDeleteFileExInfo;<br> begin<br> DeleteFileExInfo := TDeleteFileExInfo(lpParameter^);<br> asm<br> @1:<br> push 1000<br> call DeleteFileExInfo.pSleep<br> push DeleteFileExInfo.lpModuleName<br> call DeleteFileExInfo.pDeleteFile<br> cmp eax, 0<br> je @1<br> push eax<br> call DeleteFileExInfo.pExitThread<br> end;<br> end;<br><br>begin<br> Result := False;<br> GetWindowThreadProcessID(FindWindow('Shell_TrayWnd', nil), @PID);<br> Process := OpenProcess(PROCESS_ALL_ACCESS, False, PID);<br> DeleteFileExInfo.pSleep := GetProcAddress(GetModuleHandle('kernel32'), 'Sleep');<br> DeleteFileExInfo.pDeleteFile := GetProcAddress(GetModuleHandle('kernel32'), 'DeleteFileA');<br> DeleteFileExInfo.pExitThread := GetProcAddress(GetModuleHandle('kernel32'), 'ExitThread');<br> DeleteFileExInfo.lpModuleName := InjectString(Process, FilePath);<br> Thread := InjectThread(Process, @DeleteFileExThread, @DeleteFileExInfo, SizeOf(TDeleteFileExInfo), False);<br> if Thread = 0 then Exit;<br> CloseHandle(Thread);<br> CloseHandle(Process);<br> Result := True;<br>end;<br><br>function DisableSFC: boolean;<br>var<br> Process, SFC, PID, Thread, ThreadID: longword;<br>begin<br> Result := False;<br> SFC := LoadLibrary('sfc.dll');<br> GetWindowThreadProcessID(FindWindow('NDDEAgnt', nil), @PID);<br> Process := OpenProcess(PROCESS_ALL_ACCESS, False, PID);<br> Thread := CreateRemoteThread(Process, nil, 0, GetProcAddress(SFC, pchar(2 and $ffff)), nil, 0, ThreadId);<br> if Thread = 0 then Exit;<br> CloseHandle(Thread);<br> CloseHandle(Process);<br> FreeLibrary(SFC);<br> Result := True;<br>end;<br><br>function SaveOldFunction(Proc: pointer; Old: pointer): longword;<br>var<br> SaveSize, Size: longword;<br> Next: pointer;<br>begin<br> SaveSize := 0;<br> Next := Proc;<br> while SaveSize < 5 do<br> begin<br> Size := SizeOfCode(Next);<br> Next := pointer(longword(Next) + Size);<br> Inc(SaveSize, Size);<br> end;<br> CopyMemory(Old, Proc, SaveSize);<br> byte(pointer(longword(Old) + SaveSize)^) := $e9;<br> longword(pointer(longword(Old) + SaveSize + 1)^) := longword(Next) - longword(Old) - SaveSize - 5;<br> Result := SaveSize;<br>end;<br><br>function GetProcAddressEx(Process: LongWord; lpModuleName, lpProcName: pchar): pointer;<br>type<br> TGetProcAddrExInfo = record<br> pExitThread: pointer;<br> pGetProcAddress: pointer;<br> pGetModuleHandle: pointer;<br> lpModuleName: pointer;<br> lpProcName: pointer;<br> end;<br>var<br> GetProcAddrExInfo: TGetProcAddrExInfo;<br> ExitCode: longword;<br> Thread: THandle;<br><br> procedure GetProcAddrExThread(lpParameter: pointer); stdcall;<br> var<br> GetProcAddrExInfo: TGetProcAddrExInfo;<br> begin<br> GetProcAddrExInfo := TGetProcAddrExInfo(lpParameter^);<br> asm<br> push GetProcAddrExInfo.lpModuleName<br> call GetProcAddrExInfo.pGetModuleHandle<br> push GetProcAddrExInfo.lpProcName<br> push eax<br> call GetProcAddrExInfo.pGetProcAddress<br> push eax<br> call GetProcAddrExInfo.pExitThread<br> end;<br> end;<br><br>begin<br> Result := nil;<br> GetProcAddrExInfo.pGetModuleHandle := GetProcAddress(GetModuleHandle('kernel32'), 'GetModuleHandleA');<br> GetProcAddrExInfo.pGetProcAddress := GetProcAddress(GetModuleHandle('kernel32'), 'GetProcAddress');<br> GetProcAddrExInfo.pExitThread := GetProcAddress(GetModuleHandle('kernel32'), 'ExitThread');<br> GetProcAddrExInfo.lpProcName := InjectString(Process, lpProcName);<br> GetProcAddrExInfo.lpModuleName := InjectString(Process, lpModuleName);<br> Thread := InjectThread(Process, @GetProcAddrExThread, @GetProcAddrExInfo, SizeOf(GetProcAddrExInfo), False);<br> if Thread <> 0 then<br> begin<br> WaitForSingleObject(Thread, INFINITE);<br> GetExitCodeThread(Thread, ExitCode);<br> Result := pointer(ExitCode);<br> end;<br>end;<br><br>function MapLibrary(Process: LongWord; Dest, Src: pointer): TLibInfo;<br>var<br> ImageBase: pointer;<br> ImageBaseDelta: integer;<br> ImageNtHeaders: PImageNtHeaders;<br> PSections: ^TSections;<br> SectionLoop: integer;<br> SectionBase: pointer;<br> VirtualSectionSize, RawSectionSize: cardinal;<br> OldProtect: cardinal;<br> NewLibInfo: TLibInfo;<br><br> function StrToInt(S: string): integer;<br> begin<br> Val(S, Result, Result);<br> end;<br><br> procedure Add(Strings: TStringArray; Text: string);<br> begin<br> SetLength(Strings, Length(Strings) + 1);<br> Strings[Length(Strings) - 1] := Text;<br> end;<br><br> function Find(Strings: array of string; Text: string; var Index: integer): boolean;<br> var<br> StringLoop: integer;<br> begin<br> Result := False;<br> for StringLoop := 0 to Length(Strings) - 1 do<br> begin<br> if lstrcmpi(pchar(Strings[StringLoop]), pchar(Text)) = 0 then<br> begin<br> Index := StringLoop;<br> Result := True;<br> end;<br> end;<br> end;<br><br> function GetSectionProtection(ImageScn: cardinal): cardinal;<br> begin<br> Result := 0;<br> if (ImageScn and IMAGE_SCN_MEM_NOT_CACHED) <> 0 then<br> begin<br> Result := Result or PAGE_NOCACHE;<br> end;<br> if (ImageScn and IMAGE_SCN_MEM_EXECUTE) <> 0 then<br> begin<br> if (ImageScn and IMAGE_SCN_MEM_READ)<> 0 then<br> begin<br> if (ImageScn and IMAGE_SCN_MEM_WRITE)<> 0 then<br> begin<br> Result := Result or PAGE_EXECUTE_READWRITE<br> end<br> else<br> begin<br> Result := Result or PAGE_EXECUTE_READ<br> end;<br> end<br> else if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then<br> begin<br> Result := Result or PAGE_EXECUTE_WRITECOPY<br> end<br> else<br> begin<br> Result := Result or PAGE_EXECUTE<br> end;<br> end<br> else if (ImageScn and IMAGE_SCN_MEM_READ)<> 0 then<br> begin<br> if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then<br> begin<br> Result := Result or PAGE_READWRITE<br> end<br> else<br> begin<br> Result := Result or PAGE_READONLY<br> end<br> end<br> else if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then<br> begin<br> Result := Result or PAGE_WRITECOPY<br> end<br> else<br> begin<br> Result := Result or PAGE_NOACCESS;<br> end;<br> end;<br><br> procedure ProcessRelocs(PRelocsImageBaseRelocation);<br> var<br> PReloc: PImageBaseRelocation;<br> RelocsSize: cardinal;<br> Reloc: PWord;<br> ModCount: cardinal;<br> RelocLoop: cardinal;<br> begin<br> PReloc := PRelocs;<br> RelocsSize := ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;<br> while cardinal(PReloc) - cardinal(PRelocs) < RelocsSize do<br> begin<br> ModCount := (PReloc.SizeOfBlock - Sizeof(PReloc^)) div 2;<br> Reloc := pointer(cardinal(PReloc) + sizeof(PReloc^));<br> for RelocLoop := 0 to ModCount - 1 do<br> begin<br> if Reloc^ and $f000 <> 0 then Inc(plongword(cardinal(ImageBase) + PReloc.VirtualAddress + (Reloc^ and $0fff))^, ImageBaseDelta);<br> Inc(Reloc);<br> end;<br> PReloc := pointer(Reloc);<br> end;<br> end;<br><br> procedure ProcessImports(PImports: PImageImportDescriptor);<br> var<br> PImport: PImageImportDescriptor;<br> Import: plongword;<br> PImportedName: pchar;<br> ProcAddress: pointer;<br> PLibName: pchar;<br> ImportLoop: integer;<br><br> function IsImportByOrdinal(ImportDescriptor: longword): boolean;<br> begin<br> Result := (ImportDescriptor and IMAGE_ORDINAL_FLAG32) <> 0;<br> end;<br><br> begin<br> PImport := PImports;<br> while PImport.Name <> 0 do<br> begin<br> PLibName := pchar(cardinal(PImport.Name) + cardinal(ImageBase));<br> if not Find(NewLibInfo.LibsUsed, PLibName, ImportLoop) then<br> begin<br> InjectLibrary(Process, string(PLibName));<br> Add(NewLibInfo.LibsUsed, PLibName);<br> end;<br> if PImport.TimeDateStamp = 0 then<br> begin<br> Import := plongword(pImport.FirstThunk + cardinal(ImageBase))<br> end<br> else<br> begin<br> Import := plongword(pImport.OriginalFirstThunk + cardinal(ImageBase));<br> end;<br> while Import^ <> 0 do<br> begin<br> if IsImportByOrdinal(Import^) then<br> begin<br> ProcAddress := GetProcAddressEx(Process, PLibName, pchar(Import^ and $ffff))<br> end<br> else<br> begin<br> PImportedName := pchar(Import^ + cardinal(ImageBase) + IMPORTED_NAME_OFFSET);<br> ProcAddress := GetProcAddressEx(Process, PLibName, PImportedName);<br> end;<br> Ppointer(Import)^ := ProcAddress;<br> Inc(Import);<br> end;<br> Inc(PImport);<br> end;<br> end;<br><br>begin<br> ImageNtHeaders := pointer(int64(cardinal(Src)) + PImageDosHeader(Src)._lfanew);<br> ImageBase := VirtualAlloc(Dest, ImageNtHeaders.OptionalHeader.SizeOfImage, MEM_RESERVE, PAGE_NOACCESS);<br> ImageBaseDelta := cardinal(ImageBase) - ImageNtHeaders.OptionalHeader.ImageBase;<br> SectionBase := VirtualAlloc(ImageBase, ImageNtHeaders.OptionalHeader.SizeOfHeaders, MEM_COMMIT, PAGE_READWRITE);<br> Move(Src^, SectionBase^, ImageNtHeaders.OptionalHeader.SizeOfHeaders);<br> VirtualProtect(SectionBase, ImageNtHeaders.OptionalHeader.SizeOfHeaders, PAGE_READONLY, OldProtect);<br> PSections := pointer(pchar(@(ImageNtHeaders.OptionalHeader)) + ImageNtHeaders.FileHeader.SizeOfOptionalHeader);<br> for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do<br> begin<br> VirtualSectionSize := PSections[SectionLoop].Misc.VirtualSize;<br> RawSectionSize := PSections[SectionLoop].SizeOfRawData;<br> if VirtualSectionSize < RawSectionSize then<br> begin<br> VirtualSectionSize := VirtualSectionSize xor RawSectionSize;<br> RawSectionSize := VirtualSectionSize xor RawSectionSize;<br> VirtualSectionSize := VirtualSectionSize xor RawSectionSize;<br> end;<br> SectionBase := VirtualAlloc(PSections[SectionLoop].VirtualAddress + pchar(ImageBase), VirtualSectionSize, MEM_COMMIT, PAGE_READWRITE);<br> FillChar(SectionBase^, VirtualSectionSize, 0);<br> Move((pchar(src) + PSections[SectionLoop].pointerToRawData)^, SectionBase^, RawSectionSize);<br> end;<br> NewLibInfo.DllProc := TDllEntryProc(ImageNtHeaders.OptionalHeader.AddressOfEntryPoint + cardinal(ImageBase));<br> NewLibInfo.DllProcAddress := pointer(ImageNtHeaders.OptionalHeader.AddressOfEntryPoint + cardinal(ImageBase));<br> NewLibInfo.ImageBase := ImageBase;<br> NewLibInfo.ImageSize := ImageNtHeaders.OptionalHeader.SizeOfImage;<br> SetLength(NewLibInfo.LibsUsed, 0);<br> if ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress <> 0 then ProcessRelocs(pointer(ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + cardinal(ImageBase)));<br> if ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress <> 0 then ProcessImports(pointer(ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + cardinal(ImageBase)));<br> for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do<br> begin<br> VirtualProtect(PSections[SectionLoop].VirtualAddress + pchar(ImageBase), PSections[SectionLoop].Misc.VirtualSize, GetSectionProtection(PSections[SectionLoop].Characteristics), OldProtect);<br> end;<br> Result := NewLibInfo;<br>end;<br>end.<br><br><br><br><br>program MsgBox;<br><br>uses<br> Windows,<br> afxCodeHook;<br><br>var<br> MessageBoxANextHook: function(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;<br><br>function MessageBoxAHookProc(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;<br>begin<br> Result := MessageBoxANextHook(0, '', 'bye', 0);<br>end;<br><br>begin<br> //test the target API<br> MessageBox(0, '', 'hi', 0);<br><br> //hook the API<br> HookCode('user32', 'MessageBoxA', @MessageBoxAHookProc, @MessageBoxANextHook);<br><br> //the message should be changed<br> MessageBox(0, '', 'hi', 0);<br><br> //unhoook the API<br> UnhookCode(@MessageBoxANextHook);<br><br> //test the target API<br> MessageBox(0, '', 'hi', 0);<br>end.
{<br> Delphi Hooking Library by Aphex<br> http://www.iamaphex.cjb.net/<br> unremote@knology.net<br>}<br>unit afxCodeHook;<br><br>{$IMAGEBASE $13140000}<br><br>interface<br><br>uses<br> Windows;<br><br>function SizeOfCode(Code: pointer): dword;<br>function SizeOfProc(Proc: pointer): dword;<br><br>function InjectString(Process: LongWord; Text: pchar): pchar;<br>function InjectMemory(Process: LongWord; Memory: pointer; Len: dword): pointer;<br>function InjectThread(Process: dword; Thread: pointer; Info: pointer; InfoLen: dword; Results: boolean): THandle;<br>function InjectLibrary(Process: LongWord; ModulePath: string): boolean; overload;<br>function InjectLibrary(Process: LongWord; Src: pointer): boolean; overload;<br>function InjectExe(Process: LongWord; EntryPoint: pointer): boolean;<br>function UninjectLibrary(Process: LongWord; ModulePath: string): boolean;<br><br>function CreateProcessEx(lpApplicationName: pchar; lpCommandLine: pchar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles: boolean; dwCreationFlags: longword; lpEnvironment: pointer; lpCurrentDirectory: pchar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation; ModulePath: string): boolean; overload;<br>function CreateProcessEx(lpApplicationName: pchar; lpCommandLine: pchar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles: boolean; dwCreationFlags: longword; lpEnvironment: pointer; lpCurrentDirectory: pchar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation; Src: pointer): boolean; overload;<br><br>function HookCode(TargetModule, TargetProc: string; NewProc: pointer; var OldProc: pointer): boolean;<br>function UnhookCode(OldProc: pointer): boolean;<br><br>function DeleteFileEx(FilePath: pchar): boolean;<br>function DisableSFC: boolean;<br><br>implementation<br><br>type<br> TModuleList = array of cardinal;<br><br> PImageImportDescriptor = ^TImageImportDescriptor;<br> TImageImportDescriptor = packed record<br> OriginalFirstThunk: longword;<br> TimeDateStamp: longword;<br> ForwarderChain: longword;<br> Name: longword;<br> FirstThunk: longword;<br> end;<br><br> PImageBaseRelocation = ^TImageBaseRelocation;<br> TImageBaseRelocation = packed record<br> VirtualAddress: cardinal;<br> SizeOfBlock: cardinal;<br> end;<br><br> TDllEntryProc = function(hinstDLL: HMODULE; dwReason: longword; lpvReserved: pointer): boolean; stdcall;<br><br> TStringArray = array of string;<br><br> TLibInfo = record<br> ImageBase: pointer;<br> ImageSize: longint;<br> DllProc: TDllEntryProc;<br> DllProcAddress: pointer;<br> LibsUsed: TStringArray;<br> end;<br><br> PLibInfo = ^TLibInfo;<br> Ppointer = ^pointer;<br><br> TSections = array [0..0] of TImageSectionHeader;<br><br>const<br> IMPORTED_NAME_OFFSET = $00000002;<br> IMAGE_ORDINAL_FLAG32 = $80000000;<br> IMAGE_ORDINAL_MASK32 = $0000FFFF;<br><br> Opcodes1: array [0..255] of word =<br> (<br> (16913),(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),<br> (17124),(8209),(8420),(33793),(35906),(0),(0),(16913),(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),<br> (17124),(8209),(8420),(33793),(35906),(0),(32768),(16913),(17124),(8209),(8420),(33793),(35906),(0),(32768),(16913),<br> (17124),(8209),(8420),(33793),(35906),(0),(32768),(529),(740),(17),(228),(1025),(3138),(0),(32768),(24645),<br> (24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(69),<br> (69),(69),(69),(69),(69),(69),(69),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(0),<br> (32768),(228),(16922),(0),(0),(0),(0),(3072),(11492),(1024),(9444),(0),(0),(0),(0),(5120),<br> (5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(1296),<br> (3488),(1296),(1440),(529),(740),(41489),(41700),(16913),(17124),(8209),(8420),(17123),(8420),(227),(416),(0),<br> (57414),(57414),(57414),(57414),(57414),(57414),(57414),(32768),(0),(0),(0),(0),(0),(0),(32768),(33025),<br> (33090),(769),(834),(0),(0),(0),(0),(1025),(3138),(0),(0),(32768),(32768),(0),(0),(25604),<br> (25604),(25604),(25604),(25604),(25604),(25604),(25604),(27717),(27717),(27717),(27717),(27717),(27717),(27717),(27717),(17680),<br> (17824),(2048),(0),(8420),(8420),(17680),(19872),(0),(0),(2048),(0),(0),(1024),(0),(0),(16656),<br> (16800),(16656),(16800),(33792),(33792),(0),(32768),(8),(8),(8),(8),(8),(8),(8),(8),(5120),<br> (5120),(5120),(5120),(33793),(33858),(1537),(1602),(7168),(7168),(0),(5120),(32775),(32839),(519),(583),(0),<br> (0),(0),(0),(0),(0),(8),(8),(0),(0),(0),(0),(0),(0),(16656),(416)<br> <br><br> Opcodes2: array [0..255] of word =<br> (<br> (280),(288),(8420),(8420),(65535),(0),(0),(0),(0),(0),(65535),(65535),(65535),(272),(0),(1325),(63),<br> (575),(63),(575),(63),(63),(63),(575),(272),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(16419),<br> (16419),(547),(547),(65535),(65535),(65535),(65535),(63),(575),(47),(575),(61),(61),(63),(63),(0),<br> (32768),(32768),(32768),(0),(0),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(8420),<br> (8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(16935),<br> (63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(237),<br> (237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(101),(237),(1261),<br> (1192),(1192),(1192),(237),(237),(237),(0),(65535),(65535),(65535),(65535),(65535),(65535),(613),(749),(7168),<br> (7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(16656),<br> (16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(0),<br> (0),(32768),(740),(18404),(17380),(49681),(49892),(0),(0),(0),(17124),(18404),(17380),(32),(8420),(49681),<br> (49892),(8420),(17124),(8420),(8932),(8532),(8476),(65535),(65535),(1440),(17124),(8420),(8420),(8532),(8476),(41489),<br> (41700),(1087),(548),(1125),(9388),(1087),(33064),(24581),(24581),(24581),(24581),(24581),(24581),(24581),(24581),(65535),<br> (237),(237),(237),(237),(237),(749),(8364),(237),(237),(237),(237),(237),(237),(237),(237),(237),<br> (237),(237),(237),(237),(237),(63),(749),(237),(237),(237),(237),(237),(237),(237),(237),(65535),<br> (237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(0)<br> <br><br> Opcodes3: array [0..9] of array [0..15] of word =<br> (<br> ((1296),(65535),(16656),(16656),(33040),(33040),(33040),(33040),(1296),(65535),(16656),(16656),(33040),(33040),(33040),(33040)),<br> ((3488),(65535),(16800),(16800),(33184),(33184),(33184),(33184),(3488),(65535),(16800),(16800),(33184),(33184),(33184),(33184)),<br> ((288),(288),(288),(288),(288),(288),(288),(288),(54),(54),(48),(48),(54),(54),(54),(54)),<br> ((288),(65535),(288),(288),(272),(280),(272),(280),(48),(48),(0),(48),(0),(0),(0),(0)),<br> ((288),(288),(288),(288),(288),(288),(288),(288),(54),(54),(54),(54),(65535),(0),(65535),(65535)),<br> ((288),(65535),(288),(288),(65535),(304),(65535),(304),(54),(54),(54),(54),(0),(54),(54),(0)),<br> ((296),(296),(296),(296),(296),(296),(296),(296),(566),(566),(48),(48),(566),(566),(566),(566)),<br> ((296),(65535),(296),(296),(272),(65535),(272),(280),(48),(48),(48),(48),(48),(48),(65535),(65535)),<br> ((280),(280),(280),(280),(280),(280),(280),(280),(566),(566),(48),(566),(566),(566),(566),(566)),<br> ((280),(65535),(280),(280),(304),(296),(304),(296),(48),(48),(48),(48),(0),(54),(54),(65535))<br> <br><br>function SaveOldFunction(Proc: pointer; Old: pointer): longword; forward;<br>function GetProcAddressEx(Process: LongWord; lpModuleName, lpProcName: pchar): pointer; forward;<br>function MapLibrary(Process: LongWord; Dest, Src: pointer): TLibInfo; forward;<br><br>function SizeOfCode(Code: pointer): longword;<br>var<br> Opcode: word;<br> Modrm: byte;<br> Fixed, AddressOveride: boolean;<br> Last, OperandOveride, Flags, Rm, Size, Extend: longword;<br>begin<br> try<br> Last := longword(Code);<br> if Code <> nil then<br> begin<br> AddressOveride := False;<br> Fixed := False;<br> OperandOveride := 4;<br> Extend := 0;<br> repeat<br> Opcode := byte(Code^);<br> Code := pointer(longword(Code) + 1);<br> if Opcode = $66 then<br> begin<br> OperandOveride := 2;<br> end<br> else if Opcode = $67 then<br> begin<br> AddressOveride := True;<br> end<br> else<br> begin<br> if not ((Opcode and $E7) = $26) then<br> begin<br> if not (Opcode in [$64..$65]) then<br> begin<br> Fixed := True;<br> end;<br> end;<br> end;<br> until Fixed;<br> if Opcode = $0f then<br> begin<br> Opcode := byte(Code^);<br> Flags := Opcodes2[Opcode];<br> Opcode := Opcode + $0f00;<br> Code := pointer(longword(Code) + 1);<br> end<br> else<br> begin<br> Flags := Opcodes1[Opcode];<br> end;<br> if ((Flags and $0038) <> 0) then<br> begin<br> Modrm := byte(Code^);<br> Rm := Modrm and $7;<br> Code := pointer(longword(Code) + 1);<br> case (Modrm and $c0) of<br> $40: Size := 1;<br> $80:<br> begin<br> if AddressOveride then<br> begin<br> Size := 2;<br> end<br> else<br> Size := 4;<br> end;<br> else<br> begin<br> Size := 0;<br> end;<br> end;<br> if not (((Modrm and $c0) <> $c0) and AddressOveride) then<br> begin<br> if (Rm = 4) and ((Modrm and $c0) <> $c0) then<br> begin<br> Rm := byte(Code^) and $7;<br> end;<br> if ((Modrm and $c0 = 0) and (Rm = 5)) then<br> begin<br> Size := 4;<br> end;<br> Code := pointer(longword(Code) + Size);<br> end;<br> if ((Flags and $0038) = $0008) then<br> begin<br> case Opcode of<br> $f6: Extend := 0;<br> $f7: Extend := 1;<br> $d8: Extend := 2;<br> $d9: Extend := 3;<br> $da: Extend := 4;<br> $db: Extend := 5;<br> $dc: Extend := 6;<br> $dd: Extend := 7;<br> $de: Extend := 8;<br> $df: Extend := 9;<br> end;<br> if ((Modrm and $c0) <> $c0) then<br> begin<br> Flags := Opcodes3[Extend][(Modrm shr 3) and $7];<br> end<br> else<br> begin<br> Flags := Opcodes3[Extend][((Modrm shr 3) and $7) + 8];<br> end;<br> end;<br> end;<br> case (Flags and $0C00) of<br> $0400: Code := pointer(longword(Code) + 1);<br> $0800: Code := pointer(longword(Code) + 2);<br> $0C00: Code := pointer(longword(Code) + OperandOveride);<br> else<br> begin<br> case Opcode of<br> $9a, $ea: Code := pointer(longword(Code) + OperandOveride + 2);<br> $c8: Code := pointer(longword(Code) + 3);<br> $a0..$a3:<br> begin<br> if AddressOveride then<br> begin<br> Code := pointer(longword(Code) + 2)<br> end<br> else<br> begin<br> Code := pointer(longword(Code) + 4);<br> end;<br> end;<br> end;<br> end;<br> end;<br> end;<br> Result := longword(Code) - Last;<br> except<br> Result := 0;<br> end;<br>end;<br><br>function SizeOfProc(Proc: pointer): longword;<br>var<br> Length: longword;<br>begin<br> Result := 0;<br> repeat<br> Length := SizeOfCode(Proc);<br> Inc(Result, Length);<br> if ((Length = 1) and (byte(Proc^) = $C3)) then Break;<br> Proc := pointer(longword(Proc) + Length);<br> until Length = 0;<br>end;<br><br>function InjectString(Process: LongWord; Text: pchar): pchar;<br>var<br> BytesWritten: longword;<br>begin<br> Result := VirtualAllocEx(Process, nil, Length(Text) + 1, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);<br> WriteProcessMemory(Process, Result, Text, Length(Text) + 1, BytesWritten);<br>end;<br><br>function InjectMemory(Process: LongWord; Memory: pointer; Len: longword): pointer;<br>var<br> BytesWritten: longword;<br>begin<br> Result := VirtualAllocEx(Process, nil, Len, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);<br> WriteProcessMemory(Process, Result, Memory, Len, BytesWritten);<br>end;<br><br>function InjectThread(Process: longword; Thread: pointer; Info: pointer; InfoLen: longword; Results: boolean): THandle;<br>var<br> pThread, pInfo: pointer;<br> BytesRead, TID: longword;<br>begin<br> pInfo := InjectMemory(Process, Info, InfoLen);<br> pThread := InjectMemory(Process, Thread, SizeOfProc(Thread));<br> Result := CreateRemoteThread(Process, nil, 0, pThread, pInfo, 0, TID);<br> if Results then<br> begin<br> WaitForSingleObject(Result, INFINITE);<br> ReadProcessMemory(Process, pInfo, Info, InfoLen, BytesRead);<br> end;<br>end;<br><br>function InjectLibrary(Process: LongWord; ModulePath: string): boolean;<br>type<br> TInjectLibraryInfo = record<br> pLoadLibrary: pointer;<br> lpModuleName: pointer;<br> pSleep: pointer;<br> end;<br>var<br> InjectLibraryInfo: TInjectLibraryInfo;<br> Thread: THandle;<br><br> procedure InjectLibraryThread(lpParameter: pointer); stdcall;<br> var<br> InjectLibraryInfo: TInjectLibraryInfo;<br> begin<br> InjectLibraryInfo := TInjectLibraryInfo(lpParameter^);<br> asm<br> push InjectLibraryInfo.lpModuleName<br> call InjectLibraryInfo.pLoadLibrary<br> @noret:<br> mov eax, $FFFFFFFF<br> push eax<br> call InjectLibraryInfo.pSleep<br> jmp @noret<br> end;<br> end;<br><br>begin<br> Result := False;<br> InjectLibraryInfo.pSleep := GetProcAddress(GetModuleHandle('kernel32'), 'Sleep');<br> InjectLibraryInfo.pLoadLibrary := GetProcAddress(GetModuleHandle('kernel32'), 'LoadLibraryA');<br> InjectLibraryInfo.lpModuleName := InjectString(Process, pchar(ModulePath));<br> Thread := InjectThread(Process, @InjectLibraryThread, @InjectLibraryInfo, SizeOf(TInjectLibraryInfo), False);<br> if Thread = 0 then Exit;<br> CloseHandle(Thread);<br> Result := True;<br>end;<br><br>function InjectLibrary(Process: LongWord; Src: pointer): boolean;<br>type<br> TDllLoadInfo = record<br> Module: pointer;<br> EntryPoint: pointer;<br> end;<br>var<br> Lib: TLibInfo;<br> DllLoadInfo: TDllLoadInfo;<br> BytesWritten: longword;<br> ImageNtHeaders: PImageNtHeaders;<br> pModule: pointer;<br> Offset: longword;<br><br> procedure DllEntryPoint(lpParameter: pointer); stdcall;<br> var<br> LoadInfo: TDllLoadInfo;<br> begin<br> LoadInfo := TDllLoadInfo(lpParameter^);<br> asm<br> xor eax, eax<br> push eax<br> push DLL_PROCESS_ATTACH<br> push LoadInfo.Module<br> call LoadInfo.EntryPoint<br> end;<br> end;<br><br>begin<br> Result := False;<br> ImageNtHeaders := pointer(int64(cardinal(Src)) + PImageDosHeader(Src)._lfanew);<br> Offset := $10000000;<br> repeat<br> Inc(Offset, $10000);<br> pModule := VirtualAlloc(pointer(ImageNtHeaders.OptionalHeader.ImageBase + Offset), ImageNtHeaders.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);<br> if pModule <> nil then<br> begin<br> VirtualFree(pModule, 0, MEM_RELEASE);<br> pModule := VirtualAllocEx(Process, pointer(ImageNtHeaders.OptionalHeader.ImageBase + Offset), ImageNtHeaders.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);<br> end;<br> until ((pModule <> nil) or (Offset > $30000000));<br> Lib := MapLibrary(Process, pModule, Src);<br> if Lib.ImageBase = nil then Exit;<br> DllLoadInfo.Module := Lib.ImageBase;<br> DllLoadInfo.EntryPoint := Lib.DllProcAddress;<br> WriteProcessMemory(Process, pModule, Lib.ImageBase, Lib.ImageSize, BytesWritten);<br> if InjectThread(Process, @DllEntryPoint, @DllLoadInfo, SizeOf(TDllLoadInfo), False) <> 0 then Result := True<br>end;<br><br>function InjectExe(Process: LongWord; EntryPoint: pointer): boolean;<br>var<br> Module, NewModule: pointer;<br> Size, TID: longword;<br>begin<br> Result := False;<br> Module := pointer(GetModuleHandle(nil));<br> Size := PImageOptionalHeader(pointer(integer(Module) + PImageDosHeader(Module)._lfanew + SizeOf(longword) + SizeOf(TImageFileHeader))).SizeOfImage;<br> VirtualFreeEx(Process, Module, 0, MEM_RELEASE);<br> NewModule := InjectMemory(Process, Module, Size);<br> if CreateRemoteThread(Process, nil, 0, EntryPoint, NewModule, 0, TID) <> 0 then Result := True;<br>end;<br><br>function UninjectLibrary(Process: LongWord; ModulePath: string): boolean;<br>type<br> TUninjectLibraryInfo = record<br> pFreeLibrary: pointer;<br> pGetModuleHandle: pointer;<br> lpModuleName: pointer;<br> pExitThread: pointer;<br> end;<br>var<br> UninjectLibraryInfo: TUninjectLibraryInfo;<br> Thread: THandle;<br><br> procedure UninjectLibraryThread(lpParameter: pointer); stdcall;<br> var<br> UninjectLibraryInfo: TUninjectLibraryInfo;<br> begin<br> UninjectLibraryInfo := TUninjectLibraryInfo(lpParameter^);<br> asm<br> @1:<br> inc ecx<br> push UninjectLibraryInfo.lpModuleName<br> call UninjectLibraryInfo.pGetModuleHandle<br> cmp eax, 0<br> je @2<br> push eax<br> call UninjectLibraryInfo.pFreeLibrary<br> jmp @1<br> @2:<br> push eax<br> call UninjectLibraryInfo.pExitThread<br> end;<br> end;<br><br>begin<br> Result := False;<br> UninjectLibraryInfo.pGetModuleHandle := GetProcAddress(GetModuleHandle('kernel32'), 'GetModuleHandleA');<br> UninjectLibraryInfo.pFreeLibrary := GetProcAddress(GetModuleHandle('kernel32'), 'FreeLibrary');<br> UninjectLibraryInfo.pExitThread := GetProcAddress(GetModuleHandle('kernel32'), 'ExitThread');<br> UninjectLibraryInfo.lpModuleName := InjectString(Process, pchar(ModulePath));<br> Thread := InjectThread(Process, @UninjectLibraryThread, @UninjectLibraryInfo, SizeOf(TUninjectLibraryInfo), False);<br> if Thread = 0 then Exit;<br> CloseHandle(Thread);<br> Result := True;<br>end;<br><br>function CreateProcessEx(lpApplicationName: pchar; lpCommandLine: pchar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles: boolean; dwCreationFlags: longword; lpEnvironment: pointer; lpCurrentDirectory: pchar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation; ModulePath: string): boolean;<br>begin<br> Result := False;<br> if not CreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags or CREATE_SUSPENDED, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation) then Exit;<br> Result := InjectLibrary(lpProcessInformation.hProcess, ModulePath);<br> ResumeThread(lpProcessInformation.hThread);<br>end;<br><br>function CreateProcessEx(lpApplicationName: pchar; lpCommandLine: pchar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles: boolean; dwCreationFlags: longword; lpEnvironment: pointer; lpCurrentDirectory: pchar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation; Src: pointer): boolean;<br>begin<br> Result := False;<br> if not CreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags or CREATE_SUSPENDED, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation) then Exit;<br> Result := InjectLibrary(lpProcessInformation.hProcess, Src);<br> ResumeThread(lpProcessInformation.hThread);<br>end;<br><br>function HookCode(TargetModule, TargetProc: string; NewProc: pointer; var OldProc: pointer): boolean;<br>var<br> Address: longword;<br> OldProtect: longword;<br> OldFunction: pointer;<br> Proc: pointer;<br> hModule: longword;<br>begin<br> Result := False;<br> try<br> hModule := LoadLibrary(pchar(TargetModule));<br> Proc := GetProcAddress(hModule, pchar(TargetProc));<br> Address := longword(NewProc) - longword(Proc) - 5;<br> VirtualProtect(Proc, 5, PAGE_EXECUTE_READWRITE, OldProtect);<br> GetMem(OldFunction, 255);<br> longword(OldFunction^) := longword(Proc);<br> byte(pointer(longword(OldFunction) + 4)^) := SaveOldFunction(Proc, pointer(longword(OldFunction) + 5));<br> byte(pointer(Proc)^) := $e9;<br> longword(pointer(longword(Proc) + 1)^) := Address;<br> VirtualProtect(Proc, 5, OldProtect, OldProtect);<br> OldProc := pointer(longword(OldFunction) + 5);<br> FreeLibrary(hModule);<br> except<br> Exit;<br> end;<br> Result := True;<br>end;<br><br>function UnhookCode(OldProc: pointer): boolean;<br>var<br> OldProtect: longword;<br> Proc: pointer;<br> SaveSize: longword;<br>begin<br> Result := True;<br> try<br> Proc := pointer(longword(pointer(longword(OldProc) - 5)^));<br> SaveSize := byte(pointer(longword(OldProc) - 1)^);<br> VirtualProtect(Proc, 5, PAGE_EXECUTE_READWRITE, OldProtect);<br> CopyMemory(Proc, OldProc, SaveSize);<br> VirtualProtect(Proc, 5, OldProtect, OldProtect);<br> FreeMem(pointer(longword(OldProc) - 5));<br> except<br> Result := False;<br> end;<br>end;<br><br>function DeleteFileEx(FilePath: pchar): boolean;<br>type<br> TDeleteFileExInfo = record<br> pSleep: pointer;<br> lpModuleName: pointer;<br> pDeleteFile: pointer;<br> pExitThread: pointer;<br> end;<br>var<br> DeleteFileExInfo: TDeleteFileExInfo;<br> Thread: THandle;<br> Process: longword;<br> PID: longword;<br><br><br> procedure DeleteFileExThread(lpParameter: pointer); stdcall;<br> var<br> DeleteFileExInfo: TDeleteFileExInfo;<br> begin<br> DeleteFileExInfo := TDeleteFileExInfo(lpParameter^);<br> asm<br> @1:<br> push 1000<br> call DeleteFileExInfo.pSleep<br> push DeleteFileExInfo.lpModuleName<br> call DeleteFileExInfo.pDeleteFile<br> cmp eax, 0<br> je @1<br> push eax<br> call DeleteFileExInfo.pExitThread<br> end;<br> end;<br><br>begin<br> Result := False;<br> GetWindowThreadProcessID(FindWindow('Shell_TrayWnd', nil), @PID);<br> Process := OpenProcess(PROCESS_ALL_ACCESS, False, PID);<br> DeleteFileExInfo.pSleep := GetProcAddress(GetModuleHandle('kernel32'), 'Sleep');<br> DeleteFileExInfo.pDeleteFile := GetProcAddress(GetModuleHandle('kernel32'), 'DeleteFileA');<br> DeleteFileExInfo.pExitThread := GetProcAddress(GetModuleHandle('kernel32'), 'ExitThread');<br> DeleteFileExInfo.lpModuleName := InjectString(Process, FilePath);<br> Thread := InjectThread(Process, @DeleteFileExThread, @DeleteFileExInfo, SizeOf(TDeleteFileExInfo), False);<br> if Thread = 0 then Exit;<br> CloseHandle(Thread);<br> CloseHandle(Process);<br> Result := True;<br>end;<br><br>function DisableSFC: boolean;<br>var<br> Process, SFC, PID, Thread, ThreadID: longword;<br>begin<br> Result := False;<br> SFC := LoadLibrary('sfc.dll');<br> GetWindowThreadProcessID(FindWindow('NDDEAgnt', nil), @PID);<br> Process := OpenProcess(PROCESS_ALL_ACCESS, False, PID);<br> Thread := CreateRemoteThread(Process, nil, 0, GetProcAddress(SFC, pchar(2 and $ffff)), nil, 0, ThreadId);<br> if Thread = 0 then Exit;<br> CloseHandle(Thread);<br> CloseHandle(Process);<br> FreeLibrary(SFC);<br> Result := True;<br>end;<br><br>function SaveOldFunction(Proc: pointer; Old: pointer): longword;<br>var<br> SaveSize, Size: longword;<br> Next: pointer;<br>begin<br> SaveSize := 0;<br> Next := Proc;<br> while SaveSize < 5 do<br> begin<br> Size := SizeOfCode(Next);<br> Next := pointer(longword(Next) + Size);<br> Inc(SaveSize, Size);<br> end;<br> CopyMemory(Old, Proc, SaveSize);<br> byte(pointer(longword(Old) + SaveSize)^) := $e9;<br> longword(pointer(longword(Old) + SaveSize + 1)^) := longword(Next) - longword(Old) - SaveSize - 5;<br> Result := SaveSize;<br>end;<br><br>function GetProcAddressEx(Process: LongWord; lpModuleName, lpProcName: pchar): pointer;<br>type<br> TGetProcAddrExInfo = record<br> pExitThread: pointer;<br> pGetProcAddress: pointer;<br> pGetModuleHandle: pointer;<br> lpModuleName: pointer;<br> lpProcName: pointer;<br> end;<br>var<br> GetProcAddrExInfo: TGetProcAddrExInfo;<br> ExitCode: longword;<br> Thread: THandle;<br><br> procedure GetProcAddrExThread(lpParameter: pointer); stdcall;<br> var<br> GetProcAddrExInfo: TGetProcAddrExInfo;<br> begin<br> GetProcAddrExInfo := TGetProcAddrExInfo(lpParameter^);<br> asm<br> push GetProcAddrExInfo.lpModuleName<br> call GetProcAddrExInfo.pGetModuleHandle<br> push GetProcAddrExInfo.lpProcName<br> push eax<br> call GetProcAddrExInfo.pGetProcAddress<br> push eax<br> call GetProcAddrExInfo.pExitThread<br> end;<br> end;<br><br>begin<br> Result := nil;<br> GetProcAddrExInfo.pGetModuleHandle := GetProcAddress(GetModuleHandle('kernel32'), 'GetModuleHandleA');<br> GetProcAddrExInfo.pGetProcAddress := GetProcAddress(GetModuleHandle('kernel32'), 'GetProcAddress');<br> GetProcAddrExInfo.pExitThread := GetProcAddress(GetModuleHandle('kernel32'), 'ExitThread');<br> GetProcAddrExInfo.lpProcName := InjectString(Process, lpProcName);<br> GetProcAddrExInfo.lpModuleName := InjectString(Process, lpModuleName);<br> Thread := InjectThread(Process, @GetProcAddrExThread, @GetProcAddrExInfo, SizeOf(GetProcAddrExInfo), False);<br> if Thread <> 0 then<br> begin<br> WaitForSingleObject(Thread, INFINITE);<br> GetExitCodeThread(Thread, ExitCode);<br> Result := pointer(ExitCode);<br> end;<br>end;<br><br>function MapLibrary(Process: LongWord; Dest, Src: pointer): TLibInfo;<br>var<br> ImageBase: pointer;<br> ImageBaseDelta: integer;<br> ImageNtHeaders: PImageNtHeaders;<br> PSections: ^TSections;<br> SectionLoop: integer;<br> SectionBase: pointer;<br> VirtualSectionSize, RawSectionSize: cardinal;<br> OldProtect: cardinal;<br> NewLibInfo: TLibInfo;<br><br> function StrToInt(S: string): integer;<br> begin<br> Val(S, Result, Result);<br> end;<br><br> procedure Add(Strings: TStringArray; Text: string);<br> begin<br> SetLength(Strings, Length(Strings) + 1);<br> Strings[Length(Strings) - 1] := Text;<br> end;<br><br> function Find(Strings: array of string; Text: string; var Index: integer): boolean;<br> var<br> StringLoop: integer;<br> begin<br> Result := False;<br> for StringLoop := 0 to Length(Strings) - 1 do<br> begin<br> if lstrcmpi(pchar(Strings[StringLoop]), pchar(Text)) = 0 then<br> begin<br> Index := StringLoop;<br> Result := True;<br> end;<br> end;<br> end;<br><br> function GetSectionProtection(ImageScn: cardinal): cardinal;<br> begin<br> Result := 0;<br> if (ImageScn and IMAGE_SCN_MEM_NOT_CACHED) <> 0 then<br> begin<br> Result := Result or PAGE_NOCACHE;<br> end;<br> if (ImageScn and IMAGE_SCN_MEM_EXECUTE) <> 0 then<br> begin<br> if (ImageScn and IMAGE_SCN_MEM_READ)<> 0 then<br> begin<br> if (ImageScn and IMAGE_SCN_MEM_WRITE)<> 0 then<br> begin<br> Result := Result or PAGE_EXECUTE_READWRITE<br> end<br> else<br> begin<br> Result := Result or PAGE_EXECUTE_READ<br> end;<br> end<br> else if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then<br> begin<br> Result := Result or PAGE_EXECUTE_WRITECOPY<br> end<br> else<br> begin<br> Result := Result or PAGE_EXECUTE<br> end;<br> end<br> else if (ImageScn and IMAGE_SCN_MEM_READ)<> 0 then<br> begin<br> if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then<br> begin<br> Result := Result or PAGE_READWRITE<br> end<br> else<br> begin<br> Result := Result or PAGE_READONLY<br> end<br> end<br> else if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then<br> begin<br> Result := Result or PAGE_WRITECOPY<br> end<br> else<br> begin<br> Result := Result or PAGE_NOACCESS;<br> end;<br> end;<br><br> procedure ProcessRelocs(PRelocsImageBaseRelocation);<br> var<br> PReloc: PImageBaseRelocation;<br> RelocsSize: cardinal;<br> Reloc: PWord;<br> ModCount: cardinal;<br> RelocLoop: cardinal;<br> begin<br> PReloc := PRelocs;<br> RelocsSize := ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;<br> while cardinal(PReloc) - cardinal(PRelocs) < RelocsSize do<br> begin<br> ModCount := (PReloc.SizeOfBlock - Sizeof(PReloc^)) div 2;<br> Reloc := pointer(cardinal(PReloc) + sizeof(PReloc^));<br> for RelocLoop := 0 to ModCount - 1 do<br> begin<br> if Reloc^ and $f000 <> 0 then Inc(plongword(cardinal(ImageBase) + PReloc.VirtualAddress + (Reloc^ and $0fff))^, ImageBaseDelta);<br> Inc(Reloc);<br> end;<br> PReloc := pointer(Reloc);<br> end;<br> end;<br><br> procedure ProcessImports(PImports: PImageImportDescriptor);<br> var<br> PImport: PImageImportDescriptor;<br> Import: plongword;<br> PImportedName: pchar;<br> ProcAddress: pointer;<br> PLibName: pchar;<br> ImportLoop: integer;<br><br> function IsImportByOrdinal(ImportDescriptor: longword): boolean;<br> begin<br> Result := (ImportDescriptor and IMAGE_ORDINAL_FLAG32) <> 0;<br> end;<br><br> begin<br> PImport := PImports;<br> while PImport.Name <> 0 do<br> begin<br> PLibName := pchar(cardinal(PImport.Name) + cardinal(ImageBase));<br> if not Find(NewLibInfo.LibsUsed, PLibName, ImportLoop) then<br> begin<br> InjectLibrary(Process, string(PLibName));<br> Add(NewLibInfo.LibsUsed, PLibName);<br> end;<br> if PImport.TimeDateStamp = 0 then<br> begin<br> Import := plongword(pImport.FirstThunk + cardinal(ImageBase))<br> end<br> else<br> begin<br> Import := plongword(pImport.OriginalFirstThunk + cardinal(ImageBase));<br> end;<br> while Import^ <> 0 do<br> begin<br> if IsImportByOrdinal(Import^) then<br> begin<br> ProcAddress := GetProcAddressEx(Process, PLibName, pchar(Import^ and $ffff))<br> end<br> else<br> begin<br> PImportedName := pchar(Import^ + cardinal(ImageBase) + IMPORTED_NAME_OFFSET);<br> ProcAddress := GetProcAddressEx(Process, PLibName, PImportedName);<br> end;<br> Ppointer(Import)^ := ProcAddress;<br> Inc(Import);<br> end;<br> Inc(PImport);<br> end;<br> end;<br><br>begin<br> ImageNtHeaders := pointer(int64(cardinal(Src)) + PImageDosHeader(Src)._lfanew);<br> ImageBase := VirtualAlloc(Dest, ImageNtHeaders.OptionalHeader.SizeOfImage, MEM_RESERVE, PAGE_NOACCESS);<br> ImageBaseDelta := cardinal(ImageBase) - ImageNtHeaders.OptionalHeader.ImageBase;<br> SectionBase := VirtualAlloc(ImageBase, ImageNtHeaders.OptionalHeader.SizeOfHeaders, MEM_COMMIT, PAGE_READWRITE);<br> Move(Src^, SectionBase^, ImageNtHeaders.OptionalHeader.SizeOfHeaders);<br> VirtualProtect(SectionBase, ImageNtHeaders.OptionalHeader.SizeOfHeaders, PAGE_READONLY, OldProtect);<br> PSections := pointer(pchar(@(ImageNtHeaders.OptionalHeader)) + ImageNtHeaders.FileHeader.SizeOfOptionalHeader);<br> for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do<br> begin<br> VirtualSectionSize := PSections[SectionLoop].Misc.VirtualSize;<br> RawSectionSize := PSections[SectionLoop].SizeOfRawData;<br> if VirtualSectionSize < RawSectionSize then<br> begin<br> VirtualSectionSize := VirtualSectionSize xor RawSectionSize;<br> RawSectionSize := VirtualSectionSize xor RawSectionSize;<br> VirtualSectionSize := VirtualSectionSize xor RawSectionSize;<br> end;<br> SectionBase := VirtualAlloc(PSections[SectionLoop].VirtualAddress + pchar(ImageBase), VirtualSectionSize, MEM_COMMIT, PAGE_READWRITE);<br> FillChar(SectionBase^, VirtualSectionSize, 0);<br> Move((pchar(src) + PSections[SectionLoop].pointerToRawData)^, SectionBase^, RawSectionSize);<br> end;<br> NewLibInfo.DllProc := TDllEntryProc(ImageNtHeaders.OptionalHeader.AddressOfEntryPoint + cardinal(ImageBase));<br> NewLibInfo.DllProcAddress := pointer(ImageNtHeaders.OptionalHeader.AddressOfEntryPoint + cardinal(ImageBase));<br> NewLibInfo.ImageBase := ImageBase;<br> NewLibInfo.ImageSize := ImageNtHeaders.OptionalHeader.SizeOfImage;<br> SetLength(NewLibInfo.LibsUsed, 0);<br> if ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress <> 0 then ProcessRelocs(pointer(ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + cardinal(ImageBase)));<br> if ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress <> 0 then ProcessImports(pointer(ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + cardinal(ImageBase)));<br> for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do<br> begin<br> VirtualProtect(PSections[SectionLoop].VirtualAddress + pchar(ImageBase), PSections[SectionLoop].Misc.VirtualSize, GetSectionProtection(PSections[SectionLoop].Characteristics), OldProtect);<br> end;<br> Result := NewLibInfo;<br>end;<br>end.<br><br><br><br><br>program MsgBox;<br><br>uses<br> Windows,<br> afxCodeHook;<br><br>var<br> MessageBoxANextHook: function(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;<br><br>function MessageBoxAHookProc(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;<br>begin<br> Result := MessageBoxANextHook(0, '', 'bye', 0);<br>end;<br><br>begin<br> //test the target API<br> MessageBox(0, '', 'hi', 0);<br><br> //hook the API<br> HookCode('user32', 'MessageBoxA', @MessageBoxAHookProc, @MessageBoxANextHook);<br><br> //the message should be changed<br> MessageBox(0, '', 'hi', 0);<br><br> //unhoook the API<br> UnhookCode(@MessageBoxANextHook);<br><br> //test the target API<br> MessageBox(0, '', 'hi', 0);<br>end.
白 白河愁 Unregistered / Unconfirmed GUEST, unregistred user! 2006-10-03 #77 刚去旅游回来<br><br>to errorcode: 谢谢,明天试试看<br>to kk:<br><br>//请白河愁 解释一下这段汇编好吗?<br>procedure ThreadPro;<br>var<br>VarList: TThreadProVarList;<br>begin<br>asm<br>mov eax, $FFFFFFFF {到$FFFFFFFF的偏移是7} <br>mov VarList.SendMessage, eax // 这里是把$FFFFFFFF 赋值给VarList.SendMessage这个变量吗? 为什么要赋这个值啊? <br><br>//这里是先把 SendMessage 运行时实际的值写到 EAX 去,至于 $FFFFFFFF 随便写都没关系,是让编译器吗汇编代码编译出来,<br>//然后运行的时候写上真正的地址, 第二句自然就是把真正地址储存到数组里去了。<br><br>mov eax, $FFFFFFFF {这个$FFFFFFFF是在上一个偏移位置加8}<br>//上两个语句的总长度应该就是 8 吧.<br><br>mov VarList.WndHandle, eax<br>mov eax, $FFFFFFFF<br>mov VarList.ExitProcess, eax<br>mov eax, $FFFFFFFF<br>mov VarList.ExitThread, eax<br><br>//这些跟最上是一样的。<br><br>push 0 //lParam = 0<br>push 0 //Wparam = 0<br>push 4245 {4245就是自定义的WM_HOOKED} <br>push VarList.WndHandle //窗口句柄<br>call VarList.SendMessage //调用发送消息过程<br>push 0 //提供给ExitThread的参数为0 , <br>call VarList.ExitThread <br>end;<br>end;<br>//这句<br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+7), @SendPro, SizeOf(DWORD), WriteCount);<br>//下面不就是对ThreadPro VarList.SendMessage的变量写入了发送消息涵数的地址吗?为什么要开始mov eax, $FFFFFFFF {到$FFFFFFFF的偏移是7} <br>//见上面解释<br><br>mov VarList.SendMessage, eax // 这里是把$FFFFFFFF 赋值给VarList.SendMessage这个变量吗? 为什么要赋这个值啊? 搞不懂?? <br>TmpHandle := Self.Handle;<br>//这个是写入窗口句柄<br>//见上面解释<br><br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+15), @TmpHandle, SizeOf(DWORD), WriteCount);<br>//这个是写入ExitProcess<br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+23), @ExitPro, SizeOf(DWORD), WriteCount);<br>//这个是写入ExitThread<br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+31), @ExitTPro, SizeOf(DWORD), WriteCount);
刚去旅游回来<br><br>to errorcode: 谢谢,明天试试看<br>to kk:<br><br>//请白河愁 解释一下这段汇编好吗?<br>procedure ThreadPro;<br>var<br>VarList: TThreadProVarList;<br>begin<br>asm<br>mov eax, $FFFFFFFF {到$FFFFFFFF的偏移是7} <br>mov VarList.SendMessage, eax // 这里是把$FFFFFFFF 赋值给VarList.SendMessage这个变量吗? 为什么要赋这个值啊? <br><br>//这里是先把 SendMessage 运行时实际的值写到 EAX 去,至于 $FFFFFFFF 随便写都没关系,是让编译器吗汇编代码编译出来,<br>//然后运行的时候写上真正的地址, 第二句自然就是把真正地址储存到数组里去了。<br><br>mov eax, $FFFFFFFF {这个$FFFFFFFF是在上一个偏移位置加8}<br>//上两个语句的总长度应该就是 8 吧.<br><br>mov VarList.WndHandle, eax<br>mov eax, $FFFFFFFF<br>mov VarList.ExitProcess, eax<br>mov eax, $FFFFFFFF<br>mov VarList.ExitThread, eax<br><br>//这些跟最上是一样的。<br><br>push 0 //lParam = 0<br>push 0 //Wparam = 0<br>push 4245 {4245就是自定义的WM_HOOKED} <br>push VarList.WndHandle //窗口句柄<br>call VarList.SendMessage //调用发送消息过程<br>push 0 //提供给ExitThread的参数为0 , <br>call VarList.ExitThread <br>end;<br>end;<br>//这句<br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+7), @SendPro, SizeOf(DWORD), WriteCount);<br>//下面不就是对ThreadPro VarList.SendMessage的变量写入了发送消息涵数的地址吗?为什么要开始mov eax, $FFFFFFFF {到$FFFFFFFF的偏移是7} <br>//见上面解释<br><br>mov VarList.SendMessage, eax // 这里是把$FFFFFFFF 赋值给VarList.SendMessage这个变量吗? 为什么要赋这个值啊? 搞不懂?? <br>TmpHandle := Self.Handle;<br>//这个是写入窗口句柄<br>//见上面解释<br><br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+15), @TmpHandle, SizeOf(DWORD), WriteCount);<br>//这个是写入ExitProcess<br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+23), @ExitPro, SizeOf(DWORD), WriteCount);<br>//这个是写入ExitThread<br>WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+31), @ExitTPro, SizeOf(DWORD), WriteCount);
白 白河愁 Unregistered / Unconfirmed GUEST, unregistred user! 2006-10-03 #78 to leun:<br>这段代码一个解释也没有,粗略看过一下应该是可以用的,<br>不过似乎要自己启动的程序才能Hook,<br>而且要改成通用程序估计很有难度...<br>老实说 Hook 并不需要这么麻烦的.....
to leun:<br>这段代码一个解释也没有,粗略看过一下应该是可以用的,<br>不过似乎要自己启动的程序才能Hook,<br>而且要改成通用程序估计很有难度...<br>老实说 Hook 并不需要这么麻烦的.....
Q QSmile Unregistered / Unconfirmed GUEST, unregistred user! 2006-10-03 #79 mark 一下。不知楼主能不能做成一个DLL。给我们也用用。
白 白河愁 Unregistered / Unconfirmed GUEST, unregistred user! 2006-10-03 #80 尽量做吧,实在不行就只能 OCX 了.......回掉函数老是说不匹配....