User:Kmcguire

From OSDev.wiki
Revision as of 23:15, 11 September 2009 by Kmcguire (talk | contribs) (added accessing clr meta-data header)
Jump to navigation Jump to search

Portable Executable 32 File Header And NT Header Structure

typedef struct {
	uint32_t	signature;
	uint16_t	cputype;
	uint16_t	objcnt;
	
	uint32_t	tdstamp;
	uint32_t	reserved1;
	
	uint32_t	reserved2;
	uint16_t	nthdrsize;
	uint16_t	flags;
	
	uint16_t	reserved3;
	uint16_t	lmajor;
	uint16_t	lminor;
	uint16_t	reserved4;
	
	uint32_t	reserved5;
	uint32_t	reserved6;
	
	uint32_t	entrypointrva;
	uint32_t	reserved7;
	
	uint32_t	reserved8;
	uint32_t	imagebase;
	
	uint32_t	objectalign;
	uint32_t	filealign;
	
	uint16_t	osmajor;
	uint16_t	osminor;
	uint16_t	usermajor;
	uint16_t	userminor;
	
	uint16_t	subsysmajor;
	uint16_t	subsysminor;
	uint32_t	reserved9;
	
	uint32_t	imagesize;
	uint32_t	hdrsize;
	
	uint32_t	filechecksum;
	uint16_t	subsystem;
	uint16_t	dllflags;
	
	uint32_t	stackreservesize;
	uint32_t	stackcommitsize;
	
	uint32_t	heapreservesize;
	uint32_t	heapcommitsize;
	
	uint32_t	reserved10;
	uint32_t	_rvasizes;
	
	struct {
		uint32_t	rva;
		uint32_t	size;
	} tables[];
	
} win32_pe32_fhdr;

#define WIN32_PE32_TABLE_EXPORT		0x00
#define WIN32_PE32_TABLE_IMPORT		0x01
#define WIN32_PE32_TABLE_RESOURCE	0x02
#define WIN32_PE32_TABLE_EXCEPTION	0x03
#define WIN32_PE32_TABLE_SECURITY	0x04
#define WIN32_PE32_TABLE_FIXUP		0x05
#define WIN32_PE32_TABLE_DEBUG		0x06
#define WIN32_PE32_TABLE_IMAGEDESC	0x07
#define WIN32_PE32_TABLE_MACHSPEC	0x08
#define WIN32_PE32_TABLE_THREADLOC	0x09
#define WIN32_PE32_TABLE_UNKNOWN1	0x0A
#define WIN32_PE32_TABLE_UNKNOWN2	0x0B
#define WIN32_PE32_TABLE_IMPORTADDR	0x0C
#define WIN32_PE32_TABLE_UNKNOWN3	0x0D
#define WIN32_PE32_TABLE_CLRRTHDR	0x0E

Common Language Runtime Header

typedef struct {
	uint32_t	rva;
	uint32_t	size;
} win32_clr20_datadir;

/* http://ntcore.com/files/dotnetformat.htm */
typedef struct {
	uint32_t			cb;
	uint16_t			rtmajor;
	uint16_t			rtminor;
	win32_clr20_datadir		meta;
	uint32_t			flags;
	uint32_t			entrypointrva;	/* entry point rva */
	win32_clr20_datadir		resources;	/* resources */
	win32_clr20_datadir		strongnamsig;	/* strong name signature */
	win32_clr20_datadir		codemantab;	/* code manager table */
	win32_clr20_datadir		vtabfixups;	/* vtable fixups */
	win32_clr20_datadir		exaddrtabjumps;	/* export address table jumps */
} win32_clr20_hdr;

Accessing PE32 Headers

	win32_pe32_fhdr		*fhdr;
	win32_pe32_ohdr		*ohdr;	
	uint32_t		pe_off;

	/* get pe32 header offset */
	pe_off = ((uint32_t*)(buffer + 0x3c))[0];
	printf("peoff:%x\n", pe_off);
	
	if(memcmp(buffer + pe_off, "PE\0\0", 4) == 0)
	{
		printf("Yes, this is a PE header.\n");
	}else{
                printf("No, this is not a PE header.\n");
        }
	
	fhdr = (win32_pe32_fhdr*)(buffer + pe_off);
	printf("imagebase: %x\n", fhdr->imagebase);

Accessing CLR Header

	printf("CLRRTHDR_RVA:%x\nCLRRTHDR_SIZE:%x\n", 
			fhdr->tables[WIN32_PE32_TABLE_CLRRTHDR].rva, 
			fhdr->tables[WIN32_PE32_TABLE_CLRRTHDR].size);
	clr_rva = fhdr->tables[WIN32_PE32_TABLE_CLRRTHDR].rva;
	clr_size = fhdr->tables[WIN32_PE32_TABLE_CLRRTHDR].size;
	
	/* 
		The array of objects follow the headers. But, my header does
		not include the size for the data dictionary array. So to
		include that we get the number of entries in the data dictionary
		and multiple this by eight since each one is eight bytes in PE32.
	*/
	ohdr = (win32_pe32_ohdr*)(buffer + pe_off + sizeof(win32_pe32_fhdr) + (fhdr->_rvasizes * 8));

	/* find the object that the CLRRTHDR is in and point header there */
	for(x = 0; x < fhdr->objcnt; ++x)
	{
		printf("object rva %x %s\n", ohdr[x].rva, &ohdr[x].name[0]);
		if(clr_rva >= ohdr[x].rva)
		{
			/* calculating relative to file offset not memory */
			clr_off = ohdr[x].poff + (clr_rva - ohdr[x].rva);
			printf("found object for CLRRTHDR, with rva %x\n", ohdr[x].rva);
			break;
		}
	}
	clr_hdr = (uint8_t*)(buffer + clr_off);

Accessing CLR Meta-Data Header

	printf("clr-metatable:%x [size:%x]\n", clr_hdr->meta.rva, clr_hdr->meta.size);
	meta_rva = clr_hdr->meta.rva;
	meta_size = clr_hdr->meta.size;
	
	/* find the object that the metadata is in and point header there */
	for(x = 0; x < fhdr->objcnt; ++x)
	{
		printf("object rva %x %s\n", ohdr[x].rva, &ohdr[x].name[0]);
		if(meta_rva >= ohdr[x].rva)
		{
			/* calculating relative to file offset not memory */
			meta_off = ohdr[x].poff + (meta_rva - ohdr[x].rva);
			printf("found object for CLR-METADATA, with rva %x\n", ohdr[x].rva);
			break;
		}
	}
	/* offset is relative to our buffer so that (buffer + meta_off) is start and meta_size is size */