1 // copyright (c) 2019-2021 hors<horsicq@gmail.com>
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9
10 // The above copyright notice and this permission notice shall be included in all
11 // copies or substantial portions of the Software.
12
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 // SOFTWARE.
20 //
21 #include "searchsignatureswidget.h"
22 #include "ui_searchsignatureswidget.h"
23
SearchSignaturesWidget(QWidget * pParent)24 SearchSignaturesWidget::SearchSignaturesWidget(QWidget *pParent) :
25 XShortcutsWidget(pParent),
26 ui(new Ui::SearchSignaturesWidget)
27 {
28 ui->setupUi(this);
29 g_pDevice=nullptr;
30 g_pFilter=new QSortFilterProxyModel(this);
31 g_pModel=nullptr;
32 g_bInit=false;
33 g_scCopyName=nullptr;
34 g_scCopySignature=nullptr;
35 g_scCopyAddress=nullptr;
36 g_scCopyOffset=nullptr;
37 g_scHex=nullptr;
38
39 ui->tableViewResult->installEventFilter(this);
40 }
41
~SearchSignaturesWidget()42 SearchSignaturesWidget::~SearchSignaturesWidget()
43 {
44 g_watcher.waitForFinished();
45
46 delete ui;
47 }
48
setData(QIODevice * pDevice,XBinary::FT fileType,OPTIONS options,bool bAuto)49 void SearchSignaturesWidget::setData(QIODevice *pDevice, XBinary::FT fileType,OPTIONS options, bool bAuto)
50 {
51 this->g_pDevice=pDevice;
52 g_bInit=false;
53
54 QSet<XBinary::FT> stFileType=XBinary::getFileTypes(pDevice,true);
55 stFileType.insert(XBinary::FT_COM);
56 QList<XBinary::FT> listFileTypes=XBinary::_getFileTypeListFromSet(stFileType);
57
58 XBinary::FT _fileType=XFormats::setFileTypeComboBox(ui->comboBoxType,&listFileTypes,fileType);
59 XFormats::setEndianessComboBox(ui->comboBoxEndianness,_fileType);
60
61 ui->tableViewResult->setModel(nullptr);
62
63 g_fileType=fileType;
64
65 setOptions(options);
66
67 if(bAuto)
68 {
69 search();
70 }
71 }
72
setOptions(SearchSignaturesWidget::OPTIONS options)73 void SearchSignaturesWidget::setOptions(SearchSignaturesWidget::OPTIONS options)
74 {
75 g_options=options;
76 setSignaturesPath(options.sSignaturesPath);
77 }
78
getOptions()79 SearchSignaturesWidget::OPTIONS SearchSignaturesWidget::getOptions()
80 {
81 return g_options;
82 }
83
setSignaturesPath(QString sPath)84 void SearchSignaturesWidget::setSignaturesPath(QString sPath)
85 {
86 #if QT_VERSION >= 0x050300
87 const QSignalBlocker block(ui->comboBoxFile);
88 #else
89 const bool bBlocked1=ui->comboBoxFile->blockSignals(true);
90 #endif
91
92 ui->comboBoxFile->clear();
93
94 if(g_options.sUserSignature!="")
95 {
96 ui->comboBoxFile->addItem("",g_options.sUserSignature);
97 }
98
99 QList<QString> listFiles=XBinary::getAllFilesFromDirectory(XBinary::convertPathName(sPath),"*.db");
100
101 int nNumberOfFiles=listFiles.count();
102
103 for(int i=0;i<nNumberOfFiles;i++)
104 {
105 QString sFileName=listFiles.at(i);
106 ui->comboBoxFile->addItem(XBinary::getBaseFileName(sFileName),XBinary::convertPathName(sPath)+QDir::separator()+sFileName);
107 }
108
109 if(g_options.sUserSignature!="")
110 {
111 loadSignatures("");
112 }
113 else if(nNumberOfFiles)
114 {
115 loadSignatures(ui->comboBoxFile->currentData().toString());
116 }
117 #if QT_VERSION < 0x050300
118 ui->comboBoxFile->blockSignals(bBlocked1);
119 #endif
120 }
121
reload()122 void SearchSignaturesWidget::reload()
123 {
124 search();
125 }
126
getInitStatus()127 bool SearchSignaturesWidget::getInitStatus()
128 {
129 return g_bInit;
130 }
131
on_pushButtonSave_clicked()132 void SearchSignaturesWidget::on_pushButtonSave_clicked()
133 {
134 if(g_pModel)
135 {
136 QString sFileName=XBinary::getResultFileName(g_pDevice,QString("%1.txt").arg(tr("Signatures")));
137 sFileName=QFileDialog::getSaveFileName(this, tr("Save file"),sFileName, QString("%1 (*.txt);;%2 (*)").arg(tr("Text files"),tr("All files")));
138
139 if(!sFileName.isEmpty())
140 {
141 XOptions::saveTable(g_pModel,sFileName);
142 }
143 }
144 }
145
on_pushButtonSearch_clicked()146 void SearchSignaturesWidget::on_pushButtonSearch_clicked()
147 {
148 search();
149 }
150
on_tableViewResult_customContextMenuRequested(const QPoint & pos)151 void SearchSignaturesWidget::on_tableViewResult_customContextMenuRequested(const QPoint &pos)
152 {
153 QMenu contextMenu(this);
154
155 QAction actionCopyString(tr("Copy name"),this);
156 actionCopyString.setShortcut(getShortcuts()->getShortcut(XShortcuts::ID_SIGNATURES_COPYNAME));
157 connect(&actionCopyString,SIGNAL(triggered()),this,SLOT(_copyName()));
158 contextMenu.addAction(&actionCopyString);
159
160 QAction actionCopySignature(tr("Copy signature"),this);
161 actionCopySignature.setShortcut(getShortcuts()->getShortcut(XShortcuts::ID_SIGNATURES_COPYSIGNATURE));
162 connect(&actionCopySignature,SIGNAL(triggered()),this,SLOT(_copySignature()));
163 contextMenu.addAction(&actionCopySignature);
164
165 QAction actionCopyAddress(tr("Copy address"),this);
166 actionCopyAddress.setShortcut(getShortcuts()->getShortcut(XShortcuts::ID_SIGNATURES_COPYADDRESS));
167 connect(&actionCopyAddress,SIGNAL(triggered()),this,SLOT(_copyAddress()));
168 contextMenu.addAction(&actionCopyAddress);
169
170 QAction actionCopyOffset(tr("Copy offset"),this);
171 actionCopyOffset.setShortcut(getShortcuts()->getShortcut(XShortcuts::ID_SIGNATURES_COPYOFFSET));
172 connect(&actionCopyOffset,SIGNAL(triggered()),this,SLOT(_copyOffset()));
173 contextMenu.addAction(&actionCopyOffset);
174
175 QAction actionHex(tr("Hex"),this);
176
177 if(g_options.bMenu_Hex)
178 {
179 actionHex.setShortcut(getShortcuts()->getShortcut(XShortcuts::ID_SIGNATURES_HEX));
180 connect(&actionHex,SIGNAL(triggered()),this,SLOT(_hex()));
181 contextMenu.addAction(&actionHex);
182 }
183
184 contextMenu.exec(ui->tableViewResult->viewport()->mapToGlobal(pos));
185 }
186
_copyName()187 void SearchSignaturesWidget::_copyName()
188 {
189 qDebug("void SearchSignaturesWidget::_copyName()");
190
191 int nRow=ui->tableViewResult->currentIndex().row();
192
193 if((nRow!=-1)&&(g_pModel))
194 {
195 QModelIndex index=ui->tableViewResult->selectionModel()->selectedIndexes().at(2);
196
197 QString sString=ui->tableViewResult->model()->data(index).toString();
198
199 QApplication::clipboard()->setText(sString);
200 }
201 }
202
_copySignature()203 void SearchSignaturesWidget::_copySignature()
204 {
205 int nRow=ui->tableViewResult->currentIndex().row();
206
207 if((nRow!=-1)&&(g_pModel))
208 {
209 QModelIndex index=ui->tableViewResult->selectionModel()->selectedIndexes().at(0);
210
211 QString sString=ui->tableViewResult->model()->data(index,Qt::UserRole+MultiSearch::USERROLE_STRING).toString();
212
213 QApplication::clipboard()->setText(sString);
214 }
215 }
216
_copyAddress()217 void SearchSignaturesWidget::_copyAddress()
218 {
219 int nRow=ui->tableViewResult->currentIndex().row();
220
221 if((nRow!=-1)&&(g_pModel))
222 {
223 QModelIndex index=ui->tableViewResult->selectionModel()->selectedIndexes().at(0);
224
225 QString sString=ui->tableViewResult->model()->data(index).toString();
226
227 QApplication::clipboard()->setText(sString);
228 }
229 }
230
_copyOffset()231 void SearchSignaturesWidget::_copyOffset()
232 {
233 int nRow=ui->tableViewResult->currentIndex().row();
234
235 if((nRow!=-1)&&(g_pModel))
236 {
237 QModelIndex index=ui->tableViewResult->selectionModel()->selectedIndexes().at(1);
238
239 QString sString=ui->tableViewResult->model()->data(index).toString();
240
241 QApplication::clipboard()->setText(sString);
242 }
243 }
244
_hex()245 void SearchSignaturesWidget::_hex()
246 {
247 int nRow=ui->tableViewResult->currentIndex().row();
248
249 if((nRow!=-1)&&(g_pModel))
250 {
251 QModelIndex index=ui->tableViewResult->selectionModel()->selectedIndexes().at(0);
252
253 qint64 nOffset=ui->tableViewResult->model()->data(index,Qt::UserRole+MultiSearch::USERROLE_OFFSET).toLongLong();
254 qint64 nSize=ui->tableViewResult->model()->data(index,Qt::UserRole+MultiSearch::USERROLE_SIZE).toLongLong();
255
256 emit showHex(nOffset,nSize);
257 }
258 }
259
search()260 void SearchSignaturesWidget::search()
261 {
262 if(g_pDevice)
263 {
264 g_pOldModel=g_pModel;
265
266 g_pFilter->setSourceModel(nullptr);
267 ui->tableViewResult->setModel(nullptr);
268
269 XBinary::FT fileType=(XBinary::FT)(ui->comboBoxType->currentData().toInt());
270
271 MultiSearch::OPTIONS options={};
272
273 options.bMenu_Hex=g_options.bMenu_Hex;
274 options.memoryMap=XFormats::getMemoryMap(fileType,g_pDevice);
275 options.bSignature=true;
276 options.bIsBigEndian=(ui->comboBoxEndianness->currentData().toBool());
277 options.pListSignatureRecords=&g_listSignatureRecords;
278
279 QList<XBinary::MS_RECORD> listRecords;
280
281 QWidget *pParent=XOptions::getMainWidget(this);
282
283 DialogMultiSearchProcess dsp(pParent);
284 dsp.processSearch(g_pDevice,&listRecords,options,MultiSearch::TYPE_SIGNATURES);
285 dsp.exec();
286
287 DialogMultiSearchProcess dmp(pParent);
288 dmp.processModel(&listRecords,&g_pModel,options,MultiSearch::TYPE_SIGNATURES);
289 dmp.exec();
290
291 g_pFilter->setSourceModel(g_pModel);
292 ui->tableViewResult->setModel(g_pFilter);
293
294 ui->tableViewResult->setColumnWidth(0,120); // TODO
295 ui->tableViewResult->setColumnWidth(1,120); // TODO
296 ui->tableViewResult->setColumnWidth(2,120); // TODO
297
298 QFuture<void> future=QtConcurrent::run(this,&SearchSignaturesWidget::deleteOldModel);
299
300 g_watcher.setFuture(future);
301
302 // watcher.waitForFinished();
303
304 g_bInit=true;
305 }
306 }
307
deleteOldModel()308 void SearchSignaturesWidget::deleteOldModel()
309 {
310 delete g_pOldModel;
311 }
312
loadSignatures(QString sFileName)313 void SearchSignaturesWidget::loadSignatures(QString sFileName)
314 {
315 int nNumberOfSignatures=0;
316
317 g_listSignatureRecords.clear();
318
319 if(sFileName!="")
320 {
321 g_listSignatureRecords=MultiSearch::loadSignaturesFromFile(sFileName);
322 nNumberOfSignatures=g_listSignatureRecords.count();
323 }
324 else
325 {
326 // User signature
327 g_listSignatureRecords.append(MultiSearch::createSignature(g_options.sUserSignature,g_options.sUserSignature));
328 nNumberOfSignatures=1;
329 }
330
331 ui->labelInfo->setText(QString("%1: %2").arg(tr("Signatures"),QString::number(nNumberOfSignatures)));
332 }
333
on_comboBoxFile_currentIndexChanged(int index)334 void SearchSignaturesWidget::on_comboBoxFile_currentIndexChanged(int index)
335 {
336 Q_UNUSED(index)
337
338 QString sFileName=ui->comboBoxFile->currentData().toString();
339
340 loadSignatures(sFileName);
341 }
342
registerShortcuts(bool bState)343 void SearchSignaturesWidget::registerShortcuts(bool bState)
344 {
345 if(bState)
346 {
347 if(!g_scCopyName) g_scCopyName =new QShortcut(getShortcuts()->getShortcut(XShortcuts::ID_SIGNATURES_COPYNAME), this,SLOT(_copyName()));
348 if(!g_scCopySignature) g_scCopySignature =new QShortcut(getShortcuts()->getShortcut(XShortcuts::ID_SIGNATURES_COPYSIGNATURE), this,SLOT(_copySignature()));
349 if(!g_scCopyAddress) g_scCopyAddress =new QShortcut(getShortcuts()->getShortcut(XShortcuts::ID_SIGNATURES_COPYADDRESS), this,SLOT(_copyAddress()));
350 if(!g_scCopyOffset) g_scCopyOffset =new QShortcut(getShortcuts()->getShortcut(XShortcuts::ID_SIGNATURES_COPYOFFSET), this,SLOT(_copyOffset()));
351 if(!g_scHex) g_scHex =new QShortcut(getShortcuts()->getShortcut(XShortcuts::ID_SIGNATURES_HEX), this,SLOT(_hex()));
352 }
353 else
354 {
355 if(g_scCopyName) {delete g_scCopyName; g_scCopyName=nullptr;}
356 if(g_scCopySignature) {delete g_scCopySignature; g_scCopySignature=nullptr;}
357 if(g_scCopyAddress) {delete g_scCopyAddress; g_scCopyAddress=nullptr;}
358 if(g_scCopyOffset) {delete g_scCopyOffset; g_scCopyOffset=nullptr;}
359 if(g_scHex) {delete g_scHex; g_scHex=nullptr;}
360 }
361 }
362