/* Generates the name of the long file name directories */ int Generate_Long_Name ( int drive_num, UINT lba, UINT cluster_no, UCHAR long_direntry[], int i, int k) { int nam_in, flag=0; fat_nam_index = 0; do { if( i <= 0 ) { flag = 1; i = DIRENT_PER_SECTOR; k = k - 1; if( read_disk_sector(long_direntry, drive_num, lba+CLUSTER_TO_LBA(cluster_no)+k, 1) == IDE_ERR_IO_ERROR ) return(DISK_READ_ERR); } fat32longdir = (struct fat_long_dirent *)&long_direntry[(i-1)*32]; for( nam_in = 0; nam_in < 10; nam_in+=2) { Check_char( fat32longdir->LDIR_Name1[nam_in], LONG_NAME); } for( nam_in = 0; nam_in < 12; nam_in+=2) { Check_char( fat32longdir->LDIR_Name2[nam_in], LONG_NAME); } for( nam_in = 0; nam_in < 4; nam_in+=2) { Check_char( fat32longdir->LDIR_Name3[nam_in], LONG_NAME); } i--; } while ((fat32longdir->LDIR_Ord & 0x40)==0 && i>=0); if(flag) { k = k + 1; if( read_disk_sector(long_direntry, drive_num, lba+CLUSTER_TO_LBA(cluster_no)+k, 1) == IDE_ERR_IO_ERROR ) return(DISK_READ_ERR); } fat_temp->filename[fat_nam_index] = '\0'; fat_temp->next = (struct fat_file_properties *)kmalloc(sizeof(struct fat_file_properties)); fat_temp = fat_temp->next; fat_temp->next = NULL; fat_item_count++; return; }
/* Reads the FAT and decides the next cluster where the data corresponding to the file is stored */ int fat32_rd_FAT(int drive_num, UINT lba, UINT cluster) { UCHAR FAT_entry[512]; UCHAR direntry[512]; int i; UINT sec_no; UINT offset; int clu_no; sec_no = cluster / CLU_PER_FAT; offset = cluster % CLU_PER_FAT; if( read_disk_sector(FAT_entry, drive_num, fat_begin_lba + sec_no, 1) == IDE_ERR_IO_ERROR ) return (DISK_READ_ERR); FAT = (struct FAT_32bit_entry *)FAT_entry; if(FAT->fat32bit[offset]==FAT_EOF_MARKER) return(0); else return(FAT->fat32bit[offset]); }
/* Reads the bootsector of the FAT32 FS */ int fat32_rd_bootsec(int drive_num, UINT lba) { UCHAR bootsec[512], i; if( read_disk_sector(bootsec, drive_num, lba, 1) == IDE_ERR_IO_ERROR ) return(DISK_READ_ERR); fat32boot = (struct fat_bootsector *)bootsec; if ( fat32boot->magic != 0xAA55 ) return ( BAD_FAT_BOOT_SECTOR ); fat_begin_lba = lba + fat32boot->num_boot_sectors; cluster_begin_lba = fat32boot->num_boot_sectors + ( fat32boot->num_fats * fat32boot->big_sectors_per_FAT ); root_dir_first_cluster = fat32boot->root_directory_start; sectors_per_cluster = fat32boot->sectors_per_cluster; return SUCCESS; }
/* Loads the contents of the file to any specified memory address */ int fat32_mmap( int drive_num, UINT lba, UINT cluster_no, UCHAR *mem_loc, int size ) { UCHAR mmap_data[512]; int next_cluster; int k,i; for ( k = 0; k <= ((size-1)/512); k++ ) { if( read_disk_sector(mmap_data, drive_num, lba + CLUSTER_TO_LBA(cluster_no) + k, 1) == IDE_ERR_IO_ERROR ) return (DISK_READ_ERR); for(i = 0; i < 512; i++ ) *mem_loc++ = mmap_data[i]; } next_cluster=fat32_rd_FAT(drive_num, lba, cluster_no); if (!error(next_cluster)) { if (next_cluster) fat32_mmap( current_drive, current_lba, next_cluster, mem_loc, (size-512)); } else return next_cluster; return; }
int disk_dump_hex_data(int drive_number, long total_sectors_to_read, LP_PROGRAM_DATA PData) { unsigned int buffer[512]; char letra; DWORD bytes_por_setor; char const *unidade = ""; long long tam_disco; int falhas = 0, sector_index; FILE *inputFile; FILE *outputFile; struct conversion_data a1; struct conversion_mode a2; CONVERSION_DATA StructConv = &a1; CONVERSION_MODE StructMode = &a2; short res; HANDLE DiscoRigido; CHAR nome_hd[16], cmdLine[MAX_PATH], localAtual[MAX_PATH], currentFile[MAX_PATH], HexFile2[MAX_PATH], HexFile[MAX_PATH]; DWORD ptr; NTFS_VOLUME_DATA_BUFFER disk_data_buffer; DWORD bytesLidos, totalBytesLidos = 0; letra = convert_disk_number_to_letter(drive_number); if(letra == 0) return 0x83; if(!IsUserAnAdmin()) { msgaviso("You are not admin ... Changing privileges ...\n"); if(GetCurrentDirectoryA(MAX_PATH, (LPSTR)localAtual)) { sprintf(cmdLine, "%s %s %s %s", PData->command_line[1], PData->command_line[2], PData->command_line[3], PData->command_line[4]); sprintf(currentFile, "%s\\hexdumper.exe", localAtual); ShellExecuteA(0, "runas", currentFile, cmdLine, (char const *)localAtual, SW_SHOW); } exit(GetLastError()); } sprintf(nome_hd, "\\\\.\\%c:", letra); DiscoRigido = CreateFileA( nome_hd, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if(DiscoRigido == INVALID_HANDLE_VALUE) return 0x81; if(!DeviceIoControl(DiscoRigido, FSCTL_GET_NTFS_VOLUME_DATA, 0, 0, &disk_data_buffer, sizeof(disk_data_buffer), &ptr, NULL)) { if(DiscoRigido) CloseHandle(DiscoRigido); return 0x80; } bytes_por_setor = disk_data_buffer.BytesPerSector; tam_disco = disk_data_buffer.NumberSectors.QuadPart * disk_data_buffer.BytesPerSector; unidade = ""; assert(tam_disco > 0); if(tam_disco <= _1KB) unidade = "Bytes"; else if(tam_disco <= _1MB) { tam_disco /= _1KB; unidade = "KB"; } else if(tam_disco <= _1GB) { tam_disco /= _1MB; unidade = "MB"; } else { tam_disco /= _1GB; unidade = "GB"; } long long conversion_size = total_sectors_to_read * bytes_por_setor; if((conversion_size / _1GB) > (0xffffffff / _1GB)) { msgerro( "Data bigger than %.2lf GB aren´t supported yet\n", (double)(0xffffffff / _1GB)); msgerro("Your conversion size is: %.2lf KB\n", (double)conversion_size / _1KB); return 0x86; } sprintf(HexFile, "hd%d.txt", drive_number); outputFile = fopen(HexFile, "wb"); assert(outputFile != NULL); if(PData->verbose) { fprintf(stdout, "\n"); fprintf(stdout, "\t-> Disk size: %.2lf %s\n\t-> Bytes per sector %ld\n", (double)tam_disco, unidade, bytes_por_setor); fprintf(stdout, "\t-> Serial number: 0x%.8x\n\t-> MFT start address: 0x%.8x\n", disk_data_buffer.VolumeSerialNumber, disk_data_buffer.MftStartLcn); fprintf(stdout, "\t-> Number of sectors to read: %ld\n", total_sectors_to_read); fprintf(stdout, "\t-> Data length to read: %.2lf KB\n", (double)conversion_size / _1KB); fprintf(stdout, "\n"); } if (!DeviceIoControl(DiscoRigido, FSCTL_LOCK_VOLUME, 0, 0, 0, 0, &ptr, NULL)) if(PData->verbose) msgaviso( "failed to block volume ...\n"); for(sector_index = 0; sector_index < total_sectors_to_read; sector_index++) { if(!DiscoRigido || DiscoRigido == INVALID_HANDLE_VALUE) break; bytesLidos = read_disk_sector(sector_index, bytes_por_setor, buffer, DiscoRigido); if(bytesLidos) { fwrite(buffer, 1, bytesLidos, outputFile); totalBytesLidos += bytesLidos; } else { falhas++; if(falhas > 100) break; } } if(!DeviceIoControl(DiscoRigido, FSCTL_UNLOCK_VOLUME, 0, 0, NULL, 0, &ptr, NULL)) { if(PData->verbose) msgaviso( "Failed to unblock volume. Maybe it is already unblocked\n"); } if(DiscoRigido) CloseHandle(DiscoRigido); if(outputFile) fclose(outputFile); if (PData->verbose) { msginfo("Converting data to HEX format ...\n"); msginfo("Opening %s ...\n", HexFile); } inputFile = fopen(HexFile, "rb"); sprintf(HexFile2, "dump_of_%s", HexFile); outputFile = fopen(HexFile2, "wb"); assert(inputFile != NULL); assert(outputFile != NULL); // agora descarregar o arquivo no formato hexadecimal ... StructConv->bytes_to_read = totalBytesLidos; StructMode->s_mode = DEFAULT_MODE; res = hex_file_write_data_in_specified_mode(StructConv, StructMode, inputFile, outputFile, DEFAULT_MODE); if(PData->verbose && res == 0xFF) { msgerro( "Cannot make HEX dump ...\n"); } else if(PData->verbose && res == 0) msgsucesso( "Hex dump completed ...\nOutput: %s\n", HexFile2); if(inputFile) fclose(inputFile); if(outputFile) fclose(outputFile); return 0; }
/* Reads any cluster of the FAT32 FS */ int fat32_rd_cluster ( int drive_num, UINT lba, UINT cluster_no ) { UCHAR direntry[512]; UINT next_cluster, size; int i = 0,k = 0, root_cluster, j, prev = 0x00; UINT start_cluster ; for(k=0;k<sectors_per_cluster;k++) { if( read_disk_sector(direntry, drive_num, lba + CLUSTER_TO_LBA(cluster_no) + k, 1) == IDE_ERR_IO_ERROR ) return (DISK_READ_ERR); for( i = 0; i < DIRENT_PER_SECTOR; i++ ) { fat32dir = (struct fat_dirent *)&direntry[i*32]; if ( fat32dir->attrib != 0x0F && fat32dir->attrib != 0x08 ) { start_cluster = fat32dir->st_clust_msw; start_cluster = start_cluster << 16 ; start_cluster = start_cluster + fat32dir->st_clust; if (!start_cluster && fat32dir->attrib == 0x10) start_cluster += 2; /* filling in the properties of the FAT32 diectory */ if( fat32dir->attrib & FAT_ATTR_DIRECTORY || fat32dir->attrib & FAT_ATTR_VOLUME_ID ) {fat_temp->file_type = DIRECTORY;} else if ( fat32dir->attrib & FAT_ATTR_FILE ) fat_temp->file_type = REG_FILE; else fat_temp->file_type = fat32dir->attrib; fat_temp->st_clust = start_cluster; fat_temp->size = fat32dir->file_size; d_date = (struct dos_date *)&fat32dir->mdate; d_time = (struct dos_time *)&fat32dir->mtime; if(prev == 0x0F) { if(!i) { if( read_disk_sector(direntry, drive_num, lba + CLUSTER_TO_LBA(cluster_no) + k - 1, 1) == IDE_ERR_IO_ERROR ) return (DISK_READ_ERR); i = DIRENT_PER_SECTOR; Generate_Long_Name(drive_num, lba, cluster_no, direntry, i, k); if( read_disk_sector(direntry, drive_num, lba + CLUSTER_TO_LBA(cluster_no) + k, 1) == IDE_ERR_IO_ERROR ) return (DISK_READ_ERR); i = 0x00; } else Generate_Long_Name(drive_num, lba, cluster_no, direntry, i, k); prev = 0x00; } else { if(fat32dir->name[0]!=0 && fat32dir->name[0]!=0xE5 && fat32dir->name[0]!=0x20) { fat_nam_index = 0; for( j = 0; j < 8; j++) Check_char( fat32dir->name[j], SHORT_NAME ); if( fat32dir->ext[0] != ' ' ) fat_temp->filename[fat_nam_index++] = '.'; for( j = 0; j < 3; j++) Check_char( fat32dir->ext[j], SHORT_NAME ); fat_temp->filename[fat_nam_index] = '\0'; fat_item_count++; fat_temp->next = (struct fat_file_properties *) kmalloc (sizeof(struct fat_file_properties)); fat_temp = fat_temp->next; fat_temp->next = NULL; } } } if(fat32dir->name[0]!=0 && fat32dir->name[0]!=0xE5 && fat32dir->name[0]!=0x20) prev = fat32dir->attrib; } } next_cluster=fat32_rd_FAT(drive_num, lba, cluster_no); if (!error(next_cluster)) { if (next_cluster) fat32_rd_cluster( drive_num, lba, next_cluster); } else return next_cluster; strcpy ( (char*)fat_temp->filename,""); return SUCCESS; }