Assume you have a .DLL file, and you want to know some basic information regarding it,
for example:
Is it a Managed (.NET) or Non-Managed (e.g. COM, etc) DLL
If it's Managed, what minimal version of .NET it requires
(and if it's non-managed, then any other minimal version that it requires? for example minimal version of Windows, or of something else)
Any other kind of such metadata
Please note that I am less interested in seeing the Function Headers (or Classes) that are inside.
Visual Studio's Object Browser can show the Functions/Classes very well,
yet I did not find a way to make Object Browser show the metadata that I mentioned above..
So maybe another utility can do it?
I have a DLL used in a compliance scenario (the details of which are irrelevant). The important point is that the main executeable must display the DLL version number. My solution was that the DLL has a function to return it's own version - ie obtain it from the its own version resource and return it as a string.
My reviewer says that the main program should work out the DLL version number. He even gave me some code to get the DLL module handle and extract the version using that.
My question is, which is a better design and why? My feeling is that, using OO principles, I should ask the DLL for its version number. Doing it the other way means that the main program needs to know how the version information is stored and is hence more tightly coupled to the implementation.
Note that I know exactly how to extract the version information from a DLL. My question is about the best place for the code that does this.
Can you clarify the environment that you're working in? For now, since you've already mentioned getting the module handle, I'll assume you're using C++ and calling one of a handful of Win32 functions (GetModuleHandle, LoadLibrary etc).
First of all, I'd be careful about applying OO principles in too wide a context. The object oriented paradigm helps you structure your software in a more maintainable and understandable way, the problem you're describing sounds like it maybe stretches outside of the boundaries of your application. If you want to get information about a separate resource, such as a DLL, you should consider using a standard approach to achieving this to ensure that your code is decoupled from the items that it needs to inspect.
If you introduce a function into the DLL to return the version number to your main application, you have created a tight coupling between your main application and any DLL that needs to supply it's version information (by essentially defining a bespoke API or interface for this).
You should consider using standard, platform-wide functionality to retrieve the information instead This will allow your application to version any DLL for which it can obtain a handle.
Assuming you have an HMODULE for the dll (and you're using C++), call the following functions to get the version...
GetModuleFileNameEx (to get the full path and filename of the DLL if you don't already know this)
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683198(v=vs.85).aspx
using this filename, call
GetFileVersionInfoSize (look these up on MSDN)
This will tell you some crucial information about the file's version metadata (how much info, if any the file has). Assuming this function succeeds, call
GetFileVersionInfo
This will load all the file info metadata into a buffer, then call
VerQueryValue
Supply '\' as the lpSubBlock parameter to get the standard file info metadata (including the version number)
The above functions will allow you to write code to get the version number of any module that your code can get a handle to.
Of course, if you're using C# the solution is much simpler. Hope this helps...
I have a little problem with the creation of a user control.
Though I have made a control I want to use in another control.
As soon as I want to add the reference (would like to use it as compiled OCX) in the Component's list, the message "Wechselseitiger Verweis zwischen Projekten nicht zulässig" which means something like "Circular referencing between projects is not allowed"
Strange is that the control I want to use does not have any type of reference to the first project.
I've checked this using dependency walker which is shipped as a tool with Visual Studio, but it says as well that there's no reference to the other control. I've opened the project-files using a text-editor to check for referenced OCX, I didn't find any.
To avoid some comments: change to .NET or any other language is not an option.
Comment: Why ever, adding the uncompiled .ctl-file seems to work. For now I can continue my work. But anyways I'm interested in a solution and the reason why it doesn't work with the current constellation.
VOTE FOR CLOSE: I've been looking at all the files, well and now I've just simply added all control-files to the project instead of creating OCX. I'll give it up. Thanks to all...
It is possible for VB6 to get quite confused when you add references to OCX files. You should really be adding an OCX as a component instead of using Project References.
A word or two about project I have to make.
I have a list of products (XML formatted), and I have to make a bar code of that list.
Here are the requirements:
Technology has to be MFC, VS 2005 or VS2008
All functionality must be in one dll
Same solution should have a simple tester for the dll
I will use pdf417. http://en.wikipedia.org/wiki/PDF417 http://sourceforge.net/projects/pdf417lib/
Also, I would like to provide an interface, so that different bar codes can be implemented in future.
For example, my dll has "Write" method which is implemented in a separate file for pdf417 and in a separate file for some other bar code, so that user can choose which bar code to use.
Since I have no knowledge of mfc, I really don't know how to even start. I read some tutorials, created the dll with some dummy method, and then tried to use it in tester application, but no luck.
I know that this is a "needle in a haystack" type of a question, but if someone could help me how to setup/architect this project I would be very grateful.
Thanks,
Marko
I don't see how you benefit from using MFC if your DLL's client is not an MFC app. You are better off using a standard C interface in your exported functions if you want to support non-MFC clients. Just create a Win32 project and choose the project type as DLL, then the wizard will generate some example exported function for you. Follow the examples to create your own export functions.
Whats the easiest way to find out what programming language an application was written in?
I would like to know if its vb or c++ or delphi or .net etc from the program exe file.
Try PEiD
of course if they used a packer, some unpacking will need to be done first :)
Start it up and check what run-time DLLs it uses with Process Explorer.
If that doesn't make it immediately obvious, search the web for references to those DLLs.
Most disassemblers (including Olly I think) can easily show you the text contained in an EXE or DLL, and that can also sometimes give a clue. Delphi types are often prefixed with T as in TMyClass.
If it's a small executable with no DLL references and no text you might be SOL. At that point you'd need to look for idioms of particular compilers, and it would be mostly guesswork.
There is an art to detecting what language a program was written in. It is possible but there are no hard and fast rules. It takes a lot of experience (and it also leads to the question "Why would you want to..." but here are a few ideas on how to go about it.
What you're looking for is a "signature". The signature could be a certain string that is included by the compiler, a reference to an API that is quite common in the programming tool being used, or even a style of programing that is common to the tools being used, visible in the strings contained in the application.
In addition, there are styles to how an application is deployed: various configuration files found in the deployment directory, dlls and assemblies and even images, directories or icons.
Java applications wrapped in a self-launching executable will contain references to java libs, and will likely have certain libraries or files included in the same directory that indicate that it's java.
As indicated in other answers a managed assembly will show certain signs as well: you can open it in Reflector etc. While it is correct that c# and VB are "interchangable" once compiled, it is not true that they are identical. If you use Reflector to disassemble VB code you will quite often see that the assembly references the Microsoft.VisualBasic.dll assembly. You'll be able to tell the difference between Mono applications because they will most likely contain references to the mono assemblies.
Many compilers assemble and link code in certain ways, and leave footprints behind. For example, examining a window executable using "strings: tab in Process Explorer, you'll see a lot of strings. Using these you may be able to determine programming styles, methods called, error or trace methods withint the exe.
An example is that compilers use different mechanisms for localization: Microsoft stores localized strings in XML files or resource files. Other compilers will use a different tactic.
Another example is c++ name mangling. The CodeWarrior compiler uses a different algorithm to mangle the names of the member variables and functions of a call than Visual Studio.
I suppose you could write a book on the subject of accurately determining the lineage of any executable. This subject would probably be called "programming archeology".
You could try using Depends to see what runtime dependancies it has, which might give some clues.
The easiest way is to ask the developer of the program. It does not require any knowledge and utility programs.
Determine Delphi Application
Use eda_preview270.exe (from here) or some other spy tool and check the window class names. If they read like TButton or TfrmBlubb, it's a VCL app. If there is an "Afx" in them, it's probably MFC.
Compiled languages (by this I mean no scripting languages, or Java, .NET, etc.) are compiled into CPU assembly instructions, which is essentially a one-way conversion. It is not usually possible to determine which language a program was written in. However, using a dependency walker, you could potentially determine which runtime library the program was loading (if any) and therefore determine which language it used (e.g. MS Visual C++ 9 uses msvcr90.dll).
you can check is that a .net assembly or not by trying to open with ildasm.exe tool
PE Detective works best for me.
In general, you can't.
If you can load it into Reflector, you know it is a managed assembly.
That's a good question. There isn't any general way to tell, but I bet most compilers and libraries leave a mark in the resulting EXE file. If you wanted to spend a lot of time on it, you could gather a bunch of EXEs written in known languages and scan for common strings. I would image you'd find some.
Dependancy Walker, which someone else mentioned would be a good way to look for telltale dependencies, like versions of MSVCRT, etc
i'd try running the .exe thru a 'strings' program to get assorted hints.
If I remember correctly PE Explorer Disassembler gives some information about compiler that creates given not .net and java binary, for .net use Reflector or ILDAsm tool
The easiest way that I found (at least in computer games) was to look in the "redist" folder nested within the game's main folder. It might be obvious to some of you that are more experienced in programming yourself, but the specific purpose of the MSI in this folder is to allow the setup.exe file to automatically install the prerequisites for the game itself.
For example:
In Empire Total War, there is an MSI called "vcredist_x86-sp1.exe". This indicates that the game/program was written in Microsoft's "Visual C 2005" in the .NET Framework (usually).
In fact, if you open the MSI/EXE, the installer should immediately indicate the language it's written in and which version.
The reason I'm familiar is because I code in C# and VB in the .NET Framework and we auto-install the prerequisites for our business app.
Hope this helps!