1
0
mirror of https://github.com/rbmm/SC synced 2026-06-08 17:03:41 +00:00
Files
rbmm 5a33221d8b *
2025-09-29 00:42:18 +03:00

976 lines
20 KiB
C++

#include "stdafx.h"
#include <conio.h>
#include "zip.h"
ULONG BOOL_TO_ERROR(BOOL f);
PSTR __fastcall strnchr(SIZE_T n1, const void* str1, char c);
volatile UCHAR guz;
bool gIsConsole = false;
HRESULT GetLastStatus(ULONG dwError = GetLastError())
{
NTSTATUS status = RtlGetLastNtStatus();
return RtlNtStatusToDosErrorNoTeb(status) == dwError ? HRESULT_FROM_NT(status) : HRESULT_FROM_WIN32(dwError);
}
void InitConsole(HWND hwnd)
{
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), 0);
ULONG dwProcessList[2];
if (GetConsoleProcessList(dwProcessList, RTL_NUMBER_OF(dwProcessList)) == 1)
{
NONCLIENTMETRICS ncm = { sizeof(NONCLIENTMETRICS) };
if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0))
{
CONSOLE_FONT_INFOEX cf = {
sizeof(cf), 0, { (SHORT)ncm.lfCaptionFont.lfWidth, -(SHORT)ncm.iMenuHeight},
FF_MODERN, FW_NORMAL, L"Lucida Console"
};
SetCurrentConsoleFontEx(hStdout, FALSE, &cf);
CONSOLE_SCREEN_BUFFER_INFOEX csbi = { sizeof(csbi) };
if (GetConsoleScreenBufferInfoEx(hStdout, &csbi))
{
csbi.dwSize = csbi.dwMaximumWindowSize = GetLargestConsoleWindowSize(hStdout);
csbi.wAttributes = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
csbi.dwCursorPosition.X = 0, csbi.dwCursorPosition.Y = 0;
csbi.srWindow.Left = 0, csbi.srWindow.Top = 0;
csbi.srWindow.Right = csbi.dwSize.X - 1, csbi.srWindow.Bottom = csbi.dwSize.Y - 1;
SetConsoleScreenBufferInfoEx(hStdout, &csbi);
SetConsoleWindowInfo(hStdout, TRUE, &csbi.srWindow);
}
}
SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOOWNERZORDER | SWP_NOSIZE);
}
}
void InitConsole()
{
if (HWND hwnd = GetConsoleWindow())
{
FILE_FS_DEVICE_INFORMATION ffdi;
IO_STATUS_BLOCK iosb;
if (gIsConsole = IsWindowVisible(hwnd) &&
0 <= NtQueryVolumeInformationFile(GetStdHandle(STD_OUTPUT_HANDLE),
&iosb, &ffdi, sizeof(ffdi), FileFsDeviceInformation) &&
ffdi.DeviceType == FILE_DEVICE_CONSOLE &&
0 <= NtQueryVolumeInformationFile(GetStdHandle(STD_INPUT_HANDLE),
&iosb, &ffdi, sizeof(ffdi), FileFsDeviceInformation) &&
ffdi.DeviceType == FILE_DEVICE_CONSOLE)
{
InitConsole(hwnd);
}
}
}
void cprintf(ULONG nStdHandle, PCWSTR pwz, ULONG len = 0)
{
if (!len) len = (ULONG)wcslen(pwz);
HANDLE hOut = GetStdHandle(nStdHandle);
if (gIsConsole)
{
WriteConsoleW(hOut, pwz, len, &len, 0);
return;
}
UINT cp = nStdHandle == STD_ERROR_HANDLE ? GetConsoleOutputCP() : CP_UTF8;
if (ULONG cb = WideCharToMultiByte(cp, 0, pwz, len, 0, 0, 0, 0))
{
if (PSTR psz = (PSTR)_malloca(cb))
{
if (cb = WideCharToMultiByte(cp, 0, pwz, len, psz, cb, 0, 0))
{
WriteFile(hOut, psz, cb, &cb, 0);
}
_freea(psz);
}
}
}
void cprintf(PCWSTR pwz, ULONG len = 0)
{
cprintf(STD_ERROR_HANDLE, pwz, len);
}
void vprintf(ULONG nStdHandle, PCWSTR format, va_list args)
{
int len = _vscwprintf(format, args);
if (0 < len)
{
if (PWSTR pwz = (PWSTR)_malloca((len + 1) * sizeof(WCHAR)))
{
if (0 < (len = _vsnwprintf_s(pwz, len + 1, _TRUNCATE, format, args)))
{
cprintf(nStdHandle, pwz, len);
}
_freea(pwz);
}
}
}
void printf(ULONG nStdHandle, PCWSTR format, ...)
{
va_list args;
va_start(args, format);
vprintf(nStdHandle, format, args);
va_end(args);
}
void printf(PCWSTR format, ...)
{
va_list args;
va_start(args, format);
vprintf(STD_ERROR_HANDLE, format, args);
va_end(args);
}
void fprintf(PCWSTR format, ...)
{
va_list args;
va_start(args, format);
vprintf(STD_OUTPUT_HANDLE, format, args);
va_end(args);
}
void printf(HRESULT hr)
{
printf(STD_ERROR_HANDLE, L"// %x\n", hr & ~FACILITY_NT_BIT);
PWSTR psz;
HMODULE hmod = 0;
ULONG Flags = FORMAT_MESSAGE_IGNORE_INSERTS| FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM;
if (hr & FACILITY_NT_BIT)
{
Flags = FORMAT_MESSAGE_IGNORE_INSERTS| FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE;
hr &= ~FACILITY_NT_BIT;
hmod = GetModuleHandle(L"ntdll");
}
ULONG r = FormatMessage(Flags, hmod, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (PWSTR)&psz, 0, NULL);
if (r)
{
cprintf(STD_ERROR_HANDLE, psz, r);
LocalFree(psz);
}
}
void printf_status(NTSTATUS status)
{
printf(HRESULT_FROM_NT(status));
}
struct NtNameFromWin32 : public UNICODE_STRING
{
NtNameFromWin32()
{
Buffer = 0, Length = 0, MaximumLength = 0;
}
~NtNameFromWin32()
{
RtlFreeUnicodeString(this);
}
NTSTATUS Set(PCWSTR DosFileName, PWSTR * FileName = 0)
{
RtlFreeUnicodeString(this);
return RtlDosPathNameToNtPathName_U_WithStatus(DosFileName, this, FileName, 0);
}
};
NTSTATUS CreateNewFile(PHANDLE FileHandle, POBJECT_ATTRIBUTES poa)
{
IO_STATUS_BLOCK iosb;
return NtCreateFile(FileHandle, FILE_APPEND_DATA|SYNCHRONIZE, poa, &iosb, 0,
FILE_ATTRIBUTE_NORMAL, 0, FILE_CREATE, FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT, 0, 0);
}
NTSTATUS CreateFileFromData(POBJECT_ATTRIBUTES poa, PVOID pv, ULONG cb)
{
HANDLE hFile;
IO_STATUS_BLOCK iosb;
NTSTATUS status;
if (0 <= (status = CreateNewFile(&hFile, poa)))
{
if (cb)
{
status = NtWriteFile(hFile, 0, 0, 0, &iosb, pv, cb, 0, 0);
}
NtClose(hFile);
}
return status;
}
NTSTATUS SaveF(const void* pv, ULONG cb, HANDLE hRoot, PCWSTR pszFileName)
{
HANDLE hFile;
IO_STATUS_BLOCK iosb;
UNICODE_STRING ObjectName;
OBJECT_ATTRIBUTES oa = { sizeof(oa), hRoot, &ObjectName, OBJ_CASE_INSENSITIVE };
LARGE_INTEGER AllocationSize = { cb };
RtlInitUnicodeString(&ObjectName, pszFileName);
NTSTATUS status = NtCreateFile(&hFile, FILE_APPEND_DATA | SYNCHRONIZE, &oa, &iosb, &AllocationSize,
0, 0, FILE_OVERWRITE_IF, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, 0, 0);
if (0 <= status)
{
status = cb ? NtWriteFile(hFile, 0, 0, 0, &iosb, const_cast<void*>(pv), cb, 0, 0) : STATUS_SUCCESS;
NtClose(hFile);
}
return status;
}
NTSTATUS SaveToFile(_In_ PCWSTR lpFileName, _In_ const void* lpBuffer, _In_ ULONG nNumberOfBytesToWrite)
{
UNICODE_STRING ObjectName;
NTSTATUS status = RtlDosPathNameToNtPathName_U_WithStatus(lpFileName, &ObjectName, 0, 0);
DbgPrint("DosPathNameToNt(\"%ws\") = %x\r\n", lpFileName, status);
if (0 <= status)
{
HANDLE hFile;
IO_STATUS_BLOCK iosb;
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName, OBJ_CASE_INSENSITIVE };
LARGE_INTEGER AllocationSize = { nNumberOfBytesToWrite };
status = NtCreateFile(&hFile, FILE_APPEND_DATA | SYNCHRONIZE, &oa, &iosb, &AllocationSize,
0, 0, FILE_OVERWRITE_IF, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, 0, 0);
DbgPrint("CreateFile(\"%wZ\") = %x\r\n", &ObjectName, status);
RtlFreeUnicodeString(&ObjectName);
if (0 <= status)
{
status = NtWriteFile(hFile, 0, 0, 0, &iosb, const_cast<void*>(lpBuffer), nNumberOfBytesToWrite, 0, 0);
NtClose(hFile);
DbgPrint("WriteFile(%x) = %x\r\n", nNumberOfBytesToWrite, status);
}
}
return status;
}
NTSTATUS CreateRoot(_Out_ PHANDLE FileHandle, _In_ PCWSTR lpFileName)
{
UNICODE_STRING ObjectName;
NTSTATUS status = RtlDosPathNameToNtPathName_U_WithStatus(lpFileName, &ObjectName, 0, 0);
if (0 <= status)
{
IO_STATUS_BLOCK iosb;
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName, OBJ_CASE_INSENSITIVE };
status = NtCreateFile(FileHandle, FILE_ADD_FILE | SYNCHRONIZE, &oa, &iosb, 0,
FILE_ATTRIBUTE_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE, 0, 0);
RtlFreeUnicodeString(&ObjectName);
}
return status;
}
HRESULT DropVcxProj(ULONG t,
void* pv,
ULONG cb,
PCSTR pcszTargetName,
HANDLE hRoot,
PCWSTR pszFileName,
void** ppv,
ULONG* pcb)
{
GUID guid;
if (HRESULT hr = BCryptGenRandom(0, (PBYTE)&guid, sizeof(guid), BCRYPT_USE_SYSTEM_PREFERRED_RNG))
{
return hr;
}
char szGuid[39];
int i = sprintf_s(szGuid, _countof(szGuid), "{%08X-%04x-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
if (0 < i)
{
PCSTR aa[] = { pcszTargetName, szGuid, pcszTargetName };
ULONG l = (ULONG)strlen(pcszTargetName);
ULONG len[] = { l, (ULONG)i, l };
if (PSTR buf = new char[cb + 2*l + i])
{
PSTR psz = buf;
while (PSTR pc = strnchr(cb, pv, '^'))
{
l = RtlPointerToOffset(pv, pc);
cb -= l;
memcpy(psz, pv, l - 1);
pv = pc, psz += l - 1;
if (!t--)
{
*ppv = pv, * pcb = cb;
return SaveF(buf, RtlPointerToOffset(buf, psz), hRoot, pszFileName);
}
memcpy(psz, aa[t], l = len[t]);
psz += l;
}
delete[] buf;
}
}
return HRESULT_FROM_NT(STATUS_INTERNAL_ERROR);
}
HRESULT DropFoU(void* pv,
ULONG cb,
HANDLE hRoot,
PCWSTR pszFileName,
void** ppv,
ULONG* pcb)
{
if (PSTR pc = strnchr(cb, pv, '^'))
{
ULONG l = RtlPointerToOffset(pv, pc);
*ppv = pc, * pcb = cb - l;
return SaveF(pv, l - 1, hRoot, pszFileName);
}
return HRESULT_FROM_NT(STATUS_INTERNAL_ERROR);
}
extern const CHAR sc_vcxproj_begin[], sc_vcxproj_end[];
HRESULT NewVcxProj(PCWSTR pszProjectName)
{
HANDLE hFolder;
static const UNICODE_STRING CharSet = RTL_CONSTANT_STRING(L"\\/");
UNICODE_STRING str;
RtlInitUnicodeString(&str, pszProjectName);
USHORT np;
if (0 <= RtlFindCharInUnicodeString(RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END, &str, &CharSet, &np))
{
np += sizeof(WCHAR);
(PBYTE&)str.Buffer += np;
str.Length -= np, str.MaximumLength -= np;
}
PSTR Target = 0;
ULONG cch = 0;
ULONG len = str.Length / sizeof(WCHAR);
while (cch = WideCharToMultiByte(CP_UTF8, 0, str.Buffer, len, Target, cch, 0, 0))
{
if (Target)
{
Target[cch] = 0;
PWSTR buf = (PWSTR)alloca(len = str.Length + 32 * sizeof(WCHAR));
len /= sizeof(WCHAR);
int i = swprintf_s(buf, len, L"%wZ", &str);
if (0 < i)
{
PWSTR psz = buf + i;
HRESULT hr = CreateRoot(&hFolder, pszProjectName);
printf(L"Create(\"%ws\")=%x\r\n", buf, hr);
if (0 <= hr)
{
PVOID pv = const_cast<char*>(sc_vcxproj_begin);
ULONG cb = RtlPointerToOffset(sc_vcxproj_begin, sc_vcxproj_end);
if (S_OK == (hr = Unzip(pv, cb, &pv, &cb)))
{
PVOID Buf = pv;
wcscpy(psz, L".vcxproj");
psz += _countof(".vcxproj") - 1;
if (S_OK == (hr = DropVcxProj(2, pv, cb, Target, hFolder, buf, &pv, &cb)))
{
*psz++ = '.';
static const PCWSTR sc[] = {
L"imp.x86.asm",
L"imp.x64.asm",
L"x86.asm",
L"x64.asm",
L"ep.cpp",
L"stdafx.cpp",
L"stdafx.h",
L"user",
L"filters"
};
i = _countof(sc);
do
{
if (_countof(sc) - 2 == i)
{
psz = buf;
}
wcscpy(psz, sc[--i]);
if (hr = DropFoU(pv, cb, hFolder, buf, &pv, &cb))
{
break;
}
} while (i);
}
LocalFree(Buf);
}
NtClose(hFolder);
}
return hr;
}
break;
}
Target = (PSTR)alloca(cch + 1);
}
return E_FAIL;
}
NTSTATUS I_SaveAsAsm(PCWSTR pwzFileName, const void* pcv, SIZE_T cb)
{
NTSTATUS status;
union {
const void* pv;
PULONG64 pu64;
PULONG pu;
PUSHORT ps;
PUCHAR pb;
};
pv = pcv;
SIZE_T n = cb >> 3;
SIZE_T cch = n * (7 + 16) + 36;
// DD 0ABCDEF78h.. ; 7+8
// DW 0ABCDh.. ; 7+4
// DB 0ABh.. ; 7+2
if (PSTR buf = new char [cch])
{
status = STATUS_INTERNAL_ERROR;
int len;
ULONG s = 4;
PSTR psz = buf;
if (n)
{
cb -= n << 3;
do
{
if (0 >= (len = sprintf_s(psz, cch, "DQ 0%016I64xh\r\n", *pu64++)))
{
goto __exit;
}
} while (psz += len, cch -= len, --n);
}
static const PCSTR fmt[] = { "DB 0%02xh\r\n", "DW 0%04xh\r\n", "DD 0%08xh\r\n" };
n = _countof(fmt) - 1;
do
{
if (s <= cb)
{
cb -= s;
if (0 >= (len = sprintf_s(psz, cch, fmt[n], *pu & ((1ULL << (s << 3)) - 1))))
{
goto __exit;
}
psz += len, cch -= len, pb += s;
}
} while (s >>= 1, n--);
status = SaveToFile(pwzFileName, buf, RtlPointerToOffset(buf, psz));
__exit:
delete[] buf;
printf(L"SaveAsAsm(%ws)=%x\r\n", pwzFileName, status);
return status;
}
return STATUS_NO_MEMORY;
}
//## -> #
//#. -> *
//#: -> %
BOOL UnEscape(_Inout_ PWSTR str)
{
PWSTR buf = str;
WCHAR c;
do
{
if ('#' == (c = *str++))
{
switch (c = *str++)
{
case '.':
c = '*';
break;
case ':':
c = '%';
break;
case '#':
break;
default:
return FALSE;
}
}
*buf++ = c;
} while (c);
return TRUE;
}
NTSTATUS CreateAesKey(_Out_ BCRYPT_KEY_HANDLE* phKey, _In_ PBYTE secret, _In_ ULONG cb)
{
NTSTATUS status;
BCRYPT_ALG_HANDLE hAlgorithm;
if (0 <= (status = BCryptOpenAlgorithmProvider(&hAlgorithm, BCRYPT_AES_ALGORITHM, 0, 0)))
{
status = BCryptGenerateSymmetricKey(hAlgorithm, phKey, 0, 0, secret, cb, 0);
BCryptCloseAlgorithmProvider(hAlgorithm, 0);
}
return status;
}
NTSTATUS SaveAsAsm(PCWSTR pwzFileName, const void* pcv, SIZE_T cb)
{
if (PWSTR psz = wcsrchr(pwzFileName, '?'))
{
*psz++ = 0;
//while (!IsDebuggerPresent()) Sleep(100); __debugbreak();
if (!UnEscape(const_cast<PWSTR>(pwzFileName)))
{
return STATUS_BAD_DATA;
}
printf(L"password: \"%ws\"\r\n", pwzFileName);
ULONG len = RtlPointerToOffset(pwzFileName, psz);
NTSTATUS status = RtlUnicodeToUTF8N((char*)pwzFileName, len, &len, pwzFileName, len);
if (0 > status)
{
return status;
}
BCRYPT_KEY_HANDLE hKey;
UCHAR secret[32];
ULONG s = sizeof(secret);
if (CryptHashCertificate2(BCRYPT_SHA256_ALGORITHM, 0, 0, (PBYTE)pwzFileName, len, secret, &s))
{
if (0 <= (status = CreateAesKey(&hKey, secret, s)))
{
PBYTE pb = 0;
s = 0;
while (0 <= (status = BCryptEncrypt(hKey, (PBYTE)pcv, cb, 0, 0, 0, pb, s, &s, BCRYPT_BLOCK_PADDING)))
{
if (pb)
{
printf(L"Encrypt: %x -> %x\r\n", cb, s);
status = I_SaveAsAsm(psz, pb, s);
break;
}
if (!(pb = new UCHAR[s]))
{
status = STATUS_NO_MEMORY;
break;
}
}
if (pb)
{
delete[] pb;
}
BCryptDestroyKey(hKey);
}
return status;
}
return GetLastError();
}
return I_SaveAsAsm(pwzFileName, pcv, cb);
}
NTSTATUS ZipAndSaveAsAsm(PCWSTR pwzFileName, const void* pv, SIZE_T cb)
{
COMPRESSOR_HANDLE CompressorHandle;
if (CreateCompressor(COMPRESS_ALGORITHM_MSZIP, 0, &CompressorHandle))
{
ULONG dwError;
SIZE_T CompressedDataSize;
switch (dwError = BOOL_TO_ERROR(Compress(CompressorHandle, 0, cb, 0, 0, &CompressedDataSize)))
{
case NOERROR:
case ERROR_INSUFFICIENT_BUFFER:
if (PBYTE pb = new BYTE[CompressedDataSize])
{
if (Compress(CompressorHandle, pv, cb, pb, CompressedDataSize, &CompressedDataSize))
{
printf(L"Compress:%x >> %x [%u%%]\r\n", cb, CompressedDataSize, (CompressedDataSize*100)/cb);
dwError = SaveAsAsm(pwzFileName, pb, CompressedDataSize);
}
else
{
dwError = GetLastError();
}
delete [] pb;
}
break;
}
CloseCompressor(CompressorHandle);
return HRESULT_FROM_WIN32(dwError);
}
return HRESULT_FROM_WIN32(GetLastError());
}
#define FILE_SHARE_VALID_FLAGS 7
NTSTATUS ToZipAsm(PCWSTR from, PCWSTR to, bool _text, bool bZip)
{
printf(L"ToAsm(\"%ws\", \"%ws\", %u)\n", from, to, _text);
NtNameFromWin32 ObjectName;
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName, OBJ_CASE_INSENSITIVE };
NTSTATUS status = ObjectName.Set(from);
HANDLE hFile = 0, hSection = 0;
IO_STATUS_BLOCK iosb;
if (0 > status)
{
printf(L"convert <%s> = %x\n", from, status);
}
else
{
status = NtOpenFile(&hFile, FILE_GENERIC_READ, &oa, &iosb,
FILE_SHARE_VALID_FLAGS, FILE_SYNCHRONOUS_IO_NONALERT);
printf(L"OpenFile(%wZ) = %x\n", static_cast<PCUNICODE_STRING>(&ObjectName), status);
}
if (0 <= status)
{
FILE_STANDARD_INFORMATION fsi;
if (0 <= (status = NtQueryInformationFile(hFile, &iosb, &fsi, sizeof(fsi), FileStandardInformation)))
{
printf(L"File Size = %I64x\n", fsi.EndOfFile.QuadPart);
if (fsi.EndOfFile.LowPart - 1 < 0x1000000 && !fsi.EndOfFile.HighPart) // < 16mb
{
status = ZwCreateSection(&hSection, SECTION_ALL_ACCESS, 0, 0, PAGE_READONLY, SEC_COMMIT, hFile);
}
else
{
status = STATUS_EA_TOO_LARGE;
}
}
NtClose(hFile);
if (0 <= status)
{
void* BaseAddress=0;
SIZE_T ViewSize = 0;
status = ZwMapViewOfSection(hSection, NtCurrentProcess(), &BaseAddress,
0, 0, 0, &ViewSize, ViewUnmap, 0, PAGE_READONLY);
NtClose(hSection);
if (0 <= status)
{
union {
PLONGLONG pl;
PVOID pv;
PBYTE pb;
};
pv = BaseAddress;
if (_text)
{
status = STATUS_INVALID_IMAGE_FORMAT;
__try
{
if (PIMAGE_NT_HEADERS pinth = RtlImageNtHeader(BaseAddress))
{
if (pinth->FileHeader.NumberOfSections)
{
PIMAGE_SECTION_HEADER pish = IMAGE_FIRST_SECTION(pinth);
ULONG PointerToRawData = pish->PointerToRawData, SizeOfRawData = pish->SizeOfRawData;
if (PointerToRawData < ViewSize &&
PointerToRawData + SizeOfRawData <= ViewSize &&
PointerToRawData < PointerToRawData + SizeOfRawData)
{
pb += PointerToRawData;
fsi.EndOfFile.QuadPart = SizeOfRawData;
status = STATUS_SUCCESS;
printf(L".text(ofs=%x, size=%x)\n", PointerToRawData, SizeOfRawData);
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
status = GetExceptionCode();
}
}
if (0 <= status)
{
status = (bZip ? ZipAndSaveAsAsm : SaveAsAsm)(to, pv, fsi.EndOfFile.LowPart);
}
ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
}
}
}
return status;
}
NTSTATUS SetPETime(PCWSTR lpFileName, PCWSTR time)
{
printf(L"SetPETime(%ws, %ws)\r\n", lpFileName, time);
ULONG TimeDateStamp = wcstoul(time, const_cast<WCHAR**>(&time), 16);
if (!TimeDateStamp || *time)
{
return STATUS_INVALID_PARAMETER_2;
}
NtNameFromWin32 ObjectName;
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName, OBJ_CASE_INSENSITIVE };
NTSTATUS status = ObjectName.Set(lpFileName);
HANDLE hFile = 0;
IO_STATUS_BLOCK iosb;
if (0 > status)
{
printf(L"convert <%s> = %x\r\n", lpFileName, status);
}
else
{
status = NtOpenFile(&hFile, FILE_GENERIC_READ | FILE_WRITE_DATA, &oa, &iosb,
FILE_SHARE_VALID_FLAGS, FILE_SYNCHRONOUS_IO_NONALERT);
printf(L"OpenFile(%wZ) = %x\r\n", static_cast<PCUNICODE_STRING>(&ObjectName), status);
}
if (0 <= status)
{
union {
IMAGE_DOS_HEADER idh;
IMAGE_NT_HEADERS inh;
};
if (0 <= (status = NtReadFile(hFile, 0, 0, 0, &iosb, &idh, sizeof(idh), 0, 0)))
{
if (IMAGE_DOS_SIGNATURE == idh.e_magic)
{
LARGE_INTEGER bo = { (ULONG)idh.e_lfanew };
if (0 <= (status = NtReadFile(hFile, 0, 0, 0, &iosb, &inh, sizeof(inh), &bo, 0)))
{
if (IMAGE_NT_SIGNATURE == inh.Signature)
{
ULONG t = inh.FileHeader.TimeDateStamp;
inh.FileHeader.TimeDateStamp = TimeDateStamp;
status = NtWriteFile(hFile, 0, 0, 0, &iosb, &inh, sizeof(inh), &bo, 0);
printf(L"TimeDateStamp: %08X <- %08X =[%x]\r\n", t, TimeDateStamp, status);
}
else
{
status = STATUS_INVALID_IMAGE_FORMAT;
}
}
}
else
{
status = STATUS_INVALID_IMAGE_NOT_MZ;
}
}
NtClose(hFile);
}
return status;
}
void WINAPI ep(void*)
{
InitConsole();
HRESULT exitcode = HRESULT_FROM_NT(STATUS_INVALID_PARAMETER);
BOOL bWait = TRUE;
PVOID ov;
Wow64DisableWow64FsRedirection(&ov);
PVOID stack = alloca(guz);
PWSTR* argv = (PWSTR*)stack, lpsz = GetCommandLineW(), c = wcsrchr(lpsz, '\"');
if (c && !c[1]) *c=0;
cprintf(lpsz);
cprintf(L"\n");
int argc = 0;
while (lpsz = wcschr(lpsz, L'*'))
{
*lpsz++ = 0;
if (--argv < stack) stack = alloca(sizeof(PVOID));
*argv = lpsz, argc++;
}
while (argc--)
{
lpsz = *argv++;
if (!wcscmp(lpsz, L"nowait"))
{
bWait = FALSE;
continue;
}
exitcode = HRESULT_FROM_NT(STATUS_INVALID_PARAMETER);
if (!wcscmp(lpsz, L"toasm"))
{
if (argc >= 2)
{
bool _text = (argc -= 2) && !wcscmp(argv[2], L".text");
exitcode = HRESULT_FROM_NT(ToZipAsm(argv[0], argv[1], _text, FALSE)), argv += 2 + _text, argc -= _text;
}
}
else if (!wcscmp(lpsz, L"tozasm"))
{
if (argc >= 2)
{
bool _text = (argc -= 2) && !wcscmp(argv[2], L".text");
exitcode = HRESULT_FROM_NT(ToZipAsm(argv[0], argv[1], _text, TRUE)), argv += 2 + _text, argc -= _text;
}
}
else if (!wcscmp(lpsz, L"vcp"))
{
if (argc)
{
exitcode = HRESULT_FROM_NT(NewVcxProj(argv[0]));
argc--, argv++;
}
}
else if (!wcscmp(lpsz, L"ts"))
{
if (1 < argc)
{
exitcode = SetPETime(argv[0], argv[1]);
argc -= 2, argv += 2;
}
}
if (exitcode & ~FACILITY_NT_BIT) break;
}
printf(exitcode);
if (bWait)
{
if (gIsConsole)
{
cprintf(L"press any key...\n");
_getch();
}
}
ExitProcess(exitcode & ~FACILITY_NT_BIT);
}