mb.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. #include <windows.h>
  2. #include <tchar.h>
  3. #include <time.h>
  4. #include <stdlib.h>
  5. #include <stdint.h>
  6. #include <string.h>
  7. #include <stdio.h>
  8. #include "md5.h"
  9. //https://blog.csdn.net/phunxm/article/details/5082618
  10. //https://blog.csdn.net/byxdaz/article/details/80507510
  11. #pragma pack (1)
  12. typedef struct {
  13. uint8_t digit[32];
  14. }md5_t;
  15. typedef struct {
  16. char *data;
  17. uint32_t blen;
  18. uint32_t dlen;
  19. }data_t;
  20. typedef union {
  21. struct {
  22. uint8_t magic[14];
  23. uint16_t size;
  24. uint32_t partition;
  25. uint32_t version;
  26. }hdr;
  27. uint8_t padd[128];
  28. }fw_hdr_t;
  29. typedef struct {
  30. uint32_t operation_flag; // 0
  31. uint32_t partition; // 1
  32. uint32_t err; // 0
  33. uint32_t error_count; // 0
  34. uint32_t rom_addr; // PROGRAME_APP1 0x08005400
  35. uint32_t recent_running_time; // 0
  36. uint32_t running_app_version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0)
  37. uint32_t app1_version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0)
  38. uint32_t app1_rom_addr; // PROGRAME_APP1 0x08005400
  39. uint32_t app1_partition; // 1
  40. uint32_t app2_version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0)
  41. uint32_t app2_rom_addr; // PROGRAME_APP2 0x0800A400
  42. uint32_t app2_partition; // 1
  43. }fw_info_t;
  44. typedef struct {
  45. data_t boot;
  46. data_t info;
  47. data_t app1;
  48. data_t app2;
  49. }fw_image_t;
  50. #pragma pack ()
  51. static void print_md5(const char* s, char* m)
  52. {
  53. uint8_t i;
  54. printf("__%s", s);
  55. for (i = 0; i < 32; i++) {
  56. printf("%c", m[i]);
  57. }
  58. printf("\n");
  59. }
  60. static char* my_malloc(uint32_t len)
  61. {
  62. char* p = (char*)malloc(len);
  63. if (p) {
  64. memset(p, 0xff, len);
  65. }
  66. return p;
  67. }
  68. static int str_cpy(char *dst, char *src)
  69. {
  70. char* p = strchr(src, '"');
  71. if (!p) {
  72. return -1;
  73. }
  74. p += 1;
  75. while ((*p) != '"') {
  76. *dst++ = *p++;
  77. }
  78. *dst = 0;
  79. return 0;
  80. }
  81. static int digit_cpy(char* dst, char* src)
  82. {
  83. int x = 10;
  84. char* p = src;
  85. if (p[0] == '0' && (p[1]=='x' || p[1]=='X')) {
  86. memcpy(dst, p, 2);
  87. dst += 2; p += 2;
  88. x = 16;
  89. }
  90. while (isxdigit(*p)) {
  91. *dst++ = *p++;
  92. }
  93. *dst = 0;
  94. return x;
  95. }
  96. static char* get_token(char *buf, const char *tok)
  97. {
  98. char* p = strstr(buf, tok);
  99. if (!p) {
  100. printf("%s not found!!!\n", tok);
  101. return NULL;
  102. }
  103. p += strlen(tok);
  104. while (isblank(*p)) p++;
  105. return p;
  106. }
  107. static uint32_t get_addr(char* buf, const char* tok)
  108. {
  109. int x;
  110. char tmp[100];
  111. char* p = get_token(buf, tok);
  112. if (!p) {
  113. return -1;
  114. }
  115. x = digit_cpy(tmp, p);
  116. return (uint32_t)strtol(tmp, NULL, x);
  117. }
  118. static char* strstr_line(char *s, const char *tok)
  119. {
  120. char* p1 = strstr(s, tok);
  121. char* p2 = strchr(s, '\n');
  122. if (p1 && p2 && p1<p2) {
  123. return p1;
  124. }
  125. return NULL;
  126. }
  127. static uint32_t get_int(char* buf, const char* tok)
  128. {
  129. int x;
  130. uint32_t v = 1;
  131. char *t,tmp[100];
  132. char* p = get_token(buf, tok);
  133. if (!p) {
  134. return -1;
  135. }
  136. t = strstr_line(p, "0x");
  137. if (!t) {
  138. t = strstr_line(p, "0X");
  139. }
  140. if (t) {
  141. p = t;
  142. }
  143. while (1) {
  144. if (isdigit(*p)) {
  145. x = digit_cpy(tmp, p);
  146. v *= strtol(tmp, NULL, x);
  147. p += strlen(tmp);
  148. }
  149. else {
  150. if (!isgraph(*p)) {
  151. break;
  152. }
  153. p++;
  154. }
  155. }
  156. return v;
  157. }
  158. /////////////////////////////////////////////
  159. static uint32_t get_version(char *buf, const char *tok)
  160. {
  161. char tmp[10];
  162. uint32_t v, i = 0, j = 3;
  163. uint8_t* p8 = (uint8_t*)&v;
  164. char* p = get_token(buf, tok);
  165. if (!p) {
  166. return -1;
  167. }
  168. while (!isdigit(*p)) p++;
  169. while (*p) {
  170. if (isdigit(*p)) {
  171. tmp[i++] = *p;
  172. }
  173. else {
  174. if (!isgraph(*p)) {
  175. break;
  176. }
  177. if (i > 0) {
  178. tmp[i] = 0;
  179. p8[j--] = (uint8_t)atoi(tmp);
  180. }
  181. i = 0;
  182. }
  183. p++;
  184. }
  185. return v;
  186. }
  187. static int get_magic(char *buf, const char *tok, void *magic)
  188. {
  189. static char tmp[500];
  190. char* p = get_token(buf, tok);
  191. if (!p) {
  192. return -1;
  193. }
  194. str_cpy(tmp, p);
  195. memcpy(magic, tmp, strlen(tmp));
  196. return 0;
  197. }
  198. static int get_info(char *buf, fw_hdr_t *hdr, fw_info_t *inf, fw_image_t *img)
  199. {
  200. uint32_t version = get_version(buf, "VERSION");
  201. uint32_t partition = get_int(buf, "PARTITION");
  202. uint32_t rom_addr = get_int(buf, "PROGRAME_APP1");
  203. //fill hdr
  204. memset(hdr, 0xff, sizeof(fw_hdr_t));
  205. get_magic(buf, "MODBUS_HEAD", hdr->hdr.magic);
  206. hdr->hdr.size = 0;
  207. hdr->hdr.version = version;
  208. hdr->hdr.partition = partition;
  209. //fill inf
  210. inf->operation_flag = 0; // 0
  211. inf->partition = 1; // 1
  212. inf->err = 0; // 0
  213. inf->error_count = 0; // 0
  214. inf->rom_addr = rom_addr; // PROGRAME_APP1 0x08005400
  215. inf->recent_running_time; // 0
  216. inf->running_app_version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0)
  217. inf->app1_version = version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0)
  218. inf->app1_rom_addr = rom_addr; // PROGRAME_APP1 0x08005400
  219. inf->app1_partition = partition; // 1
  220. inf->app2_version = version; // V1.0.0.0 (1<<24 | 0 << 16 | 0 << 8 | 0)
  221. inf->app2_rom_addr = get_int(buf, "PROGRAME_APP2"); // PROGRAME_APP2 0x0800A400
  222. inf->app2_partition = partition; // 1
  223. //fill img
  224. img->boot.blen = get_int(buf, "BOOT_LOADER_SIZE");
  225. img->boot.data = my_malloc(img->boot.blen);
  226. img->info.blen = get_int(buf, "META_DATA_SIZE");
  227. img->info.data = my_malloc(img->info.blen);
  228. img->app1.blen = get_int(buf, "PROGRAME_APP1_SIZE");
  229. img->app1.data = my_malloc(img->app1.blen);
  230. img->app2.blen = get_int(buf, "PROGRAME_APP2_SIZE");
  231. img->app2.data = my_malloc(img->app2.blen);
  232. return 0;
  233. }
  234. /////////////////////////////////////////////
  235. static TCHAR* char_to_tchar(char* str)
  236. {
  237. DWORD dwNum = 0;
  238. dwNum = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
  239. TCHAR* pUni = new TCHAR[dwNum];
  240. MultiByteToWideChar(CP_ACP, 0, str, -1, pUni, dwNum);
  241. return pUni;
  242. }
  243. static int file_read(const TCHAR* path, data_t *data)
  244. {
  245. int r=-1;
  246. HANDLE hFile;
  247. DWORD flen,rlen;
  248. hFile = CreateFile(path, //name
  249. GENERIC_READ, //以读方式打开
  250. FILE_SHARE_READ, //可共享读
  251. NULL, //默认安全设置
  252. OPEN_EXISTING, //只打开已经存在的文件
  253. FILE_ATTRIBUTE_NORMAL, //常规文件属性
  254. NULL); //无模板
  255. if (hFile== INVALID_HANDLE_VALUE) {
  256. _tprintf(_T("%s open failed\n"), path);
  257. return -1;
  258. }
  259. flen = GetFileSize(hFile, NULL);
  260. if (flen== INVALID_FILE_SIZE) {
  261. printf("invalid file len\n");
  262. goto quit;
  263. }
  264. if(data->data==NULL) {
  265. data->data = (char*)malloc(flen);
  266. if (data->data == NULL) {
  267. printf("___ data->data is NULL\n");
  268. goto quit;
  269. }
  270. }
  271. data->dlen = flen;
  272. r = ReadFile(hFile, data->data, data->dlen, &rlen, NULL);
  273. if (r==FALSE) {
  274. _tprintf(_T("%s read failed\n"), path);
  275. goto quit;
  276. }
  277. r = 0;
  278. quit:
  279. CloseHandle(hFile);
  280. return r;
  281. }
  282. static int get_time(TCHAR* path, char* time, int len)
  283. {
  284. FILETIME IpCreationTime; //文件的创建时间
  285. FILETIME IpLastAccessTime; //对文件的最近访问时间
  286. FILETIME IpLastWriteTime; //文件的最近修改时间
  287. FILETIME ltime;
  288. SYSTEMTIME rtime;
  289. HANDLE hFile = CreateFile(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
  290. if (hFile == INVALID_HANDLE_VALUE)
  291. {
  292. printf("Get the dictionary failed!\n");
  293. CloseHandle(hFile);
  294. return -1;
  295. }
  296. if (!GetFileTime(hFile, &IpCreationTime, &IpLastAccessTime, &IpLastWriteTime)) {
  297. return -1;
  298. }
  299. CloseHandle(hFile);
  300. FileTimeToLocalFileTime(&IpLastWriteTime, &ltime);
  301. FileTimeToSystemTime(&ltime, &rtime); //将文件时间转化为系统时间
  302. snprintf(time, len, "%04u%02u%02u_%02u%02u%02u", rtime.wYear, rtime.wMonth, rtime.wDay, rtime.wHour, rtime.wMinute, rtime.wSecond);
  303. return 0;
  304. }
  305. static int get_ver(char *ver, uint32_t v)
  306. {
  307. uint8_t* p = (uint8_t*) & v;
  308. sprintf(ver, "v%d.%d.%d.%d", p[3], p[2], p[1], p[0]);
  309. return 0;
  310. }
  311. //////////////////////////////////////////
  312. static TCHAR* cfgPath = (TCHAR*)__TEXT("./cfg.h");
  313. int main(char argc, char *argv[])
  314. {
  315. int r=0,flen;
  316. HANDLE hFile=NULL;
  317. char* path1, * path2;
  318. char imgPath[500],*dot;
  319. fw_hdr_t fwHdr = { 0 };
  320. fw_info_t fwInfo = { 0 };
  321. fw_image_t fwImg = { 0 };
  322. data_t fcfg = {0}, fupg = {0};
  323. char time1[100],time2[100],*ptime;
  324. TCHAR* xpath1=NULL, * xpath2 = NULL,* xpath3 = NULL;
  325. int make_single_bin = 0;
  326. char version[32],md5[32];
  327. #define MD5_OFFSET1 52
  328. #define MD5_OFFSET2 84
  329. if (argc==2) {
  330. printf("make a upgrade file\n");
  331. }
  332. else if(argc == 3){
  333. printf("make a single bin\n");
  334. make_single_bin = 1;
  335. }
  336. else {
  337. printf("usage: mb app.bin or mb boot.bin app.bin\n");
  338. return -1;
  339. }
  340. r = file_read(cfgPath, &fcfg);
  341. if (r) {
  342. goto fail;
  343. }
  344. get_info(fcfg.data, &fwHdr, &fwInfo, &fwImg);
  345. get_ver(version, fwHdr.hdr.version);
  346. path1 = argv[1];
  347. if (make_single_bin) {
  348. xpath1 = char_to_tchar(path1);
  349. flen = file_read(xpath1, &fwImg.boot);
  350. if (flen < 0) {
  351. goto fail;
  352. }
  353. path2 = argv[2];
  354. xpath2 = char_to_tchar(path2);
  355. flen = file_read(xpath2, &fwImg.app1);
  356. if (flen < 0) {
  357. goto fail;
  358. }
  359. md5_calc(fwImg.app1.data, fwImg.app1.dlen, md5);
  360. memcpy(((char*)&fwHdr) + MD5_OFFSET1, md5, sizeof(md5));
  361. memcpy(((char*)&fwHdr) + MD5_OFFSET2, md5, sizeof(md5));
  362. if (fwImg.info.data) {
  363. memcpy(fwImg.info.data, &fwInfo, fwImg.info.blen);
  364. }
  365. get_time(xpath1, time1, sizeof(time1));
  366. get_time(xpath2, time2, sizeof(time2));
  367. if (memcmp(time1, time2, sizeof(time1)) > 0) {
  368. ptime = time1;
  369. }
  370. else {
  371. ptime = time2;
  372. }
  373. strcpy(imgPath, path1);
  374. dot = strrchr(imgPath, '\\');
  375. if (dot) {
  376. dot[1] = 0;
  377. }
  378. else {
  379. imgPath[0] = 0;
  380. }
  381. strcat(imgPath, "all_");
  382. strcat(imgPath, version);
  383. strcat(imgPath, "_");
  384. strcat(imgPath, ptime);
  385. strcat(imgPath, ".bin");
  386. xpath3 = char_to_tchar(imgPath);
  387. hFile = CreateFile(xpath3, //name
  388. GENERIC_WRITE, //以写方式打开
  389. 0, //可共享读
  390. NULL, //默认安全设置
  391. CREATE_ALWAYS, //创建新文件
  392. FILE_ATTRIBUTE_NORMAL, //常规文件属性
  393. NULL);
  394. if (!hFile) {
  395. goto fail;
  396. }
  397. WriteFile(hFile, fwImg.boot.data, fwImg.boot.blen, NULL, NULL);
  398. WriteFile(hFile, fwImg.info.data, fwImg.info.blen, NULL, NULL);
  399. WriteFile(hFile, fwImg.app1.data, fwImg.app1.blen, NULL, NULL);
  400. WriteFile(hFile, fwImg.app1.data, fwImg.app1.blen, NULL, NULL);
  401. }
  402. else {
  403. xpath1 = char_to_tchar(path1);
  404. flen = file_read(xpath1, &fupg);
  405. if (flen < 0) {
  406. goto fail;
  407. }
  408. get_time(xpath1, time1, sizeof(time1));
  409. strcpy(imgPath, path1);
  410. dot = strrchr(imgPath, '\\');
  411. if (dot) {
  412. dot[1] = 0;
  413. }
  414. else {
  415. imgPath[0] = 0;
  416. }
  417. strcat(imgPath, "app_");
  418. strcat(imgPath, version);
  419. strcat(imgPath, "_");
  420. strcat(imgPath, time1);
  421. strcat(imgPath, ".upg");
  422. xpath3 = char_to_tchar(imgPath);
  423. hFile = CreateFile(xpath3, //name
  424. GENERIC_WRITE, //以写方式打开
  425. 0, //可共享读
  426. NULL, //默认安全设置
  427. CREATE_ALWAYS, //创建新文件
  428. FILE_ATTRIBUTE_NORMAL, //常规文件属性
  429. NULL);
  430. if (!hFile) {
  431. goto fail;
  432. }
  433. md5_calc(fupg.data, fupg.dlen, md5);
  434. memcpy(((char*)&fwHdr) + MD5_OFFSET1, md5, sizeof(md5));
  435. WriteFile(hFile, &fwHdr, sizeof(fwHdr), NULL, NULL);
  436. WriteFile(hFile, fupg.data, fupg.dlen, NULL, NULL);
  437. //WriteFile(hFile, &md5, sizeof(md5), NULL, NULL);
  438. print_md5("md5: ", md5);
  439. }
  440. fail:
  441. if(hFile) CloseHandle(hFile);
  442. delete xpath1;delete xpath2;delete xpath3;
  443. return r;
  444. }