所以基本上我尝试使用 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 并重新打开进程 - 返回相同的错误 **
#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 的输出:
ConsoleApplication1.exe 的输出
软件详情: