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                                         |
+---------------------------------------------------+
#>


返回上一頁