Fix child process spawning

This commit is contained in:
Bottersnike 2023-03-30 16:15:59 +01:00
parent b015c0cce4
commit 800b6f28e1
Signed by: Bottersnike
SSH Key Fingerprint: SHA256:3g0ghwd4dNX1k1RX8qazbiT+3RIYn/daeBevHZVCiU0
14 changed files with 80 additions and 114 deletions

View File

@ -1,5 +1,6 @@
#include <signal.h>
#include "../lib/util/pid.h"
#include "common.h"
#include "devices/_devices.h"
#include "drivers/mx.h"
@ -112,7 +113,7 @@ void init_injection(HMODULE hModule) {
load_mice_config();
// We're in a new context now, so need to reconfigure
setup_logging(GetParentProcessId());
setup_logging();
log_info(plfBoot, "Handover complete. Now executing within %ls", exeName);
init_com_devices();

View File

@ -453,7 +453,7 @@ DWORD __stdcall mxjvs_comdev_thread(com_device_t* com) {
nbytes--;
}
short packetSize = bufferPtr - inBuffer;
short packetSize = (bufferPtr - inBuffer) & 0xFFFF;
mxjvs_handle(inBuffer, packetSize, outBuffer, _countof(outBuffer), &bytesReturned);
com->modemStatus = !JVS_SENSE ? MS_DSR_ON : 0;
comdev_write(com, outBuffer, bytesReturned & 0xFFFF);

View File

@ -21,21 +21,8 @@ BOOL WINAPI FakeCreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine,
log_info(plfProcesses, "CreateProcessA %s %s", lpApplicationName, lpCommandLine);
// return TrueCreateProcessA("mxAuthDisc.bat", "", lpProcessAttributes, lpThreadAttributes,
// bInheritHandles, dwCreationFlags, lpEnvironment,
// lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
// HANDLE fake_evt = CreateEvent(NULL, TRUE, FALSE, NULL);
// SetEvent(fake_evt);
HANDLE hProcess = start_and_inject(INVALID_HANDLE_VALUE, lpApplicationName, lpCommandLine,
MICELIB, FALSE, 0, "", 0);
if (lpProcessInformation) {
lpProcessInformation->hProcess = hProcess;
}
return TRUE;
return start_and_inject(INVALID_HANDLE_VALUE, lpApplicationName, lpCommandLine,
MICELIB, FALSE, 0, NULL, 0, lpProcessInformation);
}
BOOL WINAPI FakeCreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
@ -53,62 +40,8 @@ BOOL WINAPI FakeCreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
LPSTR commandLine = malloc(nMultiChars);
WideCharToMultiByte(CP_ACP, 0, lpCommandLine, -1, commandLine, nMultiChars, NULL, NULL);
// WideCharToMultiByte(CP_ACP, 0, lpApplicationName, -1, applicationName, sizeof
// applicationName,
// NULL, NULL);
// HANDLE child;
// CHAR commandLine[MAX_PATH + 1];
// WCHAR commandLineW[MAX_PATH + 1];
// WCHAR micePathW[MAX_PATH + 1];
// GetModuleFileNameW(NULL, micePathW, MAX_PATH);
// HANDLE fake_evt = CreateEvent(NULL, TRUE, FALSE, NULL);
// SetEvent(fake_evt);
// return TrueCreateProcessA(applicationName, commandLine, lpProcessAttributes, lpThreadAttributes,
// bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory,
// lpStartupInfo, lpProcessInformation);
HANDLE hProcess = start_and_inject(INVALID_HANDLE_VALUE, applicationName, commandLine, MICELIB,
TRUE, 0, NULL, 0);
if (lpProcessInformation) {
lpProcessInformation->hProcess = hProcess;
lpProcessInformation->hThread = GetDummyHandle();
}
log_game(plfProcesses, "hP: %08x", hProcess);
return TRUE;
// if (lpCommandLine != NULL) {
// log_error(plfProcesses, "!!");
// return FALSE;
// // WideCharToMultiByte(CP_ACP, 0, lpCommandLine, -1, commandLine, sizeof commandLine,
// NULL,
// // NULL);
// // child = start_and_inject(INVALID_HANDLE_VALUE, applicationName, commandLine, MICELIB,
// // false, 0, NULL,
// // CREATE_NEW_CONSOLE);
// } else {
// dwCreationFlags |= CREATE_NEW_CONSOLE;
// wsprintfW(commandLineW, L"mice -b %ls", lpApplicationName);
// printf("%ls %ls\n", micePathW, commandLineW);
// BOOL ret =
// TrueCreateProcessW(L"mice.cmd", commandLineW, lpProcessAttributes,
// lpThreadAttributes,
// bInheritHandles, dwCreationFlags, lpEnvironment,
// lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
// printf("%d\n", ret);
// return ret;
// // CHAR commandLine[]
// // child =
// // start_and_inject(INVALID_HANDLE_VALUE, applicationName, NULL, MICELIB, false, 0,
// // NULL, CREATE_NEW_CONSOLE);
// }
// return !FAILED(child);
// // #endif
return start_and_inject(INVALID_HANDLE_VALUE, applicationName, commandLine, MICELIB,
FALSE, 0, NULL, 0, lpProcessInformation);
}
BOOL WINAPI FakeGetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode) {

View File

@ -13,7 +13,6 @@ BOOL RemoveDataForHandle(HANDLE hObject, DWORD type);
HANDLE GetDummyHandle();
void BytesToHex(char* hex_buffer, BYTE* bytes, DWORD nbytes);
void PrintStack(void);
DWORD GetParentProcessId(void);
BOOL PathEqual(LPCSTR path1, LPCSTR path2);
BOOL PathPrefix(LPCSTR path, LPCSTR prefix);

View File

@ -1,7 +1,6 @@
#define _WIN32_WINNT 0x0600
#include <Windows.h>
#include <dbghelp.h>
#include <tlhelp32.h>
#include "../hooks/files.h"
@ -186,23 +185,3 @@ void* open_mapped_file(LPCWSTR path, DWORD size, HANDLE* file, HANDLE* file_mapp
}
return mapping;
}
DWORD GetParentProcessIdFor(DWORD pid) {
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe = { 0 };
pe.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(h, &pe)) {
do {
if (pe.th32ProcessID == pid) {
CloseHandle(h);
return pe.th32ParentProcessID;
}
} while (Process32Next(h, &pe));
}
CloseHandle(h);
return (DWORD)-1;
}
DWORD GetParentProcessId(void) {
return GetParentProcessIdFor(GetCurrentProcessId());
}

View File

@ -2,6 +2,7 @@
#include <stdio.h>
#include "../lib/mice/mice.h"
#include "../lib/util/pid.h"
#include "locate.h"
#include "spawn.h"
@ -112,7 +113,7 @@ static DWORD WINAPI MiceMailslotWatcher(HANDLE* pSlot) {
if (hLogFile != INVALID_HANDLE_VALUE) {
// The only VT100 sequences being used are colours, so this lazy approach works
BOOL inVt100 = FALSE;
for (int i = 0; i < nBytes; i++) {
for (unsigned int i = 0; i < nBytes; i++) {
if (readBuffer[i] == '\033') {
inVt100 = TRUE;
continue;
@ -162,17 +163,16 @@ static int terminate(int err) {
return err;
}
HANDLE hGameProc = INVALID_HANDLE_VALUE;
HANDLE hJob = INVALID_HANDLE_VALUE;
BOOL WINAPI MiceHandlerRoutine(DWORD CtrlType) {
if (hJob != INVALID_HANDLE_VALUE) CloseHandle(hJob);
// if (hGameProc != INVALID_HANDLE_VALUE) TerminateProcess(hGameProc, 0);
ExitProcess(terminate(0));
}
int main(int argc, char* argv[]) {
load_mice_config();
if (!setup_mailslot()) return 1;
setup_logging(GetCurrentProcessId());
setup_logging();
log_info(plfBoot, "Micetools version: %s", MICE_VERSION);
@ -217,17 +217,18 @@ int main(int argc, char* argv[]) {
SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &info, sizeof info);
char* extra_injections = MiceConfig.launcher.inject;
hGameProc = start_and_inject(hJob, exe_name, commandline, micepath, debug_wait, boot_delay,
extra_injections, 0);
if (!hGameProc) return terminate(-1);
PROCESS_INFORMATION pi;
if (!start_and_inject(hJob, exe_name, commandline, micepath, debug_wait, boot_delay,
extra_injections, 0, &pi))
return terminate(-1);
SetConsoleCtrlHandler(MiceHandlerRoutine, TRUE);
if (FAILED(WaitForSingleObject(hGameProc, INFINITE))) {
if (FAILED(WaitForSingleObject(pi.hProcess, INFINITE))) {
log_error(plfBoot, "Fatal: WaitForSingleObject failed: %03x", GetLastError());
} else {
log_info(plfBoot, "Shutting down");
CloseHandle(hGameProc);
CloseHandle(pi.hProcess);
}
return terminate(0);
}

View File

@ -11,6 +11,7 @@ executable(
link_with: [
mice_lib,
mxklib,
util_lib,
# Madoka service emulation
mxk,

View File

@ -73,8 +73,9 @@ bool inject_dll(HANDLE process, LPCSTR inject) {
return remote_call(process, addr_LoadLibraryA, inject, &result);
}
HANDLE start_and_inject(HANDLE hJob, LPCSTR path, LPSTR cmdline, LPCSTR inject, BOOL debug_wait,
DWORD delay, LPCSTR extra_injections, DWORD flags) {
BOOL start_and_inject(HANDLE hJob, LPCSTR path, LPSTR cmdline, LPCSTR inject, BOOL debug_wait,
DWORD delay, LPCSTR extra_injections, DWORD flags,
LPPROCESS_INFORMATION lpProcessInformation) {
STARTUPINFOA startupInfo;
PROCESS_INFORMATION processInformation = { 0 };
@ -143,7 +144,11 @@ HANDLE start_and_inject(HANDLE hJob, LPCSTR path, LPSTR cmdline, LPCSTR inject,
goto abort;
}
return processInformation.hProcess;
if (lpProcessInformation) {
memcpy(lpProcessInformation, &processInformation, sizeof processInformation);
}
return TRUE;
abort:
if (processInformation.hProcess && processInformation.hProcess != INVALID_HANDLE_VALUE) {
@ -158,5 +163,5 @@ abort:
log_error(plfProcesses, "Fatal: CloseHandle(hThread) failed: %d", GetLastError());
}
return INVALID_HANDLE_VALUE;
return FALSE;
}

View File

@ -2,7 +2,7 @@
#include <stdbool.h>
#include <stdio.h>
HANDLE start_and_inject(HANDLE hJob, LPCSTR path, LPSTR cmdline, LPCSTR inject, BOOL debug_wait,
DWORD delay, LPCSTR extra_injections, DWORD flags);
BOOL start_and_inject(HANDLE hJob, LPCSTR path, LPSTR cmdline, LPCSTR inject, BOOL debug_wait,
DWORD delay, LPCSTR extra_injections, DWORD flags, LPPROCESS_INFORMATION lpProcessInformation);
#define MICELIB "mice.dll"

View File

@ -7,6 +7,7 @@
#include <time.h>
#pragma comment(lib, "DbgHelp.lib")
#include "../util/pid.h"
#include "config.h"
#define _LF(category, name, display) \
@ -87,7 +88,6 @@ int _do_log(BYTE log_level, PLOG_FACILITY facility, const char* format, va_list
char prefix = LOG_PREFIXES[log_level];
int col_len = strlen(log_colours[log_level]);
EnterCriticalSection(&logger_lock);
@ -168,9 +168,9 @@ int _log_game(PLOG_FACILITY facility, const char* format, ...) {
return ret;
}
void setup_logging(DWORD slotPid) {
void setup_logging() {
char slotName[MAX_PATH + 1];
sprintf_s(slotName, MAX_PATH, "\\\\.\\mailslot\\micelog%d", slotPid);
sprintf_s(slotName, MAX_PATH, "\\\\.\\mailslot\\micelog%d", GetOutermostMiceId());
hSlot = CreateFile(slotName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);

View File

@ -38,7 +38,7 @@ int vlog_game(PLOG_FACILITY facility, const char* format, va_list args);
void log_stack(PLOG_FACILITY facility);
void setup_logging(DWORD slotPid);
void setup_logging();
// Disable some logging entirely at build time for speed
#define COMPILE_LOG_LEVEL 6

View File

@ -2,5 +2,6 @@ util_lib = static_library(
'miceutil',
sources: [
'hex.c',
'pid.c',
],
)

View File

@ -0,0 +1,41 @@
#include <Windows.h>
#include <psapi.h>
#include <shlwapi.h>
#include <tlhelp32.h>
#pragma comment(lib, "psapi.lib")
DWORD GetParentProcessIdFor(DWORD pid) {
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe = { 0 };
pe.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(h, &pe)) {
do {
if (pe.th32ProcessID == pid) {
CloseHandle(h);
return pe.th32ParentProcessID;
}
} while (Process32Next(h, &pe));
}
CloseHandle(h);
return (DWORD)-1;
}
DWORD GetParentProcessId(void) { return GetParentProcessIdFor(GetCurrentProcessId()); }
DWORD GetOutermostMiceId(void) {
DWORD pid = GetCurrentProcessId();
do {
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
if (hProcess) {
CHAR baseName[MAX_PATH + 1];
if (GetModuleFileNameEx(hProcess, NULL, baseName, sizeof baseName)) {
// TODO: Better
if (strcmp(PathFindFileNameA(baseName), "mice.exe") == 0) return pid;
}
CloseHandle(hProcess);
}
pid = GetParentProcessIdFor(pid);
} while (pid != (DWORD)-1);
return (DWORD)-1;
}

View File

@ -0,0 +1,5 @@
#include <Windows.h>
DWORD GetParentProcessIdFor(DWORD pid);
DWORD GetParentProcessId(void);
DWORD GetOutermostMiceId(void);