Задать вопрос
  • Как защитить offsets от RE?

    @wlastas Автор вопроса
    одсунуть твоей программке за 10 минут написанную dll прослойку

    Так у меня и так это уже DLl которая тянет данные из базы данных. В зависимости от полномочий пользователя, она использует разные струкруты(отличаются овсетами) и возвращает соответсвующие результаты.
    Важна максимальная производлительность(поэтому и используется готовые структуры а не единичные вызовы) и в тоже время желательно защитить эти овсеты.
    Не понимаю что тут можно зашифровать - не могли бы чуть подробнее описать технологию прослойки.
    Возможно она имеет какоето название, по которому можно погуглить - я просто не в теме алгоритмов шифрования от слова савсем
  • Насколько сложно reversing Native AOT сборки?

    @wlastas Автор вопроса
    установил по вашему совету dotpeek.
    В нем моя AOT сборка выглядит так же как и любой другой с++ exe файл, за исключением наличия секции .managed
    также нашел вот:
    https://github.com/dotnet/runtimelab/issues/482
  • Как защитить offsets от RE?

    @wlastas Автор вопроса
    это я все понимаю - вопрос какие есть варианты с защитой офсетов внутри структуры.
    Можно-ли как это это сделать на С# или на С++.
    Обфускация не годится - этот код должен работать максимально быстро, промежуточных данных нет - просто запрос к dll и максимально быстрый ответ в открытом виде - просто та же структура, заполненная валидными данными
  • Как считать значение нужного CPU регистра?

    @wlastas Автор вопроса
    ValdikSS, О какая интересная ссылка - биг фенкс уже пробую - пока отрубает изучаемый процесс, наверно надо подшаманить под х64
  • Как считать значение нужного CPU регистра?

    @wlastas Автор вопроса
    ValdikSS,
    Вам нужно выполнять те шаги, которые я описал в первом сообщени
    Да, большое спасибо, - это я уже понял и с зацикливанием и пересылкой данных из регистра куда-нибудь в "кучу" откуда его можно будет забрать - и то, что тут будут сложности, связанные с "мусором" в этом регистре, если считывать в нем в рандомный момент времени и т.
    Но все же, мне бы просто считать из регистра хоть чего-нибудь!
    Как это сделать?
  • Как считать значение нужного CPU регистра?

    @wlastas Автор вопроса
    ValdikSS, дак да в таком виде нет использования встроенныой функции "asm". Под моей VS это просто не компилируется уже в редакторе.
    Насколько я понимаю в этой строке используется вызов https://en.cppreference.com/w/cpp/language/asm
    только через какой-то макрос или еще как-то - меня это и интересует - как это запустить из VS 2019
  • Как считать значение нужного CPU регистра?

    @wlastas Автор вопроса
    ValdikSS
    Вы скомпилируете библиотеку с функцией,

    Так в этом то и проблема - ошибка синтаксиса - компилятор хочет ";" после "x"
    #include <stdio.h>
    long Get_rdi() {
        register long x asm("rdi");
        long y = *(&x);
        return y;
    }

    Либо, альтернативный вариант: вручную проанализировать код программы

    Да все давно проанализировано - я знаю как найти этот offset и нахожу его за 3 минуты с помощью CE, но я хочу полностью автоматизировать процесс поиска из моей С# программы, чтобы не заниматься этим c выходом каждого нового патча исследуемого приложения.
  • Как считать значение нужного CPU регистра?

    @wlastas Автор вопроса
    Если с чтением регистра все так сложно, то, возможно, можно получить нужный мне результат как то иначе.
    Меня полностью устраивает функционал, который реализован в опции меню Cheat Engine 7.x
    62407a499f251301719684.png
    В нем кстати эта опция работает без запуска отладки и без прерывания процесса, к которому он подключен - то-есть интерактивно.
    Проще всего, наверно, посмотреть на реализацию этого кода в CE исходнике, но я что-то ни нашел в нем строку этого меню, чтобы посмотреть на её обработку.
    https://github.com/cheat-engine/cheat-engine/searc...
  • Как считать значение нужного CPU регистра?

    @wlastas Автор вопроса
    ValdikSS
    Вам нужно отлаживать этот процесс.

    Мне бы для начала просто скомпилировать
    register long x asm("rdi");
    почему там подчеркивается неправильный синтаксис - в сети полно примеров именно со строкой такого вида.
    Потом, после того, как я получу хоть какое-то значение из этого регистра, я буду думать как считать в нужном контексте - по идее мне нужно считать этот регистр всего один раз при запуске исследуемого процесса и нужный адрес в этом регистре будет довольно долго - может быть даже получится считать его не прерывая процесса.
  • Как реализовать платные доп. опции в C# приложении (схема)?

    @wlastas Автор вопроса
    d-stream,
    xml с сигнатурой
    О! ничего даже не слышал про подобное - уже побежал изучать
    В общем стоит к этому подходить аккуратно дабы не получить один и тот же hardware_id для всех windows sandbox например
     
    Да спс, я как раз планировал потестировать алгоритм генерации UID на разном - у меня тут целый зоопарк под рукой
  • Как реализовать платные доп. опции в C# приложении (схема)?

    @wlastas Автор вопроса
    Griboks, да то, что как (группа) отдельных DLL - это понятно.
    Можно ли эти DLL достаточно безопасно подгрузить с сервера в рантайм, или же "запустить прям на сервере" и получить уже "машинный код(IL code)" и какие для этого есть пути.
    Я вот сейчас пытаюсь понять предложенный выше вариант с шифрованием и ResolveEventHandler - такой метод вроде выглядит очень перспективно из-за того, что не надо писать приватные DLL на с++,
    но вот после расшифровки и подгрузки они же будут в оперативе в виде "IL code" инструкций и из них же можно обратно собрать C#?
    Я в этом ничего не понимаю - это вообще сложно - вычленить из работающего c# приложения нужные инструкции и пересобрать в c#? Что (где ) почитать по этой теме?
    Тут просто лицензия всего 10уе, а в приватном коде нет ничего революционного - он просто работает чуть лучше и дает немного больше чем другие аналогичнее бесплатные реализации.
    Хотя как посмотреть. Всё такие больше 2лет его пилю ;-))
  • Как реализовать платные доп. опции в C# приложении (схема)?

    @wlastas Автор вопроса
    d-stream
    Правильно ли я понял вашу идею?
    На сервере хранятся C# dll c реализацией приватных функций.
    По запросу от пользователя, я проверяю наличие активных лицензий, привязанных к его key, и шифрую DLL с этим key и отправляю закодированную DLL пользователю.
    На PC пользователя нейтив С++ код проверяет соответствие key, вшитого в кодированную DLL, компьютеру на котором он запускается, и если все ок расшифровывает кодированные DLL внутри метода ResolveEventHandler() и подключает их к текущей запущенной версии основного приложения?
  • Как реализовать платные доп. опции в C# приложении (схема)?

    @wlastas Автор вопроса
    Да базовая программа работает только при наличии постоянного сетевого подключения. 
    Каким образом наличие "патент/лицензионное соглашение" или же привязка лицензии и "постоянная её проверка"  поможет просто  отключить эту проверку путем комментирования функции, её вызывающей. 
    Это же С# с открытым исходником.
    Скорее всего у меня какие-то базовые пробелы во всем, что касается реализации безопасности.
    Нельзя ли чуть подробнее про "непрерывно проверяете лицензию"
  • Как реализовать платные доп. опции в C# приложении (схема)?

    @wlastas Автор вопроса
    Василий Банников, О интересно - спс, мне возможно, подойдет от туда та часть, что для Windows
    Сейчас использую простенькую функ, которая упорно не дает серийник с материнки:
    public CompKey() {
                Dictionary<string, string> ids =
                   new Dictionary<string, string>();
    
                ManagementObjectSearcher searcher;
    
                //процессор
                searcher = new ManagementObjectSearcher("root\\CIMV2",
                       "SELECT * FROM Win32_Processor");
                foreach(ManagementObject queryObj in searcher.Get())
                    ids.Add("ProcessorId", queryObj["ProcessorId"].ToString());
    
                //мать
                searcher = new ManagementObjectSearcher("root\\CIMV2",
                       "SELECT * FROM CIM_Card");
                foreach(ManagementObject queryObj in searcher.Get())
                    ids["MotherBoard"] = queryObj["Product"].ToString()+" "
                        + queryObj["SerialNumber"].ToString();
                //клавиатура
                searcher = new ManagementObjectSearcher("root\\CIMV2",
                       "SELECT * FROM CIM_KeyBoard");
                foreach(ManagementObject queryObj in searcher.Get())
                    ids["KeyBoardID"]= queryObj["DeviceId"].ToString();
    
                //ОС
                searcher = new ManagementObjectSearcher("root\\CIMV2",
                       "SELECT * FROM CIM_OperatingSystem");
                foreach(ManagementObject queryObj in searcher.Get())
                    ids.Add("OSSerialNumber", queryObj["SerialNumber"].ToString());
    
                //мышь
                searcher = new ManagementObjectSearcher("root\\CIMV2",
                       "SELECT * FROM Win32_PointingDevice");
                foreach(ManagementObject queryObj in searcher.Get())
                    ids["MouseID"]= queryObj["DeviceID"].ToString();
    
                //звук
                searcher = new ManagementObjectSearcher("root\\CIMV2",
                       "SELECT * FROM Win32_SoundDevice");
                foreach(ManagementObject queryObj in searcher.Get())
                    ids["SoundCardID"]= queryObj["DeviceID"].ToString();
    
                //CD-ROM
                searcher = new ManagementObjectSearcher("root\\CIMV2",
                       "SELECT * FROM Win32_CDROMDrive");
                foreach(ManagementObject queryObj in searcher.Get())
                    ids["CDROMID"]= queryObj["DeviceID"].ToString();
    
                //UUID
                searcher = new ManagementObjectSearcher("root\\CIMV2",
                       "SELECT UUID FROM Win32_ComputerSystemProduct");
                foreach(ManagementObject queryObj in searcher.Get())
                    ids["UUID"]= queryObj["UUID"].ToString();
                var sb = new StringBuilder();
                foreach(var x in ids)
                    sb.Append( x.Key + ": " + x.Value + "\r\n");
                key = sb.ToString();
            }
  • Как реализовать платные доп. опции в C# приложении (схема)?

    @wlastas Автор вопроса
    Saboteur,  О! Про "оставлять залоченным" очень интересно - спс за идею, честно говоря еще не думал про детали реализации всей этой катавасии с лицензиями.
  • Можно ли записать в одну строку?

    @wlastas Автор вопроса
    insighter,
    вау - это в точности то, что я пытался реализовать - и то, что мне надо!!! биг фенкс Ж-))
    var leader = new Func<Entity>(() => {
                    var lui = ui as UI; var l = lui.leader;  return (l == null || l.Owner == null || !l.Owner.IsValid || lui.b_leader_dead) ? null : lui.leader.Owner; })();
  • Можно ли записать в одну строку?

    @wlastas Автор вопроса
    insighter,
    настрой отступ в два пробела ))

    Тут просто отладка на удаленной виртуальной машине в Китае(всего 1-5 кадров в сек из-за ихнего фаервола) с дорогущим видеоадаптером - приходится брать минимальное разрешение(объем памяти адаптера).
    Нужна компакность имено по вертикали -> в право я могу отскролить -если надо посомтреть значения в режиме отладки.
    Почему нельзя оставлять lui & l на все время работы метода и написать 3 строки в одну
    var lui = ui as UI;  var l = lui.leader; var leader = (l == null || lui.b_leader_dead || !l.isValid)? null : l.Owner;

    я ответил выше
  • Можно ли записать в одну строку?

    @wlastas Автор вопроса
    Foggy Finder,
    что такое ui?

    Условно - UI это imgui реализация aUI (абстрактный базовый класс) пользовательского интерфейса, в котором есть ссылка на Leader - которого нет у aUI, потому что aUI находится в другой сборке и ничего не знает про сущность "Leader" - поэтому и нужно var lui = ui as UI;
  • Можно ли записать в одну строку?

    @wlastas Автор вопроса
    edward_freedom,
    почему ты хочешь от них избавится?

    потому что в рамках метода MakeTask() переменные lui & l нужны только в момент проверки валидности leader , так же как если бы они были вынесены в отдельный Properties=>get.   Если же они висят(ссылаться на lui.leader ) все время работы метода MakeTask() или же внтури похожего Task.Tick() - который вызывается 60 раз в сек,  то это периодически вызывает исключение, так как эти Tick() работают в отдельном от lui несинхронизированном потоке