in figure 10-33.
Figure 10- 33 Mark different SPs
Before and after the execution of “PUSH {R4-R7,LR}”, the values of SP are SP1 and SP2
respectively, can you understand? Next, we will try to deduce how SP changes instruction by
instruction.
“PUSH {R4-R7,LR}” pushes 5 registers, i.e. R4, R5, R6, R7 and LR into stack. Every register
is 32-bit i.e. 4 bytes. Since the ARM stack is full descending, therefore SP2 = SP1 - 5 * 0x4 = SP1 -
0x14. “ADD R7, SP, #0xC” is equivalent to R7 = SP2 + 0xC, which has no influence on SP. The
value of var_10 in “STR.W R8, [SP,#0xC+var_10]!” is -0x10, so this instruction equals to
“STR.W R8, [SP,#-4]”, i.e. *(SP2 - 0x4) = R8 and this instruction doesn’t have impact on SP
either. “SUB SP, SP, #4” equals to SP3 = SP2 - 0x4. According to our marking rules, 13th data
source A is *(SP2 + 0x14). No instruction inside sub_26984444 has written to this address before
“LDR.W R8, [R7,#8]”, so the value of *(SP2 + 0x14) must come from the caller of
sub_26984444. Similarly, R1 is read without being written inside sub_26984444, it must also
come from the caller of sub_26984444, right? If you are still confused, please review this
paragraph until you understand it clearly, and then you’re allowed to continue.
Alright, both the 13th data source A and the 11th data source B come from the caller of
sub_26984444. So our next specific task is to find the 14th data source A and the 12th data source
B in the caller of sub_26984444.
Reinput the recipient’s address, set a breakpoint at the beginning of sub_26984444, then