|
Registriert seit: 30. Jan 2004 823 Beiträge |
#9
Vorläufige Version (in der Mittagspause gemacht, funktioniert aber noch nicht richtig, denke wegen den 3 Parametern bei DllMain)
Delphi-Quellcode:
jep liegt an dem RemoteThread, dies funcktioniert:
function LoadLibraryEx(const fsLibrary: TStream; dwProcessID: DWord): Boolean; stdcall;
type TRelocBlock = packed record dwAddress: DWord; dwSize: DWord; end; PRelocBlock = ^TRelocBlock; TImportBlock = packed record dwCharacteristics: DWord; dwTimeDateStamp: DWord; dwForwarderChain: DWord; dwName: DWord; pFirstThunk: Pointer; end; PImportBlock = ^TImportBlock; TImportNameBlock = packed record wHint: Word; pName: PChar; end; PImportNameBlock = ^TImportNameBlock; procedure ChangeReloc(POrigBase, PBaseTemp, PReloc, PBaseTarget: Pointer; dwRelocSize: DWord); stdcall; var pCurrentRelocBlock: PRelocBlock; RelocCount: DWord; PCurrentStart: PWord; i: Integer; pRelocAddress: PInteger; iDif: Integer; begin pCurrentRelocBlock := PReloc; iDif := Integer(PBaseTarget) - Integer(POrigBase); PCurrentStart := Pointer(Integer(PReloc) + 8); while (not isBadReadPtr(pCurrentRelocBlock, SizeOf(TRelocBlock))) and (not isBadReadPtr(pCurrentStart, SizeOf(Pointer))) and (DWord(pCurrentRelocBlock) < DWord(pReloc) + dwRelocSize) do begin RelocCount := (pCurrentRelocBlock^.dwSize - 8) div SizeOf(Word); for i := 0 to RelocCount - 1 do begin if (not isBadReadPtr(pCurrentStart, SizeOf(Pointer))) and (PCurrentStart^ xor $3000 < $1000) then begin pRelocAddress := Pointer(pCurrentRelocBlock^.dwAddress + PCurrentStart^ mod $3000 + DWord(PBaseTemp)); if (not isBadWritePtr(pRelocAddress, SizeOf(Integer))) then pRelocAddress^ := pRelocAddress^ + iDif; end; PCurrentStart := Pointer(DWord(PCurrentStart) + SizeOf(Word)); end; pCurrentRelocBlock := Pointer(PCurrentStart); pCurrentStart := Pointer(DWord(PCurrentStart) + 8); end; end; procedure CreateImportTable(pLibraryHandle, pImportTable: pointer); stdcall; var pIBlock: PImportBlock; pThunksRead: PDWord; pThunksWrite: PDWord; pDllName: PChar; dwLibraryHandle: DWord; dwOldProtect: DWord; begin pIBlock := pImportTable; while (not isBadReadPtr(pIBlock, SizeOf(TImportBlock))) and (pIBlock^.pFirstThunk <> nil) and (pIBlock^.dwName <> 0) do begin pDllName := Pointer(DWord(pLibraryHandle) + DWord(pIBlock^.dwName)); if (not isBadReadPtr(pDllName, 4)) then begin dwLibraryHandle := LoadLibrary(pDllName); pThunksRead := Pointer(DWord(pIBlock^.pFirstThunk) + DWord(pLibraryHandle)); pThunksWrite := pThunksRead; if (DWord(pIBlock^.dwTimeDateStamp) = $FFFFFFFF) then pThunksRead := Pointer(DWord(pIBlock^.dwCharacteristics) + DWord(pLibraryHandle)); while (not isBadReadPtr(pThunksRead, SizeOf(DWord))) and (not isBadReadPtr(pThunksWrite, SizeOf(Word))) and (pThunksRead^ <> 0) do begin if VirtualProtect(pThunksWrite, SizeOf(DWord), PAGE_EXECUTE_READWRITE, dwOldProtect) then begin if (DWord(pThunksRead^) and $80000000 <> 0) then pThunksWrite^ := DWord(GetProcAddress(dwLibraryHandle, PChar(pThunksRead^ and $FFFF))) else pThunksWrite^ := DWord(GetProcAddress(dwLibraryHandle, PChar(DWord(pLibraryHandle) + pThunksRead^ + SizeOf(Word)))); VirtualProtect(pThunksWrite, SizeOf(DWord), dwOldProtect, dwOldProtect); end; Inc(pThunksRead); Inc(pThunksWrite); end; end; pIBlock := Pointer(DWord(pIBlock) + SizeOf(TImportBlock)); end; end; var DllMain: function(dwHandle, dwReason, dwReserved: DWord): DWord; stdcall; IDH: PImageDosHeader; INH: PImageNtHeaders; SEC: PImageSectionHeader; dwSecCount: DWord; dwmemsize: DWord; i: Integer; pFileMem: Pointer; pMemLocal: Pointer; pMemProcess: Pointer; hProcessHandle: THandle; dwWritten: DWord; hThread: THandle; dwThreadID: DWord; begin Result := False; // ProcessHandle holen um Speicher für DLL zu allozieren und RemoteThread zu starten hProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, false, dwProcessID); if hProcessHandle <> 0 then begin // für den Stream speicher holen um leichter auf die Daten zuzugreifen pFileMem := VirtualAlloc(nil, fsLibrary.Size, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (pFileMem <> nil) then begin fsLibrary.Position := 0; fsLibrary.Read(pFileMem^, fsLibrary.Size); IDH := pFileMem; // ImageDosHeader gültig? if (not isBadReadPtr(IDH, SizeOf(TImageDosHeader))) and (IDH^.e_magic = IMAGE_DOS_SIGNATURE) then begin // ImageNtHeader gültig? INH := pointer(cardinal(pFileMem) + cardinal(IDH^._lfanew)); if (not isBadReadPtr(INH, SizeOf(TImageNtHeaders))) and (INH^.Signature = IMAGE_NT_SIGNATURE) then begin SEC := Pointer(Integer(INH) + SizeOf(TImageNtHeaders)); // Virtuelle größe der Dll/Exe ermitteln dwMemSize := INH^.OptionalHeader.SizeOfImage; if (dwMemSize <> 0) then begin // Lokalen speicher für die DLL holen (wir bereiten die in userem Prozess vor) pMemLocal := VirtualAlloc(nil, dwMemSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (pMemLocal <> nil) then begin // Speicher aus dem Fremdprozess holen (indem wir die dll nachher kopieren und ausführen) pMemProcess := VirtualAllocEx(hProcessHandle, nil, dwMemSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE); if pMemProcess <> nil then begin // jede Sektion and die richtige Adresse kopieren dwSecCount := INH^.FileHeader.NumberOfSections; CopyMemory(pMemLocal, IDH, DWord(SEC) - DWord(IDH) + dwSecCount * SizeOf(TImageSectionHeader)); for i := 0 to dwSecCount - 1 do begin CopyMemory(Pointer(DWord(pMemLocal) + SEC^.VirtualAddress), Pointer(DWord(pFileMem) + DWord(SEC^.PointerToRawData)), SEC^.SizeOfRawData); SEC := Pointer(Integer(SEC) + SizeOf(TImageSectionHeader)); end; // Adressen der Dll für den Zielprozess anpassen if (INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress <> 0) then begin ChangeReloc(Pointer(INH^.OptionalHeader.ImageBase), pMemLocal, Pointer(DWord(pMemLocal) + INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress), Pointer(pMemProcess), INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size); end; // die Importtabelle anpassen, die Adressen holen wir lokal aus unserem Prozess // sollte die Dll nicht im Zielprozess geladen sein -> crash // theoretisch kann man diese auch aus dem Zielprozess ermitteln // und fehlende Dlls dort ebenfalls nachladen // aber jetzt nicht hier behandelt, da dll die in einen Fremdprozess injeziert werden // IMMER nur ntdll/kernel32/(user32 falls Prozess mit Fenster) Funktionen benutzen sollen CreateImportTable(pMemLocal, Pointer(DWord(pMemLocal) + INH^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)); // bei DLL-Main einen Thread starten @DllMain := Pointer(INH^.OptionalHeader.AddressOfEntryPoint + DWord(pMemProcess)); if WriteProcessMemory(hProcessHandle, pMemProcess, pMemLocal, dwMemSize, dwWritten) and (dwWritten = dwMemSize) then begin hThread := CreateRemoteThread(hProcessHandle, nil, 0, @DllMain, nil, 0, dwThreadID); if hThread <> 0 then begin Result := True; CloseHandle(hThread); end; end else begin VirtualFreeEx(hProcessHandle, pMemProcess, dwMemSize, MEM_DECOMMIT); end; end; end; VirtualFree(pMemLocal, dwMemSize, MEM_DECOMMIT); end; end; VirtualFree(pFileMem, fsLibrary.Size, MEM_DECOMMIT); end; end; CloseHandle(hProcessHandle); end; end; procedure TForm12.FormCreate(Sender: TObject); var fm: TFileStream; begin fm := TFileStream.Create(ExtractFilePath(Paramstr(0))+'test.dll', fmOpenRead); LoadLibraryEx(fm, GetCurrentProcessID); fm.Free; end; muss man noch bisl Code injezieren um DllMain richtig aufzurufen vill schaffst das selber, ansonsten meld ich mich vill heute abend
Delphi-Quellcode:
//hThread := CreateRemoteThread(hProcessHandle, nil, 0, @DllMain, nil, 0, dwThreadID);
DllMain(0, DLL_PROCESS_ATTACH, 0); |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |