Skip to content

Instantly share code, notes, and snippets.

@randomdude999
Last active June 28, 2023 19:11
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save randomdude999/cacf792ad331759398830d448ec3920f to your computer and use it in GitHub Desktop.
Save randomdude999/cacf792ad331759398830d448ec3920f to your computer and use it in GitHub Desktop.
tiny versions of the POSIX sleep utility (for x86 Linux)
; optimized version of https://reddit.com/comments/l4wfoo/_/gkrkhkb/
; usage:
; nasm tinysleep.asm
; chmod +x tinysleep
; ./tinysleep 5
bits 64
db 0x7F, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x02, 0x00, 0x3E, 0x00, 0x01, 0x00, 0x00, 0x00
db 0x78, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00
db 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00
db 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00
db 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x78, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db flen, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db flen, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
_start: pop rdi ; rdi = argc
cmp edi, 2 ; argc == 2?
je .parse
push 1
pop rdi
jmp .exit ; exit(1)
.parse:
pop rsi ; rsi = argv[0]
pop rsi ; rsi = argv[1]
; assumes ecx = eax = 0 (holds on linux)
.loop: lodsb ; al = [rsi], rsi += 1
sub al,'0'
jl .sleep
imul ecx, ecx, 10
add ecx, eax
jmp .loop
.sleep: xor esi, esi ; &rem = 0
push rsi ; req.tv_nsec
push rcx ; req.tv_sec
mov rdi, rsp ; &req
push 35 ; SYS_nanosleep
pop rax
syscall
xor edi, edi ; exit(0)
.exit: push 60 ; SYS_exit
pop rax
syscall
flen: equ $-_start
; loosely based on https://www.muppetlabs.com/~breadbox/software/tiny/revisit.html
; usage:
; nasm tinysleep2.asm
; chmod +x tinysleep2
; ./tinysleep2 5
bits 32
; this load address is actually code: it's the mov al, 162;
; push edi at sleepcont. the ordering of the code is a bit
; wonky there as the load address needs to be page-aligned
; but also less than 0x8000_0000 to make the kernel happy
org 0x57a2b000
ehdr: ; elf header fields:
db 0x7F, "ELF" ; e_ident
_start: ; esi = argc
pop esi
cmp esi, 2
je part2
; ebx is initialized to 0 on startup,
; set it to 1 to exit with error
inc ebx
exit: ; assumes eax = 0, set eax = SYS_exit
inc eax
int 0x80
anotherexit: ; clear out most of ebx
; the 2 bit is clear because ebx used to be a stack pointer,
; which is aligned to at least 4 bytes, 6 is probably not clear
; but it doesn't matter as exit only reads the low byte
and ebx, 0x00060002 ; e_type
; e_machine
xor eax, eax ; e_version
jmp exit
dd _start ; e_entry
dd phdr - $$ ; e_phoff
part2: ; dummy load to skip argv[0]
pop esi ; e_shoff
; esi = argv[1]
pop esi
parseloop: ; read byte from esi into al and advance esi
lodsb
sub al, '0' ; e_flags
; if not null, read another character
jge loopcont
; ecx was initialized to 0 on startup
; tv_nsec = 0
push ecx
jmp sleepcont ; e_ehsize
dw phdrsz ; e_phentsize
phdr: dd 1 ; e_phnum ; p_type
; e_shentsize
dd 0 ; e_shnum ; p_offset
; e_shstrndx
db 0 ; p_vaddr
sleepcont: mov al, 162 ; SYS_nanosleep
; tv_sec = parsed number
push edi
mov ebx, esp ; p_paddr
; the first argument, the address of our struct timespec,
; is the current stack pointer (we pushed its values to the
; stack)
; the 2nd argument to nanosleep, &rem, is left as NULL
int 0x80
; p_filesz doesn't have to be the exact filesize, however it
; does have to be the same number of pages as the real file.
; in practice this means it has to be < 0x1000. note that the
; cmp opcode itself is the lowest byte of the filesize, so it's
; actually 0x13d
cmp eax, strict dword 1 ; p_filesz
; p_memsz
jmp anotherexit
loopcont: ; push another digit to the end of edi
; (it was initialized to 0 on startup)
imul edi, edi, 10 ; p_flags
add edi, eax
jmp parseloop ; p_align
; padding
dw 0
phdrsz equ $ - phdr
filesz equ $ - ehdr
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment