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

📄 reparse.h

📁 当前支持 16-bit, 32-bit and 64-bit 的二进制文件
💻 H
📖 第 1 页 / 共 2 页
字号:
// reparse.h
// Copyright (C) 2008 Willow Schlanger

bool reparser_t::reparse(U8 target)
{
	U8 mytarget = target;
	std::set<U8> locals;
	locals.insert(target);
	
	int x;
	decode_state_t s;
	s.dsz = dsz;
	
	U8 bytesleft, offset, tmp;
	
	specialized_tcode_t sp;
	expr_t *expr[X86S_SEMANTICS_MAX_SIZE];
	U4 expr_count;
	
	icode_t icode_table[ICODE_PEEP_SIZE];
	UINT icode_start, icode_size;
	
	bool is_start = true;
	bb_t *curbb;
	
	curbb = &(proc.map[target]);
	proc.root = curbb;
	curbb->address = target;
	curbb->proc = &proc;
	
	bool no_decompile = false;
	
	// now parse this procedure.
	while(!locals.empty())
	{
		target = *locals.begin();
		locals.erase(locals.begin());
		
		//printf("Now parsing locals starting at %08x\n", (U4)target);
//std::cout << "+" << std::hex << (U4)target << std::endl;
		
		icode_start = ICODE_PEEP_SIZE - 1;
		icode_size = 0;
		
		if(proc.map.find(target) == proc.map.end())
		{
			throw std::runtime_error("Basic block not found.");
		}
		curbb = &(proc.map[target]);
		
		sp.clear();	// clear temporaries (for now)...

again:
//std::cout << " " << std::hex << (U4)target << std::endl;

		if(memory.meta[target].local == 1)
		{
			// already been here - part of current procedure.
			// --- do we need to do anything special here?
			continue;
		}
		
		if(!is_start)
		{
			if(memory.meta[target].entry == 1)
			{
				// proc -> INVOKEs target. put in a synthetic jmp.
				//printf("%08x - calls %08x [+]\n", (U4)myproc, (U4)target);

				tmp = target;
				if(memory.meta[tmp].entry == 0 || procs.find(tmp) == procs.end() || procs[tmp].root == NULL)
				{
					//throw std::runtime_error("Invokation to unknown procedure (1)");
					continue;
				}

				if(memory.meta[tmp].decompiled == 0 && tmp != mytarget)
					no_decompile = true;
				if(!no_decompile)
				{
					// *** add synthetic jump hcode here.
					curbb->hcode.push_back(hcode_t());
					curbb->hcode.back().opcode = ht_jump;
					// fixme--add any arguments here.				
				}

				bb_t &bb2 = *procs[tmp].root;
				//bb2.address = tmp;
				//bb2.proc = &proc;
				//locals.insert(tmp);
				bb2.in_edges.insert(curbb);
				curbb->out_edges.push_back(&bb2);

#if 0
				bb_t &bb = &procs[target];
				bb.address = target;
				bb.proc = &proc;
				bb.in_edges.insert(curbb);
				curbb->out_edges.push_back(&bb);
#endif
				continue;
			}
		}
		is_start = false;
		
		if(memory.meta[target].branch == 1 && target != curbb->address)
		{
			curbb->hcode.push_back(hcode_t());
			curbb->hcode.back().opcode = ht_jump;
			//if()
			{
				bb_t &bb = proc.map[target];
				bb.address = target;
				bb.proc = &proc;
				bb.in_edges.insert(curbb);
				curbb->out_edges.push_back(&bb);
				curbb = &bb;
			}
		}

		s.insn = memory.image + target;
		icode_start = (icode_start + 1) & (ICODE_PEEP_SIZE - 1);
		s.icode = icode_table + icode_start;
		if(icode_size < ICODE_PEEP_SIZE)
			++icode_size;
		
		bytesleft = memory.image_size - target;
		if(bytesleft > 15)
			bytesleft = 15;
		s.end = s.insn + bytesleft;
		
		x = decode(s);
		
		if(x != 0)
		{
			no_decompile = true;
			break;
		}
		
		if(memory.meta[target].entry == 0)
			memory.meta[target].local = 1;

		// look at insn here.
		// look at instruciton here.
		switch(encodings[s.encoding].insn)
		{
			case insn__ret:
			case insn__retf:
			case insn__retfnum:
			case insn__retnum:
			case insn__iret:
				// I don't want to specify out edges for returns...
				// fixme--add expression to return.
				if(!no_decompile)
				{
					curbb->hcode.push_back(hcode_t());
					curbb->hcode.back().opcode = ht_ret;
					// fixme--add ANY arguments here.
				}
				continue;
			case insn_jmp:
				{
				icode_start = ICODE_PEEP_SIZE - 1;
				icode_size = 0;
				// fixme: add 64-bit support here. Also do something about memory.cs_base.
				offset = (U8)s.icode->imm + (U8)target + (U8)s.size + (U8)memory.image_base;
				offset &= memory.rip_mask;
				if(offset < (U8)memory.image_base)
					throw std::runtime_error("jmp above image base");
				target = offset - (U8)memory.image_base;
				//memory.meta[target].branch = 1;
				s.insn = memory.image + target;
				//printf("jmp to %08x\n", offset);
				
				if(memory.meta[target].entry == 1)
				{
					if(memory.meta[target].decompiled == 0)
						no_decompile = true;
				}
				if(!no_decompile)
				{
					curbb->hcode.push_back(hcode_t());
					curbb->hcode.back().opcode = ht_jump;
					// fixme--add ANY arguments here.
				}
				
				bb_t &bb = proc.map[target];
				bb.address = target;
				bb.proc = &proc;
				bb.in_edges.insert(curbb);
				curbb->out_edges.push_back(&bb);
				curbb = &bb;
				goto again;
				}
			case insn_call:
				{
				//icode_start = ICODE_PEEP_SIZE - 1;
				//icode_size = 0;
				// fixme: add 64-bit support here. Also do something about memory.cs_base.
				offset = (U8)target + (U8)s.size + (U8)memory.image_base;
				offset &= memory.rip_mask;
				tmp = offset - (U8)memory.image_base;
				
				if(s.icode->imm != 0)
				{
					bb_t &bb = proc.map[tmp];
					bb.address = tmp;
					bb.proc = &proc;
					bb.in_edges.insert(curbb);
					curbb->out_edges.push_back(&bb);
					if(memory.meta[tmp].entry == 0)
						locals.insert(tmp);
				}

				offset = (U8)s.icode->imm + (U8)target + (U8)s.size + (U8)memory.image_base;
				offset &= memory.rip_mask;
				tmp = offset - (U8)memory.image_base;

				if(tmp != mytarget)	// bugfix
				if(memory.meta[tmp].entry == 0 || procs.find(tmp) == procs.end() || procs[tmp].root == NULL)
				{
					no_decompile = true;
					continue;
					//throw std::runtime_error("Invokation to unknown procedure (2)");
				}

				if(memory.meta[tmp].decompiled == 0 && tmp != mytarget)
					no_decompile = true;
				if(!no_decompile)
				{
					curbb->hcode.push_back(hcode_t());
					curbb->hcode.back().opcode = ht_call;
					curbb->hcode.back().operands.push_back(NULL);	// direct call.
					curbb->hcode.back().operands.push_back(NULL);	// this is arguments - we use 'void' for now
					// fixme--add arguments here.					
				}

				bb_t &bb2 = *procs[tmp].root;
				//bb2.address = tmp;
				//bb2.proc = &proc;
				//locals.insert(tmp);
				bb2.in_edges.insert(curbb);
				curbb->out_edges.push_back(&bb2);
				
				continue;
				}
			case insn__jcc:
			case insn__jrcxz:
			case insn__loopnz:
			case insn__loopz:
			case insn__loop:
				{
				//icode_start = ICODE_PEEP_SIZE - 1;
				//icode_size = 0;
				// fixme: add 64-bit support here. Also do something about memory.cs_base.
				offset = (U8)target + (U8)s.size + (U8)memory.image_base;
				offset &= memory.rip_mask;
				tmp = offset - (U8)memory.image_base;
				
				curbb->hcode.push_back(hcode_t());
				curbb->hcode.back().opcode = ht_jcond;
				
				// *** first argument is condition code value, 0..15.
				// *** second argument is NULL, or is argsize_16/argsize_32/argsize_64 for cx/ecx/rcx
				// *** 3nd argument is hll expression.
				// *** any of these 3 args may be NULL.
				switch(encodings[s.encoding].insn)
				{
					case insn__jcc:
						curbb->hcode.back().operands.push_back(new expr_t());
						curbb->hcode.back().operands.back()->make_literal32(s.icode->argvalue[1]);
						curbb->hcode.back().operands.push_back(NULL);
						break;
					case insn__jrcxz:
						curbb->hcode.back().operands.push_back(NULL);
						curbb->hcode.back().operands.push_back(new expr_t());
						curbb->hcode.back().operands.back()->make_literal32(s.icode->asz + 0x100);
						break;
					case insn__loopnz:
						curbb->hcode.back().operands.push_back(new expr_t());
						curbb->hcode.back().operands.back()->make_literal32(5);
						curbb->hcode.back().operands.push_back(new expr_t());
						curbb->hcode.back().operands.back()->make_literal32(s.icode->asz + 0x300);
						break;
					case insn__loopz:

⌨️ 快捷键说明

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