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

📄 scan.h

📁 当前支持 16-bit, 32-bit and 64-bit 的二进制文件
💻 H
字号:
// scan.h
// Copyright (C) 2008,2009 Willow Schlanger

#ifndef l_scan_h__included
#define l_scan_h__included

#include <vector>
#include <set>
#include <map>
#include <list>

#include "x86s.h"
#include "newcoff.h"
#include "util.h"

// Note to user: if you call a procedure that is simply a jmp indirect, check to
// see if it's a jmp <invokation>. In fact, whenever we find a jmp [indirect] there
// is the possibility it's a jmp <invokation>. Keep that in mind.

namespace ceres
{

// Yet another adaptor. This adapts VmDec 1.0 to QadASm 2.0 (!)
struct scan_target_t
{
	loaded_target_t *target;
	meta_t *meta;
	U1 *bin;
	x86s::icode_t *icode;
};

//---
// ADAPTOR. This ports the old QuickCom code to VmDec's load.h interface.
class module_t
{
	public:
	scan_target_t &lt_int;

	module_t(scan_target_t &lt_int_t) :
		lt_int(lt_int_t)
	{
	}
	
	// Note--the original module_t had special bit set for relocations too.
	// Need to use is_reloc() instead for that purpose.
	U1 is_special(U8 offset)
	{
		return lt_int.meta[offset].named;
	}
	
	// was: image.base
	U8 image_base()
	{
		return lt_int.target->base;
	}
	
	// was: image.bin.size()
	U8 image_size()
	{
		return lt_int.target->size;
	}
	
	std::string get_name(U8 offset)
	{
		std::string s = "";
		if(is_special(offset))
		{
			name_t &nm = lt_int.target->names[offset];
			s = nm.import_name;
			if(s.empty())
				s = nm.export_name;
			if(s.empty())
				s = nm.user_name;
		}
		return s;
	}
	
	U1 get_byte(U8 offset)
	{
		return *(U1 *)(lt_int.bin + offset);
	}
	
	U2 get_word(U8 offset)
	{
		return *(U2 *)(lt_int.bin + offset);
	}
	
	U4 get_dword(U8 offset)
	{
		return *(U4 *)(lt_int.bin + offset);
	}
};
//---

using namespace x86s;

// a real basic block will have a field for # in edges (from same procedure).
struct scanbb_t
{
	U4 offset;					// offset
	U4 stop;					// offset of last insn in block
	std::vector<U4> out_edges;	// offsets
	U4 invokation;				// (U4)(-1) by default. else, it's a procedure entrypoint that is invoked after this.
};

struct scanproc_t
{
	U8 offset;			// offset of the procedure
	union
	{
		struct
		{
			U1 no_decompile : 1;
			
			// This is set by makesig.
			//U1 jmp_import : 1;
		} s;
		U1 v;
	}	u;
	
	// -1 : unknown return depth (default).
	int return_depth;
	bool return_many;	// true of inconsistancies exist here
	
	std::set<std::string> imports;
	std::set<U8> fixed_indirects;	// e.g. call when default target is known
	std::set<U8> calls;				// direct calls (or invokations)
	
	// This is a temporary structure used by makesig.
	//std::set<std::string> wishlist;
	
	scanproc_t()
	{
		u.v = 0;	// this clears no_decompile to 0
		return_depth = -1;
		return_many = false;
	}
	
	std::map<U8, scanbb_t> blocks;
};

struct scanprocs_t
{
	std::map<U8, scanproc_t> procs;

	scanproc_t &proc(U8 offset)
	{
		scanproc_t &p = procs[offset];
		p.offset = offset;
		return p;
	}
};

#if 0
// All of these are memset'd to zero by default.
struct scanmeta_t
{
	U4 length : 4;
	U4 branch : 1;		// =1 if a branch (not call) is here
	U4 exported : 1;
	U4 target : 1;		// =1 if it's already in our list of targets (1st pass)
	U4 procedure : 1;	// =1 if this is a known procedure entrypoint
	
	// If a byte IS A VALID OPCODE and IS PART OF A PROCEDURE with no_decompile,
	// then this is set. This means we might want to include the insn as part of
	// a disassembly. Note--it is possible for no_decompile bytes to overlap with
	// decompilable bytes. no_decompile simply means yes, we want to include the
	// byte in a disassembly. that same byte might be part of a valid procedure
	// that CAN be decompiled. In this case it will be both disassembled and
	// decompiled. Do not AVOID no_decompile bytes when decompiling.
	U4 no_decompile : 1;
};

struct scanobj_t
{
	icode_t icode;
	scanmeta_t meta;
};
#endif

struct scanner_t
{
	bool scan(scan_target_t &target, std::set<U8> &entrypoints, bool dots, scanprocs_t &procs);
	
	private:
	bool target_is_import(module_t &module, U8 offset, decode_state_t &s);
	bool handle_switch(module_t &module, U8 offset, decode_state_t &s, scan_target_t &scanx, std::list<U8> &targets);
	bool handle_switch_zx(module_t &module, U8 offset, decode_state_t &s, scan_target_t &scanx, std::list<U8> &targets);
	U8 icode_list[16];
	UINT icode_size;
	UINT icode_index;
};

}	// namespace ceres

#endif	//l_scan_h__included

⌨️ 快捷键说明

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