Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] AntiDebug Software Breakpoints detection #43

Merged
merged 4 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions AntiDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,36 @@ std::map<std::string, std::string> funcToLink;

typedef VOID AntiDBGCallBack(const ADDRINT Address, const CHAR* name, uint32_t argCount, VOID* arg1, VOID* arg2, VOID* arg3, VOID* arg4, VOID* arg5);

/* ==================================================================== */
// Compute Effective Address, given an INS
/* ==================================================================== */

ADDRINT computeEA(const CONTEXT* ctxt, INS ins, UINT32 opIdx)
{
REG baseReg = INS_OperandMemoryBaseReg(ins, opIdx);
REG indexReg = INS_OperandMemoryIndexReg(ins, opIdx);
INT32 scale = INS_OperandMemoryScale(ins, opIdx);
INT32 disp = INS_OperandMemoryDisplacement(ins, opIdx);

// Calculate the effective memory address
ADDRINT memAddress = 0;
if (baseReg != REG_INVALID())
{
ADDRINT baseValue;
PIN_GetContextRegval(ctxt, baseReg, reinterpret_cast<UINT8*>(&baseValue));
memAddress += baseValue;
}
if (indexReg != REG_INVALID())
{
ADDRINT indexValue;
PIN_GetContextRegval(ctxt, indexReg, reinterpret_cast<UINT8*>(&indexValue));
memAddress += indexValue * scale;
}
memAddress += disp;

return memAddress;
}

/* ==================================================================== */
// Leveraging the existing paramToStr, extracts only the string after '->'
/* ==================================================================== */
Expand Down Expand Up @@ -146,6 +176,43 @@ VOID AntiDbg::WatchMemoryAccess(ADDRINT addr, UINT32 size, const ADDRINT insAddr
#endif
}

/* ==================================================================== */
// Callback function to be executed when a compare is executed
/* ==================================================================== */

std::map<ADDRINT, size_t> cmpOccurrences;
VOID AntiDbg::WatchCompareSoftBrk(const CONTEXT* ctxt, ADDRINT Address, ADDRINT insArg)
{
PinLocker locker;
const WatchedType wType = isWatchedAddress(Address);
if (wType == WatchedType::NOT_WATCHED) return;

INS ins;
ins.q_set(insArg);
if (!ins.is_valid() || INS_OperandCount(ins) < 2) {
return;
}

bool isSet = false;
const UINT32 opIdx = 1;

if (INS_OperandIsImmediate(ins, opIdx) && INS_OperandSize(ins, opIdx) == sizeof(UINT8))
{
UINT8 val = 0;
if ((val = (INS_OperandImmediate(ins, opIdx) & 0xFF)) == 0xCC)
{
cmpOccurrences[Address]++;
if (cmpOccurrences[Address] == 3) isSet = true;
}
}

if (isSet) {
LogAntiDbg(wType, Address, "Software Breakpoint comparison",
"https://anti-debug.checkpoint.com/techniques/process-memory.html#anti-step-over");
}
}


std::set<THREADID> popfThreads;
#define CLEAR_TRAP
VOID AntiDbg::FlagsCheck(const CONTEXT* ctxt, THREADID tid)
Expand Down
1 change: 1 addition & 0 deletions AntiDebug.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace AntiDbg {
VOID WatchMemoryAccess(ADDRINT addr, UINT32 size, const ADDRINT insAddr);
VOID WatchThreadStart(THREADID threadid, CONTEXT* ctxt, INT32 flags, VOID* v);
VOID WatchCompareSoftBrk(const CONTEXT* ctxt, ADDRINT Address, ADDRINT insArg);
VOID MonitorAntiDbgFunctions(IMG Image);
VOID FlagsCheck(const CONTEXT* ctxt, THREADID tid);
VOID FlagsCheck_after(const CONTEXT* ctxt, THREADID tid, ADDRINT eip);
Expand Down
20 changes: 20 additions & 0 deletions TinyTracer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,10 @@ VOID InstrumentInstruction(INS ins, VOID *v)
}
#ifdef USE_ANTIDEBUG
// ANTIDEBUG: memory read instrumentation

////////////////////////////////////
// If AntiDebug level is Standard
////////////////////////////////////
if (m_Settings.antidebug != ANTIDEBUG_DISABLED) {
if (INS_IsMemoryRead(ins)) {
// Insert the callback function before memory read instructions
Expand Down Expand Up @@ -796,6 +800,22 @@ VOID InstrumentInstruction(INS ins, VOID *v)
IARG_END
);
}

////////////////////////////////////
// If AntiDebug level is Deep
////////////////////////////////////
if (m_Settings.antidebug >= ANTIDEBUG_DEEP) {
// Check all comparison for 0xCC byte (anti stepinto/stepover checks)
if (INS_Opcode(ins) == XED_ICLASS_CMP) {
INS_InsertCall(
ins,
IPOINT_BEFORE, (AFUNPTR)AntiDbg::WatchCompareSoftBrk,
IARG_CONTEXT,
IARG_INST_PTR,
IARG_ADDRINT, ins.q(),
IARG_END);
}
}
}
#endif
}
Expand Down