diff --git a/.gitignore b/.gitignore index 42ee0b9..b7a283c 100755 --- a/.gitignore +++ b/.gitignore @@ -7,9 +7,15 @@ *.ilk *.log +*.Debug +*.Release +*.stash + build/ plugins_install/ .sconsign.dblite peasoup_executable*/ + +/programs/Makefile* \ No newline at end of file diff --git a/README.md b/README.md index 122e075..22502b0 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,36 @@ # windows-binary-fuzzing -## API methods +## DLL methods -- [ ] `GetOpenFileNameA` -- [ ] `IFileOpenDialog` -- [ ] `QFileDialog::getOpenFileName` +- [x] `GetOpenFileNameA` +- [x] `QFileDialog::getOpenFileName` +- [ ] `QFileDialog::getOpenFileNames` +- [ ] `QFileDialog::getOpenFileUrl` +- [ ] `QFileDialog::getOpenFileUrls` +- [ ] `QFileDialog::getOpenFileContent` - [ ] `wxFileDialog` +- [ ] `IFileOpenDialog` -## Build commands (client) +## Build scripts ```bash -mkdir build -cmake -DDynamoRIO_DIR=C:\Users\vboxuser\DynamoRIO-Windows\cmake .. -cmake --build . +# Client(s) +clients/build_all.ps1 + +# Programs +programs/build.bat ``` ## Execution commands (drrun) -e.g. +### `GetOpenFileNameA.exe` ```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 +drrun -c ..\..\clients\CustomClient\build\Debug\CustomClient.dll -c C:\Users\vboxuser\git\winafl\build64\bin\Release\winafl.dll -debug -target_offset 0x8530 -fuzz_iterations 1 -nargs 2 -target_module .\GetOpenFileNameA.exe -- .\GetOpenFileNameA.exe +``` + +### `\QT_getOpenFileName.exe` + +```bash +drrun -c ..\..\clients\CustomClient\build\Debug\CustomClient.dll -c C:\Users\vboxuser\git\winafl\build64\bin\Release\winafl.dll -debug -target_offset 0x1320 -fuzz_iterations 1 -nargs 2 -target_module .\QT_getOpenFileName.exe -- .\QT_getOpenFileName.exe ``` \ No newline at end of file diff --git a/clients/CustomClient/CMakeLists.txt b/clients/CustomClient/CMakeLists.txt new file mode 100644 index 0000000..e76191a --- /dev/null +++ b/clients/CustomClient/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.7) +project(CustomClient) + +find_package(DynamoRIO REQUIRED) +add_library(CustomClient SHARED client.c) +target_link_libraries(CustomClient drwrap drmgr) +configure_DynamoRIO_client(CustomClient) diff --git a/clients/GetOpenFileNameA/main.c b/clients/CustomClient/client.c similarity index 63% rename from clients/GetOpenFileNameA/main.c rename to clients/CustomClient/client.c index 521354e..5cff7f8 100644 --- a/clients/GetOpenFileNameA/main.c +++ b/clients/CustomClient/client.c @@ -13,16 +13,16 @@ 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"); +static app_pc pc_QString_QString = NULL; +static app_pc pc_QFileDialog_getOpenFileName = NULL; +static void intercept_GetOpenFileNameA() { 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; @@ -32,8 +32,19 @@ static void intercept_GetOpenFileNameA() { dr_set_mcontext(drcontext, &mcontext); } +static void intercept_QFileDialog_getOpenFileName() { + void *drcontext = dr_get_current_drcontext(); + + dr_mcontext_t mcontext = { sizeof(mcontext), DR_MC_ALL }; + dr_get_mcontext(drcontext, &mcontext); + + // make use of QString constructor to construct return value + void *QString = (void *)mcontext.rcx; + void(*QString_QString)(void *, char *) = (void(*)(void *, char *))pc_QString_QString; + QString_QString(QString, CUSTOM_FILE); +} + 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) { @@ -43,6 +54,16 @@ static void event_module_load(void *drcontext, const module_data_t *mod, bool lo lowerpath[i] = tolower(lowerpath[i]); } + if (strstr(lowerpath, "qt6core.dll")) { + pc_QString_QString = (app_pc)dr_get_proc_address(mod->handle, "??0QString@@QEAA@PEBD@Z"); + // if (pc_QString_QString) dr_printf("Found QString::QString at %p\n", pc_QString_QString); + } + + if (strstr(lowerpath, "qt6widgets.dll")) { + pc_QFileDialog_getOpenFileName = (app_pc)dr_get_proc_address(mod->handle, "?getOpenFileName@QFileDialog@@SA?AVQString@@PEAVQWidget@@AEBV2@11PEAV2@V?$QFlags@W4Option@QFileDialog@@@@@Z"); + // if (pc_QFileDialog_getOpenFileName) dr_printf("Found QFileDialog::getOpenFileName at %p\n", pc_QFileDialog_getOpenFileName); + } + 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); @@ -67,14 +88,22 @@ static dr_emit_flags_t event_basic_block(void *drcontext, void *tag, instrlist_t } } + if (!target) { + instr = next; + continue; + } + 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; + } + else if (target == pc_QFileDialog_getOpenFileName) { + // dr_printf("Call to QFileDialog::getOpenFileName detected at %p\n", instr_get_app_pc(instr)); + dr_insert_clean_call(drcontext, bb, instr, (void *)intercept_QFileDialog_getOpenFileName, false, 0); + instrlist_remove(bb, instr); + instr_destroy(drcontext, instr); } instr = next; @@ -84,11 +113,9 @@ static dr_emit_flags_t event_basic_block(void *drcontext, void *tag, instrlist_t } 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/GetOpenFileNameA/CMakeLists.txt b/clients/GetOpenFileNameA/CMakeLists.txt deleted file mode 100644 index eae5a07..0000000 --- a/clients/GetOpenFileNameA/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -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/programs/build.bat b/programs/build.bat new file mode 100644 index 0000000..55db7db --- /dev/null +++ b/programs/build.bat @@ -0,0 +1,6 @@ +cl /Fe:compiled\Foo.exe source\Foo.c /Zi /Od /link /MACHINE:X64 + +cl /Fe:compiled\GetOpenFileNameA.exe comdlg32.lib source\GetOpenFileNameA.c /Zi /Od /link /MACHINE:X64 + +qmake source\QT_getOpenFileName.pro +nmake diff --git a/programs/compiled/Foo.exe b/programs/compiled/Foo.exe index 6bc31ac..87b4950 100644 Binary files a/programs/compiled/Foo.exe and b/programs/compiled/Foo.exe differ diff --git a/programs/compiled/Twice.exe b/programs/compiled/GetOpenFileNameA.exe similarity index 96% rename from programs/compiled/Twice.exe rename to programs/compiled/GetOpenFileNameA.exe index ab03c2c..8201c8d 100644 Binary files a/programs/compiled/Twice.exe and b/programs/compiled/GetOpenFileNameA.exe differ diff --git a/programs/compiled/JustOpen.exe b/programs/compiled/JustOpen.exe deleted file mode 100644 index 7133fb7..0000000 Binary files a/programs/compiled/JustOpen.exe and /dev/null differ diff --git a/programs/compiled/QT_getOpenFileName.exe b/programs/compiled/QT_getOpenFileName.exe new file mode 100644 index 0000000..c352bcd Binary files /dev/null and b/programs/compiled/QT_getOpenFileName.exe differ diff --git a/programs/source/Twice.c b/programs/source/GetOpenFileNameA.c similarity index 100% rename from programs/source/Twice.c rename to programs/source/GetOpenFileNameA.c diff --git a/programs/source/JustOpen.c b/programs/source/JustOpen.c deleted file mode 100644 index 6c74823..0000000 --- a/programs/source/JustOpen.c +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include - -int main() { - char file[MAX_PATH] = {0}; - - OPENFILENAME ofn = { - .lStructSize = sizeof(ofn), - .lpstrFilter = "All Files\0*.*\0", - .lpstrFile = file, - .nMaxFile = MAX_PATH, - .lpstrTitle = "Select File", - .Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST - }; - - int res = GetOpenFileName(&ofn); - - if (res) printf("%s\n", file); - - return res != 0; -} diff --git a/programs/source/QT_getOpenFileName.cpp b/programs/source/QT_getOpenFileName.cpp new file mode 100644 index 0000000..a150652 --- /dev/null +++ b/programs/source/QT_getOpenFileName.cpp @@ -0,0 +1,32 @@ +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + QApplication app(argc, argv); + + QString fileName = QFileDialog::getOpenFileName(nullptr, "Select File", "", "All Files (*.*)"); + if (fileName.isEmpty()) return 0; + + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + std::cerr << "Failed to open file" << std::endl; + return 1; + } + + QTextStream in(&file); + QString line = in.readLine(); + bool ok; + int number = line.toInt(&ok); + + if (!ok) { + std::cerr << "Failed to read integer from file" << std::endl; + return 1; + } + + std::cout << number * 2 << std::endl; + return 0; +} diff --git a/programs/source/QT_getOpenFileName.pro b/programs/source/QT_getOpenFileName.pro new file mode 100644 index 0000000..59da3d5 --- /dev/null +++ b/programs/source/QT_getOpenFileName.pro @@ -0,0 +1,5 @@ +QT += core widgets +CONFIG += console +SOURCES += QT_getOpenFileName.cpp +TARGET = QT_getOpenFileName +DESTDIR = compiled \ No newline at end of file