51单片机逆向
51单片机逆向
51单片机逆向1,点亮一个LED示例
C代码
参考代码
#include <reg52.h> //包含特殊功能寄存器定义的头文件
sbit LED = P0^0; //位地址声明,注意:sbit必须小写、P大写!
sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;
void main()
{
ENLED = 0;
ADDR3 = 1;
ADDR2 = 1;
ADDR1 = 1;
ADDR0 = 0;
LED = 0; //点亮小灯
while (1); //程序停止在这里
}
hex烧录文件

用IDA加载
看下框图

这里看出从地址00出,跳到地址11处,这里是做初始化工作。 完成之后跳到我们的用户程序main中。

我们一步一步来,这里先从简单的开始。

跳转指令总结:
这里用到了短跳sjmp和长跳limp指令。其中02 00 11 ,02 后面给的是绝对值地址,这个是长跳,02是机器码

其中验证一下,从初始化完成跳转到用户函数也是用的绝对值跳转,长跳。

下面看一下短跳:
短跳用到的是sjmp指令 80 是机器码,后面给一个有符号的地址(这个地址是相对地址,区别于绝对值地址。),这里要注意是有符号的,一般这样理解就没有错。如果是负数就是回跳,是正数往下跳。(注意FE需要转换为有符号的数。)

这里看一下指令djnz,机器码D8 FD

djnz是给的相对指令,相对于当前pc指针的值。这里FD也是有符号数。
给同学们留一个作业,FD转换为有符号数是多少?
51单片机逆向2,LED闪烁示例
C代码
#include<reg52.h>
sbit LED = P0^0;
sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;
void main() //void即函数类型
{
//以下为声明语句部分
unsigned int i = 0; //定义一个无符号整型变量i,并赋初值0
//以下为执行语句部分
ENLED = 0; //U3、U4两片74HC138总使能
ADDR3 = 1; //使能U3使之正常输出
ADDR2 = 1; //经U3的Y6输出开启三极管Q16
ADDR1 = 1;
ADDR0 = 0;
while (1)
{
LED = 0; //点亮小灯
for (i=0; i<30000; i++); //延时一段时间
LED = 1; //熄灭小灯
for (i=0; i<30000; i++); //延时一段时间
}
}
hex烧录文件

用IDA加载
看下框图,框图比项目1点亮led要复杂多了。看下面的分析。

汇编代码分析
1,这里我们分成模块来分析。从这里直接跳到初始化函数中。

2,初始化函数和上面基本一致,这里略。
初始化完成初始化之后跳到用户函数。这里重点是用户函数的分析。

3,用户函数分析
用户函数有点复杂,我们先看用户函数的小框架

4 ,这一段赋值和点亮led代码一致,为了方便理解这里我给添加注释,下面看重点的。

5,点亮led

6,循环
a,这里先把A寄存器清零,同时R6,R7都清零。
b,R7加1
c, 判断R7(?)与#0是否相等不相等跳到code_17的位置。code_17也是相对位置,相对距离是1个单位。
d,R6与#0x75不相等跳到code_12的位置,这里F8也是相对位置,记住这是有符号的需要大家手动转换一下。
说明:30,000 = 0x7530,在51系统中7530被分割成两部分。
上面跳到code12的位置,重复执行b—>d的步骤。结果就是当R7加到0时候,跳出改循环,这个循环我把有用的代码提取出来
code_12:INC R7
CJNE R7 #0 code_17
code_17:cjne R6, #0x75, code_12(在这个循环中R6始终等于0不满足条件),所以上面这段指令会一致循环,当R7+++++++,溢出为0的时候满足跳出该循环(相对的说法)。
溢出之后CJNE R7 #0 code_17 这条指令满足条件,顺序执行,R6++++
也上两个循环满足0x75之后,在执行inc R7
cjne R7, #0x30, code_12,0不等于0x30.所以还需要循环到0x30.完成上面循环之后,跳出循环延时时间到。

上面循环完成了。就需要熄灭LED

这里就是一两,一灭完成,下面记住重复上面的循环,不过这里的差比是循环的时候跳转的位置不一样。我们看一下差异。

这里看出跳到的是code_d,也就是点亮led的位置。这也就是while(1)的大循环。
这里需要说一下,clr c 这里用到了subb指令所以需要献给cy清零

51单片机逆向3、用P0口控制实现流水灯效果
C代码
#include <reg52.h>
sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;
void main()
{
unsigned int i = 0; //定义循环变量i,用于软件延时
unsigned char cnt = 0; //定义计数变量cnt,用于移位控制
ENLED = 0;
ADDR3 = 1;
ADDR2 = 1;
ADDR1 = 1;
ADDR0 = 0;
while (1) //主循环,程序无限循环执行该循环体语句
{
P0 = ~(0x01 << cnt); //P0等于1左移cnt位,控制8个LED
for (i=0; i<20000; i++); //软件延时
cnt++; //移位计数变量自加1
if (cnt >= 8) //移位计数超过7后,再重新从0开始
{
cnt = 0;
}
}
}
hex烧录文件
02 00 3C E4 FF FE FD C2 94 D2 93 D2 92 D2 91 C
90 A8 05 74 01 08 80 02 C3 33 D8 FC F4 F5 80 E
FE FF 0F BF 00 01 0E BE 4E F8 BF 20 F5 0D ED C
94 08 74 80 94 80 40 D9 E4 FD 80 D5 78 7F E4 F
D8 FD 75 81 07 02 00 03
000 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
010 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
020 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
030 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
040 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
050 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
用IDA加载
这里稍微看一下大概就可以了。我们把重点放在初始化和main函数里面。

汇编代码分析:
1 程序入口
从入口直接跳到初始化到吗Ini_Main函数里面。这里是一个长跳指令ljmp,机器码(02)后面跟的是绝对值地址。3C的地方,我们跳到3C的地方。

2 初始化Ini_Main函数的分析

这里可以看出初始化就是对内存0-127之前的范围初始化为0,循环128次,对内存初始化,后面是设置栈顶指针。

3,用户函数main的分析:
1,对IO口进行赋值,并对寄存器R5,6,7进行清零

2,双循环

3,补充一下,移位指令。rlc指令,机器码(0x33)
这里是循环对移位指令的操作。
###总结:这里没有新鲜内容,内容框架。
新的改变
我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:
- 全新的界面设计 ,将会带来全新的写作体验;
- 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
- 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
- 全新的 KaTeX数学公式 语法;
- 增加了支持甘特图的mermaid语法1 功能;
- 增加了 多屏幕编辑 Markdown文章功能;
- 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
- 增加了 检查列表 功能。
功能快捷键
撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
查找:Ctrl/Command + F
替换:Ctrl/Command + G
合理的创建标题,有助于目录的生成
直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC语法后生成一个完美的目录。
如何改变文本的样式
强调文本 强调文本
加粗文本 加粗文本
标记文本
删除文本
引用文本
H2O is是液体。
210 运算结果是 1024.
插入链接与图片
链接: link.
图片:
带尺寸的图片:
居中的图片:
居中并且带尺寸的图片:
当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。
如何插入一段漂亮的代码片
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.
// An highlighted block
var foo = 'bar';
生成一个适合你的列表
- 项目
- 项目
- 项目
- 项目
- 项目1
- 项目2
- 项目3
- 计划任务
- 完成任务
创建一个表格
一个简单的表格是这么创建的:
| 项目 | Value |
|---|---|
| 电脑 | $1600 |
| 手机 | $12 |
| 导管 | $1 |
设定内容居中、居左、居右
使用:---------:居中
使用:----------居左
使用----------:居右
| 第一列 | 第二列 | 第三列 |
|---|---|---|
| 第一列文本居中 | 第二列文本居右 | 第三列文本居左 |
SmartyPants
SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:
| TYPE | ASCII | HTML |
|---|---|---|
| Single backticks | 'Isn't this fun?' | ‘Isn’t this fun?’ |
| Quotes | "Isn't this fun?" | “Isn’t this fun?” |
| Dashes | -- is en-dash, --- is em-dash | – is en-dash, — is em-dash |
创建一个自定义列表
-
Markdown
- Text-to- HTML conversion tool Authors
- John
- Luke
如何创建一个注脚
一个具有注脚的文本。2
注释也是必不可少的
Markdown将文本转换为 HTML。
KaTeX数学公式
您可以使用渲染LaTeX数学表达式 KaTeX:
Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n−1)!∀n∈N 是通过欧拉积分
Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=∫0∞tz−1e−tdt.
你可以找到更多关于的信息 LaTeX 数学表达式here.
新的甘特图功能,丰富你的文章
- 关于 甘特图 语法,参考 这儿,
UML 图表
可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:
这将产生一个流程图。:
- 关于 Mermaid 语法,参考 这儿,
FLowchart流程图
我们依旧会支持flowchart的流程图:
- 关于 Flowchart流程图 语法,参考 这儿.
导出与导入
导出
如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。
导入
如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。
注脚的解释 ↩︎
1509

被折叠的 条评论
为什么被折叠?



