ELF 解析所以重定位节 包含REL RELA

ELF 解析所以重定位节 包含REL RELA,并未支持所有平台,仅实现了i386和arm平台 32位支持

/*
 * ParseRelocation.c
 *
 *  Created on: 2014年7月20日
 *      Author: angel-toms
 */

#include "ElfParser.h"

static void get_rel_dyn_type(u2 machineType,u4 rInfo,u1* type);

void print_elf_section_of_reldyn(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader){
	Elf32_Rel* pRel						= NULL;
	Elf32_Sym* pSymMem  			    = NULL;
	u1* shStringTableMem				= NULL;
	u4 i 								= 0;
	u4 size								= 0;
	u1 buf[55];
	LookupSection* pLookupSection 		= NULL;
	LookupSection* pLookupStrSection 	= NULL;
	Elf32_Shdr* pReldyn					= NULL;
	shStringTableMem = get_elf_section_of_shstr_table(mem,pHeader,pSheader);
	if(NULL == shStringTableMem){
		printf("Error,get elf section header string table failed !\n");
		goto Exit;
	}

	for( ; i < pHeader->e_shnum ; i++){
		if(pSheader[i].sh_type == SHT_REL && strcmp((const char*)(shStringTableMem + pSheader[i].sh_name),".rel.dyn") == 0){
			size = (pSheader[i].sh_size / pSheader[i].sh_entsize);
			pRel = (Elf32_Rel*)(mem->base + pSheader[i].sh_offset);
			pReldyn = (Elf32_Shdr*) &pSheader[i];
			break;
		}
		continue;
	}

	if(NULL != pRel){
		//@1 by default ,rel.dyn link dynsym ,so it sh_link is the index
		pLookupSection = get_section_by_index(mem,pHeader,pSheader,pReldyn->sh_link);
		if(NULL == pLookupSection){
			printf("Error,get section by index failed\n");
			goto Exit;
		}
		pSymMem = (Elf32_Sym*)pLookupSection->base;
		pLookupStrSection = get_section_by_index(mem,pHeader,pSheader,pLookupSection->link);
		if(NULL == pLookupStrSection){
			printf("Error,get sym tab link failed\n");
			goto Exit;
		}
		i = 0;
		printf("Relocation section '.rel.dyn' at offset 0x%.8x contains %d entries:\n",pReldyn->sh_addr,size);
		printf("Offset     Info     Type           Sym.Value  Sym. Name\n");
		for( ; i < size ; i++ ){
			printf("0x%.8x ",pRel[i].r_offset);
			printf("%.8x ",pRel[i].r_info);
			memset(&buf,0,55);
			get_rel_dyn_type((u2)pHeader->e_machine,(u4)ELF32_R_TYPE(pRel[i].r_info),(u1*)buf);
			printf("%-15s",buf);
			if(pSymMem[ELF32_R_SYM(pRel[i].r_info)].st_name != 0){
				printf("%.8x   ",pSymMem[ELF32_R_SYM(pRel[i].r_info)].st_value);
				printf("%s",(pLookupStrSection->base + pSymMem[ELF32_R_SYM(pRel[i].r_info)].st_name));
			}
			printf("\n");
		}
	}

	Exit:
	if(shStringTableMem)
		free(shStringTableMem);
	if(pLookupSection)
		free(pLookupSection);
	if(pLookupStrSection)
		free(pLookupStrSection);
}

//this impl  code almost sample as the top  print_elf_section_of_reldyn,but its' sh_info  point to which section will be relocated
void print_elf_section_of_relplt(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader){
	Elf32_Rel* pRelplt					= NULL;
	Elf32_Sym* pSymMem  			    = NULL;
	u1* shStringTableMem				= NULL;
	u4 i 								= 0;
	u4 size								= 0;
	u1 buf[55];
	LookupSection* pLookupSection 		= NULL;
	LookupSection* pLookupStrSection 	= NULL;
	Elf32_Shdr* pThisSection			= NULL;

	shStringTableMem = get_elf_section_of_shstr_table(mem,pHeader,pSheader);
	if(NULL == shStringTableMem){
		printf("Error,get elf section header string table failed !\n");
		goto Exit;
	}

	for( ; i < pHeader->e_shnum ; i++){
		if(pSheader[i].sh_type == SHT_REL && strcmp((const char*)(shStringTableMem + pSheader[i].sh_name),".rel.plt") == 0){
			size = (pSheader[i].sh_size / pSheader[i].sh_entsize);
			pRelplt =  (Elf32_Rel*)(mem->base + pSheader[i].sh_offset);
			pThisSection = (Elf32_Shdr*)&pSheader[i];
			break;
		}
		continue;
	}

	if(NULL != pRelplt){
		//@1 by default ,rel.dyn link dynsym ,so it sh_link is the index
		pLookupSection = get_section_by_index(mem,pHeader,pSheader,pThisSection->sh_link);
		if(NULL == pLookupSection){
			printf("Error,get section by index failed\n");
			goto Exit;
		}

		pSymMem = (Elf32_Sym*)pLookupSection->base;
		pLookupStrSection = get_section_by_index(mem,pHeader,pSheader,pLookupSection->link);
		if(NULL == pLookupStrSection){
			printf("Error,get sym tab link failed\n");
			goto Exit;
		}
		i = 0;
		printf("Relocation section '.rel.plt' at offset 0x%.8x contains %d entries:\n",pThisSection->sh_addr,size);
		printf("Offset     Info     Type           Sym.Value  Sym. Name\n");
		for( ; i < size ; i++ ){
			printf("0x%.8x ",pRelplt[i].r_offset);
			printf("%.8x ",pRelplt[i].r_info);
			memset(&buf,0,55);
			get_rel_dyn_type((u2)pHeader->e_machine,(u4)ELF32_R_TYPE(pRelplt[i].r_info),(u1*)buf);
			printf("%s ",buf);
			if(pSymMem[ELF32_R_SYM(pRelplt[i].r_info)].st_name != 0){
				printf("%.8x ",pSymMem[ELF32_R_SYM(pRelplt[i].r_info)].st_value);
				printf("%s",(pLookupStrSection->base + pSymMem[ELF32_R_SYM(pRelplt[i].r_info)].st_name));
			}
			printf("\n");
		}
	}

	Exit:
	if(shStringTableMem)
		free(shStringTableMem);
	if(pLookupSection)
		free(pLookupSection);
	if(pLookupStrSection)
		free(pLookupStrSection);
}



void print_elf_section_of_allrela(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader){
	Elf32_Rela* pRelplt					= NULL;
	Elf32_Sym* pRelaMem  			    = NULL;
	u4 i 								= 0;
	u4 size								= 0;
	u1 buf[55];
	LookupSection* pLookupSection 		= NULL;
	LookupSection* pLookupStrSection 	= NULL;
	Elf32_Shdr* pThisSection;
	u1* shStringTableMem				= NULL;

	shStringTableMem = get_elf_section_of_shstr_table(mem,pHeader,pSheader);
	if(NULL == shStringTableMem){
		printf("Error,get elf section header string table failed !\n");
		goto Exit;
	}

	for( ; i < pHeader->e_shnum ; i++){
		if(pSheader[i].sh_type == SHT_RELA){
			size = (pSheader[i].sh_size / pSheader[i].sh_entsize);
			pRelplt = (Elf32_Rela*)(mem->base + pSheader[i].sh_offset);
			pThisSection = (Elf32_Shdr*)(&pSheader[i]);
			if(NULL != pRelplt){
				//@1 by default ,RELA link dynsym ,so it sh_link is the index
				pLookupSection = get_section_by_index(mem,pHeader,pSheader,pThisSection->sh_link);
				if(NULL == pLookupSection){
					printf("Error,get section by index failed\n");
					goto Exit;
				}
				pRelaMem = (Elf32_Sym*)pLookupSection->base;

				pLookupStrSection = get_section_by_index(mem,pHeader,pSheader,pLookupSection->link);
				if(NULL == pLookupStrSection){
					printf("Error,get sym tab link failed\n");
					goto Exit;
				}

				u4 j = 0;
				printf("Relocation section '%s' at offset 0x%.8x contains %d entries:\n",(shStringTableMem + pSheader[i].sh_name),pThisSection->sh_offset,size);
				printf("Offset     Info     Type           Sym.Value  Sym. Name + Addend\n");
				for( ; j < size ; j++ ){
					printf("0x%.8x ",pRelplt[j].r_offset);
					printf("%.8x ",pRelplt[j].r_info);
					memset(&buf,0,55);
					get_rel_dyn_type((u2)pHeader->e_machine,(u4)ELF32_R_TYPE(pRelplt[j].r_info),(u1*)buf);
					printf("%-15s ",buf);
					if(pRelaMem[ELF32_R_SYM(pRelplt[j].r_info)].st_name != 0){
						printf("%.8x   ",pRelaMem[ELF32_R_SYM(pRelplt[j].r_info)].st_value);
						printf("%-10s  ",(pLookupStrSection->base + pRelaMem[ELF32_R_SYM(pRelplt[j].r_info)].st_name));
					}
					else{
						printf("%-22s","");
					}
					printf("%.8x",pRelplt[j].r_addend);
					printf("\n");
				}
				memset(pLookupSection,0,GET_SIZE(LookupSection));
				memset(pLookupSection,0,GET_SIZE(pLookupStrSection));
			}
		}
		continue;
	}

	Exit:
	if(shStringTableMem)
		free(shStringTableMem);
	if(pLookupSection){
		free(pLookupSection);
		pLookupSection = NULL;
	}
	if(pLookupStrSection){
		free(pLookupStrSection);
		pLookupStrSection = NULL;
	}
	return;
}

static void get_rel_dyn_type(u2 machineType,u4 rInfo,u1* type){
	switch(machineType){
	case EM_386:
		switch(rInfo){
		case	R_386_NONE:
			memcpy(type,"R_386_NONE",strlen("R_386_NONE"));
			break;
		case	R_386_32:
			memcpy(type,"R_386_32",strlen("R_386_32"));
			break;
		case	R_386_PC32:
			memcpy(type,"R_386_NONE",strlen("R_386_PC32"));
			break;
		case	R_386_GOT32:
			memcpy(type,"R_386_GOT32",strlen("R_386_GOT32"));
			break;
		case	R_386_PLT32:
			memcpy(type,"R_386_PLT32",strlen("R_386_PLT32"));
			break;
		case	R_386_COPY:
			memcpy(type,"R_386_COPY",strlen("R_386_COPY"));
			break;
		case	R_386_GLOB_DAT:
			memcpy(type,"R_386_GLOB_DAT",strlen("R_386_GLOB_DAT"));
			break;
		case	R_386_JMP_SLOT:
			memcpy(type,"R_386_JMP_SLOT",strlen("R_386_JMP_SLOT"));
			break;
		case	R_386_RELATIVE:
			memcpy(type,"R_386_RELATIVE",strlen("R_386_RELATIVE"));
			break;
		case	R_386_GOTOFF:
			memcpy(type,"R_386_GOTOFF",strlen("R_386_GOTOFF"));
			break;
		case	R_386_GOTPC:
			memcpy(type,"R_386_GLOB_DAT",strlen("R_386_GOTPC"));
			break;
		case	R_386_TLS_TPOFF:
			memcpy(type,"R_386_TLS_TPOFF",strlen("R_386_TLS_TPOFF"));
			break;
		case	R_386_TLS_IE:
			memcpy(type,"R_386_TLS_IE",strlen("R_386_TLS_IE"));
			break;
		case	R_386_TLS_GOTIE:
			memcpy(type,"R_386_TLS_GOTIE",strlen("R_386_TLS_GOTIE"));
			break;
		case	R_386_TLS_LE:
			memcpy(type,"R_386_TLS_LE",strlen("R_386_TLS_LE"));
			break;
		case	R_386_TLS_GD:
			memcpy(type,"R_386_TLS_GD",strlen("R_386_TLS_GD"));
			break;
		case	R_386_TLS_LDM:
			memcpy(type,"R_386_TLS_LDM",strlen("R_386_TLS_LDM"));
			break;
		case	R_386_16:
			memcpy(type,"R_386_16",strlen("R_386_16"));
			break;
		case	R_386_PC16:
			memcpy(type,"R_386_PC16",strlen("R_386_PC16"));
			break;
		case	R_386_8:
			memcpy(type,"R_386_8",strlen("R_386_8"));
			break;
		case	R_386_PC8:
			memcpy(type,"R_386_PC8",strlen("R_386_PC8"));
			break;
		case	R_386_TLS_GD_32:
			memcpy(type,"R_386_TLS_GD_32",strlen("R_386_TLS_GD_32"));
			break;
		case	R_386_TLS_GD_PUSH:
			memcpy(type,"R_386_TLS_GD_PUSH",strlen("R_386_TLS_GD_PUSH"));
			break;
		case	R_386_TLS_GD_CALL:
			memcpy(type,"R_386_TLS_GD_CALL",strlen("R_386_TLS_GD_CALL"));
			break;
		case	R_386_TLS_GD_POP:
			memcpy(type,"R_386_TLS_GD_POP",strlen("R_386_TLS_GD_POP"));
			break;
		case	R_386_TLS_LDM_32:
			memcpy(type,"R_386_TLS_LDM_32",strlen("R_386_TLS_LDM_32"));
			break;
		case	R_386_TLS_LDM_PUSH:
			memcpy(type,"R_386_TLS_LDM_PUSH",strlen("R_386_TLS_LDM_PUSH"));
			break;
		case	R_386_TLS_LDM_CALL:
			memcpy(type,"R_386_TLS_LDM_CALL",strlen("R_386_TLS_LDM_CALL"));
			break;
		case	R_386_TLS_LDM_POP:
			memcpy(type,"R_386_TLS_LDM_POP",strlen("R_386_TLS_LDM_POP"));
			break;
		case	R_386_TLS_LDO_32:
			memcpy(type,"R_386_TLS_LDO_32",strlen("R_386_TLS_LDO_32"));
			break;
		case	R_386_TLS_IE_32:
			memcpy(type,"R_386_TLS_IE_32",strlen("R_386_TLS_IE_32"));
			break;
		case	R_386_TLS_LE_32:
			memcpy(type,"R_386_TLS_LE_32",strlen("R_386_TLS_LE_32"));
			break;
		case	R_386_TLS_DTPMOD32:
			memcpy(type,"R_386_TLS_DTPMOD32",strlen("R_386_TLS_DTPMOD32"));
			break;
		case	R_386_TLS_DTPOFF32:
			memcpy(type,"R_386_TLS_DTPOFF32",strlen("R_386_TLS_DTPOFF32"));
			break;
		case	R_386_TLS_TPOFF32:
			memcpy(type,"R_386_TLS_TPOFF32",strlen("R_386_TLS_TPOFF32"));
			break;
		case	R_386_IRELATIVE:
			memcpy(type,"R_386_IRELATIVE",strlen("R_386_IRELATIVE"));
			break;
		default:
			break;
		}
		break;
	case EM_ARM:
		switch(rInfo){
		case	R_ARM_NONE:
			memcpy(type,"R_ARM_NONE",strlen("R_ARM_NONE"));
			break;
		case	R_ARM_PC24:
			memcpy(type,"R_ARM_PC24",strlen("R_ARM_PC24"));
			break;
		case	R_ARM_ABS32:
			memcpy(type,"R_ARM_ABS32",strlen("R_ARM_ABS32"));
			break;
		case	R_ARM_REL32:
			memcpy(type,"R_ARM_REL32",strlen("R_ARM_REL32"));
			break;
		case	R_ARM_PC13:
			memcpy(type,"R_ARM_PC13",strlen("R_ARM_PC13"));
			break;
		case	R_ARM_ABS16:
			memcpy(type,"R_ARM_ABS16",strlen("R_ARM_ABS16"));
			break;
		case	R_ARM_ABS12:
			memcpy(type,"R_ARM_ABS12",strlen("R_ARM_ABS12"));
			break;
		case	R_ARM_THM_ABS5:
			memcpy(type,"R_ARM_THM_ABS5",strlen("R_ARM_THM_ABS5"));
			break;
		case	R_ARM_ABS8:
			memcpy(type,"R_ARM_ABS8",strlen("R_ARM_ABS8"));
			break;
		case	R_ARM_SBREL32:
			memcpy(type,"R_ARM_SBREL32",strlen("R_ARM_SBREL32"));
			break;
		case	R_ARM_THM_PC22:
			memcpy(type,"R_ARM_THM_PC22",strlen("R_ARM_THM_PC22"));
			break;
		case	R_ARM_THM_PC8:
			memcpy(type,"R_ARM_THM_PC8",strlen("R_ARM_THM_PC8"));
			break;
		case	R_ARM_AMP_VCALL9:
			memcpy(type,"R_ARM_AMP_VCALL9",strlen("R_ARM_AMP_VCALL9"));
			break;
		case	R_ARM_SWI24:
			memcpy(type,"R_ARM_SWI24",strlen("R_ARM_SWI24"));
			break;
		case	R_ARM_THM_SWI8:
			memcpy(type,"R_ARM_THM_SWI8",strlen("R_ARM_THM_SWI8"));
			break;
		case	R_ARM_XPC25:
			memcpy(type,"R_ARM_XPC25",strlen("R_ARM_XPC25"));
			break;
		case	R_ARM_THM_XPC22:
			memcpy(type,"R_ARM_THM_XPC22",strlen("R_ARM_THM_XPC22"));
			break;
		case	R_ARM_TLS_DTPMOD32:
			memcpy(type,"R_ARM_TLS_DTPMOD32",strlen("R_ARM_TLS_DTPMOD32"));
			break;
		case	R_ARM_TLS_DTPOFF32:
			memcpy(type,"R_ARM_TLS_DTPOFF32",strlen("R_ARM_TLS_DTPOFF32"));
			break;
		case	R_ARM_TLS_TPOFF32:
			memcpy(type,"R_ARM_TLS_TPOFF32",strlen("R_ARM_TLS_TPOFF32"));
			break;
		case	R_ARM_COPY:
			memcpy(type,"R_ARM_COPY",strlen("R_ARM_COPY"));
			break;
		case	R_ARM_GLOB_DAT:
			memcpy(type,"R_ARM_GLOB_DAT",strlen("R_ARM_GLOB_DAT"));
			break;
		case	R_ARM_JUMP_SLOT:
			memcpy(type,"R_ARM_JUMP_SLOT",strlen("R_ARM_JUMP_SLOT"));
			break;
		case	R_ARM_RELATIVE:
			memcpy(type,"R_ARM_RELATIVE",strlen("R_ARM_RELATIVE"));
			break;
		case	R_ARM_GOTOFF:
			memcpy(type,"R_ARM_GOTOFF",strlen("R_ARM_GOTOFF"));
			break;
		case	R_ARM_GOTPC:
			memcpy(type,"R_ARM_GOTPC",strlen("R_ARM_GOTPC"));
			break;
		case	R_ARM_GOT32:
			memcpy(type,"R_ARM_GOT32",strlen("R_ARM_GOT32"));
			break;
		case	R_ARM_PLT32:
			memcpy(type,"R_ARM_PLT32",strlen("R_ARM_PLT32"));
			break;
		case	R_ARM_GNU_VTENTRY:
			memcpy(type,"R_ARM_GNU_VTENTRY",strlen("R_ARM_GNU_VTENTRY"));
			break;
		case	R_ARM_GNU_VTINHERIT:
			memcpy(type,"R_ARM_GNU_VTINHERIT",strlen("R_ARM_GNU_VTINHERIT"));
			break;
		case	R_ARM_RSBREL32:
			memcpy(type,"R_ARM_RSBREL32",strlen("R_ARM_RSBREL32"));
			break;
		case	R_ARM_THM_RPC22:
			memcpy(type,"R_ARM_THM_RPC22",strlen("R_ARM_THM_RPC22"));
			break;
		case	R_ARM_RREL32:
			memcpy(type,"R_ARM_RREL32",strlen("R_ARM_RREL32"));
			break;
		case	R_ARM_RABS32:
			memcpy(type,"R_ARM_RABS32",strlen("R_ARM_RABS32"));
			break;
		case	R_ARM_RPC24:
			memcpy(type,"R_ARM_RPC24",strlen("R_ARM_RPC24"));
			break;
		case	R_ARM_RBASE:
			memcpy(type,"R_ARM_RBASE",strlen("R_ARM_RBASE"));
			break;
		default:
			break;
		}
		break;
	default :
		//TODO other  ellipsis...
		break;
	}
}


以后会陆续增加,查看其他节,例如plt.got got  等,还包含got hook 等

猜你喜欢

转载自blog.csdn.net/ylcangel/article/details/37997963