Changes

Jump to navigation Jump to search
2,404 bytes added ,  19:10, 24 July 2008
no edit summary
Line 58: Line 58:     
After this, it loads the ELF file, and then '''zeroes out the memory area where the ELF file resides'''. Then it goes back to ARM mode and vectors to 0xFFFF0000 (the entrypoint of the ARM / vector table). The entire BOOT2 code seems to be position-independent: it can be loaded at any address and will still work, as long as it doesn't overlap with the destination of the ELF load. The entire BOOT2 file cleartext is loaded and then the loader is called, so the loader can calculate the offset of the header simply by subtracting 0x10 from the PC at its entrypoint.
 
After this, it loads the ELF file, and then '''zeroes out the memory area where the ELF file resides'''. Then it goes back to ARM mode and vectors to 0xFFFF0000 (the entrypoint of the ARM / vector table). The entire BOOT2 code seems to be position-independent: it can be loaded at any address and will still work, as long as it doesn't overlap with the destination of the ELF load. The entire BOOT2 file cleartext is loaded and then the loader is called, so the loader can calculate the offset of the header simply by subtracting 0x10 from the PC at its entrypoint.
 +
 +
=== Extract ELF file ===
 +
The following program extracts the ELF from the ARM binary. Normal ELF tools can handle the generated output.
 +
 +
<source lang="c">
 +
#include <stdio.h>
 +
#include <stdint.h>
 +
#include <malloc.h>
 +
#include <netinet/in.h>
 +
 +
/** Header for Wii ARM binaries. */
 +
typedef struct {
 +
/** Size of this header. */
 +
uint32_t headerSize;
 +
/** Offset to ELF file. */
 +
uint32_t offset;
 +
/** Size of ELF file. */
 +
uint32_t size;
 +
/** Padded with zeroes. */
 +
uint32_t resevered;
 +
} arm_binary_header_t;
 +
 +
int main(int argc, char *argv[])
 +
{
 +
const char *inFilename;
 +
const char *outFilename;
 +
FILE *fin = NULL;
 +
FILE *fout = NULL;
 +
arm_binary_header_t header;
 +
char *buffer = NULL;
 +
 +
if (argc != 3) {
 +
fprintf(stderr, "%s: [Wii ARM Binary] [ELF output file]\n\n", argv[0]);
 +
fprintf(stderr, "Extract ELF from Wii ARM binary.\n");
 +
fprintf(stderr, "Error: Parameter wrong.\n");
 +
return -1;
 +
}
 +
inFilename = argv[1];
 +
outFilename = argv[2];
 +
 +
fin = fopen(inFilename, "rb");
 +
if (fin == NULL) {
 +
fprintf(stderr, "Error: Failed to open input file \"%s\".\n", inFilename);
 +
return -2;
 +
}
 +
if (fread(&header, sizeof(header), 1, fin) != 1) {
 +
fclose(fin);
 +
fprintf(stderr, "Error: Input file \"%s\" is too small.\n", inFilename);
 +
return -3;
 +
}
 +
header.headerSize = ntohl(header.headerSize);
 +
header.offset = ntohl(header.offset);
 +
header.size = ntohl(header.size);
 +
 +
if (header.headerSize != sizeof(arm_binary_header_t)) {
 +
fclose(fin);
 +
fprintf(stderr, "Error: Input file \"%s\" is not a Wii ARM binary.\n", inFilename);
 +
return -4;
 +
}
 +
if (fseek(fin, header.offset, SEEK_CUR) != 0) {
 +
fclose(fin);
 +
fprintf(stderr, "Error: Input file \"%s\" is too small (seek to %d failed).\n", inFilename, header.offset);
 +
return -5;
 +
}
 +
buffer = malloc(header.size);
 +
if (buffer == NULL) {
 +
fclose(fin);
 +
fprintf(stderr, "Error: Out of memory.\n");
 +
return -6;
 +
}
 +
if (fread(buffer, header.size, 1, fin) != 1) {
 +
fclose(fin);
 +
fprintf(stderr, "Error: Input file \"%s\" is too small.\n", inFilename);
 +
return -7;
 +
}
 +
fclose(fin);
 +
 +
fout = fopen(outFilename, "wb");
 +
if (fout == NULL) {
 +
fclose(fin);
 +
fprintf(stderr, "Error: Failed to open output file \"%s\".\n", outFilename);
 +
return -8;
 +
}
 +
if (fwrite(buffer, header.size, 1, fout) != 1) {
 +
fclose(fin);
 +
fprintf(stderr, "Error: Output file \"%s\" write error (disc full?).\n", outFilename);
 +
return -9;
 +
}
 +
fclose(fout);
 +
return 0;
 +
}
 +
</source>
40

edits

Navigation menu