GetProcAddress로 외부 함수를 호출하면 앱이 충돌 함

user3145274

GetProcAddress 함수를 사용하여 외부 함수를 호출하려고 시도했지만 함수를 호출 할 때마다 콘솔이 충돌하고 찾고 있었지만 모든 게시물에서 동일한 최종 솔루션을 얻었지만 DLL에서 시도하면 앱이 충돌합니다. .

코드는 다음과 같습니다.

#include <Windows.h>
#include <vector>
#include "SDK\plugin.h"

typedef void (*logprintf_t)(char* format, ...);
logprintf_t logprintf;
// static void* m_AMXExports[44];

typedef bool (PLUGIN_CALL *ServerPluginLoad_t)(void **data);
typedef void (PLUGIN_CALL *ServerPluginUnload_t)();
typedef unsigned int (PLUGIN_CALL *ServerPluginSupports_t)();
typedef void (PLUGIN_CALL *ServerPluginProcessTick_t)();

typedef int (PLUGIN_CALL *ServerPluginAmxLoad_t)(AMX *amx);
typedef int (PLUGIN_CALL *ServerPluginAmxUnload_t)(AMX *amx);

struct Plugins
{
    void* AppData[256];
    SUPPORTS_FLAGS FlagSupport;
    HMODULE Module;
    ServerPluginLoad_t      LOAD;
    ServerPluginUnload_t    UNLOAD;
    ServerPluginSupports_t  SUPPORTS;
    ServerPluginProcessTick_t   PROCESSTICK;

    // AMX Plugin Interface
    ServerPluginAmxLoad_t   AMXLOAD;
    ServerPluginAmxUnload_t AMXUNLOAD;
};
Plugins* ServerPlugins;

void **ppPluginData ;

extern void *pAMXFunctions;

//native LoadLibrary(libraryname[]);
static cell AMX_NATIVE_CALL my_LoadLibrary(AMX* amx, cell* params)
{
    bool validfunc = false;
    char *path;
    amx_StrParam(amx, params[1], path);
    logprintf("Loading plugin %s", path);
    ServerPlugins = new Plugins();
    ServerPlugins->Module = LoadLibraryA(path);
    if (ServerPlugins->Module == NULL)
    {
        delete ServerPlugins;
        logprintf("Failed loading plugin %s (Error: %d)", path, GetLastError());
        return 0;
    }
    logprintf("NULL");
    ServerPlugins->LOAD = (ServerPluginLoad_t)GetProcAddress(ServerPlugins->Module, "Load");
    ServerPlugins->UNLOAD = (ServerPluginUnload_t)GetProcAddress(ServerPlugins->Module, "Unload");
    ServerPlugins->SUPPORTS = (ServerPluginSupports_t)GetProcAddress(ServerPlugins->Module, "Supports");
    if (ServerPlugins->LOAD == NULL || ServerPlugins->SUPPORTS == NULL || ServerPlugins->UNLOAD == NULL)
    {
        logprintf(" Plugin doesnt conform to architecture");
        FreeLibrary(ServerPlugins->Module);
        delete ServerPlugins;
        return false;
    }
    logprintf("NULL 1");
    ServerPlugins->FlagSupport = (SUPPORTS_FLAGS)ServerPlugins->SUPPORTS();
    if ((ServerPlugins->FlagSupport & SUPPORTS_VERSION_MASK) > SUPPORTS_VERSION)
    {
        logprintf("Unsupported Version; unloading.");
        FreeLibrary(ServerPlugins->Module);
        delete ServerPlugins;
        return false;
    }
    logprintf("NULL 2");
    if ((ServerPlugins->FlagSupport & SUPPORTS_AMX_NATIVES) > SUPPORTS_VERSION)
    {
        ServerPlugins->AMXLOAD = (ServerPluginAmxLoad_t)GetProcAddress(ServerPlugins->Module, "AmxLoad");
        ServerPlugins->AMXUNLOAD = (ServerPluginAmxUnload_t)GetProcAddress(ServerPlugins->Module, "AmxUnload");
    }
    else
    {
        ServerPlugins->AMXLOAD = NULL;
        ServerPlugins->AMXUNLOAD = NULL;
        logprintf("Any Abstract Machine has been loaded");
    }
    logprintf("NULL 3");
    if ((ServerPlugins->FlagSupport & SUPPORTS_PROCESS_TICK) != 0)
    {
        ServerPlugins->PROCESSTICK = (ServerPluginProcessTick_t)GetProcAddress(ServerPlugins->Module, "ProcessTick");
    }
    else
    {
        ServerPlugins->PROCESSTICK = NULL;
    }
    logprintf("NULL 4"); //debugging
    ServerPlugins->AppData[PLUGIN_DATA_AMX_EXPORTS] = pAMXFunctions;
    ServerPlugins->AppData[PLUGIN_DATA_LOGPRINTF] = &logprintf;
    if (!(ServerPlugins->LOAD)(ServerPlugins->AppData)) //i didnt put it as &ServerPlugins->AppData because it causes an error
    {

        logprintf("Initialized failed loading plugin %s", path);
        FreeLibrary(ServerPlugins->Module);
        logprintf("NULL 5");
        delete ServerPlugins;
        return false;
    }
    logprintf("Plugin %s loaded", path);
    return true;
}
//native UnloadLibrary(libraryname[]);
static cell AMX_NATIVE_CALL my_UnloadLibrary(AMX*amx, cell*params)
{
    char *path;
    amx_StrParam(amx, params[1], path);
    ServerPlugins->Module = GetModuleHandle((LPCTSTR)path);
    if (ServerPlugins->Module != NULL)
    {
        ServerPlugins->UNLOAD = (ServerPluginUnload_t)GetProcAddress(ServerPlugins->Module, "Unload");
        if (ServerPlugins->UNLOAD != NULL)
        {
            ServerPlugins->UNLOAD();
            FreeLibrary(GetModuleHandleA(path));
            logprintf("Library %s has been unloaded correctly", path);
            return 1;
        }
        else
        {
            logprintf("Unloading library %s failed (Error: %d)", GetLastError());
            return 0;
        }
    }
    return 1;
}

PLUGIN_EXPORT bool PLUGIN_CALL Load(void **ppData)
{
    pAMXFunctions = ppData[PLUGIN_DATA_AMX_EXPORTS];
    logprintf = (logprintf_t)ppData[PLUGIN_DATA_LOGPRINTF];
    return 1;
}

PLUGIN_EXPORT void PLUGIN_CALL Unload()
{
}

PLUGIN_EXPORT unsigned int PLUGIN_CALL Supports()
{
    return SUPPORTS_VERSION | SUPPORTS_AMX_NATIVES;
}

AMX_NATIVE_INFO projectNatives[] =
{
    { "LoadLibrary", my_LoadLibrary },
    { "UnloadLibrary", my_UnloadLibrary }
};

PLUGIN_EXPORT int PLUGIN_CALL AmxLoad(AMX *amx)
{
    return amx_Register(amx, projectNatives, -1);
}

PLUGIN_EXPORT int PLUGIN_CALL AmxUnload(AMX *amx)
{
    return AMX_ERR_NONE;
}
레미 르보

.NET에서 메모리 누수가 convertCharArrayToLPCWSTR()있습니다. 당신은 당신이 wchar_t*할당 것을 결코 해방시키지 않습니다 . convertCharArrayToLPCWSTR()자체가 필요하지 않은 기능은 단순히 전달할 수 char*에 그대로 경로를 LoadLibraryA()대신 :

char *path;
amx_StrParam(amx, params[1], path);
...
ServerPlugins->Module = LoadLibraryA(path);

ServerPlugins->UNLOAD의해 성공적으로로드 되었는지 여부를 확인 GetProcAddress("Unload")하지 않습니다.

당신이 사용하는 GetProcAddress("Load")모두 ServerPlugins->LOADServerPlugins->AMXLOAD, 그리고 GetProcAddress("Unload")모두 ServerPlugins->UNLOADServerPlugins->AMXUNLOAD. 그것은 나에게 매우 수상합니다. DLL이 AMX 및 비 AMX 진입 점에 대해 동일한 내보내기를 실제로 사용합니까? 그렇다면, 그것은 아주 나쁜 디자인은 고려이다 ServerPluginLoad_t매우 다른 서명이 ServerPluginAmxLoad_t, 그리고에 대해 동일합니다 ServerPlugin(Amx)Unload_t. 그것은 일어나기를 기다리는 손상된 호출 스택입니다. 별도의 DLL에 수출을하는 것이 훨씬 안전 할 것입니다 AmxLoad()AmxUnload()기능을 대신합니다.

그 문제에 대해 SUPPORTS_AMX_NATIVESSUPPORTS_PROCESS_TICK플래그는 GetProcAddress()해당 내보내기를 사용할 수 있는지 여부를 알려주기 때문에 중복 됩니다.

호출 할 때 충돌에 관해서는 데이터를 전달하기 전에 어떤 데이터로 ServerPlugins->LOAD초기화 ppData하는 것을 보지 못합니다 Load(). 적어도 다음 PLUGIN_DATA_AMX_EXPORTS과 같은 PLUGIN_DATA_LOGPRINTF슬롯 은 아닙니다 .

ppData[PLUGIN_DATA_AMX_EXPORTS] = pAMXFunctions;
ppData[PLUGIN_DATA_LOGPRINTF] = &logprintf;
if (!(ServerPlugins->LOAD)(ppData))

따라서 Load()자체 호출이 충돌하지 않더라도 DLL은 나중에 .NET에 할당 된 로컬 pAMXFunctionslogprintf포인터 를 사용하려고 할 때 충돌 할 가능성이 높습니다 Load().

그 문제에 대해 왜 그런 것을 void*배열 대신 struct? 훨씬 더 안전했을 것입니다. 예 :

struct PluginInitData
{
    void* pAMXFunctions;
    logprintf_t logprintf;
    ...
};

typedef bool (__stdcall *ServerPluginLoad_t)(PluginInitData* data);

PluginInitData pInitData;
pInitData.pAMXFunctions = pAMXFunctions;
pInitData.logprintf = &logprintf;
...
if (!(ServerPlugins->LOAD)(&pInitData))

extern "C" bool __stdcall Load(PluginInitData* data)
{
    pAMXFunctions = data->pAMXFunctions;
    logprintf = data->logprintf;
    ...
    return true;
}

업데이트 : 내가 언급 한 대부분의 문제를 해결했지만 이제 my_UnloadLibrary()기능이 잘못 구현되었음을 알 수 있습니다. 호출 하거나 전혀 사용 하지 말고 에서 이전에 초기화 된 기존 포인터를 사용하십시오 .GetModuleHandle()GetProcAddress()ModuleUNLOADmy_LoadLibrary()

static cell AMX_NATIVE_CALL my_LoadLibrary(AMX* amx, cell* params)
{
    char *path;
    amx_StrParam(amx, params[1], path);
    ...
    ServerPlugins->Path = path;
    ...
}

static cell AMX_NATIVE_CALL my_UnloadLibrary(AMX*amx, cell*params)
{
    if (ServerPlugins)
    {
        if (ServerPlugins->UNLOAD != NULL)
            ServerPlugins->UNLOAD();

        if (ServerPlugins->Module != NULL)
        {
            FreeLibrary(ServerPlugins->Module);
            ServerPlugins->Module = NULL;
        }

        logprintf("Library %s has been unloaded", ServerPlugins->Path);

        delete ServerPlugins;
        ServerPlugins = NULL;
    }

    return 1;
}

여전히 Load()크래시 문제가있는 경우 컴파일러의 디버거를 사용하여 런타임에 실제로 어떤 일이 발생하는지 알아 내야합니다. 지금까지 표시된 코드는 충돌하지 않아야합니다. 따라서 호출 규칙 불일치, 데이터 정렬 불일치, 메모리 손상 등이 있습니다. 디버거를 실행할 수 없습니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

외부 함수 포인터를 호출하면 프로그램이 충돌하는 이유는 무엇입니까?

분류에서Dev

고유 포인터를 사용하여 함수를 호출하면 내 프로그램이 충돌합니다.

분류에서Dev

배포 프로필을 추가하면 Mac 앱이 충돌 함

분류에서Dev

Google지도로 스크롤하면 Ionic Android 앱이 충돌 함

분류에서Dev

null 포인터 예외로 시작시 Android 앱이 충돌 함

분류에서Dev

java.lang.stackOverflow 예외로 앱이 충돌 함

분류에서Dev

SharedPreferences가 호출되면 앱이 충돌 함 (NullPointerException)

분류에서Dev

BroadcastReceiver가 호출되면 앱이 충돌 함

분류에서Dev

Parse 예외로 인해 뒤로 버튼으로 삭제하면 Android 앱이 충돌 함

분류에서Dev

GetProcAddress를 통해 추출 된 함수 포인터가 응용 프로그램과 충돌합니다.

분류에서Dev

탭으로보기 스 와이프를 설정하면 앱이 충돌 함

분류에서Dev

활동이 세로 모드를 시작하면 앱이 충돌 함

분류에서Dev

UIButton 클릭으로 앱이 충돌 함

분류에서Dev

CalendarView로 인해 앱이 충돌 함

분류에서Dev

뒤로 버튼을 누르면 앱이 충돌 함 (Android Studio)

분류에서Dev

JNI에서 Java 메소드를 호출하면 프로그램 충돌이 발생 함

분류에서Dev

libcurl curl_easy_perform () 함수 내부로 이동하면 프로그램이 충돌 함

분류에서Dev

Windows 7 이하에서 앱이 충돌하지 않고 Windows 8에만 존재하는 외부 함수를 선언하는 방법은 무엇입니까?

분류에서Dev

UITableView를 두 번 클릭하면 앱이 충돌 함

분류에서Dev

useeffect에 내 함수를 전달하면 내 앱이 충돌합니다.

분류에서Dev

Android setText가 onCreate 메서드에서 호출되면 앱이 충돌 함

분류에서Dev

PayPal이 거래를 승인 / 완료하면 외부 함수 호출

분류에서Dev

SwiftUI : EnvironmentObject를 수정하는 View 본문의 함수를 호출하면 무한 루프 및 앱 충돌이 발생합니다.

분류에서Dev

xcode를 통해 시작하지 않으면 화면을로드 한 후 앱이 충돌 함

분류에서Dev

Arduino에서 데이터를 수신하는 동안 WPF 앱이 충돌 함

분류에서Dev

ListView를 아래로 스크롤 한 후 Android 앱이 충돌 함

분류에서Dev

Android-JsonFactory를 만들면 앱 충돌이 발생 함

분류에서Dev

인텔 MKL에서 함수를 호출 할 때 Matlab이 충돌 함

분류에서Dev

hardware-settings-button을 클릭하면 앱이 충돌 함

Related 관련 기사

  1. 1

    외부 함수 포인터를 호출하면 프로그램이 충돌하는 이유는 무엇입니까?

  2. 2

    고유 포인터를 사용하여 함수를 호출하면 내 프로그램이 충돌합니다.

  3. 3

    배포 프로필을 추가하면 Mac 앱이 충돌 함

  4. 4

    Google지도로 스크롤하면 Ionic Android 앱이 충돌 함

  5. 5

    null 포인터 예외로 시작시 Android 앱이 충돌 함

  6. 6

    java.lang.stackOverflow 예외로 앱이 충돌 함

  7. 7

    SharedPreferences가 호출되면 앱이 충돌 함 (NullPointerException)

  8. 8

    BroadcastReceiver가 호출되면 앱이 충돌 함

  9. 9

    Parse 예외로 인해 뒤로 버튼으로 삭제하면 Android 앱이 충돌 함

  10. 10

    GetProcAddress를 통해 추출 된 함수 포인터가 응용 프로그램과 충돌합니다.

  11. 11

    탭으로보기 스 와이프를 설정하면 앱이 충돌 함

  12. 12

    활동이 세로 모드를 시작하면 앱이 충돌 함

  13. 13

    UIButton 클릭으로 앱이 충돌 함

  14. 14

    CalendarView로 인해 앱이 충돌 함

  15. 15

    뒤로 버튼을 누르면 앱이 충돌 함 (Android Studio)

  16. 16

    JNI에서 Java 메소드를 호출하면 프로그램 충돌이 발생 함

  17. 17

    libcurl curl_easy_perform () 함수 내부로 이동하면 프로그램이 충돌 함

  18. 18

    Windows 7 이하에서 앱이 충돌하지 않고 Windows 8에만 존재하는 외부 함수를 선언하는 방법은 무엇입니까?

  19. 19

    UITableView를 두 번 클릭하면 앱이 충돌 함

  20. 20

    useeffect에 내 함수를 전달하면 내 앱이 충돌합니다.

  21. 21

    Android setText가 onCreate 메서드에서 호출되면 앱이 충돌 함

  22. 22

    PayPal이 거래를 승인 / 완료하면 외부 함수 호출

  23. 23

    SwiftUI : EnvironmentObject를 수정하는 View 본문의 함수를 호출하면 무한 루프 및 앱 충돌이 발생합니다.

  24. 24

    xcode를 통해 시작하지 않으면 화면을로드 한 후 앱이 충돌 함

  25. 25

    Arduino에서 데이터를 수신하는 동안 WPF 앱이 충돌 함

  26. 26

    ListView를 아래로 스크롤 한 후 Android 앱이 충돌 함

  27. 27

    Android-JsonFactory를 만들면 앱 충돌이 발생 함

  28. 28

    인텔 MKL에서 함수를 호출 할 때 Matlab이 충돌 함

  29. 29

    hardware-settings-button을 클릭하면 앱이 충돌 함

뜨겁다태그

보관