Реверс инжиниринг что это в программировании
Перейти к содержимому

Реверс инжиниринг что это в программировании

  • автор:

Реверс инжиниринг для самых маленьких на практике

Скомпилированное приложение является «чёрным ящиком». Чтобы туда заглянуть, восстановить алгоритм работы применяется реверс‑инжиниринг. Это непростой навык с высоким порогом входа. В статье мы попробуем взять дизассемблер, несложную задачку и пойдём в бой. Материал будет полезен тем, кому хочется с чего-то начать и погрузиться в тему реверса.

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

Задача

В качестве примера для разбора мы взяли задачу с платформы Codeby Games из раздела Реверс-инжиниринг – файлы. Называется: «Шифрование или что-то в этом роде, не знаю». Чтобы получить доступ к платформе – нужно зарегистрироваться. К самой платформе мы не имеем никакого отношения.

Решением задачи является строка (флаг), которую будем добывать.
Скачиваем бинарный файл “task3.exe” из раздела “Файлы” и приступаем.

В статье будут применяться бесплатные инструменты:

  • Редактор исполняемых файлов CFF Explorer
  • Дизассемблер IDA Freeware
  • Редактор Microsoft Visual Studio Community и компилятор MSVC

Первичный запуск

Все исполняемые файлы, скачанные из интернета, рекомендуем всегда сначала запускать внутри виртуальной машины. Это позволит первично обезопасить себя от вредоносной активности незнакомого приложения.

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

  • VirusTotal (Есть бесплатная версия)
  • Hybrid Analysis (Есть бесплатная версия)
  • AnyRun (Есть бесплатная версия)
  • PEStudio (Есть бесплатная версия)
  • Capa (Бесплатно)

Современное вредоносное ПО часто взаимодействует с сетью как для доставки очередной «стадии вредоносности», так и для распространения в локальной сети. Рекомендуем либо целиком отключать виртуальную машину от сети, либо, если для исследуемого приложения требуется подключение в интернет, использовать VPN изнутри виртуальной машины. Это не даст образцу распространиться в сети вашей хостовой машины.

Теперь, когда обо всем предупредили, можно приступать к работе.

Перед нами классическое консольное приложение, которое запрашивает строку:

Первичный запуск

Пробуем ввести флаг и убеждаемся, что удача не на нашей стороне:

Попытка ввода флага

Но, теперь мы знаем, что проверка флага каким-то образом связана со строками INPUT YOUR FLAG: и INCORRECT. .

Запускаем дизассемблер IDA и открываем исполняемый файл. IDA предлагает использовать оставленную автором отладочную информацию:

Наличие отладочной информации всегда сильно упрощает дальнейший анализ.

Немного об отладочной информации

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

Существует множество форматов отладочных символов. Чаще всего вам придется сталкиваться с этими:

  • PDB – Program Data Base, используется в продуктах, собранных с использованием компиляторов, разработанных компанией Microsoft.
  • DWARF (Debugging With Arbitrary Record Format), STABS (Symbol Table and String Table), COFF (Common Object File Format), ELF (Executable and Linkable Format) используются в основном в продуктах, собранных с использованием open-source компиляторов.
  • Mach-O – Mach Objecton macOS and iOS, используется только в продуктах, собранных различными компиляторами, для целевых ОС MacOs или iOS.

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

Не стоит пугаться такому списку, потому что суть одна и та же. Разберем чуть подробнее, что хранят в себе DWARF и PDB – самые часто используемые форматы.

Информация DWARF обычно хранится в отдельном файле, который затем связывается (линкуется) с исполняемым файлом.

Основная информация, хранящаяся в файле DWARF:

  • имена файлов исходного кода и номера строк
  • информацию о глобальных и локальных переменных и их типах
  • информацию о функциях и подфункциях
  • граф вызовов программы

Информация PDB обычно также хранится в отдельном файле, который затем связывается с исполняемым файлом.

Основная информация, хранящаяся в файле PDB:

  • информацию об именах и типах переменных
  • информацию о функциях
  • информацию о местоположении строк кода
  • информацию о стеке вызовов

О том, как управлять своей жизнью, и самому включать отладочную информацию на примере отладчика gdb и исполняемого ELF-файла, советуем прочитать эти две статьи:

  • The GDB developer’s GNU Debugger tutorial, Part 1: Getting started with the debugger
  • The GDB developer’s GNU Debugger tutorial, Part 2: All about debuginfo

В Visual Studio отладочная информация включается при наличии флага линковщика /DEBUG. Отключить можно в настройках проекта, поставив полю Linker -> Debugging -> Generate debug info значение NO.

Также в настройках линковщика можно отключить создание pdb файла, очистив поле Linker -> Debugging -> Generate Program Database File.

Если не отключить создание PDB-файла, в собранном исполняемом файле в секции данных будет лежать путь до этого файла.

Больше о том, как исследователи используют отладочную информацию можно почитать в статье Utilizing Debugging Information of Applications in Memory Forensics.

Крис Касперски в статье Защита игр от взлома рекомендовал никогда не оставлять отладочную информацию в скомпилированной программе.

Начинаем анализировать

Теперь, когда есть поверхностное знание, что такое отладочная информация начнем анализ. Для этого откроем IDA, с использованием отладочной информации. Перед нами функция main.

Функция main

С отладочной информацией дизассемблер сразу понял, что перед нами не набор бессмысленных переменных. По модификаторам ptr понимаем, что flag , check и i это указатели на данные определенных типов.

Спускаемся ниже по коду к адресу 401598. По синтаксису команды mov [rbp+check+4], 7ABh видим, что в память по адресам check, check+4, check+8 и т.д. помещаются какие-то числа.

Больше о квадратных скобках в операндах команд и вообще о типах адресации можно почитать в статье Операнды в языке ассемблера.

Так как данные помещаются в check+N по регулярному смещению 4, делаем вывод, что check является указателем на массив. Этих команд 25 штук, поэтому можем предположить, что массив хранит в себе 25 элементов длиной 4 байта. Если это верно, то далее, когда массив будет использоваться в циклах, скорее всего операции будут проводиться с двадцатью пятью элементами.

Отвлечемся немного и ответим на пару вопросов.

А почему каждая строка начинается с “.text”?

Исполняемый файл имеет множество участков, называемых секциями. Они имеют различное назначение. Код в исполняемых файлах хранится в секции .text. У этой секции есть специальные права на исполнение. Чтобы в этом убедиться, откроем исполняемый файл в редакторе CFF Explorer.

Загрузив файл в CFF Explorer, видим вкладки в левой части рабочего пространства:

Сначала идут заголовки, потом таблицы: импорта, экспорта и TLS. Ниже различные модули для работы с исполняемыми файлами, включенные в CFF Explorer.

Информация о секциях хранится в заголовке Section Headers. Откроем его:

Копаем глубже

О структуре исполняемых файлов Windows подробне прочитать в статье Часть 1. Обзор PE формата и других статьях цикла.
Статьи покрывают: из чего состоит исполняемый файл Windows, как искать секции, что такое импортируемые и экспортируемые функции и так далее многое другое.
А выжимка есть на хабре PE (Portable Executable): На странных берегах. Для начала ее вполне хватит.

Нас интересует поле Characteristics. Здесь содержится информация о данных, хранящихся в секции. У секции .text Characteristics имеет значение 60500060. Старшая 6 говорит о том, что у секции есть характеристики:

  • IMAGE_SCN_MEM_READ и IMAGE_SCN_MEM_EXECUTE – секция может быть исполнена как код
  • IMAGE_SCN_MEM_READ – секция может быть прочитана

Все возможные характеристики можно посмотреть в документации Microsoft.

А почему после .text следует “040…”?

У исполняемого файла есть параметр ImageBase – смещение относительно адреса в памяти, куда была загружена программа. Обычно это 0x40000. Этот параметр хранится в заголовке Optional Header:

Так почему же main() не начинается с 400000? Потому что это адрес, где лежит весь исполняемый файл, в том числе заголовки. Заголовки находятся как раз над сегментом кода. Поэтому нас интересуют еще два поля Optional Header:

  • BaseOfCode – смещение относительно начала загруженного исполняемого файла (ImageBase). Здесь начинается сегмент кода text. В этой части размещается код начальной работы процесса: проверка сигнатуры исполняемого файла, получение аргументов main, StartupInfo для процесса и так далее.
  • AddressOfEntryPoint – смещение относительно ImageBase, откуда начинает исполняться программа. Здесь начинается функция mainCRTStartup, которая выполняется до человеческого main и является точкой входа библиотеки времени выполнения Си (C Runtime). Помимо прочего, здесь инициализируются статические элементы кода, а так же переменные argc, argv и envp. А еще, в этой функции помимо всего остального, инициализируются статические элементы (с пометкой static), если они используются в программе.

В нашем случае AddressOfEntryPoint равен 1510. Посмотрим на него в IDA. В IDA этот адрес будет равен ImageBase+AddressOfEntryPoint, т.е. 401510:

Вызов __tmainCRTStartup

Здесь как раз видим вызов __tmainCRTStartup , находящийся выше AddressOfEntryPoint, в котором инициализируется StartupInfo.

Дважды нажав на эту функцию, перейдем внутрь нее и немного пролистаем до момента, пока не увидим вызов функции main (call main):

Вызов main

Здесь же видим, что в функцию main передаются привычные нам аргументы: argc, argv и envp. Это происходит всегда, даже когда разработчик приложения напрямую никак не взаимодействует с этими переменными в исходном коде.

Теперь вы знаете, как найти функцию main самостоятельно и как она вызывается на самом деле, а так же что означают числа рядом с .text в дизассемблере.

Если отладочной информации нет

Давайте посмотрим, как будет выглядеть код без отладочной информаци. Откроем экземпляр IDA без использования отладочной информации. Увидим функцию main, только в менее понятном виде.

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

Ищем массив

Затем укажем дизассемблеру наличие массива. Для этого дважды кликнем по первой переменной, с которой начинается массив. Перед нами откроется окно редактирования переменных стека:

Далее выделим все необходимые переменные и с помощью горячей клавиши ‘*’ создадим массив:

Затем переименуем созданный массив с помощью горячей клавиши ‘N‘:

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

В реверсе очень важно уметь находить подобные структуры, это сильно помогает при дальнейшем анализе.

Наконец-то реверс

Вернемся к коду с отладочной информацией и продолжим.

Перейдем в раздел Strings (shift+F12) и видим уже знакомую строку, которая приглашает ввести флаг:

Строки

Дважды кликаем по ней в открывшемся окне и попадаем в секцию, где хранятся инициализированные данные приложения, предназначенные только для чтения – .rdata :

.rdata

Чтобы посмотреть, где используется текущий адрес, жмем Ctrl+X и получаем список перекрестных ссылок. Механизм называется XRefs или перекрестные ссылки.

Переходим по единственной перекрестной ссылке:

Перекрестные ссылки

Перейдя по ссылке, видим, что строка используется чуть ниже заполнения массива check (адрес 401640) в функции puts (вывод в стандартный поток вывода, в данном случае – консоль):

Ниже (адрес 40165D) замечаем вызов scanf (форматированный ввод из стандартного потока ввода) с параметрами %s и указателем flag . Значит, flag – строка, вводимая пользователем.

Спускаемся еще ниже и видим зануление значения по адресу i (адрес 401662) и на следующей строке безусловный переход на метку loc_4016b2 . Метка – название для адреса в секции кода. Переходим по этой метке, дважды нажав на loc_4016b2 .

Здесь (адрес 4016B2) мы видим сравнение i с числом 24 (18h), условный переход на метку loc_40166B , который сработает, если i будет меньше или равно 24. Если i будет больше 24, переход не произойдет и будет вызвана функция puts(“GOOD JOB, HACKER”) :

Перейдя по метке loc_40166B , видим, что в этом участке кода производятся манипуляции с массивами flag (адрес 401670) и check (адрес 401691):

Первым делом значение i помещается в регистр eax и расширяется до rax командой cdqe (адреса 40166B и 40166E). Физически eax – младшая половина регистра rax :

Схема регистров

Копаем глубже

Подробнее о регистрах можно узнать в статье Регистры процессора.

Строкой ниже (адрес 401670) в eax помещается значение, находящееся по адресу flag+rax c помощью команды movzx ( rax в два раза больше eax , поэтому используется movzx , где zx означается, что данные, находящиеся в eax дополняются нулями). Сопоставив эту строку с двумя предыдущими, понимаем, что в rax помещается i-ый элемент массива flag .

По адресу 401678 от регистра rax остается только младший байт, и расширяется до знакового четырех байтового числа командой movsx eax, al . Позже будет понятно зачем.

Далее для содержимого eax вызывается функция enc (строки 401682-401687). Параметр функции передается в регистре ecx . Кликнув дважды enc попадаем в ее тело:

Функция enc

Благодаря отладочным символам, видим, что функция возвращает тип int –четырёхбайтовое знаковое число и имеет соглашение о вызовах cdecl , а значит ее результат, возвращаемый в return будет храниться в регистре eax . При этом, параметр letter , передаваемый в функцию – четырёхбайтовое знаковое целое. Именно поэтому ранее мы видели расширение до четырёхбайтового целого.

На эту тему на хабре есть статья Соглашения о вызовах.

Расширение до четырех байт нужно для проверки модифицированного flag[i] , имеющего однобайтовый тип с некоторым четырёхбайтовым элементом check .

В функции видим, что ecx сохраняется в переменную letter (адрес 401574), а затем, строкой ниже, значение переменной сохраняется в eax .

Следующей строкой со значением регистра eax производят операцию xor eax, 0BADh – побитового исключающего ИЛИ с числом 0x0BAD.

На этом тело функции заканчивается, значит, результатом ее исполнения является:

xor(flag[i], 0x0BAD)

Вернемся к коду, вызывающему эту функцию:

После вызова функции enc видим (адрес 401682), что результат ее выполнения, хранящийся в eax , увеличивается на 0x24 и для полученного значения снова вызывается функция enc .

В результате второго выполнения enc со значением flag[i] произведено действие:

xor(xor(flag[i], 0x0BAD+0x24),0x0BAD)

Разберемся далее построчно:

  1. 40168C: результат второго выполнения enc сохраняется в edx
  2. 40168E и 401691: значение i помещается в rax .
  3. 401693: в eax сохраняется значение check[rax*4] , что означает сохранение в eax check[i*4]
  4. 401697-401699: полученное значение для i-го элемента флага сравнивается с check[i*4] , и если значения равны, происходит переход на метку loc_4016AE

Переходим на метку и видим (адрес 4016AE) увеличение значения i на единицу:

После увеличения значения i снова попадаем на сравнение с 24. Так мы понимаем, что попали в цикл.

Подтвердить это предположение можно перейдя в графическое представление кода, нажав на пробел. Метка, на которой мы сейчас находимся на скриншоте подсвечена желтым:

Цикл в IDA

В IDA зеленые стрелки означают верный результат при сравнении, красные – неверный, синие – безусловный переход (может быть как признаком команды jmp , так и вовсе отсутствия команды j*).

Обратив внимание на условный переход jle на метку loc_40166B , понимаем – чтобы на нее не переходить и добиться вывода GOOD JOB, HACKER, необходимо пройти целиком весь цикл.

Алгоритм проверки флага

В результате обратной разработки функции проверки введенного флага, имеем уравнение, в котором неизвестным является flag[i] :

(flag[i] ^ 0x0BAD + 36) ^ 0x0BAD = check[i]

Так как xor является обратимой функцией, получим flag[i] из check[i] :

int flag[i] = (check[i] ^ 0x0BAD – 36) ^ 0x0BAD

Далее остается только взять младший байт от flag[i] . Возьмем значения элементов массива из дизассемблированного кода и напишем простую программу на C:

int main() < int check[25]; char flag[25]; int i; check[0] = 1983; check[1] = 1963; check[2] = 1952; check[3] = 1953; check[4] = 1982; check[5] = 1973; check[6] = 87; check[7] = 70; check[8] = 1969; check[9] = 1967; check[10] = 80; check[11] = 1979; check[12] = 93; check[13] = 1979; check[14] = 1967; check[15] = 109; check[16] = 73; check[17] = 1964; check[18] = 72; check[19] = 111; check[20] = 1979; check[21] = 84; check[22] = 108; check[23] = 1966; check[24] = 89; for (int i = 0; i printf(flag); >

В результате выполнения получаем флаг, который вставляем в консоль и убеждаемся в его правильности.

В заключение скажем, что можно было так не страдать, сразу нажать волшебную кнопку F5, декомпилировать код и получить что-то вроде этого:

Однако, понимания в реверсе это не добавит. IDA не всегда декомпилирует во что-то читабельное (особенно при отсутствии отладочной информации), и все равно нужно сидеть над ассемблером и изучать, кто на ком стоял.

Заключение

В статье мы решили несложную задачу с применением реверс-инжиниринга. Познакомились с дизассемблером IDA и некоторыми его возможностями. Посмотрели, как выглядит код без отладочной информацией, и что в таком случае делать. Сделали теоретические отступления на тему секций и адресов.

Реверс-инжиниринг для начинающих: основные концепции программирования

Обложка поста Реверс-инжиниринг для начинающих: основные концепции программирования

В этой статье мы заглянем под капот программного обеспечения. Новички в реверс-инжиниринге получат общее представление о самом процессе исследования ПО, общих принципах построения программного кода и о том, как читать ассемблерный код.

Примечание Программный код для этой статьи компилируется с помощью Microsoft Visual Studio 2015, так что некоторые функции в новых версиях могут использоваться по-другому. В качестве дизассемблера используется IDA Pro.

  1. Инициализация переменных
  2. Стандартная функция вывода
  3. Математические операции
  4. Вызов функций
  5. Циклы
  6. Условный оператор
  7. Оператор выбора
  8. Пользовательский ввод

Инициализация переменных

Переменные — одна из основных составляющих программирования. Они делятся на несколько видов, вот некоторые из них:

  • строка;
  • целое число;
  • логическая переменная;
  • символ;
  • вещественное число с двойной точностью;
  • вещественное число;
  • массив символов.
string stringvar = "Hello World"; int intvar = 100; bool boolvar = false; char charvar = 'B'; double doublevar = 3.1415; float floatvar = 3.14159265; char carray[] = < 'a', 'b', 'c', 'd', 'e' >; 

Примечание в С++ строка — не примитивная переменная, но важно понять, как она будет выглядеть в машинном коде.

Давайте посмотрим на ассемблерный код:

Здесь можно увидеть как IDA показывает распределение пространства для переменных. Сначала под каждую переменную выделяется пространство, а потом уже она инициализируется.

Реверс-инжиниринг для начинающих: основные концепции программирования 1

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

Реверс-инжиниринг для начинающих: основные концепции программирования 2

Для инициализации строки требуется вызов встроенной функции.

Стандартная функция вывода

Примечание Здесь речь пойдёт о том, что переменные помещаются в стек и затем используются в качестве параметров для функции вывода. Концепт функции с параметрами будет рассмотрен позднее.

Для вывода данных было решено использовать printf() , а не cout .

printf("Hello String Literal"); printf("%s", stringvar); printf("%i", intvar); printf("%c", charvar); printf("%f", doublevar); printf("%f", floatvar); printf("%c", carray[3]); 

Теперь посмотрим на машинный код. Сначала строковый литерал:

Реверс-инжиниринг для начинающих: основные концепции программирования 3

Как видите, строковый литерал сначала помещается в стек для вызова в качестве параметра функции printf() .

Теперь посмотрим на вывод одной из переменных:

Реверс-инжиниринг для начинающих: основные концепции программирования 4

Как можно заметить, сначала переменная intvar помещается в регистр EAX, который в свою очередь записывается в стек вместе со строковым литералом %i , используемым для обозначения целочисленного вывода. Эти переменные затем берутся из стека и используются в качестве параметров при вызове функции printf() .

Математические операции

Сейчас мы поговорим о следующих математических операциях:

  1. Сложение.
  2. Вычитание.
  3. Умножение.
  4. Деление.
  5. Поразрядная конъюнкция (И).
  6. Поразрядная дизъюнкция (ИЛИ).
  7. Поразрядное исключающее ИЛИ.
  8. Поразрядное отрицание.
  9. Битовый сдвиг вправо.
  10. Битовый сдвиг влево.
void mathfunctions() < // математические операции int A = 10; int B = 15; int add = A + B; int sub = A - B; int mult = A * B; int div = A / B; int and = A & B; int or = A | B; int xor = A ^ B; int not = ~A; int rshift = A >> B; int lshift = A

Переведём каждую операцию в ассемблерный код:

сначала присвоим переменной A значение 0A в шестнадцатеричной системе счисления или 10 в десятичной. Переменной B — 0F , что равно 15 в десятичной.

Реверс-инжиниринг для начинающих: основные концепции программирования 5

Для сложения мы используем инструкцию add :

Реверс-инжиниринг для начинающих: основные концепции программирования 6

При вычитании используется инструкция sub :

Реверс-инжиниринг для начинающих: основные концепции программирования 7

При умножении — imul :

Реверс-инжиниринг для начинающих: основные концепции программирования 8

Для деления используется инструкция idiv . Также мы используем оператор cdq , чтобы удвоить размер EAX и результат деления уместился в регистре.

Реверс-инжиниринг для начинающих: основные концепции программирования 9

При поразрядной конъюнкции используется инструкция and :

Реверс-инжиниринг для начинающих: основные концепции программирования 10

При поразрядной дизъюнкции — or :

Реверс-инжиниринг для начинающих: основные концепции программирования 11

При поразрядном исключающем ИЛИ — xor :

Реверс-инжиниринг для начинающих: основные концепции программирования 12

При поразрядном отрицании — not :

Реверс-инжиниринг для начинающих: основные концепции программирования 13

При битовом сдвиге вправо — sar :

Реверс-инжиниринг для начинающих: основные концепции программирования 14

При битовом сдвиге влево — shl :

Реверс-инжиниринг для начинающих: основные концепции программирования 15

Вызов функций

Мы рассмотрим три вида функций:

  1. Функция, не возвращающая значение (void).
  2. Функция, возвращающая целое число.
  3. Функция с параметрами.
newfunc(); newfuncret(); funcparams(intvar, stringvar, charvar); 

Сначала посмотрим, как происходит вызов функций newfunc() и newfuncret() , которые вызываются без параметров.

Реверс-инжиниринг для начинающих: основные концепции программирования 16

Функция newfunc() просто выводит сообщение «Hello! I’m a new function!»:

void newfunc() < // новая функция без параметров printf("Hello! I'm a new function"!); > 

Эта функция использует инструкцию retn , но только для возврата к предыдущему местоположению (чтобы программа могла продолжить свою работу после завершения функции). Посмотрим на функцию newfuncret() , которая генерирует случайное целое число с помощью функции С++ rand() и затем его возвращает.

int newfuncret() < // новая функция, которая что-то возвращает int A = rand(); return A; > 

Реверс-инжиниринг для начинающих: основные концепции программирования 17

Сначала выделяется место под переменную A . Затем вызывается функция rand() , результат которой помещается в регистр EAX. Затем значение EAX помещается в место, выделенное под переменную A , фактически присваивая переменной A результат функции rand() . Наконец, переменная A помещается в регистр EAX, чтобы функция могла его использовать в качестве возвращаемого параметра. Теперь, когда мы разобрались, как происходит вызов функций без параметров и что происходит при возврате значения из функции, поговорим о вызове функции с параметрами.

Вызов такой функции выглядит следующим образом:

funcparams(intvar, stringvar, charvar); 

Вызов функции с параметрами

Строки в С++ требуют вызова функции basic_string , но концепция вызова функции с параметрами не зависит от типа данных. Сначала переменная помещается в регистр, затем оттуда в стек, а потом происходит вызов функции.

Посмотрим на код функции:

void funcparams (int iparam, string sparam, char cparam) < // функция с параметрами printf("%i \n", iparam); printf("%s \n", sparam); printf("%c \n", cparam); > 

Реверс-инжиниринг для начинающих: основные концепции программирования 18

Эта функция берёт строку, целое число и символ и печатает их с помощью функции printf() . Как видите, сначала переменные размещаются в начале функции, затем они помещаются в стек для вызова в качестве параметров функции printf() . Очень просто.

Циклы

Теперь, когда мы изучили вызов функции, вывод, переменные и математику, перейдём к контролю порядка выполнения кода (flow control). Сначала мы изучим цикл for:

void forloop (int max) < // обычный цикл for for (int i = 0; i < max; ++i)< printf("%i \n", i); >> 

Реверс-инжиниринг для начинающих: основные концепции программирования 19

Прежде чем разбить ассемблерный код на более мелкие части, посмотрим на общий вариант. Как вы можете видеть, когда цикл for запускается, у него есть 2 варианта:

  • он может перейти к блоку справа (зелёная стрелка) и вернуться в основную программу;
  • он может перейти к блоку слева (красная стрелка) и вернуться к началу цикла for.

Реверс-инжиниринг для начинающих: основные концепции программирования 20

Сначала сравниваются переменные i и max , чтобы проверить, достигла ли переменная максимального значения. Если переменная i не больше или не равна переменной max , то подпрограмма пойдёт по красной стрелке (вниз влево) и выведет переменную i , затем i увеличится на 1 и произойдёт возврат к началу цикла. Если переменная i больше или равна max , то подпрограмма пойдёт по зелёной стрелке, то есть выйдет из цикла for и вернётся в основную программу.

Теперь давайте взглянем на цикл while :

void whileloop() < // цикл while int A = 0; while (A<10) < A = 0 + (rand()%(int)(20-0+1)) >printf("I'm out!"); > 

Реверс-инжиниринг для начинающих: основные концепции программирования 21

В этом цикле генерируется случайное число от 0 до 20. Если число больше 10, то произойдёт выход из цикла со словами «I’m out!», в противном случае продолжится работа в цикле.

В машинном коде переменная А сначала инициализируется и приравнивается к нулю, а затем инициализируется цикл, A сравнивается с шестнадцатеричным числом 0A , которое равно 10 в десятичной системе счисления. Если А не больше и не равно 10, то генерируется новое случайное число, которое записывается в А , и снова происходит сравнение. Если А больше или равно 10, то происходит выход из цикла и возврат в основную программу.

Условный оператор

Теперь поговорим об условных операторах. Для начала посмотрим код:

void ifstatement() < // условные операторы int A = 0 + (rand()%(int)(20-0+1)); if (A < 15) < if (A < 10) < if (A < 5) < printf("less than 5"); >else < printf("less than 10, greater than 5"); >> else < printf("less than 15, greater than 10"); >> else < printf("greater than 15"); >> 

Эта функция генерирует случайное число от 0 до 20 и сохраняет получившееся значение в переменной А . Если А больше 15, то программа выведет «greater than 15». Если А меньше 15, но больше 10 — «less than 15, greater than 10». Если меньше 5 — «less than 5».

Посмотрим на ассемблерный граф:

Реверс-инжиниринг для начинающих: основные концепции программирования 22

Граф структурирован аналогично фактическому коду, потому что условный оператор выглядит просто: «Если X, то Y, иначе Z». Если посмотреть на первую сверху пару стрелок, то оператору предшествует сравнение А с 0F , что равно 15 в десятичной системе счисления. Если А больше или равно 15, то подпрограмма выведет «greater than 15» и вернётся в основную программу. В другом случае произойдёт сравнение А с 0A (1010). Так будет продолжаться, пока программа не выведет что-нибудь на экран и не вернётся.

Оператор выбора

Оператор выбора очень похож на оператор условия, только в операторе выбора одна переменная или выражение сравнивается с несколькими «случаями» (возможными эквивалентностями). Посмотрим код:

void switchcase() < // оператор выбора int A = 0 + (rand()%(int)(10-0+1)); switch (A) < case 0: printf("0"); break; case 1: printf("1"); break; case 2: printf("2"); break; case 3: printf("3"); break; case 4: printf("4"); break; case 5: printf("5"); break; case 6: printf("6"); break; case 7: printf("7"); break; case 8: printf("8"); break; case 9: printf("9"); break; case 10: printf("10"); break; >> 

В этой функции переменная А получает случайное значение от 0 до 10. Затем А сравнивается с несколькими случаями, используя switch . Если значение А равно одному из случаев, то на экране появится соответствующее число, а затем произойдёт выход из оператора выбора и возврат в основную программу.

Оператор выбора не следует правилу «Если X, то Y, иначе Z» в отличии от условного оператора. Вместо этого программа сравнивает входное значение с существующими случаями и выполняет только тот случай, который соответствует входному значению. Рассмотрим два первых блока подробней.

Реверс-инжиниринг для начинающих: основные концепции программирования 23

Сначала генерируется случайное число и записывается в А . Теперь программа инициализирует оператор выбора, приравняв временную переменную var_D0 к А , затем проверяет, что она равна хотя бы одному из случаев. Если var_D0 требуется значение по умолчанию, то программа пойдёт по зелёной стрелке в секцию окончательного возврата из подпрограммы. Иначе программа совершит переход в нужный case .

Реверс-инжиниринг для начинающих: основные концепции программирования 24

Если var_D0 (A) равно 5, то код перейдёт в секцию, которая показана выше, выведет «5» и затем перейдёт в секцию возврата.

Пользовательский ввод

В этом разделе мы рассмотрим ввод пользователя с помощью потока сin из C++. Во-первых, посмотрим на код:

void userinput() < // ввод с клавиатуры string sentence; cin >> sentence; printf("%s", sentence); > 

В этой функции мы просто записываем строку в переменную sentence с помощью функции C++ cin и затем выводим предложение с помощью оператора printf() .

Разберём это в машинном коде. Во-первых, функция cin :

Реверс-инжиниринг для начинающих: основные концепции программирования 25

Сначала происходит инициализация строковой переменной sentence , затем вызов cin и запись введённых данных в sentence .

Реверс-инжиниринг для начинающих: основные концепции программирования 26

Сначала программа устанавливает содержимое переменной sentence в EAX, затем помещает EAX в стек, откуда значение переменной будет использоваться в качестве параметра для потока cin , затем вызывается оператор потока >>. Его вывод помещается в ECX, который затем помещается в стек для оператора printf() :

Реверс-инжиниринг для начинающих: основные концепции программирования 27

Мы рассмотрели лишь основные принципы работы программного обеспечения на низком уровне. Без этих основ невозможно понимать работу ПО и, соответственно, заниматься его исследованием.

Что такое обратная разработка и где она применяется

Что такое обратная разработка и где она применяется

Обратная разработка — метод разборки объекта, который помогает понять, как сконструировано ранее созданное устройство, процесс, система или часть программного обеспечения. Инженер разбирает продукт на части, чтобы понять, как он работает, а потом воссоздать похожее или идентичное решение. Разработчик отвечает на вопрос: «Какие процессы провоцируют именно такое поведение продукта?».

Таким способом не удастся получить точный исходный код, но инженеры смогут понять общую логику работы и повторить функционал.

Часто встречаются названия «обратное проектирование», «обратный инжиниринг», «реверс-инжиниринг» — они означают одно и то же.

Где применяется реверс-инжиниринг

Обратный инжиниринг применяют в компьютерной инженерии, геймдеве, машиностроении, дизайне, электронной инженерии, разработке программного обеспечения, химической инженерии и даже системной биологии.

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

В IT обратная разработка программ применяется для исследования софта и железа, их элементов и принципов работы.

Объектами могут быть:

  • файлы — чтобы узнать, как именно работает приложение;
  • часть операционной системы — чтобы использовать недокументированные функции;
  • формат данных — чтобы получить структуру файлового формата;
  • сетевой протокол — чтобы восстановить формат пакетов данных и последовательность обмена данными.

Для чего используют обратную разработку:

  • поиск и исправление ошибок в программах, к исходному коду которых у разработчиков нет доступа;
  • анализ вирусов для создания антивирусного программного обеспечения;
  • улучшение функциональности приложения, когда связаться с предыдущим разработчиком не получается — например, компания-разработчик перестала существовать;
  • описание механики игры, когда разработчик берет в пример существующую игру, наблюдает за ее развитием, анализирует сценарий и предлагает свой вариант;
  • обучение: если разработчик не понимает какую-то часть своего продукта, он может проанализировать чужую и сделать выводы о ее функционировании.

Реверс-инжиниринг также применяют для нелегальных целей — кражи кода, обхода технических средств защиты авторских прав, бесконечного использования бесплатных версий приложения.

Типы реверс-инжиниринга

Существуют десятки видов обратной разработки, поскольку процесс может разбить объект на части по-разному — например, анализ системного уровня, извлечение схемы и разборка продукта.

Принципы обратной разработки

Процесс обратной разработки регулируют общие принципы:

  • 1. Не путать гипотезы с выводами. Обратный инжиниринг дает гипотезы. Разработчик должен полностью понять приложение, прежде чем делать выводы.
  • 2. Получить несколько интерпретаций. Альтернативные интерпретации данных могут давать разные результаты. Чем больше информации доступно, тем меньше должны различаться суждения реверс-инженеров.
  • 3. Понимать, что результаты приблизительны. К примеру, 80% информации девелопер получит благодаря обратной разработке. Чтобы получить оставшиеся 20%, нужно использовать методы прямого проектирования, например, опрос пользователей.
  • 4. Не удивляться странным конструкциям. Инженер не сможет воссоздать полную и точную модель, потому что такой модели до этого, возможно, не существовало.
  • 5. Следить за единым стилем. Продукт разрабатывают с использованием последовательной стратегии, которую нужно найти и понять.

Этапы реверс-разработки на примере исполняемого файла:

  • 1. Запустить и протестировать исполняемый файл, ознакомиться с приложением и его возможностями.
  • 2. Проанализировать взаимодействие файла с внешним миром: библиотеками, процессами, системными API, файловой системой, сетевыми взаимодействиями, физическими портами и т. д.
  • 3. Детально изучить код. Для этого применяют трансляцию двоичного кода на язык ассемблера, чтобы затем извлечь структуры, инструкции и вызовы функций.

Реверс-инжиниринг *

Реверс-инжиниринг ToumaPet, китайского клона тамагочи с цветным экраном

Уровень сложности Средний
Время на прочтение 14 мин
Количество просмотров 5K

Когда становишься слишком взрослым, то просто играть в игры становится не интересно. Зато разбираться в их устройстве увлекательно, я нашел себе новый объект для развлечения. На самом деле я с детства разбирал/ломал игрушки, чтобы посмотреть как внутри устроено. Так что, это не лечится и с возрастом никак не связано.

Всего голосов 99: ↑98 и ↓1 +97
Добавить в закладки 38

Новости

все подряд лучшие

Реверс-инжиниринг электромеханического компьютера с самолёта-истребителя

Уровень сложности Средний
Время на прочтение 14 мин
Количество просмотров 17K

Определить скорость полёта и высоту самолёта-истребителя сложнее, чем можно представить. При низких скоростях высоту, скорость полёта и другие «воздушные данные» можно рассчитывать по показаниям давления. Но когда самолёт близок к скорости звука, для точного вычисления этих значений требуются сложные уравнения.

В истребителях F-101 и F-111, в бомбардировщике B-58 ВВС США эту задачу решал Bendix Central Air Data Computer (CADC) 1 .

[1. Мне не удалось найти полный список самолётов, в которых использовался CADC. Судя по различным источникам, он применялся в F-86, F-101, F-104, F-105, F-106, F-111, а также в бомбардировщике B-58.]

Это электромеханическое чудо техники было реализовано на основе лучших технологий 1955 года: шестерней, кулачков, сельсинов и магнитных усилителей. В этом посте я загляну внутрь CADC, расскажу о выполняемых им расчётах и объясню, как он производил эти расчёты механически.

Всего голосов 121: ↑118 и ↓3 +115
Добавить в закладки 77

Анализ системы защиты от ботов на примере letu.ru

Уровень сложности Средний
Время на прочтение 40 мин
Количество просмотров 4.5K

Анализ системы защиты сайта от ботов на примере letu.ru с использованием javascript reverse engineering.

Всего голосов 28: ↑28 и ↓0 +28
Добавить в закладки 54

Скачать фильмы за креды без СМС и регистрации: история одного supply chain под Linux

Уровень сложности Средний
Время на прочтение 9 мин
Количество просмотров 5.1K

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

В этой статье я, Леонид Безвершенко, и мой коллега, Георгий Кучерин, — Security Researcher-ы в Глобальном центре исследования и анализа угроз (GReAT) «Лаборатории Касперского» — расскажем о нашем совместном исследовании, позволяющем проследить, как жертвы, сами того не зная, устанавливали себе зараженный Debian-пакет менеджера загрузок с официального сайта.

image

Наше исследование началось с того, что мы получили образ диска и дамп памяти одного ноутбука на операционной системе Linux. Предполагалось, что этот ноутбук был скомпрометирован. Нашей задачей было опровергнуть это или, наоборот, доказать, поняв, что там вообще произошло.

Всего голосов 23: ↑23 и ↓0 +23
Добавить в закладки 22

Истории

Когда Random совсем не случаен

Уровень сложности Средний
Время на прочтение 7 мин
Количество просмотров 17K

Этот пост — рассказ об истории, случившейся больше десятка лет назад; её код был мной утерян. Поэтому прошу простить меня, если я не вспомню точно все подробности. Кроме того, некоторые подробности упрощены, чтобы от этой статьи могли получить все, кому нравится компьютерная безопасность, а не только любители World of Warcraft (хотя, полагаю, диаграмма Венна этих двух групп сильно пересекается).

Когда мне было примерно 14 лет, я узнал об игре World of Warcraft компании Blizzard Games, и она сразу же меня увлекла. Вскоре после этого я нашёл аддоны, позволявшие модифицировать внешний вид и функциональность интерфейса игры. Однако не все скачанные мной аддоны делали именно то, что мне было нужно. Мне хотелось большего, поэтому я начал разбираться, как они сделаны.

Забавно, что в моём серьёзном увлечении программированием можно обвинить World of Warcraft. Оказалось, что код был написан на языке Lua. Аддоны — это просто парочка файлов исходного кода на .lua в папке, напрямую загружаемых в игру. Барьер входа был невероятно низок: достаточно отредактировать файл, сохранить его и перезапустить интерфейс. То, что игра загружала твой исходный код и ты мог видеть его работу, было настоящим волшебством!

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

Всего голосов 116: ↑115 и ↓1 +114
Добавить в закладки 77

Как нашли бэкдор в радиосвязи TETRA — подробный разбор

Уровень сложности Средний
Время на прочтение 19 мин
Количество просмотров 24K

Неприступных крепостей не бывает. Опасную брешь, то есть бэкдор, недавно обнаружили в шифрованном стандарте радиосвязи TETRA. А ведь он вот уже 25 лет используется военными, экстренными службами и объектами критической инфраструктуры по всему миру. Самое интересное, что на технические детали и контекст этой истории почти никто не обратил внимания.

Мы изучили статьи и доклады исследователей и собрали всю суть. Перед вами — подробная история взлома TETRA.

Всего голосов 216: ↑215 и ↓1 +214
Добавить в закладки 125

Пример исследовательского реверс-инжиниринга приложения Zone Launcher

Уровень сложности Средний
Время на прочтение 6 мин
Количество просмотров 5.2K

Друг порекомендовал приложение, но купить его не получилось с территории России. Статья о том, как поисследовать приложение до той степени, чтобы покупка потеряла свою актуальность. Может быть полезно почитать и разработчикам, чтобы понимать, что полную версию приложение включить достаточно легко.

Всего голосов 27: ↑27 и ↓0 +27
Добавить в закладки 77

Reflective Injection действительно так неотразим?

Уровень сложности Средний
Время на прочтение 3 мин
Количество просмотров 1.4K

С развитием технологий безопасности и защиты от киберугроз, появляются различные новые методы атак. Одна из сфер которая постоянно развивается в своих возможностях, называется Code Injection. В системах под управлением Windows, это стало весьма распространённым явлением. Поэтому сегодня мы обсудим один из таких способов для инъекции кода, — Reflective Injection.

Ранее на Хабре уже обсуждался и данный способ, и различные другие, поэтому конкретно в данной статье мы затронем способ защиты от подобного метода атак.

Всего голосов 3: ↑3 и ↓0 +3
Добавить в закладки 11

Еще один год из жизни ReactOS

Время на прочтение 6 мин
Количество просмотров 14K
Ретроспектива

Здравствуйте, дорогие друзья!

Вот и заканчивается 2023 год. В этой статье я хочу продолжить начатую в 2021 году традицию вспоминания наиболее важных событий из жизни ReactOS за год. То что статьи не появляются на Хабре, не значит что система мертва. Медленно, но верно, в ReactOS реализуются разные фичи и исправляются баги. И в данной статье мы рассмотрим что произошло в жизни системы в 2023 году.

Всего голосов 114: ↑112 и ↓2 +110
Добавить в закладки 30

Process Memory Map

Время на прочтение 3 мин
Количество просмотров 6.3K

Я программист, а то что я еще и реверсер — ну. так совпало. И как любому из людей занимающимся реверсом мне всегда не хватает функционала отладчика. Постоянно приходится допиливать под конкретную задачу какие-то утилитарные вещи и однажды.
Однажды я решил — хватит, каждый раз пилить новое достаточно утомительно, а что если взять и объединить все наработки в один инструмент и пользоваться именно им!
Это будет скорее рекламный пост — но не спешите минусовать, возможности утилиты, о которой пойдет речь, а называется она Process Memory Map, весьма обширны, и возможно вам понравится 🙂

Итак — что это такое? Она похожа на всем известный инструмент от Марка Руссиновича VMMap (которая кстати частично основана на коде Джефри Рихтера), её задача проанализировать сторонний процесс и вытащить из него максимум данных, о которых она знает.

Всего голосов 63: ↑63 и ↓0 +63
Добавить в закладки 67

Паяльная станция «Магистр НеоТерм-3Т». Что внутри?

Уровень сложности Простой
Время на прочтение 4 мин
Количество просмотров 13K

Вы любите паять? А я очень! В любом занятии важен инструмент. Вот и пайка не исключение. А если работать с другом, то всё становится гораздо интереснее и веселее. Сегодня познакомимся со станцией «НеоТерм-3Т», заглянем внутрь. Узнаем простое, но эффективное и красивое схемное решение и некоторые забавные, но весьма удобные хитрости пайки.

Всего голосов 37: ↑37 и ↓0 +37
Добавить в закладки 42

Реверс-инжиниринг и ремонт платы зарядного устройства

Уровень сложности Простой
Время на прочтение 18 мин
Количество просмотров 3.6K

image

Волею случая у меня в руках оказались две неисправные платы от зарядного устройства тяговых аккумуляторов LiFePo. Параметры платы вызывают уважение – она выдает в номинале 48 В при токе до 60 А, то есть мощность платы порядка 3 кВт. Плата подключается к однофазной сети 220/230В. Всего в зарядном устройстве стоит несколько таких плат, они все подключаются параллельно и работают на общую нагрузку. Выпускаются варианты таких зарядных устройств с разным числом плат, соответственно, на разный зарядный ток. Например, как на фото ниже — 3 платы, 180 А.

Всего голосов 35: ↑35 и ↓0 +35
Добавить в закладки 35

Кого на самом деле убил Энтони: разбор полётов

Уровень сложности Простой
Время на прочтение 3 мин
Количество просмотров 5.2K

Череп снова вернулся и в этот раз организовал нечто масштабное. Хакеру понадобилась сильная команда для взлома государства F и он пригласил всех желающих попробовать стать его напарниками в этом деле. Волнует лишь один вопрос…. Кого же убил Энтони?

Всего голосов 45: ↑42 и ↓3 +39
Добавить в закладки 19

Ближайшие события

Дата 30 января
Время 10:00 – 18:30
Москва • Онлайн

Дата 30 января
Время 20:00

Дата 31 января
Время 20:00

Дата 1 февраля
Время 20:00
Влево Вправо

Запускаем раритетный вольтметр на газоразрядных индикаторах

Уровень сложности Средний
Время на прочтение 7 мин
Количество просмотров 4.6K

Приветствую всех!
Часы и термометры с индикацией на ГРИ уже давно стали своеобразным культом в мире электронщиков (а для кого-то — целым бизнесом). Тем сильнее мне хотелось заполучить в коллекцию какой-то прибор промышленного изготовления с индикацией на таких лампах.
Удивительно, но на найденный мною экземпляр в интернете оказалось очень мало информации. А это значит, что самое время поделиться тем, как его подключить и как он работает.

Итак, в сегодняшней статье поговорим о щитовых приборах серии Ф294-Ф299. Узнаем, как они устроены и работают, рассмотрим такой аппарат вместе с полным комплектом, а также разберёмся, зачем ремонтировать новый прибор и как вернуть его к жизни после долгих лет простоя. Традиционно будет много интересного.

Всего голосов 47: ↑47 и ↓0 +47
Добавить в закладки 15

Санком. Неизвестный производитель оптических домофонов

Уровень сложности Средний
Время на прочтение 14 мин
Количество просмотров 7.4K

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

Итак, сегодня поговорим об оптических считывателях и домофонах ранее неизвестной мне фирмы. Узнаем, как работали их ключи и разберёмся, как всё это запустить. Традиционно будет много интересного.

Всего голосов 45: ↑45 и ↓0 +45
Добавить в закладки 11

Анализ виртуальной машины на примере VMProtect. Часть 1

Уровень сложности Средний
Время на прочтение 10 мин
Количество просмотров 1.2K

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

Ожидается, что данный материал поможет тем, кто в ходе реагирования на компьютерный инцидент или исследования какой-либо вредоносной активности столкнулся с защитой в виде виртуальной машины.

Всего голосов 1: ↑1 и ↓0 +1
Добавить в закладки 14

Зачем на камере и видеорегистраторе нужен криптоблок и как его восстановить

Уровень сложности Средний
Время на прочтение 11 мин
Количество просмотров 7.4K

Представьте себе ситуацию, когда на камере наблюдения испортилась флэшка с прошивкой, и камера нуждается в ремонте. Берём копеечную флэшку и меняем, а прошивку скопируем с точно такой же камеры. Пять минут рекламы, и теперь камера работает и показывает видеопоток вновь. Но есть нюанс. Дело в том, что она теперь является полной копией камеры-донора прошивки. Это и ежу понятно, они же и были одинаковыми — возразите вы. Были одинаковыми всем, кроме таких настроек, как MAC-адрес и идентификатор в облаке, куда камера сливает свой видеопоток. А теперь они совсем близнецы.

Когда распространились камеры с облачным доступом, массово решились такие проблемы, как доступ к камере без внешнего IP-адреса или с динамическим адресом. Теперь стало ненужным использовать проброс портов на роутере, VPN, динамический DNS, требующие целой инфраструктуры для доступа к камере. Запускай себе приложение, и оно получит доступ к видеопотоку или к архиву через облако. Производители камер в то время пробовали различные варианты, которые часто заканчивались печальными результатами, как с камерами Foscam, связанные с тем, что производитель выбрал путь простоты и дешевизны, а пользователи за него проголосовали рублём. Камеры становились легкодоступными, дешёвыми и, в конце концов, собой просто заполонили весь мир, проникнув в магазины, детские сады, зоопарки, аэропорты, бары, подъезды, офисы, входы, выходы, проходы, пароходы и даже в спальни с туалетами. В крупнейшем каталоге камер insecam.org тогда были сотни тысяч камер со всего мира.

Всего голосов 53: ↑53 и ↓0 +53
Добавить в закладки 53

Старый софт: как мы обошли запрос пароля в Shadow Defender и зачем пользоваться приложением, которое не обновляется

Время на прочтение 11 мин
Количество просмотров 2K

Привет, Хабр! Меня зовут Илья Буймистров, я занимаюсь исследованиями в области инфобеза для сервиса централизованного управления уязвимостями CICADA8. Это один из проектов блока инноваций FC компании МТС RED.

Чтобы защищать пользователей, надо понимать, где слабые места в их ИТ-системах. Сегодня я расскажу, как можно обойти ввод пароля в достаточно известной программе Shadow Defender. Если вы росли в 2000-х, наверняка сталкивались с ней в компьютерных клубах и других местах, где ПК доступен большому количеству людей. Иногда её называют антивирусом, но не совсем точное определение. Обо всём по порядку.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *