#40446: Obscure issue compiling/linking Windows binaries from Linux using mingw Open Date: 2020-05-26 07:19 Last Update: 2020-05-26 10:50 URL for this Ticket: https://osdn.net//projects/mingw/ticket/40446 RSS feed for this Ticket: https://osdn.net/ticket/ticket_rss.php?group_id=3917&tid=40446 --------------------------------------------------------------------- Last Changes/Comment on this Ticket: 2020-05-26 10:50 Updated by: keith * Status Update from Open to Closed * Resolution Update from None to Invalid Comment: I'm sorry, but this COLLECT_GCC=x86_64-w64-mingw32-gcc is not a MinGW product; indeed, that "mingw" appears in its name is a trademark infringement. As the legitimate owners of that trademark, we do not support such illegitimately distributed products. --------------------------------------------------------------------- Ticket Status: Reporter: thecolonial Owner: (None) Type: Issues Status: Closed Priority: 3 MileStone: (None) Component: (None) Severity: 5 - Medium Resolution: Invalid --------------------------------------------------------------------- Ticket details: Hi, I've recently been working on providing support to build Windows Meterpreter binaries using mingw via CMake on Linux. The project source can be found here: https://github.com/OJ/metasploit-payloads/tree/cross-compile-linux/c/ meterpreter I think it's fair to say that the kind of stuff Meterpreter does is a little "non standard" compared to most C/C++ projects and so I expected to come up against some edge case issues.For the most part it has gone very well, but I stumbled on something yesterday that has taken me a solid day of debugging to get to the bottom of. I'll do my best to describe in detail and provide links to the relevant things so that the mingw developers can get themselves to the point that I was to reproduce the issue. Meterpreter is made up of a number of components. A core component called metsrv is what's loaded first, and from there a number of other components (extensions) can be loaded on the fly. One of the extensions is called kiwi, which is made up of functionality pulled from a project called Mimikatz by Ben Delpy, the source if which can be found here: https://github.com/gentilkiwi/ mimikatz The kiwi extension makes some modifications to this project allowing it be loaded using Reflective DLL Injection. This technique was developer by Stephen Fewer, the source can be found here: https://github.com/stephenfewer/ ReflectiveDLLInjection So metsrv is loaded via RDI, it can then load kiwi via RDI. Nothing too complex so far. The kiwi source is definitely complex. Mimikatz does crazy things with the internals of Windows via obscure APIs. In order to support various versions of Windows it has to include a few custom made libraries that are shipped with the project in the lib subfolder. Prior to undertaking this task, we were able to build all the components of the project cleanly with VS 2013/2017/2019 and the binaries would work as expected. I was having the same experience porting things to mingw on Linux until I reached the kiwi extension, which resulted in the issue that I thought I'd log here. Invocation of the features of the binary would result in the program crashing. After debugging, I realised that all IAT function pointers that should have been imported from advapi32.dll were set to NULL. This seemed a little strange, because all other IAT entries looked fine. Then after many hours of digging, I noticed that there was something odd going on with the Import descriptors. Please refer to the following image: https://i.imgur.com/zXynXJp.png This image is a screenshot from PE-Bear, a PE analysis tool, and it shows the imports for the resulting ext_server_kiwi.x64.dll binary that is generated from mingw. Things to note: • Only 6 functions are imported from WINSTA.dll, though PE Bear reports that it has 105. • The list of functions that are imported contain references to functions loaded from advapi32.dll. • The RVA of the first thunk for advapi32.dll appears in the list of functions for winsta.dll. Ultimately, the root of the issue is that the import descriptor for winsta.dll is not terminted with a NULL entry. So what happens at runtime is that the DLL loader iterates through all the winsta.dll functions first, correcty resolves them using LoadLibrary and GetProcAddress, and stores the pointers in the IAT. As soon as it hits the first entry for advapi32.dll (in this case A_SHAFinal) it attempts to call GetProcAddress with an invalid module base (because it's reusing WINSTA.dll's base) and hence the call will result in NULL. The net result is that all of the advapi32.dll import entries are set to NULL. I modified the reflective DLL injection code so that it doesn't assume that a NULL terminator is present. It will also look at the next set of import characteristics and make sure that it doesn't go past the first thunk. This change resulted in everything working fine. This problem isn't present in the VS compilers/linkers I've used and hence I think it might be an issue specific to mingw. I do have a working solution, but I think there could be something that may impact other people if we don't get to the bottom of it. Hopefully it's specific to my project alone, however I don't think it is. Maybe it's an edge case that mingw doesn't yet cover. I think this is a linker issue rather than a compiler issue, but that's obviously up to people with more knowledge than me to determine. I wouldn't consider this the highest priority, given that it's rather edge case and you probably haven't seen it before despite the long history of the mingw project. If you need any more clarification on the issue, or links to sources etc, please let me know. I can provide binaries if required. Many thanks for your time and for the great work you folks do this project. Best regards OJ / @TheColonial -- Ticket information of MinGW - Minimalist GNU for Windows project MinGW - Minimalist GNU for Windows Project is hosted on OSDN Project URL: https://osdn.net/projects/mingw/ OSDN: https://osdn.net URL for this Ticket: https://osdn.net/projects/mingw/ticket/40446 RSS feed for this Ticket: https://osdn.net/ticket/ticket_rss.php?group_id=3917&tid=40446