• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Криптор исполняемых файлов. РЭволюция =).

В этот раз для получения пароля на архив нужно немножко больше навыков, чем юзать онлайн encode-decode утилиты, зато интересно и по-приколу =D.

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

sdf.png
 
ты дорабатываешь версию Октавиана? если да, то на продажу или паблик?
я уже все пофиксил

Windows Server 2012 R2 x86(exe+, dll+)/x64(exe+, dll+)
Windows Server 2016 x86(exe+, dll+)/x64(exe+, dll+)
Windows Server 2019 x86(exe+, dll+)/x64(exe+, dll+)
Windows 10 x86(exe+, dll+)/x64(exe+, dll+)
Windows 11 x86(exe+, dll+)/x64(exe+, dll+)
 
Нет не допиливал конкретно эти сорцы, у меня своя реализация и LoadPE, другая, кода кстати раза в 3 меньше, а полнота охвата поддерживаемых файлов шире, просто есть некоторые хитрости которые позволяют не обрабатывать некоторые вещи, просто нужно создать некоторые условия для этого, и все работает должным образом, но это баловство, а второй вариант интересен поболее - загрузка через абуз системного загрузчика, самый полный из всех возможных загрузчиков существующих в мире без всяких преувеличений, потому что использует все силы оригинального виндового загрузчика PE файлов (андок функции и структурки, ресеч был интересным, всем советую, занимательно и залипательно на несколько дней, но того стоит), грузит абсолютно любые файлы которые в принципе может загрузить винда в штатном режиме при двойном клике по файлу, такого нет ни в одном крипторе на данный момент, похожую идею вкидывал клерк в свое время, но у него не было даже PoC, просто теоретические выкладки и рассуждения, а у меня полноценный рабочий PoC, который можно заморфить и использовать в крипторах. Возможно даже продаем его потом, когда отлажу досканально, технология по истине уникальная, повторюсь, такого нет ни в одном крипт сервисе в данный момент и не будет в ближайшее время, в приватах возможно кто-то уже додумался, но огласке это все-равно не скоро придет даже если так, людям лень ресечить код, лень искать что-то новое, вроде LoadPE работает и все заебись, все юзают LoadPE классические и кастомные, даже обходят большинство ав, но это уже прошлый век, технологии из консервной банки

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

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

ldrapi.c

ldrinit.c

ldrsnap.c

то тут загрузка в память как и в случае loadpe . тогда толк?
системный загрузчик Windows действительно умеет загружать любые поддерживаемые форматы (PE, Net, COM и др.)
 
Пожалуйста, обратите внимание, что пользователь заблокирован
 
Написал плагин для иды который с функции, которая открыта в лог выводит перечень WinApi.
Выглядит это дело так:

Посмотреть вложение 48214


Python:
import idautils
from idc import *
import idaapi
from idautils import *


class ExtractHandler(idaapi.action_handler_t):

    def __init__(self):
        idaapi.action_handler_t.__init__(self)

    def activate(self, ctx):
        print('-------------------------------<<< WinApi Extractor >>>-------------------------------')
        ea = idaapi.get_screen_ea()

        start = idc.get_func_attr(ea, FUNCATTR_START)
        end_d = idc.get_func_attr(ea, FUNCATTR_END)

        end = end_d - 1

        for function_item in idautils.Functions():
            function_flags = idc.get_func_attr(function_item, FUNCATTR_FLAGS)
            if function_flags & FUNC_LIB or function_flags & FUNC_THUNK:
                continue

            myaddr = list(idautils.FuncItems(function_item))
            for addr in myaddr:

                if start <= addr <= end:
                    if 'call    ds:' in idc.generate_disasm_line(addr, 0):
                        print(idc.generate_disasm_line(addr, 0).lstrip('call    ds:'))

        return True

    def update(self, ctx):
        return idaapi.AST_ENABLE_ALWAYS


class ExtractWinApiPlugin(idaapi.plugin_t):
    exctract_action_name = "ExtractWinApi:extract"

    explain_menu_path = "Edit/ExtractWinApi/Extract"

    explain_action = idaapi.action_desc_t(exctract_action_name,
                                          'Extract WinApi functions',
                                          ExtractHandler(),
                                          "Ctrl+Alt+E",
                                          '',
                                          199)

    idaapi.register_action(explain_action)

    idaapi.attach_action_to_menu(explain_menu_path, exctract_action_name, idaapi.SETMENU_APP)


def PLUGIN_ENTRY():
    ExtractWinApiPlugin()
апну апдейт теперь можно всю прогу анализнуть, а не только текущий скрин, для клонирования экспорта самое то
Python:
import idautils
from idc import *
import idaapi
from idautils import *


class ExtractHandler(idaapi.action_handler_t):

    def __init__(self):
        idaapi.action_handler_t.__init__(self)

    def activate(self, ctx):
        winapi_calls = 0

        print('-------------------------------<<< WinApi Extractor >>>-------------------------------')
        for function_item in idautils.Functions():
           start = idc.get_func_attr(function_item, FUNCATTR_START)
           end_d = idc.get_func_attr(function_item, FUNCATTR_END)
           end = end_d - 1

           function_flags = idc.get_func_attr(function_item, FUNCATTR_FLAGS)
           if function_flags & FUNC_LIB or function_flags & FUNC_THUNK:
               continue

           myaddr = list(idautils.FuncItems(function_item))
           for addr in myaddr:
               if start <= addr <= end:
                   if 'call    ds:' in idc.generate_disasm_line(addr, 0):
                       print(idc.generate_disasm_line(addr, 0).lstrip('call    ds:'))
                       winapi_calls += 1


        print("Total WinAPI calls:", winapi_calls)

        return True

    def update(self, ctx):
        return idaapi.AST_ENABLE_ALWAYS


class ExtractWinApiPlugin(idaapi.plugin_t):
    exctract_action_name = "ExtractWinApi:extract"

    explain_menu_path = "Edit/ExtractWinApi/Extract"

    explain_action = idaapi.action_desc_t(exctract_action_name,
                                          'Extract WinApi functions',
                                          ExtractHandler(),
                                          "Ctrl+Alt+E",
                                          '',
                                          199)

    idaapi.register_action(explain_action)

    idaapi.attach_action_to_menu(explain_menu_path, exctract_action_name, idaapi.SETMENU_APP)


def PLUGIN_ENTRY():
    ExtractWinApiPlugin()
работает вот так
1700256007621.png
 
Пожалуйста, обратите внимание, что пользователь заблокирован
А зачем тут ида? Можно же просто с таблицы экспорта сдампить с помощью библиотеки pefile
 
Пожалуйста, обратите внимание, что пользователь заблокирован
расположение в коде же по порядку
Это бесполезно, т.к твой код не учитывает передастся ли в процессе исполнения управление на то ветвление программы, где вызывается API функция
 
Это бесполезно, т.к твой код не учитывает передастся ли в процессе исполнения управление на то ветвление программы, где вызывается API функция
а в чем задумка по твоему? чтобы управление из loc_4024E1 охватывало еще GetAtomNameW ?


1700310799716.png
 
правда обработка TLS кривая и не поддерживает статичные локальные переменные потока
согласен. есть такое
------

код для проверки
C++:
#include <iostream>
#include <thread>

// Объявление статической переменной с модификатором thread_local
thread_local int tls_variable = 0;

void threadFunction() {
    // Изменение переменной в каждом потоке
    tls_variable++;
    std::cout << "TLS variable in thread: " << tls_variable << "\r\n"<< std::endl;
}

int main() {
    // Создание нескольких потоков
    std::thread t1(threadFunction);
    std::thread t2(threadFunction);
    std::thread t3(threadFunction);

    // Ожидание завершения всех потоков
    t1.join();
    t2.join();
    t3.join();

    // Значение переменной в основном потоке не меняется
    std::cout << "TLS variable in main: " << tls_variable << std::endl;

    return 0;
}

выдает
TLS variable in thread: -2147483647
TLS variable in thread: -2147483647


TLS variable in thread: -2147483647

TLS variable in main: 0


Копаюсь в проблеме, мб кто что подскажет в теме как решить

анализ загрузчика пока дает такое
На основе анализа предоставленных файлов ldrapi.c и ldrinit.c, которые являются частью реализации загрузчика DLL в Windows, я могу сделать некоторые выводы о том, как происходит обработка TLS (thread local storage) для статических локальных переменных потока:

1. При инициализации процесса выделяется битовая карта TLS bitmap в PEB (LdrpInitializeProcess).

2. Для каждой загруженной DLL проверяется наличие данных TLS в ее заголовке (LdrpWalkImportDescriptor). Если DLL содержит TLS, то:

- Создается структура LDRP_TLS_ENTRY, которая записывается в глобальный список LdrpTlsList.

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

- Заполняется индекс и характеристики TLS в структуре IMAGE_TLS_DIRECTORY, которая записана в PE-заголовке DLL.

3. При создании нового потока вызывается LdrpAllocateTls, которая выделяет память для TLS этого потока согласно данным из LdrpTlsList и заполняет Teb->ThreadLocalStoragePointer.

4. При уничтожении потока освобождается память его TLS в LdrpFreeTls.

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

код для проверки
C++:
#include <iostream>
#include <thread>

// Объявление статической переменной с модификатором thread_local
thread_local int tls_variable = 0;

void threadFunction() {
    // Изменение переменной в каждом потоке
    tls_variable++;
    std::cout << "TLS variable in thread: " << tls_variable << "\r\n"<< std::endl;
}

int main() {
    // Создание нескольких потоков
    std::thread t1(threadFunction);
    std::thread t2(threadFunction);
    std::thread t3(threadFunction);

    // Ожидание завершения всех потоков
    t1.join();
    t2.join();
    t3.join();

    // Значение переменной в основном потоке не меняется
    std::cout << "TLS variable in main: " << tls_variable << std::endl;

    return 0;
}

выдает



Копаюсь в проблеме, мб кто что подскажет в теме как решить

анализ загрузчика пока дает такое
Тебе так нравится работать над проектом Octavian'a?)
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Так рипни обработку ТЛС из загрузчика. Можешь даже просто функцией загрузчика их обработать
 
Тебе так нравится работать над проектом Octavian'a?)
Если честно ответить - да. Единственный неплохой проект из такого рода программ.

Рассуждая про все это, вспоминаю анекдот про двух полярников, медведя и кроссовки.
Нам нафиг не надо делать идеальный криптор морфер, у которого каждый код на выдаче уникален. Достаточно лишь генерить новые версии софта быстрее, чем аверы успевают их палить.
 
Последнее редактирование:
Так рипни обработку ТЛС из загрузчика. Можешь даже просто функцией загрузчика их обработать
Вчера почитал васм и прочие блоги, выявляется что сложная задача починить все в TLS. static,dynamic,callback - чинится.

DLL_THREAD_ATTACH, DLL_THREAD_DETACH, DLL_PROCESS_DETACH вопрос в этом как обработать
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх