Download ImpDef.exe
Introduction
I just installed new Visual Studio
2010. And first thing I usually do with new studio is that I try to convince him to not link to some bizzare runtimes that nobody have and usually requres weird dependencies. I usually do this by backing up msvcrt.lib somewhere and generating my new msvcrt.lib that references good old msvcrt.dll that is part of windows since 95. I also needed to generate import library for ntdll.dll for my different project. For example ImpDef.exe for this article was build this way so it will work everywhere not needing special Visual Studio
2010 runtimes.
Background
Now to generate import library Ms provides us with tool lib.exe that takes so called DEF file and generates import library for specified dll. DEF file is simple text file usually formatted like this
LIBRARY msvcrt.dll
EXPORTS
someexport1
someexport2
...
Now the problem is that Ms doesn't provide any tool to generate DEF file from DLL files.
Ms support page mentions that you can use DUMPBIN /EXPORTS dll to get textual list of exports but it generates weird format that is not compatible with DEF And manually creating DEF file with tousands of imports is often tedious process for big dlls.
Therefore after unsuccesfull search fur such tool (since I am lazy) I unfortunately ended up creating it myself. It takes dll and produces def file. Since Gcc MS Watcom Borland etc. all generate libs in different and incompatible formats. I thought it's more flexible to generate just def and then generate import lib with lib.exe comming with particular dev. environment.
Using the code
I will just briefly go over the code since this is not supposed to be PE file format tutorial. There are already excelent detailed ones out there. Like the one from Matt Pietrek. The line I used to parse PE file is just my code snippet that I often reuse since PE format doesn't change for obvius compatibility reasons.
LoadLibray loads dll to contiguous memory block and returned handle is in fact pointer to this memory. What is important to know is that this is not 1/1 mapping and different sections of dll have different aligment in memory than in file. Therefore there is no such thing as one direct offset to exports. We therefore need to navigate in headers from dos -> nt -> export directory -> array of export names and addresses.
#include <windows.h>
#include <stdio.h>
void main(int argc,char**argv) {
DWORD* dll=(DWORD*)LoadLibrary(argv[1]);
DWORD *nt=dll+dll[15]/4+6, *dir=nt+24, *exports=(DWORD*)(nt[7]+dir[0]), *name=(DWORD*)(nt[7]+exports[8]), *addr=(DWORD*)(nt[7]+exports[7]);
printf("LIBRARY %s\nEXPORTS\n",argv[1]);
for(DWORD i=0;i<exports[6];i++) {
printf(" %s\n",nt[7]+name[i]);
}
}
Points of Interest
As for PE. If you are curious than you can find what value is on what offset in winnt.h. nt is IMAGE_OPTIONAL_HEADER but for myself I keep it in more manageable snippet form since it's code that never changes.
Also I did put addr variable there so you can iterate
over exported function addresses in case you need it one day(to find to which dll/proc some addr belongs etc.).
For those interested in MS import library format this is what I know thanks to this excelent info except that usual obj headers seem to be replaced by just one simple IMPORT_OBJECT_HEADER per import.
IMAGE_ARCHIVE_START
2 x {
IMAGE_ARCHIVE_MEMBER_HEADER
DWORD COUNT containing no of symbols
COUNT x OFFSETS to OBJ
COUNT x SYMBOLNAME \0
}
IMAGE_ARCHIVE_MEMBER_HEADER
IMAGE_ARCHIVE_MEMBER_HEADER
IMAGE_ARCHIVE_MEMBER_HEADER
COUNT x OBJ {
IMAGE_ARCHIVE_MEMBER_HEADER
IMPORT_OBJECT_HEADER
import \0
dllname\0
}
As an experiment I created also version that generates import lib directly ( MS format)
from dll and I will post it here soon after some testing so stay tuned.
So enjoy and I hope this utility/snippet will be helpfull to you guys .