透過檢查程式的父程式,可以防止loader方式的破解。一般情況下普通Win32程式的父程式是explorer.exe。如果不是,則很可能是被其它loader載入了。
在NT/2K下,可以利用native API獲得程式的父程式的PID,進而可獲得父程式的程式名。
#include <windows.h>
#include <psapi.h>
#include <iostream.h>
#define NTAPI __stdcall
typedef long NTSTATUS;
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
enum PROCESS_INFO_CLASS { ProcessBasicInformation = 0
};
typedef struct _PROCESS_BASIC_INFORMATION
{
NTSTATUS ExitStatus;
ULONG PebBaseAddress;
ULONG AffinityMask;
ULONG BasePriority;
ULONG UniqueProcessId;
ULONG InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
typedef NTSTATUS (NTAPI *ZW_QUERY_INFORMATION_PROCESS)(IN HANDLE ProcessHandle,
IN PROCESS_INFO_CLASS ProcessInformationClass, OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength, OUT PULONG ReturnLength);
ULONG GetParentPID(HANDLE hProcess)
{
ULONG ParentPID = (ULONG)(-1);
__try
{
HMODULE hModule = GetModuleHandle("ntdll.dll");
if (! hModule)
__leave;
ZW_QUERY_INFORMATION_PROCESS ZwQueryInformationProcess;
ZwQueryInformationProcess = (ZW_QUERY_INFORMATION_PROCESS)GetProcAddress(hModule,
"ZwQueryInformationProcess");
if (!ZwQueryInformationProcess)
__leave;
PROCESS_BASIC_INFORMATION ProcessInfo;
NTSTATUS Status = ZwQueryInformationProcess(hProcess,
ProcessBasicInformation, &ProcessInfo, sizeof(ProcessInfo), NULL);
if (NT_SUCCESS(Status))
{
ParentPID = ProcessInfo.InheritedFromUniqueProcessId;
}
}
__finally
{
//empty
}
return ParentPID;
}
void main(void)
{
LONG ParentPID = GetParentPID(GetCurrentProcess( ));
cout << "Parent PID: " << ParentPID <<
endl;
HANDLE hParentProcess = OpenProcess(PROCESS_ALL_ACCESS,
FALSE, ParentPID);
if (hParentProcess)
{
char FileName[MAX_PATH];
DWORD Len = GetModuleFileNameEx(hParentProcess,
NULL, FileName, MAX_PATH);
if (Len)
{
cout << "Parent
EXE name: " << FileName << endl;
}
CloseHandle(hParentProcess);
}
}
在NT/2K下,普通Win32程式的父程式還可能是cmd.exe;對於Win32服務程式,其父程式則為service.exe。