# PE 文件完整性检查脚本

$filePath = ".\test_tsn_fixed.exe"

if (-not (Test-Path $filePath)) {
    Write-Host "❌ 文件不存在: $filePath" -ForegroundColor Red
    exit 1
}

$pe = [System.IO.File]::ReadAllBytes($filePath)
Write-Host "=== PE 文件完整性检查 ===" -ForegroundColor Cyan
Write-Host "文件大小: $($pe.Length) 字节`n"

# 1. MZ 头
Write-Host "1. MZ 头 (DOS Header)" -ForegroundColor Yellow
$mzMagic = [System.Text.Encoding]::ASCII.GetString($pe[0..1])
Write-Host "   魔数: $mzMagic (期望: MZ)"
if ($mzMagic -eq "MZ") {
    Write-Host "   ✅ MZ 魔数正确" -ForegroundColor Green
} else {
    Write-Host "   ❌ MZ 魔数错误" -ForegroundColor Red
}

$e_lfanew = [BitConverter]::ToUInt32($pe, 60)
Write-Host "   PE 头偏移 (e_lfanew): 0x$($e_lfanew.ToString('X4')) (十进制: $e_lfanew)"
if ($e_lfanew -eq 0x80 -or $e_lfanew -eq 0x100) {
    Write-Host "   ✅ PE 偏移合理" -ForegroundColor Green
} else {
    Write-Host "   ⚠️  PE 偏移不常见 (通常 0x80 或 0x100)" -ForegroundColor Yellow
}

# 2. PE 签名
Write-Host "`n2. PE 签名" -ForegroundColor Yellow
$peSigStart = $e_lfanew
$peSig = [System.Text.Encoding]::ASCII.GetString($pe[$peSigStart..($peSigStart+3)])
Write-Host "   签名: '$peSig' (期望: 'PE`0`0')"
if ($peSig -eq "PE`0`0") {
    Write-Host "   ✅ PE 签名正确" -ForegroundColor Green
} else {
    Write-Host "   ❌ PE 签名错误" -ForegroundColor Red
}

# 3. COFF 头
Write-Host "`n3. COFF 头 (File Header)" -ForegroundColor Yellow
$coffStart = $peSigStart + 4
$machine = [BitConverter]::ToUInt16($pe, $coffStart)
Write-Host "   Machine: 0x$($machine.ToString('X4')) (期望: 8664 = AMD64)"
if ($machine -eq 0x8664) {
    Write-Host "   ✅ 机器类型正确 (x64)" -ForegroundColor Green
} else {
    Write-Host "   ❌ 机器类型错误" -ForegroundColor Red
}

$numSections = [BitConverter]::ToUInt16($pe, $coffStart + 2)
Write-Host "   节区数量: $numSections"

$optHeaderSize = [BitConverter]::ToUInt16($pe, $coffStart + 16)
Write-Host "   Optional Header 大小: $optHeaderSize (期望: 240 = 0xF0)"
if ($optHeaderSize -eq 240) {
    Write-Host "   ✅ Optional Header 大小正确" -ForegroundColor Green
} else {
    Write-Host "   ❌ Optional Header 大小错误" -ForegroundColor Red
}

# 4. Optional Header
Write-Host "`n4. Optional Header" -ForegroundColor Yellow
$optStart = $coffStart + 20
$magic = [BitConverter]::ToUInt16($pe, $optStart)
Write-Host "   Magic: 0x$($magic.ToString('X4')) (期望: 020B = PE32+)"
if ($magic -eq 0x020B) {
    Write-Host "   ✅ PE32+ 格式正确" -ForegroundColor Green
} else {
    Write-Host "   ❌ Magic 错误" -ForegroundColor Red
}

$entryPoint = [BitConverter]::ToUInt32($pe, $optStart + 16)
Write-Host "   入口点 RVA: 0x$($entryPoint.ToString('X8'))"

$imageBase = [BitConverter]::ToUInt64($pe, $optStart + 24)
Write-Host "   Image Base: 0x$($imageBase.ToString('X16'))"

$sectionAlignment = [BitConverter]::ToUInt32($pe, $optStart + 32)
Write-Host "   Section Alignment: 0x$($sectionAlignment.ToString('X8')) (期望: 1000)"

$fileAlignment = [BitConverter]::ToUInt32($pe, $optStart + 36)
Write-Host "   File Alignment: 0x$($fileAlignment.ToString('X8')) (期望: 200)"

# 5. 节表
Write-Host "`n5. 节表 (Section Headers)" -ForegroundColor Yellow
$sectionTableStart = $optStart + $optHeaderSize
for ($i = 0; $i -lt $numSections; $i++) {
    $secOffset = $sectionTableStart + ($i * 40)
    $secName = [System.Text.Encoding]::ASCII.GetString($pe[$secOffset..($secOffset+7)]).TrimEnd("`0")
    $virtualSize = [BitConverter]::ToUInt32($pe, $secOffset + 8)
    $virtualAddr = [BitConverter]::ToUInt32($pe, $secOffset + 12)
    $rawSize = [BitConverter]::ToUInt32($pe, $secOffset + 16)
    $rawOffset = [BitConverter]::ToUInt32($pe, $secOffset + 20)
    $chars = [BitConverter]::ToUInt32($pe, $secOffset + 36)
    
    Write-Host "   [$i] $secName"
    Write-Host "       Virtual: 0x$($virtualAddr.ToString('X8')) size: $virtualSize (0x$($virtualSize.ToString('X')))"
    Write-Host "       Raw:     0x$($rawOffset.ToString('X8')) size: $rawSize (0x$($rawSize.ToString('X')))"
    
    # 检查特征位
    $isCode = ($chars -band 0x00000020) -ne 0
    $isExecute = ($chars -band 0x20000000) -ne 0
    $isRead = ($chars -band 0x40000000) -ne 0
    $isWrite = ($chars -band 0x80000000) -ne 0
    
    $perms = @()
    if ($isCode) { $perms += "Code" }
    if ($isExecute) { $perms += "Execute" }
    if ($isRead) { $perms += "Read" }
    if ($isWrite) { $perms += "Write" }
    
    Write-Host "       权限: $($perms -join ', ')"
}

# 6. 代码段验证
Write-Host "`n6. 代码段验证" -ForegroundColor Yellow
if ($numSections -gt 0) {
    $textRawOffset = [BitConverter]::ToUInt32($pe, $sectionTableStart + 16)
    Write-Host "   .text 文件偏移: 0x$($textRawOffset.ToString('X8'))"
    
    $first16Bytes = $pe[$textRawOffset..($textRawOffset + 15)]
    $hexString = ""
    for ($j = 0; $j -lt 16; $j++) {
        $hexString += "{0:X2} " -f $first16Bytes[$j]
    }
    Write-Host "   .text 起始 16 字节: $hexString"
    
    # 检查是否是有效的 x64 指令开头
    if ($first16Bytes[0] -eq 0x55) {  # push rbp
        Write-Host "   ✅ 以 push rbp 开头 (标准函数 prologue)" -ForegroundColor Green
    } elseif ($first16Bytes[0] -eq 0x48 -and $first16Bytes[1] -eq 0x89) {  # mov rax, ...
        Write-Host "   ✅ 以 mov 指令开头" -ForegroundColor Green
    } else {
        Write-Host "   ⚠️  不常见的指令开头" -ForegroundColor Yellow
    }
}

Write-Host "`n✅ 检查完成" -ForegroundColor Green
