w_m0zart
w_m0zart

Reputation: 1

arm cbz instruction with apparent always non-zero register value

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

Answers (0)

Related Questions