Advertisement
ZxZ666

Dll injection from memory

Oct 15th, 2011
291
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Следующий код копирует и настраивает DLL в выделенный участок чужого адресного пространства:
  2. {
  3.  Отображение Dll на чужое адресное пространство, настройка импорта и релоков.
  4.  Process - хэндл процесса для отображения,
  5.  Dest    - адрес отображения в процессе Process,
  6.  Src     - адрес образа Dll в текущем процессе.
  7. }
  8. function MapLibrary(Process: dword; Dest, Src: pointer): TLibInfo;
  9. var
  10.   ImageBase: pointer;
  11.   ImageBaseDelta: integer;
  12.   ImageNtHeaders: PImageNtHeaders;
  13.   PSections: ^TSections;
  14.   SectionLoop: integer;
  15.   SectionBase: pointer;
  16.   VirtualSectionSize, RawSectionSize: dword;
  17.   OldProtect: dword;
  18.   NewLibInfo: TLibInfo;
  19.  
  20.   { Настройка релоков }
  21.   procedure ProcessRelocs(PRelocs:PImageBaseRelocation);
  22.   var
  23.     PReloc: PImageBaseRelocation;
  24.     RelocsSize: dword;
  25.     Reloc: PWord;
  26.     ModCount: dword;
  27.     RelocLoop: dword;
  28.   begin
  29.     PReloc := PRelocs;
  30.     RelocsSize := ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
  31.     while dword(PReloc) - dword(PRelocs) < RelocsSize do
  32.     begin
  33.       ModCount := (PReloc.SizeOfBlock - Sizeof(PReloc^)) div 2;
  34.       Reloc := pointer(dword(PReloc) + sizeof(PReloc^));
  35.       for RelocLoop := 0 to ModCount - 1 do
  36.       begin
  37.         if Reloc^ and $f000 <> 0 then Inc(pdword(dword(ImageBase) +
  38.                                           PReloc.VirtualAddress +
  39.                                           (Reloc^ and $0fff))^, ImageBaseDelta);
  40.         Inc(Reloc);
  41.       end;
  42.       PReloc := pointer(Reloc);
  43.     end;
  44.   end;
  45.  
  46.   { Настройка импорта Dll в чужом процессе}
  47.   procedure ProcessImports(PImports: PImageImportDescriptor);
  48.   var
  49.     PImport: PImageImportDescriptor;
  50.     Import: pdword;
  51.     PImportedName: pchar;
  52.     ProcAddress: pointer;
  53.     PLibName: pchar;
  54.     ImportLoop: integer;
  55.  
  56.     function IsImportByOrdinal(ImportDescriptor: dword): boolean;
  57.     begin
  58.       Result := (ImportDescriptor and IMAGE_ORDINAL_FLAG32) <> 0;
  59.     end;
  60.  
  61.   begin
  62.     PImport := PImports;
  63.     while PImport.Name <> 0 do
  64.     begin
  65.       PLibName := pchar(dword(PImport.Name) + dword(ImageBase));
  66.       if not Find(NewLibInfo.LibsUsed, PLibName, ImportLoop) then
  67.       begin
  68.         InjectDll(Process, PLibName);
  69.         Add(NewLibInfo.LibsUsed, PLibName);
  70.       end;
  71.       if PImport.TimeDateStamp = 0 then
  72.         Import := pdword(pImport.FirstThunk + dword(ImageBase))
  73.       else
  74.         Import := pdword(pImport.OriginalFirstThunk + dword(ImageBase));
  75.  
  76.       while Import^ <> 0 do
  77.       begin
  78.         if IsImportByOrdinal(Import^) then
  79.           ProcAddress := GetProcAddressEx(Process, PLibName, PChar(Import^ and $ffff), 4)
  80.         else
  81.         begin
  82.           PImportedName := pchar(Import^ + dword(ImageBase) + IMPORTED_NAME_OFFSET);
  83.           ProcAddress := GetProcAddressEx(Process, PLibName, PImportedName, Length(PImportedName));
  84.         end;
  85.         Ppointer(Import)^ := ProcAddress;
  86.         Inc(Import);
  87.       end;
  88.       Inc(PImport);
  89.     end;
  90.   end;
  91.  
  92. begin
  93.   ImageNtHeaders := pointer(dword(Src) + dword(PImageDosHeader(Src)._lfanew));
  94.   ImageBase := VirtualAlloc(Dest, ImageNtHeaders.OptionalHeader.SizeOfImage,
  95.                             MEM_RESERVE, PAGE_NOACCESS);
  96.                            
  97.   ImageBaseDelta := dword(ImageBase) - ImageNtHeaders.OptionalHeader.ImageBase;
  98.   SectionBase := VirtualAlloc(ImageBase, ImageNtHeaders.OptionalHeader.SizeOfHeaders,
  99.                               MEM_COMMIT, PAGE_READWRITE);
  100.   Move(Src^, SectionBase^, ImageNtHeaders.OptionalHeader.SizeOfHeaders);
  101.   VirtualProtect(SectionBase, ImageNtHeaders.OptionalHeader.SizeOfHeaders,
  102.                  PAGE_READONLY, OldProtect);
  103.   PSections := pointer(pchar(@(ImageNtHeaders.OptionalHeader)) +
  104.                                ImageNtHeaders.FileHeader.SizeOfOptionalHeader);
  105.                                
  106.   for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do
  107.   begin
  108.     VirtualSectionSize := PSections[SectionLoop].Misc.VirtualSize;
  109.     RawSectionSize := PSections[SectionLoop].SizeOfRawData;
  110.     if VirtualSectionSize < RawSectionSize then
  111.     begin
  112.       VirtualSectionSize := VirtualSectionSize xor RawSectionSize;
  113.       RawSectionSize := VirtualSectionSize xor RawSectionSize;
  114.       VirtualSectionSize := VirtualSectionSize xor RawSectionSize;
  115.     end;
  116.     SectionBase := VirtualAlloc(PSections[SectionLoop].VirtualAddress +
  117.                                 pchar(ImageBase), VirtualSectionSize,
  118.                                 MEM_COMMIT, PAGE_READWRITE);
  119.     FillChar(SectionBase^, VirtualSectionSize, 0);
  120.     Move((pchar(src) + PSections[SectionLoop].pointerToRawData)^,
  121.          SectionBase^, RawSectionSize);
  122.   end;
  123.   NewLibInfo.DllProcAddress := pointer(ImageNtHeaders.OptionalHeader.AddressOfEntryPoint +
  124.                                        dword(ImageBase));
  125.    NewLibInfo.DllProc := TDllEntryProc(NewLibInfo.DllProcAddress);
  126.  
  127.   NewLibInfo.ImageBase := ImageBase;
  128.   NewLibInfo.ImageSize := ImageNtHeaders.OptionalHeader.SizeOfImage;
  129.   SetLength(NewLibInfo.LibsUsed, 0);
  130.   if ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress <> 0
  131.      then ProcessRelocs(pointer(ImageNtHeaders.OptionalHeader.
  132.                                 DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].
  133.                                 VirtualAddress + dword(ImageBase)));
  134.  
  135.   if ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress <> 0
  136.      then ProcessImports(pointer(ImageNtHeaders.OptionalHeader.
  137.                                  DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].
  138.                                  VirtualAddress + dword(ImageBase)));
  139.      
  140.   for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do
  141.     VirtualProtect(PSections[SectionLoop].VirtualAddress + pchar(ImageBase),
  142.                    PSections[SectionLoop].Misc.VirtualSize,
  143.                    GetSectionProtection(PSections[SectionLoop].Characteristics),
  144.                    OldProtect);
  145.   Result := NewLibInfo;
  146. end;
  147.  
  148.  
  149. Теперь для внедрения DLL в целевой процесс этим способом можно использовать следующую функцию:
  150. {
  151.   Внедрение Dll в процесс методом инжекции кода и настройки образа Dll в памяти.
  152.   Данный метод внедрения более скрытен, и не обнаруживается фаерволлами.
  153. }
  154. function InjectDllEx(Process: dword; Src: pointer): boolean;
  155. type
  156.   TDllLoadInfo = packed record
  157.                   Module: pointer;
  158.                   EntryPoint: pointer;
  159.                  end;
  160. var
  161.   Lib: TLibInfo;
  162.   BytesWritten: dword;
  163.   ImageNtHeaders: PImageNtHeaders;
  164.   pModule: pointer;
  165.   Offset: dword;
  166.   DllLoadInfo: TDllLoadInfo;
  167.   hThread: dword;
  168.  
  169.  { процедура передачи управления на точку входа dll }
  170.   procedure DllEntryPoint(lpParameter: pointer); stdcall;
  171.   var
  172.     LoadInfo: TDllLoadInfo;
  173.   begin
  174.     LoadInfo := TDllLoadInfo(lpParameter^);
  175.     asm
  176.       xor eax, eax
  177.       push eax
  178.       push DLL_PROCESS_ATTACH
  179.       push LoadInfo.Module
  180.       call LoadInfo.EntryPoint
  181.     end;
  182.   end;
  183.  
  184. begin
  185.   Result := False;
  186.   ImageNtHeaders := pointer(dword(Src) + dword(PImageDosHeader(Src)._lfanew));
  187.   Offset := $10000000;
  188.   repeat
  189.     Inc(Offset, $10000);
  190.     pModule := VirtualAlloc(pointer(ImageNtHeaders.OptionalHeader.ImageBase + Offset),
  191.                             ImageNtHeaders.OptionalHeader.SizeOfImage,
  192.                             MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  193.     if pModule <> nil then
  194.     begin
  195.       VirtualFree(pModule, 0, MEM_RELEASE);
  196.       pModule := VirtualAllocEx(Process, pointer(ImageNtHeaders.OptionalHeader.
  197.                                                  ImageBase + Offset),
  198.                                                  ImageNtHeaders.OptionalHeader.
  199.                                                  SizeOfImage,
  200.                                                  MEM_COMMIT or MEM_RESERVE,
  201.                                                  PAGE_EXECUTE_READWRITE);
  202.     end;
  203.   until ((pModule <> nil) or (Offset > $30000000));
  204.   Lib := MapLibrary(Process, pModule, Src);
  205.   if Lib.ImageBase = nil then Exit;
  206.   DllLoadInfo.Module     := Lib.ImageBase;
  207.   DllLoadInfo.EntryPoint := Lib.DllProcAddress;
  208.   WriteProcessMemory(Process, pModule, Lib.ImageBase, Lib.ImageSize, BytesWritten);
  209.   hThread := InjectThread(Process, @DllEntryPoint, @DllLoadInfo,
  210.                           SizeOf(TDllLoadInfo), False);
  211.   if hThread <> 0 then Result := True
  212. end;
  213.  
Advertisement
Advertisement
Advertisement
RAW Paste Data Copied
Advertisement