Ассемблер: получаем имя файла оболочки
В этой статье я расскажу, как можно программно получить имя файла оболочки Windows. Зачем это нужно? Например, есть программа, которая инжектит свою библиотеку в работающую копию explorer.exe и при этом подразумевает, что такой процесс в системе гарантированно должен присутствовать. В подавляющем большинстве случаев действительно все работает, никаких нареканий нет. Но стоит запустить программу под альтернативным шеллом, например, Aston Desktop, и она неизбежно падает с ошибкой, потому что explorer.exe в системе вообще не запущен. Проверки на соответствие оболочки в программе нет, и вместо корректного информирования пользователя о причинах невозможности запуска мы получаем фатальное падение. И хорошо, если не вместе с системой.Чтобы найти процесс оболочки, сперва надо определить ее главное окно. В MSDN для этого рекомендуют воспользоваться следующим кодом:
Code (Assembler) : Убрать нумерацию
- ; Найти окно с классом "Progman"
- invoke FindWindow, szClass, NULL
- ...
- szClass db 'Progman',0
Более правильный путь - использование функции WinAPI GetShellWindow. Долгое время она относилась к недокументированным, но сейчас ситуация улучшилась. Как гласит официальная документация, с ее помощью можно получить хэндл главного окна, принадлежащего процессу оболочки. В случае успеха нам останется только запросить идентификатор процесса, который относится к этому окну при помощи функции GetWindowThreadProcessId, после чего можно будет получить любую информацию о процессе. Но в рамках этой статьи я не буду в это углубляться, ограничусь только простым перебором списка процессов, чтобы узнать имя исполняемого файла оболочки.
Code (Assembler) : Убрать нумерацию
- ; Получить хэндл главного окна оболочки
- invoke GetShellWindow
- or eax,eax
- jnz @f
- shell_not_found:
- ; Скорее всего используется альтернативная оболочка
- invoke MessageBox,0,szNo,szShell,0
- jmp loc_exit
- @@:
- ; Получить ID процесса, связанного с этим окном
- invoke GetWindowThreadProcessId,eax,pID
- ; Перебрать все активные процессы
- invoke CreateToolhelp32Snapshot,TH32CS_SNAPPROCESS,NULL
- mov esi,eax
- mov eax,sizeof.PROCESSENTRY32
- mov [ProcEntry.dwSize],eax
- invoke Process32First,esi,ProcEntry
- @@:
- cmp eax,FALSE
- je shell_not_found
- ; ID процессов равны, оболочка найдена
- mov eax,[ProcEntry.th32ProcessID]
- cmp eax,[pID]
- je @f
- invoke Process32Next,esi,ProcEntry
- or eax,eax
- ; Невероятно, но ничего не найдено
- jz shell_not_found
- jmp @b
- @@:
- ; EAX -> имя файла оболочки
- lea eax,[ProcEntry.szExeFile]
Code (Assembler) : Убрать нумерацию
- ;-------------------------------------------------
- ; Прочитать ключ из HKEY_CURRENT_USER
- ;-------------------------------------------------
- read_registry_user:
- ; Открыть ключ реестра
- invoke RegOpenKey,HKEY_CURRENT_USER,szReg,phkResult
- or eax,eax
- jnz read_registry_machine
- ; Получить информацию из реестра
- mov [buffSize],MAX_PATH
- invoke RegQueryValueEx,[phkResult],szKey,0,lpdwDisp,buff,buffSize
- or eax,eax
- jz @f
- mov [buffSize],0
- @@:
- ; Закрыть
- invoke RegCloseKey,[phkResult]
- cmp [buffSize],0
- je read_registry_machine
- ; buff -> имя файла оболочки
- ...
- ;-------------------------------------------------
- ; Прочитать ключ из HKEY_LOCAL_MACHINE
- ;-------------------------------------------------
- read_registry_machine:
- ; Открыть ключ реестра
- invoke RegOpenKey,HKEY_LOCAL_MACHINE,szReg,phkResult
- or eax,eax
- jnz shell_not_found
- ; Получить информацию из реестра
- mov [buffSize],MAX_PATH
- invoke RegQueryValueEx,[phkResult],szKey,0,lpdwDisp,buff,buffSize
- or eax,eax
- jz @f
- mov [buffSize],0
- @@:
- ; Закрыть
- invoke RegCloseKey,[phkResult]
- cmp [buffSize],0
- je shell_not_found
- ; buff -> имя файла оболочки
- ...
- ; Ключ реестра
- szReg db 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon',0
- szKey db 'Shell',0
В приложении пример программы с исходным текстом, которая пытается получить название файла оболочки различными способами.
Просмотров: 2429 | Комментариев: 3
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(28.09.2017 в 10:50):
Про просчет не соглашусь. Первая же проверка через GetShellWindow вернет ошибку и, соответственно, никаких действий с шеллом программа предпринимать не должна. Ровно тот же эффект будет, если при нормальной загрузке системы нахлобучить explorer.exe. Факт: запущенный ШТАТНЫЙ шелл отсутствует. А причина его отсутствия - безопасный режим, альтернативный шелл или тупо убитый шелл - это уже дело десятое.
При нормальном результате проверяем что да, в роли шелла действительно выступает процесс explorer.exe. Если вообще все по уму делать, то после этого надо проверить, действительно ли он запущен из папки Windows, действительно ли у него есть валидная цифровая подпись и всякое такое, и вот только после этого что-то в него инжектить или выполнять какие-то другие действия.
А данные из реестра - это всего лишь приятный бонус, но ни в коем случае не руководство к действию.
При нормальном результате проверяем что да, в роли шелла действительно выступает процесс explorer.exe. Если вообще все по уму делать, то после этого надо проверить, действительно ли он запущен из папки Windows, действительно ли у него есть валидная цифровая подпись и всякое такое, и вот только после этого что-то в него инжектить или выполнять какие-то другие действия.
А данные из реестра - это всего лишь приятный бонус, но ни в коем случае не руководство к действию.
АндрейК
(27.09.2017 в 23:45):
Просто напомню: в "safe mode with command prompt" дефолтная альтернативная оболочка - cmd.exe
Главное совсем забыл, к чему это я: прога пишет explorer.exe
Просчёт/баг.
И да, cmd.exe в качестве оболочки куда более распространённая/доступная ситуация, в отличии от астона.
Главное совсем забыл, к чему это я: прога пишет explorer.exe
Просчёт/баг.
И да, cmd.exe в качестве оболочки куда более распространённая/доступная ситуация, в отличии от астона.
Добавить комментарий
Заполните форму для добавления комментария
Так вот в чём цель проверки. Или я опять неправильно понял ?
Просто как-то с сабжем немного не сходится.