diff options
| author | Brandon Miller <brandon@vector35.com> | 2024-04-11 10:40:09 -0400 |
|---|---|---|
| committer | Brandon Miller <bkmiller89@icloud.com> | 2024-04-25 10:56:18 -0400 |
| commit | 465a8d5d7afd5a5648338009e0fb8dbe4f199347 (patch) | |
| tree | f3ead9b2b65a291fd7a97b2ddbbda2f10a5462ac | |
| parent | 4b2b3d561b92a01f4d29b86d5510d39e4d1accf3 (diff) | |
Querying candidate base address reasons
Querying vector of reason information for a candidate base address
using the new core API
| -rw-r--r-- | basedetection.cpp | 23 | ||||
| -rw-r--r-- | binaryninjaapi.h | 19 | ||||
| -rw-r--r-- | binaryninjacore.h | 39 | ||||
| -rw-r--r-- | examples/triage/baseaddress.cpp | 73 | ||||
| -rw-r--r-- | examples/triage/baseaddress.h | 4 |
5 files changed, 85 insertions, 73 deletions
diff --git a/basedetection.cpp b/basedetection.cpp index 4389f1b7..e994ede5 100644 --- a/basedetection.cpp +++ b/basedetection.cpp @@ -21,7 +21,6 @@ #include "binaryninjaapi.h" using namespace BinaryNinja; -using namespace std; BaseAddressDetection::BaseAddressDetection(Ref<BinaryView> bv) @@ -65,13 +64,29 @@ bool BaseAddressDetection::IsAborted() } -std::set<std::pair<size_t, uint64_t>> BaseAddressDetection::GetScores(BaseAddressDetectionConfidence* confidence) +std::set<std::pair<size_t, uint64_t>> BaseAddressDetection::GetScores(BNBaseAddressDetectionConfidence* confidence, + uint64_t *lastTestedBaseAddress) { std::set<std::pair<size_t, uint64_t>> result; BNBaseAddressDetectionScore scores[10]; - size_t numCandidates = BNGetBaseAddressDetectionScores(m_object, scores, 10, - (BNBaseAddressDetectionConfidence *)confidence); + size_t numCandidates = BNGetBaseAddressDetectionScores(m_object, scores, 10, confidence, lastTestedBaseAddress); for (size_t i = 0; i < numCandidates; i++) result.insert(std::make_pair(scores[i].Score, scores[i].BaseAddress)); return result; } + + +std::vector<BNBaseAddressDetectionReason> BaseAddressDetection::GetReasonsForBaseAddress(uint64_t baseAddress) +{ + std::vector<BNBaseAddressDetectionReason> result; + size_t count; + BNBaseAddressDetectionReason *reasons = BNGetBaseAddressDetectionReasons(m_object, baseAddress, &count); + if (!reasons) + return result; + + for (size_t i = 0; i < count; i++) + result.push_back(reasons[i]); + + free(reasons); + return result; +} diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 6bd33c80..803ebf76 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -17391,13 +17391,6 @@ namespace BinaryNinja { uint32_t MaxPointersPerCluster; }; - enum BaseAddressDetectionConfidence - { - NoConfidence = 0, - LowConfidence = 1, - HighConfidence = 2, - }; - /*! \ingroup baseaddressdetection */ @@ -17418,10 +17411,18 @@ namespace BinaryNinja { /*! Get the top 10 candidate base addresses and thier scores - \param confidence Confidence level that the top base address candidate is correct + \param confidence Confidence level that indicates the likelihood the top base address candidate is correct + \param lastTestedBaseAddress Last base address tested before analysis was aborted or completed \return Set of pairs containing candidate base addresses and their scores */ - std::set<std::pair<size_t, uint64_t>> GetScores(BaseAddressDetectionConfidence* confidence); + std::set<std::pair<size_t, uint64_t>> GetScores(BNBaseAddressDetectionConfidence* confidence, uint64_t *lastTestedBaseAddress); + + /*! Get a vector of BNBaseAddressDetectionReasons containing information that indicates why a base address was reported as a candidate + + \param baseAddress Base address to query reasons for + \return Vector of reason structures containing information about why a base address was reported as a candidate + */ + std::vector<BNBaseAddressDetectionReason> GetReasonsForBaseAddress(uint64_t baseAddress); /*! Abort base address detection */ diff --git a/binaryninjacore.h b/binaryninjacore.h index 25d7618e..ffe17dba 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -3160,25 +3160,25 @@ extern "C" typedef enum BNBaseAddressDetectionPOISetting { - POI_ANALYSIS_STRINGS_ONLY, - POI_ANALYSIS_FUNCTIONS_ONLY, - POI_ANALYSIS_ALL, + POIAnalysisStringsOnly, + POIAnalysisFunctionsOnly, + POIAnalysisAll, } BNBaseAddressDetectionPOISetting; typedef enum BNBaseAddressDetectionPOIType { - POI_STRING, - POI_FUNCTION, - POI_DATA_VARIABLE, - POI_FILE_START, - POI_FILE_END, + POIString, + POIFunction, + POIDataVariable, + POIFileStart, + POIFileEnd, } BNBaseAddressDetectionPOIType; typedef enum BNBaseAddressDetectionConfidence { - CONFIDENCE_UNASSIGNED, - CONFIDENCE_LOW, - CONFIDENCE_HIGH, + NoConfidence, + LowConfidence, + HighConfidence, } BNBaseAddressDetectionConfidence; typedef struct BNBaseAddressDetectionSettings @@ -3197,7 +3197,7 @@ extern "C" { uint64_t Pointer; uint64_t POIOffset; - BNBaseAddressDetectionPOIType BaseAddressDetectionPOIType; + BNBaseAddressDetectionPOIType POIType; } BNBaseAddressDetectionReason; typedef struct BNBaseAddressDetectionScore @@ -3206,15 +3206,6 @@ extern "C" uint64_t BaseAddress; } BNBaseAddressDetectionScore; - typedef struct BNBaseAddressDetectionResults - { - BNBaseAddressDetectionConfidence Confidence; - BNBaseAddressDetectionScore** Scores; - BNBaseAddressDetectionReason** Reasons; - char* ErrorStr; - uint64_t LastTestedBaseAddress; - } BNBaseAddressDetectionResults; - BINARYNINJACOREAPI char* BNAllocString(const char* contents); BINARYNINJACOREAPI void BNFreeString(char* str); BINARYNINJACOREAPI char** BNAllocStringList(const char** contents, size_t size); @@ -7049,8 +7040,10 @@ extern "C" // Base Address Detection BINARYNINJACOREAPI BNBaseAddressDetection* BNCreateBaseAddressDetection(BNBinaryView *view); BINARYNINJACOREAPI bool BNDetectBaseAddress(BNBaseAddressDetection* bad, BNBaseAddressDetectionSettings& settings); - BINARYNINJACOREAPI size_t BNGetBaseAddressDetectionScores(BNBaseAddressDetection* bad, - BNBaseAddressDetectionScore* scores, size_t count, BNBaseAddressDetectionConfidence* confidence); + BINARYNINJACOREAPI size_t BNGetBaseAddressDetectionScores(BNBaseAddressDetection* bad, BNBaseAddressDetectionScore* scores, size_t count, + BNBaseAddressDetectionConfidence* confidence, uint64_t* lastTestedBaseAddress); + BINARYNINJACOREAPI BNBaseAddressDetectionReason* BNGetBaseAddressDetectionReasons(BNBaseAddressDetection* bad, + uint64_t baseAddress, size_t* count); BINARYNINJACOREAPI void BNAbortBaseAddressDetection(BNBaseAddressDetection* bad); BINARYNINJACOREAPI bool BNIsBaseAddressDetectionAborted(BNBaseAddressDetection* bad); BINARYNINJACOREAPI void BNFreeBaseAddressDetection(BNBaseAddressDetection* bad); diff --git a/examples/triage/baseaddress.cpp b/examples/triage/baseaddress.cpp index 41068cfb..542a1f94 100644 --- a/examples/triage/baseaddress.cpp +++ b/examples/triage/baseaddress.cpp @@ -6,10 +6,10 @@ using namespace std; BNBaseAddressDetectionPOISetting BaseAddressDetectionPOISettingFromString(const std::string& setting) { if (setting == "Strings only") - return POI_ANALYSIS_STRINGS_ONLY; + return POIAnalysisStringsOnly; if (setting == "Functions only") - return POI_ANALYSIS_FUNCTIONS_ONLY; - return POI_ANALYSIS_ALL; // Default to All + return POIAnalysisFunctionsOnly; + return POIAnalysisAll; // Default to All } @@ -17,34 +17,34 @@ std::string BaseAddressDetectionPOITypeToString(BNBaseAddressDetectionPOIType ty { switch (type) { - case POI_STRING: - return "String"; - case POI_FUNCTION: - return "Function"; - case POI_DATA_VARIABLE: - return "Data variable"; - case POI_FILE_END: - return "File end"; - case POI_FILE_START: - return "File start"; - default: - return "Unknown"; + case POIString: + return "String"; + case POIFunction: + return "Function"; + case POIDataVariable: + return "Data variable"; + case POIFileEnd: + return "File end"; + case POIFileStart: + return "File start"; + default: + return "Unknown"; } } -std::string BaseAddressDetectionConfidenceToString(BinaryNinja::BaseAddressDetectionConfidence level) +std::string BaseAddressDetectionConfidenceToString(BNBaseAddressDetectionConfidence level) { switch (level) { - case BinaryNinja::NoConfidence: - return "Unassigned"; - case BinaryNinja::HighConfidence: - return "High"; - case BinaryNinja::LowConfidence: - return "Low"; - default: - return "Unknown"; + case NoConfidence: + return "Unassigned"; + case HighConfidence: + return "High"; + case LowConfidence: + return "Low"; + default: + return "Unknown"; } } @@ -124,21 +124,24 @@ void BaseAddressDetectionThread::run() if (!m_baseDetection->DetectBaseAddress(settings)) emit ResultReady(results); - auto scores = m_baseDetection->GetScores(&results.Confidence); + auto scores = m_baseDetection->GetScores(&results.Confidence, &results.LastTestedBaseAddress); results.Scores = scores; + for (const auto& score : scores) + { + auto reasons = m_baseDetection->GetReasonsForBaseAddress(score.second); + results.Reasons[score.second] = reasons; + } + emit ResultReady(results); } - void BaseAddressDetectionWidget::HandleResults(const BaseAddressDetectionQtResults& results) { if (!results.Status.empty()) m_status->setText(QString::fromStdString(results.Status)); - /* TODO if (results.Status.empty() && m_worker->IsAborted()) - m_status->setText("Aborted by user (Last Base: 0x" + QString::number(results.Results.LastTestedBaseAddress, 16) + ")"); - */ + m_status->setText("Aborted by user (Last Base: 0x" + QString::number(results.LastTestedBaseAddress, 16) + ")"); if (results.Scores.empty()) { @@ -159,27 +162,25 @@ void BaseAddressDetectionWidget::HandleResults(const BaseAddressDetectionQtResul } m_resultsTableWidget->clearContents(); - /* TODO size_t numRows = 0; - for (auto rit = results.Results.Scores.rbegin(); rit != results.Results.Scores.rend(); rit++) - numRows += results.Results.Reasons.at(rit->second).size(); + for (auto rit = results.Scores.rbegin(); rit != results.Scores.rend(); rit++) + numRows += results.Reasons.at(rit->second).size(); m_resultsTableWidget->setRowCount(numRows); size_t row = 0; - for (auto rit = results.Results.Scores.rbegin(); rit != results.Results.Scores.rend(); rit++) + for (auto rit = results.Scores.rbegin(); rit != results.Scores.rend(); rit++) { auto [score, baseaddr] = *rit; - for (const auto& reason : results.Results.Reasons.at(baseaddr)) + for (const auto& reason : results.Reasons.at(baseaddr)) { m_resultsTableWidget->setItem(row, 0, new QTableWidgetItem("0x" + QString::number(baseaddr, 16))); m_resultsTableWidget->setItem(row, 1, new QTableWidgetItem("0x" + QString::number(reason.Pointer, 16))); m_resultsTableWidget->setItem(row, 2, new QTableWidgetItem("0x" + QString::number(reason.POIOffset, 16))); m_resultsTableWidget->setItem(row, 3, new QTableWidgetItem( - QString::fromStdString(BaseAddressDetectionPOITypeToString(reason.BaseAddressDetectionPOIType)))); + QString::fromStdString(BaseAddressDetectionPOITypeToString(reason.POIType)))); row++; } } - */ m_detectBaseAddressButton->setEnabled(true); m_abortButton->setHidden(true); diff --git a/examples/triage/baseaddress.h b/examples/triage/baseaddress.h index aa5e70ab..f6dc79f1 100644 --- a/examples/triage/baseaddress.h +++ b/examples/triage/baseaddress.h @@ -28,7 +28,9 @@ struct BaseAddressDetectionQtResults { std::string Status; std::set<std::pair<size_t, uint64_t>> Scores; - BinaryNinja::BaseAddressDetectionConfidence Confidence; + BNBaseAddressDetectionConfidence Confidence; + std::map<uint64_t, std::vector<BNBaseAddressDetectionReason>> Reasons; + uint64_t LastTestedBaseAddress; }; class BaseAddressDetectionThread : public QThread |
