1use yaxpeax_arch::Arch;
47use arch;
48use arch::Symbol;
49
50use std::fmt;
51
52#[derive(Debug, Clone, Serialize, Deserialize)]
53pub enum Summary<A: Arch> {
54 ListBlocks,
55 ListFunctions,
56 ListFunctionBlocks(A::Address),
57 HowMuchCode,
58 ProgramInfo,
59 SymbolInfo(Option<String>, String),
60}
61
62pub struct SummaryHelp;
63
64impl fmt::Display for SummaryHelp {
65 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
66 writeln!(fmt, "list_blocks")?;
67 writeln!(fmt, "list_functions")?;
68 writeln!(fmt, "list_function_blocks:<function_address>")?;
69 writeln!(fmt, "howmuchcode")?;
70 writeln!(fmt, "program_info")?;
71 writeln!(fmt, "symbol_info:<library_name>:<symbol_name>")?;
72
73 Ok(())
74 }
75}
76
77pub struct ListHelp;
78
79impl fmt::Display for ListHelp {
80 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
81 writeln!(fmt, "list_functions")?;
82 writeln!(fmt, "list_function_blocks:<function_address>")?;
83
84 Ok(())
85 }
86}
87
88#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
89pub enum Display<A: Arch> {
90 RenderInstruction(A::Address),
91 RenderBlock(A::Address),
92 RenderRange(A::Address, A::Address),
93 RenderFunction(A::Address),
94 RenderInstructionSSA(A::Address),
95 RenderBlockSSA(A::Address),
96 RenderFunctionSSA(A::Address)
97}
98
99pub struct DisplayHelp;
100
101impl fmt::Display for DisplayHelp {
102 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
103 writeln!(fmt, "render_instruction:<address>")?;
104 writeln!(fmt, "render_block:<address>")?;
105 writeln!(fmt, "render_range:<start_address>:<end_address>")?;
106 writeln!(fmt, "render_function:<address>")?;
107 writeln!(fmt, "render_instruction_ssa:<address>")?;
108 writeln!(fmt, "render_block_ssa:<address>")?;
109 writeln!(fmt, "render_function_ssa:<address>")?;
110
111 Ok(())
112 }
113}
114
115pub enum ParseResult<A: Arch, T> {
116 Operation(Operation<A, T>),
117 Help(&'static dyn fmt::Display),
118 Err(OperationError)
119}
120
121#[derive(Debug, Clone, Serialize, Deserialize)]
122pub enum Operation<A: Arch, T> {
123 Display(Display<A>),
125 Analysis(Analysis<A>),
126 Debug(Debug),
127 Summary(Summary<A>),
128 Data(Data<A>),
129 Specific(T)
130}
131
132pub struct OperationHelp;
133
134impl fmt::Display for OperationHelp {
135 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
136 writeln!(fmt, "display")?;
137 writeln!(fmt, " commands related to displaying data, instructions, functions, etc")?;
138 writeln!(fmt, "analysis")?;
139 writeln!(fmt, " commands to run analyses of code")?;
140 writeln!(fmt, "debug")?;
141 writeln!(fmt, " commands for debugging (attaching to a process, breakpoints, execution, ...")?;
142 writeln!(fmt, "summary")?;
143 writeln!(fmt, " commands for summarizing information about the program in question, data that is known, ...")?;
144 writeln!(fmt, "data")?;
145 writeln!(fmt, " commands for directly modifying low level data that is tracked - adding function hints, adding contextual overrides of instruction semantics, data overrides, etc")?;
146 writeln!(fmt, "specific")?;
147 writeln!(fmt, " architecture-specific commands (none of these yet!)")?;
148
149 Ok(())
150 }
151}
152
153#[derive(Debug, Clone, Serialize, Deserialize)]
154pub enum Data<A: Arch> {
155 AddFunctionHint(A::Address),
156 DefineSymbol(A::Address, Symbol),
157 CodeComment(A::Address, String),
158}
159
160pub struct DataHelp;
161
162impl fmt::Display for DataHelp {
163 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
164 writeln!(fmt, "add_function_hint:<address>")?;
165 writeln!(fmt, "define_symbol:<address>:<symbol name>")?;
166 writeln!(fmt, "code_comment:<address>:<comment>")?;
167
168 Ok(())
169 }
170}
171
172#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
173pub enum Debug {
174 ShowMaps,
175 ShowModules,
176 ShowThreads,
177 ShowInfo,
178 Step,
179}
180
181pub struct DebugHelp;
182
183impl fmt::Display for DebugHelp {
184 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
185 writeln!(fmt, "show_maps")?;
186 writeln!(fmt, "show_modules")?;
187 writeln!(fmt, "show_threads")?;
188 writeln!(fmt, "show_info")?;
189
190 Ok(())
191 }
192}
193
194#[derive(Debug, Clone, Serialize, Deserialize)]
195pub enum Analysis<A: Arch> {
196 ComputeSSAForm(A::Address),
197 ControlFlowLinear(A::Address, A::Address),
198 ControlFlowIncremental(Vec<A::Address>),
199 DoEverything
200}
201
202pub struct AnalysisHelp;
203
204impl fmt::Display for AnalysisHelp {
205 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
206 writeln!(fmt, "compute_ssa_form:<at_address>")?;
207 writeln!(fmt, "control_flow_linear:<start_address>:<end_address>")?;
208 writeln!(fmt, " computes control flow between `start` and `end`")?;
209 writeln!(fmt, " this is not what you want if a linear decode is invalid (might decode incorrect instructions, for example)")?;
210 writeln!(fmt, "control_flow_incremental:<start_address>")?;
211 writeln!(fmt, " recursively builds control flow information from `start_address`, with no runtime/memory/size bounds")?;
212 writeln!(fmt, "compute_ssa_form:<address>")?;
213 writeln!(fmt, " computes SSA numbering for the control flow graph started at `address`.")?;
214 writeln!(fmt, "do_everything")?;
215 writeln!(fmt, " recursively finds control flow from hinted start points, then computes SSA form for reached code")?;
216
217 Ok(())
218 }
219}
220
221#[derive(Debug, Serialize, Deserialize)]
222pub enum OperationSuccess {
223 Ok,
224 OkWithOutput(Vec<(usize, Vec<String>)>),
225 SwitchArch(arch::ISA)
226}
227
228#[derive(Debug, Serialize, Deserialize)]
229pub enum ParseError {
230 Address(String),
231 Symbol(String),
232 Command(String),
233}
234
235impl std::fmt::Display for ParseError {
236 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
237 match self {
238 ParseError::Address(addr) => {
239 write!(fmt, "Invalid address: \"{}\"", addr)
240 },
241 ParseError::Symbol(sym) => {
242 write!(fmt, "Invalid symbol: \"{}\"", sym)
243 },
244 ParseError::Command(cmd) => {
245 write!(fmt, "Invalid command: \"{}\"", cmd)
246 },
247 }
248 }
249}
250
251#[derive(Debug, Serialize, Deserialize)]
252pub enum OperationError {
253 ParseError(ParseError),
254 Invalid(String),
255 Unknown(String),
256 Unsupported(String),
257 Misc(String)
258}
259
260pub trait Operate<T, A: Arch> {
261fn evaluate(&mut self, operation: Operation<A, T>) -> Result<OperationSuccess, OperationError>;
264}