diff --git a/.gitattributes b/.gitattributes index 3cb6410ac237805e3cc5bbe434cd95cc5673d167..d539d16943e7f7d170a3a5e3a0be50029e382a7c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,8 @@ * text=auto !eol /Makefile.in -text +buffrecv/Makefile.in -text +buffrecv/br_callbacks.c -text +buffrecv/cgc.s -text canaries/Makefile.in -text canaries/canaries_callbacks.c -text canaries/debug_canary_callbacks.c -text diff --git a/buffrecv/Makefile.in b/buffrecv/Makefile.in new file mode 100644 index 0000000000000000000000000000000000000000..2951b502824c067f08ad83782aa8fea8b57a53b9 --- /dev/null +++ b/buffrecv/Makefile.in @@ -0,0 +1,28 @@ + + +CC=@CC@ +CFLAGS=@CFLAGS@ +LIB=@LIB@ +AR=@AR@ +AS=@AS@ +ASFLAGS=@ASFLAGS@ + +OBJS=br_callbacks.o cgc.o + + +.SUFFIXES: .o .s .c + +.c.o: + $(CC) $(CFLAGS) $(INCLUDE) -D__$(ARCH) -c $< + +.s.o: + $(AS) $(ASFLAGS) $< + + +all: $(OBJS) + $(AR) -r $(LIB) $(OBJS) + +clean: + rm *.o + + diff --git a/buffrecv/br_callbacks.c b/buffrecv/br_callbacks.c new file mode 100644 index 0000000000000000000000000000000000000000..a2870b6bf2ff0fd3de54310046f4d89feee0e783 --- /dev/null +++ b/buffrecv/br_callbacks.c @@ -0,0 +1,226 @@ +#ifdef DEBUG + +#include "malloc.h" +#include "itox.h" +#include "strlen.h" +#include "null.h" + +#define DEBUG_ADD +#else + +typedef unsigned uintptr_t; +#define NULL 0L + +#endif + + +#ifdef DEBUG + #define print_str_debug print_str + #define print_int_debug print_int + #define assert(a) {if(!a) print_str("assert failure!"), cgc_terminate(254);} +#else + #define print_str_debug(a) + #define print_int_debug(a) + #define assert(a) +#endif + + +#ifdef DEBUG +#define write_fd 2 +void print_char(char c) +{ + write(write_fd,&c,1); +} +void print_str(char *s) +{ + write(write_fd,s,strlen(s)); +} +void print_int(int x) +{ + char buf[100]; + itox(x,buf); + write(write_fd,buf,strlen(buf)); +} +#endif + + + +typedef struct +{ + int edi; + int esi; + int ebp; + int esp_dummy; + int ebx; + int edx; + int ecx; + int eax; + int flags; +} reg_values_t; + +/* +deallocate(addr, length) +int zipr_delayed_deallocate(unsigned int ret_pc, reg_values_t rv) +{ + void *addr=rv.ebx; + unsigned int length=rv.ecx; + + static void* old_addr=0; + static unsigned int old_length=0; + + cgc_deallocate(old_addr,old_length); + + old_addr=addr; + old_length=length; + return 0; +} + +global cgc_receive +cgc_receive: + +orig_receive: + mov eax,0x3 + push ebx + push ecx + push edx + push esi + mov ebx, [esp+0x14] + mov ecx, [esp+0x18] + mov edx, [esp+0x1c] + mov esi, [esp+0x20] + + pushf + pusha + push retPC + int 0x80 ==> NOP callback to buffered_receive() + + +retPC: + + popa + popf + + pop esi + pop edx + pop ecx + pop ebx + ret +*/ + + +#define STORAGE_SIZE 128 +static char storage[STORAGE_SIZE]; +static int cursor_pos = 0; +static int bytes_buffered = 0; + +int buffered_receive(unsigned int ret_pc, reg_values_t rv) +{ + int fd = rv.ebx; + char *buf = (char*) rv.ecx; + int count = rv.edx; + int *rx_bytes = (int*) rv.esi; + +#ifdef DEBUG + print_str("\ncount: "); + print_int(count); + print_str("\n*rx_bytes: "); + print_int((int)rx_bytes); +#endif + + int ret = cgc_receive(fd, buf, count, rx_bytes); + +#ifdef DEBUG + print_str("\nret: "); + print_int(ret); + print_str("\nfd: "); + print_int(fd); + print_str("\nbuf[0]: "); + print_char(buf[0]); + print_str("\ncount: "); + print_int(count); + print_str("\nrx_bytes: "); + print_int(*rx_bytes); +#endif + + rv.eax = ret; + return ret; +} + +#ifdef XXX +/* +static int receive2(int fd, char *buf, int count, int *rx_bytes) +{ +*/ + int bytes_out = 0; + + if (bytes_buffered == 0) + { + cursor_pos = 0; + + // handle the case where nothing's buffered + // and requested size > STORAGE_SIZE + if (count > STORAGE_SIZE) + { + // call out to original receive() + return cgc_receive(fd, buf, count, rx_bytes); + } + } + else + { + // drain out buffer up to count bytes + while (bytes_buffered > 0 && bytes_out < count) { + *buf++ = storage[cursor_pos++]; + bytes_out++; + bytes_buffered--; + } + + if (bytes_buffered == 0 || cursor_pos == STORAGE_SIZE) { + cursor_pos = 0; + } + + // if we're lucky, we've copied out all the requested data + count -= bytes_out; + if (count == 0) + { + if (rx_bytes) + *rx_bytes = bytes_out; + return 0; + } + } + + // fill up the storage area again + int num_bytes; + int err_code = cgc_receive(fd, &storage[cursor_pos], STORAGE_SIZE - cursor_pos, &num_bytes); + if (err_code == 0) + { + int bytes_to_copy = count; + if (num_bytes < count) { + bytes_to_copy = num_bytes; + } + + // copy out to user buffer + while (bytes_to_copy--) { + *buf++ = storage[cursor_pos++]; + } + + bytes_buffered = num_bytes - count; + if (bytes_buffered >= 0) + { + if (rx_bytes) + *rx_bytes = count + bytes_out; + } + else + { + // the user requested more bytes that we can hold in storage area... + // return only the bytes we have + // higher-level code has to be able to cope w/ the case + // where the OS returns fewer bytes than requested anyhow + if (rx_bytes) + *rx_bytes = num_bytes + bytes_out; + bytes_buffered = 0; + } + } + + return err_code; +} +#endif diff --git a/buffrecv/cgc.s b/buffrecv/cgc.s new file mode 100644 index 0000000000000000000000000000000000000000..44d7645b802d07a1bf44811f9172c0c5b7ba6ce1 --- /dev/null +++ b/buffrecv/cgc.s @@ -0,0 +1,136 @@ +%ifdef CGC +section .text + + +BITS 32 + +global cgc_terminate +cgc_terminate: + mov eax,0x1 + push ebx + mov ebx, [esp+0x8] + int 0x80 + pop ebx + ret + +global cgc_transmit +cgc_transmit: + mov eax,0x2 + push ebx + push ecx + push edx + push esi + mov ebx, [esp+0x14] + mov ecx, [esp+0x18] + mov edx, [esp+0x1c] + mov esi, [esp+0x20] + int 0x80 + pop esi + pop edx + pop ecx + pop ebx + ret + + +global cgc_receive +cgc_receive: + mov eax,0x3 + push ebx + push ecx + push edx + push esi + mov ebx, [esp+0x14] + mov ecx, [esp+0x18] + mov edx, [esp+0x1c] + mov esi, [esp+0x20] + int 0x80 + pop esi + pop edx + pop ecx + pop ebx + ret + +global cgc_fdwait +cgc_fdwait: + mov eax,0x4 + push ebx + push ecx + push edx + push esi + push edi + mov ebx, [esp+0x18] + mov ecx, [esp+0x1c] + mov edx, [esp+0x20] + mov esi, [esp+0x24] + mov edi, [esp+0x28] + int 0x80 + pop edi + pop esi + pop edx + pop ecx + pop ebx + ret + +global cgc_allocate +cgc_allocate: + mov eax,0x5 + push ebx + push ecx + push edx + mov ebx, [esp+0x10] + mov ecx, [esp+0x14] + mov edx, [esp+0x18] + int 0x80 + pop edx + pop ecx + pop ebx + ret + +global cgc_deallocate +cgc_deallocate: + mov eax,0x6 + push ebx + push ecx + mov ebx, [esp+0xc] + mov ecx, [esp+0x10] + int 0x80 + pop ecx + pop ebx + ret + +global cgc_random +cgc_random: + mov eax,0x7 + push ebx + push ecx + push edx + mov ebx, [esp+0x10] + mov ecx, [esp+0x14] + mov edx, [esp+0x18] + int 0x80 + pop edx + pop ecx + pop ebx + ret + +%else + +global syscall +syscall: + push edi + push esi + push ebx + mov edi, [esp+0x24] + mov esi, [esp+0x20] + mov edx, [esp+0x1c] + mov ecx, [esp+0x18] + mov ebx, [esp+0x14] + mov eax, [esp+0x10] + int 0x80 + pop ebx + pop esi + pop edi + ret + + +%endif