This commit is contained in:
DavidXanatos 2024-08-28 13:46:34 +02:00
parent 7ad047b219
commit 379f7f7ada
8 changed files with 425 additions and 144 deletions

View File

@ -11,6 +11,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- The evaluation certificates are node lcoked to the HwID and for each HwID up to 3 certs can be requested.
- added "TerminateWhenExit"(bool,in Sandboxie-Plus.ini) to terminate all processes when Sandman exits for [#4171](https://github.com/sandboxie-plus/Sandboxie/issues/4171)
- added a question box to ask for Sandbox Import Location for [#4169](https://github.com/sandboxie-plus/Sandboxie/issues/4169)
- added UI option to configure DropConHostIntegrity
- added "HideNetworkAdapterMAC"(bool) return random value when applications tries to get network adapter mac address
### Fixed
- fixed and improved HideDiskSerialNumber option causes applications to crash [#4185](https://github.com/sandboxie-plus/Sandboxie/issues/4185)

View File

@ -26,6 +26,9 @@
#include <stdio.h>
#include <objbase.h>
#include "common/pool.h"
#include "common/map.h"
//---------------------------------------------------------------------------
// Functions
//---------------------------------------------------------------------------
@ -1387,6 +1390,259 @@ _FX RPC_STATUS NsiRpc_NsiRpcRegisterChangeNotification(LPVOID p1, LPVOID p2, L
}
//---------------------------------------------------------------------------
// Nsi_Init
//---------------------------------------------------------------------------
/*typedef struct _NPI_MODULEID {
USHORT Length;
NPI_MODULEID_TYPE Type;
union {
GUID Guid;
LUID IfLuid;
};
} NPI_MODULEID, *PNPI_MODULEID;*/
typedef ULONG (*P_NsiAllocateAndGetTable)(int a1, struct NPI_MODULEID* a2, unsigned int a3, void *a4, int a5, void *a6, int a7, void *a8, int a9, void *a10, int a11, DWORD *a12, int a13);
P_NsiAllocateAndGetTable __sys_NsiAllocateAndGetTable = NULL;
static ULONG Nsi_NsiAllocateAndGetTable(int a1, struct NPI_MODULEID* a2, unsigned int a3, void *a4, int a5, void *a6, int a7, void *a8, int a9, void *a10, int a11, DWORD *a12, int a13);
extern POOL* Dll_Pool;
static HASH_MAP Custom_NicMac;
static CRITICAL_SECTION Custom_NicMac_CritSec;
_FX BOOLEAN Nsi_Init(HMODULE module)
{
if (SbieApi_QueryConfBool(NULL, L"HideNetworkAdapterMAC", FALSE)) {
InitializeCriticalSection(&Custom_NicMac_CritSec);
map_init(&Custom_NicMac, Dll_Pool);
P_NsiAllocateAndGetTable NsiAllocateAndGetTable = (P_NsiAllocateAndGetTable)
Ldr_GetProcAddrNew(L"nsi.dll", L"NsiAllocateAndGetTable", "NsiAllocateAndGetTable");
SBIEDLL_HOOK(Nsi_, NsiAllocateAndGetTable);
}
return TRUE;
}
BYTE NPI_MS_NDIS_MODULEID[] = { 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x4A, 0x00, 0xEB, 0x1A, 0x9B, 0xD4, 0x11, 0x91, 0x23, 0x00, 0x50, 0x04, 0x77, 0x59, 0xBC };
/*
typedef struct _IP_ADAPTER_INFO {
struct _IP_ADAPTER_INFO* Next;
DWORD ComboIndex;
char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];
char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];
UINT AddressLength;
BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];
DWORD Index;
UINT Type;
UINT DhcpEnabled;
PIP_ADDR_STRING CurrentIpAddress;
IP_ADDR_STRING IpAddressList;
IP_ADDR_STRING GatewayList;
IP_ADDR_STRING DhcpServer;
BOOL HaveWins;
IP_ADDR_STRING PrimaryWinsServer;
IP_ADDR_STRING SecondaryWinsServer;
time_t LeaseObtained;
time_t LeaseExpires;
} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;
__int64 __fastcall AllocateAndGetAdaptersInfo(PIP_ADAPTER_INFO a1)
{
__int64 result; // rax
NET_IF_COMPARTMENT_ID CurrentThreadCompartmentId; // eax
unsigned int v4; // ecx
__int64 v5; // rdx
_QWORD *v6; // r13
unsigned int i; // r14d
__int64 v8; // r15
__int64 v9; // rdi
unsigned int v10; // edi
void *v11; // rax
__int64 v12; // rbx
int v13; // ecx
__int64 v14; // rax
unsigned int v15; // eax
int v16; // eax
__int64 pAddrEntry[10]; // [rsp+70h] [rbp+7h] BYREF
unsigned int Count; // [rsp+D0h] [rbp+67h] BYREF
unsigned int v19; // [rsp+D8h] [rbp+6Fh]
__int64 pOwnerEntry; // [rsp+E0h] [rbp+77h] BYREF
__int64 pStateEntry; // [rsp+E8h] [rbp+7Fh] BYREF
*a1 = 0i64; // Initialize the entire IP_ADAPTER_INFO structure to zero
result = NsiAllocateAndGetTable(
1i64,
&NPI_MS_NDIS_MODULEID,
1i64,
pAddrEntry,
8,
0i64,
0,
&pStateEntry,
656,
&pOwnerEntry,
568,
&Count,
0);
if ( !(_DWORD)result )
{
CurrentThreadCompartmentId = GetCurrentThreadCompartmentId();
v4 = Count;
v5 = CurrentThreadCompartmentId;
v19 = CurrentThreadCompartmentId;
v6 = a1;
for ( i = 0; i < v4; ++i )
{
v8 = 656i64 * i;
if ( *(_DWORD *)(v8 + pStateEntry) == (_DWORD)v5 )
{
v9 = 568i64 * i;
if ( (unsigned __int8)IsIpv4Interface(pAddrEntry[0] + 8i64 * i, *(unsigned __int16 *)(v9 + pOwnerEntry + 520)) )
{
v11 = (void *)MALLOC(0x2E0ui64); // Allocate memory for a new IP_ADAPTER_INFO structure
v12 = (__int64)v11;
if ( !v11 )
{
v10 = 8;
goto LABEL_9;
}
memset_0(v11, 0, 0x2E0ui64); // Clear the newly allocated structure
*(_QWORD *)(v12 + 720) = *(_QWORD *)(pAddrEntry[0] + 8i64 * i); // Set internal field (not directly related to IP_ADAPTER_INFO)
// Setting the AdapterName field
*(_OWORD *)(v12 + 704) = *(_OWORD *)(v9 + pOwnerEntry + 536);
// Setting the Index field
v13 = *(_DWORD *)(v8 + pStateEntry + 536);
*(_DWORD *)(v12 + 728) = v13;
// Setting the Type field
if ( v13 == 5 && (*(_DWORD *)(v8 + pStateEntry + 540) & 0xB) == 8 )
{
v16 = *(_DWORD *)(v12 + 728);
if ( (*(_DWORD *)(v9 + pOwnerEntry + 556) & 0x100) != 0 )
v16 = 1;
*(_DWORD *)(v12 + 728) = v16;
}
// Setting the ComboIndex field
*(_DWORD *)(v12 + 8) = *(_DWORD *)(v9 + pOwnerEntry);
// Setting the AdapterName field using ConvertGuidToStringA
ConvertGuidToStringA(v9 + pOwnerEntry + 536, v12 + 12, 260i64);
// Setting the Description field
v14 = *(unsigned __int16 *)(v9 + pOwnerEntry + 4) >> 1;
if ( (unsigned int)v14 > 0x100 )
v14 = 256i64;
*(_WORD *)(v9 + pOwnerEntry + 2 * v14 + 6) = 0;
StringCchPrintfA((STRSAFE_LPSTR)(v12 + 272), 0x84ui64, "%S", v9 + pOwnerEntry + 6);
// Setting the AddressLength field
v15 = 8; // Assignment of AddressLength start
if ( *(_WORD *)(v8 + pStateEntry + 548) < 8u )
v15 = *(unsigned __int16 *)(v8 + pStateEntry + 548);
*(_DWORD *)(v12 + 404) = v15; // AddressLength
// Setting the Address field
memcpy_0((void *)(v12 + 408), (const void *)(v8 + pStateEntry + 550), v15); // Address
// Setting the Index field
*(_DWORD *)(v12 + 416) = *(_DWORD *)(v9 + pOwnerEntry);
// Setting the Type field
*(_DWORD *)(v12 + 420) = *(unsigned __int16 *)(v9 + pOwnerEntry + 520);
*v6 = v12; // Link the current adapter info structure to the previous one
v6 = (_QWORD *)v12;
v10 = AddDhcpInfo(v12); // Call to set DHCP-related fields (DhcpEnabled, DhcpServer, LeaseObtained, LeaseExpires)
if ( v10 )
goto LABEL_9;
v10 = AddNetbtInfo(v12); // Call to set WINS-related fields (HaveWins, PrimaryWinsServer, SecondaryWinsServer)
if ( v10 )
goto LABEL_9;
}
v4 = Count;
v5 = v19;
}
}
// Setting additional fields like IP address list and Gateway list
v10 = AddUnicastAddressInfo(*a1, v5); // Call to set CurrentIpAddress and IpAddressList
if ( !v10 )
v10 = AddGatewayInfo(*a1); // Call to set GatewayList
LABEL_9:
NsiFreeTable(pAddrEntry[0], 0i64, pStateEntry, pOwnerEntry); // Free allocated resources
return v10;
}
return result;
}
*/
ULONG Nsi_NsiAllocateAndGetTable(int a1, struct NPI_MODULEID* NPI_MS_ID, unsigned int TcpInformationId, void **pAddrEntry, int SizeOfAddrEntry, void **a6, int a7, void **pStateEntry, int SizeOfStateEntry, void **pOwnerEntry, int SizeOfOwnerEntry, DWORD *Count, int a13)
{
ULONG ret = __sys_NsiAllocateAndGetTable(a1, NPI_MS_ID, TcpInformationId, pAddrEntry, SizeOfAddrEntry, a6, a7, pStateEntry, SizeOfStateEntry, pOwnerEntry, SizeOfOwnerEntry, Count, a13);
if (memcmp(NPI_MS_ID, NPI_MS_NDIS_MODULEID, 24) == 0 && pStateEntry)
{
typedef struct _STATE_ENTRY {
DWORD ThreadCompartmentId; // 0
BYTE Unknown1[18];
WCHAR AdapterName[256]; // 22
DWORD Index; // 536
DWORD Type; // 540
BYTE Unknown2[4];
WORD AddressLength; // 548
BYTE Address[8]; // 550
BYTE Unknown3[98];
} STATE_ENTRY, * PSTATE_ENTRY; // 656
//const int x = sizeof(STATE_ENTRY);
//const x1 = FIELD_OFFSET(STATE_ENTRY, Address);
for (DWORD i = 0; i < *Count; i++) {
PSTATE_ENTRY pEntry = (PSTATE_ENTRY)((BYTE*)*pStateEntry + i * sizeof(STATE_ENTRY));
if (pEntry->AddressLength) {
EnterCriticalSection(&Custom_NicMac_CritSec);
UINT_PTR key; // simple keys are sizeof(void*)
key = *(UINT_PTR*)&pEntry->Address[0];
#ifndef _WIN64 // on 32 bit platforms xor booth hafs to generate a 32 bit key
key ^= *(UINT_PTR*)&pEntry->Address[4];
#endif
void* lpMac = map_get(&Custom_NicMac, (void*)key);
if (lpMac)
memcpy(pEntry->Address, lpMac, 8);
else
{
*(DWORD*)&pEntry->Address[0] = Dll_rand();
*(DWORD*)&pEntry->Address[4] = Dll_rand();
map_insert(&Custom_NicMac, (void*)key, pEntry->Address, 8);
}
LeaveCriticalSection(&Custom_NicMac_CritSec);
}
}
}
return ret;
}

View File

@ -792,6 +792,8 @@ BOOLEAN Pdh_Init(HMODULE hmodule);
BOOLEAN NsiRpc_Init(HMODULE);
BOOLEAN Nsi_Init(HMODULE);
BOOLEAN Ntmarta_Init(HMODULE);
BOOLEAN Acscmonitor_Init(HMODULE);
@ -800,6 +802,7 @@ BOOLEAN DigitalGuardian_Init(HMODULE);
BOOLEAN ComDlg32_Init(HMODULE);
DWORD Dll_rand(void);
//---------------------------------------------------------------------------
// Functions (Config)

View File

@ -517,14 +517,6 @@ _FX LANGID Kernel_GetSystemDefaultLangID()
//Kernel_GetVolumeInformationByHandleW
//----------------------------------------------------------------------------
int Kernel_rand(void)
{
static unsigned long Kernel_seed = 1;
if(Kernel_seed == 1)
Kernel_seed = GetTickCount();
Kernel_seed = Kernel_seed * 1664525L + 1013904223L;
return Kernel_seed;
}
_FX BOOL Kernel_GetVolumeInformationByHandleW(HANDLE hFile, LPWSTR lpVolumeNameBuffer, DWORD nVolumeNameSize, LPDWORD lpVolumeSerialNumber,LPDWORD lpMaximumComponentLength, LPDWORD lpFileSystemFlags, LPWSTR lpFileSystemNameBuffer, DWORD nFileSystemNameSize)
{
@ -534,14 +526,16 @@ _FX BOOL Kernel_GetVolumeInformationByHandleW(HANDLE hFile, LPWSTR lpVolumeNameB
EnterCriticalSection(&Kernel_DiskSN_CritSec);
DWORD* lpCachedSerialNumber = map_get(&Kernel_DiskSN, &ourSerialNumber);
void* key = (void*)ourSerialNumber;
DWORD* lpCachedSerialNumber = map_get(&Kernel_DiskSN, key);
if (lpCachedSerialNumber)
*lpVolumeSerialNumber = *lpCachedSerialNumber;
else
{
*lpVolumeSerialNumber = Kernel_rand();
*lpVolumeSerialNumber = Dll_rand();
map_insert(&Kernel_DiskSN, &ourSerialNumber, lpVolumeSerialNumber, sizeof(DWORD));
map_insert(&Kernel_DiskSN, key, lpVolumeSerialNumber, sizeof(DWORD));
}
LeaveCriticalSection(&Kernel_DiskSN_CritSec);

View File

@ -218,6 +218,7 @@ static DLL Ldr_Dlls[] = {
{ L"uxtheme.dll", SH32_Init_UxTheme, 0}, // explorer.exe, SetWindowThemeAttribute
{ L"hnetcfg.dll", HNet_Init, 0}, // firewall workaround
{ L"winnsi.dll", NsiRpc_Init, 0}, // WININET workaround
{ L"nsi.dll", Nsi_Init, 0},
{ L"advpack.dll", Proc_Init_AdvPack, 0}, // fix for IE
{ L"dwrite.dll", Scm_DWriteDll, 0}, // hack for IE 9, make sure FontCache is running
{ L"ComDlg32.dll", ComDlg32_Init, 0}, // fix for opera.exe

View File

@ -953,4 +953,19 @@ _FX BOOLEAN SbieDll_IsReservedFileName(const WCHAR *name)
}
return FALSE;
}
//---------------------------------------------------------------------------
// Dll_rand
//---------------------------------------------------------------------------
DWORD Dll_rand(void)
{
static unsigned long seed = 1;
if(seed == 1)
seed = GetTickCount();
seed = seed * 1664525L + 1013904223L;
return seed;
}

View File

@ -45,7 +45,7 @@
<enum>QTabWidget::North</enum>
</property>
<property name="currentIndex">
<number>1</number>
<number>10</number>
</property>
<widget class="QWidget" name="tabGeneral">
<attribute name="title">
@ -4774,40 +4774,6 @@ This is done to prevent rogue processes inside the sandbox from creating a renam
<string>Privacy</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_29">
<item row="0" column="0">
<widget class="QLabel" name="lblPrivacyProtection">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string>Data Protection</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QCheckBox" name="chkHideFirmware">
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>Hide Firmware Information</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QToolButton" name="btnDumpFW">
<property name="toolTip">
<string>Dump the current Firmware Tables to HKCU\System\SbieCustom</string>
</property>
<property name="text">
<string>Dump FW Tables</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_72">
<property name="text">
@ -4815,65 +4781,7 @@ This is done to prevent rogue processes inside the sandbox from creating a renam
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QComboBox" name="cmbLangID"/>
</item>
<item row="2" column="3">
<spacer name="horizontalSpacer_24">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="chkHideSerial">
<property name="text">
<string>Hide Disk Serial Number</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="chkHideUID">
<property name="text">
<string>Obfuscate known unique identifiers in the registry</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="lblProcessHiding">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string>Process Hiding</string>
</property>
</widget>
</item>
<item row="6" column="1" colspan="3">
<widget class="QCheckBox" name="chkHideOtherBoxes">
<property name="text">
<string>Don't allow sandboxed processes to see processes running in other boxes</string>
</property>
</widget>
</item>
<item row="7" column="1" colspan="3">
<widget class="QCheckBox" name="chkHideNonSystemProcesses">
<property name="text">
<string>Don't allow sandboxed processes to see processes running outside any boxes</string>
</property>
</widget>
</item>
<item row="8" column="0" colspan="4">
<item row="9" column="0" colspan="4">
<widget class="QLabel" name="label_24">
<property name="text">
<string>Hide host processes from processes running in the sandbox.</string>
@ -4883,51 +4791,24 @@ This is done to prevent rogue processes inside the sandbox from creating a renam
</property>
</widget>
</item>
<item row="9" column="4">
<item row="7" column="1" colspan="3">
<widget class="QCheckBox" name="chkHideOtherBoxes">
<property name="text">
<string>Don't allow sandboxed processes to see processes running in other boxes</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QComboBox" name="cmbLangID"/>
</item>
<item row="10" column="4">
<widget class="QPushButton" name="btnAddProcess">
<property name="text">
<string>Add Process</string>
</property>
</widget>
</item>
<item row="10" column="4">
<spacer name="verticalSpacer_16">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="11" column="4">
<widget class="QCheckBox" name="chkShowHiddenProcTmpl">
<property name="text">
<string>Show Templates</string>
</property>
</widget>
</item>
<item row="12" column="4">
<widget class="QPushButton" name="btnDelProcess">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item row="13" column="0" colspan="4">
<widget class="QCheckBox" name="chkBlockWMI">
<property name="toolTip">
<string>Some programs read system details through WMI (a Windows built-in database) instead of normal ways. For example, &quot;tasklist.exe&quot; could get full processes list through accessing WMI, even if &quot;HideOtherBoxes&quot; is used. Enable this option to stop this behaviour.</string>
</property>
<property name="text">
<string>Prevent sandboxed processes from accessing system details through WMI (see tooltip for more info)</string>
</property>
</widget>
</item>
<item row="9" column="0" rowspan="4" colspan="4">
<item row="10" column="0" rowspan="4" colspan="4">
<widget class="QTreeWidget" name="treeHideProc">
<property name="minimumSize">
<size>
@ -4950,6 +4831,132 @@ This is done to prevent rogue processes inside the sandbox from creating a renam
</column>
</widget>
</item>
<item row="12" column="4">
<widget class="QCheckBox" name="chkShowHiddenProcTmpl">
<property name="text">
<string>Show Templates</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QToolButton" name="btnDumpFW">
<property name="toolTip">
<string>Dump the current Firmware Tables to HKCU\System\SbieCustom</string>
</property>
<property name="text">
<string>Dump FW Tables</string>
</property>
</widget>
</item>
<item row="13" column="4">
<widget class="QPushButton" name="btnDelProcess">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item row="8" column="1" colspan="3">
<widget class="QCheckBox" name="chkHideNonSystemProcesses">
<property name="text">
<string>Don't allow sandboxed processes to see processes running outside any boxes</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblPrivacyProtection">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string>Data Protection</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="lblProcessHiding">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string>Process Hiding</string>
</property>
</widget>
</item>
<item row="2" column="3">
<spacer name="horizontalSpacer_24">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="11" column="4">
<spacer name="verticalSpacer_16">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="14" column="0" colspan="4">
<widget class="QCheckBox" name="chkBlockWMI">
<property name="toolTip">
<string>Some programs read system details through WMI (a Windows built-in database) instead of normal ways. For example, &quot;tasklist.exe&quot; could get full processes list through accessing WMI, even if &quot;HideOtherBoxes&quot; is used. Enable this option to stop this behaviour.</string>
</property>
<property name="text">
<string>Prevent sandboxed processes from accessing system details through WMI (see tooltip for more info)</string>
</property>
</widget>
</item>
<item row="5" column="1" colspan="3">
<widget class="QCheckBox" name="chkHideUID">
<property name="text">
<string>Obfuscate known unique identifiers in the registry</string>
</property>
</widget>
</item>
<item row="4" column="1" colspan="3">
<widget class="QCheckBox" name="chkHideMac">
<property name="text">
<string>Hide Network Adapter MAC Address</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="3">
<widget class="QCheckBox" name="chkHideSerial">
<property name="text">
<string>Hide Disk Serial Number</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="QCheckBox" name="chkHideFirmware">
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>Hide Firmware Information</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabUsers">

View File

@ -107,6 +107,7 @@ void COptionsWindow::CreateAdvanced()
connect(ui.chkHideFirmware, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkHideUID, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkHideSerial, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.chkHideMac, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged()));
connect(ui.cmbLangID, SIGNAL(currentIndexChanged(int)), this, SLOT(OnAdvancedChanged()));
connect(ui.btnDumpFW, SIGNAL(clicked(bool)), this, SLOT(OnDumpFW()));
@ -291,6 +292,7 @@ void COptionsWindow::LoadAdvanced()
ui.chkHideFirmware->setChecked(m_pBox->GetBool("HideFirmwareInfo", false));
ui.chkHideUID->setChecked(m_pBox->GetBool("RandomRegUID",false));
ui.chkHideSerial->setChecked(m_pBox->GetBool("HideDiskSerialNumber", false));
ui.chkHideMac->setChecked(m_pBox->GetBool("HideNetworkAdapterMAC", false));
ui.cmbLangID->setCurrentIndex(ui.cmbLangID->findData(m_pBox->GetNum("CustomLCID", 0)));
@ -578,6 +580,7 @@ void COptionsWindow::SaveAdvanced()
WriteAdvancedCheck(ui.chkHideFirmware, "HideFirmwareInfo", "y", "");
WriteAdvancedCheck(ui.chkHideUID, "RandomRegUID", "y", "");
WriteAdvancedCheck(ui.chkHideSerial, "HideDiskSerialNumber", "y", "");
WriteAdvancedCheck(ui.chkHideMac, "HideNetworkAdapterMAC", "y", "");
int CustomLCID = ui.cmbLangID->currentData().toInt();
if (CustomLCID) m_pBox->SetNum("CustomLCID", CustomLCID);