Sign in to follow this  
Effection

[C / ++] Elf library question

Recommended Posts

Well i'm creating my own library to load ELFs (executable linking format) into memory and have the ability to analyse them. The basic problem is, an elf can be absolutely huge ending up being from 0x0 to 0x02000000 in memory (on a PS2). Now how on earth do i analyse this on the computer. Obviously the program section of the code doesnt take up this much memory but it has the ability to access all this user memory, and to be able to analyse this the instructions must be able to read/write to/from all addresses. My code to retrieve a programme header:
elf_pheader_t *getElfProgHeader(char *file, elf_header_t *elfheader, int offset)
{
	elf_pheader_t *elfpheader;
	FILE *elf;
	int size;
	u8 * buff;
	if(!(elf = fopen(file, "rb"))){
		printf("getElfProgHeader Error could not open file %s\n\n",file);
		return elfpheader;
	}
	//read file contents
	fseek(elf, 0, SEEK_END);
	size = ftell(elf);
	fseek(elf, 0, SEEK_SET);
	buff = (u8 *) malloc(size);
	fread(buff, 1, size, elf);
	printf("%0x\n",(buff[elfheader->phoff]));
	elfpheader = (elf_pheader_t *)(&buff[elfheader->phoff + offset]);//(buff + elfheader->phoff + (num*elfheader->phsize));
	fclose(elf);


	return elfpheader;
}
That works perfectly as far as ive been able to test it so far, the problem comes when retrieving the information from these sections.
bool loadProgrammeSection(char *file, elf_pheader_t * pheader){
	u32 virtual_address = pheader->vaddr;
	u32 physical_address = pheader->paddr;
	u32 fileoffset = pheader->offset;
	u32 size = pheader->filesize;
	u32 sizeinmemory = pheader->memsize;//not needed?
	u32 flags = pheader->flags;//not needed read write execute
	u32 aligned = pheader->align;//not needed?

	//read off the section
	FILE *elf;
	u32 * buff;
	if(!(elf = fopen(file, "rb"))){
		printf("loadProgrammeSection(): Error could not open file %s\n\n",file);
		return false;
	}
	//read file contents
	fseek(elf, fileoffset, SEEK_SET);
	buff = (u32 *) malloc(size);
	fread(buff, 1, size, elf);
	fclose(elf);
	u32 j = physical_address;
	for(u32 i = 0x0; i < size; i+=4){
		
		memcpy(&ELF[j],&buff[i],sizeof(u32));//ELF[j] = buff[i];
		//printf("%8.8x\n",i);
		j+=4;
	}
	return true;

}
basically the information is being stored in a global called ELF and is indexed according to the line in memory that the code is on. But once it gets above 0x10200ish it throws exceptions and its obviously because it cant malloc enough memory for it. Now i need a solution for this and i can't really come up with much... Any ideas?

Share this post


Link to post
Share on other sites
A typical program will read the contents of one or more elf files into memory at program start, and expand the BSS sections, so a typical loaded elf will take up more memory than the sum of all the elf files it opens and loads. That should hint that you might want to be looking elsewhere for the cause of your problems.

I don't see why you need to copy so much data: can't you just (a) use the pheader values directly instead of copying them into local scalars and (b) read directly into the buffer you allocated instead of allocating a temporary buffer and copying into some global.

Did you free() your buffer? Is ELF large enough to hold the contents of the just-read buffer?

Oh, and another thing: C doesn't throw exceptions (although some OSes might throw exceptions from system calls). Instead, various calls return values that must be tested for success. For example, malloc() returns the value zero on failure to allocate. If you're programming in C you need to check and handle every return value from pretty much every call (the bulk of your code will be status and error handling -- one of the motivations for the C++ exeption model). I don't see much of that in the code you posted. Can you guarantee that malloc() succeeded? Can you guarantee that fread() worked?

Share this post


Link to post
Share on other sites
Thank you i've taken your advice but it still doesn't work correctly, ive tried to split it up into several buffers and deal with each one separately then free the previous but free() on the buffers tells me that a breakpoint was set as the heap may of been corrupted. And when i begin reading the separate buffer it returns absolute junk.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this