From f7421e1ee17a3e2acebd5bfaf5b5144ca1e4ce38 Mon Sep 17 00:00:00 2001 From: cecio Date: Tue, 10 Dec 2024 21:33:34 +0100 Subject: [PATCH 1/3] [FEATURE] Added new option: follow child processes --- Settings.cpp | 6 ++++++ Settings.h | 2 ++ TinyTracer.cpp | 23 ++++++++++++++++++++--- install32_64/TinyTracer.ini | 1 + install32_64/run_me.bat | 4 ++-- 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/Settings.cpp b/Settings.cpp index 0d7dbf5..baa0e71 100644 --- a/Settings.cpp +++ b/Settings.cpp @@ -8,6 +8,7 @@ #define DELIM '=' #define KEY_FOLLOW_SHELLCODES "FOLLOW_SHELLCODES" +#define KEY_FOLLOW_CHILDPROCESSES "FOLLOW_CHILDPROCESSES" #define KEY_LOG_RTDSC "TRACE_RDTSC" #define KEY_LOG_INT "TRACE_INT" #define KEY_LOG_SYSCALL "TRACE_SYSCALL" @@ -131,6 +132,10 @@ bool fillSettings(Settings &s, const std::string &line) s.followShellcode = ConvertShcOption(val); isFilled = true; } + if (util::iequals(valName, KEY_FOLLOW_CHILDPROCESSES)) { + s.followChildprocesses = loadBoolean(valStr); + isFilled = true; + } if (util::iequals(valName, KEY_LOG_RTDSC)) { s.traceRDTSC = loadBoolean(valStr); isFilled = true; @@ -250,6 +255,7 @@ bool Settings::saveINI(const std::string &filename) return false; } myfile << KEY_FOLLOW_SHELLCODES << DELIM << this->followShellcode << "\r\n"; + myfile << KEY_FOLLOW_CHILDPROCESSES << DELIM << this->followChildprocesses << "\r\n"; myfile << KEY_LOG_RTDSC << DELIM << booleanToStr(this->traceRDTSC) << "\r\n"; myfile << KEY_LOG_INT << DELIM << booleanToStr(this->traceINT) << "\r\n"; myfile << KEY_LOG_SYSCALL << DELIM << booleanToStr(this->traceSYSCALL) << "\r\n"; diff --git a/Settings.h b/Settings.h index c302865..f56a891 100644 --- a/Settings.h +++ b/Settings.h @@ -103,6 +103,7 @@ class Settings { Settings() : followShellcode(SHELLC_FOLLOW_FIRST), + followChildprocesses(false), traceRDTSC(false), traceINT(false), traceSYSCALL(true), @@ -128,6 +129,7 @@ class Settings { t_shellc_options followShellcode; + bool followChildprocesses; // Follow Child Processes bool traceRDTSC; // Trace RDTSC bool traceINT; // trace INT bool traceSYSCALL; // Trace syscall instructions (i.e., syscall, int 2Eh, sysenter) diff --git a/TinyTracer.cpp b/TinyTracer.cpp index 7f7df7a..8563deb 100644 --- a/TinyTracer.cpp +++ b/TinyTracer.cpp @@ -1312,6 +1312,17 @@ static void OnCtxChange(THREADID threadIndex, _SaveTransitions(addrFrom, addrTo, FALSE); } +BOOL FollowChild(CHILD_PROCESS childProcess, VOID * userData) +{ + if (m_Settings.followChildprocesses) { + OS_PROCESS_ID childPid = CHILD_PROCESS_GetId(childProcess); + std::cerr << "Following Subprocess: " << childPid << std::endl; + return TRUE; + } + // If the callback return FALSE, the child is not followed + return FALSE; +} + /*! * The main procedure of the tool. * This function is called when the application image is loaded but not yet started. @@ -1390,8 +1401,11 @@ int main(int argc, char *argv[]) } // init output file: - traceLog.init(KnobOutputFile.Value(), m_Settings.shortLogging); - + int pid = PIN_GetPid(); + std::stringstream filename; + filename << KnobOutputFile.Value() << "_" << pid << ".log"; + traceLog.init(filename.str(), m_Settings.shortLogging); + // Register function to be called for every loaded module IMG_AddInstrumentFunction(ImageLoad, NULL); @@ -1418,10 +1432,13 @@ int main(int argc, char *argv[]) std::cerr << "Tracing module: " << app_name << std::endl; if (!KnobOutputFile.Value().empty()) { - std::cerr << "See file " << KnobOutputFile.Value() << " for analysis results" << std::endl; + std::cerr << "See file " << filename.str() << " for analysis results" << std::endl; } std::cerr << "===============================================" << std::endl; + // Register the callback function for child processes + PIN_AddFollowChildProcessFunction(FollowChild, 0); + // Start the program, never returns PIN_StartProgram(); return 0; diff --git a/install32_64/TinyTracer.ini b/install32_64/TinyTracer.ini index 1b88f89..f02a4cf 100644 --- a/install32_64/TinyTracer.ini +++ b/install32_64/TinyTracer.ini @@ -6,6 +6,7 @@ FOLLOW_SHELLCODES=1 ; 1 : follow only the first shellcode called from the main module ; 2 : follow also the shellcodes called recursively from the the original shellcode ; 3 : follow any shellcodes +FOLLOW_CHILDPROCESSES=False TRACE_RDTSC=False TRACE_INT=False TRACE_SYSCALL=True diff --git a/install32_64/run_me.bat b/install32_64/run_me.bat index e2f1994..863e593 100644 --- a/install32_64/run_me.bat +++ b/install32_64/run_me.bat @@ -97,8 +97,8 @@ if [%IS_ADMIN%] == [A] ( set ADMIN_CMD=%PIN_TOOLS_DIR%\sudo.vbs -set DLL_CMD=%PIN_DIR%\pin.exe -t %PINTOOL% -m "%TRACED_MODULE%" -o %TAG_FILE% -s %SETTINGS_FILE% -b "%WATCH_BEFORE%" -x "%EXCLUDED_FUNC%" -p "%STOP_OFFSETS%" -l "%SYSCALLS_TABLE%" -- "%DLL_LOAD%" "%TARGET_APP%" %DLL_EXPORTS% -set EXE_CMD=%PIN_DIR%\pin.exe -t %PINTOOL% -m "%TRACED_MODULE%" -o %TAG_FILE% -s %SETTINGS_FILE% -b "%WATCH_BEFORE%" -x "%EXCLUDED_FUNC%" -p "%STOP_OFFSETS%" -l "%SYSCALLS_TABLE%" -- "%TARGET_APP%" %EXE_ARGS% +set DLL_CMD=%PIN_DIR%\pin.exe -follow_execv -t %PINTOOL% -o %TAG_FILE% -s %SETTINGS_FILE% -b "%WATCH_BEFORE%" -x "%EXCLUDED_FUNC%" -p "%STOP_OFFSETS%" -l "%SYSCALLS_TABLE%" -- "%DLL_LOAD%" "%TARGET_APP%" %DLL_EXPORTS% +set EXE_CMD=%PIN_DIR%\pin.exe -follow_execv -t %PINTOOL% -o %TAG_FILE% -s %SETTINGS_FILE% -b "%WATCH_BEFORE%" -x "%EXCLUDED_FUNC%" -p "%STOP_OFFSETS%" -l "%SYSCALLS_TABLE%" -- "%TARGET_APP%" %EXE_ARGS% ;rem "Trace EXE" if [%PE_TYPE%] == [exe] ( From 18b0fc7474025d5a46372538a5285ebb62d7f332 Mon Sep 17 00:00:00 2001 From: cecio Date: Sat, 14 Dec 2024 00:08:48 +0100 Subject: [PATCH 2/3] [REFACT] processing command line for child processes --- TinyTracer.cpp | 38 ++++++++++++++++++++++++++++++++++++++ install32_64/run_me.bat | 4 ++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/TinyTracer.cpp b/TinyTracer.cpp index 8563deb..1f365dd 100644 --- a/TinyTracer.cpp +++ b/TinyTracer.cpp @@ -55,6 +55,9 @@ TraceLog traceLog; // last shellcode to which the transition got redirected: std::set m_tracedShellc; +// Full pin path +std::string pinPath; + /* ===================================================================== */ // Command line switches /* ===================================================================== */ @@ -1317,6 +1320,39 @@ BOOL FollowChild(CHILD_PROCESS childProcess, VOID * userData) if (m_Settings.followChildprocesses) { OS_PROCESS_ID childPid = CHILD_PROCESS_GetId(childProcess); std::cerr << "Following Subprocess: " << childPid << std::endl; + + // Get child process command line + INT childArgc; + CHAR const* const* childArgv; + CHILD_PROCESS_GetCommandLine(childProcess, &childArgc, &childArgv); + // Set Pin's command line for child process, rebuilding with the same options skipping "-m" + INT pinArgc = 0; + const INT pinArgcMax = 40; + CHAR const* pinArgv[pinArgcMax]; + + pinArgv[pinArgc++] = pinPath.c_str(); + pinArgv[pinArgc++] = "-follow_execv"; + pinArgv[pinArgc++] = "-t"; + pinArgv[pinArgc++] = PIN_ToolFullPath(); + pinArgv[pinArgc++] = "-o"; + pinArgv[pinArgc++] = KnobOutputFile.Value().c_str(); + pinArgv[pinArgc++] = "-s"; + pinArgv[pinArgc++] = KnobIniFile.Value().c_str(); + pinArgv[pinArgc++] = "-b"; + pinArgv[pinArgc++] = KnobWatchListFile.Value().c_str(); + pinArgv[pinArgc++] = "-x"; + pinArgv[pinArgc++] = KnobExcludedListFile.Value().c_str(); + pinArgv[pinArgc++] = "-p"; + pinArgv[pinArgc++] = KnobStopOffsets.Value().c_str(); + pinArgv[pinArgc++] = "-l"; + pinArgv[pinArgc++] = KnobSyscallsTable.Value().c_str(); + pinArgv[pinArgc++] = "--"; + // Now copy the child command line + for (int i = 0; i < childArgc && pinArgc < pinArgcMax; i++) { + pinArgv[pinArgc++] = childArgv[i]; + } + + CHILD_PROCESS_SetPinCommandLine(childProcess, pinArgc, pinArgv); return TRUE; } // If the callback return FALSE, the child is not followed @@ -1341,6 +1377,8 @@ int main(int argc, char *argv[]) return Usage(); } + pinPath = argv[0]; + std::string app_name = KnobModuleName.Value(); if (app_name.length() == 0) { // init App Name: diff --git a/install32_64/run_me.bat b/install32_64/run_me.bat index 863e593..dea01d6 100644 --- a/install32_64/run_me.bat +++ b/install32_64/run_me.bat @@ -97,8 +97,8 @@ if [%IS_ADMIN%] == [A] ( set ADMIN_CMD=%PIN_TOOLS_DIR%\sudo.vbs -set DLL_CMD=%PIN_DIR%\pin.exe -follow_execv -t %PINTOOL% -o %TAG_FILE% -s %SETTINGS_FILE% -b "%WATCH_BEFORE%" -x "%EXCLUDED_FUNC%" -p "%STOP_OFFSETS%" -l "%SYSCALLS_TABLE%" -- "%DLL_LOAD%" "%TARGET_APP%" %DLL_EXPORTS% -set EXE_CMD=%PIN_DIR%\pin.exe -follow_execv -t %PINTOOL% -o %TAG_FILE% -s %SETTINGS_FILE% -b "%WATCH_BEFORE%" -x "%EXCLUDED_FUNC%" -p "%STOP_OFFSETS%" -l "%SYSCALLS_TABLE%" -- "%TARGET_APP%" %EXE_ARGS% +set DLL_CMD=%PIN_DIR%\pin.exe -follow_execv -t %PINTOOL% -m "%TRACED_MODULE%" -o %TAG_FILE% -s %SETTINGS_FILE% -b "%WATCH_BEFORE%" -x "%EXCLUDED_FUNC%" -p "%STOP_OFFSETS%" -l "%SYSCALLS_TABLE%" -- "%DLL_LOAD%" "%TARGET_APP%" %DLL_EXPORTS% +set EXE_CMD=%PIN_DIR%\pin.exe -follow_execv -t %PINTOOL% -m "%TRACED_MODULE%" -o %TAG_FILE% -s %SETTINGS_FILE% -b "%WATCH_BEFORE%" -x "%EXCLUDED_FUNC%" -p "%STOP_OFFSETS%" -l "%SYSCALLS_TABLE%" -- "%TARGET_APP%" %EXE_ARGS% ;rem "Trace EXE" if [%PE_TYPE%] == [exe] ( From 57da37f5a9609e90fd8a0e893e0f5d24beb176d8 Mon Sep 17 00:00:00 2001 From: cecio Date: Sat, 14 Dec 2024 00:26:23 +0100 Subject: [PATCH 3/3] [REFACT] readded -m option --- TinyTracer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/TinyTracer.cpp b/TinyTracer.cpp index 1f365dd..756a5cf 100644 --- a/TinyTracer.cpp +++ b/TinyTracer.cpp @@ -1325,7 +1325,7 @@ BOOL FollowChild(CHILD_PROCESS childProcess, VOID * userData) INT childArgc; CHAR const* const* childArgv; CHILD_PROCESS_GetCommandLine(childProcess, &childArgc, &childArgv); - // Set Pin's command line for child process, rebuilding with the same options skipping "-m" + // Set Pin's command line for child process, rebuilding with the same options updated INT pinArgc = 0; const INT pinArgcMax = 40; CHAR const* pinArgv[pinArgcMax]; @@ -1346,6 +1346,8 @@ BOOL FollowChild(CHILD_PROCESS childProcess, VOID * userData) pinArgv[pinArgc++] = KnobStopOffsets.Value().c_str(); pinArgv[pinArgc++] = "-l"; pinArgv[pinArgc++] = KnobSyscallsTable.Value().c_str(); + pinArgv[pinArgc++] = "-m"; + pinArgv[pinArgc++] = childArgv[0]; pinArgv[pinArgc++] = "--"; // Now copy the child command line for (int i = 0; i < childArgc && pinArgc < pinArgcMax; i++) {