我可以在 Linux 中使用 gcc 完美链接我的 aes-x86_64.s,但无法在 Windows 中使用 TDM 的 cl、ld 或 gcc。
汇编文件具有 AES_cbc_encrypt 等功能,用于从 openssl 进行加密/解密。我不会使用他们的库。我只是对链接它感兴趣。或者,我使用这里的 perl 脚本将 .s 文件转换为 masm
https://github.com/openssl/openssl/blob/master/crypto/perlasm/x86_64-xlate.pl
这个 perl 脚本在构建 openssl 时执行,它基本上生成 aes-x86_64.s 文件,然后将其构建到 libcrypto.lib 中。生成 masm 版本的问题是,它添加了
.notes.gnu.properties SEGMENT
,我最终删除并编译了它,但是当我调用 AES_set_encrypt_key 时,我的 masm 程序无法正常工作,我相信我调用正确。这是masm节目
.data
ks DQ 32 DUP(0) ; used for aes_key struct = 60 ints = 240 bytes + int rounds = 244 bytes but rounded off to 256 anyway
OPENSSL_ia32cap_P DQ 2 DUP (0) ; unsigned int OPENSSL_ia32cap_P[4];
key db 0E0h,0E6h,00Ch,086h,0F1h,010h,0F5h,03Ah,04Eh,065h,088h,079h,074h,0B1h,04Eh,03Dh,006h,022h,09Dh,0B9h,04Eh,026h,025h,0BEh,0D1h,018h,02Bh,056h,073h,0ABh,044h,0F3h,0
.code
include aes-x86_64.asm
externdef ExitProcess:proc
main proc
sub rsp, 28h ;reserve stack space for called functions
and rsp, 0fffffffffffffff0h ;make sure stack 16-byte aligned
; AES_set_encrypt_key(key, 256, &ks);
xor rdx, rdx
lea r8, ks
mov rdx, 256
lea rcx, key
sub rsp, 20h
call AES_set_encrypt_key
exit:
sub rsp, 20h
call ExitProcess
main endp
end
脚本太长,无法粘贴到此处,但它是:这是使用 masm 语法转换后的格式。原来是GAS
https://pastebin.pl/view/raw/c8b99bd8
我不确定这个 MASM 语法是否正确,但它编译得很好,但只有当我删除它创建的最后一个 SEGMENT 部分时,它是这样的:
.text$ ENDS
".note.gnu.property" SEGMENT
DD 1f - 0f
DD 4f - 1f
DD 5
0::
DB 047h
DB 04eh
DB 055h
DB 0
1::
DD 0c0000002h
DD 3f - 2f
2::
DD 3
3::
4::
".note.gnu.property" ENDS
函数失败返回-1。它应该返回 0。我用 x64dbg 进行调试。
代码转换似乎出了问题。请注意,函数
_x86_64_AES_set_encrypt_key
被标记为 \@abi-omnipotent
,因此它不应该添加 Windows 序言,但在您的粘贴中我们可以清楚地看到它:
_x86_64_AES_set_encrypt_key PROC PRIVATE
mov QWORD PTR[8+rsp],rdi ;WIN64 prologue
mov QWORD PTR[16+rsp],rsi
mov rax,rsp
$L$SEH_begin__x86_64_AES_set_encrypt_key::
mov rdi,rcx
mov rsi,rdx
mov rdx,r8
mov rcx,r9
mov r8,QWORD PTR[40+rsp]
mov r9,QWORD PTR[48+rsp]
这段代码错误地尝试将参数从 Windows 约定移动到 sysv,但这已经由包装器完成了
AES_set_encrypt_key
。