Does the external clause take care of both loading and unloading (LoadDLL/UnloadDLL). Or do I still have to unload DLLs manually?
With the external directive, the DLLs are not unloaded at all. In general, there's no reason to. With the external directive, the assumption is that you want to use the DLLs throughout the lifetime of the installer process. There's no clear point where Inno Setup can safely assume that it can unload the DLLs. So they get unloaded automatically by the system, once Inno Setup installer process exits.
Usually the only case, where you need to unload the DLL is a use of your custom DLL in the uninstaller, if you want to delete (uninstall) the DLL afterwards. For that use the UnloadDLL function.
Related
i'm trying to understand how dll hijacking works practically for educational purpose.
I also try to fund some countermeasure as i'm currently programming a software with a friend that contains dll and an executable in a archive.
Currently the best solution i found is to check checksum of dll loaded. Are there better solution ? I want avoid solution like check EV certificat etc...
According the exploitation of dll hijacking if i understand well, the attacker just need to replace the dll by a malicious dll that as malicious code that is executed in entrypoint ?
I have created a dll with messagebox code in c, and i have created a buggy code (executable) to make a proof of concept. This worked fine. (here the image : https://ibb.co/GpDF3sP)
But when i try test it with true software on market this doesn't work. (https://ibb.co/PDLxF59 and https://ibb.co/QJP4Hxj dll is not loaded after i changed it) Any idea ?
Attacker must create same DLL export table as in your DLL. Then he just load your original DLL module in fake one and pass all calls to it, so attacker's DLL will be used like a proxy for each call.
Honestly, if you're loading DLL statically with Windows PE loader, checksum and certificate are not so reliable methods. For example, if I have access to filesystem for write, I can replace your original DLL with fake one, start your process in suspended state, replace DLL to original behind your EXE module, resume your process execution (file moving operation is available even DLL file is using). And you can check DLL checksum and it will be correct for you, but actually you will use fake DLL which already loaded in memory.
For protect you may use algorithm:
Do not use static DLL linkage. Load DLL manually using LoadLibraryEx without calling DllMain with flag LOAD_LIBRARY_AS_IMAGE_RESOURCE
Verify checksum of DLL code in memory, not in the file. If checksum is not valid, do not do next steps
Load all DLL dependencies and call DllMain manually <-- this is most complicated step, so you need to resolve all DLL refs by hands
Load required DLL functions using GetProcAddress or by parsing DLL export table manually, and use them
Of course, this can not avoid checksum verification and it is complicated way, but you can prevent most of simple attack methods.
Depends on deep of implementation step #3, some of DLLs will not work, if you didn't implement thread local storage (TLS) calls
I've built a inproc com server dll which I can package as 1 file or many via the build utility py2exe. When I allow all the dependencies to remain external, I have no issues, but bundling as 1 file produces problems.
When the dll is utilized (either registering it or instantiating a com object from it), it immediately loads MSVCR90.DLL from the path c:\windows\winsxs\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.6871_none_50944e7cbcb706e5\MSVCR90.DLL no matter what I do, I can't change that. There is no information that I can find (using Dependency Walker) to indicate what is causing that to load. It just happens magically...
Then, later on it loads that dll again via an explicit call to LoadLibraryA("MSVCR90.dll") (part of some py2exe black box?), but this time it does not look into the winsxs manifests / directory. Instead it looks to the system path and/or will respect a dll redirection. That's when the problem occurs. If I set the system path to start with c:\windows\winsxs\x86_microsoft.vc90.crt...\ it will load the exact same dll and be happy - but if ANY other file is utilized - inclusive of a copy of the EXACT same dll - but at a different path - then the whole thing blows up. It can't handle using two different files.
How can I fix this? Ideally, I've love to make the initial magic loading of the dll draw upon a private assembly, but no matter what I do with manifests or .dll.local etc it will not respect that until this second dll loading takes place.
Note that with the non-bundled dll (external dependencies) it always uses the winsxs MSVCR90.DLL.
I can "fix" my failure to use the dll by forcing the system path to load the winsxs copy, but that is pretty useless for a deployable com server!
The reason is that you DLL has a manifest that tells the module loader to search also in the SxS storage.
You have several choices
Build your DLL using static linkage. Not using any of the MFC-DLLs (see project settings)
Don't use a side by side manifest for the DLL and still use the MFC DLLs. But beware you have to ship those DLL with your DLL in the local path (see DLL search sequence docs)
Use a later build of VS. Later versions of VS don't use the SxS storage any more and there are no manifests for those DLLs any more.
For the 2. see this article in code project. There is an update for VS-2008 [here].
2
Build your DLL
As part of a build process, several dll's and tlb's are registered to COM via regsvr32. There's a step at the end of the build which unregisters that same list of dll's and tlb's. However, that step does not run if the build fails early.
The problem is that subsequent builds do not always use the same build path and project builds fail due to them looking for registered dll's in the wrong place (since they're still registered in COM from a previous failed build).
The simple solution is to ensure that the unregister script runs at the end of every build regardless of fail or pass, however this is not so easy with our build tool. Is there another way to unregister dll's/tlb's without their original source file present in it's registered path?
You don't need to call unregister with the same dll as you registered with, you just need to know that the dll you are unregistering removes the same classes in its DllUnregisterServer method as the lost dll file did in its DllRegisterServer method.
With this in mind, you should be able to use the dll at the new path to unregister the one at the old path.
Maybe try changing your build process to unregister the dlls before registering them, it will clean up the dangling references to the lost dlls before registering the correct ones and you should be good to go.
I have two use cases: 1) loading a temporary DLL during a custom action and 2) executing a temporary EXE from a custom action. The custom action DLL is unmanaged C++. I cannot figure out how to get this working correctly. Including the DLL is easy enough but LoadLibrary is failing as it cannot find the DLL. I also cannot seem to get the physical path of the extracted DLL in order to specify full path in LoadLibrary. Any help is appreciated. I'm using WIX btw for this work.
If you have included the dll and the exe in the Binary Table of the msi, the files will be physically present in the %Temp% folder of the currently logged in user which gets mapped to SUPPORTDIR property of Windows Installer.
You need to use MsiGetProperty to get the SUPPORTDIR and use that in the LoadLibrary.
One thing to remember - Windows Installer usually extracts files from Binary table to %TEMP%, however - the current work directory is often set to c:\windows\installer.
My suggestion - extract the temporary .dll from Binary table yourself when you need it. This gives you the control of when it's saved to. Just remember that you need write permission to the location, so usually some subdir of %temp% is the best choice.
I am talking about win32 dlls, those plain pe files. I am confused after I doing a test compared to what I saw in explorer.exe process.
I wrote a test with following modules:(C++)
DLLLoader.exe links to A.dll in the same folder.
B.dll links to A.dll(2) in another folder. (A.dll(2) is a totally different DLL from A.dll, but with the same name)
DLLLoader.exe will load B.dll explicitly through ::LoadLibrary.
Now I start DllLoader.exe, firstly, A.dll will be loaded, but then when it tries to load B.dll, It just failed: I suspect that is because B.dll thinks A.dll is already loaded in process, but in fact, the loaded one is not the one B.dll wanted, the import/export table can't match, so B.dll is failed to load.
This seems to tell us we can't loaded 2 dlls of same name in the same process, even they are of different path.
But when I used process explorer to monitor loaded modules in Windows's explorer.exe process, I could see following 2 dlls being loaded, with same name:
comctl32.dll User Experience Controls Library C:\WINDOWS\WinSxS...\comctl32.dll
comctl32.dll Common Controls Library C:\WINDOWS\system32\comctl32.dll
Could any of you shed some lights on this?
It basically depens on if you load the dll with its full path or only by file name. The LoadLibraryEx docs cover this pretty well:
If lpFileName does not include a path
and there is more than one loaded
module with the same base name and
extension, the function returns a
handle to the module that was loaded
first.
See http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/b3eaa07f-7f92-4693-8aa1-b8fee0b92d2f/ for a good discussion on how this can be done implicitly for WinXP and up, by activation context (manifests) to control the loading.