Skip to content

Commit

Permalink
Refactor & Implementation & Cleanup
Browse files Browse the repository at this point in the history
Refactored CapstoneTool, Implemented ARM Thumb, added the capability to add modes
  • Loading branch information
pinwhell committed Aug 24, 2023
1 parent c4efe20 commit a1d933e
Show file tree
Hide file tree
Showing 32 changed files with 300 additions and 115 deletions.
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"files.associations": {
"*.embeddedhtml": "html",
"xiosbase": "cpp"
}
}
43 changes: 32 additions & 11 deletions OffsetHunter/Arm32CapstoneHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ bool Arm32CapstoneHelper::PCRelInstAddrRebaseRoot()
return false;
}

bool Arm32CapstoneHelper::InterpretDispInst(cs_insn* pInst, uintptr_t& outDisp)
bool Arm32CapstoneHelper::GetInstructionDisp(cs_insn* pInst, uintptr_t& outDisp)
{
switch (pInst->id)
{

case ARM_INS_LDR:
case ARM_INS_LDRH:
case ARM_INS_LDRD:
case ARM_INS_LDRB:
case ARM_INS_LDRBT:
case ARM_INS_LDREXB:
{
if (ArmCapstoneAux::GetRValueRegType(pInst) == ARM_REG_PC) return TryInterpretDispPCRelative(pInst, outDisp);
if (ArmCapstoneAux::GetRValueRegType(pInst) == ARM_REG_PC) return DisasmTrySolvePositionIndependentAddress(pInst, outDisp);
else outDisp = pInst->detail->arm.operands[pInst->detail->arm.op_count - 1].mem.disp;
} break;

Expand All @@ -45,6 +45,7 @@ bool Arm32CapstoneHelper::InterpretDispInst(cs_insn* pInst, uintptr_t& outDisp)
} break;

case ARM_INS_ADD:
case ARM_INS_SUB:
{
outDisp = pInst->detail->arm.operands[pInst->detail->arm.op_count - 1].imm;
}break;
Expand Down Expand Up @@ -80,14 +81,23 @@ bool Arm32CapstoneHelper::InterpretDispInst(cs_insn* pInst, uintptr_t& outDisp)
return true;
}

bool Arm32CapstoneHelper::InterpretDispPCRelativeInst(cs_insn* pInstBegin, cs_insn* pInstEnd, uintptr_t& outDisp)
bool Arm32CapstoneHelper::SolvePositionIndependentAddress(cs_insn* pInstBegin, cs_insn* pInstEnd, uintptr_t& outDisp)
{
if ((pInstBegin + 1 < pInstEnd) == false)

// We cant precisely calculate PC Relative

return false;

uint16_t regPcRelOffHolderType = ArmCapstoneAux::GetLValueRegType(pInstBegin);
uintptr_t targetPcRelOff = ArmCapstoneAux::ResolvePCRelative((unsigned char*)pInstBegin->address, pInstBegin->detail->arm.operands[pInstBegin->detail->arm.op_count - 1].mem.disp);
uintptr_t targetPcRelOff = *(uint32_t*)(getPcFromInstruction(pInstBegin) + pInstBegin->detail->arm.operands[pInstBegin->detail->arm.op_count - 1].mem.disp);

for (auto* pCurrInst = pInstBegin + 1; pCurrInst < pInstEnd; pCurrInst++)
{

uint64_t currInstPc = getPcFromInstruction(pCurrInst);
uint64_t currInstPcBinRelOff = currInstPc - mBase;

switch (pCurrInst->id) {

case ARM_INS_LDR:
Expand All @@ -96,20 +106,24 @@ bool Arm32CapstoneHelper::InterpretDispPCRelativeInst(cs_insn* pInstBegin, cs_in
if (pCurrInst->detail->arm.operands[1].mem.base == ARM_REG_PC &&
pCurrInst->detail->arm.operands[1].mem.index == regPcRelOffHolderType)
{
outDisp = (uintptr_t(pCurrInst->address) + 0x8 + targetPcRelOff) - uintptr_t(mpBase);
outDisp = currInstPcBinRelOff + targetPcRelOff;

return true;
}
}break;

case ARM_INS_ADD:
{
if ((pCurrInst->detail->arm.operands[1].reg == ARM_REG_PC &&
pCurrInst->detail->arm.operands[2].reg == regPcRelOffHolderType) ||
(pCurrInst->detail->arm.operands[2].reg == ARM_REG_PC &&
pCurrInst->detail->arm.operands[1].reg == regPcRelOffHolderType))
if (( /*ADD R0, PC*/
pCurrInst->detail->arm.operands[1].reg == ARM_REG_PC &&
pCurrInst->detail->arm.operands[0].reg == regPcRelOffHolderType
) ||
( /*ADD R0, R0, PC*/
pCurrInst->detail->arm.operands[2].reg == ARM_REG_PC &&
pCurrInst->detail->arm.operands[1].reg == regPcRelOffHolderType
))
{
outDisp = (uintptr_t(pCurrInst->address) + 0x8 + targetPcRelOff) - uintptr_t(mpBase);
outDisp = currInstPcBinRelOff + targetPcRelOff;

return true;
}
Expand Down Expand Up @@ -147,3 +161,10 @@ bool Arm32CapstoneHelper::IsIntructionPrologRelated(cs_insn* pInst)
{
return ArmCapstoneAux::HeuristicProlog(pInst);
}

uint64_t Arm32CapstoneHelper::getPcFromInstruction(cs_insn* inst)
{
return inst->address + inst[0].size + inst[1].size;
}


5 changes: 3 additions & 2 deletions OffsetHunter/Arm32CapstoneHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ class Arm32CapstoneHelper : public ICapstoneHelper

bool PCRelInstAddrRebaseRoot();

bool InterpretDispInst(cs_insn* pInst, uintptr_t& outDisp) override;
bool InterpretDispPCRelativeInst(cs_insn* pInst, cs_insn* pInstEnd, uintptr_t& outDisp) override;
bool GetInstructionDisp(cs_insn* pInst, uintptr_t& outDisp) override;
bool SolvePositionIndependentAddress(cs_insn* pInst, cs_insn* pInstEnd, uintptr_t& outDisp) override;
bool GetCallDestinationInst(cs_insn* pInst, uintptr_t& outDest) override;
bool IsIntructionReturnRelated(cs_insn* pInst) override;
bool IsIntructionPrologRelated(cs_insn* pInst) override;
uint64_t getPcFromInstruction(cs_insn* inst) override;
};

9 changes: 1 addition & 8 deletions OffsetHunter/Arm32CapstoneHelperFactory.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
#include "Arm32CapstoneHelperFactory.h"
#include "ICapstoneHelper.h"
#include "Arm32CapstoneHelper.h"

Arm32CapstoneHelperFactory::Arm32CapstoneHelperFactory(bool bIsThumb)
: mIsThumb(bIsThumb)
{
}

ICapstoneHelper* Arm32CapstoneHelperFactory::MakeHelper()
{
if (mIsThumb == false)
return new Arm32CapstoneHelper();
return new Arm32CapstoneHelper();
}
3 changes: 0 additions & 3 deletions OffsetHunter/Arm32CapstoneHelperFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
class Arm32CapstoneHelperFactory : public ICapstoneHelperFactory
{
private:
bool mIsThumb;
public:
Arm32CapstoneHelperFactory(bool bIsThumb = false);

ICapstoneHelper* MakeHelper() override;
};

7 changes: 7 additions & 0 deletions OffsetHunter/Arm32ThumbCapstoneHelper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include "Arm32ThumbCapstoneHelper.h"

Arm32ThumbCapstoneHelper::Arm32ThumbCapstoneHelper()
: Arm32CapstoneHelper()
{
setMode(CS_MODE_THUMB);
}
9 changes: 9 additions & 0 deletions OffsetHunter/Arm32ThumbCapstoneHelper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

#include "Arm32CapstoneHelper.h"

class Arm32ThumbCapstoneHelper : public Arm32CapstoneHelper
{
public:
Arm32ThumbCapstoneHelper();
};
7 changes: 7 additions & 0 deletions OffsetHunter/Arm32ThumbCapstoneHelperFactory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include "Arm32ThumbCapstoneHelperFactory.h"
#include "Arm32ThumbCapstoneHelper.h"

ICapstoneHelper* Arm32ThumbCapstoneHelperFactory::MakeHelper()
{
return new Arm32ThumbCapstoneHelper();
}
10 changes: 10 additions & 0 deletions OffsetHunter/Arm32ThumbCapstoneHelperFactory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#include "ICapstoneHelperFactory.h"

class Arm32ThumbCapstoneHelperFactory : public ICapstoneHelperFactory
{
public:
ICapstoneHelper* MakeHelper() override;
};

8 changes: 5 additions & 3 deletions OffsetHunter/DumpTargetGroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ void DumpTargetGroup::ComputeAll()
{
printf("Computing %s\n", kv.second->getCategoryName().c_str());

tp.enqueue([&](SingleDumpTarget* pSingDumpTarg) {
pSingDumpTarg->ComputeAll();
}, kv.second.get());
kv.second->ComputeAll();

/*tp.enqueue([&](SingleDumpTarget* pSingDumpTarg) {
}, kv.second.get());*/
}
}

Expand Down
14 changes: 12 additions & 2 deletions OffsetHunter/ELF32BinaryFormat.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
#include "ELF32BinaryFormat.h"
#include "Arm32CapstoneHelperFactory.h"
#include "Arm32ThumbCapstoneHelperFactory.h"

bool ELF32BinaryFormat::MakeCapstoneHelper(CapstoneHelperProvider* pProvider, ICapstoneHelper** outHelper)
bool ELF32BinaryFormat::MakeCapstoneHelper(CapstoneHelperProvider* pProvider, ICapstoneHelper** outHelper, std::string mode)
{
if (outHelper == nullptr)
return false;

*outHelper = pProvider->getInstance(std::make_unique<Arm32CapstoneHelperFactory>());
*outHelper = nullptr;

if (mode == "default")
mode = "arm";

if (mode == "arm")
*outHelper = pProvider->getInstance(std::make_unique<Arm32CapstoneHelperFactory>());

if (mode == "thumb")
*outHelper = pProvider->getInstance(std::make_unique<Arm32ThumbCapstoneHelperFactory>());

return *outHelper != nullptr;
}
2 changes: 1 addition & 1 deletion OffsetHunter/ELF32BinaryFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ class ELF32BinaryFormat : public IBinaryFormatImpl<elf32_hdr>
private:

public:
bool MakeCapstoneHelper(CapstoneHelperProvider* pProvider, ICapstoneHelper** outHelper) override;
bool MakeCapstoneHelper(CapstoneHelperProvider* pProvider, ICapstoneHelper** outHelper, std::string mode = "default") override;
};

28 changes: 21 additions & 7 deletions OffsetHunter/FutureOffset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,37 @@ void FutureOffset::OnNotFound()

void FutureOffset::OnMultipleFound()
{
onNotSucessComputing();
auto name = mpFutureResultInfo->getUidentifier();
printf("\"%s\" with %d Results\n", name.c_str(), mScanAlgo->getResults().size());
if (getFutureResultInfo()->CanPickAnyResult() == false)
{
onNotSucessComputing();
auto name = mpFutureResultInfo->getUidentifier();
printf("\"%s\" with %d Results\n", name.c_str(), mScanAlgo->getResults().size());

return;
}

mFutureResultInfo.setFinalOffset(getFirstResult()); // Picking the first
onSucessfullyComputed();
}

uintptr_t FutureOffset::getSingleResult()
{
if (mScanAlgo->getResults().size() != 1)
return 0;

return getFirstResult();
}

uintptr_t FutureOffset::getFirstResult()
{
return *(mScanAlgo->getResults().begin());
}

ICapstoneHelper* FutureOffset::getCapstoneHelper()
{
return mParent->getCapstoneHelper(mScanAlgo->getCapstoneMode());
}

bool FutureOffset::Init()
{
if (IFutureResult::Init() == false)
Expand All @@ -49,10 +67,6 @@ bool FutureOffset::Init()
if (mScanAlgo->Init() == false)
return false;

mNeedCapstone = mScanAlgo->getNeedCapstone();

//printf("\t%s Need Capstone: %s\n", getName().c_str(), mNeedCapstone ? "Yes" : "No");

return true;
}

Expand Down
5 changes: 5 additions & 0 deletions OffsetHunter/FutureOffset.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "FutureOffsetResultInfo.h"
#include <memory>

class ICapstoneHelper;

class FutureOffset : public IFutureResultImpl<FutureOffsetResultInfo>, public IScanListener
{
private:
Expand All @@ -21,6 +23,9 @@ class FutureOffset : public IFutureResultImpl<FutureOffsetResultInfo>, public IS
void OnNotFound();
void OnMultipleFound();
uintptr_t getSingleResult();
uintptr_t getFirstResult();

ICapstoneHelper* getCapstoneHelper();

void IgniteScan();
void Compute() override;
Expand Down
34 changes: 30 additions & 4 deletions OffsetHunter/FutureResultClassifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,37 @@ void FutureResultClassifier::Classify(JsonValueWrapper& metadata, std::unique_pt
bool bContainsCombine = JSON_ASSERT(metadata, "combine");
bool bContainsPattern = JSON_ASSERT(metadata, "pattern");

if (bContainsValue == true ||
bContainsCombine && bContainsPattern == false)
outOffset = std::move(std::make_unique<HardcodedResultInfo>());
else
/*Hardcoded*/
int hardcodedResultInfoScore = 0;

if (bContainsCombine == true)
hardcodedResultInfoScore += 1;

if (bContainsValue == true)
hardcodedResultInfoScore += 1;

if (bContainsPattern == true)
hardcodedResultInfoScore -= 1;

/*Finded*/
int FutureOffsetScore = 0;

/*Hardcoded*/
if (bContainsCombine == true)
FutureOffsetScore += 1;

if (bContainsValue == true)
FutureOffsetScore += 1;

if (bContainsPattern == true)
FutureOffsetScore += 1;


if (FutureOffsetScore > hardcodedResultInfoScore)
outOffset = std::move(std::make_unique<FutureOffset>());
else
outOffset = std::move(std::make_unique<HardcodedResultInfo>());


outOffset->setMetadata(metadata);
}
2 changes: 1 addition & 1 deletion OffsetHunter/IBinaryFormat.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "IBinaryFormat.h"

bool IBinaryFormat::MakeCapstoneHelper(CapstoneHelperProvider* pProvider, ICapstoneHelper** outHelper)
bool IBinaryFormat::MakeCapstoneHelper(CapstoneHelperProvider* pProvider, ICapstoneHelper** outHelper, std::string mode)
{
return false;
}
Expand Down
3 changes: 2 additions & 1 deletion OffsetHunter/IBinaryFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <cstdint>
#include "ICapstoneHelper.h"
#include "CapstoneHelperProvider.h"
#include <string>

class IBinaryFormat {

Expand All @@ -13,7 +14,7 @@ class IBinaryFormat {
};

public:
virtual bool MakeCapstoneHelper(CapstoneHelperProvider* pProvider, ICapstoneHelper** outHelper);
virtual bool MakeCapstoneHelper(CapstoneHelperProvider* pProvider, ICapstoneHelper** outHelper, std::string mode = "default");

void setBase(uintptr_t base);
void setBase(void* base);
Expand Down
Loading

0 comments on commit a1d933e

Please sign in to comment.