generate HTML page to show dex layout
This commit is contained in:
parent
d991ac4dcd
commit
4eae524e5f
3 changed files with 125 additions and 9 deletions
|
|
@ -23,18 +23,14 @@ fn main() {
|
||||||
&cli.dex.into_os_string().into_string().unwrap(),
|
&cli.dex.into_os_string().into_string().unwrap(),
|
||||||
&data,
|
&data,
|
||||||
|_, _, _| None,
|
|_, _, _| None,
|
||||||
false,
|
true,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
//load_apk(File::open(&cli.apk).unwrap(), |_, _, _| None, false).unwrap();
|
//load_apk(File::open(&cli.apk).unwrap(), |_, _, _| None, false).unwrap();
|
||||||
for (name, dex) in &apk.dex_files {
|
for (_name, dex) in &apk.dex_files {
|
||||||
println!("{name}:");
|
//println!("{name}:");
|
||||||
|
|
||||||
#[cfg(feature = "map_dex_file")]
|
#[cfg(feature = "map_dex_file")]
|
||||||
for (off, size, dscr) in dex.layout_map.iter() {
|
println!("{}", dex.html_layout())
|
||||||
let end = off + *size as u32;
|
|
||||||
let mut dscr = dscr.clone();
|
|
||||||
dscr.truncate(100);
|
|
||||||
println!("0x{off:x} -> 0x{end:x}: {dscr}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ pub mod visitor;
|
||||||
|
|
||||||
#[cfg(feature = "code-analysis")]
|
#[cfg(feature = "code-analysis")]
|
||||||
pub mod code_analysis;
|
pub mod code_analysis;
|
||||||
|
#[cfg(feature = "map_dex_file")]
|
||||||
|
pub mod map_dex_file;
|
||||||
|
|
||||||
pub use annotation::*;
|
pub use annotation::*;
|
||||||
pub use apk::*;
|
pub use apk::*;
|
||||||
|
|
|
||||||
118
androscalpel/src/map_dex_file.rs
Normal file
118
androscalpel/src/map_dex_file.rs
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
use crate::DexFile;
|
||||||
|
|
||||||
|
static STYLE: &'static str = "
|
||||||
|
.hex_table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border: 1px solid grey;
|
||||||
|
|
||||||
|
font-family: monospace;
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
.hex_offset {
|
||||||
|
background: #A2A2A2;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
.hex_space {
|
||||||
|
//padding-right: 1em;
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
.dex_dscr {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.dex_dscr_container {
|
||||||
|
position: fixed;
|
||||||
|
display: block;
|
||||||
|
left: 25em;
|
||||||
|
top: 0px;
|
||||||
|
}
|
||||||
|
";
|
||||||
|
|
||||||
|
impl DexFile {
|
||||||
|
pub fn html_layout(&self) -> String {
|
||||||
|
assert!(
|
||||||
|
self.bin_cache.is_some(),
|
||||||
|
"cache must not be none to display layout"
|
||||||
|
);
|
||||||
|
let mut lines = vec![];
|
||||||
|
let mut current_line = vec![];
|
||||||
|
let raw = self.bin_cache.as_ref().unwrap();
|
||||||
|
let mut current_chunk = 0;
|
||||||
|
for i in 0..(raw.len() as u32) {
|
||||||
|
// We assumes that chunks are sorted by offset and non overlapping
|
||||||
|
while !((self.layout_map[current_chunk].0 <= i)
|
||||||
|
&& (i < self.layout_map[current_chunk].0 + self.layout_map[current_chunk].1 as u32))
|
||||||
|
&& self.layout_map[current_chunk].0 <= i
|
||||||
|
{
|
||||||
|
current_chunk += 1;
|
||||||
|
}
|
||||||
|
let in_chunk = (self.layout_map[current_chunk].0 <= i)
|
||||||
|
&& (i < self.layout_map[current_chunk].0 + self.layout_map[current_chunk].1 as u32);
|
||||||
|
if i % 16 == 0 {
|
||||||
|
current_line.push(format!("<td class=\"hex_offset\">{i:08x}</td>"));
|
||||||
|
current_line.push("<td class=\"hex_space\"></td>".to_string());
|
||||||
|
}
|
||||||
|
if i % 16 == 8 {
|
||||||
|
current_line.push("<td class=\"hex_space\"></td>".to_string());
|
||||||
|
}
|
||||||
|
let mut classes = vec!["hex_cel".to_string()];
|
||||||
|
if in_chunk {
|
||||||
|
classes.push(format!(
|
||||||
|
"chunk_{}_{}",
|
||||||
|
self.layout_map[current_chunk].0, self.layout_map[current_chunk].1
|
||||||
|
));
|
||||||
|
}
|
||||||
|
current_line.push(format!(
|
||||||
|
"<td class=\"{}\">{:02x}</td>",
|
||||||
|
classes.join(" "),
|
||||||
|
raw[i as usize]
|
||||||
|
));
|
||||||
|
if (i % 16 == 15) || (i == raw.len() as u32 - 1) {
|
||||||
|
let cells = current_line.join("\n ");
|
||||||
|
current_line = vec![];
|
||||||
|
lines.push(format!(
|
||||||
|
" <tr>
|
||||||
|
{cells}
|
||||||
|
</tr>
|
||||||
|
"
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let table = lines.join("\n");
|
||||||
|
let mut chunk_style_lines = vec![];
|
||||||
|
let mut data_lines = vec![];
|
||||||
|
for (off, size, dscr) in &self.layout_map {
|
||||||
|
let classname = format!("chunk_{off}_{size}");
|
||||||
|
chunk_style_lines.push(format!(
|
||||||
|
"html:has(.{classname}:hover) .{classname} {{ background-color: yellow; }}"
|
||||||
|
));
|
||||||
|
chunk_style_lines.push(format!(
|
||||||
|
"html:has(.{classname}:hover) .dscr_{classname} {{ display: block; }}"
|
||||||
|
));
|
||||||
|
data_lines.push(format!(
|
||||||
|
"<pre class=\"dex_dscr dscr_{classname}\"><code>{dscr}</code></pre>"
|
||||||
|
))
|
||||||
|
}
|
||||||
|
let chunk_style = chunk_style_lines.join("\n ");
|
||||||
|
let data = data_lines.join("\n ");
|
||||||
|
|
||||||
|
format!(
|
||||||
|
"<html>
|
||||||
|
<head>
|
||||||
|
<title>DEX layout</title>
|
||||||
|
<style>
|
||||||
|
{STYLE}
|
||||||
|
{chunk_style}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<table class=\"hex_table\">
|
||||||
|
{table}
|
||||||
|
</table>
|
||||||
|
<div class=\"dex_dscr_container\">
|
||||||
|
{data}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue