Last active
June 28, 2023 19:11
-
-
Save randomdude999/cacf792ad331759398830d448ec3920f to your computer and use it in GitHub Desktop.
tiny versions of the POSIX sleep utility (for x86 Linux)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; 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