diff --git a/include/interfaces/abstract/STARSSegment.h b/include/interfaces/abstract/STARSSegment.h index 8d9313791d0d6c695cffc1681431c35bdcecd5cd..92798587a8a76a5b8683e48e79f30f1108104b2d 100644 --- a/include/interfaces/abstract/STARSSegment.h +++ b/include/interfaces/abstract/STARSSegment.h @@ -12,20 +12,25 @@ class STARS_Segment_t virtual std::size_t get_seg_size() = 0; /* figure out what kind of segment this is */ - virtual bool IsCodeSegment() = 0; - virtual bool IsXternSegment() { return false; }; - virtual bool IsDataSegment() = 0; - virtual bool IsCommonSegment() = 0; - virtual bool IsBSSSegment() = 0; + virtual bool IsCodeSegment() const = 0; + virtual bool IsXternSegment() const { return false; }; + virtual bool IsDataSegment() const = 0; + virtual bool IsCommonSegment() const = 0; + virtual bool IsBSSSegment() const = 0; /* examine segment permissions */ - virtual bool IsReadableSegment() = 0; - virtual bool IsWriteableSegment() = 0; + virtual bool IsReadableSegment() const = 0; + virtual bool IsWriteableSegment() const = 0; /* returns the segments name in the given buffer*/ virtual STARS_ssize_t GetSegmentName(char* name, int len) = 0; - + // Fetch read-only data values, if any. + virtual bool GetReadOnlyMem64BitValue(STARS_ea_t MemAddr, uint64_t &Value) const = 0; + virtual bool GetReadOnlyMem32BitValue(STARS_ea_t MemAddr, uint32_t &Value) const = 0; + virtual bool GetReadOnlyMem16BitValue(STARS_ea_t MemAddr, uint16_t &Value) const = 0; + virtual bool GetReadOnlyMem8BitValue(STARS_ea_t MemAddr, uint8_t &Value) const = 0; + }; #endif diff --git a/include/interfaces/idapro/STARSSegment.h b/include/interfaces/idapro/STARSSegment.h index 444cf541f132db83af225930300fc28b5fe8c313..cc0154e40a78e0de06cb6a9b0138adac3d7e28b2 100644 --- a/include/interfaces/idapro/STARSSegment.h +++ b/include/interfaces/idapro/STARSSegment.h @@ -11,18 +11,41 @@ class STARS_IDA_Segment_t : public STARS_Segment_t public: STARS_IDA_Segment_t(segment_t* seg) : the_seg(seg) {} - virtual STARS_ea_t get_startEA() { return the_seg->startEA; } - virtual STARS_ea_t get_endEA() { return the_seg->endEA; } - virtual std::size_t get_seg_size() { return (std::size_t)(get_endEA() - get_startEA()); } - virtual bool IsCodeSegment() { return the_seg->type == SEG_CODE; } - virtual bool IsXternSegment() { return the_seg->type==SEG_XTRN; } - virtual bool IsDataSegment() { return the_seg->type==SEG_DATA; } - virtual bool IsCommonSegment() { return the_seg->type==SEG_COMM; } - virtual bool IsBSSSegment() { return the_seg->type==SEG_BSS; } - virtual bool IsReadableSegment() { return the_seg->perm & SEGPERM_READ; } - virtual bool IsWriteableSegment() { return the_seg->perm & SEGPERM_WRITE; } + virtual STARS_ea_t get_startEA() { return the_seg->startEA; } + virtual STARS_ea_t get_endEA() { return the_seg->endEA; } + virtual std::size_t get_seg_size() { return (std::size_t)(get_endEA() - get_startEA()); } + virtual bool IsCodeSegment() const { return the_seg->type == SEG_CODE; } + virtual bool IsXternSegment() const { return the_seg->type == SEG_XTRN; } + virtual bool IsDataSegment() const { return the_seg->type == SEG_DATA; } + virtual bool IsCommonSegment() const { return the_seg->type == SEG_COMM; } + virtual bool IsBSSSegment() const { return the_seg->type == SEG_BSS; } + virtual bool IsReadableSegment() const { return the_seg->perm & SEGPERM_READ; } + virtual bool IsWriteableSegment() const { return the_seg->perm & SEGPERM_WRITE; } virtual STARS_ssize_t GetSegmentName(char* name, int len) { return ::get_segm_name(the_seg,name,len); } + // Fetch read-only data values, if any. + virtual bool GetReadOnlyMem64BitValue(STARS_ea_t MemAddr, uint64_t &Value) const { + assert(!IsWriteableSegment()); + Value = (uint64_t) get_qword(MemAddr); + return true; + } + virtual bool GetReadOnlyMem32BitValue(STARS_ea_t MemAddr, uint32_t &Value) const { + assert(!IsWriteableSegment()); + Value = (uint32_t) get_long(MemAddr); + return true; + } + virtual bool GetReadOnlyMem16BitValue(STARS_ea_t MemAddr, uint16_t &Value) const { + assert(!IsWriteableSegment()); + Value = (uint16_t) get_word(MemAddr); + return true; + } + virtual bool GetReadOnlyMem8BitValue(STARS_ea_t MemAddr, uint8_t &Value) const { + assert(!IsWriteableSegment()); + Value = (uint8_t) get_byte(MemAddr); + return true; + } + + private: segment_t* the_seg; diff --git a/include/interfaces/irdb/STARSSegment.h b/include/interfaces/irdb/STARSSegment.h index 238ecfbd88f3bf76f6c6a68ac1be4da2e17cda6b..c86c23712a4e2ba417d0ccfd50c88898f78043d5 100644 --- a/include/interfaces/irdb/STARSSegment.h +++ b/include/interfaces/irdb/STARSSegment.h @@ -27,19 +27,19 @@ class STARS_IRDB_Segment_t : public STARS_Segment_t virtual std::size_t get_seg_size() { return (std::size_t) the_seg->get_size(); } // return if the EXE bit is set. - virtual bool IsCodeSegment() + virtual bool IsCodeSegment() const { return (the_seg->get_flags() & SHF_EXECINSTR) == SHF_EXECINSTR; } - virtual bool IsDataSegment() + virtual bool IsDataSegment() const { return IsReadableSegment() && IsWriteableSegment(); } - virtual bool IsBSSSegment() + virtual bool IsBSSSegment() const { return (the_seg->get_type() & SHT_NOBITS) == SHT_NOBITS; } - virtual bool IsReadableSegment() + virtual bool IsReadableSegment() const { return (the_seg->get_flags() & SHF_ALLOC) == SHF_ALLOC; } - virtual bool IsWriteableSegment() + virtual bool IsWriteableSegment() const { return (the_seg->get_flags() & SHF_WRITE) == SHF_WRITE; } virtual STARS_ssize_t GetSegmentName(char* name, int len) @@ -52,8 +52,15 @@ class STARS_IRDB_Segment_t : public STARS_Segment_t virtual int GetSegmentNumber() { return segno; } // these aren't used, impl. later if we know what it means. - virtual bool IsXternSegment() { assert(0); /* leave as error */} - virtual bool IsCommonSegment() { assert(0); /* leave as error */} + virtual bool IsXternSegment() const { assert(0); /* leave as error */ } + virtual bool IsCommonSegment() const { assert(0); /* leave as error */ } + + // Fetch read-only data values, if any. + virtual bool GetReadOnlyMem64BitValue(STARS_ea_t MemAddr, uint64_t &Value) const = 0; + virtual bool GetReadOnlyMem32BitValue(STARS_ea_t MemAddr, uint32_t &Value) const = 0; + virtual bool GetReadOnlyMem16BitValue(STARS_ea_t MemAddr, uint16_t &Value) const = 0; + virtual bool GetReadOnlyMem8BitValue(STARS_ea_t MemAddr, uint8_t &Value) const = 0; + private: ELFIO::section* the_seg; diff --git a/src/base/SMPInstr.cpp b/src/base/SMPInstr.cpp index 1d03927c9b7d728ae83857a7502c4f15847e9d0a..6067a3a0abccd8483bf2b6b27803f9f2aee79015 100644 --- a/src/base/SMPInstr.cpp +++ b/src/base/SMPInstr.cpp @@ -7921,6 +7921,69 @@ void SMPInstr::SCCPFetchConstUseValue(const STARSOpndTypePtr &UseOp, STARS_SCCP_ } } } + else if (UseOp->IsStaticMemOp()) { + // Fetch read-only data value, if any. + STARS_ea_t MemAddr = UseOp->GetAddr(); + bool GoodAddr = (STARS_BADADDR != MemAddr); +#if 1 + int BaseReg = (int) UseOp->GetReg(); + if (MD_STACK_POINTER_REG == BaseReg) { + // ESP BaseReg in SIB byte means no base reg for StaticMemOp + BaseReg = STARS_x86_R_none; + } + if (UseOp->HasSIBByte()) { + BaseReg = UseOp->MDGetSIBBaseReg(); + if ((STARS_x86_R_none == BaseReg) || (MD_FRAME_POINTER_REG == BaseReg)) { + // EBP BaseReg for StaticMemOp means no base reg + BaseReg = UseOp->MDGetSIBIndexReg(); + if (MD_STACK_POINTER_REG == BaseReg) { + // ESP IndexReg in SIB byte means no index reg + BaseReg = STARS_x86_R_none; + } + } + } + if (STARS_x86_R_none != BaseReg) { // have an offset reg to add to the static mem addr + // TODO: Fetch constant value for general purpose reg, with SSANum from USE set. + GoodAddr = false; + } +#endif + if (GoodAddr) { + STARS_Segment_t *MemSeg = global_stars_interface->getseg(MemAddr); + if (NULL != MemSeg) { + if (!(MemSeg->IsWriteableSegment())) { + size_t UseOpByteWidth = UseOp->GetByteWidth(); + if (UseOpByteWidth == 8) { + uint64_t MemValue; + if (MemSeg->GetReadOnlyMem64BitValue(MemAddr, MemValue)) { + ConstStruct.ConstType = STARS_CONST_HAS_VALUE; + ConstStruct.ConstValue = (STARS_uval_t)MemValue; + } + } + else if (UseOpByteWidth == 4) { + uint32_t MemValue; + if (MemSeg->GetReadOnlyMem32BitValue(MemAddr, MemValue)) { + ConstStruct.ConstType = STARS_CONST_HAS_VALUE; + ConstStruct.ConstValue = (STARS_uval_t)MemValue; + } + } + else if (UseOpByteWidth == 2) { + uint16_t MemValue; + if (MemSeg->GetReadOnlyMem16BitValue(MemAddr, MemValue)) { + ConstStruct.ConstType = STARS_CONST_HAS_VALUE; + ConstStruct.ConstValue = (STARS_uval_t)MemValue; + } + } + else if (UseOpByteWidth == 1) { + uint8_t MemValue; + if (MemSeg->GetReadOnlyMem8BitValue(MemAddr, MemValue)) { + ConstStruct.ConstType = STARS_CONST_HAS_VALUE; + ConstStruct.ConstValue = (STARS_uval_t)MemValue; + } + } + } + } + } + } return; } // end of SMPInstr::SCCPFetchConstUseValue()