void RawLoader::Map(Document& rDoc, Architecture::VectorSharedPtr const& rArchs) { rDoc.AddMemoryArea(new MappedMemoryArea( "raw", 0x0, rDoc.GetBinaryStream().GetSize(), Address(Address::FlatType, 0x0), rDoc.GetBinaryStream().GetSize(), MemoryArea::Execute | MemoryArea::Read | MemoryArea::Write )); }
bool Architecture::FormatCharacter( Document const& rDoc, Address const& rAddr, Character const& rChar, PrintData & rPrintData) const { auto const& rBinStrm = rDoc.GetBinaryStream(); std::ostringstream oss; TOffset Off; if (!rDoc.ConvertAddressToFileOffset(rAddr, Off)) return false; switch (rChar.GetSubType()) { case Character::AsciiCharacterType: default: { s8 Char; if (!rBinStrm.Read(Off, Char)) return false; switch (Char) { case '\0': oss << "\\0"; break; case '\a': oss << "\\a"; break; case '\b': oss << "\\b"; break; case '\t': oss << "\\t"; break; case '\n': oss << "\\n"; break; case '\v': oss << "\\v"; break; case '\f': oss << "\\f"; break; case '\r': oss << "\\r"; break; default: oss << Char; break; } } } rPrintData.AppendCharacter(oss.str()); return true; }
bool Architecture::FormatValue( Document const& rDoc, Address const& rAddr, Value const& rVal, PrintData & rPrintData) const { auto const& rBinStrm = rDoc.GetBinaryStream(); TOffset Off; u8 ValueModifier = rVal.GetSubType() & ValueDetail::ModifierMask; u8 ValueType = rVal.GetSubType() & ValueDetail::BaseMask; std::string BasePrefix = ""; bool IsUnk = false; switch (rVal.GetLength()) { case 1: rPrintData.AppendKeyword("db").AppendSpace(); break; case 2: rPrintData.AppendKeyword("dw").AppendSpace(); break; case 4: rPrintData.AppendKeyword("dd").AppendSpace(); break; case 8: rPrintData.AppendKeyword("dq").AppendSpace(); break; default: rPrintData.AppendKeyword("d?").AppendSpace(); break; } if (!rDoc.ConvertAddressToFileOffset(rAddr, Off)) { rPrintData.AppendOperator("(?)"); return true; } ValueDetail ValDtl("", Id(), static_cast<ValueDetail::Type>(rVal.GetSubType()), Id()); return FormatValueDetail(rDoc, rAddr, rVal.GetLength() * 8, ValDtl, rPrintData); }
bool MemoryContext::MapDocument(Document const& rDoc, CpuContext const* pCpuCtxt) { bool Res = true; rDoc.ForEachMemoryArea([&](MemoryArea const& rMemArea) { Address const& rMemAreaAddr = rMemArea.GetBaseAddress(); u32 MemAreaSize = rMemArea.GetSize(); u32 MemAreaFileSize = rMemArea.GetFileSize(); void* pRawMemory; u64 LinearAddress; if (pCpuCtxt->Translate(rMemAreaAddr, LinearAddress) == false) LinearAddress = rMemAreaAddr.GetOffset(); if (AllocateMemory(LinearAddress, MemAreaSize, &pRawMemory) == false) { Res = false; return; } // TODO: Do we have to zero-out memory? if (MemAreaFileSize == 0x0) return; TOffset MemAreaFileOff; if (rMemArea.ConvertOffsetToFileOffset(rMemAreaAddr.GetOffset(), MemAreaFileOff) == false) return; if (!rDoc.GetBinaryStream().Read(MemAreaFileOff, pRawMemory, MemAreaFileSize)) { FreeMemory(LinearAddress); Res = false; return; } }); return Res; }
bool Architecture::FormatString( Document const& rDoc, Address const& rAddr, String const& rStr, PrintData & rPrintData) const { auto const& rBinStrm = rDoc.GetBinaryStream(); TOffset FileOff; size_t StrLen = rStr.GetLength(); StringTrait const* pStrTrait = rStr.GetStringTrait(); if (pStrTrait == nullptr) return false; if (rDoc.ConvertAddressToFileOffset(rAddr, FileOff) == false) return false; char* pStrBuf = new char[StrLen]; if (rDoc.GetBinaryStream().Read(FileOff, pStrBuf, StrLen) == false) { delete[] pStrBuf; return false; } std::string OrgStr = pStrTrait->ConvertToUtf8(pStrBuf, StrLen); delete[] pStrBuf; if (OrgStr.empty()) return false; std::string FmtStr; if (rStr.GetSubType() == String::Utf16Type) rPrintData.AppendKeyword("L"); rPrintData.AppendOperator("\""); auto itCharEnd = std::end(OrgStr); size_t FmtStrBeg = FmtStr.length(); for (auto itChar = std::begin(OrgStr); itChar != itCharEnd; ++itChar) { switch (*itChar) { case '\0': FmtStr += "\\0"; break; case '\\': FmtStr += "\\\\"; break; case '\a': FmtStr += "\\a"; break; case '\b': FmtStr += "\\b"; break; case '\t': FmtStr += "\\t"; break; case '\n': FmtStr += "\\n"; break; case '\v': FmtStr += "\\v"; break; case '\f': FmtStr += "\\f"; break; case '\r': FmtStr += "\\r"; break; default: FmtStr += *itChar; break; } } rPrintData.AppendString(FmtStr); rPrintData.AppendOperator("\""); return true; }
bool Architecture::FormatOperand( Document const& rDoc, Address const& rAddr, Instruction const& rInsn, Operand const& rOprd, u8 OperandNo, PrintData & rPrintData) const { rPrintData.MarkOffset(); auto const& rBinStrm = rDoc.GetBinaryStream(); if (rOprd.GetType() == O_NONE) return true; u32 OprdType = rOprd.GetType(); auto const* pCpuInfo = GetCpuInformation(); std::string MemBegChar = "["; std::string MemEndChar = "]"; if (OprdType & O_MEM) rPrintData.AppendOperator("["); if (OprdType & O_REL || OprdType & O_ABS) { Address DstAddr; if (rInsn.GetOperandReference(rDoc, 0, rAddr, DstAddr)) { auto Lbl = rDoc.GetLabelFromAddress(DstAddr); if (Lbl.GetType() != Label::Unknown) rPrintData.AppendLabel(Lbl.GetLabel()); else rPrintData.AppendAddress(rAddr); } else rPrintData.AppendImmediate(rOprd.GetValue(), rAddr.GetOffsetSize()); } else if (OprdType & O_DISP || OprdType & O_IMM) { if (rOprd.GetType() & O_NO_REF) { rPrintData.AppendImmediate(rOprd.GetValue(), rAddr.GetOffsetSize()); return true; } Address OprdAddr = rDoc.MakeAddress(rOprd.GetSegValue(), rOprd.GetValue()); auto Lbl = rDoc.GetLabelFromAddress(OprdAddr); if (Lbl.GetType() != Label::Unknown) rPrintData.AppendLabel(Lbl.GetLabel()); else rPrintData.AppendAddress(OprdAddr); } else if (OprdType & O_REG) { if (pCpuInfo == nullptr) return false; auto pRegName = pCpuInfo->ConvertIdentifierToName(rOprd.GetReg()); if (pRegName == nullptr) return false; rPrintData.AppendRegister(pRegName); } if (OprdType & O_MEM) rPrintData.AppendOperator("]"); return true; }
bool Architecture::FormatString( Document const& rDoc, BinaryStream const& rBinStrm, Address const& rAddr, String const& rStr, std::string & rStrMultiCell, Cell::Mark::List & rMarks) const { TOffset FileOff; size_t StrLen = rStr.GetLength(); StringTrait const* pStrTrait = rStr.GetStringTrait(); if (pStrTrait == nullptr) return false; if (rDoc.ConvertAddressToFileOffset(rAddr, FileOff) == false) return false; char* pStrBuf = new char[StrLen]; if (rDoc.GetBinaryStream().Read(FileOff, pStrBuf, StrLen) == false) { delete[] pStrBuf; return false; } std::string OrgStr = pStrTrait->ConvertToUtf8(pStrBuf, StrLen); delete[] pStrBuf; if (OrgStr.empty()) return false; std::string FmtStr; if (rStr.GetSubType() == String::Utf16Type) { FmtStr += "L"; rMarks.push_back(Cell::Mark(Cell::Mark::KeywordType, 1)); } FmtStr += std::string("\""); rMarks.push_back(Cell::Mark(Cell::Mark::OperatorType, 1)); auto itCharEnd = std::end(OrgStr); size_t FmtStrBeg = FmtStr.length(); for (auto itChar = std::begin(OrgStr); itChar != itCharEnd; ++itChar) { switch (*itChar) { case '\0': FmtStr += "\\0"; break; case '\\': FmtStr += "\\\\"; break; case '\a': FmtStr += "\\a"; break; case '\b': FmtStr += "\\b"; break; case '\t': FmtStr += "\\t"; break; case '\n': FmtStr += "\\n"; break; case '\v': FmtStr += "\\v"; break; case '\f': FmtStr += "\\f"; break; case '\r': FmtStr += "\\r"; break; default: FmtStr += *itChar; break; } } FmtStr += std::string("\""); rMarks.push_back(Cell::Mark(Cell::Mark::StringType, FmtStr.length() - FmtStrBeg - 1)); rMarks.push_back(Cell::Mark(Cell::Mark::OperatorType, 1)); rStrMultiCell.swap(FmtStr); return true; }
bool Architecture::FormatValue( Document const& rDoc, BinaryStream const& rBinStrm, Address const& rAddr, Value const& rVal, std::string & rStrCell, Cell::Mark::List & rMarks) const { std::ostringstream oss; TOffset Off; u8 ValueType = rVal.GetSubType(); std::string BasePrefix = ""; bool IsUnk = false; auto const& rCurBinStrm = rDoc.GetBinaryStream(); if (!rDoc.ConvertAddressToFileOffset(rAddr, Off)) IsUnk = true; oss << std::setfill('0'); switch (ValueType) { case Value::BinaryType: BasePrefix = "0b"; break; // TODO: Unimplemented case Value::DecimalType: oss << std::dec; BasePrefix = "0n"; break; case Value::HexadecimalType: default: oss << std::hex; BasePrefix = "0x"; break; } Cell::Mark::Type MarkType = Cell::Mark::ImmediateType; switch (rVal.GetLength()) { case 1: default: { if (IsUnk) oss << "db (?)"; else { u8 Data; if (!rCurBinStrm.Read(Off, Data)) return false; oss << "db " << BasePrefix << std::setw(2) << static_cast<u16>(Data); // u8 type would be printed as char by ostream } break; } case 2: { if (IsUnk) oss << "dw (?)"; else { u16 Data; if (!rCurBinStrm.Read(Off, Data)) return false; Label Lbl = rDoc.GetLabelFromAddress(Data); if (Lbl.GetType() == Label::Unknown) oss << "dw " << BasePrefix << std::setw(4) << static_cast<u16>(Data); else { oss << "dw " << Lbl.GetLabel(); MarkType = Cell::Mark::LabelType; } } break; } case 4: { if (IsUnk) oss << "dd (?)"; else { u32 Data; if (!rCurBinStrm.Read(Off, Data)) return false; Label Lbl = rDoc.GetLabelFromAddress(Data); if (Lbl.GetType() == Label::Unknown) oss << "dd " << BasePrefix << std::setw(8) << static_cast<u32>(Data); else { oss << "dd " << Lbl.GetLabel(); MarkType = Cell::Mark::LabelType; } } break; } case 8: { if (IsUnk) oss << "dq (?)"; else { u64 Data; if (!rCurBinStrm.Read(Off, Data)) return false; Label Lbl = rDoc.GetLabelFromAddress(Data); if (Lbl.GetType() == Label::Unknown) oss << "dq " << BasePrefix << std::setw(16) << static_cast<u64>(Data); else { oss << "dq " << Lbl.GetLabel(); MarkType = Cell::Mark::LabelType; } } break; } } rMarks.push_back(Cell::Mark(Cell::Mark::KeywordType, 3)); rMarks.push_back(Cell::Mark(MarkType, oss.str().length() - 3)); rStrCell = oss.str(); return true; }