mirror of
https://github.com/BeneficialCode/WinArk.git
synced 2026-10-18 21:51:35 +08:00
131 lines
3.9 KiB
C++
131 lines
3.9 KiB
C++
#include "pch.h"
|
|
#include "Helpers.h"
|
|
#include "Logging.h"
|
|
|
|
// AntiRootkit!khook::GetSystemServiceTable
|
|
ULONG_PTR Helpers::SearchSignature(ULONG_PTR address, PUCHAR signature, ULONG size,ULONG memSize) {
|
|
int i = memSize;
|
|
ULONG_PTR maxAddress = address + memSize - size;
|
|
|
|
while (i--&&address < maxAddress) {
|
|
if (memcmp(signature, (void*)address, size) == 0) {
|
|
return address;
|
|
}
|
|
address++;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
NTSTATUS Helpers::OpenProcess(ACCESS_MASK accessMask, ULONG pid, PHANDLE phProcess) {
|
|
CLIENT_ID cid;
|
|
cid.UniqueProcess = ULongToHandle(pid);
|
|
cid.UniqueThread = nullptr;
|
|
|
|
OBJECT_ATTRIBUTES procAttributes = RTL_CONSTANT_OBJECT_ATTRIBUTES(nullptr, OBJ_KERNEL_HANDLE);
|
|
return ZwOpenProcess(phProcess, accessMask, &procAttributes, &cid);
|
|
}
|
|
|
|
ULONG_PTR Helpers::KiDecodePointer(_In_ ULONG_PTR pointer, _In_ ULONG_PTR salt) {
|
|
ULONG_PTR value = pointer;
|
|
|
|
#ifdef _WIN64
|
|
value = RotateLeft64(value ^ KiWaitNever, KiWaitNever & 0xFF);
|
|
value = RtlUlonglongByteSwap(value ^ salt)^ KiWaitAlways;
|
|
#else
|
|
value = RotateLeft32(value ^ (ULONG)KiWaitNever, KiWaitNever & 0xFF);
|
|
value = RtlUlongByteSwap(value ^ salt) ^ (ULONG)KiWaitAlways;
|
|
#endif // _WIN64
|
|
return value;
|
|
}
|
|
|
|
// Check if fullName is ends with ShortName
|
|
bool Helpers::IsSuffixedUnicodeString(PCUNICODE_STRING fullName, PCUNICODE_STRING shortName, bool caseInsensitive) {
|
|
if (fullName && shortName &&
|
|
shortName->Length <= fullName->Length) {
|
|
UNICODE_STRING ustr = {
|
|
shortName->Length,
|
|
ustr.Length,
|
|
(PWSTR)RtlOffsetToPointer(fullName->Buffer,fullName->Length - ustr.Length)
|
|
};
|
|
return RtlEqualUnicodeString(&ustr, shortName, caseInsensitive);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Helpers::IsMappedByLdrLoadDll(PCUNICODE_STRING shortName) {
|
|
// smss.exe can map kernel32.dll during creation of \\KnownDlls (in that case ArbitrayUserPointer will be 0)
|
|
// Wow64 processes map kernel32.dll serverals times (32 and 64-bit version) with WOW64_IMAGE_SECTION or
|
|
// NOT_AN_IMAGE
|
|
|
|
UNICODE_STRING name;
|
|
__try {
|
|
PNT_TIB Teb = (PNT_TIB)PsGetCurrentThreadTeb();
|
|
if (!Teb || !Teb->ArbitraryUserPointer) {
|
|
// This is not it
|
|
return false;
|
|
}
|
|
name.Buffer = (PWSTR)Teb->ArbitraryUserPointer;
|
|
|
|
// Check that we hava a valid user-mode address
|
|
ProbeForRead(name.Buffer, sizeof(WCHAR), __alignof(WCHAR));
|
|
|
|
// Check buffer length
|
|
name.Length = (USHORT)wcsnlen_s(name.Buffer, MAXSHORT);
|
|
|
|
if (name.Length == MAXSHORT) {
|
|
// name is too long
|
|
return false;
|
|
}
|
|
|
|
name.Length *= sizeof(WCHAR);
|
|
name.MaximumLength = name.Length;
|
|
|
|
// See if it's our needed module
|
|
return IsSuffixedUnicodeString(&name, shortName);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
LogDebug("#EXCEPTION: (0x%X) IsMappedByLdrLoadDll", GetExceptionCode());
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// Checks if process with pid is a specific process by its file name
|
|
bool Helpers::IsSpecificProcess(HANDLE pid,const WCHAR* imageName,bool isDebugged) {
|
|
ASSERT(imageName);
|
|
bool result = false;
|
|
|
|
PEPROCESS Process;
|
|
NTSTATUS status = PsLookupProcessByProcessId(pid, &Process);
|
|
if (NT_SUCCESS(status)) {
|
|
// Check for kernel debugger?
|
|
if (!isDebugged ||
|
|
PsIsProcessBeingDebugged(Process)) {
|
|
// Get process handle
|
|
HANDLE hProcess;
|
|
status = ObOpenObjectByPointer(Process, OBJ_KERNEL_HANDLE, nullptr,
|
|
PROCESS_ALL_ACCESS, *PsProcessType, KernelMode, &hProcess);
|
|
if (NT_SUCCESS(status)) {
|
|
// Get process name
|
|
// INFO: we need for file name, thus can't use PsGetProcessImageFileName which will truncate it past 14 chars
|
|
UCHAR buffer[280] = { 0 };
|
|
status = ZwQueryInformationProcess(hProcess, ProcessImageFileName, buffer, sizeof(buffer) - sizeof(WCHAR), nullptr);
|
|
if (NT_SUCCESS(status)) {
|
|
auto path = (UNICODE_STRING*)buffer;
|
|
auto bs = wcsrchr(path->Buffer, L'\\');
|
|
NT_ASSERT(bs);
|
|
if (bs + 1 != nullptr && !_wcsicmp(bs + 1, imageName))
|
|
result = true;
|
|
}
|
|
// Close handle
|
|
ZwClose(hProcess);
|
|
}
|
|
}
|
|
|
|
// Dereference process object back
|
|
ObDereferenceObject(Process);
|
|
}
|
|
|
|
|
|
return result;
|
|
} |