吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3567|回复: 5
上一主题 下一主题
收起左侧

[Android 原创] 基于IDA Python的OLLVM反混淆(三) 代码块的合并与无效指令的删除

[复制链接]
跳转到指定楼层
楼主
Shocker 发表于 2021-8-11 14:05 回帖奖励
本帖最后由 Shocker 于 2021-8-11 14:34 编辑

前言

本文是对上一篇文章
基于IDA Python的OLLVM反混淆(二) 实战腾讯御安全(模拟器)
的补充.

思路

  1. 合并代码块
  2. 修复call的偏移地址
  3. 去除残留的属于控制块的代码

实现过程

实验环境:ida7.5+雷电模拟器(64位)4

由上篇可知
原始指令最终被化简成了许多的代码块,且大多数代码块的结尾以jmp结束


我们就可以将jmp指令去除,将代码块合并在一起

代码块合并

#combine_block.py
import keypatch
from idaapi import *
import capstone
import struct

combine_blocks={}
ea_blcok_map={}
codes_map={}

def nop_block(block):
    nop_code=0x90
    for i in range(block.end_ea-block.start_ea):
        idc.patch_byte(block.start_ea+i,nop_code)

so_base=idaapi.get_imagebase()
fun_offset=0x25D0
f_blocks = idaapi.FlowChart(idaapi.get_func(so_base+fun_offset), flags=idaapi.FC_PREDS)
for block in f_blocks:
    if block.start_ea==block.end_ea:
        continue
    ea_blcok_map[block.start_ea]=block
    codes_map[block.start_ea]=get_bytes(block.start_ea,block.end_ea-block.start_ea)
    block_end=idc.prev_head(block.end_ea)
    if idc.print_insn_mnem(block_end).startswith('j'):
        next_block=get_operand_value(block_end,0)
        combine_blocks[block.start_ea]=next_block
    else:
        combine_blocks[block.start_ea]=block.end_ea
    # 将所有块nop后再将原始指令连接    
    nop_block(block)

first_block=so_base+fun_offset
wirte_offect=0

while True:
    if wirte_offect==0:
        block=ea_blcok_map[first_block]
    else:
        block=ea_blcok_map[next_block]

    codes=codes_map[block.start_ea]
    md=capstone.Cs(capstone.CS_ARCH_X86,capstone.CS_MODE_32)
    for code in md.disasm(codes,block.start_ea):
        if code.mnemonic=='jmp' or code.mnemonic.startswith('cmov') or code.mnemonic=='nop': #排除这些指令
            continue
        block_bytes=bytes(code.bytes)
        if code.mnemonic=='call':
            if code.op_str.startswith('0x'):
                called_addr=int(code.op_str,16)
                fix_addr=called_addr-fun_offset-wirte_offect-5
                fix_bytes=struct.pack('i',fix_addr)
                block_bytes=bytes(code.bytes[0:1])+fix_bytes
        print('combine_block:0x%x'%block.start_ea)
        patch_bytes(first_block+wirte_offect,block_bytes)
        wirte_offect=wirte_offect+len(block_bytes)

    if block.start_ea in combine_blocks:     
        next_block=combine_blocks[block.start_ea]
        if not next_block in ea_blcok_map:
            break
    else:
        break

    # print('0x%x,0x%x'%(key,combine_blocks[key]))

合并后的流程图


可以看到,还有许多属于控制块的指令没有去除

去除混淆指令

去除混淆指令原理基于
x86反混淆IDA Python脚本 (一)
反复运行该脚本直到无新指令被patch,手动删除一些无效的内存指令
最后执行combine_block.py脚本去除所有nop指令
去混淆的代码片段如下所示

相关示例代码见
https://github.com/PShocker/de-ollvm/

免费评分

参与人数 4威望 +1 吾爱币 +23 热心值 +3 收起 理由
qtfreet00 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
S11ence + 1 + 1 用心讨论,共获提升!
a3586597 + 1 用心讨论,共获提升!
nevinhappy + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
wushaoye 发表于 2021-8-11 16:08
学习学习
3#
S11ence 发表于 2021-8-11 16:33
4#
bhwxha 发表于 2021-8-11 17:55
可否基于ARM再写几篇文章?
腾讯御安全似乎是安卓端的加固,安卓基本是ARM
头像被屏蔽
5#
sincisss 发表于 2021-8-11 18:57
提示: 作者被禁止或删除 内容自动屏蔽
6#
wangjiuye 发表于 2021-8-11 19:13
每日学习一章。学习学习
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-3-28 18:29

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表