2012-03-29 14 views
2

Das ist mein Arbeits-CodeDelphi 7 Write

DriftMul:=99; 
    WriteProcessMemory(HandleWindow, ptr($4E709C), @DriftMul, 2, Write); 

ich möchte es konvertieren, ohne eine Variable zu verwenden, aber es wird nicht funktionieren Unten ist nur ein Beispiel von dem, was ich tun möchte.

WriteProcessMemory(HandleWindow, ptr($4E709C), ptr(99), 2, Write); 

Kennt jemand eine Möglichkeit, diese Arbeit mit der Verwendung einer Variable zu machen ??? Ich kann in ein paar Sprachen programmieren und jede Sprache, die ich benutze, ist eine Möglichkeit, dies zu tun. Der Grund, warum ich das machen möchte, ist, weil ich ein großes Programm machen werde, das viele verschiedene Werte schreibt und es wird mir mehr als 300 Zeilen sparen. Unten ist ein Beispiel in C++, das ich benutzt habe.

WriteProcessMemory(hProcess, (void*)0x4E709C, (void*)(PBYTE)"\x20", 1, NULL); 

Update: Gelöst es Im 4 Verfahren verwenden, die ich nenne, je nachdem, wie viele Bytes ich will schreiben.

procedure Wpm(Address: Cardinal; ChangeValues: Byte); 
Begin 
WriteProcessMemory(HandleWindow, Pointer(Address), @ChangeValues, 1, Write); 
End; 
procedure Wpm2(Address: Cardinal; ChangeValues: Word); 
Begin 
WriteProcessMemory(HandleWindow, Pointer(Address), @ChangeValues, 2, Write); 
End; 
procedure Wpm3(Address: Cardinal; ChangeValues: Word); 
Begin 
WriteProcessMemory(HandleWindow, Pointer(Address), @ChangeValues, 3, Write); 
End; 
procedure Wpm4(Address: Cardinal; ChangeValues: Cardinal); 
Begin 
WriteProcessMemory(HandleWindow, Pointer(Address), @ChangeValues, 4, Write); 
End; 

Beispiel schreibt

Wpm($477343,$EB); 
Wpm2($40A889,$37EB); 
Wpm3($416E34,$0086E9); 

Pchar die einzige Methode, i ohne Verfahren kompilieren gefunden, ich möchte nicht, obwohl die Verwendung assci.

WriteProcessMemory(HandleWindow, Pointer($449A17), PChar('90'), 1, Write); 
+0

„Warum hat der obige Code 43, obwohl schreiben ??“ Du meinst "$ 43". Nun, was ist der ASCII-Code für 'C'? Und warum benutzt du 'C3', wenn du nur ein einzelnes Byte schreibst? Was ist der Punkt des zweiten Bytes? Warum nicht "C" verwenden? –

+0

mit meinem Konverter im bekommen 99 – Tprice88

+0

Können Sie erklären, wo 99 herkommt, woher C3 kommt und was Sie erwarten? Ich muss gestehen, dass ich verrückt bin, dass du deinen Code gerne so verschleiern würdest. –

Antwort

6

Sie müssen den Inhalt des Wortes speichern, das Sie irgendwo schreiben. WriteProcessMemory erwartet einen Zeiger auf Speicher in Ihrem Prozessbereich. Wenn Sie keine Variable verwenden möchten, verwenden Sie eine Konstante.

const 
    DriftMul: word=99; 
.... 
WriteProcessMemory(HandleWindow, ptr($4E709C), @DriftMul, 2, Write); 

Passing ptr(99) schlägt fehl, da ptr(99) kein Zeiger auf ein Wort ist, den Wert enthält 99. Es ist ein Zeiger auf Adresse 99. Ich glaube, Sie haben versucht, @Word(99) zu schreiben, aber Sie können nicht die Adresse einer wahren Konstante nehmen.

Sie können dies bequemer machen, indem Sie den Aufruf an WriteProcessMemory in einer Hilfsmethode beenden. Obwohl Ihre Frage darauf hinweist, dass Sie Word Werte schreiben möchten, wurde es in Ihrem langen Chat offensichtlich, dass Sie Bytefolgen tatsächlich schreiben möchten. Das Schreiben ganzzahliger Datentypen führt zu einer Verwirrung der Endlichkeit der Maschine. Also würde ich es stattdessen mit einem offenen Array von Byte tun, um die Flexibilität an der Call-Site zu geben.

procedure WriteBytes(hProcess: THandle; Address: Pointer; 
    const Buffer: array of Byte); 
var 
    NumberOfBytesWritten: DWORD; 
begin 
    if not WriteProcessMemory(hProcess, Address, @Buffer[0], Length(Buffer), 
    NumberOfBytesWritten) then RaiseLastOSError; 
end; 

Sie können dann rufen Sie den Code

WriteBytes(Handle, Pointer($523328), [$42]);//single byte 
WriteBytes(Handle, Pointer($523328), [$CC, $90, $03]);//3 bytes 
+0

Also in Delphi gibt es keine Möglichkeit zu schreiben, ohne den Wert irgendwo zu speichern? – Tprice88

+0

Es gibt keine Möglichkeit, einen Zeiger auf ein Wort, das einen Wert enthält, zu erstellen, ohne einen Platz zum Speichern zu haben, so wie er es gesagt hat. –

+0

was ist mit einem Byte oder einem int. Für die Adresse müssen Sie sie irgendwo speichern, also sollten sie auch für die Bytes sein. – Tprice88

2

Die PTR() Methode umwandelt, um eine Adresse zu einem Zeiger. So wird der Wert in der zweiten Methode ist nicht 99, sondern der Wert, der an der Adresse geschrieben 99.

Meine schmutzige Methode, aber mit wenigen Zeilen Code:

procedure WriteBytes(hProcess: THandle; address: Pointer; buffer: Variant; count: Integer); 
begin 
    WriteProcessMemory(hProcess, address, @buffer, count, nil); 
end; 

Dann können Sie die Methode aufrufen, mit :

WriteBytes(HandleWindow, Pointer($449A17), 90, 1); 
+0

Wie kann das funktionieren? Das erste Byte einer Variante ist nicht die Nutzlast. –

+0

In diesem Fall wird die Variante als Integer behandelt. Wenn das LSB in dem ersten Byte ist, sollte es funktionieren, wenn nicht einer den Wert konvertieren muss, damit es passt. Es ist eine dreckige Methode, die ich auch nicht benutzen möchte, aber wenn es das Ziel ist, möglichst kleine Codezeilen zu bekommen, kann man damit arbeiten. – riv333

+0

Das erste Byte einer Variante ist nicht die Nutzlast. Es ist die Typinformation. –

2

In C++, dieser Code:

WriteProcessMemory(hProcess, (void*)0x4E709C, (void*)(PBYTE)"\x20", 1, NULL); 

Ist die Vereinbarkeit eines const char[] Puffer im Speicher der Anwendung, die die beiden Zeichen enthält '\x20' und '\x00' drin. Dies wird durch die Verwendung der doppelten Anführungszeichen " um das Literal ersichtlich. Sie erstellen ein Zeichenfolgenliteral, kein Zeichenliteral (das stattdessen ' Anführungszeichen verwendet). Die Anfangsadresse des ersten Zeichens dieses Literals wird an den dritten Parameter übergeben, und der vierte Parameter wird an 1 gesetzt, um WriteProcessMemory() mitzuteilen, nur 1 Byte von diesem 2-Byte-Puffer zu kopieren.

Delphi, auf der anderen Seite, verwendet das ' einfache Anführungszeichen Zeichen sowohl für Einzel- als auch Zeichenfolgenliterale, und damit hängt Code Context, um zu entscheiden, welche Art von Literal erstellt werden muss. Daher verfügt Delphi nicht über ein direktes Mittel zum Deklarieren eines aus einem Zeichen bestehenden Literals, das dem inline-Code char[] wie im C++ - Code entspricht. Die nächstgelegene equivilent ich jetzt denken kann, ohne eine Konstante erklärt, wäre so etwas wie dies:

WriteProcessMemory(hProcess, Pointer($4E709C), PAnsiChar(AnsiString(' ')), 1, nil); 

Andernfalls verwenden Sie nur eine explizite Konstante statt. Die direkte equivilent dessen, was der C++ Code tut, ist die folgende:

const 
    buffer: array[0..1] of AnsiChar = (#$20, #0); 

WriteProcessMemory(hProcess, Pointer($4E709C), Pointer(PByte(@buffer[0])), 1, nil); 

Alternativ können Sie an folgende Vereinfachung:

const 
    space: Byte = $20; 

WriteProcessMemory(hProcess, Pointer($4E709C), @space, 1, nil); 
+0

Schön die Methode, die Sie gemacht haben funktioniert tatsächlich, ich hatte ein Problem obwohl. 'WriteProcessMemory (HandleWindow, Pointer ($ 449A17), PAnsiChar (AnsiString ('C3')), 1, Write)' Warum würde das 43 – Tprice88

+0

@ Tprice88 machen, bevor Sie zu aufgeregt werden, fragen Sie sich einfach, wie Sie kodieren werden zum Beispiel Bytes mit dem Wert <32. –

+0

@Remy Warum 'Zeiger (PByte (@buffer [0]))'? Warum nicht '@buffer [0]'? –