13 jun 2024
fixPath, a tool created for making nix store concepts possible on Windows 10, see series libnix
fixPathis a tool to modify the path to a certain DLLs (Dynamic Shared Objects) for Microsoft Windows Executables by rewriting parts of the executable’s PE header, when the.fixPathsection is present and indicates support for such rewrite, but without having to realign the PE headers. In concept, it is similar to patchelf but instead of changing search paths, fixPath hard-codes each DLL to a particular filepath.
see fixPath project page:
release with prebuilt fixPath.exe tool + test program:
fixPath?windows does not have an implementation of the rpath concept unix
systems have. as a result you have to move the libraries into the same
folder as the executable. in theory one could use symlinks instead of
copies also. With fixPath you can have the libraries in the
c:\nix\store and only have to modify the PE header similar
to patchelf on Linux.
a hope of mine is that we as a community can motivate Microsoft to
continue work on rpath support for Windows but since this requires
changes on the proprietary side of the linker loader there is nothing to
be done from outside Microsoft. in that regard fixPath is a
valuable alternative which luckly works as the library field,
i.e. KERNEL32.dll, inside the Imports Section supports
absolute/relative paths already.
nixPath is the result of a blog post by Jussi, see https://nibblestew.blogspot.com/2019/05/emulating-rpath-on-windows-via-binary.html.
thanks Jussi!
for details, read https://github.com/nixcloud/fixPath
the picture below shows the SectionsHeader in ImHex with the newly added
.fixpath section:
the picture below shows the DLLName hint in ImHex
somewhere in .rdata:
note: the library names have lots of empty space so that later changes don’t require PE relocations which are very complicated.
when using the lld linker (from LLVM), instead of the
default ld linker from binutils and using this lld branch
https://github.com/llvm/llvm-project/compare/release/18.x...qknight:llvm-project:libnix_PE-fixPath,
you can get the `.fixPath PE section added
automatically!
fixPathshow library status:
$ fixPath.exe -l test_mylib.exe
TARGET:
 - test_mylib.exe
 - fixPath version: 2
 - fix_path_size: 301
IMPORTS
 - 1, mylib.dll @ 0x4274
 - 2, KERNEL32.dll @ 0x43c1
 - 3, VCRUNTIME140D.dll @ 0x450e
 - 4, ucrtbased.dll @ 0x465b
DELAYED IMPORTS
 - 1, delayedlib.dll @ 0x3894change mylib.dll library into absolute path:
$ fixPath.exe -s test_mylib.exe mylib.dll c:\some\location\mylib.dll
TARGET:
 - test_mylib.exe
UPDATE mylib.dll @ 0x4274 -> c:\some\location\mylib.dll (modified)
DONEshow updated library status:
fixPath.exe -l test_mylib.exe
TARGET:
 - test_mylib.exe
 - fixPath version: 2
 - fix_path_size: 301
IMPORTS
 - 1, mylib.dll @ 0x4274 -> c:\some\location\mylib.dll (modified)
 - 2, KERNEL32.dll @ 0x43c1
 - 3, VCRUNTIME140D.dll @ 0x450e
 - 4, ucrtbased.dll @ 0x465b
DELAYED IMPORTS
 - 1, delayedlib.dll @ 0x3894using the fixPath concept this works:
* [x] dll import supports absolute paths
* [x] dll import supports relative paths like `lib\lib.dll`
* [x] works with long filename : "c:\t\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.dll"
* [x] works with long directory: "c:\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\t.dll"
* [x] works with "C:\t\nix\store\zxxialnsgv0ahms5d35sivqzxqg1kicf-libiec61883-1.2.0\lib\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.dll" 213 chars
* [x] works with "C:\t\nix\store\zxxialnsgv0ahms5d35sivqzxqg1kicf-libiec61883-1.2.0\lib\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.dll" 269 charsnote: an override with absolute/relative path will always cause the linker-loader on Windows 10 to use exactly this library and another copy with the same name in the binary’s directory won’t override this!
fixPath concept work needs reviewi hope to get developers interested in fixPath concepts
and motivate Microsoft to also support rpath in PE!