#include <sys/auxv.h>
struct DuckInfo {
unsigned long abi; const char *stdin_ptr; unsigned long stdin_size;
char *stdout_ptr; unsigned long stdout_limit; unsigned long stdout_size;
char *stderr_ptr; unsigned long stderr_limit; unsigned long stderr_size;
const char *IB_ptr; unsigned long IB_limit;
char *OB_ptr; unsigned long OB_limit; unsigned long tsc;
} __attribute__((packed));
int plus(int a, int b) { return a + b; }
// parse auxv from stack to get duckinfo
static struct DuckInfo *get_duck(char **av) {
char **e = av + 2; // hmm: main(ac,av) not called; we have av passed to __libc_start_main
while (*e) e++;
unsigned long *aux = (unsigned long *)(e + 1);
for (; aux[0]; aux += 2) if (aux[0] == 0x6b637564) return (struct DuckInfo *)aux[1];
return 0;
}
__attribute__((naked)) void __libc_start_main(void) {
// rsi = argv at entry? crt1: _start_c passes (main, argc, argv) — our naked gets: rdi=main, rsi=argc, rdx=argv
// find duckinfo via argv
__asm__ volatile(
"push %rdx\n"
"mov %rdx,%rdi\n" // argv
"add $16,%rdi\n" // skip argc+argv[0]
"1: mov (%rdi),%rax\n"
"add $8,%rdi\n"
"test %rax,%rax\n"
"jne 1b\n"
"2: mov (%rdi),%rax\n"
"test %rax,%rax\n"
"je 3f\n"
"cmp $0x6b637564,%rax\n"
"je 4f\n"
"add $16,%rdi\n"
"jmp 2b\n"
"4: mov 8(%rdi),%rbx\n" // duckinfo ptr in rbx
"mov %rbx,%rsi\n"
"add $32,%rsi\n" // stdout_ptr at offset 16+8=24? abi8 stdin_ptr8 stdin_size8 = 24 → stdout_ptr at 24
"mov (%rsi),%rdi\n" // stdout_ptr
"movb $79,(%rdi)\n" // 'O'
"movb $75,1(%rdi)\n" // 'K'
"movb $10,2(%rdi)\n" // '\n'
"movq $3,8(%rsi)\n" // stdout_size = 3 (offset 8 from stdout_ptr)
"3: mov $60,%eax\n"
"xor %edi,%edi\n"
"syscall\n"
"pop %rdx\n"
);
}
| Compilation | N/A | N/A | Compile OK | Score: N/A | 显示更多 |
| Testcase #1 | 2.6 us | 8 KB | Wrong Answer | Score: 0 | 显示更多 |