#include "fun.h" #include #include #include void printElf(const char *fileName) { FILE *fp = fopen(fileName, "rb"); if (fp == NULL) { printf("Error: cannot open file\n"); return; } Elf32_Ehdr ehdr; fread(&ehdr, sizeof(Elf32_Ehdr), 1, fp); fclose(fp); printf("ELF header:\n"); printf(" Magic number:\t\t\t\t\t\t%02x %02x %02x %02x\n", ehdr.e_ident[0], ehdr.e_ident[1], ehdr.e_ident[2], ehdr.e_ident[3]); printf(" Class:\t\t\t\t\t\t"); switch (ehdr.e_ident[EI_CLASS]) { case ELFCLASSNONE: printf("Invalid class\n"); break; case ELFCLASS32: printf("ELF32\n"); break; case ELFCLASS64: printf("ELF64\n"); break; default: printf("Unknown class (0x%x)\n", ehdr.e_ident[4]); break; } printf(" Data:\t\t\t\t\t\t\t"); switch (ehdr.e_ident[EI_DATA]) { case ELFDATANONE: printf("Invalid data encoding\n"); break; case ELFDATA2LSB: printf("2's complement, little endian\n"); break; case ELFDATA2MSB: printf("2's complement, big endian\n"); break; default: printf("Unknown data encoding (0x%x)\n", ehdr.e_ident[5]); break; } printf(" Version:\t\t\t\t\t\t"); switch (ehdr.e_ident[EI_VERSION]) { case EV_NONE: printf("Invalid version\n"); break; case EV_CURRENT: printf("Current version\n"); break; default: printf("Unknown version (0x%x)\n", ehdr.e_ident[6]); break; } printf(" OS/ABI:\t\t\t\t\t\t"); switch (ehdr.e_ident[EI_OSABI]) { case ELFOSABI_NONE: printf("UNIX System V ABI\n"); break; default: printf("Unknown OS/ABI (0x%x)\n", ehdr.e_ident[7]); break; } printf(" ABI Version:\t\t\t\t\t\t%d\n", ehdr.e_ident[EI_ABIVERSION]); printf(" Type:\t\t\t\t\t\t\t"); switch (ehdr.e_type) { case ET_NONE: printf("No file type\n"); break; case ET_REL: printf("Relocatable file\n"); break; case ET_EXEC: printf("Executable file\n"); break; case ET_DYN: printf("Shared object file\n"); break; case ET_CORE: printf("Core file\n"); break; case ET_LOPROC: printf("Processor-specific\n"); break; case ET_HIPROC: printf("Processor-specific\n"); break; default: printf("Unknown type (0x%x)\n", ehdr.e_type); break; } printf(" Machine:\t\t\t\t\t\t"); switch (ehdr.e_machine) { case EM_386: printf("Intel 80386\n"); break; default: printf("Unknown type (0x%x)\n", ehdr.e_type); break; } printf(" Version:\t\t\t\t\t\t0x%x\n", ehdr.e_version); printf(" Entry point address:\t\t\t\t\t0x%x\n", ehdr.e_entry); printf(" Start of program headers:\t\t\t\t%d (bytes into file)\n", ehdr.e_phoff); printf(" Start of section headers:\t\t\t\t%d (bytes into file)\n", ehdr.e_shoff); printf(" Flags:\t\t\t\t\t\t0x%x\n", ehdr.e_flags); printf(" Size of this header:\t\t\t\t\t%d (bytes)\n", ehdr.e_ehsize); printf(" Size of program headers:\t\t\t\t%d (bytes)\n", ehdr.e_phentsize); printf(" Number of program headers:\t\t\t\t%d\n", ehdr.e_phnum); printf(" Size of section headers:\t\t\t\t%d (bytes)\n", ehdr.e_shentsize); printf(" Number of section headers:\t\t\t\t%d \n", ehdr.e_shnum); printf(" Section header string table index:\t\t\t%d \n", ehdr.e_shstrndx); } void printElfFunc(const char *fileName) { FILE *fd = fopen(fileName, "rb"); if (!fd) { perror("Failed to open file"); return; } Elf32_Ehdr ehdr; fread(&ehdr, sizeof(Elf32_Ehdr), 1, fd); fseek(fd, ehdr.e_shoff, SEEK_SET); Elf32_Shdr simbolHdr; Elf32_Shdr stringHdr; uint8_t strtab = 0; for (size_t i = 0; i < ehdr.e_shnum; i++) { Elf32_Shdr shdr; fread(&shdr, sizeof(Elf32_Shdr), 1, fd); if (shdr.sh_type == SHT_SYMTAB) { simbolHdr = shdr; } else if (shdr.sh_type == SHT_STRTAB) { strtab++; if (strtab == 2) { stringHdr = shdr; } } } size_t numOfSimbols = simbolHdr.sh_size / sizeof(Elf32_Sym); char name[20]; memset(name, 0, sizeof(name)); printf("%-10s%-10s %-10s%-20s\n", "NR", "Value", "Size", "Name"); int pos = 0; for (size_t i = 0; i < numOfSimbols; i++) { fseek(fd, simbolHdr.sh_offset + i * sizeof(Elf32_Sym), SEEK_SET); Elf32_Sym sys; fread(&sys, sizeof(Elf32_Sym), 1, fd); if (sys.st_size > 50) { printf("%-10d", pos++); printf("0x%-8x ", sys.st_value); printf("%-10d", sys.st_size); fseek(fd, stringHdr.sh_offset + sys.st_name, SEEK_SET); fread(&name, sizeof(name), 1, fd); printf("%-20s\n", name); } } fclose(fd); return; } void changeElf(int argc, const char **argv) { FILE *fd = fopen(argv[2], "r+b"); if (!fd) { perror("Failed to open file"); return; } Elf32_Ehdr ehdr; fread(&ehdr, sizeof(Elf32_Ehdr), 1, fd); fseek(fd, ehdr.e_shoff, SEEK_SET); Elf32_Shdr simbolHdr; Elf32_Shdr stringHdr; uint8_t strtab = 0; for (size_t i = 0; i < ehdr.e_shnum; i++) { Elf32_Shdr shdr; fread(&shdr, sizeof(Elf32_Shdr), 1, fd); if (shdr.sh_type == SHT_SYMTAB) { simbolHdr = shdr; } else if (shdr.sh_type == SHT_STRTAB) { strtab++; if (strtab == 2) { stringHdr = shdr; } } } size_t numOfSimbols = simbolHdr.sh_size / sizeof(Elf32_Sym); char name[20]; memset(name, 0, sizeof(name)); printf("%-10s\t%s\t\t%s\t%s\t\n", "IME", "NASLOV", "VREDNOST", "NOVA_VREDNOST"); for (unsigned int i = 0; i < numOfSimbols; ++i) { fseek(fd, simbolHdr.sh_offset + i * sizeof(Elf32_Sym), SEEK_SET); Elf32_Sym sys; fread(&sys, sizeof(Elf32_Sym), 1, fd); if (!(ELF32_ST_TYPE(sys.st_info) == STT_OBJECT && ELF32_ST_BIND(sys.st_info) == STB_GLOBAL)) continue; fseek(fd, stringHdr.sh_offset + sys.st_name, SEEK_SET); fread(&name, sizeof(name), 1, fd); int con = 1; for (int j = 3; j < argc; j++) { if (strcmp(name, argv[j]) == 0) { con = 0; break; } } if (con) continue; printf("%-10s\t", name); printf("%x\t\t", sys.st_value); fseek(fd, ehdr.e_shoff + sys.st_shndx * sizeof(Elf32_Shdr), SEEK_SET); Elf32_Shdr hdr; fread(&hdr, sizeof(Elf32_Shdr), 1, fd); uint32_t realAddr = (sys.st_value - hdr.sh_addr) + hdr.sh_offset; fseek(fd, realAddr, SEEK_SET); uint32_t val; fread(&val, sizeof(uint32_t), 1, fd); printf("%x\t\t", val); val += 10; fseek(fd, realAddr, SEEK_SET); fwrite(&val, sizeof(val), 1, fd); printf("%x\n", val); } fclose(fd); return; }