add signatures and checksums
This commit is contained in:
parent
d470881d98
commit
e1f1d01e2c
3 changed files with 125 additions and 27 deletions
|
|
@ -9,8 +9,10 @@ name = "androscalpel"
|
|||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
adler = "1.0.2"
|
||||
androscalpel_serializer = { version = "0.1.0", path = "../androscalpel_serializer" }
|
||||
anyhow = { version = "1.0.75", features = ["backtrace"] }
|
||||
log = "0.4.20"
|
||||
pyo3 = { version = "0.20.0", features = ["anyhow"] }
|
||||
pyo3-log = "0.8.3"
|
||||
sha1 = "0.10.6"
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
//! The structure that generate a .dex from classes.
|
||||
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
use std::io::{Cursor, Write};
|
||||
|
||||
use log::debug;
|
||||
use std::io;
|
||||
use std::io::{Cursor, Seek, SeekFrom, Write};
|
||||
|
||||
use adler::Adler32;
|
||||
use anyhow::{anyhow, bail, Context};
|
||||
use log::debug;
|
||||
use sha1::{Digest, Sha1};
|
||||
|
||||
use crate::Result;
|
||||
use crate::*;
|
||||
|
|
@ -1898,7 +1900,7 @@ impl DexWriter {
|
|||
annotation_off + 1
|
||||
} else {
|
||||
0
|
||||
}, // TODO: link
|
||||
}, // linked in link_annotations()
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -2422,57 +2424,58 @@ impl DexWriter {
|
|||
self.link_annotations();
|
||||
|
||||
debug!("Serialize the dex file");
|
||||
let mut buffer = Cursor::new(Vec::<u8>::new());
|
||||
// TODO: compute checksum, hash, ect
|
||||
self.header.serialize(writer)?;
|
||||
self.header.serialize(&mut buffer)?;
|
||||
// StringIdItem section
|
||||
let mut string_off = self.section_manager.get_offset(Section::StringDataItem);
|
||||
for string in self.string_data_list.iter() {
|
||||
let str_id = StringIdItem {
|
||||
string_data_off: string_off,
|
||||
};
|
||||
str_id.serialize(writer)?;
|
||||
str_id.serialize(&mut buffer)?;
|
||||
string_off += string.size() as u32;
|
||||
}
|
||||
// TypeId section
|
||||
for ty in &self.type_ids_list {
|
||||
ty.serialize(writer)?;
|
||||
ty.serialize(&mut buffer)?;
|
||||
}
|
||||
// ProtoId section
|
||||
for proto in &self.proto_ids_list {
|
||||
proto.serialize(writer)?;
|
||||
proto.serialize(&mut buffer)?;
|
||||
}
|
||||
// FieldIdItem section
|
||||
for field_id in &self.field_ids_list {
|
||||
field_id.serialize(writer)?;
|
||||
field_id.serialize(&mut buffer)?;
|
||||
}
|
||||
// MethodIdItem section
|
||||
for method_id in &self.method_ids_list {
|
||||
method_id.serialize(writer)?;
|
||||
method_id.serialize(&mut buffer)?;
|
||||
}
|
||||
// ClassDefItem section
|
||||
for class_def in &self.class_defs_list {
|
||||
class_def.serialize(writer)?;
|
||||
class_def.serialize(&mut buffer)?;
|
||||
}
|
||||
// CallSiteIdItem, data are inserted as encoded array item later
|
||||
for call_site_id in &self.call_site_ids {
|
||||
call_site_id.serialize(writer)?;
|
||||
call_site_id.serialize(&mut buffer)?;
|
||||
}
|
||||
|
||||
// MethodHandleItem section
|
||||
for handle in &self.method_handles {
|
||||
handle.serialize(writer)?;
|
||||
handle.serialize(&mut buffer)?;
|
||||
}
|
||||
// MapList
|
||||
self.map_list.serialize(writer)?;
|
||||
self.map_list.serialize(&mut buffer)?;
|
||||
// TypeList,
|
||||
let mut offset = 0; // the sections are always aligned until the type_lists
|
||||
for (list, _) in &self.type_lists_with_offset {
|
||||
while offset % 4 != 0 {
|
||||
offset += 1;
|
||||
0u8.serialize(writer)?;
|
||||
0u8.serialize(&mut buffer)?;
|
||||
}
|
||||
offset += list.size();
|
||||
list.serialize(writer)?;
|
||||
list.serialize(&mut buffer)?;
|
||||
}
|
||||
// The next section requires alignment to 4
|
||||
while offset % 4 != 0 {
|
||||
|
|
@ -2482,41 +2485,61 @@ impl DexWriter {
|
|||
}
|
||||
// AnnotationSetRefList section
|
||||
for list in &self.annotation_set_lists {
|
||||
list.serialize(writer)?;
|
||||
list.serialize(&mut buffer)?;
|
||||
}
|
||||
// AnnotationSetItem section
|
||||
for set in &self.annotation_set_items {
|
||||
set.serialize(writer)?;
|
||||
set.serialize(&mut buffer)?;
|
||||
}
|
||||
// ClassDataItem section
|
||||
for data in &self.class_data_list {
|
||||
data.serialize(writer)?;
|
||||
data.serialize(&mut buffer)?;
|
||||
}
|
||||
// CodeItem section
|
||||
for code_item in &self.code_items {
|
||||
code_item.serialize(writer)?
|
||||
code_item.serialize(&mut buffer)?
|
||||
}
|
||||
for string in &self.string_data_list {
|
||||
string.serialize(writer)?;
|
||||
string.serialize(&mut buffer)?;
|
||||
}
|
||||
// DebugInfoItem section
|
||||
for debug_info in &self.debug_info_items {
|
||||
debug_info.serialize(writer)?;
|
||||
debug_info.serialize(&mut buffer)?;
|
||||
}
|
||||
// AnnotationItem section
|
||||
for annot in &self.annotation_items {
|
||||
annot.serialize(writer)?;
|
||||
annot.serialize(&mut buffer)?;
|
||||
}
|
||||
// EncodedArrayItem section
|
||||
for array in &self.encoded_array_items {
|
||||
array.serialize(writer)?;
|
||||
array.serialize(&mut buffer)?;
|
||||
}
|
||||
// AnnotationsDirectoryItem section
|
||||
for dir in &self.annotations_directory_items {
|
||||
dir.serialize(writer)?;
|
||||
dir.serialize(&mut buffer)?;
|
||||
}
|
||||
// TODO: HiddenapiClassDataItem,
|
||||
|
||||
// compute signature
|
||||
buffer.seek(SeekFrom::Start(8 + 4 + 20))?;
|
||||
let mut hasher = Sha1::new();
|
||||
io::copy(&mut buffer, &mut hasher)?;
|
||||
self.header.signature = hasher.finalize().into();
|
||||
buffer.rewind()?;
|
||||
self.header.serialize(&mut buffer)?;
|
||||
|
||||
// Compute checksum
|
||||
//buffer.seek(SeekFrom::Start(8 + 4))?;
|
||||
let mut adler = Adler32::new();
|
||||
adler.write_slice(&buffer.get_ref()[8 + 4..]);
|
||||
self.header.checksum = adler.checksum();
|
||||
buffer.rewind()?;
|
||||
self.header.serialize(&mut buffer)?;
|
||||
|
||||
// copy buffer to output
|
||||
buffer.rewind()?;
|
||||
io::copy(&mut buffer, writer)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue