AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Offset bei AllocMem?

Ein Thema von Plastewolf · begonnen am 20. Sep 2013 · letzter Beitrag vom 24. Sep 2013
Antwort Antwort
Plastewolf
(Gast)

n/a Beiträge
 
#1

AW: Offset bei AllocMem?

  Alt 21. Sep 2013, 19:31
Wenn ich das mit dem VirtualProtect jetzt richtig gesehen habe, müsste ich den Befehl also insgesamt 4x ausführen und dabei als ersten Parameter den Offset, dann die Größe des Bereiches gefolgt von der gewünschten Operation und schlussendlich einen willkürlichen Parameter der einfach nur dafür da ist die Voreinstellung zu sichern.


Der erste Code läuft also von 42053B bis 42053F was einer größe von 4 entspricht.

Delphi-Quellcode:

Code := StrToHex('MOV EDX,OFFSET '+NewOffset);

VirtualProtect('$42053B', 4, PAGE_EXECUTE_READWRITE, OldProtect);
PByte($0042053B)^ := Code;

Edit:

Ach entschuldige bitte mein Kopf ist heute scheinbar nichtmehr so ganz auf der Höhe... PByte kann ja logisch auch nur das Byte schreiben, das dann natürlich vorraussetzt das ich die Hex werte Pärchenweise übergeben müsste...

Geändert von Plastewolf (21. Sep 2013 um 19:39 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#2

AW: Offset bei AllocMem?

  Alt 21. Sep 2013, 19:42
Halbwegs. Du musst dir jetzt einfach die genauen Offsets raussuchen, an denen die Adresse steht. Du brauchst ja auch nicht die kompletten Instructions überschreiben. Es reicht ja die (4 Byte lange) Adresse.

Wenn du die genauen Offsets hast, wendest du darauf jeweils einmal VirtualProtect an und schreibst dann mit PDWord(OFFSET)^ := NEWADDRESS die neue Adresse rein.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Plastewolf
(Gast)

n/a Beiträge
 
#3

AW: Offset bei AllocMem?

  Alt 21. Sep 2013, 20:09
Ich glaube ich habe das noch nicht zu 100% verstanden.

Delphi-Quellcode:
procedure Grafikspeicher();
var
  Offset : String;
  Memory : Pointer;
  OldProtect : Cardinal;

begin
   Memory := AllocMem(16777216);
  try
    Offset := IntToHex(DWord(Memory), 8);
    VirtualProtect('$0042053E', 4, PAGE_EXECUTE_READWRITE, OldProtect);
    PDWord($0042053E)^ := PDWORD(Offset)^;
  finally
    FreeMem(Memory);
    Showmessage('Es ist ein Fehler aufgetreten. Bitte starten Sie den Computer neu!');
  end;
end;
Der Bereich 0042053E-0042053F enthält das Offset zu der ersten Adresse. Ohne das VP spuckt er zwar keinen Fehler aus, änderte allerdings noch während der parallelen Überwachung mit OllyDbg nicht den gewünschten Bereich. Wenn ich es mit der VirtualProtect Variante versuche sagt er mir nur das es keine überladene Version geben würde, was unzweifelhaft daran liegt das ich den Pointer falsch übergeben habe. Vielleicht kann man den gesamten Bereich des Programmes von anfang an auf RW setzen?



Edit:

Ich habe gerade Bemerkt das es scheinbar doch funktioniert, es gab ein Problem mit dem Injector. Jedoch kommt nach der Injection eigentlich nur Datenmüll heraus, da er auf das Offset MOV EDX,37E170 schreibt, welches den Direct3D Header initialisiert.

Edit2:

Also ich hatte mich bei dem Offset verrechnet. Das korrekte Offset lautete "0042053C - 0042053F". Wenn ich des jetzt über PDword schreiben lasse kommt folgendes heraus: "MOV EDX,00450037". Obwohl der Rückgabewert für den neuen Speicher hier liegen müsste: "7EEA0010". Ich finde irgentwie den Fehler nicht...

Edit3:

Alles klar ich habe das Problem nun selbst gelöst. Mein Ansatz war falsch, ich hätte mich nie auf den String Wert Offset beziehen dürfen sondern direkt den DWORD Wert von Memory nehmen sollen. Jetzt sollte es Funktionieren. Fraglich ist aber warum er die Messagebox aus dem Finally bereich auslöst.

Vielen Dank nochmals für deine Hilfe!


Edit 4:

Das Problem ist doch noch nicht so gelöst wie ich es gerne hätte
Er reserviert zwar augenscheinlich Arbeitsspeicher und übergibt die Offset, welche jetzt auch korrekt geschrieben wird, aber wie sich gerade Rausstellt gibt es keinen freien Speicher auf der übergebenen Adresse. Irgentwie ist das übergebene Offset auch immer das gleiche, müsste das sich nicht eigentlich bei jedem Start ändern?

Geändert von Plastewolf (21. Sep 2013 um 21:30 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#4

AW: Offset bei AllocMem?

  Alt 21. Sep 2013, 21:19
Du schreibst einen String, welcher den HEX Wert des neuen Speicherbereiches enthält an eine Stelle, die für ein DWORD gedacht ist. Das kann doch nichts geben. Korrekt wäre folgendes:
PDWord($0042053E)^ := DWord(Memory); Den grade alloziierten Speicher direkt im finally Block wieder freizugeben, würde ich auch lassen, wenn du nicht willst, dass dein gepatchtes Programm beim Zugriff darauf crasht.

Darf ich fragen, um welches Spiel / Programm es sich handelt?
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Plastewolf
(Gast)

n/a Beiträge
 
#5

AW: Offset bei AllocMem?

  Alt 21. Sep 2013, 21:38
Diese ganze WinApi Geschichte kostet ganz schön Nerven

Eigentlich dürfte der Finally Block doch nur dann ausgeführt werden wenn innerhalb der Try Schleife eine Exception ausgelöst wird oder irre ich mich da?
Edit: Ich habe gerade zur Sicherheit nochmals nachgelesen, ich habe mich also geirrt. Habe das ganze jetzt durch except ersetzt. Habe den Code von Bummi mit der Try Finally Schleife übernommen gehabt

Es handelt sich um das alte Spiel Krush Kill n Destroy 2 von 1997. Wenn man die Standartauflösung mittels eines HEX Editor Patches erhöht dann Crasht das ganze einfach. Das Problem war schnell gefunden da der Speicher fix vergeben wurde und so durch die erhöhung überschwappte. Ich möchte gerne einige Funktionen in meine DLL auslagern und damit ein paar Probleme lösen.
  Mit Zitat antworten Zitat
Plastewolf
(Gast)

n/a Beiträge
 
#6

AW: Offset bei AllocMem?

  Alt 24. Sep 2013, 18:08
Kann man eigentlich über den neu generierten Speicher irgentwie ASM Code ausführen?
In der EXE sind exakt 20 DB Werte deklariert. Ich würde gerne einen Jump befehl auf einen neu angelegten Speicher setzen und dann über

Delphi-Quellcode:
  
  ASM
    db ''
    db ''
    db ''
    [....]
  END;
ein paar extra DB Werte deklarieren.

Dann müsste ich ja eigentlich nur über den DWORD befehl das Call auf den neuen Speicher umlenken und dort den Code inkl. der erweiterten Werte 1:1 übernehmen+ erweitern.

Edit: Habe ich das richtig gesehen, man kann auch ohne die ASM Befehle einfach DWORD(Speicher) := 'Teststring'; schreiben?

Geändert von Plastewolf (24. Sep 2013 um 19:02 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#7

AW: Offset bei AllocMem?

  Alt 24. Sep 2013, 21:28
Hallo Plastewolf,

Ich will dir nicht zu Nah treten aber du wirst hier bei der Sache nicht weit kommen weil du scheinbar keinen Schimmer von ASM hast und was viel schlimmer ist keine Vorstellung vom Arbeitsspeicher hast und wie dort Werte oder auch Code gespeichert ist.

Code:
Code := StrToHex('MOV EDX,OFFSET '+NewOffset);

VirtualProtect('$42053B', 4, PAGE_EXECUTE_READWRITE, OldProtect);
PByte($0042053B)^ := Code;
Auch wenn du müde warst: Die Zeilen zeigen das ganz eindeutig. ASM sind keine Texte die im Arbeitsspeicher irgendwo stehen und dann ausgeführt werden. Du hast da eine vollkommen falsche oder gar keine Vorstellung von.
Such dir vllt. mal ein paar Tutorials zu dem Thema (hab grad mal kurz geguckt ob ich dir was raussuchen kann, hab aber auf die schnelle nichts gefunden).
Und dann schau dir vllt. mal eine .exe in einem Hex-Editor an. Du wirst du nicht viel erkennen/verstehen (können) außer vllt die Tatsache dass dort in der kompletten Datei keine
"mov eax, edx"-Strings o.ä. auftauchen.

Kurze Erklärung: Assembler Befehle sind auch nur Bytes (Zahlen) die im Speicher stehen. Wenn dort z.B. (ist nur Pseudeo-"Code" - habe jetzt nicht nachgeguckt wies wirklich wäre) folgendes steht

3E 00 0F

dann könnte das z.B. heißen

3E 00 0F
mov al, 15

wobei "3E" für den Prozessor dann z.B. bedeutet: jetzt kommt ein "mov"-Befehl. Die "00" bedeutet dann "Zielregister ist das Register mit dem Index 0 (-> AL)". und "0F" ist dann der Wert der in dieses Register geschrieben werden soll (also dezimal 15).

Generell musst du lernen/verstehen dass im Speicher überall nur Bytes stehen und der Prozessor notfalls auch deinen in er .exe gespeicherten Readme-Text als Befehle zu interpretieren versucht wenn er dort (fälschlicherweise) landen sollte. Genauso kann auch versucht werden Assembler-Code im Speicher als String interpretiert zu werden. Dabei kommt dann meistens im besten Fall irgendein Kauderwelsch raus.

Du kannst dir ggf. ja auch mal das Programm "OllyDbg" anschauen. Du wirst zwar überwältigt sein aber da siehst du dann auch beim genaueren hinschauen was ich mit dem oben geschriebenen gemeint habe.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es 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

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:04 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