GCC编译的Win32程序在系统DLL调用期间崩溃

只是

我尝试从不使用Microsoft SDK库的情况下调用IcmpSendEcho加载我在Windows 7 x64上使用GCC 4.8.1(win32)。我这样尝试过:iphlpapi.dll

  1. 创建所需的结构并定义常量
  2. 获取指向DLL函数的指针
  3. 调用DLL函数

我整理了一个小例子来说明我的问题:

#include <windows.h>
#include <stdio.h>
#include <stdint.h>

typedef struct {
  union {
    struct {
      u_char s_b1,s_b2,s_b3,s_b4;
    } S_un_b;
    struct {
      u_short s_w1,s_w2;
    } S_un_w;
    u_long S_addr;
  } S_un;
} IPAddr;


#define IP_FLAG_REVERSE 0x01
#define IP_FLAG_DF      0x02

typedef struct {
  UCHAR  Ttl;
  UCHAR  Tos;
  UCHAR  Flags;
  UCHAR  OptionsSize;
  PUCHAR OptionsData;
} IP_OPTION_INFORMATION;


typedef struct {
  IPAddr                       Address;
  ULONG                        Status;
  ULONG                        RoundTripTime;
  USHORT                       DataSize;
  USHORT                       Reserved;
  PVOID                        Data;
  IP_OPTION_INFORMATION        Options;
} ICMP_ECHO_REPLY;


typedef HANDLE (*IcmpCreateFile_t)();

typedef BOOL (*IcmpCloseHandle_t)(
    HANDLE IcmpHandle // _In_  HANDLE IcmpHandle
);

typedef DWORD (*IcmpSendEcho_t)(
    HANDLE IcmpHandle,  // _In_      HANDLE IcmpHandle,
    IPAddr dst,         // _In_      IPAddr DestinationAddress,
    void * RequestData, // _In_      LPVOID RequestData,
    WORD RequestSize,   // _In_      WORD RequestSize,
    IP_OPTION_INFORMATION * RequestOptions, // _In_opt_  PIP_OPTION_INFORMATION RequestOptions,
    void * ReplyBuffer, // _Out_     LPVOID ReplyBuffer,
    DWORD ReplySize,    // _In_      DWORD ReplySize,
    DWORD Timeout       // _In_      DWORD Timeout
);


HINSTANCE hIPHLPAPI = NULL;
IcmpCreateFile_t  IcmpCreateFile  = NULL;
IcmpCloseHandle_t IcmpCloseHandle = NULL;
IcmpSendEcho_t    IcmpSendEcho    = NULL;

HANDLE hIcmpFile;

int icmp_init() {
    hIPHLPAPI = LoadLibrary("iphlpapi.dll");
    if(hIPHLPAPI == NULL) return 0;

    IcmpCreateFile = (IcmpCreateFile_t) GetProcAddress(hIPHLPAPI, "IcmpCreateFile");
    if(IcmpCreateFile == NULL) return 0;

    IcmpCloseHandle = (IcmpCloseHandle_t) GetProcAddress(hIPHLPAPI, "IcmpCloseHandle");
    if(IcmpCloseHandle == NULL) return 0;

    IcmpSendEcho = (IcmpSendEcho_t) GetProcAddress(hIPHLPAPI, "IcmpSendEcho");
    if(IcmpSendEcho == NULL) return 0;

    hIcmpFile = IcmpCreateFile();
    if(!hIcmpFile) return 0;

    return 1;
}

int icmp_ping(uint32_t ip) {
    // Echo request data
    int dataSize = 32;
    void * data = malloc(dataSize);

    // Reply buffer
    int replySize = sizeof(ICMP_ECHO_REPLY) + 128;
    void * replyBuffer = malloc(replySize);
    if(replyBuffer == NULL) return 0;

    // Send echo request and wait for reply
    IPAddr dst;
    dst.S_un.S_addr = ip;
    printf("Calling IcmpSendEcho\n");
    DWORD dwRetVal = IcmpSendEcho(hIcmpFile, dst, data, dataSize, NULL, replyBuffer, replySize, 1000);
    if(dwRetVal == 0) return 0;

    ICMP_ECHO_REPLY *echoreply = (ICMP_ECHO_REPLY *) replyBuffer;
    printf("Status = %ld\n", echoreply->Status);

    free(replyBuffer);

    return 0;
}

int icmp_free() {
    FreeLibrary(hIPHLPAPI);
    return 1;
}

int main(int argc, char *argv[]) {
    if(icmp_init()) {
        int pret = icmp_ping(2915201282 /* google.com */);
        printf("icmp_ping returned %d\n", pret);
        icmp_free();
    }
}

我使用编译此示例gcc -o icmp_test.exe icmpt_test.c它打印“ Calling IcmpSendEcho”并崩溃(请参阅下文)。

这不是“真实的”代码,但以相同的方式失败。调用IcmpCreateFile成功,但是调用IcmpSendEcho使程序崩溃,并使Windows显示“ ...已停止工作”。

我认为问题可能与错误的指针有关,但我找不到问题。

我检查

在动态链接使用的库时GetProcAddress,需要确保您同时匹配签名和调用约定。虽然通常通常很容易获得正确的签名,但忘记帐户调用约定也很容易

Windows中的系统模块始终使用__stdcall,也可以通过WINAPI预处理器宏使用。要修复代码,以便编译器为函数调用生成适当的指令,您需要更新以下函数指针类型以包括适当的调用约定:

typedef HANDLE (WINAPI* IcmpCreateFile_t)();

typedef BOOL (WINAPI* IcmpCloseHandle_t)(
    HANDLE IcmpHandle // _In_  HANDLE IcmpHandle
);

typedef DWORD (WINAPI* IcmpSendEcho_t)(
    HANDLE IcmpHandle,  // _In_      HANDLE IcmpHandle,
    IPAddr dst,         // _In_      IPAddr DestinationAddress,
    void * RequestData, // _In_      LPVOID RequestData,
    WORD RequestSize,   // _In_      WORD RequestSize,
    IP_OPTION_INFORMATION * RequestOptions, // _In_opt_  PIP_OPTION_INFORMATION
    RequestOptions,
    void * ReplyBuffer, // _Out_     LPVOID ReplyBuffer,
    DWORD ReplySize,    // _In_      DWORD ReplySize,
    DWORD Timeout       // _In_      DWORD Timeout
);

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

无法使用GCC从MSDN编译Win32应用程序的示例

来自分类Dev

win32 程序在 GCC 中编译但不是 G++ HDC 错误

来自分类Dev

从 Win32 控制台应用程序调用 dll [C]

来自分类Dev

程序集Win32 _printf代码崩溃

来自分类Dev

如何从powerbuilder11.5调用win32 dll?

来自分类Dev

从Win32 dll调用.Net内置类

来自分类Dev

我的Win32 C ++“ Hello World程序”无法编译

来自分类Dev

C#程序AccessViolationException中的Win32 DLL

来自分类Dev

mingw32-g++ 编译器如何知道在 WIN32 机器可执行文件中注入系统调用的位置?

来自分类Dev

崩溃调试Win32 App

来自分类Dev

崩溃调试Win32 App

来自分类Dev

是否有比 procmon 更可靠的 Win32 系统调用跟踪方法?

来自分类Dev

当我使用参数调用Win32函数时,为什么GCC使用帧指针?

来自分类Dev

调用dll函数,该函数需要从python指向句柄(win32)的指针

来自分类Dev

WPF程序-程序无效win32

来自分类Dev

Win32应用程序,在调用Windows东西之前调用自定义类方法

来自分类Dev

针对Win32 x64编译后,Electron应用程序将无法打开

来自分类Dev

DLL加载失败:%1不是有效的Win32应用程序-Appcelerator

来自分类Dev

在python中加载DLL时出错,不是有效的Win32应用程序

来自分类Dev

'matplotlib'ImportError:DLL加载失败:%1不是有效的Win32应用程序

来自分类Dev

DLL加载失败-不是有效的Win32应用程序-使用NumPy

来自分类Dev

JNI C ++ DLL-'UnsatisfiedLinkError:%1不是有效的Win32应用程序'

来自分类Dev

Python:DLL加载失败:%1不是有效的Win32应用程序

来自分类Dev

DLL加载失败:%1不是有效的Win32应用程序-Appcelerator

来自分类Dev

DLL加载失败-不是有效的Win32应用程序-使用NumPy

来自分类Dev

如何制作不依赖于msvc dll的Win32应用程序?

来自分类Dev

在通用 Windows 应用程序 C++ 上使用 win32 DLL 库

来自分类Dev

从Julia调用Win32函数

来自分类Dev

从Win32 / clr DLL中的资源加载.NET DLL

Related 相关文章

  1. 1

    无法使用GCC从MSDN编译Win32应用程序的示例

  2. 2

    win32 程序在 GCC 中编译但不是 G++ HDC 错误

  3. 3

    从 Win32 控制台应用程序调用 dll [C]

  4. 4

    程序集Win32 _printf代码崩溃

  5. 5

    如何从powerbuilder11.5调用win32 dll?

  6. 6

    从Win32 dll调用.Net内置类

  7. 7

    我的Win32 C ++“ Hello World程序”无法编译

  8. 8

    C#程序AccessViolationException中的Win32 DLL

  9. 9

    mingw32-g++ 编译器如何知道在 WIN32 机器可执行文件中注入系统调用的位置?

  10. 10

    崩溃调试Win32 App

  11. 11

    崩溃调试Win32 App

  12. 12

    是否有比 procmon 更可靠的 Win32 系统调用跟踪方法?

  13. 13

    当我使用参数调用Win32函数时,为什么GCC使用帧指针?

  14. 14

    调用dll函数,该函数需要从python指向句柄(win32)的指针

  15. 15

    WPF程序-程序无效win32

  16. 16

    Win32应用程序,在调用Windows东西之前调用自定义类方法

  17. 17

    针对Win32 x64编译后,Electron应用程序将无法打开

  18. 18

    DLL加载失败:%1不是有效的Win32应用程序-Appcelerator

  19. 19

    在python中加载DLL时出错,不是有效的Win32应用程序

  20. 20

    'matplotlib'ImportError:DLL加载失败:%1不是有效的Win32应用程序

  21. 21

    DLL加载失败-不是有效的Win32应用程序-使用NumPy

  22. 22

    JNI C ++ DLL-'UnsatisfiedLinkError:%1不是有效的Win32应用程序'

  23. 23

    Python:DLL加载失败:%1不是有效的Win32应用程序

  24. 24

    DLL加载失败:%1不是有效的Win32应用程序-Appcelerator

  25. 25

    DLL加载失败-不是有效的Win32应用程序-使用NumPy

  26. 26

    如何制作不依赖于msvc dll的Win32应用程序?

  27. 27

    在通用 Windows 应用程序 C++ 上使用 win32 DLL 库

  28. 28

    从Julia调用Win32函数

  29. 29

    从Win32 / clr DLL中的资源加载.NET DLL

热门标签

归档