"Invalid access to memory location" with WriteProcessMemory

698 views Asked by At

I code a script whose task is to "reset" a certain part of the process memory. I've got my Baseadress from process hacker 2 (https://cdn.discordapp.com/attachments/854061591312728085/1040805686822572093/image.png) But with the code I have, I always get a 998 Error (Invalid access to memory location.) It's kinda wierd becouse this script worked, and then after doing something else for 4-5 hours and trying it again, it didn't work any more lol.

string s = "CabinetWClass";
    wstring stemp = wstring(s.begin(), s.end());
    LPCWSTR className = stemp.c_str();
    HWND hWnd = FindWindow(className, 0);
    if (hWnd == 0) {
        std::cout << "Cannot find window." << std::endl;
    }
    DWORD pId;
    GetWindowThreadProcessId(hWnd, &pId);
    HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pId);
    DWORD baseAddress = 0xd865fee;
    //DWORD offset = 0xA7;  
    DWORD ptrAddress;
    string tmp = "."; 
    int len = 10;
    for (int i = 0; i < len; i++) {
        tmp = tmp.append(".");
    }
    const char* newString = tmp.c_str();
    cout << newString << endl;
    ReadProcessMemory(hProc, (void*)baseAddress, &ptrAddress, sizeof(DWORD), 0);
    cout << sizeof(ptrAddress) << endl;
    BOOL lol = WriteProcessMemory(hProc, (void*)ptrAddress, newString, strlen(newString), 0);
    if (!lol) {


        std::cerr << "Couldn't write process memory:" << GetLastError() << std::endl;
        DWORD errorMessageID = ::GetLastError();


        LPSTR messageBuffer = nullptr;
        size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL, errorMessageID, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);

        //Copy the error message into a std::string.
        std::string message(messageBuffer, size);

        //Free the Win32's string's buffer.
        LocalFree(messageBuffer);

        std::cerr << message << endl;

    }
    std::cout << "Done. " << &ptrAddress << std::endl;

This is my code, atm. I've tested everything with and without admin perms, both ways did not work.

1

There are 1 answers

0
thedemons On

The address 0xd865fee won't stay the same (usually), it will be changed every time you reopen the process.

Regardless of the wrong address, you might be writing into a read-only region, see Memory Protection. You'll need to change its protection to a writable one before writing:

size_t size = strlen(newString);

// change the protection to a writable one
DWORD dwOldProtect;
if (!VirtualProtectEx(hProc, ptrAddress, size, PAGE_EXECUTE_READWRITE, &dwOldProtect)) throw;

WriteProcessMemory(hProc, (void*)ptrAddress, newString, size, 0);

// backup the old protection
if (!VirtualProtectEx(hProc, ptrAddress, size, dwOldProtect, &dwOldProtect)) throw;

Be aware that VirtualProtectEx can fail for a variety of reasons.