Skip to content

Commit

Permalink
Jump tables should be only in read only sections
Browse files Browse the repository at this point in the history
  • Loading branch information
mxz297 committed Jun 10, 2016
1 parent 1c10fba commit 4e5f3ce
Show file tree
Hide file tree
Showing 10 changed files with 53 additions and 4 deletions.
4 changes: 4 additions & 0 deletions dyninstAPI/src/addressSpace.C
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,10 @@ bool AddressSpace::isData(const Address addr) const {
return false;
}

bool AddressSpace::isReadOnly(const Address ) const {
return false;
}

bool AddressSpace::isValidAddress(const Address addr) const {
mapped_object *obj = findObject(addr);
if (!obj) return false;
Expand Down
1 change: 1 addition & 0 deletions dyninstAPI/src/addressSpace.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ class AddressSpace : public InstructionSource {
bool usesDataLoadAddress() const; // OS-specific
virtual bool isCode(const Address) const;
virtual bool isData(const Address) const;
virtual bool isReadOnly(const Address) const;
virtual Address offset() const = 0;
virtual Address length() const = 0;
virtual Architecture getArch() const = 0;
Expand Down
1 change: 1 addition & 0 deletions parseAPI/h/CFGModifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ class InsertedRegion : public CodeRegion {
};
PARSER_EXPORT bool isCode(const Address a) const { return isValidAddress(a); };
PARSER_EXPORT bool isData(const Address) const { return false; };
PARSER_EXPORT bool isReadOnly(const Address) const { return false; };
PARSER_EXPORT Address offset() const { return base_; };
PARSER_EXPORT Address length() const { return size_; };
PARSER_EXPORT unsigned int getAddressWidth() const {
Expand Down
2 changes: 2 additions & 0 deletions parseAPI/h/CodeSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ class PARSER_EXPORT SymtabCodeRegion : public CodeRegion {
unsigned int getAddressWidth() const;
bool isCode(const Address) const;
bool isData(const Address) const;
bool isReadOnly(const Address) const;
Address offset() const;
Address length() const;
Architecture getArch() const;
Expand Down Expand Up @@ -282,6 +283,7 @@ class PARSER_EXPORT SymtabCodeSource : public CodeSource {
unsigned int getAddressWidth() const;
bool isCode(const Address) const;
bool isData(const Address) const;
bool isReadOnly(const Address) const;
Address offset() const;
Address length() const;
Architecture getArch() const;
Expand Down
1 change: 1 addition & 0 deletions parseAPI/h/InstructionSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class PARSER_EXPORT InstructionSource
virtual unsigned int getAddressWidth() const = 0;
virtual bool isCode(const Address) const = 0;
virtual bool isData(const Address) const = 0;
virtual bool isReadOnly(const Address) const = 0;
virtual Address offset() const = 0;
virtual Address length() const = 0;
virtual Architecture getArch() const = 0;
Expand Down
6 changes: 5 additions & 1 deletion parseAPI/src/BoundFactData.C
Original file line number Diff line number Diff line change
Expand Up @@ -635,12 +635,16 @@ void BoundValue::MemoryRead(Block* b, int readSize) {
#endif
if (IsInReadOnlyRegion(memAddrLow, memAddrHigh)) {
set<uint64_t> values;
if (interval.size() <= MAX_TABLE_ENTRY && b->obj()->cs()->isValidAddress(memAddrLow)) {
if (interval.size() <= MAX_TABLE_ENTRY && b->obj()->cs()->isValidAddress(memAddrLow) && b->obj()->cs()->isReadOnly(memAddrLow)) {
for (Address memAddr = memAddrLow ; memAddr <= memAddrHigh; memAddr += interval.stride) {
if (!b->obj()->cs()->isValidAddress(memAddr)) {
parsing_printf("INVALID ADDRESS %lx\n", memAddr);
continue;
}
if (!b->obj()->cs()->isReadOnly(memAddr)) {
parsing_printf("NOT READ ONLY SECTION %lx\n", memAddr);
continue;
}
uint64_t val;
switch (readSize) {
case 8:
Expand Down
5 changes: 5 additions & 0 deletions parseAPI/src/IndirectASTVisitor.C
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,11 @@ AST::Ptr JumpTableFormatVisitor::visit(DataflowAPI::RoseAST *ast) {
parsing_printf("\ttableBase 0x%lx invalid, not jump table format\n", tableBase);
findIncorrectFormat = true;
}
if (!b->obj()->cs()->isReadOnly(tableBase)) {
parsing_printf("\ttableBase 0x%lx not read only, not jump table format\n", tableBase);
findIncorrectFormat = true;
}

}
}
}
Expand Down
4 changes: 2 additions & 2 deletions parseAPI/src/IndirectAnalyzer.C
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ using namespace Dyninst::InstructionAPI;


bool IndirectControlFlowAnalyzer::NewJumpTableAnalysis(std::vector<std::pair< Address, Dyninst::ParseAPI::EdgeTypeEnum > >& outEdges) {
if (block->last() == 0xa2219d) dyn_debug_parsing = 1; else dyn_debug_parsing=0;
// if (block->last() == 0xacef04) dyn_debug_parsing = 1; else dyn_debug_parsing=0;
parsing_printf("Apply indirect control flow analysis at %lx\n", block->last());
parsing_printf("Looking for thunk\n");
// Find all blocks that reach the block containing the indirect jump
Expand Down Expand Up @@ -56,7 +56,7 @@ bool IndirectControlFlowAnalyzer::NewJumpTableAnalysis(std::vector<std::pair< Ad
bool ijt = jtp.IsJumpTable(g, bfc, target);
if (ijt) jtp.FillInOutEdges(target, jumpTableOutEdges);
}
fprintf(stderr, "indirect jump at %lx with %d assignments and %d edges\n", block->last(), jtp.currentAssigns.size(), jumpTableOutEdges.size());
//fprintf(stderr, "indirect jump at %lx with %d assignments and %d edges\n", block->last(), jtp.currentAssigns.size(), jumpTableOutEdges.size());

outEdges.insert(outEdges.end(), jumpTableOutEdges.begin(), jumpTableOutEdges.end());
return !jumpTableOutEdges.empty();
Expand Down
10 changes: 9 additions & 1 deletion parseAPI/src/JumpTablePred.C
Original file line number Diff line number Diff line change
Expand Up @@ -268,12 +268,20 @@ bool JumpTablePred::FillInOutEdges(BoundValue &target,
if (!block->obj()->cs()->isValidAddress(tableBase)) {
parsing_printf("\ttableBase 0x%lx invalid, returning false\n", tableBase);
jumpTableFormat = false;
fprintf(stderr, "Not jump table format!\n");
parsing_printf("Not jump table format!\n");
return false;
}
if (!block->obj()->cs()->isReadOnly(tableBase)) {
parsing_printf("\ttableBase 0x%lx not read only, returning false\n", tableBase);
jumpTableFormat = false;
parsing_printf("Not jump table format!\n");
return false;
}


for (Address tableEntry = tableBase; tableEntry <= tableLastEntry; tableEntry += target.interval.stride) {
if (!block->obj()->cs()->isValidAddress(tableEntry)) continue;
if (!block->obj()->cs()->isReadOnly(tableEntry)) continue;
Address targetAddress = 0;
if (target.tableReadSize > 0) {
switch (target.tableReadSize) {
Expand Down
23 changes: 23 additions & 0 deletions parseAPI/src/SymtabCodeSource.C
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,16 @@ SymtabCodeRegion::isData(const Address addr) const
_region->getRegionType()==SymtabAPI::Region::RT_TEXTDATA;
}

bool
SymtabCodeRegion::isReadOnly(const Address addr) const
{
if(!contains(addr)) return false;
if (_region->getRegionName() == ".data.rel.ro") return true;
// parsing_printf("Region name %s, permission %d\n", _region->getRegionName().c_str(), _region->getRegionPermissions());
return _region->getRegionPermissions() == SymtabAPI::Region::RP_R ||
_region->getRegionPermissions() == SymtabAPI::Region::RP_RX;
}

Address
SymtabCodeRegion::offset() const
{
Expand Down Expand Up @@ -685,6 +695,19 @@ SymtabCodeSource::isData(const Address addr) const
return false;
}

bool
SymtabCodeSource::isReadOnly(const Address addr) const
{
overlapping_warn(FILE__,__LINE__);

CodeRegion * cr = lookup_region(addr);
if(cr)
return cr->isReadOnly(addr);
else
return false;
}


Address
SymtabCodeSource::offset() const
{
Expand Down

0 comments on commit 4e5f3ce

Please sign in to comment.