|
-
May 22nd, 2016, 05:57 PM
#3
Re: [VB6] Loader, shellcode, without runtime...
Okay, let's return to the data directories. As we saw there is 16 items in this catalog. Usually, a PE file doesn't use all of them. Let's consider the structure of single item:
Code:
Private Type IMAGE_DATA_DIRECTORY
VirtualAddress As Long
Size As Long
End Type
This structure consist two fields. The first fields contains the offset (RVA) to the data of the catalog, second - size. When an item of data catalog is not required it contains zero in the both fields. An VB6-compiled application generally contains only 4 items: import table , resource table , bound import table and import address table (IAT). Now we consider the resource table that has the IMAGE_DIRECTORY_ENTRY_RESOURCE index, because we work with this imformation in the compiler application.
All the resources in the exe file are represented as the tree with triple depth. The first level defines the resource type (RT_BITMAP, RT_MANIFEST, RT_RCDATA, etc.), the next level defines the resource identifier, the third level defines language. In the standard resource editor you can change the first two levels. All the resources placed in the resources table located in a '.rsrc' section of the exe file. Regarding the resources structure we even can change it after compilation. In oredr to access to resources we should read the IMAGE_DIRECTORY_ENTRY_RESOURCE catalog from the optional header. The 'VirtualAddress' field of this structure contains the RVA of the resource table which has the following structure:
Code:
Type IMAGE_RESOURCE_DIRECTORY
Characteristics As Long
TimeDateStamp As Long
MajorVersion As Integer
MinorVersion As Integer
NumberOfNamedEntries As Integer
NumberOfIdEntries As Integer
End Type
This structure describes all the resources in PE file. The first four fields are not important, the 'NumberOfNamedEntries' and 'NumberOfIdEntries' contain the number of named items and the items with the numerical id respectively. For instance, when you add an image in 'VB Resource Editor' it'll add a numerical item with id = 2 (RT_BITMAP). The items are after this structure and have the following form:
Code:
Type IMAGE_RESOURCE_DIRECTORY_ENTRY
NameId As Long
OffsetToData As Long
End Type
The first field of this structure defines either an item name or an item id depending on the most significant bit. If this bit is set the remained bits show the offset from beginning of resources to IMAGE_RESOURCE_DIR_STRING_U structure that has the following format:
Code:
Type IMAGE_RESOURCE_DIR_STRING_U
Length As Integer
NameString As String
End Type
Note that this is not the proper VB structure is shown for descriptive reasons. The first two bytes is the unsigned short (the closest analog is Integer) that show the length of the unicode string (in characters) that follows them. Thus, in order to obtain a string we should read the first two bytes to an integer, allocate memory for the string with the read value size, and read the remaining data to the string variable. Conversely, if the most significant bit of the 'NameId' field is cleared the field containts an identifier (RT_BITMAP in the previous case). The 'OffsetToData' field has two interpretations too. If the MSB is set it is the offset (from beginnig of resources) to the next level of tree i.e. to an IMAGE_RESOURCE_DIRECTORY structure. Otherwise, if the MSB is cleared this is the offset (from beginning of resources too) to a "leave" of the tree, i.e. to structure IMAGE_RESOURCE_DATA_ENTRY:
Code:
Type IMAGE_RESOURCE_DATA_ENTRY
OffsetToData As Long
Size As Long
CodePage As Long
Reserved As Long
End Type
The most important fields of this structure are 'OffsetToData' and 'Size' that contain the RVA and Size of the raw data of the resource. Now we can get all the resources from a PE file.
Compilation.
So... When you start the compilation it calls the Compile function. Firstly it packs all the storage items and execute items to binary format (BinProject, BinStorageListItem, etc.) and forms the string table and the files table. The string table is saves as the unicode strings with the null-terminating characters. I use special class clsStream for safe working with binary data. This class allows to read/write any data or streams into the binary buffer, compress buffer. I use RtlCompressBuffer function for compression stream that uses LZ-compression method. After packing and compression it check output project format. It is supports two formats: bin (raw project data), and exe (loader). The binary format is not interesting right now, we will consider the exe format. Firstly, it extracts all the resources from the main executable to the three-level catalog. This operation is performed by ExtractResources function. An identifier name is saved as the "#" symbol with the appended string that represents the resource id in the decimal format. Afterwards it clones the loader template to the resulting file, then begins to modify the resources in this file using BeginUpdateResource api. Then it alternately copies all the extracted resources (UpdateResource), binary project and mainfest (if needed) to the resulting file and applies changes with EndUpdateResource function. Again, the binary project is saved with "PROJECT" name and RT_DATA type. Basically that's it.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|