Blog. Just Blog

Управление редактором реестра из своего приложения

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Наверняка вы слышали о программе RegJump от SysInternals, ныне принадлежащая Microsoft. При помощи этой программы вы можете открыть regedit сразу же на нужной ветке реестра. Мне стало очень интересно, как она это делает. Дизассемблер в руки, отладчик в боевую готовность и вперед!

Вот что мне удалось накопать. Я оставил только самый важный код, попутно упростив и оптимизировав его. Оригинальный RegJump сперва пытается найти запущенный regedit по наименованию класса окна, если такого нет, то пытается запустить regedit из системной папки. Так или иначе, вся работа выполняется с найденным окном. У меня подразумевается, что редактор реестра уже запущен.
  1. section '.data' data readable writeable
  2.  
  3. ; Классы окон для поиска
  4. szClass db 'RegEdit_RegEdit',0
  5. szList  db 'SysTreeView32',0
  6. ; Название ветки реестра
  7. szReg   db '\HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\WINDOWS\CURRENTVERSION\',0
Наименование ветки реестра, куда надо перейти, переводится в верхний регистр, а в начало и конец строки прицепляется символ "\". Традиционные сокращения типа "HKLM" разворачиваются в полноценные наименования веток реестра "HKEY_LOCAL_MACHINE" и т.п. Я надеюсь, с подобным преобразованием строки у вас проблем возникнуть не должно. У меня строка сразу приведена в должный вид.

Хэндл процесса необходим для синхронизации пользовательского ввода с окном приложения, поскольку все управление regedit выполняется через эмуляцию нажатий клавиш в списке. Для "своей" копии regedit, которая запущена RegJump, используется результат выполнения функции CreateProcess, для запущенного ранее экземпляра хэндл получается через пару функций GetWindowThreadProcessId и OpenProcess. Особых привилегий для этого не надо.
  1.         ; Найти окно редактора реестра
  2.         invoke  FindWindow,szClass,NULL
  3.         or      eax,eax
  4.         jz      loc_exit
  5.         mov     [hRWnd],eax
  6.  
  7.         ; Найти список в окне редактора реестра
  8.         invoke  FindWindowEx,[hRWnd],NULL,szList,NULL
  9.         or      eax,eax
  10.         jz      loc_exit
  11.         mov     [hWnd],eax
  12.  
  13.         ; Получить хэндл процесса-владельца
  14.         invoke  GetWindowThreadProcessId,[hRWnd],ProcessId
  15.         invoke  OpenProcess,PROCESS_QUERY_INFORMATION,0,[ProcessId]
  16.         or      eax,eax
  17.         jz      loc_exit
  18.         mov     [hProcess],eax
  19.  
  20.         ; Активировать окно редактора реестра
  21.         invoke  ShowWindow,[hRWnd],SW_RESTORE
  22.         invoke  SetForegroundWindow,[hRWnd]
  23.         ; Установить фокус на список
  24.         invoke  SetFocus,[hWnd]
  25.         invoke  WaitForInputIdle,[hProcess],-1
  26.  
  27.         ; Вот тут непонятно :(
  28.         invoke  SendMessage,[hRWnd],WM_COMMAND,10288h,0
  29.         invoke  WaitForInputIdle,[hProcess],-1
  30.  
  31.         ; Перейти на верхний уровень списка
  32.         mov     ebx,30
  33. @@:
  34.         invoke  SendMessage,[hWnd],WM_KEYDOWN,VK_LEFT,0
  35.         invoke  WaitForInputIdle,[hProcess],-1
  36.         sub     ebx,1
  37.         jnz     @b
  38.  
  39.         ; Указатель на строку в названием ветки реестра
  40.         mov     esi,szReg
  41. loc_loop:
  42.         lodsb
  43.         or      al,al
  44.         jz      loc_exit_clean
  45.  
  46.         cmp     al,'\'
  47.         jne     @f
  48.         ; Открыть ветку списка
  49.         invoke  SendMessage,[hWnd],WM_KEYDOWN,VK_RIGHT,0
  50.         invoke  WaitForInputIdle,[hProcess],-1
  51.         jmp     loc_loop
  52. @@:
  53.         movzx   eax,al
  54.         ; Поиск строки в списке
  55.         invoke  SendMessage,[hWnd],WM_CHAR,eax,0
  56.         invoke  WaitForInputIdle,[hProcess],-1
  57.         jmp     loc_loop
  58. loc_exit_clean:
  59.         invoke  CloseHandle,[hProcess]
  60.  
  61. loc_exit:
Когда все нужные окна найдены и хэндл процесса получен, начинается эмуляция нажатий клавиш. Сперва выполняется переход на самый верхний уровень списка. Судя по коду, Марк Руссинович предположил, что глубже 30-го уровня списка зайти невозможно, что ж, ему виднее. Затем начинается обработка строки с нужным названием ветки реестра. Строка обрабатывается посимвольно, когда встретится символ "\", то эмулируется нажатие стрелки вправо для открытия нужного уровня списка и перехода на него. Именно для этого исходная строка дополняется в начале и в конце этим символом. Строковые символы из строки передаются в поиск, тем самым определяя следующий уровень списка. Как видите, никаких ракетных технологий, но лично мне было очень интересно посмотреть на решение этой задачи от одного из признанных знатоков внутренностей Windows.

В приложении пример программы с исходным текстом, которая открывает в уже запущенном редакторе реестра ветку HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

RegJump.Demo.zip (2,020 bytes)


Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 223 | Комментариев: 3

Комментарии

Отзывы посетителей сайта о статье
Compiller (12.06.2020 в 14:45):
Registry Studio (который древний от Microplanet) умел ещё и встраиваться в регедит,и визуальные закладки, и предпросмотр reg файлов, и свой формат закладок с url дляоткрытия из проводника, и мультитредовый поиск и замену
Но на новых виндах глючит :-(.

На новых виндах 10 не рисует окно и меню. На Ctrl+R (хоткей для поиска изамены) отзывается.
На Ctrl+S (тот самый поиск в несколько тредов) тоже.
Сама программа вроде как слегка расширенная надстройка над регедитом.
Вы её по моей просьбе раньше правили... За что вам большущее человеческое СПАСИБО!

В Windows 10 уже встроена своя строка адреса в регедит - она делает почтито же самое, что и старые regeditx.
ManHunter (06.06.2020 в 12:00):
Ничего удивительного, тема же интересная. Только у меня исходников не было, пришлось восстанавливать по коду.
PB (06.06.2020 в 11:23):
Полтора года назад читал то же самое на форуме ПуреБасик.Только без истории про дизассемблер, ткпо исходник с Делфи переписали на purebasic.

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2020
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0034 сек.) / Память: 5 Mb
Наверх