Модификация области памяти - возвращает 0xCC VC ++ - PullRequest
3 голосов
/ 26 апреля 2019

Я изменяю некоторые разделы исполняемого кода, скомпилированного в dll. Но один байт по фиксированному адресу из всего сегмента, который я изменяю, не может быть изменен, даже не прочитан.

Код очень прост:

SEGMENT_DATA segInfo = getSegmentInfo(mHandle, segmentName);

if (segInfo.inFileSegmentAddr == 0) return false;

DWORD mOlProtection;
DWORD mOlProtection_1;

if (segInfo.architecture != MY_ARCH) {
    printf(" Not the same architecture!\n");
    return 0;
}

if(VirtualProtect((LPVOID)segInfo.segmentAddr, segInfo.segmentSize, PAGE_EXECUTE_READWRITE, &mOlProtection)==0) return false;
DWORD i=0;
for (size_t k = 0; k < segInfo.segmentSize; k++) {
    BYTE *lpByteValue = (BYTE*)(segInfo.segmentAddr + k);

    BYTE temp = *lpByteValue;
    *lpByteValue = temp ^ lDecryptionKey[i];
    i++;
    i %= decryptionKeyLength;
}

if(VirtualProtect((LPVOID)segInfo.segmentAddr, segInfo.segmentSize, mOlProtection, &mOlProtection_1)==0) return false;

Замечания:

  1. Перед тем, как изменить память, я "снимаю защиту" с флага PAGE_EXECUTE_READWRITE.
  2. Memory View в visual studio четко показывает мне значение по этому конкретному адресу. Еще более странно то, что во втором случае, когда я изменяю значение вручную из отладчика, мой код также может изменить это значение.
  3. temp переменная в примере кода содержит значение 0xCC
  4. Этот байт буквально является единственным неизменным в море из сотен других байтов. Это единственный байт, помеченный черным в представлении памяти (остальные - красные, потому что они были изменены)
  5. Dll скомпилирована в Debug / x86. / MTd флаг установлен. Нет случайного адреса (/ DYNAMICBASE: НЕТ, / FIXED: NO). Нет Целая программа оптимизации.
  6. Немодифицированный байт НЕ является переменной. Так что это не может быть "неинициализированным". На самом деле это очень важный байт: это код операции инструкции. Все падает на этот байт.
  7. Процедура дешифрования (код XOR) не влияет на ошибку. Я вхожу в код и смотрю на значение temp, прежде чем оно достигнет xor. Это означает, что ключ дешифрования никогда не используется, и поэтому он не может вызвать проблему.
  8. Виртуальная защита успешна.


Снимки : The black byte cannot be read or written to although visaul studio can display it


Visual studio can read the address Визуальная студия может прочитать адрес



Can't read byte inside program Не могу прочитать байт внутри программы


Я знаю, что это не значение байта на том единственном адресе, которое вызывает проблемы (потому что я нашел другие байты с тем же значением, которые были успешно обработаны). Возможно, байт все еще «защищен»?

Почему это происходит?

1 Ответ

3 голосов
/ 27 апреля 2019

Вы вполне могли бы справиться с очень распространенным сценарием Software Breakpoints. Software breakpoints фактически устанавливаются путем замены инструкции, которая должна быть остановлена, на инструкцию точки останова.

Инструкция точки останова присутствует в большинстве процессоров и обычно такая же короткая, как и самая короткая команда, поэтому только one byte on x86 (0xCC, INT 3).

Поскольку я не знаю, есть ли вообще какие-либо точки останова в вашем источнике, я могу только предположить, что это ваша проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...