///|
pub fn PEImage::diff(self : Self, other : Self) -> Array[DiffItem] {
let changes = []
compare_field(
changes,
"format",
format_text(self.format),
format_text(other.format),
)
compare_field(
changes,
"machine",
architecture_name(self.machine),
architecture_name(other.machine),
)
compare_field(
changes,
"subsystem",
subsystem_name(self.subsystem),
subsystem_name(other.subsystem),
)
compare_field(
changes,
"image-base",
self.image_base.to_string(),
other.image_base.to_string(),
)
compare_field(
changes,
"entry-point",
self.entry_point.to_string(),
other.entry_point.to_string(),
)
compare_field(
changes,
"image-size",
self.size_of_image.to_string(),
other.size_of_image.to_string(),
)
compare_field(
changes,
"dll-characteristics",
self.dll_characteristics.to_string(),
other.dll_characteristics.to_string(),
)
compare_field(
changes,
"sections",
sections_signature(self),
sections_signature(other),
)
compare_field(
changes,
"imports",
imports_signature(self),
imports_signature(other),
)
compare_field(
changes,
"exports",
exports_signature(self),
exports_signature(other),
)
compare_field(
changes,
"directories",
directories_signature(self),
directories_signature(other),
)
compare_field(
changes,
"security-diagnostics",
diagnostics_signature(self),
diagnostics_signature(other),
)
changes
}
///|
fn compare_field(
changes : Array[DiffItem],
field : String,
before : String,
after : String,
) -> Unit {
if before != after {
changes.push({ field, before, after, })
}
}
///|
fn sections_signature(image : PEImage) -> String {
let values = []
for section in image.sections {
values.push(
"\{section.name}:\{section.virtual_size}/\{section.raw_size}/\{section.characteristics}",
)
}
values.join(",")
}
///|
fn imports_signature(image : PEImage) -> String {
try {
let values = []
for library in image.imports() {
values.push("\{library.name}(\{library.symbols.length()})")
}
values.join(",")
} catch {
PeError(_, _) => ""
}
}
///|
fn exports_signature(image : PEImage) -> String {
try {
let values = []
for symbol in image.exports() {
values.push(symbol.name)
}
values.join(",")
} catch {
PeError(_, _) => ""
}
}
///|
fn directories_signature(image : PEImage) -> String {
let values = []
for directory in image.directories {
if directory.virtual_address != 0UL && directory.size > 0 {
values.push(directory.name)
}
}
values.join(",")
}
///|
fn diagnostics_signature(image : PEImage) -> String {
let values = []
for diagnostic in image.security_diagnostics() {
values.push(diagnostic.code)
}
values.join(",")
}
///|
fn format_text(format : PEFormat) -> String {
if format is PE32 {
"PE32"
} else {
"PE32+"
}
}