You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
5.1 KiB
184 lines
5.1 KiB
#include <fltKernel.h>
|
|
#include <ntimage.h>
|
|
#include "struct.h"
|
|
|
|
#define YOUR_APP_NAME "dwm.exe"
|
|
|
|
#define dprintf(...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, __VA_ARGS__)
|
|
|
|
EXTERN_C
|
|
PCCHAR
|
|
NTAPI
|
|
PsGetProcessImageFileName(IN PEPROCESS Process);
|
|
|
|
EXTERN_C
|
|
PVOID
|
|
PsGetProcessSectionBaseAddress(__in PEPROCESS Process);
|
|
|
|
using fnMiObtainReferencedVadEx = void *(NTAPI *)(void *a1, char a2, int *a3);
|
|
|
|
__declspec(naked) PVOID GetNtosBase()
|
|
{
|
|
_asm {
|
|
mov rax, qword ptr gs:[18h]
|
|
mov rcx, [rax+38h]
|
|
mov rax, 0FFFFFFFFFFFFF000h
|
|
and rax, [rcx+4h]
|
|
jmp while_begin
|
|
search_begin:
|
|
add rax, 0FFFFFFFFFFFFF000h
|
|
while_begin:
|
|
xor ecx, ecx
|
|
jmp search_cmp
|
|
search_next:
|
|
add rcx, 1
|
|
cmp rcx, 0FF9h
|
|
jz search_begin
|
|
search_cmp:
|
|
cmp byte ptr[rax+rcx], 48h
|
|
jnz search_next
|
|
cmp byte ptr[rax+rcx+1], 8Dh
|
|
jnz search_next
|
|
cmp byte ptr[rax+rcx+2], 1Dh
|
|
jnz search_next
|
|
cmp byte ptr[rax+rcx+6], 0FFh
|
|
jnz search_next
|
|
mov r8d,[rax+rcx+3]
|
|
lea edx,[rcx+r8]
|
|
add edx, eax
|
|
add edx, 7
|
|
test edx, 0FFFh
|
|
jnz search_next
|
|
mov rdx, 0FFFFFFFF00000000h
|
|
and rdx, rax
|
|
add r8d, eax
|
|
lea eax,[rcx+r8]
|
|
add eax, 7
|
|
or rax, rdx
|
|
ret
|
|
}
|
|
}
|
|
|
|
static PUCHAR
|
|
FindPattern(PVOID Module, ULONG Size, LPCSTR Pattern, LPCSTR Mask)
|
|
{
|
|
auto checkMask = [](PUCHAR Buffer, LPCSTR Pattern, LPCSTR Mask) -> bool {
|
|
for (auto x = Buffer; *Mask; Pattern++, Mask++, x++)
|
|
{
|
|
auto addr = *(UCHAR *)(Pattern);
|
|
if (addr != *x && *Mask != '?')
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
for (auto x = 0; x < Size - strlen(Mask); x++)
|
|
{
|
|
auto addr = (PUCHAR)Module + x;
|
|
if (checkMask(addr, Pattern, Mask))
|
|
return addr;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
static PEPROCESS
|
|
FindDWMEprocess(ULONG &OutPid)
|
|
{
|
|
OutPid = 0;
|
|
PEPROCESS pEpDWM = nullptr;
|
|
for (ULONG i = 0; i < 0x5000; i += 4)
|
|
{
|
|
PEPROCESS pEp = nullptr;
|
|
auto lStatus = PsLookupProcessByProcessId((HANDLE)i, &pEp);
|
|
if (!NT_SUCCESS(lStatus) || !pEp)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
auto pName = PsGetProcessImageFileName(pEp);
|
|
// A more casual code
|
|
if (pName && strstr(pName, YOUR_APP_NAME))
|
|
{
|
|
pEpDWM = pEp;
|
|
}
|
|
ObDereferenceObject(pEp);
|
|
|
|
if (pEpDWM)
|
|
{
|
|
OutPid = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return pEpDWM;
|
|
}
|
|
|
|
EXTERN_C
|
|
NTSTATUS
|
|
DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
|
|
{
|
|
dprintf("new world!\n");
|
|
|
|
PVOID pNtosBase = GetNtosBase();
|
|
dprintf("pNtosBase=%p\n", pNtosBase);
|
|
|
|
// 48 89 5C 24 10 48 89 74 24 18 48 89 7C 24 20 41 54 41 56 41 57 48 83 EC 20 41 C7 00 00 00 00 00 4D 8B E0 65 48 8B
|
|
// ?? ?? 88 01 00 00 44 8B ?? 48 8B ?? ?? ?? ?? B8 00 00 00
|
|
fnMiObtainReferencedVadEx pMiObtainReferencedVadEx = (fnMiObtainReferencedVadEx)FindPattern(
|
|
((PUCHAR)pNtosBase + 0x1000),
|
|
0x50000,
|
|
"\x48\x89\x5C\x24\x10\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x41\x54\x41\x56\x41\x57\x48\x83\xEC\x20\x41\xC7\x00\x00\x00\x00\x00\x4D\x8B\xE0\x65\x48\x8B\x00\x00\x88\x01\x00\x00\x44\x8B\x00\x48\x8B\x00\x00\x00\x00\xB8\x00\x00\x00",
|
|
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx??xxxxxx?xx????xxxx");
|
|
dprintf("pMiObtainReferencedVadEx=%p\n", pMiObtainReferencedVadEx);
|
|
|
|
if (!pMiObtainReferencedVadEx)
|
|
{
|
|
dprintf("Error: Not found MiObtainReferencedVadEx!\n");
|
|
return -1;
|
|
}
|
|
|
|
ULONG uDWMPID;
|
|
PEPROCESS pEpDWM = FindDWMEprocess(uDWMPID);
|
|
dprintf("pEpDWM=%p, uDWMPID=%d!\n", pEpDWM, uDWMPID);
|
|
if (uDWMPID == 0)
|
|
{
|
|
dprintf("Error: Not found DWM!\n");
|
|
return -2;
|
|
}
|
|
|
|
PUCHAR pFirstPage = (PUCHAR)PsGetProcessSectionBaseAddress(pEpDWM) + 0x1000;
|
|
dprintf("pFirstPage=%p!\n", pFirstPage);
|
|
|
|
KAPC_STATE ks;
|
|
KeStackAttachProcess(pEpDWM, &ks);
|
|
|
|
PETHREAD pCurThread = KeGetCurrentThread();
|
|
short uOldSpecialApcDisable = *(short *)((PUCHAR)pCurThread + SpecialApcDisable_17763_OFFSET);
|
|
|
|
*(short *)((PUCHAR)pCurThread + SpecialApcDisable_17763_OFFSET) = 0;
|
|
|
|
int ns = 0;
|
|
auto pVAD = (PMMVAD_SHORT_17763)pMiObtainReferencedVadEx(pFirstPage, 2, &ns);
|
|
|
|
*(short *)((PUCHAR)pCurThread + SpecialApcDisable_17763_OFFSET) = uOldSpecialApcDisable;
|
|
|
|
KeUnstackDetachProcess(&ks);
|
|
|
|
dprintf("pVAD=%p\n", pVAD);
|
|
if (pVAD)
|
|
{
|
|
dprintf("pVAD->u.VadFlags.PrivateMemory=%d\n", pVAD->u.VadFlags.PrivateMemory);
|
|
dprintf("pVAD->u.VadFlags.Graphics=%d\n", pVAD->u.VadFlags.Graphics);
|
|
dprintf("pVAD->u.VadFlags.Enclave=%d\n", pVAD->u.VadFlags.Enclave);
|
|
|
|
pVAD->u.VadFlags.PrivateMemory = 1;
|
|
pVAD->u.VadFlags.Graphics = 1;
|
|
pVAD->u.VadFlags.Enclave = 1;
|
|
dprintf("fake world!\n");
|
|
}
|
|
|
|
return STATUS_VIRUS_INFECTED;
|
|
}
|