在没有 libelf 或任何其他库的情况下使用 C 创建可重定位的 elf 二进制文件
Creating a relocatable elf binary with C without libelf nor any other libraries
所以我正在尝试用 c 创建一个可重定位的 elf 二进制文件。我不想使用和库或类似的东西。我已经写了一些代码。这是我一直在阅读的资源:https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html。我让小精灵 header 看起来正确。当涉及到部分和部分 headers 时,我只是遇到错误。
这是我的主要代码
#include <stdio.h>
#include <stdlib.h>
#include "elf.h"
const unsigned char strtab[] = {
'[=10=]',
'.', 's', 'h', 's', 't', 'r', 't', 'a', 'b', '[=10=]',
'.', 's', 't', 'r', 't', 'a', 'b', '[=10=]',
'.', 'd', 'a', 't', 'a', '[=10=]',
'.', 't', 'e', 'x', 't', '[=10=]',
};
int strtab_size = sizeof(strtab);
int strtab_index = 1;
int section_n = 2;
Elf32_Shdr * create_shdr(){
Elf32_Shdr * header = calloc(sizeof(Elf32_Shdr), 1);
if (header == NULL){
return NULL;
}
return header;
}
Elf32_Ehdr * create_ehdr(){
Elf32_Ehdr * header = calloc(sizeof(Elf32_Ehdr), 1);
if (header == NULL){
return NULL;
}
header->e_ident[EI_MAG0] = 0x7f;
header->e_ident[EI_MAG1] = 'E';
header->e_ident[EI_MAG2] = 'L';
header->e_ident[EI_MAG3] = 'F';
// set the object to 32 bit
header->e_ident[EI_CLASS] = ELFCLASS32;
header->e_ident[EI_DATA] = ELFDATA2LSB;
// set the file version
header->e_ident[EI_VERSION] = EV_CURRENT;
// set sysv abi
header->e_ident[EI_OSABI] = ELFOSABI_SYSV;
header->e_ident[EI_ABIVERSION] = ELFOSABI_NONE;
header->e_ident[EI_PAD] = 0; // needs to be changed
header->e_shentsize = sizeof(Elf32_Shdr);
// we default to relocatable
header->e_type = ET_REL;
header->e_machine = EM_X86;
header->e_version = EV_CURRENT;
header->e_ehsize = sizeof(Elf32_Ehdr);
header->e_phentsize = sizeof(Elf32_Phdr);
header->e_phnum = 0;
return header;
}
int main()
{
FILE * fout;
Elf32_Ehdr *elf_header;
Elf32_Shdr *NULL_Section; // this should all be null
Elf32_Shdr *strtab_Section;
printf("%d\n", strtab_size);
fout = fopen("output.elf", "wb");
if (fout == NULL){
printf("Failed to open output.elf\n");
return 1;
}
if ((elf_header = create_ehdr()) == NULL){
printf("Failed to create new header\n");
return 1;
}
if ((NULL_Section = create_shdr()) == NULL){
printf("Failed to create new section header\n");
return 1;
}
if ((strtab_Section = create_shdr()) == NULL){
printf("Failed to create new section header\n");
return 1;
}
elf_header->e_shstrndx = strtab_index; // Point to the shstrtab section
elf_header->e_shnum = section_n;
elf_header->e_shoff = sizeof(Elf32_Ehdr)-1;
strtab_Section->sh_type = SHT_STRTAB;
strtab_Section->sh_offset = ((sizeof(Elf32_Shdr))*1)+sizeof(Elf32_Ehdr);
strtab_Section->sh_addr = 80;
//strtab_Section->sh_addralign = 1;
strtab_Section->sh_size = strtab_size;
fwrite(elf_header, sizeof(Elf32_Ehdr), 1, fout);
fwrite(NULL_Section, sizeof(Elf32_Shdr), 1, fout);
fwrite(strtab_Section, sizeof(Elf32_Shdr), 1, fout);
fwrite(strtab, strtab_size, 1, fout);
return 0;
}
我的 elf.h 文件是
#pragma once
enum EI{
EI_MAG0 = 0,
EI_MAG1,
EI_MAG2,
EI_MAG3,
EI_CLASS,
EI_DATA,
EI_VERSION,
EI_OSABI,
EI_ABIVERSION,
EI_PAD,
};
#define ELFOSABI_NONE 0 //No extensions or unspecified
#define ELFOSABI_HPUX 1 //Hewlett-Packard HP-UX
#define ELFOSABI_NETBSD 2 //NetBSD
#define ELFOSABI_LINUX 3 //Linux
#define ELFOSABI_SOLARIS 6 //Sun Solaris
#define ELFOSABI_AIX 7 //AIX
#define ELFOSABI_IRIX 8 //IRIX
#define ELFOSABI_FREEBSD 9 //FreeBSD
#define ELFOSABI_TRU64 10 //Compaq TRU64 UNIX
#define ELFOSABI_MODESTO 11 //Novell Modesto
#define ELFOSABI_OPENBSD 12 //Open BSD
#define ELFOSABI_OPENVMS 13 //Open VMS
#define ELFOSABI_NSK 14 //Hewlett-Packard Non-Stop Kernel
#define SHF_WRITE 0x1
#define SHF_ALLOC 0x2
#define SHF_EXECINSTR 0x4
#define SHF_MERGE 0x10
#define SHF_STRINGS 0x20
#define SHF_INFO_LINK 0x40
#define SHF_LINK_ORDER 0x80
#define SHF_OS_NONCONFORMING 0x100
#define SHF_GROUP 0x200
#define SHF_TLS 0x400
#define SHF_MASKOS 0x0ff00000
#define SHF_MASKPROC 0xf0000000
#define ELFCLASSNONE 0
#define ELFCLASS32 1
#define ELFCLASS64 2
#define ELFDATANONE 0
#define ELFDATA2LSB 1
#define ELFDATA2MSB 2
#define ELFOSABI_SYSV 0
#define ELFOSABI_HPUX 1
#define ELFOSABI_STANDALONE 255
#define ET_NONE 0
#define ET_REL 1 // relocatable file
#define ET_EXEC 2 // executable file
#define ET_DYN 3 // shared object file
#define ET_CORE 4 // core file
#define ET_LOOS 0xfe00 // operating system-specific
#define ET_HIOS 0xfeff // operating system specific
#define ET_LOPROC 0xff00 // processor-specific
#define ET_HIPROC 0xffff // processor-specific
#define SHT_NULL 0
#define SHT_PROGBITS 1
#define SHT_SYMTAB 2
#define SHT_STRTAB 3
#define SHT_RELA 4
#define SHT_HASH 5
#define SHT_DYNAMIC 6
#define SHT_NOTE 7
#define SHT_NOBITS 8
#define SHT_REL 9
#define SHT_SHLIB 10
#define SHT_DYNSYM 11
#define SHT_INIT_ARRAY 14
#define SHT_FINI_ARRAY 15
#define SHT_PREINIT_ARRAY 16
#define SHT_GROUP 17
#define SHT_SYMTAB_SHNDX 18
#define SHT_LOOS 0x60000000
#define SHT_HIOS 0x6fffffff
#define SHT_LOPROC 0x70000000
#define SHT_HIPROC 0x7fffffff
#define SHT_LOUSER 0x80000000
#define SHT_HIUSER 0xffffffff
#define EM_X86 0x03
#define EM_AMD_X86_64 0x3E
#define EV_NONE 0
#define EV_CURRENT 1
#define EI_NIDENT 16
typedef unsigned int Elf32_Addr;
typedef unsigned short Elf32_Half;
typedef unsigned int Elf32_Off;
typedef signed int Elf32_Sword;
typedef unsigned int Elf32_Word;
typedef struct{ // elf file header
unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
} Elf32_Ehdr;
typedef struct { // program header
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
} Elf32_Phdr;
typedef struct{ // section header
Elf32_Word sh_name;
Elf32_Word sh_type;
Elf32_Word sh_flags;
Elf32_Addr sh_addr;
Elf32_Off sh_offset;
Elf32_Word sh_size;
Elf32_Word sh_link;
Elf32_Word sh_info;
Elf32_Word sh_addralign;
Elf32_Word sh_entsize;
} Elf32_Shdr;
我一直在用 readelf 测试我的二进制文件是否全部正确。这是使用命令 readelf --section-headers output.elf
:
时的当前输出
There are 2 section headers, starting at offset 0x33:
readelf: Error: Reading 7936 bytes extends past end of file for string table
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] <no-strings> NULL 00000000 000000 000000 00 0 0 0
readelf: Warning: Size of section 1 is larger than the entire file!
[ 1] <no-strings> 00000300: <unkn 00005000 005c00 001f00 00 0 0 0
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), p (processor specific)
readelf: Error: Reading 7936 bytes extends past end of file for string table
readelf: Error: Reading 7936 bytes extends past end of file for string table
readelf: Error: Reading 7936 bytes extends past end of file for string table
readelf: Error: Reading 7936 bytes extends past end of file for string table
readelf: Error: Reading 7936 bytes extends past end of file for string table
NULL 部分的偏移量 header 似乎一切正常,所以我认为这不是问题所在。 header 的大小是正确的,所以我不认为是这样。我真的很困惑为什么这会给我错误。有没有人看到我做错了什么?
如果您需要更多信息,请发表评论,我会添加您需要的任何内容。
更新:
这是我对代码所做的更改
elf_header->e_shstrndx = strtab_index; // Point to the shstrtab section
elf_header->e_shnum = section_n;
elf_header->e_shoff = sizeof(Elf32_Ehdr);
strtab_Section->sh_type = SHT_STRTAB;
strtab_Section->sh_offset = ((sizeof(Elf32_Shdr))*1)+sizeof(Elf32_Ehdr);
strtab_Section->sh_addr = sizeof(Elf32_Shdr)*2;
strtab_Section->sh_addralign = 1;
strtab_Section->sh_size = sizeof(*strtab_Section) + strtab_size;
i have got the elf headers looking correct.
我不这么认为:
readelf -Wh output.elf
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 51 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 2
Section header string table index: 1
readelf: Error: Reading 7936 bytes extends past end of file for string table
readelf: Error: Reading 7936 bytes extends past end of file for string table
readelf: Error: Reading 7936 bytes extends past end of file for string table
readelf: Error: Reading 7936 bytes extends past end of file for string table
readelf: Error: Reading 7936 bytes extends past end of file for string table
readelf: Error: Reading 7936 bytes extends past end of file for string table
headers 部分的开头显然 是假的。从此行中删除伪造的 -1
:
elf_header->e_shoff = sizeof(Elf32_Ehdr)-1;
生成一个看起来更好的 output.elf
二进制文件:
readelf -W --all output.elf
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 52 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 2
Section header string table index: 1
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] STRTAB 00000050 00005c 00001f 00 0 0 0
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), p (processor specific)
There are no section groups in this file.
There are no program headers in this file.
There is no dynamic section in this file.
There are no relocations in this file.
No processor specific unwind information to decode
No version information found in this file.
更新:
why my string table is not working then?
为此,您需要设置 strtab_Section->sh_name = 1;
并将其 sh_offset
设置为 ((sizeof(Elf32_Shdr))*2)+sizeof(Elf32_Ehdr)
(您有 两个 部分,而不是一个) .
As-is、.sh_name == 0
,对应空串。通过以上更改,我得到:
There are 2 section headers, starting at offset 0x34:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .shstrtab STRTAB 00000050 000084 00001f 00 0 0 0
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), p (processor specific)
所以我正在尝试用 c 创建一个可重定位的 elf 二进制文件。我不想使用和库或类似的东西。我已经写了一些代码。这是我一直在阅读的资源:https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html。我让小精灵 header 看起来正确。当涉及到部分和部分 headers 时,我只是遇到错误。 这是我的主要代码
#include <stdio.h>
#include <stdlib.h>
#include "elf.h"
const unsigned char strtab[] = {
'[=10=]',
'.', 's', 'h', 's', 't', 'r', 't', 'a', 'b', '[=10=]',
'.', 's', 't', 'r', 't', 'a', 'b', '[=10=]',
'.', 'd', 'a', 't', 'a', '[=10=]',
'.', 't', 'e', 'x', 't', '[=10=]',
};
int strtab_size = sizeof(strtab);
int strtab_index = 1;
int section_n = 2;
Elf32_Shdr * create_shdr(){
Elf32_Shdr * header = calloc(sizeof(Elf32_Shdr), 1);
if (header == NULL){
return NULL;
}
return header;
}
Elf32_Ehdr * create_ehdr(){
Elf32_Ehdr * header = calloc(sizeof(Elf32_Ehdr), 1);
if (header == NULL){
return NULL;
}
header->e_ident[EI_MAG0] = 0x7f;
header->e_ident[EI_MAG1] = 'E';
header->e_ident[EI_MAG2] = 'L';
header->e_ident[EI_MAG3] = 'F';
// set the object to 32 bit
header->e_ident[EI_CLASS] = ELFCLASS32;
header->e_ident[EI_DATA] = ELFDATA2LSB;
// set the file version
header->e_ident[EI_VERSION] = EV_CURRENT;
// set sysv abi
header->e_ident[EI_OSABI] = ELFOSABI_SYSV;
header->e_ident[EI_ABIVERSION] = ELFOSABI_NONE;
header->e_ident[EI_PAD] = 0; // needs to be changed
header->e_shentsize = sizeof(Elf32_Shdr);
// we default to relocatable
header->e_type = ET_REL;
header->e_machine = EM_X86;
header->e_version = EV_CURRENT;
header->e_ehsize = sizeof(Elf32_Ehdr);
header->e_phentsize = sizeof(Elf32_Phdr);
header->e_phnum = 0;
return header;
}
int main()
{
FILE * fout;
Elf32_Ehdr *elf_header;
Elf32_Shdr *NULL_Section; // this should all be null
Elf32_Shdr *strtab_Section;
printf("%d\n", strtab_size);
fout = fopen("output.elf", "wb");
if (fout == NULL){
printf("Failed to open output.elf\n");
return 1;
}
if ((elf_header = create_ehdr()) == NULL){
printf("Failed to create new header\n");
return 1;
}
if ((NULL_Section = create_shdr()) == NULL){
printf("Failed to create new section header\n");
return 1;
}
if ((strtab_Section = create_shdr()) == NULL){
printf("Failed to create new section header\n");
return 1;
}
elf_header->e_shstrndx = strtab_index; // Point to the shstrtab section
elf_header->e_shnum = section_n;
elf_header->e_shoff = sizeof(Elf32_Ehdr)-1;
strtab_Section->sh_type = SHT_STRTAB;
strtab_Section->sh_offset = ((sizeof(Elf32_Shdr))*1)+sizeof(Elf32_Ehdr);
strtab_Section->sh_addr = 80;
//strtab_Section->sh_addralign = 1;
strtab_Section->sh_size = strtab_size;
fwrite(elf_header, sizeof(Elf32_Ehdr), 1, fout);
fwrite(NULL_Section, sizeof(Elf32_Shdr), 1, fout);
fwrite(strtab_Section, sizeof(Elf32_Shdr), 1, fout);
fwrite(strtab, strtab_size, 1, fout);
return 0;
}
我的 elf.h 文件是
#pragma once
enum EI{
EI_MAG0 = 0,
EI_MAG1,
EI_MAG2,
EI_MAG3,
EI_CLASS,
EI_DATA,
EI_VERSION,
EI_OSABI,
EI_ABIVERSION,
EI_PAD,
};
#define ELFOSABI_NONE 0 //No extensions or unspecified
#define ELFOSABI_HPUX 1 //Hewlett-Packard HP-UX
#define ELFOSABI_NETBSD 2 //NetBSD
#define ELFOSABI_LINUX 3 //Linux
#define ELFOSABI_SOLARIS 6 //Sun Solaris
#define ELFOSABI_AIX 7 //AIX
#define ELFOSABI_IRIX 8 //IRIX
#define ELFOSABI_FREEBSD 9 //FreeBSD
#define ELFOSABI_TRU64 10 //Compaq TRU64 UNIX
#define ELFOSABI_MODESTO 11 //Novell Modesto
#define ELFOSABI_OPENBSD 12 //Open BSD
#define ELFOSABI_OPENVMS 13 //Open VMS
#define ELFOSABI_NSK 14 //Hewlett-Packard Non-Stop Kernel
#define SHF_WRITE 0x1
#define SHF_ALLOC 0x2
#define SHF_EXECINSTR 0x4
#define SHF_MERGE 0x10
#define SHF_STRINGS 0x20
#define SHF_INFO_LINK 0x40
#define SHF_LINK_ORDER 0x80
#define SHF_OS_NONCONFORMING 0x100
#define SHF_GROUP 0x200
#define SHF_TLS 0x400
#define SHF_MASKOS 0x0ff00000
#define SHF_MASKPROC 0xf0000000
#define ELFCLASSNONE 0
#define ELFCLASS32 1
#define ELFCLASS64 2
#define ELFDATANONE 0
#define ELFDATA2LSB 1
#define ELFDATA2MSB 2
#define ELFOSABI_SYSV 0
#define ELFOSABI_HPUX 1
#define ELFOSABI_STANDALONE 255
#define ET_NONE 0
#define ET_REL 1 // relocatable file
#define ET_EXEC 2 // executable file
#define ET_DYN 3 // shared object file
#define ET_CORE 4 // core file
#define ET_LOOS 0xfe00 // operating system-specific
#define ET_HIOS 0xfeff // operating system specific
#define ET_LOPROC 0xff00 // processor-specific
#define ET_HIPROC 0xffff // processor-specific
#define SHT_NULL 0
#define SHT_PROGBITS 1
#define SHT_SYMTAB 2
#define SHT_STRTAB 3
#define SHT_RELA 4
#define SHT_HASH 5
#define SHT_DYNAMIC 6
#define SHT_NOTE 7
#define SHT_NOBITS 8
#define SHT_REL 9
#define SHT_SHLIB 10
#define SHT_DYNSYM 11
#define SHT_INIT_ARRAY 14
#define SHT_FINI_ARRAY 15
#define SHT_PREINIT_ARRAY 16
#define SHT_GROUP 17
#define SHT_SYMTAB_SHNDX 18
#define SHT_LOOS 0x60000000
#define SHT_HIOS 0x6fffffff
#define SHT_LOPROC 0x70000000
#define SHT_HIPROC 0x7fffffff
#define SHT_LOUSER 0x80000000
#define SHT_HIUSER 0xffffffff
#define EM_X86 0x03
#define EM_AMD_X86_64 0x3E
#define EV_NONE 0
#define EV_CURRENT 1
#define EI_NIDENT 16
typedef unsigned int Elf32_Addr;
typedef unsigned short Elf32_Half;
typedef unsigned int Elf32_Off;
typedef signed int Elf32_Sword;
typedef unsigned int Elf32_Word;
typedef struct{ // elf file header
unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
} Elf32_Ehdr;
typedef struct { // program header
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
} Elf32_Phdr;
typedef struct{ // section header
Elf32_Word sh_name;
Elf32_Word sh_type;
Elf32_Word sh_flags;
Elf32_Addr sh_addr;
Elf32_Off sh_offset;
Elf32_Word sh_size;
Elf32_Word sh_link;
Elf32_Word sh_info;
Elf32_Word sh_addralign;
Elf32_Word sh_entsize;
} Elf32_Shdr;
我一直在用 readelf 测试我的二进制文件是否全部正确。这是使用命令 readelf --section-headers output.elf
:
There are 2 section headers, starting at offset 0x33:
readelf: Error: Reading 7936 bytes extends past end of file for string table
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] <no-strings> NULL 00000000 000000 000000 00 0 0 0
readelf: Warning: Size of section 1 is larger than the entire file!
[ 1] <no-strings> 00000300: <unkn 00005000 005c00 001f00 00 0 0 0
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), p (processor specific)
readelf: Error: Reading 7936 bytes extends past end of file for string table
readelf: Error: Reading 7936 bytes extends past end of file for string table
readelf: Error: Reading 7936 bytes extends past end of file for string table
readelf: Error: Reading 7936 bytes extends past end of file for string table
readelf: Error: Reading 7936 bytes extends past end of file for string table
NULL 部分的偏移量 header 似乎一切正常,所以我认为这不是问题所在。 header 的大小是正确的,所以我不认为是这样。我真的很困惑为什么这会给我错误。有没有人看到我做错了什么? 如果您需要更多信息,请发表评论,我会添加您需要的任何内容。
更新: 这是我对代码所做的更改
elf_header->e_shstrndx = strtab_index; // Point to the shstrtab section
elf_header->e_shnum = section_n;
elf_header->e_shoff = sizeof(Elf32_Ehdr);
strtab_Section->sh_type = SHT_STRTAB;
strtab_Section->sh_offset = ((sizeof(Elf32_Shdr))*1)+sizeof(Elf32_Ehdr);
strtab_Section->sh_addr = sizeof(Elf32_Shdr)*2;
strtab_Section->sh_addralign = 1;
strtab_Section->sh_size = sizeof(*strtab_Section) + strtab_size;
i have got the elf headers looking correct.
我不这么认为:
readelf -Wh output.elf
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 51 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 2
Section header string table index: 1
readelf: Error: Reading 7936 bytes extends past end of file for string table
readelf: Error: Reading 7936 bytes extends past end of file for string table
readelf: Error: Reading 7936 bytes extends past end of file for string table
readelf: Error: Reading 7936 bytes extends past end of file for string table
readelf: Error: Reading 7936 bytes extends past end of file for string table
readelf: Error: Reading 7936 bytes extends past end of file for string table
headers 部分的开头显然 是假的。从此行中删除伪造的 -1
:
elf_header->e_shoff = sizeof(Elf32_Ehdr)-1;
生成一个看起来更好的 output.elf
二进制文件:
readelf -W --all output.elf
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 52 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 2
Section header string table index: 1
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] STRTAB 00000050 00005c 00001f 00 0 0 0
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), p (processor specific)
There are no section groups in this file.
There are no program headers in this file.
There is no dynamic section in this file.
There are no relocations in this file.
No processor specific unwind information to decode
No version information found in this file.
更新:
why my string table is not working then?
为此,您需要设置 strtab_Section->sh_name = 1;
并将其 sh_offset
设置为 ((sizeof(Elf32_Shdr))*2)+sizeof(Elf32_Ehdr)
(您有 两个 部分,而不是一个) .
As-is、.sh_name == 0
,对应空串。通过以上更改,我得到:
There are 2 section headers, starting at offset 0x34:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .shstrtab STRTAB 00000050 000084 00001f 00 0 0 0
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), p (processor specific)