Skip to content

Instantly share code, notes, and snippets.

@Inndy
Created July 27, 2023 17:12
Show Gist options
  • Save Inndy/bca46fa1968578c3c85c0de363ab459b to your computer and use it in GitHub Desktop.
Save Inndy/bca46fa1968578c3c85c0de363ab459b to your computer and use it in GitHub Desktop.
#include <windows.h>
#include <winternl.h>
#include <stdarg.h>
#define GetCurrentProcess() ((HANDLE)-1)
NTSYSCALLAPI NTSTATUS NTAPI NtCreateSection(
_Out_ PHANDLE SectionHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_opt_ PLARGE_INTEGER MaximumSize,
_In_ ULONG SectionPageProtection,
_In_ ULONG AllocationAttributes,
_In_opt_ HANDLE FileHandle
);
NTSYSCALLAPI NTSTATUS NTAPI NtWriteFile(
_In_ HANDLE FileHandle,
_In_opt_ HANDLE Event,
_In_opt_ PIO_APC_ROUTINE ApcRoutine,
_In_opt_ PVOID ApcContext,
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
_In_ PVOID Buffer,
_In_ ULONG Length,
_In_opt_ PLARGE_INTEGER ByteOffset,
_In_opt_ PULONG Key
);
typedef enum _SECTION_INHERIT
{
ViewShare = 1,
ViewUnmap = 2
} SECTION_INHERIT;
NTSYSCALLAPI NTSTATUS NTAPI NtMapViewOfSection(
_In_ HANDLE SectionHandle,
_In_ HANDLE ProcessHandle,
_Inout_ _At_(*BaseAddress, _Readable_bytes_(*ViewSize) _Writable_bytes_(*ViewSize) _Post_readable_byte_size_(*ViewSize)) PVOID* BaseAddress,
_In_ ULONG_PTR ZeroBits,
_In_ SIZE_T CommitSize,
_Inout_opt_ PLARGE_INTEGER SectionOffset,
_Inout_ PSIZE_T ViewSize,
_In_ SECTION_INHERIT InheritDisposition,
_In_ ULONG AllocationType,
_In_ ULONG Win32Protect
);
NTSYSAPI NTSTATUS NTAPI LdrGetDllHandle(
_In_opt_ PWSTR DllPath,
_In_opt_ PULONG DllCharacteristics,
_In_ PUNICODE_STRING DllName,
_Out_ PVOID* DllHandle
);
NTSYSAPI NTSTATUS NTAPI LdrGetProcedureAddress(
_In_ PVOID DllHandle,
_In_opt_ PANSI_STRING ProcedureName,
_In_opt_ ULONG ProcedureNumber,
_Out_ PVOID* ProcedureAddress
);
NTSYSCALLAPI NTSTATUS NTAPI NtDelayExecution(
_In_ BOOLEAN Alertable,
_In_ PLARGE_INTEGER DelayInterval
);
NTSYSCALLAPI NTSTATUS NTAPI NtTerminateProcess(
_In_opt_ HANDLE ProcessHandle,
_In_ NTSTATUS ExitStatus
);
void _write(HANDLE file, LPCVOID buf, ULONG len) {
IO_STATUS_BLOCK IoStatus = { 0 };
LARGE_INTEGER Off = { 0 };
NtWriteFile(file, NULL, NULL, NULL, &IoStatus, (LPVOID)buf, len, &Off, NULL);
}
void error(const char* msg) {
HANDLE hStderr = NtCurrentTeb()->ProcessEnvironmentBlock->ProcessParameters->Reserved2[4];
_write(hStderr, msg, strlen(msg));
NtTerminateProcess(GetCurrentProcess(), 1);
}
void write_stdout(LPCVOID buf, ULONG len) {
HANDLE hStdout = NtCurrentTeb()->ProcessEnvironmentBlock->ProcessParameters->Reserved2[3];
_write(hStdout, buf, len);
}
void print(const char* msg) {
write_stdout(msg, strlen(msg));
}
void puts(const char* msg) {
print(msg);
write_stdout("\n", 1);
}
int (WINAPI* _vsnprintf)(
char* buffer,
size_t count,
const char* format,
va_list argptr
);
void printf(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
static char buf[4096];
int n = _vsnprintf(buf, sizeof(buf), fmt, args);
write_stdout(buf, n);
va_end(args);
}
void xxd(LPVOID data, SIZE_T len) {
char line[16];
for (SIZE_T i = 0; i < len; i++) {
LPCBYTE p = (LPCBYTE)data + i;
BYTE b = *p;
if (i % 16 == 0) {
printf("%p:", p);
}
printf(" %.2x", b);
line[i & 15] = (0x20 <= b && b <= 0x7e) ? b : '.';
if (i % 16 == 15) {
write_stdout(" ", 2);
write_stdout(line, 16);
write_stdout("\n", 1);
}
}
}
int mainCRTStartup() {
HANDLE hFile = NULL, hSection = NULL;
OBJECT_ATTRIBUTES ObjectAttr = { 0 };
IO_STATUS_BLOCK IoStatus = { 0 };
UNICODE_STRING Filename;
NTSTATUS status;
ANSI_STRING Procname;
RtlInitAnsiString(&Procname, "_vsnprintf");
RtlInitUnicodeString(&Filename, L"ntdll.dll");
HMODULE hNtdll = NULL;
status = LdrGetDllHandle(NULL, NULL, &Filename, &hNtdll);
if (NT_ERROR(status)) {
error("LdrGetDllHandle failed");
return 1;
}
/*
LIST_ENTRY* ldr_node = (&NtCurrentTeb()->ProcessEnvironmentBlock->Ldr->InMemoryOrderModuleList) - 1;
LDR_DATA_TABLE_ENTRY *ntdll_ldr = (LPVOID)ldr_node->Flink->Flink;
hNtdll = ntdll_ldr->DllBase;
*/
status = LdrGetProcedureAddress(hNtdll, &Procname, 0, (PVOID*)&_vsnprintf);
if (NT_ERROR(status)) {
error("LdrGetProcedureAddress failed");
return 1;
}
RtlInitUnicodeString(&Filename, L"\\??\\C:\\Windows\\System32\\ntdll.dll");
InitializeObjectAttributes(&ObjectAttr, &Filename, OBJ_INHERIT, NULL, NULL);
status = NtOpenFile(&hFile, GENERIC_READ, &ObjectAttr, &IoStatus, FILE_SHARE_READ, 0);
if (NT_ERROR(status)) {
error("NtOpenFile failed");
return 1;
}
InitializeObjectAttributes(&ObjectAttr, NULL, OBJ_INHERIT, NULL, NULL);
LARGE_INTEGER MaximumSize = { .QuadPart = 4096 };
status = NtCreateSection(&hSection, GENERIC_READ, &ObjectAttr, &MaximumSize, PAGE_READONLY, SEC_COMMIT, hFile);
if (NT_ERROR(status)) {
error("NtCreateSection failed");
return 1;
}
SIZE_T vsize = 256;
LPVOID ptr = NULL;
status = NtMapViewOfSection(hSection, GetCurrentProcess(), &ptr, 0, 0, NULL, &vsize, ViewShare, 0, PAGE_WRITECOPY);
if (NT_ERROR(status)) {
error("NtMapViewOfSection failed");
return 1;
}
printf("Mapped at %p, size 0x%llx, attach debugger now\n", ptr, vsize);
printf("Wait 30s...\n");
NtDelayExecution(FALSE, &(LARGE_INTEGER){.QuadPart = -10000 * 30 * 1000 });
RtlCopyMemory(ptr, "Hello, World?!\r\n", 16);
xxd(ptr, 256);
NtClose(hFile);
NtDelayExecution(FALSE, &(LARGE_INTEGER){.QuadPart = 0x8000000000000000ll });
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment