Einzelnen Beitrag anzeigen

Benutzerbild von arcticwolf
arcticwolf

Registriert seit: 3. Aug 2021
Ort: Erfurt
41 Beiträge
 
Delphi 11 Alexandria
 
#13

AW: RTL Fehler beheben - System.pas

  Alt 10. Okt 2023, 16:10
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.
Wolfgang
coding is an art - code for people not for machines
  Mit Zitat antworten Zitat