帮助理解MOVSXD

逆向工程 部件 x86-64
2021-06-17 23:12:39

我试过阅读文档,但这条指令的功能对我来说仍然很模糊。例如,我想知道在这些说明之后 RDX 中存储了什么:

mov    edx, 0x26d1
mov    eax, 0x40d
add    eax, edx
movsxd rdx, eax

就我个人而言,我认为它是 0x0000000000002ade,因为我认为当时 eax 中不存在第 31 位的有符号位。(如果这有任何意义?)任何帮助将不胜感激,也许一个不会让我感到困惑的解释也会很棒:) 谢谢,祝你有美好的一天!

1个回答

movsxd 通过将 dword 扩展为 qword 的符号来移动 dword

所以在这个例子中 rdx 将是 eax+edx

C:\>python -c "print( hex(0x26d1+0x40d))
0x2ade

您可以使用一些模拟器,如 unicorn
或使用调试器并在某个地方修补此指令并循环
或编译一个小源,如下所示
(符号下面的代码将 16 位输入扩展为 32 位输出)
在您的示例中为 32 位输入被用来输出 64 位
还有一个 8 位输入和 16 位输出
movsxb(8in160ut),movsxw(16in320ut),movsxd (32in640ut)

#include <stdio.h>
int main(void)
{
    printf("movsxd demo\n");
    signed short edx = 0x26d1;
    signed short eax = 0x40d;
    for (int i = 0; i < 25; i++ ){
        edx = edx + eax;
        printf("%x\n",edx);
    }
}

编译和执行,你可以看到它是如何以及何时被符号扩展的

:\>cl /Zi /W4 /analyze /EHsc /nologo /Od movsxd.cpp /link /release
movsxd.cpp

:\>movsxd.exe
movsxd demo
2ade
2eeb
32f8
3705
3b12
3f1f
432c
4739
4b46
4f53
5360
576d
5b7a
5f87
6394
67a1
6bae
6fbb
73c8
77d5
7be2
7fef
ffff83fc <<<<<<<<<<
ffff8809 <<<<<<<<<
ffff8c16 <<<<<<<<<<<<<

只是为了显示一个简化的反汇编,我重构了代码以消除多余的打印、赋值等,并使用完整的优化和反汇编
代码编译它

#include <stdio.h>
int main(void)
{
    signed short edx = 0x26d1;
    for (int i = 0; i < 25; i++ ){
        edx = edx + 0x40d;
        printf("%x\n",edx);
    }
}

反汇编查看 si(ESI 的 16 位)中的单词如何符号扩展到 eax(32 位)

:\>cdb -c "uf movsxd!main;q" movsxd.exe |awk "/Reading/,/quit/"
0:000> cdb: Reading initial command 'uf movsxd!main;q'
movsxd!main:
01291000 56              push    esi
01291001 57              push    edi
01291002 bed1260000      mov     esi,26D1h
01291007 bf19000000      mov     edi,19h
0129100c 0f1f4000        nop     dword ptr [eax]

movsxd!main+0x10:
01291010 81c60d040000    add     esi,40Dh

01291016 0fbfc6          movsx   eax,si <<<<<<<<<
when si will be  > 0x7fff (max signed short) eax will
get sign extended.

01291019 50              push    eax
0129101a 6890012d01      push    offset movsxd!__xt_z+0x8 (012d0190)
0129101f e85c000000      call    movsxd!printf (01291080)
01291024 83c408          add     esp,8
01291027 83ef01          sub     edi,1
0129102a 75e4            jne     movsxd!main+0x10 (01291010)

movsxd!main+0x2c:
0129102c 5f              pop     edi
0129102d 33c0            xor     eax,eax
0129102f 5e              pop     esi
01291030 c3              ret
quit: