1
0
mirror of https://github.com/rbmm/SC synced 2026-06-08 17:03:41 +00:00
Files
rbmm 97e37278db *
2025-12-12 12:25:34 +02:00

189 lines
4.3 KiB
C++

#include "stdafx.h"
_NT_BEGIN
#include "../DelayImp/DirectSysCall.h"
NTSTATUS RedirectContext(PVOID BaseAddress)
{
CONTEXT ctx = {};
RtlCaptureContext(&ctx);
_PEB* peb = RtlGetCurrentPeb(); // 2 parameter
PVOID ImageBaseAddress = peb->ImageBaseAddress;
if (PIMAGE_NT_HEADERS pinth = RtlImageNtHeader(ImageBaseAddress))
{
(ULONG_PTR&)ImageBaseAddress += pinth->OptionalHeader.AddressOfEntryPoint; // 1 parameter
if (PVOID Rip = GetProcAddress(GetModuleHandleW(L"ntdll"), "RtlUserThreadStart"))
{
PNT_TIB Tib = reinterpret_cast<PNT_TIB>(NtCurrentTeb());
union {
PCONTEXT pctx;
ULONG_PTR StackBase;
};
for (StackBase = (ULONG_PTR)Tib->StackBase - sizeof(CONTEXT);
&ctx < pctx;
StackBase -= __alignof(CONTEXT))
{
if (pctx->Rcx == (ULONG_PTR)ImageBaseAddress &&
pctx->Rdx == (ULONG_PTR)peb &&
pctx->Rip == (ULONG_PTR)Rip &&
pctx->SegCs == ctx.SegCs &&
pctx->SegSs == ctx.SegSs)
{
pctx->Rcx = (ULONG_PTR)BaseAddress;
//LdrSetDllManifestProber(MyDllManifestProber, 0, 0);
return STATUS_SUCCESS;
}
}
}
}
return STATUS_NOT_FOUND;
}
PCWSTR GetShellName(PCWSTR* ppc)
{
if (PWSTR psz = wcschr(GetCommandLineW(), '*'))
{
if (PWSTR pc = wcschr(++psz, '*'))
{
*pc++ = 0;
*ppc = pc;
return psz;
}
}
return L"sc.bin";
}
NTSTATUS OnProcessAttach()
{
NTSTATUS status = STATUS_INTERNAL_ERROR;
if (InitZwSupport())
{
status = STATUS_INVALID_PARAMETER_1;
PCWSTR pc = 0;
if (PCWSTR psz = GetShellName(&pc))
{
UNICODE_STRING ObjectName;
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName };
if (0 <= (status = RtlDosPathNameToNtPathName_U_WithStatus(psz, &ObjectName, 0, 0)))
{
if (pc) wcscpy(GetCommandLineW(), pc);
HANDLE hFile;
IO_STATUS_BLOCK iosb;
status = ZwOpenFile(&hFile, FILE_GENERIC_READ, &oa, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);
RtlFreeUnicodeString(&ObjectName);
if (0 <= status)
{
FILE_STANDARD_INFORMATION fsi;
if (0 <= (status = ZwQueryInformationFile(hFile, &iosb, &fsi, sizeof(fsi), FileStandardInformation)))
{
if (!fsi.EndOfFile.QuadPart || fsi.EndOfFile.HighPart)
{
status = STATUS_FILE_TOO_LARGE;
}
else
{
PVOID BaseAddress = 0;
SIZE_T RegionSize = fsi.EndOfFile.QuadPart;
if (0 <= (status = ZwAllocateVirtualMemory(NtCurrentProcess(), &BaseAddress, 0,
&RegionSize, MEM_TOP_DOWN | MEM_COMMIT, PAGE_READWRITE)))
{
if (0 > (status = ZwReadFile(hFile, 0, 0, 0, &iosb, BaseAddress, fsi.EndOfFile.LowPart, 0, 0)) ||
0 > (status = ZwProtectVirtualMemory(NtCurrentProcess(), &BaseAddress, &RegionSize,
PAGE_EXECUTE_READ, &fsi.NumberOfLinks)) ||
0 > (status = RedirectContext(BaseAddress)))
{
ZwFreeVirtualMemory(NtCurrentProcess(), &BaseAddress, &RegionSize, MEM_RELEASE);
BaseAddress = 0;
}
}
}
}
ZwClose(hFile);
}
}
}
RtlNtStatusToDosError(status);
}
return 0 <= status;
}
void CALLBACK OnTls(PVOID, DWORD Reason, PVOID)
{
switch (Reason)
{
case DLL_PROCESS_DETACH:
FreeZwSupport();
break;
case DLL_PROCESS_ATTACH:
OnProcessAttach();
break;
}
}
ULONG _tls_index;
static const PIMAGE_TLS_CALLBACK g_tls_cb[] = { OnTls, 0 };
#pragma const_seg(".rdata$T")
EXTERN_C const IMAGE_TLS_DIRECTORY _tls_used = {
(ULONG_PTR)0, // start of tls data
(ULONG_PTR)0, // end of tls data
(ULONG_PTR)&_tls_index, // address of tls_index
(ULONG_PTR)g_tls_cb, // pointer to call back array
};
#pragma const_seg()
#ifdef _WIN64
__pragma(comment(linker, "/include:_tls_used"))
#else
__pragma(comment(linker, "/include:__tls_used"))
#endif
EXTERN_C
DECLSPEC_NORETURN
NTSYSAPI
VOID
NTAPI
RtlExitUserProcess(
_In_ NTSTATUS ExitStatus
);
EXTERN_C
NTSYSCALLAPI
NTSTATUS
NTAPI
NtRaiseHardError(
_In_ NTSTATUS ErrorStatus,
_In_ ULONG NumberOfParameters,
_In_ ULONG UnicodeStringParameterMask,
_In_reads_(NumberOfParameters) PULONG_PTR Parameters,
_In_ HARDERROR_RESPONSE_OPTION ValidResponseOptions,
_Out_ HARDERROR_RESPONSE* Response
);
void WINAPI ep(HARDERROR_RESPONSE Response)
{
NTSTATUS status = RtlGetLastNtStatus();
if (0 <= status)
{
status = STATUS_UNSUCCESSFUL;
}
RtlExitUserProcess(NtRaiseHardError(status, 0, 0, 0, OptionOk, &Response));
}
_NT_END