Code:
#include <iostream>
#include <windows.h>
#include <Tlhelp32.h>
#include <vector>
using namespace std;
typedef struct ProcessInfo {
int procId;
char * procName;
} ProcessInfo;
ProcessInfo EnumerateProcesses();
int main(int argc, char * argv[]) {
if (argc != 2 && argc != 1) {
printf("Usage: <memHack.exe> <executable.exe>\n");
return 1;
}
LUID privLuid;
HANDLE hTokenHandle = 0;
/* Change the process security token to debug mode */
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hTokenHandle))
printf("[!] Error opening process token: %d\n", GetLastError());
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &privLuid))
printf("[!] Error looking up the privilege value: %d\n", GetLastError());
TOKEN_PRIVILEGES sTokenPrivs;
sTokenPrivs.PrivilegeCount = 1;
sTokenPrivs.Privileges[0].Luid = privLuid;
sTokenPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hTokenHandle, FALSE, &sTokenPrivs, NULL, NULL, NULL))
printf("[!] Error adjusting process token privileges: %d\n", GetLastError());
CloseHandle(hTokenHandle);
bool userInput = false;
ProcessInfo sProcInfo;
memset(&sProcInfo, 0, sizeof(ProcessInfo));
/* Check if file exists */
if (argc == 2) {
OFSTRUCT fileInfo;
HFILE fileHandle = 0;
if ((fileHandle = OpenFile(argv[1], &fileInfo, OF_EXIST)) == HFILE_ERROR) {
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
printf("[!] File \"%s\" does not exist.\n", argv[1]);
CloseHandle((HANDLE)fileHandle);
return 1;
}
}
CloseHandle((HANDLE)fileHandle);
}
/* If not parsed a file to load, enumerate processes for user decision */
else {
userInput = true;
sProcInfo = EnumerateProcesses();
}
HANDLE targetProcess = 0;
/* Opening a running process or loading a process */
if (userInput) {
if ((targetProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, sProcInfo.procId)) == NULL) {
printf("[!] Error acquiring %s process handle with PID %d: %d\n",
sProcInfo.procName,
sProcInfo.procId,
GetLastError());
return 1;
}
}
else {
STARTUPINFO startupInfo;
PROCESS_INFORMATION processInformation;
memset(&startupInfo, 0, sizeof STARTUPINFO);
memset(&processInformation, 0, sizeof PROCESS_INFORMATION);
startupInfo.cb = sizeof STARTUPINFO;
if (!CreateProcess(argv[1], NULL, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation)) {
printf("[!] Error loading program and creating process: %d\n", GetLastError());
return 1;
}
if (processInformation.hProcess)
targetProcess = processInformation.hProcess;
if (processInformation.hThread)
CloseHandle(processInformation.hThread);
}
unsigned char memoryDump[65535];
int byteCount = 0;
SIZE_T readAmount = 0;
// Read memory into buffer in 65k byte chunks
for (SIZE_T y = 0x00400000; y < 0x7FFFFFFF; y += 65535) {
if (ReadProcessMemory(targetProcess, &y, memoryDump, 65535, &readAmount)) {
for (SIZE_T n = 0; n < 65535; n++) {
// 16 bytes have been printed
if (byteCount % 16 == 0)
printf("\n0x%x: ", y+n);
printf("%02x ", memoryDump[n]);
byteCount++;
}
}
else {
printf("\n[!] Error reading process memory: %d, read %d bytes before error.\n", GetLastError(), readAmount);
break;
}
}
if (targetProcess)
CloseHandle(targetProcess);
}
// Returns the name of the user chosen process
ProcessInfo EnumerateProcesses() {
HANDLE hSnapshot = 0;
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) {
printf("[!] Failed to obtain process snapshot handle: %d\n", GetLastError());
CloseHandle(hSnapshot);
exit(0);
}
PROCESSENTRY32 sProc;
sProc.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hSnapshot, &sProc)) {
printf("Failed to enumerate first process from snapshot: %d\n", GetLastError());
CloseHandle(hSnapshot);
exit(0);
}
vector<char *> processes;
vector<int> processIds;
do {
char * tmp = new char[MAX_PATH];
strcpy(tmp, sProc.szExeFile);
processes.push_back(tmp);
processIds.push_back(sProc.th32ProcessID);
} while (Process32Next(hSnapshot, &sProc));
for (int i = 2; i < processes.size(); i++) {
printf("[%d] %s - %d\n", i - 1, processes[i], processIds[i]);
}
int process = 0;
printf("\nProcess #: ");
cin >> process;
process += 1;
ProcessInfo sProcInfo;
sProcInfo.procName = new char[MAX_PATH];
strcpy(sProcInfo.procName, processes[process]);
sProcInfo.procId = processIds[process];
for (int i = 0; i < processes.size(); i++)
delete [] processes[i];
return sProcInfo;
}