I'm trying to port DDetours
lib to Delphi 5/7. The lines that wont compile have this pattern:
procedure Decode_J(PInst: PInstruction; Size: Byte);
var
Value: Int64;
VA: PByte;
begin
...
VA := PInst^.VirtualAddr + (PInst^.NextInst - PInst^.Addr) // <- compiler error
with compiler error:
[Error] InstDecode.pas(882): Operator not applicable to this operand type
PInst^.VirtualAddr, PInst^.NextInst, PInst^.Addr
are all declared as PByte
(PByte = ^Byte
)
What can I do to resolve this?
EDIT:
PInstruction
is defined as:
TInstruction = record
Archi: Byte; { CPUX32 or CPUX64 ! }
AddrMode: Byte; { Address Mode }
Addr: PByte;
VirtualAddr: PByte;
NextInst: PByte; { Pointer to the Next Instruction }
OpCode: Byte; { OpCode Value }
OpType: Byte;
OpKind: Byte;
OpTable: Byte; { tbOneByte,tbTwoByte,... }
OperandFlags: Byte;
Prefixes: Word; { Sets of Prf_xxx }
ModRm: TModRM;
Sib: TSib;
Disp: TDisplacement;
Imm: TImmediat; { Primary Immediat }
ImmEx: TImmediat; { Secondary Immediat if used ! }
Branch: TBranch; { JMP & CALL }
SegReg: Byte; { Segment Register }
Rex: TRex;
Vex: TVex;
LID: TInternalData; { Internal Data }
Errors: Byte;
InstSize: Byte;
Options: Byte;
UserTag: UInt64;
end;
PInstruction = ^TInstruction;
In newer Delphi versions, PByte
can be used in pointer arithmetic. Before that, the only type that could do that was PChar
(PAnsiChar
or PWideChar
). In Delphi 5, PChar
is a PAnsiChar
.
Now I know the structure of the record and know what you want to achieve, I think you should probably do the following.
You could change all PBytes
in TInstruction
to PAnsiChar
(or PChar
, if you only care about D5), and also all PBytes
in every routine. Then you get:
PInstruction = ^TInstruction;
TInstruction = record
Archi: Byte; { CPUX32 or CPUX64 ! }
AddrMode: Byte; { Address Mode }
Addr: PAnsiChar;
VirtualAddr: PAnsiChar;
NextInst: PAnsiChar; { Pointer to the Next Instruction }
...
end;
...
procedure Decode_J(PInst: PInstruction; Size: Byte);
var
Value: Int64;
VA: PAnsiChar;
begin
...
VA := PInst^.VirtualAddr + (PInst^.NextInst - PInst^.Addr);
...
But note that if you want to read or write a byte using these PAnsiChars
, you will have to cast them to PByte
.