I'm currently studying VSHADOW.EXE 3.0 from the MS Windows SDK 6.1. I have made a version which can be compiled into a DLL that only exports one newly written function which expects the commandline as a string, tokenizes it, and then calls the old wmain. The DLL is not a COM server.
It works exactly as the old one when compiled as an EXE but doesn't quite work when compiled as a DLL because this call fails:
CoInitializeSecurity(NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
RPC_C_IMP_LEVEL_IDENTIFY,
NULL, EOAC_NONE, NULL);
which fails with HRESULT error 0x80010119 (RPC_E_TOO_LATE, Security must be initialized before any interfaces are marshalled or unmarshalled. It cannot be changed once initialized.)
I run the exported function from a VB6 program where the function is imported with Declare Function vss Lib vshadow.dll ....
Does the error mean that the VB6 program already called CoInitializeSecurity? What can I do against the error?
Also, I have another question: why were exactly the security values RPC_C_AUTHN_LEVEL_PKT_PRIVACY and RPC_C_IMP_LEVEL_IDENTIFY chosen? What impact would other settings have?
There are a couple of standard COM calls that do not belong in a DLL. Like CoInitializeEx(), the call that initializes COM for a thread. The DLL doesn't own the thread, it is powerless to override the apartment state that the EXE selected.
CoInitializeSecurity() is another one, it is the job of the EXE to call it. Only it knows the proper values to pass, it's the one that determines the security policy. A DLL can't, it doesn't know anything about the client process.
Related
I want to call functions defined by caller of a dll from dll. I am working on a C/C++ application. Main application may or may not use certain dlls as per the configuration provided and both the sides(Main application and dll) need to invoke each others functions. These example explained fairly well how one can create a dll and call it's functions at runtime.
https://learn.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-dynamic-link-library-cpp?view=vs-2019
https://learn.microsoft.com/en-us/cpp/build/linking-an-executable-to-a-dll?view=vs-2019
However it doesn't explain how can I call functions defined in Main application from dll.
When I try to declare the same function in dll's headers it throws error saying failed to find function.
How can I tell to linker that certain function will be available at run time. In gcc there is --export-dynamic. This can be used for exporting the symbols and later shared object is able to use these symbols. Is there something similar in windows?
Edit:
Following discussion gives a possible solution, Here caller must pass the function to dll as argument.
How to call a function defined in my exe inside my DLL?
This will be little cumbersome to use in my situation. I am trying to port here a linux application on windows. There are many methods which are called by dll. Passing all of them to dll as function doesn't sound as a good idea however this can be doable as last resort. Other downside I see on taking this approach is, this will require Main application to be changed on every time plug in(dll) wish to use some new function of Main application.
I have the following situation:
I have a delphi application {$APPTYPE GUI}. (APP1)
If APP1 gets started, it runs the code between
begin and end., just as it should be.
Later, APP1 will be transformed to a DLL (another application will do that - APP2).
APP2 adds the IMAGE_FILE_DLL flag to the Characteristics in the NTFileHeader of APP1.
Then APP2 tries to load the DLL (APP1) with LoadLibrary (or some other COM Command to load a dll) but it returns the error:
Windows encountered an internal error while initializing COM
libraries.
I've done all this with a C project and used the WinMain function. However it seems not to work in Delphi (APP1 gets not started as a DLL). How is it possible to convert APP1 to a working DLL?
EDIT:
I'm trying to port this code from C to Delphi : http://level-23.info/forum/showthread.php?14721-UAC-Bypass-for-Windows-7-RTM-SP1-Windows-8-DP&p=31749
I've ported it correctly and everything works but the CRYPTBASE.dll (APP1) doesn't start . (See Error above)
In a nutshell:
Create a delphi application, add the IMAGE_FILE_DLL characteristics in the file header. Rename it to CRYPTBASE.dll and copy it to C:\Windows\System32\sysprep. Then start sysprep.exe
INFOS HERE: http://www.pretentiousname.com/misc/W7E_Source/win7_uac_poc_details.html
WinMain is a just a name, by convention, to use as the entry point of an executable. The convention for DLL's is to use the name DllMain. The Windows loader does not search for WinMain and LoadLibrary does not search for DllMain, it just calls the entrypoint in the pe header.
Delphi doesn't use either, the exported name of the entry point is start.
WinMain signature differs from DllMain (WinMain takes four parameters), my suggestion is to declare a function DllMain and export it in your exe:
function DllMain(hinstDLL: THandle; fdwReason: DWORD; lpvReserverd: Pointer): BOOL; stdcall;
begin
// do something
end;
exports
DllMain;
The code that modifies your exe (in mem I presume) to be a dll should set the entry point to DllMain (get it's address by walking the EAT).
Also: make sure that the relocation table it not stripped (in release mode) as DLL's require it when they are rebased.
I don't think you should do that at all. Code is compiled with different assumptions when building EXE and DLLs, it will not work if you simply flip the flag and change the extension.
Trying something like that is a good way to experiment and learn stuff but it's a bad idea for production.
Tell us what are you trying to achieve, in more concrete terms than "To run my DLL as EXE". Why do you need to run your DLL as EXE?
For instance, you can build DLL and then load and call it with rundll32. If you need this for COM, you can build an COM host exe and rely on COM's automatic marshalling to achieve the effect of "as if my code was in the same process". It's all already present in COM.
Apologies in advance for the following verbose question ; I am a COM noob.
Scenario: I need to call a managed DLL built with C# from native Visual C++ code. In my native VC++ code, I do the following after registering "SomeDLL.dll" and generating the "SomeDLL.tlb" file with RegAsm.exe.
Import the TLB file with #import "SomeDLL.tlb"
Use the class MyClass defined in the DLL with CComPtr<MyClass>.
Everything's great! It compiles, and I can run the code etc. It hits the fan when I try to run this application on a different machine (i.e. not the one I compiled it on). I copy all the required DLLs, and I register the same DLL with RegAsm.exe but it doesn't work.
It specifically fails when it tries to initialize the COM library with CoInitialize(0) and returns the S_FALSE error which means
The COM library is already initialized on this thread.
I can confidently state that I have not called this function anywhere else in my code.
Any suggestions?
Hard to help you find that code from here, you're a lot closer. Maybe a DLL that gets injected.
Getting S_FALSE is not an error, getting RPC_E_CHANGED_MODE would be quite bad. Be sure to use the FAILED macro:
HRESULT hr = CoInitialize(0);
if (FAILED(hr)) {
CallNineOneOne(hr);
exit(hr);
}
Maybe you called OleInitialize or another function which calls ComInitialize behind the scenes.
Anyway, it does not matter to call CoInitialize several times per thread if you match each of them with a call to CoUninitialize
For various reasons (questioning the reasons is not helpful to me), I'd like to implement my own extended mapi dll for windows xp. I have a skeleton dll now, just a few entrypoints exist for testing, but the system mapi stub (c:\windows\system32\mapi32.dll, I've checked that it's identical to mapistub.dll) will not pass through calls to my dll, while it happily passes the same calls through to MS Outlook's msmapi32.dll, (MAPIInitialize, MAPILoginEx are two such calls). There's some secret handshake between the stub and the extended mapi dll wherein the stub checks that "yup, it's an extended mapi dll": maybe it's the presence of some additional entrypoints I haven't implemented yet, maybe it's the return value from some function, I don't know. I've tried tracing a sample app I wrote that calls MAPIInitialize with STraceNT and ProcessMonitor but that didn't show anything obvious. Tracing has shown that indeed the stub loads my dll, but then finds the secret sauce is missing apparently, and returns an error code instead of calling my dll's function. What more could be needed for calling MAPIInitialize than the presence of MAPIInitialize in my dll's exports table? GetProcAddress says it's there.
What I'd like to know is how to minimally extend my skeleton extended mapi dll so that the stub mapi dll will pass through extended mapi calls to my dll. What's the secret sauce? I'd rather not spend a painful week in msvc reverse engineering the stub behavior.
Figured it out by loading MS's debugging symbols and diving in to the stub library code in the debugger. The stub library doesn't load "MAPIInitialize", it loads "MAPIInitialize#4". I added MAPIInitialize#4=_MAPIInitialize#4 to my EXPORTS section of the .def file and all works fine now.
By the way, in order to get symbols for system libraries, don't download MS's debugging symbol package for XP SP3, the symbols were not updated correctly and won't work in the debugger. Instead point VS to MS's online symbol server (http://msdl.microsoft.com/download/symbols) and let VS slurp the symbols to a local symbol cache directory.
The canned DllMain for MFC 8.0 does not seem to call ExitInstance when it gets a DLL_PROCESS_DETACH. One possible solution is to define my own DllMain, but how do I tell the linker to use mine and not MFC's?
Or, is there another override which gets called on DLL_PROCESS_DETACH I'm not aware of?
I have had similar issues for a project compiled with /clr. Are you in the same situation? I was never able to trace it to a specific condition, but changing some static initializers to set null cleared it up. I think it has something to do with the order that static destructors are registered.
I'm not sure why your ExitInstance isn't called, but it's possible to define your own DllMain by copying the contents of MFC's dllmodul.cpp file into a file in your dll and adding any extra required functionality. The procedure is documented in this MS knowledge base article. Though it was written for MFC 4.0, I have used this method successfully for apps using MFC 8.0.