Page MenuHomePhabricator

No OneTemporary

Size
18 KB
Referenced Files
None
Subscribers
None
diff --git a/trunk/dlgaddkey.cpp b/trunk/dlgaddkey.cpp
index f291c91..5f00cf6 100644
--- a/trunk/dlgaddkey.cpp
+++ b/trunk/dlgaddkey.cpp
@@ -1,379 +1,381 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include <QString>
#include <QStringList>
#include <QMessageBox>
#include <QRegExp>
#include <stdlib.h>
#include <QDebug>
#include "dlgaddkey.h"
#include "ui_dlgaddkey.h"
#include "registryhive.h"
#define MACROS_ENDIANNESS
#include "macros.h"
DlgAddKey::DlgAddKey(QWidget *p_parent,
QString key_name,
QString key_value_type,
QByteArray key_value) :
QDialog(p_parent),
ui(new Ui::DlgAddKey)
{
this->p_current_widget=NULL;
ui->setupUi(this);
// Create widgets
this->CreateValueWidgets();
// Set dialog title
if(key_name.isEmpty() && key_value_type.isEmpty() && key_value.isEmpty()) {
// If no values were passed, we consider this the ddd key dialog
this->setWindowTitle(tr("Add key"));
} else {
// If a value was passed, this is considered the edit key dialog
this->setWindowTitle(tr("Edit key"));
this->ui->EdtKeyName->setEnabled(false);
this->ui->CmbKeyType->setEnabled(false);
}
// Preload key value type values
QStringList value_types=RegistryHive::GetKeyValueTypes();
this->ui->CmbKeyType->addItems(value_types);
// Load values
if(!key_name.isEmpty()) this->ui->EdtKeyName->setText(key_name);
if(!key_value_type.isEmpty())
this->ui->CmbKeyType->setCurrentIndex(value_types.indexOf(key_value_type));
if(!key_value.isEmpty()) this->SetValueWidgetData(key_value,key_value_type);
}
DlgAddKey::~DlgAddKey() {
this->DestroyValueWidgets();
delete ui;
}
QString DlgAddKey::KeyName() {
return this->ui->EdtKeyName->text();
}
QString DlgAddKey::KeyType() {
return this->ui->CmbKeyType->currentText();
}
QByteArray DlgAddKey::KeyValue() {
return this->GetValueWidgetData();
}
void DlgAddKey::on_BtnCancel_clicked() {
this->reject();
}
void DlgAddKey::on_BtnOk_clicked() {
QString key_value_type=this->KeyType();
// Check entered data for correctness
if(key_value_type=="REG_MULTI_SZ") {
// REG_MULTI_SZ's can't contain empty sub-strings
QString cur_data=this->p_text_widget_text_edit->toPlainText();
QString new_data=cur_data;
// TODO: Do we need to check for \r\n on Windows??
new_data.replace(QRegExp("\n\n*"),"\n");
if(new_data.startsWith("\n")) new_data.remove(0,1);
if(new_data.endsWith("\n")) new_data.chop(1);
if(cur_data!=new_data) {
if(QMessageBox::information(this,
tr("Invalid data"),
tr("A REG_MULTI_SZ can not contain empty sub-strings! If you continue, they will be removed."),
QMessageBox::Yes,
QMessageBox::No)==QMessageBox::Yes)
{
this->p_text_widget_text_edit->setPlainText(new_data);
} else {
return;
}
}
} else if(key_value_type=="REG_DWORD" ||
key_value_type=="REG_DWORD_BIG_ENDIAN")
{
bool ok=false;
if(this->p_number_widget_rb_decimal->isChecked()) {
this->p_number_widget_line_edit->text().toInt(&ok);
} else {
// TODO: There seems to be a problem with 0xFFFFFFFF
this->p_number_widget_line_edit->text().toInt(&ok,16);
}
if(!ok) {
QMessageBox::information(this,
tr("Invalid data"),
tr("The value you entered could not be converted to a %1! Please correct it.").arg(key_value_type),
QMessageBox::Ok);
return;
}
} else if(key_value_type=="REG_QWORD") {
bool ok=false;
if(this->p_number_widget_rb_decimal->isChecked()) {
this->p_number_widget_line_edit->text().toLongLong(&ok);
} else {
this->p_number_widget_line_edit->text().toLongLong(&ok,16);
}
if(!ok) {
QMessageBox::information(this,
tr("Invalid data"),
tr("The value you entered could not be converted to a %1! Please correct it.").arg(key_value_type),
QMessageBox::Ok);
return;
}
}
this->accept();
}
void DlgAddKey::on_CmbKeyType_currentIndexChanged(const QString &arg1) {
// Remove current widget from grid layout
if(this->p_current_widget!=NULL) {
this->ui->gridLayout->removeWidget(this->p_current_widget);
this->p_current_widget->setVisible(false);
this->p_current_widget=NULL;
}
// Add new widget for selected value type
if(arg1=="REG_SZ" || arg1=="REG_EXPAND_SZ") {
// Line edit widget for REG_SZ and REG_EXPAND_SZ
this->ui->gridLayout->addWidget(this->p_line_widget,2,1);
this->p_current_widget=this->p_line_widget;
} else if(arg1=="REG_MULTI_SZ") {
// Text edit widget for REG_MULTI_SZ
this->ui->gridLayout->addWidget(this->p_text_widget,2,1);
this->p_current_widget=this->p_text_widget;
} else if(arg1=="REG_DWORD" ||
arg1=="REG_DWORD_BIG_ENDIAN" ||
arg1=="REG_QWORD")
{
// Number widget for REG_DWORD, REG_DWORD_BIG_ENDIAN and REG_QWORD
this->ui->gridLayout->addWidget(this->p_number_widget,2,1);
this->p_current_widget=this->p_number_widget;
} else if(arg1=="REG_BINARY" ||
arg1=="REG_LINK" ||
arg1=="REG_RESOURCE_LIST" ||
arg1=="REG_FULL_RESOURCE_DESC" ||
arg1=="REG_RESOURCE_REQ_LIST")
{
// Binary widget for all other types
this->ui->gridLayout->addWidget(this->p_binary_widget,2,1);
this->p_current_widget=this->p_binary_widget;
}
if(arg1!="REG_NONE") {
this->p_current_widget->setVisible(true);
this->ui->LblKeyValue->setVisible(true);
} else {
this->ui->LblKeyValue->setVisible(false);
}
}
void DlgAddKey::CreateValueWidgets() {
this->p_line_widget=new QWidget();
this->p_line_widget_layout=new QHBoxLayout(this->p_line_widget);
this->p_line_widget_line_edit=new QLineEdit();
this->p_line_widget->setContentsMargins(0,0,0,0);
this->p_line_widget_layout->setContentsMargins(0,0,0,0);
this->p_line_widget_layout->addWidget(this->p_line_widget_line_edit);
this->p_text_widget=new QWidget();
this->p_text_widget_layout=new QHBoxLayout(this->p_text_widget);
this->p_text_widget_text_edit=new QPlainTextEdit();
this->p_text_widget->setContentsMargins(0,0,0,0);
this->p_text_widget_layout->setContentsMargins(0,0,0,0);
this->p_text_widget_layout->addWidget(this->p_text_widget_text_edit);
this->p_number_widget=new QWidget();
this->p_number_widget_layout=new QHBoxLayout(this->p_number_widget);
this->p_number_widget_line_edit=new QLineEdit();
this->p_number_widget_rb_decimal=new QRadioButton(tr("Dec base"));
this->p_number_widget_rb_decimal->setChecked(true);
this->p_number_widget_rb_hex=new QRadioButton(tr("Hex base"));
this->p_number_widget->setContentsMargins(0,0,0,0);
this->p_number_widget_layout->setContentsMargins(0,0,0,0);
this->p_number_widget_layout->addWidget(this->p_number_widget_line_edit);
this->p_number_widget_layout->addWidget(this->p_number_widget_rb_decimal);
this->p_number_widget_layout->addWidget(this->p_number_widget_rb_hex);
this->p_binary_widget=new QWidget();
this->p_binary_widget_layout=new QHBoxLayout(this->p_binary_widget);
+ this->p_binary_widget_hex_edit=new HexEditWidget(this,false,false);
this->p_binary_widget->setContentsMargins(0,0,0,0);
this->p_binary_widget_layout->setContentsMargins(0,0,0,0);
+ this->p_binary_widget_layout->addWidget(this->p_binary_widget_hex_edit);
}
void DlgAddKey::DestroyValueWidgets() {
delete this->p_line_widget_line_edit;
delete this->p_line_widget_layout;
delete this->p_line_widget;
delete this->p_text_widget_text_edit;
delete this->p_text_widget_layout;
delete this->p_text_widget;
delete this->p_number_widget_rb_hex;
delete this->p_number_widget_rb_decimal;
delete this->p_number_widget_line_edit;
delete this->p_number_widget_layout;
delete this->p_number_widget;
+ delete this->p_binary_widget_hex_edit;
delete this->p_binary_widget_layout;
delete this->p_binary_widget;
}
void DlgAddKey::SetValueWidgetData(QByteArray &key_value,
QString &key_value_type)
{
if(key_value_type=="REG_SZ" || key_value_type=="REG_EXPAND_SZ") {
this->p_line_widget_line_edit->setText(
RegistryHive::KeyValueToString(key_value,
RegistryHive::StringToKeyValueType(
key_value_type)));
} else if(key_value_type=="REG_MULTI_SZ") {
// TODO: Identify if this is UTF16 or UTF8 and remember it
QStringList strings=RegistryHive::KeyValueToStringList(key_value,
key_value_type);
this->p_text_widget_text_edit->setPlainText(strings.join("\n"));
} else if(key_value_type=="REG_DWORD") {
this->p_number_widget_line_edit->setText(
RegistryHive::KeyValueToString(key_value,"int32"));
} else if(key_value_type=="REG_DWORD_BIG_ENDIAN") {
this->p_number_widget_line_edit->setText(
RegistryHive::KeyValueToString(key_value,"int32",0,0,false));
} else if(key_value_type=="REG_QWORD") {
this->p_number_widget_line_edit->setText(
RegistryHive::KeyValueToString(key_value,"int64",0,0,false));
} else if(key_value_type=="REG_BINARY" ||
key_value_type=="REG_LINK" ||
key_value_type=="REG_RESOURCE_LIST" ||
key_value_type=="REG_FULL_RESOURCE_DESC" ||
key_value_type=="REG_RESOURCE_REQ_LIST")
{
- // TODO: Set binary data
+ this->p_binary_widget_hex_edit->SetData(key_value);
}
}
QByteArray DlgAddKey::GetValueWidgetData() {
QString key_value_type=this->KeyType();
if(key_value_type=="REG_SZ" || key_value_type=="REG_EXPAND_SZ") {
// TODO: Wouldn't it be wise to let the user choose the encoding?
// Get data
QString data=this->p_line_widget_line_edit->text();
// Convert data to UTF16LE buffer
uint16_t *p_buf=NULL;
int buf_len=this->ToUtf16LeBuf(&p_buf,data.utf16(),data.size());
if(p_buf==NULL || buf_len==0) {
// TODO: Inform user there was an error???
return QByteArray("\x00\x00",2);
}
// Construct ByteArray, free buffer and return
QByteArray ret=QByteArray((char*)p_buf,buf_len);
free(p_buf);
return ret;
} else if(key_value_type=="REG_MULTI_SZ") {
// TODO: Wouldn't it be wise to let the user choose the encoding?
// TODO: When editing, use same encoding as original data
QString data=this->p_text_widget_text_edit->toPlainText();
// Convert data to UTF16LE buffer
uint16_t *p_buf=NULL;
int buf_len=this->ToUtf16LeBuf(&p_buf,data.utf16(),data.size());
if(p_buf==NULL || buf_len==0) {
// TODO: Inform user there was an error???
return QByteArray("\x00\x00\x00\x00",4);
}
// Replace \n in buffer with \0 which actually converts it to a
// semi REG_MULTI_SZ :-)
// TODO: Do we need to check for \r\n on Windows??
for(int i=0;i<buf_len;i++) {
if(LE32TOH(p_buf[i])==10) p_buf[i]=0;
}
// Construct ByteArray
QByteArray ret=QByteArray((char*)p_buf,buf_len);
// Append \0\0 to the end to make a real REG_MULTI_SZ
ret.append("\x00\x00",2);
// Free buffer and return
free(p_buf);
return ret;
} else if(key_value_type=="REG_DWORD" ||
key_value_type=="REG_DWORD_BIG_ENDIAN")
{
int32_t val;
if(this->p_number_widget_rb_decimal->isChecked()) {
val=this->p_number_widget_line_edit->text().toInt();
} else {
val=this->p_number_widget_line_edit->text().toInt(0,16);
}
if(key_value_type=="REG_DWORD") val=HTOLE32(val);
else val=HTOBE32(val);
return QByteArray((char*)&val,4);
} else if(key_value_type=="REG_QWORD") {
int64_t val;
if(this->p_number_widget_rb_decimal->isChecked()) {
val=this->p_number_widget_line_edit->text().toLongLong();
} else {
val=this->p_number_widget_line_edit->text().toLongLong(0,16);
}
val=HTOLE64(val);
return QByteArray((char*)&val,8);
} else if(key_value_type=="REG_BINARY" ||
key_value_type=="REG_LINK" ||
key_value_type=="REG_RESOURCE_LIST" ||
key_value_type=="REG_FULL_RESOURCE_DESC" ||
key_value_type=="REG_RESOURCE_REQ_LIST")
{
- // TODO: Return binary data
- return QByteArray();
+ return this->p_binary_widget_hex_edit->GetData();
}
return QByteArray();
}
int DlgAddKey::ToUtf16LeBuf(uint16_t **pp_buf,
const uint16_t *p_data,
int ascii_len)
{
// Calculate utf16 buffer size
// TODO: This fails if there are chars that need more than 16bit!!
int buf_len=(ascii_len*2)+2;
// Alloc buffer and set to 0x00h
*pp_buf=(uint16_t*)malloc(buf_len);
if(*pp_buf==NULL) return 0;
memset(*pp_buf,0,buf_len);
if(ascii_len==0) {
// Empty string, we're done (buffer contains \0\0)
return buf_len;
}
// Fill buffer with UTF16 string (ignoring \0\0 at the end)
memcpy(*pp_buf,p_data,buf_len-2);
// Make sure endianness is LE
for(int i=0;i<ascii_len;i++) {
(*pp_buf)[i]=HTOLE16((*pp_buf)[i]);
}
return buf_len;
}
diff --git a/trunk/dlgaddkey.h b/trunk/dlgaddkey.h
index 0bbd23c..136fad8 100644
--- a/trunk/dlgaddkey.h
+++ b/trunk/dlgaddkey.h
@@ -1,80 +1,83 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef DLGADDKEY_H
#define DLGADDKEY_H
#include <QDialog>
#include <QWidget>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QPlainTextEdit>
#include <QRadioButton>
#include <inttypes.h>
+#include "hexeditwidget.h"
+
namespace Ui {
class DlgAddKey;
}
class DlgAddKey : public QDialog {
Q_OBJECT
public:
explicit DlgAddKey(QWidget *p_parent=0,
QString key_name=QString(),
QString key_value_type=QString(),
QByteArray key_value=QByteArray());
~DlgAddKey();
QString KeyName();
QString KeyType();
QByteArray KeyValue();
private slots:
void on_BtnCancel_clicked();
void on_BtnOk_clicked();
void on_CmbKeyType_currentIndexChanged(const QString &arg1);
private:
Ui::DlgAddKey *ui;
QWidget *p_current_widget;
QWidget *p_line_widget;
QHBoxLayout *p_line_widget_layout;
QLineEdit *p_line_widget_line_edit;
QWidget *p_text_widget;
QHBoxLayout *p_text_widget_layout;
QPlainTextEdit *p_text_widget_text_edit;
QWidget *p_number_widget;
QHBoxLayout *p_number_widget_layout;
QLineEdit *p_number_widget_line_edit;
QRadioButton *p_number_widget_rb_decimal;
QRadioButton *p_number_widget_rb_hex;
QWidget *p_binary_widget;
QHBoxLayout *p_binary_widget_layout;
+ HexEditWidget *p_binary_widget_hex_edit;
void CreateValueWidgets();
void DestroyValueWidgets();
void SetValueWidgetData(QByteArray &key_value, QString &key_value_type);
QByteArray GetValueWidgetData();
int ToUtf16LeBuf(uint16_t **pp_buf,const uint16_t *p_data, int ascii_len);
};
#endif // DLGADDKEY_H

File Metadata

Mime Type
text/x-diff
Expires
Wed, Dec 25, 4:07 AM (43 m, 8 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1176940
Default Alt Text
(18 KB)

Event Timeline