// 簡單的程序僞裝就是修改程序名稱,比如svchost.exe、services.exe等系統程序。
// 進階的程序僞裝就是修改程序的PEB資料,也就是在任務管理器中看到的程序的名稱、啟動路徑等資訊。
// NtQueryInformationProcess函數
// 作用:擷取指定程序的資訊。
// 原型:NSTATUS WINAPI NtQueryInformationProcess(
// _In_ HANLDE hProcess;
// _In_ PROCESSINFOCLASS ProcessInformationClass,
// _Out_ PVOID ProcesInformation,
// _In_ ULONG ProcessInformationLength,
// _Out_opt_ PULONG ReturnLength
// )
// 參數:hProcess:程序句柄,由OpenProcess函數擷取。
// ProcessInformationClass:程序資訊的類型,為以下枚舉值之一:
// ProcessBasicInformation:檢索指向PEB結構的指針。
// ProcessDebugPort:擷取作為程序調試器端口号的DWORD_PTR值。
// ProcessWow64Information:确定程序是否在Wow64環境中運作。
// ProcessImageFileName:檢索包含該程序映像檔案名稱的UNICODE_STRING值。
// ProcessBreakOnTermination:檢索訓示程序是否被視為關鍵的ULONG值。
// ProcessSubsystemInformation:檢索訓示程序子系統類别的SUBSYSTEM_INFORMATION_TYPE值。
// ProcessInformation:接收值,
// ProcessInformationLength:指定接收資料緩沖區的大小。
// ReturnLength:接收傳回所請求資訊的大小。
// 結果:傳回一個NTSTATUS成功或錯誤代碼。
// PROCESS_BASIC_INFORMATION結構體
// 定義: typedef struct _PROCESS_BASIC_INFORMATION {
// PVOID Reserved1;
// PPEB PebBaseAddress,
// PVOID Reserved2[2];
// ULONG_PTR UniqueProcessId;
// PVOID Reserved3;
// } PROCESS_BASIC_INFORMATION;
// 參數:PebBaseAddress成員指向PEB結構。
// 實作原理:就是修改指定程序環境塊(PEB)中的程序路徑以及指令行資訊,進而達到程序僞裝的效果。
// PS:NtQueryInformationProcess這個函數不是公開的,需要從ntdll.dll中擷取函數位址。
// 示例代碼:
BOOL DisguiseProcess(DWORD dwProcessId, wchar_t* lpwszPath, wchar_t* lpwszCmd)
{
// 打開程序,擷取程序句柄
HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if (NLL == hProcess)
{
ShowError("OpenProcess");
return FALSE;
}
typedef_NtQueryInformationProcess NtQueryInformationProcess = NULL;
PROCESS_BASIC_INFORMATION pbi = {0};
PEB peb = {0};
RTL_USER_PROCESS_PARAMETERS Param = {0};
USHORT usCmdLen = 0;
USHORT usPathLen = 0;
// 需要通過LoadLibrary、GetProcessAddress從ntdll.dll中擷取位址
NtQueryInformationProcess = ::GetProcAddress(::LoadLibrary("ntdll.dll"), "NtQueryInformationProcess");
if (NULL == NtQueryInformationProcess)
{
ShowError("GetProcAddress");
return FALSE;
}
// 擷取指定程序的基本資訊
NTSATUS status = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
if (!NT_SUCCESS(status))
{
ShowError("NtQueryInformationProcess");
return FALSE;
}
// 擷取指定程序基本資訊結構中的PebBaseAddress
::ReadProcessMemory(hProcess, pbi.PebBaseAddress, &peb, sizeof(peb), NULL);
// 擷取指定程序環境塊結構中的ProcessParameters
::ReadProcessMemory(hProcess, peb.ProcessParameters, &Param, sizeof(Param), NULL);
// 修改指定PEB中指令行資訊
usCmdLen = 2 + 2 * ::wcslen(lpwszCmd);
::WriteProcessMemory(hProcess, Param.CommandLine.Buffer, lpwszCmd, usCmdLen, NULL);
::WriteProcessMemory(hProcess, Param.CommandLine.Length, &usCmdLen, sizeof(usCmdLen), NULL);
// 修改指定PEB中的路徑資訊
usPathLen = 2 + 2 * wcslen(lpwszPath);
::WriteProcessMemory(hProcess, Param.ImagePathName.Buffer, lpwszPath, usPathLen, NULL);
::WriteProcessMemory(hProcess, Param.ImagePathName.Length, &usPathLen, sizeof(usPathLen), NULL);
return TRUE;
}