Created
February 17, 2026 09:59
-
-
Save TomKing062/b92f5c923e0675326e562a5a9655ecb0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <stdint.h> | |
| #include <string.h> | |
| #include <stdlib.h> | |
| #include <ctype.h> | |
| typedef struct | |
| { | |
| uint8_t* raw_buf, * enc_buf, * temp_buf; | |
| int flags, recv_len, recv_pos; | |
| int raw_len, enc_len, verbose, timeout; | |
| } spdio_t; | |
| #define FLAGS_CRC16 1 | |
| #define FLAGS_TRANSCODE 2 | |
| #define HDLC_HEADER 0x7e | |
| #define HDLC_ESCAPE 0x7d | |
| #define CHK_FIXZERO 1 | |
| #define CHK_ORIG 2 | |
| #define ERR_EXIT(...) \ | |
| do \ | |
| { \ | |
| fprintf(stderr, __VA_ARGS__); \ | |
| system("pause"); \ | |
| exit(1); \ | |
| } while (0) | |
| #define DBG_LOG(...) fprintf(stderr, __VA_ARGS__) | |
| #define WRITE16_LE(p, a) \ | |
| do \ | |
| { \ | |
| ((uint8_t *)(p))[0] = (uint8_t)(a); \ | |
| ((uint8_t *)(p))[1] = (a) >> 8; \ | |
| } while (0) | |
| #define WRITE32_LE(p, a) \ | |
| do \ | |
| { \ | |
| ((uint8_t *)(p))[0] = (uint8_t)(a); \ | |
| ((uint8_t *)(p))[1] = (a) >> 8; \ | |
| ((uint8_t *)(p))[2] = (a) >> 16; \ | |
| ((uint8_t *)(p))[3] = (a) >> 24; \ | |
| } while (0) | |
| #define READ32_LE(p) ( \ | |
| ((uint8_t *)(p))[0] | \ | |
| ((uint8_t *)(p))[1] << 8 | \ | |
| ((uint8_t *)(p))[2] << 16 | \ | |
| ((uint8_t *)(p))[3] << 24) | |
| #define WRITE16_BE(p, a) \ | |
| do \ | |
| { \ | |
| ((uint8_t *)(p))[0] = (a) >> 8; \ | |
| ((uint8_t *)(p))[1] = (uint8_t)(a); \ | |
| } while (0) | |
| #define WRITE32_BE(p, a) \ | |
| do \ | |
| { \ | |
| ((uint8_t *)(p))[0] = (a) >> 24; \ | |
| ((uint8_t *)(p))[1] = (a) >> 16; \ | |
| ((uint8_t *)(p))[2] = (a) >> 8; \ | |
| ((uint8_t *)(p))[3] = (uint8_t)(a); \ | |
| } while (0) | |
| #define READ16_BE(p) ( \ | |
| ((uint8_t *)(p))[0] << 8 | \ | |
| ((uint8_t *)(p))[1]) | |
| #define READ32_BE(p) ( \ | |
| ((uint8_t *)(p))[0] << 24 | \ | |
| ((uint8_t *)(p))[1] << 16 | \ | |
| ((uint8_t *)(p))[2] << 8 | \ | |
| ((uint8_t *)(p))[3]) | |
| spdio_t* spdio_init(int flags) | |
| { | |
| uint8_t* p; | |
| spdio_t* io; | |
| p = (uint8_t*)malloc(sizeof(spdio_t) + (4 + 0x10000 + 2) * 3 + 2); | |
| io = (spdio_t*)p; | |
| if (!p) | |
| ERR_EXIT("malloc failed\n"); | |
| memset(io, 0, sizeof(spdio_t)); | |
| p += sizeof(spdio_t); | |
| io->flags = flags; | |
| io->temp_buf = p + 4; | |
| io->raw_buf = p; | |
| p += 4 + 0x10000 + 2; | |
| io->enc_buf = p; | |
| io->timeout = 1000; | |
| return io; | |
| } | |
| unsigned recv_type(uint8_t* buf) | |
| { | |
| // if (io->raw_len < 6) return -1; | |
| return READ16_BE(buf); | |
| } | |
| #define MAX_DATA_SIZE 4096 | |
| int is7E(const char* str) | |
| { | |
| return (tolower((unsigned char)str[0]) == '7' && tolower((unsigned char)str[1]) == 'e'); | |
| } | |
| void parseHexByte(const char* ptr, unsigned char* out) | |
| { | |
| char hexStr[3] = { 0 }; | |
| int i = 0; | |
| while (i < 2) | |
| { | |
| hexStr[i++] = *ptr++; | |
| } | |
| *out = (unsigned char)strtol(hexStr, NULL, 16); | |
| } | |
| int main(int argc, char* argv[]) | |
| { | |
| if (argc != 2) | |
| { | |
| fprintf(stderr, "用法: %s <输入文件>\n", argv[0]); | |
| return 1; | |
| } | |
| FILE* file = fopen(argv[1], "r"); | |
| if (!file) | |
| { | |
| perror("无法打开文件"); | |
| return 1; | |
| } | |
| int out_count = 0; | |
| char out_name[40] = { 0 }; | |
| FILE* fo = NULL; | |
| spdio_t* io = NULL; | |
| io = spdio_init(0); | |
| io->flags |= FLAGS_TRANSCODE; | |
| char line[0xfffff]; | |
| unsigned char extractedData[MAX_DATA_SIZE] = { 0 }; | |
| int extractedCount = 0; | |
| int in7EBlock = 0; | |
| int start_addr = 0, read_len = 0, file_len = 0; | |
| while (fgets(line, sizeof(line), file)) | |
| { | |
| int extractedCount = 0; | |
| int in7EBlock = 0; | |
| const char* ptr = line; | |
| while (*ptr) | |
| { | |
| if (is7E(ptr)) | |
| { | |
| if (!in7EBlock) | |
| { | |
| extractedData[extractedCount++] = 0x7e; | |
| in7EBlock = 1; | |
| ptr += 3; | |
| continue; | |
| } | |
| else | |
| { | |
| extractedData[extractedCount++] = 0x7e; | |
| break; | |
| } | |
| } | |
| if (in7EBlock && extractedCount < MAX_DATA_SIZE) | |
| { | |
| unsigned char byte; | |
| parseHexByte(ptr, &byte); | |
| extractedData[extractedCount++] = byte; | |
| ptr += 3; | |
| } | |
| else | |
| { | |
| ptr++; | |
| } | |
| } | |
| if (!extractedCount) continue; | |
| printf("addr 0x%08x, extractedCount 0x%0x, ", start_addr + read_len, extractedCount); | |
| int ret = recv_type(&extractedData[1]); | |
| { | |
| unsigned char* pdump = &extractedData[1]; | |
| uint8_t* p = io->raw_buf; | |
| while (*pdump != 0x7e) { | |
| uint8_t chdump = *(pdump++); | |
| if (chdump == 0x7d) { | |
| if (*pdump == 0x5d || *pdump == 0x5e) chdump = *(pdump++) + 0x20; | |
| } | |
| *p++ = chdump; | |
| } | |
| printf("trans 0x%0x\n", (p - io->raw_buf)); | |
| } | |
| if (ret == 1) | |
| { | |
| if (file_len) | |
| { | |
| if (read_len != file_len) | |
| DBG_LOG("addr 0x%0x, wanted 0x%0x, recv 0x%0x!\n", start_addr, file_len, read_len); | |
| else { | |
| fclose(file); | |
| fclose(fo); | |
| return 0; | |
| } | |
| } | |
| start_addr = READ32_BE(io->raw_buf + 4); | |
| sprintf(out_name, "payload__0x%x.bin", start_addr); | |
| fo = fopen(out_name, "wb"); | |
| //fseek(fo, (start_addr & 0x000fffff), 0); | |
| file_len = READ32_BE(io->raw_buf + 8); | |
| read_len = 0; | |
| } | |
| else if (ret == 2) | |
| { | |
| int len = READ16_BE(io->raw_buf + 2); | |
| fwrite(io->raw_buf + 4, 1, len, fo); | |
| read_len += len; | |
| } | |
| else if (ret == 3) | |
| { | |
| printf("current start addr 0x%0x\n", start_addr); | |
| fclose(fo); | |
| out_count++; | |
| sprintf(out_name, "out_%d.bin", out_count); | |
| FILE* fo = fopen(out_name, "wb"); | |
| } | |
| else | |
| printf("ret_type = 0x%0x\n", ret); | |
| } | |
| fclose(file); | |
| fclose(fo); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment