dll_import_list.zip/dll_import_list/main.cpp
#include <iostream>
#include <Windows.h>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/format.hpp>
const IMAGE_DOS_HEADER *getMz(const unsigned char * const data) {
return reinterpret_cast<const IMAGE_DOS_HEADER *>(data);
}
template<typename NT_HEADER>
const NT_HEADER *getPe(const unsigned char * const data, const IMAGE_DOS_HEADER &mz) {
return reinterpret_cast<const NT_HEADER *>(data + mz.e_lfanew);
}
template<typename NT_HEADER>
const IMAGE_SECTION_HEADER *getSectionHeader(const unsigned char * const data, const IMAGE_DOS_HEADER &mz, const NT_HEADER &pe) {
return reinterpret_cast<const IMAGE_SECTION_HEADER *>(
data
+ mz.e_lfanew
+ sizeof(NT_HEADER) - sizeof(NT_HEADER::OptionalHeader)
+ pe.FileHeader.SizeOfOptionalHeader);
}
template<typename NT_HEADER, WORD MAGIC>
bool LoadImage(const boost::filesystem::path &path, std::vector<unsigned char> &out) {
if (!boost::filesystem::exists(path)) {
return false;
}
boost::filesystem::ifstream ifs(path, std::ios::binary);
if (!ifs.is_open()) {
return false;
}
// MZヘッダーの読み込み
out.resize(sizeof(IMAGE_DOS_HEADER));
ifs.read(reinterpret_cast<char*>(&out.front()), out.size());
const IMAGE_DOS_HEADER *mz = getMz(&out.front());
if (!ifs.good()) {
return false;
}
// PEヘッダーの読み込み
out.resize(mz->e_lfanew + sizeof(NT_HEADER) - sizeof(NT_HEADER::OptionalHeader));
mz = getMz(&out.front());
ifs.seekg(0, std::ios::beg);
ifs.read(reinterpret_cast<char*>(&out.front()), out.size());
const NT_HEADER *pe = getPe<NT_HEADER>(&out.front(), *mz);
if (!ifs.good()) {
return false;
}
// PEオプショナルヘッダーからセクションリストまでの読み込み
out.resize(
mz->e_lfanew
+ sizeof(NT_HEADER) - sizeof(NT_HEADER::OptionalHeader)
+ pe->FileHeader.SizeOfOptionalHeader
+ sizeof(IMAGE_SECTION_HEADER) * pe->FileHeader.NumberOfSections);
mz = getMz(&out.front());
pe = getPe<NT_HEADER>(&out.front(), *mz);
ifs.seekg(0, std::ios::beg);
ifs.read(reinterpret_cast<char*>(&out.front()), out.size());
if (!ifs.good()) {
return false;
}
if (pe->OptionalHeader.Magic != MAGIC) {
return false;
}
// セクションの読み込み
const IMAGE_SECTION_HEADER *sectionList = getSectionHeader<NT_HEADER>(&out.front(), *mz, *pe);
for (unsigned int i = 0; i < pe->FileHeader.NumberOfSections; i++) {
if (sectionList[i].Misc.VirtualSize == 0) {
continue;
}
if (out.size() < sectionList[i].VirtualAddress + sectionList[i].Misc.VirtualSize) {
out.resize(sectionList[i].VirtualAddress + sectionList[i].Misc.VirtualSize);
mz = getMz(&out.front());
pe = getPe<NT_HEADER>(&out.front(), *mz);
sectionList = getSectionHeader<NT_HEADER>(&out.front(), *mz, *pe);
}
ifs.seekg(sectionList[i].PointerToRawData, std::ios::beg);
ifs.read(reinterpret_cast<char*>(&out[sectionList[i].VirtualAddress]), (std::min)(sectionList[i].Misc.VirtualSize, sectionList[i].SizeOfRawData));
if (!ifs.good()) {
return false;
}
}
return true;
}
template<typename NT_HEADER, WORD MAGIC>
bool ExeParse(const boost::filesystem::path &path) {
if (!boost::filesystem::exists(path)) {
return false;
}
std::vector<unsigned char> image;
if (!LoadImage<NT_HEADER, MAGIC>(path, image)) {
return false;
}
const unsigned char * const baseAddr = &image.front();
const IMAGE_DOS_HEADER &mz = *getMz(baseAddr);
const NT_HEADER &pe = *getPe<NT_HEADER>(baseAddr, mz);
const IMAGE_DATA_DIRECTORY &dir = pe.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
if (dir.Size == 0) {
return false;
}
const IMAGE_IMPORT_DESCRIPTOR *desc = reinterpret_cast<const IMAGE_IMPORT_DESCRIPTOR *>(baseAddr + dir.VirtualAddress);
for (; desc->FirstThunk != NULL; desc++) {
const char * const dllName = reinterpret_cast<const char *>(baseAddr + desc->Name);
std::cout << boost::format("%s\n") % dllName;
const unsigned int *thunk = reinterpret_cast<const unsigned int *>(baseAddr + desc->FirstThunk);
for (; *thunk != NULL; thunk++) {
if ((*thunk & 0x80000000) != 0) {
std::cout << boost::format("\t@%d\n") % (*thunk - 0x80000000);
continue;
}
const char * const funcName = reinterpret_cast<const char *>(baseAddr + *thunk + 2);
std::cout << boost::format("\t%s\n") % funcName;
}
}
return true;
}
int main(const unsigned int argc, const char * const * argv) {
if (argc != 2) {
std::wcout << boost::wformat(L"usage: %s path") % boost::filesystem::path(argv[0]).filename().wstring();
return 1;
}
if (!ExeParse<IMAGE_NT_HEADERS32, IMAGE_NT_OPTIONAL_HDR32_MAGIC>(argv[1]) && !ExeParse<IMAGE_NT_HEADERS64, IMAGE_NT_OPTIONAL_HDR64_MAGIC>(argv[1])) {
std::cout << "ファイルを開けないか、実行可能形式ファイルではありません\n";
return 1;
}
return 0;
}