Delphi-PRAXiS
Seite 1 von 6  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Adresse einer Funktion ohne @ ermitteln (evtl über CS:IP) (https://www.delphipraxis.net/104996-adresse-einer-funktion-ohne-%40-ermitteln-evtl-ueber-cs-ip.html)

Zacherl 13. Dez 2007 21:16


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ß

Apollonius 13. Dez 2007 21:20

Re: Adresse einer Funktion ohne @ ermitteln (evtl über CS:IP
 
Hoppla, wozu brauchst du das denn? Und inwiefern kannst du die Funktion verändern?

Zacherl 13. Dez 2007 21:22

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 ..

sirius 14. Dez 2007 07:24

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:
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;
..aber das passt nicht ganz zu dem beschriebenen Problem :wiejetzt: .

Zacherl 14. Dez 2007 13:16

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 =/

Luckie 14. Dez 2007 13:18

Re: Adresse einer Funktion ohne @ ermitteln (evtl über CS:IP
 
Zitat:

Zitat von Zacherl
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.

Tja, dann funktioniert diese Technik unter Vista nicht mehr. Aber wozu brauchst du das überhaupt?

Zacherl 14. Dez 2007 13:24

Re: Adresse einer Funktion ohne @ ermitteln (evtl über CS:IP
 
Zitat:

Zitat von Luckie
Zitat:

Zitat von Zacherl
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.

Tja, dann funktioniert diese Technik unter Vista nicht mehr. Aber wozu brauchst du das überhaupt?

Schade, wenn es nicht mehr funktionieren würde. Ich möchte einen Updater entwickeln, der einfach die Resourcen updatet um laufende Programme on-thy-fly updaten zu können, ohne sie vorher zu beenden.
Vielleicht wurde einfach nur CreateThread modifizert. Wenn jemand ein Beispiel zum Aufruf von NtCreateThread hätte, würde mir das vielleicht weiterhelfen.

sirius 14. Dez 2007 13:39

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?

Zacherl 14. Dez 2007 13:53

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;

OldGrumpy 14. Dez 2007 20:58

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.
Seite 1 von 6  1 23     Letzte »    

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