google-site-verification: googlebaca44933768a824.html Enumerating x64 processes from x86 process - Old Royal Hack Forum

Announcement

Collapse
No announcement yet.

Enumerating x64 processes from x86 process

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Enumerating x64 processes from x86 process

    Hi, after changing from x86 Windows 7 to x64 Windows 7 my overlay stopped working. After some examining I noticed the issue is the way I'm enumerating processes. It works for x86 processes which are my maintarget anyway ( games ) but for the sake of perfectness I would like it to work with x64 procs too. GetModuleBaseName call seems to result garbage if my target is x64 process, what is the proper way to solve this, all the topics I found of this just recommended using CreateToolHelp32Snapshot but is it seriously only way?

    Code:
    void CProcess::GetProcNameID( DWORD_PTR dwPID )
    {
    	CHAR szProcessName[MAX_PATH];
    	HANDLE hProcess = /*g_pFramework->pApiCall()->Nt*/OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE, dwPID );
    		
    	if( hProcess == NULL )
    		return;
    
    	HMODULE hMod;
    	DWORD_PTR dwNeeded;
    
    	if ( g_pFramework->pApiCall()->EnumProcessModulesEx( hProcess, &hMod, sizeof(hMod), &dwNeeded, 0x03/*LIST_MODULES_ALL*/ )) // x86 and x64
    		g_pFramework->pApiCall()->GetModuleBaseName( hProcess, hMod, szProcessName, sizeof( szProcessName )/sizeof( CHAR ) );
    
    	ProcessInfo ProcInfo;
    		
    	ProcInfo.dwPID			= dwPID;
    	ProcInfo.hProc			= hProcess;
    	ProcInfo._ProcessName.append( szProcessName ); 
    		
    	m_vecGlobalProcInfo.push_back( ProcInfo );
    		
    	g_pFramework->pApiCall()->CloseHandle( hProcess );
    }
    	
    BOOL CProcess::FindProc()
    {
    	//if( m_vecTargetProcInfo.size() > 0 )
    	//	return TRUE;
    
    	DWORD_PTR dwProcCount[1024], dwNeeded, dwProcesses;
    				
    	if( !g_pFramework->pApiCall()->EnumProcesses( dwProcCount, sizeof( dwProcCount ), &dwNeeded ) )
    		return FALSE;
    
    	dwProcesses = dwNeeded / sizeof( DWORD_PTR );
    					
    	for( UINT uiCount = 0; uiCount < dwProcesses; uiCount++ )
    	{
    		if( dwProcCount[uiCount] == 0 )
    			continue;
    
    		GetProcNameID( dwProcCount[uiCount] );
    	}
    		
    	for( size_t vecSize = 0; vecSize < m_vecGlobalProcInfo.size(); vecSize++ )
    	{
    		if( !m_vecGlobalProcInfo[vecSize]._ProcessName.find( g_pFramework->pCVarManager()->GetCVarString( "processname" ) ) )
    		{
    			static ProcessInfo ProcInfo; // memorayzleak fix
    				
    			ProcInfo.dwPID			 = m_vecGlobalProcInfo[vecSize].dwPID;
    			ProcInfo.hProc			 = m_vecGlobalProcInfo[vecSize].hProc;
    			ProcInfo._ProcessName	 = m_vecGlobalProcInfo[vecSize]._ProcessName;
    				
    			m_vecGlobalProcInfo.clear();
    			m_vecTargetProcInfo.push_back( ProcInfo );
    								
    			return TRUE;
    		}
    	}
    		
    	return FALSE;
    }
    lolmaoman: Germans are born with a lifetime x22 login engraved into their birth certificates. True story.
    I DONT HAVE TEAMVIEWER AND IM NOT GOING TO GIVE ANY 24/7 ONLINE SUPPORT VIA STEAM, XFIRE OR OTHER IM PROGRAMS SO DONT BOTHER ASKING. THANKS.

    #2
    Re: Enumerating x64 processes from x86 process

    Code:
      MCV(BOOL) _FindProcess( dword ulCrc, PULONG pProcessIds )
      {
        using namespace windows_api;
    
        if( !ulCrc || !pProcessIds  || !_ZwQuerySystemInformation )
        {
          return FALSE;
        }
    
        // retlen / sizeof(SYSTEM_PROCESS_INFORMATION) = running process count 32 & 64
        dword retlen = 0;
        dword    len = 4096 * sizeof(SYSTEM_PROCESS_INFORMATION);
    
        // When the SystemInformationClass parameter is SystemProcessInformation,
        // the buffer pointed to by the SystemInformation parameter should be large enough
        // to hold an array that contains as many SYSTEM_PROCESS_INFORMATION structures
        // as there are processes running in the system.
        std::vector<byte> psList(len);
        if( !NT_SUCCESS(_ZwQuerySystemInformation(SystemProcessInformation,psList.begin(),len,&retlen)) )
        {
          goto fail_cleanup;
        }
        else
        {
          if( !retlen )
          {
            goto fail_cleanup;
          }
        }
    
        PSYSTEM_PROCESS_INFORMATION m_pInfo = (PSYSTEM_PROCESS_INFORMATION)psList.begin();
        uint32                process_count = retlen / sizeof(SYSTEM_PROCESS_INFORMATION);
        if( !process_count )
        {
          return FALSE;
        }
    
        dspeak("%i process running,",process_count );
    
        typedef PSYSTEM_PROCESS_INFORMATION pspi;
    
    #define cii( pOffs )                          \
      ( pOffs                                     \
      && (DWORD_PTR(pOffs) >= DWORD_PTR(m_pInfo)) \
      && (DWORD_PTR(pOffs)  < DWORD_PTR(m_pInfo) + retlen) )
    
        for( pspi pEntry = m_pInfo; cii(pEntry);
          pEntry = (pspi)((DWORD_PTR)pEntry + pEntry->NextEntryOffset) )
        {
          if( !pEntry )
          {
            dspeak("( !pEntry )");
            goto fail_cleanup;
          }
    
          PUNICODE_STRING exe = &pEntry->ImageName;
          if( !exe )
          {
            goto fail_cleanup;
          }
    
          pwchar szexe = exe->Buffer;
          if( !szexe )
          {
            continue; // sys (null)
          }
    
          char ansii[1024];
          if( 0 == tools::_sprintf(ansii,"%ws",szexe) )
          {
            goto fail_cleanup;
          }
          
          dword crc32;
          if ( tools::chksum_crc32s(ansii,&crc32) == FALSE )
          {
            goto fail_cleanup;
          }
    
          if ( crc32 && ulCrc && ulCrc == crc32 )
          {
            (*pProcessIds) = 0;
            (*pProcessIds) = (dword)pEntry->UniqueProcessId;
    
            encrypt_speak("found: %s,",txt,ansii );
            goto done_cleanup;
          }
    
          if( !pEntry->NextEntryOffset )
          {
            goto fail_cleanup;
          }
        }
    
    fail_cleanup:
        if( pProcessIds )
        {
          (*pProcessIds) = 0;
        }
        return FALSE;
    
    done_cleanup:
        if( (*pProcessIds) == 0 )
        {
          encrypt_speak("( !(*pProcessIds) )",err);
          goto fail_cleanup;
        }
        return TRUE;
      }
    :D






    gibs coins @
    1KatP9B8KG7mvcoFhdLGua1isG88nYZE8C

    Comment


      #3
      Re: Enumerating x64 processes from x86 process

      Originally posted by νзηοма View Post
      Code:
       cake.
      :D
      Thanks a lot, I try the NTAPI approach for this and post when I'm done!
      lolmaoman: Germans are born with a lifetime x22 login engraved into their birth certificates. True story.
      I DONT HAVE TEAMVIEWER AND IM NOT GOING TO GIVE ANY 24/7 ONLINE SUPPORT VIA STEAM, XFIRE OR OTHER IM PROGRAMS SO DONT BOTHER ASKING. THANKS.

      Comment


        #4
        Re: Enumerating x64 processes from x86 process

        Man, these anti memory leak techniques, TEACH ME MENC9RE.

        (gj)

        Comment


          #5
          Re: Enumerating x64 processes from x86 process

          Originally posted by badsta View Post
          Man, these anti memory leak techniques, TEACH ME MENC9RE.

          (gj)
          I can't, you are lost case man. :x
          lolmaoman: Germans are born with a lifetime x22 login engraved into their birth certificates. True story.
          I DONT HAVE TEAMVIEWER AND IM NOT GOING TO GIVE ANY 24/7 ONLINE SUPPORT VIA STEAM, XFIRE OR OTHER IM PROGRAMS SO DONT BOTHER ASKING. THANKS.

          Comment


            #6
            Re: Enumerating x64 processes from x86 process

            Originally posted by mencore View Post
            Thanks a lot, I try the NTAPI approach for this and post when I'm done!
            Oops forgot this.

            Code:
            BOOL CProcess::FindProc2() // credits evil0r & v3n0m4
            	{
            		LPVOID lpBuffer;
            		ULONG dwBufLen = 0x8000;
            		PSYSTEM_PROCESSES pProcs;
            		NTSTATUS ntStat = NULL;
            		
            		do
            		{
            			// allocate memory for lpBuffer with dwBufLen
            			lpBuffer = malloc( dwBufLen );
            			// try to fill buffer with systemprocesses and thread information struct
            			ntStat = (NTSTATUS)g_pFramework->pApiCall()->QuerySystemInformation( (SYSTEM_INFORMATION_CLASS)SystemProcessesAndThreadsInformation, lpBuffer, dwBufLen, NULL );
            
            			// too small cock.... err buffer
            			if( ntStat == STATUS_INFO_LENGTH_MISMATCH ) 
            			{
            				free( lpBuffer );	// clean up
            				dwBufLen *= 2;		// double the fun
            			}
            			else if( !NT_SUCCESS( ntStat ) )  // raged
            			{
            				free( lpBuffer );
            				return FALSE;
            			}
            		}while( ntStat == STATUS_INFO_LENGTH_MISMATCH );
            				
            		pProcs = (PSYSTEM_PROCESSES)lpBuffer; // fill PSYSTEM_PROCESSES with our buffer
            		
            		//g_pFramework->pLogger()->//Spew( "FindProc called, looping through processes" );
            
            		while( TRUE )
            		{
            			g_pFramework->pApiCall()->Sleep( 10 );
            			
            			char szFound[512], szTarget[512];
            			 // target process name from settings.ini
            			sprintf_s( szTarget, "%ws", s2wchar2( g_pFramework->pGetWindowCVar()->GetCVarString( /*processname*/XorStr<0xB2,12,0x25044B2A>("\xC2\xC1\xDB\xD6\xD3\xC4\xCB\xD7\xDB\xD6\xD9"+0x25044B2A).s ) ) );			
            			// I just hate this WCHAR bullshit from the bottom of my heart
            			sprintf_s( szFound, "%ws", pProcs->ProcessName.Buffer );
            
            			//g_pFramework->pLogger()->//Spew( szFound );
            
            			if( strcmp( szFound, szTarget ) == 0 ) // bing0, ring-ding-ding
            			{
            				HANDLE hTargetProc = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE, pProcs->ProcessId );
            		
            				if( hTargetProc )
            				{
            					ProcessInfo *ProcInfo = new ProcessInfo;
            				
            					ProcInfo->dwPID			= pProcs->ProcessId;
            					ProcInfo->hProc			= hTargetProc;
            					ProcInfo->_ProcessName	= std::string( szFound );
            					
            					m_vecTargetProcInfo.push_back( ProcInfo );
            
            					//g_pFramework->pLogger()->//Spew( "Found:" + ProcInfo->_ProcessName );
            					//g_pFramework->pLogger()->//Spew( _OUT_NUMR_, "PID:", ProcInfo->dwPID );
            					// TODO: this should be on it's own function
            
            					HMODULE hModules[1024];
            					DWORD_PTR dwNeeded;
            						
            					BOOL EnumMods = g_pFramework->pApiCall()->EnumProcessModules( hTargetProc, hModules, sizeof( hModules ), &dwNeeded );
            					
            					if( EnumMods )
            					{
            						//g_pFramework->pLogger()->//Spew( "looping through modules..." );
            
            						for( int i = 0; i < ( dwNeeded / sizeof( HMODULE ) ); i++ )
            						{
            							CHAR szModuleName[MAX_PATH];
            							CHAR szModulePath[MAX_PATH];
            
            							if( g_pFramework->pApiCall()->GetModuleBaseName( hTargetProc, hModules[i], szModuleName, sizeof( szModuleName ) / sizeof( CHAR ) ) )
            							{
            								//MessageBox( NULL, szModuleName, NULL, NULL );
            								MODULEINFO modInfo;
            								
            								if( g_pFramework->pApiCall()->GetModuleInformation( hTargetProc, hModules[i], &modInfo, sizeof( modInfo ) ) )
            								{
            								//	if( g_pFramework->pApiCall()->GetModuleFileName( hModules[i], szModulePath, sizeof( szModulePath ) / sizeof( CHAR ) ) )
            								//	{
            									//MessageBox( NULL, szModuleName, NULL, NULL );
            
            									ModuleInfo *pModuleInfo = new ModuleInfo;
            									
            									pModuleInfo->hModuleHandle = (HMODULE)hModules[i];
            									pModuleInfo->dwBase = (DWORD_PTR)modInfo.lpBaseOfDll;
            									pModuleInfo->dwSize = (DWORD_PTR)modInfo.SizeOfImage;
            									pModuleInfo->_ModuleName = szModuleName;
            									//pModuleInfo->_ModulePath = szModulePath;
            									
            
            									//MessageBox( NULL, szModulePath, NULL, MB_OK );
            									
            									m_vecModuleInfo.push_back( pModuleInfo );
            								//	}
            									//g_pFramework->pLogger()->//Spew( _OUT_HEXA_, pModuleInfo->_ModuleName + " @", pModuleInfo->dwBase );
            								}
            							}
            						}
            					}
            					g_pFramework->pApiCall()->EmptyWorkingSet( ::GetCurrentProcess()/*hTargetProc*/ ); // free some memorayz :P
            					//g_pFramework->pApiCall()->CloseHandle( hTargetProc ); // LOL, this was a funny mistake to make, I just leave it here so I can feel ashamed of it.
            
            					return TRUE;
            				}
            				return FALSE; // why u mad tho
            			}
            		
            			if( pProcs->NextEntryDelta == NULL ) // end of list
            				break;
            			
            			pProcs = (PSYSTEM_PROCESSES)( (DWORD_PTR)pProcs + pProcs->NextEntryDelta ); // loooooop
            		}
            
            		return FALSE;
            	}
            and then I get the shiznit from my vectors with functions like this, you get the drill:

            Code:
            DWORD_PTR CProcess::GetModuleBase( const std::string &_module )
            	{
            		static DWORD_PTR dwRet;
            				
            		if( m_vecModuleInfo.size() == 0 )
            			return NULL;
            					
            		for( size_t i = 0; i < m_vecModuleInfo.size(); ++i )
            		{
            			if( m_vecModuleInfo[i]->_ModuleName.compare( _module ) == 0 )
            			{
            				dwRet = m_vecModuleInfo[i]->dwBase;
            				break;
            			}
            		}
            
            		return dwRet;
            	}
            lolmaoman: Germans are born with a lifetime x22 login engraved into their birth certificates. True story.
            I DONT HAVE TEAMVIEWER AND IM NOT GOING TO GIVE ANY 24/7 ONLINE SUPPORT VIA STEAM, XFIRE OR OTHER IM PROGRAMS SO DONT BOTHER ASKING. THANKS.

            Comment


              #7
              Re: Enumerating x64 processes from x86 process

              Code:
              dwSizeRequired = SBI.PhysicalPageSize;
              
              do
              {
              	pbBuffer = ( PBYTE )NtAllocateMemory ( 0, dwSizeRequired, PAGE_READWRITE );
              				
              	if ( pbBuffer == NULL )
              	{		
              		return 0;
              	}
              		
              	status = NtQuerySystemInformation ( SystemProcessInformation, pbBuffer, dwSizeRequired, &dwSizeRequired );
              
              	dwSizeRequired += SBI.PhysicalPageSize;
              
              	if ( NT_ERROR ( status ) )
              	{
              		if ( !NtFreeMemory ( ( DWORD )pbBuffer, 0, MEM_RELEASE ) )
              		{
              			return 0;
              		}
              	}
              	else if ( NT_SUCCESS ( status ) )
              	{
              		break;
              	}
              
              }while ( 1 );
              		
              if ( NT_SUCCESS ( status ) )
              {
              	PSPI = ( PSYSTEM_PROCESS_INFORMATION )pbBuffer;
              
              	do
              	{
              		CID.UniqueProcess = ( DWORD )PSPI->ProcessId;
              		CID.UniqueThread = 0;
              
              		bInheritHandle = FALSE;
              
              		InitializeObjectAttributes ( &ObjectAttributes, NULL, ( bInheritHandle ? OBJ_INHERIT : 0 ), NULL, NULL );
              
              		status = NtOpenProcess ( &hProcessHandle, PROCESS_ALL_ACCESS, &ObjectAttributes, &CID );
              
              		if ( NT_SUCCESS ( status ) )
              		{
              			status = NtQueryInformationProcess ( hProcessHandle, ProcessWow64Information, &dwTEB, sizeof ( DWORD ), &dwLength );
              
              			if ( NT_SUCCESS ( status ) && dwTEB == 0 ) // not WOW64
              			{
              				// check if this process matches what we're looking for
              			}
              		}
              		else
              		{
              			// Try to adjust privledges, then repeat
              		}
              				
              		PSPI = ( PSYSTEM_PROCESS_INFORMATION )( ( DWORD )PSPI + PSPI->NextEntryDelta );
              
              	}while ( PSPI->NextEntryDelta != 0  );
              }
              
              if ( NtFreeMemory ( ( DWORD )pbBuffer, 0, MEM_RELEASE ) != 1 )
              {
              	return 0;
              }
              As far as modules go, just read the PEB loader block lists and that'll list the loaded modules. You can check all 4 loader module lists for validity that by doing a walking NtQueryVirtualMemory to check the regions and section names.
              Last edited by wav; 01-03-2013, 06:11 PM.

              Comment


                #8
                Re: Enumerating x64 processes from x86 process

                Originally posted by wav View Post
                Code:
                mucho codens
                As far as modules go, just read the PEB loader block lists and that'll list the loaded modules. You can check all 4 loader module lists for validity that by doing a walking NtQueryVirtualMemory to check the regions and section names.
                Good shit, 10 times less code than mine and more than likely does not leak memory either
                lolmaoman: Germans are born with a lifetime x22 login engraved into their birth certificates. True story.
                I DONT HAVE TEAMVIEWER AND IM NOT GOING TO GIVE ANY 24/7 ONLINE SUPPORT VIA STEAM, XFIRE OR OTHER IM PROGRAMS SO DONT BOTHER ASKING. THANKS.

                Comment


                  #9
                  Re: Enumerating x64 processes from x86 process

                  Originally posted by mencore View Post
                  Good shit, 10 times less code than mine and more than likely does not leak memory either
                  Doesn't leak memory period. MEM_RELEASE assures that the entire allocated region will be removed.

                  Comment


                    #10
                    Re: Enumerating x64 processes from x86 process

                    Originally posted by wav View Post
                    Code:
                    do
                    {
                    // very gay loop because i didnt read msdn
                    }while ( 1 );
                    Code:
                    	Status = NtQuerySystemInformation( SystemProcessInformation, NULL, NULL, &InformationLength );
                    
                    	if( Status == STATUS_INFO_LENGTH_MISMATCH )
                    	{
                    		InformationBuffer = RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, NULL, InformationLength );
                    
                    		Status = NtQuerySystemInformation( SystemProcessInformation, InformationBuffer, InformationLength, NULL );
                    
                    		if( NT_SUCCESS( Status ) )
                    		{
                    			ProcessInformation = ( PSYSTEM_PROCESS_INFORMATION )InformationBuffer;
                    		}
                    		else
                    		{
                    			RtlFreeHeap( NtCurrentPeb()->ProcessHeap, NULL, InformationBuffer );
                    
                    			return NULL;
                    		}
                    	}
                    	else
                    	{
                    		return NULL;
                    	}
                    Last edited by extern4ever; 01-09-2013, 12:25 PM.

                    Comment


                      #11
                      Re: Enumerating x64 processes from x86 process

                      Originally posted by extern4ever View Post
                      Code:
                      codens
                      wav's loop breaks properly on NT_SUCCESS tho so I dont see the problem
                      lolmaoman: Germans are born with a lifetime x22 login engraved into their birth certificates. True story.
                      I DONT HAVE TEAMVIEWER AND IM NOT GOING TO GIVE ANY 24/7 ONLINE SUPPORT VIA STEAM, XFIRE OR OTHER IM PROGRAMS SO DONT BOTHER ASKING. THANKS.

                      Comment


                        #12
                        Re: Enumerating x64 processes from x86 process

                        Originally posted by mencore View Post
                        wav's loop breaks properly on NT_SUCCESS tho so I dont see the problem
                        extern seems to be under the assumption that every index for NtQuerySystemInformation always returns the correct buffer length you need. Apparently you haven't tested on a wide enough variety of systems to see cases where this is not true.

                        Comment


                          #13
                          Re: Enumerating x64 processes from x86 process

                          Originally posted by wav View Post
                          extern seems to be under the assumption that every index for NtQuerySystemInformation always returns the correct buffer length you need. Apparently you haven't tested on a wide enough variety of systems to see cases where this is not true.
                          Originally posted by MSDN
                          ReturnLength [out, optional]
                          An optional pointer to a location where the function writes the actual size of the information requested. If that size is less than or equal to the SystemInformationLength parameter, the function copies the information into the SystemInformation buffer; otherwise, it returns an NTSTATUS error code and returns in ReturnLength the size of buffer required to receive the requested information.
                          If they cared enough to document it on MSDN means it should be right for all current systems they didnt dropped support for, go ahead and check it to prove me wrong and cover up your homosexual loop

                          Comment


                            #14
                            Re: Enumerating x64 processes from x86 process

                            Originally posted by extern4ever View Post
                            If they cared enough to document it on MSDN means it should be right for all current systems they didnt dropped support for, go ahead and check it to prove me wrong and cover up your homosexual loop
                            You'd do well to learn by now that MSDN is not always right or up to date. I don't know what you're trying to prove here, or if you're just trying to get under my skin since you're Polish. Regardless when you deploy software across a wide variety of systems and have to debug client machines only to find out that shit like GetThreadContext fails for no apparent reason and you have to resort to less clean methods come back.

                            related:

                            This domain name has been registered with Gandi.net. It is currently parked by the owner.


                            and final rule i've learnt:

                            assume the end user is a moron
                            Last edited by wav; 01-09-2013, 08:13 PM.

                            Comment


                              #15
                              Re: Enumerating x64 processes from x86 process

                              Originally posted by wav View Post
                              You'd do well to learn by now that MSDN is not always right or up to date. I don't know what you're trying to prove here, or if you're just trying to get under my skin since you're Polish. Regardless when you deploy software across a wide variety of systems and have to debug client machines only to find out that shit like GetThreadContext fails for no apparent reason and you have to resort to less clean methods come back.
                              Does it atleast fail on any other version than win7 which is used by almost everyone? If my method would fail then your method would fail aswell cause you used the last argument kinda wrong

                              Originally posted by wav
                              Code:
                              status = NtQuerySystemInformation ( SystemProcessInformation, pbBuffer, dwSizeRequired, &dwSizeRequired );
                              Last edited by extern4ever; 01-10-2013, 01:25 AM.

                              Comment

                              Working...
                              X