Detect PLT standard expression

This commit is contained in:
Théophile Bastian 2018-07-02 16:22:13 +02:00
parent 4181dd828a
commit f2642a70c9
4 changed files with 102 additions and 0 deletions

View file

@ -1,5 +1,7 @@
#include "DwarfReader.hpp" #include "DwarfReader.hpp"
#include "plt_std_expr.hpp"
#include <fstream> #include <fstream>
#include <fileno.hpp> #include <fileno.hpp>
#include <set> #include <set>
@ -107,6 +109,13 @@ SimpleDwarf::DwRegister DwarfReader::read_register(
output.type = SimpleDwarf::DwRegister::REG_UNDEFINED; output.type = SimpleDwarf::DwRegister::REG_UNDEFINED;
break; 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: default:
output.type = SimpleDwarf::DwRegister::REG_NOT_IMPLEMENTED; output.type = SimpleDwarf::DwRegister::REG_NOT_IMPLEMENTED;
break; break;
@ -139,3 +148,26 @@ SimpleDwarf::MachineRegister DwarfReader::from_dwarfpp_reg(
throw UnsupportedRegister(); 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;
}

View file

@ -34,6 +34,9 @@ class DwarfReader {
int ra_reg=-1 int ra_reg=-1
) const; ) const;
bool is_plt_expr(
const dwarf::core::FrameSection::register_def& reg) const;
class UnsupportedRegister: public std::exception {}; class UnsupportedRegister: public std::exception {};
private: private:

View file

@ -32,6 +32,10 @@ struct SimpleDwarf {
defined at some later IP in the same DIE) */ defined at some later IP in the same DIE) */
REG_REGISTER, ///< Value of a machine register plus offset REG_REGISTER, ///< Value of a machine register plus offset
REG_CFA_OFFSET, ///< Value stored at some offset from CFA 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 REG_NOT_IMPLEMENTED ///< This type of register is not supported
}; };

63
src/plt_std_expr.hpp Normal file
View 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
}
}
});