1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
|
/* DllExportParser.cpp : Defines the entry point for the console application.
** Neitsa pour DVP **
Extrait les fonctions exportées par une DLL.
Usage : passer le chemin complet de la DLL à l'exécutable.
ex: DllExportParsser.exe c:\windows\system32\kernel32.dll > out.txt
*/
#include "stdafx.h"
#include <windows.h>
#include <time.h>
typedef struct _HANDLES {
HANDLE hFile;
HANDLE hMapping;
LPVOID pMapping;
} HANDLES, *PHANDLES;
BOOL MapFile(TCHAR* fileName, HANDLES* handles);
PIMAGE_NT_HEADERS CheckPeValidity(HANDLES* handles);
BOOL DumpExports(HANDLES* handles, PIMAGE_NT_HEADERS ImageNtHeaders);
void CleanAll (HANDLES* handles);
int _tmain(int argc, _TCHAR* argv[])
{
HANDLES handles;
PIMAGE_NT_HEADERS pINH = NULL;
if(argc == 2)
{
memset(&handles, 0, sizeof(handles));
if(MapFile(argv[1], &handles))
{
pINH = CheckPeValidity(&handles);
if(pINH != NULL)
{
DumpExports(&handles, pINH);
}
}
CleanAll(&handles);
}
else
_tprintf(_T("Usage :\nDllExportParser.exe dll_full_path"));
return 0;
}
BOOL MapFile(TCHAR* fileName, HANDLES* handles)
{
DWORD FileSize = 0;
//open the DLL file
handles->hFile = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (handles->hFile == INVALID_HANDLE_VALUE)
{
printf("Can't open the required file");
return FALSE;
}
// get the DLL size
FileSize = GetFileSize (handles->hFile, NULL);
if (FileSize == 0)
{
//Error handling
CleanAll (handles);
printf("FileSize is 0 !");
return FALSE;
}
handles->hMapping = CreateFileMapping (handles->hFile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL);
if (handles->hMapping == NULL)
{
//error handling
CleanAll (handles);
printf("Can't create the file mapping !");
return FALSE;
}
handles->pMapping = MapViewOfFile (handles->hMapping, FILE_MAP_READ, 0, 0, 0);
if (handles->pMapping == NULL)
{
//error handling
CleanAll (handles);
printf("Can't map the requested file !");
return FALSE;
}
return TRUE;
}
PIMAGE_NT_HEADERS CheckPeValidity(HANDLES* handles)
{
PIMAGE_DOS_HEADER ImageDosHeader = NULL;
PIMAGE_NT_HEADERS ImageNtHeaders = NULL;
//cast pMapping to IMAGE_DOS_HEADER
ImageDosHeader = (PIMAGE_DOS_HEADER)handles->pMapping;
//test if the DLL is really a PE (portable executable) file
if (ImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
{
//error handling
CleanAll (handles);
printf("This file isn't a PE file !\n\n Wrong IMAGE_DOS_SIGNATURE");
return NULL;
}
ImageNtHeaders = (PIMAGE_NT_HEADERS)(ImageDosHeader->e_lfanew + (DWORD) ImageDosHeader);
//test if the NT_SIGNATURE is ok
if (ImageNtHeaders->Signature != IMAGE_NT_SIGNATURE)
{
//error handling
CleanAll (handles);
printf("This file isn't a PE file !\n\n Wrong IMAGE_NT_SIGNATURE");
return NULL;
}
return ImageNtHeaders;
}
BOOL DumpExports(HANDLES* handles, PIMAGE_NT_HEADERS ImageNtHeaders)
{
DWORD ImageBase, ExportTableRVA, NumOfNames, ExportTableSize, ETUpperBoundary;
unsigned int i = 0;
PIMAGE_EXPORT_DIRECTORY ImageExportDirectory = NULL;
PWORD pOrdinals = NULL;
PDWORD pFuncs = NULL;
//pMapping is the ImageBase of the file
ImageBase = (DWORD)handles->pMapping;
//required file has passed all tests. Now get the ExportTable RVA
ExportTableRVA = ImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
if (ExportTableRVA == 0)
{
//we got a problem...
CleanAll (handles);
printf("Export table not found !");
return FALSE;
}
// add the Export table RVA and image base to get IED (IMAGE_EXPORT_DIRECTORY)
ImageExportDirectory = (PIMAGE_EXPORT_DIRECTORY) (ExportTableRVA + ImageBase);
//Print all infos from Export directory
_tprintf (_T("TimeDateStamp: 0x%08lX - "), ImageExportDirectory->TimeDateStamp);
_tprintf (_tctime( (time_t*)&ImageExportDirectory->TimeDateStamp ));
printf("\nDLL name : %s\n", ImageExportDirectory->Name + ImageBase);
_tprintf (
_T("Major Version: %i\n")
_T("Minor Version: %i\n")
_T("Name RVA: 0x%08lX\n")
_T("Ordinal Base: 0x%08lX\n")
_T("Address Table Entries: %d\n")
_T("Number of Name Pointers: %d\n")
_T("Export Table Address RVA: 0x%08lX\n")
_T("Name Pointer RVA: 0x%08lX\n")
_T("Ordinal Table RVA: 0x%08lX\n"),
ImageExportDirectory->MajorVersion,
ImageExportDirectory->MinorVersion,
ImageExportDirectory->Name,
ImageExportDirectory->Base,
ImageExportDirectory->NumberOfFunctions,
ImageExportDirectory->NumberOfNames,
ImageExportDirectory->AddressOfFunctions,
ImageExportDirectory->AddressOfNames,
ImageExportDirectory->AddressOfNameOrdinals);
pOrdinals = (PWORD) (ImageExportDirectory->AddressOfNameOrdinals + ImageBase);//ordinal pointer
pFuncs = (PDWORD) (ImageExportDirectory->AddressOfFunctions + ImageBase);//func pointer
NumOfNames = ImageExportDirectory->NumberOfNames;
//get the export table size in PE header (needed for testing if func is forwarded)
ExportTableSize = ImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
ETUpperBoundary = ExportTableRVA + ExportTableSize;
//parse the export table and retrieve each function ordinal's.
for (i = 0; i < ImageExportDirectory->NumberOfFunctions; i++)
{
_tprintf (_T("\nOrd: %04lX (0x%08lX)"), ImageExportDirectory->Base + i, pFuncs[i]);
//parse the export table and retrieve the function name's IF it exists !
if (pOrdinals[i] < NumOfNames)
{
PDWORD pNamePointerRVA =(PDWORD)(ImageExportDirectory->AddressOfNames + ImageBase);
PCHAR pFuncName = (PCHAR) (pNamePointerRVA[i] + (DWORD) ImageBase);
printf (" - %s", pFuncName);
//now test if the function is forwarded (see pecoff and "Russ Osterlund" papers about that)
if ( (pFuncs[i] >= ExportTableRVA) && (pFuncs[i] <= ETUpperBoundary) )
{
//func is forwarded !
PDWORD pFwdFunc = (PDWORD) (pFuncs[i] + (DWORD)ImageBase);
printf (" - Fwd to: %s", pFwdFunc);
}
}
}
return TRUE;
}
// release handles
void CleanAll (HANDLES* handles)
{
if (handles->hFile != NULL){
CloseHandle (handles->hFile);
}
if (handles->pMapping != NULL){
UnmapViewOfFile (handles->pMapping);
}
if (handles->hMapping != NULL){
CloseHandle (handles->hMapping);
}
} |
Partager