extract uncompressed files
This commit is contained in:
parent
5a3a9c39ac
commit
982f8bc4a2
|
@ -19,6 +19,10 @@ public:
|
||||||
explicit ResourceExplorer(QWidget *parent = nullptr);
|
explicit ResourceExplorer(QWidget *parent = nullptr);
|
||||||
~ResourceExplorer();
|
~ResourceExplorer();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void extractButtonPressed();
|
||||||
|
void itemSelected(QTreeWidgetItem*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct MemoryMap {
|
struct MemoryMap {
|
||||||
const unsigned char* begin;
|
const unsigned char* begin;
|
||||||
|
@ -46,6 +50,7 @@ private:
|
||||||
std::vector<ResourceNode*> children;
|
std::vector<ResourceNode*> children;
|
||||||
|
|
||||||
bool isDir() const;
|
bool isDir() const;
|
||||||
|
bool isCompressed() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
using data = const unsigned char*;
|
using data = const unsigned char*;
|
||||||
|
|
|
@ -33,7 +33,7 @@ SOURCES += \
|
||||||
src/resourceexplorer.cpp
|
src/resourceexplorer.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
include/injector.cpp \
|
include/injector.h \
|
||||||
include/qtdebugger.h \
|
include/qtdebugger.h \
|
||||||
include/resourceexplorer.h
|
include/resourceexplorer.h
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ int main(int argc, char** argv) {
|
||||||
setenv("LD_PRELOAD", "/usr/local/lib/libqtdebugger.so", 1);
|
setenv("LD_PRELOAD", "/usr/local/lib/libqtdebugger.so", 1);
|
||||||
|
|
||||||
// should never return
|
// should never return
|
||||||
execv(argv[1], argv+1);
|
execvp(argv[1], argv+1);
|
||||||
|
|
||||||
fprintf(stderr, "exec failed: %s\n", strerror(errno));
|
fprintf(stderr, "exec failed: %s\n", strerror(errno));
|
||||||
return 2;
|
return 2;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QFileDialog>
|
||||||
|
|
||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
@ -59,6 +60,38 @@ ResourceExplorer::~ResourceExplorer() {
|
||||||
delete this->ui;
|
delete this->ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResourceExplorer::extractButtonPressed() {
|
||||||
|
QTreeWidgetItem* item = this->ui->treeWidget->currentItem();
|
||||||
|
if ( !item ) return;
|
||||||
|
|
||||||
|
ResourceNode* node = (ResourceNode*) item->data(0, Qt::UserRole).toULongLong();
|
||||||
|
if ( !node ) return;
|
||||||
|
|
||||||
|
QString saveFile = QFileDialog::getSaveFileName(this, "Extract File");
|
||||||
|
|
||||||
|
if ( saveFile.isEmpty() ) return;
|
||||||
|
|
||||||
|
QFile fileOut( saveFile );
|
||||||
|
if( !fileOut.open( QIODevice::WriteOnly | QIODevice::Truncate )) return;
|
||||||
|
|
||||||
|
QByteArray data = QByteArray::fromRawData( (const char*) node->start, node->size );
|
||||||
|
fileOut.write(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceExplorer::itemSelected(QTreeWidgetItem* newItem) {
|
||||||
|
if ( !newItem ) return;
|
||||||
|
|
||||||
|
ResourceNode* node = (ResourceNode*) newItem->data(0, Qt::UserRole).toULongLong();
|
||||||
|
|
||||||
|
if ( node ) {
|
||||||
|
if ( !node->isDir() && !node->isCompressed() ) {
|
||||||
|
this->ui->extractButton->setEnabled( true );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->ui->extractButton->setEnabled( false );
|
||||||
|
}
|
||||||
|
|
||||||
ResourceExplorer::ResourceNode::~ResourceNode() {
|
ResourceExplorer::ResourceNode::~ResourceNode() {
|
||||||
for ( ResourceNode* rn : this->children ) {
|
for ( ResourceNode* rn : this->children ) {
|
||||||
delete rn;
|
delete rn;
|
||||||
|
@ -69,8 +102,13 @@ bool ResourceExplorer::ResourceNode::isDir() const {
|
||||||
return this->flags & ResourceFlags::Directory;
|
return this->flags & ResourceFlags::Directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ResourceExplorer::ResourceNode::isCompressed() const {
|
||||||
|
return this->flags & ResourceFlags::Compressed;
|
||||||
|
}
|
||||||
|
|
||||||
void ResourceExplorer::rebuild() {
|
void ResourceExplorer::rebuild() {
|
||||||
this->ui->treeWidget->clear();
|
this->ui->treeWidget->clear();
|
||||||
|
this->ui->extractButton->setEnabled(false);
|
||||||
|
|
||||||
if ( !registeredResources || registeredResources->empty() ) {
|
if ( !registeredResources || registeredResources->empty() ) {
|
||||||
QTreeWidgetItem* resItem = new QTreeWidgetItem();
|
QTreeWidgetItem* resItem = new QTreeWidgetItem();
|
||||||
|
@ -253,6 +291,9 @@ QTreeWidgetItem* ResourceExplorer::resourceNodeToItem( ResourceNode* node, const
|
||||||
item->addChild( sub );
|
item->addChild( sub );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariant ptrVariant( (qulonglong) node );
|
||||||
|
item->setData(0, Qt::UserRole, ptrVariant);
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,16 @@
|
||||||
</column>
|
</column>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QPushButton" name="extractButton">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Extract</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenuBar" name="menubar">
|
<widget class="QMenuBar" name="menubar">
|
||||||
|
@ -58,5 +68,42 @@
|
||||||
<widget class="QStatusBar" name="statusbar"/>
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>extractButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>ResourceExplorer</receiver>
|
||||||
|
<slot>extractButtonPressed()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>421</x>
|
||||||
|
<y>550</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>450</x>
|
||||||
|
<y>646</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>treeWidget</sender>
|
||||||
|
<signal>currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)</signal>
|
||||||
|
<receiver>ResourceExplorer</receiver>
|
||||||
|
<slot>itemSelected(QTreeWidgetItem*)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>641</x>
|
||||||
|
<y>387</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>842</x>
|
||||||
|
<y>410</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
<slots>
|
||||||
|
<slot>extractButtonPressed()</slot>
|
||||||
|
<slot>itemSelected(QTreeWidgetItem*)</slot>
|
||||||
|
</slots>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
Loading…
Reference in New Issue