mirror of
https://github.com/mirkobrombin/raven.git
synced 2026-10-28 21:25:06 +00:00
87 lines
3.2 KiB
C
87 lines
3.2 KiB
C
#define WIN32_LEAN_AND_MEAN
|
|
#include <windows.h>
|
|
|
|
static volatile LONG ready, request, acknowledged, stop;
|
|
static volatile ULONG_PTR remote_pointer;
|
|
static volatile LONG counters[2];
|
|
static PROCESS_INFORMATION child;
|
|
|
|
static DWORD WINAPI compute(void *parameter)
|
|
{
|
|
(void)parameter;
|
|
InterlockedIncrement(&ready);
|
|
while (!stop) InterlockedIncrement(&counters[1]);
|
|
return 0;
|
|
}
|
|
|
|
static int parent(void)
|
|
{
|
|
WCHAR command[1024];
|
|
STARTUPINFOW startup = {sizeof(startup)};
|
|
command[0] = '"';
|
|
DWORD length = GetModuleFileNameW(0, command + 1, 1000);
|
|
if (!length || length >= 1000) return 1;
|
|
command[++length] = '"';
|
|
command[++length] = ' ';
|
|
command[++length] = 'c';
|
|
command[++length] = 0;
|
|
if (!CreateProcessW(0, command, 0, 0, FALSE, 0, 0, 0, &startup, &child)) return 2;
|
|
LONG value = 0;
|
|
for (unsigned i = 0; value != 2 && i < 1000; ++i) {
|
|
if (!ReadProcessMemory(child.hProcess, (void *)&ready, &value, sizeof(value), 0)) return 3;
|
|
Sleep(1);
|
|
}
|
|
if (value != 2) return 4;
|
|
void *allocation = VirtualAllocEx(child.hProcess, 0, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
|
if (!allocation) return 5;
|
|
DWORD magic = 0x13579bdf, previous;
|
|
if (!WriteProcessMemory(child.hProcess, allocation, &magic, sizeof(magic), 0)) return 6;
|
|
if (!VirtualProtectEx(child.hProcess, allocation, 4096, PAGE_READONLY, &previous) || previous != PAGE_READWRITE) return 7;
|
|
MEMORY_BASIC_INFORMATION information;
|
|
if (!VirtualQueryEx(child.hProcess, allocation, &information, sizeof(information)) || information.Protect != PAGE_READONLY) return 8;
|
|
ULONG_PTR pointer = (ULONG_PTR)allocation;
|
|
if (!WriteProcessMemory(child.hProcess, (void *)&remote_pointer, &pointer, sizeof(pointer), 0)) return 9;
|
|
value = 1;
|
|
if (!WriteProcessMemory(child.hProcess, (void *)&request, &value, sizeof(value), 0)) return 10;
|
|
value = 0;
|
|
for (unsigned i = 0; !value && i < 1000; ++i) {
|
|
if (!ReadProcessMemory(child.hProcess, (void *)&acknowledged, &value, sizeof(value), 0)) return 11;
|
|
Sleep(1);
|
|
}
|
|
if (value != 1) return 12;
|
|
if (!VirtualFreeEx(child.hProcess, allocation, 0, MEM_RELEASE)) return 13;
|
|
value = 1;
|
|
if (!WriteProcessMemory(child.hProcess, (void *)&stop, &value, sizeof(value), 0)) return 14;
|
|
if (WaitForSingleObject(child.hProcess, 5000) != WAIT_OBJECT_0) return 15;
|
|
DWORD code;
|
|
if (!GetExitCodeProcess(child.hProcess, &code) || code) return 16;
|
|
CloseHandle(child.hThread);
|
|
CloseHandle(child.hProcess);
|
|
return 0;
|
|
}
|
|
|
|
int raven_entry(void)
|
|
{
|
|
const WCHAR *line = GetCommandLineW();
|
|
unsigned length = 0;
|
|
while (line[length]) ++length;
|
|
if (!length || line[length - 1] != 'c') {
|
|
const int result = parent();
|
|
if (result && child.hProcess) {
|
|
TerminateProcess(child.hProcess, 99);
|
|
WaitForSingleObject(child.hProcess, 5000);
|
|
CloseHandle(child.hThread);
|
|
CloseHandle(child.hProcess);
|
|
}
|
|
return result;
|
|
}
|
|
HANDLE thread = CreateThread(0, 0, compute, 0, 0, 0);
|
|
if (!thread) return 20;
|
|
InterlockedIncrement(&ready);
|
|
while (!request) InterlockedIncrement(&counters[0]);
|
|
acknowledged = *(volatile DWORD *)remote_pointer == 0x13579bdf ? 1 : 2;
|
|
while (!stop) InterlockedIncrement(&counters[0]);
|
|
if (WaitForSingleObject(thread, 5000) != WAIT_OBJECT_0) return 21;
|
|
return counters[0] && counters[1] && acknowledged == 1 ? 0 : 22;
|
|
}
|