#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(type) << 48; if (type & (otRegistr | otSegmentRegistr | otControlRegistr | otDebugRegistr | otFPURegistr | otHiPartRegistr | otMMXRegistr | otXMMRegistr)) res |= static_cast(registr) << 44; if (type & otBaseRegistr) res |= static_cast(base_registr) << 40; if (type & otValue) res |= static_cast(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(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(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 vm_links_; InternalLinkList internal_links_; std::vector 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 { 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(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 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 { 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 command_list_; IntelStack stack_; IntelRegistrStorage registr_values_; IntelFlagsValue flags_; std::map 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 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 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 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 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 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 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 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 import_function_info_; std::map 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 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(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 { size_t position_; public: circular_queue() : std::vector(), 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 { 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 { public: IntelRegistrList() : std::vector() {} 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> 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(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 GetOpcodeCryptorList(IntelVMCommand *command); VirtualMachineType type_; IntelVirtualMachineProcessor *processor_; IntelRegistrList registr_list_; IntelOpcodeList opcode_list_; std::unordered_map opcode_stack_; ByteList registr_order_; ValueCryptor entry_cryptor_; OpcodeCryptor *command_cryptor_; std::vector cryptor_list_; IntelCommand *entry_command_; IntelCommand *init_command_; IntelCommand *ext_jmp_command_; bool backward_direction_; std::vector 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(IVirtualMachineList::item(index)); } virtual IntelVirtualMachineList *Clone() const; uint64_t GetCRCValue(uint64_t &address, size_t size); void ClearCRCMap(); private: MemoryManager *crc_manager_; std::map map_; // no copy ctr or assignment op IntelVirtualMachineList(const IntelVirtualMachineList &); IntelVirtualMachineList &operator =(const IntelVirtualMachineList &); }; #endif