我正在尝试编写一个工具来扫描 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 表达式计算器会自动对数字进行符号扩展。符号扩展只能影响从0x80000000到0xFFFFFFFF的数字。也就是说,符号扩展只影响可以写入 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
问题:是否有完整的易于签名扩展的指令列表?