Skip to content

Commit 039e321

Browse files
committed
Merge branch 'main' into release/10.2.x
2 parents b55a779 + 6869b5f commit 039e321

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+813
-225
lines changed

CHANGELOG.md

+17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
# ChangeLog
22

3+
## [10.2.4] - 2024-02-02
4+
### Added
5+
- Outline: add install_date, install_time and shutdown_time filled from registry
6+
- Outline: add computer_name to match outcome's
7+
8+
### Changed
9+
- Ntfs: improve behavior for compressed buffers when shadow copy block is lost
10+
- GetThis: go to next file in case of errors like unrecoverable deleted file
11+
- Yara: update to v4.4.0
12+
- Yara: replace Windows library with LibreSSL to benefit some features
13+
14+
### Fixed
15+
- ToolEmbed: remove unwanted warning message for run32 and run64 attributes
16+
- Fix breaking stdout redirection on unicode character
17+
- Yara: use yara.exe's workaround for block api (files are now entirely mapped)
18+
19+
320
## [10.2.3] - 2023-11-15
421
### Added
522
- Ntfs: Windows overlay file compression support with resident files

cmake/FindYara.cmake

+3
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,11 @@ find_library(YARA_LIB_RELEASE
3232

3333
add_library(yara::yara INTERFACE IMPORTED)
3434

35+
find_package(OpenSSL REQUIRED)
36+
3537
# Add 'OpenSSL::Crypto' if yara is built with openssl or libressl
3638
target_link_libraries(yara::yara
3739
INTERFACE
3840
debug ${YARA_LIB_DEBUG} optimized ${YARA_LIB_RELEASE}
41+
OpenSSL::Crypto
3942
)

cmake/Orc.cmake

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ add_compile_definitions(
1818
NOMINMAX
1919
BOOST_NO_SWPRINTF
2020
_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
21+
_SILENCE_ALL_MS_EXT_DEPRECATION_WARNINGS
2122
_7ZIP_ST
2223
)
2324

src/OrcCommand/Command/GetThis/GetThis_Output.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include "ToolVersion.h"
1818

1919
#include "Text/Fmt/Boolean.h"
20+
#include "Text/Fmt/ByteQuantity.h"
21+
#include "Text/Fmt/Limit.h"
2022
#include "Text/Print.h"
2123
#include "Text/Print/LocationSet.h"
2224
#include "Text/Print/OutputSpec.h"

src/OrcCommand/Command/GetThis/GetThis_Run.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "Archive/Appender.h"
4545
#include "Archive/7z/Archive7z.h"
4646
#include "Text/Fmt/Result.h"
47+
#include "Text/Fmt/Limit.h"
4748

4849
namespace fs = std::filesystem;
4950

src/OrcCommand/Command/WolfLauncher/WolfLauncher_Run.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,12 @@ HRESULT Orc::Command::Wolf::Main::CreateAndUploadOutline()
593593
SystemDetails::GetTimeStamp(strTimeStamp);
594594
writer->WriteNamed(L"timestamp", strTimeStamp);
595595

596+
{
597+
std::wstring computerName;
598+
SystemDetails::GetFullComputerName(computerName);
599+
writer->WriteNamed(L"computer_name", computerName);
600+
}
601+
596602
auto mothership_id = SystemDetails::GetParentProcessId();
597603
if (mothership_id)
598604
{

src/OrcCommand/Command/WolfLauncher/WolfTask.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ HRESULT WolfTask::ApplyNotification(
156156
{
157157
if (dwHangTime - m_dwLastReportedHang >= 30)
158158
{
159-
Log::Error(
159+
Log::Debug(
160160
L"{} (pid: {}): Hanged for {} secs",
161161
m_command,
162162
m_dwPID == 0 ? notification->GetProcessID() : m_dwPID,

src/OrcCommand/Log/UtilitiesLoggerConfiguration.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ std::optional<Log::Level> ParseLogLevel(const ConfigItem& item)
196196
const auto level = Log::ToLevel(item[CONFIGITEM_LOG_COMMON_LEVEL]);
197197
if (!level)
198198
{
199-
Log::Error(L"Failed to parse log level: {} [{}]", item[CONFIGITEM_LOG_COMMON_LEVEL], level.error());
199+
Log::Error(L"Failed to parse log level: {} [{}]", item[CONFIGITEM_LOG_COMMON_LEVEL].c_str(), level.error());
200200
return {};
201201
}
202202

@@ -214,7 +214,7 @@ std::optional<Log::Level> ParseBacktraceLevel(const ConfigItem& item)
214214
if (!level)
215215
{
216216
Log::Error(
217-
L"Failed to parse backtrace trigger level: {} [{}]", item[CONFIGITEM_LOG_COMMON_BACKTRACE], level.error());
217+
L"Failed to parse backtrace trigger level: {} [{}]", item[CONFIGITEM_LOG_COMMON_BACKTRACE].c_str(), level.error());
218218
return {};
219219
}
220220

src/OrcCommand/UtilitiesMain.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,14 @@ class UtilitiesMain
797797
virtual HRESULT GetConfigurationFromArgcArgv(int argc, const WCHAR* argv[]) = 0;
798798
virtual HRESULT CheckConfiguration() = 0;
799799

800+
//
801+
// Tool Description
802+
//
803+
static LPCWSTR ToolName() { return kOrcMetaNameW; }
804+
static LPCWSTR ToolDescription() { return L"DFIR-ORC Windows artefact collection tool"; }
805+
static LPCWSTR ToolVersion() { return kOrcVersionStringW; }
806+
807+
800808
//
801809
// Output handling
802810
//
@@ -850,7 +858,7 @@ class UtilitiesMain
850858
// TODO: FIXME
851859

852860
Cmd.LoadCommonExtensions();
853-
Cmd.PrintHeader(UtilityT::ToolName(), UtilityT::ToolDescription(), kOrcFileVerStringW);
861+
Cmd.PrintHeader(UtilityT::ToolName(), UtilityT::ToolDescription(), UtilityT::ToolVersion());
854862

855863
try
856864
{

src/OrcLib/Archive/7z/Archive7z.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ void Archive7z::Compress(
207207
}
208208

209209
CComQIPtr<IInArchive, &IID_IInArchive> archiverIn(archiver);
210-
CComPtr<InStreamAdapter> inStream = new InStreamAdapter(inputArchive);
210+
CComPtr<InStreamAdapter> inStream = new InStreamAdapter(inputArchive, true);
211211
CComPtr<ArchiveOpenCallback> archiveOpenCallback(new ArchiveOpenCallback());
212212
hr = archiverIn->Open(inStream, nullptr, archiveOpenCallback);
213213
if (FAILED(hr))

src/OrcLib/Archive/7z/ArchiveUpdateCallback.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ STDMETHODIMP ArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream*
227227
return S_OK;
228228
}
229229

230-
CComQIPtr<ISequentialInStream, &IID_ISequentialInStream> stream(new InStreamAdapter(item));
230+
CComQIPtr<ISequentialInStream, &IID_ISequentialInStream> stream(new InStreamAdapter(item, true));
231231
*pInStream = stream.Detach();
232232

233233
return S_OK;

src/OrcLib/Archive/7z/InStreamAdapter.cpp

+14-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,20 @@ STDMETHODIMP InStreamAdapter::Read(void* data, UInt32 size, UInt32* processedSiz
3030
}
3131

3232
// Transform S_FALSE to S_OK
33-
return SUCCEEDED(hr) ? S_OK : hr;
33+
if (SUCCEEDED(hr))
34+
{
35+
return S_OK;
36+
}
37+
38+
// Shadow copy volume Read can silently fail with some blocks and it will produce an error with ntfs compressed
39+
// files. That error should be ignored so the archive is not aborted.
40+
if (m_readErrorIsNotFailure)
41+
{
42+
Log::Error("Failed to read a stream to compress (archived item size: {}) [{}]", read, SystemError(hr));
43+
return S_OK;
44+
}
45+
46+
return hr;
3447
}
3548

3649
STDMETHODIMP InStreamAdapter::Seek(Int64 offset, UInt32 seekOrigin, UInt64* newPosition)

src/OrcLib/Archive/7z/InStreamAdapter.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ class InStreamAdapter
2525
, public CMyUnknownImp
2626
{
2727
public:
28-
InStreamAdapter(std::shared_ptr<ByteStream> outByteStream)
28+
InStreamAdapter(std::shared_ptr<ByteStream> outByteStream, bool readErrorIsNotFailure)
2929
: m_stream(std::move(outByteStream))
30+
, m_readErrorIsNotFailure(readErrorIsNotFailure)
3031
{
3132
}
3233

@@ -43,6 +44,7 @@ class InStreamAdapter
4344

4445
private:
4546
std::shared_ptr<ByteStream> m_stream;
47+
bool m_readErrorIsNotFailure;
4648
};
4749

4850
} // namespace Archive

src/OrcLib/Buffer.h

+17-2
Original file line numberDiff line numberDiff line change
@@ -811,7 +811,22 @@ class Buffer
811811
return 0;
812812

813813
ULONG len = 0;
814-
auto pCur = get();
814+
auto pCur = get_as<CHAR>();
815+
while (len < size() && *pCur != 0)
816+
{
817+
pCur++;
818+
len++;
819+
}
820+
return len;
821+
}
822+
823+
ULONG WStrNLen() const
824+
{
825+
if (empty())
826+
return 0;
827+
828+
ULONG len = 0;
829+
auto pCur = get_as<WCHAR>();
815830
while (len < size() && *pCur != 0)
816831
{
817832
pCur++;
@@ -902,7 +917,7 @@ class Buffer
902917
if (_size == 0)
903918
return std::wstring();
904919

905-
auto stringLength = StrNLen();
920+
auto stringLength = WStrNLen();
906921

907922
if (stringLength == 0)
908923
return std::wstring();

src/OrcLib/Configuration/ConfigFile.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ HRESULT ConfigFile::PrintConfig(const ConfigItem& config, DWORD dwIndent)
376376
(config.Flags & ConfigItem::MANDATORY) ? L"Mandatory" : L"Optional",
377377
config ? L"Present" : L"Absent");
378378
if (!config.empty())
379-
Log::Info(L"{}\tDATA: \"{}\" ", szIndent, config);
379+
Log::Info(L"{}\tDATA: \"{}\" ", szIndent, config.c_str());
380380

381381
std::for_each(begin(config.SubItems), end(config.SubItems), [dwIndent](const ConfigItem& item) {
382382
PrintConfig(item, dwIndent + 1);
@@ -388,7 +388,7 @@ HRESULT ConfigFile::PrintConfig(const ConfigItem& config, DWORD dwIndent)
388388
L"{}ATTRIBUTE: \"{}={}\" {} {}",
389389
szIndent,
390390
config.strName,
391-
config,
391+
config.c_str(),
392392
(config.Flags & ConfigItem::MANDATORY) ? L"Mandatory" : L"Optional",
393393
config ? L"Present" : L"Absent");
394394
break;
@@ -456,7 +456,7 @@ HRESULT ConfigFile::GetOutputDir(const ConfigItem& item, std::wstring& outputDir
456456
{
457457
if (FAILED(hr = ::GetOutputDir(item.c_str(), outputDir)))
458458
{
459-
Log::Error(L"Error in specified outputdir '{}' in config file [{}]", item, SystemError(hr));
459+
Log::Error(L"Error in specified outputdir '{}' in config file [{}]", item.c_str(), SystemError(hr));
460460
return hr;
461461
}
462462

@@ -477,7 +477,7 @@ HRESULT ConfigFile::GetOutputDir(const ConfigItem& item, std::wstring& outputDir
477477
{
478478
Log::Error(
479479
L"Invalid encoding for outputdir in config file: '{}' [{}]",
480-
item.SubItems[CONFIG_CSVENCODING],
480+
item.SubItems[CONFIG_CSVENCODING].c_str(),
481481
SystemError(hr));
482482
return hr;
483483
}
@@ -578,7 +578,7 @@ HRESULT ConfigFile::GetInputFile(const ConfigItem& item, std::wstring& inputFile
578578
{
579579
if (FAILED(hr = ::ExpandFilePath(item.c_str(), inputFile)))
580580
{
581-
Log::Error(L"Error in specified inputfile in config file '{}' [{}]", item, SystemError(hr));
581+
Log::Error(L"Error in specified inputfile in config file '{}' [{}]", item.c_str(), SystemError(hr));
582582
return hr;
583583
}
584584
}

src/OrcLib/EmbeddedResource_Embed.cpp

+15-16
Original file line numberDiff line numberDiff line change
@@ -261,11 +261,11 @@ class ResourceRegistry
261261
std::vector<ResourceRegistryItem> m_items;
262262
};
263263

264-
// Look into the current xml element for an attribute's name which match the provided regex
265-
Result<std::optional<XmlString>>
264+
// Look into the current xml element for an attributes name which match the provided regex
265+
Result<std::vector<XmlString>>
266266
GetXmlAttributeValueMatch(const CComPtr<IXmlReader>& reader, std::wstring_view attributeValueRegex)
267267
{
268-
std::vector<std::wstring> values;
268+
std::vector<XmlString> values;
269269

270270
UINT uiAttrCount = 0;
271271
HRESULT hr = reader->GetAttributeCount(&uiAttrCount);
@@ -277,7 +277,7 @@ GetXmlAttributeValueMatch(const CComPtr<IXmlReader>& reader, std::wstring_view a
277277

278278
if (uiAttrCount == 0L)
279279
{
280-
return std::optional<XmlString> {};
280+
return std::vector<XmlString>();
281281
}
282282

283283
hr = reader->MoveToFirstAttribute();
@@ -316,30 +316,28 @@ GetXmlAttributeValueMatch(const CComPtr<IXmlReader>& reader, std::wstring_view a
316316
}
317317

318318
std::wregex regex(attributeValueRegex.data(), std::regex_constants::icase);
319-
if (!std::regex_search(pValue, regex))
319+
if (std::regex_search(pValue, regex))
320320
{
321-
hr = reader->MoveToNextAttribute();
321+
UINT lineNumber = 0;
322+
hr = reader->GetLineNumber(&lineNumber);
322323
if (FAILED(hr))
323324
{
324325
XmlLiteExtension::LogError(hr, reader);
325-
return SystemError(hr);
326+
// return;
326327
}
327328

328-
continue;
329+
values.emplace_back(XmlString {{}, lineNumber, pValue});
329330
}
330331

331-
UINT lineNumber = 0;
332-
hr = reader->GetLineNumber(&lineNumber);
332+
hr = reader->MoveToNextAttribute();
333333
if (FAILED(hr))
334334
{
335335
XmlLiteExtension::LogError(hr, reader);
336-
// return;
336+
return SystemError(hr);
337337
}
338-
339-
return XmlString {{}, lineNumber, pValue};
340338
}
341339

342-
return std::optional<XmlString> {};
340+
return values;
343341
}
344342

345343
// Look into the current xml file for all attributes name which match the provided regex
@@ -380,9 +378,10 @@ GetXmlAttributesValueMatch(const std::shared_ptr<ByteStream>& xmlStream, std::ws
380378
continue;
381379
}
382380

383-
if ((*result).has_value())
381+
if (!result->empty())
384382
{
385-
values.emplace_back(std::move(**result));
383+
std::move(std::begin(*result), std::end(*result), std::back_inserter(values));
384+
result->clear();
386385
}
387386
}
388387

0 commit comments

Comments
 (0)