如何处理 D5/D7 中的 PByte 指针操作(运算符不适用于此操作数类型)
How to handle PByte pointer operations in D5/D7 (Operator not applicable to this operand type)
我正在尝试将 DDetours
库移植到 Delphi 5/7。不会编译的行具有这种模式:
procedure Decode_J(PInst: PInstruction; Size: Byte);
var
Value: Int64;
VA: PByte;
begin
...
VA := PInst^.VirtualAddr + (PInst^.NextInst - PInst^.Addr) // <- compiler error
编译器错误:
[Error] InstDecode.pas(882): Operator not applicable to this operand
type
PInst^.VirtualAddr, PInst^.NextInst, PInst^.Addr
都声明为 PByte
(PByte = ^Byte
)
我该怎么做才能解决这个问题?
编辑:
PInstruction
定义为:
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;
下Delphi5,试试:
procedure Decode_J(PInst: PInstruction; Size: Byte);
var
Value: Int64;
VA: PByte;
begin
...
VA := PByte(integer(PInst^.VirtualAddr) + (integer(PInst^.NextInst) - integer(PInst^.Addr)));
使用integer()
类型转换可能会解决指针运算问题。但它只能在 32 位可执行文件下运行。
在较新的 Delphi 版本中,PByte
可用于指针运算。在此之前,唯一可以做到这一点的类型是 PChar
(PAnsiChar
或 PWideChar
)。在Delphi5中,PChar
是一个PAnsiChar
.
更新
现在我知道了记录的结构,也知道你想要实现什么,我想你大概应该做下面的事情。
您可以将 TInstruction
中的所有 PBytes
更改为 PAnsiChar
(或 PChar
,如果您只关心 D5),以及所有 PBytes
在每个例程中。然后你得到:
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);
...
但请注意,如果您想使用这些 PAnsiChars
读取或写入一个字节,则必须将它们转换为 PByte
。
我正在尝试将 DDetours
库移植到 Delphi 5/7。不会编译的行具有这种模式:
procedure Decode_J(PInst: PInstruction; Size: Byte);
var
Value: Int64;
VA: PByte;
begin
...
VA := PInst^.VirtualAddr + (PInst^.NextInst - PInst^.Addr) // <- compiler error
编译器错误:
[Error] InstDecode.pas(882): Operator not applicable to this operand type
PInst^.VirtualAddr, PInst^.NextInst, PInst^.Addr
都声明为 PByte
(PByte = ^Byte
)
我该怎么做才能解决这个问题?
编辑:
PInstruction
定义为:
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;
下Delphi5,试试:
procedure Decode_J(PInst: PInstruction; Size: Byte);
var
Value: Int64;
VA: PByte;
begin
...
VA := PByte(integer(PInst^.VirtualAddr) + (integer(PInst^.NextInst) - integer(PInst^.Addr)));
使用integer()
类型转换可能会解决指针运算问题。但它只能在 32 位可执行文件下运行。
在较新的 Delphi 版本中,PByte
可用于指针运算。在此之前,唯一可以做到这一点的类型是 PChar
(PAnsiChar
或 PWideChar
)。在Delphi5中,PChar
是一个PAnsiChar
.
更新
现在我知道了记录的结构,也知道你想要实现什么,我想你大概应该做下面的事情。
您可以将 TInstruction
中的所有 PBytes
更改为 PAnsiChar
(或 PChar
,如果您只关心 D5),以及所有 PBytes
在每个例程中。然后你得到:
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);
...
但请注意,如果您想使用这些 PAnsiChars
读取或写入一个字节,则必须将它们转换为 PByte
。