add signatures and checksums

This commit is contained in:
Jean-Marie Mineau 2024-01-04 14:28:13 +01:00
parent d470881d98
commit e1f1d01e2c
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
3 changed files with 125 additions and 27 deletions

View file

@ -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"

View file

@ -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(())
}