13 jun 2024
fixPath, a tool created for making nix store concepts possible on Windows 10, see series libnix
fixPath
is 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.fixPath
section 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!
fixPath
show 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 @ 0x3894
change 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)
DONE
show 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 @ 0x3894
using 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 chars
note: 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!