⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decompiler.cpp

📁 一个反汇编器源码 一个反汇编器源码
💻 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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -