Зависает комп при выполнении главной функции DLL

Тема в разделе "WASM.WIN32", создана пользователем piritus, 14 май 2009.

  1. piritus

    piritus Member

    Публикаций:
    0
    Регистрация:
    7 июл 2007
    Сообщения:
    36
    Здравствуйте.
    код гдавной функции библиотеки:
    Код (Text):
    1. ...
    2. invoke RegOpenKeyEx,HKEY_LOCAL_MACHINE,offset SubKey,0,KEY_QUERY_VALUE,offset hKey  
    3. invoke RegQueryInfoKey, hKey,0,0,0,0,0,0,0,0,offset hValue,0,0      
    4. invoke RegCloseKey,hKey    
    5.  
    6. invoke GetLocalTime,addr systime
    7. mov dateaddr, eax
    8.  
    9. loop1:
    10. invoke RegOpenKeyEx,HKEY_LOCAL_MACHINE,offset SubKey,0,KEY_CREATE_SUB_KEY or KEY_SET_VALUE,offset hKey
    11. .if eax == ERROR_SUCCESS  
    12.     invoke RegSetValueEx,hKey,offset RegValue,0,REG_DWORD,offset szBuffer3,DWORD
    13. .endif     
    14. invoke RegCloseKey,hKey
    15.  
    16. .if
    17. ;условие....
    18. jmp loop1
    19. .endif
    20.  
    21. invoke RegOpenKeyEx,HKEY_LOCAL_MACHINE,offset SubKey,0,KEY_CREATE_SUB_KEY or KEY_SET_VALUE,offset hKey
    22. .if eax == ERROR_SUCCESS  
    23.     invoke RegSetValueEx,hKey,offset RegValue,0,REG_DWORD,offset szBuffer,DWORD
    24. .endif     
    25. invoke RegCloseKey,hKey
    26. ;invoke Sleep,1000
    27. jmp loop1
    При загрузке компьютера загружается эта библиотека и комп. зависает.
    Если этот код использовать не в библиотеке, а в exe'шнике, то всё нормально работает.
    В чем может быть проблема?
    С уважением, Илья
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Конечно виснет, выже поток не отпускаете из цикла, при подгрузке вашего модуля к системному процессу он не может дальше отработать. Нужно тред создать и в нём чёрные дела делать. А так вобщем не делается. Нужно ждать изменение на сервисе(NtNotifyChangeKey/NtNotifyChangeMultipleKeys), либо в апи RegNotifyChangeKeyValue(), затем когда оно произошло писать реестр.
     
  3. piritus

    piritus Member

    Публикаций:
    0
    Регистрация:
    7 июл 2007
    Сообщения:
    36
    Благодарю.
     
  4. piritus

    piritus Member

    Публикаций:
    0
    Регистрация:
    7 июл 2007
    Сообщения:
    36
    Наверное, я что-то не так делаю...
    Вот новый код:
    Нужно, что бы проверка на неизменность ключа была постоянно, но если ее поручать треду, то главня функция его запустит и перейдет к ret, и всё будет завершено, т.е. в любом случае, главная функция не должна никогда завершаться. Я так понимаю...

    Когда эту библиотеку регистрирую в автозапуске, то она запускается (без перезагрузки системы). Но нельзя запустить ни одно приложение (в т.ч. regedit) и нормально перезагрузить компьютер. Только если из
    "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs" удалить эту библиотеку заранее написанной для этого программой, то система восстанавливает работоспособность и выше приведеннй код нормально работает(т.е. я изменяю ключ реестра, который библиотека контролирует и он тут же меняется обратно). Но если опять просто вписать в "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs" имя библиотеки, то комп вешается и возобнавляет работоспособность только после удаления из AppInit_DLLs имени библиотеки специальной программой для этого. (Т.к. regedit опять отказывается запускаться, как и любая другая программа, кроме Explorer'а, т.е. мой компьтер)

    Старался как можно более подробно изложить суть проблемы. Скажите, пожалуйста, чем может быть вызвана такая реакция на рапись в AppInit_DLLs (всё происходило даже без перезагрузки)?
     
  5. piritus

    piritus Member

    Публикаций:
    0
    Регистрация:
    7 июл 2007
    Сообщения:
    36
    Наверное из-за того, что библиотеки из AppInit_DLLs подгружаются ко всем приложениям, использующим User32.dll
    Не досмотрел...
     
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Сказал ведь, поток создай который будет крутится в цикле этом, а главный тред продолжит исполнение загрузчика.
     
  7. piritus

    piritus Member

    Публикаций:
    0
    Регистрация:
    7 июл 2007
    Сообщения:
    36
    Сделал.
    Для проверки в тред написал:
    Код (Text):
    1. invoke MessageBox,NULL,$CTA0("TEST"),$CTA0("TEST"),MB_OK
    2. ;invoke ExitThread,NULL
    3. ret
    Теперь приложение загружается (например calc.exe), но в это же время вылезает бесконечное множество
    MessageBox'ов - помогает только перезагрузка. В главном процессе нет цикла, только:
    Код (Text):
    1. invoke CreateThread,NULL,NULL,offset SetReg,0,0,ADDR ThreadID
    2. invoke CloseHandle,eax
    3. ret
    Почему идет бесконечный цикл и как вырубить этот тред?
     
  8. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Либа ко всем GUI-процессам грузится, разумеется нужно определить что модуль уже был загружен к другому процессу. Напимер атом создай, или эвент именованный и чекай его.
     
  9. onSide

    onSide New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2008
    Сообщения:
    476
    Помоему из аппинит грузится к новым процессам. Сомневаюь что у него процессы бесконечно создаются, наверное где-то в коде напорол))
     
  10. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    onSide
    После ребута они все новые, хотя точно сказать нельзя.
     
  11. piritus

    piritus Member

    Публикаций:
    0
    Регистрация:
    7 июл 2007
    Сообщения:
    36
    Посмотрите, может что-то в коде?
    Код (Text):
    1. DllEntry proc hInst:HINSTANCE, reason:DWORD, reserved1:DWORD
    2.     invoke GetModuleFileName,NULL,offset szBufferHost,64
    3.     invoke lstrlen,offset szBufferHost
    4.     invoke CharLowerBuff,offset szBufferHost,eax
    5.  
    6.     invoke StrStr,offset szBufferHost,offset szHost ;поиск подстроки "\calc.exe"
    7.     .if eax
    8.         mov  eax,offset SetReg
    9.         invoke CreateThread,NULL,NULL,eax,0,0,ADDR ThreadID
    10.         invoke CloseHandle,eax
    11.     .endif
    12.  
    13.     ret
    14. DllEntry Endp
    15.  
    16. SetReg proc USES ecx param:DWORD
    17.     invoke MessageBox,NULL,$CTA0("TEST"),$CTA0("TEST"),MB_OK
    18.  
    19.     ret
    20. SetReg endp
    При запуске калькулятора вылазят сообщения без остановки...
     
  12. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Причину чекать надо, фильтруй аттачь.
     
  13. onSide

    onSide New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2008
    Сообщения:
    476
    Это ты специально так оптимизировал ?)) Просто мне это кажется немного запутанным и ненаглядным...
    Во-первых добавь что-то вроде
    mov eax,reason
    cmp eax, DLL_PROCESS_ATTACH
    jz some_proc
    т.е. обрабатывай нормально атач и детач. Твои действия должны производится на атаче.
    и возвращай TRUE вконце DllMain если все прошло успешно.
     
  14. onSide

    onSide New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2008
    Сообщения:
    476
    Clerk опередил...
     
  15. piritus

    piritus Member

    Публикаций:
    0
    Регистрация:
    7 июл 2007
    Сообщения:
    36
    Добавил:
    Код (Text):
    1. mov eax,reason ;без этого
    2. cmp eax, DLL_PROCESS_ATTACH ;множество раз выполнялся поток
    3. jnz exit_dll
    4. ...
    5. mov  eax,offset SetReg
    6. invoke CreateThread,NULL,NULL,eax,0,0,ADDR ThreadID
    7. invoke CloseHandle,eax
    8. ...
    9. exit_dll:
    10. xor eax,eax ;без этого
    11. inc eax ;вылезала ошибка
    12. ret
    и всё пошло как надо :)
    Всем спасибо, очень помогли.
     
  16. onSide

    onSide New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2008
    Сообщения:
    476
    Блин...ты бы хоть документацию прочитал, особенно про ф-цию DllMain и о том что она должна возвращать.

    exit_dll у тебя делает не то что надо, когда возвращаешь TRUE длл остается в памяти процесса, когда FALSE - выгружается, что и надо тебе в данном случае.
    А у тебя она всегда в памяти остается.
     
  17. piritus

    piritus Member

    Публикаций:
    0
    Регистрация:
    7 июл 2007
    Сообщения:
    36
    Уже прочитал :). Добавил обработку DLL_PROCESS_DETACH
    Всё примеры библиотек искал, а документацию сразу не додумался прочитать. Стыдно... :)