Can you retrieve source from a debug-compiled binary? - c++

I was digging around and found an executable for something I wrote in Visual C++ 6.0 about 8 years ago. I never backed up the source code, but I think I always compiled everything in debug mode. I also vaguely remember hearing somewhere that "you can't decompile an executable into source code unless you have your compiler's debugging symbols or something." The code would have sentimental value, but its not mission-critical that I retrieve it.
That's the background; here are the questions:
How do I check if an executable was compiled in debug mode or not?
If it is, what information comes with a debug mode executable?
Can I retrieve full source code? Failing that, can I get any substantial improvement when decompiling compared to a release version? If so, how?
Thanks,
-- Michael Burge

I do not believe there is a flag though you might find something by using PEDUMP which will dump out COFF file formats (Windows EXE and DLLs). You can infer if an executable was compiled for debug rather quickly by running Dependecy Walker and seeing if your EXE is linking to any debug DLLs (suffixed with D, e.g. MSVCRT5D.DLL).
FYI in VC6 Debug and Release are simple named builds, not modes per say, each build a collection of compiler and linker settings. The EXE is just code, debug exes normally not having been optimized which makes using a debugger with it easy (versus debugging optimized code). Thus you can compile a Release binary with Debug Symbols which is sometimes useful for tracking down optimized code errors.
Debug EXEs and DLLs did not contain any debugging information but instead had a sidecar PDB file that resided in the same folder and contains all the debugging symbols information that was produced during compilation.
No, source is source and not compiled into the symbols file or executables. There are some amazing decompilers out there that can regenerate decent C versions of your code but they are amazing only in how good the C is, not in how well they can recreate your source.

With Visual Studio, I am afraid you can't, since the debug executable doesn't contain the source. Visual Studio generates pdb files that only contains the mapping between the binary and the sources filenames and line numbers, but you still need the source code with them. That might be different with gcc, which I think integrate the source itself inside the binaries.

I think that many disassemblers can show the source if a binary is compiled in debug mode. For example, I use OllyDBG and it has an option to show the source, although I've never tried.

Related

Debugging shared library .so with JNI using gdb

I have java application which is calling c/cpp code (it is .so files) using JNI.
I am using API's from this .so files. I have to debug .so files, how to debug it?
I tried below things:
I attached gdb to xyz.so and add breakpoints.
run java code
but not able to hit breakpoint.
can you suggest how to debug it.
after breakpoint, I can not run r or c (continue).
so how can we debug in such case?
thanks in advance.
When you compile something, as output, you have assembly code (which is run by the computer) and the symbols (which are the association between your source code and the assembly code).
In order to debug the C/C++ part, you must have the appropriate symbols in order to be able to place a break point with the same user experience you have in java. Otherwise, you'll just see a huge sequence of numbers and what you are doing is actually reverse engineering the code.
Therefore, you need the symbols which are not shipped by default (you should ask the vendor if they can provide them).

should I link to Debug or Release dll with same name?

I was working on a MS Visual Studio project and noticed that the Debug build was Linking to a Release library (DLL), when a Debug library with the same name was also available. I switched the path to Link the Debug library, and it seems to still work. Is there any way to know if my change was correct?
Additional Information:
Using the debug DLL triggers a small memory leak that wasn't triggered with the release DLL. Or possibly that is debug related cache data. That leak made me question if it was including the lib headers without _DEBUG somehow. Thus this question.
It is the preferred way to link Debug builds of your program with Debug version of external dynamic libraries as it guarantees that uniform Visual C++ runtime libraries will be used. Mixing libraries built in Debug and Release mode will result in both Debug and Release VC++ runtimes being linked and annoying linker warnings about multiple symbol definitions in conflicting Debug/Runtime libraries.
Sometimes it may be inevitable as i.e. only Release version of some external library may be available. Hence in VC++ there are linker settings allowing to ignore some specific libraries. So you may start checking in the Linker-Input settings of the Debug build if such ignores are already defined for existing conflicts. With some luck you might be able to remove them now.
If using the Debug version of some library breaks the whole program it might be an insight how to improve the whole system, it is that what a Debug build is for anyway.
Assuming that it is the right library (as in the same code compiled to a different configuration), you are right to link to the debug dll on your debug configuration (and should link to the release dll on your release configuration).
The differences tend to be related to the optimisation level (Debug is usually compiled without any optimisation at all) and any symbols that might be included to make it easier to develop with and maybe step into.

Finding all libraries and header files forming a C++ executable

If I have a C++ source file, gcc can give all its dependencies, in a tree structure, using the -H option. But given only the C++ executable, is it possible to find all libraries and header files that went into its compilation and linking?
If you've compiled the executable with debugging symbols, then yes, you can use the symbols to get the files.
If you have .pdb files (Visual studio creates them to store sebugging information separately) you can use all kinds of programs to open them and see the source files and methods.
You can even open it with a text editor and you'll see, among the gibrish, a list of the functions and source files.
If you're using linux (or GNU compilers in general), you can use gdb (again only if you have debug symbols enables in compilation time).
Run gdb on your executable, then run the command: info sources
That's an important reason why you should always remove that flag when going into production. You don't want clients to mess around with your sources, functions, and code.
You cannot do that, because that executable might have been build on a machine on which the header files (or the C++ code, or the libraries) are private or even generated. Also, if a static library is linked in, you have no reliable way to find out.
In practice however, on Linux, using nm or objdump or ldd on the executable will often (but not always) gives you a good clue about the needed libraries.
Also, some executables are dynamically loading a plugin e.g. using dlopen, so your question might not have any sense (since that plugin is known only at runtime).
Notice also that you might not know if an executable is obtained by compiling some C++ code (you might not be able to tell if it was obtained from C, C++, D, or Ocaml, ... source code, or a mixture of them).
On Linux, if you build an executable with static linking and stripping, people won't be able to easily guess the source programming language that you have used.
BTW, on Linux distributions, it is the role of the package management system to deal with such dependencies.
As answered by Yochai Timmer if the executable contains debug information (e.g. in DWARF format) you should be able to get a lot more information.

how to debug a release version of library in Visual Studio

I need to debug the release version of my linked library. I am already generating debug information with my release build following this article but how can I do the same with the library project? Note that library project doesn't have link page in properties where debug information is created in the link above. I am using VS2010.
What I really want is to make TRACE work whlile debugging the library. I tried to link debug version of library with the release exe but it creates linker errors.
What I really want is to make TRACE work...
You mean the MFC TRACE macro? The one that writes messages to the debug/output window of the debugger?
Unfortunately, even if you do fix your build settings so that your final executable contains debug information for your static library it won't bring back those trace statements. TRACE is a macro and therefore is handled by the compiler preprocessor. When you compile in release mode, that macro is redefined to be a no-op. It's as if the TRACE statement was deleted from the source code.
Even if you do resolve the problem of adding debug symbols to your library and executable, it won't bring those trace statements back. They were removed during the compile phase.
So what to do? Turns out, if you dig deep enough into those macros, they are ultimately calling a Win32 function OutputDebugString. This call is available in both debug and release versions of the ms libraries. So ... you could replace the trace macros with explicit calls to OutputDebugString - it's not as convenient to code with but at least you will get your debug output in release mode.
BTW, I finally gave up on all those macros years ago and we have completely replaced them with log4cplus calls. Any logging framework would be better than the trace macros - because the time when you really need tracing is not when you are debugging but when your code is in production and you cannot reproduce the problem locally. It's much better to log to a file which the customer can send to you, then rely on tracing that only works in the debugger. Something to consider anyways...
A static library isn't linked, so it's no surprise that linker options are unavailable. You basically just need to tell the compiler to produce debugging information. From there, creating the library is little more than putting a bunch of object files together into a single file.
So basically, just tell the compiler to produce debug information, and the library will contain debug info.

Is it possible to strip debug information from a COFF library file (.lib)?

I am linking with a number of 3rd party .lib files, and I get a large number of LNK4099 warnings at link time. It appears that this warning message cannot be supressed, so I believe that if I remove all debug information from the .lib files, the warning will not be shown. Is there a way to remove the debug information? These are libraries that I do not have the source code for.
I am using VS2005 C++ (on Windows of course).
I don't think it is possible, at least with not with conventional tools. I would recommend you contact the vendor and request that they rebuild the .lib file without debug information.
COFF format - as found on Unix, at any rate, is reasonably well organized. There are lots of sections in it. There was also a tool, mcs for 'manipulate comment section' which could be used to remove material. The tool is available on Solaris for ELF (which is an extension of COFF), and probably elsewhere.
What this might mean is that you can find the program and use it on the MS object files.
On the other hand, it seems unlikely that the complaints would be resolved by removing the debug information; the debug information should not affect the running (or linking) of the program. That said, the information found via Google 'microsoft lnk4009' is non-conclusive; two entries appear, but both end up showing 'LNK4099' rather than 'LNK4009' messages.
I guess you have already read this page from MSDN:
MSDN: Linker Tools Warning LNK4099
Link says that "... remove the /DEBUG linker option if you do not have .pdb files for the objects you are linking."