PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197 Inside the executable: a VB programmer's guide to the portable executable format-VBForums
Inside the executable: a VB programmer's guide to the portable executable format
Introduction
The Portable Executable Format is the data structure that describes how the various parts of a Win32
executable file are held together. It allows the operating system to load the executable and to locate the dynamically
linked libraries required to run that executable and to navigate the code,data and resource sections compiled into that
executable. Getting over DOS
The PE Format was created for Windows but Microsoft had to make sure that running such an executable in DOS would
yield a meaningful error message and exit. To this end the very first bit of a windows executable file is actually a DOS
executable (sometimes known as the stub) which writes "This program requires Windows" or similar then exits.
The format of the DOS stub is:
VB Code:
PrivateType IMAGE_DOS_HEADER
e_magic AsInteger''\\ Magic number
e_cblp AsInteger''\\ Bytes on last page of file
e_cp AsInteger''\\ Pages in file
e_crlc AsInteger''\\ Relocations
e_cparhdr AsInteger''\\ Size of header in paragraphs
e_minalloc AsInteger''\\ Minimum extra paragraphs needed
e_maxalloc AsInteger''\\ Maximum extra paragraphs needed
e_ss AsInteger''\\ Initial (relative) SS value
e_sp AsInteger''\\ Initial SP value
e_csum AsInteger''\\ Checksum
e_ip AsInteger''\\ Initial IP value
e_cs AsInteger''\\ Initial (relative) CS value
e_lfarlc AsInteger''\\ File address of relocation table
e_oeminfo AsInteger''\\ OEM information; e_oemid specific
e_res2(0 To 9) AsInteger''\\ Reserved words
e_lfanew AsLong''\\ File address of new exe header
EndType
The only field of this structure that is of interest to Windows is e_lfanew which is the file pointer to the new
Windows executable header. To skip over the DOS part of the program, set the file pointer to the value held in this field:
The NT header
The NT header holds the information needed by the windows program loader to load the program. It consists of the PE File signature
followed by an IMAGE_FILE_HEADER and IMAGE_OPTIONAL_HEADER records.
For applications designed to run under Windows (i.e. not OS/2 or VxD files) the four bytes of the PE File signature should equal &h4550.
The other defined signatures are:
VB Code:
PublicEnum ImageSignatureTypes
IMAGE_DOS_SIGNATURE = &H5A4D ''\\ MZ
IMAGE_OS2_SIGNATURE = &H454E ''\\ NE
IMAGE_OS2_SIGNATURE_LE = &H454C ''\\ LE
IMAGE_VXD_SIGNATURE = &H454C ''\\ LE
IMAGE_NT_SIGNATURE = &H4550 ''\\ PE00
EndEnum
Following the PE file signature is the IMAGE_NT_HEADERS structure that stores information about the target environment of the executable.
The structure is:
VB Code:
PrivateType IMAGE_FILE_HEADER
Machine AsInteger
NumberOfSections AsInteger
TimeDateStamp AsLong
PointerToSymbolTable AsLong
NumberOfSymbols AsLong
SizeOfOptionalHeader AsInteger
Characteristics AsInteger
EndType
The Machine member describes what target CPU the executable was compiled for. It can be one of:
IMAGE_FILE_MACHINE_ARM = &H1C0 ''\\ ARM Little-Endian
IMAGE_FILE_MACHINE_IA64 = &b00 ''\\ Intel 64
EndEnum
The SizeOfOptionalHeader member indicates the size (in bytes) of the IMAGE_OPTIONAL_HEADER structure that immediatley follows it.
In practice this structure is not optional so that is a bit of a misnomer. This structure is defined as:
VB Code:
PrivateType IMAGE_OPTIONAL_HEADER
Magic AsInteger
MajorLinkerVersion AsByte
MinorLinkerVersion AsByte
SizeOfCode AsLong
SizeOfInitializedData AsLong
SizeOfUninitializedData AsLong
AddressOfEntryPoint AsLong
BaseOfCode AsLong
BaseOfData AsLong
EndType
and this in turn is immediately followed by the IMAGE_OPTIONAL_HEADER_NT structure:
VB Code:
PrivateType IMAGE_OPTIONAL_HEADER_NT
ImageBase AsLong
SectionAlignment AsLong
FileAlignment AsLong
MajorOperatingSystemVersion AsInteger
MinorOperatingSystemVersion AsInteger
MajorImageVersion AsInteger
MinorImageVersion AsInteger
MajorSubsystemVersion AsInteger
MinorSubsystemVersion AsInteger
Win32VersionValue AsLong
SizeOfImage AsLong
SizeOfHeaders AsLong
CheckSum AsLong
Subsystem AsInteger
DllCharacteristics AsInteger
SizeOfStackReserve AsLong
SizeOfStackCommit AsLong
SizeOfHeapReserve AsLong
SizeOfHeapCommit AsLong
LoaderFlags AsLong
NumberOfRvaAndSizes AsLong
DataDirectory(0 To 15) As IMAGE_DATA_DIRECTORY
EndType
The most useful field of this structure (to my purposes, anyhow) are the 16 IMAGE_DATA_DIRECTORY entries. These describe whereabouts
(if at all) the particular sections of the executable are located. The structure is defined thus:
Note that is an executable does not contain one of the sections (as is often the case) there will be an IMAGE_DATA_DIRECTORY for it but the
address and size will both be zero. The image data directories
The image data directories...continued The exports directory
The exports directory holds details of the functions exported by this executable. For example, if you were to look in the exports directory
of the MSVBVM50.dll it would list all the functions it exports that make up the visual basic 5 runtime environment.
This directory consists of some info to tell you how many exported functions there are followed by three parallel arrays which give you the
address, name and ordinal of the functions respectively. The structure is defined thus:
VB Code:
PrivateType IMAGE_EXPORT_DIRECTORY
Characteristics AsLong
TimeDateStamp AsLong
MajorVersion AsInteger
MinorVersion AsInteger
lpName AsLong
Base AsLong
NumberOfFunctions AsLong
NumberOfNames AsLong
lpAddressOfFunctions AsLong'\\ Three parrallel arrays...(LONG)
lpAddressOfNames AsLong'\\ (LONG)
lpAddressOfNameOrdinals AsLong'\\ (INTEGER)
EndType
And you can read this info from the executable thus:
VB Code:
PrivateSub ProcessExportTable(ExportDirectory As IMAGE_DATA_DIRECTORY)
Dim deThis As IMAGE_EXPORT_DIRECTORY
Dim lBytesWritten AsLong
Dim lpAddress AsLong
Dim nFunction AsLong
If ExportDirectory.VirtualAddress > 0 And ExportDirectory.Size > 0 Then
The imports directory
The imports directory lists the dynamic link libraries that this executable depends on and which functions it imports from that dynamic link library.
It consists of an array of IMAGE_IMPORT_DESCRIPTOR structures terminated by an instance of this structure where the lpName parameter is zero.
The structure is defined as:
VB Code:
PrivateType IMAGE_IMPORT_DESCRIPTOR
lpImportByName AsLong''\\ 0 for terminating null import descriptor
TimeDateStamp AsLong''\\ 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 AsLong''\\ -1 if no forwarders
lpName AsLong
lpFirstThunk AsLong''\\ RVA to IAT (if bound this IAT has actual addresses)
EndType
And you can walk the import directory thus:
VB Code:
PrivateSub ProcessImportTable(ImportDirectory As IMAGE_DATA_DIRECTORY)
Dim lpAddress AsLong
Dim diThis As IMAGE_IMPORT_DESCRIPTOR
Dim byteswritten AsLong
Dim sName AsString
Dim lpNextName AsLong
Dim lpNextThunk AsLong
Dim lImportEntryIndex AsLong
Dim nOrdinal AsInteger
Dim lpFuncAddress AsLong
'\\ If the image has an imports section...
If ImportDirectory.VirtualAddress > 0 And ImportDirectory.Size > 0 Then
The resource directory
The structure of the resource director is somewhat more involved. It consists of a root directory (defined by the structure IMAGE_RESOURCE_DIRECTORY immediately followed by a number of resource directory entries (defined by the structure
IMAGE_RESOURCE_DIRECTORY_ENTRY). These are defined thus:
VB Code:
PrivateType IMAGE_RESOURCE_DIRECTORY
Characteristics AsLong'\\Seems to be always zero?
TimeDateStamp AsLong
MajorVersion AsInteger
MinorVersion AsInteger
NumberOfNamedEntries AsInteger
NumberOfIdEntries AsInteger
EndType
PrivateType IMAGE_RESOURCE_DIRECTORY_ENTRY
dwName AsLong
dwDataOffset AsLong
CodePage AsLong
Reserved AsLong
EndType
Each resource directory entry can either point to the actual resource data or to another layer of resource directory entries. If the highest bit of dwDataOffset is set then this points to a directory otherwise it points to the resource data.
How is this information useful?
Once you know how an executable is put together you can use this information to peer into its workings. You can view the resources compiled into
it, the dlls it depends on and the actual functions it imports from them. More importantly you can attach to the executable as a debugger and
track down any of those really troublesome general protection faults. The next article will describe how to attach a debugger and use the PE file
format.
I know its a bit dated - this thread - but I could sure do with some help
Note
It's no virus, as in it's not malicious. All users will be aware of whats going on, though not how it's carried out. Hey, thats where I get my bread and butter from
The Prob.
All commericial and hacker tooled (and the crappy one I coded in VB) EXE Joiners rely solely on the System Temp or some other Hard Disk dump area, to de-bundle and execute the joined executables from that directory. No can do for my App, as its run off a CD-ROM with extensive "App.Path" dependencies.
The Q.
Would it be possible to crack open an EXE with what you have listed above and insert another arbitary EXE which is to be executed when the EXE is launched? If so, could you point me to how to get it done. If not, thanx for taking the time to answer.
Regards
Kaushik Janardhanan
"Brothers, you asked for it."
...Francisco Domingo Carlos Andres Sebastian D'Anconia
Introduction
[P]Windows NT (and successive operating system versions) expose a set of API functions and structures for debugging a running process. This article shows how these can be accessed from Visual Basic (version 5 or 6). It is recomended that the article [a href="http://www.thecodeproject.com/win32/vbdebugger.asp"]Inside the executable: an introduction to the Portable Executable format for VB programmers[/a] be read in conjunction with this article, and the source code attached to it has the code for this article included. [/P]
Getting a process to debug
[P]There are two ways to get a process to debug. Either (a) attach a debugger to a process that is already running or (b) start a new process with a debugger attached to it.[/P]
Starting a new process with a debugger attached
[P]To start a process you can use the CreateProcess API call:[/P]
VB Code:
PrivateDeclareFunction CreateProcess Lib _
"kernel32" Alias "CreateProcessA" (ByVal lpApplicationName AsString, ByVal lpCommandLine AsString, _
ByVal dwCreationFlags As ProcessCreationFlags, ByVal lpEnvironment AsLong, ByVal lpCurrentDirectory AsString, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) AsLong
[P]In addition to the functionality of the Shell command this allows you to specify additional flags that affect how the process is created:[/p]
VB Code:
PublicEnum ProcessCreationFlags
DEBUG_PROCESS = &H1
DEBUG_ONLY_THIS_PROCESS = &H2
CREATE_SUSPENDED = &H4
DETACHED_PROCESS = &H8
CREATE_NEW_CONSOLE = &H10
NORMAL_PRIORITY_CLASS = &H20
IDLE_PRIORITY_CLASS = &H40
HIGH_PRIORITY_CLASS = &H80
REALTIME_PRIORITY_CLASS = &H100
CREATE_NEW_PROCESS_GROUP = &H200
CREATE_UNICODE_ENVIRONMENT = &H400
CREATE_SEPARATE_WOW_VDM = &H800
CREATE_SHARED_WOW_VDM = &H1000
CREATE_FORCEDOS = &H2000
CREATE_DEFAULT_ERROR_MODE = &H4000000
CREATE_NO_WINDOW = &H8000000
EndEnum
[P]In order to start the process with an attached debugger you specify the flags DEBUG_PROCESS + DEBUG_ONLY_THIS_PROCESS
[/P]
Attaching a debugger to an existing process
[P]To attach a debugger to a process which is already running you need to obtain a handle to it and then attach a debugger using the DebugActiveProcess API call[/P]
The debug loop
[P]Once you have attached your debugger to the process you need to go into a debug loop. This consists of waiting for a debug event, processing the event when it comes in and then allowing the debugee to continue.[/P] Waiting for a debug event to occur
[P]To wait for a debug event you call the WaitForDebugEvent API call:[/P]
[P]This will return TRUE when a debug event has occured and fill out the DEBUG_EVENT_... structure, which depends on what event occured but always starts with a DEBUG_EVENT_HEADER:[/P]
VB Code:
PrivateType DEBUG_EVENT_HEADER
dwDebugEventCode As DebugEventTypes
dwProcessId AsLong
dwThreadId AsLong
EndType
Processing the debug event
[P]How you deal with a debug event depends, naturally enough, on what event occured. The event types are:[/P]
VB Code:
PublicEnum DebugEventTypes
EXCEPTION_DEBUG_EVENT = 1&
CREATE_THREAD_DEBUG_EVENT = 2&
CREATE_PROCESS_DEBUG_EVENT = 3&
EXIT_THREAD_DEBUG_EVENT = 4&
EXIT_PROCESS_DEBUG_EVENT = 5&
LOAD_DLL_DEBUG_EVENT = 6&
UNLOAD_DLL_DEBUG_EVENT = 7&
OUTPUT_DEBUG_STRING_EVENT = 8&
RIP_EVENT = 9&
EndEnum
[P]EXCEPTION_DEBUG_EVENT[/P]
[P]This debug event is thrown whenever an exception occurs in the application being debugged. For example if there was code in that application that was attempting to divide by zero then you would get an EXCEPTION_DEBUG_EVENT. The buffer that is passed back for this event is:[/P]
[P]The exception flags tell you if it is possible to resume from the exception or not[/P]
[P]CREATE_THREAD_DEBUG_EVENT[/P]
[P]This event occurs whenever a new thread is created by the debugee application. The buffer that is passed in is:[/P]
VB Code:
PrivateType DEBUG_CREATE_THREAD_DEBUG_INFO
Header As DEBUG_EVENT_HEADER
hThread AsLong
lpThreadLocalBase AsLong
lpStartAddress AsLong
EndType
[P]This gives you a thread handle (for thread control API calls) and the base address and start address of the thread in the debugee process which is useful for analysing the memory of that application[/P]
CREATE_PROCESS_DEBUG_EVENT
This event occurs when the process is created. The buffer passed in is:
VB Code:
PrivateType DEBUG_CREATE_PROCESS_DEBUG_INFO
Header As DEBUG_EVENT_HEADER
hfile AsLong
hProcess AsLong
hThread AsLong
lpBaseOfImage AsLong
dwDebugInfoFileOffset AsLong
nDebugInfoSize AsLong
lpThreadLocalBase AsLong
lpStartAddress AsLong
lpImageName AsLong
fUnicode AsInteger
EndType
You can use the file handle passed in as part of this buffer to find the different parts of the process (imports section, exports, debug information etc.) as per this article
EXIT_THREAD_DEBUG_EVENT
This event occurs when a thread exits. The buffer passed in is:
VB Code:
PrivateType DEBUG_EXIT_THREAD_DEBUG_INFO
Header As DEBUG_EVENT_HEADER
dwExitCode AsLong
EndType
The exit code is whatever the thread set it to but is usually set to be non zero if an error caused the thread exit
EXIT_PROCESS_DEBUG_EVENT
This event occurs when the process exits. The buffer passed in is:
VB Code:
PrivateType DEBUG_EXIT_PROCESS_DEBUG_INFO
Header As DEBUG_EVENT_HEADER
dwExitCode AsLong
EndType
The exit code is whatever the process set it to but is usually set to be non zero if an error caused the thread exit. You should stop the debug loop after you recieve this event.
LOAD_DLL_DEBUG_EVENT
This event occurs when teh application being debugged loads a dynamic link library. The buffer passed in is:
VB Code:
PrivateType DEBUG_LOAD_DLL_DEBUG_INFO
Header As DEBUG_EVENT_HEADER
hfile AsLong
lpBaseOfDll AsLong
dwDebugInfoFileOffset AsLong
nDebugInfoSize AsLong
lpImageName AsLong
fUnicode AsInteger
EndType
You can use the file handle passed in as part of this buffer to find the different parts of the dll (imports section, exports, debug information etc.) as per this article
UNLOAD_DLL_DEBUG_EVENT
This event occurs when the process being debugged unloads a dll it had loaded. The buffer passed in is:
VB Code:
PrivateType DEBUG_UNLOAD_DLL_DEBUG_INFO
Header As DEBUG_EVENT_HEADER
lpBaseOfDll AsLong
EndType
And you can use the lpBaseOfDll value to identify which dll was unloaded
OUTPUT_DEBUG_STRING_EVENT
This event occurs when the debugee calls the API call OutputDebugString to send debugging information to a debugger (where one is attached). The buffer passed in is:
VB Code:
PrivateType DEBUG_OUTPUT_DEBUG_STRING_INFO
Header As DEBUG_EVENT_HEADER
lpDebugStringData AsLong
fUnicode AsInteger
nDebugStringLength AsInteger
EndType
And you can read the string from the debugee using the ReadProcessMemory API call
RIP_EVENT
This occurs if your process being debugged dies unexpectedly. The buffer passed in is:
VB Code:
PrivateType DEBUG_RIP_INFO
Header As DEBUG_EVENT_HEADER
dwError AsLong
dwType AsLong
EndType
Resuming the debugee
Once you have extracted the information you need form the debug event you need to resume the debugee so that it can continue running. To do this you call the ContinueDebugEvent API call:
Further development
To expand on this framework and create a full debugger requires the ability to walk the memory and stack of the process being debugged and also to set breakpoints. I hope to get to this in the next article
Re: Inside the executable: a VB programmer's guide to the portable executable format
Talk about digging up old threads.
Merrion, I saw your code for the PE_Utilities.bas posted on another website can't remember where now. I was trying to convert it over to vb2005 but it is throwing to many errors for me. I'm a hobbiest programmer.
I was wondering if you ever converted this code over to vb.net or if you knew of a way to get header info from a file to determine if it is a exe, dll, sys or whichever executable type in vb.net
→ The Comprehensive Guide to Cloud Computing
A complete overview of Cloud Computing focused on what you need to know, from selecting a platform to choosing a cloud vendor.