Detect PLT standard expression
This commit is contained in:
parent
4181dd828a
commit
f2642a70c9
4 changed files with 102 additions and 0 deletions
|
@ -1,5 +1,7 @@
|
|||
#include "DwarfReader.hpp"
|
||||
|
||||
#include "plt_std_expr.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <fileno.hpp>
|
||||
#include <set>
|
||||
|
@ -107,6 +109,13 @@ SimpleDwarf::DwRegister DwarfReader::read_register(
|
|||
output.type = SimpleDwarf::DwRegister::REG_UNDEFINED;
|
||||
break;
|
||||
|
||||
case core::FrameSection::register_def::SAVED_AT_EXPR:
|
||||
if(is_plt_expr(reg))
|
||||
output.type = SimpleDwarf::DwRegister::REG_PLT_EXPR;
|
||||
else
|
||||
output.type = SimpleDwarf::DwRegister::REG_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
default:
|
||||
output.type = SimpleDwarf::DwRegister::REG_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
@ -139,3 +148,26 @@ SimpleDwarf::MachineRegister DwarfReader::from_dwarfpp_reg(
|
|||
throw UnsupportedRegister();
|
||||
}
|
||||
}
|
||||
|
||||
static bool compare_dw_expr(
|
||||
const encap::loc_expr& e1,
|
||||
const encap::loc_expr& e2)
|
||||
{
|
||||
const std::vector<encap::expr_instr>& e1_vec =
|
||||
static_cast<const vector<encap::expr_instr>&>(e1);
|
||||
const std::vector<encap::expr_instr>& e2_vec =
|
||||
static_cast<const vector<encap::expr_instr>&>(e2);
|
||||
|
||||
return e1_vec == e2_vec;
|
||||
}
|
||||
|
||||
bool DwarfReader::is_plt_expr(
|
||||
const core::FrameSection::register_def& reg) const
|
||||
{
|
||||
if(reg.k != core::FrameSection::register_def::SAVED_AT_EXPR)
|
||||
return false;
|
||||
const encap::loc_expr& expr = reg.saved_at_expr_r();
|
||||
|
||||
bool res = compare_dw_expr(expr, REFERENCE_PLT_EXPR);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,9 @@ class DwarfReader {
|
|||
int ra_reg=-1
|
||||
) const;
|
||||
|
||||
bool is_plt_expr(
|
||||
const dwarf::core::FrameSection::register_def& reg) const;
|
||||
|
||||
class UnsupportedRegister: public std::exception {};
|
||||
|
||||
private:
|
||||
|
|
|
@ -32,6 +32,10 @@ struct SimpleDwarf {
|
|||
defined at some later IP in the same DIE) */
|
||||
REG_REGISTER, ///< Value of a machine register plus offset
|
||||
REG_CFA_OFFSET, ///< Value stored at some offset from CFA
|
||||
REG_PLT_EXPR, /**< Value is the evaluation of the standard PLT
|
||||
expression, ie `((rip & 15) >= 11) >> 3 + rsp`
|
||||
This is hardcoded because it's the only expression
|
||||
found so far, thus worth implementing. */
|
||||
REG_NOT_IMPLEMENTED ///< This type of register is not supported
|
||||
};
|
||||
|
||||
|
|
63
src/plt_std_expr.hpp
Normal file
63
src/plt_std_expr.hpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
#pragma once
|
||||
|
||||
#include <dwarfpp/expr.hpp>
|
||||
|
||||
static const dwarf::encap::loc_expr REFERENCE_PLT_EXPR(
|
||||
std::vector<dwarf::encap::expr_instr> {
|
||||
{
|
||||
{
|
||||
.lr_atom = 0x77,
|
||||
.lr_number = 8,
|
||||
.lr_number2 = 0,
|
||||
.lr_offset = 0
|
||||
},
|
||||
{
|
||||
.lr_atom = 0x80,
|
||||
.lr_number = 0,
|
||||
.lr_number2 = 0,
|
||||
.lr_offset = 2
|
||||
},
|
||||
{
|
||||
.lr_atom = 0x3f,
|
||||
.lr_number = 15,
|
||||
.lr_number2 = 0,
|
||||
.lr_offset = 4
|
||||
},
|
||||
{
|
||||
.lr_atom = 0x1a,
|
||||
.lr_number = 0,
|
||||
.lr_number2 = 0,
|
||||
.lr_offset = 5
|
||||
},
|
||||
{
|
||||
.lr_atom = 0x3b,
|
||||
.lr_number = 11,
|
||||
.lr_number2 = 0,
|
||||
.lr_offset = 6
|
||||
},
|
||||
{
|
||||
.lr_atom = 0x2a,
|
||||
.lr_number = 0,
|
||||
.lr_number2 = 0,
|
||||
.lr_offset = 7
|
||||
},
|
||||
{
|
||||
.lr_atom = 0x33,
|
||||
.lr_number = 3,
|
||||
.lr_number2 = 0,
|
||||
.lr_offset = 8
|
||||
},
|
||||
{
|
||||
.lr_atom = 0x24,
|
||||
.lr_number = 0,
|
||||
.lr_number2 = 0,
|
||||
.lr_offset = 9
|
||||
},
|
||||
{
|
||||
.lr_atom = 0x22,
|
||||
.lr_number = 0,
|
||||
.lr_number2 = 0,
|
||||
.lr_offset = 10
|
||||
}
|
||||
}
|
||||
});
|
Loading…
Reference in a new issue