【总结】对大量函数进行trace调用流程+国际AIS3题

news2024/11/16 18:06:01

现在混淆的主要目的之一就有让逆向分析人员不清楚函数的调用流程,给你一堆函数,加了高强度的OLLVM,更不能看了。那么Trace跟踪技术就显得很重要的,如果清楚了函数调用流程,那么逐个分析,距离成功不就很快了。

万事开头难,逆向程序难在不知道从哪开始。

前几天做了一道AIS3的题目,内含50个加密函数,加密的流程很简单,关键是对这50个加密函数进行了ollvm控制流平坦化魔改(去除也很简单),主要是想抛砖引玉,锻炼和练习trace的技术。这样在以后遇到高强度的混淆干扰也能有一战的能力。

题目附件如下:

[stateful]

本文的重点在于总结trace技巧,题目本身不算很难。

分析

打开题目,进入main函数

图片

{width="5.75in" height="3.4270833333333335in"}

发现逻辑不是很难,进入state_machine函数

好家伙,一大坨

图片

{width="5.75in" height="3.4166666666666665in"}

尝试使用OBPO插件去除,发现直接卡死。使用D810也是卡死。

更高级的玩法使用Unicorn进行去除,类似deflat

本文的重点是在不去除平坦化的前提下去trace函数调用流程

图片

{width="5.75in" height="3.09375in"}

发现有50多个state函数,并且每个函数的功能很简单,我们的目的是:

trace每一个函数,并在梳理调用流程的过程中,输出关键的加密流程,从而写出解密流程

注意调试的时候,记得传入参数

图片

{width="5.75in" height="2.4895833333333335in"}

Trace

方法一:手动trace

最简单粗暴的方法,对每一个state函数下断点,然后运行程序,逐一拿到调用流程。

如果函数过多,这种方法就不太行了

图片

{width="5.75in" height="2.1770833333333335in"}

最终笔者运行拿到了调用的流程


 a1[14] += a1[35] + a1[8];
  a1[9] -= a1[2] + a1[22];
  *a1 -= a1[18] + a1[31];
  a1[2] += a1[11] + a1[8];
  a1[6] += a1[10] + a1[41];
  a1[14] -= a1[32] + a1[6];
  a1[16] += a1[25] + a1[11];
  a1[31] += a1[34] + a1[16];
  a1[9] += a1[11] + a1[3];
  a1[17] += *a1 + a1[7];
  a1[5] += a1[40] + a1[4];
  a1[37] -= a1[29] + a1[3];
  a1[23] += a1[7] + a1[34];
  a1[39] -= a1[25] + a1[38];
  a1[27] += a1[18] + a1[20];
  a1[20] += a1[19] + a1[24];
  a1[15] += a1[22] + a1[10];
  a1[30] -= a1[33] + a1[8];
  a1[1] -= a1[29] + a1[13];
  a1[19] += a1[10] + a1[16];
  *a1 += a1[33] + a1[16];
  a1[36] += a1[11] + a1[15];
  a1[24] += a1[20] + a1[5];
  a1[7] += a1[21] + *a1;
  a1[1] += a1[15] + a1[6];
  a1[30] -= a1[13] + a1[2];
  a1[1] += a1[16] + a1[40];
  a1[31] += a1[1] + a1[16];
  a1[32] += a1[5] + a1[25];
  a1[13] += a1[25] + a1[28];
  a1[7] += a1[10] + *a1;
  a1[21] += a1[34] + a1[15];
  a1[21] -= a1[13] + a1[42];
  a1[18] += a1[29] + a1[15];
  a1[4] += a1[7] + a1[25];
  *a1 += a1[28] + a1[31];
  a1[2] += a1[34] + a1[25];
  a1[13] += a1[26] + a1[8];
  a1[41] -= a1[3] + a1[34];
  a1[37] += a1[27] + a1[18];
  a1[4] += a1[27] + a1[25];
  a1[23] += a1[30] + a1[39];
  a1[18] += a1[26] + a1[31];
  a1[10] -= a1[12] + a1[22];
  a1[4] += a1[6] + a1[22];
  a1[37] += a1[12] + a1[16];
  a1[15] += a1[40] + a1[8];
  a1[17] += a1[38] + a1[24];
  a1[8] += a1[14] + a1[16];
  a1[5] += a1[37] + a1[20];

其实手都快残了

方法二:IDA-trace

程序动态调试的时候才可以使用trace功能

图片

{width="5.75in" height="2.40625in"}

图片

{width="5.75in" height="2.8854166666666665in"}

IDA自动进行trace跟踪,然后稍等片刻

图片

{width="5.75in" height="2.6041666666666665in"}

可以发现成功的trace了调用了流程

图片

{width="5.75in" height="2.4375in"}

但是有一点不方便的是,有了调用流程,但是我们还要进入每一个函数,提取加密的流程才行。

IDA快捷键Ctrl+F5可以导出整个程序的伪代码

然后进一步提取和分析

图片

{width="5.75in" height="3.6875in"}

这里可以使用IDA-python自动下断点


  Go
  import idc
  
  bpt_addr = 0x5599F331ADA7
  bpt_size=1
  idaapi.add_bpt(bpt_addr,bpt_size)
  print("Final")

当然还不够,我们要达到的效果是,触发断点然后输出相关加密信息到output函数窗口,就是有断点回调函数


  import idaapi
  
  # 定义回调函数
  def my_bpt_callback(bptno):
  print("Breakpoint %d hit!" % bptno)
  
  # 添加断点
  bpt_addr = 0x5599F331ADA7
  bpt_size=1
  bpt = idaapi.add_bpt(bpt_addr,bpt_size)
  
  # 设置断点回调
  idaapi.add_bpt_chngev_cnd(bpt, idaapi.BPT_EXEC, my_bpt_callback)
  #设置执行断点

-----------------------------------------------------------------------

idaapi.BPT_EXEC 表示执行事件

方法三:trace_natives

https://github.com/Pr0214/trace_natives

按照说明,进行输出,发现是这样的效果(IDA中,Edit-Plugins-traceNatives)

图片

{width="5.75in" height="1.125in"}

解密

有了调用流程,剩下的就很简单了


 #define _CRT_SECURE_NO_WARNINGS
  #include <stdio.h>
  #include <iostream>
  
  int main() {
  unsigned char a1[] =
  {
  0x0F, 0x77, 0xEC, 0x33, 0x44, 0x16, 0x13, 0x59, 0x1D, 0x42,
  0x84, 0x75, 0x5F, 0xE4, 0x83, 0xC0, 0x3B, 0xC1, 0x95, 0xCF,
  0xDB, 0x33, 0x6C, 0xD2, 0xED, 0x72, 0x5F, 0x0D, 0x74, 0x41,
  0x5B, 0x73, 0xA0, 0x33, 0x53, 0x24, 0x02, 0x59, 0x74, 0x60,
  0x33, 0xCC, 0x7D
  };
  
  
  a1[5] -= a1[37] + a1[20];
  a1[8] -= a1[14] + a1[16];
  a1[17] -= a1[38] + a1[24];
  a1[15] -= a1[40] + a1[8];
  a1[37] -= a1[12] + a1[16];
  a1[4] -= a1[6] + a1[22];
  a1[10] += a1[12] + a1[22];
  a1[18] -= a1[26] + a1[31];
  a1[23] -= a1[30] + a1[39];
  a1[4] -= a1[27] + a1[25];
  a1[37] -= a1[27] + a1[18];
  a1[41] += a1[3] + a1[34];
  a1[13] -= a1[26] + a1[8];
  a1[2] -= a1[34] + a1[25];
  *a1 -= a1[28] + a1[31];
  a1[4] -= a1[7] + a1[25];
  a1[18] -= a1[29] + a1[15];
  a1[21] += a1[13] + a1[42];
  a1[21] -= a1[34] + a1[15];
  a1[7] -= a1[10] + *a1;
  a1[13] -= a1[25] + a1[28];
  a1[32] -= a1[5] + a1[25];
  a1[31] -= a1[1] + a1[16];
  a1[1] -= a1[16] + a1[40];
  a1[30] += a1[13] + a1[2];
  a1[1] -= a1[15] + a1[6];
  a1[7] -= a1[21] + *a1;
  a1[24] -= a1[20] + a1[5];
  a1[36] -= a1[11] + a1[15];
  *a1 -= a1[33] + a1[16];
  a1[19] -= a1[10] + a1[16];
  a1[1] += a1[29] + a1[13];
  a1[30] -= a1[33] + a1[8];
  a1[15] -= a1[22] + a1[10];
  a1[20] -= a1[19] + a1[24];
  a1[27] -= a1[18] + a1[20];
  a1[39] += a1[25] + a1[38];
  a1[23] -= a1[7] + a1[34];
  a1[37] += a1[29] + a1[3];
  a1[5] -= a1[40] + a1[4];
  a1[17] -= *a1 + a1[7];
  a1[9] -= a1[11] + a1[3];
  a1[31] -= a1[34] + a1[16];
  a1[16] -= a1[25] + a1[11];
  a1[14] += a1[32] + a1[6];
  a1[6] -= a1[10] + a1[41];
  a1[2] -= a1[11] + a1[8];
  *a1 += a1[18] + a1[31];
  a1[9] += a1[2] + a1[22];
  a1[14] -= a1[35] + a1[8];
  
  printf("%s", a1);
  return 0;
  }

得到flag


AIS3{4re_YOu_@_sTATEfUl_0r_StA03L3S$_ctF3R}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1480751.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

方格分割644--2017蓝桥杯

1.用dfs解决&#xff0c;首先这题的方格图形就很像一个走迷宫的类型&#xff0c;迷宫想到dfs&#xff0c;最中心点视为起点&#xff0c;起点有两个小人在这个方格里面对称行动&#xff0c;直到走出迷宫&#xff08;一个人走出来了另一个人就也走出来了&#xff0c;而走过的点会…

亚信安慧AntDB:打破数据孤岛,实现实时处理

AntDB数据库以其独特的创新能力在分布式数据库领域引领潮流。其中&#xff0c;融合统一与实时处理是其两大核心创新能力&#xff0c;为其赢得广泛关注与赞誉。融合统一意味着AntDB能够将多种不同类型的数据库融合为一体&#xff0c;实现数据的统一管理与处理&#xff0c;极大地…

NC65 rest接口 开发 NC65接口开发

一、在对应模块META-INF下编写 xxx.rest 文件,也要放在Home里对应的目录下。 二、开发接口&#xff0c;继承extends AbstractUAPRestResource&#xff0c;&#xff08;有的项目会继承别的方法如&#xff1a;AbstractNCCRestResource&#xff0c;MTFRestResource&#xff1b;有…

公司招嵌入式开发岗位,为什么感觉一年比一年难?

最近看到一个问题&#xff1a; 是一个HR在吐槽招不到嵌入式开发的人才。 这句话&#xff0c;难免会误导一些想入行嵌入式的同学&#xff0c;卧槽&#xff0c;这么缺人?赶紧冲&#xff01; 哼次哼次学完一堆技术栈&#xff0c;一投简历&#xff0c;一个面试机会都没有。 这就是…

详解字符串函数<string.h>(上)

1. strlen函数的使用和模拟实现 size_t strlen(const char* str); 1.1 函数功能以及用法 字符串长度 strlen函数的功能是计算字符串的长度。在使用时&#xff0c;要求用户传入需要计算长度的字符串的起始位置&#xff0c;并返回字符串的长度。 #include <stdio.h> #…

CC攻击与DDoS攻击有什么区别?如何进行有效防护?

CC攻击的前身是一个名为Fatboy攻击程序&#xff0c;而之所以后来人们会成为CC&#xff0c;是因为DDoS攻击发展的初期阶段&#xff0c;绝大部分DDoS攻击都能被业界熟知的“黑洞”&#xff08;collapsar&#xff0c;一种安全防护产品&#xff09;所抵挡&#xff0c;CC攻击的诞生就…

NFTScan NFT API 在 Web3 钱包追踪器上的开发应用

Web3 钱包追踪器是通过整合区块链数据 API&#xff0c;为加密资产投资者提供全面的钱包分析和追踪工具。用户可以利用钱包追踪器跟踪特定钱包地址的资产总额和交易情况&#xff0c;分析历史交易发现交易趋势&#xff0c;设置资产价格警报&#xff0c;生成钱包报告&#xff0c;同…

C++二叉搜树的实现(递归和非递归)

目录 1.什么是二叉搜索树 2.二叉搜索树的查找 3.二叉搜索树插入 4.二叉搜索树的删除 1.删除的节点只有左子树或者右子树 2.删除节点左右子树都有的情况 5.代码 1.什么是二叉搜索树 左节点的值小于根节点 右节点大于根节点 左右子树也满足上面两个条件 例&#xff1a;…

Liberod的License申请

Liberod的License申请 找到license申请的路径 查找C盘的磁盘序列号 键盘的win+R,输入cmd 输入vol,然后回车 图中的DiskID就是填写你C盘序列号的位置,填写完成后点击Register,几秒钟后会提示你,预计45分钟后会发送到你的邮箱

绍兴市新昌县人大一行莅临迪捷软件走访考察

2024年2月29日下午&#xff0c;绍兴市新昌县人大常委会副主任王敏慧一行莅临迪捷软件走访考察&#xff0c;绍兴市委科创委副主任、科创走廊建设领导小组副组长、市人大一级巡视员王继岗&#xff0c;绍兴市科技局副局长、科创走廊建设办公室常务副主任梁枫陪同。 王主任一行听取…

LabVIEW起重机工作参数远程监测系统

LabVIEW起重机工作参数远程监测系统 随着起重机技术的持续发展&#xff0c;对其工作参数的实时监控需求日益增加。设计了一个基于LabVIEW和TBox的起重机工作参数远程监测系统&#xff0c;能够实现起重机工作参数的实时采集、传输、解析和显示&#xff0c;有效提升起重机的性能…

2024中国5G随身WiFi十大品牌排行榜,20245G随身口碑排行榜,5G随身WiFi2024最新款!5G随身WiFi推荐测评

【中国品牌网中国3C质量评测中心权威榜单联合发布】 第一名&#xff1a;格行5G随身WiFi&#xff1a; 优点&#xff1a;随身WiFi行业的头部和领跑品牌&#xff0c;15年专业物联网行业经验&#xff0c;格行在技术研发、产品创新和客户服务方面具有很高的口碑&#xff0c;被业内…

VR虚拟现实技术应用到猪抗原体检测的好处

利用VR虚拟仿真技术开展猪瘟检测实验教学确保生猪产业健康发展 为了有效提高猪场猪瘟防控意识和检测技术&#xff0c;避免生猪养殖业遭受猪瘟危害&#xff0c;基于VR虚拟仿真技术开展猪瘟检测实验教学数据能大大推动基层畜牧养殖业持续稳步发展保驾护航。 一、提高实验效率 VR虚…

SpringBoot整合rabbitmq-直连队列,没有交换机(一)

说明&#xff1a;本文章只是springboot和rabbitmq的直连整合&#xff0c;只使用队列生产和消费消息&#xff0c;最简单整合&#xff01; 工程图&#xff1a; A.总体pom.xml <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://…

开发一个圈子社交系统有哪些特点

1.以兴趣聚合&#xff1a;圈子社交系统的核心是以共同的兴趣或爱好为纽带&#xff0c;将用户聚集在一起。这样的设计使得用户能够迅速找到与自己有共同话题和兴趣的人&#xff0c;从而建立深度联系。 2.个性化体验&#xff1a;系统会根据用户的喜好和行为&#xff0c;智能推荐…

【Vue】更换浏览器默认 logo

更换浏览器默认logo为自定义图片 一. 浏览器默认 logo二. 替换为自定义logo三. 步骤3.1 转换大小3.1.1 查看图片尺寸3.1.2 修改尺寸&#xff08;为32px 32px&#xff09; 3.2 替换成功 一. 浏览器默认 logo 二. 替换为自定义logo 三. 步骤 3.1 转换大小 将自定义 logo 转为323…

OSCP靶场--DVR4

OSCP靶场–DVR4 考点(1.windows&#xff1a;路径遍历获取私钥getshell 2.ssh shell中runas切换用户) 1.nmap扫描 ┌──(root㉿kali)-[~/Desktop] └─# nmap -sV -sC -p- 192.168.161.179 --min-rate 2000 Starting Nmap 7.92 ( https://nmap.org ) at 2024-02-29 07:14 EST…

租床小程序|租床系统|租赁软件开发功能

随着移动互联网的普及&#xff0c;越来越多的人开始选择在线上完成各种租赁业务&#xff0c;而医院租床也不例外。在这个趋势下&#xff0c;开发一款租赁小程序成为了市场的必然需求。 租床小程序的功能 1、搜索与筛选 为了满足不同用户的需求&#xff0c;小程序应该提供设备…

掘根宝典之C语言字符串输入函数(gets(),fgets(),get_s())

字符串输入前的注意事项 如果想把一个字符串读入程序&#xff0c;首先必须预留该字符串的空间&#xff0c;然后用输入函数获取该字符串 这意味着必须要为字符串分配足够的空间。 不要指望计算机在读取字符串时顺便计算它的长度&#xff0c;然后再分配空间(计算机不会这样做&a…

DDR5内存相比DDR4内存的优势和区别?选择哪一个服务器内存配置能避免丢包和延迟高?

根据幻兽帕鲁服务器的实际案例分析&#xff0c;选择合适的DDR4与DDR5内存大小以避免丢包和延迟高&#xff0c;需要考虑以下几个方面&#xff1a; 性能与延迟&#xff1a;DDR5内存相比DDR4在传输速率、带宽、工作电压等方面都有显著提升&#xff0c;但同时也伴随着更高的延迟。D…