Странное поведение программы под отладчиком и "вживую"
Просмотр Call stack показал,что падает программа в вызове HeapAlloc,в то время как под отладчиком никаких падений не наблюдается
Причём после выбора "Не отправлять" в диалоге ошибки программа ещё и не сразу завершается…ну это так,к слову
Как показали дополнительные тесты,если не будет задан параметр WorkDir,то программа работает как и должна(запрашивает имя папки и завершается нормально),т.е. падение происходит во 2м вызове HeapAlloc
Может кто попробовать у себя это сделать?Кстати,заодно я выложил bat-ник,которым компилировал…ну так,на всякий случай.Хотя от него вряд ли что зависит
И ещё–почему HeapAlloc падает только во 2м случае,и только тогда,когда параметра в реестре не было?
Помогите,пожалуйста,а то я корпел-корпел…ведь не под отладчиком предлагать эту программу исполнять!:D
P.S.Только пути относительные не забудьте подкорректировать;)
Для компиляции требуется наличие Link32.exe и ML.exe
Ну как не установлено. Оно если не установлено, то при втором запуске просит меня ввести это значение, тоесть значение будет в любом случае.
Даже если удалю от сюда.
А как упало?У меня–ошибка в NTDLL.dll,0x5
Упало один раз так что я проглядел, как упало.
Т.е. у тебя после установки значений программа запускается и сразу выходит?
Т.е. у тебя после установки значений программа запускается и сразу выходит?
Ага именно так.
Значения я установил такие
WorkDir 123
Так для слова.
Да может в нем дело так что вот тебе .zip с моей сборкой.
Далее–здесь же 2 сходных по смыслу участка,поэтому один сделан копипастой другого(естественно,с хорошей отладкой копируемого участка).Но факт остаётся фактом–функции реестра/выделения памяти вызываются и там,и там,но падает только во 2м вызове,и ТОЛЬКО вживую(не под отладчиком)
Как показали единичные эксперименты,падает гарантированно только у меня.Желающие могут скачать компиляцию от palevo060 и затестить
И ещё вопрос–а как мне дамп скопировать?Он защищён даже от чтения(интересно,зачем?)
А если совсем по тупому, все на той же тряпке в технических подробностях есть путь к отправляемой гадости, эта гадость тоже сгодится.
PS: Ах да, можно и убогого доктора ватсона заюзать.
А в качестве гадости только appcompat.txt.Его скопировать можно,а вот дамп нет.Dr. Watson отключен
Собственно,вопрос решился только с использованием Unlocker'а[COLOR="Gray"](кстати,подскажите,пожалуйста,его официальный сайт,а то мало ли…в комплекте с установкой были какие-то 2 файла без расширения,изнутри явно .exe)[/COLOR],ибо OllyDbg,к сожалению,дампать не умеет(по крайней мере,я не нашёл),а отладчик VS 2005 по какой-то причине потребовал переустановки(только вчера всё работало)
Файлы прилагаю
Upd:сравнение моего и скомпилированного палевом екзешника показало следующее:
файл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
Что интересного может находиться по тем смещениям?
Ramon,а точнее(ну чтоб я понял:))?И есть ли решение?
Под отладчиком бы тоже вставало,так нет же,выполняется на ура!Это два
У меня 1 раз(о да,только 1) сработало нормально.Это 3[COLOR="Gray"](впрочем,это можно не учитывать…)[/COLOR]
Под отладчиком бы тоже вставало,так нет же,выполняется на ура!Это два
У меня 1 раз(о да,только 1) сработало нормально.Это 3[COLOR="Gray"](впрочем,это можно не учитывать…)[/COLOR]
На самом деле все не так, вы действительно всегда гадите в кучку, косвенно, но гадите. А результат гажения в кучку может не проявляться, но это не значит, что оно отсутствует.
Ключ же к источнику ваших заблуждений:
Mov lpszPwd,EAX
Invoke lStrCpy,EAX,ESI
[COLOR="Red"]Mov dwBytes,SizeOf cBuf ;Проверка на наличие заданного имени папки[/COLOR]
Invoke RegQueryValueEx,hKey,Addr szDirVal,EBX,EBX,EAX,Addr dwBytes
Только ошибочка была не в этом месте,а строчкой ниже.Я обчитался MSDN'а("If the function succeeds, the return value is a pointer to the buffer") и перепутал буфера,поэтому в EAX у меня оказывался адрес на память в куче,что,естественно,было неверно.Заменив в RegQueryValueEx EAX на EDI,я справился с проблемой
Но,ЧСХ,под отладчиком-то не падает!:D Почему хоть?(чисто спортивный вопрос…ну или почти)
P.S.Во время отладки заметил,что в буфере оказывается Unicode-строка,затёртая строкой ANSI.Внимательно вчитавшись,я понял,что дело в этом
НО!..Тут же написано,что преобразование в ANSI происходит ДО копирования в буфер.В моём же случае выходит,что преобразование происходит там же,в буфере.Получается,что надо выделять буфер двойного размера!
Можете как-нибудь прокомменитировать это?
Только ошибочка была не в этом месте,а строчкой ниже.Я обчитался 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 несколько иная.
Хм,но ведь,как там говорится,"размер буфера должен быть достаточной длины,чтобы вместить значение",и про Unicode ничего не говорится.Т.е. если я знаю(или я быдлокодер и использую жёсткую привязку),что у меня значение !>N символов(+1 для \0),то я и выделю буфер размером N.А на деле окажется,что надо было выделять в 2 раза больше,ибо функции,видите ли,захотелось конвертить в моём буфере
Странно,но звёзды складывались так каждый раз:)
Размер пути–в смысле длина моего параметра WorkDir?Так она всегда постоянной была.И программа всегда запускалась из одной локации.В общем,исходные данные при запуске вживую и под отладчиком были одинаковы…настолько,насколько они могут быть одинаковы при этом(наверняка отладчик что-то да вносит при отладке)
Если можно,хотелось бы узнать поточнее.Ибо я читал MSDN перед тем,как всё это делать
P.S.Заменю потом на RegGetValue–там специально адаптировано для строковых значений и вроде есть отсев по типу значения
Ей "захотелось" оптимизировать процесс ибо переданный ей буфер достаточный для сохранения в нем юникодной строки с последующей конвертацией, зачем что-то аллоцировать если это уже есть.
Размер пути–в смысле длина моего параметра WorkDir?Так она всегда постоянной была.И программа всегда запускалась из одной локации.В общем,исходные данные при запуске вживую и под отладчиком были одинаковы…настолько,насколько они могут быть одинаковы при этом(наверняка отладчик что-то да вносит при отладке)
На сколько они одинаковые это вопрос ибо что делает отладчик - это все на его совести, да и алгоритмы распределения и верификации в кучке такие же особенные. Отладка гаженья в кучку - дело вообще неблагодарное, особенно если это не 10 строчек и приложение многопоточное, радости бывает полные штаны. Посему за ресурсами следует следить внимательно, особенно за памятью, хотя все это и боян.
PS: И вообще пишите как минимум на Ц :D
По-хорошему сие стоит учитывать.
Также понял,что надо было применить процедурный подход,а то у меня программа–один сплошной кусок текста.Например,в меню будет пункт "Сменить пароль",так нафига ж я буду заново копировать участок из приведённой ниже программы?Почему сейчас буду переделывать процедурно
Спасибо за ответы.И за юмор (=