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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
use clap::Parser;
use kerbalobjects::ko::KOFile;
use kerbalobjects::ksm::KSMFile;
use kerbalobjects::BufferIterator;
use std::io::Write;
use std::path::PathBuf;
use std::{error::Error, fs};
use termcolor::{Color, ColorSpec, StandardStream};
mod fio;
use fio::{determine_file_type, FileType};
mod output;
use output::KOFileDebug;
use output::KSMFileDebug;
pub static NO_COLOR: Color = Color::Rgb(255, 255, 255);
pub static VERSION: &str = env!("CARGO_PKG_VERSION");
pub static ORANGE_COLOR: Color = Color::Rgb(201, 155, 87);
pub static PURPLE_COLOR: Color = Color::Rgb(133, 80, 179);
pub static DARK_RED_COLOR: Color = Color::Rgb(201, 87, 87);
pub static LIGHT_RED_COLOR: Color = Color::Rgb(255, 147, 147);
pub static GREEN_COLOR: Color = Color::Rgb(129, 181, 154);
pub fn run(config: &CLIConfig) -> Result<(), Box<dyn Error>> {
let mut stream = StandardStream::stdout(termcolor::ColorChoice::Auto);
let mut no_color = ColorSpec::new();
no_color.set_fg(Some(NO_COLOR));
writeln!(stream, "kDump version {}", VERSION)?;
let raw_contents = fs::read(&config.file_path)?;
let mut raw_contents_iter = BufferIterator::new(&raw_contents);
let file_type = determine_file_type(&raw_contents)?;
match file_type {
FileType::KerbalMachineCode => {
let ksm = KSMFile::parse(&mut raw_contents_iter)?;
let ksm_debug = KSMFileDebug::new(ksm);
ksm_debug.dump(&mut stream, config)?;
Ok(())
}
FileType::KerbalObject => {
let kofile = KOFile::parse(&mut raw_contents_iter)?;
let ko_debug = KOFileDebug::new(kofile);
ko_debug.dump(&mut stream, config)?;
Ok(())
}
FileType::Unknown => Err("File type not recognized.".into()),
}
}
#[derive(Debug, Parser)]
#[command(name = "kDump Utility", author, version, about, long_about = None)]
pub struct CLIConfig {
#[arg(value_name = "FILE", help = "Sets the input file to use")]
pub file_path: PathBuf,
#[arg(
short = 'D',
long,
help = "Disassembles the contents of the entire object file",
conflicts_with("disassemble_symbol"),
conflicts_with("full_contents")
)]
pub disassemble: bool,
#[arg(
short = 'd',
long = "disassemble-symbol",
help = "Disassembles at the symbol provided until the end of the section",
require_equals = true,
value_name = "SYMBOL",
conflicts_with("disassemble"),
conflicts_with("full_contents")
)]
pub disassemble_symbol: Option<String>,
#[arg(
short = 'f',
long = "file-headers",
help = "Displays summary information of the KO file header"
)]
pub file_headers: bool,
#[arg(
short = 'a',
long = "argument-section",
help = "Displays the contents of the argument section of a KSM file"
)]
pub argument_section: bool,
#[arg(
short = 'l',
long = "line-numbers",
help = "Displays the line numbers of disassembled instructions when disassembling"
)]
pub line_numbers: bool,
#[arg(
long = "section-headers",
help = "Displays the section header table of a KO file"
)]
pub section_headers: bool,
#[arg(long = "data", help = "Displays each data section of a KO file")]
pub data: bool,
#[arg(
short = 's',
long = "full-contents",
help = "Displays the contents of every section in the object file"
)]
pub full_contents: bool,
#[arg(
short = 'S',
long = "stabs",
help = "Displays each string table of a KO file"
)]
pub stabs: bool,
#[arg(
short = 't',
long = "syms",
help = "Displays each symbol table of a KO file"
)]
pub syms: bool,
#[arg(
short = 'r',
long = "reloc",
help = "Displays each relocation data table of a KO file"
)]
pub reloc: bool,
#[arg(
short = 'x',
long = "all-headers",
help = "Displays all available KO file header information including the symbol table"
)]
pub all_headers: bool,
#[arg(
short = 'i',
long = "info",
help = "Displays all available meta info of the object file including compiler comments and version information"
)]
pub info: bool,
#[arg(
short = 'C',
long = "demangle",
help = "Tries to demangle disassembled function and variable names"
)]
pub demangle: bool,
#[arg(
long = "show-no-raw-instr",
help = "When disassembling, disables showing the raw bytes that make up each instruction"
)]
pub show_no_raw_instr: bool,
#[arg(
long = "show-no-labels",
help = "When disassembling, disables showing the label of each instruction"
)]
pub show_no_labels: bool,
}