mirror of
https://github.com/fail0verflow/hbc.git
synced 2024-11-25 19:16:54 +01:00
110 lines
2.1 KiB
C
110 lines
2.1 KiB
C
#include "common.h"
|
|
|
|
#include "string.h"
|
|
#include "elf.h"
|
|
|
|
#include "LzmaDec.h"
|
|
|
|
extern const u8 __self_start[], __self_end[];
|
|
extern const u8 __payload[];
|
|
|
|
extern void _plunge(u32 entry);
|
|
|
|
typedef struct {
|
|
u8 * const data;
|
|
const u32 len_in;
|
|
const u32 len_out;
|
|
const u8 props[LZMA_PROPS_SIZE];
|
|
} __attribute__((packed)) _payload;
|
|
|
|
const _payload * const payload = (void *) __payload;
|
|
|
|
u8 * const code_buffer = (u8 *) 0x90100000;
|
|
|
|
static void *lz_malloc(void *p, size_t size) {
|
|
(void) p;
|
|
(void) size;
|
|
printf("lz_malloc %u\n", size);
|
|
return (void *) 0x90081000;
|
|
}
|
|
|
|
static void lz_free(void *p, void *address) {
|
|
(void) p;
|
|
(void) address;
|
|
printf("lz_free %p\n", address);
|
|
}
|
|
|
|
static const ISzAlloc lz_alloc = { lz_malloc, lz_free };
|
|
|
|
static inline __attribute__((always_inline)) int decode(void) {
|
|
SizeT len_in;
|
|
SizeT len_out;
|
|
ELzmaStatus status;
|
|
SRes res;
|
|
|
|
len_in = payload->len_in;
|
|
len_out = payload->len_out;
|
|
|
|
printf("in: %d out: %d\n", len_in, len_out);
|
|
|
|
res = LzmaDecode(code_buffer, &len_out, payload->data, &len_in,
|
|
payload->props, LZMA_PROPS_SIZE, LZMA_FINISH_END,
|
|
&status, (ISzAlloc*)&lz_alloc);
|
|
|
|
if (res != SZ_OK) {
|
|
printf("decoding error %d (%u)\n", res, status);
|
|
return res;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void stubmain(void) {
|
|
#ifndef NDEBUG
|
|
exception_init();
|
|
#endif
|
|
|
|
// clear interrupt mask
|
|
write32(0x0c003004, 0);
|
|
|
|
#ifndef NDEBUG
|
|
#ifndef DKPPC
|
|
udelay(500 * 1000); // wait for mini - avoid EXI battle
|
|
#endif
|
|
gecko_init();
|
|
#endif
|
|
printf("hello world\n");
|
|
printf("payload @%p blob @%p\n", payload, payload->data);
|
|
|
|
if (decode() == 0 && valid_elf_image(code_buffer)) {
|
|
printf("Valid ELF image detected.\n");
|
|
u32 entry = load_elf_image(code_buffer);
|
|
|
|
if (entry) {
|
|
// Disable all IRQs; ack all pending IRQs.
|
|
write32(0x0c003004, 0);
|
|
write32(0x0c003000, 0xffffffff);
|
|
|
|
printf("Branching to 0x%08x\n", entry);
|
|
#ifndef DKPPC
|
|
// detect failkit apps packed with the mini stub
|
|
if (entry & 0xc0000000) {
|
|
void (*ep)() = (void (*)()) entry;
|
|
ep();
|
|
} else {
|
|
_plunge(entry);
|
|
}
|
|
#else
|
|
void (*ep)() = (void (*)()) entry;
|
|
ep();
|
|
#endif
|
|
}
|
|
}
|
|
|
|
error:
|
|
blink();
|
|
udelay(500000);
|
|
goto error;
|
|
}
|
|
|