Advertisement
0xNOP

afxCodeHook - Support for XE

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