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

📄 crudcom2.cpp

📁 当前支持 16-bit, 32-bit and 64-bit 的二进制文件
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		{
			memory.meta[i].local = 0;
			//memory.meta[i].decompiled = 0;
		}
	}
	
	bool reparse(U8 target);
	
};

static void load_operand(expr_t *&expr, U4 value, expr_t *table[])
{
	if(value >= 0x80000000)
	{
		value -= 0x80000000;
		if(value == no_void)
		{
			expr = NULL;
			return;
		}
		else
//	et_reg_reg		// subtype is 0. u.data[0] is argsize_*, u.data[1] is 1st reg index, u.data[2] is 2nd reg index.
		if(value > no__begin_x86_regs && value < no__end_x86_regs)
		{
			expr = new expr_t();
			expr->subtype = 0;
			switch(value)
			{
				case no_x86_ah:			expr->type = et_reg; expr->u.data[0] = argsize_8; expr->u.data[1] = 4; break;
				case no_x86_al:			expr->type = et_reg; expr->u.data[0] = argsize_8; expr->u.data[1] = 0; break;
				case no_x86_dl:			expr->type = et_reg; expr->u.data[0] = argsize_8; expr->u.data[1] = 2; break;
				case no_x86_ax:			expr->type = et_reg; expr->u.data[0] = argsize_16; expr->u.data[1] = 0; break;
				case no_x86_dx:			expr->type = et_reg; expr->u.data[0] = argsize_16; expr->u.data[1] = 2; break;
				case no_x86_eax:		expr->type = et_reg; expr->u.data[0] = argsize_32; expr->u.data[1] = 0; break;
				case no_x86_edx:		expr->type = et_reg; expr->u.data[0] = argsize_32; expr->u.data[1] = 2; break;
				case no_x86_rax:		expr->type = et_reg; expr->u.data[0] = argsize_64; expr->u.data[1] = 0; break;
				case no_x86_rdx:		expr->type = et_reg; expr->u.data[0] = argsize_64; expr->u.data[1] = 2; break;
				case no_x86_dx_ax:		expr->type = et_reg_reg; expr->u.data[0] = argsize_16; expr->u.data[1] = 2; expr->u.data[2] = 0; break;
				case no_x86_edx_eax:	expr->type = et_reg_reg; expr->u.data[0] = argsize_32; expr->u.data[1] = 2; expr->u.data[2] = 0; break;
				case no_x86_rdx_rax:	expr->type = et_reg_reg; expr->u.data[0] = argsize_64; expr->u.data[1] = 2; expr->u.data[2] = 0; break;
				default:
					throw std::runtime_error("invalid register");
					break;
			}
		}
		else
		{
			expr = new expr_t();
			expr->type = et_nodeoperand;
			expr->subtype = value;
		}
	}
	else
	{
		expr = table[value];
	}
}

#include "reparse.h"

std::set<U8> test_visited;
std::list<bb_t *> test_list;
void test_dfs(bb_t *node)
{
	if(test_visited.find(node->address) != test_visited.end())
		return;
	test_visited.insert(node->address);
	// call all out edges
	std::vector<bb_t *>::iterator i = node->out_edges.end();
	for(;;)
	{
		if(i == node->out_edges.begin())
			break;
		--i;
		if((*i)->proc == node->proc)
			test_dfs(*i);
	}
	test_list.push_front(node);
}
std::string int_to_string(U4 value, const char *fmt)
{
	char buf[1024];
	std::sprintf(buf, fmt, value);
	return std::string(buf);
}
std::string expr_to_string(expr_t *expr)
{
	const char *reg8[] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"};
	const char *reg16[] = {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"};
	const char *reg32[] = {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"};
	const char *sregs[] = {"es", "cs", "ss", "ds", "fs", "gs", "ss", "ds"};

	std::string s;
	if(expr->type == et_nodetype)
	{
		if(expr->subtype == nt__x86_cc)
		{
			s = get_ll_cc_text(expr->u.subexpr[0]->u.data[0]);
			return s;
		}
	
		s = strings_nt[expr->subtype];
		if(expr->subtype == nt_zx || expr->subtype == nt_sx || expr->subtype == nt_trunc || expr->subtype == nt_deref || expr->subtype == nt_stack ||
			expr->subtype == nt_quest
		)
		{
			s += "<" + get_node_size_text(expr->size) + ">";
		}
		s += "(";
		for(int i = 0; i < 3; ++i)
		{
			if(expr->u.subexpr[i] == NULL)
				break;
			if(i != 0)
				s += ", ";
			s += expr_to_string(expr->u.subexpr[i]);
		}
		s += ")";
		return s;
	}
	if(expr->type == et_nodeoperand)
	{
		s = strings_no[expr->subtype];
		return s;
	}
	if(expr->type == et_asgn)
	{
		if(expr->u.subexpr[0]->type == et_nodetype && expr->u.subexpr[0]->subtype == nt_tmp)
		{
			// asgn(tmp, value) -- needs size.
			s = get_node_size_text(expr->u.subexpr[0]->size);
			s += " tmp" + int_to_string(expr->u.subexpr[0]->u.subexpr[0]->u.data[0], "%d");
			s += " = ";
			s += expr_to_string(expr->u.subexpr[1]);
			s += ";";
		}
		else
		{
			s = expr_to_string(expr->u.subexpr[0]);
			s += " = ";
			s += expr_to_string(expr->u.subexpr[1]);
			s += ";";
		}
	}
	else
	if(expr->type == et_literal32)
	{
		if(expr->u.data[0] >= 10)
			s += "0x";
		s += int_to_string(expr->u.data[0], "%x");
	}
	else
	if(expr->type == et_reg)
	{
		// subtype is 0 for general register, u.data[0] is argsize_*, u.data[1] is register index number
		if(expr->subtype == 0)
		{
			if(expr->u.data[0] == argsize_8)
				s += std::string("x86_") + reg8[expr->u.data[1]];
			else
			if(expr->u.data[0] == argsize_16)
				s += std::string("x86_") + reg16[expr->u.data[1]];
			else
				s += std::string("x86_") + reg32[expr->u.data[1]];
		}
	}
	else
	if(expr->type == et_reg_reg)
	{
		// subtype is 0 for general register, u.data[0] is argsize_*, u.data[1] is register index number
		if(expr->subtype == 0)
		{
			if(expr->u.data[0] == argsize_8)
				s += std::string("x86_") + reg8[expr->u.data[1]] + ":x86_" + reg8[expr->u.data[2]];
			else
			if(expr->u.data[0] == argsize_16)
				s += std::string("x86_") + reg16[expr->u.data[1]] + ":x86_" + reg16[expr->u.data[2]];
			else
				s += std::string("x86_") + reg32[expr->u.data[1]] + ":x86_" + reg32[expr->u.data[2]];
		}
	}
	else
	if(expr->type == et_ea16 || expr->type == et_ea32 || expr->type == et_ea64)
	{
		if((expr->subtype & 128) == 0)
		{
			// print any seg reg.
			s += std::string("x86_") + sregs[expr->subtype & 7] + "+";
		}
		U1 base = expr->u.data[0] & 31;
		U1 index = (expr->u.data[0] >> 5) & 31;
		U1 scale = (expr->subtype & 0x7f) / 8;
		const char **ptrs;
		if(expr->type == et_ea16)
			ptrs = reg16;
		else
			ptrs = reg32;
		if(base != 31)
			s += std::string("x86_") + ptrs[base];
		if(index != 31)
		{
			if(base != 31)
				s += "+";
			s += std::string("x86_") + ptrs[index];
			if(scale != 0)
				s += std::string("*") + int_to_string(1 << scale, "%d");
		}
		if(expr->u.data[1] != 0 || (index == 31 && base == 31))
		{
			if(index != 31 || base != 31)
				s += "+";
			s += std::string("0x") + int_to_string(expr->u.data[1], "%x");
		}
	}
//	et_ea16,		// subtype is segreg + 8 * index_shift. u.data[0] is base + 32 * index (use 31 for none). data[1] is disp.
//	et_ea32,		// subtype is segreg + 8 * index_shift. u.data[0] is base + 32 * index (use 31 for none). data[1] is disp.
//	et_ea64,		// subtype is segreg + 8 * index_shift. u.data[0] is base + 32 * index (use 31 for none). data[1] is disp.
	return s;
}
void do_test(U8 image_base)
{
	for(std::list<bb_t *>::iterator i = test_list.begin(); i != test_list.end(); ++i)
	{
		bb_t *node = *i;
		
		/*std::cout << std::endl;	
		std::cout << std::hex << (U4)node->address << std::dec << ":" << std::endl;
		std::cout << "out:";
		{
		for(std::vector<bb_t *>::iterator i = node->out_edges.begin(); i != node->out_edges.end(); ++i)
			std::cout << " " << std::hex << (*i)->address << std::dec;
		}
		std::cout << std::endl;
		std::cout << "in:";
		{
		for(std::set<bb_t *>::iterator i = node->in_edges.begin(); i != node->in_edges.end(); ++i)
			std::cout << " " << std::hex << (*i)->address << std::dec;
		}*/
		if(!(*i)->hcode.empty())
			std::cout << "loc_" << std::hex << (U4)(node->address + image_base) << ":" << std::dec << std::endl;

		/*std::cout << std::endl;
		std::cout << "def:" << std::endl;
		node->def.debug();
		std::cout << std::endl;
		std::cout << "live_use:" << std::endl;
		node->live_use.debug();
		std::cout << std::endl;*/
		
		// print opcodes.
		//int line = 0;
		for(std::list<hcode_t>::iterator j = (*i)->hcode.begin(); j != (*i)->hcode.end(); ++j)
		{
			//++line;
			if(j->opcode == ht_expr)
			{
				std::cout << "  " << /*line << ". " <<*/ expr_to_string(*j->operands.begin());
				std::cout << std::endl;
			}
			else
			if(j->opcode == ht_call)
			{
				std::cout << std::hex << "  fn_" << (U4)((*i)->out_edges[1]->address + image_base) << "() then goto " <<
					"fn_" << (U4)((*i)->out_edges[0]->address + image_base) << ";" << std::dec << std::endl;
				;
			}
			else
			if(j->opcode == ht_jump)
			{
				std::cout << std::hex << "  goto loc_" << (U4)((*i)->out_edges[0]->address + image_base) << ";" << std::dec << std::endl;
			}
			else
			if(j->opcode == ht_jcond)
			{
				// jcond--print hll expr here ?
				std::cout << "  if (";
				std::list<expr_t *>::iterator e = j->operands.begin();
				if(j->operands.front() != NULL)
				{
					//std::cout << "cc=" << j->operands.front()->u.data[0];
					std::cout << get_ll_cc_text(j->operands.front()->u.data[0]);
				}
				++e;
				if(*e != NULL)
				{
					if(j->operands.front() != 0)
						std::cout<<" && ";
					if((U1)((*e)->u.data[0]) == (U1)argsize_16)
						std::cout << "cx";
					else
					if((U1)((*e)->u.data[0]) == (U1)argsize_32)
						std::cout << "ecx";
					else
						std::cout << "rcx";
					if((*e)->u.data[0] >= 0x200)
						std::cout << "!=";
					else
						std::cout << "==";
					std::cout << "0";
				}
				std::cout << std::hex << ") goto loc_" << (U4)((*i)->out_edges[1]->address + image_base) << " else goto " <<
					"loc_" << (U4)((*i)->out_edges[0]->address + image_base) << ";" << std::dec << std::endl;
			}
			else
			{
				std::cout << "  " << ht_strings[j->opcode] << " ";
				if(!j->operands.empty())
				{
					std::cout << "(";
					for(std::list<expr_t *>::iterator k = j->operands.begin(); k != j->operands.end(); ++k)
					{
						if(k != j->operands.begin())
							std::cout << ", ";
						if(*k == NULL)
							std::cout << "(Null)";
						else
							std::cout << expr_to_string(*k);
					}
					std::cout << ")";
				}
				std::cout << std::endl;
			}
		}
	}
}

// If you encounter an unhandled instruction, or a locked instruction, clear 'decompile' to false.
void dataflow_t::dataflow(procedure_t &p, parser_call_t &j)
{
	// always try to decompile even if we know it won't work, so we can build
	// the control flow graph properly.
	//if(j.decompile == false)
	//	return;
	//U8 target = p.address;
	
	reparser_t reparser(memory, dsz, p, procs, xgraph);
	bool success = reparser.reparse(p.address);
	
	if(!success || p.root == NULL)
	{
#if 0
		// Don't kill input edges, and don't delete this procedure.
		// Was going to: kill all input edges!
		for(bb_map_t::iterator i = p.map.begin(); i != p.map.end(); ++i)
		{
			bb_t &bb = i->second;
			for(std::vector<bb_t *>::iterator j = bb.out_edges.begin(); j != bb.out_edges.end(); ++j)
			{
				if((*j)->proc != &p)

⌨️ 快捷键说明

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