#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <stdlib.h>
#include <QByteArray>
#include <QDataStream>
typedef struct{
unsigned char datalen;//数据字节
unsigned short addr;//地址域
unsigned char datatype;//类型
unsigned char databuf[16];//数据记录
unsigned char checkout;//校验和
}HexFormatForLine ;
bool ReadHexLineData(HexFormatForLine* out,const QByteArray & ba)//false: 校验错误 true:校验成功
{
unsigned char i,checkoutCal=0;
//计算校验值
for(i=0;i < ba.size()-1;i++){
checkoutCal += (unsigned char)ba.at(i);
}
checkoutCal = 0x100-checkoutCal;
//获取个部分域的值
out->datalen =(unsigned char)ba.at(0);
out->addr = ((unsigned char)ba.at(1)<<8)|(unsigned char)ba.at(2);
out->datatype = (unsigned char)ba.at(3);
memset(out->databuf,0,sizeof(out->databuf));
for(i = 0;i<out->datalen;i++){
out->databuf[i] = (unsigned char)ba.at(4+i);
}
out->checkout = (unsigned char)ba.at(4+i);
#if 0 //调试时打开
qDebug("datalen=%X",out->datalen);
qDebug("addr=%X",out->addr);
qDebug("datatype=%X",out->datatype);
qDebug("checkout=%X",out->checkout);
qDebug("checkoutCal=%X",checkoutCal);
#endif
//比较读取的校验值和计算的校验值是否一致
if(checkoutCal == out->checkout){
return true;
}
return false;
}
#if 1
char HexToBin(HexFormatForLine* ba,QDataStream & out)//return 0: ok 1:hex文件结束 2:hex文件有误
{
static unsigned int ExStageAddr = 0x00;//扩展段地址
static unsigned int ExLineAddr = 0x00;//扩展线性地址
static unsigned int absoluteAddrLocal = 0x00;//本地记录绝对地址
unsigned int absoluteAddrCurrent = 0x00;//计算当前记录的绝对地址
unsigned int Bytesskipped = 0;//被跳过的字节数
switch(ba->datatype){
case 0x00://数据记录
//计算出当前记录的绝对地址
if(ExStageAddr != 0){
absoluteAddrCurrent = (ba->addr+ExStageAddr);
}else if(ExLineAddr != 0){
absoluteAddrCurrent = (ba->addr|ExLineAddr);
}else{
absoluteAddrCurrent = ba->addr;
}
//hex文件第一条数据记录时,将本地绝对地址absoluteAddrLocal同步等于当前记录的绝对地址absoluteAddrCurrent
if(absoluteAddrLocal == 0){
absoluteAddrLocal = absoluteAddrCurrent;
}
Bytesskipped = absoluteAddrCurrent-absoluteAddrLocal;//比较当前记录的绝对地址absoluteAddrCurrent和本地的绝对地址absoluteAddrLocal是否有偏差
break;
case 0x01://文件结束记录
return 1;
break;
case 0x02://扩展段地址记录
ExStageAddr = (ba->databuf[0]<<8|ba->databuf[1])<<2;
ExLineAddr = 0x00;
return 0;//return ok
break;
case 0x04://扩展线性地址记录
ExLineAddr = (ba->databuf[0]<<8|ba->databuf[1])<<16;
ExStageAddr = 0x00;
return 0;//return ok
break;
default:
return 2;
break;
}
for(unsigned int i = 0;i < Bytesskipped;i++){//被跳过的地址,填充0
out <<(unsigned char)0x00;
}
if(Bytesskipped!=0){
qDebug() <<Bytesskipped;
}
absoluteAddrLocal += Bytesskipped;//本地绝对地址absoluteAddrLocal累加
for(unsigned int i = 0;i < ba->datalen;i++){
out <<ba->databuf[i];
}
absoluteAddrLocal += ba->datalen;//本地绝对地址absoluteAddrLocal累加
return 0;//return ok
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString filepath=QString(argv[1]);//获取hex文件路径
QFile hexfile(filepath);
QFile outfile;
outfile.setFileName(QString(argv[2]));//获取bin文件的保存路径
if(outfile.open(QIODevice::WriteOnly)==false){
qDebug("创建bin文件失败!");
a.exit(0);
}
QDataStream out(&outfile);
if(hexfile.open(QIODevice::ReadOnly)==false){
qDebug("打开hex文件失败!");
outfile.close();
a.exit(0);
}
QByteArray alinedata;
HexFormatForLine HexDataStr;
while(!hexfile.atEnd()){//循环处理,至hex文件读完
/*若: alinedata =QByteArray::fromHex(":12345678");
则: alinedara ={0x12,0x23,0x45,0x78};*/
alinedata = QByteArray::fromHex(hexfile.readLine());//从hex文件中读取一行
bool ret = ReadHexLineData(&HexDataStr,alinedata);//将一行数据解读到HexDataStr结构体
if(!ret){
qDebug("校验出错,hex文件有误.");
outfile.remove();//删除输出的bin文件
hexfile.close();//关闭输入文件
a.exit(0);
}
ret=HexToBin(&HexDataStr,out);//将解读后的数据写入bin文件
if(ret!=0){
break;
}
}
qDebug() <<"hex2bin ok.";
hexfile.close();
outfile.close();
a.exit(0);
}
#else
unsigned int startAddr;
unsigned int endAddr;
char HexToBin(HexFormatForLine* ba,QDataStream & out)//return 0: ok 1:hex文件结束 2:hex文件有误
{
static unsigned int ExStageAddr = 0x00;//扩展段地址
static unsigned int ExLineAddr = 0x00;//扩展线性地址
static unsigned int absoluteAddrLocal = 0x00;//本地记录绝对地址
unsigned int absoluteAddrCurrent = 0x00;//计算当前记录的绝对地址
unsigned int Bytesskipped = 0;//被跳过的字节数
switch(ba->datatype){
case 0x00://数据记录
//计算出当前记录的绝对地址
if(ExStageAddr != 0){
absoluteAddrCurrent = (ba->addr+ExStageAddr);
}else if(ExLineAddr != 0){
absoluteAddrCurrent = (ba->addr|ExLineAddr);
}else{
absoluteAddrCurrent = ba->addr;
}
#if 1
if(absoluteAddrCurrent<startAddr){
return 0;
}
if(absoluteAddrCurrent>endAddr){
return 1;
}
#endif
//hex文件第一条数据记录时,将本地绝对地址absoluteAddrLocal同步等于当前记录的绝对地址absoluteAddrCurrent
if(absoluteAddrLocal == 0){
absoluteAddrLocal = absoluteAddrCurrent;
}
Bytesskipped = absoluteAddrCurrent-absoluteAddrLocal;//比较当前记录的绝对地址absoluteAddrCurrent和本地的绝对地址absoluteAddrLocal是否有偏差
break;
case 0x01://文件结束记录
return 1;
break;
case 0x02://扩展段地址记录
ExStageAddr = (ba->databuf[0]<<8|ba->databuf[1])<<2;
ExLineAddr = 0x00;
return 0;//return ok
break;
case 0x04://扩展线性地址记录
ExLineAddr = (ba->databuf[0]<<8|ba->databuf[1])<<16;
ExStageAddr = 0x00;
return 0;//return ok
break;
default:
return 2;
break;
}
for(unsigned int i = 0;i < Bytesskipped;i++){//被跳过的地址,填充0
out <<(unsigned char)0x00;
}
if(Bytesskipped!=0){
//qDebug() <<Bytesskipped;
}
absoluteAddrLocal += Bytesskipped;//本地绝对地址absoluteAddrLocal累加
for(unsigned int i = 0;i < ba->datalen;i++){
out <<ba->databuf[i];
}
absoluteAddrLocal += ba->datalen;//本地绝对地址absoluteAddrLocal累加
return 0;//return ok
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
#if 1
#if 1
QString saddrRange = QString(argv[3]);
#else
Qt5制作Hex文件转Bin文件的工具
3星 · 超过75%的资源 需积分: 49 23 浏览量
2020-07-17
14:37:53
上传
评论 5
收藏 5KB ZIP 举报
脆弱的代码
- 粉丝: 668
- 资源: 15