diff --git a/.gitattributes b/.gitattributes index bfee7a5fd6415e13cb90dca762cb2fac57b49019..2e45f284a43724d4c641c4be8fe7b4efd3dae6d7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -277,11 +277,14 @@ libIRDB/test/read_variantir.cpp -text libIRDB/test/unfix_calls.cpp -text libIRDB/test/unwind-pe.h -text libMEDSannotation/Makefile -text +libMEDSannotation/include/MEDS.hpp -text libMEDSannotation/include/MEDS_AnnotationParser.hpp -text libMEDSannotation/include/MEDS_InstructionCheckAnnotation.hpp -text +libMEDSannotation/include/MEDS_Register.hpp -text libMEDSannotation/include/VirtualOffset.hpp -text libMEDSannotation/src/MEDS_AnnotationParser.cpp -text libMEDSannotation/src/MEDS_InstructionCheckAnnotation.cpp -text +libMEDSannotation/src/MEDS_Register.cpp -text libMEDSannotation/src/Makefile -text libMEDSannotation/src/VirtualOffset.cpp -text libintegertransform/Makefile -text diff --git a/libMEDSannotation/include/MEDS.hpp b/libMEDSannotation/include/MEDS.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7560c37989cce55f4b09cfa603dcb4960fcb0ff0 --- /dev/null +++ b/libMEDSannotation/include/MEDS.hpp @@ -0,0 +1,10 @@ +#ifndef _MEDS_H +#define _MEDS_H + +class MEDS +{ + public: + enum Register { UNKNOWN, EAX, EBX, ECX, EDX }; +} + +#endif diff --git a/libMEDSannotation/include/MEDS_AnnotationParser.hpp b/libMEDSannotation/include/MEDS_AnnotationParser.hpp index 41cdba58270b71e0940b43e870c6dd03e6ef6b9d..94f9c6dbbde1ccbdb6ec9734820cc392fee056b9 100644 --- a/libMEDSannotation/include/MEDS_AnnotationParser.hpp +++ b/libMEDSannotation/include/MEDS_AnnotationParser.hpp @@ -6,6 +6,9 @@ #include "MEDS_InstructionCheckAnnotation.hpp" #include "VirtualOffset.hpp" +namespace MEDS_Annotation +{ + class MEDS_AnnotationParser { public: @@ -16,4 +19,6 @@ class MEDS_AnnotationParser std::map<VirtualOffset, MEDS_InstructionCheckAnnotation> m_annotations; }; +} + #endif diff --git a/libMEDSannotation/include/MEDS_InstructionCheckAnnotation.hpp b/libMEDSannotation/include/MEDS_InstructionCheckAnnotation.hpp index b1e6a197e38e7e0da50e0908b52992a011ef2f3e..9a0f7c160982414dbf9fe8288ee5be1ab6a519d3 100644 --- a/libMEDSannotation/include/MEDS_InstructionCheckAnnotation.hpp +++ b/libMEDSannotation/include/MEDS_InstructionCheckAnnotation.hpp @@ -3,7 +3,13 @@ #include <string> #include "VirtualOffset.hpp" +#include "MEDS_Register.hpp" + +namespace MEDS_Annotation +{ + +// These strings must match those emitted by MEDS in the information annotation file exactly #define MEDS_ANNOT_INSTR "INSTR" #define MEDS_ANNOT_CHECK "CHECK" #define MEDS_ANNOT_OVERFLOW "OVERFLOW" @@ -12,6 +18,10 @@ #define MEDS_ANNOT_TRUNCATION "TRUNCATION" #define MEDS_ANNOT_SIGNED "SIGNED" #define MEDS_ANNOT_UNSIGNED "UNSIGNED" +#define MEDS_ANNOT_UNKNOWNSIGN "UNKNOWNSIGN" + +using namespace std; +using namespace MEDS_Annotation; // // Class to handle one MEDS (integer vulnerability) annotation @@ -20,7 +30,7 @@ class MEDS_InstructionCheckAnnotation { public: MEDS_InstructionCheckAnnotation() { m_isValid = false; } - MEDS_InstructionCheckAnnotation(const std::string &p_rawLine); + MEDS_InstructionCheckAnnotation(const string &p_rawLine); // valid annotation? bool isValid() const { return m_isValid; } @@ -34,25 +44,40 @@ class MEDS_InstructionCheckAnnotation // signed vs. unsigned bool isUnsigned() const { return m_isUnsigned; } bool isSigned() const { return m_isSigned; } + bool isUnknownSign() const { return m_isUnknownSign; } + + // get bitwidth + int getBitWidth() const { return m_bitWidth; } + int getTruncationFromWidth() const { return m_truncationFromWidth; } + int getTruncationToWidth() const { return m_truncationToWidth; } + + // get register + MEDS_Annotation::Register::RegisterName getRegister() const { return m_register; } // virtual offset VirtualOffset getVirtualOffset() const; - std::string& toString() { return m_rawInputLine; } + const string& toString() const { return m_rawInputLine; } private: void parse(); private: - std::string m_rawInputLine; + string m_rawInputLine; bool m_isOverflow; bool m_isUnderflow; bool m_isSignedness; bool m_isTruncation; bool m_isSigned; bool m_isUnsigned; + bool m_isUnknownSign; + int m_bitWidth; + int m_truncationFromWidth; + int m_truncationToWidth; VirtualOffset m_virtualOffset; bool m_isValid; + MEDS_Annotation::Register::RegisterName m_register; }; +} #endif diff --git a/libMEDSannotation/include/MEDS_Register.hpp b/libMEDSannotation/include/MEDS_Register.hpp new file mode 100644 index 0000000000000000000000000000000000000000..bc0388f04c85cd0cb16363846d52361759d8d8e5 --- /dev/null +++ b/libMEDSannotation/include/MEDS_Register.hpp @@ -0,0 +1,17 @@ +#ifndef _MEDS_REGISTER_H +#define _MEDS_REGISTER_H + +#include <string> + +namespace MEDS_Annotation +{ + +class Register { +public: + enum RegisterName { UNKNOWN, EAX, EBX, ECX, EDX, AX, BX, CX, DX, AL, BL, CL, DL }; + static RegisterName getRegister(std::string); +}; + +} + +#endif diff --git a/libMEDSannotation/src/MEDS_AnnotationParser.cpp b/libMEDSannotation/src/MEDS_AnnotationParser.cpp index d80fcb35f3b48731d0e558b410d563a3ed8413e6..dfcc7555e22c4dbedd18375fc20f81186dc0de77 100644 --- a/libMEDSannotation/src/MEDS_AnnotationParser.cpp +++ b/libMEDSannotation/src/MEDS_AnnotationParser.cpp @@ -4,6 +4,7 @@ #define MAX_BUF_SIZE 2048 using namespace std; +using namespace MEDS_Annotation; MEDS_AnnotationParser::MEDS_AnnotationParser(istream &p_inputStream) { diff --git a/libMEDSannotation/src/MEDS_InstructionCheckAnnotation.cpp b/libMEDSannotation/src/MEDS_InstructionCheckAnnotation.cpp index d8730f620698f9fef285ad27e801d7f720c06f67..93591c299bb0efcc35a71c8f358dcb3dfac7a166 100644 --- a/libMEDSannotation/src/MEDS_InstructionCheckAnnotation.cpp +++ b/libMEDSannotation/src/MEDS_InstructionCheckAnnotation.cpp @@ -2,9 +2,11 @@ #include <cstdio> #include <string> +#include "MEDS_Register.hpp" #include "MEDS_InstructionCheckAnnotation.hpp" using namespace std; +using namespace MEDS_Annotation; /* Example format (as of 10/18/2011) -- subject to change: @@ -29,6 +31,11 @@ MEDS_InstructionCheckAnnotation::MEDS_InstructionCheckAnnotation(const std::stri m_isSignedness = false; m_isSigned = false; m_isUnsigned = false; + m_isUnknownSign = true; + m_bitWidth = -1; + m_truncationFromWidth = -1; + m_truncationToWidth = -1; + m_register = Register::UNKNOWN; parse(); } @@ -43,7 +50,7 @@ void MEDS_InstructionCheckAnnotation::parse() // field 3 - INSTR // field 4 - CHECK // field 5 - {OVERFLOW | UNDERFLOW | SIGNEDNESS | TRUNCATION } - // field 6 - {SIGNED | UNSIGNED | 16 | 32} + // field 6 - {SIGNED | UNSIGNED | UNKNOWNSIGN | 16 | 32} // field 7 - {<register> | <memory reference>} if (m_rawInputLine.find(MEDS_ANNOT_INSTR)==string::npos || m_rawInputLine.find(MEDS_ANNOT_CHECK)==string::npos) @@ -53,6 +60,9 @@ void MEDS_InstructionCheckAnnotation::parse() VirtualOffset vo(m_rawInputLine); m_virtualOffset = vo; + // The annotation format is very simple so we don't bother with any fancy parsing + // Later, this may need to be changed + // get check type if (m_rawInputLine.find(MEDS_ANNOT_OVERFLOW)!=string::npos) m_isOverflow = true; @@ -68,9 +78,34 @@ void MEDS_InstructionCheckAnnotation::parse() // signed vs. unsigned if (m_rawInputLine.find(MEDS_ANNOT_UNSIGNED)!=string::npos) + { m_isUnsigned = true; + m_isUnknownSign = false; + } else if (m_rawInputLine.find(MEDS_ANNOT_SIGNED)!=string::npos) + { m_isSigned = true; + m_isUnknownSign = false; + } + else if (m_rawInputLine.find(MEDS_ANNOT_UNKNOWNSIGN)!=string::npos) + { + m_isUnsigned = false; + m_isSigned = false; + m_isUnknownSign = true; + } + + // get bit width information for overflow & underflow + if (m_isOverflow || m_isUnderflow) + { + sscanf(m_rawInputLine.c_str(), "%*s %*d %*s %*s %*s %*s %d", &m_bitWidth); + } + else if (m_isTruncation) // get bid width from/to information for truncation + { + char buf[1024] = ""; + // [ADDR] [SIZE] INSTR CHECK TRUNCATION UNKNOWNSIGN 32 EAX 16 AX ZZ mov [esp+2Ah], ax + sscanf(m_rawInputLine.c_str(), "%*s %*d %*s %*s %*s %*s %d %s %d", &m_truncationFromWidth, buf, &m_truncationToWidth); + m_register = Register::getRegister(string(buf)); + } m_isValid = true; diff --git a/libMEDSannotation/src/MEDS_Register.cpp b/libMEDSannotation/src/MEDS_Register.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ba4e829add8e8d25fc8f88182ac6183032b7d87e --- /dev/null +++ b/libMEDSannotation/src/MEDS_Register.cpp @@ -0,0 +1,37 @@ +#include <string> +#include <strings.h> + +#include "MEDS_Register.hpp" + +using namespace MEDS_Annotation; + +Register::RegisterName Register::getRegister(std::string p_reg) +{ + if (strcasecmp(p_reg.c_str(), "EAX") == 0) + return EAX; + else if (strcasecmp(p_reg.c_str(), "EBX") == 0) + return EBX; + else if (strcasecmp(p_reg.c_str(), "ECX") == 0) + return ECX; + else if (strcasecmp(p_reg.c_str(), "EDX") == 0) + return EDX; + else if (strcasecmp(p_reg.c_str(), "AX") == 0) + return AX; + else if (strcasecmp(p_reg.c_str(), "BX") == 0) + return BX; + else if (strcasecmp(p_reg.c_str(), "CX") == 0) + return CX; + else if (strcasecmp(p_reg.c_str(), "DX") == 0) + return DX; + else if (strcasecmp(p_reg.c_str(), "AL") == 0) + return AL; + else if (strcasecmp(p_reg.c_str(), "BL") == 0) + return BL; + else if (strcasecmp(p_reg.c_str(), "CL") == 0) + return CL; + else if (strcasecmp(p_reg.c_str(), "DL") == 0) + return DL; + else + return UNKNOWN; +} + diff --git a/libMEDSannotation/src/Makefile b/libMEDSannotation/src/Makefile index ce5933b5960edb105a526846d1f7729fb9c86ca6..76cd72b4ec6781c2edefdd56325151898039828f 100644 --- a/libMEDSannotation/src/Makefile +++ b/libMEDSannotation/src/Makefile @@ -1,7 +1,7 @@ LIB=../lib/libMEDSannotation.a -OBJS=VirtualOffset.o MEDS_AnnotationParser.o MEDS_InstructionCheckAnnotation.o +OBJS=VirtualOffset.o MEDS_Register.o MEDS_AnnotationParser.o MEDS_InstructionCheckAnnotation.o all: $(OBJS)