test(ssh): summarize complete Windows PE drift

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
Jinwoo-H
2026-07-14 13:37:48 -04:00
co-authored by Orca
parent 27c6a5718c
commit cd7f941365
2 changed files with 144 additions and 23 deletions
@@ -8,6 +8,8 @@ const MAX_SECTIONS = 96
const MAX_DEBUG_ENTRIES = 32
const MAX_DIFF_RANGES = 128
const MAX_HEADER_DIFFERENCES = 128
const MAX_RANGE_SAMPLE_BYTES = 32
const MAX_REGION_SAMPLES = 8
const READ_CHUNK_BYTES = 64 * 1024
const DIAGNOSTIC_TIMEOUT_MS = 60_000
@@ -146,11 +148,76 @@ function parsePeHeader(buffer) {
start: section.headerOffset,
end: section.headerOffset + 40,
label: `section header ${section.name}`
}))
})),
...sections
.filter((section) => section.rawSize > 0)
.map((section) => ({
start: section.rawPointer,
end: section.rawPointer + section.rawSize,
label: `section ${section.name}`
}))
]
return { header, regions, sections }
}
function regionAt(regions, offset) {
const matches = regions.filter((region) => offset >= region.start && offset < region.end)
matches.sort((left, right) => left.end - left.start - (right.end - right.start))
return matches[0]?.label ?? 'unmapped file data'
}
function bytesHex(bytes) {
return bytes
.map((byte) => (byte === undefined ? '--' : byte.toString(16).padStart(2, '0')))
.join('')
}
function rangeRecord(state, firstRegions, secondRegions) {
const firstRegion = regionAt(firstRegions, state.start)
const secondRegion = regionAt(secondRegions, state.start)
return {
start: state.start,
endExclusive: state.end,
startHex: hex(state.start),
endExclusiveHex: hex(state.end),
length: state.end - state.start,
firstRegion,
secondRegion,
firstBytes: bytesHex(state.firstBytes),
secondBytes: bytesHex(state.secondBytes),
bytesTruncated: state.end - state.start > state.firstBytes.length
}
}
function addRegionSummary(state, range) {
const key = `${range.firstRegion}\0${range.secondRegion}`
let summary = state.regionSummaries.get(key)
if (!summary) {
summary = {
firstRegion: range.firstRegion,
secondRegion: range.secondRegion,
differingBytes: 0,
rangeCount: 0,
firstOffset: range.start,
lastEndExclusive: range.endExclusive,
samples: []
}
state.regionSummaries.set(key, summary)
}
summary.differingBytes += range.length
summary.rangeCount += 1
summary.lastEndExclusive = range.endExclusive
if (summary.samples.length < MAX_REGION_SAMPLES) {
summary.samples.push({
start: range.start,
endExclusive: range.endExclusive,
firstBytes: range.firstBytes,
secondBytes: range.secondBytes,
bytesTruncated: range.bytesTruncated
})
}
}
function rvaToFileOffset(rva, header, sections) {
if (rva < header.optional.sizeOfHeaders) {
return rva
@@ -275,27 +342,29 @@ function finishRange(state, firstRegions, secondRegions) {
return
}
state.rangeCount += 1
const range = rangeRecord(state, firstRegions, secondRegions)
addRegionSummary(state, range)
if (state.ranges.length < MAX_DIFF_RANGES) {
const regionAt = (regions) =>
regions.find((region) => state.start >= region.start && state.start < region.end)?.label ??
'unmapped file data'
state.ranges.push({
start: state.start,
endExclusive: state.end,
startHex: hex(state.start),
endExclusiveHex: hex(state.end),
length: state.end - state.start,
firstRegion: regionAt(firstRegions),
secondRegion: regionAt(secondRegions)
})
state.ranges.push(range)
}
state.start = undefined
state.firstBytes = []
state.secondBytes = []
}
async function compareBytes(first, second, signal) {
const firstHash = createHash('sha256')
const secondHash = createHash('sha256')
const state = { differingBytes: 0, end: 0, rangeCount: 0, ranges: [], start: undefined }
const state = {
differingBytes: 0,
end: 0,
firstBytes: [],
rangeCount: 0,
ranges: [],
regionSummaries: new Map(),
secondBytes: [],
start: undefined
}
const length = Math.max(first.metadata.size, second.metadata.size)
for (let offset = 0; offset < length; offset += READ_CHUNK_BYTES) {
signal.throwIfAborted()
@@ -313,7 +382,15 @@ async function compareBytes(first, second, signal) {
index >= firstLength || index >= secondLength || firstBytes[index] !== secondBytes[index]
if (different) {
state.differingBytes += 1
state.start ??= offset + index
if (state.start === undefined) {
state.start = offset + index
state.firstBytes = []
state.secondBytes = []
}
if (state.firstBytes.length < MAX_RANGE_SAMPLE_BYTES) {
state.firstBytes.push(index < firstLength ? firstBytes[index] : undefined)
state.secondBytes.push(index < secondLength ? secondBytes[index] : undefined)
}
state.end = offset + index + 1
} else {
finishRange(state, first.parsed.regions, second.parsed.regions)
@@ -327,7 +404,8 @@ async function compareBytes(first, second, signal) {
differingBytes: state.differingBytes,
rangeCount: state.rangeCount,
ranges: state.ranges,
rangesTruncated: state.rangeCount > state.ranges.length
rangesTruncated: state.rangeCount > state.ranges.length,
regionSummaries: [...state.regionSummaries.values()]
}
}
@@ -390,6 +468,7 @@ export async function diagnoseWindowsPeMismatch({
rangeCount: comparison.rangeCount,
ranges: comparison.ranges,
rangesTruncated: comparison.rangesTruncated,
regionSummaries: comparison.regionSummaries,
headerDifferences: headerState.differences,
headerDifferencesTruncated: headerState.truncated
}
@@ -74,10 +74,10 @@ async function fixturePair(firstBytes, secondBytes) {
describe('SSH relay Windows PE mismatch diagnostic', () => {
it('reports bounded byte ranges and relevant header differences without file paths', async () => {
const fixture = await fixturePair(
peFixture(),
peFixture({ identifierByte: 0x22, timestamp: 0x87654321 })
)
const first = peFixture()
const second = peFixture({ identifierByte: 0x22, timestamp: 0x87654321 })
second[0x300] = 0xff
const fixture = await fixturePair(first, second)
const result = await diagnoseWindowsPeMismatch(fixture)
@@ -90,8 +90,8 @@ describe('SSH relay Windows PE mismatch diagnostic', () => {
sha256: expect.stringMatching(/^sha256:/)
}),
difference: expect.objectContaining({
differingBytes: 24,
rangeCount: 3,
differingBytes: 25,
rangeCount: 4,
rangesTruncated: false
})
})
@@ -101,8 +101,22 @@ describe('SSH relay Windows PE mismatch diagnostic', () => {
expect(result.difference.ranges.map((range) => range.firstRegion)).toEqual([
'COFF header',
'debug directory',
'CodeView data 0'
'CodeView data 0',
'section .rdata'
])
expect(result.difference.regionSummaries).toEqual([
expect.objectContaining({ firstRegion: 'COFF header', differingBytes: 4, rangeCount: 1 }),
expect.objectContaining({ firstRegion: 'debug directory', differingBytes: 4, rangeCount: 1 }),
expect.objectContaining({
firstRegion: 'CodeView data 0',
differingBytes: 16,
rangeCount: 1
}),
expect.objectContaining({ firstRegion: 'section .rdata', differingBytes: 1, rangeCount: 1 })
])
expect(result.difference.regionSummaries[3].samples[0]).toEqual(
expect.objectContaining({ firstBytes: '00', secondBytes: 'ff', bytesTruncated: false })
)
expect(result.difference.headerDifferences.map((entry) => entry.field)).toEqual([
'coff.timeDateStamp',
'debugDirectory.0.codeView.identifier',
@@ -131,6 +145,34 @@ describe('SSH relay Windows PE mismatch diagnostic', () => {
).rejects.toThrow('aborted')
})
it('caps per-region samples and per-range byte excerpts', async () => {
const first = peFixture()
const second = peFixture()
for (let index = 0; index < 10; index += 1) {
second[0x280 + index * 2] = 0xff
}
second.fill(0xff, 0x340, 0x368)
const result = await diagnoseWindowsPeMismatch(await fixturePair(first, second))
expect(result.difference.regionSummaries).toEqual([
expect.objectContaining({
firstRegion: 'section .rdata',
differingBytes: 50,
rangeCount: 11,
samples: expect.any(Array)
})
])
expect(result.difference.regionSummaries[0].samples).toHaveLength(8)
expect(result.difference.ranges.at(-1)).toEqual(
expect.objectContaining({
length: 40,
bytesTruncated: true,
firstBytes: '00'.repeat(32),
secondBytes: 'ff'.repeat(32)
})
)
})
it('parses only the two explicit CLI inputs', () => {
expect(
parseWindowsPeDiagnosticArguments(['--first-pe', 'first.node', '--second-pe', 'second.node'])