Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi EXE Patchen (nichts illegales!!) (https://www.delphipraxis.net/105795-exe-patchen-nichts-illegales.html)

hedie 30. Dez 2007 11:31


EXE Patchen (nichts illegales!!)
 
Hallo

Ich habe mir mal ein CrackME heruntergeladen

Nun habe ich es geschafft, es zu Patchen. Nun wollte ich mir auch einen Patch
in Delphi schreiben, jedoch habe ich bei der Suche nichts Gefunden

Wenn ich mich geirrt haben sollte, dann schreibt doch kurz den Link... Danke


Ansonsten:

Ich habe die Adresse, es soll einfach mit NOP's gepatcht werden

Liebe grüsse
Claudio

Daniel 30. Dez 2007 11:40

Re: EXE Patchen (nichts illegales!!)
 
Du hast also das Offset in der EXE-Datei, das Du verändern möchtest und fragst Dich nun, wie das geht?

(1) TFileStream oder meinetwegen auch die Klassiker "AssignFile()", "Reset()", "Seek()", "Write()" und "Close()". (Siehe Delphi-Hilfe).

(2) Bleibt die Frage, wie die binäre Repräsentation von NOP ausschaut, sprich: Welches Byte Du da zu schreiben hast.

ErazerZ 30. Dez 2007 11:43

Re: EXE Patchen (nichts illegales!!)
 
Also als erstes, Datei im Speicher laden, mittels CreateFile, und dann ReadFile bei einem Zeiger einlesen oder sonstiges.
Danach einfach z.b. mit
Delphi-Quellcode:
PWord(Cardinal(lpBuffer) + Offset)^ := $90; // $90 = nop
den Wert an der bestimmten Adresse ändern.
Wenns RVA hast, dann musst du es in den FileOffset umwandeln. Danach einfach mittels WriteFile, den Pointer (lpBuffer) in einer Datei schreiben.

hedie 30. Dez 2007 11:47

Re: EXE Patchen (nichts illegales!!)
 
Danke für die Antworten...

Ok ich hab das mal im ansatz verstanden.. aber wörter wie FileOffset sind neu für mich :D


Ich habe einfach das hier

Code:
004012AF    75 1F         JNZ SHORT crackme2.004012D0
Diese Zeile soll durch NOP's ersetzt werden

Bei OllyDbg werden 2 zeilen NOP's gesetzt, ist das, weil dieser Befehl 2 Takte braucht?

Ist das mit dem oben genannten vorgang möglich?

Mao 30. Dez 2007 11:51

Re: EXE Patchen (nichts illegales!!)
 
Nein, das hat mit der Anzahl der benötigten Takte für einen Befehl nix zutun. Nur mit der Größe der gespeicherten Information, also der Repräsentation des Codes in für die CPU lesbarer Binärform. Und die braucht hier 2 Bytes.

/Ergänzung:
Du müsstest also auch 2 NOPs schreiben.

Balu der Bär 30. Dez 2007 12:11

Re: EXE Patchen (nichts illegales!!)
 
Leicht Offtopic: Es gibt fertiges Tools die dir sowas ohne weiteres zutun erledigen. Du gibts die ungepatchte EXE an, die gepatchte und das Programm erstellt den Patch von alleine. Müsste was in Richtung (diablo2oo2's Universal Patcher [dUP]) gehen.

ErazerZ 30. Dez 2007 12:21

Re: EXE Patchen (nichts illegales!!)
 
Ich habe hier mal was ganz schnell zusammengeschrieben, sollte funktionieren. Du musst halt den FileOffset zuerst mittels RvaToFileOffset umwandeln, also falls du Virtuelle Adressen benutzts.
Delphi-Quellcode:
function LoadFile(const sFilename: string; var lpBuffer: Pointer; var dwFileSize: Cardinal): Boolean;
var
  hFile: THandle;
  lpNumberOfBytesRead: Cardinal;
begin
  Result := False;
  hFile := CreateFile(PAnsiChar(sFilename), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
  if (hFile <> INVALID_HANDLE_VALUE) then
  begin
    dwFileSize := GetFileSize(hFile, nil);
    if (dwFileSize > 0) then
    begin
      GetMem(lpBuffer, dwFileSize);
      Result := ReadFile(hFile, lpBuffer^, dwFileSize, lpNumberOfBytesRead, nil) and (lpNumberOfBytesRead = dwFileSize);
    end;
    CloseHandle(hFile);
  end;
end;

function SaveFile(const sFilename: string; var lpBuffer: Pointer; var dwFileSize: Cardinal): Boolean;
var
  hFile: THandle;
  lpNumberOfBytesWritten: Cardinal;
begin
  Result := False;
  hFile := CreateFile(PAnsiChar(sFilename), GENERIC_WRITE, FILE_SHARE_WRITE, nil, CREATE_ALWAYS, 0, 0);
  if (hFile <> INVALID_HANDLE_VALUE) and (dwFileSize > 0) then
  begin
    Result := WriteFile(hFile, lpBuffer^, dwFileSize, lpNumberOfBytesWritten, nil) and (lpNumberOfBytesWritten = dwFileSize);
    CloseHandle(hFile);
  end;
end;

function RvaToFileOffset(var lpBuffer: Pointer; dwRva: Cardinal): Cardinal;
var
  ImageDosHeader: PImageDosHeader;
  ImageNtHeaders: PImageNtHeaders;
  ImageSection: PImageSectionHeader;
  x: Word;
begin
  Result := 0;
  ImageDosHeader := PImageDosHeader(Cardinal(lpBuffer));
  if (ImageDosHeader^.e_magic = IMAGE_DOS_SIGNATURE) then
  begin
    ImageNtHeaders := PImageNtHeaders(Cardinal(lpBuffer) + Cardinal(ImageDosHeader._lfanew));
    if (ImageNtHeaders^.Signature = IMAGE_NT_SIGNATURE) then
    begin
      if (dwRva > ImageNtHeaders^.OptionalHeader.ImageBase) then
        dwRva := dwRva - ImageNtHeaders^.OptionalHeader.ImageBase;
      for x := 0 to ImageNtHeaders^.FileHeader.NumberOfSections -1 do
      begin
        ImageSection := PImageSectionHeader(Cardinal(lpBuffer) + Cardinal(ImageDosHeader^._lfanew) + SizeOf(TImageNtHeaders) + (x * SizeOf(TImageSectionHeader)));
        if (dwRva >= ImageSection.VirtualAddress) and (dwRva < ImageSection.VirtualAddress + ImageSection.SizeOfRawData) then
        begin
          Result := dwRva - ImageSection.VirtualAddress + ImageSection.PointerToRawData;
          Break;
        end;
      end;
    end;
  end;
end;

procedure UpdateOffset(var lpBuffer: Pointer; dwFileOffset: Cardinal; Value: Byte); overload;
begin
  PByte(Cardinal(lpBuffer) + dwFileOffset)^ := Value;
end;

procedure UpdateOffset(var lpBuffer: Pointer; dwFileOffset: Cardinal; Value: Word); overload;
begin
  PWord(Cardinal(lpBuffer) + dwFileOffset)^ := Value;
end;

procedure UpdateOffset(var lpBuffer: Pointer; dwFileOffset: Cardinal; Value: DWORD); overload;
begin
  PDWORD(Cardinal(lpBuffer) + dwFileOffset)^ := Value;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  lpBuffer: Pointer;
  dwFileSize, dwFileOffset: Cardinal;
begin
  if LoadFile('C:\z.exe', lpBuffer, dwFileSize) then
  begin
    dwFileOffset := RvaToFileOffset(lpBuffer, $0040104E);
    UpdateOffset(lpBuffer, dwFileOffset, $90909090);
    SaveFile('C:\z2.exe', lpBuffer, dwFileSize);
    FreeMem(lpBuffer, dwFileSize);
  end;
end;

hedie 30. Dez 2007 12:54

Re: EXE Patchen (nichts illegales!!)
 
Ok hab das jetzt einfach mal frech direkt Üernommen....

Es erstellt eine neue EXE und diese ist auch gepatcht :D :D :D

Ich werde den Code noch genau Studieren... Aber eins könntest du mir sagen, was hat es mit der zweiten adresse aufsich?

Was genau meinst du mit Umwandeln und fals ich Virtuelle Adressen benutze?

ErazerZ 30. Dez 2007 13:00

Re: EXE Patchen (nichts illegales!!)
 
Virtuelle Adresse ist die Adresse die du mit z.B OllyDbg siehst. Das ist die Adresse wo die Datei im Speicher liegt (0x0401000, etc.)
File Offset ist die Adresse in der Datei. Und da wir die Datei in unserem Speicher einfach nur eingelesen haben müssen wir FileOffset nutzten um es zu patchen.

hedie 30. Dez 2007 13:02

Re: EXE Patchen (nichts illegales!!)
 
Ok

Also wenn ich deinen Code 1:1 übernehme, dan funktioniert er nicht, ich musste zuerst die erste

Adresse richtig stellen (auf die die ich oben gepostet hab)

Danach hats geklappt :D

sirius 30. Dez 2007 13:04

Re: EXE Patchen (nichts illegales!!)
 
Du solltest dir mal dringend ansehen, wie das Exe-Format aussieht. Prinzipiell wichtig für dich jetzt erstmal ist zu wissen, dass die EXE in sogenannte Sections unterteilt sind. Das ind einfach zusammenhängende Teile von Code oder Daten (und noch anderes). diese Teile werden (meist) 1:1 in deinen virtuellen Adressraum kopiert (was z.B. deiner Adresse "004012AF" entspricht) Wo der Teil landet steht in den Headern zu jeder Section. Also z.B. so:
Section 1 steht in der Datei ab Byte $3000 (das wäre das FileOffset) und wird in den Virtuellen Adressraum ab Byte $00401000 kopiert und es ist 1024 Bytes lang.
Daraus kannst du jetzt zurückrechnen, wo deine zu patchenden Bytes in welcher Section und damit an welchem FileOffset liegen. Besipielcode steht bereits oben (ob der richtig, weis ich nicht; gibts auch noch mehrmals in der DP)

Edit: Aber ganz so einfach sind die PE-Header nicht aufgebaut. Prinzipiell musst du dir aber die oben genannten Informationen zusammensuchen und zusammenrechnen.

hedie 30. Dez 2007 13:14

Re: EXE Patchen (nichts illegales!!)
 
Ok Danke für diese einleitende info

Aber es ist doch grundsätzlich möglich, wie ich es jetzt gemacht hab, ein Programm in OllyDbg zu laden
und die Adresse herauszufinden, diese dan in mein Delphi Programm schreiben und gut is (vorausgesetzt das es NOP's braucht)

Und nochwas...

Mit diesem "grundcode" kann ich ja praktisch jede EXE beliebig Patchen....

Wenn ich nun anstelle des NOP's zb was anderes haben möchte, was muss ich dan wie ändern?

Also $90; // $90 = nop aber woher weiss ich was die anderen sind?


Entschuldige mich jetzt schon für alfällige genervte gemüter :D

Mao 30. Dez 2007 13:20

Re: EXE Patchen (nichts illegales!!)
 
Einfachste Möglichkeit wäre in meinen Augen, den entsprechenden Code zu assemblieren und mit einem Hex-Editor wieder auszulesen. :stupid:
Oder du gehst den Weg über die Dokumentationen von Intel, was dann der Professionellere wäre.

hedie 30. Dez 2007 13:21

Re: EXE Patchen (nichts illegales!!)
 
Jo stimmt.. hast recht

Ich werd mal n bissel experimentieren...

Danke an alle die geholfen haben

ErazerZ 30. Dez 2007 13:22

Re: EXE Patchen (nichts illegales!!)
 
Benutz OllyDbg um die Hex-Codes rauszufinden. Einfach Leertaste im CPU fenster drücken, danach deinen Assembler befehl z.B mov eax, dword ptr [0x12345678] und Enter und dann siehst du die Hex-Codes wie zum Beispiel:
Zitat:

00401054 A1 78563412 MOV EAX,DWORD PTR DS:[12345678]
Wie dir aufgefallen ist, ist hier der Befehl 0xA1, und der Rest ist die Adresse (78563412 - verkehrt gelesen heißt es 12 34 56 78). Die Virtuelle Adresse ist natürlich 00401054.

sirius 30. Dez 2007 13:42

Re: EXE Patchen (nichts illegales!!)
 
Zitat:

Zitat von hedie
Mit diesem "grundcode" kann ich ja praktisch jede EXE beliebig Patchen....

Wenn ich nun anstelle des NOP's zb was anderes haben möchte, was muss ich dan wie ändern?

Naja, irgendwie müssen ja auch die Compiler/Assembler wissen wie sie den Code für den Prozessor (und das BS) vorbereiten.
Grundlegend zu Intel-Architektur wäre ja diese Seite zu empfehlen. Aber bevor du hier fließend IA-32 oder IA-64 beherrschst kannst du erstmal einfach in Debuggern schauen, wie welche Befehle als OpCode aussehen.

hedie 30. Dez 2007 16:41

Re: EXE Patchen (nichts illegales!!)
 
Gut Danke für den Link

Ich hätte noch ne Frage zum "grundcode"

Wo steht da das $90 = NOP ?

Habs nirgends gefunden... ich will eben nun bei einer adresse , wo 74 49 steht 75 49 hinmachen....

grüsschen

sirius 31. Dez 2007 10:23

Re: EXE Patchen (nichts illegales!!)
 
Die Manuals sind auch nicht einfach zu lesen.
Die Erklärung zu NOP findest du im "Architectures Software Developer's Manual
Volume 2B: Instruction Set Reference, N-Z" auf Seite 7. Oder im selben Dokument in der OpCodeMap auf Seite 600.

Zitat:

Habs nirgends gefunden... ich will eben nun bei einer adresse , wo 74 49 steht 75 49 hinmachen....
:gruebel: und was hilft dir dabei zu wissen wo in den Manuals NOP erklärt wird?

hedie 31. Dez 2007 10:31

Re: EXE Patchen (nichts illegales!!)
 
Nee ich mein nicht wo in den Manuals NOP erklärt is sondern wo im
geposteten Code NOP steht

Also wie muss ich den geposteten code abändern damit anstelle von nop

74 49 in 75 49 umgewandelt wird....

Und noch ne frage....

Wen ich in OllyDbg EB 21 eingebe, dan bedeutet das JMP 00401044 die adresse wo JMP steht is 00401021

Weshalb is 21 die adresse 00401044 ?

Danke schonmal :D

Apollonius 31. Dez 2007 10:45

Re: EXE Patchen (nichts illegales!!)
 
Das ist ein Jump relativ zur derzeitigen Adresse: Der Befehl selbst ist zwei Byte lang (=vier hexadezimale Ziffern) und dazu nochmal 21 drauf, dann kommst du auf die neue Adresse.

hedie 31. Dez 2007 10:51

Re: EXE Patchen (nichts illegales!!)
 
Also seh ich das richtig?

EB = 235
21 = 33

235 + 33 = 268 // Ist das irgendwie relativ zur adresse?

Und wie siehts aus mit der grundcode frage? :D

Danke

Apollonius 31. Dez 2007 10:57

Re: EXE Patchen (nichts illegales!!)
 
EB = Opcode für einen relativen Jump mit bestimmten Operanden

EB21 ist zwei Bytes lang => Der Befehl endet an der Adresse $00401021 + 2 = $00401023
Gejumpt wird $21 vorwärts, also von $00401023 auf $00401023 + $21 = $00401044.

hedie 31. Dez 2007 10:58

Re: EXE Patchen (nichts illegales!!)
 
Wahnsinn :D Du kannst das ja zuper erklären

Jetzt hab ichs verstanden Danke

gut damit wäre dieser Thread wohl abgeschlossen :D


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:27 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