
found myself
   
Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006
Репутация: 1 Всего: 121
|
Ну тогда разбирайся  | Код | var PLibInfo = ^TLibInfo; TLibInfo = packed record ImageBase: pointer; ImageSize: longint; DllProc: TDllEntryProc; DllProcAddress: pointer; LibsUsed: TStringArray; end;
TSections = array [0..0] of TImageSectionHeader;
begin
{ Отображение 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 в памяти. Данный метод внедрения более скрытен, и не обнаруживается фаерволлами. } 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;
|
Есть ещё пример на асме, могу дать
--------------------
"Бог умер" © Ницше "Ницше умер" © Бог
|