update to ida 7.6, add builds
This commit is contained in:
217
idasdk76/plugins/pdb/pdb.hpp
Normal file
217
idasdk76/plugins/pdb/pdb.hpp
Normal file
@@ -0,0 +1,217 @@
|
||||
//
|
||||
// Copyright (c) 2005-2021 Hex-Rays SA <support@hex-rays.com>
|
||||
// ALL RIGHTS RESERVED.
|
||||
//
|
||||
#pragma once
|
||||
#include <idp.hpp>
|
||||
#include <idd.hpp>
|
||||
#include <typeinf.hpp>
|
||||
#include "../../ldr/pe/pe.h"
|
||||
|
||||
#define PDB_NODE_NAME "$ pdb"
|
||||
#define PDB_DLLBASE_NODE_IDX 0
|
||||
#define PDB_DLLNAME_NODE_IDX 0
|
||||
#define PDB_LOADING_WIN32_DBG 1
|
||||
#define PDB_TYPESONLY_NODE_IDX 2
|
||||
|
||||
enum pdb_callcode_t
|
||||
{
|
||||
// user invoked 'load pdb' command, load pdb for the input file.
|
||||
// after invocation, result (boolean) is stored in: netnode(PDB_NODE_NAME).altval(PDB_DLLBASE_NODE_IDX)
|
||||
PDB_CC_USER = 0,
|
||||
// ida decided to call the plugin itself
|
||||
PDB_CC_IDA = 1,
|
||||
// load additional pdb. This is semantically the same as
|
||||
// PDB_CC_USER (i.e., "File > Load file > PDB file..."), except
|
||||
// it won't ask the user for the data; rather it expects it in
|
||||
// netnode(PDB_NODE_NAME):
|
||||
// load_addr: netnode(PDB_NODE_NAME).altval(PDB_DLLBASE_NODE_IDX)
|
||||
// dll_name: netnode(PDB_NODE_NAME).supstr(PDB_DLLNAME_NODE_IDX)
|
||||
PDB_CC_USER_WITH_DATA = 3,
|
||||
// load debug info from the COFF file
|
||||
// ida decided to call the plugin itself
|
||||
// dbginfo_params_t: netnode(DBGINFO_PARAM_NODE_NAME).supval(DBGINFO_PARAMS_KEY)
|
||||
PDB_CC_IDA_COFF = 4,
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
struct pdb_signature_t
|
||||
{
|
||||
uint32 guid[4]; // if all zeroes, then consider as non-existing
|
||||
uint32 sig;
|
||||
uint32 age;
|
||||
pdb_signature_t(void) { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
struct pdbargs_t
|
||||
{
|
||||
qstring pdb_path; // Path to PDB file.
|
||||
qstring input_path; // Path to PE file with associated PDB.
|
||||
pdb_signature_t pdb_sign;
|
||||
qstring spath;
|
||||
ea_t loaded_base;
|
||||
void *user_data;
|
||||
uint32 flags;
|
||||
#define PDBFLG_DBG_MODULE 0x0001
|
||||
#define PDBFLG_ONLY_TYPES 0x0002
|
||||
#define PDBFLG_EFD 0x0004
|
||||
#define PDBFLG_COFF_FILE 0x0008
|
||||
#define PDBFLG_USE_HTTP 0x0100
|
||||
|
||||
pdbargs_t(void)
|
||||
: loaded_base(BADADDR),
|
||||
user_data(NULL),
|
||||
flags(0)
|
||||
{}
|
||||
|
||||
// If true, we are in a debugging session and the file specified by
|
||||
// input_path is an additional module that has been loaded by the
|
||||
// debugger itself.
|
||||
bool is_dbg_module(void) const
|
||||
{
|
||||
return (flags & PDBFLG_DBG_MODULE) != 0;
|
||||
}
|
||||
// PDB?
|
||||
bool is_pdbfile(void) const { return (flags & PDBFLG_COFF_FILE) == 0; }
|
||||
bool use_http() const { return (flags & PDBFLG_USE_HTTP) != 0; }
|
||||
|
||||
const char *fname(void) const
|
||||
{
|
||||
return !pdb_path.empty() ? pdb_path.begin() : input_path.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
struct pdb_ctx_t : public plugmod_t, public event_listener_t
|
||||
{
|
||||
processor_t &ph;
|
||||
|
||||
// PDB search path (in _NT_SYMBOL_PATH format)
|
||||
qstring full_sympath;
|
||||
|
||||
peheader_t pe;
|
||||
|
||||
// config options
|
||||
int pdb_remote_port = DEBUGGER_PORT_NUMBER;
|
||||
int pdb_remote_port_64 = -1;
|
||||
qstring pdb_remote_server;
|
||||
qstring pdb_remote_passwd;
|
||||
#define PDB_PROVIDER_MSDIA 1
|
||||
uint pdb_provider = PDB_PROVIDER_MSDIA;
|
||||
#define PDB_NETWORK_OFF 0 // local directories search only
|
||||
#define PDB_NETWORK_PE 1 // local directories search for COFF, full search for PE
|
||||
#define PDB_NETWORK_ON 2 // no restrictions
|
||||
uint pdb_network = PDB_NETWORK_PE;
|
||||
bool use_http(bool is_pe) const
|
||||
{
|
||||
bool ok = pdb_network == PDB_NETWORK_PE && is_pe
|
||||
|| pdb_network == PDB_NETWORK_ON;
|
||||
deb(IDA_DEBUG_DBGINFO, ok ? "PDB: symbol servers will be used\n"
|
||||
: "PDB: local directories search only\n");
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Plugin options
|
||||
uint opt_provider = 0;
|
||||
// -1 don't specified
|
||||
// 0 set PDB_FALLBACK to false
|
||||
// 1 set PDB_FALLBACK to true
|
||||
int opt_fallback = -1;
|
||||
|
||||
using namelist_t = std::map<ea_t, qstring>;
|
||||
namelist_t namelist;
|
||||
|
||||
// srcinfo provider
|
||||
class pdb_provider_t *pdb_srcinfo_provider = nullptr;
|
||||
|
||||
pdb_ctx_t();
|
||||
virtual ~pdb_ctx_t();
|
||||
virtual bool idaapi run(size_t arg) override;
|
||||
virtual ssize_t idaapi on_event(ssize_t code, va_list va) override;
|
||||
|
||||
void parse_options(bool *opt_skip);
|
||||
|
||||
void init_sympaths();
|
||||
void load_vc_til(void) const;
|
||||
|
||||
// maybe_func: -1:no, 0-maybe, 1-yes, 2:no,but iscode
|
||||
bool apply_name_in_idb(ea_t ea, const qstring &name, int maybe_func, uint32 the_machine_type);
|
||||
bool apply_debug_info(pdbargs_t &pdbargs);
|
||||
|
||||
// printable register name
|
||||
bool get_pdb_register_info(int *p_reg, uint64 *p_mask, int machine, int reg);
|
||||
|
||||
// Because we need to be able to call the 'old' pdb plugin
|
||||
// code, which knows nothing about the til_builder_t (and
|
||||
// thus its 'machine_type' field, and also because, at the
|
||||
// very time we call the old pdb code, our til_builder_t
|
||||
// instance will have been long forgotten and destroyed,
|
||||
// we must keep this machine type information somewhere.
|
||||
uint32 g_machine_type = 0; // will be set to CV_CFL_80386 in ctor
|
||||
|
||||
private:
|
||||
//-------------------------------------------------------------------------
|
||||
int utf16_encidx = -1;
|
||||
int get_utf16_encoding_idx();
|
||||
|
||||
bool checked_types = false;
|
||||
bool has_sid = false;
|
||||
bool check_for_ids(ea_t ea, const char *name, bool has_typeinfo);
|
||||
|
||||
void alloc_pdb_srcinfo_provider();
|
||||
void free_pdb_srcinfo_provider();
|
||||
|
||||
public:
|
||||
//-------------------------------------------------------------------------
|
||||
//#define CHECK_CREATED_TYPES
|
||||
#ifdef CHECK_CREATED_TYPES
|
||||
struct type_to_check_t
|
||||
{
|
||||
// one of the following 3 will be valid:
|
||||
ea_t ea;
|
||||
int id;
|
||||
qstring name;
|
||||
|
||||
// the type itself
|
||||
tinfo_t type;
|
||||
};
|
||||
|
||||
qvector<type_to_check_t> types_to_check;
|
||||
int check_n = 0;
|
||||
|
||||
void check_tinfo(ea_t ea, int id, const char *name, const tinfo_t &tif)
|
||||
{
|
||||
type_to_check_t &tc = types_to_check.push_back();
|
||||
tc.ea = ea;
|
||||
tc.id = id;
|
||||
tc.name = name;
|
||||
tc.type = tif;
|
||||
}
|
||||
|
||||
void check_added_types(void)
|
||||
{
|
||||
for ( const auto &tc : types_to_check )
|
||||
{
|
||||
if ( !tc.type.is_correct() )
|
||||
{
|
||||
msg("%d: INCORRECT TYPE ", check_n);
|
||||
if ( !tc.name.empty() )
|
||||
msg("%s", tc.name.begin());
|
||||
else if ( tc.ea != BADADDR )
|
||||
msg("%a", tc.ea);
|
||||
else
|
||||
msg("#%d", tc.id);
|
||||
qstring res;
|
||||
tc.type.print(&res);
|
||||
msg(": %s\n", res.c_str());
|
||||
check_n++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
inline void check_tinfo(ea_t,int,const char*,const tinfo_t &) {}
|
||||
inline void check_added_types(void) {}
|
||||
#endif
|
||||
};
|
||||
extern int data_id;
|
||||
Reference in New Issue
Block a user