225 lines
3.3 KiB
NASM
225 lines
3.3 KiB
NASM
; -*- tab-width: 8 -*-
|
|
|
|
; MD5 checksum utility for x86_64 Linux, assembly version
|
|
; To build: nasm -f bin -O9 prog.x86_64.asm -o prog
|
|
|
|
%define @pie 0
|
|
|
|
BITS 64
|
|
%if @pie
|
|
ORG 0
|
|
%else
|
|
ORG 0x400000
|
|
%endif
|
|
|
|
%define @sys_read 0
|
|
%define @sys_write 1
|
|
%define @sys_exit 60
|
|
|
|
section .text
|
|
|
|
_code_seg:
|
|
_elf: db 0x7f,'ELF',2,1,1,0 ; e_ident
|
|
dq 0
|
|
dw 2+@pie ; e_type
|
|
dw 62 ; e_machine
|
|
dd 1 ; e_version
|
|
dq _start ; e_entry
|
|
dq .ph-_elf ; e_phoff
|
|
dq 0 ; e_shoff
|
|
dd 0 ; e_flags
|
|
dw 0x40 ; e_ehsize
|
|
dw 0x38, 1 ; e_phentsize, e_phnum
|
|
dw 0x40, 0 ; e_shentsize, e_shnum
|
|
dw 0 ; e_shstrndx
|
|
.ph: dd 1, 5 ; p_type, p_flags
|
|
dq 0 ; p_offset
|
|
dq _code_seg ; p_vaddr
|
|
dq _code_seg ; p_paddr
|
|
dq _code_end-_code_seg ; p_filesz
|
|
dq _code_end-_code_seg ; p_memsz
|
|
dq 0x1000 ; p_align
|
|
|
|
_start:
|
|
mov rax, ~0xefcdab8967452301
|
|
push rax
|
|
not rax
|
|
push rax
|
|
sub rsp, 64+8
|
|
|
|
xor r12, r12
|
|
; xor edx, edx
|
|
cdq
|
|
|
|
.2: mov rdi, rsp
|
|
xor eax, eax
|
|
lea ecx, [rax+8]
|
|
rep stosq
|
|
test edx, edx
|
|
lea edx, [rax+64]
|
|
jne .2a
|
|
xchg edi, eax ; 0 (stdin)
|
|
mov rsi, rsp
|
|
%if @sys_read != 0 || @sys_write != 1
|
|
lea ebx, [rdi+@sys_read]
|
|
%endif
|
|
call _io
|
|
mov byte [rsi], 0x80
|
|
sub esi, esp
|
|
lea r12, [r12+rsi*8]
|
|
.2a: cmp edx, 8
|
|
jb .2b
|
|
neg edx
|
|
mov [rsp+56], r12
|
|
.2b: push rdx
|
|
xor ebx, ebx
|
|
mov r14, 0x8a51407da834 << 15 ; cos(1) * 2^48
|
|
mov r15, 0xd76aa4784867 << 15 ; sin(1) * 2^48
|
|
mov r8, r14
|
|
mov r9, r15
|
|
|
|
mov rdx, rsp
|
|
mov ecx, [rdx+0x50]
|
|
mov edi, [rdx+0x54]
|
|
mov esi, [rdx+0x58]
|
|
mov ebp, [rdx+0x5c]
|
|
.1:
|
|
mov rax, r9
|
|
cqo
|
|
shr rax, 31
|
|
xor eax, edx
|
|
add ecx, eax
|
|
|
|
; r9' = r9 * r14 + r8 * r15
|
|
; r8' = r8 * r14 - r9 * r15
|
|
|
|
mov rax, r9
|
|
imul r15
|
|
mov r11, rdx
|
|
mov rax, r8
|
|
imul r14
|
|
sub rdx, r11
|
|
lea rax, [rdx+rdx]
|
|
xchg rax, r8
|
|
imul r15
|
|
lea rax, [rdx+rdx]
|
|
xchg rax, r9
|
|
imul r14
|
|
lea r9, [rdx*2+r9]
|
|
|
|
; r10d, edi, esi, ebp
|
|
|
|
%define PACK(a,b,c,d,e,f) (d<<15|c<<10|b<<5|a)<<4|e<<24|f
|
|
|
|
mov edx, ebx
|
|
shr edx, 5
|
|
mov eax, ebp
|
|
jne .1b
|
|
jc .1a
|
|
; 0: ((b^c)&a)^c
|
|
mov edx, PACK(7,12,17,22,1,0)
|
|
xor eax, esi
|
|
and eax, edi
|
|
xor eax, ebp
|
|
jmp .1e
|
|
|
|
.1a: ; 1: ((a^b)&c)^b
|
|
mov edx, PACK(5, 9,14,20,5,1)
|
|
mov eax, edi
|
|
xor eax, esi
|
|
and eax, ebp
|
|
jmp .1d
|
|
|
|
.1b: jc .1c
|
|
; 2: a^b^c
|
|
mov edx, PACK(4,11,16,23,3,5)
|
|
xor eax, edi
|
|
jmp .1d
|
|
|
|
.1c: ; 3: (~c|a)^b
|
|
mov edx, PACK(6,10,15,21,7,0)
|
|
not eax
|
|
or eax, edi
|
|
.1d: xor eax, esi
|
|
.1e: add eax, ecx
|
|
|
|
mov ecx, edx
|
|
shr ecx, 24
|
|
imul ecx, ebx
|
|
add ecx, edx
|
|
and ecx, 15
|
|
add eax, [rsp+8+rcx*4]
|
|
|
|
mov ecx, ebx
|
|
and ecx, 3
|
|
lea ecx, [rcx+rcx*4+4]
|
|
shr edx, cl
|
|
mov ecx, edx
|
|
rol eax, cl
|
|
|
|
mov ecx, ebp ; a = d
|
|
mov ebp, esi ; d = c
|
|
mov esi, edi ; c = b
|
|
add edi, eax ; b += x
|
|
inc ebx
|
|
cmp ebx, 64
|
|
jne .1
|
|
|
|
mov rdx, rsp
|
|
add [rdx+0x50], ecx
|
|
add [rdx+0x54], edi
|
|
add [rdx+0x58], esi
|
|
add [rdx+0x5c], ebp
|
|
pop rdx
|
|
test edx, edx
|
|
jge .2
|
|
|
|
xor edx, edx
|
|
mov rdi, rsp
|
|
.3: mov eax, edx
|
|
shr eax, 1
|
|
mov al, [rsp+0x40+8+rax]
|
|
jc .3a
|
|
shr al, 4
|
|
.3a: and al, 15
|
|
cmp al, 10
|
|
jb .3b
|
|
add al, 'a'-'0'-10
|
|
.3b: add al, '0'
|
|
stosb
|
|
inc edx
|
|
cmp edx, 32
|
|
jne .3
|
|
mov al, 10
|
|
stosb
|
|
inc edx
|
|
|
|
mov rsi, rsp
|
|
lea edi, [rdx-32] ; 1 (stdout)
|
|
%if @sys_read != 0 || @sys_write != 1
|
|
lea ebx, [rdi+@sys_write-1]
|
|
%endif
|
|
call _io
|
|
xor edi, edi ; exit code
|
|
lea eax, [rdi+@sys_exit]
|
|
syscall
|
|
|
|
_io:
|
|
%if @sys_read != 0 || @sys_write != 1
|
|
mov eax, ebx
|
|
%else
|
|
mov eax, edi
|
|
%endif
|
|
syscall
|
|
test eax, eax
|
|
jle .1
|
|
add rsi, rax
|
|
sub edx, eax
|
|
ja _io
|
|
; xor edx, edx
|
|
cdq
|
|
.1: ret
|
|
|
|
_code_end:
|
|
|