CfgConstVertexSet findFunctionReturns(const ControlFlowGraph &cfg, const ControlFlowGraph::ConstVertexIterator &beginVertex) { ASSERT_require2(cfg.isValidVertex(beginVertex), "beginVertex must belong to the CFG"); CfgConstVertexSet endVertices; typedef Sawyer::Container::Algorithm::DepthFirstForwardEdgeTraversal<const ControlFlowGraph> Traversal; for (Traversal t(cfg, beginVertex); t; ++t) { if (t->value().type() == E_FUNCTION_RETURN) { endVertices.insert(t->source()); t.skipChildren(); // found a function return edge } else if (t->value().type() == E_FUNCTION_CALL) { // not E_FUNCTION_XFER t.skipChildren(); // stay in this function } } return endVertices; }
static void sendCommand(__ptrace_request request, int child, void *addr=0, void *data=0) { ASSERT_require2(child, "must be attached to a subordinate process"); if (-1==ptrace(request, child, addr, data)) throw std::runtime_error("BinaryDebugger::sendCommand failed: " + boost::to_lower_copy(std::string(strerror(errno)))); }
// Read a string from memory std::string StringFinder::decode(const MemoryMap &map, const String &string) const { ASSERT_require(string.isValid()); struct Resources { uint8_t *buffer; Resources(): buffer(NULL) {} ~Resources() { delete buffer; } } r; // Read the data for the string r.buffer = new uint8_t[string.nBytes()]; size_t nRead = map.at(string.address()).limit(string.nBytes()).read(r.buffer).size(); if (nRead < string.nBytes()) { throw MemoryMap::NotMapped("short read for " + StringUtility::numberToString(string.nBytes()) + "-byte string at " + StringUtility::addrToString(string.address()), &map, string.address() + nRead); } // Decode the string length uint8_t *data = r.buffer; size_t dataSize = string.nBytes(); ASSERT_require(string.isValid()); // checks string length for encoding switch (string.lengthEncoding()) { case MAP_TERMINATED: case SEQUENCE_TERMINATED: break; case NUL_TERMINATED: --dataSize; break; case BYTE_LENGTH: { size_t n = *data++; --dataSize; ASSERT_require2(n == dataSize, "mismatched lengths in byte-length encoded string"); break; } case LE16_LENGTH: { size_t n = ByteOrder::le_to_host(*(uint16_t*)data); data += 2; dataSize -= 2; ASSERT_require2(n == dataSize, "mismatched lengths in le16-length encoded string"); break; } case BE16_LENGTH: { size_t n = ByteOrder::be_to_host(*(uint16_t*)data); data += 2; dataSize -= 2; ASSERT_require2(n == dataSize, "mismatched lengths in be16-length encoded string"); break; } case LE32_LENGTH: { size_t n = ByteOrder::le_to_host(*(uint32_t*)data); data += 4; dataSize -= 4; ASSERT_require2(n == dataSize, "mismatched lengths in le32-length encoded string"); break; } case BE32_LENGTH: { size_t n = ByteOrder::be_to_host(*(uint32_t*)data); data += 4; dataSize -= 4; ASSERT_require2(n == dataSize, "mismatched lengths in be32-length encoded string"); break; } } // Decode the string std::string s; switch (string.characterEncoding()) { case ASCII: s = std::string((const char*)data, dataSize); break; } return s; }