mirror of
https://github.com/mirkobrombin/raven.git
synced 2026-10-26 21:17:40 +00:00
55 lines
2.2 KiB
C
55 lines
2.2 KiB
C
#include <windows.h>
|
|
#include <winternl.h>
|
|
|
|
__declspec(dllimport) unsigned int Query(void);
|
|
__declspec(dllimport) unsigned int DependentState(void);
|
|
__declspec(dllexport) unsigned int entered;
|
|
__declspec(dllexport) unsigned int exit_requested;
|
|
|
|
static unsigned int verify_list(LIST_ENTRY *head, unsigned int member, unsigned int *found)
|
|
{
|
|
unsigned int count = 0;
|
|
LIST_ENTRY *previous = head;
|
|
for (LIST_ENTRY *link = head->Flink; link != head; link = link->Flink) {
|
|
if (++count > 128 || link->Blink != previous || link->Flink->Blink != link)
|
|
return 0;
|
|
unsigned char *entry = (unsigned char *)link - member;
|
|
PVOID image = *(PVOID *)(entry + 0x30);
|
|
UNICODE_STRING *name = (UNICODE_STRING *)(entry + 0x48);
|
|
if (!image || !name->Length || name->Length % 2 || name->MaximumLength < name->Length + 2 ||
|
|
name->Buffer[name->Length / 2] != 0)
|
|
return 0;
|
|
WCHAR *basename = name->Buffer;
|
|
for (unsigned int character = 0; character < name->Length / 2; ++character)
|
|
if (name->Buffer[character] == '\\' || name->Buffer[character] == '/')
|
|
basename = name->Buffer + character + 1;
|
|
if (GetModuleHandleW(basename) != image)
|
|
return 0;
|
|
IMAGE_DOS_HEADER *dos = image;
|
|
IMAGE_NT_HEADERS *nt = (IMAGE_NT_HEADERS *)((unsigned char *)image + dos->e_lfanew);
|
|
if (*(unsigned int *)(entry + 0x40) != nt->OptionalHeader.SizeOfImage)
|
|
return 0;
|
|
if (image == GetModuleHandleA("base.dll")) *found |= 1;
|
|
if (image == GetModuleHandleA("dependent.dll")) *found |= 2;
|
|
previous = link;
|
|
}
|
|
return head->Blink == previous ? count : 0;
|
|
}
|
|
|
|
unsigned int raven_entry(void)
|
|
{
|
|
entered = 1;
|
|
PPEB_LDR_DATA loader = NtCurrentTeb()->ProcessEnvironmentBlock->Ldr;
|
|
if (!loader || Query() != 112 || DependentState() != 21)
|
|
return 1;
|
|
unsigned int found = 0;
|
|
unsigned int load_count = verify_list((LIST_ENTRY *)((unsigned char *)loader + 0x10), 0, &found);
|
|
unsigned int memory_count = verify_list(&loader->InMemoryOrderModuleList, 0x10, &found);
|
|
unsigned int init_count = verify_list((LIST_ENTRY *)((unsigned char *)loader + 0x30), 0x20, &found);
|
|
if (load_count < 4 || memory_count != load_count || init_count != load_count - 1 || found != 3)
|
|
return 2;
|
|
if (exit_requested)
|
|
ExitProcess(0);
|
|
return 0;
|
|
}
|