1

我正在尝试编写一个工具来扫描 64 位汇编代码以查找可能的符号扩展错误。
例如,假设一个 32 位常量 (imm32) 定义为

SOCKET_ERROR_INT EQU 0FFFFFFFFh

接下来,调用任何返回 SOCKET_ERROR(32 位整数)的 API,并将结果存储在 64 位变量retval中。但是,将retval与 SOCKET_ERROR_INT 进行比较会生成

cmp qword ptr [rbp-8],0FFFFFFFFFFFFFFFFh

请注意 SOCKET_ERROR_INT (imm32) 符号扩展为 64 位!(见下表:cmp m64, imm32)但是,qword ptr [rbp-8]0FFFFFFFFh ( retval ),所以比较阴险地失败了!

笔记

立即操作数 (imm32) 是常量值或常量表达式的结果。汇编器在汇编时将立即值编码到指令中。

在某些情况下,MASM 表达式计算器会自动对数字进行符号扩展。符号扩展只能影响从0x800000000xFFFFFFFF的数字。也就是说,符号扩展只影响可以写入 32 位且高位等于 1 的数字。

例如,当调试器将其视为 64 位数字时,数字 0x12345678 始终保持为 0x0000000012345678。另一方面,当 0x890ABCDE 被视为 64 位值时,它可能会保持 0x00000000890ABCDE 或 MASM 表达式评估器可能会将其符号扩展为 0xFFFFFFFF890ABCDE。

这是符号扩展的指令的不完整列表:

add  m64, imm32
add  r64, imm32 
add  rax, imm32
and  rax, imm32
and  r64, imm32
cmp  m64, imm32
cmp  r64, imm32
cmp  rax, imm32
sub  m64, imm32
sub  r64, imm32
sub  rax, imm32
test m64, imm32
test rax, imm32
test r64, imm32
mov  m64, imm32
push imm32

offset64.asm

option casemap:none

externdef MessageBoxA : near
externdef ExitProcess : near

   .data
   
    szDlgTitle    db "MASM64",0
    szMsg         db "HELLO",0   

    SOCKET_ERROR_INT EQU 0FFFFFFFFh

   .code

main proc
   LOCAL myLocal:QWORD
   mov  myLocal,0
   mov  DWORD PTR myLocal,SOCKET_ERROR_INT
   cmp  myLocal,SOCKET_ERROR_INT
   je  exit_now

   sub  rsp, 28h       
   xor  r9d, r9d       
   lea  r8, szDlgTitle  
   lea  rdx, szMsg    
   xor  rcx, rcx       
   call MessageBoxA

exit_now:
   xor  ecx, ecx
   call ExitProcess
   
main endp
   end

要构建示例,请创建一个makeit64.bat,如下所示:

@echo on

if not defined DevEnvDir (
  call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat"
)

ml64.exe offset64.asm /link /WX /VERBOSE /subsystem:console /defaultlib:kernel32.lib /defaultlib:user32.lib /entry:main

运行批处理文件会创建此输出。(没有警告或错误)

C:\masm32>makeit64

C:\masm32>if not defined DevEnvDir (call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat" )

C:\masm32>ml64.exe offset64.asm /link /WX /VERBOSE /subsystem:console /defaultlib:kernel32.lib /defaultlib:user32.lib /entry:main
Microsoft (R) Macro Assembler (x64) Version 14.29.30037.0
Copyright (C) Microsoft Corporation.  All rights reserved.

 Assembling: offset64.asm
Microsoft (R) Incremental Linker Version 14.29.30037.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/OUT:offset64.exe
offset64.obj
/WX
/VERBOSE
/subsystem:console
/defaultlib:kernel32.lib
/defaultlib:user32.lib
/entry:main
Processed /DEFAULTLIB:kernel32.lib
Processed /DEFAULTLIB:user32.lib

Starting pass 1

Searching libraries
    Searching C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\um\x64\kernel32.lib:
      Found ExitProcess
        Referenced in offset64.obj
        Loaded kernel32.lib(KERNEL32.dll)
      Found __IMPORT_DESCRIPTOR_KERNEL32
        Referenced in kernel32.lib(KERNEL32.dll)
        Loaded kernel32.lib(KERNEL32.dll)
      Found __NULL_IMPORT_DESCRIPTOR
        Referenced in kernel32.lib(KERNEL32.dll)
        Loaded kernel32.lib(KERNEL32.dll)
      Found ⌂KERNEL32_NULL_THUNK_DATA
        Referenced in kernel32.lib(KERNEL32.dll)
        Loaded kernel32.lib(KERNEL32.dll)
    Searching C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\um\x64\user32.lib:
      Found MessageBoxA
        Referenced in offset64.obj
        Loaded user32.lib(USER32.dll)
      Found __IMPORT_DESCRIPTOR_USER32
        Referenced in user32.lib(USER32.dll)
        Loaded user32.lib(USER32.dll)
      Found ⌂USER32_NULL_THUNK_DATA
        Referenced in user32.lib(USER32.dll)
        Loaded user32.lib(USER32.dll)

Finished searching libraries

Finished pass 1


Starting pass 2
     offset64.obj
     kernel32.lib(KERNEL32.dll)
     kernel32.lib(KERNEL32.dll)
     kernel32.lib(KERNEL32.dll)
     kernel32.lib(KERNEL32.dll)
     user32.lib(USER32.dll)
     user32.lib(USER32.dll)
     user32.lib(USER32.dll)
Finished pass 2
C:\masm32>

沉默的 MASM

没有警告、错误和跳转等于 FALSE。例如,

mov  DWORD PTR myLocal,SOCKET_ERROR_INT
cmp  myLocal,SOCKET_ERROR_INT
je   exit_now

生成

 mov     dword ptr [rbp-8],0FFFFFFFFh
 cmp     qword ptr [rbp-8],0FFFFFFFFFFFFFFFFh
 je      offset64+0x1034

问题:是否有完整的易于签名扩展的指令列表?

4

0 回答 0