Сейчас на форуме: bartolomeo (+6 невидимых)

 eXeL@B —› Программирование —› Ошибка выполнения (DEP?)
Посл.ответ Сообщение


Ранг: 216.9 (наставник), 85thx
Активность: 0.310.15
Статус: Участник
X-Literator

Создано: 21 февраля 2011 19:30
· Личное сообщение · #1

Собственно, при выполнении компилированной в VS2010 программы возникает следующее исключение:


"Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена." (при вызове strncpy).

Выложить исходники не могу.

Вероятность того, что где-то память теряется, чрезвычайно мала. Скорее всего, из-за DEP. Прочитал на одном форуме следующее:

Windows Vista и выше по умолчанию используют возможности процессора под названием DEP (aka NX) для предотвращения "исполнения данных". Однако, многие неуправляемые библиотеки активно "исполняют данные", особенно, если эти библиотеки написаны с использованием старых версий ATL. По умолчанию компилятор C# для фреймворка 2.0 c установленным SP1 помечает все сборки специальным флагом в PE заголовке, который сообщает системе, что данный код совместим с DEP/NX и не собирается "исполнять данные". В принципе, если приложение написано на чистом управляемом коде и не использует P/Invoke то такое предположение верно. Но во многих случаях это не так. Повлиять на компилятор "по-хорошему" не получится, ибо флага, управляющего таким поведением попросту нет. Зато есть дивный инструмент - editbin из состава Platform SDK - вот он позволяет поправить некоторые флаги в PE заголовке уже готовой управляемой сборки (да и для неуправляемых библиотек он тоже подойдёт). Так что, если это Ваш случай, то editbin Вам в руки. Я с этой проблемой столкнулся где-то год назад и теперь в моём проекте главный exe-шник патчится примерно так:
Code:
  1. view source
  2. print?
  3. 1.call "$(DevEnvDir)\..\tools\vsvars32.bat"
  4. 2.editbin /NXCOMPAT:NO  $(TargetPath)
  5. Это фрагмент post-build event-а для сброса флага DEP/NX - надеюсь, что это поможет


Вопрос в следующем: куда вообще фигачить эти макросы? ( ну не занимался я программированием долго )

-----
Харе курить веники и нюхать клей, к вам едет из Америки бог Шива, и он еврей.




Ранг: 37.1 (посетитель), 11thx
Активность: 0.030
Статус: Участник

Создано: 21 февраля 2011 19:58
· Личное сообщение · #2

Ну, вообще, это надо в консоли выполнять...

PS Мне всё равно кажется, что это проблема не из-за DEP, а из-за неправильной работы с указателями...




Ранг: 216.9 (наставник), 85thx
Активность: 0.310.15
Статус: Участник
X-Literator

Создано: 21 февраля 2011 20:16
· Личное сообщение · #3

да фишка в том, что до переноса из консольного проекта ряда функций в проект windows foorms все работало идеально. Поэтому и думаю, что не из-за неправильной работы.

-----
Харе курить веники и нюхать клей, к вам едет из Америки бог Шива, и он еврей.





Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 21 февраля 2011 22:54
· Личное сообщение · #4

А при чём тут ДЕП и копирование, когда деп отслеживает выполнение кода, на что его название как бы намекает. Лучше бы взял и отладил, чем все подряд флаги тыкал наобум.



Ранг: 101.0 (ветеран), 344thx
Активность: 1.150
Статус: Участник

Создано: 21 февраля 2011 23:21
· Личное сообщение · #5

Crawler пишет:
при вызове strncpy

Ну так смотри куда пишешь), проверь длину строки (наличие нуль-символа) и размер буффера, а также доступность буффера на запись.




Ранг: 238.8 (наставник), 67thx
Активность: 0.20
Статус: Участник
CyberHunter

Создано: 22 февраля 2011 10:28
· Личное сообщение · #6

Деп можно так отключить
Code:
  1. mov dword ptr ds:[pointer], 2
  2.  
  3. push 4
  4. push offset pointer
  5. push 22h
  6. push -1
  7. call NtSetInformationProcess
  8.  


-----
Nulla aetas ad discendum sera





Ранг: 216.9 (наставник), 85thx
Активность: 0.310.15
Статус: Участник
X-Literator

Создано: 24 февраля 2011 06:20 · Поправил: Crawler
· Личное сообщение · #7

Archer
Не наобум. Я ж говорю - в консольной версии работало... причем набор функций тот же. И люди сталкивались с подобной проблемой, отключение dep их решало. Может, правда и твоя.


int
да отлаживал в 2010 студии пошагово все. на первой итерации цикла пишет в массив, на второй - уже отказзывается. Адреса совпадают, атрибуты памяти никакие не изменяются. Примерно так это было:

Code:
  1.  
  2.  
  3.  
  4.                               userbase *ubase=new userbase [users_counter];
  5.  
  6.                               for (int d=0;d<users_counter;d++)
  7.  
  8.                                    {
  9.  
  10.                                    ubase[d].username[0]                    =           new char [1000];
  11.                                    ubase[d].RID[0]                           =                 new char [50];
  12.                                    //... и так далее <img src="http://exelab.ruimg/smilies/s1.gif" border="0" align="" alt="">
  13.          
  14.                                    };
  15.  
  16.  
  17.  
  18.          for (int i=0;i<users_counter;i++)
  19.  
  20.  
  21.                                    {
  22.  
  23.                               //... тут код
  24.                               //   strncpy (ubase[0].username[0],str[i],strlen (str[i])); // Копируем в базу пользователей наши RID-ы - и получаем ошибку на второй итерации
  25.                               //... и тут код
  26.                                        };
  27.  
  28.  


Flint
спасибо, попробую чисто ради интереса (: проблему решил просто - полностью переписал код по-новой потратил время, конечно. Как ни отлавливал этот баг, никак не понял, в чем он заключается.

-----
Харе курить веники и нюхать клей, к вам едет из Америки бог Шива, и он еврей.




Ранг: 65.3 (постоянный), 10thx
Активность: 0.020
Статус: Участник

Создано: 24 февраля 2011 12:09 · Поправил: tomac
· Личное сообщение · #8

Код к DEP не имеет никакого отношения. Где-то портится память. Причем, совсем не обязательно, что в том участке кода, где падает. Возможно, действительно, в str[i] не было \0. или портился указатель ubase[0].username[0]. Кстати, как userbase[0].username определен и инициализирован?

//Если код переписан по-новому и нормально работает, я бы не стал париться с отключением DEP, а просто использовал новый код.



Ранг: 101.0 (ветеран), 344thx
Активность: 1.150
Статус: Участник

Создано: 24 февраля 2011 12:45
· Личное сообщение · #9

Crawler
Как определено поле username в структуре/классе userbase? Сдается мне, что задумано было так: username[0]




Ранг: 216.9 (наставник), 85thx
Активность: 0.310.15
Статус: Участник
X-Literator

Создано: 24 февраля 2011 15:01
· Личное сообщение · #10

int

ubase[d].username[0] = new char [1000];
все правильно

-----
Харе курить веники и нюхать клей, к вам едет из Америки бог Шива, и он еврей.




Ранг: 419.0 (мудрец), 647thx
Активность: 0.460.51
Статус: Участник
"Тибериумный реверсинг"

Создано: 24 февраля 2011 18:42 · Поправил: ELF_7719116
· Личное сообщение · #11

Crawler
Может дело в static ?? По ходу вы свой нехилый массив запихиваете в стек, который есно не резиновый. В крайнем случае пул выделить для массива



Ранг: 101.0 (ветеран), 344thx
Активность: 1.150
Статус: Участник

Создано: 24 февраля 2011 19:52
· Личное сообщение · #12

Crawler пишет:
ubase[d].username[0] = new char [1000];

Почему 0?

Либо у тебя так:

char *username[];

либо так:

char *username;

Во втором случае никакого нуля не надо (и ubase[d].username = new char [1000];). Это конечно было бы странно, если бы в этом ошибся, но мало ли.



Ранг: 237.0 (наставник), 20thx
Активность: 0.130
Статус: Участник
sysenter

Создано: 24 февраля 2011 21:34
· Личное сообщение · #13

Flint
Сомнительно что это можно динамически.
Crawler
DEP - это из области перекидывания EIP на стек или другую область данных.
Почему бы вам не поставить обработку исключений и посмотреть адрес ошибки
и её причину. см. wasm.ru/forum/viewtopic.php?pid=309996#p309996

-----
продавец резиновых утёнков





Ранг: 238.8 (наставник), 67thx
Активность: 0.20
Статус: Участник
CyberHunter

Создано: 24 февраля 2011 22:07
· Личное сообщение · #14

HiEndsoft пишет:
Flint
Сомнительно что это можно динамически.


Проверьте



77f6_24.02.2011_CRACKLAB.rU.tgz - test_DEP.rar

-----
Nulla aetas ad discendum sera




Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 25 февраля 2011 00:03
· Личное сообщение · #15

Flint
Сервис возвращает STATUS_ACCESS_DENIED изза флажка MEM_EXECUTE_OPTION_PERMANENT, после установки которого повторный вызов сервиса будет отклонён, что собственно и происходит. А устанавливает его загрузчик(можно обнаружить вызов в олли сразу за системным брейком) на основе конфигурации(флажки в реестре и пр.), по дефолту читает параметры из USD, куда они загружаются на основе ключей в бутини при запуске ядра. По тойже причине нельзя использовать сех вне модулей.



Ранг: 53.9 (постоянный), 19thx
Активность: 0.040
Статус: Участник

Создано: 25 февраля 2011 06:23 · Поправил: Zorn
· Личное сообщение · #16

Crawler пишет:
strncpy (ubase[0].username[0],str[i],strlen (str[i]));

Что такое str ? Почему пишем ТОЛЬКО в ubase[0] ? (но это скорей логическая ошибка)

Проблему вижу в следующем: str - массив из 1 строки (опять логическая ошибка где то при заполнении). Отсюда при обращении ко второму элементу получаем Access Violation.

Crawler пишет:
Я ж говорю - в консольной версии работало...

Консольная версия скорей всего была собрана в release (без проверок) и в твою базу писался мусор.



Ранг: 237.0 (наставник), 20thx
Активность: 0.130
Статус: Участник
sysenter

Создано: 25 февраля 2011 10:24 · Поправил: HiEndsoft
· Личное сообщение · #17

Flint
Ваш код ничего не доказывает: при запуске вашего теста - DEP для вашего приложения не включен (не взведён NX бит в PE хидере. Мой проц не поддерживает аппаратный DEP.). Поместите в тестовую программу принудительное вкл. DEP (установите при линковке NX-бит + DWORD flags=1; HANDLE hProcess=LongToHandle(-1); NtSetInformationProcess(hProcess,ProcessExecuteFlags, &flags, 4); ) тогда ещё что-то можно будет рассмотреть. Но насколько помню включать динамически DEP можно, причём hProcess, полученный с соответствующими правам может быть практически любой, а вот отключать "на лету" - нет.

-----
продавец резиновых утёнков




Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 25 февраля 2011 17:04 · Поправил: Clerk
· Личное сообщение · #18

HiEndsoft
Вы меня слышите или нет ?
Какое есчо включите.. имя вашего экзешника нужно зарегать в в конфиге ?
Или мб изменить бутини и выполнить ребут.. это защита установлена авторами намеренно и просто так она не обходится поймите.



Ранг: 237.0 (наставник), 20thx
Активность: 0.130
Статус: Участник
sysenter

Создано: 25 февраля 2011 17:58 · Поправил: HiEndsoft
· Личное сообщение · #19

Clerk
А написал я всё вышеизложенное для того что бы указать Flint что его пример ничего не доказывает.
Включать DEP динамически можно, выключать - нет. Пример из жизни XPSP3, проц без аппаратной поддержки DEP. Мой процесс создаёт дочерний процесс в Job'e в suspend - состоянии (у дочернего в PE установлен NX), затем ч/з NtSetInformationProcess вкл. для дочернего DEP, и он реально включается flags=1; NtSetInformationProcess(pi.hProcess,ProcessExecuteFlags, &flags, 4)=STATUS_SUCCESS, что DEP включился - наглядно видно в том же ProcessExplorer. При этом в винде DEP по умолчанию включен только для осн. служб + PAE. Обратная операция не прокатывает.

-----
продавец резиновых утёнков





Ранг: 238.8 (наставник), 67thx
Активность: 0.20
Статус: Участник
CyberHunter

Создано: 25 февраля 2011 21:10
· Личное сообщение · #20

HiEndsoft в общем спорить не буду, не в полной мере владею информацией ) Однако:

HiEndsoft пишет:
При этом в винде DEP по умолчанию включен только для осн. служб


Сделайте "Включить DEP для всех программ и служб, кроме выбранных ниже:", после перезагрузки запустите test_DEP.exe с адреса 0040101A. Получите исключение. А если начать с OEP, то программа нормально выполнится.

О чем это говорит?

-----
Nulla aetas ad discendum sera




Ранг: 237.0 (наставник), 20thx
Активность: 0.130
Статус: Участник
sysenter

Создано: 25 февраля 2011 22:56
· Личное сообщение · #21

Flint пишет:
О чем это говорит?

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

-----
продавец резиновых утёнков





Ранг: 238.8 (наставник), 67thx
Активность: 0.20
Статус: Участник
CyberHunter

Создано: 25 февраля 2011 23:13
· Личное сообщение · #22

Что есть по-вашему нормальный тест?

-----
Nulla aetas ad discendum sera




Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 25 февраля 2011 23:18
· Личное сообщение · #23

Flint
Вызвать код на стеке, заключив вызывающий код в сех.




Ранг: 238.8 (наставник), 67thx
Активность: 0.20
Статус: Участник
CyberHunter

Создано: 25 февраля 2011 23:37
· Личное сообщение · #24

Clerk

))) Я сам хотел такое предложить, но не стал. Вот он:



a268_25.02.2011_CRACKLAB.rU.tgz - 1.rar

-----
Nulla aetas ad discendum sera



 eXeL@B —› Программирование —› Ошибка выполнения (DEP?)
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати