📄 mtkmenu.c
字号:
/* mtkmenu, 6/sep/03
(c)copyright 2003, av_pete
a tool to display contents of a mtkosd menu string block.
note: this tool does *not* correlate menu items to code functions.
mtkosd menu string block overview:
the menu block has a header which points to an index (see mtk_header_t).
the index points to numerous menu sets. there is typically a menu set for
each language supported by the firmware. within each menu set there are
numerous records. each records stores some basic fields (see mtk_record_t)
and the string text.
*/
#include <stdlib.h>
#include <stdio.h>
typedef struct {
unsigned char magic[12]; /* "MTKOSD 0.1\0\0" */
int index;
} mtk_header_t;
typedef struct {
char length1;
char length2;
char zero; /* often zero; possibly a "flags" field */
} mtk_record_t;
/* ------------------------ */
#define SANITIZE(X) ( ((X)<32||(X)>127) ? '.' : (X) )
void print_raw(unsigned char *buf, int length)
{
int i;
for(i=0;i<length;i++)
printf("%c", SANITIZE(buf[i]));
}
void dump_menu(int start_address, int table_offset, int data_offset, FILE *f)
{
mtk_record_t rec;
int num_records, i;
fseek(f, start_address + table_offset, SEEK_SET);
fread(&num_records, sizeof(long), 1, f);
for (i=0; i < num_records ; i++) {
int offset;
unsigned char buf[1024];
fseek(f, start_address + table_offset + 4 + i*4, SEEK_SET);
fread(&offset, sizeof(long), 1, f);
fseek(f, start_address + data_offset + offset, SEEK_SET);
fread(&rec, sizeof(mtk_record_t), 1, f);
fread(buf, rec.length1, 1, f);
printf("%3i: 0x%x\t : %2i %2i %2i : ", i, offset, rec.length1, rec.length2, rec.zero);
print_raw(buf, rec.length1);
printf("\n");
if (rec.length1 != rec.length2) printf("warning: length1 != length2\n");
if (rec.zero != 0) printf("warning: zero != 0\n");
}
}
#define MAX_NUM_MENUS 1024
int main(int argc, char **argv)
{
FILE * f;
mtk_header_t hdr;
unsigned int start_address;
int i;
int num_menus;
int menu[MAX_NUM_MENUS][2];
if (argc<2||argc>4) {
printf("usage: %s filename.bin [start_address]\n", argv[0]);
printf("\nstart_address=location in file where MTKOSD 0.1 magic header appears\n");
return 0;
}
f = fopen(argv[1], "rb");
if (f==NULL) {
printf("fopen failed\n");
return EXIT_FAILURE;
}
if (argc==3) {
if (sscanf(argv[2],"0x%x", &start_address)!=1 &&
sscanf(argv[2],"%u", &start_address)!=1) {
printf("invalid start_address\n");
fclose(f);
return EXIT_FAILURE;
}
}else{
start_address = 0;
}
printf("[header]\n");
fseek(f, start_address, SEEK_SET);
fread(&hdr, sizeof(mtk_header_t), 1, f);
printf("magic "); print_raw(hdr.magic, 12); printf("\n");
printf("index %i (0x%x)\n", hdr.index, hdr.index);
printf("\n[menu index]\n");
fseek(f, start_address + hdr.index, SEEK_SET);
fread(&num_menus, sizeof(long), 1, f);
printf("num_menus %i (0x%x)\n", num_menus, num_menus);
if (num_menus > MAX_NUM_MENUS) {
printf("warning: insufficient menus[] array; increase MAX_NUM_MENUS\n");
}
/* read menu index offsets */
for (i=0; i < num_menus ; i++) {
fread(&menu[i][0], sizeof(long), 1, f);
}
/* read menu data offsets */
printf("num : index\t : data\n");
printf("--------------------------\n");
for (i=0; i < num_menus ; i++) {
fread(&menu[i][1], sizeof(long), 1, f);
printf("%03i : 0x%x\t : 0x%x\n", i, menu[i][0], menu[i][1]);
}
printf("\n");
for (i=0; i < num_menus ; i++) {
printf("\n[menu %i]\n", i);
dump_menu(start_address, menu[i][0], menu[i][1], f);
}
fclose(f);
return EXIT_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -