mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-07-30 07:18:37 -09:00
GP-0: Removing unnecessary DMG NPE check, and some cleanup
(Closes #1740)
This commit is contained in:
@@ -27,7 +27,7 @@ public class GByteProvider implements Closeable {
|
||||
/**
|
||||
* Constructs a byte provider using the specified file and permissions string
|
||||
* @param file the file to open for random access
|
||||
* @param string indicating permissions used for open
|
||||
* @param permissions indicating permissions used for open
|
||||
* @throws FileNotFoundException if the file does not exist
|
||||
*/
|
||||
public GByteProvider(File file, String permissions) throws IOException {
|
||||
|
||||
@@ -31,24 +31,25 @@ public class AttributesFileParser {
|
||||
private GByteProvider provider;
|
||||
private BTreeRootNodeDescriptor root;
|
||||
|
||||
public AttributesFileParser( HFSXFileSystemHandler handler, String prefix ) throws IOException {
|
||||
public AttributesFileParser(HFSXFileSystemHandler handler, String prefix) throws IOException {
|
||||
|
||||
ImplHFSXFileSystemView hfsxFileSystemView = (ImplHFSXFileSystemView) handler.getFSView();
|
||||
HFSPlusVolumeHeader volumeHeader = hfsxFileSystemView.getHFSPlusVolumeHeader();
|
||||
|
||||
HFSPlusForkData attributes = volumeHeader.getAttributesFile();
|
||||
|
||||
File attributesFile = writeVolumeHeaderFile( hfsxFileSystemView, attributes, prefix + "_" + "attributesFile" );
|
||||
File attributesFile =
|
||||
writeVolumeHeaderFile(hfsxFileSystemView, attributes, prefix + "_" + "attributesFile");
|
||||
|
||||
provider = new GByteProvider( attributesFile );
|
||||
provider = new GByteProvider(attributesFile);
|
||||
|
||||
if ( attributesFile.length() == 0 ) {
|
||||
if (attributesFile.length() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
GBinaryReader reader = new GBinaryReader( provider, false );
|
||||
GBinaryReader reader = new GBinaryReader(provider, false);
|
||||
|
||||
root = new BTreeRootNodeDescriptor( reader );
|
||||
root = new BTreeRootNodeDescriptor(reader);
|
||||
}
|
||||
|
||||
public void dispose() throws IOException {
|
||||
@@ -58,9 +59,10 @@ public class AttributesFileParser {
|
||||
|
||||
private int getFileID(FSFile file) {
|
||||
try {
|
||||
HFSCommonFSFile hfsFile = (HFSCommonFSFile)file;
|
||||
HFSCommonFSFile hfsFile = (HFSCommonFSFile) file;
|
||||
CommonHFSCatalogFile catalogFile = hfsFile.getInternalCatalogFile();
|
||||
CommonHFSCatalogFile.HFSPlusImplementation hfsPlusCatalogFile = (CommonHFSCatalogFile.HFSPlusImplementation)catalogFile;
|
||||
CommonHFSCatalogFile.HFSPlusImplementation hfsPlusCatalogFile =
|
||||
(CommonHFSCatalogFile.HFSPlusImplementation) catalogFile;
|
||||
HFSPlusCatalogFile underlying = hfsPlusCatalogFile.getUnderlying();
|
||||
HFSCatalogNodeID fileID = underlying.getFileID();
|
||||
return fileID.toInt();
|
||||
@@ -70,49 +72,42 @@ public class AttributesFileParser {
|
||||
}
|
||||
}
|
||||
|
||||
private File writeVolumeHeaderFile( ImplHFSXFileSystemView hfsxFileSystemView,
|
||||
private File writeVolumeHeaderFile(ImplHFSXFileSystemView hfsxFileSystemView,
|
||||
HFSPlusForkData volumeHeaderFile,
|
||||
String volumeHeaderFileName ) throws IOException {
|
||||
String volumeHeaderFileName) throws IOException {
|
||||
|
||||
if (volumeHeaderFile == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
File file = File.createTempFile( "Ghidra_" + volumeHeaderFileName + "_", ".tmp" );
|
||||
File file = File.createTempFile("Ghidra_" + volumeHeaderFileName + "_", ".tmp");
|
||||
file.deleteOnExit();
|
||||
OutputStream out = new FileOutputStream( file );
|
||||
try {
|
||||
CommonHFSForkData fork = CommonHFSForkData.create( volumeHeaderFile );
|
||||
hfsxFileSystemView.extractForkToStream( fork, fork.getBasicExtents(), out, new NullProgressMonitor() {} );
|
||||
}
|
||||
finally {
|
||||
out.close();
|
||||
try (OutputStream out = new FileOutputStream(file)) {
|
||||
CommonHFSForkData fork = CommonHFSForkData.create(volumeHeaderFile);
|
||||
hfsxFileSystemView.extractForkToStream(fork, fork.getBasicExtents(), out,
|
||||
new NullProgressMonitor() {/*empty*/});
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
public DecmpfsHeader getDecmpfsHeader(FSFile file) throws IOException {
|
||||
public DecmpfsHeader getDecmpfsHeader(FSFile file) {
|
||||
|
||||
if ( root == null ) {
|
||||
if (root == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( map.get( file ) != null ) {
|
||||
return map.get( file );
|
||||
if (map.get(file) != null) {
|
||||
return map.get(file);
|
||||
}
|
||||
|
||||
int fileID = getFileID( file );
|
||||
int fileID = getFileID(file);
|
||||
|
||||
if ( fileID == -1 ) {
|
||||
if (fileID == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for ( BTreeNodeDescriptor node : root.getNodes() ) {
|
||||
for ( BTreeNodeRecord record : node.getRecords() ) {
|
||||
if ( record.getFileID() == fileID ) {
|
||||
for (BTreeNodeDescriptor node : root.getNodes()) {
|
||||
for (BTreeNodeRecord record : node.getRecords()) {
|
||||
if (record.getFileID() == fileID) {
|
||||
DecmpfsHeader header = record.getDecmpfsHeader();
|
||||
if ( header != null ) {
|
||||
map.put( file, header );
|
||||
if (header != null) {
|
||||
map.put(file, header);
|
||||
return header;
|
||||
}
|
||||
}
|
||||
@@ -121,5 +116,4 @@ public class AttributesFileParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class DmgFileReader implements Closeable {
|
||||
private List<FSFolder> rootFolders = new ArrayList<FSFolder>();
|
||||
private List<FileSystemHandler> fileSystemHandlers = new ArrayList<FileSystemHandler>();
|
||||
|
||||
public DmgFileReader( GByteProvider provider ) {
|
||||
public DmgFileReader(GByteProvider provider) {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
@@ -85,23 +85,23 @@ public class DmgFileReader implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
private void debug( byte [] plistData, String fileName ) {
|
||||
private void debug(byte[] plistData, String fileName) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
private void openPartition( Partition selectedPartition ) throws IOException {
|
||||
private void openPartition(Partition selectedPartition) throws IOException {
|
||||
long fsOffset = selectedPartition.getStartOffset();//getPmPyPartStart()+selectedPartition.getPmLgDataStart())*blockSize;
|
||||
long fsLength = selectedPartition.getLength();//getPmDataCnt()*blockSize;
|
||||
|
||||
FileSystemRecognizer fsr = new FileSystemRecognizer( rras, fsOffset );
|
||||
FileSystemRecognizer fsr = new FileSystemRecognizer(rras, fsOffset);
|
||||
FileSystemRecognizer.FileSystemType fsType = fsr.detectFileSystem();
|
||||
|
||||
if ( fsType == FileSystemRecognizer.FileSystemType.HFS_PLUS ||
|
||||
if (fsType == FileSystemRecognizer.FileSystemType.HFS_PLUS ||
|
||||
fsType == FileSystemRecognizer.FileSystemType.HFSX ||
|
||||
fsType == FileSystemRecognizer.FileSystemType.HFS ) {
|
||||
fsType == FileSystemRecognizer.FileSystemType.HFS) {
|
||||
|
||||
final FileSystemMajorType fsMajorType;
|
||||
switch ( fsType ) {
|
||||
switch (fsType) {
|
||||
case HFS:
|
||||
fsMajorType = FileSystemMajorType.APPLE_HFS;
|
||||
break;
|
||||
@@ -117,9 +117,9 @@ public class DmgFileReader implements Closeable {
|
||||
}
|
||||
|
||||
FileSystemHandlerFactory factory = fsMajorType.createDefaultHandlerFactory();
|
||||
if ( factory.isSupported( StandardAttribute.CACHING_ENABLED ) ) {
|
||||
factory.getCreateAttributes().
|
||||
setBooleanAttribute(StandardAttribute.CACHING_ENABLED,
|
||||
if (factory.isSupported(StandardAttribute.CACHING_ENABLED)) {
|
||||
factory.getCreateAttributes()
|
||||
.setBooleanAttribute(StandardAttribute.CACHING_ENABLED,
|
||||
true);
|
||||
}
|
||||
|
||||
@@ -135,15 +135,18 @@ public class DmgFileReader implements Closeable {
|
||||
DataLocator dataLocator = new ReadableStreamDataLocator(stage1);
|
||||
|
||||
FileSystemHandler fileSystemHandler = factory.createHandler(dataLocator);
|
||||
fileSystemHandlers.add( fileSystemHandler );
|
||||
fileSystemHandlers.add(fileSystemHandler);
|
||||
|
||||
rootFolders.add( fileSystemHandler.getRoot() );
|
||||
rootFolders.add(fileSystemHandler.getRoot());
|
||||
|
||||
if ( fileSystemHandler instanceof HFSXFileSystemHandler ) {
|
||||
parser = new AttributesFileParser( (HFSXFileSystemHandler)fileSystemHandler, fileSystemHandler.getRoot( ).getName( ) );
|
||||
if (fileSystemHandler instanceof HFSXFileSystemHandler) {
|
||||
parser = new AttributesFileParser((HFSXFileSystemHandler) fileSystemHandler,
|
||||
fileSystemHandler.getRoot().getName());
|
||||
}
|
||||
} else {
|
||||
System.err.println("UNKNOWN file system type. Can't Open filesystem. Suspect this is an APFS.\n");
|
||||
}
|
||||
else {
|
||||
System.err.println(
|
||||
"UNKNOWN file system type. Can't Open filesystem. Suspect this is an APFS.\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +158,7 @@ public class DmgFileReader implements Closeable {
|
||||
catch (Exception e) {
|
||||
//ignore
|
||||
}
|
||||
if ( parser != null ) {
|
||||
if (parser != null) {
|
||||
parser.dispose();
|
||||
parser = null;
|
||||
}
|
||||
@@ -163,34 +166,36 @@ public class DmgFileReader implements Closeable {
|
||||
rootFolders.clear();
|
||||
}
|
||||
|
||||
public InputStream getData( FSEntry entry ) throws IOException {
|
||||
if ( entry != null && entry.isFile() ) {
|
||||
FSFile fsFile = (FSFile)entry;
|
||||
public InputStream getData(FSEntry entry) throws IOException {
|
||||
if (entry != null && entry.isFile()) {
|
||||
FSFile fsFile = (FSFile) entry;
|
||||
FSFork mainFork = fsFile.getMainFork();
|
||||
if ( mainFork.getLength() > 0 ) {
|
||||
ReadableRandomAccessStream mainForkStream = mainFork.getReadableRandomAccessStream();
|
||||
if ( mainForkStream.length() != 0 ) {
|
||||
return new DmgInputStream( mainForkStream );
|
||||
if (mainFork.getLength() > 0) {
|
||||
ReadableRandomAccessStream mainForkStream =
|
||||
mainFork.getReadableRandomAccessStream();
|
||||
if (mainForkStream.length() != 0) {
|
||||
return new DmgInputStream(mainForkStream);
|
||||
}
|
||||
}
|
||||
else if ( mainFork.getLength() == 0 ) {
|
||||
else if (mainFork.getLength() == 0) {
|
||||
|
||||
FSFork resourceFork = fsFile.getForkByType( FSForkType.MACOS_RESOURCE );
|
||||
ReadableRandomAccessStream resourceForkStream = resourceFork.getReadableRandomAccessStream();
|
||||
FSFork resourceFork = fsFile.getForkByType(FSForkType.MACOS_RESOURCE);
|
||||
ReadableRandomAccessStream resourceForkStream =
|
||||
resourceFork.getReadableRandomAccessStream();
|
||||
|
||||
if ( parser == null ) {
|
||||
if (parser == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DecmpfsHeader decmpfsHeader = parser.getDecmpfsHeader( fsFile );
|
||||
DecmpfsHeader decmpfsHeader = parser.getDecmpfsHeader(fsFile);
|
||||
|
||||
if ( decmpfsHeader == null ) {
|
||||
if (decmpfsHeader == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( decmpfsHeader.getCompressionType() == DecmpfsCompressionTypes.CMP_Type3 ) {
|
||||
if (decmpfsHeader.getCompressionType() == DecmpfsCompressionTypes.CMP_Type3) {
|
||||
|
||||
if ( decmpfsHeader.getAttrBytes()[ 0 ] == -1 ) {
|
||||
if (decmpfsHeader.getAttrBytes()[0] == -1) {
|
||||
return new ByteArrayInputStream(decmpfsHeader.getAttrBytes(), 1,
|
||||
decmpfsHeader.getAttrBytes().length - 1);
|
||||
}
|
||||
@@ -198,7 +203,7 @@ public class DmgFileReader implements Closeable {
|
||||
return new RestrictedInflaterInputStream(decmpfsHeader.getAttrBytes(),
|
||||
(int) decmpfsHeader.getUncompressedSize());
|
||||
}
|
||||
else if ( decmpfsHeader.getCompressionType() == DecmpfsCompressionTypes.CMP_Type4 ) {
|
||||
else if (decmpfsHeader.getCompressionType() == DecmpfsCompressionTypes.CMP_Type4) {
|
||||
return decompressResourceFork(entry, resourceForkStream,
|
||||
(int) decmpfsHeader.getUncompressedSize());
|
||||
}
|
||||
@@ -207,11 +212,12 @@ public class DmgFileReader implements Closeable {
|
||||
return null;
|
||||
}
|
||||
|
||||
private InputStream decompressResourceFork( FSEntry entry,
|
||||
private InputStream decompressResourceFork(FSEntry entry,
|
||||
ReadableRandomAccessStream resourceForkStream,
|
||||
int expectedLength ) throws IOException {
|
||||
int expectedLength) throws IOException {
|
||||
|
||||
File tempFile = GFileUtilityMethods.writeTemporaryFile( new DmgInputStream( resourceForkStream ) );
|
||||
File tempFile =
|
||||
GFileUtilityMethods.writeTemporaryFile(new DmgInputStream(resourceForkStream));
|
||||
System.err.println(
|
||||
"dmg resource fork for " + entry.getName() + ": " + tempFile.getAbsolutePath());
|
||||
|
||||
@@ -313,28 +319,28 @@ public class DmgFileReader implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getInfo( String path ) {
|
||||
if ( path != null ) {
|
||||
DmgInfoGenerator info = new DmgInfoGenerator( this, path, parser );
|
||||
return info.getInformation( );
|
||||
public List<String> getInfo(String path) {
|
||||
if (path != null) {
|
||||
DmgInfoGenerator info = new DmgInfoGenerator(this, path, parser);
|
||||
return info.getInformation();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<FSEntry> getListing( String path ) {
|
||||
public List<FSEntry> getListing(String path) {
|
||||
List<FSEntry> list = new ArrayList<FSEntry>();
|
||||
if ( path == null || path.equals( "/" ) ) {
|
||||
for ( FileSystemHandler handler : fileSystemHandlers ) {
|
||||
list.add( handler.getRoot() );
|
||||
if (path == null || path.equals("/")) {
|
||||
for (FileSystemHandler handler : fileSystemHandlers) {
|
||||
list.add(handler.getRoot());
|
||||
}
|
||||
}
|
||||
else {
|
||||
FSEntry fileByPath = getFileByPath( path );
|
||||
if ( fileByPath != null ) {
|
||||
if ( fileByPath.isFolder() ) {
|
||||
FSEntry [] listEntries = fileByPath.asFolder().listEntries();
|
||||
for ( FSEntry entry : listEntries ) {
|
||||
list.add( entry );
|
||||
FSEntry fileByPath = getFileByPath(path);
|
||||
if (fileByPath != null) {
|
||||
if (fileByPath.isFolder()) {
|
||||
FSEntry[] listEntries = fileByPath.asFolder().listEntries();
|
||||
for (FSEntry entry : listEntries) {
|
||||
list.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -343,16 +349,18 @@ public class DmgFileReader implements Closeable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the given file system entry.
|
||||
* {@return the length of the given file system entry}
|
||||
* <p>
|
||||
* If the entry is actually a directory, then -1 is returned.
|
||||
*
|
||||
* @param entry the file system entry
|
||||
*/
|
||||
public long getLength( FSEntry entry ) {
|
||||
public long getLength(FSEntry entry) {
|
||||
if (entry != null && entry.isFile()) {
|
||||
FSFork mainFork = entry.asFile().getMainFork();
|
||||
if ( mainFork.getLength() > 0 ) {
|
||||
if (mainFork.getLength() > 0) {
|
||||
return mainFork.getLength();
|
||||
}
|
||||
try {
|
||||
if (parser != null) {
|
||||
DecmpfsHeader header = parser.getDecmpfsHeader(entry.asFile());
|
||||
if (header != null) {
|
||||
@@ -360,41 +368,42 @@ public class DmgFileReader implements Closeable {
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
return 1;//TODO lookup valid length in DECMPFS
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert path to string array.
|
||||
*
|
||||
* {@return a path converted to a string array}
|
||||
* <p>
|
||||
* For example, "/a/b/c.txt" will be converted to [ "a", "b", "c.txt" ].
|
||||
*
|
||||
* <p>
|
||||
* Note: the "a" will be stripped because it corresponds to the file system handler.
|
||||
*
|
||||
* @param path the path
|
||||
*/
|
||||
public String [] convertPathToArrayAndStripFileSystemName( String path ) {
|
||||
String [] splitPath = path.split( "/" );
|
||||
if ( splitPath.length <= 2 ) {
|
||||
return new String[ 0 ];
|
||||
public String[] convertPathToArrayAndStripFileSystemName(String path) {
|
||||
String[] splitPath = path.split("/");
|
||||
if (splitPath.length <= 2) {
|
||||
return new String[0];
|
||||
}
|
||||
String [] temp = new String[ splitPath.length - 2 ];
|
||||
System.arraycopy( splitPath, 2, temp, 0, splitPath.length - 2 );
|
||||
String[] temp = new String[splitPath.length - 2];
|
||||
System.arraycopy(splitPath, 2, temp, 0, splitPath.length - 2);
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the DMG file object for the corresponding path.
|
||||
* {@return the DMG file object for the corresponding path}
|
||||
* <p>
|
||||
* Path should contain the file system handler name.
|
||||
*
|
||||
* @param path the path
|
||||
*/
|
||||
public FSEntry getFileByPath( String path ) {
|
||||
if ( path == null || path.equals( "/" ) ) {//ROOT
|
||||
public FSEntry getFileByPath(String path) {
|
||||
if (path == null || path.equals("/")) {//ROOT
|
||||
return null;
|
||||
}
|
||||
for ( FileSystemHandler handler : fileSystemHandlers ) {
|
||||
FSEntry entry = handler.getEntry( convertPathToArrayAndStripFileSystemName( path ) );
|
||||
if ( entry != null ) {
|
||||
for (FileSystemHandler handler : fileSystemHandlers) {
|
||||
FSEntry entry = handler.getEntry(convertPathToArrayAndStripFileSystemName(path));
|
||||
if (entry != null) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
*/
|
||||
package mobiledevices.dmg.reader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -20,9 +19,7 @@ import mobiledevices.dmg.decmpfs.DecmpfsHeader;
|
||||
import mobiledevices.dmg.hfsplus.AttributesFileParser;
|
||||
|
||||
/**
|
||||
*
|
||||
* @see org.catacombae.hfsexplorer.gui.FSEntrySummaryPanel
|
||||
*
|
||||
*/
|
||||
class DmgInfoGenerator {
|
||||
private DmgFileReader fileSystem;
|
||||
@@ -60,16 +57,12 @@ class DmgInfoGenerator {
|
||||
appendFileID(infoList, file);
|
||||
|
||||
if (parser != null) {
|
||||
try {
|
||||
DecmpfsHeader decmpfsHeader = parser.getDecmpfsHeader(file);
|
||||
if (decmpfsHeader != null) {
|
||||
infoList.add(
|
||||
"Decmpfs Size: " + getSizeString(decmpfsHeader.getUncompressedSize()));
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (entry instanceof FSFolder) {
|
||||
FSFolder folder = (FSFolder) entry;
|
||||
@@ -201,21 +194,21 @@ class DmgInfoGenerator {
|
||||
}
|
||||
|
||||
private void calculateFolderSize(FSFolder folder, ObjectContainer<Long> result) {
|
||||
for (FSEntry entry : folder.listEntries()) {
|
||||
if (entry instanceof FSFile) {
|
||||
for (FSEntry e : folder.listEntries()) {
|
||||
if (e instanceof FSFile) {
|
||||
Long value = result.o;
|
||||
value += ((FSFile) entry).getMainFork().getLength();
|
||||
value += ((FSFile) e).getMainFork().getLength();
|
||||
result.o = value;
|
||||
}
|
||||
else if (entry instanceof FSFolder) {
|
||||
calculateFolderSize((FSFolder) entry, result);
|
||||
else if (e instanceof FSFolder) {
|
||||
calculateFolderSize((FSFolder) e, result);
|
||||
}
|
||||
else if (entry instanceof FSLink) {
|
||||
else if (e instanceof FSLink) {
|
||||
/* Do nothing. Symbolic link targets aren't part of the folder. */
|
||||
}
|
||||
else {
|
||||
System.err.println("FSEntrySummaryPanel.calculateFolderSize():" +
|
||||
" unexpected type " + entry.getClass());
|
||||
" unexpected type " + e.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user