Abrí una mi viejo proyecto desde el momento en que me gusta que examinó la estructura de directorios de importación y exportación (IMAGE_DIRECTORY_ENTRY_EXPORT
, IMAGE_DIRECTORY_ENTRY_IMPORT
, IMAGE_DIRECTORY_ENTRY_IAT
y IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
). En resumen, puedo explicar la parte en la que tienes un problema. Me refiero a la parte de cómo encontrar el puntero a, por ejemplo, IMAGE_EXPORT_DIRECTORY
dentro de PE.
primer lugar de la causa, es posible utilizar las operaciones de lectura de archivos/escritura para analizar un archivo PE, pero es mucho más fácil de utilizar la asignación de archivos como siguiente:
hSrcFile = CreateFile (pszSrcFilename, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, 0, NULL);
hMapSrcFile = CreateFileMapping (hSrcFile, NULL, PAGE_READONLY, 0, 0, NULL);
pSrcFile = (PBYTE) MapViewOfFile (hMapSrcFile, FILE_MAP_READ, 0, 0, 0);
después de que tengamos el puntero pSrcFile
que apuntan al archivo PE contienen podemos encontrar otros lugares importantes dentro del PE:
pDosHeader = (IMAGE_DOS_HEADER *)pSrcFile;
IMAGE_NT_HEADERS32 *pNtHdr = (IMAGE_NT_HEADERS32 *)
((PBYTE)pDosHeader + pDosHeader->e_lfanew);
IMAGE_SECTION_HEADER *pFirstSectionHeader = (IMAGE_SECTION_HEADER *)
((PBYTE)&pNtHdr->OptionalHeader +
pNtHdr->FileHeader.SizeOfOptionalHeader);
dirección virtual Ahora todos hemos necesitado de cualquier directorio. Por ejemplo,
pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
es una dirección virtual del directorio de exportación. Después de eso, para convertir la dirección virtual al puntero de memoria, , debemos encontrar la sección de PE que tiene esta dirección virtual dentro de.Para ello podemos enumerar las secciones del PE y encontrar un rallador i
o igual a 0
y menos de pNtHdr->FileHeader.NumberOfSection
s donde
pFirstSectionHeader[i].VirtualAddress <=
pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
y al mismo tiempo
pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
< pFirstSectionHeader[i].VirtualAddress + pFirstSectionHeader[i].Misc.VirtualSize
entonces usted debe buscar los datos de exportación en la sección pFirstSectionHeader[i]
:
IMAGE_SECTION_HEADER *pSectionHeader = &pFirstSectionHeader[i];
IMAGE_EXPORT_DIRECTORY *pExportDirectory =
(IMAGE_EXPORT_DIRECTORY *)((PBYTE)pbyFile + pSectionHeader->PointerToRawData +
pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress -
pSectionHeader->VirtualAddress);
el mismo procedimiento se debe repetir para encontrar (IMAGE_IMPORT_DESCRIPTOR *)
WH ich corresponde a IMAGE_DIRECTORY_ENTRY_IMPORT
y (IMAGE_BOUND_IMPORT_DESCRIPTOR *)
que corresponde a IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT
para volcar la información de importación, incluida una información vinculante (si existe).
para volcar la información de IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
(corresponde a (ImgDelayDescr *)
definido en delayimp.h) se debe utilizar también la información de la IMAGE_DIRECTORY_ENTRY_IAT
(corresponde a (IMAGE_THUNK_DATA32 *)
).
Para obtener más información acerca de PE recomiendo que http://msdn.microsoft.com/en-us/magazine/cc301808.aspx
El conjunto de artículos señaló en este SO respuesta podría ser de ayuda: http://stackoverflow.com/questions/2307754/within-a-dll-how-is-the-function-table-structured/2307850#2307850 –