sub_18AB0(v21, v20);


__int64 __usercall sub_18AB0@<X0>(__int64 a1@<X8>)
{
  __int64 v2; // x20
  __int64 v3; // x0
  char v5[24]; // [xsp+8h] [xbp-88h] BYREF
  char s[16]; // [xsp+20h] [xbp-70h] BYREF
  __int128 v7; // [xsp+30h] [xbp-60h] BYREF
  __int64 v8; // [xsp+48h] [xbp-48h] BYREF
  __int64 v9; // [xsp+50h] [xbp-40h]
  __int64 v10; // [xsp+58h] [xbp-38h]

  v10 = *(_QWORD *)(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40);
  sub_18D30();
  .........
  .......

可以看到sub_18AB0签名ida反汇编的不正确,传入了两个参数,但只显示了一个。这里可以改一下,改成sub_18AB0@(__int64 a1, _int64 a2)
按tab键看下汇编代码

.text:0000000000013638                 BL              sub_1391C
.text:000000000001363C                 ADD             X8, SP, #0xC0+var_90
.text:0000000000013640                 ADD             X0, SP, #0xC0+var_A8
.text:0000000000013644                 MOV             X1, SP
.text:0000000000013648                 BL              sub_18AB0

可以看到sub_18AB0传入参数是两个x0和x1,(arm64 abi调用约定函数的第 1~8 个参数,固定依次使用 X0、X1、X2、X3、X4、X5、X6、X7 这 8 个寄存器传递,多于8个时候才会使用栈)
sub_18AB0我们hook发现传参是传入了两个字符串,返回参数没有看出来什么价值,因为x8在arm64比较特殊,返回的内容大于16字节就用x8来存储返回内容的地址
,我们又hook了x8寄存器,发现x8寄存器里记录了返回的地址,通过hexdump(ptr(this.arg8).add(Process.pointerSize *2).readPointer()); 发现里面存储了加密的字符串。
我们进到方法里面看下

.text:0000000000018AB0 ; __unwind { // __gxx_personality_v0
.text:0000000000018AB0                 SUB             SP, SP, #0xA0
.text:0000000000018AB4                 STR             X23, [SP,#0x90+var_30]
.text:0000000000018AB8                 STP             X22, X21, [SP,#0x90+var_20]
.text:0000000000018ABC                 STP             X20, X19, [SP,#0x90+var_10]
.text:0000000000018AC0                 STP             X29, X30, [SP,#0x90+var_s0]
.text:0000000000018AC4                 ADD             X29, SP, #0x90
.text:0000000000018AC8                 MRS             X22, #3, c13, c0, #2
.text:0000000000018ACC                 MOV             X19, X8          ;因为结果在x8里面,所以我们看x8
.text:0000000000018AD0                 LDR             X8, [X22,#0x28]
.text:0000000000018AD4                 STUR            X8, [X29,#var_38]
.text:0000000000018AD8                 ADD             X8, SP, #0x90+var_88
.text:0000000000018ADC                 BL              sub_18D30
.text:0000000000018AE0                 ADRP            X21, #y_ptr@PAGE
.text:0000000000018AE4                 LDR             X21, [X21,#y_ptr@PAGEOFF]
.text:0000000000018AE8                 STP             XZR, XZR, [SP,#0x90+var_48]
.text:0000000000018AEC                 ADRP            X23, #x_ptr@PAGE
.text:0000000000018AF0                 LDR             W8, [X21]
.text:0000000000018AF4                 LDR             X23, [X23,#x_ptr@PAGEOFF]
.text:0000000000018AF8                 CMP             W8, #0xA
.text:0000000000018AFC                 B.LT            loc_18B10
.text:0000000000018B00                 LDR             W8, [X23]
......
......
.text:0000000000018CAC                 MOV             X1, X20 ; format
.text:0000000000018CB0                 BL              .sprintf
.text:0000000000018CB4                 LDRB            W2, [SP,#0x90+var_3A]
.text:0000000000018CB8                 ADD             X0, X23, #0x1C ; s
.text:0000000000018CBC                 MOV             X1, X20 ; format
.text:0000000000018CC0                 BL              .sprintf
.text:0000000000018CC4                 LDRB            W2, [SP,#0x90+var_39]
.text:0000000000018CC8                 ADD             X0, X23, #0x1E ; s
.text:0000000000018CCC                 MOV             X1, X20 ; format
.text:0000000000018CD0                 BL              .sprintf
.text:0000000000018CD4                 ADD             X1, SP, #0x90+s
.text:0000000000018CD8                 MOV             W2, #0x20 ; ' '
.text:0000000000018CDC                 MOV             X0, X19
.text:0000000000018CE0                 BL              sub_19248
.text:0000000000018CE4                 ADD             X0, SP, #0x90+var_88
.text:0000000000018CE8                 BL              sub_12CF4
.text:0000000000018CEC                 LDR             X8, [X22,#0x28]
.text:0000000000018CF0                 LDUR            X9, [X29,#var_38]
.text:0000000000018CF4                 CMP             X8, X9
.text:0000000000018CF8                 B.NE            loc_18D14
.text:0000000000018CFC                 LDP             X29, X30, [SP,#0x90+var_s0]
.text:0000000000018D00                 LDP             X20, X19, [SP,#0x90+var_10]
.text:0000000000018D04                 LDP             X22, X21, [SP,#0x90+var_20]
.text:0000000000018D08                 LDR             X23, [SP,#0x90+var_30]
.text:0000000000018D0C                 ADD             SP, SP, #0xA0
.text:0000000000018D10                 RET
.text:0000000000018D14 ; ---------------------------------------------------------------------------
.text:0000000000018D14
.text:0000000000018D14 loc_18D14                               ; CODE XREF: sub_18AB0+248↑j
.text:0000000000018D14                 BL              .__stack_chk_fail
.text:0000000000018D18 ; ---------------------------------------------------------------------------
.text:0000000000018D18                 B               loc_18D1C
.text:0000000000018D1C ; ---------------------------------------------------------------------------
.text:0000000000018D1C
.text:0000000000018D1C loc_18D1C                               ; CODE XREF: sub_18AB0+268↑j
.text:0000000000018D1C                 MOV             X19, X0
.text:0000000000018D20                 ADD             X0, SP, #0x90+var_88
.text:0000000000018D24                 BL              sub_12CF4
.text:0000000000018D28                 MOV             X0, X19
.text:0000000000018D2C                 BL              ._Unwind_Resume
.text:0000000000018D2C ; } // starts at 18AB0
.text:0000000000018D2C ; End of function sub_18AB0
.text:0000000000018D2C
.text:0000000000018D30
.text:0000000000018D30 ; =============== S U B R O U T I N E =======================================

因为结果在x8里面,所以我们看x8,发现x8在一开始的时候赋值给了x19,而x19在下面调用处,x0被赋值为x19,x0作为了sub_19248参数,很可疑,我们再去hook这个函数。

补充:

只要值被放进 X19–X28,它就从‘临时值’升级成‘逻辑对象’了

X8 不是“返回值”,而是“返回值将要写入的地方”

所以它在函数一开始就必须是有效的

Scratch Register (X0-X15) 就是工地上的临时工,干完这票就走,随时可能被换掉;

Callee-Saved Register (X19-X29) 就是公司的正式员工,稳定性强,负责核心业务。

x8三大用处:

1.间接返回:

ABI 规定:

- 调用者先分配内存

- 地址放在 X8

- 被调用函数把结果写到 [X8]

X8 放的是“返回值地址”,不是返回值本身

2.临时 scratch 寄存器

- 编译器爱用

- 调用后随时可被覆盖

3.JNI / C++ 内部惯用法

BL some_func
MOV X19, X8

通常意味着:
– 返回的是 对象

- 通过 X8 间接返回

- 然后被“升级”为长期变量(X19)

在 ARM64 ABI 里:

寄存器 含义
X0–X7 参数 / 返回值(调用后不保证保存)
X8 临时寄存器 / 间接返回值 / scratch
X19–X28 被调用者保存(callee-saved)

x8随时可能被下一个函数调用改掉
X19:跨函数调用仍然稳定

var sub_18AB0 = base.add(0x18AB0);
Inteceptor.attach(sub_18AB0, {
    onEnter:function(args){
        this.arg8 = this.context.x8;
        console.log("sub_18AB0 onEnter: arg0:", ptr(args[0]).readCString(), "  arg1:"ptr(args[1]).readCString(), "  arg8:\n", hexdump(this.arg8))
    }, onLeave: function(retVal){
        console.log("sub_18AB0 onLeave:\n", hexdump(retVal), "  arg8:\n", hexdump(this.arg8))
    }
})
分类: app逆向

0 条评论

发表回复

Avatar placeholder

您的邮箱地址不会被公开。 必填项已用 * 标注

站点统计

  • 文章总数:327 篇
  • 分类总数:20 个
  • 标签总数:193 个
  • 运行天数:1546 天
  • 访问总数:919440 人次

浙公网安备33011302000604

辽ICP备20003309号