We’ve covered offsets with base previously. There is a variation of such offsets commonly used in position-independent code which can be handled easily with a little trick.
Let’s consider this ARM function from an ARM32 firmware:
ROM:00000058 ; int sub_58() ROM:00000058 sub_58 ; CODE XREF: sub_10A4:loc_50↑j ROM:00000058 ; DATA XREF: sub_8D40+20↓r ... ROM:00000058 ADR R0, off_88 ; R0 = 0x88 ROM:0000005C LDM R0, {R10,R11} ; R10 = 0x3ADC0, R11 = 0x3AE00 ROM:00000060 ADD R10, R10, R0 ; R10 = 0x3ADC0+0x88 ROM:00000064 SUB R7, R10, #1 ROM:00000068 ADD R11, R11, R0 ; R11 = 0x3AE00+0x88 ROM:0000006C ROM:0000006C loc_6C ; DATA XREF: sub_58+20↓o ROM:0000006C CMP R10, R11 ROM:00000070 BEQ sub_D50 ROM:00000074 LDM R10!, {R0-R3} ROM:00000078 ADR LR, loc_6C ROM:0000007C TST R3, #1 ROM:00000080 SUBNE PC, R7, R3 ROM:00000084 BX R3 ROM:00000084 ; End of function sub_58 ROM:00000084 ROM:00000084 ; --------------------------------------------------------------------------- ROM:00000088 off_88 DCD dword_3ADC0 ; DATA XREF: sub_58↑o ROM:00000088 ; sub_58+4↑o ROM:0000008C DCD off_3AE00
IDA has converted the values at addresses 88 and 8C to offsets because they happen to be valid addresses, but if you look at what the code does (I’ve added comments describing what happens), we’ll see that both values are added to the address from which they’re loaded (0x88), i.e. they’re relative to their own position (or self-relative).
To get the final value they refer to, we can use the action Edit > Operand type > Offset >Offset (user-defined) (shortcut Ctrl–R), and enter as the base either the address value (0x88), or, for the case of the value at 00000088
, the IDC keyword here
, which expands to the address under the cursor.
IDA calculates the final address and replaces the value with an expression which uses a special symbol .
, which denotes the current address on ARM:
ROM:00000088 off_88 DCD off_3AE48 - . ; DATA XREF: sub_58↑o
For the value at 0000008C
, here
will not work since it expands to 0x8c while the addend is 0x88. There are several options we can use:
- use the actual value
0x88
as the base - use the expression
here-4
which resolves to 0x88. - use
here
, but specify 4 in the Target delta field.
IDA will use the delta as an additional adjustment for the expression:
ROM:0000008C DCD byte_3AE88+4 - .
Now we can see what addresses the function is actually using and analyze it further.
See also:
Igor’s tip of the week #105: Offsets with custom base
Igor’s tip of the week #21: Calculator and expression evaluation feature in IDA