在阅读了一篇博客文章后,我试图反汇编 BCM4366C [1] 的 ROM 映像,其中研究人员逆转了一些其他 Broadcom 芯片 [2]。我已经分析了Ghidra ROM映像,我试图找出malloc,memcpy,free和printf功能,但现在我在努力理解我认为是主要的malloc循环。我相信入口点malloc是 at 00012124,基于 Ghidra 发现的大量外部参照, wherer0设置为一个小的立即数,然后是指向该地址的分支,例如:
00018dcc 4f f4 a2 70 mov.w r0,#0x144
00018dd0 f9 f7 a8 f9 bl malloc ;; 00012124
在00012124有一个分支00011eb8,我相信是的胆量malloc功能:
LAB_00011eb8 XREF[2]: 00012126(j), 0001212c(j)
00011eb8 2d e9 f7 4f push { r0, r1, r2, r4, r5, r6, r7, r8, r9, r10, r1...
00011ebc 03 30 add r0,#0x3
00011ebe 4f f0 01 0b mov.w r11,#0x1
00011ec2 20 f0 03 04 bic r4,r0,#0x3
00011ec6 0b fa 01 f1 lsl.w r1,r11,r1
00011eca b1 f5 80 4f cmp.w r1,#0x4000
00011ece 34 bf itE cc
00011ed0 8b 46 mov.cc r11,r1
00011ed2 4f f4 80 4b mov.cs.w r11,#0x4000
00011ed6 90 f0 a7 f8 bl FUN_000a2028 undefined FUN_000a2028()
00011eda 39 4b ldr r3,[DAT_00011fc0] = 002007B8h
00011edc 00 22 mov r2,#0x0
00011ede bb f1 04 0f cmp.w r11,#0x4
00011ee2 38 bf it cc
00011ee4 4f f0 04 0b mov.cc.w r11,#0x4
00011ee8 d3 f8 00 a0 ldr.w r10,[r3,#0x0]=>DAT_002007b8
00011eec 15 46 mov r5,r2
00011eee 91 46 mov r9,r2
00011ef0 13 46 mov r3,r2
00011ef2 cb f1 00 01 rsb r1,r11,#0x0
00011ef6 0b f1 ff 3b add.w r11,r11,#0xffffffff
00011efa 01 91 str r1,[sp,#Stack[-0x2c]]
00011efc cd f8 00 b0 str.w r11,[sp,#0x0]=>Stack[-0x30]
LAB_00011f00 XREF[1]: 00011f4a(j)
00011f00 41 68 ldr r1,[r0,#0x4]
00011f02 19 b3 cbz r1,LAB_00011f4c
00011f04 d1 f8 00 80 ldr.w r8,[r1,#0x0]
00011f08 a0 45 cmp r8,r4
00011f0a 1d d3 bcc LAB_00011f48
00011f0c dd f8 04 b0 ldr.w r11,[sp,#Stack[-0x2c]]
00011f10 01 f1 08 07 add.w r7,r1,#0x8
00011f14 07 eb 08 0c add.w r12,r7,r8
00011f18 c4 eb 0c 06 rsb.w r6,r4,r12
00011f1c 0b ea 06 06 and.w r6,r11,r6
00011f20 be 42 cmp r6,r7
00011f22 11 d3 bcc LAB_00011f48
00011f24 dd f8 00 b0 ldr.w r11,[sp,#0x0]=>Stack[-0x30]
00011f28 1b ea 07 0f tst.w r11,r7
00011f2c 02 d0 beq LAB_00011f34
00011f2e f7 1b sub r7,r6,r7
00011f30 07 2f cmp r7,#0x7
00011f32 09 d9 bls LAB_00011f48
LAB_00011f34 XREF[1]: 00011f2c(j)
00011f34 c4 eb 08 07 rsb.w r7,r4,r8
00011f38 57 45 cmp r7,r10
00011f3a 05 d2 bcs LAB_00011f48
00011f3c 62 46 mov r2,r12
00011f3e 35 46 mov r5,r6
00011f40 67 b1 cbz r7,LAB_00011f5c
00011f42 ba 46 mov r10,r7
00011f44 81 46 mov r9,r0
00011f46 0b 46 mov r3,r1
LAB_00011f48 XREF[4]: 00011f0a(j), 00011f22(j),
00011f32(j), 00011f3a(j)
00011f48 08 46 mov r0,r1
00011f4a d9 e7 b LAB_00011f00
LAB_00011f4c XREF[1]: 00011f02(j)
00011f4c 48 46 mov r0,r9
[snip]
有一个循环进入 at00011f00并在 处反向跳转00011f4a,并在 处单次跳出循环00011f40。
令我困惑的行是循环 ( 00011f00)的第一行——这里的指令ldr r1,[r0,#0x4]将r0用作基地址,然后解引用r0+0x4到r1(因为[],指示立即偏移寻址)。但是,在r0加载到此之前我找不到任何指令,它似乎只在malloc调用站点加载了一个小的立即值(我认为这是调用者指定了他们想要分配的内存大小) . 除了 at 的“包装器”之外00012124,我在脑海中的执行跟踪中遇到的唯一其他代码块是 at 的分支00011ed6,并且那里的函数也没有触及r0。
循环在跳回开始之前移动r1到结束r0,此时ldr r1,[r0,#0x4]再次执行指令。基于此,我认为这个循环正在遍历空闲堆块的链表:每个堆块都有一个指向偏移量 0x4 处的下一个堆块的指针,该指针在循环开始时被检索。
指令00011f00实际上是否将大小取消引用为基地址?或者是r0在流程的早期写入,我看不到它在哪里发生?
此外,我很想知道我是否在理解分配器方面走在正确的轨道上,但如果您能帮助我完成这一ldr说明,我将不胜感激!🙏
谢谢 :)
[1] https://github.com/seemoo-lab/bcm_misc/blob/master/bcm4366c/rom.bin
[2] https://blog.quarkslab.com/reverse-engineering-broadcom-wireless-chipsets.html
编辑:FUN_000a2028定义为:
**************************************************************
* FUNCTION *
**************************************************************
undefined FUN_000a2028()
undefined r0:1 <RETURN>
undefined4 Stack[-0x4]:4 local_4 XREF[1]: 000a202e(W)
FUN_000a2028 XREF[2]: FUN_00011dc4:00011de0(c),
malloc:00011ed6(c)
000a2028 10 b5 push { r4, lr }
000a202a 02 4c ldr r4,[DAT_000a2034] = 00200418h
000a202c 24 68 ldr r4,[r4,#0x0]=>DAT_00200418
000a202e 01 94 str r4,[sp,#local_4]
000a2030 10 bd pop { r4, pc }