i want to stop search the net and think hard on this read the code and improve it this can be done better than what is now the offsets its meant to find from the strings are in the .data section but im not sure its finding the right thing #include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <tlhelp32.h>
#include <string>
#include <ctime>
#include <psapi.h>

// Function to log messages to console and file
void log_message(FILE* log_file, bool log_to_file, const char* format, ...) {
    va_list args;
    va_start(args, format);
    vprintf(format, args);
    if (log_to_file && log_file != NULL) {
        vfprintf(log_file, format, args);
        fflush(log_file);
    }
    va_end(args);
}

// Function to get process ID by name
DWORD get_process_id_by_name(const char* process_name, FILE* log_file) {
    PROCESSENTRY32 pe32;
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (hSnapshot == INVALID_HANDLE_VALUE) {
        log_message(log_file, false, "Error: Unable to create tool help snapshot\n");
        return 0;
    }

    pe32.dwSize = sizeof(PROCESSENTRY32);
    if (!Process32First(hSnapshot, &pe32)) {
        CloseHandle(hSnapshot);
        log_message(log_file, false, "Error: Unable to retrieve information on the first process\n");
        return 0;
    }

    do {
        char exeFile[MAX_PATH];
        size_t converted_chars = 0;
        wcstombs_s(&converted_chars, exeFile, MAX_PATH, pe32.szExeFile, _TRUNCATE);

        if (_stricmp(exeFile, process_name) == 0) {
            CloseHandle(hSnapshot);
            log_message(log_file, false, "Process '%s' found with PID %u\n", process_name, pe32.th32ProcessID);
            return pe32.th32ProcessID;
        }
    } while (Process32Next(hSnapshot, &pe32));

    CloseHandle(hSnapshot);
    log_message(log_file, false, "Error: Process '%s' not found\n", process_name);
    return 0;
}

// Function to get the base address of the main module
unsigned long long get_base_address(DWORD pid, FILE* log_file) {
    MODULEENTRY32 me32;
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid);

    if (hSnapshot == INVALID_HANDLE_VALUE) {
        log_message(log_file, false, "Error: Unable to create module snapshot\n");
        return 0;
    }

    me32.dwSize = sizeof(MODULEENTRY32);
    if (!Module32First(hSnapshot, &me32)) {
        CloseHandle(hSnapshot);
        log_message(log_file, false, "Error: Unable to retrieve information on the first module\n");
        return 0;
    }

    unsigned long long base_address = (unsigned long long)me32.modBaseAddr;
    CloseHandle(hSnapshot);
    log_message(log_file, false, "Base address of the main module: 0x%llx\n", base_address);
    return base_address;
}

// Function to get section limits
bool get_section_limits(HANDLE hProcess, unsigned long long base_addr, const char* section_name, unsigned long long& section_start, unsigned long long& section_end) {
    IMAGE_DOS_HEADER dos_header;
    if (!ReadProcessMemory(hProcess, (LPCVOID)base_addr, &dos_header, sizeof(dos_header), NULL)) {
        return false;
    }

    if (dos_header.e_magic != IMAGE_DOS_SIGNATURE) {
        return false;
    }

    IMAGE_NT_HEADERS nt_headers;
    if (!ReadProcessMemory(hProcess, (LPCVOID)(base_addr + dos_header.e_lfanew), &nt_headers, sizeof(nt_headers), NULL)) {
        return false;
    }

    if (nt_headers.Signature != IMAGE_NT_SIGNATURE) {
        return false;
    }

    IMAGE_SECTION_HEADER* section_headers = new IMAGE_SECTION_HEADER[nt_headers.FileHeader.NumberOfSections];
    if (!ReadProcessMemory(hProcess, (LPCVOID)((unsigned long long)(base_addr + dos_header.e_lfanew) + sizeof(nt_headers)), section_headers, sizeof(IMAGE_SECTION_HEADER) * nt_headers.FileHeader.NumberOfSections, NULL)) {
        delete[] section_headers;
        return false;
    }

    for (int i = 0; i < nt_headers.FileHeader.NumberOfSections; ++i) {
        if (strncmp((char*)section_headers[i].Name, section_name, IMAGE_SIZEOF_SHORT_NAME) == 0) {
            section_start = base_addr + section_headers[i].VirtualAddress;
            section_end = section_start + section_headers[i].Misc.VirtualSize;
            delete[] section_headers;
            return true;
        }
    }

    delete[] section_headers;
    return false;
}

// Function to find string in section
unsigned long long find_string_in_section(HANDLE hProcess, unsigned long long section_start, unsigned long long section_end, const char* string_to_search, FILE* log_file) {
    unsigned long long string_addr = 0;
    SIZE_T totalBytesSearched = 0;
    unsigned long long addr = section_start;

    while (addr < section_end) {
        MEMORY_BASIC_INFORMATION mbi;
        if (!VirtualQueryEx(hProcess, (LPCVOID)addr, &mbi, sizeof(mbi))) {
            break;
        }

        if (mbi.State == MEM_COMMIT &&
            (mbi.Protect == PAGE_READWRITE || mbi.Protect == PAGE_EXECUTE_READWRITE ||
                mbi.Protect == PAGE_EXECUTE_WRITECOPY || mbi.Protect == PAGE_WRITECOPY ||
                mbi.Protect == PAGE_READONLY || mbi.Protect == PAGE_EXECUTE_READ)) {

            char* buffer = new char[mbi.RegionSize];
            SIZE_T bytesRead;

            if (ReadProcessMemory(hProcess, (LPCVOID)addr, buffer, mbi.RegionSize, &bytesRead) && bytesRead > 0) {
                totalBytesSearched += bytesRead;

                for (SIZE_T i = 0; i < bytesRead - strlen(string_to_search); i++) {
                    if (_strnicmp(buffer + i, string_to_search, strlen(string_to_search)) == 0) {
                        string_addr = addr + i;
                        delete[] buffer;
                        log_message(log_file, false, "Found string at address 0x%llx after searching %zu bytes\n", string_addr, totalBytesSearched);
                        return string_addr;
                    }
                }
            }

            delete[] buffer;
        }

        addr += mbi.RegionSize;
        log_message(log_file, false, "Searched memory region: 0x%llx - 0x%llx\n", (unsigned long long)mbi.BaseAddress, (unsigned long long)mbi.BaseAddress + mbi.RegionSize);
    }

    log_message(log_file, false, "Could not find string '%s' in section memory. Total bytes searched: %zu\n", string_to_search, totalBytesSearched);
    return 0;
}

// Function to find load address
unsigned long long find_load_address(HANDLE hProcess, unsigned long long string_addr, unsigned long long section_start, unsigned long long section_end, FILE* log_file) {
    SIZE_T totalBytesSearched = 0;
    unsigned long long addr = section_start;

    while (addr < section_end) {
        MEMORY_BASIC_INFORMATION mbi;
        if (!VirtualQueryEx(hProcess, (LPCVOID)addr, &mbi, sizeof(mbi))) {
            break;
        }

        if (mbi.State == MEM_COMMIT &&
            (mbi.Protect == PAGE_READWRITE || mbi.Protect == PAGE_EXECUTE_READWRITE ||
                mbi.Protect == PAGE_EXECUTE_WRITECOPY || mbi.Protect == PAGE_WRITECOPY ||
                mbi.Protect == PAGE_READONLY || mbi.Protect == PAGE_EXECUTE_READ)) {

            unsigned char* buffer = new unsigned char[mbi.RegionSize];
            SIZE_T bytesRead;

            if (ReadProcessMemory(hProcess, (LPCVOID)addr, buffer, mbi.RegionSize, &bytesRead) && bytesRead > 0) {
                totalBytesSearched += bytesRead;

                for (SIZE_T i = 0; i < bytesRead - sizeof(unsigned long long); i++) {
                    unsigned long long* potential_ptr = (unsigned long long*)(buffer + i);
                    if (*potential_ptr == string_addr) {
                        unsigned long long load_addr = addr + i;
                        delete[] buffer;
                        log_message(log_file, false, "Found potential load address at 0x%llx after searching %zu bytes\n", load_addr, totalBytesSearched);
                        return load_addr;
                    }
                }
            }

            delete[] buffer;
        }

        addr += mbi.RegionSize;
        log_message(log_file, false, "Searched memory region: 0x%llx - 0x%llx\n", (unsigned long long)mbi.BaseAddress, (unsigned long long)mbi.BaseAddress + mbi.RegionSize);
    }

    log_message(log_file, false, "Could not find load address for string at 0x%llx. Total bytes searched: %zu\n", string_addr, totalBytesSearched);
    return 0;
}

// Main function
int main() {
    const char* process_name = "Fallout76.exe";
    const char* gameSettings[] = {
        "fVATSMaxChance",
        "fVATSChancePerceptionMultiplier",
        "fVATSMaxEngageDistance",
        "fVATSChanceRaycastVisibilityMininmum",
        "fVATSPingCost",
        "fVATSCriticalChargeBase",
        "fVATSCriticalChargeBonusMult",
        "fVATSCriticalChargeLimit",
        "fVATSCriticalChargeMult",
        "fPlayerAutoReloadDelaySec",
        "bDisablePlayerCollision",
        "fAVDCarryWeightBase",
        "fAbsolutePlayerInventoryWeightLimit",
        "fInvisibilityMaxRefraction",
        "fInvisibilityMinRefraction",
        "fJetpackThrustInitial",
        "fJetpackThrustSustained",
        "fJetpackTimeToSustained",
        "bJetpackInitialThrustOnlyOnTakeoff",
        "fAimStabilityCrouchedScopeMult",
        "fPropModScaleWeapDurability",
        "fLockpickSkillSweetSpotBase",
        "fSweetSpotEasy",
        "fSweetSpotAverage",
        "fSweetSpotHard",
        "fSweetSpotVeryHard",
        "iHackingMinWords",
        "iHackingMaxWords",
        "fCombatMusicNearCombatInnerRadius",
        "fCombatMusicNearCombatOuterRadius",
        "fCombatMusicPlayerTargetedThreatRatio",
        "pkKeywords",
        "fAttackActionPointCost",
        "fspeed",
        "fweight",
        "iDurability",
        "ihealth",
        "bHoldInputToPower",
        "fMinPowerPerShot",
        "poAmmo",
        "paAimModel",
        "ppOverrideProjectile",
        "uNumProjectiles",
        "vaActorValues"
    };

    FILE* log_file;
    if (fopen_s(&log_file, "memscan.log", "w") != 0) {
        printf("Could not open log file for writing\n");
        return 1;
    }

    time_t t = time(NULL);
    struct tm tm;
    localtime_s(&tm, &t);
    log_message(log_file, false, "Memory scan started at: %04d-%02d-%02d %02d:%02d:%02d\n",
        tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);

    DWORD pid = get_process_id_by_name(process_name, log_file);
    if (pid == 0) {
        log_message(log_file, false, "Could not find process '%s'\n", process_name);
        fclose(log_file);
        return 1;
    }

    unsigned long long base_addr = get_base_address(pid, log_file);
    if (base_addr == 0) {
        log_message(log_file, false, "Could not get base address of process '%s'\n", process_name);
        fclose(log_file);
        return 1;
    }

    HANDLE hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, pid);
    if (hProcess == NULL) {
        log_message(log_file, false, "Could not open process %d. Error: %lu\n", pid, GetLastError());
        fclose(log_file);
        return 1;
    }

    unsigned long long data_section_start, data_section_end;
    if (!get_section_limits(hProcess, base_addr, ".data", data_section_start, data_section_end)) {
        log_message(log_file, false, "Could not find .data section in process\n");
        CloseHandle(hProcess);
        fclose(log_file);
        return 1;
    }

    unsigned long long rdata_section_start, rdata_section_end;
    if (!get_section_limits(hProcess, base_addr, ".rdata", rdata_section_start, rdata_section_end)) {
        log_message(log_file, false, "Could not find .rdata section in process\n");
        CloseHandle(hProcess);
        fclose(log_file);
        return 1;
    }

    fprintf(log_file, "$gameSettings = [\n");

    for (const char* string_to_search : gameSettings) {
        unsigned long long string_addr = find_string_in_section(hProcess, data_section_start, data_section_end, string_to_search, log_file);
        if (string_addr == 0) {
            string_addr = find_string_in_section(hProcess, rdata_section_start, rdata_section_end, string_to_search, log_file);
            if (string_addr == 0) {
                log_message(log_file, false, "String '%s' not found\n", string_to_search);
                continue;
            }
        }

        log_message(log_file, false, "Found string '%s' at address 0x%llx\n", string_to_search, string_addr);

        unsigned long long load_addr = find_load_address(hProcess, string_addr, data_section_start, data_section_end, log_file);
        if (load_addr == 0) {
            load_addr = find_load_address(hProcess, string_addr, rdata_section_start, rdata_section_end, log_file);
            if (load_addr == 0) {
                log_message(log_file, false, "Could not find address that loads string '%s'\n", string_to_search);
                continue;
            }
        }

        log_message(log_file, false, "Found address that loads string '%s' at address 0x%llx\n", string_to_search, load_addr);

        unsigned long long func_ptr = load_addr - 0x10;
        log_message(log_file, false, "Function pointer: 0x%llx\n", func_ptr);

        unsigned long long offset = func_ptr - base_addr;
        fprintf(log_file, "    \"%s\" => 0x%llx,\n", string_to_search, offset);
    }

    fprintf(log_file, "];\n");

    CloseHandle(hProcess);

    t = time(NULL);
    localtime_s(&tm, &t);
    log_message(log_file, false, "Memory scan ended at: %04d-%02d-%02d %02d:%02d:%02d\n",
        tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);

    fclose(log_file);

    return 0;
}