From 8b92a40e19c1a90a31e7514de1c90f0cf558a62a Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 22 Jan 2020 02:08:30 +0100 Subject: [PATCH] c example now uses persistent mode --- unicorn_mode/samples/c/a.out | Bin 17184 -> 0 bytes unicorn_mode/samples/c/harness.c | 43 ++++++++++++++---- .../{simple_target.c => persistent_target.c} | 27 ++++++----- .../samples/c/persistent_target_x86_64 | Bin 0 -> 16544 bytes 4 files changed, 50 insertions(+), 20 deletions(-) delete mode 100644 unicorn_mode/samples/c/a.out rename unicorn_mode/samples/c/{simple_target.c => persistent_target.c} (51%) create mode 100644 unicorn_mode/samples/c/persistent_target_x86_64 diff --git a/unicorn_mode/samples/c/a.out b/unicorn_mode/samples/c/a.out deleted file mode 100644 index 176c25e1232741d579008dd24852586a98600468..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17184 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 // Path to the file containing the binary to emulate -#define BINARY_FILE ("simple_target_x86_64") +#define BINARY_FILE ("persistent_target_x86_64") // Memory map for the code to be tested // Arbitrary address where code to test will be loaded static const int64_t BASE_ADDRESS = 0x100000; -static const int64_t CODE_ADDRESS = 0x101119; -static const int64_t END_ADDRESS = 0x1011d7; +static const int64_t CODE_ADDRESS = 0x101139; +static const int64_t END_ADDRESS = 0x10120d; // Address of the stack (Some random address again) static const int64_t STACK_ADDRESS = (((int64_t) 0x01) << 58); // Size of the stack (arbitrarily chosen, just make it big enough) @@ -52,15 +52,33 @@ static const int64_t ALIGNMENT = 0x1000; // In our special case, we emulate main(), so argc is needed. static const uint64_t EMULATED_ARGC = 2; +// The return from our fake strlen +static size_t current_input_len = 0; + static void hook_block(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) { printf(">>> Tracing basic block at 0x%"PRIx64 ", block size = 0x%x\n", address, size); } -static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) -{ +static void hook_code(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) { printf(">>> Tracing instruction at 0x%"PRIx64 ", instruction size = 0x%x\n", address, size); } +/* +The sample uses strlen, since we don't have a loader or libc, we'll fake it. +We know the strlen will return the lenght of argv[1] that we just planted. +It will be a lot faster than an actual strlen for this specific purpose. +*/ +static void hook_strlen(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) { + //Hook + //116b: e8 c0 fe ff ff call 1030 + // We place the return at RAX + //printf("Strlen hook at addr 0x%lx (size: 0x%x), result: %ld\n", address, size, current_input_len); + uc_reg_write(uc, UC_X86_REG_RAX, ¤t_input_len); + // We skip the actual call by updating RIP + uint64_t next_addr = address + size; + uc_reg_write(uc, UC_X86_REG_RIP, &next_addr); +} + /* Unicorn page needs to be 0x1000 aligned, apparently */ static uint64_t pad(uint64_t size) { if (size % ALIGNMENT == 0) return size; @@ -107,8 +125,6 @@ static bool place_input_callback( // Test input too short or too long, ignore this testcase return false; } - // We need a valid c string, make sure it never goes out of bounds. - input[input_len-1] = '\0'; // For persistent mode, we have to set up stack and memory each time. uc_reg_write(uc, UC_X86_REG_RIP, &CODE_ADDRESS); // Set the instruction pointer back @@ -116,10 +132,14 @@ static bool place_input_callback( uc_reg_write(uc, UC_X86_REG_RSI, &INPUT_LOCATION); // argv uc_reg_write(uc, UC_X86_REG_RDI, &EMULATED_ARGC); // argc == 2 - // Make sure the input is 0 terminated. - //input[input_len-1] = '\0'; + // We need a valid c string, make sure it never goes out of bounds. + input[input_len-1] = '\0'; // Write the testcase to unicorn. uc_mem_write(uc, INPUT_LOCATION + INPUT_OFFSET, input, input_len); + + // store input_len for the faux strlen hook + current_input_len = input_len; + return true; } @@ -211,6 +231,11 @@ int main(int argc, char **argv, char **envp) { uc_hook_add(uc, &hooks[1], UC_HOOK_CODE, hook_code, NULL, BASE_ADDRESS, BASE_ADDRESS + len - 1); } + // Add our strlen hook (for this specific testcase only) + int strlen_hook_pos = BASE_ADDRESS + 0x116b; + uc_hook strlen_hook; + uc_hook_add(uc, &strlen_hook, UC_HOOK_CODE, hook_strlen, NULL, strlen_hook_pos, strlen_hook_pos); + printf("Starting to fuzz :)\n"); fflush(stdout); diff --git a/unicorn_mode/samples/c/simple_target.c b/unicorn_mode/samples/c/persistent_target.c similarity index 51% rename from unicorn_mode/samples/c/simple_target.c rename to unicorn_mode/samples/c/persistent_target.c index dbf10911..5b866f86 100644 --- a/unicorn_mode/samples/c/simple_target.c +++ b/unicorn_mode/samples/c/persistent_target.c @@ -10,25 +10,30 @@ * Written by Nathan Voss * Adapted by Lukas Seidel */ +#include +#include int main(int argc, char** argv) { - if(argc < 2){ - return -1; - } + if (argc < 2) return -1; char *data_buf = argv[1]; + uint64_t data_len = strlen(data_buf); + if (data_len < 20) return -2; - if (data_buf[20] != 0) { - // Cause an 'invalid read' crash if data[0..3] == '\x01\x02\x03\x04' - unsigned char invalid_read = *(unsigned char *) 0x00000000; - } else if (data_buf[0] > 0x10 && data_buf[0] < 0x20 && data_buf[1] > data_buf[2]) { + for (; data_len --> 0 ;) { + if (data_len >= 18) continue; + if (data_len > 2 && data_len < 18) { + ((char *)data_len)[(uint64_t)data_buf] = data_buf[data_len + 1]; + } else if (data_buf[9] == 0x90 && data_buf[10] != 0x00 && data_buf[11] == 0x90) { + // Cause a crash if data[10] is not zero, but [9] and [11] are zero + unsigned char invalid_read = *(unsigned char *) 0x00000000; + } + } + if (data_buf[0] > 0x10 && data_buf[0] < 0x20 && data_buf[1] > data_buf[2]) { // Cause an 'invalid read' crash if (0x10 < data[0] < 0x20) and data[1] > data[2] unsigned char invalid_read = *(unsigned char *) 0x00000000; - } else if (data_buf[9] == 0x00 && data_buf[10] != 0x00 && data_buf[11] == 0x00) { - // Cause a crash if data[10] is not zero, but [9] and [11] are zero - unsigned char invalid_read = *(unsigned char *) 0x00000000; - } + } return 0; } diff --git a/unicorn_mode/samples/c/persistent_target_x86_64 b/unicorn_mode/samples/c/persistent_target_x86_64 new file mode 100644 index 0000000000000000000000000000000000000000..22e04357ebd63bb86b55a9ee5f451aa4851a0f9a GIT binary patch literal 16544 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 literal 0 HcmV?d00001