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.
Save me from madness!!!
I have a several smartphone devices with windows CE
CE 6.0 - hp IPAQ 500 series
CE 5.0 - Samsung i600
I need to inject DLL into the process "home.exe". I use method with performcallback4 function. This method works successfully for all processes ("device.exe", "service.exe", etc.) except process "home.exe". In what a problem?
source code : InjectDLL.exe link with toolhelp.lib
#include <windows.h>
#include <Tlhelp32.h>
typedef struct _CALLBACKINFO {
HANDLE hProc;
FARPROC pfn;
PVOID pvArg0;
} CALLBACKINFO;
extern "C"
{
DWORD PerformCallBack4(CALLBACKINFO *pcbi,...);
LPVOID MapPtrToProcess(LPVOID lpv, HANDLE hProc);
BOOL SetKMode(BOOL fMode);
DWORD SetProcPermissions(DWORD newperms);
};
DWORD GetProcessId(WCHAR *wszProcessName)
{
HANDLE hTH= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe;
pe.dwSize= sizeof(PROCESSENTRY32);
DWORD PID=0;
if (Process32First(hTH, &pe))
{
do {
if (wcsicmp(wszProcessName, pe.szExeFile)==0)
{
PID=pe.th32ProcessID;
}
} while (Process32Next(hTH, &pe));
}
CloseToolhelp32Snapshot(hTH);
return PID;
}
HMODULE GetDllHandle(DWORD ProcessId,WCHAR* ModuleName)
{
HANDLE ToolHelp=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,ProcessId);
if (ToolHelp!=INVALID_HANDLE_VALUE)
{
MODULEENTRY32 ModuleEntry={sizeof MODULEENTRY32};
if (Module32First(ToolHelp,&ModuleEntry))
do
{
if (wcsicmp(ModuleEntry.szModule, ModuleName)==0)
return ModuleEntry.hModule;
}
while(Module32Next(ToolHelp,&ModuleEntry));
CloseToolhelp32Snapshot(ToolHelp);
}
return NULL;
}
BOOL InjectDll(WCHAR* ProcessName,WCHAR* ModuleName)
{
DWORD ProcessId=GetProcessId(ProcessName);
HMODULE ModuleHandle=GetDllHandle(ProcessId,ModuleName);
if (ModuleHandle!=NULL)
return TRUE;
HANDLE Process=OpenProcess(0,0,ProcessId);
if (Process==NULL)
return FALSE;
void* ModuleNamePtr=MapPtrToProcess(ModuleName,GetCurrentProcess());
if (ModuleNamePtr==NULL)
return FALSE;
CALLBACKINFO ci;
ci.hProc=Process;
void* LoadLibraryPtr=MapPtrToProcess(GetProcAddress(GetModuleHandle(L"coredll.dll"),L"LoadLibraryW"),Process);
if (LoadLibraryPtr==NULL)
return FALSE;
ci.pfn=(FARPROC)LoadLibraryPtr;
ci.pvArg0=ModuleNamePtr;
PerformCallBack4(&ci); in this place process exit. visual studio output message : "process exit with code 0xc0000030"
Sleep(500);
CloseHandle(Process);
return GetDllHandle(ProcessId,ModuleName)!=NULL;
}
extern "C"
{
BOOL SetKMode(BOOL fMode);
DWORD SetProcPermissions(DWORD newperms);
};
#define DLLNAME L"MyDll.dll"
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPWSTR lpCmdLine,int nShowCmd)
{
WCHAR Path[MAX_PATH];
GetModuleFileName(NULL,Path,MAX_PATH);
wcscpy(wcsrchr(Path,L'\\')+1,DLLNAME);
WCHAR NewPath[MAX_PATH]=L"\\Windows\\";
wcscat(NewPath,DLLNAME);
CopyFile(Path,NewPath,FALSE);
BOOL Res=InjectDll(L"home.exe",L"MyDll.dll");
return 0;
}
the error code is
#define STATUS_INVALID_PARAMETER_MIX 0xC0000030
(maybe too fast for getting the thread infos?)
try to make the "Sleep(500);" before "PerformCallBack4(&ci);"
I have tried, a problem not in it. Any ideas?
I have not found the reason.... I Use other method without performcallback4
Problem with injection dll to cprog.exe process?
I want to inject dll to cprog.exe process. but it doesn't work.
source code.
Code:
VOID
InjectDllToCprog()
{
WCHAR DllPath[MAX_PATH] = L"";
CallbackInfo ci;
GetModuleFileName(NULL, DllPath, MAX_PATH);
PWCHAR p = wcsrchr(DllPath, L'\\');
DllPath[p - DllPath] = '\0';
wcscat(DllPath, L"\\CprogInject.dll");
ZeroMemory(&ci, sizeof(ci));
g_hCprog = FindCprogProcess(L"Cprog.exe"); // the handle is right.
if(g_hCprog != NULL)
{
DWORD dwMode = SetKMode(TRUE);
DWORD dwPerm = SetProcPermissions(0xFFFFFFFF);
FARPROC pFunc = GetProcAddress(GetModuleHandle(L"Coredll.dll"), L"LoadLibraryW");
ci.ProcId = (HANDLE)g_hCprog;
ci.pFunc = (FARPROC)MapPtrToProcess(pFunc, g_hCprog);
ci.pvArg0 = MapPtrToProcess(DllPath, GetCurrentProcess());
g_InjectCprog = (HINSTANCE)PerformCallBack4(&ci, 0, 0, 0);
if(GetLastError() != 0) // GetLastError() = 5
DbgError(L"PerformCallBack 执行失败", GetLastError());
SetKMode(dwMode);
SetProcPermissions(dwPerm);
}
}
GetLastError() return 0x00000005(Access is denied)
Anyone can help me? Sorry for my poor english.