refactoring; GetOpenFileNameA; QFileDialog::getOpenFileName

This commit is contained in:
Ludwig Lehnert 2025-05-08 14:26:12 +02:00
parent 2c08f1ba04
commit 56cb018a0f
Signed by: ludwig
SSH Key Fingerprint: SHA256:4vshH9GJ8TLO1RS2fY6rDDLnq7+KVvSClCY+uEhYYRA
14 changed files with 114 additions and 48 deletions

6
.gitignore vendored
View File

@ -7,9 +7,15 @@
*.ilk *.ilk
*.log *.log
*.Debug
*.Release
*.stash
build/ build/
plugins_install/ plugins_install/
.sconsign.dblite .sconsign.dblite
peasoup_executable*/ peasoup_executable*/
/programs/Makefile*

View File

@ -1,24 +1,36 @@
# windows-binary-fuzzing # windows-binary-fuzzing
## API methods ## DLL methods
- [ ] `GetOpenFileNameA` - [x] `GetOpenFileNameA`
- [ ] `IFileOpenDialog` - [x] `QFileDialog::getOpenFileName`
- [ ] `QFileDialog::getOpenFileName` - [ ] `QFileDialog::getOpenFileNames`
- [ ] `QFileDialog::getOpenFileUrl`
- [ ] `QFileDialog::getOpenFileUrls`
- [ ] `QFileDialog::getOpenFileContent`
- [ ] `wxFileDialog` - [ ] `wxFileDialog`
- [ ] `IFileOpenDialog`
## Build commands (client) ## Build scripts
```bash ```bash
mkdir build # Client(s)
cmake -DDynamoRIO_DIR=C:\Users\vboxuser\DynamoRIO-Windows\cmake .. clients/build_all.ps1
cmake --build .
# Programs
programs/build.bat
``` ```
## Execution commands (drrun) ## Execution commands (drrun)
e.g. ### `GetOpenFileNameA.exe`
```bash ```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
``` ```

View File

@ -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)

View File

@ -13,16 +13,16 @@ char *CUSTOM_FILE = "C:\\Users\\vboxuser\\Downloads\\spoofed_number.txt";
static app_pc pc_GetOpenFileNameA = NULL; static app_pc pc_GetOpenFileNameA = NULL;
static void intercept_GetOpenFileNameA() { static app_pc pc_QString_QString = NULL;
// dr_printf("intercept_GetOpenFileNameA(...)\n"); static app_pc pc_QFileDialog_getOpenFileName = NULL;
static void intercept_GetOpenFileNameA() {
void *drcontext = dr_get_current_drcontext(); void *drcontext = dr_get_current_drcontext();
dr_mcontext_t mcontext = { sizeof(mcontext), DR_MC_ALL }; dr_mcontext_t mcontext = { sizeof(mcontext), DR_MC_ALL };
dr_get_mcontext(drcontext, &mcontext); dr_get_mcontext(drcontext, &mcontext);
OPENFILENAME *ofn = (OPENFILENAME *)mcontext.rcx; 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]; for (int i = 0; i < strlen(CUSTOM_FILE); i++) ofn->lpstrFile[i] = CUSTOM_FILE[i];
ofn->lpstrFile[strlen(CUSTOM_FILE)] = 0; ofn->lpstrFile[strlen(CUSTOM_FILE)] = 0;
@ -32,8 +32,19 @@ static void intercept_GetOpenFileNameA() {
dr_set_mcontext(drcontext, &mcontext); 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) { 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) { 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]); 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")) { if (strstr(lowerpath, "comdlg32.dll")) {
pc_GetOpenFileNameA = (app_pc)dr_get_proc_address(mod->handle, "GetOpenFileNameA"); pc_GetOpenFileNameA = (app_pc)dr_get_proc_address(mod->handle, "GetOpenFileNameA");
// if (pc_GetOpenFileNameA) dr_printf("Found GetOpenFileNameA at %p\n", pc_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) { if (target == pc_GetOpenFileNameA) {
// dr_printf("Call to GetOpenFileNameA detected at %p\n", instr_get_app_pc(instr)); // 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); dr_insert_clean_call(drcontext, bb, instr, (void *)intercept_GetOpenFileNameA, false, 0);
instrlist_remove(bb, instr); instrlist_remove(bb, instr);
instr_destroy(drcontext, 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; 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_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_set_client_name("Custom DynamoRIO client", "https://gitea.cloud.lehnert.dev/ludwig/windows-binary-fuzzing");
dr_register_exit_event(event_exit); dr_register_exit_event(event_exit);
dr_register_module_load_event(event_module_load); dr_register_module_load_event(event_module_load);
dr_register_bb_event(event_basic_block); dr_register_bb_event(event_basic_block);
// dr_printf("Custom DynamoRIO client loaded.\n");
} }

View File

@ -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)

6
programs/build.bat Normal file
View File

@ -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

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,22 +0,0 @@
#include <windows.h>
#include <commdlg.h>
#include <stdio.h>
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;
}

View File

@ -0,0 +1,32 @@
#include <QApplication>
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
#include <QDebug>
#include <iostream>
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;
}

View File

@ -0,0 +1,5 @@
QT += core widgets
CONFIG += console
SOURCES += QT_getOpenFileName.cpp
TARGET = QT_getOpenFileName
DESTDIR = compiled