DRAFT - Generating Export Tables from DLLs
Recently, I was on a threat hunt and noticed a
.dll being used in the command-line by
rundll32. My bad-guy radar immediately went off, as this is a common way for adversaries to execute specific functions from both legitimate and illegitimate
.dll files. I tried googling the exact filename and filepath, but unfortunately Microsoft does not keep a centralized directory of all of their distributed
.dll files and what they do. I want to change that.
Often times, when looking at endpoint security events, you’ll see
.dll (Dynamic-Link Library) files being referenced. They are often a source of confusion and anxeity for junior programmers and security analysts alike. I won’t be explaining what they are or how they work, but rather I’ll be showing you a method to generate a useful list of exports from
The goal for this post is to both produce code that anyone can run and scan their computer for all
.dll files and generate an output of the exported functions, and also to document the ones I found on my system for quick reference.
I was going to cheat and use Python, but I am starting to get too familiar with it and wanted to challenge myself. Plus, one of the goals is to produce a portable application that others can use on their systems, and while
Py2EXE is a thing, it’s not a good thing. So let’s launch Visual Studio 2017 and break out some C++.
The first thing we need to do is scan the harddrive for all
.dll files and keep their path in a
list vector for reference. We’ll come back to that vector and use the files to actually view the exported functions. Luckily, C++17 has implemented some cool filesystem features so we don’t have to mess around with the
dirent library(?). One thing I later realized is that you can’t open 32-bit
.dll files from a 64-bit process, so I ended up organizing the
.dll files into two vectors with the help of
Unfortunately, that was the easy part. We now need to figure out how to read the export table from each of the files. I read an amazing article on the Win32 Portable Executable file format, and the article happened to include code on how to extract everything we need. No need to re-invent the wheel, right? ;)
After a lot of finagling since the original code was incomplete/broken, I ended up finding an online source with a complete code and header file that I could use.
To be continued…