please help with PE import directory
I am writing a small code to get the import functions of a PE file, it works ok for all normal files, but for some special files(probably corrupted), it will cause the app to crash.
I test it with microsoft's dependency walker, it could detect it is not valid for the import directory, but I do not know how to verify.
any one please pay a little time to check it out?
Re: please help with PE import directory
I would suggest removing the .exe file from your Zip.
Noone, including me, is going to download anything that has compiled code in it.
Re: please help with PE import directory
Quote:
Originally Posted by Hack
I would suggest removing the .exe file from your Zip.
Noone, including me, is going to download anything that has compiled code in it.
hi, do you mean the compiled project exe, or the including corrupted sample exe file?
if you mean removing the sample file, how can people test it?
1 Attachment(s)
Re: please help with PE import directory
the file server is not available right now, so I could not remove the exe files. then I post the code here, and the attached file is the corrupted sample:
Code:
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
Private Type IMAGEDOSHEADER
e_Magic As String * 2
e_Cblp As Integer
e_Cp As Integer
e_Crlc As Integer
e_Cparhdr As Integer
e_Minalloc As Integer
e_Maxalloc As Integer
e_Ss As Integer
e_Sp As Integer
e_Csum As Integer
e_Ip As Integer
e_Cs As Integer
e_Lfarlc As Integer
e_Ovno As Integer
e_Res(1 To 4) As Integer
e_Oemid As Integer
e_Oeminfo As Integer
e_Res2(1 To 10) As Integer
e_Lfanew As Long
End Type
Private Type IMAGE_SECTION_HEADER
NameSec As String * 6
PhisicalAddress As Integer
VirtualSize As Long
VirtualAddress As Long
SizeOfRawData As Long
PointerToRawData As Long
PointerToRelocations As Long
PointerToLinenumbers As Long
NumberOfRelocations As Integer
NumberOfLinenumbers As Integer
Characteristics As Long
End Type
Private Type IMAGE_FILE_HEADER
Machine As Integer
NumberOfSections As Integer
TimeDateStamp As Long
PointerToSymbolTable As Long
NumberOfSymbols As Long
SizeOfOptionalHeader As Integer
Characteristics As Integer
End Type
Private Type IMAGE_DATA_DIRECTORY
VirtualAddress As Long
Size As Long
End Type
Private Type IMAGE_OPTIONAL_HEADER
Magic As Integer
MajorLinkerVersion As Byte
MinorLinkerVersion As Byte
SizeOfCode As Long
SizeOfInitializedData As Long
SizeOfUninitializedData As Long
AddressOfEntryPoint As Long
BaseOfCode As Long
BaseOfData As Long
ImageBase As Long
SectionAlignment As Long
FileAlignment As Long
MajorOperatingSystemVersion As Integer
MinorOperatingSystemVersion As Integer
MajorImageVersion As Integer
MinorImageVersion As Integer
MajorSubsystemVersion As Integer
MinorSubsystemVersion As Integer
Win32VersionValue As Long
SizeOfImage As Long
SizeOfHeaders As Long
Checksum As Long
Subsystem As Integer
DllCharacteristics As Integer
SizeOfStackReserve As Long
SizeOfStackCommit As Long
SizeOfHeapReserve As Long
SizeOfHeapCommit As Long
LoaderFlags As Long
NumberOfRvaAndSizes As Long
DataDirectory(0 To 15) As IMAGE_DATA_DIRECTORY
End Type
Private Type IMAGE_NT_HEADERS
signature As String * 4
FileHeader As IMAGE_FILE_HEADER
OptionalHeader As IMAGE_OPTIONAL_HEADER
End Type
Private Type IMAGE_NT_HEADERS2
signature As Long
FileHeader As IMAGE_FILE_HEADER
OptionalHeader As IMAGE_OPTIONAL_HEADER
End Type
'
' Import modules directory entry
'
Private Type IMAGE_IMPORT_DESCRIPTOR
OriginalFirstThunk As Long ' RVA to original unbound IAT
TimeDateStamp As Long ' 0 if not bound,
' -1 if bound, and real date\time stamp
' in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
' O.W. date/time stamp of DLL bound to (Old BIND)
ForwarderChain As Long ' -1 if no forwarders
name As Long
FirstThunk As Long ' RVA to IAT (if bound this IAT has actual addresses)
End Type
Private Type IMAGE_IMPORT_BY_NAME
Hint As Integer
FuncName(1) As Byte
End Type
Private Const IMAGE_ORDINAL_FLAG = &H80000000
Private Type IMAGE_BOUND_IMPORT_DESCRIPTOR
TimeDateStamp As Long
OffsetModuleName As Integer
NumberOfModuleForwarderRefs As Integer
' Array of zero or more IMAGE_BOUND_FORWARDER_REF follows
End Type
Private Type IMAGE_BOUND_FORWARDER_REF
TimeDateStamp As Long
OffsetModuleName As Integer
Reserved As Integer
End Type
Private Type LIST_ENTRY
Flk As Long
Blk As Long
End Type
Private Type LOADED_IMAGE
ModuleName As Long 'String
hFile As Long
MappedAddress As Long ' UCHAR *
FileHeader As Long ' IMAGE_NT_HEADERS *
LastRvaSection As Long ' IMAGE_SECTION_HEADER *
NumberOfSections As Long
Sections As Long ' IMAGE_SECTION_HEADER *
Characteristics As Long
fSystemImage As Byte
fDOSImage As Byte
Lks As LIST_ENTRY
SizeOfImage As Long
End Type
Private Const IMAGE_DIRECTORY_ENTRY_IMPORT = 1 ' Import Directory
Private Const UNDNAME_COMPLETE = &H0 ' Enable full undecoration
Private Declare Function ImageRvaToVa Lib "imagehlp" ( _
NtHeaders As Any, _
ByVal Base As Long, _
ByVal RVA As Long, _
Optional LastRvaSection As Long) As Long ' void *
Private Declare Function ImageDirectoryEntryToData Lib "imagehlp" ( _
ByVal Base As Long, _
ByVal MappedAsImage As Byte, _
ByVal DirectoryEntry As Integer, _
Size As Long) As Long ' void *
Private Declare Function MapAndLoad Lib "imagehlp" ( _
ByVal ImageName As String, _
ByVal DllPath As String, _
LoadedImage As LOADED_IMAGE, _
ByVal DotDll As Long, _
ByVal ReadOnly As Long) As Long
Private Declare Function UnMapAndLoad Lib "imagehlp" ( _
LoadedImage As LOADED_IMAGE) As Long
Private Declare Function lstrcpyA Lib "kernel32" (ByVal pString1 As Any, ByVal pString2 As Any) As Long
Private Declare Function lstrlenA Lib "kernel32" (ByVal pString As Any) As Long
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (Dest As Any, Src As Any, ByVal l As Long)
Private m_IsLoaded As Boolean
Private m_LI As LOADED_IMAGE
Private m_udtImageNTHeader2 As IMAGE_NT_HEADERS2
'
' Returns a string given its relative virtual address (RVA)
'
Private Function pvStringFromRVA(ByVal RVA As Long) As String
Dim lVA As Long
' Obtain the VA from RVA address
lVA = ImageRvaToVa(ByVal m_LI.FileHeader, m_LI.MappedAddress, RVA)
' Initialize return value
pvStringFromRVA = String$(lstrlenA(lVA), 0)
' Copy the string
lstrcpyA pvStringFromRVA, lVA
End Function
'
' Returns a string given its relative virtual address (RVA)
'
Private Function pvStringFromPtr(ByVal RVA As Long) As String
Dim lVA As Long
' Initialize return value
pvStringFromPtr = String$(lstrlenA(RVA), 0)
' Copy the string
lstrcpyA pvStringFromPtr, RVA
End Function
Public Sub EnumerateImportedModules(ByRef strModules() As String, _
ByRef lngReturned As Long)
Dim ImpDir As IMAGE_IMPORT_DESCRIPTOR
Dim lNamePtr As Long, lIdx As Long
Dim lImpPtr As Long, lSize As Long
lngReturned = 0
' Reinitialize the array
Erase strModules
If Not m_IsLoaded Then Exit Sub
' Get pointer to import directory data.
lImpPtr = ImageDirectoryEntryToData(m_LI.MappedAddress, 0, IMAGE_DIRECTORY_ENTRY_IMPORT, lSize)
' Check if the pointer is valid
If lImpPtr Then
' The import modules directory
' is just an array that ends
' with an empty structure.
' We have to read it until we
' found a null module name pointer
' Copy the first entry
' from the pointer
MoveMemory ImpDir, ByVal lImpPtr, Len(ImpDir) 'will crash for my sample
' Read entries until Name = 0
Do Until ImpDir.name = 0
' Redim the array
ReDim Preserve strModules(0 To lIdx)
' Get the module name
strModules(lIdx) = pvStringFromRVA(ImpDir.name)
' Increment array index
lIdx = lIdx + 1
' Copy the next entry
MoveMemory ImpDir, ByVal lImpPtr + (Len(ImpDir) * lIdx), Len(ImpDir)
Loop
lngReturned = lIdx
End If
End Sub
Public Function LoadPE(ByVal File As String) As Boolean
Dim lRet As Long
On Error GoTo HandleError
' Unload previous mapped file
If m_IsLoaded Then UnloadPE
' Load and map the file
' into the current address space
lRet = MapAndLoad(File, vbNullString, m_LI, True, True)
If lRet Then
' Set the loaded flag
m_IsLoaded = True
' Copy the NT header from pointer
If m_LI.FileHeader Then
MoveMemory m_udtImageNTHeader2, ByVal m_LI.FileHeader, Len(m_udtImageNTHeader2)
End If
LoadPE = True
Else
'Err.Raise Err.LastDllError, , "Cannot load and map the file. GetLastError = " & Err.LastDllError
End If
Exit Function
HandleError:
LoadPE = False
End Function
Public Sub UnloadPE()
' Unload any loaded file
If m_IsLoaded Then
UnMapAndLoad m_LI
m_IsLoaded = False
End If
End Sub
Public Sub Main()
Dim m() As String
Dim i As Long
Dim l As Long
LoadPE App.Path & "\sample.exe" 'set your file here
EnumerateImportedModules m, i
UnloadPE
For l = LBound(m) To UBound(m)
Debug.Print m(i)
Next
End Sub
Re: please help with PE import directory