switch to live patching MSIL approach

This commit is contained in:
itsmattkc 2024-04-19 13:40:33 -07:00
parent 356bf0888e
commit 61e8ac5840
19 changed files with 116 additions and 4 deletions

View file

@ -35,6 +35,11 @@ jobs:
cd build
cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release
cmake --build .
- name: Generate patched MSIL
shell: cmd
run: |
msil\patch.bat
- name: Build installer
shell: cmd

BIN
bin/ildasm/1033/IlDasmrc.dll Executable file

Binary file not shown.

BIN
bin/ildasm/1033/TrackerUI.dll Executable file

Binary file not shown.

BIN
bin/ildasm/1033/flogvwrc.dll Executable file

Binary file not shown.

BIN
bin/ildasm/1033/gacutlrc.dll Executable file

Binary file not shown.

BIN
bin/ildasm/1033/pevrfyrc.dll Executable file

Binary file not shown.

BIN
bin/ildasm/1033/snrc.dll Executable file

Binary file not shown.

BIN
bin/ildasm/ildasm.exe Executable file

Binary file not shown.

6
bin/ildasm/ildasm.exe.config Executable file
View file

@ -0,0 +1,6 @@
<?xml version ="1.0"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<requiredRuntime safemode="true" imageVersion="v4.0.30319" version="v4.0.30319"/>
</startup>
</configuration>

BIN
bin/patch/patch.exe Normal file

Binary file not shown.

View file

@ -1,5 +1,5 @@
# Patched MSIL/managed code DLLs
This folder contains managed code DLLs that have been manually patched to redirect or remove references to Win32 APIs that do not exist on Windows 95. They have been edited with [https://github.com/dnSpy/dnSpy](dnSpy).
This folder contains patches for managed code DLLs to redirect or remove references to Win32 APIs that do not exist on Windows 95. They are applied to the MSIL that can be generated using `ildisasm` (in the `bin` folder) and reassembled with `ilasm` (in `bin/dotnetfx20/URTInstallPath`). For ease of use, a `patch.bat` script is provided which should automate this process.
.NET appears to use a hashing/signing system that will prevent these DLLs from getting installed into the Global Assembly Cache (GAC) by any normal means. Instead, the installer installs the original DLLs into the GAC and then clobbers them with these patched DLLs at the end. The hash/signing check is never done again so this ends up working, even though it is a hacky solution. There may be a better one I'm not aware of.

Binary file not shown.

View file

@ -0,0 +1,20 @@
--- System.Windows.Forms.asm.original 2024-04-19 12:15:06.880649435 -0700
+++ System.Windows.Forms.asm 2024-04-19 12:16:01.487091612 -0700
@@ -58528,7 +58528,7 @@
IL_000f: ret
} // end of method UnsafeNativeMethods::CreateMenu
- .method public hidebysig static pinvokeimpl("comdlg32.dll" autochar lasterr winapi)
+ .method public hidebysig static pinvokeimpl("corkel32.dll" autochar lasterr winapi)
bool GetOpenFileName([in][out] class System.Windows.Forms.NativeMethods/OPENFILENAME_I ofn) cil managed preservesig
{
}
@@ -59879,7 +59879,7 @@
[in][out] object& marshal( interface ) pAcc) cil managed preservesig
{
}
- .method public hidebysig static pinvokeimpl("user32.dll" nomangle autochar winapi)
+ .method public hidebysig static pinvokeimpl("corusr.dll" nomangle autochar winapi)
void NotifyWinEvent(int32 winEvent,
valuetype [mscorlib]System.Runtime.InteropServices.HandleRef hwnd,
int32 objType,

Binary file not shown.

View file

@ -0,0 +1,19 @@
--- System.configuration.asm.original 2024-04-19 13:20:09.458249700 -0700
+++ System.configuration.asm 2024-04-19 13:22:09.844507556 -0700
@@ -8,6 +8,7 @@
.module extern kernel32.dll
.module extern crypt32.dll
.module extern advapi32.dll
+.module extern corkel32.dll
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
@@ -71914,7 +71915,7 @@
.field static assembly literal int32 GetFileExInfoStandard = int32(0x00000000)
.field static assembly literal int32 MOVEFILE_REPLACE_EXISTING = int32(0x00000001)
- .method assembly hidebysig static pinvokeimpl("kernel32.dll" autochar lasterr winapi bestfit:off)
+ .method assembly hidebysig static pinvokeimpl("corkel32.dll" autochar lasterr winapi bestfit:off)
bool GetFileAttributesEx(string name,
int32 fileInfoLevel,
[out] valuetype Microsoft.Win32.UnsafeNativeMethods/WIN32_FILE_ATTRIBUTE_DATA& data) cil managed preservesig

Binary file not shown.

42
msil/mscorlib.patch Normal file
View file

@ -0,0 +1,42 @@
--- mscorlib.asm.original 2024-04-19 12:55:04.782157988 -0700
+++ mscorlib.asm 2024-04-19 12:57:54.287832486 -0700
@@ -11,6 +11,7 @@
.module extern kernel32.dll
.module extern mscorwks.dll
.module extern oleaut32.dll
+.module extern corkel32.dll
.module extern advapi32.dll
.module extern ole32.dll
.module extern user32.dll
@@ -367275,19 +367276,19 @@
native int mustBeZero) cil managed preservesig
{
}
- .method assembly hidebysig static pinvokeimpl("kernel32.dll" autochar lasterr winapi bestfit:off)
+ .method assembly hidebysig static pinvokeimpl("corkel32.dll" autochar lasterr winapi bestfit:off)
int32 GetLongPathName(string path,
class System.Text.StringBuilder longPathBuffer,
int32 bufferLength) cil managed preservesig
{
}
- .method assembly hidebysig static pinvokeimpl("kernel32.dll" autochar lasterr winapi bestfit:off)
+ .method assembly hidebysig static pinvokeimpl("corkel32.dll" autochar lasterr winapi bestfit:off)
int32 GetLongPathName([in] char[] path,
[out] char[] longPathBuffer,
int32 bufferLength) cil managed preservesig
{
}
- .method assembly hidebysig static pinvokeimpl("kernel32.dll" autochar lasterr winapi bestfit:off)
+ .method assembly hidebysig static pinvokeimpl("corkel32.dll" autochar lasterr winapi bestfit:off)
int32 GetLongPathName(char* path,
char* longPathBuffer,
int32 bufferLength) cil managed preservesig
@@ -367675,7 +367676,7 @@
class System.Text.StringBuilder lpBuffer) cil managed preservesig
{
}
- .method assembly hidebysig static pinvokeimpl("kernel32.dll" autochar lasterr winapi bestfit:off)
+ .method assembly hidebysig static pinvokeimpl("corkel32.dll" autochar lasterr winapi bestfit:off)
bool GetFileAttributesEx(string name,
int32 fileInfoLevel,
valuetype Microsoft.Win32.Win32Native/WIN32_FILE_ATTRIBUTE_DATA& lpFileInformation) cil managed preservesig

20
msil/patch.bat Normal file
View file

@ -0,0 +1,20 @@
@echo off
setlocal
cd /d %~dp0
mkdir build
mkdir temp
cd temp
goto patchFiles
:doPatch
..\..\bin\ildasm\ildasm.exe /out=%~1.asm ../../bin/dotnetfx20/URTInstallPath/%~1.dll
..\..\bin\patch\patch %~1.asm ..\%~1.patch
..\..\bin\dotnetfx20\URTInstallPath\ilasm.exe /dll %~1.asm
copy %~1.dll ..\build
goto :eof
:patchFiles
call:doPatch System.Windows.Forms
call:doPatch mscorlib
call:doPatch System.configuration

View file

@ -5583,11 +5583,11 @@ File /r "..\wrappers\build\*.dll"
!insertmacro Check95 0 SkipNET20MSILPatches
SetOutPath $WINDIR\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089
File "..\msil\System.Windows.Forms.dll"
File "..\msil\build\System.Windows.Forms.dll"
SetOutPath $WINDIR\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089
File "..\msil\mscorlib.dll"
File "..\msil\build\mscorlib.dll"
SetOutPath $WINDIR\assembly\GAC_MSIL\System.Configuration\2.0.0.0__b03f5f7f11d50a3a
File "..\msil\System.configuration.dll"
File "..\msil\build\System.configuration.dll"
SkipNET20MSILPatches: