-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdisassembler.py
More file actions
81 lines (71 loc) · 4.16 KB
/
Copy pathdisassembler.py
File metadata and controls
81 lines (71 loc) · 4.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
"""
# CCS Disassembler
# For Raytheon Research Project and Interdisciplinary Capstone Project
# Dr. Clem Izurieta
# Dr. Brock LaMeres
# Written by Walker Ward and Michael Heidal
"""
import os
import pathlib
import platform
import subprocess
from ccs_project import CCSProject
from pique_bin import PiqueBin
from static_utilities import StaticUtilities
class Disassembler:
"""
Disassembles an MSP430 binary.
"""
def __init__(self, ccs_project_to_disassemble: CCSProject, *,
disassembler_output_file_name: str = "generated_disassembly.txt") -> None:
self.ccs_project: CCSProject = ccs_project_to_disassemble
self.disassembler_directory: pathlib.Path = StaticUtilities.project_root_directory() / 'tools'
self.disassembler_executable: str = 'dis430.exe'
self.disassembler_output_file_name: str = disassembler_output_file_name
self.disassembler_output_file_directory: pathlib.Path = StaticUtilities.project_root_directory() / "generated_disassembly"
self.disassembler_exit_status: int = 0
StaticUtilities.logger.debug(f"{Disassembler.__name__} object initialized")
def disassemble(self) -> None:
"""
Generates disassembly for a binary generated by the MSP430 in CCS.
- Checks that the input file exists.
- Checks if the output file already exists. If so removes it.
- Runs dis430.exe on the input file and output file.
- Checks the exit status of the dis430.exe.
- Note: Extremely dependent on package structure.
:raise: OSError if the input file does not exist.
:raise: OSError if the disassembler failed.
"""
# Check if the disassembler input exists.
StaticUtilities.file_should_exist(self.ccs_project.path, self.ccs_project.source_file)
# Check if the output file already exists. If it exists delete in.
disassembler_output_path: pathlib.Path = self.disassembler_output_file_directory / self.disassembler_output_file_name
if os.path.exists(disassembler_output_path):
os.remove(disassembler_output_path)
StaticUtilities.logger.debug(
rf"Removed {disassembler_output_path}")
disassembler_binary_path: pathlib.Path = self.disassembler_directory / self.disassembler_executable
binary_file_path: pathlib.Path = self.ccs_project.path / self.ccs_project.binary_file_path
if platform.system() == "Linux":
self.disassembler_exit_status = subprocess.Popen(
["wine64", disassembler_binary_path, binary_file_path, disassembler_output_path], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
else:
self.disassembler_exit_status = subprocess.Popen([disassembler_binary_path, binary_file_path, disassembler_output_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, error = self.disassembler_exit_status.communicate()
StaticUtilities.logger.debug(f"Disassembler exit status: {self.disassembler_exit_status.returncode}")
if self.disassembler_exit_status.returncode != 0:
if platform.system() != "Windows":
StaticUtilities.logger.warning("You are not on Windows. You may need to install wine64 to run /tools/dis430.exe as it is a Windows binary")
StaticUtilities.logger.error(f"Failed to generate disassembly for {self.ccs_project.binary_file_path} with exit status {self.disassembler_exit_status.returncode};\noutput: {output};\nerror: {error}")
exit(1)
else:
StaticUtilities.logger.debug(
f'Generated {self.disassembler_output_file_name} at the directory {self.disassembler_output_file_directory}')
self.ccs_project.set_disassembly_file_path(
self.disassembler_output_file_directory / self.disassembler_output_file_name)
if __name__ == '__main__':
ccs_project: CCSProject = CCSProject(project_name="test_target", source_file="main.c",
path=StaticUtilities.project_root_directory() / "ccs_workspace" / "test_target")
disassembler: Disassembler = Disassembler(ccs_project_to_disassemble=ccs_project)
disassembler.disassemble()