Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
pinwhell committed Jun 6, 2024
2 parents 1e392f5 + 2e37564 commit 87e6ab9
Show file tree
Hide file tree
Showing 19 changed files with 223 additions and 32 deletions.
8 changes: 8 additions & 0 deletions include/FunctionScanConfig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

#include <PatternScanConfig.h>

struct FunctionScanConfig {
PatternScanConfig mScanConfig;
size_t mDefSize;
};
52 changes: 52 additions & 0 deletions include/MHTRSDK/MHTRSDK.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#pragma once

#include <cstdint>
#include <unordered_map>
#include <variant>
#include <string>
#include <iterator>

namespace MHTR {
using Metadata = std::variant<std::string, uint64_t>;
using MetadataMap = std::unordered_map<std::string, Metadata>;

class MetadataProvider {
public:
inline MetadataProvider()
{}

inline MetadataProvider(MetadataMap&& metadatas)
: mMetadatas(std::move(metadatas))
{}

inline MetadataProvider(MetadataProvider&& other) noexcept {
mMetadatas = std::move(other.mMetadatas);
}

inline uint64_t GetOffset(const std::string& key)
{
return std::get<uint64_t>(mMetadatas[key]);
}

inline std::string GetPattern(const std::string& key)
{
return std::get<std::string>(mMetadatas[key]);
}

inline MetadataProvider& operator+(MetadataProvider&& other)
{
*this += std::move(other);
return *this;
}

inline void operator+=(MetadataProvider&& other)
{
for (auto& [key, value] : other.mMetadatas) {
mMetadatas[key] = std::move(value);
}
other.mMetadatas.clear();
}

MetadataMap mMetadatas;
};
}
9 changes: 9 additions & 0 deletions include/MetadataSynthers.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,14 @@ class MultiNsMultiMetadataReportSynther : public IMultiLineSynthesizer {

std::vector<std::string> Synth() const override;

std::vector<MetadataTarget*> mTargets;
};

class HppStaticReport : public IMultiLineSynthesizer {
public:
HppStaticReport(const std::vector<MetadataTarget*>& targets);

std::vector<std::string> Synth() const override;

std::vector<MetadataTarget*> mTargets;
};
3 changes: 2 additions & 1 deletion include/Provider/ProcedureRange.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@

class ProcedureRangeProvider : public IRangeProvider {
public:
ProcedureRangeProvider(ICapstoneProvider* cstoneProvider, IProcedureEntryProvider* procEntryProvider);
ProcedureRangeProvider(ICapstoneProvider* cstoneProvider, IProcedureEntryProvider* procEntryProvider, size_t defProcSize = 0);

Range GetRange() override;

ICapstoneProvider* mCStoneProvider;
IProcedureEntryProvider* mProcEntryProvider;
size_t mDefProcSize;
};
4 changes: 2 additions & 2 deletions include/Provider/ProcedureRangeChain.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
#include <Storage.h>
#include <Provider/IRange.h>
#include <CStone/IProvider.h>
#include <PatternScanConfig.h>
#include <FunctionScanConfig.h>
#include <vector>

class ProcedureRangeProviderChain : public IRangeProvider {
public:
ProcedureRangeProviderChain(ICapstoneProvider* cstoneInstanceProvider, IRangeProvider* baseRangeProvider, const std::vector<PatternScanConfig>& nestedProcedurePatterns);
ProcedureRangeProviderChain(ICapstoneProvider* cstoneInstanceProvider, IRangeProvider* baseRangeProvider, const std::vector<FunctionScanConfig>& nestedProcedurePatterns);

Range GetRange() override;

Expand Down
2 changes: 2 additions & 0 deletions include/Synther/Line.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ class Line : public ILineSynthesizer {
// Inherited via ILineSynthesizer
std::string Synth() const override;

static Line Empty();

std::string mLine;
};
60 changes: 47 additions & 13 deletions samples/libdummy.json
Original file line number Diff line number Diff line change
@@ -1,28 +1,62 @@
[
{
"name": "Foo",
"name": "Bar",
"type": "INSN_IMM",
"immIndex": 1,
"pattern": "AA BB CC",
"disp": -5,
"pattern": "42 00 ? B9",
"disp": -2,
"immIndex": 0,

"scanRange": "Bar"
"scanRange": "FooFuncRange"
},
{
"name": "Bar",
"name": "BarPattern",
"type": "PATTERN_VALIDATE",
"pattern": "42 00 ? B9",
"disp": -2,

"scanRange": "FooFuncRange"
},
{
"name": "BarPatternResult",
"type": "PATTERN_SINGLE_RESULT",
"pattern": "42 00 ? B9",
"disp": -2,

"scanRange": "FooFuncRange"
},
{
"name": "Baz",
"type": "FAR_ADDR",
"pattern": "49 78 44 ? 4A ? 4B",
"disp": -1,

"scanRange": "FooFuncRange"
},
{
"name": "Foo",
"type": "PATTERN_SINGLE_RESULT",
"pattern": "20 0B C0 EC",

"scanRange": "BarRange"
},
{
"name": "FooFuncRange",
"scanRange": [
{
"defFnSize": 10,
"defFnSize": 162,
"pattern": {
"pattern": "AA BB C? D? ? E?",
"disp": -10
"pattern": "08 30 00 F0 57 B9",
"disp": 2
}
},
}
]
},
{
"name": "BarRange",
"scanRange": [
{
"defFnSize": 10,
"pattern": {
"pattern": "AA BB C? D? ? E?",
"disp": -10
"pattern": "FF F7 8C ED 10 E0"
}
}
]
Expand Down
11 changes: 11 additions & 0 deletions samples/result.report.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

#include <cstdint>

namespace Dummy {
constexpr auto BarPattern = "42 00 ? B9";
constexpr uint64_t BarPatternResult = 0x1A94;
constexpr uint64_t Baz = 0x2640;
constexpr uint64_t Foo = 0x15B0;
constexpr uint64_t Bar = 0x42;
}
8 changes: 8 additions & 0 deletions samples/result.report.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Dummy:
{
BarPattern: "42 00 ? B9"
BarPatternResult: 0x1a94
Baz: 0x2640
Foo: 0x15b0
Bar: 0x42
}
Binary file added samples/samples.zip
Binary file not shown.
2 changes: 1 addition & 1 deletion src/CLI/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
add_executable(MHCLI main.cpp "MH.cpp")
add_executable(MHCLI main.cpp MH.cpp)

target_link_libraries(MHCLI MetadataHunter cxxopts BSThreadPool)
17 changes: 16 additions & 1 deletion src/CLI/MH.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ MHCLI::MHCLI(int argc, const char** argv)
{
mCLIOptions.add_options()
("r,report", "Output result report", cxxopts::value<std::string>(), "[output path]")
("rhpp,report-hpp", "Output result report to hpp file", cxxopts::value<std::string>(), "[output path]")
("t,targets", "JSON targets path", cxxopts::value<std::string>())
("j,threads", "Number of threads", cxxopts::value<int>(DEFAULT_NTHREADS)->default_value("1"))
("h,help", "Print help");
Expand Down Expand Up @@ -90,6 +91,12 @@ int MHCLI::Run()
return ptr.get();
});

std::unordered_set<MetadataTarget*> allTargets;

std::transform(allLookablesPtr.begin(), allLookablesPtr.end(), std::inserter(allTargets, allTargets.end()), [](ILookableMetadata* metadata) {
return metadata->GetTarget();
});

{
BS::thread_pool pool(nThreads);

Expand All @@ -106,7 +113,7 @@ int MHCLI::Run()
}
catch (const std::exception& e)
{
std::cerr << fmt::format("warning: '{}':{}\n", lookable->GetTarget()->GetFullName(), e.what());
std::cerr << fmt::format("'{}':{}\n", lookable->GetTarget()->GetFullName(), e.what());
}
});
}
Expand All @@ -125,5 +132,13 @@ int MHCLI::Run()
FileWrite(mCLIParseRes["report"].as<std::string>(), &reportSynther);
}

if (mCLIParseRes.count("report-hpp"))
{
HppStaticReport report(foundTargetVec);
FileWrite(mCLIParseRes["report-hpp"].as<std::string>(), &report);
}

std::cout << fmt::format("{}/{} targets successful.", foundTargets.size(), allTargets.size()) << std::endl;

return 0;
}
17 changes: 11 additions & 6 deletions src/IR/ToMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ std::vector<std::unique_ptr<ILookableMetadata>> FromIRMultiMetadataFactory::Prod
});

std::vector<std::unique_ptr<ILookableMetadata>> result;
std::unordered_set<std::string> uids;

for (MetadataIR* metadata : allMetadataPtr)
{
Expand Down Expand Up @@ -163,19 +164,23 @@ IRangeProvider* FromIRMultiMetadataFactory::CreateScanRangeFromIR(const ScanRang

IRangeProvider* FromIRMultiMetadataFactory::CreateScanRangePipelineFromIR(const MetadataScanRangePipelineIR& pipeline)
{
std::vector<PatternScanConfig> configs;
std::vector<FunctionScanConfig> configs;

for (const auto& stage : pipeline.mStages)
{
if (!std::holds_alternative<MetadataScanRangeStageFunctionIR>(stage.mStage))
throw std::logic_error(fmt::format("Unimplemented Stage detected"));

const auto& scanCFG = std::get<MetadataScanRangeStageFunctionIR>(stage.mStage).mScanCFG;
const auto& fnStage = std::get<MetadataScanRangeStageFunctionIR>(stage.mStage);
const auto& scanCFG = fnStage.mScanCFG;

configs.emplace_back(std::move(PatternScanConfig(
scanCFG.mPattern,
scanCFG.mDisp
)));
configs.emplace_back(std::move(FunctionScanConfig{
PatternScanConfig(
scanCFG.mPattern,
scanCFG.mDisp
),
fnStage.mDefFnSize
}));
}

return (IRangeProvider*)mProvidersStorage.Store(std::make_unique<ProcedureRangeProviderChain>(mCapstoneProvider, mDefaultScanRange, configs)).get();
Expand Down
33 changes: 32 additions & 1 deletion src/MetadataSynthers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <iterator>
#include <Synther/Line.h>
#include <algorithm>
#include <Synther/MultiLineGroup.h>

template<typename T>
std::string Literal(T str)
Expand Down Expand Up @@ -91,11 +92,16 @@ std::vector<std::string> MultiMetadataReportSynther::Synth() const {
std::vector<Line> content;

std::transform(mTargets.begin(), mTargets.end(), std::back_inserter(content), [](MetadataTarget* target) {
const auto& result = target->mResult;
bool bIsPattern = std::holds_alternative<PatternMetadata>(result.mMetadata);
auto resultStr = target->mResult.ToString(); resultStr = bIsPattern ? Literal(resultStr) : resultStr;

return fmt::format(
"{}: {}",
target->GetName(),
target->mHasResult
? target->mResult.ToString()
? resultStr

: "Not found."
);
});
Expand Down Expand Up @@ -134,4 +140,29 @@ std::vector<std::string> MultiNsMultiMetadataReportSynther::Synth() const {
}

return result;
}

HppStaticReport::HppStaticReport(const std::vector<MetadataTarget*>& targets)
: mTargets(targets)
{}

std::vector<std::string> HppStaticReport::Synth() const
{
Line pragmaOnce("#pragma once");
Line emptyLine(Line::Empty());
Line includeCstdint("#include <cstdint>");
LineSynthesizerGroup headerGroup({
&pragmaOnce,
&emptyLine,
&includeCstdint,
&emptyLine
});
MultiNsMultiMetadataStaticSynther allNsSynther(mTargets);

MultiLineSynthesizerGroup synthGroup({
&headerGroup,
&allNsSynther,
});

return synthGroup.Synth();
}
2 changes: 1 addition & 1 deletion src/OffsetCalculator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ OffsetCalculator::OffsetCalculator(IRangeProvider* rangeProvider)
uint64_t OffsetCalculator::ComputeOffset(const void* at)
{
auto range = mRangeProvider->GetRange();
return (uint64_t)(range.GetStart<char*>() - (char*)at);
return (uint64_t)((char*)at - range.GetStart<char*>());
}
9 changes: 8 additions & 1 deletion src/Provider/ProcedureRange.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
#include <Provider/ProcedureRange.h>
#include <stdexcept>

ProcedureRangeProvider::ProcedureRangeProvider(ICapstoneProvider* cstoneProvider, IProcedureEntryProvider* procEntryProvider)
ProcedureRangeProvider::ProcedureRangeProvider(ICapstoneProvider* cstoneProvider, IProcedureEntryProvider* procEntryProvider, size_t defProcSize)
: mCStoneProvider(cstoneProvider)
, mProcEntryProvider(procEntryProvider)
, mDefProcSize(defProcSize)
{}

Range ProcedureRangeProvider::GetRange() {

uint64_t procEntry = mProcEntryProvider->GetEntry();

if (mDefProcSize != 0)
// Procedure size seems already known
return Range((void*)mProcEntryProvider->GetEntry(), mDefProcSize);

uint64_t procEnd = 0;
ICapstone* cstone = mCStoneProvider->GetInstance();
ICapstoneHeuristic* heuristic = cstone->getHeuristic();
Expand Down
Loading

0 comments on commit 87e6ab9

Please sign in to comment.