I'm trying to trace a function, but unfortunately that function is huge and has lots and lots of jumps to other locations, making it almost impossible to trace for humans. I know the entry point and the exit point of the function. I would like a way to be able to run the function and see all of the opcodes that were executed afterwards so I can manually recreate the function later in c++. It will also help me find exactly where the function is crashing (since it would be last executed code) when it crashes. I've tried the tracing method in x64dbg but that would not record opcodes that I didn't manually walk over.
On Windows Travel Debugging (TTD) is a perfect use case for this scenario.
To use TTD, you need to run the debugger elevated. Install WinDbg Preview from Windows 10 store using an account that has administrator privileges and use that account when recording in the debugger. In order to run the debugger elevated, select and hold (or right-click) the WinDbg Preview icon in the Start menu and then select More > Run as Administrator.
If you need to run on system without Windows 10 I have used it on Windows 8.1/Server 2012 and later by first installing on windows 10 then copying the installed files to another system. As a normal administrator account doesn't have access to the files I copy them running as SYSTEM Account using psexec -sid cmd.exe then copy to a folder with command such as
robocopy "C:\program files\WindowsApps\Microsoft.WinDbg_1.2007.6001.0_neutral__8wekyb3d8bbwe" "C\windbgx" * /s
To take trace:
- In WinDbg Preview, select File > Start debugging > Launch executable (advanced).
- Enter the path to the user mode executable that you wish to record or select Browse to navigate to the executable.
- Check the Record process with Time Travel Debugging box to record a trace when the executable is launched.
You can set breakpoints, create timelines of exceptions/breakpoints/memory access, trace instructions forwards/backwards, and inspect memory/registry/disassembly at any point in execution.
If you copied the files out of WindowsApps folder you can also run it via command line in different ways. The ttd.exe is used in amd64\ttd and x86\ttd folders.
The following command line options are available.
Usage: ttd [options] [mode] [PID | program [<arguments>] | <package> <app>]] Options: -? Display this help. -help Display this help. -ring Trace to a ring buffer. -ringMode <mode> Specify how to record a ring trace. Possible modes: file - The ring will be in a file on disk. This is the default. mappedFile - The ring will be in a file, but the entire file will be fully mapped in memory. This reduces the I/O overhead, but the entire file is mapped in contiguous address space, which may add significant memory pressure to 32-bit processes. -maxFile <size> Maximum size of the trace file in MB. When in full trace mode the default is 1024GB and the minimum value is 1MB. When in ring buffer mode the default is 2048MB, the minimum value is 1MB, and the maximum value is 32768MB. The default for in-memory ring on 32-bit processes is 256MB. -out <file> Specify a trace file name or a directory. If a file, the tracer will replace the first instance of '%' with a version number. By default the executable's base name with a version number is used to prefix the trace file name. -children Trace through family of child processes. Modes: -plm To specify a PLM app/package for tracing from launch or to launch that app. These PLM apps can only be setup for tracing if specifying the plm option. See -launch for the parameters required. The default name for a single app package is 'app' and must be included. -launch Launch and trace the program (default). This is the only mode that uses the program arguments. For -plm apps it must be specified, and you must include the package and the app (-launch <package> <app>). Note: This must be the last option in the command-line, followed by the program + arguments or the package + app -attach <PID> Attach to a running process specified by process ID. Control: -stop Stop tracing the process specified (name, PID or "all").
Some walkthroughs of what can be achieved with TTD are here:
If using Visual Studio you can also use IntelliTrace feature to record a debugging trace.