帮我写一个最简单的windows64的tea加密程序,语言是x86汇编语言,将代码尽可能减到最少。 ...
Создано: 4 марта 2026 г.
Отвечено с использованием GPT-5.1 Pro от Chat01
Создано: 4 марта 2026 г.
Отвечено с использованием GPT-5.1 Pro от Chat01
帮我写一个最简单的windows64的tea加密程序,语言是x86汇编语言,将代码尽可能减到最少。
要求key固定使用0x12345678,0x12345678,0x12345678,0x12345678
用户打开程序在命令行输入明文,返回密文的十六进制,显示必要的提示字符串。
写源代码给我,再教我一步一步编译成exe
先给你一份可以直接用 NASM+MinGW‑w64 编译的 64 位 TEA 加密程序(x86‑64 汇编),然后一步一步教你怎么变成 exe。
(为了让代码尽量短,这个版本有几个简化条件:明文长度必须是 8 的倍数,并且不能包含空格。)
asm; 64-bit Windows + NASM + gcc ; TEA 加密,key 固定为 0x12345678 * 4 ; 明文:命令行输入的 ASCII 字符串(不含空格,长度必须是 8 的倍数) ; 输出:密文的十六进制(每 8 字节明文 -> 16 个十六进制字符) bits 64 default rel extern printf extern scanf extern strlen global main section .data msg_input db "Input plaintext (length must be multiple of 8, no spaces): ",0 msg_errlen db "Error: length must be a multiple of 8.",10,0 msg_output db "Ciphertext (hex): ",0 msg_newline db 10,0 ; "\n" fmt_scan db "%1023s",0 ; 读入最多 1023 字符(不含空格) fmt_hex db "%08X%08X",0 ; 输出两个 32bit 为 8 位十六进制 section .bss buffer resb 1024 ; 明文缓冲区 section .text main: ; 预留 32 字节 shadow space + 16 字节本地变量,并保证 16 字节对齐 ; [rsp..rsp+31] : shadow space ; [rsp+32..+47] : 本地变量 (len, nblocks, offset) sub rsp, 56 ; printf("Input plaintext ..."); lea rcx, [msg_input] call printf ; scanf("%1023s", buffer); lea rcx, [fmt_scan] ; 第 1 个参数:格式串 lea rdx, [buffer] ; 第 2 个参数:缓冲区地址 call scanf ; len = strlen(buffer); lea rcx, [buffer] call strlen ; 返回值在 RAX mov [rsp+32], eax ; len (int) ; if (len % 8 != 0) { printf("Error ..."); return; } mov ecx, eax and ecx, 7 jz .len_ok lea rcx, [msg_errlen] call printf jmp .finish .len_ok: ; nblocks = len / 8; mov ecx, eax shr ecx, 3 mov [rsp+36], ecx ; nblocks (其实后面只用 offset + len 判断) ; offset = 0; xor eax, eax mov [rsp+40], eax ; offset ; printf("Ciphertext (hex): "); lea rcx, [msg_output] call printf .loop_blocks: ; offset >= len ? 结束 mov eax, [rsp+40] ; offset cmp eax, [rsp+32] ; len jae .loop_done ; block_ptr = buffer + offset; lea r11, [buffer] add r11, rax ; r11 = 当前 8 字节分组地址 ; v0 = *(uint32_t*)(block_ptr) ; v1 = *(uint32_t*)(block_ptr+4) mov r8d, [r11] ; v0 mov r9d, [r11+4] ; v1 ; TEA 加密(32 轮) ; sum = 0; delta = 0x9E3779B9; xor edx, edx ; sum mov ecx, 32 ; 轮计数 mov r10d, 0x9E3779B9 ; delta .round: ; sum += delta; add edx, r10d ; v0 += ((v1<<4)+k0) ^ (v1+sum) ^ ((v1>>5)+k1); mov eax, r9d ; v1 shl eax, 4 add eax, 0x12345678 ; (v1<<4) + k0 mov r11d, r9d add r11d, edx ; v1 + sum xor eax, r11d mov r11d, r9d shr r11d, 5 add r11d, 0x12345678 ; (v1>>5) + k1 xor eax, r11d add r8d, eax ; v0 += t ; v1 += ((v0<<4)+k2) ^ (v0+sum) ^ ((v0>>5)+k3); mov eax, r8d shl eax, 4 add eax, 0x12345678 ; (v0<<4) + k2 mov r11d, r8d add r11d, edx ; v0 + sum xor eax, r11d mov r11d, r8d shr r11d, 5 add r11d, 0x12345678 ; (v0>>5) + k3 xor eax, r11d add r9d, eax ; v1 += t2 dec ecx jnz .round ; printf("%08X%08X", v0, v1); lea rcx, [fmt_hex] ; 第 1 个参数:格式串 mov edx, r8d ; 第 2 个参数:v0 mov r8d, r9d ; 第 3 个参数:v1 call printf ; offset += 8; mov eax, [rsp+40] add eax, 8 mov [rsp+40], eax jmp .loop_blocks .loop_done: ; 打印换行 lea rcx, [msg_newline] call printf .finish: xor eax, eax ; return 0 add rsp, 56 ret
程序行为说明:
Input plaintext (length must be multiple of 8, no spaces):ABCDEFGH
Ciphertext (hex): BD7EA971733A0EED
ABC),会提示:
Error: length must be a multiple of 8.为了减代码量:
- 不支持空格(
scanf("%1023s")读到空格会停止)。- 长度必须是 8 的倍数(没有做 padding)。
下面以 Windows 64 位 为前提,使用 NASM + MinGW‑w64 (gcc) 来编译:
nasm.exe 所在目录加到 PATH。gcc.exe 所在目录加到 PATH。装好后,在 命令提示符(cmd)里输入:
batnasm -v gcc --version
能看到版本信息就 OK。
把上面的汇编代码保存为,例如:tea.asm
注意:文件编码最好用 UTF‑8 或 ANSI,避免奇怪字符。
在 tea.asm 所在目录打开命令提示符:
batnasm -f win64 tea.asm -o tea.obj
-f win64 告诉 NASM 生成 Windows 64 位目标文件。-o tea.obj 输出目标文件名。如果语法没问题,这一步不会报错,会生成 tea.obj。
继续在同一目录执行:
batgcc tea.obj -o tea.exe
gcc 会自动链接 C 运行时库(里面有 printf/scanf/strlen),生成控制台程序 tea.exe。如果一切正常,你会在当前目录看到 tea.exe。
在命令行运行:
battea.exe
示例 1:
textInput plaintext (length must be multiple of 8, no spaces): ABCDEFGH Ciphertext (hex): BD7EA971733A0EED
示例 2:
textInput plaintext (length must be multiple of 8, no spaces): 12345678 Ciphertext (hex): A15C29DB3C58D5B2
示例 3(错误长度):
textInput plaintext (length must be multiple of 8, no spaces): ABC Error: length must be a multiple of 8.
如果你愿意,我们可以下一步再做几个改进版本,比如:
fgets 或 WinAPI 读取)。