0%

破解某东路由宝之官方固件结构

通过官方固件中的某二进制文件我们可以得知固件的结构如下:

  • 0x00-0x03: 固定字符HIMG
  • 0x0c-0x0f: 真实的固件大小
  • 0x10-0x1F: 固件的MD5值
  • 0x20-0x11F: 固件RSA签名
  • 0x220-0x22F: AES-128-CBC KEY
  • 0x230-0x23F: AES-128-CBC IV
  • 0x240-文件末尾: 加密主体

通过以上结构,我们可以很容易写出解密固件的代码逻辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
int decrypt(char *encrypt_content, int encrypt_size, char *key, char *iv, char *dec_content)
{
int result = -1;
EVP_CIPHER_CTX *ctx;
int dec_out[2];

ctx = EVP_CIPHER_CTX_new();
if (ctx == 0)
{
ERR_print_errors_fp(stderr);
}
else
{
if (EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), 0, key, iv))
{
if (EVP_DecryptUpdate(ctx, dec_content, dec_out, encrypt_content, encrypt_size))
{
result = dec_out[0];
if (EVP_DecryptFinal_ex(ctx, dec_content + dec_out[0], dec_out))
{
result += dec_out[0];
}
else
{
ERR_print_errors_fp(stderr);
}
}
else
{
ERR_print_errors_fp(stderr);
}
}
else
{
ERR_print_errors_fp(stderr);
}
}
if (ctx != 0)
{
EVP_CIPHER_CTX_free(ctx);
}
return result;
}
int save_to_file(char *filename, char *decode_buffer, int size)
{
FILE *fp = fopen(filename, "w+");
if (NULL == fp)
{
return -1;
}
fwrite(decode_buffer, size, 1, fp);
fclose(fp);
fp = NULL;
return 0;
}
int decode_img(char *buffer, char *dec_file_name)
{
//获取文件大小
int size = ntohl(*(uint32_t *)(buffer + 0xc));
char *decoded_buffer = malloc(size + -0x230);
int decoded_size = decrypt(buffer + 0x240, size + -0x230, buffer + 0x220, buffer + 0x230, decoded_buffer);
if (decoded_size > 0)
{
return save_to_file(dec_file_name, decoded_buffer, decoded_size);
}
return -1;
}