Reputation: 1
While analyzing a 3d-printer firmware (From Flashforge) with ghidra, I stumbled upon following arm thumb code:
...
LAB_0012a734: XREF[2]: 0012a808(j), 0012a810(j)
0012a734 06 9b ldr r3,[sp,#local_18]
0012a736 a3 f1 0c 00 sub.w r0,r3,#0xc
0012a73a a0 42 cmp r0,r4
0012a73c 69 d1 bne LAB_0012a812
...
...
LAB_0012a806: XREF[1]: 0012a85a(j)
0012a806 00 2a cmp r2,#0x0
0012a808 94 dc bgt LAB_0012a734
0012a80a 05 a9 add r1,sp,#0x14
0012a80c f9 f6 f6 ea blx <EXTERNAL>::std::basic_string<char,std::char_t
0012a810 90 e7 b LAB_0012a734
LAB_0012a812: XREF[1]: 0012a73c(j)
0012a812 43 f2 40 72 movw r2,#0x3740
0012a816 c0 f2 02 02 movt r2,#0x2
0012a81a 8a b1 cbz r2,LAB_0012a840
0012a81c 04 3b subs r3,#0x4
0012a81e bf f3 5f 8f dmb #0x1f
LAB_0012a822: XREF[1]: 0012a82e(j)
0012a822 53 e8 00 2f ldrex r2,[r3,#0x0]
0012a826 51 1e subs r1,r2,#0x1
0012a828 43 e8 00 14 strex r4,r1,[r3,#0x0]
0012a82c 00 2c cmp r4,#0x0
0012a82e f8 d1 bne LAB_0012a822
0012a830 bf f3 5f 8f dmb #0x1f
...
The cbz
instruction at 0012a81a
compares register value r2
and branches to LAB_0012a840
if the value is zero.
In the case from above r2
gets the value 0x23740
at 12a812/12a816
and thus will never be zero. The code is also not self-modifying. The movw/movt instructions are not skipped either, since there is no branch instruction which would go directly to 12a81a
.
I verified the instructions with a debugger, but since it looks so obvious, it does exactly what is programmed. r2 is never zero.
Might this be a safeguard against a nullpointer (Which can obviously never happen though)?
So my question is, does anyone know what the purpose of the cbz instruction could be?
Upvotes: 0
Views: 74