我有下面这段代码,我想将它翻译成ASM,在Delphi中使用过。

var
    FunctionAddressList: Array of Integer;

type TFunction = function(parameter: Integer): Integer; cdecl;

function Function(parameter: Integer): Integer;
var
    ExternFunction: TFunction;
begin
    ExternFunction := TFunction(FunctionAddressList[5]);
    Result := ExternFunction(parameter);
end;

它的工作原理normaly,但是当我尝试它的程序集的版本:

function Function(parameter: Integer): Integer; cdecl;
asm
  mov eax, FunctionAddressList
  jmp dword ptr [eax + 5 * 4]
end;

它应该的工作,因为,在C ++它工作在两种方式:

void *FunctionAddressList;

_declspec(naked) int Function(int parameter)
{
    _asm mov eax, FunctionAddressList;
    _asm jmp dword ptr [eax + 5 * 4];
}

typedef int (*TFunction)(int parameter);
int Function(int parameter)
{
    TFunction ExternFunction = ((TFunction *)FunctionAddressList)[5];
    return ExternFunction(parameter);
}

但是,它确实在Delphi不工作。

在大会版本,它乘以阵列4,因为它的阵列中的每个元件之间的偏移大小,因此这两个版本是等价的。

所以,我想知道为什么它不与德尔福工作。在Delphi,一个阵列中的整数值之间的偏移大小是比C ++不同?

我已经尝试了许多的偏移,如1,2,4,6,8,等等和许多类型的阵列(指针的数组;只有指针;整数的数组,等等),并且我已经试过许多调用约定,和CDECL是唯一的,与非ASM版本的工作,但与ASM,所有的测试都没有工作。

感谢。

有帮助吗?

解决方案

首先测试应用程序以再现错误:

var
  FunctionAddressList: Array of Integer;

function Bar(parameter: Integer): Integer; cdecl;
begin
  ShowMessage('Bar '+IntToStr(parameter));
end;

function Foo(parameter: Integer): Integer; cdecl;
asm
  mov eax, FunctionAddressList
  jmp dword ptr [eax + 5 * 4]
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SetLength(FunctionAddressList, 6);
  FunctionAddressList[5]:= Integer(@Bar);
  Foo(25);
end;

在酒吧地址正确定义,但问题是,Delphi编译器生成的Foo序幕和收尾,所以真正的Foo代码是

0046CD30 55               push ebp
0046CD31 8BEC             mov ebp,esp
Unit1.pas.46:             mov eax, FunctionAddressList
Unit1.pas.47:             jmp dword ptr [eax + 5 * 4]
0046CD3B 5D               pop ebp
0046CD3C C3               ret

其结果是,堆被损坏,则参数是错误的,酒吧返回地址是错误的。如果你仍然想要做的伎俩,使用

function Foo(parameter: Integer): Integer; cdecl;
asm
  pop ebp
  mov eax, FunctionAddressList
  jmp dword ptr [eax + 5 * 4]
end;

其他提示

Array of Integer是不是你认为它是。这是一个自动管理动态数组。

您应该尝试使用相同FunctionAddressList: ^Pointer; - 不过请注意,你将不得不做手工分配和释放

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top