create "no-op" version of a dll? - c++

Suppose I have an application app.exe which does a load-time link to d.dll, which in turn does a load-time link to dangerous.dll. Suppose that dangerous.dll is considered to have various security vulnerabilities. Suppose also that none of the functionality in dangerous.dll is needed by app.exe, and app.exe does not make any calls to d.dll that require it to use any functions in dangerous.dll.
I want to distribute the app without dangerous.dll, and ideally with minimal or no modifications to app.exe or d.dll. If I just remove dangerous.dll, I get a loading error when starting app.exe because it loads d.ll and d.dll tries to load dangerous.dll, which fails.
Option 1
I could make a "no-op" version of dangerous.dll, that provided all the same export function signatures as dangerous.dll, but had no-op code for all the exported functions themselves. That might not be too bad. I wonder if there already exists a tool that can take a .dll file and output another .dll file that has the same export functions, but ones that do nothing? This has the disadvantage that my no-op version of dangerous.dll would still be visible to the user, and it would look like my application still has the vulnerabilities in dangerous.dll.
Option 2
I wonder if there is some way, without building d.dll from source, I could hack d.dll so that it does not attempt a load-time load of dangerous.dll. It would be okay if this caused any calls from d.dll to a dangerous.dll function to fail/crash, since as I say app.exe should not cause d.ll to use any of the functions in dangerous.dll.

If you have the source for d.dll, then just fix it to not load/use dangerous.dll.
If you don't have the source, just build a dangerous.dll with stub implementations for all exported functions.
Case closed. Move on and spend your time on more productive stuff.

Related

Detect missing dlls by C++ program using it?

Is it somehow possible to run .exe without some of the (mainly 3rd party) dlls which may (or may not) be present? The reason for this is that if some of the drivers are not present, I want only to block using the HWs, not to block program execution.
For example: Run .exe which checks if there is desired .dll libraries and make action if not:
Warn user that some of the libraries are missing.
Forbid to use some part of code until the appropriate library is present.
I found out, that library checking is possible with function like this:
bool checkLibrary(std::string dllName) {
std::wstring stemp = std::wstring(dllName.begin(), dllName.end());
return LoadLibrary(stemp.c_str()) != NULL;
}
But when I run .exe, it shows me allways error, that .dll is missing. It looks like that OS or APP finds all dependecies before start of the .exe, but seems to be static linked. How link dlls dynamically when its functions is needed?
This is an option in Visual Studio. It's called Delay-Load Linking (/DELAYLOAD). By default, Visual Studio will set it up entirely for you, including the call to LoadLibrary.
Since you want to be notified about load failures, you'll need to set up a hook function. This will need to handle the dliFailLoadLib notification. Here you can show a custom error message, and set a "disabled" flag for your app's internal use.
Continuing with missing functions is a bit trickier. You'll need to handle more events though. If you set a "disabled" flag for internal use, you could just return &ExitProcessWrapper for each and every function that's not supposed to be called. This wrapper just calls ExitProcess(0), in case you overlooked something.
If you use headers you automatically link to library so on .exe loading it looks for that library. If you want to manually load DLL, you need to open it as you did and replace all calls by calls to place given by https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress

Using __gcov_flush within a library doesn't force the other modules to yield .gcda files

Lately I have been trying to use gcc/gcov to undertake code-coverage testing for a C++ project. The project consists of its main module and several .so libraries, which should all be taken into measurement.
I have compiled all the modules with --coverage parameter each with gcc and kept them where they were generated, together with corresponding .gcno tag files. After a normal execution and graceful exit the .gcda files could be properly generated.
The problem is, the program is supposed to be a services without interruption or termination, and it's not allowed to insert any customized code (like a signal handler) into the main module. As the solutions from the web suggest, I wrote a signal handler function in a standalone .so library, which invokes __gcov_flush on receiving SIGUSR1 signal to flush the runtime coverage counters to files.
However, it was observed that, while the __gcov_flush function is guaranteed to be properly invoked, only the .gcda file of the .so library is generated during runtime. It seems to me that __gcov_flush is in charge of flushing the data of the wrapper module but not the others. I wonder if this is how it is supposed to work, or is there some tricks I need to take care of to generate complete results?
I see two problems here.
If your executable loads several shared libraries it is quite hard
to get the functionality needed. The linker adds profiling code from
libgcov.a for every shared library and it is hard to call every
library's __gcov_flush() from one central place like signal handler
defined in yet another shared library.
The function __gcov_flush() function from libgcov.a is declared
with __attribute__ ((__visibility__ ("hidden")))
If you extract _gcov.o from the archive and run
objdump -t _gcov.o
you see something like
_gcov.o: file format elf32-littlearm
SYMBOL TABLE:
000014b4 g F .text 00000016 .hidden __gcov_flush
Linker doesn't export hidden symbols even if you ask it to do that
as it mentioned here or here
So I see two solutions for the second problem.
You may try to edit symbol table for _gcov.o in libgcov.a and
set visibility to "default" instead of "hidden". I didn't take
that way because I didn't find any good elf editor.
If you managed to do that make sure to update your link command so
it links this patched _gcov.o instead of default one from
libgcov.a. Basically, you need to remove --coverage option from
your linker flags for that.
You may create a wrapper for __gcov_flush() declare and export it
as it suggested in the links above. Call this wrapper from your
signal handler in the shared library.
I suggest you not to add profiling for the small signal handler
library - it is really unnecessary.

utilizing a static library to create an import library

I am interested in using my static lib to create a dll (implicitly linking). which means I need to (in vs2008)
create a dll project that should generate the following:
header file (which have export function declarations. These are simple wrappers to actual functions in the static lib using __declspec(dllexport) which are in the .cpp )
import lib which will be made as a result of creating the dll
the actual dll which is created.
I have made a test program that will utilize the above dll(including the import lib/header files) to test it.
in this I have included all the three items. now the exe compiles/links without issue.
however in the main.cpp when i call the exported functions (with the associated __declspec(dllimport) call it never seems to execute. I am uncertain why this is?
Its almost like the even though the exe can see the exported function in in the dll...the dll cannot call on the code that is in the static lib?
i just cannot answer why my exe can't see the code in the static lib? do i need an archiver/librarian for vs2008 to include all those obj files as part of the import lib?
I am at a loss and am not sure how to test this?
other than just making my static lib directly into a dll. I wanted to try this method. I know i am missing something...i have read all over the place and i am just stuck. There were some threads here that had some people posting something similar but i can't seem to get it. please be as detailed as possible as I am new to this. thanks again.
update 1:
ok so currently i added the extern line to the function prototype and now it sees the exported function from the dll. however, now the only issue left is that:
i can't invoke the function that this exported function (aka wrapper) is trying to call. which happens to be in the static library. how should my exe get visibility to that static library function. I know it can be done because I think there was one other person on this board who was able to make this work.
update 2: my setup is exactly like this questioner...
How to force inclusion of an object file in a static library when linking into executable?
but i am not using explicit linking. i am using implicit linking. my real issue is how to call a static lib function in my dll wrapper which is exported to the exe?
If the app and DLLs are MFC app/dlls, then make sure that the application and all dlls are either "Debug" versions or "release" versions and not a mix.

Detecting / avoiding g++ symbol collisions

Is there a way to detect and avoid if two shared libraries both expose the same global scope symbols? We recently ran into a situation where we had libA.so that exported the SuperCoolMethod() and libB.so that also exposed the SuperCoolMethod() which would clobber the previous copy of said method. This is on Linux using g++ 4.0 and later. So in isolation if you link against libA.so everything would work as expected, but once libB.so was added to the picture the wrong method was called and the call would fail causing the executing thread to abort without notifying us of the potential problem. Through exhausting trial and error we eventually found the SuperCoolMethod() getting clobbered and notified the vendor of libB.so so that the __attribute__((visibility("hidden"))) can be applied to their copy of the method.
As this is C++ the libraries each ought to be in their own namespace so collisions do no occur.
dynamically loading the library and attaching the symbols via dlopen and dlsym would work. You would have to write code to do it but if you were really truly stuck it would be a solution
As a work-around, if you only use one of the two methods, the order in which they appear on the link command line determines which version of the function you end up with in the final executable.
This isn't just an artifact, it's defined behavior, so you can depend on it (until the vendor fixes it).

Trouble compiling dll that accesses another dll

So, I have an interesting issue. I am working with a proprietary set of dlls that I ,obviously, don't have the source for. The goal is to write an intermediate dll that groups together a large series of funnction calls from the proprietary dlls. The problem I am having, when compiling with g++, is that I get errors for the original dlls along the lines of:
cannot export libname_NULL_THUNK_DATA. Symbol not found.
If I add a main and just compile to an executable everything works as expected. I'm using mingw for compilation. Thanks for any help.
In response to the first reply: Either I'm confused about what you're saying or I didn't word my question very well. I'm not explicitly trying to export anything from my wrapper I am just calling functions from their dlls. The problem is that I get errors that it can't export these specific symbols from the dll to my wrapper. The issue is that I'm not even entirely sure what these _NULL_THUNK_DATA symbols are for. I did a search and read somewhere that they shouldn't be exported because they're internal symbols that windows uses. I have tried using the --exclude-symbols directive to the linker but it didn't seem to do anything. I apologize if I'm completely misunderstanding what you're trying to say.
So, I think my issue was related to this. When just compiling a standard executable that uses a dll I was able to include the headers and directly call the functions for example:
#include :3rdparty.h
int main(){
dostuff(); // a function in the 3rdparty.dll
}
this would compile and run fine. I just needed to link the libraries in the g++ command.
When linking with the -shared flag I would get these errors (with main removed of course). I think it has something to do with the fact that by default g++ attempts to import all symbols from the dll. What I didn't understand is why this happens in the dll vs in an executable. I will try doing it using GetProcAddress(). Thank you!
it should be as easy as you think it should be.
eg:
your dll code needs:
void doStuff()
{
3rdparty.login();
3rdparty.dostuff();
3rdparty.logoff();
};
so far - so good, you've included the right headers .... (if you have them, if you don't then you need to import the library using LoadLibrary(), then create a function pointer to each exported dll entrypoint using GetProcAddress() and then call that function pointer)
You then link with the 3rd party lib and that's it. Occasionally you will have to wrap the definitions with 'extern "C"' in order to get the linkage name mangling correct.
As you say you're using g++, you can't be getting confused with __declspec(dllimport) which is a MS VC extension.
"Compiling" tells me that you're approaching this from the wrong end. Your DLL should not export its own wrapper functions, but directly refer to exports from other DLLs.
E.g. in a Windows Kernel32.DEF file, the following forward exists:
EXPORTS
...
HeapAlloc = NTDLL.RtlAllocHeap
There's no code for the HeapAlloc function.