一个四年前产品引发的血案

[复制链接]
 楼主| 叶春勇 发表于 2021-9-23 17:09 | 显示全部楼层 |阅读模式
本帖最后由 tyw 于 2021-9-23 17:16 编辑

最近客户寄过来一个产品,一看,居然时4年前在上一个东家搞得产品,代码我都有,可惜不知道是哪个了。问其要技术图纸,答曰无。
在绝望之下,想起了N年以前沉迷于看雪论坛,搞**的那段日子。
搜了一下反汇编的软件,一看有老牌的ida pro 还有一个号称美国中情局出品的ghidra反汇编程序,好奇心陡然上升,下载之。
软件界面如下:
1、新建一个工程,随便弄,是个目录就行
2、import一个hex文件

3、进入一个反汇编的对话框,选择正确的cpu

4、点击language的。。。,如下,选择8051

5、点击ok,以后出现一个对话框表示成功,双击导入的main.hex

6.进入listing窗口,Ctrl+A,鼠标右键,点击反汇编

7.成功反汇编如下

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| 叶春勇 发表于 2021-9-23 17:17 | 显示全部楼层
单片机是老姚的stc15w404as
根据8051的中断向量表,第一行就是跳到main的,下面几行全是中断向量表。
往下翻,翻到一个io口的初始化代码

ghidra反汇编的伪代码如下:

比对一下自己的代码。

终于锁定自己的代码了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| 叶春勇 发表于 2021-9-23 17:23 | 显示全部楼层
这些老姚的寄存器,反汇编程序没有识别,看了一下stc15w404as写的头文件,以前stc15w404as改用sdcc开源编译器,自己写的头文件

把ghidra没有识别的特殊寄存器sfr,果断重命名

这样就清晰了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| 叶春勇 发表于 2021-9-23 17:25 | 显示全部楼层
本帖最后由 叶春勇 于 2021-9-24 09:57 编辑

51单片机的前面是中断向量表,当然stc15w404as是增强型的51核,增加了很多功能,其中指令速度提高号称12T,中断也增加了很多。这个中断向量表,是分析程序的关键。下面的网友有说区分数据和代码的傻瓜**软件。据我的了解,通用的反汇编软件针对x86上的程序非常傻瓜,对于嵌入式就一般般。
下图是stc15w404as的中断图

我们按照stc,datasheet的描述,把反汇编程序的中断服务程序注释一下。这样结构就非常清晰了。
  1.                              //
  2.                              // CODE
  3.                              // Generated by Intel Hex
  4.                              // CODE:0000-CODE:0003
  5.                              //
  6.                              reset_routine
  7.        CODE:0000 02 00 31        LJMP       start
  8.                              INT0_ISR
  9.        CODE:0003 32              RETI
  10.                              //
  11.                              // CODE
  12.                              // Generated by Intel Hex
  13.                              // CODE:000b-CODE:000d
  14.                              //
  15.                              timer0_isr_routine
  16.        CODE:000b 02 06 c3        LJMP       timer0_isr
  17.                              //
  18.                              // CODE
  19.                              // Generated by Intel Hex
  20.                              // CODE:0013-CODE:0013
  21.                              //
  22.        CODE:0013 32              RETI
  23.                              //
  24.                              // CODE
  25.                              // Generated by Intel Hex
  26.                              // CODE:001b-CODE:001b
  27.                              //
  28.                              timer1_isr_routine
  29.        CODE:001b 32              RETI
  30.                              //
  31.                              // CODE
  32.                              // Generated by Intel Hex
  33.                              // CODE:0023-CODE:0023
  34.                              //
  35.                              usart1_isr
  36.        CODE:0023 32              RETI
  37.                              //
  38.                              // CODE
  39.                              // Generated by Intel Hex
  40.                              // CODE:002b-CODE:0816
  41.                              //
  42.                              adc_isr_routine
  43.        CODE:002b 02 03 2d        LJMP       adc_isr
这个程序只使用timer0,adc中断,这些是我们分析程序的框架。程序框架清楚了,代码和数据就可以区分开来了。
裸奔的单片机程序,由若干中断和一个while循环构成。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
athlon64fx 发表于 2021-9-23 17:42 | 显示全部楼层
弓虽
henangongda123 发表于 2021-9-23 17:57 | 显示全部楼层
老妖不是号称**不了吗?

评论

[url=home.php?mod=space&uid=537303]@huarana[/url] :哦  发表于 2021-9-23 20:03
楼主是已经有hex文件了吧。 老妖号称的是烧写到芯片里的程序搞不出来可以用的。  发表于 2021-9-23 18:14
xxdcq 发表于 2021-9-23 18:35 | 显示全部楼层
你试试你这个反汇编软件对于有大量的数据表的代码会反成数据还是代码?如果这个能完美区分开那就算是比较强的反汇编软件,另外反汇编之后再编译也能正确通过,并且对比最后生成的bin文件要完全一样这就是高质量的反汇编
fengok008 发表于 2021-9-23 19:47 | 显示全部楼层
地瓜patch 发表于 2021-9-23 21:47 | 显示全部楼层
牛牛
mbutterfly 发表于 2021-9-24 09:40 | 显示全部楼层
厉害,还没用过反汇编
 楼主| 叶春勇 发表于 2021-9-24 10:08 | 显示全部楼层
这是老姚的寄存器表,通用的反汇编程序是无法识别的,所以得自己改成所需的寄存器

以老姚的看门狗寄存器位例子,下面是反汇编的代码段和伪代码,WDT_CONTR再sfr的0xC1,这里被错误识别成FI**1,需要改成

通过网上搜索,ghidra,有一个51的寄存器识别表。改写这个寄存器表,就能正确识别。
如下图所示


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| 叶春勇 发表于 2021-9-24 10:25 | 显示全部楼层
这张寄存器表,快速定位自己的单片机初始化程序,如下图,锁定寄存器即锁定初始化程序。

把所有的初始化程序全部注释一遍,最终找到一个init_all程序。看了一下伪代码,太残暴了。与自己写的程序几乎一摸一样。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| 叶春勇 发表于 2021-9-24 10:34 | 显示全部楼层
对于工程师确定hex与源代码的对于关系,基本就完了,找到相应的关键设定参数。从start一直去追踪,以及软件给出的伪代码。轻松锁定自己的代码。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| 叶春勇 发表于 2021-9-24 10:50 | 显示全部楼层
总结:
1、51单片机,前面的中断向量表,快速确定,中断服务程序和start程序(跟c不一样,包括编译器自带的初始化代码),把代码跑出来。剩下的都是数据区。
2、start程序,从初始化代码入手,最后返回start,借助伪代码,快速锁定while循环,while循环里基本都是关键代码。
3、如需进阶,对于c语言比较熟悉的人,需要了解如16bit和32bit的四则运算的汇编程序,汇编程序看着很长很吓人,都是这折腾这些16bit和32bit的四则运算。其中if语句,C语言中的判断,x大于y,被转换成四则运算,对于16bit或32bit,代码都是很长的。我这里都是sdcc编译的,跟keil c51编译的不同。一般来说,rom尺寸优先的优化代码好阅读,速度优先的代码就是天书(函数被优化掉了)。
数码小叶 发表于 2021-9-24 11:23 | 显示全部楼层
这波操作厉害了
 楼主| 叶春勇 发表于 2021-9-24 11:45 | 显示全部楼层
来看看这段代码:
  1. if(alarm_delay_timer_disable>TIMER_10S) alarm_disable_flag=0;

其中:
变量alarm_delay_timer_disable是两个字节
设定参数TIMER_10S=1000
变量alarm_disable为一个字节
反汇编出来的代码如下
  1.        CODE:0178 c3              CLR        CY
  2.        CODE:0179 74 e8           MOV        A,#0xe8
  3.        CODE:017b 95 4d           SUBB       A,WORD_INTMEM_4d                                 = ??
  4.        CODE:017d 74 03           MOV        A,#0x3
  5.        CODE:017f 95 4e           SUBB       A,WORD_INTMEM_4d+1                               = null
  6.        CODE:0181 50 03           JNC        LAB_CODE_0186
  7.        CODE:0183 75 51 00        MOV        DAT_INTMEM_51,#0x0                               = ??


编译器还是给力的

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
ningling_21 发表于 2021-9-24 11:58 | 显示全部楼层
厉害了
天意无罪 发表于 2021-9-24 12:30 | 显示全部楼层
STC貌似也安于它现在的状态,能在细分市场占领一些份额,挣点*币也不错了。
 楼主| 叶春勇 发表于 2021-9-24 13:24 | 显示全部楼层
天意无罪 发表于 2021-9-24 12:30
STC貌似也安于它现在的状态,能在细分市场占领一些份额,挣点*币也不错了。 ...

我本来是看一下程序的参数,好确定是哪个版本。
结果编译器优化的面目全非。还得分析程序。好好的设定值1000,被拦腰打断了。
圣骑士by 发表于 2021-9-24 13:25 | 显示全部楼层
厉害了 点赞
您需要登录后才可以回帖 登录 | 注册

本版积分规则

151

主题

4810

帖子

50

粉丝
快速回复 在线客服 返回列表 返回顶部