mirror of
https://github.com/DarkStore-3DS/Project_CTR.git
synced 2026-07-03 00:39:14 +00:00
6c44c7af5e
It has some issues, but I'm going to do anymore work on it.
1004 lines
32 KiB
C
1004 lines
32 KiB
C
#include "lib.h"
|
|
#include "ncch.h"
|
|
#include "elf_hdr.h"
|
|
#include "elf.h"
|
|
#include "blz.h"
|
|
|
|
int ImportPlainRegionFromFile(ncch_settings *ncchset);
|
|
int ImportExeFsCodeBinaryFromFile(ncch_settings *ncchset);
|
|
|
|
u32 GetPageSize(ncch_settings *ncchset);
|
|
u32 SizeToPage(u32 memorySize, ElfContext *elf);
|
|
|
|
int GetBSS_SizeFromElf(ElfContext *elf, u8 *ElfFile, ncch_settings *ncchset);
|
|
int ImportPlainRegionFromElf(ElfContext *elf, u8 *ElfFile, ncch_settings *ncchset);
|
|
int CreateExeFsCode(ElfContext *elf, u8 *ElfFile, ncch_settings *ncchset);
|
|
int CreateCodeSegmentFromElf(CodeSegment *out, ElfContext *elf, u8 *ElfFile, char **Names, u32 NameNum);
|
|
ElfSegment** GetContinuousSegments(u16 *ContinuousSegmentNum, ElfContext *elf, char **Names, u32 NameNum);
|
|
ElfSegment** GetSegments(u16 *SegmentNum, ElfContext *elf, char **Names, u32 NameNum);
|
|
|
|
// ELF Functions
|
|
int GetElfContext(ElfContext *elf, u8 *ElfFile);
|
|
int GetElfSectionEntries(ElfContext *elf, u8 *ElfFile);
|
|
int GetElfProgramEntries(ElfContext *elf, u8 *ElfFile);
|
|
#ifdef DEBUG
|
|
void PrintElfContext(ElfContext *elf, u8 *ElfFile);
|
|
#endif
|
|
int ReadElfHdr(ElfContext *elf, u8 *ElfFile);
|
|
|
|
int CreateElfSegments(ElfContext *elf, u8 *ElfFile);
|
|
bool IsIgnoreSection(ElfSectionEntry info);
|
|
|
|
/* ELF Section Entry Functions */
|
|
u8* GetELFSectionHeader(u16 Index, ElfContext *elf, u8 *ElfFile);
|
|
u8* GetELFSectionEntry(u16 Index, ElfContext *elf, u8 *ElfFile);
|
|
char* GetELFSectionEntryName(u16 Index, ElfContext *elf, u8 *ElfFile);
|
|
u64 GetELFSectionEntryType(u16 Index, ElfContext *elf, u8 *ElfFile);
|
|
u64 GetELFSectionEntryFlags(u16 Index, ElfContext *elf, u8 *ElfFile);
|
|
u64 GetELFSectionEntryAddress(u16 Index, ElfContext *elf, u8 *ElfFile);
|
|
u64 GetELFSectionEntryFileOffset(u16 Index, ElfContext *elf, u8 *ElfFile);
|
|
u64 GetELFSectionEntrySize(u16 Index, ElfContext *elf, u8 *ElfFile);
|
|
u64 GetELFSectionEntryAlignment(u16 Index, ElfContext *elf, u8 *ElfFile);
|
|
|
|
u16 GetElfSectionIndexFromName(char *Name, ElfContext *elf, u8 *ElfFile);
|
|
|
|
bool IsBss(ElfSectionEntry *Section);
|
|
bool IsData(ElfSectionEntry *Section);
|
|
bool IsRO(ElfSectionEntry *Section);
|
|
bool IsText(ElfSectionEntry *Section);
|
|
|
|
/* ELF Program Entry Functions */
|
|
u8* GetELFProgramHeader(u16 Index, ElfContext *elf, u8 *ElfFile);
|
|
u8* GetELFProgramEntry(u16 Index, ElfContext *elf, u8 *ElfFile);
|
|
u64 GetELFProgramEntryType(u16 Index, ElfContext *elf, u8 *ElfFile);
|
|
u64 GetELFProgramEntryFlags(u16 Index, ElfContext *elf, u8 *ElfFile);
|
|
u64 GetELFProgramEntryFileSize(u16 Index, ElfContext *elf, u8 *ElfFile);
|
|
u64 GetELFProgramEntryFileOffset(u16 Index, ElfContext *elf, u8 *ElfFile);
|
|
u64 GetELFProgramEntryMemorySize(u16 Index, ElfContext *elf, u8 *ElfFile);
|
|
u64 GetELFProgramEntryVAddress(u16 Index, ElfContext *elf, u8 *ElfFile);
|
|
u64 GetELFProgramEntryPAddress(u16 Index, ElfContext *elf, u8 *ElfFile);
|
|
u64 GetELFProgramEntryAlignment(u16 Index, ElfContext *elf, u8 *ElfFile);
|
|
|
|
|
|
int BuildExeFsCode(ncch_settings *ncchset)
|
|
{
|
|
int result = 0;
|
|
if(ncchset->options.IsCfa)
|
|
return result;
|
|
if(ncchset->componentFilePtrs.plainregion){ // Import PlainRegion from file
|
|
result = ImportPlainRegionFromFile(ncchset);
|
|
if(result) return result;
|
|
}
|
|
if(!ncchset->options.IsBuildingCodeSection){ // Import ExeFs Code from file and return
|
|
result = ImportExeFsCodeBinaryFromFile(ncchset);
|
|
return result;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
printf("[DEBUG] Import ELF\n");
|
|
#endif
|
|
/* Import ELF */
|
|
u8 *ElfFile = malloc(ncchset->componentFilePtrs.elfSize);
|
|
if(!ElfFile) {
|
|
fprintf(stderr,"[ELF ERROR] Not enough memory\n");
|
|
return MEM_ERROR;
|
|
}
|
|
ReadFile_64(ElfFile,ncchset->componentFilePtrs.elfSize,0,ncchset->componentFilePtrs.elf);
|
|
|
|
#ifdef DEBUG
|
|
printf("[DEBUG] Create ELF Context\n");
|
|
#endif
|
|
/* Create ELF Context */
|
|
ElfContext *elf = calloc(1,sizeof(ElfContext));
|
|
if(!elf) {
|
|
fprintf(stderr,"[ELF ERROR] Not enough memory\n");
|
|
free(ElfFile);
|
|
return MEM_ERROR;
|
|
}
|
|
|
|
result = GetElfContext(elf,ElfFile);
|
|
if(result) goto finish;
|
|
|
|
/* Setting Page Size */
|
|
elf->pageSize = GetPageSize(ncchset);
|
|
|
|
if(!ncchset->componentFilePtrs.plainregion){
|
|
result = ImportPlainRegionFromElf(elf,ElfFile,ncchset);
|
|
if(result) goto finish;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
PrintElfContext(elf,ElfFile);
|
|
#endif
|
|
|
|
#ifdef DEBUG
|
|
printf("[DEBUG] Create ExeFs Code\n");
|
|
#endif
|
|
result = CreateExeFsCode(elf,ElfFile,ncchset);
|
|
if(result) goto finish;
|
|
#ifdef DEBUG
|
|
printf("[DEBUG] Get BSS Size\n");
|
|
#endif
|
|
result = GetBSS_SizeFromElf(elf,ElfFile,ncchset);
|
|
if(result) goto finish;
|
|
|
|
finish:
|
|
if(result){
|
|
if(result == NOT_ELF_FILE) fprintf(stderr,"[ELF ERROR] Not ELF File\n");
|
|
else if(result == NOT_ARM_ELF) fprintf(stderr,"[ELF ERROR] Not ARM ELF\n");
|
|
else if(result == NON_EXECUTABLE_ELF) fprintf(stderr,"[ELF ERROR] Not Executeable ELF\n");
|
|
else if(result == NOT_FIND_BSS_SIZE) fprintf(stderr,"[ELF ERROR] BSS Size Could not be found\n");
|
|
else if(result == NOT_FIND_CODE_SECTIONS) fprintf(stderr,"[ELF ERROR] Failed to retrieve code sections from ELF\n");
|
|
else fprintf(stderr,"[ELF ERROR] Failed to process ELF file (%d)\n",result);
|
|
}
|
|
#ifdef DEBUG
|
|
printf("[DEBUG] Free Segment Header/Sections\n");
|
|
#endif
|
|
for(int i = 0; i < elf->activeSegments; i++){
|
|
#ifdef DEBUG
|
|
printf("[DEBUG] %d\n",i);
|
|
#endif
|
|
free(elf->segments[i].sections);
|
|
}
|
|
#ifdef DEBUG
|
|
printf("[DEBUG] Free others\n");
|
|
#endif
|
|
free(ElfFile);
|
|
free(elf->sections);
|
|
free(elf->programHeaders);
|
|
free(elf->segments);
|
|
free(elf);
|
|
return result;
|
|
}
|
|
|
|
int ImportPlainRegionFromFile(ncch_settings *ncchset)
|
|
{
|
|
ncchset->sections.plainRegion.size = align(ncchset->componentFilePtrs.plainregionSize,ncchset->options.mediaSize);
|
|
ncchset->sections.plainRegion.buffer = malloc(ncchset->sections.plainRegion.size);
|
|
if(!ncchset->sections.plainRegion.buffer) {fprintf(stderr,"[ELF ERROR] Not enough memory\n"); return MEM_ERROR;}
|
|
ReadFile_64(ncchset->sections.plainRegion.buffer,ncchset->componentFilePtrs.plainregionSize,0,ncchset->componentFilePtrs.plainregion);
|
|
return 0;
|
|
}
|
|
|
|
int ImportExeFsCodeBinaryFromFile(ncch_settings *ncchset)
|
|
{
|
|
u32 size = ncchset->componentFilePtrs.codeSize;
|
|
u8 *buffer = malloc(size);
|
|
if(!buffer) {fprintf(stderr,"[ELF ERROR] Not enough memory\n"); return MEM_ERROR;}
|
|
ReadFile_64(buffer,size,0,ncchset->componentFilePtrs.code);
|
|
|
|
ncchset->exefsSections.code.size = ncchset->componentFilePtrs.codeSize;
|
|
ncchset->exefsSections.code.buffer = malloc(ncchset->exefsSections.code.size);
|
|
if(!ncchset->exefsSections.code.buffer) {fprintf(stderr,"[ELF ERROR] Not enough memory\n"); return MEM_ERROR;}
|
|
ReadFile_64(ncchset->exefsSections.code.buffer,ncchset->exefsSections.code.size,0,ncchset->componentFilePtrs.code);
|
|
if(ncchset->options.CompressCode){
|
|
u32 new_len;
|
|
ncchset->exefsSections.code.buffer = BLZ_Code(buffer,size,&new_len,BLZ_NORMAL);
|
|
ncchset->exefsSections.code.size = new_len;
|
|
free(buffer);
|
|
}
|
|
else{
|
|
ncchset->exefsSections.code.size = size;
|
|
ncchset->exefsSections.code.buffer = buffer;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
u32 GetPageSize(ncch_settings *ncchset)
|
|
{
|
|
if(ncchset->rsfSet->Option.PageSize)
|
|
return strtoul(ncchset->rsfSet->Option.PageSize,NULL,10);
|
|
return 0x1000;
|
|
}
|
|
|
|
u32 SizeToPage(u32 memorySize, ElfContext *elf)
|
|
{
|
|
return align(memorySize,elf->pageSize)/elf->pageSize;
|
|
}
|
|
|
|
|
|
int GetBSS_SizeFromElf(ElfContext *elf, u8 *ElfFile, ncch_settings *ncchset)
|
|
{
|
|
for(int i = 0; i < elf->sectionTableEntryCount; i++){
|
|
if(IsBss(&elf->sections[i])) {
|
|
ncchset->codeDetails.bssSize = elf->sections[i].size;
|
|
return 0;
|
|
}
|
|
}
|
|
return NOT_FIND_BSS_SIZE;
|
|
}
|
|
|
|
int ImportPlainRegionFromElf(ElfContext *elf, u8 *ElfFile, ncch_settings *ncchset) // Doesn't work same as N makerom
|
|
{
|
|
if(!ncchset->rsfSet->PlainRegionNum) return 0;
|
|
u16 *Index = calloc(ncchset->rsfSet->PlainRegionNum,sizeof(u16));
|
|
|
|
/* Getting Index Values for each section */
|
|
for(int i = 0; i < ncchset->rsfSet->PlainRegionNum; i++){
|
|
Index[i] = GetElfSectionIndexFromName(ncchset->rsfSet->PlainRegion[i],elf,ElfFile);
|
|
}
|
|
|
|
// Eliminating Duplicated Sections
|
|
for(int i = ncchset->rsfSet->PlainRegionNum - 1; i >= 0; i--){
|
|
for(int j = i-1; j >= 0; j--){
|
|
if(Index[i] == Index[j]) Index[i] = 0;
|
|
}
|
|
}
|
|
|
|
/* Calculating Total Size of Data */
|
|
u64 TotalSize = 0;
|
|
for(int i = 0; i < ncchset->rsfSet->PlainRegionNum; i++){
|
|
TotalSize += elf->sections[Index[i]].size;
|
|
}
|
|
|
|
/* Creating Output Buffer */
|
|
ncchset->sections.plainRegion.size = align(TotalSize,ncchset->options.mediaSize);
|
|
ncchset->sections.plainRegion.buffer = malloc(ncchset->sections.plainRegion.size);
|
|
if(!ncchset->sections.plainRegion.buffer) {fprintf(stderr,"[ELF ERROR] Not enough memory\n"); return MEM_ERROR;}
|
|
memset(ncchset->sections.plainRegion.buffer,0,ncchset->sections.plainRegion.size);
|
|
|
|
/* Storing Sections */
|
|
u64 pos = 0;
|
|
for(int i = 0; i < ncchset->rsfSet->PlainRegionNum; i++){
|
|
memcpy((ncchset->sections.plainRegion.buffer+pos),elf->sections[Index[i]].ptr,elf->sections[Index[i]].size);
|
|
pos += elf->sections[Index[i]].size;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int CreateExeFsCode(ElfContext *elf, u8 *ElfFile, ncch_settings *ncchset)
|
|
{
|
|
/* Getting Code Segments */
|
|
CodeSegment Text;
|
|
memset(&Text,0,sizeof(CodeSegment));
|
|
CodeSegment RO;
|
|
memset(&RO,0,sizeof(CodeSegment));
|
|
CodeSegment Data;
|
|
memset(&Data,0,sizeof(CodeSegment));
|
|
|
|
int result = CreateCodeSegmentFromElf(&Text,elf,ElfFile,ncchset->rsfSet->ExeFs.Text,ncchset->rsfSet->ExeFs.TextNum);
|
|
if(result) return result;
|
|
result = CreateCodeSegmentFromElf(&RO,elf,ElfFile,ncchset->rsfSet->ExeFs.ReadOnly,ncchset->rsfSet->ExeFs.ReadOnlyNum);
|
|
if(result) return result;
|
|
result = CreateCodeSegmentFromElf(&Data,elf,ElfFile,ncchset->rsfSet->ExeFs.ReadWrite,ncchset->rsfSet->ExeFs.ReadWriteNum);
|
|
if(result) return result;
|
|
|
|
/* Allocating Buffer for ExeFs Code */
|
|
u32 size = (Text.maxPageNum + RO.maxPageNum + Data.maxPageNum)*elf->pageSize;
|
|
u8 *code = malloc(size);
|
|
|
|
/* Writing Code into Buffer */
|
|
u8 *TextPos = (code + 0);
|
|
u8 *ROPos = (code + Text.maxPageNum*elf->pageSize);
|
|
u8 *DataPos = (code + (Text.maxPageNum + RO.maxPageNum)*elf->pageSize);
|
|
if(Text.size) memcpy(TextPos,Text.data,Text.size);
|
|
if(RO.size) memcpy(ROPos,RO.data,RO.size);
|
|
if(Data.size) memcpy(DataPos,Data.data,Data.size);
|
|
|
|
|
|
/* Compressing If needed */
|
|
if(ncchset->options.CompressCode){
|
|
u32 new_len;
|
|
ncchset->exefsSections.code.buffer = BLZ_Code(code,size,&new_len,BLZ_NORMAL);
|
|
ncchset->exefsSections.code.size = new_len;
|
|
free(code);
|
|
}
|
|
else{
|
|
ncchset->exefsSections.code.size = size;
|
|
ncchset->exefsSections.code.buffer = code;
|
|
}
|
|
|
|
/* Setting CodeSegment Data and freeing original buffers */
|
|
ncchset->codeDetails.textAddress = Text.address;
|
|
ncchset->codeDetails.textMaxPages = Text.maxPageNum;
|
|
ncchset->codeDetails.textSize = Text.size;
|
|
if(Text.size) free(Text.data);
|
|
|
|
ncchset->codeDetails.roAddress = RO.address;
|
|
ncchset->codeDetails.roMaxPages = RO.maxPageNum;
|
|
ncchset->codeDetails.roSize = RO.size;
|
|
if(RO.size) free(RO.data);
|
|
|
|
ncchset->codeDetails.rwAddress = Data.address;
|
|
ncchset->codeDetails.rwMaxPages = Data.maxPageNum;
|
|
ncchset->codeDetails.rwSize = Data.size;
|
|
if(Data.size) free(Data.data);
|
|
|
|
/* Return */
|
|
return 0;
|
|
}
|
|
|
|
int CreateCodeSegmentFromElf(CodeSegment *out, ElfContext *elf, u8 *ElfFile, char **Names, u32 NameNum)
|
|
{
|
|
u16 ContinuousSegmentNum = 0;
|
|
memset(out,0,sizeof(CodeSegment));
|
|
ElfSegment **ContinuousSegments = GetContinuousSegments(&ContinuousSegmentNum,elf,Names,NameNum);
|
|
if (ContinuousSegments == NULL){
|
|
if(!ContinuousSegmentNum){// Nothing Was Found
|
|
//printf("Nothing was found\n");
|
|
return 0;
|
|
}
|
|
else // Error with found segments
|
|
return ELF_SEGMENTS_NOT_CONTINUOUS;
|
|
}
|
|
|
|
/* Getting Segment Size/Settings */
|
|
u32 vAddr = 0;
|
|
u32 memorySize = 0;
|
|
for(int i = 0; i < ContinuousSegmentNum; i++){
|
|
if (i==0){
|
|
vAddr = ContinuousSegments[i]->vAddr;
|
|
}
|
|
else{ // Add rounded size from previous segment
|
|
u32 padding = ContinuousSegments[i]->vAddr - (vAddr + memorySize);
|
|
memorySize += padding;
|
|
}
|
|
|
|
memorySize += ContinuousSegments[i]->header->sizeInMemory;
|
|
|
|
if(IsBss(&ContinuousSegments[i]->sections[ContinuousSegments[i]->sectionNum-1]))
|
|
memorySize -= ContinuousSegments[i]->sections[ContinuousSegments[i]->sectionNum-1].size;
|
|
}
|
|
|
|
// For Check
|
|
#ifdef DEBUG
|
|
printf("Address: 0x%x\n",vAddr);
|
|
printf("Size: 0x%x\n",memorySize);
|
|
#endif
|
|
|
|
out->address = vAddr;
|
|
out->size = memorySize;
|
|
out->maxPageNum = SizeToPage(memorySize,elf);
|
|
out->data = malloc(memorySize);
|
|
|
|
/* Writing Segment to Buffer */
|
|
//vAddr = 0;
|
|
//memorySize = 0;
|
|
for(int i = 0; i < ContinuousSegmentNum; i++){
|
|
/*
|
|
if (i==0)
|
|
vAddr = ContinuousSegments[i]->vAddr;
|
|
|
|
else{
|
|
u32 num = ContinuousSegments[i]->vAddr - (vAddr + memorySize);
|
|
memorySize += num;
|
|
}
|
|
*/
|
|
//u32 size = 0;
|
|
for (int j = 0; j < ContinuousSegments[i]->sectionNum; j++){
|
|
ElfSectionEntry *Section = &ContinuousSegments[i]->sections[j];
|
|
if (!IsBss(Section)){
|
|
u8 *pos = (out->data + (Section->address - ContinuousSegments[i]->vAddr));
|
|
memcpy(pos,Section->ptr,Section->size);
|
|
//size += Section->size;
|
|
}
|
|
|
|
//else if (j == (ContinuousSegments[i]->sectionNum-1))
|
|
//memorySize -= Section->size;
|
|
//'else
|
|
//size += Section->size;
|
|
}
|
|
}
|
|
|
|
free(ContinuousSegments);
|
|
return 0;
|
|
}
|
|
|
|
|
|
ElfSegment** GetContinuousSegments(u16 *ContinuousSegmentNum, ElfContext *elf, char **Names, u32 NameNum)
|
|
{
|
|
u16 SegmentNum = 0;
|
|
ElfSegment **Segments = GetSegments(&SegmentNum, elf, Names, NameNum);
|
|
if (Segments == NULL || SegmentNum == 0){ // No Segments for the names were found
|
|
//printf("Not Found Segment\n");
|
|
return NULL;
|
|
}
|
|
|
|
if (SegmentNum == 1){ //Return as there is no need to check
|
|
*ContinuousSegmentNum = SegmentNum;
|
|
return Segments;
|
|
}
|
|
|
|
u32 vAddr = Segments[0]->vAddr + Segments[0]->header->sizeInMemory;
|
|
for (int i = 1; i < SegmentNum; i++){
|
|
if (Segments[i]->vAddr != (u32)align(vAddr,Segments[i]->header->alignment)){ //Each Segment must start after each other
|
|
fprintf(stderr,"[ELF ERROR] %s segment and %s segment are not continuous\n", Segments[i]->name, Segments[i - 1]->name);
|
|
free(Segments);
|
|
*ContinuousSegmentNum = 0xffff; // Signify to function that an error occured
|
|
return NULL;
|
|
}
|
|
}
|
|
*ContinuousSegmentNum = SegmentNum;
|
|
return Segments;
|
|
}
|
|
|
|
|
|
ElfSegment** GetSegments(u16 *SegmentNum, ElfContext *elf, char **Names, u32 NameNum)
|
|
{
|
|
if (Names == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
ElfSegment **Segments = calloc(NameNum,sizeof(ElfSegment*));
|
|
*SegmentNum = 0; // There can be a max of NameNum Segments, however, they might not all exist
|
|
for (int i = 0; i < NameNum; i++){
|
|
for(int j = 0; j < elf->activeSegments; j++){
|
|
if(strcmp(Names[i],elf->segments[j].name) == 0){ // If there is a match, store Segment data pointer & increment index
|
|
Segments[*SegmentNum] = &elf->segments[j];
|
|
*SegmentNum = *SegmentNum + 1;
|
|
}
|
|
}
|
|
}
|
|
return Segments;
|
|
}
|
|
|
|
// ELF Functions
|
|
|
|
int GetElfContext(ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(u8_to_u32(ElfFile,BE) != ELF_MAGIC) return NOT_ELF_FILE;
|
|
|
|
elf->Is64bit = (ElfFile[4] == elf_64_bit);
|
|
elf->IsLittleEndian = (ElfFile[5] == elf_little_endian);
|
|
|
|
int result = ReadElfHdr(elf,ElfFile);
|
|
if(result) return result;
|
|
|
|
result = GetElfSectionEntries(elf,ElfFile);
|
|
if(result) return result;
|
|
|
|
result = GetElfProgramEntries(elf,ElfFile);
|
|
if(result) return result;
|
|
|
|
result = CreateElfSegments(elf,ElfFile);
|
|
if(result) return result;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int GetElfSectionEntries(ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
elf->sections = calloc(elf->sectionTableEntryCount,sizeof(ElfSectionEntry));
|
|
if(!elf->sections) {
|
|
fprintf(stderr,"[ELF ERROR] Not enough memory\n");
|
|
return MEM_ERROR;
|
|
}
|
|
|
|
for(int i = 0; i < elf->sectionTableEntryCount; i++){
|
|
elf->sections[i].name = GetELFSectionEntryName(i,elf,ElfFile);
|
|
elf->sections[i].type = GetELFSectionEntryType(i,elf,ElfFile);
|
|
elf->sections[i].flags = GetELFSectionEntryFlags(i,elf,ElfFile);
|
|
elf->sections[i].ptr = GetELFSectionEntry(i,elf,ElfFile);
|
|
elf->sections[i].offsetInFile = GetELFSectionEntryFileOffset(i,elf,ElfFile);
|
|
elf->sections[i].size = GetELFSectionEntrySize(i,elf,ElfFile);
|
|
elf->sections[i].address = GetELFSectionEntryAddress(i,elf,ElfFile);
|
|
elf->sections[i].alignment = GetELFSectionEntryAlignment(i,elf,ElfFile);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int GetElfProgramEntries(ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
elf->programHeaders = calloc(elf->programTableEntryCount,sizeof(ElfProgramEntry));
|
|
if(!elf->programHeaders) {
|
|
fprintf(stderr,"[ELF ERROR] Not enough memory\n");
|
|
return MEM_ERROR;
|
|
}
|
|
|
|
for(int i = 0; i < elf->programTableEntryCount; i++){
|
|
elf->programHeaders[i].type = GetELFProgramEntryType(i,elf,ElfFile);
|
|
elf->programHeaders[i].flags = GetELFProgramEntryFlags(i,elf,ElfFile);
|
|
elf->programHeaders[i].ptr = GetELFProgramEntry(i,elf,ElfFile);
|
|
elf->programHeaders[i].offsetInFile = GetELFProgramEntryFileOffset(i,elf,ElfFile);
|
|
elf->programHeaders[i].sizeInFile = GetELFProgramEntryFileSize(i,elf,ElfFile);
|
|
elf->programHeaders[i].physicalAddress = GetELFProgramEntryPAddress(i,elf,ElfFile);
|
|
elf->programHeaders[i].virtualAddress = GetELFProgramEntryVAddress(i,elf,ElfFile);
|
|
elf->programHeaders[i].sizeInMemory = GetELFProgramEntryMemorySize(i,elf,ElfFile);
|
|
elf->programHeaders[i].alignment = GetELFProgramEntryAlignment(i,elf,ElfFile);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
void PrintElfContext(ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
printf("[+] Basic Details\n");
|
|
printf(" Class: %s\n",elf->Is64bit ? "64-bit" : "32-bit");
|
|
printf(" Data: %s\n",elf->IsLittleEndian ? "Little Endian" : "Big Endian");
|
|
printf("\n[+] Program Table Data\n");
|
|
printf(" Offset: 0x%lx\n",elf->programTableOffset);
|
|
printf(" Size: 0x%x\n",elf->programTableEntrySize);
|
|
printf(" Count: 0x%x\n",elf->programTableEntryCount);
|
|
printf("\n[+] Section Table Data\n");
|
|
printf(" Offset: 0x%lx\n",elf->sectionTableOffset);
|
|
printf(" Size: 0x%x\n",elf->sectionTableEntrySize);
|
|
printf(" Count: 0x%x\n",elf->sectionTableEntryCount);
|
|
printf(" Lable Index: 0x%x\n",elf->sectionHeaderNameEntryIndex);
|
|
for(int i = 0; i < elf->activeSegments; i++){
|
|
printf(" Segment [%d][%s]\n",i,elf->segments[i].name);
|
|
printf(" > Size : 0x%x\n",elf->segments[i].header->sizeInFile);
|
|
printf(" > Address : 0x%x\n",elf->segments[i].vAddr);
|
|
printf(" > Sections : %d\n",elf->segments[i].sectionNum);
|
|
for(int j = 0; j < elf->segments[i].sectionNum; j++){
|
|
printf(" > Section [%d][%s]\n",j,elf->segments[i].sections[j].name);
|
|
}
|
|
|
|
/*
|
|
char outpath[100];
|
|
memset(&outpath,0,100);
|
|
sprintf(outpath,"%s.bin",elf->sections[i].name);
|
|
chdir("elfsections");
|
|
FILE *tmp = fopen(outpath,"wb");
|
|
WriteBuffer(elf->sections[i].ptr,elf->sections[i].size,0,tmp);
|
|
fclose(tmp);
|
|
chdir("..");
|
|
*/
|
|
}
|
|
|
|
}
|
|
#endif
|
|
|
|
int ReadElfHdr(ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(elf->Is64bit){
|
|
elf_64_hdr *hdr = (elf_64_hdr*)ElfFile;
|
|
|
|
u16 Architecture = u8_to_u16(hdr->targetArchitecture,elf->IsLittleEndian);
|
|
u16 Type = u8_to_u16(hdr->type,elf->IsLittleEndian);
|
|
if(Architecture != elf_arm) return NOT_ARM_ELF;
|
|
if(Type != elf_executeable) return NON_EXECUTABLE_ELF;
|
|
|
|
elf->programTableOffset = u8_to_u64(hdr->programHeaderTableOffset,elf->IsLittleEndian);
|
|
elf->programTableEntrySize = u8_to_u16(hdr->programHeaderEntrySize,elf->IsLittleEndian);
|
|
elf->programTableEntryCount = u8_to_u16(hdr->programHeaderEntryCount,elf->IsLittleEndian);
|
|
|
|
elf->sectionTableOffset = u8_to_u64(hdr->sectionHeaderTableOffset,elf->IsLittleEndian);
|
|
elf->sectionTableEntrySize = u8_to_u16(hdr->sectionTableEntrySize,elf->IsLittleEndian);
|
|
elf->sectionTableEntryCount = u8_to_u16(hdr->sectionHeaderEntryCount,elf->IsLittleEndian);
|
|
|
|
elf->sectionHeaderNameEntryIndex = u8_to_u16(hdr->sectionHeaderNameEntryIndex,elf->IsLittleEndian);
|
|
}
|
|
else{
|
|
elf_32_hdr *hdr = (elf_32_hdr*)ElfFile;
|
|
|
|
u16 Architecture = u8_to_u16(hdr->targetArchitecture,elf->IsLittleEndian);
|
|
u16 Type = u8_to_u16(hdr->type,elf->IsLittleEndian);
|
|
if(Architecture != elf_arm) return NOT_ARM_ELF;
|
|
if(Type != elf_executeable) return NON_EXECUTABLE_ELF;
|
|
|
|
elf->programTableOffset = u8_to_u32(hdr->programHeaderTableOffset,elf->IsLittleEndian);
|
|
elf->programTableEntrySize = u8_to_u16(hdr->programHeaderEntrySize,elf->IsLittleEndian);
|
|
elf->programTableEntryCount = u8_to_u16(hdr->programHeaderEntryCount,elf->IsLittleEndian);
|
|
|
|
elf->sectionTableOffset = u8_to_u32(hdr->sectionHeaderTableOffset,elf->IsLittleEndian);
|
|
elf->sectionTableEntrySize = u8_to_u16(hdr->sectionTableEntrySize,elf->IsLittleEndian);
|
|
elf->sectionTableEntryCount = u8_to_u16(hdr->sectionHeaderEntryCount,elf->IsLittleEndian);
|
|
|
|
elf->sectionHeaderNameEntryIndex = u8_to_u16(hdr->sectionHeaderNameEntryIndex,elf->IsLittleEndian);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* Section Hdr Functions */
|
|
|
|
u8* GetELFSectionHeader(u16 Index, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(Index >= elf->sectionTableEntryCount) return NULL;
|
|
|
|
return (ElfFile + elf->sectionTableOffset + elf->sectionTableEntrySize*Index);
|
|
}
|
|
|
|
u8* GetELFSectionEntry(u16 Index, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(Index >= elf->sectionTableEntryCount) return NULL;
|
|
|
|
return (u8*) (ElfFile + GetELFSectionEntryFileOffset(Index,elf,ElfFile));
|
|
}
|
|
|
|
char* GetELFSectionEntryName(u16 Index, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(Index >= elf->sectionTableEntryCount) return 0;
|
|
|
|
u64 NameIndex = 0;
|
|
if(elf->Is64bit){
|
|
elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
|
|
NameIndex = u8_to_u64(shdr->sh_name,elf->IsLittleEndian);
|
|
}
|
|
else{
|
|
elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
|
|
NameIndex = u8_to_u32(shdr->sh_name,elf->IsLittleEndian);
|
|
}
|
|
|
|
u8 *NameTable = GetELFSectionEntry(elf->sectionHeaderNameEntryIndex,elf,ElfFile);
|
|
|
|
return (char*)(NameTable+NameIndex);
|
|
}
|
|
|
|
u64 GetELFSectionEntryType(u16 Index, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(Index >= elf->sectionTableEntryCount) return 0;
|
|
|
|
if(elf->Is64bit){
|
|
elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
|
|
return u8_to_u64(shdr->sh_type,elf->IsLittleEndian);
|
|
}
|
|
else{
|
|
elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
|
|
return u8_to_u32(shdr->sh_type,elf->IsLittleEndian);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
u64 GetELFSectionEntryFlags(u16 Index, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(Index >= elf->sectionTableEntryCount) return 0;
|
|
|
|
if(elf->Is64bit){
|
|
elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
|
|
return u8_to_u64(shdr->sh_flags,elf->IsLittleEndian);
|
|
}
|
|
else{
|
|
elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
|
|
return u8_to_u32(shdr->sh_flags,elf->IsLittleEndian);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
u64 GetELFSectionEntryAddress(u16 Index, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(Index >= elf->sectionTableEntryCount) return 0;
|
|
|
|
if(elf->Is64bit){
|
|
elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
|
|
return u8_to_u64(shdr->sh_addr,elf->IsLittleEndian);
|
|
}
|
|
else{
|
|
elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
|
|
return u8_to_u32(shdr->sh_addr,elf->IsLittleEndian);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
u64 GetELFSectionEntryFileOffset(u16 Index, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(Index >= elf->sectionTableEntryCount) return 0;
|
|
|
|
if(elf->Is64bit){
|
|
elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
|
|
return u8_to_u64(shdr->sh_offset,elf->IsLittleEndian);
|
|
}
|
|
else{
|
|
elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
|
|
return u8_to_u32(shdr->sh_offset,elf->IsLittleEndian);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
u64 GetELFSectionEntrySize(u16 Index, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(Index >= elf->sectionTableEntryCount) return 0;
|
|
|
|
if(elf->Is64bit){
|
|
elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
|
|
return u8_to_u64(shdr->sh_size,elf->IsLittleEndian);
|
|
}
|
|
else{
|
|
elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
|
|
return u8_to_u32(shdr->sh_size,elf->IsLittleEndian);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
u64 GetELFSectionEntryAlignment(u16 Index, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(Index >= elf->sectionTableEntryCount) return 0;
|
|
|
|
if(elf->Is64bit){
|
|
elf_64_shdr *shdr = (elf_64_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
|
|
return u8_to_u64(shdr->sh_addralign,elf->IsLittleEndian);
|
|
}
|
|
else{
|
|
elf_32_shdr *shdr = (elf_32_shdr*)GetELFSectionHeader(Index,elf,ElfFile);
|
|
return u8_to_u32(shdr->sh_addralign,elf->IsLittleEndian);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
u16 GetElfSectionIndexFromName(char *Name, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
for(int i = 0; i < elf->sectionTableEntryCount; i++){
|
|
if(strcmp(Name,elf->sections[i].name) == 0) return i;
|
|
}
|
|
return 0; // Assuming 0 is always empty
|
|
}
|
|
|
|
bool IsBss(ElfSectionEntry *Section)
|
|
{
|
|
if(Section->type == 8 && Section->flags == 3)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool IsData(ElfSectionEntry *Section)
|
|
{
|
|
if(Section->type == 1 && Section->flags == 3)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool IsRO(ElfSectionEntry *Section)
|
|
{
|
|
if(Section->type == 1 && Section->flags == 2)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool IsText(ElfSectionEntry *Section)
|
|
{
|
|
if(Section->type == 1 && Section->flags == 6)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
/* ProgramHeader Functions */
|
|
|
|
u8* GetELFProgramHeader(u16 Index, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(Index >= elf->programTableEntryCount) return NULL;
|
|
|
|
return (ElfFile + elf->programTableOffset + elf->programTableEntrySize*Index);
|
|
}
|
|
|
|
u8* GetELFProgramEntry(u16 Index, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(Index >= elf->programTableEntryCount) return NULL;
|
|
|
|
return (u8*) (ElfFile + GetELFProgramEntryFileOffset(Index,elf,ElfFile));
|
|
|
|
return NULL;
|
|
}
|
|
|
|
u64 GetELFProgramEntryType(u16 Index, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(Index >= elf->programTableEntryCount) return 0;
|
|
|
|
if(elf->Is64bit){
|
|
elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
|
|
return u8_to_u64(phdr->p_type,elf->IsLittleEndian);
|
|
}
|
|
else{
|
|
elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
|
|
return u8_to_u32(phdr->p_type,elf->IsLittleEndian);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
u64 GetELFProgramEntryFlags(u16 Index, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(Index >= elf->programTableEntryCount) return 0;
|
|
|
|
if(elf->Is64bit){
|
|
elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
|
|
return u8_to_u64(phdr->p_flags,elf->IsLittleEndian);
|
|
}
|
|
else{
|
|
elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
|
|
return u8_to_u32(phdr->p_flags,elf->IsLittleEndian);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
u64 GetELFProgramEntryFileSize(u16 Index, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(Index >= elf->programTableEntryCount) return 0;
|
|
|
|
if(elf->Is64bit){
|
|
elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
|
|
return u8_to_u64(phdr->p_filesz,elf->IsLittleEndian);
|
|
}
|
|
else{
|
|
elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
|
|
return u8_to_u32(phdr->p_filesz,elf->IsLittleEndian);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
u64 GetELFProgramEntryFileOffset(u16 Index, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(Index >= elf->programTableEntryCount) return 0;
|
|
|
|
if(elf->Is64bit){
|
|
elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
|
|
return u8_to_u64(phdr->p_offset,elf->IsLittleEndian);
|
|
}
|
|
else{
|
|
elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
|
|
return u8_to_u32(phdr->p_offset,elf->IsLittleEndian);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
u64 GetELFProgramEntryMemorySize(u16 Index, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(Index >= elf->programTableEntryCount) return 0;
|
|
|
|
if(elf->Is64bit){
|
|
elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
|
|
return u8_to_u64(phdr->p_memsz,elf->IsLittleEndian);
|
|
}
|
|
else{
|
|
elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
|
|
return u8_to_u32(phdr->p_memsz,elf->IsLittleEndian);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
u64 GetELFProgramEntryVAddress(u16 Index, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(Index >= elf->programTableEntryCount) return 0;
|
|
|
|
if(elf->Is64bit){
|
|
elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
|
|
return u8_to_u64(phdr->p_vaddr,elf->IsLittleEndian);
|
|
}
|
|
else{
|
|
elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
|
|
return u8_to_u32(phdr->p_vaddr,elf->IsLittleEndian);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
u64 GetELFProgramEntryPAddress(u16 Index, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(Index >= elf->programTableEntryCount) return 0;
|
|
|
|
if(elf->Is64bit){
|
|
elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
|
|
return u8_to_u64(phdr->p_paddr,elf->IsLittleEndian);
|
|
}
|
|
else{
|
|
elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
|
|
return u8_to_u32(phdr->p_paddr,elf->IsLittleEndian);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
u64 GetELFProgramEntryAlignment(u16 Index, ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
if(Index >= elf->programTableEntryCount) return 0;
|
|
|
|
if(elf->Is64bit){
|
|
elf_64_phdr *phdr = (elf_64_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
|
|
return u8_to_u64(phdr->p_align,elf->IsLittleEndian);
|
|
}
|
|
else{
|
|
elf_32_phdr *phdr = (elf_32_phdr*)GetELFProgramHeader(Index,elf,ElfFile);
|
|
return u8_to_u32(phdr->p_align,elf->IsLittleEndian);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int CreateElfSegments(ElfContext *elf, u8 *ElfFile)
|
|
{
|
|
int num = 0;
|
|
// Interate through Each Program Header
|
|
elf->activeSegments = 0;
|
|
elf->segments = calloc(elf->programTableEntryCount,sizeof(ElfSegment));
|
|
ElfSegment *segment = malloc(sizeof(ElfSegment)); // Temporary Buffer
|
|
for (int i = 0; i < elf->programTableEntryCount; i++){
|
|
if (elf->programHeaders[i].sizeInMemory != 0 && elf->programHeaders[i].type == 1){
|
|
memset(segment,0,sizeof(ElfSegment));
|
|
|
|
bool foundFirstSection = false;
|
|
u32 size = 0;
|
|
u32 vAddr = elf->programHeaders[i].virtualAddress;
|
|
u32 memorySize = elf->programHeaders[i].sizeInMemory;
|
|
//printf("Segment Size in memory: 0x%x\n",memorySize);
|
|
//printf("Segment Alignment: 0x%x\n",elf->programHeaders[i].alignment);
|
|
|
|
u16 SectionInfoCapacity = 10;
|
|
segment->sectionNum = 0;
|
|
segment->sections = calloc(SectionInfoCapacity,sizeof(ElfSectionEntry));
|
|
|
|
// Itterate Through Section Headers
|
|
for (int j = num; j < elf->sectionTableEntryCount; j++){
|
|
if (!foundFirstSection){
|
|
if (elf->sections[j].address != vAddr)
|
|
continue;
|
|
|
|
while (j < (int)elf->sections[j].size && elf->sections[j].address == vAddr && !IsIgnoreSection(elf->sections[j]))
|
|
j++;
|
|
|
|
j--;
|
|
|
|
foundFirstSection = true;
|
|
segment->vAddr = elf->sections[j].address;
|
|
segment->name = elf->sections[j].name;
|
|
}
|
|
|
|
if(segment->sectionNum < SectionInfoCapacity)
|
|
memcpy(&segment->sections[segment->sectionNum],&elf->sections[j],sizeof(ElfSectionEntry));
|
|
else{
|
|
SectionInfoCapacity = SectionInfoCapacity*2;
|
|
ElfSectionEntry *tmp = calloc(SectionInfoCapacity,sizeof(ElfSectionEntry));
|
|
for(int k = 0; k < segment->sectionNum; k++)
|
|
memcpy(&tmp[k],&segment->sections[k],sizeof(ElfSectionEntry));
|
|
free(segment->sections);
|
|
segment->sections = tmp;
|
|
memcpy(&segment->sections[segment->sectionNum],&elf->sections[j],sizeof(ElfSectionEntry));
|
|
}
|
|
segment->sectionNum++;
|
|
|
|
if(size == 0)
|
|
size += elf->sections[j].size;
|
|
else{
|
|
u32 padding = elf->sections[j].address - (elf->sections[j-1].address + elf->sections[j-1].size);
|
|
size += padding + elf->sections[j].size;
|
|
}
|
|
|
|
//printf("Section Name: %s",elf->sections[j].name);
|
|
//printf(" 0x%lx",elf->sections[j].size);
|
|
//printf(" (Total Size: 0x%x)\n",size);
|
|
|
|
if (size == memorySize)
|
|
break;
|
|
|
|
if (size > memorySize){
|
|
fprintf(stderr,"[ELF ERROR] Too large section size.\n Segment size = 0x%x\n Section Size = 0x%x\n", memorySize, size);
|
|
return ELF_SEGMENT_SECTION_SIZE_MISMATCH;
|
|
}
|
|
}
|
|
if(segment->sectionNum){
|
|
segment->header = &elf->programHeaders[i];
|
|
memcpy(&elf->segments[elf->activeSegments],segment,sizeof(ElfSegment));
|
|
elf->activeSegments++;
|
|
}
|
|
else{
|
|
free(segment->sections);
|
|
free(segment);
|
|
fprintf(stderr,"[ELF ERROR] Program Header Has no corresponding Sections, ELF Cannot be proccessed\n");
|
|
return ELF_SEGMENTS_NOT_FOUND;
|
|
}
|
|
}
|
|
}
|
|
|
|
free(segment);
|
|
return 0;
|
|
}
|
|
|
|
bool IsIgnoreSection(ElfSectionEntry info)
|
|
{
|
|
if (info.address)
|
|
return false;
|
|
|
|
if (info.type != 1 && info.type != 0)
|
|
return true;
|
|
|
|
char IgnoreSectionNames[7][20] = { ".debug_abbrev", ".debug_frame", ".debug_info", ".debug_line", ".debug_loc", ".debug_pubnames", ".comment" };
|
|
for (int i = 0; i < 7; i++){
|
|
if (strcmp(IgnoreSectionNames[i],info.name) == 0)
|
|
return true;
|
|
}
|
|
return false;
|
|
|
|
}
|