Browse Source

Initial commit

master
Bottersnike 8 months ago
commit
320617e2e5
  1. 10
      .gitignore
  2. 45
      Makefile
  3. 8
      README.md
  4. 11
      cross-32.ini
  5. 10
      cross-64.ini
  6. 14
      meson.build
  7. 1
      meson_options.txt
  8. 4
      src/meson.build
  9. 141
      src/micetools/dll/com.c
  10. 47
      src/micetools/dll/com.h
  11. 44
      src/micetools/dll/comdevice.c
  12. 11
      src/micetools/dll/comdevice.h
  13. 147
      src/micetools/dll/dllmain.c
  14. 51
      src/micetools/dll/drivers/columba.c
  15. 23
      src/micetools/dll/drivers/mx.h
  16. 24
      src/micetools/dll/drivers/mxhwreset.c
  17. 37
      src/micetools/dll/drivers/mxjvs.c
  18. 0
      src/micetools/dll/drivers/mxparallel.c
  19. 363
      src/micetools/dll/drivers/mxsmbus.c
  20. 126
      src/micetools/dll/drivers/mxsram.c
  21. 289
      src/micetools/dll/drivers/mxsuperio.c
  22. 205
      src/micetools/dll/files.c
  23. 63
      src/micetools/dll/files.h
  24. 22
      src/micetools/dll/meson.build
  25. 1
      src/micetools/dll/mice.def
  26. 29
      src/micetools/dll/micesetupapi.h
  27. 119
      src/micetools/dll/setupapi.c
  28. 29
      src/micetools/dll/smbus.h
  29. 143
      src/micetools/dll/w83791d.h
  30. 123
      src/micetools/launcher/exe.c
  31. 4
      src/micetools/launcher/exe.h
  32. 65
      src/micetools/launcher/locate.c
  33. 8
      src/micetools/launcher/locate.h
  34. 41
      src/micetools/launcher/main.c
  35. 12
      src/micetools/launcher/meson.build
  36. 19
      src/micetools/lib/am/amtimer.c
  37. 15
      src/micetools/lib/am/amtimer.h
  38. 6
      src/micetools/lib/am/meson.build
  39. 110
      src/micetools/lib/dmi/dmi.c
  40. 58
      src/micetools/lib/dmi/dmi.h
  41. 6
      src/micetools/lib/dmi/meson.build
  42. 25
      src/micetools/lib/json/LICESNSE
  43. 1
      src/micetools/lib/json/README.txt
  44. 813
      src/micetools/lib/json/json.c
  45. 114
      src/micetools/lib/json/json.h
  46. 7
      src/micetools/lib/json/meson.build
  47. 16
      src/micetools/lib/meson.build
  48. 95
      src/micetools/lib/mice/hook.c
  49. 22
      src/micetools/lib/mice/hook.h
  50. 56
      src/micetools/lib/mice/ioctl.h
  51. 168
      src/micetools/lib/mice/log.c
  52. 26
      src/micetools/lib/mice/log.h
  53. 7
      src/micetools/lib/mice/meson.build
  54. 3
      src/micetools/lib/mice/mice.h
  55. 57
      src/micetools/lib/util/hex.c
  56. 2
      src/micetools/lib/util/hex.h
  57. 6
      src/micetools/lib/util/meson.build
  58. 6
      src/micetools/meson.build
  59. 77
      src/micetools/micekeychip/callbacks/appboot.c
  60. 112
      src/micetools/micekeychip/callbacks/billing.c
  61. 94
      src/micetools/micekeychip/callbacks/callbacks.h
  62. 12
      src/micetools/micekeychip/callbacks/crypto.c
  63. 20
      src/micetools/micekeychip/callbacks/misc.c
  64. 10
      src/micetools/micekeychip/callbacks/storage.c
  65. 35
      src/micetools/micekeychip/callbacks/tracedata.c
  66. 50
      src/micetools/micekeychip/config.def
  67. 14
      src/micetools/micekeychip/config.h
  68. 111
      src/micetools/micekeychip/main.c
  69. 28
      src/micetools/micekeychip/meson.build
  70. 154
      src/micetools/micekeychip/mxk.c
  71. 11
      src/micetools/micekeychip/mxk.h
  72. 303
      src/micetools/micepatch/main.c
  73. 15
      src/micetools/micepatch/meson.build
  74. 0
      src/micetools/traces.c
  75. BIN
      src/system/billing.pub
  76. BIN
      src/system/ca.crt
  77. 40
      src/tools/keys.py
  78. 27
      subprojects/inih_dep/LICENSE.txt
  79. 159
      subprojects/inih_dep/README.md
  80. 298
      subprojects/inih_dep/ini.c
  81. 178
      subprojects/inih_dep/ini.h
  82. 96
      subprojects/inih_dep/meson.build
  83. 70
      subprojects/inih_dep/meson_options.txt

10
.gitignore vendored

@ -0,0 +1,10 @@
dist/
build/
builddir/
srcdir/
.vscode/
# Don't distribute the libpcp sources
src/micetools/lib/libpcp/
# And keep build artifacts out of git!
src/libpcp.lib

45
Makefile

@ -0,0 +1,45 @@
BUILD_DIR := build
BUILD_DIR_32 := $(BUILD_DIR)/build32
BUILD_DIR_64 := $(BUILD_DIR)/build64
DIST_DIR := dist
MICE_32 = "$(BUILD_DIR_32)/src\mice.exe"
MICE_64 = "$(BUILD_DIR_64)/src\mice.exe"
VCVARS_32 = C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars32.bat
VCVARS_64 = C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat
.PHONY: all
all: mice86 dist
mice86:
"$(VCVARS_32)" \
& meson setup --backend ninja --cross cross-32.ini $(BUILD_DIR_32) \
& meson compile -C $(BUILD_DIR_32)
mice64:
"$(VCVARS_64)" \
& meson setup --cross cross-64.ini $(BUILD_DIR_64) \
& meson compile -C $(BUILD_DIR_64)
.PHONY: clean
clean:
@del /S /F /Q $(BUILD_DIR)
@rmdir /S /Q $(BUILD_DIR)
@del /S /F /Q $(DIST_DIR)
@rmdir /S /Q $(DIST_DIR)
.PHONY: dist
dist:
@-mkdir $(DIST_DIR)
@copy /Y "$(BUILD_DIR_32)/src/micetools/micekeychip\micekeychip.exe" "$(DIST_DIR)/micekeychip.exe"
@copy /Y "$(BUILD_DIR_32)/src/micetools/micepatch\micepatch.exe" "$(DIST_DIR)/micepatch.exe"
@copy /Y "$(BUILD_DIR_32)/src/micetools/lib/libpcp\libpcp.lib" "$(DIST_DIR)/libpcp.lib"
@copy /Y "$(BUILD_DIR_32)/src/micetools/launcher\mice.exe" "$(DIST_DIR)/mice86.exe"
@copy /Y "$(BUILD_DIR_32)/src/micetools/dll\mice.dll" "$(DIST_DIR)/mice86.dll"
# @copy /Y "$(BUILD_DIR_64)/src/micetools/launcher\mice.exe" "$(DIST_DIR)/mice64.exe"
# @copy /Y "$(BUILD_DIR_64)/src/micetools/dll\mice.dll" "$(DIST_DIR)/mice64.dll"
@xcopy /E /H /C /R /Q /Y src\system "$(DIST_DIR)\system/*"
@xcopy /E /H /C /R /Q /Y src\tools "$(DIST_DIR)\tools/*"

8
README.md

@ -0,0 +1,8 @@
# micetools
For a complete build, ensure to download `libpcp.lib` and place it in `src/`
prior to running `make`.
**Note:** exe hashes will not match the distributed binaries when compiling
using `libpcp.lib` as the distributed binaries have been compiled directly
against libpcp's source.

11
cross-32.ini

@ -0,0 +1,11 @@
[binaries]
c = 'cl'
cpp = 'cl'
strip = 'cl'
[host_machine]
system = 'windows'
cpu_family = 'x86'
cpu = 'i686'
endian = 'little'

10
cross-64.ini

@ -0,0 +1,10 @@
[binaries]
c = 'cl'
cpp = 'cl'
strip = 'cl'
[host_machine]
system = 'windows'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'

14
meson.build

@ -0,0 +1,14 @@
project('micetools', 'c')
if (host_machine.cpu_family() == 'x86')
add_project_arguments('-DMICE_WIN32', language: 'c')
endif
add_project_arguments(
'-DWIN32_LEAN_AND_MEAN', # Strip out headers we don't really need
'-D_WIN32_WINNT=_WIN32_WINNT_WINXP', # hahahahaha I hate it
# '/O1', # Optimise size
language: 'c',
)
subdir('src')

1
meson_options.txt

@ -0,0 +1 @@
option('vsenv', type: 'boolean', value: false)

4
src/meson.build

@ -0,0 +1,4 @@
inih = subproject('inih_dep')
libs_dir = meson.current_source_dir()
subdir('micetools')

141
src/micetools/dll/com.c

@ -0,0 +1,141 @@
#include "com.h"
com_hook_t* com_hook_list = NULL;
com_hook_t* new_com_hook(BYTE port) {
com_hook_t* hook = (com_hook_t*)malloc(sizeof *hook);
swprintf(hook->wName, (sizeof hook->wName) / (sizeof hook->wName[0]), L"COM%d", port);
hook->com = port;
hook->GetCommState = NULL;
hook->SetCommState = NULL;
hook->GetCommTimeouts = NULL;
hook->SetCommTimeouts = NULL;
hook->SetupComm = NULL;
hook->PurgeComm = NULL;
hook->GetCommModemStatus = NULL;
hook->WaitCommEvent = NULL;
hook->ClearCommError = NULL;
return hook;
};
void hook_com(com_hook_t* hook) {
hook->next = NULL;
hook->virtual_handle = NULL;
if (com_hook_list == NULL) {
com_hook_list = hook;
return;
}
com_hook_t* hl = com_hook_list;
while (hl->next != NULL) hl = hl->next;
hl->next = hook;
};
BOOL WINAPI FakeGetCommState(HANDLE hFile, LPDCB lpDCB) {
log_misc("comm", "GetCommState(0x%p, 0x%p)", hFile, lpDCB);
com_hook_t* hook = com_hook_list;
while (hook != NULL) {
if (hook->virtual_handle == hFile && hook->GetCommState != NULL) {
return hook->GetCommState(hook->data, lpDCB);
}
}
return TrueGetCommState(hFile, lpDCB);
}
BOOL WINAPI FakeSetCommState(HANDLE hFile, LPDCB lpDCB) {
log_misc("comm", "SetCommState(0x%p, 0x%p)", hFile, lpDCB);
com_hook_t* hook = com_hook_list;
while (hook != NULL) {
if (hook->virtual_handle == hFile && hook->SetCommState != NULL) {
return hook->SetCommState(hook->data, lpDCB);
}
}
return TrueSetCommState(hFile, lpDCB);
}
BOOL WINAPI FakeGetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) {
log_misc("comm", "GetCommTimeouts(0x%p, 0x%p)", hFile, lpCommTimeouts);
com_hook_t* hook = com_hook_list;
while (hook != NULL) {
if (hook->virtual_handle == hFile && hook->GetCommTimeouts != NULL) {
return hook->GetCommTimeouts(hook->data, lpCommTimeouts);
}
}
return TrueGetCommTimeouts(hFile, lpCommTimeouts);
}
BOOL WINAPI FakeSetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) {
log_misc("comm", "SetCommTimeouts(0x%p, 0x%p)", hFile, lpCommTimeouts);
com_hook_t* hook = com_hook_list;
while (hook != NULL) {
if (hook->virtual_handle == hFile && hook->SetCommTimeouts != NULL) {
return hook->SetCommTimeouts(hook->data, lpCommTimeouts);
}
}
return TrueSetCommTimeouts(hFile, lpCommTimeouts);
}
BOOL WINAPI FakeSetupComm(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue) {
log_misc("comm", "SetupCom(0x%p, 0x%08x, 0x%08x)", hFile, dwInQueue, dwOutQueue);
com_hook_t* hook = com_hook_list;
while (hook != NULL) {
if (hook->virtual_handle == hFile && hook->SetupComm != NULL) {
return hook->SetupComm(hook->data, dwInQueue, dwOutQueue);
}
}
return TrueSetupComm(hFile, dwInQueue, dwOutQueue);
}
BOOL WINAPI FakePurgeComm(HANDLE hFile, DWORD dwFlags) {
log_misc("comm", "PurgeComm(0x%p, 0x%08x)", hFile, dwFlags);
com_hook_t* hook = com_hook_list;
while (hook != NULL) {
if (hook->virtual_handle == hFile && hook->PurgeComm != NULL) {
return hook->PurgeComm(hook->data, dwFlags);
}
}
return TruePurgeComm(hFile, dwFlags);
}
BOOL WINAPI FakeGetCommModemStatus(HANDLE hFile, LPDWORD lpModelStat) {
log_misc("comm", "GetCommModemStatus(0x%p, 0x%p)", hFile, lpModelStat);
com_hook_t* hook = com_hook_list;
while (hook != NULL) {
if (hook->virtual_handle == hFile && hook->GetCommModemStatus != NULL) {
return hook->GetCommModemStatus(hook->data, lpModelStat);
}
}
return TrueGetCommModemStatus(hFile, lpModelStat);
}
BOOL WINAPI FakeWaitCommEvent(HANDLE hFile, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped) {
log_misc("comm", "WaitCommEvent");
com_hook_t* hook = com_hook_list;
while (hook != NULL) {
if (hook->virtual_handle == hFile && hook->WaitCommEvent != NULL) {
return hook->WaitCommEvent(hook->data, lpEvtMask, lpOverlapped);
}
}
return TrueWaitCommEvent(hFile, lpEvtMask, lpOverlapped);
}
BOOL WINAPI FakeClearCommError(HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpStat) {
log_misc("comm", "ClearCommError");
com_hook_t* hook = com_hook_list;
while (hook != NULL) {
if (hook->virtual_handle == hFile && hook->ClearCommError != NULL) {
return hook->ClearCommError(hook->data, lpErrors, lpStat);
}
}
return TrueClearCommError(hFile, lpErrors, lpStat);
}
void hook_commio() {
hook("Kernel32.dll", "GetCommState", FakeGetCommState, (void**)&TrueGetCommState, 6);
hook("Kernel32.dll", "SetCommState", FakeSetCommState, (void**)&TrueSetCommState, 6);
hook("Kernel32.dll", "GetCommTimeouts", FakeGetCommTimeouts, (void**)&TrueGetCommTimeouts, 6);
hook("Kernel32.dll", "SetCommTimeouts", FakeSetCommTimeouts, (void**)&TrueSetCommTimeouts, 6);
hook("Kernel32.dll", "SetupComm", FakeSetupComm, (void**)&TrueSetupComm, 6);
hook("Kernel32.dll", "PurgeComm", FakePurgeComm, (void**)&TruePurgeComm, 6);
hook("Kernel32.dll", "GetCommModemStatus", FakeGetCommModemStatus, (void**)&TrueGetCommModemStatus, 6);
hook("Kernel32.dll", "WaitCommEvent", FakeWaitCommEvent, (void**)&TrueWaitCommEvent, 6);
hook("Kernel32.dll", "ClearCommError", FakeClearCommError, (void**)&TrueClearCommError, 6);
}

47
src/micetools/dll/com.h

@ -0,0 +1,47 @@
#include <Windows.h>
#include <stdbool.h>
#include <stdio.h>
static BOOL(WINAPI* TrueGetCommState)(HANDLE hFile, LPDCB lpDCB);
static BOOL(WINAPI* TrueSetCommState)(HANDLE hFile, LPDCB lpDCB);
static BOOL(WINAPI* TrueGetCommTimeouts)(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts);
static BOOL(WINAPI* TrueSetCommTimeouts)(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts);
static BOOL(WINAPI* TrueSetupComm)(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue);
static BOOL(WINAPI* TruePurgeComm)(HANDLE hFile, DWORD dwFlags);
static BOOL(WINAPI* TrueGetCommModemStatus)(HANDLE hFile, LPDWORD lpModelStat);
static BOOL(WINAPI* TrueWaitCommEvent)(HANDLE hFile, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped);
static BOOL(WINAPI* TrueClearCommError)(HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpStat);
typedef BOOL(FnGetCommState)(void* com, LPDCB lpDCB);
typedef BOOL(FnSetCommState)(void* com, LPDCB lpDCB);
typedef BOOL(FnGetCommTimeouts)(void* com, LPCOMMTIMEOUTS lpCommTimeouts);
typedef BOOL(FnSetCommTimeouts)(void* com, LPCOMMTIMEOUTS lpCommTimeouts);
typedef BOOL(FnSetupComm)(void* com, DWORD dwInQueue, DWORD dwOutQueue);
typedef BOOL(FnPurgeComm)(void* com, DWORD dwFlags);
typedef BOOL(FnGetCommModemStatus)(void* com, LPDWORD lpModelStat);
typedef BOOL(FnWaitCommEvent)(void* com, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped);
typedef BOOL(FnClearCommError)(void* com, LPDWORD lpErrors, LPCOMSTAT lpStat);
typedef struct com_hook {
HANDLE virtual_handle;
WCHAR wName[7]; // max is COM255
BYTE com;
FnGetCommState* GetCommState;
FnSetCommState* SetCommState;
FnGetCommTimeouts* GetCommTimeouts;
FnSetCommTimeouts* SetCommTimeouts;
FnSetupComm* SetupComm;
FnPurgeComm* PurgeComm;
FnGetCommModemStatus* GetCommModemStatus;
FnWaitCommEvent* WaitCommEvent;
FnClearCommError* ClearCommError;
void* data;
struct com_hook* next;
} com_hook_t;
com_hook_t* new_com_hook(BYTE port);
void hook_com(com_hook_t* hook);
void hook_com();

44
src/micetools/dll/comdevice.c

@ -0,0 +1,44 @@
#include "comdevice.h"
BOOL DevGetCommState(void* data, LPDCB lpDCB) { return TRUE; }
BOOL DevSetCommState(void* data, LPDCB lpDCB) { return TRUE; }
BOOL DevGetCommTimeouts(void* data, LPCOMMTIMEOUTS lpCommTimeouts) { return TRUE; }
BOOL DevSetCommTimeouts(void* data, LPCOMMTIMEOUTS lpCommTimeouts) { return TRUE; }
BOOL DevSetupComm(void* data, DWORD dwInQueue, DWORD dwOutQueue) { return TRUE; }
BOOL DevPurgeComm(void* data, DWORD dwFlags) {
if (dwFlags & PURGE_RXCLEAR) ((com_device_t*)data)->filled = 0;
return TRUE;
}
BOOL DevGetCommModemStatus(void* data, LPDWORD lpModelStat) {
// TODO: JVS SENSE
return TRUE;
}
BOOL DevWaitCommEvent(void* data, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped) {
WaitForSingleObject(((com_device_t*)data)->event, INFINITE);
if (lpOverlapped != NULL) SetEvent(lpOverlapped->hEvent);
return TRUE;
}
BOOL DevClearCommError(void* data, LPDWORD lpErrors, LPCOMSTAT lpStat) { return TRUE; }
com_device_t* new_com_device(BYTE port) {
com_device_t* hook = (com_device_t*)malloc(sizeof *hook);
com_hook_t* com = new_com_hook(port);
file_hook_t* file = new_file_hook(com->wName);
com->data = hook;
com->GetCommState = DevGetCommState;
com->SetCommState = DevSetCommState;
com->GetCommTimeouts = DevGetCommTimeouts;
com->SetCommTimeouts = DevSetCommTimeouts;
com->SetupComm = DevSetupComm;
com->PurgeComm = DevPurgeComm;
com->GetCommModemStatus = DevGetCommModemStatus;
com->WaitCommEvent = DevWaitCommEvent;
com->ClearCommError = DevClearCommError;
hook->filled = 0;
hook->event = CreateEventW(NULL, TRUE, FALSE, hook->com->wName);
hook->com = com;
return hook;
}

11
src/micetools/dll/comdevice.h

@ -0,0 +1,11 @@
#include "com.h"
#include "files.h"
typedef struct com_device {
com_hook_t* com;
file_hook_t* file;
BYTE queue[2048];
DWORD filled;
HANDLE event;
} com_device_t;

147
src/micetools/dll/dllmain.c

@ -0,0 +1,147 @@
#include <Windows.h>
#include <shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")
#include <stdio.h>
#include "../lib/mice/mice.h"
#include "drivers/mx.h"
#include "files.h"
#include "com.h"
#include "micesetupapi.h"
WCHAR exePath[MAX_PATH + 1];
void enable_traces() {
if (wcscmp(exePath, L"Game.exe") == 0) {
*(DWORD*)(0x008717a0) = 1;
*(DWORD*)(0x00871728) = 1;
*(DWORD*)(0x00871cd8) = 1;
*(DWORD*)(0x00872660) = 1;
*(DWORD*)(0x0087297c) = 1; // LOG_EN_EEPROM
*(DWORD*)(0x00872980) = 1;
*(DWORD*)(0x00872988) = 1;
*(DWORD*)(0x00873540) = 1;
*(DWORD*)(0x00873538) = 1;
*(DWORD*)(0x0087f890) = 1;
*(DWORD*)(0x00882ce4) = 1;
*(DWORD*)(0x00882cec) = 1;
*(DWORD*)(0x00883018) = 1;
*(DWORD*)(0x00886ff8) = 1;
*(DWORD*)(0x0088b1b8) = 1;
*(DWORD*)(0x0088b1c0) = 1;
} else if (wcscmp(exePath, L"ALLNetProc_Win.exe") == 0) {
*(DWORD*)(0x004f48b0) = 1; // LOG_EN_DONGLE
*(DWORD*)(0x004f989c) = 1; // LOG_EN_PCP
*(DWORD*)(0x004f7d04) = 1; // LOG_EN_EEPROM
*(DWORD*)(0x004f7d08) = 1; // LOG_EN_BACKUP
*(DWORD*)(0x004f8118) = 1; // LOG_EN_RTC
*(DWORD*)(0x004f96dc) = 1; // LOG_EN_GFETCHER
*(DWORD*)(0x004f8338) = 1; // LOG_EN_NETWORK
*(DWORD*)(0x004f88c0) = 1; // LOG_EN_MASTER
*(DWORD*)(0x004f88b0) = 1; // LOG_EN_HM
*(DWORD*)(0x004f8330) = 1; // LOG_EN_SRAM
*(DWORD*)(0x004f9728) = 1; // LOG_EN_PLATFORM
//*(DWORD*)(0x004f9e7c) = 5; // LOG_EN_ASSERTS (handled by the bellow
// instead)
*(DWORD*)(0x004e884c) = 10; // ALPB_LOG_LEVEL (0=None, 1=Error,
// 2=Warning, 3=Most, 4=Debug)
} else if (wcscmp(exePath, L"ORIG_mxsegaboot.exe") == 0 || wcscmp(exePath, L"mxsegaboot.exe") == 0) {
// start of am
*(DWORD*)(0x0054fcd8) = 1; // LOG_EN_JVS_DRIVER
*(DWORD*)(0x00538810) = 1; // LOG_EN_DIPSW
*(DWORD*)(0x0054afc8) = 1; // LOG_EN_ATA
*(DWORD*)(0x00544b78) = 1; // LOG_EN_DONGLE
*(DWORD*)(0x00536c98) = 1; // LOG_EN_EEPROM
*(DWORD*)(0x00537834) = 1; // LOG_EN_GCATCHER
*(DWORD*)(0x00537d4c) = 1; // LOG_EN_GDELIVER
*(DWORD*)(0x0053828c) = 1; // LOG_EN_GFETCHER
*(DWORD*)(0x00547fd0) = 1; // LOG_EN_HWRESET
*(DWORD*)(0x00547fd8) = 1; // LOG_EN_PLATFORM
*(DWORD*)(0x00548268) = 1; // LOG_EN_HM
*(DWORD*)(0x00536f30) = 1; // LOG_EN_BACKUP
*(DWORD*)(0x00547fcc) = 1; // LOG_EN_CMOS
*(DWORD*)(0x005382d8) = 1; // LOG_EN_INSTALL
*(DWORD*)(0x00538818) = 1; // LOG_EN_JVS
*(DWORD*)(0x00544b68) = 1; // LOG_EN_JVSP
*(DWORD*)(0x0054b3d8) = 1; // LOG_EN_MASTER
*(DWORD*)(0x00548280) = 1; // LOG_EN_NETWORK
*(DWORD*)(0x00548050) = 1; // LOG_EN_RTC
*(DWORD*)(0x00536c94) = 1; // LOG_EN_SRAM
*(DWORD*)(0x005487f8) = 1; // LOG_EN_STORAGE
*(DWORD*)(0x00536c90) = 1; // LOG_EN_SYS
// end of am
*(DWORD*)(0x00536c70) = 1; // LOG_EN_PCPT
} else if (wcscmp(exePath, L"maimai_dump_.exe") == 0) {
*(DWORD*)(0x00c8ab7c) = 1; // LOG_EN_SRAM
*(DWORD*)(0x00f406f0) = 1; // LOG_EN_CABINET_DL
*(DWORD*)(0x00c88680) = 1; // LOG_EN_INSTALL
*(DWORD*)(0x00c8ab78) = 1; // LOG_EN_EEPROM
*(DWORD*)(0x00c88608) = 1; // LOG_EN_PLATFORM
*(DWORD*)(0x00c88dd0) = 1; // LOG_EN_STORAGE
*(DWORD*)(0x00ca25ec) = 1; // LOG_EN_PCP
*(DWORD*)(0x00c96ed0) = 1; // LOG_EN_HM
*(DWORD*)(0x00f406ec) = 1; // LOG_EN_HTTP
*(DWORD*)(0x00c89ca8) = 1; // LOG_EN_DIPSW
*(DWORD*)(0x00c96ed8) = 1; // LOG_EN_DONGLE
*(DWORD*)(0x00c9a83c) = 1; // LOG_EN_JVSP
*(DWORD*)(0x00c89730) = 1; // LOG_EN_NETWORK
*(DWORD*)(0x00c9a440) = 1; // LOG_EN_JVST_THREAD
*(DWORD*)(0x00c8ab80) = 1; // LOG_EN_JVS
*(DWORD*)(0x00c89fc8) = 1; // LOG_EN_MASTER
*(DWORD*)(0x00c88bb8) = 1; // LOG_EN_RTC
*(DWORD*)(0x00c9e420) = 1; // LOG_EN_JVST_DRIVER
*(DWORD*)(0x00c89320) = 1; // LOG_EN_BACKUP
*(DWORD*)(0x00c88bb4) = 1; // LOG_EN_HWRESET
*(DWORD*)(0x00c830e8) = 1; // LOG_EN
} else if (wcscmp(exePath, L"mxnetwork.exe") == 0) {
*(DWORD*)(0x004438e0) = 1; // LOG_EN_PCP
*(DWORD*)(0x004433f8) = 1; // LOG_EN_UTL
} else {
log_warning("traces", "No known traces for %ls", exePath);
}
}
void prebind_hooks() {
hook_setupapi();
hook_commio();
hook_io();
}
void init_injection() {
// We're in a new context now, so need to reconfigure
setup_logging();
log_info(BOOT_LOGGER, "Handover complete. Now executing within %ls", exePath);
dmi_build_default();
enable_traces();
setup_columba();
setup_mxsram();
setup_mxsuperio();
setup_mxjvs();
setup_mxhwreset();
setup_mxsmbus();
if (!add_fake_device(&PLATFORM_GUID, L"\\\\.\\platform")) {
log_error("platform", "failed to install platform device");
}
// Must be the last thing called!
// register_devices();
prebind_hooks();
setup_hooks();
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
if (ul_reason_for_call != DLL_PROCESS_ATTACH) return TRUE;
GetModuleFileNameW(NULL, exePath, MAX_PATH);
wcscpy_s(exePath, MAX_PATH + 1, PathFindFileNameW(exePath));
init_injection();
return TRUE;
}

51
src/micetools/dll/drivers/columba.c

@ -0,0 +1,51 @@
#include <Windows.h>
#include "../lib/dmi/dmi.h"
#include "../lib/mice/mice.h"
#include "files.h"
BOOL columba_DeviceIoControl(DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer,
DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
switch (dwIoControlCode) {
case IOCTL_COLUMBA_READ_DMI:
log_misc("columba",
"DeviceIoControl(<columba>, <read dmi>, 0x%p, 0x%x, -, "
"0x%x, -, -)",
lpInBuffer, nInBufferSize, nOutBufferSize);
memset(lpOutBuffer, 0, nOutBufferSize);
if (((LPWORD)lpInBuffer)[0] == 0x0000) {
DMI_HEADER dmi = {
.Signature = {'_', 'D', 'M', 'I', '_'},
.Checksum = 0,
.StructLength = dmi_size,
.StructAddr = 0xdeeabeef,
.NumberOfStructs = 0x20,
.BCDRevision = 0,
.Reserved = 0,
};
dmi.Checksum = dmi_calc_checksum((char*)&dmi, 15);
memcpy(lpOutBuffer, &dmi, sizeof(DMI_HEADER));
if (lpBytesReturned) *lpBytesReturned = sizeof(DMI_HEADER);
} else {
memcpy(lpOutBuffer, dmi_table, dmi_size);
if (lpBytesReturned) *lpBytesReturned = dmi_size;
}
break;
default:
log_warning("columba", "unhandled 0x%08x", dwIoControlCode);
return FALSE;
}
return FALSE;
}
void setup_columba() {
file_hook_t* columba = new_file_hook(L"\\\\.\\columba");
columba->DeviceIoControl = &columba_DeviceIoControl;
hook_file(columba);
}

23
src/micetools/dll/drivers/mx.h

@ -0,0 +1,23 @@
#include "../files.h"
#include <initguid.h>
FnDeviceIoControl mxhwreset_DeviceIoControl;
void setup_mxhwreset();
FnDeviceIoControl mxjvs_DeviceIoControl;
void setup_mxjvs();
FnDeviceIoControl mxsmbus_DeviceIoControl;
void setup_mxsmbus();
FnDeviceIoControl mxsram_DeviceIoControl;
FnSetFilePointer mxsram_SetFilePointer;
FnWriteFile mxsram_WriteFile;
FnReadFile mxsram_ReadFile;
void setup_mxsram();
FnDeviceIoControl mxsuperio_DeviceIoControl;
void setup_mxsuperio();
DEFINE_GUID(MXSMBUS_GUID, 0x5C49E1FE, 0x3FEC, 0x4B8D, 0xA4, 0xB5, 0x76, 0xBE, 0x70, 0x25, 0xD8, 0x42);
DEFINE_GUID(PLATFORM_GUID, 0x86E0D1E0, 0x8089, 0x11D0, 0x9C, 0xE4, 0x08, 0x00, 0x3e, 0x30, 0x1F, 0x73);

24
src/micetools/dll/drivers/mxhwreset.c

@ -0,0 +1,24 @@
#include <Windows.h>
#include "../lib/mice/mice.h"
#include "mx.h"
BOOL mxhwreset_DeviceIoControl(DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer,
DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
switch (dwIoControlCode) {
case IOCTL_MXHWRESET_RESET:
if (lpBytesReturned) *lpBytesReturned = 0;
break;
default:
log_warning("mxhwreset", "unhandled 0x%08x", dwIoControlCode);
return FALSE;
}
return TRUE;
}
void setup_mxhwreset() {
file_hook_t* mxhwreset = new_file_hook(L"\\\\.\\mxhwreset");
mxhwreset->DeviceIoControl = &mxhwreset_DeviceIoControl;
hook_file(mxhwreset);
}

37
src/micetools/dll/drivers/mxjvs.c

@ -0,0 +1,37 @@
#include <Windows.h>
#include "../lib/mice/mice.h"
#include "mx.h"
BOOL mxjvs_DeviceIoControl(DWORD dwIoControlCode, LPVOID lpInBuffer,
DWORD nInBufferSize, LPVOID lpOutBuffer,
DWORD nOutBufferSize, LPDWORD lpBytesReturned,
LPOVERLAPPED lpOverlapped) {
switch (dwIoControlCode) {
case IOCTL_MXJVS_EXCHANGE:
log_misc("mxjvs",
"DeviceIoControl(<mxjvs>, <exchange>, 0x%p, 0x%x, -, "
"0x%x, -, -)",
lpInBuffer, nInBufferSize, nOutBufferSize);
// mxjvsDevice->exchange(
// lpbyte(lpInBuffer), nInBufferSize & 0xFFFF,
// lpbyte(lpOutBuffer), lpBytesReturned
// );
if (lpBytesReturned) *lpBytesReturned = 0;
break;
default:
log_warning("mxjvs", "unhandled 0x%08x", dwIoControlCode);
return FALSE;
}
return TRUE;
}
void setup_mxjvs() {
file_hook_t* mxjvs = new_file_hook(L"\\\\.\\mxjvs");
mxjvs->DeviceIoControl = &mxjvs_DeviceIoControl;
hook_file(mxjvs);
}

0
src/micetools/dll/drivers/mxparallel.c

363
src/micetools/dll/drivers/mxsmbus.c

@ -0,0 +1,363 @@
#include <Windows.h>
#include "../lib/dmi/dmi.h"
#include "../lib/mice/mice.h"
#include "mx.h"
#include "smbus.h"
// PCA9535 (DIPSW)
#define PCA9535_WRITE 0x04
#define PCA9535_READ 0x05
#define PCA9535_IN0 0x00
#define PCA9535_IN1 0x01
#define PCA9535_OUT0 0x02
#define PCA9535_OUT1 0x03
#define PCA9535_INV0 0x04
#define PCA9535_INV1 0x05
#define PCA9535_CONF0 0x06
#define PCA9535_CONF1 0x07
#define PCA9535 0x20
#define EEPROM 0x57
#define EEPROM_DUMP L"dev/eeprom.bin"
typedef struct eeprom_reg {
BYTE data[32];
} eeprom_reg_t;
typedef struct eeprom_bank {
eeprom_reg_t reg[0x100];
} eeprom_bank_t;
// 256 registers, 32 bytes each
eeprom_bank_t EEPROM_DATA;
/*
* Known registers:
* - Reg 0x00: Stores ??? in [00]
* - Reg 0x08: Stores LPC address in [00, 01]
* - Reg 0x16: Stores ??? in [00, 01]
* - Reg 0x0e: Stores
*/
typedef uint_fast32_t crc_t;
static const crc_t crc_table[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832,
0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a,
0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab,
0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4,
0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074,
0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525,
0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76,
0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6,
0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7,
0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7,
0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330,
0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
#define CRC_ALGO_TABLE_DRIVEN 1
static inline crc_t crc_init(void) { return 0xffffffff; }
crc_t crc_update(crc_t crc, const void* data, size_t data_len) {
const unsigned char* d = (const unsigned char*)data;
unsigned int tbl_idx;
while (data_len--) {
tbl_idx = (crc ^ *d) & 0xff;
crc = (crc_table[tbl_idx] ^ (crc >> 8)) & 0xffffffff;
d++;
}
return crc & 0xffffffff;
}
static inline crc_t crc_finalize(crc_t crc) { return crc ^ 0xffffffff; }
void eeprom_dump() {
HANDLE dump = _CreateFileW(EEPROM_DUMP, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
if (dump == INVALID_HANDLE_VALUE) {
log_error("eeprom", "CreateFileA(EEPROM_DUMP) failed");
return;
}
_WriteFile(dump, &EEPROM_DATA, sizeof EEPROM_DATA, NULL, NULL);
FlushFileBuffers(dump);
_CloseHandle(dump);
}
void eeprom_restore() {
HANDLE dump =
_CreateFileW(EEPROM_DUMP, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (dump == INVALID_HANDLE_VALUE) return;
DWORD read;
if (!_ReadFile(dump, &EEPROM_DATA, sizeof EEPROM_DATA, &read, NULL))
log_error("eeprom", "failed to restore (%d)", GetLastError());
_CloseHandle(dump);
}
DWORD eeprom_crc(BYTE reg) {
if (reg == 0x80 || reg == 0x280) {
// Some registers are only treated as 16 byte values
return crc_finalize(crc_update(crc_init(), EEPROM_DATA.reg[reg].data + 4, 12));
}
return crc_finalize(crc_update(crc_init(), EEPROM_DATA.reg[reg].data + 4, 28));
}
void eeprom_read(BYTE reg, BYTE index, BYTE* data, BYTE length) {
eeprom_restore();
for (BYTE i = index; i < index + length; i++) {
if (i > 0x1f) break;
BYTE byte = EEPROM_DATA.reg[reg].data[i];
// If register has a CRC
// if (reg == 0x00 || reg == 0x01 || reg == 0x02 || reg == 0x10 || reg
// == 0x11 || reg == 0x12 || reg == 0x200) {
if (true) {
// Intercept the read and inject a CRC instead
if (i == 0x00 || i == 0x01 || i == 0x02 || i == 0x03) {
DWORD crc = eeprom_crc(reg);
byte = crc >> 8 * i & 0xff;
}
}
data[i - index] = byte;
}
}
void eeprom_write(BYTE reg, BYTE index, BYTE* data, BYTE length) {
for (BYTE i = index; i < index + length; i++) {
if (i > 0x1f) break;
EEPROM_DATA.reg[reg].data[i] = data[i - index];
}
eeprom_dump();
}
BYTE eeprom_read_one(BYTE reg, BYTE index) {
BYTE data;
eeprom_read(reg, index, &data, 1);
return data;
}
void eeprom_write_one(BYTE reg, BYTE index, BYTE data) { eeprom_write(reg, index, &data, 1); }
BOOL mxsmbus_DeviceIoControl(DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer,
DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
mxsmbus_i2c_packet* i2c_packet = (mxsmbus_i2c_packet*)lpInBuffer;
mxsmbus_i2c_packet* i2c_out = (mxsmbus_i2c_packet*)lpOutBuffer;
mxsmbus_request_packet* request_packet = (mxsmbus_request_packet*)lpInBuffer;
mxsmbus_request_packet* request_out = (mxsmbus_request_packet*)lpOutBuffer;
BYTE dlen;
switch (dwIoControlCode) {
case IOCTL_MXSMBUS_GET_VERSION:
log_misc("mxsmbus",
"DeviceIoControl(<mxsmbus>, <get version>, 0x%p, 0x%x, "
"-, 0x%x, -, -)",
lpInBuffer, nInBufferSize, nOutBufferSize);
((LPDWORD)lpOutBuffer)[0] = 0x01020001;
if (lpBytesReturned) *lpBytesReturned = 4;
break;
case IOCTL_MXSMBUS_REQUEST: // dip r/w
log_misc("mxsmbus",
"DeviceIoControl(<mxsmbus>, <request>, 0x%p, 0x%x, -, "
"0x%x, -, -)",
lpInBuffer, nInBufferSize, nOutBufferSize);
// Game trace:
// 05 for 20
// ^[x3]
// 04 for 20
// ^[x3]
// 05 for 20
// 03 for 57
// ^[after every eeprom read/write]
// Address 0x20 = PCA9535 = DIP switches
// Address 0x30 = Keychip? "N2"
// Address 0x55 = Keychip?
// Address 0x57 = EEPROM
// dyn = 0x57
// 03: addr dyn: amEepromWait
// 04: addr dyn: amHmI2CWriteByte (via IOCTL_MXSMBUS_I2C instead)
// 05: addr dyn: amHmI2CWriteByte (via IOCTL_MXSMBUS_I2C instead)
//
// dyn2 = 0x20
// 04: addr dyn2: amDipswWriteByteInternal
// 05: addr dyn2: amDipswReadByteInternal[Ex]
// 0B: addr 0x20: amHmGetLPCChipId
// 0B: addr 0x21: amHmGetLPCChipId
// 48: addr 0x00: amHmGetLPCChipId
switch (i2c_packet->addr) {
case PCA9535:
switch (i2c_packet->prt) {
case PCA9535_WRITE:
switch (i2c_packet->reg) {
case PCA9535_OUT1:
log_error("mxsmbus", "pca9535 OUT1: %02x %02x", i2c_packet->data[0],
i2c_packet->data[1]);
break;
case PCA9535_INV0:
log_error("mxsmbus", "pca9535 INV0: %02x %02x", i2c_packet->data[0],
i2c_packet->data[1]);
break;
case PCA9535_INV1:
log_error("mxsmbus", "pca9535 INV1: %02x %02x", i2c_packet->data[0],
i2c_packet->data[1]);
break;
default:
log_error("mxsmbux",
"(write) Undefined pca9535 "
"register: 0x%02x",
i2c_packet->reg);
exit(1);
}
break;
case PCA9535_READ:
switch (i2c_packet->reg) {
case PCA9535_IN0: // DIPSW
i2c_packet->data[0] = 0x00;
break;
case PCA9535_IN1: // What's this one?
i2c_packet->data[0] = 0x00;
break;
case PCA9535_INV0:
case PCA9535_INV1:
case PCA9535_OUT1:
i2c_packet->data[0] = 0x00;
break;
default:
log_error("mxsmbux",
"(read) Undefined pca9535 "
"register: 0x%02x",
i2c_packet->reg);
exit(1);
}
i2c_packet->status = 0x00;
break;
default:
log_error("mxsmbux", "Unknown pca9535 command: 0x%02x", i2c_packet->prt);
exit(1);
}
break;
case EEPROM:
switch (i2c_packet->prt) {
case 3: // Wait
// 0x18 = wait, 0x00 = done
i2c_packet->status = 0;
break;
default:
log_error("mxsmbux", "Unknown eeprom command: 0x%02x", i2c_packet->prt);
exit(1);
}
break;
default:
log_error("mxsmbus", "Unknown smbus device: 0x%02x", i2c_packet->addr);
exit(1);
}
i2c_out->status = MXSBUS_OKAY;
if (lpBytesReturned) *lpBytesReturned = sizeof(mxsmbus_i2c_packet);
break;
case IOCTL_MXSMBUS_I2C: // i2c r/w
log_misc("mxsmbus",
"DeviceIoControl(<mxsmbus>, <i2c>, 0x%p, 0x%x, -, 0x%x, "
"-, -)",
lpInBuffer, nInBufferSize, nOutBufferSize);
log_misc("mxsmbus", "SMBus I2C request for %02x: 0x%02x (%02x bytes @ %02x)", request_packet->addr,
request_packet->prt, request_packet->dlen, request_packet->reg);
// log_warning("eeprom", "%08x %08x %08x %08x", dwordInBuffer[0],
// dwordInBuffer[1], dwordInBuffer[2], dwordInBuffer[3]);
// log_warning("eeprom", "%08x %08x %08x %08x", dwordInBuffer[4],
// dwordInBuffer[5], dwordInBuffer[6], dwordInBuffer[7]);
// log_warning("eeprom", "%08x %08x", dwordInBuffer[8],
// dwordInBuffer[9]);
// for (int i = 0; i < nInBufferSize; i++) {
// printf("%02x ", ((LPBYTE)lpInBuffer)[i]);
// }
// puts("");
// prt = byteInBuffer[1];
// addr = wordInBuffer[1];
// reg = wordInBuffer[2] & 0xFF;
dlen = request_packet->dlen;
if (dlen > 0x20) dlen = 0x20;
/*
* Known addresses:
* - 0x57: EEPROM
**/
request_packet->status = MXSBUS_OKAY;
if (request_packet->status != 0) {
log_error("mxsmbus", "invalid i2c packet");
return FALSE;
}
if (request_packet->addr != EEPROM) {
log_error("mxsmbus", "Unexpected I2C device: 0x%02x", request_packet->addr);
exit(1);
}
// 04 = Write byte
// 05 = Read byte
//
// 08 = Write block
// 09 = Read block
if (request_packet->prt == 0x08) {
// Write
log_misc("mxsmbus", "eeprom write %02x (0x%04x)", dlen, request_packet->reg);
// for (int i = 0; i < dlen; i++) printf("%02x ",
// request_packet->data[i]); puts("");
eeprom_write(request_packet->reg >> 5, request_packet->reg & 0x1f, request_packet->data,
request_packet->dlen);
request_out->status = 0;
} else if (i2c_packet->prt == 0x09) {
// Read
log_misc("mxsmbus", "eeprom read %02x (0x%04x)", dlen, request_packet->reg);
eeprom_read(request_packet->reg >> 5, request_packet->reg & 0x1f, request_out->data, dlen);
// for (int i = 0; i < dlen; i++) printf("%02x ",
// request_out->data[i]); puts("");
request_out->status = 0;
} else {
log_warning("mxsmbus", "UNHANDLED MXSMBUS I2C %02x", request_packet->prt);
exit(1);
}
if (lpBytesReturned) *lpBytesReturned = sizeof(mxsmbus_request_packet);
break;
default:
log_warning("mxsmbus", "unhandled 0x%08x", dwIoControlCode);
return FALSE;
}
return TRUE;
}
void setup_mxsmbus() {
file_hook_t* mxsmbus = new_file_hook(L"\\\\.\\mxsmbus");
mxsmbus->DeviceIoControl = &mxsmbus_DeviceIoControl;
hook_file(mxsmbus);
if (!add_fake_device(&MXSMBUS_GUID, L"\\\\.\\mxsmbus")) {
log_error("mxsmbus", "failed to install mxsmbus device");
}
}

126
src/micetools/dll/drivers/mxsram.c

@ -0,0 +1,126 @@
#include <Windows.h>
#include "../lib/mice/mice.h"
#include "mx.h"
#define SRAM_DUMP L"dev/sram.bin"
#define SRAM_SIZE 1024 * 2084
LPBYTE SRAM;
DWORD SRAM_POINTER = 0;
void sram_dump() {
HANDLE dump = _CreateFileW(SRAM_DUMP, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
if (dump == INVALID_HANDLE_VALUE) {
log_error("sram", "CreateFileA(SRAM_DUMP) failed");
return;
}
_WriteFile(dump, SRAM, SRAM_SIZE, NULL, NULL);
_CloseHandle(dump);
}
void sram_restore() {
HANDLE dump =
_CreateFileW(SRAM_DUMP, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (dump == INVALID_HANDLE_VALUE) return;
DWORD read;
if (!_ReadFile(dump, SRAM, SRAM_SIZE, &read, NULL)) log_error("sram", "failed to restore (%d)", GetLastError());
_CloseHandle(dump);
}
BOOL mxsram_DeviceIoControl(DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer,
DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
DWORD SRAM_VERSION = 0x0001;
DWORD SRAM_SECTOR_SIZE = 0x100; // Max is 0x800
switch (dwIoControlCode) {
case IOCTL_MXSRAM_PING: // Get version
log_misc("mxsram",
"DeviceIoControl(<mxsram>, <ping>, 0x%p, 0x%x, -, 0x%x, "
"-, -)",
lpInBuffer, nInBufferSize, nOutBufferSize);
((LPDWORD)lpOutBuffer)[0] = SRAM_VERSION;
if (lpBytesReturned) *lpBytesReturned = 4;
break;
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
log_misc("mxsram",
"DeviceIoControl(<mxsram>, <get drive geom>, 0x%p, "
"0x%x, -, 0x%x, -, -)",
lpInBuffer, nInBufferSize, nOutBufferSize);
DISK_GEOMETRY out = *(PDISK_GEOMETRY)lpOutBuffer;
memset(&out, 0, sizeof(out));
out.Cylinders.QuadPart = 1;
out.MediaType = FixedMedia;
out.TracksPerCylinder = 224;
out.SectorsPerTrack = 32;
out.BytesPerSector = 1;
if (lpBytesReturned) *lpBytesReturned = sizeof(DISK_GEOMETRY);
break;
case IOCTL_MXSRAM_GET_SECTOR_SIZE:
log_misc("mxsram",
"DeviceIoControl(<mxsram>, <get sector size>, 0x%p, "
"0x%x, -, 0x%x, -, -)",
lpInBuffer, nInBufferSize, nOutBufferSize);
((LPDWORD)lpOutBuffer)[0] = SRAM_SECTOR_SIZE;
if (lpBytesReturned) *lpBytesReturned = 4;
break;
default:
log_warning("mxsram", "unhandled 0x%08x", dwIoControlCode);
return FALSE;
}
return TRUE;
}
DWORD mxsram_SetFilePointer(LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod) {
if (dwMoveMethod == FILE_BEGIN) {
SRAM_POINTER = lDistanceToMove;
} else if (dwMoveMethod == FILE_CURRENT) {
SRAM_POINTER += lDistanceToMove;
}
return SRAM_POINTER;
}
BOOL mxsram_WriteFile(LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped) {
log_misc("mxsram", "sram write 0x%08x (0x%04x bytes)", SRAM_POINTER, nNumberOfBytesToWrite);
if (SRAM_POINTER + nNumberOfBytesToWrite >= SRAM_SIZE) {
nNumberOfBytesToWrite = SRAM_SIZE - SRAM_POINTER;
}
memcpy(SRAM + SRAM_POINTER, lpBuffer, nNumberOfBytesToWrite);
sram_dump();
*lpNumberOfBytesWritten = nNumberOfBytesToWrite;
return TRUE;
}
BOOL mxsram_ReadFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped) {
log_misc("mxsram", "sram read 0x%08x (0x%04x bytes)", SRAM_POINTER, nNumberOfBytesToRead);
if (SRAM_POINTER + nNumberOfBytesToRead >= SRAM_SIZE) {
nNumberOfBytesToRead = SRAM_SIZE - SRAM_POINTER;
}
sram_restore();
memcpy((LPVOID)lpBuffer, SRAM + SRAM_POINTER, nNumberOfBytesToRead);
*lpNumberOfBytesRead = nNumberOfBytesToRead;
return TRUE;
}
void setup_mxsram() {
// Allocate 2MB of SRAM
SRAM = (LPBYTE)malloc(SRAM_SIZE);
if (!SRAM) {
log_error(BOOT_LOGGER, "unable to allocate 2MiB for SRAM");
exit(1);
}
memset(SRAM, 0, SRAM_SIZE);
sram_restore();
file_hook_t* mxsram = new_file_hook(L"\\\\.\\mxsram");
mxsram->SetFilePointer = &mxsram_SetFilePointer;
mxsram->ReadFile = &mxsram_ReadFile;
mxsram->WriteFile = &mxsram_WriteFile;
hook_file(mxsram);
}

289
src/micetools/dll/drivers/mxsuperio.c

@ -0,0 +1,289 @@
#include <Windows.h>
#include "../lib/mice/mice.h"
#include "mx.h"
#include "smbus.h"
#include "w83791d.h"
BYTE w83791d_bank = 0x00;
BYTE w83791d_config = W83791D_CONFIG_START;
BYTE w83791d_noncrit_t1 = 75; // C
BYTE w83791d_crit_t1 = 80; // C
BYTE w83791d_noncrit_t2 = 75; // C
BYTE w83791d_crit_t2 = 80; // C
BYTE w83791d_noncrit_t3 = 75; // C
BYTE w83791d_crit_t3 = 80; // C
BYTE w83791d_vbat_monitor_control = 0x00;
BOOL w83791d_4f_high = 0;
BOOL mxsuperio_DeviceIoControl(DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer,
DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
mxsuperio_lpc_packet* lpc_packet = (mxsuperio_lpc_packet*)lpInBuffer;
mxsuperio_lpc_packet* lpc_out = (mxsuperio_lpc_packet*)lpOutBuffer;
switch (dwIoControlCode) {
case IOCTL_MXSUPERIO_PING:
log_misc("mxsuperio",
"DeviceIoControl(<mxsuperio>, <ping>, 0x%p, 0x%x, -, "
"0x%x, -, -)",
lpInBuffer, nInBufferSize, nOutBufferSize);
((LPDWORD)lpOutBuffer)[0] = 0x01000001;
if (lpBytesReturned) *lpBytesReturned = 4;
break;
case IOCTL_MXSUPERIO_READ:
log_warning("mxsuperio",
"DeviceIoControl(<mxsuperio>, <read>, 0x%p, 0x%x, -, "
"0x%x, -, -)",
lpInBuffer, nInBufferSize, nOutBufferSize);
/*
BYTE chipId = 0|1
BYTE ?? = 0x0b
BYTE ?? = 0x20|0x21
BYTE ret = 0
*/
switch (((LPBYTE)lpInBuffer)[2]) {
case 0x20:
((LPBYTE)lpInBuffer)[3] = 0xa0;
break;
case 0x21:
((LPBYTE)lpInBuffer)[3] = 0x20;
break;
default:
((LPBYTE)lpInBuffer)[3] = 0x00;
break;
}
if (lpBytesReturned) *lpBytesReturned = 4;
break;
case IOCTL_MXSUPERIO_HWMONITOR_LPC_READ: {
BYTE index = lpc_packet->index;
BYTE reg = lpc_packet->reg;
switch (w83791d_bank) {
case 0x00: {
switch (reg) {
case W83791D_REG_WCHIPID:
lpc_out->data = 0x71;
break;
case W83791D_REG_CHIPMAN:
if (w83791d_4f_high)
lpc_out->data = 0x5c; // High byte
else
lpc_out->data = 0xa3; // Low byte
break;
case W83791D_REG_I2C_ADDR:
lpc_out->data = 0x11;
break;
case W83791D_REG_BANK:
lpc_out->data = w83791d_bank;
break;
case W83791D_REG_CONFIG:
lpc_out->data = w83791d_config;
break;
case W83791D_REG_BEEP_CTRL_0:
lpc_out->data = 0xff; // All the beeps! (see main.h)
break;
case W83791D_REG_TEMP1_0:
lpc_out->data = 0x00; // TODO: Figure out the temp val lol
break;
case W83791D_RAM_VCOREA:
case W83791D_RAM_VNIR0:
case W83791D_RAM_12VIN:
lpc_out->data = 0x00; // TODO: Figure out the batt val
break;
case W83791D_RAM_FAN1:
case W83791D_RAM_FAN2:
case W83791D_RAM_FAN3:
lpc_out->data = 0x00; // Fan no spinny!
break;
case W83791D_VID_FAN_DIV:
// Boths fans divide by 2 (01), VDD 5 latched
// good.
lpc_out->data = 0b01011111; // Let's not /0!
break;
case W83791D_VBAT_MONITOR_CONTROL:
lpc_out->data = w83791d_vbat_monitor_control;
break;
default:
log_error("mxsuperio", "Unknown HM b0 register: 0x%02x", reg);
exit(1);
}
} break;
case 0x01: {
switch (reg) {
case W83791D_REG_BANK:
lpc_out->data = w83791d_bank;
break;
case W83791D_NONCRIT_TEMP_1:
lpc_out->data = w83791d_noncrit_t1;
break;
case W83791D_CRIT_TEMP_1:
lpc_out->data = w83791d_crit_t1;
break;
case W83791D_NONCRIT_TEMP_2:
lpc_out->data = w83791d_noncrit_t2;
break;
case W83791D_CRIT_TEMP_2:
lpc_out->data = w83791d_crit_t2;
break;
case W83791D_NONCRIT_TEMP_3:
lpc_out->data = w83791d_noncrit_t3;
break;
case W83791D_CRIT_TEMP_3:
lpc_out->data = w83791d_crit_t3;
break;
case W83791D_VIN0:
lpc_out->data = W83791D_ENTITY_CPU;
break;
case W83791D_VIN1:
lpc_out->data = W83791D_ENTITY_SYSTEM;
break;
default: