UACME/Source/Naka/main.c

295 lines
6.8 KiB
C

/*******************************************************************************
*
* (C) COPYRIGHT AUTHORS, 2016
*
* TITLE: MAIN.C
*
* VERSION: 2.51
*
* DATE: 10 July 2016
*
* Naka, support payload compressor.
*
* 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.
*
*******************************************************************************/
#pragma once
#if !defined UNICODE
#error ANSI build is not supported
#endif
#if (_MSC_VER >= 1900)
#ifdef _DEBUG
#pragma comment(lib, "vcruntimed.lib")
#pragma comment(lib, "ucrtd.lib")
#else
#pragma comment(lib, "libvcruntime.lib")
#endif
#endif
//disable nonmeaningful warnings.
#pragma warning(disable: 4005) // macro redefinition
#pragma warning(disable: 4055) // %s : from data pointer %s to function pointer %s
#pragma warning(disable: 4152) // nonstandard extension, function/data pointer conversion in expression
#pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union
#pragma warning(disable: 6102) // Using %s from failed function call at line %u
#pragma warning(disable: 6320) // exception-filter expression is the constant EXCEPTION_EXECUTE_HANDLER
#include <Windows.h>
#include <ntstatus.h>
#include "..\shared\ntos.h"
#include "..\shared\minirtl.h"
#include "..\Shared\cmdline.h"
#include "..\Shared\_filename.h"
ULONG g_XorKey = 'naka';
/*
* EncodeBuffer
*
* Purpose:
*
* Decrypt/Encrypt given buffer.
*
*/
VOID EncodeBuffer(
PVOID Buffer,
ULONG BufferSize
)
{
ULONG k, c;
PUCHAR ptr;
if ((Buffer == NULL) || (BufferSize == 0))
return;
k = g_XorKey;
c = BufferSize;
ptr = Buffer;
do {
*ptr ^= k;
k = _rotl(k, 1);
ptr++;
--c;
} while (c != 0);
}
/*
* supWriteBufferToFile
*
* Purpose:
*
* Create new file and write buffer to it.
*
*/
BOOL supWriteBufferToFile(
_In_ LPWSTR lpFileName,
_In_ PVOID Buffer,
_In_ DWORD BufferSize
)
{
HANDLE hFile;
DWORD bytesIO;
if (
(lpFileName == NULL) ||
(Buffer == NULL) ||
(BufferSize == 0)
)
{
return FALSE;
}
hFile = CreateFileW(lpFileName,
GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
return FALSE;
}
WriteFile(hFile, Buffer, BufferSize, &bytesIO, NULL);
CloseHandle(hFile);
return (bytesIO == BufferSize);
}
/*
* CompressBufferLZNT1
*
* Purpose:
*
* Compress given buffer with LZ algorithm.
*
* Use VirtualFree to release returned buffer when it no longer needed.
*
*/
PUCHAR CompressBufferLZNT1(
_In_ PUCHAR SrcBuffer,
_In_ ULONG SrcSize,
_Inout_ PULONG FinalCompressedSize
)
{
BOOL cond = FALSE;
NTSTATUS status;
ULONG CompressedSize = 0;
ULONG CompressBufferWorkSpaceSize = 0;
ULONG CompressFragmentWorkSpaceSize = 0;
ULONG CompBufferSize = 0;
PVOID WorkSpace = NULL;
PUCHAR CompBuffer = NULL;
if (FinalCompressedSize == NULL)
return NULL;
do {
status = RtlGetCompressionWorkSpaceSize(
COMPRESSION_FORMAT_LZNT1,
&CompressBufferWorkSpaceSize,
&CompressFragmentWorkSpaceSize
);
//accept nothing but STATUS_SUCCESS
if (status != STATUS_SUCCESS) {
break;
}
WorkSpace = (PVOID)VirtualAlloc(NULL, CompressBufferWorkSpaceSize,
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (WorkSpace == NULL) {
break;
}
//original size + safe buffer + sizeof header
CompBufferSize = SrcSize + 0x1000 + sizeof(ULONG);
CompBuffer = (PUCHAR)VirtualAlloc(NULL, CompBufferSize,
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (CompBuffer == NULL) {
break;
}
CompressedSize = 0;
status = RtlCompressBuffer(
COMPRESSION_FORMAT_LZNT1,
SrcBuffer,
SrcSize,
&CompBuffer[4],
CompBufferSize,
4096,
&CompressedSize,
WorkSpace
);
if (status != STATUS_SUCCESS) {
VirtualFree(CompBuffer, 0, MEM_RELEASE);
break;
}
*(PULONG)&CompBuffer[0] = SrcSize;//save original size
CompressedSize += sizeof(ULONG); //add header size
*FinalCompressedSize = CompressedSize;
} while (cond);
if (WorkSpace != NULL) {
VirtualFree(WorkSpace, 0, MEM_RELEASE);
}
return CompBuffer;
}
void CompressPayload(
LPWSTR lpInputFile
)
{
BOOL bCond = FALSE;
PUCHAR Data = NULL, FileData = NULL;
ULONG FinalCompressedSize = 0, r = 0;
HANDLE hFile = INVALID_HANDLE_VALUE;
LPWSTR NewName = NULL;
SIZE_T sz = 0;
LARGE_INTEGER FileSize;
do {
if (lpInputFile == NULL)
break;
sz = _strlen(lpInputFile) * sizeof(WCHAR);
NewName = LocalAlloc(LPTR, sz);
if (NewName == NULL)
break;
hFile = CreateFile(lpInputFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
break;
FileSize.QuadPart = 0;
if (!GetFileSizeEx(hFile, &FileSize))
break;
if (FileSize.QuadPart == 0)
break;
FileData = LocalAlloc(LPTR, (SIZE_T)FileSize.LowPart);
if (FileData == NULL)
break;
if (!ReadFile(hFile, FileData, FileSize.LowPart, (LPDWORD)&r, NULL))
break;
Data = CompressBufferLZNT1((PUCHAR)FileData, r, &FinalCompressedSize);
if (Data) {
EncodeBuffer(Data, FinalCompressedSize);
if (_filename_noext(NewName, lpInputFile)) {
_strcat(NewName, TEXT(".cd"));
supWriteBufferToFile(NewName, Data, FinalCompressedSize);
}
VirtualFree(Data, 0, MEM_RELEASE);
}
} while (bCond);
if (NewName != NULL)
LocalFree(NewName);
if (FileData != NULL)
LocalFree(FileData);
if (hFile != INVALID_HANDLE_VALUE)
CloseHandle(hFile);
}
void main()
{
LPWSTR lpInputFile = NULL;
LPWSTR *szArglist;
INT nArgs = 0;
szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
if (szArglist) {
if (nArgs > 1) {
lpInputFile = szArglist[1];
if (nArgs > 2) {
g_XorKey = strtoul(szArglist[2]);
}
if (lpInputFile) {
CompressPayload(lpInputFile);
}
}
else {
MessageBox(GetDesktopWindow(), TEXT("Input file not specified"), TEXT("Naka"), MB_ICONINFORMATION);
}
LocalFree(szArglist);
}
ExitProcess(0);
}