Blog. Just Blog

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

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

Интерпретатор Brainfuck на Ассемблере

21.07.2017 | Категория: Образ мышления: Assembler | Автор: ManHunter

Интерпретатор Brainfuck на Ассемблере

Если вы увлекаетесь программированием, то скорее всего слышали об эзотерическом языке программирования Brainfuck. Дословно его название переводится на русский язык как "мозгоёбка", но в приличном обществе его обычно сглаживают до "вынос мозга". Язык имеет всего восемь команд, каждая из которых записывается одним символом. В полном соответствии с названием, программы на Brainfuck трудно не только читать, но и писать, поскольку они представляют собой последовательность символов-команд без какого-либо дополнительного синтаксиса. Несмотря на это, Brainfuck является полноценной машиной Тьюринга, и поэтому может выполнять любые вычислительные задачи. Ветераны реверса наверняка помнят KeygenMe от легендарного Ms-Rem, в котором алгоритм проверки ключа был спрятан внутри виртуальной машины на Brainfuck.

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

Обработка критических ошибок на Ассемблере

08.07.2017 | Категория: Образ мышления: Assembler | Автор: ManHunter

Обработка критических ошибок на Ассемблере

Как гласит один из законов Мерфи для программистов, в каждой программе есть ошибки. Какими бы суровыми ни были тесты, с их помощью невозможно доказать полное отсутствие ошибок. Всегда остается вероятность возникновения ситуации, не охваченной тестовой средой. В таких случаях для разработчиков и тестеров важно получить подробную информацию об ошибке, чтобы попытаться воспроизвести ее и устранить. Делается это различными способами, в том числе и при помощи обработчиков критических ошибок.

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

Правильное принудительное обновление иконок в трее

21.06.2017 | Категория: Образ мышления: Assembler | Автор: ManHunter
Несколько лет назад я опубликовал в блоге статью о принудительном обновлении иконок в трее, в которой опрометчиво заявил, что это единственный способ решения задачи. Все течет, все изменяется, поэтому представляю вашему вниманию новую статью-опровержение, в которой расскажу, как правильно обновлять иконки в трее.

Суть задачи остается прежней: некое приложение аварийно завершило работу, в трее остался его значок. Нужно из своего приложения обновить системный трей таким образом, чтобы этот значок убрать. Все трудности этой задачи я подробно описал в статье по ссылке выше, поэтому повторяться не буду и перейду сразу к решению. За основу взят код получения списка иконок в трее. При переборе проверяется наличие окна, которому должна принадлежать иконка. Если окна нет, значит и иконки существовать не должно. Такие иконки удаляются при помощи функции Shell_NotifyIcon с параметром NIM_DELETE.
  1. ; Сегмент данных
  2. section '.data' data readable writeable
  3.  
  4. ; Структура пользовательских данных иконки
  5. struct EXTRADATA
  6.         Wnd dd ?
  7.         uID dd ?
  8. ends
  9.  
  10. class1     db 'Shell_TrayWnd',0    ; Название класса окна трея
  11. class2     db 'TrayNotifyWnd',0    ; Название класса панели уведомлений
  12. class3     db 'SysPager',0         ; Трей
  13. class4     db 'ToolbarWindow32',0  ; Панель с иконками
  14.  
  15. ; Структура для кнопки
  16. button     TBBUTTON
  17. ; Структура для пользовательских данных иконки
  18. extra      EXTRADATA
  19. ; Структура для работы с иконкой в трее
  20. nid        NOTIFYICONDATA
  21.  
  22. hToolbar   dd ?    ; Хэндл окна с иконками
  23. IconsCount dd ?    ; Количество иконок в трее
  24. ProcId     dd ?    ; Id процесса
  25. hProcess   dd ?    ; Хэндл процесса
  26. lpData     dd ?    ; Указатель на блок памяти
  27. BytesRead  dd ?    ; Количество прочитанных символов
  1.         ; Найти окно трея
  2.         invoke  FindWindow,class1,NULL
  3.         or      eax,eax
  4.         jz      exit_process
  5.  
  6.         ; Найти панель уведомлений
  7.         invoke  FindWindowEx,eax,NULL,class2,NULL
  8.         or      eax,eax
  9.         jz      exit_process
  10.  
  11.         ; Найти трей
  12.         invoke  FindWindowEx,eax,NULL,class3,NULL
  13.         or      eax,eax
  14.         jz      exit_process
  15.  
  16.         ; Найти панель иконок в трее
  17.         invoke  FindWindowEx,eax,NULL,class4,NULL
  18.         or      eax,eax
  19.         jz      exit_process
  20.  
  21.         ; Сохранить хэндл окна с иконками
  22.         mov     [hToolbar],eax
  23.  
  24.         ; Получить количество иконок в трее
  25.         invoke  SendMessage,eax,TB_BUTTONCOUNT,0,0
  26.         or      eax,eax
  27.         jz      exit_process
  28.  
  29.         ; Сохранить количество иконок в трее
  30.         mov     [IconsCount],eax
  31.  
  32.         ; Получить ID процесса-владельца трея
  33.         invoke  GetWindowThreadProcessId,[hToolbar],ProcId
  34.         ; Открыть процесс с для чтения и записи
  35.         invoke  OpenProcess,PROCESS_VM_OPERATION or PROCESS_VM_READ,\
  36.                 FALSE,[ProcId]
  37.         or      eax,eax
  38.         ; Фокус не удался
  39.         jz      exit_process
  40.  
  41.         ; Сохранить хэндл процесса-владельца трея
  42.         mov     [hProcess],eax
  43.  
  44.         ; Выделить блок памяти в контексте процесса
  45.         invoke  VirtualAllocEx,[hProcess],NULL,dword sizeof.TBBUTTON,\
  46.                 MEM_COMMIT,PAGE_READWRITE
  47.         or      eax,eax
  48.         jz      exit_process
  49.  
  50.         ; Сохранить указатель на блок памяти
  51.         mov     [lpData],eax
  52.  
  53.         ; Перебрать все иконки в трее
  54. loc_loop:
  55.         ; Все иконки обработали?
  56.         cmp     [IconsCount],0
  57.         je      clear_memory
  58.  
  59.         ; Следующая иконка
  60.         dec     [IconsCount]
  61.  
  62.         ; Получить иконку из трея с индексом IconsCount
  63.         invoke  SendMessage,[hToolbar],TB_GETBUTTON,[IconsCount],[lpData]
  64.         ; Прочитать структуру иконки
  65.         invoke  ReadProcessMemory,[hProcess],[lpData],button,\
  66.                 dword sizeof.TBBUTTON,BytesRead
  67.         or      eax,eax
  68.         jz      clear_memory
  69.         ; Прочиталась вся структура?
  70.         cmp     [BytesRead],sizeof.TBBUTTON
  71.         jnz     clear_memory
  72.  
  73.         ; Прочитать пользовательские данные иконки
  74.         invoke  ReadProcessMemory,[hProcess],[button.dwData],extra,\
  75.                 dword sizeof.EXTRADATA,BytesRead
  76.         or      eax,eax
  77.         jz      clear_memory
  78.         ; Прочиталась вся структура?
  79.         cmp     [BytesRead],sizeof.EXTRADATA
  80.         jnz     clear_memory
  81.  
  82.         ; Это скрытая иконка?
  83.         mov     eax,[extra.uID]
  84.         and     eax,80000000h
  85.         or      eax,eax
  86.         ; Да, пропустить
  87.         jnz     loc_loop
  88.  
  89.         ; Окно процесса существует?
  90.         invoke  IsWindow,[extra.Wnd]
  91.         or      eax,eax
  92.         jnz     loc_loop
  93.  
  94.         ; Удалить иконку, у которой нет родителя
  95.         mov     [nid.cbSize],sizeof.NOTIFYICONDATA
  96.         mov     eax,[extra.Wnd]
  97.         mov     [nid.hWnd],eax
  98.         mov     eax,[extra.uID]
  99.         mov     [nid.uID],eax
  100.         invoke  Shell_NotifyIcon,NIM_DELETE,nid
  101.         jmp     loc_loop
  102.  
  103. clear_memory:
  104.         ; Очистить память и ресурсы
  105.         invoke  VirtualFreeEx,[hProcess],[lpData],0,MEM_RELEASE
  106.         invoke  CloseHandle,[hProcess]
  107.  
  108. exit_process:
Способ простой, надежный и не вызывает побочных эффектов типа реакции приложений при эмуляции движения курсора над треем.

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

Получение списка DLL, загруженных в текущий процесс

12.06.2017 | Категория: Образ мышления: Assembler | Автор: ManHunter
Сегодня я покажу вам небольшой трюк, с помощью которого вы сможете получить список всех DLL (динамических библиотек), загруженных в ваше приложение. Хитрость заключается в том, что для этого мы вообще не будем использовать никакие API.

Сперва немного теории. Каждому процессу в системе соответствует особая структура PEB (Process Enviroment Block), в ней содержится большое количество полезной информации о процессе. Адрес PEB можно узнать из другой структуры - TIB (Thread Information Block), адрес которой, в свою очередь, всегда можно получить по фиксированному адресу [FS:0]. Так вот, одно из полей PEB указывает на массив структур, в которых содержится информация о всех динамических библиотеках, загруженных в адресное пространство процесса. Этот массив называется PEB_LDR_DATA. Перебирая по очереди записи из этого массива, можно получить интересующий нас список DLL, а также адреса загрузки в память и Virtual Address точки входа этих библиотек.

Переходим к программированию. Flat Assembler "из коробки" не знает структур для работы с PEB_LDR_DATA, поэтому придется ему в этом помочь:
  1. struct UNICODE_STRING
  2.   Length        dw ?
  3.   MaximumLength dw ?
  4.   Buffer        dd ?
  5. ends
  6.  
  7. struct LIST_ENTRY
  8.   Flink         dd ?
  9.   Blink         dd ?
  10. ends
  11.  
  12. struct LDR_DATA_ENTRY
  13.   InMemoryOrderModuleList LIST_ENTRY
  14.   BaseAddress   dd ?
  15.   EntryPoint    dd ?
  16.   SizeOfImage   dd ?
  17.   FullDllName   UNICODE_STRING
  18.   BaseDllName   UNICODE_STRING
  19.   Flags         dd ?
  20.   LoadCount     dw ?
  21.   TlsIndex      dw ?
  22.   HashTableEntry LIST_ENTRY
  23.   TimeDateStamp dd ?
  24. ends
Записи перелинкованы между собой посредством поля InMemoryOrderModuleList.Flink, в котором прописана информация об адресе следующей записи. Важно учитывать, что массив "закольцован", то есть последняя запись ссылается на первую. При переборе надо проверять, например, поле BaseAddress текущей записи, если оно нулевое, то обработку следует остановить. Записи в массиве располагаются в порядке их загрузки в память.

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

Как определить состояние SUSPENDED процесса

26.04.2017 | Категория: Образ мышления: Assembler | Автор: ManHunter

Как определить состояние SUSPENDED процесса

Сегодня разберем интересный вопрос. Как программно узнать, заморожен процесс (SUSPENDED) или выполняется? Подобную информацию показывает, например, утилита Process Explorer. Строго говоря, у процесса не может быть состояния SUSPENDED, так что сама постановка вопроса и заголовок статьи не вполне корректные. Процесс может считаться замороженным, когда все без исключения его потоки находятся в состоянии SUSPENDED. Если хоть один поток активен, процесс также считается активным.

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

01 ... 05 06 07 08 09 10 11 ... 36
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2019
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.4 сек. / MySQL: 3 (0.0947 сек.) / Память: 4.75 Mb
Наверх