From f2642a70c9c3434ab4785af7fcc9723fa199a9e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Bastian?= Date: Mon, 2 Jul 2018 16:22:13 +0200 Subject: [PATCH] Detect PLT standard expression --- src/DwarfReader.cpp | 32 ++++++++++++++++++++++ src/DwarfReader.hpp | 3 +++ src/SimpleDwarf.hpp | 4 +++ src/plt_std_expr.hpp | 63 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+) create mode 100644 src/plt_std_expr.hpp diff --git a/src/DwarfReader.cpp b/src/DwarfReader.cpp index 76cde53..eef4809 100644 --- a/src/DwarfReader.cpp +++ b/src/DwarfReader.cpp @@ -1,5 +1,7 @@ #include "DwarfReader.hpp" +#include "plt_std_expr.hpp" + #include #include #include @@ -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& e1_vec = + static_cast&>(e1); + const std::vector& e2_vec = + static_cast&>(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; +} diff --git a/src/DwarfReader.hpp b/src/DwarfReader.hpp index 034d055..2d0f5ee 100644 --- a/src/DwarfReader.hpp +++ b/src/DwarfReader.hpp @@ -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: diff --git a/src/SimpleDwarf.hpp b/src/SimpleDwarf.hpp index 8d69c12..6be3ea9 100644 --- a/src/SimpleDwarf.hpp +++ b/src/SimpleDwarf.hpp @@ -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 }; diff --git a/src/plt_std_expr.hpp b/src/plt_std_expr.hpp new file mode 100644 index 0000000..ec8c690 --- /dev/null +++ b/src/plt_std_expr.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include + +static const dwarf::encap::loc_expr REFERENCE_PLT_EXPR( + std::vector { + { + { + .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 + } + } + });