summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/sbinfo/elf.c74
-rw-r--r--utils/sbinfo/elf.h39
-rw-r--r--utils/sbinfo/sbinfo.c59
3 files changed, 129 insertions, 43 deletions
diff --git a/utils/sbinfo/elf.c b/utils/sbinfo/elf.c
index 0fe6792..6c5ed2e 100644
--- a/utils/sbinfo/elf.c
+++ b/utils/sbinfo/elf.c
@@ -57,13 +57,16 @@ void elf_add_fill_section(struct elf_params_t *params,
void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user)
{
Elf32_Ehdr ehdr;
- uint32_t phoff = sizeof(Elf32_Ehdr);
- uint32_t phentsize = sizeof(Elf32_Phdr);
uint32_t phnum = 0;
- uint32_t shstrndx = SHN_UNDEF;
struct elf_section_t *sec = params->first_section;
uint32_t offset = 0;
Elf32_Phdr phdr;
+ Elf32_Shdr shdr;
+ memset(&ehdr, 0, EI_NIDENT);
+
+ uint32_t bss_strtbl = 0;
+ uint32_t text_strtbl = bss_strtbl + strlen(".bss") + 1;
+ uint32_t strtbl_size = text_strtbl + strlen(".text") + 1;
while(sec)
{
@@ -77,7 +80,8 @@ void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user)
sec = sec->next;
}
- memset(&ehdr, 0, EI_NIDENT);
+ uint32_t strtbl_offset = offset;
+
ehdr.e_ident[EI_MAG0] = ELFMAG0;
ehdr.e_ident[EI_MAG1] = ELFMAG1;
ehdr.e_ident[EI_MAG2] = ELFMAG2;
@@ -91,25 +95,28 @@ void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user)
ehdr.e_machine = EM_ARM;
ehdr.e_version = EV_CURRENT;
ehdr.e_entry = params->start_addr;
- ehdr.e_phoff = phoff;
- ehdr.e_shoff = 0;
ehdr.e_flags = 0;
if(params->has_start_addr)
ehdr.e_flags |= EF_ARM_HASENTRY;
ehdr.e_ehsize = sizeof ehdr;
- ehdr.e_phentsize = phentsize;
+ ehdr.e_phentsize = sizeof phdr;
ehdr.e_phnum = phnum;
- ehdr.e_shentsize = 0;
- ehdr.e_shnum = 0;
- ehdr.e_shstrndx = shstrndx;
+ ehdr.e_shentsize = sizeof shdr;
+ ehdr.e_shnum = phnum + 1;
+ ehdr.e_shstrndx = ehdr.e_shnum - 1;
+ ehdr.e_phoff = ehdr.e_ehsize;
+ ehdr.e_shoff = ehdr.e_ehsize + ehdr.e_phnum * ehdr.e_phentsize;
write(user, 0, &ehdr, sizeof ehdr);
+ uint32_t data_offset = ehdr.e_ehsize + ehdr.e_phnum * ehdr.e_phentsize +
+ ehdr.e_shnum * ehdr.e_shentsize;
+
sec = params->first_section;
- offset = phoff;
+ offset = ehdr.e_phoff;
while(sec)
{
- sec->offset += phoff + phnum * phentsize;
+ sec->offset += data_offset;
phdr.p_type = PT_LOAD;
if(sec->type == EST_LOAD)
@@ -133,12 +140,55 @@ void elf_output(struct elf_params_t *params, elf_write_fn_t write, void *user)
}
sec = params->first_section;
+ offset = ehdr.e_shoff;
+ while(sec)
+ {
+ shdr.sh_name = text_strtbl;
+ if(sec->type == EST_LOAD)
+ shdr.sh_type = SHT_PROGBITS;
+ else
+ shdr.sh_type = SHT_NOBITS;
+ shdr.sh_flags = SHF_ALLOC | SHF_EXECINSTR;
+ shdr.sh_addr = sec->addr;
+ shdr.sh_offset = sec->offset;
+ shdr.sh_size = sec->size;
+ shdr.sh_link = SHN_UNDEF;
+ shdr.sh_info = 0;
+ shdr.sh_addralign = 1;
+ shdr.sh_entsize = 0;
+
+ write(user, offset, &shdr, sizeof shdr);
+
+ offset += sizeof(Elf32_Shdr);
+ sec = sec->next;
+ }
+
+ {
+ shdr.sh_name = bss_strtbl;
+ shdr.sh_type = SHT_STRTAB;
+ shdr.sh_flags = 0;
+ shdr.sh_addr = 0;
+ shdr.sh_offset = strtbl_offset + data_offset;
+ shdr.sh_size = strtbl_size;
+ shdr.sh_link = SHN_UNDEF;
+ shdr.sh_info = 0;
+ shdr.sh_addralign = 1;
+ shdr.sh_entsize = 0;
+
+ write(user, offset, &shdr, sizeof shdr);
+
+ offset += sizeof(Elf32_Shdr);
+ }
+
+ sec = params->first_section;
while(sec)
{
if(sec->type == EST_LOAD)
write(user, sec->offset, sec->section, sec->size);
sec = sec->next;
}
+
+ write(user, strtbl_offset + data_offset, ".bss\0.text\0", strtbl_size);
}
bool elf_is_empty(struct elf_params_t *params)
diff --git a/utils/sbinfo/elf.h b/utils/sbinfo/elf.h
index eb99038..d2bf210 100644
--- a/utils/sbinfo/elf.h
+++ b/utils/sbinfo/elf.h
@@ -80,6 +80,45 @@ typedef struct
typedef struct
{
+ Elf32_Word sh_name; /* Section name (string tbl index) */
+ Elf32_Word sh_type; /* Section type */
+ Elf32_Word sh_flags; /* Section flags */
+ Elf32_Addr sh_addr; /* Section virtual addr at execution */
+ Elf32_Off sh_offset; /* Section file offset */
+ Elf32_Word sh_size; /* Section size in bytes */
+ Elf32_Word sh_link; /* Link to another section */
+ Elf32_Word sh_info; /* Additional section information */
+ Elf32_Word sh_addralign; /* Section alignment */
+ Elf32_Word sh_entsize; /* Entry size if section holds table */
+}Elf32_Shdr;
+
+#define SHT_NULL 0 /* Section header table entry unused */
+#define SHT_PROGBITS 1 /* Program data */
+#define SHT_SYMTAB 2 /* Symbol table */
+#define SHT_STRTAB 3 /* String table */
+#define SHT_RELA 4 /* Relocation entries with addends */
+#define SHT_HASH 5 /* Symbol hash table */
+#define SHT_DYNAMIC 6 /* Dynamic linking information */
+#define SHT_NOTE 7 /* Notes */
+#define SHT_NOBITS 8 /* Program space with no data (bss) */
+#define SHT_REL 9 /* Relocation entries, no addends */
+#define SHT_SHLIB 10 /* Reserved */
+#define SHT_DYNSYM 11 /* Dynamic linker symbol table */
+#define SHT_INIT_ARRAY 14 /* Array of constructors */
+#define SHT_FINI_ARRAY 15 /* Array of destructors */
+#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
+#define SHT_GROUP 17 /* Section group */
+#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
+#define SHT_NUM 19 /* Number of defined types. */
+
+#define SHF_WRITE (1 << 0) /* Writable */
+#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */
+#define SHF_EXECINSTR (1 << 2) /* Executable */
+#define SHF_MERGE (1 << 4) /* Might be merged */
+#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */
+
+typedef struct
+{
Elf32_Word p_type; /* Segment type */
Elf32_Off p_offset; /* Segment file offset */
Elf32_Addr p_vaddr; /* Segment virtual address */
diff --git a/utils/sbinfo/sbinfo.c b/utils/sbinfo/sbinfo.c
index d065fc9..710c481 100644
--- a/utils/sbinfo/sbinfo.c
+++ b/utils/sbinfo/sbinfo.c
@@ -63,8 +63,8 @@ char BLUE[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '4', 0x6d, '\0' };
/* byte swapping */
#define get32le(a) ((uint32_t) \
- ( buf[a+3] << 24 | buf[a+2] << 16 | buf[a+1] << 8 | buf[a] ))
-#define get16le(a) ((uint16_t)( buf[a+1] << 8 | buf[a] ))
+ ( g_buf[a+3] << 24 | g_buf[a+2] << 16 | g_buf[a+1] << 8 | g_buf[a] ))
+#define get16le(a) ((uint16_t)( g_buf[a+1] << 8 | g_buf[a] ))
/* all blocks are sized as a multiple of 0x1ff */
#define PAD_TO_BOUNDARY(x) (((x) + 0x1ff) & ~0x1ff)
@@ -74,8 +74,8 @@ char BLUE[] = { 0x1b, 0x5b, 0x31, 0x3b, '3', '4', 0x6d, '\0' };
/* globals */
-size_t sz; /* file size */
-uint8_t *buf; /* file content */
+size_t g_sz; /* file size */
+uint8_t *g_buf; /* file content */
#define PREFIX_SIZE 128
char out_prefix[PREFIX_SIZE];
const char *key_file;
@@ -129,25 +129,23 @@ void *xmalloc(size_t s) /* malloc helper, used in elf.c */
static char getchr(int offset)
{
char c;
- c = buf[offset];
+ c = g_buf[offset];
return isprint(c) ? c : '_';
}
static void getstrle(char string[], int offset)
{
int i;
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < 4; i++)
string[i] = getchr(offset + 3 - i);
- }
string[4] = 0;
}
static void getstrbe(char string[], int offset)
{
int i;
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < 4; i++)
string[i] = getchr(offset + i);
- }
string[4] = 0;
}
@@ -155,9 +153,8 @@ static void printhex(int offset, int len)
{
int i;
- for (i = 0; i < len; i++) {
- printf("%02X ", buf[offset + i]);
- }
+ for (i = 0; i < len; i++)
+ printf("%02X ", g_buf[offset + i]);
printf("\n");
}
@@ -222,7 +219,7 @@ static key_array_t read_keys(int num_keys)
bugp("key file stat() failed");
size = st.st_size;
char *buf = xmalloc(size);
- if(read(fd,buf,sz)!=(ssize_t)size)
+ if(read(fd, buf, size) != (ssize_t)size)
bugp("reading key file");
close(fd);
@@ -417,13 +414,13 @@ static void extract(unsigned long filesize)
printf("Basic info:\n");
color(GREEN);
printf("\tHeader SHA-1: ");
- byte *hdr_sha1 = &buf[0];
+ byte *hdr_sha1 = &g_buf[0];
color(YELLOW);
print_sha1(hdr_sha1);
/* Check SHA1 sum */
byte computed_sha1[20];
sha_1_init(&sha_1_params);
- sha_1_update(&sha_1_params, &buf[0x14], 0x4C);
+ sha_1_update(&sha_1_params, &g_buf[0x14], 0x4C);
sha_1_finish(&sha_1_params);
sha_1_output(&sha_1_params, computed_sha1);
color(RED);
@@ -480,7 +477,7 @@ static void extract(unsigned long filesize)
if(num_enc > 0)
{
keys = read_keys(num_enc);
- color(BLUE),
+ color(BLUE);
printf("Encryption data\n");
for(int i = 0; i < num_enc; i++)
{
@@ -492,14 +489,14 @@ static void extract(unsigned long filesize)
printf("\t\tCBC-MAC of headers: ");
/* copy the cbc mac */
byte hdr_cbc_mac[16];
- memcpy(hdr_cbc_mac, &buf[0x60 + 16 * num_chunks + 32 * i], 16);
+ memcpy(hdr_cbc_mac, &g_buf[0x60 + 16 * num_chunks + 32 * i], 16);
color(YELLOW);
print_key(hdr_cbc_mac);
/* check it */
byte computed_cbc_mac[16];
byte zero[16];
memset(zero, 0, 16);
- cbc_mac(buf, NULL, 6 + num_chunks, keys[i], zero, &computed_cbc_mac, 1);
+ cbc_mac(g_buf, NULL, 6 + num_chunks, keys[i], zero, &computed_cbc_mac, 1);
color(RED);
if(memcmp(hdr_cbc_mac, computed_cbc_mac, 16) == 0)
printf(" Ok\n");
@@ -509,7 +506,7 @@ static void extract(unsigned long filesize)
printf("\t\tEncrypted key : ");
byte (*encrypted_key)[16];
- encrypted_key = (key_array_t)&buf[0x60 + 16 * num_chunks + 32 * i + 16];
+ encrypted_key = (key_array_t)&g_buf[0x60 + 16 * num_chunks + 32 * i + 16];
color(YELLOW);
print_key(*encrypted_key);
printf("\n");
@@ -517,7 +514,7 @@ static void extract(unsigned long filesize)
/* decrypt */
byte decrypted_key[16];
byte iv[16];
- memcpy(iv, buf, 16); /* uses the first 16-bytes of SHA-1 sig as IV */
+ memcpy(iv, g_buf, 16); /* uses the first 16-bytes of SHA-1 sig as IV */
cbc_mac(*encrypted_key, decrypted_key, 1, keys[i], iv, NULL, 0);
printf("\t\tDecrypted key : ");
color(YELLOW);
@@ -571,9 +568,9 @@ static void extract(unsigned long filesize)
/* save it */
byte *sec = xmalloc(size);
if(encrypted)
- cbc_mac(buf + pos, sec, size / 16, real_key, buf, NULL, 0);
+ cbc_mac(g_buf + pos, sec, size / 16, real_key, g_buf, NULL, 0);
else
- memcpy(sec, buf + pos, size);
+ memcpy(sec, g_buf + pos, size);
extract_section(data_sec, name, sec, size, "\t\t\t");
free(sec);
@@ -590,16 +587,16 @@ static void extract(unsigned long filesize)
printf("\t\t");
printhex(filesize - 16, 16);
/* decrypt it */
- byte *encrypted_block = &buf[filesize - 32];
+ byte *encrypted_block = &g_buf[filesize - 32];
byte decrypted_block[32];
- cbc_mac(encrypted_block, decrypted_block, 2, real_key, buf, NULL, 0);
+ cbc_mac(encrypted_block, decrypted_block, 2, real_key, g_buf, NULL, 0);
color(GREEN);
printf("\tDecrypted SHA-1:\n\t\t");
color(YELLOW);
print_sha1(decrypted_block);
/* check it */
sha_1_init(&sha_1_params);
- sha_1_update(&sha_1_params, buf, filesize - 32);
+ sha_1_update(&sha_1_params, g_buf, filesize - 32);
sha_1_finish(&sha_1_params);
sha_1_output(&sha_1_params, computed_sha1);
color(RED);
@@ -621,17 +618,17 @@ int main(int argc, const char **argv)
else
strcpy(out_prefix, "");
- if( (fd = open(argv[1],O_RDONLY)) == -1 )
+ if( (fd = open(argv[1], O_RDONLY)) == -1 )
bugp("opening firmware failed");
key_file = argv[2];
- if(fstat(fd,&st) == -1)
+ if(fstat(fd, &st) == -1)
bugp("firmware stat() failed");
- sz = st.st_size;
+ g_sz = st.st_size;
- buf=xmalloc(sz);
- if(read(fd,buf,sz)!=(ssize_t)sz) /* load the whole file into memory */
+ g_buf = xmalloc(g_sz);
+ if(read(fd, g_buf, g_sz) != (ssize_t)g_sz) /* load the whole file into memory */
bugp("reading firmware");
close(fd);
@@ -641,6 +638,6 @@ int main(int argc, const char **argv)
color(OFF);
- free(buf);
+ free(g_buf);
return 0;
}