/* * hide.c -- hides a file in an alternate data stream on NTFS * */ #define WIN32_LEAN_AND_MEAN #define WIN32_DEFAULT_LIBS #include #include #include #define APPLICATION __T("hide") #define VERSION __T("v1.01") #define AUTHOR __T("nabiy . http://nabiy.sdf1.org") void usage( void ) ; _Bool NTFS( void ) ; int main (int argc, LPTSTR argv []) { HANDLE hIn, hOut, hFile; DWORD nIn, nOut; CHAR Buffer [MAX_PATH]; FILETIME lastAccessTime, lastWriteTime ; LPFILETIME pAccessTime, pWriteTime ; if (argc != 3) { usage() ; return ERROR_INVALID_PARAMETER ; } if (_tcslen(argv[1]) > MAX_PATH || _tcslen(argv[2]) > MAX_PATH) { return ERROR_INVALID_PARAMETER ; } if (!NTFS()) { _ftprintf (stderr, __T("NTFS Required for Alternate Data Streams\n") ) ; return ERROR_NOT_SUPPORTED ; } char altDataStream[MAX_PATH] ; _tcscpy(altDataStream, argv[2]) ; _tcscat(altDataStream, ":") ; _tcscat(altDataStream, argv[1]) ; /* * get the original File Times for the place to hide */ hFile = CreateFile (argv[2], GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL) ; if (hFile == INVALID_HANDLE_VALUE) { _ftprintf (stderr, __T("Cannot open %s. Error: %x\n"), argv[2], GetLastError() ) ; return GetLastError() ; } if (!GetFileTime( hFile, NULL, &lastAccessTime, &lastWriteTime ) ) { _ftprintf (stderr, __T("Failed to get file times for %s. Error: %x\n"), argv[2], GetLastError() ) ; return GetLastError() ; } pAccessTime = &lastAccessTime ; pWriteTime = &lastWriteTime ; /* * Done Getting the Files Times. Now we Open the files and the Alternate Data Stream * and copy the file into the ADS. */ hIn = CreateFile (argv[1], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (hIn == INVALID_HANDLE_VALUE) { _ftprintf (stderr, __T("Cannot open %s. Error: %x\n"), argv[1], GetLastError() ) ; return GetLastError() ; } hOut = CreateFile (altDataStream, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (hOut == INVALID_HANDLE_VALUE) { _ftprintf (stderr, __T("Cannot open %s. Error: %x\n"), argv[1], GetLastError() ) ; return GetLastError() ; } // copy the first file to ADS while (ReadFile (hIn, Buffer, sizeof(Buffer), &nIn, NULL) && nIn > 0) { WriteFile (hOut, Buffer, nIn, &nOut, NULL); if (nIn != nOut) { _ftprintf (stderr, __T("Fatal write error: %x\n"), GetLastError ()); return GetLastError() ; } } CloseHandle (hIn); CloseHandle (hOut); /* * Now we restore the original filetimes. */ if (!SetFileTime( hFile, NULL, pAccessTime, pWriteTime ) ) { _ftprintf (stderr, __T("Failed to set file times for %s. Error: %x\n"), argv[2], GetLastError() ) ; return GetLastError() ; } CloseHandle (hFile) ; _tprintf( __T("file %s hidden as %s\n"), argv[1], altDataStream) ; return 0; } void usage( void ) { char szUsage[] = __T("\n") APPLICATION __T(" ") VERSION __T(" by ") AUTHOR __T("\n") __T("Usage is:\n") __T("\t") APPLICATION __T(" file2hide place2hide\n\n") ; _ftprintf(stderr,szUsage); } _Bool NTFS( void ) { char szVolName[MAX_PATH], szFSName[MAX_PATH] ; DWORD dwMaxLen, dwVolFlags ; GetVolumeInformation( NULL, szVolName, MAX_PATH, NULL, &dwMaxLen, &dwVolFlags, szFSName, MAX_PATH); // if szFSName is NTFS then we have Alternate Data Streams // and we return true if (_tcsicmp(szFSName, __T("NTFS") ) == 0) { return 1 ; } // if not then return false return 0 ; }