这听起来真的很奇怪。我正在使用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的地址,而不是RtlInt64ToUnicodeString的地址(这真是令人惊讶!)。这是代码:
// 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无关的事情似乎是罪魁祸首。
谢谢您的帮助。