4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / libarchive-harness-win.cpp CPP
// 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));