Я изменяю некоторые разделы исполняемого кода, скомпилированного в 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;
Наблюдения:
- Прежде чем модифицировать память, я «снимаю защиту» с региона с флагом
PAGE_EXECUTE_READWRITE
. - Представление памяти в визуальной студии ясно показывает мне значение по этому конкретному адресу. Еще более странным является то, что во второй раз, когда я изменяю значение вручную из отладчика, мой код также может изменить это значение.
- переменная
temp
в примере кода содержит значение0xCC
- Этот байт буквально единственный неизменный в море сотен других байтов. Это единственный байт, отмеченный черным цветом в представлении памяти (остальные выделены красным, потому что они были изменены).
- Dll компилируется в Debug/x86. Флаг /MTd установлен. Нет случайного адреса (/DYNAMICBASE : NO , /FIXED: NO). Нет Оптимизация всей программы.
- Немодифицированный байт НЕ ЯВЛЯЕТСЯ переменной. Таким образом, он не может быть «неинициализирован». На самом деле это очень важный байт: это код операции инструкции. Все рушится на этом байте.
- Процедура расшифровки (код XOR) не влияет на ошибку. Я вхожу в код и смотрю на значение
temp
до того, как оно достигнетxor
. Это означает, что ключ дешифрования никогда не используется и, следовательно, не может вызвать проблему. - Виртуальная защита удалась.
Visual Studio может прочитать адрес
Невозможно прочитать байт внутри программы
Я знаю, что проблемы вызывает не значение байта по этому единственному адресу (потому что я нашел другие байты с тем же значением, которые были успешно обработаны). Возможно, байт все еще «защищен»?
Почему это происходит?
i
иsegInfo.segmentSize
выглядит подозрительно. - person Quentin   schedule 26.04.2019lpByteValue
достигает адреса этого странного байта, я смотрю на значениеtemp
. Я не выполняю этот XOR. Значениеtemp
равно 0xCC. Это не имеет ничего общего с кодом расшифровки. Я мог бы также удалить весь этот код. И код, который я предоставил, изменен. Этоi
правильно проверено в исходном коде. Я отредактирую вопрос. - person sergiu reznicencu   schedule 26.04.2019