关于一个QT程序的简单破解思路(不需要分析信号和槽的方法,通用所有程序的破解思路)

news2024/12/27 11:43:01

几年前,公司买了台国产贴片机,里面的主程序是QT编写,运行在WINDOW XP系统上。主程序打开的界面,如图:

我来简单介绍下程序界面,各位读者不需要搞明白功能,只要知道大体的流程即可。

分析主界面:

一、左边的列表:

贴片生产文件,里面包括了贴片时元器件的坐标、飞达安装的元器件类型、Mark定位点等信息的贴片机工艺文件(文件的格式为CSV),使用和编辑工艺文件时,需先点击选中。

二、右边的三个按钮:

  1. 用打开自带的WPS,以便直接编辑CSV工艺文件,但是因为CSV文件格式比较复杂,一般不使用此功能;
  2. 中间的编辑是在程序中详细设定CSV
  3. 最后的加工按钮,就是进入贴片加工工艺,也是我们今天需要分析的重点项目。 

分析加工界面:

注意: 因为逆向不能影响生产,我是在虚拟机下运行的主程序,所以下面的6个摄像头控件是不工作的,实际是显示了6个吸嘴取料的放大照片。同时因为我运行的是贴片机的默认工艺文件,所以左边的列表也是不显示内容的

一、左侧部分:

  1. 最左侧的列表,显示了MARK点信息(MARK点是PCB板上的一个标记,因为每次进板时位置的不同,所以需要MARK点,来定位每块PCB板的实际坐标,方便程序换算实际贴片坐标用的)。
  2. 中间的列表显示的贴片元器件的详细参数列表。

二、右侧部分:

  1.  加工日志,显示了PCB加工的结果信息。
  2. 功能按钮区域:
    1. 启动:开始贴片
    2. 单步(Enter):贴片每步细化,按此按钮一次即操作一步,比如:进板-->识别板边-->识别Mark点-->吸嘴取料-->贴装-->吸嘴再次取料-->再次贴装-->吸嘴N次取料-->N次贴装-->结束贴装
    3. 停止:在贴装时的暂停操作
    4. 配置:这个我们在下面会详细说说,里面包括了我们需要修改的同取功能
    5. 退出加工:顾名思义退出贴片
    6. PCB退板:把贴好的或者不贴的PCB板退出贴片机

三、下部:

  1. 六个贴装头取料时的照片(飞行相机拍摄)
  2. MARK点图片(MARK相机识别,在图1,复用贴装头1)

因为这台贴片机是多个贴装头的,所以取料时可以并排同时取多个料栈的元器件(需要满足连续的料栈才能同取),但是让人费解的是,这个主程序的贴片配置中(功能按钮中的"配置"按钮),关于同取的设置,每次退出加工程序都会重置,如果没有设置,就会变成没有同取,如下图所示:

逆向目标: 

        所以我们需要实现的目的已经明确:"取料支持同取"自动勾选(不用每次去按"配置"按钮,自动设置同取操作)

逆向思路:

在这里我想分享我逆向程序的一些经验给大家:

  1. 针对一个未知源代码程序时,我们需要大体知道一个程序的界面流程,可以在心里构建出一个大概的分析目标,不能没有目的。
  2. 特别是定位关键的代码时,我们至少需要大体知道代码所在的区域在哪里。
  3. 使用IDA找到函数调用堆栈链。
  4. 还有这个关键代码一定是修改了某些变量,我们只要定位到这个变量。
  5. 使用我们的二分算法,在这个区域内的中间函数下断点,观察定位到的变量是否改变成理想值。
    1. 如变量改变,则在前半段代码区域使用相同的方法,不停缩小范围,最终定位到关键函数。
    2. 如变量不改变,则在后半段区域再次使用二分法不停缩小范围,最终定位到关键函数。
  6. 在关键函数内,通过同样的二分法,定位到关键代码跳转即可。

接下来,我就为大家演示下分析流程。

逆向分析流程:

根据上面的逆向思路,我们已经有了第一条的分析目标--"取料支持同取"自动勾选;所以我们看看第二条的代码所在区域,根据我们之前分析的主界面和加工界面相关信息,我们知道,点击主界面的"加工"按钮会进入加工界面,再点击"配置"按钮可以设置"取料支持同取"

流程如下:"加工"-->"配置"-->"取料支持同取"

因为我们需要勾选"取料支持同取"(下面简称:"同取"),所以不免要从程序初始化CheckBox控件代码入手,我们暂时还不知道QT里是怎么初始化CheckBox控件(因为CheckBox控件有选中和未选中两种状态,所以这个初始化的过程包括:修改并保存一个类似布尔值的公共变量,然后通过读取这个公共变量的值,来修改CheckBox的属性。PS:因为代码设计的关系,点击退出加工后,这个布尔值会重置),我们现在还不知道这个变量的位置,但是可以确定的是,初始化这个控件时,一定会初始化"同取"字符串,如果我们能定位到初始化"同取"的代码处,我们就可以通过IDA的Xref grap to确定初始化CheckBox的函数调用链。

如果大家还不是太明白,我们实际来操作一下吧!

打开我们的IDA8.3,加载贴片机主程序,按Shift+F5打开字符串窗口(怎么使用IDA8.3搜索中文字符串的方法请看以下链接。)

最新IDA8.3安装后需要做的一些完善工作(包括IDAPython报错、ChatGPT的模块安装、中文字符串的显示,各种问题解决方法合集)icon-default.png?t=N7T8https://blog.csdn.net/donglxd/article/details/135243027如下图所示,在String窗口中,我们搜索下"取料支持同取"字符串,可以看到有一个结果,点击后,我们很方便的定位到调用它的代码处。

点击上面的搜索到的字符串来到字符串的定义位置,如下图所示: 

点击上图中字符串后面的引用代码地址,我们来到了如下图的地址处: 

选中如上图中的引用代码位置,然后按一下空格,切换到如下图的方框格模式,方便我们找到函数头,我们只要点击下图中红框处的函数规模总体预览图的最上面,就可以快速定位到函数头部。 

如下图:来到函数头部后,我们右击第一行代码,在弹出的菜单中选择Xrefs graph to来显示函数的调用链 

 如下图就是刚刚引用"同取"字符串之前运行的所有调用函数链。

 知道了函数调用链,我们接下去分析下,因为我们要找到设置CheckBox的公共变量,而设置CheckBox的操作,QT一定有相应的API函数,我们打开IDA搜索下导入表,如下图:

 至于那个API,查询微软的Copilot AI后,给出了下面的链接(QT系统学习系列:1.1 QAbstractButton(按钮抽象基类)),这个链接中说明了AbstractButton是checkbox的基类,CheckBox有两个函数setChecked和isChecked,分别是设置CheckBox和读取CheckBox状态。

然后我们再次使用Copilot查询setChecked函数的名称修饰,如下图:

所以,我们IDA查询到的第一个函数"_ZN15QABstractButton10setCheckedEb"就是setChecked,同样的方法查询到"_ZNK15QAbstractButton9isCheckedEv" 就是isChecked,既然知道了setChecked这个API函数,我们查找下引用他的地址有哪些,方法如下图:

 点击上图中的setChecked名称修饰,定位到下图中的函数输入表位置,右击后打开函数调用链图

 如下图所示,setChecked的调用链,咋一看很复杂是不是?是不是想放弃不接着看了,其实不用想的太复杂,有时答案就在眼前,只要你耐心查找。请接着读下去。

你们还记得,我们刚刚也查找过一个函数调用链吗? 对了,就是调用同取函数那个调用链,我们把两张图放一起对比下,如下图所示: 

 我用红笔圈出的两张图的相同之处,显然这个函数调用链(sub_4A2500-->sub_4A23E0-->sub_4362F0-->sub_491660-->sub_4CBB40)中的最后一链sub_491660-->sub_4CBB40中包含了sub_491230-->"_ZN15QABstractButton10setCheckedEb"(setChecked),所以我们只需找到sub_491230中的setChecked,以方便之后,我们定位到之前提到的公共变量位置。

我们先用IDA定位到sub_491230函数看看,因为里面有setChecked函数调用,具体的分析请看下图:

因为程序是X86的,所以我们用X32DBG调试下,如下图: 

可以看到内存地址74D0C8就是setChecked的公共变量参数(根据call esi得知,esp就是第一参数,而mov dword ptr ss:[esp],eax这句设置了esp,所以eax的赋值语句就是这个第一参数,也就是公共变量),打开主程序后运行启动,打开加工窗口后这个变量会一直存在,我们可以尝试设置下复选框,看看这个公共变量会改变吗?如下图:

 

可以看到公共变量74D0C8变成了00 00 01 01的格式,因为内存中是从高到低读取,所以我们需要的是从右往左数第二个字节的01 。

 既然我们知道了公共变量,让我们再来分析下程序的流程,根据之前的程序流程分析,在主程序页面点击加工后,公共变量就建立了(这点从退出加工页面就会重置"同取"设置就可以判断出来),所以我们从主程序页面的"启动"这个字符串"开刀",Strings搜索下"启动",如下图:

 下图是函数头部:

 

右击这个sub_433830,点击Xrefs graph to,查看函数调用链: 

函数sub_433830的调用链如下图右半部分,可以看到sub_433830的调用链在setChecked调用链的前面,和我们分析的一样:

 如上图,我们需要判断设定公共变量74D0C8是否在蓝色部分的这些函数里? 所以我们先把蓝色部分的这些函数头部都下断点,使用之前文章中提到的二分法,逐步缩小区域即可。我们在x32dbg中使用bp命令快速下断点,如bp 4352C0,下断之后的效果如下:

然后重新运行程序,把下面的内存也设置到公共变量74D0C8的地址观察变化。程序启动后,点击主界面的"启动"按钮,遗憾的是程序直接运行到了加工界面,断点并没有断下,而是需要点击加工界面里的配置才会断下,观察公共变量74D0C8发现,在进入加工界面后,就已经被设置,所以我们可以尝试sub_433830函数的另一边调用链,如下图:

我为了调试时,观察方便,把红框中下断的每个函数都注释了一个简称,如sub1、sub2这样的,方便辨认,并在X32dbg中也对应的注释了函数简称,如下图:

然后,我们用x32dbg重新运行程序,我们一边观察公共变量74D0C8的变化,一边在中断时按运行按钮,跳过不需要的断点,如果x32dbg不中断时,我们再切会贴片机程序正常操作下,如点击项目名、点击启动等,经过几次中断后,我发现公共变量74D0C8变化成我们需要的00 00 00 01了,如下图:

如上图,因为中断在sub5函数头部,所以设置公共变量的代码一定在sub4函数,然后我们可以使用,如下图的二分法,逐步缩小查找范围,定位到关键代码(记住每次都要重启程序调试,我们可以按空格键把不需要的断点关掉,加快调试速度。还有别忘了重启后每次都要在内存1中定位到公共变量74D0C8)。

通过上面的方法,我们很快定位到了关键函数,如下图:

如上图,可以看到运行过注释的这句关键点,下面的公共变量74D0C8变成了00 00 00 01,显然设置代码在这个函数(关键点)中,在这个关键函数上下断。

把不需要的断点取消,重新运行程序,按F7进这个函数看看,如图:

如上图,进关键函数后是一个大跳转,此时单步下去,并注意下面的公共变量74D0C8的值。

我们跟进这个大跳转,如图:

如上图,我们来到了设置公共变量74D0C8的关键函数处,粗略看了下都是mov的赋值操作,看来地方来对了。这个函数不长,我们一行行单步观察公共变量的值变化就好。 

如上图可知,我们运行了上面4行mov的赋值代码后,74D0C8变量成我们需要的值,但是这个00 00 00 01是不设置同取的变量。不知道大家还记得之前我们调试时,尝试点击"同取"复选框改变的值吗? 

就是上图第3个字节位,而我们再看这4句mov赋值,显然赋值的地址也是按ecx的寄存器累加上去,一位位的设置的,显然mov byte ptr ds:[ecx+0x02], 0x00,这句就是我们需要修改的,把后面的0x00改成0x01即可,如下图:

 

 然后右击修改的代码,点击补丁保存修改后的文件,我们可以另起一个名称,如下图:

 

然后我们运行下这个修改后的主程序看看。

 可以看到,修改成功了,教程到此也写完了,感谢大家的耐心观看,本人不才,但是希望大家有学到新知识,谢谢!

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

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

相关文章

GPT5?OpenAI 创始人:GPT5 已在训练中,需要更多数据

OpenAI 最近发出征集大规模数据集的呼吁,特别是“今天在互联网上尚未公开轻松获取”的数据集,尤其是长篇写作或任何格式的对话。 GPT-5丨AI浪潮席卷全球,OpenAI 推出GPT-4 后,又于上月26日宣布今年9月、10月将推出GPT-4.5&#xf…

【openlayers】移动视角适应所有点

移动视角适应所有点 连接 chatgpt 代码 // 创建一个地图 var map new ol.Map({target: map, // 指定地图容器的IDlayers: [// 添加你的地图图层// 例如:new ol.layer.Tile({ source: new ol.source.OSM() })],view: new ol.View({center: [0, 0], // 地图初始中…

Java中的HTTPS通信

在Java中实现HTTPS通信,主要涉及到SSL/TLS协议的使用,用于提供数据传输的安全性。下面我们将深入探讨如何使用Java进行HTTPS通信。 一、基本概念 HTTPS,全称为Hypertext Transfer Protocol Secure,是HTTP的安全版本。它使用SSL/…

【JavaEE进阶】 MyBatis使用注解实现增删改查

文章目录 🍃前言🌴传递参数🎋增(Insert)🚩返回主键 🎄删(Delete)🌲改(Update)🌳查(Select)🚩起别名🚩结果映射🚩开启驼峰命名(推荐使用) ⭕总结 &#x1f343…

代课老师是劳务派遣吗

劳务派遣是一种特殊的用工形式,指由劳务派遣机构与派遣劳工签订劳动合同,并支付报酬,把劳动者派向其他用工单位,再由其用工单位向派遣机构支付一笔服务费用的一种用工形式。也就是说,劳务派遣的员工和实际工作的单位没…

谁能做智驾?国内电动车新王者诞生在望

书接上回,我来告诉你们,近来国内科技巨头华为和比亚迪之间,在电动车智能化领域也快开打起来了!你们心里一定有一个问题—这两家公司到底是为什么要较量呢?难道仅仅是想比比看谁技术更强?还是产品谁能卖的更好?其实,…

【Linux】文件周边001之系统文件IO

👀樊梓慕:个人主页 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 🌝每一个不曾起舞的日子,都是对生命的辜负 目录 前言 1.C语言文件IO 1.1…

HCIP网络类型+串线+GRE

一.网络类型: 点到点 BMA:广播型多路访问 -- 在一个MA网络中同时存在广播(泛洪)机制 NBMA:非广播型多路访问 -- 在一个MA网络中,没有泛洪机制-----不怎么使用了 MA:多路访问 -- 在一个…

手机App防沉迷系统 - 华为OD统一考试

OD统一考试(C卷) 分值: 100分 题解: Java / Python / C 题目描述 智能手机方便了我们生活的同时,也侵占了我们不少的时间。“手机Ap防沉迷系统” 能够让我们每天合理的规划手机App使用时间,在正确的时间做…

Redis - redis.windows.conf配置文件及RDB和AOF数据持久化方案

Redis - redis.windows.conf配置文件及RDB和AOF数据持久化方案 Redis的高性能是由于其将所有数据都存储在了内存中,为了使Redis在重启之后仍能保证数据不丢失,需要将数据从内存中同步到硬盘中,这一过程就是持久化。 Redis支持两种方式的持久化…

Vue3 Suspense 优雅地处理异步组件加载

✨ 专栏介绍 在当今Web开发领域中,构建交互性强、可复用且易于维护的用户界面是至关重要的。而Vue.js作为一款现代化且流行的JavaScript框架,正是为了满足这些需求而诞生。它采用了MVVM架构模式,并通过数据驱动和组件化的方式,使…

[Linux]HTTP状态响应码和示例

1xx:信息响应类,表示接收到请求并且继续处理 2xx:处理成功响应类,表示动作被成功接收、理解和接受 3xx:重定向响应类,为了完成指定的动作,必须接受进一步处理 4xx:客户端错误&#x…

[笔记]Spring AOP

Spring AOP(Aspect Oriented Programming) AOP将应用程序分为核心业务和非核心的公共功能,AOP的关注点是系统中的非核心的公共功能; AOP可以通过预编译或者运行期动态代理的方式,为横跨多个对象(没有继承关…

四、Flask学习之JavaScript

四、Flask学习之JavaScript JavaScript,作为一种前端脚本语言,赋予网页生动的交互性和动态性。通过它,开发者能够操作DOM(文档对象模型)实现页面元素的动态改变、响应用户事件,并借助AJAX技术实现异步数据…

omron adept控制器维修SmartController EX

欧姆龙机器人adept运动控制器维修SmartController EX 19300-000 维修范围:姆龙机器人;码垛机器人;搬运机器人;焊机机器人;变位机等。 Adept Viper s650/s850用于装配、物料搬运、包装和机械装卸,循环周期短…

基于YOLOv8深度学习的102种花卉智能识别系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战

《博主简介》 小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推…

dom-to-image-more 使用

与网上不同的使用方式: 官网 dom-to-image-more - npm 这里不会出现两行缩略不行的bug yarn add dom-to-image-more 下面 生成图片并下载图片 const picture ref() const dom2img () > {var node picture.valuedomtoimage.toPng(node, { cacheBust: t…

iou的cpu和gpu源码实现

本专栏主要是深度学习/自动驾驶相关的源码实现,获取全套代码请参考 简介 IoU(Intersection over Union)是一种测量在特定数据集中检测相应物体准确度的一个标准,通常用于目标检测中预测框(bounding box)之间准确度的…

Arduino U8g2库:图形界面库的强大利器,

Arduino U8g2库:图形界面库的强大利器 介绍 在Arduino世界中,图形界面的显示通常是一项关键的任务。为了简化这个过程,提高开发效率,许多库被开发出来,其中U8g2库就是其中之一。U8g2库是一个功能强大的图形库&#x…

uniapp复选框 实现排他选项

选择了排他选项之后 复选框其他选项不可以选择 <view class"reportData" v-for"(val, index) in obj" :key"index"> <view v-if"val.type 3" ><u-checkbox-group v-model"optionValue" placement"colu…