📄 scan.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 <_int;
module_t(scan_target_t <_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 + -