freemyipod r145 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r144‎ | r145 | r146 >
Date:23:33, 15 August 2010
Author:theseven
Status:new
Tags:
Comment:
Port iLoader uninstaller to emBIOS. Not tested yet.
Modified paths:
  • /apps/uninstaller-nano2g (added) (history)
  • /apps/uninstaller-nano2g/Makefile (added) (history)
  • /apps/uninstaller-nano2g/SOURCES (added) (history)
  • /apps/uninstaller-nano2g/ls.x (added) (history)
  • /apps/uninstaller-nano2g/main.c (added) (history)
  • /apps/uninstaller-nano2g/version.h (added) (history)

Diff [purge]

Index: apps/uninstaller-nano2g/SOURCES
@@ -0,0 +1 @@
 2+main.c
Index: apps/uninstaller-nano2g/ls.x
@@ -0,0 +1,37 @@
 2+ENTRY(__embios_executable_hdr)
 3+OUTPUT_FORMAT(elf32-littlearm)
 4+OUTPUT_ARCH(arm)
 5+
 6+MEMORY
 7+{
 8+ RAM : ORIGIN = 0x08800000, LENGTH = 0x01600000
 9+}
 10+
 11+SECTIONS
 12+{
 13+ .text :
 14+ {
 15+ KEEP(.execheader*)
 16+ *(.execheader*)
 17+ *(.text*)
 18+ *(.glue_7)
 19+ *(.glue_7t)
 20+ . = ALIGN(0x4);
 21+ *(.rodata*)
 22+ . = ALIGN(0x4);
 23+ *(.data*)
 24+ . = ALIGN(0x4);
 25+ } > RAM
 26+
 27+ .bss (NOLOAD) :
 28+ {
 29+ *(.bss*)
 30+ *(COMMON)
 31+ } > RAM
 32+
 33+ /DISCARD/ :
 34+ {
 35+ *(.eh_frame)
 36+ }
 37+
 38+}
Index: apps/uninstaller-nano2g/main.c
@@ -0,0 +1,219 @@
 2+#include "embiosapp.h"
 3+
 4+
 5+void main();
 6+EMBIOS_APP_HEADER("Uninstaller thread", 0x1000, main, 127)
 7+
 8+
 9+uint16_t lcdbuffer[176 * 132];
 10+
 11+struct wakeup eventwakeup;
 12+volatile int button;
 13+
 14+char mallocbuf[0x1000000] __attribute__((aligned(16)));
 15+tlsf_pool mallocpool;
 16+
 17+uint8_t norbuf[0x100000] __attribute__((aligned(16)));
 18+#define norbufword ((uint32_t*)norbuf)
 19+
 20+#define nor ((uint8_t*)0x24000000)
 21+#define norword ((uint32_t*)0x24000000)
 22+
 23+
 24+void handler(enum button_event eventtype, int which, int value)
 25+{
 26+ if (eventtype == BUTTON_PRESS) button |= 1 << which;
 27+ wakeup_signal(&eventwakeup);
 28+}
 29+
 30+uint32_t freeret(uint32_t rc, void* ptr)
 31+{
 32+ tlsf_free(mallocpool, ptr);
 33+ return rc;
 34+}
 35+
 36+uint32_t decryptfw(void* image, uint32_t offset)
 37+{
 38+ uint32_t size = ((uint32_t*)image)[5];
 39+ if (size > 0x800000) return 0;
 40+ hwkeyaes(HWKEYAES_DECRYPT, ((uint32_t*)image)[2], &((uint8_t*)image)[offset], size);
 41+ memcpy(image, &((uint8_t*)image)[offset], size);
 42+ return size;
 43+}
 44+
 45+uint32_t getfw(const char* filename, uint32_t* sector, uint32_t* size)
 46+{
 47+ uint32_t i;
 48+ uint32_t* buffer = tlsf_memalign(mallocpool, 0x10, 0x800);
 49+ if (storage_read_sectors_md(0, 0, 1, buffer) != 0) return freeret(1, buffer);
 50+ if (*((uint16_t*)((uint32_t)buffer + 0x1FE)) != 0xAA55) return freeret(1, buffer);
 51+ uint32_t startsector = 0;
 52+ for (i = 0x1C2; i < 0x200; i += 0x10)
 53+ if (((uint8_t*)buffer)[i] == 0)
 54+ {
 55+ startsector = *((uint16_t*)((uint32_t)buffer + i + 4))
 56+ | (*((uint16_t*)((uint32_t)buffer + i + 6)) << 16);
 57+ break;
 58+ }
 59+ if (startsector == 0) return freeret(1, buffer);
 60+ if (storage_read_sectors_md(0, startsector, 1, buffer) != 0) return freeret(1, buffer);
 61+ if (buffer[0x40] != 0x5B68695D) return freeret(1, buffer);
 62+ if (storage_read_sectors_md(0, startsector + 1 + (buffer[0x41] >> 11), 1, buffer) != 0)
 63+ return freeret(1, buffer);
 64+ for (i = 0; i < 0x1FE; i += 10)
 65+ if (memcmp(&buffer[i], filename, 8) == 0)
 66+ {
 67+ *sector = startsector + (buffer[i + 3] >> 11);
 68+ *size = buffer[i + 4] + 0x800;
 69+ tlsf_free(mallocpool, buffer);
 70+ return 0;
 71+ }
 72+ return freeret(2, buffer);
 73+}
 74+
 75+uint32_t readfwptr(const char* filename, void* address, uint32_t* size)
 76+{
 77+ uint32_t sector;
 78+ uint32_t rc = getfw(filename, &sector, size);
 79+ if (rc) return rc;
 80+ if (storage_read_sectors_md(0, sector, ((*size + 0x7FF) >> 11), address) != 0) return 1;
 81+ *size = decryptfw(address, 0x800);
 82+ return 0;
 83+}
 84+
 85+uint32_t readfw(const char* filename, void** address, uint32_t* size)
 86+{
 87+ uint32_t sector;
 88+ uint32_t rc = getfw(filename, &sector, size);
 89+ if (rc) return rc;
 90+ *address = tlsf_memalign(mallocpool, 0x10, *size);
 91+ if (storage_read_sectors_md(0, sector, ((*size + 0x7FF) >> 11), *address) != 0)
 92+ return freeret(1, *address);
 93+ *size = decryptfw(*address, 0x800);
 94+ tlsf_realloc(mallocpool, *address, *size);
 95+ return 0;
 96+}
 97+
 98+void main(void)
 99+{
 100+ uint32_t i, j, k;
 101+ uint8_t* aupd;
 102+ uint32_t aupdsize;
 103+ uint32_t payloadstart = 0;
 104+ struct progressbar_state progressbar;
 105+
 106+ wakeup_init(&eventwakeup);
 107+ button_register_handler(handler);
 108+ mallocpool = tlsf_create(mallocbuf, sizeof(mallocbuf));
 109+
 110+ memset(lcdbuffer, 0xff, 176 * 132 * 2);
 111+ rendertext(&lcdbuffer[177], 0, 0xffff, "Loading...", 176);
 112+ displaylcd(0, 175, 0, 131, lcdbuffer, 0);
 113+ if (norword[0x400] != 0x53436667)
 114+ {
 115+ cputs(1, "Boot flash contents are damaged! (No SYSCFG found)\n\nPlease ask for help.\n");
 116+ return;
 117+ }
 118+
 119+ memset(norbuf, 0xff, 0x100000);
 120+ memcpy(&norbuf[0x4000], &nor[0x1000], 0x1000);
 121+
 122+ aupdsize = 0;
 123+ if (readfw("DNANdpua", (void**)&aupd, &aupdsize)) aupdsize = 0;
 124+ if (!aupdsize)
 125+ {
 126+ memset(lcdbuffer, 0xff, 176 * 132 * 2);
 127+ rendertext(&lcdbuffer[176 * 10 + 10], 0, 0xffff, "Please press any key to", 176);
 128+ rendertext(&lcdbuffer[176 * 18 + 10], 0, 0xffff, "enter disk mode and", 176);
 129+ rendertext(&lcdbuffer[176 * 26 + 10], 0, 0xffff, "restore your iPod using", 176);
 130+ rendertext(&lcdbuffer[176 * 34 + 10], 0, 0xffff, "iTunes. Your iPod will", 176);
 131+ rendertext(&lcdbuffer[176 * 42 + 10], 0, 0xffff, "reboot and ask you to", 176);
 132+ rendertext(&lcdbuffer[176 * 50 + 10], 0, 0xffff, "uninstall iLoader again.", 176);
 133+ rendertext(&lcdbuffer[176 * 66 + 10], 0, 0xffff, "If this message is still", 176);
 134+ rendertext(&lcdbuffer[176 * 74 + 10], 0, 0xffff, "shown after restoring,", 176);
 135+ rendertext(&lcdbuffer[176 * 82 + 10], 0, 0xffff, "please ask for help.", 176);
 136+ displaylcd(0, 175, 0, 131, lcdbuffer, 0);
 137+ button = 0;
 138+ while (true)
 139+ {
 140+ wakeup_wait(&eventwakeup, TIMEOUT_BLOCK);
 141+ if (button)
 142+ {
 143+ int size = bootflash_filesize("diskmode");
 144+ cprintf(1, "\nsize = %d bytes\n", size);
 145+ if (size > 0)
 146+ {
 147+ if (bootflash_attributes("diskmode") & 0x800)
 148+ {
 149+ if (!ucl_decompress(bootflash_getaddr("diskmode"), size,
 150+ (void*)0x08000000, (uint32_t*)&size))
 151+ {
 152+ shutdown(false);
 153+ execfirmware((void*)0x08000000);
 154+ }
 155+ }
 156+ else if (bootflash_read("diskmode", (void*)0x08000000, 0, size) == size)
 157+ {
 158+ shutdown(false);
 159+ execfirmware((void*)0x08000000);
 160+ }
 161+ }
 162+ cputs(1, "Could not boot disk mode.\nPlease ask for help.\n");
 163+ return;
 164+ }
 165+ }
 166+ }
 167+ for (i = 0; i < (aupdsize >> 2); i++)
 168+ if (((uint32_t*)aupd)[i] == 0x50796c64 && ((uint32_t*)aupd)[i + 4] == 0x46775570)
 169+ payloadstart = i << 2;
 170+ if (!payloadstart)
 171+ {
 172+ cputs(1, "Restore image is weird:\nNo payload start found.\nPlease ask for help.\n");
 173+ return;
 174+ }
 175+ memcpy(norbuf, &aupd[payloadstart + 0x2c], 0x2000);
 176+ memcpy(&norbuf[0x8800], &aupd[payloadstart + 0x2048], 0x1f800);
 177+ memcpy(&norbuf[0x28000], &aupd[payloadstart + 0x22048], 0xd8000);
 178+ tlsf_free(mallocpool, aupd);
 179+
 180+ rendertext(&lcdbuffer[177], 0, 0xffff, "Encrypting flash update...", 176);
 181+ displaylcd(0, 175, 0, 131, lcdbuffer, 0);
 182+ memset(&norbuf[0x8000], 0, 0x800);
 183+ norbufword[0x2000] = 0x31303738;
 184+ norbufword[0x2001] = 0x00302e31;
 185+ norbufword[0x2002] = 0x800;
 186+ norbufword[0x2003] = 0x1f800;
 187+ hmacsha1(&norbuf[0x8800], 0x1f800, &norbuf[0x8010]);
 188+ hmacsha1(&norbuf[0x8000], 0x40, &norbuf[0x8040]);
 189+ hwkeyaes(HWKEYAES_ENCRYPT, 2, &norbuf[0x8000], 0x20000);
 190+ for (i = 0xffe00; i < 0xffec8; i += 0x28)
 191+ if (norbufword[i >> 2])
 192+ {
 193+ uint32_t offs = norbufword[(i >> 2) + 3] >> 2;
 194+ norbufword[offs] = 0;
 195+ norbufword[offs + 1] = 2;
 196+ norbufword[offs + 2] = 2;
 197+ norbufword[offs + 3] = 0x40;
 198+ norbufword[offs + 4] = 0;
 199+ norbufword[offs + 5] = norbufword[(i >> 2) + 4];
 200+ hmacsha1(&norbufword[offs + 0x80], norbufword[(i >> 2) + 4], &norbufword[offs + 7]);
 201+ memset(&norbufword[offs + 0x75], 0, 0x14);
 202+ hmacsha1(&norbufword[offs], 0x200, &norbufword[offs + 0x75]);
 203+ hwkeyaes(HWKEYAES_ENCRYPT, 2, &norbufword[offs + 0x80], norbufword[(i >> 2) + 4]);
 204+ }
 205+
 206+ rendertext(&lcdbuffer[177], 0, 0xffff, "Flashing... (DO NOT RESET!!!)", 176);
 207+ displaylcd(0, 175, 0, 131, lcdbuffer, 0);
 208+ progressbar_init(&progressbar, 1, 174, 10, 17, 0, lcd_translate_color(0, 0xcf, 0xcf, 0xcf),
 209+ lcd_translate_color(0, 0, 0, 0xcf), 0, 256);
 210+ for (i = 0; i < 256; i++)
 211+ {
 212+ bootflash_writeraw(&norbuf[i * 0x1000], i * 0x1000, 0x1000);
 213+ progressbar_setpos(&progressbar, i, false);
 214+ }
 215+ rendertext(&lcdbuffer[177], 0, 0xffff, "Uninstallation successful! ", 176);
 216+ displaylcd(0, 175, 0, 131, lcdbuffer, 0);
 217+ sleep(1000000);
 218+ shutdown(true);
 219+ reset();
 220+}
Index: apps/uninstaller-nano2g/version.h
@@ -0,0 +1,36 @@
 2+//
 3+//
 4+// Copyright 2010 TheSeven
 5+//
 6+//
 7+// This file is part of emBIOS.
 8+//
 9+// emBIOS is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emBIOS is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emBIOS. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#ifndef __VERSION_H__
 26+#define __VERSION_H__
 27+
 28+
 29+#define VERSION "0.0.1pre"
 30+#define VERSION_MAJOR 0
 31+#define VERSION_MINOR 0
 32+#define VERSION_PATCH 1
 33+#define VERSION_SVN "$REVISION$"
 34+#define VERSION_SVN_INT $REVISIONINT$
 35+
 36+
 37+#endif
\ No newline at end of file
Index: apps/uninstaller-nano2g/Makefile
@@ -0,0 +1,90 @@
 2+NAME := uninstaller-nano2g
 3+
 4+EMBIOSDIR ?= ../../embios/trunk/
 5+
 6+CROSS ?= arm-none-eabi-
 7+CC := $(CROSS)gcc
 8+AS := $(CROSS)as
 9+LD := $(CROSS)ld
 10+OBJCOPY := $(CROSS)objcopy
 11+UCLPACK := ucl2e10singleblk
 12+
 13+CFLAGS += -Os -fno-pie -fno-stack-protector -fomit-frame-pointer -I. -I$(EMBIOSDIR)/export -ffunction-sections -fdata-sections
 14+LDFLAGS += "$(shell $(CC) -print-libgcc-file-name)" --gc-sections
 15+
 16+preprocess = $(shell $(CC) $(PPCFLAGS) $(2) -E -P -x c $(1) | grep -v "^\#")
 17+preprocesspaths = $(shell $(CC) $(PPCFLAGS) $(2) -E -P -x c $(1) | grep -v "^\#" | sed -e "s:^..*:$(dir $(1))&:")
 18+
 19+REVISION := $(shell svnversion .)
 20+REVISIONINT := $(shell echo $(REVISION) | sed -e "s/[^0-9].*$$//")
 21+
 22+SRC := $(call preprocesspaths,SOURCES,-I. -I..)
 23+OBJ := $(SRC:%.c=build/%.o)
 24+OBJ := $(OBJ:%.S=build/%.o)
 25+
 26+all: $(NAME)
 27+
 28+-include $(OBJ:%=%.dep)
 29+
 30+$(NAME): build/$(NAME).embiosapp.ucl
 31+
 32+build/$(NAME).embiosapp.ucl: build/$(NAME).embiosapp
 33+ @echo [UCL] $<
 34+ @$(UCLPACK) $^ $@
 35+
 36+build/$(NAME).embiosapp: build/$(NAME).elf
 37+ @echo [OC] $<
 38+ @$(OBJCOPY) -O binary $^ $@
 39+
 40+build/$(NAME).elf: ls.x $(OBJ)
 41+ @echo [LD] $@
 42+ @$(LD) $(LDFLAGS) -o $@ -T ls.x $(OBJ)
 43+
 44+build/%.o: %.c build/version.h
 45+ @echo [CC] $<
 46+ifeq ($(shell uname),WindowsNT)
 47+ @-if not exist $(subst /,\,$(dir $@)) md $(subst /,\,$(dir $@))
 48+else
 49+ @-mkdir -p $(dir $@)
 50+endif
 51+ @$(CC) -c $(CFLAGS) -o $@ $<
 52+ @$(CC) -MM $(CFLAGS) $< > $@.dep.tmp
 53+ @sed -e "s|.*:|$@:|" < $@.dep.tmp > $@.dep
 54+ifeq ($(shell uname),WindowsNT)
 55+ @sed -e "s/.*://" -e "s/\\$$//" < $@.dep.tmp | fmt -1 | sed -e "s/^ *//" -e "s/$$/:/" >> $@.dep
 56+else
 57+ @sed -e 's/.*://' -e 's/\\$$//' < $@.dep.tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $@.dep
 58+endif
 59+ @rm -f $@.dep.tmp
 60+
 61+build/%.o: %.S build/version.h
 62+ @echo [CC] $<
 63+ifeq ($(shell uname),WindowsNT)
 64+ @-if not exist $(subst /,\,$(dir $@)) md $(subst /,\,$(dir $@))
 65+else
 66+ @-mkdir -p $(dir $@)
 67+endif
 68+ @$(CC) -c $(CFLAGS) -o $@ $<
 69+ @$(CC) -MM $(CFLAGS) $< > $@.dep.tmp
 70+ @sed -e "s|.*:|$@:|" < $@.dep.tmp > $@.dep
 71+ifeq ($(shell uname),WindowsNT)
 72+ @sed -e "s/.*://" -e "s/\\$$//" < $@.dep.tmp | fmt -1 | sed -e "s/^ *//" -e "s/$$/:/" >> $@.dep
 73+else
 74+ @sed -e 's/.*://' -e 's/\\$$//' < $@.dep.tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $@.dep
 75+endif
 76+ @rm -f $@.dep.tmp
 77+
 78+build/version.h: version.h .svn/entries
 79+ @echo [PP] $<
 80+ifeq ($(shell uname),WindowsNT)
 81+ @-if not exist build md build
 82+ @sed -e "s/\$$REVISION\$$/$(REVISION)/" -e "s/\$$REVISIONINT\$$/$(REVISIONINT)/" < $< > $@
 83+else
 84+ @-mkdir -p build
 85+ @sed -e 's/\$$REVISION\$$/$(REVISION)/' -e 's/\$$REVISIONINT\$$/$(REVISIONINT)/' < $< > $@
 86+endif
 87+
 88+clean:
 89+ @rm -rf build
 90+
 91+.PHONY: all clean $(NAME)
Index: apps/uninstaller-nano2g
Property changes on: apps/uninstaller-nano2g
___________________________________________________________________
Added: svn:ignore
## -0,0 +1 ##
 92+build