Files
PEArch/Includes/ImageNtHeaderHelper.pbi
T

161 lines
4.5 KiB
Plaintext

;{- Code Header
; ==- Basic Info -================================
; Name: ImageNtHeaderHelper.pbi
; Version: 0.0.2
; Author: Herwin Bozet (NibblePoker)
;
; ==- Compatibility -=============================
; Compiler version:
; * PureBasic 5.73 LTS (x86/x64)
; * PureBasic 6.0 LTS (x64)
; * PureBasic 6.0 LTS - C Backend (x64)
;
; ==- Links & License -===========================
; License: CC0 1.0 Universal (Public Domain)
; GitHub: https://github.com/aziascreations/PB-PEArch
;}
;- Module declaration
DeclareModule ImageNtHeaderHelper
Enumeration INHH_ErrorCodes
#INHH_ERROR_None = 0
#INHH_ERROR_IdAlreadyUsed
#INHH_ERROR_IdNotfound
#INHH_ERROR_CannotOpenFile
#INHH_ERROR_CannotCreateFileMapping
#INHH_ERROR_CannotMapViewOfFile
#INHH_ERROR_CannotRetrieveHeaders
#INHH_ERROR_InvalidId
EndEnumeration
; Loads the given file into memory, maps a view of it into memory and attempts to retrieve the IMAGE_NT_HEADERS32 structure.
Declare.i GetImageNtHeader32(ImageNtHeaderId.i, FilePath$)
;
Declare.i FreeImageNtHeader32(ImageNtHeaderId.i)
;
Declare.i GetLastError()
Declare ClearLastError()
EndDeclareModule
;- Module definition
Module ImageNtHeaderHelper
EnableExplicit
CompilerIf Not Defined(SEC_IMAGE_NO_EXECUTE, #PB_Constant)
#SEC_IMAGE_NO_EXECUTE = $11000000
CompilerEndIf
Structure OpenImageNtHeader
FileId.i
*ViewAddress
*RetrievedNtHeaders
EndStructure
Global LastErrorCode.i = 0
Global NewMap OpenImageNtHeaders.OpenImageNtHeader()
Procedure.i GetImageNtHeader32(ImageNtHeaderId.i, FilePath$)
; Handling the ID and the map
Define ImageNtHeaderId$
If ImageNtHeaderId = #PB_Any
DebuggerError("Unable to us #PB_Any as 'ImageNtHeaderId' !")
LastErrorCode = #INHH_ERROR_InvalidId
Goto INHH_GetImageNtHeader32_BadEnding
Else
ImageNtHeaderId$ = Str(ImageNtHeaderId)
If FindMapElement(OpenImageNtHeaders(), ImageNtHeaderId$) <> #Null
Debug "The value used for 'ImageNtHeaderId' was already in use ! (" + ImageNtHeaderId$ + ")"
LastErrorCode = #INHH_ERROR_IdAlreadyUsed
ProcedureReturn #Null
EndIf
EndIf
AddMapElement(OpenImageNtHeaders(), ImageNtHeaderId$)
; Opening the file
Define InputFileHandle = ReadFile(#PB_Any, FilePath$)
If InputFileHandle = 0
Debug "Unable to open input file !"
LastErrorCode = #INHH_ERROR_CannotOpenFile
Goto INHH_GetImageNtHeader32_BadEnding
EndIf
OpenImageNtHeaders()\FileId = InputFileHandle
; Mapping the file into memory
Define InputFileMappingHandle = CreateFileMapping_(FileID(InputFileHandle), #Null, #PAGE_READONLY | #SEC_IMAGE_NO_EXECUTE, 0, 0, #Null)
If InputFileMappingHandle = #ERROR_ALREADY_EXISTS Or InputFileMappingHandle = 0
Debug "Unable to create a file mapping !"
LastErrorCode = #INHH_ERROR_CannotCreateFileMapping
Goto INHH_GetImageNtHeader32_CloseInputFileHandle
EndIf
Define InputFileViewPtr.i = MapViewOfFile_(InputFileMappingHandle, #FILE_MAP_READ, 0, 0, 0)
If InputFileViewPtr = #Null
Debug "Unable to map the input file into memory !"
LastErrorCode = #INHH_ERROR_CannotMapViewOfFile
Goto INHH_GetImageNtHeader32_CloseInputFileHandle
EndIf
OpenImageNtHeaders()\ViewAddress = InputFileViewPtr
; Retrieving the NT headers
Define *RetrievedNtHeaders.IMAGE_NT_HEADERS32 = ImageNtHeader_(InputFileViewPtr)
If *RetrievedNtHeaders = #Null
Debug "Unable to retrieve the NT headers !"
LastErrorCode = #INHH_ERROR_CannotRetrieveHeaders
Goto INHH_GetImageNtHeader32_UnmapFileView
EndIf
OpenImageNtHeaders()\RetrievedNtHeaders = *RetrievedNtHeaders
ProcedureReturn *RetrievedNtHeaders
; Error cases
INHH_GetImageNtHeader32_UnmapFileView:
UnmapViewOfFile_(InputFileViewPtr)
INHH_GetImageNtHeader32_CloseInputFileHandle:
CloseFile(InputFileHandle)
INHH_GetImageNtHeader32_BadEnding:
DeleteMapElement(OpenImageNtHeaders(), ImageNtHeaderId$)
ProcedureReturn #Null
EndProcedure
Procedure.i FreeImageNtHeader32(ImageNtHeaderId.i)
Define ImageNtHeaderId$ = Str(ImageNtHeaderId)
Define *HeaderInternalData.OpenImageNtHeader = FindMapElement(OpenImageNtHeaders(), ImageNtHeaderId$)
If *HeaderInternalData = #Null
ProcedureReturn #INHH_ERROR_IdNotfound
EndIf
UnmapViewOfFile_(*HeaderInternalData\ViewAddress)
CloseFile(*HeaderInternalData\FileId)
ProcedureReturn #Null
EndProcedure
Procedure.i GetLastError()
ProcedureReturn LastErrorCode
EndProcedure
Procedure ClearLastError()
LastErrorCode = 0
EndProcedure
EndModule