Merge tag 'Ghidra_11.2_build' into stable

This commit is contained in:
ghidra1 2024-09-26 18:00:09 -04:00
commit 7de1f643f9
2077 changed files with 93594 additions and 47671 deletions

10
.gitignore vendored
View File

@ -82,12 +82,12 @@ Release
*.iml *.iml
.idea .idea
# Ignore gradle wrapper files
gradle/wrapper
gradlew
gradlew.*
# Ignore logs and core dumps # Ignore logs and core dumps
*.log *.log
core.* core.*
!core.png !core.png
!core.py
# python files
*.egg-info
__pycache__

View File

@ -32,7 +32,7 @@ authors' names directly in the source code, so it is discouraged.
Download non-Maven Central dependencies. This creates a `dependencies` directory in the repository Download non-Maven Central dependencies. This creates a `dependencies` directory in the repository
root. root.
``` ```
gradle -I gradle/support/fetchDependencies.gradle init gradle -I gradle/support/fetchDependencies.gradle
``` ```
Download Maven Central dependencies and setup the repository for development. By default, these Download Maven Central dependencies and setup the repository for development. By default, these
@ -97,7 +97,7 @@ Sometimes you may want to move the Ghidra repository to an offline network and d
These are the recommended steps to ensure that you not only move the source repository, but all These are the recommended steps to ensure that you not only move the source repository, but all
downloaded dependencies as well: downloaded dependencies as well:
1. `gradle -I gradle/support/fetchDependencies.gradle init` 1. `gradle -I gradle/support/fetchDependencies.gradle`
2. `gradle -g dependencies/gradle prepdev` 2. `gradle -g dependencies/gradle prepdev`
3. Move ghidra directory to different system 3. Move ghidra directory to different system
4. `gradle -g dependencies/gradle buildGhidra` (on offline system) 4. `gradle -g dependencies/gradle buildGhidra` (on offline system)

View File

@ -60,8 +60,6 @@ def configureVisualStudio() {
def vcvarsPath = "${vsInstallDir}\\VC\\Auxiliary\\Build\\vcvarsall.bat" def vcvarsPath = "${vsInstallDir}\\VC\\Auxiliary\\Build\\vcvarsall.bat"
def vcvarsCmd = "\"${vcvarsPath}\" x86_amd64" def vcvarsCmd = "\"${vcvarsPath}\" x86_amd64"
def vcvarsEnvCmd = "cmd /v:ON /c ${vcvarsCmd} > nul && cmd /c echo" def vcvarsEnvCmd = "cmd /v:ON /c ${vcvarsCmd} > nul && cmd /c echo"
def toolsVersion = "${vcvarsEnvCmd} !VCToolsVersion!".execute().text.trim()
println " -> VCTools Version (default): ${toolsVersion}"
def sdkDir = "${vcvarsEnvCmd} !WindowsSdkDir!".execute().text.trim() def sdkDir = "${vcvarsEnvCmd} !WindowsSdkDir!".execute().text.trim()
println " -> SDK Directory (default): ${sdkDir}" println " -> SDK Directory (default): ${sdkDir}"
def sdkVersion = "${vcvarsEnvCmd} !WindowsSDKVersion!".execute().text.trim().replace('\\', '') def sdkVersion = "${vcvarsEnvCmd} !WindowsSDKVersion!".execute().text.trim().replace('\\', '')
@ -73,7 +71,6 @@ def configureVisualStudio() {
// Save Visual Studio information so other projects can access it // Save Visual Studio information so other projects can access it
rootProject.ext.VISUAL_STUDIO_INSTALL_DIR = vsInstallDir rootProject.ext.VISUAL_STUDIO_INSTALL_DIR = vsInstallDir
rootProject.ext.VISUAL_STUDIO_TOOLS_VERSION_DEFAULT = toolsVersion
rootProject.ext.VISUAL_STUDIO_SDK_DIR_DEFAULT = sdkDir rootProject.ext.VISUAL_STUDIO_SDK_DIR_DEFAULT = sdkDir
rootProject.ext.VISUAL_STUDIO_SDK_VERSION_DEFAULT = sdkVersion rootProject.ext.VISUAL_STUDIO_SDK_VERSION_DEFAULT = sdkVersion
rootProject.ext.VISUAL_STUDIO_SDK_VERSION_OVERRIDE = windowsTargetPlatformVersion rootProject.ext.VISUAL_STUDIO_SDK_VERSION_OVERRIDE = windowsTargetPlatformVersion

View File

@ -22,6 +22,170 @@
<BODY> <BODY>
<H1 align="center">Ghidra 11.2 Change History (September 2024)</H1>
<blockquote><p><u><B>New Features</B></u></p>
<ul>
<li><I>Basic Infrastructure</I>. Ghidra now requires JDK 21 to run. (GP-4122)</li>
<li><I>Build</I>. A Gradle wrapper script is now included at <span class="gcode">support/gradle/gradlew(.bat)</span> which can be used to perform all Gradle commands without the need for prior Gradle installation. The Gradle wrapper requires an Internet connection to work. Offline Gradle installations on the PATH continue to work the same way as before. (GP-4486, Issue #455)</li>
<li><I>Debugger</I>. Provided new launchers/features for the traceRMI version of dbgeng, including extended launch options, kernel debugging, and remote process server connections. (GP-4686)</li>
<li><I>Debugger</I>. The Debugger Python components now require Python 3.9 to Python 3.12. (GP-4842)</li>
<li><I>Decompiler</I>. The Decompiler now supports the automatic recovery of <em>stack strings</em>. (GP-3307, Issue #1380, #2285, #6431, #6592)</li>
<li><I>Decompiler</I>. Added a <span class="gtitle">Search All</span> button to the Decompiler <span class="gtitle">Find</span> dialog. This button will show all results of the search in a table. (GP-3491, Issue #5317, #538)</li>
<li><I>GUI</I>. Added <span class="gtitle">Create Table</span> action to the <span class="gtitle">Symbol Tree</span> and <span class="gtitle">Symbol Table</span> to create a new temporary table of symbols. (GP-4574)</li>
<li><I>GUI</I>. Added a <span class="gtitle">Find Uses of</span> field action to the Enum Editor. (GP-4577, Issue #6475)</li>
<li><I>GUI</I>. Added support for <span class="gcode">Ctrl-A</span> to select <em>all</em> in the Python window. (GP-4605, Issue #6502)</li>
<li><I>Headless</I>. Added a JShell launcher with the full Ghidra classpath. (GP-4876)</li>
<li><I>Processors</I>. Added Intel MC16/60 and MC16/80 processor specifications. (GP-4879)</li>
<li><I>Scripting</I>. Added <span class="gcode">VSCodeProjectScript</span>, which can create a new Visual Studio Code project that is setup to do Ghidra scripting and module development, with similar capabilities to the Eclipse GhidraDev plugin. (GP-4795)</li>
<li><I>Search</I>. Updated the Memory Search feature to show results in the query window and added two new features: (1) dynamic updating of results that change, stay the same, increment, or decrement; and (2) combining results from successive searches using boolean set operations. (GP-4559)</li>
</ul>
</blockquote>
<blockquote><p><u><B>Improvements</B></u></p>
<ul>
<li><I>Analysis</I>. Refactored Sparc processor detection and mitigation of Call/Return behavior due to an instruction in the delay slot that changes the <span class="gcode">o7</span> link register. Also fixed 64/32 relocations, sparc calling conventions, and added several missing instructions and hidden structure return pointer location. (GP-3808, Issue #5646, #6300)</li>
<li><I>Analysis</I>. Added support for Golang 1.15 and 1.16. Versions supported are now 1.15-1.22. (GP-4482)</li>
<li><I>Analysis</I>. Added a new <span class="gcode">MIDIDataType</span> and audio player for embedded MIDI scores. (GP-4516, Issue #6337)</li>
<li><I>Analysis</I>. Refactored eBPF analyzers and expanded on applied BPF Helper functions. (GP-4682)</li>
<li><I>Analysis</I>. Updated the <span class="gcode">RTTIAnalyzer</span> to improve its determination of the end of virtual function tables. (GP-4748)</li>
<li><I>BSim</I>. Added BSim database <span class="gcode">connect</span>/<span class="gcode">disconnect</span> actions to BSim Server Manager. This will allow an idle connection to be disconnected without the need to exit Ghidra or removing a server entry, which, in the case of a local H2 database, will allow another process to use it. (GP-4867, Issue #6703)</li>
<li><I>Byte Viewer</I>. Extended HexInteger to other integral data types. (GP-4709, Issue #6658, #6659)</li>
<li><I>CodeCompare</I>. Added ability to add functions to the last function comparison window. (GP-4634)</li>
<li><I>Data Types</I>. Added <span class="gtitle">Edit Data Type</span> action that allows users to edit a chosen data type from anywhere in the tool by using the <span class="gcode">Ctrl-Shift-D</span> keyboard shortcut. (GP-4148, Issue #5975, #6576)</li>
<li><I>Data Types</I>. Added <span class="gtitle">Undo</span>/<span class="gtitle">Redo</span> popup menu actions for Archives within datatype tree. (GP-4719)</li>
<li><I>Data Types</I>. Added <span class="gtitle">Undo</span>/<span class="gtitle">Redo</span> support to the structure and union datatype editors as well as other minor improvements. (GP-4740)</li>
<li><I>Data Types</I>. Improved performance of various structure editor behaviors including setting the structure size. (GP-4949, Issue #6504, #6936)</li>
<li><I>Debugger</I>. Provided more complete compiler matching using <span class="gcode">ldefs</span> language definition files. (GP-4675)</li>
<li><I>Debugger:Agents</I>. Deprecated Framework-Debugging module and Model-based debug connectors, moving toward removal. (GP-4801)</li>
<li><I>Debugger:Agents</I>. User may now use binary (0b prefix), octal (0 prefix), or hex (0x prefix) in integer-valued launcher option fields. (GP-4847)</li>
<li><I>Debugger:Registers</I>. Changed how <span class="gtitle">Go To [address]</span> actions are presented with regard to <span class="gtitle">Force Full View</span>. (GP-3898, Issue #5817)</li>
<li><I>Decompiler</I>. Added <span class="gtitle">Go To Next/Previous Highlight</span> actions to allow navigating Decompiler middle-mouse highlights. (GP-3494, Issue #538)</li>
<li><I>Decompiler</I>. Improved Function Editor to facilitate partial changes which limit impact to Decompiler results (e.g., only change calling convention) and avoid locking full function signature. (GP-4324)</li>
<li><I>Decompiler</I>. Improved multi-threaded decompilation performance and possibly disassembly by removing some unnecessary locking. (GP-4712, Issue #6649, #6650)</li>
<li><I>Decompiler</I>. Provided initial support for recovering optimized heap strings in the Decompiler. (GP-4733)</li>
<li><I>Decompiler</I>. The Decompiler now forces casting to a signed value when converting integers to floating-point. (GP-4871, Issue #6760)</li>
<li><I>Demangler</I>. Added support for GNU Demangler output simplification. (GP-3810, Issue #5725)</li>
<li><I>Demangler</I>. Improved Microsoft Demangler to include handling of <span class="gcode">noexcept</span> attributes and certain type name suffixes. (GP-4626)</li>
<li><I>Demangler</I>. Modified MDMang: added calling conventions and custom data type; added end, empty parameter, and unnamed template types; modified reference modifiers and guard name processing; fixed empty member pointer qualification; and worked around LLVM embedded object issue. (GP-4663)</li>
<li><I>Demangler</I>. Changed application of MDMang <span class="gcode">`anonymous namespace'</span> strings to their underlying anonymous name to avoid namespace conflicts. (GP-4717, Issue #6661)</li>
<li><I>Demangler</I>. Added <span class="gcode">char8_t</span> primitive type to DemangledDataType. (GP-4823)</li>
<li><I>Demangler</I>. Updated the GNU Demangler to support global constructors and destructors. (GP-4825, Issue #6791)</li>
<li><I>Documentation</I>. Added discussions of program specification extensions and instruction length modification to the advanced Ghidra class slides, along with miscellaneous clarifications and improvements. (GP-3774, Issue #5667, #5702)</li>
<li><I>DWARF</I>. Added DWARF analyzer option to ignore parameter storage location info and to use calling convention default layout instead. Also added DWARF analyzer option to specify the calling convention name for functions created by the analyzer. (GP-4150)</li>
<li><I>Eclipse Integration</I>. The latest Eclipse GhidraDev plugin (4.0.0) now requires Eclipse 2023-12 or later running under JDK 21 or later. (GP-4846)</li>
<li><I>Function Compare</I>. Added actions to compare functions from the Listing, Decompiler, and Functions Table. (GP-4619)</li>
<li><I>GUI</I>. Updated the Listing and Byte Viewer title bars to show the number of addresses or bytes selected while dragging. (GP-1359, Issue #2482)</li>
<li><I>GUI</I>. Added <span class="gtitle">Show Namespace</span> action to the Function Call Trees to display the function's namespace in each node. (GP-3251, Issue #5115)</li>
<li><I>GUI</I>. Add <span class="gtitle">Filter Thunks</span> action to the Function Call Trees to hide think functions. (GP-3252, Issue #5116)</li>
<li><I>GUI</I>. Added the <span class="gtitle">Simplified Name</span> column to the Symbol Table. (GP-3377, Issue #6125)</li>
<li><I>GUI</I>. Added the ability to Snapshot the Symbol Tree. (GP-3849)</li>
<li><I>GUI</I>. Added the structure member comment to the Decompiler tooltip window. (GP-4661)</li>
<li><I>GUI</I>. Added single option in the Front End Tool to control whether or not cursors blink in any field panel or text component. (GP-4676, Issue #6570)</li>
<li><I>GUI</I>. The <span class="gtitle">Edit Data Type</span> action in the Decompiler will now select the structure field row when launching the editor. (GP-4728, Issue #5717)</li>
<li><I>GUI</I>. New Listing fields and <span class="gcode">Copy Special</span> actions have been added for imagebase offset, memory block offset, and function offset (disabled by default). (GP-4855, Issue #6794)</li>
<li><I>Headless</I>. Improved handling of headless command-line arguments when the optional list of arguments passed to a pre/post script contain arguments that start with a dash. (GP-4707, Issue #6639)</li>
<li><I>Importer</I>. Added a new <span class="gtitle">Add Library Search Path</span> action to files and folders in the File System Browser that will allow library files to be loaded from within a GFileSystem. (GP-4563)</li>
<li><I>Importer</I>. Added a new <span class="gcode">-librarySearchPaths</span> command line argument to the headless analyzer, which allows a semicolon-delimited list of library search paths to be specified. (GP-4564)</li>
<li><I>Importer</I>. OMF records are now marked up. (GP-4722)</li>
<li><I>Importer:ELF</I>. Improved ELF handling of unresolved symbols during relocation-processing to prevent import failure. (GP-4737, Issue #6673)</li>
<li><I>Multi-User</I>. Upgraded <span class="gcode">yajsw</span> to 13.12. (GP-4860)</li>
<li><I>PDB</I>. Changed the PDB symbol server search config dialog to allow marking symbol servers as trusted/untrusted instead of using the symbol server's connection type. (GP-4735)</li>
<li><I>PDB</I>. Improved PDB class namespaces determination and standardized some naming between PDB and MDMang. (GP-4773)</li>
<li><I>PDB</I>. Added <span class="gcode">char8_t</span> primitive type to PDB Universal analyzer. (GP-4822)</li>
<li><I>PDB</I>. Modified PDB MSDIA interpretation of malformed datatype fields with no underlying datatype. (GP-4827, Issue #6744)</li>
<li><I>Processors</I>. Fixed several PPC EVX instructions that were not affecting the destination register as a return value assigned from a pseudoOp call. (GP-4702)</li>
<li><I>Processors</I>. Added PSPEC label description tag and <span class="gcode">addr="next"</span> which allows for a large number of contiguous labels placed at an address based on the previous label without specifying the exact address of each label. (GP-4742)</li>
<li><I>Processors</I>. Processor specs now accept the <span class="gcode">volatile</span> attribute in <register> tags. (GP-4849, Issue #6755)</li>
<li><I>ProgramTree</I>. Updated the Program Tree default double-click behavior. Double-clicking now navigates instead of replacing the view. This can be changed in the tool options. (GP-4691)</li>
<li><I>Scripting</I>. GhidraScripts can now declare an <span class="gcode">@runtime</span> metadata comment to specify which GhidraScriptProvider is required to run them (e.g., <span class="gcode">Jython</span>). This will allow different GhidraScriptProviders that use the same script file extension (e.g., <span class="gcode">.py</span>) to coexist. (GP-4706)</li>
<li><I>Scripting</I>. Improved <span class="gcode">RecoverClassesFromRTTIScript</span> heuristics for determining class constructors and destructors. (GP-4764)</li>
<li><I>Scripting</I>. Changed <span class="gcode">RecoverClassesFromRTTIScript</span> virtual function definitions from using the formal signature (i.e., no <span class="gcode">this</span> param) to using <span class="gcode">void *this</span> param. This will improve the Decompiler output while continuing to not force a particular class structure on the generic definition's <span class="gcode">this</span> param. (GP-4812)</li>
<li><I>Scripting</I>. <span class="gcode">RecoverClassesFromRTTIScript</span> now caches <span class="gcode">vfunction</span> list in order to speed up processing. (GP-4863, Issue #6834)</li>
<li><I>Scripting</I>. Fixed a recursion issue in RecoverClassesFromRTTIScript. (GP-4865, Issue #6832, #6833)</li>
<li><I>Scripting</I>. Changed PasteCopiedListingBytesScript to handle hexdump format and listing bytes field split to multiple lines. (GP-4928)</li>
<li><I>Terminal</I>. Added <span class="gtitle">Select All</span> action to <span class="gtitle">Terminal</span> window. (GP-4631, Issue #6502)</li>
<li><I>Version Tracking</I>. The Version Tracking Matches table now has table column filters and now allows users to delete matches from the table (although this is not recommended). (GP-4410, Issue #6066, #6281)</li>
</ul>
</blockquote>
<blockquote><p><u><B>Bugs</B></u></p>
<ul>
<li><I>Basic Infrastructure</I>. Fixed a ClassSearcher exception that could occur when launching Ghidra in <span class="gcode">single jar mode</span>. (GP-4844, Issue #6809)</li>
<li><I>Data Types</I>. Corrected concurrency exception related to use of <span class="gcode">EnumDataType.getNames()</span> method. (GP-4797, Issue #6765)</li>
<li><I>Data Types</I>. Fixed <span class="gcode">StructureDB.delete(Set ordinals)</span> and <span class="gcode">UnionDB.delete(Set ordinals)</span> method implementations which failed to properly remove component records from database and update remaining components correctly. This method is used by the Structure and Union editors when removing components. (GP-4814)</li>
<li><I>Data Types</I>. Fixed issue in the Data Type Chooser dialog that caused inconsistent auto-complete behavior. (GP-4854)</li>
<li><I>Debugger</I>. Fixed catchpoint-related errors in GDB versions &lt;= 10. (GP-4745, Issue #6666)</li>
<li><I>Debugger</I>. Provided an initial fix for dealing with error induced by the occurrence of <span class="gcode">continue</span> during another GDB command. (GP-4750, Issue #6678)</li>
<li><I>Debugger</I>. Fixed potential register description errors when <span class="gcode">info registers all</span> or <span class="gcode">info registers general</span> are invalid. (GP-4757)</li>
<li><I>Debugger</I>. Added <span class="gcode">attach</span> script for dbgeng (WinDbg). (GP-4784, Issue #6735)</li>
<li><I>Debugger</I>. Fixed an issue with Listing display when trace overlay spaces are present. This issue had affected the dbgmodel connector. (GP-4788)</li>
<li><I>Debugger</I>. Removed test logic that was accidentally left in place. (GP-4841, Issue #6802)</li>
<li><I>Debugger</I>. Fix for potentially missing <span class="gcode">Attributes</span> field from older versions of dbgmodel. (GP-4856, Issue #6825)</li>
<li><I>Debugger</I>. The default Emulator was updated to remove TraceRmi launchers. Users should delete and re-import Emulator.tool, or remove the TraceRmiPlugin manually. (GP-4953)</li>
<li><I>Debugger:Emulator</I>. Fixed memory-space issues, especially in RegistersProvider. (GP-4781)</li>
<li><I>Debugger:Emulator</I>. Changed stack allocation to adhere to SP in program register context at PC. (GP-4834, Issue #6427)</li>
<li><I>Debugger:GDB</I>. Fixed issue with GDB continuing instead of stepping over (or out of) library function calls. (GP-4858, Issue #6822)</li>
<li><I>Debugger:Mappings</I>. Fixed launchers to adhere to <span class="gtitle">Modules</span> window's <span class="gtitle">Auto-Map</span> setting. Fixed <span class="gcode">DebuggerStaticMappingService</span> to update properly on changes. (GP-4713, Issue #6662)</li>
<li><I>Debugger:Mappings</I>. Fixed/rewrote buggy <span class="gcode">StaticMappingService</span>. (GP-4868)</li>
<li><I>Debugger:Memory</I>. Fixed stale <span class="gtitle">Force Full View</span> menu toggle when tabbing between traces. (GP-4835)</li>
<li><I>Debugger:Registers</I>. Fixed issue preventing <span class="gtitle">Registers</span> panel from displaying frames other than 0. (GP-4850)</li>
<li><I>Debugger:Watches</I>. Fixed issue in Watches where evaluation of concatenations failed. The error reported was <em>"index -1 in array of size 2"</em> or similar. (GP-4952)</li>
<li><I>Decompiler</I>. Fixed analysis of floating-point expressions in the Decompiler that could sometimes cause loss of precision in constants. (GP-2559, Issue #4586, #5785, #6708)</li>
<li><I>Decompiler</I>. Fixed a bug causing the Decompiler to fail to resolve array references properly in nested structures. (GP-4887)</li>
<li><I>Decompiler</I>. Fixed a corner case in the Decompiler for optimized division simplification where the division operands are extended from different-sized variables. (GP-4890, Issue #6648)</li>
<li><I>Decompiler</I>. Corrected a use after free vulnerability in Sleigh decompiler backend. (GP-4929, Issue #6890)</li>
<li><I>Diff Tool</I>. Fixed the <span class="gtitle">Save Default Diff Apply Settings</span> action in the <span class="gtitle">Diff Apply Settings</span> window. (GP-4670)</li>
<li><I>Eclipse Integration</I>. Fixed a GhidraDev issue that could result in a <span class="gcode">NullPointerException</span> within <span class="gcode">GhidraHelpService</span> when launching Ghidra. (GP-3490, Issue #6734)</li>
<li><I>Function</I>. Fixed an issue with incomplete function body creation due to the removal of a branching reference when the branch destination was to the next instruction and the instruction flowType had no fallthrough. (GP-4926)</li>
<li><I>GUI</I>. Fixed the Structure Editor <span class="gcode">Tab</span> key traversal. (GP-4716, Issue #5738)</li>
<li><I>GUI</I>. Fixed issue in add references dialog where moving the mouse sometimes reset the address space combo box back to the default ram space. (GP-4779)</li>
<li><I>GUI</I>. Fixed minor rendering issues with combo boxes when using the Metal Look and Feel. (GP-4818)</li>
<li><I>GUI</I>. Fixed <span class="gtitle">Structure Editor</span> sometimes not getting focus when opening. (GP-4857, Issue #6782)</li>
<li><I>GUI</I>. Fixed an exception in the Stack editor when editing and using the down arrow. (GP-4891, Issue #6883)</li>
<li><I>GUI</I>. Fixed incorrect cell being edited on <span class="gcode">Tab</span> key press while editing in the Enum Editor. (GP-4892, Issue #6873)</li>
<li><I>Importer</I>. Fixed an <span class="gcode">IndexOutOfBoundsException</span> that could occur when loading OMF binaries. (GP-4884, Issue #6862)</li>
<li><I>Importer:ELF</I>. Corrected regression bug where ELF Importer was ignoring option to disable relocation processing. (GP-4799, Issue #6751)</li>
<li><I>Importer:ELF</I>. Added missing mips opinion for R3/4 n32 automatic processor identification during import. (GP-4939)</li>
<li><I>Listing</I>. Fixed bug in the GoTo dialog where it wouldn't find a label if you had more than one namespace in the path. (GP-4761, Issue #6699)</li>
<li><I>Multi-User</I>. Fixed regression causing Version Control status not updated after check-in. (GP-4921)</li>
<li><I>PDB</I>. Supplied work-around for class that contains inner member with same class name as containing class name; pertaining to LLVM lambdas. (GP-4595)</li>
<li><I>PDB</I>. Fixed a bug in the processing of PDB MSDIA names passed from the native <span class="gcode">pdb.exe</span> processing component. Members that had a bit-field type or that had a namespace delimiter in the name were affected. (GP-4843, Issue #6788)</li>
<li><I>Processors</I>. Fixed PIC16 <span class="gcode">PCLATH</span> and <span class="gcode">RP0</span> code flow and data reference issues. (GP-4596, Issue #3239, #6466)</li>
<li><I>Processors</I>. Fixed ARM <span class="gcode">ldaexd</span> instruction semantics. (GP-4645, Issue #6526)</li>
<li><I>Processors</I>. Fixed ARM <span class="gcode">sha1su0.32</span> instruction semantics. (GP-4646, Issue #6529)</li>
<li><I>Processors</I>. Fixed ARM <span class="gcode">sha1su1.32</span> instruction semantics. (GP-4647, Issue #6530)</li>
<li><I>Processors</I>. Corrected <span class="gcode">CMOV</span> semantics when destination and source overlap. (GP-4714, Issue #6523)</li>
<li><I>Processors</I>. Fixed bug in SPARC <span class="gcode">sdivcc</span> instruction. (GP-4747, Issue #6689)</li>
<li><I>Processors</I>. Fixed m68000 <span class="gcode">ext</span> instruction not updating flags. (GP-4749, Issue #6679, #6690)</li>
<li><I>Processors</I>. Fixed extension of immediates for certain variants of the x86 <span class="gcode">SBB</span> instruction. (GP-4754, Issue #6521)</li>
<li><I>Processors</I>. Corrected semantics for x86 <span class="gcode">PEXTR</span> instructions which write to memory. (GP-4769, Issue #6511)</li>
<li><I>Processors</I>. Corrected semantics of x86 <span class="gcode">CMPPS</span> instruction. (GP-4772, Issue #6512)</li>
<li><I>Processors</I>. Added semantics for several x86 AVX instructions in use by GCC: <span class="gcode">VCVTTSx2Sx</span>, <span class="gcode">VDIVSx</span>, <span class="gcode">VINSTERT128</span>, and <span class="gcode">VEXTRACT128</span>. (GP-4776)</li>
<li><I>Processors</I>. Corrected semantics of x86 <span class="gcode">PACKUSWB</span> instruction. (GP-4777, Issue #6514)</li>
<li><I>Processors</I>. Added missing float-to-integer cast operation, <span class="gcode">trunc()</span>, to x86 <span class="gcode">CVTSD2SI</span> instruction. (GP-4778, Issue #6513)</li>
<li><I>Processors</I>. Fixed aliasing issues in certain x86 SIMD instructions. (GP-4783, Issue #6524)</li>
<li><I>Processors</I>. Fixed incorrect <span class="gcode">.sla</span> file reference in PPC e500mc processor specification. (GP-4826)</li>
<li><I>Processors</I>. Fixed issue with the M68000 <span class="gcode">fmovem.l</span> instruction using FPCR in place of FPIAR. (GP-4845, Issue #6810)</li>
<li><I>Processors</I>. Fixed sparc 32/64-bit multiply instructions. (GP-4912, Issue #6287, #6346)</li>
<li><I>ProgramDB</I>. Corrected <span class="gcode">NullPointerException</span> when setting instruction length override for a non-fallthrough instruction. (GP-4775)</li>
<li><I>References</I>. Fixed spurious replacement of small constants when the low byte of an offset matches the low byte of the reference address. Also turned the option to manipulate constants with masks and shifts to be off by default. (GP-4667, Issue #1564)</li>
<li><I>Scripting</I>. Added check in the <span class="gcode">RecoverClassesFromRTTIScript</span> to make sure <span class="gcode">ClassHierarchyDescriptor</span> symbols are in a non-Global namespace before trying to promote their namespace to a class namespace. If such symbols are found in the Global namespace it indicates potential issues with either the RTTI data or the processing of the RTTI data; in these cases, no class recovery will be done for the associated classes. (GP-4763, Issue #6704)</li>
<li><I>Scripting</I>. Fixed <span class="gcode">NullPointerException</span> in <span class="gcode">PropagateExternalParametersScript</span>. (GP-4883, Issue #6841)</li>
<li><I>Scripting</I>. Fixed CodeUnitInsertionException error in RecoverClassesFromRTTIScript.java script. (GP-4932, Issue #6848)</li>
</ul>
</blockquote>
<blockquote><p><u><B>Notable API Changess</B></u></p>
<ul>
<li><I>Search</I>. (GP-4559)
The MemorySearchService has been changed. This had been a very specific service API created to support just one plugin and was not generally useful. The three existing methods have been consolidated into one method. The old service has been marked as deprecated and may be removed in future releases. If, in the unlikely event that anyone is using this service, please contact the Ghidra team to discuss your use case.
</li>
<li><I>Data Types</I>. (GP-4949)
Added API method <span class="gcode">Structure.setLength(int length)</span> which allows the size of a non-packed structure to be set.
</li>
<li><I>Debugger:Agents</I>. (GP-4847)
<span class="gcode">LaunchConfigurator.configureLauncher()</span> is changed such that <span class="gcode">arguments</span> now requires <span class="gcode">ValStr&lt;?&gt;</span> instead of just <span class="gcode">?</span> for its values. This affects both the new Trace-RMI launchers and the deprecated object-model launchers.
</li>
</ul>
</blockquote>
<H1 align="center">Ghidra 11.1.2 Change History (July 2024)</H1> <H1 align="center">Ghidra 11.1.2 Change History (July 2024)</H1>
<blockquote><p><u><B>New Features</B></u></p> <blockquote><p><u><B>New Features</B></u></p>
<ul> <ul>

View File

@ -47,19 +47,25 @@
</P> </P>
<hr> <hr>
<H1>What's New in Ghidra 11.1</H1> <H1>What's New in Ghidra 11.2</H1>
<H2>The not-so-fine print: Please Read!</H2>
<P>This release includes new features, enhancements, performance improvements, quite a few bug fixes, and many pull-request <P>This release includes new features, enhancements, performance improvements, quite a few bug fixes, and many pull-request
contributions. Thanks to all those who have contributed their time, thoughts, and code. The Ghidra user community thanks you too!</P> contributions. Thanks to all those who have contributed their time, thoughts, and code. The Ghidra user community thanks you too!</P>
<P>Ghidra 11.x is fully backward compatible with project data from previous releases. <H2>The not-so-fine print: Please Read!</H2>
However, programs and data type archives which are created or modified in 11.x will not be usable by an earlier Ghidra version. </P>
<P>This distribution requires at minimum JDK 17 to run, but can also run under JDK 21.</P> <P>Ghidra 11.2 is fully backward compatible with project data from previous releases.
However, programs and data type archives which are created or modified in 11.2 will not be usable by an earlier Ghidra version.</P>
<P>NOTE: Each build distribution will include native components (e.g., decompiler) for at least one platform (e.g., Windows x86-64). <P><span class="gtitle">IMPORTANT:</span> Ghidra 11.2 requires at minimum JDK 21 to run.</P>
<P><span class="gtitle">IMPORTANT:</span> To use the Debugger or do a full source distribution build, you will need Python3 (3.9 to 3.12 supported) installed on your system.</P>
<P><span class="gtitle">NOTE:</span> There have been reports of certain features causing the XWindows server to crash. A fix for
CVE-2024-31083 in X.org software in April 2024 introduced a regression, which has been fixed in xwayland 23.2.6 and xorg-server 21.1.13. If you experience
any crashing of Ghidra, most likely causing a full logout, check if your xorg-server has been updated to at least the noted version.</P>
<P><span class="gtitle">NOTE:</span> Each build distribution will include native components (e.g., decompiler) for at least one platform (e.g., Windows x86-64).
If you have another platform that is not included in the build distribution, you can build If you have another platform that is not included in the build distribution, you can build
native components for your platform directly from the distribution. native components for your platform directly from the distribution.
See the <a href="InstallationGuide.html">Ghidra Installation Guide</a> for additional information. See the <a href="InstallationGuide.html">Ghidra Installation Guide</a> for additional information.
@ -67,13 +73,11 @@
compatibility errors when launching native executables such as the Decompiler and GNU Demangler which compatibility errors when launching native executables such as the Decompiler and GNU Demangler which
may necessitate a rebuild of native components.</P> may necessitate a rebuild of native components.</P>
<P>IMPORTANT: To use the Debugger, you will need Python3 (3.7 to 3.12 supported) installed on your system.</P> <P><span class="gtitle">NOTE:</span> Ghidra Server: The Ghidra 11.x server is compatible with Ghidra 9.2 and later Ghidra clients. Ghidra 11.x
<P>NOTE: Ghidra Server: The Ghidra 11.x server is compatible with Ghidra 9.2 and later Ghidra clients. Ghidra 11.x
clients are compatible with all 10.x and 9.x servers. Although, due to potential Java version differences, it is recommended clients are compatible with all 10.x and 9.x servers. Although, due to potential Java version differences, it is recommended
that Ghidra Server installations older than 10.2 be upgraded. Those using 10.2 and newer should not need a server upgrade.</P> that Ghidra Server installations older than 10.2 be upgraded. Those using 10.2 and newer should not need a server upgrade.</P>
<P>NOTE: Any programs imported with a Ghidra beta version or code built directly from source code outside of a release tag may not be compatible, <P><span class="gtitle">NOTE:</span> Any programs imported with a Ghidra beta version or code built directly from source code outside of a release tag may not be compatible,
and may have flaws that won't be corrected by using this new release. Any programs analyzed from a beta or other local master source build should be considered and may have flaws that won't be corrected by using this new release. Any programs analyzed from a beta or other local master source build should be considered
experimental and re-imported and analyzed with a release version.</P> experimental and re-imported and analyzed with a release version.</P>
@ -82,147 +86,76 @@
Ghidra versions. You might consider comparing a fresh import of any program you will continue to reverse engineer to see if the latest Ghidra Ghidra versions. You might consider comparing a fresh import of any program you will continue to reverse engineer to see if the latest Ghidra
provides better results.</P> provides better results.</P>
<H2>Debugger </H2> <H2>Memory Search</H2>
<P><span class="gtitle">ATTENTION:</span> Please delete and re-import the default Debugger tool!</P> <P>The <span class="gtitle">Search Memory</span> feature in Ghidra has been updated substantially to provide two new features:</P>
<P> We are introducing a new debugger connection system called Trace RMI. This is replacing the older system,
which we are calling the Recorder system.</P>
<P>The most noticeable difference will be a new menu for launching targets. It is very similar to the previous system, but with some key differences:</P>
<BLOCKQUOTE> <BLOCKQUOTE>
<UL> <UL>
<LI>Connection and launching are no longer separated into two different configuration panels. There is one panel to launch your target.</LI> <LI>The ability to perform set operations on successive searches</LI>
<LI>Ghidra will no longer attempt to launch blindly with defaults. The first time you launch a program, you must select a launcher and configure it.</LI> <LI>The ability to (re)scan memory for changes in value</LI>
<LI>After the initial launch you can re-launch with a previous configuration, without requiring a prompt.</LI>
</UL> </UL>
</BLOCKQUOTE> </BLOCKQUOTE>
<P>The next most noticeable difference will be the replacement of the Interpreter window with the Terminal window. This is a proper VT-100 <P>Set operations, accessible from the pull-down menu under <span class="gtitle">Search</span>, allow you to augment
terminal emulator, so the experience will be much like, if not identical to, how you'd debug in a plain terminal, except embedded into and integrated with Ghidra. results by performing boolean operations on an existing search. For example, you might search for the hex pattern "DE AD" using <span class="gtitle">Search</span>,
Some notable improvements that brings:</P> add "BE EF" to the pattern field, and then select "A-B" to retrieve a list of byte sequences that begin with "DE AD" but do not include "DE AD BE EF".
<BLOCKQUOTE> Scanning for changes is most useful in a dynamic environment, such as the Debugger. Given an existing search, you can look for values that have changed,
<UL> increased, decreased, or remained the same. Simple examples might include looking for counters while a process is running, checking for areas of decompressed
<LI>Tab completion, history, etc., should all work as implemented by the connected debugger's command-line interface.</LI> memory, or identifying active areas of the heap.</P>
<LI>When the target is running, it has proper I/O in that terminal.</LI>
<LI>If connecting goes poorly for some reason, the debugger's command-line interface is likely still operational.</LI>
</UL>
</BLOCKQUOTE>
<P>You may also notice the replacement of the Debugger Targets window with the Connection Manager window, and the replacement <H2>PDB</H2>
of the Objects window with the Model window. These are operationally very similar to their previous counterparts.</P>
<P><span class="gtitle">For Power Users:</span> The launchers are just shell scripts on Linux and macOS, and batch files on Windows. We have provided plugins <P>The PDB Symbol Server Search Config dialog has been changed, allowing the user to mark symbol servers as trusted or untrusted.
for integrating with GDB, LLDB, and the Windows Debugger. So long as your target works with one of these debuggers, orchestrating This is an improvement over the previous mechanism that based trust on the symbol server's connection type.</P>
another kind of target is mostly a matter of creating a new shell script. This is usually accomplished by using the most similar
one as a template and then trying it out in Ghidra. When errors occur, Ghidra will inform you of what progress it made before it
failed, and the Terminal should display any error messages produced by your script.</P>
<P><span class="gtitle">For Developers:</span> Developers may notice that debugger integration is now all done using Python 3. <H2>Debugger</H2>
We have specified a new protocol we call Trace RMI, which provides client access to Ghidra's trace databases over TCP.
It uses protobuf and is substantially simpler than the previous GADP protocol. We have provided the client implementation in
Python 3. Existing integrations can be fairly easily extended, if necessary. For example, see the support for Wine we included in our GDB plugin.</P>
<P>If you wish to integrate a completely new debugger, and it has a Python 3 API, then things are relatively straightforward, so long as <P><span class="gtitle">ATTENTION:</span> Please either delete and re-import the default Emulator tool, or
the debugger provides the events and information that Ghidra expects. Use an existing plugin as a template or reference and have fun. manually remove the TraceRmiPlugin from your EmulatorTool!</P>
If the new debugger does not have Python 3 bindings, the protobuf specification is available, so the client can be ported, if necessary.</P>
<P><span class="gtitle">IMPORTANT:</span> To use the new Trace RMI system, you will need Python3 (3.7 to 3.12 supported) installed on your system. <P>There are new launchers/features for the traceRMI version of dbgeng, including extended launch options, kernel debugging, and
Additional setup may be required for each type of debug connection. Press <span class="gtitle">F1</span> in the debug connector's launch dialog remote process server connections.</P>
for more information.</P>
<P>Overall, we believe this a substantially more approachable system than our previous DebuggerObjectModel SPI used in the Recorder system.</P> <H2>Decompiler</H2>
<P>The Decompiler can now automatically recover strings built on the stack and initial support for optimized heap strings has been added.
Stack strings are typically found in optimized code and obfuscated malware.</P>
<H2>GhidraGo </H2> <P>A new Search All action has been added which displays a table containing the results found within the current function.</P>
<P>GhidraGo is an experimental feature that adds integration support for Ghidra URL's and Ghidra Tools. GhidraGO can now process GhidraURL's that <H2>Programming Languages</H2>
locate folders within a project instead of only programs. For example a remote GhidraURL locating a project folder will open a read only view of
the repository in the front end tool and select the folder from the URL. If the GhidraURL refers to a folder in the currently open
active project, then the folder is selected within the active project's view instead of a read only view.
</P>
<H2>PDB </H2> <P>Golang support for versions 1.15 and 1.16 have been added. This brings the supported Golang versions to 1.15 thru 1.22.</P>
<P>The PDB data type processing changes from release 11.0 have been further enhanced, simplifying the processing model and reducing the number of datatype
conflicts. The algorithm for choosing the primary symbol at an address has been improved to provide the richest possible information. The PDB Universal
Analyzer has been split into multiple analyzers so that PDB function processing can follow interim analyzers that specialize in finding code.
Lastly, the Load PDB Task has been improved to schedule appropriate follow-on analyzers that are selected in the Analysis Options.</P>
<H2>Version Tracking </H2> <H2>Processors</H2>
<P> Version Tracking Session files may now be added to a shared project repository. Once a version tracking file has been checked in to a project, <P>There have been quite a few improvements to the Sparc processor specification, including additional instructions, 64-bit relocation support, and better
it must be checked out for exclusive access. For more information, see help found in the Version Tracking's handling of call/return detection through tracking of the o7 link register. In addition, the calling convention for both sparc 32 and 64 bit binaries
Session Wizard help for more information.</P> have had an overhaul to support hidden structure return and much improved parameter allocation of floating point and general data types.</P>
<P>NOTE: Prior to adding a pre-existing VT Session to a shared project repository, it is highly recommended that it first be re-opened <P>The Intel M16C/60/80 sleigh processor specifications have been added. In addition, there have been numerous fixes to the
and saved. This will upgrade the VT Session internal version to prevent its use with older versions of Ghidra which will not respect ARM, RX, M68000, PIC16, PPC, and x86 processor specifications.</P>
the exclusive checkout requirement.</P>
<H2>Mach-O Improvements</H2> <H2>Other Improvements</H2>
<P>Mach-O support continues to improve, adding support for new features as well as filling in some gaps that existed for several years.
The latest dyld_shared_cache files use a new format for pointer fixups, which Ghidra now supports. A new GFileSystem has also been
implemented to import and/or extract individual Mach-O binaries from Mach-O "file sets" (i.e., kernelcache). A second new GFileSystem
has been added which can extract Apple LZFSE-compressed files. Other improvements have also been made to provide more complete markup of Mach-O load commands.</P>
<H2>Swift </H2> <P>Actions have been added to compare functions directly from the Listing, Decompiler, or Functions Table via popup menu items. If there
<P>Initial support for binaries written in the Swift Programming Language has been added. The new support relies on the native Swift demangler being is already a Function Comparison window showing, there are two actions: one to add the selected function(s) to the existing comparison, and
present on the user's system. Swift is automatically bundled with XCode on macOS, and can be optionally installed on Windows and Linux. one to create a new Function Comparison Window. This allows a workflow where users can build up a set of functions to compare as they browse
See the "Demangler Swift" analyzer options for more information. Type information gathered from the demangled Swift symbol names is used to around instead of having to select them all at once.</P>
create corresponding Ghidra data types. This currently works for Swift primitives and structures, but more work needs to be done to include
classes and other advanced data types. Swift-specific calling conventions are also applied to demangled Swift functions.</P>
<H2>Usability </H2> <P>For Ghidra script and plugin developers who would prefer to use Visual Studio Code, a new script VSCodeProjectScript will create a new
Visual Studio Code project that is setup to do Ghidra scripting and module development. The capabilities are similar to the Eclipse
GhidraDev plugin.</P>
<P>There have been many improvements to keyboard only actions and navigation in Ghidra. These changes will be welcome for those who <P>There have been major speed improvements when creating or modifying large structures within the structure editor. In general large structure manipulation
prefer to use the keyboard as much as possible and those needing better accessibility. Improvements include:</P> should perform fluidly no matter the size of the structure. If the structure contains a large number of defined data, there could still be some degradation in
<BLOCKQUOTE> speed. Some fixed performance issues include: resizing a structure smaller or larger, clicking on an item to select a row, and defining a data type either with keyboard actions or dragging
<UL> and dropping from the data type manager. In addition, the behavior of automatically growing the size of a structure has been made consistent. Defining data on the last element of a structure
<LI>Standard keyboard navigation should now work in most component windows and dialogs. In general, <span class="gtitle">Tab</span> and <span class="gtitle">&lt;CTRL&gt; Tab</span> will is allowed to automatically grow the structure to fit the data type. Defining data anywhere other than the last element isn't allowed if the data type does not fit because
move focus to the next focusable component and <span class="gtitle">&lt;SHIFT&gt; Tab</span> and <span class="gtitle">&lt;CTRL&gt;&lt;SHIFT&gt; Tab</span> will move to the of defined data that would need to be cleared, or there are not enough undefined bytes.</P>
previous focusable component. <span class="gtitle">Tab</span> and <span class="gtitle">&lt;SHIFT&gt; Tab</span> do not always work as some components use those keys internally, but
<span class="gtitle">&lt;CTRL&gt; Tab,</span> and <span class="gtitle">&lt;SHIFT&gt;&lt;CTRL&gt; Tab</span> should work universally.</LI>
<LI>Ghidra now provides some convenient keyboard shortcut actions for transferring focus:</LI>
<UL>
<LI><span class="gtitle">&lt;CTRL&gt; F3</span> - Transfers focus to the next window or dialog.</LI>
<LI><span class="gtitle">&lt;CTRL&gt;&lt;SHIFT&gt; F3</span> - Transfers focus to the previous window or dialog.</LI>
<LI><span class="gtitle">&lt;CTRL&gt; J</span> - Transfers focus to the next titled dockable component (titled windows).</LI>
<LI><span class="gtitle">&lt;CTRL&gt;&lt;SHIFT&gt; J</span> - Transfers focus to the previous titled dockable component.</LI>
</UL>
<LI>All actions can now be accessed via a searchable dialog.</LI>
<UL>
<LI>Pressing <span class="gtitle">&lt;CTRL&gt; 3</span> will bring up the actions dialog with the local toolbar, popup and keyboard actions.</LI>
<LI>Pressing <span class="gtitle">&lt;CTRL&gt; 3</span> a second time will add in all the global actions. </LI>
<LI>Pressing <span class="gtitle">&lt;CTRL&gt; 3</span> a third time will add in the disabled actions as well.</LI>
<LI>The actions dialog was specifically designed to be easy to use without a mouse. Typing will filter the actions list and the
arrow keys allow you to select an action and enter will invoke the selected action </LI>
</UL>
</UL>
</BLOCKQUOTE>
<H2>Other Improvements </H2>
<P>Support for the <span class="gtitle">SquashFS</span> filesystem has been added.</P>
<P>A new wildcard assembler API has been added that can generate all possible variants of an instruction with a variety of wildcards for operands.
Two new scripts, <span class="gtitle">FindInstructionWithWildcard</span> and <span class="gtitle">WildSleighAssemblerInfo</span>, demonstrate how to use the API.
For more information, see help and search for <span class="gtitle">Wildcard Assembler</span>.
<P>A new <span class="gtitle">Runtime Information</span> dialog has replaced the Show VM Memory dialog. The dialog contains more information
which can aid in debugging, including version information, classpath, defined properties, environment variables, and more.</P>
<P>The GhidraDev Eclipse plugin has a new wizard for importing an existing Ghidra module source directory. This will work best with Ghidra module projects
created against Ghidra 11.1 or later.</P>
<P>Finding references to fields within a structure has been greatly improved. Previously many references to the field would be missed if they occurred within
functions calling external functions using the structure, or when the field was used only in local variables dynamically generated by
the decompiler.</P>
<P>Golang versions 17 thru 22 are now supported.</P>
<P>DWARF5 debug format is now supported. In addition, DWARF line number information processing has been incorporated into the base DWARF analyzer and the
separate DWARF line number analyzer has been removed.</P>
<H2>Additional Bug Fixes and Enhancements</H2> <H2>Additional Bug Fixes and Enhancements</H2>
<P> Numerous other new features, improvements, and bug fixes are fully listed in the <a href="ChangeHistory.html">ChangeHistory</a> file.</P> <P> Numerous other new features, improvements, and bug fixes are fully listed in the <a href="ChangeHistory.html">ChangeHistory</a> file.</P>
<div align="center"> <div align="center">

View File

@ -20,13 +20,33 @@ import java.lang.annotation.Annotation;
import javax.lang.model.element.*; import javax.lang.model.element.*;
import javax.tools.Diagnostic.Kind; import javax.tools.Diagnostic.Kind;
import ghidra.util.database.DBAnnotatedObject;
/**
* An abstract class for validating annotations on {@link DBAnnotatedObject}.
*
* <p>
* Performs validation checks on annotated fields and their enclosing types.
*/
public class AbstractDBAnnotationValidator { public class AbstractDBAnnotationValidator {
protected final ValidationContext ctx; protected final ValidationContext ctx;
/**
* Construct a new {@code AbstractDBAnnotationValidator} with the specified validation context.
*
* @param ctx the validation context
*/
public AbstractDBAnnotationValidator(ValidationContext ctx) { public AbstractDBAnnotationValidator(ValidationContext ctx) {
this.ctx = ctx; this.ctx = ctx;
} }
/**
* Check the enclosing type of the annotated field.
*
* @param annotType the type of the annotation being validated
* @param field the field being validated
* @param type the enclosing type of the field
*/
protected void checkEnclosingType(Class<? extends Annotation> annotType, VariableElement field, protected void checkEnclosingType(Class<? extends Annotation> annotType, VariableElement field,
TypeElement type) { TypeElement type) {
if (type.getKind() != ElementKind.CLASS) { if (type.getKind() != ElementKind.CLASS) {

View File

@ -19,6 +19,10 @@ import java.util.Set;
import javax.lang.model.element.Modifier; import javax.lang.model.element.Modifier;
/**
* An enum to represent different levels of access specifiers (private, package-private, protected,
* public) with corresponding access levels
*/
public enum AccessSpec { public enum AccessSpec {
PRIVATE(0), PACKAGE(1), PROTECTED(2), PUBLIC(3); PRIVATE(0), PACKAGE(1), PROTECTED(2), PUBLIC(3);
@ -29,7 +33,7 @@ public enum AccessSpec {
} }
/** /**
* Checks if the second permits the same or more access than the first * Check if the second permits the same or more access than the first
* *
* @param first the first * @param first the first
* @param second the second * @param second the second

View File

@ -22,14 +22,43 @@ import javax.tools.Diagnostic.Kind;
import ghidra.util.database.annot.DBAnnotatedColumn; import ghidra.util.database.annot.DBAnnotatedColumn;
/**
* A class for validating fields annotated with {@link DBAnnotatedColumn}.
*
* <p>
* To ensure fields annotated with {@link DBAnnotatedColumn} comply with the expected criteria for
* database columns in Ghidra.
* </p>
*/
public class DBAnnotatedColumnValidator extends AbstractDBAnnotationValidator { public class DBAnnotatedColumnValidator extends AbstractDBAnnotationValidator {
final VariableElement column; final VariableElement column;
/**
* Construct a new {@code DBAnnotatedColumnValidator} with the specified validation context and
* the column element.
*
* @param ctx the validation context
* @param column the field representing the column
*/
public DBAnnotatedColumnValidator(ValidationContext ctx, VariableElement column) { public DBAnnotatedColumnValidator(ValidationContext ctx, VariableElement column) {
super(ctx); super(ctx);
this.column = column; this.column = column;
} }
/**
* Validate the annotated column field.
*
* <p>
* It performs the following checks to ensure it meets the requirements for database columns:
* <ul>
* <li>The field must be of the type specified by {@code ctx.DB_OBJECT_COLUMN_ELEM}.</li>
* <li>The field must not be declared as {@code final}.</li>
* <li>The field must be declared as {@code static}.</li>
* <li>The enclosing type of the field must meet the criteria defined in
* {@code checkEnclosingType}.</li>
* </ul>
*/
public void validate() { public void validate() {
if (!ctx.hasType(column, ctx.DB_OBJECT_COLUMN_ELEM)) { if (!ctx.hasType(column, ctx.DB_OBJECT_COLUMN_ELEM)) {
ctx.messager.printMessage(Kind.ERROR, ctx.messager.printMessage(Kind.ERROR,

View File

@ -23,6 +23,14 @@ import javax.tools.Diagnostic.Kind;
import ghidra.util.database.annot.DBAnnotatedField; import ghidra.util.database.annot.DBAnnotatedField;
/**
* A class for validating fields annotated with {@link DBAnnotatedField}
*
* <p>
* To ensure fields annotated with {@link DBAnnotatedField} meet the criteria required for database
* fields in Ghidra. It extends the {@code AbstractDBAnnotationValidator} to provide additional
* validation logic specific to database field annotations.
*/
public class DBAnnotatedFieldValidator extends AbstractDBAnnotationValidator { public class DBAnnotatedFieldValidator extends AbstractDBAnnotationValidator {
final VariableElement field; final VariableElement field;
final Map<TypeMirror, TypeElement> javaToDBTypeMap; final Map<TypeMirror, TypeElement> javaToDBTypeMap;
@ -39,6 +47,13 @@ public class DBAnnotatedFieldValidator extends AbstractDBAnnotationValidator {
final TypeElement ENUM_CODEC_ELEM; final TypeElement ENUM_CODEC_ELEM;
/**
* Construct a new {@code DBAnnotatedFieldValidator} with the specified validation context and
* field element.
*
* @param ctx the validation context
* @param field the field to validate
*/
public DBAnnotatedFieldValidator(ValidationContext ctx, VariableElement field) { public DBAnnotatedFieldValidator(ValidationContext ctx, VariableElement field) {
super(ctx); super(ctx);
this.field = field; this.field = field;
@ -59,6 +74,13 @@ public class DBAnnotatedFieldValidator extends AbstractDBAnnotationValidator {
ENUM_CODEC_ELEM = ctx.elementUtils.getTypeElement(ENUM_CODEC_NAME); ENUM_CODEC_ELEM = ctx.elementUtils.getTypeElement(ENUM_CODEC_NAME);
} }
/**
* Associate a primitive type and its boxed type with the specified codec type in the map.
*
* @param map the map linking java types to their corresponding codec types
* @param kind the primitive type kind
* @param codecName the fully qualified name of the codec type
*/
protected void putPrimitiveTypeCodec(Map<TypeMirror, TypeElement> map, TypeKind kind, protected void putPrimitiveTypeCodec(Map<TypeMirror, TypeElement> map, TypeKind kind,
String codecName) { String codecName) {
PrimitiveType primitive = ctx.typeUtils.getPrimitiveType(kind); PrimitiveType primitive = ctx.typeUtils.getPrimitiveType(kind);
@ -68,12 +90,26 @@ public class DBAnnotatedFieldValidator extends AbstractDBAnnotationValidator {
map.put(boxed, codec); map.put(boxed, codec);
} }
/**
* Associate a specified class type with the specified codec type in the map.
*
* @param map the map linking Java types to their corresponding codec types
* @param cls the class type
* @param codecName the fully qualified name of the codec type
*/
protected void putTypeCodec(Map<TypeMirror, TypeElement> map, Class<?> cls, String codecName) { protected void putTypeCodec(Map<TypeMirror, TypeElement> map, Class<?> cls, String codecName) {
TypeMirror type = ctx.elementUtils.getTypeElement(cls.getCanonicalName()).asType(); TypeMirror type = ctx.elementUtils.getTypeElement(cls.getCanonicalName()).asType();
TypeElement codec = ctx.elementUtils.getTypeElement(codecName); TypeElement codec = ctx.elementUtils.getTypeElement(codecName);
map.put(type, codec); map.put(type, codec);
} }
/**
* Associate a primitive array type with the specified codec type inthe map.
*
* @param map the map linking Java types to their corresponding codec types
* @param kind the primitive type kind
* @param codecName the fully qualified name of the codec type
*/
protected void putPrimitiveArrayTypeCodec(Map<TypeMirror, TypeElement> map, TypeKind kind, protected void putPrimitiveArrayTypeCodec(Map<TypeMirror, TypeElement> map, TypeKind kind,
String codecName) { String codecName) {
PrimitiveType primitive = ctx.typeUtils.getPrimitiveType(kind); PrimitiveType primitive = ctx.typeUtils.getPrimitiveType(kind);
@ -82,6 +118,19 @@ public class DBAnnotatedFieldValidator extends AbstractDBAnnotationValidator {
map.put(array, codec); map.put(array, codec);
} }
/**
* Validate the annotated field to ensure it meets the requirements for database fields.
*
* <p>
* It performs the following checks:
* <ul>
* <li>The field must not be declared as {@code final}.</li>
* <li>The field must not be declared as {@code static}.</li>
* <li>The enclosing type of the field must meet the criteria defined in
* {@code checkEnclosingType}.</li>
* <li>The codec types for the field must be appropriate.</li>
* </ul>
*/
public void validate() { public void validate() {
Set<Modifier> mods = field.getModifiers(); Set<Modifier> mods = field.getModifiers();
if (mods.contains(Modifier.FINAL)) { if (mods.contains(Modifier.FINAL)) {
@ -101,6 +150,12 @@ public class DBAnnotatedFieldValidator extends AbstractDBAnnotationValidator {
checkCodecTypes(type); checkCodecTypes(type);
} }
/**
* Return the default codec type element for the specified Java type.
*
* @param javaType the Java type for which the default codec is needed
* @return the default codec type element, or {@code null} if no default codec is found
*/
protected TypeElement getDefaultCodecType(TypeMirror javaType) { protected TypeElement getDefaultCodecType(TypeMirror javaType) {
if (ctx.isEnumType(javaType)) { if (ctx.isEnumType(javaType)) {
return ENUM_CODEC_ELEM; return ENUM_CODEC_ELEM;
@ -108,6 +163,12 @@ public class DBAnnotatedFieldValidator extends AbstractDBAnnotationValidator {
return javaToDBTypeMap.get(javaType); return javaToDBTypeMap.get(javaType);
} }
/**
* Return the codec type element specified in the {@link DBAnnotatedField} annotation for the
* field, or the default codec type if none is specified.
*
* @return the codec type element for the field
*/
protected TypeElement getCodecTypeElement() { protected TypeElement getCodecTypeElement() {
DBAnnotatedField annotation = field.getAnnotation(DBAnnotatedField.class); DBAnnotatedField annotation = field.getAnnotation(DBAnnotatedField.class);
TypeElement codecElem; TypeElement codecElem;
@ -123,6 +184,12 @@ public class DBAnnotatedFieldValidator extends AbstractDBAnnotationValidator {
return codecElem; return codecElem;
} }
/**
* Check the codec types associated with the field to ensure they meet the necessary
* requirements.
*
* @param objectType the type of the enclosing object
*/
protected void checkCodecTypes(TypeElement objectType) { protected void checkCodecTypes(TypeElement objectType) {
TypeElement codecType = getCodecTypeElement(); TypeElement codecType = getCodecTypeElement();

View File

@ -29,8 +29,10 @@ import ghidra.util.database.annot.*;
/** /**
* A compile-time annotation processor for {@link DBAnnotatedObject}-related annotations. * A compile-time annotation processor for {@link DBAnnotatedObject}-related annotations.
* *
* Currently just performs compile-time checks. It does not generate any code, but perhaps one day, * <p>
* it will. * This processor performs compile-time validation checks on annotations related to
* {@link DBAnnotatedObject}. Currently just performs compile-time checks. It does not generate any
* code, but perhaps one day, it will.
*/ */
//@AutoService(Processor.class) // TODO: Evaluate Google's auto-service as a dependency //@AutoService(Processor.class) // TODO: Evaluate Google's auto-service as a dependency
public class DBAnnotatedObjectProcessor extends AbstractProcessor { public class DBAnnotatedObjectProcessor extends AbstractProcessor {
@ -39,6 +41,11 @@ public class DBAnnotatedObjectProcessor extends AbstractProcessor {
private ValidationContext ctx; private ValidationContext ctx;
/**
* Initialize the processor with the given preprocessing environment.
*
* @param env the processing environment
*/
@Override @Override
public synchronized void init(ProcessingEnvironment env) { public synchronized void init(ProcessingEnvironment env) {
//System.err.println("HERE4"); //System.err.println("HERE4");
@ -46,6 +53,14 @@ public class DBAnnotatedObjectProcessor extends AbstractProcessor {
ctx = new ValidationContext(env); ctx = new ValidationContext(env);
} }
/**
* Process the specified annotations for the current round of processing..
*
* @param annotations the set of annotations to process
* @param roundEnv the environment for information about the current and prior round
* @return {@code true} if the annotations are claimed by this processor, {@code false}
* otherwise
*/
@Override @Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Map<TypeElement, DBAnnotatedObjectValidator> types = new LinkedHashMap<>(); Map<TypeElement, DBAnnotatedObjectValidator> types = new LinkedHashMap<>();
@ -76,21 +91,40 @@ public class DBAnnotatedObjectProcessor extends AbstractProcessor {
return true; return true;
} }
/**
* Provide completion suggestion for the specified element, annotation, and member.
*
* @param element the element being annotated
* @param annotation the annotation being processed
* @param member the annotation member being completed
* @param userText the text entered by the user
* @return an iterable of completions.
*/
@Override @Override
public Iterable<? extends Completion> getCompletions(Element element, public Iterable<? extends Completion> getCompletions(Element element,
AnnotationMirror annotation, ExecutableElement member, String userText) { AnnotationMirror annotation, ExecutableElement member, String userText) {
// TODO Auto-generated method stub
return super.getCompletions(element, annotation, member, userText); return super.getCompletions(element, annotation, member, userText);
} }
/**
* Return the latest supported source version.
*
* @return the latest supported source version
*/
@Override @Override
public SourceVersion getSupportedSourceVersion() { public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported(); return SourceVersion.latestSupported();
} }
/**
* Return the set of supported annotation types.
*
* @return the set of supported annotation types
*/
@Override @Override
public Set<String> getSupportedAnnotationTypes() { public Set<String> getSupportedAnnotationTypes() {
return SUPPORTED_ANNOTATIONS.stream().map(Class::getCanonicalName).collect( return SUPPORTED_ANNOTATIONS.stream()
Collectors.toSet()); .map(Class::getCanonicalName)
.collect(Collectors.toSet());
} }
} }

View File

@ -20,31 +20,62 @@ import java.util.*;
import javax.lang.model.element.*; import javax.lang.model.element.*;
import javax.tools.Diagnostic.Kind; import javax.tools.Diagnostic.Kind;
import ghidra.util.database.DBAnnotatedObject;
import ghidra.util.database.annot.*; import ghidra.util.database.annot.*;
/**
* Validate {@link DBAnnotatedObject}-related annotations on a given type element.
*
* <p>
* This class ensures that annotations such as {@link DBAnnotatedField}, {@link DBAnnotatedColumn},
* and {@link DBAnnotatedObjectInfo} are applied correctly and consistently on the fields and
* columns of a class.
*/
public class DBAnnotatedObjectValidator { public class DBAnnotatedObjectValidator {
private final ValidationContext ctx; private final ValidationContext ctx;
private final TypeElement type; private final TypeElement type;
private final Map<String, DBAnnotatedFieldValidator> fieldsByName = new LinkedHashMap<>(); private final Map<String, DBAnnotatedFieldValidator> fieldsByName = new LinkedHashMap<>();
private final Map<String, DBAnnotatedColumnValidator> columnsByName = new LinkedHashMap<>(); private final Map<String, DBAnnotatedColumnValidator> columnsByName = new LinkedHashMap<>();
/**
* Construct a new validator for the given type element within the specified validation context
*
* @param ctx the validation context
* @param type the type element to be validated
*/
public DBAnnotatedObjectValidator(ValidationContext ctx, TypeElement type) { public DBAnnotatedObjectValidator(ValidationContext ctx, TypeElement type) {
this.ctx = ctx; this.ctx = ctx;
this.type = type; this.type = type;
} }
/**
* Add a field annotated with {@link DBAnnotatedField} to be validator.
*
* @param field the field element annotated with {@link DBAnnotatedField}
*/
public void addAnnotatedField(VariableElement field) { public void addAnnotatedField(VariableElement field) {
DBAnnotatedField annotation = field.getAnnotation(DBAnnotatedField.class); DBAnnotatedField annotation = field.getAnnotation(DBAnnotatedField.class);
assert annotation != null; assert annotation != null;
fieldsByName.put(annotation.column(), new DBAnnotatedFieldValidator(ctx, field)); fieldsByName.put(annotation.column(), new DBAnnotatedFieldValidator(ctx, field));
} }
/**
* Add a column annotated with {@link DBAnnotatedColumn} to the validator.
*
* @param column the field element annotated with {@link DBAnnotatedColumn}
*/
public void addAnnotatedColumn(VariableElement column) { public void addAnnotatedColumn(VariableElement column) {
DBAnnotatedColumn annotation = column.getAnnotation(DBAnnotatedColumn.class); DBAnnotatedColumn annotation = column.getAnnotation(DBAnnotatedColumn.class);
assert annotation != null; assert annotation != null;
columnsByName.put(annotation.value(), new DBAnnotatedColumnValidator(ctx, column)); columnsByName.put(annotation.value(), new DBAnnotatedColumnValidator(ctx, column));
} }
/**
* Validate the annotated fields, columns, and the type element itself.
*
* <p>
* Checks for various annotation constraints and consistency rules.
*/
public void validate() { public void validate() {
DBAnnotatedObjectInfo annotation = type.getAnnotation(DBAnnotatedObjectInfo.class); DBAnnotatedObjectInfo annotation = type.getAnnotation(DBAnnotatedObjectInfo.class);
if (annotation != null && type.getKind() != ElementKind.CLASS) { if (annotation != null && type.getKind() != ElementKind.CLASS) {
@ -81,18 +112,27 @@ public class DBAnnotatedObjectValidator {
checkMissing(); checkMissing();
} }
/**
* Validate all fields annotated with {@link DBAnnotatedField}.
*/
protected void validateFields() { protected void validateFields() {
for (DBAnnotatedFieldValidator fv : fieldsByName.values()) { for (DBAnnotatedFieldValidator fv : fieldsByName.values()) {
fv.validate(); fv.validate();
} }
} }
/**
* Validate all columns annotated with {@link DBAnnotatedColumn}.
*/
protected void validateColumns() { protected void validateColumns() {
for (DBAnnotatedColumnValidator cv : columnsByName.values()) { for (DBAnnotatedColumnValidator cv : columnsByName.values()) {
cv.validate(); cv.validate();
} }
} }
/**
* Check for missing corresponding annotations between fields and columns.
*/
protected void checkMissing() { protected void checkMissing() {
Set<String> names = new LinkedHashSet<>(); Set<String> names = new LinkedHashSet<>();
names.addAll(fieldsByName.keySet()); names.addAll(fieldsByName.keySet());
@ -121,6 +161,13 @@ public class DBAnnotatedObjectValidator {
} }
/**
* Check that the access specifiers of the field and column are compatible.
*
* @param field the field element
* @param column the column element
* @param name the name of the column
*/
protected void checkAccess(VariableElement field, VariableElement column, String name) { protected void checkAccess(VariableElement field, VariableElement column, String name) {
AccessSpec fieldSpec = AccessSpec.get(field.getModifiers()); AccessSpec fieldSpec = AccessSpec.get(field.getModifiers());
AccessSpec columnSpec = AccessSpec.get(column.getModifiers()); AccessSpec columnSpec = AccessSpec.get(column.getModifiers());

View File

@ -38,6 +38,11 @@ public class ValidationContext {
final TypeElement DEFAULT_CODEC_ELEM; final TypeElement DEFAULT_CODEC_ELEM;
final TypeElement ENUM_ELEM; final TypeElement ENUM_ELEM;
/**
* Construct a Validation Context with the specified processing environment/
*
* @param env the processing environment
*/
public ValidationContext(ProcessingEnvironment env) { public ValidationContext(ProcessingEnvironment env) {
typeUtils = env.getTypeUtils(); typeUtils = env.getTypeUtils();
elementUtils = env.getElementUtils(); elementUtils = env.getElementUtils();
@ -54,14 +59,35 @@ public class ValidationContext {
ENUM_ELEM = elementUtils.getTypeElement(Enum.class.getCanonicalName()); ENUM_ELEM = elementUtils.getTypeElement(Enum.class.getCanonicalName());
} }
/**
* Check if t1 is a subclass of t2.
*
* @param t1 the potential subclass
* @param t2 the potential superclass
* @return true if t1 is a subclass of t2, false otherwise
*/
public boolean isSubclass(TypeElement t1, TypeElement t2) { public boolean isSubclass(TypeElement t1, TypeElement t2) {
return typeUtils.isSubtype(typeUtils.erasure(t1.asType()), typeUtils.erasure(t2.asType())); return typeUtils.isSubtype(typeUtils.erasure(t1.asType()), typeUtils.erasure(t2.asType()));
} }
/**
* Check if the field has the specified type.
*
* @param field the field element
* @param type the type element
* @return true if the field has the specified type, false otherwise
*/
public boolean hasType(VariableElement field, TypeElement type) { public boolean hasType(VariableElement field, TypeElement type) {
return hasType(field, type.asType()); return hasType(field, type.asType());
} }
/**
* Check if the field has the specified type.
*
* @param field the field element
* @param type the type mirror
* @return true if the field has the specified type, false otherwise
*/
public boolean hasType(VariableElement field, TypeMirror type) { public boolean hasType(VariableElement field, TypeMirror type) {
TypeMirror fieldType = field.asType(); TypeMirror fieldType = field.asType();
try { try {
@ -86,9 +112,16 @@ public class ValidationContext {
} }
return typeUtils.isAssignable(fieldType, type); return typeUtils.isAssignable(fieldType, type);
// return typeUtils.isSameType(fieldType, type); // return typeUtils.isSameType(fieldType, type);
} }
/**
* Check if t1 is capturable by t2.
*
* @param t1 is the type to check
* @param t2 the capture target type
* @return true if t1 is capturable by t2, false otherwise
*/
public boolean isCapturable(TypeMirror t1, TypeMirror t2) { public boolean isCapturable(TypeMirror t1, TypeMirror t2) {
// TODO: This only works for typevar at top level... // TODO: This only works for typevar at top level...
// TODO: Need to figure out how to check for capture and check // TODO: Need to figure out how to check for capture and check
@ -105,6 +138,12 @@ public class ValidationContext {
return typeUtils.isSubtype(t1, t2); return typeUtils.isSubtype(t1, t2);
} }
/**
* Check if the type is an enum type.
*
* @param t the type mirror to check
* @return true if the type is an enum type, false otherwise
*/
public boolean isEnumType(TypeMirror t) { public boolean isEnumType(TypeMirror t) {
if (t.getKind() != TypeKind.DECLARED) { if (t.getKind() != TypeKind.DECLARED) {
return false; return false;
@ -113,6 +152,13 @@ public class ValidationContext {
return typeUtils.isSubtype(t, enumType); return typeUtils.isSubtype(t, enumType);
} }
/**
* Find the supertype of a set of declared types that matches the specified super type.
*
* @param types the set of declared types
* @param superType the super type element to match
* @return the matching declared type, or null if no match is found
*/
protected DeclaredType findSupertype(Set<DeclaredType> types, TypeElement superType) { protected DeclaredType findSupertype(Set<DeclaredType> types, TypeElement superType) {
Set<DeclaredType> next; Set<DeclaredType> next;
while (!types.isEmpty()) { while (!types.isEmpty()) {
@ -132,14 +178,35 @@ public class ValidationContext {
return null; return null;
} }
/**
* Find the supertype of a declared type that matches the specified super type element.
*
* @param type the declared type
* @param superElem the super type element to match
* @return the matching declared type, or null if no match is found
*/
public DeclaredType findSupertype(DeclaredType type, TypeElement superElem) { public DeclaredType findSupertype(DeclaredType type, TypeElement superElem) {
return findSupertype(Set.of(type), superElem); return findSupertype(Set.of(type), superElem);
} }
/**
* Find the supertype of a type element that matches the specified super type element.
*
* @param elem the type element
* @param superElem the super type element to match
* @return the matching declared type, or null if no match is found
*/
public DeclaredType findSupertype(TypeElement elem, TypeElement superElem) { public DeclaredType findSupertype(TypeElement elem, TypeElement superElem) {
return findSupertype((DeclaredType) elem.asType(), superElem); return findSupertype((DeclaredType) elem.asType(), superElem);
} }
/**
* Convert the type arguments of the super type element to a map.
*
* @param superElem the super type element
* @param superType the declared super type
* @return a map of type argument names to their corresponding type mirrors
*/
protected Map<String, TypeMirror> toArgsMap(TypeElement superElem, DeclaredType superType) { protected Map<String, TypeMirror> toArgsMap(TypeElement superElem, DeclaredType superType) {
List<? extends TypeParameterElement> typeParameters = superElem.getTypeParameters(); List<? extends TypeParameterElement> typeParameters = superElem.getTypeParameters();
List<? extends TypeMirror> typeArguments = superType.getTypeArguments(); List<? extends TypeMirror> typeArguments = superType.getTypeArguments();
@ -151,14 +218,34 @@ public class ValidationContext {
return result; return result;
} }
/**
* Get the type arguments of a declared type as a map.
*
* @param type the declared type
* @param superElem the super type element
* @return a map of type argument names to their corresponding type mirrors
*/
public Map<String, TypeMirror> getArguments(DeclaredType type, TypeElement superElem) { public Map<String, TypeMirror> getArguments(DeclaredType type, TypeElement superElem) {
return toArgsMap(superElem, findSupertype(type, superElem)); return toArgsMap(superElem, findSupertype(type, superElem));
} }
/**
* Get the type arguments of a type element as a map.
*
* @param elem the type element
* @param superElem the super type element
* @return a map of type argument names to their corresponding type mirrors
*/
public Map<String, TypeMirror> getArguments(TypeElement elem, TypeElement superElem) { public Map<String, TypeMirror> getArguments(TypeElement elem, TypeElement superElem) {
return toArgsMap(superElem, findSupertype(elem, superElem)); return toArgsMap(superElem, findSupertype(elem, superElem));
} }
/**
* Format the given type mirror as a string.
*
* @param type the type mirror to format
* @return the formatted type mirror as a string
*/
public String format(TypeMirror type) { public String format(TypeMirror type) {
FormatVisitor vis = new FormatVisitor(); FormatVisitor vis = new FormatVisitor();
type.accept(vis, null); type.accept(vis, null);
@ -166,9 +253,20 @@ public class ValidationContext {
} }
} }
/**
* Class for formatting {@link TypeMirror} instances into a readable string
*/
class FormatVisitor implements TypeVisitor<Void, Void> { class FormatVisitor implements TypeVisitor<Void, Void> {
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
/**
* Visit method for {@link TypeMirror}. Delegates to specific visit methods based on the type
* kind.
*
* @param t the type mirror to visit
* @param p unused parameter (can be {@code null})
* @return {@code null}
*/
@Override @Override
public Void visit(TypeMirror t, Void p) { public Void visit(TypeMirror t, Void p) {
switch (t.getKind()) { switch (t.getKind()) {
@ -207,18 +305,39 @@ class FormatVisitor implements TypeVisitor<Void, Void> {
} }
} }
/**
* Visit method for {@link PrimitiveType}.
*
* @param t the primitive type to visit
* @param p unused parameter (can be {@code null})
* @return {@code null}
*/
@Override @Override
public Void visitPrimitive(PrimitiveType t, Void p) { public Void visitPrimitive(PrimitiveType t, Void p) {
buf.append(t.toString()); buf.append(t.toString());
return null; return null;
} }
/**
* Visit method for {@link NullType}.
*
* @param t the null type to visit
* @param p unused parameter (can be {@code null})
* @return {@code null}
*/
@Override @Override
public Void visitNull(NullType t, Void p) { public Void visitNull(NullType t, Void p) {
buf.append(t.toString()); buf.append(t.toString());
return null; return null;
} }
/**
* Visit method for {@link ArrayType}.
*
* @param t the array type to visit
* @param p unused parameter (can be {@code null})
* @return {@code null}
*/
@Override @Override
public Void visitArray(ArrayType t, Void p) { public Void visitArray(ArrayType t, Void p) {
visit(t.getComponentType()); visit(t.getComponentType());
@ -226,6 +345,13 @@ class FormatVisitor implements TypeVisitor<Void, Void> {
return null; return null;
} }
/**
* Visit method for {@link DeclaredType}.
*
* @param t the declared type to visit
* @param p unused parameter (can be {@code null})
* @return {@code null}
*/
@Override @Override
public Void visitDeclared(DeclaredType t, Void p) { public Void visitDeclared(DeclaredType t, Void p) {
buf.append(t.asElement().toString()); buf.append(t.asElement().toString());
@ -242,12 +368,26 @@ class FormatVisitor implements TypeVisitor<Void, Void> {
return null; return null;
} }
/**
* Visit method for {@link ErrorType}.
*
* @param t the error type to visit
* @param p unused parameter (can be {@code null})
* @return {@code null}
*/
@Override @Override
public Void visitError(ErrorType t, Void p) { public Void visitError(ErrorType t, Void p) {
buf.append(t.toString()); buf.append(t.toString());
return null; return null;
} }
/**
* Visit method for {@link TypeVariable}.
*
* @param t the type variable to visit
* @param p unused parameter (can be {@code null})
* @return {@code null}
*/
@Override @Override
public Void visitTypeVariable(TypeVariable t, Void p) { public Void visitTypeVariable(TypeVariable t, Void p) {
buf.append(t.toString()); buf.append(t.toString());
@ -264,6 +404,13 @@ class FormatVisitor implements TypeVisitor<Void, Void> {
return null; return null;
} }
/**
* Visit method for {@link WildcardType}.
*
* @param t the wildcard type to visit
* @param p unused parameter (can be {@code null})
* @return {@code null}
*/
@Override @Override
public Void visitWildcard(WildcardType t, Void p) { public Void visitWildcard(WildcardType t, Void p) {
buf.append("?"); buf.append("?");
@ -280,24 +427,52 @@ class FormatVisitor implements TypeVisitor<Void, Void> {
return null; return null;
} }
/**
* Visit method for {@link ExecutableType}.
*
* @param t the executable type to visit
* @param p unused parameter (can be {@code null})
* @return {@code null}
*/
@Override @Override
public Void visitExecutable(ExecutableType t, Void p) { public Void visitExecutable(ExecutableType t, Void p) {
buf.append(t.toString()); buf.append(t.toString());
return null; return null;
} }
/**
* Visit method for {@link NoType}.
*
* @param t the no-type to visit
* @param p unused parameter (can be {@code null})
* @return {@code null}
*/
@Override @Override
public Void visitNoType(NoType t, Void p) { public Void visitNoType(NoType t, Void p) {
buf.append(t.toString()); buf.append(t.toString());
return null; return null;
} }
/**
* Visit method for unknown {@link TypeMirror} instances.
*
* @param t the unknown type to visit
* @param p unused parameter (can be {@code null})
* @return {@code null}
*/
@Override @Override
public Void visitUnknown(TypeMirror t, Void p) { public Void visitUnknown(TypeMirror t, Void p) {
buf.append(t.toString()); buf.append(t.toString());
return null; return null;
} }
/**
* Visit method for {@link UnionType}.
*
* @param t the union type to visit
* @param p unused parameter (can be {@code null})
* @return {@code null}
*/
@Override @Override
public Void visitUnion(UnionType t, Void p) { public Void visitUnion(UnionType t, Void p) {
Iterator<? extends TypeMirror> it = t.getAlternatives().iterator(); Iterator<? extends TypeMirror> it = t.getAlternatives().iterator();
@ -311,6 +486,13 @@ class FormatVisitor implements TypeVisitor<Void, Void> {
return null; return null;
} }
/**
* Visit method for {@link IntersectionType}.
*
* @param t the intersection type to visit
* @param p unused parameter (can be {@code null})
* @return {@code null}
*/
@Override @Override
public Void visitIntersection(IntersectionType t, Void p) { public Void visitIntersection(IntersectionType t, Void p) {
Iterator<? extends TypeMirror> it = t.getBounds().iterator(); Iterator<? extends TypeMirror> it = t.getBounds().iterator();

View File

@ -1,5 +1,5 @@
MODULE FILE LICENSE: pypkg/dist/capstone-5.0.1-py3-none-win_amd64.whl BSD-3-CAPSTONE MODULE FILE LICENSE: pypkg/dist/capstone-5.0.1-py3-none-win_amd64.whl BSD-3-CAPSTONE
MODULE FILE LICENSE: pypkg/dist/comtypes-1.4.1-py3-none-any.whl MIT MODULE FILE LICENSE: pypkg/dist/comtypes-1.4.1-py3-none-any.whl MIT
MODULE FILE LICENSE: pypkg/dist/Pybag-2.2.10-py3-none-any.whl MIT MODULE FILE LICENSE: pypkg/dist/Pybag-2.2.12-py3-none-any.whl MIT
MODULE FILE LICENSE: pypkg/dist/pywin32-306-cp312-cp312-win_amd64.whl Python Software Foundation License MODULE FILE LICENSE: pypkg/dist/pywin32-306-cp312-cp312-win_amd64.whl Python Software Foundation License

View File

@ -93,7 +93,7 @@ else {
} }
} }
distributePyDep("Pybag-2.2.10-py3-none-any.whl") distributePyDep("Pybag-2.2.12-py3-none-any.whl")
distributePyDep("capstone-5.0.1-py3-none-win_amd64.whl") distributePyDep("capstone-5.0.1-py3-none-win_amd64.whl")
distributePyDep("comtypes-1.4.1-py3-none-any.whl") distributePyDep("comtypes-1.4.1-py3-none-any.whl")
distributePyDep("pywin32-306-cp312-cp312-win_amd64.whl") distributePyDep("pywin32-306-cp312-cp312-win_amd64.whl")

View File

@ -2,8 +2,12 @@
##MODULE IP: Apache License 2.0 ##MODULE IP: Apache License 2.0
##MODULE IP: MIT ##MODULE IP: MIT
Module.manifest||GHIDRA||||END| Module.manifest||GHIDRA||||END|
data/debugger-launchers/kernel-dbgeng.bat||GHIDRA||||END|
data/debugger-launchers/local-dbgeng-attach.bat||GHIDRA||||END|
data/debugger-launchers/local-dbgeng-ext.bat||GHIDRA||||END|
data/debugger-launchers/local-dbgeng.bat||GHIDRA||||END| data/debugger-launchers/local-dbgeng.bat||GHIDRA||||END|
data/debugger-launchers/local-ttd.bat||GHIDRA||||END| data/debugger-launchers/local-ttd.bat||GHIDRA||||END|
data/debugger-launchers/remote-dbgeng.bat||GHIDRA||||END|
src/main/py/LICENSE||GHIDRA||||END| src/main/py/LICENSE||GHIDRA||||END|
src/main/py/MANIFEST.in||GHIDRA||||END| src/main/py/MANIFEST.in||GHIDRA||||END|
src/main/py/README.md||GHIDRA||||END| src/main/py/README.md||GHIDRA||||END|

View File

@ -0,0 +1,20 @@
::@title dbgeng-kernel
::@desc <html><body width="300px">
::@desc <h3>Kernel debugging using <tt>dbgeng</tt> (in a Python interpreter)</h3>
::@desc <p>
::@desc This will connect the kernel debugger to a remote machine using <tt>dbgeng.dll</tt>.
::@desc For setup instructions, press <b>F1</b>.
::@desc </p>
::@desc </body></html>
::@menu-group local
::@icon icon.debugger
::@help TraceRmiLauncherServicePlugin#dbgeng_kernel
::@env OPT_PYTHON_EXE:file="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH."
:: Use env instead of args, because "all args except first" is terrible to implement in batch
::@env OPT_TARGET_ARGS:str="" "Arguments" "Connection-string arguments (a la .server)"
::@env OPT_USE_DBGMODEL:bool=true "Use dbgmodel" "Load and use dbgmodel.dll if it is available."
::@env WINDBG_DIR:dir="" "Path to dbgeng.dll directory" "Path containing dbgeng and associated DLLS (if not Windows Kits)."
@echo off
"%OPT_PYTHON_EXE%" -i ..\support\kernel-dbgeng.py

View File

@ -0,0 +1,20 @@
::@title dbgeng-attach
::@desc <html><body width="300px">
::@desc <h3>Attach with <tt>dbgeng</tt> (in a Python interpreter)</h3>
::@desc <p>
::@desc This will attach to a running target on the local machine using <tt>dbgeng.dll</tt>.
::@desc For setup instructions, press <b>F1</b>.
::@desc </p>
::@desc </body></html>
::@menu-group local
::@icon icon.debugger
::@help TraceRmiLauncherServicePlugin#dbgeng_attach
::@env OPT_PYTHON_EXE:file="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH."
::@env OPT_TARGET_PID:str="" "Process id" "The target process id"
::@env OPT_ATTACH_FLAGS:str="0" "Attach flags" "Attach flags"
::@env OPT_USE_DBGMODEL:bool=true "Use dbgmodel" "Load and use dbgmodel.dll if it is available."
::@env WINDBG_DIR:dir="" "Path to dbgeng.dll directory" "Path containing dbgeng and associated DLLS (if not Windows Kits)."
@echo off
"%OPT_PYTHON_EXE%" -i ..\support\local-dbgeng-attach.py

View File

@ -0,0 +1,26 @@
::@title dbgeng-ext
::@desc <html><body width="300px">
::@desc <h3>Launch with <tt>dbgeng</tt> (in a Python interpreter)</h3>
::@desc <p>
::@desc This will launch the target on the local machine using <tt>dbgeng.dll</tt>.
::@desc For setup instructions, press <b>F1</b>.
::@desc </p>
::@desc </body></html>
::@menu-group local
::@icon icon.debugger
::@help TraceRmiLauncherServicePlugin#dbgeng_ext
::@env OPT_PYTHON_EXE:file="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH."
:: Use env instead of args, because "all args except first" is terrible to implement in batch
::@env OPT_TARGET_IMG:file="" "Image" "The target binary executable image"
::@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
::@env OPT_USE_DBGMODEL:bool=true "Use dbgmodel" "Load and use dbgmodel.dll if it is available."
::@env WINDBG_DIR:dir="" "Path to dbgeng.dll directory" "Path containing dbgeng and associated DLLS (if not Windows Kits)."
::@env OPT_TARGET_DIR:str="" "Dir" "Initial directory"
::@env OPT_TARGET_ENV:str="" "Env" "Environment variables (sep=/0)"
::@env OPT_CREATE_FLAGS:str="1" "Create flags" "Creation flags"
::@env OPT_CREATE_ENGFLAGS:str="0" "Create flags (Engine)" "Engine-specific creation flags"
::@env OPT_VERIFIER_FLAGS:str="0" "Verifier flags" "Verifier flags"
@echo off
"%OPT_PYTHON_EXE%" -i ..\support\local-dbgeng-ext.py

View File

@ -0,0 +1,22 @@
::@title dbgeng-remote
::@desc <html><body width="300px">
::@desc <h3>Launch with <tt>dbgeng</tt> remotely (in a Python interpreter)</h3>
::@desc <p>
::@desc This will launch the target on a remote machine using <tt>dbgeng.dll</tt>.
::@desc For setup instructions, press <b>F1</b>.
::@desc </p>
::@desc </body></html>
::@menu-group local
::@icon icon.debugger
::@help TraceRmiLauncherServicePlugin#dbgeng_remote
::@env OPT_PYTHON_EXE:file="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH."
:: Use env instead of args, because "all args except first" is terrible to implement in batch
::@env OPT_TARGET_IMG:file="" "Image" "The target binary executable image"
::@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target"
::@env OPT_CONNECT_STRING:str="" "Connection" "Connection-string arguments (a la dbgsrv args)"
::@env OPT_USE_DBGMODEL:bool=true "Use dbgmodel" "Load and use dbgmodel.dll if it is available."
::@env WINDBG_DIR:dir="" "Path to dbgeng.dll directory" "Path containing dbgeng and associated DLLS (if not Windows Kits)."
@echo off
"%OPT_PYTHON_EXE%" -i ..\support\remote-dbgeng.py

View File

@ -0,0 +1,67 @@
## ###
# IP: GHIDRA
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##
import os
import sys
home = os.getenv('GHIDRA_HOME')
if os.path.isdir(f'{home}\\ghidra\\.git'):
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-agent-dbgeng\\build\\pypkg\\src')
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-rmi-trace\\build\\pypkg\\src')
elif os.path.isdir(f'{home}\\.git'):
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-agent-dbgeng\\build\\pypkg\\src')
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-rmi-trace\\build\\pypkg\\src')
else:
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-agent-dbgeng\\pypkg\\src')
sys.path.append(f'{home}\\Ghidra\\Debug\\Debugger-rmi-trace\\pypkg\\src')
def main():
# Delay these imports until sys.path is patched
from ghidradbg import commands as cmd
from pybag.dbgeng import core as DbgEng
from ghidradbg.hooks import on_state_changed
from ghidradbg.util import dbg
# So that the user can re-enter by typing repl()
global repl
repl = cmd.repl
cmd.ghidra_trace_connect(os.getenv('GHIDRA_TRACE_RMI_ADDR'))
args = os.getenv('OPT_TARGET_ARGS')
cmd.ghidra_trace_attach_kernel(args, start_trace=False)
# TODO: HACK
try:
dbg.wait()
except KeyboardInterrupt as ki:
dbg.interrupt()
cmd.ghidra_trace_start(os.getenv('OPT_TARGET_IMG'))
cmd.ghidra_trace_sync_enable()
on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS, DbgEng.DEBUG_STATUS_BREAK)
cmd.repl()
if __name__ == '__main__':
main()

View File

@ -0,0 +1,69 @@
## ###
# IP: GHIDRA
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##
import os
import sys
home = os.getenv('GHIDRA_HOME')
if os.path.isdir(f'{home}\\ghidra\\.git'):
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-agent-dbgeng\\build\\pypkg\\src')
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-rmi-trace\\build\\pypkg\\src')
elif os.path.isdir(f'{home}\\.git'):
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-agent-dbgeng\\build\\pypkg\\src')
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-rmi-trace\\build\\pypkg\\src')
else:
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-agent-dbgeng\\pypkg\\src')
sys.path.append(f'{home}\\Ghidra\\Debug\\Debugger-rmi-trace\\pypkg\\src')
def main():
# Delay these imports until sys.path is patched
from ghidradbg import commands as cmd
from pybag.dbgeng import core as DbgEng
from ghidradbg.hooks import on_state_changed
from ghidradbg.util import dbg
# So that the user can re-enter by typing repl()
global repl
repl = cmd.repl
cmd.ghidra_trace_connect(os.getenv('GHIDRA_TRACE_RMI_ADDR'))
flags = os.getenv('OPT_ATTACH_FLAGS')
cmd.ghidra_trace_attach(
os.getenv('OPT_TARGET_PID'), flags, start_trace=False)
# TODO: HACK
try:
dbg.wait()
except KeyboardInterrupt as ki:
dbg.interrupt()
cmd.ghidra_trace_start(os.getenv('OPT_TARGET_IMG'))
cmd.ghidra_trace_sync_enable()
on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS, DbgEng.DEBUG_STATUS_BREAK)
cmd.repl()
if __name__ == '__main__':
main()

View File

@ -0,0 +1,77 @@
## ###
# IP: GHIDRA
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##
import os
import sys
home = os.getenv('GHIDRA_HOME')
if os.path.isdir(f'{home}\\ghidra\\.git'):
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-agent-dbgeng\\build\\pypkg\\src')
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-rmi-trace\\build\\pypkg\\src')
elif os.path.isdir(f'{home}\\.git'):
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-agent-dbgeng\\build\\pypkg\\src')
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-rmi-trace\\build\\pypkg\\src')
else:
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-agent-dbgeng\\pypkg\\src')
sys.path.append(f'{home}\\Ghidra\\Debug\\Debugger-rmi-trace\\pypkg\\src')
def main():
# Delay these imports until sys.path is patched
from ghidradbg import commands as cmd
from pybag.dbgeng import core as DbgEng
from ghidradbg.hooks import on_state_changed
from ghidradbg.util import dbg
# So that the user can re-enter by typing repl()
global repl
repl = cmd.repl
cmd.ghidra_trace_connect(os.getenv('GHIDRA_TRACE_RMI_ADDR'))
args = os.getenv('OPT_TARGET_ARGS')
if args:
args = ' ' + args
cmd.ghidra_trace_create_ext(
os.getenv('OPT_TARGET_IMG') + args,
os.getenv('OPT_TARGET_DIR'),
os.getenv('OPT_TARGET_ENV'),
os.getenv('OPT_CREATE_FLAGS'),
os.getenv('OPT_CREATE_ENGFLAGS'),
os.getenv('OPT_VERIFIER_FLAGS'),
start_trace=False)
# TODO: HACK
try:
dbg.wait()
except KeyboardInterrupt as ki:
dbg.interrupt()
cmd.ghidra_trace_start(os.getenv('OPT_TARGET_IMG'))
cmd.ghidra_trace_sync_enable()
on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS, DbgEng.DEBUG_STATUS_BREAK)
cmd.repl()
if __name__ == '__main__':
main()

View File

@ -0,0 +1,73 @@
## ###
# IP: GHIDRA
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##
import os
import sys
home = os.getenv('GHIDRA_HOME')
if os.path.isdir(f'{home}\\ghidra\\.git'):
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-agent-dbgeng\\build\\pypkg\\src')
sys.path.append(
f'{home}\\ghidra\\Ghidra\\Debug\\Debugger-rmi-trace\\build\\pypkg\\src')
elif os.path.isdir(f'{home}\\.git'):
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-agent-dbgeng\\build\\pypkg\\src')
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-rmi-trace\\build\\pypkg\\src')
else:
sys.path.append(
f'{home}\\Ghidra\\Debug\\Debugger-agent-dbgeng\\pypkg\\src')
sys.path.append(f'{home}\\Ghidra\\Debug\\Debugger-rmi-trace\\pypkg\\src')
def main():
# Delay these imports until sys.path is patched
from ghidradbg import commands as cmd
from pybag.dbgeng import core as DbgEng
from ghidradbg.hooks import on_state_changed
from ghidradbg.util import dbg
# So that the user can re-enter by typing repl()
global repl
repl = cmd.repl
cmd.ghidra_trace_connect(os.getenv('GHIDRA_TRACE_RMI_ADDR'))
args = os.getenv('OPT_TARGET_ARGS')
if args:
args = ' ' + args
cmd.ghidra_trace_connect_server(os.getenv('OPT_CONNECT_STRING'))
img = os.getenv('OPT_TARGET_IMG')
if img is not None and img != "":
cmd.ghidra_trace_create(img + args, start_trace=False)
# TODO: HACK
try:
dbg.wait()
except KeyboardInterrupt as ki:
dbg.interrupt()
cmd.ghidra_trace_start(os.getenv('OPT_TARGET_IMG'))
cmd.ghidra_trace_sync_enable()
on_state_changed(DbgEng.DEBUG_CES_EXECUTION_STATUS, DbgEng.DEBUG_STATUS_BREAK)
cmd.repl()
if __name__ == '__main__':
main()

View File

@ -220,7 +220,7 @@ public interface DbgEngGadpServer extends AutoCloseable {
* {@link #terminate()}, or 3) When an error occurs causing the server to terminate * {@link #terminate()}, or 3) When an error occurs causing the server to terminate
* unexpectedly. Otherwise, it returns true. * unexpectedly. Otherwise, it returns true.
* *
* @returns true if the server is currently running. * @return true if the server is currently running.
*/ */
public boolean isRunning(); public boolean isRunning();

View File

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "ghidradbg" name = "ghidradbg"
version = "11.1.2" version = "11.2"
authors = [ authors = [
{ name="Ghidra Development Team" }, { name="Ghidra Development Team" },
] ]
@ -17,8 +17,8 @@ classifiers = [
"Operating System :: OS Independent", "Operating System :: OS Independent",
] ]
dependencies = [ dependencies = [
"ghidratrace==11.1.2", "ghidratrace==11.2",
"pybag>=2.2.10" "pybag>=2.2.12"
] ]
[project.urls] [project.urls]

View File

@ -26,6 +26,9 @@ language_map = {
'x86': ['x86:LE:32:default'], 'x86': ['x86:LE:32:default'],
'x86_64': ['x86:LE:64:default'], 'x86_64': ['x86:LE:64:default'],
'EFI': ['x86:LE:64:default'], 'EFI': ['x86:LE:64:default'],
'MIPS': ['MIPS:LE:64:default'],
'MIPS-BE': ['MIPS:BE:64:default'],
'SH4': ['SuperH4:LE:32:default'],
} }
data64_compiler_map = { data64_compiler_map = {
@ -37,11 +40,11 @@ x86_compiler_map = {
'Cygwin': 'windows', 'Cygwin': 'windows',
} }
aarch64_compiler_map = { default_compiler_map = {
'windows': 'default', 'windows': 'default',
} }
arm_compiler_map = { windows_compiler_map = {
'windows': 'windows', 'windows': 'windows',
} }
@ -50,8 +53,11 @@ compiler_map = {
'DATA:LE:64:default': data64_compiler_map, 'DATA:LE:64:default': data64_compiler_map,
'x86:LE:32:default': x86_compiler_map, 'x86:LE:32:default': x86_compiler_map,
'x86:LE:64:default': x86_compiler_map, 'x86:LE:64:default': x86_compiler_map,
'AARCH64:LE:64:AppleSilicon': aarch64_compiler_map, 'AARCH64:LE:64:AppleSilicon': default_compiler_map,
'ARM:LE:32:v8': arm_compiler_map, 'ARM:LE:32:v8': windows_compiler_map,
'MIPS:BE:64:default': default_compiler_map,
'MIPS:LE:64:default': windows_compiler_map,
'SuperH4:LE:32:default': windows_compiler_map,
} }
@ -69,12 +75,56 @@ def get_arch():
return "AARCH64" return "AARCH64"
if type == 0x014c: if type == 0x014c:
return "x86" return "x86"
if type == 0x01c0: if type == 0x0160: # R3000 BE
return "MIPS-BE"
if type == 0x0162: # R3000 LE
return "MIPS"
if type == 0x0166: # R4000 LE
return "MIPS"
if type == 0x0168: # R10000 LE
return "MIPS"
if type == 0x0169: # WCE v2 LE
return "MIPS"
if type == 0x0266: # MIPS 16
return "MIPS"
if type == 0x0366: # MIPS FPU
return "MIPS"
if type == 0x0466: # MIPS FPU16
return "MIPS"
if type == 0x0184: # Alpha AXP
return "Alpha"
if type == 0x0284: # Aplha 64
return "Alpha"
if type >= 0x01a2 and type < 0x01a6:
return "SH"
if type == 0x01a6:
return "SH4"
if type == 0x01a6:
return "SH5"
if type == 0x01c0: # ARM LE
return "ARM" return "ARM"
if type == 0x01c2: # ARM Thumb/Thumb-2 LE
return "ARM"
if type == 0x01c4: # ARM Thumb-2 LE
return "ARM"
if type == 0x01d3: # AM33
return "ARM"
if type == 0x01f0 or type == 0x1f1: # PPC
return "PPC"
if type == 0x0200: if type == 0x0200:
return "Itanium" return "Itanium"
if type == 0x0520:
return "Infineon"
if type == 0x0CEF:
return "CEF"
if type == 0x0EBC: if type == 0x0EBC:
return "EFI" return "EFI"
if type == 0x8664: # AMD64 (K8)
return "x86_64"
if type == 0x9041: # M32R
return "M32R"
if type == 0xC0EE:
return "CEE"
return "Unknown" return "Unknown"
@ -154,14 +204,18 @@ class DefaultMemoryMapper(object):
self.defaultSpace = defaultSpace self.defaultSpace = defaultSpace
def map(self, proc: int, offset: int): def map(self, proc: int, offset: int):
if proc == 0:
space = self.defaultSpace space = self.defaultSpace
else:
space = f'{self.defaultSpace}{proc}'
return self.defaultSpace, Address(space, offset) return self.defaultSpace, Address(space, offset)
def map_back(self, proc: int, address: Address) -> int: def map_back(self, proc: int, address: Address) -> int:
if address.space == self.defaultSpace: if address.space == self.defaultSpace and proc == 0:
return address.offset return address.offset
raise ValueError( if address.space == f'{self.defaultSpace}{proc}':
f"Address {address} is not in process {proc.GetProcessID()}") return address.offset
raise ValueError(f"Address {address} is not in process {proc}")
DEFAULT_MEMORY_MAPPER = DefaultMemoryMapper('ram') DEFAULT_MEMORY_MAPPER = DefaultMemoryMapper('ram')

View File

@ -22,6 +22,7 @@ import socket
import sys import sys
import time import time
from comtypes import c_ulong
from ghidratrace import sch from ghidratrace import sch
from ghidratrace.client import Client, Address, AddressRange, TraceObject from ghidratrace.client import Client, Address, AddressRange, TraceObject
from pybag import pydbg, userdbg, kerneldbg from pybag import pydbg, userdbg, kerneldbg
@ -32,7 +33,6 @@ from pybag.dbgeng.win32.kernel32 import STILL_ACTIVE
from . import util, arch, methods, hooks from . import util, arch, methods, hooks
from .dbgmodel.imodelobject import ModelObjectKind from .dbgmodel.imodelobject import ModelObjectKind
PAGE_SIZE = 4096 PAGE_SIZE = 4096
AVAILABLES_PATH = 'Available' AVAILABLES_PATH = 'Available'
@ -68,10 +68,11 @@ GENERIC_KEY_PATTERN = '[{key}]'
class ErrorWithCode(Exception): class ErrorWithCode(Exception):
def __init__(self, code): def __init__(self, code):
self.code = code self.code = code
def __str__(self)->str: def __str__(self) -> str:
return repr(self.code) return repr(self.code)
@ -216,6 +217,8 @@ def start_trace(name):
with STATE.trace.open_tx("Create Root Object"): with STATE.trace.open_tx("Create Root Object"):
root = STATE.trace.create_root_object(schema_xml, 'DbgRoot') root = STATE.trace.create_root_object(schema_xml, 'DbgRoot')
root.set_value('_display', util.DBG_VERSION.full + ' via pybag' + variant) root.set_value('_display', util.DBG_VERSION.full + ' via pybag' + variant)
if util.dbg.use_generics:
put_generic(root)
util.set_convenience_variable('_ghidra_tracing', "true") util.set_convenience_variable('_ghidra_tracing', "true")
@ -261,6 +264,84 @@ def ghidra_trace_create(command=None, initial_break=True, timeout=DbgEng.WAIT_IN
ghidra_trace_start(command) ghidra_trace_start(command)
@util.dbg.eng_thread
def ghidra_trace_create_ext(command=None, initialDirectory='.', envVariables="\0\0", create_flags=1, create_flags_eng=0, verifier_flags=0, initial_break=True, timeout=DbgEng.WAIT_INFINITE, start_trace=True):
"""
Create a session.
"""
dbg = util.dbg._base
if command != None:
if create_flags == "":
create_flags = 1
if create_flags_eng == "":
create_flags_eng = 0
if verifier_flags == "":
verifier_flags = 0
options = DbgEng._DEBUG_CREATE_PROCESS_OPTIONS()
options.CreateFlags = c_ulong(int(create_flags))
options.EngCreateFlags = c_ulong(int(create_flags_eng))
options.VerifierFlags = c_ulong(int(verifier_flags))
options.Reserved = c_ulong(int(0))
if initialDirectory == "":
initialDirectory = None
if envVariables == "":
envVariables = None
if envVariables is not None and envVariables.endswith("/0/0") is False:
envVariables += "/0/0"
dbg._client.CreateProcess2(command, options, initialDirectory, envVariables)
if initial_break:
dbg._control.AddEngineOptions(DbgEng.DEBUG_ENGINITIAL_BREAK)
if start_trace:
ghidra_trace_start(command)
@util.dbg.eng_thread
def ghidra_trace_attach(pid=None, attach_flags='0', initial_break=True, timeout=DbgEng.WAIT_INFINITE, start_trace=True):
"""
Create a session by attaching.
"""
dbg = util.dbg._base
if initial_break:
dbg._control.AddEngineOptions(DbgEng.DEBUG_ENGINITIAL_BREAK)
if attach_flags == None:
attach_flags = '0'
if pid != None:
dbg._client.AttachProcess(int(pid,0), int(attach_flags,0))
if start_trace:
ghidra_trace_start("pid_"+pid)
@util.dbg.eng_thread
def ghidra_trace_attach_kernel(command=None, initial_break=True, timeout=DbgEng.WAIT_INFINITE, start_trace=True):
"""
Create a session.
"""
dbg = util.dbg._base
util.set_kernel(True)
if initial_break:
dbg._control.AddEngineOptions(DbgEng.DEBUG_ENGINITIAL_BREAK)
if command != None:
dbg._client.AttachKernel(command)
if start_trace:
ghidra_trace_start(command)
@util.dbg.eng_thread
def ghidra_trace_connect_server(options=None):
"""
Connect to a process server session.
"""
dbg = util.dbg._base
if options != None:
if isinstance(options, str):
enc_options = options.encode()
dbg._client.ConnectProcessServer(enc_options)
@util.dbg.eng_thread @util.dbg.eng_thread
def ghidra_trace_kill(): def ghidra_trace_kill():
""" """
@ -370,7 +451,7 @@ def ghidra_trace_set_snap(snap=None):
def quantize_pages(start, end): def quantize_pages(start, end):
return (start // PAGE_SIZE * PAGE_SIZE, (end+PAGE_SIZE-1) // PAGE_SIZE*PAGE_SIZE) return (start // PAGE_SIZE * PAGE_SIZE, (end + PAGE_SIZE - 1) // PAGE_SIZE * PAGE_SIZE)
@util.dbg.eng_thread @util.dbg.eng_thread
@ -453,7 +534,7 @@ def putmem_state(address, length, state, pages=True):
nproc = util.selected_process() nproc = util.selected_process()
base, addr = STATE.trace.memory_mapper.map(nproc, start) base, addr = STATE.trace.memory_mapper.map(nproc, start)
if base != addr.space and state != 'unknown': if base != addr.space and state != 'unknown':
trace.create_overlay_space(base, addr.space) STATE.trace.create_overlay_space(base, addr.space)
STATE.trace.set_memory_state(addr.extend(end - start), state) STATE.trace.set_memory_state(addr.extend(end - start), state)
@ -718,6 +799,7 @@ def ghidra_trace_get_obj(path):
class TableColumn(object): class TableColumn(object):
def __init__(self, head): def __init__(self, head):
self.head = head self.head = head
self.contents = [head] self.contents = [head]
@ -735,6 +817,7 @@ class TableColumn(object):
class Tabular(object): class Tabular(object):
def __init__(self, heads): def __init__(self, heads):
self.columns = [TableColumn(h) for h in heads] self.columns = [TableColumn(h) for h in heads]
self.columns[-1].is_last = True self.columns[-1].is_last = True
@ -1077,6 +1160,8 @@ def put_regions():
regions = util.dbg._base.memory_list() regions = util.dbg._base.memory_list()
except Exception: except Exception:
regions = [] regions = []
if len(regions) == 0:
regions = util.full_mem()
mapper = STATE.trace.memory_mapper mapper = STATE.trace.memory_mapper
keys = [] keys = []
@ -1096,6 +1181,8 @@ def put_regions():
regobj.set_value('AllocationBase', hex(r.AllocationBase)) regobj.set_value('AllocationBase', hex(r.AllocationBase))
regobj.set_value('Protect', hex(r.Protect)) regobj.set_value('Protect', hex(r.Protect))
regobj.set_value('Type', hex(r.Type)) regobj.set_value('Type', hex(r.Type))
if hasattr(r, 'Name') and r.Name is not None:
regobj.set_value('_display', r.Name)
regobj.insert() regobj.insert()
STATE.trace.proxy_object_path( STATE.trace.proxy_object_path(
MEMORY_PATTERN.format(procnum=nproc)).retain_values(keys) MEMORY_PATTERN.format(procnum=nproc)).retain_values(keys)
@ -1296,37 +1383,44 @@ def ghidra_trace_put_frames():
put_frames() put_frames()
def update_by_container(np, index, obj): def update_by_container(np, keyval, obj):
index = keyval[0]
key = ''
if np.endswith("Processes") or np.endswith("Threads"): if np.endswith("Processes") or np.endswith("Threads"):
istate = compute_proc_state(index) istate = compute_proc_state(index)
obj.set_value('State', istate) obj.set_value('State', istate)
if np.endswith("Sessions"):
key = '[{:x}]'.format(index)
if np.endswith("Processes"): if np.endswith("Processes"):
create_generic(obj.path) create_generic(obj.path)
id = util.get_proc_id(index)
obj.set_value('PID', index) obj.set_value('PID', index)
obj.set_value('_display', '{:x} {:x}'.format(id, index)) create_generic(obj.path + ".Memory")
if util.is_kernel():
key = '[{:x}]'.format(index)
else:
id = util.get_proc_id(index)
key = '{:x} [{:x}]'.format(id, index)
if np.endswith("Breakpoints"): if np.endswith("Breakpoints"):
create_generic(obj.path) create_generic(obj.path)
#id = util.get_thread_id(index)
#obj.set_value('TID', index)
#obj.set_value('_display','{:x} {:x}'.format(id, index))
if np.endswith("Threads"): if np.endswith("Threads"):
create_generic(obj.path) create_generic(obj.path)
id = util.get_thread_id(index)
obj.set_value('TID', index) obj.set_value('TID', index)
obj.set_value('_display', '{:x} {:x}'.format(id, index)) if util.is_kernel():
key = '[{:x}]'.format(index)
else:
id = util.get_thread_id(index)
key = '{:x} [{:x}]'.format(id, index)
if np.endswith("Frames"): if np.endswith("Frames"):
mo = util.get_object(obj.path) mo = util.get_object(obj.path)
map = util.get_attributes(mo) map = util.get_attributes(mo)
if 'Attributes' in map:
attr = map["Attributes"] attr = map["Attributes"]
if attr is None: if attr is not None:
return
create_generic(obj.path+".Attributes")
map = util.get_attributes(attr) map = util.get_attributes(attr)
pc = util.get_value(map["InstructionOffset"]) pc = util.get_value(map["InstructionOffset"])
(pc_base, pc_addr) = map_address(pc) (pc_base, pc_addr) = map_address(pc)
obj.set_value('Instruction Offset', pc_addr) obj.set_value('Instruction Offset', pc_addr)
obj.set_value('_display', '#{:x} 0x{:x}'.format(index, pc)) key = '#{:x} 0x{:x}'.format(index, pc)
if np.endswith("Modules"): if np.endswith("Modules"):
create_generic(obj.path) create_generic(obj.path)
mo = util.get_object(obj.path) mo = util.get_object(obj.path)
@ -1337,7 +1431,12 @@ def update_by_container(np, index, obj):
obj.set_value('Name', '{}'.format(name)) obj.set_value('Name', '{}'.format(name))
(base_base, base_addr) = map_address(base) (base_base, base_addr) = map_address(base)
obj.set_value('Range', base_addr.extend(size)) obj.set_value('Range', base_addr.extend(size))
obj.set_value('_display', '{:x} {:x} {}'.format(index, base, name)) key = '{:x} {:x} {}'.format(index, base, name)
disp = util.to_display_string(keyval[1])
if disp is not None:
key += " " + disp
if key is not None and key != "":
obj.set_value('_display', key)
def create_generic(path): def create_generic(path):
@ -1348,58 +1447,81 @@ def create_generic(path):
def put_generic(node): def put_generic(node):
#print(f"put_generic: {node}") # print(f"put_generic: {node}")
nproc = util.selected_process() nproc = util.selected_process()
if nproc is None: if nproc is None:
return return
nthrd = util.selected_thread() nthrd = util.selected_thread()
mapper = STATE.trace.memory_mapper
mo = util.get_object(node.path) mo = util.get_object(node.path)
kind = util.get_kind(mo) mapper = STATE.trace.register_mapper
type = util.get_type(mo)
vstr = util.get_value(mo)
# print(f"MO={mo}")
attributes = util.get_attributes(mo) attributes = util.get_attributes(mo)
# print(f"ATTR={attributes}") # print(f"ATTR={attributes}")
mapper = STATE.trace.register_mapper
values = [] values = []
if attributes is not None:
for key, value in attributes.items(): for key, value in attributes.items():
if value is None:
continue
kind = util.get_kind(value) kind = util.get_kind(value)
vstr = util.get_value(value) if kind == ModelObjectKind.METHOD.value:
#print(f"key={key} kind={kind} value={vstr} type={type}") continue
if kind == ModelObjectKind.PROPERTY_ACCESSOR.value or \ # print(f"key={key} kind={kind}")
kind == ModelObjectKind.SYNTHETIC.value or \ if kind != ModelObjectKind.INTRINSIC.value:
kind == ModelObjectKind.METHOD.value: apath = node.path + '.' + key
if vstr is not None:
key += " : " + vstr
apath = node.path+'.'+key
aobj = STATE.trace.create_object(apath) aobj = STATE.trace.create_object(apath)
set_display(key, value, aobj)
aobj.insert() aobj.insert()
else: else:
val = util.get_value(value)
try: try:
if node.path.endswith('.User'): if node.path.endswith('.User'):
values.append(mapper.map_value(nproc, key, vstr)) # print(f"PUT_REG: {key} {val}")
node.set_value(key, hex(vstr)) values.append(mapper.map_value(nproc, key, val))
node.set_value(key, hex(val))
elif isinstance(val, int):
(v_base, v_addr) = map_address(val)
node.set_value(key, v_addr, schema="ADDRESS")
else:
node.set_value(key, val)
except Exception as e: except Exception as e:
pass # Error is printed by another mechanism print(f"Attribute exception for {key} {type(val)}: {e}")
elements = util.get_elements(mo) elements = util.get_elements(mo)
# print(f"ELEM={elements}") # print(f"ELEM={elements}")
keys = [] keys = []
if elements is not None:
for el in elements: for el in elements:
index = el[0] index = el[0]
key = GENERIC_KEY_PATTERN.format(key=index) key = GENERIC_KEY_PATTERN.format(key=index)
lpath = node.path+key lpath = node.path + key
lobj = STATE.trace.create_object(lpath) lobj = STATE.trace.create_object(lpath)
update_by_container(node.path, index, lobj) update_by_container(node.path, el, lobj)
lobj.insert() lobj.insert()
keys.append(key) keys.append(key)
node.retain_values(keys) node.retain_values(keys)
return (values, keys) return (values, keys)
def set_display(key, value, obj):
kind = util.get_kind(value)
vstr = util.get_value(value)
# istr = util.get_intrinsic_value(value)
if kind == ModelObjectKind.TARGET_OBJECT.value:
hloc = util.get_location(value)
ti = util.get_type_info(value)
if ti is not None:
name = util.get_name(ti)
if name is not None:
key += " : " + name
obj.set_value('_display', key)
if hloc is not None:
key += " @ " + str(hloc)
obj.set_value('_display', key)
(hloc_base, hloc_addr) = map_address(int(hloc,0))
obj.set_value('_address', hloc_addr, schema=Address)
if vstr is not None:
key += " : " + str(vstr)
obj.set_value('_display', key)
def map_address(address): def map_address(address):
nproc = util.selected_process() nproc = util.selected_process()
mapper = STATE.trace.memory_mapper mapper = STATE.trace.memory_mapper

View File

@ -155,6 +155,13 @@ library DbgMod
DWORD NotSupported; DWORD NotSupported;
}; };
typedef struct _DEBUG_CREATE_PROCESS_OPTIONS {
ULONG CreateFlags;
ULONG EngCreateFlags;
ULONG VerfierFlags;
ULONG Reserved;
} DEBUG_CREATE_PROCESS_OPTIONS, *PDEBUG_CREATE_PROCESS_OPTIONS;
/* /*
struct _MEMORY_BASIC_INFORMATION64 { struct _MEMORY_BASIC_INFORMATION64 {
ULONGLONG BaseAddress; ULONGLONG BaseAddress;

View File

@ -40,8 +40,10 @@ class ModelIterator(object):
except COMError as ce: except COMError as ce:
return None return None
index = mo.ModelObject(indexer) index = mo.ModelObject(indexer)
id = index.GetIntrinsicValue().value ival = index.GetIntrinsicValue()
return (id, mo.ModelObject(object)) if ival is None:
return (0, mo.ModelObject(object))
return (ival.value, mo.ModelObject(object))
def Reset(self): def Reset(self):
hr = self._keys.Reset() hr = self._keys.Reset()

View File

@ -22,10 +22,13 @@ from comtypes.gen import DbgMod
from comtypes.hresult import S_OK, S_FALSE from comtypes.hresult import S_OK, S_FALSE
from pybag.dbgeng import exception from pybag.dbgeng import exception
from comtypes import BSTR
from comtypes.gen.DbgMod import * from comtypes.gen.DbgMod import *
from .iiterableconcept import IterableConcept from .iiterableconcept import IterableConcept
from .istringdisplayableconcept import StringDisplayableConcept
from .ikeyenumerator import KeyEnumerator from .ikeyenumerator import KeyEnumerator
from .irawenumerator import RawEnumerator
class ModelObjectKind(Enum): class ModelObjectKind(Enum):
@ -45,6 +48,7 @@ class ModelObject(object):
def __init__(self, obj): def __init__(self, obj):
self._obj = obj self._obj = obj
self.concept = None self.concept = None
self.dconcept = None
exception.wrap_comclass(self._obj) exception.wrap_comclass(self._obj)
def Release(self): def Release(self):
@ -96,12 +100,16 @@ class ModelObject(object):
return RawEnumerator(keys, kind) return RawEnumerator(keys, kind)
def GetConcept(self, ref): def GetConcept(self, ref):
try:
ifc = POINTER(IUnknown)() ifc = POINTER(IUnknown)()
metadata = POINTER(DbgMod.IKeyStore)() metadata = POINTER(DbgMod.IKeyStore)()
hr = self._obj.GetConcept(ref._iid_, byref(ifc), byref(metadata)) hr = self._obj.GetConcept(ref._iid_, byref(ifc), byref(metadata))
if hr != S_OK: if hr != S_OK:
return None return None
return cast(ifc, POINTER(ref)) return cast(ifc, POINTER(ref))
except Exception as e:
print(f"GetConcept exception: {e}")
return None
def GetContext(self, context): def GetContext(self, context):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
@ -111,10 +119,14 @@ class ModelObject(object):
def GetIntrinsicValue(self): def GetIntrinsicValue(self):
var = VARIANT() var = VARIANT()
try:
hr = self._obj.GetIntrinsicValue(var) hr = self._obj.GetIntrinsicValue(var)
if hr != S_OK: if hr != S_OK:
return None return None
return var return var
except Exception as e:
print(f"GetIntrinsicValue exception: {e}")
return None
def GetIntrinsicValueAs(self, vt): def GetIntrinsicValueAs(self, vt):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
@ -140,8 +152,31 @@ class ModelObject(object):
exception.check_err(hr) exception.check_err(hr)
return kind return kind
def GetLocation(self, location): # DOESN"T WORK YET
raise exception.E_NOTIMPL_Error # def GetTypeKind(self):
# typeKind = None
# modelKind = self.GetKind()
# if modelKind.value == ModelObjectKind.TARGET_OBJECT.value:
# targetInfo = self.GetTargetInfo()
# if targetInfo is not None:
# typeKind = DbgMod.tagTYPEKIND()
# hr = targetInfo._obj.GetTypeKind(byref(typeKind))
# if hr != S_OK:
# return None
# if modelKind.value == ModelObjectKind.INTRINSIC.value:
# typeInfo = self.GetTypeInfo()
# if typeInfo is not None:
# typeKind = DbgMod.tagTYPEKIND()
# hr = typeInfo._obj.GetTypeKind(byref(typeKind))
# if hr != S_OK:
# return None
# return typeKind
def GetLocation(self):
loc = DbgMod._Location()
hr = self._obj.GetLocation(loc)
exception.check_err(hr)
return loc
def GetNumberOfParentModels(self, numModels): def GetNumberOfParentModels(self, numModels):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
@ -152,18 +187,55 @@ class ModelObject(object):
def GetRawReference(self, kind, name, searchFlags, object): def GetRawReference(self, kind, name, searchFlags, object):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def GetRawValue(self, kind, name, searchFlags, object): def GetRawValue(self, kind, name, searchFlags):
raise exception.E_NOTIMPL_Error kbuf = cast(c_wchar_p(name), POINTER(c_ushort))
value = POINTER(DbgMod.IModelObject)()
hr = self._obj.GetRawValue(kind, kbuf, searchFlags, byref(value))
if hr != S_OK:
return None
return ModelObject(value)
def GetTargetInfo(self): def GetTargetInfo(self):
location = POINTER(DbgMod._Location)() location = DbgMod._Location()
type = POINTER(DbgMod.IDebugHostType)() type = POINTER(DbgMod.IDebugHostType)()
hr = self._obj.GetTargetInfo(location, byref(type)) hr = self._obj.GetTargetInfo(location, byref(type))
exception.check_err(hr) exception.check_err(hr)
return type return ModelObject(type)
def GetTypeInfo(self, type): def GetTypeInfo(self):
raise exception.E_NOTIMPL_Error type = POINTER(DbgMod.IDebugHostType)()
hr = self._obj.GetTypeInfo(byref(type))
exception.check_err(hr)
return ModelObject(type)
def GetName(self):
name = BSTR()
hr = self._obj.GetName(name)
exception.check_err(hr)
return name
def ToDisplayString(self):
if self.dconcept is None:
dconcept = self.GetConcept(DbgMod.IStringDisplayableConcept)
if dconcept is None:
return None
self.dconcept = StringDisplayableConcept(dconcept)
return self.dconcept.ToDisplayString(self)
# This does NOT work - returns a null pointer for value. Why?
# One possibility: casting is not a valid way to obtain an IModelMethod
#
# def ToDisplayString0(self):
# map = self.GetAttributes()
# method = map["ToDisplayString"]
# mm = cast(method._obj, POINTER(DbgMod.IModelMethod))
# context = self._obj
# args = POINTER(DbgMod.IModelObject)()
# value = POINTER(DbgMod.IModelObject)()
# meta = POINTER(DbgMod.IKeyStore)()
# hr = mm.Call(context, c_ulonglong(0), args, byref(value), byref(meta))
# exception.check_err(hr)
# return ModelObject(value)
def IsEqualTo(self, other, equal): def IsEqualTo(self, other, equal):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
@ -198,23 +270,28 @@ class ModelObject(object):
return map return map
def GetRawValueMap(self): def GetRawValueMap(self):
# print(f"GetRawValueMap: {self}")
map = {} map = {}
kind = self.GetKind() kind = self.GetKind()
keys = self.EnumerateRawValues(kind, c_long(0)) # TODO: forcing kind to 0 because we can't GetTypeKind
keys = self.EnumerateRawValues(c_long(0), 0)
(k, v) = keys.GetNext() (k, v) = keys.GetNext()
while k is not None: while k is not None:
map[k.value] = v map[k.value] = v
(k, v) = keys.GetNext() (k, v) = keys.GetNext()
# print(f"{k}:{v}")
return map return map
def GetAttributes(self): def GetAttributes(self):
map = {} map = {}
kind = self.GetKind() kind = self.GetKind()
if kind == ModelObjectKind.ERROR: # print(f"GetAttributes: {kind}")
if kind is not None and kind.value == ModelObjectKind.ERROR.value:
print(f"ERROR from GetAttributes")
return map return map
if kind == ModelObjectKind.INTRINSIC or \ if kind.value == ModelObjectKind.INTRINSIC.value or \
kind == ModelObjectKind.TARGET_OBJECT or \ kind.value == ModelObjectKind.TARGET_OBJECT.value or \
kind == ModelObjectKind.TARGET_OBJECT_REFERENCE: kind.value == ModelObjectKind.TARGET_OBJECT_REFERENCE.value:
return self.GetRawValueMap() return self.GetRawValueMap()
return self.GetKeyValueMap() return self.GetKeyValueMap()
@ -245,6 +322,9 @@ class ModelObject(object):
def GetOffspring(self, path): def GetOffspring(self, path):
next = self next = self
for element in path: for element in path:
if next is None:
return None
kind = next.GetKind()
if element.startswith("["): if element.startswith("["):
idx = element[1:len(element)-1] idx = element[1:len(element)-1]
if "x" not in idx: if "x" not in idx:
@ -252,12 +332,17 @@ class ModelObject(object):
else: else:
idx = int(idx, 16) idx = int(idx, 16)
next = next.GetElement(idx) next = next.GetElement(idx)
# THIS IS RELATIVELY HORRIBLE - replace with GetRawValue?
elif kind is not None and kind.value == ModelObjectKind.TARGET_OBJECT.value:
map = next.GetAttributes()
next = map[element]
else: else:
next = next.GetKeyValue(element) next = next.GetKeyValue(element)
if next is None: #if next is None:
print(f"{element} not found") # print(f"{element} not found")
return next return next
def GetValue(self): def GetValue(self):
value = self.GetIntrinsicValue() value = self.GetIntrinsicValue()
if value is None: if value is None:
@ -266,9 +351,3 @@ class ModelObject(object):
return None return None
return value.value return value.value
def GetTypeKind(self):
kind = self.GetKind()
if kind == ModelObjectKind.TARGET_OBJECT or \
kind == ModelObjectKind.INTRINSIC:
return self.GetTargetInfo()
return None

View File

@ -0,0 +1,37 @@
## ###
# IP: GHIDRA
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##
from ctypes import *
from comtypes import BSTR, COMError
from comtypes.gen import DbgMod
from comtypes.hresult import S_OK, S_FALSE
from pybag.dbgeng import exception
class StringDisplayableConcept(object):
def __init__(self, concept):
self._concept = concept
concept.AddRef()
# StringDisplayableConcept
def ToDisplayString(self, context):
try:
val = BSTR()
self._concept.ToDisplayString(context._obj, None, byref(val))
except COMError as ce:
return None
return val.value

View File

@ -13,7 +13,6 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
## ##
from _ctypes_test import func
import functools import functools
import sys import sys
import threading import threading
@ -64,8 +63,11 @@ class ProcessState(object):
if description is not None: if description is not None:
commands.STATE.trace.snapshot(description) commands.STATE.trace.snapshot(description)
if first: if first:
if util.is_kernel():
commands.create_generic("Sessions")
commands.put_processes() commands.put_processes()
commands.put_environment() commands.put_environment()
commands.put_threads()
if self.threads: if self.threads:
commands.put_threads() commands.put_threads()
self.threads = False self.threads = False
@ -98,6 +100,7 @@ class ProcessState(object):
commands.put_threads(running=True) commands.put_threads(running=True)
def record_exited(self, exit_code, description=None): def record_exited(self, exit_code, description=None):
# print("RECORD_EXITED")
if description is not None: if description is not None:
commands.STATE.trace.snapshot(description) commands.STATE.trace.snapshot(description)
proc = util.selected_process() proc = util.selected_process()

View File

@ -536,6 +536,7 @@ def delete_breakpoint(breakpoint: sch.Schema('BreakpointSpec')):
@REGISTRY.method @REGISTRY.method
@util.dbg.eng_thread
def read_mem(process: sch.Schema('Process'), range: AddressRange): def read_mem(process: sch.Schema('Process'), range: AddressRange):
"""Read memory.""" """Read memory."""
# print("READ_MEM: process={}, range={}".format(process, range)) # print("READ_MEM: process={}, range={}".format(process, range))

View File

@ -8,13 +8,13 @@
<attribute name="Utility" schema="ANY" /> <attribute name="Utility" schema="ANY" />
<attribute name="_display" schema="STRING" hidden="yes" /> <attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" /> <attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" hidden="yes" /> <attribute schema="ANY"/>
</schema> </schema>
<schema name="SessionContainer" canonical="yes" elementResync="NEVER" attributeResync="NEVER"> <schema name="SessionContainer" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<interface name="Configurable" /> <interface name="Configurable" />
<element schema="Session" /> <element schema="Session" />
<attribute name="_order" schema="INT" hidden="yes" /> <attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" hidden="yes" /> <attribute schema="ANY"/>
</schema> </schema>
<schema name="Session" elementResync="NEVER" attributeResync="NEVER"> <schema name="Session" elementResync="NEVER" attributeResync="NEVER">
<interface name="Activatable" /> <interface name="Activatable" />
@ -34,7 +34,7 @@
<attribute name="_focus" schema="Selectable" required="yes" hidden="yes" /> <attribute name="_focus" schema="Selectable" required="yes" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" /> <attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" /> <attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" hidden="yes" /> <attribute schema="ANY"/>
</schema> </schema>
<schema name="Selectable" elementResync="NEVER" attributeResync="NEVER"> <schema name="Selectable" elementResync="NEVER" attributeResync="NEVER">
<element schema="OBJECT" /> <element schema="OBJECT" />
@ -53,7 +53,7 @@
<interface name="BreakpointSpecContainer" /> <interface name="BreakpointSpecContainer" />
<element schema="BreakpointSpec" /> <element schema="BreakpointSpec" />
<attribute name="_order" schema="INT" hidden="yes" /> <attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" hidden="yes" /> <attribute schema="ANY" />
</schema> </schema>
<schema name="AvailableContainer" canonical="yes" elementResync="ALWAYS" attributeResync="NEVER"> <schema name="AvailableContainer" canonical="yes" elementResync="ALWAYS" attributeResync="NEVER">
<interface name="Configurable" /> <interface name="Configurable" />
@ -65,7 +65,7 @@
<interface name="Configurable" /> <interface name="Configurable" />
<element schema="Process" /> <element schema="Process" />
<attribute name="_order" schema="INT" hidden="yes" /> <attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" hidden="yes" /> <attribute schema="ANY" />
</schema> </schema>
<schema name="BreakpointSpec" canonical="yes" elementResync="NEVER" attributeResync="NEVER"> <schema name="BreakpointSpec" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<interface name="BreakpointSpec" /> <interface name="BreakpointSpec" />
@ -132,7 +132,7 @@
<attribute name="_display" schema="STRING" hidden="yes" /> <attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" /> <attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" /> <attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" hidden="yes" /> <attribute schema="ANY" />
</schema> </schema>
<schema name="Environment" elementResync="NEVER" attributeResync="NEVER"> <schema name="Environment" elementResync="NEVER" attributeResync="NEVER">
<interface name="Environment" /> <interface name="Environment" />
@ -152,7 +152,7 @@
<interface name="ModuleContainer" /> <interface name="ModuleContainer" />
<element schema="Module" /> <element schema="Module" />
<attribute name="_order" schema="INT" hidden="yes" /> <attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" hidden="yes" /> <attribute schema="ANY" />
</schema> </schema>
<schema name="Memory" canonical="yes" elementResync="NEVER" attributeResync="NEVER"> <schema name="Memory" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<interface name="Memory" /> <interface name="Memory" />
@ -178,7 +178,7 @@
<interface name="Configurable" /> <interface name="Configurable" />
<element schema="Thread" /> <element schema="Thread" />
<attribute name="_order" schema="INT" hidden="yes" /> <attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" hidden="yes" /> <attribute schema="ANY" />
</schema> </schema>
<schema name="Method" elementResync="NEVER" attributeResync="NEVER"> <schema name="Method" elementResync="NEVER" attributeResync="NEVER">
<interface name="Method" /> <interface name="Method" />
@ -207,7 +207,7 @@
<attribute name="_short_display" schema="STRING" hidden="yes" /> <attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" /> <attribute name="_order" schema="INT" hidden="yes" />
<attribute name="Advance" schema="Method" required="yes" fixed="yes" hidden="yes" /> <attribute name="Advance" schema="Method" required="yes" fixed="yes" hidden="yes" />
<attribute schema="ANY" hidden="yes" /> <attribute schema="ANY" />
</schema> </schema>
<schema name="Module" elementResync="NEVER" attributeResync="NEVER"> <schema name="Module" elementResync="NEVER" attributeResync="NEVER">
<interface name="Module" /> <interface name="Module" />
@ -255,7 +255,7 @@
<element schema="StackFrame" /> <element schema="StackFrame" />
<attribute name="_display" schema="STRING" hidden="yes" /> <attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" /> <attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" hidden="yes" /> <attribute schema="ANY" />
</schema> </schema>
<schema name="SymbolContainer" canonical="yes" elementResync="ONCE" attributeResync="NEVER"> <schema name="SymbolContainer" canonical="yes" elementResync="ONCE" attributeResync="NEVER">
<interface name="SymbolNamespace" /> <interface name="SymbolNamespace" />
@ -284,7 +284,7 @@
<attribute name="Frame Offset" schema="ADDRESS" /> <attribute name="Frame Offset" schema="ADDRESS" />
<attribute name="_display" schema="STRING" hidden="yes" /> <attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" /> <attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" hidden="yes" /> <attribute schema="ANY" />
</schema> </schema>
<schema name="Section" elementResync="NEVER" attributeResync="NEVER"> <schema name="Section" elementResync="NEVER" attributeResync="NEVER">
<interface name="Section" /> <interface name="Section" />

View File

@ -37,6 +37,7 @@ from pybag.dbgeng import util as DbgUtil
from pybag.dbgeng.callbacks import DbgEngCallbacks from pybag.dbgeng.callbacks import DbgEngCallbacks
from ghidradbg.dbgmodel.ihostdatamodelaccess import HostDataModelAccess from ghidradbg.dbgmodel.ihostdatamodelaccess import HostDataModelAccess
from _winapi import STILL_ACTIVE
DbgVersion = namedtuple('DbgVersion', ['full', 'name', 'dotted', 'arch']) DbgVersion = namedtuple('DbgVersion', ['full', 'name', 'dotted', 'arch'])
@ -236,6 +237,7 @@ class GhidraDbg(object):
'load_dump' 'load_dump'
]: ]:
setattr(self, name, self.eng_thread(getattr(base, name))) setattr(self, name, self.eng_thread(getattr(base, name)))
self.IS_KERNEL = False
def _new_base(self): def _new_base(self):
self._protected_base = AllDbg() self._protected_base = AllDbg()
@ -364,6 +366,8 @@ class GhidraDbg(object):
@check_thread @check_thread
def pid(self): def pid(self):
try: try:
if is_kernel():
return 0
return self._base._systems.GetCurrentProcessSystemId() return self._base._systems.GetCurrentProcessSystemId()
except exception.E_UNEXPECTED_Error: except exception.E_UNEXPECTED_Error:
# There is no process # There is no process
@ -451,10 +455,27 @@ def get_breakpoints():
@dbg.eng_thread @dbg.eng_thread
def selected_process(): def selected_process():
try: try:
if is_kernel():
do = dbg._base._systems.GetCurrentProcessDataOffset()
id = c_ulong()
offset = c_ulonglong(do)
nproc = dbg._base._systems._sys.GetProcessIdByDataOffset(offset, byref(id))
return id.value
if dbg.use_generics: if dbg.use_generics:
return dbg._base._systems.GetCurrentProcessSystemId() return dbg._base._systems.GetCurrentProcessSystemId()
return dbg._base._systems.GetCurrentProcessId() return dbg._base._systems.GetCurrentProcessId()
except exception.E_UNEXPECTED_Error: except (exception.E_UNEXPECTED_Error, exception.E_NOTIMPL_Error) as e:
# NB: we're intentionally returning 0 instead of None
return 0
@dbg.eng_thread
def selected_process_space():
try:
if is_kernel():
return dbg._base._systems.GetCurrentProcessDataOffset()
return selected_process()
except (exception.E_UNEXPECTED_Error, exception.E_NOTIMPL_Error) as e:
# NB: we're intentionally returning 0 instead of None # NB: we're intentionally returning 0 instead of None
return 0 return 0
@ -462,10 +483,12 @@ def selected_process():
@dbg.eng_thread @dbg.eng_thread
def selected_thread(): def selected_thread():
try: try:
if is_kernel():
return 0
if dbg.use_generics: if dbg.use_generics:
return dbg._base._systems.GetCurrentThreadSystemId() return dbg._base._systems.GetCurrentThreadSystemId()
return dbg._base._systems.GetCurrentThreadId() return dbg._base._systems.GetCurrentThreadId()
except exception.E_UNEXPECTED_Error: except (exception.E_UNEXPECTED_Error, exception.E_NOTIMPL_Error) as e:
return None return None
@ -485,6 +508,10 @@ def selected_frame():
@dbg.eng_thread @dbg.eng_thread
def select_process(id: int): def select_process(id: int):
if is_kernel():
# TODO: Ideally this should get the data offset from the id and then call
# SetImplicitProcessDataOffset
return
if dbg.use_generics: if dbg.use_generics:
id = get_proc_id(id) id = get_proc_id(id)
return dbg._base._systems.SetCurrentProcessId(id) return dbg._base._systems.SetCurrentProcessId(id)
@ -492,6 +519,10 @@ def select_process(id: int):
@dbg.eng_thread @dbg.eng_thread
def select_thread(id: int): def select_thread(id: int):
if is_kernel():
# TODO: Ideally this should get the data offset from the id and then call
# SetImplicitThreadDataOffset
return
if dbg.use_generics: if dbg.use_generics:
id = get_thread_id(id) id = get_thread_id(id)
return dbg._base._systems.SetCurrentThreadId(id) return dbg._base._systems.SetCurrentThreadId(id)
@ -586,14 +617,32 @@ def GetCurrentProcessPeb():
# TODO: upstream? # TODO: upstream?
_dbg = dbg._base _dbg = dbg._base
offset = c_ulonglong() offset = c_ulonglong()
if dbg.is_kernel():
hr = _dbg._systems._sys.GetCurrentProcessDataOffset(byref(offset))
else:
hr = _dbg._systems._sys.GetCurrentProcessPeb(byref(offset)) hr = _dbg._systems._sys.GetCurrentProcessPeb(byref(offset))
exception.check_err(hr) exception.check_err(hr)
return offset.value return offset.value
@dbg.eng_thread
def GetCurrentThreadTeb():
# TODO: upstream?
_dbg = dbg._base
offset = c_ulonglong()
if is_kernel():
hr = _dbg._systems._sys.GetCurrentThreadDataOffset(byref(offset))
else:
hr = _dbg._systems._sys.GetCurrentThreadTeb(byref(offset))
exception.check_err(hr)
return offset.value
@dbg.eng_thread @dbg.eng_thread
def GetExitCode(): def GetExitCode():
# TODO: upstream? # TODO: upstream?
if is_kernel():
return STILL_ACTIVE
exit_code = c_ulong() exit_code = c_ulong()
hr = dbg._base._client._cli.GetExitCode(byref(exit_code)) hr = dbg._base._client._cli.GetExitCode(byref(exit_code))
return exit_code.value return exit_code.value
@ -669,6 +718,21 @@ def get_proc_id(pid):
return None return None
def full_mem():
sizeptr = 64; #int(gdb.parse_and_eval('sizeof(void*)')) * 8
infoLow = DbgEng._MEMORY_BASIC_INFORMATION64()
infoLow.BaseAddress = 0
infoLow.RegionSize = (1 << (sizeptr-1))
infoLow.Protect = 0xFFF
infoLow.Name = "UMEM"
infoHigh = DbgEng._MEMORY_BASIC_INFORMATION64()
infoHigh.BaseAddress = 1 << (sizeptr-1)
infoHigh.RegionSize = (1 << (sizeptr-1))
infoHigh.Protect = 0xFFF
infoHigh.Name = "KMEM"
return [ infoLow, infoHigh ]
@dbg.eng_thread @dbg.eng_thread
def get_thread_id(tid): def get_thread_id(tid):
"""Get the list of all threads""" """Get the list of all threads"""
@ -715,39 +779,107 @@ def get_object(relpath):
if relpath != '': if relpath != '':
pathstr += "."+relpath pathstr += "."+relpath
path = split_path(pathstr) path = split_path(pathstr)
# print(f"PATH: {pathstr}")
return root.GetOffspring(path) return root.GetOffspring(path)
@dbg.eng_thread @dbg.eng_thread
def get_attributes(obj): def get_attributes(obj):
"""Get the list of attributes""" """Get the list of attributes"""
if obj is None:
return None
return obj.GetAttributes() return obj.GetAttributes()
@dbg.eng_thread @dbg.eng_thread
def get_elements(obj): def get_elements(obj):
"""Get the list of all threads""" """Get the list of all threads"""
if obj is None:
return None
return obj.GetElements() return obj.GetElements()
@dbg.eng_thread @dbg.eng_thread
def get_kind(obj): def get_kind(obj):
"""Get the list of all threads""" """Get the list of all threads"""
if obj is None:
return None
kind = obj.GetKind()
if kind is None:
return None
return obj.GetKind().value return obj.GetKind().value
@dbg.eng_thread @dbg.eng_thread
def get_type(obj): def get_type(obj):
"""Get the list of all threads""" """Get the list of all threads"""
if obj is None:
return None
return obj.GetTypeKind() return obj.GetTypeKind()
@dbg.eng_thread @dbg.eng_thread
def get_value(obj): def get_value(obj):
"""Get the list of all threads""" """Get the list of all threads"""
if obj is None:
return None
return obj.GetValue() return obj.GetValue()
@dbg.eng_thread
def get_intrinsic_value(obj):
"""Get the list of all threads"""
if obj is None:
return None
return obj.GetIntrinsicValue()
@dbg.eng_thread
def get_target_info(obj):
"""Get the list of all threads"""
if obj is None:
return None
return obj.GetTargetInfo()
@dbg.eng_thread
def get_type_info(obj):
"""Get the list of all threads"""
if obj is None:
return None
return obj.GetTypeInfo()
@dbg.eng_thread
def get_name(obj):
"""Get the list of all threads"""
if obj is None:
return None
return obj.GetName().value
@dbg.eng_thread
def to_display_string(obj):
"""Get the list of all threads"""
if obj is None:
return None
return obj.ToDisplayString()
@dbg.eng_thread
def get_location(obj):
"""Get the list of all threads"""
if obj is None:
return None
try:
loc = obj.GetLocation()
if loc is None:
return None
return hex(loc.Offset)
except:
return None
conv_map = {} conv_map = {}
@ -762,3 +894,11 @@ def get_convenience_variable(id):
def set_convenience_variable(id, value): def set_convenience_variable(id, value):
conv_map[id] = value conv_map[id] = value
def set_kernel(value):
dbg.IS_KERNEL = value
def is_kernel():
return dbg.IS_KERNEL

View File

@ -16,7 +16,7 @@
package agent.dbgeng.dbgeng; package agent.dbgeng.dbgeng;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.junit.Assume.*; import static org.junit.Assume.assumeTrue;
import java.io.*; import java.io.*;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -45,6 +45,7 @@ import ghidra.test.AbstractGhidraHeadlessIntegrationTest;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.NumericUtilities; import ghidra.util.NumericUtilities;
@Ignore("deprecated")
public class DbgEngTest extends AbstractGhidraHeadlessIntegrationTest { public class DbgEngTest extends AbstractGhidraHeadlessIntegrationTest {
private interface DummyLibIf extends StdCallLibrary { private interface DummyLibIf extends StdCallLibrary {

View File

@ -17,8 +17,11 @@ package agent.dbgeng.manager.impl;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import org.junit.Ignore;
import agent.dbgeng.manager.DbgManager; import agent.dbgeng.manager.DbgManager;
@Ignore("deprecated")
public class SpawnedDbgManagerTest extends AbstractDbgManagerTest { public class SpawnedDbgManagerTest extends AbstractDbgManagerTest {
@Override @Override
protected CompletableFuture<Void> startManager(DbgManager manager) { protected CompletableFuture<Void> startManager(DbgManager manager) {

View File

@ -15,10 +15,13 @@
*/ */
package agent.dbgeng.model.gadp; package agent.dbgeng.model.gadp;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengBreakpointsTest; import agent.dbgeng.model.AbstractModelForDbgengBreakpointsTest;
import ghidra.dbg.util.PathPattern; import ghidra.dbg.util.PathPattern;
import ghidra.dbg.util.PathUtils; import ghidra.dbg.util.PathUtils;
@Ignore("deprecated")
public class GadpModelForDbgengBreakpointsTest extends AbstractModelForDbgengBreakpointsTest { public class GadpModelForDbgengBreakpointsTest extends AbstractModelForDbgengBreakpointsTest {
@Override @Override

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgeng.model.gadp; package agent.dbgeng.model.gadp;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengFactoryTest; import agent.dbgeng.model.AbstractModelForDbgengFactoryTest;
@Ignore("deprecated")
public class GadpModelForDbgengFactoryTest extends AbstractModelForDbgengFactoryTest { public class GadpModelForDbgengFactoryTest extends AbstractModelForDbgengFactoryTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {

View File

@ -15,13 +15,17 @@
*/ */
package agent.dbgeng.model.gadp; package agent.dbgeng.model.gadp;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengFrameActivationTest; import agent.dbgeng.model.AbstractModelForDbgengFrameActivationTest;
import ghidra.dbg.util.PathPattern; import ghidra.dbg.util.PathPattern;
import ghidra.dbg.util.PathUtils; import ghidra.dbg.util.PathUtils;
@Ignore("deprecated")
public class GadpModelForDbgengFrameActivationTest public class GadpModelForDbgengFrameActivationTest
extends AbstractModelForDbgengFrameActivationTest { extends AbstractModelForDbgengFrameActivationTest {
@Override
protected PathPattern getStackPattern() { protected PathPattern getStackPattern() {
return new PathPattern(PathUtils.parse("Sessions[0].Processes[].Threads[].Stack[]")); return new PathPattern(PathUtils.parse("Sessions[0].Processes[].Threads[].Stack[]"));
} }

View File

@ -20,6 +20,7 @@ import org.junit.Test;
import agent.dbgeng.model.AbstractModelForDbgengInterpreterTest; import agent.dbgeng.model.AbstractModelForDbgengInterpreterTest;
@Ignore("deprecated")
public class GadpModelForDbgengInterpreterTest extends AbstractModelForDbgengInterpreterTest { public class GadpModelForDbgengInterpreterTest extends AbstractModelForDbgengInterpreterTest {
// NB: testLaunchViaInterpreterShowInProcessContainer fails // NB: testLaunchViaInterpreterShowInProcessContainer fails

View File

@ -17,13 +17,17 @@ package agent.dbgeng.model.gadp;
import java.util.List; import java.util.List;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengProcessActivationTest; import agent.dbgeng.model.AbstractModelForDbgengProcessActivationTest;
import ghidra.dbg.util.PathPattern; import ghidra.dbg.util.PathPattern;
import ghidra.dbg.util.PathUtils; import ghidra.dbg.util.PathUtils;
@Ignore("deprecated")
public class GadpModelForDbgengProcessActivationTest public class GadpModelForDbgengProcessActivationTest
extends AbstractModelForDbgengProcessActivationTest { extends AbstractModelForDbgengProcessActivationTest {
@Override
protected PathPattern getProcessPattern() { protected PathPattern getProcessPattern() {
return new PathPattern(PathUtils.parse("Sessions[0].Processes[]")); return new PathPattern(PathUtils.parse("Sessions[0].Processes[]"));
} }
@ -38,6 +42,7 @@ public class GadpModelForDbgengProcessActivationTest
return PathUtils.parse("Sessions[0]"); return PathUtils.parse("Sessions[0]");
} }
@Override
public String getIdFromCapture(String line) { public String getIdFromCapture(String line) {
return line.split("\\s+")[1]; return line.split("\\s+")[1];
} }

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgeng.model.gadp; package agent.dbgeng.model.gadp;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengRootAttacherTest; import agent.dbgeng.model.AbstractModelForDbgengRootAttacherTest;
@Ignore("deprecated")
public class GadpModelForDbgengRootAttacherTest extends AbstractModelForDbgengRootAttacherTest { public class GadpModelForDbgengRootAttacherTest extends AbstractModelForDbgengRootAttacherTest {
// NB: testListAttachable fails with OTE - [] not invalidated // NB: testListAttachable fails with OTE - [] not invalidated

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgeng.model.gadp; package agent.dbgeng.model.gadp;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengRootLauncherTest; import agent.dbgeng.model.AbstractModelForDbgengRootLauncherTest;
@Ignore("deprecated")
public class GadpModelForDbgengRootLauncherTest extends AbstractModelForDbgengRootLauncherTest { public class GadpModelForDbgengRootLauncherTest extends AbstractModelForDbgengRootLauncherTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgeng.model.gadp; package agent.dbgeng.model.gadp;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengScenarioCloneExitTest; import agent.dbgeng.model.AbstractModelForDbgengScenarioCloneExitTest;
@Ignore("deprecated")
public class GadpModelForDbgengScenarioCloneExitTest public class GadpModelForDbgengScenarioCloneExitTest
extends AbstractModelForDbgengScenarioCloneExitTest { extends AbstractModelForDbgengScenarioCloneExitTest {
@Override @Override

View File

@ -20,9 +20,11 @@ import org.junit.Test;
import agent.dbgeng.model.AbstractModelForDbgengScenarioForkExitTest; import agent.dbgeng.model.AbstractModelForDbgengScenarioForkExitTest;
@Ignore("deprecated")
public class GadpModelForDbgengScenarioForkExitTest public class GadpModelForDbgengScenarioForkExitTest
extends AbstractModelForDbgengScenarioForkExitTest { extends AbstractModelForDbgengScenarioForkExitTest {
@Override
@Ignore("Specimen is currently defunct") @Ignore("Specimen is currently defunct")
@Test @Test
public void testScenario() throws Throwable { public void testScenario() throws Throwable {

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgeng.model.gadp; package agent.dbgeng.model.gadp;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengScenarioMemoryTest; import agent.dbgeng.model.AbstractModelForDbgengScenarioMemoryTest;
@Ignore("deprecated")
public class GadpModelForDbgengScenarioMemoryTest extends AbstractModelForDbgengScenarioMemoryTest { public class GadpModelForDbgengScenarioMemoryTest extends AbstractModelForDbgengScenarioMemoryTest {
// NB: Fails on validateCompletionThread // NB: Fails on validateCompletionThread

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgeng.model.gadp; package agent.dbgeng.model.gadp;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengScenarioStackTest; import agent.dbgeng.model.AbstractModelForDbgengScenarioStackTest;
@Ignore("deprecated")
public class GadpModelForDbgengScenarioStackTest extends AbstractModelForDbgengScenarioStackTest { public class GadpModelForDbgengScenarioStackTest extends AbstractModelForDbgengScenarioStackTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgeng.model.gadp; package agent.dbgeng.model.gadp;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengScenarioX64RegistersTest; import agent.dbgeng.model.AbstractModelForDbgengScenarioX64RegistersTest;
@Ignore("deprecated")
public class GadpModelForDbgengScenarioX64RegistersTest public class GadpModelForDbgengScenarioX64RegistersTest
extends AbstractModelForDbgengScenarioX64RegistersTest { extends AbstractModelForDbgengScenarioX64RegistersTest {
@Override @Override

View File

@ -19,8 +19,9 @@ import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengSessionActivationTest; import agent.dbgeng.model.AbstractModelForDbgengSessionActivationTest;
@Ignore("Don't know how to make multiple sessions") @Ignore("Don't know how to make multiple sessions, deprecated")
public class GadpModelForDbgengSessionActivationTest extends AbstractModelForDbgengSessionActivationTest { public class GadpModelForDbgengSessionActivationTest
extends AbstractModelForDbgengSessionActivationTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {
return new GadpDbgengModelHost(); return new GadpDbgengModelHost();

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgeng.model.gadp; package agent.dbgeng.model.gadp;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengSteppableTest; import agent.dbgeng.model.AbstractModelForDbgengSteppableTest;
@Ignore("deprecated")
public class GadpModelForDbgengSteppableTest extends AbstractModelForDbgengSteppableTest { public class GadpModelForDbgengSteppableTest extends AbstractModelForDbgengSteppableTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {

View File

@ -17,13 +17,17 @@ package agent.dbgeng.model.gadp;
import java.util.List; import java.util.List;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengThreadActivationTest; import agent.dbgeng.model.AbstractModelForDbgengThreadActivationTest;
import ghidra.dbg.util.PathPattern; import ghidra.dbg.util.PathPattern;
import ghidra.dbg.util.PathUtils; import ghidra.dbg.util.PathUtils;
@Ignore("deprecated")
public class GadpModelForDbgengThreadActivationTest public class GadpModelForDbgengThreadActivationTest
extends AbstractModelForDbgengThreadActivationTest { extends AbstractModelForDbgengThreadActivationTest {
@Override
protected PathPattern getThreadPattern() { protected PathPattern getThreadPattern() {
return new PathPattern(PathUtils.parse("Sessions[0].Processes[].Threads[]")); return new PathPattern(PathUtils.parse("Sessions[0].Processes[].Threads[]"));
} }
@ -38,6 +42,7 @@ public class GadpModelForDbgengThreadActivationTest
return PathUtils.parse("Sessions[0]"); return PathUtils.parse("Sessions[0]");
} }
@Override
public String getIdFromCapture(String line) { public String getIdFromCapture(String line) {
return line.split("\\s+")[1]; return line.split("\\s+")[1];
} }

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgeng.model.gadp; package agent.dbgeng.model.gadp;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengX64RegistersTest; import agent.dbgeng.model.AbstractModelForDbgengX64RegistersTest;
@Ignore("deprecated")
public class GadpModelForDbgengX64RegistersTest extends AbstractModelForDbgengX64RegistersTest { public class GadpModelForDbgengX64RegistersTest extends AbstractModelForDbgengX64RegistersTest {
// NB: Fails testWriteRegisters // NB: Fails testWriteRegisters

View File

@ -15,11 +15,14 @@
*/ */
package agent.dbgeng.model.invm; package agent.dbgeng.model.invm;
import org.junit.Ignore;
import agent.dbgeng.DbgEngInJvmDebuggerModelFactory; import agent.dbgeng.DbgEngInJvmDebuggerModelFactory;
import agent.dbgeng.dbgeng.DbgEngTest; import agent.dbgeng.dbgeng.DbgEngTest;
import agent.dbgeng.model.AbstractDbgengModelHost; import agent.dbgeng.model.AbstractDbgengModelHost;
import ghidra.dbg.DebuggerModelFactory; import ghidra.dbg.DebuggerModelFactory;
@Ignore("deprecated")
public class InVmDbgengModelHost extends AbstractDbgengModelHost { public class InVmDbgengModelHost extends AbstractDbgengModelHost {
@Override @Override
public DebuggerModelFactory getModelFactory() { public DebuggerModelFactory getModelFactory() {

View File

@ -15,10 +15,15 @@
*/ */
package agent.dbgeng.model.invm; package agent.dbgeng.model.invm;
import org.junit.Ignore;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengBreakpointsTest; import agent.dbgeng.model.AbstractModelForDbgengBreakpointsTest;
import ghidra.dbg.util.PathPattern; import ghidra.dbg.util.PathPattern;
import ghidra.dbg.util.PathUtils; import ghidra.dbg.util.PathUtils;
@Ignore("deprecated")
public class InVmModelForDbgengBreakpointsTest extends AbstractModelForDbgengBreakpointsTest { public class InVmModelForDbgengBreakpointsTest extends AbstractModelForDbgengBreakpointsTest {
@Override @Override

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgeng.model.invm; package agent.dbgeng.model.invm;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengFactoryTest; import agent.dbgeng.model.AbstractModelForDbgengFactoryTest;
@Ignore("deprecated")
public class InVmModelForDbgengFactoryTest extends AbstractModelForDbgengFactoryTest { public class InVmModelForDbgengFactoryTest extends AbstractModelForDbgengFactoryTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {

View File

@ -15,13 +15,17 @@
*/ */
package agent.dbgeng.model.invm; package agent.dbgeng.model.invm;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengFrameActivationTest; import agent.dbgeng.model.AbstractModelForDbgengFrameActivationTest;
import ghidra.dbg.util.PathPattern; import ghidra.dbg.util.PathPattern;
import ghidra.dbg.util.PathUtils; import ghidra.dbg.util.PathUtils;
@Ignore("deprecated")
public class InVmModelForDbgengFrameActivationTest public class InVmModelForDbgengFrameActivationTest
extends AbstractModelForDbgengFrameActivationTest { extends AbstractModelForDbgengFrameActivationTest {
@Override
protected PathPattern getStackPattern() { protected PathPattern getStackPattern() {
return new PathPattern(PathUtils.parse("Sessions[0].Processes[].Threads[].Stack[]")); return new PathPattern(PathUtils.parse("Sessions[0].Processes[].Threads[].Stack[]"));
} }

View File

@ -21,6 +21,7 @@ import org.junit.Test;
import agent.dbgeng.model.AbstractModelForDbgengInterpreterTest; import agent.dbgeng.model.AbstractModelForDbgengInterpreterTest;
import ghidra.dbg.error.DebuggerModelTerminatingException; import ghidra.dbg.error.DebuggerModelTerminatingException;
@Ignore("deprecated")
public class InVmModelForDbgengInterpreterTest extends AbstractModelForDbgengInterpreterTest { public class InVmModelForDbgengInterpreterTest extends AbstractModelForDbgengInterpreterTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {

View File

@ -17,13 +17,17 @@ package agent.dbgeng.model.invm;
import java.util.List; import java.util.List;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengProcessActivationTest; import agent.dbgeng.model.AbstractModelForDbgengProcessActivationTest;
import ghidra.dbg.util.PathPattern; import ghidra.dbg.util.PathPattern;
import ghidra.dbg.util.PathUtils; import ghidra.dbg.util.PathUtils;
@Ignore("deprecated")
public class InVmModelForDbgengProcessActivationTest public class InVmModelForDbgengProcessActivationTest
extends AbstractModelForDbgengProcessActivationTest { extends AbstractModelForDbgengProcessActivationTest {
@Override
protected PathPattern getProcessPattern() { protected PathPattern getProcessPattern() {
return new PathPattern(PathUtils.parse("Sessions[0].Processes[]")); return new PathPattern(PathUtils.parse("Sessions[0].Processes[]"));
} }
@ -38,6 +42,7 @@ public class InVmModelForDbgengProcessActivationTest
return PathUtils.parse("Sessions[0]"); return PathUtils.parse("Sessions[0]");
} }
@Override
public String getIdFromCapture(String line) { public String getIdFromCapture(String line) {
return line.split("\\s+")[1]; return line.split("\\s+")[1];
} }

View File

@ -20,6 +20,7 @@ import org.junit.Test;
import agent.dbgeng.model.AbstractModelForDbgengRootAttacherTest; import agent.dbgeng.model.AbstractModelForDbgengRootAttacherTest;
@Ignore("deprecated")
public class InVmModelForDbgengRootAttacherTest extends AbstractModelForDbgengRootAttacherTest { public class InVmModelForDbgengRootAttacherTest extends AbstractModelForDbgengRootAttacherTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgeng.model.invm; package agent.dbgeng.model.invm;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengRootLauncherTest; import agent.dbgeng.model.AbstractModelForDbgengRootLauncherTest;
@Ignore("deprecated")
public class InVmModelForDbgengRootLauncherTest extends AbstractModelForDbgengRootLauncherTest { public class InVmModelForDbgengRootLauncherTest extends AbstractModelForDbgengRootLauncherTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgeng.model.invm; package agent.dbgeng.model.invm;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengScenarioCloneExitTest; import agent.dbgeng.model.AbstractModelForDbgengScenarioCloneExitTest;
@Ignore("deprecated")
public class InVmModelForDbgengScenarioCloneExitTest public class InVmModelForDbgengScenarioCloneExitTest
extends AbstractModelForDbgengScenarioCloneExitTest { extends AbstractModelForDbgengScenarioCloneExitTest {
@Override @Override

View File

@ -20,9 +20,11 @@ import org.junit.Test;
import agent.dbgeng.model.AbstractModelForDbgengScenarioForkExitTest; import agent.dbgeng.model.AbstractModelForDbgengScenarioForkExitTest;
@Ignore("deprecated")
public class InVmModelForDbgengScenarioForkExitTest public class InVmModelForDbgengScenarioForkExitTest
extends AbstractModelForDbgengScenarioForkExitTest { extends AbstractModelForDbgengScenarioForkExitTest {
@Override
@Ignore("Specimen is currently defunct") @Ignore("Specimen is currently defunct")
@Test @Test
public void testScenario() throws Throwable { public void testScenario() throws Throwable {

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgeng.model.invm; package agent.dbgeng.model.invm;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengScenarioMemoryTest; import agent.dbgeng.model.AbstractModelForDbgengScenarioMemoryTest;
@Ignore("deprecated")
public class InVmModelForDbgengScenarioMemoryTest extends AbstractModelForDbgengScenarioMemoryTest { public class InVmModelForDbgengScenarioMemoryTest extends AbstractModelForDbgengScenarioMemoryTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgeng.model.invm; package agent.dbgeng.model.invm;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengScenarioStackTest; import agent.dbgeng.model.AbstractModelForDbgengScenarioStackTest;
@Ignore("deprecated")
public class InVmModelForDbgengScenarioStackTest extends AbstractModelForDbgengScenarioStackTest { public class InVmModelForDbgengScenarioStackTest extends AbstractModelForDbgengScenarioStackTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgeng.model.invm; package agent.dbgeng.model.invm;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengScenarioX64RegistersTest; import agent.dbgeng.model.AbstractModelForDbgengScenarioX64RegistersTest;
@Ignore("deprecated")
public class InVmModelForDbgengScenarioX64RegistersTest public class InVmModelForDbgengScenarioX64RegistersTest
extends AbstractModelForDbgengScenarioX64RegistersTest { extends AbstractModelForDbgengScenarioX64RegistersTest {
@Override @Override

View File

@ -19,8 +19,9 @@ import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengSessionActivationTest; import agent.dbgeng.model.AbstractModelForDbgengSessionActivationTest;
@Ignore("Don't know how to make multiple sessions") @Ignore("Don't know how to make multiple sessions, deprecated")
public class InVmModelForDbgengSessionActivationTest extends AbstractModelForDbgengSessionActivationTest { public class InVmModelForDbgengSessionActivationTest
extends AbstractModelForDbgengSessionActivationTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {
return new InVmDbgengModelHost(); return new InVmDbgengModelHost();

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgeng.model.invm; package agent.dbgeng.model.invm;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengSteppableTest; import agent.dbgeng.model.AbstractModelForDbgengSteppableTest;
@Ignore("deprecated")
public class InVmModelForDbgengSteppableTest extends AbstractModelForDbgengSteppableTest { public class InVmModelForDbgengSteppableTest extends AbstractModelForDbgengSteppableTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {

View File

@ -17,13 +17,17 @@ package agent.dbgeng.model.invm;
import java.util.List; import java.util.List;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengThreadActivationTest; import agent.dbgeng.model.AbstractModelForDbgengThreadActivationTest;
import ghidra.dbg.util.PathPattern; import ghidra.dbg.util.PathPattern;
import ghidra.dbg.util.PathUtils; import ghidra.dbg.util.PathUtils;
@Ignore("deprecated")
public class InVmModelForDbgengThreadActivationTest public class InVmModelForDbgengThreadActivationTest
extends AbstractModelForDbgengThreadActivationTest { extends AbstractModelForDbgengThreadActivationTest {
@Override
protected PathPattern getThreadPattern() { protected PathPattern getThreadPattern() {
return new PathPattern(PathUtils.parse("Sessions[0].Processes[].Threads[]")); return new PathPattern(PathUtils.parse("Sessions[0].Processes[].Threads[]"));
} }
@ -38,6 +42,7 @@ public class InVmModelForDbgengThreadActivationTest
return PathUtils.parse("Sessions[0]"); return PathUtils.parse("Sessions[0]");
} }
@Override
public String getIdFromCapture(String line) { public String getIdFromCapture(String line) {
return line.split("\\s+")[1]; return line.split("\\s+")[1];
} }

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgeng.model.invm; package agent.dbgeng.model.invm;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengX64RegistersTest; import agent.dbgeng.model.AbstractModelForDbgengX64RegistersTest;
@Ignore("deprecated")
public class InVmModelForDbgengX64RegistersTest extends AbstractModelForDbgengX64RegistersTest { public class InVmModelForDbgengX64RegistersTest extends AbstractModelForDbgengX64RegistersTest {
@Override @Override

View File

@ -21,8 +21,7 @@ import static org.junit.Assert.assertNotNull;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import org.junit.Before; import org.junit.*;
import org.junit.Test;
import agent.dbgeng.dbgeng.*; import agent.dbgeng.dbgeng.*;
import agent.dbgeng.dbgeng.DebugBreakpoint.BreakFlags; import agent.dbgeng.dbgeng.DebugBreakpoint.BreakFlags;
@ -37,6 +36,7 @@ import ghidra.dbg.util.PathUtils;
import ghidra.test.AbstractGhidraHeadlessIntegrationTest; import ghidra.test.AbstractGhidraHeadlessIntegrationTest;
import ghidra.util.Msg; import ghidra.util.Msg;
@Ignore("deprecated")
public class DbgModelSetContextMWETest extends AbstractGhidraHeadlessIntegrationTest { public class DbgModelSetContextMWETest extends AbstractGhidraHeadlessIntegrationTest {
@Before @Before

View File

@ -22,8 +22,7 @@ import java.nio.ByteBuffer;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import org.junit.Before; import org.junit.*;
import org.junit.Test;
import com.sun.jna.Pointer; import com.sun.jna.Pointer;
import com.sun.jna.WString; import com.sun.jna.WString;
@ -53,6 +52,7 @@ import agent.dbgmodel.jna.dbgmodel.UnknownWithUtils;
import ghidra.test.AbstractGhidraHeadlessIntegrationTest; import ghidra.test.AbstractGhidraHeadlessIntegrationTest;
import ghidra.util.NumericUtilities; import ghidra.util.NumericUtilities;
@Ignore("deprecated")
public class DbgModelTest extends AbstractGhidraHeadlessIntegrationTest { public class DbgModelTest extends AbstractGhidraHeadlessIntegrationTest {
protected static HostDataModelAccess cachedAccess = null; protected static HostDataModelAccess cachedAccess = null;
protected static DebugClient cachedClient = null; protected static DebugClient cachedClient = null;

View File

@ -15,10 +15,13 @@
*/ */
package agent.dbgmodel.model.invm; package agent.dbgmodel.model.invm;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengBreakpointsTest; import agent.dbgeng.model.AbstractModelForDbgengBreakpointsTest;
import ghidra.dbg.util.PathPattern; import ghidra.dbg.util.PathPattern;
import ghidra.dbg.util.PathUtils; import ghidra.dbg.util.PathUtils;
@Ignore("deprecated")
public class InVmModelForDbgmodelBreakpointsTest extends AbstractModelForDbgengBreakpointsTest { public class InVmModelForDbgmodelBreakpointsTest extends AbstractModelForDbgengBreakpointsTest {
@Override @Override

View File

@ -15,9 +15,12 @@
*/ */
package agent.dbgmodel.model.invm; package agent.dbgmodel.model.invm;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengFactoryTest; import agent.dbgeng.model.AbstractModelForDbgengFactoryTest;
import ghidra.dbg.testutil.TestDebuggerModelProvider.ModelHost.WithoutThreadValidation; import ghidra.dbg.testutil.TestDebuggerModelProvider.ModelHost.WithoutThreadValidation;
@Ignore("deprecated")
public class InVmModelForDbgmodelFactoryTest extends AbstractModelForDbgengFactoryTest { public class InVmModelForDbgmodelFactoryTest extends AbstractModelForDbgengFactoryTest {
@Override @Override

View File

@ -15,13 +15,17 @@
*/ */
package agent.dbgmodel.model.invm; package agent.dbgmodel.model.invm;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengFrameActivationTest; import agent.dbgeng.model.AbstractModelForDbgengFrameActivationTest;
import ghidra.dbg.util.PathPattern; import ghidra.dbg.util.PathPattern;
import ghidra.dbg.util.PathUtils; import ghidra.dbg.util.PathUtils;
@Ignore("deprecated")
public class InVmModelForDbgmodelFrameActivationTest public class InVmModelForDbgmodelFrameActivationTest
extends AbstractModelForDbgengFrameActivationTest { extends AbstractModelForDbgengFrameActivationTest {
@Override
protected PathPattern getStackPattern() { protected PathPattern getStackPattern() {
return new PathPattern( return new PathPattern(
PathUtils.parse("Sessions[0x0].Processes[].Threads[].Stack.Frames[]")); PathUtils.parse("Sessions[0x0].Processes[].Threads[].Stack.Frames[]"));

View File

@ -32,6 +32,7 @@ import ghidra.dbg.test.AbstractDebuggerModelTest;
import ghidra.dbg.test.ProvidesTargetViaLaunchSpecimen; import ghidra.dbg.test.ProvidesTargetViaLaunchSpecimen;
import ghidra.dbg.util.PathUtils; import ghidra.dbg.util.PathUtils;
@Ignore("deprecated")
public class InVmModelForDbgmodelInterpreterTest extends AbstractModelForDbgengInterpreterTest public class InVmModelForDbgmodelInterpreterTest extends AbstractModelForDbgengInterpreterTest
implements ProvidesTargetViaLaunchSpecimen { implements ProvidesTargetViaLaunchSpecimen {
@Override @Override

View File

@ -17,15 +17,19 @@ package agent.dbgmodel.model.invm;
import java.util.List; import java.util.List;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengProcessActivationTest; import agent.dbgeng.model.AbstractModelForDbgengProcessActivationTest;
import ghidra.dbg.target.TargetInterpreter; import ghidra.dbg.target.TargetInterpreter;
import ghidra.dbg.target.TargetObject; import ghidra.dbg.target.TargetObject;
import ghidra.dbg.util.PathPattern; import ghidra.dbg.util.PathPattern;
import ghidra.dbg.util.PathUtils; import ghidra.dbg.util.PathUtils;
@Ignore("deprecated")
public class InVmModelForDbgmodelProcessActivationTest public class InVmModelForDbgmodelProcessActivationTest
extends AbstractModelForDbgengProcessActivationTest { extends AbstractModelForDbgengProcessActivationTest {
@Override
protected PathPattern getProcessPattern() { protected PathPattern getProcessPattern() {
return new PathPattern(PathUtils.parse("Sessions[0x0].Processes[]")); return new PathPattern(PathUtils.parse("Sessions[0x0].Processes[]"));
} }
@ -40,6 +44,7 @@ public class InVmModelForDbgmodelProcessActivationTest
return PathUtils.parse("Sessions[0x0]"); return PathUtils.parse("Sessions[0x0]");
} }
@Override
public String getIdFromCapture(String line) { public String getIdFromCapture(String line) {
return "0x" + line.split("\\s+")[3]; return "0x" + line.split("\\s+")[3];
} }

View File

@ -20,6 +20,7 @@ import org.junit.Test;
import agent.dbgeng.model.AbstractModelForDbgengRootAttacherTest; import agent.dbgeng.model.AbstractModelForDbgengRootAttacherTest;
@Ignore("deprecated")
public class InVmModelForDbgmodelRootAttacherTest extends AbstractModelForDbgengRootAttacherTest { public class InVmModelForDbgmodelRootAttacherTest extends AbstractModelForDbgengRootAttacherTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgmodel.model.invm; package agent.dbgmodel.model.invm;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengRootLauncherTest; import agent.dbgeng.model.AbstractModelForDbgengRootLauncherTest;
@Ignore("deprecated")
public class InVmModelForDbgmodelRootLauncherTest extends AbstractModelForDbgengRootLauncherTest { public class InVmModelForDbgmodelRootLauncherTest extends AbstractModelForDbgengRootLauncherTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgmodel.model.invm; package agent.dbgmodel.model.invm;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengScenarioCloneExitTest; import agent.dbgeng.model.AbstractModelForDbgengScenarioCloneExitTest;
@Ignore("deprecated")
public class InVmModelForDbgmodelScenarioCloneExitTest public class InVmModelForDbgmodelScenarioCloneExitTest
extends AbstractModelForDbgengScenarioCloneExitTest { extends AbstractModelForDbgengScenarioCloneExitTest {
@Override @Override

View File

@ -20,9 +20,11 @@ import org.junit.Test;
import agent.dbgeng.model.AbstractModelForDbgengScenarioForkExitTest; import agent.dbgeng.model.AbstractModelForDbgengScenarioForkExitTest;
@Ignore("deprecated")
public class InVmModelForDbgmodelScenarioForkExitTest public class InVmModelForDbgmodelScenarioForkExitTest
extends AbstractModelForDbgengScenarioForkExitTest { extends AbstractModelForDbgengScenarioForkExitTest {
@Override
@Ignore("Specimen is currently defunct") @Ignore("Specimen is currently defunct")
@Test @Test
public void testScenario() throws Throwable { public void testScenario() throws Throwable {

View File

@ -17,6 +17,8 @@ package agent.dbgmodel.model.invm;
import java.util.*; import java.util.*;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengScenarioMemoryTest; import agent.dbgeng.model.AbstractModelForDbgengScenarioMemoryTest;
import ghidra.dbg.target.TargetModule; import ghidra.dbg.target.TargetModule;
import ghidra.dbg.target.TargetProcess; import ghidra.dbg.target.TargetProcess;
@ -24,6 +26,7 @@ import ghidra.dbg.util.PathUtils;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressRange; import ghidra.program.model.address.AddressRange;
@Ignore("deprecated")
public class InVmModelForDbgmodelScenarioMemoryTest public class InVmModelForDbgmodelScenarioMemoryTest
extends AbstractModelForDbgengScenarioMemoryTest { extends AbstractModelForDbgengScenarioMemoryTest {
@Override @Override

View File

@ -15,10 +15,13 @@
*/ */
package agent.dbgmodel.model.invm; package agent.dbgmodel.model.invm;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengScenarioStackTest; import agent.dbgeng.model.AbstractModelForDbgengScenarioStackTest;
import ghidra.dbg.target.TargetProcess; import ghidra.dbg.target.TargetProcess;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
@Ignore("deprecated")
public class InVmModelForDbgmodelScenarioStackTest extends AbstractModelForDbgengScenarioStackTest { public class InVmModelForDbgmodelScenarioStackTest extends AbstractModelForDbgengScenarioStackTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgmodel.model.invm; package agent.dbgmodel.model.invm;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengScenarioX64RegistersTest; import agent.dbgeng.model.AbstractModelForDbgengScenarioX64RegistersTest;
@Ignore("deprecated")
public class InVmModelForDbgmodelScenarioX64RegistersTest public class InVmModelForDbgmodelScenarioX64RegistersTest
extends AbstractModelForDbgengScenarioX64RegistersTest { extends AbstractModelForDbgengScenarioX64RegistersTest {
@Override @Override

View File

@ -19,8 +19,9 @@ import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengSessionActivationTest; import agent.dbgeng.model.AbstractModelForDbgengSessionActivationTest;
@Ignore("Don't know how to make multiple sessions") @Ignore("Don't know how to make multiple sessions, deprecated")
public class InVmModelForDbgmodelSessionActivationTest extends AbstractModelForDbgengSessionActivationTest { public class InVmModelForDbgmodelSessionActivationTest
extends AbstractModelForDbgengSessionActivationTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {
return new InVmDbgmodelModelHost(); return new InVmDbgmodelModelHost();

View File

@ -15,8 +15,11 @@
*/ */
package agent.dbgmodel.model.invm; package agent.dbgmodel.model.invm;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengSteppableTest; import agent.dbgeng.model.AbstractModelForDbgengSteppableTest;
@Ignore("deprecated")
public class InVmModelForDbgmodelSteppableTest extends AbstractModelForDbgengSteppableTest { public class InVmModelForDbgmodelSteppableTest extends AbstractModelForDbgengSteppableTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {

View File

@ -17,15 +17,19 @@ package agent.dbgmodel.model.invm;
import java.util.List; import java.util.List;
import org.junit.Ignore;
import agent.dbgeng.model.AbstractModelForDbgengThreadActivationTest; import agent.dbgeng.model.AbstractModelForDbgengThreadActivationTest;
import ghidra.dbg.target.TargetInterpreter; import ghidra.dbg.target.TargetInterpreter;
import ghidra.dbg.target.TargetObject; import ghidra.dbg.target.TargetObject;
import ghidra.dbg.util.PathPattern; import ghidra.dbg.util.PathPattern;
import ghidra.dbg.util.PathUtils; import ghidra.dbg.util.PathUtils;
@Ignore("deprecated")
public class InVmModelForDbgmodelThreadActivationTest public class InVmModelForDbgmodelThreadActivationTest
extends AbstractModelForDbgengThreadActivationTest { extends AbstractModelForDbgengThreadActivationTest {
@Override
protected PathPattern getThreadPattern() { protected PathPattern getThreadPattern() {
return new PathPattern(PathUtils.parse("Sessions[0x0].Processes[].Threads[]")); return new PathPattern(PathUtils.parse("Sessions[0x0].Processes[].Threads[]"));
} }
@ -40,6 +44,7 @@ public class InVmModelForDbgmodelThreadActivationTest
return PathUtils.parse("Sessions[0x0]"); return PathUtils.parse("Sessions[0x0]");
} }
@Override
public String getIdFromCapture(String line) { public String getIdFromCapture(String line) {
return "0x" + line.split("\\s+")[3].split("\\.")[1]; return "0x" + line.split("\\s+")[3].split("\\.")[1];
} }

View File

@ -24,6 +24,7 @@ import org.junit.Test;
import agent.dbgeng.model.AbstractModelForDbgengX64RegistersTest; import agent.dbgeng.model.AbstractModelForDbgengX64RegistersTest;
import ghidra.dbg.util.PathUtils; import ghidra.dbg.util.PathUtils;
@Ignore("deprecated")
public class InVmModelForDbgmodelX64RegistersTest extends AbstractModelForDbgengX64RegistersTest { public class InVmModelForDbgmodelX64RegistersTest extends AbstractModelForDbgengX64RegistersTest {
public final Map<String, byte[]> REG_VALSX = Map.ofEntries( public final Map<String, byte[]> REG_VALSX = Map.ofEntries(

View File

@ -176,7 +176,7 @@ public interface FridaGadpServer extends AutoCloseable {
* {@link #terminate()}, or 3) When an error occurs causing the server to terminate * {@link #terminate()}, or 3) When an error occurs causing the server to terminate
* unexpectedly. Otherwise, it returns true. * unexpectedly. Otherwise, it returns true.
* *
* @returns true if the server is currently running. * @return true if the server is currently running.
*/ */
public boolean isRunning(); public boolean isRunning();

View File

@ -15,8 +15,11 @@
*/ */
package agent.frida.model.gadp; package agent.frida.model.gadp;
import org.junit.Ignore;
import agent.frida.model.AbstractModelForFridaFactoryTest; import agent.frida.model.AbstractModelForFridaFactoryTest;
@Ignore("deprecated")
public class GadpModelForFridaFactoryTest extends AbstractModelForFridaFactoryTest { public class GadpModelForFridaFactoryTest extends AbstractModelForFridaFactoryTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {

View File

@ -21,6 +21,7 @@ import org.junit.Test;
import agent.frida.model.AbstractModelForFridaInterpreterTest; import agent.frida.model.AbstractModelForFridaInterpreterTest;
import ghidra.dbg.test.ProvidesTargetViaLaunchSpecimen; import ghidra.dbg.test.ProvidesTargetViaLaunchSpecimen;
@Ignore("deprecated")
public class GadpModelForFridaInterpreterTest extends AbstractModelForFridaInterpreterTest public class GadpModelForFridaInterpreterTest extends AbstractModelForFridaInterpreterTest
implements ProvidesTargetViaLaunchSpecimen { implements ProvidesTargetViaLaunchSpecimen {
@Override @Override
@ -61,4 +62,3 @@ public class GadpModelForFridaInterpreterTest extends AbstractModelForFridaInter
} }
} }

View File

@ -15,8 +15,11 @@
*/ */
package agent.frida.model.gadp; package agent.frida.model.gadp;
import org.junit.Ignore;
import agent.frida.model.AbstractModelForFridaRootLauncherTest; import agent.frida.model.AbstractModelForFridaRootLauncherTest;
@Ignore("deprecated")
public class GadpModelForFridaRootLauncherTest extends AbstractModelForFridaRootLauncherTest { public class GadpModelForFridaRootLauncherTest extends AbstractModelForFridaRootLauncherTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {

View File

@ -15,8 +15,11 @@
*/ */
package agent.frida.model.gadp; package agent.frida.model.gadp;
import org.junit.Ignore;
import agent.frida.model.AbstractModelForFridaScenarioStackTest; import agent.frida.model.AbstractModelForFridaScenarioStackTest;
@Ignore("deprecated")
public class GadpModelForFridaScenarioStackTest extends AbstractModelForFridaScenarioStackTest { public class GadpModelForFridaScenarioStackTest extends AbstractModelForFridaScenarioStackTest {
@Override @Override
public ModelHost modelHost() throws Throwable { public ModelHost modelHost() throws Throwable {

View File

@ -15,8 +15,11 @@
*/ */
package agent.frida.model.gadp; package agent.frida.model.gadp;
import org.junit.Ignore;
import agent.frida.model.AbstractModelForFridaX64RegistersTest; import agent.frida.model.AbstractModelForFridaX64RegistersTest;
@Ignore("deprecated")
public class GadpModelForFridaX64RegistersTest extends AbstractModelForFridaX64RegistersTest { public class GadpModelForFridaX64RegistersTest extends AbstractModelForFridaX64RegistersTest {
@Override @Override

View File

@ -15,11 +15,13 @@
*/ */
package agent.frida.model.invm; package agent.frida.model.invm;
import org.junit.Ignore;
import org.junit.experimental.categories.Category; import org.junit.experimental.categories.Category;
import agent.frida.model.AbstractModelForFridaFactoryTest; import agent.frida.model.AbstractModelForFridaFactoryTest;
import generic.test.category.NightlyCategory; import generic.test.category.NightlyCategory;
@Ignore("deprecated")
@Category(NightlyCategory.class) // this may actually be an @PortSensitive test @Category(NightlyCategory.class) // this may actually be an @PortSensitive test
public class InVmModelForFridaFactoryTest extends AbstractModelForFridaFactoryTest { public class InVmModelForFridaFactoryTest extends AbstractModelForFridaFactoryTest {
@Override @Override

View File

@ -23,6 +23,7 @@ import agent.frida.model.AbstractModelForFridaInterpreterTest;
import generic.test.category.NightlyCategory; import generic.test.category.NightlyCategory;
import ghidra.dbg.test.ProvidesTargetViaLaunchSpecimen; import ghidra.dbg.test.ProvidesTargetViaLaunchSpecimen;
@Ignore("deprecated")
@Category(NightlyCategory.class) // this may actually be an @PortSensitive test @Category(NightlyCategory.class) // this may actually be an @PortSensitive test
public class InVmModelForFridaInterpreterTest extends AbstractModelForFridaInterpreterTest public class InVmModelForFridaInterpreterTest extends AbstractModelForFridaInterpreterTest
implements ProvidesTargetViaLaunchSpecimen { implements ProvidesTargetViaLaunchSpecimen {

View File

@ -15,11 +15,13 @@
*/ */
package agent.frida.model.invm; package agent.frida.model.invm;
import org.junit.Ignore;
import org.junit.experimental.categories.Category; import org.junit.experimental.categories.Category;
import agent.frida.model.AbstractModelForFridaMethodsTest; import agent.frida.model.AbstractModelForFridaMethodsTest;
import generic.test.category.NightlyCategory; import generic.test.category.NightlyCategory;
@Ignore("deprecated")
@Category(NightlyCategory.class) // this may actually be an @PortSensitive test @Category(NightlyCategory.class) // this may actually be an @PortSensitive test
public class InVmModelForFridaMethodsTest extends AbstractModelForFridaMethodsTest { public class InVmModelForFridaMethodsTest extends AbstractModelForFridaMethodsTest {
@Override @Override

View File

@ -22,6 +22,7 @@ import org.junit.experimental.categories.Category;
import agent.frida.model.AbstractModelForFridaRootAttacherTest; import agent.frida.model.AbstractModelForFridaRootAttacherTest;
import generic.test.category.NightlyCategory; import generic.test.category.NightlyCategory;
@Ignore("deprecated")
@Category(NightlyCategory.class) // this may actually be an @PortSensitive test @Category(NightlyCategory.class) // this may actually be an @PortSensitive test
public class InVmModelForFridaRootAttacherTest extends AbstractModelForFridaRootAttacherTest { public class InVmModelForFridaRootAttacherTest extends AbstractModelForFridaRootAttacherTest {
@Override @Override

View File

@ -15,11 +15,13 @@
*/ */
package agent.frida.model.invm; package agent.frida.model.invm;
import org.junit.Ignore;
import org.junit.experimental.categories.Category; import org.junit.experimental.categories.Category;
import agent.frida.model.AbstractModelForFridaRootLauncherTest; import agent.frida.model.AbstractModelForFridaRootLauncherTest;
import generic.test.category.NightlyCategory; import generic.test.category.NightlyCategory;
@Ignore("deprecated")
@Category(NightlyCategory.class) // this may actually be an @PortSensitive test @Category(NightlyCategory.class) // this may actually be an @PortSensitive test
public class InVmModelForFridaRootLauncherTest extends AbstractModelForFridaRootLauncherTest { public class InVmModelForFridaRootLauncherTest extends AbstractModelForFridaRootLauncherTest {
@Override @Override

View File

@ -15,11 +15,13 @@
*/ */
package agent.frida.model.invm; package agent.frida.model.invm;
import org.junit.Ignore;
import org.junit.experimental.categories.Category; import org.junit.experimental.categories.Category;
import agent.frida.model.AbstractModelForFridaScenarioStackTest; import agent.frida.model.AbstractModelForFridaScenarioStackTest;
import generic.test.category.NightlyCategory; import generic.test.category.NightlyCategory;
@Ignore("deprecated")
@Category(NightlyCategory.class) // this may actually be an @PortSensitive test @Category(NightlyCategory.class) // this may actually be an @PortSensitive test
public class InVmModelForFridaScenarioStackTest extends AbstractModelForFridaScenarioStackTest { public class InVmModelForFridaScenarioStackTest extends AbstractModelForFridaScenarioStackTest {
@Override @Override

Some files were not shown because too many files have changed in this diff Show More