?? decompiler.cpp
字號:
#include "stdafx.h"
#include <winsock.h>
#include "decompiler.h"
#pragma comment(lib,"wsock32")
CArray<Constant,Constant &> g_ConstTable;
CArray<Function,Function &> g_FuncTable;
char *ConstantType[] =
{
"char8","short16","int32","float32","UTF-8_Str","\"\"","OtherCharsetStr"
};
static char tmp[128];
char * make_call_name(int lindex,int findex)
{
static char buf[256];
static char *lib_name[6] = {"Lang","Float","String","URL","WMLBrowser","Dialogs"};
static char *lib_func_table[6][16] =
{
{"abs","min","max","parseInt","parseFloat","isInt","isFloat","maxInt","minInt","float","exit","abort","random","seed","characterSet"},
{"int","floor","ceil","pow","round","sqrt","maxFloat","minFloat","*","*","*","*","*","*","*"},
{"length","isEmpty","charAt","subString","find","replace","elements","elementAt","removeAt","replaceAt","insertAt","squeeze","trim","compare","toString","format"},
{"isValid","getScheme","getHost","getPort","getPath","getParameters","getQuery","getFragment","getBase","getReferer","resolve","escapeString","unescapeString","loadString","*","*"},
{"getVer","setVer","go","prev","newContext","getCurrentCard","refresh","*","*","*","*","*","*","*","*","*"},
{"prompt","confirm","alert","*","*","*","*","*","*","*","*","*","*","*","*","*"}
};
if(lindex == -1) //local func
{
Function &f = g_FuncTable.ElementAt(findex);
strcpy(buf,f.func_name);
}
else if(lindex < 6)
{
if(lib_func_table[lindex][findex][0] == '*')
{
throw "function not found";
}
sprintf(buf,"%s.%s()",lib_name[lindex],lib_func_table[lindex][findex]);
}
else
{
sprintf(buf,"lib_%d.func_%d()",lindex,findex);
}
return buf;
}
//local var's index >= arg_num
char *make_var_name(int vindex,int arg_num)
{
static char buf[32];
if(vindex >= arg_num)
{
sprintf(buf,"var_%d",vindex-arg_num);
}
else
{
sprintf(buf,"arg_%d",vindex);
}
return buf;
}
int JUMP_FW(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
int offset = data[1];
sprintf(tmp,"JUMP_FW %04X",addr + 2 + offset);
return 2;
}
int JUMP_FW_W(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
int offset = htons(*(unsigned short*)(data+1));
sprintf(tmp,"JUMP_FW_W %04X",addr + 3 + offset);
return 3;
}
int JUMP_BW(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
BYTE offset = data[1];
sprintf(tmp,"JUMP_FW_W %04X",addr - offset);
return 2;
}
int JUMP_BW_W(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
int offset = htons(*(unsigned short*)(data+1));
sprintf(tmp,"JUMP_BW_W %04X",addr - offset);
return 3;
}
int TJUMP_FW(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
BYTE offset = data[1];
sprintf(tmp,"TJUMP_FW %04X",addr + 2 + offset);
return 2;
}
int TJUMP_FW_W(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
int offset = htons(*(unsigned short*)(data+1));
sprintf(tmp,"TJUMP_FW_W %04X",addr + 3 + offset);
return 3;
}
int TJUMP_BW(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
BYTE offset = data[1];
sprintf(tmp,"TJUMP_BW %04X",addr - offset);
return 2;
}
int TJUMP_BW_W(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
int offset = htons(*(unsigned short*)(data+1));
sprintf(tmp,"TJUMP_BW_W %04X",addr - offset);
return 3;
}
int CALL(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
int findex = data[1];
sprintf(tmp,"CALL %s",make_call_name(-1,findex));
return 2;
}
int CALL_LIB(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
int findex = data[1];
int lindex = data[2];
sprintf(tmp,"CALL %s",make_call_name(lindex,findex));
return 3;
}
int CALL_LIB_W(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
int findex = data[1];
int lindex = htons(*(unsigned short *)(data+1));
sprintf(tmp,"CALL %s",make_call_name(lindex,findex));
return 4;
}
int CALL_URL(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
int url_index = data[1];
BYTE findex = data[2];
BYTE args = data[3];
Constant c = g_ConstTable.ElementAt(url_index);
sprintf(tmp,"CALL_URL con_%d.func_%d args_num=%d ;url=%s",url_index,findex,args,c.toStr);
return 4;
}
int CALL_URL_W(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
int uindex = htons(*(unsigned short*)(data+1));
int findex = htons(*(unsigned short*)(data+3));
BYTE args = data[5];
sprintf(tmp,"CALL_URL_W url_%d.func_%d argc_%d",addr,op_code,uindex,findex,args);
return 6;
}
int LOAD_VAR(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
int vindex = data[1];
sprintf(tmp,"LOAD_VAR %s",make_var_name(vindex,arg_num));
return 2;
}
int STORE_VAR(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
int vindex = data[1];
sprintf(tmp,"STORE_VAR %s",make_var_name(vindex,arg_num));
return 2;
}
int INCR_VAR(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
int vindex = data[1];
sprintf(tmp,"INCR_VAR %s",make_var_name(vindex,arg_num));
return 2;
}
int DECR_VAR(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
int vindex = data[1];
sprintf(tmp,"DECR_VAR %s",make_var_name(vindex,arg_num));
return 2;
}
int LOAD_CONST(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
int cindex = data[1];
Constant c = g_ConstTable.ElementAt(cindex);
sprintf(tmp,"LOAD_CONST con_%d ;TYPE:%s,[%s]",cindex,ConstantType[c.type],c.toStr);
return 2;
}
int LOAD_CONST_W(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
int cindex = htons(*(unsigned short *)(data+1));
Constant c = g_ConstTable.ElementAt(cindex);
sprintf(tmp,"LOAD_CONST_W con_%d ;TYPE:%s,[%s]",cindex,ConstantType[c.type],c.toStr);
return 3;
}
int ADD_ASG(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
BYTE vindex = data[1];
sprintf(tmp,"ADD_ASG %s",make_var_name(vindex,arg_num));
return 2;
}
int SUB_ASG(BYTE *data,int addr,int arg_num)
{
BYTE op_code = data[0];
BYTE vindex = data[1];
sprintf(tmp,"SUB_ASG %s",make_var_name(vindex,arg_num));
return 2;
}
Instruction InArray[] =
{
{"",NULL}, //0
{"JUMP_FW", JUMP_FW}, //1
{"JUMP_FW_W", JUMP_FW_W}, //2
{"JUMP_BW", JUMP_BW}, //3
{"JUMP_BW_W", JUMP_BW_W}, //4
{"TJUMP_FW", TJUMP_FW}, //5
{"TJUMP_FW_W", TJUMP_FW_W}, //6
{"TJUMP_BW", TJUMP_BW}, //7
{"TJUMP_BW_W",TJUMP_BW_W}, //8
{"CALL", CALL}, //9
{"CALL_LIB", CALL_LIB}, //10
{"CALL_LIB_W", CALL_LIB_W}, //11
{"CALL_URL", CALL_URL}, //12
{"CALL_URL_W", CALL_URL_W}, //13
{"LOAD_VAR", LOAD_VAR}, //14
{"STORE_VAR", STORE_VAR}, //15
{"INCR_VAR", INCR_VAR}, //16
{"DECR_VAR", DECR_VAR}, //17
{"LOAD_CONST", LOAD_CONST}, //18
{"LOAD_CONST_W",LOAD_CONST_W}, //19
{"CONST_0",NULL}, //20
{"CONST_1",NULL}, //21
{"CONST_M1",NULL}, //22
{"CONST_ES",NULL}, //23
{"CONST_INVALID",NULL}, //24
{"CONST_TRUE",NULL}, //25
{"CONST_FALSE",NULL}, //26
{"INCR",NULL}, //27
{"DECR",NULL}, //28
{"ADD_ASG",ADD_ASG}, //29
{"SUB_ASG",SUB_ASG}, //30
{"UMINUS",NULL}, //31
{"ADD",NULL}, //32
{"SUB",NULL}, //33
{"MUL",NULL}, //34
{"DIV",NULL}, //35
{"IDIV",NULL}, //36
{"REM",NULL}, //37
{"B_AND",NULL}, //38
{"B_OR",NULL}, //39
{"B_XOR",NULL}, //40
{"B_NOT",NULL}, //41
{"B_LSHIFT",NULL}, //42
{"B_RSSHIFT",NULL}, //43
{"B_RSZSHIFT",NULL}, //44
{"EQ",NULL}, //45
{"LE",NULL}, //46
{"LT",NULL}, //47
{"GE",NULL}, //48
{"GT",NULL}, //49
{"NE",NULL}, //50
{"NOT",NULL}, //51
{"SCAND",NULL}, //52
{"SCOR",NULL}, //53
{"TOBOOL",NULL},//54
{"POP",NULL}, //55
{"TYPEOF",NULL},//56
{"ISVALID",NULL},//57
{"RETURN",NULL},//58
{"RETURN_ES",NULL},//59
{"DEBUG",NULL}, //60
};
int TransCode(BYTE *data,int addr,int arg_num)
{
int i = 0;
BYTE op_code = data[i++];
if((op_code & 0x80) == 0x80)
{
//JUMP_FW_S/JUMP_BW_S/TJUMP_FW_S/LOAD_VAR_S
if(
(op_code & 0x80) == 0x80 &&
(op_code & 0x60) == 0) //JUMP_FW_S 100iiiii
{
int offset = (op_code & 0x1F);
sprintf(tmp,"JUMP_FW_S %04X",addr + 1 + offset);
}
else if(
(op_code & 0xA0) == 0xA0 &&
(op_code & 0x40) == 0) //JUMP_BW_S
{
int offset = (op_code & 0x1F);
sprintf(tmp,"JUMP_BW_S %04X",addr + 1 + offset);
}
else if(
(op_code & 0xC0) == 0xC0 &&
(op_code & 0x20) == 0) //TJUMP_FW_S
{
int offset = (op_code & 0x1F);
sprintf(tmp,"TJUMP_FW_S %04X",addr + 1 + offset);
}
else if(
(op_code & 0xE0) == 0xE0) //LOAD_VAR_S
{
int vindex = (op_code & 0x1F);
sprintf(tmp,"LOAD_VAR_S %s",make_var_name(vindex,arg_num));
}
}
else if((op_code & 0x40) == 0x40 && (op_code & 0xA0)==0)
{
//STORE_VAR_S/LOAD_CONST_S
if(
(op_code & 0x40) == 0x40 &&
(op_code & 0xB0) == 0) //STORE_VAR_S
{
int vindex = (op_code & 0x0F);
sprintf(tmp,"STORE_VAR_S %s",make_var_name(vindex,arg_num));
}
else if(
(op_code & 0x40) == 0x40 &&
(op_code & 0xA0) == 0) //LOAD_CONST_S
{
int cindex = (op_code & 0x0F);
Constant c = g_ConstTable.ElementAt(cindex);
sprintf(tmp,"LOAD_CONST_S con_%d ;TYPE:%s,[%s]",cindex,ConstantType[c.type],c.toStr);
}
else
{
ASSERT(FALSE);
}
}
else if((op_code & 0x60) == 0x60)
{
//CALL_S/CALL_LIB_S/INCR_VAR_S
if(
(op_code & 0x60) == 0x60 &&
(op_code & 0x98) == 0) //CALL_S
{
int findex = (op_code & 0x07);
sprintf(tmp,"CALL_S %s",make_call_name(-1,findex));
}
else if(
(op_code & 0x68) == 0x68 &&
(op_code & 0x90) == 0) //CALL_LIB_S
{
int findex = (op_code & 0x07);
int lindex = data[i++];
sprintf(tmp,"CALL_LIB_S %s",make_call_name(lindex,findex));
}
else if(
(op_code & 0x70) == 0x70 &&
(op_code & 0x88) == 0) //INCR_VAR_S
{
int vindex = (op_code & 0x07);
sprintf(tmp,"INCR_VAR_S %s",make_var_name(vindex,arg_num));
}
else
{
ASSERT(FALSE);
}
}
else
{
const ins_count = sizeof(InArray)/sizeof(InArray[0]);
if(op_code >= ins_count)
{
return -1;
}
Instruction *ip = InArray + op_code;
if(ip->parser == NULL)
{
sprintf(tmp,"%s",ip->ins_name);
}
else
{
int n = ip->parser(data,addr,arg_num);
i = i + n - 1;
}
}
return i;
}
unsigned int get_mb_uint(BYTE *data,int len,int &k)
{
unsigned int r = 0;
int i = 0;
for(i=0;i<len;i++)
{
BYTE b = data[i];
r = (r << 7) | (b & 0x7F);
if( (b & 0x80)==0 )
{
break;
}
}
k = k + i + 1;
return r;
}
bool DeCompile(BYTE *bin_code,int len,CList<CString,CString&> &result)
{
int i = 0;
int k = 0;
g_ConstTable.RemoveAll();
//version
BYTE ver = bin_code[k++];
if(ver != 1)
{
return false;
}
//code_size
unsigned int code_size = get_mb_uint(bin_code + k,4,k);
///////////////////////////////////////////////
//ConstantPool
///////////////////////////////////////////////
unsigned short cont_num = get_mb_uint(bin_code + k,2,k);
unsigned short charset = get_mb_uint(bin_code + k,2,k);
for(i=0;i<cont_num;i++)
{
Constant c;
BYTE cons_type = bin_code[k++];
c.type = cons_type;
switch(cons_type)
{
case 0: //char
c.size = 1;
c.toStr.Format("%d",bin_code[k]);
break;
case 1: //short
{
c.size = 2;
short v = htons(*(short *)(bin_code + k));
c.toStr.Format("%d",v);
}
break;
case 2: //int
{
c.size = 4;
int v = htonl(*(int *)(bin_code + k));
c.toStr.Format("%d",v);
}
break;
case 3:
{
c.size = 4;
int tv = htonl(*(int *)(bin_code + k));
float v = *(float*)&tv;
c.toStr.Format("%f",v);
}
break;
case 4: //UTF-8
{
c.size = get_mb_uint(bin_code+k,4,k);
for(unsigned j=0;j<c.size;j++)
{
CString uc;
uc.Format("%c",bin_code[k+j]);
c.toStr += uc;
}
}
break;
case 5: //EMPTY STR
c.size = 0;
c.toStr = "EMPTY_STR";
break;
case 6:
{
c.size = get_mb_uint(bin_code+k,4,k);
c.toStr = "...(can't display)";
}
break;
default:
return false;
break;
}
k+=c.size;
g_ConstTable.Add(c);
}
///////////////////////////////////////////////
//PragmaPool
///////////////////////////////////////////////
BYTE prama_num = get_mb_uint(bin_code+k,2,k);
for(i=0;i<prama_num;i++)
{
BYTE ptype = bin_code[k++];
switch(ptype)
{
case 0://access domain
{
unsigned p_index = get_mb_uint(bin_code+k,2,k);
}
break;
case 1: //access path
{
unsigned p_index = get_mb_uint(bin_code+k,2,k);
}
break;
case 2:
{
unsigned prop_name_index = get_mb_uint(bin_code+k,2,k);
unsigned content_index = get_mb_uint(bin_code+k,2,k);
}
break;
case 3:
{
unsigned prop_name_index = get_mb_uint(bin_code+k,2,k);
unsigned content_index = get_mb_uint(bin_code+k,2,k);
unsigned scheme_index = get_mb_uint(bin_code+k,2,k);
}
break;
default:
return false;
}
}
///////////////////////////////////////////////
//FunctionPool
///////////////////////////////////////////////
g_FuncTable.RemoveAll();
BYTE func_num = bin_code[k++];
int num_func_names = bin_code[k++];
for(int j=0;j<num_func_names;j++)
{
Function f;
f.findex = bin_code[k++];
int func_name_size = bin_code[k++];
CString uc;
for(int m=0;m<func_name_size;m++)
{
uc.Format("%c",bin_code[k++]);
f.func_name += uc;
}
g_FuncTable.Add(f);
}
for(i=0;i<g_FuncTable.GetSize();i++)
{
Function &f = g_FuncTable.ElementAt(i);
f.arg_num = bin_code[k++];
f.lvar_num = bin_code[k++];
f.func_size = get_mb_uint(bin_code+k,4,k);
f.CodeArray = new BYTE[f.func_size];
memcpy(f.CodeArray,bin_code+k,f.func_size);
k+=f.func_size;
}
for(int f=0;f<g_FuncTable.GetSize();f++)
{
CString str,arg_str,local_var_str = "var ";
Function func = g_FuncTable.ElementAt(f);
for(int j=0;j<func.arg_num;j++)
{
CString arg;
arg.Format("arg_%d",j);
if(j != func.arg_num-1)
{
arg += ",";
}
arg_str += arg;
}
for(j=0;j<func.lvar_num;j++)
{
CString lvar;
lvar.Format("var_%d",j);
if(j != func.lvar_num-1)
{
lvar += ",";
}
else
{
lvar += ";";
}
local_var_str += lvar;
}
str.Format("function %s(%s)",func.func_name,arg_str);
result.AddTail(str);
if(local_var_str.GetLength() > 4)
{
result.AddTail(local_var_str);
}
i = 0;
while(i < (int)func.func_size)
{
int n = TransCode(func.CodeArray + i, i,func.arg_num);
if(n < 0)
{
return false;
}
CString code;
CString byte_code;
for(int j=0;j<n;j++)
{
char tmp_str[128];
sprintf(tmp_str,"%02X",func.CodeArray[i + j]);
if(j != n-1)
{
strcat(tmp_str," ");
}
byte_code += tmp_str;
}
code.Format("%04X %-12s %s",i,byte_code, tmp);
result.AddTail(code);
i += n;
}
}
return true;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -