From d37947cb7a709aeb9fca5ca96bced7fcb9c9db4d Mon Sep 17 00:00:00 2001 From: naf Date: Wed, 16 Oct 2024 14:55:13 -0500 Subject: [PATCH] param_dump: common sources between devices --- obi2xx/param_dump.c | 191 +++++++++++++++++----- obi5xx/param_dump.c | 202 +---------------------- obid230/param_dump.c | 363 +----------------------------------------- obiphone/param_dump.c | 258 +----------------------------- 4 files changed, 150 insertions(+), 864 deletions(-) mode change 100644 => 120000 obi5xx/param_dump.c mode change 100755 => 120000 obid230/param_dump.c mode change 100644 => 120000 obiphone/param_dump.c diff --git a/obi2xx/param_dump.c b/obi2xx/param_dump.c index e149d8e..aaefcc9 100755 --- a/obi2xx/param_dump.c +++ b/obi2xx/param_dump.c @@ -19,50 +19,128 @@ Map m; void dump_section(FILE* file, size_t location, unsigned char mask[6]); -static const int OFFSET_MAC = 0x40100; -static const int OFFSET_HWVERS = 0x40010; -static const int OFFSET_PARAM_1 = 0x400000; -static const int OFFSET_PARAM_2 = 0x420000; -static const int OFFSET_PARAM_ZT = 0x460000; +#if OBI_DEVICE == 200 + #define OFFSET_MAC 0x40100 + #define OFFSET_HWVERS 0x40010 + #define OFFSET_PARAM_1 0x400000 + #define OFFSET_PARAM_2 0x420000 + #define OFFSET_PARAM_ZT 0x460000 + #define MTD_DEV "/dev/mtd6ro" + #define PARAMS_DEV "/dev/mtd6ro" +#elif OBI_DEVICE == 500 + #define OFFSET_MAC 0xA0100 + #define OFFSET_HWVERS 0xA0010 + #define OFFSET_PARAM_1 0x1F00000 + #define OFFSET_PARAM_2 0x1F80000 + #define OFFSET_PARAM_ZT 0xB0000 + #define MTD_DEV "/dev/mtd5ro" + #define PARAMS_DEV "/dev/mtd5ro" +#elif OBI_DEVICE == 1000 + #define OFFSET_MAC 0x300100 + #define OFFSET_HWVERS 0x300010 + #define OFFSET_PARAM_1 0x0 + #define OFFSET_PARAM_2 0x20000 + #define OFFSET_PARAM_ZT 0x340000 + #define MTD_DEV "/dev/mtd11ro" + #define PARAMS_DEV "/scratch/obiparam.dat" +#elif OBI_DEVICE == 2000 + #define OFFSET_MAC 0x100100 + #define OFFSET_HWVERS 0x100010 + #define OFFSET_PARAM_1 0x0 + #define OFFSET_PARAM_2 0x20000 + #define OFFSET_PARAM_ZT 0x180000 + #define MTD_DEV "/dev/mtd2ro" + #define PARAMS_DEV "/scratch/obiparam.dat" +#elif OBI_DEVICE == 1000 + #define OFFSET_MAC 0x300100 + #define OFFSET_HWVERS 0x300010 + #define OFFSET_PARAM_1 0x0 + #define OFFSET_PARAM_2 0x20000 + #define OFFSET_PARAM_ZT 0x340000 + #define MTD_DEV "/dev/mtd11ro" + #define PARAMS_DEV "/scratch/obiparam.dat" +#elif OBI_DEVICE == 500 + #define OFFSET_MAC 0xA0100 + #define OFFSET_HWVERS 0xA0010 + #define OFFSET_PARAM_1 0x1F00000 + #define OFFSET_PARAM_2 0x1F80000 + #define OFFSET_PARAM_ZT 0xB0000 + #define MTD_DEV "/dev/mtd5ro" + #define PARAMS_DEV "/dev/mtd5ro" +#elif OBI_DEVICE == 230 + #define OFFSET_PARAM_1 0x0 + #define OFFSET_PARAM_2 0x80000 + #define OFFSET_PARAM_ZT 0x0 + #define MTD_DEV "/scratch/obizt.dat" + #define PARAMS_DEV "/scratch/obiparam.dat" +#else + #error "Must define OBI_DEVICE to be 200/500/1000/2000" +#endif + static int debug = 0; int main(int argc, char** argv) { map_init(); - FILE* fd; + char* mtd_name; + char* obiparam_name; - if (argc < 2) - fd = fopen("/dev/mtd6ro", "rb"); - else - fd = fopen(argv[1], "rb"); + FILE* fd_mtd; - unsigned char mac[6]; - fseek(fd, OFFSET_MAC, SEEK_SET); - fread(mac, sizeof(mac), 1, fd); + if (argc == 3) { + mtd_name = argv[1]; + obiparam_name = argv[2]; + } else if (argc == 2) { + mtd_name = argv[1]; + obiparam_name = argv[1]; + } else { + mtd_name = MTD_DEV; + obiparam_name = PARAMS_DEV; + } + + fd_mtd = fopen(mtd_name, "rb"); + if (!fd_mtd) { + printf("ERROR: cannot open %s\n", mtd_name); + return 1; + } + int need_mask; + unsigned char mac[6]; unsigned char hw_vers[4]; - fseek(fd, OFFSET_HWVERS, SEEK_SET); - fread(hw_vers, sizeof(hw_vers), 1, fd); +#if OBI_DEVICE != 230 + fseek(fd_mtd, OFFSET_MAC, SEEK_SET); + fread(mac, sizeof(mac), 1, fd_mtd); + + fseek(fd_mtd, OFFSET_HWVERS, SEEK_SET); + fread(hw_vers, sizeof(hw_vers), 1, fd_mtd); printf("mac: %02x%02x%02x%02x%02x%02x, hw_vers: %02x%02x%02x%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], hw_vers[0], hw_vers[1], hw_vers[2], hw_vers[3]); - int need_mask; - if (hw_vers[0] == 0x00 && hw_vers[1] == 0x01 && hw_vers[3] == 0xff) { - if (hw_vers[2] == 0x04 || hw_vers[2] == 0x05) - need_mask = 1; - else if (hw_vers[2] == 0x00 || hw_vers[2] == 0x01 || hw_vers[2] == 0x02 || hw_vers[2] == 0x03) - need_mask = 0; - else { - printf("unknown hw_vers\n"); - return 1; - } - } else { + if (!(hw_vers[0] == 0x00 && hw_vers[1] == 0x01 && hw_vers[3] == 0xff)) { + printf("unknown hw_vers\n"); + return 1; + } +#endif + +#if OBI_DEVICE == 200 + if (hw_vers[2] == 0x04 || hw_vers[2] == 0x05) + need_mask = 1; + else if (hw_vers[2] == 0x00 || hw_vers[2] == 0x01 || hw_vers[2] == 0x02 || hw_vers[2] == 0x03) + need_mask = 0; + else { printf("unknown hw_vers\n"); return 1; } +#elif OBI_DEVICE == 230 + printf("assuming need_mask = false\n"); + need_mask = 0; +#else + printf("assuming need_mask = true\n"); + need_mask = 1; +#endif printf("using mac as rc4 key mask: %s\n", need_mask ? "true" : "false"); @@ -71,11 +149,18 @@ int main(int argc, char** argv) memcpy(&mask[0], &mac[0], 6); } - dump_section(fd, OFFSET_PARAM_1, mask); - dump_section(fd, OFFSET_PARAM_2, mask); - dump_section(fd, OFFSET_PARAM_ZT, mask); + FILE* fd_param = fopen(obiparam_name, "rb"); + if (!fd_param) { + printf("WARN: cannot open %s\n", obiparam_name); + } else { + dump_section(fd_param, OFFSET_PARAM_1, mask); + dump_section(fd_param, OFFSET_PARAM_2, mask); + fclose(fd_param); + } + + dump_section(fd_mtd, OFFSET_PARAM_ZT, mask); - fclose(fd); + fclose(fd_mtd); map_free(&m); @@ -140,6 +225,7 @@ void warn_on_checksum_mismatch(unsigned char* data, int len, int expected) { void dump_section(FILE* file, size_t location, unsigned char mask[6]) { + int i; printf("-- params at %08x --\n", location); static const int KEY_LENGTH = 15; @@ -160,6 +246,22 @@ void dump_section(FILE* file, size_t location, unsigned char mask[6]) section_header[13] << 8 | section_header[12]; + if (debug) { + printf("raw section header: ", SECTION_HEADER_LEN); + for (i = 0; i < SECTION_HEADER_LEN; ++i) + printf("%02x", section_header[i]); + printf("\n"); + } + + if (section_header[0] == 0xFF && section_header[1] == 0xFF && + section_header[2] == 0xFF && section_header[3] == 0xFF) { + printf("WARN: empty section header\n"); + return; + } else if (section_header[0] != 0xFD && section_header[0] != 0xFB) { + printf("ERROR: unknown packed encryption scheme: %02x\n", section_header[0]); + return; + } + unsigned char* section_ciphertext = malloc(section_payload_len); unsigned char* section_plaintext = malloc(section_payload_len); @@ -168,7 +270,6 @@ void dump_section(FILE* file, size_t location, unsigned char mask[6]) memcpy(keytext, section_header, KEY_LENGTH); keytext[0] = 0xFD; - int i; for (i = 0; i < 6; ++i) keytext[i] &= mask[i]; @@ -179,11 +280,6 @@ void dump_section(FILE* file, size_t location, unsigned char mask[6]) if (debug) { - printf("raw section header: ", SECTION_HEADER_LEN); - for (i = 0; i < SECTION_HEADER_LEN; ++i) - printf("%02x", section_header[i]); - printf("\n"); - printf("raw section payload: ", section_payload_len); for (i = 0; i < section_payload_len; ++i) { printf("%02x", section_plaintext[i]); @@ -219,6 +315,20 @@ void dump_section(FILE* file, size_t location, unsigned char mask[6]) param_header[9] << 8 | param_header[8]; + if (debug) { + printf("@ %08x\n", current_loc); + + printf("raw header: ", PARAM_HEADER_LEN); + for (i = 0; i < PARAM_HEADER_LEN; ++i) + printf("%02x", param_header[i]); + printf("\n"); + } + + if (param_header[0] != 0xFC) { + printf("ERROR: unknown unpacked encryption scheme: %02x\n", param_header[0]); + return; + } + memcpy(keytext, param_header, KEY_LENGTH); unsigned char* param_ciphertext = malloc(param_payload_len); @@ -236,13 +346,6 @@ void dump_section(FILE* file, size_t location, unsigned char mask[6]) RC4(&key, param_payload_len, param_ciphertext, param_plaintext); if (debug) { - printf("@ %08x\n", current_loc); - - printf("raw header: ", PARAM_HEADER_LEN); - for (i = 0; i < PARAM_HEADER_LEN; ++i) - printf("%02x", param_header[i]); - printf("\n"); - printf("raw payload: ", param_payload_len); for (i = 0; i < param_payload_len; ++i) { printf("%02x", param_plaintext[i]); @@ -304,7 +407,7 @@ void addHashIndexed(Map* m, const char* fmt, int i) void map_init() { //hidden or non-backup params int i; - for (i = 1; i <= 4; ++i) { + for (i = 1; i <= 9; ++i) { addHashIndexed(&m, "VoiceService.1.VoiceProfile.%d.GVSIP", i); addHashIndexed(&m, "VoiceService.1.VoiceProfile.1.Line.%d.X_GApiRefreshToken", i); addHashIndexed(&m, "VoiceService.1.VoiceProfile.1.Line.%d.X_GApiAccessToken", i); diff --git a/obi5xx/param_dump.c b/obi5xx/param_dump.c deleted file mode 100644 index c239b6b..0000000 --- a/obi5xx/param_dump.c +++ /dev/null @@ -1,201 +0,0 @@ -// arm-unknown-linux-uclibcgnueabi-g++ -static param_dump.c -o param_dump -lcrypto -// *or* -// g++ param_dump.c -o param_dump -lcrypto - - -#include -#include -#include -#include -#include -#include -#include - -using namespace std; - -map init_map() { - map m; - //manual - m["f5e1d7f1"] = "DHCP/DefaultGateway"; - m["4d56eeaf"] = "X_GApiAccessToken"; - m["e261b32a"] = "VS1.VP1.L1.X_GApiRefreshToken"; - //auto -#include "param_dump_keys.h" - return m; -}; - -std::string string_format(const string& format, size_t size_man, ...) -{ - va_list args; - va_start(args, size_man); - //snprintf returns 20 instead of 8 for "%02x%02x%02x%02x". wtf? - size_t size = size_man + 1; //snprintf(nullptr, 0, format.c_str(), args) + 1; - char* buf = new char[size]; - vsnprintf(buf, size, format.c_str(), args); - string str(buf, buf + size - 1); - delete buf; - return str; - va_end(args); -} - -void dump_section(FILE* file, size_t location, unsigned char mask[6]); -void dump_section_zt(FILE* file, size_t location, unsigned char mask[6]); - -map m = init_map(); - -int main(void) -{ - FILE* fd; - fd = fopen("/dev/mtd5ro", "rb"); - //fd = fopen("mtd5ro", "rb"); - - unsigned char mac[6]; - fseek(fd, 0xa0100, SEEK_SET); - fread(mac, sizeof(mac), 1, fd); - - unsigned char hw_vers[4]; - fseek(fd, 0xa0010, SEEK_SET); - fread(hw_vers, sizeof(hw_vers), 1, fd); - - printf("mac: %02x%02x%02x%02x%02x%02x, hw_vers: %02x%02x%02x%02x\n", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], - hw_vers[0], hw_vers[1], hw_vers[2], hw_vers[3]); - - unsigned char mask[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - memcpy(&mask[0], &mac[0], 6); - - dump_section(fd, 0x1f00000, mask); - dump_section(fd, 0x1f80000, mask); - dump_section_zt(fd, 0xb0000, mask); - - fclose(fd); - - return 0; -} - -void print_param(unsigned char* p) -{ - string param_key = string_format("%02x%02x%02x%02x", 8, - p[3], p[2], p[1], p[0]); - - string param_name = param_key + " (\?\?\?)"; - if (m.find(param_key) != m.end()) - { - param_name = param_key + " (" + m[param_key] + ")"; - } - - for (int i = 0; i < 4; ++i) - printf("%02x", p[i]); - printf(" "); - for (int i = 4; i < 8; ++i) - printf("%02x", p[i]); - - printf(": "); - printf(param_name.c_str()); - printf(" = "); - - int len = p[4]; - int type = p[7]; - - if (type == 1 || type == 4 || type == 5) { - printf("\"%.*s\"", len, &p[8]); - } else { - printf("0x"); - for (int i = 0; i < len; ++i) - printf("%02x", p[i+8]); - } - - printf("\n"); - -} - -void dump_section(FILE* file, size_t location, unsigned char mask[6]) -{ - printf("-- params at %08x --\n", location); - fseek( file, location + 0x100, SEEK_SET ); - - int header_len = 16; - int payload_len = 240; - - unsigned char* ciphertext = (unsigned char*) malloc(sizeof(char) * payload_len); - unsigned char* plaintext = (unsigned char*) malloc(sizeof(char) * payload_len); - unsigned char* keytext = (unsigned char*) malloc(sizeof(char) * header_len); - - - while (fread(keytext, 1, header_len, file) == header_len && - keytext[0] != 0xFF) { - - fread(ciphertext, 1, payload_len, file); - - //little endian obi200 - if (keytext[0] == 0xFC) - keytext[0] = 0xFE; - else { - printf("WARN: unknown encrpytion type = %02x\n", keytext[0]); - keytext[0] += 2; - } - - for (int i = 0; i < 6; ++i) - keytext[i] &= mask[i]; - - RC4_KEY key; - RC4_set_key(&key, 15, keytext); - - RC4(&key, payload_len, ciphertext, plaintext); - - print_param(plaintext); - } - - free(ciphertext); - free(plaintext); - free(keytext); -} - -void dump_section_zt(FILE* file, size_t location, unsigned char mask[6]) -{ - printf("-- params at %08x --\n", location); - fseek( file, location, SEEK_SET ); - - int header_len = 256; - - unsigned char* keytext = (unsigned char*) malloc(sizeof(char) * header_len); - - fread(keytext, 1, header_len, file); - - int payload_len = keytext[15] << 24 | - keytext[14] << 16 | - keytext[13] << 8 | - keytext[12]; - - unsigned char* ciphertext = (unsigned char*) malloc(sizeof(char) * payload_len); - unsigned char* plaintext = (unsigned char*) malloc(sizeof(char) * payload_len); - - - fread(ciphertext, 1, payload_len, file); - - //little endian obi500 - keytext[0] = 0xFD; - - for (int i = 0; i < 6; ++i) - keytext[i] &= mask[i]; - - RC4_KEY key; - RC4_set_key(&key, 15, keytext); - - RC4(&key, payload_len, ciphertext, plaintext); - - unsigned char* current = plaintext; - while (current < plaintext + payload_len && current[0] != 0xff) - { - print_param(current); - int len = 8 + current[4]; - current += len; - } - - printf("\n"); - - free(ciphertext); - free(plaintext); - free(keytext); - -} diff --git a/obi5xx/param_dump.c b/obi5xx/param_dump.c new file mode 120000 index 0000000..0004cb0 --- /dev/null +++ b/obi5xx/param_dump.c @@ -0,0 +1 @@ +../obi2xx/param_dump.c \ No newline at end of file diff --git a/obid230/param_dump.c b/obid230/param_dump.c deleted file mode 100755 index b770ad8..0000000 --- a/obid230/param_dump.c +++ /dev/null @@ -1,362 +0,0 @@ -// arm-unknown-linux-gnueabi-gcc param_dump.c -o param_dump -L /path/to/openssl/lib -l crypto -I /path/to/openssl/include -// *or* -// gcc param_dump.c -o param_dump -lcrypto - -#define _GNU_SOURCE //for asprintf - -#include -#include -#include -#include -#include - -typedef struct Map Map; -void map_init(); -const char* map_get(Map* table, const unsigned int key); -int map_insert(Map* table, const unsigned int key, const char* value); -void map_free(Map* table); -Map m; - -void dump_section(FILE* file, size_t location, unsigned char mask[6]); - -static const int OFFSET_PARAM_1 = 0x0; -static const int OFFSET_PARAM_2 = 0x80000; -static const int OFFSET_PARAM_ZT = 0x0; -static int debug = 0; - -int main(int argc, char** argv) -{ - map_init(); - - const char* obiparam_name = "/scratch/obiparam.dat"; - const char* obizt_name = "/scratch/obizt.dat"; - - FILE* fd_param; - FILE* fd_zt; - - if (argc < 2) { - fd_param = fopen(obiparam_name, "rb"); - fd_zt = fopen(obizt_name, "rb"); - } else if (argc == 3) { - fd_param = fopen(argv[1], "rb"); - fd_zt = fopen(argv[2], "rb"); - } else { - printf("USAGE: param_dump [/path/to/obiparam.dat /path/to/obizt.dat]\n"); - return 1; - } - - unsigned char mask[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - - if (fd_param) { - dump_section(fd_param, OFFSET_PARAM_1, mask); - dump_section(fd_param, OFFSET_PARAM_2, mask); - fclose(fd_param); - } else { - printf("ERROR: cannot open obiparam.dat\n"); - } - - if (fd_zt) { - dump_section(fd_zt, OFFSET_PARAM_ZT, mask); - fclose(fd_zt); - } else { - printf("ERROR: cannot open obizt.dat\n"); - } - - map_free(&m); - - return 0; -} - -int print_param(unsigned char* p) -{ - unsigned int param_key = p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0]; - - const char* param_key_name = map_get(&m, param_key); - - int i; - for (i = 0; i < 4; ++i) - printf("%02x", p[i]); - printf(" "); - for (i = 4; i < 8; ++i) - printf("%02x", p[i]); - printf(": "); - - printf("%08x (%s)", param_key, param_key_name != NULL ? param_key_name : ""); - printf(" = "); - - int len = p[4] | p[5] << 8; - //printf("[len %u] ", len); - int type = p[7]; - - if (type == 1 || type == 4 || type == 5) { - printf("\"%.*s\"", len, &p[8]); - } else { - printf("0x"); - for (i = 0; i < len; ++i) - printf("%02x", p[i+8]); - } - - printf("\n"); - - return 8+len; -} - -void print_params(unsigned char* plaintext, int payload_len) -{ - unsigned char* current = plaintext; - while (current < plaintext + payload_len && - !(current[0] == 0xFF && current[1] == 0xFF && current[2] == 0xFF && current[3] == 0xFF)) - { - current += print_param(current); - } -} - -void dump_section(FILE* file, size_t location, unsigned char mask[6]) -{ - printf("-- params at %08x --\n", location); - - static const int KEY_LENGTH = 15; - unsigned char keytext[KEY_LENGTH]; - - fseek( file, location, SEEK_SET ); - size_t current_loc = location; - - //first, read packed params at begninning - - static const int SECTION_HEADER_LEN = 256; - unsigned char section_header[SECTION_HEADER_LEN]; - - current_loc += fread(section_header, 1, SECTION_HEADER_LEN, file); - - int section_payload_len = section_header[15] << 24 | - section_header[14] << 16 | - section_header[13] << 8 | - section_header[12]; - - unsigned char* section_ciphertext = malloc(section_payload_len); - unsigned char* section_plaintext = malloc(section_payload_len); - - current_loc += fread(section_ciphertext, 1, section_payload_len, file); - - memcpy(keytext, section_header, KEY_LENGTH); - - keytext[0] = 0xFD; - int i; - for (i = 0; i < 6; ++i) - keytext[i] &= mask[i]; - - RC4_KEY key; - RC4_set_key(&key, KEY_LENGTH, keytext); - - RC4(&key, section_payload_len, section_ciphertext, section_plaintext); - - - if (debug) { - printf("raw section header: ", SECTION_HEADER_LEN); - for (i = 0; i < SECTION_HEADER_LEN; ++i) - printf("%02x", section_header[i]); - printf("\n"); - - printf("raw section payload: ", section_payload_len); - int checksum = 0; - for (i = 0; i < section_payload_len; ++i) { - printf("%02x", section_plaintext[i]); - checksum += *((signed char*)§ion_plaintext[i]); - } - printf("\n"); - - printf("checksum: %08x\n", checksum); - } - - print_params(section_plaintext, section_payload_len); - - free(section_ciphertext); - free(section_plaintext); - - - - - //then, read remaining unpacked params - - static const int PARAM_HEADER_LEN = 16; - unsigned char param_header[PARAM_HEADER_LEN]; - - while (fread(param_header, 1, PARAM_HEADER_LEN, file) == PARAM_HEADER_LEN && - param_header[0] != 0xFF) { - - int param_payload_len = param_header[11] << 24 | - param_header[10] << 16 | - param_header[9] << 8 | - param_header[8]; - - memcpy(keytext, param_header, KEY_LENGTH); - - unsigned char* param_ciphertext = malloc(param_payload_len); - unsigned char* param_plaintext = malloc(param_payload_len); - - fread(param_ciphertext, 1, param_payload_len, file); - - keytext[0] = 0xFE; - for (i = 0; i < 6; ++i) - keytext[i] &= mask[i]; - - RC4_KEY key; - RC4_set_key(&key, KEY_LENGTH, keytext); - - RC4(&key, param_payload_len, param_ciphertext, param_plaintext); - - if (debug) { - printf("@ %08x\n", current_loc); - - printf("raw header: ", PARAM_HEADER_LEN); - for (i = 0; i < PARAM_HEADER_LEN; ++i) - printf("%02x", param_header[i]); - printf("\n"); - - printf("raw payload: ", param_payload_len); - int checksum = 0; - for (i = 0; i < param_payload_len; ++i) { - printf("%02x", param_plaintext[i]); - checksum += *((signed char*)¶m_plaintext[i]); - } - printf("\n"); - - printf("checksum: %08x\n", checksum); - } - - print_params(param_plaintext, param_payload_len); - - free(param_ciphertext); - free(param_plaintext); - - current_loc += PARAM_HEADER_LEN + param_payload_len; - } -} - -//simple hashmap, we dont need no stinkin c++ std::map -#define MAP_BUCKETS 1024 -struct MapNode { - unsigned int key; - const char* value; - struct MapNode* next; -}; -struct Map { - struct MapNode* buckets[MAP_BUCKETS]; -}; - -unsigned int djb2(const char* str) -{ - unsigned int hash = 5381; - int c; - - while (c = *str++) - hash = ((hash << 5) + hash) + c; // hash * 33 + c - - return hash; -} - -void addHash(Map* m, const char* val) -{ - map_insert(m, djb2(val), val); -} - -void addHashIndexed(Map* m, const char* fmt, int i) -{ - char* tmp; - asprintf(&tmp, fmt, i); - map_insert(m, djb2(tmp), tmp); - free(tmp); -} - -void map_init() { - //hidden or non-backup params - int i; - for (i = 1; i <= 4; ++i) { - addHashIndexed(&m, "VoiceService.1.VoiceProfile.%d.GVSIP", i); - addHashIndexed(&m, "VoiceService.1.VoiceProfile.1.Line.%d.X_GApiRefreshToken", i); - addHashIndexed(&m, "VoiceService.1.VoiceProfile.1.Line.%d.X_GApiAccessToken", i); - addHashIndexed(&m, "VoiceService.1.VoiceProfile.1.Line.%d.X_GApiInitAccessToken", i); - addHashIndexed(&m, "VoiceService.1.VoiceProfile.1.Line.%d.X_GoogleClientInfo", i); - } - - addHash(&m, "X_DeviceManagement.License.LicenseURL"); - - addHash(&m, "SystemInfo.DisableBT"); - addHash(&m, "SystemInfo.DisableFXO"); - addHash(&m, "SystemInfo.DisableFXS1"); - addHash(&m, "SystemInfo.DisableFXS2"); - addHash(&m, "SystemInfo.DisableGVProv"); - addHash(&m, "SystemInfo.DisableRouterCfg"); - addHash(&m, "SystemInfo.SkypeDisable"); - addHash(&m, "SystemInfo.X_GVAutoSetting"); - - addHash(&m, "VoiceService.1.X_OBP.Forbidden"); - addHash(&m, "VoiceService.1.X_OBP.BasicLicense"); - addHash(&m, "VoiceService.1.X_OBP.NoLicense"); - addHash(&m, "VoiceService.1.X_OBP.License"); - - for (i = 0; i < 8; ++i) { - addHashIndexed(&m, "X_DeviceManagement.Provisioning.SPRM%d", i); - addHashIndexed(&m, "X_DeviceManagement.ITSPProvisioning.SPRM%d", i); - } - - for (i = 4; i <=31; ++i) { - addHashIndexed(&m, "X_DeviceManagement.X_UserDefinedMacro.%d.Value", i); - addHashIndexed(&m, "X_DeviceManagement.X_UserDefinedMacro.%d.ExpandIn", i); - addHashIndexed(&m, "X_DeviceManagement.X_UserDefinedMacro.%d.SyntaxCheckResult", i); - } - - //params in backup - #include "param_dump_keys.h" -}; - -const char* map_get(Map* table, const unsigned int key) -{ - unsigned int bucket = key % MAP_BUCKETS; - struct MapNode* node; - node = table->buckets[bucket]; - while(node) { - if(key == node->key) - return node->value; - node = node->next; - } - return NULL; -} - -int map_insert(Map* table, const unsigned int key, const char* value) -{ - unsigned int bucket = key % MAP_BUCKETS; - struct MapNode** node; - - char* value_copy; - asprintf(&value_copy, "%s", value); //free'd in map_free() - - node = &table->buckets[bucket]; - while(*node) - node = &(*node)->next; - - *node = malloc(sizeof(struct MapNode)); //free'd in map_free() - if(*node == NULL) - return -1; - (*node)->next = NULL; - (*node)->key = key; - (*node)->value = value_copy; - - return 0; -} - -void map_free(Map* table) -{ - unsigned int bucket; - struct MapNode* node; - struct MapNode* next; - for (bucket = 0; bucket < MAP_BUCKETS; bucket++) { - node = table->buckets[bucket]; - while(node) { - next = node->next; - free((void*)node->value); - free(node); - node = next; - } - } -} diff --git a/obid230/param_dump.c b/obid230/param_dump.c new file mode 120000 index 0000000..0004cb0 --- /dev/null +++ b/obid230/param_dump.c @@ -0,0 +1 @@ +../obi2xx/param_dump.c \ No newline at end of file diff --git a/obiphone/param_dump.c b/obiphone/param_dump.c deleted file mode 100644 index ec059f4..0000000 --- a/obiphone/param_dump.c +++ /dev/null @@ -1,257 +0,0 @@ -// arm-unknown-linux-gnueabi-g++ param_dump.c -o param_dump -I/path/to/buildroot-2013.05/output/build/openssl-1.0.1e/include -static -lcrypto -// *or* -// g++ param_dump.c -o param_dump -lcrypto - - -#include -#include -#include -#include -#include -#include -#include - -using namespace std; - -map init_map() { - map m; - //manual - m["f5e1d7f1"] = "DHCP/DefaultGateway"; - m["4d56eeaf"] = "X_GApiAccessToken"; - m["e261b32a"] = "VS1.VP1.L1.X_GApiRefreshToken"; - //auto -#include "param_dump_keys.h" - return m; -}; - -/* -template -string string_format_c11(const string& format, Args ... args) -{ - size_t size = snprintf(nullptr, 0, format.c_str(), args ...) + 1; - unique_ptr buf(new char[size]); - snprintf(buf.get(), size, format.c_str(), args ...); - return string(buf.get(), buf.get() + size - 1); -} -*/ - -std::string string_format(const string& format, size_t size_man, ...) -{ - va_list args; - va_start(args, size_man); - //snprintf returns 20 instead of 8 for "%02x%02x%02x%02x". wtf? - size_t size = size_man + 1; //snprintf(nullptr, 0, format.c_str(), args) + 1; - char* buf = new char[size]; - vsnprintf(buf, size, format.c_str(), args); - string str(buf, buf + size - 1); - delete buf; - return str; - va_end(args); -} - -void dump_section(FILE* file, size_t location, unsigned char mask[6]); -void dump_section_zt(FILE* file, size_t location, unsigned char mask[6]); - -map m = init_map(); - -int main(void) -{ - const char* mtd_name = "/dev/mtd11ro"; - const char* obiparam_name = "/scratch/obiparam.dat"; - - static int PARAM_OFFSET = 0x20000; - static int MTD_ZT_OFFSET = 0x340000; - - FILE* fd_mtd = fopen(mtd_name, "rb"); - - if (!fd_mtd) { - printf("ERROR: cannot open %s\n", mtd_name); - return 1; - } - - unsigned char mac[6]; - fseek(fd_mtd, 0x300100, SEEK_SET); - fread(mac, sizeof(mac), 1, fd_mtd); - - unsigned char hw_vers[4]; - fseek(fd_mtd, 0x300010, SEEK_SET); - fread(hw_vers, sizeof(hw_vers), 1, fd_mtd); - - printf("mac: %02x%02x%02x%02x%02x%02x, hw_vers: %02x%02x%02x%02x\n", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], - hw_vers[0], hw_vers[1], hw_vers[2], hw_vers[3]); - - bool need_mask; - if (hw_vers[0] == 0x00 && hw_vers[1] == 0x01 && hw_vers[3] == 0xff) { - if (hw_vers[2] == 0x03) - need_mask = true; - else { - printf("WARN: unknown hw_vers. assuming need_mask = true\n"); - need_mask = true; - } - } else { - printf("unknown hw_vers\n"); - return 1; - } - - printf("using mac as rc4 key mask: %s\n", need_mask ? "true" : "false"); - - unsigned char mask[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - if (need_mask) { - memcpy(&mask[0], &mac[0], 6); - } - - FILE* fd_param = fopen(obiparam_name, "rb"); - if (!fd_param) { - printf("WARN: cannot open %s\n", obiparam_name); - } else { - dump_section(fd_param, PARAM_OFFSET, mask); - fclose(fd_param); - } - - dump_section_zt(fd_mtd, MTD_ZT_OFFSET, mask); - - fclose(fd_mtd); - - return 0; -} - -void print_param(unsigned char* p) -{ - string param_key = string_format("%02x%02x%02x%02x", 8, - p[3], p[2], p[1], p[0]); - - string param_name = param_key + " (\?\?\?)"; - if (m.find(param_key) != m.end()) - { - param_name = param_key + " (" + m[param_key] + ")"; - } - - for (int i = 0; i < 4; ++i) - printf("%02x", p[i]); - printf(" "); - for (int i = 4; i < 8; ++i) - printf("%02x", p[i]); - - printf(": "); - printf(param_name.c_str()); - printf(" = "); - - int len = (p[5] << 8 | p[4]); - int type = p[7]; - - if (type == 1 || type == 4 || type == 5) { - printf("\"%.*s\"", len, &p[8]); - } else if (type == 2 || type == 3) { - printf("0x"); - for (int i = 0; i < len; ++i) - printf("%02x", p[i+8]); - } else { - printf("<<>>"); - } - - printf("\n"); - -} - -void dump_section(FILE* file, size_t location, unsigned char mask[6]) -{ - printf("-- params at %08x --\n", location); - fseek( file, location + 0x100, SEEK_SET ); - - int header_len = 16; - int payload_len = 240; - - unsigned char* ciphertext = (unsigned char*) malloc(sizeof(char) * payload_len); - unsigned char* plaintext = (unsigned char*) malloc(sizeof(char) * payload_len); - unsigned char* keytext = (unsigned char*) malloc(sizeof(char) * header_len); - - while (fread(keytext, 1, header_len, file) == header_len && - keytext[0] != 0xFF) { - - fread(ciphertext, 1, payload_len, file); - - //little endian obi200 - if (keytext[0] == 0xFC) - keytext[0] = 0xFE; - else - printf("WARN: unknown encrpytion type = %02x\n", keytext[0]); - - for (int i = 0; i < 6; ++i) - keytext[i] &= mask[i]; - - RC4_KEY key; - RC4_set_key(&key, 15, keytext); - - RC4(&key, payload_len, ciphertext, plaintext); - - print_param(plaintext); - } - - free(ciphertext); - free(plaintext); - free(keytext); -} - -void dump_section_zt(FILE* file, size_t location, unsigned char mask[6]) -{ - printf("-- params at %08x", location); - fseek( file, location, SEEK_SET ); - - int header_len = 256; - - unsigned char* keytext = (unsigned char*) malloc(sizeof(char) * header_len); - - fread(keytext, 1, header_len, file); - - int payload_len = keytext[15] << 24 | - keytext[14] << 16 | - keytext[13] << 8 | - keytext[12]; - - printf("(length %d) --\n", payload_len); - - if (keytext[0] == 0xFF || payload_len < 0) { - - printf("no params found\n"); - - } else { - - unsigned char* ciphertext = (unsigned char*) malloc(sizeof(char) * payload_len); - unsigned char* plaintext = (unsigned char*) malloc(sizeof(char) * payload_len); - - fread(ciphertext, 1, payload_len, file); - - //little endian obi200 - keytext[0] = 0xFD; - - for (int i = 0; i < 6; ++i) - keytext[i] &= mask[i]; - - //printf("payload length %d using key: ", payload_len); - //for (int i = 0; i < 15; ++i) - // printf("%02x", keytext[i]); - //printf("\n"); - - RC4_KEY key; - RC4_set_key(&key, 15, keytext); - - RC4(&key, payload_len, ciphertext, plaintext); - - unsigned char* current = plaintext; - while (current < plaintext + payload_len && current[0] != 0xff) - { - print_param(current); - int len = 8 + (current[5] << 8 | current[4]); - current += len; - } - - printf("\n"); - - free(ciphertext); - free(plaintext); - } - - free(keytext); - -} diff --git a/obiphone/param_dump.c b/obiphone/param_dump.c new file mode 120000 index 0000000..0004cb0 --- /dev/null +++ b/obiphone/param_dump.c @@ -0,0 +1 @@ +../obi2xx/param_dump.c \ No newline at end of file