Joh*_*ica 5 delphi 64-bit assembly exception
我想在X64 asm块中引发异常.
让我们假设我有这样的函数:
function Example(Values: array of integer): integer;
asm
or rcx,rcx
jz @error
....
Run Code Online (Sandbox Code Playgroud)
我知道我只能读取指针并获得AV,但是我想提出一个更具描述性的错误.
我可以做一个额外的功能并调用那个:
asm
or rcx,rcx
jz @error
....
@error:
mov ecx, 1
mov rdx, ErrorString
jmp RaiseError
....
function RaiseError(code: integer; const Msg: string);
begin
case code of
1: raise EEmptyArrayError.Create(Msg);
Run Code Online (Sandbox Code Playgroud)
但是,错误将在引起的函数之外发生.如何从(似乎)来自Example函数内部获得异常.
请注意,这是X64,因此适用于X86的所有SEH答案都不合适,因为X64使用VEH.
raise 的完整语法是:
raise Exception at address
Run Code Online (Sandbox Code Playgroud)
您需要做的就是将当前 IP 作为参数传递,错误过程可以将其传递给异常。
您可以使用 获取 RIP lea rax, [rip]。
这样代码就变成了:
asm
or rcx,rcx
jz @error
....
@error:
mov ecx, 1
mov rdx, ErrorString
lea r8,[rip]
jmp RaiseError
....
function RaiseError(code: integer; const Msg: string; address: pointer);
begin
case code of
1: raise EEmptyArrayError.Create(Msg) at address;
Run Code Online (Sandbox Code Playgroud)
当然在这种情况下使用起来更方便
function RaiseError(code: integer; const Msg: string);
begin
case code of
1: raise EEmptyArrayError.Create(Msg) at ReturnAddress;
Run Code Online (Sandbox Code Playgroud)
注意
在这种情况下,如果保留 jmp,则错误似乎源自调用例程,在这种情况下,这实际上是正确的。如果您希望异常将罪魁祸首指向您的 asm 代码,请使用调用。