From 428a51c3b7881622f0c10ebd08800b97199a32fb Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 29 Jul 2018 12:04:23 -0700 Subject: [PATCH] elf2nso/elf2nro: Parse Build ID into header. --- src/elf2nro.c | 19 +++++++++++++++++++ src/elf2nso.c | 19 +++++++++++++++++++ src/elf_common.h | 1 + 3 files changed, 39 insertions(+) diff --git a/src/elf2nro.c b/src/elf2nro.c index 271b6ed..2e04ef7 100644 --- a/src/elf2nro.c +++ b/src/elf2nro.c @@ -184,6 +184,25 @@ int main(int argc, char* argv[]) { file_off += nro_hdr.Segments[i].Size; file_off = (file_off + 0xFFF) & ~0xFFF; } + + /* Iterate over sections to find build id. */ + size_t cur_sect_hdr_ofs = hdr->e_shoff; + for (unsigned int i = 0; i < hdr->e_shnum; i++) { + Elf64_Shdr *cur_shdr = (Elf64_Shdr *)(elf + cur_sect_hdr_ofs); + if (cur_shdr->sh_type == SHT_NOTE) { + Elf64_Nhdr *note_hdr = (Elf64_Nhdr *)(elf + cur_shdr->sh_offset); + u8 *note_name = (u8 *)((uintptr_t)note_hdr + sizeof(Elf64_Nhdr)); + u8 *note_desc = note_name + note_hdr->n_namesz; + if (note_hdr->n_type == NT_GNU_BUILD_ID && note_hdr->n_namesz == 4 && memcmp(note_name, "GNU\x00", 4) == 0) { + size_t build_id_size = note_hdr->n_descsz; + if (build_id_size > 0x20) { + build_id_size = 0x20; + } + memcpy(nro_hdr.BuildId, note_desc, build_id_size); + } + } + cur_sect_hdr_ofs += hdr->e_shentsize; + } FILE* out = fopen(argv[2], "wb"); diff --git a/src/elf2nso.c b/src/elf2nso.c index bf2ce3a..22c3444 100644 --- a/src/elf2nso.c +++ b/src/elf2nso.c @@ -157,6 +157,25 @@ int main(int argc, char* argv[]) { nso_hdr.CompSz[i] = comp_sz[i]; file_off += comp_sz[i]; } + + /* Iterate over sections to find build id. */ + size_t cur_sect_hdr_ofs = hdr->e_shoff; + for (unsigned int i = 0; i < hdr->e_shnum; i++) { + Elf64_Shdr *cur_shdr = (Elf64_Shdr *)(elf + cur_sect_hdr_ofs); + if (cur_shdr->sh_type == SHT_NOTE) { + Elf64_Nhdr *note_hdr = (Elf64_Nhdr *)(elf + cur_shdr->sh_offset); + u8 *note_name = (u8 *)((uintptr_t)note_hdr + sizeof(Elf64_Nhdr)); + u8 *note_desc = note_name + note_hdr->n_namesz; + if (note_hdr->n_type == NT_GNU_BUILD_ID && note_hdr->n_namesz == 4 && memcmp(note_name, "GNU\x00", 4) == 0) { + size_t build_id_size = note_hdr->n_descsz; + if (build_id_size > 0x20) { + build_id_size = 0x20; + } + memcpy(nso_hdr.BuildId, note_desc, build_id_size); + } + } + cur_sect_hdr_ofs += hdr->e_shentsize; + } FILE* out = fopen(argv[2], "wb"); diff --git a/src/elf_common.h b/src/elf_common.h index 2e45407..d2dda43 100644 --- a/src/elf_common.h +++ b/src/elf_common.h @@ -995,5 +995,6 @@ typedef struct { #define R_X86_64_TPOFF32 23 /* Offset in static TLS block */ #define R_X86_64_IRELATIVE 37 +#define NT_GNU_BUILD_ID 3 /* Note type for .note.gnu.build-id */ #endif /* !_SYS_ELF_COMMON_H_ */