![]() |
Adresse einer Funktion ohne @ ermitteln (evtl über CS:IP)
Hey,
ich muss die Adresse einer Funktion in meiner eigenen EXE herausfinden ohne den @ Operator zu verwenden. Wie kann ich sowas realisieren? Kann ich irgendwie mit Assembler tricksen, sodass ich die betreffende Funktion aufrufe und in dieser irgendwie CS:IP ermittele? Gruß |
Re: Adresse einer Funktion ohne @ ermitteln (evtl über CS:IP
Hoppla, wozu brauchst du das denn? Und inwiefern kannst du die Funktion verändern?
|
Re: Adresse einer Funktion ohne @ ermitteln (evtl über CS:IP
Ich kann in die Funktion alles reinschreiben was ich möchte. In dem speziellen Szenario, welches ich habe, funktioniert der @ Operator im Bezug auf Funktionsadressen unter Vista nicht korrekt.
CreateThread mit @ThreadProc als dritten Parameter schlägt fehlt. GetLastError liefert mir ERROR_BAD_EXE_FORMAT. Daher suche ich nun nach Alternativen .. sowas wie @Array[0] hingegen z.b. unter Verwendung von CopyMemory funktioniert allerdings wunderbar .. |
Re: Adresse einer Funktion ohne @ ermitteln (evtl über CS:IP
:gruebel:
Und was hat das mit Vista zu tun? Das @ wird vom Compiler umgesetzt. Er weis ja, an welche Stelle er die Funktion geschrieben hat. Was machst du genau? Der üblich Weg innerhalb der Funktion ist so:
Delphi-Quellcode:
..aber das passt nicht ganz zu dem beschriebenen Problem :wiejetzt: .
function xyz
asm call @@n //dadurch landet die Rücksprungadresse auf dem Stack (diese zeigt auf den nächsten Befehl "pop eax") @@n: pop eax //Adresse vom Stack holen add eax,-5 //und zurückrechnen auf den Anfang der Funktion ... //weiter im Text end; |
Re: Adresse einer Funktion ohne @ ermitteln (evtl über CS:IP
Mit Vista hat es insofern zu tun, dass es nur dort nicht mit dem @ Funktioniert. Das Szenario ist folgendes: Ich habe ein Programm, welches ich nach dem Prinzip von Nicos InMemExe direkt aus einer Resource starte.
Rufe ich in diesem unter XP CreateThread auf, wird der Thread ganz normal gestartet, wie es sein sollte. Rufe ich nun CreateThread unter Vista auf, wird ERROR_BAD_EXE_FORMAT von GetLastError zurückgegeben. Deshalb dachte ich, könnte man die Adressen der Funktionen erst mit einem einfachen Aufruf [ThreadProc(nil)] ermitteln, in einer globalen Variable speichern und dann die Adresse an CreateThread übergeben .. Edit: Grade mal getestet. Die Adresse wird korrekt ermittelt, der Aufruf von CreateThread schlägt leider immer noch fehl =/ |
Re: Adresse einer Funktion ohne @ ermitteln (evtl über CS:IP
Zitat:
|
Re: Adresse einer Funktion ohne @ ermitteln (evtl über CS:IP
Zitat:
Vielleicht wurde einfach nur CreateThread modifizert. Wenn jemand ein Beispiel zum Aufruf von NtCreateThread hätte, würde mir das vielleicht weiterhelfen. |
Re: Adresse einer Funktion ohne @ ermitteln (evtl über CS:IP
Hast du auch mal gesehen ob der Anfang der Funktion wirklich der Anfang ist. Manchmal (also bei längeren Funktionen) packt der Compiler noch einiges davor.
Edit: Hast du mal die ImageBase überprüft? |
Re: Adresse einer Funktion ohne @ ermitteln (evtl über CS:IP
Ja, starte ich die EXE auf normale Weise funktioniert das CreateThread. Das sollte also nicht der Fehler sein. Was muss ich bei der ImageBase beachten?
Versuch mit NtCreateThread (Alle nativen Funktionen schlagen fehl -.- Ich weiß aber auch nicht genau, was ich da alles initialisieren muss und vor allem wie ..):
Delphi-Quellcode:
function ThreadProc(P: Pointer): Cardinal; stdcall;
begin MessageBox(0, 'Thread', 'Info', MB_SYSTEMMODAL); end; procedure DoCreateThread; const THREAD_TERMINATE = $0001; THREAD_SUSPEND_RESUME = $0002; THREAD_GET_CONTEXT = $0008; THREAD_SET_CONTEXT = $0010; THREAD_SET_INFORMATION = $0020; THREAD_QUERY_INFORMATION = $0040; THREAD_SET_THREAD_TOKEN = $0080; THREAD_IMPERSONATE = $0100; THREAD_DIRECT_IMPERSONATION = $0200; THREAD_SET_LIMITED_INFORMATION = $0400; THREAD_QUERY_LIMITED_INFORMATION = $0800; THREAD_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $03FF; var ThreadHandle: Cardinal; DesiredAccess: Cardinal; ObjectAttributes: OBJECT_ATTRIBUTES; ProcessHandle: Cardinal; ClientID: CLIENT_ID; ThreadContext: CONTEXT; UserStack: USER_STACK; CreateSuspended: Boolean; P: Pointer; begin DesiredAccess := THREAD_ALL_ACCESS; ObjectAttributes.Length := SizeOf(OBJECT_ATTRIBUTES); ObjectAttributes.RootDirectory := 0; ObjectAttributes.ObjectName := nil; ObjectAttributes.Attributes := 0; ObjectAttributes.SecurityDescriptor := nil; ObjectAttributes.SecurityQualityOfService := nil; ProcessHandle := GetCurrentProcess; FillChar(ThreadContext, SizeOf(CONTEXT), 0); ThreadContext.Eip := Longint(@ThreadProc); UserStack.FixedStackLimit := Pointer($1000000); UserStack.FixedStackBase := Pointer($1000000); if not NT_SUCCESS(NtAllocateVirtualMemory(ProcessHandle, @UserStack.ExpandableStackBottom, 0, UserStack.FixedStackLimit, MEM_RESERVE, PAGE_READWRITE)) then begin MessageBox(0, 'NtAllocateVirtualMemory1 failed', '', 0); end; UserStack.ExpandableStackBase := Pointer(Cardinal(UserStack.ExpandableStackBottom) + Cardinal(UserStack.FixedStackLimit)); UserStack.ExpandableStackLimit := Pointer(Cardinal(UserStack.ExpandableStackBase) - Cardinal(UserStack.FixedStackBase)); if not NT_SUCCESS(NtAllocateVirtualMemory(ProcessHandle, UserStack.ExpandableStackLimit, 0, UserStack.FixedStackBase, MEM_RESERVE, PAGE_READWRITE)) then begin MessageBox(0, 'NtAllocateVirtualMemory2 failed', '', 0); end; if not NT_SUCCESS(NtCreateThread(@ThreadHandle, DesiredAccess, @ObjectAttributes, ProcessHandle, @ClientID, @ThreadContext, @UserStack, CreateSuspended)) then begin MessageBox(0, 'NtCreateThread failed', '', 0); end; end; |
Re: Adresse einer Funktion ohne @ ermitteln (evtl über CS:IP
ERROR_BAD_EXE_FORMAT tritt zum Beispiel auf wenn eine 32-Bit-Anwendung auf Vista x64 eine 64-Bit-DLL anzieht (anziehen will).
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:15 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz