Example: TROJ_DASMIN.C 在 HKLM\Software\Microsoft\Windows\CurrentVersion\Run 寫入 MSConfigr = "%System%\JDBGMRG.EXE" 和 VirusCheckII = "%System%\AVIRCHK.EXE",因此每次系統啟動時,TROJ_DASMIN.C 就會被執行。
怎麼找出這些威脅呢?當然就是列舉所有的 autostart registry entries。這讓我想到 iterator patterns: provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation. [GoF]
有想法之後,該怎麼用 C++ 實做出來呢?首先先偷 [chrome]/trunk/src/base/win/registry.h,稍微修改一下,接著寫自己的 autostart_reg_iterator.h:
// The author disclaims copyright to this source code.底下是 .cc 檔:
#ifndef MODULE_AUTOSTART_REG_ITERATOR_H_
#define MODULE_AUTOSTART_REG_ITERATOR_H_
#pragma once
#include <windows.h>
#include "base/basictypes.h"
#include <vector>
namespace base {
namespace win {
class RegValueIterator;
}
}
namespace module {
// Iterates the autostart entries.
class AutostartRegIterator {
public:
AutostartRegIterator();
~AutostartRegIterator();
DWORD ValueCount() const;
// True while the iterator is valid.
bool Valid() const;
// Advances to the next entry.
void Next();
const wchar_t* Key() const;
const wchar_t* Name() const;
const wchar_t* Value() const;
DWORD ValueSize() const;
DWORD Type() const;
private:
// All iterators of autostart registry iterator.
std::vector<base::win::RegValueIterator*> iterators_;
// Current index of iterators.
int index_;
DISALLOW_COPY_AND_ASSIGN(AutostartRegIterator);
};
} // namespace module
#endif // MODULE_AUTOSTART_REG_ITERATOR_H_
// The author disclaims copyright to this source code.有些細節就略過了,重點就是如何用大的 iterator 包住小的 base::win::RegValueIterator iterators,如何實做 multiple traversals of aggregate objects。
#include "module/autostart_reg_iterator.h"
#include "module/reg_value_iterator_factory.h"
#include "base/win/reg.h"
namespace module {
using base::win::RegValueIterator;
const wchar_t* kAutostartRegKey[] = { ... };
AutostartRegIterator::AutostartRegIterator() {
RegValueIteratorFactory factory;
for (int i = 0; i != arraysize(kAutostartRegKey); ++i) {
iterators_.push_back(factory.Create(kAutostartRegKey[i]));
}
index_ = iterators_.size() - 1;
}
AutostartRegIterator::~AutostartRegIterator() {
for (int i = 0; i != arraysize(kAutostartRegKey); ++i) {
delete iterators_.at(i);
}
iterators_.clear();
}
DWORD AutostartRegIterator::ValueCount() const {
DWORD count = 0;
for (int i = 0; i != arraysize(kAutostartRegKey); ++i) {
count += iterators_.at(i)->ValueCount();
}
return count;
}
bool AutostartRegIterator::Valid() const {
return index_ > 0 || iterators_.at(0)->Valid();
}
void AutostartRegIterator::Next() {
if (index_ > 0 && !iterators_.at(index_)->Valid()) {
--index_;
} else {
iterators_.at(index_)->Next();
}
}
const wchar_t* AutostartRegIterator::Key() const {
return kAutostartRegKey[index_];
}
const wchar_t* AutostartRegIterator::Name() const {
return iterators_.at(index_)->Name();
}
const wchar_t* AutostartRegIterator::Value() const {
return iterators_.at(index_)->Value();
}
DWORD AutostartRegIterator::ValueSize() const {
return iterators_.at(index_)->ValueSize();
}
DWORD AutostartRegIterator::Type() const {
return iterators_.at(index_)->Type();
}
} // namespace module