299 lines
7.2 KiB
C

#include "fun.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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;
}