![我可以使用该脚本正确修补可执行文件吗?](https://linux22.com/image/1553849/%E6%88%91%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%E8%AF%A5%E8%84%9A%E6%9C%AC%E6%AD%A3%E7%A1%AE%E4%BF%AE%E8%A1%A5%E5%8F%AF%E6%89%A7%E8%A1%8C%E6%96%87%E4%BB%B6%E5%90%97%EF%BC%9F.png)
最近我得到了一些关于文本替换脚本的帮助,想知道它是否可以用于修补。我通常使用氢键,并认为如果它本质上是一个美化的记事本,那么在文本编辑器和十六进制编辑器中编辑可执行文件有什么区别?我决定验证我的理论,并对脚本进行测试,而它能替换指定的字符串,它会将信息添加到可执行文件中。
让我困惑的是,如果将其用于替换文本文档中的文本,它只会替换字符串,而不会向文档添加字节,除非新字符串比前一个字符串长。我相信这是因为该脚本是为编辑文本文档而设计的,因此会修改标题。我使用 HxD 比较了前后情况,果然标题被修改了。这是我目前拥有的脚本:
@echo off
setlocal enableextensions disabledelayedexpansion
set search=OutDir=Old String
set replace=OutDir=New String
set textFile=Document.txt
:PowerShell
SET PSScript=%temp%\~tmpStrRplc.ps1
ECHO (Get-Content "%~dp0%textFile%").replace("%search%", "%replace%") ^| Set-Content "%~dp0%textFile%">"%PSScript%"
SET PowerShellDir=C:\Windows\System32\WindowsPowerShell\v1.0
CD /D "%PowerShellDir%"
Powershell -ExecutionPolicy Bypass -Command "& '%PSScript%'"
EXIT
(我将替换的字符串大小相同,因此可执行文件的大小将保持不变,并且不会使用字符串损坏。)
我想指出的是,我是 PowerShell 的新手,所以我仍在学习它的工作原理。我注意到了这个%~dp0%textFile%
变量。如果我正确解释了这个变量,它会告诉 PowerShell 脚本处理要修改的定义文件作为文本文档。按照这个逻辑(如果正确的话),是否有类似的变量可以忽略格式或将输入文件作为可执行文件处理?我的脚本能够更改我定义的内容,但会破坏可执行文件,用我的脚本进行修补是否可行?
答案1
摘自我最近看到的一个例子:
# Description: set your.exe resolution 0 to any x/y specified
# By knowning the offset for these values hard coded in your
# executable
# - None of this is real world... example only
Set-Location(Split-Path $MyInvocation.MyCommand.Path)
# Prompt resolution
$resolutionX = Read-Host -Prompt "Width"
$resolutionY = Read-Host -Prompt "Height"
# Resolution Z is just hard coded as 32
# Patch bytes
$bytes = [System.IO.File]::ReadAllBytes("your.exe")
# Arbitrary locations and values for example
$offsetX = 0x0039CA70
$offsetY = $offsetX + 4
$offsetZ = $offsetY + 4
$resolutionX = [BitConverter]::GetBytes([Int16]$resolutionX)
$resolutionY = [BitConverter]::GetBytes([Int16]$resolutionY)
$resolutionZ = [BitConverter]::GetBytes([Int16]32)
# SMASH your new values into the exe
$bytes[$offsetX] = $resolutionX[0]
$bytes[$offsetX+1] = $resolutionX[1]
$bytes[$offsetY] = $resolutionY[0]
$bytes[$offsetY+1] = $resolutionY[1]
$bytes[$offsetZ] = $resolutionZ[0]
# And save the result
[System.IO.File]::WriteAllBytes("your.exe", $bytes)
Read-Host -Prompt "Press Enter to exit"