default rel ; default using relative address, can prevent some reloc
global _start
section .text
%define u(x) __?utf16?__(x) ; can use u('123') to define utf-16 string
_start:
lea rdi, [msg_ascii] ; or you should use `lea rax, [rel message]` without `default rel`
mov rax, msg_ascii_len ; mov length (value, not ref) to rax
mov ax,11001000b ; binary
jmp stop
stop:
times 64 db 0x90 ; fill 64 nop
ret
; function calling convention mark:
; for example (linux)[linux, windows]:
; self and sub function including linux and windows call
; current function use linux call
; caller must make sure preserve callee saved regs
; and if current function is windows call,
; make sure preserve 0x20 space on stack
; or for example (linux)[rdi, rsi, rcx, rdx, rax]:
; means only `rdi, rsi, rcx, rdx, rax` will change by function
; windows safe reg: rbx, rbp, rdi, rsi, rsp, r12, r13, r14, r15
; linux safe reg: rbx, rbp, rsp, r12, r13, r14, r15 (windows -rdi, -rsi)
; memcmp(addr1: rdi, addr2: rsi, length: edx)
; rax: 0 -> same
; 1 -> not the same
; (linux)[rdi, rsi, rcx, rdx, rax]
memcmp:
mov ecx, edx
repe cmpsb
setne al
movzx eax, al
ret
; memset(dst: rdi, value: sil, length: edx)
; (linux)[rdi, rsi, rcx, rdx, rax]
memset:
mov eax, esi
mov ecx, edx
rep stosb
ret
; memcpy(dst: rdi, src: rsi, length: edx)
; (linux)[rdi, rsi, rcx, rdx, rax]
memcpy:
mov ecx, edx
rep movsb
ret
; strlen(str: rdi)
; eax: length
; (linux)[rdi, rcx, rax]
strlen:
xor ecx, ecx ; ecx = 0
dec ecx ; ecx = -1 (0xFFFFFFFF)
; rcx = maximum length to scan
xor eax, eax ; eax = 0 (al = 0 value to scan for)
cld ; clear DF, rep will mov forward, rcx will dec
repne scasb ; scan the memory for AL
sub eax, ecx ; eax = 0 - ecx_leftover = scanned bytes + 1
sub eax, 2 ; fix that into "string length" (-1 for '\\0')
ret
; strcmp(str1: rdi, str2: rsi)
; rax: 0 -> same
; 1 -> not the same
; (linux)[rdi, rsi, rcx, rdx, rax, r8]
strcmp:
mov r8, rdi ; save str1 to r8
call strlen ; get str1 len
mov rdi, r8
mov edx, eax
inc edx ; compare including ending NULL byte
call memcmp ; memcmp(str1, str2, strlen(str1) + 1)
ret
section .data
msg_ascii: db '123', 0
msg_ascii_len: equ $-msg_ascii ; represent msg_ascii, a const, will not present in final shellcode
msg_16: dw u('hello, world'), 0
msg_16_len: equ $-msg_16
buffer: resb 64 ; reserve 64 bytes
db `\\u263a` ; unicode, will be store in UTF-8, a smiley face
db `\\xe2\\x98\\xba` ; hex bytes
字符串、常量等内容:
需要Mingw-w64的ld
注意链接出的.text段不可写,只有RX,需要RWX可以加上 -N 参数
nasm ./sc.asm -fwin64 -o sc.o
C:\\msys64\\mingw64\\bin\\ld.exe .\\sc.o -o sc.exe