关于Hex文件的解析和修改应用
生活随笔
收集整理的這篇文章主要介紹了
关于Hex文件的解析和修改应用
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目錄
前言
一、Hex是什么?
二、使用步驟
1.引入HexLexer類
2.調用類
前言
最近研究了一下hex文件的用法。主要用途是配合STVP進行量產工具的開發應用。因為涉及到常量的修改不想編譯和修改或者應用再無法修改原始文件的地方 可以通過提前記錄對應的常量偏移來進行修改。
?
需求:修改指定偏移位置的hex文件 并將此行的記錄校驗修正。
下面是我對網上提供的一些源碼基礎上進行的代碼修改
這里是我的試驗工程代碼有興趣可以查閱
? ? ? ?工程下載地址--有需要的可以下載
一、Hex是什么?
網上對于hex文件的說明和分析已經很詳細了。這里就不多啰嗦了。
二、使用步驟
1.引入HexLexer類
HexLexer.cpp
#pragma once #include "stdafx.h" #include "HexLexer.h" //#include <iostream> //using namespace std; //獲取記錄標識Hex::Hex(char mark) {this->m_cRecordMark = mark;m_cBuffer[0] = '\0';//m_pBuffer = NULL;m_nRecordLength = 0;m_pLoadOffset = NULL;m_pRecordType = NULL;m_pData = NULL;m_pChecksum = NULL;m_bRecvStatus = false;//m_nIndex = 0; }Hex::~Hex() {delete m_pLoadOffset, m_pRecordType, m_pData, m_pChecksum; }char Hex::GetRecordMark() {return this->m_cRecordMark; } //獲取每條記錄的長度 size_t Hex::GetRecordLength() {//char *len = (char*)malloc(sizeof(char)* 3);if (strlen(m_cBuffer) >= 2){char len[3];len[0] = m_cBuffer[0];len[1] = m_cBuffer[1];len[2] = '\0';char *p = NULL;return strtol(len, &p, 16);}else{return 0;} } //獲取裝載偏移 char* Hex::GetLoadOffset() {if (strlen(m_cBuffer) == (GetRecordLength() + 5) * 2){char *offset = (char*)malloc(sizeof(char) * 5);for (int i = 0; i < 4; ++i){offset[i] = m_cBuffer[i + 2];}offset[4] = '\0';m_pLoadOffset = offset;offset = NULL;}return m_pLoadOffset; } //獲取記錄類型 char* Hex::GetRecordType() {if (strlen(m_cBuffer) == (GetRecordLength() + 5) * 2){char *type = (char*)malloc(sizeof(char) * 3);type[0] = m_cBuffer[6];type[1] = m_cBuffer[7];type[2] = '\0';m_pRecordType = type;type = NULL;}return m_pRecordType; } //獲取數據 char* Hex::GetData() {if (strlen(m_cBuffer) == (GetRecordLength() + 5) * 2){int len = GetRecordLength();char *data = (char*)malloc(sizeof(char)*(len * 2 + 1));for (int i = 0; i < len * 2; ++i){data[i] = m_cBuffer[i + 8];}data[len * 2] = '\0';m_pData = data;data = NULL;}return m_pData; } //獲取校驗和 char* Hex::GetChecksum() {int len = GetRecordLength();if (strlen(m_cBuffer) == (len + 5) * 2){char *checksum = (char*)malloc(sizeof(char) * 3);checksum[0] = m_cBuffer[(len + 5) * 2 - 2];checksum[1] = m_cBuffer[(len + 5) * 2 - 1];checksum[2] = '\0';m_pChecksum = checksum;checksum = NULL;}return m_pChecksum; } //解析Hex文件中的每一條記錄 void Hex::ParseRecord(char ch) {size_t buf_len = strlen(m_cBuffer);if (GetRecordMark() == ch){m_bRecvStatus = true;m_cBuffer[0] = '\0';//m_nIndex = 0;return;}if ((buf_len == (GetRecordLength() + 5) * 2 - 1)){//接收最后一個字符m_cBuffer[buf_len] = ch;m_cBuffer[buf_len + 1] = '\0';//檢驗接收的數據char temp[3];char *p = NULL;long int checksum = 0;for (size_t i = 0; i < strlen(m_cBuffer); i += 2){temp[0] = m_cBuffer[i];temp[1] = m_cBuffer[i + 1];temp[2] = '\0';checksum += strtol(temp, &p, 16);temp[0] = '\0';}checksum &= 0x00ff;//取計算結果的低8位if (checksum == 0)//checksum為0說明接收的數據無誤{cout <<GetRecordMark();//輸入記錄標記GetLoadOffset();//獲取偏移項 //你可以在這個地方進新hex文件的修改 ModifyRecord(1, (char*)"C010", "66");ModifyRecord(13, (char*)"C020","66");//修改指定的偏移數據cout << m_cBuffer << endl; }else//否則接收數據有誤{cout << "Error!" << endl;}m_cBuffer[0] = '\0';m_bRecvStatus = false;m_nRecordLength = 0;m_pLoadOffset = NULL;m_pRecordType = NULL;m_pChecksum = NULL;}else if (m_bRecvStatus){m_cBuffer[buf_len] = ch;m_cBuffer[buf_len + 1] = '\0';//m_nIndex++;} } //解析Hex文件 void Hex::ParseHex(char *data) {for (size_t i = 0; i < strlen(data); ++i){ParseRecord(data[i]);} }//重新校驗此行數據 char* Hex::GetChecksumEx() {//校驗方法//020000040003F7//0x100 - ((0x02 + 0x00 + 0x00 + 0x04 + 0x00 + 0x03) % 256) = 0xF7//檢驗接收的數據char temp[3] = { '\0', '\0', '\0' };char* p = NULL;long int checksum = 0;int len = strlen(m_cBuffer) - 2;for (size_t i = 0; i < len; i += 2){temp[0] = m_cBuffer[i];temp[1] = m_cBuffer[i + 1];temp[2] = '\0';checksum += strtol(temp, &p, 16);temp[0] = '\0';}checksum %= 256;checksum = 0x100 - checksum;itoa(checksum, temp, 16);m_pChecksum = strupr(temp);return m_pChecksum; }void Hex::ModifyRecord(int nModifyOffset, char* cOffsetData, char* cModifyData)//修改某一行指定的偏移的數據 {if (nModifyOffset<0|| nModifyOffset>16){return;//偏移位置有誤則返回}//(13-1)*2 24+9int nOffset = (nModifyOffset - 1) * 2 + 9;//計算偏移位置if (!strcmp(m_pLoadOffset, cOffsetData))//對比偏移數據是否一致{//修改此行的記錄數據m_cBuffer[nOffset] = cModifyData[0];m_cBuffer[nOffset-1] = cModifyData[1];GetChecksumEx();//獲取修改后的校驗數據//修正校驗位m_cBuffer[43 - 3] = m_pChecksum[0];m_cBuffer[43 - 2] = m_pChecksum[1];} }void Hex::ModifyHex(char* SrcPath, char* DesPath) {FILE* fp_in = freopen(SrcPath, "r", stdin);rewind(fp_in);FILE* fp_out = freopen(DesPath, "w", stdout);rewind(fp_out);char ch;while (1){ch = fgetc(fp_in);ParseRecord(ch);if (feof(fp_in)){break;}}fclose(stdout);fclose(stdin); }#if 0 int main(int argc, char *argv[]) {freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);Hex hex(':');char ch;while (cin >> ch){hex.ParseRecord(ch);}fclose(stdout);fclose(stdin);return 0; } #endifHexLexer.h
#pragma once #ifndef _HEXLEXER_H_ #define _HEXLEXER_H_ #include <cstdio> #include <cstring> #include <cstdlib> /* Intel Hex文件解析器V1.0 Hex文件的格式如下: RecordMark RecordLength LoadOffset RecordType Data Checksum 在Intel Hex文件中,RecordMark規定為“:” */ #pragma warning(disable:4996) #define MAX_BUFFER_SIZE 43 class Hex { public:Hex(char mark);~Hex();void ParseHex(char *data);//解析Hex文件void ParseRecord(char ch);//解析每一條記錄size_t GetRecordLength();//獲取記錄長度char GetRecordMark();//獲取記錄標識char *GetLoadOffset();//獲取內存裝載偏移char *GetRecordType();//獲取記錄類型char *GetData();//獲取數據char *GetChecksum();//獲取校驗和char* GetChecksumEx();//獲取新的校驗void ModifyRecord(int nModifyOffset,char* cOffsetData, char* cModifyData);//修改某一行指定的偏移的數據void ModifyHex(char* SrcPath, char* DesPath);//修改文件 private:char m_cBuffer[MAX_BUFFER_SIZE];//存儲待解析的記錄char m_cRecordMark;//記錄標識size_t m_nRecordLength;//記錄長度char *m_pLoadOffset;//裝載偏移char *m_pRecordType;//記錄類型char *m_pData;//數據字段char *m_pChecksum;//校驗和bool m_bRecvStatus;//接收狀態標識//size_t m_nIndex;//緩存的字符索引值 };#endif2.調用類
Hex hex(':'); hex.ModifyHex("in.hex", "out.hex");?
總結
以上是生活随笔為你收集整理的关于Hex文件的解析和修改应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 修复bat打开方式
- 下一篇: golang游戏开发学习笔记-开发一个简