在我将近一年前的上一个问题将我引导到 YAA 格式以了解可以解压缩的块之后,这次我们正在处理的块pbzx
告诉我们我们正在处理非 xz 块。
我已经尝试在 Rust 中慢慢重写Jonathan Levin 的第一个 pbzx 提取器,到目前为止我编写的代码只是读出文件的标志和每个块的标志、长度和签名(大部分应该是 XZ 标头魔法)。
use std::io::{self, BufReader, Read, Seek, SeekFrom};
use std::fs::File;
use std::path::Path;
use binread::{BinRead, BinReaderExt};
#[derive(Debug, BinRead)]
pub struct block {
flg: u64,
len: i64,
sig: u64
}
#[derive(Debug, BinRead)]
#[br(magic = b"pbzx")]
pub struct pbzx {
flag0: u64,
chunk: block
}
fn main() -> io::Result<()> {
// Read file
let file = File::open("payload.008")?;
let mut reader = BufReader::new(file);
// Apply it
let header: pbzx = reader.read_be().unwrap();
println!(" {:#04x}", header.flag0);
// Zeroth block
println!(" {:#04x}, {}, {:#04x}", header.chunk.flg, header.chunk.len, header.chunk.sig);
reader.seek(SeekFrom::Current(header.chunk.len-8)).expect("Could not get current position!");
// All the other blocks
while (true) { //
// I should actually be using "chunk.flg & ((1 << 24) | (1 << 23)) != 0" but I don't know
// where that's come from
// How does someone exactly calculate these bitshifts?
//
let chunk: block = reader.read_be().unwrap();
println!(" {:#04x}, {}, {:#04x}", chunk.flg, chunk.len, chunk.sig);
reader.seek(SeekFrom::Current(chunk.len-8)).expect("Could not get current position!");
}
Ok(())
}
运行它使它按预期运行,向我们显示大部分块是 XZ,但其他一些块,特别是在开始时,显示似乎没有多大意义的非重复值。
kitty@kitty ~/Projects/pbzx
> $ ./target/debug/pbzx
0x800000
0x800000, 8386152, 0xfd377a585a000000
0x800000, 8388608, 0xf5278dda2c95573c
0x800000, 8387764, 0xfd377a585a000000
0x800000, 8388608, 0x7ec3ca75b21ecca8
0x800000, 8377552, 0xfd377a585a000000
0x800000, 8387576, 0xfd377a585a000000
0x800000, 8388608, 0x2cb02061c42ec23b
0x800000, 8388608, 0x94f8a22d86b5b145
0x800000, 8388608, 0x7cf626aff7e56be6
0x800000, 8388608, 0xd053c8e78ee64674
0x800000, 8388608, 0xafac0d53e933e247
0x800000, 8388608, 0xcc6c78f45ab958a5
0x800000, 5815664, 0xfd377a585a000000
0x800000, 3505580, 0xfd377a585a000000
_____________repeating_______________
0x800000, 4876720, 0xfd377a585a000000
0x800000, 4761144, 0xfd377a585a000000
0x800000, 4905372, 0xfd377a585a000000
_____________repeating_______________
0x51e0b5, 4568784, 0xfd377a585a000000
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Io(Custom { kind: UnexpectedEof, error: "Out of bytes in reader" })', src/main.rs:35:45
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
在 Hex Fiend 中搜索它们,确认它们是非重复的,与有效块相邻(参见YZ
结束签名)并且不匹配任何已知签名。我尝试在字节序之间进行转换,但一无所获,以防万一。
我可以随便说他们是加密的,但这引出了一个问题,但这引出了一个问题,我如何在探索该路径之前确认它已加密?
Pudquick 的版本,使用新标志修改,继续将其视为解压缩的 cpio 块,但给了我一些有效块和一些包含未知或没有数据的块,Levin 的更新版本,我大约一年前使用的,完全跳过了这些块
-rw-r--r-- 1 kitty staff 388745580 May 12 19:10 payload.008
-rw-r--r-- 1 kitty staff 8386152 Jun 21 02:30 payload.008.part00.cpio.xz
-rw-r--r-- 1 kitty staff 8388608 Jun 21 02:30 payload.008.part01.cpio
-rw-r--r-- 1 kitty staff 8387764 Jun 21 02:30 payload.008.part02.cpio.xz
-rw-r--r-- 1 kitty staff 8388608 Jun 21 02:30 payload.008.part03.cpio
-rw-r--r-- 1 kitty staff 16765128 Jun 21 02:30 payload.008.part04.cpio.xz
-rw-r--r-- 1 kitty staff 8388608 Jun 21 02:30 payload.008.part05.cpio
-rw-r--r-- 1 kitty staff 0 Jun 21 02:30 payload.008.part06.cpio.xz
-rw-r--r-- 1 kitty staff 8388608 Jun 21 02:30 payload.008.part07.cpio
-rw-r--r-- 1 kitty staff 0 Jun 21 02:30 payload.008.part08.cpio.xz
-rw-r--r-- 1 kitty staff 8388608 Jun 21 02:30 payload.008.part09.cpio
-rw-r--r-- 1 kitty staff 0 Jun 21 02:30 payload.008.part10.cpio.xz
-rw-r--r-- 1 kitty staff 8388608 Jun 21 02:30 payload.008.part11.cpio
-rw-r--r-- 1 kitty staff 0 Jun 21 02:30 payload.008.part12.cpio.xz
-rw-r--r-- 1 kitty staff 8388608 Jun 21 02:30 payload.008.part13.cpio
-rw-r--r-- 1 kitty staff 0 Jun 21 02:30 payload.008.part14.cpio.xz
-rw-r--r-- 1 kitty staff 8388608 Jun 21 02:30 payload.008.part15.cpio
-rw-r--r-- 1 kitty staff 288096620 Jun 21 02:30 payload.008.part16.cpio.xz
你怎么知道一块数据是加密的?
最初的 PBZX 解压工具是如何计算出要在标志上执行的二进制操作来表示存档结束的?我无法弄清楚
0x51e0b5
和之间的关系0x800000
如果只是比较标志的问题,那么这还
while (flag == 0x800000)
不够,为什么首先要考虑这些值?理解这些魔法值的含义的下一步是什么?