Уважаемые Експерты! Есть пока что простенькое приложение в котором данные находятся сразу же за кодом в одной области памяти. Вот исходный код: Код (Text): .586 .model flat, stdcall option casemap :none ; case sensitive. ;######################################################################### include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib ;######################################################################### .data ;######################################################################### .code Modulation proc ret Modulation endp start: mov eax, offset CS:Dump ; Занести в ЕАХ адрес Dump-а. Просто для теста правильности. mov EBX, 0AAAAAAAAh; mov [eax], EBX ; Попытка записать в область памяти Dump-а число 0AAAAAAAAh. В отладчике да и в следующем ексепшене адреса правильные. ; Но, вылетает Exception: Инструкция по адресу 0х0040100B обратилась к памяти по адресу 0x0040101F. Память ; не может быть written. mov eax, CS:Dump ; Занести в ЕАХ 4 байта из того что находиться в Dump-е, в моем примере FF00FF00h. Тоже для теста правильности. call Modulation ; Пока ничего не делает. invoke ExitProcess, NULL ; Звершение процесса. Dump dd 100h dup (00FF00FFh) ; Данные в области кода, которые следуют за размещением invoke ExitProcess, NULL. end start Нужно сделать так чтобы весь код (его численное представление), который идет после метки Start и до оглашения массива Dump записался в этот массив. Так сказать создалась резервная копия кода. Всё сводится к тому что нужно побайтно прочитать код после метки Start и записать его побайтно в массив Dump. Для демонстрации я пытаюсь записать число 0AAAAAAAAh в первые 4 байта массива Dump, но вылетает Exception: Инструкция по адресу 0х0040100B обратилась к памяти по адресу 0x0040101F. Память не может быть written. Но мне именно надо записывать сверху области кода. Перед вызовом процедури Modulation в EAX должно быть число 0AAAAAAAAh, а не 00FF00FFh. Использую masm32 (ml 6.14) Окошко OLLY DEBUGGER прилагается.
Защита это базовое понятие в архитектуре, на основе этого сама модель системы стоется. Как можно кодить на масме не понимая этого не понимаю.
Спасибо qwe8013. Ключевое слово твоего поста VirtualProtect позволило сформировать правильный запрос в Google. Действительно запись в области кода можно разрешить с помощью этой функции. Её я и буду использовать. Спасибо VaZoNeZ Указав сборщику такие параметры: link.exe /SUBSYSTEM:WINDOWS /section:.text,ERW можно разрешить запись во всей области кода, но иногда нужно разрешить запись только в некоторой части кода. Спасибо Mika0x65 Я так и сделал. Вынес массив для сохранения кода в отдельную секцию. Но не использовал адресацию CSump и размер блока равный размеру Dump-а. Вместо этого я ссылаюсь на адрес начала блока и вычисляю его размер (АдресКонцаБлока-АдресНачалаБлока). Всё вышло благодаря вашим ответам. Код (Text): .586 .model flat, stdcall option casemap :none; case sensitive. ;######################################################################### include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib ;######################################################################### .data OldData dd 00000000h ; ;######################################################################### .code Modulation proc ret Modulation endp start: mov ecx, Execute_Read_Write_Start ; Сохранить в ЕСХ адрес начала блока в которм теперь будет разрешена запись. mov eax, Execute_Read_Write_End ; sub eax, ecx ; Записать в ЕАХ размер блока в байтах. xor edx, edx ; mov ebx, 00000004h ; Размер в байтах типа SIZE_T (для моей MustDie (Windows) XP x32). div ebx ; Теперь в ЕАХ находится размер блока в единицах SIZE_T (потому что размер ; блока для которого изменяются права на чтение-запись-выполнение в VirtualProtect ; должен быть указан в единицах SIZE_T). В x32 размер SIZE_T равен 4 байта, в x64 - 8 байт. invoke VirtualProtect, ecx, eax, PAGE_EXECUTE_READWRITE, ADDR OldData ; Разрешаем запись в область между Execute_Read_Write_Start ; и Execute_Read_Write_End. mov eax, offset CS:Dump ; Занести в ЕАХ адрес Dump-а. mov ebx, 0AAAAAAAAh ; mov [eax], EBX ; Записать в область памяти Dump-а число 0AAAAAAAAh. Теперь этот код успешно выполняется. mov eax, CS:Dump ; Занести в ЕАХ 4 байта из того что находиться в Dump-е. call Modulation ; Пока ничего не делает. invoke ExitProcess, NULL ; Завершение процесса. Execute_Read_Write_Start: Dump dd 100h dup (00FF00FFh) ; Данные в области кода, которые следуют за размещением invoke ExitProcess, NULL. Execute_Read_Write_End: end start Теперь перед вызовом процедуры Modulation в ЕАХ находится значение 0AAAAAAAAh. Полезные ссылки 1. Запись в сегмент кода http://forum.sources.ru/index.php?showtopic=84220&hl= 2. VirtualProtect Function (MSDN) http://msdn.microsoft.com/en-us/library/Aa366898 P. S. А нужно это всё было собственно для шифрования кода программы и последующей дешифровки перед её запуском.
Код (Text): xor edx, edx ; mov ebx, 00000004h ; Размер в байтах типа SIZE_T (для моей MustDie (Windows) XP x32). div ebx ; Теперь в ЕАХ находится размер блока в единицах SIZE_T (потому что размер ; блока для которого изменяются права на чтение-запись-выполнение в VirtualProtect ; должен быть указан в единицах SIZE_T). В x32 размер SIZE_T равен 4 байта, Оффтоп: вобщето это сдвигом делается... SHR EAX, 2
Экспериментальным путём доказано, что google - прав. Спасибо за пост. Вывод: MSDN - это не Microsoft Developers Network, а MuSt Die Nihilism.
На самом деле непонятно, откуда изначально взялась мысль об измерении размера региона для VirtualProtect() в единицах sizeof SIZE_T. Написано же (выделение моё):