mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 12:32:40 +02:00
elf2nso: Ignore non-PT_LOAD program headers
This commit is contained in:
parent
1e0d868b0c
commit
7cc1442588
@ -62,8 +62,8 @@ uint8_t* ReadEntireFile(const char* fn, size_t* len_out) {
|
|||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
printf("%s <elf-file> <nso-file>\n", argv[0]);
|
fprintf(stderr, "%s <elf-file> <nso-file>\n", argv[0]);
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NsoHeader nso_hdr;
|
NsoHeader nso_hdr;
|
||||||
@ -72,48 +72,57 @@ int main(int argc, char* argv[]) {
|
|||||||
nso_hdr.Unk3 = 0x3f;
|
nso_hdr.Unk3 = 0x3f;
|
||||||
|
|
||||||
if (sizeof(NsoHeader) != 0x100) {
|
if (sizeof(NsoHeader) != 0x100) {
|
||||||
printf("Bad compile environment!\n");
|
fprintf(stderr, "Bad compile environment!\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t elf_len;
|
size_t elf_len;
|
||||||
uint8_t* elf = ReadEntireFile(argv[1], &elf_len);
|
uint8_t* elf = ReadEntireFile(argv[1], &elf_len);
|
||||||
if (elf == NULL) {
|
if (elf == NULL) {
|
||||||
printf("Failed to open input!\n");
|
fprintf(stderr, "Failed to open input!\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elf_len < sizeof(Elf64_Ehdr)) {
|
if (elf_len < sizeof(Elf64_Ehdr)) {
|
||||||
printf("Input file doesn't fit ELF header!\n");
|
fprintf(stderr, "Input file doesn't fit ELF header!\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Elf64_Ehdr* hdr = (Elf64_Ehdr*) elf;
|
Elf64_Ehdr* hdr = (Elf64_Ehdr*) elf;
|
||||||
if (hdr->e_machine != EM_AARCH64) {
|
if (hdr->e_machine != EM_AARCH64) {
|
||||||
printf("Invalid ELF: expected AArch64!\n");
|
fprintf(stderr, "Invalid ELF: expected AArch64!\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Elf64_Off ph_end = hdr->e_phoff + 3 * sizeof(Elf64_Phdr);
|
Elf64_Off ph_end = hdr->e_phoff + hdr->e_phnum * sizeof(Elf64_Phdr);
|
||||||
|
|
||||||
if (ph_end < hdr->e_phoff || ph_end > elf_len) {
|
if (ph_end < hdr->e_phoff || ph_end > elf_len) {
|
||||||
printf("Invalid ELF: phdrs outside file!\n");
|
fprintf(stderr, "Invalid ELF: phdrs outside file!\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdr->e_phnum != 3) {
|
Elf64_Phdr* phdrs = (Elf64_Phdr*) &elf[hdr->e_phoff];
|
||||||
printf("Invalid ELF: expected 3 phdrs!\n");
|
size_t i, j = 0;
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Elf64_Phdr* phdr = (Elf64_Phdr*) &elf[hdr->e_phoff];
|
|
||||||
size_t i;
|
|
||||||
size_t file_off = sizeof(NsoHeader);
|
size_t file_off = sizeof(NsoHeader);
|
||||||
|
|
||||||
uint8_t* comp_buf[3];
|
uint8_t* comp_buf[3];
|
||||||
int comp_sz[3];
|
int comp_sz[3];
|
||||||
|
|
||||||
for (i=0; i<3; i++, phdr++) {
|
for (i=0; i<3; i++) {
|
||||||
|
Elf64_Phdr* phdr = NULL;
|
||||||
|
while (j < hdr->e_phnum) {
|
||||||
|
Elf64_Phdr* cur = &phdrs[j++];
|
||||||
|
if (cur->p_type == PT_LOAD) {
|
||||||
|
phdr = cur;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phdr == NULL) {
|
||||||
|
fprintf(stderr, "Invalid ELF: expected 3 loadable phdrs!\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
nso_hdr.Segments[i].FileOff = file_off;
|
nso_hdr.Segments[i].FileOff = file_off;
|
||||||
nso_hdr.Segments[i].DstOff = phdr->p_vaddr;
|
nso_hdr.Segments[i].DstOff = phdr->p_vaddr;
|
||||||
nso_hdr.Segments[i].DecompSz = phdr->p_filesz;
|
nso_hdr.Segments[i].DecompSz = phdr->p_filesz;
|
||||||
@ -133,16 +142,16 @@ int main(int argc, char* argv[]) {
|
|||||||
comp_buf[i] = malloc(comp_max);
|
comp_buf[i] = malloc(comp_max);
|
||||||
|
|
||||||
if (comp_buf[i] == NULL) {
|
if (comp_buf[i] == NULL) {
|
||||||
printf("Compressing: Out of memory!\n");
|
fprintf(stderr, "Compressing: Out of memory!\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO check p_offset
|
// TODO check p_offset
|
||||||
comp_sz[i] = LZ4_compress_default(&elf[phdr->p_offset], comp_buf[i], phdr->p_filesz, comp_max);
|
comp_sz[i] = LZ4_compress_default(&elf[phdr->p_offset], comp_buf[i], phdr->p_filesz, comp_max);
|
||||||
|
|
||||||
if (comp_sz[i] < 0) {
|
if (comp_sz[i] < 0) {
|
||||||
printf("Failed to compress!\n");
|
fprintf(stderr, "Failed to compress!\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nso_hdr.CompSz[i] = comp_sz[i];
|
nso_hdr.CompSz[i] = comp_sz[i];
|
||||||
@ -152,8 +161,8 @@ int main(int argc, char* argv[]) {
|
|||||||
FILE* out = fopen(argv[2], "wb");
|
FILE* out = fopen(argv[2], "wb");
|
||||||
|
|
||||||
if (out == NULL) {
|
if (out == NULL) {
|
||||||
printf("Failed to open output file!\n");
|
fprintf(stderr, "Failed to open output file!\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO check retvals
|
// TODO check retvals
|
||||||
@ -162,5 +171,5 @@ int main(int argc, char* argv[]) {
|
|||||||
for (i=0; i<3; i++)
|
for (i=0; i<3; i++)
|
||||||
fwrite(comp_buf[i], comp_sz[i], 1, out);
|
fwrite(comp_buf[i], comp_sz[i], 1, out);
|
||||||
|
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user