diff --git a/include/interfaces/abstract/STARSInterface.h b/include/interfaces/abstract/STARSInterface.h index a474338c10d5d988618630640939c397e4f45630..77e6ad9c1ee5487fc5c553b470236009cfd64a36 100644 --- a/include/interfaces/abstract/STARSInterface.h +++ b/include/interfaces/abstract/STARSInterface.h @@ -85,6 +85,8 @@ class STARS_Interface_t virtual void AuditCodeTargets(void) = 0; // Detect IDA Pro func boundary problems, if code segment range; true if problems found virtual bool AuditFunctionBoundaries(const STARS_ea_t startEA, const STARS_ea_t endEA) const = 0; + // Detect IDA Pro func boundary problems using EH_FRAME FDE info; true if problems found + virtual bool AuditEHFunctionBoundaries(void) const = 0; virtual bool STARS_patch_byte(STARS_ea_t InstAddr, uint32_t ByteValue) = 0; // Patch IDA Pro database. diff --git a/include/interfaces/abstract/STARSSegment.h b/include/interfaces/abstract/STARSSegment.h index ef4932435fe820ddaa55e7659766bb3c7f308646..3b72cc1b591d1581cd6558ac4a1aaea34a00a335 100644 --- a/include/interfaces/abstract/STARSSegment.h +++ b/include/interfaces/abstract/STARSSegment.h @@ -23,7 +23,7 @@ class STARS_Segment_t virtual bool IsReadableSegment() const = 0; virtual bool IsWriteableSegment() const = 0; - /* returns the segments name in the given buffer*/ + /* returns the segment's name in the given buffer */ virtual STARS_ssize_t GetSegmentName(char* name, int len) = 0; // Fetch read-only data values, if any. @@ -33,7 +33,6 @@ class STARS_Segment_t virtual bool GetReadOnlyMem8BitValue(STARS_ea_t MemAddr, uint8_t &Value) const = 0; virtual void Dump() { } - }; #endif diff --git a/include/interfaces/idapro/STARSInterface.h b/include/interfaces/idapro/STARSInterface.h index b19556ac404bc0863ae46c11e80b60ec1e153cb5..a8d8df2d415125ce15285b9133fc40b2bbefb842 100644 --- a/include/interfaces/idapro/STARSInterface.h +++ b/include/interfaces/idapro/STARSInterface.h @@ -138,6 +138,8 @@ public: // Detect IDA Pro func boundary problems, if code segment range; true if problems found virtual bool AuditFunctionBoundaries(const STARS_ea_t startEA, const STARS_ea_t endEA) const; + // Detect IDA Pro func boundary problems using EH_FRAME FDE info; true if problems found + virtual bool AuditEHFunctionBoundaries(void) const; virtual bool STARS_patch_byte(STARS_ea_t InstAddr, uint32_t ByteValue); // Patch IDA Pro database. diff --git a/include/interfaces/idapro/STARSSegment.h b/include/interfaces/idapro/STARSSegment.h index a272a3cadaa034e9cc1580c44948e90e5251228e..7e325700fdc7722fc8ab652b40e1712ec8ba78da 100644 --- a/include/interfaces/idapro/STARSSegment.h +++ b/include/interfaces/idapro/STARSSegment.h @@ -66,7 +66,6 @@ class STARS_IDA_Segment_t : public STARS_Segment_t return true; } - private: segment_t* the_seg; diff --git a/include/interfaces/irdb/STARSInterface.h b/include/interfaces/irdb/STARSInterface.h index 3faf46bda2e6322838155cb04ee45fbce1bb9e09..e3e1966bb4a361112e3718fda87609121f455cdf 100644 --- a/include/interfaces/irdb/STARSInterface.h +++ b/include/interfaces/irdb/STARSInterface.h @@ -30,8 +30,8 @@ public: InitFunctions(); // init instruction predecessors. instruction_preds.AddFile(p_firp); - // init IBT provenance info - IBT_provs.AddFile(p_firp); + // init IBT provenance info + IBT_provs.AddFile(p_firp); InitIBTAMaps(); } @@ -195,6 +195,8 @@ public: { assert(0); return; /* shouldn't be called. */ } // Detect IDA Pro func boundary problems, if code segment; true if problems found virtual bool AuditFunctionBoundaries(const STARS_ea_t startEA, const STARS_ea_t endEA) const { return false; }; + // Detect IDA Pro func boundary problems using EH_FRAME FDE info; true if problems found + virtual bool AuditEHFunctionBoundaries(void) const { return false; }; // Patch IDA Pro database. virtual bool STARS_patch_byte(STARS_ea_t InstAddr, uint32_t ByteValue) @@ -312,7 +314,7 @@ private: libIRDB::pqxxDB_t &pqxx_interface; libIRDB::InstructionPredecessors_t instruction_preds; - libIRDB::IBTProvenance_t IBT_provs; + libIRDB::IBTProvenance_t IBT_provs; friend class STARS_IRDB_Function_t; }; diff --git a/include/interfaces/irdb/STARSSegment.h b/include/interfaces/irdb/STARSSegment.h index 0f1b6cabaa794cf43930730c9d44f7be74e05092..da1ea9fe1b53839572b48125f3642d437b551360 100644 --- a/include/interfaces/irdb/STARSSegment.h +++ b/include/interfaces/irdb/STARSSegment.h @@ -66,7 +66,6 @@ class STARS_IRDB_Segment_t : public STARS_Segment_t virtual bool GetReadOnlyMem16BitValue(STARS_ea_t MemAddr, uint16_t &Value) const; virtual bool GetReadOnlyMem8BitValue(STARS_ea_t MemAddr, uint8_t &Value) const; - private: ELFIO::section* the_seg; int segno; diff --git a/src/base/SMPProgram.cpp b/src/base/SMPProgram.cpp index 74faa6dd3f949d30b9dc191980813eefcc69beeb..0d55d3f3f2b4f399d01687d3bea8453a9b977b87 100644 --- a/src/base/SMPProgram.cpp +++ b/src/base/SMPProgram.cpp @@ -324,6 +324,11 @@ void SMPProgram::Analyze(ProfilerInformation *pi, FILE *AnnotFile, FILE *InfoAnn } // end for all segments // #endif // STARS_IDA_INTERFACE + bool FuncBoundProblems2 = global_stars_interface->AuditEHFunctionBoundaries(); + if (FuncBoundProblems2) { + SMP_msg("SERIOUS WARNING: Function boundary problems detected using EH_FRAME FDEs.\n"); + } + size_t NumFuncs = SMP_get_func_qty(); #if SMP_DEBUG SMP_msg("INFO: Number of functions: %zu Total Code Size: %llu\n", NumFuncs, STARS_TotalCodeSize); diff --git a/src/interfaces/idapro/STARSInterface.cpp b/src/interfaces/idapro/STARSInterface.cpp index 81ec89d9158446b8f884e60f0874e42356b6bf32..fc6a60f739508d29a764d8fc2ebef852e2844a00 100644 --- a/src/interfaces/idapro/STARSInterface.cpp +++ b/src/interfaces/idapro/STARSInterface.cpp @@ -9,6 +9,11 @@ #include "base/SMPFunction.h" #include "base/SMPProgram.h" +#define STARS_USE_EHP_LIB 0 +#if STARS_USE_EHP_LIB +#include <ehp.hpp> // security_transforms/libehp/include/ehp.hpp +#endif + #if 0 #include <pro.h> #include <fpro.h> @@ -28,7 +33,9 @@ #pragma GCC diagnostic pop using namespace std; - +#if STARS_USE_EHP_LIB +using namespace EHP; +#endif int STARS_IDA_Interface_t::STARS_fprintf(FILE *fp, const char *format, ...) { va_list va; va_start(va, format); @@ -388,7 +395,7 @@ void STARS_IDA_Interface_t::AuditCodeTargets(void) bool STARS_IDA_Interface_t::AuditFunctionBoundaries(const STARS_ea_t startEA, const STARS_ea_t endEA) const { bool ProblemFound = false; - // Use the tryblks.hpp interface from IDA Pro to parse the EH_FRAME + // First, use the tryblks.hpp interface from IDA Pro to parse the EH_FRAME // section in the ELF binary, or equivalent section in other binaries. // // Algorithm: @@ -410,9 +417,10 @@ bool STARS_IDA_Interface_t::AuditFunctionBoundaries(const STARS_ea_t startEA, co if (CurrTryBlk.is_cpp()) { // C++ try/catch type // Step 3. - for (std::size_t TryIndex = 0; TryIndex < CurrTryBlk.size(); ++TryIndex) { - range_t CurrTryBlk2 = CurrTryBlk.at(TryIndex); - for (std::size_t TryIndex2 = 0; TryIndex2 < CurrTryBlk2.size(); ++TryIndex2) { + for (std::size_t TryIndex2 = 0; TryIndex2 < CurrTryBlk.size(); ++TryIndex2) { + range_t CurrTryBlk2 = CurrTryBlk.at(TryIndex2); + // !!!!****!!!! TryIndex3 not used; review data structures + for (std::size_t TryIndex3 = 0; TryIndex3 < CurrTryBlk2.size(); ++TryIndex3) { STARS_ea_t CurrStartEA = CurrTryBlk2.start_ea; STARS_ea_t CurrEndEA = CurrTryBlk2.end_ea; @@ -430,16 +438,46 @@ bool STARS_IDA_Interface_t::AuditFunctionBoundaries(const STARS_ea_t startEA, co SMP_msg("ERROR: FUNCBOUNDS: Try block from %llx to %llx spans functions\n", (uint64_t) CurrStartEA, (uint64_t) (CurrEndEA - 1)); } - } - } + } // end for TryIndex3 + } // end for TryIndex2 } - } + } // end for TryIndex delete TryBlockVec; return ProblemFound; } // end of STARS_IDA_Interface_t::AuditFunctionBoundaries() +// Detect IDA Pro func boundary problems using EH_FRAME FDE info; true if problems found +bool STARS_IDA_Interface_t::AuditEHFunctionBoundaries(void) const { + bool ProblemFound = false; +#if STARS_USE_EHP_LIB + // Use the FDEs (Frame Descriptor Entries) from the eh_frame section + // to perform the same algorithm as above: an FDE should contain only one func. + const auto & EHParser = EHFrameParser_t::factory(global_STARS_program->GetRootFileName()); + for (auto &FDEvecptr : EHParser->getFDEs()) { + for (auto &FDEveciter = FDEvecptr->begin(); FDEveciter != FDEvecptr->end(); ++FDEveciter) { + uint64_t startAddr = (*FDEveciter)->getStartAddress(); + uint64_t endAddr = (*FDEveciter)->getEndAddress(); + + // See if start and end of FDE landing pad are in the same func. + STARS_ea_t CurrStartEA = (STARS_ea_t) startAddr; + STARS_ea_t CurrEndEA = (STARS_ea_t) endAddr; + STARS_Function_t *StartFunc = SMP_get_func(CurrStartEA); + STARS_Function_t *EndFunc = SMP_get_func(CurrEndEA - 1); + + if (StartFunc != EndFunc) { + ProblemFound = true; + SMP_msg("ERROR: FUNCBOUNDS: FDE range from %llx to %llx spans functions\n", + (uint64_t) CurrStartEA, (uint64_t) (CurrEndEA - 1)); + } + } + } +#endif + + return ProblemFound; +} // end of STARS_IDA_Interface_t::AuditEHFunctionBoundaries() + // Patch IDA Pro database. bool STARS_IDA_Interface_t::STARS_patch_byte(STARS_ea_t InstAddr, uint32_t ByteValue) { return patch_byte(InstAddr, ByteValue);