778 lines
20 KiB
C
778 lines
20 KiB
C
/*
|
|
*
|
|
* Copyright (C) 2020-2022, paldier<paldier@hotmail.com>.
|
|
* Copyright (C) 2022, ericwang2006.
|
|
*
|
|
*${CORSS_PREFIX}gcc -static mitool.c -o mitool
|
|
*${CORSS_PREFIX}strip mitool
|
|
*
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <sys/stat.h>
|
|
|
|
#define BUFSIZE 65532
|
|
|
|
static int modelid = 0;
|
|
|
|
struct model_s {
|
|
int modelid;
|
|
char *pid;
|
|
char *model;
|
|
};
|
|
|
|
static const struct model_s model_list[] = {
|
|
{ 1, "CR6606", "CR6606" },//xiaomi
|
|
{ 2, "CR6608", "CR6608" },//xiaomi
|
|
{ 3, "CR6609", "CR6609" },//xiaomi
|
|
{ 4, "RA67", "AX5" },//redmi
|
|
{ 5, "RA69", "AX6" },//redmi
|
|
{ 6, "RA70", "AX9000" },//xiaomi
|
|
{ 7, "RA72", "AX6000" },//xiaomi
|
|
{ 8, "RA80", "AX3000" },//xiaomi
|
|
{ 9, "RA81", "AX3000" },//redmi
|
|
{ 10, "RM1800", "AX1800" },//xiaomi
|
|
{ 11, "R1800", "AX1800" },//xiaomi
|
|
{ 12, "R3600", "AX3600" },//xiaomi
|
|
{ 13, "RB06", "AX6000" },//redmi
|
|
{ 14, "RD03", "AX3000T" },//xiaomi
|
|
{ -1, NULL, NULL },
|
|
};
|
|
|
|
typedef struct
|
|
{
|
|
unsigned int count[2];
|
|
unsigned int state[4];
|
|
unsigned char buffer[64];
|
|
}MD5_CTX;
|
|
|
|
|
|
#define F(x,y,z) ((x & y) | (~x & z))
|
|
#define G(x,y,z) ((x & z) | (y & ~z))
|
|
#define H(x,y,z) (x^y^z)
|
|
#define I(x,y,z) (y ^ (x | ~z))
|
|
#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))
|
|
#define FF(a,b,c,d,x,s,ac) \
|
|
{ \
|
|
a += F(b,c,d) + x + ac; \
|
|
a = ROTATE_LEFT(a,s); \
|
|
a += b; \
|
|
}
|
|
#define GG(a,b,c,d,x,s,ac) \
|
|
{ \
|
|
a += G(b,c,d) + x + ac; \
|
|
a = ROTATE_LEFT(a,s); \
|
|
a += b; \
|
|
}
|
|
#define HH(a,b,c,d,x,s,ac) \
|
|
{ \
|
|
a += H(b,c,d) + x + ac; \
|
|
a = ROTATE_LEFT(a,s); \
|
|
a += b; \
|
|
}
|
|
#define II(a,b,c,d,x,s,ac) \
|
|
{ \
|
|
a += I(b,c,d) + x + ac; \
|
|
a = ROTATE_LEFT(a,s); \
|
|
a += b; \
|
|
}
|
|
unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
|
|
|
void MD5Init(MD5_CTX *context)
|
|
{
|
|
context->count[0] = 0;
|
|
context->count[1] = 0;
|
|
context->state[0] = 0x67452301;
|
|
context->state[1] = 0xEFCDAB89;
|
|
context->state[2] = 0x98BADCFE;
|
|
context->state[3] = 0x10325476;
|
|
}
|
|
|
|
void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len)
|
|
{
|
|
unsigned int i = 0,j = 0;
|
|
while(j < len)
|
|
{
|
|
output[j] = input[i] & 0xFF;
|
|
output[j+1] = (input[i] >> 8) & 0xFF;
|
|
output[j+2] = (input[i] >> 16) & 0xFF;
|
|
output[j+3] = (input[i] >> 24) & 0xFF;
|
|
i++;
|
|
j+=4;
|
|
}
|
|
}
|
|
void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len)
|
|
{
|
|
unsigned int i = 0,j = 0;
|
|
while(j < len)
|
|
{
|
|
output[i] = (input[j]) |
|
|
(input[j+1] << 8) |
|
|
(input[j+2] << 16) |
|
|
(input[j+3] << 24);
|
|
i++;
|
|
j+=4;
|
|
}
|
|
}
|
|
void MD5Transform(unsigned int state[4],unsigned char block[64])
|
|
{
|
|
unsigned int a = state[0];
|
|
unsigned int b = state[1];
|
|
unsigned int c = state[2];
|
|
unsigned int d = state[3];
|
|
unsigned int x[64];
|
|
MD5Decode(x,block,64);
|
|
FF(a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */
|
|
FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */
|
|
FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */
|
|
FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */
|
|
FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */
|
|
FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */
|
|
FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */
|
|
FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */
|
|
FF(a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */
|
|
FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */
|
|
FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */
|
|
FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */
|
|
FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */
|
|
FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */
|
|
FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */
|
|
FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */
|
|
|
|
/* Round 2 */
|
|
GG(a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */
|
|
GG(d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */
|
|
GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */
|
|
GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */
|
|
GG(a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */
|
|
GG(d, a, b, c, x[10], 9, 0x2441453); /* 22 */
|
|
GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */
|
|
GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */
|
|
GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */
|
|
GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */
|
|
GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */
|
|
GG(b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */
|
|
GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */
|
|
GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */
|
|
GG(c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */
|
|
GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */
|
|
|
|
/* Round 3 */
|
|
HH(a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */
|
|
HH(d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */
|
|
HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */
|
|
HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */
|
|
HH(a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */
|
|
HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */
|
|
HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */
|
|
HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */
|
|
HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */
|
|
HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */
|
|
HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */
|
|
HH(b, c, d, a, x[ 6], 23, 0x4881d05); /* 44 */
|
|
HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */
|
|
HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */
|
|
HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */
|
|
HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */
|
|
|
|
/* Round 4 */
|
|
II(a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */
|
|
II(d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */
|
|
II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */
|
|
II(b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */
|
|
II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */
|
|
II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */
|
|
II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */
|
|
II(b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */
|
|
II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */
|
|
II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */
|
|
II(c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */
|
|
II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */
|
|
II(a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */
|
|
II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */
|
|
II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */
|
|
II(b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */
|
|
state[0] += a;
|
|
state[1] += b;
|
|
state[2] += c;
|
|
state[3] += d;
|
|
}
|
|
|
|
void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen)
|
|
{
|
|
unsigned int i = 0,index = 0,partlen = 0;
|
|
index = (context->count[0] >> 3) & 0x3F;
|
|
partlen = 64 - index;
|
|
context->count[0] += inputlen << 3;
|
|
if(context->count[0] < (inputlen << 3))
|
|
context->count[1]++;
|
|
context->count[1] += inputlen >> 29;
|
|
|
|
if(inputlen >= partlen)
|
|
{
|
|
memcpy(&context->buffer[index],input,partlen);
|
|
MD5Transform(context->state,context->buffer);
|
|
for(i = partlen;i+64 <= inputlen;i+=64)
|
|
MD5Transform(context->state,&input[i]);
|
|
index = 0;
|
|
}
|
|
else
|
|
{
|
|
i = 0;
|
|
}
|
|
memcpy(&context->buffer[index],&input[i],inputlen-i);
|
|
}
|
|
|
|
void MD5Final(MD5_CTX *context,unsigned char digest[16])
|
|
{
|
|
unsigned int index = 0,padlen = 0;
|
|
unsigned char bits[8];
|
|
index = (context->count[0] >> 3) & 0x3F;
|
|
padlen = (index < 56)?(56-index):(120-index);
|
|
MD5Encode(bits,context->count,8);
|
|
MD5Update(context,PADDING,padlen);
|
|
MD5Update(context,bits,8);
|
|
MD5Encode(digest,context->state,16);
|
|
}
|
|
|
|
static const unsigned int crc32tab[] = {
|
|
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL,
|
|
0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
|
|
0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
|
|
0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
|
|
0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
|
|
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
|
|
0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL,
|
|
0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
|
|
0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,
|
|
0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
|
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L,
|
|
0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
|
|
0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L,
|
|
0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
|
|
0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
|
|
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
|
|
0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL,
|
|
0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
|
|
0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L,
|
|
0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
|
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
|
|
0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
|
|
0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL,
|
|
0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
|
|
0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
|
|
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
|
|
0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
|
|
0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
|
|
0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L,
|
|
0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
|
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L,
|
|
0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
|
|
0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,
|
|
0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,
|
|
0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
|
|
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
|
|
0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL,
|
|
0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,
|
|
0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,
|
|
0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
|
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L,
|
|
0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
|
|
0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L,
|
|
0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,
|
|
0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
|
|
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
|
|
0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L,
|
|
0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
|
|
0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL,
|
|
0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
|
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,
|
|
0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
|
|
0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL,
|
|
0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
|
|
0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
|
|
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
|
|
0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,
|
|
0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,
|
|
0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L,
|
|
0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
|
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L,
|
|
0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
|
|
0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L,
|
|
0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
|
|
};
|
|
|
|
|
|
static unsigned int crc32( const unsigned char *buf, unsigned int size)
|
|
{
|
|
unsigned int i, crc;
|
|
crc = 0xFFFFFFFF;
|
|
|
|
|
|
for (i = 0; i < size; i++)
|
|
crc = crc32tab[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
|
|
|
|
return crc^0xFFFFFFFF;
|
|
}
|
|
|
|
|
|
unsigned char temp_str[30];
|
|
unsigned char password[30];
|
|
void ReadStrUnit(unsigned char * str, unsigned char *temp_str,int idx,int len)
|
|
{
|
|
int index = 0;
|
|
for(index; index < len; index++)
|
|
{
|
|
temp_str[index] = str[idx+index];
|
|
}
|
|
temp_str[index] = '\0';
|
|
}
|
|
|
|
int GetSubStrPos(unsigned char *str1, unsigned char *str2)
|
|
{
|
|
int idx = 0;
|
|
int len1 = BUFSIZE;
|
|
int len2 = strlen(str2);
|
|
|
|
if( len1 < len2)
|
|
return -1;
|
|
|
|
while(1)
|
|
{
|
|
ReadStrUnit(str1,temp_str,idx,len2);
|
|
if(strcmp(str2,temp_str)==0)break;
|
|
idx++;
|
|
if(idx>=len1)return -1;
|
|
}
|
|
|
|
return idx;
|
|
}
|
|
|
|
int atoe(unsigned char *a, unsigned char *e)
|
|
{
|
|
int i;
|
|
unsigned char temp[3] = {0};
|
|
memset(e, 0, 4);
|
|
for (i = 0; i < 4; i++) {
|
|
memset(temp, 0, sizeof(temp));
|
|
memcpy(temp, a + (i*2), 2);
|
|
e[i] = strtoul(temp, NULL, 16);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int find_mtd(char *mtd)
|
|
{
|
|
int part;
|
|
unsigned int size, erasesize;
|
|
char name[65];
|
|
char line[128];
|
|
FILE *fp = fopen("/proc/mtd", "r");
|
|
if (fp == NULL)
|
|
return -1;
|
|
while (fgets(line, sizeof(line), fp)){
|
|
if (sscanf(line, "mtd%d: %x %x \"%64[^\"]\"", &part, &size, &erasesize, name) == 4 && strcmp(name, mtd) == 0){
|
|
fclose(fp);
|
|
return part;
|
|
}
|
|
}
|
|
fclose(fp);
|
|
return -1;
|
|
}
|
|
|
|
unsigned char buf[BUFSIZE];
|
|
unsigned char buff[99];
|
|
static int load_buf(void)
|
|
{
|
|
FILE *fd;
|
|
int bdata;
|
|
char path[11];
|
|
bdata = find_mtd("Bdata");
|
|
if(bdata == -1)
|
|
bdata = find_mtd("bdata");
|
|
|
|
memset(path, 0, sizeof(path));
|
|
snprintf(path, sizeof(path), "/dev/mtd%d", bdata);
|
|
fd = fopen(path, "rb");
|
|
if (fd < 0)
|
|
return -1;
|
|
memset(buf, 0, sizeof(buf));
|
|
fseek(fd, 4, SEEK_SET);
|
|
fread(buf, BUFSIZE, 1,fd);
|
|
fclose(fd);
|
|
return 0;
|
|
}
|
|
|
|
static int lock_mtd(int t)
|
|
{
|
|
FILE *fd;
|
|
unsigned char temp[4];
|
|
char path[11];
|
|
char path2[16];
|
|
int bdata;
|
|
int crash = find_mtd("crash");
|
|
|
|
bdata = find_mtd("Bdata");
|
|
if(bdata == -1)
|
|
bdata = find_mtd("bdata");
|
|
|
|
memset(path, 0, sizeof(path));
|
|
memset(path2, 0, sizeof(path2));
|
|
snprintf(path, sizeof(path), "/dev/mtd%d", crash);
|
|
snprintf(path2, sizeof(path2), "/dev/mtdblock%d", crash);
|
|
fd = fopen(path, "rb");
|
|
if (fd < 0)
|
|
return -1;
|
|
memset(temp, 0, sizeof(temp));
|
|
fseek(fd, 0, SEEK_SET);
|
|
fread(temp, 4, 1,fd);
|
|
fclose(fd);
|
|
if(t == 0){
|
|
if(temp[0] != 0xA5){
|
|
temp[0] = 0xA5;
|
|
temp[1] = 0x5A;
|
|
temp[2] = 0x0;
|
|
temp[3] = 0x0;
|
|
fd = fopen(path2, "wb");
|
|
if (fd < 0)
|
|
return -1;
|
|
fseek(fd, 0, SEEK_SET);
|
|
fwrite(temp, 1, 4, fd);
|
|
fclose(fd);
|
|
system("/sbin/reboot");
|
|
}
|
|
printf("mtd unlocked\n");
|
|
}else{
|
|
if(temp[0] != 0xFF){
|
|
temp[0] = 0xFF;
|
|
temp[1] = 0xFF;
|
|
temp[2] = 0xFF;
|
|
temp[3] = 0xFF;
|
|
fd = fopen(path2, "wb");
|
|
if (fd < 0)
|
|
return -1;
|
|
fseek(fd, 0, SEEK_SET);
|
|
fwrite(temp, 1, 4, fd);
|
|
fclose(fd);
|
|
system("/sbin/reboot");
|
|
}
|
|
printf("mtd locked\n");
|
|
}
|
|
|
|
}
|
|
|
|
static int check_unlock()
|
|
{
|
|
FILE *fd;
|
|
unsigned char temp[4];
|
|
int crash = find_mtd("crash");
|
|
char path[11];
|
|
memset(path, 0, sizeof(path));
|
|
snprintf(path, sizeof(path), "/dev/mtd%d", crash);
|
|
fd = fopen(path, "rb");
|
|
if (fd < 0)
|
|
return -1;
|
|
memset(temp, 0, sizeof(temp));
|
|
fseek(fd, 0, SEEK_SET);
|
|
fread(temp, 4, 1, fd);
|
|
fclose(fd);
|
|
if(temp[0] != 0xA5)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
char *get_model(char *pid)
|
|
{
|
|
char *model = "unknown";
|
|
const struct model_s *p;
|
|
|
|
for (p = &model_list[0]; p->pid; ++p) {
|
|
if (!strcmp(pid, p->pid)) {
|
|
model = p->model;
|
|
break;
|
|
}
|
|
}
|
|
return model;
|
|
}
|
|
|
|
int get_modelid(char *pid)
|
|
{
|
|
int id;
|
|
const struct model_s *p;
|
|
|
|
for (p = &model_list[0]; p->pid; ++p) {
|
|
if (!strcmp(pid, p->pid)) {
|
|
id = p->modelid;
|
|
break;
|
|
}
|
|
}
|
|
return id;
|
|
}
|
|
|
|
static int model_show(void)
|
|
{
|
|
int i;
|
|
|
|
if(load_buf()<0)
|
|
return -1;
|
|
i = GetSubStrPos(buf, "model");
|
|
printf("model=%s\n", get_model(&buf[i+6]));
|
|
}
|
|
|
|
static char *show_lockmtd()
|
|
{
|
|
int i;
|
|
if(modelid == 0){
|
|
if(load_buf()<0)
|
|
return "unknown";
|
|
i = GetSubStrPos(buf, "model");
|
|
modelid = get_modelid(&buf[i+6]);
|
|
}
|
|
if(modelid == 1 || modelid == 2 || modelid == 3)
|
|
return "mtd2";
|
|
else if(modelid == 13)
|
|
return "mtd6";
|
|
else
|
|
return "mtd6";
|
|
}
|
|
|
|
static void usage(void)
|
|
{
|
|
const char* lockmtd = show_lockmtd();
|
|
fprintf(stderr, "Copyright (c) 2020-2022, paldier<paldier@hotmail.com>.\n");
|
|
fprintf(stderr, "Usage: mitool\n");
|
|
fprintf(stderr, "mitool lock\n");
|
|
fprintf(stderr, "\tlock %s and auto reboot\n", lockmtd);
|
|
fprintf(stderr, "mitool unlock\n");
|
|
fprintf(stderr, "\tunlock %s and auto reboot\n", lockmtd);
|
|
fprintf(stderr, "mitool password\n");
|
|
fprintf(stderr, "\tprintf default password\n");
|
|
fprintf(stderr, "mitool hack\n");
|
|
fprintf(stderr, "\tset ssh telnet uart to default enable\n");
|
|
fprintf(stderr, "mitool model\n");
|
|
fprintf(stderr, "\tshow model\n");
|
|
fprintf(stderr, "mitool sn\n");
|
|
fprintf(stderr, "\tshow sn\n");
|
|
fprintf(stderr, "mitool setsn xxxxxxxx\n");
|
|
fprintf(stderr, "\tset sn\n");
|
|
}
|
|
|
|
static int password_show(void)
|
|
{
|
|
int i,j;
|
|
unsigned char decrypt[16];
|
|
unsigned char sn[99];
|
|
unsigned char salt[]="6d2df50a-250f-4a30-a5e6-d44fb0960aa0";
|
|
if(load_buf()<0)
|
|
return -1;
|
|
i = GetSubStrPos(buf, "SN=");
|
|
for(j=0;j<15;j++){
|
|
sprintf(&sn[j], "%c", buf[i+3+j]);//sn
|
|
}
|
|
memset(buff, 0, sizeof(buff));
|
|
sprintf(buff, "%s%s", sn, salt);
|
|
MD5_CTX md5;
|
|
MD5Init(&md5);
|
|
MD5Update(&md5, buff, strlen(buff));
|
|
MD5Final(&md5, decrypt);
|
|
memset(password, 0, sizeof(password));
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
sprintf(&password[i*2], "%02x", decrypt[i]);
|
|
}
|
|
}
|
|
|
|
static int calc_img_crc()
|
|
{
|
|
unsigned int crc = 0xffffffff;
|
|
FILE *fd;
|
|
int bdata;
|
|
char path[16];
|
|
|
|
bdata = find_mtd("Bdata");
|
|
if(bdata == -1)
|
|
bdata = find_mtd("bdata");
|
|
|
|
memset(path, 0, sizeof(path));
|
|
snprintf(path, sizeof(path), "/dev/mtdblock%d", bdata);
|
|
fd = fopen(path, "wb");
|
|
if (fd < 0)
|
|
return -1;
|
|
fseek(fd, 4, SEEK_SET);
|
|
fwrite(buf, 1, BUFSIZE, fd);
|
|
crc = crc32(buf, BUFSIZE);
|
|
memset(buf, 0, sizeof(buf));
|
|
memset(buff, 0, sizeof(buff));
|
|
snprintf(buff, sizeof(buff), "%08X", crc);
|
|
atoe(buff, buf);
|
|
memset(buff, 0, sizeof(buff));
|
|
buff[0] = buf[3];
|
|
buff[1] = buf[2];
|
|
buff[2] = buf[1];
|
|
buff[3] = buf[0];
|
|
fseek(fd, 0, SEEK_SET);
|
|
fwrite(buff, 1, 4, fd);
|
|
fclose(fd);
|
|
return 0;
|
|
}
|
|
|
|
static int add_bdata(char *s)
|
|
{
|
|
int i;
|
|
if(s == NULL)
|
|
return -1;
|
|
for(i = 0; i < BUFSIZE; i++ ){
|
|
if(buf[i] == 0x0 && buf[i+1] == 0x0){
|
|
sprintf(&buf[i+1], "%s", s);
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int verify_sn(char *s)
|
|
{
|
|
char sn[16];
|
|
int i;
|
|
memset(sn, 0, sizeof(sn));
|
|
snprintf(sn, sizeof(sn), "%s", s);
|
|
if(sn[5] != '/')
|
|
return -1;
|
|
for(i = 0; i < 5; i++){
|
|
if(sn[i] < '0' || sn[i] > '9')
|
|
return -1;
|
|
}
|
|
for(i = 6; i < 15; i++){
|
|
if((sn[i] < '0' || sn[i] > '9') && (sn[i] < 'A' || sn[i] > 'Z'))
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int set_ssh()
|
|
{
|
|
int i, ret = 0;
|
|
|
|
if(load_buf() < 0)
|
|
return -1;
|
|
if(check_unlock()){
|
|
printf("mtd is not unlocked\n");
|
|
return -1;
|
|
}
|
|
i = GetSubStrPos(buf, "model");
|
|
printf("model=%s\n", get_model(&buf[i+6]));
|
|
i = GetSubStrPos(buf, "ssh_en");
|
|
if(i < 0){
|
|
printf("not found ssh_en, add it.\n");
|
|
add_bdata("ssh_en=1");
|
|
}else{
|
|
printf("get ssh_en=%c", buf[i+7]);
|
|
buf[i+7] = '1';//ssh
|
|
}
|
|
i = GetSubStrPos(buf, "telnet_en");
|
|
if(i < 0){
|
|
printf("not found telnet_en, add it.\n");
|
|
add_bdata("telnet_en=1");
|
|
}else{
|
|
printf(" telnet_en=%c", buf[i+10]);
|
|
buf[i+10] = '1';//telnet
|
|
}
|
|
i = GetSubStrPos(buf, "uart_en");
|
|
if(i < 0){
|
|
printf("not found uart_en, add it.\n");
|
|
add_bdata("uart_en=1");
|
|
}else{
|
|
printf(" uart_en=%c\n", buf[i+8]);
|
|
buf[i+8] = '1';//uart
|
|
}
|
|
ret = calc_img_crc();
|
|
system("sed -i 's/channel=.*/channel=\"debug\"/g' /etc/init.d/dropbear");
|
|
system("/etc/init.d/dropbear start &");
|
|
return ret;
|
|
}
|
|
|
|
static int show_sn()
|
|
{
|
|
int i;
|
|
if(load_buf() < 0)
|
|
return -1;
|
|
i = GetSubStrPos(buf, "model");
|
|
printf("model=%s\n", get_model(&buf[i+6]));
|
|
i = GetSubStrPos(buf, "SN");
|
|
printf("get %s\n", &buf[i]);
|
|
return 0;
|
|
}
|
|
|
|
static int set_sn(char *sn)
|
|
{
|
|
int i, ret = 0;
|
|
|
|
if(load_buf() < 0)
|
|
return -1;
|
|
if(check_unlock()){
|
|
printf("mtd is not unlocked\n");
|
|
return -1;
|
|
}
|
|
if(strlen(sn) != 15 || verify_sn(sn) < 0){
|
|
printf("SN is wrong,%s\n",sn);
|
|
return -1;
|
|
}
|
|
i = GetSubStrPos(buf, "model");
|
|
printf("model=%s\n", get_model(&buf[i+6]));
|
|
i = GetSubStrPos(buf, "SN");
|
|
if(i < 0){
|
|
char tmp[19];
|
|
printf("not found SN, add it.\n");
|
|
memset(tmp, 0, sizeof(tmp));
|
|
snprintf(tmp, sizeof(tmp), "SN=%s", sn);
|
|
add_bdata(tmp);
|
|
}else{
|
|
printf("get %s\n", &buf[i]);
|
|
sprintf(&buf[i], "SN=%s", sn);
|
|
}
|
|
ret = calc_img_crc();
|
|
return ret;
|
|
}
|
|
int main(int argc, char **argv)
|
|
{
|
|
int ret;
|
|
if (argc < 2)
|
|
usage();
|
|
else if (!strcmp(argv[1], "hack")) {
|
|
ret = set_ssh();
|
|
if (ret < 0) {
|
|
exit(1);
|
|
}
|
|
password_show();
|
|
printf("set ssh_en=1 telnet_en=1 uart_en=1\nNOTE!!! ssh/telnet default usesrname:root\ndefault password:%s\n",password);
|
|
printf("automatic lock mtd and reboot\n");
|
|
lock_mtd(1);
|
|
} else if (!strcmp(argv[1], "lock"))
|
|
lock_mtd(1);
|
|
else if (!strcmp(argv[1], "unlock"))
|
|
lock_mtd(0);
|
|
else if (!strcmp(argv[1], "password")){
|
|
password_show();
|
|
printf("ssh/telnet default usesrname:root password:%s\n",password);
|
|
} else if (!strcmp(argv[1], "model")){
|
|
model_show();
|
|
} else if (!strcmp(argv[1], "sn")){
|
|
show_sn();
|
|
} else if (!strcmp(argv[1], "setsn") && argv[2]){
|
|
set_sn(argv[2]);
|
|
printf("automatic lock mtd and reboot\n");
|
|
lock_mtd(1);
|
|
} else
|
|
usage();
|
|
|
|
return 0;
|
|
}
|
|
|