|
Antwort |
Hallo zusammen,
bei meinem letzten Projekt kam ich in die Verlegenheit Code in einem anderen Prozess ausführen zu müssen. Eine komplette DLL Injection wollte ich vermeiden, da die Codemenge in diesem Fall nur sehr gering war. Nun kann man natürlich einfach den Assembler Code einer kompletten Delphi Funktion injizieren und ausführen. Dies bringt allerdings einige Schwierigkeiten mit sich:
Um diesen Problemen entgegenzuwirken, habe ich eine Klasse geschrieben, welche Code erzeugen kann, der direkt in einem anderen Prozess ausführbar ist. Für den maximalen Komfort wird der Shellcode in einer Klasse gekapselt, die ihr von TBasicShellcode ableiten müsst. Alle Felder der Klasse werden zur Laufzeit im Fremdprozess verfügbar sein. Ebenfalls könnt ihr alle Klassenfunktionen für die Verwendung im Shellcode registrieren (nur VIRTUAL Methods) und so Unterfunktionen ganz intuitiv verwenden. Wenn der Shellcode externe API Imports benötigt, so reicht es einfach die jeweilige Funktion an ein beliebiges Feld der Klasse zu binden. Beispiel:
Delphi-Quellcode:
const
ID_WSTRING_INFO = $00000001; ID_WSTRING_INFO_TEXT = $00000002; ID_WSTRING_QUESTION = $00000003; ID_WSTRING_QUESTION_TEXT = $00000004; type TMyShellcode = class(TBasicShellcode) private FMessageTitle: PWideChar; FMessageText: PWideChar; FMessageFlags: DWord; private APIBeep: function(dwFreq, dwDuration: DWORD): BOOL; stdcall; APIMessageBoxW: function(hWnd: HWND; lpText, lpCaption: LPCWSTR; uType: UINT): Integer; stdcall; private function ShowQuestion(Text, Title: PWideChar): Integer; virtual; procedure DoShowMessage; virtual; protected procedure RegisterImports(Forger: TBasicShellcodeForger); override; procedure RegisterMethods(Forger: TBasicShellcodeForger); override; procedure RegisterStrings(Forger: TBasicShellcodeForger); override; protected function Initialize({Param: Pointer}): DWord; override; function Finalize: DWord; override; end; { TMyShellcode } function TMyShellcode.ShowQuestion(Text, Title: PWideChar): Integer; begin Result := APIMessageBoxW(0, Text, Title, MB_ICONQUESTION or MB_YESNO); end; procedure EndOfTMyShellcodeShowQuestion; begin end; function TMyShellcode.Initialize({Param: Pointer}): DWord; begin APIBeep(1000, 200); FMessageText := FindWideString(ID_WSTRING_INFO_TEXT); FMessageTitle := FindWideString(ID_WSTRING_INFO); FMessageFlags := MB_ICONINFORMATION; DoShowMessage; Result := 0; end; procedure EndOfTMyShellcodeInitialize; begin end; procedure TMyShellcode.DoShowMessage; begin APIMessageBoxW(0, FMessageText, FMessageTitle, FMessageFlags); end; procedure EndOfTMyShellcodeDoShowMessage; begin end; function TMyShellcode.Finalize: DWord; begin APIBeep(500, 200); Result := ShowQuestion(FindWideString(ID_WSTRING_QUESTION_TEXT), FindWideString(ID_WSTRING_QUESTION)); end; procedure EndOfTMyShellcodeFinalize; begin end; procedure TMyShellcode.RegisterImports(Forger: TBasicShellcodeForger); begin inherited; RegisterImport(Forger, @@APIBeep, 'kernel32.dll', 'Beep'); RegisterImport(Forger, @@APIMessageBoxW, 'user32.dll', 'MessageBoxW'); end; procedure TMyShellcode.RegisterMethods(Forger: TBasicShellcodeForger); begin inherited; RegisterMethod(Forger, @TMyShellcode.Initialize, NativeUInt(@EndOfTMyShellcodeInitialize) - NativeUInt(@TMyShellcode.Initialize)); RegisterMethod(Forger, @TMyShellcode.Finalize, NativeUInt(@EndOfTMyShellcodeFinalize) - NativeUInt(@TMyShellcode.Finalize)); RegisterMethod(Forger, @TMyShellcode.ShowQuestion, NativeUInt(@EndOfTMyShellcodeShowQuestion) - NativeUInt(@TMyShellcode.ShowQuestion)); RegisterMethod(Forger, @TMyShellcode.DoShowMessage, NativeUInt(@EndOfTMyShellcodeDoShowMessage) - NativeUInt(@TMyShellcode.DoShowMessage)); end; procedure TMyShellcode.RegisterStrings(Forger: TBasicShellcodeForger); begin inherited; RegisterWideString(Forger, ID_WSTRING_INFO, 'Info'); RegisterWideString(Forger, ID_WSTRING_INFO_TEXT, 'Hello hello boys and girls!'); RegisterWideString(Forger, ID_WSTRING_QUESTION, 'Question'); RegisterWideString(Forger, ID_WSTRING_QUESTION_TEXT, 'Bye bye. What do you want me to return?'); end;
Delphi-Quellcode:
Feedback und Verbesserungsvorschläge erwünscht!
var
Forger: TBasicShellcodeForger; ProcessHandle, ThreadHandleA, ThreadHandleB: THandle; Shellcode: TMemoryStream; ShellcodeSize: DWord; BaseAddress, ProcEntryPoint, ProcDestructor: Pointer; BytesWritten: SIZE_T; TID, ExitCode: DWord; begin Forger := TBasicShellcodeForger.Create(TMyShellcode); try ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, false, {Process ID}); if (ProcessHandle <> 0) and (ProcessHandle <> INVALID_HANDLE_VALUE) then try ShellcodeSize := Forger.GetShellcodeSize; BaseAddress := VirtualAllocEx(ProcessHandle, nil, ShellcodeSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE); if Assigned(BaseAddress) then try Shellcode := TMemoryStream.Create; try Forger.GenerateShellcode(BaseAddress, Shellcode, ProcEntryPoint, ProcDestructor); if (WriteProcessMemory(ProcessHandle, BaseAddress, Shellcode.Memory, Shellcode.Size, BytesWritten)) and (BytesWritten = Shellcode.Size) then begin ThreadHandleA := CreateRemoteThread(ProcessHandle, nil, 0, ProcEntryPoint, BaseAddress, 0, TID); if (ThreadHandleA <> 0) and (ThreadHandleA <> INVALID_HANDLE_VALUE) then try WaitForSingleObject(ThreadHandleA, INFINITE); if GetExitCodeThread(ThreadHandleA, ExitCode) then begin MessageBox(0, PChar(Format('Shellcode initialize returned: %.8x.', [ExitCode])), 'Info', MB_ICONINFORMATION); end; finally CloseHandle(ThreadHandleA); end; ThreadHandleB := CreateRemoteThread(ProcessHandle, nil, 0, ProcDestructor, BaseAddress, 0, TID); if (ThreadHandleB <> 0) and (ThreadHandleB <> INVALID_HANDLE_VALUE) then try WaitForSingleObject(ThreadHandleB, INFINITE); if GetExitCodeThread(ThreadHandleB, ExitCode) then begin MessageBox(0, PChar(Format('Shellcode finalize returned: %.8x.', [ExitCode])), 'Info', MB_ICONINFORMATION); end; finally CloseHandle(ThreadHandleB); end; end; finally Shellcode.Free; end; finally VirtualFreeEx(ProcessHandle, BaseAddress, ShellcodeSize, MEM_RELEASE or MEM_FREE); end; finally CloseHandle(ProcessHandle); end; finally Forger.Free; end; end; Viele Grüße Zacherl |
Ansicht |
Linear-Darstellung |
Zur Hybrid-Darstellung wechseln |
Zur Baum-Darstellung wechseln |
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 |
LinkBack URL |
About LinkBacks |