Skip to content

Commit

Permalink
Merge pull request #734 from avast/improvement-vmprotect-detection
Browse files Browse the repository at this point in the history
Add detection support for newer versions of VMProtect.
  • Loading branch information
s3rvac authored Apr 14, 2020
2 parents 49b6672 + 7ba8691 commit 9f36fb2
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 0 deletions.
19 changes: 19 additions & 0 deletions include/retdec/fileformat/types/sec_seg/sec_seg.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,25 @@ class SecSeg
bool getSizeOfOneEntry(unsigned long long &sEntrySize) const;
bool getMemory() const;
bool getEntropy(double &res) const;

/**
* Read bytes from the given offset as a number of the given type.
* @param sOffset Index from which the number should be read.
* @return The read number. Returns zero if the offset is out-of-bounds or
* if there are not enough bytes to read.
* @tparam NumberType Type of the number to read and return.
*/
template<typename NumberType>
NumberType getBytesAtOffsetAsNumber(unsigned long long sOffset) const
{
if(bytes.size() < sizeof(NumberType) || sOffset > bytes.size() - sizeof(NumberType))
{
return {};
}

auto rawBytes = bytes.data();
return *reinterpret_cast<const NumberType *>(&rawBytes[sOffset]);
}
/// @}

/// @name Getters of section or segment content
Expand Down
24 changes: 24 additions & 0 deletions src/cpdetect/compiler_detector/heuristics/pe_heuristics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1142,6 +1142,8 @@ void PeHeuristics::getExcelsiorHeuristics()
*/
void PeHeuristics::getVmProtectHeuristics()
{
static const std::size_t BLOCK_COUNT = 64;
static const std::size_t BLOCK_SIZE = BLOCK_COUNT * sizeof(std::uint32_t);
auto source = DetectionMethod::COMBINED;
auto strength = DetectionStrength::HIGH;

Expand All @@ -1150,6 +1152,28 @@ void PeHeuristics::getVmProtectHeuristics()
return;
}

for (std::size_t i = 0; i < noOfSections; ++i) {
auto& section = sections[i];
if (section->isCode() && section->getSizeInFile() > BLOCK_SIZE)
{
std::uint32_t checksum = 0;
// Compute the sum of first 64 DWORDs of the executable section.
for (std::size_t i = 0; i < BLOCK_COUNT; ++i)
{
checksum += section->getBytesAtOffsetAsNumber<std::uint32_t>(
i * sizeof(std::uint32_t)
);
}
// If the checksum is correct, the sample is 100% packed with
// VMProtect 2.04+.
if (checksum == 0xB7896EB5)
{
addPacker(source, strength, "VMProtect", "2.04+");
return;
}
}
}

if (toolInfo.entryPointOffset && canSearch)
{
const std::string sig = "54C70424--------9C60C74424----------C64424----887424--60;";
Expand Down
12 changes: 12 additions & 0 deletions support/yara_patterns/tools/pe/x86/packers.yara
Original file line number Diff line number Diff line change
Expand Up @@ -16643,6 +16643,18 @@ rule vmprotect_1x {
$1 at pe.entry_point
}

rule vmprotect_2x_xx {
meta:
tool = "P"
name = "VMProtect"
version = "2.04+"
pattern = "50F01FFDFD8??7926???B4??C2???07?4?????C?C??F?D2?6??19CBF0?9912?717??3635CA8A?7?0???F?C?D7D7??9E5?1?84E4???24??D45?5?C?04B9E?D?2?15?89??6?784?????D9??1?1?E??03?????446?6???3EC941E?6A??4?5????????8?C??8???2???0C8EB?C1?D?"
strings:
$1 = { 50 F0 1F FD FD 8? ?7 92 6? ?? B4 ?? C2 ?? ?0 7? 4? ?? ?? C? C? ?F ?D 2? 6? ?1 9C BF 0? 99 12 ?7 17 ?? 36 35 CA 8A ?7 ?0 ?? ?F ?C ?D 7D 7? ?9 E5 ?1 ?8 4E 4? ?? 24 ?? D4 5? 5? C? 04 B9 E? D? 2? 15 ?8 9? ?6 ?7 84 ?? ?? ?D 9? ?1 ?1 ?E ?? 03 ?? ?? ?4 46 ?6 ?? ?3 EC 94 1E ?6 A? ?4 ?5 ?? ?? ?? ?? 8? C? ?8 ?? ?2 ?? ?0 C8 EB ?C 1? D? }
condition:
@1 < pe.overlay.offset
}

rule vob_protectcd_uv {
meta:
tool = "P"
Expand Down

0 comments on commit 9f36fb2

Please sign in to comment.