Синхронизация | Как смотреть картины
Я в восторге! Довольно часто посещаю лекции по живописи. Когда рассказывает Наталья Вострикова, это всегда ярко, очень информативно, живо, эмоционально. Даже если не успевает по времени, всегда задержится. Всем рекомендую.
Кира Куркина
«Эпохи и стили в живописи. Практикум»
Кира Куркина
«Эпохи и стили в живописи. Практикум»
Я в восторге! Довольно часто посещаю лекции по живописи. Когда рассказывает Наталья Вострикова, это всегда ярко, очень информативно, живо, эмоционально. Даже если не успевает по времени, всегда задержится. Всем рекомендую.
Восторг!!! Наталья Вострикова супер- лектор,4 часа пролетели незаметно, много интересного узнала, буду и дальше по мере возможности ходить на ваши лекции. Спасибо за ваш труд!
Анжела Осипова
«Сюжеты и символы в живописи. Практикум»
Анжела Осипова
«Сюжеты и символы в живописи. Практикум»
Восторг!!! Наталья Вострикова супер- лектор,4 часа пролетели незаметно, много интересного узнала, буду и дальше по мере возможности ходить на ваши лекции. Спасибо за ваш труд!
Наталья читает лекцию увлеченно, эмоционально, вовлекает в рассказ — и наконец-то тексты скучных школьных учебников обрели жизнь. После лекции захотелось продолжить банкет, пойдя гулять по улицам и музеям) Из пожеланий — захотелось немного сократить практическую часть, а на постмодерн наоборот добавить времени.
Юлия Баукова
«Эпохи и стили в живописи. Практикум»
Юлия Баукова
«Эпохи и стили в живописи. Практикум»
Наталья читает лекцию увлеченно, эмоционально, вовлекает в рассказ — и наконец-то тексты скучных школьных учебников обрели жизнь. После лекции захотелось продолжить банкет, пойдя гулять по улицам и музеям)
Из пожеланий — захотелось немного сократить практическую часть, а на постмодерн наоборот добавить времени.
Лекция очень и очень интересная. Действительно начинаешь понимать картины на более глубоком уровне. Плюс Наталья — великолепный рассказчик! Искренне рекомендую посетить эту лекцию.
Екатерина Романова
«Сюжеты и символы в живописи.
Практикум»Екатерина Романова
«Сюжеты и символы в живописи. Практикум»
Лекция очень и очень интересная. Действительно начинаешь понимать картины на более глубоком уровне. Плюс Наталья — великолепный рассказчик! Искренне рекомендую посетить эту лекцию.
Очень интересная и познавательная лекция.
Olena Grechkosieieva
«Эпохи и стили в живописи. Практикум»
Olena Grechkosieieva
«Эпохи и стили в живописи. Практикум»
Очень интересная и познавательная лекция.
Как всегда потрясающая лекция! За чуть более чем 3,5 часа ни разу не возникло ощущения, что информации слишком много, «переваривать» её сложно. Идеальный баланс теории, примеров, «мест для размышлений». Отдельно хочу отметить, что данный практикум хоть и входит в часть курса, не требует предварительного посещения каких-либо ещё лекций, что очень удобно. Конечно же, приду снова! P. S. Всем сомнева
Ольга Ивашкина
«Приёмы и техники в живописи. Практикум»
Ольга Ивашкина
«Приёмы и техники в живописи.
Практикум»Как всегда потрясающая лекция! За чуть более чем 3,5 часа ни разу не возникло ощущения, что информации слишком много, «переваривать» её сложно. Идеальный баланс теории, примеров, «мест для размышлений». Отдельно хочу отметить, что данный практикум хоть и входит в часть курса, не требует предварительного посещения каких-либо ещё лекций, что очень удобно. Конечно же, приду снова!
P. S. Всем сомневающимся: если вы ждёте знака свыше, это он) Не проходите мимо)
Лекция была просто прекрасна! Хотя нет.. Она была невероятно прекрасна! И лекция, и Наталья. Очень сильно энергетически заряженный человек, который так передает информацию, так погружает, что хочется, чтобы это никогда не заканчивалось) Я не знаю, были ли в зале люди далекие от искусства, но если и были, то они сегодня стали к нему гораздо ближе. Я под очень большим впечатлением. Спасибо!
Александра Гордеева
«Приёмы и техники в живописи. Практикум»
Александра Гордеева
«Приёмы и техники в живописи.
Практикум»Лекция была просто прекрасна! Хотя нет.. Она была невероятно прекрасна! И лекция, и Наталья. Очень сильно энергетически заряженный человек, который так передает информацию, так погружает, что хочется, чтобы это никогда не заканчивалось) Я не знаю, были ли в зале люди далекие от искусства, но если и были, то они сегодня стали к нему гораздо ближе. Я под очень большим впечатлением. Спасибо!
Очень интересная лекция: структурированность изложения, примеры и восхитительная харизма Натальи! Чувствуется, что ей самой с нами и с картинами очень интересно. Много нового почерпнула, о чем раньше, глядя на картины, даже не думала. Ушла с пониманием как попунктно разложить эпоху, и жанр, и состояние художника в момент написания. Спасибо!
Ольга Некредина
«Сюжеты и символы в живописи. Практикум»
Ольга Некредина
«Сюжеты и символы в живописи. Практикум»
Очень интересная лекция: структурированность изложения, примеры и восхитительная харизма Натальи! Чувствуется, что ей самой с нами и с картинами очень интересно. Много нового почерпнула, о чем раньше, глядя на картины, даже не думала. Ушла с пониманием как попунктно разложить эпоху, и жанр, и состояние художника в момент написания. Спасибо!
Восторг ! 4 часа на одном дыхании…с удивительной и эпатажной Натальей Востриковой!
Анастасия Севастьянова
«Сюжеты и символы в живописи. Практикум»
Анастасия Севастьянова
«Сюжеты и символы в живописи. Практикум»
Восторг ! 4 часа на одном дыхании…с удивительной и эпатажной Натальей Востриковой!
Как всегда у Натальи — интересно, живо, красочно и глубоко настолько, что забываешь о времени))) Отличная лекция 👍
Григорий Гончарский
«Эпохи и стили в живописи. Практикум»
Григорий Гончарский
«Эпохи и стили в живописи. Практикум»
Как всегда у Натальи — интересно, живо, красочно и глубоко настолько, что забываешь о времени))) Отличная лекция 👍
как смотрит на код реверсер / Хабр
Привет! Меня зовут Денис, я Lead Security Researcher в центре Global Research & Analysis Team (GReAT) — подразделении «Лаборатории Касперского», которое занимается целевыми вредоносами. Это значит, что их авторы не рассылают трояны всем подряд, а тщательно выбирают свои организации-жертвы. Иногда их «продукты» написаны интересно.
Мы в GReAT в буквальном смысле слова годами следим за командами, которые пишут такое, детально разбираем их зло, формируем отчеты для заказчиков, плюс иногда подкидывая идеи и продуктовым командам.
Эта статья написана по мотивам выступления на C++ Russia. Я хочу рассказать, как на код C++ смотрит реверсер и что он видит в этом комбайне прекрасном языке. Обычно разработчик идет от исходного кода к двоичному, а мы — наоборот. Ко мне и коллегам приезжают самплы — уже скомпилированные исполняемые (PE, ELF, etc.) файлы, возможно, какой-то байткод одного из intermediate languages или даже прошивка. И мы начинаем их разбирать. Как мне кажется, реверсеры и разработчики могли бы обогатить друг друга.
Я расскажу о реверсе С++ на трех примерах из реальной жизни.
- Microcin: С с классами.
- ScrambleCross: С++ Linux ELF64. А вот этот пример как раз большая редкость. Под Linux таких развесистых троянов мало, тем более на современном С++. Посмотрим, к чему на нашей бинарной стороне приводит использование контейнеров (скажу сразу, ничего хорошего про ваши шаблоны мы с коллегами не думаем). Покажу, как мы работаем со структурами — это важная часть для нас, при разборе исполняемого файла важно правильно их разметить.
- BluePants: C++ Windows PE+. Тоже современный С++, но под Windows. Еще более развесистый last stager, т. е. последний в цепочке заражения с функциональностью удаленного администрирования. Предыдущие стейджи, как правило, сильно многослойны и занимаются расшифровкой-антидетектом, эскалацией привилегий и т. п. В этом примере, как и в предыдущем, с нами RTTI, видимо, где-то по пути был dynamic_cast. А в случае BluePants из удобно читаемого есть еще и кастомный логгер.
Пример 1. Microcin: С с классами
Вероятнее всего, эти скриншоты с исходниками появились потому, что уважаемый разработчик, он же тестер, перед кем-то отчитывался о том, что текущую версию его решения, установленную на виртуалке, защитные продукты не детектируют. На самом деле это то, как обычно реверсер код_не_видит, но всегда интересно потом сверить свой анализ с настоящим исходником.
На момент появления этих скриншотов вредонос мы уже анализировали и помнили класс zmm. Понятно, что очень интересно было изучить и исходник на C с классами.
Здесь сначала идет создание некого уникального идентификатора (применен rand(), вызван без srand(), но GetTickCount и time(0) все же дадут ему условно уникальное значение). Пока что можно предположить создание сессионного ключа или чего-то похожего.
Функция Judge_Time — это планировщик. Изучать кастомные планировщики всегда очень забавно. По «команде» планировщика запускается некий Client_Processing. Больше в коде смотреть особо не на что — сверху гасятся ошибки, если планировщик не дал команду продолжать, то в бесконечном цикле следующая проверка повторится через пятисекундный таймаут, все.
Перейдем к следующему куску кода, который заставил меня почувствовать в разработчике родную душу. Виндовый API позволяет понять день недели из коробки, но тут подрезан код безумной функции, считающей день недели по текущей дате. Похоже, здесь закрался stackoverflow-based programming в стиле определения знака float через строку.
На скриншот попало дерево проекта, и в нем видно, что zlib решили вкомпилировать, а не использовать как внешнюю библиотеку. Во вредоносах так бывает довольно часто — берут zlib, mbed TLS, OpenSSL. Если все это слинковано в финальный бинарник и пострипано, то приходится разбираться с 300 килобайтами кода (и это совсем не предел, даже для не Delfi-кода), из которых 250 — какой-нибудь OpenSSL с коллегами. Честно говоря, при реверсе гораздо удобнее, если они приходят извне — из библиотек.
Еще на следующем скриншоте нашего первого примера видна многопоточность. В целом, если мы не говорим про ботнеты (а наш случай целевого вредоноса принципиально иной), такие программы не работают у массы пользователей. Они не высоконагруженные, даже их серверная часть. С такой функциональностью асинхронность или многопоточность вряд ли нужны. Тем не менее они регулярно встречаются. Я думаю, причина в том, что у разработчиков накоплены библиотеки, привычные подходы, и они просто не хотят сбивать прицел.
Мне даже искренне интересно, как уровень разработки по этому скриншоту оценят на Хабре. Мне кажется, что это такая история получается немного из XX века. (Да, я стараюсь быть вежливым со всеми, получается не всегда.)
Закончим с исходным кодом — на Хабре его нужно было показать, и перейдем к обещанному «как видит реверсер» — что же у того вредоноса в собранном PE-файле:
Давайте сразу договоримся, что здесь и далее я привожу интерфейс декомпилятора и состояние кода уже после работы аналитика с ним. Т. е. уже причесанный код, в котором размечены структуры данных и даны осмысленные имена. Поверьте, до этого анализа картина была совсем не такой красивой. Как водится, временами для того, чтобы уговорить декомпилятор, приходилось переходить в дизассемблер. И второй момент: полное покрытие кода в рамках статьи мы не сделаем, будем концентрироваться на местах в нем, которые хочется подсветить. Поехали.
Помните прекрасную функцию выше, которая определяла день недели по дате? Из кода (его нет на скриншоте) видно, что загрузчик (а по функциональности это именно он) умеет устраивать себе выходные — в конфиге можно отметить любые два дня на неделе, когда он не будет работать. В случае этого сампла вредонос почти соблюдает шаббат — пропускает субботу и воскресенье. Разве что календарные, а не от заката. И нет, на национальность авторов или жертв мы не намекаем. Просто, скорее всего, разработчик не хотел генерировать трафик по выходным, чтобы защитные системы не среагировали на такую подозрительную активность.
Заглянем в их vftable и почти ничего не найдем — буквально по одному деструктору, которые мы не стали переименовывать:
И получили очень странные автоимена. Здесь видна работа двух механизмов, которые помогают нам откинуть библиотечные функции и сконцентрироваться на анализе кастомного кода:
- поиск библиотечных функций по двоичным сигнатурам;
- их же поиск по хэшу, посчитанному от прототипа, сигнатуры функции (не путать с двоичной сигнатурой).
В случае наших деструкторов оба механизма дали сбой. Это простительно, потому что деструкторы и у TCPConnect, и у zmm слишком малы и не уникальны.
В качестве аналогии можете представить старые антивирусы. Так что здесь важно, чтобы в функции были уникальные сигнатуры. В настройках можно выставить, что функции короче такой-то длины не стоит пытаться узнавать.
Справедливости ради — для более крупных кусков кода (и в основном для традиционных, близких к С компиляторов) механизм поиска библиотечных функций по бинарным сигнатурам очень помогает. Подключаются так называемые библиотеки типов — описания в проприетарном формате.
На этот раз не будем сильно углубляться в распознавание библиотечных функций и вернемся к нашему resolver-у на первом скриншоте. Тут важный момент для реверса: при их создании разработчик часто не хочет показывать, например, импорт сетевых функций. Работа с сетью у какого-нибудь калькулятора выглядит подозрительно. Поэтому часто реализуется менее явный динамический импорт — получение адресов API функций «на лету». В нашем resolver очень типичная картина — LoadLibrary и GetProcAddress.
Результат работы — инициализированная таблица диспетчеризации в объекте. В нее постепенно резолвятся и заносятся адреса, Пока аналитик не пройдет весь этот код и не заполнит адреса, он не сможет понять, что происходит в коде дальше.
В первом сампле давайте посмотрим еще один забавный момент. Как я уже упоминал, по функциональности это загрузчик. Когда все адреса функций готовы и scheduler дает добро (будний день) на продолжение работы, он отправляется за следующим модулем, который получает в виде исполняемого файла. И начинается поиск экспорта из этого модуля. В нашем случае он называется TransFile.
Видите, разработчик здесь использует qsort и bsearch для сортировки найденных функций по именам и поиска нужной. Алгоритм, как мне кажется, неплох, но зачем использовать его там, где речь явно не идет о миллионах экспортов? Вероятно, автор где-то подрезал этот код или ему просто понравился подход. Когда TransFile найден, его запускают, работа загрузчика завершена.
Из этого примера видно, что разработчики даже целевых вредоносов далеко не всегда суперпрограммисты. Что они с большой вероятностью знают лучше среднего «гражданского» программиста — так это относительные кишки операционной системы: как в ней спрятаться, как закрепиться, подменить библиотеку и т. п.
Безусловно, бывают и очень интересные технические решения, но чаще всего просто наворачивают много этапов расшифровки-инжекта-загрузки. Один из давних классических способов, например, — взять совершенно легитимный софт, добавленный в white list, подложить в ту же директорию библиотеку со специфическим именем, она на старте пропатчит точку входа исходного процесса, чтобы легитимный софт не исполнялся дальше, и продолжит путь к финальному трояну. Через кучу таких распаковок, деобфускаций, расшифровок он в итоге оказывается в памяти системного процесса.
Достаточно С с классами, пойдемте ближе к C++.
Пример 2.
ScrambleCross: С++ Linux ELF64Второй пример — линуксовый. Здесь функция RunStageClient уже больше похожа на C++ — она красиво отображается в декомпиляторе. Нет, С++ не стал декомпилируемым, просто спасибо современным инструментам, которые делают предположения о том, как это могло бы выглядеть в исходнике. Как действительно выглядел исходник, мы узнаем, если попадается, допустим, необфусцированный сампл на C#.
В любом случае, здесь снова были оставлены символы. Все эти StageClient мы, можно сказать, получили «бесплатно», но не получили никаких структур. Это уже работа человека по эту сторону клавиатуры. Он должен объяснить декомпилятору, что там прилетает в виде аргумента. Перечислители для кодов ошибок здесь сделаны тоже вручную. Как правило, я их создаю, если количество кастомных кодов не переваливает за пару десятков.
Давайте посмотрим внутрь этого ELF-файла. В конструкторе ModuleMgr начинаются деревья. Предполагаю, что в исходниках это был словарик типа std::map. Но в ELF сама структура не сохранилась — ведь мы не на отладочную сборку смотрим, а на непострипанный файл. Так что создание ноды дерева уже с нас, изначально здесь были только оффсеты, не более того — никаких rbTree и _M_left.
Здесь видно, что у ModuleMgr есть метод — AddModule. Для удобства я сделал перечислитель с возможными ключами словаря (pShellMgr, pFileMgr).
Обратите внимание на vftable, например ShellMgr (у других модулей под управлением ModuleMgr он будет похож). Уже интереснее, чем в предыдущем примере с одними деструкторами и почти пустыми vftable.
OnModuleLoad, OnModuleUnload и т. д. будут дергаться менеджером по наступлении нужных событий. RTTI видно, кто на ком стоял — в частности, что ShellManager унаследовал от ModuleBase, а тот, в свою очередь, от Interface. Что нам нужно от vftable для ShellMgr в первую очередь — это сделать ссылку на эту таблицу первой же полянкой в структуре для ShellMgr. В итоге из кода можно будет красиво переходить на все методы OnModuleClose, OnLoaderOffline и т. д. Без этого разобраться в логике вредоноса будет затруднительно.
Без RTTI vftable все равно бы существовала, но это были бы безымянные функции. Их нахождение в одной таблице позволило бы дать имена вроде ShellMgr::Method1 (уже хорошо), дать первому аргументу типа указатель на объект ShellMgr, а вот поименовать методы более осмысленно получилось бы только после анализа того, что происходит внутри.
Давайте теперь посмотрим на метод AddModule — выше он уже у нас вызывался. Здесь хорошо видно, чем платит программист за использование контейнера-словаря. В этом коде сначала происходит поиск, потом — в случае успеха — добавление и балансировка дерева (все не влезло на скриншот).
Частый актуальный вопрос к реверсеру: если структура дерева не приехала сама, то как понять, что происходит в таком вот AddModule? Как понять, кто тут родитель, кто цвет? Здесь отчасти помогает опыт — если вы уже видели деревья пять раз, то шестые будут на них похожи. Также помогает grep по документации и компиляция своих кусков кода с контейнерами, которые, кажется, есть в коде вредоноса.
В принципе, можно поставить себе на виртуалку разные версии STL, угадывать нужную библиотеку и опции компилятора и в итоге создать сигнатуры для распознаваний функций. Честно скажу, до этих высот я еще не добрался. В случае разных языков больше пользуюсь grep-ом по исходникам, получая нечто, что логично накладывается на какие-нибудь функторы или деревья.
Так или иначе — структура вершины найдена, и в дизассемблере появилось нечто примерно такое. И да, если разработчики описывают структуры там же, где и код, то у реверсеров под это в инструменте выделены отдельные вкладки.
Теперь о главной боли. Вот эту сигнатуру я подрезал из сэмпла с C++.
Шаблоны. В виде одной строки для меня это какое-то безумие. Ладно бы для меня — главное, что так же про шаблонизированный код думают и инструменты, которые пытаются понять, относится ли эта штука к стандартной библиотеке. В шаблоны же можно подставить разные типы данных — и указатель на char, и кастомную 200-байтовую структуру. И в этом месте сигнатуры страдают. И ничего хорошего реверсеры про STL и шаблоны не думают.
В общем, приходится работать руками. Я несу в VSCode, чтобы расставить все табы и понять, кто на ком стоял.
В DataExchanger ситуация ровно та же: вижу имена, а структуру не вижу и делаю сам. В принципе, ничего нового по сравнению с деревьями, которые рассматривали выше.
Давайте в этом примере еще разберемся с Function_base. Функтором я буду называть некую обертку вокруг того кода, который хочется дернуть, содержащую какие-то дополнительные данные.
Потребовалась еще одна дополнительная структура, в поиске которой помогла документация. Главную полянку я назвал content, а аргументом для нее служит указатель на StageClient — наш главный объект. Есть еще вызыватель и менеджер, посмотрим во второго.
Все, что нужно было сделать внутри менеджера — взять из документации коды для get_functor, clone_functor. После этого становится понятно, за что этот менеджер отвечает. Попутно призываю обращать внимание на любые new() и аналоги — очень ценно, когда видно, сколько памяти выделяется. Например, может быть видно, что происходит инициализация полянки вложенной структуры. Бывший абстрактный оффсет во внешней структуре сначала получит имя buf80. Главное, что несколько полей в ней теперь логически связаны. Потом работа с полями этой вложенной структуры позволит дать ей и осмысленное имя.
Пример 3. BluePants: C++ Windows PE+
Бывает, что проблема не в многочисленных обертках вокруг вредоноса, а в том, что архитектор на той стороне решает разбить его на множество модулей, управляя их запуском через оркестратор. Буквально любую функцию трояна он может оформить в виде самостоятельного модуля: запустить скрипт powershell, сделать снимок экрана и т. п. Таких модулей могут быть десятки, и в этом примере я покажу, как это может быть реализовано на C++.
Посмотрим на модуль-диспетчер:
Что хорошо — здесь появляется полезный незаконченный логгер. Глобальное статическое хранилище сообщений.
New(), помогающий понять размер структур, здесь у компилятора получился интересным: значение указателя на журнализатор плюс 8. Смотрится странно, но это же все внутри if, и мы попадем в это выделение памяти, только если она еще не выделена, т. е. если логгера еще нет. Иными словами, размер все равно понятен — 8 байт. Это 64-битный сампл, так что в этом месте журнализатор получает свой указатель на таблицу виртуальных функций и не более того.
Давайте теперь зайдем в фабрику RatCore.
Как и все основные объекты в этом сампле, он глобальный. Размер виден в new — он достаточно крупный. Иногда приходится размечать и такие структуры, и когда аналитик их получает, там еще нет никаких векторов и строк — одни оффсеты.
Но мы в декомпиляторе смотрим на файл, с которым аналитик уже поработал. Видим, какие поля здесь инициализируются. Любой такой конструктор показывает не только общий размер структуры, но и набор полей, с них удобно начинать разметку. Но, конечно, сразу про вектора и строки понятно не станет, только уже дальше по коду.
А вот кусок, с которым я возился долго.
Здесь есть некая таблица диспетчеризации, это имя я достал из vftable.
В RatCore мы видели нечто похожее — снова фабрика с начальной инициализацией полей, но есть и особенность.
Видим очередной статический объект, new() и размер, завязанный на нулевой указатель. Новое по сравнению с двумя предыдущими примерами — две vftable. Почему таблицы две?
Выше в примере мы видели интерфейс, унаследованный от него ModuleBase и дальше, в свою очередь, уже от него ShellMgr, FileMgr. А тут мы видим множественное наследование. На уровне бинарного файла в RTTI оно будет выглядеть так:
Есть шаблонизированный Singleton (в этот раз там DispatcherTable) и еще отдельно DispatchInterface. Отсюда и две vftable. Поэтому когда аналитик будет создавать структуру, то оставит под них уже не одну 8-байтную полянку, а две.
Вернемся на предыдущий скриншот.
Вторая строка здесь — вызов DispatcherTable::Append. И снова это были просто оффсеты, но благодаря тому, что обе vftable были добавлены, этот Append и удалось найти.
Создав объект DispatcherTable, аналогично мы достали и AppendKey:
Дальше мне пришлось сильно поколдовать над Binder из STL. Как и в примере выше, я уносил этот фрагмент в VSCode, чтобы понять хотя бы, кто на ком стоит. В итоге удалось разобраться, что будет аргументами, а что — самой вызываемой функцией: Rat::CoreGetConfig. Важно было понять, где ключ, с которым такие методы добавляются в словарь. На этапе загрузки плагинов и вызова функций это очень поможет понять, что происходит. Плагины, кстати, тоже возвращают свои объекты этому оркестратору, после чего из их vftable оркестратор дергает методы.
Вместо итогов
Любим ли мы вредоносы на С++? Нет. Больше всего мы любим хороший plain C. Но когда C++ попадается — не беда, жить можно, как в примерах выше. За целевыми вредоносами мы наблюдаем годами. Забавно видеть, как из некоторых логирование со временем уходит. Видимо, их разработчики считают, что отладили продукт, и убирают соответствующие строки кода.
Все примеры выше специально подобраны с RTTI. Хуже ли С++ без RTTI для реверсера, чем все остальное? В принципе, нет. У всех более современных компиляторов наблюдается тенденция к статической линковке. И вот если в рантайме есть дженерики, распознавать которые автоматически непросто, то дело усложняется. C++ с этой точки зрения не самый плохой компилятор. Есть еще Delphi, Rust, Nim и Go. Иногда такие языки выбирают для обертки над следующим модулем, просто пытаясь сбить детект. Тогда достать следующий модуль не так сложно, как разобрать полноценный троян.
Хорошие ли программисты малварщики? Мне из моего опыта кажется, что, как правило, не очень. Но, безусловно, есть «приятные» исключения. Могли ли малварщики не использовать C++ в перечисленных случаях? Конечно, могли бы. Задача создания утилиты удаленного администрирования не настолько требовательна к производительности, как создание компьютерной игры. Мне кажется, они просто выбирают привычный язык и свои уже готовые библиотеки. Иногда эти наработки оказываются на С++. Что ж, будем работать с тем, что есть.
Ну и напоследок: если вам тоже интересно копаться в подобных задачах, приходите работать в нашу команду Core Tech. Она разрабатывает все базовые функции продуктов «Лаборатории Касперского», работая с C++, Assembler и Python.
>>>
Видео моего выступления на С++ Russia-2022:
ЧТО ЭТО ВЫГЛЯДИТ vs КАК ЭТО ВЫГЛЯДИТ vs КАК ЭТО ВЫГЛЯДИТ – Bizio
Резюме: Правильно использовать вопросительное слово what с предлогом like, но неправильно использовать вопросительное слово how с предлогом like. Итак, то, как это выглядит, правильно, но *то, как это выглядит, неверно. С грамматической точки зрения нам нужно использовать существительное what после предлога like, а не наречие как.
Введение
Во-первых, взгляните на это предложение и следующий за ним вопрос. Подумайте, являются ли конструкции «грамматическими» в стандартном американском английском (SAE).
*Я слышал о Джоне Ленноне, но никогда не видел его фотографии. Как он выглядит?
Если вы подумали, что в написанном выше есть что-то неграмотное, похлопайте себя по спине, потому что вы правы. Вот как можно исправить сказанное выше:
Я слышал о Джоне Ленноне, но никогда не видел его фотографии. Как он выглядит?
Это тоже верно:
Я слышал о Джоне Ленноне, но никогда не видел его фотографии. Как он выглядит?
Но почему? Что не так с исходным вопросом? Давайте посмотрим поближе. И не волнуйтесь. Мы собираемся сделать это простым способом, поэтому, если вы убегаете от грамматических терминов, таких как конъюнктивное наречие, все должно быть в порядке. Конечно, если у вас есть какие-либо вопросы, пожалуйста, напишите ниже, и я сделаю все возможное, чтобы помочь.
Простое объяснение
Я написал пять разных объяснений того, почему это неправильно, и, в конце концов, я думаю, что самый простой способ объяснить, почему «как он выглядит» неверен, — это использовать «переместить слова вокруг». », который на самом деле работает на удивление хорошо для многих грамматических объяснений. Во-первых, важно осознать, что многие высказывания (то есть то, что вы говорите или пишете) на английском языке могут быть сформулированы по-разному и при этом иметь более или менее одно и то же значение (хотя, скорее всего, это приведет к разным акцентам). Например, я могу спросить: «Чем вы писали?» или «Чем ты писал?», и эти два вопроса означают почти одно и то же, хотя, конечно, последний звучит более формально, чем первый. Давайте сделаем то же самое с нашими примерами выше.
Но нам нужно немного сократить текст. Давайте просто избавимся от вступительного предложения и сосредоточимся на вопросе, т. е. «как он выглядит?» часть. Теперь давайте немного переставим слова, проделаем другую магию и напишем два эквивалентных предложения. Начнем с двух правильных примеров:
«Как он выглядит?» можно переставить так: «Он похож на… на что?»
Точно так же «Как он выглядит» можно переставить следующим образом: «Он выглядит… как?»
Наконец, и это важно, следуя той же процедуре: «*Как он выглядит?» будет переупорядочено следующим образом: «*Он выглядит… как?» Это звучит неправильно для ваших ушей? Я надеюсь на это, потому что это точно делает мое! Когда вы в последний раз слышали, как кто-то говорит «нравится как»? Мы слышим «как я», «как ты», «как в кино» и т. д., но не «нравится как». Верно?
По тем же причинам они также неверны и должны быть переписаны:
- Нехорошо: *Каков вкус баклажанов? Лучше: Какой вкус у баклажанов?
- Плохо: *Как выглядит гусиный пух? Лучше: На что похож гусиный пух?
- Плохо: *Как пахнет лаванда? Лучше: Как пахнет лаванда?
- Плохо: *Как звучит туманный горн? Лучше: Как звучит туманный горн?
Если вы заметили, что я использовал глаголы для обозначения наших чувств, вы получите бонусные баллы.
Интересуетесь грамматикой, стоящей за всем этим? Читай дальше.
Но почему? Дайте мне грамматику!
Давайте посмотрим на грамматику. Во-первых, нам нужно понять, что слово «нравится» — это предлог. Во-вторых, нам нужно знать это очень важное грамматическое правило:
предлог + существительное
Предлоги — это такие слова, как in, of, with, like и т. д. После предлога у нас должно быть существительное. Это существительное называется объектом предлога. Например, если мы говорим «на столе», «на» — это предлог, а «стол» — объект предлога «на». (Для получения дополнительной информации см. страницу TestMagic о предлогах.)
Теперь держитесь за свои шляпы, так как это будет немного технически. (Надеюсь, через какое-то время все сойдется воедино.) Мы установили, что «нравится» — это предлог, и ему нужен объект (то есть существительное). Этот объект — слово «что». Почему? Потому что «что» — существительное; «как» — это не существительное (это наречие). Итак, если у нас есть «нравится» в этом вопросе, мы не можем также иметь в нем «как»; эти два слова не уживаются, и они не могут быть вместе в одном предложении или вопросе (в этой конструкции, конечно). Нам нужно избавиться от того или иного. Итак, мы можем сказать «как он выглядит» и «как он выглядит», но мы не можем сказать «*как он выглядит». Проще говоря, нам нужен предлог + существительное, а не предлог + наречие.
Нужны подробности? Вот так: когда мы задаем вопрос и ожидаем, что ответ будет существительным, мы используем «вопросительное слово» (также известное как «вопросительное слово», «вопросительное слово» или «вопросительное слово WH») «что» ( для вещей) или «кто» или «кого» (для людей) в начале вопроса. Например, если мы хотим узнать, что вы ели на обед (вещь), мы можем спросить: «Что вы ели?» Точно так же, если мы хотим знать, кого вы видели, мы можем спросить: «Кого вы видели?» (Не беспокойтесь сейчас о разнице между «кто» и «кому»; это совсем другая тема!) И в завершение, поскольку мы используем эти слова в вопросах и потому что они существительные в качестве ответов, они называются вопросительными («вопросительный» в основном означает «спрашивающий») местоимениями (слова, которые заменяют, заменяют или относятся к существительным). Другими словами, это вопросительные слова, которые функционируют как существительные. Другими словами, вы используете существительное в вопросе, чтобы получить существительное в качестве ответа.
Напротив, когда мы спрашиваем кого-то «как» (за которым следует предложение), мы хотим знать, как что-то произошло, качества чего-то и т. д. Другими словами, мы ищем ответ, который является наречием или прилагательное. И да, «как» — это вопросительное наречие, если вам интересно.
Вот и все! Дайте мне знать, если вам нужны разъяснения или дополнительные пояснения.
грамматичность — «Как это выглядит?»
спросил
Изменено 8 лет, 4 месяца назад
Просмотрено 46 тысяч раз
Формально, в моем английском образовании я научился спрашивать внешний вид чего-либо, используя выражение:
«На что это похоже?»
Поскольку мой родной язык немецкий и мы говорим «Wie sieht es aus?», я часто ловлю себя на том, что говорю:
«Как это выглядит?»
, что было бы прямым переводом с немецкого.
Поскольку я не думаю, что перевод звучит неправильно (хотя я, конечно, предвзят), я хотел бы спросить вас, это правильный английский язык хотя бы в некоторых случаях или это просто моя ошибка?
Спасибо!
- грамматичность
- глаголы смысла
3
По-английски «Как это выглядит?» обычно требует оценочного суждения, тогда как «Как это выглядит?» просит физическое описание.
Как выглядит это платье?
Тебе идет.Как выглядит эта собака?
Выглядит здоровым.
против:
Как выглядит это платье?
Имеет высокую талию и короткую юбку.Как выглядит эта собака?
Черный с белой мордочкой и носками.
Вопросы имеют больше совпадений при обсуждении более абстрактных тем:
Как проходит твоя неделя?
Я очень занят.Как выглядит твоя неделя?
Я свободен во вторник и четверг.
В этом случае ответы по-прежнему будут разумными, если вопросы перевернуты.
2
Оба вполне приемлемы.
Я хотел бы отметить, что « Как это выглядит? » больше относится к вещам или свойствам вещей, которые являются абстрактными, используя метафорический смысл глагола смотреть например. » Как выглядит твое расписание на вечер? » звучит немного лучше, чем » Какое у тебя расписание на вечер? «. » Как это выглядит ?» больше относится к физическим объектам или физическим свойствам объектов, например, » Как выглядит слон? «Хорошо, но» Как выглядит слон? » кажется странным. Тем не менее, оба могут применяться в любой ситуации, и это различие несколько тонкое. Вы также можете обнаружить, что это различие варьируется в зависимости от диалекта, поэтому другие могут не согласиться.
» Как это выглядит? » также может внести двусмысленность, которой нет у другой конструкции. Например, одним правильным ответом на вопрос « Как выглядит слон? » будет « Глазами. »
7
«Как это выглядит?» это запрос на критику внешнего вида чего-либо.
Ваша девушка (или парень) наносит макияж и спрашивает: «Как это выглядит?»
Ответ всегда «Красиво!»
«На что это похоже?» это запрос на описание чего-либо.
Ваша девушка (или бойфренд) спрашивает: «Я слышал, что твоя старая подруга (или бойфренд) пришла на сегодняшнюю вечеринку в новом наряде, и ты уже его видел.