Fandom

Magic Lantern Firmware Wiki

Decompiling

328pages on
this wiki
Add New Page
Talk0 Share

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

An experimental decompiler for ARM ASM is implemented in ARM-console, module deco.

Theory: Static_analysis

NotationsEdit

  • arg0, arg1, arg2, arg3 => function arguments passed in r0, r1, r2, r3
  • sp0 => stack pointer at the beginning of the function
    • *(sp0), *(sp0+4), *(sp0+8) => arg4, arg5, arg6
    • *(sp0-4), *(sp0-8)... => local variables
  •  !end => end of code path
  • EQ(x), NE(x): check some condition flags; e.g. EQ(x) is true if x == 0
  • EQ5(x) is true if x == 5 (these will appear when decompiling jump tables)

Forward (normal) decompilationEdit

You decompile from the start of a function.

dec AJ_guess_get_DIGIC_time
return struct_0xc0242000.off_0x14 /*0xC0242014*/
!end
dec PrintRemconParam
*(-4 + sp0) = lr0
*(-8 + sp0) = unk_R4
TH_con_puts('\n[RemDriver] RemconParam\n', arg1, arg2, arg3) => ret_TH_con_puts_FF066D6C
TH_con_puts(' PulseWidthMin  : %4ld\n', remocon_struct.PulseWidthMin /*off_0x10, 0x2AA0*/, arg2, arg3) => ret_TH_con_puts_FF066D7C
TH_con_puts(' PulseWidthMax  : %4ld\n', remocon_struct.PulseWidthMax /*off_0x14, 0x2AA4*/, arg2, arg3) => ret_TH_con_puts_FF066D88
[...]
return 0
!end
dec RemOff_secret_mode_RemOn
*(-4 + sp0) = lr0
*(-8 + sp0) = unk_R4
RemOff() => ret_RemOff_FF07BF08
if arg0 != 0:
    if arg0 == 1:
        secret_mode(0x4, 0x14, 0x1, 0x2) => ret_secret_mode_FF07BF30
    
if arg0 == 0:
    secret_mode(0x4, 0x14, 0x1, 0x1) => ret_secret_mode_FF07BF30
RemOn() => ret_RemOn_FF07BF38
!end

LoopsEdit

The decompiler doesn't supoort loops, but it will usually handle the first iteration:

dec gui_main_task
*(-4 + sp0) = lr0
*(-8 + sp0) = unk_R5
*(-12 + sp0) = unk_R4
memcpy(-44 + sp0, GMT_FUNCTABLE, 0x20) => ret_memcpy_FF01FFA8
gui_init_end() => ret_gui_init_end_FF01FFAC
msg_queue_receive(gui_main_struct.msg_queue /*off_0x38, 0x1C3C*/, -48 + sp0, 0x0, arg3) => ret_msg_queue_receive_FF01FFC4
gui_main_struct.counter /*off_0x4, 0x1C08*/ = -1 + gui_main_struct.counter /*off_0x4, 0x1C08*/
[...]

Reverse decompilationEdit

This is useful when normal decompilation fails (usually when you have to deal with huge monsters like IDLEHandler or AJ_CopyDataToStorage).

S PROP_SHUT

String references to ff2014d4 'PROP_SHUTTER_COUNTER [%d][%d]':

AJ_CopyDataToStorage+22892:
ff201390:	e28f2f4f 	add	r2, pc, #316	; *'PROP_SHUTTER_COUNTER [%d][%d]'
'PROP_SHUTTER_COUNTER [%d][%d]'

[...]
g ff201390
f201390:	e28f2f4f 	add	r2, pc, #316	; *'PROP_SHUTTER_COUNTER [%d][%d]'
ff201394:	e58d3000 	str	r3, [sp]
ff201398:	e5943004 	ldr	r3, [r4, #4]
ff20139c:	e3a01003 	mov	r1, #3
ff2013a0:	e3a00083 	mov	r0, #131	; 0x83
ff2013a4:	ebf99810 	bl	@DebugMsg	
[...]
bd ff2013a4
[...]
DebugMsg(132, 2, msg='copyDataToStorage eventID(%#x)Data(%d)size(%d)', *(arg0), arg0->off_0x8, arg3, unk_R4, unk_R5, ...)
if arg0 != 0:
    if *(arg0) <= 0x8005002D:
        if *(arg0) > 0x80030013:
            if *(arg0) <= 0x80040006:
                if *(arg0) <= PROP_HDMI_CHANGE:
                    if *(arg0) <= 0x80030029:
                        REGWRITE(PC, 4279483944 + 4**(arg0))
                        if EQ21(2147287020 + *(arg0)):
                            *(-40 + sp0) = arg0->off_0x8
                            DebugMsg(131, 3, msg='PROP_SHUTTER_COUNTER [%d][%d]', arg0->off_0x4, arg0->off_0x8, arg3, unk_R4, unk_R5, ...)
                            !!! Stack not restored !!!
                            !end
hex(21 - 2147287020)
'80030029'
#define PROP_SHUTTER_COUNTER 0x80030029 :)

Advanced useEdit

cp = range(0xff31695c, 0xff316970+1, 4)
cp
[4281428316L, 4281428320L, 4281428324L, 4281428328L, 4281428332L, 4281428336L]
emusym.print_cp(cp)
CODE PATH:
ff31695c:	e5940008 	ldr	r0, [r4, #8]
ff316960:	e3500007 	cmp	r0, #7
ff316964:	83a020d3 	movhi	r2, #211	; 0xd3
ff316968:	828f1f55 	addhi	r1, pc, #340	; *'GUI\\ShootInfo\\DlgShootOlcAFFrame.c'
ff31696c:	828f0f5d 	addhi	r0, pc, #372	; 0xff316ae8: pointer to 0x30
ff316970:	8bf3f3a9 	blhi	@assert_0	
cp = emusym.add_branch_info(cp)
print deco.decompile(cp[0], [cp])
SEQ(IF(-7 + MEM(8 + unk_R4), IFB(HI, SEQ(CALL(4281428336, 4278269980, 4281428712, 4281428676, 211, arg3, arg4, arg5, arg6, arg7), !end))))
print emusym.P.doprint(deco.decompile(cp[0], [cp]))
if unk_R4->off_0x8 > 7:
    assert_0(0xff316ae8: pointer to 0x30, 'GUI\\ShootInfo\\DlgShootOlcAFFrame.c', 0xd3) => ret_assert_0_FF316970
    !end

Also on Fandom

Random Wiki