
Быстрый поиск
Введите фрагмент названия статьи для поиска

Как узнать, что программа запущена под Администратором
20.11.2011 | Категория: Образ мышления: Assembler | Автор: ManHunter
Иногда требуется узнать, запущена ли ваша программа под учетной записью с правами Администратора, или же от обычного пользователя. Для чего это нужно? Например, некоторые операции с реестром или файлами требуют права Администратора. При попытке выполнить их обычному пользователю вернется ошибка ERROR_ACCESS_DENIED, но для более точного анализа ситуации надо будет проверить права доступа и уведомить об этом пользователя. Проверить, что программа запущена под Администратором, можно несколькими способами.Первый способ наиболее универсальный и работает даже на старых операционных системах. Он заключается в том, что надо получить группы доступа для токена текущего процесса, а затем проверить, входит ли хоть одна из них в группу Администраторов локального компьютера. Вот пример реализации:
Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- section '.data' data readable writeable
- SECURITY_NT_AUTHORITY = 5
- TOKEN_READ = 0x00020008
- SECURITY_BUILTIN_DOMAIN_RID = 0x00000020
- DOMAIN_ALIAS_RID_ADMINS = 0x00000220
- TokenGroups = 0x00000002
- BUFF_SIZE = 1024h ; Размер буфера для групп доступа токена
- NtAuthority db 0,0,0,0,0,SECURITY_NT_AUTHORITY
- hTokenHandle dd ?
- dInfoSize dd ?
- psidAdmins dd ?
- hHeap dd ?
- pTokenGroups dd ?
- ;---------------------------------------------
- ; Сегмент кода
- section '.code' code readable executable
- ...
- ; Получить токен текущего процесса
- invoke GetCurrentProcess
- invoke OpenProcessToken,eax,TOKEN_READ,hTokenHandle
- ; Выделить память для массива групп
- invoke GetProcessHeap
- mov [hHeap],eax
- invoke HeapAlloc,eax,HEAP_ZERO_MEMORY,BUFF_SIZE
- mov [pTokenGroups],eax
- ; Получить информацию о группах доступа токена
- invoke GetTokenInformation,[hTokenHandle],TokenGroups,\
- [pTokenGroups],dword BUFF_SIZE,dInfoSize
- ; Прибраться за собой
- invoke CloseHandle,[hTokenHandle]
- invoke AllocateAndInitializeSid,NtAuthority,2,\
- SECURITY_BUILTIN_DOMAIN_RID,\
- DOMAIN_ALIAS_RID_ADMINS,0,0,0,0,0,0,psidAdmins
- ; Количество записей в структуре TOKEN_GROUPS
- mov esi,[pTokenGroups]
- mov ebx,dword [esi]
- ; Указатель на массив SID_AND_ATTRIBUTES
- add esi,4
- @@:
- ; Проверить соответствие SID
- mov eax,dword [esi]
- invoke EqualSid,[psidAdmins],eax
- or eax,eax
- jnz loc_admin
- ; Следующая группа
- add esi,8
- dec ebx
- or ebx,ebx
- jnz @b
- loc_not_admin:
- ; Пользователь не Администратор
- ...
- loc_admin:
- ; Пользователь Администратор
- ...
Читать статью целиком »
Просмотров: 8771 | Комментариев: 21

Принудительное завершение процесса
20.08.2011 | Категория: Образ мышления: Assembler | Автор: ManHunter
Рано или поздно в программистской практике возникает задача по управлению процессами, в частности их принудительного завершения. Для дочерних процессов, порожденных собственным приложением, обычно хватает вызова TerminateProcess, но в некоторых случаях требуется принудительно завершить чужой процесс. Зная идентификатор процесса сделать это не составит большого труда. Открываем процесс функцией OpenProcess с правами PROCESS_TERMINATE, а затем, в случае успеха, отдаем полученный хэндл функции TerminateProcess. Вроде бы все просто, но не тут-то было. При попытке открыть некоторые процессы, как правило системные, возвращается ошибка ERROR_ACCESS_DENIED. Это связано с тем, что дескрипторы безопасности системных процессов блокируют такой доступ для всех пользователей, включая Администраторов. Чтобы обойти запрет, требуется поднять привилегии нашего процесса, а именно получить привилегию отладчика SE_DEBUG_NAME. Как повышать привилегии процесса в системе я уже писал. Напомню только, что необходимые структуры и константы в FASM отсутствуют и их придется определить самостоятельно.Code (Assembler) : Убрать нумерацию
- ; Константы для работы привилегиями
- TOKEN_ADJUST_PRIVILEGES = 20h
- TOKEN_QUERY = 8h
- SE_PRIVILEGE_ENABLED = 2h
- ; Структуры для работы привилегиями
- struct LUID
- lowPart dd ?
- HighPart dd ?
- ends
- struct LUID_AND_ATTRIBUTES
- pLuid LUID
- Attributes dd ?
- ends
- struct _TOKEN_PRIVILEGES
- PrivilegeCount dd ?
- Privileges LUID_AND_ATTRIBUTES
- ends
Code (Assembler) : Убрать нумерацию
- invoke GetCurrentProcess
- invoke OpenProcessToken,eax,TOKEN_ADJUST_PRIVILEGES+TOKEN_QUERY,TTokenHd
- ; Получить привилегии процесса
- invoke LookupPrivilegeValue,NULL,SE_DEBUG_NAME,udtLUID
- ; Повысить привилегии процесса
- mov [tkp.PrivilegeCount],1
- mov [tkp.Privileges.Attributes],SE_PRIVILEGE_ENABLED
- mov eax,[udtLUID.lowPart]
- mov [tkp.Privileges.pLuid.lowPart],eax
- mov eax,[udtLUID.HighPart]
- mov [tkp.Privileges.pLuid.HighPart],eax
- invoke AdjustTokenPrivileges,[TTokenHd],0,tkp,0,0,0
Читать статью целиком »
Просмотров: 7179 | Комментариев: 18

Получение списка иконок в трее
18.07.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
Иногда приложению требуется получить список иконок, находящихся в трее, а также список приложений, которые их туда разместили. Это может быть нужно для обнаружения некоторых скрывающихся приложений, для эмуляции кликов на иконках, ну или просто для спортивного интереса. В любом случае для получения списка иконок надо сделать следующее: найти в трее панель с иконками, при помощи сообщения TB_BUTTONCOUNT получить количество иконок, а затем через отправку сообщения TB_GETBUTTON получить всю необходимую информацию по каждой иконке. Теперь рассмотрим все шаги подробнее.Работать с вложенными окнами трея мы уже умеем, здесь практически то же самое, разница только в названиях классов дочерних окон.
Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- section '.data' data readable writeable
- ...
- class1 db 'Shell_TrayWnd',0 ; Название класса окна трея
- class2 db 'TrayNotifyWnd',0 ; Название класса панели уведомлений
- class3 db 'SysPager',0 ; Трей
- class4 db 'ToolbarWindow32',0 ; Панель с иконками
- ToolbarHandle dd ? ; Хэндл окна с иконками
- ...
- ; Сегмент кода
- section '.code' code readable executable
- ...
- ; Найти окно трея
- invoke FindWindow,class1,NULL
- or eax,eax
- jz exit_process
- ; Найти панель уведомлений
- invoke FindWindowEx,eax,NULL,class2,NULL
- or eax,eax
- jz exit_process
- ; Найти трей
- invoke FindWindowEx,eax,NULL,class3,NULL
- or eax,eax
- jz exit_process
- ; Найти панель иконок в трее
- invoke FindWindowEx,eax,NULL,class4,NULL
- or eax,eax
- jz exit_process
- ; Сохранить хэндл окна с иконками
- mov [ToolbarHandle],eax
- ...
Code (Assembler) : Убрать нумерацию
- ; Получить количество иконок в трее
- invoke SendMessage,eax,TB_BUTTONCOUNT,0,0
- or eax,eax
- jz exit_process
- ; Сохранить количество иконок в трее
- mov [IconsCount],eax
Читать статью целиком »
Просмотров: 7523 | Комментариев: 9

Построение карты памяти процесса
02.04.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
Умение работать с памятью сторонних процессов - полезный навык адепта Темной стороны Силы. Таким способом можно найти нужные данные, хранящиеся в памяти, например, расшифрованные файлы, изображения, пароли, и еще много чего вкусного. Также этот навык пригодится при создании распаковщиков, лоадеров для программ и трейнеров для различных игр. Я привел лишь несколько примеров, на практике их можно найти гораздо больше.Для построения карты памяти процесса используется функция VirtualQueryEx и специальная структура MEMORY_BASIC_INFORMATION. В FASM она как обычно не определена, придется сделать это самостоятельно в сегменте данных:
Code (Assembler) : Убрать нумерацию
- ; Структура для чтения памяти процесса
- struct MEMORY_BASIC_INFORMATION
- BaseAddress dd ?
- AllocationBase dd ?
- AllocationProtect dd ?
- RegionSize dd ?
- State dd ?
- Protect dd ?
- Type dd ?
- ends
- ; Структура для чтения памяти процесса
- mbi MEMORY_BASIC_INFORMATION
Читать статью целиком »
Просмотров: 7818 | Комментариев: 8

Проверка и обнаружение зависших приложений
27.10.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Иногда для работы требуется определение зависших приложений, окна которых не отвечают на сообщения. Для этого есть два способа. Первый - официально документированный, через функцию SendMessageTimeOut. Особенность ее работы заключается в том, что после отправки сообщения окну она ждет ответ заданное время, и, если ответа от приложения не последовало, то возвращает FALSE. Вот пример использования функции. Нужные константы, как обычно, в FASM не определены, пришлось брать их из других источников.Code (Assembler) : Убрать нумерацию
- ...
- ; Определить таймаут 50 миллисекунд
- TIMEOUT = 50
- ; Определить константу SMTO_ABORTIFHUNG
- SMTO_ABORTIFHUNG = 2
- ; hwnd - хэндл проверяемого окна
- invoke SendMessageTimeout,[hwnd],NULL,0,0,SMTO_ABORTIFHUNG,TIMEOUT,NULL
- ; Если вернулся 0, то приложение "висит"
- or eax,eax
- jz app_hung_up
- ...
Читать статью целиком »
Просмотров: 7216 | Комментариев: 2
