aboutsummaryrefslogtreecommitdiff
path: root/entry.c
diff options
context:
space:
mode:
authorn0p <0x90@n0p.cc>2018-10-25 23:14:29 +0200
committern0p <0x90@n0p.cc>2018-10-25 23:14:29 +0200
commit6814897ce2de08180b6537fcccfb104827e2a131 (patch)
treecf07de03d5800f8dd6e1c265e6122f8fcb650655 /entry.c
downloadForgetfulCommander-6814897ce2de08180b6537fcccfb104827e2a131.tar.gz
ForgetfulCommander-6814897ce2de08180b6537fcccfb104827e2a131.zip
Init.
Diffstat (limited to 'entry.c')
-rw-r--r--entry.c233
1 files changed, 233 insertions, 0 deletions
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");
+}