aboutsummaryrefslogtreecommitdiff
path: root/core/processors.h
diff options
context:
space:
mode:
authorjmpoep <OriginalEntryPoint@qq.com>2023-12-07 16:51:07 +0800
committerjmpoep <OriginalEntryPoint@qq.com>2023-12-07 16:51:07 +0800
commit28008a746a31abb7909dd86cb0cd413ac8943b0b (patch)
treea30b74b8cad548048c3c1551d652828ab76fa9bd /core/processors.h
downloadvmprotect-3.5.1-master.tar
vmprotect-3.5.1-master.tar.gz
vmprotect-3.5.1-master.tar.bz2
vmprotect-3.5.1-master.zip
first commitHEADmaster
Diffstat (limited to 'core/processors.h')
-rw-r--r--core/processors.h1059
1 files changed, 1059 insertions, 0 deletions
diff --git a/core/processors.h b/core/processors.h
new file mode 100644
index 0000000..3309c57
--- /dev/null
+++ b/core/processors.h
@@ -0,0 +1,1059 @@
+#ifndef PROCESSORS_H
+#define PROCESSORS_H
+
+#include "osutils.h"
+
+class CommandLink;
+class Buffer;
+class CommandBlock;
+class IVirtualMachine;
+class SignatureList;
+class ICommand;
+class IFunction;
+class Folder;
+class MemoryManager;
+class CommandInfoList;
+class FunctionInfoList;
+class FunctionInfo;
+
+enum OperandType : uint16_t {
+ otNone = 0x0000,
+ otValue = 0x0001,
+ otRegistr = 0x0002,
+ otMemory = 0x0004,
+ otSegmentRegistr = 0x0008,
+ otControlRegistr = 0x0010,
+ otDebugRegistr = 0x0020,
+ otFPURegistr = 0x0040,
+ otHiPartRegistr = 0x0080,
+ otBaseRegistr = 0x0100,
+ otMMXRegistr = 0x0200,
+ otXMMRegistr = 0x0400,
+ // otAbsolute = 0x0800,
+};
+
+enum CommandOption {
+ roInverseFlag = 0x0001,
+ roLockPrefix = 0x0002,
+ roFar = 0x0004,
+ roVexPrefix = 0x0008,
+ roBreaked = 0x0010,
+ roClearOriginalCode = 0x0020,
+ roNeedCompile = 0x0040,
+ roCreateNewBlock = 0x0080,
+ roFillNop = 0x0100,
+ roInternal = 0x0200,
+ roNoNative = 0x0400,
+ roNoSaveFlags = 0x0800,
+ roWritable = 0x1000,
+ roUseAsJmp = 0x2000,
+ roNoProgress = 0x4000,
+ roExternal = 0x8000,
+ roNeedCRC = 0x10000,
+ roInvalidOpcode = 0x20000,
+ roDataSegment = 0x40000,
+ roImportSegment = 0x80000,
+};
+
+enum VMRegistr {
+ regEFX = 16,
+ regETX,
+ regERX,
+ regEIX,
+ regEmpty,
+ regExtended = 0x80
+};
+
+typedef uint32_t CommandType;
+
+enum LinkType {
+ ltNone,
+ ltSEHBlock,
+ ltFinallyBlock,
+ ltDualSEHBlock,
+ ltFilterSEHBlock,
+ ltJmp,
+ ltJmpWithFlag,
+ ltJmpWithFlagNSFS,
+ ltJmpWithFlagNSNA,
+ ltJmpWithFlagNSNS,
+ ltCall,
+ ltCase,
+ ltSwitch,
+ ltNative,
+ ltOffset,
+ ltGateOffset,
+ ltExtSEHBlock,
+ ltMemSEHBlock,
+ ltExtSEHHandler,
+ ltVBMemSEHBlock,
+ ltDelta
+};
+
+enum SectionOption {
+ rtNone = 0x0000,
+ rtLinkedToInt = 0x0001,
+ rtLinkedToExt = 0x0002,
+ rtLinkedFrom = 0x0004,
+ rtLinkedNext = 0x0008,
+ rtBeginSection = 0x0010,
+ rtEndSection = 0x0020,
+ rtCloseSection = 0x0040,
+ rtNoInverseResult = 0x0080,
+ rtInverseResult = 0x0100,
+ rtNoSaveFlags = 0x0200,
+ rtInverseWrite = 0x0400,
+ rtLinkedFromOtherType = 0x0800,
+ rtBackwardDirection = 0x1000
+};
+
+class IVMCommand: public IObject
+{
+public:
+ virtual void WriteToFile(IArchitecture &file) = 0;
+ virtual void Compile() = 0;
+ virtual size_t dump_size() const = 0;
+ virtual void set_address(uint64_t address) = 0;
+ virtual uint64_t address() const = 0;
+ virtual ICommand *owner() const = 0;
+ virtual bool is_end() const = 0;
+};
+
+enum VMCommandOption {
+ voNone = 0x0000,
+ voLinkCommand = 0x0001,
+ voFixup = 0x0002,
+ voSectionCommand = 0x0004,
+ voInverseValue = 0x0008,
+ voUseBeginSectionCryptor = 0x0010,
+ voUseEndSectionCryptor = 0x0020,
+ voBeginOffset = 0x0040,
+ voEndOffset = 0x0080,
+ voInitOffset = 0x0100,
+ voNoCRC = 0x0200,
+ voNoCryptValue = 0x0400
+};
+
+class BaseVMCommand: public IVMCommand
+{
+public:
+ explicit BaseVMCommand(ICommand *owner);
+ ~BaseVMCommand();
+ virtual ICommand *owner() const { return owner_; }
+ void set_owner(ICommand *owner) { owner_ = owner; }
+private:
+ ICommand *owner_;
+};
+
+enum CommentType : uint8_t {
+ ttUnknown,
+ ttNone,
+ ttJmp,
+ ttFunction,
+ ttImport,
+ ttString,
+ ttVariable,
+ ttComment,
+ ttExport,
+ ttMarker
+};
+
+struct CommentInfo {
+ std::string value;
+ CommentType type;
+ CommentInfo() : type(ttUnknown) {}
+ CommentInfo(CommentType type_, const std::string &value_) : type(type_), value(value_) {}
+ std::string display_value() const
+ {
+ std::string res;
+ if (value.empty())
+ return std::string();
+ return (value[0] < 5) ? value[0] + DisplayString(value.substr(1)) : DisplayString(value);
+ }
+};
+
+class AddressRange;
+class ISEHandler;
+struct CompileContext;
+
+class ICommand: public ObjectList<IVMCommand>
+{
+public:
+ virtual uint64_t address() const = 0;
+ virtual uint64_t next_address() const = 0;
+ virtual CommandType type() const = 0;
+ virtual std::string text() const = 0;
+ virtual CommentInfo comment() = 0;
+ virtual void set_comment(const CommentInfo &value) = 0;
+ virtual uint32_t options() const = 0;
+ virtual CommandLink *link() const = 0;
+ virtual void set_link(CommandLink *link) = 0;
+ virtual uint8_t dump(size_t index) const = 0;
+ virtual size_t dump_size() const = 0;
+ virtual std::string dump_str() const = 0;
+ virtual size_t original_dump_size() const = 0;
+ virtual size_t vm_dump_size() const = 0;
+ virtual void clear() = 0;
+ virtual void CompileToNative() = 0;
+ virtual void CompileLink(const CompileContext &ctx) = 0;
+ virtual void PrepareLink(const CompileContext &ctx) = 0;
+ virtual void CompileInfo() = 0;
+ virtual void set_operand_value(size_t operand_index, uint64_t value) = 0;
+ virtual void set_link_value(size_t link_index, uint64_t value) = 0;
+ virtual void set_jmp_value(size_t link_index, uint64_t value) = 0;
+ virtual void set_address(uint64_t address) = 0;
+ virtual uint64_t vm_address() const = 0;
+ virtual uint64_t ext_vm_address() const = 0;
+ virtual void set_vm_address(uint64_t address) = 0;
+ virtual void WriteToFile(IArchitecture &file) = 0;
+ virtual void ReadFromBuffer(Buffer &buffer, IArchitecture &file) = 0;
+ virtual size_t alignment() const = 0;
+ virtual CommandBlock *block() const = 0;
+ virtual void set_block(CommandBlock *block) = 0;
+ virtual void Rebase(uint64_t delta_base) = 0;
+ virtual IFunction *owner() const = 0;
+ virtual ICommand *Clone(IFunction *owner) const = 0;
+ virtual CommandLink *AddLink(int operand_index, LinkType type, ICommand *to_command) = 0;
+ virtual CommandLink *AddLink(int operand_index, LinkType type, uint64_t to_address = 0) = 0;
+ virtual void include_section_option(SectionOption option) = 0;
+ virtual uint32_t section_options() const = 0;
+ virtual ISEHandler *seh_handler() const = 0;
+ virtual AddressRange *address_range() const = 0;
+ virtual void set_address_range(AddressRange *address_range) = 0;
+ virtual bool Merge(ICommand *command) = 0;
+ virtual bool is_data() const = 0;
+ virtual bool is_end() const = 0;
+ virtual void include_option(CommandOption value) = 0;
+ virtual void exclude_option(CommandOption value) = 0;
+ virtual std::string display_address() const = 0;
+ virtual void set_tag(uint8_t tag) = 0;
+ virtual uint8_t tag() const = 0;
+
+ using IObject::CompareWith;
+ int CompareWith(const ICommand &obj) const
+ {
+ if (address() < obj.address())
+ return -1;
+ if (address() > obj.address())
+ return 1;
+ return 0;
+ }
+#ifdef CHECKED
+ virtual bool check_hash() const = 0;
+#endif
+};
+
+enum AccessType : uint8_t {
+ atRead,
+ atWrite
+};
+
+class CommandInfo : public IObject
+{
+public:
+ explicit CommandInfo(CommandInfoList *owner, AccessType type, uint8_t value, OperandType operand_type, OperandSize size);
+ ~CommandInfo();
+ AccessType type() const { return type_; }
+ OperandType operand_type() const { return operand_type_; }
+ uint8_t value() const { return value_; }
+ OperandSize size() const { return size_; }
+ void set_size(OperandSize size) { size_ = size; }
+private:
+ CommandInfoList *owner_;
+ OperandType operand_type_;
+ AccessType type_;
+ uint8_t value_;
+ OperandSize size_;
+};
+
+class CommandInfoList: public ObjectList<CommandInfo>
+{
+public:
+ explicit CommandInfoList();
+ virtual void Add(AccessType access_type, uint8_t value, OperandType operand_type, OperandSize size);
+ void set_need_flags(uint16_t flags) { need_flags_ = flags; }
+ void set_change_flags(uint16_t flags) { change_flags_ = flags; }
+ CommandInfo *GetInfo(AccessType type, OperandType operand_type, uint8_t value) const;
+ CommandInfo *GetInfo(AccessType type, OperandType operand_type) const;
+ CommandInfo *GetInfo(OperandType operand_type) const;
+ uint16_t need_flags() const { return need_flags_; }
+ uint16_t change_flags() const { return change_flags_; }
+ virtual void clear();
+private:
+ uint16_t need_flags_;
+ uint16_t change_flags_;
+};
+
+class BaseCommand: public ICommand
+{
+public:
+ explicit BaseCommand(IFunction *owner);
+ explicit BaseCommand(IFunction *owner, const std::string &value);
+ explicit BaseCommand(IFunction *owner, const os::unicode_string &value);
+ explicit BaseCommand(IFunction *owner, const Data &value);
+ explicit BaseCommand(IFunction *owner, const BaseCommand &src);
+ ~BaseCommand();
+ virtual uint64_t next_address() const { return address() + dump_size(); }
+ virtual uint8_t dump(size_t index) const { return dump_[index]; }
+ uint64_t dump_value(size_t pos, OperandSize size) const;
+ Data &raw_dump(void) { return dump_; };
+ virtual size_t dump_size() const { return dump_.size(); }
+ virtual std::string dump_str() const;
+ virtual size_t vm_dump_size() const;
+ virtual void clear();
+ virtual void ReadFromBuffer(Buffer &buffer, IArchitecture &file);
+ virtual void WriteToFile(IArchitecture &file);
+ virtual CommandLink *link() const { return link_; }
+ virtual void set_link(CommandLink *link) { link_ = link; }
+ virtual CommandBlock *block() const { return block_; }
+ virtual void set_block(CommandBlock *block) { block_ = block; }
+ virtual IFunction *owner() const { return owner_; }
+ virtual CommandLink *AddLink(int operand_index, LinkType type, ICommand *to_command);
+ virtual CommandLink *AddLink(int operand_index, LinkType type, uint64_t to_address = 0);
+ virtual uint64_t vm_address() const { return vm_address_; }
+ virtual uint64_t ext_vm_address() const { return vm_address_; }
+ virtual void set_vm_address(uint64_t address);
+ bool CompareDump(const uint8_t *buffer, size_t size) const;
+ void set_dump(const void *buffer, size_t size);
+ virtual ISEHandler *seh_handler() const { return NULL; }
+ virtual CommentInfo comment() { return comment_; }
+ virtual void set_comment(const CommentInfo &comment) { comment_ = comment; }
+ virtual AddressRange *address_range() const { return address_range_; }
+ virtual void set_address_range(AddressRange *address_range) { address_range_ = address_range; }
+ virtual void CompileInfo();
+ virtual size_t alignment() const { return alignment_; }
+ void set_alignment(size_t alignment) { alignment_ = alignment; }
+ virtual uint32_t options() const { return options_; }
+ virtual void include_option(CommandOption value) { options_ |= value; }
+ virtual void exclude_option(CommandOption value) { options_ &= ~value; }
+#ifdef CHECKED
+ virtual bool check_hash() const { return true; }
+#endif
+ virtual void set_tag(uint8_t tag) { tag_ = tag; }
+ virtual uint8_t tag() const { return tag_; }
+protected:
+ void Read(IArchitecture &file, size_t len);
+ uint8_t ReadByte(IArchitecture &file);
+ uint16_t ReadWord(IArchitecture &file);
+ uint32_t ReadDWord(IArchitecture &file);
+ uint64_t ReadQWord(IArchitecture &file);
+
+ void PushByte(uint8_t value);
+ void PushWord(uint16_t value);
+ void PushDWord(uint32_t value);
+ void PushQWord(uint64_t value);
+ void InsertByte(size_t position, uint8_t value);
+ void WriteDWord(size_t position, uint32_t value);
+ std::string comment_text() const { return comment_.value; }
+private:
+ Data dump_;
+ IFunction *owner_;
+ CommandLink *link_;
+ CommandBlock *block_;
+ uint64_t vm_address_;
+ AddressRange *address_range_;
+ CommentInfo comment_;
+ size_t alignment_;
+ uint32_t options_;
+ uint8_t tag_;
+};
+
+class InternalLinkList;
+
+enum InternalLinkType {
+ vlNone,
+ vlCRCTableAddress,
+ vlCRCTableCount,
+ vlCRCValue
+};
+
+class InternalLink : public IObject
+{
+public:
+ InternalLink(InternalLinkList *owner, InternalLinkType type, IVMCommand *from_command, IObject *to_command);
+ ~InternalLink();
+ InternalLinkType type() const { return type_; }
+ IVMCommand *from_command() const { return from_command_; }
+ IObject *to_command() const { return to_command_; }
+private:
+ InternalLinkList *owner_;
+ InternalLinkType type_;
+ IVMCommand *from_command_;
+ IObject *to_command_;
+};
+
+class InternalLinkList : public ObjectList<InternalLink>
+{
+public:
+ InternalLink *Add(InternalLinkType type, IVMCommand *from_command, IObject *to_command);
+};
+
+enum CryptCommandType : uint8_t {
+ ccAdd,
+ ccSub,
+ ccXor,
+ ccInc,
+ ccDec,
+ ccBswap,
+ ccRol,
+ ccRor,
+ ccNot,
+ ccNeg,
+ ccUnknown
+};
+
+class ValueCryptor;
+
+class ValueCommand: public IObject
+{
+public:
+ explicit ValueCommand(ValueCryptor *owner, OperandSize size, CryptCommandType type, uint64_t value);
+ explicit ValueCommand(ValueCryptor *owner, const ValueCommand &src);
+ ~ValueCommand();
+ ValueCommand *Clone(ValueCryptor *owner) const;
+ CryptCommandType type(bool is_decrypt = false) const;
+ uint64_t Encrypt(uint64_t value);
+ uint64_t Decrypt(uint64_t value);
+ uint64_t value() const { return value_; }
+ OperandSize size() const { return size_; }
+private:
+ uint64_t value_;
+ ValueCryptor *owner_;
+ uint64_t Calc(uint64_t value, bool is_decrypt);
+ CryptCommandType type_;
+ OperandSize size_;
+};
+
+class ValueCryptor : public ObjectList<ValueCommand>
+{
+public:
+ ValueCryptor();
+ ValueCryptor(const ValueCryptor &src);
+ ValueCryptor *Clone() const;
+ virtual void Init(OperandSize size);
+ uint64_t Encrypt(uint64_t value);
+ uint64_t Decrypt(uint64_t value);
+ OperandSize size() const { return size_; }
+ void set_size(OperandSize size) { size_ = size; }
+ void Add(CryptCommandType command, uint64_t value);
+private:
+ OperandSize size_;
+ // no assignment op
+ ValueCryptor &operator =(const ValueCryptor &);
+};
+
+class OpcodeCryptor : public ValueCryptor
+{
+public:
+ OpcodeCryptor();
+ virtual void Init(OperandSize size);
+ uint64_t EncryptOpcode(uint64_t value1, uint64_t value2);
+ uint64_t DecryptOpcode(uint64_t value1, uint64_t value2);
+ CryptCommandType type() const { return type_; }
+private:
+ uint64_t Calc(uint64_t value1, uint64_t value2, bool is_decrypt);
+ CryptCommandType type_;
+};
+
+class CommandLinkList;
+class FunctionInfo;
+
+class CommandLink: public IObject
+{
+public:
+ explicit CommandLink(CommandLinkList *owner, ICommand *from_command, int operand_index, LinkType type, uint64_t to_address);
+ explicit CommandLink(CommandLinkList *owner, ICommand *from_command, int operand_index, LinkType type, ICommand *to_command);
+ explicit CommandLink(CommandLinkList *owner, const CommandLink &src);
+ virtual ~CommandLink();
+ CommandLink *Clone(CommandLinkList *owner) const;
+ ICommand *from_command() const { return from_command_; }
+ ICommand *parent_command() const { return parent_command_; }
+ ICommand *to_command() const { return to_command_; }
+ ICommand *next_command() const { return next_command_; }
+ uint64_t to_address() const { return to_address_; }
+ LinkType type() const { return type_; }
+ bool parsed() const { return parsed_; }
+ int operand_index() const { return operand_index_; }
+ void set_operand_index(int value) { operand_index_ = value; }
+ void set_parsed(bool parsed) { parsed_ = parsed; }
+ void set_type(LinkType type) { type_ = type; }
+ void set_parent_command(ICommand *parent_command) { parent_command_ = parent_command; }
+ void set_from_command(ICommand *command);
+ void set_to_command(ICommand *command) { to_command_ = command; }
+ void set_next_command(ICommand *command) { next_command_ = command; }
+ void set_sub_value(uint64_t value) { sub_value_ = value; }
+ uint64_t sub_value() const { return sub_value_; }
+ ICommand *gate_command(size_t index) const { return gate_commands_[index]; }
+ void Rebase(uint64_t delta_base);
+ void AddGateCommand(ICommand *command) { gate_commands_.push_back(command); }
+ uint64_t Encrypt(uint64_t value) const;
+ ValueCryptor *cryptor() const { return cryptor_; }
+ void set_cryptor(ValueCryptor *cryptor);
+ FunctionInfo *base_function_info() const { return base_function_info_; }
+ void set_base_function_info(FunctionInfo *base_function_info) { base_function_info_ = base_function_info; }
+ void set_is_inverse(bool is_inverse) { is_inverse_ = is_inverse; }
+private:
+ CommandLinkList *owner_;
+ bool parsed_;
+ ICommand *from_command_;
+ ICommand *parent_command_;
+ ICommand *to_command_;
+ ICommand *next_command_;
+ LinkType type_;
+ uint64_t to_address_;
+ int operand_index_;
+ uint64_t sub_value_;
+ std::vector<ICommand *> gate_commands_;
+ ValueCryptor *cryptor_;
+ FunctionInfo *base_function_info_;
+ bool is_inverse_;
+
+ // no copy ctr or assignment op
+ CommandLink(const CommandLink &);
+ CommandLink &operator =(const CommandLink &);
+};
+
+class CommandLinkList : public ObjectList<CommandLink>
+{
+public:
+ explicit CommandLinkList();
+ explicit CommandLinkList(const CommandLinkList &src);
+ virtual CommandLinkList *Clone() const;
+ CommandLink *Add(ICommand *from_command, int operand_index, LinkType type, uint64_t to_address = 0);
+ CommandLink *Add(ICommand *from_command, int operand_index, LinkType type, ICommand *to_command);
+ CommandLink *GetLinkByToAddress(LinkType type, uint64_t to_address);
+ void Rebase(uint64_t delta_base);
+private:
+ // no assignment op
+ CommandLinkList &operator =(const CommandLinkList &);
+};
+
+class ExtCommandList;
+
+class ExtCommand: public IObject
+{
+public:
+ explicit ExtCommand(ExtCommandList *owner, uint64_t address, ICommand *command, bool use_call);
+ explicit ExtCommand(ExtCommandList *owner, const ExtCommand &src);
+ virtual ~ExtCommand();
+ virtual ExtCommand *Clone(ExtCommandList *owner) const;
+
+ using IObject::CompareWith;
+ int CompareWith(const ExtCommand &obj) const;
+ uint64_t address() const { return address_; }
+ ICommand *command() const { return command_; }
+ bool use_call() const { return use_call_; }
+ void set_command(ICommand *command) { command_ = command; }
+ ExtCommandList *owner() const { return owner_; }
+private:
+ ExtCommandList *owner_;
+ uint64_t address_;
+ ICommand *command_;
+ bool use_call_;
+};
+
+class ExtCommandList : public ObjectList<ExtCommand>
+{
+public:
+ explicit ExtCommandList(IFunction *owner);
+ explicit ExtCommandList(IFunction *owner, const ExtCommandList &src);
+ virtual ExtCommandList *Clone(IFunction *owner) const;
+ ExtCommand *Add(uint64_t address);
+ ExtCommand *Add(uint64_t address, ICommand *command, bool use_call = false);
+ ExtCommand *GetCommandByAddress(uint64_t address) const;
+ virtual void AddObject(ExtCommand *ext_command);
+ virtual void RemoveObject(ExtCommand *ext_command);
+ IFunction *owner() const { return owner_; }
+private:
+ IFunction *owner_;
+};
+
+class CommandBlockList;
+
+class CommandBlock: public AddressableObject
+{
+public:
+ explicit CommandBlock(CommandBlockList *owner, uint32_t type, size_t start_index);
+ explicit CommandBlock(CommandBlockList *owner, const CommandBlock &src);
+ ~CommandBlock();
+ CommandBlock *Clone(CommandBlockList *owner);
+ size_t start_index() const { return start_index_; }
+ size_t end_index() const { return end_index_; }
+ uint32_t type() const { return type_; }
+ void set_start_index(size_t start_index) { start_index_ = start_index; }
+ void set_end_index(size_t end_index) { end_index_ = end_index; }
+ void Compile(MemoryManager &manager);
+ void CompileLinks(const CompileContext &ctx);
+ void CompileInfo();
+ size_t WriteToFile(IArchitecture &file);
+ uint8_t GetRegistr(OperandSize size, uint8_t registr, bool is_write);
+ void AddCorrectCommand(IVMCommand *command) { correct_command_list_.push_back(command); }
+ std::vector<IVMCommand *> correct_command_list() const { return correct_command_list_; }
+ IFunction *function() const;
+ IVirtualMachine *virtual_machine() const { return virtual_machine_; }
+ void set_virtual_machine(IVirtualMachine *value) { virtual_machine_ = value; }
+ size_t sort_index() const { return sort_index_; }
+ void set_sort_index(size_t sort_index) { sort_index_ = sort_index; }
+ CommandBlockList *owner() { return owner_; };
+private:
+ CommandBlockList *owner_;
+ uint32_t type_;
+ size_t start_index_;
+ size_t end_index_;
+ uint8_t registr_indexes_[24];
+ size_t registr_count_;
+ std::vector<IVMCommand *> correct_command_list_;
+ IVirtualMachine *virtual_machine_;
+ size_t sort_index_;
+};
+
+class CommandBlockList : public ObjectList<CommandBlock>
+{
+public:
+ explicit CommandBlockList(IFunction *owner);
+ explicit CommandBlockList(IFunction *owner, const CommandBlockList &src);
+ CommandBlockList *Clone(IFunction *owner) const;
+ CommandBlock *Add(uint32_t memory_type, size_t start_index);
+ void CompileBlocks(MemoryManager &manager);
+ void CompileLinks(const CompileContext &ctx);
+ void CompileInfo();
+ size_t WriteToFile(IArchitecture &file);
+ IFunction *owner() const { return owner_; }
+private:
+ IFunction *owner_;
+};
+
+enum EntryType : uint8_t {
+ etDefault,
+ etRandomAddress,
+ etNone
+};
+
+enum CompilationOption {
+ coLockToKey = 0x2000
+};
+
+enum FunctionTag {
+ ftNone,
+ ftLicensing,
+ ftBundler,
+ ftRegistry,
+ ftResources,
+ ftLoader,
+ ftProcessor
+};
+
+enum CommandTag {
+ cmdtNone,
+ cmdtMutant
+};
+
+class AddressRange : public IObject
+{
+public:
+ explicit AddressRange(FunctionInfo *owner, uint64_t begin, uint64_t end, ICommand *begin_entry, ICommand *end_entry, ICommand *size_entry);
+ explicit AddressRange(FunctionInfo *owner, const AddressRange &src);
+ ~AddressRange();
+ uint64_t begin() const { return begin_; }
+ uint64_t end() const { return end_; }
+ uint64_t original_begin() const { return original_begin_ ? original_begin_ : begin_; }
+ uint64_t original_end() const { return original_end_ ? original_end_ : end_; }
+ ICommand *begin_entry() const { return begin_entry_; }
+ ICommand *end_entry() const { return end_entry_; }
+ ICommand *size_entry() const { return size_entry_; }
+ void set_begin_entry(ICommand *begin_entry) { begin_entry_ = begin_entry; }
+ void set_end_entry(ICommand *end_entry) { end_entry_ = end_entry; }
+ void set_size_entry(ICommand *size_entry) { size_entry_ = size_entry; }
+ AddressRange *Clone(FunctionInfo *owner) const;
+ void Add(uint64_t address, size_t size);
+ void Prepare();
+ void Rebase(uint64_t delta_base);
+ FunctionInfo *owner() const { return owner_; }
+ void set_begin(uint64_t value) { begin_ = value; }
+ void set_end(uint64_t value) { end_ = value; }
+ FunctionInfo *link_info() const { return link_info_; }
+ void set_link_info(FunctionInfo *info) { link_info_ = info; }
+ void AddLink(AddressRange *link) { link_list_.push_back(link); }
+private:
+ FunctionInfo *owner_;
+ uint64_t begin_;
+ uint64_t end_;
+ uint64_t original_begin_;
+ uint64_t original_end_;
+ ICommand *begin_entry_;
+ ICommand *end_entry_;
+ ICommand *size_entry_;
+ FunctionInfo *link_info_;
+ std::vector<AddressRange *> link_list_;
+};
+
+enum AddressBaseType {
+ btValue,
+ btImageBase,
+ btFunctionBegin
+};
+
+class FunctionInfo : public ObjectList<AddressRange>
+{
+public:
+ explicit FunctionInfo();
+ explicit FunctionInfo(FunctionInfoList *owner, uint64_t begin, uint64_t end, AddressBaseType base_type, uint64_t base_value, size_t prolog_size,
+ uint8_t frame_registr, IRuntimeFunction *source, ICommand *entry);
+ explicit FunctionInfo(FunctionInfoList *owner, const FunctionInfo &src);
+ ~FunctionInfo();
+ AddressRange *Add(uint64_t begin, uint64_t end, ICommand *begin_entry, ICommand *end_entry, ICommand *size_entry);
+ AddressRange *GetRangeByAddress(uint64_t address) const;
+ uint64_t begin() const { return begin_; }
+ uint64_t end() const { return end_; }
+ size_t prolog_size() const { return prolog_size_; }
+ AddressBaseType base_type() const { return base_type_; }
+ uint64_t base_value() const { return base_value_; }
+ ICommand *entry() const { return entry_; }
+ void set_entry(ICommand *entry) { entry_ = entry; }
+ ICommand *data_entry() const { return data_entry_; }
+ void set_data_entry(ICommand *data_entry) { data_entry_ = data_entry; }
+ FunctionInfo *Clone(FunctionInfoList *owner) const;
+ void Prepare();
+ void Compile();
+ void WriteToFile(IArchitecture &file);
+ void Rebase(uint64_t delta_base);
+ uint8_t frame_registr() const { return frame_registr_; }
+ IRuntimeFunction *source() const { return source_; }
+ void set_source(IRuntimeFunction *source) { source_ = source; }
+ std::vector<ICommand *> *unwind_opcodes() { return &unwind_opcodes_; }
+ void set_unwind_opcodes(const std::vector<ICommand *> &unwind_opcodes) { unwind_opcodes_ = unwind_opcodes; }
+private:
+ FunctionInfoList *owner_;
+ uint64_t begin_;
+ uint64_t end_;
+ size_t prolog_size_;
+ ICommand *entry_;
+ ICommand *data_entry_;
+ uint8_t frame_registr_;
+ AddressBaseType base_type_;
+ uint64_t base_value_;
+ IRuntimeFunction *source_;
+ std::vector<ICommand *> unwind_opcodes_;
+};
+
+class FunctionInfoList : public ObjectList<FunctionInfo>
+{
+public:
+ explicit FunctionInfoList();
+ explicit FunctionInfoList(const FunctionInfoList &src);
+ FunctionInfoList *Clone() const;
+ FunctionInfo *GetItemByAddress(uint64_t address) const;
+ AddressRange *GetRangeByAddress(uint64_t address) const;
+ FunctionInfo *Add(uint64_t begin, uint64_t end, AddressBaseType base_type, uint64_t base_value, size_t prolog_size, uint8_t frame_registr,
+ IRuntimeFunction *source, ICommand *entry);
+ void Prepare();
+ void Compile();
+ void WriteToFile(IArchitecture &file);
+ void Rebase(uint64_t delta_base);
+private:
+ // no assignment op
+ FunctionInfoList &operator =(const FunctionInfoList &);
+};
+
+class IFunctionList;
+
+class IFunction : public ObjectList<ICommand>
+{
+public:
+ virtual uint64_t address() const = 0;
+ virtual uint64_t break_address() const = 0;
+ virtual ObjectType type() const = 0;
+ virtual EntryType entry_type() const = 0;
+ virtual ICommand *entry() const = 0;
+ virtual std::string name() const = 0;
+ virtual std::string display_name() const = 0;
+ virtual FunctionName full_name() const = 0;
+ virtual OperandSize cpu_address_size() const = 0;
+ virtual CommandLinkList *link_list() const = 0;
+ virtual ExtCommandList *ext_command_list() const = 0;
+ virtual CommandBlockList *block_list() const = 0;
+ virtual bool need_compile() const = 0;
+ virtual CompilationType compilation_type() const = 0;
+ virtual CompilationType default_compilation_type() const = 0;
+ virtual uint32_t compilation_options() const = 0;
+ virtual Folder *folder() const = 0;
+ virtual void set_break_address(uint64_t break_address) = 0;
+ virtual bool is_breaked_address(uint64_t address) const = 0;
+ virtual void set_compilation_type(CompilationType compilation_type) = 0;
+ virtual void set_compilation_options(uint32_t compilation_options) = 0;
+ virtual void set_need_compile(bool need_compile) = 0;
+ virtual void set_folder(Folder *folder) = 0;
+ virtual void set_tag(uint8_t tag) = 0;
+ virtual bool from_runtime() const = 0;
+ virtual void set_from_runtime(bool from_runtime) = 0;
+ virtual IFunction *Clone(IFunctionList *owner) const = 0;
+ virtual size_t ReadFromFile(IArchitecture &file, uint64_t address) = 0;
+ virtual size_t WriteToFile(IArchitecture &file) = 0;
+ virtual bool Init(const CompileContext &ctx) = 0;
+ virtual bool Prepare(const CompileContext &ctx) = 0;
+ virtual bool PrepareExtCommands(const CompileContext &ctx) = 0;
+ virtual bool PrepareLinks(const CompileContext &ctx) = 0;
+ virtual bool Compile(const CompileContext &ctx) = 0;
+ virtual void AfterCompile(const CompileContext &ctx) = 0;
+ virtual void CompileLinks(const CompileContext &ctx) = 0;
+ virtual void CompileInfo(const CompileContext &ctx) = 0;
+ virtual ICommand *GetCommandByAddress(uint64_t address) const = 0;
+ virtual ICommand *GetCommandByNearAddress(uint64_t address) const = 0;
+ virtual void ReadFromBuffer(Buffer &buffer, IArchitecture &file) = 0;
+ virtual uint8_t tag() const = 0;
+ virtual void Rebase(uint64_t delta_base) = 0;
+ virtual uint32_t memory_type() const = 0;
+ virtual void set_memory_type(uint32_t memory_type) = 0;
+ virtual ICommand *ParseCommand(IArchitecture &file, uint64_t address, bool dump_mode = false) = 0;
+ virtual IFunctionList *owner() const = 0;
+ virtual IFunction *parent() const = 0;
+ virtual void Notify(MessageType type, IObject *sender, const std::string &message = "") const = 0;
+ virtual CommandBlock *AddBlock(size_t start_index, bool is_executable = false) = 0;
+ virtual ICommand *AddCommand(const Data &value) = 0;
+ virtual ICommand *AddCommand(OperandSize value_size, uint64_t value) = 0;
+ virtual std::string display_address(const std::string &arch_name) const = 0;
+ virtual Data hash() const = 0;
+ virtual FunctionInfoList *function_info_list() const = 0;
+#ifdef CHECKED
+ virtual bool check_hash() const = 0;
+#endif
+protected:
+ virtual ICommand *CreateCommand() = 0;
+};
+
+struct CommandBlockListCompareHelper {
+ bool operator () (const CommandBlock *block1, const CommandBlock *block2) const;
+};
+
+class BaseFunction : public IFunction
+{
+public:
+ explicit BaseFunction(IFunctionList *owner, const FunctionName &name, CompilationType compilation_type, uint32_t compilation_options, bool need_compile, Folder *folder);
+ explicit BaseFunction(IFunctionList *owner, OperandSize cpu_address_size, IFunction *parent);
+ explicit BaseFunction(IFunctionList *owner, const BaseFunction &source);
+ virtual ~BaseFunction();
+ virtual void RemoveObject(ICommand *obj);
+ virtual void clear();
+ virtual uint64_t address() const { return address_; }
+ virtual ObjectType type() const { return type_; }
+ virtual EntryType entry_type() const { return entry_type_; }
+ virtual void set_entry_type(EntryType entry_type) { entry_type_ = entry_type; }
+ virtual ICommand *entry() const { return entry_; }
+ virtual std::string name() const { return name_.name(); }
+ virtual std::string display_name() const { return name_.display_name(); }
+ virtual FunctionName full_name() const { return name_; }
+ virtual OperandSize cpu_address_size() const { return cpu_address_size_; }
+ virtual CommandLinkList *link_list() const { return link_list_; }
+ virtual ExtCommandList *ext_command_list() const { return ext_command_list_; }
+ virtual CommandBlockList *block_list() const { return block_list_; }
+ virtual bool need_compile() const { return need_compile_; }
+ virtual CompilationType compilation_type() const { return (default_compilation_type_ == ctNone) ? compilation_type_ : default_compilation_type_; }
+ virtual CompilationType default_compilation_type() const { return default_compilation_type_; }
+ virtual uint32_t compilation_options() const { return compilation_options_ | (internal_lock_to_key_ ? coLockToKey : 0); }
+ virtual Folder *folder() const { return folder_; }
+ virtual uint32_t memory_type() const { return memory_type_; }
+ virtual void set_memory_type(uint32_t memory_type) { memory_type_ = memory_type; }
+ virtual uint8_t tag() const { return tag_; }
+ virtual void set_compilation_type(CompilationType compilation_type);
+ virtual void set_compilation_options(uint32_t compilation_options);
+ virtual void set_need_compile(bool need_compile);
+ virtual void set_folder(Folder *folder);
+ virtual void set_tag(uint8_t tag) { tag_ = tag; }
+ virtual bool from_runtime() const { return from_runtime_; }
+ virtual void set_from_runtime(bool from_runtime) { from_runtime_ = from_runtime; }
+ virtual size_t ReadFromFile(IArchitecture &file, uint64_t address);
+ virtual size_t WriteToFile(IArchitecture &file);
+ virtual ICommand *GetCommandByAddress(uint64_t address) const;
+ virtual ICommand *GetCommandByNearAddress(uint64_t address) const;
+ virtual bool Init(const CompileContext &ctx);
+ virtual bool Prepare(const CompileContext &ctx);
+ virtual bool PrepareExtCommands(const CompileContext &ctx);
+ virtual bool PrepareLinks(const CompileContext &ctx);
+ virtual bool Compile(const CompileContext &ctx);
+ virtual void AfterCompile(const CompileContext &ctx);
+ virtual void CompileLinks(const CompileContext &ctx);
+ virtual void CompileInfo(const CompileContext &ctx);
+ void AddWatermark(Watermark *watermark, int copy_count);
+ virtual void ReadFromBuffer(Buffer &buffer, IArchitecture &file);
+ virtual void Rebase(uint64_t delta_base);
+ bool FreeByManager(const CompileContext &ctx);
+ virtual IFunctionList *owner() const { return owner_; }
+ virtual uint64_t break_address() const { return break_address_; }
+ virtual void set_break_address(uint64_t break_address);
+ virtual bool is_breaked_address(uint64_t address) const { return break_address_ ? address >= break_address_ : false; }
+ virtual IFunction *parent() const { return parent_; }
+ virtual CommandBlock *AddBlock(size_t start_index, bool is_executable = false);
+ virtual void Notify(MessageType type, IObject *sender, const std::string &message = "") const;
+ virtual FunctionInfo *range_list() const { return range_list_; }
+ virtual FunctionInfoList *function_info_list() const { return function_info_list_; }
+ virtual std::string display_address(const std::string &arch_name) const;
+ virtual Data hash() const;
+ virtual IVirtualMachine *virtual_machine(IVirtualMachineList *virtual_machine_list, ICommand *command) const;
+ virtual void AddObject(ICommand *command);
+#ifdef CHECKED
+ virtual bool check_hash() const;
+#endif
+protected:
+ virtual ICommand *ParseString(IArchitecture & /*file*/, uint64_t /*address*/, size_t /*len*/) { return NULL; }
+ virtual void ParseBeginCommands(IArchitecture & /*file*/) { return; }
+ virtual void ParseEndCommands(IArchitecture & /*file*/) { return; }
+ void set_entry(ICommand *entry) { entry_ = entry; }
+ ICommand *GetCommandByLowerAddress(uint64_t address) const;
+ ICommand *GetCommandByUpperAddress(uint64_t address) const;
+ virtual uint64_t GetNextAddress(IArchitecture &file);
+ virtual IFunction *CreateFunction(IFunction *parent = NULL) = 0;
+ void ClearItems();
+private:
+ typedef std::map<uint64_t, ICommand *> map_command_list_t;
+
+ map_command_list_t map_;
+ FunctionName name_;
+ IFunction *parent_;
+
+ uint64_t address_;
+ uint64_t break_address_;
+
+ IFunctionList *owner_;
+ CommandLinkList *link_list_;
+ ExtCommandList *ext_command_list_;
+ CommandBlockList *block_list_;
+ Folder *folder_;
+ ICommand *entry_;
+ FunctionInfo *range_list_;
+ FunctionInfoList *function_info_list_;
+
+ uint32_t compilation_options_;
+ uint32_t memory_type_;
+
+ ObjectType type_;
+ OperandSize cpu_address_size_;
+ CompilationType compilation_type_;
+ CompilationType default_compilation_type_;
+ uint8_t tag_;
+ EntryType entry_type_;
+ bool from_runtime_;
+ bool internal_lock_to_key_;
+ bool need_compile_;
+
+ // no copy ctr or assignment op
+ BaseFunction(const BaseFunction &);
+ BaseFunction &operator =(const BaseFunction &);
+};
+
+class Signature: public IObject
+{
+public:
+ explicit Signature(SignatureList *owner, const std::string &value, uint32_t tag);
+ ~Signature();
+ size_t size() const { return dump_.size(); }
+ uint8_t dump(size_t index) const { return dump_[index]; }
+ uint32_t tag() const { return tag_; }
+ void InitSearch() { pos_.clear(); }
+ bool SearchByte(uint8_t value);
+private:
+ void Init();
+
+ SignatureList *owner_;
+ std::string value_;
+ std::vector<uint8_t> dump_;
+ std::vector<uint8_t> mask_;
+ std::vector<size_t> pos_;
+ uint32_t tag_;
+};
+
+class SignatureList: public ObjectList<Signature>
+{
+public:
+ explicit SignatureList();
+ Signature *Add(const std::string &value, uint32_t tag = 0);
+ void InitSearch();
+};
+
+class IFunctionList : public ObjectList<IFunction>
+{
+public:
+ virtual IFunction *Add(const std::string &name, CompilationType compilation_type, uint32_t compilation_options, bool need_compile, Folder *folder) = 0;
+ virtual IFunction *GetFunctionByAddress(uint64_t address) const = 0;
+ virtual IFunction *GetFunctionByName(const std::string &name) const = 0;
+ virtual IFunction *GetUnknownByName(const std::string &name) const = 0;
+ virtual ICommand *GetCommandByAddress(uint64_t address, bool need_compile) const = 0;
+ virtual ICommand *GetCommandByNearAddress(uint64_t address, bool need_compile) const = 0;
+ virtual IFunction *AddUnknown(const std::string &name, CompilationType compilation_type, uint32_t compilation_options, bool need_compile, Folder *folder) = 0;
+ virtual IFunction *AddByAddress(uint64_t address, CompilationType compilation_type, uint32_t compilation_options, bool need_compile, Folder *folder) = 0;
+ virtual IFunctionList *Clone(IArchitecture *owner) const = 0;
+ virtual bool Prepare(const CompileContext &ctx) = 0;
+ virtual bool Compile(const CompileContext &ctx) = 0;
+ virtual void CompileLinks(const CompileContext &ctx) = 0;
+ virtual void ReadFromBuffer(Buffer &buffer, IArchitecture &file) = 0;
+ virtual IFunction *crc_table() const = 0;
+ virtual ValueCryptor *crc_cryptor() const = 0;
+ virtual void Rebase(uint64_t delta_base) = 0;
+ virtual IFunction *CreateFunction(OperandSize cpu_address_size = osDefault) = 0;
+ virtual IArchitecture *owner() const = 0;
+ virtual void Notify(MessageType type, IObject *sender, const std::string &message = "") const = 0;
+ virtual bool GetRuntimeOptions() const = 0;
+ virtual std::vector<IFunction *> processor_list() const = 0;
+#ifdef CHECKED
+ virtual bool check_hash() const = 0;
+#endif
+};
+
+class BaseFunctionList : public IFunctionList
+{
+public:
+ explicit BaseFunctionList(IArchitecture *owner);
+ explicit BaseFunctionList(IArchitecture *owner, const BaseFunctionList &src);
+ virtual IFunction *GetFunctionByAddress(uint64_t address) const;
+ virtual IFunction *GetFunctionByName(const std::string &name) const;
+ virtual IFunction *GetUnknownByName(const std::string &name) const;
+ virtual ICommand *GetCommandByAddress(uint64_t address, bool need_compile) const;
+ virtual ICommand *GetCommandByNearAddress(uint64_t address, bool need_compile) const;
+ virtual IFunction *AddUnknown(const std::string &name, CompilationType compilation_type, uint32_t compilation_options, bool need_compile, Folder *folder);
+ virtual IFunction *AddByAddress(uint64_t address, CompilationType compilation_type, uint32_t compilation_options, bool need_compile, Folder *folder);
+ virtual bool Prepare(const CompileContext &ctx);
+ virtual bool Compile(const CompileContext &ctx);
+ virtual void CompileLinks(const CompileContext &ctx);
+ virtual void CompileInfo(const CompileContext &ctx);
+ virtual void ReadFromBuffer(Buffer &buffer, IArchitecture &file);
+ virtual void Rebase(uint64_t delta_base);
+ virtual IArchitecture *owner() const { return owner_; }
+ virtual void RemoveObject(IFunction *func);
+ virtual void Notify(MessageType type, IObject *sender, const std::string &message = "") const;
+ virtual std::vector<IFunction *> processor_list() const;
+#ifdef CHECKED
+ virtual bool check_hash() const;
+#endif
+private:
+ IArchitecture *owner_;
+};
+
+typedef std::vector<uint8_t> ByteList;
+
+class IVirtualMachine : public IObject
+{
+public:
+ virtual uint8_t id() const = 0;
+ virtual ByteList *registr_order() = 0;
+ virtual bool backward_direction() const = 0;
+ virtual IFunction *processor() const = 0;
+};
+
+class IVirtualMachineList : public ObjectList<IVirtualMachine>
+{
+public:
+ virtual IVirtualMachineList *Clone() const = 0;
+ virtual void Prepare(const CompileContext &ctx) = 0;
+};
+
+class BaseVirtualMachine : public IVirtualMachine
+{
+public:
+ BaseVirtualMachine(IVirtualMachineList *owner, uint8_t id);
+ ~BaseVirtualMachine();
+ virtual uint8_t id() const { return id_; }
+private:
+ IVirtualMachineList *owner_;
+ uint8_t id_;
+};
+
+#endif