Skip to content

Commit

Permalink
[FEATURE] Check DLL before deciding if it is indirect syscall
Browse files Browse the repository at this point in the history
  • Loading branch information
hasherezade committed Nov 19, 2024
1 parent f593984 commit df50ad3
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 10 deletions.
12 changes: 11 additions & 1 deletion Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ t_shellc_options ConvertShcOption(int value);

class SyscallsTable {
public:
static bool isSyscallFuncName(const std::string name)
static bool isSyscallFuncName(const std::string &name)
{
if (name.length() < 2) return false;
if ((name[0] == 'Z' && name[1] == 'w') ||
Expand All @@ -33,6 +33,16 @@ class SyscallsTable {
return false;
}

static bool isSyscallDll(const std::string& dllName)
{
if (util::iequals("ntdll", dllName)
|| util::iequals("win32u", dllName))
{
return true;
}
return false;
}

static std::string convertNameToNt(std::string funcName)
{
std::string prefix1("Nt");
Expand Down
19 changes: 10 additions & 9 deletions TinyTracer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ VOID SaveHeavensGateTransitions(const ADDRINT addrFrom, const ADDRINT addrTo, AD
PIN_WriteErrorMessage("ERROR: Cannot trace after the far transition", 1000, PIN_ERR_SEVERITY_TYPE::PIN_ERR_FATAL, 0);
}

std::string resolve_func_name(const ADDRINT addrTo, const CONTEXT* ctx)
std::string resolve_func_name(const ADDRINT addrTo, const std::string& dll_name, const CONTEXT* ctx)
{
ADDRINT diff = 0;
const std::string name = get_func_at(addrTo, diff);
Expand All @@ -193,8 +193,11 @@ std::string resolve_func_name(const ADDRINT addrTo, const CONTEXT* ctx)
}
std::ostringstream sstr;
sstr << "[" << name << "+" << std::hex << diff << "]*";

if (ctx && m_Settings.syscallsTable.count() && SyscallsTable::isSyscallFuncName(name)) { //possibly a proxy to the invalid syscall

if (ctx && m_Settings.syscallsTable.count()
&& SyscallsTable::isSyscallFuncName(name) && SyscallsTable::isSyscallDll(util::getDllName(dll_name)))
{
//possibly a proxy to the indirect syscall
const ADDRINT eax = (ADDRINT)PIN_GetContextReg(ctx, REG_GAX);
const std::string realName = m_Settings.syscallsTable.getName(eax);
if (realName.length() && SyscallsTable::convertNameToNt(name) != realName) {
Expand Down Expand Up @@ -226,8 +229,8 @@ VOID _SaveTransitions(const ADDRINT addrFrom, const ADDRINT addrTo, BOOL isIndir
{
ADDRINT RvaFrom = addr_to_rva(addrFrom);
if (isTargetPeModule) {
const std::string func = resolve_func_name(addrTo, ctx);
const std::string dll_name = IMG_Name(targetModule);
const std::string func = resolve_func_name(addrTo, dll_name, ctx);
if (m_Settings.excludedFuncs.contains(dll_name, func)) {
return;
}
Expand All @@ -250,8 +253,8 @@ VOID _SaveTransitions(const ADDRINT addrFrom, const ADDRINT addrTo, BOOL isIndir
const ADDRINT pageTo = query_region_base(addrTo);

if (isTargetPeModule) { // it is a call to a module
const std::string func = resolve_func_name(addrTo, ctx);
const std::string dll_name = IMG_Name(targetModule);
const std::string func = resolve_func_name(addrTo, dll_name, ctx);
if (m_Settings.excludedFuncs.contains(dll_name, func)) {
return;
}
Expand Down Expand Up @@ -287,8 +290,8 @@ VOID _SaveTransitions(const ADDRINT addrFrom, const ADDRINT addrTo, BOOL isIndir
const ADDRINT returnAddr = getReturnFromTheStack(ctx);
const WatchedType toWType = isWatchedAddress(returnAddr); // does it return into the traced area?
if (toWType != WatchedType::NOT_WATCHED) {
const std::string func = resolve_func_name(addrTo, ctx);
const std::string dll_name = IMG_Name(targetModule);
const std::string func = resolve_func_name(addrTo, dll_name, ctx);
if (m_Settings.excludedFuncs.contains(dll_name, func)) {
return;
}
Expand Down Expand Up @@ -630,9 +633,7 @@ VOID SyscallCalled(THREADID tid, CONTEXT* ctxt, SYSCALL_STANDARD std, VOID* v)
// check if it is watched by the function name:
std::string syscallFuncName = SyscallsTable::convertNameToNt(m_Settings.syscallsTable.getName(syscallNum));
for (size_t i = 0; i < m_Settings.funcWatch.funcs.size(); i++) {
if (util::iequals("ntdll", m_Settings.funcWatch.funcs[i].dllName)
|| util::iequals("win32u", m_Settings.funcWatch.funcs[i].dllName))
{
if (SyscallsTable::isSyscallDll(m_Settings.funcWatch.funcs[i].dllName)) {
std::string funcName = SyscallsTable::convertNameToNt(m_Settings.funcWatch.funcs[i].funcName);
if (syscallFuncName == funcName) {
LogSyscallsArgs(funcName.c_str(), ctxt, std, address, m_Settings.funcWatch.funcs[i].paramCount);
Expand Down
2 changes: 2 additions & 0 deletions Util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ size_t util::getAsciiLenW(const wchar_t *inp, size_t maxInp)
std::string util::getDllName(const std::string& str)
{
std::size_t len = str.length();
if (!len) return str;

std::size_t found = str.find_last_of("/\\");
std::size_t ext = str.find_last_of(".");
if (ext > len) ext = len;
Expand Down

0 comments on commit df50ad3

Please sign in to comment.