Как найти адрес по шестнадцатеричному значению в строковом формате? - PullRequest
0 голосов
/ 05 февраля 2019

У меня есть int key1 = -1466731422;, который возвращает мне шестнадцатеричное значение 62 74 93 A8 из .exe, когда я ищу его в шестнадцатеричном редакторе.
Я пытаюсь переписать newKey1,который может быть выбран пользователем, вместо этого key1.
Предположим, мы хотим перезаписать это key1 для int newKey1 = -1566731422, что я до сих пор делал:

private void btnGravar_Click(object sender, EventArgs e)
{
    FixHex(key1, newKey1); //transform the int key in hex string

    br = new BinaryReader(File.OpenRead(element.FileName));            
    try
    {                
        for (long i = 0; i <= br.BaseStream.Length; i++)
        {
            if (br.BaseStream.ReadByte() == (byte)Convert.ToInt32(key1, 16))
            {
                progressBar.Value = progressBar.Maximum;
                br.Close();
                bw = new BinaryWriter(File.OpenWrite(element.FileName));
                bw.BaseStream.Position = i;
                bw.Write(newKey1);
                bw.Close();

                MessageBox.Show("Key updated", "Success");
                break;
            }
            else
            {
                progressBar.Value += 1;
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}        

Это не такт работа, хотяМой цикл for не находит совпадений, поэтому я думаю, что он решит это метод поиска адреса по int key (так как в шестнадцатеричном редакторе я могу это сделать) ИЛИ по шестнадцатеричному в строковом формате.

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019
  1. Поскольку вы ищете целочисленное значение (которое занимает четыре байта), нет необходимости читать один байт.Непосредственно прочитайте целое число, используя перегрузку BinaryReader, которая принимает значение Int32, и посмотрите, соответствует ли оно искомому.
  2. Вы пытаетесь написать строку.Это не строка, это последовательность из четырех байтов с прямым порядком байтов.Вам нужно записать эти четыре байта, чтобы заменить существующие.

BinaryReader.ReadInt32 () увеличивает позицию потока на 4 байта, поэтому вам необходимо отслеживать позицию чтения, увеличивая ее на 1 для каждого чтения и устанавливая BaseStream положение вручную .

Используя FileAccess.ReadWrite и FileShare.ReadWrite для BinaryReader и BinaryWriter, вы можете найти значение и перезаписать его за один раз:

Примечание: здесь нет средств для проверки возможного ложного срабатывания из-за отсутствия информации о структуре файла.Это зависит от вас.

int valOriginal = -1466731422;
int valSubstitute = -1566731422;
int valLength = BitConverter.GetBytes(valOriginal).Length;

using (var reader = new BinaryReader(
    File.Open("[File Path]", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))) {
    int position = 0;
    while (position < (reader.BaseStream.Length - valLength))
    {
        reader.BaseStream.Position = position;
        if (reader.ReadInt32() == valOriginal)
        {
            using (var writer = new BinaryWriter(
                File.Open("[File Path]", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))) {
                writer.BaseStream.Position = position;
                writer.Write(valSubstitute);
            };
            break;
        }
        position += 1;
    }
};
0 голосов
/ 06 февраля 2019

Как говорили другие, вы не правильно сравниваете правильные вещи.То, как вы хотите сравнить вещи, которые вы сравниваете, зависит от формата данных, которые вы читаете в BinaryReader, и типа «key1».

В своем описании вы говорите, что «key1» - этоint, но затем попытайтесь преобразовать его как строку.Я просто собираюсь предположить, что это INT.Вы можете оставить комментарий, если это не так.

Формат данных в вашем файле также не понятен из описания.Я собираюсь предположить, что это целые.Если его нет, добавьте комментарий.Чтение целого числа выглядит следующим образом:

int testVal = br.ReadInt32();

Это дает вам целое число, и, поскольку оба являются целыми числами, вы можете просто сравнить как целые числа:

if(testVal == key1)
{/*do your other stuff*/}

Вероятно, лучше выполнить цикл, пока неконец файла, а не цикл по каждому байту, что-то вроде:

while(br.BaseStream.Position != br.Basestream.Length)

Объединение его может выглядеть примерно так:

while(br.BaseStream.Position != br.Basestream.Length)
{        
    int testVal = br.ReadInt32();

    if(testVal == key1)
    {/*do your other stuff*/}
}

Еще одно примечание: потому что вы «новичок»Используя BinaryReader каждый раз, когда вызывается этот метод, и BinaryReader закрывается в «если», вы можете рассмотреть using вокруг вашего BinaryReader и объявить его там же.Это обеспечит правильное удаление BinaryReader в случае исключения.Приведенный ниже вариант позволит надлежащим образом избавиться от BinaryReader, но при этом поймать любое исключение (а также его неодобрение, чтобы поймать общее исключение):

try
{
    using(var br = new BinaryReader(File.OpenRead(element.FileName)))
    {
        while(br.BaseStream.Position != br.Basestream.Length)
        {        
            if(br.ReadInt32() == key1)
            {/*do your other stuff*/}
        }
    }
}
catch(Exception ex)
{
}

Надежда, которая помогает.

...