diff --git a/.gitignore b/.gitignore index 348204b..42ee0b9 100755 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ *.obj *.pdb *.ilk +*.log build/ plugins_install/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..122e075 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# windows-binary-fuzzing + +## API methods + +- [ ] `GetOpenFileNameA` +- [ ] `IFileOpenDialog` +- [ ] `QFileDialog::getOpenFileName` +- [ ] `wxFileDialog` + +## Build commands (client) + +```bash +mkdir build +cmake -DDynamoRIO_DIR=C:\Users\vboxuser\DynamoRIO-Windows\cmake .. +cmake --build . +``` + +## Execution commands (drrun) + +e.g. + +```bash +drrun -c ..\..\clients\mov_to_nop\build\Debug\mov_to_nop.dll -c C:\Users\vboxuser\git\winafl\build64\bin\Release\winafl.dll -debug -target_offset 0x8530 -fuzz_iterations 1 -nargs 2 -target_module Twice.exe -- .\Twice.exe +``` \ No newline at end of file diff --git a/clients/GetOpenFileNameA/CMakeLists.txt b/clients/GetOpenFileNameA/CMakeLists.txt new file mode 100644 index 0000000..eae5a07 --- /dev/null +++ b/clients/GetOpenFileNameA/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.7) +project(GetOpenFileNameA) + +find_package(DynamoRIO REQUIRED) +add_library(GetOpenFileNameA SHARED main.c) +target_link_libraries(GetOpenFileNameA drwrap drmgr) +configure_DynamoRIO_client(GetOpenFileNameA) diff --git a/clients/GetOpenFileNameA/main.c b/clients/GetOpenFileNameA/main.c new file mode 100644 index 0000000..521354e --- /dev/null +++ b/clients/GetOpenFileNameA/main.c @@ -0,0 +1,94 @@ +#include "dr_api.h" +#include "dr_ir_opnd.h" +#include "dr_ir_instr.h" +#include "dr_ir_opcodes_x86.h" +#include "dr_ir_macros_x86.h" + +#include +#include +#include +#include + +char *CUSTOM_FILE = "C:\\Users\\vboxuser\\Downloads\\spoofed_number.txt"; + +static app_pc pc_GetOpenFileNameA = NULL; + +static void intercept_GetOpenFileNameA() { + // dr_printf("intercept_GetOpenFileNameA(...)\n"); + + void *drcontext = dr_get_current_drcontext(); + + dr_mcontext_t mcontext = { sizeof(mcontext), DR_MC_ALL }; + dr_get_mcontext(drcontext, &mcontext); + + OPENFILENAME *ofn = (OPENFILENAME *)mcontext.rcx; + // dr_printf("OPENFILENAME at %p\n", ofn); + + for (int i = 0; i < strlen(CUSTOM_FILE); i++) ofn->lpstrFile[i] = CUSTOM_FILE[i]; + ofn->lpstrFile[strlen(CUSTOM_FILE)] = 0; + + mcontext.rax = 1; + + dr_set_mcontext(drcontext, &mcontext); +} + +static void event_exit(void) { + // dr_printf("Exiting custom DynamoRIO client...\n"); +} + +static void event_module_load(void *drcontext, const module_data_t *mod, bool loaded) { + char lowerpath[MAX_PATH]; + strcpy(lowerpath, mod->full_path); + for (int i = 0; i < strlen(lowerpath); i++) { + lowerpath[i] = tolower(lowerpath[i]); + } + + if (strstr(lowerpath, "comdlg32.dll")) { + pc_GetOpenFileNameA = (app_pc)dr_get_proc_address(mod->handle, "GetOpenFileNameA"); + // if (pc_GetOpenFileNameA) dr_printf("Found GetOpenFileNameA at %p\n", pc_GetOpenFileNameA); + } +} + + +static dr_emit_flags_t event_basic_block(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating) { + instr_t *to_remove = NULL, *instr = instrlist_first(bb); + while (instr) { + instr_t *next = instr_get_next(instr); + + app_pc target = NULL; + + if (instr_is_call_direct(instr)) { + app_pc target = instr_get_branch_target_pc(instr); + } else if (instr_is_call_indirect(instr)) { + opnd_t opnd = instr_get_src(instr, 0); + if (opnd_is_memory_reference(opnd)) { + app_pc addr = opnd_compute_address(opnd, drcontext); + if (addr) dr_safe_read(addr, sizeof(app_pc), &target, NULL); + } + } + + if (target == pc_GetOpenFileNameA) { + // dr_printf("Call to GetOpenFileNameA detected at %p\n", instr_get_app_pc(instr)); + + dr_insert_clean_call(drcontext, bb, instr, (void *)intercept_GetOpenFileNameA, false, 0); + + instrlist_remove(bb, instr); + instr_destroy(drcontext, instr); + instr = next; + } + + instr = next; + } + + return DR_EMIT_DEFAULT; +} + +DR_EXPORT void dr_client_main(client_id_t id, int argc, const char *argv[]) { + // dr_printf("Loading custom DynamoRIO client...\n"); + dr_set_client_name("Custom DynamoRIO client", "https://gitea.cloud.lehnert.dev/ludwig/windows-binary-fuzzing"); + dr_register_exit_event(event_exit); + dr_register_module_load_event(event_module_load); + dr_register_bb_event(event_basic_block); + // dr_printf("Custom DynamoRIO client loaded.\n"); +} + diff --git a/clients/build_all.ps1 b/clients/build_all.ps1 new file mode 100755 index 0000000..e8cc20b --- /dev/null +++ b/clients/build_all.ps1 @@ -0,0 +1,17 @@ +$CWD = (pwd).Path + +$DIR = $PSScriptRoot +cd $DIR + +Get-ChildItem -Directory | % { + $clientDir = "$DIR\$_" + $buildDir = "$DIR\$_\build" + + $$ = New-Item -ItemType Directory -Force $buildDir + cd $buildDir + + cmake -DDynamoRIO_DIR=C:\Users\vboxuser\DynamoRIO-Windows\cmake .. + cmake --build . +} + +cd $CWD diff --git a/clients/mov_to_nop/CMakeLists.txt b/clients/mov_to_nop/CMakeLists.txt deleted file mode 100644 index b4ac465..0000000 --- a/clients/mov_to_nop/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -cmake_minimum_required(VERSION 3.7) -project(mov_to_nop) - -find_package(DynamoRIO REQUIRED) -add_library(mov_to_nop SHARED mov_to_nop.c) -configure_DynamoRIO_client(mov_to_nop) diff --git a/clients/mov_to_nop/mov_to_nop.c b/clients/mov_to_nop/mov_to_nop.c deleted file mode 100644 index f67cdba..0000000 --- a/clients/mov_to_nop/mov_to_nop.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "dr_api.h" -#include "dr_ir_opcodes_x86.h" - -static dr_emit_flags_t event_basic_block(void *drcontext, void *tag, - instrlist_t *bb, bool for_trace, bool translating); - -DR_EXPORT void dr_client_main(client_id_t id, int argc, const char *argv[]) { - dr_set_client_name("MOV-to-NOP Client (No drmgr)", "https://dynamorio.org/"); - dr_register_bb_event(event_basic_block); - dr_printf("MOV-to-NOP client loaded (no drmgr).\n"); -} - -static dr_emit_flags_t event_basic_block(void *drcontext, void *tag, - instrlist_t *bb, bool for_trace, bool translating) { - for (instr_t *instr = instrlist_first_app(bb); - instr != NULL; - instr = instr_get_next_app(instr)) { - - int opcode = instr_get_opcode(instr); - if (opcode == OP_mov_st || opcode == OP_mov_ld) { - instr_set_opcode(instr, OP_nop); - } - } - - return DR_EMIT_DEFAULT; -} diff --git a/programs/Makefile b/programs/Makefile index 50dcc9d..3e2da7d 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -7,10 +7,10 @@ clean: del /Q "compiled\*" compiled\Foo.exe: source\Foo.c - $(CC) /Fe:$@ source\Foo.c comdlg32.lib $(CFLAGS) + $(CC) /Fe:$@ source\Foo.c $(CFLAGS) compiled\Twice.exe: source\Twice.c $(CC) /Fe:$@ source\Twice.c comdlg32.lib $(CFLAGS) compiled\JustOpen.exe: source\JustOpen.c - $(CC) /Fe:$@ source\JustOpen.c comdlg32.lib $(CFLAGS) \ No newline at end of file + $(CC) /Fe:$@ source\JustOpen.c comdlg32.lib $(CFLAGS)