mirror of
https://github.com/Momoko-Ayase/Senbei.git
synced 2026-09-19 03:57:59 -04:00
build: require Rust 1.98.1
This commit is contained in:
@@ -177,18 +177,14 @@ fn decrypt_header(raw: &[u8], constant: u32) -> Result<Stage1Header> {
|
||||
}
|
||||
|
||||
fn decrypt_words(ciphertext: &[u8], key: u32, constant: u32) -> Result<Vec<u8>> {
|
||||
if ciphertext.len() % 4 != 0 {
|
||||
if !ciphertext.len().is_multiple_of(4) {
|
||||
return invalid("Stage 1 word cipher input is not 4-byte aligned");
|
||||
}
|
||||
let mut plaintext = ciphertext.to_vec();
|
||||
for (index, chunk) in plaintext.chunks_exact_mut(4).enumerate() {
|
||||
for (index, chunk) in plaintext.as_chunks_mut::<4>().0.iter_mut().enumerate() {
|
||||
let index = u32::try_from(index)
|
||||
.map_err(|_| Error::Invalid("Stage 1 word index exceeds u32".to_owned()))?;
|
||||
let mut word = u32::from_le_bytes(
|
||||
chunk
|
||||
.try_into()
|
||||
.map_err(|_| Error::Invalid("Stage 1 word has an invalid size".to_owned()))?,
|
||||
);
|
||||
let mut word = u32::from_le_bytes(*chunk);
|
||||
word = word.wrapping_add(index.wrapping_add(3).wrapping_mul(key));
|
||||
word ^= constant.wrapping_mul(index.wrapping_add(1));
|
||||
chunk.copy_from_slice(&word.to_le_bytes());
|
||||
|
||||
@@ -130,13 +130,9 @@ fn decrypt_record(raw: &[u8], index: usize, state: u32) -> Result<Record> {
|
||||
let mut accumulator = 0x7993_4cf6_u32;
|
||||
let mut feedback = 0xf02f_7685_u32;
|
||||
let mut words = [0_u32; RECORD_SIZE / 4];
|
||||
for (word_index, chunk) in raw.chunks_exact(4).enumerate() {
|
||||
for (word_index, chunk) in raw.as_chunks::<4>().0.iter().enumerate() {
|
||||
feedback = feedback.wrapping_mul(feedback);
|
||||
let cipher = u32::from_le_bytes(
|
||||
chunk
|
||||
.try_into()
|
||||
.map_err(|_| Error::Invalid("record word has an invalid size".to_owned()))?,
|
||||
);
|
||||
let cipher = u32::from_le_bytes(*chunk);
|
||||
let mut value = gf32_mul_fixed(cipher ^ (feedback >> 3)) ^ index_mask;
|
||||
value = value.wrapping_add(accumulator).wrapping_add(state);
|
||||
value = value.wrapping_sub(mix >> ((word_index * 4 + 3) & 5));
|
||||
|
||||
@@ -477,7 +477,8 @@ fn restore_hidden_symbols(
|
||||
dynstr: SectionHeader,
|
||||
patch_data: &[u8],
|
||||
) -> Result<(Vec<u8>, Vec<u8>, HiddenSymbolReport)> {
|
||||
if dynsym.entry_size != ELF64_SYMBOL_SIZE as u64 || dynsym.size % ELF64_SYMBOL_SIZE as u64 != 0
|
||||
if dynsym.entry_size != ELF64_SYMBOL_SIZE as u64
|
||||
|| !dynsym.size.is_multiple_of(ELF64_SYMBOL_SIZE as u64)
|
||||
{
|
||||
return invalid("unexpected .dynsym entry layout");
|
||||
}
|
||||
@@ -584,11 +585,13 @@ fn restore_hidden_symbols(
|
||||
}
|
||||
|
||||
fn dynamic_symbol_names(symbols: &[u8], strings: &[u8]) -> Result<Vec<Vec<u8>>> {
|
||||
if symbols.len() % ELF64_SYMBOL_SIZE != 0 {
|
||||
if !symbols.len().is_multiple_of(ELF64_SYMBOL_SIZE) {
|
||||
return invalid("dynamic symbol table is not entry-aligned");
|
||||
}
|
||||
symbols
|
||||
.chunks_exact(ELF64_SYMBOL_SIZE)
|
||||
.as_chunks::<ELF64_SYMBOL_SIZE>()
|
||||
.0
|
||||
.iter()
|
||||
.map(|symbol| {
|
||||
let name_offset = read_u32(symbol, 0)? as usize;
|
||||
Ok(read_c_string(strings, name_offset, strings.len())?.to_vec())
|
||||
@@ -698,7 +701,7 @@ fn patch_dynamic_tags(
|
||||
dynamic: SectionHeader,
|
||||
values: &BTreeMap<u64, u64>,
|
||||
) -> Result<()> {
|
||||
if dynamic.size % 0x10 != 0 {
|
||||
if !dynamic.size.is_multiple_of(0x10) {
|
||||
return invalid(".dynamic size is not entry-aligned");
|
||||
}
|
||||
let start = usize_from_u64(dynamic.offset, ".dynamic offset")?;
|
||||
@@ -732,7 +735,7 @@ fn patch_dynamic_tags(
|
||||
}
|
||||
|
||||
fn dynamic_contains_tag(output: &[u8], dynamic: SectionHeader, wanted: u64) -> Result<bool> {
|
||||
if dynamic.size % 0x10 != 0 {
|
||||
if !dynamic.size.is_multiple_of(0x10) {
|
||||
return invalid(".dynamic size is not entry-aligned");
|
||||
}
|
||||
let start = usize_from_u64(dynamic.offset, ".dynamic offset")?;
|
||||
@@ -1418,13 +1421,12 @@ fn validate_restored_binary(
|
||||
rela_plt.size / ELF64_RELA_SIZE as u64,
|
||||
"restored PLT relocation count",
|
||||
)?;
|
||||
if let Some(expected) = materialization {
|
||||
if dynamic_symbols != expected.new_symbol_count
|
||||
if let Some(expected) = materialization
|
||||
&& (dynamic_symbols != expected.new_symbol_count
|
||||
|| dynamic_relocations != expected.rela_dyn_count
|
||||
|| pltgot_relocations != expected.rela_plt_count
|
||||
{
|
||||
return invalid("restored ELF table counts do not match materialization report");
|
||||
}
|
||||
|| pltgot_relocations != expected.rela_plt_count)
|
||||
{
|
||||
return invalid("restored ELF table counts do not match materialization report");
|
||||
}
|
||||
Ok(ValidationReport {
|
||||
format: "ELF64".to_owned(),
|
||||
|
||||
@@ -396,7 +396,7 @@ impl<'a> Unpacker<'a> {
|
||||
// non-critical for false-positive rejection.
|
||||
if v8 < info6 {
|
||||
let delta = info6.wrapping_sub(v8);
|
||||
if delta <= 0x1000 && delta % 0x200 == 0 {
|
||||
if delta <= 0x1000 && delta.is_multiple_of(0x200) {
|
||||
anchor = Some(probe);
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user