Auf der Suche nach Alternate Data Streams



  • Servus an alle,

    wie findet man einen Alternate Data Stream? Ich will nämlich ein Programm schreiben, das das macht. Ich weiß auch, dass es solche Programme bereits gibt, aber ich würde gerne wissen, wie diese funktionieren.
    Ich würde mich über eine Antwort freuen,
    Felix


  • Mod

    Man liest und schreibt diese wie man auch normale Dateien liest schreibt:
    http://support.microsoft.com/kb/105763/en-us



  • Danke, aber das hab ich schon gewusst. Meine Frage ist, wie man sieht, dass sich hinter einer Datei ein Stream versteckt und wie dieser heißt.





  • Danke Jochen. Der Link hat mir sehr geholfen. Ich kann jetzt Streams ausfindig machen, aber das Wichtigste klappt noch nicht. Ich kann den Namen des Streams einfach nicht ermitteln. Hier meine Funktion:

    #define MAX_STREAM_DATA_PREVIEW_SIZE 64
    
    typedef struct tagSTREAM_INFO
    {
    	char sName[1024];
    	LONG	lSize;
    	BYTE	baData[MAX_STREAM_DATA_PREVIEW_SIZE];
    
    } STREAM_INFO;
    
    int GetStreams(char *streams)
    {
        HANDLE hFile;
    
    	hFile = CreateFile( streams, 
    						GENERIC_READ, 
    						FILE_SHARE_READ, 
    						NULL, 
    						OPEN_EXISTING, 
    						FILE_FLAG_BACKUP_SEMANTICS, 
    						NULL );
    
    	if(hFile == INVALID_HANDLE_VALUE)
    	{
    		return 0;
    	}
    
    	int bResult=1;
    	BYTE				baData[sizeof(WIN32_STREAM_ID) + sizeof(TCHAR)];
    	LPWIN32_STREAM_ID	pStrmId;
    	DWORD				dwBytesToRead;
    	DWORD				dwBytesRead;
    	LPVOID				pContext;
    	LARGE_INTEGER		liDataSize;
    	DWORD				dwNameSize;
    
    	pContext	  = NULL;
    
    	while(bResult==1)
    	{
    		dwBytesToRead = sizeof(baData);
    
    		if(!BackupRead(	hFile,baData,dwBytesToRead,&dwBytesRead,FALSE,FALSE,&pContext ) )
    		{
    			bResult = 0;
    		}
    		else
    		{
                if(dwBytesRead == 0)
    			{
    				bResult = 0;
    			}
    			else
    			{
    				pStrmId = (LPWIN32_STREAM_ID)baData;
    				dwNameSize = pStrmId->dwStreamNameSize;
    				liDataSize = pStrmId->Size;
    
    				char neu[900];
    				int big;
    				sprintf(neu,"%d",liDataSize);
    				sscanf(neu,"%d",&big);
    
    				if(big==0)
    				{
                                     bResult = 0;
                                     break;
                    }
    
    				printf("liDataSize: %d\n",liDataSize);
    
    				if(dwNameSize > 0)
    				{
    					char wcsStreamName[dwNameSize + sizeof(TCHAR)];
    
    					ZeroMemory(wcsStreamName, dwNameSize + 2);
                       CopyMemory(wcsStreamName, pStrmId->cStreamName, 6);
    
                        printf("wcsStreamName: %s\n",wcsStreamName);
    
    					dwBytesToRead = dwNameSize - 6;
    					BYTE lpBuffer[dwBytesToRead + 1];
    
    					if(!BackupRead(	hFile, 
    									lpBuffer,
    									dwBytesToRead,
    									&dwBytesRead,
    									FALSE,
    									FALSE,
    									&pContext ) )
    					{
    						bResult = 0;
    					}			
    
    					char wszStreamName[MAX_PATH]; 
                        BackupRead(hFile, (LPBYTE) wszStreamName, dwNameSize, &dwBytesRead, FALSE, FALSE, &pContext);
    
                        CopyMemory((wcsStreamName + 3), lpBuffer, dwBytesToRead);
    
                        STREAM_INFO info;
    					strcpy(info.sName,wcsStreamName);
    					info.lSize = liDataSize.LowPart;
    					info.baData[0] = 0;
    
    					pStrmId = NULL;
    	          }
               }
               }
    		}
    		CloseHandle(hFile);
    }
    

    Ich hab mich mit dem Sourcecode(von http://www.codeproject.com/w2k/AlternateDataStream.asp) beschäftigt, aber ganz verstehen tu ich ihn leider noch nicht. Ich hab ihn ein bisschen gekürzt und C compatibel gemacht, aber ich komm einfach nicht drauf wie ich aus diesem Code den Namen des Streams ermittle.



  • Ähhh.... Du solltest Dir vielleicht mal ganz grobe Gedanken darüber machen, was WCHAR (oder wchar_t) und char ist...
    Ganz grob gesagt: Das eine ist UNICODE und das andere ist ANSI... Du kannst nicht einfach wild casten und nach char ändern und erwarten dass alles noch tut...



  • Ich hab jetzt:

    TCHAR* wcsStreamName[dwNameSize + sizeof(TCHAR)];
    

    aber wie kann ich jetzt zu dem Namen kommen?



  • Nach langer Suche hab ich was im Internet gefunden: http://win32.mvps.org/ntfs/dump_ntfs_streams.cpp

    Dieser Sourcecode funktioniert wunderbar. Für alle die das Suchen der Streams interessiert. Der Code ist zu empfehlen.


  • Mod

    Felix15 schrieb:

    Ich hab jetzt:

    TCHAR* wcsStreamName[dwNameSize + sizeof(TCHAR)];
    

    aber wie kann ich jetzt zu dem Namen kommen?

    Du hast nicht verstanden was ein TCHAR ist.
    Egal was Du für einen Code findest. Du solltest verstehen was er tut.


Anmelden zum Antworten