and with less double-compiling if you put a label at each svc instruction:
void
x() {
__asm volatile(
" mov x8, #1;"
" _x: svc #0;"
);
}
typedef unsigned long size_t;
int
w(void *what, size_t len) {
__asm volatile(
" mov x2, x1;"
" mov x1, x0;"
" mov w0, #1;"
" mov x8, #4;"
" _w: svc #0;"
);
return 0;
}
void
start()
{
w("hello\n", 6);
x();
}
__asm(" .section \".note.openbsd.ident\", \"a\"\n"
" .p2align 2\n"
" .long 8\n"
" .long 4\n"
" .long 1\n"
" .ascii \"OpenBSD\\0\"\n"
" .long 0\n"
" .previous\n");
__asm(
" .pushsection \".openbsd.syscalls\", \"\",@progbits\n"
" .p2align 2\n"
" .long _w, 4\n"
" .long _x, 1\n"
" .popsection\n");
and compile line would be something like:
cc -c hello.c && ld -e start --eh-frame-hdr -Bstatic -o hello hello.o && ./hello
Den lör 15 mars 2025 kl 09:34 skrev Janne Johansson <[email protected]>:
>
> Den lör 15 mars 2025 kl 09:17 skrev Janne Johansson <[email protected]>:
> >
> > This might also help:
> > https://flak.tedunangst.com/post/dude-where-are-your-syscalls
> >
>
> And the text hints at it, but the exact trick to figure out the
> offsets to put in the "what" ELF section is to compile and link it
> once, then run
>
> $ llvm-objdump hello3 -d|grep -B1 svc
> 1047c: d2800028 mov x8, #0x1
> 10480: d4000001 svc #0
> --
> 104c8: d2800088 mov x8, #0x4
> 104cc: d4000001 svc #0
>
> so that you can edit your source to:
>
> struct whats {
> unsigned int offset;
> unsigned int sysno;
> } happening[] __attribute__((section(".openbsd.syscalls"))) = {
> { 0x104cc, 4 },
> { 0x10480, 1 },
> };
>
> and recompile and link again, then it works. A slight reshuffling of
> the "not-C" code might also be needed, or the compiler will whine at
> you for calling stuff without declaration of the functions. Binary
> size down to some 2600 bytes after "strip"ing, and it's now "free" of
> libc. Also, it is rather cumbersome to double-compile all the time.
>
> --
> May the most significant bit of your life be positive.
--
May the most significant bit of your life be positive.