Kaputtes(?) GetProcAdress - Win8.1/WinXP-Kompatibilität

20/02/2015 - 22:45 von Robert Hartmann | Report spam
Hallo zusammen,

ich stehe vor einem Ràtsel.

Kann es sein das GetProcAdress unter Windows 8.1
einfach Pointer auf falsche Funktionen zurück liefert?


Ich stehe vor dem Problem, dass meine Executable(32bit)
sowohl auf Windows XP (32bit/ 64bit) wie auch neuerdings
auf Win 8.1 (32bit/64bit) laufen soll.

Kompiliert mit MinGW32 g++, MS VC 2005.

Unter XP làuft meine Anwendung.

Unter Win8.1 schmiert meine Anwendung einfach ab.

Um auszuschließen, dass sich irgendetwas anderes miteinander nicht
vertràgt, habe ich die problematische Anweisung
in ein kleines Beispiel eingebettet.
Dort besteht das Problem weiterhin.
Der kompilierbare Beispiel-Quelltext befindet sich unten.

Die problematische Zeile ist:

// crash in nextline: Win8.1 (64bit)
if (STATUS_SUCCESS != (nterr=pt2GetSecurityUserInfo(NULL, flag,
(PSecurityUserData) &userdata))){


Wobei pt2GetSecurityUserInfo ein Funktionspointer ist, dessen Adresse
durch GetProcAdress gesetzt wird.
Meine erste Vermutung war, dass ich unter Win8.1 nicht direkt die
Funktion aus der secur32.dll holen dürfe, daher hole ich die Funktion
aus der sspicli.dll, falls es diese Datei gibt. Aber auch der "Umweg"
über sspicli.dll bringt keine Verbesserung.


Das Beispiel liefert, so es làuft, auf der Konsole die
Informationen zum eingeloggten Nutzer, der das Programm gestartet hat.


Gruß Robert




8<==SecurityUserInfo.cpp>8

//// Name : SecurityUserInfo.cpp
// Author : Robert Hartmann ( Robert_Hartmann AT gmx DOT net)
// Version : alpha
// Copyright : Free and open source

// Description : SecurityUserInfo works in WinXP
// - why broken in Windows 8.1 ?

// g++ compile : g++ -DDEBUG -D_DEBUG -URELEASE -UNDEBUG -UUNICODE
-U_UNICODE -U_MBCS -O0 -g3 -Wall -Wextra -Wconversion -c
-fmessage-length=0 -o "SecurityUserInfo.o" SecurityUserInfo.cpp

// g++ link : g++ -static -o SecurityUserInfo.exe "SecurityUserInfo.o"

//
#if ( defined(UNICODE) && !defined(_UNICODE) ) || ( !defined(UNICODE) &&
defined(_UNICODE) )
#warning "UNICODE symbol definition is not complete"
#endif

#ifdef UNICODE
#ifndef _UNICODE
#define _UNICODE
#warning "...autodefine _UNICODE"
#endif
#endif

#ifdef _UNICODE
#ifndef UNICODE
#define UNICODE
#warning "...autodefine UNICODE"
#endif
#endif

#if ((defined(UNICODE) || defined(_UNICODE)) && defined(_MBCS))
#error "you cannot be in UNICODE and MBCS mode ... something is wrong"
#endif

#ifdef WINVER
#warning "...undefine WINVER"
#undef WINVER
#endif

#ifndef WINVER
#define WINVER 0x0400 //should run from Win95 and Win NT 4.0
#endif

#ifdef _WIN32_WINNT
#undef _WIN32_WINNT //ignore Windows NT/XP
//extensions in WinAPI header files
#endif

#ifdef _WIN32_WINDOWS
#undef _WIN32_WINDOWS //ignore Windows 95/98/ME
//extensions in WinAPI header files
#endif

#include<cstdlib>
#include<cerrno>
#include<cstdio>
#include<string>

//it is a windows thing:
//Multibyte character + string
#ifndef STRICT
#define STRICT //strengere WinAPI-Typ-Prüfung
#endif

#include<windows.h>
#include<winnt.h>
#include<winerror.h>


#ifndef NTSTATUS
typedef LONG NTSTATUS;
#endif

#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)

typedef struct _LSA_UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} SECURITY_STRING, *PSECURITY_STRING, LSA_UNICODE_STRING,
*PLSA_UNICODE_STRING,
UNICODE_STRING, *PUNICODE_STRING;

typedef struct _SECURITY_USER_DATA {
SECURITY_STRING UserName;
SECURITY_STRING LogonDomainName;
SECURITY_STRING LogonServer;
PSID pSid;
} SECURITY_USER_DATA, *PSECURITY_USER_DATA, SecurityUserData,
*PSecurityUserData;


HINSTANCE hInssecur = NULL;
NTSTATUS (NTAPI *pt2GetSecurityUserInfo)(PLUID, ULONG,
PSecurityUserData) = NULL;
NTSTATUS (WINAPI *pt2LsaFreeReturnBuffer)(PVOID) = NULL;


bool fileExists(const char* path ,const char* file)
{
std::string f = std::string(path).append("\\").append(file);
WIN32_FIND_DATA FindFileData;
HANDLE handle = ::FindFirstFileA(f.c_str(), &FindFileData) ;
bool found = (handle != INVALID_HANDLE_VALUE);
if(found)
{
::FindClose(handle);
}
return found;
}


int main() {

DWORD gle = 0L; //Win32-API error
NTSTATUS nterr = 0L; //NT-API error

::SetLastError(gle);
char * nativSystemDir = (char *) ::malloc(MAX_PATH);
if(NULL == nativSystemDir){
::perror("out of Memory");
::exit(1);
}
::ZeroMemory(nativSystemDir,MAX_PATH);

UINT length = 0;
length = ::GetSystemDirectoryA(nativSystemDir, MAX_PATH);
if (length == 0) {
gle = ::GetLastError();
}

char * secur = (char*) ::malloc(length + 1 + 12);
if(NULL == secur){
::perror("out of Memory");
::exit(1);
}
ZeroMemory(secur,length+13);
strncpy(secur, nativSystemDir, length);

if(fileExists(secur,"sspicli.dll")){

strcat(secur, "\\sspicli.dll");

} else{
OSVERSIONINFO os;
os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!::GetVersionEx(&os)) {
gle = ::GetLastError();
}

if ((os.dwPlatformId == VER_PLATFORM_WIN32_NT)
&& (os.dwMajorVersion <= 4)) {

strcat(secur, "\\security.dll");

} else{

strcat(secur, "\\secur32.dll");

}
}

hInssecur = LoadLibraryA(secur);
if (hInssecur) {

pt2LsaFreeReturnBuffer
= (NTSTATUS (WINAPI *)(PVOID))
GetProcAddress(hInssecur, "LsaFreeReturnBuffer");

pt2GetSecurityUserInfo
= (NTSTATUS(WINAPI *)(PLUID, ULONG, PSecurityUserData))
GetProcAddress(hInssecur, "GetSecurityUserInfo");
}

/**
* fills up UserInformation
*/
#ifndef UNDERSTANDS_LONG_NAMES
#define UNDERSTANDS_LONG_NAMES 1
#endif

#ifndef NO_LONG_NAMES
#define NO_LONG_NAMES 2
#endif


PSecurityUserData userdata = NULL;
ULONG flag = UNDERSTANDS_LONG_NAMES;


// crash in nextline: Win8.1 (64bit)
if (STATUS_SUCCESS != (nterr=pt2GetSecurityUserInfo(NULL, flag,
(PSecurityUserData) &userdata))){
gle = ::GetLastError();
} else {
if(userdata){
::printf("LogonDomain: %S",userdata->LogonDomainName.Buffer);
::printf("LogonName: %S", userdata->UserName.Buffer);
::printf("LogonServer: %S", userdata->LogonServer.Buffer);
pt2LsaFreeReturnBuffer(userdata);
userdata = NULL;
}
}

return 0;
}
 

Lesen sie die antworten

#1 Florian Weimer
20/02/2015 - 23:35 | Warnen spam
* Robert Hartmann:

Kann es sein das GetProcAdress unter Windows 8.1
einfach Pointer auf falsche Funktionen zurück liefert?



Bist Du Dir sicher, daß die Funktion unter Windows 8.1 noch denselben
Prototyp hat? Möglicherweise erwartet sie einfach andere Argumente
im Vergleich zu früheren Windows-Versionen.

Ähnliche fragen