The most recent ROM update released by Dopod has changed the format of NBF files. Here is the information I've found. Maybe someone would create a new xda3nbftool from the code I provide? I don't have time for this. Probably the same format soon would be used in other operator's updates.
New NBF files header is normally 0xAB bytes in length and looks like "K7qAW73q39..skipped..t7=". It is a base64 encoded string with a modified alphabet. The string length may change in the newer version, so you need to search for "=" to find the end of a header.
Here is a sample code that decodes it:
Code:
/*
* $Id: base64.c,v 1.1.1.1 2001/10/04 00:16:06 andrewr Exp $
* modified by mamaich for HTC firmware
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static void base64_init(void);
static int base64_initialized = 0;
#define BASE64_VALUE_SZ 256
#define BASE64_RESULT_SZ 8192
int base64_value[BASE64_VALUE_SZ];
/*
* This is the original base64 decode table:
*
const char* base64_code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
*/
/*
* BaUpgradeUt uses a modified alphabet:
*/
const char* base64_code = "yz98765432UVWXYZabcdKLMNOPQRSTopqrstuvwxefghijklmnABCDEFGHIJ10+/";
static void
base64_init(void)
{
int i;
for (i = 0; i < BASE64_VALUE_SZ; i++)
base64_value[i] = -1;
for (i = 0; i < 64; i++)
base64_value[(int) base64_code[i]] = i;
base64_value['='] = 0;
base64_initialized = 1;
}
char *
base64_decode(const char *p)
{
static char result[BASE64_RESULT_SZ];
int j;
int c;
long val;
if (!p)
return NULL;
if (!base64_initialized)
base64_init();
val = c = 0;
for (j = 0; *p && j + 4 < BASE64_RESULT_SZ; p++) {
unsigned int k = ((unsigned char) *p) % BASE64_VALUE_SZ;
if (base64_value[k] < 0)
continue;
val <<= 6;
val += base64_value[k];
if (++c < 4)
continue;
/* One quantum of four encoding characters/24 bit */
result[j++] = val >> 16; /* High 8 bits */
result[j++] = (val >> 8) & 0xff; /* Mid 8 bits */
result[j++] = val & 0xff; /* Low 8 bits */
val = c = 0;
}
result[j] = 0;
return result;
}
/* adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments */
const char *
base64_encode(const char *decoded_str)
{
static char result[BASE64_RESULT_SZ];
int bits = 0;
int char_count = 0;
int out_cnt = 0;
int c;
if (!decoded_str)
return decoded_str;
if (!base64_initialized)
base64_init();
while ((c = (unsigned char) *decoded_str++) && out_cnt < sizeof(result) - 5) {
bits += c;
char_count++;
if (char_count == 3) {
result[out_cnt++] = base64_code[bits >> 18];
result[out_cnt++] = base64_code[(bits >> 12) & 0x3f];
result[out_cnt++] = base64_code[(bits >> 6) & 0x3f];
result[out_cnt++] = base64_code[bits & 0x3f];
bits = 0;
char_count = 0;
} else {
bits <<= 8;
}
}
if (char_count != 0) {
bits <<= 16 - (8 * char_count);
result[out_cnt++] = base64_code[bits >> 18];
result[out_cnt++] = base64_code[(bits >> 12) & 0x3f];
if (char_count == 1) {
result[out_cnt++] = '=';
result[out_cnt++] = '=';
} else {
result[out_cnt++] = base64_code[(bits >> 6) & 0x3f];
result[out_cnt++] = '=';
}
}
result[out_cnt] = '\0'; /* terminate */
return result;
}
int main()
{
char *In="K7qAW73q39yq39yq39yq37bZK707Xtyn39yq39yq39zNLCKq39yq387kWtakW8Oq39yq39yq39z9R4LvaMHxPMmq39yq39yqW9yq39yq39zrW8ymW8ymW8amW8ym39yq39yq39yq39yq39yq39yq39yq39yq39yqW5KEY8qAWt7=";
puts(base64_decode(In));
}
Re: Encryption algo in ba_dpodcht_12406_110_10600 + radio RO
The encryption of the ROM image has also changed. It is still a modification of XOR algorythm. The remaining part of the file starting from 0xAB offset may be decrypted with this procedure:
Code:
bool XorBuffer(BYTE *buf, int len, DWORD &dwVal)
{
DWORD *p= (DWORD*)buf;
if (len&3)
printf("WARNING: buffer not multiple of 4\n");
len >>= 2;
while (len--)
{
*p++ ^= dwVal;
dwVal^=p[-1];
}
return true;
}
The modification is minimal - the XOR constant is XORed itself with a decrypted byte. The other code of xda3nbftool does not need to be modified except for skipping the 0xAB bytes from the start of a file.
The starting values of dwVal for the chinese update:
Extended ROM: 0x9d94b405
Main ROM: 0xE688221
Radio: 0x1F1F5006
Maybe later I'll make a program that would automatically calculate these constants for a given ROM image.
Re: Encryption algo in ba_dpodcht_12406_110_10600 + radio RO
To protect radio ROM from reverse engeneering HTC used a simple substitution cipher. I've managed to calculate a part of a table for ascii characters and numbers. Someone with a better cryptographic skills is needed to find the remaining part of the table. Here is a sample code that partially decrypts the radio ROM image. All embedded strings become readable, but the code still cannot be decompiled.
Edited: I've calculated the whole table. See posts below.
Code:
#include <stdio.h>
int Arr[256];
void main(int argc, char *argv[])
{
FILE *SrcFile;
unsigned long Count[256], MaxCount=0;
int I, Ch, PrevCh=0, Divider, Value;
for(int i=0; i<256; i++)
Arr[i]=i;
Arr[0xFF]=0xFF;
... deleted ...
Arr[0x2D]=0x7e;
if (argc != 2)
{
printf("\nSyntax: DECR <file>");
return;
}
if ((SrcFile=fopen(argv[1],"rb")) == NULL)
{
printf("\nCannot open %s",argv[1]);
return;
}
FILE *O=fopen("radio","wb");
for (I=0; I < sizeof(Count)/sizeof(Count[0]); I++)
Count[I]=0;
while ((Ch=fgetc(SrcFile)) != EOF)
fputc(Arr[Ch],O);
fclose(SrcFile);
fclose(O);
}
The code looks ugly, but it works.
Looking at Magician ROM?
Hi mamaich,
Thanks for your continuous good work!
Are you looking at Magician ROM as well? While it uses USB for ActiveSync, it may mean the closest and most official port that Himalaya can have.
Re: Looking at Magician ROM?
I've found a simple method to generate the complete table.
Here is it:
Code:
int Arr[256]={
0x34, 0x4F, 0x9E, 0x59, 0x47, 0xC1, 0xAC, 0x96, 0xF5, 0x99, 0xF4, 0x24, 0x58, 0xFD, 0x2C, 0x7B,
0x3F, 0x25, 0x26, 0x00, 0x61, 0x21, 0x30, 0x54, 0x1D, 0x2D, 0xDF, 0x05, 0xBD, 0x29, 0x2A, 0x82,
0x14, 0x6E, 0x31, 0x68, 0x10, 0x5C, 0x63, 0x13, 0x1C, 0xDE, 0x39, 0x1F, 0x18, 0x7E, 0x66, 0xD0,
0xB3, 0x1B, 0xED, 0x20, 0x27, 0x3B, 0x8D, 0x0B, 0xB6, 0x64, 0xC2, 0x28, 0x2F, 0x9D, 0x78, 0x0E,
0xAF, 0x52, 0xD4, 0xD6, 0x70, 0x6C, 0x53, 0x73, 0x7C, 0x5A, 0xD1, 0x7F, 0x6D, 0x69, 0x5D, 0x12,
0x43, 0xCB, 0x2E, 0xBC, 0x04, 0xB8, 0x86, 0x44, 0x4B, 0x3E, 0xD5, 0xB9, 0x01, 0x4D, 0xA8, 0x4C,
0xE4, 0xAB, 0x7A, 0x35, 0xA3, 0xEC, 0x3D, 0x72, 0x11, 0x5E, 0x8F, 0xC0, 0x56, 0x19, 0xC8, 0x87,
0x0F, 0x45, 0x46, 0xC3, 0x55, 0xCC, 0x6B, 0xB7, 0x0A, 0x62, 0x71, 0x36, 0xA0, 0x49, 0x4A, 0xB2,
0xC4, 0x92, 0xD9, 0x77, 0xE1, 0x07, 0x38, 0x17, 0x74, 0x9A, 0xBA, 0xBF, 0x67, 0x02, 0x1A, 0xE2,
0x83, 0xA5, 0xA6, 0xD7, 0x6F, 0xA1, 0x33, 0x84, 0x8B, 0xAD, 0x85, 0xD2, 0x6A, 0xA9, 0xAA, 0x8C,
0x94, 0x0C, 0xAE, 0x50, 0x90, 0x95, 0xB4, 0x93, 0x9C, 0x09, 0x5B, 0x9F, 0x98, 0xCD, 0xB1, 0xE6,
0xF2, 0x57, 0x4E, 0x23, 0xCE, 0xFA, 0x2B, 0x97, 0xA2, 0x48, 0x8E, 0xCF, 0x40, 0x89, 0x3A, 0x91,
0x5F, 0x9B, 0x03, 0xF7, 0xF0, 0xBB, 0xEE, 0xF3, 0xFC, 0xDB, 0x06, 0x65, 0xE9, 0xBE, 0xF8, 0xFB,
0x16, 0xE5, 0x88, 0xC7, 0x51, 0x1E, 0x79, 0x80, 0xE3, 0x15, 0x7D, 0x32, 0xA4, 0xEB, 0xEA, 0x75,
0x42, 0xB0, 0xF1, 0x76, 0x22, 0xF6, 0x08, 0xD3, 0xDC, 0xB5, 0xF9, 0x41, 0x81, 0xFE, 0x0D, 0xDA,
0xD8, 0xC5, 0xC6, 0xE0, 0xE7, 0x3C, 0x37, 0x60, 0xDD, 0x8A, 0xA7, 0xE8, 0xEF, 0xC9, 0xCA, 0xFF
};
I've removed useless table from my previous post.
Here is the decrypted BlueAngel 1.06 radio ROM.
henrylim I don't have Magician so I cannot make any tools for it.
One note. Do not ask me for the compiled versions of these tools, nor ask for writing the unlocker for BlueAngel. I'll ignore such posts.
After the download, Wht do i need to do?
weasley said:
After the download, Wht do i need to do?
Click to expand...
Click to collapse
Dumb question. Why have you downloaded a file if you don't know how to use it?
I just bought a xda iis and wish to upgrade the rom to chinese but i got a radion sum error when i start the upgrade. so could you kindly advise me what to do?
weasley said:
I just bought a xda iis and wish to upgrade the rom to chinese but i got a radion sum error when i start the upgrade. so could you kindly advise me what to do?
Click to expand...
Click to collapse
you should ask in "BlueAngel upgrading" forum. There may be 2 reasons for this:
1. Archive is broken. You should redownload the update. And make sure that you are not installing the Himalaya ROM on BlueAngel.
2. Something is wrong with your PC. Try the upgrade on different PC.
Or you may keep the old radio and upgrade everything else.
hi mamaich,
is there any tool like an updated version of xda3nbftool so that we can change the operator and country code for the new roms. pls help how modify the new roms using the new encryption method.
thanks
jeet
jeet said:
hi mamaich,
is there any tool like an updated version of xda3nbftool so that we can change the operator and country code for the new roms. pls help how modify the new roms using the new encryption method.
thanks
jeet
Click to expand...
Click to collapse
This would be great indeed.... If someone could make the time for this a lot of people would be most happy.
Hi mamaich,
you ARE genius... )))) perfect...
buzz
Ok, i dont quite get it, how do I decrypt.............naaaaaa just kidding :lol:
Damm, keep up the good work.
Whish i had more time to study this
Great post, and great work!
Thanks!
I am actually using a perl script, written by itsme...the array is the same.
My question: Is the process reversible?
If I would take a radio_.nbf (or better yet, a dump), decrypt it to nba using xda3nbftool, then decode it, edit it...and encode it again by reversing the script, would I get a valid encoded nba back?
Thanks again,
HapyGoat
You can reencrypt the file back. Of cause you'll need to reverse the table to do this. I did it and it worked. But be careful, you can kill the radio part of your device.
Thanks mamaich for experimenting! That is great news...
Did you use a radio dump or started with an original nbf file?
I've worked with original NBF
Has anyone been able to compile an easy-to-use executable? I don't have access to a C compiler, and I tried reprogramming it in PureBasic, but it still comes out totally garbled. I'm assuming the 256-byte decryption table is specific for that one encrypted ROM file.
Please help, I'm trying to compare Anansky's BigStorage hack on the Magicians and provide support to other language ROM files and future updates.
Thanks!
I've managed to compile a program based on mamaich's previous posts to read in the header of an encrypted ROM file to spit out the XOR key and the unencrypted header, but I don't understand the decryption of the actual ROM portion with the modified XOR. My programming skills are intermediate and this was actually my first attempt at C++ programming (well, the second half anyway).
I compiled the code using Bloodshed.net's Dev-C++ program (very nice and simple).
Can anyone help out with the rest to decrypt (and of course, re-encrypt) the latest ROMs, and to possibly inject the code into a new xda3nbftool?
Code:
/*
* $Id: base64.c,v 1.1.1.1 2001/10/04 00:16:06 andrewr Exp $
* modified by mamaich for HTC firmware
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static void base64_init(void);
static int base64_initialized = 0;
#define BASE64_VALUE_SZ 256
#define BASE64_RESULT_SZ 8192
int base64_value[BASE64_VALUE_SZ];
/*
* This is the original base64 decode table:
*
const char* base64_code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
*/
/*
* BaUpgradeUt uses a modified alphabet:
*/
const char* base64_code = "yz98765432UVWXYZabcdKLMNOPQRSTopqrstuvwxefghijklmnABCDEFGHIJ10+/";
static void
base64_init(void)
{
int i;
for (i = 0; i < BASE64_VALUE_SZ; i++)
base64_value[i] = -1;
for (i = 0; i < 64; i++)
base64_value[(int) base64_code[i]] = i;
base64_value['='] = 0;
base64_initialized = 1;
}
char *
base64_decode(const char *p)
{
static char result[BASE64_RESULT_SZ];
int j;
int c;
long val;
if (!p)
return NULL;
if (!base64_initialized)
base64_init();
val = c = 0;
for (j = 0; *p && j + 4 < BASE64_RESULT_SZ; p++) {
unsigned int k = ((unsigned char) *p) % BASE64_VALUE_SZ;
if (base64_value[k] < 0)
continue;
val <<= 6;
val += base64_value[k];
if (++c < 4)
continue;
/* One quantum of four encoding characters/24 bit */
result[j++] = val >> 16; /* High 8 bits */
result[j++] = (val >> 8) & 0xff; /* Mid 8 bits */
result[j++] = val & 0xff; /* Low 8 bits */
val = c = 0;
}
result[j] = 0;
return result;
}
/* adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments */
const char *
base64_encode(const char *decoded_str)
{
static char result[BASE64_RESULT_SZ];
int bits = 0;
int char_count = 0;
int out_cnt = 0;
int c;
if (!decoded_str)
return decoded_str;
if (!base64_initialized)
base64_init();
while ((c = (unsigned char) *decoded_str++) && out_cnt < sizeof(result) - 5) {
bits += c;
char_count++;
if (char_count == 3) {
result[out_cnt++] = base64_code[bits >> 18];
result[out_cnt++] = base64_code[(bits >> 12) & 0x3f];
result[out_cnt++] = base64_code[(bits >> 6) & 0x3f];
result[out_cnt++] = base64_code[bits & 0x3f];
bits = 0;
char_count = 0;
} else {
bits <<= 8;
}
}
if (char_count != 0) {
bits <<= 16 - (8 * char_count);
result[out_cnt++] = base64_code[bits >> 18];
result[out_cnt++] = base64_code[(bits >> 12) & 0x3f];
if (char_count == 1) {
result[out_cnt++] = '=';
result[out_cnt++] = '=';
} else {
result[out_cnt++] = base64_code[(bits >> 6) & 0x3f];
result[out_cnt++] = '=';
}
}
result[out_cnt] = '\0'; /* terminate */
return result;
}
int main(int argc, char *argv[])
{
char In[0xFF],Ch;
FILE *SrcFile;
int i;
if (argc != 2)
{
printf("\nSyntax: HEADER <newROMfile>");
return 1;
}
if ((SrcFile=fopen(argv[1],"rb")) == NULL)
{
printf("\nCannot open %s",argv[1]);
return 1;
}
Ch=fgetc(SrcFile);
i=0;
while (Ch != 0x3D)
{
In[i]=(char)Ch;
Ch=fgetc(SrcFile);
i++;
}
In[i]=(char)Ch;
printf("\nHeader of %s:\n",argv[1]);
puts(base64_decode(In));
}
Output:
Code:
C:\>result.exe radio_.nbf
Header of radio_.nbf:
PM10C CDL__001 WWE 1.11.00 Magician 0
0 0 3bd9e0b4
Manich
I know you have had contact with the auther of the new tool, what I am not aware of is if you were able to help him work out the checksum of modifed type II rom.
This seems to be the problem he has when saving a type II rom.