The MASM Forum Archive 2004 to 2012

General Forums => The Laboratory => Topic started by: Dimarik__ on February 26, 2012, 12:46:12 PM

Title: load file as PE-loader
Post by: Dimarik__ on February 26, 2012, 12:46:12 PM
I want to work with PE-files. But I found that I can't use all addresses (RVA) without change them. For example, I want to know, where starts and ends Section table. But I can't add PointerToRawData from IMAGE_SECTION_HEADER to base address of loaded PE-file. I should to change this adress to work with him. But I found in the Internet, that if I load PE file like PE-loader, I can work with all addresses withoun changes.
Please, tell me algoritm, how to load file as PE-loader.
I started to do this, but I can't finish this.
.586p
.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib

include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib


.data
struct_IMAGE_DOS_HEADER IMAGE_DOS_HEADER <?>;for load this file like PE-loader
struct_IMAGE_NT_HEADERS IMAGE_NT_HEADERS <?>;for load this file like PE-loader
struct_IMAGE_FILE_HEADER IMAGE_FILE_HEADER <?>;for load this file like PE-loader
struct_OPTIONAL_HEADER OPTIONAL_HEADER <?>;;for load this file like PE-loader
struct_IMAGE_DATA_DIRECTORY IMAGE_DATA_DITECTORY 16 dup <?>;;for load this file like PE-loader
struct_IMAGE_SECTION_HEADER IMAGE_SECTION_HEADER 100 dup <?>;for load this file like PE-loader
DD_baseAddress_ReturnedVirtualAlloc DD ?;base address
DD_numberOfBytesToRead DD ?;for function  ReadFile
DD_hFile DD ?
DW_numberOfSections DW ?
DD_addressOfIMAGE_DOS_HEADER DD ?
DD_addressOfIMAGE_FILE_HEADER DD ?
DD_addressOfIMAGE_OPTIONAL_HEADER DD ?
DD_addressOfIMAGE_NT_HEADERS DD ?
DD_addressOfDataDirectory DD ?
DD_addressOfIMAGE_SECTION_HEADER DD ?
.code
_start:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;load file like PE-loader
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Step 1. Open file
push 0
push FILE_ATTRIBUTE_NORMAL;The file does not have other attributes set. This attribute is valid only if used alone.
push OPEN_EXISTING
push 0
push FILE_SHARE_DELETE
push GENERIC_WRITE or GENERIC_READ
push offset DB_strAddress
call CreateFileA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

cmp EAX, -1;
jz EXIT

mov DD_hFile, EAX

mov EBX, EAX
assume EBX:IMAGE_DOS_HEADER
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
invoke ReadFile, EBX, struct_IMAGE_DOS_HEADER, sizeof struct_IMAGE_DOS_HEADER, DD_numberOfBytesToRead, 0
invoke SetFilePointer,EBX,struct_IMAGE_DOS_HEADER.e_lfanew,0,FILE_BEGIN; set pointer to DOS-header
invoke ReadFile, EBX, struct_IMAGE_NT_HEADERS, sizeof struct_IMAGE_NT_HEADERS, DD_numberOfBytesToRead, 0
invoke SetFilePointer,EBX,struct_IMAGE_NT_HEADERS.FileHeader,0,FILE_CURRENT;set pointer to PE-header
invoke ReadFile, EBX, struct_IMAGE_FILE_HEADER, sizeof struct_IMAGE_FILE_HEADER, DD_numberOfBytesToRead, 0
mov CX, struct_IMAGE_FILE_HEADER.NumberOfSections
mov DW_numberOfSections, CX;number of sections in the file
invoke SetFilePointer, EBX, struct_IMAGE_NT_HEADERS.OptionalHeader,
0, FILE_CURRENT;set pointer to Optional header
invoke ReadFile, EBX, struct_IMAGE_OPTIONAL_HEADER, sizeof struct_IMAGE_OPTIONAL_HEADER,
DD_numberOfBytesToRead, 0
invoke SetFilePointer, EBX, struct_IMAGE_OPTIONAL_HEADER.DataDirectory,
0, FILE_CURRENT;set pointer to IMAGE_DATA_DIRECTORY
mov CX, sizeof IMAGE_DATA_DIRECTORY
mul CX, 16;size of filled array
mov DD_addressOfIMAGE_SECTION_HEADER, EAX
add DD_addressOfIMAGE_SECTION_HEADER, CX;address of IMAGE_SECTION_HEADER
invoke ReadFile, EBX, struct_IMAGE_DATA_DIRECTORY, CX, DD_numberOfBytesToRead, 0;fill IMAGE_DATA_DIRECTORY


invoke VirtualAlloc,0,struct_IMAGE_OPTIONAL_HEADER.SizeOfImage,MEM_COMMIT,PAGE_READWRITE
mov DD_baseAddress_ReturnedVirtualAlloc, EAX
movzx ESI, DW_numberOfSections
movzx EDX, DW_numberOfSections
mul ESI, EDX;size of array IMAGE_SECTION_HEADER
invoke SetFilePointer, EBX, DD_addressOfIMAGE_SECTION_HEADER,
0, FILE_CURRENT;set pointer to IMAGE_SECTION_HEADER
invoke ReadFile, EBX, struct_IMAGE_DATA_DIRECTORY, CX, DD_numberOfBytesToRead, 0;fill IMAGE_SECTION_HEADER

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
EXIT:
invoke ExitProcess,0
end _start

P.S. If you can, speak simply, and sorry for my bad English, I'm from Russia.
Title: Re: load file as PE-loader
Post by: dedndave on February 26, 2012, 08:27:30 PM
maybe this will help...

http://www.masm32.com/board/index.php?topic=13135.0
Title: Re: load file as PE-loader
Post by: dedndave on February 26, 2012, 08:36:05 PM
i didn't look it up, but it seems to me that you should be using DWORD-size, instead of WORD-size operations
Я не смотрел его, но мне кажется, что вы должны использовать DWORD размера, а размер WORD-операций
        mov     CX,sizeof IMAGE_DATA_DIRECTORY
        mul     CX,16 ;size of filled array
        mov     DD_addressOfIMAGE_SECTION_HEADER,EAX
        add     DD_addressOfIMAGE_SECTION_HEADER,CX ;address of IMAGE_SECTION_HEADER


i don't think this is a valid instruction form
Я не думаю, что это действительно форма инструкции
        mul     CX,16

you can use this to multiply a register by 16, provided the value is reasonably small
Вы можете использовать это, чтобы умножить регистр на 16 при условии, что значение сравнительно небольшие
        shl     ecx,4

you can also let the assembler do some of the work because it is a constant that is known at assembly-time
Вы также можете позволить ассемблер сделать часть работы, потому что это константа, которая, как известно на собрании времени
        mov     DD_addressOfIMAGE_SECTION_HEADER,16*sizeof IMAGE_DATA_DIRECTORY

i don't need to look this one up - i know all the parameters must be DWORD-size - try ECX
Я не нужно искать эту вверх - я знаю, что все параметры должны быть DWORD размера - попробуйте ECX
        invoke  ReadFile, EBX, struct_IMAGE_DATA_DIRECTORY, CX, DD_numberOfBytesToRead, 0
Title: Re: load file as PE-loader
Post by: Dimarik__ on February 27, 2012, 06:27:09 AM
Thank you, I'll read this documentation.
Title: Re: load file as PE-loader
Post by: Dimarik__ on February 27, 2012, 10:01:42 AM
At this moment I'm reading documentation about Section Table (sections headers).
There is written about field "VirtuallAddress": "For executable images, the address of the first byte of the section relative to the image base when the section is loaded into memory." And about PointerToRawData: "The file pointer to the first page of the section within the COFF file. For executable images, this must be a multiple of FileAlignment from the optional header.".
If you can, answer f few questions:
1. Is COFF files a file which is created bu compiler and used by linker? If I'm wrong, please, explain what is this file.
2. PointerToRawData is used only in COFF files and doesn't used in PE-files? If PointerToRawData is used in PE-files, what is the difference between field PointerToRawData and field VirtuallAddress?
Title: Re: load file as PE-loader
Post by: dedndave on February 27, 2012, 11:39:01 AM
1. yes - the COFF format is used for OBJ files, which are input to the linker
2. correct - PointerToRawData is a COFF file member however, the term "raw data" may apply to any section type
the VirtualAddress is essentially the RVA (relative virtual address), which generally applies to PE files after they are loaded into memory
this is the offset of the object in memory from the base address of the module
typically, the base address for the module when loaded is 00400000h
Title: Re: load file as PE-loader
Post by: Dimarik__ on February 27, 2012, 01:02:36 PM
Thank you
Title: Re: load file as PE-loader
Post by: vanjast on February 27, 2012, 09:05:38 PM
Dave.. how did you translate to Russian.. and can you do it from Russian to English (a translater site) ?
:8)
Title: Re: load file as PE-loader
Post by: dedndave on February 27, 2012, 09:29:25 PM
didn't you know i speak Russian fluently ?   :bg

http://translate.google.com/

i have that as one of my bookmarks and use it all the time
you can place text or a URL in the left pane and it will usually translate
Title: Re: load file as PE-loader
Post by: clive on February 27, 2012, 09:44:10 PM
You should probably not assume the size of the header, and instead read the SizeOfOptionalHeader, and use that to get to the section table

And yes, you'll need to traverse the section table to convert virtual addresses to offsets in the file image. There is not always a direct relationship, and some sections do not have file data behind them.

You have to convert the Offset into a Section's VirtualAddress, and convert that to a file offset using PointerToRawData.

When the Windows Loader loads an image into memory it likely changes the header/section structures to reflect that.

Title: Re: load file as PE-loader
Post by: Dimarik__ on March 03, 2012, 01:36:23 PM
I've read about Certificate Data.
Quote4.7.1. Certificate Data
As stated in the preceding section, the certificates in the attribute certificate table can contain any certificate type. Certificates that ensure a PE file's integrity may include a PE image hash.
A PE image hash (or file hash) is similar to a file checksum in that the hash algorithm produces a message digest that is related to the integrity of a file. However, a checksum is produced by a simple algorithm and is used primarily to detect whether a block of memory on disk has gone bad and the values stored there have become corrupted. A file hash is similar to a checksum in that it also detects file corruption. However, unlike most checksum algorithms, it is very difficult to modify a file without changing the file hash from its original unmodified value. A file hash can thus be used to detect intentional and even subtle modifications to a file, such as those introduced by viruses, hackers, or Trojan horse programs.
When included in a certificate, the image digest must exclude certain fields in the PE Image, such as the Checksum and Certificate Table entry in Optional Header Data Directories. This is because the act of adding a Certificate changes these fields and would cause a different hash value to be calculated.
The Win32 ImageGetDigestStream function provides a data stream from a target PE file with which to hash functions. This data stream remains consistent when certificates are added to or removed from a PE file. Based on the parameters that are passed to ImageGetDigestStream, other data from the PE image can be omitted from the hash computation. For a link to the function's reference page, see "References."
Can you tell me, where is this certificate located? As I understood it is located in some header like Optional header. But in which header and how I should address to this field?
Title: Re: load file as PE-loader
Post by: clive on March 03, 2012, 03:25:01 PM
Quote from: Dimarik__ on March 03, 2012, 01:36:23 PM
Can you tell me, where is this certificate located? As I understood it is located in some header like Optional header. But in which header and how I should address to this field?

Wouldn' it be in the Security directory entry?
Title: Re: load file as PE-loader
Post by: donkey on March 03, 2012, 03:56:33 PM
Don't have any experience with certificates but the certificate table address is located at offset 128 (x32) or 144 (x64) in the IMAGE_DATA_DIRECTORY entries of the IMAGE_OPTIONAL_HEADER. Note that the certificate table address is a file offset, not an RVA so it has to be handled as a special case, though it always just appended to the end of the file.
Title: Re: load file as PE-loader
Post by: Dimarik__ on March 03, 2012, 04:05:14 PM
Quote from: donkey on March 03, 2012, 03:56:33 PM
Don't have any experience with certificates but the certificate table address is located at offset 128 (x32) or 144 (x64) in the IMAGE_DATA_DIRECTORY entries of the IMAGE_OPTIONAL_HEADER. Note that the certificate table address is a file offset, not an RVA so it has to be handled as a special case, though it always just appended to the end of the file.
Please, clarify difference between RVA and file offset. I understood that file offset used with files on hard disk. RVA used when whis file was loaded into the memory by PE-loader. And if you want to work with RVA, you should convert them to file offset. Am I right?
Title: Re: load file as PE-loader
Post by: donkey on March 03, 2012, 04:14:40 PM
RVA or Relative Virtual Address is a memory offset from an unknown base. Generally it is added to the load address of the PE resulting in the actual virtual memory address of a particular peice of data. For example the first entry in the DATA section might have an RVA of 0x1000, if the PE is loaded at 0x400000, the actual VA (Virtual Address) is 0x401000. It is a method of allowing each section to be relocated in memory without have too much to fix up by the PE loader. The file offset is simply the number of bytes from the beginning of the file.
Title: Re: load file as PE-loader
Post by: Dimarik__ on March 04, 2012, 07:47:04 AM
Quote from: donkey on March 03, 2012, 04:14:40 PM
RVA or Relative Virtual Address is a memory offset from an unknown base. Generally it is added to the load address of the PE resulting in the actual virtual memory address of a particular peice of data. For example the first entry in the DATA section might have an RVA of 0x1000, if the PE is loaded at 0x400000, the actual VA (Virtual Address) is 0x401000. It is a method of allowing each section to be relocated in memory without have too much to fix up by the PE loader. The file offset is simply the number of bytes from the beginning of the file.
Thank you very much.
Title: Re: load file as PE-loader
Post by: Vortex on March 04, 2012, 09:31:12 AM
Hi Dimarik,

Here is a project to create a simple PE loader :

Loading and running EXEs and DLLs from memory (http://www.masm32.com/board/index.php?topic=3150.0)
Title: Re: load file as PE-loader
Post by: Dimarik__ on March 05, 2012, 05:26:52 AM
Quote from: Vortex on March 04, 2012, 09:31:12 AM
Hi Dimarik,

Here is a project to create a simple PE loader :

Loading and running EXEs and DLLs from memory (http://www.masm32.com/board/index.php?topic=3150.0)
Thank you for the reference.
Title: Re: load file as PE-loader
Post by: dedndave on March 05, 2012, 06:39:47 AM
Erol always has nice stuff   :bg
check out his site for some great tools
http://www.vortex.masmcode.com/
Title: Re: load file as PE-loader
Post by: Dimarik__ on March 05, 2012, 08:32:41 AM
I found some interesting about linkers and loaders and I'm going to read this. If you want you can view this article. I uploaded it here http://zalil.ru/32821967
Title: Re: load file as PE-loader
Post by: vanjast on March 05, 2012, 10:42:59 AM
looks interesting..  :U
Title: Re: load file as PE-loader
Post by: Dimarik__ on March 05, 2012, 12:34:37 PM
Quote from: vanjast on March 05, 2012, 10:42:59 AM
looks interesting..  :U
When I was searcing this information, I wanted to find algorithm where describes, how Windows loads PE-file into the memory. But... I understood that Vortex's theme and his code is more useful for me that my article. Thank you))) I'll study this information by your code=)
Title: Re: load file as PE-loader
Post by: Dimarik__ on March 05, 2012, 04:34:02 PM
Quote from: Vortex on March 04, 2012, 09:31:12 AM
Hi Dimarik,

Here is a project to create a simple PE loader :

Loading and running EXEs and DLLs from memory (http://www.masm32.com/board/index.php?topic=3150.0)
Thank you for code. It is the best material which I've ever seen by this theme.
But I didn't understand one comment in your code:
mov   [ecx+eax*4], edi                  ;<----- Save API address at IAT
It's in the file import.asm
Please, explain, what is the IAT?
Title: Re: load file as PE-loader
Post by: dedndave on March 06, 2012, 03:00:51 AM
Import Address Table

typically, when the OS loads an exe, the functions called are referenced in the IAT
the OS fills in the addresses of the actual code

it might looks something like this before it is loaded
00401DB4: FF2534234000 jmp dword[00402334 ->00002398 GetStdHandle] ;call kernel32.GetStdHandle
00401DBA: FF2540234000 jmp dword[00402340 ->000023C2 ExitProcess]  ;call kernel32.ExitProcess
00401DC0: FF2544234000 jmp dword[00402344 ->000023D0 ReadFile]     ;call kernel32.ReadFile
00401DC6: FF2548234000 jmp dword[00402348 ->000023DC CloseHandle]  ;call kernel32.CloseHandle
00401DCC: FF2574234000 jmp dword[00402374 ->00002494 WriteFile]    ;call kernel32.WriteFile


when your program calls a function, it actually calls a jmp in the IAT

sometimes, a program may use LoadModule and GetProcAddress to get the address of a function
in such cases, a "fake" entry can be made in the code or data section to emulate the IAT

here is a simple example by Erol (Vortex)
http://www.masm32.com/board/index.php?topic=11772.msg89003#msg89003
Title: Re: load file as PE-loader
Post by: Dimarik__ on March 06, 2012, 08:55:16 AM
I read this article and saw that the autor had recommended to read one article.
QuoteI highly recommend reading Russell Osterlund's article in this issue which describes the steps that the Windows loader takes.
Can you tell me where I can find this article or where I can find similar article?
Title: Re: load file as PE-loader
Post by: dedndave on March 06, 2012, 09:54:52 AM
http://www.smidgeonsoft.prohosting.com/

http://www.smidgeonsoft.prohosting.com/documentation.html

QuoteI highly recommend reading Russell Osterlund's article in this issue which describes the steps that the Windows loader takes.

where did you see that reference ?

here we go - try this...
http://msdn.microsoft.com/en-us/magazine/cc301727.aspx
Title: Re: load file as PE-loader
Post by: Dimarik__ on March 06, 2012, 06:29:12 PM
Quote from: dedndave on March 06, 2012, 09:54:52 AM
http://www.smidgeonsoft.prohosting.com/

http://www.smidgeonsoft.prohosting.com/documentation.html

QuoteI highly recommend reading Russell Osterlund's article in this issue which describes the steps that the Windows loader takes.

where did you see that reference ?

here we go - try this...
http://msdn.microsoft.com/en-us/magazine/cc301727.aspx
I saw it here http://msdn.microsoft.com/en-us/magazine/cc301808.aspx