Vielen Dank Stefan!
Es ist tatsächlich so, dass sich die Funktionen aus der System.pas, wie zum Beispiel "_WriteLong" oder "_WriteString", nicht direkt aufrufen lassen. Also habe ich es wie folgt versucht und das scheint auch zu funktionieren.
Delphi-Quellcode:
function GetWriteLongAddress: Pointer;
asm
{$ifdef CPU64}
mov rax,offset System.@WriteLong
{$else}
mov eax,offset System.@WriteLong
{$endif}
end;
function GetWriteStringAddress: Pointer;
asm
{$ifdef CPU64}
mov rax,offset System.@WriteString
{$else}
mov eax,offset System.@WriteString
{$endif}
end;
Ich möchte einen Fehler in der Funktion _WriteLong korrigieren:
Delphi-Quellcode:
function _WriteLong(var t: TTextRec; val, width: Integer): Pointer;
var
S: _ShortStr;
begin
// Str(val:0, S); Fehler
Str(Val:width, S); // Korrigiert
Result := _WriteString(t, S, width);
end;
Im Anschluß muss der richtige Wert wieder an die nicht direkt aufrufbare Funktion _WriteString aus der System.pas übergeben werden. Also dachte ich, nichts leichter als das und habe folgendes versucht:
Delphi-Quellcode:
Type TFuncWriteString = Function(var t: TTextRec; const s: ShortString; width: Integer) : Pointer;
Const FuncWriteString : TFuncWriteString = Nil;
// Fixed Function WriteLong form System.pas
function WriteLongFixed(var t: TTextRec; val, width: Integer): Pointer;
var
S: ShortString;
begin
Str(val:width, S);
Result := FuncWriteString(t, S, width);
end;
procedure RedirectFunction(OrgProc, NewProc: Pointer);
type
TJmpBuffer = packed record
Jmp: Byte;
Offset: Integer;
end;
var
n: UINT_PTR;
JmpBuffer: TJmpBuffer;
begin
JmpBuffer.Jmp := $E9;
JmpBuffer.Offset := PByte(NewProc) - (PByte(OrgProc) + 5);
if not WriteProcessMemory(GetCurrentProcess, OrgProc, @JmpBuffer, SizeOf(JmpBuffer), n) then
RaiseLastOSError;
end;
procedure ApplyPatch;
begin
FuncWriteString := GetWriteStringAddress;
RedirectFunction(GetWriteLongAddress, @WriteLongFixed);
end;
Bei folgender Zeile wirft der Compiler den Fehler "E2009 Inkompatible Typen: 'Liste der Parameter ist unterschiedlich'" aus.
FuncWriteString := GetWriteStringAddress;
Delphi-Quellcode:
// Aus System.pas
function _WriteString(var t: TTextRec; const s: _ShortStr; width: Integer): Pointer;
begin
Result := _WriteLString(t, s, width);
end;
// Meine Deklaration (siehe oben)
Function(var t: TTextRec; const s: ShortString; width: Integer) : Pointer;
Wobei _ShortStr nur ein Alias für ShortString ist. Ergo sehe ich das Problem nicht!?
FuncWriteString := @GetWriteStringAddress;
Funktioniert (lässt sich compilieren) und im Debug-Modus springt Delphi dann auch in meine Funktion WriteLongFixed (Redirect funktioniert also). Der Aufruf von FuncWriteString wird dann jedoch mit einem IoError 103 quittiert.
Wie muss ich die Funktion _WriteString aus der System.pas richtig aufrufen/addresieren, damit das funktioniert? Ich stehe auf dem Schlauch.