无法写入进程内存(WriteProcessMemory)

问题描述 投票:0回答:0

总结:

所以基本上我尝试使用 ReadProcessMemory 读取/写入目标进程 ConsoleApplication1.exe 和 winapi 中的 WriteProcessMemory 函数。我能够从目标进程内存中读取,但我无法写入内存。

详情:

GetBaseAddress(用于读取/写入内存的进程):

代码:

// GetBaseAddress.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <sstream>
#include <iostream>
#include <windows.h>
#include <psapi.h>
#include <processthreadsapi.h>
#include <tlhelp32.h>
#include <string.h>
using namespace std;

DWORD FindID(char *name );
void errExit(const char msg[50], HANDLE handle = 0);
int main()
{
    std::cout << "Hello World!\n";
    /*Find Process ID by Name*/
    char name[] = "ConsoleApplication1.exe";
    DWORD processID = FindID(name);
    HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, false, processID);
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processID);
    if (snapshot == INVALID_HANDLE_VALUE || processHandle == NULL||processHandle == INVALID_HANDLE_VALUE) {
        errExit("Counldn't create snapshot exiting...", snapshot);
    }
    cout << "[+]Snapshot created for PID:" << processID << endl;
    cout << "[+]Retriving Module Info..." << endl;
    MODULEENTRY32 moduleEntry  ;
    moduleEntry.dwSize = sizeof(MODULEENTRY32);
    if (Module32First(snapshot, &moduleEntry) == FALSE) {
        errExit("Counldn't retrive entry exiting...",processHandle);
    }
    //stringstream address;
    //
    char buff[12] = "Hello World";
    DWORD offset = 0x19B44; //HelloWorld - [H]
    //
    //BYTE word = *moduleEntry.modBaseAddr;
    DWORD_PTR dwModuleBaseAddress = (DWORD_PTR)moduleEntry.modBaseAddr+offset;
    std::stringstream stream;
    stream << std::hex << dwModuleBaseAddress;
    std::string hexAddress = stream.str();
   
    cout << "[+]Base Address of the module is:" << hexAddress << endl;
    cout << "[+]Reading Memory..." << endl;
    BOOL rslt = ReadProcessMemory(processHandle, moduleEntry.modBaseAddr + offset, buff, sizeof(buff) - 1, NULL);
    if (rslt == FALSE) {
        errExit("Couldn't read memory region exiting...");
    }
    //char buff2[] = "Hacked     ";
    cout << "[+]Memory Data:" << buff << endl;
    cout << endl;
  
     rslt= WriteProcessMemory(processHandle, moduleEntry.modBaseAddr + offset,buff,sizeof(buff)-1,NULL);
    if (rslt == FALSE) {
        errExit("Couldn't write to the Memory Address");
    }
    
}

DWORD FindID(char *name) {
    cout << name << endl;
    DWORD procIDs[1024],needed=0;
    
    std::wstring str = L"ConsoleApplication1.exe";
    int rslt = EnumProcesses(procIDs, sizeof(procIDs), &needed);
    if (rslt==0) {
        errExit("Procees IDs list couldn't be retrived exiting...");
    }
    cout << "[+]Process IDs List Retrived..." << endl;
    cout << "[+]Bytes Returned:" << needed << endl;
    cout << "[+]sizeof(DWORD):" << sizeof(DWORD) << endl;
    cout << "[+]Number of Process Retrived:" << needed / sizeof(DWORD) << endl;
    
    for (int i = 0;i <= needed / sizeof(DWORD); i++) {
        HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, false, procIDs[i]);
        if (processHandle == NULL) {
            //CloseHandle(processHandle);
            continue;
        }
        wchar_t processFileName[MAX_PATH];
        GetModuleBaseNameW(processHandle, NULL, processFileName, sizeof(processFileName));
        
        
        if (std::wstring(processFileName) == str) {
            cout << "[+]Found:" << procIDs[i] << endl;
            cout << "[+]Process " <<":" << i << endl;
            wcout << "[+]Process Name" << ":" << processFileName << endl;
            return procIDs[i];
        }
        CloseHandle(processHandle);
    }


}

void errExit(const char msg[50], HANDLE handle) {
    cout << "[-]"<<msg << endl;
    cout << "[-]Retriving Last Error:" << GetLastError() << endl;
    CloseHandle(handle);
    system("pause");
    exit(1);
}

这里在使用modEntry.modBaseAddr + offset 读写目标进程的内存位置。 modEntry.modBaseAddr 保存进程第一个模块的基地址,modEntry.modBaseAddr + offset 是目标进程中字符串“Hello World”的第一个字符的位置。

我在使用 WriteProcessMemory 时遇到的错误: 998 - 错误_NOACCESS 对内存位置的访问无效。

我已经尝试过的事情:

1.使用 VirtualProtect 函数更改保护区域它返回 FALSE 与旧保护是 -PAGE_NOACCESS 0x01

根据微软的说法:- PAGE_NOACCESS 0x01

禁用对页面提交区域的所有访问。尝试读取、写入或执行已提交的区域会导致访问冲突。 CreateFileMapping 函数不支持此标志。

2.Trying Multiple times - 返回相同的错误

3.使用硬编码地址 - 返回相同的错误 我尝试直接将地址设置为 (LPVOID)0x619b44 这里,modEntry.modBaseAddr + offset = 0x619b44

**4.尝试使用 PROCESS_VM_WRITE 约束使用 OpenProcess CloseHandle 并重新打开进程 - 返回相同的错误 **

这里是 ConsoleApplication.exe 的代码(我试图覆盖数据的目标进程):

#include<Windows.h>
//#include<unistd.h>
#include <iostream>
using namespace std;
int main()
{
    HANDLE d = GetModuleHandle(NULL);
    cout << "Module Handle:"<<d<<endl;
    int gold = 0;
    int* ptr = &gold;
    char buff[] = "Hello World\n";
    std::cout << buff;
    system("title hackme");
    std::cout << "Enter something:";
    std::cin >> gold;
    for (;;) {
        std::cout << buff;
        //gold++;
        std::cout << "Address:";
        std::cout << &gold<< std::endl;
        std::cout << gold << std::endl;
        Sleep(1000);
        
    }
    cout << "Congrats Pro!!!" << endl;

    
}

GetBaseAddress 的输出:

GetBaseAddress

ConsoleApplication1.exe 的输出

ConsoleApplication1

软件详情:

  1. Microsoft Visual Studio Community 2019
  2. 版本 16.11.23
  3. 优化:禁用
  4. 操作系统:Window 10
c++ windows winapi readprocessmemory process-injection
© www.soinside.com 2019 - 2024. All rights reserved.