|
Packit Service |
c5cf8c |
/* -*- Mode: C++; c-basic-offset:4 ; -*- */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* (C) 2001 by Argonne National Laboratory.
|
|
Packit Service |
c5cf8c |
* See COPYRIGHT in top-level directory.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include <windows.h>
|
|
Packit Service |
c5cf8c |
#include <stdio.h>
|
|
Packit Service |
c5cf8c |
#include <time.h>
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* This function returns a pointer to the section header containing the RVA. Return NULL on error */
|
|
Packit Service |
c5cf8c |
template < typename NTHeaderType > static inline PIMAGE_SECTION_HEADER GetSecHeader(DWORD rva,
|
|
Packit Service |
c5cf8c |
NTHeaderType *
|
|
Packit Service |
c5cf8c |
pNTHeader)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
PIMAGE_SECTION_HEADER section;
|
|
Packit Service |
c5cf8c |
section = IMAGE_FIRST_SECTION(pNTHeader);
|
|
Packit Service |
c5cf8c |
for (int i = 0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++) {
|
|
Packit Service |
c5cf8c |
DWORD size = section->Misc.VirtualSize;
|
|
Packit Service |
c5cf8c |
DWORD secRVA = section->VirtualAddress;
|
|
Packit Service |
c5cf8c |
if ((secRVA <= rva) && (rva < (secRVA + size))) {
|
|
Packit Service |
c5cf8c |
return section;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
return NULL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* This function returns the real address from the RVA. Returns NULL on error */
|
|
Packit Service |
c5cf8c |
template < typename NTHeaderType > static inline LPVOID GetRealAddrFromRVA(DWORD rva,
|
|
Packit Service |
c5cf8c |
NTHeaderType * pNTHeader,
|
|
Packit Service |
c5cf8c |
PBYTE imageBase)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
PIMAGE_SECTION_HEADER pSectionHdr = GetSecHeader(rva, pNTHeader);
|
|
Packit Service |
c5cf8c |
if (!pSectionHdr) {
|
|
Packit Service |
c5cf8c |
return NULL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* Since we map the DLL manually we need to calculate mapShift to get the real addr */
|
|
Packit Service |
c5cf8c |
INT mapShift = (INT) (pSectionHdr->VirtualAddress - pSectionHdr->PointerToRawData);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return (PVOID) (imageBase + rva - mapShift);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* This function reads the exported symbols from a dll/exe and prints a DLL definition file, compatible with gcc,
|
|
Packit Service |
c5cf8c |
with those symbols.
|
|
Packit Service |
c5cf8c |
INPUT:
|
|
Packit Service |
c5cf8c |
pImageBase : Pointer to the base of the dll image, offset = 0
|
|
Packit Service |
c5cf8c |
pNTHeader : Pointer to the NT header (32-bit/64-bit) section of image.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
template < typename NTHeaderType > void PrintDefFileWithExpSymbols(PBYTE pImageBase,
|
|
Packit Service |
c5cf8c |
NTHeaderType * pNTHeader)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
/* Export Section RVA */
|
|
Packit Service |
c5cf8c |
DWORD expSecRVA =
|
|
Packit Service |
c5cf8c |
pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* From RVA get the real addrs for the various components of the exports section */
|
|
Packit Service |
c5cf8c |
PIMAGE_EXPORT_DIRECTORY pExportDir =
|
|
Packit Service |
c5cf8c |
(PIMAGE_EXPORT_DIRECTORY) GetRealAddrFromRVA(expSecRVA, pNTHeader, pImageBase);
|
|
Packit Service |
c5cf8c |
PDWORD pszFuncNames =
|
|
Packit Service |
c5cf8c |
(PDWORD) GetRealAddrFromRVA(pExportDir->AddressOfNames, pNTHeader, pImageBase);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
printf("EXPORTS\n");
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (unsigned int i = 0; i < pExportDir->NumberOfFunctions; i++) {
|
|
Packit Service |
c5cf8c |
/* FIXME: Assumes that the current DLL does not have ordinal nums */
|
|
Packit Service |
c5cf8c |
if (i < pExportDir->NumberOfNames) {
|
|
Packit Service |
c5cf8c |
/* Ordinal numbers start at 1 - not 0 */
|
|
Packit Service |
c5cf8c |
printf("\t%s @ %d ;\n", GetRealAddrFromRVA(pszFuncNames[i], pNTHeader, pImageBase),
|
|
Packit Service |
c5cf8c |
i + 1);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
break;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static void HelpUsage(char *exe_name)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
printf("Usage: %s <DLLNAME>\n", exe_name);
|
|
Packit Service |
c5cf8c |
printf
|
|
Packit Service |
c5cf8c |
("\t\t The tool reads the export section from <DLLNAME> and prints the definition file for gcc to stdout\n");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int main(int argc, char *argv[])
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
HANDLE hFile, hFileMapping;
|
|
Packit Service |
c5cf8c |
LPVOID lpFileBase;
|
|
Packit Service |
c5cf8c |
PIMAGE_DOS_HEADER pImgHeader;
|
|
Packit Service |
c5cf8c |
PIMAGE_NT_HEADERS pImgNTHeader;
|
|
Packit Service |
c5cf8c |
PIMAGE_NT_HEADERS64 pImgNTHeader64;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if ((argc < 2) || (strcmp(argv[1], "/?") == 0) || (strcmp(argv[1], "--help") == 0)) {
|
|
Packit Service |
c5cf8c |
HelpUsage(argv[0]);
|
|
Packit Service |
c5cf8c |
exit(1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Open the DLL and map it to memory */
|
|
Packit Service |
c5cf8c |
hFile =
|
|
Packit Service |
c5cf8c |
CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
|
Packit Service |
c5cf8c |
FILE_ATTRIBUTE_NORMAL, 0);
|
|
Packit Service |
c5cf8c |
if (hFile == INVALID_HANDLE_VALUE) {
|
|
Packit Service |
c5cf8c |
printf("Unable to open dll, %s\n", argv[1]);
|
|
Packit Service |
c5cf8c |
exit(-1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
|
|
Packit Service |
c5cf8c |
if (hFileMapping == 0) {
|
|
Packit Service |
c5cf8c |
CloseHandle(hFile);
|
|
Packit Service |
c5cf8c |
printf("Cannot open file mapping for dll, %s\n", argv[1]);
|
|
Packit Service |
c5cf8c |
exit(-1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
|
|
Packit Service |
c5cf8c |
if (lpFileBase == 0) {
|
|
Packit Service |
c5cf8c |
CloseHandle(hFileMapping);
|
|
Packit Service |
c5cf8c |
CloseHandle(hFile);
|
|
Packit Service |
c5cf8c |
printf("Cannot map view of dll, %s\n", argv[1]);
|
|
Packit Service |
c5cf8c |
exit(-1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* pImgHeader points to the MS-DOS HEADER section, offset=0, of dll */
|
|
Packit Service |
c5cf8c |
pImgHeader = (PIMAGE_DOS_HEADER) lpFileBase;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* pImgNTHeader points to the NT HEADER section of the dll, pImgHeader + <File address of new exe header> */
|
|
Packit Service |
c5cf8c |
pImgNTHeader = (PIMAGE_NT_HEADERS) ((DWORD_PTR) pImgHeader + (DWORD_PTR) pImgHeader->e_lfanew);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* In the case of the 64-bit dlls, the Optional header section within NT header has 64-bit fields */
|
|
Packit Service |
c5cf8c |
pImgNTHeader64 = (PIMAGE_NT_HEADERS64) pImgNTHeader;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* The Magic number is always a WORD. This number is used to determine if the dll is 32-bit or 64-bit */
|
|
Packit Service |
c5cf8c |
if (pImgNTHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
|
|
Packit Service |
c5cf8c |
/* 64-bit dll */
|
|
Packit Service |
c5cf8c |
PrintDefFileWithExpSymbols((PBYTE) pImgHeader, pImgNTHeader64);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* 32-bit dll */
|
|
Packit Service |
c5cf8c |
PrintDefFileWithExpSymbols((PBYTE) pImgHeader, pImgNTHeader);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
UnmapViewOfFile(lpFileBase);
|
|
Packit Service |
c5cf8c |
CloseHandle(hFileMapping);
|
|
Packit Service |
c5cf8c |
CloseHandle(hFile);
|
|
Packit Service |
c5cf8c |
}
|