44 #include <sys/procfs.h>
46 #include <sys/types.h>
47 #include <sys/ucontext.h>
55 #include <sys/types.h>
62 #include <nametotype.h>
63 #include <nametoalign.h>
64 #include <nametoentsz.h>
65 #include <nametolink.h>
66 #include <nametoinfo.h>
72 #define DEFAULT_STRNDX_SIZE 4096
77 #define FLAG_NOWRITE 4
80 #define ifis(x) if(!strncmp(name, x, strlen(x)))
81 #define elis(x) else if(!strncmp(name, x, strlen(x)))
85 #define EXTRA_CREATED_SECTIONS 4
88 #define RELOC_X86_64 1
89 #define RELOC_X86_32 2
92 #ifdef __LP64__ // Generic 64b
93 #define Elf_Ehdr Elf64_Ehdr
94 #define Elf_Shdr Elf64_Shdr
95 #define Elf_Sym Elf64_Sym
96 #define Elf_Addr Elf64_Addr
97 #define Elf_Sword Elf64_Sxword
98 #define Elf_Section Elf64_Half
99 #define ELF_ST_BIND ELF64_ST_BIND
100 #define ELF_ST_TYPE ELF64_ST_TYPE
101 #define Elf_Rel Elf64_Rel
102 #define Elf_Rela Elf64_Rela
103 #define ELF_R_SYM ELF64_R_SYM
104 #define ELF_R_TYPE ELF64_R_TYPE
105 #define ELF_R_INFO ELF64_R_INFO
106 #define Elf_Phdr Elf64_Phdr
107 #define Elf_Xword Elf64_Xword
108 #define Elf_Word Elf64_Word
109 #define Elf_Off Elf64_Off
110 #define ELFCLASS ELFCLASS64
111 #define ELFMACHINE EM_X86_64
112 #define CS_MODE CS_MODE_64
113 #define RELOC_MODE RELOC_X86_64
115 #define Elf_Ehdr Elf32_Ehdr
116 #define Elf_Shdr Elf32_Shdr
117 #define Elf_Sym Elf32_Sym
118 #define Elf_Addr Elf32_Addr
119 #define Elf_Sword Elf64_Sword
120 #define Elf_Section Elf32_Half
121 #define ELF_ST_BIND ELF32_ST_BIND
122 #define ELF_ST_TYPE ELF32_ST_TYPE
123 #define Elf_Rel Elf32_Rel
124 #define Elf_Rela Elf32_Rela
125 #define ELF_R_SYM ELF32_R_SYM
126 #define ELF_R_TYPE ELF32_R_TYPE
127 #define ELF_R_INFO ELF32_R_INFO
128 #define Elf_Phdr Elf32_Phdr
129 #define Elf_Xword Elf32_Xword
130 #define Elf_Word Elf32_Word
131 #define Elf_Off Elf32_Off
132 #define ELFCLASS ELFCLASS32
133 #define ELFMACHINE EM_386
134 #define CS_MODE CS_MODE_32
135 #define RELOC_MODE RELOC_X86_32
139 #define nullstr "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
159 "__init_array_start",
163 "__x86.get_pc_thunk.bx",
178 "__GNU_EH_FRAME_HDR",
182 ".note.gnu.build-id",
193 "_ITM_registerTMCloneTable",
194 "_ITM_deregisterTMClone",
195 "_ITM_deregisterTMCloneTab",
196 "_Jv_RegisterClasses",
197 "_ITM_registerTMCloneTa",
200 "_GLOBAL_OFFSET_TABLE_",
207 "__do_global_dtors_aux",
208 "__do_global_dtors_aux_fini_array_entry",
210 "__frame_dummy_init_array_entry",
219 "deregister_tm_clones",
221 "register_tm_clones",
331 unsigned long int addr);
366 static int parse_bfd_perm(
int perm)
370 heal_perm |= (perm & SEC_CODE ? 1 : 0);
371 heal_perm |= (perm & SEC_DATA ? 2 : 0);
372 heal_perm |= (perm & SEC_ALLOC ? 4 : 0);
373 heal_perm = (perm & SEC_READONLY ? heal_perm : 4);
383 unsigned int memperms = 0;
387 memperms = PROT_READ | PROT_WRITE | PROT_EXEC;
390 memperms = PROT_READ;
393 memperms = PROT_READ | PROT_EXEC;
396 memperms = PROT_READ | PROT_WRITE;
428 unsigned long int nameptr = 0;
438 if ((s->st_value == addr -
textvma) && (s->st_value != 0)) {
444 for (i = 0; i <
sizeof(
blnames) /
sizeof(
char *); i++) {
445 if ((strlen(name) == strlen(
blnames[i]))
451 memset(sa, 0,
sizeof(
struct symaddr));
452 sa->
name = strdup(name);
464 printf(
"%s% *s\t\t%x\t\t%c\n", sa->
name, pad,
"", sa->
addr, symclass);
493 s->st_name = nameptr;
512 s->st_value -= t->
s_bfd->vma;
549 if (isupper(symclass)) {
577 asymbol **symbol_table = NULL;
578 long number_of_symbols;
582 const char *sym_name;
587 printf(
"\n\n -- Reading symbols\n\n");
588 printf(
" Symbol\t\t\t\taddress\t\tclass\n");
589 printf(
" -----------------------------------------------------\n");
595 storage_needed = bfd_get_symtab_upper_bound(ctx->
abfd);
596 if (storage_needed < 0) {
597 bfd_perror(
"warning: bfd_get_symtab_upper_bound");
601 if (storage_needed == 0) {
602 fprintf(stderr,
"warning: no symbols\n");
605 symbol_table = (asymbol **) malloc(storage_needed);
606 number_of_symbols = bfd_canonicalize_symtab(ctx->
abfd, symbol_table);
607 if (number_of_symbols < 0) {
608 bfd_perror(
"warning: bfd_canonicalize_symtab");
612 for (i = 0; i < number_of_symbols; i++) {
613 asymbol *asym = symbol_table[i];
614 sym_name = bfd_asymbol_name(asym);
615 symclass = bfd_decode_symclass(asym);
616 sym_value = bfd_asymbol_value(asym);
617 if (*sym_name ==
'\0') {
620 if (bfd_is_undefined_symclass(symclass)) {
638 storage_needed = bfd_get_dynamic_symtab_upper_bound(ctx->
abfd);
639 if (storage_needed < 0) {
640 bfd_perror(
"warning: bfd_get_dynamic_symtab_upper_bound");
644 if (storage_needed == 0) {
645 fprintf(stderr,
"warning: no symbols\n");
648 symbol_table = (asymbol **) malloc(storage_needed);
649 number_of_symbols = bfd_canonicalize_dynamic_symtab(ctx->
abfd, symbol_table);
650 if (number_of_symbols < 0) {
651 bfd_perror(
"warning: bfd_canonicalize_symtab");
655 for (i = 0; i < number_of_symbols; i++) {
656 asymbol *asym = symbol_table[i];
657 sym_name = bfd_asymbol_name(asym);
658 symclass = bfd_decode_symclass(asym);
659 sym_value = bfd_asymbol_value(asym);
660 if (*sym_name ==
'\0') {
663 if (bfd_is_undefined_symclass(symclass)) {
686 for (i = 0; i <
sizeof(nametosize) /
sizeof(assoc_nametosz_t); i++) {
687 if (!strncmp(nametosize[i].name, name, strlen(name))) {
688 return nametosize[i].sz;
697 unsigned int max(
unsigned int a,
unsigned int b)
699 return a < b ? b : a;
709 DL_FOREACH(ctx->
mshdrs, s) {
710 if (!strncmp(s->
name, name,
max(strlen(name), strlen(s->
name)))) {
724 DL_FOREACH(ctx->
mshdrs, s) {
725 if ((s->
s_bfd->vma) && (s->
s_bfd->vma <= addr)
740 DL_FOREACH(ctx->
mshdrs, s) {
758 DL_FOREACH(ctx->
mshdrs, s) {
759 if (!strncmp(s->
name, name,
max(strlen(name), strlen(s->
name)))) {
776 DL_FOREACH(ctx->
mshdrs, s) {
777 if (!strncmp(s->
name, name,
max(strlen(name), strlen(s->
name)))) {
798 DL_FOREACH(ctx->
mshdrs, s) {
826 for (i = 0; i <
sizeof(nametolink) /
sizeof(assoc_nametolink_t); i++) {
827 if (!strncmp(nametolink[i].name, name, strlen(name))) {
828 destsec = nametolink[i].dst;
849 for (i = 0; i <
sizeof(nametoinfo) /
sizeof(assoc_nametoinfo_t); i++) {
850 if (!strncmp(nametoinfo[i].name, name, strlen(name))) {
851 destsec = nametoinfo[i].dst;
870 for (i = 0; i <
sizeof(nametotype) /
sizeof(assoc_nametotype_t); i++) {
871 if (!strncmp(nametotype[i].name, name, strlen(name))) {
872 return nametotype[i].type;
885 for (i = 0; i <
sizeof(nametoalign) /
sizeof(assoc_nametoalign_t); i++) {
886 if (!strncmp(nametoalign[i].name, name, strlen(name))) {
887 return nametoalign[i].alignment;
900 if (!strncmp(ms->
name,
".interp", 7)) {
904 if (!strncmp(ms->
name,
".dynamic", 8)) {
908 if (!strncmp(ms->
name,
".eh_frame_hdr", 13)) {
909 return PT_GNU_EH_FRAME;
912 switch (ms->
s_elf->sh_type) {
932 case SHT_GNU_verneed:
945 unsigned int dperms = 0;
948 switch (ms->
s_elf->sh_flags) {
949 case SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR:
950 dperms = PF_R | PF_W | PF_X;
955 case SHF_ALLOC | SHF_EXECINSTR:
956 dperms = PF_R | PF_X;
958 case SHF_ALLOC | SHF_WRITE:
959 dperms = PF_R | PF_W;
1015 p = calloc(1,
sizeof(
mseg_t));
1037 DL_FOREACH_SAFE(ctx->
mshdrs, ms, tmp) {
1041 if (p->
p_type == PT_LOAD) {
1054 DL_APPEND(ctx->
mphdrs, p);
1128 printf(
"\n * first loadable segment at: 0x%x\n", ctx->
base_address);
1133 if ((ms->
p_type == PT_LOAD) && (ms->
p_flags == (PF_R | PF_X))) {
1136 (
" -- patching base load address of first PT_LOAD Segment: %lu -->> %u\n",
1146 ms = (
void *) ms->
next;
1154 static unsigned int rd_phdrs(
ctx_t * ctx)
1164 if (stat(ctx->
binname, &sb) == -1) {
1169 p = calloc(1, sb.st_size);
1170 fdin = open(ctx->
binname, O_RDONLY);
1175 nread = read(fdin, p, sb.st_size);
1176 if (nread != sb.st_size) {
1182 printf(
" -- read: %u bytes\n", nread);
1185 phdr = (
Elf_Phdr *) (p + e->e_phoff);
1186 eph = phdr + e->e_phnum;
1187 for (; phdr < eph; phdr++) {
1197 memcpy(ms, phdr,
sizeof(
Elf_Phdr));
1200 DL_APPEND(ctx->
mphdrs, ms);
1206 printf(
" -- Original: %u\n", i);
1213 static unsigned int mk_phdrs(
ctx_t * ctx)
1244 static unsigned int write_phdrs(
ctx_t * ctx)
1246 unsigned int tmpm = 0;
1249 tmpm = lseek(ctx->
fdout, 0x00, SEEK_END);
1251 if ((tmpm % 8) == 0) {
1256 ftruncate(ctx->
fdout, tmpm);
1263 printf(
" -- Writting %u segment headers\n", ctx->
phnum);
1269 phdr->p_type = PT_PHDR;
1279 DL_FOREACH(ctx->
mphdrs, p) {
1286 phdr->p_type = PT_GNU_STACK;
1291 phdr->p_align = 0x10;
1301 static unsigned int write_phdrs_original(
ctx_t * ctx)
1303 unsigned int tmpm = 0;
1306 tmpm = lseek(ctx->
fdout, 0x00, SEEK_END);
1308 if ((tmpm % 8) == 0) {
1313 ftruncate(ctx->
fdout, tmpm);
1319 DL_FOREACH(ctx->
mphdrs, p) {
1335 ms = calloc(1,
sizeof(
msec_t));
1352 static int write_strtab_and_reloc(
ctx_t * ctx)
1355 unsigned int tmpm = 0;
1362 tmpm = lseek(ctx->
fdout, 0x00, SEEK_END);
1365 if ((tmpm % 8) == 0) {
1370 ftruncate(ctx->
fdout, tmpm);
1373 tmpm = lseek(ctx->
fdout, 0x00, SEEK_END);
1378 tmpm = lseek(ctx->
fdout, 0x00, SEEK_END);
1383 tmpm = lseek(ctx->
fdout, 0x00, SEEK_END);
1398 htype =
"R_X86_64_NONE";
1402 htype =
"R_X86_64_64";
1406 htype =
"R_X86_64_32";
1410 htype =
"R_X86_64_32S";
1414 htype =
"R_X86_64_PC32";
1417 case R_X86_64_GOT32:
1418 htype =
"R_X86_64_GOT32";
1421 case R_X86_64_PLT32:
1422 htype =
"R_X86_64_PLT32";
1426 htype =
"R_X86_64_COPY";
1429 case R_X86_64_GLOB_DAT:
1430 htype =
"R_X86_64_GLOB_DAT";
1433 case R_X86_64_JUMP_SLOT:
1434 htype =
"R_X86_64_JUMP_SLOT";
1437 case R_X86_64_RELATIVE:
1438 htype =
"R_X86_64_RELATIVE";
1441 case R_X86_64_GOTPCREL:
1442 htype =
"R_X86_64_GOTPCREL";
1446 htype =
"R_X86_64_16";
1450 htype =
"R_X86_64_PC16";
1454 htype =
"R_X86_64_8";
1458 htype =
"R_X86_64_PC8";
1462 htype =
"R_X86_64_NUM";
1480 htype =
"R_386_NONE";
1488 htype =
"R_386_PC32";
1492 htype =
"R_386_GOT32";
1496 htype =
"R_386_PLT32";
1500 htype =
"R_386_COPY";
1503 case R_386_GLOB_DAT:
1504 htype =
"R_386_GLOB_DAT";
1507 case R_386_JMP_SLOT:
1508 htype =
"R_386_JMP_SLOT";
1511 case R_386_RELATIVE:
1512 htype =
"R_386_RELATIVE";
1516 htype =
"R_386_GOTOFF";
1520 htype =
"R_386_GOTPC";
1524 htype =
"R_386_NUM";
1543 return "UNKNOWN_RELOCATION";
1559 unsigned int sindex = 0;
1561 unsigned int has_addend = 0;
1566 has_addend = (shdr->sh_type == SHT_RELA) ? 1 : 0;
1568 if ((shdr->sh_type == SHT_RELA)
1570 printf(
"warning: strange relocation size: %lu != %u in %s\n",
1575 if ((shdr->sh_type == SHT_REL)
1577 printf(
"warning: strange relocation size: %lu != %u in %s\n",
1582 if ((shdr->sh_type == SHT_RELA)
1585 (
"warning: strange relocation section size: %lu not a multiple of %u in %s\n",
1590 if ((shdr->sh_type == SHT_REL) && (shdr->sh_size %
entszfromname(
".rel.dyn"))) {
1592 (
"warning: strange relocation section size: %lu not a multiple of %u in %s\n",
1598 printf(
"\t%s\tsize:%u\t%lu relocations\n", s->
name, sz,
1599 sz / shdr->sh_entsize);
1602 for (i = 0; i < sz / shdr->sh_entsize; i++) {
1603 r = s->
data + i * shdr->sh_entsize;
1607 if (
ELF_R_TYPE(r->r_info) == R_X86_64_RELATIVE) {
1609 printf(
"reloc[%u] %016lx\t%lu\t%s\t%u\taddend:%lx\t\n", i, r->r_offset,
1610 r->r_info, htype, sindex, r->r_addend);
1611 printf(
" * Skipping relative relocation\n");
1625 printf(
"reloc[%u] %016lx\t%lu\t%s\t%u\taddend:%lu\t\n", i, r->r_offset,
1626 r->r_info, htype, sindex, r->r_addend);
1643 unsigned int i, sindex;
1654 printf(
"\n -- Fixing strtab and symtab with delta of %u\n\n",
deltastrtab);
1668 for (i = 0; i <
sizeof(
blnames) /
sizeof(
char *); i++) {
1671 && (strlen(sname) == strlen(
blnames[i]))
1674 printf(
" * name blacklisted: %s at index %u\n", sname, sindex);
1699 printf(
" -- Fixup .text\n\n");
1702 DL_FOREACH(ctx->
mshdrs, s) {
1703 if (!strncmp(s->
name,
".text", 6)) {
1707 (
" * .text section found, increasing size from 0x%lx to 0x%x (0x%lx)\n",
1710 s->
s_elf->sh_size = newsz;
1714 memset(s->
data + s->
len, 0x00, newsz - s->
len);
1729 static unsigned int parse_relocations(
ctx_t * ctx)
1734 printf(
"\n -- Parsing existing relocations\n\n");
1736 DL_FOREACH(ctx->
mshdrs, s) {
1737 if ((s->
s_elf) && (s->
s_elf->sh_type == SHT_RELA)) {
1738 parse_reloc(ctx, s);
1739 }
else if ((s->
s_elf) && (s->
s_elf->sh_type == SHT_REL)) {
1740 parse_reloc(ctx, s);
1779 unsigned int nameptr;
1798 static int create_section_symbols(
ctx_t * ctx)
1803 unsigned int nameptr;
1807 sym = calloc(1,
sizeof(
Elf_Sym));
1821 printf(
" -- Max section index after stripping: %u\n",
maxnewsec);
1834 newsname =
".rela.all";
1837 newsname =
".strtab";
1840 newsname =
".symtab";
1843 newsname =
".shstrtab";
1847 newsname =
".unknown";
1856 printf(
"%u %s\n", i, newsname);
1859 sym->st_name = nameptr;
1874 printf(
" -- Base sections symbol index: %u\n", 0);
1875 printf(
" -- Delta string table: %u\n",
deltastrtab);
1881 static unsigned int process_text(
ctx_t * ctx)
1903 static unsigned int write_shdrs(
ctx_t * ctx)
1906 unsigned int tmpm = 0;
1913 tmpm = lseek(ctx->
fdout, 0x00, SEEK_END);
1917 tmpm = lseek(ctx->
fdout, 0x00, SEEK_END);
1919 if ((tmpm % 8) == 0) {
1925 ftruncate(ctx->
fdout, tmpm);
1934 DL_FOREACH(ctx->
mshdrs, s) {
1956 shdr = calloc(1,
sizeof(
Elf_Shdr));
1959 shdr->sh_type = SHT_RELA;
1964 shdr->sh_link = ctx->
shnum + 3;
1966 shdr->sh_addralign = 8;
1985 shdr = calloc(1,
sizeof(
Elf_Shdr));
1988 shdr->sh_type = SHT_STRTAB;
1995 shdr->sh_addralign = 1;
2015 shdr = calloc(1,
sizeof(
Elf_Shdr));
2018 shdr->sh_type = SHT_SYMTAB;
2023 shdr->sh_link = ctx->
shnum + 2;
2024 shdr->sh_info = ctx->
shnum + 1;
2025 shdr->sh_addralign = 8;
2047 shdr = calloc(1,
sizeof(
Elf_Shdr));
2050 shdr->sh_type = SHT_STRTAB;
2054 shdr->sh_offset = lseek(ctx->
fdout, 0x00, SEEK_END) +
sizeof(
Elf_Shdr);
2058 shdr->sh_addralign = 1;
2059 shdr->sh_entsize = 0;
2072 printf(
" * section headers at:\t\t\t0x%x\n", ctx->
start_shdrs);
2073 printf(
" * section string table index:\t\t%u\n", ctx->
shnum);
2081 static int mk_ehdr(
ctx_t * ctx)
2096 memcpy(e->e_ident,
"\x7f\x45\x4c\x46\x02\x01\x01", 7);
2098 e->e_entry = bfd_get_start_address(ctx->
abfd);
2108 e->e_phnum = ctx->
phnum;
2110 e->e_shnum = ctx->
shnum + 5;
2111 e->e_shstrndx = ctx->
shnum + 4;
2124 e->e_type = ET_EXEC;
2138 e->e_type = ET_CORE;
2141 lseek(ctx->
fdout, 0x00, SEEK_SET);
2151 unsigned int nwrite = 0;
2158 if (nwrite != m->
len) {
2159 printf(
"write failed: %u != %lu %s\n", nwrite, m->
len, strerror(errno));
2165 static int rd_extended_text(
ctx_t * ctx)
2171 printf(
" -- Finding .text segment boundaries\n\n");
2173 printf(
" index\t\tname\t\t\trange\tsize\tpermissions\toffset\n");
2175 (
"--------------------------------------------------------------------\n");
2177 s = ctx->
abfd->sections;
2178 for (i = 0; i < ctx->
shnum; i++) {
2179 unsigned perms = parse_bfd_perm(s->flags);
2188 printf(
" [%2u] \t%s% *s\t%012llx-%012llx %llu\t%s\t%llu\n", i + 1,
2189 s->name, pad,
"", s->vma, s->vma + s->size, s->size,
"RX",
2197 if (s->filepos + s->size >
maxtext) {
2198 maxtext = s->filepos + s->size;
2205 printf(
" --> .text future boundaries: offset:%lu sz:%lu vma:%lx\n\n",
2211 static int rd_extended_data(
ctx_t * ctx)
2217 printf(
" -- Finding .data segment boundaries\n\n");
2219 printf(
" index\t\tname\t\t\trange\tsize\tpermissions\toffset\n");
2220 printf(
"--------------------------------------------------------------------\n");
2222 s = ctx->
abfd->sections;
2223 for (i = 0; i < ctx->
shnum; i++) {
2224 unsigned perms = parse_bfd_perm(s->flags);
2233 printf(
" [%2u] \t%s % *s\t%012llx-%012llx %llu\t%s\t%lu\n", i + 1,
2234 s->name, pad,
"", s->vma, s->vma + s->size, s->size,
"RW",
2242 if (s->filepos + s->size >
maxdata) {
2243 maxdata = s->filepos + s->size;
2250 printf(
" --> .data future boundaries: offset:%lu sz:%lu vma:%lx\n\n",
2257 static int extend_text(
ctx_t * ctx)
2263 printf(
" -- Extending .text\n\n");
2266 s = ctx->
abfd->sections;
2267 for (i = 0; i < ctx->
shnum; i++) {
2268 if (!strncmp(s->name,
".text", 5)) {
2275 printf(
" * extending section %s\n", s->name);
2276 printf(
" * new .text boundaries: offset:%lu sz:%lu vma:%lx\n\n",
2277 mintext, s->size, textvma);
2297 printf(
"\n -- Input binary sections\n\n");
2299 (
" name address range pages perms offset\n");
2301 (
" --------------------------------------------------------------------------------\n");
2304 s = ctx->
abfd->sections;
2305 for (i = 0; i < ctx->
shnum; i++) {
2306 perms = parse_bfd_perm(s->flags);
2331 printf(
" [%2u] %s% *s\t%012llx-%012llx %llu\t%s\t%lu\n", i + 1, s->name,
2332 pad,
"", s->vma, s->vma + s->size, s->size, hperms, s->filepos);
2350 for (j = 0; j < size; j += 16) {
2351 for (i = j; i < j + 16; i++) {
2353 printf(
"%02x ", data[i] & 255);
2359 for (i = j; i < j + 16; i++) {
2361 putchar(32 <= (data[i] & 127)
2362 && (data[i] & 127) < 127 ? data[i] & 127 :
'.');
2378 formatok = bfd_check_format(ctx->
abfd, bfd_object);
2379 ctx->
shnum = bfd_count_sections(ctx->
abfd);
2383 if ((!formatok) || (!ctx->
shnum)) {
2384 formatok = bfd_check_format(ctx->
abfd, bfd_core);
2385 ctx->
shnum = bfd_count_sections(ctx->
abfd);
2389 if ((!formatok) || (!ctx->
shnum)) {
2390 formatok = bfd_check_format(ctx->
abfd, bfd_archive);
2391 ctx->
shnum = bfd_count_sections(ctx->
abfd);
2395 if ((!formatok) || (!ctx->
shnum)) {
2396 printf(
" -- couldn't find a format for %s\n", ctx->
binname);
2412 if (stat(ctx->
binname, &sb) == -1) {
2420 newname = calloc(1, strlen(ctx->
binname) + 20);
2421 sprintf(newname,
"a.out");
2425 printf(
" -- Creating output file: %s\n\n", newname);
2428 fd = open(newname, O_RDWR | O_CREAT | O_TRUNC, 0666);
2430 printf(
" ERROR: open(%s) %s\n", newname, strerror(errno));
2434 ftruncate(fd, sb.st_size);
2437 p = calloc(1, sb.st_size);
2443 int fdin = open(ctx->
binname, O_RDONLY);
2444 read(fdin, p, sb.st_size);
2447 lseek(fd, 0x00, SEEK_SET);
2448 write(fd, p, sb.st_size);
2450 lseek(fd, 0x00, SEEK_SET);
2463 DL_FOREACH(ctx->
mshdrs, s) {
2464 write_section(ctx, s);
2478 printf(
" -- Architecture size: %u\n", ctx->
archsz);
2502 asection *s = m->
s_bfd;
2504 unsigned int dalign = 0;
2505 unsigned int dperms = 0;
2507 unsigned perms = parse_bfd_perm(s->flags);
2509 switch (perms & 0xf) {
2511 dperms = SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR;
2517 dperms = SHF_ALLOC | SHF_EXECINSTR;
2520 dperms = SHF_ALLOC | SHF_WRITE;
2533 shdr->sh_flags = dperms;
2534 shdr->sh_addr = s->vma;
2540 shdr->sh_offset = s->filepos;
2541 shdr->sh_size = s->size;
2542 shdr->sh_addralign = dalign ? dalign :
alignfromname(s->name);
2552 static int read_section(
ctx_t * ctx, asection * s)
2555 unsigned int n, nread = 0, nwrite = 0;
2557 unsigned int wantedsz = 0;
2560 fd = open(ctx->
binname, O_RDONLY);
2562 printf(
"error: open(%s) : %s\n", ctx->
binname, strerror(errno));
2566 lseek(fd, s->filepos, SEEK_SET);
2570 if (!strncmp(s->name,
".text", 5)) {
2573 buf = calloc(1, wantedsz);
2588 if (!strncmp(s->name,
".bss", 4)) {
2591 buf = realloc(buf, 0);
2595 nread = read(fd, buf, s->size);
2596 while ((nread != 0) && (n <= s->size)) {
2598 nread = read(fd, buf + n, s->size - n);
2601 if ((n != s->size) && (!strncmp(s->name,
".text", 5))) {
2604 }
else if (n != s->size) {
2605 printf(
"read failed: %u != %u\n", n, (
unsigned int) s->size);
2612 ms->
name = strdup(s->name);
2613 ms->
data = (
unsigned char *) buf;
2622 DL_APPEND(ctx->
mshdrs, ms);
2638 DL_COUNT(ctx->
mshdrs, ms, count);
2639 printf(
" -- %u elements\n", count);
2641 DL_FOREACH(ctx->
mshdrs, ms) {
2642 printf(
"%s %lu\n", ms->
name, ms->
len);
2654 asection *s = ctx->
abfd->sections;
2655 for (i = 0; i < ctx->
shnum; i++) {
2656 read_section(ctx, s);
2692 binary + shdr.sh_offset +
sizeof(
Elf_Sym),
2693 shdr.sh_size -
sizeof(
Elf_Sym));
2724 unsigned int sindex;
2750 if (s->r_offset == r->r_offset) {
2751 printf(
"warning: already have a relocation at %lu\n", r->r_offset);
2791 (
"recording blobal import variable %s in section: %s\t%s\tat:%lu\toff:%lu\n",
2793 r->r_offset - textvma);
2797 g->
sname = strdup(sname);
2801 rnew = calloc(1,
sizeof(
Elf_Rela));
2807 gimports = calloc(1,
sizeof(
gimport_t *));
2809 gimports = realloc(gimports,
sizeof(
gimport_t *) * (gimportslen + 1));
2811 gimports[gimportslen++] = g;
2827 if ((gimports[i]) && (gimports[i]->r) && (gimports[i]->r->r_offset == addr)) {
2848 rout = calloc(1,
sizeof(
Elf_Rela));
2857 printf(
"warning: no symbol table for relocation index %u\n", sindex);
2862 printf(
"warning: symbol index %u is out of bounds of symbol table\n",
2868 printf(
"warning: no string table for relocation index %u\n", sindex);
2876 if (!strncmp(sname,
"old_", 4)) {
2880 for (i = 0; i <
sizeof(
blnames) /
sizeof(
char *); i++) {
2881 if ((strlen(sname) == strlen(
blnames[i]))
2884 printf(
" * name blacklisted: %s\n", sname);
2891 printf(
" * adding relocation for: %s\n", sname);
2903 if (!strncmp(sec->
name,
".bss", 4)) {
2911 (
"warning: skipping unknown relocation for symbol: %s in section: %s\t%s\tat:%lu\toff:%lu\n",
2913 rout->r_offset - textvma);
2920 }
else if (rtype == R_X86_64_RELATIVE) {
2922 printf(
" * Not saving Relative relocation %lu %lu\n", rout->r_offset,
2929 printf(
" no section info for symbol: %s\n", sname);
2934 outtype = R_X86_64_64;
2947 printf(
"-->> %016lx\t%lu\t%s\t%u\taddend:%lu\t\n\n", rout->r_offset,
2948 rout->r_info, htype, sindex, rout->r_addend);
2956 #include <capstone/capstone.h>
2958 static void print_string_hex(
char *comment,
unsigned char *str,
size_t len)
2962 printf(
"%s", comment);
2963 for (c = str; c < str + len; c++) {
2964 printf(
"0x%02x ", *c & 0xff);
2972 static void print_insn_detail(
ctx_t * ctx, csh handle, cs_mode mode,
2979 if (ins->detail == NULL)
2982 x86 = &(ins->detail->x86);
2983 printf(
"\tAddress: %lu\n", ins->address);
2984 printf(
"\tInstruction Length: %u\n", ins->size);
2986 print_string_hex(
"\tPrefix:", x86->prefix, 4);
2988 print_string_hex(
"\tOpcode:", x86->opcode, 4);
2990 printf(
"\trex: 0x%x\n", x86->rex);
2992 printf(
"\taddr_size: %u\n", x86->addr_size);
2993 printf(
"\tmodrm: 0x%x\n", x86->modrm);
2994 printf(
"\tdisp: 0x%x\n", x86->disp);
2997 if ((mode & CS_MODE_16) == 0) {
2998 printf(
"\tsib: 0x%x\n", x86->sib);
2999 if (x86->sib_base != X86_REG_INVALID)
3000 printf(
"\t\tsib_base: %s\n", cs_reg_name(handle, x86->sib_base));
3001 if (x86->sib_index != X86_REG_INVALID)
3002 printf(
"\t\tsib_index: %s\n", cs_reg_name(handle, x86->sib_index));
3003 if (x86->sib_scale != 0)
3004 printf(
"\t\tsib_scale: %d\n", x86->sib_scale);
3007 if (x86->sse_cc != X86_SSE_CC_INVALID) {
3008 printf(
"\tsse_cc: %u\n", x86->sse_cc);
3011 if (x86->avx_cc != X86_AVX_CC_INVALID) {
3012 printf(
"\tavx_cc: %u\n", x86->avx_cc);
3016 printf(
"\tavx_sae: %u\n", x86->avx_sae);
3019 if (x86->avx_rm != X86_AVX_RM_INVALID) {
3020 printf(
"\tavx_rm: %u\n", x86->avx_rm);
3023 count = cs_op_count(handle, ins, X86_OP_IMM);
3025 printf(
"\timm_count: %u\n", count);
3026 for (i = 1; i < count + 1; i++) {
3027 int index = cs_op_index(handle, ins, X86_OP_IMM, i);
3028 printf(
"\t\timms[%u]: 0x%" PRIx64
"\n", i, x86->operands[index].imm);
3033 printf(
"\top_count: %u\n", x86->op_count);
3034 for (i = 0; i < x86->op_count; i++) {
3035 cs_x86_op *op = &(x86->operands[i]);
3037 switch ((
int) op->type) {
3039 printf(
"\t\toperands[%u].type: REG = %s\n", i,
3040 cs_reg_name(handle, op->reg));
3043 printf(
"\t\toperands[%u].type: IMM = 0x%" PRIx64
"\n", i, op->imm);
3046 printf(
"\t\toperands[%u].type: MEM\n", i);
3047 if (op->mem.segment != X86_REG_INVALID)
3048 printf(
"\t\t\toperands[%u].mem.segment: REG = %s\n", i,
3049 cs_reg_name(handle, op->mem.segment));
3050 if (op->mem.base != X86_REG_INVALID)
3051 printf(
"\t\t\toperands[%u].mem.base: REG = %s\n", i,
3052 cs_reg_name(handle, op->mem.base));
3053 if (op->mem.index != X86_REG_INVALID)
3054 printf(
"\t\t\toperands[%u].mem.index: REG = %s\n", i,
3055 cs_reg_name(handle, op->mem.index));
3056 if (op->mem.scale != 1)
3057 printf(
"\t\t\toperands[%u].mem.scale: %u\n", i, op->mem.scale);
3058 if (op->mem.disp != 0)
3059 printf(
"\t\t\toperands[%u].mem.disp: 0x%" PRIx64
"\n", i, op->mem.disp);
3066 if (op->avx_bcast != X86_AVX_BCAST_INVALID)
3067 printf(
"\t\toperands[%u].avx_bcast: %u\n", i, op->avx_bcast);
3070 if (op->avx_zero_opmask !=
false)
3071 printf(
"\t\toperands[%u].avx_zero_opmask: TRUE\n", i);
3073 printf(
"\t\toperands[%u].size: %u\n", i, op->size);
3079 static int create_text_data_reloc(
ctx_t * ctx, cs_insn * ins,
msec_t * m,
3080 unsigned int soff,
int rip_relative,
unsigned int argnum)
3082 unsigned int sindex = 0;
3083 unsigned int wheretowrite = 0;
3088 x86 = &(ins->detail->x86);
3090 wheretowrite = ins->size - 4;
3093 printf(
" --> transforming relocation from section: %s at ", m->
name);
3094 printf(
"0x%" PRIx64
":\t%s\t%s\tinslen:%u argoffset:%u\n", ins->address,
3095 ins->mnemonic, ins->op_str, ins->size, wheretowrite);
3100 if ((!strncmp(m->
name,
".bss", 4)) && (n == 2) && (!rip_relative)) {
3108 printf(
"** global imports match : %d\n", gimport);
3112 if ((gimport != -1) && (!rip_relative)) {
3115 printf(
" * known imported global : %s\n", gimports[gimport]->sname);
3124 sindex = gimports[gimport]->
sindex;
3132 r->r_info =
ELF_R_INFO(gimports[gimport]->sindex, R_X86_64_PC32);
3134 r->r_offset = ins->address - textvma + wheretowrite;
3138 memset(t->
data + r->r_offset, 0x00, 4);
3141 printf(
"%" PRIx64
"\t%s+%u\t\t\t(%s %s)\n", ins->address, m->
name, soff,
3142 ins->mnemonic, ins->op_str);
3143 printf(
"%012lx\t%012lx\t%s\t%012x\t%s+%u\n", r->r_offset, r->r_info,
3144 "R_X86_64_32", 0, m->
name, soff);
3151 }
else if ((gimport != -1) && (rip_relative)) {
3154 printf(
" * known imported global (rip relative) : %s\n",
3155 gimports[gimport]->sname);
3164 sindex = gimports[gimport]->
sindex;
3172 r->r_info =
ELF_R_INFO(gimports[gimport]->sindex, R_X86_64_PC32);
3174 r->r_offset = ins->address - textvma + wheretowrite;
3178 memset(t->
data + r->r_offset, 0x00, 4);
3181 printf(
"%012lx\t%012lx\t%s\t%012x\t%s+%ld\n", r->r_offset, r->r_info,
3182 "R_X86_64_32", 0, gimports[gimport]->
sname, r->r_addend);
3189 }
else if (sindex) {
3198 printf(
"new %s sindex:%u addent:%u, off:0x%lx\thasrel:%u\n",
3199 rip_relative ?
"rip relative local" :
"local", sindex, soff,
3200 ins->address - textvma + wheretowrite,
3220 for (wheretowrite = 0; wheretowrite <= ins->size; wheretowrite++) {
3221 unsigned int searchval = x86->operands[0].mem.disp;
3223 (t->
data + (ins->address - textvma + wheretowrite), &searchval,
3231 if (wheretowrite == ins->size) {
3232 printf(
"error: can't find patch location\n");
3239 cs_x86_op *op = &(x86->operands[argnum]);
3241 r->r_addend = ((op->mem.disp) + ins->address) - m->
s_bfd->vma;
3244 newtype = R_X86_64_PC32;
3251 r->r_offset = ins->address - textvma + wheretowrite;
3253 if ((argnum == 0) && (rip_relative)) {
3254 memset(t->
data + r->r_offset, 0x00, 4);
3256 }
else if (rip_relative) {
3257 memset(t->
data + r->r_offset, 0x00, 4);
3260 memcpy(t->
data + r->r_offset, &soff, 4);
3262 memset(t->
data + r->r_offset, 0x00, 4);
3280 printf(
"warning: unknown relocation section: %s at ", m->
name);
3281 printf(
"0x%" PRIx64
":\t%s\t%s\n", ins->address, ins->mnemonic,
3296 memset(buff, 0x00, 200);
3297 snprintf(buff, 200,
"internal_%08llx", addr);
3310 if (s->st_value == addr) {
3319 static void parse_text_data_reloc(
ctx_t * ctx, csh ud, cs_mode mode,
3326 if (ins->detail == NULL)
3329 x86 = &(ins->detail->x86);
3336 for (i = 0; i < x86->op_count; i++) {
3337 cs_x86_op *op = &(x86->operands[i]);
3339 switch ((
int) op->type) {
3345 create_text_data_reloc(ctx, ins, m, op->imm - m->
s_bfd->vma, 0, i);
3346 }
else if (i == 0) {
3348 if ((!strncmp(ins->mnemonic,
"call", 4))
3349 && (!strncmp(m->
name,
".text", 5))) {
3365 if ((m) && (m->
name) && (strncmp(m->
name,
".text", 5) || ctx->
has_relativerelocations) && (cs_reg_name(ud, op->mem.base)) && (!strncmp(cs_reg_name(ud, op->mem.base),
"rip", 3))) {
3367 create_text_data_reloc(ctx, ins, m, op->mem.disp + ins->address - m->
s_bfd->vma, 1, i);
3372 if (!strncmp(ins->mnemonic,
"nop", 3)) {
3376 if ((i == 0) && (m) && (m->
name)
3378 && (cs_reg_name(ud, op->mem.base))
3379 && (!strncmp(cs_reg_name(ud, op->mem.base),
"rip", 3))) {
3381 create_text_data_reloc(ctx, ins, m, op->mem.disp + ins->address - m->
s_bfd->vma, 1, i);
3396 unsigned long int addr)
3403 if (cs_open(CS_ARCH_X86,
CS_MODE, &handle)) {
3404 printf(
"error: Failed to initialize capstone library\n");
3408 cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
3410 count = cs_disasm(handle, data, datalen - 1, addr, 0, &insn);
3412 printf(
"error: Cannot disassemble code\n");
3417 printf(
" -- parsing %lu instructions from %lx (.text) for relocations\n\n",
3420 (
"\n Offset Info Type Sym. Value Sym. Name + Addend\n");
3423 for (j = 0; j < count; j++) {
3426 printf(
"0x%" PRIx64
":\t%s\t%s\n", insn[j].address, insn[j].mnemonic,
3428 print_insn_detail(ctx, handle,
CS_MODE, &insn[j]);
3431 parse_text_data_reloc(ctx, handle,
CS_MODE, &insn[j]);
3434 cs_free(insn, count);
3446 Elf_Scn *scn = NULL;
3455 printf(
" -- searching for .strtab/.symtab\n");
3458 elf_version(EV_CURRENT);
3460 fd = open(ctx->
binname, O_RDONLY);
3462 binary = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
3463 if (binary == MAP_FAILED) {
3468 elf = elf_begin(fd, ELF_C_READ, NULL);
3470 printf(
"error: not a valid ELF\n");
3474 if (elf_getshdrstrndx(elf, &shstrndx) != 0) {
3475 printf(
"error: in elf_getshdrstrndx\n");
3479 while ((scn = elf_nextscn(elf, scn)) != NULL) {
3480 gelf_getshdr(scn, &shdr);
3481 sname = elf_strptr(elf, shstrndx, shdr.sh_name);
3483 switch (shdr.sh_type) {
3486 printf(
" * symbol table at offset:%lu, sz:%lu\n", shdr.sh_offset,
3492 if (!strncmp(sname,
".dynstr", 7)) {
3494 printf(
" * dynamic string table at offset:%lu, sz:%lu\n",
3495 shdr.sh_offset, shdr.sh_size);
3500 printf(
" * string table at offset:%lu, sz:%lu\n", shdr.sh_offset,
3508 printf(
" * dynamic symbol table at offset:%lu, sz:%lu\n",
3509 shdr.sh_offset, shdr.sh_size);
3538 DL_FOREACH(ctx->
mshdrs, s) {
3539 if (!strncmp(s->
name, name, strlen(name))) {
3549 DL_DELETE(ctx->
mshdrs, rmsec);
3563 unsigned int allowed, i;
3566 printf(
"\n -- Stripping\n\n");
3570 DL_FOREACH_SAFE(ctx->
mshdrs, s, tmp) {
3581 printf(
" * %s\n", s->
name);
3599 char const *target = NULL;
3600 int is_pe64 = 0, is_pe32 = 0;
3620 rd_extended_text(ctx);
3621 rd_extended_data(ctx);
3636 create_section_symbols(ctx);
3649 target = bfd_get_target(ctx->
abfd);
3651 is_pe64 = (strcmp(target,
"pe-x86-64") == 0
3652 || strcmp(target,
"pei-x86-64") == 0);
3653 is_pe32 = (strcmp(target,
"pe-i386") == 0 || strcmp(target,
"pei-i386") == 0
3654 || strcmp(target,
"pe-arm-wince-little") == 0
3655 || strcmp(target,
"pei-arm-wince-little") == 0);
3657 if ((is_pe64) || (is_pe32)) {
3658 printf(
"target: %s\n", target);
3674 parse_relocations(ctx);
3727 write_strtab_and_reloc(ctx);
3743 write_phdrs_original(ctx);
3767 sprintf(cmd,
"cat /proc/%u/maps", getpid());
3781 ctx = calloc(1,
sizeof(
ctx_t));
3783 printf(
"error: calloc(): %s\n", strerror(errno));
3797 printf(
"Usage: %s [options] file\n", name);
3798 printf(
"\noptions:\n\n");
3799 printf(
" -o, --output <output file>\n");
3800 printf(
" -m, --march <architecture>\n");
3801 printf(
" -e, --entrypoint <0xaddress>\n");
3802 printf(
" -i, --interpreter <interpreter>\n");
3803 printf(
" -p, --poison <poison>\n");
3804 printf(
" -s, --shared\n");
3805 printf(
" -c, --compile\n");
3806 printf(
" -S, --static\n");
3807 printf(
" -x, --strip\n");
3808 printf(
" -X, --sstrip\n");
3809 printf(
" -E, --exec\n");
3810 printf(
" -C, --core\n");
3811 printf(
" -O, --original\n");
3812 printf(
" -D, --disasm\n");
3813 printf(
" -d, --debug\n");
3814 printf(
" -h, --help\n");
3815 printf(
" -v, --verbose\n");
3816 printf(
" -V, --version\n");
3823 printf(
"%s version:%s (%s %s)\n", WNAME, WVERSION, WTIME, WDATE);
3832 for (i = 0; i <
sizeof(wccarch) /
sizeof(archi_t); i++) {
3833 if (!strncmp(wccarch[i].name, name, strlen(name))) {
3835 printf(
" * architecture: %s\n", name);
3837 return wccarch[i].value;
3841 printf(
"error: architecture %s not supported\n", name);
3849 const char *short_opt =
"ho:i:scSEsxCvVXp:Odm:e:f:D";
3854 struct option long_opt[] = {
3855 {
"help", no_argument, NULL,
'h'},
3856 {
"march", required_argument, NULL,
'm'},
3857 {
"output", required_argument, NULL,
'o'},
3858 {
"shared", no_argument, NULL,
's'},
3859 {
"compile", no_argument, NULL,
'c'},
3860 {
"debug", no_argument, NULL,
'd'},
3861 {
"disasm", no_argument, NULL,
'D'},
3862 {
"static", no_argument, NULL,
'S'},
3863 {
"exec", no_argument, NULL,
'E'},
3864 {
"core", no_argument, NULL,
'C'},
3865 {
"strip", no_argument, NULL,
'x'},
3866 {
"sstrip", no_argument, NULL,
'X'},
3867 {
"entrypoint", required_argument, NULL,
'e'},
3868 {
"interpreter", required_argument, NULL,
'i'},
3869 {
"poison", required_argument, NULL,
'p'},
3870 {
"original", no_argument, NULL,
'O'},
3871 {
"verbose", no_argument, NULL,
'v'},
3872 {
"version", no_argument, NULL,
'V'},
3884 while ((c = getopt_long(argc, argv, short_opt, long_opt, NULL)) != -1) {
3918 ctx->
opt_flags = strtoul(optarg, NULL, 16);
3978 fprintf(stderr,
"Try `%s --help' for more information.\n", argv[0]);
3982 fprintf(stderr,
"%s: invalid option -- %c\n", argv[0], c);
3983 fprintf(stderr,
"Try `%s --help' for more information.\n", argv[0]);
3989 if (count >= argc - 1) {
3990 fprintf(stderr,
"error: No source binary found in arguments.\n");
3991 fprintf(stderr,
"Try `%s --help' for more information.\n", argv[0]);
3995 if (stat(argv[count + 1], &sb)) {
3996 printf(
"error: Could not open file %s : %s\n", argv[count + 1],
4004 printf(
" -- Analysing: %s\n", argv[count + 1]);
4007 ctx->
binname = strdup(argv[count + 1]);
unsigned int protect_perms(unsigned int perms)
void hexdump(unsigned char *data, size_t size)
int save_reloc(ctx_t *ctx, Elf_Rela *r, unsigned int sindex, int has_addend)
unsigned int append_strtab(char *str)
int flags_from_name(const char *name)
int save_dynsym(ctx_t *ctx, GElf_Shdr shdr, char *binary)
unsigned int max(unsigned int a, unsigned int b)
char * reloc_htype_x86_32(int thetype)
msec_t * section_from_index(ctx_t *ctx, unsigned int index)
int append_reloc(Elf_Rela *r)
unsigned long int mindata
msec_t * section_from_addr(ctx_t *ctx, unsigned long int addr)
char * reloc_htype_x86_64(int thetype)
struct symaddr * symaddrs
unsigned int globalsymindex
int open_target(ctx_t *ctx)
int load_binary(ctx_t *ctx)
unsigned int globalrelocoffset
unsigned int opt_original
int adjust_baseaddress(ctx_t *ctx)
int rd_symtab(ctx_t *ctx)
int sort_phdrs_premerge(ctx_t *ctx)
int copy_body(ctx_t *ctx)
int link_from_name(ctx_t *ctx, const char *name)
int patch_symbol_index(ctx_t *ctx, Elf_Sym *s)
int check_global_import(unsigned long int addr)
#define ELF64_ST_INFO(bind, type)
unsigned int secindex_from_name(ctx_t *ctx, const char *name)
int ctx_getopt(ctx_t *ctx, int argc, char **argv)
unsigned int base_address
unsigned int globalstrtableoffset
unsigned long int opt_entrypoint
int main(int argc, char **argv)
struct gimport_t gimport_t
char * sec_name_from_index_after_strip(ctx_t *ctx, unsigned int index)
unsigned long int maxdata
unsigned int alignfromname(const char *name)
msec_t * section_from_name(ctx_t *ctx, char *name)
unsigned int pflag_from_section(msec_t *ms)
void add_symaddr(ctx_t *ctx, const char *name, int addr, char symclass)
char * allowed_sections[]
unsigned long int textvma
unsigned long int maxtext
int save_dynstr(ctx_t *ctx, GElf_Shdr shdr, char *binary)
unsigned long int orig_sz
unsigned int libify(ctx_t *ctx)
int analyze_text(ctx_t *ctx, char *data, unsigned int datalen, unsigned long int addr)
int phdr_cmp_premerge(mseg_t *a, mseg_t *b)
unsigned int globalsymtableoffset
int fixup_strtab_and_symtab(ctx_t *ctx)
int info_from_name(ctx_t *ctx, const char *name)
unsigned long int datavma
int desired_arch(ctx_t *ctx, char *name)
int entszfromname(const char *name)
unsigned int opt_asmdebug
int strip_binary_reloc(ctx_t *ctx)
int fixup_symtab_section_index(ctx_t *ctx)
#define DEFAULT_STRNDX_SIZE
int sort_phdrs(ctx_t *ctx)
int add_extra_symbols(ctx_t *ctx)
int merge_phdrs(ctx_t *ctx)
unsigned int globalreloclen
unsigned int has_relativerelocations
unsigned int ptype_from_section(msec_t *ms)
int craft_section(ctx_t *ctx, msec_t *m)
int internal_function_store(ctx_t *ctx, unsigned long long int addr)
int create_phdrs(ctx_t *ctx)
#define EXTRA_CREATED_SECTIONS
mseg_t * alloc_phdr(msec_t *ms)
int print_bfd_sections(ctx_t *ctx)
unsigned long int mintext
char * reloc_htype(int thetype)
int rd_symbols(ctx_t *ctx)
unsigned int open_best(ctx_t *ctx)
msec_t * mk_section(void)
int rm_section(ctx_t *ctx, char *name)
int save_global_import(ctx_t *ctx, char *sname, msec_t *sec, Elf_Rela *r, unsigned int sindex)
unsigned int secindex_from_name_after_strip(ctx_t *ctx, const char *name)
int print_msec(ctx_t *ctx)
unsigned long int orig_text
unsigned int strndx_index
int typefromname(const char *name)
unsigned int globalstrtablen
int rd_sections(ctx_t *ctx)
int phdr_cmp(mseg_t *a, mseg_t *b)
unsigned int append_sym(Elf_Sym *s)
int fixup_text(ctx_t *ctx)