├── README.md
├── ddr_client
├── Debug
│ ├── ddr_stable.dll
│ ├── ddr_stable.exp
│ ├── ddr_stable.ilk
│ ├── ddr_stable.lib
│ └── ddr_stable.pdb
├── Release
│ ├── ddr_stable.dll
│ ├── ddr_stable.exp
│ ├── ddr_stable.iobj
│ ├── ddr_stable.ipdb
│ ├── ddr_stable.lib
│ └── ddr_stable.pdb
├── ddr_stable.sln
├── ddr_stable
│ ├── Debug
│ │ ├── ddr_helper_functions.obj
│ │ ├── ddr_stable.Build.CppClean.log
│ │ ├── ddr_stable.dll.recipe
│ │ ├── ddr_stable.log
│ │ ├── ddr_stable.tlog
│ │ │ ├── CL.command.1.tlog
│ │ │ ├── CL.read.1.tlog
│ │ │ ├── CL.write.1.tlog
│ │ │ ├── ddr_stable.lastbuildstate
│ │ │ ├── ddr_stable.write.1u.tlog
│ │ │ ├── link.command.1.tlog
│ │ │ ├── link.read.1.tlog
│ │ │ └── link.write.1.tlog
│ │ ├── ddr_stable.vcxproj.FileListAbsolute.txt
│ │ ├── dump_buffer1.obj
│ │ ├── main.obj
│ │ ├── patch_exe.obj
│ │ ├── trace_instr.obj
│ │ ├── vc142.idb
│ │ └── vc142.pdb
│ ├── DynRio_debug_x32_PropertySheet.props
│ ├── DynRio_debug_x64_PropertySheet.props
│ ├── DynRio_release_x64_PropertySheet.props
│ ├── DynRio_release_x86_PropertySheet.props
│ ├── Release
│ │ ├── ddr_helper_functions.obj
│ │ ├── ddr_stable.Build.CppClean.log
│ │ ├── ddr_stable.dll.recipe
│ │ ├── ddr_stable.log
│ │ ├── ddr_stable.tlog
│ │ │ ├── CL.command.1.tlog
│ │ │ ├── CL.read.1.tlog
│ │ │ ├── CL.write.1.tlog
│ │ │ ├── ddr_stable.lastbuildstate
│ │ │ ├── ddr_stable.write.1u.tlog
│ │ │ ├── link.command.1.tlog
│ │ │ ├── link.read.1.tlog
│ │ │ └── link.write.1.tlog
│ │ ├── ddr_stable.vcxproj.FileListAbsolute.txt
│ │ ├── dump_buffer1.obj
│ │ ├── main.obj
│ │ ├── patch_exe.obj
│ │ ├── trace_instr.obj
│ │ └── vc142.pdb
│ ├── ddr.h
│ ├── ddr_config.txt
│ ├── ddr_config64.txt
│ ├── ddr_helper_functions.c
│ ├── ddr_stable.vcxproj
│ ├── ddr_stable.vcxproj.filters
│ ├── ddr_stable.vcxproj.user
│ ├── dump_buffer1.c
│ ├── globals.h
│ ├── main.c
│ ├── patch_exe.c
│ ├── trace_instr.c
│ └── x64
│ │ ├── Debug
│ │ ├── ddr_helper_functions.obj
│ │ ├── ddr_stable.Build.CppClean.log
│ │ ├── ddr_stable.dll.recipe
│ │ ├── ddr_stable.log
│ │ ├── ddr_stable.tlog
│ │ │ ├── CL.command.1.tlog
│ │ │ ├── CL.read.1.tlog
│ │ │ ├── CL.write.1.tlog
│ │ │ ├── ddr_stable.lastbuildstate
│ │ │ ├── ddr_stable.write.1u.tlog
│ │ │ ├── link.command.1.tlog
│ │ │ ├── link.read.1.tlog
│ │ │ └── link.write.1.tlog
│ │ ├── ddr_stable.vcxproj.FileListAbsolute.txt
│ │ ├── dump_buffer1.obj
│ │ ├── main.obj
│ │ ├── patch_exe.obj
│ │ ├── trace_instr.obj
│ │ ├── vc142.idb
│ │ └── vc142.pdb
│ │ └── Release
│ │ ├── ddr_helper_functions.obj
│ │ ├── ddr_stable.Build.CppClean.log
│ │ ├── ddr_stable.dll.recipe
│ │ ├── ddr_stable.log
│ │ ├── ddr_stable.tlog
│ │ ├── CL.command.1.tlog
│ │ ├── CL.read.1.tlog
│ │ ├── CL.write.1.tlog
│ │ ├── ddr_stable.lastbuildstate
│ │ ├── ddr_stable.write.1u.tlog
│ │ ├── link.command.1.tlog
│ │ ├── link.read.1.tlog
│ │ └── link.write.1.tlog
│ │ ├── ddr_stable.vcxproj.FileListAbsolute.txt
│ │ ├── dump_buffer1.obj
│ │ ├── main.obj
│ │ ├── patch_exe.obj
│ │ ├── trace_instr.obj
│ │ └── vc142.pdb
└── x64
│ ├── Debug
│ ├── ddr_stable.dll
│ ├── ddr_stable.exp
│ ├── ddr_stable.ilk
│ ├── ddr_stable.lib
│ └── ddr_stable.pdb
│ └── Release
│ ├── ddr_stable.dll
│ ├── ddr_stable.exp
│ ├── ddr_stable.iobj
│ ├── ddr_stable.ipdb
│ ├── ddr_stable.lib
│ └── ddr_stable.pdb
├── ddr_installer.zip
└── ddr_installer
├── DDR_INSTALLER.py
├── README.txt
├── ddr_test_samples
├── testsample0_32_dyn.cfg
├── testsample0_32_dyn.exe
├── testsample0_64_dyn.cfg
├── testsample0_64_dyn.exe
├── testsample1_32.cfg
├── testsample1_32.exe
├── testsample1_64.cfg
├── testsample1_64.exe
├── testsample_with_args_x32.exe
├── testsample_with_args_x64.exe
└── testsamples_README.txt
├── docs
├── ddr_client_dll_sample_config32.txt
└── ddr_client_dll_sample_config64.txt
├── install_data
├── ddr32.dll
├── ddr32dbg.dll
├── ddr64.dll
├── ddr64dbg.dll
├── ddr_plugin.py
├── ddr_server.py
└── installer_web_server.py
├── known_bugs.txt
├── release_notes.txt
├── requirements.in
├── requirements.txt
├── roadmap.txt
└── templates
├── ddr_config_template.json
├── ddr_server_template.json
└── ida_plugin_installer_template.py
/README.md:
--------------------------------------------------------------------------------
1 | # Dynamic Data Resolver (DDR)
2 |
3 | ---
4 |
5 | Release date Version 1.0.2 beta: 17th of December 2020 15:00 CET
6 |
7 | New features:
8 |
9 | Start address - The instrumentation/analysis starts at this address
10 |
11 | Break address - The instrumentation and execution of the sample process stops here
12 |
13 | You can find a detailed description of the 1.0.2 features here at release time
14 | https://blog.talosintelligence.com/2020/12/talos-tools-of-trade.html
15 |
16 | ---
17 |
18 | Release date Version 1.0.1 beta: 20th of October 2020 17:00 CET
19 |
20 | You can find an overview of the 1.0.1 features here
21 | https://blog.talosintelligence.com/2020/10/ddr101beta.html
22 |
23 | ---
24 |
25 | Version 1.0
26 |
27 | Copyright (C) 2020 Cisco Talos
28 | Author: Holger Unterbrink (hunterbr@cisco.com)
29 |
30 | This program is free software; you can redistribute it and/or modify
31 | it under the terms of the GNU General Public License as published by
32 | the Free Software Foundation; either version 2 of the License, or
33 | (at your option) any later version.
34 |
35 | This program is distributed in the hope that it will be useful,
36 | but WITHOUT ANY WARRANTY; without even the implied warranty of
37 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 | GNU General Public License for more details.
39 |
40 | You should have received a copy of the GNU General Public License along
41 | with this program; if not, write to the Free Software Foundation, Inc.,
42 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 |
44 | **Blog**
45 |
46 | Release date Version 1.0: 28th of May 2020 17:00 CET
47 |
48 | The documentation and installation description of the project can be found here at release time:
49 |
50 | https://blog.talosintelligence.com/tbd
51 |
52 | A quick feature walkthrough video is here:
53 |
54 | https://youtu.be/miSFddzvzL8
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/ddr_client/Debug/ddr_stable.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/Debug/ddr_stable.dll
--------------------------------------------------------------------------------
/ddr_client/Debug/ddr_stable.exp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/Debug/ddr_stable.exp
--------------------------------------------------------------------------------
/ddr_client/Debug/ddr_stable.ilk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/Debug/ddr_stable.ilk
--------------------------------------------------------------------------------
/ddr_client/Debug/ddr_stable.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/Debug/ddr_stable.lib
--------------------------------------------------------------------------------
/ddr_client/Debug/ddr_stable.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/Debug/ddr_stable.pdb
--------------------------------------------------------------------------------
/ddr_client/Release/ddr_stable.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/Release/ddr_stable.dll
--------------------------------------------------------------------------------
/ddr_client/Release/ddr_stable.exp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/Release/ddr_stable.exp
--------------------------------------------------------------------------------
/ddr_client/Release/ddr_stable.iobj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/Release/ddr_stable.iobj
--------------------------------------------------------------------------------
/ddr_client/Release/ddr_stable.ipdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/Release/ddr_stable.ipdb
--------------------------------------------------------------------------------
/ddr_client/Release/ddr_stable.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/Release/ddr_stable.lib
--------------------------------------------------------------------------------
/ddr_client/Release/ddr_stable.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/Release/ddr_stable.pdb
--------------------------------------------------------------------------------
/ddr_client/ddr_stable.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30114.105
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ddr_stable", "ddr_stable\ddr_stable.vcxproj", "{6C96058E-3DA0-4451-816B-2A5E2E714911}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {6C96058E-3DA0-4451-816B-2A5E2E714911}.Debug|x64.ActiveCfg = Debug|x64
17 | {6C96058E-3DA0-4451-816B-2A5E2E714911}.Debug|x64.Build.0 = Debug|x64
18 | {6C96058E-3DA0-4451-816B-2A5E2E714911}.Debug|x86.ActiveCfg = Debug|Win32
19 | {6C96058E-3DA0-4451-816B-2A5E2E714911}.Debug|x86.Build.0 = Debug|Win32
20 | {6C96058E-3DA0-4451-816B-2A5E2E714911}.Release|x64.ActiveCfg = Release|x64
21 | {6C96058E-3DA0-4451-816B-2A5E2E714911}.Release|x64.Build.0 = Release|x64
22 | {6C96058E-3DA0-4451-816B-2A5E2E714911}.Release|x86.ActiveCfg = Release|Win32
23 | {6C96058E-3DA0-4451-816B-2A5E2E714911}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {BA49BEBA-3B25-4C4C-9E8D-C9D724CF926D}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Debug/ddr_helper_functions.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Debug/ddr_helper_functions.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Debug/ddr_stable.Build.CppClean.log:
--------------------------------------------------------------------------------
1 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\debug\vc142.pdb
2 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\debug\vc142.idb
3 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\debug\trace_instr.obj
4 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\debug\patch_exe.obj
5 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\debug\main.obj
6 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\debug\dump_buffer1.obj
7 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\debug\ddr_helper_functions.obj
8 | c:\tools\dev\git\dyndataresolver\ddr_client\debug\ddr_stable.lib
9 | c:\tools\dev\git\dyndataresolver\ddr_client\debug\ddr_stable.exp
10 | c:\tools\dev\git\dyndataresolver\ddr_client\debug\ddr_stable.ilk
11 | c:\tools\dev\git\dyndataresolver\ddr_client\debug\ddr_stable.dll
12 | c:\tools\dev\git\dyndataresolver\ddr_client\debug\ddr_stable.pdb
13 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\debug\ddr_stable.tlog\cl.command.1.tlog
14 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\debug\ddr_stable.tlog\cl.read.1.tlog
15 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\debug\ddr_stable.tlog\cl.write.1.tlog
16 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\debug\ddr_stable.tlog\ddr_stable.write.1u.tlog
17 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\debug\ddr_stable.tlog\link.command.1.tlog
18 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\debug\ddr_stable.tlog\link.read.1.tlog
19 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\debug\ddr_stable.tlog\link.write.1.tlog
20 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Debug/ddr_stable.dll.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | C:\tools\dev\git\DynDataResolver\ddr_client\Debug\ddr_stable.dll
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Debug/ddr_stable.log:
--------------------------------------------------------------------------------
1 | ddr_helper_functions.c
2 | dump_buffer1.c
3 | main.c
4 | patch_exe.c
5 | trace_instr.c
6 | Generating Code...
7 | ddr_stable.vcxproj -> C:\tools\dev\git\DynDataResolver\ddr_client\Debug\ddr_stable.dll
8 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Debug/ddr_stable.tlog/CL.command.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Debug/ddr_stable.tlog/CL.command.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Debug/ddr_stable.tlog/CL.read.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Debug/ddr_stable.tlog/CL.read.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Debug/ddr_stable.tlog/CL.write.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Debug/ddr_stable.tlog/CL.write.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Debug/ddr_stable.tlog/ddr_stable.lastbuildstate:
--------------------------------------------------------------------------------
1 | PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.28.29333:TargetPlatformVersion=10.0.18362.0:
2 | Debug|Win32|C:\tools\dev\git\DynDataResolver\ddr_client\|
3 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Debug/ddr_stable.tlog/ddr_stable.write.1u.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Debug/ddr_stable.tlog/ddr_stable.write.1u.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Debug/ddr_stable.tlog/link.command.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Debug/ddr_stable.tlog/link.command.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Debug/ddr_stable.tlog/link.read.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Debug/ddr_stable.tlog/link.read.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Debug/ddr_stable.tlog/link.write.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Debug/ddr_stable.tlog/link.write.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Debug/ddr_stable.vcxproj.FileListAbsolute.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Debug/ddr_stable.vcxproj.FileListAbsolute.txt
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Debug/dump_buffer1.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Debug/dump_buffer1.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Debug/main.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Debug/main.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Debug/patch_exe.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Debug/patch_exe.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Debug/trace_instr.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Debug/trace_instr.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Debug/vc142.idb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Debug/vc142.idb
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Debug/vc142.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Debug/vc142.pdb
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/DynRio_debug_x32_PropertySheet.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | C:\tools\dev\git\dynamorioX32_dbg\build\ext\include;C:\tools\dev\git\dynamorioX32_dbg\build\include;%(AdditionalIncludeDirectories)
9 | true
10 |
11 | WINDOWS;X86_32;WIN32;_DEBUG;DDRSTABLE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
12 | false
13 | Level3
14 | true
15 | true
16 | MultiThreadedDebug
17 |
18 |
19 | C:\tools\dev\git\dynamorioX32_dbg\build\lib32\debug;C:\tools\dev\git\dynamorioX32_dbg\build\lib32;C:\tools\dev\git\dynamorioX32_dbg\build\ext\lib32\debug;C:\tools\dev\git\dynamorioX32_dbg\build\lib32\debug;%(AdditionalLibraryDirectories)
20 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;dynamorio.lib;drmgr.lib;drreg.lib;drx.lib;drsyms.lib;drcontainers.lib;ntdll_imports.lib;drwrap.lib;%(AdditionalDependencies)
21 | DebugFull
22 | false
23 | false
24 | Windows
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/DynRio_debug_x64_PropertySheet.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | C:\tools\dev\git\dynamorioX64_dbg\build\ext\include;C:\tools\dev\git\dynamorioX64_dbg\build\include;%(AdditionalIncludeDirectories)
9 |
10 |
11 |
12 |
13 | true
14 |
15 |
16 |
17 |
18 | WINDOWS;X86_64;_WINDLL;X86_64;_DEBUG;DDRSTABLE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
19 |
20 |
21 |
22 |
23 | false
24 |
25 |
26 |
27 |
28 | true
29 |
30 |
31 |
32 |
33 | true
34 | Level3
35 |
36 | MultiThreadedDebug
37 |
38 |
39 | C:\tools\dev\git\dynamorioX64_dbg\build\lib64\debug;C:\tools\dev\git\dynamorioX64_dbg\build\lib64;C:\tools\dev\git\dynamorioX64_dbg\build\ext\lib64\debug;C:\tools\dev\git\dynamorioX64_dbg\build\lib64\debug;%(AdditionalLibraryDirectories)
40 |
41 |
42 | dynamorio.lib;drmgr.lib;drreg.lib;drx.lib;drsyms.lib;drcontainers.lib;ntdll_imports.lib;drwrap.lib;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)
43 |
44 |
45 | false
46 |
47 |
48 | DebugFull
49 |
50 |
51 | Windows
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/DynRio_release_x64_PropertySheet.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | C:\tools\dev\git\dynamorioX64\build\ext\include;C:\tools\dev\git\dynamorioX64\build\include;%(AdditionalIncludeDirectories)
9 | Level3
10 | true
11 | WINDOWS;X86_64;%(PreprocessorDefinitions)
12 | MultiThreaded
13 | false
14 | true
15 |
16 |
17 | C:\tools\dev\git\dynamorioX64\build\lib64;C:\tools\dev\git\dynamorioX64\build\ext\lib64\release;C:\tools\dev\git\dynamorioX64\build\lib64\release;%(AdditionalLibraryDirectories)
18 |
19 |
20 | dynamorio.lib;drmgr.lib;drreg.lib;drx.lib;drsyms.lib;drcontainers.lib;ntdll_imports.lib;drwrap.lib;%(AdditionalDependencies)
21 |
22 |
23 | true
24 |
25 |
26 | true
27 |
28 |
29 | /FORCE:MULTIPLE %(AdditionalOptions)
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/DynRio_release_x86_PropertySheet.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | C:\tools\dev\git\dynamorioX32\build\lib32;C:\tools\dev\git\dynamorioX32\build\ext\lib32\release;C:\tools\dev\git\dynamorioX32\build\lib32\release;%(AdditionalLibraryDirectories)
9 | dynamorio.lib;drmgr.lib;drreg.lib;drx.lib;drsyms.lib;drcontainers.lib;ntdll_imports.lib;drwrap.lib;
10 | true
11 | true
12 |
13 |
14 | C:\tools\dev\git\dynamorioX32\build\ext\include;C:\tools\dev\git\dynamorioX32\build\include;%(AdditionalIncludeDirectories)
15 |
16 |
17 | Level3
18 |
19 |
20 | true
21 |
22 |
23 | WINDOWS;X86_32;%(PreprocessorDefinitions)
24 |
25 |
26 | MultiThreaded
27 |
28 |
29 | false
30 |
31 |
32 | true
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Release/ddr_helper_functions.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Release/ddr_helper_functions.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Release/ddr_stable.Build.CppClean.log:
--------------------------------------------------------------------------------
1 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\release\vc142.pdb
2 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\release\trace_instr.obj
3 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\release\patch_exe.obj
4 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\release\main.obj
5 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\release\dump_buffer1.obj
6 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\release\ddr_helper_functions.obj
7 | c:\tools\dev\git\dyndataresolver\ddr_client\release\ddr_stable.lib
8 | c:\tools\dev\git\dyndataresolver\ddr_client\release\ddr_stable.exp
9 | c:\tools\dev\git\dyndataresolver\ddr_client\release\ddr_stable.ipdb
10 | c:\tools\dev\git\dyndataresolver\ddr_client\release\ddr_stable.iobj
11 | c:\tools\dev\git\dyndataresolver\ddr_client\release\ddr_stable.dll
12 | c:\tools\dev\git\dyndataresolver\ddr_client\release\ddr_stable.pdb
13 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\release\ddr_stable.tlog\cl.command.1.tlog
14 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\release\ddr_stable.tlog\cl.read.1.tlog
15 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\release\ddr_stable.tlog\cl.write.1.tlog
16 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\release\ddr_stable.tlog\ddr_stable.write.1u.tlog
17 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\release\ddr_stable.tlog\link.command.1.tlog
18 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\release\ddr_stable.tlog\link.read.1.tlog
19 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\release\ddr_stable.tlog\link.write.1.tlog
20 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Release/ddr_stable.dll.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | C:\tools\dev\git\DynDataResolver\ddr_client\Release\ddr_stable.dll
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Release/ddr_stable.log:
--------------------------------------------------------------------------------
1 | ddr_helper_functions.c
2 | dump_buffer1.c
3 | main.c
4 | patch_exe.c
5 | trace_instr.c
6 | Creating library C:\tools\dev\git\DynDataResolver\ddr_client\Release\ddr_stable.lib and object C:\tools\dev\git\DynDataResolver\ddr_client\Release\ddr_stable.exp
7 | Generating code
8 | 11 of 56 functions (19.6%) were compiled, the rest were copied from previous compilation.
9 | 3 functions were new in current compilation
10 | 2 functions had inline decision re-evaluated but remain unchanged
11 | Finished generating code
12 | ddr_stable.vcxproj -> C:\tools\dev\git\DynDataResolver\ddr_client\Release\ddr_stable.dll
13 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Release/ddr_stable.tlog/CL.command.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Release/ddr_stable.tlog/CL.command.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Release/ddr_stable.tlog/CL.read.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Release/ddr_stable.tlog/CL.read.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Release/ddr_stable.tlog/CL.write.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Release/ddr_stable.tlog/CL.write.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Release/ddr_stable.tlog/ddr_stable.lastbuildstate:
--------------------------------------------------------------------------------
1 | PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.28.29333:TargetPlatformVersion=10.0.18362.0:
2 | Release|Win32|C:\tools\dev\git\DynDataResolver\ddr_client\|
3 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Release/ddr_stable.tlog/ddr_stable.write.1u.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Release/ddr_stable.tlog/ddr_stable.write.1u.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Release/ddr_stable.tlog/link.command.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Release/ddr_stable.tlog/link.command.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Release/ddr_stable.tlog/link.read.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Release/ddr_stable.tlog/link.read.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Release/ddr_stable.tlog/link.write.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Release/ddr_stable.tlog/link.write.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Release/ddr_stable.vcxproj.FileListAbsolute.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Release/ddr_stable.vcxproj.FileListAbsolute.txt
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Release/dump_buffer1.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Release/dump_buffer1.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Release/main.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Release/main.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Release/patch_exe.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Release/patch_exe.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Release/trace_instr.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Release/trace_instr.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/Release/vc142.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/Release/vc142.pdb
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/ddr.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "dr_api.h"
3 | #include "drmgr.h"
4 | //#include "utils.h"
5 | #include "drreg.h"
6 | #include "drx.h"
7 | #include "drwrap.h"
8 | #include "dr_tools.h"
9 | #include "dr_ir_opnd.h"
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | // --- Defines ---
21 | #define DDR_VERSION "1.02 beta"
22 |
23 | #define CmdOpt_NormalTrace 1
24 | #define CmdOpt_DumpBuffer 2
25 | #define CmdOpt_Patch_EFLAG 4
26 | #define CmdOpt_Patch_NOP 8
27 | #define CmdOpt_Patch_CALL 16
28 | #define CmdOpt_Patch_Loop 32
29 |
30 | #ifdef X86_64
31 | #define PATCH_ADDR_SIZE 16
32 | #else
33 | #define PATCH_ADDR_SIZE 8
34 | #endif
35 |
36 | #define MAX_DUMP_FILENAME 256
37 | #define MAX_TRACE_FILENAME 256
38 | #define MAX_OP_PARA_LEN 3
39 | #define MAX_FILE_LINE_LEN 356
40 | #define MAX_CFG_LINE 350
41 | #define MAX_PROCESSES 255
42 | #define MAX_PROCESSNAME 255
43 | #define MAX_SEC_TO_WAIT_FOR_PROCS 20
44 |
45 | #define CF 5862190
46 | #define PF 5862619
47 | #define AF 5862124
48 | #define ZF 5862949
49 | #define SF 5862718
50 | #define DF 5862223
51 | #define OF 5862586
52 | #define FILENAME_OPT 2089071269
53 |
54 | #define MAX_INSTR_COUNT 100000 // max. number of instructions to trace
55 | #define MAX_NUM_DSTS_OP 9 // BUG workaround - TBD Fixed, will remove this after some final checks (popa = 8 DST_OP)
56 | #define MAX_NUM_SRCS_OP 9 // BUG workaround - TBD Fixed, will remove this after some final checks (pusha = 8 DST_OP)
57 |
58 | #ifdef _DEBUG
59 | #define debug_print(fmt, ...) \
60 | do { dr_printf("[DDR] [DEBUG] %s:%d:%s(): " fmt, __FILE__, __LINE__, __func__, __VA_ARGS__); } while (0)
61 | #else
62 | #define debug_print(...)
63 | #endif
64 |
65 |
66 | // --- Typedefs ---
67 | typedef struct p_eflag_para {
68 | unsigned char* patch_eflag_flag_str;
69 | reg_t patch_eflag_flag;
70 | size_t patch_eflag_PC;
71 | struct p_eflag_para* nextpe;
72 | } P_EFLAG_PARA;
73 |
74 | typedef struct p_nop_para {
75 | size_t patch_nop_start_PC;
76 | size_t patch_nop_end_PC;
77 | struct p_nop_para* nextpa;
78 | } P_NOP_PARA;
79 |
80 | typedef struct p_call_para {
81 | size_t patch_call_func_PC;
82 | size_t patch_call_ret;
83 | struct p_call_para* nextcp;
84 | } P_CALL_PARA;
85 |
86 | typedef struct s_dump_para {
87 | size_t bufferPC;
88 | char* bufferOp;
89 | int bufferOpnum;
90 | char bufferOptype;
91 | char bufferOptypePtrType;
92 |
93 | size_t sizePC;
94 | char* sizeOp;
95 | int sizeOpnum;
96 | char sizeOptype;
97 | char sizeOptypePtrType;
98 |
99 | size_t dumpPC;
100 | char* filename;
101 | struct s_dump_para* nextdp;
102 | } S_DUMP_PARA;
103 |
104 | typedef struct s_trace_para {
105 | size_t start;
106 | size_t end;
107 | size_t max_instr;
108 | bool light_trace_only;
109 | char* filename;
110 | file_t fpTracefile;
111 | struct s_trace_para* nexttr;
112 | } S_TRACE_PARA;
113 |
114 | typedef struct s_pListThreads {
115 | struct s_pListThreads* prevproc;
116 | process_id_t start_process_id;
117 | process_id_t process_id;
118 | thread_id_t threat_id;
119 | struct s_pListThreads* nextproc;
120 | } S_PROCS;
121 |
122 |
123 | // --- Functions prototypes ---
124 |
125 | // main
126 | DR_EXPORT void dr_client_main(client_id_t id, int argc, const char* argv[]);
127 | int parse_cmd_opt();
128 | void event_exit(void);
129 | bool parse_loop_line(char* line, unsigned int linenr);
130 | bool parse_startaddr_line(char* line, unsigned int linenr);
131 | bool parse_breakaddr_line(char* line, unsigned int linenr);
132 | bool parse_cfgfile(char* filename);
133 | bool parse_patch_flag_line(char* line);
134 | bool parse_patch_nop_line(char* line);
135 | bool parse_patch_call_line(char* line);
136 | bool parse_dump_buffer_line(char* line, unsigned int linenr);
137 | bool parse_trace_line(char* line, unsigned int linenr);
138 |
139 | // ddr_helper_functions
140 | void usage();
141 | bool CheckFileExists(const CHAR* fileName);
142 | char* getSubstr(char* str, char* p1, char* p2);
143 | char* escape_filename(char* filename);
144 | int escape_dir_str(char* dirStr);
145 | bool getOEPfromPEfile(char* pefile, app_pc* oep);
146 | void __cdecl print_disasm(void* drcontext, app_pc instr_addr, size_t instr_addr_fixed);
147 | unsigned long djb2_hash(unsigned char* str);
148 | unsigned char* strtoupper(unsigned char* t);
149 | void check_strlen(char* str, size_t maxlen, char* failmsg, unsigned int linenr);
150 | bool fix_comma_in_jsonfile(char* fname);
151 | app_pc my_opnd_compute_address(opnd_t opnd, dr_mcontext_t* mc);
152 | bool my_opnd_is_reg(opnd_t opnd);
153 | int IncProcCounter();
154 | int DecProcCounter();
155 | int GetProcCounter();
156 | process_id_t* getSharedProcessIDs(process_id_t* pProcessids);
157 | char* getSharedProcessNames(char* pProcessnames);
158 | char* getLogFilePath(char* fullpath, char* dir);
159 | char* getSharedLogpath(char* pLogpath);
160 |
161 | // trace_instr
162 | void event_module_load_trace_instr(void* drcontext, const module_data_t* info, bool loaded);
163 | void event_thread_init_trace_instr(void* drcontext);
164 | void event_thread_exit_trace_instr(void* drcontext);
165 | //void __cdecl process_instr_trace_instr(app_pc instr_addr);
166 | void __cdecl process_instr_trace_instr_new(app_pc instr_addr, S_TRACE_PARA* tr);
167 | static void iterate_exports_trace_instr(const module_data_t* info);
168 | static bool lib_is_not_blacklisted_trace_instr(const module_data_t* info);
169 | static unsigned char* get_byte_string_trace_instr(unsigned char* bytesbuf, size_t bytesread, size_t* resultstr_size);
170 | static void log_bytestream_trace_instr(file_t f, unsigned char* bytesbuf, size_t bytesread, app_pc memaddr, uint instr_mem_size);
171 | static bool write_mem_data_trace_instr(file_t f, size_t numbytes, app_pc memaddr, char* json_field_str);
172 | static bool write_mem_to_file_trace_instr(file_t f, ssize_t numbytes, app_pc memaddr);
173 | static void write_src_op_to_logfile_trace_instr(file_t f, instr_t* instr, app_pc memaddr_src0, size_t bytesread, size_t numbytes);
174 | static void log_instr_opnds_trace_instr(file_t f, instr_t* instr, dr_mcontext_t* mc, void* drcontext, size_t numbytes);
175 | static void log_mem_at_reg_trace_instr(app_pc memaddr, char* regstr, file_t f);
176 | static void handler_instr_is_return(file_t f, instr_t* instr, dr_mcontext_t* mc, size_t numbytes);
177 | static void handler_instr_is_call(file_t f, instr_t* instr, dr_mcontext_t* mc, size_t numbytes);
178 | static void handler_instr_is_pop(file_t f, instr_t* instr, dr_mcontext_t* mc, size_t numbytes);
179 | static void handler_instr_interesting_instr(file_t f, instr_t* instr, dr_mcontext_t* mc, size_t numbytes);
180 | static void handler_all_other_mem_instr(file_t f, instr_t* instr, dr_mcontext_t* mc, size_t numbytes);
181 |
182 | // dump_buffer
183 | void my_call_pre_wrapper(void* wrapcxt, OUT void** user_data);
184 | void event_thread_init_global(void* drcontext);
185 | int __cdecl get_mem_addr_dump_buffer(void* drcontext, reg_t* memaddr, char Optype, char OptypePtrType, int Opnum, app_pc instr_addr, dr_mcontext_t mc);
186 | int __cdecl get_op_size_dump_buffer(void* drcontext, reg_t* memaddr, char Optype, char OptypePtrType, int Opnum, app_pc instr_addr, dr_mcontext_t mc);
187 | dr_emit_flags_t event_bb_instr_global(void* drcontext, void* tag, instrlist_t* bb, instr_t* instr, bool for_trace, bool translating, void* user_data);
188 | void __cdecl process_instr_size_dump_buffer(app_pc instr_addr, S_DUMP_PARA* dp);
189 | void __cdecl process_instr_addr_dump_buffer(app_pc instr_addr, S_DUMP_PARA* dp);
190 | void __cdecl process_instr_dump_buffer(app_pc instr_addr, S_DUMP_PARA* dp);
191 |
192 | // patch_exe
193 | void __cdecl patch_eflag(app_pc instr_addr, P_EFLAG_PARA* pp);
194 | void __cdecl patch_sleep(app_pc instr_addr);
195 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/ddr_config.txt:
--------------------------------------------------------------------------------
1 | # --- DDR sample config file ---
2 | #
3 | # Lines should not be more than 80 characters long
4 | # 3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
5 | #
6 | # Comments must be written with a leading '#'
7 | # No extra spaces are allowed in config lines
8 | # Different fields are separated by exactly one blank
9 | #
10 | # All number/address values are expected to be hexadecimal values without any
11 | # leading character.
12 | # -----------------------------------------------------------------------------
13 |
14 | # -- NOP out instructions --
15 | # N
16 | # = Start program counter address for NOP'ing instructions (hex)
17 | # = End program counter address for NOP'ing instructions (hex)
18 | # and can be the same for NOP'ing one instr.
19 | # e.g. N 004012EE 004012F6
20 | #N 0040115A 0040115A
21 | #N 00401337 0040133A
22 |
23 | # -- Patch EFLAG --
24 | # T
25 | # = [CF, PF, AF, ZF, SF, DF, OF]
26 | # = program counter address (hex) where to toggle the EFLAG before
27 | # instruction gets executed e.g. jle
28 | # e.g. T SF 004012C4 #example comment
29 | #T SF 004012BB
30 | #T SF 004012FB #example comment
31 |
32 | # -- Always skip function at when called --
33 | # = Functions address which gets wrapped, call to func is skipped
34 | # = set return value of wrapped function (NEED TO BE UNSINGED INT)
35 | # C
36 | # e.g. C 00401100 00000001
37 | C 00401120 FFFFFFFF # = -1
38 | C 00401150 FF
39 |
40 | # -- Dump buffer to file --:
41 | # D
42 | # = program counter address where to get the size of the buffer
43 | # = operant at to get the buffer size from
44 | # e.g. SP0 = (S)ource operant 0. Value is a (P)ointer.
45 | # DV1 = (D)estination operant 1. Absolut (V)alue.
46 | # = program counter address where to get the buffer address
47 | # = operant at PC to get the buffer size from
48 | # = program counter address where to finally dump the buffer
49 | # = dump filename
50 | #
51 | # All numbers/addresses are hexdecimal values without any leading character
52 | #
53 | # e.g. D 0040117E SP0 0040118B SP0 004011F9 dump1.bin
54 | #D 004011B5 SP0 004011C2 SP0 00401230 dump1.bin
55 | #D 004013A2 SP0 004013AF SP0 0040141D dump2.bin
56 | #
57 | # -- Run Trace --:
58 | # start end max.instr breakaddr lighttrace filename (the last in the list will be used)
59 | L 4012BE 40130F 20000 na TRUE "C:\Users\Dex Dexter\Documents\test\test\buffertest_trace.json"
60 | L 401335 4013CA 20000 na TRUE "C:\Users\Dex Dexter\Documents\test\test\buffertest_trace.json"
61 | L 401411 40146E 20000 na TRUE "C:\Users\Dex Dexter\Documents\test\test\buffertest_trace.json"
62 |
63 | # -- Patch binary with endless Loop at address --:
64 | # loop-addr
65 | B 40170C
66 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/ddr_config64.txt:
--------------------------------------------------------------------------------
1 | # --- DDR sample config file ---
2 | #
3 | # Lines should not be more than 80 characters long
4 | # 3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
5 | #
6 | # Comments must be written with a leading '#'
7 | # No extra spaces are allowed in config lines
8 | # Different fields are separated by exactly one blank
9 |
10 | All number/address values are expected to be hexadecimal values without any
11 | leading character.
12 | # -----------------------------------------------------------------------------
13 |
14 | # -- NOP out instructions --
15 | # N
16 | # = Start program counter address for NOP'ing instructions (hex)
17 | # = End program counter address for NOP'ing instructions (hex)
18 | # and can be the same for NOP'ing one instr.
19 | # e.g. N 004012EE 004012F6
20 | N 000000014000121C 000000014000121C
21 | N 000000014000145A 000000014000145A
22 |
23 | # -- Patch EFLAG --
24 | # T
25 | # = [CF, PF, AF, ZF, SF, DF, OF]
26 | # = program counter address where to toggle the EFLAG before
27 | # instruction gets executed e.g. jle (hex)
28 | # e.g. T SF 004012C4 #example comment
29 | T SF 00000001400013A7
30 | T SF 00000001400013E5 #example comment
31 |
32 | # -- Always skip function at when called --
33 | # = Functions address which gets wrapped, call to func is skipped
34 | # = set return value of wrapped function (NEED TO BE UNSINGED INT)
35 | # C
36 | # e.g. C 00401100 00000001
37 | C 00000001400011E0 0
38 | C 0000000140001210 FFFFFFFFFFFFFFFF # -1
39 |
40 | # -- Dump buffer to file --:
41 | # D
42 | # = program counter address where to get the size of the buffer
43 | # = operant at to get the buffer size from
44 | # e.g. SP0 = (S)ource operant 0. Value is a (P)ointer.
45 | # DV1 = (D)estination operant 1. Absolut (V)alue.
46 | # = program counter address where to get the buffer address
47 | # = operant at PC to get the buffer size from
48 | # = program counter address where to finally dump the buffer
49 | # = dump filename
50 | # e.g. D 0040117E SP0 0040118B SP0 004011F9 dump1.bin
51 | D 0000000140001280 SP0 000000014000128D SP0 000000014000132B dump_x64_1.bin
52 | D 0000000140001494 SP0 00000001400014A1 SP0 000000014000153F dump_x64_2.bin
53 | #
54 | # -- Run Trace --:
55 | # start end max.instr breakaddr lighttrace filename (the last in the list will be used)
56 | L 140001000 140003000 20000 na FALSE trace_tmp_CBEFF9E003C9FA8D8C568CFB85A885AF.json
57 | #
58 | # -- Patch binary with endless Loop at address --:
59 | # loop-addr
60 | B 0000000140001280
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/ddr_helper_functions.c:
--------------------------------------------------------------------------------
1 | #include "ddr.h"
2 | #include "globals.h"
3 |
4 | void usage()
5 | {
6 | // -no_follow_children drrun does not follow into any child processes
7 | dr_printf("\n");
8 | dr_printf("Usage:\n");
9 | dr_printf("drrun.exe -c -c -- \n");
10 | #ifdef _DEBUG
11 | dr_printf("-d Set verbose level for debugging. (0-5)\n");
12 | #endif
13 | dr_printf("-c Set Dump and patching configuration in \n");
14 | dr_printf(" See sample \"ddr_config.cfg\" for details\n");
15 | dr_printf(" Sample PE file to analyse\n\n");
16 | dr_printf("Examples:\n");
17 | dr_printf("C:\\DYNRIO_DIR\\bin64\\drrun.exe -c \"C:\\ddr\\ddr64.dll\" -c my_x32_config.cfg -- \"C:\\tools\\ddr\\samples\\buffertest.exe\"\n");
18 | dr_printf("C:\\DYNRIO_DIR\\bin32\\drrun.exe -c \"C:\\ddr\\ddr32.dll\" -c my_x64_config.cfg -- \"C:\\tools\\ddr\\samples\\buffertest.exe\"\n\n");
19 | }
20 |
21 | bool CheckFileExists(const CHAR* fileName)
22 | {
23 | DWORD fileAttr;
24 |
25 | fileAttr = GetFileAttributesA(fileName);
26 | if (0xFFFFFFFF == fileAttr)
27 | return false;
28 | return true;
29 | }
30 |
31 | // Get string between substring p1 and p2
32 | char* getSubstr(char* str, char* p1, char* p2)
33 | {
34 | char* ret;
35 | char* stmp1 = strstr(str, p1);
36 | char* stmp2;
37 |
38 | if (stmp1 != NULL)
39 | {
40 | size_t slen = strlen(p1);
41 | stmp2 = strstr(stmp1 + slen, p2);
42 | if (p2 != NULL)
43 | {
44 | size_t mlen = stmp2 - stmp1;
45 | if (mlen > 1) {
46 | ret = dr_global_alloc(mlen);
47 | if (ret != NULL)
48 | {
49 | memcpy(ret, stmp1 + 1, mlen - 1);
50 | ret[mlen - 1] = '\0';
51 | return ret;
52 | }
53 | }
54 | }
55 | }
56 | return NULL;
57 | }
58 |
59 | char* escape_filename(char* filename) {
60 | // --- TBD ---
61 | return filename;
62 | }
63 |
64 | int escape_dir_str(char* dirStr)
65 | {
66 | int count;
67 | size_t SearchStrLen;
68 | size_t ReplaceStrLen;
69 | char* sp;
70 | const char* search = "\\";
71 | const char* replace = "\\\\";
72 |
73 | if ((sp = strstr(dirStr, search)) == NULL) {
74 | return(0);
75 | }
76 | count = 1;
77 | SearchStrLen = strlen(search);
78 | ReplaceStrLen = strlen(replace);
79 | if (SearchStrLen > ReplaceStrLen) {
80 | char* src = sp + SearchStrLen;
81 | char* dst = sp + ReplaceStrLen;
82 | while ((*dst = *src) != '\0') { dst++; src++; }
83 | }
84 | else if (SearchStrLen < ReplaceStrLen) {
85 | size_t tmpLen = strlen(sp) - SearchStrLen;
86 | char* stop = sp + ReplaceStrLen;
87 | char* src = sp + SearchStrLen + tmpLen;
88 | char* dst = sp + ReplaceStrLen + tmpLen;
89 | while (dst >= stop) { *dst = *src; dst--; src--; }
90 | }
91 | memcpy(sp, replace, ReplaceStrLen);
92 |
93 | //interate through string
94 | count += escape_dir_str(sp + ReplaceStrLen);
95 |
96 | return(count);
97 | }
98 |
99 | bool getOEPfromPEfile(char* pefile, app_pc* oep) {
100 |
101 | FILE* fp;
102 | errno_t err;
103 | err = fopen_s(&fp, pefile, "rb");
104 | if (err != 0) {
105 | dr_printf("[DDR] [ERROR] Failed opening PE file\n", pefile);
106 | return FALSE;
107 | }
108 | if (fp != NULL) {
109 | fseek(fp, 0, SEEK_SET);
110 | }
111 | else {
112 | dr_printf("[DDR] [ERROR] Failed opening PE file. File pointer invalid.\n", pefile);
113 | return FALSE;
114 | }
115 |
116 | IMAGE_DOS_HEADER imgDosHdr;
117 | fread(&imgDosHdr, sizeof(IMAGE_DOS_HEADER), 1, fp);
118 |
119 | fseek(fp, imgDosHdr.e_lfanew, SEEK_SET);
120 | IMAGE_NT_HEADERS imgNtHdr;
121 | fread(&imgNtHdr, sizeof(IMAGE_NT_HEADERS), 1, fp);
122 |
123 | *oep = (app_pc)(imgNtHdr.OptionalHeader.ImageBase + imgNtHdr.OptionalHeader.AddressOfEntryPoint);
124 |
125 | fclose(fp);
126 | return TRUE;
127 | }
128 |
129 | void __cdecl print_disasm(void* drcontext, app_pc instr_addr, size_t instr_addr_fixed) {
130 | byte* pc;
131 | instr_t instr;
132 | instr_init(drcontext, &instr);
133 | instr_reset(drcontext, &instr);
134 | pc = decode(drcontext, instr_addr, &instr); // fill in instr
135 |
136 | size_t disasm_buf_size = 254;
137 | unsigned char* disasm_buf = (unsigned char*)dr_global_alloc(sizeof(unsigned char) * disasm_buf_size);
138 | instr_disassemble_to_buffer(dr_get_current_drcontext(), &instr, disasm_buf, disasm_buf_size);
139 | dr_printf("[DDR] [INFO] Disasm(PC 0x%x): %s\n", instr_addr_fixed, disasm_buf);
140 | dr_global_free(disasm_buf, sizeof(unsigned char) * disasm_buf_size);
141 | instr_free(drcontext, &instr);
142 | }
143 |
144 | unsigned long djb2_hash(unsigned char* str) {
145 | unsigned long hash = 5381;
146 | int c;
147 |
148 | while (c = *str++)
149 | hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
150 |
151 | return hash;
152 | }
153 |
154 | unsigned char* strtoupper(unsigned char* s) {
155 | char* t = s;
156 | while (*s) {
157 | *s = toupper(*s);
158 | s++;
159 | }
160 | return t;
161 | }
162 |
163 | void check_strlen(char* str, size_t maxlen, char* failmsg, unsigned int linenr) {
164 | if (strlen(str) > maxlen) {
165 | dr_printf("[DDR] [ERROR] %s. Max. length is %d for this field in Line %d.\n", failmsg, maxlen, linenr);
166 | usage();
167 | dr_exit_process(1);
168 | }
169 | }
170 |
171 | bool fix_comma_in_jsonfile(char *fname) {
172 | // Checking for a wrong set comma at the end of the last block in the JSON file
173 | file_t f;
174 | bool ret = false;
175 | uint64 fsize = 0;
176 | char* buf;
177 | size_t buf_len;
178 | ssize_t i;
179 | bool c_bracket = false;
180 | bool s_bracket = false;
181 | bool next_c_bracket = false;
182 |
183 | dr_printf("[DDR] [INFO] Fixing file: %s\n", fname);
184 |
185 | f = dr_open_file(fname, DR_FILE_READ);
186 | if (f == INVALID_FILE) {
187 | dr_printf("[DDR] [ERROR] Can't open instruction log file for reading.\n");
188 | dr_printf("[DDR] [ERROR] Filename: '%s'\n", fname);
189 | dr_exit_process(1);
190 | }
191 |
192 | dr_file_size(f, &fsize);
193 | if (fsize > UINT_MAX) {
194 | dr_printf("[DDR] [WARNING] Can't cleanup JSON file. File is too big. Filesize is %.0lf\n", fsize);
195 | }
196 | else {
197 | buf_len = (size_t)fsize;
198 | buf = dr_global_alloc(sizeof(char) * buf_len);
199 | ssize_t n = dr_read_file(f, buf, buf_len);
200 | dr_close_file(f);
201 |
202 | for (i = n; i > n - 12; i--) {
203 | if (buf[i] == '}') {
204 | c_bracket = true;
205 | }
206 | if (buf[i] == ']' && c_bracket) {
207 | s_bracket = true;
208 | }
209 | if (buf[i] == ',' && s_bracket) {
210 | buf[i] = ' ';
211 | dr_printf("[DDR] [INFO] Fixed comma at the end of JSON file.\n");
212 | break;
213 | }
214 | if (buf[i] == '}' && s_bracket) {
215 | dr_printf("[DDR] [INFO] JSON file is ok, no comma at the end found.\n");
216 | break;
217 | }
218 | }
219 | dr_printf("[DDR] [INFO] Opening file: %s for writing\n", fname);
220 | f = dr_open_file(fname, DR_FILE_WRITE_OVERWRITE);
221 | if (f == INVALID_FILE) {
222 | dr_printf("[DDR] [ERROR] Can't open file for writing.\n");
223 | dr_printf("[DDR] [ERROR] Filename: '%s'\n", fname);
224 | dr_exit_process(1);
225 | }
226 | dr_printf("[DDR] [INFO] Writing fixed buffer to file: %s\n", fname);
227 | n = dr_write_file(f, buf, buf_len);
228 | if (buf_len != n) {
229 | dr_printf("[DDR] [WARNING] Org. JSON file (%d) and fixed JSON file (%d) have a different length. \n", buf_len, n);
230 | }
231 | else {
232 | ret = true;
233 | }
234 |
235 | dr_close_file(f);
236 | dr_printf("[DDR] [INFO] Done. Final logfile %s written. Length: %d bytes.\n", fname, n);
237 |
238 | dr_global_free(buf, sizeof(char) * buf_len);
239 | }
240 |
241 | return ret;
242 | }
243 |
244 | app_pc my_opnd_compute_address(opnd_t opnd, dr_mcontext_t* mc) {
245 | // Wrapper to opnd_compute_address that verifies that opnd is a memory reference
246 | app_pc pc;
247 |
248 | if (opnd_is_memory_reference(opnd)) {
249 | pc = opnd_compute_address(opnd, mc);
250 | }
251 | else {
252 | pc = 0;
253 | }
254 |
255 | return pc;
256 | }
257 |
258 | bool my_opnd_is_reg(opnd_t opnd) {
259 | // Wrapper to opnd_is_reg that verifies the operant is a register
260 |
261 | reg_id_t reg = 0;
262 | void* drcontext;
263 |
264 | if (opnd_is_reg(opnd)) {
265 | if (reg = opnd_get_reg(opnd)) {
266 | drcontext = dr_get_current_drcontext();
267 | dr_mcontext_t mc = { sizeof(mc),DR_MC_ALL };
268 | dr_get_mcontext(drcontext, &mc);
269 | if (reg_is_xmm(reg)) {
270 | #ifdef _DEBUG
271 | dr_printf("[DDR] [DEBUG] Operant is XMM Register this is not supported in the moment\n");
272 | #endif
273 | return FALSE;
274 | }
275 | }
276 | return TRUE;
277 | }
278 | return FALSE;
279 | }
280 |
281 | int IncProcCounter() {
282 | // Initalize or increase process counter and return number of running processes launched by the sample
283 |
284 | HANDLE hMapFile;
285 | int Counter;
286 | int* pCounter = &Counter;
287 |
288 | hMapFile = OpenFileMapping(
289 | FILE_MAP_ALL_ACCESS, // read/write access
290 | FALSE, // do not inherit the name
291 | szName); // name of mapping object
292 |
293 | if (hMapFile == NULL) {
294 | debug_print("First instance.\n");
295 |
296 | Counter = 1;
297 |
298 | hMapFile = CreateFileMapping(
299 | INVALID_HANDLE_VALUE, // use paging file
300 | NULL, // default security
301 | PAGE_READWRITE, // read/write access
302 | 0, // maximum object size (high-order DWORD)
303 | sizeof(unsigned int), // maximum object size (low-order DWORD)
304 | szName); // name of mapping object
305 |
306 | if (hMapFile == NULL) {
307 | dr_printf("[DDR] [ERROR] [%s:%d] Could not create file mapping object (%d).\n", GetLastError(), __FILE__, __LINE__);
308 | return -1;
309 | }
310 | pCounter = (unsigned int*)MapViewOfFile(hMapFile, // handle to map object
311 | FILE_MAP_ALL_ACCESS, // read/write permission
312 | 0,
313 | 0,
314 | sizeof(unsigned int));
315 |
316 | if (pCounter == NULL) {
317 | dr_printf("[DDR] [ERROR] [%s:%d] Could not map view of file (%d).\n", GetLastError(), __FILE__, __LINE__);
318 | CloseHandle(hMapFile);
319 | return -1;
320 | }
321 |
322 | CopyMemory((PVOID)pCounter, &Counter, sizeof(unsigned int));
323 |
324 | debug_print("process counter = %u.\n", Counter);
325 |
326 | //UnmapViewOfFile(pBuf); TBD: unmap file after last process.
327 | //CloseHandle(hMapFile);
328 |
329 | return Counter;
330 | }
331 | else {
332 | debug_print("Not the first process.\n");
333 |
334 | pCounter = (unsigned int*)MapViewOfFile(hMapFile,
335 | FILE_MAP_ALL_ACCESS,
336 | 0,
337 | 0,
338 | sizeof(unsigned int));
339 |
340 | if (pCounter == NULL) {
341 | dr_printf("[DDR] [ERROR] [%s:%d] Could not map view of file (%d).\n",GetLastError(), __FILE__, __LINE__);
342 | CloseHandle(hMapFile);
343 | return -1;
344 | }
345 |
346 | Counter = ++(*pCounter);
347 | debug_print("Increased process counter = %u.\n", Counter);
348 |
349 | return Counter;
350 | }
351 | }
352 |
353 | int DecProcCounter() {
354 | // Decrease process counter and return number of running processes launched by the sample
355 |
356 | HANDLE hMapFile;
357 | int Counter;
358 | int* pCounter = &Counter;
359 |
360 | hMapFile = OpenFileMapping(
361 | FILE_MAP_ALL_ACCESS,
362 | FALSE,
363 | szName);
364 |
365 | if (hMapFile == NULL) {
366 | dr_printf("[DDR] [ERROR] [%s:%d] Failed to open shared object.\n", __FILE__, __LINE__);
367 | return -1;
368 | }
369 |
370 | pCounter = (int*)MapViewOfFile(hMapFile,
371 | FILE_MAP_ALL_ACCESS,
372 | 0,
373 | 0,
374 | sizeof(unsigned int));
375 |
376 | if (pCounter == NULL) {
377 | dr_printf("[DDR] [ERROR] [%s:%d] Could not map view of file (%d).\n", GetLastError(), __FILE__, __LINE__);
378 | CloseHandle(hMapFile);
379 | return -1;
380 | }
381 |
382 | Counter = --(*pCounter);
383 | debug_print("Decreased process counter = %u.\n", Counter);
384 |
385 | return Counter;
386 | }
387 |
388 | int GetProcCounter() {
389 | // Return number of launched processes by the sample
390 |
391 | HANDLE hMapFile;
392 | int Counter;
393 | int* pCounter = &Counter;
394 |
395 | hMapFile = OpenFileMapping(
396 | FILE_MAP_ALL_ACCESS,
397 | FALSE,
398 | szName);
399 |
400 | if (hMapFile == NULL) {
401 | dr_printf("[DDR] [ERROR] [%s:%d] Failed to open shared object.\n", __FILE__, __LINE__);
402 | return -1;
403 | }
404 |
405 | pCounter = (int*)MapViewOfFile(hMapFile,
406 | FILE_MAP_ALL_ACCESS,
407 | 0,
408 | 0,
409 | sizeof(unsigned int));
410 |
411 | if (pCounter == NULL) {
412 | dr_printf("[DDR] [ERROR] [%s:%d] Could not map view of file (%d).\n", GetLastError(), __FILE__, __LINE__);
413 | CloseHandle(hMapFile);
414 | return -1;
415 | }
416 |
417 | Counter = *pCounter;
418 | debug_print("process counter = %u.\n", Counter);
419 |
420 | return Counter;
421 | }
422 |
423 | process_id_t* getSharedProcessIDs(process_id_t* pProcessids) {
424 | // Return shared object pointing to Process IDs (pProcessids)
425 |
426 | HANDLE hMapFile;
427 |
428 | hMapFile = OpenFileMapping(
429 | FILE_MAP_ALL_ACCESS,
430 | FALSE,
431 | szProcIDs);
432 |
433 | if (hMapFile == NULL) {
434 | debug_print("Creating ProcessIDs shared memory.\n");
435 |
436 | hMapFile = CreateFileMapping(
437 | INVALID_HANDLE_VALUE,
438 | NULL,
439 | PAGE_READWRITE,
440 | 0,
441 | MAX_PROCESSES * sizeof(process_id_t),
442 | szProcIDs);
443 |
444 | if (hMapFile == NULL) {
445 | dr_printf("[DDR] [ERROR] [%s:%d] Could not create file mapping object (%d).\n", GetLastError(), __FILE__, __LINE__);
446 | return NULL;
447 | }
448 | pProcessids = (process_id_t*)MapViewOfFile(hMapFile,
449 | FILE_MAP_ALL_ACCESS,
450 | 0,
451 | 0,
452 | MAX_PROCESSES * sizeof(process_id_t));
453 |
454 | if (pProcessids == NULL) {
455 | dr_printf("[DDR] [ERROR] [%s:%d] Could not map view of file (%d).\n", GetLastError(), __FILE__, __LINE__);
456 | CloseHandle(hMapFile);
457 | return NULL;
458 | }
459 | return pProcessids;
460 | }
461 | else {
462 | debug_print("Not the first process.\n");
463 |
464 | pProcessids = (process_id_t*)MapViewOfFile(hMapFile,
465 | FILE_MAP_ALL_ACCESS,
466 | 0,
467 | 0,
468 | MAX_PROCESSES * sizeof(process_id_t));
469 |
470 | if (pProcessids == NULL) {
471 | dr_printf("[DDR] [ERROR] [%s:%d] Could not map view of file (%d).\n", GetLastError(), __FILE__, __LINE__);
472 | CloseHandle(hMapFile);
473 | return NULL;
474 | }
475 | return pProcessids;
476 | }
477 | }
478 |
479 | char* getSharedProcessNames(char* pProcessnames) {
480 | // Return shared object pointing to process names (pProcessnames)
481 |
482 | HANDLE hMapFile;
483 |
484 | hMapFile = OpenFileMapping(
485 | FILE_MAP_ALL_ACCESS,
486 | FALSE,
487 | szProcNames);
488 |
489 | if (hMapFile == NULL) {
490 | debug_print("Creating ProcessNames shared memory.\n");
491 |
492 | hMapFile = CreateFileMapping(
493 | INVALID_HANDLE_VALUE,
494 | NULL,
495 | PAGE_READWRITE,
496 | 0,
497 | MAX_PROCESSES * MAX_PROCESSNAME * sizeof(char),
498 | szProcNames);
499 |
500 | if (hMapFile == NULL) {
501 | dr_printf("[DDR] [ERROR] [%s:%d] Could not create file mapping object (%d).\n", GetLastError(), __FILE__, __LINE__);
502 | return NULL;
503 | }
504 | pProcessnames = (char*)MapViewOfFile(hMapFile,
505 | FILE_MAP_ALL_ACCESS,
506 | 0,
507 | 0,
508 | MAX_PROCESSES * MAX_PROCESSNAME * sizeof(char));
509 |
510 | if (pProcessnames == NULL) {
511 | dr_printf("[DDR] [ERROR] [%s:%d] Could not map view of file (%d).\n", GetLastError(), __FILE__, __LINE__);
512 | CloseHandle(hMapFile);
513 | return NULL;
514 | }
515 | return pProcessnames;
516 | }
517 | else {
518 | debug_print("Not the first process.\n");
519 |
520 | pProcessnames = (char*)MapViewOfFile(hMapFile,
521 | FILE_MAP_ALL_ACCESS,
522 | 0,
523 | 0,
524 | MAX_PROCESSES * MAX_PROCESSNAME * sizeof(char));
525 |
526 | if (pProcessnames == NULL) {
527 | dr_printf("[DDR] [ERROR] [%s:%d] Could not map view of file (%d).\n", GetLastError(), __FILE__, __LINE__);
528 | CloseHandle(hMapFile);
529 | return NULL;
530 | }
531 | return pProcessnames;
532 | }
533 | }
534 |
535 | char* getSharedLogpath(char* pLogpath) {
536 | // Return shared object pointing to plogpath
537 | // pLogpath will be the path from the sample file
538 | // pLogpath needs to be allocated by caller with min. MAX_PATH
539 |
540 | HANDLE hMapFile;
541 |
542 | hMapFile = OpenFileMapping(
543 | FILE_MAP_ALL_ACCESS,
544 | FALSE,
545 | szLogPath);
546 |
547 | if (hMapFile == NULL) {
548 | debug_print("Creating Logpath shared memory object.\n");
549 |
550 | hMapFile = CreateFileMapping(
551 | INVALID_HANDLE_VALUE,
552 | NULL,
553 | PAGE_READWRITE,
554 | 0,
555 | MAX_PATH,
556 | szLogPath);
557 |
558 | if (hMapFile == NULL) {
559 | dr_printf("[DDR] [ERROR] [%s:%d] Could not create file mapping object (%d).\n", GetLastError(), __FILE__, __LINE__);
560 | return NULL;
561 | }
562 | pLogpath = (char*)MapViewOfFile(hMapFile,
563 | FILE_MAP_ALL_ACCESS,
564 | 0,
565 | 0,
566 | MAX_PATH);
567 |
568 | if (pLogpath == NULL) {
569 | dr_printf("[DDR] [ERROR] [%s:%d] Could not map view of file (%d).\n", GetLastError(), __FILE__, __LINE__);
570 | CloseHandle(hMapFile);
571 | return NULL;
572 | }
573 |
574 | module_data_t *app = dr_get_main_module();
575 | if (getLogFilePath(app->full_path, pLogpath) == NULL) {
576 | dr_printf("[DDR] [ERROR] [%s:%d] Failed to extract global logpath from log filename\n.", __FILE__, __LINE__);
577 | dr_exit_process(1);
578 | }
579 | dr_free_module_data(app);
580 | debug_print("[FIRST PROC FIRST THREAD] Using log path %s\n", pLogpath);
581 |
582 | return pLogpath;
583 | }
584 | else {
585 | debug_print("Not the first process.\n");
586 |
587 | pLogpath = (char*)MapViewOfFile(hMapFile,
588 | FILE_MAP_ALL_ACCESS,
589 | 0,
590 | 0,
591 | MAX_PATH);
592 |
593 | if (pLogpath == NULL) {
594 | dr_printf("[DDR] [ERROR] [%s:%d] Could not map view of file (%d).\n", GetLastError(), __FILE__, __LINE__);
595 |
596 | CloseHandle(hMapFile);
597 |
598 | return NULL;
599 | }
600 | debug_print("[SUB THREAD] Using log path %s\n", pLogpath);
601 | return pLogpath;
602 | }
603 | }
604 |
605 | char* getLogFilePath(char* fullpath, char *dir) {
606 | // return path from fullpath e.g. "C:\\abc\\test.txt" -> "C:\\abc\\"
607 | // char *dir needs to allocated by caller with min. MAX_PATH
608 |
609 | errno_t e;
610 | char driveletter[3];
611 | char dirpart[MAX_PATH];
612 |
613 | e = _splitpath_s(fullpath, driveletter, 3, dirpart, MAX_PATH, NULL, 0, NULL, 0);
614 |
615 | if (e == 0) {
616 | CopyMemory((PVOID)dir, driveletter, sizeof(driveletter));
617 | CopyMemory((PVOID)(dir+2), dirpart, MAX_PATH-2);
618 | return dir;
619 | }
620 | else {
621 | return NULL;
622 | }
623 | }
624 |
625 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/ddr_stable.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | 16.0
34 | Win32Proj
35 | {6c96058e-3da0-4451-816b-2a5e2e714911}
36 | ddrstable
37 | 10.0
38 |
39 |
40 |
41 | DynamicLibrary
42 | true
43 | v142
44 | Unicode
45 |
46 |
47 | DynamicLibrary
48 | false
49 | v142
50 | true
51 | Unicode
52 |
53 |
54 | DynamicLibrary
55 | true
56 | v142
57 | Unicode
58 |
59 |
60 | DynamicLibrary
61 | false
62 | v142
63 | true
64 | Unicode
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 | %(AdditionalLibraryDirectories)
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | %(AdditionalLibraryDirectories)
110 |
111 |
112 |
113 |
114 |
115 |
116 | %(AdditionalLibraryDirectories)
117 |
118 |
119 |
120 |
121 |
122 |
123 | %(AdditionalLibraryDirectories)
124 |
125 |
126 |
127 |
128 | %(AdditionalDependencies)
129 |
130 |
131 |
132 |
133 | %(AdditionalDependencies)
134 |
135 |
136 |
137 |
138 | %(AdditionalDependencies)
139 |
140 |
141 |
142 |
143 | %(AdditionalDependencies)
144 |
145 |
146 |
147 |
148 |
149 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/ddr_stable.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Resource Files
20 |
21 |
22 | Resource Files
23 |
24 |
25 |
26 |
27 | Source Files
28 |
29 |
30 | Source Files
31 |
32 |
33 | Source Files
34 |
35 |
36 | Source Files
37 |
38 |
39 | Source Files
40 |
41 |
42 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/ddr_stable.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/dump_buffer1.c:
--------------------------------------------------------------------------------
1 | #include "ddr.h"
2 | #include "globals.h"
3 |
4 | reg_t dumpbuf_size = 0;
5 | reg_t dumpbuf_addr = 0;
6 |
7 | void my_call_pre_wrapper(void* wrapcxt, OUT void** user_data) {
8 |
9 | size_t func_addr_fixed;
10 | size_t retval = 0x666;
11 | dr_mcontext_t* mc = drwrap_get_mcontext(wrapcxt);
12 | app_pc wrapped_func = drwrap_get_func(wrapcxt);
13 |
14 | pa_call_para = pa_call_para_start;
15 | while (pa_call_para) {
16 |
17 | if (!OEP_moved_plus)
18 | func_addr_fixed = pa_call_para->patch_call_func_PC - oep_diff;
19 | else
20 | func_addr_fixed = pa_call_para->patch_call_func_PC + oep_diff;
21 |
22 | if (func_addr_fixed == (size_t) wrapped_func) {
23 | retval = pa_call_para->patch_call_ret;
24 | }
25 | pa_call_para = pa_call_para->nextcp;
26 | }
27 | pa_call_para = pa_call_para_start;
28 |
29 | drwrap_skip_call(wrapcxt, (void*)retval, 0);
30 |
31 | dr_printf("[DDR] [INFO] Wrapped function "PFX" called from "PFX".\n", wrapped_func, mc->pc);
32 | dr_printf("[DDR] [INFO] Return value set to "PFX"(signed decimal:%d)(unsigned decimal:%u)\n", retval, retval, retval);
33 | }
34 |
35 | int __cdecl get_mem_addr_dump_buffer(void* drcontext, reg_t* memaddr, char Optype, char OptypePtrType, int Opnum, app_pc instr_addr, dr_mcontext_t mc) {
36 | byte* pc;
37 | opnd_t opnd;
38 | reg_id_t reg;
39 | instr_t instr;
40 | instr_init(drcontext, &instr);
41 | instr_reset(drcontext, &instr);
42 | pc = decode(drcontext, instr_addr, &instr); // fill in instr
43 | opnd = instr_get_src(&instr, Opnum);
44 | *memaddr = 0;
45 |
46 | // Source operant
47 | if (tolower(Optype) == 's') {
48 | dr_printf("[DDR] [INFO] Getting buffer address from source operant %d.\n", Opnum);
49 | // op is register
50 | if (my_opnd_is_reg(opnd)) {
51 | reg = opnd_get_reg(opnd);
52 | *memaddr = reg_get_value(reg, &mc);
53 | //dr_printf("[DDR] [DEBUG] inst_mem_addr_reg: "PFX"\n", *memaddr);
54 | }
55 | else if (opnd_is_immed(opnd)) {
56 | *memaddr = opnd_get_immed_int(opnd);
57 | //dr_printf("[DDR] [DEBUG] inst_mem_addr_immed: "PFX"\n", *memaddr);
58 | }
59 | // op is not a register
60 | else {
61 | *memaddr = (reg_t)my_opnd_compute_address(opnd, &mc);
62 | //dr_printf("[DDR] [DEBUG] inst_mem_addr_noreg: "PFX"\n", *memaddr);
63 | }
64 | }
65 | // Destination operant
66 | else if (tolower(Optype) == 'd') {
67 | dr_printf("[DDR] [INFO] Getting buffer address from destination operant %d.\n", Opnum);
68 |
69 | opnd = instr_get_dst(&instr, Opnum);
70 |
71 | // op is register
72 | if (my_opnd_is_reg(opnd)) {
73 | reg = opnd_get_reg(opnd);
74 | *memaddr = reg_get_value(reg, &mc);
75 | //dr_printf("[DDR] [INFO] inst_mem_addr_reg: "PFX"\n", *memaddr);
76 | }
77 | else if (opnd_is_immed(opnd)) {
78 | *memaddr = opnd_get_immed_int(opnd);
79 | //dr_printf("[DDR] [INFO] inst_mem_addr_immed: "PFX"\n", *memaddr);
80 | }
81 | // op is not a register
82 | else {
83 | *memaddr = (reg_t)my_opnd_compute_address(opnd, &mc);
84 | //dr_printf("[DDR] [INFO] inst_mem_addr_noreg: "PFX"\n", *memaddr);
85 | }
86 | }
87 | instr_free(drcontext, &instr);
88 |
89 | return (memaddr != 0) ? TRUE : FALSE;
90 | }
91 |
92 | int __cdecl get_op_size_dump_buffer(void* drcontext, reg_t* memaddr, char Optype, char OptypePtrType, int Opnum, app_pc instr_addr, dr_mcontext_t mc) {
93 | byte* pc;
94 | opnd_t opnd;
95 | reg_id_t reg;
96 | instr_t instr;
97 | instr_init(drcontext, &instr);
98 | instr_reset(drcontext, &instr);
99 | pc = decode(drcontext, instr_addr, &instr); // fill in instr
100 | opnd = instr_get_src(&instr, Opnum);
101 | *memaddr = 0;
102 |
103 | // Source operant
104 | if (tolower(Optype) == 's') {
105 | dr_printf("[DDR] [INFO] Getting buffer size from source operant %d.\n", Opnum);
106 | // op is register
107 | if (my_opnd_is_reg(opnd)) {
108 | reg = opnd_get_reg(opnd);
109 | *memaddr = (reg_t)reg_get_value(reg, &mc);
110 | //dr_printf("[DDR] [INFO] inst_mem_addr_reg: "PFX"\n", *memaddr);
111 | }
112 | // op is an immediate value
113 | else if (opnd_is_immed(opnd)) {
114 | *memaddr = (reg_t)opnd_get_immed_int(opnd);
115 | //dr_printf("[DDR] [INFO] inst_mem_addr_immed: "PFX"\n", *memaddr);
116 | }
117 | // op is not a register
118 | else {
119 | *memaddr = (reg_t)my_opnd_compute_address(opnd, &mc);
120 | //dr_printf("[DDR] [INFO] inst_mem_addr_noreg: "PFX"\n", *memaddr);
121 | }
122 | }
123 | // Destination operant
124 | else if (tolower(Optype) == 'd') {
125 | dr_printf("[DDR] [INFO] Getting buffer size from destination operant %d.\n", Opnum);
126 |
127 | opnd = instr_get_dst(&instr, Opnum);
128 |
129 | // op is register
130 | if (my_opnd_is_reg(opnd)) {
131 | reg = opnd_get_reg(opnd);
132 | *memaddr = reg_get_value(reg, &mc);
133 | //dr_printf("[DDR] [INFO] inst_mem_addr_reg: "PFX"\n", *memaddr);
134 | }
135 | // op is an immediate value
136 | else if (opnd_is_immed(opnd)) {
137 | *memaddr = opnd_get_immed_int(opnd);
138 | //dr_printf("[DDR] [INFO] inst_mem_addr_immed: "PFX"\n", *memaddr);
139 | }
140 | else {
141 | *memaddr = (reg_t)my_opnd_compute_address(opnd, &mc);
142 | //dr_printf("[DDR] [INFO] inst_mem_addr_noreg: "PFX"\n", *memaddr);
143 | }
144 | }
145 | instr_free(drcontext, &instr);
146 |
147 | return (memaddr != 0) ? TRUE : FALSE;
148 | }
149 |
150 | void event_thread_init_global(void* drcontext)
151 | {
152 | app_pc FileEntryPoint, PEEntryPoint, PEImagebase;
153 | module_data_t* app;
154 |
155 | char* samplename;
156 | char samplename_cleaned[MAX_PATH * 2];
157 | byte* peb;
158 |
159 | size_t func_addr_fixed;
160 | static thread_id_t last_threat_id;
161 |
162 | thread_id = dr_get_thread_id(drcontext);
163 | process_id = dr_get_process_id();
164 | dr_printf("[DDR] [INFO] New Threat initalization started. Process ID = %u Threat ID = %u\n", process_id, thread_id);
165 |
166 | if (last_threat_id != 0) {
167 | dr_printf("[DDR] [WARNING] This is not the first thread. Multithreaded is not supported, but works in many cases.\n");
168 |
169 | if (patch_call_set) {
170 |
171 | pa_call_para = pa_call_para_start;
172 |
173 | while (pa_call_para) {
174 |
175 | if (!OEP_moved_plus)
176 | func_addr_fixed = pa_call_para->patch_call_func_PC - oep_diff;
177 | else
178 | func_addr_fixed = pa_call_para->patch_call_func_PC + oep_diff;
179 |
180 | drwrap_wrap((app_pc)func_addr_fixed, my_call_pre_wrapper, NULL);
181 | dr_printf("[DDR] [INFO] Function at "PFX" wrapped and return value set to "PFX"\n", func_addr_fixed, pa_call_para->patch_call_ret);
182 | pa_call_para = pa_call_para->nextcp;
183 | }
184 |
185 | pa_call_para = pa_call_para_start;
186 | }
187 | return;
188 | }
189 | else {
190 | first_thread_id = thread_id;
191 | dr_printf("[DDR] [INFO] First thread. Setting main thread id to %d\n", first_thread_id);
192 | }
193 |
194 | // Get sample filename
195 | app = dr_get_main_module();
196 | samplename = app->full_path;
197 | if (strlen(samplename) > MAX_PATH) {
198 | dr_printf("[DDR] [ERROR] Filename path too long\n");
199 | dr_exit_process(1);
200 | }
201 | else {
202 | memcpy(samplename_cleaned, samplename, strlen(samplename));
203 | samplename_cleaned[strlen(samplename)] = '\0';
204 | }
205 | dr_printf("[DDR] [INFO] Samplename: %s.\n", samplename_cleaned);
206 |
207 | // Get PEB
208 | peb = dr_get_app_PEB();
209 |
210 | // Get Imagebase and EP from PE in memory
211 | PEEntryPoint = app->entry_point;
212 | PEImagebase = app->start;
213 |
214 | // Get EP from orginal file on disk like IDA sees it
215 | if (!getOEPfromPEfile(samplename, &FileEntryPoint)) {
216 | dr_printf("[DDR] [WARNING] OEP not found in file.\n");
217 | FileEntryPoint = PEEntryPoint;
218 | }
219 |
220 | // Calculate the offset if the loader moved it
221 | if (FileEntryPoint >= PEEntryPoint) {
222 | oep_diff = FileEntryPoint - PEEntryPoint;
223 | }
224 | else {
225 | oep_diff = PEEntryPoint - FileEntryPoint;
226 | OEP_moved_plus = TRUE;
227 | }
228 |
229 | dr_printf("[DDR] [INFO] PEB : "PFX"\n", peb);
230 | dr_printf("[DDR] [INFO] PE Imagebase : "PFX"\n", PEImagebase);
231 | dr_printf("[DDR] [INFO] PE EP : "PFX"\n", PEEntryPoint);
232 | dr_printf("[DDR] [INFO] File EP : "PFX"\n", FileEntryPoint);
233 | dr_printf("[DDR] [INFO] EP diff : "PFX"\n", oep_diff);
234 |
235 | dr_free_module_data(app);
236 |
237 | if (patch_call_set) {
238 |
239 | pa_call_para = pa_call_para_start;
240 |
241 | while (pa_call_para) {
242 |
243 | if (!OEP_moved_plus)
244 | func_addr_fixed = pa_call_para->patch_call_func_PC - oep_diff;
245 | else
246 | func_addr_fixed = pa_call_para->patch_call_func_PC + oep_diff;
247 |
248 | drwrap_wrap((app_pc) func_addr_fixed, my_call_pre_wrapper, NULL);
249 | dr_printf("[DDR] [INFO] Function at "PFX" wrapped and return value set to "PFX"\n", func_addr_fixed, pa_call_para->patch_call_ret);
250 | pa_call_para = pa_call_para->nextcp;
251 | }
252 |
253 | pa_call_para = pa_call_para_start;
254 | }
255 |
256 | last_threat_id = thread_id;
257 | }
258 |
259 | void __cdecl process_instr_size_dump_buffer(app_pc instr_addr, S_DUMP_PARA* dp) {
260 |
261 | size_t instr_addr_fixed;
262 | void* drcontext;
263 | int ret;
264 |
265 | drcontext = dr_get_current_drcontext();
266 | dr_mcontext_t mc = { sizeof(mc),DR_MC_ALL };
267 | dr_get_mcontext(drcontext, &mc);
268 |
269 | // Calculate the instr addr in file/IDA
270 | if (!OEP_moved_plus)
271 | instr_addr_fixed = (size_t)instr_addr + oep_diff;
272 | else
273 | instr_addr_fixed = (size_t)instr_addr - oep_diff;
274 |
275 | // Disasm instruction at PC
276 | print_disasm(drcontext, instr_addr, instr_addr_fixed);
277 |
278 | // Get size of buffer in operator
279 | ret = get_op_size_dump_buffer(drcontext, &dumpbuf_size, dp->sizeOptype, dp->sizeOptypePtrType, dp->sizeOpnum, instr_addr, mc);
280 |
281 | if (ret) {
282 | dr_printf("[DDR] [INFO] buffer size = "PFX" (%d)\n", dumpbuf_size, dumpbuf_size);
283 | dumbuf_SizeFound = TRUE;
284 | }
285 | else {
286 | dr_printf("[DDR] [ERROR] Getting buffer size failed\n", dumpbuf_size);
287 | dr_exit_process(1);
288 | }
289 | }
290 |
291 | void __cdecl process_instr_addr_dump_buffer(app_pc instr_addr, S_DUMP_PARA* dp) {
292 |
293 | size_t instr_addr_fixed;
294 | void* drcontext;
295 | int ret;
296 |
297 | drcontext = dr_get_current_drcontext();
298 | dr_mcontext_t mc = { sizeof(mc),DR_MC_ALL };
299 | dr_get_mcontext(drcontext, &mc);
300 |
301 | // Calculate the instr addr in file/IDA
302 | if (!OEP_moved_plus)
303 | instr_addr_fixed = (size_t)instr_addr + oep_diff;
304 | else
305 | instr_addr_fixed = (size_t)instr_addr - oep_diff;
306 |
307 | // Disasm instruction at PC
308 | print_disasm(drcontext, instr_addr, instr_addr_fixed);
309 |
310 | // Get memory address of buffer in operator
311 | ret = get_mem_addr_dump_buffer(drcontext, &dumpbuf_addr, dp->bufferOptype, dp->bufferOptypePtrType, dp->bufferOpnum, instr_addr, mc);
312 |
313 | if (ret) {
314 | dr_printf("[DDR] [INFO] buffer address = "PFX"\n", dumpbuf_addr);
315 | dumpbuf_AddrFound = TRUE;
316 | }
317 | else {
318 | dr_printf("[DDR] [ERROR] Getting buffer address failed\n");
319 | dr_exit_process(1);
320 | }
321 | }
322 |
323 | void __cdecl process_instr_dump_buffer(app_pc instr_addr, S_DUMP_PARA* dp) {
324 |
325 | size_t bytesread;
326 | char* bytesbuf;
327 | void* drcontext;
328 | size_t instr_addr_fixed;
329 |
330 | file_t dump_fp = dr_open_file(dp->filename, DR_FILE_WRITE_OVERWRITE);
331 | if (dump_fp == INVALID_FILE) {
332 | dr_printf("[DDR] [ERROR] Can't create dump file. Does the directory you specified exist?\n");
333 | dr_exit_process(1);
334 | }
335 |
336 | drcontext = dr_get_current_drcontext();
337 |
338 | // Calculate the instr addr in file/IDA
339 | if (!OEP_moved_plus)
340 | instr_addr_fixed = (size_t)instr_addr + oep_diff;
341 | else
342 | instr_addr_fixed = (size_t)instr_addr - oep_diff;
343 |
344 | // Print disasm at instr_addr
345 | print_disasm(drcontext, instr_addr, instr_addr_fixed);
346 |
347 | bytesbuf = (char*) dr_global_alloc(sizeof(char) * dumpbuf_size);
348 |
349 | // Safe memory buffer to file
350 | if (dr_safe_read((app_pc)dumpbuf_addr, (size_t) dumpbuf_size, bytesbuf, &bytesread)) {
351 |
352 | if (bytesread == dumpbuf_size) {
353 | dr_write_file(dump_fp, bytesbuf, dumpbuf_size);
354 | dr_close_file(dump_fp);
355 | dr_printf("[DDR] [INFO] [FINAL] Done. Written %d bytes from address "PFX" to file: %s.\n", dumpbuf_size, dumpbuf_addr, dp->filename);
356 | }
357 | else {
358 | dr_printf("[DDR] [ERROR] [FINAL] Data not written to file. Bytes read: %d.\n", bytesread);
359 | }
360 | }
361 | dr_global_free(bytesbuf, sizeof(char) * dumpbuf_size);
362 | }
363 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/globals.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | extern int cmd_opts;
4 | extern unsigned int dbgLevel;
5 | extern int tls_idx;
6 | extern int tls_idx2;
7 | extern int tls_idx3;
8 | extern client_id_t my_id;
9 | extern size_t oep_diff;
10 | extern size_t ref_flags;
11 | extern size_t from_addr;
12 | extern size_t to_addr;
13 | extern size_t inst_count;
14 | extern size_t inst_num;
15 | extern bool light_trace_only;
16 | extern bool trace_set;
17 | extern bool first_instr_set;
18 | extern bool OEP_moved_plus;
19 |
20 | extern bool patch_eflag_set;
21 | extern P_EFLAG_PARA* pa_flag_para;
22 | extern P_EFLAG_PARA* pa_flag_para_start;
23 |
24 | extern bool patch_nop_set;
25 | extern P_NOP_PARA* pa_nop_para;
26 | extern P_NOP_PARA* pa_nop_para_start;
27 |
28 | extern bool patch_call_set;
29 | extern P_CALL_PARA* pa_call_para;
30 | extern P_CALL_PARA* pa_call_para_start;
31 |
32 | extern bool dump_buffer_set;
33 | extern S_DUMP_PARA* dump_para;
34 | extern S_DUMP_PARA* dump_para_start;
35 |
36 | extern bool trace_para_set;
37 | extern S_TRACE_PARA* trace_para;
38 | extern S_TRACE_PARA* trace_para_start;
39 |
40 | extern S_PROCS* pListThreads;
41 | extern S_PROCS* pListThreads_start;
42 | extern unsigned int thread_counter;
43 |
44 | extern file_t global_fPidThreads;
45 | extern char* global_pidThreadsFilename;
46 | extern char* global_pidThreadsFullFilename;
47 | extern char* global_logpath;
48 |
49 | extern bool dumpbuf_AddrFound;
50 | extern bool dumbuf_SizeFound;
51 |
52 | extern char *global_trace_LogFilename;
53 | extern char *global_trace_ApiLogfilename;
54 | extern char* global_client_path;
55 | extern file_t global_trace_fp;
56 | extern file_t global_trace_api_fp;
57 | extern file_t global_exec_counter_fp;
58 | extern uint thread_couter;
59 | extern thread_id_t thread_id;
60 | extern process_id_t process_id;
61 | extern thread_id_t first_thread_id;
62 | extern unsigned int dr_exec_ctr;
63 |
64 | extern bool loop_set;
65 | extern size_t loop_addr;
66 | extern bool startaddr_set;
67 | extern size_t startaddr;
68 | extern bool breakaddr_set;
69 | extern size_t breakaddr;
70 |
71 | extern TCHAR szName[];
72 | extern TCHAR szProcIDs[];
73 | extern TCHAR szProcNames[];
74 | extern TCHAR szLogPath[];
75 | extern process_id_t *processids;
76 |
77 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/patch_exe.c:
--------------------------------------------------------------------------------
1 | #include "ddr.h"
2 | #include "globals.h"
3 |
4 | void __cdecl patch_eflag(app_pc instr_addr, P_EFLAG_PARA* pp) {
5 | void* drcontext;
6 | size_t instr_addr_fixed;
7 | byte* pc;
8 |
9 | drcontext = dr_get_current_drcontext();
10 | dr_mcontext_t mc = { sizeof(mc),DR_MC_ALL };
11 | dr_get_mcontext(drcontext, &mc);
12 |
13 | // Calculate the instr addr in file/IDA
14 | if (!OEP_moved_plus)
15 | instr_addr_fixed = (size_t)instr_addr + oep_diff;
16 | else
17 | instr_addr_fixed = (size_t)instr_addr - oep_diff;
18 |
19 | dr_printf("[DDR] [INFO] Toggling %s EFLAG at "PFX"\n", pp->patch_eflag_flag_str, instr_addr_fixed);
20 | print_disasm(drcontext, instr_addr, instr_addr_fixed);
21 |
22 | instr_t instr;
23 | instr_init(drcontext, &instr);
24 | instr_reset(drcontext, &instr);
25 |
26 | pc = decode(drcontext, instr_addr, &instr);
27 | if (pc == NULL) {
28 | dr_printf("[DDR] [ERROR] Invalid Instruction found! DynamoRIO can't decode instruction\n");
29 | dr_exit_process(1);
30 | }
31 |
32 | dr_printf("[DDR] [INFO] EFLAGS register before toggling: 0x%x\n", mc.xflags);
33 | if (mc.xflags & pp->patch_eflag_flag)
34 | dr_printf("[DDR] [INFO] %s EFLAG = 1\n", pp->patch_eflag_flag_str);
35 | else
36 | dr_printf("[DDR] [INFO] %s EFLAG = 0\n", pp->patch_eflag_flag_str);
37 |
38 | mc.xflags ^= pp->patch_eflag_flag; // toggle eflag bit
39 | dr_set_mcontext(drcontext, &mc);
40 |
41 | dr_printf("[DDR] [INFO] EFLAGS register after toggling: 0x%x\n", mc.xflags);
42 | if (mc.xflags & pp->patch_eflag_flag)
43 | dr_printf("[DDR] [INFO] %s EFLAG set to 1\n", pp->patch_eflag_flag_str);
44 | else
45 | dr_printf("[DDR] [INFO] %s EFLAG set to 0\n", pp->patch_eflag_flag_str);
46 |
47 | instr_free(drcontext, &instr);
48 | }
49 |
50 | void __cdecl patch_sleep(app_pc instr_addr) {
51 | dr_messagebox("Execution stopped. Please click ok to proceed.");
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/trace_instr.c:
--------------------------------------------------------------------------------
1 | /* This file handles the CmdOpt_NormalTrace */
2 |
3 | #include "ddr.h"
4 | #include "globals.h"
5 |
6 | void event_module_load_trace_instr(void* drcontext, const module_data_t* info, bool loaded)
7 | {
8 | #ifdef _DEBUG
9 | dr_printf("[DDR] [DEBUG] event_module_load_trace_instr module loaded: %s:\n", dr_module_preferred_name(info));
10 | #endif
11 | if (lib_is_not_blacklisted_trace_instr(info))
12 | iterate_exports_trace_instr(info);
13 | }
14 |
15 | process_id_t getFirstPIDfromFile(char* pidsfilename) {
16 |
17 | file_t fPidsfile;
18 | uint max_retries;
19 | process_id_t pid = 0;
20 | size_t bytes_read;
21 | char data[MAX_PATH + 20];
22 | char* sPid;
23 | size_t sPidLen=0;
24 |
25 | for (max_retries = 0; max_retries < 3; max_retries++) {
26 | dr_printf("[DDR] [INFO] Trying to open PID file: %s\n", pidsfilename);
27 | fPidsfile = dr_open_file(pidsfilename, DR_FILE_READ); // write PID to PIDs file
28 | if (fPidsfile == INVALID_FILE) {
29 | dr_printf("[DDR] [ERROR] Failed to open initial process log file: %s. Attempt number: %u\n", pidsfilename, max_retries);
30 | Sleep(300);
31 | continue;
32 | }
33 | break;
34 | }
35 |
36 | bytes_read = dr_read_file(fPidsfile, data, MAX_PATH + 10);
37 | data[bytes_read] = '\0';
38 | sPid = getSubstr(data, "[", "]");
39 | sPidLen = strlen(sPid);
40 | pid = (process_id_t) strtoull(sPid, NULL, 10);
41 |
42 | dr_close_file(fPidsfile);
43 |
44 | dr_global_free(sPid, strlen(sPid)+1);
45 | return pid;
46 |
47 | }
48 |
49 | void event_thread_init_trace_instr(void* drcontext)
50 | {
51 | #ifdef _DEBUG
52 | dr_printf("\n[DDR] [DEBUG] event_thread_init_trace_instr start.\n");
53 | #endif
54 |
55 | app_pc FileEntryPoint, PEEntryPoint, PEImagebase;
56 | module_data_t* app;
57 |
58 | char* samplename;
59 | char samplename_cleaned[MAX_PATH * 2];
60 | const char *app_name;
61 | byte* peb;
62 | static thread_id_t last_threat_id;
63 | size_t func_addr_fixed;
64 |
65 | thread_counter = thread_counter + 1;
66 | thread_id = dr_get_thread_id(drcontext);
67 | process_id = dr_get_process_id();
68 | app_name = dr_get_application_name();
69 | dr_printf("[DDR] [INFO] New thread initialization started. Appname = %s Process ID = %u Threat ID = %u Thread counter = %u\n",
70 | app_name, process_id, thread_id, thread_counter);
71 |
72 | // is this first thread of the process ?
73 | if (pListThreads == NULL) {
74 | // ---- New process, first threat. ----
75 | dr_printf("[DDR] [INFO] New process, first thread started.\n");
76 |
77 | // allocate memory for threads linked list (pListThreads)
78 | pListThreads = (S_PROCS*)dr_global_alloc(sizeof(S_PROCS));
79 | pListThreads_start = pListThreads;
80 |
81 | #ifdef _DEBUG
82 | dr_printf("[DDR] [DEBUG] [MEMOP] allocated memory for main thread. Memaddr: "PFX" thread_id=%d process_id=%u\n",
83 | pListThreads, thread_id, process_id);
84 | #endif
85 | // create process-thread log file
86 | if (global_pidThreadsFullFilename == NULL) {
87 | global_pidThreadsFullFilename = (char*)dr_global_alloc(MAX_PATH);
88 | }
89 |
90 | dr_snprintf(global_pidThreadsFullFilename, MAX_PATH, "%s\\%s_%s_%u.txt", global_logpath, global_pidThreadsFilename, app_name, dr_get_process_id());
91 | dr_printf("[DDR] [INFO] writing thread info to: %s\n", global_pidThreadsFullFilename);
92 |
93 | global_fPidThreads = dr_open_file(global_pidThreadsFullFilename, DR_FILE_WRITE_OVERWRITE); // write PID to PIDs file
94 | if (global_fPidThreads == INVALID_FILE) {
95 | dr_printf("[DDR] [ERROR] Failed to open individual threads log file: %s\n", global_pidThreadsFullFilename);
96 | }
97 | dr_global_free(global_pidThreadsFullFilename, MAX_PATH);
98 |
99 | dr_fprintf(global_fPidThreads, "%s [%u] [%u]\r\n", app_name, process_id, thread_id);
100 |
101 | // fill process structure
102 | // is this the first process ?
103 | if (*processids == process_id) {
104 | pListThreads->start_process_id = process_id;
105 | }
106 | else {
107 | pListThreads->start_process_id = *processids;
108 | }
109 | pListThreads->prevproc = NULL;
110 | pListThreads->process_id = process_id;
111 | pListThreads->threat_id = thread_id;
112 | pListThreads->nextproc = NULL;
113 | }
114 | else {
115 | // ---- Existing process 2nd to n thread ----
116 | dr_printf("[DDR] [INFO] Existing process. New thread started.\n");
117 |
118 | if (global_logpath) {
119 | debug_print("Using log path %s\n", global_logpath);
120 | }
121 | else {
122 | dr_printf("[DDR] [ERROR] [%s:%d] global logpath file not found\n", __FILE__, __LINE__);
123 | }
124 |
125 | // log process/thread info to process-thread file
126 | dr_fprintf(global_fPidThreads, "%s [%u] [%u]\r\n", app_name, process_id, thread_id);
127 |
128 | pListThreads->nextproc = (S_PROCS*)dr_global_alloc(sizeof(S_PROCS));
129 | #ifdef _DEBUG
130 | dr_printf("[DDR] [DEBUG] [MEMOP] allocated memory for sub thread. Memaddr: "PFX" thread_id=%d process_id=%u\n",
131 | pListThreads->nextproc, thread_id, process_id);
132 | #endif
133 | pListThreads->nextproc->prevproc = pListThreads;
134 | pListThreads = pListThreads->nextproc;
135 |
136 | // is this the first process ?
137 | if (*processids == process_id) {
138 | pListThreads->start_process_id = process_id;
139 | }
140 | else {
141 | pListThreads->start_process_id = *processids;
142 | }
143 | pListThreads->process_id = process_id;
144 | pListThreads->threat_id = thread_id;
145 | pListThreads->nextproc = NULL;
146 | }
147 |
148 | if (last_threat_id != 0) {
149 | dr_printf("[DDR] [WARNING] This is not the first thread. Multithreaded is not supported, but works in many cases.\n");
150 |
151 | if (patch_call_set) {
152 |
153 | pa_call_para = pa_call_para_start;
154 |
155 | while (pa_call_para) {
156 |
157 | if (!OEP_moved_plus)
158 | func_addr_fixed = pa_call_para->patch_call_func_PC - oep_diff;
159 | else
160 | func_addr_fixed = pa_call_para->patch_call_func_PC + oep_diff;
161 |
162 | drwrap_wrap((app_pc)func_addr_fixed, my_call_pre_wrapper, NULL);
163 | dr_printf("[DDR] [INFO] Function at "PFX" wrapped and return value set to "PFX"\n", func_addr_fixed, pa_call_para->patch_call_ret);
164 | pa_call_para = pa_call_para->nextcp;
165 | }
166 |
167 | pa_call_para = pa_call_para_start;
168 | }
169 | return;
170 | }
171 | else {
172 | first_thread_id = thread_id;
173 | dr_printf("[DDR] [INFO] First thread. Setting main thread id to %d\n", first_thread_id);
174 | }
175 |
176 | // Get sample Filename
177 | app = dr_get_main_module();
178 | samplename = app->full_path;
179 | if (strlen(samplename) > MAX_PATH) {
180 | dr_printf("[DDR] [ERROR] Filename path too long\n");
181 | dr_exit_process(1);
182 | }
183 | else {
184 | memcpy(samplename_cleaned, samplename, strlen(samplename));
185 | samplename_cleaned[strlen(samplename)] = '\0';
186 | }
187 | dr_printf("[DDR] [INFO] Samplename: %s.\n", samplename_cleaned);
188 |
189 | // Escape filename string for JSON file
190 | if (!escape_dir_str(samplename_cleaned)) {
191 | dr_printf("[DDR] [ERROR] Failed to escape file path\n");
192 | dr_exit_process(1);
193 | }
194 |
195 | // Write meta data about the sample into the logfile
196 | // TBD: use a proper JSON lib instead
197 | dr_fprintf(global_trace_fp, "{\n\"samplename\" : \"%s\",\n", samplename_cleaned ? samplename_cleaned : "FILENAME_PARSING_ERROR");
198 |
199 | #ifdef X86_64
200 | dr_fprintf(global_trace_fp, "\"architecture\" : \"x64\",\n");
201 | #else
202 | dr_fprintf(global_trace_fp, "\"architecture\" : \"x32\",\n");
203 | #endif
204 |
205 | dr_fprintf(global_trace_fp, "\"trace_start\" : \""PFX"\",\n", from_addr);
206 | dr_fprintf(global_trace_fp, "\"trace_end\" : \""PFX"\",\n", to_addr);
207 | dr_fprintf(global_trace_fp, "\"num_instr_to_trace\" : \"%d\",\n", inst_count);
208 |
209 | // Get PEB
210 | peb = dr_get_app_PEB();
211 |
212 | PEEntryPoint = app->entry_point;
213 | PEImagebase = app->start;
214 |
215 | // get OEP from orginal file on disk
216 | if (!getOEPfromPEfile(samplename, &FileEntryPoint)) {
217 | dr_printf("[DDR] [WARNING] OEP not found in file.\n");
218 | FileEntryPoint = PEEntryPoint;
219 | }
220 |
221 | // Calculate the offset if the loader moved it
222 | if (FileEntryPoint >= PEEntryPoint) {
223 | oep_diff = FileEntryPoint - PEEntryPoint;
224 | }
225 | else {
226 | oep_diff = PEEntryPoint - FileEntryPoint;
227 | OEP_moved_plus = TRUE;
228 | }
229 |
230 | dr_printf("[DDR] [INFO] PEB : "PFX"\n", peb);
231 | dr_printf("[DDR] [INFO] PE Imagebase : "PFX"\n", PEImagebase);
232 | dr_printf("[DDR] [INFO] PE EP : "PFX"\n", PEEntryPoint);
233 | dr_printf("[DDR] [INFO] File EP : "PFX"\n", FileEntryPoint);
234 | dr_printf("[DDR] [INFO] EP diff : "PFX"\n", oep_diff);
235 |
236 | dr_fprintf(global_trace_fp, "\"peb\" : \""PFX"\",\n", peb);
237 | dr_fprintf(global_trace_fp, "\"imagebase\" : \""PFX"\",\n", PEImagebase);
238 | dr_fprintf(global_trace_fp, "\"entrypoint\" : \""PFX"\",\n", PEEntryPoint);
239 | dr_fprintf(global_trace_fp, "\"oep\" : \""PFX"\",\n", FileEntryPoint);
240 | dr_fprintf(global_trace_fp, "\"oep_diff\" : \""PFX"\",\n", oep_diff);
241 | dr_fprintf(global_trace_fp, "\"instruction\" : \n[\n");
242 |
243 | if (patch_call_set) {
244 |
245 | pa_call_para = pa_call_para_start;
246 |
247 | while (pa_call_para) {
248 |
249 | if (!OEP_moved_plus)
250 | func_addr_fixed = pa_call_para->patch_call_func_PC - oep_diff;
251 | else
252 | func_addr_fixed = pa_call_para->patch_call_func_PC + oep_diff;
253 |
254 | drwrap_wrap((app_pc)func_addr_fixed, my_call_pre_wrapper, NULL);
255 | dr_printf("[DDR] [INFO] Function at "PFX" wrapped and return value set to "PFX"\n", func_addr_fixed, pa_call_para->patch_call_ret);
256 | pa_call_para = pa_call_para->nextcp;
257 | }
258 |
259 | pa_call_para = pa_call_para_start;
260 | }
261 |
262 | //last_threat_id = thread_id;
263 | last_threat_id = dr_get_thread_id(drcontext);
264 |
265 | dr_free_module_data(app);
266 |
267 | #ifdef _DEBUG
268 | dr_printf("\n[DDR] [DEBUG] event_thread_init_trace_instr end.\n");
269 | #endif
270 | }
271 |
272 | void event_thread_exit_trace_instr(void* drcontext)
273 | {
274 | //S_TRACE_PARA* trace_para_prev;
275 | S_PROCS* pListThreads_tmp;
276 |
277 | #ifdef _DEBUG
278 | dr_printf("\n[DDR] [DEBUG] event_thread_exit_trace_instr start.\n");
279 | dr_printf("[DDR] [DEBUG] Thread counter: %u\n", thread_counter);
280 | #endif
281 |
282 | if (first_thread_id == dr_get_thread_id(drcontext)) {
283 |
284 | dr_printf("[DDR] [INFO] Main thread (id = %d) was terminated.\n", first_thread_id);
285 | dr_close_file(global_fPidThreads);
286 |
287 | // Fix trace file
288 | dr_fprintf(global_trace_fp, " ]\n}\n");
289 | dr_close_file(global_trace_fp);
290 |
291 | dr_printf("[DDR] [INFO] Fixing trace file: %s\n", global_trace_LogFilename);
292 | fix_comma_in_jsonfile(global_trace_LogFilename);
293 | dr_printf("[DDR] [INFO] Trace file fixed.\n");
294 |
295 | // Fix API trace file
296 | dr_file_seek(global_trace_api_fp, -2, DR_SEEK_CUR);
297 | dr_fprintf(global_trace_api_fp, "\n ]\n}\n");
298 | dr_close_file(global_trace_api_fp);
299 |
300 | dr_printf("[DDR] [INFO] Fixing API trace file: %s\n", global_trace_ApiLogfilename);
301 | fix_comma_in_jsonfile(global_trace_ApiLogfilename);
302 | dr_printf("[DDR] [INFO] API trace file fixed.\n");
303 |
304 | dr_global_free(global_trace_LogFilename, MAX_PATH);
305 | dr_global_free(global_trace_ApiLogfilename, MAX_PATH);
306 |
307 | /*if (trace_para_set) {
308 | trace_para = trace_para_start;
309 | while (trace_para) {
310 | dr_global_free(trace_para->filename, MAX_FILE_LINE_LEN);
311 | trace_para_prev = trace_para;
312 | trace_para = trace_para->nexttr;
313 | dr_global_free(trace_para_prev, sizeof(S_TRACE_PARA));
314 | }
315 | }*/
316 |
317 | SYSTEMTIME lt;
318 | GetLocalTime(<);
319 | dr_printf("[DDR] [INFO] Time : %02d:%02d:%02d:%d\n", lt.wHour, lt.wMinute, lt.wSecond, lt.wMilliseconds);
320 | }
321 | else {
322 | dr_printf("[DDR] [INFO] Thread with id %d was terminated\n", dr_get_thread_id(drcontext));
323 | }
324 |
325 | // Is this the last living thread ? Free the linked list
326 | if (thread_counter == 1) {
327 | #ifdef _DEBUG
328 | dr_printf("[DDR] [DEBUG] [MEMOP] Last living thread (thread_id = %d proccess = %u) reached. Free'ing memory.\n",
329 | dr_get_thread_id(drcontext), dr_get_process_id());
330 | #endif
331 | pListThreads = pListThreads_start;
332 | while (pListThreads) {
333 | pListThreads_tmp = pListThreads->nextproc;
334 | #ifdef _DEBUG
335 | dr_printf("[DDR] [DEBUG] [MEMOP] free'ing memory: "PFX" thread_id = %d\n", pListThreads, pListThreads->threat_id);
336 | #endif
337 | dr_global_free(pListThreads, sizeof(S_PROCS));
338 | pListThreads = pListThreads_tmp;
339 | }
340 | #ifdef _DEBUG
341 | dr_printf("[DDR] [DEBUG] [MEMOP] process memory free'ed.\n");
342 | #endif
343 | }
344 | thread_counter = thread_counter - 1;
345 |
346 |
347 | #ifdef _DEBUG
348 | dr_printf("\n[DDR] [DEBUG] event_thread_exit_trace_instr end.\n");
349 | #endif
350 | }
351 |
352 |
353 | void __cdecl process_instr_trace_instr_new(app_pc instr_addr, S_TRACE_PARA* tr)
354 | {
355 | char* cf_bit = "cf=0";
356 | char* pf_bit = "pf=0";
357 | char* af_bit = "af=0";
358 | char* zf_bit = "zf=0";
359 | char* sf_bit = "sf=0";
360 | char* df_bit = "df=0";
361 | char* of_bit = "of=0";
362 |
363 | size_t instr_addr_fixed;
364 |
365 | void* drcontext;
366 | byte* pc;
367 |
368 | drcontext = dr_get_current_drcontext();
369 | dr_mcontext_t mc = { sizeof(mc),DR_MC_ALL };
370 | dr_get_mcontext(drcontext, &mc);
371 |
372 | if (!OEP_moved_plus)
373 | instr_addr_fixed = (size_t)instr_addr + oep_diff;
374 | else
375 | instr_addr_fixed = (size_t)instr_addr - oep_diff;
376 |
377 | if (tr->max_instr <= 0) {
378 | dr_printf("[DDR] [WARNING] Max. number of instructions reached. Logging stopped at 0x%x.\n", instr_addr);
379 | dr_exit_process(0); // calls exit routines
380 | }
381 |
382 | #ifdef _DEBUG
383 | if (dbgLevel >= 5) {
384 | dr_printf("[DDR] [DEBUG] i:0x%x\n", instr_addr_fixed);
385 | }
386 | /*
387 | // Testing a crash....
388 | //
389 | if (instr_addr_fixed == 0x401924) {
390 | dr_printf("[DDR] [DEBUG] -------- Create access violation when process instruction 0x401924. -----------\n");
391 | memcpy(NULL, 0xffffffff, 50); // create access violation
392 | }
393 | */
394 | #endif
395 |
396 | if ((instr_addr_fixed >= tr->start) && (instr_addr_fixed <= tr->end)) {
397 |
398 | instr_t instr;
399 |
400 | if (first_thread_id == dr_get_thread_id(drcontext)) {
401 | // light trace
402 | if (tr->light_trace_only) {
403 | dr_fprintf(global_trace_fp, " {\n \"instr_num\" : \"%d\",\n", inst_num++);
404 | // medium trace preparation: TBD add a medium trace option to config
405 | if (true) {
406 | instr_init(drcontext, &instr);
407 | instr_reset(drcontext, &instr);
408 | dr_fprintf(global_trace_fp, " \"address\" : \""PFX"\",\n", instr_addr_fixed);
409 | pc = decode(drcontext, instr_addr, &instr);
410 |
411 | size_t disasm_buf_size = 254;
412 | unsigned char* disasm_buf = (unsigned char*)dr_global_alloc(sizeof(unsigned char) * disasm_buf_size);
413 | instr_disassemble_to_buffer(dr_get_current_drcontext(), &instr, disasm_buf, disasm_buf_size);
414 | dr_fprintf(global_trace_fp, " \"disasm\" : \"%s\",\n", disasm_buf);
415 | dr_global_free(disasm_buf, sizeof(unsigned char) * disasm_buf_size);
416 |
417 | log_instr_opnds_trace_instr(global_trace_fp, &instr, &mc, drcontext, 16);
418 | instr_free(drcontext, &instr);
419 | }
420 | else {
421 | dr_fprintf(global_trace_fp, " \"address\" : \""PFX"\"\n", instr_addr_fixed);
422 | }
423 | dr_fprintf(global_trace_fp, " },\n");
424 | tr->max_instr--;
425 | }
426 | // full trace
427 | else {
428 | instr_init(drcontext, &instr);
429 | instr_reset(drcontext, &instr);
430 |
431 | tr->max_instr--;
432 |
433 | pc = decode(drcontext, instr_addr, &instr);
434 | if (pc == NULL) {
435 | dr_fprintf(global_trace_fp, "ERROR: Invalid Instruction found! DynamoRIO can't decode instruction\n");
436 | return;
437 | }
438 |
439 | // get flags and registers
440 | ref_flags = mc.xflags;
441 |
442 | if (EFLAGS_CF & ref_flags) cf_bit = "cf=1";
443 | if (EFLAGS_PF & ref_flags) pf_bit = "pf=1";
444 | if (EFLAGS_AF & ref_flags) af_bit = "af=1";
445 | if (EFLAGS_ZF & ref_flags) zf_bit = "zf=1";
446 | if (EFLAGS_SF & ref_flags) sf_bit = "sf=1";
447 | if (EFLAGS_DF & ref_flags) df_bit = "df=1";
448 | if (EFLAGS_OF & ref_flags) of_bit = "of=1";
449 |
450 | if (first_instr_set)
451 | first_instr_set = FALSE;
452 | else
453 | dr_fprintf(global_trace_fp, ",\n");
454 |
455 | dr_fprintf(global_trace_fp, " {\n");
456 | dr_fprintf(global_trace_fp, " \"instr_num\" : \"%d\",\n", inst_num++);
457 | dr_fprintf(global_trace_fp, " \"address\" : \""PFX"\",\n", instr_addr_fixed);
458 | dr_fprintf(global_trace_fp, " \"xax\" : \""PFX"\",\n", mc.xax);
459 | log_mem_at_reg_trace_instr((app_pc)mc.xax, "xax", global_trace_fp);
460 | dr_fprintf(global_trace_fp, " \"xbx\" : \""PFX"\",\n", mc.xbx);
461 | log_mem_at_reg_trace_instr((app_pc)mc.xbx, "xbx", global_trace_fp);
462 | dr_fprintf(global_trace_fp, " \"xcx\" : \""PFX"\",\n", mc.xcx);
463 | log_mem_at_reg_trace_instr((app_pc)mc.xcx, "xcx", global_trace_fp);
464 | dr_fprintf(global_trace_fp, " \"xdx\" : \""PFX"\",\n", mc.xdx);
465 | log_mem_at_reg_trace_instr((app_pc)mc.xdx, "xdx", global_trace_fp);
466 | dr_fprintf(global_trace_fp, " \"xsp\" : \""PFX"\",\n", mc.xsp);
467 | log_mem_at_reg_trace_instr((app_pc)mc.xsp, "xsp", global_trace_fp);
468 | dr_fprintf(global_trace_fp, " \"xbp\" : \""PFX"\",\n", mc.xbp);
469 | log_mem_at_reg_trace_instr((app_pc)mc.xbp, "xbp", global_trace_fp);
470 | dr_fprintf(global_trace_fp, " \"xsi\" : \""PFX"\",\n", mc.xsi);
471 | log_mem_at_reg_trace_instr((app_pc)mc.xsi, "xsi", global_trace_fp);
472 | dr_fprintf(global_trace_fp, " \"xdi\" : \""PFX"\",\n", mc.xdi);
473 | log_mem_at_reg_trace_instr((app_pc)mc.xdi, "xdi", global_trace_fp);
474 |
475 | #ifdef X86_64
476 | dr_fprintf(global_trace_fp, " \"r8\" : \""PFX"\",\n", mc.r8);
477 | log_mem_at_reg_trace_instr((app_pc)mc.r8, "r8", global_trace_fp);
478 | dr_fprintf(global_trace_fp, " \"r9\" : \""PFX"\",\n", mc.r9);
479 | log_mem_at_reg_trace_instr((app_pc)mc.r9, "r9", global_trace_fp);
480 | dr_fprintf(global_trace_fp, " \"r10\" : \""PFX"\",\n", mc.r10);
481 | log_mem_at_reg_trace_instr((app_pc)mc.r10, "r10", global_trace_fp);
482 | dr_fprintf(global_trace_fp, " \"r11\" : \""PFX"\",\n", mc.r11);
483 | log_mem_at_reg_trace_instr((app_pc)mc.r11, "r11", global_trace_fp);
484 | dr_fprintf(global_trace_fp, " \"r12\" : \""PFX"\",\n", mc.r12);
485 | log_mem_at_reg_trace_instr((app_pc)mc.r12, "r12", global_trace_fp);
486 | dr_fprintf(global_trace_fp, " \"r13\" : \""PFX"\",\n", mc.r13);
487 | log_mem_at_reg_trace_instr((app_pc)mc.r13, "r13", global_trace_fp);
488 | dr_fprintf(global_trace_fp, " \"r14\" : \""PFX"\",\n", mc.r14);
489 | log_mem_at_reg_trace_instr((app_pc)mc.r14, "r14", global_trace_fp);
490 | dr_fprintf(global_trace_fp, " \"r15\" : \""PFX"\",\n", mc.r15);
491 | log_mem_at_reg_trace_instr((app_pc)mc.r15, "r15", global_trace_fp);
492 | #endif
493 |
494 | dr_fprintf(global_trace_fp, " \"eflags\" : \"0x%x\",\n", ref_flags);
495 | dr_fprintf(global_trace_fp, " \"cf_bit\" : \"%s\",\n", cf_bit);
496 | dr_fprintf(global_trace_fp, " \"pf_bit\" : \"%s\",\n", pf_bit);
497 | dr_fprintf(global_trace_fp, " \"af_bit\" : \"%s\",\n", af_bit);
498 | dr_fprintf(global_trace_fp, " \"zf_bit\" : \"%s\",\n", zf_bit);
499 | dr_fprintf(global_trace_fp, " \"sf_bit\" : \"%s\",\n", sf_bit);
500 | dr_fprintf(global_trace_fp, " \"df_bit\" : \"%s\",\n", df_bit);
501 | dr_fprintf(global_trace_fp, " \"of_bit\" : \"%s\",\n", of_bit);
502 |
503 | // Print DISASM of instruction to JSON file
504 | size_t disasm_buf_size = 254;
505 | unsigned char* disasm_buf = (unsigned char*)dr_global_alloc(sizeof(unsigned char) * disasm_buf_size);
506 | instr_disassemble_to_buffer(dr_get_current_drcontext(), &instr, disasm_buf, disasm_buf_size);
507 | dr_fprintf(global_trace_fp, " \"disasm\" : \"%s\",\n", disasm_buf);
508 | dr_global_free(disasm_buf, sizeof(unsigned char)* disasm_buf_size);
509 |
510 | log_instr_opnds_trace_instr(global_trace_fp, &instr, &mc, drcontext, 16);
511 | dr_fprintf(global_trace_fp, "\n");
512 | dr_fprintf(global_trace_fp, " }");
513 |
514 | instr_free(drcontext, &instr);
515 | }
516 | }
517 | }
518 | }
519 |
520 | static void iterate_exports_trace_instr(const module_data_t* info)
521 | {
522 | dr_symbol_export_iterator_t* exp_iter =
523 | dr_symbol_export_iterator_start(info->handle);
524 | while (dr_symbol_export_iterator_hasnext(exp_iter)) {
525 | dr_symbol_export_t* sym = dr_symbol_export_iterator_next(exp_iter);
526 | if ((sym->is_code) && (sym->addr != NULL)) {
527 | dr_fprintf(global_trace_api_fp, " {\"address\" : \""PFX"\",\n", sym->addr);
528 | dr_fprintf(global_trace_api_fp, " \"name\" : \"%s\",\n", sym->name);
529 | dr_fprintf(global_trace_api_fp, " \"module\" : \"%s\"},\n", dr_module_preferred_name(info));
530 | }
531 | }
532 | dr_symbol_export_iterator_stop(exp_iter);
533 | }
534 |
535 | static bool lib_is_not_blacklisted_trace_instr(const module_data_t* info) {
536 |
537 | char* blacklist[] = { "dynamorio.dll", "drmgr.dll", "ddr.dll", NULL };
538 | int i = 0;
539 | while (blacklist[i]) {
540 | if (strstr(dr_module_preferred_name(info), blacklist[i++]) != NULL)
541 | return FALSE;
542 | }
543 | return TRUE;
544 | }
545 |
546 | static unsigned char* get_byte_string_trace_instr(unsigned char* bytesbuf, size_t bytesread, size_t *resultstr_size) {
547 |
548 | if (bytesread < 1) return NULL;
549 |
550 | unsigned int i;
551 | unsigned char* bytestr = (unsigned char*)dr_global_alloc(sizeof(unsigned char) * (bytesread * 3 + 1));
552 | unsigned char* bytestr_tmp = bytestr;
553 | unsigned char c;
554 | for (i = 0; i < bytesread; i++) {
555 | c = *(bytesbuf + i);
556 | dr_snprintf(bytestr_tmp, 4, "%02x ", c);
557 | bytestr_tmp += 3;
558 | }
559 | unsigned char* charstr = (unsigned char*)dr_global_alloc(sizeof(unsigned char) * (bytesread + 1));
560 | unsigned char* charstr_tmp = charstr;
561 | for (i = 0; i < bytesread; i++) {
562 | c = *(bytesbuf + i);
563 | if ((c < 127) && (c > 31) && (c != 92) && (c != 34)) // exclude '\'=92 and "=34 for JSON comp.
564 | dr_snprintf(charstr_tmp++, 2, "%c", c);
565 | else
566 | dr_snprintf(charstr_tmp++, 2, ".");
567 | }
568 |
569 | *resultstr_size = strlen(bytestr) + strlen(charstr) + 3 + 1; //3 spaces in snprintf below
570 | unsigned char* resultstr = (unsigned char*)dr_global_alloc(sizeof(unsigned char) * (*resultstr_size));
571 | if (resultstr) {
572 | dr_snprintf(resultstr, *resultstr_size, "%s %s", bytestr, charstr);
573 |
574 | dr_global_free(bytestr, sizeof(unsigned char) * (bytesread * 3 + 1));
575 | dr_global_free(charstr, sizeof(unsigned char) * (bytesread + 1));
576 |
577 | return resultstr;
578 | }
579 | else {
580 | dr_printf("[DDR] [ERROR] Failed to allocate memory in get_byte_string_trace_instr.\n");
581 | dr_exit_process(1);
582 | }
583 | return NULL;
584 | }
585 |
586 | static void log_bytestream_trace_instr(file_t f, unsigned char* bytesbuf, size_t bytesread, app_pc memaddr, uint instr_mem_size) {
587 |
588 | size_t resultstr_size;
589 |
590 | char* bytesstr = get_byte_string_trace_instr(bytesbuf, bytesread, &resultstr_size);
591 |
592 | if (bytesstr) {
593 | dr_fprintf(f, " \"inst_mem_addr\" : \""PFX"\",\n", memaddr);
594 | dr_fprintf(f, " \"inst_mem_size\" : \""PFX"\",\n", instr_mem_size);
595 | dr_fprintf(f, " \"inst_mem_data\" : \"%s\",\n", bytesstr);
596 | dr_global_free(bytesstr, resultstr_size);
597 | }
598 | else {
599 | dr_fprintf(f, " \"inst_mem_addr\" : \""PFX"\",\n", memaddr);
600 | dr_fprintf(f, " \"inst_mem_size\" : \""PFX"\",\n", instr_mem_size);
601 | dr_fprintf(f, " \"inst_mem_data\" : \"NOT_DECODED\",\n");
602 | }
603 | }
604 |
605 | static bool write_mem_data_trace_instr(file_t f, size_t numbytes, app_pc memaddr, char* json_field_str) {
606 | char* bytesbuf, * bytesstr;
607 | size_t bytesread;
608 | size_t resultstr_size;
609 |
610 | bytesbuf = (char*)dr_global_alloc(sizeof(char) * numbytes);
611 | if (bytesbuf) {
612 | dr_safe_read(memaddr, numbytes, bytesbuf, &bytesread);
613 |
614 | bytesstr = get_byte_string_trace_instr(bytesbuf, bytesread, &resultstr_size);
615 | if (bytesstr) {
616 | // only add to JSON file if not NULL
617 | dr_fprintf(f, ",\n");
618 | dr_fprintf(f, " \"%s\" : \"%s\"", json_field_str, bytesstr);
619 | dr_global_free(bytesstr, resultstr_size);
620 | dr_global_free(bytesbuf, sizeof(char) * numbytes);
621 | return TRUE;
622 | }
623 | else {
624 | dr_global_free(bytesbuf, sizeof(char) * numbytes);
625 | return FALSE;
626 | }
627 | }
628 | else {
629 | dr_printf("[DDR] [ERROR] Failed to allocate memory in write_mem_data_trace_instr.");
630 | dr_exit_process(1);
631 | }
632 | return FALSE;
633 | }
634 |
635 | static bool write_mem_to_file_trace_instr(file_t f, ssize_t numbytes, app_pc memaddr) {
636 | char* bytesbuf;
637 | ssize_t bytesread;
638 | ssize_t byteswritten;
639 |
640 | bytesbuf = (char*)dr_global_alloc(sizeof(char) * numbytes);
641 | dr_safe_read(memaddr, numbytes, bytesbuf, &bytesread);
642 | dr_printf("[DDR] [INFO] Bytes read: %d\n", bytesread);
643 |
644 | byteswritten = dr_write_file(f, bytesbuf, numbytes);
645 | dr_printf("[DDR] [INFO] Bytes written: %d\n", byteswritten);
646 |
647 | if (bytesbuf) {
648 | dr_global_free(bytesbuf, sizeof(char) * numbytes);
649 | return FALSE;
650 | }
651 | }
652 |
653 | static void write_src_op_to_logfile_trace_instr(file_t f, instr_t* instr, app_pc memaddr_src0, size_t bytesread, size_t numbytes) {
654 |
655 | size_t memaddr_src0_ptr;
656 |
657 | dr_fprintf(f, " \"inst_mem_addr_src0\" : \""PFX"\"", memaddr_src0);
658 | write_mem_data_trace_instr(f, numbytes, memaddr_src0, "inst_mem_addr_src0_data");
659 | dr_safe_read(memaddr_src0, sizeof(size_t), &memaddr_src0_ptr, &bytesread);
660 | dr_fprintf(f, ",\n \"inst_mem_addr_src0_data_ptr\" : \""PFX"\"", memaddr_src0_ptr);
661 | write_mem_data_trace_instr(f, numbytes, (app_pc)memaddr_src0_ptr, "inst_mem_addr_src0_data_ptr_data");
662 |
663 | }
664 |
665 | static void log_instr_opnds_trace_instr(file_t f, instr_t* instr, dr_mcontext_t* mc, void* drcontext, size_t numbytes) {
666 |
667 | int num_dsts = 0, num_srcs = 0;
668 | opnd_t opnd_src0, opnd_dst0;
669 | app_pc memaddr_src0, memaddr_dst0;
670 | size_t memaddr_src0_ptr, memaddr_dst0_ptr;
671 | size_t bytesread = 0;
672 | reg_id_t reg;
673 |
674 | num_dsts = instr_num_dsts(instr);
675 | num_srcs = instr_num_srcs(instr);
676 |
677 | // --- handle memory access of special instructions --- :
678 |
679 | // direct call
680 | if (instr_is_call_direct(instr)) {
681 |
682 | opnd_src0 = instr_get_src(instr, 0);
683 |
684 | if (my_opnd_is_reg(opnd_src0)) {
685 | reg = opnd_get_reg(opnd_src0);
686 | memaddr_src0 = (app_pc)reg_get_value(reg, mc);
687 | }
688 | else {
689 | memaddr_src0 = opnd_get_pc(opnd_src0);
690 | }
691 | write_src_op_to_logfile_trace_instr(f, instr, memaddr_src0, bytesread, numbytes);
692 | return;
693 | }
694 | // indirect call
695 | if (instr_is_call_indirect(instr)) {
696 |
697 | opnd_src0 = instr_get_src(instr, 0);
698 | if (my_opnd_is_reg(opnd_src0)) {
699 | reg = opnd_get_reg(opnd_src0);
700 | memaddr_src0 = (app_pc)reg_get_value(reg, mc);
701 | }
702 | else {
703 | memaddr_src0 = my_opnd_compute_address(opnd_src0, mc);
704 | }
705 | write_src_op_to_logfile_trace_instr(f, instr, memaddr_src0, bytesread, numbytes);
706 | return;
707 | }
708 |
709 | // ret
710 | if (instr_is_return(instr)) {
711 |
712 | opnd_src0 = instr_get_src(instr, 0);
713 | if (my_opnd_is_reg(opnd_src0)) {
714 | reg = opnd_get_reg(opnd_src0);
715 | memaddr_src0 = (app_pc)reg_get_value(reg, mc);
716 | write_src_op_to_logfile_trace_instr(f, instr, memaddr_src0, bytesread, numbytes);
717 | }
718 |
719 | if (opnd_is_immed(opnd_src0)) {
720 | memaddr_src0 = (app_pc) opnd_get_immed_int(opnd_src0);
721 | write_src_op_to_logfile_trace_instr(f, instr, memaddr_src0, bytesread, numbytes);
722 | }
723 |
724 | return;
725 | }
726 |
727 | // unconditional direct branch (jmp, etc)
728 | if (instr_is_ubr(instr)) {
729 |
730 | opnd_src0 = instr_get_src(instr, 0);
731 | memaddr_src0 = opnd_get_pc(opnd_src0);
732 | write_src_op_to_logfile_trace_instr(f, instr, memaddr_src0, bytesread, numbytes);
733 | return;
734 | }
735 |
736 | // conditional branch
737 | if (instr_is_cbr(instr)) {
738 | if (light_trace_only) {
739 | // skip if jump is not taken
740 | if (!instr_jcc_taken(instr, mc->xflags)) {
741 | dr_file_seek(f, -2, DR_SEEK_CUR);
742 | dr_fprintf(f, "\n");
743 | return;
744 | }
745 | }
746 | opnd_src0 = instr_get_src(instr, 0);
747 | memaddr_src0 = opnd_get_pc(opnd_src0);
748 | write_src_op_to_logfile_trace_instr(f, instr, memaddr_src0, bytesread, numbytes);
749 | return;
750 | }
751 |
752 | // Don't log anything further if light_trace_only is set
753 | if (light_trace_only) {
754 | // Delete last comma
755 | dr_file_seek(f, -2, DR_SEEK_CUR);
756 | dr_fprintf(f, "\n");
757 | return;
758 | }
759 |
760 | // push
761 | if (instr_get_opcode(instr) == OP_push || instr_get_opcode(instr) == OP_push_imm) {
762 | opnd_src0 = instr_get_src(instr, 0);
763 |
764 | // operant is register
765 | if (my_opnd_is_reg(opnd_src0)) {
766 | reg = opnd_get_reg(opnd_src0);
767 | memaddr_src0 = (app_pc)reg_get_value(reg, mc); //TBD check typecast
768 | write_src_op_to_logfile_trace_instr(f, instr, memaddr_src0, bytesread, numbytes);
769 | return;
770 | }
771 | // anyhing else
772 | else {
773 | memaddr_src0 = my_opnd_compute_address(opnd_src0, mc);
774 | write_src_op_to_logfile_trace_instr(f, instr, memaddr_src0, bytesread, numbytes);
775 | return;
776 | }
777 | }
778 |
779 | // CMP
780 | if (instr_get_opcode(instr) == OP_cmp) {
781 | dr_fprintf(f, " \"inst_mem_instr_opname_cmp\" : \"%s\",\n", decode_opcode_name(instr_get_opcode(instr)));
782 |
783 | opnd_src0 = instr_get_src(instr, 0);
784 | opnd_dst0 = instr_get_src(instr, 1);
785 |
786 | // src operant is register
787 | if (my_opnd_is_reg(opnd_src0)) {
788 | reg = opnd_get_reg(opnd_src0);
789 | memaddr_src0 = (app_pc)reg_get_value(reg, mc); //TBD check typecast
790 | dr_fprintf(f, " \"inst_mem_addr_src0\" : \""PFX"\"", memaddr_src0);
791 | write_mem_data_trace_instr(f, numbytes, memaddr_src0, "inst_mem_addr_src0_data");
792 | dr_fprintf(f, ",\n");
793 | }
794 | // src operant is anyhing else
795 | else {
796 | memaddr_src0 = my_opnd_compute_address(opnd_src0, mc);
797 | dr_fprintf(f, " \"inst_mem_addr_src0\" : \""PFX"\"", memaddr_src0);
798 | write_mem_data_trace_instr(f, numbytes, memaddr_src0, "inst_mem_addr_src0_data");
799 | dr_fprintf(f, ",\n");
800 | }
801 |
802 | // dst operant is register
803 | if (my_opnd_is_reg(opnd_dst0)) {
804 | reg = opnd_get_reg(opnd_dst0);
805 | memaddr_dst0 = (app_pc)reg_get_value(reg, mc); //TBD check typecast
806 | dr_fprintf(f, " \"inst_mem_addr_dst0\" : \""PFX"\"", memaddr_dst0);
807 | write_mem_data_trace_instr(f, numbytes, memaddr_dst0, "inst_mem_addr_dst0_data");
808 | return;
809 | }
810 | // dst operant is anyhing else
811 | else {
812 | memaddr_dst0 = my_opnd_compute_address(opnd_dst0, mc);
813 | dr_fprintf(f, " \"inst_mem_addr_dst0\" : \""PFX"\"", memaddr_dst0);
814 | write_mem_data_trace_instr(f, numbytes, memaddr_dst0, "inst_mem_addr_dst0_data");
815 | return;
816 | }
817 | }
818 |
819 | // --- handle all other instructions --- :
820 | if (((num_dsts > 0) && (num_dsts < MAX_NUM_DSTS_OP)) || (num_srcs > 0) && (num_dsts < MAX_NUM_SRCS_OP))
821 | dr_fprintf(f, " \"inst_mem_instr_opname\" : \"%s\",\n", decode_opcode_name(instr_get_opcode(instr)));
822 | else
823 | dr_fprintf(f, " \"inst_mem_instr_opname\" : \"%s\"", decode_opcode_name(instr_get_opcode(instr)));
824 |
825 | // destination operant
826 | if ((num_dsts > 0) && (num_dsts < MAX_NUM_DSTS_OP)) { // '&& num_dsts < 3' covers dynamoRio bug
827 |
828 | opnd_dst0 = instr_get_dst(instr, 0);
829 |
830 | // op is register
831 | if (my_opnd_is_reg(opnd_dst0)) {
832 | reg = opnd_get_reg(opnd_dst0);
833 | memaddr_dst0 = (app_pc)reg_get_value(reg, mc);
834 | dr_fprintf(f, " \"inst_mem_addr_dst0\" : \""PFX"\"", memaddr_dst0);
835 | write_mem_data_trace_instr(f, numbytes, memaddr_dst0, "inst_mem_addr_dst0_data");
836 | }
837 | // op is not a register
838 | else {
839 | memaddr_dst0 = my_opnd_compute_address(opnd_dst0, mc);
840 | dr_fprintf(f, " \"inst_mem_addr_dst0\" : \""PFX"\"", memaddr_dst0);
841 | write_mem_data_trace_instr(f, numbytes, memaddr_dst0, "inst_mem_addr_dst0_data");
842 | }
843 |
844 | // the op is a memory reference
845 | if (opnd_is_memory_reference(opnd_dst0)) {
846 | dr_fprintf(f, ",\n");
847 | dr_safe_read(memaddr_dst0, sizeof(size_t), &memaddr_dst0_ptr, &bytesread);
848 | dr_fprintf(f, " \"inst_mem_addr_dst0_data_ptr\" : \""PFX"\"", memaddr_dst0_ptr);
849 | write_mem_data_trace_instr(f, numbytes, (app_pc)memaddr_dst0_ptr, "inst_mem_addr_dst0_data_ptr_data");
850 | }
851 |
852 | }
853 | // source operant
854 | if ((num_srcs > 0) && (num_dsts < MAX_NUM_SRCS_OP)) { // '&& num_dsts < 3' covers dynamoRio bug
855 | if ((num_dsts > 0) && (num_dsts < MAX_NUM_DSTS_OP))
856 | dr_fprintf(f, ",\n");
857 |
858 | opnd_src0 = instr_get_src(instr, 0);
859 |
860 | // op is register
861 | if (my_opnd_is_reg(opnd_src0)) {
862 | reg = opnd_get_reg(opnd_src0);
863 | memaddr_src0 = (app_pc)reg_get_value(reg, mc);
864 | dr_fprintf(f, " \"inst_mem_addr_src0\" : \""PFX"\"", memaddr_src0);
865 | write_mem_data_trace_instr(f, numbytes, memaddr_src0, "inst_mem_addr_src0_data");
866 | }
867 | // op is not a register
868 | else {
869 | memaddr_src0 = my_opnd_compute_address(opnd_src0, mc);
870 | dr_fprintf(f, " \"inst_mem_addr_src0\" : \""PFX"\"", memaddr_src0);
871 | write_mem_data_trace_instr(f, numbytes, memaddr_src0, "inst_mem_addr_src0_data");
872 | }
873 |
874 | // the op is a memory reference
875 | if (opnd_is_memory_reference(opnd_src0)) {
876 | dr_fprintf(f, ",\n");
877 | dr_safe_read(memaddr_src0, sizeof(size_t), &memaddr_src0_ptr, &bytesread);
878 | dr_fprintf(f, " \"inst_mem_addr_src0_data_ptr\" : \""PFX"\"", memaddr_src0_ptr);
879 | write_mem_data_trace_instr(f, numbytes, (app_pc)memaddr_src0_ptr, "inst_mem_addr_src0_data_ptr_data");
880 | }
881 |
882 | // --- Code for detecting an DynamoRIO bug with instr_t init ---
883 | if (num_dsts > MAX_NUM_DSTS_OP - 1) {
884 | dr_fprintf(f, "!! -- fail -- !!"); // break JSON format to generate error in IDA plugin, remove if you don't want this
885 | dr_fprintf(f, ",\n");
886 | dr_fprintf(f, " \"inst_mem_addr_dst0_fail\" : \"DR_BUG_DETECTED\",\n");
887 | dr_fprintf(f, " \"inst_mem_addr_dst0_num_dsts\" : \"%d\"", num_dsts);
888 | num_dsts = 0;
889 | }
890 | if (num_srcs > MAX_NUM_SRCS_OP - 1) {
891 | dr_fprintf(f, "!! -- fail -- !!"); // break JSON format to generate error in IDA plugin, remove if you don't want this
892 | dr_fprintf(f, ",\n");
893 | dr_fprintf(f, ",\n");
894 | dr_fprintf(f, " \"inst_mem_addr_src0_fail\" : \"DR_BUG_DETECTED\",\n");
895 | dr_fprintf(f, " \"inst_mem_addr_src0_num_srcs\" : \"%d\"", num_srcs);
896 | num_srcs = 0;
897 | }
898 | // --- End ---
899 |
900 | // --- Maybe used in a future feature ---
901 | /*
902 | if (opnd_is_abs_addr(opnd_src0))
903 | dr_fprintf(f, " \"opnd_is_abs_addr\" : \"true\"\n");
904 | if (opnd_is_immed(opnd_src0))
905 | dr_fprintf(f, " \"opnd_is_immed\" : \"true\"\n");
906 | if (opnd_is_memory_reference(opnd_src0))
907 | dr_fprintf(f, " \"opnd_is_memory_reference\" : \"true\"\n");
908 | if (opnd_is_rel_addr(opnd_src0))
909 | dr_fprintf(f, " \"opnd_is_rel_addr\" : \"true\"\n");
910 | if (opnd_is_pc(opnd_src0))
911 | dr_fprintf(f, " \"opnd_is_pc\" : \"true\"\n");
912 | */
913 | // --- End of maybe used in a future feature ---
914 | }
915 | }
916 |
917 | static void log_mem_at_reg_trace_instr(app_pc memaddr, char* regstr, file_t f) {
918 |
919 | size_t bytesread;
920 | size_t bytesbuf_len = 16;
921 | size_t resultstr_size;
922 | char* bytesstr;
923 | char* bytesbuf = (char*)dr_global_alloc(sizeof(char) * bytesbuf_len);
924 |
925 | if (dr_safe_read(memaddr, 16, bytesbuf, &bytesread)) {
926 |
927 | bytesstr = get_byte_string_trace_instr(bytesbuf, bytesread, &resultstr_size);
928 | if (bytesstr) {
929 | dr_fprintf(f, " \"%s_ptr_data\" : \"%s\",\n", regstr, bytesstr);
930 | dr_global_free(bytesstr, strlen(bytesstr) + 1);
931 | dr_global_free(bytesbuf, sizeof(char) * bytesbuf_len);
932 | return;
933 | }
934 | else {
935 | dr_global_free(bytesbuf, sizeof(char) * bytesbuf_len);
936 | }
937 | }
938 | dr_fprintf(f, " \"%s_ptr_data\" : \"NO_DATA\",\n", regstr);
939 | }
940 |
941 | static void handler_instr_is_return(file_t f, instr_t* instr, dr_mcontext_t* mc, size_t numbytes) {
942 | return;
943 | }
944 |
945 | static void handler_instr_is_call(file_t f, instr_t* instr, dr_mcontext_t* mc, size_t numbytes) {
946 | return;
947 | }
948 |
949 | static void handler_instr_is_pop(file_t f, instr_t* instr, dr_mcontext_t* mc, size_t numbytes) {
950 | return;
951 | }
952 |
953 | static void handler_instr_interesting_instr(file_t f, instr_t* instr, dr_mcontext_t* mc, size_t numbytes) {
954 | opnd_t op = instr_get_src(instr, 0);
955 | app_pc memaddr = my_opnd_compute_address(op, mc);
956 | size_t bytesread;
957 |
958 | uint instr_mem_size = instr_memory_reference_size(instr);
959 |
960 | char* bytesbuf = (char*)dr_global_alloc(sizeof(char) * numbytes);
961 | dr_safe_read(memaddr, numbytes, bytesbuf, &bytesread);
962 |
963 | log_bytestream_trace_instr(f, bytesbuf, bytesread, memaddr, instr_mem_size);
964 |
965 | dr_global_free(bytesbuf, sizeof(char) * numbytes);
966 | return;
967 | }
968 |
969 | static void handler_all_other_mem_instr(file_t f, instr_t* instr, dr_mcontext_t* mc, size_t numbytes) {
970 |
971 | opnd_t op = instr_get_src(instr, 0);
972 | app_pc memaddr = my_opnd_compute_address(op, mc);
973 | size_t bytesread;
974 |
975 | uint instr_mem_size = instr_memory_reference_size(instr);
976 |
977 | char* bytesbuf = (char*)dr_global_alloc(sizeof(char) * numbytes);
978 | dr_safe_read(memaddr, numbytes, bytesbuf, &bytesread);
979 |
980 | log_bytestream_trace_instr(f, bytesbuf, bytesread, memaddr, instr_mem_size);
981 |
982 | dr_global_free(bytesbuf, sizeof(char) * numbytes);
983 |
984 | return;
985 | }
986 |
987 |
988 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Debug/ddr_helper_functions.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Debug/ddr_helper_functions.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Debug/ddr_stable.Build.CppClean.log:
--------------------------------------------------------------------------------
1 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\vc142.pdb
2 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\vc142.idb
3 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\trace_instr.obj
4 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\patch_exe.obj
5 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\main.obj
6 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\dump_buffer1.obj
7 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\ddr_helper_functions.obj
8 | c:\tools\dev\git\dyndataresolver\ddr_client\x64\debug\ddr_stable.lib
9 | c:\tools\dev\git\dyndataresolver\ddr_client\x64\debug\ddr_stable.exp
10 | c:\tools\dev\git\dyndataresolver\ddr_client\x64\debug\ddr_stable.pdb
11 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\ddr_stable.tlog\cl.command.1.tlog
12 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\ddr_stable.tlog\cl.read.1.tlog
13 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\ddr_stable.tlog\cl.write.1.tlog
14 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\ddr_stable.tlog\ddr_stable.write.1u.tlog
15 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\ddr_stable.tlog\link.10364-cvtres.read.1.tlog
16 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\ddr_stable.tlog\link.10364-cvtres.write.1.tlog
17 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\ddr_stable.tlog\link.10364-rc.read.1.tlog
18 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\ddr_stable.tlog\link.10364-rc.write.1.tlog
19 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\ddr_stable.tlog\link.10364.read.1.tlog
20 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\ddr_stable.tlog\link.10364.write.1.tlog
21 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\ddr_stable.tlog\link.command.1.tlog
22 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\ddr_stable.tlog\link.read.1.tlog
23 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\debug\ddr_stable.tlog\link.write.1.tlog
24 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Debug/ddr_stable.dll.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | C:\tools\dev\git\DynDataResolver\ddr_client\x64\Debug\ddr_stable.dll
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Debug/ddr_stable.log:
--------------------------------------------------------------------------------
1 | ddr_helper_functions.c
2 | dump_buffer1.c
3 | main.c
4 | patch_exe.c
5 | trace_instr.c
6 | Generating Code...
7 | ddr_stable.vcxproj -> C:\tools\dev\git\DynDataResolver\ddr_client\x64\Debug\ddr_stable.dll
8 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Debug/ddr_stable.tlog/CL.command.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Debug/ddr_stable.tlog/CL.command.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Debug/ddr_stable.tlog/CL.read.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Debug/ddr_stable.tlog/CL.read.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Debug/ddr_stable.tlog/CL.write.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Debug/ddr_stable.tlog/CL.write.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Debug/ddr_stable.tlog/ddr_stable.lastbuildstate:
--------------------------------------------------------------------------------
1 | PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.28.29333:TargetPlatformVersion=10.0.18362.0:
2 | Debug|x64|C:\tools\dev\git\DynDataResolver\ddr_client\|
3 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Debug/ddr_stable.tlog/ddr_stable.write.1u.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Debug/ddr_stable.tlog/ddr_stable.write.1u.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Debug/ddr_stable.tlog/link.command.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Debug/ddr_stable.tlog/link.command.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Debug/ddr_stable.tlog/link.read.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Debug/ddr_stable.tlog/link.read.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Debug/ddr_stable.tlog/link.write.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Debug/ddr_stable.tlog/link.write.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Debug/ddr_stable.vcxproj.FileListAbsolute.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Debug/ddr_stable.vcxproj.FileListAbsolute.txt
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Debug/dump_buffer1.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Debug/dump_buffer1.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Debug/main.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Debug/main.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Debug/patch_exe.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Debug/patch_exe.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Debug/trace_instr.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Debug/trace_instr.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Debug/vc142.idb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Debug/vc142.idb
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Debug/vc142.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Debug/vc142.pdb
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Release/ddr_helper_functions.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Release/ddr_helper_functions.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Release/ddr_stable.Build.CppClean.log:
--------------------------------------------------------------------------------
1 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\release\vc142.pdb
2 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\release\trace_instr.obj
3 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\release\patch_exe.obj
4 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\release\main.obj
5 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\release\dump_buffer1.obj
6 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\release\ddr_helper_functions.obj
7 | c:\tools\dev\git\dyndataresolver\ddr_client\x64\release\ddr_stable.lib
8 | c:\tools\dev\git\dyndataresolver\ddr_client\x64\release\ddr_stable.exp
9 | c:\tools\dev\git\dyndataresolver\ddr_client\x64\release\ddr_stable.ipdb
10 | c:\tools\dev\git\dyndataresolver\ddr_client\x64\release\ddr_stable.iobj
11 | c:\tools\dev\git\dyndataresolver\ddr_client\x64\release\ddr_stable.dll
12 | c:\tools\dev\git\dyndataresolver\ddr_client\x64\release\ddr_stable.pdb
13 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\release\ddr_stable.tlog\cl.command.1.tlog
14 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\release\ddr_stable.tlog\cl.read.1.tlog
15 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\release\ddr_stable.tlog\cl.write.1.tlog
16 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\release\ddr_stable.tlog\ddr_stable.write.1u.tlog
17 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\release\ddr_stable.tlog\link.command.1.tlog
18 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\release\ddr_stable.tlog\link.read.1.tlog
19 | c:\tools\dev\git\dyndataresolver\ddr_client\ddr_stable\x64\release\ddr_stable.tlog\link.write.1.tlog
20 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Release/ddr_stable.dll.recipe:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | C:\tools\dev\git\DynDataResolver\ddr_client\x64\Release\ddr_stable.dll
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Release/ddr_stable.log:
--------------------------------------------------------------------------------
1 | ddr_helper_functions.c
2 | dump_buffer1.c
3 | main.c
4 | patch_exe.c
5 | trace_instr.c
6 | Creating library C:\tools\dev\git\DynDataResolver\ddr_client\x64\Release\ddr_stable.lib and object C:\tools\dev\git\DynDataResolver\ddr_client\x64\Release\ddr_stable.exp
7 | Generating code
8 | 11 of 56 functions (19.6%) were compiled, the rest were copied from previous compilation.
9 | 3 functions were new in current compilation
10 | 2 functions had inline decision re-evaluated but remain unchanged
11 | Finished generating code
12 | ddr_stable.vcxproj -> C:\tools\dev\git\DynDataResolver\ddr_client\x64\Release\ddr_stable.dll
13 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Release/ddr_stable.tlog/CL.command.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Release/ddr_stable.tlog/CL.command.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Release/ddr_stable.tlog/CL.read.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Release/ddr_stable.tlog/CL.read.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Release/ddr_stable.tlog/CL.write.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Release/ddr_stable.tlog/CL.write.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Release/ddr_stable.tlog/ddr_stable.lastbuildstate:
--------------------------------------------------------------------------------
1 | PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.28.29333:TargetPlatformVersion=10.0.18362.0:
2 | Release|x64|C:\tools\dev\git\DynDataResolver\ddr_client\|
3 |
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Release/ddr_stable.tlog/ddr_stable.write.1u.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Release/ddr_stable.tlog/ddr_stable.write.1u.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Release/ddr_stable.tlog/link.command.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Release/ddr_stable.tlog/link.command.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Release/ddr_stable.tlog/link.read.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Release/ddr_stable.tlog/link.read.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Release/ddr_stable.tlog/link.write.1.tlog:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Release/ddr_stable.tlog/link.write.1.tlog
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Release/ddr_stable.vcxproj.FileListAbsolute.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Release/ddr_stable.vcxproj.FileListAbsolute.txt
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Release/dump_buffer1.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Release/dump_buffer1.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Release/main.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Release/main.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Release/patch_exe.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Release/patch_exe.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Release/trace_instr.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Release/trace_instr.obj
--------------------------------------------------------------------------------
/ddr_client/ddr_stable/x64/Release/vc142.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/ddr_stable/x64/Release/vc142.pdb
--------------------------------------------------------------------------------
/ddr_client/x64/Debug/ddr_stable.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/x64/Debug/ddr_stable.dll
--------------------------------------------------------------------------------
/ddr_client/x64/Debug/ddr_stable.exp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/x64/Debug/ddr_stable.exp
--------------------------------------------------------------------------------
/ddr_client/x64/Debug/ddr_stable.ilk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/x64/Debug/ddr_stable.ilk
--------------------------------------------------------------------------------
/ddr_client/x64/Debug/ddr_stable.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/x64/Debug/ddr_stable.lib
--------------------------------------------------------------------------------
/ddr_client/x64/Debug/ddr_stable.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/x64/Debug/ddr_stable.pdb
--------------------------------------------------------------------------------
/ddr_client/x64/Release/ddr_stable.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/x64/Release/ddr_stable.dll
--------------------------------------------------------------------------------
/ddr_client/x64/Release/ddr_stable.exp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/x64/Release/ddr_stable.exp
--------------------------------------------------------------------------------
/ddr_client/x64/Release/ddr_stable.iobj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/x64/Release/ddr_stable.iobj
--------------------------------------------------------------------------------
/ddr_client/x64/Release/ddr_stable.ipdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/x64/Release/ddr_stable.ipdb
--------------------------------------------------------------------------------
/ddr_client/x64/Release/ddr_stable.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/x64/Release/ddr_stable.lib
--------------------------------------------------------------------------------
/ddr_client/x64/Release/ddr_stable.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_client/x64/Release/ddr_stable.pdb
--------------------------------------------------------------------------------
/ddr_installer.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_installer.zip
--------------------------------------------------------------------------------
/ddr_installer/DDR_INSTALLER.py:
--------------------------------------------------------------------------------
1 | #-------------------------------------------------------------------------------
2 | #
3 | # IDA Pro Plug-in: Dynamic Data Resolver (DDR) Server Installer script
4 | #
5 | # Version 1.0
6 | #
7 | # Copyright (C) 2020 Cisco Talos
8 | # Author: Holger Unterbrink (hunterbr@cisco.com)
9 | #
10 | # This program is free software; you can redistribute it and/or modify
11 | # it under the terms of the GNU General Public License as published by
12 | # the Free Software Foundation; either version 2 of the License, or
13 | # (at your option) any later version.
14 | #
15 | # This program is distributed in the hope that it will be useful,
16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | # GNU General Public License for more details.
19 | #
20 | # You should have received a copy of the GNU General Public License along
21 | # with this program; if not, write to the Free Software Foundation, Inc.,
22 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 | #
24 | # ------------------------------------------------------------------------------
25 | #
26 | # Hint: This script does not have any dependencies. All non default dependencies
27 | # will be installed into a virtual envirmoent at run time.
28 | #
29 | # ------------------------------------------------------------------------------
30 |
31 | import venv
32 | import os
33 | import sys
34 | import subprocess
35 | import pathlib
36 | import time
37 | import os
38 | import sys
39 | import subprocess
40 | import importlib
41 | import tempfile
42 | import zipfile
43 | import glob
44 | import shutil
45 | import string
46 | import random
47 | import re
48 | import platform
49 | from distutils.dir_util import copy_tree
50 |
51 | # IDA DDR plugin globals
52 | IDA_PLUGIN_ZIP = "ddr_plugin.zip"
53 | DDR_PLUGIN_SRCPATH = "ddr_plugin"
54 | IDA_DEFAULT_INSTALL_DIR = os.getenv('ProgramW6432') + "\\IDA Pro 7.5"
55 | IDA_DEFAULT_PLUGIN_DIR = os.getenv('APPDATA') + "\\Hex-Rays\\IDA Pro\\plugins"
56 | IDA_DEFAULT_PYTHON_PATH = os.getenv('ProgramW6432') + "\\Python38"
57 |
58 | # DDR Server
59 | DYNRIO_DOWNLOAD_URL = r"https://github.com/DynamoRIO/dynamorio/releases/download/release_8.0.0-1/DynamoRIO-Windows-8.0.0-1.zip"
60 | #DYNRIO_DOWNLOAD_URL_LATEST = r"https://github.com/DynamoRIO/dynamorio/releases/download/cronbuild-8.0.18547/DynamoRIO-Windows-8.0.18547.zip"
61 | DYNRIO_DOWNLOAD_URL_LATEST = r"https://github.com/DynamoRIO/dynamorio/releases/download/cronbuild-8.0.18585/DynamoRIO-Windows-8.0.18585.zip"
62 | DDRSERVER_CONFIG_FILE_TEMPLATE = "templates\\ddr_server_template.json"
63 | DDRSERVER_CONFIG_FILE = "ddr_server.cfg"
64 | DDRSERVER_VERSION = "1.02 beta"
65 | APILOGGING = "DEBUG"
66 | DEBUG_API_JSON = "false"
67 | MY_FQDN = "malwarehost.local" # only used as name in the certificate, no DNS required.
68 | MAX_CFG_LINE_LENGTH = 356
69 | DDR_DLL32 = "ddr32.dll"
70 | DDR_DLL64 = "ddr64.dll"
71 | DDR_CERT_FILENAME = "ddr_server.crt"
72 | DDR_CERT_KEY_FILENAME = "ddr_server.key"
73 | DDR_APIKEY_FILE = "ddr_apikey.txt"
74 | DDR_APIKEY = "not set"
75 | DDR_VIRTENV_NAME = "ddr_venv"
76 | MAX_INSTALL_DIR = 160
77 | DDR_SERVER_IP = "0.0.0.0"
78 | DDR_SERVER_PORT = "5000"
79 |
80 | def proceed(question):
81 | """
82 | Do you want to proceed [Y/n]. Returns True if 'yes' and False if 'no'
83 | """
84 | valid = ["y"]
85 |
86 | while True:
87 | sys.stdout.write(question)
88 | choice = input().lower()
89 | if choice == '':
90 | return True
91 | elif choice == 'y':
92 | return True
93 | else:
94 | return False
95 |
96 | def is_venv():
97 | """
98 | Do we run in a virtual enviroment
99 | """
100 | return (hasattr(sys, 'real_prefix') or
101 | (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix))
102 |
103 | def get_ida_dir():
104 | print("[DDR_PLUGIN_INSTALLER][INFO] Please enter the IDA installation directory.")
105 | print("[DDR_PLUGIN_INSTALLER][INFO] Default is {}".format(IDA_DEFAULT_INSTALL_DIR))
106 | ida_dir = input("[DDR_PLUGIN_INSTALLER][INFO] IDA installation directory: ") or IDA_DEFAULT_INSTALL_DIR
107 | print()
108 | return ida_dir
109 |
110 | def get_ida_plugin_dir():
111 | print("[DDR_PLUGIN_INSTALLER][INFO] Please go to IDA and find out where the user plugin directory is.")
112 | print("[DDR_PLUGIN_INSTALLER][INFO] You can do that by entering the follwing into the Python command prompt of IDA:")
113 | print("[DDR_PLUGIN_INSTALLER][INFO] print(os.path.join(idaapi.get_user_idadir(), \"plugins\"))")
114 | print("[DDR_PLUGIN_INSTALLER][INFO] Default plugin directory is {}".format(IDA_DEFAULT_PLUGIN_DIR))
115 | ida_plugin_dir = input("[DDR_PLUGIN_INSTALLER][INFO] IDA plugin directory: ") or IDA_DEFAULT_PLUGIN_DIR
116 | print()
117 | return ida_plugin_dir
118 |
119 | def get_ida_python_version():
120 | print("[DDR_PLUGIN_INSTALLER][INFO] Please go to IDA and find out which Python version IDA is using.")
121 | print("[DDR_PLUGIN_INSTALLER][INFO] You can do that by entering the follwing into the Python command prompt of IDA:")
122 | print("[DDR_PLUGIN_INSTALLER][INFO] print(sys.exec_prefix)")
123 | print("[DDR_PLUGIN_INSTALLER][INFO] Default plugin directory is {}".format(IDA_DEFAULT_PYTHON_PATH))
124 | ida_python_path = input("[DDR_PLUGIN_INSTALLER][INFO] Please enter the IDA Python directory path: ") or IDA_DEFAULT_PYTHON_PATH
125 | print()
126 | return ida_python_path
127 |
128 | def create_apikey(apikey_file):
129 | """
130 | Generate API key
131 | """
132 | global DDR_APIKEY
133 |
134 | try:
135 | DDR_APIKEY = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(24))
136 | with open(apikey_file, "w") as text_file:
137 | text_file.write("{}".format(DDR_APIKEY))
138 | print("[DDR_INSTALLER][INFO] --------------------------------------------------------------------------------")
139 | print("[DDR_INSTALLER][INFO] Generated new API Key and wrote it to {}".format(apikey_file))
140 | print("[DDR_INSTALLER][INFO] --------------------------------------------------------------------------------\n")
141 | return True
142 | except:
143 | print("[DDR_INSTALLER][ERROR] Genrating API Key file {} failed.".format(apikey_file))
144 | raise
145 | return False
146 |
147 | def create_self_signed_cert(my_ipaddr, cert_file, key_file):
148 | """
149 | Create self signed certificate and key
150 | """
151 |
152 | print("We need a serial number for the certificate.")
153 | print("If this is the first time you are generating and using the certificate,")
154 | print("you can use the default number (1001). If this is not the first time, ")
155 | print("you should pick a higher number than you used the last time. Otherwise,")
156 | print("you might run into serial number re-use issues with some browsers.")
157 | cert_serial = input("Please enter the serial number for the certificate (Default: 1001) :") or "1001"
158 | cert_serial = int(cert_serial)
159 |
160 | # create a key pair
161 | k = OpenSSL.crypto.PKey()
162 | k.generate_key(OpenSSL.crypto.TYPE_RSA, 1024)
163 |
164 | # create a self-signed cert
165 | cert = OpenSSL.crypto.X509()
166 | cert.get_subject().C = "DE" # country of residence
167 | cert.get_subject().ST = "Berlin" # state of residence
168 | cert.get_subject().L = "SomeLocality" # locality
169 | cert.get_subject().O = "Talos" # organization
170 | cert.get_subject().OU = "Security" # organizational unit
171 | cert.get_subject().CN = my_ipaddr # common name IP or FQDN
172 | san_list = ["IP:" + my_ipaddr, "DNS:" + my_ipaddr] # subjectAltName list
173 | cert.add_extensions([ OpenSSL.crypto.X509Extension(b'subjectAltName', False, bytes(', '.join(san_list), 'utf-8'))])
174 | cert.set_serial_number(1001)
175 | cert.gmtime_adj_notBefore(0)
176 | cert.gmtime_adj_notAfter(10*365*24*60*60)
177 | cert.set_issuer(cert.get_subject())
178 | cert.set_pubkey(k)
179 | cert.sign(k, 'sha1')
180 | open(cert_file, "wt").write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert).decode())
181 | open(key_file, "wt").write(OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, k).decode())
182 |
183 | print("")
184 | print("[DDR_INSTALLER][INFO] -------------------------------------------------------------")
185 | print("[DDR_INSTALLER][INFO] Individual self signed certificate and secret key generated. ")
186 | print("[DDR_INSTALLER][INFO] DDR will use these credentials to encrypt the HTTPS traffic ")
187 | print("[DDR_INSTALLER][INFO] between the DDR IDA plugin and the DDR server. ")
188 | print("[DDR_INSTALLER][INFO] -------------------------------------------------------------")
189 |
190 |
191 | def load_mod(mod_name):
192 | """
193 | Load modules at runtime by name stored in variable
194 | """
195 | globals()[mod_name] = importlib.import_module(mod_name)
196 |
197 | def runcmd(my_cmd):
198 | """
199 | Execute shell command
200 | """
201 |
202 | print("[DDR_INSTALLER][INFO] Executing cmd: \n{}\n".format(my_cmd))
203 |
204 | stdout = False
205 | stderr = False
206 |
207 | try:
208 | #process = subprocess.Popen(my_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
209 | #stdout, stderr = process.communicate()
210 | process = subprocess.run(my_cmd)
211 |
212 | if process.returncode != 0:
213 | print("\n[DDR_INSTALLER][WARNING] Command execution failed. Error code: {:d}".format(process.returncode))
214 | ret = False
215 | else:
216 | ret = True
217 |
218 | # if stderr:
219 | # print("[DDR_INSTALLER][WARNING] Command execution failed. Stderr:")
220 | # print("{}".format(stderr.decode("utf-8")))
221 |
222 | # ret['stderr'] = stderr
223 | # ret['status'] = False
224 |
225 | # if stdout:
226 | # print("[DDR_INSTALLER][INFO] Command execution stdout:")
227 | # print("{}".format(stdout.decode("utf-8")))
228 |
229 | # ret['stdout'] = stdout
230 | # ret['status'] = True
231 |
232 | except :
233 | print("[DDR_INSTALLER][ERROR] Exception: Command execution failed with unknown error.")
234 | ret = False
235 |
236 | return ret
237 |
238 | def check_files_exist(files = [], dirs = []):
239 | """
240 | Verify if the files and dirs configured exist
241 | """
242 | ret = True
243 |
244 | for dir in dirs:
245 | if not os.path.isdir(dir):
246 | print("[DDR_INSTALLER][ERROR] Directory: {} not found.".format(dir))
247 | ret = False
248 |
249 | for fname in files:
250 | if not os.path.isfile(fname):
251 | print("[DDR_INSTALLER][ERROR] File: {} not found.".format(fname))
252 | ret = False
253 |
254 | return ret
255 |
256 | def zip_is_valid(zipfilename):
257 | """
258 | Check if zipfilename is a valid zip file. Return True if valid. False if not valid.
259 | """
260 |
261 | if not os.path.isfile(zipfilename):
262 | print("[DDR_INSTALLER][ERROR] Zip file not found.")
263 | return False
264 |
265 | try:
266 | zip_file = zipfile.ZipFile(zipfilename)
267 | res = zip_file.testzip()
268 |
269 | if res is not None:
270 | print("[DDR_INSTALLER][ERROR] Bad file in zip archive: {}".format(res))
271 | return False
272 | else:
273 | return True
274 | except:
275 | print("[DDR_INSTALLER][ERROR] Zip file: {} is corrupt.".format(zipfilename))
276 | os.remove(zipfilename)
277 | print("[DDR_INSTALLER][ERROR] Corrupt zip file: {} deleted.".format(zipfilename))
278 | return False
279 |
280 | def download_zip_and_unpack(unpack_dir, url):
281 | """
282 | Download zip file from url and unpack it to directory unpack_dir. Verify if zip file is valid.
283 | Return True if successfully downloaded file and deleted the temp. files.
284 | Return False if anything went wrong.
285 | """
286 | print("Downloading from url: {}".format(url))
287 | zipfilename = tempfile.gettempdir() + "\\tmp.zip"
288 |
289 | with requests.get(url, stream=True) as res:
290 | if res.status_code == 200:
291 | with open(zipfilename, 'wb') as f:
292 | total_length = int(res.headers.get('content-length'))
293 | for chunk in clint.textui.progress.bar(res.iter_content(chunk_size=1024), expected_size=(total_length/1024) + 1):
294 | if chunk:
295 | f.write(chunk)
296 | f.flush()
297 | print("\n[DDR_INSTALLER] [INFO] File downloaded.")
298 | else:
299 | print("[DDR_INSTALLER] [ERROR] Download failed.")
300 |
301 | # Verify zip file is valid
302 | if not zip_is_valid(zipfilename):
303 | print("[DDR_INSTALLER] [ERROR] Zip file verification failed.")
304 | return False
305 |
306 | # check if unpack_dir exists otherwise create it
307 | pathlib.Path(unpack_dir).mkdir(parents=True, exist_ok=True)
308 |
309 | # Extract files from zip archive
310 | with zipfile.ZipFile(zipfilename, "r") as ziparchive:
311 | print("[DDR_INSTALLER] [INFO] Extracting files to {}".format(unpack_dir))
312 | ziparchive.extractall(unpack_dir)
313 |
314 | # Delete zip archive
315 | print("[DDR_INSTALLER] [INFO] Deleting downloaded archive: {}".format(zipfilename))
316 | try:
317 | os.remove(zipfilename)
318 | except:
319 | print("[DDR_INSTALLER] [ERROR] Failed to delete zip file: {}".format(zipfilename))
320 | pass
321 |
322 | return True
323 |
324 | def cpu_is_AMD():
325 | """
326 | Check if CPU is from AMD
327 | """
328 | cpu = platform.processor()
329 |
330 | if "amd" in cpu.lower():
331 | return True
332 |
333 | return False
334 |
335 |
336 | def install_deps(venv, ddr_default_dir):
337 | """
338 | Main installer routine to install all neccessary
339 | dependencies for DDR
340 | """
341 |
342 | global DDR_SERVER_IP
343 | global DDR_SERVER_PORT
344 |
345 | # update pip in virtual enviroment
346 | print("[DDR_INSTALLER][INFO] Updating pip in virtual enviroment.")
347 | my_cmd = venv + "\\Scripts\\activate.bat && " + "python -m pip install --upgrade pip"
348 | if runcmd(my_cmd):
349 | print("[DDR_INSTALLER][INFO] pip updated.")
350 | else:
351 | print("Failed to update pip.")
352 | return False
353 |
354 | # Install pip tools
355 | print("[DDR_INSTALLER][INFO] Installing pip-tools.")
356 | my_cmd = venv + "\\Scripts\\activate.bat && " + "pip install --upgrade pip-tools"
357 | if runcmd(my_cmd):
358 | print("[DDR_INSTALLER][INFO] pip tools installed.")
359 | else:
360 | print("Failed to install pip tools.")
361 | return False
362 |
363 | # Sync DDR Python dependencies
364 | # https://stackoverflow.com/questions/10333814/tell-pip-to-install-the-dependencies-of-packages-listed-in-a-requirement-file
365 | #
366 | print("[DDR_INSTALLER][INFO] Installing DDR Python dependencies.")
367 | my_cmd = venv + "\\Scripts\\activate.bat && " + "pip-sync"
368 | if runcmd(my_cmd):
369 | print("[DDR_INSTALLER][INFO] DDR Python dependencies installed and synchronized.")
370 | else:
371 | print("Failed to install DDR Python dependencies.")
372 | return False
373 |
374 | # Load non standard modules
375 | load_mod("requests")
376 | load_mod("clint")
377 |
378 | # Install DynamoRio
379 | if proceed("Should we proceed with downloading and installing DynamoRio to {} [Y/n] ?".format(ddr_default_dir)):
380 | if cpu_is_AMD():
381 | print("[DDR_INSTALLER][WARNING] It seems to be you have an AMD CPU. There is a AMD CPU which makes DynamoRio fail in WOW64 operations.")
382 | print("[DDR_INSTALLER][WARNING] Details can be found here: https://github.com/DynamoRIO/dynamorio/issues/4091#")
383 | print("[DDR_INSTALLER][WARNING] with an AMD processor it is highly recommend to use the latest DynamoRio GIT version.")
384 |
385 | if proceed("Should we install the weekly package (recommended - includes AMD CPU bug fix) or the latest stable release. [W/S] ? ".format(ddr_default_dir)):
386 | print("[DDR_INSTALLER][WARNING] Installing weekly DynamoRio package:\n{}".format(DYNRIO_DOWNLOAD_URL_LATEST))
387 | download_zip_and_unpack(ddr_default_dir, DYNRIO_DOWNLOAD_URL_LATEST)
388 | else:
389 | print("[DDR_INSTALLER][WARNING] Installing latest stable DynamoRio package:\n{}".format(DYNRIO_DOWNLOAD_URL_LATEST))
390 | download_zip_and_unpack(ddr_default_dir, DYNRIO_DOWNLOAD_URL)
391 |
392 | try:
393 | dynrio_path = glob.glob(ddr_default_dir + '\\DynamoRIO-Windows*')[0]
394 | dynrio_run32 = dynrio_path + "\\bin32\\drrun.exe"
395 | dynrio_run64 = dynrio_path + "\\bin64\\drrun.exe"
396 | except:
397 | print("[DDR_INSTALLER][ERROR] DynamoRio installation not found.")
398 | return False
399 |
400 | if not check_files_exist(dirs = [dynrio_path]):
401 | print("[DDR_INSTALLER][ERROR] DynamoRio directory does not exist. Installation failed.")
402 | return False
403 | else:
404 | print("[DDR_INSTALLER][INFO] DynamoRio directory found.")
405 |
406 | if not check_files_exist(files = [dynrio_run32, dynrio_run64]):
407 | print("[DDR_INSTALLER][ERROR] DynamoRio drrun file(s) do not exist. Installation failed.")
408 | return False
409 | else:
410 | print("[DDR_INSTALLER][INFO] DynamoRio run binaries found.\n")
411 |
412 | # Network setup
413 | print("[DDR_INSTALLER][INFO] Network setup:")
414 |
415 | DDR_SERVER_PORT = input("[DDR_INSTALLER][INFO] Please enter server PORT to listen on (Default is 5000) :") or "5000"
416 |
417 | process = subprocess.run("ipconfig",stdout=subprocess.PIPE, stderr=subprocess.PIPE)
418 | data = process.stdout.decode()
419 | ip_list = re.findall(r'IPv4 Address.*: (\d+\.\d+\.\d+\.\d+)',data)
420 | ip_list = [(ip) for ip in ip_list if not ip.startswith("255")]
421 |
422 | if not ip_list:
423 | print("[DDR_INSTALLER][WARNING] Didn't find any local IP addresses on this machine.")
424 | print("[DDR_INSTALLER][WARNING] Keep in mind this address needs to be reachable from the DDR IDA plugin.")
425 | DDR_SERVER_IP = input("[DDR_INSTALLER][INFO] Pls enter the server IP address manually: ")
426 |
427 | else:
428 | print("[DDR_INSTALLER][INFO] Found the following IP addresses:")
429 | for num, ip in enumerate(ip_list):
430 | print("[{:d}] {}".format(num,ip))
431 |
432 | DDR_SERVER_IP = input("[DDR_INSTALLER][INFO] Please choose server IP address (Default is 0) :") or "0"
433 | DDR_SERVER_IP = ip_list[int(DDR_SERVER_IP)]
434 |
435 | if DDR_SERVER_IP == "":
436 | print("[DDR_INSTALLER][ERROR] No server IP address found.")
437 | exit(1)
438 |
439 | print("[DDR_INSTALLER][INFO] server will listen on {}:{}".format(DDR_SERVER_IP, DDR_SERVER_PORT))
440 |
441 | # Create Certificates and copy them to server directory
442 | ddr_escaped_default_dir = ddr_default_dir.replace("\\","\\\\")
443 | ddr_cert_file = ddr_escaped_default_dir + "\\\\" + DDR_CERT_FILENAME
444 | ddr_key_file = ddr_escaped_default_dir + "\\\\" + DDR_CERT_KEY_FILENAME
445 | load_mod("OpenSSL")
446 | create_self_signed_cert(DDR_SERVER_IP, ddr_cert_file, ddr_key_file)
447 |
448 | # Create DDR server API key file
449 | apikey_file = ddr_default_dir + "\\" + DDR_APIKEY_FILE
450 | escapced_apikey_file = apikey_file.replace("\\","\\\\")
451 | if not create_apikey(apikey_file):
452 | return False
453 |
454 | # Create DDR server config file
455 | with open(DDRSERVER_CONFIG_FILE_TEMPLATE, 'r') as f:
456 | ddrserver_cfg_file = f.read()
457 |
458 | escaped_dynrio_run32 = dynrio_run32.replace("\\","\\\\")
459 | escaped_dynrio_run64 = dynrio_run64.replace("\\","\\\\")
460 | escaped_venv = venv.replace("\\","\\\\")
461 |
462 | ddrserver_cfg_file = ddrserver_cfg_file.replace("" , DDRSERVER_VERSION)
463 | ddrserver_cfg_file = ddrserver_cfg_file.replace("" , APILOGGING)
464 | ddrserver_cfg_file = ddrserver_cfg_file.replace("" , DEBUG_API_JSON)
465 | ddrserver_cfg_file = ddrserver_cfg_file.replace("" , DDR_CERT_FILENAME)
466 | ddrserver_cfg_file = ddrserver_cfg_file.replace("" , DDR_CERT_KEY_FILENAME)
467 | ddrserver_cfg_file = ddrserver_cfg_file.replace("" , DDR_APIKEY_FILE)
468 | ddrserver_cfg_file = ddrserver_cfg_file.replace("" , DDR_SERVER_IP)
469 | ddrserver_cfg_file = ddrserver_cfg_file.replace("" , DDR_SERVER_PORT)
470 | ddrserver_cfg_file = ddrserver_cfg_file.replace("" , MY_FQDN)
471 | ddrserver_cfg_file = ddrserver_cfg_file.replace("" , ddr_escaped_default_dir)
472 | ddrserver_cfg_file = ddrserver_cfg_file.replace("" , escaped_venv)
473 | ddrserver_cfg_file = ddrserver_cfg_file.replace("" , str(MAX_CFG_LINE_LENGTH))
474 | ddrserver_cfg_file = ddrserver_cfg_file.replace("" , escaped_dynrio_run32)
475 | ddrserver_cfg_file = ddrserver_cfg_file.replace("" , ddr_escaped_default_dir + "\\\\" + DDR_DLL32)
476 | ddrserver_cfg_file = ddrserver_cfg_file.replace("" , escaped_dynrio_run64)
477 | ddrserver_cfg_file = ddrserver_cfg_file.replace("" , ddr_escaped_default_dir + "\\\\" + DDR_DLL64)
478 |
479 | # save individualized config file
480 | ddrserver_cfg_filename = ddr_default_dir + "\\" + DDRSERVER_CONFIG_FILE
481 | with open(ddrserver_cfg_filename, 'w') as f:
482 | f.write(ddrserver_cfg_file)
483 | print("[DDR_INSTALLER][INFO] Wrote DDR server configuration to {}".format(ddrserver_cfg_filename))
484 |
485 | # copy DDR files to installation directory
486 | filename_list = [ "ddr_server.py", DDR_DLL32, DDR_DLL64]
487 | for fn in filename_list:
488 | shutil.copyfile( "install_data\\" + fn, ddr_default_dir + "\\" + fn)
489 | print("[DDR_INSTALLER][INFO] Copied file: {}".format(fn))
490 |
491 | return True
492 |
493 | def built_plugin_zip(ddr_default_dir):
494 |
495 | ida_plugin_tmp = "install_data\\ddr_plugin"
496 | ida_plugin_cfg_template = "templates\\ddr_config_template.json"
497 | ida_plugin_install_template = "templates\\ida_plugin_installer_template.py"
498 | ida_install_dir = get_ida_dir()
499 | ida_plugin_dir = get_ida_plugin_dir()
500 | ida_python_path = get_ida_python_version()
501 |
502 | print("[DDR_INSTALLER][INFO] Using the following directories:")
503 | print("[DDR_INSTALLER][INFO] IDA install dir: {}".format(ida_install_dir))
504 | print("[DDR_INSTALLER][INFO] IDA plugin dir : {}".format(ida_plugin_dir))
505 | print("[DDR_INSTALLER][INFO] IDA Python dir : {}\n".format(ida_python_path))
506 |
507 | if not proceed("[DDR_INSTALLER][INFO] Is this correct ? [Y/n]"):
508 | exit(1)
509 |
510 | # copy plugin, plugin config file and cert file
511 | filename_list = [ "ddr_server.crt" ]
512 | os.makedirs(ida_plugin_tmp + "\\ddr", exist_ok=True)
513 | for fn in filename_list:
514 | cf = shutil.copyfile(ddr_default_dir + "\\" + fn, ida_plugin_tmp + "\\ddr\\" + fn)
515 | print("[DDR_INSTALLER][INFO] Copied file: {}".format(cf))
516 |
517 | cf = shutil.copyfile("install_data\\ddr_plugin.py", ida_plugin_tmp + "\\ddr_plugin.py")
518 | print("[DDR_INSTALLER][INFO] Copied file: {}".format(cf))
519 |
520 | # Create DDR plugin config file
521 | with open(ida_plugin_cfg_template, 'r') as f:
522 | ddrplugin_cfg_file = f.read()
523 |
524 | ida_plugin_dir_escaped = ida_plugin_dir.replace("\\", "\\\\")
525 |
526 | ddrplugin_cfg_file = ddrplugin_cfg_file.replace("" , DDR_SERVER_IP)
527 | ddrplugin_cfg_file = ddrplugin_cfg_file.replace("" , DDR_SERVER_PORT)
528 | ddrplugin_cfg_file = ddrplugin_cfg_file.replace("" , DDR_APIKEY)
529 | ddrplugin_cfg_file = ddrplugin_cfg_file.replace("" , ida_plugin_dir_escaped + "\\\\ddr\\\\" + DDR_CERT_FILENAME)
530 | ddrplugin_cfg_file = ddrplugin_cfg_file.replace("" , "true")
531 | ddrplugin_cfg_file = ddrplugin_cfg_file.replace("" , "tmp_dump.cfg")
532 | ddrplugin_cfg_file = ddrplugin_cfg_file.replace("" , "30.0")
533 | ddrplugin_cfg_file = ddrplugin_cfg_file.replace("" , "2")
534 | ddrplugin_cfg_file = ddrplugin_cfg_file.replace("", "20000")
535 | ddrplugin_cfg_file = ddrplugin_cfg_file.replace("" , "5")
536 | ddrplugin_cfg_file = ddrplugin_cfg_file.replace("" , "3")
537 | ddrplugin_cfg_file = ddrplugin_cfg_file.replace("" , "50")
538 | ddrplugin_cfg_file = ddrplugin_cfg_file.replace("" , "3")
539 |
540 | ddrplugin_cfg_filename = ida_plugin_tmp + "\\ddr\\ddr_config.json"
541 |
542 | with open(ddrplugin_cfg_filename, 'w') as f:
543 | f.write(ddrplugin_cfg_file)
544 |
545 | print("[DDR_INSTALLER][INFO] Created IDA DDR plugin config file: {}".format(ddrplugin_cfg_filename))
546 |
547 | # Create plugin installer python script
548 | with open(ida_plugin_install_template, 'r') as f:
549 | ddrplugin_install_script = f.read()
550 |
551 | ddrplugin_install_script = ddrplugin_install_script.replace("" , ida_install_dir)
552 | ddrplugin_install_script = ddrplugin_install_script.replace("" , ida_plugin_dir)
553 | ddrplugin_install_script = ddrplugin_install_script.replace("" , ida_python_path)
554 |
555 | ddrplugin_install_script_filename = ida_plugin_tmp + "\\ida_plugin_installer.py"
556 |
557 | with open(ddrplugin_install_script_filename, 'w') as f:
558 | f.write(ddrplugin_install_script)
559 | print("[DDR_INSTALLER][INFO] Created IDA DDR plugin installer script: {}".format(ddrplugin_install_script_filename))
560 |
561 | #Copy test files
562 | test_samples_dir = ida_plugin_tmp + "\\ddr\\ddr_test_samples"
563 | os.makedirs(test_samples_dir, exist_ok=True)
564 | cf = copy_tree("ddr_test_samples", test_samples_dir)
565 |
566 | print("Copied test samples to:")
567 | for copied_file in cf:
568 | print(copied_file)
569 |
570 | # Create ZIP archive
571 | res = shutil.make_archive(ida_plugin_tmp, 'zip', ida_plugin_tmp)
572 |
573 | print("\n[DDR_INSTALLER][INFO] Created IDA DDR plugin zip archive: {}\n".format(ddrplugin_cfg_filename))
574 |
575 | def installer_done():
576 | """
577 | Finalize installation and start DDR server in virtual environment.
578 | """
579 | print("\n")
580 | print("[DDR_INSTALLER][INFO] ------------------- Installer is done ------------------------")
581 | print("[DDR_INSTALLER][INFO] You can now go to '{}' and run 'python ddr_server.py'".format(ddr_default_dir))
582 | print("[DDR_INSTALLER][INFO] This will start the DDR server.\n")
583 | print("[DDR_INSTALLER][INFO] Make sure to allow the Windows Firewall rule")
584 | print("[DDR_INSTALLER][INFO] the first time you start the DDR server\n")
585 | print("[DDR_INSTALLER][INFO] You can test connectifity by going to the")
586 | print("[DDR_INSTALLER][INFO] following test website:\n")
587 | print("[DDR_INSTALLER][INFO] https://{}:{} \n".format(DDR_SERVER_IP, DDR_SERVER_PORT))
588 | print("[DDR_INSTALLER][INFO] with your prefered browser.")
589 | print("[DDR_INSTALLER][INFO] Once the server is running, you can start using the")
590 | print("[DDR_INSTALLER][INFO] IDA DDR plugin.")
591 | print("[DDR_INSTALLER][INFO] --------------------------------------------------------------\n")
592 |
593 | if not proceed("[DDR_INSTALLER][INFO] Should we proceed with starting the DDR server (ddr_server.py) for you ? [Y/n]"):
594 | print("[DDR_INSTALLER][INFO] Good bye !")
595 | exit(0)
596 |
597 | print("")
598 | my_cmd = 'python "' + ddr_default_dir + '"\\ddr_server.py "' + ddr_default_dir + '"\\ddr_server.cfg'
599 | try:
600 | print("[DDR_INSTALLER][INFO] Starting DDR server:")
601 | print("[DDR_INSTALLER][INFO] {}".format(my_cmd))
602 | subprocess.run(my_cmd)
603 | except KeyboardInterrupt:
604 | pass
605 | exit(0)
606 |
607 | # --- Main ---
608 | if __name__ == "__main__":
609 |
610 | os.chdir(os.path.dirname(os.path.abspath(__file__)))
611 | mydir = os.path.realpath(__file__)
612 | print("\n[DDR_INSTALLER][INFO] Running from directory {}\n".format(mydir))
613 |
614 | TMP_FILE1 = "ddr_install_dir.tmp"
615 |
616 | if not sys.version_info >= (3, 0):
617 | print("[DDR_INSTALLER][ERROR] This script only runs in Python 3. Please install Python 3 first")
618 | print("[DDR_INSTALLER][ERROR] Reminder: The same applies to the IDA server and plugin.")
619 | print("[DDR_INSTALLER][INFO] Due to an IDA bug it is recommended to use Python 3.7 in the moment")
620 | print("[DDR_INSTALLER][INFO] on the machine where IDA is running on. You should still use Python 3.8")
621 | print("[DDR_INSTALLER][INFO] for the DDR server machine (this one). If it is the same machine, go for 3.7")
622 | print("[DDR_INSTALLER][INFO] Again, the latter is NOT recommended, better use two separate machines !")
623 | exit(1)
624 |
625 | if not os.path.isfile(TMP_FILE1):
626 | print("\n[DDR_INSTALLER][INFO] --- Welcome to the DDR Server installer script ---")
627 | print("[DDR_INSTALLER][INFO] This script installs the DDR server and all its dependencies. It will create a virtual environment")
628 | print("[DDR_INSTALLER][INFO] for all Python dependencies to make sure that it will not interfere with your existing Python setup.")
629 | print("[DDR_INSTALLER][INFO] Both DDR server and the DDR plugin only support Python version 3 and higher.")
630 | print("[DDR_INSTALLER][INFO] ------------------------------------- READ THIS ----------------------------------------------------")
631 | print("[DDR_INSTALLER][INFO] If you are using IDA < 7.5 you should use Python 3.7 on the IDA machine. This is due to a")
632 | print("[DDR_INSTALLER][INFO] bug in IDA 7.4 which is fixed in 7.5. If you are using 7.5 we recommend to use Python 3.8.")
633 | print("[DDR_INSTALLER][INFO] In any case it is recommended to use Python 3.8 for the DDR server machine. If it is the")
634 | print("[DDR_INSTALLER][INFO] same machine, go for 3.7. Again, the latter setup is NOT recommended, better use two separate")
635 | print("[DDR_INSTALLER][INFO] machines !")
636 | print("[DDR_INSTALLER][INFO] ----------------------------------------------------------------------------------------------------")
637 | if not proceed("[DDR_INSTALLER][INFO] Do you want to proceed ? [Y/n] ? "):
638 | print("[DDR_INSTALLER][INFO] Good bye!")
639 | exit(0)
640 |
641 | print("[DDR_INSTALLER][INFO] Please enter installation directory for DDR server or hit enter for default directory.")
642 | ddr_default_dir = input("[DDR_INSTALLER][INFO] Default is C:\\tools\\DDR : ") or "C:\\tools\\DDR"
643 | if ddr_default_dir[-1:] == "\\":
644 | ddr_default_dir = ddr_default_dir[:-1]
645 |
646 | if len(ddr_default_dir) > MAX_INSTALL_DIR:
647 | print("[DDR_INSTALLER][ERROR] Max. install directory length is {:d}. Please use a shorter path.".format(MAX_INSTALL_DIR))
648 | print("[DDR_INSTALLER][ERROR] Your DDR installation path is {:d} characters long.".format(len(ddr_default_dir)))
649 | exit(1)
650 |
651 | if os.path.exists(ddr_default_dir):
652 | print("[DDR_INSTALLER][INFO] Directory '{}' exists.".format(ddr_default_dir))
653 | print("[DDR_INSTALLER][INFO] If this is an update it is recommended to delete the old installation first.")
654 | if proceed("[DDR_INSTALLER][INFO] Should we delete the Directory '{}' [Y/n] ?"):
655 | shutil.rmtree(ddr_default_dir)
656 |
657 | print("[DDR_INSTALLER][INFO] Installing DDR server to directory: {}".format(ddr_default_dir))
658 |
659 | try:
660 | pathlib.Path(ddr_default_dir).mkdir(parents=True, exist_ok=True)
661 | except PermissionError:
662 | print("[DDR_INSTALLER][ERROR] You do not have the access rights to create this directory.")
663 | exit(1)
664 |
665 | with open(TMP_FILE1, 'w') as f:
666 | f.write(ddr_default_dir)
667 | else:
668 | with open(TMP_FILE1, 'r') as f:
669 | ddr_default_dir = f.read()
670 | print("[DDR_INSTALLER][INFO] Found DDR directory: {} for phase 2.".format(ddr_default_dir))
671 |
672 | venv=ddr_default_dir + "\\" + DDR_VIRTENV_NAME
673 |
674 | if not os.path.isdir(venv):
675 | # Phase 1: Create virtual enviroment
676 | if proceed("[DDR_INSTALLER][INFO] Installing virtual enviroment to '{}' Proceed [Y/n] ? ".format(venv) ):
677 | print("[DDR_INSTALLER][INFO] Phase 1: Create virtual enviroment.")
678 | runcmd("python -m venv \"" + venv + "\"")
679 | else:
680 | print("[DDR_INSTALLER][ERROR] Installation aborted.")
681 | exit(1)
682 |
683 | if not is_venv():
684 | # Phase 2: Activate virtual enviroment and restart this script in it
685 | print("[DDR_INSTALLER][INFO] Phase 2: Activating virtual enviroment.")
686 | python_bin = venv + "\\Scripts\\python.exe"
687 | script_file = os.path.realpath(__file__)
688 | try:
689 | subprocess.run([python_bin, script_file])
690 | except KeyboardInterrupt:
691 | pass
692 | exit(0)
693 | else:
694 | if sys.prefix == venv:
695 | print("[DDR_INSTALLER][INFO] We are running in the right virtual enviroment : {}".format(sys.prefix))
696 | os.remove(TMP_FILE1)
697 | print("[DDR_INSTALLER][INFO] Temp. file: {} deleted. Starting main installation routine.".format(TMP_FILE1))
698 |
699 | # Main installation routine
700 | # Install virtual enviroment and dependancies
701 | if install_deps(venv, ddr_default_dir):
702 | print("[DDR_INSTALLER][INFO] Successfully installed DDR server to {}".format(ddr_default_dir))
703 |
704 | if not proceed("[DDR_INSTALLER][INFO] Should we proceed with the installation of the plugin ? [Y/n]"):
705 | print("[DDR_INSTALLER][INFO] IDA Plugin installation skipped.")
706 | installer_done()
707 | exit(0)
708 |
709 | #Prepare IDA plugin files and config and built zip file
710 | built_plugin_zip(ddr_default_dir)
711 |
712 | # start web server
713 | python_bin = venv + "\\Scripts\\python.exe"
714 | script_file = "install_data\\installer_web_server.py"
715 | args = "{}".format(DDR_SERVER_IP)
716 | try:
717 | subprocess.run([python_bin, script_file, args])
718 | except KeyboardInterrupt:
719 | pass
720 |
721 | installer_done()
722 | else:
723 | print("[DDR_INSTALLER][ERROR] Failed installing dependencies.")
724 | exit(1)
725 | else:
726 | print("[DDR_INSTALLER][ERROR] We are in a different virtual enviroment : {}".format(sys.prefix))
727 | exit(1)
728 |
729 | exit(0)
730 |
731 |
732 |
733 |
734 |
735 |
736 |
--------------------------------------------------------------------------------
/ddr_installer/README.txt:
--------------------------------------------------------------------------------
1 |
2 | Usual setup:
3 | ------------
4 |
5 | Analyst PC (IDA, ddr_plugin.py)
6 | |
7 | | IP network (Allow port DDR_CONFIG_SETTINGS.WEBSERVER_PORT (Default: 5000)
8 | | in your firewall. There should be a pop when you run ddr_server.py)
9 | | the first time during installation.
10 | V
11 | Malware PC (DynamoRio, ddr32.dll, ddr64.dll, ddr_server.py)
12 |
13 | Notes:
14 | ------
15 | Installing both the server and the plugin on the same PC, should work to, but is not
16 | recommended. Keep in mind that the malware sample is executed by the DynamoRio framework.
17 |
18 |
19 | Installation:
20 | -------------
21 | Copy this directory to the Malware PC (ddr_server PC) and run DDR_INSTALLER.py.
22 | The script will download all dependencies and create all necessary configuration files
23 | for your environment. It will guide you through the whole installation process of the
24 | DDR server and IDA plugin.
25 | It will not touch your local python environment, instead it creates a dedicated virtual
26 | Python environment for all dependencies. It will also create individual cryptographic
27 | material for the SSL encrypted traffic between the DDR server and IDA plugin.
28 |
29 | Pls report bugs and issues to hunterbr@cisco.com
30 |
31 | ===========================================================================================
32 | You can find more infos at https://blog.talosintelligence.com/ search for DDR or Dynamic
33 | Data Resolver to find the latest blog about DDR. It is highly recommended to read this blog
34 | as far as DDR is a complex tool and without knowing some basics, it might be difficult to
35 | use the tool in a proper way.
36 | ============================================================================================
37 |
38 | Dependencies:
39 | =============
40 |
41 | Python 3.7 or 3.8
42 | ------------------
43 | If you are using IDA < 7.5 you should use Python 3.7 on the IDA machine. This is due to a
44 | bug in IDA 7.4 which is fixed in 7.5. If you are using 7.5 we recommend to use Python 3.8.
45 | In any case it is recommended to use Python 3.8 for the DDR server machine. If it is the
46 | same machine, go for 3.7. Again, the latter setup is NOT recommended, better use two separate
47 | machines !
48 |
49 | Latest versions of IDA are supporting Python 3.8, if your IDA setup is up to date, you can run
50 | Python 3.8 on the DDR server and plugin side.
51 |
52 | See https://blog.talosintelligence.com/ for details.
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/ddr_installer/ddr_test_samples/testsample0_32_dyn.cfg:
--------------------------------------------------------------------------------
1 | S 40119F
2 | A 4011FD
3 | L 401000 403000 20000 TRUE "C:\tools\DDR\samples\trace_tmp_A1FB519FD6C00B8116BCB1D78567BAE0.json"
4 |
--------------------------------------------------------------------------------
/ddr_installer/ddr_test_samples/testsample0_32_dyn.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_installer/ddr_test_samples/testsample0_32_dyn.exe
--------------------------------------------------------------------------------
/ddr_installer/ddr_test_samples/testsample0_64_dyn.cfg:
--------------------------------------------------------------------------------
1 | T SF 14000124C
2 | S 140001241
3 | A 140001275
4 | L 140001000 140003000 20000 FALSE "C:\tools\DDR\samples\trace_tmp_CBEFF9E003C9FA8D8C568CFB85A885AF.json"
5 |
--------------------------------------------------------------------------------
/ddr_installer/ddr_test_samples/testsample0_64_dyn.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_installer/ddr_test_samples/testsample0_64_dyn.exe
--------------------------------------------------------------------------------
/ddr_installer/ddr_test_samples/testsample1_32.cfg:
--------------------------------------------------------------------------------
1 | T ZF 4016D8
2 | S 4016D3
3 | A 401813
4 | L 401000 403000 20000 TRUE "C:\tools\DDR\samples\trace_tmp_A1FB519FD6C00B8116BCB1D78567BAE0.json"
5 |
--------------------------------------------------------------------------------
/ddr_installer/ddr_test_samples/testsample1_32.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_installer/ddr_test_samples/testsample1_32.exe
--------------------------------------------------------------------------------
/ddr_installer/ddr_test_samples/testsample1_64.cfg:
--------------------------------------------------------------------------------
1 | S 14000178B
2 | L 140001000 140003000 20000 TRUE "C:\tools\DDR\samples\trace_tmp_B4AB561A5A8A53E262C3D09738FFBFA3.json"
3 |
--------------------------------------------------------------------------------
/ddr_installer/ddr_test_samples/testsample1_64.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_installer/ddr_test_samples/testsample1_64.exe
--------------------------------------------------------------------------------
/ddr_installer/ddr_test_samples/testsample_with_args_x32.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_installer/ddr_test_samples/testsample_with_args_x32.exe
--------------------------------------------------------------------------------
/ddr_installer/ddr_test_samples/testsample_with_args_x64.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_installer/ddr_test_samples/testsample_with_args_x64.exe
--------------------------------------------------------------------------------
/ddr_installer/ddr_test_samples/testsamples_README.txt:
--------------------------------------------------------------------------------
1 | These are test sample to test DDR with if you don't want to use real malware.
2 |
3 | NN = 32 bit or 64 bit
4 |
5 | testsample0_NN_dyn.exe - simple program doing a couple of calculations, memory allocs and function calls
6 |
7 | testsample1_NN.exe - Simulates real malware, but doesn't do anything malicious. It copies itself to the
8 | %TEMP% folder and launces a 2nd instance of itself as EvIlMaLwArE.exe
9 | Also launches write.exe/wordpad.exe in the beginning and a notepad.exe at the end
10 |
11 | testsample_with_args_xNN.exe - test sample which prints out its command line arguments, allocates a buffer and uses a function.
12 |
13 |
14 | HINT:
15 | -----
16 | MS Defender detects some of the samples as malicious. This is nonsense and a FP. You might need to disable Defender
17 | or make an exception for them.
18 |
19 | It is a good idea to analyse the samples in IDA first anyway, so you have a good understanding about what they do and what/when/where it makes sense to
20 | use certain DDR features.
21 |
22 |
23 | Caveats:
24 | --------
25 |
26 | 0) Some test samples need the MS Visual C++ 2015-2019 Redistributables. Sorry, I was too lazy to compile them statically. Run the samples stand alone first
27 | to make sure that they are executing on your machine.
28 |
29 | ---
30 |
31 | 1) There is an issue with DynamoRIO in the moment. It doesn't support injection for 32bit processes which are launching
32 | 64bit child processes. A Scenario which some of the test samples above are doing e.g. testsample2_32.exe launches notepad.exe
33 | which could be 64bit process depending on the OS you are running it on.
34 | You can still analyse those processes with DDR, the only caveat is that DDR (or better the underlying DynmaoRIO) is not recognizing
35 | the 64bit processes in this scenario and thou will not trace any data for it. The initial 32bit process is still analysed.
36 |
37 | If you run in such a scenario and want to verify it, you could run DynamoRio in debug mode e.g. :
38 |
39 | C:\tools\DDR\DynamoRIO-Windows-8.0.0-1\bin32\drrun.exe -debug -checklevel 0 -loglevel 2 -- testsample32.exe
40 |
41 | this will write a detailed logging file to C:\tools\DDR\DynamoRIO-Windows-8.0.0-1\logs\\log..html
42 |
43 | You can find an entry like this one in it:
44 |
45 | --- snip ---
46 | syscall: NtCreateUserProcess presys \??\C:\windows\write.exe
47 | Exit from system call
48 | post syscall: sysnum=0x000000aa, params @0x0016f22c, result=0x00000000
49 | syscall: NtCreateUserProcess => 0x0
50 | syscall: NtCreateUserProcess created process 0x848 with main thread 0xd28
51 | WARNING: make_writable 0x73dc6000: param size 0x3f000 vs. mbi size 0x2c000 base 0x73dc6000
52 | WARNING: make_writable 0x73df2000: param size 0x13000 vs. mbi size 0x7000 base 0x73df2000
53 | WARNING: make_unwritable 0x73dc6000: param size 0x3f000 vs. mbi size 0x2c000 base 0x73dc6000
54 | WARNING: make_unwritable 0x73df2000: param size 0x13000 vs. mbi size 0x7000 base 0x73df2000
55 | SYSLOG_WARNING: Injecting from 32-bit into 64-bit process is not yet supported.
56 | syscall: NtCreateUserProcess: WARNING: failed to get cxt of thread (0xc000000d) so can't follow children on WOW64.
57 | --- snip ---
58 |
59 | Luckily for malware analysis, this scenario is not happening very often.
60 |
61 | You can find more infos at https://blog.talosintelligence.com/ search for DDR or Dynamic
62 | Data Resolver to find the latest blog about DDR.
63 |
64 | ---
65 |
66 | 2) Under certain rare contitions the client DLL is crashing if you have NOP'ed out instructions. This bug is under investigation. A
67 | dirty workaround is to clear the configuration in IDA (DDR/Config/Clear configured DDR request) and re-run the sample again.
68 |
69 |
70 |
--------------------------------------------------------------------------------
/ddr_installer/docs/ddr_client_dll_sample_config32.txt:
--------------------------------------------------------------------------------
1 | # --- DDR sample config file ---
2 | #
3 | # Lines should not be more than 350 characters long, file names not more than 256
4 | # characters.
5 | #
6 | # Comments must be written with a leading '#'
7 | # No extra spaces are allowed in config lines
8 | # Different fields are separated by exactly one blank
9 | #
10 | # All number/address values are expected to be hexadecimal values without any
11 | # leading character.
12 | # -----------------------------------------------------------------------------
13 |
14 | # -- NOP out instructions --
15 | # N
16 | # = Start program counter address for NOP'ing instructions (hex)
17 | # = End program counter address for NOP'ing instructions (hex)
18 | # and can be the same for NOP'ing one instr.
19 | # e.g. N 004012EE 004012F6
20 | #N 0040115A 0040115A
21 | #N 00401337 0040133A
22 |
23 | # -- Patch EFLAG --
24 | # T
25 | # = [CF, PF, AF, ZF, SF, DF, OF]
26 | # = program counter address (hex) where to toggle the EFLAG before
27 | # instruction gets executed e.g. jle
28 | # e.g. T SF 004012C4 #example comment
29 | #T SF 004012BB
30 | #T SF 004012FB #example comment
31 |
32 | # -- Always skip function at when called --
33 | # = Functions address which gets wrapped, call to func is skipped
34 | # = set return value of wrapped function (NEED TO BE UNSINGED INT)
35 | # C
36 | # e.g. C 00401100 00000001
37 | C 00401120 FFFFFFFF # = -1
38 | C 00401150 FF
39 |
40 | # -- Dump buffer to file --:
41 | # D
42 | # = program counter address where to get the size of the buffer
43 | # = operant at to get the buffer size from
44 | # e.g. SP0 = (S)ource operant 0. Value is a (P)ointer.
45 | # DV1 = (D)estination operant 1. Absolut (V)alue.
46 | # = program counter address where to get the buffer address
47 | # = operant at PC to get the buffer size from
48 | # = program counter address where to finally dump the buffer
49 | # = dump filename
50 | #
51 | # All numbers/addresses are hexdecimal values without any leading character
52 | #
53 | # e.g. D 0040117E SP0 0040118B SP0 004011F9 dump1.bin
54 | #D 004011B5 SP0 004011C2 SP0 00401230 dump1.bin
55 | #D 004013A2 SP0 004013AF SP0 0040141D dump2.bin
56 | #
57 | # -- Run Trace --:
58 | # start end max.instr lighttrace filename (the last filename in the list will be used)
59 | # 401335 4013CA 20000 TRUE "C:\Users\Dex Dexter\Documents\test\test\buffertest_trace.json"
60 | # e.g.
61 | L 4012BE 40130F 20000 TRUE "C:\Users\Dex Dexter\Documents\test\test\buffertest_trace.json"
62 | L 401335 4013CA 20000 TRUE "C:\Users\Dex Dexter\Documents\test\test\buffertest_trace.json"
63 | L 401411 40146E 20000 FALSE "C:\Users\Dex Dexter\Documents\test\test\buffertest_trace.json"
64 |
65 | # -- Patch binary with endless Loop at address --:
66 | # loop-addr
67 | B 40170C
68 |
69 | # --- use a start address ---
70 | # DDR will start the instrumentation/analysis at this address
71 | # it is useful to use this if the start/end alone doesn't do the trick
72 | # e.g. the sample later jump to an address wich is smaller than the start address
73 | # you handed over in the trace(L) line for example
74 | S 40119F
75 |
76 | # --- use a break address ---
77 | # DDR stops instrumentation and execution of the process at this address
78 | A 4011FD
--------------------------------------------------------------------------------
/ddr_installer/docs/ddr_client_dll_sample_config64.txt:
--------------------------------------------------------------------------------
1 | # --- DDR sample config file ---
2 | #
3 | # Lines should not be more than 350 characters long, file names not more than 256
4 | # characters.
5 | #
6 | # Comments must be written with a leading '#'
7 | # No extra spaces are allowed in config lines
8 | # Different fields are separated by exactly one blank
9 |
10 | All number/address values are expected to be hexadecimal values without any
11 | leading character.
12 | # -----------------------------------------------------------------------------
13 |
14 | # -- NOP out instructions --
15 | # N
16 | # = Start program counter address for NOP'ing instructions (hex)
17 | # = End program counter address for NOP'ing instructions (hex)
18 | # and can be the same for NOP'ing one instr.
19 | # e.g. N 004012EE 004012F6
20 | N 000000014000121C 000000014000121C
21 | N 000000014000145A 000000014000145A
22 |
23 | # -- Patch EFLAG --
24 | # T
25 | # = [CF, PF, AF, ZF, SF, DF, OF]
26 | # = program counter address where to toggle the EFLAG before
27 | # instruction gets executed e.g. jle (hex)
28 | # e.g. T SF 004012C4 #example comment
29 | T SF 00000001400013A7
30 | T SF 00000001400013E5 #example comment
31 |
32 | # -- Always skip function at when called --
33 | # = Functions address which gets wrapped, call to func is skipped
34 | # = set return value of wrapped function (NEED TO BE UNSINGED INT)
35 | # C
36 | # e.g. C 00401100 00000001
37 | C 00000001400011E0 0
38 | C 0000000140001210 FFFFFFFFFFFFFFFF # -1
39 |
40 | # -- Dump buffer to file --:
41 | # D
42 | # = program counter address where to get the size of the buffer
43 | # = operant at to get the buffer size from
44 | # e.g. SP0 = (S)ource operant 0. Value is a (P)ointer.
45 | # DV1 = (D)estination operant 1. Absolut (V)alue.
46 | # = program counter address where to get the buffer address
47 | # = operant at PC to get the buffer size from
48 | # = program counter address where to finally dump the buffer
49 | # = dump filename
50 | # e.g. D 0040117E SP0 0040118B SP0 004011F9 dump1.bin
51 | D 0000000140001280 SP0 000000014000128D SP0 000000014000132B dump_x64_1.bin
52 | D 0000000140001494 SP0 00000001400014A1 SP0 000000014000153F dump_x64_2.bin
53 | #
54 | # -- Run Trace --:
55 | # start end max.instr lighttrace filename (the last filename in the
56 | # list will be used)
57 | L 140001000 140003000 20000 FALSE trace_tmp_CBEFF9E003C9FA8D8C568CFB85A885AF.json
58 | #
59 | # -- Patch binary with endless Loop at address --:
60 | # loop-addr
61 | B 0000000140001280
62 |
63 | # --- use a start address ---
64 | # DDR will start the instrumentation/analysis at this address
65 | # it is useful to use this if the start/end alone doesn't do the trick
66 | # e.g. the sample later jump to an address wich is smaller than the start address
67 | # you handed over in the trace(L) line for example
68 | S 140001241
69 |
70 | # --- use a break address ---
71 | # DDR stops instrumentation and execution of the process at this address
72 | A 140001275
--------------------------------------------------------------------------------
/ddr_installer/install_data/ddr32.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_installer/install_data/ddr32.dll
--------------------------------------------------------------------------------
/ddr_installer/install_data/ddr32dbg.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_installer/install_data/ddr32dbg.dll
--------------------------------------------------------------------------------
/ddr_installer/install_data/ddr64.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_installer/install_data/ddr64.dll
--------------------------------------------------------------------------------
/ddr_installer/install_data/ddr64dbg.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cisco-Talos/DynDataResolver/e630bd3d81062f790d932bbe7c594fde93da5f5f/ddr_installer/install_data/ddr64dbg.dll
--------------------------------------------------------------------------------
/ddr_installer/install_data/installer_web_server.py:
--------------------------------------------------------------------------------
1 | import flask
2 | import json
3 | import sys
4 | import os
5 | import shutil
6 | import zipfile
7 | import ctypes
8 | from cheroot.wsgi import Server as WSGIServer
9 |
10 | IDA_PLUGIN_ZIP = "ddr_plugin.zip"
11 | MY_IP = sys.argv[1]
12 | MY_PORT = "80"
13 |
14 | app = flask.Flask(__name__)
15 | app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
16 |
17 | # prevent cached responses. Sets no-cache parameters header for every flask response.
18 | @app.after_request
19 | def add_header(r):
20 | """
21 | Add headers to both force latest IE rendering engine or Chrome Frame,
22 | and also to cache the rendered page for 10 minutes.
23 | """
24 | r.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
25 | r.headers["Pragma"] = "no-cache"
26 | r.headers["Expires"] = "0"
27 | r.headers['Cache-Control'] = 'public, max-age=0'
28 | return r
29 |
30 | @app.route('/', methods=['GET'])
31 | def ddr_plugin_installation():
32 |
33 | webcontent = '''
34 |
35 | DDR IDA Plugin Installer Website
36 |
37 |
38 | Hello DDR User,
39 |
40 | Just download ,
41 | unzip it and execute the ida_plugin_installer.py script.
42 |
43 |
44 |
45 | '''
46 | webcontent = webcontent.replace('', IDA_PLUGIN_ZIP)
47 | webcontent = webcontent.replace('' , MY_IP)
48 | webcontent = webcontent.replace('' , MY_PORT)
49 |
50 | return webcontent
51 |
52 | @app.route('/get_plugin', methods=['GET'])
53 | def ddr_plugin_download():
54 | return flask.send_file(IDA_PLUGIN_ZIP, as_attachment=True)
55 |
56 | def run_webserver():
57 |
58 | server = WSGIServer(bind_addr=(MY_IP, int(MY_PORT)), wsgi_app=app, numthreads=100)
59 |
60 | print("[DDR_INSTALLER][INFO] ------------------------------------------------------------------------")
61 | print("[DDR_INSTALLER][INFO] Starting IDA plugin installation.")
62 | print("[DDR_INSTALLER][INFO] Please go to your IDA machine and point your browser to:\n")
63 | print("[DDR_INSTALLER][INFO] http://{}:{}\n".format(MY_IP,MY_PORT))
64 | print("[DDR_INSTALLER][INFO] Once you are done installing the IDA plugin, hit Ctrl-C here to stop the")
65 | print("[DDR_INSTALLER][INFO] webserver and proceed with the installation.")
66 | print("[DDR_INSTALLER][INFO] ------------------------------------------------------------------------")
67 |
68 | try:
69 | server.start()
70 | except KeyboardInterrupt:
71 | server.stop()
72 | except:
73 | print("[DDR_INSTALLER][ERROR] Failed to start installation server. Please check if you")
74 | print("[DDR_INSTALLER][ERROR] have configured a valid NGINX IP address above.\n")
75 | raise
76 |
77 | if __name__ == "__main__":
78 |
79 | run_webserver()
80 |
--------------------------------------------------------------------------------
/ddr_installer/known_bugs.txt:
--------------------------------------------------------------------------------
1 | 1) Injection for 32bit processes which are launching 64bit child processes
2 |
3 | There is an issue with DynamoRIO in the moment. It doesn't support injection for 32bit processes which are launching
4 | 64bit child processes. A Scenario which some of the test samples above are doing e.g. testsample2_32.exe launches notepad.exe
5 | which could be 64bit process depending on the OS you are running it on.
6 | You can still analyse those processes with DDR, the only caveat is that DDR (or better the underlying DynmaoRIO) is not recognizing
7 | the 64bit processes in this scenario and thou will not trace any data for it. The initial 32bit process is still analysed.
8 |
9 | If you run in such a scenario and want to verify it, you could run DynamoRio in debug mode e.g. :
10 |
11 | C:\tools\DDR\DynamoRIO-Windows-8.0.0-1\bin32\drrun.exe -debug -checklevel 0 -loglevel 2 -- testsample32.exe
12 |
13 | this will write a detailed logging file to C:\tools\DDR\DynamoRIO-Windows-8.0.0-1\logs\\log..html
14 |
15 | You can find an entry like this one in it:
16 |
17 | --- snip ---
18 | syscall: NtCreateUserProcess presys \??\C:\windows\write.exe
19 | Exit from system call
20 | post syscall: sysnum=0x000000aa, params @0x0016f22c, result=0x00000000
21 | syscall: NtCreateUserProcess => 0x0
22 | syscall: NtCreateUserProcess created process 0x848 with main thread 0xd28
23 | WARNING: make_writable 0x73dc6000: param size 0x3f000 vs. mbi size 0x2c000 base 0x73dc6000
24 | WARNING: make_writable 0x73df2000: param size 0x13000 vs. mbi size 0x7000 base 0x73df2000
25 | WARNING: make_unwritable 0x73dc6000: param size 0x3f000 vs. mbi size 0x2c000 base 0x73dc6000
26 | WARNING: make_unwritable 0x73df2000: param size 0x13000 vs. mbi size 0x7000 base 0x73df2000
27 | SYSLOG_WARNING: Injecting from 32-bit into 64-bit process is not yet supported.
28 | syscall: NtCreateUserProcess: WARNING: failed to get cxt of thread (0xc000000d) so can't follow children on WOW64.
29 | --- snip ---
30 |
31 | Luckily for malware analysis, this scenario is not happening very often.
32 |
33 | You can find more infos at https://blog.talosintelligence.com/ search for DDR or Dynamic
34 | Data Resolver to find the latest blog about DDR.
35 |
36 | ===========================================================================================================================================================
37 |
38 | 2) Under certain rare contitions the client DLL is crashing if you have NOP'ed out instructions. This bug is under investigation. A
39 | dirty workaround is to clear the configuration in IDA (DDR/Config/Clear configured DDR request) and re-run the sample again.
40 |
41 | ===========================================================================================================================================================
42 |
43 | 3) AMD CPU bug
44 | There is a DDR independent AMD CPU bug which crashes the DynamoRio framework if a 32bit sample is executed on a 64bit machine and the WoW64 architecture is switching between the 32 and 64 bit world. The issue is identified and the root cause found. The DynamoRio team has released a special build here which fixes the issue. You can download it and replace the original DynamoRio directory with this one. Unzip DynamoRIO-Windows-8.0.18547.zip and rename or backup the old directory (C:\tools\DDR\DynamoRIO-Windows-8.0.0-1), give the downloaded one the same name like the old one and move it to the same place.
45 |
46 | You can read more details here . The bug is confirmed on Ryzen CPUs, but may also occur on other AMD CPUs. We haven’t seen any issues on Intel CPUs.
47 |
48 | In some cases, a possible workaround, until we have an updated version of DynamoRio, is to set MaxLoaderThreads to 1 in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\
49 |
50 | ===========================================================================================================================================================
51 |
52 | 4) Access violations from 'dynamorio!safe_read_asm_xxx' functions are expected and can be ignored in WinDbg.They are caused by the way DynamoRio has implemented these functions (Try-Except).They are handled by DynamoRio internally if you haven’t attached a debugger. In In WinDbg, just proceed (F5) if something like below happens:
53 |
54 | WinDbg Console:
55 | (1df0.1a28) : Access violation - code c0000005(first chance)
56 | First chance exceptions are reported before any exception handling.
57 | This exception may be expected and handled.
58 | dynamorio!safe_read_asm_pre
59 |
60 | The functions are heavily used in DDR, so you might see a lot of these exceptions. You can filter them by disable Access Violations in WInDbg. Most serious exceptions will still break into the debugger.
61 |
62 | ===========================================================================================================================================================
63 |
64 | 5) IDA Debugger and image relocation in IDA is not supported in DDR in the moment.
65 |
66 | If you use the IDA debugger for a sample which is using reloacation, IDA is rebasing the segments (or you rebase the segments manually), than DDR will use the
67 | rebased EA address, which will not work as far as DDR server/ DDR client need the org. PE RVA.
68 |
69 |
70 | Missing features:
71 | =================
72 |
73 | - autom. add break address to full trace basic block (last address in basic block)
74 | - add break and start address feature to dump buffer and other features (works only for trace feature itm)
--------------------------------------------------------------------------------
/ddr_installer/release_notes.txt:
--------------------------------------------------------------------------------
1 | #### Release Notes ####
2 |
3 | Version 1.02
4 | - Added 'start offset' feature. You can now set a start offset for traces. DDR starts the analysis at that address.
5 | - Added 'break address' feature. You can now add an address where DDR should break/stop the anaylsis.
6 | - Added an option to pass command line parameters to the sample
7 | - Added a check to pop up a warning if the sample was relocated in IDA
8 | - updated DynamoRio version
9 | - updated uvicorn library to 0.12.3
10 | - updated cryptography to 3.2.1
11 | - updated some test samples
12 | - fixed a few minor bugs
13 |
14 |
--------------------------------------------------------------------------------
/ddr_installer/requirements.in:
--------------------------------------------------------------------------------
1 | fastapi
2 | uvicorn
3 | requests
4 | clint
5 | Flask
6 | pyOpenSSL
7 | cheroot
8 | werkzeug
9 | python-multipart
10 | aiofiles
11 | psutil
--------------------------------------------------------------------------------
/ddr_installer/requirements.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile
3 | # To update, run:
4 | #
5 | # pip-compile requirements.in
6 | #
7 | aiofiles==0.5.0 # via -r requirements.in
8 | args==0.1.0 # via clint
9 | certifi==2020.4.5.1 # via requests
10 | cffi==1.14.0 # via cryptography
11 | chardet==3.0.4 # via requests
12 | cheroot==8.3.0 # via -r requirements.in
13 | click==7.1.2 # via flask, uvicorn
14 | clint==0.5.1 # via -r requirements.in
15 | cryptography==3.2.1 # via pyopenssl
16 | fastapi==0.54.2 # via -r requirements.in
17 | flask==1.1.2 # via -r requirements.in
18 | h11==0.9.0 # via uvicorn
19 | idna==2.9 # via requests
20 | itsdangerous==1.1.0 # via flask
21 | jaraco.functools==3.0.1 # via cheroot
22 | jinja2==2.11.2 # via flask
23 | markupsafe==1.1.1 # via jinja2
24 | more-itertools==8.3.0 # via cheroot, jaraco.functools
25 | psutil==5.7.0 # via -r requirements.in
26 | pycparser==2.20 # via cffi
27 | pydantic==1.5.1 # via fastapi
28 | pyopenssl==19.1.0 # via -r requirements.in
29 | python-multipart==0.0.5 # via -r requirements.in
30 | requests==2.23.0 # via -r requirements.in
31 | six==1.14.0 # via cheroot, cryptography, pyopenssl, python-multipart
32 | starlette==0.13.2 # via fastapi
33 | urllib3==1.25.9 # via requests
34 | uvicorn==0.12.3 # via -r requirements.in
35 | websockets==8.1 # via uvicorn
36 | werkzeug==1.0.1 # via -r requirements.in, flask
37 |
--------------------------------------------------------------------------------
/ddr_installer/roadmap.txt:
--------------------------------------------------------------------------------
1 | Feature requests and roadmap:
2 | (no special order, not committed, just brainstorming)
3 |
4 | - Snapshots for loaded trace files (pull-down menu to quickly jump between different scans)
5 | - highlighting of executed instructions in IDAs decompiler view
6 | - patch register at PC n
7 | - exec shellcode at PC n
8 | - pause and exec custom app/tool at PC n
9 | - dump custom memory range at PC n
10 |
--------------------------------------------------------------------------------
/ddr_installer/templates/ddr_config_template.json:
--------------------------------------------------------------------------------
1 | { "WEBSERVER" : "",
2 | "WEBSERVER_PORT" : "",
3 | "DDR_WEBAPI_KEY" : "",
4 | "CA_CERT" : "",
5 | "VERIFY_CERT" : ,
6 | "DUMP_CFG_FILE" : "",
7 | "MAX_API_TIMEOUT" : ,
8 | "DBG_LEVEL" : ,
9 | "MAX_INSTR_TO_EXECUTE" : ,
10 | "MAX_LOG_ROUNDS" : ,
11 | "MAX_CMT_ROUNDS" : ,
12 | "MAX_INSTR_COUNT" : ,
13 | "MAX_UPLOAD_ATTEMPTS" :
14 | }
--------------------------------------------------------------------------------
/ddr_installer/templates/ddr_server_template.json:
--------------------------------------------------------------------------------
1 | {
2 | "DDR_SERVER_VERSION" : "",
3 | "APILOGGING" : "",
4 | "DEBUG_API_JSON" : ,
5 | "CERT_FILE" : "",
6 | "KEY_FILE" : "",
7 | "APIKEY_FILE" : "",
8 | "SERVER_IP" : "",
9 | "SERVER_PORT" : "",
10 | "MY_FQDN" : "",
11 | "CONFDIR" : "",
12 | "DDR_VIRTENV" : "",
13 | "MAX_CFG_LINE_LENGTH" : ,
14 | "CFG_DYNRIO_DRRUN_X32" : "",
15 | "CFG_DYNRIO_CLIENTDLL_X32" : "",
16 | "CFG_DYNRIO_DRRUN_X64" : "",
17 | "CFG_DYNRIO_CLIENTDLL_X64" : ""
18 | }
19 |
--------------------------------------------------------------------------------
/ddr_installer/templates/ida_plugin_installer_template.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 | import subprocess
4 | import shutil
5 | from distutils import dir_util, file_util
6 |
7 | # List of Python module dependencies
8 | DEPS = ["requests", "pefile"]
9 |
10 | def proceed(question):
11 | """
12 | Do you want to proceed [Y/n]. Returns True if 'yes' and False if 'no'
13 | """
14 | valid = ["y"]
15 |
16 | while True:
17 | sys.stdout.write(question)
18 | choice = input().lower()
19 | if choice == '':
20 | return True
21 | elif choice == 'y':
22 | return True
23 | else:
24 | return False
25 |
26 |
27 | def runcmd(my_cmd):
28 | """
29 | Execute shell command
30 | """
31 |
32 | print("[DDR_INSTALLER][INFO] Executing cmd: \n{}\n".format(my_cmd))
33 |
34 | stdout = False
35 | stderr = False
36 |
37 | try:
38 | process = subprocess.run(my_cmd)
39 |
40 | if process.returncode != 0:
41 | print("\n[DDR_INSTALLER][WARNING] Command execution failed. Error code: {:d}".format(process.returncode))
42 | ret = False
43 | else:
44 | ret = True
45 |
46 | except :
47 | print("[DDR_INSTALLER][ERROR] Exception: Command execution failed with unknown error.")
48 | ret = False
49 |
50 | return ret
51 |
52 | def install_deps(ida_python_path):
53 | """
54 | Main installer routine to install all neccessary
55 | dependencies for DDR IDA plugin
56 | """
57 |
58 | ida_python_interpreter = ida_python_path + "\\python.exe"
59 | ida_python_pip = ida_python_path + "\\Scripts\\pip.exe"
60 |
61 | # update pip in virtual enviroment
62 | pip_latest_version = False
63 | while pip_latest_version == False:
64 | print("[DDR_INSTALLER][INFO] Checking for pip in virtual enviroment...")
65 | my_cmd = ida_python_interpreter + " -m pip install --no-warn-script-location --upgrade pip"
66 | if runcmd(my_cmd):
67 | print("[DDR_INSTALLER][INFO] pip tools upgraded/installed.\n")
68 | pip_latest_version=True
69 | else:
70 | print("\n[DDR_INSTALLER][ERROR] pip is not the latest version.")
71 | print("[DDR_INSTALLER][ERROR] Please update your pip tools manually first")
72 | print("[DDR_INSTALLER][ERROR] Installing/Updating the pip tools likely needs admin rights in your setup.")
73 | print("[DDR_INSTALLER][ERROR] Run a command prompt (cmd.exe) as administrator and enter:")
74 | print("[DDR_INSTALLER][ERROR] \"{}\\python.exe\" -m pip install --upgrade pip\n".format(ida_python_path))
75 | proceed("[DDR_INSTALLER][ERROR] Hit any key once you have updated pip.")
76 |
77 | # Install pip tools
78 | print("[DDR_INSTALLER][INFO] Installing pip-tools.")
79 | my_cmd = ida_python_pip + " install --no-warn-script-location --upgrade pip-tools"
80 | if runcmd(my_cmd):
81 | print("[DDR_INSTALLER][INFO] pip-tools upgraded/installed.\n")
82 | else:
83 | print("\n[DDR_INSTALLER][ERROR] Failed to upgrad/install pip-tools.")
84 | return False
85 |
86 | # Install dependencies
87 | for m in DEPS:
88 | print("[DDR_INSTALLER][INFO] --- Installing {} ---".format(m))
89 | my_cmd = ida_python_pip + " install --no-warn-script-location --upgrade " + m
90 | if runcmd(my_cmd):
91 | print("[DDR_INSTALLER][INFO] --- {} installed. ---\n".format(m))
92 | else:
93 | print("[DDR_INSTALLER][ERROR] Failed to install {}.\n".format(m))
94 | return False
95 |
96 | # --- Main ---
97 | if __name__ == "__main__":
98 |
99 | os.chdir(os.path.dirname(os.path.abspath(__file__)))
100 | mydir = os.path.realpath(__file__)
101 | print("\n[DDR_INSTALLER][INFO] Running from directory {}\n".format(mydir))
102 |
103 | ida_install_dir = r""
104 | ida_plugin_dir = r""
105 | ida_python_path = r""
106 |
107 | print("[DDR_INSTALLER][INFO] Using the following directories:")
108 | print("[DDR_INSTALLER][INFO] IDA install dir: {}".format(ida_install_dir))
109 | print("[DDR_INSTALLER][INFO] IDA plugin dir : {}".format(ida_plugin_dir))
110 | print("[DDR_INSTALLER][INFO] IDA Python dir : {}\n".format(ida_python_path))
111 |
112 | if os.path.isdir(ida_install_dir) == False:
113 | print("[DDR_INSTALLER][ERROR] {} is not a directory.".format(ida_install_dir))
114 | exit(1)
115 |
116 | if os.path.isdir(ida_plugin_dir) == False:
117 | # Doesn't exist or is no directory
118 | if os.path.exists(ida_plugin_dir):
119 | print("[DDR_INSTALLER][ERROR] {} is not a directory.".format(ida_plugin_dir))
120 | exit(1)
121 | else:
122 | if proceed("[DDR_INSTALLER][WARNING] {} does not exist. Should I create it [Y/n] ?".format(ida_plugin_dir)):
123 | try:
124 | os.makedirs(ida_plugin_dir)
125 | print("Directory {} successfully created.".format(ida_plugin_dir))
126 | except:
127 | print("[DDR_INSTALLER][ERROR] Failed to create directory; {}" , ida_plugin_dir)
128 | exit(1)
129 |
130 | if os.path.isdir(ida_python_path) == False:
131 | print("[DDR_INSTALLER][ERROR] {} is not a directory.".format(ida_python_path))
132 | exit(1)
133 |
134 | if os.path.isfile(ida_plugin_dir + "\\ddr_plugin.py"):
135 | print("[DDR_INSTALLER][INFO] IDA plugin exists at {}".format(ida_plugin_dir + "\\ddr_plugin.py"))
136 | if os.path.exists(ida_plugin_dir + "\\ddr"):
137 | print("[DDR_INSTALLER][INFO] IDA plugin directory exists at {}".format(ida_plugin_dir + "\\ddr"))
138 | print("[DDR_INSTALLER][INFO] If this is an update it is recommended to delete the old installation first.")
139 | if proceed("[DDR_INSTALLER][INFO] Should we delete it [Y/n] ?"):
140 | os.remove(ida_plugin_dir + "\\ddr_plugin.py")
141 | shutil.rmtree(ida_plugin_dir + "\\ddr")
142 | print("[DDR_INSTALLER][INFO] Old installation removed")
143 |
144 | # Install dependencies
145 | if proceed("[DDR_INSTALLER][INFO] Should we proceed with installing the Python module dependencies ? [Y/n]"):
146 | install_deps(ida_python_path)
147 |
148 | # Copy DDR files to plugin directory
149 | if proceed("[DDR_INSTALLER][INFO] Should we proceed with copying the DDR plugin files to the IDA plugin directory? [Y/n]"):
150 | print("[DDR_INSTALLER][INFO] Copying plugin files to {}...".format(ida_plugin_dir))
151 | flist = dir_util.copy_tree("ddr", ida_plugin_dir + "\\ddr")
152 | for f in flist:
153 | print("[DDR_INSTALLER][INFO] File: {} copied.".format(f))
154 |
155 | f = file_util.copy_file("ddr_plugin.py", ida_plugin_dir + "\\ddr_plugin.py")
156 | print("[DDR_INSTALLER][INFO] File: {} copied.".format(f[0]))
157 |
158 | print("\nDone. Go back to the malware machine side and start the DDR server. By default: C:\\tools\\DDR\\ddr_server.py")
159 | print("(If you still have the DDR server installer open, it will do that for you if you hit Ctrl-C.)\n")
160 | print("Then start IDA and ... Happy reversing !\n")
161 |
162 | proceed("[DDR_INSTALLER][INFO] Hit any key to end installer.\n")
163 |
164 |
165 |
--------------------------------------------------------------------------------