Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Странное поведение программы под отладчиком и "вживую"

7
31 декабря 2009 года
@pixo $oft
3.4K / / 20.09.2006
Сама программа приложена в аттаче.Причём тут такое дело–если программа запускается в 1й раз(т.е. в реестре отсутствовали значения,которые она читает),то работа проходит нормально,и все значения по окончании оказываются записанными в реестр.Но стоит повторно запустить программу,как она вылетает с ошибкой.Попытка отладки(из диалога ошибки) ничего хорошего не дала,ибо в ней внезапно появляются 2 дополнительных потока,а OllyDbg с ними работает как-то странно(о чём я уже неоднократно спрашивал,но ответа так и не было)
Просмотр Call stack показал,что падает программа в вызове HeapAlloc,в то время как под отладчиком никаких падений не наблюдается
Причём после выбора "Не отправлять" в диалоге ошибки программа ещё и не сразу завершается…ну это так,к слову

Как показали дополнительные тесты,если не будет задан параметр WorkDir,то программа работает как и должна(запрашивает имя папки и завершается нормально),т.е. падение происходит во 2м вызове HeapAlloc

Может кто попробовать у себя это сделать?Кстати,заодно я выложил bat-ник,которым компилировал…ну так,на всякий случай.Хотя от него вряд ли что зависит
И ещё–почему HeapAlloc падает только во 2м случае,и только тогда,когда параметра в реестре не было?

Помогите,пожалуйста,а то я корпел-корпел…ведь не под отладчиком предлагать эту программу исполнять!:D

P.S.Только пути относительные не забудьте подкорректировать;)
Для компиляции требуется наличие Link32.exe и ML.exe
10K
31 декабря 2009 года
palevo060
144 / / 05.09.2009
Падение произошло, только один раз да и то только с 10-го раза и больше никакого падения не происходит.
7
31 декабря 2009 года
@pixo $oft
3.4K / / 20.09.2006
А как упало?У меня–ошибка в NTDLL.dll,0x5.Возникает каждый раз после запуска,если значение WorkDir не установлено,иначе всё работает нормально.В каких условиях испытывал ты?
10K
31 декабря 2009 года
palevo060
144 / / 05.09.2009
Цитата:
Возникает каждый раз после запуска,если значение WorkDir не установлено


Ну как не установлено. Оно если не установлено, то при втором запуске просит меня ввести это значение, тоесть значение будет в любом случае.

Цитата:
HKEY_LOCAL_MACHINE\SOFTWARE\FoldLock



Даже если удалю от сюда.

Цитата:

А как упало?У меня–ошибка в NTDLL.dll,0x5


Упало один раз так что я проглядел, как упало.

7
31 декабря 2009 года
@pixo $oft
3.4K / / 20.09.2006
Блин,во дела!У меня каждый раз падает при установленном значении.Не пойму,что такого во вторичном вызове HeapAlloc
Т.е. у тебя после установки значений программа запускается и сразу выходит?
10K
31 декабря 2009 года
palevo060
144 / / 05.09.2009
Цитата:

Т.е. у тебя после установки значений программа запускается и сразу выходит?



Ага именно так.

Значения я установил такие

Цитата:
Password 1234
WorkDir 123


Так для слова.

10K
31 декабря 2009 года
palevo060
144 / / 05.09.2009
Да и не забывай что у меня компилятор другой Masm32v10 тоже к слову =)

Да может в нем дело так что вот тебе .zip с моей сборкой.
5
31 декабря 2009 года
hardcase
4.5K / / 09.08.2005
Код не смотрел, Пихо, но что-то мне подсказывает что проблема в вызовах функций реестра и выделении памяти под их аргументы.
7
01 января 2010 года
@pixo $oft
3.4K / / 20.09.2006
Дык…хъ,в том-то и проблема,что непонятно с этими функциями.Делал,наблюдая в MSDN,т.е. в соответствии с описанием.Это раз
Далее–здесь же 2 сходных по смыслу участка,поэтому один сделан копипастой другого(естественно,с хорошей отладкой копируемого участка).Но факт остаётся фактом–функции реестра/выделения памяти вызываются и там,и там,но падает только во 2м вызове,и ТОЛЬКО вживую(не под отладчиком)
Как показали единичные эксперименты,падает гарантированно только у меня.Желающие могут скачать компиляцию от palevo060 и затестить
260
01 января 2010 года
Ramon
1.1K / / 16.08.2003
Читать, компилировать и запускать - лень, приложите дамп упавшего приложения.
7
01 января 2010 года
@pixo $oft
3.4K / / 20.09.2006
Что самое интересное–я сейчас запустил приложение(в реестре записей не было),ввёл,что требовалось,оно закрылось и я запустил ещё раз.Прошло без ошибок.Но последующие разы–одно сплошное падение…:(
И ещё вопрос–а как мне дамп скопировать?Он защищён даже от чтения(интересно,зачем?)
260
01 января 2010 года
Ramon
1.1K / / 16.08.2003
При так называемом "падении" вылезает тряпка, аля отослать гадость мелкомягкому. Дамп можно снять практически любым уважающим себя зарегенным в системе отладчиком, ткнув на той тряпке "Отладка", а в поднявшемся отладчике на соотв. пункт меню.

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

PS: Ах да, можно и убогого доктора ватсона заюзать.
7
01 января 2010 года
@pixo $oft
3.4K / / 20.09.2006
Почему "тряпка"?
А в качестве гадости только appcompat.txt.Его скопировать можно,а вот дамп нет.Dr. Watson отключен

Собственно,вопрос решился только с использованием Unlocker'а[COLOR="Gray"](кстати,подскажите,пожалуйста,его официальный сайт,а то мало ли…в комплекте с установкой были какие-то 2 файла без расширения,изнутри явно .exe)[/COLOR],ибо OllyDbg,к сожалению,дампать не умеет(по крайней мере,я не нашёл),а отладчик VS 2005 по какой-то причине потребовал переустановки(только вчера всё работало)
Файлы прилагаю

Upd:сравнение моего и скомпилированного палевом екзешника показало следующее:
Цитата:
Ошибка сравнения: Смещение 80
файл1 = 68
файл2 = F5
Ошибка сравнения: Смещение 82
файл1 = 6F
файл2 = 8D
Ошибка сравнения: Смещение 83
файл1 = FB
файл2 = D7
Ошибка сравнения: Смещение 84
файл1 = 2C
файл2 = B1
Ошибка сравнения: Смещение 86
файл1 = 1
файл2 = E3
Ошибка сравнения: Смещение 87
файл1 = A8
файл2 = 84
Ошибка сравнения: Смещение 88
файл1 = 2C
файл2 = B1
Ошибка сравнения: Смещение 8A
файл1 = 1
файл2 = E3
Ошибка сравнения: Смещение 8B
файл1 = A8
файл2 = 84
Ошибка сравнения: Смещение 8C
файл1 = 2C
файл2 = B1

Что интересного может находиться по тем смещениям?

10K
01 января 2010 года
palevo060
144 / / 05.09.2009
Как так не дампится. А лорда не пробовал. Там найдешь приложение, потом правой кнопкой, full dump и все.
260
01 января 2010 года
Ramon
1.1K / / 16.08.2003
Диагноз - нагадили в кучку :D
7
01 января 2010 года
@pixo $oft
3.4K / / 20.09.2006
palevo060,ну его…Кстати,есть PETools,там вроде что-то похожее есть.Ну и вообще,я уже сдампал:)
Ramon,а точнее(ну чтоб я понял:))?И есть ли решение?
260
01 января 2010 года
Ramon
1.1K / / 16.08.2003
Записали по указателю больше чем выделили и тем самым загадили кучку. Ибо беглый просмотр кода говорит о более менее верных параметрах у хипаллока.
7
01 января 2010 года
@pixo $oft
3.4K / / 20.09.2006
Дык в том-то и дело,что я пишу не больше,чем выделяю.Это раз
Под отладчиком бы тоже вставало,так нет же,выполняется на ура!Это два
У меня 1 раз(о да,только 1) сработало нормально.Это 3[COLOR="Gray"](впрочем,это можно не учитывать…)[/COLOR]
260
02 января 2010 года
Ramon
1.1K / / 16.08.2003
Цитата: @pixo $oft
Дык в том-то и дело,что я пишу не больше,чем выделяю.Это раз
Под отладчиком бы тоже вставало,так нет же,выполняется на ура!Это два
У меня 1 раз(о да,только 1) сработало нормально.Это 3[COLOR="Gray"](впрочем,это можно не учитывать…)[/COLOR]


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

Ключ же к источнику ваших заблуждений:

 
Код:
Invoke HeapAlloc,hHeap,EBX,EAX
    Mov lpszPwd,EAX
    Invoke lStrCpy,EAX,ESI
    [COLOR="Red"]Mov dwBytes,SizeOf cBuf        ;Проверка на наличие заданного имени папки[/COLOR]
    Invoke RegQueryValueEx,hKey,Addr szDirVal,EBX,EBX,EAX,Addr dwBytes
7
02 января 2010 года
@pixo $oft
3.4K / / 20.09.2006
Риальне накосячил!Ramon,спасибо,что не отказался покопаться в моём [COLOR="Silver"]быдлокоде[/COLOR] великом творении,большой † тебе за это!
Только ошибочка была не в этом месте,а строчкой ниже.Я обчитался MSDN'а("If the function succeeds, the return value is a pointer to the buffer") и перепутал буфера,поэтому в EAX у меня оказывался адрес на память в куче,что,естественно,было неверно.Заменив в RegQueryValueEx EAX на EDI,я справился с проблемой

Но,ЧСХ,под отладчиком-то не падает!:D Почему хоть?(чисто спортивный вопрос…ну или почти)

P.S.Во время отладки заметил,что в буфере оказывается Unicode-строка,затёртая строкой ANSI.Внимательно вчитавшись,я понял,что дело в этом
Цитата:
If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, and the ANSI version of this function is used (either by explicitly calling RegQueryValueExA or by not defining UNICODE before including the Windows.h file), this function converts the stored Unicode string to an ANSI string before copying it to the buffer pointed to by lpData

НО!..Тут же написано,что преобразование в ANSI происходит ДО копирования в буфер.В моём же случае выходит,что преобразование происходит там же,в буфере.Получается,что надо выделять буфер двойного размера!
Можете как-нибудь прокомменитировать это?

260
02 января 2010 года
Ramon
1.1K / / 16.08.2003
Цитата: @pixo $oft
Риальне накосячил!Ramon,спасибо,что не отказался покопаться в моём [COLOR="Silver"]быдлокоде[/COLOR] великом творении,большой † тебе за это!
Только ошибочка была не в этом месте,а строчкой ниже.Я обчитался MSDN'а("If the function succeeds, the return value is a pointer to the buffer") и перепутал буфера,поэтому в EAX у меня оказывался адрес на память в куче,что,естественно,было неверно.Заменив в RegQueryValueEx EAX на EDI,я справился с проблемой

Но,ЧСХ,под отладчиком-то не падает!:D Почему хоть?(чисто спортивный вопрос…ну или почти)

P.S.Во время отладки заметил,что в буфере оказывается Unicode-строка,затёртая строкой ANSI.Внимательно вчитавшись,я понял,что дело в этомНО!..Тут же написано,что преобразование в ANSI происходит ДО копирования в буфер.В моём же случае выходит,что преобразование происходит там же,в буфере.Получается,что надо выделять буфер двойного размера!
Можете как-нибудь прокомменитировать это?



Все именно так, передается буфер и размер больше чем есть на самом деле, а ф-ция юзает его же для конвертации ибо в реестре все юникодное да и размер то "подходящий", зачем новый выделять?

PS: А то что под отладчиком не падает - так сложились звезды внутри кучкинного аллокатора, да и размер пути важен ибо в кучке аллоцируются не точное кол-во которое запросили, а кратное некому минимальному.
PS2: И по хорошему семантика использования RegQueryValueEx несколько иная.

7
02 января 2010 года
@pixo $oft
3.4K / / 20.09.2006
Цитата: Ramon
Все именно так, передается буфер и размер больше чем есть на самом деле, а ф-ция юзает его же для конвертации ибо в реестре все юникодное да и размер то "подходящий", зачем новый выделять?

Хм,но ведь,как там говорится,"размер буфера должен быть достаточной длины,чтобы вместить значение",и про Unicode ничего не говорится.Т.е. если я знаю(или я быдлокодер и использую жёсткую привязку),что у меня значение !>N символов(+1 для \0),то я и выделю буфер размером N.А на деле окажется,что надо было выделять в 2 раза больше,ибо функции,видите ли,захотелось конвертить в моём буфере

Цитата: Ramon
PS: А то что под отладчиком не падает - так сложились звезды внутри кучкинного аллокатора, да и размер пути важен ибо в кучке аллоцируются не точное кол-во которое запросили, а кратное некому минимальному.

Странно,но звёзды складывались так каждый раз:)
Размер пути–в смысле длина моего параметра WorkDir?Так она всегда постоянной была.И программа всегда запускалась из одной локации.В общем,исходные данные при запуске вживую и под отладчиком были одинаковы…настолько,насколько они могут быть одинаковы при этом(наверняка отладчик что-то да вносит при отладке)

Цитата: Ramon
PS2: И по хорошему семантика использования RegQueryValueEx несколько иная.

Если можно,хотелось бы узнать поточнее.Ибо я читал MSDN перед тем,как всё это делать

P.S.Заменю потом на RegGetValue–там специально адаптировано для строковых значений и вроде есть отсев по типу значения

260
02 января 2010 года
Ramon
1.1K / / 16.08.2003
Цитата: @pixo $oft
Хм,но ведь,как там говорится,"размер буфера должен быть достаточной длины,чтобы вместить значение",и про Unicode ничего не говорится.Т.е. если я знаю(или я быдлокодер и использую жёсткую привязку),что у меня значение !>N символов(+1 для \0),то я и выделю буфер размером N.А на деле окажется,что надо было выделять в 2 раза больше,ибо функции,видите ли,захотелось конвертить в моём буфере



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

260
02 января 2010 года
Ramon
1.1K / / 16.08.2003
Цитата: @pixo $oft
Странно,но звёзды складывались так каждый раз:)
Размер пути–в смысле длина моего параметра WorkDir?Так она всегда постоянной была.И программа всегда запускалась из одной локации.В общем,исходные данные при запуске вживую и под отладчиком были одинаковы…настолько,насколько они могут быть одинаковы при этом(наверняка отладчик что-то да вносит при отладке)



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

PS: И вообще пишите как минимум на Ц :D

260
02 января 2010 года
Ramon
1.1K / / 16.08.2003
Цитата: @pixo $oft
Если можно,хотелось бы узнать поточнее.Ибо я читал MSDN перед тем,как всё это делать



Цитата:
If the buffer specified by lpData parameter is not large enough to hold the data, the function returns ERROR_MORE_DATA and stores the required buffer size in the variable pointed to by lpcbData. In this case, the contents of the lpData buffer are undefined.



По-хорошему сие стоит учитывать.

7
02 января 2010 года
@pixo $oft
3.4K / / 20.09.2006
А,ну да;прочитать-то это я прочитал.Пока что тестовая версия,посему много что делается без оглядки на это(помнится,кто-то писал про вред преждевременной оптимизации)
Также понял,что надо было применить процедурный подход,а то у меня программа–один сплошной кусок текста.Например,в меню будет пункт "Сменить пароль",так нафига ж я буду заново копировать участок из приведённой ниже программы?Почему сейчас буду переделывать процедурно

Спасибо за ответы.И за юмор (=
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог