从反编译的ASM中获取信息

问题描述 投票:0回答:1

我愿意在一个小型3D游戏上修改相机坐标。我已经找到了三个功能,每个轴一个。我们称它们为CameraX,CameraY和CameraZ。当我发现我遗漏了某些东西时,我只与第一个一起工作。

这里是ASM指令,来自Ghidra:

                             *************************************************************
                             *                           FUNCTION                         
                             *************************************************************
                             undefined1  __register  CameraX (undefined2  x)
             undefined1        AL:1           <RETURN>
             undefined2        AX:2           x
             undefined1        Stack[-0x14]   local_14                                XREF[8]:     00478abe (*) , 
                                                                                                   00478aca (*) , 
                                                                                                   00478b44 (*) , 
                                                                                                   00478b53 (*) , 
                                                                                                   00478bb3 (*) , 
                                                                                                   00478bbf (*) , 
                                                                                                   00478c1d (*) , 
                                                                                                   00478c29 (*)   
             undefined4        Stack[-0x18]   local_18                                XREF[4]:     00478ae8 (R) , 
                                                                                                   00478b6e (R) , 
                                                                                                   00478bdd (R) , 
                                                                                                   00478c47 (R)   
             undefined4        Stack[-0x1c]   local_1c                                XREF[4]:     00478ae1 (R) , 
                                                                                                   00478b67 (R) , 
                                                                                                   00478bd6 (R) , 
                                                                                                   00478c40 (R)   
             undefined4        Stack[-0x20]   local_20                                XREF[8]:     00478ace (*) , 
                                                                                                   00478ada (R) , 
                                                                                                   00478b57 (*) , 
                                                                                                   00478b60 (R) , 
                                                                                                   00478bc3 (*) , 
                                                                                                   00478bcf (R) , 
                                                                                                   00478c2d (*) , 
                                                                                                   00478c39 (R)   
             undefined8        Stack[-0x28]   local_28                                XREF[4,2]:   004789ec (*) , 
                                                                                                   004789f5 (*) , 
                                                                                                   00478b06 (*) , 
                                                                                                   00478b0f (*) , 
                                                                                                   004789f1 (W) , 
                                                                                                   00478b0b (W)   
             undefined4        Stack[-0x2c]   local_2c                                XREF[1]:     00478b40 (*)   
                             CameraX                                         XREF[1]:     FUN_0047a280:0047a291 (c)   
        004789e0 53              PUSH       EBX
        004789e1 56              PUSH       ESI
        004789e2 83  c4  e0       ADD        ESP ,-0x20
        004789e5 8b  f0           MOV        ESI ,x
        004789e7 e8  68  9b       CALL       FUN_00462554                                     undefined FUN_00462554()
                 fe  ff
        004789ec 89  04  24       MOV        dword ptr [ESP ]=> local_28 ,x
        004789ef 33  c0           XOR        x,x
        004789f1 89  44  24       MOV        dword ptr [ESP  + local_28 +0x4 ],x
                 04
        004789f5 df  2c  24       FILD       qword ptr [ESP ]=> local_28
        004789f8 dc  66  08       FSUB       qword ptr [ESI  + 0x8 ]
        004789fb d9  1d  18       FSTP       dword ptr [DAT_00871218 ]                        = ??
                 12  87  00


...
...
...


        00478c4e 8b  c3          MOV        x,EBX
        00478c50 83  c4  20      ADD        ESP ,0x20
        00478c53 5e              POP        ESI
        00478c54 5b              POP        EBX
        00478c55 c3              RET

我知道:-我的可执行文件是32位,由Delphi制作。-x是新的x轴值。

我的目标是将此功能与注入的dll一起使用。我来到这里:

typedef int (__stdcall *_CameraX)(int x);
_CameraX CameraX = (_CameraX)0x04789E0;

但是,在004789fb FSTP dword ptr [DAT_00871218]行上出现“访问冲突”。这是x值的首次使用。所以我想这是错误的类型。

这是我的理解:-由于原始程序是用Delphi编写的,因此请记住__pascal调用约定。由于它在Visual Studio中已弃用,因此我正在使用__stdcall。我认为,由于只有一个参数*,不会有任何区别。-x总是很大。如果不是32位的话,我会选择很长的时间。-我真的不知道返回类型。我之所以选择int是因为在调用之后,调用者函数会创建一个test al, al

* *:吉德拉(Ghidra)告诉我只有一个论点,但是如果我在听我自己的话,就会有两个:

        004789e0 53              PUSH       EBX
        004789e1 56              PUSH       ESI
...
...
        00478c53 5e              POP        ESI
        00478c54 5b              POP        EBX
        00478c55 c3              RET

所以这是我的问题:-真的只有一种说法吗?-如果正确的是__pascal,我应该使用哪种调用约定,因为它不能在Visual Studio中使用? (如果有多个参数)-如何获取返回值?-为什么我们“发明”了许多电话会议?例如,为什么我们都不使用__cdecl呢?为什么有些人从左到右阅读,为什么使用从右到左?有什么区别吗?

我很确定缺少某些信息,由Ghidra生成的伪代码有用吗?

编辑:

int CameraX(int x)

{
  undefined4 *puVar1;
  uint uVar2;
  undefined4 unaff_EBX;
  int iVar3;
  float10 in_ST0;
  undefined4 local_20;
  undefined4 local_1c;
  undefined4 local_18;
  undefined local_14 [12];

  uVar2 = FUN_00462554();
  DAT_00871218 = (float)(ulonglong)uVar2 - (float)*(double *)(x + 8);
    iVar3 = CONCAT31((int3)((uint)unaff_EBX >> 8),1);
  if (*(float *)(x + 0x6c) < DAT_00871218) {
  // ...
assembly reverse-engineering calling-convention ghidra
1个回答
1
投票

这似乎使用的是Borland注册调用约定(也称为Borland快速调用)。它分别使用EAX,EDX和ECX作为前三个参数,其余参数进入堆栈。被呼叫者还必须保留EBX,ESI,EDI和EBP寄存器。

您可以看到您的函数保存了EBX和ESI寄存器,并且不使用EDI或EBP。根据约定,它还使用EAX作为第一个参数x,并在EAX中返回结果。

在现代Visual Studio中,没有针对Borland fastcall的等效调用约定。您可能会依赖使用内联汇编作为调用此Delphi函数的解决方法。

此解决方法可能会使用临时的Microsoft fastcall函数指针,因为它也使用了第一个参数的寄存器,但EAX除外,我们必须使用内联汇编传递它,例如(不确定代码语法) ,将其视为伪代码):

typedef void (__fastcall *_CameraX)();
_CameraX CameraXTemp = (_CameraX)0x04789E0;

int CameraX(int x) {
    int ret;
    __asm mov eax, x
    CameraXTemp();
    __asm mov ret, eax
    return ret;
}
© www.soinside.com 2019 - 2024. All rights reserved.