From 6814897ce2de08180b6537fcccfb104827e2a131 Mon Sep 17 00:00:00 2001 From: n0p <0x90@n0p.cc> Date: Thu, 25 Oct 2018 23:14:29 +0200 Subject: Init. --- entry.c | 233 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 entry.c (limited to 'entry.c') diff --git a/entry.c b/entry.c new file mode 100644 index 0000000..f5bdf3d --- /dev/null +++ b/entry.c @@ -0,0 +1,233 @@ +/* + * clang -s -m32 -nostdlib -nodefaultlibs -fPIC -Wl,-shared entry.c -oentry + */ + +__attribute__((naked)) void entry() { + __asm__ volatile( + ".intel_syntax noprefix\n" + "push eax\n" + "pushad\n" + "pushfd\n" + + "sub esp, 0x5000\n" + + // get the pathname of the binary with readlink + "mov eax, 85\n" + // /proc/self/exe + "push 0x6578\n" + "push 0x652f666c\n" + "push 0x65732f63\n" + "push 0x6f72702f\n" + // pathname of the symlink + "mov ebx, esp\n" + // buf + "lea ecx, [esp + 0x4010]\n" + // bufsiz + "mov edx, 0xfff\n" + "int 0x80\n" + + // cleanup arguments from stack + "add esp, 0x10\n" + + "cmp eax, 0\n" + "jle fail\n" + + // save the length of the pathname + "mov edi, eax\n" + + // write newline at the end of the pathname + "lea ecx, [esp + 0x4000 + eax]\n" + "mov byte ptr [ecx], 0xa\n" + + // inc saved length, to also compare the newline + "inc edi\n" + + // open /proc/self/maps to get the base address of the binary + "mov eax, 5\n" + "push 0x737061\n" + "push 0x6d2f666c\n" + "push 0x65732f63\n" + "push 0x6f72702f\n" + "mov ebx, esp\n" + "xor ecx, ecx\n" + "int 0x80\n" + + // cleanup arguments from stack + "add esp, 0x10\n" + + "cmp eax, 0\n" + "jl fail\n" + + // save the fd + "mov esi, eax\n" + + // loop to get the program base + // read from /proc/self/maps + "read:" + "mov eax, 3\n" + "mov ebx, esi\n" + "mov ecx, esp\n" + "mov edx, 0x4000\n" + "int 0x80\n" + + "cmp eax, 0\n" + "jle close\n" + + // set maps iterator to 0 + "xor ecx, ecx\n" + // set pathname iterator to 0 + "xor edx, edx\n" + // ebp will be set to 0, if we got a match + "mov ebp, 1\n" + + "find_pathname:\n" + "cmp ecx, eax\n" + "jge find_pathname_finished\n" + + // char from the maps buffer + "movzx ebx, byte ptr [esp + ecx]\n" + // compare with char in the pathname buffer + // always inc maps iterator + "inc ecx\n" + "cmp byte ptr [esp + edx + 0x4000], bl\n" + "jnz find_pathname_no_match\n" + // inc pathname iterator + "inc edx\n" + // have we found the full pathname? + "cmp edx, edi\n" + "jnz find_pathname\n" + // jepp + "xor ebp, ebp\n" + "jmp find_pathname_finished\n" + + "find_pathname_no_match:\n" + // reset pathname iterator + "xor edx, edx\n" + "jmp find_pathname\n" + + "find_pathname_finished:\n" + + // did we have a match? + "test ebp, ebp\n" + "jnz read\n" + // jepp + // search the beginning of the maps line + "find_beginning_of_line:" + "xor ebx, ebx\n" + "dec ecx\n" + // is the maps iterator non null? + "cmp ecx, 0\n" + "setg bl\n" + // is the char before the maps iterator not a '\n' + "cmp byte ptr [esp + ecx - 1], 0xa\n" + "setnz bh\n" + "test bl, bh\n" + "jnz find_beginning_of_line\n" + + // convert the 8 hex digits to 4 bytes => the base address + "xor edx, edx\n" + "mov ebp, ecx\n" + "add ecx, 8\n" + "convert_base:" + "cmp ebp, ecx\n" + "jge close\n" + "rol edx, 4\n" + + // check if it's a number + "xor ebx, ebx\n" + "cmp byte ptr [esp + ecx + ebp], 0x30\n" + "setge bl\n" + "cmp byte ptr [esp + ecx + ebp], 0x39\n" + "setle bh\n" + "sub byte ptr [esp + ecx + ebp], 0x30\n" + "xor dl, byte ptr [esp + ecx + ebp]\n" + "inc ebp\n" + "test bl, bh\n" + "jnz convert_base\n" + // wasn't a number, revert stuff + "dec ebp\n" + "xor dl, byte ptr [esp + ecx + ebp]\n" + "add byte ptr [esp + ecx + ebp], 0x30\n" + // check if it's a lowercase hex letter + "xor ebx, ebx\n" + "cmp byte ptr [esp + ecx + ebp], 0x61\n" + "setge bl\n" + "cmp byte ptr [esp + ecx + ebp], 0x7a\n" + "setle bh\n" + "sub byte ptr [esp + ecx + ebp], 0x57\n" + "xor dl, byte ptr [esp + ecx + ebp]\n" + "inc ebp\n" + "test bl, bh\n" + "jnz convert_base\n" + // wasn't a lowercase hex letter, revert stuff + "dec ebp\n" + "xor dl, byte ptr [esp + ecx + ebp]\n" + "add byte ptr [esp + ecx + ebp], 0x61\n" + // check if it's an uppercase hex letter + "xor ebx, ebx\n" + "cmp byte ptr [esp + ecx + ebp], 0x41\n" + "setge bl\n" + "cmp byte ptr [esp + ecx + ebp], 0x5a\n" + "setle bh\n" + "sub byte ptr [esp + ecx + ebp], 0x37\n" + "xor dl, byte ptr [esp + ecx + ebp]\n" + "inc ebp\n" + "test bl, bh\n" + "jnz convert_base\n" + // wasn't an uppercase hex letter, failed to convert + "xor edx, edx\n" + "jmp close\n" + + "jmp read\n" + + "close:\n" + // close the fd + "mov eax, 6\n" + "mov ebx, esi\n" + "int 0x80\n" + + // if the base hasn't been found quit + "test edx, edx\n" + "jz fail\n" + + // set the oep as return + "add edx, 0x2050\n" + "mov dword ptr [esp + 0x5024], edx\n" + "sub edx, 0x50\n" + + "mov ebp, eax\n" + "inc eax\n" + "inc eax\n" + + "dec_outer_loop:\n" + "mov esi, 0x466c7578\n" + "xor ebx, ebx\n" + "cmp eax, ebp\n" + "jz dec_outer_loop_finished\n" + + "mov ecx, 0x400\n" + + "dec_inner_loop:\n" + "xor dword ptr [edx], ebx\n" + "xor dword ptr [edx], esi\n" + "ror esi, 8\n" + "mov ebx, dword ptr [edx]\n" + "add edx, 4\n" + "loop dec_inner_loop\n" + + "dec eax\n" + "jmp dec_outer_loop\n" + + "dec_outer_loop_finished:\n" + + "add esp, 0x5000\n" + "popfd\n" + "popad\n" + "ret\n" + + "fail:\n" + // exit the program gracefully + "mov eax, 1\n" + "xor ebx, ebx\n" + "int 0x80"); +} -- cgit v1.2.3