diff --git a/androscalpel/src/apk.rs b/androscalpel/src/apk.rs index e4662f5..64e0286 100644 --- a/androscalpel/src/apk.rs +++ b/androscalpel/src/apk.rs @@ -2750,7 +2750,9 @@ impl Apk { if let Some(try_) = tries.remove(&addr) { insns.push(try_); } - if let Some(label_l) = labels.remove(&addr) { + if let Some(mut label_l) = labels.remove(&addr) { + label_l.sort(); + label_l.dedup(); for label in label_l.into_iter() { insns.push(Instruction::Label { name: label }); } diff --git a/androscalpel/src/code_analysis/method_cfg.rs b/androscalpel/src/code_analysis/method_cfg.rs index 1b4333d..0b5729c 100644 --- a/androscalpel/src/code_analysis/method_cfg.rs +++ b/androscalpel/src/code_analysis/method_cfg.rs @@ -271,8 +271,10 @@ impl<'a> MethodCFG<'a> { format!("block {i}") }; let label = if node.code_block.is_empty() { - format!("{{\\< {block_name} \\>}}") + //format!("{{\\< {block_name} \\>}}") + format!("
{block_name}
") } else { + /* let mut label = format!("{{\\< {block_name} \\>:\\l\\\n"); for (i, ins) in node.code_block.iter().enumerate() { label += &format!("|"); @@ -284,17 +286,38 @@ impl<'a> MethodCFG<'a> { .replace("\"", "\\\"") .replace("{", "\\{") .replace("}", "\\}") + //.replace("[", "\\[") .as_str(); label += "\\l\\\n"; } label += "}"; + */ + let mut label = format!("\n \n"); + for (i, ins) in node.code_block.iter().enumerate() { + label += &format!( + " \n", + ins.__str__() + //.replace(" ", "\\ ") + .replace("&", "&") + .replace(">", ">") + .replace("<", "<") + .replace("\"", """) + //.replace("{", "\\{") + //.replace("}", "\\}") + //.replace("[", "\\[") + .as_str() + ); + } + label += "
{block_name}
{}
"; label }; dot_string += &format!( - " node_{i} [shape=record,style=filled,fillcolor=lightgrey,label=\"{label}\"];\n\n" + //" node_{i} [shape=record,style=filled,fillcolor=lightgrey,label=\"{label}\"];\n\n" + " node_{i} [shape=plaintext,style=filled,fillcolor=lightgrey,label=<{label}>];\n\n" ); } - dot_string += " node_end [shape=record,style=filled,fillcolor=lightgrey,label=\"{\\< EXIT \\>}\"];\n\n"; + //dot_string += " node_end [shape=record,style=filled,fillcolor=lightgrey,label=\"{\\< EXIT \\>}\"];\n\n"; + dot_string += " node_end [shape=plaintext,style=filled,fillcolor=lightgrey,label=<
EXIT
>];\n\n"; for (i, node) in self.nodes.iter().enumerate() { for j in &node.next_nodes { diff --git a/androscalpel/src/code_analysis/register_type.rs b/androscalpel/src/code_analysis/register_type.rs index 582c486..b459e90 100644 --- a/androscalpel/src/code_analysis/register_type.rs +++ b/androscalpel/src/code_analysis/register_type.rs @@ -112,20 +112,40 @@ impl MethodCFG<'_> { dot_string += " color=\"black\";\n"; dot_string += " rankdir=\"TB\";\n"; dot_string += &format!( - " label=\"Register Types{}\";\n", + " label=\"Register Types for {}\";\n", self.method.descriptor.__str__() ); - for (label, regs) in &types { + let mut labels: Vec<_> = types.keys().collect(); + labels.sort(); // Order more or less by addresses, good enought + let mut prev = None; + for label in labels.into_iter() { + let regs = types.get(label).unwrap(); let mut node_label = String::new(); - for reg in regs { - node_label += "|"; - node_label += reg.to_str(); - } - node_label += "|"; - dot_string += &format!( - " node_{label} [shape=record,style=filled,fillcolor=lightgrey,label=\"{node_label}\"];\n" + node_label += "\n"; + node_label += &format!( + " \n ", regs.len(), ); + for i in 0..regs.len() { + node_label += &format!(" \n"); + } + node_label += " \n"; + for reg in regs { + //node_label += "|"; + //node_label += reg.to_str(); + node_label += &format!(" \n", reg.to_str()); + } + //node_label += "|"; + node_label += "
register types at {label}
{i}
{}
"; + dot_string += &format!( + //" node_{label} [shape=record,style=filled,fillcolor=lightgrey,label=\"{node_label}\"];\n" + " node_{label} [shape=plaintext,style=filled,fillcolor=lightgrey,label=<{node_label}>];\n" + ); + if let Some(prev) = prev { + // Add invisible edge to ensure the nodes are verticals + dot_string += &format!(" {prev}:s -> node_{label}:n [style=\"invis\"];\n"); + } + prev = Some(format!("node_{label}")); } dot_string += "}\n"; @@ -135,7 +155,7 @@ impl MethodCFG<'_> { if let Instruction::Label { name } = ins { let mid = self.dot_sanitized_method_dscr(); dot_string += &format!( - " node_{i}:i{j}:e -> node_{name}:w \ + " node_{i}:i{j}:e -> node_{name} \ [ltail=cluster_{mid},lhead=cluster_reg_types_{mid},style=\"solid,bold\",color=grey,weight=10,constraint=true];\n", ); }