about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/afl-fuzz-init.c6
-rw-r--r--unicorn_mode/samples/c/harness.c50
2 files changed, 33 insertions, 23 deletions
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 5fe3689e..48b0d8ac 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -1940,17 +1940,17 @@ void check_binary(u8* fname) {
 
   }
 
-  if ((qemu_mode || unicorn_mode) &&
+  if ((qemu_mode) &&
       memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) {
 
     SAYF("\n" cLRD "[-] " cRST
          "This program appears to be instrumented with afl-gcc, but is being "
          "run in\n"
-         "    QEMU or Unicorn mode (-Q or -U). This is probably not what you "
+         "    QEMU mode (-Q). This is probably not what you "
          "want -\n"
          "    this setup will be slow and offer no practical benefits.\n");
 
-    FATAL("Instrumentation found in -Q or -U mode");
+    FATAL("Instrumentation found in -Q mode");
 
   }
 
diff --git a/unicorn_mode/samples/c/harness.c b/unicorn_mode/samples/c/harness.c
index cc81ba7f..4239b222 100644
--- a/unicorn_mode/samples/c/harness.c
+++ b/unicorn_mode/samples/c/harness.c
@@ -33,21 +33,24 @@
 
 // Memory map for the code to be tested
 // Arbitrary address where code to test will be loaded
-#define BASE_ADDRESS (0x100000)
-#define CODE_ADDRESS (0x101119)
-#define END_ADDRESS  (0x1011d7)
+static const int64_t BASE_ADDRESS = 0x100000;
+static const int64_t CODE_ADDRESS = 0x101119;
+static const int64_t END_ADDRESS = 0x1011d7;
 // Address of the stack (Some random address again)
-#define STACK_ADDRESS (((int64_t) 0x01) << 58)
+static const int64_t STACK_ADDRESS = (((int64_t) 0x01) << 58);
 // Size of the stack (arbitrarily chosen, just make it big enough)
-#define STACK_SIZE (0x10000)  
+static const int64_t STACK_SIZE = 0x10000;
 // Location where the input will be placed (make sure the emulated program knows this somehow, too ;) )
-#define INPUT_LOCATION (0x10000)
+static const int64_t INPUT_LOCATION = 0x10000;
 // Inside the location, we have an ofset in our special case
-#define INPUT_OFFSET (0x16) 
+static const int64_t INPUT_OFFSET = 0x16;
 // Maximum allowable size of mutated data from AFL
-#define INPUT_SIZE_MAX (0x10000)  
+static const int64_t INPUT_SIZE_MAX = 0x10000;
 // Alignment for unicorn mappings (seems to be needed)
-#define ALIGNMENT ((uint64_t) 0x1000)
+static const int64_t ALIGNMENT = 0x1000;
+
+// In our special case, we emulate main(), so argc is needed.
+static const uint64_t EMULATED_ARGC = 2;
 
 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);
@@ -100,10 +103,22 @@ static bool place_input_callback(
     void *data
 ){
     // printf("Placing input with len %ld to %x\n", input_len, DATA_ADDRESS);
-    if (input_len >= INPUT_SIZE_MAX - INPUT_OFFSET) {
-        // Test input too long, ignore this testcase
+    if (input_len < 1 || input_len >= INPUT_SIZE_MAX - INPUT_OFFSET) {
+        // 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
+    // Set up the function parameters accordingly RSI, RDI (see calling convention/disassembly)
+    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';
+    // Write the testcase to unicorn.
     uc_mem_write(uc, INPUT_LOCATION + INPUT_OFFSET, input, input_len);
     return true;
 }
@@ -188,12 +203,7 @@ int main(int argc, char **argv, char **envp) {
 
     uc_mem_write(uc, 0x10008, "\x16\x00\x01", 3); // little endian of 0x10016, see above
 
-    // Set up the function parameters accordingly RSI, RDI (see calling convention/disassembly)
-    uint64_t input_location = INPUT_LOCATION;
-    uc_reg_write(uc, UC_X86_REG_RSI, &input_location); // argv
-    uint64_t emulated_argc = 2;
-    uc_reg_write(uc, UC_X86_REG_RDI, &emulated_argc);  // argc == 2
-   
+
     // If we want tracing output, set the callbacks here
     if (tracing) {
         // tracing all basic blocks with customized callback
@@ -212,9 +222,9 @@ int main(int argc, char **argv, char **envp) {
         &end_address, // Where to exit (this is an array)
         1,  // Count of end addresses
         NULL, // Optional calback to run after each exec
-        false,
-        1, // For persistent mode: How many rounds to run
-        NULL
+        false, // true, if the optional callback should be run also for non-crashes
+        100, // For persistent mode: How many rounds to run
+        NULL // additional data pointer
     );
     switch(afl_ret) {
         case UC_AFL_RET_ERROR: