micetools/src/micetools/miceboot/mxstartup.c

411 lines
12 KiB
C

#include <Windows.h>
#include <shellapi.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "ewfapi.h"
typedef enum {
MxError_Unknown = -1,
MxError_None = 0,
MxError_Ewf = 501,
MxError_Version = 502,
MxError_NoKeyFile = 503,
MxError_DiskAccessPrivilege = 504,
MxError_SystemMount = 505,
MxError_MxMaster = 507,
MxError_SBR = 511,
MxError_SysKeyDelete = 512,
} MxError_t;
typedef enum {
Init = 0,
CheckEwf = 1,
EwfDisabled = 2,
GetSBR = 3,
NormalBoot = 4,
SystemUpdate2 = 5,
SystemUpdate3 = 6,
Done = 7,
} StartupStep_t;
#define VERSION_BUFFER 256
#define VERSION_FILE "C:\\System\\SystemVersion.txt"
#define DEFAULT_VERSION_FILE "C:\\System\\DefaultSystemVersion.txt"
#define SYSTEM_KEY_FILE "Z:\\SystemKeyFile"
#define OS_UPDATE_KEY_FILE "Z:\\UpdateKeyFile"
#define SYSTEM_VOLUME "C:\\System\\Execute\\System"
#define SYSTEM_MOUNT "S:"
#define NEXT_HOP_CWD SYSTEM_MOUNT "\\"
#define NEXT_HOP_MXMASTER NEXT_HOP_CWD "mxmaster.exe"
#define CACLS_REMPERM_EXECUTE "cacls c:\\system\\execute /t /e /p AppUser:N"
#define CACLS_REMPERM_Z "cacls z:\\ /t /e /p appuser:N"
#define CACLS_REMPERM_S "cacls s:\\ /t /e /p appuser:N"
// Rather than implement these sums in code, we're just going to use the
// presummed versions, because we have nothing to gain by obfuscating this.
// These two sum to TC_PASSWORD
#define TC_PASSWORD_1 "3d550a335d2557055d2b3d1444153348"
#define TC_PASSWORD_2 "36105d2e0b3c1b5f1336365f335a3f1c"
#define TC_PASSWORD "segahardpassword"
// These two sum to SYSTEM_KEYFILE_ADS
#define SYSTEM_KEYFILE_1 "041443255b204a3f054d1b4c352a22292f211b29440e1237591f2e49375d093967614d"
#define SYSTEM_KEYFILE_2 "3f26192e1e532a26680f2a2c3039534b363b2923082c41421a5537241408700d020b18"
#define SYSTEM_KEYFILE_ADS "C:\\System\\Execute\\DLL:SystemKeyFile"
// These two sum to OS_UPDATE_ADS
#define OS_UPDATE_KEYFILE_1 "4019582c56283006300b40042110143d603b3d3b1d012b5c0d5423152235163f624a43"
#define OS_UPDATE_KEYFILE_2 "03210427234b445f3d51057444536137052107112f392a14570d515029306307072222"
#define OS_UPDATE_KEYFILE_ADS "C:\\System\\Execute\\DLL:UpdateKeyFile"
int LOG_EN_PLATFORM = 0;
#define MX_LOG(...) log(__FUNCTION__, __LINE__, __VA_ARGS__)
void log(char* function, unsigned int line_number, char* fmt, ...) {
va_list args;
va_start(args, fmt);
printf("%s: Line%d ", function, line_number);
vprintf(fmt, args);
va_end(args);
}
// TODO: These two
bool InitGraphics() { return true; }
bool PopulateEventInfo() { return true; }
// TODO: These three
void AppendAsterisk(void){};
void setStrForStep2(void){};
void setStrForStep3(void){};
int osuExecProcess(char* command) {
PROCESS_INFORMATION processInformation = { 0 };
STARTUPINFOA startupInfo = {
.cb = 68,
.dwFlags = STARTF_USESHOWWINDOW,
.wShowWindow = SW_HIDE,
};
if (command == NULL) return -150;
BOOL spanwed = CreateProcessA(NULL, command, NULL, NULL, 0, 0, NULL, NULL, &startupInfo, &processInformation);
DWORD wait = WaitForSingleObject(processInformation.hProcess, INFINITE);
int ret;
if (!spanwed) {
ret = -140;
} else if (wait == WAIT_OBJECT_0) {
DWORD exitCode;
GetExitCodeProcess(processInformation.hProcess, &exitCode);
ret = exitCode == 0 ? 0 : -141;
} else {
ret = -141;
}
CloseHandle(processInformation.hProcess);
CloseHandle(processInformation.hThread);
return ret;
}
/* Read a version from a text file */
bool GetVersionText(char* version, char* path) {
char buffer[VERSION_BUFFER];
FILE* file;
memset(buffer, 0, sizeof buffer);
if (fopen_s(&file, path, "r") || file == NULL) {
MX_LOG("Error : GetVersionText error path = %s\n", path);
return false;
}
fgets(buffer, sizeof buffer, file);
fclose(file);
strncpy_s(version, VERSION_BUFFER, buffer, VERSION_BUFFER);
return true;
}
/* Get the currently running version of the system */
bool GetCurrentVersion(char* version) { return GetVersionText(version, VERSION_FILE); }
/* Get the default version of the system */
bool GetDefaultVersion(char* version) { return GetVersionText(version, DEFAULT_VERSION_FILE); }
/* Mount the system volume */
bool MountSystemVolume(void) {
char command[256];
snprintf(command, sizeof command, "TrueCrypt /p %s /k %s /v %s /l %s /w /s /q", TC_PASSWORD, SYSTEM_KEY_FILE,
SYSTEM_VOLUME, SYSTEM_MOUNT);
int ret = osuExecProcess(command);
if (ret == 0) return true;
MX_LOG("Error : osuExecProcess error. ret = %d\n", ret);
return false;
};
/* Try to mount the system volume with up to 100 retries */
bool TryMountSystemVolume(void) {
for (int i = 0; i < 100; i++) {
if (MountSystemVolume()) return true;
Sleep(200);
}
return false;
}
/* Copies the file at src to dst */
bool GetKeyFile(LPCSTR src, LPCSTR dst) {
HANDLE file_1 = CreateFileA(src, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (file_1 == INVALID_HANDLE_VALUE) {
MX_LOG("CreaterFile Src error\n");
return false;
}
HANDLE file_2 = CreateFileA(dst, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_2 == INVALID_HANDLE_VALUE) {
CloseHandle(file_1);
MX_LOG("Error : CreateFile Dst error\n");
return false;
}
CHAR readBuffer[260];
DWORD bytesRead;
if (!ReadFile(file_1, readBuffer, 255, &bytesRead, NULL)) {
CloseHandle(file_1);
CloseHandle(file_2);
MX_LOG("Error : ReadFile error\n");
return false;
}
readBuffer[bytesRead] = '\0';
DWORD written;
bool ret = WriteFile(file_2, readBuffer, strlen(readBuffer), &written, NULL) != 0;
if (!ret) MX_LOG("Error : WriteFile error\n");
CloseHandle(file_1);
CloseHandle(file_2);
return ret;
}
bool GetSystemKeyFile() { return GetKeyFile(SYSTEM_KEYFILE_ADS, SYSTEM_KEY_FILE); };
bool GetOOUpdateKeyFile() { return GetKeyFile(OS_UPDATE_KEYFILE_ADS, OS_UPDATE_KEY_FILE); };
bool SetDiskAccessPrivilege() {
int i;
for (i = 0; i < 100; i++) {
if (osuExecProcess(CACLS_REMPERM_EXECUTE) != -140) break;
Sleep(200);
}
if (i == 100) {
MX_LOG("Error : osuExecProcess error\n");
return false;
}
for (i = 0; i < 100; i++) {
if (osuExecProcess(CACLS_REMPERM_Z) != -140) break;
Sleep(200);
}
if (i == 100) {
MX_LOG("Error : osuExecProcess error\n");
return false;
}
for (i = 0; i < 100; i++) {
if (osuExecProcess(CACLS_REMPERM_S) != -140) break;
Sleep(200);
}
if (i == 100) {
MX_LOG("Error : osuExecProcess error\n");
return false;
}
return true;
};
bool ExecuteMxMaster() {
HINSTANCE ret = ShellExecuteA(NULL, NULL, NEXT_HOP_MXMASTER, NULL, NEXT_HOP_CWD, 0);
if ((int)ret < 33) {
MX_LOG("Error : ShellExecute ret = %d\n", ret);
return false;
}
return true;
};
bool MxInitStartup(int* diskNumber) { return false; }
bool CheckEwfState(EWF_STATE* state) {
// TODO: Consider a better implementation of this!
*state = EWF_ENABLED; // Nothing to do, boot the system
// *state = EWF_DISABLED; // We're in the middle of an update, so finish
return true;
}
bool GetSBRSlotOSState(int diskNumber, int* updateState) { return false; };
bool SystemUpdateStep2(int diskNumber) { return false; }
bool SystemUpdateStep3(int diskNumber) { return false; }
MxError_t NormalBootStep(void) {
AppendAsterisk();
if (!GetSystemKeyFile()) return MxError_NoKeyFile;
AppendAsterisk();
if (!TryMountSystemVolume()) return MxError_SystemMount;
AppendAsterisk();
if (!DeleteFileA(SYSTEM_KEY_FILE)) return MxError_SysKeyDelete;
AppendAsterisk();
if (!SetDiskAccessPrivilege()) return MxError_DiskAccessPrivilege;
AppendAsterisk();
if (!ExecuteMxMaster()) return MxError_MxMaster;
return MxError_None;
}
int DoStartup() {
StartupStep_t step = Init;
MxError_t error = MxError_None;
int diskNumber = 0;
while (step != Done) {
printf("Step: %d (%d)\n", step, error);
switch (step) {
case Init:
if (!MxInitStartup(&diskNumber))
step = CheckEwf;
else
step = Done;
break;
case CheckEwf: {
AppendAsterisk();
EWF_STATE state;
if (!CheckEwfState(&state)) {
error = MxError_Ewf;
step = Done;
break;
}
if (state == EWF_ENABLED)
step = NormalBoot;
else
step = EwfDisabled;
break;
}
case EwfDisabled: {
char versionString[VERSION_BUFFER];
char defaultVersionString[VERSION_BUFFER];
if (!GetCurrentVersion(versionString) || !GetDefaultVersion(defaultVersionString)) {
error = MxError_Version;
step = Done;
break;
}
if (strcmp(versionString, defaultVersionString) == 0)
step = GetSBR;
else
step = SystemUpdate3;
break;
}
case GetSBR: {
int updateState;
AppendAsterisk();
if (!GetSBRSlotOSState(diskNumber, &updateState)) {
error = MxError_SBR;
step = Done;
break;
}
if (updateState == 2)
step = SystemUpdate2;
else
step = SystemUpdate3;
break;
}
case NormalBoot:
error = NormalBootStep();
step = Done;
break;
case SystemUpdate2:
setStrForStep2();
error = SystemUpdateStep2(diskNumber);
step = Done;
break;
case SystemUpdate3:
setStrForStep3();
error = SystemUpdateStep3(diskNumber);
step = Done;
break;
default:
error = MxError_Unknown;
step = Done;
break;
}
}
return error;
}
int setEventSource(char** source) {
// if (WIN_EVENT->ready == 0) {
// return -3;
// }
// if (source == (char**)0x0) {
// return -2;
// }
// _memcpy_s(&WIN_EVENT->eventSource, 16, source, 16);
return 0;
}
void setLogFn(void* log_fn) {
// LOG_FUN = log_fn;
return;
}
int __cdecl logToEventlog(LPCSTR msg) {
//
return 0;
}
bool ExitGraphics(void) {
// int iVar1;
// iVar1 = FUN_0040b9e0((int)&hInstance);
// return iVar1 != 0;
return true;
}
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
PVOID old = NULL;
Wow64DisableWow64FsRedirection(&old);
if (!InitGraphics(hInstance, nShowCmd)) {
MX_LOG("Error : InitGraphics failed.\n");
}
if (!PopulateEventInfo()) {
LOG_EN_PLATFORM = 1;
char* mxstartup = "mxstartup";
setEventSource(&mxstartup);
setLogFn(logToEventlog);
}
MxError_t err = DoStartup();
if (!err) {
if (!ExitGraphics()) {
MX_LOG("Error : ExitGraphics failed.\n");
}
// FUN_00408810();#
Sleep(1000000);
return 0;
}
printf("Fatal: %04d\n", err);
// while (1) {
// FUN_00424640();
// Sleep(100000);
//}
return 0;
}
int main() { return WinMain(NULL, NULL, NULL, 0); }