Closed lwerdna closed 12 months ago
Related issue that envisions an authenticated function attribute: https://github.com/Vector35/binaryninja-api/issues/3856 Related issue: https://github.com/Vector35/binaryninja-api/issues/3997
Commit: https://github.com/Vector35/arch-arm64/commit/3847e619459195db64b5a1ea14a445dbe1c4e8ce
Instructions that sign pointers (PAC.*
), authenticate pointers (AUT.*
) and strip pointers (XPAC.*
) now, by default, will lift to nop, so not touching the pointer.
The instructions that were like "old instruction plus authentication" like BLRA.*
, .LDRA.*
, and RETA.*
just lift to "old instruction".
Here's a function using pacibsp
(add PAC to lr using key B and context/modifier sp) and corresponding retab
(return to lr after authenticating with key B). Left to right it's Disassembly, Low Level IL, Pseudo C:
before:
after:
EDIT: The below table is obsolete! I originally thought each instruction would be permanently converted, and the table would track the progress. Instead, the architecture now has this configurable, controlled by a preprocessor macro. And the default setting is non-intrinsic for the instructions whose intrinsic lift degrades readability.
These are all the instructions associated with PAC, along with an example encoding to demonstrate. Most are lifted as intrinsics and we need to move away from this and towards just the normal (non-authenticated) llil description of what the instructions do.
autda x22, x18
AUTDA_64P_dp_1src
LLIL_INTRINSIC([x22],__autda,[LLIL_REG.q(x22),LLIL_REG.q(x18)])
autdza x1
AUTDZA_64Z_dp_1src
LLIL_INTRINSIC([x1],__autda,[LLIL_REG.q(x1),LLIL_CONST.q(0x0)])
autdb x19, x3
AUTDB_64P_dp_1src
LLIL_INTRINSIC([x19],__autdb,[LLIL_REG.q(x19),LLIL_REG.q(x3)])
autdzb x1
AUTDZB_64Z_dp_1src
LLIL_INTRINSIC([x1],__autdb,[LLIL_REG.q(x1),LLIL_CONST.q(0x0)])
autia x26, x9
AUTIA_64P_dp_1src
LLIL_INTRINSIC([x26],__autia,[LLIL_REG.q(x26),LLIL_REG.q(x9)])
autiza x30
AUTIZA_64Z_dp_1src
LLIL_INTRINSIC([x30],__autia,[LLIL_REG.q(x30),LLIL_CONST.q(0x0)])
autib x18, x21
AUTIB_64P_dp_1src
LLIL_INTRINSIC([x18],__autib,[LLIL_REG.q(x18),LLIL_REG.q(x21)])
autizb x17
AUTIZB_64Z_dp_1src
LLIL_INTRINSIC([x17],__autib,[LLIL_REG.q(x17),LLIL_CONST.q(0x0)])
blr x12
BLR_64_branch_reg
LLIL_CALL(LLIL_REG.q(x12))
blraaz x7
BLRAAZ_64_branch_reg
LLIL_CALL(LLIL_REG.q(x7))
blraa xzr, sp
BLRAA_64P_branch_reg
LLIL_CALL(LLIL_CONST.q(0x0))
blrabz x13
BLRABZ_64_branch_reg
LLIL_CALL(LLIL_REG.q(x13))
blrab x4, sp
BLRAB_64P_branch_reg
LLIL_CALL(LLIL_REG.q(x4))
br x21
BR_64_branch_reg
LLIL_JUMP(LLIL_REG.q(x21))
braaz x7
BRAAZ_64_branch_reg
LLIL_JUMP(LLIL_REG.q(x7))
braa x25, x5
BRAA_64P_branch_reg
LLIL_JUMP(LLIL_REG.q(x25))
brabz x6
BRABZ_64_branch_reg
LLIL_JUMP(LLIL_REG.q(x6))
brab x23, x17
BRAB_64P_branch_reg
LLIL_JUMP(LLIL_REG.q(x23))
eret
ERET_64E_branch_reg
LLIL_INTRINSIC([],_eret,[]); LLIL_TRAP(0)
eretaa
ERETAA_64E_branch_reg
LLIL_INTRINSIC([],_eret,[]); LLIL_TRAP(0)
eretab
ERETAB_64E_branch_reg
LLIL_INTRINSIC([],_eret,[]); LLIL_TRAP(0)
ldraa x7, [x30, #-0x6b0]
LDRAA_64_ldst_pac
LLIL_SET_REG.q(x7,LLIL_LOAD.q(LLIL_ADD.q(LLIL_REG.q(x30),LLIL_CONST.q(0xFFFFFFFFFFFFF950))))
ldraa x7, [sp, #-0xf20]!
LDRAA_64W_ldst_pac
LLIL_SET_REG.q(sp,LLIL_ADD.q(LLIL_REG.q(sp),LLIL_CONST.q(0xFFFFFFFFFFFFF0E0))); LLIL_SET_REG.q(x7,LLIL_LOAD.q(LLIL_REG.q(sp)))
ldrab x27, [x17, #0x8d0]
LDRAB_64_ldst_pac
LLIL_SET_REG.q(x27,LLIL_LOAD.q(LLIL_ADD.q(LLIL_REG.q(x17),LLIL_CONST.q(0x8D0))))
ldrab x20, [x1, #0xac8]!
LDRAB_64W_ldst_pac
LLIL_SET_REG.q(x1,LLIL_ADD.q(LLIL_REG.q(x1),LLIL_CONST.q(0xAC8))); LLIL_SET_REG.q(x20,LLIL_LOAD.q(LLIL_REG.q(x1)))
pacda x9, x21
PACDA_64P_dp_1src
LLIL_INTRINSIC([x9],__pacda,[LLIL_REG.q(x9),LLIL_REG.q(x21)])
pacdza x5
PACDZA_64Z_dp_1src
LLIL_INTRINSIC([x5],__pacda,[LLIL_REG.q(x5),LLIL_CONST.q(0x0)])
pacdb x14, x3
PACDB_64P_dp_1src
LLIL_INTRINSIC([x14],__pacdb,[LLIL_REG.q(x14),LLIL_REG.q(x3)])
pacdzb x1
PACDZB_64Z_dp_1src
LLIL_INTRINSIC([x1],__pacdb,[LLIL_REG.q(x1),LLIL_CONST.q(0x0)])
pacga x1, xzr, x12
PACGA_64P_dp_2src
LLIL_INTRINSIC([x1],__pacga,[LLIL_CONST.q(0x0),LLIL_REG.q(x12)])
pacia x6, x14
PACIA_64P_dp_1src
LLIL_INTRINSIC([x6],__pacia,[LLIL_REG.q(x6),LLIL_REG.q(x14)])
paciza x21
PACIZA_64Z_dp_1src
LLIL_INTRINSIC([x21],__pacia,[LLIL_REG.q(x21),LLIL_CONST.q(0x0)])
pacib x29, x4
PACIB_64P_dp_1src
LLIL_INTRINSIC([x29],__pacib,[LLIL_REG.q(x29),LLIL_REG.q(x4)])
pacizb x14
PACIZB_64Z_dp_1src
LLIL_INTRINSIC([x14],__pacib,[LLIL_REG.q(x14),LLIL_CONST.q(0x0)])
ret x27
RET_64R_branch_reg
LLIL_RET(LLIL_REG.q(x27))
retaa
RETAA_64E_branch_reg
LLIL_RET(LLIL_REG.q(x30))
retab
RETAB_64E_branch_reg
LLIL_RET(LLIL_REG.q(x30))
xpacd xzr
XPACD_64Z_dp_1src
LLIL_INTRINSIC([xzr],__xpacd,[LLIL_CONST.q(0x0)])
xpaci x25
XPACI_64Z_dp_1src
LLIL_INTRINSIC([x25],__xpaci,[LLIL_REG.q(x25)])
A convenient list of these encodings is:
I will try to mark the status column with checkboxes as progress is made.