README.md
Rendering markdown...
// libarchive-harness-win.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include <windows.h>
// Declare function pointers for the exported functions
typedef void *(*ArchiveReadNew)();
typedef int (*ArchiveReadSupportFormatAll)(void *);
typedef int (*ArchiveReadOpenFilename)(void *, const char *);
typedef int (*ArchiveReadNextHeader)(void *, void **);
typedef int (*ArchiveReadData)(void *, void *, size_t); //(struct archive*,void*, size_t)
typedef int (*ArchiveReadExtract)(void *, void *, int); // archive_read_extract(struct archive* _a, struct archive_entry* entry, int flags)
typedef int (*ArchiveReadClose)(void *);
typedef void (*ArchiveReadFree)(void *);
#define ARCHIVE_OK 0 /* Operation was successful. */
ArchiveReadNew archive_read_new = NULL;
ArchiveReadSupportFormatAll archive_read_support_format_all = NULL;
ArchiveReadOpenFilename archive_read_open_filename = NULL;
ArchiveReadNextHeader archive_read_next_header = NULL;
ArchiveReadData archive_read_data = NULL;
ArchiveReadExtract archive_read_extract = NULL;
ArchiveReadClose archive_read_close = NULL;
ArchiveReadFree archive_read_free = NULL;
extern "C" __declspec(dllexport) int fuzzme(const char *filename);
int fuzzme(const char *filename)
{
int result = 0;
struct archive_entry *ae = {0};
char *buff[100];
// Example usage: Open an archive file
void *archive = archive_read_new();
if (!archive)
{
std::cerr << "Error creating archive object" << std::endl;
return 1;
}
archive_read_support_format_all(archive);
if (archive_read_open_filename(archive, filename) != ARCHIVE_OK)
{
std::cerr << "Error opening archive file" << std::endl;
archive_read_free(archive);
return 1;
}
// Process headers and data (add your logic here)
if (archive_read_next_header(archive, (void **)&ae) != ARCHIVE_OK)
{
std::cerr << "Error read_next_header" << std::endl;
archive_read_free(archive);
return 1;
}
if (archive_read_extract(archive, ae, 0x0002) != ARCHIVE_OK)
{
std::cerr << "Error read_extract" << std::endl;
archive_read_free(archive);
return 1;
}
if (result = archive_read_data(archive, buff, 99) != ARCHIVE_OK)
{
std::cerr << "Error read_data" << std::endl;
archive_read_free(archive);
return 1;
}
// Clean up
archive_read_close(archive);
archive_read_free(archive);
return result;
}
int main(int argc, char **argv)
{
// inspired by https://symeonp.github.io/2017/09/17/fuzzing-winafl.html
if (argc < 2)
{
printf("Usage: %s <rar file>\n", argv[0]);
return 0;
}
// Load the DLL you want to fuzz/test
HMODULE archiveDll = LoadLibrary(L"C:\\Users\\User\\Desktop\\archiveint.dll.x64.10.0.19041.3636");
if (!archiveDll)
{
std::cerr << "Error loading archiveint.dll" << std::endl;
return 1;
}
// Get function addresses
archive_read_new = reinterpret_cast<ArchiveReadNew>(GetProcAddress(archiveDll, "archive_read_new"));
archive_read_support_format_all = reinterpret_cast<ArchiveReadSupportFormatAll>(GetProcAddress(archiveDll, "archive_read_support_format_all"));
archive_read_open_filename = reinterpret_cast<ArchiveReadOpenFilename>(GetProcAddress(archiveDll, "archive_read_open_filename"));
archive_read_next_header = reinterpret_cast<ArchiveReadNextHeader>(GetProcAddress(archiveDll, "archive_read_next_header"));
archive_read_data = reinterpret_cast<ArchiveReadData>(GetProcAddress(archiveDll, "archive_read_data"));
archive_read_close = reinterpret_cast<ArchiveReadClose>(GetProcAddress(archiveDll, "archive_read_close"));
archive_read_free = reinterpret_cast<ArchiveReadFree>(GetProcAddress(archiveDll, "archive_read_free"));
archive_read_extract = reinterpret_cast<ArchiveReadExtract>(GetProcAddress(archiveDll, "archive_read_extract"));
if (!archive_read_new || !archive_read_support_format_all || !archive_read_open_filename ||
!archive_read_next_header || !archive_read_data || !archive_read_close || !archive_read_free || !archive_read_extract)
{
std::cerr << "Error getting function addresses" << std::endl;
FreeLibrary(archiveDll);
return 1;
}
int result = fuzzme(argv[1]);
std::cout << "fuzzme result: " << result << "filename: " << argv[1];
FreeLibrary(archiveDll);
return 0;
}
// https://github.com/libarchive/libarchive/blob/master/libarchive/test/test_read_format_rar_invalid1.c
// #include "test.h"
//
// DEFINE_TEST(test_read_format_rar_invalid1)
//{
// const char* refname = "test_read_format_rar_invalid1.rar";
// struct archive* a;
// struct archive_entry* ae;
// char* buff[100];
//
// extract_reference_file(refname);
// assert((a = archive_read_new()) != NULL);
// assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
// assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
// assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240));
// assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
// assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buff, 99));
// assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
// assertEqualInt(ARCHIVE_OK, archive_read_free(a));
//}
///* Extract the entries to disk. */
// assert((a = archive_read_new()) != NULL);
// assertA(0 == archive_read_support_format_all(a));
// assertA(0 == archive_read_support_filter_all(a));
// assertA(0 == archive_read_open_memory(a, buff, BUFF_SIZE));
///* Restore first entry with _EXTRACT_PERM. */
// failure("Error reading first entry");
// assertA(0 == archive_read_next_header(a, &ae));
// assertA(0 == archive_read_extract(a, ae, ARCHIVE_EXTRACT_PERM));
///* Rest of entries get restored with no flags. */
// for (i = 1; i < numEntries; i++) {
// failure("Error reading entry %d", i);
// assertA(0 == archive_read_next_header(a, &ae));
// failure("Failed to extract entry %d: %s", i,
// archive_entry_pathname(ae));
// assertA(0 == archive_read_extract(a, ae, 0));
// }
// assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
// assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
// assertEqualInt(ARCHIVE_OK, archive_read_free(a));