Read from an exe using known data - visual-c++

I want to read the code, more like variable and function names since I can catch values with CheatEngine, of an exe file. I got information about the file from Exeinfo PE which told me
"Microsoft Visual C++ ver. 8.0 / Visual Studio 2005 [ Debug:02 ]"
a screencap from Exeinfo PE
I have identified the code in assembly in some ways using IDA, radare2 and CheatEngine's Memory Table.
I don't know what else I can list so ask me if you need further details. thank you very much.

I believe your question is:
How to view the function and variable names of a compiled program?
When compiled in debug mode, some information will be present in the binary. If there is a .pdb it will contain additional debug information as well.
But when compiled in release mode, C++ itself does not compile in a way in which it retains any variable names or function names or other identifying information such as this.
The only exception to this is RTTI or Run Time Type Information. RTTI you can think of like symbol names for virtual functions. Microsoft Visual C++ predominantly does this but other compilers can as well. RTTI can be parsed and it will give you the class names in relation to the their virtual function tables. If the class does not have virtual functions, you will not find RTTI for it.
The best tool I know of for parsing RTTI is Class Informer which is a plugin for IDA Pro.

Related

Which type library hosts stdDataFormat?

I am trying to import VB6's VBRUN type library into a Visual C++ 2017 header file, but it is failing due to a missing dependency.
Visual C++ reports
"error C4772: #import referenced a type from a missing type library;
'missing_type' used as a placeholder"
Viewing the file with OLE View reveals the problem is with the DataFormat property (DataFormat([out, retval] --<GetRefTypeInfo failed>** Return)).
The missing dependency would appear to be stdDataFormat: which type library does stdDataFormat reside in and why is it missing? (My operating system is Windows 10 Enterprise, 21H1.) Did I miss a selection when installing Visual Studio 6?
This addresses the first part of the question, how to find the typelib (TLB) containing a given interface or class.
Assuming you have no preconception about the TLB / DLL hosting a given COM interface or class you can find it by a couple of registry searches, assuming the type in question actually has been registered.
I started off in HKEY_CLASSES_ROOT with a search for data values = stdDataFormat. This lead to:
[HKEY_CLASSES_ROOT\MSSTDFMT.StdDataFormat]
#="StdDataFormat Object"
[HKEY_CLASSES_ROOT\MSSTDFMT.StdDataFormat\CLSID]
#="{6D835690-900B-11D0-9484-00A0C91110ED}"
Now armed with the CLSID GUID of 6D835690-900B-11D0-9484-00A0C91110ED, search for that value, finding:
HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{6D835690-900B-11D0-9484-00A0C91110ED
of which its important sub-element for our purposes is:
[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{6D835690-900B-11D0-9484-00A0C91110ED}\InprocServer32]
#="c:\\windows\\SysWow64\\msstdfmt.dll"
...
The InprocServer32 value was the main thing I wanted to find; it tells you the DLL - which is c:\windows\SysWow64\msstdfmt.dll (on my PC - but this should be typical).
Opening msstdfmt.dll in OLEView (or OLEViewDotNet) confirms this; the decompiled IDL from the TLB in that DLL contains:
[
uuid(6D835690-900B-11D0-9484-00A0C91110ED),
helpstring("StdDataFormat Object"),
helpcontext(0x00066b5f)
]
coclass StdDataFormat {
[default] interface IStdDataFormatDisp;
[default, source] dispinterface IStdDataFormatEvents;
};
So msstdfmt.dll should be the missing dependency.
If you did suspect this DLL to begin with, then obviously its a lot quicker to just load it in OLEView and check. But in many cases that won't be obvious when you're starting out.
As for the second part of the question - why is this dependency missing - maybe it would help if you added the relevant section of your code / includes?

Visual C++ Release build - is string getting corrupted when passed across DLL because compiled with different runtime version?

After building in Release mode, I am seeing exceptions which didn't occur in Debug mode. When debugging the release build, it looks like string references are not being passed correctly from the EXE (our application) to the DLL which is receiving the string reference.
Our EXE code looks like this:
string contents = "handle_message(): received=" + msg->encode();
LOG4CXX_DEBUG(logger, contents);
The LOG4CXX_DEBUG is going to log4cxx.dll, whose code looks like this:
CharMessageBuffer& CharMessageBuffer::operator<<(const std::basic_string<char>& msg) {
if (stream == 0) {
buf.append(msg);
} else {
*stream << msg;
}
return *this;
}
Looking at the Call Stack in the debugger, when I navigate down to the frame which has our source, I can see that contents is a valid string with size=583, capacity=838.
In the frame inside the log4cxx.dll (the next frame above in the stack) the string reference shows size=838, capacity=363113231 (and the values are all garbage).
Both our app and log4cxx.dll were compiled on the same machine, using the same runtime settings (/MD), but different versions of Visual Studio. The log4cxx dll was compiled using Visual Studio 2008 and our application was compiled using Visual Studio 2010. Running dumpbin on the 2 objects shows:
Our App (EXE)
MSVCP100.dll
MSVCR100.dll
log4cxx.dll (DLL)
MSVCP90.dll
MSVCR90.dll
Is this problem due to the fact that they are using different runtime versions?
If you pass non-POD (plain old datatypes) between DLL/EXE boundaries (like STL string or CRT FILE pointers) you must use the same shared CRT.
In your case, you must recompile all DLLs/LIBs with the same compiler!
See also: I can pass std::string for a Dll and what i can do with DLL´s?
The implicit question is:"Is there a way to pass data, hopefully using string and other STL containers, to DLLs of another version of visual studio either previous or later than the one that I'm using?".
Aside from using POD, there are probably three approaches: shared memory, sockets( to local host ) and MSMQ. All of these methods require additional extensive programming, but the deeper answer is found in how the interface is changing the input parameter.
I have found a possible solution to the string passing problem on the internet. It removes one layer of corruption; cast a pointer to the container to a uint and pass the uint. Dereference the uint to the pointer and the object is revealed. Beware, auto_ptrs are usually deleted in this process, so don't use them. If the passed object is still offset incorrectly( this happened to me with VS08 passing to a VS13 ), then pass the c_str() of the string instead. It's certainly inelegant, but we need to know all the alternatives. See "HowTo: Export C++ classes from a DLL" in Code Project( Nov 22, 2012 ).

Visual Studio 2012 undocumented warning C4447

dllmain.cpp(16): warning C4447: 'main' signature found without threading mode
l. Consider using 'int main(Platform::Array<Platform::String^>^ args)'.
Above is a warning I got from building a Windows Store App DLL project. I didn't change anything in that default dllmain.cpp file except for including my own version of pch.
The documentation for this warning (along with many VS2012 errors/warnings) is nowhere to be found on MSDN and here is the only relevant link I can find:
http://social.msdn.microsoft.com/Forums/en-US/vssetup/thread/6daa9587-fe54-4e84-a8b9-0e5c52c2f6e8/
and the op there didn't get an answer.
If anyone knows what it means and how to fix it, it would be great!
As far as I can tell, you can safely ignore the warning. The compiler cribs when it sees a Win32-style DllMain being compiled using the /ZW flag (Consume Windows Runtime Extensions). However, the function gets called as you'd normally expect.
Alternatively, you can work around the warning by compiling dllmain.cpp without /ZW. You might need to adjust the PCH settings for this to properly work. This is the path taken by the DLL (Windows Store apps) C++/CX project template in Visual Studio.
Incidentally, the reason you do not get the warning when you're trying to build a Windows Runtime Component project (which builds everything using /ZW) is that a Windows Runtime Component doesn't declare a DllMain. This is not to say that it can't; it just picks up the dummy DllMain that the CRT defines (which basically turns off per-thread initialization and reports success).

VC++ 2012 and Boost incompatibility - `throw()` specifications in library headers

I have a new project where I cannot use boost::format. I get a compiler error complaining that boost's override of a virtual function, ~basic_altstringbuf, lacks a "throw()". Even the most trivial attempt to use boost::format does that.
I have other projects where it works fine. I have verified that the new project uses the same include-paths for boost, and for the VC++ includes. All the projects have "Enable C++ Exceptions" set to Yes. The only explanation I can come up with is that the projects that work have some #DEFINE or some setting that disables those vile exception specs in the std:: include-files. But I have no idea what or where it might be. Any ideas?
Error 1 error C2694: 'boost::io::basic_altstringbuf::~basic_altstringbuf(void)': overriding virtual function has less restrictive exception specification than base class virtual member function 'std::basic_streambuf<_Elem,_Traits>::~basic_streambuf(void) throw()
EDIT: Corollary question: Is there a Properties-item in VS++ 2012 that will cause the std:: header files to be included without exception-specs? - short of turning off exceptions, that is?
At the request of the original owner of the green check-mark, I am submitting this summary.
The bugs are on the Microsoft side, in header-files for C++ standard library interfaces, and in the VC++ compiler when "Disable Language Extensions" is NOT set. The header files contain exception-specifications that the standard does not call for. When "language extensions" are not enabled, the compiler accepts invalid code. I have filed a bug report.
Boost could work around the problem in this specific case by adding seven characters to a nested include-file, i.e. "throw()" at line 65 in alt_sstream_impl.hpp. I filed a report with boost also, although I made it clear that the bug is not in their code. I am just suggesting a workaround.
All the tedious details are in the two reports linked above.
Check the preprocessor defines.
You might turn on and inspect verbose logging to see the exact flags that are passed to cl.exe
You could keep the preprocessed source and compare the version from the old (working) project with the new (failing) project.
My gut says, something else is being #defined/passed using -D in the old project that is not being defined in the new project, of differently (think of WINVER type macros)
See new answer posted: VC++ 2012 and Boost incompatibility - `throw()` specifications in library headers
EDIT by OP, Jive Dadson - It turned out to be /Za, which enables/disables "Microsoft language extensions." It is the contention of Visual Studio that the C++ standard requires that a program shall not compile if it has a virtual function override that is less restrictive in the "throw()" category than the function it overrides. Boost has a class that derives from basic_streambuf, and has a virtual destructor that lacks "throw()". The original destructor has that evil festoon. My new project will compile boost::format if I turn MS language extensions ON.
So the question becomes, who is wrong, and how? Is it standard-complying to put throw() on that destructor or not? Is the desired behavior (desired by me, that is) actually an "extension"? I seem to recall that MS considered some standard C++11 features to be "extensions," but I am not sure I remember correctly. Anyway, I will leave it to the boosters to decide, if they are interested. https://svn.boost.org/trac/boost/ticket/7477

fatal error C1084: Cannot read type library file: 'Smegui.tlb': Error loading type library/DLL

I am trying to build an old version of an application which consists of VC++ projects that were written in Visual Studio 2003.
My OS is Windows 7 Enterprise (64-bit).
When I try and build the solution I get the following errors:
error C4772: #import referenced a type from a missing type library; '__missing_type__' used as a placeholder
fatal error C1084: Cannot read type library file: 'Smegui.tlb': Error loading type library/DLL.
They both complain about the following import statement:
#import "Smegui.tlb" no_implementation
This is not a case of the file path being incorrect as renaming the Smegui.tlb file causes the compiler to throw another error saying it cannot find the library.
Smegui is from another application that this one depends on. I thought perhaps I was missing a dll but there is no such thing as Smegui.dll.
All I know about .tlb files is that they are a type library and you can create them from an assembly using tlbexp.exe or regasm.exe (the later also registers the assembly with COM)
There is also an Apache Ant build script which uses a custom task to invoke devenv.com to build the projects. This is the same script that the build server originally used to build the application. It gives me the same errors when I try and run it.
The strangest thing about this is that I knew it ought to work seeing as it is all freshly checked out from subversion. I tried many different combinations of admin vs user elevation, VS vs Ant build, cleaning, release.
I have got it to build successfully about 5 times but the build seems to be non-deterministic.
If anyone can shed some light on how this tlb stuff even works or what this error might mean I would greatly appreciate it.
I found a far more reliable solution: open the tlb with oleview.exe and then close it.
Not sure what this actually does but it works every time.
I think oleview is actually one of the samples included with Visual Studio but I haven't had the time to debug it and see what it is doing.
I ran into this error because one type library was trying to load a dependent type library, which it could not find. Even though the dependent type library was in the same directory, and even though that directory was in the searchable path, the compiler would error loading the first type library, but not mention the dependent type library in the error.
To find the pseudo-missing type library, I ran Process Monitor (procman64.exe) during the compile. This showed that after the reported type library had successfully loaded, a dependent type library could not be found. It even showed all of the places that it was looking for the dependent type library, none of which were where it should have been looking (e.g.: ).
The fix was to add a <PreBuildEvent> to the project to copy the dependent .tlb file to one of the directories that was actually being searched.
<PreBuildEvent>
<Command>copy /Y ..\Lib\Interop\CWSpeechRecLib.tlb .\</Command>
</PreBuildEvent>
http://msdn.microsoft.com/en-us/library/sce74ah7%28VS.71%29.aspx
smegui.tlb is referencing some other tlb that the compiler can't find. If you have the .idl for smegui you might be able to figure out what the other is. I suspect the missing tlb is something that original build machine had registered but that your machine doesn't have registered.
A type library is a binary description of a set of interfaces, coclasses and enums. They're usually generated for COM components, in the case of tlbexp and regasm the tlb is created from the assembly metadata. For native COM components they are usually generated from an idl (Interface Description Language) file by the midl tool.
Edit:
I just noticed you're on x64 Windows. Are you building the project with a new version of Visual Studio? If so, are you targeting x86 or x64? If the latter, it may simply be a 32bit component that the compiler can't find (or less likely, a x64 component the x86 compiler can't find if you are targeting x86), for WOW64 the registry is virtualized for x86 vs. x64 applications.
Well I finally found out why I managed to get it to build sometimes and not others... sort of.
So long as I ran the build script with elevated administrator permissions and let that get as far as it could until that error occurred, then run the build script again as a protected administrator succeeded. Those steps must be done in that exact order with no other steps in between. If I try build in Visual Studio it does not work (although I did get it to succeed once). Probably some kind of virtualisation issue although it still doesn't quite make sense.
Well I don't need help on this any more and I know it's probably impossible to fully answer this question without knowing exactly what the build is doing. However if anyone does have any more thoughts I would happily receive them.
Cheers,
Steiny

Resources