已进行编辑,以更正和阐明我的原始要求。抱歉,这很令人困惑。
我正在尝试使用在堆栈溢出中发现的这种方法来搜索在“ testBin.exe”中编译的24个字符串中的2个字符“ YY”。我想用较小或相同长度的字符串覆盖“ YY”及所有后续数据。如果搜索字符串和替换字符串的长度相同,则testBin.exe可以很好地执行;如果搜索字符串小于24个字符,则覆盖其中的值,并将替换字符串附加到原始字符串中,从而破坏二进制文件。
我希望替换字符串从发现搜索字符串的第一个实例开始覆盖数据。我意识到这具有破坏性,因此我在可执行文件中填充了较大的字符串作为占位符。只要总字符串长度保持不变,程序将照常执行。我已经使用这种方法几天了,我认为在Buffer.BlockCopy中没有看到什么,我只需要以某种方式省去搜索字符串的长度,这样它将覆盖整个字符串。任何帮助表示赞赏。
Here is a hex view of the unaltered testBin.exe with 24 Y characters.
参考:How can I replace a unicode string in a binary file?
我的方法:
// Works fine when searchString and replacementString are the
// same length.
static string searchString = "YYYYYYYYYYYYYYYYYYYYYYYY";
static string replacementString = "ZZZZZZZZZZZZZZZZZZZZZZZZ";
// Corrupts the binary when the searchString is a lesser length than
// replacementString.
static string searchString = "YY";
static string replacementString = "ZZZZZZZZZZZZZZZZZZZZZZZZ";
public static void BinaryWriter(object state)
{
byte[] fileName = File.ReadAllBytes(@"testBin.exe"),
oldBytes = Encoding.Unicode.GetBytes(searchString),
newBytes = Encoding.Unicode.GetBytes(replacementString);
int index = IndexOfBytes(fileName, oldBytes);
if (index < 0)
{
return;
}
byte[] newFileBytes =
new byte[fileName.Length + newBytes.Length - oldBytes.Length];
Buffer.BlockCopy(fileName, 0, newFileBytes, 0, index);
Buffer.BlockCopy(newBytes, 0, newFileBytes, index, newBytes.Length);
Buffer.BlockCopy(fileName, index + oldBytes.Length, newFileBytes,
index + newBytes.Length, fileName.Length - index - oldBytes.Length);
File.WriteAllBytes(@"new_testBin.exe", newFileBytes);
int IndexOfBytes(byte[] searchBuffer, byte[] bytesToFind)
{
for (int i = 0; i < searchBuffer.Length - bytesToFind.Length; i++)
{
bool success = true;
for (int j = 0; j < bytesToFind.Length; j++)
{
if (searchBuffer[i + j] != bytesToFind[j])
{
success = false;
break;
}
}
if (success)
{
return i;
}
}
return -1;
}
}
答案 0 :(得分:1)
您为什么要这么做? 更换后您期待什么? -可执行文件? -因为它不起作用!
您的方法使用ReplaceTextInFile
,但是.exe文件是结构化文件,而不是简单的二进制原始字符。标记了一些关键位置。
示例: 偏移量0:-命令 偏移量100:一些代码 偏移200:您的文字 偏移量220:其他文字
现在,如果您将给定偏移量的“您的文本”替换为更长的字符(例如长度为40),而不是替换下一个String(可以是机器指令,数据或文本)。
我搜索了“ .net exe文件结构”,试图为您找到正确的方向。 以下是一些结果,您应该阅读它:
Anatomy of a .NET Assembly – PE Headers
What is the file structure of an .exe file? What is the memory location of its starting address?
答案 1 :(得分:0)
我知道了。这是简单的方法。
使用子字符串,我减去了searchString的长度,所以我不会覆盖缓冲区。很棒!
参考:https://www.dotnetperls.com/substring
string searchString = "YY";
string replacementString = "ZZZ";
string update = replacementString.Substring(0, searchString.Length);
byte[] fileName = File.ReadAllBytes(@"testBin.exe"),
oldBytes = Encoding.Unicode.GetBytes(searchString),
newBytes = Encoding.Unicode.GetBytes(update);