Skip to content

Commit

Permalink
Merge pull request #21 from ergrelet/feature/syscall_tracing
Browse files Browse the repository at this point in the history
Implement logging of inline syscall instructions
  • Loading branch information
hasherezade authored Feb 14, 2022
2 parents d275b36 + f94c01f commit 235773f
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
A Pin Tool for tracing:
+ API calls, including [parameters of selected functions](https://github.com/hasherezade/tiny_tracer/wiki/Tracing-parameters-of-functions)
+ selected instructions: [RDTSC](https://c9x.me/x86/html/file_module_x86_id_278.html), [CPUID](https://c9x.me/x86/html/file_module_x86_id_45.html)
+ inline system calls
+ transition between sections of the traced module (helpful in finding OEP of the packed module)

Bypasses the anti-tracing check based on RDTSC.
Expand Down
5 changes: 5 additions & 0 deletions Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#define KEY_FOLLOW_SHELLCODES "FOLLOW_SHELLCODES"
#define KEY_LOG_RTDSC "TRACE_RDTSC"
#define KEY_LOG_SYSCALL "TRACE_SYSCALL"
#define KEY_LOG_SECTIONS_TRANSITIONS "LOG_SECTIONS_TRANSITIONS"
#define KEY_LOG_SHELLCODES_TRANSITIONS "LOG_SHELLCODES_TRANSITIONS"
#define KEY_SHORT_LOGGING "ENABLE_SHORT_LOGGING"
Expand Down Expand Up @@ -64,6 +65,10 @@ bool fillSettings(Settings &s, std::string line)
s.traceRDTSC = loadBoolean(valStr, s.traceRDTSC);
isFilled = true;
}
if (util::iequals(valName, KEY_LOG_SYSCALL)) {
s.traceSYSCALL = loadBoolean(valStr, s.traceSYSCALL);
isFilled = true;
}
if (util::iequals(valName, KEY_LOG_SECTIONS_TRANSITIONS)) {
s.logSectTrans = loadBoolean(valStr, s.logSectTrans);
isFilled = true;
Expand Down
2 changes: 2 additions & 0 deletions Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class Settings {
Settings()
: followShellcode(SHELLC_FOLLOW_FIRST),
traceRDTSC(false),
traceSYSCALL(false),
logSectTrans(true),
logShelcTrans(true),
logIndirect(false),
Expand All @@ -32,6 +33,7 @@ class Settings {
t_shellc_options followShellcode;

bool traceRDTSC; // Trace RDTSC
bool traceSYSCALL; // Trace syscall instructions (i.e., syscall, int 2Eh, sysenter)
bool logSectTrans; // watch transitions between sections
bool logShelcTrans; // watch transitions between shellcodes
bool shortLogging; // Use short call logging (without a full DLL path)
Expand Down
47 changes: 47 additions & 0 deletions TinyTracer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,47 @@ VOID CpuidCalled(const CONTEXT* ctxt)
}
}

VOID SyscallCalled(THREADID tid, CONTEXT* ctxt, SYSCALL_STANDARD std, VOID* v)
{
PinLocker locker;

const auto address = [&]() -> ADDRINT {
if (std == SYSCALL_STANDARD_WOW64) {
// Note: In this case, the current instruction address is in a 64-bit
// code portion. The address that we're interested in is the return
// address, which is in a 32-bit code portion.
const auto* stackPtr = reinterpret_cast<ADDRINT*>(PIN_GetContextReg(ctxt, REG_STACK_PTR));
ADDRINT retAddr = 0;
PIN_SafeCopy(&retAddr, stackPtr, sizeof(retAddr));
return retAddr;
}
return PIN_GetContextReg(ctxt, REG_INST_PTR);
}();

const auto syscallNum = [&]() -> ADDRINT {
if (std == SYSCALL_STANDARD_WINDOWS_INT) {
// Note: Somehow `PIN_GetSyscallNumber` doesn't return the correct
// result in this case.
return PIN_GetContextReg(ctxt, REG_GAX);
}
return PIN_GetSyscallNumber(ctxt, std);
}();

const IMG currModule = IMG_FindByAddress(address);
const bool isCurrMy = pInfo.isMyAddress(address);
if (isCurrMy) {
ADDRINT rva = addr_to_rva(address); // convert to RVA
traceLog.logSyscall(0, rva, syscallNum);
}
if (m_Settings.followShellcode && !IMG_Valid(currModule)) {
const ADDRINT start = query_region_base(address);
ADDRINT rva = address - start;
if (start != UNKNOWN_ADDR) {
traceLog.logSyscall(start, rva, syscallNum);
}
}
}

ADDRINT _setTimer(const CONTEXT* ctxt, bool isEax)
{
static UINT64 Timer = 0;
Expand Down Expand Up @@ -667,6 +708,12 @@ int main(int argc, char *argv[])
// Register function to be called before every instruction
INS_AddInstrumentFunction(InstrumentInstruction, NULL);

if (m_Settings.traceSYSCALL) {
// Register function to be called before every syscall instruction
// (i.e., syscall, sysenter, int 2Eh)
PIN_AddSyscallEntryFunction(SyscallCalled, NULL);
}

// Register context changes
PIN_AddContextChangeFunction(OnCtxChange, NULL);

Expand Down
16 changes: 15 additions & 1 deletion TraceLog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ void TraceLog::logRdtsc(const ADDRINT base, const ADDRINT rva)
m_traceFile.flush();
}


void TraceLog::logCpuid(const ADDRINT base, const ADDRINT rva, const ADDRINT param)
{
if (!createFile()) return;
Expand All @@ -125,6 +124,21 @@ void TraceLog::logCpuid(const ADDRINT base, const ADDRINT rva, const ADDRINT par
m_traceFile.flush();
}

void TraceLog::logSyscall(const ADDRINT base, const ADDRINT rva, const ADDRINT param)
{
if (!createFile()) return;
if (base) {
m_traceFile << "> " << std::hex << base << "+";
}
m_traceFile
<< std::hex << rva
<< DELIMITER
<< "SYSCALL:"
<< std::hex << param
<< std::endl;
m_traceFile.flush();
}

void TraceLog::logLine(std::string str)
{
if (!createFile()) return;
Expand Down
1 change: 1 addition & 0 deletions TraceLog.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class TraceLog
void logIndirectCall(const ADDRINT prevModuleBase, const ADDRINT prevAddr, bool isRVA, const ADDRINT calledBase, const ADDRINT callRVA);
void logRdtsc(const ADDRINT base, const ADDRINT rva);
void logCpuid(const ADDRINT base, const ADDRINT rva, const ADDRINT param);
void logSyscall(const ADDRINT base, const ADDRINT rva, const ADDRINT param);

void logLine(std::string str);

Expand Down
1 change: 1 addition & 0 deletions install32_64/TinyTracer.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ FOLLOW_SHELLCODES=1
; 2 : follow also the shellcodes called recursively from the the original shellcode
; 3 : follow any shellcodes
TRACE_RDTSC=False
TRACE_SYSCALL=True
LOG_SECTIONS_TRANSITIONS=True
LOG_SHELLCODES_TRANSITIONS=True
HEXDUMP_SIZE=8
Expand Down

0 comments on commit 235773f

Please sign in to comment.