first commit
This commit is contained in:
373
project/fm_viewer/data/an6000_decode.cpp
Normal file
373
project/fm_viewer/data/an6000_decode.cpp
Normal file
@@ -0,0 +1,373 @@
|
||||
|
||||
#include "an6000_decode.h"
|
||||
#if (RM_MODEL == RM_MODEL_TYPE_AN6000)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
volatile unsigned long size;
|
||||
volatile char type[4];
|
||||
} BoxHeader_t;
|
||||
|
||||
typedef struct _BoxAddress_t {
|
||||
fpos_t addr;
|
||||
unsigned long size;
|
||||
} BoxAddress_t;
|
||||
|
||||
/**
|
||||
* @brief Convert the Byte-order(32bit) <for little-endian environment>
|
||||
*
|
||||
* @param[in] val target value
|
||||
*
|
||||
* @return convert value
|
||||
*/
|
||||
unsigned long convertEndian_32(unsigned long val)
|
||||
{
|
||||
unsigned long result = 0;
|
||||
unsigned char *p1 = (unsigned char *)&val;
|
||||
unsigned char *p2 = (unsigned char *)&result;
|
||||
p2[0] = p1[3];
|
||||
p2[1] = p1[2];
|
||||
p2[2] = p1[1];
|
||||
p2[3] = p1[0];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief [DEBUG] Box data analysis
|
||||
*
|
||||
* @param[in] fp target file pointer
|
||||
* @param[in] level analysis depth
|
||||
* @param[in] parentSize parent box size
|
||||
*/
|
||||
void BoxAnalysis(FILE *fp, int level, size_t parentSize)
|
||||
{
|
||||
BoxHeader_t boxHead, childBoxHead;
|
||||
char typeDesc[8] = {0};
|
||||
size_t readSize;
|
||||
int i;
|
||||
int isNotAscii;
|
||||
char *pbuf = NULL;
|
||||
fpos_t pos;
|
||||
|
||||
while (1) {
|
||||
// read box header
|
||||
readSize = fread(&boxHead, 1, sizeof(BoxHeader_t), fp);
|
||||
if ((feof(fp) != 0) || (readSize == 0)) {
|
||||
break;
|
||||
}
|
||||
boxHead.size = convertEndian_32(boxHead.size);
|
||||
strncpy(typeDesc, (const char *)&boxHead.type[0], 4);
|
||||
if (boxHead.size == 0) {
|
||||
break;
|
||||
}
|
||||
fgetpos(fp, &pos);
|
||||
printf("[%08X] ", (unsigned long)(pos - sizeof(BoxHeader_t)));
|
||||
for (i = 0; i < level; i++) {
|
||||
printf(" ");
|
||||
}
|
||||
printf("%s[%d]\n", typeDesc, boxHead.size);
|
||||
if (parentSize != (size_t)-1) {
|
||||
parentSize -= boxHead.size;
|
||||
}
|
||||
|
||||
// check child box exist
|
||||
readSize = fread(&childBoxHead, 1, sizeof(BoxHeader_t), fp);
|
||||
childBoxHead.size = convertEndian_32(childBoxHead.size);
|
||||
isNotAscii = 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
if ((childBoxHead.type[i] < 'a') || (childBoxHead.type[i] > 'z')) {
|
||||
++isNotAscii;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fseek(fp, -(long)sizeof(BoxHeader_t), SEEK_CUR);
|
||||
|
||||
if ((boxHead.size > childBoxHead.size) && (isNotAscii == 0)) {
|
||||
// child box exist
|
||||
BoxAnalysis(fp, level + 1, boxHead.size - sizeof(BoxHeader_t));
|
||||
}
|
||||
else {
|
||||
// child box not exist
|
||||
pbuf = (char *)malloc(boxHead.size - sizeof(BoxHeader_t));
|
||||
fread(pbuf, 1, boxHead.size - sizeof(BoxHeader_t), fp);
|
||||
free(pbuf);
|
||||
}
|
||||
|
||||
// check of continue the child box loop
|
||||
if (parentSize == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// terminal box
|
||||
if (strncmp((const char *)boxHead.type, "FWVR", 4) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (parentSize == (size_t)-1) {
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the crypt target box information
|
||||
*
|
||||
* @param[in] fp target file pointer
|
||||
* @param[out] buf target box information
|
||||
* @param[in] bufSize number of \a buf buffer
|
||||
* @param[in] level analysis depth
|
||||
* @param[in] parentSize parent box size
|
||||
*
|
||||
* @return number of available target box information
|
||||
*/
|
||||
static bool gFound_stsz = false;
|
||||
static bool gFount_udat = false;
|
||||
|
||||
size_t GetCryptTarget(FILE *fp, BoxAddress_t *buf, size_t bufSize, int level, size_t parentSize)
|
||||
{
|
||||
size_t buf_num = 0;
|
||||
BoxHeader_t boxHead = {0,};
|
||||
BoxHeader_t childBoxHead = {0,};
|
||||
size_t readSize = 0;
|
||||
int isNotAscii = 0;
|
||||
int i = 0;
|
||||
//char *pbuf = NULL;
|
||||
fpos_t pos = 0;
|
||||
|
||||
if (bufSize == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
// read box header
|
||||
readSize = fread(&boxHead, 1, sizeof(BoxHeader_t), fp);
|
||||
if (readSize == 0) {
|
||||
break;
|
||||
}
|
||||
boxHead.size = convertEndian_32(boxHead.size);
|
||||
if (boxHead.size == 0) {
|
||||
break;
|
||||
}
|
||||
if (parentSize != (size_t)-1) {
|
||||
parentSize -= boxHead.size;
|
||||
}
|
||||
|
||||
// check crypt target box
|
||||
|
||||
if (((strncmp((const char *)boxHead.type, "stsz", 4) == 0) && (gFound_stsz == false) )
|
||||
|| (strncmp((const char *)boxHead.type, "udat", 4) == 0) && (gFount_udat == false)){
|
||||
fgetpos(fp, &pos);
|
||||
buf[buf_num].addr = pos - sizeof(BoxHeader_t);
|
||||
buf[buf_num].size = boxHead.size;
|
||||
fseek(fp, boxHead.size - sizeof(BoxHeader_t), SEEK_CUR);
|
||||
|
||||
if(strncmp((const char *)boxHead.type, "stsz", 4) == 0)
|
||||
{
|
||||
gFound_stsz = true;
|
||||
}
|
||||
else if(strncmp((const char *)boxHead.type, "udat", 4) == 0)
|
||||
{
|
||||
gFount_udat = true;
|
||||
}
|
||||
|
||||
if (++buf_num == bufSize) {
|
||||
return buf_num;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Existence check of child box
|
||||
readSize = fread(&childBoxHead, 1, sizeof(BoxHeader_t), fp);
|
||||
fseek(fp, -(long)sizeof(BoxHeader_t), SEEK_CUR);
|
||||
childBoxHead.size = convertEndian_32(childBoxHead.size);
|
||||
isNotAscii = 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
if ((childBoxHead.type[i] < 'a') || (childBoxHead.type[i] > 'z')) {
|
||||
++isNotAscii;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((boxHead.size > childBoxHead.size) && (isNotAscii == 0)) {
|
||||
// child box is exist
|
||||
buf_num += GetCryptTarget(fp, &buf[buf_num], bufSize - buf_num, level + 1, boxHead.size - sizeof(BoxHeader_t));
|
||||
if (buf_num == bufSize) {
|
||||
return buf_num;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// child box is not exist
|
||||
fseek(fp, boxHead.size - sizeof(BoxHeader_t), SEEK_CUR);
|
||||
}
|
||||
}
|
||||
|
||||
// check of continue the child box loop
|
||||
if (parentSize == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// terminal box
|
||||
if (strncmp((const char *)boxHead.type, "FWVR", 4) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return buf_num;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Encrypt MP4 File
|
||||
*
|
||||
* @param[in] filename target file name
|
||||
*
|
||||
* @retval 0 successful
|
||||
* @retval non-zero failed
|
||||
*/
|
||||
int encrypt_an6000(const wchar_t *filename)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
BoxAddress_t tgtInfo[8];
|
||||
size_t infoSize, i, x;
|
||||
char *pbuf;
|
||||
char key = 0x19;
|
||||
char preData, enc;
|
||||
|
||||
memset(tgtInfo, 0, sizeof(tgtInfo));
|
||||
infoSize = sizeof(tgtInfo) / sizeof(BoxAddress_t);
|
||||
|
||||
fp = _wfopen(filename,L"r+b");
|
||||
//fp = fopen(filename, "r+b");
|
||||
if (fp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
// Analysis box information
|
||||
//BoxAnalysis(fp, 0, (size_t)-1);
|
||||
infoSize = GetCryptTarget(fp, tgtInfo, infoSize, 0, -1);
|
||||
|
||||
for (i = 0; i < infoSize; i++) {
|
||||
pbuf = (char*)malloc(tgtInfo[i].size);
|
||||
|
||||
// read the target data
|
||||
fsetpos(fp, &tgtInfo[i].addr);
|
||||
fread(pbuf, 1, tgtInfo[i].size, fp);
|
||||
|
||||
// data encrypt
|
||||
preData = 0;
|
||||
for (x = 8; x < tgtInfo[i].size; x++) {
|
||||
enc = ((~pbuf[x]) ^ preData) ^ key;
|
||||
preData = pbuf[x];
|
||||
pbuf[x] = enc;
|
||||
}
|
||||
|
||||
// over-write the target data
|
||||
fsetpos(fp, &tgtInfo[i].addr);
|
||||
fwrite(pbuf, 1, tgtInfo[i].size, fp);
|
||||
|
||||
free(pbuf);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Decrypt MP4 File
|
||||
*
|
||||
* @param[in] filename target file name
|
||||
*
|
||||
* @retval 0 successful
|
||||
* @retval non-zero failed
|
||||
*/
|
||||
int decrypt_an6000(const wchar_t *filename)
|
||||
{
|
||||
gFound_stsz = false;
|
||||
gFount_udat = false;
|
||||
|
||||
FILE *fp = NULL;
|
||||
BoxAddress_t tgtInfo[8] = {0,};
|
||||
size_t infoSize, i, x;
|
||||
char *pbuf = NULL;
|
||||
char key = 0x19;
|
||||
char preData = 0;
|
||||
|
||||
memset(tgtInfo, 0, sizeof(_BoxAddress_t) * 8);
|
||||
infoSize = sizeof(tgtInfo) / sizeof(_BoxAddress_t);
|
||||
|
||||
// filePathCH2.toStdWString().c_str()
|
||||
fp = _wfopen(filename,L"r+b");
|
||||
//fp = fopen(filename, "r+b");
|
||||
if (fp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
// Analysis box information
|
||||
infoSize = GetCryptTarget(fp, tgtInfo, infoSize, 0, -1);
|
||||
|
||||
for (i = 0; i < infoSize; i++) {
|
||||
pbuf = (char*)malloc(tgtInfo[i].size);
|
||||
|
||||
// read the target data
|
||||
fsetpos(fp, &tgtInfo[i].addr);
|
||||
fread(pbuf, 1, tgtInfo[i].size, fp);
|
||||
|
||||
// data decrypt
|
||||
preData = 0;
|
||||
for (x = 8; x < tgtInfo[i].size; x++) {
|
||||
pbuf[x] = ~((pbuf[x] ^ key) ^ preData);
|
||||
preData = pbuf[x];
|
||||
}
|
||||
|
||||
// over-write the target data
|
||||
fsetpos(fp, &tgtInfo[i].addr);
|
||||
fwrite(pbuf, 1, tgtInfo[i].size, fp);
|
||||
|
||||
free(pbuf);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
bool is_encrypted_an6000(const wchar_t *filename)
|
||||
{
|
||||
gFound_stsz = false;
|
||||
gFount_udat = false;
|
||||
|
||||
FILE *fp = NULL;
|
||||
BoxAddress_t tgtInfo[8] = {0,};
|
||||
size_t infoSize, i, x;
|
||||
|
||||
memset(tgtInfo, 0, sizeof(_BoxAddress_t) * 8);
|
||||
infoSize = sizeof(tgtInfo) / sizeof(_BoxAddress_t);
|
||||
|
||||
fp = _wfopen(filename,L"r+b");
|
||||
if (fp == NULL) {
|
||||
return false;
|
||||
}
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
infoSize = GetCryptTarget(fp, tgtInfo, infoSize, 0, -1);
|
||||
|
||||
char buffer[16] = {0,};
|
||||
for (i = 0; i < infoSize; i++) {
|
||||
// read the target data
|
||||
tgtInfo[i].addr += 4;
|
||||
fsetpos(fp, &tgtInfo[i].addr);
|
||||
fread(buffer, 1, 16, fp);
|
||||
if(buffer[0] == 's' && buffer[1] =='t' && buffer[2] =='s' && buffer[3] =='z') {
|
||||
|
||||
bool enc = (buffer[4] != 0 || buffer[5] != 0 || buffer[6] != 0 || buffer[7] != 0);
|
||||
fclose(fp);
|
||||
return enc;//(buffer[4] != 0 || buffer[5] != 0 || buffer[6] != 0 || buffer[7] != 0);
|
||||
}
|
||||
//printf("%c:%c:%c:%c\n",buffer[0],buffer[1],buffer[2],buffer[3]);
|
||||
//printf("%02X:%02X:%02X:%02X %02X:%02X:%02X:%02X\n",buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5],buffer[6],buffer[7]);
|
||||
}
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
#endif // #if (RM_MODEL == RM_MODEL_TYPE_AN6000)
|
||||
Reference in New Issue
Block a user