всем привет! завёз очень крупную обнову в которой наконец переписал то мясо что было в репозитории, и заодно подвёз новый функционал
список изменений:
[
+] Добавлена поддержка компилятора gcc
[
+] Добавлена поддержка компилятора clang
[
+] Добавлен метод
shadowcall
, делает то же что и lazy_import
[
+] Добавлен класс
c_modules_range
который позволяет енумерироваться по всем модулям загруженным в процесс
[
+] Добавлен класс
c_module
для получения информации о заранее известном модуле
[
+] Добавлен класс
c_exports
для получения информации о EAT (а конкретнее енумерации экспортов) загруженного в процесс dll модуля
[
+] Добавлена структура
hash_t
хэширующая строки на этапе компиляции с гарантией consteval
[
+] Добавлены структуры
linux-pe
, за что большое спасибо
репозиторию и его контрибьюторам
[
+] Добавлена адекватная поддержка x86 архитектуры. к сожалению, но метод syscall будет недоступен, однако вы всё ещё можете юзать остальные классы и методы этой библиотеки
[
+] Изменено: shadowsyscall который раньше был дефайном, сейчас является функцией
[
+] Изменено: каждая ошибка что ранее обозначалась как #error стала static_assert
[
+] Изменено: static_assert на x86 архитектуре триггерится только при вызове .shadowsyscall функции. остальной функционал библиотеки всё ещё остаётся рабочим
[
+] Изменено: недо-мапа из прошлого репозитория заменена на std::unordered_map
[
-] Удалено: фарш из дефайнов
[
-] Удалено: метод .cached_call, каждый вызов теперь по дефолту является кэшированным. для полного отключения кэширования необходимо установить у дефайна SHADOWSYSCALLS_CACHING значение false
upd: example
int main()
{
shadowcall<HMODULE>( "LoadLibraryA", "user32.dll" );
/// Enumerate every module loaded to current process
///
for ( auto module : shadow::c_modules_range{} )
std::wcout << module->name.to_wstring() << "\n";
/// Find exactly known module loaded to current process
/// "ntdll.dll" doesn't leave string in executable, it
/// being hashed on compile-time with conclusive guarantee
///
auto module = shadow::c_module{ "ntdll.dll" };
/// Enumerate EAT of module
///
for ( auto [export_name, export_address] : shadow::c_exports{ module } )
std::cout << export_name << " : " << export_address << "\n";
/// Enumerate sections of module
///
for ( auto section : module.image()->get_nt_headers()->sections() )
std::cout << section.name.to_string() << "\n";
/// Execute any export at runtime
///
shadowcall<int>( "MessageBoxA", nullptr, "string 1", "string 2", MB_OK );
/// We need to call actually MessageBoxA, but not just MessageBox,
/// because the MessageBox is just a line of code defined by
/// Microsoft, the actual export is MessageBoxA / MessageBoxW.
// MessageBoxA( nullptr, "string 1", "string 2", MB_OK );
/// Execute syscall
///
shadowsyscall<NTSTATUS>( "NtTerminateProcess", reinterpret_cast< HANDLE >( -1 ), -6932 );
/// Find an export address
///
auto export_address = shadow::find_export_address( "NtTerminateProcess" );
// do something with the export
}