快手逆向-花指令实战分析

新的最新版armv8的,快手花指令脚本,本文为了学习安全思路,切勿做一些非法事情。

1.jnionload不能f5

libkwsgmain.so

在这里插入图片描述

2.手算花指令跳转

.text:00000000000462C4                 STP             X0, X1, [SP,#-32]!

.text:00000000000462C8                 STP             X2, X30, [SP,#16]

.text:00000000000462CC                 ADR             X1, dword_462EC

.text:00000000000462D0                 SUBS            X1, X1, #0xC

.text:00000000000462D4                 MOV             X0, X1

.text:00000000000462D8                 ADDS            X0, X0, #0x3C ; '<'

.text:00000000000462DC                 STR             X0, [SP,#24]

.text:00000000000462E0                 LDP             X2, X9, [SP,#16]

.text:00000000000462E4                 LDP             X0, X1, [SP],#0x20

.text:00000000000462E8                 BR              X9

导致不能f5的原因是在地址0x462E8,x9寄存器的值没有被ida计算出来

我们看x9是从0x462E0,相当于从[SP,#24],又因为在0x462DC是x0给予的。

所以我们搞清X0的来源,就可以算出来,x9的值了。

.text:00000000000462CC                 ADR             X1, dword_462EC
.text:00000000000462D0                 SUBS            X1, X1, #0xC
.text:00000000000462D4                 MOV             X0, X1
.text:00000000000462D8                 ADDS            X0, X0, #0x3C

可以得出X0 = 0x462EC -0xc + 0x3c = 0x4631c

在这里插入图片描述
这不是逗我吗,怎么全出来了

在这里插入图片描述
但是发现后面也有很多的花
在这里插入图片描述
那我们可以先写个python脚本

思路遍历所有的指令,如果当前指令是

.text:0000000000041688                 ADR             X1, qword_416A8

.text:000000000004168C                 SUBS            X1, X1, #0xC

.text:0000000000041690                 MOV             X0, X1

.text:0000000000041694                 ADDS            X0, X0, #0x3C ; '<'

第一条指令为x1,且下三条指令为 subs mov adds,这个时候就可以计算,x0的值,然后获取当前 0x41688 +0x7 *0x4 的位置是不是br

然后直接去替换

我记得之前ks花指令比这个复杂来着,不知道为啥变成这样了

附代码

3.写代码用idapatch

from capstone.arm64_const import *

import idaapi
import idc
import idautils
from capstone import *
from keystone import *
import ida_bytes
import keypatch
ks = Ks(KS_ARCH_ARM64, KS_MODE_LITTLE_ENDIAN)
md = Cs(CS_ARCH_ARM64, KS_MODE_LITTLE_ENDIAN)
kp = keypatch.Keypatch_Asm()
md.detail = True


def get_all_adr(code="ADR"):

    allAddr = []
 
    adr_count = 0
    for seg in idautils.Segments():
        
        start = idc.get_segm_start(seg)
        end = idc.get_segm_end(seg)
        
        for ea in idautils.Heads(start, end):


            insn = idaapi.insn_t()

            if idaapi.decode_insn(insn, ea):


                if insn.get_canon_mnem() == code:
                    adr_count += 1
                    is_fake_adr(ea)

    return allAddr





def is_fake_adr(ea):
    codelist = ida_bytes.get_bytes(ea, 0x100)
    for insn in md.disasm(codelist[0:4], ea):
        if insn.mnemonic == "adr" and len(insn.operands) > 0 and insn.operands[0].type == ARM64_OP_REG:
            if(insn.operands[0].reg - ARM64_REG_X0 == 1):

                subsFlag  =None
                addsFlag = None
                for subs_insn in md.disasm(codelist[4:8], 0):
                    if subs_insn.mnemonic =="subs":
                        subsFlag = subs_insn
                for adds_insn in md.disasm(codelist[3*4:3 *8], 0):
                    if adds_insn.mnemonic == "adds":
                        addsFlag = adds_insn
                if(subsFlag and addsFlag):
                    print(subsFlag.operands[2].type)
                    if(subsFlag.operands[2].type ==ARM64_OP_IMM and addsFlag.operands[2].type ==ARM64_OP_IMM):

                        x9Addr = insn.operands[1].imm -subsFlag.operands[2].imm + addsFlag.operands[2].imm
                        print(hex(x9Addr),hex(ea))
                        for br_insn in md.disasm(codelist[7 * 4:7 * 8], ea + 4*7):


                            if br_insn.mnemonic == "br":
                                print("addr",hex(ea + 4*7),hex(x9Addr))
                                kp.patch_code(ea + 4*7, "b " + hex(x9Addr), None, None, None,
                                                  None)





get_all_adr()

为了验证我们的patch是否有问题,从手机上替换了他,app正常运行,完美

4.4.总结

在这里插入图片描述
欢迎关注公众号:二进制科学

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二进制科学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值