Gemei A330
(MyBootloader) UART
目前國外已經有高手釋出GA330掌機的燒錄程式(rom.bin),但是受限於原廠的限制,這位高手並沒有釋出相關資料手冊,司徒也只能先將此燒錄程式進行逆向工程,看看是否有機會將Linux系統移植到GA330掌機身上,當然,要把所有GA330掌機的CPU暫存器全部逆向出來也是不太可能的,但是,至少這是唯一有機會將Linux移植到GA330掌機。
首先開啟Command Line並輸入如下指令進行反組譯
c:\> PATH c:/ga330/cygwin/arm-linux/bin;c:/ga330/CYGWIN/BIN;C:\windows\ c:\> arm-linux-objcopy --change-addresses=0x00000000 -I binary -O elf32-littlearm -B arm rom.bin rom-elf c:\> arm-linux-objcopy --set-section-flags .data=code rom-elf c:\> arm-linux-objdump -d rom-elf > rom.dis
司徒花了一些時間,從反組譯後的程式改寫一個簡單的Helo, world!程式,並將此訊息從UART輸出,希望從簡單的Hello, world!程式,開始進行GA330掌機的逆向破解之路
.equ UART_BASE, 0x04000000 .equ UART_FLAG, 0x04000018 .equ UART_TX, 0x04000020 .global _start _start: b begin undefined: b undefined software: b software preabort: b preabort dataabort: b dataabort irq: b irq_process fiq: b fiq .align welcome_msg: .ascii "\r\n" .ascii "+---------------------------------------------------+\r\n" .ascii "| (MyBootloader) UART for Gemei A330 by Steward_Fu |\r\n" .ascii "| 2013.3.10 |\r\n" .ascii "+---------------------------------------------------+\r\n" .asciz "#> " .align irq_process: sub sp, sp, #4 stmdb sp!, {r8} ldr r8, =0x00103ff0 ldr r8, [r8] str r8, [sp, #4] ldmia sp!, {r8, pc} begin: ldr r0, =0x0408800c ldr r1, =0x00ffeaaa str r1, [r0] /* [0x0408800c] <= 0x00ffeaaa */ mov r0, #1048576 /* r0 = 0x100000 */ add r1, r0, #8192 /* r1 = 0x102000 */ add r3, r1, #8192 /* r3 = 0x104000 */ relocate_code: /* copy code from 0x1000000 to 0x102000 with 0x2000 bytes */ cmp r1, r3 ldrcc r2, [r0], #4 strcc r2, [r1], #4 bcc relocate_code add r0, pc, #4 /* r0 = pc + 4 */ add r0, r0, #8192 /* r0+= 0x2000 */ mov pc, r0 /* jump to ram address */ bl init_irq ldr r0, =0x00102b7c ldr r1, =0x00102b7c ldr r3, =0x00102b80 cmp r0, r1 beq init_boot relocate_ram: cmp r1, r3 /* copy data from 0x00102b7c to 0x00102b80 with 4 bytes */ ldrcc r2, [r0], #4 strcc r2, [r1], #4 bcc relocate_ram init_boot: ldr r1, =0x00102b94 mov r2, #0 init_ram: cmp r3, r1 strcc r2, [r3], #4 /* zero ram from 0x00102b80 to 0x00102b94 */ bcc init_ram b init_uart_reg init_irq: mrs r0, CPSR bic r0, r0, #31 /* 0x1f */ orr r1, r0, #219 /* 0xdb */ msr CPSR_fsxc, r1 /* disable irq and fiq, enter udefined mode*/ ldr sp, =0x00103cf0 orr r1, r0, #215 /* 0xd7 */ msr CPSR_fsxc, r1 /* disable irq and fiq, enter abort mode*/ ldr sp, =0x00103d70 orr r1, r0, #210 /* 0xd2 */ msr CPSR_fsxc, r1 /* disable irq and fiq, enter irq mode*/ ldr sp, =0x00103f70 orr r1, r0, #209 /* 0xd1 */ msr CPSR_fsxc, r1 /* disable irq and fiq, enter fiq mode*/ ldr sp, =0x00103ff0 bic r0, r0, #223 /* 0xdf */ orr r1, r0, #19 /* 0x13 */ msr CPSR_fsxc, r1 /* enable irq and fiq, enter supervisor mode*/ ldr sp, =0x00103bf0 mov pc, lr send_char: mov r2, #0x04000000 /* uart base address */ wait_tx_flag: ldr r1, [r2, #0x18] /* r1 = [0x4000018] */ tst r1, #0x200 /* tx flag */ bne wait_tx_flag strb r0, [r2, #0x20] /* [0x4000020] = char */ bx lr show_message: str lr, [sp, #-4]! mov r3, r0 b check_char next_char: add r3, r3, #1 bl send_char check_char: ldrb r0, [r3] /* if not ending char, send this char via uart */ cmp r0, #0 bne next_char ldr pc, [sp], #4 init_uart_reg: mov r0, #19 mov r1, #67108864 str r0, [r1, #40] /* [0x4000040] = 0x13 */ mov r0, #7 mov r1, #67108864 str r0, [r1] /* [0x4000000] = 0x07 */ mov r0, #133 mov r1, #67108864 str r0, [r1, #4] /* [0x4000004] = 0x85 */ mov r0, #150 mov r1, #67108864 str r0, [r1, #8] /* [0x4000008] = 0x96 */ add r0, r1, #565248 ldr r1, [r0, #16] orr r1, r1, #2 str r1, [r0, #16] /* [0x408a010]|= 2 */ adr r0, welcome_msg /* pointer to uart initial message */ bl show_message while: b while
經由上面的程式註解可以知道RAM的起始執行位置是位於0x1002000,因此我們需要一個LD Script檔案進行定位,該檔案內容如下
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { . = 0x102000; . = ALIGN(4); .text : { *(.text) } }
接著使用如下指令進行編譯即可產生boot.bin燒錄檔案
c:\> PATH c:/ga330/cygwin/arm-linux/bin;c:/ga330/CYGWIN/BIN;C:\windows\ c:\> arm-linux-gcc -fno-pic -pipe -O2 -Wall -finline-functions -fomit-frame-pointer -msoft-float -fno-builtin -mcpu=arm926ej-s -c ga330_boot.s c:\> arm-linux-gcc -nostdlib -o boot-elf32 ga330_boot.o -T ga330_link c:\> arm-linux-objcopy -O binary boot-elf32 boot.bin
接著使用司徒之前介紹的燒錄步驟,將boot.bin燒錄到MiniSD並插上UART線,接著按下DPad的下按鈕開機,即可看到如下的開機訊息(Baudrate: 115200bps)
+---------------------------------------------------+ | (MyBootloader) UART for Gemei A330 by Steward_Fu | | 2013.3.10 | +---------------------------------------------------+ #>