Page 1 of 1

Loading a PE file (.exe)q

Posted: Mon Dec 29, 2008 6:47 pm
by sweetgum
Does anyone have any information about loading recent PE files? I have the documentation from micosoft about the format of the file, although there is no information about actually loading one. Im trying to write an OS that can execute pe files, I know that ReactOS can do it and I haven't looked at it yet because of errors i've run into using ReactOS. I'd rather see documentation and do it myself. If someone can contribute this information I'd greatly appreciate it!

Re: Loading a PE file (.exe)q

Posted: Mon Dec 29, 2008 7:07 pm
by Firestryke31
I've found this site useful when I wrote my simple loader. Don't let the big bold "Working with the ELF Program Format" in the middle of the screen scare you off, the PE info is farther down. Some of the terms used are a bit confusing, but once you figure out what they mean it's easy to handle.

My simple loader ATM doesn't do any DLL stuff, because it's just to load the third stage so that I can work in pure Pmode and C/C++, so I didn't really look to see if the site explains that...

Re: Loading a PE file (.exe)q

Posted: Mon Dec 29, 2008 7:18 pm
by sweetgum
Hrm, the information that would be helpful from that document has a FIXME to it (PE file in memory) i've got all the information about the file format. Could you maybe post the source to your loader? How can you load a file without loading it's dlls?

Re: Loading a PE file (.exe)q

Posted: Mon Dec 29, 2008 8:05 pm
by Dex

Re: Loading a PE file (.exe)q

Posted: Mon Dec 29, 2008 10:09 pm
by Firestryke31
sweetgum wrote:How can you load a file without loading it's dlls?
Simple: The exe file I load doesn't need any DLLs. It's the third stage of my boot system, and I did it that way so I could write in 32-bit Pmode C/C++, which is much easier for me than ASM.

Here's my simple code that takes a PE file and puts it into memory. Keep in mind that the setup for this code is that it just got into Pmode and so doesn't have to deal with paging or returning or any of that stuff...
It assumes that the file has been loaded to 0x00100000

Code: Select all

EXELOADADDR 	equ 0x00100000
;; _IMAGE_DOS_HEADER.e_magic: Should be "MZ"
sigMZ			equ esi
;; _IMAGE_DOS_HEADER.e_lfanew: Offset into file where PE header is
PEheaderOffset	equ esi+60
;; _IMAGE_NT_HEADERS.Signature: Should be "PE\0\0"
sigPE			equ esi
;; _IMAGE_NT_HEADERS.FileHeader.NumberOfSections: Self explanatory
NumSections		equ esi+6
;; _IMAGE_NT_HEADERS.IMAGE_OPTIONAL_HEADERS.BaseOfCode: Where the code section should go
BaseOfCode		equ esi+52
;; _IMAGE_NT_HEADERS.IMAGE_OPTIONAL_HEADERS.AddressOfEntryPoint: Offset, relative to load address, of the entry point
EntryAddressOffset	equ esi+40
;; sizeof(_IMAGE_NT_HEADERS.IMAGE_OPTIONAL_HEADERS) + sizeof(_IMAGE_NT_HEADERS.FileHeader): to get to the section directory
SizeOfNT_HEADERS	equ 248

SectionSize		equ esi+8

SectionBase		equ esi+12

SectionFileOffset	equ esi+20

SizeOfSECTION_HEADER	equ 40

	;; Now, let's map in the PE file and run it!
	
	mov esi, EXELOADADDR
	mov eax, [sigMZ]
	;; Compare the first signature
	cmp ax, 0x5A4D
	jnz badPE
	;; If we got here, it's a 'valid' exe.
	;; Let's get the offset to the PE header:
	mov eax, [PEheaderOffset]
	
	add esi, eax
	mov eax, [sigPE]
	;; Now the second
	cmp eax, 0x00004550
	jnz badPE2
	
	;; let us assume (for now) that the PE is for the x86 platform,
	;;  and not, say, ARM or something...
	
	xor edx, edx
	mov dx, [NumSections]
	mov eax, [BaseOfCode]
	mov ebx, [EntryAddressOffset]
	
	;; Add the base of the code to the entry point offset
	;; to get the function pointer
	add ebx, eax
	;; ebx now equals loader's entry point, so let's save it
	push ebx
	
	;; skip the PE header, since we don't need the rest for this simple loader
	add esi, SizeOfNT_HEADERS

.loadloop:
	;; eax still contains BaseOfCode
	;; and dx still contains the number of sections

	;; Get the size of the section
	mov ecx, [SectionSize]
	;; Get the relative address of the section
	mov edi, [SectionBase]
	;; calculate the actual address of the section
	add edi, eax
	;; now get the file offset of the section
	mov ebx, [SectionFileOffset]
	;; and add the load address to get the memory location of the section
	add ebx, EXELOADADDR
	
	;; save where we are in the file
	push esi
	
	;; and copy the section data
	mov esi, ebx
	rep movsb
	
	;; restore our location...
	pop esi
	;; and skip to the next section
	add esi, SizeOfSECTION_HEADER
	
	;; That's one more section down
	dec edx
	;; Are we done yet?
	or edx, edx
	jnz .loadloop

	;; Yes we are! Let's get the entry function pointer and go there!
	pop ebx
	jmp ebx

badPE:
	call cls32
	mov esi, fbLoaderBad
	call putStr32
	cli
	hlt

badPE2:
	call cls32
	mov esi, fbLoaderBad2
	call putStr32
	cli
	hlt

fbLoaderBad:
	db "/BOOT/FBLOADER.EXE is not a valid executable file!",0

fbLoaderBad2:
	db "/BOOT/FBLOADER.EXE is not a Win32/Firebird executable file!",0
It helps to open a real EXE in a hex editor and look through that site I gave you to see what's really going on.

cls32 is my 32-bit Pmode clear screen routine and I think you can figure out putStr32.

I may go through and clean it up a bit later...

EDIT: cleaned up code

Re: Loading a PE file (.exe)q

Posted: Sat Jan 03, 2009 5:38 pm
by sweetgum
Can someone out there help me out with some basic ASM

I have the variable AddressOfEntryPoint and I'd like to jump to ti
how can i pass that variable to a line of asm code that'll just jmp to it

jmp AddressOfEntryPoint

is what im looking for, I can't figure it out with the online manuals for at&t asm

Re: Loading a PE file (.exe)q

Posted: Sat Jan 03, 2009 7:59 pm
by Firestryke31
mov >insert register here<, AddressOfEntryPoint
jmp >insert above register<

I used ebx in my code. You could also do call >register< which would allow the PE to return. Or at least, I think that opcode exists...

Re: Loading a PE file (.exe)q

Posted: Sun Jan 18, 2009 5:32 am
by david
Would you like to email the PE information to me ?

My OS also wants to load the binary file(*.exe).

my email: [email protected]

thank you!

Re: Loading a PE file (.exe)q

Posted: Sun Jan 18, 2009 10:53 am
by Firestryke31
I'm not entirely sure what you're asking. The second post in this thread has a link to a site with the PE format info, and another post contains some ASM code (that should probably be converted to C) for loading an EXE file. There are only a few bits of info missing, but that's what Google's for.

Re: Loading a PE file (.exe)q

Posted: Sun Jan 18, 2009 4:02 pm
by Brynet-Inc
david wrote:Would you like to email the PE information to me ?

My OS also wants to load the binary file(*.exe).

my email: ...

thank you!
Posting your email address like that isn't a very good idea.. ;)

Re: Loading a PE file (.exe)q

Posted: Mon Jan 19, 2009 4:37 am
by Combuster
Posting your email address like that isn't a very good idea.
He posted it so often that I'm not going to bother removing it :roll:

Re: Loading a PE file (.exe)q

Posted: Fri Jan 23, 2009 12:26 am
by iammisc
I wrote a simple userspace pe loader that loads a pe file on windows and linux and runs it. See it at http://xpapi.svn.sourceforge.net/viewvc ... iew=markup and http://xpapi.svn.sourceforge.net/viewvc ... iew=markup


Hope that helps