#include <stdio.h> #include <string.h> #include <stdlib.h> #ifndef DWORD #define DWORD unsigned int #endif #ifndef BYTE #define BYTE unsigned char #endif #ifndef bool #define bool unsigned int #endif #define FLASH_HW_KEY 0x08825252 #define FLASH_HW_KEY_0 ((FLASH_HW_KEY <<(32-11)) |(FLASH_HW_KEY>>11)) #define FLASH_HW_KEY_1 ((FLASH_HW_KEY <<(32-20)) |(FLASH_HW_KEY>>20)) #define FLASH_HW_KEY_2 ((FLASH_HW_KEY <<(32-26)) |(FLASH_HW_KEY>>26)) #define FLASH_HW_KEY_3 ((FLASH_HW_KEY <<(32-7)) |(FLASH_HW_KEY>>7)) DWORD cmN_BytesToDWORD(char* bytes) { int i; DWORD value; value = 0; char* tmpByte; //printf("cmN_BytesToDWORD %p ", bytes); for(i=0;i<4;i++) { tmpByte = &bytes[i]; if(tmpByte) { value |= (*tmpByte & 0xFF) <<(8*i); //printf("%x ", value); } } return value; } void cmN_DWORDToBytes(char* bytes, DWORD value) { int i; char* tmpbyte; for(i=0;i<4;i++) { tmpbyte = &bytes[i]; *tmpbyte = (BYTE)(value >> (8*i)) & 0xFF; } } bool cmN_GetBitFromDword(DWORD data, BYTE i) { if( (data>>i)&1 ) return 1; else return 0; } DWORD Mix_0(DWORD data) { return ( (cmN_GetBitFromDword(data, 22)<<31) | (cmN_GetBitFromDword(data, 8)<<30) | (cmN_GetBitFromDword(data, 7)<<29) | (cmN_GetBitFromDword(data, 21)<<28) | (cmN_GetBitFromDword(data, 0)<<27) | (cmN_GetBitFromDword(data, 25)<<26) | (cmN_GetBitFromDword(data, 20)<<25) | (cmN_GetBitFromDword(data, 6)<<24) | (cmN_GetBitFromDword(data, 19)<<23) | (cmN_GetBitFromDword(data, 16)<<22) | (cmN_GetBitFromDword(data, 24)<<21) | (cmN_GetBitFromDword(data, 5)<<20) | (cmN_GetBitFromDword(data, 23)<<19) | (cmN_GetBitFromDword(data, 1)<<18) | (cmN_GetBitFromDword(data, 18)<<17) | (cmN_GetBitFromDword(data, 15)<<16) | (cmN_GetBitFromDword(data, 26)<<15) | (cmN_GetBitFromDword(data, 3)<<14) | (cmN_GetBitFromDword(data, 17)<<13) | (cmN_GetBitFromDword(data, 14)<<12) | (cmN_GetBitFromDword(data, 4)<<11) | (cmN_GetBitFromDword(data, 13)<<10) | (cmN_GetBitFromDword(data, 2)<<9) | (cmN_GetBitFromDword(data, 30)<<8) | (cmN_GetBitFromDword(data, 12)<<7) | (cmN_GetBitFromDword(data, 29)<<6) | (cmN_GetBitFromDword(data, 28)<<5) | (cmN_GetBitFromDword(data, 11)<<4) | (cmN_GetBitFromDword(data, 9)<<3) | (cmN_GetBitFromDword(data, 31)<<2) | (cmN_GetBitFromDword(data, 27)<<1) | (cmN_GetBitFromDword(data, 10)<<0) ); } DWORD Mix_1(DWORD data) { return ( (cmN_GetBitFromDword(data, 11)<<31) | (cmN_GetBitFromDword(data, 7)<<30) | (cmN_GetBitFromDword(data, 21)<<29) | (cmN_GetBitFromDword(data, 29)<<28) | (cmN_GetBitFromDword(data, 18)<<27) | (cmN_GetBitFromDword(data, 31)<<26) | (cmN_GetBitFromDword(data, 3)<<25) | (cmN_GetBitFromDword(data, 30)<<24) | (cmN_GetBitFromDword(data, 8)<<23) | (cmN_GetBitFromDword(data, 26)<<22) | (cmN_GetBitFromDword(data, 12)<<21) | (cmN_GetBitFromDword(data, 28)<<20) | (cmN_GetBitFromDword(data, 2)<<19) | (cmN_GetBitFromDword(data, 25)<<18) | (cmN_GetBitFromDword(data, 17)<<17) | (cmN_GetBitFromDword(data, 14)<<16) | (cmN_GetBitFromDword(data, 23)<<15) | (cmN_GetBitFromDword(data, 1)<<14) | (cmN_GetBitFromDword(data, 20)<<13) | (cmN_GetBitFromDword(data, 5)<<12) | (cmN_GetBitFromDword(data, 19)<<11) | (cmN_GetBitFromDword(data, 15)<<10) | (cmN_GetBitFromDword(data, 9)<<9) | (cmN_GetBitFromDword(data, 4)<<8) | (cmN_GetBitFromDword(data, 0)<<7) | (cmN_GetBitFromDword(data, 16)<<6) | (cmN_GetBitFromDword(data, 24)<<5) | (cmN_GetBitFromDword(data, 6)<<4) | (cmN_GetBitFromDword(data, 10)<<3) | (cmN_GetBitFromDword(data, 22)<<2) | (cmN_GetBitFromDword(data, 27)<<1) | (cmN_GetBitFromDword(data, 13)<<0) ); } DWORD Mix_2(DWORD data) { return ( (cmN_GetBitFromDword(data, 13)<<31) | (cmN_GetBitFromDword(data, 23)<<30) | (cmN_GetBitFromDword(data, 9)<<29) | (cmN_GetBitFromDword(data, 20)<<28) | (cmN_GetBitFromDword(data, 3)<<27) | (cmN_GetBitFromDword(data, 25)<<26) | (cmN_GetBitFromDword(data, 14)<<25) | (cmN_GetBitFromDword(data, 24)<<24) | (cmN_GetBitFromDword(data, 2)<<23) | (cmN_GetBitFromDword(data, 11)<<22) | (cmN_GetBitFromDword(data, 30)<<21) | (cmN_GetBitFromDword(data, 16)<<20) | (cmN_GetBitFromDword(data, 6)<<19) | (cmN_GetBitFromDword(data, 19)<<18) | (cmN_GetBitFromDword(data, 1)<<17) | (cmN_GetBitFromDword(data, 5)<<16) | (cmN_GetBitFromDword(data, 0)<<15) | (cmN_GetBitFromDword(data, 22)<<14) | (cmN_GetBitFromDword(data, 12)<<13) | (cmN_GetBitFromDword(data, 26)<<12) | (cmN_GetBitFromDword(data, 8)<<11) | (cmN_GetBitFromDword(data, 21)<<10) | (cmN_GetBitFromDword(data, 10)<<9) | (cmN_GetBitFromDword(data, 17)<<8) | (cmN_GetBitFromDword(data, 28)<<7) | (cmN_GetBitFromDword(data, 4)<<6) | (cmN_GetBitFromDword(data, 29)<<5) | (cmN_GetBitFromDword(data, 15)<<4) | (cmN_GetBitFromDword(data, 31)<<3) | (cmN_GetBitFromDword(data, 18)<<2) | (cmN_GetBitFromDword(data, 7)<<1) | (cmN_GetBitFromDword(data, 27)<<0) ); } DWORD Mix_3(DWORD data) { return ( (cmN_GetBitFromDword(data, 20)<<31) | (cmN_GetBitFromDword(data, 11)<<30) | (cmN_GetBitFromDword(data, 31)<<29) | (cmN_GetBitFromDword(data, 25)<<28) | (cmN_GetBitFromDword(data, 10)<<27) | (cmN_GetBitFromDword(data, 17)<<26) | (cmN_GetBitFromDword(data, 29)<<25) | (cmN_GetBitFromDword(data, 7)<<24) | (cmN_GetBitFromDword(data, 13)<<23) | (cmN_GetBitFromDword(data, 27)<<22) | (cmN_GetBitFromDword(data, 2)<<21) | (cmN_GetBitFromDword(data, 22)<<20) | (cmN_GetBitFromDword(data, 26)<<19) | (cmN_GetBitFromDword(data, 16)<<18) | (cmN_GetBitFromDword(data, 6)<<17) | (cmN_GetBitFromDword(data, 30)<<16) | (cmN_GetBitFromDword(data, 14)<<15) | (cmN_GetBitFromDword(data, 24)<<14) | (cmN_GetBitFromDword(data, 4)<<13) | (cmN_GetBitFromDword(data, 19)<<12) | (cmN_GetBitFromDword(data, 0)<<11) | (cmN_GetBitFromDword(data, 8)<<10) | (cmN_GetBitFromDword(data, 18)<<9) | (cmN_GetBitFromDword(data, 1)<<8) | (cmN_GetBitFromDword(data, 21)<<7) | (cmN_GetBitFromDword(data, 15)<<6) | (cmN_GetBitFromDword(data, 3)<<5) | (cmN_GetBitFromDword(data, 5)<<4) | (cmN_GetBitFromDword(data, 23)<<3) | (cmN_GetBitFromDword(data, 9)<<2) | (cmN_GetBitFromDword(data, 28)<<1) | (cmN_GetBitFromDword(data, 12)<<0) ); } DWORD unMix_0(DWORD data) { return ( (cmN_GetBitFromDword(data, 2)<<31) | (cmN_GetBitFromDword(data, 8)<<30) | (cmN_GetBitFromDword(data, 6)<<29) | (cmN_GetBitFromDword(data, 5)<<28) | (cmN_GetBitFromDword(data, 1)<<27) | (cmN_GetBitFromDword(data, 15)<<26) | (cmN_GetBitFromDword(data, 26)<<25) | (cmN_GetBitFromDword(data, 21)<<24) | (cmN_GetBitFromDword(data, 19)<<23) | (cmN_GetBitFromDword(data, 31)<<22) | (cmN_GetBitFromDword(data, 28)<<21) | (cmN_GetBitFromDword(data, 25)<<20) | (cmN_GetBitFromDword(data, 23)<<19) | (cmN_GetBitFromDword(data, 17)<<18) | (cmN_GetBitFromDword(data, 13)<<17) | (cmN_GetBitFromDword(data, 22)<<16) | (cmN_GetBitFromDword(data, 16)<<15) | (cmN_GetBitFromDword(data, 12)<<14) | (cmN_GetBitFromDword(data, 10)<<13) | (cmN_GetBitFromDword(data, 7)<<12) | (cmN_GetBitFromDword(data, 4)<<11) | (cmN_GetBitFromDword(data, 0)<<10) | (cmN_GetBitFromDword(data, 3)<<9) | (cmN_GetBitFromDword(data, 30)<<8) | (cmN_GetBitFromDword(data, 29)<<7) | (cmN_GetBitFromDword(data, 24)<<6) | (cmN_GetBitFromDword(data, 20)<<5) | (cmN_GetBitFromDword(data, 11)<<4) | (cmN_GetBitFromDword(data, 14)<<3) | (cmN_GetBitFromDword(data, 9)<<2) | (cmN_GetBitFromDword(data, 18)<<1) | (cmN_GetBitFromDword(data, 27)<<0) ); } DWORD unMix_1(DWORD data) { return ( (cmN_GetBitFromDword(data, 26)<<31) | (cmN_GetBitFromDword(data, 24)<<30) | (cmN_GetBitFromDword(data, 28)<<29) | (cmN_GetBitFromDword(data, 20)<<28) | (cmN_GetBitFromDword(data, 1)<<27) | (cmN_GetBitFromDword(data, 22)<<26) | (cmN_GetBitFromDword(data, 18)<<25) | (cmN_GetBitFromDword(data, 5)<<24) | (cmN_GetBitFromDword(data, 15)<<23) | (cmN_GetBitFromDword(data, 2)<<22) | (cmN_GetBitFromDword(data, 29)<<21) | (cmN_GetBitFromDword(data, 13)<<20) | (cmN_GetBitFromDword(data, 11)<<19) | (cmN_GetBitFromDword(data, 27)<<18) | (cmN_GetBitFromDword(data, 17)<<17) | (cmN_GetBitFromDword(data, 6)<<16) | (cmN_GetBitFromDword(data, 10)<<15) | (cmN_GetBitFromDword(data, 16)<<14) | (cmN_GetBitFromDword(data, 0)<<13) | (cmN_GetBitFromDword(data, 21)<<12) | (cmN_GetBitFromDword(data, 31)<<11) | (cmN_GetBitFromDword(data, 3)<<10) | (cmN_GetBitFromDword(data, 9)<<9) | (cmN_GetBitFromDword(data, 23)<<8) | (cmN_GetBitFromDword(data, 30)<<7) | (cmN_GetBitFromDword(data, 4)<<6) | (cmN_GetBitFromDword(data, 12)<<5) | (cmN_GetBitFromDword(data, 8)<<4) | (cmN_GetBitFromDword(data, 25)<<3) | (cmN_GetBitFromDword(data, 19)<<2) | (cmN_GetBitFromDword(data, 14)<<1) | (cmN_GetBitFromDword(data, 7)<<0) ); } DWORD unMix_2(DWORD data) { return ( (cmN_GetBitFromDword(data, 3)<<31) | (cmN_GetBitFromDword(data, 21)<<30) | (cmN_GetBitFromDword(data, 5)<<29) | (cmN_GetBitFromDword(data, 7)<<28) | (cmN_GetBitFromDword(data, 0)<<27) | (cmN_GetBitFromDword(data, 12)<<26) | (cmN_GetBitFromDword(data, 26)<<25) | (cmN_GetBitFromDword(data, 24)<<24) | (cmN_GetBitFromDword(data, 30)<<23) | (cmN_GetBitFromDword(data, 14)<<22) | (cmN_GetBitFromDword(data, 10)<<21) | (cmN_GetBitFromDword(data, 28)<<20) | (cmN_GetBitFromDword(data, 18)<<19) | (cmN_GetBitFromDword(data, 2)<<18) | (cmN_GetBitFromDword(data, 8)<<17) | (cmN_GetBitFromDword(data, 20)<<16) | (cmN_GetBitFromDword(data, 4)<<15) | (cmN_GetBitFromDword(data, 25)<<14) | (cmN_GetBitFromDword(data, 31)<<13) | (cmN_GetBitFromDword(data, 13)<<12) | (cmN_GetBitFromDword(data, 22)<<11) | (cmN_GetBitFromDword(data, 9)<<10) | (cmN_GetBitFromDword(data, 29)<<9) | (cmN_GetBitFromDword(data, 11)<<8) | (cmN_GetBitFromDword(data, 1)<<7) | (cmN_GetBitFromDword(data, 19)<<6) | (cmN_GetBitFromDword(data, 16)<<5) | (cmN_GetBitFromDword(data, 6)<<4) | (cmN_GetBitFromDword(data, 27)<<3) | (cmN_GetBitFromDword(data, 23)<<2) | (cmN_GetBitFromDword(data, 17)<<1) | (cmN_GetBitFromDword(data, 15)<<0) ); } DWORD unMix_3(DWORD data) { return ( (cmN_GetBitFromDword(data, 29)<<31) | (cmN_GetBitFromDword(data, 16)<<30) | (cmN_GetBitFromDword(data, 25)<<29) | (cmN_GetBitFromDword(data, 1)<<28) | (cmN_GetBitFromDword(data, 22)<<27) | (cmN_GetBitFromDword(data, 19)<<26) | (cmN_GetBitFromDword(data, 28)<<25) | (cmN_GetBitFromDword(data, 14)<<24) | (cmN_GetBitFromDword(data, 3)<<23) | (cmN_GetBitFromDword(data, 20)<<22) | (cmN_GetBitFromDword(data, 7)<<21) | (cmN_GetBitFromDword(data, 31)<<20) | (cmN_GetBitFromDword(data, 12)<<19) | (cmN_GetBitFromDword(data, 9)<<18) | (cmN_GetBitFromDword(data, 26)<<17) | (cmN_GetBitFromDword(data, 18)<<16) | (cmN_GetBitFromDword(data, 6)<<15) | (cmN_GetBitFromDword(data, 15)<<14) | (cmN_GetBitFromDword(data, 23)<<13) | (cmN_GetBitFromDword(data, 0)<<12) | (cmN_GetBitFromDword(data, 30)<<11) | (cmN_GetBitFromDword(data, 27)<<10) | (cmN_GetBitFromDword(data, 2)<<9) | (cmN_GetBitFromDword(data, 10)<<8) | (cmN_GetBitFromDword(data, 24)<<7) | (cmN_GetBitFromDword(data, 17)<<6) | (cmN_GetBitFromDword(data, 4)<<5) | (cmN_GetBitFromDword(data, 13)<<4) | (cmN_GetBitFromDword(data, 5)<<3) | (cmN_GetBitFromDword(data, 21)<<2) | (cmN_GetBitFromDword(data, 8)<<1) | (cmN_GetBitFromDword(data, 11)<<0) ); } void hwEncodeRawDataForFlash(char * pChar, DWORD length, DWORD ref_address) { DWORD tmplength=0; DWORD in_data, data_add, pre_xor_data, out_data; BYTE type; //to handle for each DWORD while( tmplength < length) { //printf("tmplength %d ", tmplength); in_data = cmN_BytesToDWORD(pChar); data_add = in_data + FLASH_HW_KEY; type = (BYTE)(ref_address>>2) & 0x03; if(type==0) { pre_xor_data = Mix_0(data_add); out_data = pre_xor_data^FLASH_HW_KEY_0; cmN_DWORDToBytes(pChar, out_data); } else if(type==1) { pre_xor_data = Mix_1(data_add); out_data = pre_xor_data^FLASH_HW_KEY_1; cmN_DWORDToBytes(pChar, out_data); } else if(type==2) { pre_xor_data = Mix_2(data_add); out_data = pre_xor_data^FLASH_HW_KEY_2; cmN_DWORDToBytes(pChar, out_data); } else if(type==3) { pre_xor_data = Mix_3(data_add); out_data = pre_xor_data^FLASH_HW_KEY_3; cmN_DWORDToBytes(pChar, out_data); } ref_address += 4; pChar += 4; tmplength += 4; } pChar -= tmplength; } void hwDecodeRawDataForFlash(char * pChar, DWORD length, DWORD ref_address) { DWORD tmplength=0; DWORD in_data, pre_xor_data, out_data; BYTE type; while( tmplength < length) { in_data = cmN_BytesToDWORD(pChar); type = (BYTE)(ref_address>>2) & 0x03; if(type==0) { in_data = in_data^FLASH_HW_KEY_0; pre_xor_data = unMix_0(in_data); out_data = pre_xor_data - FLASH_HW_KEY; cmN_DWORDToBytes(pChar, out_data); } else if(type==1) { in_data = in_data^FLASH_HW_KEY_1; pre_xor_data = unMix_1(in_data); out_data = pre_xor_data - FLASH_HW_KEY; cmN_DWORDToBytes(pChar, out_data); } else if(type==2) { in_data = in_data^FLASH_HW_KEY_2; pre_xor_data = unMix_2(in_data); out_data = pre_xor_data - FLASH_HW_KEY; cmN_DWORDToBytes(pChar, out_data); } else if(type==3) { in_data = in_data^FLASH_HW_KEY_3; pre_xor_data = unMix_3(in_data); out_data = pre_xor_data - FLASH_HW_KEY; cmN_DWORDToBytes(pChar, out_data); } ref_address += 4; pChar += 4; tmplength += 4; } pChar -= tmplength; } #define BUF_SIZE 128 main(int argc,char *argv[]) { char buf[BUF_SIZE]; char outFile[64]; FILE *filein = fopen( argv[1], "rb" ); if(filein == NULL) { printf("open %s fail ", argv[1] ); return 1; } memset(outFile,0,64); sprintf(outFile,"decrypt_%s",argv[1]+2); //printf("--->%s ",outFile); FILE *fileout=fopen(outFile, "wb" ); if(fileout == NULL) { printf("open outfile fail " ); return 1; } while(1) { int ret = fread(buf, 1, BUF_SIZE, filein); if(ret <=0) { break; } hwDecodeRawDataForFlash( &buf[0], BUF_SIZE, 0); fwrite(buf, 1, BUF_SIZE, fileout); } fclose(filein); fclose(fileout); return 0; }