Blog. Just Blog

Образ мышления: Assembler

То, что не удается запрограммировать на Ассемблере, приходится паять
Образ мышления: Assembler - RSS-канал Образ мышления: Assembler - Карта сайта

Перетаскивание окна за любое место

13.09.2008 | Категория: Образ мышления: Assembler | Автор: ManHunter
Перетаскивание окна за любое место, а не только за заголовок, реализуется очень просто, но смотрится очень эффектно. Тем более, что окно может быть вообще без заголовка. Для этого в обработчик окна надо добавить следующий код.
  1. ; Процедура обработчика окна
  2. proc  DialogProc hwnddlg,msg,wparam,lparam
  3.       ......
  4.       ; Нажата левая кнопка мышки на окне?
  5.       cmp     [msg], WM_LBUTTONDOWN
  6.       je      drag_window
  7.       ......
  8. drag_window:
  9.       ; Освободить захват мыши окном в текущем потоке и
  10.       ; восстановить обычную обработку ввода данных от мыши
  11.       invoke  ReleaseCapture
  12.       ; Перенаправить сообщение передвижения мышью SC_MOVE на заголовок окна
  13.       ; 61458 = SC_MOVE or HTCAPTION, в FASM по умолчанию не определено,
  14.       ; поэтому сразу задается числовым значением
  15.       invoke  SendMessage,[hwnddlg],WM_SYSCOMMAND,61458,0
  16.       ......
Вызов функции ReleaseCapture необходим для освобождения окна от захвата сообщений мыши. Даже если вы сами не устанавливали эти перехватчики, то они вполне могут быть установлены сторонними программами. В этом случае окно может перемещаться неправильно. Исходник с откомпилированным файлом прилагается.

Читать статью целиком »
Просмотров: 6188 | Комментариев: 6

Повышение привилегий процесса

09.09.2008 | Категория: Образ мышления: Assembler | Автор: ManHunter
Любой процесс в системе выполняется с правами какого-то пользователя или самой системы. Привилегии – это права процесса на совершение каких-либо действий по отношению ко всей системе, и при выполнении каких-либо привилегированных операций система проверяет, обладает ли пользователь соответствующей привилегией. Например, выключение и перезагрузка компьютера компьютера относятся как раз к таким операциям, и без повышения привилегий функция ExitWindowsEx завершится с ошибкой. Готовых решений на FASM найти не удалось, пришлось портировать из языков высокого уровня.
  1. ; Сегмент данных
  2. section '.data' data readable writeable
  3.  
  4. ; Определяем константы
  5. TOKEN_ADJUST_PRIVILEGES = 20h
  6. TOKEN_QUERY             = 8h
  7. SE_PRIVILEGE_ENABLED    = 2h
  8.  
  9. ; Определяем необходимые структуры, потому что в FASM'е их нет
  10. struct LUID
  11.   lowPart  dd ?
  12.   HighPart dd ?
  13. ends
  14.  
  15. struct LUID_AND_ATTRIBUTES
  16.   pLuid       LUID
  17.   Attributes  dd ?
  18. ends
  19.  
  20. struct _TOKEN_PRIVILEGES
  21.   PrivilegeCount   dd ?
  22.   Privileges       LUID_AND_ATTRIBUTES
  23. ends
  24.  
  25. TTokenHd dd ?
  26.  
  27. udtLUID  LUID
  28. ; Важно! Структура _TOKEN_PRIVILEGES должна быть выровнена на границу 4 байт!
  29. align 4
  30. tkp     _TOKEN_PRIVILEGES
  31.  
  32. SE_SHUTDOWN_NAME db 'SeShutdownPrivilege',0
  33.  
  34. ; Сегмент кода
  35. section '.code' code readable executable
  36.  
  37.     invoke    GetCurrentProcess
  38.  
  39.     ; Открыть маркер доступа (access token), ассоциирующийся с процессом
  40.     invoke    OpenProcessToken,eax,TOKEN_ADJUST_PRIVILEGES+TOKEN_QUERY,TTokenHd
  41.     or        eax,eax
  42.     jz        loc_exit  ; Ошибка
  43.  
  44.     ; Получить текущее значение привилегии на выключение и
  45.     ; перезагрузку системы
  46.     invoke    LookupPrivilegeValue, NULL, SE_SHUTDOWN_NAME, udtLUID
  47.     or        eax,eax
  48.     jz        loc_exit  ; Ошибка
  49.  
  50.     ; Заполнить структуры
  51.     mov       [tkp.PrivilegeCount],1
  52.     mov       [tkp.Privileges.Attributes],SE_PRIVILEGE_ENABLED
  53.     mov       eax,[udtLUID.lowPart]
  54.     mov       [tkp.Privileges.pLuid.lowPart],eax
  55.     mov       eax,[udtLUID.HighPart]
  56.     mov       [tkp.Privileges.pLuid.HighPart],eax
  57.     invoke    AdjustTokenPrivileges,[TTokenHd],0,tkp,0,0,0
  58.  
  59.     ; Здесь будет код, требующий повышенных привилегий, 
  60.     ; например выключение компьютера
  61.     invoke    ExitWindowsEx,EWX_POWEROFF,NULL
  62.     ...
  63.  
  64.     ; Выход
  65. loc_exit:
  66.     invoke    ExitProcess,0
Выключение рассмотрено как наиболее часто встречающаяся задача, более подробное описание использованных структур и функций вы можете найти на сайте Microsoft Developer Network.

Просмотров: 6888 | Комментариев: 5

Генератор случайных чисел на Ассемблере

03.09.2008 | Категория: Образ мышления: Assembler | Автор: ManHunter
При написании программ часто возникает необходимость получить последовательность случайных чисел. В языках высокого уровня существуют штатные функции, а для Ассемблера я использую так называемый "Минимальный генератор Парка-Миллера" (Minimal portable random generator by Park and Miller). От аналогичных алгоритмов его отличает очень малый размер и равномерное распределение получаемых случайных чисел. Математическую модель и описание работы алгоритма можно без труда найти в интернете, поэтому эту информацию я здесь не привожу.
  1. ;---------------------------------------------
  2. ; Park Miller random number algorithm
  3. ; Получить случайное число 0 ... 99999
  4. ; stdcall WRandom
  5. ; на выходе EAX - случайное число 
  6. ;---------------------------------------------
  7. proc    WRandom
  8.         push    edx ecx
  9.         mov     eax,[random_seed]
  10.         xor     edx,edx
  11.         mov     ecx,127773
  12.         div     ecx
  13.         mov     ecx,eax
  14.         mov     eax,16807
  15.         mul     edx
  16.         mov     edx,ecx
  17.         mov     ecx,eax
  18.         mov     eax,2836
  19.         mul     edx
  20.         sub     ecx,eax
  21.         xor     edx,edx
  22.         mov     eax,ecx
  23.         mov     [random_seed],ecx
  24.         mov     ecx,100000
  25.         div     ecx
  26.         mov     eax,edx
  27.         pop     ecx edx
  28.         ret
  29. endp
  30.  
  31. ;---------------------------------------------
  32. ; Получить случайное число в нужном интервале
  33. ; Требуется процедура WRandom
  34. ; stdcall WIRandom,min,max
  35. ; на выходе EAX - случайное число   
  36. ;---------------------------------------------
  37. proc    WIRandom rmin:dword,rmax:dword
  38.         push    edx ecx
  39.         mov     ecx,[rmax]
  40.         sub     ecx,[rmin]
  41.         inc     ecx
  42.         stdcall WRandom
  43.         xor     edx,edx
  44.         div     ecx
  45.         mov     eax,edx
  46.         add     eax,[rmin]
  47.         pop     ecx edx
  48.         ret
  49. endp
  50.  
  51. ;---------------------------------------------
  52. ; Инициализация генератора случайных чисел
  53. ; stdcall WRandomInit 
  54. ;---------------------------------------------
  55. proc    WRandomInit
  56.         push    eax edx
  57.         rdtsc
  58.         xor     eax,edx
  59.         mov     [random_seed],eax
  60.         pop     edx eax
  61.         ret
  62. endp
После небольшой доработки он получил возможность генерировать случайные числа в заданном интервале.

Читать статью целиком »
Просмотров: 25317 | Комментариев: 7

prev 01 ... 29 30 31 32 33 34 35 36 37 next
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2019
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.08 сек. / MySQL: 2 (0.0029 сек.) / Память: 4.75 Mb
Наверх