пятница, 12 июня 2020 г.

arm64 pc-relative literals

Lets see for example non-exported function function SepInitializeCodeIntegrity from arm64 kernel:
  STP             X19, X20, [SP,#-0x20+var_10]!
  STP             X21, X22, [SP,#0x10+var_s0]
  STR             X23, [SP,#0x10+var_s10]
  STP             X29, X30, [SP,#0x10+var_20]!
  MOV             X29, SP
  ADRP            X8, #SeCiCallbacks@PAGE
  ADD             X20, X8, #SeCiCallbacks@PAGEOFF
  ADD             X8, X20, #4
  MOV             W21, #6
  ADD             X9, X8, #0xC0

loc_1406A9C90                           ; CODE XREF: SepInitializeCodeIntegrity+30 j
  STP             XZR, XZR, [X8],#0x10
  CMP             X8, X9
  B.NE            loc_1406A9C90
  STR             WZR, [X8]
  MOV             W9, #0xD0
  LDR             X8, =0xA000007

qword_1406A9D30 DCQ 0xA000007


As you can see all DWORD constants under arm64 stored in some place after function, so you sure can find address 1406A9D30 but how to find function which using this constant? Instruction ldr can be located in range of 1Mb from this address

Right answer - we can use .pdata section. Under arm64 data in this section looks like:
struct pdata_item
{
  DWORD off;
  DWORD seh_off;
};

and they already sorted by offset, so we can use some kind of binary search - for example I used std::lower_bound
So algo for search by constants in arm64 code is simple:
  • find address of some constant in desired section
  • find address of function from .pdata section
  • disasm this function
  • PROFIT

Комментариев нет:

Отправить комментарий