diff options
Diffstat (limited to 'core/intel.h')
-rw-r--r-- | core/intel.h | 1570 |
1 files changed, 1570 insertions, 0 deletions
diff --git a/core/intel.h b/core/intel.h new file mode 100644 index 0000000..3b890bc --- /dev/null +++ b/core/intel.h @@ -0,0 +1,1570 @@ +#ifndef INTEL_H +#define INTEL_H + +enum IntelCommandType : uint16_t +{ + cmUnknown,cmPush,cmPop,cmMov,cmAdd,cmXor,cmTest,cmLea, + cmUd0, cmRet,cmNor,cmNand,cmCrc,cmCall,cmJmp,cmFstsw,cmFsqrt,cmFchs,cmFstcw,cmFldcw, + cmFild,cmFist,cmFistp,cmFld,cmFstp,cmFst, + cmFadd,cmFsub,cmFsubr,cmFisub,cmFisubr,cmFdiv,cmFcomp,cmFmul, + cmRepe,cmRepne,cmRep,cmDB,cmDW,cmDD,cmDQ, + cmMovs,cmCmps,cmScas, + cmMovzx,cmMovsx, + + cmInc,cmDec, + cmLes,cmLds,cmLfs,cmLgs,cmLss, + cmXadd,cmBswap, + cmJmpWithFlag, + cmAnd,cmSub,cmStos,cmLods,cmNop,cmXchg, + cmPushf,cmPopf,cmSahf,cmLahf,cmShl,cmShr,cmSal,cmSar,cmRcl,cmRcr,cmRol,cmRor,cmShld,cmShrd, + cmLoope,cmLoopne,cmLoop,cmJCXZ, + cmIn,cmIns,cmOut,cmOuts,cmWait, + cmCbw,cmCwde,cmCdqe,cmCwd,cmCdq,cmCqo, + cmClc,cmStc,cmCli,cmSti,cmCld,cmStd, + cmNot,cmNeg,cmDiv,cmImul,cmIdiv,cmMul, + cmOr,cmAdc,cmCmp,cmSbb, + cmPusha,cmPopa, + + cmClflush,cmPause, + + cmBound,cmArpl,cmDaa,cmDas,cmAaa,cmAam,cmAad,cmAas,cmEnter,cmLeave,cmInt,cmInto,cmIret, + cmSetXX,cmCmov, + + cmAddpd,cmAddps,cmAddsd,cmAddss, + cmAndpd,cmAndps,cmAndnpd,cmAndnps, + cmCmppd,cmCmpps,cmCmpsd,cmCmpss, + cmComisd,cmComiss, + cmCvtdq2ps,cmCvtpd2dq,cmCvtdq2pd,cmCvtpd2pi,cmCvtps2pi, + cmCvtpd2ps,cmCvtps2pd,cmCvtpi2pd,cmCvtpi2ps,cmCvtps2dq, + cmCvtsd2si,cmCvtss2si,cmCvtsd2ss,cmCvtss2sd, + cmCvttpd2pi,cmCvttps2pi,cmCvttpd2dq,cmCvttps2dq, + cmCvttsd2si,cmCvttss2si, + cmDivpd,cmDivps,cmDivsd,cmDivss, + cmMaxpd,cmMaxps,cmMaxsd,cmMaxss, + cmMinpd,cmMinps,cmMinsd,cmMinss, + cmMulpd,cmMulps,cmMulsd,cmMulss, + cmOrpd,cmOrps, + + cmMovd,cmMovq,cmMovntq,cmMovapd,cmMovaps,cmMovdqa,cmMovdqu, + cmMovdq2q,cmMovq2dq, + cmMovhlps,cmMovhpd,cmMovhps,cmMovlhps,cmMovlpd,cmMovlps, + cmMovmskpd,cmMovmskps, + cmMovnti, + cmMovntpd,cmMovntps, + cmMovsd,cmMovss, + cmMovupd,cmMovups, + + cmPmovmskb,cmPsadbw, + cmPshufw,cmPshufd,cmPshuflw,cmPshufhw, + cmPsubb,cmPsubw,cmPsubd,cmPsubq, + cmPsubsb,cmPsubsw, + cmPsubusb,cmPsubusw, + cmPaddb,cmPaddw,cmPaddd,cmPaddq, + cmPaddsb,cmPaddsw, + cmPaddusb,cmPaddusw, + cmPavgb,cmPavgw, + cmPinsrb,cmPinsrw,cmPinsrd,cmPinsrq,cmPextrw, + cmPmaxsb,cmPmaxsw,cmPmaxsd,cmPmaxub,cmPmaxuw,cmPmaxud, + cmPminsb,cmPminsw,cmPminsd,cmPminub,cmPminuw,cmPminud, + cmPmulhuw,cmPmulhw,cmPmullw,cmPmuludq,cmPmulld, + cmPsllw,cmPslld,cmPsllq,cmPslldq, + cmPsraw,cmPsrad, + cmPsrlw,cmPsrld,cmPsrlq,cmPsrldq, + + cmPunpcklbw,cmPunpcklwd,cmPunpckldq,cmPunpcklqdq,cmPunpckhqdq, + + cmPackusdw,cmPcmpgtb,cmPcmpgtw,cmPcmpgtd,cmPcmpeqb,cmPcmpeqw,cmPcmpeqd,cmEmms, + cmPacksswb,cmPackuswb,cmPunpckhbw,cmPunpckhwd,cmPunpckhdq,cmPackssdw,cmPand,cmPandn,cmPor,cmPxor,cmPmaddwd, + cmRcpps,cmRcpss, + cmRsqrtss,cmMovsxd, + cmShufps,cmShufpd, + cmSqrtpd,cmSqrtps,cmSqrtsd,cmSqrtss, + cmSubpd,cmSubps,cmSubsd,cmSubss, + cmUcomisd,cmUcomiss, + cmUnpckhpd,cmUnpckhps, + cmUnpcklpd,cmUnpcklps, + cmXorpd,cmXorps, + + cmBt,cmBts,cmBtr,cmBtc,cmXlat,cmCpuid,cmRsm,cmBsf,cmBsr,cmCmpxchg,cmCmpxchg8b, + cmHlt,cmCmc, + cmLgdt,cmSgdt,cmLidt,cmSidt,cmSmsw,cmLmsw,cmInvlpg, + cmLar,cmLsl,cmClts,cmInvd,cmWbinvd,cmUd2,cmWrmsr,cmRdtsc,cmRdmsr,cmRdpmc, + + cmFcom,cmFdivr, + cmFiadd,cmFimul,cmFicom,cmFicomp,cmFidiv,cmFidivr, + cmFaddp,cmFmulp,cmFsubp,cmFsubrp,cmFdivp,cmFdivrp, + cmFbld,cmFbstp, + + cmFfree,cmFrstor,cmFsave,cmFucom,cmFucomp, + + cmFldenv,cmFstenvm, + cmFxch,cmFabs,cmFxam, + cmFld1,cmFldl2t,cmFldl2e,cmFldpi,cmFldlg2,cmFldln2, + + cmFldz,cmFyl2x,cmFptan,cmFpatan,cmFxtract,cmFprem1,cmFdecstp,cmFincstp, + cmFprem,cmFyl2xp1,cmFsincos,cmFrndint,cmFscale,cmFsin,cmFcos,cmFtst, + cmFstenv,cmF2xm1,cmFnop,cmFinit,cmFclex,cmFcompp, + + cmSysenter,cmSysexit,cmSldt,cmStr,cmLldt,cmLtr,cmVerr,cmVerw, + cmSfence,cmLfence,cmMfence,cmPrefetchnta,cmPrefetcht0,cmPrefetcht1,cmPrefetcht2,cmPrefetch,cmPrefetchw, + cmFxrstor,cmFxsave,cmLdmxcsr,cmStmxcsr, + + cmFcmovb, cmFcmove, cmFcmovbe, cmFcmovu, cmFcmovnb, cmFcmovne, cmFcmovnbe, cmFcmovnu, + + cmFucomi,cmFcomi, + cmFucomip,cmFcomip,cmFucompp, + + cmVmcall, cmVmlaunch, cmVmresume, cmVmxoff, cmMonitor, cmMwait, cmXgetbv, cmXsetbv, cmVmrun, cmVmmcall, + cmVmload, cmVmsave, cmStgi, cmClgi, cmSkinit, cmInvlpga, cmSwapgs, cmRdtscp, cmSyscall, cmSysret, cmFemms, cmGetsec, + cmPshufb, cmPhaddw, cmPhaddd, cmPhaddsw, cmPmaddubsw, cmPhsubw, cmPhsubd, cmPhsubsw, cmPsignb, cmPsignw, cmPsignd, cmPmulhrsw, + cmPabsb, cmPabsw, cmPabsd, cmMovbe, cmPalignr, cmRsqrtps, cmVmread, cmVmwrite, cmSvldt, cmRsldt, cmSvts, cmRsts, + cmXsave, cmXrstor, cmVmptrld, cmVmptrst, cmMaskmovq, cmFnstenv, cmFnstcw, cmFstp1, cmFneni, cmFndisi, cmFnclex, cmFninit, + cmFsetpm, cmFisttp, cmFnsave, cmFnstsw, cmFxch4, cmFcomp5, cmFfreep, cmFxch7, cmFstp8, cmFstp9, cmHaddpd, cmHsubpd, + cmAddsubpd, cmAddsubps, cmMovntdq, cmFcom2, cmFcomp3, cmHaddps, cmHsubps, cmMovddup, cmMovsldup, cmCvtsi2sd, cmCvtsi2ss, + cmMovntsd, cmMovntss, cmLddqu, cmMovshdup, cmPopcnt, cmTzcnt, cmLzcnt, + cmPblendvb, cmPblendps, cmPblendpd, cmPblendw, cmPtest, cmPmovsxbw, cmPmovsxbd, cmPmovsxbq, cmPmovsxwd, cmPmovsxwq, cmPmovsxdq, cmPmuldq, + cmPcmpeqq, cmMovntdqa, cmXsaveopt, cmMaskmovdqu, cmUd1, cmPcmpgtq, + cmAesdec, cmAesdeclast, cmAesenc, cmAesenclast, cmAesimc, cmAeskeygenassist, + cmRdrand, cmRdseed, + cmPmovzxbw, cmPmovzxbd, cmPmovzxbq, cmPmovzxwd, cmPmovzxwq, cmPmovzxdq, + + cmFnmadd132sd, cmFnmadd213sd, cmFnmadd231sd, + cmFnmadd132ss, cmFnmadd213ss, cmFnmadd231ss, + + cmUleb,cmSleb,cmDC, + cmVbroadcastss, cmVbroadcastsd, cmVbroadcastf128, cmVperm2f128, cmVpermilpd, cmVpermilps, cmRoundpd, cmRoundps, cmCrc32, cmPextrb, cmPextrd, cmPextrq, cmVzeroupper, + cmVzeroall, cmBlendpd, cmBlendps, cmBlendvpd, cmBlendvps, cmDpps, cmExtractf128, cmInsertf128, cmMaskmovpd, cmMaskmovps, + cmVtestps, cmVtestpd, cmPcmpistri +}; + +static const char *intel_command_name[] = { + "db ??","push","pop","mov","add","xor","test","lea", + "ud0", "ret","nor","nand","crc","call","jmp","fstsw","fsqrt","fchs","fstcw","fldcw", + "fild","fist","fistp","fld","fstp","fst", + "fadd","fsub","fsubr","fisub","fisubr","fdiv","fcomp","fmul", + "repe","repne","rep","db","dw","dd","dq", + "movs","cmps","scas", + "movzx","movsx", + + "inc","dec", + "les","lds","lfs","lgs","lss", + "xadd","bswap", + "j", + "and","sub","stos","lods","nop","xchg", + "pushf","popf","sahf","lahf","shl","shr","sal","sar","rcl","rcr","rol","ror","shld","shrd", + "loope","loopne","loop","jcxz", + "in","ins","out","outs","wait", + "cbw","cwde","cdqe","cwd","cdq","cqo", + "clc","stc","cli","sti","cld","std", + "not","neg","div","imul","idiv","mul", + "or","adc","cmp","sbb", + "pusha","popa", + + "clflush","pause", + + "bound","arpl","daa","das","aaa","aam","aad","aas","enter","leave","int","into","iret", + "set","cmov", + "addpd","addps","addsd","addss", + "andpd","andps","andnpd","andnps", + "cmppd","cmpps","cmpsd","cmpss", + "comisd","comiss", + "cvtdq2ps","cvtpd2dq","cvtdq2pd","cvtpd2pi","cvtps2pi", + "cvtpd2ps","cvtps2pd","cvtpi2pd","cvtpi2ps","cvtps2dq", + "cvtsd2si","cvtss2si","cvtsd2ss","cvtss2sd", + "cvttpd2pi","cvttps2pi","cvttpd2dq","cvttps2dq", + "cvttsd2si","cvttss2si", + "divpd","divps","divsd","divss", + "maxpd","maxps","maxsd","maxss", + "minpd","minps","minsd","minss", + "mulpd","mulps","mulsd","mulss", + "orpd","orps", + + "movd","movq","movntq","movapd","movaps","movdqa","movdqu", + "movdq2q","movq2dq", + "movhlps","movhpd","movhps","movlhps","movlpd","movlps", + "movmskpd","movmskps", + "movnti", + "movntpd","movntps", + "movsd","movss", + "movupd","movups", + + "pmovmskb","psadbw", + "pshufw","pshufd","pshuflw","pshufhw", + "psubb","psubw","psubd","psubq", + "psubsb","psubsw", + "psubusb","psubusw", + "paddb","paddw","paddd","paddq", + "paddsb","paddsw", + "paddusb","paddusw", + "pavgb","pavgw", + "pinsrb","pinsrw","pinsrd","pinsrq","pextrw", + "pmaxsb","pmaxsw","pmaxsd","pmaxub","pmaxuw","pmaxud", + "pminsb","pminsw","pminsd","pminub","pminuw","pminud", + "pmulhuw","pmulhw","pmullw","pmuludq","pmulld", + "psllw","pslld","psllq","pslldq", + "psraw","psrad", + "psrlw","psrld","psrlq","psrldq", + "punpcklbw","punpcklwd","punpckldq","punpcklqdq","punpckhqdq", + + "packusdw","pcmpgtb","pcmpgtw","pcmpgtd","pcmpeqb","pcmpeqw","pcmpeqd","emms", + "packsswb","packuswb","punpckhbw","punpckhwd","punpckhdq","packssdw","pand","pandn","por","pxor","pmaddwd", + "rcpps","rcpss", + "rsqrtss","movsxd", + "shufps","shufpd", + "sqrtpd","sqrtps","sqrtsd","sqrtss", + "subpd","subps","subsd","subss", + "ucomisd","ucomiss", + "unpckhpd","unpckhps", + "unpcklpd","unpcklps", + "xorpd","xorps", + + "bt","bts","btr","btc","xlat","cpuid","rsm","bsf","bsr","cmpxchg","cmpxchg8b", + "hlt","cmc", + "lgdt","sgdt","lidt","sidt","smsw","lmsw","invlpg", + "lar","lsl","clts","invd","wbinvd","ud2","wrmsr","rdtsc","rdmsr","rdpmc", + "fcom","fdivr", + "fiadd","fimul","ficom","ficomp","fidiv","fidivr", + "faddp","fmulp","fsubp","fsubrp","fdivp","fdivrp", + "fbld","fbstp", + + "ffree","frstor","fsave","fucom","fucomp", + + "fldenv","fstenvm", + "fxch","fabs","fxam", + "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2", + + "fldz","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp", + "fprem","fyl2xp1","fsincos","frndint","fscale","fsin","fcos","ftst", + + "fstenv","f2xm1","fnop","finit","fclex","fcompp", + + "sysenter","sysexit","sldt","str","lldt","ltr","verr","verw", + "sfence","lfence","mfence","prefetchnta","prefetcht0","prefetcht1","prefetcht2","prefetch","prefetchw", + "fxrstor","fxsave","ldmxcsr","stmxcsr", + + "fcmovb", "fcmove", "fcmovbe", "fcmovu", "fcmovnb", "fcmovne", "fcmovnbe", "fcmovnu", + "fucomi","fcomi", + "fucomip","fcomip","fucompp", + "vmcall", "vmlaunch", "vmresume", "vmxoff", "monitor", "mwait", "xgetbv", "xsetbv", "vmrun", "vmmcall", + "vmload", "vmsave", "stgi", "clgi", "skinit", "invlpga", "swapgs", "rdtscp", "syscall", "sysret", "femms", "getsec", + "pshufb", "phaddw", "phaddd", "phaddsw", "pmaddubsw", "phsubw", "phsubd", "phsubsw", "psignb", "psignw", "psignd", "pmulhrsw", + "pabsb", "pabsw", "pabsd", "movbe", "palignr", "rsqrtps", "vmread", "vmwrite", "svldt", "rsldt", "svts", "rsts", + "xsave", "xrstor", "vmptrld", "vmptrst", "maskmovq", "fnstenv", "fnstcw", "fstp1", "fneni", "fndisi", "fnclex", "fninit", + "fsetpm", "fisttp", "fnsave", "fnstsw", "fxch4", "fcomp5", "ffreep", "fxch7", "fstp8", "fstp9", "haddpd", "hsubpd", + "addsubpd", "addsubps", "movntdq", "fcom2", "fcomp3", "haddps", "hsubps", "movddup", "movsldup", "cvtsi2sd", "cvtsi2ss", + "movntsd", "movntss", "lddqu", "movshdup", "popcnt", "tzcnt", "lzcnt", + "pblendvb", "pblendps", "pblendpd", "pblendw", "ptest", "pmovsxbw", "pmovsxbd", "pmovsxbq", "pmovsxwd", "pmovsxwq", "pmovsxdq", "pmuldq", + "pcmpeqq", "movntdqa", "xsaveopt", "maskmovdqu", "ud1", "pcmpgtq", + "aesdec", "aesdeclast", "aesenc", "aesenclast", "aesimc", "aeskeygenassist", + "rdrand", "rdseed", + "pmovzxbw", "pmovzxbd", "pmovzxbq", "pmovzxwd", "pmovzxwq", "pmovzxdq", + + "fnmadd132sd", "fnmadd213sd", "fnmadd231sd", + "fnmadd132ss", "fnmadd213ss", "fnmadd231ss", + + "uleb","sleb","dc", + "broadcastss", "broadcastsd", "broadcastf128", "perm2f128", "permilpd", "permilps", "roundpd", "roundps", "crc32", "pextrb", "pextrd", "pextrq", "zeroupper", + "zeroall", "blendpd", "blendps", "blendvpd", "blendvps", "dpps", "extractf128", "insertf128", "maskmovpd", "maskmovps", + "testps", "testpd", "pcmpistri" +}; + +enum IntelFlags : uint16_t { + fl_C = 0x0001, + fl_P = 0x0004, + fl_A = 0x0010, + fl_Z = 0x0040, + fl_S = 0x0080, + fl_T = 0x0100, + fl_I = 0x0200, + fl_D = 0x0400, + fl_O = 0x0800, + fl_OS = fl_S | fl_O +}; + +enum IntelRegistr : uint8_t { + regEAX, + regECX, + regEDX, + regEBX, + regESP, + regEBP, + regESI, + regEDI, + regR8, + regR9, + regR10, + regR11, + regR12, + regR13, + regR14, + regR15, + regEIP +}; + +enum IntelSegment : uint8_t { + segES, + segCS, + segSS, + segDS, + segFS, + segGS, + segDefault = 0xff +}; + +enum IntelRexFlags : uint8_t { + rexB = 0x01, + rexX = 0x02, + rexR = 0x04, + rexW = 0x08, + vexL = 0x80 +}; + +struct IntelOperand { + uint64_t value; + IFixup *fixup; + IRelocation *relocation; + uint16_t type; + OperandSize size; + uint8_t registr; + uint8_t base_registr; + uint8_t scale_registr; + uint8_t value_pos; + OperandSize address_size; + OperandSize value_size; + bool show_size; + bool is_large_value; + + IntelOperand() + { + Clear(); + } + + void Clear() + { + type = otNone; + fixup = NULL; + relocation = NULL; + registr = 0; + base_registr = 0; + scale_registr = 0; + size = osDefault; + value_size = address_size = osDefault; + value_pos = 0; + value = 0; + show_size = false; + is_large_value = false; + } + + IntelSegment effective_base_segment(IntelSegment base_segment) const + { + if (base_segment == segDefault && + (((type & otBaseRegistr) && (base_registr == regESP || base_registr == regEBP)) || + ((type & otRegistr) && (registr == regESP || registr == regEBP)))) { + return segSS; + } else { + return (base_segment == segDefault) ? segDS : base_segment; + } + } + + IntelOperand(uint32_t type_, OperandSize size_, uint8_t registr_ = 0, uint64_t value_ = 0, IFixup *fixup_ = NULL); + + uint64_t encode() const + { + uint64_t res = static_cast<uint64_t>(type) << 48; + if (type & (otRegistr | otSegmentRegistr | otControlRegistr | otDebugRegistr | otFPURegistr | otHiPartRegistr | otMMXRegistr | otXMMRegistr)) + res |= static_cast<uint64_t>(registr) << 44; + if (type & otBaseRegistr) + res |= static_cast<uint64_t>(base_registr) << 40; + if (type & otValue) + res |= static_cast<uint32_t>(value); + return res; + } + + void decode(uint64_t value_) + { + type = (value_ >> 48) & 0xffff; + if (type & (otRegistr | otSegmentRegistr | otControlRegistr | otDebugRegistr | otFPURegistr | otHiPartRegistr | otMMXRegistr | otXMMRegistr)) + registr = (value_ >> 44) & 0xf; + if (type & otBaseRegistr) + base_registr = (value_ >> 40) & 0xf; + if (type & otValue) + value = static_cast<uint32_t>(value_); + } + + bool operator == (const IntelOperand &operand) const + { + if (type != operand.type) + return false; + if (type & (otRegistr | otSegmentRegistr | otControlRegistr | otDebugRegistr | otFPURegistr | otHiPartRegistr | otMMXRegistr | otXMMRegistr)) { + if (registr != operand.registr) + return false; + } + if ((type & (otMemory | otRegistr)) == (otMemory | otRegistr)) { + if (scale_registr != operand.scale_registr) + return false; + } + if (type & otBaseRegistr) { + if (base_registr != operand.base_registr) + return false; + } + if (type & otValue) { + if (value != operand.value) + return false; + } + return true; + } + + bool operator != (const IntelOperand &operand) const + { + return !(operator == (operand)); + } +}; + +class IntelCommand; +class IntelOpcodeInfo; + +class IntelVMCommand : public BaseVMCommand +{ +public: + explicit IntelVMCommand(IntelCommand *owner, IntelCommandType command_type, OperandType operand_type, OperandSize size, uint64_t value, uint32_t options); + explicit IntelVMCommand(IntelCommand *owner, const IntelVMCommand &src); + virtual void WriteToFile(IArchitecture &file); + virtual void Compile(); + IntelVMCommand *Clone(IntelCommand *owner); + virtual uint64_t address() const { return address_; } + virtual size_t dump_size() const { return dump_.size(); } + virtual void set_address(uint64_t address) { address_ = address; } + virtual void set_value(uint64_t value) { value_ = value; } + void set_sub_value(uint64_t sub_value) { sub_value_ = sub_value; } + void set_dump(const Data &dump) { dump_ = dump; } + uint32_t options() const { return options_; } + void include_option(VMCommandOption option) { options_ |= option; } + int GetStackLevel() const; + IntelCommandType crypt_command() const { return crypt_command_; } + OperandSize crypt_size() const { return crypt_size_; } + uint64_t crypt_key() const { return crypt_key_; } + IntelVMCommand *link_command() const { return link_command_; } + void set_crypt_command(IntelCommandType crypt_command, OperandSize crypt_size, uint64_t crypt_key) { crypt_command_ = crypt_command; crypt_size_ = crypt_size; crypt_key_ = crypt_key; } + void set_link_command(IntelVMCommand *command) { link_command_ = command; } + IntelCommandType command_type() const { return command_type_; } + OperandType operand_type() const { return operand_type_; } + uint8_t registr() const { return registr_; } + OperandSize size() const { return size_; } + uint64_t value() const { return value_; } + uint64_t sub_value() const { return sub_value_; } + IntelSegment base_segment() const { return base_segment_; } + uint8_t subtype() const { return subtype_; } + uint8_t dump(size_t pos) const { return dump_[pos]; } + uint64_t dump_value(OperandSize size, size_t pos) const; + void set_dump_value(OperandSize size, size_t pos, uint64_t value); + void set_dump(size_t pos, uint8_t value) { dump_[pos] = value; } + bool can_merge(CommandInfoList &command_info_list) const; + IntelOpcodeInfo *opcode() const { return opcode_; } + void set_opcode(IntelOpcodeInfo *opcode) { opcode_ = opcode; } + virtual bool is_end() const; + bool is_data() const { return (command_type_ == cmDD || command_type_ == cmDQ); } + IFixup *fixup() const { return fixup_; } + void set_fixup(IFixup *fixup) { fixup_ = fixup; } +private: + uint64_t CorrectDumpValue(OperandSize size, uint64_t value) const; + uint64_t address_; + uint64_t crypt_key_; + uint64_t sub_value_; + uint64_t value_; + + IntelVMCommand *link_command_; + IntelOpcodeInfo *opcode_; + + uint32_t options_; + IntelCommandType command_type_; + IntelCommandType crypt_command_; + + Data dump_; + + OperandType operand_type_; + uint8_t registr_; + uint8_t subtype_; + OperandSize size_; + IntelSegment base_segment_; + OperandSize crypt_size_; + IFixup *fixup_; +}; + +struct DisasmContext { + IArchitecture *file; + bool lower_reg; + bool lower_address; + uint8_t rex_prefix; + uint8_t vex_registr; + bool use_last_byte; +}; + +struct AsmContext { + uint8_t rex_prefix; +}; + +enum CompileOperandOption { + coSaveResult = 0x0001, + coAsPointer = 0x0002, + coInverse = 0x0004, + coFixup = 0x0008, + coAsWord = 0x0010 +}; + +class IntelFunction; +class SectionCryptor; +class AddressRange; + +class IntelCommandInfoList : public CommandInfoList +{ +public: + explicit IntelCommandInfoList(OperandSize cpu_address_size); + virtual void Add(AccessType access_type, uint8_t value, OperandType operand_type, OperandSize size); + void AddOperand(const IntelOperand &operand, AccessType access_type); + void set_base_segment(IntelSegment base_segment) { base_segment_ = base_segment; } +private: + OperandSize cpu_address_size_; + IntelSegment base_segment_; +}; + +class EncodedData; + +class IntelCommand: public BaseCommand +{ +public: + explicit IntelCommand(IFunction *owner, OperandSize size, uint64_t address = 0); + explicit IntelCommand(IFunction *owner, OperandSize size, IntelCommandType type, IntelOperand operand1 = IntelOperand(), IntelOperand operand2 = IntelOperand(), IntelOperand operand3 = IntelOperand()); + explicit IntelCommand(IFunction *owner, OperandSize size, const std::string &value); + explicit IntelCommand(IFunction *owner, OperandSize size, const os::unicode_string &value); + explicit IntelCommand(IFunction *owner, OperandSize size, const Data &value); + explicit IntelCommand(IFunction *owner, const IntelCommand &source); + ~IntelCommand(); + virtual void clear(); + virtual IntelCommand *Clone(IFunction *owner) const; + virtual void CompileToNative(); + virtual void CompileLink(const CompileContext &ctx); + virtual void PrepareLink(const CompileContext &ctx); + void CompileToVM(const CompileContext &ctx); + virtual uint64_t address() const { return address_; } + virtual CommandType type() const { return type_; } + IntelOperand operand(size_t index) const { + if (index >= _countof(operand_)) + throw std::runtime_error("subscript out of range"); + return operand_[index]; + } + const IntelOperand *operand_ptr(size_t index) const { + if (index >= _countof(operand_)) + throw std::runtime_error("subscript out of range"); + return &operand_[index]; + } + virtual std::string text() const; + virtual CommentInfo comment(); + virtual uint32_t section_options() const { return section_options_; } + virtual void set_address(uint64_t address); + virtual size_t original_dump_size() const { return (original_dump_size_) ? original_dump_size_ : dump_size(); } + IntelSegment base_segment() const { return base_segment_; } + CommandType preffix_command() const { return preffix_command_; } + OperandSize size() const { return size_; } + uint32_t flags() const { return flags_; } + void set_flags(uint32_t flags) { flags_ = flags; } + virtual ISEHandler *seh_handler() const { return seh_handler_; } + void set_seh_handler(ISEHandler *handler) { seh_handler_ = handler; } + size_t command_pos() const { return command_pos_; } + size_t ReadFromFile(IArchitecture &file); + uint64_t ReadValueFromFile(IArchitecture &file, OperandSize size); + void ReadArray(IArchitecture &file, size_t len); + virtual void ReadFromBuffer(Buffer &buffer, IArchitecture &file); + virtual void WriteToFile(IArchitecture &file); + virtual void set_operand_value(size_t operand_index, uint64_t value); + virtual void set_link_value(size_t link_index, uint64_t value); + virtual void set_jmp_value(size_t link_index, uint64_t value); + void set_operand_fixup(size_t operand_index, IFixup *fixup); + void set_operand_relocation(size_t operand_index, IRelocation *relocation); + void set_operand_scale(size_t operand_index, uint8_t value); + void set_base_segment(IntelSegment base_segment) { base_segment_ = base_segment; } + void set_preffix_command(IntelCommandType preffix_command) { preffix_command_ = preffix_command; } + void Init(IntelCommandType type, IntelOperand operand1 = IntelOperand(), IntelOperand operand2 = IntelOperand(), IntelOperand operand3 = IntelOperand()); + void Init(const Data &data); + void InitUnknown(); + virtual bool is_data() const; + virtual bool is_end() const; + virtual void Rebase(uint64_t delta_base); + virtual void include_section_option(SectionOption option) { section_options_ |= option; } + virtual void exclude_section_option(SectionOption option) { section_options_ &= ~option; } + IntelVMCommand *AddVMCommand(const CompileContext &ctx, IntelCommandType command_type, OperandType operand_type, OperandSize size, uint64_t value, uint32_t options = 0, IFixup *fixup = NULL); + void AddBeginSection(const CompileContext &ctx, uint32_t options = 0); + void AddEndSection(const CompileContext &ctx, IntelCommandType end_command, uint8_t end_value = 0, uint32_t options = 0); + void AddExtSection(const CompileContext &ctx, IntelCommand *command); + uint64_t AddStoreEIPSection(const CompileContext &ctx, uint64_t prev_eip); + void AddStoreExtRegistrSection(const CompileContext &ctx, uint8_t registr); + void AddStoreExtRegistersSection(const CompileContext &ctx); + void AddCryptorSection(const CompileContext &ctx, ValueCryptor *cryptor, bool is_decrypt); + IntelVMCommand *item(size_t index) const { return reinterpret_cast<IntelVMCommand *>(BaseCommand::item(index)); } + virtual uint64_t ext_vm_address() const { return (ext_vm_entry_) ? ext_vm_entry_->address() : vm_address(); } + virtual std::string dump_str() const; + virtual std::string display_address() const; + bool is_equal(const IntelCommand &command) const; + IntelVMCommand *ext_vm_entry() const { return ext_vm_entry_; } + bool GetCommandInfo(IntelCommandInfoList &command_info_list) const; + virtual bool Merge(ICommand *command); + uint8_t ReadDataByte(EncodedData &data, size_t *pos); + uint16_t ReadDataWord(EncodedData &data, size_t *pos); + uint32_t ReadDataDWord(EncodedData &data, size_t *pos); + uint64_t ReadDataQWord(EncodedData &data, size_t *pos); + uint64_t ReadUleb128(EncodedData &data, size_t *pos); + int64_t ReadSleb128(EncodedData &data, size_t *pos); + uint64_t ReadEncoding(EncodedData &data, uint8_t encoding, size_t *pos); + std::string ReadString(EncodedData &data, size_t *pos); + void ReadData(EncodedData &data, size_t size, size_t *pos); + int32_t ReadCompressedValue(IArchitecture &file); +#ifdef CHECKED + virtual bool check_hash() const; + void update_hash(); +#endif +private: + bool GetOperandText(std::string &str, size_t index) const; + IntelOperand *GetFreeOperand(); + // disasm methods + void ReadCommand(IntelCommandType type, uint32_t of_1, uint32_t of_2, uint32_t of_3, DisasmContext &ctx); + void ReadRegFromRM(uint8_t code, OperandSize operand_size, OperandType operand_type, const DisasmContext &ctx); + void ReadRM(uint8_t code, OperandSize operand_size, OperandType operand_type, bool show_size, const DisasmContext &ctx); + void ReadReg(uint8_t code, OperandSize operand_size, OperandType operand_type, const DisasmContext &ctx); + IntelOperand *ReadValue(OperandSize operand_size, OperandSize value_size, const DisasmContext &ctx); + void ReadValueAddAddress(OperandSize operand_size, OperandSize value_size, const DisasmContext &ctx); + void ReadFlags(uint8_t code); + // asm methods + void PushReg(size_t operand_index, uint8_t add_code, AsmContext &ctx); + void PushRM(size_t operand_index, uint8_t add_code, AsmContext &ctx); + void PushRegAndRM(size_t reg_operand_index, size_t rm_operand_index, AsmContext &ctx); + void PushFlags(uint8_t add_code); + void PushPrefix(AsmContext &ctx); + void PushBytePrefix(uint8_t prefix); + void PushWordPrefix(); + // virtualization methods + void CompileOperand(const CompileContext &ctx, size_t operand_index, uint32_t options = 0); + void AddCorrectOperandSizeSection(const CompileContext &ctx, OperandSize src, OperandSize dst); + void AddCombineFlagsSection(const CompileContext &ctx, uint16_t mask); + void AddRegistrAndValueSection(const CompileContext &ctx, uint8_t registr, OperandSize registr_size, uint64_t value, bool need_pushf = false); + void AddRegistrOrValueSection(const CompileContext &ctx, uint8_t registr, OperandSize registr_size, uint64_t value, bool need_pushf = false); + void AddCorrectFlagSection(const CompileContext &ctx, uint16_t flags); + void AddExtractFlagSection(const CompileContext &ctx, uint16_t flags, bool is_inverse, uint8_t extract_to); + void AddJmpWithFlagSection(const CompileContext &ctx, IntelCommandType command_type); + void AddCorrectESPSection(const CompileContext &ctx, OperandSize operand_size, size_t value); + void AddCheckBreakpointSection(const CompileContext &ctx, OperandSize address_size); + void AddCheckCRCSection(const CompileContext &ctx, OperandSize address_size); +#ifdef CHECKED + uint32_t calc_hash() const; + uint32_t hash_; +#endif + + uint64_t address_; + IntelOperand operand_[3]; + uint32_t vex_operand_; + uint32_t flags_; + + std::vector<IntelVMCommand *> vm_links_; + InternalLinkList internal_links_; + std::vector<IntelVMCommand *> jmp_links_; + + IntelVMCommand *ext_vm_entry_; + SectionCryptor *begin_section_cryptor_; + SectionCryptor *end_section_cryptor_; + IntelCommandInfoList *vm_command_info_list_; + + size_t command_pos_; + size_t original_dump_size_; + uint32_t section_options_; + + IntelCommandType type_; + IntelCommandType preffix_command_; + + OperandSize size_; + IntelSegment base_segment_; + + ISEHandler *seh_handler_; + + // no copy ctr or assignment op + IntelCommand(const IntelCommand &); + IntelCommand &operator =(const IntelCommand &); +}; + +class SectionCryptorList; + +class SectionCryptor : public IObject +{ +public: + explicit SectionCryptor(SectionCryptorList *owner, OperandSize cpu_address_size); + ~SectionCryptor(); + ByteList *registr_order() { return ®istr_order_; } + SectionCryptor *end_cryptor(); + void set_end_cryptor(SectionCryptor *cryptor); +private: + SectionCryptorList *owner_; + ByteList registr_order_; + SectionCryptor *parent_cryptor_; +}; + +class SectionCryptorList : public ObjectList<SectionCryptor> +{ +public: + explicit SectionCryptorList(IFunction *owner); + SectionCryptor *Add(); +private: + IFunction *owner_; +}; + +enum ReadMarkerOption { + moNone, + moNeedParam = 0x1, + moForward = 0x2, + moSkipLastCall = 0x4 +}; + +class IntelFunction : public BaseFunction +{ +public: + explicit IntelFunction(IFunctionList *owner, const std::string &name, CompilationType compilation_type, uint32_t compilation_options, bool need_compile, Folder *folder); + explicit IntelFunction(IFunctionList *owner = NULL); + explicit IntelFunction(IFunctionList *owner, OperandSize cpu_address_size, IFunction *parent = NULL); + explicit IntelFunction(IFunctionList *owner, const IntelFunction &src); + virtual ~IntelFunction(); + virtual void clear(); + virtual IntelFunction *Clone(IFunctionList *owner) const; + IntelCommand *item(size_t index) const { return reinterpret_cast<IntelCommand *>(IFunction::item(index)); } + IntelCommand *ReadValidCommand(IArchitecture &file, uint64_t address); + void ReadMarkerCommands(IArchitecture &file, MarkerCommandList &command_list, uint64_t address, uint32_t options); + virtual bool Compile(const CompileContext &ctx); + virtual void AfterCompile(const CompileContext &ctx); + virtual void CompileLinks(const CompileContext &ctx); + virtual bool Init(const CompileContext &ctx); + virtual bool Prepare(const CompileContext &ctx); + virtual bool PrepareExtCommands(const CompileContext &ctx); + virtual void CompileInfo(const CompileContext &ctx); + IntelCommand *AddCommand(OperandSize value_size, uint64_t value); + IntelCommand *AddCommand(const std::string &value); + IntelCommand *AddCommand(const os::unicode_string &value); + IntelCommand *AddCommand(const Data &value); + IntelCommand *Add(uint64_t address); + IntelCommand *AddCommand(IntelCommandType type, IntelOperand operand1 = IntelOperand(), IntelOperand operand2 = IntelOperand(), IntelOperand operand3 = IntelOperand()); + SectionCryptorList *section_cryptor_list() { return section_cryptor_list_; } + void AddWatermarkReference(uint64_t address, const std::string &value); + IntelCommand *GetCommandByAddress(uint64_t address) const; + IntelCommand *GetCommandByNearAddress(uint64_t address) const; + virtual void ReadFromBuffer(Buffer &buffer, IArchitecture &file); + bool ParseNewSEH(IArchitecture &file, uint64_t address); + bool ParseCxxSEH(IArchitecture &file, uint64_t address); + bool ParseCompressedCxxSEH(IArchitecture &file, uint64_t address, uint64_t begin); + bool ParseScopeSEH(IArchitecture &file, uint64_t address, uint32_t table_count); + virtual IntelCommand *ParseCommand(IArchitecture &file, uint64_t address, bool dump_mode = false); + uint64_t ParseParam(IArchitecture &file, size_t index, uint64_t ¶m_reference); +protected: + virtual IntelCommand *CreateCommand(); + virtual IntelCommand *ParseString(IArchitecture &file, uint64_t address, size_t len); + virtual void ParseBeginCommands(IArchitecture &file); + virtual void ParseEndCommands(IArchitecture &file); + virtual uint64_t GetNextAddress(IArchitecture &file); + virtual IntelFunction *CreateFunction(IFunction *parent = NULL) { return new IntelFunction(NULL, cpu_address_size(), parent); } + void CompileToNative(const CompileContext &ctx); + void CompileToVM(const CompileContext &ctx); + void CreateBlocks(); +private: + bool ParseFilterSEH(IArchitecture &file, uint64_t address); + bool ParseSwitch(IArchitecture &file, uint64_t address, OperandSize value_size, uint64_t add_value, IntelCommand *parent_command, size_t mode, size_t max_table_count); + bool ParseSEH3(IArchitecture &file, uint64_t address); + bool ParseSEH4(IArchitecture &file, uint64_t address); + bool ParseVB6SEH(IArchitecture &file, uint64_t address); + bool ParseBCBSEH(IArchitecture &file, uint64_t address, uint64_t next_address, uint8_t version); + bool ParseDelphiSEH(IArchitecture &file, uint64_t address); + CompilerFunction *ParseCompilerFunction(IArchitecture &file, uint64_t address); + IntelCommand *AddGate(ICommand *to_command, AddressRange *address_range); + IntelCommand *AddShortGate(ICommand *to_command, AddressRange *address_range); + + uint64_t GetRegistrValue(uint8_t reg, size_t end_index); + uint64_t GetRegistrMaxValue(uint8_t reg, size_t end_index, IArchitecture &file); + void GetFreeRegisters(size_t index, CommandInfoList &command_info_list) const; + void Mutate(const CompileContext &ctx, bool for_virtualization, int index = 0); + + SectionCryptorList *section_cryptor_list_; + std::set<uint64_t> break_case_list_; + + // no copy ctr or assignment op + IntelFunction(const IntelFunction &); + IntelFunction &operator =(const IntelFunction &); +}; + +class IntelStack; +class IntelFlagsValue; + +enum ValueType { + vtNone = 0, + vtValue = 1, + vtRegistr = 2, + vtReturnAddress = 4 +}; + +class IntelStackValue : public IObject +{ +public: + IntelStackValue(IntelStack *owner, ValueType type, uint64_t value); + ~IntelStackValue(); + ValueType type() const { return type_; } + uint64_t value() const { return value_; } + void set_value(uint64_t value) { value_ = value; } + bool is_modified() const { return is_modified_; } + void set_is_modified(bool value) { is_modified_ = value; } + void Calc(IntelCommandType command_type, uint16_t command_flags, bool inverse_flags, OperandSize size, uint64_t op2, IntelFlagsValue *flags); +private: + IntelStack *owner_; + ValueType type_; + uint64_t value_; + bool is_modified_; +}; + +class IntelStack : public ObjectList<IntelStackValue> +{ +public: + IntelStack(); + IntelStackValue *Add(ValueType type, uint64_t value); + IntelStackValue *Insert(size_t index, ValueType type, uint64_t value); + IntelStackValue *GetRegistr(uint8_t reg) const; + IntelStackValue *GetRandom(uint32_t types); +}; + +class IntelRegistrValue : public IntelStackValue +{ +public: + IntelRegistrValue(IntelStack *owner, uint8_t registr, uint64_t value) + : IntelStackValue(owner, vtValue, value), registr_(registr) { } + uint8_t registr() const { return registr_; } +private: + uint8_t registr_; +}; + +class IntelFlagsValue : public IObject +{ +public: + IntelFlagsValue(); + uint32_t mask() const { return mask_; } + uint32_t value() const { return value_; } + void Calc(IntelCommandType command_type, OperandSize size, uint64_t op1, uint64_t op2, uint64_t result); + uint16_t GetRandom() const; + bool Check(uint16_t flags) const; + void clear() { + mask_ = 0; + value_ = 0; + } +private: + void exclude(uint16_t mask); + + uint32_t mask_; + uint32_t value_; +}; + +class IntelRegistrStorage : public IntelStack +{ +public: + IntelRegistrStorage(); + IntelRegistrValue *item(size_t index) const; + IntelRegistrValue *GetRegistr(uint8_t reg) const; + IntelRegistrValue *Add(uint8_t reg, uint64_t value); +}; + +class IntelObfuscation : public IObject +{ +public: + explicit IntelObfuscation(); + void Compile(IntelFunction *func, size_t index, size_t end_index = -1, bool for_virtualization = false); +private: + IntelCommand *AddCommand(IntelCommandType type, IntelOperand operand1 = IntelOperand(), IntelOperand operand2 = IntelOperand(), IntelOperand operand3 = IntelOperand()); + void AddRandomCommands(); + void AddRestoreStack(size_t to_index); + void AddRestoreRegistr(uint8_t reg); + void AddRestoreStackItem(IntelStackValue *stack_item); + void CompileOperand(IntelOperand *operand); + + IntelFunction *func_; + AddressRange *address_range_; + std::vector<IntelCommand *> command_list_; + IntelStack stack_; + IntelRegistrStorage registr_values_; + IntelFlagsValue flags_; + std::map<IntelCommand *, size_t> jmp_command_list_; +}; + +class IntelFileHelper : public IObject +{ +public: + explicit IntelFileHelper(); + ~IntelFileHelper(); + void Parse(IArchitecture &file); +private: + void AddMarker(IArchitecture &file, uint64_t address, uint64_t name_reference, uint64_t name_address, ObjectType type, uint8_t tag, bool is_unicode); + void AddString(IArchitecture &file, uint64_t address, uint64_t reference, bool is_unicode); + void AddEndMarker(IArchitecture &file, uint64_t address, uint64_t next_address, ObjectType type); + + std::vector<MapFunction *> string_list_; + MapFunctionList *marker_name_list_; + size_t marker_index_; + + // no copy ctr or assignment op + IntelFileHelper(const IntelFileHelper &); + IntelFileHelper &operator =(const IntelFileHelper &); +}; + +class IntelSDK : public IntelFunction +{ +public: + explicit IntelSDK(IFunctionList *owner, OperandSize cpu_address_size); + virtual bool Init(const CompileContext &ctx); +}; + +class PEIntelSDK : public IntelSDK +{ +public: + explicit PEIntelSDK(IFunctionList *owner, OperandSize cpu_address_size); + virtual bool Init(const CompileContext &ctx); +}; + +class PEIntelExport : public IntelFunction +{ +public: + explicit PEIntelExport(IFunctionList *owner, OperandSize cpu_address_size); + virtual bool Init(const CompileContext &ctx); + virtual bool Compile(const CompileContext &ctx); + uint32_t size() const { return size_; } +private: + uint32_t size_; +}; + +class PEImportFunction; +class IntelImport : public IntelFunction +{ +public: + explicit IntelImport(IFunctionList *owner, OperandSize cpu_address_size); + bool Init(const CompileContext &ctx); + IntelCommand *GetIATCommand(PEImportFunction *import_function) const; +private: + struct IATInfo { + PEImportFunction *import_function; + IntelCommand *command; + bool from_runtime; + }; + std::vector<IATInfo> iat_info_list_; +}; + +class IntelCRCTable : public IntelFunction +{ +public: + explicit IntelCRCTable(IFunctionList *owner, OperandSize cpu_address_size); + virtual bool Init(const CompileContext &ctx); + size_t table_size() const { return (count() - 2) * OperandSizeToValue(osDWord); } + IntelCommand *table_entry() const { return item(0); } + IntelCommand *size_entry() const { return size_entry_; } + IntelCommand *hash_entry() const { return hash_entry_; } +private: + IntelCommand *size_entry_; + IntelCommand *hash_entry_; +}; + +class IntelRuntimeData : public IntelFunction +{ +public: + explicit IntelRuntimeData(IFunctionList *owner, OperandSize cpu_address_size); + virtual bool Init(const CompileContext &ctx); + virtual size_t WriteToFile(IArchitecture &file); +private: + RC5Key rc5_key_; + uint32_t data_key_; + IntelCommand *strings_entry_; + uint32_t strings_size_; + IntelCommand *resources_entry_; + uint32_t resources_size_; + IntelCommand *trial_hwid_entry_; + uint32_t trial_hwid_size_; +#ifdef ULTIMATE + IntelCommand *license_data_entry_; + uint32_t license_data_size_; + IntelCommand *files_entry_; + uint32_t files_size_; + IntelCommand *registry_entry_; + uint32_t registry_size_; +#endif + + struct CommandCompareHelper { + bool operator () (const IntelCommand *left, IntelCommand *right) const; + }; +}; + +class IntelLoaderData : public IntelFunction +{ +public: + explicit IntelLoaderData(IFunctionList *owner, OperandSize cpu_address_size); + bool Init(const CompileContext &ctx); +}; + +class IntelWatermark : public IntelFunction +{ +public: + explicit IntelWatermark(IFunctionList *owner, OperandSize cpu_address_size); + bool Init(const CompileContext &ctx); +}; + +class IntelRuntimeCRCTable : public IntelFunction +{ +public: + explicit IntelRuntimeCRCTable(IFunctionList *owner, OperandSize cpu_address_size); + virtual void clear(); + virtual bool Compile(const CompileContext &ctx); + virtual size_t WriteToFile(IArchitecture &file); + size_t region_count() const { return region_info_list_.size(); } +private: + struct RegionInfo { + uint64_t address; + uint32_t size; + bool is_self_crc; + + RegionInfo(uint64_t address_, uint32_t size_, bool is_self_crc_) + : address(address_), size(size_), is_self_crc(is_self_crc_) + { + } + }; + std::vector<RegionInfo> region_info_list_; + ValueCryptor *cryptor_; +}; + +class IntelVirtualMachineProcessor; + +class IntelFunctionList : public BaseFunctionList +{ +public: + explicit IntelFunctionList(IArchitecture *owner); + explicit IntelFunctionList(IArchitecture *owner, const IntelFunctionList &src); + ~IntelFunctionList(); + virtual IntelFunctionList *Clone(IArchitecture *owner) const; + virtual IntelFunction *Add(const std::string &name, CompilationType compilation_type, uint32_t compilation_options, bool need_compile, Folder *folder); + IntelFunction *item(size_t index) const; + IntelFunction *GetFunctionByAddress(uint64_t address) const; + virtual bool Prepare(const CompileContext &ctx); + virtual void CompileLinks(const CompileContext &ctx); + IntelImport *import() const { return import_; } + virtual IntelCRCTable *crc_table() const { return crc_table_; } + IntelLoaderData *loader_data() const { return loader_data_; } + IntelRuntimeCRCTable *runtime_crc_table() const { return runtime_crc_table_; } + virtual void ReadFromBuffer(Buffer &buffer, IArchitecture &file); + virtual ValueCryptor *crc_cryptor() const { return crc_cryptor_; } + virtual IntelFunction *CreateFunction(OperandSize cpu_address_size = osDefault); + virtual bool GetRuntimeOptions() const; + IntelVirtualMachineProcessor *AddProcessor(OperandSize cpu_address_size); +protected: + virtual IntelSDK *AddSDK(OperandSize cpu_address_size); +private: + IntelImport *AddImport(OperandSize cpu_address_size); + IntelRuntimeData *AddRuntimeData(OperandSize cpu_address_size); + IntelCRCTable *AddCRCTable(OperandSize cpu_address_size); + IntelLoaderData *AddLoaderData(OperandSize cpu_address_size); + IntelFunction *AddWatermark(OperandSize cpu_address_size, Watermark *watermark, int copy_count); + IntelRuntimeCRCTable *AddRuntimeCRCTable(OperandSize cpu_address_size); + + ValueCryptor *crc_cryptor_; + IntelImport *import_; + IntelCRCTable *crc_table_; + IntelLoaderData *loader_data_; + IntelRuntimeCRCTable *runtime_crc_table_; + + // no copy ctr or assignment op + IntelFunctionList(const IntelFunctionList &); + IntelFunctionList &operator =(const IntelFunctionList &); +}; + +class PEIntelFunctionList : public IntelFunctionList +{ +public: + explicit PEIntelFunctionList(IArchitecture *owner); + explicit PEIntelFunctionList(IArchitecture *owner, const PEIntelFunctionList &src); + virtual PEIntelFunctionList *Clone(IArchitecture *owner) const; + virtual bool Prepare(const CompileContext &ctx); + PEIntelExport *AddExport(OperandSize cpu_address_size); + virtual void ReadFromBuffer(Buffer &buffer, IArchitecture &file); +protected: + virtual IntelSDK *AddSDK(OperandSize cpu_address_size); +}; + +class BaseIntelLoader : public IntelFunction +{ +public: + BaseIntelLoader(IntelFunctionList *owner, OperandSize cpu_address_size); + virtual bool Prepare(const CompileContext &ctx); + virtual bool Compile(const CompileContext &ctx); + virtual IVirtualMachine *virtual_machine(IVirtualMachineList *virtual_machine_list, ICommand *command) const; + uint64_t import_segment_address() const { return import_segment_address_; } + uint64_t data_segment_address() const { return data_segment_address_; } +protected: + struct LoaderInfo { + IntelCommand *data; + size_t size; + LoaderInfo(IntelCommand *data_, size_t size_) + : data(data_), size(size_) {} + }; + void AddAVBuffer(const CompileContext &ctx); +private: + std::set<ICommand *> command_group_; + uint64_t import_segment_address_; + uint64_t data_segment_address_; +}; + +class PESegment; + +class PEIntelLoader : public BaseIntelLoader +{ +public: + PEIntelLoader(IntelFunctionList *owner, OperandSize cpu_address_size); + virtual bool Prepare(const CompileContext &ctx); + IntelCommand *import_entry() const { return import_entry_; } + uint32_t import_size() const { return import_size_; } + IntelCommand *iat_entry() const { return iat_entry_; } + uint32_t iat_size() const { return iat_size_; } + IntelCommand *name_entry() const { return name_entry_; } + uint32_t name_size() const { return iat_size_; } + IntelCommand *export_entry() const { return export_entry_; } + uint32_t export_size() const { return export_size_; } + IntelCommand *tls_entry() const { return tls_entry_; } + uint32_t tls_size() const { return tls_size_; } + IntelCommand *delay_import_entry() const { return delay_import_entry_; } + uint32_t delay_import_size() const { return delay_import_size_; } + IntelCommand *resource_section_info() const { return resource_section_info_; } + IntelCommand *resource_packer_info() const { return resource_packer_info_; } + IntelCommand *file_crc_entry() const { return file_crc_entry_; } + uint32_t file_crc_size() const { return file_crc_size_; } + IntelCommand *file_crc_size_entry() const { return file_crc_size_entry_; } + IntelCommand *loader_crc_entry() const { return loader_crc_entry_; } + uint32_t loader_crc_size() const { return loader_crc_size_; } + IntelCommand *loader_crc_size_entry() const { return loader_crc_size_entry_; } + IntelCommand *loader_crc_hash_entry() const { return loader_crc_hash_entry_; } + IntelCommand *cfg_check_function_entry() const { return cfg_check_function_entry_; } + void set_security_cookie(uint64_t value) { security_cookie_ = value; } + void set_iat_address(uint64_t value) { iat_address_ = value; } + std::vector<uint64_t> cfg_address_list() const; +private: + IntelCommand *import_entry_; + uint32_t import_size_; + IntelCommand *iat_entry_; + uint32_t iat_size_; + IntelCommand *name_entry_; + IntelCommand *resource_section_info_; + IntelCommand *resource_packer_info_; + IntelCommand *export_entry_; + uint32_t export_size_; + IntelCommand *tls_entry_; + IntelCommand *tls_call_back_entry_; + uint32_t tls_size_; + IntelCommand *file_crc_entry_; + uint32_t file_crc_size_; + IntelCommand *file_crc_size_entry_; + IntelCommand *loader_crc_entry_; + uint32_t loader_crc_size_; + IntelCommand *loader_crc_size_entry_; + IntelCommand *loader_crc_hash_entry_; + IntelCommand *delay_import_entry_; + uint32_t delay_import_size_; + uint64_t security_cookie_; + uint64_t iat_address_; + IntelCommand *cfg_check_function_entry_; + + struct ImportInfo { + IntelCommand *original_first_thunk; + IntelCommand *name; + IntelCommand *first_thunk; + IntelCommand *loader_name; + }; + + struct ImportFunctionInfo { + PEImportFunction *import_function; + IntelCommand *name; + IntelCommand *thunk; + IntelCommand *loader_name; + ImportFunctionInfo(PEImportFunction *import_function_) + : import_function(import_function_), name(NULL), thunk(NULL), loader_name(NULL) {} + bool operator == (PEImportFunction *import_function_) const + { + return (import_function == import_function_); + } + }; + + struct PackerInfo { + PESegment *section; + uint64_t address; + size_t size; + IntelCommand *data; + bool operator == (PESegment *section_) const + { + return (section == section_); + } + }; +}; + +class MacArchitecture; +class MacImportFunction; +class MacFixup; +class MacSegment; +class MacSymbol; + +class MacIntelSDK : public IntelSDK +{ +public: + explicit MacIntelSDK(IFunctionList *owner, OperandSize cpu_address_size); +}; + +class MacIntelFunctionList : public IntelFunctionList +{ +public: + explicit MacIntelFunctionList(IArchitecture *owner); + explicit MacIntelFunctionList(IArchitecture *owner, const MacIntelFunctionList &src); + virtual MacIntelFunctionList *Clone(IArchitecture *owner) const; + virtual bool Prepare(const CompileContext &ctx); + virtual bool Compile(const CompileContext &ctx); +protected: + virtual IntelSDK *AddSDK(OperandSize cpu_address_size); +private: + std::map<MacImportFunction *, IntelCommand *> relocation_list_; +}; + +class MacIntelLoader : public BaseIntelLoader +{ +public: + MacIntelLoader(IntelFunctionList *owner, OperandSize cpu_address_size); + virtual bool Prepare(const CompileContext &ctx); + virtual bool Compile(const CompileContext &ctx); + IntelCommand *import_entry() const { return import_entry_; } + uint32_t import_size() const { return import_size_; } + IntelCommand *jmp_table_entry() const { return jmp_table_entry_; } + uint32_t jmp_table_size() const { return jmp_table_size_; } + IntelCommand *lazy_import_entry() const { return lazy_import_entry_; } + uint32_t lazy_import_size() const { return lazy_import_size_; } + IntelCommand *init_entry() const { return init_entry_; } + uint32_t init_size() const { return init_size_; } + IntelCommand *term_entry() const { return term_entry_; } + uint32_t term_size() const { return term_size_; } + IntelCommand *thread_variables_entry() const { return thread_variables_entry_; } + uint32_t thread_variables_size() const { return thread_variables_size_; } + IntelCommand *thread_data_entry() const { return thread_data_entry_; } + uint32_t thread_data_size() const { return thread_data_size_; } + IntelCommand *file_crc_entry() const { return file_crc_entry_; } + uint32_t file_crc_size() const { return file_crc_size_; } + IntelCommand *file_crc_size_entry() const { return file_crc_size_entry_; } + IntelCommand *loader_crc_entry() const { return loader_crc_entry_; } + uint32_t loader_crc_size() const { return loader_crc_size_; } + IntelCommand *loader_crc_size_entry() const { return loader_crc_size_entry_; } + IntelCommand *loader_crc_hash_entry() const { return loader_crc_hash_entry_; } + IntelCommand *file_entry() const { return file_entry_; } + std::vector<MacSegment *> packed_segment_list() const { return packed_segment_list_; } + IntelCommand *patch_section_entry() const { return patch_section_entry_; } +private: + IntelCommand *import_entry_; + uint32_t import_size_; + IntelCommand *jmp_table_entry_; + uint32_t jmp_table_size_; + IntelCommand *lazy_import_entry_; + uint32_t lazy_import_size_; + IntelCommand *init_entry_; + uint32_t init_size_; + IntelCommand *term_entry_; + uint32_t term_size_; + IntelCommand *thread_variables_entry_; + uint32_t thread_variables_size_; + IntelCommand *thread_data_entry_; + uint32_t thread_data_size_; + std::map<MacImportFunction *, IntelCommand *> import_function_info_; + std::map<MacFixup *, IntelCommand *> relocation_info_; + IntelCommand *file_crc_entry_; + uint32_t file_crc_size_; + IntelCommand *file_crc_size_entry_; + IntelCommand *loader_crc_entry_; + uint32_t loader_crc_size_; + IntelCommand *loader_crc_size_entry_; + IntelCommand *loader_crc_hash_entry_; + IntelCommand *file_entry_; + IntelCommand *patch_section_entry_; + std::vector<MacSegment *> packed_segment_list_; + + struct PackerInfo { + uint64_t address; + size_t size; + MacSegment *segment; + IntelCommand *data; + PackerInfo() + : address(0), size(0), segment(NULL), data(NULL) + { + } + + PackerInfo(MacSegment *segment_, uint64_t address_, size_t size_) + : address(address_), size(size_), segment(segment_), data(NULL) + { + } + + bool operator == (MacSegment *segment_) const + { + return (segment == segment_); + } + }; +}; + +class ELFImportFunction; +class ELFSegment; +class ELFFixup; +class ELFArchitecture; + +class ELFIntelSDK : public IntelSDK +{ +public: + explicit ELFIntelSDK(IFunctionList *owner, OperandSize cpu_address_size); +}; + +class ELFIntelFunctionList : public IntelFunctionList +{ +public: + explicit ELFIntelFunctionList(IArchitecture *owner); + explicit ELFIntelFunctionList(IArchitecture *owner, const ELFIntelFunctionList &src); + virtual ELFIntelFunctionList *Clone(IArchitecture *owner) const; + virtual void ReadFromBuffer(Buffer &buffer, IArchitecture &file); +protected: + virtual IntelSDK *AddSDK(OperandSize cpu_address_size); +}; + +class ELFIntelLoader : public BaseIntelLoader +{ +public: + ELFIntelLoader(IntelFunctionList *owner, OperandSize cpu_address_size); + virtual bool Prepare(const CompileContext &ctx); + virtual bool Compile(const CompileContext &ctx); + IntelCommand *import_entry() const { return import_entry_; } + uint32_t import_size() const { return import_size_; } + IntelCommand *file_crc_entry() const { return file_crc_entry_; } + uint32_t file_crc_size() const { return file_crc_size_; } + IntelCommand *file_crc_size_entry() const { return file_crc_size_entry_; } + IntelCommand *loader_crc_entry() const { return loader_crc_entry_; } + uint32_t loader_crc_size() const { return loader_crc_size_; } + IntelCommand *loader_crc_size_entry() const { return loader_crc_size_entry_; } + IntelCommand *loader_crc_hash_entry() const { return loader_crc_hash_entry_; } + IntelCommand *term_entry() const { return term_entry_ ? reinterpret_cast<IntelCommand *>(term_entry_->link()->to_command()) : NULL; } + IntelCommand *preinit_entry() const { return preinit_entry_; } + uint32_t preinit_size() const { return preinit_size_; } + IntelCommand *init_entry() const { return init_entry_; } + IntelCommand *tls_entry() const { return tls_entry_; } + uint32_t GetPackedSize(ELFArchitecture *file) const; +private: + IntelCommand *import_entry_; + uint32_t import_size_; + IntelCommand *file_crc_entry_; + uint32_t file_crc_size_; + IntelCommand *file_crc_size_entry_; + IntelCommand *loader_crc_entry_; + uint32_t loader_crc_size_; + IntelCommand *loader_crc_size_entry_; + IntelCommand *loader_crc_hash_entry_; + IntelCommand *preinit_entry_; + uint32_t preinit_size_; + IntelCommand *term_entry_; + IntelCommand *init_entry_; + IntelCommand *tls_entry_; + IntelCommand *relro_entry_; + + struct PackerInfo { + uint64_t address; + size_t size; + ELFSegment *segment; + IntelCommand *data; + PackerInfo() + : address(0), size(0), segment(NULL), data(NULL) + { + } + + PackerInfo(ELFSegment *segment_, uint64_t address_, size_t size_) + : address(address_), size(size_), segment(segment_), data(NULL) + { + } + + bool operator == (ELFSegment *segment_) const + { + return (segment == segment_); + } + }; +}; + +class IntelOpcodeList; + +class IntelOpcodeInfo : public IObject +{ +public: + IntelOpcodeInfo(IntelOpcodeList *owner, IntelCommandType command_type, OperandType operand_type, OperandSize size, uint8_t value, IntelCommand *entry, OpcodeCryptor *value_cryptor = NULL, OpcodeCryptor *end_cryptor = NULL); + ~IntelOpcodeInfo(); + IntelCommandType command_type() const { return command_type_; } + OperandType operand_type() const { return operand_type_; } + OperandSize size() const { return size_; } + uint8_t value() const { return value_; } + IntelCommand *entry() const { return entry_; } + uint8_t opcode() const { return opcode_; } + void set_opcode(uint8_t opcode) { opcode_ = opcode; } + OpcodeCryptor *value_cryptor() const { return value_cryptor_; } + OpcodeCryptor *end_cryptor() const { return end_cryptor_; } + uint64_t Key(); + static uint64_t Key(IntelCommandType command_type, OperandType operand_type, OperandSize size, uint8_t value); + class circular_queue : public std::vector<IntelOpcodeInfo *> + { + size_t position_; + public: + circular_queue() : std::vector<IntelOpcodeInfo *>(), position_(0) {} + IntelOpcodeInfo *Next(); + }; +private: + IntelOpcodeList *owner_; + IntelCommand *entry_; + IntelCommandType command_type_; + OperandType operand_type_; + OperandSize size_; + uint8_t value_; + uint8_t opcode_; + OpcodeCryptor *value_cryptor_; + OpcodeCryptor *end_cryptor_; +}; + +class IntelOpcodeList : public ObjectList<IntelOpcodeInfo> +{ +public: + IntelOpcodeList(); + IntelOpcodeInfo *Add(IntelCommandType command_type, OperandType operand_type, OperandSize size, uint8_t value, IntelCommand *entry = NULL, OpcodeCryptor *value_cryptor = NULL, OpcodeCryptor *end_cryptor = NULL); + IntelOpcodeInfo *GetOpcodeInfo(IntelCommandType command_type, OperandType operand_type, OperandSize size, uint8_t value) const; +}; + +class IntelRegistrList : public std::vector<uint8_t> +{ +public: + IntelRegistrList() : std::vector<uint8_t>() {} + uint8_t GetRandom(bool no_solid = false) + { + if (empty()) + return regEmpty; + uint8_t res; + while (true) { + size_t i = rand() % size(); + res = at(i); + if (no_solid && (res == regESI || res == regEDI || res == regEBP)) + continue; + erase(begin() + i); + break; + } + return res; + } + void remove(uint8_t reg) + { + iterator it = std::find(begin(), end(), reg); + if (it != end()) + erase(it); + } + void remove(const IntelRegistrList ®_list) + { + for (size_t i = 0; i < reg_list.size(); i++) { + remove(reg_list[i]); + } + } +}; + +enum VirtualMachineType { + vtClassic, + vtAdvanced +}; + +struct IntelVirtualMachineObfuscation +{ + IntelCommand *begin_; + IntelCommand *end_; + + IntelVirtualMachineObfuscation(IntelCommand *begin, IntelCommand *end) : begin_(begin), end_(end) { + } +}; + +class IntelVirtualMachineProcessor : public IntelFunction +{ +public: + IntelVirtualMachineProcessor(IntelFunctionList *parent, OperandSize cpu_address_size); + virtual bool Prepare(const CompileContext &ctx); + void AddExceptionHandler(const CompileContext &ctx); + void AddObfuscation(size_t old_count); + void AddObfuscationHandler(IntelCommand *begin); + + std::vector<std::unique_ptr<IntelVirtualMachineObfuscation>> obfuscation_list_; +}; + +class IntelVirtualMachineList; + +class IntelVirtualMachine : public BaseVirtualMachine +{ +public: + IntelVirtualMachine(IntelVirtualMachineList *owner, VirtualMachineType type, uint8_t id, IntelVirtualMachineProcessor *processor); + ~IntelVirtualMachine(); + void Init(const CompileContext &ctx, const IntelOpcodeList &visible_opcode_list); + void Prepare(const CompileContext &ctx); + ByteList *registr_order() { return ®istr_order_; } + virtual bool backward_direction() const { return backward_direction_; } + void CompileCommand(IntelVMCommand &vm_command); + void CompileBlock(CommandBlock &block, bool need_encrypt); + void AddExtJmpCommand(uint8_t id); + ValueCryptor *entry_cryptor() const { return &const_cast<ValueCryptor &>(entry_cryptor_); } + VirtualMachineType type() const { return type_; } + IntelCommand *entry_command() const { return entry_command_; } + IntelCommand *init_command() const { return init_command_; } + virtual IntelFunction *processor() const { return processor_; } +private: + IntelCommand *AddReadCommand(OperandSize size, OpcodeCryptor *command_cryptor, uint8_t registr); + void AddValueCommand(ValueCommand &value_command, bool is_decrypt, uint8_t registr); + void AddEndHandlerCommands(IntelCommand *to_command, OpcodeCryptor *command_cryptor); + IntelCommand *CloneHandler(IntelCommand *handler); + void InitCommands(const CompileContext &ctx, const IntelOpcodeList &visible_opcode_list); + void AddCallCommands(CallingConvention calling_convention, IntelCommand *call_entry, uint8_t registr); + IntelOpcodeInfo *GetOpcode(IntelCommandType command_type, OperandType operand_type, OperandSize size, uint8_t value); + bool IsRegistrUsed(uint8_t registr); + std::vector<OpcodeCryptor *> GetOpcodeCryptorList(IntelVMCommand *command); + VirtualMachineType type_; + IntelVirtualMachineProcessor *processor_; + IntelRegistrList registr_list_; + IntelOpcodeList opcode_list_; + std::unordered_map<uint64_t, IntelOpcodeInfo::circular_queue> opcode_stack_; + ByteList registr_order_; + ValueCryptor entry_cryptor_; + OpcodeCryptor *command_cryptor_; + std::vector<OpcodeCryptor *> cryptor_list_; + IntelCommand *entry_command_; + IntelCommand *init_command_; + IntelCommand *ext_jmp_command_; + bool backward_direction_; + std::vector<IntelCommand *> vm_links_; + uint8_t stack_registr_; + uint8_t pcode_registr_; + uint8_t jmp_registr_; + uint8_t crypt_registr_; + IntelRegistrList free_registr_list_; + + // no copy ctr or assignment op + IntelVirtualMachine(const IntelVirtualMachine &); + IntelVirtualMachine &operator =(const IntelVirtualMachine &); +}; + +class IntelVirtualMachineList : public IVirtualMachineList +{ +public: + IntelVirtualMachineList(); + ~IntelVirtualMachineList(); + virtual void Prepare(const CompileContext &ctx); + IntelVirtualMachine *item(size_t index) const { return reinterpret_cast<IntelVirtualMachine *>(IVirtualMachineList::item(index)); } + virtual IntelVirtualMachineList *Clone() const; + uint64_t GetCRCValue(uint64_t &address, size_t size); + void ClearCRCMap(); +private: + MemoryManager *crc_manager_; + std::map<uint64_t, ICommand *> map_; + + // no copy ctr or assignment op + IntelVirtualMachineList(const IntelVirtualMachineList &); + IntelVirtualMachineList &operator =(const IntelVirtualMachineList &); +}; + +#endif
\ No newline at end of file |