Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > C/C++
You last visited: Today at 01:53

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



[c++] GetModuleHandle(NtDll) 64Bit

Discussion on [c++] GetModuleHandle(NtDll) 64Bit within the C/C++ forum part of the Coders Den category.

Reply
 
Old   #1
 
Mi4uric3's Avatar
 
elite*gold: 405
Join Date: Dec 2007
Posts: 6,615
Received Thanks: 6,358
[c++] GetModuleHandle(NtDll) 64Bit

Hey,
Ich hab ein Problem beim Beschaffen eines Modulehandles unter 64 Bit Systemen.
Ein 32Bit Prozess in einem 64Bit System lädt bei mir 2 verschiedene "NtDll.dll"s
()
Quote:
%WinDir%\SysWOW64\NtDll.dll
%WinDir%\System32\NtDll.dll
Wenn ich nun GetModuleHandle("NtDll.dll") nutze, bekomme ich das Handle zur SysWOW64\NtDll.dll.
Ich möchte aber die andere haben.

Dazu hab ich mich mal schlau gemacht, und folgendes gefunden ():
Quote:
Originally Posted by MSDN
If lpModuleName does not include a path and there is more than one loaded module with the same base name and extension, you cannot predict which module handle will be returned. To work around this problem, you could specify a path.
Hab ich probiert, und so versucht:
Code:
char WinDir[1024];
int Length = GetWindowsDirectory(WinDir, 1024);
String NtDll = AnsiString(WinDir) + "\\System32\\NtDll.dll";
char* t1 = AnsiString(NtDll).c_str();
HANDLE NtDllHandle = GetModuleHandle(t1);
Ich erhalte jedoch trotzdem das Handle zur SysWOW64\NtDll.dll.

Was mach ich falsch..?
Mi4uric3 is offline  
Old 08/02/2012, 14:12   #2
 
elite*gold: 0
Join Date: Jun 2012
Posts: 187
Received Thanks: 58
wenn du mit einem 32bit programm auf C:\Windows\System32\ zugreifst, landest du ohne was zu merken IMMER in SysWow64. Die ntdll in System32 wirst du NIEMALS in einem 32bit prozess finden - eine 64bit DLL kannst du nunmal nicht als solche in einen 32bit prozess mappen. Daher erhälst du auch, egal was du machst, das handle zur 32bit version (die nunmal unter SysWow64 liegt).

Edit: Also ja du findest sie zwar, sie ist gemapped aber jeder zugriff darauf endet in einer AV oder sogar GPF. D.h. sie ist zwar augenscheinlich da, aber weder der Prozess an sich noch ein externer Prozess können damit etwas anfangen, es sei denn man sucht nach alternativen ein Programm unsauber und schnell zu beenden.

Das ganze 64/32Gating/Node System hat auch noch weitere nebeneffekte. Wenn du zb. versuchst die ntdll aus System32 mit deinem Browser auf z.b. virusscan.jotti.org hochzuladen, lädt er die ntdll aus SysWow64 hoch - obwohl der Pfad eindeutig System32 sagt. Vorrausgesetzt du verwendest einen 32bit Browser wie Chrome und Firefox, glaube der internet explorer hat ne 64bit version, da würde er die korrekte Datei hochladen.
tnd0 is offline  
Thanks
1 User
Old 08/02/2012, 14:25   #3
 
elite*gold: 0
Join Date: Aug 2005
Posts: 443
Received Thanks: 72
noch weitere Informationen dazu.
neji is offline  
Thanks
1 User
Old 08/02/2012, 14:31   #4
 
elite*gold: 5
Join Date: Sep 2006
Posts: 385
Received Thanks: 218
Schau dir folgende Funktionen an, mit denen kannst du dir dein eigenes GetModuleHandle bauen:



Nightblizard is offline  
Thanks
1 User
Old 08/02/2012, 14:32   #5
 
Dr. Coxxy's Avatar
 
elite*gold: 0
Join Date: Feb 2011
Posts: 1,206
Received Thanks: 736
Quote:
Originally Posted by neji View Post
noch weitere Informationen dazu.
was hat das denn jetzt damit zu tun?

@thread:
das hier könnte gehen:
Quote:
As a walk-around solution, 32-bit applications can access the native system directory by substituting %windir%\Sysnative for %windir%\System32. WOW64 recognizes Sysnative as a special alias used to indicate that the file system should not redirect the access.

So, if we want to access C:\Windows\System32\Winevt folder from 32-bit application, we can use C:\Windows\Sysnative\Winevt instead.
Edit:
wofür brauchst du überhaupt das 64 bit ntdll handle?
Dr. Coxxy is offline  
Thanks
1 User
Old 08/02/2012, 14:35   #6
 
Mi4uric3's Avatar
 
elite*gold: 405
Join Date: Dec 2007
Posts: 6,615
Received Thanks: 6,358
Quote:
Originally Posted by tnd0 View Post
wenn du mit einem 32bit programm auf C:\Windows\System32\ zugreifst, landest du ohne was zu merken IMMER in SysWow64. Die ntdll in System32 wirst du NIEMALS in einem 32bit prozess finden - eine 64bit DLL kannst du nunmal nicht als solche in einen 32bit prozess mappen. Daher erhälst du auch, egal was du machst, das handle zur 32bit version (die nunmal unter SysWow64 liegt).

Das ganze 64/32Gating/Node System hat auch noch weitere nebeneffekte. Wenn du zb. versuchst die ntdll aus System32 mit deinem Browser auf z.b. virusscan.jotti.org hochzuladen, lädt er die ntdll aus SysWow64 hoch - obwohl der Pfad eindeutig System32 sagt. Vorrausgesetzt du verwendest einen 32bit Browser wie Chrome und Firefox, glaube der internet explorer hat ne 64bit version, da würde er die korrekte Datei hochladen.
Danke für die Information!

Das ist ja fies..
Das komische ist aber trotzdem, dass die 64Bit Datei ja im Memory geladen ist (siehe Screenshot)..

Quote:
Originally Posted by Dr. Coxxy View Post
%windir%\Sysnative
Ausprobiert, kommt leider auch das falsche Handle raus.. :/
Mi4uric3 is offline  
Old 08/02/2012, 14:43   #7
 
Dr. Coxxy's Avatar
 
elite*gold: 0
Join Date: Feb 2011
Posts: 1,206
Received Thanks: 736
dann bleibt dir wohl wirklich nur noch nightblizzards methode und du baust dir selber ein getmodulehandle, ist nicht viel arbeit.

wofür brauchst du denn überhaupt die 64bit ntdll version in nem 32 bit prozess?
wie tnd0 schon korrigiert hat, wird das sehr wahrscheinlich in murks enden wenn du da versuchst i-was draus zu benutzen/zuzugreifen.
Dr. Coxxy is offline  
Old 08/02/2012, 14:47   #8
 
Mi4uric3's Avatar
 
elite*gold: 405
Join Date: Dec 2007
Posts: 6,615
Received Thanks: 6,358
Quote:
Originally Posted by tnd0 View Post
D.h. sie ist zwar augenscheinlich da, aber weder der Prozess an sich noch ein externer Prozess können damit etwas anfangen, es sei denn man sucht nach alternativen ein Programm unsauber und schnell zu beenden.
Also mit Cheat Engine (64 Bit) habe ich Zugriff darauf & kann auch darin Opcodes ändern.. Das versuche ich halt auch mit dem Prozess selbst, dass er halt selbst darin was verändert, so wie Cheat Engine es extern macht..
Mi4uric3 is offline  
Old 08/02/2012, 14:49   #9
 
Dr. Coxxy's Avatar
 
elite*gold: 0
Join Date: Feb 2011
Posts: 1,206
Received Thanks: 736
aber die 32 bit applikation wird die 64 bit version von der ntdll nie (direkt) benutzen, wieso modifizierst du nicht einfach die 32bit ntdll?
Dr. Coxxy is offline  
Old 08/02/2012, 15:41   #10
 
Mi4uric3's Avatar
 
elite*gold: 405
Join Date: Dec 2007
Posts: 6,615
Received Thanks: 6,358
Quote:
Originally Posted by Dr. Coxxy View Post
aber die 32 bit applikation wird die 64 bit version von der ntdll nie benutzen, wieso modifizierst du nicht einfach die 32bit ntdll?
Tu ich, hat leider nicht den gewünschten Effekt.
Wenn ich es mit Cheat Engine mache, also die System32\Ntdll.dll modifiziere tritt der gewünschte Effekt auf.


Ich hab die Methode von Nightblizard ausprobiert, der überspringt die im enthaltenen
Quote:
wow64.dll
wow64win.dll
wow64cpu.dll
ntdll.dll
einfach. :/
Mensch das kann doch nicht so schwer sein, die DLL ist doch im Memory -.-
Mi4uric3 is offline  
Old 08/02/2012, 16:07   #11
 
elite*gold: 0
Join Date: Jun 2012
Posts: 187
Received Thanks: 58
Code:
program moduletest;

uses
 SysUtils, Windows;

type
 TModuleEntry = record
   Name:        string;
   Path:        string;
   BaseSize:    integer;
   BaseAddress: integer;
   handle:      THandle;
   accessible:  boolean;
 end;

var
 ModuleList: array of TModuleEntry;

function ExtractProcessInformation(const MTarget: Integer): Boolean;
var
 Handle: THandle; // aka NativeUInt
 me32:   tagMODULEENTRY32; // aka winbase._tagMODULEENTRY32;
begin
 try
  result := false;
  Handle := CreateToolhelp32Snapshot(TH32CS_SNAPALL, MTarget);
  if not ( Handle > 0 ) then
   Exit;
  me32.dwSize := SizeOf(tagmoduleentry32);
  if not Module32First(Handle, me32) then
   Exit;

  SetLength(ModuleList, 0);
  repeat
   SetLength(ModuleList, Length(ModuleList)+1);
   ModuleList[High(ModuleList)].Name := me32.szModule;
   ModuleList[High(ModuleList)].BaseSize := me32.modBaseSize;
   ModuleList[High(ModuleList)].BaseAddress := Integer(me32.modBaseAddr);
   ModuleList[High(ModuleList)].handle := me32.hModule;
   ModuleList[High(ModuleList)].accessible := me32.hModule <> 0;
  until not Module32Next(Handle, me32);
  Result := true;
  if GetLastError = 18 then SetLastError(0); // 18 = No More Data 
 finally
  CloseHandle(Handle);
 end;
end;

begin
 if ParamCount = 2 then
  ExtractProcessInformation(IntToStr(ParamStr(1))) 
 else
  WriteLn('Usage: program.exe PID');
end.

Damit Liste ich mir alle Module eines Prozesses auf - und hab gleich auf jedes Modul ein Handle. Jetzt kannst du z.b. mittels der BaseSize oder der BaseAdress differenzieren, welches die richtige ntdll ist. Die 64Bit ntdll wird immer eine größere BaseSize haben als das 32bit äquivalent.

Musst das ganze nurnoch nach C++ oder whatever du benutzt übersetzen.
tnd0 is offline  
Old 08/02/2012, 16:10   #12
 
elite*gold: 0
Join Date: Aug 2005
Posts: 443
Received Thanks: 72
Quote:
Originally Posted by Dr. Coxxy View Post
was hat das denn jetzt damit zu tun?
Hättest du den ganzen Text gelesen, dann wüsstest du es.
Während man zwischen 32 und 16 bit noch auf die jeweils anderen dll's zugreifen konnte (weil die Größe der Pointer die gleiche war), geht das zwischen 32 und 64 bit nicht mehr. Das Ändern einer 32-Bit Struktur in eine 64-Bit Struktur ändert hier auch dessen Größe. Viele Adressen von Funktionen von 64 Bit dll's können im 32 Bit raum nicht gefunden werden, weil es da schlicht einen Integerüberlauf gibt (der Adressraum von 64 Bit ist 4 Milliarden mal größer, als bei 32 Bit).

Windows hat die Filterung nicht ohne Grund in seine Apis eingebaut. Selbst wenn du also die 64 Bit DLL laden kannst, dann wirst du trotzdem Probleme haben, Funktionen darin aufzurufen (oder auch nur zu adressieren)
neji is offline  
Old 08/02/2012, 16:15   #13
 
Mi4uric3's Avatar
 
elite*gold: 405
Join Date: Dec 2007
Posts: 6,615
Received Thanks: 6,358
Code:
HMODULE NtDll32;
HMODULE NtDll64;

void GetModuleHandles() {
 	char WinDir[1024];
	int Length = GetWindowsDirectory(WinDir, 1024);
	char* t1 = AnsiString(AnsiString(WinDir) + "\\system32\\ntdll.dll").c_str();
	char* t2 = AnsiString(AnsiString(WinDir) + "\\SysWOW64\\ntdll.dll").c_str();

	MODULEENTRY32 ModuleEntry;
	ModuleEntry.dwSize = sizeof(MODULEENTRY32);

	HANDLE Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);
	if (Snapshot == 0) Debugger::Hacking++;
	Module32First(Snapshot, &ModuleEntry);
	do {
		if (strcmp(ModuleEntry.szExePath, t1) == 0) {
			NtDll32 = ModuleEntry.hModule;
		}
		else if (strcmp(ModuleEntry.szExePath, t2) == 0) {
			NtDll64 = ModuleEntry.hModule;
		}
	} while (Module32Next(Snapshot, &ModuleEntry));
}
Quote:
int strcmp (const char *s1, const char *s)
liefert: 0 wenn s1 gleich s2
NtDll32 (System32) enthält danach das Handle von der SysWow64
Waaas ist falsch, ich raffs nicht.

Quote:
Originally Posted by neji View Post
Hättest du den ganzen Text gelesen, dann wüsstest du es.
Während man zwischen 32 und 16 bit noch auf die jeweils anderen dll's zugreifen konnte (weil die Größe der Pointer die gleiche war), geht das zwischen 32 und 64 bit nicht mehr. Das Ändern einer 32-Bit Struktur in eine 64-Bit Struktur ändert hier auch dessen Größe. Viele Adressen von Funktionen von 64 Bit dll's können im 32 Bit raum nicht gefunden werden, weil es da schlicht einen Integerüberlauf gibt (der Adressraum von 64 Bit ist 4 Milliarden mal größer, als bei 32 Bit).

Windows hat die Filterung nicht ohne Grund in seine Apis eingebaut. Selbst wenn du also die 64 Bit DLL laden kannst, dann wirst du trotzdem Probleme haben, Funktionen darin aufzurufen (oder auch nur zu adressieren)
Wie auf dem Screenshot erkennbar befindet sich das Modul jedoch bei 0x772E0000, was im 32Bit Bereich liegt.
Ich will nichts aufrufen, ich will nur ein paar Bytes ändern, was ja möglich sein sollte, da es sich halt im 32Bit Bereich befindet.
Mi4uric3 is offline  
Old 08/02/2012, 16:24   #14
 
elite*gold: 0
Join Date: Aug 2005
Posts: 443
Received Thanks: 72
Hast du schon versucht, durch einen Api Hook auf IsWow64Process() Windows davon zu überzeugen, dass du wirklich ein 32-Bit Prozess bist?
neji is offline  
Old 08/02/2012, 17:34   #15
 
elite*gold: 0
Join Date: Jun 2012
Posts: 187
Received Thanks: 58
Code:
#include <windows.h>
#include <psapi.h>
#pragma comment(lib, "psapi.lib")
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>


// For the following function see:
//http://msdn.microsoft.com/library/en-us/fileio/fs/obtaining_a_file_name_from_a_file_handle.asp
#define BUFSIZE 512
BOOL DisplayRealFileName(LPCTSTR szFileName)
{
   HANDLE hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ | 
FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL);
   if (hFile == INVALID_HANDLE_VALUE)
     return FALSE;

   BOOL bSuccess = FALSE;
   TCHAR pszFilename[MAX_PATH+1];
   HANDLE hFileMap;

   // Get the file size.
   DWORD dwFileSizeHi = 0;
   DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi);

   if( dwFileSizeLo == 0 && dwFileSizeHi == 0 )
   {
      _tprintf(_T("Cannot map a file with a length of zero.\n"));
      CloseHandle(hFile);
      return FALSE;
   }

   // Create a file mapping object.
   hFileMap = CreateFileMapping(hFile,
                     NULL,
                     PAGE_READONLY,
                     0,
                     1,
                     NULL);

   if (hFileMap)
   {
     // Create a file mapping to get the file name.
     void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);

     if (pMem)
     {
       if (GetMappedFileName (GetCurrentProcess(),
                              pMem,
                              pszFilename,
                              MAX_PATH))
       {

         // Translate path with device name to drive letters.
         TCHAR szTemp[BUFSIZE];
         szTemp[0] = '\0';

         if (GetLogicalDriveStrings(BUFSIZE-1, szTemp))
         {
           TCHAR szName[MAX_PATH];
           TCHAR szDrive[3] = TEXT(" :");
           BOOL bFound = FALSE;
           TCHAR* p = szTemp;

           do
           {
             // Copy the drive letter to the template string
             *szDrive = *p;

             // Look up each device name
             if (QueryDosDevice(szDrive, szName, BUFSIZE))
             {
               size_t uNameLen = _tcslen(szName);

               if (uNameLen < MAX_PATH)
               {
                 bFound = _tcsnicmp(pszFilename, szName,
                     uNameLen) == 0;

                 if (bFound)
                 {
                   // Reconstruct pszFilename using szTemp
                   // Replace device path with DOS path
                   TCHAR szTempFile[MAX_PATH];
                   _stprintf_s(szTempFile,
                             TEXT("%s%s"),
                             szDrive,
                             pszFilename+uNameLen);
                   _tcsncpy_s(pszFilename, szTempFile, MAX_PATH);
                 }
               }
             }

             // Go to the next NULL character.
             while (*p++);
           } while (!bFound && *p); // end of string
         }
       }
       bSuccess = TRUE;
       UnmapViewOfFile(pMem);
     }

     CloseHandle(hFileMap);
   }
   _tprintf(_T("File name is %s\n"), pszFilename);
   CloseHandle(hFile);
   return(bSuccess);
}



void PrintModules( DWORD processID )
{
   HMODULE hMods[1024];
   HANDLE hProcess;
   DWORD cbNeeded;
   unsigned int i;

   _tprintf( _T("\nProcess ID: %u\n"), processID );
   hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |PROCESS_VM_READ, 
FALSE, processID);
   if (NULL == hProcess)
     return;
   if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
   {
     for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
     {
       TCHAR szModName[MAX_PATH];
       if ( GetModuleFileNameEx( hProcess, hMods[i], szModName, 
sizeof(szModName)))
       {
         _tprintf(_T("\t%s (0x%p)\n"), szModName, hMods[i] );
         DisplayRealFileName(szModName);
       }
     }
   }
   CloseHandle( hProcess );
}


int _tmain(int argc, _TCHAR* argv[])
{
   int pprocessID = GetCurrentProcessId();
   if (argc > 1)
     pprocessID = _tstol(argv[1]);

   PrintModules(pprocessID);

   _tprintf(_T("Press any key to continue..."));
   _getch();
	return 0;
}
Das hab ich irgendwo in meiner SDK lib gefunden. Das sollte es tun, habs jedoch nicht ausprobiert, da grade kein compiler zur hand.
tnd0 is offline  
Thanks
1 User
Reply


Similar Threads Similar Threads
Ollydbg / return to ntdll
05/08/2012 - General Coding - 9 Replies
Ahoi. Everytime I'm debugging the process terminates.. For now I see: process terminated, exit code 1.. And it bounces me to: RETURN TO ntdll. Using Ollydbg 1.10 on Win7x64 2 alpha whatever doesnt work too.. Any ideas? http://www.abload.de/img/unbenanntspcn9.png
Ntdll.dll Problem
02/25/2012 - Allods - 2 Replies
So dann frage ich mal hier da die GMs aus dem dt. Allods -Forum anscheinend zu inkompetent für dieses Thema sind. Jedes mal wenn ich allods starten will ernscheint mal kurz der Launcher dieser stürzt dann sofort ab und es kommt diese Fehlermeldung Allods Online. Update system. funktioniert nicht mehr Problemsignatur: Problemereignisname: APPCRASH Anwendungsname: Launcher.exe_Allods Online EU DE Anwendungsversion: 3.0.0.50
WorldServer-Error ntdll.dll
08/14/2011 - Flyff Private Server - 5 Replies
#Removed
[Request] NTDLL SDK?
08/14/2011 - General Coding - 2 Replies
Hi members, I need urgently SDK of NTDLL (if exists) because when i compile a cpp file with #include <nt/ntdll.h> I got some errors about ntos, anyone have SDK of NTDLL? Thank you ;)
ntdll
10/02/2010 - General Coding - 8 Replies
Hat, weis, kennt wer die Funktionen der ntdll ?? Alles was ich gefunden habe ist das: :: The Undocumented Functions by NTinternals :: Aber das reicht mir nicht. Ich möchte auch eine Beschreibung der Funktionen da ich nicht alle kenne...



All times are GMT +1. The time now is 01:55.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.