Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F4325117
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Size
19 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/trunk/dlgaddkey.cpp b/trunk/dlgaddkey.cpp
index 96a408c..f291c91 100644
--- a/trunk/dlgaddkey.cpp
+++ b/trunk/dlgaddkey.cpp
@@ -1,239 +1,379 @@
-#include "dlgaddkey.h"
-#include "ui_dlgaddkey.h"
-
-#include "registryhive.h"
+/*******************************************************************************
+* 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()
-{
+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->setContentsMargins(0,0,0,0);
this->p_binary_widget_layout->setContentsMargins(0,0,0,0);
}
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_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") {
- p_line_widget_line_edit->setText(
+ 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: How should text be splitted? Ascii, utfxx ??????
- // p_text_widget_text_edit
+ // 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") {
- p_number_widget_line_edit->setText(
+ this->p_number_widget_line_edit->setText(
RegistryHive::KeyValueToString(key_value,"int32"));
} else if(key_value_type=="REG_DWORD_BIG_ENDIAN") {
- p_number_widget_line_edit->setText(
+ this->p_number_widget_line_edit->setText(
RegistryHive::KeyValueToString(key_value,"int32",0,0,false));
} else if(key_value_type=="REG_QWORD") {
- p_number_widget_line_edit->setText(
+ 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
}
}
QByteArray DlgAddKey::GetValueWidgetData() {
QString key_value_type=this->KeyType();
if(key_value_type=="REG_SZ" || key_value_type=="REG_EXPAND_SZ") {
- // TODO: Won't work! Normally UTF16_LE, but??????
- return QByteArray(p_line_widget_line_edit->text().toLocal8Bit().constData());
+ // 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: How should text be concatenated? Ascii, utfxx ??????
- // p_text_widget_text_edit
- return QByteArray();
- } else if(key_value_type=="REG_DWORD") {
- // TODO: When pressing ok, we need to check if conversion to number works!
- // TODO: We need host_to_le32 here!
+ // 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(p_number_widget_rb_decimal->isChecked()) {
- val=p_number_widget_line_edit->text().toInt();
+ if(this->p_number_widget_rb_decimal->isChecked()) {
+ val=this->p_number_widget_line_edit->text().toInt();
} else {
- val=p_number_widget_line_edit->text().toInt(0,16);
+ 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_DWORD_BIG_ENDIAN") {
- // TODO: Convert to big endian
- return QByteArray();
} else if(key_value_type=="REG_QWORD") {
- // TODO: We need host_to_le64 here!
int64_t val;
- if(p_number_widget_rb_decimal->isChecked()) {
- val=p_number_widget_line_edit->text().toLongLong();
+ if(this->p_number_widget_rb_decimal->isChecked()) {
+ val=this->p_number_widget_line_edit->text().toLongLong();
} else {
- val=p_number_widget_line_edit->text().toLongLong(0,16);
+ 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 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 a15c3c3..0bbd23c 100644
--- a/trunk/dlgaddkey.h
+++ b/trunk/dlgaddkey.h
@@ -1,57 +1,80 @@
+/*******************************************************************************
+* 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>
+
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;
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
Details
Attached
Mime Type
text/x-diff
Expires
Wed, Dec 25, 4:07 AM (46 m, 17 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1176936
Default Alt Text
(19 KB)
Attached To
Mode
rFRED fred
Attached
Detach File
Event Timeline
Log In to Comment