freemyipod r670 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r669‎ | r670 | r671 >
Date:18:34, 25 March 2011
Author:theseven
Status:new
Tags:
Comment:
Port iPod Nano 2G uninstaller to emCORE
Modified paths:
  • /apps/uninstaller-ipodnano2g (added) (history)
  • /apps/uninstaller-ipodnano2g/Makefile (modified) (history)
  • /apps/uninstaller-ipodnano2g/ls.x (modified) (history)
  • /apps/uninstaller-ipodnano2g/main.c (modified) (history)
  • /apps/uninstaller-ipodnano2g/version.h (modified) (history)

Diff [purge]

Index: apps/uninstaller-ipodnano2g/ls.x
@@ -0,0 +1,42 @@
 2+ENTRY(__emcore_entrypoint)
 3+OUTPUT_FORMAT(elf32-littlearm)
 4+OUTPUT_ARCH(arm)
 5+
 6+MEMORY
 7+{
 8+ VIRTUAL : ORIGIN = 0x00000000, LENGTH = 0x10000000
 9+}
 10+
 11+SECTIONS
 12+{
 13+ .text :
 14+ {
 15+ __emcore_app_base = .;
 16+ KEEP(.emcoreentrypoint*)
 17+ *(.emcoreentrypoint*)
 18+ *(.text*)
 19+ *(.glue_7)
 20+ *(.glue_7t)
 21+ . = ALIGN(0x10);
 22+ } > VIRTUAL
 23+
 24+ .data :
 25+ {
 26+ *(.rodata*)
 27+ . = ALIGN(0x4);
 28+ *(.data*)
 29+ . = ALIGN(0x10);
 30+ } > VIRTUAL
 31+
 32+ .bss (NOLOAD) :
 33+ {
 34+ *(.bss*)
 35+ *(COMMON)
 36+ } > VIRTUAL
 37+
 38+ /DISCARD/ :
 39+ {
 40+ *(.eh_frame)
 41+ }
 42+
 43+}
Index: apps/uninstaller-ipodnano2g/main.c
@@ -0,0 +1,224 @@
 2+//
 3+//
 4+// Copyright 2010 TheSeven
 5+//
 6+//
 7+// This file is part of emCORE.
 8+//
 9+// emCORE 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+// emCORE 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 emCORE. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#include "emcoreapp.h"
 26+#include "libboot.h"
 27+
 28+
 29+void main();
 30+EMCORE_APP_HEADER("emCORE uninstaller", main, 127)
 31+
 32+
 33+struct wakeup eventwakeup;
 34+volatile int button;
 35+
 36+#define nor ((uint8_t*)0x24000000)
 37+#define norword ((uint32_t*)0x24000000)
 38+
 39+
 40+void handler(void* user, enum button_event eventtype, int which, int value)
 41+{
 42+ if (eventtype == BUTTON_PRESS) button |= 1 << which;
 43+ wakeup_signal(&eventwakeup);
 44+}
 45+
 46+void* safe_memalign(size_t align, size_t size)
 47+{
 48+ void* addr = memalign(align, size);
 49+ if (!addr) panicf(PANIC_KILLTHREAD, "Out of memory!");
 50+ return addr;
 51+}
 52+
 53+uint32_t freeret(uint32_t rc, void* ptr)
 54+{
 55+ free(ptr);
 56+ return rc;
 57+}
 58+
 59+uint32_t decryptfw(void* image, uint32_t offset)
 60+{
 61+ uint32_t size = ((uint32_t*)image)[5];
 62+ if (size > 0x800000) return 0;
 63+ hwkeyaes(HWKEYAES_DECRYPT, ((uint32_t*)image)[2], &((uint8_t*)image)[offset], size);
 64+ memcpy(image, &((uint8_t*)image)[offset], size);
 65+ return size;
 66+}
 67+
 68+uint32_t getfw(const char* filename, uint32_t* sector, uint32_t* size)
 69+{
 70+ uint32_t i;
 71+ uint32_t* buffer = safe_memalign(0x10, 0x800);
 72+ if (storage_read_sectors_md(0, 0, 1, buffer) != 0) return freeret(1, buffer);
 73+ if (*((uint16_t*)((uint32_t)buffer + 0x1FE)) != 0xAA55) return freeret(1, buffer);
 74+ uint32_t startsector = 0;
 75+ for (i = 0x1C2; i < 0x200; i += 0x10)
 76+ if (((uint8_t*)buffer)[i] == 0)
 77+ {
 78+ startsector = *((uint16_t*)((uint32_t)buffer + i + 4))
 79+ | (*((uint16_t*)((uint32_t)buffer + i + 6)) << 16);
 80+ break;
 81+ }
 82+ if (startsector == 0) return freeret(1, buffer);
 83+ if (storage_read_sectors_md(0, startsector, 1, buffer) != 0) return freeret(1, buffer);
 84+ if (buffer[0x40] != 0x5B68695D) return freeret(1, buffer);
 85+ if (storage_read_sectors_md(0, startsector + 1 + (buffer[0x41] >> 11), 1, buffer) != 0)
 86+ return freeret(1, buffer);
 87+ for (i = 0; i < 0x1FE; i += 10)
 88+ if (memcmp(&buffer[i], filename, 8) == 0)
 89+ {
 90+ *sector = startsector + (buffer[i + 3] >> 11);
 91+ *size = buffer[i + 4] + 0x800;
 92+ free(buffer);
 93+ return 0;
 94+ }
 95+ return freeret(2, buffer);
 96+}
 97+
 98+uint32_t readfw(const char* filename, void** address, uint32_t* size)
 99+{
 100+ uint32_t sector;
 101+ uint32_t rc = getfw(filename, &sector, size);
 102+ if (rc) return rc;
 103+ *address = safe_memalign(0x10, *size);
 104+ if (storage_read_sectors_md(0, sector, ((*size + 0x7FF) >> 11), *address) != 0)
 105+ return freeret(1, *address);
 106+ *size = decryptfw(*address, 0x800);
 107+ *address = realloc(*address, *size);
 108+ return 0;
 109+}
 110+
 111+void main(void)
 112+{
 113+ uint32_t i, j, k;
 114+ uint8_t* aupd;
 115+ uint32_t aupdsize;
 116+ uint32_t payloadstart = 0;
 117+ struct progressbar_state progressbar;
 118+
 119+ cputc(1, '.');
 120+
 121+ if (norword[0x400] != 0x53436667)
 122+ panicf(PANIC_KILLTHREAD, "Boot flash contents are damaged! (No SYSCFG found)\n\n"
 123+ "Please ask for help.");
 124+
 125+ aupdsize = 0;
 126+ if (readfw("DNANdpua", (void**)&aupd, &aupdsize)) aupdsize = 0;
 127+ cputc(1, '.');
 128+ if (!aupdsize)
 129+ {
 130+ cputs(3, "\n\nPlease press any key to\nenter disk mode and\nrestore your iPod using\n"
 131+ "iTunes. After your iPod\nreboots, run the\nuninstaller again.\n"
 132+ "If this message is still\nshown after restoring,\nplease ask for help.");
 133+ wakeup_init(&eventwakeup);
 134+ struct button_hook_entry* hook = button_register_handler(handler, NULL);
 135+ if (!hook) panicf(PANIC_KILLTHREAD, "Could not register button hook!");
 136+ button = 0;
 137+ while (true)
 138+ {
 139+ wakeup_wait(&eventwakeup, TIMEOUT_BLOCK);
 140+ if (button)
 141+ {
 142+ void* firmware = NULL;
 143+ int size;
 144+ struct emcorelib_header* lib = get_library(LIBBOOT_IDENTIFIER, LIBBOOT_API_VERSION,
 145+ LIBSOURCE_BOOTFLASH, "libboot ");
 146+ if (!lib) panicf(PANIC_KILLTHREAD, "Could not load libboot!");
 147+ struct libboot_api* boot = (struct libboot_api*)lib->api;
 148+ boot->load_from_flash(&firmware, &size, false, "diskmode", 0x100000);
 149+ release_library(lib);
 150+ library_unload(lib);
 151+ if (!firmware)
 152+ panicf(PANIC_KILLTHREAD, "Could not boot disk mode.\nPlease ask for help.");
 153+ shutdown(false);
 154+ execfirmware((void*)0x08000000, firmware, size);
 155+ }
 156+ }
 157+ }
 158+
 159+ cputc(1, '.');
 160+ uint8_t* norbuf = (uint8_t*)safe_memalign(0x10, 0x100000);
 161+ #define norbufword ((uint32_t*)norbuf)
 162+ cputc(1, '.');
 163+ memset(norbuf, 0xff, 0x100000);
 164+ cputc(1, '.');
 165+ memcpy(&norbuf[0x4000], &nor[0x1000], 0x1000);
 166+ cputc(1, '.');
 167+
 168+ for (i = 0; i < (aupdsize >> 2); i++)
 169+ if (((uint32_t*)aupd)[i] == 0x50796c64 && ((uint32_t*)aupd)[i + 4] == 0x46775570)
 170+ payloadstart = i << 2;
 171+ if (!payloadstart)
 172+ panicf(PANIC_KILLTHREAD, "Restore image is weird:\nNo payload start found.\n"
 173+ "Please ask for help.");
 174+ cputc(1, '.');
 175+ memcpy(norbuf, &aupd[payloadstart + 0x2c], 0x2000);
 176+ cputc(1, '.');
 177+ memcpy(&norbuf[0x8800], &aupd[payloadstart + 0x2048], 0x1f800);
 178+ cputc(1, '.');
 179+ memcpy(&norbuf[0x28000], &aupd[payloadstart + 0x22048], 0xd8000);
 180+ cputc(1, '.');
 181+ free(aupd);
 182+
 183+ memset(&norbuf[0x8000], 0, 0x800);
 184+ cputc(1, '.');
 185+ norbufword[0x2000] = 0x31303738;
 186+ norbufword[0x2001] = 0x00302e31;
 187+ norbufword[0x2002] = 0x800;
 188+ norbufword[0x2003] = 0x1f800;
 189+ cputc(1, '.');
 190+ hmacsha1(&norbuf[0x8800], 0x1f800, &norbuf[0x8010]);
 191+ cputc(1, '.');
 192+ hmacsha1(&norbuf[0x8000], 0x40, &norbuf[0x8040]);
 193+ cputc(1, '.');
 194+ hwkeyaes(HWKEYAES_ENCRYPT, 2, &norbuf[0x8000], 0x20000);
 195+ cputc(1, '.');
 196+ for (i = 0xffe00; i < 0xffec8; i += 0x28)
 197+ if (norbufword[i >> 2])
 198+ {
 199+ uint32_t offs = norbufword[(i >> 2) + 3] >> 2;
 200+ norbufword[offs] = 0;
 201+ norbufword[offs + 1] = 2;
 202+ norbufword[offs + 2] = 2;
 203+ norbufword[offs + 3] = 0x40;
 204+ norbufword[offs + 4] = 0;
 205+ norbufword[offs + 5] = norbufword[(i >> 2) + 4];
 206+ cputc(1, '.');
 207+ hmacsha1(&norbufword[offs + 0x80], norbufword[(i >> 2) + 4], &norbufword[offs + 7]);
 208+ cputc(1, '.');
 209+ memset(&norbufword[offs + 0x75], 0, 0x14);
 210+ cputc(1, '.');
 211+ hmacsha1(&norbufword[offs], 0x200, &norbufword[offs + 0x75]);
 212+ cputc(1, '.');
 213+ hwkeyaes(HWKEYAES_ENCRYPT, 2, &norbufword[offs + 0x80], norbufword[(i >> 2) + 4]);
 214+ cputc(1, '.');
 215+ }
 216+
 217+ for (i = 0; i < 16; i++)
 218+ {
 219+ bootflash_writeraw(&norbuf[i * 0x10000], i * 0x10000, 0x10000);
 220+ cputc(1, '.');
 221+ }
 222+ free(norbuf);
 223+ shutdown(false);
 224+ reset();
 225+}
Index: apps/uninstaller-ipodnano2g/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.3.0"
 30+#define VERSION_MAJOR 0
 31+#define VERSION_MINOR 3
 32+#define VERSION_PATCH 0
 33+#define VERSION_SVN "$REVISION$"
 34+#define VERSION_SVN_INT $REVISIONINT$
 35+
 36+
 37+#endif
\ No newline at end of file
Index: apps/uninstaller-ipodnano2g/Makefile
@@ -0,0 +1,121 @@
 2+NAME := uninstaller-ipodnano2g
 3+STACKSIZE := 4096
 4+COMPRESS := true
 5+
 6+EMCOREDIR ?= ../../emcore/trunk/
 7+LIBBOOTDIR ?= ../../libs/boot/
 8+
 9+ifeq ($(shell uname),WindowsNT)
 10+CCACHE :=
 11+else
 12+CCACHE := $(shell which ccache)
 13+endif
 14+
 15+CROSS ?= arm-elf-eabi-
 16+CC := $(CCACHE) $(CROSS)gcc
 17+AS := $(CROSS)as
 18+LD := $(CROSS)ld
 19+OBJCOPY := $(CROSS)objcopy
 20+ELF2ECA := $(CROSS)elf2emcoreapp
 21+
 22+LIBINCLUDES := -I$(LIBBOOTDIR)/export
 23+
 24+CFLAGS += -Os -fno-pie -fno-stack-protector -fomit-frame-pointer -I. -I$(EMCOREDIR)/export $(LIBINCLUDES) -ffunction-sections -fdata-sections -mcpu=arm940t -DARM_ARCH=4
 25+LDFLAGS += "$(shell $(CC) -print-libgcc-file-name)" --emit-relocs --gc-sections
 26+
 27+preprocess = $(shell $(CC) $(PPCFLAGS) $(2) -E -P -x c $(1) | grep -v "^\#")
 28+preprocesspaths = $(shell $(CC) $(PPCFLAGS) $(2) -E -P -x c $(1) | grep -v "^\#" | sed -e "s:^..*:$(dir $(1))&:" | sed -e "s:^\\./::")
 29+
 30+REVISION := $(shell svnversion .)
 31+REVISIONINT := $(shell echo $(REVISION) | sed -e "s/[^0-9].*$$//")
 32+
 33+HELPERS := build/__emcore_armhelpers.o
 34+
 35+SRC := $(call preprocesspaths,SOURCES,-I. -I..)
 36+OBJ := $(SRC:%.c=build/%.o)
 37+OBJ := $(OBJ:%.S=build/%.o) $(HELPERS)
 38+
 39+all: $(NAME)
 40+
 41+-include $(OBJ:%=%.dep)
 42+
 43+$(NAME): build/$(NAME).emcoreapp
 44+
 45+build/$(NAME).emcoreapp: build/$(NAME).elf
 46+ @echo [EMCAPP] $<
 47+ifeq ($(COMPRESS),true)
 48+ @$(ELF2ECA) -z -s $(STACKSIZE) -o $@ $^
 49+else
 50+ @$(ELF2ECA) -s $(STACKSIZE) -o $@ $^
 51+endif
 52+
 53+build/$(NAME).elf: ls.x $(OBJ)
 54+ @echo [LD] $@
 55+ @$(LD) $(LDFLAGS) -o $@ -T ls.x $(OBJ)
 56+
 57+build/%.o: %.c build/version.h
 58+ @echo [CC] $<
 59+ifeq ($(shell uname),WindowsNT)
 60+ @-if not exist $(subst /,\,$(dir $@)) md $(subst /,\,$(dir $@))
 61+else
 62+ @-mkdir -p $(dir $@)
 63+endif
 64+ @$(CC) -c $(CFLAGS) -o $@ $<
 65+ @$(CC) -MM $(CFLAGS) $< > $@.dep.tmp
 66+ @sed -e "s|.*:|$@:|" < $@.dep.tmp > $@.dep
 67+ifeq ($(shell uname),WindowsNT)
 68+ @sed -e "s/.*://" -e "s/\\$$//" < $@.dep.tmp | fmt -1 | sed -e "s/^ *//" -e "s/$$/:/" >> $@.dep
 69+else
 70+ @sed -e 's/.*://' -e 's/\\$$//' < $@.dep.tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $@.dep
 71+endif
 72+ @rm -f $@.dep.tmp
 73+
 74+build/%.o: %.S build/version.h
 75+ @echo [CC] $<
 76+ifeq ($(shell uname),WindowsNT)
 77+ @-if not exist $(subst /,\,$(dir $@)) md $(subst /,\,$(dir $@))
 78+else
 79+ @-mkdir -p $(dir $@)
 80+endif
 81+ @$(CC) -c $(CFLAGS) -o $@ $<
 82+ @$(CC) -MM $(CFLAGS) $< > $@.dep.tmp
 83+ @sed -e "s|.*:|$@:|" < $@.dep.tmp > $@.dep
 84+ifeq ($(shell uname),WindowsNT)
 85+ @sed -e "s/.*://" -e "s/\\$$//" < $@.dep.tmp | fmt -1 | sed -e "s/^ *//" -e "s/$$/:/" >> $@.dep
 86+else
 87+ @sed -e 's/.*://' -e 's/\\$$//' < $@.dep.tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $@.dep
 88+endif
 89+ @rm -f $@.dep.tmp
 90+
 91+build/__emcore_%.o: $(EMCOREDIR)/export/%.c
 92+ @echo [CC] $<
 93+ifeq ($(shell uname),WindowsNT)
 94+ @-if not exist $(subst /,\,$(dir $@)) md $(subst /,\,$(dir $@))
 95+else
 96+ @-mkdir -p $(dir $@)
 97+endif
 98+ @$(CC) -c $(CFLAGS) -o $@ $<
 99+
 100+build/__emcore_%.o: $(EMCOREDIR)/export/%.S
 101+ @echo [CC] $<
 102+ifeq ($(shell uname),WindowsNT)
 103+ @-if not exist $(subst /,\,$(dir $@)) md $(subst /,\,$(dir $@))
 104+else
 105+ @-mkdir -p $(dir $@)
 106+endif
 107+ @$(CC) -c $(CFLAGS) -o $@ $<
 108+
 109+build/version.h: version.h .svn/entries
 110+ @echo [PP] $<
 111+ifeq ($(shell uname),WindowsNT)
 112+ @-if not exist build md build
 113+ @sed -e "s/\$$REVISION\$$/$(REVISION)/" -e "s/\$$REVISIONINT\$$/$(REVISIONINT)/" < $< > $@
 114+else
 115+ @-mkdir -p build
 116+ @sed -e 's/\$$REVISION\$$/$(REVISION)/' -e 's/\$$REVISIONINT\$$/$(REVISIONINT)/' < $< > $@
 117+endif
 118+
 119+clean:
 120+ @rm -rf build
 121+
 122+.PHONY: all clean $(NAME)
Index: apps/uninstaller-ipodnano2g/SOURCES
@@ -0,0 +1 @@
 2+main.c
Index: apps/uninstaller-ipodnano2g
Property changes on: apps/uninstaller-ipodnano2g
___________________________________________________________________
Added: svn:ignore
## -0,0 +1 ##
 3+build