i want you to use all the code in this to make a single app that postively idenify a text intrgity check in .text section and gets its offset #include <windows.h>
#include <dbghelp.h>
#include <fstream>
#include <sstream>
#include <iostream>
#include <shlobj.h>
#include <psapi.h>
#include <unordered_map>
#include <vector>

#pragma comment(lib, "Dbghelp.lib")
#pragma comment(lib, "Shell32.lib")
#pragma comment(lib, "User32.lib")
#pragma comment(lib, "Psapi.lib")

std::ofstream xrefLogFile;

#define XREF_LOG_FILE_NAME "xref_log.txt"
#define SUBROUTINE_DUMP_PREFIX "subroutine_"
#define MAX_LOG_FILE_SIZE 895620

static HRESULT(__stdcall* pCreateDXGIFactory)(REFIID riid, void** ppFactory) = nullptr;
static HRESULT(__stdcall* pCreateDXGIFactory1)(REFIID riid, void** ppFactory) = nullptr;
static HRESULT(__stdcall* pCreateDXGIFactory2)(UINT flags, REFIID riid, void** ppFactory) = nullptr;

std::string getDocumentsPath() {
    char path[MAX_PATH];
    SHGetFolderPathA(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, path);
    return std::string(path);
}

void openLogFile() {
    std::string documentsPath = getDocumentsPath();
    xrefLogFile.open(documentsPath + "\\" + XREF_LOG_FILE_NAME, std::ios::app);
}

void logMessage(const std::string& message) {
    std::cout << message << std::endl;
    xrefLogFile << message << std::endl;
    xrefLogFile.flush();

    if (xrefLogFile.tellp() >= MAX_LOG_FILE_SIZE) {
        xrefLogFile.close();
        xrefLogFile.open(xrefLogFile.getloc().name().c_str(), std::ios::app);
    }
}

void captureStackTrace(EXCEPTION_POINTERS* exceptionInfo) {
    void* stack[64];
    HANDLE process = GetCurrentProcess();
    SymInitialize(process, NULL, TRUE);
    WORD numberOfFrames = CaptureStackBackTrace(0, 64, stack, NULL);
    SYMBOL_INFO* symbol = (SYMBOL_INFO*)calloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1);
    symbol->MaxNameLen = 255;
    symbol->SizeOfStruct = sizeof(SYMBOL_INFO);

    for (WORD i = 0; i < numberOfFrames; i++) {
        SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol);
        std::ostringstream oss;
        oss << "[" << i << "] " << symbol->Name << " - 0x" << std::hex << symbol->Address;
        logMessage(oss.str());
    }

    free(symbol);
}

LONG WINAPI exceptionHandler(EXCEPTION_POINTERS* exceptionInfo) {
    logMessage("Exception caught!");
    captureStackTrace(exceptionInfo);
    return EXCEPTION_EXECUTE_HANDLER;
}

bool Disassemble(PBYTE code, char* instructionString, size_t instructionStringSize, DWORD64 address) {
    sprintf_s(instructionString, instructionStringSize, "0x%llx: %02x %02x %02x %02x", address, code[0], code[1], code[2], code[3]);
    return true;
}

DWORD GetInstructionLength(PBYTE code) {
    return 4;
}

void dumpSubroutine(void* address) {
    HANDLE process = GetCurrentProcess();
    SymInitialize(process, NULL, TRUE);

    DWORD64 displacement = 0;
    SYMBOL_INFO* symbol = (SYMBOL_INFO*)calloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1);
    if (!symbol) {
        logMessage("Failed to allocate memory for symbol.");
        return;
    }
    symbol->MaxNameLen = 255;
    symbol->SizeOfStruct = sizeof(SYMBOL_INFO);

    if (!SymFromAddr(process, (DWORD64)address, &displacement, symbol)) {
        logMessage("SymFromAddr failed.");
        free(symbol);
        return;
    }

    std::ostringstream oss;
    oss << getDocumentsPath() << "\\" << SUBROUTINE_DUMP_PREFIX << symbol->Name << ".txt";
    std::ofstream dumpFile(oss.str(), std::ios::app);
    if (!dumpFile.is_open()) {
        logMessage("Failed to open dump file.");
        free(symbol);
        return;
    }

    dumpFile << "Function: " << symbol->Name << " at address 0x" << std::hex << symbol->Address << std::endl;
    dumpFile << std::endl;

    const size_t bufferSize = 4096;
    BYTE buffer[bufferSize];
    DWORD64 offset = 0;
    SIZE_T bytesRead;
    bool endOfSubroutine = false;

    while (!endOfSubroutine) {
        if (ReadProcessMemory(process, (PBYTE)address + offset, buffer, bufferSize, &bytesRead)) {
            size_t localOffset = 0;
            while (localOffset < bytesRead) {
                char instructionString[256];
                if (Disassemble(buffer + localOffset, instructionString, sizeof(instructionString), (DWORD64)address + offset + localOffset)) {
                    dumpFile << instructionString << std::endl;
                    DWORD instrLength = GetInstructionLength(buffer + localOffset);
                    if (instrLength == 0) break;
                    localOffset += instrLength;

                    if (buffer[localOffset - 1] == 0xC3 || buffer[localOffset - 1] == 0xCB || buffer[localOffset - 1] == 0xC2 || buffer[localOffset - 1] == 0xCA) {
                        endOfSubroutine = true;
                        break;
                    }
                }
                else {
                    endOfSubroutine = true;
                    break;
                }
            }
            offset += localOffset;
        }
        else {
            logMessage("ReadProcessMemory failed.");
            break;
        }
    }

    dumpFile.close();
    free(symbol);
}

void* GetReturnAddress() {
    CONTEXT context = {};
    RtlCaptureContext(&context);
#if defined(_M_IX86)
    return (void*)context.Eip;
#elif defined(_M_X64)
    return (void*)context.Rip;
#else
    return nullptr;
#endif
}

std::unordered_map<void*, bool> tracedFunctions;

extern "C" {
    __declspec(dllexport) HRESULT __stdcall CreateDXGIFactory(REFIID riid, void** ppFactory) {
        HRESULT result = pCreateDXGIFactory(riid, ppFactory);
        void* address = GetReturnAddress();
        if (tracedFunctions.find(address) == tracedFunctions.end()) {
            logMessage("CreateDXGIFactory called");
            dumpSubroutine(address);
            tracedFunctions[address] = true;
        }
        return result;
    }

    __declspec(dllexport) HRESULT __stdcall CreateDXGIFactory1(REFIID riid, void** ppFactory) {
        HRESULT result = pCreateDXGIFactory1(riid, ppFactory);
        void* address = GetReturnAddress();
        if (tracedFunctions.find(address) == tracedFunctions.end()) {
            logMessage("CreateDXGIFactory1 called");
            dumpSubroutine(address);
            tracedFunctions[address] = true;
        }
        return result;
    }

    __declspec(dllexport) HRESULT __stdcall CreateDXGIFactory2(UINT flags, REFIID riid, void** ppFactory) {
        HRESULT result = pCreateDXGIFactory2(flags, riid, ppFactory);
        void* address = GetReturnAddress();
        if (tracedFunctions.find(address) == tracedFunctions.end()) {
            logMessage("CreateDXGIFactory2 called");
            dumpSubroutine(address);
            tracedFunctions[address] = true;
        }
        return result;
    }
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
    UNREFERENCED_PARAMETER(hinstDLL);
    UNREFERENCED_PARAMETER(lpvReserved);

    switch (fdwReason) {
    case DLL_PROCESS_ATTACH: {
        char dllPath[MAX_PATH];
        ZeroMemory(dllPath, sizeof(dllPath));
        GetSystemDirectoryA(dllPath, sizeof(dllPath));
        strcat_s(dllPath, "\\dxgi.dll");

        HMODULE dxgi = LoadLibraryA(dllPath);
        if (!dxgi) {
            MessageBoxA(NULL, "Error loading original dxgi.dll", "Error", MB_ICONERROR | MB_OK);
            return FALSE;
        }

        *(void**)&pCreateDXGIFactory = GetProcAddress(dxgi, "CreateDXGIFactory");
        *(void**)&pCreateDXGIFactory1 = GetProcAddress(dxgi, "CreateDXGIFactory1");
        *(void**)&pCreateDXGIFactory2 = GetProcAddress(dxgi, "CreateDXGIFactory2");

        openLogFile();
        AddVectoredExceptionHandler(1, exceptionHandler);
    }
                           break;
    case DLL_PROCESS_DETACH:
        xrefLogFile.close();
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}