require 'msf/core/exploit/local/compile_c'

module Msf
module Exploit::Local::Linux
	include Exploit::Local::CompileC

	def linux_x86_syscall_wrappers(metasm_exe)
		cparser.parse <<-EOC
			#ifndef size_t
			#define size_t int
			#endif
			#ifndef off_t
			#define off_t unsigned long
			#endif

			#define O_CREAT 64
			#define O_RDWR 2

			#define MAP_PRIVATE   0x02
			#define MAP_FIXED     0x10
			#define MAP_ANONYMOUS 0x20
			#define MAP_ANON MAP_ANONYMOUS
			#define MAP_FAILED ((void *)-1)

			#define PROT_READ  0x1
			#define PROT_WRITE 0x2
			#define PROT_EXEC  0x4

			void exit(int status);
			int read(int fd, void *buf, size_t count);
			int write(int fd, void *buf, size_t count);
			int open(const char *pathname, int flags, int mode);
			int unlink(const char *pathname);
			int ftruncate(int fd, off_t length);
			int socket(int, int, int);
			int sendfile(int in_fd, int out_fd, void *, int count);
			void *__mmap2(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

			#ifdef DEBUGGING
			void sigtrap();
			#else
			#define sigtrap()
			#endif
			void *__get_tls();

		EOC
		metasm_exe.parse <<-EOS
			sigtrap:
				int    3
				ret
			exit:
				mov    eax, 1         ; sys_exit
				mov    ebx, [esp+4]
				int    0x80
				ret
			read:
				mov    eax, 3         ; sys_write
				mov    edx,[esp+12]   ; length
				mov    ecx,[esp+8]    ; string
				mov    ebx,[esp+4]    ; file descriptor
				int    0x80
				ret
			write:
				mov    eax, 4         ; sys_write
				mov    edx,[esp+12]   ; length
				mov    ecx,[esp+8]    ; string
				mov    ebx,[esp+4]    ; file descriptor
				int    0x80
				ret
			open:
				mov    eax, 5         ; sys_open
				mov    edx,[esp+12]   ; mode
				mov    ecx,[esp+8]    ; flags
				mov    ebx,[esp+4]    ; file name
				int    0x80
				cmp    eax, -129
				jb     1f
				neg    eax
				push   eax
				call   __set_errno
				add    esp, 4
				or     eax, -1
			1:
				ret
			ftruncate:
				push   ebx
				push   ecx
				mov    eax, 93        ; sys_ftruncate
				mov    ecx,[esp+16]   ; file descriptor
				mov    ebx,[esp+12]   ; size
				int    0x80
				cmp    eax, -129
				jb     1f
				neg    eax
				push   eax
				call   __set_errno
				add    esp, 4
				or     eax, -1
			1:
				pop    ecx
				pop    ebx
				ret
			socket:
				push   ebx
				push   ecx
				mov    eax, 102       ; sys_socketcall
				mov    ebx, 1
				mov    ecx, esp
				add    ecx, 12
				int    0x80
				cmp    eax, -129
				jb     1f
				neg    eax
				push   eax
				call   __set_errno
				add    esp, 4
				or     eax, -1
			1:
				pop    ecx
				pop    ebx
				ret
			sendfile:
				push   ebx
				push   ecx
				push   edx
				push   esi

				mov    eax, 187       ; sys_sendfile
				mov    esi,[esp+32]   ; size
				mov    edx,[esp+28]   ; offset
				mov    ecx,[esp+24]    ; out_fd
				mov    ebx,[esp+20]    ; in_fd
				int    0x80
				cmp    eax, -129
				jb     1f
				neg    eax
				push   eax
				call   __set_errno
				add    esp, 4
				or     eax, -1
			1:
				pop    esi
				pop    edx
				pop    ecx
				pop    ebx
				ret

			unlink:
				mov    eax, 10        ; sys_unlink
				mov    ebx,[esp+4]    ; filename
				int    0x80
				ret

			; stolen from bionic
			__mmap2:
				push   ebx
				push   ecx
				push   edx
				push   esi
				push   edi
				push   ebp

				mov    eax, 192
				mov    ebx, [esp+28]
				mov    ecx, [esp+32]
				mov    edx, [esp+36]
				mov    esi, [esp+40]
				mov    edi, [esp+44]
				mov    ebp, [esp+48]
				int    0x80
				cmp    eax, -129
				jb     1f
				neg    eax
				push   eax
				call   __set_errno
				add    esp, 4
				or     eax, -1
			1:
				pop    ebp
				pop    edi
				pop    esi
				pop    edx
				pop    ecx
				pop    ebx
				ret

			; Thread Local Storage, used by errno
			__get_tls:
				mov    eax, gs:[0]
				ret
		EOS

	end
end
end

