mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-21 19:42:14 +00:00
GT-2758 - fix and normalize GFileSystem.getInfo()
Remove unnecessary boilerplate impls that returned null. Build info string better, handle the GTree node where a sub-file system is mounted so that both are included in the info display. Fix missing img3 icon.
This commit is contained in:
parent
4ce178c419
commit
203dacdecc
@ -14,7 +14,7 @@
|
||||
<file_extension extension=".h" icon="images/oxygen/16x16/text-x-chdr.png" />
|
||||
<file_extension extension=".html" icon="images/famfamfam_silk_icons_v013/html.png" />
|
||||
<file_extension extension=".img" icon="images/famfamfam_silk_icons_v013/images.png" />
|
||||
<file_extension extension=".img3" icon="images/famfamfam_silk_icons_v013/bullet-orange.png" />
|
||||
<file_extension extension=".img3" icon="images/famfamfam_silk_icons_v013/bullet_orange.png" />
|
||||
<file_extension extension=".index" icon="images/oxygen/16x16/bookmarks.png" />
|
||||
<file_extension extension=".ipsw" icon="images/oxygen/16x16/multimedia-player-apple-ipod.png" />
|
||||
<file_extension extension=".iso" icon="images/nuvola/16x16/cdimage.png" />
|
||||
|
@ -108,7 +108,7 @@ public class FileSystemIndexHelper<METADATATYPE> {
|
||||
* @return {@link GFile} instance or null if no file was added to the index at that path.
|
||||
*/
|
||||
public GFile lookup(String path) {
|
||||
String[] nameparts = path.split("/");
|
||||
String[] nameparts = (path != null ? path : "").split("/");
|
||||
GFile parent = lookupParent(nameparts);
|
||||
if (nameparts.length == 0) {
|
||||
return parent;
|
||||
|
@ -15,14 +15,14 @@
|
||||
*/
|
||||
package ghidra.formats.gfilesystem;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
|
||||
import ghidra.util.classfinder.ExtensionPoint;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Interface that represents a filesystem that contains files.
|
||||
* <p>
|
||||
@ -155,9 +155,10 @@ public interface GFileSystem extends Closeable, ExtensionPoint {
|
||||
* <p>
|
||||
* @param file {@link GFile} to get info message for.
|
||||
* @param monitor {@link TaskMonitor} to watch and update progress.
|
||||
* @return multi-line formatted string with info about the file.
|
||||
* @throws IOException if IO problem.
|
||||
* @return multi-line formatted string with info about the file, or null.
|
||||
*/
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException;
|
||||
default public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -129,9 +129,6 @@ public abstract class GFileSystemBase implements GFileSystem {
|
||||
@Override
|
||||
abstract public List<GFile> getListing(GFile directory) throws IOException;
|
||||
|
||||
@Override
|
||||
abstract public String getInfo(GFile file, TaskMonitor monitor) throws IOException;
|
||||
|
||||
/**
|
||||
* Legacy implementation of {@link #getInputStream(GFile, TaskMonitor)}.
|
||||
*
|
||||
|
@ -130,14 +130,19 @@ public class LocalFileSystemSub implements GFileSystem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
File localFile = getFileFromGFile(file);
|
||||
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("Name: " + localFile.getName() + "\n");
|
||||
buffer.append("Size: " + localFile.length() + "\n");
|
||||
buffer.append("Date: " + new Date(localFile.lastModified()).toString() + "\n");
|
||||
return buffer.toString();
|
||||
public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
try {
|
||||
File localFile = getFileFromGFile(file);
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("Name: " + localFile.getName() + "\n");
|
||||
buffer.append("Size: " + localFile.length() + "\n");
|
||||
buffer.append("Date: " + new Date(localFile.lastModified()).toString() + "\n");
|
||||
return buffer.toString();
|
||||
}
|
||||
catch (IOException e) {
|
||||
// fail and return null
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -472,42 +472,50 @@ class FSBActionManager {
|
||||
* @param monitor {@link TaskMonitor} to monitor and update when accessing the filesystems.
|
||||
*/
|
||||
private void showInfoForFile(FSRL fsrl, TaskMonitor monitor) {
|
||||
String title = " no title ";
|
||||
String info = " no information available ";
|
||||
String fileSystemName = " unknown ";
|
||||
String title;
|
||||
String info;
|
||||
|
||||
if (fsrl != null) {
|
||||
info = "";
|
||||
title = "Info about " + fsrl.getName();
|
||||
if (fsrl instanceof FSRLRoot && ((FSRLRoot) fsrl).hasContainer()) {
|
||||
fsrl = ((FSRLRoot) fsrl).getContainer();
|
||||
}
|
||||
try (RefdFile refdFile = FileSystemService.getInstance().getRefdFile(fsrl, monitor)) {
|
||||
|
||||
title = fsrl.getName();
|
||||
|
||||
GFileSystem fs = refdFile.fsRef.getFilesystem();
|
||||
fileSystemName = fs.getDescription();
|
||||
info = "FSRL: " + fsrl + "\n";
|
||||
DomainFile associatedDomainFile =
|
||||
ProgramMappingService.getCachedDomainFileFor(fsrl);
|
||||
if (associatedDomainFile != null) {
|
||||
info = info + "Project file: " + associatedDomainFile.getPathname() + "\n";
|
||||
}
|
||||
String nodeInfo = fs.getInfo(refdFile.file, monitor);
|
||||
if (nodeInfo != null) {
|
||||
info += nodeInfo;
|
||||
}
|
||||
}
|
||||
catch (IOException | CancelledException e) {
|
||||
info = "Error retrieving information: " + e.getMessage();
|
||||
FSRL containerFSRL = ((FSRLRoot) fsrl).getContainer();
|
||||
title = containerFSRL.getName();
|
||||
info = getInfoStringFor(containerFSRL, monitor);
|
||||
info += "------------------------------------\n";
|
||||
}
|
||||
info += getInfoStringFor(fsrl, monitor);
|
||||
}
|
||||
else {
|
||||
title = "Missing File";
|
||||
info = "Unable to retrieve information";
|
||||
}
|
||||
|
||||
MultiLineMessageDialog.showMessageDialog(plugin.getTool().getActiveWindow(),
|
||||
"Info about " + title, null, "File system: " + fileSystemName + '\n' + info,
|
||||
MultiLineMessageDialog.INFORMATION_MESSAGE);
|
||||
MultiLineMessageDialog.showMessageDialog(plugin.getTool().getActiveWindow(), title, null,
|
||||
info, MultiLineMessageDialog.INFORMATION_MESSAGE);
|
||||
|
||||
}
|
||||
|
||||
private String getInfoStringFor(FSRL fsrl, TaskMonitor monitor) {
|
||||
try (RefdFile refdFile = FileSystemService.getInstance().getRefdFile(fsrl, monitor)) {
|
||||
GFileSystem fs = refdFile.fsRef.getFilesystem();
|
||||
String result = "File system: " + fs.getDescription() + "\n";
|
||||
result += "FSRL: " + fsrl + "\n";
|
||||
DomainFile associatedDomainFile = ProgramMappingService.getCachedDomainFileFor(fsrl);
|
||||
if (associatedDomainFile != null) {
|
||||
result += "Project file: " + associatedDomainFile.getPathname() + "\n";
|
||||
}
|
||||
String nodeInfo = fs.getInfo(refdFile.file, monitor);
|
||||
if (nodeInfo != null) {
|
||||
result += nodeInfo;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (IOException | CancelledException e) {
|
||||
return "Error retrieving information: " + e.getMessage() + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a list of supported file system types and loaders.
|
||||
*/
|
||||
|
@ -55,11 +55,6 @@ public class ApkFileSystem extends GFileSystemBase {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InputStream getData(GFile file, TaskMonitor monitor)
|
||||
throws IOException, CancelledException, CryptoException {
|
||||
|
@ -86,7 +86,7 @@ public class BootImageFileSystem extends GFileSystemBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
if (file == kernelFile) {
|
||||
return "This is the actual KERNEL for the android device. You can analyze this file.";
|
||||
}
|
||||
|
@ -175,9 +175,4 @@ public class DexToJarFileSystem extends GFileSystemBase {
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -146,7 +146,6 @@ public class DexToSmaliFileSystem extends GFileSystemBase {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void storeFile(GFile file, File entry) {
|
||||
if (file == null) {
|
||||
return;
|
||||
@ -166,11 +165,6 @@ public class DexToSmaliFileSystem extends GFileSystemBase {
|
||||
map.clear();
|
||||
super.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/* DexHeader header = new DexHeader(provider);
|
||||
|
@ -95,11 +95,6 @@ public class KernelFileSystem extends GFileSystemBase {
|
||||
: Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InputStream getData(GFile file, TaskMonitor monitor)
|
||||
throws IOException, CancelledException, CryptoException {
|
||||
|
@ -64,7 +64,7 @@ public class OdexFileSystem extends GFileSystemBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("Magic: " + odexHeader.getMagic()).append("\n");
|
||||
builder.append("Dex Offset: " + Integer.toHexString(odexHeader.getDexOffset())).append(
|
||||
|
@ -96,11 +96,6 @@ public class AndroidXmlFileSystem extends GFileSystemBase {
|
||||
return new ByteArrayInputStream(payloadBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GFile> getListing(GFile directory) throws IOException {
|
||||
List<GFile> tmp = new ArrayList<>();
|
||||
|
@ -104,7 +104,7 @@ public class CoffArchiveFileSystem implements GFileSystem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
CoffArchiveMemberHeader entry = fsih.getMetadata(file);
|
||||
return (entry == null) ? null : FSUtilities.infoMapToString(getInfoMap(entry));
|
||||
}
|
||||
|
@ -55,11 +55,6 @@ public class CompLzssFileSystem extends GFileSystemBase {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GFile> getListing(GFile directory) throws IOException {
|
||||
return (directory == null || directory.equals(root)) ? Arrays.asList(decompressedFile)
|
||||
|
@ -107,9 +107,9 @@ public class CpioFileSystem extends GFileSystemBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
CpioArchiveEntry entry = map.get(file);
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
try {
|
||||
buffer.append("Name: " + entry.getName() + "\n");
|
||||
buffer.append("Checksum: " + Long.toHexString(entry.getChksum()) + "\n");
|
||||
@ -126,6 +126,7 @@ public class CpioFileSystem extends GFileSystemBase {
|
||||
buffer.append("Device ID: " + Long.toHexString(entry.getDevice()) + "\n");
|
||||
}
|
||||
catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
@ -43,221 +43,219 @@ public class Ext4FileSystem implements GFileSystem {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
public void mountFS( TaskMonitor monitor ) throws IOException, CancelledException {
|
||||
BinaryReader reader = new BinaryReader( provider, true );
|
||||
reader.setPointerIndex( 0x400 );
|
||||
public void mountFS(TaskMonitor monitor) throws IOException, CancelledException {
|
||||
BinaryReader reader = new BinaryReader(provider, true);
|
||||
reader.setPointerIndex(0x400);
|
||||
|
||||
Ext4SuperBlock superBlock = new Ext4SuperBlock( reader );
|
||||
Ext4SuperBlock superBlock = new Ext4SuperBlock(reader);
|
||||
|
||||
this.volumeName = superBlock.getVolumeName( );
|
||||
this.volumeName = superBlock.getVolumeName();
|
||||
|
||||
this.uuid = NumericUtilities.convertBytesToString( superBlock.getS_uuid( ) );
|
||||
this.uuid = NumericUtilities.convertBytesToString(superBlock.getS_uuid());
|
||||
|
||||
int s_log_block_size = superBlock.getS_log_block_size( );
|
||||
blockSize = ( int ) Math.pow( 2, ( 10 + s_log_block_size ) );
|
||||
int s_log_block_size = superBlock.getS_log_block_size();
|
||||
blockSize = (int) Math.pow(2, (10 + s_log_block_size));
|
||||
|
||||
int groupSize = blockSize * superBlock.getS_blocks_per_group( );
|
||||
int numGroups = ( int ) ( provider.length( ) / groupSize );
|
||||
if ( provider.length( ) % groupSize != 0 ) {
|
||||
int groupSize = blockSize * superBlock.getS_blocks_per_group();
|
||||
int numGroups = (int) (provider.length() / groupSize);
|
||||
if (provider.length() % groupSize != 0) {
|
||||
numGroups++;
|
||||
}
|
||||
|
||||
boolean is64Bit = ( superBlock.getS_desc_size( ) > 32 ) && ( ( superBlock.getS_feature_incompat( ) & 0x80 ) > 0 );
|
||||
boolean is64Bit =
|
||||
(superBlock.getS_desc_size() > 32) && ((superBlock.getS_feature_incompat() & 0x80) > 0);
|
||||
|
||||
int groupDescriptorOffset = blockSize;
|
||||
reader.setPointerIndex( groupDescriptorOffset );
|
||||
Ext4GroupDescriptor [] groupDescriptors = new Ext4GroupDescriptor [ numGroups ];
|
||||
for ( int i = 0; i < numGroups; i++ ) {
|
||||
monitor.checkCanceled( );
|
||||
groupDescriptors[ i ] = new Ext4GroupDescriptor( reader, is64Bit );
|
||||
monitor.incrementProgress( 1 );
|
||||
reader.setPointerIndex(groupDescriptorOffset);
|
||||
Ext4GroupDescriptor[] groupDescriptors = new Ext4GroupDescriptor[numGroups];
|
||||
for (int i = 0; i < numGroups; i++) {
|
||||
monitor.checkCanceled();
|
||||
groupDescriptors[i] = new Ext4GroupDescriptor(reader, is64Bit);
|
||||
monitor.incrementProgress(1);
|
||||
}
|
||||
|
||||
Ext4Inode [] inodes = getInodes( reader, superBlock, groupDescriptors, is64Bit, monitor );
|
||||
Ext4Inode[] inodes = getInodes(reader, superBlock, groupDescriptors, is64Bit, monitor);
|
||||
|
||||
int s_inodes_count = superBlock.getS_inodes_count( );
|
||||
for ( int i = 0; i < s_inodes_count; i++ ) {
|
||||
Ext4Inode inode = inodes[ i ];
|
||||
if ( inode == null ) {
|
||||
int s_inodes_count = superBlock.getS_inodes_count();
|
||||
for (int i = 0; i < s_inodes_count; i++) {
|
||||
Ext4Inode inode = inodes[i];
|
||||
if (inode == null) {
|
||||
continue;
|
||||
}
|
||||
if ( ( inode.getI_mode( ) & Ext4Constants.I_MODE_MASK ) == Ext4Constants.S_IFDIR ) {
|
||||
processDirectory( reader, superBlock, inodes, i, null, null, monitor );
|
||||
if ((inode.getI_mode() & Ext4Constants.I_MODE_MASK) == Ext4Constants.S_IFDIR) {
|
||||
processDirectory(reader, superBlock, inodes, i, null, null, monitor);
|
||||
}
|
||||
else if ( ( inode.getI_mode( ) & Ext4Constants.I_MODE_MASK ) == Ext4Constants.S_IFREG ) {
|
||||
processFile( reader, superBlock, inode, monitor );
|
||||
else if ((inode.getI_mode() & Ext4Constants.I_MODE_MASK) == Ext4Constants.S_IFREG) {
|
||||
processFile(reader, superBlock, inode, monitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processDirectory( BinaryReader reader,
|
||||
Ext4SuperBlock superBlock,
|
||||
Ext4Inode[] inodes,
|
||||
int index,
|
||||
String name,
|
||||
GFile parent,
|
||||
TaskMonitor monitor ) throws IOException, CancelledException {
|
||||
private void processDirectory(BinaryReader reader, Ext4SuperBlock superBlock,
|
||||
Ext4Inode[] inodes, int index, String name, GFile parent, TaskMonitor monitor)
|
||||
throws IOException, CancelledException {
|
||||
|
||||
if ( name != null && ( name.equals( "." ) || name.equals( ".." ) ) ) {
|
||||
if (name != null && (name.equals(".") || name.equals(".."))) {
|
||||
return;
|
||||
}
|
||||
Ext4Inode inode = inodes[ index ];
|
||||
if ( name == null && parent == null ) {
|
||||
parent = fsih.getRootDir( );
|
||||
Ext4Inode inode = inodes[index];
|
||||
if (name == null && parent == null) {
|
||||
parent = fsih.getRootDir();
|
||||
}
|
||||
else {
|
||||
if ( parent == null ) {
|
||||
parent = fsih.getRootDir( );
|
||||
if (parent == null) {
|
||||
parent = fsih.getRootDir();
|
||||
}
|
||||
parent = fsih.storeFileWithParent( name, parent, -1, true, ( inode.getI_size_high( ) << 32 ) | inode.getI_size_lo( ), new Ext4File( name, inode ) );
|
||||
parent = fsih.storeFileWithParent(name, parent, -1, true,
|
||||
(inode.getI_size_high() << 32) | inode.getI_size_lo(), new Ext4File(name, inode));
|
||||
}
|
||||
if ( ( inode.getI_flags( ) & Ext4Constants.EXT4_EXTENTS_FL ) == 0 ) {
|
||||
if ((inode.getI_flags() & Ext4Constants.EXT4_EXTENTS_FL) == 0) {
|
||||
return;
|
||||
}
|
||||
boolean isDirEntry2 = ( superBlock.getS_feature_incompat( ) & Ext4Constants.INCOMPAT_FILETYPE ) != 0;
|
||||
boolean isDirEntry2 =
|
||||
(superBlock.getS_feature_incompat() & Ext4Constants.INCOMPAT_FILETYPE) != 0;
|
||||
// if uses extents
|
||||
if ( ( inode.getI_flags( ) & Ext4Constants.EXT4_EXTENTS_FL ) != 0 ) {
|
||||
Ext4IBlock i_block = inode.getI_block( );
|
||||
processIBlock( reader, superBlock, inodes, parent, isDirEntry2, i_block, monitor );
|
||||
if ((inode.getI_flags() & Ext4Constants.EXT4_EXTENTS_FL) != 0) {
|
||||
Ext4IBlock i_block = inode.getI_block();
|
||||
processIBlock(reader, superBlock, inodes, parent, isDirEntry2, i_block, monitor);
|
||||
}
|
||||
else {
|
||||
throw new IOException( "File system fails to use extents." );
|
||||
throw new IOException("File system fails to use extents.");
|
||||
}
|
||||
inodes[ index ] = null;
|
||||
inodes[index] = null;
|
||||
}
|
||||
|
||||
private void processIBlock( BinaryReader reader,
|
||||
Ext4SuperBlock superBlock,
|
||||
Ext4Inode[] inodes,
|
||||
GFile parent,
|
||||
boolean isDirEntry2,
|
||||
Ext4IBlock i_block,
|
||||
TaskMonitor monitor ) throws CancelledException, IOException {
|
||||
Ext4ExtentHeader header = i_block.getHeader( );
|
||||
if ( header.getEh_depth( ) == 0 ) {
|
||||
short numEntries = header.getEh_entries( );
|
||||
List< Ext4Extent > entries = i_block.getExtentEntries( );
|
||||
for ( int i = 0; i < numEntries; i++ ) {
|
||||
monitor.checkCanceled( );
|
||||
Ext4Extent extent = entries.get( i );
|
||||
long low = extent.getEe_start_lo( ) & 0xffffffffL;
|
||||
long high = extent.getEe_start_hi( ) & 0xffffffffL;
|
||||
long blockNumber = ( high << 16 ) | low;
|
||||
private void processIBlock(BinaryReader reader, Ext4SuperBlock superBlock, Ext4Inode[] inodes,
|
||||
GFile parent, boolean isDirEntry2, Ext4IBlock i_block, TaskMonitor monitor)
|
||||
throws CancelledException, IOException {
|
||||
Ext4ExtentHeader header = i_block.getHeader();
|
||||
if (header.getEh_depth() == 0) {
|
||||
short numEntries = header.getEh_entries();
|
||||
List<Ext4Extent> entries = i_block.getExtentEntries();
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
monitor.checkCanceled();
|
||||
Ext4Extent extent = entries.get(i);
|
||||
long low = extent.getEe_start_lo() & 0xffffffffL;
|
||||
long high = extent.getEe_start_hi() & 0xffffffffL;
|
||||
long blockNumber = (high << 16) | low;
|
||||
long offset = blockNumber * blockSize;
|
||||
reader.setPointerIndex( offset );
|
||||
if ( isDirEntry2 ) {
|
||||
processDirEntry2( reader, superBlock, inodes, parent, monitor, extent, offset );
|
||||
reader.setPointerIndex(offset);
|
||||
if (isDirEntry2) {
|
||||
processDirEntry2(reader, superBlock, inodes, parent, monitor, extent, offset);
|
||||
}
|
||||
else {
|
||||
processDirEntry( reader, superBlock, inodes, parent, monitor, extent, offset );
|
||||
processDirEntry(reader, superBlock, inodes, parent, monitor, extent, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
//throw new IOException( "Unhandled extent tree depth > 0 for inode " + index );
|
||||
short numEntries = header.getEh_entries( );
|
||||
short numEntries = header.getEh_entries();
|
||||
List<Ext4ExtentIdx> entries = i_block.getIndexEntries();
|
||||
for ( int i = 0; i < numEntries; i++ ) {
|
||||
monitor.checkCanceled( );
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
monitor.checkCanceled();
|
||||
|
||||
Ext4ExtentIdx extentIndex = entries.get( i );
|
||||
Ext4ExtentIdx extentIndex = entries.get(i);
|
||||
long lo = extentIndex.getEi_leaf_lo();
|
||||
long hi = extentIndex.getEi_leaf_hi();
|
||||
long physicalBlockOfNextLevel = ( hi << 16 ) | lo;
|
||||
long physicalBlockOfNextLevel = (hi << 16) | lo;
|
||||
long offset = physicalBlockOfNextLevel * blockSize;
|
||||
|
||||
// System.out.println( ""+physicalBlockOfNextLevel );
|
||||
// System.out.println( "" );
|
||||
|
||||
reader.setPointerIndex( offset );
|
||||
Ext4IBlock intermediateBlock = new Ext4IBlock( reader, true );
|
||||
processIBlock( reader, superBlock, inodes, parent, isDirEntry2, intermediateBlock, monitor );
|
||||
reader.setPointerIndex(offset);
|
||||
Ext4IBlock intermediateBlock = new Ext4IBlock(reader, true);
|
||||
processIBlock(reader, superBlock, inodes, parent, isDirEntry2, intermediateBlock,
|
||||
monitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processDirEntry( BinaryReader reader,
|
||||
Ext4SuperBlock superBlock,
|
||||
Ext4Inode [] inodes,
|
||||
GFile parent,
|
||||
TaskMonitor monitor,
|
||||
Ext4Extent extent,
|
||||
long offset ) throws CancelledException, IOException {
|
||||
private void processDirEntry(BinaryReader reader, Ext4SuperBlock superBlock, Ext4Inode[] inodes,
|
||||
GFile parent, TaskMonitor monitor, Ext4Extent extent, long offset)
|
||||
throws CancelledException, IOException {
|
||||
|
||||
while ( ( reader.getPointerIndex( ) - offset ) < ( ( long ) extent.getEe_len( ) * blockSize ) ) {
|
||||
monitor.checkCanceled( );
|
||||
if ( reader.peekNextInt( ) == 0 ) {
|
||||
while ((reader.getPointerIndex() - offset) < ((long) extent.getEe_len() * blockSize)) {
|
||||
monitor.checkCanceled();
|
||||
if (reader.peekNextInt() == 0) {
|
||||
return;
|
||||
}
|
||||
Ext4DirEntry dirEnt = new Ext4DirEntry( reader );
|
||||
int childIndex = dirEnt.getInode( );
|
||||
Ext4Inode child = inodes[ childIndex ];
|
||||
if ( ( child.getI_mode( ) & Ext4Constants.I_MODE_MASK ) == Ext4Constants.S_IFDIR ) {
|
||||
String childName = dirEnt.getName( );
|
||||
long readerOffset = reader.getPointerIndex( );
|
||||
processDirectory( reader, superBlock, inodes, childIndex, childName, parent, monitor );
|
||||
reader.setPointerIndex( readerOffset );
|
||||
Ext4DirEntry dirEnt = new Ext4DirEntry(reader);
|
||||
int childIndex = dirEnt.getInode();
|
||||
Ext4Inode child = inodes[childIndex];
|
||||
if ((child.getI_mode() & Ext4Constants.I_MODE_MASK) == Ext4Constants.S_IFDIR) {
|
||||
String childName = dirEnt.getName();
|
||||
long readerOffset = reader.getPointerIndex();
|
||||
processDirectory(reader, superBlock, inodes, childIndex, childName, parent,
|
||||
monitor);
|
||||
reader.setPointerIndex(readerOffset);
|
||||
}
|
||||
else if ( ( child.getI_mode( ) & Ext4Constants.I_MODE_MASK ) == Ext4Constants.S_IFREG || ( child.getI_mode( ) & Ext4Constants.I_MODE_MASK ) == Ext4Constants.S_IFLNK ) {
|
||||
storeFile( inodes, dirEnt, parent );
|
||||
else if ((child.getI_mode() & Ext4Constants.I_MODE_MASK) == Ext4Constants.S_IFREG ||
|
||||
(child.getI_mode() & Ext4Constants.I_MODE_MASK) == Ext4Constants.S_IFLNK) {
|
||||
storeFile(inodes, dirEnt, parent);
|
||||
}
|
||||
else {
|
||||
throw new IOException( "Inode " + dirEnt.getInode( ) + " has unhandled file type: " + ( child.getI_mode( ) & 0xF000 ) );
|
||||
throw new IOException("Inode " + dirEnt.getInode() + " has unhandled file type: " +
|
||||
(child.getI_mode() & 0xF000));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processDirEntry2( BinaryReader reader,
|
||||
Ext4SuperBlock superBlock,
|
||||
Ext4Inode [] inodes,
|
||||
GFile parent,
|
||||
TaskMonitor monitor,
|
||||
Ext4Extent extent,
|
||||
long offset ) throws CancelledException, IOException {
|
||||
private void processDirEntry2(BinaryReader reader, Ext4SuperBlock superBlock,
|
||||
Ext4Inode[] inodes, GFile parent, TaskMonitor monitor, Ext4Extent extent, long offset)
|
||||
throws CancelledException, IOException {
|
||||
|
||||
while ( ( reader.getPointerIndex( ) - offset ) < ( ( long ) extent.getEe_len( ) * blockSize ) ) {
|
||||
monitor.checkCanceled( );
|
||||
if ( reader.peekNextInt( ) == 0 ) {
|
||||
while ((reader.getPointerIndex() - offset) < ((long) extent.getEe_len() * blockSize)) {
|
||||
monitor.checkCanceled();
|
||||
if (reader.peekNextInt() == 0) {
|
||||
return;
|
||||
}
|
||||
Ext4DirEntry2 dirEnt2 = new Ext4DirEntry2( reader );
|
||||
if ( dirEnt2.getFile_type( ) == Ext4Constants.FILE_TYPE_DIRECTORY ) {
|
||||
int childInode = dirEnt2.getInode( );
|
||||
String childName = dirEnt2.getName( );
|
||||
long readerOffset = reader.getPointerIndex( );
|
||||
processDirectory( reader, superBlock, inodes, childInode, childName, parent, monitor );
|
||||
reader.setPointerIndex( readerOffset );
|
||||
Ext4DirEntry2 dirEnt2 = new Ext4DirEntry2(reader);
|
||||
if (dirEnt2.getFile_type() == Ext4Constants.FILE_TYPE_DIRECTORY) {
|
||||
int childInode = dirEnt2.getInode();
|
||||
String childName = dirEnt2.getName();
|
||||
long readerOffset = reader.getPointerIndex();
|
||||
processDirectory(reader, superBlock, inodes, childInode, childName, parent,
|
||||
monitor);
|
||||
reader.setPointerIndex(readerOffset);
|
||||
}
|
||||
else if ( dirEnt2.getFile_type( ) == Ext4Constants.FILE_TYPE_REGULAR_FILE || dirEnt2.getFile_type( ) == Ext4Constants.FILE_TYPE_SYMBOLIC_LINK ) {
|
||||
storeFile( inodes, dirEnt2, parent );
|
||||
else if (dirEnt2.getFile_type() == Ext4Constants.FILE_TYPE_REGULAR_FILE ||
|
||||
dirEnt2.getFile_type() == Ext4Constants.FILE_TYPE_SYMBOLIC_LINK) {
|
||||
storeFile(inodes, dirEnt2, parent);
|
||||
}
|
||||
else {
|
||||
throw new IOException( "Inode " + dirEnt2.getInode( ) + " has unhandled file type: " + dirEnt2.getFile_type( ) );
|
||||
throw new IOException("Inode " + dirEnt2.getInode() + " has unhandled file type: " +
|
||||
dirEnt2.getFile_type());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void storeFile( Ext4Inode [] inodes, Ext4DirEntry dirEnt, GFile parent ) {
|
||||
int fileInodeNum = dirEnt.getInode( );
|
||||
Ext4Inode fileInode = inodes[ fileInodeNum ];
|
||||
long fileSize = ( fileInode.getI_size_high( ) << 32 ) | fileInode.getI_size_lo( );
|
||||
fsih.storeFileWithParent( dirEnt.getName( ), parent, -1, ( fileInode.getI_mode( ) & Ext4Constants.I_MODE_MASK ) == Ext4Constants.S_IFDIR, fileSize,
|
||||
new Ext4File( dirEnt.getName( ), fileInode ) );
|
||||
inodes[ fileInodeNum ] = null;
|
||||
private void storeFile(Ext4Inode[] inodes, Ext4DirEntry dirEnt, GFile parent) {
|
||||
int fileInodeNum = dirEnt.getInode();
|
||||
Ext4Inode fileInode = inodes[fileInodeNum];
|
||||
long fileSize = (fileInode.getI_size_high() << 32) | fileInode.getI_size_lo();
|
||||
fsih.storeFileWithParent(dirEnt.getName(), parent, -1,
|
||||
(fileInode.getI_mode() & Ext4Constants.I_MODE_MASK) == Ext4Constants.S_IFDIR, fileSize,
|
||||
new Ext4File(dirEnt.getName(), fileInode));
|
||||
inodes[fileInodeNum] = null;
|
||||
}
|
||||
|
||||
private void storeFile( Ext4Inode [] inodes, Ext4DirEntry2 dirEnt2, GFile parent ) {
|
||||
int fileInodeNum = dirEnt2.getInode( );
|
||||
Ext4Inode fileInode = inodes[ fileInodeNum ];
|
||||
if ( fileInode == null ) {
|
||||
private void storeFile(Ext4Inode[] inodes, Ext4DirEntry2 dirEnt2, GFile parent) {
|
||||
int fileInodeNum = dirEnt2.getInode();
|
||||
Ext4Inode fileInode = inodes[fileInodeNum];
|
||||
if (fileInode == null) {
|
||||
return;//TODO
|
||||
}
|
||||
long fileSize = ( fileInode.getI_size_high( ) << 32 ) | fileInode.getI_size_lo( );
|
||||
fsih.storeFileWithParent( dirEnt2.getName( ), parent, -1, dirEnt2.getFile_type( ) == Ext4Constants.FILE_TYPE_DIRECTORY, fileSize, new Ext4File( dirEnt2.getName( ), fileInode ) );
|
||||
inodes[ fileInodeNum ] = null;
|
||||
long fileSize = (fileInode.getI_size_high() << 32) | fileInode.getI_size_lo();
|
||||
fsih.storeFileWithParent(dirEnt2.getName(), parent, -1,
|
||||
dirEnt2.getFile_type() == Ext4Constants.FILE_TYPE_DIRECTORY, fileSize,
|
||||
new Ext4File(dirEnt2.getName(), fileInode));
|
||||
inodes[fileInodeNum] = null;
|
||||
}
|
||||
|
||||
private void processFile( BinaryReader reader, Ext4SuperBlock superBlock, Ext4Inode inode, TaskMonitor monitor ) {
|
||||
private void processFile(BinaryReader reader, Ext4SuperBlock superBlock, Ext4Inode inode,
|
||||
TaskMonitor monitor) {
|
||||
|
||||
}
|
||||
|
||||
@ -272,7 +270,7 @@ public class Ext4FileSystem implements GFileSystem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
Ext4File ext4File = fsih.getMetadata(file);
|
||||
if (ext4File == null) {
|
||||
return null;
|
||||
@ -337,7 +335,7 @@ public class Ext4FileSystem implements GFileSystem {
|
||||
throw new IOException("Not parent file for " + file);
|
||||
}
|
||||
symlinkDestPath =
|
||||
FSUtilities.appendPath(file.getParentFile().getPath(), symlinkDestPath);
|
||||
FSUtilities.appendPath(file.getParentFile().getPath(), symlinkDestPath);
|
||||
}
|
||||
|
||||
file = lookup(symlinkDestPath);
|
||||
@ -347,17 +345,17 @@ public class Ext4FileSystem implements GFileSystem {
|
||||
}
|
||||
|
||||
private InputStream getInputStream(Ext4Inode inode) throws IOException {
|
||||
int i_size_lo = inode.getI_size_lo( );
|
||||
int i_size_high = inode.getI_size_high( );
|
||||
long size = ( i_size_high << 32 ) | i_size_lo;
|
||||
int i_size_lo = inode.getI_size_lo();
|
||||
int i_size_high = inode.getI_size_high();
|
||||
long size = (i_size_high << 32) | i_size_lo;
|
||||
|
||||
boolean usesExtents = ( inode.getI_flags( ) & Ext4Constants.EXT4_EXTENTS_FL ) != 0;
|
||||
if ( usesExtents ) {
|
||||
Ext4IBlock i_block = inode.getI_block( );
|
||||
Ext4ExtentHeader header = i_block.getHeader( );
|
||||
if ( header.getEh_depth( ) == 0 ) {
|
||||
List< Ext4Extent > entries = i_block.getExtentEntries( );
|
||||
return concatenateExtents( entries, size );
|
||||
boolean usesExtents = (inode.getI_flags() & Ext4Constants.EXT4_EXTENTS_FL) != 0;
|
||||
if (usesExtents) {
|
||||
Ext4IBlock i_block = inode.getI_block();
|
||||
Ext4ExtentHeader header = i_block.getHeader();
|
||||
if (header.getEh_depth() == 0) {
|
||||
List<Ext4Extent> entries = i_block.getExtentEntries();
|
||||
return concatenateExtents(entries, size);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@ -369,65 +367,67 @@ public class Ext4FileSystem implements GFileSystem {
|
||||
*
|
||||
* TODO better memory management? currently loads entire file into memory.
|
||||
*/
|
||||
private InputStream concatenateExtents( List< Ext4Extent > entries, long actualSize ) throws IOException {
|
||||
if ( actualSize > Integer.MAX_VALUE ) {
|
||||
throw new IOException( "File is >2GB, too large to extract. Please report to Ghidra team." );
|
||||
private InputStream concatenateExtents(List<Ext4Extent> entries, long actualSize)
|
||||
throws IOException {
|
||||
if (actualSize > Integer.MAX_VALUE) {
|
||||
throw new IOException(
|
||||
"File is >2GB, too large to extract. Please report to Ghidra team.");
|
||||
}
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream( );
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
for ( int i = 0 ; i < entries.size( ) ; ++i ) {
|
||||
Ext4Extent extent = entries.get( i );
|
||||
for (int i = 0; i < entries.size(); ++i) {
|
||||
Ext4Extent extent = entries.get(i);
|
||||
|
||||
long low = extent.getEe_start_lo( ) & 0xffffffffL;
|
||||
long high = extent.getEe_start_hi( ) & 0xffffffffL;
|
||||
long blockNumber = ( high << 16 ) | low;
|
||||
long low = extent.getEe_start_lo() & 0xffffffffL;
|
||||
long high = extent.getEe_start_hi() & 0xffffffffL;
|
||||
long blockNumber = (high << 16) | low;
|
||||
long extentOffset = blockNumber * blockSize;
|
||||
long extentSize = ( extent.getEe_len( ) & 0xffffL ) * blockSize;
|
||||
long extentSize = (extent.getEe_len() & 0xffffL) * blockSize;
|
||||
|
||||
try {
|
||||
byte [] extentBytes = provider.readBytes( extentOffset, extentSize );
|
||||
baos.write( extentBytes );
|
||||
byte[] extentBytes = provider.readBytes(extentOffset, extentSize);
|
||||
baos.write(extentBytes);
|
||||
}
|
||||
catch ( IOException e ) {
|
||||
catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
return new ByteArrayInputStream( baos.toByteArray( ), 0, (int) actualSize );
|
||||
return new ByteArrayInputStream(baos.toByteArray(), 0, (int) actualSize);
|
||||
}
|
||||
|
||||
private Ext4Inode [] getInodes( BinaryReader reader,
|
||||
Ext4SuperBlock superBlock,
|
||||
Ext4GroupDescriptor [] groupDescriptors,
|
||||
boolean is64Bit,
|
||||
TaskMonitor monitor ) throws IOException, CancelledException {
|
||||
private Ext4Inode[] getInodes(BinaryReader reader, Ext4SuperBlock superBlock,
|
||||
Ext4GroupDescriptor[] groupDescriptors, boolean is64Bit, TaskMonitor monitor)
|
||||
throws IOException, CancelledException {
|
||||
|
||||
int inodeCount = superBlock.getS_inodes_count( );
|
||||
Ext4Inode [] inodes = new Ext4Inode [ inodeCount + 1 ];
|
||||
int inodeCount = superBlock.getS_inodes_count();
|
||||
Ext4Inode[] inodes = new Ext4Inode[inodeCount + 1];
|
||||
int inodeIndex = 1;
|
||||
|
||||
for ( int i = 0; i < groupDescriptors.length; i++ ) {
|
||||
monitor.checkCanceled( );
|
||||
long inodeTableBlockOffset = groupDescriptors[ i ].getBg_inode_table_lo( ) & 0xffffffffL;
|
||||
if ( is64Bit ) {
|
||||
inodeTableBlockOffset = ( groupDescriptors[ i ].getBg_inode_table_hi( ) << 32 ) | inodeTableBlockOffset;
|
||||
for (int i = 0; i < groupDescriptors.length; i++) {
|
||||
monitor.checkCanceled();
|
||||
long inodeTableBlockOffset = groupDescriptors[i].getBg_inode_table_lo() & 0xffffffffL;
|
||||
if (is64Bit) {
|
||||
inodeTableBlockOffset =
|
||||
(groupDescriptors[i].getBg_inode_table_hi() << 32) | inodeTableBlockOffset;
|
||||
}
|
||||
long offset = inodeTableBlockOffset * blockSize;
|
||||
reader.setPointerIndex( offset );
|
||||
int inodesPerGroup = superBlock.getS_inodes_per_group( );
|
||||
monitor.setMessage( "Reading inode table " + i + " of " + ( groupDescriptors.length - 1 ) + "..." );
|
||||
monitor.setMaximum( inodesPerGroup );
|
||||
monitor.setProgress( 0 );
|
||||
for ( int j = 0; j < inodesPerGroup; j++ ) {
|
||||
monitor.checkCanceled( );
|
||||
monitor.incrementProgress( 1 );
|
||||
reader.setPointerIndex(offset);
|
||||
int inodesPerGroup = superBlock.getS_inodes_per_group();
|
||||
monitor.setMessage(
|
||||
"Reading inode table " + i + " of " + (groupDescriptors.length - 1) + "...");
|
||||
monitor.setMaximum(inodesPerGroup);
|
||||
monitor.setProgress(0);
|
||||
for (int j = 0; j < inodesPerGroup; j++) {
|
||||
monitor.checkCanceled();
|
||||
monitor.incrementProgress(1);
|
||||
|
||||
Ext4Inode inode = new Ext4Inode( reader );
|
||||
offset = offset + superBlock.getS_inode_size( );
|
||||
reader.setPointerIndex( offset );
|
||||
Ext4Inode inode = new Ext4Inode(reader);
|
||||
offset = offset + superBlock.getS_inode_size();
|
||||
reader.setPointerIndex(offset);
|
||||
|
||||
inodes[ inodeIndex++ ] = inode; //inodes[ inodesPerGroup * i + j ] = inode;
|
||||
inodes[inodeIndex++] = inode; //inodes[ inodesPerGroup * i + j ] = inode;
|
||||
}
|
||||
}
|
||||
return inodes;
|
||||
|
@ -147,12 +147,11 @@ public class GZipFileSystem implements GFileSystem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
if (payload.equals(file)) {
|
||||
return FSUtilities.infoMapToString(getInfoMap());
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public Map<String, String> getInfoMap() {
|
||||
|
@ -81,9 +81,4 @@ public class Apple8900FileSystem extends GFileSystemBase {
|
||||
dataFile = GFileImpl.fromFilename(this, root, "DATA", false, header.getSizeOfData(), null);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -15,16 +15,16 @@
|
||||
*/
|
||||
package ghidra.file.formats.ios.dmg;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.formats.gfilesystem.*;
|
||||
import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A {@link GFileSystem} that uses an external DMG server process to parse DMG files
|
||||
* and presents the contents as a filesystem.
|
||||
@ -200,7 +200,7 @@ public class DmgClientFileSystem implements GFileSystem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile gFile, TaskMonitor monitor) throws IOException {
|
||||
public String getInfo(GFile gFile, TaskMonitor monitor) {
|
||||
monitor.addCancelledListener(listener);
|
||||
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
@ -111,11 +111,6 @@ public class DyldCacheFileSystem extends GFileSystemBase {
|
||||
}
|
||||
*/
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GFile> getListing(GFile directory) throws IOException {
|
||||
if (directory == null || directory.equals(root)) {
|
||||
|
@ -32,8 +32,8 @@ import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.CryptoException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
@FileSystemInfo(type = "ibootim", description = "iOS "
|
||||
+ iBootImConstants.SIGNATURE, factory = GFileSystemBaseFactory.class)
|
||||
@FileSystemInfo(type = "ibootim", description = "iOS " +
|
||||
iBootImConstants.SIGNATURE, factory = GFileSystemBaseFactory.class)
|
||||
public class iBootImFileSystem extends GFileSystemBase implements GIconProvider {
|
||||
|
||||
private iBootImHeader header;
|
||||
@ -59,19 +59,15 @@ public class iBootImFileSystem extends GFileSystemBase implements GIconProvider
|
||||
public Icon getIcon(GFile file, TaskMonitor monitor) throws IOException, CancelledException {
|
||||
File cacheFile = fsService.getFile(file.getFSRL(), monitor);
|
||||
try (InputStream cacheInputStream = new FileInputStream(cacheFile)) {
|
||||
GImageFormat format = (header.getFormat() == iBootImConstants.FORMAT_ARGB) ? GImageFormat.RGB_ALPHA_4BYTE
|
||||
: GImageFormat.GRAY_ALPHA_2BYTE;
|
||||
GImage image = new GImage(header.getWidth(), header.getHeight(), format, cacheInputStream,
|
||||
cacheFile.length());
|
||||
GImageFormat format =
|
||||
(header.getFormat() == iBootImConstants.FORMAT_ARGB) ? GImageFormat.RGB_ALPHA_4BYTE
|
||||
: GImageFormat.GRAY_ALPHA_2BYTE;
|
||||
GImage image = new GImage(header.getWidth(), header.getHeight(), format,
|
||||
cacheInputStream, cacheFile.length());
|
||||
return image.toPNG();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GFile> getListing(GFile directory) throws IOException {
|
||||
if (directory == null || directory.equals(root)) {
|
||||
|
@ -55,11 +55,6 @@ public class Img2FileSystem extends GFileSystemBase {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GFile> getListing(GFile directory) throws IOException {
|
||||
return (directory == null || directory.equals(root)) ? Arrays.asList(imageTypeFile)
|
||||
|
@ -57,11 +57,6 @@ public class IpswFileSystem extends GFileSystemBase {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InputStream getData(GFile file, TaskMonitor monitor)
|
||||
throws IOException, CancelledException, CryptoException {
|
||||
|
@ -92,7 +92,7 @@ public class CrushedPNGFileSystem extends GFileSystemBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
return png.toString();
|
||||
}
|
||||
|
||||
|
@ -118,12 +118,9 @@ public class PrelinkFileSystem extends GFileSystemBase implements GFileSystemPro
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
PrelinkMap info = fileToPrelinkInfoMap.get(file);
|
||||
if (info != null) {
|
||||
return info.toString();
|
||||
}
|
||||
return null;
|
||||
return (info != null) ? info.toString() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -160,7 +160,7 @@ public class ISO9660FileSystem extends GFileSystemBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
ISO9660Directory dir = fileToDirectoryMap.get(file);
|
||||
if (dir != null) {
|
||||
return dir.toString();
|
||||
|
@ -139,7 +139,7 @@ public class JavaClassDecompilerFileSystem implements GFileSystem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
if (fsIndexHelper.getPayloadFile().equals(file)) {
|
||||
Map<String, String> info = new HashMap<>();
|
||||
info.put("Class name", className);
|
||||
|
@ -110,7 +110,7 @@ public class OmfArchiveFileSystem implements GFileSystem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
OmfLibraryRecord.MemberHeader entry = fsih.getMetadata(file);
|
||||
return (entry == null) ? null : FSUtilities.infoMapToString(getInfoMap(entry));
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ public class SevenZipFileSystem extends GFileSystemBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
ISimpleInArchiveItem entry = map.get(file);
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
try {
|
||||
|
@ -15,15 +15,15 @@
|
||||
*/
|
||||
package ghidra.file.formats.sparseimage;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
import ghidra.formats.gfilesystem.*;
|
||||
import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A pseudo filesystem that contains a single file that is the decompressed contents
|
||||
* of the sparse container file.
|
||||
@ -101,7 +101,7 @@ public class SparseImageFileSystem implements GFileSystem {
|
||||
SparseImageDecompressor sid = new SparseImageDecompressor(provider, os);
|
||||
sid.decompress(monitor);
|
||||
}
|
||||
} , monitor);
|
||||
}, monitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -123,7 +123,7 @@ public class SparseImageFileSystem implements GFileSystem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
if (payload.equals(file)) {
|
||||
return FSUtilities.infoMapToString(getInfoMap());
|
||||
}
|
||||
|
@ -15,17 +15,17 @@
|
||||
*/
|
||||
package ghidra.file.formats.tar;
|
||||
|
||||
import ghidra.formats.gfilesystem.*;
|
||||
import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
|
||||
import ghidra.formats.gfilesystem.*;
|
||||
import ghidra.formats.gfilesystem.annotations.FileSystemInfo;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* TAR file system implementation.
|
||||
* <p>
|
||||
@ -169,12 +169,9 @@ public class TarFileSystem implements GFileSystem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
TarMetadata tmd = fsih.getMetadata(file);
|
||||
if (tmd == null) {
|
||||
throw new IOException("Unknown file " + file);
|
||||
}
|
||||
return FSUtilities.infoMapToString(getInfoMap(tmd.tarArchiveEntry));
|
||||
return (tmd != null) ? FSUtilities.infoMapToString(getInfoMap(tmd.tarArchiveEntry)) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -45,12 +45,9 @@ public class UniversalBinaryFileSystem extends GFileSystemBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
int index = list.indexOf(file);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
}
|
||||
return header.getArchitectures().get(index).toString();
|
||||
return (index != -1) ? header.getArchitectures().get(index).toString() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -79,7 +76,8 @@ public class UniversalBinaryFileSystem extends GFileSystemBase {
|
||||
Processor processor =
|
||||
CpuTypes.getProcessor(architecture.getCpuType(), architecture.getCpuSubType());
|
||||
int bitSize = CpuTypes.getProcessorBitSize(architecture.getCpuType());
|
||||
String name = processor + "-" + bitSize + "-cpu0x" + Integer.toHexString(architecture.getCpuSubType());
|
||||
String name = processor + "-" + bitSize + "-cpu0x" +
|
||||
Integer.toHexString(architecture.getCpuSubType());
|
||||
GFileImpl file =
|
||||
GFileImpl.fromFilename(this, root, name, false, architecture.getSize(), null);
|
||||
list.add(file);
|
||||
@ -100,7 +98,8 @@ public class UniversalBinaryFileSystem extends GFileSystemBase {
|
||||
|
||||
FatArch architecture = architectures.get(index);
|
||||
|
||||
return new BoundedInputStream(provider.getInputStream(architecture.getOffset()), architecture.getSize());
|
||||
return new BoundedInputStream(provider.getInputStream(architecture.getOffset()),
|
||||
architecture.getSize());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -98,7 +98,7 @@ public class YAFFS2FileSystem extends GFileSystemBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
return "YAFFS2, Yet Another Flash File System V2, commonly used for Android System and UserData images.";
|
||||
}
|
||||
|
||||
|
@ -117,9 +117,9 @@ public class ZipFileSystem implements GFileSystem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
ZipEntry zipEntry = fsIndexHelper.getMetadata(file);
|
||||
return FSUtilities.infoMapToString(getInfoMap(zipEntry));
|
||||
return (zipEntry != null) ? FSUtilities.infoMapToString(getInfoMap(zipEntry)) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -30,10 +30,8 @@ import ghidra.util.task.TaskMonitor;
|
||||
/**
|
||||
* TODO: Provide class-level documentation that describes what this file system does.
|
||||
*/
|
||||
@FileSystemInfo(
|
||||
type = "fstypegoeshere", // ([a-z0-9]+ only)
|
||||
description = "File system description goes here",
|
||||
factory = SkeletonFileSystem.MyFileSystemFactory.class)
|
||||
@FileSystemInfo(type = "fstypegoeshere", // ([a-z0-9]+ only)
|
||||
description = "File system description goes here", factory = SkeletonFileSystem.MyFileSystemFactory.class)
|
||||
public class SkeletonFileSystem implements GFileSystem {
|
||||
|
||||
private final FSRLRoot fsFSRL;
|
||||
@ -130,7 +128,7 @@ public class SkeletonFileSystem implements GFileSystem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo(GFile file, TaskMonitor monitor) throws IOException {
|
||||
public String getInfo(GFile file, TaskMonitor monitor) {
|
||||
MyMetadata metadata = fsih.getMetadata(file);
|
||||
return (metadata == null) ? null : FSUtilities.infoMapToString(getInfoMap(metadata));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user