ghidra_analyzer.py
ofrak_ghidra.components.ghidra_analyzer
GhidraCodeRegionModifier (Modifier, OfrakGhidraMixin)
modify(self, resource, config=None)
async
Modify the given resource.
Users should not call this method directly; rather, they should run Resource.run.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
resource |
Resource |
required | |
config |
Optional config for modification. If an implementation provides a default, this default will always be used when config would otherwise be None. Note that a copy of the default config will be passed, so the default config values cannot be modified persistently by a component run. |
None |
Source code in ofrak_ghidra/components/ghidra_analyzer.py
async def modify(self, resource: Resource, config=None):
code_region = await resource.view_as(CodeRegion)
ghidra_project = await OfrakGhidraMixin.get_ghidra_project(resource)
ofrak_code_regions = await ghidra_project.resource.get_descendants_as_view(
v_type=CodeRegion, r_filter=ResourceFilter(tags=[CodeRegion])
)
backend_code_regions_json = await self.get_code_regions_script.call_script(resource)
backend_code_regions = []
for cr_j in backend_code_regions_json:
cr = CodeRegion(cr_j["start"], cr_j["size"])
backend_code_regions.append(cr)
ofrak_code_regions = sorted(ofrak_code_regions, key=lambda cr: cr.virtual_address)
backend_code_regions = sorted(backend_code_regions, key=lambda cr: cr.virtual_address)
if len(ofrak_code_regions) > 0:
relative_va = code_region.virtual_address - ofrak_code_regions[0].virtual_address
for backend_cr in backend_code_regions:
backend_relative_va = (
backend_cr.virtual_address - backend_code_regions[0].virtual_address
)
if backend_relative_va == relative_va and backend_cr.size == code_region.size:
resource.add_view(backend_cr)
return
LOGGER.debug(
f"No code region with relative offset {relative_va} and size {code_region.size} found in Ghidra"
)
else:
LOGGER.debug("No OFRAK code regions to match in Ghidra")
GhidraCustomLoadAnalyzer (GhidraProjectAnalyzer)
analyze(self, resource, config=None)
async
Analyze a resource for to extract specific ResourceAttributes.
Users should not call this method directly; rather, they should run Resource.run or Resource.analyze.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
resource |
Resource |
The resource that is being analyzed |
required |
config |
Optional[ofrak_ghidra.components.ghidra_analyzer.GhidraProjectConfig] |
Optional config for analyzing. If an implementation provides a default, this default will always be used when config would otherwise be None. Note that a copy of the default config will be passed, so the default config values cannot be modified persistently by a component run. |
None |
Returns:
Type | Description |
---|---|
GhidraProject |
The analysis results |
Source code in ofrak_ghidra/components/ghidra_analyzer.py
async def analyze(
self, resource: Resource, config: Optional[GhidraProjectConfig] = None
) -> GhidraProject:
arch_info: ArchInfo = await resource.analyze(ProgramAttributes)
mem_blocks = await self._get_memory_blocks(await resource.view_as(Program))
use_existing = config.use_existing if config is not None else False
async with self._prepare_ghidra_project(resource) as (ghidra_project, full_fname):
program_name = await self._do_ghidra_import(
ghidra_project,
full_fname,
use_existing=use_existing,
use_binary_loader=True,
processor=arch_info,
blocks=mem_blocks,
)
await self._do_ghidra_analyze_and_serve(
ghidra_project,
program_name,
skip_analysis=config is not None,
)
return GhidraProject(
ghidra_project, f"http://{GHIDRA_SERVER_HOST}:{GHIDRA_SERVER_PORT}"
)
GhidraProgramLoadConfig (ComponentConfig)
dataclass
Config for GhidraProjectAnalyzer to pass in a pre-analyzed Ghidra project for a binary as a Ghidra Zip file.
A Ghidra Zip File can be exported from Ghidra's project window, right-clicking on an analyzed file and "Export...". Then select the Ghidra Zip File format and save the file. This will create a .gzf file that you can import with this GhidraProjectConfig.
GhidraProjectAnalyzer (Analyzer)
Use Ghidra backend to create project for and analyze a binary. This analyzer must run before Ghidra analysis can be accessed from OFRAK. This Analyzer can either create a new project and new analysis for a binary or, if a config is passed to it, load an existing Ghidra project.
analyze(self, resource, config=None)
async
Analyze a resource for to extract specific ResourceAttributes.
Users should not call this method directly; rather, they should run Resource.run or Resource.analyze.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
resource |
Resource |
The resource that is being analyzed |
required |
config |
Optional[ofrak_ghidra.components.ghidra_analyzer.GhidraProjectConfig] |
Optional config for analyzing. If an implementation provides a default, this default will always be used when config would otherwise be None. Note that a copy of the default config will be passed, so the default config values cannot be modified persistently by a component run. |
None |
Returns:
Type | Description |
---|---|
GhidraProject |
The analysis results |
Source code in ofrak_ghidra/components/ghidra_analyzer.py
async def analyze(
self, resource: Resource, config: Optional[GhidraProjectConfig] = None
) -> GhidraProject:
gzf = config.ghidra_zip_file if config is not None else None
binary_fname = config.name if config is not None else None
# if passing a name for the file, by default don't overwrite an existing file
# of the same name in the ghidra project.
use_existing = config.use_existing if config is not None else binary_fname is not None
async with self._prepare_ghidra_project(resource, gzf, binary_fname) as (
ghidra_project,
full_fname,
):
program_name = await self._do_ghidra_import(
ghidra_project, full_fname, use_existing=use_existing, use_binary_loader=False
)
await self._do_ghidra_analyze_and_serve(
ghidra_project,
program_name,
skip_analysis=config is not None,
)
return GhidraProject(
ghidra_project, f"http://{GHIDRA_SERVER_HOST}:{GHIDRA_SERVER_PORT}"
)
GhidraProjectConfig (ComponentConfig)
dataclass
Config for GhidraProjectAnalyzer to pass in a pre-analyzed Ghidra project for a binary as a Ghidra Zip file.
A Ghidra Zip File can be exported from Ghidra's project window, right-clicking on an analyzed file and "Export...". Then select the Ghidra Zip File format and save the file. This will create a .gzf file that you can import with this GhidraProjectConfig.