afxCodeHook.pas
上传用户:hndmjx
上传日期:2014-09-16
资源大小:3369k
文件大小:31k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {
  2.   Delphi Hooking Library by Aphex
  3.   http://www.iamaphex.cjb.net/
  4.   unremote@knology.net
  5. }
  6. unit afxCodeHook;
  7. {$IMAGEBASE $13140000}
  8. interface
  9. uses
  10.   Windows;
  11. function SizeOfCode(Code: pointer): dword;
  12. function SizeOfProc(Proc: pointer): dword;
  13. function InjectString(Process: LongWord; Text: pchar): pchar;
  14. function InjectMemory(Process: LongWord; Memory: pointer; Len: dword): pointer;
  15. function InjectThread(Process: dword; Thread: pointer; Info: pointer; InfoLen: dword; Results: boolean): THandle;
  16. function InjectLibrary(Process: LongWord; ModulePath: string): boolean; overload;
  17. function InjectLibrary(Process: LongWord; Src: pointer): boolean; overload;
  18. function InjectExe(Process: LongWord; EntryPoint: pointer): boolean;
  19. function UninjectLibrary(Process: LongWord; ModulePath: string): boolean;
  20. 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;
  21. 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;
  22. function HookCode(TargetModule, TargetProc: string; NewProc: pointer; var OldProc: pointer): boolean;
  23. function UnhookCode(OldProc: pointer): boolean;
  24. function DeleteFileEx(FilePath: pchar): boolean;
  25. function DisableSFC: boolean;
  26. implementation
  27. type
  28.   TModuleList = array of cardinal;
  29.   PImageImportDescriptor = ^TImageImportDescriptor;
  30.   TImageImportDescriptor = packed record
  31.     OriginalFirstThunk: longword;
  32.     TimeDateStamp: longword;
  33.     ForwarderChain: longword;
  34.     Name: longword;
  35.     FirstThunk: longword;
  36.   end;
  37.   PImageBaseRelocation = ^TImageBaseRelocation;
  38.   TImageBaseRelocation = packed record
  39.     VirtualAddress: cardinal;
  40.     SizeOfBlock: cardinal;
  41.   end;
  42.   TDllEntryProc = function(hinstDLL: HMODULE; dwReason: longword; lpvReserved: pointer): boolean; stdcall;
  43.   TStringArray = array of string;
  44.   TLibInfo = record
  45.     ImageBase: pointer;
  46.     ImageSize: longint;
  47.     DllProc: TDllEntryProc;
  48.     DllProcAddress: pointer;
  49.     LibsUsed: TStringArray;
  50.   end;
  51.   PLibInfo = ^TLibInfo;
  52.   Ppointer = ^pointer;
  53.   TSections = array [0..0] of TImageSectionHeader;
  54. const
  55.   IMPORTED_NAME_OFFSET = $00000002;
  56.   IMAGE_ORDINAL_FLAG32 = $80000000;
  57.   IMAGE_ORDINAL_MASK32 = $0000FFFF;
  58.   Opcodes1: array [0..255] of word =
  59.   (
  60.     (16913),(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),
  61.     (17124),(8209),(8420),(33793),(35906),(0),(0),(16913),(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),
  62.     (17124),(8209),(8420),(33793),(35906),(0),(32768),(16913),(17124),(8209),(8420),(33793),(35906),(0),(32768),(16913),
  63.     (17124),(8209),(8420),(33793),(35906),(0),(32768),(529),(740),(17),(228),(1025),(3138),(0),(32768),(24645),
  64.     (24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(69),
  65.     (69),(69),(69),(69),(69),(69),(69),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(0),
  66.     (32768),(228),(16922),(0),(0),(0),(0),(3072),(11492),(1024),(9444),(0),(0),(0),(0),(5120),
  67.     (5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(1296),
  68.     (3488),(1296),(1440),(529),(740),(41489),(41700),(16913),(17124),(8209),(8420),(17123),(8420),(227),(416),(0),
  69.     (57414),(57414),(57414),(57414),(57414),(57414),(57414),(32768),(0),(0),(0),(0),(0),(0),(32768),(33025),
  70.     (33090),(769),(834),(0),(0),(0),(0),(1025),(3138),(0),(0),(32768),(32768),(0),(0),(25604),
  71.     (25604),(25604),(25604),(25604),(25604),(25604),(25604),(27717),(27717),(27717),(27717),(27717),(27717),(27717),(27717),(17680),
  72.     (17824),(2048),(0),(8420),(8420),(17680),(19872),(0),(0),(2048),(0),(0),(1024),(0),(0),(16656),
  73.     (16800),(16656),(16800),(33792),(33792),(0),(32768),(8),(8),(8),(8),(8),(8),(8),(8),(5120),
  74.     (5120),(5120),(5120),(33793),(33858),(1537),(1602),(7168),(7168),(0),(5120),(32775),(32839),(519),(583),(0),
  75.     (0),(0),(0),(0),(0),(8),(8),(0),(0),(0),(0),(0),(0),(16656),(416)
  76.   );
  77.   Opcodes2: array [0..255] of word =
  78.   (
  79.     (280),(288),(8420),(8420),(65535),(0),(0),(0),(0),(0),(65535),(65535),(65535),(272),(0),(1325),(63),
  80.     (575),(63),(575),(63),(63),(63),(575),(272),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(16419),
  81.     (16419),(547),(547),(65535),(65535),(65535),(65535),(63),(575),(47),(575),(61),(61),(63),(63),(0),
  82.     (32768),(32768),(32768),(0),(0),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(8420),
  83.     (8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(16935),
  84.     (63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(237),
  85.     (237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(101),(237),(1261),
  86.     (1192),(1192),(1192),(237),(237),(237),(0),(65535),(65535),(65535),(65535),(65535),(65535),(613),(749),(7168),
  87.     (7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(16656),
  88.     (16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(0),
  89.     (0),(32768),(740),(18404),(17380),(49681),(49892),(0),(0),(0),(17124),(18404),(17380),(32),(8420),(49681),
  90.     (49892),(8420),(17124),(8420),(8932),(8532),(8476),(65535),(65535),(1440),(17124),(8420),(8420),(8532),(8476),(41489),
  91.     (41700),(1087),(548),(1125),(9388),(1087),(33064),(24581),(24581),(24581),(24581),(24581),(24581),(24581),(24581),(65535),
  92.     (237),(237),(237),(237),(237),(749),(8364),(237),(237),(237),(237),(237),(237),(237),(237),(237),
  93.     (237),(237),(237),(237),(237),(63),(749),(237),(237),(237),(237),(237),(237),(237),(237),(65535),
  94.     (237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(0)
  95.   );
  96.   Opcodes3: array [0..9] of array [0..15] of word =
  97.   (
  98.     ((1296),(65535),(16656),(16656),(33040),(33040),(33040),(33040),(1296),(65535),(16656),(16656),(33040),(33040),(33040),(33040)),
  99.     ((3488),(65535),(16800),(16800),(33184),(33184),(33184),(33184),(3488),(65535),(16800),(16800),(33184),(33184),(33184),(33184)),
  100.     ((288),(288),(288),(288),(288),(288),(288),(288),(54),(54),(48),(48),(54),(54),(54),(54)),
  101.     ((288),(65535),(288),(288),(272),(280),(272),(280),(48),(48),(0),(48),(0),(0),(0),(0)),
  102.     ((288),(288),(288),(288),(288),(288),(288),(288),(54),(54),(54),(54),(65535),(0),(65535),(65535)),
  103.     ((288),(65535),(288),(288),(65535),(304),(65535),(304),(54),(54),(54),(54),(0),(54),(54),(0)),
  104.     ((296),(296),(296),(296),(296),(296),(296),(296),(566),(566),(48),(48),(566),(566),(566),(566)),
  105.     ((296),(65535),(296),(296),(272),(65535),(272),(280),(48),(48),(48),(48),(48),(48),(65535),(65535)),
  106.     ((280),(280),(280),(280),(280),(280),(280),(280),(566),(566),(48),(566),(566),(566),(566),(566)),
  107.     ((280),(65535),(280),(280),(304),(296),(304),(296),(48),(48),(48),(48),(0),(54),(54),(65535))
  108.   );
  109. function SaveOldFunction(Proc: pointer; Old: pointer): longword; forward;
  110. function GetProcAddressEx(Process: LongWord; lpModuleName, lpProcName: pchar): pointer; forward;
  111. function MapLibrary(Process: LongWord; Dest, Src: pointer): TLibInfo; forward;
  112. function SizeOfCode(Code: pointer): longword;
  113. var
  114.   Opcode: word;
  115.   Modrm: byte;
  116.   Fixed, AddressOveride: boolean;
  117.   Last, OperandOveride, Flags, Rm, Size, Extend: longword;
  118. begin
  119.   try
  120.     Last := longword(Code);
  121.     if Code <> nil then
  122.     begin
  123.       AddressOveride := False;
  124.       Fixed := False;
  125.       OperandOveride := 4;
  126.       Extend := 0;
  127.       repeat
  128.         Opcode := byte(Code^);
  129.         Code := pointer(longword(Code) + 1);
  130.         if Opcode = $66 then
  131.         begin
  132.           OperandOveride := 2;
  133.         end
  134.         else if Opcode = $67 then
  135.         begin
  136.           AddressOveride := True;
  137.         end
  138.         else
  139.         begin
  140.           if not ((Opcode and $E7) = $26) then
  141.           begin
  142.             if not (Opcode in [$64..$65]) then
  143.             begin
  144.               Fixed := True;
  145.             end;
  146.           end;
  147.         end;
  148.       until Fixed;
  149.       if Opcode = $0f then
  150.       begin
  151.         Opcode := byte(Code^);
  152.         Flags := Opcodes2[Opcode];
  153.         Opcode := Opcode + $0f00;
  154.         Code := pointer(longword(Code) + 1);
  155.       end
  156.       else
  157.       begin
  158.         Flags := Opcodes1[Opcode];
  159.       end;
  160.       if ((Flags and $0038) <> 0) then
  161.       begin
  162.         Modrm := byte(Code^);
  163.         Rm := Modrm and $7;
  164.         Code := pointer(longword(Code) + 1);
  165.         case (Modrm and $c0) of
  166.           $40: Size := 1;
  167.           $80:
  168.             begin
  169.               if AddressOveride then
  170.               begin
  171.                 Size := 2;
  172.               end
  173.               else
  174.                 Size := 4;
  175.               end;
  176.           else
  177.           begin
  178.             Size := 0;
  179.           end;
  180.         end;
  181.         if not (((Modrm and $c0) <> $c0) and AddressOveride) then
  182.         begin
  183.           if (Rm = 4) and ((Modrm and $c0) <> $c0) then
  184.           begin
  185.             Rm := byte(Code^) and $7;
  186.           end;
  187.           if ((Modrm and $c0 = 0) and (Rm = 5)) then
  188.           begin
  189.             Size := 4;
  190.           end;
  191.           Code := pointer(longword(Code) + Size);
  192.         end;
  193.         if ((Flags and $0038) = $0008) then
  194.         begin
  195.           case Opcode of
  196.             $f6: Extend := 0;
  197.             $f7: Extend := 1;
  198.             $d8: Extend := 2;
  199.             $d9: Extend := 3;
  200.             $da: Extend := 4;
  201.             $db: Extend := 5;
  202.             $dc: Extend := 6;
  203.             $dd: Extend := 7;
  204.             $de: Extend := 8;
  205.             $df: Extend := 9;
  206.           end;
  207.           if ((Modrm and $c0) <> $c0) then
  208.           begin
  209.             Flags := Opcodes3[Extend][(Modrm shr 3) and $7];
  210.           end
  211.           else
  212.           begin
  213.             Flags := Opcodes3[Extend][((Modrm shr 3) and $7) + 8];
  214.           end;
  215.         end;
  216.       end;
  217.       case (Flags and $0C00) of
  218.         $0400: Code := pointer(longword(Code) + 1);
  219.         $0800: Code := pointer(longword(Code) + 2);
  220.         $0C00: Code := pointer(longword(Code) + OperandOveride);
  221.         else
  222.         begin
  223.           case Opcode of
  224.             $9a, $ea: Code := pointer(longword(Code) + OperandOveride + 2);
  225.             $c8: Code := pointer(longword(Code) + 3);
  226.             $a0..$a3:
  227.               begin
  228.                 if AddressOveride then
  229.                 begin
  230.                   Code := pointer(longword(Code) + 2)
  231.                 end
  232.                 else
  233.                 begin
  234.                   Code := pointer(longword(Code) + 4);
  235.                 end;
  236.               end;
  237.           end;
  238.         end;
  239.       end;
  240.     end;
  241.     Result := longword(Code) - Last;
  242.   except
  243.     Result := 0;
  244.   end;
  245. end;
  246. function SizeOfProc(Proc: pointer): longword;
  247. var
  248.   Length: longword;
  249. begin
  250.   Result := 0;
  251.   repeat
  252.     Length := SizeOfCode(Proc);
  253.     Inc(Result, Length);
  254.     if ((Length = 1) and (byte(Proc^) = $C3)) then Break;
  255.     Proc := pointer(longword(Proc) + Length);
  256.   until Length = 0;
  257. end;
  258. function InjectString(Process: LongWord; Text: pchar): pchar;
  259. var
  260.   BytesWritten: longword;
  261. begin
  262.   Result := VirtualAllocEx(Process, nil, Length(Text) + 1, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  263.   WriteProcessMemory(Process, Result, Text, Length(Text) + 1, BytesWritten);
  264. end;
  265. function InjectMemory(Process: LongWord; Memory: pointer; Len: longword): pointer;
  266. var
  267.   BytesWritten: longword;
  268. begin
  269.   Result := VirtualAllocEx(Process, nil, Len, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  270.   WriteProcessMemory(Process, Result, Memory, Len, BytesWritten);
  271. end;
  272. function InjectThread(Process: longword; Thread: pointer; Info: pointer; InfoLen: longword; Results: boolean): THandle;
  273. var
  274.   pThread, pInfo: pointer;
  275.   BytesRead, TID: longword;
  276. begin
  277.   pInfo := InjectMemory(Process, Info, InfoLen);
  278.   pThread := InjectMemory(Process, Thread, SizeOfProc(Thread));
  279.   Result := CreateRemoteThread(Process, nil, 0, pThread, pInfo, 0, TID);
  280.   if Results then
  281.   begin
  282.     WaitForSingleObject(Result, INFINITE);
  283.     ReadProcessMemory(Process, pInfo, Info, InfoLen, BytesRead);
  284.   end;
  285. end;
  286. function InjectLibrary(Process: LongWord; ModulePath: string): boolean;
  287. type
  288.   TInjectLibraryInfo = record
  289.     pLoadLibrary: pointer;
  290.     lpModuleName: pointer;
  291.     pSleep: pointer;
  292.   end;
  293. var
  294.   InjectLibraryInfo: TInjectLibraryInfo;
  295.   Thread: THandle;
  296.   procedure InjectLibraryThread(lpParameter: pointer); stdcall;
  297.   var
  298.     InjectLibraryInfo: TInjectLibraryInfo;
  299.   begin
  300.     InjectLibraryInfo := TInjectLibraryInfo(lpParameter^);
  301.     asm
  302.       push InjectLibraryInfo.lpModuleName
  303.       call InjectLibraryInfo.pLoadLibrary
  304.       @noret:
  305.         mov eax, $FFFFFFFF
  306.         push eax
  307.         call InjectLibraryInfo.pSleep
  308.       jmp @noret
  309.     end;
  310.   end;
  311. begin
  312.   Result := False;
  313.   InjectLibraryInfo.pSleep := GetProcAddress(GetModuleHandle('kernel32'), 'Sleep');
  314.   InjectLibraryInfo.pLoadLibrary := GetProcAddress(GetModuleHandle('kernel32'), 'LoadLibraryA');
  315.   InjectLibraryInfo.lpModuleName := InjectString(Process, pchar(ModulePath));
  316.   Thread := InjectThread(Process, @InjectLibraryThread, @InjectLibraryInfo, SizeOf(TInjectLibraryInfo), False);
  317.   if Thread = 0 then Exit;
  318.   CloseHandle(Thread);
  319.   Result := True;
  320. end;
  321. function InjectLibrary(Process: LongWord; Src: pointer): boolean;
  322. type
  323.   TDllLoadInfo = record
  324.     Module: pointer;
  325.     EntryPoint: pointer;
  326.   end;
  327. var
  328.   Lib: TLibInfo;
  329.   DllLoadInfo: TDllLoadInfo;
  330.   BytesWritten: longword;
  331.   ImageNtHeaders: PImageNtHeaders;
  332.   pModule: pointer;
  333.   Offset: longword;
  334.   procedure DllEntryPoint(lpParameter: pointer); stdcall;
  335.   var
  336.     LoadInfo: TDllLoadInfo;
  337.   begin
  338.     LoadInfo := TDllLoadInfo(lpParameter^);
  339.     asm
  340.       xor eax, eax
  341.       push eax
  342.       push DLL_PROCESS_ATTACH
  343.       push LoadInfo.Module
  344.       call LoadInfo.EntryPoint
  345.     end;
  346.   end;
  347. begin
  348.   Result := False;
  349.   ImageNtHeaders := pointer(int64(cardinal(Src)) + PImageDosHeader(Src)._lfanew);
  350.   Offset := $10000000;
  351.   repeat
  352.     Inc(Offset, $10000);
  353.     pModule := VirtualAlloc(pointer(ImageNtHeaders.OptionalHeader.ImageBase + Offset), ImageNtHeaders.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  354.     if pModule <> nil then
  355.     begin
  356.       VirtualFree(pModule, 0, MEM_RELEASE);
  357.       pModule := VirtualAllocEx(Process, pointer(ImageNtHeaders.OptionalHeader.ImageBase + Offset), ImageNtHeaders.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  358.     end;
  359.   until ((pModule <> nil) or (Offset > $30000000));
  360.   Lib := MapLibrary(Process, pModule, Src);
  361.   if Lib.ImageBase = nil then Exit;
  362.   DllLoadInfo.Module := Lib.ImageBase;
  363.   DllLoadInfo.EntryPoint := Lib.DllProcAddress;
  364.   WriteProcessMemory(Process, pModule, Lib.ImageBase, Lib.ImageSize, BytesWritten);
  365.   if InjectThread(Process, @DllEntryPoint, @DllLoadInfo, SizeOf(TDllLoadInfo), False) <> 0 then Result := True
  366. end;
  367. function InjectExe(Process: LongWord; EntryPoint: pointer): boolean;
  368. var
  369.   Module, NewModule: pointer;
  370.   Size, TID: longword;
  371. begin
  372.   Result := False;
  373.   Module := pointer(GetModuleHandle(nil));
  374.   Size := PImageOptionalHeader(pointer(integer(Module) + PImageDosHeader(Module)._lfanew + SizeOf(longword) + SizeOf(TImageFileHeader))).SizeOfImage;
  375.   VirtualFreeEx(Process, Module, 0, MEM_RELEASE);
  376.   NewModule := InjectMemory(Process, Module, Size);
  377.   if CreateRemoteThread(Process, nil, 0, EntryPoint, NewModule, 0, TID) <> 0 then Result := True;
  378. end;
  379. function UninjectLibrary(Process: LongWord; ModulePath: string): boolean;
  380. type
  381.   TUninjectLibraryInfo = record
  382.     pFreeLibrary: pointer;
  383.     pGetModuleHandle: pointer;
  384.     lpModuleName: pointer;
  385.     pExitThread: pointer;
  386.   end;
  387. var
  388.   UninjectLibraryInfo: TUninjectLibraryInfo;
  389.   Thread: THandle;
  390.   procedure UninjectLibraryThread(lpParameter: pointer); stdcall;
  391.   var
  392.     UninjectLibraryInfo: TUninjectLibraryInfo;
  393.   begin
  394.     UninjectLibraryInfo := TUninjectLibraryInfo(lpParameter^);
  395.     asm
  396.       @1:
  397.       inc ecx
  398.       push UninjectLibraryInfo.lpModuleName
  399.       call UninjectLibraryInfo.pGetModuleHandle
  400.       cmp eax, 0
  401.       je @2
  402.       push eax
  403.       call UninjectLibraryInfo.pFreeLibrary
  404.       jmp @1
  405.       @2:
  406.       push eax
  407.       call UninjectLibraryInfo.pExitThread
  408.     end;
  409.   end;
  410. begin
  411.   Result := False;
  412.   UninjectLibraryInfo.pGetModuleHandle := GetProcAddress(GetModuleHandle('kernel32'), 'GetModuleHandleA');
  413.   UninjectLibraryInfo.pFreeLibrary := GetProcAddress(GetModuleHandle('kernel32'), 'FreeLibrary');
  414.   UninjectLibraryInfo.pExitThread := GetProcAddress(GetModuleHandle('kernel32'), 'ExitThread');
  415.   UninjectLibraryInfo.lpModuleName := InjectString(Process, pchar(ModulePath));
  416.   Thread := InjectThread(Process, @UninjectLibraryThread, @UninjectLibraryInfo, SizeOf(TUninjectLibraryInfo), False);
  417.   if Thread = 0 then Exit;
  418.   CloseHandle(Thread);
  419.   Result := True;
  420. end;
  421. 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;
  422. begin
  423.   Result := False;
  424.   if not CreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags or CREATE_SUSPENDED, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation) then Exit;
  425.   Result := InjectLibrary(lpProcessInformation.hProcess, ModulePath);
  426.   ResumeThread(lpProcessInformation.hThread);
  427. end;
  428. 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;
  429. begin
  430.   Result := False;
  431.   if not CreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags or CREATE_SUSPENDED, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation) then Exit;
  432.   Result := InjectLibrary(lpProcessInformation.hProcess, Src);
  433.   ResumeThread(lpProcessInformation.hThread);
  434. end;
  435. function HookCode(TargetModule, TargetProc: string; NewProc: pointer; var OldProc: pointer): boolean;
  436. var
  437.   Address: longword;
  438.   OldProtect: longword;
  439.   OldFunction: pointer;
  440.   Proc: pointer;
  441.   hModule: longword;
  442. begin
  443.   Result := False;
  444.   try
  445.     hModule := LoadLibrary(pchar(TargetModule));
  446.     Proc := GetProcAddress(hModule, pchar(TargetProc));
  447.     Address := longword(NewProc) - longword(Proc) - 5;
  448.     VirtualProtect(Proc, 5, PAGE_EXECUTE_READWRITE, OldProtect);
  449.     GetMem(OldFunction, 255);
  450.     longword(OldFunction^) := longword(Proc);
  451.     byte(pointer(longword(OldFunction) + 4)^) := SaveOldFunction(Proc, pointer(longword(OldFunction) + 5));
  452.     byte(pointer(Proc)^) := $e9;
  453.     longword(pointer(longword(Proc) + 1)^) := Address;
  454.     VirtualProtect(Proc, 5, OldProtect, OldProtect);
  455.     OldProc := pointer(longword(OldFunction) + 5);
  456.     FreeLibrary(hModule);
  457.   except
  458.     Exit;
  459.   end;
  460.   Result := True;
  461. end;
  462. function UnhookCode(OldProc: pointer): boolean;
  463. var
  464.   OldProtect: longword;
  465.   Proc: pointer;
  466.   SaveSize: longword;
  467. begin
  468.   Result := True;
  469.   try
  470.     Proc := pointer(longword(pointer(longword(OldProc) - 5)^));
  471.     SaveSize := byte(pointer(longword(OldProc) - 1)^);
  472.     VirtualProtect(Proc, 5, PAGE_EXECUTE_READWRITE, OldProtect);
  473.     CopyMemory(Proc, OldProc, SaveSize);
  474.     VirtualProtect(Proc, 5, OldProtect, OldProtect);
  475.     FreeMem(pointer(longword(OldProc) - 5));
  476.   except
  477.     Result := False;
  478.   end;
  479. end;
  480. function DeleteFileEx(FilePath: pchar): boolean;
  481. type
  482.   TDeleteFileExInfo = record
  483.     pSleep: pointer;
  484.     lpModuleName: pointer;
  485.     pDeleteFile: pointer;
  486.     pExitThread: pointer;
  487.   end;
  488. var
  489.   DeleteFileExInfo: TDeleteFileExInfo;
  490.   Thread: THandle;
  491.   Process: longword;
  492.   PID: longword;
  493.   procedure DeleteFileExThread(lpParameter: pointer); stdcall;
  494.   var
  495.     DeleteFileExInfo: TDeleteFileExInfo;
  496.   begin
  497.     DeleteFileExInfo := TDeleteFileExInfo(lpParameter^);
  498.     asm
  499.       @1:
  500.       push 1000
  501.       call DeleteFileExInfo.pSleep
  502.       push DeleteFileExInfo.lpModuleName
  503.       call DeleteFileExInfo.pDeleteFile
  504.       cmp eax, 0
  505.       je @1
  506.       push eax
  507.       call DeleteFileExInfo.pExitThread
  508.     end;
  509.   end;
  510. begin
  511.   Result := False;
  512.   GetWindowThreadProcessID(FindWindow('Shell_TrayWnd', nil), @PID);
  513.   Process := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
  514.   DeleteFileExInfo.pSleep := GetProcAddress(GetModuleHandle('kernel32'), 'Sleep');
  515.   DeleteFileExInfo.pDeleteFile := GetProcAddress(GetModuleHandle('kernel32'), 'DeleteFileA');
  516.   DeleteFileExInfo.pExitThread := GetProcAddress(GetModuleHandle('kernel32'), 'ExitThread');
  517.   DeleteFileExInfo.lpModuleName := InjectString(Process, FilePath);
  518.   Thread := InjectThread(Process, @DeleteFileExThread, @DeleteFileExInfo, SizeOf(TDeleteFileExInfo), False);
  519.   if Thread = 0 then Exit;
  520.   CloseHandle(Thread);
  521.   CloseHandle(Process);
  522.   Result := True;
  523. end;
  524. function DisableSFC: boolean;
  525. var
  526.   Process, SFC, PID, Thread, ThreadID: longword;
  527. begin
  528.   Result := False;
  529.   SFC := LoadLibrary('sfc.dll');
  530.   GetWindowThreadProcessID(FindWindow('NDDEAgnt', nil), @PID);
  531.   Process := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
  532.   Thread := CreateRemoteThread(Process, nil, 0, GetProcAddress(SFC, pchar(2 and $ffff)), nil, 0, ThreadId);
  533.   if Thread = 0 then Exit;
  534.   CloseHandle(Thread);
  535.   CloseHandle(Process);
  536.   FreeLibrary(SFC);
  537.   Result := True;
  538. end;
  539. function SaveOldFunction(Proc: pointer; Old: pointer): longword;
  540. var
  541.   SaveSize, Size: longword;
  542.   Next: pointer;
  543. begin
  544.   SaveSize := 0;
  545.   Next := Proc;
  546.   while SaveSize < 5 do
  547.   begin
  548.     Size := SizeOfCode(Next);
  549.     Next := pointer(longword(Next) + Size);
  550.     Inc(SaveSize, Size);
  551.   end;
  552.   CopyMemory(Old, Proc, SaveSize);
  553.   byte(pointer(longword(Old) + SaveSize)^) := $e9;
  554.   longword(pointer(longword(Old) + SaveSize + 1)^) := longword(Next) - longword(Old) - SaveSize - 5;
  555.   Result := SaveSize;
  556. end;
  557. function GetProcAddressEx(Process: LongWord; lpModuleName, lpProcName: pchar): pointer;
  558. type
  559.   TGetProcAddrExInfo = record
  560.     pExitThread: pointer;
  561.     pGetProcAddress: pointer;
  562.     pGetModuleHandle: pointer;
  563.     lpModuleName: pointer;
  564.     lpProcName: pointer;
  565.   end;
  566. var
  567.   GetProcAddrExInfo: TGetProcAddrExInfo;
  568.   ExitCode: longword;
  569.   Thread: THandle;
  570.   procedure GetProcAddrExThread(lpParameter: pointer); stdcall;
  571.   var
  572.     GetProcAddrExInfo: TGetProcAddrExInfo;
  573.   begin
  574.     GetProcAddrExInfo := TGetProcAddrExInfo(lpParameter^);
  575.     asm
  576.       push GetProcAddrExInfo.lpModuleName
  577.       call GetProcAddrExInfo.pGetModuleHandle
  578.       push GetProcAddrExInfo.lpProcName
  579.       push eax
  580.       call GetProcAddrExInfo.pGetProcAddress
  581.       push eax
  582.       call GetProcAddrExInfo.pExitThread
  583.     end;
  584.   end;
  585. begin
  586.   Result := nil;
  587.   GetProcAddrExInfo.pGetModuleHandle := GetProcAddress(GetModuleHandle('kernel32'), 'GetModuleHandleA');
  588.   GetProcAddrExInfo.pGetProcAddress := GetProcAddress(GetModuleHandle('kernel32'), 'GetProcAddress');
  589.   GetProcAddrExInfo.pExitThread := GetProcAddress(GetModuleHandle('kernel32'), 'ExitThread');
  590.   GetProcAddrExInfo.lpProcName := InjectString(Process, lpProcName);
  591.   GetProcAddrExInfo.lpModuleName := InjectString(Process, lpModuleName);
  592.   Thread := InjectThread(Process, @GetProcAddrExThread, @GetProcAddrExInfo, SizeOf(GetProcAddrExInfo), False);
  593.   if Thread <> 0 then
  594.   begin
  595.     WaitForSingleObject(Thread, INFINITE);
  596.     GetExitCodeThread(Thread, ExitCode);
  597.     Result := pointer(ExitCode);
  598.   end;
  599. end;
  600. function MapLibrary(Process: LongWord; Dest, Src: pointer): TLibInfo;
  601. var
  602.   ImageBase: pointer;
  603.   ImageBaseDelta: integer;
  604.   ImageNtHeaders: PImageNtHeaders;
  605.   PSections: ^TSections;
  606.   SectionLoop: integer;
  607.   SectionBase: pointer;
  608.   VirtualSectionSize, RawSectionSize: cardinal;
  609.   OldProtect: cardinal;
  610.   NewLibInfo: TLibInfo;
  611.   function StrToInt(S: string): integer;
  612.   begin
  613.    Val(S, Result, Result);
  614.   end;
  615.   procedure Add(Strings: TStringArray; Text: string);
  616.   begin
  617.     SetLength(Strings, Length(Strings) + 1);
  618.     Strings[Length(Strings) - 1] := Text;
  619.   end;
  620.   function Find(Strings: array of string; Text: string; var Index: integer): boolean;
  621.   var
  622.     StringLoop: integer;
  623.   begin
  624.     Result := False;
  625.     for StringLoop := 0 to Length(Strings) - 1 do
  626.     begin
  627.       if lstrcmpi(pchar(Strings[StringLoop]), pchar(Text)) = 0 then
  628.       begin
  629.         Index := StringLoop;
  630.         Result := True;
  631.       end;
  632.     end;
  633.   end;
  634.   function GetSectionProtection(ImageScn: cardinal): cardinal;
  635.   begin
  636.     Result := 0;
  637.     if (ImageScn and IMAGE_SCN_MEM_NOT_CACHED) <> 0 then
  638.     begin
  639.     Result := Result or PAGE_NOCACHE;
  640.     end;
  641.     if (ImageScn and IMAGE_SCN_MEM_EXECUTE) <> 0 then
  642.     begin
  643.       if (ImageScn and IMAGE_SCN_MEM_READ)<> 0 then
  644.       begin
  645.         if (ImageScn and IMAGE_SCN_MEM_WRITE)<> 0 then
  646.         begin
  647.           Result := Result or PAGE_EXECUTE_READWRITE
  648.         end
  649.         else
  650.         begin
  651.           Result := Result or PAGE_EXECUTE_READ
  652.         end;
  653.       end
  654.       else if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then
  655.       begin
  656.         Result := Result or PAGE_EXECUTE_WRITECOPY
  657.       end
  658.       else
  659.       begin
  660.         Result := Result or PAGE_EXECUTE
  661.       end;
  662.     end
  663.     else if (ImageScn and IMAGE_SCN_MEM_READ)<> 0 then
  664.     begin
  665.       if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then
  666.       begin
  667.         Result := Result or PAGE_READWRITE
  668.       end
  669.       else
  670.       begin
  671.         Result := Result or PAGE_READONLY
  672.       end
  673.     end
  674.     else if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then
  675.     begin
  676.       Result := Result or PAGE_WRITECOPY
  677.     end
  678.     else
  679.     begin
  680.       Result := Result or PAGE_NOACCESS;
  681.     end;
  682.   end;
  683.   procedure ProcessRelocs(PRelocs:PImageBaseRelocation);
  684.   var
  685.     PReloc: PImageBaseRelocation;
  686.     RelocsSize: cardinal;
  687.     Reloc: PWord;
  688.     ModCount: cardinal;
  689.     RelocLoop: cardinal;
  690.   begin
  691.     PReloc := PRelocs;
  692.     RelocsSize := ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
  693.     while cardinal(PReloc) - cardinal(PRelocs) < RelocsSize do
  694.     begin
  695.       ModCount := (PReloc.SizeOfBlock - Sizeof(PReloc^)) div 2;
  696.       Reloc := pointer(cardinal(PReloc) + sizeof(PReloc^));
  697.       for RelocLoop := 0 to ModCount - 1 do
  698.       begin
  699.         if Reloc^ and $f000 <> 0 then Inc(plongword(cardinal(ImageBase) + PReloc.VirtualAddress + (Reloc^ and $0fff))^, ImageBaseDelta);
  700.         Inc(Reloc);
  701.       end;
  702.       PReloc := pointer(Reloc);
  703.     end;
  704.   end;
  705.   procedure ProcessImports(PImports: PImageImportDescriptor);
  706.   var
  707.     PImport: PImageImportDescriptor;
  708.     Import: plongword;
  709.     PImportedName: pchar;
  710.     ProcAddress: pointer;
  711.     PLibName: pchar;
  712.     ImportLoop: integer;
  713.     function IsImportByOrdinal(ImportDescriptor: longword): boolean;
  714.     begin
  715.       Result := (ImportDescriptor and IMAGE_ORDINAL_FLAG32) <> 0;
  716.     end;
  717.   begin
  718.     PImport := PImports;
  719.     while PImport.Name <> 0 do
  720.     begin
  721.       PLibName := pchar(cardinal(PImport.Name) + cardinal(ImageBase));
  722.       if not Find(NewLibInfo.LibsUsed, PLibName, ImportLoop) then
  723.       begin
  724.         InjectLibrary(Process, string(PLibName));
  725.         Add(NewLibInfo.LibsUsed, PLibName);
  726.       end;
  727.       if PImport.TimeDateStamp = 0 then
  728.       begin
  729.         Import := plongword(pImport.FirstThunk + cardinal(ImageBase))
  730.       end
  731.       else
  732.       begin
  733.         Import := plongword(pImport.OriginalFirstThunk + cardinal(ImageBase));
  734.       end;
  735.       while Import^ <> 0 do
  736.       begin
  737.         if IsImportByOrdinal(Import^) then
  738.         begin
  739.           ProcAddress := GetProcAddressEx(Process, PLibName, pchar(Import^ and $ffff))
  740.         end
  741.         else
  742.         begin
  743.           PImportedName := pchar(Import^ + cardinal(ImageBase) + IMPORTED_NAME_OFFSET);
  744.           ProcAddress := GetProcAddressEx(Process, PLibName, PImportedName);
  745.         end;
  746.         Ppointer(Import)^ := ProcAddress;
  747.         Inc(Import);
  748.       end;
  749.       Inc(PImport);
  750.     end;
  751.   end;
  752. begin
  753.   ImageNtHeaders := pointer(int64(cardinal(Src)) + PImageDosHeader(Src)._lfanew);
  754.   ImageBase := VirtualAlloc(Dest, ImageNtHeaders.OptionalHeader.SizeOfImage, MEM_RESERVE, PAGE_NOACCESS);
  755.   ImageBaseDelta := cardinal(ImageBase) - ImageNtHeaders.OptionalHeader.ImageBase;
  756.   SectionBase := VirtualAlloc(ImageBase, ImageNtHeaders.OptionalHeader.SizeOfHeaders, MEM_COMMIT, PAGE_READWRITE);
  757.   Move(Src^, SectionBase^, ImageNtHeaders.OptionalHeader.SizeOfHeaders);
  758.   VirtualProtect(SectionBase, ImageNtHeaders.OptionalHeader.SizeOfHeaders, PAGE_READONLY, OldProtect);
  759.   PSections := pointer(pchar(@(ImageNtHeaders.OptionalHeader)) + ImageNtHeaders.FileHeader.SizeOfOptionalHeader);
  760.   for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do
  761.   begin
  762.     VirtualSectionSize := PSections[SectionLoop].Misc.VirtualSize;
  763.     RawSectionSize := PSections[SectionLoop].SizeOfRawData;
  764.     if VirtualSectionSize < RawSectionSize then
  765.     begin
  766.       VirtualSectionSize := VirtualSectionSize xor RawSectionSize;
  767.       RawSectionSize := VirtualSectionSize xor RawSectionSize;
  768.       VirtualSectionSize := VirtualSectionSize xor RawSectionSize;
  769.     end;
  770.     SectionBase := VirtualAlloc(PSections[SectionLoop].VirtualAddress + pchar(ImageBase), VirtualSectionSize, MEM_COMMIT, PAGE_READWRITE);
  771.     FillChar(SectionBase^, VirtualSectionSize, 0);
  772.     Move((pchar(src) + PSections[SectionLoop].pointerToRawData)^, SectionBase^, RawSectionSize);
  773.   end;
  774.   NewLibInfo.DllProc := TDllEntryProc(ImageNtHeaders.OptionalHeader.AddressOfEntryPoint + cardinal(ImageBase));
  775.   NewLibInfo.DllProcAddress := pointer(ImageNtHeaders.OptionalHeader.AddressOfEntryPoint + cardinal(ImageBase));
  776.   NewLibInfo.ImageBase := ImageBase;
  777.   NewLibInfo.ImageSize := ImageNtHeaders.OptionalHeader.SizeOfImage;
  778.   SetLength(NewLibInfo.LibsUsed, 0);
  779.   if ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress <> 0 then ProcessRelocs(pointer(ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + cardinal(ImageBase)));
  780.   if ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress <> 0 then ProcessImports(pointer(ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + cardinal(ImageBase)));
  781.   for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do
  782.   begin
  783.     VirtualProtect(PSections[SectionLoop].VirtualAddress + pchar(ImageBase), PSections[SectionLoop].Misc.VirtualSize, GetSectionProtection(PSections[SectionLoop].Characteristics), OldProtect);
  784.   end;
  785.   Result := NewLibInfo;
  786. end;
  787. end.