Blog. Just Blog

Быстрый поиск

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

Вывод лога на Ассемблере

19.09.2008 | Категория: Образ мышления: Assembler | Автор: ManHunter
Если при работе вашей программы требуется вывод лога неопределенной длины, то это удобно делать в многострочном поле Edit. Преимущества такого способа налицо: можно мышкой выделить и скопировать любой кусок текста, средствами API получить весь текст целиком и сохранить в файл, быстро очистить окно лога и многое другое. Удобно делать все, кроме главного: добавление новых строчек в лог. Конечно, можно получать текст, в памяти добавлять к нему новые строчки и вставлять обратно. Но это долго, неудобно и требует дополнительных ресурсов, а для очень больших логов и вовсе неприемлемо. Поэтому воспользуемся следующей функцией:
  1. ;---------------------------------------------
  2. ; procedure AddLog
  3. ; void AddLog(hWnd:dword,CtrlID:dword,pStr:&string)
  4. ;---------------------------------------------
  5. proc    AddLog  hWnd:dword,CtrlID:dword,pStr:dword
  6.         push    eax
  7.         invoke  GetDlgItem,[hWnd],[CtrlID]
  8.         or      eax,eax
  9.         jz      .AddLog_1
  10.         mov     [CtrlID],eax
  11.         invoke  SendMessage,[CtrlID],EM_GETLINECOUNT,0,0
  12.         dec     eax
  13.         invoke  SendMessage,[CtrlID],EM_LINEINDEX,eax,0
  14.         invoke  SendMessage,[CtrlID],EM_SETSEL,eax,eax
  15.         invoke  SendMessage,[CtrlID],EM_REPLACESEL,FALSE,[pStr]
  16. .AddLog_1:
  17.         pop     eax
  18.         ret
  19. endp  
Парметры вызова: hWnd - хэндл окна, которому принадлежит дочернее окно логом, CtrlID - идентификатор окна Edit в ресурсах, pStr - указатель на строку ASCIIZ, которую надо записать в лог.

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

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

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 необходим для освобождения окна от захвата сообщений мыши. Даже если вы сами не устанавливали эти перехватчики, то они вполне могут быть установлены сторонними программами. В этом случае окно может перемещаться неправильно. Исходник с откомпилированным файлом прилагается.

Читать статью целиком »
Просмотров: 6655 | Комментариев: 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.

Просмотров: 7459 | Комментариев: 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
После небольшой доработки он получил возможность генерировать случайные числа в заданном интервале.

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

01 ... 43 44 45 46 47 48 49 50 51 next
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2021
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.12 сек. / MySQL: 3 (0.0489 сек.) / Память: 4.75 Mb
Наверх