GetProcAddress使用Visual C ++返回正确的地址,使用g ++返回错误的地址

时间:2018-07-14 05:19:22

标签: g++ mingw-w64

这听起来真的很奇怪。我正在使用Visual Studio 2017 C ++(本机模式)以及MingW工具链的g ++ 4.7.1-2。目标是Windows 64位。

我使用VS C ++编译以下简单程序:

#include "stdafx.h"
#include <Windows.h>
#include <winternl.h>

typedef NTSTATUS (NTAPI* RTLINT64)(ULONGLONG, ULONG, PUNICODE_STRING);

RTLINT64 RtlInt64 = (RTLINT64) nullptr;

int main()
{
  UNICODE_STRING unicodestring    = { 0 };
  WCHAR          localbuffer[256] = { 0 };    // way more than enough

  __int64        value            =   0;

  unicodestring.Length = 0;
  unicodestring.MaximumLength = sizeof(localbuffer);
  unicodestring.Buffer = (PWCH) &localbuffer;

  // get ntdll's module handle 

  HMODULE NtDllModule = LoadLibrary(L"ntdll.dll");
  if (NtDllModule)
  {
     RtlInt64 = (RTLINT64) GetProcAddress(NtDllModule,
                                          "RtlInt64ToUnicodeString");

     value = 0xFFFFFFFFF;
     RtlInt64 (value, 10, &unicodestring);

     wprintf(L"%s\n", unicodestring.Buffer);
  }

  return 0;
}

` 如预期的那样,GetProcAddress返回RtlInt64ToUnicodeString的地址(在此不足为奇!)

下面的代码(除了包含代码)几乎是上面代码的副本。但是,以某种方式,在使用G ++编译的版本中,GetProcAddress返回RtlInterlockedSetBitRun的地址,而不是Rtl​​Int64ToUnicodeString的地址(这真是令人惊讶!)。这是代码:

// GCC  and MingW version

#include <Windows.h>
#include <winbase.h>
#include <strsafe.h>
#include <winuser.h>
#include <winternl.h>

// --------------------------------------------------------------------------

typedef NTSTATUS(NTAPI* RTLINT64)(ULONGLONG, ULONG, PUNICODE_STRING);

RTLINT64 RtlInt64 = (RTLINT64) nullptr;

// --------------------------------------------------------------------------

int main(int argc, char *argv[])
{
  WCHAR          localbuffer[256] = {0};     // way more than enough
  UNICODE_STRING unicodestring    = {0};

  __int64        value            =   0;

  unicodestring.Length = 0;
  unicodestring.MaximumLength = sizeof(localbuffer);
  unicodestring.Buffer = (PWCH) &localbuffer;

  // get ntdll's module handle 

  HMODULE NtDllModule = LoadLibraryW(L"ntdll.dll");
  if (NtDllModule)
  {
     RtlInt64 = (RTLINT64) GetProcAddress(NtDllModule,
                                     "RtlInt64ToUnicodeString");

     // the above call to GetProcAddress returned the address of 
     // RtlInterlockedSetBitRun instead of the address of the requested function

     // as a result, the statements below don't work.

         value = 0xFFFFFFFFF;
     RtlInt64(value, 10, &unicodestring);

     wprintf(L"%s\n", unicodestring.Buffer);
  }

  return 0;
}

我的问题是:上面的代码中是否有可以证明差异的理由?

还要注意,我将G ++与一个名为VisualGDB的工具一起使用,该工具将编译器和调试器集成到Visual Studio中。通常,这种事情会引起奇怪的“副作用”,但是在这种情况下,与ntdll无关的事情似乎是罪魁祸首。

谢谢您的帮助。

0 个答案:

没有答案