Skip to content

Instantly share code, notes, and snippets.

@TomKing062
Created February 17, 2026 09:59
Show Gist options
  • Select an option

  • Save TomKing062/b92f5c923e0675326e562a5a9655ecb0 to your computer and use it in GitHub Desktop.

Select an option

Save TomKing062/b92f5c923e0675326e562a5a9655ecb0 to your computer and use it in GitHub Desktop.
#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