通过Nt函数NtQuerySystemInformation来获取所有的进程信息,然后进行名称匹配,若匹配成功,返回ProcessID。
#ifdef UNICODE
#define GetProcessID_Nt GetProcessID_NtW
#else
#define GetProcessID_Nt GetProcessID_NtA
#endif
BOOL IsBadWritePtr(LPVOID lp, UINT_PTR cb);
BOOL IsBadReadPtr(CONST VOID *lp, UINT_PTR cb);
VOID RtlInitUnicodeString(OUT PUNICODE_STRING DestinationString,IN PCWSTR SourceString OPTIONAL );
ULONG BaseSetLastNTError(IN NTSTATUS Status);
LONG RtlCompareUnicodeString(IN PUNICODE_STRING s1,IN PUNICODE_STRING s2,IN BOOLEAN CaseInsensitive);
BOOL IsBadReadPtr(CONST VOID *lp, UINT_PTR cb)
{
char* EndAddress;
char* StartAddress;
ULONG PageSize;
PageSize = PAGE_SIZE; //0x1000
if (cb != 0)
{
if (lp == NULL) {
return TRUE;
}
StartAddress = (char*)lp;
EndAddress = StartAddress + cb - 1;
if (EndAddress < StartAddress)
{
return TRUE;
}
else
{
__try
{
*(volatile CHAR *)StartAddress; //获得当前页面是否能读
//获得当前虚拟地址的所属页的基地址
StartAddress = (PCHAR)((ULONG_PTR)StartAddress & (~((LONG)PageSize - 1)));
EndAddress = (PCHAR)((ULONG_PTR)EndAddress & (~((LONG)PageSize - 1)));
while (StartAddress != EndAddress)
{
StartAddress = StartAddress + PageSize;
*(volatile CHAR *)StartAddress;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return TRUE;
}
}
}
return FALSE;
}
BOOL IsBadWritePtr(LPVOID lp, UINT_PTR cb)
{
char* EndAddress;
char* StartAddress;
ULONG PageSize;
PageSize = PAGE_SIZE;
if (cb != 0)
{
if (lp == NULL)
{
return TRUE;
}
StartAddress = (PCHAR)lp;
EndAddress = StartAddress + cb - 1;
if (EndAddress < StartAddress) {
return TRUE;
}
else
{
__try
{
*(volatile CHAR *)StartAddress = *(volatile CHAR *)StartAddress;
StartAddress = (PCHAR)((ULONG_PTR)StartAddress & (~((LONG)PageSize - 1)));
EndAddress = (PCHAR)((ULONG_PTR)EndAddress & (~((LONG)PageSize - 1)));
while (StartAddress != EndAddress)
{
StartAddress = StartAddress + PageSize;
*(volatile CHAR *)StartAddress = *(volatile CHAR *)StartAddress;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return TRUE;
}
}
}
return FALSE;
}
VOID RtlInitUnicodeString(OUT PUNICODE_STRING DestinationString,IN PCWSTR SourceString OPTIONAL )
{
SIZE_T Size;
#define MAXUSHORT 0xffff
const SIZE_T MaxSize = (MAXUSHORT & ~1) - sizeof(UNICODE_NULL); // an even number
if (SourceString)
{
Size = wcslen(SourceString) * sizeof(WCHAR);
if (Size > MaxSize)
Size = MaxSize;
DestinationString->Length = (USHORT)Size;
DestinationString->MaximumLength = (USHORT)Size + sizeof(UNICODE_NULL);
}
else
{
DestinationString->Length = 0;
DestinationString->MaximumLength = 0;
}
DestinationString->Buffer = (PWCHAR)SourceString;
}
LONG RtlCompareUnicodeString(IN PUNICODE_STRING s1,IN PUNICODE_STRING s2,IN BOOLEAN CaseInsensitive)
{
unsigned int len;
LONG ret = 0;
LPCWSTR p1, p2;
len = min(s1->Length, s2->Length) / sizeof(WCHAR);
p1 = s1->Buffer;
p2 = s2->Buffer;
if (CaseInsensitive)
{
p1 = CharUpperW(s1->Buffer);
p2 = CharUpperW(s2->Buffer);
while (!ret && len--)
{
ret = *p1 - *p2;
p1++;
p2++;
}
}
else
{
while (!ret && len--)
{
ret = *p1 - *p2;
p1++;
p2++;
}
}
if (!ret)
{
ret = s1->Length - s2->Length;
}
return ret;
}
ULONG BaseSetLastNTError(IN NTSTATUS Status)
{
LONG ErrorCode;
ErrorCode = __RtlNtStatusToDosError(Status);
SetLastError(ErrorCode);
return(ErrorCode);
}
BOOL GetProcessID_NtA(HANDLE* ProcessIdentify, ULONG_PTR ProcessIdentifyLength,const CHAR* ProcessImageName,ULONG_PTR ProcessImageNameLength)
{
BOOL IsOk = TRUE;
int LastError = 0;
if (IsBadWritePtr(ProcessIdentify, ProcessIdentifyLength) || IsBadReadPtr(ProcessImageName, ProcessImageNameLength))
{
LastError = ERROR_INVALID_PARAMETER;
goto Exit;
}
wchar_t* v5 = NULL;
int v7 = 0;
v7 = MultiByteToWideChar(CP_ACP, 0, ProcessImageName, -1, NULL, 0);
v5 = SysAllocStringLen(NULL, v7 - 1);
MultiByteToWideChar(CP_ACP, 0, ProcessImageName, -1, v5, v7);
if (GetProcessID_NtW(ProcessIdentify, ProcessIdentifyLength, v5, v7) == FALSE)
{
IsOk = FALSE;
}
LastError = GetLastError();
Exit:
if (v5 != NULL)
{
SysFreeString(v5);
v5 = NULL;
}
SetLastError(LastError);
return IsOk;
}
BOOL GetProcessID_NtW(HANDLE* ProcessIdentify, ULONG_PTR ProcessIdentifyLength,const WCHAR* ProcessImageName,ULONG_PTR ProcessImageNameLength)
{
BOOL IsOk = FALSE;
HANDLE SnapshotHandle = INVALID_HANDLE_VALUE;
PROCESSENTRY32 ProcessEntry32;
ProcessEntry32.dwSize = sizeof(PROCESSENTRY32);
int LastError = 0;
NTSTATUS Status = STATUS_SUCCESS;
if (IsBadWritePtr(ProcessIdentify, ProcessIdentifyLength) ||IsBadReadPtr(ProcessImageName, ProcessImageNameLength))
{
LastError = ERROR_INVALID_PARAMETER;
goto Exit;
}
PVOID ProcThrdInfo = NULL;
SIZE_T ProcThrdInfoSize = 0;
UNICODE_STRING v1;
RtlInitUnicodeString((_STRING_HEIPER_::PUNICODE_STRING)&v1, ProcessImageName);
for (;;)
{
ProcThrdInfoSize += 0x10000;
Status = __NtAllocateVirtualMemory(NtCurrentProcess(),
&ProcThrdInfo,
0,
&ProcThrdInfoSize,
MEM_COMMIT,
PAGE_READWRITE);
#ifndef NT_SUCCESS
#define NT_SUCCESS(StatCode) ((NTSTATUS)(StatCode) >= 0)
#endif
if (!NT_SUCCESS(Status))
{
LastError =BaseSetLastNTError(Status);
goto Exit;
}
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
Status = __NtQuerySystemInformation(SystemProcessInformation,
ProcThrdInfo,
ProcThrdInfoSize,
NULL);
if (Status == STATUS_INFO_LENGTH_MISMATCH)
{
__NtFreeVirtualMemory(NtCurrentProcess(),
&ProcThrdInfo,
&ProcThrdInfoSize,
MEM_RELEASE);
ProcThrdInfo = NULL;
}
else
{
break;
}
}
LastError = BaseSetLastNTError(Status);
if (!NT_SUCCESS(Status))
{
goto Exit;
}
ULONG ProcOffset = 0;
PSYSTEM_PROCESS_INFORMATION ProcessInfo;
ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)ProcThrdInfo;
do
{
ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)ProcessInfo + ProcOffset);
if (RtlCompareUnicodeString(((_STRING_HEIPER_::PUNICODE_STRING)&v1),
((_STRING_HEIPER_::PUNICODE_STRING)&ProcessInfo->ImageName), TRUE) == 0)
{
*ProcessIdentify = ProcessInfo->UniqueProcessId;
IsOk = TRUE;
goto Exit;
}
ProcOffset = ProcessInfo->NextEntryOffset;
} while (ProcOffset != 0);
LastError = ERROR_MOD_NOT_FOUND;
Exit:
if (ProcThrdInfo != NULL)
{
__NtFreeVirtualMemory(NtCurrentProcess(),
&ProcThrdInfo,
&ProcThrdInfoSize,
MEM_RELEASE);
ProcThrdInfo = NULL;
}
SetLastError(LastError);
return IsOk;
}