├── extrn └── ihulib │ └── .keep ├── make ├── unzip.exe ├── prebuild.cmd ├── dldep.ps1 ├── stracent.sln ├── stracent.vcxproj ├── stserum.vcxproj └── straceui.vcxproj ├── src ├── app │ ├── strace.ico │ ├── gui │ │ ├── res │ │ │ ├── aboutBtn.bmp │ │ │ ├── greenAbout.bmp │ │ │ ├── greenStop.bmp │ │ │ ├── ihSymbol.bmp │ │ │ ├── orangeStop.bmp │ │ │ ├── greenOption.bmp │ │ │ ├── orangeAbout.bmp │ │ │ └── orangeOption.bmp │ │ ├── stoptionsdlg.h │ │ ├── stgui.h │ │ ├── stcommon.h │ │ ├── stmiscdlgs.h │ │ ├── stcommon.cpp │ │ ├── stguires.h │ │ ├── stgui.cpp │ │ ├── stguiview.h │ │ ├── stgui.rc │ │ ├── stoptionsdlg.cpp │ │ └── stmiscdlgs.cpp │ ├── cli │ │ ├── stcli.rc │ │ ├── stcliview.h │ │ ├── stcli.cpp │ │ └── stcliview.cpp │ ├── stres.h │ ├── strace.h │ ├── strace.rc │ └── stFilter.txt ├── serum │ ├── stserum.def │ ├── stserum.rc │ ├── xprintf.c │ ├── serum.cpp │ ├── serum.h │ ├── patchutl.cpp │ └── patchmgr.cpp └── inc │ ├── stver.h │ └── stcmn.h ├── readme.txt ├── .gitignore └── hlp └── info.txt /extrn/ihulib/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /make/unzip.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipankajg/stracent/HEAD/make/unzip.exe -------------------------------------------------------------------------------- /src/app/strace.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipankajg/stracent/HEAD/src/app/strace.ico -------------------------------------------------------------------------------- /src/app/gui/res/aboutBtn.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipankajg/stracent/HEAD/src/app/gui/res/aboutBtn.bmp -------------------------------------------------------------------------------- /src/app/gui/res/greenAbout.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipankajg/stracent/HEAD/src/app/gui/res/greenAbout.bmp -------------------------------------------------------------------------------- /src/app/gui/res/greenStop.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipankajg/stracent/HEAD/src/app/gui/res/greenStop.bmp -------------------------------------------------------------------------------- /src/app/gui/res/ihSymbol.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipankajg/stracent/HEAD/src/app/gui/res/ihSymbol.bmp -------------------------------------------------------------------------------- /src/app/gui/res/orangeStop.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipankajg/stracent/HEAD/src/app/gui/res/orangeStop.bmp -------------------------------------------------------------------------------- /src/serum/stserum.def: -------------------------------------------------------------------------------- 1 | LIBRARY stserum 2 | EXPORTS 3 | IhSerumLoad 4 | IhSerumUnload 5 | IhSerumGetRefCount 6 | -------------------------------------------------------------------------------- /src/app/gui/res/greenOption.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipankajg/stracent/HEAD/src/app/gui/res/greenOption.bmp -------------------------------------------------------------------------------- /src/app/gui/res/orangeAbout.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipankajg/stracent/HEAD/src/app/gui/res/orangeAbout.bmp -------------------------------------------------------------------------------- /src/app/gui/res/orangeOption.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ipankajg/stracent/HEAD/src/app/gui/res/orangeOption.bmp -------------------------------------------------------------------------------- /make/prebuild.cmd: -------------------------------------------------------------------------------- 1 | echo Launch directory: "%~dp0" 2 | pushd "..\extrn\ihulib" 3 | echo Current directory: "%CD%" 4 | powershell.exe -ExecutionPolicy Bypass -File ../../make/dldep.ps1 5 | pause -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | StraceNT 2 | -------- 3 | This program is a Linux strace clone for Windows. It uses IAT patching and 4 | provides an efficient way to monitor API calls made by various DLLs. 5 | 6 | 7 | Compile 8 | ------- 9 | - Use Visual Studio 2013 to compile the software. 10 | - First download IHULIB library from: 11 | https://github.com/intellectualheaven/ihulib/releases/download/v1.1/ihulib_v_1_1.zip 12 | - Extract this to stracent/extrn/ihulib (preserve folder paths) 13 | - You should have files like ihulib/bin/x64/Debug/ihulib.lib etc. 14 | - Open stracent.sln in make folder and build. 15 | 16 | 17 | Install 18 | ------- 19 | - Download the zip file from github release tab and extract it to any folder. 20 | - There is no special installation required. You can run stracent or straceui 21 | from the extracted location. 22 | 23 | 24 | Notes 25 | ----- 26 | Please read info.txt for more details about this program, usage and 27 | limitations etc. 28 | 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## 2 | ## Master ignore file to be used in most projects. 3 | ## 4 | ## TODO: Right now mostly geared towards VisualStudio. Enhance to incorporate 5 | ## other compilers in future. 6 | ## 7 | 8 | 9 | # Build results 10 | [Dd]ebug/ 11 | [Rr]elease/ 12 | [Rr]eleases/ 13 | [Bb]in/ 14 | [Oo]bj/ 15 | [Bb]ld/ 16 | 17 | 18 | # IDE generated files. 19 | *.suo 20 | *.user 21 | *.userosscache 22 | *.sln.docstates 23 | ipch/ 24 | *.aps 25 | *.ncb 26 | *.opensdf 27 | *.sdf 28 | *.cachefile 29 | *.psess 30 | *.vsp 31 | *.vspx 32 | 33 | 34 | # Compiler generated files. 35 | dlldata.c 36 | *_i.c 37 | *_p.c 38 | *_i.h 39 | *.ilk 40 | *.meta 41 | *.obj 42 | *.pch 43 | *.pdb 44 | *.pgc 45 | *.pgd 46 | *.rsp 47 | *.sbr 48 | *.tlb 49 | *.tli 50 | *.tlh 51 | *.tmp 52 | *.tmp_proj 53 | *.log 54 | *.vspscc 55 | *.vssscc 56 | .builds 57 | *.pidb 58 | *.svclog 59 | *.scc 60 | *.swp 61 | *.zip 62 | 63 | # Windows Store app package directory 64 | AppPackages/ 65 | 66 | # Microsoft Fakes 67 | FakesAssemblies/ 68 | 69 | # VIM Temporary Files 70 | *.swp 71 | *.swo 72 | *.swn 73 | *.un~ 74 | 75 | # Thumbnail cache 76 | Thumbs.db 77 | 78 | -------------------------------------------------------------------------------- /make/dldep.ps1: -------------------------------------------------------------------------------- 1 | $file = "ihulib.zip" 2 | $url = "https://github.com/intellectualheaven/ihulib/releases/download/v1.1.1/ihulib.zip" 3 | $clnt = new-object System.Net.WebClient 4 | 5 | [bool]$downloadFile = $False 6 | $clnt.OpenRead($Url).Close() 7 | $lastModified = $clnt.ResponseHeaders["Last-Modified"] 8 | 9 | If (!(Test-Path($file))) { 10 | Write-Host "File $file does not exist." 11 | $downloadFile = $True 12 | } Else { 13 | [DateTime]$remoteLastModified = $lastModified 14 | $localLastModified = (Get-Item $file).LastWriteTime 15 | $downloadFile = !($localLastModified -eq $remoteLastModified) 16 | If ($downloadFile) { 17 | Write-Host "Local and remote files are different." 18 | } Else { 19 | Write-Host "Local and remote files are same." 20 | } 21 | } 22 | 23 | If ($downloadFile) { 24 | Write-Host "Downloading $file from $url ..." 25 | $clnt.DownloadFile($url, $file) 26 | $fileItem = Get-Item $file 27 | $fileItem.LastWriteTime = $lastModified 28 | Write-Host "unzip $file ..." 29 | $prg = "$PSScriptRoot\unzip.exe" 30 | $arg = "-o $file" 31 | Start-Process -FilePath "$prg" -ArgumentList "$arg" -Wait 32 | } 33 | -------------------------------------------------------------------------------- /src/app/gui/stoptionsdlg.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | INT_PTR 30 | CALLBACK 31 | stOptionsDlgProc( 32 | HWND hDlg, 33 | UINT msg, 34 | WPARAM wParam, 35 | LPARAM lParam); -------------------------------------------------------------------------------- /src/app/cli/stcli.rc: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | /*++ 30 | 31 | Module Name: 32 | 33 | stcli.rc 34 | 35 | Module Description: 36 | 37 | Resource file for CLI version of StraceNt 38 | 39 | --*/ 40 | 41 | #include "strace.rc" 42 | 43 | -------------------------------------------------------------------------------- /src/app/stres.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | #ifndef _STRES_H_ 30 | #define _STRES_H_ 31 | 32 | // 33 | // Icons 34 | // 35 | #define IDI_APP_ICON 101 36 | 37 | // 38 | // Binary resource 39 | // 40 | #define IDR_BIN_DLL 201 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/app/gui/stgui.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | /*++ 30 | 31 | Module Name: 32 | 33 | stgui.h 34 | 35 | Module Description: 36 | 37 | STraceNT GUI based interface implementation 38 | 39 | --*/ 40 | 41 | #ifndef _STGUI_H_ 42 | #define _STGUI_H_ 43 | 44 | // Local Include Files!!! 45 | #include "stguiview.h" 46 | 47 | extern CStGuiView *g_pViewObj; 48 | 49 | extern LRESULT CALLBACK WndProc( 50 | HWND hwnd, 51 | UINT nMsg, 52 | WPARAM wParam, 53 | LPARAM lParam); 54 | 55 | #endif -------------------------------------------------------------------------------- /src/app/gui/stcommon.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | #ifndef _STCOMMON_H_ 30 | #define _STCOMMON_H_ 31 | 32 | #include 33 | #include 34 | 35 | // 36 | // Macro to calculate count of characters in an array 37 | // 38 | #define CHARCOUNT(_sz_) (sizeof((_sz_)) / sizeof((_sz_)[0])) 39 | 40 | // 41 | // ANSI/UNICODE independent STL string 42 | // 43 | #if _UNICODE || UNICODE 44 | typedef std::wstring tstring; 45 | #else 46 | typedef std::string tstring; 47 | #endif 48 | 49 | // 50 | // Global application instance 51 | // 52 | extern HINSTANCE ghInstance; 53 | 54 | // 55 | // Function to move the dialog to center of the parent 56 | // 57 | void 58 | CenterDialog(HWND hwndDlg); 59 | 60 | #endif -------------------------------------------------------------------------------- /make/stracent.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stracent", "stracent.vcxproj", "{FE15209A-9026-4B4C-9D52-83EC133EECA3}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {D48A7EAF-8C12-4C53-90D0-9A228D9E113E} = {D48A7EAF-8C12-4C53-90D0-9A228D9E113E} 9 | EndProjectSection 10 | EndProject 11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stserum", "stserum.vcxproj", "{D48A7EAF-8C12-4C53-90D0-9A228D9E113E}" 12 | EndProject 13 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "straceui", "straceui.vcxproj", "{B95CC236-749A-4152-9C50-3246B72B010D}" 14 | ProjectSection(ProjectDependencies) = postProject 15 | {D48A7EAF-8C12-4C53-90D0-9A228D9E113E} = {D48A7EAF-8C12-4C53-90D0-9A228D9E113E} 16 | EndProjectSection 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|Win32 = Debug|Win32 21 | Release|Win32 = Release|Win32 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {FE15209A-9026-4B4C-9D52-83EC133EECA3}.Debug|Win32.ActiveCfg = Debug|Win32 25 | {FE15209A-9026-4B4C-9D52-83EC133EECA3}.Debug|Win32.Build.0 = Debug|Win32 26 | {FE15209A-9026-4B4C-9D52-83EC133EECA3}.Release|Win32.ActiveCfg = Release|Win32 27 | {FE15209A-9026-4B4C-9D52-83EC133EECA3}.Release|Win32.Build.0 = Release|Win32 28 | {D48A7EAF-8C12-4C53-90D0-9A228D9E113E}.Debug|Win32.ActiveCfg = Debug|Win32 29 | {D48A7EAF-8C12-4C53-90D0-9A228D9E113E}.Debug|Win32.Build.0 = Debug|Win32 30 | {D48A7EAF-8C12-4C53-90D0-9A228D9E113E}.Release|Win32.ActiveCfg = Release|Win32 31 | {D48A7EAF-8C12-4C53-90D0-9A228D9E113E}.Release|Win32.Build.0 = Release|Win32 32 | {B95CC236-749A-4152-9C50-3246B72B010D}.Debug|Win32.ActiveCfg = Debug|Win32 33 | {B95CC236-749A-4152-9C50-3246B72B010D}.Debug|Win32.Build.0 = Debug|Win32 34 | {B95CC236-749A-4152-9C50-3246B72B010D}.Release|Win32.ActiveCfg = Release|Win32 35 | {B95CC236-749A-4152-9C50-3246B72B010D}.Release|Win32.Build.0 = Release|Win32 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | EndGlobal 41 | -------------------------------------------------------------------------------- /src/app/strace.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | #ifndef _STRACE_H_ 30 | #define _STRACE_H_ 31 | 32 | #include 33 | #include 34 | #include 35 | #include "ihulib.h" 36 | 37 | #define TRC_STRACE IHU_LOGGING_OFF 38 | 39 | class CStView 40 | { 41 | 42 | public: 43 | 44 | virtual void PrintMessage(LPCWSTR inFormat, ...) = 0; 45 | virtual void PrintTitle(LPCWSTR inFormat, ...) = 0; 46 | virtual void PrintTrace(LPCWSTR inFormat, ...) = 0; 47 | virtual void PrintTraceA(LPCSTR inFormat, ...) = 0; 48 | virtual void PrintTraceOrig(LPCWSTR inFormat, ...) = 0; 49 | virtual void PrintTraceOrigA(LPCSTR inFormat, ...) = 0; 50 | virtual void PrintWarning(LPCWSTR inFormat, ...) = 0; 51 | virtual void PrintError(LPCWSTR inFormat, ...) = 0; 52 | virtual void PrintErrorA(LPCSTR inFormat, ...) = 0; 53 | 54 | }; 55 | 56 | 57 | extern CStView *gView; 58 | 59 | void 60 | stInitStrace(CStView *inView); 61 | 62 | void 63 | stPrematureTracerExit(); 64 | 65 | void 66 | stProcessArguments( 67 | int argC, 68 | wchar_t *argV[]); 69 | 70 | BOOL 71 | stObtainSeDebugPrivilege(void); 72 | 73 | #endif -------------------------------------------------------------------------------- /src/app/cli/stcliview.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | #ifndef _STCUIVIEW_H_ 30 | #define _STCUIVIEW_H_ 31 | 32 | #include 33 | #include "ihulib.h" 34 | #include "strace.h" 35 | 36 | // White color definition for console colors 37 | #define FOREGROUND_WHITE (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE) 38 | 39 | 40 | class CStCuiView : public CStView 41 | { 42 | public: 43 | virtual void PrintW(WORD inClr, LPCWSTR inFormat, va_list inArgList); 44 | virtual void PrintA(WORD inClr, LPCSTR inFormat, va_list inArgList); 45 | 46 | virtual void PrintMessage(LPCWSTR inFormat, ...); 47 | virtual void PrintTitle(LPCWSTR inFormat, ...); 48 | virtual void PrintTrace(LPCWSTR inFormat, ...); 49 | virtual void PrintTraceA(LPCSTR inFormat, ...); 50 | virtual void PrintTraceOrig(LPCWSTR inFormat, ...); 51 | virtual void PrintTraceOrigA(LPCSTR inFormat, ...); 52 | virtual void PrintWarning(LPCWSTR inFormat, ...); 53 | virtual void PrintError(LPCWSTR inFormat, ...); 54 | virtual void PrintErrorA(LPCSTR inFormat, ...); 55 | 56 | }; 57 | 58 | WORD 59 | ChangeTextClr(WORD colorNew); 60 | 61 | #endif -------------------------------------------------------------------------------- /src/serum/stserum.rc: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | #include "windows.h" 30 | #include "ntverp.h" 31 | #include "stver.h" 32 | 33 | // 34 | // StraceNT Serum DLL version resources 35 | // 36 | 37 | VS_VERSION_INFO VERSIONINFO 38 | FILEVERSION STRACE_BIN_VERSION 39 | PRODUCTVERSION STRACE_BIN_VERSION 40 | FILETYPE 0x00000001L 41 | FILESUBTYPE 0x00000006L 42 | BEGIN 43 | BLOCK "StringFileInfo" 44 | BEGIN 45 | BLOCK "040904B0" 46 | BEGIN 47 | VALUE "CompanyName", COMPANY_NAME 48 | VALUE "LegalCopyright", LEGAL_COPYRIGHT 49 | VALUE "ProductName", PRODUCT_NAME 50 | VALUE "ProductVersion", ST_MAKE_STR(STRACE_STR_VERSION) 51 | VALUE "FileVersion", ST_MAKE_STR(STRACE_STR_VERSION) 52 | VALUE "FileDescription", "StraceNT Code Patching Library\0" 53 | VALUE "OriginalFilename","stserum.dll\0" 54 | VALUE "InternalName", "stserum.dll\0" 55 | END 56 | END 57 | BLOCK "VarFileInfo" 58 | BEGIN 59 | VALUE "Translation", 0x409, 1200 60 | END 61 | END 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /src/app/gui/stmiscdlgs.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | #ifndef _STMISCDLGS_H_ 30 | #define _STMISCDLGS_H_ 31 | 32 | #include 33 | #include 34 | #include "stcommon.h" 35 | #include "stguires.h" 36 | 37 | // 38 | // Dialog Proc for About Dialog 39 | // 40 | INT_PTR 41 | CALLBACK 42 | stAboutDlgProc( 43 | HWND hDlg, 44 | UINT msg, 45 | WPARAM wParam, 46 | LPARAM lParam); 47 | 48 | 49 | typedef struct _ST_ATTACH_PROCESS 50 | { 51 | std::wstring ProcessId; 52 | bool ApplyFilter; 53 | std::wstring FilterFile; 54 | 55 | }ST_ATTACH_PROCESS, *PST_ATTACH_PROCESS; 56 | 57 | INT_PTR 58 | CALLBACK 59 | stProcessAttachDlgProc( 60 | HWND hDlg, 61 | UINT msg, 62 | WPARAM wParam, 63 | LPARAM lParam); 64 | 65 | 66 | typedef struct _ST_LAUNCH_PROCESS 67 | { 68 | std::wstring Arguments; 69 | bool ApplyFilter; 70 | std::wstring FilterFile; 71 | 72 | }ST_LAUNCH_PROCESS, *PST_LAUNCH_PROCESS; 73 | 74 | INT_PTR 75 | CALLBACK 76 | stLaunchProcessDlgProc( 77 | HWND hDlg, 78 | UINT msg, 79 | WPARAM wParam, 80 | LPARAM lParam); 81 | 82 | #endif -------------------------------------------------------------------------------- /src/app/strace.rc: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg (pankaj@intellectualheaven.com). 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | #include "windows.h" 30 | #include "ntverp.h" 31 | #include "stver.h" 32 | #include "stres.h" 33 | 34 | // 35 | // App Icon 36 | // 37 | IDI_APP_ICON ICON strace.ico 38 | 39 | // 40 | // Binary injector dll 41 | // 42 | IDR_BIN_DLL BIN "stserum.dll" 43 | 44 | // 45 | // StraceNT Executable version resources 46 | // 47 | 48 | VS_VERSION_INFO VERSIONINFO 49 | FILEVERSION STRACE_BIN_VERSION 50 | PRODUCTVERSION STRACE_BIN_VERSION 51 | FILETYPE 0x00000001L 52 | FILESUBTYPE 0x00000006L 53 | BEGIN 54 | BLOCK "StringFileInfo" 55 | BEGIN 56 | BLOCK "040904B0" 57 | BEGIN 58 | VALUE "CompanyName", COMPANY_NAME 59 | VALUE "LegalCopyright", LEGAL_COPYRIGHT 60 | VALUE "ProductName", PRODUCT_NAME 61 | VALUE "ProductVersion", ST_MAKE_STR(STRACE_STR_VERSION) 62 | VALUE "FileVersion", ST_MAKE_STR(STRACE_STR_VERSION) 63 | VALUE "FileDescription", "IntellectualHeaven StraceNT Executable\0" 64 | VALUE "OriginalFilename","StraceNT.exe\0" 65 | VALUE "InternalName", "StraceNT.exe\0" 66 | END 67 | END 68 | BLOCK "VarFileInfo" 69 | BEGIN 70 | VALUE "Translation", 0x409, 1200 71 | END 72 | END 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /src/inc/stver.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | #ifndef _STVER_H_ 30 | #define _STVER_H_ 31 | 32 | // 33 | // Version related Macros 34 | // 35 | #define ST_MAKE_STR(_X_) ST_MAKE_STR_REAL(_X_) 36 | #define ST_MAKE_STR_REAL(_X_) #_X_ 37 | 38 | #define ST_CASTBYTE(b) ((DWORD)(b) & 0xFF) 39 | #define ST_DWORD_VERSION(VER_MAJOR, VER_MINOR, VER_BUILD, VER_STEP) \ 40 | (ST_CASTBYTE(VER_MAJOR) << 24 | \ 41 | ST_CASTBYTE(VER_MINOR) << 16 | \ 42 | ST_CASTBYTE(VER_BUILD) << 8 | \ 43 | ST_CASTBYTE(VER_STEP)) 44 | 45 | // 46 | // Common version defines for StraceNT 47 | // 48 | 49 | #define COMPANY_NAME "www.intellectualheaven.com\0" 50 | #define PRODUCT_NAME "System Call Tracer for Windows XP - Windows 10.\0" 51 | #define LEGAL_COPYRIGHT "Copyright (c): Pankaj Garg .\0" 52 | 53 | #define STRACE_VER_MAJOR 0 54 | #define STRACE_VER_MINOR 9 55 | #define STRACE_VER_BUILD 3 56 | #define STRACE_VER_STEP 0 57 | 58 | #define STRACE_BIN_VERSION STRACE_VER_MAJOR,STRACE_VER_MINOR,STRACE_VER_BUILD,STRACE_VER_STEP 59 | #define STRACE_STR_VERSION STRACE_VER_MAJOR.STRACE_VER_MINOR.STRACE_VER_BUILD.STRACE_VER_STEP 60 | #define STRACE_DWORD_VERSION ST_DWORD_VERSION(STRACE_VER_MAJOR, STRACE_VER_MINOR, STRACE_VER_BUILD, STRACE_VER_STEP) 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /hlp/info.txt: -------------------------------------------------------------------------------- 1 | StraceNT: 2 | ========= 3 | StraceNT is a system call tracer and it can trace all the calls a program makes 4 | to the functions imported from other DLLs. It is developed by Pankaj Garg for 5 | IntellectualHeaven (http://www.intellectualheaven.com) 6 | 7 | 8 | Updates: 9 | ======== 10 | Please check http://www.intellectualheaven.com to make sure that you have 11 | the latest version of StraceNT 12 | 13 | 14 | Installation: 15 | ============= 16 | For Windows 2000, XP and 2003: 17 | 1. Extract stracent.exe and straceui.exe to a directory. 18 | 2. Extract sample filter file stFilter.txt to the same directory. 19 | 20 | 21 | Features: 22 | ========= 23 | - Uses IAT patching which is a very efficient way to trace functions. 24 | - Provides excellent include/exclude support to give finer control over 25 | tracing. 26 | - Trace functions calls made to DLLs loaded dynamically using LoadLibrary. 27 | - Allows user to specify a different return value from a function. 28 | - Comes in both Graphical UI and command line version. 29 | - 100% free of cost. 30 | 31 | 32 | Known Limitation: 33 | ================= 34 | - Does not trace child processes created by the traced process. 35 | - Does not trace functions which are called by using GetProcAddress method. 36 | 37 | 38 | Version: 39 | ======== 40 | v0.8.1 (Beta2) (2005/03/01) 41 | - Added tracing of DLLs which are loaded dynamically using LoadLibrary 42 | - Added option for returning a different value from a function 43 | - Support is added for tracing functions exported by Ordinal 44 | - Modified inclusion/exclusion to provide much better control 45 | - Fixed few crashing bugs 46 | - Made a GUI version of StraceNT also 47 | 48 | v0.6.2 (Beta1) (2004/09/22) 49 | Current version of StraceNT is 0.6 which is also declared Beta1. This means 50 | that even though the program is throughly tested, there may be some unearthed 51 | bugs. If you encounter a bug or have a feature request, please drop a mail to 52 | x_pankaj_x@intellectualheaven.com 53 | 54 | 55 | Supported platforms: 56 | ==================== 57 | Windows 2000 58 | Windows XP (32-bit) 59 | Windows 2003 (32-bit) 60 | Windows XP (64-bit) - For tracing 32bit process *only* running inside wow64 61 | Windows 2003 (64-bit) - For tracing 32bit process *only* running inside wow64 62 | 63 | 64 | Warning: 65 | ======== 66 | On windows 2000, it uses windows debug support so if you attach StraceNT 67 | to a process, the process will die if you kill StraceNT. 68 | 69 | 70 | Usage: 71 | ====== 72 | Run stracent.exe from command line without any parameters. StraceNT will show 73 | its usage details. Alternatively, run straceui.exe which is a win32 GUI based 74 | version of StraceNT. To filter any particular DLLs or Function, use 75 | stFilter.txt as a sample and modify it to your needs. 76 | 77 | 78 | Questions: 79 | ========== 80 | For questions or suggestions, contact pankaj@intellectualheaven.com 81 | 82 | 83 | -- 84 | Regards, 85 | Pankaj Garg 86 | www.intellectualheaven.com 87 | -------------------------------------------------------------------------------- /src/app/gui/stcommon.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | #include 30 | #include "stcommon.h" 31 | #include "stguires.h" 32 | 33 | 34 | // 35 | // Global application instance 36 | // 37 | HINSTANCE ghInstance; 38 | 39 | 40 | void 41 | CenterDialog( 42 | HWND hwndDlg) 43 | /*++ 44 | 45 | Routine Description: 46 | 47 | Moves the dialog box to the center of its 48 | parent. If parent is NULL then dialog box 49 | is moved to the center of the desktop 50 | 51 | Returns: 52 | 53 | None 54 | 55 | --*/ 56 | { 57 | HWND hwndOwner; 58 | 59 | if ((hwndOwner = GetParent(hwndDlg)) == NULL) 60 | { 61 | hwndOwner = GetDesktopWindow(); 62 | } 63 | 64 | RECT rcOwner; 65 | RECT rcDlg; 66 | RECT rc; 67 | 68 | GetWindowRect(hwndOwner, &rcOwner); 69 | GetWindowRect(hwndDlg, &rcDlg); 70 | CopyRect(&rc, &rcOwner); 71 | 72 | // 73 | // Offset the owner and dialog box rectangles so that 74 | // right and bottom values represent the width and 75 | // height, and then offset the owner again to discard 76 | // space taken up by the dialog box. 77 | // 78 | OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top); 79 | OffsetRect(&rc, -rc.left, -rc.top); 80 | OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom); 81 | 82 | if (rc.right < 0) 83 | { 84 | rc.right = 0; 85 | } 86 | 87 | if (rc.bottom < 0) 88 | { 89 | rc.bottom = 0; 90 | } 91 | 92 | // The new position is the sum of half the remaining 93 | // space and the owner's original position. 94 | SetWindowPos( 95 | hwndDlg, 96 | HWND_TOP, 97 | rcOwner.left + (rc.right / 2), 98 | rcOwner.top + (rc.bottom / 2), 99 | 0, 0, // ignores size arguments 100 | SWP_NOSIZE); 101 | 102 | return; 103 | } 104 | 105 | 106 | -------------------------------------------------------------------------------- /src/app/cli/stcli.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | #include 30 | #include 31 | #include 32 | #include "ihulib.h" 33 | #include "stcliview.h" 34 | 35 | // 36 | // Application Title 37 | // 38 | #define APPLICATION_TITLE L"StraceNT - System Call Tracer for NT, 2K, XP, 2K3" 39 | 40 | 41 | // 42 | // Global color variable to record color on application start 43 | // This variable is used to restore original color on Ctrl-C 44 | // or normal application exit 45 | // 46 | WORD gDefaultColor; 47 | 48 | 49 | 50 | BOOL 51 | WINAPI 52 | stProcessExit( 53 | DWORD inCtrlType) 54 | /*++ 55 | 56 | Routine Description: 57 | 58 | This routine handles the CTRL-C, CTRL-BREAK etc. events. On such event 59 | it removes the IAT patches from the process and then return FALSE to 60 | invoke system Ctrl handler. 61 | 62 | Arguments: 63 | 64 | inCtrlType - A well-defined ctrl type code. We don't use it 65 | 66 | --*/ 67 | { 68 | stPrematureTracerExit(); 69 | ChangeTextClr(gDefaultColor); 70 | return FALSE; 71 | } 72 | 73 | 74 | int 75 | __cdecl 76 | wmain(int argC, wchar_t *argV[]) 77 | /*++ 78 | 79 | Routine Description: 80 | 81 | strace application's main entry point. It does following 82 | things: 83 | - Parse user supplied arguments 84 | - Process arguments 85 | - Attach to the target application as a debugger 86 | - Display debug spew of target application 87 | - On process detach, terminate self, but leave target running 88 | 89 | Return: 90 | 91 | 0 (zero) - success 92 | non-zero - failure 93 | 94 | --*/ 95 | { 96 | CStCuiView cuiView; 97 | 98 | stInitStrace(&cuiView); 99 | 100 | wchar_t consoleTitle[MAX_PATH] = {0}; 101 | GetConsoleTitle(consoleTitle, MAX_PATH - 1); 102 | SetConsoleTitle(APPLICATION_TITLE); 103 | gDefaultColor = ChangeTextClr(FOREGROUND_WHITE); 104 | 105 | SetConsoleCtrlHandler(stProcessExit, TRUE); 106 | stProcessArguments(argC, argV); 107 | 108 | ChangeTextClr(gDefaultColor); 109 | SetConsoleTitle(consoleTitle); 110 | 111 | 112 | return 0; 113 | } 114 | -------------------------------------------------------------------------------- /src/app/gui/stguires.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | /*++ 30 | 31 | Module Name: 32 | 33 | stguires.h 34 | 35 | Module Description: 36 | 37 | Resource identifier file for the application 38 | 39 | --*/ 40 | 41 | #ifndef _STGUIRES_H_ 42 | #define _STGUIRES_H_ 43 | 44 | #include "stres.h" 45 | #include "stver.h" 46 | 47 | // 48 | // Menus 49 | // 50 | #define IDR_MENU 1001 51 | 52 | 53 | // 54 | // Bitmaps 55 | // 56 | #define IDB_GREEN_OPTION 1101 57 | #define IDB_ORANGE_OPTION 1102 58 | #define IDB_GREEN_ABOUT 1103 59 | #define IDB_ORANGE_ABOUT 1104 60 | #define IDB_GREEN_STOP 1105 61 | #define IDB_ORANGE_STOP 1106 62 | #define IDB_IH_SYMBOL 1107 63 | #define IDB_ABOUT_BTN 1108 64 | 65 | 66 | // 67 | // Menu Items 68 | // 69 | #define ID_FILE_SAVE 1201 70 | #define ID_FILE_EXIT 1202 71 | #define ID_TRACE_NEW 1211 72 | #define ID_TRACE_ATTACH 1212 73 | #define ID_TRACE_STOP 1213 74 | #define ID_CONFIG_FILTER 1221 75 | #define ID_HELP_ABOUT 1231 76 | 77 | 78 | // 79 | // Dialogs & Controls 80 | // 81 | #define IDC_STATIC -1 82 | 83 | #define IDD_DIALOG_ABOUT 1301 84 | #define IDC_STATIC_LINK 1302 85 | 86 | #define IDD_DIALOG_OPTIONS 1401 87 | #define IDC_CHECK_MAIN_EXE 1402 88 | #define IDC_EDIT_LOADED_MOD 1403 89 | #define IDC_EDIT_IMP_MOD 1404 90 | #define IDC_EDIT_FN_NAME 1405 91 | #define IDC_BTN_INCL 1406 92 | #define IDC_BTN_EXCL 1407 93 | #define IDC_BTN_SAVE 1408 94 | #define IDC_BTN_CLOSE 1409 95 | #define IDC_BTN_DEL_INCL 1410 96 | #define IDC_BTN_DEL_EXCL 1411 97 | #define IDC_LIST_INCL 1412 98 | #define IDC_LIST_EXCL 1413 99 | 100 | #define IDD_DIALOG_ATTACH_PROCESS 1501 101 | #define IDC_LIST_PROCESS 1502 102 | #define IDC_CHECK_FILTER 1503 103 | #define IDC_EDIT_FILTER_FILE 1504 104 | #define ID_BTN_BROWSE 1505 105 | #define ID_BTN_REFRESH 1506 106 | 107 | #define IDD_DIALOG_LAUNCH_PROCESS 1601 108 | #define IDC_EDIT_ARGS 1602 109 | 110 | #endif 111 | 112 | -------------------------------------------------------------------------------- /src/app/gui/stgui.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | /*++ 30 | 31 | Module Name: 32 | 33 | stgui.cpp 34 | 35 | Module Description: 36 | 37 | STraceNT GUI based interface implementation 38 | 39 | --*/ 40 | 41 | #include 42 | #include 43 | #include 44 | #include "stgui.h" 45 | #include "stguires.h" 46 | #include "stguiview.h" 47 | 48 | 49 | // 50 | // Global view object 51 | // 52 | CStGuiView *g_pViewObj = NULL; 53 | 54 | 55 | 56 | /*++ 57 | 58 | Routine Name: 59 | 60 | WndProc 61 | 62 | Routine Description: 63 | 64 | Our Windows message handling routine. Routes control to 65 | our view class's message handling code. 66 | 67 | Returns: 68 | 69 | If a message is handled the return value is zero. Otherwise 70 | its non-zero. 71 | 72 | 73 | --*/ 74 | LRESULT CALLBACK 75 | WndProc( HWND hwnd, 76 | UINT nMsg, 77 | WPARAM wParam, 78 | LPARAM lParam) 79 | { 80 | return g_pViewObj->WndProc( hwnd, 81 | nMsg, 82 | wParam, 83 | lParam); 84 | } 85 | 86 | 87 | 88 | /*++ 89 | 90 | Routine Name: 91 | 92 | WinMain 93 | 94 | Routine Description: 95 | 96 | Entry point for the application 97 | 98 | Returns: 99 | 100 | 101 | 102 | 103 | --*/ 104 | int WINAPI 105 | WinMain( HINSTANCE hInstance, 106 | HINSTANCE /* hPrevInstance */, 107 | PSTR /* szCmdLine */, 108 | int /* iCmdShow */) 109 | { 110 | int funcResult = 0; 111 | MSG msg; 112 | 113 | g_pViewObj = new CStGuiView(hInstance); 114 | 115 | if (!g_pViewObj) 116 | { 117 | ::MessageBox( NULL, 118 | L"Memory allocation failure.....\n", 119 | L"Resource Error", 120 | MB_OK); 121 | funcResult = 1; 122 | goto funcExit; 123 | } 124 | 125 | g_pViewObj->InitInstance(); 126 | 127 | stInitStrace(g_pViewObj); 128 | 129 | 130 | // 131 | // Message loop 132 | // 133 | int status; 134 | while ((status = GetMessage(&msg, NULL, 0, 0)) != 0) 135 | { 136 | if (status == -1) 137 | { 138 | funcResult = -1; 139 | goto funcExit; 140 | } 141 | 142 | if (!TranslateAccelerator(g_pViewObj->GetMainWindow(), g_pViewObj->GetAccel(), &msg)) 143 | { 144 | TranslateMessage(&msg); 145 | DispatchMessage(&msg); 146 | } 147 | } 148 | 149 | funcExit: 150 | 151 | if (g_pViewObj) 152 | { 153 | delete g_pViewObj; 154 | } 155 | 156 | return funcResult; 157 | } 158 | 159 | -------------------------------------------------------------------------------- /src/app/cli/stcliview.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | #include "stcliview.h" 30 | 31 | 32 | WORD 33 | ChangeTextClr( 34 | WORD colorNew) 35 | /*++ 36 | 37 | Routine Description: 38 | 39 | Set the new console text color and return the old 40 | console text color 41 | 42 | Return: 43 | 44 | Previous Color 45 | 46 | --*/ 47 | { 48 | HANDLE conOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE); 49 | 50 | CONSOLE_SCREEN_BUFFER_INFO consoleInfo; 51 | 52 | GetConsoleScreenBufferInfo( 53 | conOutputHandle, 54 | &consoleInfo); 55 | 56 | SetConsoleTextAttribute( 57 | conOutputHandle, 58 | colorNew); 59 | 60 | return consoleInfo.wAttributes; 61 | } 62 | 63 | 64 | void 65 | CStCuiView::PrintW( 66 | WORD inClr, 67 | LPCWSTR inFormat, 68 | va_list inArgList) 69 | { 70 | WORD oldClr = ChangeTextClr(inClr); 71 | vwprintf(inFormat, inArgList); 72 | ChangeTextClr(oldClr); 73 | } 74 | 75 | 76 | void 77 | CStCuiView::PrintA( 78 | WORD inClr, 79 | LPCSTR inFormat, 80 | va_list inArgList) 81 | { 82 | WORD oldClr = ChangeTextClr(inClr); 83 | vprintf(inFormat, inArgList); 84 | ChangeTextClr(oldClr); 85 | } 86 | 87 | 88 | void 89 | CStCuiView::PrintMessage( 90 | LPCWSTR inFormat, 91 | ...) 92 | { 93 | va_list argList; 94 | va_start(argList, inFormat); 95 | PrintW(FOREGROUND_WHITE, inFormat, argList); 96 | } 97 | 98 | void 99 | CStCuiView::PrintTitle( 100 | LPCWSTR inFormat, 101 | ...) 102 | { 103 | va_list argList; 104 | va_start(argList, inFormat); 105 | PrintW(FOREGROUND_GREEN | FOREGROUND_INTENSITY, inFormat, argList); 106 | } 107 | 108 | 109 | void 110 | CStCuiView::PrintTrace( 111 | LPCWSTR inFormat, 112 | ...) 113 | { 114 | va_list argList; 115 | va_start(argList, inFormat); 116 | PrintW(FOREGROUND_INTENSITY, inFormat, argList); 117 | } 118 | 119 | void 120 | CStCuiView::PrintTraceA( 121 | LPCSTR inFormat, 122 | ...) 123 | { 124 | va_list argList; 125 | va_start(argList, inFormat); 126 | PrintA(FOREGROUND_INTENSITY, inFormat, argList); 127 | } 128 | 129 | void 130 | CStCuiView::PrintTraceOrig( 131 | LPCWSTR inFormat, 132 | ...) 133 | { 134 | va_list argList; 135 | va_start(argList, inFormat); 136 | PrintW(FOREGROUND_BLUE | FOREGROUND_INTENSITY, inFormat, argList); 137 | } 138 | 139 | void 140 | CStCuiView::PrintTraceOrigA( 141 | LPCSTR inFormat, 142 | ...) 143 | { 144 | va_list argList; 145 | va_start(argList, inFormat); 146 | PrintA(FOREGROUND_BLUE | FOREGROUND_INTENSITY, inFormat, argList); 147 | } 148 | 149 | 150 | void 151 | CStCuiView::PrintWarning( 152 | LPCWSTR inFormat, 153 | ...) 154 | { 155 | va_list argList; 156 | va_start(argList, inFormat); 157 | PrintW( 158 | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY, 159 | inFormat, 160 | argList); 161 | } 162 | 163 | 164 | void 165 | CStCuiView::PrintError( 166 | LPCWSTR inFormat, 167 | ...) 168 | { 169 | va_list argList; 170 | va_start(argList, inFormat); 171 | PrintW(FOREGROUND_RED | FOREGROUND_INTENSITY, inFormat, argList); 172 | } 173 | 174 | void 175 | CStCuiView::PrintErrorA( 176 | LPCSTR inFormat, 177 | ...) 178 | { 179 | va_list argList; 180 | va_start(argList, inFormat); 181 | PrintA(FOREGROUND_RED | FOREGROUND_INTENSITY, inFormat, argList); 182 | } 183 | 184 | -------------------------------------------------------------------------------- /src/serum/xprintf.c: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------/ 2 | / 3 | / Copyright(C) 2011, ChaN, all right reserved. 4 | / 5 | / *This software is a free software and there is NO WARRANTY. 6 | / *No restriction on use.You can use, modify and redistribute it for 7 | / personal, non - profit or commercial products UNDER YOUR RESPONSIBILITY. 8 | / *Redistributions of source code must retain the above copyright notice. 9 | / 10 | /--------------------------------------------------------------------------*/ 11 | 12 | typedef char* x_va_list; 13 | #define x_va_start _x_va_start 14 | #define x_va_arg _x_va_arg 15 | #define x_va_end _x_va_end 16 | 17 | #define _X_ADDRESSOF(v) (&(v)) 18 | #define _X_INTSIZEOF(n) ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1)) 19 | 20 | #define _x_va_start(ap,v) (ap = (x_va_list)_X_ADDRESSOF(v) + _X_INTSIZEOF(v)) 21 | #define _x_va_arg(ap,t) (*(t *)((ap += _X_INTSIZEOF(t)) - _X_INTSIZEOF(t))) 22 | #define _x_va_end(ap) (ap = (x_va_list)0) 23 | 24 | typedef struct _xout { 25 | char *outptr; 26 | } xout, *pxout; 27 | 28 | void 29 | xputc(pxout xo, char c) 30 | { 31 | *xo->outptr++ = (unsigned char)c; 32 | } 33 | 34 | void 35 | xputs(pxout xo, const char *str) 36 | { 37 | while (*str) 38 | xputc(xo, *str++); 39 | } 40 | 41 | static void 42 | xvprintf(pxout xo, const char *fmt, x_va_list arp) 43 | { 44 | unsigned int r, i, j, w, f; 45 | unsigned long v; 46 | char s[16], c, d, *p; 47 | 48 | 49 | for (;;) { 50 | c = *fmt++; /* Get a char */ 51 | if (!c) 52 | break; 53 | if (c != '%') { /* Pass through it if not a % sequense */ 54 | xputc(xo, c); 55 | continue; 56 | } 57 | f = 0; 58 | c = *fmt++; /* Get first char of the sequense */ 59 | if (c == '0') { /* Flag: '0' padded */ 60 | f = 1; 61 | c = *fmt++; 62 | } 63 | else { 64 | if (c == '-') { /* Flag: left justified */ 65 | f = 2; 66 | c = *fmt++; 67 | } 68 | } 69 | for (w = 0; c >= '0' && c <= '9'; c = *fmt++) /* Minimum width */ 70 | w = w * 10 + c - '0'; 71 | if (c == 'l' || c == 'L') { /* Prefix: Size is long int */ 72 | f |= 4; 73 | c = *fmt++; 74 | } 75 | if (!c) 76 | break; /* End of format? */ 77 | d = c; 78 | if (d >= 'a') 79 | d -= 0x20; 80 | switch (d) { /* Type is... */ 81 | case 'S': /* String */ 82 | p = x_va_arg(arp, char *); 83 | for (j = 0; p[j]; j++); 84 | while (!(f & 2) && j++ < w) 85 | xputc(xo, ' '); 86 | xputs(xo, p); 87 | while (j++ < w) 88 | xputc(xo, ' '); 89 | continue; 90 | case 'C': /* Character */ 91 | xputc(xo, (char)x_va_arg(arp, int)); 92 | continue; 93 | case 'B': /* Binary */ 94 | r = 2; 95 | break; 96 | case 'O': /* Octal */ 97 | r = 8; 98 | break; 99 | case 'D': /* Signed decimal */ 100 | case 'U': /* Unsigned decimal */ 101 | r = 10; 102 | break; 103 | case 'X': /* Hexdecimal */ 104 | r = 16; 105 | break; 106 | default: /* Unknown type (passthrough) */ 107 | xputc(xo, c); 108 | continue; 109 | } 110 | 111 | /* Get an argument and put it in numeral */ 112 | v = (f & 4) ? 113 | x_va_arg(arp, long) : 114 | ((d == 'D') ? 115 | (long)x_va_arg(arp, int) : 116 | (long)x_va_arg(arp, unsigned int)); 117 | 118 | if (d == 'D' && (v & 0x80000000)) { 119 | v = 0 - v; 120 | f |= 8; 121 | } 122 | i = 0; 123 | do { 124 | d = (char)(v % r); 125 | v /= r; 126 | if (d > 9) 127 | d += (c == 'x') ? 0x27 : 0x07; 128 | s[i++] = d + '0'; 129 | } 130 | while (v && i < sizeof(s)); 131 | if (f & 8) 132 | s[i++] = '-'; 133 | j = i; 134 | d = (f & 1) ? '0' : ' '; 135 | while (!(f & 2) && j++ < w) 136 | xputc(xo, d); 137 | do 138 | xputc(xo, s[--i]); 139 | while (i); 140 | while (j++ < w) 141 | xputc(xo, ' '); 142 | } 143 | } 144 | 145 | void 146 | xsprintf(char *buff, const char *fmt, ...) 147 | { 148 | x_va_list arp; 149 | xout xo; 150 | 151 | xo.outptr = buff; 152 | 153 | x_va_start(arp, fmt); 154 | xvprintf(&xo, fmt, arp); 155 | x_va_end(arp); 156 | 157 | *xo.outptr = 0; /* Terminate output string with a \0 */ 158 | } 159 | 160 | -------------------------------------------------------------------------------- /src/app/gui/stguiview.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | /*++ 30 | 31 | Module Name: 32 | 33 | stguiview.h 34 | 35 | Module Description: 36 | 37 | GUI Window for strace. 38 | 39 | --*/ 40 | 41 | #ifndef _STGUIVIEW_H_ 42 | #define _STGUIVIEW_H_ 43 | 44 | 45 | // System Include Files!!! 46 | #include 47 | #include 48 | #include 49 | 50 | 51 | // Local Include Files!!! 52 | #include "strace.h" 53 | 54 | 55 | // 56 | // Our Application's Title 57 | // 58 | 59 | #define STRACE_NT_WINDOW_TITLE L"IntellectualHeaven (R) System Call Tracer for NT, 2K, XP, 2K3" 60 | 61 | 62 | // 63 | // Unique child window identifiers 64 | // They should be unique for one parent 65 | // 66 | #define IDC_STATUS_BAR 20001 67 | #define IDC_TOOL_BAR 20002 68 | #define IDC_TRACE_LIST_VIEW 20003 69 | 70 | 71 | // 72 | // status bar related data 73 | // 74 | 75 | // Number of breaks in Status bar 76 | #define STATUS_BAR_NUM_PARTS 4 77 | #define STATUS_WIDTH_OF_FIRST_PART 75 78 | #define STATUS_WIDTH_OF_SECOND_PART 66 79 | #define STATUS_WIDTH_OF_THIRD_PART 176 80 | #define STATUS_WIDTH_OF_FOURTH_PART 98 81 | 82 | 83 | // 84 | // Class for the main StraceNT view 85 | // 86 | class CStGuiView : public CStView 87 | { 88 | public: 89 | CStGuiView(HINSTANCE hInstance); 90 | virtual ~CStGuiView(); 91 | 92 | void InitInstance(); 93 | void ExitInstance(); 94 | 95 | LRESULT WndProc( 96 | HWND hwnd, 97 | UINT nMsg, 98 | WPARAM wParam, 99 | LPARAM lParam); 100 | 101 | HWND GetMainWindow(); 102 | HACCEL GetAccel(); 103 | 104 | virtual void PrintMessage(LPCWSTR inFormat, ...); 105 | virtual void PrintTitle(LPCWSTR inFormat, ...); 106 | virtual void PrintTrace(LPCWSTR inFormat, ...); 107 | virtual void PrintTraceA(LPCSTR inFormat, ...); 108 | virtual void PrintTraceOrig(LPCWSTR inFormat, ...); 109 | virtual void PrintTraceOrigA(LPCSTR inFormat, ...); 110 | virtual void PrintWarning(LPCWSTR inFormat, ...); 111 | virtual void PrintError(LPCWSTR inFormat, ...); 112 | virtual void PrintErrorA(LPCSTR inFormat, ...); 113 | 114 | // Called by StraceThread to indicate that it is exiting 115 | void SignalStraceThreadExit(); 116 | 117 | private: 118 | 119 | void CreateMainWindow(); 120 | 121 | int CreateStatusBar(); 122 | void UpdateStatusBarData(); 123 | 124 | bool HandleMenuCommand(WORD inMenuCmd); 125 | void UpdateMenus(); 126 | void EnableMenuToolbarItem(DWORD inItemId, bool inEnable); 127 | 128 | void CreateToolBar(); 129 | void AddToolbarButton( 130 | int iBitmap, 131 | int idCommand, 132 | BYTE fsState, 133 | BYTE fsStyle, 134 | DWORD_PTR dwData, 135 | INT_PTR iString); 136 | 137 | void CreateTraceListCtrl(); 138 | 139 | void LaunchStraceThread(std::wstring& inCmdLine); 140 | void KillStraceThread(); 141 | 142 | void PrintW( 143 | ULONG inPrintWhat, 144 | LPCWSTR inFormat, 145 | va_list inArgList); 146 | void PrintA( 147 | ULONG inPrintWhat, 148 | LPCSTR inFormat, 149 | va_list inArgList); 150 | 151 | int SaveAppInformation(); 152 | int LoadAppInformation(RECT *pRect); 153 | 154 | 155 | // 156 | // Window handles and other class data required for our view class 157 | // 158 | HINSTANCE m_hInstance; 159 | HWND m_hwnd; 160 | HWND m_hwndStatus; 161 | HWND m_hwndToolBar; 162 | HACCEL m_hAccel; 163 | 164 | HWND m_hwndListCtrl; 165 | HFONT m_TraceListFont; 166 | HFONT m_TraceListFontBold; 167 | 168 | HANDLE mThreadHandle; 169 | DWORD mThreadId; 170 | bool mTraceRunning; 171 | 172 | bool m_OldComctl32; 173 | 174 | }; 175 | 176 | 177 | #endif 178 | -------------------------------------------------------------------------------- /src/inc/stcmn.h: -------------------------------------------------------------------------------- 1 | #ifndef _ST_CMN_H_ 2 | #define _ST_CMN_H_ 3 | 4 | typedef struct _ST_TRACE_OPTIONS { 5 | bool EnableAntiDebugMeasures; 6 | bool EnableDebugging; 7 | ULONG LoggingLevel; 8 | bool UseSharedMemory; 9 | LUID TraceMemoryLuid; 10 | ULONG TraceBufferCount; 11 | ULONG IncludeListOffset; 12 | ULONG ExcludeListOffset; 13 | } ST_TRACE_OPTIONS, *PST_TRACE_OPTIONS; 14 | 15 | typedef enum _ST_TRACE_TYPE { 16 | ST_TRACE_FUNCTION_CALL, 17 | ST_TRACE_MESSAGE, 18 | } ST_TRACE_TYPE; 19 | 20 | typedef struct _ST_TRACE_DATA { 21 | volatile BOOL IsReady; 22 | ST_TRACE_TYPE TraceType; 23 | CHAR FunctionName[64]; 24 | ULONG_PTR FunctionArgs[4]; 25 | ULONG_PTR Ecx; 26 | ULONG_PTR Edx; 27 | ULONG_PTR OrigReturnValue; 28 | BOOL IsReturnValueModified; 29 | ULONG_PTR NewReturnValue; 30 | } ST_TRACE_DATA, *PST_TRACE_DATA; 31 | 32 | typedef struct _IHI_RING_BUFFER { 33 | ULONG Mask; 34 | volatile ULONG Head; 35 | volatile ULONG Tail; 36 | volatile BOOL BlockWriteOnFull; 37 | } IHI_RING_BUFFER, *PIHI_RING_BUFFER; 38 | 39 | typedef struct _IHI_SHARED_MEMORY { 40 | HANDLE Handle; 41 | PVOID Memory; 42 | } IHI_SHARED_MEMORY, *PIHI_SHARED_MEMORY; 43 | 44 | inline 45 | bool 46 | ihiRingBufferInit(PIHI_RING_BUFFER ioRingBuffer, ULONG inSize, BOOL inBlockWriteOnFull) 47 | { 48 | if ((inSize & (inSize - 1)) != 0) 49 | { 50 | // 51 | // Only 2 ^ n size is supported as this makes it very easy to do a modulo 52 | // operation that is needed for circular ring buffer. 53 | // 54 | return false; 55 | } 56 | 57 | ioRingBuffer->Mask = inSize - 1; 58 | ioRingBuffer->BlockWriteOnFull = inBlockWriteOnFull; 59 | ioRingBuffer->Head = 0; 60 | ioRingBuffer->Tail = 0; 61 | return true; 62 | } 63 | 64 | inline 65 | void 66 | ihiRingBufferUpdate(PIHI_RING_BUFFER ioRingBuffer, BOOL inBlockWriteOnFull) 67 | { 68 | ioRingBuffer->BlockWriteOnFull = inBlockWriteOnFull; 69 | } 70 | 71 | inline 72 | bool 73 | ihiRingBufferIsEmpty(PIHI_RING_BUFFER inRingBuffer) 74 | { 75 | return (inRingBuffer->Head == inRingBuffer->Tail); 76 | } 77 | 78 | inline 79 | bool 80 | ihiRingBufferAllocate(PIHI_RING_BUFFER ioRingBuffer, PULONG outIndex) 81 | { 82 | bool status = false; 83 | struct _IHI_RING_BUFFER rb = { 0 }; 84 | rb; 85 | _asm 86 | { 87 | mov ebx, ioRingBuffer; 88 | 89 | checkFull: 90 | mov eax, [ebx]rb.Tail; 91 | mov ecx, eax; 92 | inc ecx; 93 | mov edx, [ebx]rb.Mask; 94 | and ecx, edx; 95 | mov edx, [ebx]rb.Head; 96 | cmp ecx, edx; 97 | jne tryAlloc; 98 | 99 | mov eax, [ebx]rb.BlockWriteOnFull; 100 | test eax, eax; 101 | jnz checkFull; 102 | jmp done; 103 | 104 | tryAlloc : 105 | lock cmpxchg [ebx]rb.Tail, ecx; 106 | jnz checkFull; 107 | mov ecx, outIndex; 108 | mov [ecx], eax; 109 | mov eax, 1; 110 | 111 | done: 112 | mov status, al; 113 | } 114 | 115 | return status; 116 | } 117 | 118 | inline 119 | VOID 120 | ihiRingBufferFree(PIHI_RING_BUFFER ioRingBuffer) 121 | { 122 | struct _IHI_RING_BUFFER rb = { 0 }; 123 | rb; 124 | _asm 125 | { 126 | mov ebx, ioRingBuffer; 127 | 128 | tryFree: 129 | mov eax, [ebx]rb.Head; 130 | mov ecx, eax; 131 | inc ecx; 132 | mov edx, [ebx]rb.Mask; 133 | and ecx, edx; 134 | lock cmpxchg [ebx]rb.Head, ecx; 135 | jnz tryFree; 136 | } 137 | } 138 | 139 | inline 140 | BOOL 141 | ihiCreateSharedMemory(LPCWSTR inName, ULONG inSize, PIHI_SHARED_MEMORY oSharedMemory) 142 | { 143 | BOOL status; 144 | 145 | status = FALSE; 146 | 147 | oSharedMemory->Handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, 148 | PAGE_READWRITE, 0, inSize, 149 | inName); 150 | if (oSharedMemory->Handle == NULL) 151 | { 152 | goto Exit; 153 | } 154 | 155 | oSharedMemory->Memory = (PVOID)MapViewOfFile(oSharedMemory->Handle, 156 | FILE_MAP_ALL_ACCESS, 0, 0, 157 | inSize); 158 | if (oSharedMemory->Memory == NULL) 159 | { 160 | CloseHandle(oSharedMemory->Handle); 161 | goto Exit; 162 | } 163 | 164 | memset(oSharedMemory->Memory, 0, inSize); 165 | status = TRUE; 166 | 167 | Exit: 168 | 169 | return status; 170 | } 171 | 172 | inline 173 | BOOL 174 | ihiOpenSharedMemory(LPCWSTR inName, ULONG inSize, PIHI_SHARED_MEMORY oSharedMemory) 175 | { 176 | BOOL status; 177 | 178 | status = FALSE; 179 | 180 | oSharedMemory->Handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, 181 | inName); 182 | if (oSharedMemory->Handle == NULL) 183 | { 184 | goto Exit; 185 | } 186 | 187 | oSharedMemory->Memory = (PVOID)MapViewOfFile(oSharedMemory->Handle, 188 | FILE_MAP_ALL_ACCESS, 0, 0, 189 | inSize); 190 | if (oSharedMemory->Memory == NULL) 191 | { 192 | CloseHandle(oSharedMemory->Handle); 193 | goto Exit; 194 | } 195 | 196 | status = TRUE; 197 | 198 | Exit: 199 | 200 | return status; 201 | } 202 | 203 | inline 204 | VOID 205 | ihiCloseSharedMemory(PIHI_SHARED_MEMORY inSharedMemory) 206 | { 207 | UnmapViewOfFile(inSharedMemory->Memory); 208 | CloseHandle(inSharedMemory->Handle); 209 | } 210 | 211 | 212 | extern IHI_SHARED_MEMORY gTraceMemory; 213 | extern PIHI_RING_BUFFER gTraceRingBuffer; 214 | extern PST_TRACE_DATA gTraceBuffer; 215 | 216 | #endif 217 | 218 | -------------------------------------------------------------------------------- /make/stracent.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {FE15209A-9026-4B4C-9D52-83EC133EECA3} 31 | Win32Proj 32 | StraceNt 33 | 34 | 35 | 36 | Application 37 | true 38 | Unicode 39 | v120_xp 40 | 41 | 42 | Application 43 | false 44 | true 45 | Unicode 46 | v120_xp 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | true 60 | $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);..\extrn\ihulib\bin\$(Platform)\$(Configuration) 61 | $(SolutionDir)..\bld\bin\$(Configuration)\ 62 | $(SolutionDir)..\bld\tmp\$(ProjectName)\$(Configuration)\ 63 | 64 | 65 | false 66 | $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);..\extrn\ihulib\bin\$(Platform)\$(Configuration) 67 | $(SolutionDir)..\bld\bin\$(Configuration)\ 68 | $(SolutionDir)..\bld\tmp\$(ProjectName)\$(Configuration)\ 69 | 70 | 71 | 72 | 73 | 74 | Level3 75 | Disabled 76 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS; 77 | $(SolutionDir)..\src\app;$(SolutionDir)..\src\inc;$(SolutionDir)..\extrn\ihulib\bin; 78 | 79 | 80 | Console 81 | true 82 | $(OutDir) 83 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);psapi.lib;ihulib.lib; 84 | 85 | 86 | $(SolutionDir)..\src\inc;$(OutDir);$(SolutionDir)..\src\app; 87 | 88 | 89 | xcopy /EY $(TargetPath) $(SolutionDir)..\bld\final\ 90 | 91 | 92 | 93 | 94 | Level3 95 | 96 | 97 | MaxSpeed 98 | true 99 | true 100 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS; 101 | $(SolutionDir)..\src\app;$(SolutionDir)..\src\inc;$(SolutionDir)..\extrn\ihulib\bin; 102 | 103 | 104 | Console 105 | true 106 | true 107 | true 108 | $(OutDir) 109 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);psapi.lib;ihulib.lib; 110 | 111 | 112 | $(SolutionDir)..\src\inc;$(OutDir);$(SolutionDir)..\src\app; 113 | 114 | 115 | xcopy /EY $(TargetPath) $(SolutionDir)..\bld\final\ 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /src/app/stFilter.txt: -------------------------------------------------------------------------------- 1 | #++ 2 | # 3 | # Sample Trace filter file for StraceNT 4 | # Copyright (c) Pankaj Garg. All rights reserved 5 | # 6 | # 7 | # Usage Notes: 8 | # 9 | # You can specify INCLUDES and EXCLUDES in this filter file. You 10 | # can include/exclude a module (or dll) for tracing or even chose 11 | # their individual functions for tracing 12 | # 13 | # In the filters, you can specify an absolute name like name of a 14 | # function or dll (eg EnterCriticalSection or kernel32.dll or 15 | # user32.dll) or you can specify * which means all 16 | # 17 | # Rules of prcedence 18 | # 19 | # An absolute name takes precedence over a pattern. If you 20 | # specify EnterCriticalSection in includes and Enter* in excludes 21 | # then EnterCriticalSection would be included but all other functions 22 | # which start with Enter would be excluded. Similarly if you specify 23 | # Load* in includes and LoadLibraryExA in excludes, then all the 24 | # functions would be included for tracing except LoadLibraryExA 25 | # 26 | # This prcedence rule is designed to give a user finer control on 27 | # inclusion/exclusion of functions for tracing 28 | # 29 | # If same absolute name or pattern is specified in both INCLUDES and 30 | # EXCLUDES then INCLUDES takes preference over EXCLUDES. 31 | # 32 | # By default everything is included. You need to specify EXCLUDES 33 | # to exclude particular modules from tracing 34 | # 35 | #-- 36 | 37 | 38 | #################################################################### 39 | # Calling modules, Owner modules and Imported functions # 40 | #################################################################### 41 | # # 42 | # The diagram below shows how the modules are loaded and the # 43 | # relationship between calling module, owner module and function # 44 | # name The sample process is wordpad.exe. # 45 | # # 46 | # Calling/Loaded Owner/Imported Imported Functions # 47 | # Module Module # 48 | # ------------- --------------- ------------------ # 49 | # wordpad.exe # 50 | # |- gdi32.dll (fgA, fgB, ...) # 51 | # |- kernel32.dll (fkA, fkB, ...) # 52 | # gdi32.dll # 53 | # |- kernel32.dll (fkA, fkX, fkY, ...) # 54 | # kernel32.dll # 55 | # |- ntdll.dll (fnA, fnB, ...) # 56 | # ntdll.dll # 57 | # |- (No imports - Ntdll doesn't import anything) # 58 | # # 59 | # In the above example: # 60 | # - wordpad.exe uses functions from kernel32.dll and gdi32.dll # 61 | # - gdi32.dll also imports function from kernel32.dll # 62 | # - kernel32.dll imports functions from ntdll.dll # 63 | # - ntdll.dll doesn't import any functions so it is not dependent # 64 | # on any other module # 65 | # # 66 | # StraceNT gives you fine control on which functions to trace when # 67 | # called by which module. For example if you want to trace all # 68 | # calls to CreateFileW made by notepad.exe, you can put an include # 69 | # filter as, .:kernel32.dll:CreateFileW, If you wish to trace all # 70 | # calls to CreateFileW from all modules, you can do # 71 | # *:kernel32.dll:CreateFileW # 72 | # # 73 | #################################################################### 74 | 75 | 76 | #################################################################### 77 | # INCLUDES and EXCLUDES FORMAT SPECIFICATION # 78 | #################################################################### 79 | # # 80 | # Calling_Module:Owning_Module:Imported_Function # 81 | # # 82 | # Use . for Calling Module to indicate the main program executable # 83 | # Use * for Calling Module to indicate any calling module # 84 | # # 85 | # Use * for Owning Module to trace all the owning modules. For # 86 | # example, something like .:*:* will trace all calls from all the # 87 | # DLLs made by wordpad.exe (if we are tracing wordpad.exe) # 88 | # # 89 | # Use * for Imported Functions to trace all the functions imported # 90 | # from the corressponding owning module # 91 | # # 92 | # NOTE: Put each INCLUDE/EXCLUDE entry at a seperate line # 93 | # # 94 | #################################################################### 95 | 96 | 97 | #################################################################### 98 | # SAMPLE FOR INCLUDES/EXCLUDES FILTER # 99 | #################################################################### 100 | # # 101 | # The sample below uses notepad.exe as an example. It specify inc- # 102 | # -ludes and excludes a way such that EnterCriticalSection when c- # 103 | # -alled by notepad.exe is traced and all the functions of user32- # 104 | # -.dll are traced when called by notepad.exe. If any other module # 105 | # like user32.dll or gdi32.dll calls EnterCriticalSection, they r # 106 | # not traced # 107 | # # 108 | #################################################################### 109 | 110 | 111 | # Trace EnterCriticialSection calls if called directly by notepad.exe 112 | INCLUDES=.:kernel32.dll:EnterCriticalSection 113 | 114 | 115 | # Trace ReadProcessMemory calls if called from gdi32.dll 116 | INCLUDES=gdi32.dll:kernel32.dll:ReadProcessMemory 117 | 118 | 119 | # Trace CreateFileW calls from all the modules 120 | INCLUDES=*:kernel32.dll:CreateFileW 121 | 122 | 123 | # Trace CreateFileW calls from the main process exe but return -1 if 124 | # it is called from main process executable 125 | # To test this run straceNt -f stfilter.txt notepad.exe and you will see 126 | # that notepad is unable to open any file because we return -1 which 127 | # is INVALID_HANDLE_VALUE from CreateFileW 128 | INCLUDES=*:kernel32.dll:CreateFileW=-1 129 | 130 | 131 | # Exclude everything except what is specified in INCLUDES 132 | EXCLUDES=*:*:* 133 | 134 | -------------------------------------------------------------------------------- /make/stserum.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {D48A7EAF-8C12-4C53-90D0-9A228D9E113E} 31 | stserum 32 | 33 | 34 | 35 | DynamicLibrary 36 | true 37 | Unicode 38 | v120_xp 39 | 40 | 41 | DynamicLibrary 42 | false 43 | true 44 | Unicode 45 | v120_xp 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);..\extrn\ihulib\bin\$(Platform)\$(Configuration) 59 | $(SolutionDir)..\bld\bin\$(Configuration)\ 60 | $(SolutionDir)..\bld\tmp\$(ProjectName)\$(Configuration)\ 61 | 62 | 63 | $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);..\extrn\ihulib\bin\$(Platform)\$(Configuration) 64 | $(SolutionDir)..\bld\bin\$(Configuration)\ 65 | $(SolutionDir)..\bld\tmp\$(ProjectName)\$(Configuration)\ 66 | 67 | 68 | 69 | Level3 70 | Disabled 71 | $(SolutionDir)..\src\inc;$(SolutionDir)..\extrn\ihulib\bin; 72 | _WINDLL;%(PreprocessorDefinitions)_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS; 73 | NoListing 74 | 75 | 76 | true 77 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);psapi.lib;ihulib.lib; 78 | $(OutDir) 79 | $(SolutionDir)..\src\serum\stserum.def 80 | Console 81 | 82 | 83 | $(SolutionDir)..\src\inc; 84 | 85 | 86 | xcopy /EY $(TargetPath) $(SolutionDir)..\bld\final\ 87 | 88 | 89 | $(SolutionDir)\prebuild.cmd 90 | 91 | 92 | 93 | 94 | Level3 95 | MaxSpeed 96 | true 97 | true 98 | $(SolutionDir)..\src\inc;$(SolutionDir)..\extrn\ihulib\bin; 99 | _WINDLL;%(PreprocessorDefinitions)_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS; 100 | NoListing 101 | 102 | 103 | true 104 | true 105 | true 106 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);psapi.lib;ihulib.lib; 107 | $(OutDir) 108 | $(SolutionDir)..\src\serum\stserum.def 109 | Console 110 | 111 | 112 | $(SolutionDir)..\src\inc; 113 | 114 | 115 | xcopy /EY $(TargetPath) $(SolutionDir)..\bld\final\ 116 | 117 | 118 | $(SolutionDir)\prebuild.cmd 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /make/straceui.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | {B95CC236-749A-4152-9C50-3246B72B010D} 36 | Win32Proj 37 | StraceNtUi 38 | straceui 39 | 40 | 41 | 42 | Application 43 | true 44 | Unicode 45 | v120_xp 46 | 47 | 48 | Application 49 | false 50 | true 51 | Unicode 52 | v120_xp 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | true 66 | $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);..\extrn\ihulib\bin\$(Platform)\$(Configuration) 67 | $(SolutionDir)..\bld\bin\$(Configuration)\ 68 | $(SolutionDir)..\bld\tmp\$(ProjectName)\$(Configuration)\ 69 | 70 | 71 | false 72 | $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);..\extrn\ihulib\bin\$(Platform)\$(Configuration) 73 | $(SolutionDir)..\bld\bin\$(Configuration)\ 74 | $(SolutionDir)..\bld\tmp\$(ProjectName)\$(Configuration)\ 75 | 76 | 77 | 78 | 79 | 80 | Level3 81 | Disabled 82 | WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS; 83 | $(SolutionDir)..\src\app;$(SolutionDir)..\src\inc;$(SolutionDir)..\extrn\ihulib\bin; 84 | 85 | 86 | Windows 87 | true 88 | $(OutDir) 89 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);psapi.lib;ihulib.lib;comctl32.lib; 90 | 91 | 92 | $(SolutionDir)..\src\inc;$(OutDir);$(SolutionDir)..\src\app; 93 | 94 | 95 | xcopy /EY $(TargetPath) $(SolutionDir)..\bld\final\ 96 | 97 | 98 | 99 | 100 | Level3 101 | 102 | 103 | MaxSpeed 104 | true 105 | true 106 | WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS; 107 | $(SolutionDir)..\src\app;$(SolutionDir)..\src\inc;$(SolutionDir)..\extrn\ihulib\bin; 108 | 109 | 110 | Windows 111 | true 112 | true 113 | true 114 | $(OutDir) 115 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);psapi.lib;ihulib.lib;comctl32.lib; 116 | 117 | 118 | $(SolutionDir)..\src\inc;$(OutDir);$(SolutionDir)..\src\app; 119 | 120 | 121 | xcopy /EY $(TargetPath) $(SolutionDir)..\bld\final\ 122 | 123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /src/serum/serum.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | /*++ 30 | 31 | Module Description: 32 | 33 | Implements DllMain and other exported routines. 34 | 35 | --*/ 36 | 37 | #include "serum.h" 38 | 39 | // 40 | // Global handle to DLL Instance. This handle is used to make sure/ that we 41 | // don't patch ourselves when we are patching various modules. 42 | // 43 | // 44 | HINSTANCE g_hInstance = NULL; 45 | 46 | // 47 | // Global variable to manage multiple patching 48 | // i.e if user tries to patch the same process 49 | // twice 50 | // 51 | bool g_processPatched = false; 52 | 53 | // 54 | // Name of main process executable 55 | // 56 | std::string g_MainExeName; 57 | 58 | // 59 | // Used to maintain the count of number of threads attached 60 | // to our injector DLL 61 | // 62 | LONG gThreadReferenceCount; 63 | 64 | // 65 | // Representation of command line options. 66 | // 67 | bool gEnableAntiDebugMeasures = false; 68 | 69 | // 70 | // Global to store shared memory pointers for trace buffers. 71 | // 72 | bool gUseSharedMemory = false; 73 | IHI_SHARED_MEMORY gTraceMemory; 74 | PIHI_RING_BUFFER gTraceRingBuffer; 75 | PST_TRACE_DATA gTraceBuffer; 76 | 77 | /*++ 78 | 79 | Routine Name: 80 | 81 | IhSerumLoad 82 | 83 | Routine Description: 84 | 85 | Patch the given modules of the process 86 | in which this DLL is loaded 87 | 88 | Routine Arguments: 89 | 90 | inFnIncludes 91 | Which functions to include 92 | 93 | inFnExcludes 94 | Which functions to exclude 95 | 96 | Return: 97 | 98 | none 99 | 100 | --*/ 101 | void 102 | WINAPI 103 | IhSerumLoad(PVOID inContext, ULONG inContextSize) 104 | { 105 | PST_TRACE_OPTIONS trcOptions; 106 | DWORD osVersion; 107 | 108 | trcOptions = (PST_TRACE_OPTIONS)inContext; 109 | 110 | // 111 | // TODO: Validate if IncludeListOffset and ExcludeListOffset fall 112 | // with-in inContext size or not. 113 | // 114 | 115 | gDebug = trcOptions->EnableDebugging; 116 | ihiDebugLoop(gDebug); 117 | 118 | IhuSetDbgLogLevel(trcOptions->LoggingLevel); 119 | 120 | // 121 | // Detect ProcessHeap field offsets for disabling debugger detection. 122 | // 123 | osVersion = GetVersion(); 124 | gMajorOSVersion = (DWORD)(LOBYTE(LOWORD(osVersion))); 125 | 126 | // 127 | // Setup shared memory for trace data. 128 | // 129 | if (trcOptions->UseSharedMemory) 130 | { 131 | wchar_t shmName[64]; 132 | wsprintf(shmName, L"%08x%08x", 133 | trcOptions->TraceMemoryLuid.HighPart, 134 | trcOptions->TraceMemoryLuid.LowPart); 135 | ULONG shmSize; 136 | shmSize = sizeof(IHI_RING_BUFFER) + sizeof(ST_TRACE_DATA) * trcOptions->TraceBufferCount; 137 | if (ihiOpenSharedMemory(shmName, shmSize, &gTraceMemory)) 138 | { 139 | gTraceRingBuffer = (PIHI_RING_BUFFER)gTraceMemory.Memory; 140 | gTraceBuffer = (PST_TRACE_DATA)((PUCHAR)gTraceRingBuffer + sizeof(IHI_RING_BUFFER)); 141 | gUseSharedMemory = true; 142 | } 143 | else 144 | { 145 | IHU_DBG_LOG_EX(TRC_INJECTOR, IHU_LEVEL_FATAL, 146 | L"Failed to open shared memory (Error: %x), using OutputDebugString as fallback.\n", 147 | GetLastError()); 148 | } 149 | } 150 | 151 | gTlsIndex = TlsAlloc(); 152 | if (gTlsIndex == TLS_OUT_OF_INDEXES) 153 | { 154 | IHU_DBG_LOG_EX(TRC_INJECTOR, IHU_LEVEL_FATAL, 155 | L"Failed to allocate a TLS Index, patching cannot continue.\n"); 156 | goto Exit; 157 | } 158 | 159 | IHU_DBG_LOG_EX(TRC_INJECTOR, IHU_LEVEL_INFO, 160 | L"TLS Index successfully allocated. Value: %x.\n", gTlsIndex); 161 | 162 | ihiDisableReEntrancy(); 163 | 164 | if (trcOptions->EnableAntiDebugMeasures) 165 | { 166 | IHU_DBG_LOG_EX(TRC_INJECTOR, IHU_LEVEL_LOUD, 167 | L"Enabling Anti-Debug Measures.\n"); 168 | ihiEnableAntiDebugMeasures(); 169 | } 170 | 171 | char szModuleName[MAX_PATH] = {0}; 172 | 173 | if (GetModuleBaseNameA(GetCurrentProcess(), GetModuleHandle(NULL), 174 | szModuleName, sizeof(szModuleName)) > 0) 175 | { 176 | g_MainExeName = szModuleName; 177 | } 178 | else 179 | { 180 | IHU_DBG_LOG_EX(TRC_INJECTOR, IHU_LEVEL_ERROR, 181 | L"Failed to obtain the main executable name. Error = %x\n", GetLastError()); 182 | } 183 | 184 | // 185 | // We need to patch based on Module name to patch, 186 | // Which modules import table to patch, and finally 187 | // which functions to patch 188 | // 189 | gPatchInclExclMgr.SetInclExclList((PCHAR)trcOptions + trcOptions->IncludeListOffset, 190 | (PCHAR)trcOptions + trcOptions->ExcludeListOffset); 191 | 192 | IHU_DBG_LOG_EX(TRC_INJECTOR, IHU_LEVEL_LOUD, L"Initiating the patching process.\n"); 193 | ihiPatchUnpatchModules(g_hInstance, true); 194 | 195 | g_processPatched = true; 196 | 197 | Exit: 198 | return; 199 | } 200 | 201 | 202 | 203 | /*++ 204 | 205 | Routine Name: 206 | 207 | ihiRemovePatching 208 | 209 | Routine Description: 210 | 211 | Remove all the previously patched 212 | modules 213 | 214 | Return: 215 | 216 | none 217 | 218 | --*/ 219 | void 220 | WINAPI 221 | IhSerumUnload() 222 | { 223 | if (g_processPatched) 224 | { 225 | ihiPatchUnpatchModules(g_hInstance, false); 226 | g_processPatched = false; 227 | } 228 | } 229 | 230 | 231 | 232 | 233 | volatile 234 | LONG 235 | WINAPI 236 | IhSerumGetRefCount() 237 | /*++ 238 | 239 | Routine Description: 240 | 241 | Returns the global thread reference count 242 | 243 | --*/ 244 | { 245 | return gThreadReferenceCount; 246 | } 247 | 248 | 249 | 250 | /*++ 251 | 252 | Routine Name: 253 | 254 | DllMain 255 | 256 | Routine Description: 257 | 258 | Entry point 259 | 260 | Return: 261 | 262 | none 263 | 264 | --*/ 265 | extern "C" 266 | BOOL 267 | WINAPI 268 | DllMain( 269 | HINSTANCE hInstance, 270 | DWORD dwReason, 271 | LPVOID lpReserved) 272 | { 273 | g_hInstance = hInstance; 274 | 275 | switch (dwReason) 276 | { 277 | case DLL_PROCESS_ATTACH: 278 | { 279 | IHU_DBG_LOG_EX(TRC_INJECTOR, IHU_LEVEL_FLOOD, L"Process attach signalled\n"); 280 | break; 281 | } 282 | case DLL_PROCESS_DETACH: 283 | { 284 | IHU_DBG_LOG_EX(TRC_INJECTOR, IHU_LEVEL_FLOOD, L"Process detach signalled\n"); 285 | IhSerumUnload(); 286 | gThreadReferenceCount = 0; 287 | break; 288 | } 289 | case DLL_THREAD_ATTACH: 290 | { 291 | break; 292 | } 293 | case DLL_THREAD_DETACH: 294 | { 295 | break; 296 | } 297 | } 298 | 299 | return TRUE; 300 | } 301 | 302 | -------------------------------------------------------------------------------- /src/app/gui/stgui.rc: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | /*++ 30 | 31 | Module Name: 32 | 33 | stgui.rc 34 | 35 | Module Description: 36 | 37 | Resource file for GUI version of StraceNt 38 | 39 | --*/ 40 | 41 | #include "windows.h" 42 | #include "ntverp.h" 43 | #include "stguires.h" 44 | #include "strace.rc" 45 | 46 | 47 | // 48 | // Menu Items 49 | // 50 | IDR_MENU MENU DISCARDABLE 51 | BEGIN 52 | POPUP "&File" 53 | BEGIN 54 | MENUITEM "Save Trace\tCtrl+S", ID_FILE_SAVE 55 | MENUITEM SEPARATOR 56 | MENUITEM "Exit\tAlt+F4", ID_FILE_EXIT 57 | END 58 | POPUP "&Trace" 59 | BEGIN 60 | MENUITEM "Launch New Process\tCtrl+N", ID_TRACE_NEW 61 | MENUITEM "Attach to Process\tCtrl+P", ID_TRACE_ATTACH 62 | MENUITEM SEPARATOR 63 | MENUITEM "Stop Tracing\tCtrl+Q", ID_TRACE_STOP 64 | END 65 | POPUP "&Configure" 66 | BEGIN 67 | MENUITEM "Filter Options\tCtrl+F", ID_CONFIG_FILTER 68 | END 69 | POPUP "&Help" 70 | BEGIN 71 | MENUITEM "About StraceNT\tCtrl+H", ID_HELP_ABOUT 72 | END 73 | END 74 | 75 | 76 | // 77 | // Bitmaps 78 | // 79 | IDB_ORANGE_OPTION BITMAP DISCARDABLE "res\\orangeOption.bmp" 80 | IDB_GREEN_OPTION BITMAP DISCARDABLE "res\\greenOption.bmp" 81 | IDB_ORANGE_ABOUT BITMAP DISCARDABLE "res\\orangeAbout.bmp" 82 | IDB_GREEN_ABOUT BITMAP DISCARDABLE "res\\greenAbout.bmp" 83 | IDB_ORANGE_STOP BITMAP DISCARDABLE "res\\orangeStop.bmp" 84 | IDB_GREEN_STOP BITMAP DISCARDABLE "res\\greenStop.bmp" 85 | IDB_IH_SYMBOL BITMAP DISCARDABLE "res\\ihSymbol.bmp" 86 | IDB_ABOUT_BTN BITMAP DISCARDABLE "res\\aboutBtn.bmp" 87 | 88 | 89 | // 90 | // Accelerators 91 | // 92 | IDR_MENU ACCELERATORS DISCARDABLE 93 | BEGIN 94 | "S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT 95 | 96 | "N", ID_TRACE_NEW, VIRTKEY, CONTROL, NOINVERT 97 | "P", ID_TRACE_ATTACH, VIRTKEY, CONTROL, NOINVERT 98 | "Q", ID_TRACE_STOP, VIRTKEY, CONTROL, NOINVERT 99 | 100 | "F", ID_CONFIG_FILTER, VIRTKEY, CONTROL, NOINVERT 101 | 102 | "H", ID_HELP_ABOUT, VIRTKEY, CONTROL, NOINVERT 103 | END 104 | 105 | 106 | 107 | // 108 | // Dialog 109 | // 110 | IDD_DIALOG_ABOUT DIALOGEX 0, 0, 200, 100 111 | STYLE WS_POPUP | WS_BORDER | WS_SYSMENU 112 | FONT 8, "MS Shell Dlg" 113 | BEGIN 114 | GROUPBOX "",IDC_STATIC,4,3,192,67 115 | CONTROL 1107,IDC_STATIC,"Static",SS_BITMAP | 116 | SS_REALSIZEIMAGE,6,10,68,64, WS_EX_TRANSPARENT 117 | LTEXT "StraceNT - System Call Tracer",IDC_STATIC,74,14,114,8 118 | LTEXT "Windows XP - Windows 10",IDC_STATIC,74,27,114,8 119 | LTEXT "Copyright (c) : Pankaj Garg",IDC_STATIC,74,40,88,8 120 | LTEXT "http://www.intellectualheaven.com",IDC_STATIC_LINK,74,53,114,8,SS_NOTIFY 121 | CONTROL 1108,IDOK,"Static",SS_BITMAP | SS_NOTIFY | SS_REALSIZEIMAGE, 122 | 60,75,10,10, WS_EX_TRANSPARENT 123 | END 124 | 125 | 126 | IDD_DIALOG_OPTIONS DIALOG DISCARDABLE 0, 0, 301, 282 127 | STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 128 | CAPTION "StraceNT Filter Options" 129 | FONT 8, "MS Shell Dlg" 130 | BEGIN 131 | CONTROL "Trace function calls made by main program executable only", 132 | IDC_CHECK_MAIN_EXE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,21, 133 | 205,10 134 | EDITTEXT IDC_EDIT_FN_NAME,12,84,100,12,ES_AUTOHSCROLL 135 | EDITTEXT IDC_EDIT_IMP_MOD,12,115,100,12,ES_AUTOHSCROLL 136 | EDITTEXT IDC_EDIT_LOADED_MOD,12,146,100,12,ES_AUTOHSCROLL 137 | PUSHBUTTON "&Include",IDC_BTN_INCL,11,165,50,14,0,WS_EX_STATICEDGE 138 | PUSHBUTTON "&Delete",IDC_BTN_DEL_INCL,71,165,50,14,0,WS_EX_STATICEDGE 139 | PUSHBUTTON "&Exclude",IDC_BTN_EXCL,157,165,50,14,0,WS_EX_STATICEDGE 140 | PUSHBUTTON "De&Lete",IDC_BTN_DEL_EXCL,217,165,50,14,0,WS_EX_STATICEDGE 141 | PUSHBUTTON "&Save",IDC_BTN_SAVE,179,255,50,14,0,WS_EX_STATICEDGE 142 | PUSHBUTTON "&Close",IDC_BTN_CLOSE,241,255,50,14,0,WS_EX_STATICEDGE 143 | CONTROL "",IDC_LIST_INCL,"SysListView32",LVS_REPORT | 144 | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER | 145 | WS_BORDER | WS_TABSTOP,9,184,136,66 146 | CONTROL "",IDC_LIST_EXCL,"SysListView32",LVS_REPORT | 147 | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER | 148 | WS_BORDER | WS_TABSTOP,155,184,136,66 149 | LTEXT "Function Name (Use * for all functions, Ord#### for functions exported by Ordinal number #### e.g. Ord1234 or Ord0004)", 150 | IDC_STATIC,12,37,272,16 151 | LTEXT "Calling module (Use . to represent main program exe, * to represent all modules)", 152 | IDC_STATIC,12,133,259,8 153 | LTEXT "Module that implements the function (Use * to represent any module)", 154 | IDC_STATIC,12,102,223,8 155 | GROUPBOX "Create a filter file for StraceNT", 156 | IDC_STATIC,4,4,294,272 157 | LTEXT "(You can also use FunctionName=ReturnValue to return a different value e.g. CreateFile=0 to always return 0 from CreateFile, Ord4534=90 to always return 90 from the function exported by Ordinal 4534 or *=-1 to return -1 from all the functions)", 158 | IDC_STATIC,12,56,270,24 159 | END 160 | 161 | IDD_DIALOG_ATTACH_PROCESS DIALOG DISCARDABLE 0, 0, 300, 304 162 | STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 163 | CAPTION "Attach to Process" 164 | FONT 8, "MS Shell Dlg" 165 | BEGIN 166 | CONTROL "",IDC_LIST_PROCESS,"SysListView32",LVS_REPORT | 167 | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | LVS_ALIGNLEFT | 168 | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP | LVS_SINGLESEL, 169 | 12,11,276,209 170 | PUSHBUTTON "&Refresh",ID_BTN_REFRESH,12,224,50,14,0,WS_EX_STATICEDGE 171 | CONTROL "Use the following StraceNT Filter File", 172 | IDC_CHECK_FILTER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 173 | 12,245,205,10 174 | EDITTEXT IDC_EDIT_FILTER_FILE,12,260,216,12,ES_AUTOHSCROLL 175 | PUSHBUTTON "&Browse",ID_BTN_BROWSE,238,260,50,14,0,WS_EX_STATICEDGE 176 | PUSHBUTTON "&Attach",IDOK,93,282,50,14,0,WS_EX_STATICEDGE 177 | PUSHBUTTON "&Cancel",IDCANCEL,157,282,50,14,0,WS_EX_STATICEDGE 178 | END 179 | 180 | IDD_DIALOG_LAUNCH_PROCESS DIALOG DISCARDABLE 0, 0, 209, 55 181 | STYLE DS_3DLOOK | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN 182 | FONT 8, "MS Shell DLG" 183 | BEGIN 184 | LTEXT "&Arguments:",IDC_STATIC,7,1,47,12,SS_CENTERIMAGE 185 | EDITTEXT IDC_EDIT_ARGS,54,1,155,12,ES_AUTOHSCROLL 186 | CONTROL "Use the following StraceNT Filter File", 187 | IDC_CHECK_FILTER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 188 | 7,20,205,10 189 | EDITTEXT IDC_EDIT_FILTER_FILE,7,32,142,12,ES_AUTOHSCROLL 190 | PUSHBUTTON "&Browse",ID_BTN_BROWSE,159,32,50,14,0,WS_EX_STATICEDGE 191 | // 192 | // Use the commented resource below when Start directory support 193 | // is added to strace and also when trace child process is available 194 | // 195 | // LTEXT "&Start directory:",IDC_STATIC,7,22,47,12,SS_CENTERIMAGE 196 | // EDITTEXT IDC_EDIT_START_DIR,54,22,155,12,ES_AUTOHSCROLL 197 | // CONTROL "&Debug child processes also",IDC_EXEOPEN_CHILD_PROCESSES, 198 | // "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,40,150,12 199 | // 200 | END 201 | -------------------------------------------------------------------------------- /src/app/gui/stoptionsdlg.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include "stoptionsdlg.h" 34 | #include "stguires.h" 35 | #include "stcommon.h" 36 | 37 | 38 | 39 | // 40 | // The code should only write ASCII text to the filter 41 | // file because we only support ASCII names in our filter 42 | // file 43 | // 44 | void 45 | stAddFilterToListView( 46 | HWND inListViewHwnd, 47 | HWND inDlgHwnd) 48 | { 49 | std::string fnName; 50 | std::string ownerMod; 51 | std::string callingMod; 52 | 53 | char itemText[MAX_PATH] = {0}; 54 | 55 | GetWindowTextA( 56 | GetDlgItem(inDlgHwnd, IDC_EDIT_FN_NAME), 57 | itemText, 58 | CHARCOUNT(itemText)); 59 | 60 | fnName = itemText; 61 | 62 | GetWindowTextA( 63 | GetDlgItem(inDlgHwnd, IDC_EDIT_IMP_MOD), 64 | itemText, 65 | CHARCOUNT(itemText)); 66 | 67 | ownerMod = itemText; 68 | 69 | GetWindowTextA( 70 | GetDlgItem(inDlgHwnd, IDC_EDIT_LOADED_MOD), 71 | itemText, 72 | CHARCOUNT(itemText)); 73 | 74 | callingMod = itemText; 75 | 76 | std::string strFilter = callingMod + ":" + ownerMod + ":" + fnName; 77 | 78 | int itemCount = ListView_GetItemCount(inListViewHwnd); 79 | 80 | LVITEMA lvItem; 81 | ZeroMemory(&lvItem, sizeof(LVITEMA)); 82 | lvItem.mask = LVIF_TEXT; 83 | lvItem.iItem = itemCount; 84 | lvItem.iSubItem = 0; 85 | lvItem.pszText = (LPSTR)strFilter.c_str(); 86 | 87 | SendMessageA(inListViewHwnd, LVM_INSERTITEMA, 0, (LPARAM)&lvItem); 88 | ListView_EnsureVisible(inListViewHwnd, itemCount, FALSE); 89 | ListView_SetColumnWidth(inListViewHwnd, 0, LVSCW_AUTOSIZE); 90 | } 91 | 92 | // 93 | // Only write ascii data to filter file 94 | // 95 | void 96 | stWriteFilterToFile( 97 | HANDLE inFile, 98 | HWND inListViewHwnd, 99 | std::string inPrefix) 100 | { 101 | DWORD bytesWritten = 0; 102 | 103 | int itemCount = ListView_GetItemCount(inListViewHwnd); 104 | for (int i = 0; i < itemCount; i++) 105 | { 106 | char itemText[MAX_PATH]; 107 | 108 | LVITEMA lvItem; 109 | ZeroMemory(&lvItem, sizeof(LVITEMA)); 110 | 111 | lvItem.mask = LVIF_TEXT; 112 | lvItem.pszText = itemText; 113 | lvItem.cchTextMax = MAX_PATH; 114 | 115 | int nChar = SendMessageA( 116 | inListViewHwnd, 117 | LVM_GETITEMTEXTA, 118 | i, 119 | (LPARAM)&lvItem); 120 | 121 | WriteFile( 122 | inFile, 123 | inPrefix.c_str(), 124 | inPrefix.length() * sizeof(char), 125 | &bytesWritten, 126 | NULL); 127 | 128 | WriteFile( 129 | inFile, 130 | itemText, 131 | nChar * sizeof(char), 132 | &bytesWritten, 133 | NULL); 134 | 135 | WriteFile( 136 | inFile, 137 | "\r\n", 138 | 2, 139 | &bytesWritten, 140 | NULL); 141 | } 142 | } 143 | 144 | INT_PTR 145 | CALLBACK 146 | stOptionsDlgProc( 147 | HWND hDlg, 148 | UINT msg, 149 | WPARAM wParam, 150 | LPARAM lParam) 151 | { 152 | switch(msg) 153 | { 154 | case WM_INITDIALOG: 155 | { 156 | HICON hIcon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_APP_ICON)); 157 | SendMessage (hDlg, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hIcon); 158 | SendMessage (hDlg, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hIcon); 159 | 160 | LVCOLUMN lvColumn; 161 | lvColumn.mask = LVCF_WIDTH; 162 | lvColumn.cx = 1; 163 | 164 | 165 | ListView_InsertColumn( 166 | GetDlgItem(hDlg, IDC_LIST_INCL), 0, &lvColumn); 167 | 168 | ListView_InsertColumn( 169 | GetDlgItem(hDlg, IDC_LIST_EXCL), 0, &lvColumn); 170 | 171 | 172 | SetFocus(GetDlgItem(hDlg, IDC_EDIT_FN_NAME)); 173 | 174 | CenterDialog(hDlg); 175 | 176 | break; 177 | } 178 | case WM_COMMAND: 179 | { 180 | switch(wParam) 181 | { 182 | case IDC_CHECK_MAIN_EXE: 183 | { 184 | if (IsDlgButtonChecked(hDlg, IDC_CHECK_MAIN_EXE)) 185 | { 186 | SetWindowTextA( 187 | GetDlgItem(hDlg, IDC_EDIT_LOADED_MOD), 188 | "."); 189 | 190 | EnableWindow( 191 | GetDlgItem(hDlg, IDC_EDIT_LOADED_MOD), 192 | FALSE); 193 | } 194 | else 195 | { 196 | EnableWindow( 197 | GetDlgItem(hDlg, IDC_EDIT_LOADED_MOD), 198 | TRUE); 199 | } 200 | 201 | return FALSE; 202 | } 203 | case IDC_BTN_INCL: 204 | { 205 | stAddFilterToListView( 206 | GetDlgItem(hDlg, IDC_LIST_INCL), 207 | hDlg); 208 | 209 | return TRUE; 210 | } 211 | case IDC_BTN_EXCL: 212 | { 213 | stAddFilterToListView( 214 | GetDlgItem(hDlg, IDC_LIST_EXCL), 215 | hDlg); 216 | 217 | return TRUE; 218 | } 219 | case IDC_BTN_DEL_INCL: 220 | { 221 | int nSelectedItem = ListView_GetSelectionMark(GetDlgItem(hDlg, IDC_LIST_INCL)); 222 | 223 | if (nSelectedItem >= 0) 224 | { 225 | ListView_DeleteItem( 226 | GetDlgItem(hDlg, IDC_LIST_INCL), 227 | nSelectedItem); 228 | } 229 | 230 | return TRUE; 231 | } 232 | case IDC_BTN_DEL_EXCL: 233 | { 234 | int nSelectedItem = ListView_GetSelectionMark(GetDlgItem(hDlg, IDC_LIST_EXCL)); 235 | 236 | if (nSelectedItem >= 0) 237 | { 238 | ListView_DeleteItem( 239 | GetDlgItem(hDlg, IDC_LIST_EXCL), 240 | nSelectedItem); 241 | } 242 | 243 | return TRUE; 244 | } 245 | case IDC_BTN_SAVE: 246 | { 247 | wchar_t fileName[MAX_PATH]; 248 | fileName[0] = 0; 249 | 250 | OPENFILENAME sfn = {0}; 251 | 252 | sfn.lStructSize = OPENFILENAME_SIZE_VERSION_400; 253 | sfn.hwndOwner = hDlg; 254 | sfn.hInstance = ghInstance; 255 | sfn.lpstrFile = fileName; 256 | sfn.nMaxFile = MAX_PATH; 257 | sfn.lpstrTitle = L"Save Options to a Text file"; 258 | sfn.Flags = OFN_HIDEREADONLY | OFN_LONGNAMES | OFN_OVERWRITEPROMPT; 259 | 260 | sfn.lpstrFilter = L"Text Files (*.txt)\0*.txt;\0\0"; 261 | sfn.lpstrDefExt = L"txt"; 262 | 263 | if (GetSaveFileName(&sfn)) 264 | { 265 | std::wstring fileName = sfn.lpstrFile; 266 | 267 | HANDLE hFile = CreateFile( 268 | sfn.lpstrFile, 269 | GENERIC_READ | GENERIC_WRITE, 270 | 0, 271 | NULL, 272 | CREATE_ALWAYS, 273 | FILE_ATTRIBUTE_NORMAL, 274 | NULL); 275 | 276 | if (hFile != INVALID_HANDLE_VALUE) 277 | { 278 | stWriteFilterToFile( 279 | hFile, 280 | GetDlgItem(hDlg, IDC_LIST_INCL), 281 | "INCLUDES="); 282 | 283 | stWriteFilterToFile( 284 | hFile, 285 | GetDlgItem(hDlg, IDC_LIST_EXCL), 286 | "EXCLUDES="); 287 | 288 | CloseHandle(hFile); 289 | } 290 | else 291 | { 292 | MessageBox(hDlg, L"Error", L"Failed to create the specified file.", MB_OK); 293 | } 294 | } 295 | break; 296 | } 297 | case IDC_BTN_CLOSE: 298 | { 299 | EndDialog(hDlg, 0); 300 | return TRUE; 301 | } 302 | case IDCANCEL: 303 | { 304 | EndDialog(hDlg, -1); 305 | return TRUE; 306 | } 307 | } 308 | 309 | break; 310 | } 311 | case WM_NOTIFY: 312 | { 313 | } 314 | } 315 | 316 | return FALSE; 317 | } 318 | 319 | -------------------------------------------------------------------------------- /src/serum/serum.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | // 30 | // Declares structures and functions for serum DLL. 31 | // 32 | 33 | #ifndef _SERUM_H_ 34 | #define _SERUM_H_ 35 | 36 | #define STRSAFE_NO_DEPRECATE 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include "ihulib.h" 45 | #include "stcmn.h" 46 | 47 | #define TRC_PATCHIAT IHU_LOGGING_ON 48 | #define TRC_INJECTOR IHU_LOGGING_ON 49 | 50 | using namespace std; 51 | 52 | extern HINSTANCE g_hInstance; 53 | extern LONG gThreadReferenceCount; 54 | extern string g_MainExeName; 55 | extern DWORD gMajorOSVersion; 56 | extern DWORD gTlsIndex; 57 | 58 | // 59 | // Exported functions. 60 | // 61 | void 62 | WINAPI 63 | IhSerumLoad( 64 | LPCSTR inFnIncludes, 65 | LPCSTR inFnExcludes); 66 | 67 | void 68 | WINAPI 69 | IhSerumUnload(); 70 | 71 | volatile 72 | LONG 73 | WINAPI 74 | IhSerumGetRefCount(); 75 | 76 | 77 | // 78 | // IAT Patching related structure and functions 79 | // 80 | 81 | // We use this function type to simulate original 82 | // function call 83 | typedef PVOID(_stdcall *PFNORIGINAL)(void); 84 | 85 | #pragma pack(push) 86 | #pragma pack(1) 87 | 88 | typedef struct _PATCH_CODE 89 | { 90 | struct 91 | { 92 | BYTE Call[2]; 93 | DWORD pdwAddress; 94 | DWORD dwId; 95 | DWORD dwAddress; 96 | 97 | }Prolog; 98 | 99 | }PATCH_CODE; 100 | 101 | #pragma pack(pop) 102 | 103 | 104 | void 105 | ihiInitPatchCode( 106 | PATCH_CODE &ioPatchCode, 107 | ULONG inApiIndex); 108 | 109 | 110 | void 111 | ihiPatchProlog(); 112 | 113 | void 114 | __stdcall 115 | ihiPatchedFuncEntry( 116 | DWORD **ppStackPos, 117 | DWORD inECX, 118 | DWORD inEDX); 119 | 120 | DWORD_PTR 121 | __stdcall 122 | ihiGetOrigFuncAddrAt(PULONG inId); 123 | 124 | ULONG 125 | __stdcall 126 | ihiGetLastErrorValue(); 127 | 128 | VOID 129 | __stdcall 130 | ihiSetLastErrorValue(ULONG inErrorValue); 131 | 132 | BOOL 133 | __stdcall 134 | ihiPreventReEnter(); 135 | 136 | VOID 137 | __stdcall 138 | ihiDisableReEntrancy(); 139 | 140 | VOID 141 | __stdcall 142 | ihiEnableReEntrancy(); 143 | 144 | extern "C" 145 | void 146 | xsprintf(char *buff, const char *fmt, ...); 147 | 148 | void 149 | ihiPatchUnpatchImports( 150 | HANDLE inModuleHandle, 151 | LPCSTR inModuleBaseName, 152 | BYTE *inModuleBaseAddress, 153 | bool inApplyHook); 154 | 155 | 156 | void 157 | WINAPI 158 | ihiPatchUnpatchModules(HINSTANCE hDll, bool inApplyHook); 159 | 160 | void 161 | WINAPI 162 | ihiRemoveUnloadedModules(); 163 | 164 | // Function typedef to convert a character to uppercase 165 | typedef char(__cdecl *TO_UPPER)(char); 166 | 167 | // Function to convert a char to uppercase 168 | char 169 | __cdecl 170 | ihiToUpper(char c); 171 | 172 | // 173 | // Patching management structures and functions 174 | // 175 | 176 | // 177 | // Macro for maximum number of modules patched in a process 178 | // 179 | #define IHI_MAX_MODULES 1024 180 | 181 | // 182 | // We initially don't know how many APIs we need to hook 183 | // so we will allocate PATCH_CODE in chunks of X entries 184 | // to optimize memory allocation. 185 | // 186 | #define M_HOOK_ENTRY_CHUNK_SIZE 128 187 | 188 | // 189 | // Max API Name length 190 | // 191 | #define MAX_API_NAME_LENGTH 128 192 | 193 | // 194 | // Store information about the return value of an API, if user specified 195 | // this information in the filter file 196 | // 197 | typedef struct _IHI_FN_RETURN_VALUE 198 | { 199 | bool UserSpecified; 200 | ULONG_PTR Value; 201 | 202 | } IHI_FN_RETURN_VALUE, *PIHI_FN_RETURN_VALUE; 203 | 204 | 205 | // 206 | // Stores some information about each patched API 207 | // 208 | typedef struct _IHI_API_DATA 209 | { 210 | // API name inside IAT is always in Ascii 211 | char mApiName[MAX_API_NAME_LENGTH]; 212 | 213 | // Original address to which a particular API points 214 | PVOID mOriginalAddress; 215 | 216 | // If user specified a different return value, save it here 217 | IHI_FN_RETURN_VALUE mReturnValue; 218 | 219 | }IHI_API_DATA; 220 | 221 | // 222 | // Struct to store information about M_HOOK_ENTRY_CHUNK_SIZE 223 | // number of patched APIs 224 | // 225 | 226 | struct _IHI_PATCHED_API_DATA; 227 | 228 | typedef struct _IHI_PATCHED_API_DATA 229 | { 230 | // Array of IHI_API_DATA. Each memeber of this array has a corresponding 231 | // patch code in the mPatchCodeArray array 232 | IHI_API_DATA mApiData[M_HOOK_ENTRY_CHUNK_SIZE]; 233 | 234 | // Array of patch code for various APIs. These are allocated in 235 | // M_HOOK_ENTRY_CHUNK_SIZE chunk size 236 | PATCH_CODE *mPatchCodeArray; 237 | 238 | // Pointer to the next member in this linked list 239 | struct _IHI_PATCHED_API_DATA *Next; 240 | 241 | }IHI_PATCHED_API_DATA; 242 | 243 | // 244 | // Data structures to manage inclusion/exclusion of functions 245 | // 246 | struct _IHI_MAP; 247 | 248 | typedef struct _IHI_MAP 249 | { 250 | char Key[MAX_PATH]; 251 | bool IsPrefix; 252 | LPVOID Value; 253 | struct _IHI_MAP *Next; 254 | 255 | } IHI_MAP, *PIHI_MAP; 256 | 257 | struct InclExclRule 258 | { 259 | string LoadedModuleName; 260 | bool LoadedModuleNameIsPrefix; 261 | string ImportedModuleName; 262 | bool ImportedModuleNameIsPrefix; 263 | string FunctionName; 264 | bool FunctionNameIsPrefix; 265 | IHI_FN_RETURN_VALUE ReturnValue; 266 | }; 267 | 268 | typedef vector InclExclRuleList; 269 | 270 | struct InclExclRuleMatchInfo 271 | { 272 | string LoadedModuleName; 273 | string ImportedModuleName; 274 | string FunctionName; 275 | IHI_FN_RETURN_VALUE ReturnValue; 276 | ULONG MatchWeight; 277 | }; 278 | 279 | void 280 | ihiRuleListDump(InclExclRuleList &inRuleList, LPCWSTR inTitle); 281 | 282 | bool 283 | ihiRuleFind(InclExclRuleList &inRuleList, InclExclRuleMatchInfo &ioRuleMatchInfo); 284 | 285 | bool 286 | ihiIsModuleExcluded(string &inModuleName, vector &inExcludedModuleList, InclExclRuleList &inIncludedRuleList); 287 | 288 | // 289 | // Patch manager class 290 | // 291 | class CPatchManager 292 | { 293 | public: 294 | 295 | // Constructor 296 | CPatchManager(); 297 | 298 | // Destructor 299 | ~CPatchManager(); 300 | 301 | 302 | void 303 | Lock(); 304 | 305 | void 306 | UnLock(); 307 | 308 | // 309 | // Functions for API patching 310 | // 311 | IHI_PATCHED_API_DATA * 312 | GetPatchedApiArrayAt( 313 | ULONG inIndex); 314 | 315 | // Fix-Me!!! 316 | // The name of functions below needs to be 317 | // changed to reflect their meaning more clearly 318 | // 319 | LPVOID 320 | GetOrigFuncAddrAt( 321 | ULONG inIndex); 322 | 323 | LPVOID 324 | GetMatchingOrigFuncAddr( 325 | LPVOID pfnPatchedFunction); 326 | 327 | LPCSTR 328 | GetFuncNameAt( 329 | ULONG inIndex); 330 | 331 | void 332 | GetFnReturnValueInfoAt( 333 | ULONG inIndex, 334 | IHI_FN_RETURN_VALUE &oRetValInfo); 335 | 336 | LPVOID 337 | InsertNewPatch( 338 | LPSTR inApiName, 339 | LPVOID inOrigFuncAddr, 340 | IHI_FN_RETURN_VALUE &inRetValInfo); 341 | 342 | void 343 | RemoveAllPatches(); 344 | 345 | // 346 | // House-Keeping functions to maintain which modules 347 | // are patched and which aren't. 348 | // 349 | bool 350 | IsModulePatched( 351 | HANDLE inModuleHandle); 352 | 353 | void 354 | AddModuleToPatchedList( 355 | HANDLE inModuleHandle); 356 | 357 | void 358 | RemoveModuleFromPatchedList( 359 | HANDLE inModuleHandle); 360 | 361 | HANDLE 362 | GetPatchedModulesHandle( 363 | ULONG moduleIndex); 364 | 365 | ULONG 366 | GetPatchedModulesCount(); 367 | 368 | private: 369 | // Used to synchronize access to patch manager database 370 | // Client application should determine when to lock it 371 | // At minimum, It should be locked when any write operation 372 | // happens in the patch manager, such as patching/removing 373 | // a module or patching a new api 374 | HANDLE mPatchManagerMutex; 375 | 376 | // For patched APIs 377 | IHI_PATCHED_API_DATA *mPatchedApiListHead; 378 | IHI_PATCHED_API_DATA *mPatchedApiListTail; 379 | ULONG mPatchedApiCount; 380 | 381 | // For patched Modules 382 | HANDLE mPatchedModuleList[IHI_MAX_MODULES]; 383 | ULONG mPatchedModuleCount; 384 | 385 | // Used to decide patches lifetime 386 | bool mPatchesRemoved; 387 | }; 388 | 389 | // 390 | // global object to manage patched functions 391 | // 392 | extern CPatchManager gPatchManager; 393 | 394 | // 395 | // Class to manage inclusion/exclusion list for patching 396 | // 397 | class CPatchInclExclMgr 398 | { 399 | public: 400 | 401 | // Constructor/Destructor 402 | CPatchInclExclMgr(); 403 | ~CPatchInclExclMgr(); 404 | 405 | // Functions 406 | void 407 | SetInclExclList( 408 | LPCSTR inFnIncludes, 409 | LPCSTR inFnExcludes); 410 | 411 | void 412 | BuildInclOrExclList( 413 | std::string inFnList, 414 | InclExclRuleList &ioRuleList); 415 | 416 | bool 417 | PatchRequired( 418 | LPCSTR loadedModuleName, 419 | LPCSTR impModuleName, 420 | LPCSTR fnName, 421 | bool inOrdinalExport, 422 | IHI_FN_RETURN_VALUE *oRetVal); 423 | 424 | private: 425 | InclExclRuleList m_IncludeRuleList; 426 | InclExclRuleList m_ExcludeRuleList; 427 | vector m_ExcludeModuleList; 428 | }; 429 | 430 | 431 | // 432 | // global object to manage inclusion/exclusion 433 | // 434 | extern CPatchInclExclMgr gPatchInclExclMgr; 435 | 436 | // 437 | // Utilities to handle PE image's import/export tables. 438 | // 439 | 440 | class CMappedFileObject 441 | { 442 | public: 443 | CMappedFileObject() 444 | { 445 | m_FileHandle = INVALID_HANDLE_VALUE; 446 | m_FileMappingHandle = NULL; 447 | m_MappedBaseAddress = NULL; 448 | } 449 | ~CMappedFileObject() 450 | { 451 | if (m_MappedBaseAddress != NULL) 452 | { 453 | UnmapViewOfFile(m_MappedBaseAddress); 454 | CloseHandle(m_FileMappingHandle); 455 | CloseHandle(m_FileHandle); 456 | } 457 | } 458 | 459 | BOOL Initialize(LPCWSTR inFileName); 460 | LPBYTE GetMappedBaseAddress() 461 | { 462 | return m_MappedBaseAddress; 463 | } 464 | LPCWSTR GetFileName() 465 | { 466 | return m_FileName.c_str(); 467 | } 468 | 469 | private: 470 | HANDLE m_FileHandle; 471 | HANDLE m_FileMappingHandle; 472 | LPBYTE m_MappedBaseAddress; 473 | wstring m_FileName; 474 | }; 475 | 476 | LPVOID ihiGetPtrFromRVA(DWORD relVA, PIMAGE_NT_HEADERS inINTH, 477 | DWORD inBaseAddress); 478 | 479 | BOOL ihiGetFileImportDescriptor(CMappedFileObject &inFileObject, PIMAGE_NT_HEADERS *INTHPtr, 480 | PIMAGE_IMPORT_DESCRIPTOR *IIDPtr); 481 | 482 | BOOL ihiGetModuleImportDescriptor(PBYTE inModuleBaseAddress, LPCSTR inModuleBaseName, 483 | PIMAGE_NT_HEADERS *INTHPtr, PIMAGE_IMPORT_DESCRIPTOR *IIDPtr); 484 | 485 | BOOL ihiGetExportedFunctionName(LPCWSTR inModuleName, WORD inOrdinal, 486 | LPSTR outFnName, DWORD inFnNameSize); 487 | 488 | extern bool gEnableAntiDebugMeasures; 489 | extern BOOL gDebug; 490 | extern bool gUseSharedMemory; 491 | 492 | VOID 493 | ihiEnableAntiDebugMeasures(); 494 | 495 | BOOL 496 | ihiPatchAntiDebugFunction(LPCSTR inModuleName, LPCSTR inFnName); 497 | 498 | VOID 499 | ihiDebugLoop(BOOL inEnterLoop); 500 | 501 | VOID 502 | ihiFastMemCpy(PULONG inDest, PULONG inSrc, int inCount); 503 | 504 | VOID 505 | ihiSlowMemCpy(PUCHAR inDest, PUCHAR inSrc, int inCount); 506 | 507 | #endif -------------------------------------------------------------------------------- /src/serum/patchutl.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | /*++ 30 | 31 | Module Description: 32 | 33 | Implements utility functions like MAP management, reading Import/ 34 | Export table etc. 35 | 36 | --*/ 37 | 38 | #include "serum.h" 39 | 40 | 41 | void 42 | ihiRuleListDump(InclExclRuleList &inRuleList, LPCWSTR inTitle) 43 | { 44 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_INFO, L"**** DUMPING %s Rule List ****\n", inTitle); 45 | for (size_t i = 0; i < inRuleList.size(); i++) 46 | { 47 | ULONG tmpWeight = 0; 48 | InclExclRule &rule = inRuleList.at(i); 49 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_INFO, 50 | L"Rule Index: %d\n" 51 | L"\tLoadedModuleName: %S, PrefixBased: %S\n" 52 | L"\tImportModuleName: %S, PrefixBased: %S\n" 53 | L"\tFunctionName: %S, PrefixBased: %S\n", 54 | i, 55 | rule.LoadedModuleName.c_str(), (rule.LoadedModuleNameIsPrefix ? "Yes" : "No"), 56 | rule.ImportedModuleName.c_str(), (rule.ImportedModuleNameIsPrefix ? "Yes" : "No"), 57 | rule.FunctionName.c_str(), (rule.FunctionNameIsPrefix ? "Yes" : "No")); 58 | } 59 | } 60 | 61 | 62 | ULONG 63 | ihiCalcMatchWeight(string &inString1, bool inIsPrefix, string &inString2) 64 | { 65 | ULONG matchWeight = 0; 66 | if (inIsPrefix) 67 | { 68 | if (_strnicmp(inString1.c_str(), inString2.c_str(), strlen(inString1.c_str())) == 0) 69 | { 70 | matchWeight = strlen(inString1.c_str()) + 1; 71 | } 72 | } 73 | else 74 | { 75 | if (_stricmp(inString1.c_str(), inString2.c_str()) == 0) 76 | { 77 | matchWeight = strlen(inString1.c_str()) + 2; 78 | } 79 | } 80 | 81 | return matchWeight; 82 | } 83 | 84 | 85 | bool 86 | ihiRuleFind(InclExclRuleList &inRuleList, InclExclRuleMatchInfo &ioRuleMatchInfo) 87 | { 88 | bool matchFound; 89 | InclExclRuleList::iterator rlIter; 90 | ULONG loadedModuleMatchWeight; 91 | ULONG importModuleMatchWeight; 92 | ULONG fnMatchWeight; 93 | ULONG totalWeight; 94 | 95 | matchFound = false; 96 | totalWeight = 0; 97 | 98 | for (size_t i = 0; i < inRuleList.size(); i++) 99 | { 100 | ULONG tmpWeight = 0; 101 | InclExclRule &rule = inRuleList.at(i); 102 | loadedModuleMatchWeight = ihiCalcMatchWeight(rule.LoadedModuleName, rule.LoadedModuleNameIsPrefix, ioRuleMatchInfo.LoadedModuleName); 103 | importModuleMatchWeight = ihiCalcMatchWeight(rule.ImportedModuleName, rule.ImportedModuleNameIsPrefix, ioRuleMatchInfo.ImportedModuleName); 104 | fnMatchWeight = ihiCalcMatchWeight(rule.FunctionName, rule.FunctionNameIsPrefix, ioRuleMatchInfo.FunctionName); 105 | 106 | if (loadedModuleMatchWeight != 0 && importModuleMatchWeight != 0 && fnMatchWeight != 0) 107 | { 108 | matchFound = TRUE; 109 | tmpWeight = loadedModuleMatchWeight + importModuleMatchWeight + fnMatchWeight; 110 | 111 | if (tmpWeight > totalWeight) 112 | { 113 | totalWeight = tmpWeight; 114 | ioRuleMatchInfo.ReturnValue = rule.ReturnValue; 115 | ioRuleMatchInfo.MatchWeight = totalWeight; 116 | } 117 | } 118 | } 119 | 120 | return matchFound; 121 | } 122 | 123 | 124 | bool 125 | ihiIsModuleExcluded(string &inModuleName, vector &inExcludedModuleList, InclExclRuleList &inIncludedRuleList) 126 | { 127 | ULONG moduleExclusionWeight = 0; 128 | ULONG moduleInclusionWeight = 0; 129 | 130 | for (size_t i = 0; i < inIncludedRuleList.size(); i++) 131 | { 132 | ULONG tmpWeight = 0; 133 | InclExclRule &rule = inIncludedRuleList.at(i); 134 | tmpWeight = ihiCalcMatchWeight(rule.ImportedModuleName, rule.ImportedModuleNameIsPrefix, inModuleName); 135 | 136 | if (tmpWeight > moduleInclusionWeight) 137 | { 138 | moduleInclusionWeight = tmpWeight; 139 | } 140 | } 141 | 142 | for (size_t i = 0; i < inExcludedModuleList.size(); i++) 143 | { 144 | ULONG tmpWeight = 0; 145 | string &moduleName = inExcludedModuleList.at(i); 146 | tmpWeight = ihiCalcMatchWeight(moduleName, true, inModuleName); 147 | 148 | if (tmpWeight > moduleExclusionWeight) 149 | { 150 | moduleExclusionWeight = tmpWeight; 151 | } 152 | } 153 | 154 | return (moduleExclusionWeight > moduleInclusionWeight); 155 | } 156 | 157 | 158 | BOOL 159 | CMappedFileObject::Initialize(LPCWSTR inFileName) 160 | { 161 | BOOL status; 162 | HANDLE hFile; 163 | HANDLE hFileMapping; 164 | LPBYTE lpFileBase; 165 | 166 | status = FALSE; 167 | hFile = INVALID_HANDLE_VALUE; 168 | hFileMapping = NULL; 169 | lpFileBase = NULL; 170 | 171 | hFile = CreateFile(inFileName, GENERIC_READ, FILE_SHARE_READ, NULL, 172 | OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 173 | if (hFile == INVALID_HANDLE_VALUE) 174 | { 175 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_ERROR, L"Couldn't open file with CreateFile()\n"); 176 | goto Exit; 177 | } 178 | 179 | hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); 180 | if (hFileMapping == NULL) 181 | { 182 | CloseHandle(hFile); 183 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_ERROR, L"Couldn't open file mapping with CreateFileMapping()\n"); 184 | goto Exit; 185 | } 186 | 187 | lpFileBase = (LPBYTE)MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0); 188 | if (lpFileBase == NULL) 189 | { 190 | CloseHandle(hFileMapping); 191 | CloseHandle(hFile); 192 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_ERROR, L"Couldn't map view of file with MapViewOfFile()\n"); 193 | goto Exit; 194 | } 195 | 196 | m_FileName = inFileName; 197 | status = TRUE; 198 | 199 | Exit: 200 | if (status) 201 | { 202 | m_FileHandle = hFile; 203 | m_FileMappingHandle = hFileMapping; 204 | m_MappedBaseAddress = lpFileBase; 205 | } 206 | return status; 207 | } 208 | 209 | 210 | PIMAGE_SECTION_HEADER 211 | ihiGetEnclosingSection(DWORD relVA, PIMAGE_NT_HEADERS inINTH) 212 | { 213 | PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(inINTH); 214 | unsigned i; 215 | 216 | for (i = 0; i < inINTH->FileHeader.NumberOfSections; i++, section++) 217 | { 218 | // Is the RVA within this section? 219 | if ((relVA >= section->VirtualAddress) && 220 | (relVA < (section->VirtualAddress + section->Misc.VirtualSize))) 221 | { 222 | return section; 223 | } 224 | } 225 | 226 | return 0; 227 | } 228 | 229 | 230 | LPVOID 231 | ihiGetPtrFromRVA(DWORD relVA, PIMAGE_NT_HEADERS inINTH, DWORD inBaseAddress) 232 | { 233 | PIMAGE_SECTION_HEADER pISH; 234 | INT delta; 235 | 236 | pISH = ihiGetEnclosingSection(relVA, inINTH); 237 | if (!pISH) 238 | { 239 | return 0; 240 | } 241 | 242 | delta = (INT)(pISH->VirtualAddress - pISH->PointerToRawData); 243 | return (PVOID)(inBaseAddress + relVA - delta); 244 | } 245 | 246 | 247 | BOOL 248 | ihiGetFileImportDescriptor(CMappedFileObject &inFileObject, PIMAGE_NT_HEADERS *INTHPtr, 249 | PIMAGE_IMPORT_DESCRIPTOR *IIDPtr) 250 | { 251 | LPBYTE lpFileBase; 252 | PIMAGE_DOS_HEADER pIDH; 253 | PIMAGE_NT_HEADERS pINTH = NULL; 254 | PIMAGE_IMPORT_DESCRIPTOR pIID = NULL; 255 | DWORD importTableRVA; 256 | BOOL result; 257 | 258 | result = FALSE; 259 | 260 | lpFileBase = inFileObject.GetMappedBaseAddress(); 261 | pIDH = (PIMAGE_DOS_HEADER)lpFileBase; 262 | if (pIDH->e_magic == IMAGE_DOS_SIGNATURE) 263 | { 264 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_INFO, 265 | L"Module for file %s is PE format.\n", 266 | inFileObject.GetFileName()); 267 | pINTH = (PIMAGE_NT_HEADERS)(lpFileBase + pIDH->e_lfanew); 268 | importTableRVA = pINTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; 269 | if (importTableRVA == 0) 270 | { 271 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_INFO, 272 | L"PatchFailure: No Import Table Offset for module: %s.\n", 273 | inFileObject.GetFileName()); 274 | goto Exit; 275 | } 276 | pIID = (PIMAGE_IMPORT_DESCRIPTOR)ihiGetPtrFromRVA(importTableRVA, pINTH, (DWORD)lpFileBase); 277 | } 278 | else 279 | { 280 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_ERROR, 281 | L"Unrecognized file format for file: %s\n", 282 | inFileObject.GetFileName()); 283 | goto Exit; 284 | } 285 | 286 | result = TRUE; 287 | 288 | Exit: 289 | 290 | *INTHPtr = pINTH; 291 | *IIDPtr = pIID; 292 | return result; 293 | } 294 | 295 | 296 | BOOL ihiGetModuleImportDescriptor(PBYTE inModuleBaseAddress, LPCSTR inModuleBaseName, 297 | PIMAGE_NT_HEADERS *INTHPtr, PIMAGE_IMPORT_DESCRIPTOR *IIDPtr) 298 | { 299 | PIMAGE_DOS_HEADER pIDH; 300 | PIMAGE_NT_HEADERS pINTH; 301 | PIMAGE_IMPORT_DESCRIPTOR pIID; 302 | DWORD importTableRVA; 303 | BOOL result; 304 | 305 | pINTH = NULL; 306 | pIID = NULL; 307 | result = FALSE; 308 | 309 | pIDH = (PIMAGE_DOS_HEADER)inModuleBaseAddress; 310 | if (IsBadReadPtr(inModuleBaseAddress, sizeof(IMAGE_DOS_HEADER))) 311 | { 312 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_ERROR, 313 | L"PatchFailure: Unable to read IMAGE_DOS_HEADER for module: %S.\n", 314 | inModuleBaseName); 315 | goto Exit; 316 | } 317 | pINTH = (PIMAGE_NT_HEADERS)(inModuleBaseAddress + pIDH->e_lfanew); 318 | importTableRVA = pINTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; 319 | if (importTableRVA == 0) 320 | { 321 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_INFO, 322 | L"PatchFailure: No Import Table Offset for module: %S.\n", 323 | inModuleBaseName); 324 | goto Exit; 325 | } 326 | pIID = (PIMAGE_IMPORT_DESCRIPTOR)(inModuleBaseAddress + importTableRVA); 327 | result = TRUE; 328 | 329 | Exit: 330 | 331 | *INTHPtr = pINTH; 332 | *IIDPtr = pIID; 333 | return result; 334 | } 335 | 336 | 337 | BOOL ihiGetExportedFunctionName(LPCWSTR inModuleName, WORD inOrdinal, 338 | LPSTR outFnName, DWORD inFnNameSize) 339 | { 340 | CMappedFileObject peFileObject; 341 | wchar_t inFileName[MAX_PATH + 1]; 342 | HMODULE modHandle; 343 | LPBYTE lpFileBase; 344 | PIMAGE_DOS_HEADER pIDH; 345 | PIMAGE_NT_HEADERS pINTH = NULL; 346 | PIMAGE_EXPORT_DIRECTORY pIED; 347 | DWORD exportTableRVA; 348 | LPSTR* pNames; 349 | PWORD pOrdinals; 350 | BOOL result; 351 | DWORD i; 352 | 353 | result = FALSE; 354 | 355 | modHandle = GetModuleHandle(inModuleName); 356 | if (modHandle == NULL) 357 | { 358 | goto Exit; 359 | } 360 | 361 | inFileName[MAX_PATH] = L'\0'; 362 | if (!GetModuleFileName(modHandle, inFileName, MAX_PATH)) 363 | { 364 | goto Exit; 365 | } 366 | 367 | if (!peFileObject.Initialize(inFileName)) 368 | { 369 | goto Exit; 370 | } 371 | 372 | lpFileBase = peFileObject.GetMappedBaseAddress(); 373 | pIDH = (PIMAGE_DOS_HEADER)lpFileBase; 374 | if (pIDH->e_magic == IMAGE_DOS_SIGNATURE) 375 | { 376 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_INFO, L"Module for file %s is PE format.\n", inFileName); 377 | pINTH = (PIMAGE_NT_HEADERS)(lpFileBase + pIDH->e_lfanew); 378 | exportTableRVA = pINTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; 379 | if (exportTableRVA == 0) 380 | { 381 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_ERROR, 382 | L"PatchFailure: No Export Table Offset for module: %s.\n", 383 | inFileName); 384 | goto Exit; 385 | } 386 | pIED = (PIMAGE_EXPORT_DIRECTORY)ihiGetPtrFromRVA(exportTableRVA, pINTH, (DWORD)lpFileBase); 387 | if (pIED == NULL) 388 | { 389 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_ERROR, 390 | L"PatchFailure: Unable to find Export Table for module: %s.\n", 391 | inFileName); 392 | goto Exit; 393 | } 394 | pOrdinals = (PWORD)ihiGetPtrFromRVA(pIED->AddressOfNameOrdinals, pINTH, (DWORD)lpFileBase); 395 | pNames = (LPSTR*)ihiGetPtrFromRVA(pIED->AddressOfNames, pINTH, (DWORD)lpFileBase); 396 | if (pOrdinals == NULL || pNames == NULL) 397 | { 398 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_ERROR, L"Name or Ordinal Array is NULL\n"); 399 | goto Exit; 400 | } 401 | for (i = 0; i < pIED->NumberOfNames; i++) 402 | { 403 | 404 | WORD ordinal = pOrdinals[i] + (WORD)pIED->Base; 405 | if (_IhuDbgLogLevel <= IHU_LEVEL_FLOOD) 406 | { 407 | LPSTR name = (LPSTR)ihiGetPtrFromRVA((DWORD)pNames[i], pINTH, (DWORD)lpFileBase); 408 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_FLOOD, L"PrintAll: Ordinal: %x, Name: %S\n", ordinal, name); 409 | } 410 | if (ordinal == inOrdinal) 411 | { 412 | LPSTR name = (LPSTR)ihiGetPtrFromRVA((DWORD)pNames[i], pINTH, (DWORD)lpFileBase); 413 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_INFO, L"Found: Ordinal: %x, Name: %S\n", ordinal, name); 414 | if (strlen(name) < inFnNameSize) 415 | { 416 | strcpy(outFnName, name); 417 | result = TRUE; 418 | } 419 | else 420 | { 421 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_ERROR, L"Failed to copy exported function name - supplied buffer is smaller.\n"); 422 | } 423 | goto Exit; 424 | } 425 | } 426 | } 427 | 428 | Exit: 429 | 430 | return result; 431 | } 432 | 433 | 434 | VOID 435 | ihiEnableAntiDebugMeasures() 436 | { 437 | gEnableAntiDebugMeasures = true; 438 | 439 | // 440 | // Calculate the correct offset for ProcessHeap fields. 441 | // 442 | // N.B. The correct offsets are shown below in form of the code, from: 443 | // https://github.com/nihilus/ScyllaHide/blob/master/Test/TestMain.cpp 444 | // 445 | DWORD flagsOffset; 446 | DWORD forceFlagsOffset; 447 | 448 | #ifdef _WIN64 449 | if (gMajorOSVersion >= 6) 450 | { 451 | flagsOffset = 0x70; 452 | forceFlagsOffset = 0x74; 453 | } 454 | else 455 | { 456 | flagsOffset = 0x14; 457 | forceFlagsOffset = 0x18; 458 | } 459 | #else 460 | if (gMajorOSVersion >= 6) 461 | { 462 | flagsOffset = 0x40; 463 | forceFlagsOffset = 0x44; 464 | } 465 | else 466 | { 467 | flagsOffset = 0x0C; 468 | forceFlagsOffset = 0x10; 469 | } 470 | #endif 471 | 472 | __asm 473 | { 474 | push eax; 475 | push ebx; 476 | 477 | // 478 | // Clear PEB.BeingDebugged. 479 | // 480 | mov eax, dword ptr fs : [0x30]; 481 | mov byte ptr[eax + 0x2], 0; 482 | 483 | // 484 | // Clear PEB.NtGlobalFlag 485 | // 486 | mov dword ptr[eax + 0x68], 0; 487 | 488 | // 489 | // Set ProcessHeap.Flags to 0x2 490 | // and ProcessHeap.ForceFlags to 0x0 491 | // 492 | mov ebx, dword ptr[eax + 0x18]; 493 | 494 | lea eax, [ebx + flagsOffset]; 495 | mov dword ptr[eax], 2; 496 | 497 | lea eax, [ebx + forceFlagsOffset]; 498 | mov dword ptr[eax], 0; 499 | 500 | pop ebx; 501 | pop eax; 502 | } 503 | } 504 | 505 | 506 | BOOL 507 | ihiPatchAntiDebugFunction(LPCSTR inModuleName, LPCSTR inFnName) 508 | { 509 | if (gEnableAntiDebugMeasures && 510 | (_stricmp(inFnName, "IsDebuggerPresent") == 0 || 511 | _stricmp(inFnName, "CheckRemoteDebuggerPresent") == 0 || 512 | _stricmp(inFnName, "NtQueryInformationProcess") == 0 || 513 | _stricmp(inFnName, "ZwQueryInformationProcess") == 0)) 514 | { 515 | return TRUE; 516 | } 517 | 518 | return FALSE; 519 | } 520 | 521 | 522 | VOID 523 | ihiDebugLoop(BOOL inEnterLoop) 524 | { 525 | _asm push eax; 526 | _asm mov eax, inEnterLoop; 527 | debug: 528 | _asm cmp eax, 1; 529 | _asm je debug; 530 | _asm pop eax; 531 | } 532 | 533 | 534 | VOID 535 | ihiFastMemCpy(PULONG inDest, PULONG inSrc, int inCount) 536 | { 537 | ULONG fullUlongs; 538 | ULONG trailingBytes; 539 | PUCHAR inDestChar; 540 | PUCHAR inSrcChar; 541 | 542 | fullUlongs = inCount / sizeof(ULONG); 543 | trailingBytes = inCount % sizeof(ULONG); 544 | 545 | while (fullUlongs-- > 0) 546 | { 547 | *inDest++ = *inSrc++; 548 | } 549 | 550 | inDestChar = (PUCHAR)inDest; 551 | inSrcChar = (PUCHAR)inSrc; 552 | while (trailingBytes-- > 0) 553 | { 554 | *inDestChar++ = *inSrcChar; 555 | } 556 | } 557 | 558 | 559 | VOID 560 | ihiSlowMemCpy(PUCHAR inDest, PUCHAR inSrc, int inCount) 561 | { 562 | while (inCount-- > 0) 563 | { 564 | *inDest++ = *inSrc; 565 | } 566 | } 567 | 568 | -------------------------------------------------------------------------------- /src/app/gui/stmiscdlgs.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include "ihulib.h" 36 | #include "stgui.h" 37 | #include "stcommon.h" 38 | #include "stguires.h" 39 | #include "stmiscdlgs.h" 40 | 41 | INT_PTR 42 | CALLBACK 43 | stAboutDlgProc( 44 | HWND hDlg, 45 | UINT msg, 46 | WPARAM wParam, 47 | LPARAM lParam) 48 | /*++ 49 | 50 | Routine Description: 51 | 52 | dialog box to show information about StraceNT 53 | 54 | Returns: 55 | 56 | TRUE - Message handled by the dialog proc 57 | FALSE - Message not handled 58 | 59 | --*/ 60 | { 61 | int result = 0; 62 | 63 | switch(msg) 64 | { 65 | case WM_INITDIALOG: 66 | { 67 | HICON hIcon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_APP_ICON)); 68 | SendMessage (hDlg, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hIcon); 69 | SendMessage (hDlg, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hIcon); 70 | 71 | SendMessage( 72 | GetDlgItem(hDlg,IDOK), 73 | BM_SETIMAGE, 74 | IMAGE_BITMAP, 75 | (LPARAM)LoadBitmap(ghInstance, MAKEINTRESOURCE(IDB_ABOUT_BTN))); 76 | 77 | CenterDialog(hDlg); 78 | 79 | break; 80 | } 81 | case WM_CTLCOLORDLG: 82 | { 83 | HDC hdc = (HDC)wParam; 84 | SetBkColor(hdc, RGB(0, 0, 0)); 85 | return (INT_PTR)GetStockObject(BLACK_BRUSH); 86 | } 87 | case WM_CTLCOLORSTATIC: 88 | { 89 | HDC hdc = (HDC)wParam; 90 | 91 | SetBkColor(hdc, RGB(0, 0, 0)); 92 | 93 | if (GetDlgItem(hDlg, IDC_STATIC_LINK) == (HWND)lParam) 94 | { 95 | SetTextColor(hdc, RGB(128, 128, 192)); 96 | } 97 | else 98 | { 99 | SetTextColor(hdc, RGB(128, 255, 0)); 100 | } 101 | 102 | return (INT_PTR)GetStockObject(BLACK_BRUSH); 103 | } 104 | case WM_COMMAND: 105 | { 106 | switch(wParam) 107 | { 108 | case IDC_STATIC_LINK: 109 | { 110 | ShellExecute( 111 | NULL, 112 | NULL, 113 | L"http://www.intellectualheaven.com", 114 | NULL, 115 | NULL, 116 | SW_SHOW | SW_MAXIMIZE); 117 | 118 | return TRUE; 119 | } 120 | case IDOK: 121 | { 122 | EndDialog(hDlg, IDOK); 123 | return TRUE; 124 | } 125 | case IDCANCEL: 126 | { 127 | EndDialog(hDlg, IDCANCEL); 128 | return TRUE; 129 | } 130 | } 131 | 132 | break; 133 | } 134 | } 135 | 136 | return FALSE; 137 | } 138 | 139 | HIMAGELIST g_hProcessILSmall = NULL; 140 | 141 | bool 142 | stFillProcessInformation( 143 | HWND inListViewHwnd) 144 | { 145 | ListView_DeleteAllItems(inListViewHwnd); 146 | 147 | bool funcResult = false; 148 | 149 | IHU_PROCESS_LIST processList; 150 | IHU_PROCESS_LIST_ITER processListIter; 151 | IHU_PROCESS_INFO processInfo; 152 | 153 | if (IhuGetProcessList(processList) < 0) 154 | { 155 | funcResult = false; 156 | goto funcExit; 157 | } 158 | 159 | if (g_hProcessILSmall) 160 | { 161 | ImageList_Destroy(g_hProcessILSmall); 162 | } 163 | 164 | g_hProcessILSmall = ImageList_Create(16, 16, ILC_COLOR24 | ILC_MASK, 4, 1); 165 | 166 | if (g_hProcessILSmall) 167 | { 168 | ListView_SetImageList(inListViewHwnd, g_hProcessILSmall, LVSIL_SMALL); 169 | } 170 | 171 | for ( processListIter = processList.begin(); 172 | processListIter != processList.end(); 173 | processListIter++) 174 | { 175 | processInfo = *processListIter; 176 | 177 | LVITEM lvItem; 178 | ZeroMemory(&lvItem, sizeof(LVITEM)); 179 | lvItem.mask = LVIF_TEXT; 180 | lvItem.iItem = 0; 181 | lvItem.iSubItem = 0; 182 | lvItem.pszText = (LPWSTR)processInfo.mProcessName.c_str(); 183 | 184 | if (g_hProcessILSmall) 185 | { 186 | int iIndex = 0; 187 | HICON hIcon; 188 | IhuGetFileIcon(processInfo.mBinaryName.c_str(), hIcon); 189 | iIndex = ImageList_AddIcon(g_hProcessILSmall, hIcon); 190 | DestroyIcon(hIcon); 191 | 192 | lvItem.mask = LVIF_TEXT | LVIF_IMAGE; 193 | lvItem.iImage = iIndex; 194 | } 195 | 196 | int itemIndex = SendMessage(inListViewHwnd, LVM_INSERTITEM, 0, (LPARAM)&lvItem); 197 | ListView_SetColumnWidth(inListViewHwnd, 0, LVSCW_AUTOSIZE); 198 | 199 | wchar_t szPid[32] = {0}; 200 | 201 | StringCchPrintf(szPid, CHARCOUNT(szPid), L"%d", processInfo.mProcessId); 202 | 203 | lvItem.iItem = itemIndex; 204 | lvItem.iSubItem = 1; 205 | lvItem.pszText = szPid; 206 | SendMessage(inListViewHwnd, LVM_SETITEM, 0, (LPARAM)&lvItem); 207 | ListView_SetColumnWidth(inListViewHwnd, 1, LVSCW_AUTOSIZE); 208 | 209 | lvItem.iItem = itemIndex; 210 | lvItem.iSubItem = 2; 211 | lvItem.pszText = (LPWSTR)processInfo.mBinaryName.c_str(); 212 | SendMessage(inListViewHwnd, LVM_SETITEM, 0, (LPARAM)&lvItem); 213 | ListView_SetColumnWidth(inListViewHwnd, 2, LVSCW_AUTOSIZE); 214 | } 215 | 216 | funcExit: 217 | return funcResult; 218 | } 219 | 220 | 221 | INT_PTR 222 | CALLBACK 223 | stProcessAttachDlgProc( 224 | HWND hDlg, 225 | UINT msg, 226 | WPARAM wParam, 227 | LPARAM lParam) 228 | /*++ 229 | 230 | Routine Description: 231 | 232 | Dialog box for user to attach to a process 233 | 234 | Returns: 235 | 236 | TRUE - Message handled by the dialog proc 237 | FALSE - Message not handled 238 | 239 | --*/ 240 | { 241 | PST_ATTACH_PROCESS pAttachProcess = NULL; 242 | 243 | if (msg == WM_INITDIALOG) 244 | { 245 | SetWindowLongPtr(hDlg, GWLP_USERDATA, lParam); 246 | pAttachProcess = (PST_ATTACH_PROCESS)lParam; 247 | } 248 | else 249 | { 250 | pAttachProcess = (PST_ATTACH_PROCESS) 251 | GetWindowLongPtr(hDlg, GWLP_USERDATA); 252 | } 253 | 254 | //IHU_DBG_ASSERT(pAttachProcess); 255 | 256 | switch(msg) 257 | { 258 | case WM_INITDIALOG: 259 | { 260 | HICON hIcon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_APP_ICON)); 261 | SendMessage (hDlg, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hIcon); 262 | SendMessage (hDlg, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hIcon); 263 | 264 | CenterDialog(hDlg); 265 | 266 | LVCOLUMN lvColumn; 267 | lvColumn.mask = LVCF_TEXT | LVCF_WIDTH; 268 | lvColumn.cx = 1; 269 | 270 | lvColumn.pszText = L"Process Name"; 271 | ListView_InsertColumn( 272 | GetDlgItem(hDlg, IDC_LIST_PROCESS), 0, &lvColumn); 273 | 274 | lvColumn.pszText = L"PID"; 275 | ListView_InsertColumn( 276 | GetDlgItem(hDlg, IDC_LIST_PROCESS), 1, &lvColumn); 277 | 278 | lvColumn.pszText = L"Process Image"; 279 | ListView_InsertColumn( 280 | GetDlgItem(hDlg, IDC_LIST_PROCESS), 2, &lvColumn); 281 | 282 | ListView_SetExtendedListViewStyle( 283 | GetDlgItem(hDlg, IDC_LIST_PROCESS), 284 | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); 285 | 286 | stFillProcessInformation(GetDlgItem(hDlg, IDC_LIST_PROCESS)); 287 | 288 | EnableWindow( 289 | GetDlgItem(hDlg, IDC_EDIT_FILTER_FILE), 290 | FALSE); 291 | 292 | EnableWindow( 293 | GetDlgItem(hDlg, ID_BTN_BROWSE), 294 | FALSE); 295 | 296 | return TRUE; 297 | } 298 | case WM_COMMAND: 299 | { 300 | switch(wParam) 301 | { 302 | case IDC_CHECK_FILTER: 303 | { 304 | if (IsDlgButtonChecked(hDlg, IDC_CHECK_FILTER)) 305 | { 306 | EnableWindow( 307 | GetDlgItem(hDlg, IDC_EDIT_FILTER_FILE), 308 | TRUE); 309 | 310 | EnableWindow( 311 | GetDlgItem(hDlg, ID_BTN_BROWSE), 312 | TRUE); 313 | } 314 | else 315 | { 316 | EnableWindow( 317 | GetDlgItem(hDlg, IDC_EDIT_FILTER_FILE), 318 | FALSE); 319 | 320 | EnableWindow( 321 | GetDlgItem(hDlg, ID_BTN_BROWSE), 322 | FALSE); 323 | } 324 | 325 | return FALSE; 326 | } 327 | case ID_BTN_REFRESH: 328 | { 329 | stFillProcessInformation(GetDlgItem(hDlg, IDC_LIST_PROCESS)); 330 | break; 331 | } 332 | case ID_BTN_BROWSE: 333 | { 334 | wchar_t tempFileName[MAX_PATH]; 335 | tempFileName[0] = 0; 336 | 337 | OPENFILENAME ofn = {0}; 338 | 339 | ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; 340 | ofn.hwndOwner = hDlg; 341 | ofn.hInstance = ghInstance; 342 | ofn.lpstrFile = tempFileName; 343 | ofn.nMaxFile = MAX_PATH; 344 | ofn.lpstrTitle = L"Select an StraceNT Filter File"; 345 | ofn.Flags = OFN_LONGNAMES | OFN_PATHMUSTEXIST; 346 | 347 | ofn.lpstrFilter = L"Text Files (*.txt)\0*.txt;\0\0"; 348 | ofn.lpstrDefExt = L"txt"; 349 | 350 | if (GetOpenFileName(&ofn)) 351 | { 352 | SetWindowText( 353 | GetDlgItem(hDlg, IDC_EDIT_FILTER_FILE), 354 | ofn.lpstrFile); 355 | } 356 | 357 | return TRUE; 358 | } 359 | case IDOK: 360 | { 361 | if (IsDlgButtonChecked(hDlg, IDC_CHECK_FILTER)) 362 | { 363 | wchar_t itemText[MAX_PATH] = {0}; 364 | 365 | GetWindowText( 366 | GetDlgItem(hDlg, IDC_EDIT_FILTER_FILE), 367 | itemText, 368 | CHARCOUNT(itemText)); 369 | 370 | pAttachProcess->ApplyFilter = true; 371 | pAttachProcess->FilterFile = itemText; 372 | 373 | if (pAttachProcess->FilterFile.length() <= 0) 374 | { 375 | MessageBox( 376 | hDlg, 377 | L"Please specify a valid filter file path", 378 | L"StraceNT Error", 379 | MB_OK | MB_ICONSTOP); 380 | 381 | return TRUE; 382 | } 383 | } 384 | 385 | int nSelectedItem = 386 | ListView_GetSelectionMark( 387 | GetDlgItem(hDlg, IDC_LIST_PROCESS)); 388 | 389 | if (nSelectedItem >= 0) 390 | { 391 | wchar_t itemText[MAX_PATH] = {0}; 392 | ListView_GetItemText( 393 | GetDlgItem(hDlg, IDC_LIST_PROCESS), 394 | nSelectedItem, 395 | 1, 396 | itemText, 397 | CHARCOUNT(itemText)); 398 | 399 | pAttachProcess->ProcessId = itemText; 400 | } 401 | else 402 | { 403 | MessageBox( 404 | hDlg, 405 | L"Please select a process to trace.", 406 | L"StraceNT Error", 407 | MB_OK | MB_ICONSTOP); 408 | 409 | return TRUE; 410 | } 411 | 412 | EndDialog(hDlg, IDOK); 413 | return TRUE; 414 | } 415 | case IDCANCEL: 416 | { 417 | EndDialog(hDlg, IDCANCEL); 418 | return TRUE; 419 | } 420 | } 421 | 422 | break; 423 | } 424 | } 425 | 426 | return FALSE; 427 | } 428 | 429 | 430 | INT_PTR 431 | CALLBACK 432 | stLaunchProcessDlgProc( 433 | HWND hDlg, 434 | UINT msg, 435 | WPARAM wParam, 436 | LPARAM lParam) 437 | /*++ 438 | 439 | Routine Description: 440 | 441 | Dialog box for user to launch a new process 442 | 443 | Returns: 444 | 445 | TRUE - Message handled by the dialog proc 446 | FALSE - Message not handled 447 | 448 | --*/ 449 | { 450 | PST_LAUNCH_PROCESS pLaunchProcess = NULL; 451 | 452 | if (msg == WM_INITDIALOG) 453 | { 454 | OPENFILENAME *pOpenFile = (OPENFILENAME *)lParam; 455 | SetWindowLongPtr(hDlg, GWLP_USERDATA, pOpenFile->lCustData); 456 | pLaunchProcess = (PST_LAUNCH_PROCESS)pOpenFile->lCustData; 457 | } 458 | else 459 | { 460 | pLaunchProcess = (PST_LAUNCH_PROCESS) 461 | GetWindowLongPtr(hDlg, GWLP_USERDATA); 462 | } 463 | 464 | //IHU_DBG_ASSERT(pLaunchProcess); 465 | 466 | switch(msg) 467 | { 468 | case WM_INITDIALOG: 469 | { 470 | EnableWindow( 471 | GetDlgItem(hDlg, IDC_EDIT_FILTER_FILE), 472 | FALSE); 473 | 474 | EnableWindow( 475 | GetDlgItem(hDlg, ID_BTN_BROWSE), 476 | FALSE); 477 | 478 | return FALSE; 479 | } 480 | case WM_COMMAND: 481 | { 482 | switch(wParam) 483 | { 484 | case IDC_CHECK_FILTER: 485 | { 486 | if (IsDlgButtonChecked(hDlg, IDC_CHECK_FILTER)) 487 | { 488 | EnableWindow( 489 | GetDlgItem(hDlg, IDC_EDIT_FILTER_FILE), 490 | TRUE); 491 | 492 | EnableWindow( 493 | GetDlgItem(hDlg, ID_BTN_BROWSE), 494 | TRUE); 495 | } 496 | else 497 | { 498 | EnableWindow( 499 | GetDlgItem(hDlg, IDC_EDIT_FILTER_FILE), 500 | FALSE); 501 | 502 | EnableWindow( 503 | GetDlgItem(hDlg, ID_BTN_BROWSE), 504 | FALSE); 505 | } 506 | 507 | return TRUE; 508 | } 509 | case ID_BTN_BROWSE: 510 | { 511 | wchar_t tempFileName[MAX_PATH]; 512 | tempFileName[0] = 0; 513 | 514 | OPENFILENAME ofn = {0}; 515 | 516 | ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; 517 | ofn.hwndOwner = hDlg; 518 | ofn.hInstance = ghInstance; 519 | ofn.lpstrFile = tempFileName; 520 | ofn.nMaxFile = MAX_PATH; 521 | ofn.lpstrTitle = L"Select an StraceNT Filter File"; 522 | ofn.Flags = OFN_LONGNAMES | OFN_PATHMUSTEXIST; 523 | 524 | ofn.lpstrFilter = L"Text Files (*.txt)\0*.txt;\0\0"; 525 | ofn.lpstrDefExt = L"txt"; 526 | 527 | if (GetOpenFileName(&ofn)) 528 | { 529 | SetWindowText( 530 | GetDlgItem(hDlg, IDC_EDIT_FILTER_FILE), 531 | ofn.lpstrFile); 532 | } 533 | 534 | return TRUE; 535 | } 536 | } 537 | 538 | break; 539 | } 540 | case WM_NOTIFY: 541 | { 542 | if (((LPOFNOTIFY)lParam)->hdr.code == CDN_FILEOK) 543 | { 544 | if (IsDlgButtonChecked(hDlg, IDC_CHECK_FILTER)) 545 | { 546 | wchar_t itemText[MAX_PATH] = {0}; 547 | 548 | GetWindowText( 549 | GetDlgItem(hDlg, IDC_EDIT_FILTER_FILE), 550 | itemText, 551 | CHARCOUNT(itemText)); 552 | 553 | pLaunchProcess->ApplyFilter = true; 554 | pLaunchProcess->FilterFile = itemText; 555 | 556 | if (pLaunchProcess->FilterFile.length() <= 0) 557 | { 558 | MessageBox( 559 | hDlg, 560 | L"Please specify a valid filter file path", 561 | L"StraceNT Error", 562 | MB_OK | MB_ICONSTOP); 563 | 564 | return TRUE; 565 | } 566 | } 567 | 568 | wchar_t processArguments[1024] = {0}; 569 | 570 | GetDlgItemText( 571 | hDlg, 572 | IDC_EDIT_ARGS, 573 | processArguments, 574 | CHARCOUNT(processArguments)); 575 | 576 | pLaunchProcess->Arguments = processArguments; 577 | 578 | return FALSE; 579 | } 580 | 581 | break; 582 | } 583 | } 584 | 585 | return FALSE; 586 | } 587 | -------------------------------------------------------------------------------- /src/serum/patchmgr.cpp: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) 2011, Pankaj Garg 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | --*/ 28 | 29 | /*++ 30 | 31 | Module Description: 32 | 33 | Implements house-keeping for patched functions like their 34 | name, original return address and patched address etc. Also 35 | implements exclusion/inclusion for patched functions and 36 | modules. 37 | 38 | --*/ 39 | 40 | #include "serum.h" 41 | 42 | // 43 | // Used to convert a character to uppercase 44 | // 45 | TO_UPPER gToUpper = ihiToUpper; 46 | 47 | 48 | /*++ 49 | 50 | Routine Name: 51 | 52 | ihiToUpper 53 | 54 | Routine Description: 55 | 56 | Converts a character to uppercase. It is implemented to 57 | remove warnings generated due to use of int in toupper. 58 | 59 | Return: 60 | 61 | Upper case character 62 | 63 | --*/ 64 | char 65 | __cdecl 66 | ihiToUpper(char c) 67 | { 68 | return (char)toupper((char)c); 69 | } 70 | 71 | 72 | /*++ 73 | 74 | Routine Name: 75 | 76 | CPatchManager 77 | 78 | Routine Description: 79 | 80 | Constructs a Patch manager object 81 | 82 | Return: 83 | 84 | none 85 | 86 | --*/ 87 | CPatchManager::CPatchManager() 88 | { 89 | mPatchManagerMutex = CreateMutex(NULL, FALSE, NULL); 90 | 91 | mPatchedApiListHead = NULL; 92 | mPatchedApiListTail = NULL; 93 | mPatchedApiCount = 0; 94 | 95 | mPatchedModuleCount = 0; 96 | memset(mPatchedModuleList, 0, sizeof(mPatchedModuleList)); 97 | 98 | mPatchesRemoved = false; 99 | } 100 | 101 | 102 | /*++ 103 | 104 | Routine Name: 105 | 106 | ~CPatchManager 107 | 108 | Routine Description: 109 | 110 | Destroys a Patch manager object 111 | 112 | Return: 113 | 114 | none 115 | 116 | --*/ 117 | CPatchManager::~CPatchManager() 118 | { 119 | // Reset the list of patched API 120 | mPatchedApiListHead = NULL; 121 | mPatchedApiListTail = NULL; 122 | mPatchedApiCount = 0; 123 | 124 | // Reset the patched module count 125 | mPatchedModuleCount = 0; 126 | 127 | // close the handles to the mutex created for patching 128 | // house-keeping 129 | CloseHandle(mPatchManagerMutex); 130 | } 131 | 132 | 133 | /*++ 134 | 135 | Routine Name: 136 | 137 | Lock 138 | 139 | Routine Description: 140 | 141 | Lock the patch manager object for write access 142 | 143 | Return: 144 | 145 | none 146 | 147 | --*/ 148 | void 149 | CPatchManager::Lock() 150 | { 151 | WaitForSingleObject(mPatchManagerMutex, INFINITE); 152 | } 153 | 154 | 155 | /*++ 156 | 157 | Routine Name: 158 | 159 | UnLock 160 | 161 | Routine Description: 162 | 163 | UnLock the patch manager object once write operations 164 | are done 165 | 166 | Return: 167 | 168 | none 169 | 170 | --*/ 171 | void 172 | CPatchManager::UnLock() 173 | { 174 | ReleaseMutex(mPatchManagerMutex); 175 | } 176 | 177 | 178 | /*++ 179 | 180 | Routine Name: 181 | 182 | InsertNewPatch 183 | 184 | Routine Description: 185 | 186 | Allocates memory for code and data for a new patch and add 187 | it to the global list. 188 | 189 | Memory is allocated in chunks of M_HOOK_ENTRY_CHUNK_SIZE 190 | to make patching efficient. Once we hit the limit on one 191 | chunk we allocate next chunk of memory and add it to our list. 192 | 193 | To-Do!!! 194 | APIs even if imported in two modules should still have a common 195 | Hook entry if both name and original address are same. 196 | 197 | Return: 198 | 199 | Prolog code address - if we could allocate memory 200 | NULL - otherwise 201 | 202 | --*/ 203 | LPVOID 204 | CPatchManager::InsertNewPatch( 205 | LPSTR inApiName, 206 | LPVOID inOrigFuncAddr, 207 | IHI_FN_RETURN_VALUE &inRetValInfo) 208 | { 209 | LPVOID funcReturn = NULL; 210 | IHI_PATCHED_API_DATA *patchedApiArray = NULL; 211 | 212 | ULONG tableIndex = mPatchedApiCount / M_HOOK_ENTRY_CHUNK_SIZE; 213 | ULONG entryIndex = mPatchedApiCount % M_HOOK_ENTRY_CHUNK_SIZE; 214 | 215 | if ((mPatchedApiCount % M_HOOK_ENTRY_CHUNK_SIZE) == 0) 216 | { 217 | patchedApiArray = (IHI_PATCHED_API_DATA *) 218 | VirtualAlloc( 219 | NULL, 220 | sizeof(IHI_PATCHED_API_DATA), 221 | MEM_COMMIT, 222 | PAGE_READWRITE); 223 | 224 | if (patchedApiArray == NULL) 225 | { 226 | goto funcEnd; 227 | } 228 | 229 | if (mPatchedApiListTail) 230 | { 231 | mPatchedApiListTail->Next = patchedApiArray; 232 | } 233 | 234 | patchedApiArray->Next = NULL; 235 | mPatchedApiListTail = patchedApiArray; 236 | 237 | if (mPatchedApiListHead == NULL) 238 | { 239 | mPatchedApiListHead = patchedApiArray; 240 | } 241 | 242 | patchedApiArray->mPatchCodeArray = (PATCH_CODE *) 243 | VirtualAlloc( 244 | NULL, 245 | sizeof(PATCH_CODE) * M_HOOK_ENTRY_CHUNK_SIZE, 246 | MEM_COMMIT, 247 | PAGE_EXECUTE_READWRITE); 248 | 249 | if (patchedApiArray->mPatchCodeArray == NULL) 250 | { 251 | goto funcEnd; 252 | } 253 | } 254 | 255 | patchedApiArray = GetPatchedApiArrayAt(tableIndex); 256 | 257 | ihiInitPatchCode( 258 | patchedApiArray->mPatchCodeArray[entryIndex], 259 | mPatchedApiCount); 260 | 261 | StringCchCopyA( 262 | patchedApiArray->mApiData[entryIndex].mApiName, 263 | MAX_API_NAME_LENGTH, 264 | inApiName); 265 | 266 | patchedApiArray->mApiData[entryIndex].mOriginalAddress = inOrigFuncAddr; 267 | patchedApiArray->mApiData[entryIndex].mReturnValue = inRetValInfo; 268 | 269 | // one more api patched 270 | mPatchedApiCount++; 271 | 272 | funcReturn = &patchedApiArray->mPatchCodeArray[entryIndex].Prolog; 273 | 274 | funcEnd: 275 | 276 | if (funcReturn == NULL) 277 | { 278 | if (patchedApiArray) 279 | { 280 | VirtualFree(patchedApiArray, 0, MEM_RELEASE); 281 | } 282 | } 283 | 284 | return funcReturn; 285 | } 286 | 287 | 288 | IHI_PATCHED_API_DATA * 289 | CPatchManager::GetPatchedApiArrayAt( 290 | ULONG inIndex) 291 | /*++ 292 | 293 | Routine Description: 294 | 295 | Returns the Patched API array at the given index 296 | 297 | Return: 298 | 299 | returns patched API array 300 | 301 | --*/ 302 | { 303 | IHI_PATCHED_API_DATA *pCurrent = mPatchedApiListHead; 304 | 305 | for (ULONG i = 0; i < inIndex; i++) 306 | { 307 | if (pCurrent == NULL) 308 | { 309 | break; 310 | } 311 | 312 | pCurrent = pCurrent->Next; 313 | } 314 | 315 | return pCurrent; 316 | } 317 | 318 | 319 | LPVOID 320 | CPatchManager::GetOrigFuncAddrAt( 321 | ULONG inIndex) 322 | /*++ 323 | 324 | Routine Description: 325 | 326 | Returns the address of original function, that 327 | we patched, at given index 328 | 329 | Return: 330 | 331 | Original Function address - if inIndex is valid 332 | NULL - otherwise 333 | 334 | --*/ 335 | { 336 | //IHU_DBG_ASSERT(inIndex < mPatchedApiCount); 337 | 338 | ULONG tableIndex = inIndex / M_HOOK_ENTRY_CHUNK_SIZE; 339 | ULONG entryIndex = inIndex % M_HOOK_ENTRY_CHUNK_SIZE; 340 | 341 | IHI_PATCHED_API_DATA *patchedApiArray = GetPatchedApiArrayAt(tableIndex); 342 | 343 | return (LPVOID)patchedApiArray->mApiData[entryIndex].mOriginalAddress; 344 | } 345 | 346 | 347 | /*++ 348 | 349 | Routine Name: 350 | 351 | GetMatchingOrigFuncAddr 352 | 353 | Routine Description: 354 | 355 | Returns the address of original function corresponding 356 | to a patch address 357 | 358 | Return: 359 | 360 | Original Function address - if Patched address if found 361 | NULL - otherwise 362 | 363 | --*/ 364 | LPVOID 365 | CPatchManager::GetMatchingOrigFuncAddr( 366 | LPVOID pfnPatchedFunction) 367 | { 368 | IHI_PATCHED_API_DATA *pPatchedApiArray = mPatchedApiListHead; 369 | 370 | while (pPatchedApiArray) 371 | { 372 | for (int i = 0; i < M_HOOK_ENTRY_CHUNK_SIZE; ++i) 373 | { 374 | if ((DWORD_PTR)&pPatchedApiArray->mPatchCodeArray[i].Prolog == (DWORD_PTR)pfnPatchedFunction) 375 | { 376 | return pPatchedApiArray->mApiData[i].mOriginalAddress; 377 | } 378 | } 379 | 380 | pPatchedApiArray = pPatchedApiArray->Next; 381 | } 382 | 383 | return NULL; 384 | } 385 | 386 | 387 | /*++ 388 | 389 | Routine Name: 390 | 391 | GetFuncNameAt 392 | 393 | Routine Description: 394 | 395 | Returns the name of a patched function at given index 396 | 397 | Return: 398 | 399 | Function name 400 | 401 | --*/ 402 | LPCSTR 403 | CPatchManager::GetFuncNameAt( 404 | ULONG inIndex) 405 | { 406 | //IHU_DBG_ASSERT(inIndex < mPatchedApiCount); 407 | 408 | ULONG tableIndex = inIndex / M_HOOK_ENTRY_CHUNK_SIZE; 409 | ULONG entryIndex = inIndex % M_HOOK_ENTRY_CHUNK_SIZE; 410 | 411 | IHI_PATCHED_API_DATA *patchedApiArray = GetPatchedApiArrayAt(tableIndex); 412 | 413 | return patchedApiArray->mApiData[entryIndex].mApiName; 414 | } 415 | 416 | 417 | void 418 | CPatchManager::GetFnReturnValueInfoAt( 419 | ULONG inIndex, 420 | IHI_FN_RETURN_VALUE &oRetValInfo) 421 | /*++ 422 | 423 | Routine Description: 424 | 425 | Copies the Return Data information about the function at given index 426 | in the output variable 427 | 428 | Return: 429 | 430 | none 431 | 432 | --*/ 433 | { 434 | //IHU_DBG_ASSERT(inIndex < mPatchedApiCount); 435 | 436 | ULONG tableIndex = inIndex / M_HOOK_ENTRY_CHUNK_SIZE; 437 | ULONG entryIndex = inIndex % M_HOOK_ENTRY_CHUNK_SIZE; 438 | 439 | IHI_PATCHED_API_DATA *patchedApiArray = GetPatchedApiArrayAt(tableIndex); 440 | 441 | oRetValInfo = patchedApiArray->mApiData[entryIndex].mReturnValue; 442 | return; 443 | } 444 | 445 | 446 | void 447 | CPatchManager::RemoveAllPatches() 448 | /*++ 449 | 450 | Routine Description: 451 | 452 | Remove all the patches from the process 453 | 454 | NOTE: 455 | In our earlier design, we were freeing the memory allocated for the patches 456 | here. This works fine for IAT patched functions, but the functions which we 457 | patched dynamically by hooking GetProcAddress may still have the address to 458 | our patch code and if we free this memory, we end up crashing the target. 459 | 460 | Because RemoveAllPatches is mostly called when our DLL is getting unloaded 461 | we either need to restore the original functions that we patched or we need 462 | to modify our patches in such a way that they don't refer to our injector 463 | DLL. We are not able to restore all the patches as described in the first 464 | paragraph. So we simply fix the patch code to refer back to the original 465 | function and we don't free any memory. The *not* freeing of memory should 466 | not be a problem because in most cases as injector.dll is only unloaded 467 | when the target program is exiting. When injector.dll is unloaded for some 468 | other reason, then we would cause a small memory leak, but since the leak 469 | is small, we can ignore it. (TODO: If this memory leak becomes too big a 470 | problem, then can differentiate IAT patches from GetProcAddress patches and 471 | selectively free memory allocated to IAT patches) 472 | 473 | Initially our patch code is of the format 474 | addr_x CALL [addr32] 475 | addr_y api_index 476 | addr_32 [address of ihiPatchProlog] 477 | 478 | in our patch fixing to refer to original function, we convert it to 479 | addr_x JMP [addr32] 480 | addr_y api_index 481 | addr_32 [address of Original function] 482 | 483 | Returns: 484 | 485 | none 486 | 487 | --*/ 488 | { 489 | if (mPatchesRemoved == false) 490 | { 491 | for (ULONG i = 0; i < mPatchedApiCount; ++i) 492 | { 493 | ULONG tableIndex = i / M_HOOK_ENTRY_CHUNK_SIZE; 494 | ULONG entryIndex = i % M_HOOK_ENTRY_CHUNK_SIZE; 495 | 496 | IHI_PATCHED_API_DATA *patchedApiArray = GetPatchedApiArrayAt(tableIndex); 497 | 498 | IHI_API_DATA *apiInfo = &patchedApiArray->mApiData[entryIndex]; 499 | PATCH_CODE *patchCode = &patchedApiArray->mPatchCodeArray[entryIndex]; 500 | 501 | patchCode->Prolog.Call[1] = 0x25; 502 | patchCode->Prolog.dwAddress = (DWORD)(DWORD_PTR)apiInfo->mOriginalAddress; 503 | } 504 | 505 | mPatchesRemoved = true; 506 | } 507 | } 508 | 509 | 510 | /*++ 511 | 512 | Routine Name: 513 | 514 | IsModulePatched 515 | 516 | Routine Description: 517 | 518 | Finds whether a given module is already patched or 519 | not. 520 | 521 | Return: 522 | 523 | true - If the specified module is already patched 524 | false - otherwise 525 | 526 | --*/ 527 | bool 528 | CPatchManager::IsModulePatched( 529 | HANDLE inModuleHandle) 530 | { 531 | bool bFound = false; 532 | 533 | for (ULONG i = 0; i < mPatchedModuleCount; ++i) 534 | { 535 | if (mPatchedModuleList[i] == inModuleHandle) 536 | { 537 | bFound = true; 538 | break; 539 | } 540 | } 541 | 542 | return bFound; 543 | } 544 | 545 | 546 | /*++ 547 | 548 | Routine Name: 549 | 550 | AddModuleToPatchedList 551 | 552 | Routine Description: 553 | 554 | Add a new module to the list of patched modules 555 | 556 | Return: 557 | 558 | none 559 | 560 | --*/ 561 | void 562 | CPatchManager::AddModuleToPatchedList( 563 | HANDLE inModuleHandle) 564 | { 565 | if (!IsModulePatched(inModuleHandle)) 566 | { 567 | if (mPatchedModuleCount < (IHI_MAX_MODULES - 1)) 568 | { 569 | mPatchedModuleList[mPatchedModuleCount++] = inModuleHandle; 570 | } 571 | } 572 | } 573 | 574 | 575 | /*++ 576 | 577 | Routine Name: 578 | 579 | RemoveModuleFromPatchedList 580 | 581 | Routine Description: 582 | 583 | Removes a module from the list of patched modules 584 | 585 | Return: 586 | 587 | none 588 | 589 | --*/ 590 | void 591 | CPatchManager::RemoveModuleFromPatchedList( 592 | HANDLE inModuleHandle) 593 | { 594 | ULONG moduleIndex = 0; 595 | ULONG i = 0; 596 | 597 | for ( moduleIndex = 0; 598 | moduleIndex < mPatchedModuleCount; 599 | ++moduleIndex) 600 | { 601 | if (mPatchedModuleList[moduleIndex] == inModuleHandle) 602 | { 603 | break; 604 | } 605 | } 606 | 607 | for (i = moduleIndex; i < mPatchedModuleCount; ++i) 608 | { 609 | mPatchedModuleList[i] = mPatchedModuleList[i+1]; 610 | } 611 | 612 | mPatchedModuleList[i] = NULL; 613 | --mPatchedModuleCount; 614 | } 615 | 616 | 617 | /*++ 618 | 619 | Routine Name: 620 | 621 | GetPatchedModulesHandle 622 | 623 | Routine Description: 624 | 625 | Returns the handle of patched module 626 | at the given index 627 | 628 | Return: 629 | 630 | handle of patched module at given index 631 | null if the index is out of bounds 632 | 633 | --*/ 634 | HANDLE 635 | CPatchManager::GetPatchedModulesHandle( 636 | ULONG moduleIndex) 637 | { 638 | if (moduleIndex < mPatchedModuleCount) 639 | { 640 | return mPatchedModuleList[moduleIndex]; 641 | } 642 | 643 | return NULL; 644 | } 645 | 646 | 647 | /*++ 648 | 649 | Routine Name: 650 | 651 | GetPatchedModulesCount 652 | 653 | Routine Description: 654 | 655 | Returns the total number of patched modules 656 | 657 | Return: 658 | 659 | count of patched modules 660 | 661 | --*/ 662 | ULONG 663 | CPatchManager::GetPatchedModulesCount() 664 | { 665 | return mPatchedModuleCount; 666 | } 667 | 668 | 669 | /*++ 670 | 671 | Routine Name: 672 | 673 | CPatchInclExclMgr 674 | 675 | Routine Description: 676 | 677 | Constructs a Patch Inclusion/Exclusion manager 678 | 679 | --*/ 680 | CPatchInclExclMgr::CPatchInclExclMgr() 681 | { 682 | } 683 | 684 | 685 | /*++ 686 | 687 | Routine Name: 688 | 689 | ~CPatchInclExclMgr 690 | 691 | Routine Description: 692 | 693 | Destructs a Patch Inclusion/Exclusion manager 694 | 695 | --*/ 696 | CPatchInclExclMgr::~CPatchInclExclMgr() 697 | { 698 | } 699 | 700 | 701 | /*++ 702 | 703 | Routine Name: 704 | 705 | SetInclExclList 706 | 707 | Routine Description: 708 | 709 | This function is used to set the inclusion and exclusion 710 | list of Functions. 711 | 712 | Return: 713 | 714 | none 715 | 716 | --*/ 717 | void 718 | CPatchInclExclMgr::SetInclExclList( 719 | LPCSTR inFnIncludes, 720 | LPCSTR inFnExcludes) 721 | { 722 | // 723 | // Hardcoded exclusion for problem causing modules. 724 | // 725 | string modName; 726 | modName = "ntdll"; 727 | m_ExcludeModuleList.push_back(modName); 728 | modName = "msvc"; 729 | m_ExcludeModuleList.push_back(modName); 730 | modName = "mfc"; 731 | m_ExcludeModuleList.push_back(modName); 732 | modName = "api-ms-win"; 733 | m_ExcludeModuleList.push_back(modName); 734 | 735 | // 736 | // User provided include/exclude. 737 | // 738 | std::string fnIncList = inFnIncludes; 739 | std::string fnExcList = inFnExcludes; 740 | 741 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_INFO, 742 | L"Adding user includes: %S\n", 743 | fnIncList.c_str()); 744 | BuildInclOrExclList(fnIncList, m_IncludeRuleList); 745 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_INFO, 746 | L"Adding user excludes: %S\n", 747 | fnExcList.c_str()); 748 | BuildInclOrExclList(fnExcList, m_ExcludeRuleList); 749 | 750 | ihiRuleListDump(m_IncludeRuleList, L"INCLUDE"); 751 | ihiRuleListDump(m_ExcludeRuleList, L"EXCLUDE"); 752 | } 753 | 754 | 755 | void 756 | CPatchInclExclMgr::BuildInclOrExclList( 757 | std::string inFnList, 758 | InclExclRuleList &ioRuleList) 759 | { 760 | // Start from second character as first character will be < 761 | int index_begin = 1; 762 | int index_end = 0; 763 | 764 | while (true) 765 | { 766 | index_end = inFnList.find_first_of('>', index_begin); 767 | 768 | if (index_end == -1) 769 | { 770 | break; 771 | } 772 | 773 | std::string fnInc = inFnList.substr(index_begin, index_end - index_begin); 774 | 775 | int i_begin = 0; 776 | int i_end = 0; 777 | do 778 | { 779 | std::string loadedModule; 780 | std::string impModule; 781 | std::string fnName; 782 | bool loadedModuleIsPrefix; 783 | bool impModuleIsPrefix; 784 | bool fnNameIsPrefix; 785 | std::string retValStr; 786 | IHI_FN_RETURN_VALUE retValInfo = {0}; 787 | 788 | loadedModuleIsPrefix = false; 789 | impModuleIsPrefix = false; 790 | fnNameIsPrefix = false; 791 | 792 | i_end = fnInc.find_first_of(':', i_begin); 793 | 794 | if (i_end == -1) 795 | { 796 | // incorrect format, required : missing 797 | break; 798 | } 799 | 800 | loadedModule = fnInc.substr(i_begin, i_end - i_begin); 801 | 802 | if (loadedModule.compare(".") == 0) 803 | { 804 | loadedModule = g_MainExeName; 805 | } 806 | 807 | i_begin = i_end + 1; 808 | 809 | i_end = fnInc.find_first_of(':', i_begin); 810 | 811 | if (i_end == -1) 812 | { 813 | // incorrect format, required : missing 814 | break; 815 | } 816 | 817 | impModule = fnInc.substr(i_begin, i_end - i_begin); 818 | 819 | i_begin = i_end + 1; 820 | 821 | i_end = fnInc.find_first_of('=', i_begin); 822 | 823 | if (i_end == -1) 824 | { 825 | fnName = fnInc.substr(i_begin, fnInc.length() - i_begin); 826 | } 827 | else 828 | { 829 | fnName = fnInc.substr(i_begin, i_end - i_begin); 830 | 831 | i_begin = i_end + 1; 832 | 833 | if (i_begin < (int)fnInc.length()) 834 | { 835 | // a return value is specified 836 | retValStr = fnInc.substr(i_begin, fnInc.length() - i_begin); 837 | 838 | retValInfo.UserSpecified = true; 839 | retValInfo.Value = (int)strtoul(retValStr.c_str(), NULL, 0); 840 | } 841 | } 842 | 843 | if (loadedModule.empty() || impModule.empty() || fnName.empty()) 844 | { 845 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_ERROR, 846 | L"Ignoring invalid include/exclude list: %S\n", 847 | fnInc.c_str()); 848 | break; 849 | } 850 | 851 | if (*loadedModule.rbegin() == '*') 852 | { 853 | loadedModule.pop_back(); 854 | loadedModuleIsPrefix = true; 855 | } 856 | 857 | if (*impModule.rbegin() == '*') 858 | { 859 | impModule.pop_back(); 860 | impModuleIsPrefix = true; 861 | } 862 | 863 | if (*fnName.rbegin() == '*') 864 | { 865 | fnName.pop_back(); 866 | fnNameIsPrefix = true; 867 | } 868 | 869 | InclExclRule rule; 870 | rule.LoadedModuleName = loadedModule; 871 | rule.LoadedModuleNameIsPrefix = loadedModuleIsPrefix; 872 | rule.ImportedModuleName = impModule; 873 | rule.ImportedModuleNameIsPrefix = impModuleIsPrefix; 874 | rule.FunctionName = fnName; 875 | rule.FunctionNameIsPrefix = fnNameIsPrefix; 876 | rule.ReturnValue = retValInfo; 877 | ioRuleList.push_back(rule); 878 | } while (false); 879 | 880 | index_begin = index_end + 2; 881 | } 882 | } 883 | 884 | 885 | // 886 | // TODO 887 | // We need better inclusion/exclusion management code 888 | // The concept i am using is fine but the implementation is 889 | // not very good. Since this is not a critical piece of code 890 | // this should be acceptable for now 891 | // 892 | 893 | bool 894 | CPatchInclExclMgr::PatchRequired( 895 | LPCSTR inLoadedModuleName, 896 | LPCSTR inImpModuleName, 897 | LPCSTR inFnName, 898 | bool inOrdinalExport, 899 | IHI_FN_RETURN_VALUE *oRetValInfo) 900 | /*++ 901 | 902 | Routine Description: 903 | 904 | This routine checks if a function should be patched or not, based on the 905 | exclusion/inclusion list. 906 | 907 | Arguments: 908 | 909 | inLoadedModuleName - The module which is calling the function 910 | 911 | inImpModuleName - The module which implements the function 912 | 913 | inFnName - Name of the function (for functions exported by ordinal 914 | this name is Ord%x) 915 | 916 | inOrdinalExport - Was the function exported by ordinal 917 | 918 | oRetValInfo - Return value information if a different return value is 919 | specified by the user 920 | 921 | Return: 922 | 923 | true - Patching required 924 | false - Don't patch 925 | 926 | --*/ 927 | { 928 | bool funcResult = false; 929 | int inclWeight = 0; 930 | int exclWeight = 0; 931 | InclExclRuleMatchInfo inclRule; 932 | InclExclRuleMatchInfo exclRule; 933 | 934 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_LOUD, 935 | L"IsPatchRequired for: %S, %S, %S\n", 936 | inLoadedModuleName, inImpModuleName, inFnName); 937 | 938 | if (ihiPatchAntiDebugFunction(inImpModuleName, inFnName)) 939 | { 940 | funcResult = true; 941 | goto Exit; 942 | } 943 | 944 | inclRule.MatchWeight = 0; 945 | inclRule.LoadedModuleName = inLoadedModuleName; 946 | inclRule.ImportedModuleName = inImpModuleName; 947 | inclRule.FunctionName = inFnName; 948 | exclRule = inclRule; 949 | 950 | if (ihiIsModuleExcluded(inclRule.ImportedModuleName, m_ExcludeModuleList, m_IncludeRuleList)) 951 | { 952 | funcResult = false; 953 | goto Exit; 954 | } 955 | 956 | ihiRuleFind(m_IncludeRuleList, inclRule); 957 | ihiRuleFind(m_ExcludeRuleList, exclRule); 958 | 959 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_LOUD, 960 | L"IsPatchRequired InclWeight: %x, ExclWeight: %x\n", 961 | inclRule.MatchWeight, exclRule.MatchWeight); 962 | 963 | if (exclRule.MatchWeight <= inclRule.MatchWeight) 964 | { 965 | funcResult = true; 966 | 967 | if (oRetValInfo != NULL && inclRule.MatchWeight > 0) 968 | { 969 | *oRetValInfo = inclRule.ReturnValue; 970 | } 971 | } 972 | else 973 | { 974 | funcResult = false; 975 | } 976 | 977 | Exit: 978 | 979 | if (funcResult) 980 | { 981 | if (inFnName != NULL) 982 | { 983 | IHU_DBG_LOG_EX(TRC_PATCHIAT, IHU_LEVEL_INFO, 984 | L"Patching Function: %S->%S:%S\n", 985 | inLoadedModuleName, 986 | inImpModuleName, 987 | inFnName); 988 | } 989 | } 990 | 991 | return funcResult; 992 | } 993 | 994 | 995 | --------------------------------------------------------------------------------