48656C6C6F2C20776F726C64210A
5: 48 rex64 6: 65 gs 7: 6c ins BYTE PTR es:[rdi],[dx] 8: 6c ins BYTE PTR es:[rdi],[dx] 9: 6f outs [dx],DWORD PTR ds:[rsi] a: 2c 20 sub al,0x20 c: 77 6f ja 7de: 72 6c jb 7c 10: 64 21 0a and DWORD PTR fs:[rdx],ecx
This has the lovely property of being gibberish to both those who do, and those who do not know Intel assembly.
The clever trick here is to place a string somewhere that can be executed by a CPU but just before that string place a call to somewhere else, and in that call the return address (the next instruction after the call, or here also the string) is popped and used as the address to print via write.
The assembly might be less confusing than a context-free disassembly.
; OpenBSD, AMD64, NASM
BITS 64
%define sys_exit 1
%define sys_write 4
section .note.openbsd.ident
align 2
dd 8, 4, 1
db 'OpenBSD',0
dd 0
align 2
section .text
global _start
_start:
call clever_trick
db "Hello, world!", 0x0a
clever_trick:
pop rsi
mov rax,sys_write
mov rdi,1 ; stdout
mov rdx,14 ; length
syscall
mov rax,sys_exit
xor rdi,rdi
syscall
You may want to know how to actually build this file into something. Porting it to some other operating system or architecture will take more work.
$ make clever-helloworld
nasm -f elf64 clever-helloworld.asm -o clever-helloworld.o
ld.bfd -m elf_x86_64_obsd -nopie clever-helloworld.o -o clever-helloworld
$ objdump -M intel -D clever-helloworld.o
...
On a somewhat related note, dc(1) can act as a hex decoder.
$ echo 16 i 48656C6C6F2C20776F726C64210A P | dc
Hello, world!
Or worse.
$ echo 16 i F09F86970A P | dc
🆗
tags #asm