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

Странная ошибка при попытке скрыть импорт C++

Alexey18

(L3) cache
Пользователь
Регистрация
11.06.2023
Сообщения
163
Реакции
30
Вызвано исключение по адресу 0x00000000 в example.exe: 0xC0000005: нарушение прав доступа при исполнении по адресу 0x00000000.
Код ниже. Самое удивительное, что в дебаге отрабатывает, а в релизе нет. Думал что проблема в оптимизации - оказался не прав.
1690407886383.png

В релизе запускается только так
1690408115266.png


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


Вот несколько основных проблем с вашим исходным кодом:

  1. Синтаксис определения функции: В вашем исходном коде используется нестандартный синтаксис для определения функции. В C++ функции обычно определяются с помощью следующего синтаксиса:
    cpp
  • returnType functionName(argType1 arg1, argType2 arg2, ...)
    Ваша попытка определить функцию MyMessageBoxA не следует этому синтаксису.
  • Использование оператора #define: Вы пытались использовать #define для создания макроса, который определяет MyMessageBoxA, но его синтаксис был неверным. #define используется для создания макросов или констант, а не для определения функций.
  • Неинициализированный указатель функции: В вашем коде указатель на функцию MyMessageBoxA был объявлен, но не инициализирован. Это могло привести к ошибке сегментации или нарушению защиты памяти при попытке использовать указатель.
  • Ошибка в использовании GetModuleHandleA и GetProcAddress: Ваш код содержал ошибку регистра при вызове getprocaddress(huser32, "messageboxa"). В C++ регистр имеет значение, поэтому getprocaddress и huser32 должны быть написаны как GetProcAddress и hUser32 соответственно.
  • Отсутствие вызова connect: В вашем коде функция connect была определена, но не вызывалась. Без вызова этой функции указатель MyMessageBoxA так и остается неинициализированным.
  • Неправильный вызов функции MessageBoxA: Ваш код пытался вызвать MessageBoxA напрямую, вместо использования указателя MyMessageBoxA. Поскольку MyMessageBoxA является указателем на функцию, его следует использовать для вызова функции.



    C++:
    #include <windows.h>
    #include <iostream>
    
    // Define the MessageBox function type
    typedef int (WINAPI *MessageBoxA_t)(HWND, LPCSTR, LPCSTR, UINT);
    
    MessageBoxA_t MyMessageBoxA = NULL;
    
    void connect() {
        HMODULE hUser32 = GetModuleHandleA("user32.dll");
        if (hUser32 != NULL) {
            MyMessageBoxA = (MessageBoxA_t)GetProcAddress(hUser32, "MessageBoxA");
            if (MyMessageBoxA == NULL) {
                std::cout << "Failed to get MessageBoxA address" << std::endl;
            }
        } else {
            std::cout << "Failed to get user32.dll handle" << std::endl;
        }
    }
    
    int main() {
        connect();
        if (MyMessageBoxA != NULL) {
            MyMessageBoxA(NULL, "Hello, world!", "", MB_OK);
        }
        std::cin.get();
        return 0;
    }
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Во-первых, выкладывайте код, а не скрины.
Во-вторых, а с чего вы взяли, что user32.dll загружена в процесс? Ошибка в том, что она не загружена.
В-третьих, старайтесь не называть функции также, как есть и в винапи) (я про connect)

То есть хотя бы так сделайте
C++:
int(__stdcall* MyMessageBoxA)(HWND, LPCSTR, LPCSTR, UINT) = 0;

void _connect() {
    HMODULE hUser32 = GetModuleHandleA("user32.dll");
    if (!hUser32) {
        hUser32 = LoadLibraryA("user32.dll");
        if (hUser32) {
            MyMessageBoxA = reinterpret_cast<int(__stdcall*)(HWND, LPCSTR, LPCSTR, UINT)>(GetProcAddress(hUser32, "MessageBoxA"));
        }
    }
}

int main(int argc, char* argv[])
{
    _connect();
    if (MyMessageBoxA)
        MyMessageBoxA(0, 0, 0, 0);
    return 0;
}
 
Пожалуйста, обратите внимание, что пользователь заблокирован
пробуй)


Вот несколько основных проблем с вашим исходным кодом:

  1. Синтаксис определения функции: В вашем исходном коде используется нестандартный синтаксис для определения функции. В C++ функции обычно определяются с помощью следующего синтаксиса:
    cpp
  • returnType functionName(argType1 arg1, argType2 arg2, ...)
    Ваша попытка определить функцию MyMessageBoxA не следует этому синтаксису.
  • Использование оператора #define: Вы пытались использовать #define для создания макроса, который определяет MyMessageBoxA, но его синтаксис был неверным. #define используется для создания макросов или констант, а не для определения функций.
  • Неинициализированный указатель функции: В вашем коде указатель на функцию MyMessageBoxA был объявлен, но не инициализирован. Это могло привести к ошибке сегментации или нарушению защиты памяти при попытке использовать указатель.
  • Ошибка в использовании GetModuleHandleA и GetProcAddress: Ваш код содержал ошибку регистра при вызове getprocaddress(huser32, "messageboxa"). В C++ регистр имеет значение, поэтому getprocaddress и huser32 должны быть написаны как GetProcAddress и hUser32 соответственно.
  • Отсутствие вызова connect: В вашем коде функция connect была определена, но не вызывалась. Без вызова этой функции указатель MyMessageBoxA так и остается неинициализированным.
  • Incorrect call to MessageBoxA : Your code tried to call MessageBoxA directly instead of using the MyMessageBoxA pointer. Because MyMessageBoxA is a function pointer, it should be used to call the function.



    C++:
    #include <windows.h> 
    #include <iostream> 
    
    // Define the MessageBox function type 
    typedef int (WINAPI *MessageBoxA_t)(HWND, LPCSTR, LPCSTR, UINT); 
    
    MessageBoxA_t MyMessageBoxA = NULL; 
    
    void connect() { 
        HMODULE hUser32 = GetModuleHandleA("user32.dll"); 
        if (hUser32 != NULL) { 
            MyMessageBoxA = (MessageBoxA_t)GetProcAddress(hUser32, "MessageBoxA"); 
            if (MyMessageBoxA == NULL) {
                std::cout << "Failed to get MessageBoxA address" << std::endl; 
            } 
        } else { 
            std::cout << "Failed to get user32.dll handle" << std::endl; 
        } 
    } 
    
    int main() { 
        connect(); 
        if (MyMessageBoxA != NULL) { 
            MyMessageBoxA(NULL, "Hello, world!", "", MB_OK); 
        } 
        std::cin.get(); 
        return 0; 
    }
CHATGPT dropped it
 
Доброшу, что можно не плодить typedef-ы и получать тип функции в прямом эфире и без регистрации копипасты:
C++:
template <typename T>
struct decay {
    template <typename U> static U impl(U);
    using type = decltype(impl(declval<T>()));
};

template<auto F>
using function_type = decay<decltype(F)>::type;

Ну и дефайн для простоты набросить, но это уже на твое усмотрение
C++:
API(dll, function) static_cast<function_type<function>>(GetFuncAddr(dll, # function))

API(KERNEL32, Sleep)(5000);
 
1) Нужно сначала обьявлять прототип функции, а затем указатель на неё. Ты же обращаешься к прототипу. Правильно будет вот так:

MyMessageBoxA fnMessageBoxA = (MyMessageBoxA)...
2) User32 не загружается в каждый процесс при старте, если она отсутствует, используй LoadLibraryA("user32.dll").
3) Нейминг говно. Он непонятен и пересекается с именами API функций, как указали выше. Называй функции и переменные логично, чтобы было понятно, для чего они предназначены.
4) У тебя в самом верху обьявлен макрос, который переопределяет MessageBoxA на _obf123. Зачем?

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


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