mb.cpp 11 KB

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