使用这个api可以在指定的进程中将数据写入内存区域。
注意:以管理员权限运行,并且以x64调试。
#include <windows.h> #include <iostream> #include <tlhelp32.h> #include <psapi.h> DWORD_PTR GetProcessBaseAddress(DWORD processID) { DWORD_PTR baseAddress = 0; HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID); HMODULE* moduleArray; LPBYTE moduleArrayBytes; DWORD bytesRequired; if (processHandle) { if (EnumProcessModules(processHandle, NULL, 0, &bytesRequired)) { if (bytesRequired) { moduleArrayBytes = (LPBYTE)LocalAlloc(LPTR, bytesRequired); if (moduleArrayBytes) { unsigned int moduleCount; moduleCount = bytesRequired / sizeof(HMODULE); moduleArray = (HMODULE*)moduleArrayBytes; if (EnumProcessModules(processHandle, moduleArray, bytesRequired, &bytesRequired)) { baseAddress = (DWORD_PTR)moduleArray[0]; } LocalFree(moduleArrayBytes); } } } CloseHandle(processHandle); } return baseAddress; } BOOL SetPrivilege( HANDLE hToken, // access token handle LPCTSTR lpszPrivilege, // name of privilege to enable/disable BOOL bEnablePrivilege // to enable or disable privilege ) { TOKEN_PRIVILEGES tp; LUID luid; if (!LookupPrivilegeValue( NULL, // lookup privilege on local system lpszPrivilege, // privilege to lookup &luid)) // receives LUID of privilege { printf("LookupPrivilegeValue error: %u ", GetLastError()); return FALSE; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; if (bEnablePrivilege) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0; // Enable the privilege or disable all privileges. if (!AdjustTokenPrivileges( hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) { printf("AdjustTokenPrivileges error: %u ", GetLastError()); return FALSE; } if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) { printf("The token does not have the specified privilege. "); return FALSE; } return TRUE; } void write() { std::string writing = "lmaoxd"; auto writing_size = writing.size(); DWORD pID = 1092; HANDLE hToken; OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken); SetPrivilege(hToken, SE_DEBUG_NAME, TRUE); CloseHandle(hToken); HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID); DWORD h = GetProcessBaseAddress(pID); SetLastError(0); DWORD oldProtect; BOOL ret = VirtualProtectEx(pHandle, (LPVOID)h, writing_size, PAGE_READWRITE, &oldProtect); // VOID* pp = VirtualAllocEx(pHandle, (LPVOID)h, writing_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); DWORD error = GetLastError(); SetLastError(0); ret = WriteProcessMemory(pHandle, (LPVOID)h, writing.c_str(), writing_size, 0); error = GetLastError(); std::cout << "Error: " << error << std::endl; CloseHandle(pHandle); } int main() { write(); system("pause"); }
VirtualProtectEx和VirtualAllocEx的效果类似。
使用VirtualAllocEx的代码示例:
VOID* pp = VirtualAllocEx(pHandle, (LPVOID)h, writing_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); DWORD error = GetLastError(); SetLastError(0); ret = WriteProcessMemory(pHandle, (LPVOID)pp, &writing, writing_size, 0);