libTriton version 1.0 build 1592
Loading...
Searching...
No Matches
x86Semantics.cpp
Go to the documentation of this file.
1
2/*
3** Copyright (C) - Triton
4**
5** This program is under the terms of the Apache License 2.0.
6*/
7
8#include <triton/cpuSize.hpp>
12#include <triton/astContext.hpp>
13
14
15
421namespace triton {
422 namespace arch {
423 namespace x86 {
424
428 const triton::modes::SharedModes& modes,
429 const triton::ast::SharedAstContext& astCtxt) : modes(modes), astCtxt(astCtxt) {
430
431 this->architecture = architecture;
432 this->exception = triton::arch::NO_FAULT;
433 this->symbolicEngine = symbolicEngine;
434 this->taintEngine = taintEngine;
435
436 if (architecture == nullptr)
437 throw triton::exceptions::Semantics("x86Semantics::x86Semantics(): The architecture API must be defined.");
438
439 if (this->symbolicEngine == nullptr)
440 throw triton::exceptions::Semantics("x86Semantics::x86Semantics(): The symbolic engine API must be defined.");
441
442 if (this->taintEngine == nullptr)
443 throw triton::exceptions::Semantics("x86Semantics::x86Semantics(): The taint engines API must be defined.");
444 }
445
446
448 this->exception = triton::arch::NO_FAULT;
449 switch (inst.getType()) {
450 case ID_INS_AAA: this->aaa_s(inst); break;
451 case ID_INS_AAD: this->aad_s(inst); break;
452 case ID_INS_AAM: this->aam_s(inst); break;
453 case ID_INS_AAS: this->aas_s(inst); break;
454 case ID_INS_ADC: this->adc_s(inst); break;
455 case ID_INS_ADCX: this->adcx_s(inst); break;
456 case ID_INS_ADD: this->add_s(inst); break;
457 case ID_INS_AND: this->and_s(inst); break;
458 case ID_INS_ANDN: this->andn_s(inst); break;
459 case ID_INS_ANDNPD: this->andnpd_s(inst); break;
460 case ID_INS_ANDNPS: this->andnps_s(inst); break;
461 case ID_INS_ANDPD: this->andpd_s(inst); break;
462 case ID_INS_ANDPS: this->andps_s(inst); break;
463 case ID_INS_BEXTR: this->bextr_s(inst); break;
464 case ID_INS_BLSI: this->blsi_s(inst); break;
465 case ID_INS_BLSMSK: this->blsmsk_s(inst); break;
466 case ID_INS_BLSR: this->blsr_s(inst); break;
467 case ID_INS_BSF: this->bsf_s(inst); break;
468 case ID_INS_BSR: this->bsr_s(inst); break;
469 case ID_INS_BSWAP: this->bswap_s(inst); break;
470 case ID_INS_BT: this->bt_s(inst); break;
471 case ID_INS_BTC: this->btc_s(inst); break;
472 case ID_INS_BTR: this->btr_s(inst); break;
473 case ID_INS_BTS: this->bts_s(inst); break;
474 case ID_INS_CALL: this->call_s(inst); break;
475 case ID_INS_CBW: this->cbw_s(inst); break;
476 case ID_INS_CDQ: this->cdq_s(inst); break;
477 case ID_INS_CDQE: this->cdqe_s(inst); break;
478 case ID_INS_CLC: this->clc_s(inst); break;
479 case ID_INS_CLD: this->cld_s(inst); break;
480 case ID_INS_CLFLUSH: this->clflush_s(inst); break;
481 case ID_INS_CLTS: this->clts_s(inst); break;
482 case ID_INS_CLI: this->cli_s(inst); break;
483 case ID_INS_CMC: this->cmc_s(inst); break;
484 case ID_INS_CMOVA: this->cmova_s(inst); break;
485 case ID_INS_CMOVAE: this->cmovae_s(inst); break;
486 case ID_INS_CMOVB: this->cmovb_s(inst); break;
487 case ID_INS_CMOVBE: this->cmovbe_s(inst); break;
488 case ID_INS_CMOVE: this->cmove_s(inst); break;
489 case ID_INS_CMOVG: this->cmovg_s(inst); break;
490 case ID_INS_CMOVGE: this->cmovge_s(inst); break;
491 case ID_INS_CMOVL: this->cmovl_s(inst); break;
492 case ID_INS_CMOVLE: this->cmovle_s(inst); break;
493 case ID_INS_CMOVNE: this->cmovne_s(inst); break;
494 case ID_INS_CMOVNO: this->cmovno_s(inst); break;
495 case ID_INS_CMOVNP: this->cmovnp_s(inst); break;
496 case ID_INS_CMOVNS: this->cmovns_s(inst); break;
497 case ID_INS_CMOVO: this->cmovo_s(inst); break;
498 case ID_INS_CMOVP: this->cmovp_s(inst); break;
499 case ID_INS_CMOVS: this->cmovs_s(inst); break;
500 case ID_INS_CMP: this->cmp_s(inst); break;
501 case ID_INS_CMPSB: this->cmpsb_s(inst); break;
502 case ID_INS_CMPSD: this->cmpsd_s(inst); break;
503 case ID_INS_CMPSQ: this->cmpsq_s(inst); break;
504 case ID_INS_CMPSW: this->cmpsw_s(inst); break;
505 case ID_INS_CMPXCHG: this->cmpxchg_s(inst); break;
506 case ID_INS_CMPXCHG16B: this->cmpxchg16b_s(inst); break;
507 case ID_INS_CMPXCHG8B: this->cmpxchg8b_s(inst); break;
508 case ID_INS_CPUID: this->cpuid_s(inst); break;
509 case ID_INS_CQO: this->cqo_s(inst); break;
510 case ID_INS_CWD: this->cwd_s(inst); break;
511 case ID_INS_CWDE: this->cwde_s(inst); break;
512 case ID_INS_DEC: this->dec_s(inst); break;
513 case ID_INS_DIV: this->div_s(inst); break;
514 case ID_INS_ENDBR32: this->endbr32_s(inst); break;
515 case ID_INS_ENDBR64: this->endbr64_s(inst); break;
516 case ID_INS_EXTRACTPS: this->extractps_s(inst); break;
517 case ID_INS_FXRSTOR64: this->fxrstor64_s(inst); break;
518 case ID_INS_FXRSTOR: this->fxrstor_s(inst); break;
519 case ID_INS_FXSAVE64: this->fxsave64_s(inst); break;
520 case ID_INS_FXSAVE: this->fxsave_s(inst); break;
521 case ID_INS_IDIV: this->idiv_s(inst); break;
522 case ID_INS_IMUL: this->imul_s(inst); break;
523 case ID_INS_INC: this->inc_s(inst); break;
524 case ID_INS_INVD: this->invd_s(inst); break;
525 case ID_INS_INVLPG: this->invlpg_s(inst); break;
526 case ID_INS_JA: this->ja_s(inst); break;
527 case ID_INS_JAE: this->jae_s(inst); break;
528 case ID_INS_JB: this->jb_s(inst); break;
529 case ID_INS_JBE: this->jbe_s(inst); break;
530 case ID_INS_JCXZ: this->jcxz_s(inst); break;
531 case ID_INS_JE: this->je_s(inst); break;
532 case ID_INS_JECXZ: this->jecxz_s(inst); break;
533 case ID_INS_JG: this->jg_s(inst); break;
534 case ID_INS_JGE: this->jge_s(inst); break;
535 case ID_INS_JL: this->jl_s(inst); break;
536 case ID_INS_JLE: this->jle_s(inst); break;
537 case ID_INS_JMP: this->jmp_s(inst); break;
538 case ID_INS_JNE: this->jne_s(inst); break;
539 case ID_INS_JNO: this->jno_s(inst); break;
540 case ID_INS_JNP: this->jnp_s(inst); break;
541 case ID_INS_JNS: this->jns_s(inst); break;
542 case ID_INS_JO: this->jo_s(inst); break;
543 case ID_INS_JP: this->jp_s(inst); break;
544 case ID_INS_JRCXZ: this->jrcxz_s(inst); break;
545 case ID_INS_JS: this->js_s(inst); break;
546 case ID_INS_LAHF: this->lahf_s(inst); break;
547 case ID_INS_LDDQU: this->lddqu_s(inst); break;
548 case ID_INS_LDMXCSR: this->ldmxcsr_s(inst); break;
549 case ID_INS_LEA: this->lea_s(inst); break;
550 case ID_INS_LEAVE: this->leave_s(inst); break;
551 case ID_INS_LFENCE: this->lfence_s(inst); break;
552 case ID_INS_LODSB: this->lodsb_s(inst); break;
553 case ID_INS_LODSD: this->lodsd_s(inst); break;
554 case ID_INS_LODSQ: this->lodsq_s(inst); break;
555 case ID_INS_LODSW: this->lodsw_s(inst); break;
556 case ID_INS_LOOP: this->loop_s(inst); break;
557 case ID_INS_LZCNT: this->lzcnt_s(inst); break;
558 case ID_INS_INT3: this->int3_s(inst); break;
559 case ID_INS_MFENCE: this->mfence_s(inst); break;
560 case ID_INS_MOV: this->mov_s(inst); break;
561 case ID_INS_MOVABS: this->movabs_s(inst); break;
562 case ID_INS_MOVAPD: this->movapd_s(inst); break;
563 case ID_INS_MOVAPS: this->movaps_s(inst); break;
564 case ID_INS_MOVBE: this->movbe_s(inst); break;
565 case ID_INS_MOVD: this->movd_s(inst); break;
566 case ID_INS_MOVDDUP: this->movddup_s(inst); break;
567 case ID_INS_MOVDQ2Q: this->movdq2q_s(inst); break;
568 case ID_INS_MOVDQA: this->movdqa_s(inst); break;
569 case ID_INS_MOVDQU: this->movdqu_s(inst); break;
570 case ID_INS_MOVHLPS: this->movhlps_s(inst); break;
571 case ID_INS_MOVHPD: this->movhpd_s(inst); break;
572 case ID_INS_MOVHPS: this->movhps_s(inst); break;
573 case ID_INS_MOVLHPS: this->movlhps_s(inst); break;
574 case ID_INS_MOVLPD: this->movlpd_s(inst); break;
575 case ID_INS_MOVLPS: this->movlps_s(inst); break;
576 case ID_INS_MOVMSKPD: this->movmskpd_s(inst); break;
577 case ID_INS_MOVMSKPS: this->movmskps_s(inst); break;
578 case ID_INS_MOVNTDQ: this->movntdq_s(inst); break;
579 case ID_INS_MOVNTI: this->movnti_s(inst); break;
580 case ID_INS_MOVNTPD: this->movntpd_s(inst); break;
581 case ID_INS_MOVNTPS: this->movntps_s(inst); break;
582 case ID_INS_MOVNTQ: this->movntq_s(inst); break;
583 case ID_INS_MOVQ2DQ: this->movq2dq_s(inst); break;
584 case ID_INS_MOVQ: this->movq_s(inst); break;
585 case ID_INS_MOVSB: this->movsb_s(inst); break;
586 case ID_INS_MOVSD: this->movsd_s(inst); break;
587 case ID_INS_MOVSHDUP: this->movshdup_s(inst); break;
588 case ID_INS_MOVSLDUP: this->movsldup_s(inst); break;
589 case ID_INS_MOVUPD: this->movupd_s(inst); break;
590 case ID_INS_MOVUPS: this->movups_s(inst); break;
591 case ID_INS_MOVSS: this->movss_s(inst); break;
592 case ID_INS_MOVSQ: this->movsq_s(inst); break;
593 case ID_INS_MOVSW: this->movsw_s(inst); break;
594 case ID_INS_MOVSX: this->movsx_s(inst); break;
595 case ID_INS_MOVSXD: this->movsxd_s(inst); break;
596 case ID_INS_MOVZX: this->movzx_s(inst); break;
597 case ID_INS_MUL: this->mul_s(inst); break;
598 case ID_INS_MULX: this->mulx_s(inst); break;
599 case ID_INS_NEG: this->neg_s(inst); break;
600 case ID_INS_NOP: this->nop_s(inst); break;
601 case ID_INS_NOT: this->not_s(inst); break;
602 case ID_INS_OR: this->or_s(inst); break;
603 case ID_INS_ORPD: this->orpd_s(inst); break;
604 case ID_INS_ORPS: this->orps_s(inst); break;
605 case ID_INS_PACKUSWB: this->packuswb_s(inst); break;
606 case ID_INS_PACKSSDW: this->packssdw_s(inst); break;
607 case ID_INS_PACKSSWB: this->packsswb_s(inst); break;
608 case ID_INS_PADDB: this->paddb_s(inst); break;
609 case ID_INS_PADDD: this->paddd_s(inst); break;
610 case ID_INS_PADDQ: this->paddq_s(inst); break;
611 case ID_INS_PADDW: this->paddw_s(inst); break;
612 case ID_INS_PALIGNR: this->palignr_s(inst); break;
613 case ID_INS_PAND: this->pand_s(inst); break;
614 case ID_INS_PANDN: this->pandn_s(inst); break;
615 case ID_INS_PAUSE: this->pause_s(inst); break;
616 case ID_INS_PAVGB: this->pavgb_s(inst); break;
617 case ID_INS_PAVGW: this->pavgw_s(inst); break;
618 case ID_INS_PCMPEQB: this->pcmpeqb_s(inst); break;
619 case ID_INS_PCMPEQD: this->pcmpeqd_s(inst); break;
620 case ID_INS_PCMPEQW: this->pcmpeqw_s(inst); break;
621 case ID_INS_PCMPGTB: this->pcmpgtb_s(inst); break;
622 case ID_INS_PCMPGTD: this->pcmpgtd_s(inst); break;
623 case ID_INS_PCMPGTW: this->pcmpgtw_s(inst); break;
624 case ID_INS_PEXTRB: this->pextrb_s(inst); break;
625 case ID_INS_PEXTRD: this->pextrd_s(inst); break;
626 case ID_INS_PEXTRQ: this->pextrq_s(inst); break;
627 case ID_INS_PEXTRW: this->pextrw_s(inst); break;
628 case ID_INS_PINSRB: this->pinsrb_s(inst); break;
629 case ID_INS_PINSRD: this->pinsrd_s(inst); break;
630 case ID_INS_PINSRQ: this->pinsrq_s(inst); break;
631 case ID_INS_PINSRW: this->pinsrw_s(inst); break;
632 case ID_INS_PMADDWD: this->pmaddwd_s(inst); break;
633 case ID_INS_PMAXSB: this->pmaxsb_s(inst); break;
634 case ID_INS_PMAXSD: this->pmaxsd_s(inst); break;
635 case ID_INS_PMAXSW: this->pmaxsw_s(inst); break;
636 case ID_INS_PMAXUB: this->pmaxub_s(inst); break;
637 case ID_INS_PMAXUD: this->pmaxud_s(inst); break;
638 case ID_INS_PMAXUW: this->pmaxuw_s(inst); break;
639 case ID_INS_PMINSB: this->pminsb_s(inst); break;
640 case ID_INS_PMINSD: this->pminsd_s(inst); break;
641 case ID_INS_PMINSW: this->pminsw_s(inst); break;
642 case ID_INS_PMINUB: this->pminub_s(inst); break;
643 case ID_INS_PMINUD: this->pminud_s(inst); break;
644 case ID_INS_PMINUW: this->pminuw_s(inst); break;
645 case ID_INS_PMOVMSKB: this->pmovmskb_s(inst); break;
646 case ID_INS_PMOVSXBD: this->pmovsxbd_s(inst); break;
647 case ID_INS_PMOVSXBQ: this->pmovsxbq_s(inst); break;
648 case ID_INS_PMOVSXBW: this->pmovsxbw_s(inst); break;
649 case ID_INS_PMOVSXDQ: this->pmovsxdq_s(inst); break;
650 case ID_INS_PMOVSXWD: this->pmovsxwd_s(inst); break;
651 case ID_INS_PMOVSXWQ: this->pmovsxwq_s(inst); break;
652 case ID_INS_PMOVZXBD: this->pmovzxbd_s(inst); break;
653 case ID_INS_PMOVZXBQ: this->pmovzxbq_s(inst); break;
654 case ID_INS_PMOVZXBW: this->pmovzxbw_s(inst); break;
655 case ID_INS_PMOVZXDQ: this->pmovzxdq_s(inst); break;
656 case ID_INS_PMOVZXWD: this->pmovzxwd_s(inst); break;
657 case ID_INS_PMOVZXWQ: this->pmovzxwq_s(inst); break;
658 case ID_INS_PMULHW: this->pmulhw_s(inst); break;
659 case ID_INS_PMULLD: this->pmulld_s(inst); break;
660 case ID_INS_PMULLW: this->pmullw_s(inst); break;
661 case ID_INS_PMULUDQ: this->pmuludq_s(inst); break;
662 case ID_INS_POPCNT: this->popcnt_s(inst); break;
663 case ID_INS_POP: this->pop_s(inst); break;
664 case ID_INS_POPAL: this->popal_s(inst); break;
665 case ID_INS_POPF: this->popf_s(inst); break;
666 case ID_INS_POPFD: this->popfd_s(inst); break;
667 case ID_INS_POPFQ: this->popfq_s(inst); break;
668 case ID_INS_POR: this->por_s(inst); break;
669 case ID_INS_PREFETCH: this->prefetchx_s(inst); break;
670 case ID_INS_PREFETCHNTA: this->prefetchx_s(inst); break;
671 case ID_INS_PREFETCHT0: this->prefetchx_s(inst); break;
672 case ID_INS_PREFETCHT1: this->prefetchx_s(inst); break;
673 case ID_INS_PREFETCHT2: this->prefetchx_s(inst); break;
674 case ID_INS_PREFETCHW: this->prefetchx_s(inst); break;
675 case ID_INS_PSHUFB: this->pshufb_s(inst); break;
676 case ID_INS_PSHUFD: this->pshufd_s(inst); break;
677 case ID_INS_PSHUFHW: this->pshufhw_s(inst); break;
678 case ID_INS_PSHUFLW: this->pshuflw_s(inst); break;
679 case ID_INS_PSHUFW: this->pshufw_s(inst); break;
680 case ID_INS_PSLLD: this->pslld_s(inst); break;
681 case ID_INS_PSLLDQ: this->pslldq_s(inst); break;
682 case ID_INS_PSLLQ: this->psllq_s(inst); break;
683 case ID_INS_PSLLW: this->psllw_s(inst); break;
684 case ID_INS_PSRAD: this->psrad_s(inst); break;
685 case ID_INS_PSRAW: this->psraw_s(inst); break;
686 case ID_INS_PSRLD: this->psrld_s(inst); break;
687 case ID_INS_PSRLDQ: this->psrldq_s(inst); break;
688 case ID_INS_PSRLQ: this->psrlq_s(inst); break;
689 case ID_INS_PSRLW: this->psrlw_s(inst); break;
690 case ID_INS_PSUBB: this->psubb_s(inst); break;
691 case ID_INS_PSUBD: this->psubd_s(inst); break;
692 case ID_INS_PSUBQ: this->psubq_s(inst); break;
693 case ID_INS_PSUBW: this->psubw_s(inst); break;
694 case ID_INS_PTEST: this->ptest_s(inst); break;
695 case ID_INS_PUNPCKHBW: this->punpckhbw_s(inst); break;
696 case ID_INS_PUNPCKHDQ: this->punpckhdq_s(inst); break;
697 case ID_INS_PUNPCKHQDQ: this->punpckhqdq_s(inst); break;
698 case ID_INS_PUNPCKHWD: this->punpckhwd_s(inst); break;
699 case ID_INS_PUNPCKLBW: this->punpcklbw_s(inst); break;
700 case ID_INS_PUNPCKLDQ: this->punpckldq_s(inst); break;
701 case ID_INS_PUNPCKLQDQ: this->punpcklqdq_s(inst); break;
702 case ID_INS_PUNPCKLWD: this->punpcklwd_s(inst); break;
703 case ID_INS_PUSH: this->push_s(inst); break;
704 case ID_INS_PUSHAL: this->pushal_s(inst); break;
705 case ID_INS_PUSHFD: this->pushfd_s(inst); break;
706 case ID_INS_PUSHFQ: this->pushfq_s(inst); break;
707 case ID_INS_PXOR: this->pxor_s(inst); break;
708 case ID_INS_RCL: this->rcl_s(inst); break;
709 case ID_INS_RCR: this->rcr_s(inst); break;
710 case ID_INS_RDTSC: this->rdtsc_s(inst); break;
711 case ID_INS_RET: this->ret_s(inst); break;
712 case ID_INS_ROL: this->rol_s(inst); break;
713 case ID_INS_ROR: this->ror_s(inst); break;
714 case ID_INS_RORX: this->rorx_s(inst); break;
715 case ID_INS_SAHF: this->sahf_s(inst); break;
716 case ID_INS_SAL: this->shl_s(inst); break;
717 case ID_INS_SAR: this->sar_s(inst); break;
718 case ID_INS_SARX: this->sarx_s(inst); break;
719 case ID_INS_SBB: this->sbb_s(inst); break;
720 case ID_INS_SCASB: this->scasb_s(inst); break;
721 case ID_INS_SCASD: this->scasd_s(inst); break;
722 case ID_INS_SCASQ: this->scasq_s(inst); break;
723 case ID_INS_SCASW: this->scasw_s(inst); break;
724 case ID_INS_SETA: this->seta_s(inst); break;
725 case ID_INS_SETAE: this->setae_s(inst); break;
726 case ID_INS_SETB: this->setb_s(inst); break;
727 case ID_INS_SETBE: this->setbe_s(inst); break;
728 case ID_INS_SETE: this->sete_s(inst); break;
729 case ID_INS_SETG: this->setg_s(inst); break;
730 case ID_INS_SETGE: this->setge_s(inst); break;
731 case ID_INS_SETL: this->setl_s(inst); break;
732 case ID_INS_SETLE: this->setle_s(inst); break;
733 case ID_INS_SETNE: this->setne_s(inst); break;
734 case ID_INS_SETNO: this->setno_s(inst); break;
735 case ID_INS_SETNP: this->setnp_s(inst); break;
736 case ID_INS_SETNS: this->setns_s(inst); break;
737 case ID_INS_SETO: this->seto_s(inst); break;
738 case ID_INS_SETP: this->setp_s(inst); break;
739 case ID_INS_SETS: this->sets_s(inst); break;
740 case ID_INS_SFENCE: this->sfence_s(inst); break;
741 case ID_INS_SHL: this->shl_s(inst); break;
742 case ID_INS_SHLD: this->shld_s(inst); break;
743 case ID_INS_SHLX: this->shlx_s(inst); break;
744 case ID_INS_SHR: this->shr_s(inst); break;
745 case ID_INS_SHRD: this->shrd_s(inst); break;
746 case ID_INS_SHRX: this->shrx_s(inst); break;
747 case ID_INS_STC: this->stc_s(inst); break;
748 case ID_INS_STD: this->std_s(inst); break;
749 case ID_INS_STI: this->sti_s(inst); break;
750 case ID_INS_STMXCSR: this->stmxcsr_s(inst); break;
751 case ID_INS_STOSB: this->stosb_s(inst); break;
752 case ID_INS_STOSD: this->stosd_s(inst); break;
753 case ID_INS_STOSQ: this->stosq_s(inst); break;
754 case ID_INS_STOSW: this->stosw_s(inst); break;
755 case ID_INS_SUB: this->sub_s(inst); break;
756 case ID_INS_SYSCALL: this->syscall_s(inst); break;
757 case ID_INS_SYSENTER: this->sysenter_s(inst); break;
758 case ID_INS_TEST: this->test_s(inst); break;
759 case ID_INS_TZCNT: this->tzcnt_s(inst); break;
760 case ID_INS_UNPCKHPD: this->unpckhpd_s(inst); break;
761 case ID_INS_UNPCKHPS: this->unpckhps_s(inst); break;
762 case ID_INS_UNPCKLPD: this->unpcklpd_s(inst); break;
763 case ID_INS_UNPCKLPS: this->unpcklps_s(inst); break;
764 case ID_INS_VERR: this->verr_s(inst); break;
765 case ID_INS_VERW: this->verw_s(inst); break;
766 case ID_INS_VEXTRACTI128: this->vextracti128_s(inst); break;
767 case ID_INS_VMOVD: this->vmovd_s(inst); break;
768 case ID_INS_VMOVDQA: this->vmovdqa_s(inst); break;
769 case ID_INS_VMOVDQU: this->vmovdqu_s(inst); break;
770 case ID_INS_VMOVNTDQ: this->vmovntdq_s(inst); break;
771 case ID_INS_VMOVQ: this->vmovq_s(inst); break;
772 case ID_INS_VMOVSD: this->vmovsd_s(inst); break;
773 case ID_INS_VMOVAPS: this->vmovaps_s(inst); break;
774 case ID_INS_VMOVUPS: this->vmovups_s(inst); break;
775 case ID_INS_VPACKUSWB: this->vpackuswb_s(inst); break;
776 case ID_INS_VPACKSSDW: this->vpackssdw_s(inst); break;
777 case ID_INS_VPACKSSWB: this->vpacksswb_s(inst); break;
778 case ID_INS_VPADDB: this->vpaddb_s(inst); break;
779 case ID_INS_VPADDD: this->vpaddd_s(inst); break;
780 case ID_INS_VPADDW: this->vpaddw_s(inst); break;
781 case ID_INS_VPAND: this->vpand_s(inst); break;
782 case ID_INS_VPANDN: this->vpandn_s(inst); break;
783 case ID_INS_VPERM2I128: this->vperm2i128_s(inst); break;
784 case ID_INS_VPERMQ: this->vpermq_s(inst); break;
785 case ID_INS_VPEXTRB: this->vpextrb_s(inst); break;
786 case ID_INS_VPEXTRD: this->vpextrd_s(inst); break;
787 case ID_INS_VPEXTRQ: this->vpextrq_s(inst); break;
788 case ID_INS_VPEXTRW: this->vpextrw_s(inst); break;
789 case ID_INS_VPBROADCASTB: this->vpbroadcastb_s(inst); break;
790 case ID_INS_VPCMPEQB: this->vpcmpeqb_s(inst); break;
791 case ID_INS_VPCMPEQD: this->vpcmpeqd_s(inst); break;
792 case ID_INS_VPCMPEQQ: this->vpcmpeqq_s(inst); break;
793 case ID_INS_VPCMPEQW: this->vpcmpeqw_s(inst); break;
794 case ID_INS_VPCMPGTB: this->vpcmpgtb_s(inst); break;
795 case ID_INS_VPCMPGTD: this->vpcmpgtd_s(inst); break;
796 case ID_INS_VPCMPGTW: this->vpcmpgtw_s(inst); break;
797 case ID_INS_VPMADDWD: this->vpmaddwd_s(inst); break;
798 case ID_INS_VPMOVMSKB: this->vpmovmskb_s(inst); break;
799 case ID_INS_VPMINUB: this->vpminub_s(inst); break;
800 case ID_INS_VPMULHW: this->vpmulhw_s(inst); break;
801 case ID_INS_VPMULLW: this->vpmullw_s(inst); break;
802 case ID_INS_VPOR: this->vpor_s(inst); break;
803 case ID_INS_VPSHUFD: this->vpshufd_s(inst); break;
804 case ID_INS_VPSIGNW: this->vpsignw_s(inst); break;
805 case ID_INS_VPSLLDQ: this->vpslldq_s(inst); break;
806 case ID_INS_VPSLLW: this->vpsllw_s(inst); break;
807 case ID_INS_VPSRAD: this->vpsrad_s(inst); break;
808 case ID_INS_VPSRAW: this->vpsraw_s(inst); break;
809 case ID_INS_VPSRLDQ: this->vpsrldq_s(inst); break;
810 case ID_INS_VPSRLW: this->vpsrlw_s(inst); break;
811 case ID_INS_VPSUBB: this->vpsubb_s(inst); break;
812 case ID_INS_VPSUBD: this->vpsubd_s(inst); break;
813 case ID_INS_VPSUBQ: this->vpsubq_s(inst); break;
814 case ID_INS_VPSUBW: this->vpsubw_s(inst); break;
815 case ID_INS_VPTEST: this->vptest_s(inst); break;
816 case ID_INS_VPUNPCKHBW: this->vpunpckhbw_s(inst); break;
817 case ID_INS_VPUNPCKHDQ: this->vpunpckhdq_s(inst); break;
818 case ID_INS_VPUNPCKHQDQ: this->vpunpckhqdq_s(inst); break;
819 case ID_INS_VPUNPCKHWD: this->vpunpckhwd_s(inst); break;
820 case ID_INS_VPUNPCKLBW: this->vpunpcklbw_s(inst); break;
821 case ID_INS_VPUNPCKLDQ: this->vpunpckldq_s(inst); break;
822 case ID_INS_VPUNPCKLQDQ: this->vpunpcklqdq_s(inst); break;
823 case ID_INS_VPUNPCKLWD: this->vpunpcklwd_s(inst); break;
824 case ID_INS_VPXOR: this->vpxor_s(inst); break;
825 case ID_INS_VXORPS: this->vxorps_s(inst); break;
826 case ID_INS_WAIT: this->wait_s(inst); break;
827 case ID_INS_WBINVD: this->wbinvd_s(inst); break;
828 case ID_INS_XADD: this->xadd_s(inst); break;
829 case ID_INS_XCHG: this->xchg_s(inst); break;
830 case ID_INS_XOR: this->xor_s(inst); break;
831 case ID_INS_XORPD: this->xorpd_s(inst); break;
832 case ID_INS_XORPS: this->xorps_s(inst); break;
833 default:
834 this->exception = triton::arch::FAULT_UD;
835 break;
836 }
837 return this->exception;
838 }
839
840
841 triton::uint64 x86Semantics::alignAddStack_s(triton::arch::Instruction& inst, triton::uint32 delta) {
842 auto dst = triton::arch::OperandWrapper(this->architecture->getStackPointer());
843
844 /* Create symbolic operands */
845 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
846 auto op2 = this->astCtxt->bv(delta, dst.getBitSize());
847
848 /* Create the semantics */
849 auto node = this->astCtxt->bvadd(op1, op2);
850
851 /* Create symbolic expression */
852 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "Stack alignment");
853
854 /* Spread taint */
855 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
856
857 /* Return the new stack value */
858 return static_cast<triton::uint64>(node->evaluate());
859 }
860
861
862 triton::uint64 x86Semantics::alignSubStack_s(triton::arch::Instruction& inst, triton::uint32 delta) {
863 auto dst = triton::arch::OperandWrapper(this->architecture->getStackPointer());
864
865 /* Create symbolic operands */
866 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
867 auto op2 = this->astCtxt->bv(delta, dst.getBitSize());
868
869 /* Create the semantics */
870 auto node = this->astCtxt->bvsub(op1, op2);
871
872 /* Create symbolic expression */
873 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "Stack alignment");
874
875 /* Spread taint */
876 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
877
878 /* Return the new stack value */
879 return static_cast<triton::uint64>(node->evaluate());
880 }
881
882
883 void x86Semantics::clearFlag_s(triton::arch::Instruction& inst, const triton::arch::Register& flag, std::string comment) {
884 /* Create the semantics */
885 auto node = this->astCtxt->bv(0, 1);
886
887 /* Create symbolic expression */
888 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, flag, comment);
889
890 /* Spread taint */
891 expr->isTainted = this->taintEngine->setTaintRegister(flag, triton::engines::taint::UNTAINTED);
892 }
893
894
895 void x86Semantics::setFlag_s(triton::arch::Instruction& inst, const triton::arch::Register& flag, std::string comment) {
896 /* Create the semantics */
897 auto node = this->astCtxt->bv(1, 1);
898
899 /* Create symbolic expression */
900 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, flag, comment);
901
902 /* Spread taint */
903 expr->isTainted = this->taintEngine->setTaintRegister(flag, triton::engines::taint::UNTAINTED);
904 }
905
906
907 void x86Semantics::undefined_s(triton::arch::Instruction& inst, const triton::arch::Register& reg) {
908 if (this->modes->isModeEnabled(triton::modes::CONCRETIZE_UNDEFINED_REGISTERS)) {
909 this->symbolicEngine->concretizeRegister(reg);
910 }
911 /* Tell that the instruction defines a register as undefined and untaint */
912 inst.setUndefinedRegister(reg);
914 }
915
916
917 void x86Semantics::controlFlow_s(triton::arch::Instruction& inst) {
918 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
919 auto counter = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
920 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
921
922 switch (inst.getPrefix()) {
923
925 /* Create symbolic operands */
926 auto op1 = this->symbolicEngine->getOperandAst(inst, counter);
927
928 /* Create the semantics for Counter */
929 auto node1 = this->astCtxt->ite(
930 this->astCtxt->equal(op1, this->astCtxt->bv(0, counter.getBitSize())),
931 op1,
932 this->astCtxt->bvsub(op1, this->astCtxt->bv(1, counter.getBitSize()))
933 );
934
935 /* Create the semantics for PC */
936 auto node2 = this->astCtxt->ite(
937 this->astCtxt->equal(node1, this->astCtxt->bv(0, counter.getBitSize())),
938 this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize()),
939 this->astCtxt->bv(inst.getAddress(), pc.getBitSize())
940 );
941
942 /* Create symbolic expression */
943 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, counter, "Counter operation");
944 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, pc, "Program Counter");
945
946 /* Spread taint for PC */
947 expr1->isTainted = this->taintEngine->taintUnion(counter, counter);
948 expr2->isTainted = this->taintEngine->taintAssignment(pc, counter);
949 break;
950 }
951
953 /* Create symbolic operands */
954 auto op1 = this->symbolicEngine->getOperandAst(inst, counter);
955 auto op2 = this->symbolicEngine->getOperandAst(inst, zf);
956
957 /* Create the semantics for Counter */
958 auto node1 = this->astCtxt->ite(
959 this->astCtxt->equal(op1, this->astCtxt->bv(0, counter.getBitSize())),
960 op1,
961 this->astCtxt->bvsub(op1, this->astCtxt->bv(1, counter.getBitSize()))
962 );
963
964 /* Create the semantics for PC */
965 auto node2 = this->astCtxt->ite(
966 this->astCtxt->lor(
967 this->astCtxt->equal(node1, this->astCtxt->bv(0, counter.getBitSize())),
968 this->astCtxt->equal(op2, this->astCtxt->bvfalse())
969 ),
970 this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize()),
971 this->astCtxt->bv(inst.getAddress(), pc.getBitSize())
972 );
973
974 /* Create symbolic expression */
975 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, counter, "Counter operation");
976 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, pc, "Program Counter");
977
978 /* Spread taint */
979 expr1->isTainted = this->taintEngine->taintUnion(counter, counter);
980 expr2->isTainted = this->taintEngine->taintAssignment(pc, counter);
981 break;
982 }
983
985 /* Create symbolic operands */
986 auto op1 = this->symbolicEngine->getOperandAst(inst, counter);
987 auto op2 = this->symbolicEngine->getOperandAst(inst, zf);
988
989 /* Create the semantics for Counter */
990 auto node1 = this->astCtxt->ite(
991 this->astCtxt->equal(op1, this->astCtxt->bv(0, counter.getBitSize())),
992 op1,
993 this->astCtxt->bvsub(op1, this->astCtxt->bv(1, counter.getBitSize()))
994 );
995
996 /* Create the semantics for PC */
997 auto node2 = this->astCtxt->ite(
998 this->astCtxt->lor(
999 this->astCtxt->equal(node1, this->astCtxt->bv(0, counter.getBitSize())),
1000 this->astCtxt->equal(op2, this->astCtxt->bvtrue())
1001 ),
1002 this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize()),
1003 this->astCtxt->bv(inst.getAddress(), pc.getBitSize())
1004 );
1005
1006 /* Create symbolic expression */
1007 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, counter, "Counter operation");
1008 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, pc, "Program Counter");
1009
1010 /* Spread taint */
1011 expr1->isTainted = this->taintEngine->taintUnion(counter, counter);
1012 expr2->isTainted = this->taintEngine->taintAssignment(pc, counter);
1013 break;
1014 }
1015
1016 default: {
1017 /* Create the semantics */
1018 auto node = this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize());
1019
1020 /* Create symbolic expression */
1021 auto expr = this->symbolicEngine->createSymbolicRegisterExpression(inst, node, this->architecture->getProgramCounter(), "Program Counter");
1022
1023 /* Spread taint */
1024 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getProgramCounter(), triton::engines::taint::UNTAINTED);
1025 break;
1026 }
1027 }
1028 }
1029
1030
1032 void x86Semantics::updateFTW(triton::arch::Instruction& inst, const triton::engines::symbolic::SharedSymbolicExpression& parent) {
1033 /* Fetch the STX registers */
1034 auto st0 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST0));
1035 auto st1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST1));
1036 auto st2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST2));
1037 auto st3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST3));
1038 auto st4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST4));
1039 auto st5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST5));
1040 auto st6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST6));
1041 auto st7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST7));
1042
1043 /* Fetch the STX ASTs */
1044 auto st0_ast = this->symbolicEngine->getOperandAst(inst, st0);
1045 auto st1_ast = this->symbolicEngine->getOperandAst(inst, st1);
1046 auto st2_ast = this->symbolicEngine->getOperandAst(inst, st2);
1047 auto st3_ast = this->symbolicEngine->getOperandAst(inst, st3);
1048 auto st4_ast = this->symbolicEngine->getOperandAst(inst, st4);
1049 auto st5_ast = this->symbolicEngine->getOperandAst(inst, st5);
1050 auto st6_ast = this->symbolicEngine->getOperandAst(inst, st6);
1051 auto st7_ast = this->symbolicEngine->getOperandAst(inst, st7);
1052
1053 /* Extract the fraction from the STX registers */
1054 auto fraction_st0 = this->astCtxt->extract(62, 0, st0_ast);
1055 auto fraction_st1 = this->astCtxt->extract(62, 0, st1_ast);
1056 auto fraction_st2 = this->astCtxt->extract(62, 0, st2_ast);
1057 auto fraction_st3 = this->astCtxt->extract(62, 0, st3_ast);
1058 auto fraction_st4 = this->astCtxt->extract(62, 0, st4_ast);
1059 auto fraction_st5 = this->astCtxt->extract(62, 0, st5_ast);
1060 auto fraction_st6 = this->astCtxt->extract(62, 0, st6_ast);
1061 auto fraction_st7 = this->astCtxt->extract(62, 0, st7_ast);
1062
1063 /* Extract the integer bit from the STX registers */
1064 auto integer_st0 = this->astCtxt->extract(63, 63, st0_ast);
1065 auto integer_st1 = this->astCtxt->extract(63, 63, st1_ast);
1066 auto integer_st2 = this->astCtxt->extract(63, 63, st2_ast);
1067 auto integer_st3 = this->astCtxt->extract(63, 63, st3_ast);
1068 auto integer_st4 = this->astCtxt->extract(63, 63, st4_ast);
1069 auto integer_st5 = this->astCtxt->extract(63, 63, st5_ast);
1070 auto integer_st6 = this->astCtxt->extract(63, 63, st6_ast);
1071 auto integer_st7 = this->astCtxt->extract(63, 63, st7_ast);
1072
1073 /* Extract the exponent from the STX registers */
1074 auto exponent_st0 = this->astCtxt->extract(79, 64, st0_ast);
1075 auto exponent_st1 = this->astCtxt->extract(79, 64, st1_ast);
1076 auto exponent_st2 = this->astCtxt->extract(79, 64, st2_ast);
1077 auto exponent_st3 = this->astCtxt->extract(79, 64, st3_ast);
1078 auto exponent_st4 = this->astCtxt->extract(79, 64, st4_ast);
1079 auto exponent_st5 = this->astCtxt->extract(79, 64, st5_ast);
1080 auto exponent_st6 = this->astCtxt->extract(79, 64, st6_ast);
1081 auto exponent_st7 = this->astCtxt->extract(79, 64, st7_ast);
1082
1083 /* Exponent All Zeros */
1084 auto ea0_st0 = this->astCtxt->equal(exponent_st0, this->astCtxt->bv(0x0000, 16));
1085 auto ea0_st1 = this->astCtxt->equal(exponent_st1, this->astCtxt->bv(0x0000, 16));
1086 auto ea0_st2 = this->astCtxt->equal(exponent_st2, this->astCtxt->bv(0x0000, 16));
1087 auto ea0_st3 = this->astCtxt->equal(exponent_st3, this->astCtxt->bv(0x0000, 16));
1088 auto ea0_st4 = this->astCtxt->equal(exponent_st4, this->astCtxt->bv(0x0000, 16));
1089 auto ea0_st5 = this->astCtxt->equal(exponent_st5, this->astCtxt->bv(0x0000, 16));
1090 auto ea0_st6 = this->astCtxt->equal(exponent_st6, this->astCtxt->bv(0x0000, 16));
1091 auto ea0_st7 = this->astCtxt->equal(exponent_st7, this->astCtxt->bv(0x0000, 16));
1092
1093 /* Exponent All Ones */
1094 auto ea1_st0 = this->astCtxt->equal(exponent_st0, this->astCtxt->bv(0xFFFF, 16));
1095 auto ea1_st1 = this->astCtxt->equal(exponent_st1, this->astCtxt->bv(0xFFFF, 16));
1096 auto ea1_st2 = this->astCtxt->equal(exponent_st2, this->astCtxt->bv(0xFFFF, 16));
1097 auto ea1_st3 = this->astCtxt->equal(exponent_st3, this->astCtxt->bv(0xFFFF, 16));
1098 auto ea1_st4 = this->astCtxt->equal(exponent_st4, this->astCtxt->bv(0xFFFF, 16));
1099 auto ea1_st5 = this->astCtxt->equal(exponent_st5, this->astCtxt->bv(0xFFFF, 16));
1100 auto ea1_st6 = this->astCtxt->equal(exponent_st6, this->astCtxt->bv(0xFFFF, 16));
1101 auto ea1_st7 = this->astCtxt->equal(exponent_st7, this->astCtxt->bv(0xFFFF, 16));
1102
1103 /* Exponent Neither All Zeroes Or Ones */
1104 auto ena01_st0 = this->astCtxt->equal(this->astCtxt->lor(ea0_st0, ea1_st0), this->astCtxt->bvfalse());
1105 auto ena01_st1 = this->astCtxt->equal(this->astCtxt->lor(ea0_st1, ea1_st1), this->astCtxt->bvfalse());
1106 auto ena01_st2 = this->astCtxt->equal(this->astCtxt->lor(ea0_st2, ea1_st2), this->astCtxt->bvfalse());
1107 auto ena01_st3 = this->astCtxt->equal(this->astCtxt->lor(ea0_st3, ea1_st3), this->astCtxt->bvfalse());
1108 auto ena01_st4 = this->astCtxt->equal(this->astCtxt->lor(ea0_st4, ea1_st4), this->astCtxt->bvfalse());
1109 auto ena01_st5 = this->astCtxt->equal(this->astCtxt->lor(ea0_st5, ea1_st5), this->astCtxt->bvfalse());
1110 auto ena01_st6 = this->astCtxt->equal(this->astCtxt->lor(ea0_st6, ea1_st6), this->astCtxt->bvfalse());
1111 auto ena01_st7 = this->astCtxt->equal(this->astCtxt->lor(ea0_st7, ea1_st7), this->astCtxt->bvfalse());
1112
1113 /* Integer Bit 0 */
1114 auto ib0_st0 = this->astCtxt->equal(integer_st0, this->astCtxt->bv(0, 1));
1115 auto ib0_st1 = this->astCtxt->equal(integer_st1, this->astCtxt->bv(0, 1));
1116 auto ib0_st2 = this->astCtxt->equal(integer_st2, this->astCtxt->bv(0, 1));
1117 auto ib0_st3 = this->astCtxt->equal(integer_st3, this->astCtxt->bv(0, 1));
1118 auto ib0_st4 = this->astCtxt->equal(integer_st4, this->astCtxt->bv(0, 1));
1119 auto ib0_st5 = this->astCtxt->equal(integer_st5, this->astCtxt->bv(0, 1));
1120 auto ib0_st6 = this->astCtxt->equal(integer_st6, this->astCtxt->bv(0, 1));
1121 auto ib0_st7 = this->astCtxt->equal(integer_st7, this->astCtxt->bv(0, 1));
1122
1123 /* Fraction All Zeroes */
1124 auto fa0_st0 = this->astCtxt->equal(fraction_st0, this->astCtxt->bv(0, 63));
1125 auto fa0_st1 = this->astCtxt->equal(fraction_st1, this->astCtxt->bv(0, 63));
1126 auto fa0_st2 = this->astCtxt->equal(fraction_st2, this->astCtxt->bv(0, 63));
1127 auto fa0_st3 = this->astCtxt->equal(fraction_st3, this->astCtxt->bv(0, 63));
1128 auto fa0_st4 = this->astCtxt->equal(fraction_st4, this->astCtxt->bv(0, 63));
1129 auto fa0_st5 = this->astCtxt->equal(fraction_st5, this->astCtxt->bv(0, 63));
1130 auto fa0_st6 = this->astCtxt->equal(fraction_st6, this->astCtxt->bv(0, 63));
1131 auto fa0_st7 = this->astCtxt->equal(fraction_st7, this->astCtxt->bv(0, 63));
1132
1133 /* Determine the x87 FPU Tag Word (Diagram at page 379 of the AMD Architecture Programmer's Manual, Volume 2: System Programming) */
1134 auto db_1_0 = this->astCtxt->ite(ea0_st0,
1135 this->astCtxt->ite(ib0_st0,
1136 this->astCtxt->ite(fa0_st0,
1137 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
1138 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
1139 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
1140 this->astCtxt->ite(ena01_st0,
1141 this->astCtxt->ite(ib0_st0,
1142 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
1143 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
1144 this->astCtxt->bv(2, 2))); // 'Exponent All 1'
1145
1146 auto db_3_2 = this->astCtxt->ite(ea0_st1,
1147 this->astCtxt->ite(ib0_st1,
1148 this->astCtxt->ite(fa0_st1,
1149 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
1150 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
1151 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
1152 this->astCtxt->ite(ena01_st1,
1153 this->astCtxt->ite(ib0_st1,
1154 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
1155 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
1156 this->astCtxt->bv(2, 2))); // 'Exponent All 1'
1157
1158 auto db_5_4 = this->astCtxt->ite(ea0_st2,
1159 this->astCtxt->ite(ib0_st2,
1160 this->astCtxt->ite(fa0_st2,
1161 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
1162 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
1163 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
1164 this->astCtxt->ite(ena01_st2,
1165 this->astCtxt->ite(ib0_st2,
1166 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
1167 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
1168 this->astCtxt->bv(2, 2))); // 'Exponent All 1'
1169
1170 auto db_7_6 = this->astCtxt->ite(ea0_st3,
1171 this->astCtxt->ite(ib0_st3,
1172 this->astCtxt->ite(fa0_st3,
1173 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
1174 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
1175 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
1176 this->astCtxt->ite(ena01_st3,
1177 this->astCtxt->ite(ib0_st3,
1178 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
1179 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
1180 this->astCtxt->bv(2, 2))); // 'Exponent All 1'
1181
1182 auto db_9_8 = this->astCtxt->ite(ea0_st4,
1183 this->astCtxt->ite(ib0_st4,
1184 this->astCtxt->ite(fa0_st4,
1185 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
1186 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
1187 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
1188 this->astCtxt->ite(ena01_st4,
1189 this->astCtxt->ite(ib0_st4,
1190 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
1191 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
1192 this->astCtxt->bv(2, 2))); // 'Exponent All 1'
1193
1194 auto db_11_10 = this->astCtxt->ite(ea0_st5,
1195 this->astCtxt->ite(ib0_st5,
1196 this->astCtxt->ite(fa0_st5,
1197 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
1198 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
1199 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
1200 this->astCtxt->ite(ena01_st5,
1201 this->astCtxt->ite(ib0_st5,
1202 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
1203 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
1204 this->astCtxt->bv(2, 2))); // 'Exponent All 1'
1205
1206 auto db_13_12 = this->astCtxt->ite(ea0_st6,
1207 this->astCtxt->ite(ib0_st6,
1208 this->astCtxt->ite(fa0_st6,
1209 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
1210 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
1211 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
1212 this->astCtxt->ite(ena01_st6,
1213 this->astCtxt->ite(ib0_st6,
1214 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
1215 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
1216 this->astCtxt->bv(2, 2))); // 'Exponent All 1'
1217
1218 auto db_15_14 = this->astCtxt->ite(ea0_st7,
1219 this->astCtxt->ite(ib0_st7,
1220 this->astCtxt->ite(fa0_st7,
1221 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
1222 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
1223 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
1224 this->astCtxt->ite(ena01_st7,
1225 this->astCtxt->ite(ib0_st7,
1226 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
1227 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
1228 this->astCtxt->bv(2, 2))); // 'Exponent All 1'
1229
1230 /* Restore the x87 FPU Tag Word */
1231 auto node = this->astCtxt->concat(db_15_14,
1232 this->astCtxt->concat(db_13_12,
1233 this->astCtxt->concat(db_11_10,
1234 this->astCtxt->concat(db_9_8,
1235 this->astCtxt->concat(db_7_6,
1236 this->astCtxt->concat(db_5_4,
1237 this->astCtxt->concat(db_3_2, db_1_0)))))));
1238
1239 /* Create the symbolic expression */
1240 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_FTW), "x87 FPU Tag Word");
1241
1242 /* Spread the taint from the parent to the child */
1243 auto st0_taint = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_ST0));
1244 auto st1_taint = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_ST1));
1245 auto st2_taint = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_ST2));
1246 auto st3_taint = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_ST3));
1247 auto st4_taint = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_ST4));
1248 auto st5_taint = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_ST5));
1249 auto st6_taint = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_ST6));
1250 auto st7_taint = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_ST7));
1251
1252 auto is_ftw_tainted = st0_taint | st1_taint | st2_taint | st3_taint |
1253 st4_taint | st5_taint | st6_taint | st7_taint;
1254
1255 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_FTW), is_ftw_tainted);
1256 }
1257
1258
1259 void x86Semantics::af_s(triton::arch::Instruction& inst,
1264 bool vol) {
1265
1266 auto bvSize = dst.getBitSize();
1267 auto low = vol ? 0 : dst.getLow();
1268 auto high = vol ? bvSize-1 : dst.getHigh();
1269
1270 /*
1271 * Create the semantic.
1272 * af = 0x10 == (0x10 & (regDst ^ op1 ^ op2))
1273 */
1274 auto node = this->astCtxt->ite(
1275 this->astCtxt->equal(
1276 this->astCtxt->bv(0x10, bvSize),
1277 this->astCtxt->bvand(
1278 this->astCtxt->bv(0x10, bvSize),
1279 this->astCtxt->bvxor(
1280 this->astCtxt->extract(high, low, this->astCtxt->reference(parent)),
1281 this->astCtxt->bvxor(op1, op2)
1282 )
1283 )
1284 ),
1285 this->astCtxt->bv(1, 1),
1286 this->astCtxt->bv(0, 1)
1287 );
1288
1289 /* Create the symbolic expression */
1290 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_AF), "Adjust flag");
1291
1292 /* Spread the taint from the parent to the child */
1293 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_AF), parent->isTainted);
1294 }
1295
1296
1297 void x86Semantics::afAaa_s(triton::arch::Instruction& inst,
1302 bool vol) {
1303
1304 auto bvSize = dst.getBitSize();
1305
1306 /*
1307 * Create the semantic.
1308 * af = 1 if ((AL AND 0FH) > 9) or (AF = 1) then 0
1309 */
1310 auto node = this->astCtxt->ite(
1311 this->astCtxt->lor(
1312 this->astCtxt->bvugt(
1313 this->astCtxt->bvand(op1, this->astCtxt->bv(0xf, bvSize)),
1314 this->astCtxt->bv(9, bvSize)
1315 ),
1316 this->astCtxt->equal(op3, this->astCtxt->bvtrue())
1317 ),
1318 this->astCtxt->bv(1, 1),
1319 this->astCtxt->bv(0, 1)
1320 );
1321
1322 /* Create the symbolic expression */
1323 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_AF), "Adjust flag");
1324
1325 /* Spread the taint from the parent to the child */
1326 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_AF), parent->isTainted);
1327 }
1328
1329
1330 void x86Semantics::afNeg_s(triton::arch::Instruction& inst,
1334 bool vol) {
1335
1336 auto bvSize = dst.getBitSize();
1337 auto low = vol ? 0 : dst.getLow();
1338 auto high = vol ? bvSize-1 : dst.getHigh();
1339
1340 /*
1341 * Create the semantic.
1342 * af = 0x10 == (0x10 & (op1 ^ regDst))
1343 */
1344 auto node = this->astCtxt->ite(
1345 this->astCtxt->equal(
1346 this->astCtxt->bv(0x10, bvSize),
1347 this->astCtxt->bvand(
1348 this->astCtxt->bv(0x10, bvSize),
1349 this->astCtxt->bvxor(
1350 op1,
1351 this->astCtxt->extract(high, low, this->astCtxt->reference(parent))
1352 )
1353 )
1354 ),
1355 this->astCtxt->bv(1, 1),
1356 this->astCtxt->bv(0, 1)
1357 );
1358
1359 /* Create the symbolic expression */
1360 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_AF), "Adjust flag");
1361
1362 /* Spread the taint from the parent to the child */
1363 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_AF), parent->isTainted);
1364 }
1365
1366
1367 void x86Semantics::cfAaa_s(triton::arch::Instruction& inst,
1372 bool vol) {
1373
1374 auto bvSize = dst.getBitSize();
1375
1376 /*
1377 * Create the semantic.
1378 * cf = 1 if ((AL AND 0FH) > 9) or (AF = 1) then 0
1379 */
1380 auto node = this->astCtxt->ite(
1381 this->astCtxt->lor(
1382 this->astCtxt->bvugt(
1383 this->astCtxt->bvand(op1, this->astCtxt->bv(0xf, bvSize)),
1384 this->astCtxt->bv(9, bvSize)
1385 ),
1386 this->astCtxt->equal(op3, this->astCtxt->bvtrue())
1387 ),
1388 this->astCtxt->bv(1, 1),
1389 this->astCtxt->bv(0, 1)
1390 );
1391
1392 /* Create the symbolic expression */
1393 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1394
1395 /* Spread the taint from the parent to the child */
1396 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1397 }
1398
1399
1400 void x86Semantics::cfAdd_s(triton::arch::Instruction& inst,
1405 bool vol) {
1406
1407 auto bvSize = dst.getBitSize();
1408 auto low = vol ? 0 : dst.getLow();
1409 auto high = vol ? bvSize-1 : dst.getHigh();
1410
1411 /*
1412 * Create the semantic.
1413 * cf = MSB((op1 & op2) ^ ((op1 ^ op2 ^ parent) & (op1 ^ op2)));
1414 */
1415 auto node = this->astCtxt->extract(bvSize-1, bvSize-1,
1416 this->astCtxt->bvxor(
1417 this->astCtxt->bvand(op1, op2),
1418 this->astCtxt->bvand(
1419 this->astCtxt->bvxor(
1420 this->astCtxt->bvxor(op1, op2),
1421 this->astCtxt->extract(high, low, this->astCtxt->reference(parent))
1422 ),
1423 this->astCtxt->bvxor(op1, op2))
1424 )
1425 );
1426
1427 /* Create the symbolic expression */
1428 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1429
1430 /* Spread the taint from the parent to the child */
1431 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1432 }
1433
1434
1435 void x86Semantics::cfBlsi_s(triton::arch::Instruction& inst,
1439 bool vol) {
1440
1441 /*
1442 * Create the semantic.
1443 * cf = 0 if op1 == 0 else 1
1444 */
1445 auto node = this->astCtxt->ite(
1446 this->astCtxt->equal(
1447 op1,
1448 this->astCtxt->bv(0, dst.getBitSize())
1449 ),
1450 this->astCtxt->bv(0, 1),
1451 this->astCtxt->bv(1, 1)
1452 );
1453
1454 /* Create the symbolic expression */
1455 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1456
1457 /* Spread the taint from the parent to the child */
1458 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1459 }
1460
1461
1462 void x86Semantics::cfBlsmsk_s(triton::arch::Instruction& inst,
1466 bool vol) {
1467
1468 /*
1469 * Create the semantic.
1470 * cf = 1 if op1 == 0 else 0
1471 */
1472 auto node = this->astCtxt->ite(
1473 this->astCtxt->equal(
1474 op1,
1475 this->astCtxt->bv(0, dst.getBitSize())
1476 ),
1477 this->astCtxt->bv(1, 1),
1478 this->astCtxt->bv(0, 1)
1479 );
1480
1481 /* Create the symbolic expression */
1482 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1483
1484 /* Spread the taint from the parent to the child */
1485 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1486 }
1487
1488
1489 void x86Semantics::cfBlsr_s(triton::arch::Instruction& inst,
1493 bool vol) {
1494
1495 /*
1496 * Create the semantic.
1497 * cf = 1 if op1 == 0 else 0
1498 */
1499 auto node = this->astCtxt->ite(
1500 this->astCtxt->equal(
1501 op1,
1502 this->astCtxt->bv(0, dst.getBitSize())
1503 ),
1504 this->astCtxt->bv(1, 1),
1505 this->astCtxt->bv(0, 1)
1506 );
1507
1508 /* Create the symbolic expression */
1509 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1510
1511 /* Spread the taint from the parent to the child */
1512 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1513 }
1514
1515
1516 void x86Semantics::cfImul_s(triton::arch::Instruction& inst,
1521 bool vol) {
1522
1523 /*
1524 * Create the semantic.
1525 * cf = 0 if sx(dst) == node else 1
1526 */
1527 auto node = this->astCtxt->ite(
1528 this->astCtxt->equal(
1529 this->astCtxt->sx(dst.getBitSize(), op1),
1530 res
1531 ),
1532 this->astCtxt->bv(0, 1),
1533 this->astCtxt->bv(1, 1)
1534 );
1535
1536 /* Create the symbolic expression */
1537 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1538
1539 /* Spread the taint from the parent to the child */
1540 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1541 }
1542
1543
1544 void x86Semantics::cfLzcnt_s(triton::arch::Instruction& inst,
1548 bool vol) {
1549
1550 auto bvSize = src.getBitSize();
1551 auto low = vol ? 0 : src.getLow();
1552 auto high = vol ? bvSize-1 : src.getHigh();
1553
1554 /*
1555 * Create the semantic.
1556 * cf = 0 == parent
1557 */
1558 auto node = this->astCtxt->ite(
1559 this->astCtxt->equal(
1560 this->astCtxt->extract(high, low, op1),
1561 this->astCtxt->bv(0, bvSize)
1562 ),
1563 this->astCtxt->bv(1, 1),
1564 this->astCtxt->bv(0, 1)
1565 );
1566
1567 /* Create the symbolic expression */
1568 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1569
1570 /* Spread the taint from the parent to the child */
1571 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1572 }
1573
1574
1575 void x86Semantics::cfMul_s(triton::arch::Instruction& inst,
1579 bool vol) {
1580
1581 /*
1582 * Create the semantic.
1583 * cf = 0 if op1 == 0 else 1
1584 */
1585 auto node = this->astCtxt->ite(
1586 this->astCtxt->equal(
1587 op1,
1588 this->astCtxt->bv(0, dst.getBitSize())
1589 ),
1590 this->astCtxt->bv(0, 1),
1591 this->astCtxt->bv(1, 1)
1592 );
1593
1594 /* Create the symbolic expression */
1595 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1596
1597 /* Spread the taint from the parent to the child */
1598 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1599 }
1600
1601
1602 void x86Semantics::cfNeg_s(triton::arch::Instruction& inst,
1606 bool vol) {
1607
1608 /*
1609 * Create the semantic.
1610 * cf = 0 if op1 == 0 else 1
1611 */
1612 auto node = this->astCtxt->ite(
1613 this->astCtxt->equal(
1614 op1,
1615 this->astCtxt->bv(0, dst.getBitSize())
1616 ),
1617 this->astCtxt->bv(0, 1),
1618 this->astCtxt->bv(1, 1)
1619 );
1620
1621 /* Create the symbolic expression */
1622 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1623
1624 /* Spread the taint from the parent to the child */
1625 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1626 }
1627
1628
1629 void x86Semantics::cfPtest_s(triton::arch::Instruction& inst,
1632 bool vol) {
1633
1634 auto bvSize = dst.getBitSize();
1635 auto low = vol ? 0 : dst.getLow();
1636 auto high = vol ? bvSize-1 : dst.getHigh();
1637
1638 /*
1639 * Create the semantic.
1640 * cf = 0 == regDst
1641 */
1642 auto node = this->astCtxt->ite(
1643 this->astCtxt->equal(
1644 this->astCtxt->extract(high, low, this->astCtxt->reference(parent)),
1645 this->astCtxt->bv(0, bvSize)
1646 ),
1647 this->astCtxt->bv(1, 1),
1648 this->astCtxt->bv(0, 1)
1649 );
1650
1651 /* Create the symbolic expression */
1652 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1653
1654 /* Spread the taint from the parent to the child */
1655 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1656 }
1657
1658
1659 void x86Semantics::cfRcl_s(triton::arch::Instruction& inst,
1661 const triton::ast::SharedAbstractNode& result,
1663 bool vol) {
1664
1665 auto bvSize = op2->getBitvectorSize();
1666 auto high = result->getBitvectorSize() - 1;
1667 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
1668
1669 auto node = this->astCtxt->ite(
1670 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)),
1671 this->symbolicEngine->getOperandAst(cf),
1672 this->astCtxt->extract(high, high, result)
1673 );
1674
1675 /* Create the symbolic expression */
1676 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag");
1677
1678 if (op2->evaluate()) {
1679 /* Spread the taint from the parent to the child */
1680 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted);
1681 }
1682 else {
1683 inst.removeWrittenRegister(cf.getConstRegister());
1684 }
1685 }
1686
1687
1688 void x86Semantics::cfRcr_s(triton::arch::Instruction& inst,
1691 const triton::ast::SharedAbstractNode& result,
1693 bool vol) {
1694
1695 auto bvSize = op2->getBitvectorSize();
1696 auto high = result->getBitvectorSize() - 1;
1697 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
1698
1699 auto node = this->astCtxt->ite(
1700 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)),
1701 this->symbolicEngine->getOperandAst(cf),
1702 this->astCtxt->extract(high, high, result) /* yes it's should be LSB, but here it's a trick :-) */
1703 );
1704
1705 /* Create the symbolic expression */
1706 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag");
1707
1708 if (op2->evaluate()) {
1709 /* Spread the taint from the parent to the child */
1710 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted);
1711 }
1712 else {
1713 inst.removeWrittenRegister(cf.getConstRegister());
1714 }
1715 }
1716
1717
1718 void x86Semantics::cfRol_s(triton::arch::Instruction& inst,
1722 bool vol) {
1723
1724 auto bvSize = op2->getBitvectorSize();
1725 auto low = vol ? 0 : dst.getLow();
1726 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
1727
1728 auto node = this->astCtxt->ite(
1729 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)),
1730 this->symbolicEngine->getOperandAst(cf),
1731 this->astCtxt->extract(low, low, this->astCtxt->reference(parent))
1732 );
1733
1734 /* Create the symbolic expression */
1735 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag");
1736
1737 if (op2->evaluate()) {
1738 /* Spread the taint from the parent to the child */
1739 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted);
1740 }
1741 else {
1742 inst.removeWrittenRegister(cf.getConstRegister());
1743 }
1744 }
1745
1746
1747 void x86Semantics::cfRor_s(triton::arch::Instruction& inst,
1751 bool vol) {
1752
1753 auto bvSize = op2->getBitvectorSize();
1754 auto high = vol ? bvSize-1 : dst.getHigh();
1755 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
1756
1757 auto node = this->astCtxt->ite(
1758 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)),
1759 this->symbolicEngine->getOperandAst(cf),
1760 this->astCtxt->extract(high, high, this->astCtxt->reference(parent))
1761 );
1762
1763 /* Create the symbolic expression */
1764 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag");
1765
1766 if (op2->evaluate()) {
1767 /* Spread the taint from the parent to the child */
1768 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted);
1769 }
1770 else {
1771 inst.removeWrittenRegister(cf.getConstRegister());
1772 }
1773 }
1774
1775
1776 void x86Semantics::cfSar_s(triton::arch::Instruction& inst,
1781 bool vol) {
1782
1783 auto bvSize = dst.getBitSize();
1784 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
1785
1786 /*
1787 * Create the semantic.
1788 * if op2 != 0:
1789 * if op2 > bvSize:
1790 * cf.id = ((op1 >> (bvSize - 1)) & 1)
1791 * else:
1792 * cf.id = ((op1 >> (op2 - 1)) & 1)
1793 */
1794 auto node = this->astCtxt->ite(
1795 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)),
1796 this->symbolicEngine->getOperandAst(cf),
1797 this->astCtxt->ite(
1798 this->astCtxt->bvugt(op2, this->astCtxt->bv(bvSize, bvSize)),
1799 this->astCtxt->extract(0, 0, this->astCtxt->bvlshr(op1, this->astCtxt->bvsub(this->astCtxt->bv(bvSize, bvSize), this->astCtxt->bv(1, bvSize)))),
1800 this->astCtxt->extract(0, 0, this->astCtxt->bvlshr(op1, this->astCtxt->bvsub(op2, this->astCtxt->bv(1, bvSize))))
1801 )
1802 );
1803
1804 /* Create the symbolic expression */
1805 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag");
1806
1807 if (op2->evaluate()) {
1808 /* Spread the taint from the parent to the child */
1809 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted);
1810 }
1811 else {
1812 inst.removeWrittenRegister(cf.getConstRegister());
1813 }
1814 }
1815
1816
1817 void x86Semantics::cfShl_s(triton::arch::Instruction& inst,
1822 bool vol) {
1823
1824 auto bvSize = dst.getBitSize();
1825 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
1826
1827 /*
1828 * Create the semantic.
1829 * cf = (op1 >> ((bvSize - op2) & 1) if op2 != 0
1830 */
1831 auto node = this->astCtxt->ite(
1832 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)),
1833 this->symbolicEngine->getOperandAst(cf),
1834 this->astCtxt->extract(0, 0,
1835 this->astCtxt->bvlshr(
1836 op1,
1837 this->astCtxt->bvsub(
1838 this->astCtxt->bv(bvSize, bvSize),
1839 op2
1840 )
1841 )
1842 )
1843 );
1844
1845 /* Create the symbolic expression */
1846 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag");
1847
1848 if (op2->evaluate()) {
1849 /* Spread the taint from the parent to the child */
1850 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted);
1851 }
1852 else {
1853 inst.removeWrittenRegister(cf.getConstRegister());
1854 }
1855 }
1856
1857
1858 void x86Semantics::cfShld_s(triton::arch::Instruction& inst,
1864 bool vol) {
1865
1866 auto bv1Size = op1->getBitvectorSize();
1867 auto bv2Size = op2->getBitvectorSize();
1868 auto bv3Size = op3->getBitvectorSize();
1869 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
1870
1871 /*
1872 * Create the semantic.
1873 * cf = MSB(rol(op3, concat(op2,op1))) if op3 != 0
1874 */
1875 auto node = this->astCtxt->ite(
1876 this->astCtxt->equal(op3, this->astCtxt->bv(0, bv3Size)),
1877 this->symbolicEngine->getOperandAst(cf),
1878 this->astCtxt->extract(
1879 dst.getBitSize(), dst.getBitSize(),
1880 this->astCtxt->bvrol(
1881 this->astCtxt->concat(op2, op1),
1882 this->astCtxt->zx(((bv1Size + bv2Size) - bv3Size), op3)
1883 )
1884 )
1885 );
1886
1887 /* Create the symbolic expression */
1888 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag");
1889
1890 if (op3->evaluate()) {
1891 /* Spread the taint from the parent to the child */
1892 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted);
1893 }
1894 else {
1895 inst.removeWrittenRegister(cf.getConstRegister());
1896 }
1897 }
1898
1899
1900 void x86Semantics::cfShr_s(triton::arch::Instruction& inst,
1905 bool vol) {
1906
1907 auto bvSize = dst.getBitSize();
1908 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
1909
1910 /*
1911 * Create the semantic.
1912 * cf = ((op1 >> (op2 - 1)) & 1) if op2 != 0
1913 */
1914 auto node = this->astCtxt->ite(
1915 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)),
1916 this->symbolicEngine->getOperandAst(cf),
1917 this->astCtxt->extract(0, 0,
1918 this->astCtxt->bvlshr(
1919 op1,
1920 this->astCtxt->bvsub(
1921 op2,
1922 this->astCtxt->bv(1, bvSize))
1923 )
1924 )
1925 );
1926
1927 /* Create the symbolic expression */
1928 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag");
1929
1930 if (op2->evaluate()) {
1931 /* Spread the taint from the parent to the child */
1932 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted);
1933 }
1934 else {
1935 inst.removeWrittenRegister(cf.getConstRegister());
1936 }
1937 }
1938
1939
1940 void x86Semantics::cfShrd_s(triton::arch::Instruction& inst,
1946 bool vol) {
1947
1948 auto bvSize = dst.getBitSize();
1949 auto bv1Size = op1->getBitvectorSize();
1950 auto bv2Size = op2->getBitvectorSize();
1951 auto bv3Size = op3->getBitvectorSize();
1952 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
1953
1954 /*
1955 * Create the semantic.
1956 * cf = MSB(ror(op3, concat(op2,op1))) if op3 != 0
1957 */
1958 auto node = this->astCtxt->ite(
1959 this->astCtxt->equal(op3, this->astCtxt->bv(0, bv3Size)),
1960 this->symbolicEngine->getOperandAst(cf),
1961 this->astCtxt->extract(
1962 (bvSize * 2) - 1, (bvSize * 2) - 1,
1963 this->astCtxt->bvror(
1964 this->astCtxt->concat(op2, op1),
1965 this->astCtxt->zx(((bv1Size + bv2Size) - bv3Size), op3)
1966 )
1967 )
1968 );
1969
1970 /* Create the symbolic expression */
1971 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag");
1972
1973 if (op3->evaluate()) {
1974 /* Spread the taint from the parent to the child */
1975 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted);
1976 }
1977 else {
1978 inst.removeWrittenRegister(cf.getConstRegister());
1979 }
1980 }
1981
1982
1983 void x86Semantics::cfSub_s(triton::arch::Instruction& inst,
1988 bool vol) {
1989
1990 auto bvSize = dst.getBitSize();
1991 auto low = vol ? 0 : dst.getLow();
1992 auto high = vol ? bvSize-1 : dst.getHigh();
1993
1994 /*
1995 * Create the semantic.
1996 * cf = extract(bvSize, bvSize (((op1 ^ op2 ^ res) ^ ((op1 ^ res) & (op1 ^ op2)))))
1997 */
1998 auto node = this->astCtxt->extract(bvSize-1, bvSize-1,
1999 this->astCtxt->bvxor(
2000 this->astCtxt->bvxor(op1, this->astCtxt->bvxor(op2, this->astCtxt->extract(high, low, this->astCtxt->reference(parent)))),
2001 this->astCtxt->bvand(
2002 this->astCtxt->bvxor(op1, this->astCtxt->extract(high, low, this->astCtxt->reference(parent))),
2003 this->astCtxt->bvxor(op1, op2)
2004 )
2005 )
2006 );
2007
2008 /* Create the symbolic expression */
2009 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
2010
2011 /* Spread the taint from the parent to the child */
2012 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
2013 }
2014
2015
2016 void x86Semantics::cfTzcnt_s(triton::arch::Instruction& inst,
2020 bool vol) {
2021
2022 auto bvSize = src.getBitSize();
2023 auto low = vol ? 0 : src.getLow();
2024 auto high = vol ? bvSize-1 : src.getHigh();
2025
2026 /*
2027 * Create the semantic.
2028 * cf = 0 == parent
2029 */
2030 auto node = this->astCtxt->ite(
2031 this->astCtxt->equal(
2032 this->astCtxt->extract(high, low, op1),
2033 this->astCtxt->bv(0, bvSize)
2034 ),
2035 this->astCtxt->bv(1, 1),
2036 this->astCtxt->bv(0, 1)
2037 );
2038
2039 /* Create the symbolic expression */
2040 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
2041
2042 /* Spread the taint from the parent to the child */
2043 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
2044 }
2045
2046
2047 void x86Semantics::ofAdd_s(triton::arch::Instruction& inst,
2052 bool vol) {
2053
2054 auto bvSize = dst.getBitSize();
2055 auto low = vol ? 0 : dst.getLow();
2056 auto high = vol ? bvSize-1 : dst.getHigh();
2057
2058 /*
2059 * Create the semantic.
2060 * of = MSB((op1 ^ ~op2) & (op1 ^ regDst))
2061 */
2062 auto node = this->astCtxt->extract(bvSize-1, bvSize-1,
2063 this->astCtxt->bvand(
2064 this->astCtxt->bvxor(op1, this->astCtxt->bvnot(op2)),
2065 this->astCtxt->bvxor(op1, this->astCtxt->extract(high, low, this->astCtxt->reference(parent)))
2066 )
2067 );
2068
2069 /* Create the symbolic expression */
2070 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_OF), "Overflow flag");
2071
2072 /* Spread the taint from the parent to the child */
2073 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_OF), parent->isTainted);
2074 }
2075
2076
2077 void x86Semantics::ofImul_s(triton::arch::Instruction& inst,
2082 bool vol) {
2083 /*
2084 * Create the semantic.
2085 * of = 0 if sx(dst) == node else 1
2086 */
2087 auto node = this->astCtxt->ite(
2088 this->astCtxt->equal(
2089 this->astCtxt->sx(dst.getBitSize(), op1),
2090 res
2091 ),
2092 this->astCtxt->bv(0, 1),
2093 this->astCtxt->bv(1, 1)
2094 );
2095
2096 /* Create the symbolic expression */
2097 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_OF), "Overflow flag");
2098
2099 /* Spread the taint from the parent to the child */
2100 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_OF), parent->isTainted);
2101 }
2102
2103
2104 void x86Semantics::ofMul_s(triton::arch::Instruction& inst,
2108 bool vol) {
2109
2110 /*
2111 * Create the semantic.
2112 * of = 0 if up == 0 else 1
2113 */
2114 auto node = this->astCtxt->ite(
2115 this->astCtxt->equal(
2116 op1,
2117 this->astCtxt->bv(0, dst.getBitSize())
2118 ),
2119 this->astCtxt->bv(0, 1),
2120 this->astCtxt->bv(1, 1)
2121 );
2122
2123 /* Create the symbolic expression */
2124 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_OF), "Overflow flag");
2125
2126 /* Spread the taint from the parent to the child */
2127 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_OF), parent->isTainted);
2128 }
2129
2130
2131 void x86Semantics::ofNeg_s(triton::arch::Instruction& inst,
2135 bool vol) {
2136
2137 auto bvSize = dst.getBitSize();
2138 auto low = vol ? 0 : dst.getLow();
2139 auto high = vol ? bvSize-1 : dst.getHigh();
2140
2141 /*
2142 * Create the semantic.
2143 * of = (res & op1) >> (bvSize - 1) & 1
2144 */
2145 auto node = this->astCtxt->extract(0, 0,
2146 this->astCtxt->bvlshr(
2147 this->astCtxt->bvand(this->astCtxt->extract(high, low, this->astCtxt->reference(parent)), op1),
2148 this->astCtxt->bvsub(this->astCtxt->bv(bvSize, bvSize), this->astCtxt->bv(1, bvSize))
2149 )
2150 );
2151
2152 /* Create the symbolic expression */
2153 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_OF), "Overflow flag");
2154
2155 /* Spread the taint from the parent to the child */
2156 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_OF), parent->isTainted);
2157 }
2158
2159
2160 void x86Semantics::ofRol_s(triton::arch::Instruction& inst,
2164 bool vol) {
2165
2166 auto bvSize = dst.getBitSize();
2167 auto high = vol ? bvSize-1 : dst.getHigh();
2168 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
2169 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
2170
2171 auto node = this->astCtxt->ite(
2172 this->astCtxt->equal(this->astCtxt->zx(bvSize - op2->getBitvectorSize(), op2), this->astCtxt->bv(1, bvSize)),
2173 this->astCtxt->bvxor(
2174 this->astCtxt->extract(high, high, this->astCtxt->reference(parent)),
2175 this->symbolicEngine->getOperandAst(inst, cf)
2176 ),
2177 this->symbolicEngine->getOperandAst(of)
2178 );
2179
2180 /* Create the symbolic expression */
2181 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag");
2182
2183 if (op2->evaluate()) {
2184 /* Spread the taint from the parent to the child */
2185 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted);
2186 }
2187 else {
2188 inst.removeReadRegister(cf.getConstRegister());
2189 inst.removeWrittenRegister(of.getConstRegister());
2190 }
2191 }
2192
2193
2194 void x86Semantics::ofRor_s(triton::arch::Instruction& inst,
2198 bool vol) {
2199
2200 auto bvSize = op2->getBitvectorSize();
2201 auto high = vol ? bvSize-1 : dst.getHigh();
2202 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
2203
2204 auto node = this->astCtxt->ite(
2205 this->astCtxt->equal(op2, this->astCtxt->bv(1, bvSize)),
2206 this->astCtxt->bvxor(
2207 this->astCtxt->extract(high, high, this->astCtxt->reference(parent)),
2208 this->astCtxt->extract(high-1, high-1, this->astCtxt->reference(parent))
2209 ),
2210 this->symbolicEngine->getOperandAst(of)
2211 );
2212
2213 /* Create the symbolic expression */
2214 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag");
2215
2216 if (op2->evaluate()) {
2217 /* Spread the taint from the parent to the child */
2218 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted);
2219 }
2220 else {
2221 inst.removeWrittenRegister(of.getConstRegister());
2222 }
2223 }
2224
2225
2226 void x86Semantics::ofRcr_s(triton::arch::Instruction& inst,
2231 bool vol) {
2232
2233 auto bvSize = op2->getBitvectorSize();
2234 auto high = dst.getBitSize()-1;
2235 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
2236 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
2237
2238 auto node = this->astCtxt->ite(
2239 this->astCtxt->equal(op2, this->astCtxt->bv(1, bvSize)),
2240 this->astCtxt->bvxor(
2241 this->astCtxt->extract(high, high, op1),
2242 this->symbolicEngine->getOperandAst(inst, cf)
2243 ),
2244 this->symbolicEngine->getOperandAst(of)
2245 );
2246
2247 /* Create the symbolic expression */
2248 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag");
2249
2250 if (op2->evaluate()) {
2251 /* Spread the taint from the parent to the child */
2252 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted);
2253 }
2254 else {
2255 inst.removeReadRegister(cf.getConstRegister());
2256 inst.removeWrittenRegister(of.getConstRegister());
2257 }
2258 }
2259
2260
2261 void x86Semantics::ofSar_s(triton::arch::Instruction& inst,
2265 bool vol) {
2266
2267 auto bvSize = dst.getBitSize();
2268 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
2269
2270 /*
2271 * Create the semantic.
2272 * of = 0 if op2 == 1
2273 */
2274 auto node = this->astCtxt->ite(
2275 this->astCtxt->land(
2276 this->astCtxt->equal(
2277 /* #672 */
2278 this->astCtxt->reference(parent),
2279 this->astCtxt->reference(parent)
2280 /* ---- */
2281 ),
2282 this->astCtxt->equal(
2283 op2,
2284 this->astCtxt->bv(1, bvSize)
2285 )
2286 ),
2287 this->astCtxt->bv(0, 1),
2288 this->symbolicEngine->getOperandAst(of)
2289 );
2290
2291 /* Create the symbolic expression */
2292 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag");
2293
2294 if (op2->evaluate()) {
2295 /* Spread the taint from the parent to the child */
2296 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted);
2297 }
2298 else {
2299 inst.removeWrittenRegister(of.getConstRegister());
2300 }
2301 }
2302
2303
2304 void x86Semantics::ofShl_s(triton::arch::Instruction& inst,
2309 bool vol) {
2310
2311 auto bvSize = dst.getBitSize();
2312 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
2313
2314 /*
2315 * Create the semantic.
2316 * of = ((op1 >> (bvSize - 1)) ^ (op1 >> (bvSize - 2))) & 1; if op2 == 1
2317 */
2318 auto node = this->astCtxt->ite(
2319 this->astCtxt->equal(
2320 op2,
2321 this->astCtxt->bv(1, bvSize)),
2322 this->astCtxt->extract(0, 0,
2323 this->astCtxt->bvxor(
2324 this->astCtxt->bvlshr(op1, this->astCtxt->bvsub(this->astCtxt->bv(bvSize, bvSize), this->astCtxt->bv(1, bvSize))),
2325 this->astCtxt->bvlshr(op1, this->astCtxt->bvsub(this->astCtxt->bv(bvSize, bvSize), this->astCtxt->bv(2, bvSize)))
2326 )
2327 ),
2328 this->symbolicEngine->getOperandAst(of)
2329 );
2330
2331 /* Create the symbolic expression */
2332 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag");
2333
2334 if (op2->evaluate()) {
2335 /* Spread the taint from the parent to the child */
2336 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted);
2337 }
2338 else {
2339 inst.removeWrittenRegister(of.getConstRegister());
2340 }
2341 }
2342
2343
2344 void x86Semantics::ofShld_s(triton::arch::Instruction& inst,
2350 bool vol) {
2351
2352 auto bvSize = dst.getBitSize();
2353 auto bv1Size = op1->getBitvectorSize();
2354 auto bv2Size = op2->getBitvectorSize();
2355 auto bv3Size = op3->getBitvectorSize();
2356 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
2357
2358 /*
2359 * Create the semantic.
2360 * of = MSB(rol(op3, concat(op2,op1))) ^ MSB(op1); if op3 == 1
2361 */
2362 auto node = this->astCtxt->ite(
2363 this->astCtxt->equal(
2364 this->astCtxt->zx(bvSize - bv3Size, op3),
2365 this->astCtxt->bv(1, bvSize)),
2366 this->astCtxt->bvxor(
2367 this->astCtxt->extract(
2368 bvSize-1, bvSize-1,
2369 this->astCtxt->bvrol(
2370 this->astCtxt->concat(op2, op1),
2371 this->astCtxt->zx(((bv1Size + bv2Size) - bv3Size), op3)
2372 )
2373 ),
2374 this->astCtxt->extract(bvSize-1, bvSize-1, op1)
2375 ),
2376 this->symbolicEngine->getOperandAst(of)
2377 );
2378
2379 /* Create the symbolic expression */
2380 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag");
2381
2382 if (op3->evaluate()) {
2383 /* Spread the taint from the parent to the child */
2384 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted);
2385 }
2386 else {
2387 inst.removeWrittenRegister(of.getConstRegister());
2388 }
2389 }
2390
2391
2392 void x86Semantics::ofShr_s(triton::arch::Instruction& inst,
2397 bool vol) {
2398
2399 auto bvSize = dst.getBitSize();
2400 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
2401
2402 /*
2403 * Create the semantic.
2404 * of = ((op1 >> (bvSize - 1)) & 1) if op2 == 1
2405 */
2406 auto node = this->astCtxt->ite(
2407 this->astCtxt->equal(
2408 op2,
2409 this->astCtxt->bv(1, bvSize)),
2410 this->astCtxt->extract(0, 0, this->astCtxt->bvlshr(op1, this->astCtxt->bvsub(this->astCtxt->bv(bvSize, bvSize), this->astCtxt->bv(1, bvSize)))),
2411 this->symbolicEngine->getOperandAst(of)
2412 );
2413
2414 /* Create the symbolic expression */
2415 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag");
2416
2417 if (op2->evaluate()) {
2418 /* Spread the taint from the parent to the child */
2419 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted);
2420 }
2421 else {
2422 inst.removeWrittenRegister(of.getConstRegister());
2423 }
2424 }
2425
2426
2427 void x86Semantics::ofShrd_s(triton::arch::Instruction& inst,
2433 bool vol) {
2434
2435 auto bvSize = dst.getBitSize();
2436 auto bv1Size = op1->getBitvectorSize();
2437 auto bv2Size = op2->getBitvectorSize();
2438 auto bv3Size = op3->getBitvectorSize();
2439 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
2440
2441 /*
2442 * Create the semantic.
2443 * of = MSB(ror(op3, concat(op2,op1))) ^ MSB(op1); if op3 == 1
2444 */
2445 auto node = this->astCtxt->ite(
2446 this->astCtxt->equal(
2447 this->astCtxt->zx(bvSize - op3->getBitvectorSize(), op3),
2448 this->astCtxt->bv(1, bvSize)),
2449 this->astCtxt->bvxor(
2450 this->astCtxt->extract(
2451 bvSize - 1, bvSize - 1,
2452 this->astCtxt->bvror(
2453 this->astCtxt->concat(op2, op1),
2454 this->astCtxt->zx(((bv1Size + bv2Size) - bv3Size), op3)
2455 )
2456 ),
2457 this->astCtxt->extract(dst.getBitSize()-1, dst.getBitSize()-1, op1)
2458 ),
2459 this->symbolicEngine->getOperandAst(of)
2460 );
2461
2462 /* Create the symbolic expression */
2463 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag");
2464
2465 if (op3->evaluate()) {
2466 /* Spread the taint from the parent to the child */
2467 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted);
2468 }
2469 else {
2470 inst.removeWrittenRegister(of.getConstRegister());
2471 }
2472 }
2473
2474
2475 void x86Semantics::ofSub_s(triton::arch::Instruction& inst,
2480 bool vol) {
2481
2482 auto bvSize = dst.getBitSize();
2483 auto low = vol ? 0 : dst.getLow();
2484 auto high = vol ? bvSize-1 : dst.getHigh();
2485
2486 /*
2487 * Create the semantic.
2488 * of = high:bool((op1 ^ op2) & (op1 ^ regDst))
2489 */
2490 auto node = this->astCtxt->extract(bvSize-1, bvSize-1,
2491 this->astCtxt->bvand(
2492 this->astCtxt->bvxor(op1, op2),
2493 this->astCtxt->bvxor(op1, this->astCtxt->extract(high, low, this->astCtxt->reference(parent)))
2494 )
2495 );
2496
2497 /* Create the symbolic expression */
2498 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_OF), "Overflow flag");
2499
2500 /* Spread the taint from the parent to the child */
2501 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_OF), parent->isTainted);
2502 }
2503
2504
2505 void x86Semantics::pf_s(triton::arch::Instruction& inst,
2508 bool vol) {
2509
2510 auto low = vol ? 0 : dst.getLow();
2511 auto high = vol ? triton::bitsize::byte-1 : !low ? triton::bitsize::byte-1 : triton::bitsize::word-1;
2512
2513 /*
2514 * Create the semantics.
2515 *
2516 * pf is set to one if there is an even number of bit set to 1 in the least
2517 * significant byte of the result.
2518 */
2519 auto node = this->astCtxt->bv(1, 1);
2520 for (triton::uint32 counter = 0; counter <= triton::bitsize::byte-1; counter++) {
2521 node = this->astCtxt->bvxor(node, this->astCtxt->extract(counter, counter, this->astCtxt->reference(parent)));
2522 }
2523
2524 /* Create the symbolic expression */
2525 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_PF), "Parity flag");
2526
2527 /* Spread the taint from the parent to the child */
2528 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_PF), parent->isTainted);
2529 }
2530
2531
2532 void x86Semantics::pfShl_s(triton::arch::Instruction& inst,
2536 bool vol) {
2537
2538 auto bvSize = dst.getBitSize();
2539 auto low = vol ? 0 : dst.getLow();
2540 auto high = vol ? triton::bitsize::byte-1 : !low ? triton::bitsize::byte-1 : triton::bitsize::word-1;
2541 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
2542
2543 /*
2544 * Create the semantics.
2545 * pf if op2 != 0
2546 */
2547 auto node1 = this->astCtxt->bv(1, 1);
2548 for (triton::uint32 counter = 0; counter <= triton::bitsize::byte-1; counter++) {
2549 node1 = this->astCtxt->bvxor(node1, this->astCtxt->extract(counter, counter, this->astCtxt->reference(parent)));
2550 }
2551
2552 auto node2 = this->astCtxt->ite(
2553 this->astCtxt->equal(this->astCtxt->zx(bvSize - op2->getBitvectorSize(), op2), this->astCtxt->bv(0, bvSize)),
2554 this->symbolicEngine->getOperandAst(pf),
2555 node1
2556 );
2557
2558 /* Create the symbolic expression */
2559 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, pf.getConstRegister(), "Parity flag");
2560
2561 if (op2->evaluate()) {
2562 /* Spread the taint from the parent to the child */
2563 expr->isTainted = this->taintEngine->setTaintRegister(pf.getConstRegister(), parent->isTainted);
2564 }
2565 else {
2566 inst.removeWrittenRegister(pf.getConstRegister());
2567 }
2568 }
2569
2570
2571 void x86Semantics::sf_s(triton::arch::Instruction& inst,
2574 bool vol) {
2575
2576 auto bvSize = dst.getBitSize();
2577 auto high = vol ? bvSize-1 : dst.getHigh();
2578
2579 /*
2580 * Create the semantic.
2581 * sf = high:bool(regDst)
2582 */
2583 auto node = this->astCtxt->extract(high, high, this->astCtxt->reference(parent));
2584
2585 /* Create the symbolic expression */
2586 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_SF), "Sign flag");
2587
2588 /* Spread the taint from the parent to the child */
2589 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_SF), parent->isTainted);
2590 }
2591
2592
2593 void x86Semantics::sfShl_s(triton::arch::Instruction& inst,
2597 bool vol) {
2598
2599 auto bvSize = dst.getBitSize();
2600 auto high = vol ? bvSize-1 : dst.getHigh();
2601 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
2602
2603 /*
2604 * Create the semantic.
2605 * sf if op2 != 0
2606 */
2607 auto node = this->astCtxt->ite(
2608 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)),
2609 this->symbolicEngine->getOperandAst(sf),
2610 this->astCtxt->extract(high, high, this->astCtxt->reference(parent))
2611 );
2612
2613 /* Create the symbolic expression */
2614 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, sf.getConstRegister(), "Sign flag");
2615
2616 if (op2->evaluate()) {
2617 /* Spread the taint from the parent to the child */
2618 expr->isTainted = this->taintEngine->setTaintRegister(sf.getConstRegister(), parent->isTainted);
2619 }
2620 else {
2621 inst.removeWrittenRegister(sf.getConstRegister());
2622 }
2623 }
2624
2625
2626 void x86Semantics::sfShld_s(triton::arch::Instruction& inst,
2632 bool vol) {
2633
2634 auto bvSize = dst.getBitSize();
2635 auto bv1Size = op1->getBitvectorSize();
2636 auto bv2Size = op2->getBitvectorSize();
2637 auto bv3Size = op3->getBitvectorSize();
2638 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
2639
2640 /*
2641 * Create the semantic.
2642 * MSB(rol(op3, concat(op2,op1))) if op3 != 0
2643 */
2644 auto node = this->astCtxt->ite(
2645 this->astCtxt->equal(op3, this->astCtxt->bv(0, bv3Size)),
2646 this->symbolicEngine->getOperandAst(sf),
2647 this->astCtxt->extract(
2648 bvSize-1, bvSize-1,
2649 this->astCtxt->bvrol(
2650 this->astCtxt->concat(op2, op1),
2651 this->astCtxt->zx(((bv1Size + bv2Size) - bv3Size), op3)
2652 )
2653 )
2654 );
2655
2656 /* Create the symbolic expression */
2657 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, sf.getConstRegister(), "Sign flag");
2658
2659 if (op3->evaluate()) {
2660 /* Spread the taint from the parent to the child */
2661 expr->isTainted = this->taintEngine->setTaintRegister(sf.getConstRegister(), parent->isTainted);
2662 }
2663 else {
2664 inst.removeWrittenRegister(sf.getConstRegister());
2665 }
2666 }
2667
2668
2669 void x86Semantics::sfShrd_s(triton::arch::Instruction& inst,
2675 bool vol) {
2676
2677 auto bvSize = dst.getBitSize();
2678 auto bv1Size = op1->getBitvectorSize();
2679 auto bv2Size = op2->getBitvectorSize();
2680 auto bv3Size = op3->getBitvectorSize();
2681 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
2682
2683 /*
2684 * Create the semantic.
2685 * MSB(ror(op3, concat(op2,op1))) if op3 != 0
2686 */
2687 auto node = this->astCtxt->ite(
2688 this->astCtxt->equal(op3, this->astCtxt->bv(0, bv3Size)),
2689 this->symbolicEngine->getOperandAst(sf),
2690 this->astCtxt->extract(
2691 bvSize - 1, bvSize - 1,
2692 this->astCtxt->bvror(
2693 this->astCtxt->concat(op2, op1),
2694 this->astCtxt->zx(((bv1Size + bv2Size) - bv3Size), op3)
2695 )
2696 )
2697 );
2698
2699 /* Create the symbolic expression */
2700 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, sf.getConstRegister(), "Sign flag");
2701
2702 if (op3->evaluate()) {
2703 /* Spread the taint from the parent to the child */
2704 expr->isTainted = this->taintEngine->setTaintRegister(sf.getConstRegister(), parent->isTainted);
2705 }
2706 else {
2707 inst.removeWrittenRegister(sf.getConstRegister());
2708 }
2709 }
2710
2711
2712 void x86Semantics::zf_s(triton::arch::Instruction& inst,
2715 bool vol) {
2716
2717 auto bvSize = dst.getBitSize();
2718 auto low = vol ? 0 : dst.getLow();
2719 auto high = vol ? bvSize-1 : dst.getHigh();
2720
2721 /*
2722 * Create the semantic.
2723 * zf = 0 == regDst
2724 */
2725 auto node = this->astCtxt->ite(
2726 this->astCtxt->equal(
2727 this->astCtxt->extract(high, low, this->astCtxt->reference(parent)),
2728 this->astCtxt->bv(0, bvSize)
2729 ),
2730 this->astCtxt->bv(1, 1),
2731 this->astCtxt->bv(0, 1)
2732 );
2733
2734 /* Create the symbolic expression */
2735 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_ZF), "Zero flag");
2736
2737 /* Spread the taint from the parent to the child */
2738 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_ZF), parent->isTainted);
2739 }
2740
2741
2742 void x86Semantics::zfBsf_s(triton::arch::Instruction& inst,
2746 bool vol) {
2747
2748 /*
2749 * Create the semantic.
2750 * zf = 1 if op2 == 0 else 0
2751 */
2752 auto node = this->astCtxt->ite(
2753 this->astCtxt->equal(op2, this->astCtxt->bv(0, src.getBitSize())),
2754 this->astCtxt->bvtrue(),
2755 this->astCtxt->bvfalse()
2756 );
2757
2758 /* Create the symbolic expression */
2759 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_ZF), "Zero flag");
2760
2761 /* Spread the taint from the parent to the child */
2762 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_ZF), parent->isTainted);
2763 }
2764
2765
2766 void x86Semantics::zfShl_s(triton::arch::Instruction& inst,
2770 bool vol) {
2771
2772 auto bvSize = dst.getBitSize();
2773 auto low = vol ? 0 : dst.getLow();
2774 auto high = vol ? bvSize-1 : dst.getHigh();
2775 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
2776
2777 /*
2778 * Create the semantic.
2779 * zf if op2 != 0
2780 */
2781 auto node = this->astCtxt->ite(
2782 this->astCtxt->equal(this->astCtxt->zx(bvSize - op2->getBitvectorSize(), op2), this->astCtxt->bv(0, bvSize)),
2783 this->symbolicEngine->getOperandAst(zf),
2784 this->astCtxt->ite(
2785 this->astCtxt->equal(
2786 this->astCtxt->extract(high, low, this->astCtxt->reference(parent)),
2787 this->astCtxt->bv(0, bvSize)
2788 ),
2789 this->astCtxt->bv(1, 1),
2790 this->astCtxt->bv(0, 1)
2791 )
2792 );
2793
2794 /* Create the symbolic expression */
2795 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, zf.getConstRegister(), "Zero flag");
2796
2797 if (op2->evaluate()) {
2798 /* Spread the taint from the parent to the child */
2799 expr->isTainted = this->taintEngine->setTaintRegister(zf.getConstRegister(), parent->isTainted);
2800 }
2801 else {
2802 inst.removeWrittenRegister(zf.getConstRegister());
2803 }
2804 }
2805
2806
2807 void x86Semantics::aaa_s(triton::arch::Instruction& inst) {
2808 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
2809 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AH));
2810 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF));
2811 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
2812 auto dsttmp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
2813
2814 /* Create symbolic operands */
2815 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
2816 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
2817 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
2818
2819 /* Create the semantics */
2820 auto node = this->astCtxt->ite(
2821 // if
2822 this->astCtxt->lor(
2823 this->astCtxt->bvugt(
2824 this->astCtxt->bvand(op1, this->astCtxt->bv(0xf, src1.getBitSize())),
2825 this->astCtxt->bv(9, src1.getBitSize())
2826 ),
2827 this->astCtxt->equal(op3, this->astCtxt->bvtrue())
2828 ),
2829 // then
2830 this->astCtxt->concat(
2831 this->astCtxt->bvadd(op2, this->astCtxt->bv(1, src2.getBitSize())),
2832 this->astCtxt->bvand(
2833 this->astCtxt->bvadd(op1, this->astCtxt->bv(6, src1.getBitSize())),
2834 this->astCtxt->bv(0xf, src1.getBitSize())
2835 )
2836 ),
2837 // else
2838 this->astCtxt->concat(
2839 op2,
2840 this->astCtxt->bvand(op1, this->astCtxt->bv(0xf, src1.getBitSize()))
2841 )
2842 );
2843
2844 /* Create symbolic expression */
2845 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "AAA operation");
2846
2847 /* Spread taint */
2848 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
2849
2850 /* Update symbolic flags */
2851 this->afAaa_s(inst, expr, dsttmp, op1, op3);
2852 this->cfAaa_s(inst, expr, dsttmp, op1, op3);
2853
2854 /* Tag undefined flags */
2855 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
2856 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
2857 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
2858 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF));
2859
2860 /* Update the symbolic control flow */
2861 this->controlFlow_s(inst);
2862 }
2863
2864
2865 void x86Semantics::aad_s(triton::arch::Instruction& inst) {
2867 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
2868 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AH));
2869 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
2870 auto dsttmp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
2871
2872 /* D5 ib */
2873 if (inst.operands.size() == 1)
2874 src1 = inst.operands[0];
2875
2876 /* Create symbolic operands */
2877 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
2878 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
2879 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
2880
2881 /* Create the semantics */
2882 auto node = this->astCtxt->zx(
2884 this->astCtxt->bvadd(
2885 op2,
2886 this->astCtxt->bvmul(op3, op1)
2887 )
2888 );
2889
2890 /* Create symbolic expression */
2891 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "AAD operation");
2892
2893 /* Spread taint */
2894 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
2895
2896 /* Update symbolic flags */
2897 this->pf_s(inst, expr, dsttmp);
2898 this->sf_s(inst, expr, dsttmp);
2899 this->zf_s(inst, expr, dsttmp);
2900
2901 /* Tag undefined flags */
2902 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
2903 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
2904 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
2905
2906 /* Update the symbolic control flow */
2907 this->controlFlow_s(inst);
2908 }
2909
2910
2911 void x86Semantics::aam_s(triton::arch::Instruction& inst) {
2913 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
2914 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
2915 auto dsttmp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
2916
2917 /* D4 ib */
2918 if (inst.operands.size() == 1)
2919 src1 = inst.operands[0];
2920
2921 /* Create symbolic operands */
2922 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
2923 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
2924
2925 /* Create the semantics */
2926 auto node = this->astCtxt->concat(
2927 this->astCtxt->bvudiv(op2, op1),
2928 this->astCtxt->bvurem(op2, op1)
2929 );
2930
2931 /* Create symbolic expression */
2932 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "AAM operation");
2933
2934 /* Spread taint */
2935 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
2936
2937 /* Update symbolic flags */
2938 this->pf_s(inst, expr, dsttmp);
2939 this->sf_s(inst, expr, dsttmp);
2940 this->zf_s(inst, expr, dsttmp);
2941
2942 /* Tag undefined flags */
2943 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
2944 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
2945 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
2946
2947 /* Update the symbolic control flow */
2948 this->controlFlow_s(inst);
2949 }
2950
2951
2952 void x86Semantics::aas_s(triton::arch::Instruction& inst) {
2953 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
2954 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AH));
2955 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF));
2956 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
2957 auto dsttmp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
2958
2959 /* Create symbolic operands */
2960 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
2961 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
2962 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
2963
2964 /* Create the semantics */
2965 auto node = this->astCtxt->ite(
2966 // if
2967 this->astCtxt->lor(
2968 this->astCtxt->bvugt(
2969 this->astCtxt->bvand(op1, this->astCtxt->bv(0xf, src1.getBitSize())),
2970 this->astCtxt->bv(9, src1.getBitSize())
2971 ),
2972 this->astCtxt->equal(op3, this->astCtxt->bvtrue())
2973 ),
2974 // then
2975 this->astCtxt->concat(
2976 this->astCtxt->bvsub(op2, this->astCtxt->bv(1, src2.getBitSize())),
2977 this->astCtxt->bvand(
2978 this->astCtxt->bvsub(op1, this->astCtxt->bv(6, src1.getBitSize())),
2979 this->astCtxt->bv(0xf, src1.getBitSize())
2980 )
2981 ),
2982 // else
2983 this->astCtxt->concat(
2984 op2,
2985 this->astCtxt->bvand(op1, this->astCtxt->bv(0xf, src1.getBitSize()))
2986 )
2987 );
2988
2989 /* Create symbolic expression */
2990 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "AAS operation");
2991
2992 /* Spread taint */
2993 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
2994
2995 /* Update symbolic flags */
2996 this->afAaa_s(inst, expr, dsttmp, op1, op3);
2997 this->cfAaa_s(inst, expr, dsttmp, op1, op3);
2998
2999 /* Tag undefined flags */
3000 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
3001 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
3002 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
3003 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF));
3004
3005 /* Update the symbolic control flow */
3006 this->controlFlow_s(inst);
3007 }
3008
3009
3010 void x86Semantics::adc_s(triton::arch::Instruction& inst) {
3011 auto& dst = inst.operands[0];
3012 auto& src = inst.operands[1];
3013 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
3014
3015 /* Create symbolic operands */
3016 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3017 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3018 auto op3 = this->symbolicEngine->getOperandAst(inst, cf);
3019
3020 /* Create the semantics */
3021 auto node = this->astCtxt->bvadd(this->astCtxt->bvadd(op1, op2), this->astCtxt->zx(dst.getBitSize()-1, op3));
3022
3023 /* Create symbolic expression */
3024 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ADC operation");
3025
3026 /* Spread taint */
3027 expr->isTainted = this->taintEngine->taintUnion(dst, src);
3028 expr->isTainted = this->taintEngine->taintUnion(dst, cf);
3029
3030 /* Update symbolic flags */
3031 this->af_s(inst, expr, dst, op1, op2);
3032 this->cfAdd_s(inst, expr, dst, op1, op2);
3033 this->ofAdd_s(inst, expr, dst, op1, op2);
3034 this->pf_s(inst, expr, dst);
3035 this->sf_s(inst, expr, dst);
3036 this->zf_s(inst, expr, dst);
3037
3038 /* Update the symbolic control flow */
3039 this->controlFlow_s(inst);
3040 }
3041
3042
3043 void x86Semantics::adcx_s(triton::arch::Instruction& inst) {
3044 auto& dst = inst.operands[0];
3045 auto& src = inst.operands[1];
3046 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
3047
3048 /* Create symbolic operands */
3049 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3050 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3051 auto op3 = this->symbolicEngine->getOperandAst(inst, cf);
3052
3053 /* Create the semantics */
3054 auto node = this->astCtxt->bvadd(this->astCtxt->bvadd(op1, op2), this->astCtxt->zx(dst.getBitSize()-1, op3));
3055
3056 /* Create symbolic expression */
3057 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ADCX operation");
3058
3059 /* Spread taint */
3060 expr->isTainted = this->taintEngine->taintUnion(dst, src);
3061 expr->isTainted = this->taintEngine->taintUnion(dst, cf);
3062
3063 /* Update symbolic flags */
3064 this->cfAdd_s(inst, expr, dst, op1, op2);
3065
3066 /* Update the symbolic control flow */
3067 this->controlFlow_s(inst);
3068 }
3069
3070
3071 void x86Semantics::add_s(triton::arch::Instruction& inst) {
3072 auto& dst = inst.operands[0];
3073 auto& src = inst.operands[1];
3074
3075 /* Create symbolic operands */
3076 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3077 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3078
3079 /* Create the semantics */
3080 auto node = this->astCtxt->bvadd(op1, op2);
3081
3082 /* Create symbolic expression */
3083 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ADD operation");
3084
3085 /* Spread taint */
3086 expr->isTainted = this->taintEngine->taintUnion(dst, src);
3087
3088 /* Update symbolic flags */
3089 this->af_s(inst, expr, dst, op1, op2);
3090 this->cfAdd_s(inst, expr, dst, op1, op2);
3091 this->ofAdd_s(inst, expr, dst, op1, op2);
3092 this->pf_s(inst, expr, dst);
3093 this->sf_s(inst, expr, dst);
3094 this->zf_s(inst, expr, dst);
3095
3096 /* Update the symbolic control flow */
3097 this->controlFlow_s(inst);
3098 }
3099
3100
3101 void x86Semantics::and_s(triton::arch::Instruction& inst) {
3102 auto& dst = inst.operands[0];
3103 auto& src = inst.operands[1];
3104
3105 /* Create symbolic operands */
3106 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3107 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3108
3109 /* Create the semantics */
3110 auto node = this->astCtxt->bvand(op1, op2);
3111
3112 /* Create symbolic expression */
3113 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "AND operation");
3114
3115 /* Spread taint */
3116 expr->isTainted = this->taintEngine->taintUnion(dst, src);
3117
3118 /* Update symbolic flags */
3119 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag");
3120 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
3121 this->pf_s(inst, expr, dst);
3122 this->sf_s(inst, expr, dst);
3123 this->zf_s(inst, expr, dst);
3124
3125 /* Tag undefined flags */
3126 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
3127
3128 /* Update the symbolic control flow */
3129 this->controlFlow_s(inst);
3130 }
3131
3132
3133 void x86Semantics::andn_s(triton::arch::Instruction& inst) {
3134 auto& dst = inst.operands[0];
3135 auto& src1 = inst.operands[1];
3136 auto& src2 = inst.operands[2];
3137
3138 /* Create symbolic operands */
3139 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
3140 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
3141
3142 /* Create the semantics */
3143 auto node = this->astCtxt->bvand(this->astCtxt->bvnot(op2), op3);
3144
3145 /* Create symbolic expression */
3146 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ANDN operation");
3147
3148 /* Spread taint */
3149 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
3150
3151 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag");
3152 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
3153 this->sf_s(inst, expr, dst);
3154 this->zf_s(inst, expr, dst);
3155
3156 /* Update the symbolic control flow */
3157 this->controlFlow_s(inst);
3158 }
3159
3160
3161 void x86Semantics::andnpd_s(triton::arch::Instruction& inst) {
3162 auto& dst = inst.operands[0];
3163 auto& src = inst.operands[1];
3164
3165 /* Create symbolic operands */
3166 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3167 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3168
3169 /* Create the semantics */
3170 auto node = this->astCtxt->bvand(this->astCtxt->bvnot(op1), op2);
3171
3172 /* Create symbolic expression */
3173 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ANDNPD operation");
3174
3175 /* Spread taint */
3176 expr->isTainted = this->taintEngine->taintUnion(dst, src);
3177
3178 /* Update the symbolic control flow */
3179 this->controlFlow_s(inst);
3180 }
3181
3182
3183 void x86Semantics::andnps_s(triton::arch::Instruction& inst) {
3184 auto& dst = inst.operands[0];
3185 auto& src = inst.operands[1];
3186
3187 /* Create symbolic operands */
3188 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3189 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3190
3191 /* Create the semantics */
3192 auto node = this->astCtxt->bvand(this->astCtxt->bvnot(op1), op2);
3193
3194 /* Create symbolic expression */
3195 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ANDNPS operation");
3196
3197 /* Spread taint */
3198 expr->isTainted = this->taintEngine->taintUnion(dst, src);
3199
3200 /* Update the symbolic control flow */
3201 this->controlFlow_s(inst);
3202 }
3203
3204
3205 void x86Semantics::andpd_s(triton::arch::Instruction& inst) {
3206 auto& dst = inst.operands[0];
3207 auto& src = inst.operands[1];
3208
3209 /* Create symbolic operands */
3210 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3211 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3212
3213 /* Create the semantics */
3214 auto node = this->astCtxt->bvand(op1, op2);
3215
3216 /* Create symbolic expression */
3217 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ANDPD operation");
3218
3219 /* Spread taint */
3220 expr->isTainted = this->taintEngine->taintUnion(dst, src);
3221
3222 /* Update the symbolic control flow */
3223 this->controlFlow_s(inst);
3224 }
3225
3226
3227 void x86Semantics::andps_s(triton::arch::Instruction& inst) {
3228 auto& dst = inst.operands[0];
3229 auto& src = inst.operands[1];
3230
3231 /* Create symbolic operands */
3232 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3233 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3234
3235 /* Create the semantics */
3236 auto node = this->astCtxt->bvand(op1, op2);
3237
3238 /* Create symbolic expression */
3239 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ANDPS operation");
3240
3241 /* Spread taint */
3242 expr->isTainted = this->taintEngine->taintUnion(dst, src);
3243
3244 /* Update the symbolic control flow */
3245 this->controlFlow_s(inst);
3246 }
3247
3248
3249 void x86Semantics::bextr_s(triton::arch::Instruction& inst) {
3250 auto& dst = inst.operands[0];
3251 auto& src1 = inst.operands[1];
3252 auto& src2 = inst.operands[2];
3253
3254 /* Create symbolic operands */
3255 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
3256 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
3257
3258 /* Create the semantics */
3259 auto node = this->astCtxt->bvand(
3260 this->astCtxt->bvlshr(
3261 op1,
3262 this->astCtxt->zx(src1.getBitSize() - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2))
3263 ),
3264 this->astCtxt->bvsub(
3265 this->astCtxt->bvshl(
3266 this->astCtxt->bv(1, src1.getBitSize()),
3267 this->astCtxt->zx(src1.getBitSize() - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2))
3268 ),
3269 this->astCtxt->bv(1, src1.getBitSize())
3270 )
3271 );
3272
3273 /* Create symbolic expression */
3274 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "BEXTR operation");
3275
3276 /* Spread taint */
3277 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
3278
3279 /* Update symbolic flags */
3280 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag");
3281 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
3282 this->zf_s(inst, expr, dst);
3283
3284 /* Update the symbolic control flow */
3285 this->controlFlow_s(inst);
3286 }
3287
3288
3289 void x86Semantics::blsi_s(triton::arch::Instruction& inst) {
3290 auto& dst = inst.operands[0];
3291 auto& src = inst.operands[1];
3292
3293 /* Create symbolic operands */
3294 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
3295
3296 /* Create the semantics */
3297 auto node = this->astCtxt->bvand(this->astCtxt->bvneg(op1), op1);
3298
3299 /* Create symbolic expression */
3300 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "BLSI operation");
3301
3302 /* Spread taint */
3303 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
3304
3305 /* Update symbolic flags */
3306 this->cfBlsi_s(inst, expr, src, op1);
3307 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
3308 this->sf_s(inst, expr, dst);
3309 this->zf_s(inst, expr, dst);
3310
3311 /* Update the symbolic control flow */
3312 this->controlFlow_s(inst);
3313 }
3314
3315
3316 void x86Semantics::blsmsk_s(triton::arch::Instruction& inst) {
3317 auto& dst = inst.operands[0];
3318 auto& src = inst.operands[1];
3319
3320 /* Create symbolic operands */
3321 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
3322
3323 /* Create the semantics */
3324 auto node = this->astCtxt->bvxor(
3325 this->astCtxt->bvsub(op1, this->astCtxt->bv(1, src.getBitSize())),
3326 op1
3327 );
3328
3329 /* Create symbolic expression */
3330 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "BLSMSK operation");
3331
3332 /* Spread taint */
3333 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
3334
3335 /* Update symbolic flags */
3336 this->cfBlsmsk_s(inst, expr, src, op1);
3337 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
3338 this->sf_s(inst, expr, dst);
3339 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_ZF), "Clears zero flag");
3340
3341 /* Update the symbolic control flow */
3342 this->controlFlow_s(inst);
3343 }
3344
3345
3346 void x86Semantics::blsr_s(triton::arch::Instruction& inst) {
3347 auto& dst = inst.operands[0];
3348 auto& src = inst.operands[1];
3349
3350 /* Create symbolic operands */
3351 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
3352
3353 /* Create the semantics */
3354 auto node = this->astCtxt->bvand(
3355 this->astCtxt->bvsub(op1, this->astCtxt->bv(1, src.getBitSize())),
3356 op1
3357 );
3358
3359 /* Create symbolic expression */
3360 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "BLSR operation");
3361
3362 /* Spread taint */
3363 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
3364
3365 /* Update symbolic flags */
3366 this->cfBlsr_s(inst, expr, src, op1);
3367 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
3368 this->sf_s(inst, expr, dst);
3369 this->zf_s(inst, expr, dst);
3370
3371 /* Update the symbolic control flow */
3372 this->controlFlow_s(inst);
3373 }
3374
3375
3376 void x86Semantics::bsf_s(triton::arch::Instruction& inst) {
3377 auto& dst = inst.operands[0];
3378 auto& src = inst.operands[1];
3379 auto bvSize1 = dst.getBitSize();
3380 auto bvSize2 = src.getBitSize();
3381
3382 /* Create symbolic operands */
3383 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3384 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3385
3386 /* Create the semantics */
3387 triton::ast::SharedAbstractNode node = nullptr;
3388 switch (src.getSize()) {
3389 case triton::size::byte:
3390 node = this->astCtxt->ite(
3391 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSF only if op2 != 0 */
3392 op1,
3393 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
3394 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
3395 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
3396 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
3397 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
3398 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
3399 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
3400 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
3401 this->astCtxt->bv(0, bvSize1)
3402 ))))))))
3403 );
3404 break;
3405 case triton::size::word:
3406 node = this->astCtxt->ite(
3407 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSF only if op2 != 0 */
3408 op1,
3409 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
3410 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
3411 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
3412 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
3413 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
3414 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
3415 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
3416 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
3417 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
3418 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
3419 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
3420 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
3421 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
3422 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
3423 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
3424 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
3425 this->astCtxt->bv(0, bvSize1)
3426 ))))))))))))))))
3427 );
3428 break;
3430 node = this->astCtxt->ite(
3431 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSF only if op2 != 0 */
3432 op1,
3433 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
3434 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
3435 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
3436 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
3437 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
3438 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
3439 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
3440 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
3441 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
3442 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
3443 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
3444 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
3445 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
3446 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
3447 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
3448 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
3449 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(16, 16, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1),
3450 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(17, 17, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1),
3451 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(18, 18, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1),
3452 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(19, 19, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1),
3453 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(20, 20, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1),
3454 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(21, 21, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1),
3455 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(22, 22, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1),
3456 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(23, 23, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1),
3457 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(24, 24, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1),
3458 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(25, 25, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1),
3459 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(26, 26, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1),
3460 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(27, 27, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1),
3461 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(28, 28, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1),
3462 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(29, 29, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1),
3463 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(30, 30, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1),
3464 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(31, 31, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1),
3465 this->astCtxt->bv(0, bvSize1)
3466 ))))))))))))))))))))))))))))))))
3467 );
3468 break;
3470 node = this->astCtxt->ite(
3471 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSF only if op2 != 0 */
3472 op1,
3473 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
3474 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
3475 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
3476 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
3477 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
3478 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
3479 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
3480 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
3481 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
3482 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
3483 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
3484 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
3485 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
3486 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
3487 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
3488 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
3489 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(16, 16, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1),
3490 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(17, 17, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1),
3491 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(18, 18, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1),
3492 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(19, 19, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1),
3493 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(20, 20, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1),
3494 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(21, 21, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1),
3495 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(22, 22, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1),
3496 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(23, 23, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1),
3497 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(24, 24, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1),
3498 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(25, 25, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1),
3499 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(26, 26, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1),
3500 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(27, 27, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1),
3501 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(28, 28, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1),
3502 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(29, 29, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1),
3503 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(30, 30, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1),
3504 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(31, 31, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1),
3505 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(32, 32, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(32, bvSize1),
3506 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(33, 33, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(33, bvSize1),
3507 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(34, 34, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(34, bvSize1),
3508 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(35, 35, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(35, bvSize1),
3509 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(36, 36, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(36, bvSize1),
3510 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(37, 37, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(37, bvSize1),
3511 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(38, 38, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(38, bvSize1),
3512 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(39, 39, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(39, bvSize1),
3513 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(40, 40, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(40, bvSize1),
3514 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(41, 41, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(41, bvSize1),
3515 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(42, 42, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(42, bvSize1),
3516 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(43, 43, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(43, bvSize1),
3517 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(44, 44, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(44, bvSize1),
3518 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(45, 45, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(45, bvSize1),
3519 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(46, 46, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(46, bvSize1),
3520 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(47, 47, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(47, bvSize1),
3521 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(48, 48, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(48, bvSize1),
3522 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(49, 49, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(49, bvSize1),
3523 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(50, 50, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(50, bvSize1),
3524 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(51, 51, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(51, bvSize1),
3525 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(52, 52, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(52, bvSize1),
3526 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(53, 53, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(53, bvSize1),
3527 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(54, 54, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(54, bvSize1),
3528 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(55, 55, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(55, bvSize1),
3529 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(56, 56, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(56, bvSize1),
3530 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(57, 57, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(57, bvSize1),
3531 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(58, 58, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(58, bvSize1),
3532 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(59, 59, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(59, bvSize1),
3533 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(60, 60, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(60, bvSize1),
3534 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(61, 61, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(61, bvSize1),
3535 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(62, 62, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(62, bvSize1),
3536 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(63, 63, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(63, bvSize1),
3537 this->astCtxt->bv(0, bvSize1)
3538 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
3539 );
3540 break;
3541 default:
3542 throw triton::exceptions::Semantics("x86Semantics::bsf_s(): Invalid operand size.");
3543 }
3544
3545 /* Create symbolic expression */
3546 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "BSF operation");
3547
3548 /* Spread taint */
3549 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
3550
3551 /* Update symbolic flags */
3552 this->zfBsf_s(inst, expr, src, op2);
3553
3554 /* Tag undefined flags */
3555 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
3556 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
3557 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
3558 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
3559 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
3560
3561 /* Update the symbolic control flow */
3562 this->controlFlow_s(inst);
3563 }
3564
3565
3566 void x86Semantics::bsr_s(triton::arch::Instruction& inst) {
3567 auto& dst = inst.operands[0];
3568 auto& src = inst.operands[1];
3569 auto bvSize1 = dst.getBitSize();
3570 auto bvSize2 = src.getBitSize();
3571
3572 /* Create symbolic operands */
3573 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3574 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3575
3576 /* Create the semantics */
3577 triton::ast::SharedAbstractNode node = nullptr;
3578 switch (src.getSize()) {
3579 case triton::size::byte:
3580 node = this->astCtxt->ite(
3581 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSR only if op2 != 0 */
3582 op1,
3583 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
3584 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
3585 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
3586 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
3587 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
3588 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
3589 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
3590 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
3591 this->astCtxt->bv(0, bvSize1)
3592 ))))))))
3593 );
3594 break;
3595 case triton::size::word:
3596 node = this->astCtxt->ite(
3597 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSR only if op2 != 0 */
3598 op1,
3599 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
3600 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
3601 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
3602 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
3603 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
3604 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
3605 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
3606 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
3607 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
3608 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
3609 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
3610 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
3611 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
3612 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
3613 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
3614 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
3615 this->astCtxt->bv(0, bvSize1)
3616 ))))))))))))))))
3617 );
3618 break;
3620 node = this->astCtxt->ite(
3621 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSR only if op2 != 0 */
3622 op1,
3623 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(31, 31, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1),
3624 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(30, 30, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1),
3625 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(29, 29, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1),
3626 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(28, 28, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1),
3627 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(27, 27, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1),
3628 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(26, 26, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1),
3629 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(25, 25, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1),
3630 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(24, 24, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1),
3631 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(23, 23, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1),
3632 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(22, 22, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1),
3633 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(21, 21, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1),
3634 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(20, 20, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1),
3635 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(19, 19, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1),
3636 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(18, 18, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1),
3637 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(17, 17, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1),
3638 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(16, 16, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1),
3639 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
3640 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
3641 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
3642 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
3643 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
3644 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
3645 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
3646 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
3647 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
3648 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
3649 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
3650 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
3651 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
3652 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
3653 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
3654 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
3655 this->astCtxt->bv(0, bvSize1)
3656 ))))))))))))))))))))))))))))))))
3657 );
3658 break;
3660 node = this->astCtxt->ite(
3661 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSR only if op2 != 0 */
3662 op1,
3663 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(63, 63, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(63, bvSize1),
3664 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(62, 62, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(62, bvSize1),
3665 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(61, 61, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(61, bvSize1),
3666 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(60, 60, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(60, bvSize1),
3667 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(59, 59, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(59, bvSize1),
3668 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(58, 58, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(58, bvSize1),
3669 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(57, 57, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(57, bvSize1),
3670 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(56, 56, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(56, bvSize1),
3671 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(55, 55, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(55, bvSize1),
3672 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(54, 54, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(54, bvSize1),
3673 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(53, 53, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(53, bvSize1),
3674 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(52, 52, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(52, bvSize1),
3675 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(51, 51, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(51, bvSize1),
3676 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(50, 50, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(50, bvSize1),
3677 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(49, 49, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(49, bvSize1),
3678 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(48, 48, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(48, bvSize1),
3679 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(47, 47, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(47, bvSize1),
3680 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(46, 46, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(46, bvSize1),
3681 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(45, 45, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(45, bvSize1),
3682 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(44, 44, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(44, bvSize1),
3683 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(43, 43, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(43, bvSize1),
3684 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(42, 42, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(42, bvSize1),
3685 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(41, 41, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(41, bvSize1),
3686 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(40, 40, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(40, bvSize1),
3687 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(39, 39, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(39, bvSize1),
3688 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(38, 38, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(38, bvSize1),
3689 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(37, 37, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(37, bvSize1),
3690 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(36, 36, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(36, bvSize1),
3691 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(35, 35, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(35, bvSize1),
3692 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(34, 34, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(34, bvSize1),
3693 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(33, 33, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(33, bvSize1),
3694 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(32, 32, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(32, bvSize1),
3695 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(31, 31, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1),
3696 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(30, 30, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1),
3697 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(29, 29, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1),
3698 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(28, 28, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1),
3699 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(27, 27, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1),
3700 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(26, 26, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1),
3701 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(25, 25, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1),
3702 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(24, 24, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1),
3703 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(23, 23, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1),
3704 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(22, 22, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1),
3705 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(21, 21, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1),
3706 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(20, 20, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1),
3707 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(19, 19, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1),
3708 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(18, 18, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1),
3709 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(17, 17, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1),
3710 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(16, 16, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1),
3711 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
3712 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
3713 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
3714 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
3715 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
3716 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
3717 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
3718 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
3719 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
3720 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
3721 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
3722 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
3723 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
3724 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
3725 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
3726 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
3727 this->astCtxt->bv(0, bvSize1)
3728 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
3729 );
3730 break;
3731 default:
3732 throw triton::exceptions::Semantics("x86Semantics::bsr_s(): Invalid operand size.");
3733 }
3734
3735 /* Create symbolic expression */
3736 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "BSR operation");
3737
3738 /* Spread taint */
3739 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
3740
3741 /* Update symbolic flags */
3742 this->zfBsf_s(inst, expr, src, op2); /* same as bsf */
3743
3744 /* Tag undefined flags */
3745 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
3746 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
3747 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
3748 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
3749 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
3750
3751 /* Update the symbolic control flow */
3752 this->controlFlow_s(inst);
3753 }
3754
3755
3756 void x86Semantics::bswap_s(triton::arch::Instruction& inst) {
3757 auto& src = inst.operands[0];
3758
3759 /* Create symbolic operands */
3760 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
3761
3762 /* Create the semantics */
3763 std::list<triton::ast::SharedAbstractNode> bytes;
3764 switch (src.getSize()) {
3766 bytes.push_front(this->astCtxt->extract(63, 56, op1));
3767 bytes.push_front(this->astCtxt->extract(55, 48, op1));
3768 bytes.push_front(this->astCtxt->extract(47, 40, op1));
3769 bytes.push_front(this->astCtxt->extract(39, 32, op1));
3771 bytes.push_front(this->astCtxt->extract(31, 24, op1));
3772 bytes.push_front(this->astCtxt->extract(23, 16, op1));
3773 bytes.push_front(this->astCtxt->extract(15, 8, op1));
3774 bytes.push_front(this->astCtxt->extract(7, 0, op1));
3775 break;
3776 case triton::size::word:
3777 // See #1131
3778 bytes.push_front(this->astCtxt->bv(0, 8));
3779 bytes.push_front(this->astCtxt->bv(0, 8));
3780 break;
3781 default:
3782 throw triton::exceptions::Semantics("x86Semantics::bswap_s(): Invalid operand size.");
3783 }
3784
3785 auto node = this->astCtxt->concat(bytes);
3786
3787 /* Create symbolic expression */
3788 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, src, "BSWAP operation");
3789
3790 /* Spread taint */
3791 expr->isTainted = this->taintEngine->taintAssignment(src, src);
3792
3793 /* Tag undefined registers */
3794 if (src.getSize() == triton::size::word) {
3795 // When the BSWAP instruction references a 16-bit register, the result is undefined.
3796 this->undefined_s(inst, src.getRegister());
3797 }
3798
3799 /* Update the symbolic control flow */
3800 this->controlFlow_s(inst);
3801 }
3802
3803
3804 void x86Semantics::bt_s(triton::arch::Instruction& inst) {
3805 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
3806 auto& src1 = inst.operands[0];
3807 auto& src2 = inst.operands[1];
3808
3809 /* Create symbolic operands */
3810 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
3811 auto op2 = this->astCtxt->zx(src1.getBitSize() - src2.getBitSize(), this->symbolicEngine->getOperandAst(inst, src2));
3812
3813 /* Create the semantics */
3814 auto node = this->astCtxt->extract(0, 0,
3815 this->astCtxt->bvlshr(
3816 op1,
3817 this->astCtxt->bvsmod(
3818 op2,
3819 this->astCtxt->bv(src1.getBitSize(), src1.getBitSize())
3820 )
3821 )
3822 );
3823
3824 /* Create symbolic expression */
3825 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "BT operation");
3826
3827 /* Spread taint */
3828 expr->isTainted = this->taintEngine->taintUnion(dst, src1);
3829 expr->isTainted = this->taintEngine->taintUnion(dst, src2);
3830
3831 /* Tag undefined flags */
3832 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
3833 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
3834 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
3835 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
3836
3837 /* Update the symbolic control flow */
3838 this->controlFlow_s(inst);
3839 }
3840
3841
3842 void x86Semantics::btc_s(triton::arch::Instruction& inst) {
3843 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
3844 auto& dst2 = inst.operands[0];
3845 auto& src1 = inst.operands[1];
3846
3847 /* Create symbolic operands */
3848 auto op1 = this->symbolicEngine->getOperandAst(inst, dst2);
3849 auto op2 = this->astCtxt->zx(dst2.getBitSize() - src1.getBitSize(), this->symbolicEngine->getOperandAst(inst, src1));
3850
3851 /* Create the semantics */
3852 auto node1 = this->astCtxt->extract(0, 0,
3853 this->astCtxt->bvlshr(
3854 op1,
3855 this->astCtxt->bvsmod(
3856 op2,
3857 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize())
3858 )
3859 )
3860 );
3861 auto node2 = this->astCtxt->ite(
3862 this->astCtxt->equal(node1, this->astCtxt->bvfalse()),
3863 /* BTS */
3864 this->astCtxt->bvor(
3865 op1,
3866 this->astCtxt->bvshl(
3867 this->astCtxt->bv(1, dst2.getBitSize()),
3868 this->astCtxt->bvsmod(
3869 op2,
3870 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize())
3871 )
3872 )
3873 ),
3874 /* BTR */
3875 this->astCtxt->bvand(
3876 op1,
3877 this->astCtxt->bvsub(
3878 op1,
3879 this->astCtxt->bvshl(
3880 this->astCtxt->bv(1, dst2.getBitSize()),
3881 this->astCtxt->bvsmod(
3882 op2,
3883 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize())
3884 )
3885 )
3886 )
3887 )
3888 );
3889
3890 /* Create symbolic expression */
3891 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, this->architecture->getRegister(ID_REG_X86_CF), "BTC carry operation");
3892 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "BTC complement operation");
3893
3894 /* Spread taint */
3895 expr1->isTainted = this->taintEngine->taintUnion(dst1, dst2);
3896 expr1->isTainted = this->taintEngine->taintUnion(dst1, src1);
3897 expr2->isTainted = this->taintEngine->taintUnion(dst2, src1);
3898
3899 /* Tag undefined flags */
3900 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
3901 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
3902 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
3903 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
3904
3905 /* Update the symbolic control flow */
3906 this->controlFlow_s(inst);
3907 }
3908
3909
3910 void x86Semantics::btr_s(triton::arch::Instruction& inst) {
3911 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
3912 auto& dst2 = inst.operands[0];
3913 auto& src1 = inst.operands[1];
3914
3915 /* Create symbolic operands */
3916 auto op1 = this->symbolicEngine->getOperandAst(inst, dst2);
3917 auto op2 = this->astCtxt->zx(dst2.getBitSize() - src1.getBitSize(), this->symbolicEngine->getOperandAst(inst, src1));
3918
3919 /* Create the semantics */
3920 auto node1 = this->astCtxt->extract(0, 0,
3921 this->astCtxt->bvlshr(
3922 op1,
3923 this->astCtxt->bvsmod(
3924 op2,
3925 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize())
3926 )
3927 )
3928 );
3929 auto node2 = this->astCtxt->ite(
3930 this->astCtxt->equal(node1, this->astCtxt->bvfalse()),
3931 op1,
3932 this->astCtxt->bvand(
3933 op1,
3934 this->astCtxt->bvsub(
3935 op1,
3936 this->astCtxt->bvshl(
3937 this->astCtxt->bv(1, dst2.getBitSize()),
3938 this->astCtxt->bvsmod(
3939 op2,
3940 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize())
3941 )
3942 )
3943 )
3944 )
3945 );
3946
3947 /* Create symbolic expression */
3948 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, this->architecture->getRegister(ID_REG_X86_CF), "BTR carry operation");
3949 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "BTR reset operation");
3950
3951 /* Spread taint */
3952 expr1->isTainted = this->taintEngine->taintUnion(dst1, dst2);
3953 expr1->isTainted = this->taintEngine->taintUnion(dst1, src1);
3954 expr2->isTainted = this->taintEngine->taintUnion(dst2, src1);
3955
3956 /* Tag undefined flags */
3957 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
3958 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
3959 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
3960 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
3961
3962 /* Update the symbolic control flow */
3963 this->controlFlow_s(inst);
3964 }
3965
3966
3967 void x86Semantics::bts_s(triton::arch::Instruction& inst) {
3968 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
3969 auto& dst2 = inst.operands[0];
3970 auto& src1 = inst.operands[1];
3971
3972 /* Create symbolic operands */
3973 auto op1 = this->symbolicEngine->getOperandAst(inst, dst2);
3974 auto op2 = this->astCtxt->zx(dst2.getBitSize() - src1.getBitSize(), this->symbolicEngine->getOperandAst(inst, src1));
3975
3976 /* Create the semantics */
3977 auto node1 = this->astCtxt->extract(0, 0,
3978 this->astCtxt->bvlshr(
3979 op1,
3980 this->astCtxt->bvsmod(
3981 op2,
3982 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize())
3983 )
3984 )
3985 );
3986 auto node2 = this->astCtxt->bvor(
3987 op1,
3988 this->astCtxt->bvshl(
3989 this->astCtxt->bv(1, dst2.getBitSize()),
3990 this->astCtxt->bvsmod(
3991 op2,
3992 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize())
3993 )
3994 )
3995 );
3996
3997 /* Create symbolic expression */
3998 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, this->architecture->getRegister(ID_REG_X86_CF), "BTS carry operation");
3999 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "BTS set operation");
4000
4001 /* Spread taint */
4002 expr1->isTainted = this->taintEngine->taintUnion(dst1, dst2);
4003 expr1->isTainted = this->taintEngine->taintUnion(dst1, src1);
4004 expr2->isTainted = this->taintEngine->taintUnion(dst2, src1);
4005
4006 /* Tag undefined flags */
4007 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
4008 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
4009 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
4010 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
4011
4012 /* Update the symbolic control flow */
4013 this->controlFlow_s(inst);
4014 }
4015
4016
4017 void x86Semantics::call_s(triton::arch::Instruction& inst) {
4018 auto& src = inst.operands[0];
4019
4020 /* Create symbolic operands */
4021 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
4022
4023 /* Create the semantics - side effect */
4024 auto stack = this->architecture->getStackPointer();
4025 auto stackValue = alignSubStack_s(inst, stack.getSize());
4026 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
4027 auto sp = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize()));
4028
4029 auto node1 = this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize());
4030
4031 /* Create the semantics */
4032 auto node2 = op1;
4033
4034 /* Create the symbolic expression */
4035 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, sp, "Saved Program Counter");
4036
4037 /* Create symbolic expression */
4038 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, pc, "Program Counter");
4039
4040 /* Spread taint */
4041 expr1->isTainted = this->taintEngine->untaintMemory(sp.getMemory());
4042 expr2->isTainted = this->taintEngine->taintAssignment(pc, src);
4043
4044 /* Create the path constraint */
4045 this->symbolicEngine->pushPathConstraint(inst, expr2);
4046 }
4047
4048
4049 void x86Semantics::cbw_s(triton::arch::Instruction& inst) {
4050 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
4051
4052 /* Create symbolic operands */
4053 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4054
4055 /* Create the semantics */
4056 auto node = this->astCtxt->sx(triton::bitsize::byte, this->astCtxt->extract(triton::bitsize::byte-1, 0, op1));
4057
4058 /* Create symbolic expression */
4059 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CBW operation");
4060
4061 /* Spread taint */
4062 expr->isTainted = this->taintEngine->taintAssignment(dst, dst);
4063
4064 /* Update the symbolic control flow */
4065 this->controlFlow_s(inst);
4066 }
4067
4068
4069 void x86Semantics::cdq_s(triton::arch::Instruction& inst) {
4070 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
4071 auto src = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
4072
4073 /* Create symbolic operands */
4074 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
4075
4076 /* Create the semantics - TMP = 64 bitvec (EDX:EAX) */
4077 auto node1 = this->astCtxt->sx(triton::bitsize::dword, op1);
4078
4079 /* Create symbolic expression */
4080 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "Temporary variable");
4081
4082 /* Spread taint */
4083 expr1->isTainted = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_EAX));
4084
4085 /* Create the semantics - EDX = TMP[63...32] */
4086 auto node2 = this->astCtxt->extract(triton::bitsize::qword-1, triton::bitsize::dword, this->astCtxt->reference(expr1));
4087
4088 /* Create symbolic expression */
4089 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "CDQ operation");
4090
4091 /* Spread taint */
4092 expr2->isTainted = this->taintEngine->taintAssignment(dst, src);
4093
4094 /* Update the symbolic control flow */
4095 this->controlFlow_s(inst);
4096 }
4097
4098
4099 void x86Semantics::cdqe_s(triton::arch::Instruction& inst) {
4100 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX));
4101
4102 /* Create symbolic operands */
4103 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4104
4105 /* Create the semantics */
4106 auto node = this->astCtxt->sx(triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::dword-1, 0, op1));
4107
4108 /* Create symbolic expression */
4109 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CDQE operation");
4110
4111 /* Spread taint */
4112 expr->isTainted = this->taintEngine->taintAssignment(dst, dst);
4113
4114 /* Update the symbolic control flow */
4115 this->controlFlow_s(inst);
4116 }
4117
4118
4119 void x86Semantics::clc_s(triton::arch::Instruction& inst) {
4120 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag");
4121 /* Update the symbolic control flow */
4122 this->controlFlow_s(inst);
4123 }
4124
4125
4126 void x86Semantics::cld_s(triton::arch::Instruction& inst) {
4127 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_DF), "Clears direction flag");
4128 /* Update the symbolic control flow */
4129 this->controlFlow_s(inst);
4130 }
4131
4132
4133 void x86Semantics::clflush_s(triton::arch::Instruction& inst) {
4134 /* Update the symbolic control flow */
4135 this->controlFlow_s(inst);
4136 }
4137
4138
4139 void x86Semantics::clts_s(triton::arch::Instruction& inst) {
4140 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CR0));
4141
4142 /* Create symbolic operands */
4143 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4144
4145 /* Create the semantics */
4146 triton::ast::SharedAbstractNode node = nullptr;
4147
4148 switch (dst.getBitSize()) {
4150 node = this->astCtxt->bvand(op1, this->astCtxt->bv(0xfffffffffffffff7, triton::bitsize::qword));
4151 break;
4153 node = this->astCtxt->bvand(op1, this->astCtxt->bv(0xfffffff7, triton::bitsize::dword));
4154 break;
4155 default:
4156 throw triton::exceptions::Semantics("x86Semantics::clts_s(): Invalid operand size.");
4157 }
4158
4159 /* Create symbolic expression */
4160 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CLTS operation");
4161
4162 /* Spread taint */
4163 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4164
4165 /* Update the symbolic control flow */
4166 this->controlFlow_s(inst);
4167 }
4168
4169
4170 void x86Semantics::cli_s(triton::arch::Instruction& inst) {
4171 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_IF), "Clears interrupt flag");
4172 /* Update the symbolic control flow */
4173 this->controlFlow_s(inst);
4174 }
4175
4176
4177 void x86Semantics::cmc_s(triton::arch::Instruction& inst) {
4178 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
4179
4180 /* Create symbolic operands */
4181 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4182
4183 /* Create the semantics */
4184 auto node = this->astCtxt->bvnot(op1);
4185
4186 /* Create symbolic expression */
4187 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst.getRegister(), "CMC operation");
4188
4189 /* Spread taint */
4190 expr->isTainted = this->taintEngine->taintAssignment(dst, dst);
4191
4192 /* Update the symbolic control flow */
4193 this->controlFlow_s(inst);
4194 }
4195
4196
4197 void x86Semantics::cmova_s(triton::arch::Instruction& inst) {
4198 auto& dst = inst.operands[0];
4199 auto& src = inst.operands[1];
4200 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
4201 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
4202
4203 /* Create symbolic operands */
4204 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4205 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4206 auto op3 = this->symbolicEngine->getOperandAst(inst, cf);
4207 auto op4 = this->symbolicEngine->getOperandAst(inst, zf);
4208
4209 /* Create the semantics */
4210 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvand(this->astCtxt->bvnot(op3), this->astCtxt->bvnot(op4)), this->astCtxt->bvtrue()), op2, op1);
4211
4212 /* Create symbolic expression */
4213 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVA operation");
4214
4215 /* Spread taint and condition flag */
4216 if (op3->evaluate().is_zero() && op4->evaluate().is_zero()) {
4217 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4218 inst.setConditionTaken(true);
4219 }
4220 else {
4221 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4222 }
4223
4224 expr->isTainted |= this->taintEngine->isTainted(cf) || this->taintEngine->isTainted(zf);
4225
4226 /* Update the symbolic control flow */
4227 this->controlFlow_s(inst);
4228 }
4229
4230
4231 void x86Semantics::cmovae_s(triton::arch::Instruction& inst) {
4232 auto& dst = inst.operands[0];
4233 auto& src = inst.operands[1];
4234 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
4235
4236 /* Create symbolic operands */
4237 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4238 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4239 auto op3 = this->symbolicEngine->getOperandAst(inst, cf);
4240
4241 /* Create the semantics */
4242 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvfalse()), op2, op1);
4243
4244 /* Create symbolic expression */
4245 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVAE operation");
4246
4247 /* Spread taint and condition flag */
4248 if (op3->evaluate().is_zero()) {
4249 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4250 inst.setConditionTaken(true);
4251 }
4252 else {
4253 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4254 }
4255
4256 expr->isTainted |= this->taintEngine->isTainted(cf);
4257
4258 /* Update the symbolic control flow */
4259 this->controlFlow_s(inst);
4260 }
4261
4262
4263 void x86Semantics::cmovb_s(triton::arch::Instruction& inst) {
4264 auto& dst = inst.operands[0];
4265 auto& src = inst.operands[1];
4266 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
4267
4268 /* Create symbolic operands */
4269 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4270 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4271 auto op3 = this->symbolicEngine->getOperandAst(inst, cf);
4272
4273 /* Create the semantics */
4274 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvtrue()), op2, op1);
4275
4276 /* Create symbolic expression */
4277 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVB operation");
4278
4279 /* Spread taint and condition flag */
4280 if (!op3->evaluate().is_zero()) {
4281 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4282 inst.setConditionTaken(true);
4283 }
4284 else {
4285 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4286 }
4287
4288 expr->isTainted |= this->taintEngine->isTainted(cf);
4289
4290 /* Update the symbolic control flow */
4291 this->controlFlow_s(inst);
4292 }
4293
4294
4295 void x86Semantics::cmovbe_s(triton::arch::Instruction& inst) {
4296 auto& dst = inst.operands[0];
4297 auto& src = inst.operands[1];
4298 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
4299 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
4300
4301 /* Create symbolic operands */
4302 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4303 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4304 auto op3 = this->symbolicEngine->getOperandAst(inst, cf);
4305 auto op4 = this->symbolicEngine->getOperandAst(inst, zf);
4306
4307 /* Create the semantics */
4308 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvor(op3, op4), this->astCtxt->bvtrue()), op2, op1);
4309
4310 /* Create symbolic expression */
4311 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVBE operation");
4312
4313 /* Spread taint and condition flag */
4314 if (!op3->evaluate().is_zero() || !op4->evaluate().is_zero()) {
4315 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4316 inst.setConditionTaken(true);
4317 }
4318 else {
4319 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4320 }
4321
4322 expr->isTainted |= this->taintEngine->isTainted(cf) || this->taintEngine->isTainted(zf);
4323
4324 /* Update the symbolic control flow */
4325 this->controlFlow_s(inst);
4326 }
4327
4328
4329 void x86Semantics::cmove_s(triton::arch::Instruction& inst) {
4330 auto& dst = inst.operands[0];
4331 auto& src = inst.operands[1];
4332 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
4333
4334 /* Create symbolic operands */
4335 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4336 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4337 auto op3 = this->symbolicEngine->getOperandAst(inst, zf);
4338
4339 /* Create the semantics */
4340 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvtrue()), op2, op1);
4341
4342 /* Create symbolic expression */
4343 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVE operation");
4344
4345 /* Spread taint and condition flag */
4346 if (!op3->evaluate().is_zero()) {
4347 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4348 inst.setConditionTaken(true);
4349 }
4350 else {
4351 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4352 }
4353
4354 expr->isTainted |= this->taintEngine->isTainted(zf);
4355
4356 /* Update the symbolic control flow */
4357 this->controlFlow_s(inst);
4358 }
4359
4360
4361 void x86Semantics::cmovg_s(triton::arch::Instruction& inst) {
4362 auto& dst = inst.operands[0];
4363 auto& src = inst.operands[1];
4364 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
4365 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
4366 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
4367
4368 /* Create symbolic operands */
4369 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4370 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4371 auto op3 = this->symbolicEngine->getOperandAst(inst, sf);
4372 auto op4 = this->symbolicEngine->getOperandAst(inst, of);
4373 auto op5 = this->symbolicEngine->getOperandAst(inst, zf);
4374
4375 /* Create the semantics */
4376 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvor(this->astCtxt->bvxor(op3, op4), op5), this->astCtxt->bvfalse()), op2, op1);
4377
4378 /* Create symbolic expression */
4379 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVG operation");
4380
4381 /* Spread taint and condition flag */
4382 if ((op3->evaluate().is_zero() == op4->evaluate().is_zero()) && op5->evaluate().is_zero()) {
4383 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4384 inst.setConditionTaken(true);
4385 }
4386 else {
4387 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4388 }
4389
4390 expr->isTainted |= this->taintEngine->isTainted(sf) || this->taintEngine->isTainted(of) || this->taintEngine->isTainted(zf);
4391
4392 /* Update the symbolic control flow */
4393 this->controlFlow_s(inst);
4394 }
4395
4396
4397 void x86Semantics::cmovge_s(triton::arch::Instruction& inst) {
4398 auto& dst = inst.operands[0];
4399 auto& src = inst.operands[1];
4400 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
4401 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
4402
4403 /* Create symbolic operands */
4404 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4405 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4406 auto op3 = this->symbolicEngine->getOperandAst(inst, sf);
4407 auto op4 = this->symbolicEngine->getOperandAst(inst, of);
4408
4409 /* Create the semantics */
4410 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, op4), op2, op1);
4411
4412 /* Create symbolic expression */
4413 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVGE operation");
4414
4415 /* Spread taint and condition flag */
4416 if (op3->evaluate().is_zero() == op4->evaluate().is_zero()) {
4417 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4418 inst.setConditionTaken(true);
4419 }
4420 else {
4421 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4422 }
4423
4424 expr->isTainted |= this->taintEngine->isTainted(sf) || this->taintEngine->isTainted(of);
4425
4426 /* Update the symbolic control flow */
4427 this->controlFlow_s(inst);
4428 }
4429
4430
4431 void x86Semantics::cmovl_s(triton::arch::Instruction& inst) {
4432 auto& dst = inst.operands[0];
4433 auto& src = inst.operands[1];
4434 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
4435 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
4436
4437 /* Create symbolic operands */
4438 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4439 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4440 auto op3 = this->symbolicEngine->getOperandAst(inst, sf);
4441 auto op4 = this->symbolicEngine->getOperandAst(inst, of);
4442
4443 /* Create the semantics */
4444 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvxor(op3, op4), this->astCtxt->bvtrue()), op2, op1);
4445
4446 /* Create symbolic expression */
4447 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVL operation");
4448
4449 /* Spread taint and condition flag */
4450 if (op3->evaluate().is_zero() != op4->evaluate().is_zero()) {
4451 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4452 inst.setConditionTaken(true);
4453 }
4454 else {
4455 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4456 }
4457
4458 expr->isTainted |= this->taintEngine->isTainted(sf) || this->taintEngine->isTainted(of);
4459
4460
4461 /* Update the symbolic control flow */
4462 this->controlFlow_s(inst);
4463 }
4464
4465
4466 void x86Semantics::cmovle_s(triton::arch::Instruction& inst) {
4467 auto& dst = inst.operands[0];
4468 auto& src = inst.operands[1];
4469 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
4470 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
4471 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
4472
4473 /* Create symbolic operands */
4474 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4475 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4476 auto op3 = this->symbolicEngine->getOperandAst(inst, sf);
4477 auto op4 = this->symbolicEngine->getOperandAst(inst, of);
4478 auto op5 = this->symbolicEngine->getOperandAst(inst, zf);
4479
4480 /* Create the semantics */
4481 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvor(this->astCtxt->bvxor(op3, op4), op5), this->astCtxt->bvtrue()), op2, op1);
4482
4483 /* Create symbolic expression */
4484 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVBE operation");
4485
4486 /* Spread taint and condition flag */
4487 if ((op3->evaluate().is_zero() != op4->evaluate().is_zero()) || !op5->evaluate().is_zero()) {
4488 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4489 inst.setConditionTaken(true);
4490 }
4491 else {
4492 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4493 }
4494
4495 expr->isTainted |= this->taintEngine->isTainted(sf) || this->taintEngine->isTainted(of) || this->taintEngine->isTainted(zf);
4496
4497 /* Update the symbolic control flow */
4498 this->controlFlow_s(inst);
4499 }
4500
4501
4502 void x86Semantics::cmovne_s(triton::arch::Instruction& inst) {
4503 auto& dst = inst.operands[0];
4504 auto& src = inst.operands[1];
4505 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
4506
4507 /* Create symbolic operands */
4508 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4509 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4510 auto op3 = this->symbolicEngine->getOperandAst(inst, zf);
4511
4512 /* Create the semantics */
4513 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvfalse()), op2, op1);
4514
4515 /* Create symbolic expression */
4516 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVNE operation");
4517
4518 /* Spread taint and condition flag */
4519 if (op3->evaluate().is_zero()) {
4520 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4521 inst.setConditionTaken(true);
4522 }
4523 else {
4524 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4525 }
4526
4527 expr->isTainted |= this->taintEngine->isTainted(zf);
4528
4529 /* Update the symbolic control flow */
4530 this->controlFlow_s(inst);
4531 }
4532
4533
4534 void x86Semantics::cmovno_s(triton::arch::Instruction& inst) {
4535 auto& dst = inst.operands[0];
4536 auto& src = inst.operands[1];
4537 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
4538
4539 /* Create symbolic operands */
4540 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4541 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4542 auto op3 = this->symbolicEngine->getOperandAst(inst, of);
4543
4544 /* Create the semantics */
4545 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvfalse()), op2, op1);
4546
4547 /* Create symbolic expression */
4548 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVNO operation");
4549
4550 /* Spread taint and condition flag */
4551 if (op3->evaluate().is_zero()) {
4552 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4553 inst.setConditionTaken(true);
4554 }
4555 else {
4556 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4557 }
4558
4559 expr->isTainted |= this->taintEngine->isTainted(of);
4560
4561 /* Update the symbolic control flow */
4562 this->controlFlow_s(inst);
4563 }
4564
4565
4566 void x86Semantics::cmovnp_s(triton::arch::Instruction& inst) {
4567 auto& dst = inst.operands[0];
4568 auto& src = inst.operands[1];
4569 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
4570
4571 /* Create symbolic operands */
4572 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4573 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4574 auto op3 = this->symbolicEngine->getOperandAst(inst, pf);
4575
4576 /* Create the semantics */
4577 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvfalse()), op2, op1);
4578
4579 /* Create symbolic expression */
4580 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVNP operation");
4581
4582 /* Spread taint and condition flag */
4583 if (op3->evaluate().is_zero()) {
4584 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4585 inst.setConditionTaken(true);
4586 }
4587 else {
4588 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4589 }
4590
4591 expr->isTainted |= this->taintEngine->isTainted(pf);
4592
4593 /* Update the symbolic control flow */
4594 this->controlFlow_s(inst);
4595 }
4596
4597
4598 void x86Semantics::cmovns_s(triton::arch::Instruction& inst) {
4599 auto& dst = inst.operands[0];
4600 auto& src = inst.operands[1];
4601 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
4602
4603 /* Create symbolic operands */
4604 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4605 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4606 auto op3 = this->symbolicEngine->getOperandAst(inst, sf);
4607
4608 /* Create the semantics */
4609 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvfalse()), op2, op1);
4610
4611 /* Create symbolic expression */
4612 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVNS operation");
4613
4614 /* Spread taint and condition flag */
4615 if (op3->evaluate().is_zero()) {
4616 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4617 inst.setConditionTaken(true);
4618 }
4619 else {
4620 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4621 }
4622
4623 expr->isTainted |= this->taintEngine->isTainted(sf);
4624
4625 /* Update the symbolic control flow */
4626 this->controlFlow_s(inst);
4627 }
4628
4629
4630 void x86Semantics::cmovo_s(triton::arch::Instruction& inst) {
4631 auto& dst = inst.operands[0];
4632 auto& src = inst.operands[1];
4633 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
4634
4635 /* Create symbolic operands */
4636 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4637 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4638 auto op3 = this->symbolicEngine->getOperandAst(inst, of);
4639
4640 /* Create the semantics */
4641 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvtrue()), op2, op1);
4642
4643 /* Create symbolic expression */
4644 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVO operation");
4645
4646 /* Spread taint and condition flag */
4647 if (!op3->evaluate().is_zero()) {
4648 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4649 inst.setConditionTaken(true);
4650 }
4651 else {
4652 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4653 }
4654
4655 expr->isTainted |= this->taintEngine->isTainted(of);
4656
4657 /* Update the symbolic control flow */
4658 this->controlFlow_s(inst);
4659 }
4660
4661
4662 void x86Semantics::cmovp_s(triton::arch::Instruction& inst) {
4663 auto& dst = inst.operands[0];
4664 auto& src = inst.operands[1];
4665 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
4666
4667 /* Create symbolic operands */
4668 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4669 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4670 auto op3 = this->symbolicEngine->getOperandAst(inst, pf);
4671
4672 /* Create the semantics */
4673 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvtrue()), op2, op1);
4674
4675 /* Create symbolic expression */
4676 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVP operation");
4677
4678 /* Spread taint and condition flag */
4679 if (!op3->evaluate().is_zero()) {
4680 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4681 inst.setConditionTaken(true);
4682 }
4683 else {
4684 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4685 }
4686
4687 expr->isTainted |= this->taintEngine->isTainted(pf);
4688
4689 /* Update the symbolic control flow */
4690 this->controlFlow_s(inst);
4691 }
4692
4693
4694 void x86Semantics::cmovs_s(triton::arch::Instruction& inst) {
4695 auto& dst = inst.operands[0];
4696 auto& src = inst.operands[1];
4697 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
4698
4699 /* Create symbolic operands */
4700 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4701 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4702 auto op3 = this->symbolicEngine->getOperandAst(inst, sf);
4703
4704 /* Create the semantics */
4705 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvtrue()), op2, op1);
4706
4707 /* Create symbolic expression */
4708 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVS operation");
4709
4710 /* Spread taint and condition flag */
4711 if (!op3->evaluate().is_zero()) {
4712 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4713 inst.setConditionTaken(true);
4714 }
4715 else {
4716 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4717 }
4718
4719 expr->isTainted |= this->taintEngine->isTainted(sf);
4720
4721 /* Update the symbolic control flow */
4722 this->controlFlow_s(inst);
4723 }
4724
4725
4726 void x86Semantics::cmp_s(triton::arch::Instruction& inst) {
4727 auto& dst = inst.operands[0];
4728 auto& src = inst.operands[1];
4729
4730 /* Create symbolic operands */
4731 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4732 auto op2 = this->astCtxt->sx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
4733
4734 /* Create the semantics */
4735 auto node = this->astCtxt->bvsub(op1, op2);
4736
4737 /* Create symbolic expression */
4738 auto expr = this->symbolicEngine->createSymbolicVolatileExpression(inst, node, "CMP operation");
4739
4740 /* Spread taint */
4741 expr->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
4742
4743 /* Update symbolic flags */
4744 this->af_s(inst, expr, dst, op1, op2, true);
4745 this->cfSub_s(inst, expr, dst, op1, op2, true);
4746 this->ofSub_s(inst, expr, dst, op1, op2, true);
4747 this->pf_s(inst, expr, dst, true);
4748 this->sf_s(inst, expr, dst, true);
4749 this->zf_s(inst, expr, dst, true);
4750
4751 /* Update the symbolic control flow */
4752 this->controlFlow_s(inst);
4753 }
4754
4755
4756 void x86Semantics::cmpsb_s(triton::arch::Instruction& inst) {
4757 auto& dst = inst.operands[0];
4758 auto& src = inst.operands[1];
4759 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
4760 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
4761 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
4762 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
4763
4764 /* If the REP prefix is defined, convert REP into REPE */
4767
4768 /* Check if there is a REP prefix and a counter to zero */
4769 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
4770 this->controlFlow_s(inst);
4771 return;
4772 }
4773
4774 /* Create symbolic operands */
4775 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4776 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4777 auto op3 = this->symbolicEngine->getOperandAst(inst, index1);
4778 auto op4 = this->symbolicEngine->getOperandAst(inst, index2);
4779 auto op5 = this->symbolicEngine->getOperandAst(inst, df);
4780
4781 /* Create the semantics */
4782 auto node1 = this->astCtxt->bvsub(op1, op2);
4783 auto node2 = this->astCtxt->ite(
4784 this->astCtxt->equal(op5, this->astCtxt->bvfalse()),
4785 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::byte, index1.getBitSize())),
4786 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::byte, index1.getBitSize()))
4787 );
4788 auto node3 = this->astCtxt->ite(
4789 this->astCtxt->equal(op5, this->astCtxt->bvfalse()),
4790 this->astCtxt->bvadd(op4, this->astCtxt->bv(triton::size::byte, index2.getBitSize())),
4791 this->astCtxt->bvsub(op4, this->astCtxt->bv(triton::size::byte, index2.getBitSize()))
4792 );
4793
4794 /* Create symbolic expression */
4795 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMPSB operation");
4796 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (SI) operation");
4797 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (DI) operation");
4798
4799 /* Spread taint */
4800 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
4801 expr2->isTainted = this->taintEngine->taintUnion(index1, index1);
4802 expr3->isTainted = this->taintEngine->taintUnion(index2, index2);
4803
4804 /* Update symbolic flags */
4805 this->af_s(inst, expr1, dst, op1, op2, true);
4806 this->cfSub_s(inst, expr1, dst, op1, op2, true);
4807 this->ofSub_s(inst, expr1, dst, op1, op2, true);
4808 this->pf_s(inst, expr1, dst, true);
4809 this->sf_s(inst, expr1, dst, true);
4810 this->zf_s(inst, expr1, dst, true);
4811
4812 /* Update the symbolic control flow */
4813 this->controlFlow_s(inst);
4814 }
4815
4816
4817 void x86Semantics::cmpsd_s(triton::arch::Instruction& inst) {
4818 auto& dst = inst.operands[0];
4819 auto& src = inst.operands[1];
4820 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
4821 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
4822 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
4823 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
4824
4825 /* If the REP prefix is defined, convert REP into REPE */
4828
4829 /* Check if there is a REP prefix and a counter to zero */
4830 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
4831 this->controlFlow_s(inst);
4832 return;
4833 }
4834
4835 /* Create symbolic operands */
4836 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4837 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4838 auto op3 = this->symbolicEngine->getOperandAst(inst, index1);
4839 auto op4 = this->symbolicEngine->getOperandAst(inst, index2);
4840 auto op5 = this->symbolicEngine->getOperandAst(inst, df);
4841
4842 /* Create the semantics */
4843 auto node1 = this->astCtxt->bvsub(op1, op2);
4844 auto node2 = this->astCtxt->ite(
4845 this->astCtxt->equal(op5, this->astCtxt->bvfalse()),
4846 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::dword, index1.getBitSize())),
4847 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::dword, index1.getBitSize()))
4848 );
4849 auto node3 = this->astCtxt->ite(
4850 this->astCtxt->equal(op5, this->astCtxt->bvfalse()),
4851 this->astCtxt->bvadd(op4, this->astCtxt->bv(triton::size::dword, index2.getBitSize())),
4852 this->astCtxt->bvsub(op4, this->astCtxt->bv(triton::size::dword, index2.getBitSize()))
4853 );
4854
4855 /* Create symbolic expression */
4856 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMPSD operation");
4857 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (SI) operation");
4858 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (DI) operation");
4859
4860 /* Spread taint */
4861 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
4862 expr2->isTainted = this->taintEngine->taintUnion(index1, index1);
4863 expr3->isTainted = this->taintEngine->taintUnion(index2, index2);
4864
4865 /* Update symbolic flags */
4866 this->af_s(inst, expr1, dst, op1, op2, true);
4867 this->cfSub_s(inst, expr1, dst, op1, op2, true);
4868 this->ofSub_s(inst, expr1, dst, op1, op2, true);
4869 this->pf_s(inst, expr1, dst, true);
4870 this->sf_s(inst, expr1, dst, true);
4871 this->zf_s(inst, expr1, dst, true);
4872
4873 /* Update the symbolic control flow */
4874 this->controlFlow_s(inst);
4875 }
4876
4877
4878 void x86Semantics::cmpsq_s(triton::arch::Instruction& inst) {
4879 auto& dst = inst.operands[0];
4880 auto& src = inst.operands[1];
4881 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
4882 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
4883 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
4884 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
4885
4886 /* If the REP prefix is defined, convert REP into REPE */
4889
4890 /* Check if there is a REP prefix and a counter to zero */
4891 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
4892 this->controlFlow_s(inst);
4893 return;
4894 }
4895
4896 /* Create symbolic operands */
4897 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4898 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4899 auto op3 = this->symbolicEngine->getOperandAst(inst, index1);
4900 auto op4 = this->symbolicEngine->getOperandAst(inst, index2);
4901 auto op5 = this->symbolicEngine->getOperandAst(inst, df);
4902
4903 /* Create the semantics */
4904 auto node1 = this->astCtxt->bvsub(op1, op2);
4905 auto node2 = this->astCtxt->ite(
4906 this->astCtxt->equal(op5, this->astCtxt->bvfalse()),
4907 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::qword, index1.getBitSize())),
4908 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::qword, index1.getBitSize()))
4909 );
4910 auto node3 = this->astCtxt->ite(
4911 this->astCtxt->equal(op5, this->astCtxt->bvfalse()),
4912 this->astCtxt->bvadd(op4, this->astCtxt->bv(triton::size::qword, index2.getBitSize())),
4913 this->astCtxt->bvsub(op4, this->astCtxt->bv(triton::size::qword, index2.getBitSize()))
4914 );
4915
4916 /* Create symbolic expression */
4917 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMPSQ operation");
4918 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (SI) operation");
4919 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (DI) operation");
4920
4921 /* Spread taint */
4922 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
4923 expr2->isTainted = this->taintEngine->taintUnion(index1, index1);
4924 expr3->isTainted = this->taintEngine->taintUnion(index2, index2);
4925
4926 /* Update symbolic flags */
4927 this->af_s(inst, expr1, dst, op1, op2, true);
4928 this->cfSub_s(inst, expr1, dst, op1, op2, true);
4929 this->ofSub_s(inst, expr1, dst, op1, op2, true);
4930 this->pf_s(inst, expr1, dst, true);
4931 this->sf_s(inst, expr1, dst, true);
4932 this->zf_s(inst, expr1, dst, true);
4933
4934 /* Update the symbolic control flow */
4935 this->controlFlow_s(inst);
4936 }
4937
4938
4939 void x86Semantics::cmpsw_s(triton::arch::Instruction& inst) {
4940 auto& dst = inst.operands[0];
4941 auto& src = inst.operands[1];
4942 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
4943 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
4944 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
4945 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
4946
4947 /* If the REP prefix is defined, convert REP into REPE */
4950
4951 /* Check if there is a REP prefix and a counter to zero */
4952 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
4953 this->controlFlow_s(inst);
4954 return;
4955 }
4956
4957 /* Create symbolic operands */
4958 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4959 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4960 auto op3 = this->symbolicEngine->getOperandAst(inst, index1);
4961 auto op4 = this->symbolicEngine->getOperandAst(inst, index2);
4962 auto op5 = this->symbolicEngine->getOperandAst(inst, df);
4963
4964 /* Create the semantics */
4965 auto node1 = this->astCtxt->bvsub(op1, op2);
4966 auto node2 = this->astCtxt->ite(
4967 this->astCtxt->equal(op5, this->astCtxt->bvfalse()),
4968 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::word, index1.getBitSize())),
4969 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::word, index1.getBitSize()))
4970 );
4971 auto node3 = this->astCtxt->ite(
4972 this->astCtxt->equal(op5, this->astCtxt->bvfalse()),
4973 this->astCtxt->bvadd(op4, this->astCtxt->bv(triton::size::word, index2.getBitSize())),
4974 this->astCtxt->bvsub(op4, this->astCtxt->bv(triton::size::word, index2.getBitSize()))
4975 );
4976
4977 /* Create symbolic expression */
4978 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMPSW operation");
4979 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (SI) operation");
4980 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (DI) operation");
4981
4982 /* Spread taint */
4983 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
4984 expr2->isTainted = this->taintEngine->taintUnion(index1, index1);
4985 expr3->isTainted = this->taintEngine->taintUnion(index2, index2);
4986
4987 /* Update symbolic flags */
4988 this->af_s(inst, expr1, dst, op1, op2, true);
4989 this->cfSub_s(inst, expr1, dst, op1, op2, true);
4990 this->ofSub_s(inst, expr1, dst, op1, op2, true);
4991 this->pf_s(inst, expr1, dst, true);
4992 this->sf_s(inst, expr1, dst, true);
4993 this->zf_s(inst, expr1, dst, true);
4994
4995 /* Update the symbolic control flow */
4996 this->controlFlow_s(inst);
4997 }
4998
4999
5000 void x86Semantics::cmpxchg_s(triton::arch::Instruction& inst) {
5001 auto& src1 = inst.operands[0];
5002 auto& src2 = inst.operands[1];
5003
5004 /* Create the tempory accumulator */
5005 triton::arch::OperandWrapper accumulator(this->architecture->getRegister(ID_REG_X86_AL));
5006 triton::arch::OperandWrapper accumulatorp(this->architecture->getParentRegister(ID_REG_X86_AL));
5007
5008 switch (src1.getSize()) {
5009 case triton::size::word:
5010 accumulator.setRegister(arch::Register(this->architecture->getRegister(ID_REG_X86_AX)));
5011 break;
5013 accumulator.setRegister(arch::Register(this->architecture->getRegister(ID_REG_X86_EAX)));
5014 break;
5016 accumulator.setRegister(arch::Register(this->architecture->getRegister(ID_REG_X86_RAX)));
5017 break;
5018 }
5019
5020 /* Create symbolic operands */
5021 auto op1 = this->symbolicEngine->getOperandAst(inst, accumulator);
5022 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
5023 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
5024 auto op1p = this->symbolicEngine->getOperandAst(accumulatorp);
5025 auto op2p = this->symbolicEngine->getRegisterAst((src1.getType() == triton::arch::OP_REG ? Register(this->architecture->getParentRegister(src1.getRegister())) : accumulatorp.getRegister()));
5026 auto op3p = this->symbolicEngine->getRegisterAst((src1.getType() == triton::arch::OP_REG ? Register(this->architecture->getParentRegister(src2.getRegister())) : accumulatorp.getRegister()));
5027
5028 /* Create the semantics */
5029 auto nodeq = this->astCtxt->equal(op1, op2);
5030 auto node1 = this->astCtxt->bvsub(op1, op2);
5031 auto node2 = this->astCtxt->ite(nodeq, op3, op2);
5032 auto node3 = this->astCtxt->ite(nodeq, op1, op2);
5033 auto node2p = this->astCtxt->ite(nodeq, op3p, op2p);
5034 auto node3p = this->astCtxt->ite(nodeq, op1p, op2p);
5035
5036 /* Create symbolic expression */
5037 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMP operation");
5038 auto expr2 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node2, "Temporary operation");
5039 auto expr3 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node2p, "Temporary operation");
5040 auto expr4 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node3, "Temporary operation");
5041 auto expr5 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node3p, "Temporary operation");
5042
5045
5046 /* Destination */
5047 if (nodeq->evaluate() == false && src1.getType() == triton::arch::OP_REG) {
5048 const auto& src1p = this->architecture->getParentRegister(src1.getRegister());
5049 expr6 = this->symbolicEngine->createSymbolicRegisterExpression(inst, node2p, src1p, "XCHG operation");
5050 } else
5051 expr6 = this->symbolicEngine->createSymbolicExpression(inst, node2, src1, "XCHG operation");
5052
5053 /* Accumulator */
5054 if (nodeq->evaluate() == true)
5055 expr7 = this->symbolicEngine->createSymbolicExpression(inst, node3p, accumulatorp, "XCHG operation");
5056 else
5057 expr7 = this->symbolicEngine->createSymbolicExpression(inst, node3, accumulator, "XCHG operation");
5058
5059 /* Spread taint */
5060 expr1->isTainted = this->taintEngine->isTainted(accumulator) | this->taintEngine->isTainted(src1);
5061 expr2->isTainted = expr1->isTainted;
5062 expr3->isTainted = expr1->isTainted;
5063 expr4->isTainted = expr1->isTainted;
5064 expr5->isTainted = expr1->isTainted;
5065 expr6->isTainted = this->taintEngine->taintAssignment(src1, src2);
5066 expr7->isTainted = this->taintEngine->taintAssignment(accumulator, src1);
5067
5068 /* Update symbolic flags */
5069 this->af_s(inst, expr1, accumulator, op1, op2, true);
5070 this->cfSub_s(inst, expr1, accumulator, op1, op2, true);
5071 this->ofSub_s(inst, expr1, accumulator, op1, op2, true);
5072 this->pf_s(inst, expr1, accumulator, true);
5073 this->sf_s(inst, expr1, accumulator, true);
5074 this->zf_s(inst, expr1, accumulator, true);
5075
5076 /* Update the symbolic control flow */
5077 this->controlFlow_s(inst);
5078 }
5079
5080
5081 void x86Semantics::cmpxchg16b_s(triton::arch::Instruction& inst) {
5082 auto& src1 = inst.operands[0];
5083 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX));
5084 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX));
5085 auto src4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RCX));
5086 auto src5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RBX));
5087
5088 /* Create symbolic operands */
5089 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
5090 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
5091 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
5092 auto op4 = this->symbolicEngine->getOperandAst(inst, src4);
5093 auto op5 = this->symbolicEngine->getOperandAst(inst, src5);
5094
5095 /* Create the semantics */
5096 /* CMP8B */
5097 auto node1 = this->astCtxt->bvsub(this->astCtxt->concat(op2, op3), op1);
5098 /* Destination */
5099 auto node2 = this->astCtxt->ite(this->astCtxt->equal(node1, this->astCtxt->bv(0, triton::bitsize::dqword)), this->astCtxt->concat(op4, op5), op1);
5100 /* EDX:EAX */
5101 auto node3 = this->astCtxt->ite(this->astCtxt->equal(node1, this->astCtxt->bv(0, triton::bitsize::dqword)), this->astCtxt->concat(op2, op3), op1);
5102
5103 /* Create symbolic expression */
5104 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMP operation");
5105 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, src1, "XCHG16B memory operation");
5106 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(127, 64, node3), src2, "XCHG16B RDX operation");
5107 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(63, 0, node3), src3, "XCHG16B RAX operation");
5108
5109 /* Spread taint */
5110 expr1->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(src3);
5111 expr2->isTainted = this->taintEngine->setTaint(src1, this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(src3));
5112 expr3->isTainted = this->taintEngine->taintAssignment(src2, src1);
5113 expr4->isTainted = this->taintEngine->taintAssignment(src3, src1);
5114
5115 /* Update symbolic flags */
5116 this->zf_s(inst, expr1, src1, true);
5117
5118 /* Update the symbolic control flow */
5119 this->controlFlow_s(inst);
5120 }
5121
5122
5123 void x86Semantics::cmpxchg8b_s(triton::arch::Instruction& inst) {
5124 auto& src1 = inst.operands[0];
5125 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
5126 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
5127 auto src4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ECX));
5128 auto src5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EBX));
5129 auto src2p = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_EDX));
5130 auto src3p = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_EAX));
5131
5132 /* Create symbolic operands */
5133 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
5134 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
5135 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
5136 auto op4 = this->symbolicEngine->getOperandAst(inst, src4);
5137 auto op5 = this->symbolicEngine->getOperandAst(inst, src5);
5138 auto op2p = this->symbolicEngine->getOperandAst(inst, src2p);
5139 auto op3p = this->symbolicEngine->getOperandAst(inst, src3p);
5140
5141 /* Create the semantics */
5142 /* CMP8B */
5143 auto node1 = this->astCtxt->bvsub(this->astCtxt->concat(op2, op3), op1);
5144 /* Destination */
5145 auto node2 = this->astCtxt->ite(this->astCtxt->equal(node1, this->astCtxt->bv(0, triton::bitsize::qword)), this->astCtxt->concat(op4, op5), op1);
5146 /* EDX:EAX */
5147 auto node3 = this->astCtxt->ite(this->astCtxt->equal(node1, this->astCtxt->bv(0, triton::bitsize::qword)), this->astCtxt->concat(op2, op3), op1);
5148 auto node3p = this->astCtxt->ite(
5149 this->astCtxt->equal(
5150 node1,
5151 this->astCtxt->bv(0, triton::bitsize::qword)),
5152 this->astCtxt->concat(op2p, op3p),
5153 this->astCtxt->zx(src2p.getBitSize() + src3p.getBitSize() - src1.getBitSize(), op1)
5154 );
5155
5156 /* Create symbolic expression */
5157 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMP operation");
5158 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, src1, "XCHG8B memory operation");
5159 auto expr3 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node3, "Temporary operation");
5160 auto expr4 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node3p, "Temporary operation");
5161
5164
5165 /* EDX */
5166 if (node1->evaluate() == 0)
5167 expr5 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract((src2p.getBitSize() * 2 - 1), src2p.getBitSize(), node3p), src2p, "XCHG8B EDX operation");
5168 else
5169 expr5 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(63, 32, node3), src2, "XCHG8B EDX operation");
5170
5171 /* EAX */
5172 if (node1->evaluate() == 0)
5173 expr6 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(src2p.getBitSize() - 1, 0, node3p), src3p, "XCHG8B EAX operation");
5174 else
5175 expr6 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(31, 0, node3), src3, "XCHG8B EAX operation");
5176
5177 /* Spread taint */
5178 expr1->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(src3);
5179 expr2->isTainted = this->taintEngine->setTaint(src1, this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(src3));
5180 expr3->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(src3);
5181 expr4->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(src3);
5182 expr5->isTainted = this->taintEngine->taintAssignment(src2, src1);
5183 expr6->isTainted = this->taintEngine->taintAssignment(src3, src1);
5184
5185 /* Update symbolic flags */
5186 this->zf_s(inst, expr1, src1, true);
5187
5188 /* Update the symbolic control flow */
5189 this->controlFlow_s(inst);
5190 }
5191
5192
5193 void x86Semantics::cpuid_s(triton::arch::Instruction& inst) {
5194 auto src = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_AX));
5195 auto dst1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_AX));
5196 auto dst2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_BX));
5197 auto dst3 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
5198 auto dst4 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DX));
5199
5200 /* Create symbolic operands */
5201 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
5202
5203 /* Create the semantics */
5204 triton::ast::SharedAbstractNode node1 = nullptr;
5205 triton::ast::SharedAbstractNode node2 = nullptr;
5206 triton::ast::SharedAbstractNode node3 = nullptr;
5207 triton::ast::SharedAbstractNode node4 = nullptr;
5208
5209 /* In this case, we concretize the AX option */
5210 switch (static_cast<triton::uint32>(op1->evaluate())) {
5211 case 0:
5212 node1 = this->astCtxt->bv(0x0000000d, dst1.getBitSize());
5213 node2 = this->astCtxt->bv(0x756e6547, dst2.getBitSize());
5214 node3 = this->astCtxt->bv(0x6c65746e, dst3.getBitSize());
5215 node4 = this->astCtxt->bv(0x49656e69, dst4.getBitSize());
5216 break;
5217 case 1:
5218 node1 = this->astCtxt->bv(0x000306a9, dst1.getBitSize());
5219 node2 = this->astCtxt->bv(0x02100800, dst2.getBitSize());
5220 node3 = this->astCtxt->bv(0x7fbae3ff, dst3.getBitSize());
5221 node4 = this->astCtxt->bv(0xbfebfbff, dst4.getBitSize());
5222 break;
5223 case 2:
5224 node1 = this->astCtxt->bv(0x76035a01, dst1.getBitSize());
5225 node2 = this->astCtxt->bv(0x00f0b2ff, dst2.getBitSize());
5226 node3 = this->astCtxt->bv(0x00000000, dst3.getBitSize());
5227 node4 = this->astCtxt->bv(0x00ca0000, dst4.getBitSize());
5228 break;
5229 case 3:
5230 node1 = this->astCtxt->bv(0x00000000, dst1.getBitSize());
5231 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize());
5232 node3 = this->astCtxt->bv(0x00000000, dst3.getBitSize());
5233 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize());
5234 break;
5235 case 4:
5236 node1 = this->astCtxt->bv(0x1c004121, dst1.getBitSize());
5237 node2 = this->astCtxt->bv(0x01c0003f, dst2.getBitSize());
5238 node3 = this->astCtxt->bv(0x0000003f, dst3.getBitSize());
5239 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize());
5240 break;
5241 case 5:
5242 node1 = this->astCtxt->bv(0x00000040, dst1.getBitSize());
5243 node2 = this->astCtxt->bv(0x00000040, dst2.getBitSize());
5244 node3 = this->astCtxt->bv(0x00000003, dst3.getBitSize());
5245 node4 = this->astCtxt->bv(0x00021120, dst4.getBitSize());
5246 break;
5247 case 0x80000000:
5248 node1 = this->astCtxt->bv(0x80000008, dst1.getBitSize());
5249 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize());
5250 node3 = this->astCtxt->bv(0x00000000, dst3.getBitSize());
5251 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize());
5252 break;
5253 case 0x80000001:
5254 node1 = this->astCtxt->bv(0x00000000, dst1.getBitSize());
5255 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize());
5256 node3 = this->astCtxt->bv(0x00000001, dst3.getBitSize());
5257 node4 = this->astCtxt->bv(0x28100800, dst4.getBitSize());
5258 break;
5259 case 0x80000002:
5260 node1 = this->astCtxt->bv(0x20202020, dst1.getBitSize());
5261 node2 = this->astCtxt->bv(0x49202020, dst2.getBitSize());
5262 node3 = this->astCtxt->bv(0x6c65746e, dst3.getBitSize());
5263 node4 = this->astCtxt->bv(0x20295228, dst4.getBitSize());
5264 break;
5265 case 0x80000003:
5266 node1 = this->astCtxt->bv(0x65726f43, dst1.getBitSize());
5267 node2 = this->astCtxt->bv(0x294d5428, dst2.getBitSize());
5268 node3 = this->astCtxt->bv(0x2d376920, dst3.getBitSize());
5269 node4 = this->astCtxt->bv(0x30323533, dst4.getBitSize());
5270 break;
5271 case 0x80000004:
5272 node1 = this->astCtxt->bv(0x5043204d, dst1.getBitSize());
5273 node2 = this->astCtxt->bv(0x20402055, dst2.getBitSize());
5274 node3 = this->astCtxt->bv(0x30392e32, dst3.getBitSize());
5275 node4 = this->astCtxt->bv(0x007a4847, dst4.getBitSize());
5276 break;
5277 case 0x80000005:
5278 node1 = this->astCtxt->bv(0x00000000, dst1.getBitSize());
5279 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize());
5280 node3 = this->astCtxt->bv(0x00000000, dst3.getBitSize());
5281 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize());
5282 break;
5283 case 0x80000006:
5284 node1 = this->astCtxt->bv(0x00000000, dst1.getBitSize());
5285 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize());
5286 node3 = this->astCtxt->bv(0x01006040, dst3.getBitSize());
5287 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize());
5288 break;
5289 case 0x80000007:
5290 node1 = this->astCtxt->bv(0x00000000, dst1.getBitSize());
5291 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize());
5292 node3 = this->astCtxt->bv(0x00000000, dst3.getBitSize());
5293 node4 = this->astCtxt->bv(0x00000100, dst4.getBitSize());
5294 break;
5295 case 0x80000008:
5296 node1 = this->astCtxt->bv(0x00003024, dst1.getBitSize());
5297 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize());
5298 node3 = this->astCtxt->bv(0x00000000, dst3.getBitSize());
5299 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize());
5300 break;
5301 default:
5302 node1 = this->astCtxt->bv(0x00000007, dst1.getBitSize());
5303 node2 = this->astCtxt->bv(0x00000340, dst2.getBitSize());
5304 node3 = this->astCtxt->bv(0x00000340, dst3.getBitSize());
5305 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize());
5306 break;
5307 }
5308
5309 /* Create symbolic expression */
5310 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1, "CPUID AX operation");
5311 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "CPUID BX operation");
5312 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3, "CPUID CX operation");
5313 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4, "CPUID DX operation");
5314
5315 /* Spread taint */
5316 expr1->isTainted = this->taintEngine->setTaintRegister(this->architecture->getParentRegister(ID_REG_X86_AX), false);
5317 expr2->isTainted = this->taintEngine->setTaintRegister(this->architecture->getParentRegister(ID_REG_X86_BX), false);
5318 expr3->isTainted = this->taintEngine->setTaintRegister(this->architecture->getParentRegister(ID_REG_X86_CX), false);
5319 expr4->isTainted = this->taintEngine->setTaintRegister(this->architecture->getParentRegister(ID_REG_X86_DX), false);
5320
5321 /* Update the symbolic control flow */
5322 this->controlFlow_s(inst);
5323 }
5324
5325
5326 void x86Semantics::cqo_s(triton::arch::Instruction& inst) {
5327 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX));
5328 auto src = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX));
5329
5330 /* Create symbolic operands */
5331 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
5332
5333 /* Create the semantics - TMP = 128 bitvec (RDX:RAX) */
5334 auto node1 = this->astCtxt->sx(triton::bitsize::qword, op1);
5335
5336 /* Create symbolic expression */
5337 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "Temporary variable");
5338
5339 /* Spread taint */
5340 expr1->isTainted = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_RAX));
5341
5342 /* Create the semantics - RDX = TMP[127...64] */
5343 auto node2 = this->astCtxt->extract(triton::bitsize::dqword-1, triton::bitsize::qword, this->astCtxt->reference(expr1));
5344
5345 /* Create symbolic expression */
5346 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "CQO operation");
5347
5348 /* Spread taint */
5349 expr2->isTainted = this->taintEngine->taintAssignment(dst, src);
5350
5351 /* Update the symbolic control flow */
5352 this->controlFlow_s(inst);
5353 }
5354
5355
5356 void x86Semantics::cwd_s(triton::arch::Instruction& inst) {
5357 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DX));
5358 auto src = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
5359
5360 /* Create symbolic operands */
5361 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
5362
5363 /* Create the semantics - TMP = 32 bitvec (DX:AX) */
5364 auto node1 = this->astCtxt->sx(triton::bitsize::word, op1);
5365
5366 /* Create symbolic expression */
5367 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "Temporary variable");
5368
5369 /* Spread taint */
5370 expr1->isTainted = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_AX));
5371
5372 /* Create the semantics - DX = TMP[31...16] */
5373 auto node2 = this->astCtxt->extract(triton::bitsize::dword-1, triton::bitsize::word, this->astCtxt->reference(expr1));
5374
5375 /* Create symbolic expression */
5376 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "CWD operation");
5377
5378 /* Spread taint */
5379 expr2->isTainted = this->taintEngine->taintAssignment(dst, src);
5380
5381 /* Update the symbolic control flow */
5382 this->controlFlow_s(inst);
5383 }
5384
5385
5386 void x86Semantics::cwde_s(triton::arch::Instruction& inst) {
5387 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
5388
5389 /* Create symbolic operands */
5390 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
5391
5392 /* Create the semantics */
5393 auto node = this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(triton::bitsize::word-1, 0, op1));
5394
5395 /* Create symbolic expression */
5396 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CWDE operation");
5397
5398 /* Spread taint */
5399 expr->isTainted = this->taintEngine->taintAssignment(dst, dst);
5400
5401 /* Update the symbolic control flow */
5402 this->controlFlow_s(inst);
5403 }
5404
5405
5406 void x86Semantics::dec_s(triton::arch::Instruction& inst) {
5407 auto& dst = inst.operands[0];
5408
5409 /* Create symbolic operands */
5410 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
5411 auto op2 = this->astCtxt->bv(1, dst.getBitSize());
5412
5413 /* Create the semantics */
5414 auto node = this->astCtxt->bvsub(op1, op2);
5415
5416 /* Create symbolic expression */
5417 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "DEC operation");
5418
5419 /* Spread taint */
5420 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
5421
5422 /* Update symbolic flags */
5423 this->af_s(inst, expr, dst, op1, op2);
5424 this->ofSub_s(inst, expr, dst, op1, op2);
5425 this->pf_s(inst, expr, dst);
5426 this->sf_s(inst, expr, dst);
5427 this->zf_s(inst, expr, dst);
5428
5429 /* Update the symbolic control flow */
5430 this->controlFlow_s(inst);
5431 }
5432
5433
5434 void x86Semantics::div_s(triton::arch::Instruction& inst) {
5435 auto& src = inst.operands[0];
5436
5437 /* Create symbolic operands */
5438 auto divisor = this->symbolicEngine->getOperandAst(inst, src);
5439
5440 /* Create symbolic expression */
5441 switch (src.getSize()) {
5442
5443 case triton::size::byte: {
5444 /* AX */
5445 auto ax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
5446 auto dividend = this->symbolicEngine->getOperandAst(inst, ax);
5447 /* res = AX / Source */
5448 auto result = this->astCtxt->bvudiv(dividend, this->astCtxt->zx(triton::bitsize::byte, divisor));
5449 /* mod = AX % Source */
5450 auto mod = this->astCtxt->bvurem(dividend, this->astCtxt->zx(triton::bitsize::byte, divisor));
5451 /* AH = mod */
5452 /* AL = res */
5453 auto node = this->astCtxt->concat(
5454 this->astCtxt->extract((triton::bitsize::byte - 1), 0, mod), /* AH = mod */
5455 this->astCtxt->extract((triton::bitsize::byte - 1), 0, result) /* AL = res */
5456 );
5457 /* Create symbolic expression */
5458 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, ax, "DIV operation");
5459 /* Apply the taint */
5460 expr->isTainted = this->taintEngine->taintUnion(ax, src);
5461 /* Divide error */
5462 if (result->evaluate() > 0xff) {
5463 this->exception = triton::arch::FAULT_DE;
5464 return;
5465 }
5466 break;
5467 }
5468
5469 case triton::size::word: {
5470 /* DX:AX */
5471 auto dx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DX));
5472 auto ax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
5473 auto dividend = this->astCtxt->concat(this->symbolicEngine->getOperandAst(inst, dx), this->symbolicEngine->getOperandAst(inst, ax));
5474 /* res = DX:AX / Source */
5475 auto temp = this->astCtxt->bvudiv(dividend, this->astCtxt->zx(triton::bitsize::word, divisor));
5476 auto result = this->astCtxt->extract((triton::bitsize::word - 1), 0, temp);
5477 /* mod = DX:AX % Source */
5478 auto mod = this->astCtxt->extract((triton::bitsize::word - 1), 0, this->astCtxt->bvurem(dividend, this->astCtxt->zx(triton::bitsize::word, divisor)));
5479 /* Create the symbolic expression for AX */
5480 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, result, ax, "DIV operation");
5481 /* Apply the taint for AX */
5482 expr1->isTainted = this->taintEngine->taintUnion(ax, src);
5483 /* Create the symbolic expression for DX */
5484 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, mod, dx, "DIV operation");
5485 /* Apply the taint for DX */
5486 expr2->isTainted = this->taintEngine->taintUnion(dx, src);
5487 /* Divide error */
5488 if (temp->evaluate() > 0xffff) {
5489 this->exception = triton::arch::FAULT_DE;
5490 return;
5491 }
5492 break;
5493 }
5494
5495 case triton::size::dword: {
5496 /* EDX:EAX */
5497 auto edx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
5498 auto eax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
5499 auto dividend = this->astCtxt->concat(this->symbolicEngine->getOperandAst(inst, edx), this->symbolicEngine->getOperandAst(inst, eax));
5500 /* res = EDX:EAX / Source */
5501 auto temp = this->astCtxt->bvudiv(dividend, this->astCtxt->zx(triton::bitsize::dword, divisor));
5502 auto result = this->astCtxt->extract((triton::bitsize::dword - 1), 0, temp);
5503 /* mod = EDX:EAX % Source */
5504 auto mod = this->astCtxt->extract((triton::bitsize::dword - 1), 0, this->astCtxt->bvurem(dividend, this->astCtxt->zx(triton::bitsize::dword, divisor)));
5505 /* Create the symbolic expression for EAX */
5506 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, result, eax, "DIV operation");
5507 /* Apply the taint for EAX */
5508 expr1->isTainted = this->taintEngine->taintUnion(eax, src);
5509 /* Create the symbolic expression for EDX */
5510 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, mod, edx, "DIV operation");
5511 /* Apply the taint for EDX */
5512 expr2->isTainted = this->taintEngine->taintUnion(edx, src);
5513 /* Divide error */
5514 if (temp->evaluate() > 0xffffffff) {
5515 this->exception = triton::arch::FAULT_DE;
5516 return;
5517 }
5518 break;
5519 }
5520
5521 case triton::size::qword: {
5522 /* RDX:RAX */
5523 auto rdx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX));
5524 auto rax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX));
5525 auto dividend = this->astCtxt->concat(this->symbolicEngine->getOperandAst(inst, rdx), this->symbolicEngine->getOperandAst(inst, rax));
5526 /* res = RDX:RAX / Source */
5527 auto temp = this->astCtxt->bvudiv(dividend, this->astCtxt->zx(triton::bitsize::qword, divisor));
5528 auto result = this->astCtxt->extract((triton::bitsize::qword - 1), 0, temp);
5529 /* mod = RDX:RAX % Source */
5530 auto mod = this->astCtxt->extract((triton::bitsize::qword - 1), 0, this->astCtxt->bvurem(dividend, this->astCtxt->zx(triton::bitsize::qword, divisor)));
5531 /* Create the symbolic expression for RAX */
5532 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, result, rax, "DIV operation");
5533 /* Apply the taint for EAX */
5534 expr1->isTainted = this->taintEngine->taintUnion(rax, src);
5535 /* Create the symbolic expression for RDX */
5536 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, mod, rdx, "DIV operation");
5537 /* Apply the taint for EDX */
5538 expr2->isTainted = this->taintEngine->taintUnion(rdx, src);
5539 /* Divide error */
5540 if (temp->evaluate() > 0xffffffffffffffff) {
5541 this->exception = triton::arch::FAULT_DE;
5542 return;
5543 }
5544 break;
5545 }
5546
5547 }
5548
5549 /* Tag undefined flags */
5550 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
5551 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
5552 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
5553 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
5554 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
5555 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF));
5556
5557 /* Return an exception if the divisor is zero */
5558 if (divisor->evaluate() == 0) {
5559 this->exception = triton::arch::FAULT_DE;
5560 return;
5561 }
5562
5563 /* Update the symbolic control flow */
5564 this->controlFlow_s(inst);
5565 }
5566
5567
5568 void x86Semantics::endbr32_s(triton::arch::Instruction& inst) {
5569 /* Update the symbolic control flow */
5570 this->controlFlow_s(inst);
5571 }
5572
5573
5574 void x86Semantics::endbr64_s(triton::arch::Instruction& inst) {
5575 /* Update the symbolic control flow */
5576 this->controlFlow_s(inst);
5577 }
5578
5579
5580 void x86Semantics::extractps_s(triton::arch::Instruction& inst) {
5581 auto& dst = inst.operands[0];
5582 auto& src1 = inst.operands[1];
5583 auto& src2 = inst.operands[2];
5584
5585 /* Create symbolic operands */
5586 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
5587 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
5588
5589 /* Create the semantics */
5590 auto node = this->astCtxt->extract(triton::bitsize::dword-1, 0,
5591 this->astCtxt->bvlshr(
5592 op2,
5593 this->astCtxt->bvmul(
5594 this->astCtxt->zx(126, this->astCtxt->extract(1, 0, op3)),
5596 )
5597 )
5598 );
5599
5600 switch (dst.getBitSize()) {
5602 break;
5604 node = this->astCtxt->zx(triton::bitsize::dword, node);
5605 break;
5606 default:
5607 throw triton::exceptions::Semantics("x86Semantics::extractps_s(): Invalid destination operand.");
5608 }
5609
5610 /* Create symbolic expression */
5611 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "EXTRACTPS operation");
5612
5613 /* Spread taint */
5614 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
5615
5616 /* Update the symbolic control flow */
5617 this->controlFlow_s(inst);
5618 }
5619
5620
5621 void x86Semantics::fxrstor_s(triton::arch::Instruction& inst) {
5622 /* Fetch the current architecture */
5623 auto arch = this->architecture->getArchitecture();
5624
5625 /* Determine if we are executing in 64 bit mode */
5626 auto is64bits = arch == triton::arch::architecture_e::ARCH_X86_64;
5627
5628 /* Fetch the memory operand */
5629 auto& dst = inst.operands[0];
5630 auto& mem = dst.getMemory();
5631 auto m512byte = mem.getAddress();
5632
5633 /* Check if the address is on a 16-byte boundary */
5634 if (m512byte & 0xF) {
5635 this->exception = triton::arch::FAULT_GP;
5636 return;
5637 }
5638
5639 /* Fetch the FPU, STX, SSE, EFER and CS implicit operands */
5640 auto fcw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FCW));
5641 auto fsw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FSW));
5642 auto ftw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FTW));
5643 auto fop = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FOP));
5644 auto fip = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FIP));
5645 auto fcs = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FCS));
5646 auto fdp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FDP));
5647 auto fds = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FDS));
5648 auto mxcsr = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR));
5649 auto mxcsr_mask = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR_MASK));
5650 auto st0 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST0));
5651 auto st1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST1));
5652 auto st2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST2));
5653 auto st3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST3));
5654 auto st4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST4));
5655 auto st5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST5));
5656 auto st6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST6));
5657 auto st7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST7));
5658 auto xmm0 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM0));
5659 auto xmm1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM1));
5660 auto xmm2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM2));
5661 auto xmm3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM3));
5662 auto xmm4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM4));
5663 auto xmm5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM5));
5664 auto xmm6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM6));
5665 auto xmm7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM7));
5666 auto ffxsr = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EFER_FFXSR));
5667 auto cs = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CS));
5668
5669 /* Fetch the implicit memory slots for the 'Non-64-bit Mode Layout' */
5670 auto fcw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 0, fcw.getSize()));
5671 auto fsw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 2, fsw.getSize()));
5672 auto ftw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 4, ftw.getSize() / 2));
5673 auto fop_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 6, fop.getSize()));
5674 auto fip_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 8, fip.getSize() / 2));
5675 auto fcs_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 12, fcs.getSize()));
5676 auto fdp_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 16, fdp.getSize() / 2));
5677 auto fds_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 20, fds.getSize()));
5678 auto mxcsr_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 24, mxcsr.getSize()));
5679 auto mxcsr_mask_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 28, mxcsr_mask.getSize()));
5680 auto st0_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 32, st0.getSize()));
5681 auto st1_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 48, st1.getSize()));
5682 auto st2_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 64, st2.getSize()));
5683 auto st3_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 80, st3.getSize()));
5684 auto st4_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 96, st4.getSize()));
5685 auto st5_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 112, st5.getSize()));
5686 auto st6_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 128, st6.getSize()));
5687 auto st7_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 144, st7.getSize()));
5688 auto xmm0_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 160, xmm0.getSize()));
5689 auto xmm1_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 176, xmm1.getSize()));
5690 auto xmm2_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 192, xmm2.getSize()));
5691 auto xmm3_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 208, xmm3.getSize()));
5692 auto xmm4_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 224, xmm4.getSize()));
5693 auto xmm5_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 240, xmm5.getSize()));
5694 auto xmm6_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 256, xmm6.getSize()));
5695 auto xmm7_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 272, xmm7.getSize()));
5696
5697 /* Create the symbolic operands */
5698 auto fcw_ast = this->symbolicEngine->getOperandAst(inst, fcw_addr);
5699 auto fsw_ast = this->symbolicEngine->getOperandAst(inst, fsw_addr);
5700 auto ftw_ast = this->symbolicEngine->getOperandAst(inst, ftw_addr);
5701 auto fop_ast = this->symbolicEngine->getOperandAst(inst, fop_addr);
5702 auto fip_ast = this->astCtxt->zx(triton::bitsize::dword, this->symbolicEngine->getOperandAst(inst, fip_addr));
5703 auto fcs_ast = this->symbolicEngine->getOperandAst(inst, fcs_addr);
5704 auto fdp_ast = this->astCtxt->zx(triton::bitsize::dword, this->symbolicEngine->getOperandAst(inst, fdp_addr));
5705 auto fds_ast = this->symbolicEngine->getOperandAst(inst, fds_addr);
5706 auto mxcsr_ast = this->symbolicEngine->getOperandAst(inst, mxcsr_addr);
5707 auto mxcsr_mask_ast = this->symbolicEngine->getOperandAst(inst, mxcsr_mask_addr);
5708 auto st0_ast = this->symbolicEngine->getOperandAst(inst, st0_addr);
5709 auto st1_ast = this->symbolicEngine->getOperandAst(inst, st1_addr);
5710 auto st2_ast = this->symbolicEngine->getOperandAst(inst, st2_addr);
5711 auto st3_ast = this->symbolicEngine->getOperandAst(inst, st3_addr);
5712 auto st4_ast = this->symbolicEngine->getOperandAst(inst, st4_addr);
5713 auto st5_ast = this->symbolicEngine->getOperandAst(inst, st5_addr);
5714 auto st6_ast = this->symbolicEngine->getOperandAst(inst, st6_addr);
5715 auto st7_ast = this->symbolicEngine->getOperandAst(inst, st7_addr);
5716 auto xmm0_ast = this->symbolicEngine->getOperandAst(inst, xmm0_addr);
5717 auto xmm1_ast = this->symbolicEngine->getOperandAst(inst, xmm1_addr);
5718 auto xmm2_ast = this->symbolicEngine->getOperandAst(inst, xmm2_addr);
5719 auto xmm3_ast = this->symbolicEngine->getOperandAst(inst, xmm3_addr);
5720 auto xmm4_ast = this->symbolicEngine->getOperandAst(inst, xmm4_addr);
5721 auto xmm5_ast = this->symbolicEngine->getOperandAst(inst, xmm5_addr);
5722 auto xmm6_ast = this->symbolicEngine->getOperandAst(inst, xmm6_addr);
5723 auto xmm7_ast = this->symbolicEngine->getOperandAst(inst, xmm7_addr);
5724 auto ffxsr_ast = this->symbolicEngine->getOperandAst(inst, ffxsr);
5725 auto cs_ast = this->symbolicEngine->getOperandAst(inst, cs);
5726
5727 /* Fetch the original values for the XMM0-XMM7 registers */
5728 auto xmm0_orig = this->symbolicEngine->getOperandAst(inst, xmm0);
5729 auto xmm1_orig = this->symbolicEngine->getOperandAst(inst, xmm1);
5730 auto xmm2_orig = this->symbolicEngine->getOperandAst(inst, xmm2);
5731 auto xmm3_orig = this->symbolicEngine->getOperandAst(inst, xmm3);
5732 auto xmm4_orig = this->symbolicEngine->getOperandAst(inst, xmm4);
5733 auto xmm5_orig = this->symbolicEngine->getOperandAst(inst, xmm5);
5734 auto xmm6_orig = this->symbolicEngine->getOperandAst(inst, xmm6);
5735 auto xmm7_orig = this->symbolicEngine->getOperandAst(inst, xmm7);
5736
5737 /* Check if we are running in CPL = 0 (ring 0) and if the FFXSR bit is set in EFER */
5738 auto cpl = this->astCtxt->equal(this->astCtxt->extract(1, 0, cs_ast), this->astCtxt->bv(0, 2));
5739 auto ffx = this->astCtxt->equal(ffxsr_ast, this->astCtxt->bv(1, 1));
5740 auto b64 = this->astCtxt->equal(this->astCtxt->bv(is64bits, 1), this->astCtxt->bv(1, 1));
5741 auto is_fast = this->astCtxt->land(this->astCtxt->land(cpl, ffx), b64);
5742
5743 /* Apply the fast restore logic if needed */
5744 xmm0_ast = this->astCtxt->ite(is_fast, xmm0_orig, xmm0_ast);
5745 xmm1_ast = this->astCtxt->ite(is_fast, xmm1_orig, xmm1_ast);
5746 xmm2_ast = this->astCtxt->ite(is_fast, xmm2_orig, xmm2_ast);
5747 xmm3_ast = this->astCtxt->ite(is_fast, xmm3_orig, xmm3_ast);
5748 xmm4_ast = this->astCtxt->ite(is_fast, xmm4_orig, xmm4_ast);
5749 xmm5_ast = this->astCtxt->ite(is_fast, xmm5_orig, xmm5_ast);
5750 xmm6_ast = this->astCtxt->ite(is_fast, xmm6_orig, xmm6_ast);
5751 xmm7_ast = this->astCtxt->ite(is_fast, xmm7_orig, xmm7_ast);
5752
5753 /* Fetch the abridged x87 FPU Tag Word Encoded Bits */
5754 auto eb_1_0 = this->astCtxt->extract(0, 0, ftw_ast);
5755 auto eb_3_2 = this->astCtxt->extract(1, 1, ftw_ast);
5756 auto eb_5_4 = this->astCtxt->extract(2, 2, ftw_ast);
5757 auto eb_7_6 = this->astCtxt->extract(3, 3, ftw_ast);
5758 auto eb_9_8 = this->astCtxt->extract(4, 4, ftw_ast);
5759 auto eb_11_10 = this->astCtxt->extract(5, 5, ftw_ast);
5760 auto eb_13_12 = this->astCtxt->extract(6, 6, ftw_ast);
5761 auto eb_15_14 = this->astCtxt->extract(7, 7, ftw_ast);
5762
5763 /* Extract the fraction from the STX registers */
5764 auto fraction_st0 = this->astCtxt->extract(62, 0, st0_ast);
5765 auto fraction_st1 = this->astCtxt->extract(62, 0, st1_ast);
5766 auto fraction_st2 = this->astCtxt->extract(62, 0, st2_ast);
5767 auto fraction_st3 = this->astCtxt->extract(62, 0, st3_ast);
5768 auto fraction_st4 = this->astCtxt->extract(62, 0, st4_ast);
5769 auto fraction_st5 = this->astCtxt->extract(62, 0, st5_ast);
5770 auto fraction_st6 = this->astCtxt->extract(62, 0, st6_ast);
5771 auto fraction_st7 = this->astCtxt->extract(62, 0, st7_ast);
5772
5773 /* Extract the integer bit from the STX registers */
5774 auto integer_st0 = this->astCtxt->extract(63, 63, st0_ast);
5775 auto integer_st1 = this->astCtxt->extract(63, 63, st1_ast);
5776 auto integer_st2 = this->astCtxt->extract(63, 63, st2_ast);
5777 auto integer_st3 = this->astCtxt->extract(63, 63, st3_ast);
5778 auto integer_st4 = this->astCtxt->extract(63, 63, st4_ast);
5779 auto integer_st5 = this->astCtxt->extract(63, 63, st5_ast);
5780 auto integer_st6 = this->astCtxt->extract(63, 63, st6_ast);
5781 auto integer_st7 = this->astCtxt->extract(63, 63, st7_ast);
5782
5783 /* Extract the exponent from the STX registers */
5784 auto exponent_st0 = this->astCtxt->extract(79, 64, st0_ast);
5785 auto exponent_st1 = this->astCtxt->extract(79, 64, st1_ast);
5786 auto exponent_st2 = this->astCtxt->extract(79, 64, st2_ast);
5787 auto exponent_st3 = this->astCtxt->extract(79, 64, st3_ast);
5788 auto exponent_st4 = this->astCtxt->extract(79, 64, st4_ast);
5789 auto exponent_st5 = this->astCtxt->extract(79, 64, st5_ast);
5790 auto exponent_st6 = this->astCtxt->extract(79, 64, st6_ast);
5791 auto exponent_st7 = this->astCtxt->extract(79, 64, st7_ast);
5792
5793 /* Exponent All Zeros */
5794 auto ea0_st0 = this->astCtxt->equal(exponent_st0, this->astCtxt->bv(0x0000, 16));
5795 auto ea0_st1 = this->astCtxt->equal(exponent_st1, this->astCtxt->bv(0x0000, 16));
5796 auto ea0_st2 = this->astCtxt->equal(exponent_st2, this->astCtxt->bv(0x0000, 16));
5797 auto ea0_st3 = this->astCtxt->equal(exponent_st3, this->astCtxt->bv(0x0000, 16));
5798 auto ea0_st4 = this->astCtxt->equal(exponent_st4, this->astCtxt->bv(0x0000, 16));
5799 auto ea0_st5 = this->astCtxt->equal(exponent_st5, this->astCtxt->bv(0x0000, 16));
5800 auto ea0_st6 = this->astCtxt->equal(exponent_st6, this->astCtxt->bv(0x0000, 16));
5801 auto ea0_st7 = this->astCtxt->equal(exponent_st7, this->astCtxt->bv(0x0000, 16));
5802
5803 /* Exponent All Ones */
5804 auto ea1_st0 = this->astCtxt->equal(exponent_st0, this->astCtxt->bv(0xFFFF, 16));
5805 auto ea1_st1 = this->astCtxt->equal(exponent_st1, this->astCtxt->bv(0xFFFF, 16));
5806 auto ea1_st2 = this->astCtxt->equal(exponent_st2, this->astCtxt->bv(0xFFFF, 16));
5807 auto ea1_st3 = this->astCtxt->equal(exponent_st3, this->astCtxt->bv(0xFFFF, 16));
5808 auto ea1_st4 = this->astCtxt->equal(exponent_st4, this->astCtxt->bv(0xFFFF, 16));
5809 auto ea1_st5 = this->astCtxt->equal(exponent_st5, this->astCtxt->bv(0xFFFF, 16));
5810 auto ea1_st6 = this->astCtxt->equal(exponent_st6, this->astCtxt->bv(0xFFFF, 16));
5811 auto ea1_st7 = this->astCtxt->equal(exponent_st7, this->astCtxt->bv(0xFFFF, 16));
5812
5813 /* Exponent Neither All Zeroes Or Ones */
5814 auto ena01_st0 = this->astCtxt->equal(this->astCtxt->lor(ea0_st0, ea1_st0), this->astCtxt->bvfalse());
5815 auto ena01_st1 = this->astCtxt->equal(this->astCtxt->lor(ea0_st1, ea1_st1), this->astCtxt->bvfalse());
5816 auto ena01_st2 = this->astCtxt->equal(this->astCtxt->lor(ea0_st2, ea1_st2), this->astCtxt->bvfalse());
5817 auto ena01_st3 = this->astCtxt->equal(this->astCtxt->lor(ea0_st3, ea1_st3), this->astCtxt->bvfalse());
5818 auto ena01_st4 = this->astCtxt->equal(this->astCtxt->lor(ea0_st4, ea1_st4), this->astCtxt->bvfalse());
5819 auto ena01_st5 = this->astCtxt->equal(this->astCtxt->lor(ea0_st5, ea1_st5), this->astCtxt->bvfalse());
5820 auto ena01_st6 = this->astCtxt->equal(this->astCtxt->lor(ea0_st6, ea1_st6), this->astCtxt->bvfalse());
5821 auto ena01_st7 = this->astCtxt->equal(this->astCtxt->lor(ea0_st7, ea1_st7), this->astCtxt->bvfalse());
5822
5823 /* Integer Bit 0 */
5824 auto ib0_st0 = this->astCtxt->equal(integer_st0, this->astCtxt->bv(0, 1));
5825 auto ib0_st1 = this->astCtxt->equal(integer_st1, this->astCtxt->bv(0, 1));
5826 auto ib0_st2 = this->astCtxt->equal(integer_st2, this->astCtxt->bv(0, 1));
5827 auto ib0_st3 = this->astCtxt->equal(integer_st3, this->astCtxt->bv(0, 1));
5828 auto ib0_st4 = this->astCtxt->equal(integer_st4, this->astCtxt->bv(0, 1));
5829 auto ib0_st5 = this->astCtxt->equal(integer_st5, this->astCtxt->bv(0, 1));
5830 auto ib0_st6 = this->astCtxt->equal(integer_st6, this->astCtxt->bv(0, 1));
5831 auto ib0_st7 = this->astCtxt->equal(integer_st7, this->astCtxt->bv(0, 1));
5832
5833 /* Fraction All Zeroes */
5834 auto fa0_st0 = this->astCtxt->equal(fraction_st0, this->astCtxt->bv(0, 63));
5835 auto fa0_st1 = this->astCtxt->equal(fraction_st1, this->astCtxt->bv(0, 63));
5836 auto fa0_st2 = this->astCtxt->equal(fraction_st2, this->astCtxt->bv(0, 63));
5837 auto fa0_st3 = this->astCtxt->equal(fraction_st3, this->astCtxt->bv(0, 63));
5838 auto fa0_st4 = this->astCtxt->equal(fraction_st4, this->astCtxt->bv(0, 63));
5839 auto fa0_st5 = this->astCtxt->equal(fraction_st5, this->astCtxt->bv(0, 63));
5840 auto fa0_st6 = this->astCtxt->equal(fraction_st6, this->astCtxt->bv(0, 63));
5841 auto fa0_st7 = this->astCtxt->equal(fraction_st7, this->astCtxt->bv(0, 63));
5842
5843 /* Determine the x87 FPU Tag Word (Diagram at page 379 of the AMD Architecture Programmer's Manual, Volume 2: System Programming) */
5844 auto db_1_0 = this->astCtxt->ite(this->astCtxt->equal(eb_1_0, this->astCtxt->bv(0, 1)),
5845 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
5846 this->astCtxt->ite(ea0_st0,
5847 this->astCtxt->ite(ib0_st0,
5848 this->astCtxt->ite(fa0_st0,
5849 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
5850 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
5851 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
5852 this->astCtxt->ite(ena01_st0,
5853 this->astCtxt->ite(ib0_st0,
5854 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
5855 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
5856 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
5857
5858 auto db_3_2 = this->astCtxt->ite(this->astCtxt->equal(eb_3_2, this->astCtxt->bv(0, 1)),
5859 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
5860 this->astCtxt->ite(ea0_st1,
5861 this->astCtxt->ite(ib0_st1,
5862 this->astCtxt->ite(fa0_st1,
5863 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
5864 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
5865 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
5866 this->astCtxt->ite(ena01_st1,
5867 this->astCtxt->ite(ib0_st1,
5868 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
5869 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
5870 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
5871
5872 auto db_5_4 = this->astCtxt->ite(this->astCtxt->equal(eb_5_4, this->astCtxt->bv(0, 1)),
5873 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
5874 this->astCtxt->ite(ea0_st2,
5875 this->astCtxt->ite(ib0_st2,
5876 this->astCtxt->ite(fa0_st2,
5877 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
5878 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
5879 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
5880 this->astCtxt->ite(ena01_st2,
5881 this->astCtxt->ite(ib0_st2,
5882 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
5883 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
5884 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
5885
5886 auto db_7_6 = this->astCtxt->ite(this->astCtxt->equal(eb_7_6, this->astCtxt->bv(0, 1)),
5887 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
5888 this->astCtxt->ite(ea0_st3,
5889 this->astCtxt->ite(ib0_st3,
5890 this->astCtxt->ite(fa0_st3,
5891 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
5892 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
5893 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
5894 this->astCtxt->ite(ena01_st3,
5895 this->astCtxt->ite(ib0_st3,
5896 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
5897 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
5898 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
5899
5900 auto db_9_8 = this->astCtxt->ite(this->astCtxt->equal(eb_9_8, this->astCtxt->bv(0, 1)),
5901 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
5902 this->astCtxt->ite(ea0_st4,
5903 this->astCtxt->ite(ib0_st4,
5904 this->astCtxt->ite(fa0_st4,
5905 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
5906 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
5907 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
5908 this->astCtxt->ite(ena01_st4,
5909 this->astCtxt->ite(ib0_st4,
5910 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
5911 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
5912 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
5913
5914 auto db_11_10 = this->astCtxt->ite(this->astCtxt->equal(eb_11_10, this->astCtxt->bv(0, 1)),
5915 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
5916 this->astCtxt->ite(ea0_st5,
5917 this->astCtxt->ite(ib0_st5,
5918 this->astCtxt->ite(fa0_st5,
5919 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
5920 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
5921 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
5922 this->astCtxt->ite(ena01_st5,
5923 this->astCtxt->ite(ib0_st5,
5924 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
5925 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
5926 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
5927
5928 auto db_13_12 = this->astCtxt->ite(this->astCtxt->equal(eb_13_12, this->astCtxt->bv(0, 1)),
5929 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
5930 this->astCtxt->ite(ea0_st6,
5931 this->astCtxt->ite(ib0_st6,
5932 this->astCtxt->ite(fa0_st6,
5933 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
5934 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
5935 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
5936 this->astCtxt->ite(ena01_st6,
5937 this->astCtxt->ite(ib0_st6,
5938 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
5939 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
5940 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
5941
5942 auto db_15_14 = this->astCtxt->ite(this->astCtxt->equal(eb_15_14, this->astCtxt->bv(0, 1)),
5943 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
5944 this->astCtxt->ite(ea0_st7,
5945 this->astCtxt->ite(ib0_st7,
5946 this->astCtxt->ite(fa0_st7,
5947 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
5948 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
5949 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
5950 this->astCtxt->ite(ena01_st7,
5951 this->astCtxt->ite(ib0_st7,
5952 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
5953 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
5954 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
5955
5956 /* Restore the x87 FPU Tag Word */
5957 auto uftw_ast = this->astCtxt->concat(db_15_14,
5958 this->astCtxt->concat(db_13_12,
5959 this->astCtxt->concat(db_11_10,
5960 this->astCtxt->concat(db_9_8,
5961 this->astCtxt->concat(db_7_6,
5962 this->astCtxt->concat(db_5_4,
5963 this->astCtxt->concat(db_3_2, db_1_0)))))));
5964
5965 /* Craft the symbolic expressions */
5966 auto fcw_expr = this->symbolicEngine->createSymbolicExpression(inst, fcw_ast, fcw, "FXRSTOR FCW operation");
5967 auto fsw_expr = this->symbolicEngine->createSymbolicExpression(inst, fsw_ast, fsw, "FXRSTOR FSW operation");
5968 auto ftw_expr = this->symbolicEngine->createSymbolicExpression(inst, uftw_ast, ftw, "FXRSTOR Updated FTW operation");
5969 auto fop_expr = this->symbolicEngine->createSymbolicExpression(inst, fop_ast, fop, "FXRSTOR FOP operation");
5970 auto fip_expr = this->symbolicEngine->createSymbolicExpression(inst, fip_ast, fip, "FXRSTOR FIP operation");
5971 auto fcs_expr = this->symbolicEngine->createSymbolicExpression(inst, fcs_ast, fcs, "FXRSTOR FCS operation");
5972 auto fdp_expr = this->symbolicEngine->createSymbolicExpression(inst, fdp_ast, fdp, "FXRSTOR FDP operation");
5973 auto fds_expr = this->symbolicEngine->createSymbolicExpression(inst, fds_ast, fds, "FXRSTOR FDS operation");
5974 auto mxcsr_expr = this->symbolicEngine->createSymbolicExpression(inst, mxcsr_ast, mxcsr, "FXRSTOR MXCSR operation");
5975 auto mxcsr_mask_expr = this->symbolicEngine->createSymbolicExpression(inst, mxcsr_mask_ast, mxcsr_mask, "FXRSTOR MXCSR_MASK operation");
5976 auto st0_expr = this->symbolicEngine->createSymbolicExpression(inst, st0_ast, st0, "FXRSTOR ST0 operation");
5977 auto st1_expr = this->symbolicEngine->createSymbolicExpression(inst, st1_ast, st1, "FXRSTOR ST1 operation");
5978 auto st2_expr = this->symbolicEngine->createSymbolicExpression(inst, st2_ast, st2, "FXRSTOR ST2 operation");
5979 auto st3_expr = this->symbolicEngine->createSymbolicExpression(inst, st3_ast, st3, "FXRSTOR ST3 operation");
5980 auto st4_expr = this->symbolicEngine->createSymbolicExpression(inst, st4_ast, st4, "FXRSTOR ST4 operation");
5981 auto st5_expr = this->symbolicEngine->createSymbolicExpression(inst, st5_ast, st5, "FXRSTOR ST5 operation");
5982 auto st6_expr = this->symbolicEngine->createSymbolicExpression(inst, st6_ast, st6, "FXRSTOR ST6 operation");
5983 auto st7_expr = this->symbolicEngine->createSymbolicExpression(inst, st7_ast, st7, "FXRSTOR ST7 operation");
5984 auto xmm0_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm0_ast, xmm0, "FXRSTOR XMM0 operation");
5985 auto xmm1_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm1_ast, xmm1, "FXRSTOR XMM1 operation");
5986 auto xmm2_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm2_ast, xmm2, "FXRSTOR XMM2 operation");
5987 auto xmm3_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm3_ast, xmm3, "FXRSTOR XMM3 operation");
5988 auto xmm4_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm4_ast, xmm4, "FXRSTOR XMM4 operation");
5989 auto xmm5_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm5_ast, xmm5, "FXRSTOR XMM5 operation");
5990 auto xmm6_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm6_ast, xmm6, "FXRSTOR XMM6 operation");
5991 auto xmm7_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm7_ast, xmm7, "FXRSTOR XMM7 operation");
5992
5993 /* Spread the taint */
5994 fcw_expr->isTainted = this->taintEngine->taintAssignment(fcw, fcw_addr);
5995 fsw_expr->isTainted = this->taintEngine->taintAssignment(fsw, fsw_addr);
5996 ftw_expr->isTainted = this->taintEngine->taintAssignment(ftw, ftw_addr);
5997 fop_expr->isTainted = this->taintEngine->taintAssignment(fop, fop_addr);
5998 fip_expr->isTainted = this->taintEngine->taintAssignment(fip, fip_addr);
5999 fcs_expr->isTainted = this->taintEngine->taintAssignment(fcs, fcs_addr);
6000 fdp_expr->isTainted = this->taintEngine->taintAssignment(fdp, fdp_addr);
6001 fds_expr->isTainted = this->taintEngine->taintAssignment(fds, fds_addr);
6002 mxcsr_expr->isTainted = this->taintEngine->taintAssignment(mxcsr, mxcsr_addr);
6003 mxcsr_mask_expr->isTainted = this->taintEngine->taintAssignment(mxcsr_mask, mxcsr_mask_addr);
6004 st0_expr->isTainted = this->taintEngine->taintAssignment(st0, st0_addr);
6005 st1_expr->isTainted = this->taintEngine->taintAssignment(st1, st1_addr);
6006 st2_expr->isTainted = this->taintEngine->taintAssignment(st2, st2_addr);
6007 st3_expr->isTainted = this->taintEngine->taintAssignment(st3, st3_addr);
6008 st4_expr->isTainted = this->taintEngine->taintAssignment(st4, st4_addr);
6009 st5_expr->isTainted = this->taintEngine->taintAssignment(st5, st5_addr);
6010 st6_expr->isTainted = this->taintEngine->taintAssignment(st6, st6_addr);
6011 st7_expr->isTainted = this->taintEngine->taintAssignment(st7, st7_addr);
6012 xmm0_expr->isTainted = this->taintEngine->taintAssignment(xmm0, xmm0_addr);
6013 xmm1_expr->isTainted = this->taintEngine->taintAssignment(xmm1, xmm1_addr);
6014 xmm2_expr->isTainted = this->taintEngine->taintAssignment(xmm2, xmm2_addr);
6015 xmm3_expr->isTainted = this->taintEngine->taintAssignment(xmm3, xmm3_addr);
6016 xmm4_expr->isTainted = this->taintEngine->taintAssignment(xmm4, xmm4_addr);
6017 xmm5_expr->isTainted = this->taintEngine->taintAssignment(xmm5, xmm5_addr);
6018 xmm6_expr->isTainted = this->taintEngine->taintAssignment(xmm6, xmm6_addr);
6019 xmm7_expr->isTainted = this->taintEngine->taintAssignment(xmm7, xmm7_addr);
6020
6021 /* Additional semantics, symbolic expressions and tainting for the '64-bit Mode Layout (with REX.W = 0)' */
6022 if (is64bits) {
6023 auto xmm8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM8));
6024 auto xmm9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM9));
6025 auto xmm10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM10));
6026 auto xmm11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM11));
6027 auto xmm12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM12));
6028 auto xmm13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM13));
6029 auto xmm14 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM14));
6030 auto xmm15 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM15));
6031
6032 auto xmm8_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 288, xmm8.getSize()));
6033 auto xmm9_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 304, xmm9.getSize()));
6034 auto xmm10_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 320, xmm10.getSize()));
6035 auto xmm11_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 336, xmm11.getSize()));
6036 auto xmm12_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 352, xmm12.getSize()));
6037 auto xmm13_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 368, xmm13.getSize()));
6038 auto xmm14_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 384, xmm14.getSize()));
6039 auto xmm15_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 400, xmm15.getSize()));
6040
6041 auto xmm8_ast = this->symbolicEngine->getOperandAst(inst, xmm8_addr);
6042 auto xmm9_ast = this->symbolicEngine->getOperandAst(inst, xmm9_addr);
6043 auto xmm10_ast = this->symbolicEngine->getOperandAst(inst, xmm10_addr);
6044 auto xmm11_ast = this->symbolicEngine->getOperandAst(inst, xmm11_addr);
6045 auto xmm12_ast = this->symbolicEngine->getOperandAst(inst, xmm12_addr);
6046 auto xmm13_ast = this->symbolicEngine->getOperandAst(inst, xmm13_addr);
6047 auto xmm14_ast = this->symbolicEngine->getOperandAst(inst, xmm14_addr);
6048 auto xmm15_ast = this->symbolicEngine->getOperandAst(inst, xmm15_addr);
6049
6050 /* Fetch the original values for the XMM8-XMM15 registers */
6051 auto xmm8_orig = this->symbolicEngine->getOperandAst(inst, xmm8);
6052 auto xmm9_orig = this->symbolicEngine->getOperandAst(inst, xmm9);
6053 auto xmm10_orig = this->symbolicEngine->getOperandAst(inst, xmm10);
6054 auto xmm11_orig = this->symbolicEngine->getOperandAst(inst, xmm11);
6055 auto xmm12_orig = this->symbolicEngine->getOperandAst(inst, xmm12);
6056 auto xmm13_orig = this->symbolicEngine->getOperandAst(inst, xmm13);
6057 auto xmm14_orig = this->symbolicEngine->getOperandAst(inst, xmm14);
6058 auto xmm15_orig = this->symbolicEngine->getOperandAst(inst, xmm15);
6059
6060 /* Apply the fast restore logic if needed */
6061 xmm8_ast = this->astCtxt->ite(is_fast, xmm8_orig, xmm8_ast);
6062 xmm9_ast = this->astCtxt->ite(is_fast, xmm9_orig, xmm9_ast);
6063 xmm10_ast = this->astCtxt->ite(is_fast, xmm10_orig, xmm10_ast);
6064 xmm11_ast = this->astCtxt->ite(is_fast, xmm11_orig, xmm11_ast);
6065 xmm12_ast = this->astCtxt->ite(is_fast, xmm12_orig, xmm12_ast);
6066 xmm13_ast = this->astCtxt->ite(is_fast, xmm13_orig, xmm13_ast);
6067 xmm14_ast = this->astCtxt->ite(is_fast, xmm14_orig, xmm14_ast);
6068 xmm15_ast = this->astCtxt->ite(is_fast, xmm15_orig, xmm15_ast);
6069
6070 auto xmm8_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm8_ast, xmm8, "FXRSTOR XMM8 operation");
6071 auto xmm9_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm9_ast, xmm9, "FXRSTOR XMM9 operation");
6072 auto xmm10_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm10_ast, xmm10, "FXRSTOR XMM10 operation");
6073 auto xmm11_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm11_ast, xmm11, "FXRSTOR XMM11 operation");
6074 auto xmm12_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm12_ast, xmm12, "FXRSTOR XMM12 operation");
6075 auto xmm13_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm13_ast, xmm13, "FXRSTOR XMM13 operation");
6076 auto xmm14_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm14_ast, xmm14, "FXRSTOR XMM14 operation");
6077 auto xmm15_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm15_ast, xmm15, "FXRSTOR XMM15 operation");
6078
6079 xmm8_expr->isTainted = this->taintEngine->taintAssignment(xmm8, xmm8_addr);
6080 xmm9_expr->isTainted = this->taintEngine->taintAssignment(xmm9, xmm9_addr);
6081 xmm10_expr->isTainted = this->taintEngine->taintAssignment(xmm10, xmm10_addr);
6082 xmm11_expr->isTainted = this->taintEngine->taintAssignment(xmm11, xmm11_addr);
6083 xmm12_expr->isTainted = this->taintEngine->taintAssignment(xmm12, xmm12_addr);
6084 xmm13_expr->isTainted = this->taintEngine->taintAssignment(xmm13, xmm13_addr);
6085 xmm14_expr->isTainted = this->taintEngine->taintAssignment(xmm14, xmm14_addr);
6086 xmm15_expr->isTainted = this->taintEngine->taintAssignment(xmm15, xmm15_addr);
6087 }
6088
6089 /* Update the symbolic control flow */
6090 this->controlFlow_s(inst);
6091 }
6092
6093
6094 void x86Semantics::fxrstor64_s(triton::arch::Instruction& inst) {
6095 /* Fetch the memory operand */
6096 auto& dst = inst.operands[0];
6097 auto& mem = dst.getMemory();
6098 auto m512byte = mem.getAddress();
6099
6100 /* Check if the address is on a 16-byte boundary */
6101 if (m512byte & 0xF) {
6102 this->exception = triton::arch::FAULT_GP;
6103 return;
6104 }
6105
6106 /* Fetch the FPU, STX, SSE, EFER and CS implicit operands */
6107 auto fcw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FCW));
6108 auto fsw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FSW));
6109 auto ftw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FTW));
6110 auto fop = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FOP));
6111 auto fip = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FIP));
6112 auto fcs = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FCS));
6113 auto fdp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FDP));
6114 auto fds = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FDS));
6115 auto mxcsr = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR));
6116 auto mxcsr_mask = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR_MASK));
6117 auto st0 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST0));
6118 auto st1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST1));
6119 auto st2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST2));
6120 auto st3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST3));
6121 auto st4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST4));
6122 auto st5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST5));
6123 auto st6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST6));
6124 auto st7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST7));
6125 auto xmm0 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM0));
6126 auto xmm1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM1));
6127 auto xmm2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM2));
6128 auto xmm3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM3));
6129 auto xmm4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM4));
6130 auto xmm5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM5));
6131 auto xmm6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM6));
6132 auto xmm7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM7));
6133 auto xmm8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM8));
6134 auto xmm9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM9));
6135 auto xmm10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM10));
6136 auto xmm11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM11));
6137 auto xmm12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM12));
6138 auto xmm13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM13));
6139 auto xmm14 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM14));
6140 auto xmm15 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM15));
6141 auto ffxsr = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EFER_FFXSR));
6142 auto cs = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CS));
6143
6144 /* Fetch the implicit memory slots for the '64-bit Mode Layout (with REX.W = 1)' */
6145 auto fcw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 0, fcw.getSize()));
6146 auto fsw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 2, fsw.getSize()));
6147 auto ftw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 4, ftw.getSize() / 2));
6148 auto fop_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 6, fop.getSize()));
6149 auto fip_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 8, fip.getSize()));
6150 auto fcs_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 12, fcs.getSize()));
6151 auto fdp_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 16, fdp.getSize()));
6152 auto fds_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 20, fds.getSize()));
6153 auto mxcsr_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 24, mxcsr.getSize()));
6154 auto mxcsr_mask_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 28, mxcsr_mask.getSize()));
6155 auto st0_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 32, st0.getSize()));
6156 auto st1_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 48, st1.getSize()));
6157 auto st2_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 64, st2.getSize()));
6158 auto st3_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 80, st3.getSize()));
6159 auto st4_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 96, st4.getSize()));
6160 auto st5_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 112, st5.getSize()));
6161 auto st6_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 128, st6.getSize()));
6162 auto st7_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 144, st7.getSize()));
6163 auto xmm0_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 160, xmm0.getSize()));
6164 auto xmm1_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 176, xmm1.getSize()));
6165 auto xmm2_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 192, xmm2.getSize()));
6166 auto xmm3_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 208, xmm3.getSize()));
6167 auto xmm4_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 224, xmm4.getSize()));
6168 auto xmm5_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 240, xmm5.getSize()));
6169 auto xmm6_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 256, xmm6.getSize()));
6170 auto xmm7_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 272, xmm7.getSize()));
6171 auto xmm8_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 288, xmm8.getSize()));
6172 auto xmm9_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 304, xmm9.getSize()));
6173 auto xmm10_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 320, xmm10.getSize()));
6174 auto xmm11_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 336, xmm11.getSize()));
6175 auto xmm12_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 352, xmm12.getSize()));
6176 auto xmm13_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 368, xmm13.getSize()));
6177 auto xmm14_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 384, xmm14.getSize()));
6178 auto xmm15_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 400, xmm15.getSize()));
6179
6180 /* Create the symbolic operands */
6181 auto fcw_ast = this->symbolicEngine->getOperandAst(inst, fcw_addr);
6182 auto fsw_ast = this->symbolicEngine->getOperandAst(inst, fsw_addr);
6183 auto ftw_ast = this->symbolicEngine->getOperandAst(inst, ftw_addr);
6184 auto fop_ast = this->symbolicEngine->getOperandAst(inst, fop_addr);
6185 auto fip_ast = this->symbolicEngine->getOperandAst(inst, fip_addr);
6186 auto fcs_ast = this->symbolicEngine->getOperandAst(inst, fcs_addr);
6187 auto fdp_ast = this->symbolicEngine->getOperandAst(inst, fdp_addr);
6188 auto fds_ast = this->symbolicEngine->getOperandAst(inst, fds_addr);
6189 auto mxcsr_ast = this->symbolicEngine->getOperandAst(inst, mxcsr_addr);
6190 auto mxcsr_mask_ast = this->symbolicEngine->getOperandAst(inst, mxcsr_mask_addr);
6191 auto st0_ast = this->symbolicEngine->getOperandAst(inst, st0_addr);
6192 auto st1_ast = this->symbolicEngine->getOperandAst(inst, st1_addr);
6193 auto st2_ast = this->symbolicEngine->getOperandAst(inst, st2_addr);
6194 auto st3_ast = this->symbolicEngine->getOperandAst(inst, st3_addr);
6195 auto st4_ast = this->symbolicEngine->getOperandAst(inst, st4_addr);
6196 auto st5_ast = this->symbolicEngine->getOperandAst(inst, st5_addr);
6197 auto st6_ast = this->symbolicEngine->getOperandAst(inst, st6_addr);
6198 auto st7_ast = this->symbolicEngine->getOperandAst(inst, st7_addr);
6199 auto xmm0_ast = this->symbolicEngine->getOperandAst(inst, xmm0_addr);
6200 auto xmm1_ast = this->symbolicEngine->getOperandAst(inst, xmm1_addr);
6201 auto xmm2_ast = this->symbolicEngine->getOperandAst(inst, xmm2_addr);
6202 auto xmm3_ast = this->symbolicEngine->getOperandAst(inst, xmm3_addr);
6203 auto xmm4_ast = this->symbolicEngine->getOperandAst(inst, xmm4_addr);
6204 auto xmm5_ast = this->symbolicEngine->getOperandAst(inst, xmm5_addr);
6205 auto xmm6_ast = this->symbolicEngine->getOperandAst(inst, xmm6_addr);
6206 auto xmm7_ast = this->symbolicEngine->getOperandAst(inst, xmm7_addr);
6207 auto xmm8_ast = this->symbolicEngine->getOperandAst(inst, xmm8_addr);
6208 auto xmm9_ast = this->symbolicEngine->getOperandAst(inst, xmm9_addr);
6209 auto xmm10_ast = this->symbolicEngine->getOperandAst(inst, xmm10_addr);
6210 auto xmm11_ast = this->symbolicEngine->getOperandAst(inst, xmm11_addr);
6211 auto xmm12_ast = this->symbolicEngine->getOperandAst(inst, xmm12_addr);
6212 auto xmm13_ast = this->symbolicEngine->getOperandAst(inst, xmm13_addr);
6213 auto xmm14_ast = this->symbolicEngine->getOperandAst(inst, xmm14_addr);
6214 auto xmm15_ast = this->symbolicEngine->getOperandAst(inst, xmm15_addr);
6215 auto ffxsr_ast = this->symbolicEngine->getOperandAst(inst, ffxsr);
6216 auto cs_ast = this->symbolicEngine->getOperandAst(inst, cs);
6217
6218 /* Fetch the original values for the XMM0-XMM15 registers */
6219 auto xmm0_orig = this->symbolicEngine->getOperandAst(inst, xmm0);
6220 auto xmm1_orig = this->symbolicEngine->getOperandAst(inst, xmm1);
6221 auto xmm2_orig = this->symbolicEngine->getOperandAst(inst, xmm2);
6222 auto xmm3_orig = this->symbolicEngine->getOperandAst(inst, xmm3);
6223 auto xmm4_orig = this->symbolicEngine->getOperandAst(inst, xmm4);
6224 auto xmm5_orig = this->symbolicEngine->getOperandAst(inst, xmm5);
6225 auto xmm6_orig = this->symbolicEngine->getOperandAst(inst, xmm6);
6226 auto xmm7_orig = this->symbolicEngine->getOperandAst(inst, xmm7);
6227 auto xmm8_orig = this->symbolicEngine->getOperandAst(inst, xmm8);
6228 auto xmm9_orig = this->symbolicEngine->getOperandAst(inst, xmm9);
6229 auto xmm10_orig = this->symbolicEngine->getOperandAst(inst, xmm10);
6230 auto xmm11_orig = this->symbolicEngine->getOperandAst(inst, xmm11);
6231 auto xmm12_orig = this->symbolicEngine->getOperandAst(inst, xmm12);
6232 auto xmm13_orig = this->symbolicEngine->getOperandAst(inst, xmm13);
6233 auto xmm14_orig = this->symbolicEngine->getOperandAst(inst, xmm14);
6234 auto xmm15_orig = this->symbolicEngine->getOperandAst(inst, xmm15);
6235
6236 /* Check if we are running in CPL = 0 (ring 0) and if the FFXSR bit is set in EFER */
6237 auto cpl = this->astCtxt->equal(this->astCtxt->extract(1, 0, cs_ast), this->astCtxt->bv(0, 2));
6238 auto ffx = this->astCtxt->equal(ffxsr_ast, this->astCtxt->bv(1, 1));
6239 auto is_fast = this->astCtxt->land(cpl, ffx);
6240
6241 /* Apply the fast restore logic if needed */
6242 xmm0_ast = this->astCtxt->ite(is_fast, xmm0_orig, xmm0_ast);
6243 xmm1_ast = this->astCtxt->ite(is_fast, xmm1_orig, xmm1_ast);
6244 xmm2_ast = this->astCtxt->ite(is_fast, xmm2_orig, xmm2_ast);
6245 xmm3_ast = this->astCtxt->ite(is_fast, xmm3_orig, xmm3_ast);
6246 xmm4_ast = this->astCtxt->ite(is_fast, xmm4_orig, xmm4_ast);
6247 xmm5_ast = this->astCtxt->ite(is_fast, xmm5_orig, xmm5_ast);
6248 xmm6_ast = this->astCtxt->ite(is_fast, xmm6_orig, xmm6_ast);
6249 xmm7_ast = this->astCtxt->ite(is_fast, xmm7_orig, xmm7_ast);
6250 xmm8_ast = this->astCtxt->ite(is_fast, xmm8_orig, xmm8_ast);
6251 xmm9_ast = this->astCtxt->ite(is_fast, xmm9_orig, xmm9_ast);
6252 xmm10_ast = this->astCtxt->ite(is_fast, xmm10_orig, xmm10_ast);
6253 xmm11_ast = this->astCtxt->ite(is_fast, xmm11_orig, xmm11_ast);
6254 xmm12_ast = this->astCtxt->ite(is_fast, xmm12_orig, xmm12_ast);
6255 xmm13_ast = this->astCtxt->ite(is_fast, xmm13_orig, xmm13_ast);
6256 xmm14_ast = this->astCtxt->ite(is_fast, xmm14_orig, xmm14_ast);
6257 xmm15_ast = this->astCtxt->ite(is_fast, xmm15_orig, xmm15_ast);
6258
6259 /* Fetch the abridged x87 FPU Tag Word Encoded Bits */
6260 auto eb_1_0 = this->astCtxt->extract(0, 0, ftw_ast);
6261 auto eb_3_2 = this->astCtxt->extract(1, 1, ftw_ast);
6262 auto eb_5_4 = this->astCtxt->extract(2, 2, ftw_ast);
6263 auto eb_7_6 = this->astCtxt->extract(3, 3, ftw_ast);
6264 auto eb_9_8 = this->astCtxt->extract(4, 4, ftw_ast);
6265 auto eb_11_10 = this->astCtxt->extract(5, 5, ftw_ast);
6266 auto eb_13_12 = this->astCtxt->extract(6, 6, ftw_ast);
6267 auto eb_15_14 = this->astCtxt->extract(7, 7, ftw_ast);
6268
6269 /* Extract the fraction from the STX registers */
6270 auto fraction_st0 = this->astCtxt->extract(62, 0, st0_ast);
6271 auto fraction_st1 = this->astCtxt->extract(62, 0, st1_ast);
6272 auto fraction_st2 = this->astCtxt->extract(62, 0, st2_ast);
6273 auto fraction_st3 = this->astCtxt->extract(62, 0, st3_ast);
6274 auto fraction_st4 = this->astCtxt->extract(62, 0, st4_ast);
6275 auto fraction_st5 = this->astCtxt->extract(62, 0, st5_ast);
6276 auto fraction_st6 = this->astCtxt->extract(62, 0, st6_ast);
6277 auto fraction_st7 = this->astCtxt->extract(62, 0, st7_ast);
6278
6279 /* Extract the integer bit from the STX registers */
6280 auto integer_st0 = this->astCtxt->extract(63, 63, st0_ast);
6281 auto integer_st1 = this->astCtxt->extract(63, 63, st1_ast);
6282 auto integer_st2 = this->astCtxt->extract(63, 63, st2_ast);
6283 auto integer_st3 = this->astCtxt->extract(63, 63, st3_ast);
6284 auto integer_st4 = this->astCtxt->extract(63, 63, st4_ast);
6285 auto integer_st5 = this->astCtxt->extract(63, 63, st5_ast);
6286 auto integer_st6 = this->astCtxt->extract(63, 63, st6_ast);
6287 auto integer_st7 = this->astCtxt->extract(63, 63, st7_ast);
6288
6289 /* Extract the exponent from the STX registers */
6290 auto exponent_st0 = this->astCtxt->extract(79, 64, st0_ast);
6291 auto exponent_st1 = this->astCtxt->extract(79, 64, st1_ast);
6292 auto exponent_st2 = this->astCtxt->extract(79, 64, st2_ast);
6293 auto exponent_st3 = this->astCtxt->extract(79, 64, st3_ast);
6294 auto exponent_st4 = this->astCtxt->extract(79, 64, st4_ast);
6295 auto exponent_st5 = this->astCtxt->extract(79, 64, st5_ast);
6296 auto exponent_st6 = this->astCtxt->extract(79, 64, st6_ast);
6297 auto exponent_st7 = this->astCtxt->extract(79, 64, st7_ast);
6298
6299 /* Exponent All Zeros */
6300 auto ea0_st0 = this->astCtxt->equal(exponent_st0, this->astCtxt->bv(0x0000, 16));
6301 auto ea0_st1 = this->astCtxt->equal(exponent_st1, this->astCtxt->bv(0x0000, 16));
6302 auto ea0_st2 = this->astCtxt->equal(exponent_st2, this->astCtxt->bv(0x0000, 16));
6303 auto ea0_st3 = this->astCtxt->equal(exponent_st3, this->astCtxt->bv(0x0000, 16));
6304 auto ea0_st4 = this->astCtxt->equal(exponent_st4, this->astCtxt->bv(0x0000, 16));
6305 auto ea0_st5 = this->astCtxt->equal(exponent_st5, this->astCtxt->bv(0x0000, 16));
6306 auto ea0_st6 = this->astCtxt->equal(exponent_st6, this->astCtxt->bv(0x0000, 16));
6307 auto ea0_st7 = this->astCtxt->equal(exponent_st7, this->astCtxt->bv(0x0000, 16));
6308
6309 /* Exponent All Ones */
6310 auto ea1_st0 = this->astCtxt->equal(exponent_st0, this->astCtxt->bv(0xFFFF, 16));
6311 auto ea1_st1 = this->astCtxt->equal(exponent_st1, this->astCtxt->bv(0xFFFF, 16));
6312 auto ea1_st2 = this->astCtxt->equal(exponent_st2, this->astCtxt->bv(0xFFFF, 16));
6313 auto ea1_st3 = this->astCtxt->equal(exponent_st3, this->astCtxt->bv(0xFFFF, 16));
6314 auto ea1_st4 = this->astCtxt->equal(exponent_st4, this->astCtxt->bv(0xFFFF, 16));
6315 auto ea1_st5 = this->astCtxt->equal(exponent_st5, this->astCtxt->bv(0xFFFF, 16));
6316 auto ea1_st6 = this->astCtxt->equal(exponent_st6, this->astCtxt->bv(0xFFFF, 16));
6317 auto ea1_st7 = this->astCtxt->equal(exponent_st7, this->astCtxt->bv(0xFFFF, 16));
6318
6319 /* Exponent Neither All Zeroes Or Ones */
6320 auto ena01_st0 = this->astCtxt->equal(this->astCtxt->lor(ea0_st0, ea1_st0), this->astCtxt->bvfalse());
6321 auto ena01_st1 = this->astCtxt->equal(this->astCtxt->lor(ea0_st1, ea1_st1), this->astCtxt->bvfalse());
6322 auto ena01_st2 = this->astCtxt->equal(this->astCtxt->lor(ea0_st2, ea1_st2), this->astCtxt->bvfalse());
6323 auto ena01_st3 = this->astCtxt->equal(this->astCtxt->lor(ea0_st3, ea1_st3), this->astCtxt->bvfalse());
6324 auto ena01_st4 = this->astCtxt->equal(this->astCtxt->lor(ea0_st4, ea1_st4), this->astCtxt->bvfalse());
6325 auto ena01_st5 = this->astCtxt->equal(this->astCtxt->lor(ea0_st5, ea1_st5), this->astCtxt->bvfalse());
6326 auto ena01_st6 = this->astCtxt->equal(this->astCtxt->lor(ea0_st6, ea1_st6), this->astCtxt->bvfalse());
6327 auto ena01_st7 = this->astCtxt->equal(this->astCtxt->lor(ea0_st7, ea1_st7), this->astCtxt->bvfalse());
6328
6329 /* Integer Bit 0 */
6330 auto ib0_st0 = this->astCtxt->equal(integer_st0, this->astCtxt->bv(0, 1));
6331 auto ib0_st1 = this->astCtxt->equal(integer_st1, this->astCtxt->bv(0, 1));
6332 auto ib0_st2 = this->astCtxt->equal(integer_st2, this->astCtxt->bv(0, 1));
6333 auto ib0_st3 = this->astCtxt->equal(integer_st3, this->astCtxt->bv(0, 1));
6334 auto ib0_st4 = this->astCtxt->equal(integer_st4, this->astCtxt->bv(0, 1));
6335 auto ib0_st5 = this->astCtxt->equal(integer_st5, this->astCtxt->bv(0, 1));
6336 auto ib0_st6 = this->astCtxt->equal(integer_st6, this->astCtxt->bv(0, 1));
6337 auto ib0_st7 = this->astCtxt->equal(integer_st7, this->astCtxt->bv(0, 1));
6338
6339 /* Fraction All Zeroes */
6340 auto fa0_st0 = this->astCtxt->equal(fraction_st0, this->astCtxt->bv(0, 63));
6341 auto fa0_st1 = this->astCtxt->equal(fraction_st1, this->astCtxt->bv(0, 63));
6342 auto fa0_st2 = this->astCtxt->equal(fraction_st2, this->astCtxt->bv(0, 63));
6343 auto fa0_st3 = this->astCtxt->equal(fraction_st3, this->astCtxt->bv(0, 63));
6344 auto fa0_st4 = this->astCtxt->equal(fraction_st4, this->astCtxt->bv(0, 63));
6345 auto fa0_st5 = this->astCtxt->equal(fraction_st5, this->astCtxt->bv(0, 63));
6346 auto fa0_st6 = this->astCtxt->equal(fraction_st6, this->astCtxt->bv(0, 63));
6347 auto fa0_st7 = this->astCtxt->equal(fraction_st7, this->astCtxt->bv(0, 63));
6348
6349 /* Determine the x87 FPU Tag Word (Diagram at page 379 of the AMD Architecture Programmer's Manual, Volume 2: System Programming) */
6350 auto db_1_0 = this->astCtxt->ite(this->astCtxt->equal(eb_1_0, this->astCtxt->bv(0, 1)),
6351 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
6352 this->astCtxt->ite(ea0_st0,
6353 this->astCtxt->ite(ib0_st0,
6354 this->astCtxt->ite(fa0_st0,
6355 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
6356 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
6357 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
6358 this->astCtxt->ite(ena01_st0,
6359 this->astCtxt->ite(ib0_st0,
6360 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
6361 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
6362 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
6363
6364 auto db_3_2 = this->astCtxt->ite(this->astCtxt->equal(eb_3_2, this->astCtxt->bv(0, 1)),
6365 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
6366 this->astCtxt->ite(ea0_st1,
6367 this->astCtxt->ite(ib0_st1,
6368 this->astCtxt->ite(fa0_st1,
6369 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
6370 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
6371 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
6372 this->astCtxt->ite(ena01_st1,
6373 this->astCtxt->ite(ib0_st1,
6374 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
6375 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
6376 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
6377
6378 auto db_5_4 = this->astCtxt->ite(this->astCtxt->equal(eb_5_4, this->astCtxt->bv(0, 1)),
6379 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
6380 this->astCtxt->ite(ea0_st2,
6381 this->astCtxt->ite(ib0_st2,
6382 this->astCtxt->ite(fa0_st2,
6383 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
6384 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
6385 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
6386 this->astCtxt->ite(ena01_st2,
6387 this->astCtxt->ite(ib0_st2,
6388 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
6389 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
6390 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
6391
6392 auto db_7_6 = this->astCtxt->ite(this->astCtxt->equal(eb_7_6, this->astCtxt->bv(0, 1)),
6393 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
6394 this->astCtxt->ite(ea0_st3,
6395 this->astCtxt->ite(ib0_st3,
6396 this->astCtxt->ite(fa0_st3,
6397 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
6398 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
6399 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
6400 this->astCtxt->ite(ena01_st3,
6401 this->astCtxt->ite(ib0_st3,
6402 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
6403 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
6404 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
6405
6406 auto db_9_8 = this->astCtxt->ite(this->astCtxt->equal(eb_9_8, this->astCtxt->bv(0, 1)),
6407 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
6408 this->astCtxt->ite(ea0_st4,
6409 this->astCtxt->ite(ib0_st4,
6410 this->astCtxt->ite(fa0_st4,
6411 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
6412 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
6413 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
6414 this->astCtxt->ite(ena01_st4,
6415 this->astCtxt->ite(ib0_st4,
6416 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
6417 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
6418 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
6419
6420 auto db_11_10 = this->astCtxt->ite(this->astCtxt->equal(eb_11_10, this->astCtxt->bv(0, 1)),
6421 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
6422 this->astCtxt->ite(ea0_st5,
6423 this->astCtxt->ite(ib0_st5,
6424 this->astCtxt->ite(fa0_st5,
6425 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
6426 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
6427 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
6428 this->astCtxt->ite(ena01_st5,
6429 this->astCtxt->ite(ib0_st5,
6430 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
6431 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
6432 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
6433
6434 auto db_13_12 = this->astCtxt->ite(this->astCtxt->equal(eb_13_12, this->astCtxt->bv(0, 1)),
6435 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
6436 this->astCtxt->ite(ea0_st6,
6437 this->astCtxt->ite(ib0_st6,
6438 this->astCtxt->ite(fa0_st6,
6439 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
6440 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
6441 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
6442 this->astCtxt->ite(ena01_st6,
6443 this->astCtxt->ite(ib0_st6,
6444 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
6445 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
6446 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
6447
6448 auto db_15_14 = this->astCtxt->ite(this->astCtxt->equal(eb_15_14, this->astCtxt->bv(0, 1)),
6449 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
6450 this->astCtxt->ite(ea0_st7,
6451 this->astCtxt->ite(ib0_st7,
6452 this->astCtxt->ite(fa0_st7,
6453 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
6454 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
6455 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
6456 this->astCtxt->ite(ena01_st7,
6457 this->astCtxt->ite(ib0_st7,
6458 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
6459 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
6460 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
6461
6462 /* Restore the x87 FPU Tag Word */
6463 auto uftw_ast = this->astCtxt->concat(db_15_14,
6464 this->astCtxt->concat(db_13_12,
6465 this->astCtxt->concat(db_11_10,
6466 this->astCtxt->concat(db_9_8,
6467 this->astCtxt->concat(db_7_6,
6468 this->astCtxt->concat(db_5_4,
6469 this->astCtxt->concat(db_3_2, db_1_0)))))));
6470
6471 /* Craft the symbolic expressions */
6472 auto fcw_expr = this->symbolicEngine->createSymbolicExpression(inst, fcw_ast, fcw, "FXRSTOR64 FCW operation");
6473 auto fsw_expr = this->symbolicEngine->createSymbolicExpression(inst, fsw_ast, fsw, "FXRSTOR64 FSW operation");
6474 auto ftw_expr = this->symbolicEngine->createSymbolicExpression(inst, uftw_ast, ftw, "FXRSTOR64 Updated FTW operation");
6475 auto fop_expr = this->symbolicEngine->createSymbolicExpression(inst, fop_ast, fop, "FXRSTOR64 FOP operation");
6476 auto fip_expr = this->symbolicEngine->createSymbolicExpression(inst, fip_ast, fip, "FXRSTOR64 FIP operation");
6477 auto fcs_expr = this->symbolicEngine->createSymbolicExpression(inst, fcs_ast, fcs, "FXRSTOR64 FCS operation");
6478 auto fdp_expr = this->symbolicEngine->createSymbolicExpression(inst, fdp_ast, fdp, "FXRSTOR64 FDP operation");
6479 auto fds_expr = this->symbolicEngine->createSymbolicExpression(inst, fds_ast, fds, "FXRSTOR64 FDS operation");
6480 auto mxcsr_expr = this->symbolicEngine->createSymbolicExpression(inst, mxcsr_ast, mxcsr, "FXRSTOR64 MXCSR operation");
6481 auto mxcsr_mask_expr = this->symbolicEngine->createSymbolicExpression(inst, mxcsr_mask_ast, mxcsr_mask, "FXRSTOR64 MXCSR_MASK operation");
6482 auto st0_expr = this->symbolicEngine->createSymbolicExpression(inst, st0_ast, st0, "FXRSTOR64 ST0 operation");
6483 auto st1_expr = this->symbolicEngine->createSymbolicExpression(inst, st1_ast, st1, "FXRSTOR64 ST1 operation");
6484 auto st2_expr = this->symbolicEngine->createSymbolicExpression(inst, st2_ast, st2, "FXRSTOR64 ST2 operation");
6485 auto st3_expr = this->symbolicEngine->createSymbolicExpression(inst, st3_ast, st3, "FXRSTOR64 ST3 operation");
6486 auto st4_expr = this->symbolicEngine->createSymbolicExpression(inst, st4_ast, st4, "FXRSTOR64 ST4 operation");
6487 auto st5_expr = this->symbolicEngine->createSymbolicExpression(inst, st5_ast, st5, "FXRSTOR64 ST5 operation");
6488 auto st6_expr = this->symbolicEngine->createSymbolicExpression(inst, st6_ast, st6, "FXRSTOR64 ST6 operation");
6489 auto st7_expr = this->symbolicEngine->createSymbolicExpression(inst, st7_ast, st7, "FXRSTOR64 ST7 operation");
6490 auto xmm0_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm0_ast, xmm0, "FXRSTOR64 XMM0 operation");
6491 auto xmm1_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm1_ast, xmm1, "FXRSTOR64 XMM1 operation");
6492 auto xmm2_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm2_ast, xmm2, "FXRSTOR64 XMM2 operation");
6493 auto xmm3_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm3_ast, xmm3, "FXRSTOR64 XMM3 operation");
6494 auto xmm4_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm4_ast, xmm4, "FXRSTOR64 XMM4 operation");
6495 auto xmm5_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm5_ast, xmm5, "FXRSTOR64 XMM5 operation");
6496 auto xmm6_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm6_ast, xmm6, "FXRSTOR64 XMM6 operation");
6497 auto xmm7_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm7_ast, xmm7, "FXRSTOR64 XMM7 operation");
6498 auto xmm8_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm8_ast, xmm8, "FXRSTOR64 XMM8 operation");
6499 auto xmm9_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm9_ast, xmm9, "FXRSTOR64 XMM9 operation");
6500 auto xmm10_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm10_ast, xmm10, "FXRSTOR64 XMM10 operation");
6501 auto xmm11_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm11_ast, xmm11, "FXRSTOR64 XMM11 operation");
6502 auto xmm12_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm12_ast, xmm12, "FXRSTOR64 XMM12 operation");
6503 auto xmm13_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm13_ast, xmm13, "FXRSTOR64 XMM13 operation");
6504 auto xmm14_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm14_ast, xmm14, "FXRSTOR64 XMM14 operation");
6505 auto xmm15_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm15_ast, xmm15, "FXRSTOR64 XMM15 operation");
6506
6507 /* Spread the taint */
6508 fcw_expr->isTainted = this->taintEngine->taintAssignment(fcw, fcw_addr);
6509 fsw_expr->isTainted = this->taintEngine->taintAssignment(fsw, fsw_addr);
6510 ftw_expr->isTainted = this->taintEngine->taintAssignment(ftw, ftw_addr);
6511 fop_expr->isTainted = this->taintEngine->taintAssignment(fop, fop_addr);
6512 fip_expr->isTainted = this->taintEngine->taintAssignment(fip, fip_addr);
6513 fcs_expr->isTainted = this->taintEngine->taintAssignment(fcs, fcs_addr);
6514 fdp_expr->isTainted = this->taintEngine->taintAssignment(fdp, fdp_addr);
6515 fds_expr->isTainted = this->taintEngine->taintAssignment(fds, fds_addr);
6516 mxcsr_expr->isTainted = this->taintEngine->taintAssignment(mxcsr, mxcsr_addr);
6517 mxcsr_mask_expr->isTainted = this->taintEngine->taintAssignment(mxcsr_mask, mxcsr_mask_addr);
6518 st0_expr->isTainted = this->taintEngine->taintAssignment(st0, st0_addr);
6519 st1_expr->isTainted = this->taintEngine->taintAssignment(st1, st1_addr);
6520 st2_expr->isTainted = this->taintEngine->taintAssignment(st2, st2_addr);
6521 st3_expr->isTainted = this->taintEngine->taintAssignment(st3, st3_addr);
6522 st4_expr->isTainted = this->taintEngine->taintAssignment(st4, st4_addr);
6523 st5_expr->isTainted = this->taintEngine->taintAssignment(st5, st5_addr);
6524 st6_expr->isTainted = this->taintEngine->taintAssignment(st6, st6_addr);
6525 st7_expr->isTainted = this->taintEngine->taintAssignment(st7, st7_addr);
6526 xmm0_expr->isTainted = this->taintEngine->taintAssignment(xmm0, xmm0_addr);
6527 xmm1_expr->isTainted = this->taintEngine->taintAssignment(xmm1, xmm1_addr);
6528 xmm2_expr->isTainted = this->taintEngine->taintAssignment(xmm2, xmm2_addr);
6529 xmm3_expr->isTainted = this->taintEngine->taintAssignment(xmm3, xmm3_addr);
6530 xmm4_expr->isTainted = this->taintEngine->taintAssignment(xmm4, xmm4_addr);
6531 xmm5_expr->isTainted = this->taintEngine->taintAssignment(xmm5, xmm5_addr);
6532 xmm6_expr->isTainted = this->taintEngine->taintAssignment(xmm6, xmm6_addr);
6533 xmm7_expr->isTainted = this->taintEngine->taintAssignment(xmm7, xmm7_addr);
6534 xmm8_expr->isTainted = this->taintEngine->taintAssignment(xmm8, xmm8_addr);
6535 xmm9_expr->isTainted = this->taintEngine->taintAssignment(xmm9, xmm9_addr);
6536 xmm10_expr->isTainted = this->taintEngine->taintAssignment(xmm10, xmm10_addr);
6537 xmm11_expr->isTainted = this->taintEngine->taintAssignment(xmm11, xmm11_addr);
6538 xmm12_expr->isTainted = this->taintEngine->taintAssignment(xmm12, xmm12_addr);
6539 xmm13_expr->isTainted = this->taintEngine->taintAssignment(xmm13, xmm13_addr);
6540 xmm14_expr->isTainted = this->taintEngine->taintAssignment(xmm14, xmm14_addr);
6541 xmm15_expr->isTainted = this->taintEngine->taintAssignment(xmm15, xmm15_addr);
6542
6543 /* Update the symbolic control flow */
6544 this->controlFlow_s(inst);
6545 }
6546
6547
6548 void x86Semantics::fxsave_s(triton::arch::Instruction& inst) {
6549 /* Fetch the current architecture */
6550 auto arch = this->architecture->getArchitecture();
6551
6552 /* Determine if we are executing in 64 bit mode */
6553 auto is64bits = arch == triton::arch::architecture_e::ARCH_X86_64;
6554
6555 /* Fetch the memory operand */
6556 auto& dst = inst.operands[0];
6557 auto& mem = dst.getMemory();
6558 auto m512byte = mem.getAddress();
6559
6560 /* Check if the address is on a 16-byte boundary */
6561 if (m512byte & 0xF) {
6562 this->exception = triton::arch::FAULT_GP;
6563 return;
6564 }
6565
6566 /* Fetch the FPU, STX, SSE, EFER and CS implicit operands */
6567 auto fcw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FCW));
6568 auto fsw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FSW));
6569 auto ftw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FTW));
6570 auto fop = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FOP));
6571 auto fip = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FIP));
6572 auto fcs = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FCS));
6573 auto fdp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FDP));
6574 auto fds = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FDS));
6575 auto mxcsr = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR));
6576 auto mxcsr_mask = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR_MASK));
6577 auto st0 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST0));
6578 auto st1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST1));
6579 auto st2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST2));
6580 auto st3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST3));
6581 auto st4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST4));
6582 auto st5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST5));
6583 auto st6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST6));
6584 auto st7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST7));
6585 auto xmm0 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM0));
6586 auto xmm1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM1));
6587 auto xmm2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM2));
6588 auto xmm3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM3));
6589 auto xmm4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM4));
6590 auto xmm5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM5));
6591 auto xmm6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM6));
6592 auto xmm7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM7));
6593 auto ffxsr = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EFER_FFXSR));
6594 auto cs = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CS));
6595
6596 /* Create the symbolic operands */
6597 auto fcw_ast = this->symbolicEngine->getOperandAst(inst, fcw);
6598 auto fsw_ast = this->symbolicEngine->getOperandAst(inst, fsw);
6599 auto ftw_ast = this->symbolicEngine->getOperandAst(inst, ftw);
6600 auto fop_ast = this->symbolicEngine->getOperandAst(inst, fop);
6601 auto fip_ast = this->astCtxt->extract(triton::bitsize::dword - 1, 0, this->symbolicEngine->getOperandAst(inst, fip));
6602 auto fcs_ast = this->symbolicEngine->getOperandAst(inst, fcs);
6603 auto fdp_ast = this->astCtxt->extract(triton::bitsize::dword - 1, 0, this->symbolicEngine->getOperandAst(inst, fdp));
6604 auto fds_ast = this->symbolicEngine->getOperandAst(inst, fds);
6605 auto mxcsr_ast = this->symbolicEngine->getOperandAst(inst, mxcsr);
6606 auto mxcsr_mask_ast = this->symbolicEngine->getOperandAst(inst, mxcsr_mask);
6607 auto st0_ast = this->symbolicEngine->getOperandAst(inst, st0);
6608 auto st1_ast = this->symbolicEngine->getOperandAst(inst, st1);
6609 auto st2_ast = this->symbolicEngine->getOperandAst(inst, st2);
6610 auto st3_ast = this->symbolicEngine->getOperandAst(inst, st3);
6611 auto st4_ast = this->symbolicEngine->getOperandAst(inst, st4);
6612 auto st5_ast = this->symbolicEngine->getOperandAst(inst, st5);
6613 auto st6_ast = this->symbolicEngine->getOperandAst(inst, st6);
6614 auto st7_ast = this->symbolicEngine->getOperandAst(inst, st7);
6615 auto xmm0_ast = this->symbolicEngine->getOperandAst(inst, xmm0);
6616 auto xmm1_ast = this->symbolicEngine->getOperandAst(inst, xmm1);
6617 auto xmm2_ast = this->symbolicEngine->getOperandAst(inst, xmm2);
6618 auto xmm3_ast = this->symbolicEngine->getOperandAst(inst, xmm3);
6619 auto xmm4_ast = this->symbolicEngine->getOperandAst(inst, xmm4);
6620 auto xmm5_ast = this->symbolicEngine->getOperandAst(inst, xmm5);
6621 auto xmm6_ast = this->symbolicEngine->getOperandAst(inst, xmm6);
6622 auto xmm7_ast = this->symbolicEngine->getOperandAst(inst, xmm7);
6623 auto ffxsr_ast = this->symbolicEngine->getOperandAst(inst, ffxsr);
6624 auto cs_ast = this->symbolicEngine->getOperandAst(inst, cs);
6625
6626 /*
6627 Calculate the abridged x87 FPU Tag Word (from 2 bytes to 1 byte encoding)
6628 - Two-bit values of 00, 01, and 10 are encoded as a 1
6629 - A two-bit value of 11 is encoded as a 0
6630 */
6631 auto eb_1_0 = this->astCtxt->ite(
6632 this->astCtxt->equal(this->astCtxt->extract(1, 0, ftw_ast), this->astCtxt->bv(3, 2)),
6633 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6634
6635 auto eb_3_2 = this->astCtxt->ite(
6636 this->astCtxt->equal(this->astCtxt->extract(3, 2, ftw_ast), this->astCtxt->bv(3, 2)),
6637 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6638
6639 auto eb_5_4 = this->astCtxt->ite(
6640 this->astCtxt->equal(this->astCtxt->extract(5, 4, ftw_ast), this->astCtxt->bv(3, 2)),
6641 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6642
6643 auto eb_7_6 = this->astCtxt->ite(
6644 this->astCtxt->equal(this->astCtxt->extract(7, 6, ftw_ast), this->astCtxt->bv(3, 2)),
6645 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6646
6647 auto eb_9_8 = this->astCtxt->ite(
6648 this->astCtxt->equal(this->astCtxt->extract(9, 8, ftw_ast), this->astCtxt->bv(3, 2)),
6649 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6650
6651 auto eb_11_10 = this->astCtxt->ite(
6652 this->astCtxt->equal(this->astCtxt->extract(11, 10, ftw_ast), this->astCtxt->bv(3, 2)),
6653 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6654
6655 auto eb_13_12 = this->astCtxt->ite(
6656 this->astCtxt->equal(this->astCtxt->extract(13, 12, ftw_ast), this->astCtxt->bv(3, 2)),
6657 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6658
6659 auto eb_15_14 = this->astCtxt->ite(
6660 this->astCtxt->equal(this->astCtxt->extract(15, 14, ftw_ast), this->astCtxt->bv(3, 2)),
6661 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6662
6663 auto aftw_ast = this->astCtxt->concat(eb_15_14,
6664 this->astCtxt->concat(eb_13_12,
6665 this->astCtxt->concat(eb_11_10,
6666 this->astCtxt->concat(eb_9_8,
6667 this->astCtxt->concat(eb_7_6,
6668 this->astCtxt->concat(eb_5_4,
6669 this->astCtxt->concat(eb_3_2, eb_1_0)))))));
6670
6671 /* Fetch the implicit memory slots for the 'Non-64-bit Mode Layout' */
6672 auto fcw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 0, fcw.getSize()));
6673 auto fsw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 2, fsw.getSize()));
6674 auto ftw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 4, ftw.getSize() / 2));
6675 auto fop_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 6, fop.getSize()));
6676 auto fip_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 8, fip.getSize() / 2));
6677 auto fcs_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 12, fcs.getSize()));
6678 auto fdp_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 16, fdp.getSize() / 2));
6679 auto fds_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 20, fds.getSize()));
6680 auto mxcsr_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 24, mxcsr.getSize()));
6681 auto mxcsr_mask_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 28, mxcsr_mask.getSize()));
6682 auto st0_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 32, st0.getSize()));
6683 auto st1_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 48, st1.getSize()));
6684 auto st2_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 64, st2.getSize()));
6685 auto st3_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 80, st3.getSize()));
6686 auto st4_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 96, st4.getSize()));
6687 auto st5_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 112, st5.getSize()));
6688 auto st6_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 128, st6.getSize()));
6689 auto st7_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 144, st7.getSize()));
6690 auto xmm0_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 160, xmm0.getSize()));
6691 auto xmm1_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 176, xmm1.getSize()));
6692 auto xmm2_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 192, xmm2.getSize()));
6693 auto xmm3_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 208, xmm3.getSize()));
6694 auto xmm4_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 224, xmm4.getSize()));
6695 auto xmm5_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 240, xmm5.getSize()));
6696 auto xmm6_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 256, xmm6.getSize()));
6697 auto xmm7_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 272, xmm7.getSize()));
6698
6699 /* Fetch the original values of the XMM0-XMM7 memory spaces */
6700 auto xmm0_orig = this->symbolicEngine->getOperandAst(xmm0_addr);
6701 auto xmm1_orig = this->symbolicEngine->getOperandAst(xmm1_addr);
6702 auto xmm2_orig = this->symbolicEngine->getOperandAst(xmm2_addr);
6703 auto xmm3_orig = this->symbolicEngine->getOperandAst(xmm3_addr);
6704 auto xmm4_orig = this->symbolicEngine->getOperandAst(xmm4_addr);
6705 auto xmm5_orig = this->symbolicEngine->getOperandAst(xmm5_addr);
6706 auto xmm6_orig = this->symbolicEngine->getOperandAst(xmm6_addr);
6707 auto xmm7_orig = this->symbolicEngine->getOperandAst(xmm7_addr);
6708
6709 /* Check if we are running in CPL = 0 (ring 0) and if the FFXSR bit is set in EFER */
6710 auto cpl = this->astCtxt->equal(this->astCtxt->extract(1, 0, cs_ast), this->astCtxt->bv(0, 2));
6711 auto ffx = this->astCtxt->equal(ffxsr_ast, this->astCtxt->bv(1, 1));
6712 auto b64 = this->astCtxt->equal(this->astCtxt->bv(is64bits, 1), this->astCtxt->bv(1, 1));
6713 auto is_fast = this->astCtxt->land(this->astCtxt->land(cpl, ffx), b64);
6714
6715 /* Apply the fast save logic if needed */
6716 xmm0_ast = this->astCtxt->ite(is_fast, xmm0_orig, xmm0_ast);
6717 xmm1_ast = this->astCtxt->ite(is_fast, xmm1_orig, xmm1_ast);
6718 xmm2_ast = this->astCtxt->ite(is_fast, xmm2_orig, xmm2_ast);
6719 xmm3_ast = this->astCtxt->ite(is_fast, xmm3_orig, xmm3_ast);
6720 xmm4_ast = this->astCtxt->ite(is_fast, xmm4_orig, xmm4_ast);
6721 xmm5_ast = this->astCtxt->ite(is_fast, xmm5_orig, xmm5_ast);
6722 xmm6_ast = this->astCtxt->ite(is_fast, xmm6_orig, xmm6_ast);
6723 xmm7_ast = this->astCtxt->ite(is_fast, xmm7_orig, xmm7_ast);
6724
6725 /* Craft the symbolic expressions */
6726 auto fcw_expr = this->symbolicEngine->createSymbolicExpression(inst, fcw_ast, fcw_addr, "FXSAVE FCW operation");
6727 auto fsw_expr = this->symbolicEngine->createSymbolicExpression(inst, fsw_ast, fsw_addr, "FXSAVE FSW operation");
6728 auto ftw_expr = this->symbolicEngine->createSymbolicExpression(inst, aftw_ast, ftw_addr, "FXSAVE Abridged FTW operation");
6729 auto fop_expr = this->symbolicEngine->createSymbolicExpression(inst, fop_ast, fop_addr, "FXSAVE FOP operation");
6730 auto fip_expr = this->symbolicEngine->createSymbolicExpression(inst, fip_ast, fip_addr, "FXSAVE FIP operation");
6731 auto fcs_expr = this->symbolicEngine->createSymbolicExpression(inst, fcs_ast, fcs_addr, "FXSAVE FCS operation");
6732 auto fdp_expr = this->symbolicEngine->createSymbolicExpression(inst, fdp_ast, fdp_addr, "FXSAVE FDP operation");
6733 auto fds_expr = this->symbolicEngine->createSymbolicExpression(inst, fds_ast, fds_addr, "FXSAVE FDS operation");
6734 auto mxcsr_expr = this->symbolicEngine->createSymbolicExpression(inst, mxcsr_ast, mxcsr_addr, "FXSAVE MXCSR operation");
6735 auto mxcsr_mask_expr = this->symbolicEngine->createSymbolicExpression(inst, mxcsr_mask_ast, mxcsr_mask_addr, "FXSAVE MXCSR_MASK operation");
6736 auto st0_expr = this->symbolicEngine->createSymbolicExpression(inst, st0_ast, st0_addr, "FXSAVE ST0 operation");
6737 auto st1_expr = this->symbolicEngine->createSymbolicExpression(inst, st1_ast, st1_addr, "FXSAVE ST1 operation");
6738 auto st2_expr = this->symbolicEngine->createSymbolicExpression(inst, st2_ast, st2_addr, "FXSAVE ST2 operation");
6739 auto st3_expr = this->symbolicEngine->createSymbolicExpression(inst, st3_ast, st3_addr, "FXSAVE ST3 operation");
6740 auto st4_expr = this->symbolicEngine->createSymbolicExpression(inst, st4_ast, st4_addr, "FXSAVE ST4 operation");
6741 auto st5_expr = this->symbolicEngine->createSymbolicExpression(inst, st5_ast, st5_addr, "FXSAVE ST5 operation");
6742 auto st6_expr = this->symbolicEngine->createSymbolicExpression(inst, st6_ast, st6_addr, "FXSAVE ST6 operation");
6743 auto st7_expr = this->symbolicEngine->createSymbolicExpression(inst, st7_ast, st7_addr, "FXSAVE ST7 operation");
6744 auto xmm0_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm0_ast, xmm0_addr, "FXSAVE XMM0 operation");
6745 auto xmm1_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm1_ast, xmm1_addr, "FXSAVE XMM1 operation");
6746 auto xmm2_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm2_ast, xmm2_addr, "FXSAVE XMM2 operation");
6747 auto xmm3_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm3_ast, xmm3_addr, "FXSAVE XMM3 operation");
6748 auto xmm4_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm4_ast, xmm4_addr, "FXSAVE XMM4 operation");
6749 auto xmm5_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm5_ast, xmm5_addr, "FXSAVE XMM5 operation");
6750 auto xmm6_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm6_ast, xmm6_addr, "FXSAVE XMM6 operation");
6751 auto xmm7_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm7_ast, xmm7_addr, "FXSAVE XMM7 operation");
6752
6753 /* Spread the taint */
6754 fcw_expr->isTainted = this->taintEngine->taintAssignment(fcw_addr, fcw);
6755 fsw_expr->isTainted = this->taintEngine->taintAssignment(fsw_addr, fsw);
6756 ftw_expr->isTainted = this->taintEngine->taintAssignment(ftw_addr, ftw);
6757 fop_expr->isTainted = this->taintEngine->taintAssignment(fop_addr, fop);
6758 fip_expr->isTainted = this->taintEngine->taintAssignment(fip_addr, fip);
6759 fcs_expr->isTainted = this->taintEngine->taintAssignment(fcs_addr, fcs);
6760 fdp_expr->isTainted = this->taintEngine->taintAssignment(fdp_addr, fdp);
6761 fds_expr->isTainted = this->taintEngine->taintAssignment(fds_addr, fds);
6762 mxcsr_expr->isTainted = this->taintEngine->taintAssignment(mxcsr_addr, mxcsr);
6763 mxcsr_mask_expr->isTainted = this->taintEngine->taintAssignment(mxcsr_mask_addr, mxcsr_mask);
6764 st0_expr->isTainted = this->taintEngine->taintAssignment(st0_addr, st0);
6765 st1_expr->isTainted = this->taintEngine->taintAssignment(st1_addr, st1);
6766 st2_expr->isTainted = this->taintEngine->taintAssignment(st2_addr, st2);
6767 st3_expr->isTainted = this->taintEngine->taintAssignment(st3_addr, st3);
6768 st4_expr->isTainted = this->taintEngine->taintAssignment(st4_addr, st4);
6769 st5_expr->isTainted = this->taintEngine->taintAssignment(st5_addr, st5);
6770 st6_expr->isTainted = this->taintEngine->taintAssignment(st6_addr, st6);
6771 st7_expr->isTainted = this->taintEngine->taintAssignment(st7_addr, st7);
6772 xmm0_expr->isTainted = this->taintEngine->taintAssignment(xmm0_addr, xmm0);
6773 xmm1_expr->isTainted = this->taintEngine->taintAssignment(xmm1_addr, xmm1);
6774 xmm2_expr->isTainted = this->taintEngine->taintAssignment(xmm2_addr, xmm2);
6775 xmm3_expr->isTainted = this->taintEngine->taintAssignment(xmm3_addr, xmm3);
6776 xmm4_expr->isTainted = this->taintEngine->taintAssignment(xmm4_addr, xmm4);
6777 xmm5_expr->isTainted = this->taintEngine->taintAssignment(xmm5_addr, xmm5);
6778 xmm6_expr->isTainted = this->taintEngine->taintAssignment(xmm6_addr, xmm6);
6779 xmm7_expr->isTainted = this->taintEngine->taintAssignment(xmm7_addr, xmm7);
6780
6781 /* Additional semantics, symbolic expressions and tainting for the '64-bit Mode Layout (with REX.W = 0)' */
6782 if (is64bits) {
6783 auto xmm8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM8));
6784 auto xmm9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM9));
6785 auto xmm10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM10));
6786 auto xmm11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM11));
6787 auto xmm12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM12));
6788 auto xmm13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM13));
6789 auto xmm14 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM14));
6790 auto xmm15 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM15));
6791
6792 auto xmm8_ast = this->symbolicEngine->getOperandAst(inst, xmm8);
6793 auto xmm9_ast = this->symbolicEngine->getOperandAst(inst, xmm9);
6794 auto xmm10_ast = this->symbolicEngine->getOperandAst(inst, xmm10);
6795 auto xmm11_ast = this->symbolicEngine->getOperandAst(inst, xmm11);
6796 auto xmm12_ast = this->symbolicEngine->getOperandAst(inst, xmm12);
6797 auto xmm13_ast = this->symbolicEngine->getOperandAst(inst, xmm13);
6798 auto xmm14_ast = this->symbolicEngine->getOperandAst(inst, xmm14);
6799 auto xmm15_ast = this->symbolicEngine->getOperandAst(inst, xmm15);
6800
6801 auto xmm8_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 288, xmm8.getSize()));
6802 auto xmm9_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 304, xmm9.getSize()));
6803 auto xmm10_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 320, xmm10.getSize()));
6804 auto xmm11_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 336, xmm11.getSize()));
6805 auto xmm12_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 352, xmm12.getSize()));
6806 auto xmm13_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 368, xmm13.getSize()));
6807 auto xmm14_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 384, xmm14.getSize()));
6808 auto xmm15_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 400, xmm15.getSize()));
6809
6810 /* Fetch the original values of the XMM8-XMM15 memory spaces */
6811 auto xmm8_orig = this->symbolicEngine->getOperandAst(xmm8_addr);
6812 auto xmm9_orig = this->symbolicEngine->getOperandAst(xmm9_addr);
6813 auto xmm10_orig = this->symbolicEngine->getOperandAst(xmm10_addr);
6814 auto xmm11_orig = this->symbolicEngine->getOperandAst(xmm11_addr);
6815 auto xmm12_orig = this->symbolicEngine->getOperandAst(xmm12_addr);
6816 auto xmm13_orig = this->symbolicEngine->getOperandAst(xmm13_addr);
6817 auto xmm14_orig = this->symbolicEngine->getOperandAst(xmm14_addr);
6818 auto xmm15_orig = this->symbolicEngine->getOperandAst(xmm15_addr);
6819
6820 /* Check if we are running in CPL = 0 (ring 0) and if the FFXSR bit is set in EFER */
6821 auto cpl = this->astCtxt->equal(this->astCtxt->extract(1, 0, cs_ast), this->astCtxt->bv(0, 2));
6822 auto ffx = this->astCtxt->equal(ffxsr_ast, this->astCtxt->bv(1, 1));
6823 auto is_fast = this->astCtxt->land(cpl, ffx);
6824
6825 /* Apply the fast save logic if needed */
6826 xmm8_ast = this->astCtxt->ite(is_fast, xmm8_orig, xmm8_ast);
6827 xmm9_ast = this->astCtxt->ite(is_fast, xmm9_orig, xmm9_ast);
6828 xmm10_ast = this->astCtxt->ite(is_fast, xmm10_orig, xmm10_ast);
6829 xmm11_ast = this->astCtxt->ite(is_fast, xmm11_orig, xmm11_ast);
6830 xmm12_ast = this->astCtxt->ite(is_fast, xmm12_orig, xmm12_ast);
6831 xmm13_ast = this->astCtxt->ite(is_fast, xmm13_orig, xmm13_ast);
6832 xmm14_ast = this->astCtxt->ite(is_fast, xmm14_orig, xmm14_ast);
6833 xmm15_ast = this->astCtxt->ite(is_fast, xmm15_orig, xmm15_ast);
6834
6835 auto xmm8_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm8_ast, xmm8_addr, "FXSAVE XMM8 operation");
6836 auto xmm9_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm9_ast, xmm9_addr, "FXSAVE XMM9 operation");
6837 auto xmm10_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm10_ast, xmm10_addr, "FXSAVE XMM10 operation");
6838 auto xmm11_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm11_ast, xmm11_addr, "FXSAVE XMM11 operation");
6839 auto xmm12_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm12_ast, xmm12_addr, "FXSAVE XMM12 operation");
6840 auto xmm13_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm13_ast, xmm13_addr, "FXSAVE XMM13 operation");
6841 auto xmm14_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm14_ast, xmm14_addr, "FXSAVE XMM14 operation");
6842 auto xmm15_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm15_ast, xmm15_addr, "FXSAVE XMM15 operation");
6843
6844 xmm8_expr->isTainted = this->taintEngine->taintAssignment(xmm8_addr, xmm8);
6845 xmm9_expr->isTainted = this->taintEngine->taintAssignment(xmm9_addr, xmm9);
6846 xmm10_expr->isTainted = this->taintEngine->taintAssignment(xmm10_addr, xmm10);
6847 xmm11_expr->isTainted = this->taintEngine->taintAssignment(xmm11_addr, xmm11);
6848 xmm12_expr->isTainted = this->taintEngine->taintAssignment(xmm12_addr, xmm12);
6849 xmm13_expr->isTainted = this->taintEngine->taintAssignment(xmm13_addr, xmm13);
6850 xmm14_expr->isTainted = this->taintEngine->taintAssignment(xmm14_addr, xmm14);
6851 xmm15_expr->isTainted = this->taintEngine->taintAssignment(xmm15_addr, xmm15);
6852 }
6853
6854 /* Update the symbolic control flow */
6855 this->controlFlow_s(inst);
6856 }
6857
6858
6859 void x86Semantics::fxsave64_s(triton::arch::Instruction& inst) {
6860 /* Fetch the memory operand */
6861 auto& dst = inst.operands[0];
6862 auto& mem = dst.getMemory();
6863 auto m512byte = mem.getAddress();
6864
6865 /* Check if the address is on a 16-byte boundary */
6866 if (m512byte & 0xF) {
6867 this->exception = triton::arch::FAULT_GP;
6868 return;
6869 }
6870
6871 /* Fetch the FPU, STX, SSE, EFER and CS implicit operands */
6872 auto fcw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FCW));
6873 auto fsw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FSW));
6874 auto ftw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FTW));
6875 auto fop = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FOP));
6876 auto fip = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FIP));
6877 auto fcs = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FCS));
6878 auto fdp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FDP));
6879 auto fds = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FDS));
6880 auto mxcsr = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR));
6881 auto mxcsr_mask = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR_MASK));
6882 auto st0 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST0));
6883 auto st1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST1));
6884 auto st2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST2));
6885 auto st3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST3));
6886 auto st4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST4));
6887 auto st5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST5));
6888 auto st6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST6));
6889 auto st7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST7));
6890 auto xmm0 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM0));
6891 auto xmm1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM1));
6892 auto xmm2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM2));
6893 auto xmm3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM3));
6894 auto xmm4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM4));
6895 auto xmm5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM5));
6896 auto xmm6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM6));
6897 auto xmm7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM7));
6898 auto xmm8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM8));
6899 auto xmm9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM9));
6900 auto xmm10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM10));
6901 auto xmm11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM11));
6902 auto xmm12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM12));
6903 auto xmm13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM13));
6904 auto xmm14 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM14));
6905 auto xmm15 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM15));
6906 auto ffxsr = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EFER_FFXSR));
6907 auto cs = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CS));
6908
6909 /* Create the symbolic operands */
6910 auto fcw_ast = this->symbolicEngine->getOperandAst(inst, fcw);
6911 auto fsw_ast = this->symbolicEngine->getOperandAst(inst, fsw);
6912 auto ftw_ast = this->symbolicEngine->getOperandAst(inst, ftw);
6913 auto fop_ast = this->symbolicEngine->getOperandAst(inst, fop);
6914 auto fip_ast = this->symbolicEngine->getOperandAst(inst, fip);
6915 auto fcs_ast = this->symbolicEngine->getOperandAst(inst, fcs);
6916 auto fdp_ast = this->symbolicEngine->getOperandAst(inst, fdp);
6917 auto fds_ast = this->symbolicEngine->getOperandAst(inst, fds);
6918 auto mxcsr_ast = this->symbolicEngine->getOperandAst(inst, mxcsr);
6919 auto mxcsr_mask_ast = this->symbolicEngine->getOperandAst(inst, mxcsr_mask);
6920 auto st0_ast = this->symbolicEngine->getOperandAst(inst, st0);
6921 auto st1_ast = this->symbolicEngine->getOperandAst(inst, st1);
6922 auto st2_ast = this->symbolicEngine->getOperandAst(inst, st2);
6923 auto st3_ast = this->symbolicEngine->getOperandAst(inst, st3);
6924 auto st4_ast = this->symbolicEngine->getOperandAst(inst, st4);
6925 auto st5_ast = this->symbolicEngine->getOperandAst(inst, st5);
6926 auto st6_ast = this->symbolicEngine->getOperandAst(inst, st6);
6927 auto st7_ast = this->symbolicEngine->getOperandAst(inst, st7);
6928 auto xmm0_ast = this->symbolicEngine->getOperandAst(inst, xmm0);
6929 auto xmm1_ast = this->symbolicEngine->getOperandAst(inst, xmm1);
6930 auto xmm2_ast = this->symbolicEngine->getOperandAst(inst, xmm2);
6931 auto xmm3_ast = this->symbolicEngine->getOperandAst(inst, xmm3);
6932 auto xmm4_ast = this->symbolicEngine->getOperandAst(inst, xmm4);
6933 auto xmm5_ast = this->symbolicEngine->getOperandAst(inst, xmm5);
6934 auto xmm6_ast = this->symbolicEngine->getOperandAst(inst, xmm6);
6935 auto xmm7_ast = this->symbolicEngine->getOperandAst(inst, xmm7);
6936 auto xmm8_ast = this->symbolicEngine->getOperandAst(inst, xmm8);
6937 auto xmm9_ast = this->symbolicEngine->getOperandAst(inst, xmm9);
6938 auto xmm10_ast = this->symbolicEngine->getOperandAst(inst, xmm10);
6939 auto xmm11_ast = this->symbolicEngine->getOperandAst(inst, xmm11);
6940 auto xmm12_ast = this->symbolicEngine->getOperandAst(inst, xmm12);
6941 auto xmm13_ast = this->symbolicEngine->getOperandAst(inst, xmm13);
6942 auto xmm14_ast = this->symbolicEngine->getOperandAst(inst, xmm14);
6943 auto xmm15_ast = this->symbolicEngine->getOperandAst(inst, xmm15);
6944 auto ffxsr_ast = this->symbolicEngine->getOperandAst(inst, ffxsr);
6945 auto cs_ast = this->symbolicEngine->getOperandAst(inst, cs);
6946
6947 /*
6948 Calculate the abridged x87 FPU Tag Word (from 2 bytes to 1 byte encoding)
6949 - Two-bit values of 00, 01, and 10 are encoded as a 1
6950 - A two-bit value of 11 is encoded as a 0
6951 */
6952 auto eb_1_0 = this->astCtxt->ite(
6953 this->astCtxt->equal(this->astCtxt->extract(1, 0, ftw_ast), this->astCtxt->bv(3, 2)),
6954 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6955
6956 auto eb_3_2 = this->astCtxt->ite(
6957 this->astCtxt->equal(this->astCtxt->extract(3, 2, ftw_ast), this->astCtxt->bv(3, 2)),
6958 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6959
6960 auto eb_5_4 = this->astCtxt->ite(
6961 this->astCtxt->equal(this->astCtxt->extract(5, 4, ftw_ast), this->astCtxt->bv(3, 2)),
6962 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6963
6964 auto eb_7_6 = this->astCtxt->ite(
6965 this->astCtxt->equal(this->astCtxt->extract(7, 6, ftw_ast), this->astCtxt->bv(3, 2)),
6966 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6967
6968 auto eb_9_8 = this->astCtxt->ite(
6969 this->astCtxt->equal(this->astCtxt->extract(9, 8, ftw_ast), this->astCtxt->bv(3, 2)),
6970 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6971
6972 auto eb_11_10 = this->astCtxt->ite(
6973 this->astCtxt->equal(this->astCtxt->extract(11, 10, ftw_ast), this->astCtxt->bv(3, 2)),
6974 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6975
6976 auto eb_13_12 = this->astCtxt->ite(
6977 this->astCtxt->equal(this->astCtxt->extract(13, 12, ftw_ast), this->astCtxt->bv(3, 2)),
6978 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6979
6980 auto eb_15_14 = this->astCtxt->ite(
6981 this->astCtxt->equal(this->astCtxt->extract(15, 14, ftw_ast), this->astCtxt->bv(3, 2)),
6982 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6983
6984 auto aftw_ast = this->astCtxt->concat(eb_15_14,
6985 this->astCtxt->concat(eb_13_12,
6986 this->astCtxt->concat(eb_11_10,
6987 this->astCtxt->concat(eb_9_8,
6988 this->astCtxt->concat(eb_7_6,
6989 this->astCtxt->concat(eb_5_4,
6990 this->astCtxt->concat(eb_3_2, eb_1_0)))))));
6991
6992 /* Fetch the implicit memory slots for the '64-bit Mode Layout (with REX.W = 1)' */
6993 auto fcw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 0, fcw.getSize()));
6994 auto fsw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 2, fsw.getSize()));
6995 auto ftw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 4, ftw.getSize() / 2));
6996 auto fop_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 6, fop.getSize()));
6997 auto fip_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 8, fip.getSize()));
6998 auto fcs_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 12, fcs.getSize()));
6999 auto fdp_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 16, fdp.getSize()));
7000 auto fds_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 20, fds.getSize()));
7001 auto mxcsr_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 24, mxcsr.getSize()));
7002 auto mxcsr_mask_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 28, mxcsr_mask.getSize()));
7003 auto st0_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 32, st0.getSize()));
7004 auto st1_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 48, st1.getSize()));
7005 auto st2_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 64, st2.getSize()));
7006 auto st3_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 80, st3.getSize()));
7007 auto st4_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 96, st4.getSize()));
7008 auto st5_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 112, st5.getSize()));
7009 auto st6_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 128, st6.getSize()));
7010 auto st7_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 144, st7.getSize()));
7011 auto xmm0_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 160, xmm0.getSize()));
7012 auto xmm1_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 176, xmm1.getSize()));
7013 auto xmm2_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 192, xmm2.getSize()));
7014 auto xmm3_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 208, xmm3.getSize()));
7015 auto xmm4_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 224, xmm4.getSize()));
7016 auto xmm5_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 240, xmm5.getSize()));
7017 auto xmm6_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 256, xmm6.getSize()));
7018 auto xmm7_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 272, xmm7.getSize()));
7019 auto xmm8_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 288, xmm8.getSize()));
7020 auto xmm9_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 304, xmm9.getSize()));
7021 auto xmm10_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 320, xmm10.getSize()));
7022 auto xmm11_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 336, xmm11.getSize()));
7023 auto xmm12_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 352, xmm12.getSize()));
7024 auto xmm13_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 368, xmm13.getSize()));
7025 auto xmm14_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 384, xmm14.getSize()));
7026 auto xmm15_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 400, xmm15.getSize()));
7027
7028 /* Fetch the original values of the XMM0-XMM7 memory spaces */
7029 auto xmm0_orig = this->symbolicEngine->getOperandAst(xmm0_addr);
7030 auto xmm1_orig = this->symbolicEngine->getOperandAst(xmm1_addr);
7031 auto xmm2_orig = this->symbolicEngine->getOperandAst(xmm2_addr);
7032 auto xmm3_orig = this->symbolicEngine->getOperandAst(xmm3_addr);
7033 auto xmm4_orig = this->symbolicEngine->getOperandAst(xmm4_addr);
7034 auto xmm5_orig = this->symbolicEngine->getOperandAst(xmm5_addr);
7035 auto xmm6_orig = this->symbolicEngine->getOperandAst(xmm6_addr);
7036 auto xmm7_orig = this->symbolicEngine->getOperandAst(xmm7_addr);
7037 auto xmm8_orig = this->symbolicEngine->getOperandAst(xmm8_addr);
7038 auto xmm9_orig = this->symbolicEngine->getOperandAst(xmm9_addr);
7039 auto xmm10_orig = this->symbolicEngine->getOperandAst(xmm10_addr);
7040 auto xmm11_orig = this->symbolicEngine->getOperandAst(xmm11_addr);
7041 auto xmm12_orig = this->symbolicEngine->getOperandAst(xmm12_addr);
7042 auto xmm13_orig = this->symbolicEngine->getOperandAst(xmm13_addr);
7043 auto xmm14_orig = this->symbolicEngine->getOperandAst(xmm14_addr);
7044 auto xmm15_orig = this->symbolicEngine->getOperandAst(xmm15_addr);
7045
7046 /* Check if we are running in CPL = 0 (ring 0) and if the FFXSR bit is set in EFER */
7047 auto cpl = this->astCtxt->equal(this->astCtxt->extract(1, 0, cs_ast), this->astCtxt->bv(0, 2));
7048 auto ffx = this->astCtxt->equal(ffxsr_ast, this->astCtxt->bv(1, 1));
7049 auto is_fast = this->astCtxt->land(cpl, ffx);
7050
7051 /* Apply the fast save logic if needed */
7052 xmm0_ast = this->astCtxt->ite(is_fast, xmm0_orig, xmm0_ast);
7053 xmm1_ast = this->astCtxt->ite(is_fast, xmm1_orig, xmm1_ast);
7054 xmm2_ast = this->astCtxt->ite(is_fast, xmm2_orig, xmm2_ast);
7055 xmm3_ast = this->astCtxt->ite(is_fast, xmm3_orig, xmm3_ast);
7056 xmm4_ast = this->astCtxt->ite(is_fast, xmm4_orig, xmm4_ast);
7057 xmm5_ast = this->astCtxt->ite(is_fast, xmm5_orig, xmm5_ast);
7058 xmm6_ast = this->astCtxt->ite(is_fast, xmm6_orig, xmm6_ast);
7059 xmm7_ast = this->astCtxt->ite(is_fast, xmm7_orig, xmm7_ast);
7060 xmm8_ast = this->astCtxt->ite(is_fast, xmm8_orig, xmm8_ast);
7061 xmm9_ast = this->astCtxt->ite(is_fast, xmm9_orig, xmm9_ast);
7062 xmm10_ast = this->astCtxt->ite(is_fast, xmm10_orig, xmm10_ast);
7063 xmm11_ast = this->astCtxt->ite(is_fast, xmm11_orig, xmm11_ast);
7064 xmm12_ast = this->astCtxt->ite(is_fast, xmm12_orig, xmm12_ast);
7065 xmm13_ast = this->astCtxt->ite(is_fast, xmm13_orig, xmm13_ast);
7066 xmm14_ast = this->astCtxt->ite(is_fast, xmm14_orig, xmm14_ast);
7067 xmm15_ast = this->astCtxt->ite(is_fast, xmm15_orig, xmm15_ast);
7068
7069 /* Craft the symbolic expressions */
7070 auto fcw_expr = this->symbolicEngine->createSymbolicExpression(inst, fcw_ast, fcw_addr, "FXSAVE64 FCW operation");
7071 auto fsw_expr = this->symbolicEngine->createSymbolicExpression(inst, fsw_ast, fsw_addr, "FXSAVE64 FSW operation");
7072 auto ftw_expr = this->symbolicEngine->createSymbolicExpression(inst, aftw_ast, ftw_addr, "FXSAVE64 Abridged FTW operation");
7073 auto fop_expr = this->symbolicEngine->createSymbolicExpression(inst, fop_ast, fop_addr, "FXSAVE64 FOP operation");
7074 auto fip_expr = this->symbolicEngine->createSymbolicExpression(inst, fip_ast, fip_addr, "FXSAVE64 FIP operation");
7075 auto fcs_expr = this->symbolicEngine->createSymbolicExpression(inst, fcs_ast, fcs_addr, "FXSAVE64 FCS operation");
7076 auto fdp_expr = this->symbolicEngine->createSymbolicExpression(inst, fdp_ast, fdp_addr, "FXSAVE64 FDP operation");
7077 auto fds_expr = this->symbolicEngine->createSymbolicExpression(inst, fds_ast, fds_addr, "FXSAVE64 FDS operation");
7078 auto mxcsr_expr = this->symbolicEngine->createSymbolicExpression(inst, mxcsr_ast, mxcsr_addr, "FXSAVE64 MXCSR operation");
7079 auto mxcsr_mask_expr = this->symbolicEngine->createSymbolicExpression(inst, mxcsr_mask_ast, mxcsr_mask_addr, "FXSAVE64 MXCSR_MASK operation");
7080 auto st0_expr = this->symbolicEngine->createSymbolicExpression(inst, st0_ast, st0_addr, "FXSAVE64 ST0 operation");
7081 auto st1_expr = this->symbolicEngine->createSymbolicExpression(inst, st1_ast, st1_addr, "FXSAVE64 ST1 operation");
7082 auto st2_expr = this->symbolicEngine->createSymbolicExpression(inst, st2_ast, st2_addr, "FXSAVE64 ST2 operation");
7083 auto st3_expr = this->symbolicEngine->createSymbolicExpression(inst, st3_ast, st3_addr, "FXSAVE64 ST3 operation");
7084 auto st4_expr = this->symbolicEngine->createSymbolicExpression(inst, st4_ast, st4_addr, "FXSAVE64 ST4 operation");
7085 auto st5_expr = this->symbolicEngine->createSymbolicExpression(inst, st5_ast, st5_addr, "FXSAVE64 ST5 operation");
7086 auto st6_expr = this->symbolicEngine->createSymbolicExpression(inst, st6_ast, st6_addr, "FXSAVE64 ST6 operation");
7087 auto st7_expr = this->symbolicEngine->createSymbolicExpression(inst, st7_ast, st7_addr, "FXSAVE64 ST7 operation");
7088 auto xmm0_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm0_ast, xmm0_addr, "FXSAVE64 XMM0 operation");
7089 auto xmm1_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm1_ast, xmm1_addr, "FXSAVE64 XMM1 operation");
7090 auto xmm2_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm2_ast, xmm2_addr, "FXSAVE64 XMM2 operation");
7091 auto xmm3_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm3_ast, xmm3_addr, "FXSAVE64 XMM3 operation");
7092 auto xmm4_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm4_ast, xmm4_addr, "FXSAVE64 XMM4 operation");
7093 auto xmm5_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm5_ast, xmm5_addr, "FXSAVE64 XMM5 operation");
7094 auto xmm6_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm6_ast, xmm6_addr, "FXSAVE64 XMM6 operation");
7095 auto xmm7_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm7_ast, xmm7_addr, "FXSAVE64 XMM7 operation");
7096 auto xmm8_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm8_ast, xmm8_addr, "FXSAVE64 XMM8 operation");
7097 auto xmm9_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm9_ast, xmm9_addr, "FXSAVE64 XMM9 operation");
7098 auto xmm10_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm10_ast, xmm10_addr, "FXSAVE64 XMM10 operation");
7099 auto xmm11_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm11_ast, xmm11_addr, "FXSAVE64 XMM11 operation");
7100 auto xmm12_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm12_ast, xmm12_addr, "FXSAVE64 XMM12 operation");
7101 auto xmm13_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm13_ast, xmm13_addr, "FXSAVE64 XMM13 operation");
7102 auto xmm14_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm14_ast, xmm14_addr, "FXSAVE64 XMM14 operation");
7103 auto xmm15_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm15_ast, xmm15_addr, "FXSAVE64 XMM15 operation");
7104
7105 /* Spread the taint */
7106 fcw_expr->isTainted = this->taintEngine->taintAssignment(fcw_addr, fcw);
7107 fsw_expr->isTainted = this->taintEngine->taintAssignment(fsw_addr, fsw);
7108 ftw_expr->isTainted = this->taintEngine->taintAssignment(ftw_addr, ftw);
7109 fop_expr->isTainted = this->taintEngine->taintAssignment(fop_addr, fop);
7110 fip_expr->isTainted = this->taintEngine->taintAssignment(fip_addr, fip);
7111 fcs_expr->isTainted = this->taintEngine->taintAssignment(fcs_addr, fcs);
7112 fdp_expr->isTainted = this->taintEngine->taintAssignment(fdp_addr, fdp);
7113 fds_expr->isTainted = this->taintEngine->taintAssignment(fds_addr, fds);
7114 mxcsr_expr->isTainted = this->taintEngine->taintAssignment(mxcsr_addr, mxcsr);
7115 mxcsr_mask_expr->isTainted = this->taintEngine->taintAssignment(mxcsr_mask_addr, mxcsr_mask);
7116 st0_expr->isTainted = this->taintEngine->taintAssignment(st0_addr, st0);
7117 st1_expr->isTainted = this->taintEngine->taintAssignment(st1_addr, st1);
7118 st2_expr->isTainted = this->taintEngine->taintAssignment(st2_addr, st2);
7119 st3_expr->isTainted = this->taintEngine->taintAssignment(st3_addr, st3);
7120 st4_expr->isTainted = this->taintEngine->taintAssignment(st4_addr, st4);
7121 st5_expr->isTainted = this->taintEngine->taintAssignment(st5_addr, st5);
7122 st6_expr->isTainted = this->taintEngine->taintAssignment(st6_addr, st6);
7123 st7_expr->isTainted = this->taintEngine->taintAssignment(st7_addr, st7);
7124 xmm0_expr->isTainted = this->taintEngine->taintAssignment(xmm0_addr, xmm0);
7125 xmm1_expr->isTainted = this->taintEngine->taintAssignment(xmm1_addr, xmm1);
7126 xmm2_expr->isTainted = this->taintEngine->taintAssignment(xmm2_addr, xmm2);
7127 xmm3_expr->isTainted = this->taintEngine->taintAssignment(xmm3_addr, xmm3);
7128 xmm4_expr->isTainted = this->taintEngine->taintAssignment(xmm4_addr, xmm4);
7129 xmm5_expr->isTainted = this->taintEngine->taintAssignment(xmm5_addr, xmm5);
7130 xmm6_expr->isTainted = this->taintEngine->taintAssignment(xmm6_addr, xmm6);
7131 xmm7_expr->isTainted = this->taintEngine->taintAssignment(xmm7_addr, xmm7);
7132 xmm8_expr->isTainted = this->taintEngine->taintAssignment(xmm8_addr, xmm8);
7133 xmm9_expr->isTainted = this->taintEngine->taintAssignment(xmm9_addr, xmm9);
7134 xmm10_expr->isTainted = this->taintEngine->taintAssignment(xmm10_addr, xmm10);
7135 xmm11_expr->isTainted = this->taintEngine->taintAssignment(xmm11_addr, xmm11);
7136 xmm12_expr->isTainted = this->taintEngine->taintAssignment(xmm12_addr, xmm12);
7137 xmm13_expr->isTainted = this->taintEngine->taintAssignment(xmm13_addr, xmm13);
7138 xmm14_expr->isTainted = this->taintEngine->taintAssignment(xmm14_addr, xmm14);
7139 xmm15_expr->isTainted = this->taintEngine->taintAssignment(xmm15_addr, xmm15);
7140
7141 /* Update the symbolic control flow */
7142 this->controlFlow_s(inst);
7143 }
7144
7145
7146 void x86Semantics::idiv_s(triton::arch::Instruction& inst) {
7147 auto& src = inst.operands[0];
7148
7149 /* Create symbolic operands */
7150 auto divisor = this->symbolicEngine->getOperandAst(inst, src);
7151
7152 /* Create symbolic expression */
7153 switch (src.getSize()) {
7154
7155 case triton::size::byte: {
7156 /* AX */
7157 auto ax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
7158 auto dividend = this->symbolicEngine->getOperandAst(inst, ax);
7159 /* res = AX / Source */
7160 auto result = this->astCtxt->bvsdiv(dividend, this->astCtxt->sx(triton::bitsize::byte, divisor));
7161 /* mod = AX % Source */
7162 auto mod = this->astCtxt->bvsrem(dividend, this->astCtxt->sx(triton::bitsize::byte, divisor));
7163 /* AH = mod */
7164 /* AL = res */
7165 auto node = this->astCtxt->concat(
7166 this->astCtxt->extract((triton::bitsize::byte - 1), 0, mod), /* AH = mod */
7167 this->astCtxt->extract((triton::bitsize::byte - 1), 0, result) /* AL = res */
7168 );
7169 /* Create symbolic expression */
7170 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, ax, "IDIV operation");
7171 /* Apply the taint */
7172 expr->isTainted = this->taintEngine->taintUnion(ax, src);
7173 break;
7174 }
7175
7176 case triton::size::word: {
7177 /* DX:AX */
7178 auto dx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DX));
7179 auto ax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
7180 auto dividend = this->astCtxt->concat(this->symbolicEngine->getOperandAst(inst, dx), this->symbolicEngine->getOperandAst(inst, ax));
7181 /* res = DX:AX / Source */
7182 auto temp = this->astCtxt->bvsdiv(dividend, this->astCtxt->sx(triton::bitsize::word, divisor));
7183 auto result = this->astCtxt->extract((triton::bitsize::word - 1), 0, temp);
7184 /* mod = DX:AX % Source */
7185 auto mod = this->astCtxt->extract((triton::bitsize::word - 1), 0, this->astCtxt->bvsrem(dividend, this->astCtxt->sx(triton::bitsize::word, divisor)));
7186 /* Create the symbolic expression for AX */
7187 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, result, ax, "IDIV operation");
7188 /* Apply the taint for AX */
7189 expr1->isTainted = this->taintEngine->taintUnion(ax, src);
7190 /* Create the symbolic expression for DX */
7191 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, mod, dx, "IDIV operation");
7192 /* Apply the taint for DX */
7193 expr2->isTainted = this->taintEngine->taintUnion(dx, src);
7194 break;
7195 }
7196
7197 case triton::size::dword: {
7198 /* EDX:EAX */
7199 auto edx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
7200 auto eax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
7201 auto dividend = this->astCtxt->concat(this->symbolicEngine->getOperandAst(inst, edx), this->symbolicEngine->getOperandAst(inst, eax));
7202 /* res = EDX:EAX / Source */
7203 auto temp = this->astCtxt->bvsdiv(dividend, this->astCtxt->sx(triton::bitsize::dword, divisor));
7204 auto result = this->astCtxt->extract((triton::bitsize::dword - 1), 0, temp);
7205 /* mod = EDX:EAX % Source */
7206 auto mod = this->astCtxt->extract((triton::bitsize::dword - 1), 0, this->astCtxt->bvsrem(dividend, this->astCtxt->sx(triton::bitsize::dword, divisor)));
7207 /* Create the symbolic expression for EAX */
7208 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, result, eax, "IDIV operation");
7209 /* Apply the taint for EAX */
7210 expr1->isTainted = this->taintEngine->taintUnion(eax, src);
7211 /* Create the symbolic expression for EDX */
7212 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, mod, edx, "IDIV operation");
7213 /* Apply the taint for EDX */
7214 expr2->isTainted = this->taintEngine->taintUnion(edx, src);
7215 break;
7216 }
7217
7218 case triton::size::qword: {
7219 /* RDX:RAX */
7220 auto rdx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX));
7221 auto rax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX));
7222 auto dividend = this->astCtxt->concat(this->symbolicEngine->getOperandAst(inst, rdx), this->symbolicEngine->getOperandAst(inst, rax));
7223 /* res = RDX:RAX / Source */
7224 auto temp = this->astCtxt->bvsdiv(dividend, this->astCtxt->sx(triton::bitsize::qword, divisor));
7225 auto result = this->astCtxt->extract((triton::bitsize::qword - 1), 0, temp);
7226 /* mod = RDX:RAX % Source */
7227 auto mod = this->astCtxt->extract((triton::bitsize::qword - 1), 0, this->astCtxt->bvsrem(dividend, this->astCtxt->sx(triton::bitsize::qword, divisor)));
7228 /* Create the symbolic expression for RAX */
7229 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, result, rax, "IDIV operation");
7230 /* Apply the taint for EAX */
7231 expr1->isTainted = this->taintEngine->taintUnion(rax, src);
7232 /* Create the symbolic expression for RDX */
7233 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, mod, rdx, "IDIV operation");
7234 /* Apply the taint for EDX */
7235 expr2->isTainted = this->taintEngine->taintUnion(rdx, src);
7236 break;
7237 }
7238
7239 }
7240
7241 /* Tag undefined flags */
7242 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
7243 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
7244 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
7245 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
7246 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
7247 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF));
7248
7249 /* Return an exception if the divisor is zero */
7250 if (divisor->evaluate() == 0) {
7251 this->exception = triton::arch::FAULT_DE;
7252 return;
7253 }
7254
7255 /* Update the symbolic control flow */
7256 this->controlFlow_s(inst);
7257 }
7258
7259
7260 void x86Semantics::imul_s(triton::arch::Instruction& inst) {
7261 switch (inst.operands.size()) {
7262
7263 /* one operand */
7264 case 1: {
7265 auto& src = inst.operands[0];
7266
7267 /* size of the Operand */
7268 switch (src.getSize()) {
7269
7270 /* dst = AX */
7271 case triton::size::byte: {
7272 auto ax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
7273 auto al = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
7274 auto op1 = this->symbolicEngine->getOperandAst(inst, al);
7275 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
7276 auto node = this->astCtxt->bvmul(this->astCtxt->sx(triton::bitsize::byte, op1), this->astCtxt->sx(triton::bitsize::byte, op2));
7277 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, ax, "IMUL operation");
7278 expr->isTainted = this->taintEngine->taintUnion(ax, src);
7279 this->cfImul_s(inst, expr, al, this->astCtxt->bvmul(op1, op2), node);
7280 this->ofImul_s(inst, expr, al, this->astCtxt->bvmul(op1, op2), node);
7281 break;
7282 }
7283
7284 /* dst = DX:AX */
7285 case triton::size::word: {
7286 auto ax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
7287 auto dx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DX));
7288 auto op1 = this->symbolicEngine->getOperandAst(inst, ax);
7289 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
7290 auto node1 = this->astCtxt->bvmul(op1, op2);
7291 auto node2 = this->astCtxt->bvmul(this->astCtxt->sx(triton::bitsize::word, op1), this->astCtxt->sx(triton::bitsize::word, op2));
7292 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, ax, "IMUL operation");
7293 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(triton::bitsize::dword-1, triton::bitsize::word, node2), dx, "IMUL operation");
7294 expr1->isTainted = this->taintEngine->taintUnion(ax, src);
7295 expr2->isTainted = this->taintEngine->taintUnion(dx, ax);
7296 this->cfImul_s(inst, expr1, ax, node1, node2);
7297 this->ofImul_s(inst, expr1, ax, node1, node2);
7298 break;
7299 }
7300
7301 /* dst = EDX:EAX */
7302 case triton::size::dword: {
7303 auto eax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
7304 auto edx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
7305 auto op1 = this->symbolicEngine->getOperandAst(inst, eax);
7306 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
7307 auto node1 = this->astCtxt->bvmul(op1, op2);
7308 auto node2 = this->astCtxt->bvmul(this->astCtxt->sx(triton::bitsize::dword, op1), this->astCtxt->sx(triton::bitsize::dword, op2));
7309 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, eax, "IMUL operation");
7310 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(triton::bitsize::qword-1, triton::bitsize::dword, node2), edx, "IMUL operation");
7311 expr1->isTainted = this->taintEngine->taintUnion(eax, src);
7312 expr2->isTainted = this->taintEngine->taintUnion(edx, eax);
7313 this->cfImul_s(inst, expr1, eax, node1, node2);
7314 this->ofImul_s(inst, expr1, eax, node1, node2);
7315 break;
7316 }
7317
7318 /* dst = RDX:RAX */
7319 case triton::size::qword: {
7320 auto rax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX));
7321 auto rdx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX));
7322 auto op1 = this->symbolicEngine->getOperandAst(inst, rax);
7323 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
7324 auto node1 = this->astCtxt->bvmul(op1, op2);
7325 auto node2 = this->astCtxt->bvmul(this->astCtxt->sx(triton::bitsize::qword, op1), this->astCtxt->sx(triton::bitsize::qword, op2));
7326 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, rax, "IMUL operation");
7327 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(triton::bitsize::dqword-1, triton::bitsize::qword, node2), rdx, "IMUL operation");
7328 expr1->isTainted = this->taintEngine->taintUnion(rax, src);
7329 expr2->isTainted = this->taintEngine->taintUnion(rdx, rax);
7330 this->cfImul_s(inst, expr1, rax, node1, node2);
7331 this->ofImul_s(inst, expr1, rax, node1, node2);
7332 break;
7333 }
7334
7335 }
7336 break;
7337 }
7338
7339 /* two operands */
7340 case 2: {
7341 auto& dst = inst.operands[0];
7342 auto& src = inst.operands[1];
7343 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
7344 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
7345 auto node1 = this->astCtxt->bvmul(op1, op2);
7346 auto node2 = this->astCtxt->bvmul(this->astCtxt->sx(dst.getBitSize(), op1), this->astCtxt->sx(src.getBitSize(), op2));
7347 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "IMUL operation");
7348 expr->isTainted = this->taintEngine->taintUnion(dst, src);
7349 this->cfImul_s(inst, expr, dst, node1, node2);
7350 this->ofImul_s(inst, expr, dst, node1, node2);
7351 break;
7352 }
7353
7354 /* three operands */
7355 case 3: {
7356 auto& dst = inst.operands[0];
7357 auto& src1 = inst.operands[1];
7358 auto& src2 = inst.operands[2];
7359 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
7360 auto op3 = this->astCtxt->sx(src1.getBitSize() - src2.getBitSize(), this->symbolicEngine->getOperandAst(inst, src2));
7361 auto node1 = this->astCtxt->bvmul(op2, op3);
7362 auto node2 = this->astCtxt->bvmul(this->astCtxt->sx(src1.getBitSize(), op2), this->astCtxt->sx(src2.getBitSize(), op3));
7363 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "IMUL operation");
7364 expr->isTainted = this->taintEngine->setTaint(dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
7365 this->cfImul_s(inst, expr, dst, node1, node2);
7366 this->ofImul_s(inst, expr, dst, node1, node2);
7367 break;
7368 }
7369
7370 }
7371
7372 /* Tag undefined flags */
7373 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
7374 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
7375 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
7376 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF));
7377
7378 /* Update the symbolic control flow */
7379 this->controlFlow_s(inst);
7380 }
7381
7382
7383 void x86Semantics::inc_s(triton::arch::Instruction& inst) {
7384 auto& dst = inst.operands[0];
7385
7386 /* Create symbolic operands */
7387 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
7388 auto op2 = this->astCtxt->bv(1, dst.getBitSize());
7389
7390 /* Create the semantics */
7391 auto node = this->astCtxt->bvadd(op1, op2);
7392
7393 /* Create symbolic expression */
7394 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "INC operation");
7395
7396 /* Spread taint */
7397 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
7398
7399 /* Update symbolic flags */
7400 this->af_s(inst, expr, dst, op1, op2);
7401 this->ofAdd_s(inst, expr, dst, op1, op2);
7402 this->pf_s(inst, expr, dst);
7403 this->sf_s(inst, expr, dst);
7404 this->zf_s(inst, expr, dst);
7405
7406 /* Update the symbolic control flow */
7407 this->controlFlow_s(inst);
7408 }
7409
7410
7411 void x86Semantics::invd_s(triton::arch::Instruction& inst) {
7412 /* Update the symbolic control flow */
7413 this->controlFlow_s(inst);
7414 }
7415
7416
7417 void x86Semantics::invlpg_s(triton::arch::Instruction& inst) {
7418 /* Update the symbolic control flow */
7419 this->controlFlow_s(inst);
7420 }
7421
7422
7423 void x86Semantics::ja_s(triton::arch::Instruction& inst) {
7424 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7425 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
7426 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
7427 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7428 auto& srcImm2 = inst.operands[0];
7429
7430 /* Create symbolic operands */
7431 auto op1 = this->symbolicEngine->getOperandAst(inst, cf);
7432 auto op2 = this->symbolicEngine->getOperandAst(inst, zf);
7433 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7434 auto op4 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7435
7436 /* Create the semantics */
7437 auto node = this->astCtxt->ite(
7438 this->astCtxt->equal(
7439 this->astCtxt->bvand(
7440 this->astCtxt->bvnot(op1),
7441 this->astCtxt->bvnot(op2)
7442 ),
7443 this->astCtxt->bvtrue()
7444 ), op4, op3);
7445
7446 /* Create symbolic expression */
7447 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7448
7449 /* Set condition flag */
7450 if (op1->evaluate().is_zero() && op2->evaluate().is_zero())
7451 inst.setConditionTaken(true);
7452
7453 /* Spread taint */
7454 expr->isTainted = this->taintEngine->taintAssignment(pc, cf);
7455 expr->isTainted = this->taintEngine->taintUnion(pc, zf);
7456
7457 /* Create the path constraint */
7458 this->symbolicEngine->pushPathConstraint(inst, expr);
7459 }
7460
7461
7462 void x86Semantics::jae_s(triton::arch::Instruction& inst) {
7463 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7464 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
7465 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7466 auto& srcImm2 = inst.operands[0];
7467
7468 /* Create symbolic operands */
7469 auto op1 = this->symbolicEngine->getOperandAst(inst, cf);
7470 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7471 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7472
7473 /* Create the semantics */
7474 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvfalse()), op3, op2);
7475
7476 /* Create symbolic expression */
7477 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7478
7479 /* Set condition flag */
7480 if (op1->evaluate().is_zero())
7481 inst.setConditionTaken(true);
7482
7483 /* Spread taint */
7484 expr->isTainted = this->taintEngine->taintAssignment(pc, cf);
7485
7486 /* Create the path constraint */
7487 this->symbolicEngine->pushPathConstraint(inst, expr);
7488 }
7489
7490
7491 void x86Semantics::jb_s(triton::arch::Instruction& inst) {
7492 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7493 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
7494 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7495 auto& srcImm2 = inst.operands[0];
7496
7497 /* Create symbolic operands */
7498 auto op1 = this->symbolicEngine->getOperandAst(inst, cf);
7499 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7500 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7501
7502 /* Create the semantics */
7503 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvtrue()), op3, op2);
7504
7505 /* Create symbolic expression */
7506 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7507
7508 /* Set condition flag */
7509 if (!op1->evaluate().is_zero())
7510 inst.setConditionTaken(true);
7511
7512 /* Spread taint */
7513 expr->isTainted = this->taintEngine->taintAssignment(pc, cf);
7514
7515 /* Create the path constraint */
7516 this->symbolicEngine->pushPathConstraint(inst, expr);
7517 }
7518
7519
7520 void x86Semantics::jbe_s(triton::arch::Instruction& inst) {
7521 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7522 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
7523 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
7524 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7525 auto& srcImm2 = inst.operands[0];
7526
7527 /* Create symbolic operands */
7528 auto op1 = this->symbolicEngine->getOperandAst(inst, cf);
7529 auto op2 = this->symbolicEngine->getOperandAst(inst, zf);
7530 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7531 auto op4 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7532
7533 /* Create the semantics */
7534 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvor(op1, op2), this->astCtxt->bvtrue()), op4, op3);
7535
7536 /* Create symbolic expression */
7537 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7538
7539 /* Set condition flag */
7540 if (!op1->evaluate().is_zero() || !op2->evaluate().is_zero())
7541 inst.setConditionTaken(true);
7542
7543 /* Spread taint */
7544 expr->isTainted = this->taintEngine->taintAssignment(pc, cf);
7545 expr->isTainted = this->taintEngine->taintUnion(pc, zf);
7546
7547 /* Create the path constraint */
7548 this->symbolicEngine->pushPathConstraint(inst, expr);
7549 }
7550
7551
7552 void x86Semantics::jcxz_s(triton::arch::Instruction& inst) {
7553 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7554 auto cx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CX));
7555 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7556 auto& srcImm2 = inst.operands[0];
7557
7558 /* Create symbolic operands */
7559 auto op1 = this->symbolicEngine->getOperandAst(inst, cx);
7560 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7561 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7562
7563 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bv(0, triton::bitsize::word)), op3, op2);
7564
7565 /* Create symbolic expression */
7566 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7567
7568 /* Set condition flag */
7569 if (!op1->evaluate().is_zero())
7570 inst.setConditionTaken(true);
7571
7572 /* Spread taint */
7573 expr->isTainted = this->taintEngine->taintAssignment(pc, cx);
7574
7575 /* Create the path constraint */
7576 this->symbolicEngine->pushPathConstraint(inst, expr);
7577 }
7578
7579
7580 void x86Semantics::je_s(triton::arch::Instruction& inst) {
7581 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7582 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
7583 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7584 auto& srcImm2 = inst.operands[0];
7585
7586 /* Create symbolic operands */
7587 auto op1 = this->symbolicEngine->getOperandAst(inst, zf);
7588 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7589 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7590
7591 /* Create the semantics */
7592 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvtrue()), op3, op2);
7593
7594 /* Create symbolic expression */
7595 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7596
7597 /* Set condition flag */
7598 if (!op1->evaluate().is_zero())
7599 inst.setConditionTaken(true);
7600
7601 /* Spread taint */
7602 expr->isTainted = this->taintEngine->taintAssignment(pc, zf);
7603
7604 /* Create the path constraint */
7605 this->symbolicEngine->pushPathConstraint(inst, expr);
7606 }
7607
7608
7609 void x86Semantics::jecxz_s(triton::arch::Instruction& inst) {
7610 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7611 auto ecx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ECX));
7612 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7613 auto& srcImm2 = inst.operands[0];
7614
7615 /* Create symbolic operands */
7616 auto op1 = this->symbolicEngine->getOperandAst(inst, ecx);
7617 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7618 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7619
7620 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bv(0, triton::bitsize::dword)), op3, op2);
7621
7622 /* Create symbolic expression */
7623 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7624
7625 /* Set condition flag */
7626 if (!op1->evaluate().is_zero())
7627 inst.setConditionTaken(true);
7628
7629 /* Spread taint */
7630 expr->isTainted = this->taintEngine->taintAssignment(pc, ecx);
7631
7632 /* Create the path constraint */
7633 this->symbolicEngine->pushPathConstraint(inst, expr);
7634 }
7635
7636
7637 void x86Semantics::jg_s(triton::arch::Instruction& inst) {
7638 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7639 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
7640 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
7641 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
7642 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7643 auto& srcImm2 = inst.operands[0];
7644
7645 /* Create symbolic operands */
7646 auto op1 = this->symbolicEngine->getOperandAst(inst, sf);
7647 auto op2 = this->symbolicEngine->getOperandAst(inst, of);
7648 auto op3 = this->symbolicEngine->getOperandAst(inst, zf);
7649 auto op4 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7650 auto op5 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7651
7652 /* Create the semantics */
7653 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvor(this->astCtxt->bvxor(op1, op2), op3), this->astCtxt->bvfalse()), op5, op4);
7654
7655 /* Create symbolic expression */
7656 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7657
7658 /* Set condition flag */
7659 if ((op1->evaluate().is_zero() == op2->evaluate().is_zero()) && op3->evaluate().is_zero())
7660 inst.setConditionTaken(true);
7661
7662 /* Spread taint */
7663 expr->isTainted = this->taintEngine->taintAssignment(pc, sf);
7664 expr->isTainted = this->taintEngine->taintUnion(pc, of);
7665 expr->isTainted = this->taintEngine->taintUnion(pc, zf);
7666
7667 /* Create the path constraint */
7668 this->symbolicEngine->pushPathConstraint(inst, expr);
7669 }
7670
7671
7672 void x86Semantics::jge_s(triton::arch::Instruction& inst) {
7673 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7674 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
7675 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
7676 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7677 auto& srcImm2 = inst.operands[0];
7678
7679 /* Create symbolic operands */
7680 auto op1 = this->symbolicEngine->getOperandAst(inst, sf);
7681 auto op2 = this->symbolicEngine->getOperandAst(inst, of);
7682 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7683 auto op4 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7684
7685 /* Create the semantics */
7686 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, op2), op4, op3);
7687
7688 /* Create symbolic expression */
7689 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7690
7691 /* Set condition flag */
7692 if (op1->evaluate().is_zero() == op2->evaluate().is_zero())
7693 inst.setConditionTaken(true);
7694
7695 /* Spread taint */
7696 expr->isTainted = this->taintEngine->taintAssignment(pc, sf);
7697 expr->isTainted = this->taintEngine->taintUnion(pc, of);
7698
7699 /* Create the path constraint */
7700 this->symbolicEngine->pushPathConstraint(inst, expr);
7701 }
7702
7703
7704 void x86Semantics::jl_s(triton::arch::Instruction& inst) {
7705 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7706 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
7707 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
7708 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7709 auto& srcImm2 = inst.operands[0];
7710
7711 /* Create symbolic operands */
7712 auto op1 = this->symbolicEngine->getOperandAst(inst, sf);
7713 auto op2 = this->symbolicEngine->getOperandAst(inst, of);
7714 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7715 auto op4 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7716
7717 /* Create the semantics */
7718 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvxor(op1, op2), this->astCtxt->bvtrue()), op4, op3);
7719
7720 /* Create symbolic expression */
7721 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7722
7723 /* Set condition flag */
7724 if (op1->evaluate().is_zero() != op2->evaluate().is_zero())
7725 inst.setConditionTaken(true);
7726
7727 /* Spread taint */
7728 expr->isTainted = this->taintEngine->taintAssignment(pc, sf);
7729 expr->isTainted = this->taintEngine->taintUnion(pc, of);
7730
7731 /* Create the path constraint */
7732 this->symbolicEngine->pushPathConstraint(inst, expr);
7733 }
7734
7735
7736 void x86Semantics::jle_s(triton::arch::Instruction& inst) {
7737 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7738 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
7739 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
7740 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
7741 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7742 auto& srcImm2 = inst.operands[0];
7743
7744 /* Create symbolic operands */
7745 auto op1 = this->symbolicEngine->getOperandAst(inst, sf);
7746 auto op2 = this->symbolicEngine->getOperandAst(inst, of);
7747 auto op3 = this->symbolicEngine->getOperandAst(inst, zf);
7748 auto op4 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7749 auto op5 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7750
7751 /* Create the semantics */
7752 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvor(this->astCtxt->bvxor(op1, op2), op3), this->astCtxt->bvtrue()), op5, op4);
7753
7754 /* Create symbolic expression */
7755 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7756
7757 /* Set condition flag */
7758 if ((op1->evaluate().is_zero() != op2->evaluate().is_zero()) || !op3->evaluate().is_zero())
7759 inst.setConditionTaken(true);
7760
7761 /* Spread taint */
7762 expr->isTainted = this->taintEngine->taintAssignment(pc, sf);
7763 expr->isTainted = this->taintEngine->taintUnion(pc, of);
7764 expr->isTainted = this->taintEngine->taintUnion(pc, zf);
7765
7766 /* Create the path constraint */
7767 this->symbolicEngine->pushPathConstraint(inst, expr);
7768 }
7769
7770
7771 void x86Semantics::jmp_s(triton::arch::Instruction& inst) {
7772 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7773 auto& src = inst.operands[0];
7774
7775 /* Create symbolic operands */
7776 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
7777
7778 /* Create the semantics */
7779 auto node = op1;
7780
7781 /* Create symbolic expression */
7782 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7783
7784 /* Set condition flag */
7785 inst.setConditionTaken(true);
7786
7787 /* Spread taint */
7788 expr->isTainted = this->taintEngine->taintAssignment(pc, src);
7789
7790 /* Create the path constraint */
7791 this->symbolicEngine->pushPathConstraint(inst, expr);
7792 }
7793
7794
7795 void x86Semantics::jne_s(triton::arch::Instruction& inst) {
7796 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7797 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
7798 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7799 auto& srcImm2 = inst.operands[0];
7800
7801 /* Create symbolic operands */
7802 auto op1 = this->symbolicEngine->getOperandAst(inst, zf);
7803 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7804 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7805
7806 /* Create the semantics */
7807 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvfalse()), op3, op2);
7808
7809 /* Create symbolic expression */
7810 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7811
7812 /* Set condition flag */
7813 if (op1->evaluate().is_zero())
7814 inst.setConditionTaken(true);
7815
7816 /* Spread taint */
7817 expr->isTainted = this->taintEngine->taintAssignment(pc, zf);
7818
7819 /* Create the path constraint */
7820 this->symbolicEngine->pushPathConstraint(inst, expr);
7821 }
7822
7823
7824 void x86Semantics::jno_s(triton::arch::Instruction& inst) {
7825 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7826 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
7827 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7828 auto& srcImm2 = inst.operands[0];
7829
7830 /* Create symbolic operands */
7831 auto op1 = this->symbolicEngine->getOperandAst(inst, of);
7832 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7833 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7834
7835 /* Create the semantics */
7836 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvfalse()), op3, op2);
7837
7838 /* Create symbolic expression */
7839 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7840
7841 /* Set condition flag */
7842 if (op1->evaluate().is_zero())
7843 inst.setConditionTaken(true);
7844
7845 /* Spread taint */
7846 expr->isTainted = this->taintEngine->taintAssignment(pc, of);
7847
7848 /* Create the path constraint */
7849 this->symbolicEngine->pushPathConstraint(inst, expr);
7850 }
7851
7852
7853 void x86Semantics::jnp_s(triton::arch::Instruction& inst) {
7854 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7855 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
7856 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7857 auto& srcImm2 = inst.operands[0];
7858
7859 /* Create symbolic operands */
7860 auto op1 = this->symbolicEngine->getOperandAst(inst, pf);
7861 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7862 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7863
7864 /* Create the semantics */
7865 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvfalse()), op3, op2);
7866
7867 /* Create symbolic expression */
7868 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7869
7870 /* Set condition flag */
7871 if (op1->evaluate().is_zero())
7872 inst.setConditionTaken(true);
7873
7874 /* Spread taint */
7875 expr->isTainted = this->taintEngine->taintAssignment(pc, pf);
7876
7877 /* Create the path constraint */
7878 this->symbolicEngine->pushPathConstraint(inst, expr);
7879 }
7880
7881
7882 void x86Semantics::jns_s(triton::arch::Instruction& inst) {
7883 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7884 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
7885 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7886 auto& srcImm2 = inst.operands[0];
7887
7888 /* Create symbolic operands */
7889 auto op1 = this->symbolicEngine->getOperandAst(inst, sf);
7890 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7891 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7892
7893 /* Create the semantics */
7894 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvfalse()), op3, op2);
7895
7896 /* Create symbolic expression */
7897 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7898
7899 /* Set condition flag */
7900 if (op1->evaluate().is_zero())
7901 inst.setConditionTaken(true);
7902
7903 /* Spread taint */
7904 expr->isTainted = this->taintEngine->taintAssignment(pc, sf);
7905
7906 /* Create the path constraint */
7907 this->symbolicEngine->pushPathConstraint(inst, expr);
7908 }
7909
7910
7911 void x86Semantics::jo_s(triton::arch::Instruction& inst) {
7912 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7913 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
7914 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7915 auto& srcImm2 = inst.operands[0];
7916
7917 /* Create symbolic operands */
7918 auto op1 = this->symbolicEngine->getOperandAst(inst, of);
7919 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7920 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7921
7922 /* Create the semantics */
7923 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvtrue()), op3, op2);
7924
7925 /* Create symbolic expression */
7926 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7927
7928 /* Set condition flag */
7929 if (!op1->evaluate().is_zero())
7930 inst.setConditionTaken(true);
7931
7932 /* Spread taint */
7933 expr->isTainted = this->taintEngine->taintAssignment(pc, of);
7934
7935 /* Create the path constraint */
7936 this->symbolicEngine->pushPathConstraint(inst, expr);
7937 }
7938
7939
7940 void x86Semantics::jp_s(triton::arch::Instruction& inst) {
7941 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7942 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
7943 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7944 auto& srcImm2 = inst.operands[0];
7945
7946 /* Create symbolic operands */
7947 auto op1 = this->symbolicEngine->getOperandAst(inst, pf);
7948 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7949 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7950
7951 /* Create the semantics */
7952 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvtrue()), op3, op2);
7953
7954 /* Create symbolic expression */
7955 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7956
7957 /* Set condition flag */
7958 if (!op1->evaluate().is_zero())
7959 inst.setConditionTaken(true);
7960
7961 /* Spread taint */
7962 expr->isTainted = this->taintEngine->taintAssignment(pc, pf);
7963
7964 /* Create the path constraint */
7965 this->symbolicEngine->pushPathConstraint(inst, expr);
7966 }
7967
7968
7969 void x86Semantics::jrcxz_s(triton::arch::Instruction& inst) {
7970 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7971 auto rcx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RCX));
7972 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7973 auto& srcImm2 = inst.operands[0];
7974
7975 /* Create symbolic operands */
7976 auto op1 = this->symbolicEngine->getOperandAst(inst, rcx);
7977 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7978 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7979
7980 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bv(0, triton::bitsize::qword)), op3, op2);
7981
7982 /* Create symbolic expression */
7983 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7984
7985 /* Set condition flag */
7986 if (!op1->evaluate().is_zero())
7987 inst.setConditionTaken(true);
7988
7989 /* Spread taint */
7990 expr->isTainted = this->taintEngine->taintAssignment(pc, rcx);
7991
7992 /* Create the path constraint */
7993 this->symbolicEngine->pushPathConstraint(inst, expr);
7994 }
7995
7996
7997 void x86Semantics::js_s(triton::arch::Instruction& inst) {
7998 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7999 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
8000 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
8001 auto& srcImm2 = inst.operands[0];
8002
8003 /* Create symbolic operands */
8004 auto op1 = this->symbolicEngine->getOperandAst(inst, sf);
8005 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
8006 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
8007
8008 /* Create the semantics */
8009 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvtrue()), op3, op2);
8010
8011 /* Create symbolic expression */
8012 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
8013
8014 /* Set condition flag */
8015 if (!op1->evaluate().is_zero())
8016 inst.setConditionTaken(true);
8017
8018 /* Spread taint */
8019 expr->isTainted = this->taintEngine->taintAssignment(pc, sf);
8020
8021 /* Create the path constraint */
8022 this->symbolicEngine->pushPathConstraint(inst, expr);
8023 }
8024
8025
8026 void x86Semantics::lahf_s(triton::arch::Instruction& inst) {
8027 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AH));
8028 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
8029 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
8030 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF));
8031 auto src4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
8032 auto src5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
8033
8034 /* Create symbolic operands */
8035 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
8036 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
8037 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
8038 auto op4 = this->symbolicEngine->getOperandAst(inst, src4);
8039 auto op5 = this->symbolicEngine->getOperandAst(inst, src5);
8040
8041 /* Create the semantics */
8042 std::vector<triton::ast::SharedAbstractNode> flags;
8043 flags.reserve(8);
8044
8045 flags.push_back(op1);
8046 flags.push_back(op2);
8047 flags.push_back(this->astCtxt->bvfalse());
8048 flags.push_back(op3);
8049 flags.push_back(this->astCtxt->bvfalse());
8050 flags.push_back(op4);
8051 flags.push_back(this->astCtxt->bvtrue());
8052 flags.push_back(op5);
8053
8054 auto node = this->astCtxt->concat(flags);
8055
8056 /* Create symbolic expression */
8057 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "LAHF operation");
8058
8059 /* Spread taint */
8060 this->taintEngine->taintUnion(dst, src1);
8061 this->taintEngine->taintUnion(dst, src2);
8062 this->taintEngine->taintUnion(dst, src3);
8063 this->taintEngine->taintUnion(dst, src4);
8064 expr->isTainted = this->taintEngine->taintUnion(dst, src5);
8065
8066 /* Update the symbolic control flow */
8067 this->controlFlow_s(inst);
8068 }
8069
8070
8071 void x86Semantics::lddqu_s(triton::arch::Instruction& inst) {
8072 auto& dst = inst.operands[0];
8073 auto& src = inst.operands[1];
8074
8075 /* Create the semantics */
8076 auto node = this->symbolicEngine->getOperandAst(inst, src);
8077
8078 /* Create symbolic expression */
8079 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "LDDQU operation");
8080
8081 /* Spread taint */
8082 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8083
8084 /* Update the symbolic control flow */
8085 this->controlFlow_s(inst);
8086 }
8087
8088
8089 void x86Semantics::ldmxcsr_s(triton::arch::Instruction& inst) {
8090 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR));
8091 auto& src = inst.operands[0];
8092
8093 /* Create the semantics */
8094 auto node = this->symbolicEngine->getOperandAst(inst, src);
8095
8096 /* Create symbolic expression */
8097 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "LDMXCSR operation");
8098
8099 /* Spread taint */
8100 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8101
8102 /* Update the symbolic control flow */
8103 this->controlFlow_s(inst);
8104 }
8105
8106
8107 void x86Semantics::lea_s(triton::arch::Instruction& inst) {
8108 auto& dst = inst.operands[0].getRegister();
8109 auto& srcDisp = inst.operands[1].getMemory().getDisplacement();
8110 auto& srcBase = inst.operands[1].getMemory().getBaseRegister();
8111 auto& srcIndex = inst.operands[1].getMemory().getIndexRegister();
8112 auto& srcScale = inst.operands[1].getMemory().getScale();
8113 triton::uint32 leaSize = 0;
8114
8115 /* Setup LEA size */
8116 if (this->architecture->isRegisterValid(srcBase))
8117 leaSize = srcBase.getBitSize();
8118 else if (this->architecture->isRegisterValid(srcIndex))
8119 leaSize = srcIndex.getBitSize();
8120 else
8121 leaSize = srcDisp.getBitSize();
8122
8123 /* Create symbolic operands */
8124
8125 /* Displacement */
8126 auto op2 = this->symbolicEngine->getImmediateAst(inst, srcDisp);
8127 if (leaSize > srcDisp.getBitSize())
8128 op2 = this->astCtxt->zx(leaSize - srcDisp.getBitSize(), op2);
8129
8130 /* Base */
8131 triton::ast::SharedAbstractNode op3 = nullptr;
8132 if (this->architecture->isRegisterValid(srcBase))
8133 op3 = this->symbolicEngine->getRegisterAst(inst, srcBase);
8134 else
8135 op3 = this->astCtxt->bv(0, leaSize);
8136
8137 /* Base with PC */
8138 if (this->architecture->isRegisterValid(srcBase) && (this->architecture->getParentRegister(srcBase) == this->architecture->getProgramCounter()))
8139 op3 = this->astCtxt->bvadd(op3, this->astCtxt->bv(inst.getSize(), leaSize));
8140
8141 /* Index */
8142 triton::ast::SharedAbstractNode op4 = nullptr;
8143 if (this->architecture->isRegisterValid(srcIndex))
8144 op4 = this->symbolicEngine->getRegisterAst(inst, srcIndex);
8145 else
8146 op4 = this->astCtxt->bv(0, leaSize);
8147
8148 /* Scale */
8149 auto op5 = this->symbolicEngine->getImmediateAst(inst, srcScale);
8150 if (leaSize > srcScale.getBitSize())
8151 op5 = this->astCtxt->zx(leaSize - srcScale.getBitSize(), op5);
8152
8153 /* Create the semantics */
8154 /* Effective address = Displacement + BaseReg + IndexReg * Scale */
8155 auto node = this->astCtxt->bvadd(op2, this->astCtxt->bvadd(op3, this->astCtxt->bvmul(op4, op5)));
8156
8157 if (dst.getBitSize() > leaSize)
8158 node = this->astCtxt->zx(dst.getBitSize() - leaSize, node);
8159
8160 if (dst.getBitSize() < leaSize)
8161 node = this->astCtxt->extract(dst.getHigh(), dst.getLow(), node);
8162
8163 /* Create symbolic expression */
8164 auto expr = this->symbolicEngine->createSymbolicRegisterExpression(inst, node, dst, "LEA operation");
8165
8166 /* Spread taint */
8167 expr->isTainted = this->taintEngine->setTaint(dst, this->taintEngine->isTainted(srcBase) | this->taintEngine->isTainted(srcIndex));
8168
8169 /* Update the symbolic control flow */
8170 this->controlFlow_s(inst);
8171 }
8172
8173
8174 void x86Semantics::leave_s(triton::arch::Instruction& inst) {
8175 auto stack = this->architecture->getStackPointer();
8176 auto base = this->architecture->getParentRegister(ID_REG_X86_BP);
8177 auto baseValue = static_cast<triton::uint64>(this->architecture->getConcreteRegisterValue(base));
8178 auto bp1 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(baseValue, base.getSize()));
8179 auto bp2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_BP));
8180 auto sp = triton::arch::OperandWrapper(stack);
8181
8182 /* Create symbolic operands */
8183 auto op1 = this->symbolicEngine->getOperandAst(inst, bp2);
8184
8185 /* RSP = RBP */
8186 auto node1 = op1;
8187
8188 /* Create the symbolic expression */
8189 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, sp, "Stack Pointer");
8190
8191 /* Spread taint */
8192 expr1->isTainted = this->taintEngine->taintAssignment(sp, bp2);
8193
8194 /* Create symbolic operands */
8195 auto op2 = this->symbolicEngine->getOperandAst(inst, bp1);
8196
8197 /* RBP = pop() */
8198 auto node2 = op2;
8199
8200 /* Create the symbolic expression */
8201 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, bp2, "Stack Top Pointer");
8202
8203 /* Spread taint */
8204 expr2->isTainted = this->taintEngine->taintAssignment(bp2, bp1);
8205
8206 /* Create the semantics - side effect */
8207 alignAddStack_s(inst, bp1.getSize());
8208
8209 /* Update the symbolic control flow */
8210 this->controlFlow_s(inst);
8211 }
8212
8213
8214 void x86Semantics::lfence_s(triton::arch::Instruction& inst) {
8215 /* Update the symbolic control flow */
8216 this->controlFlow_s(inst);
8217 }
8218
8219
8220 void x86Semantics::lodsb_s(triton::arch::Instruction& inst) {
8221 auto& dst = inst.operands[0];
8222 auto& src = inst.operands[1];
8223 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
8224 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
8225 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
8226
8227 /* Check if there is a REP prefix and a counter to zero */
8228 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
8229 this->controlFlow_s(inst);
8230 return;
8231 }
8232
8233 /* Create symbolic operands */
8234 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
8235 auto op2 = this->symbolicEngine->getOperandAst(inst, index);
8236 auto op3 = this->symbolicEngine->getOperandAst(inst, df);
8237
8238 /* Create the semantics */
8239 auto node1 = op1;
8240 auto node2 = this->astCtxt->ite(
8241 this->astCtxt->equal(op3, this->astCtxt->bvfalse()),
8242 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::byte, index.getBitSize())),
8243 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::byte, index.getBitSize()))
8244 );
8245
8246 /* Create symbolic expression */
8247 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "LODSB operation");
8248 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
8249
8250 /* Spread taint */
8251 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
8252 expr2->isTainted = this->taintEngine->taintUnion(index, index);
8253
8254 /* Update the symbolic control flow */
8255 this->controlFlow_s(inst);
8256 }
8257
8258
8259 void x86Semantics::lodsd_s(triton::arch::Instruction& inst) {
8260 auto& dst = inst.operands[0];
8261 auto& src = inst.operands[1];
8262 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
8263 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
8264 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
8265
8266 /* Check if there is a REP prefix and a counter to zero */
8267 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
8268 this->controlFlow_s(inst);
8269 return;
8270 }
8271
8272 /* Create symbolic operands */
8273 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
8274 auto op2 = this->symbolicEngine->getOperandAst(inst, index);
8275 auto op3 = this->symbolicEngine->getOperandAst(inst, df);
8276
8277 /* Create the semantics */
8278 auto node1 = op1;
8279 auto node2 = this->astCtxt->ite(
8280 this->astCtxt->equal(op3, this->astCtxt->bvfalse()),
8281 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::dword, index.getBitSize())),
8282 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::dword, index.getBitSize()))
8283 );
8284
8285 /* Create symbolic expression */
8286 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "LODSD operation");
8287 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
8288
8289 /* Spread taint */
8290 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
8291 expr2->isTainted = this->taintEngine->taintUnion(index, index);
8292
8293 /* Update the symbolic control flow */
8294 this->controlFlow_s(inst);
8295 }
8296
8297
8298 void x86Semantics::lodsq_s(triton::arch::Instruction& inst) {
8299 auto& dst = inst.operands[0];
8300 auto& src = inst.operands[1];
8301 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
8302 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
8303 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
8304
8305 /* Check if there is a REP prefix and a counter to zero */
8306 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
8307 this->controlFlow_s(inst);
8308 return;
8309 }
8310
8311 /* Create symbolic operands */
8312 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
8313 auto op2 = this->symbolicEngine->getOperandAst(inst, index);
8314 auto op3 = this->symbolicEngine->getOperandAst(inst, df);
8315
8316 /* Create the semantics */
8317 auto node1 = op1;
8318 auto node2 = this->astCtxt->ite(
8319 this->astCtxt->equal(op3, this->astCtxt->bvfalse()),
8320 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::qword, index.getBitSize())),
8321 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::qword, index.getBitSize()))
8322 );
8323
8324 /* Create symbolic expression */
8325 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "LODSQ operation");
8326 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
8327
8328 /* Spread taint */
8329 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
8330 expr2->isTainted = this->taintEngine->taintUnion(index, index);
8331
8332 /* Update the symbolic control flow */
8333 this->controlFlow_s(inst);
8334 }
8335
8336
8337 void x86Semantics::lodsw_s(triton::arch::Instruction& inst) {
8338 auto& dst = inst.operands[0];
8339 auto& src = inst.operands[1];
8340 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
8341 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
8342 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
8343
8344 /* Check if there is a REP prefix and a counter to zero */
8345 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
8346 this->controlFlow_s(inst);
8347 return;
8348 }
8349
8350 /* Create symbolic operands */
8351 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
8352 auto op2 = this->symbolicEngine->getOperandAst(inst, index);
8353 auto op3 = this->symbolicEngine->getOperandAst(inst, df);
8354
8355 /* Create the semantics */
8356 auto node1 = op1;
8357 auto node2 = this->astCtxt->ite(
8358 this->astCtxt->equal(op3, this->astCtxt->bvfalse()),
8359 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::word, index.getBitSize())),
8360 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::word, index.getBitSize()))
8361 );
8362
8363 /* Create symbolic expression */
8364 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "LODSW operation");
8365 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
8366
8367 /* Spread taint */
8368 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
8369 expr2->isTainted = this->taintEngine->taintUnion(index, index);
8370
8371 /* Update the symbolic control flow */
8372 this->controlFlow_s(inst);
8373 }
8374
8375
8376 void x86Semantics::loop_s(triton::arch::Instruction& inst) {
8377 auto count = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
8378 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
8379 auto& src = inst.operands[0];
8380
8381 /* Create symbolic operands */
8382 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
8383 auto op2 = this->symbolicEngine->getOperandAst(inst, count);
8384
8385 /* Create the semantics */
8386 auto node1 = this->astCtxt->ite(
8387 this->astCtxt->equal(op2, this->astCtxt->bv(0, op2->getBitvectorSize())),
8388 this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize()),
8389 op1
8390 );
8391
8392 /* Create symbolic expression */
8393 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, pc, "Program Counter");
8394
8395 /* Set condition flag */
8396 if (op2->evaluate()) {
8397 inst.setConditionTaken(true);
8398 /* Spread taint */
8399 expr1->isTainted = this->taintEngine->taintAssignment(pc, count);
8400 }
8401 else {
8402 expr1->isTainted = this->taintEngine->taintAssignment(pc, src);
8403 }
8404
8405 /* Create the semantics */
8406 auto node2 = this->astCtxt->bvsub(op2, this->astCtxt->bv(1, op2->getBitvectorSize()));
8407
8408 /* Create symbolic expression */
8409 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, count, "LOOP counter operation");
8410
8411 /* Create the path constraint */
8412 this->symbolicEngine->pushPathConstraint(inst, expr1);
8413 }
8414
8415
8416 void x86Semantics::lzcnt_s(triton::arch::Instruction& inst) {
8417 auto& dst = inst.operands[0];
8418 auto& src = inst.operands[1];
8419 auto bvSize1 = dst.getBitSize();
8420 auto bvSize2 = src.getBitSize();
8421
8422 /* Create symbolic operands */
8423 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
8424
8425 /* Create the semantics */
8426 triton::ast::SharedAbstractNode node = nullptr;
8427 switch (src.getSize()) {
8428 case triton::size::byte:
8429 node = this->astCtxt->ite(
8430 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)),
8431 this->astCtxt->bv(bvSize2, bvSize1),
8432 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 1, bvSize2 - 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
8433 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 2, bvSize2 - 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
8434 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 3, bvSize2 - 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
8435 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 4, bvSize2 - 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
8436 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 5, bvSize2 - 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
8437 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 6, bvSize2 - 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
8438 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 7, bvSize2 - 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
8439 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 8, bvSize2 - 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
8440 this->astCtxt->bv(8, bvSize1))))))))));
8441 break;
8442 case triton::size::word:
8443 node = this->astCtxt->ite(
8444 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)),
8445 this->astCtxt->bv(bvSize2, bvSize1),
8446 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 1, bvSize2 - 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
8447 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 2, bvSize2 - 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
8448 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 3, bvSize2 - 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
8449 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 4, bvSize2 - 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
8450 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 5, bvSize2 - 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
8451 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 6, bvSize2 - 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
8452 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 7, bvSize2 - 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
8453 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 8, bvSize2 - 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
8454 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 9, bvSize2 - 9, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
8455 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 10, bvSize2 - 10, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
8456 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 11, bvSize2 - 11, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
8457 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 12, bvSize2 - 12, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
8458 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 13, bvSize2 - 13, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
8459 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 14, bvSize2 - 14, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
8460 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 15, bvSize2 - 15, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
8461 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 16, bvSize2 - 16, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
8462 this->astCtxt->bv(16, bvSize1))))))))))))))))));
8463 break;
8465 node = this->astCtxt->ite(
8466 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)),
8467 this->astCtxt->bv(bvSize2, bvSize1),
8468 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 1, bvSize2 - 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
8469 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 2, bvSize2 - 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
8470 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 3, bvSize2 - 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
8471 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 4, bvSize2 - 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
8472 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 5, bvSize2 - 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
8473 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 6, bvSize2 - 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
8474 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 7, bvSize2 - 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
8475 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 8, bvSize2 - 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
8476 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 9, bvSize2 - 9, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
8477 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 10, bvSize2 - 10, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
8478 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 11, bvSize2 - 11, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
8479 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 12, bvSize2 - 12, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
8480 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 13, bvSize2 - 13, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
8481 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 14, bvSize2 - 14, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
8482 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 15, bvSize2 - 15, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
8483 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 16, bvSize2 - 16, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
8484 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 17, bvSize2 - 17, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1),
8485 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 18, bvSize2 - 18, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1),
8486 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 19, bvSize2 - 19, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1),
8487 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 20, bvSize2 - 20, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1),
8488 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 21, bvSize2 - 21, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1),
8489 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 22, bvSize2 - 22, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1),
8490 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 23, bvSize2 - 23, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1),
8491 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 24, bvSize2 - 24, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1),
8492 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 25, bvSize2 - 25, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1),
8493 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 26, bvSize2 - 26, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1),
8494 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 27, bvSize2 - 27, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1),
8495 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 28, bvSize2 - 28, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1),
8496 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 29, bvSize2 - 29, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1),
8497 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 30, bvSize2 - 30, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1),
8498 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 31, bvSize2 - 31, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1),
8499 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 32, bvSize2 - 32, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1),
8500 this->astCtxt->bv(32, bvSize1))))))))))))))))))))))))))))))))));
8501 break;
8503 node = this->astCtxt->ite(
8504 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)),
8505 this->astCtxt->bv(bvSize2, bvSize1),
8506 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 1, bvSize2 - 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
8507 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 2, bvSize2 - 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
8508 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 3, bvSize2 - 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
8509 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 4, bvSize2 - 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
8510 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 5, bvSize2 - 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
8511 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 6, bvSize2 - 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
8512 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 7, bvSize2 - 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
8513 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 8, bvSize2 - 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
8514 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 9, bvSize2 - 9, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
8515 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 10, bvSize2 - 10, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
8516 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 11, bvSize2 - 11, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
8517 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 12, bvSize2 - 12, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
8518 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 13, bvSize2 - 13, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
8519 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 14, bvSize2 - 14, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
8520 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 15, bvSize2 - 15, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
8521 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 16, bvSize2 - 16, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
8522 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 17, bvSize2 - 17, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1),
8523 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 18, bvSize2 - 18, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1),
8524 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 19, bvSize2 - 19, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1),
8525 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 20, bvSize2 - 20, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1),
8526 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 21, bvSize2 - 21, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1),
8527 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 22, bvSize2 - 22, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1),
8528 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 23, bvSize2 - 23, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1),
8529 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 24, bvSize2 - 24, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1),
8530 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 25, bvSize2 - 25, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1),
8531 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 26, bvSize2 - 26, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1),
8532 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 27, bvSize2 - 27, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1),
8533 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 28, bvSize2 - 28, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1),
8534 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 29, bvSize2 - 29, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1),
8535 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 30, bvSize2 - 30, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1),
8536 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 31, bvSize2 - 31, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1),
8537 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 32, bvSize2 - 32, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1),
8538 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 33, bvSize2 - 33, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(32, bvSize1),
8539 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 34, bvSize2 - 34, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(33, bvSize1),
8540 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 35, bvSize2 - 35, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(34, bvSize1),
8541 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 36, bvSize2 - 36, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(35, bvSize1),
8542 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 37, bvSize2 - 37, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(36, bvSize1),
8543 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 38, bvSize2 - 38, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(37, bvSize1),
8544 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 39, bvSize2 - 39, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(38, bvSize1),
8545 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 40, bvSize2 - 40, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(39, bvSize1),
8546 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 41, bvSize2 - 41, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(40, bvSize1),
8547 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 42, bvSize2 - 42, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(41, bvSize1),
8548 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 43, bvSize2 - 43, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(42, bvSize1),
8549 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 44, bvSize2 - 44, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(43, bvSize1),
8550 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 45, bvSize2 - 45, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(44, bvSize1),
8551 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 46, bvSize2 - 46, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(45, bvSize1),
8552 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 47, bvSize2 - 47, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(46, bvSize1),
8553 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 48, bvSize2 - 48, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(47, bvSize1),
8554 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 49, bvSize2 - 49, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(48, bvSize1),
8555 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 50, bvSize2 - 50, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(49, bvSize1),
8556 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 51, bvSize2 - 51, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(50, bvSize1),
8557 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 52, bvSize2 - 52, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(51, bvSize1),
8558 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 53, bvSize2 - 53, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(52, bvSize1),
8559 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 54, bvSize2 - 54, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(53, bvSize1),
8560 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 55, bvSize2 - 55, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(54, bvSize1),
8561 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 56, bvSize2 - 56, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(55, bvSize1),
8562 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 57, bvSize2 - 57, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(56, bvSize1),
8563 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 58, bvSize2 - 58, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(57, bvSize1),
8564 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 59, bvSize2 - 59, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(58, bvSize1),
8565 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 60, bvSize2 - 60, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(59, bvSize1),
8566 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 61, bvSize2 - 61, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(60, bvSize1),
8567 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 62, bvSize2 - 62, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(61, bvSize1),
8568 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 63, bvSize2 - 63, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(62, bvSize1),
8569 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 64, bvSize2 - 64, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(63, bvSize1),
8570 this->astCtxt->bv(64, bvSize1))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
8571 break;
8572 default:
8573 throw triton::exceptions::Semantics("x86Semantics::lzcnt_s(): Invalid operand size.");
8574 }
8575
8576 /* Create symbolic expression */
8577 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "LZCNT operation");
8578
8579 /* Spread taint */
8580 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8581
8582 /* Update symbolic flags */
8583 this->cfLzcnt_s(inst, expr, src, op1);
8584 this->zf_s(inst, expr, src);
8585
8586 /* Tag undefined flags */
8587 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
8588 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
8589 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
8590 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
8591
8592 /* Update the symbolic control flow */
8593 this->controlFlow_s(inst);
8594 }
8595
8596
8597 void x86Semantics::int3_s(triton::arch::Instruction& inst) {
8598 /* Return a breakpoint fault */
8599 this->exception = triton::arch::FAULT_BP;
8600 }
8601
8602
8603 void x86Semantics::mfence_s(triton::arch::Instruction& inst) {
8604 /* Update the symbolic control flow */
8605 this->controlFlow_s(inst);
8606 }
8607
8608
8609 void x86Semantics::mov_s(triton::arch::Instruction& inst) {
8610 auto& dst = inst.operands[0];
8611 auto& src = inst.operands[1];
8612 bool undef = false;
8613
8614 /* Create the semantics */
8615 auto node = this->symbolicEngine->getOperandAst(inst, src);
8616
8617 /*
8618 * Special cases:
8619 *
8620 * Triton defines segment registers as 32 or 64 bits vector to
8621 * avoid to simulate the GDT which allows users to directly define
8622 * their segments offset.
8623 *
8624 * The code below, handles the case: MOV r/m{16/32/64}, Sreg
8625 */
8626 if (src.getType() == triton::arch::OP_REG) {
8627 uint32 id = src.getConstRegister().getId();
8628 if (id >= triton::arch::ID_REG_X86_CS && id <= triton::arch::ID_REG_X86_SS) {
8629 node = this->astCtxt->extract(dst.getBitSize()-1, 0, node);
8630 }
8631 if (id >= triton::arch::ID_REG_X86_CR0 && id <= triton::arch::ID_REG_X86_CR15) {
8632 undef = true;
8633 }
8634 }
8635
8636 /*
8637 * The code below, handles the case: MOV Sreg, r/m{16/32/64}
8638 */
8639 if (dst.getType() == triton::arch::OP_REG) {
8640 uint32 id = dst.getConstRegister().getId();
8641 if (id >= triton::arch::ID_REG_X86_CS && id <= triton::arch::ID_REG_X86_SS) {
8642 node = this->astCtxt->extract(triton::bitsize::word-1, 0, node);
8643 }
8644 if (id >= triton::arch::ID_REG_X86_CR0 && id <= triton::arch::ID_REG_X86_CR15) {
8645 undef = true;
8646 }
8647 }
8648
8649 /* Create symbolic expression */
8650 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOV operation");
8651
8652 /* Spread taint */
8653 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8654
8655 /* Tag undefined flags */
8656 if (undef) {
8657 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
8658 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
8659 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
8660 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
8661 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
8662 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF));
8663 }
8664
8665 /* Update the symbolic control flow */
8666 this->controlFlow_s(inst);
8667 }
8668
8669
8670 void x86Semantics::movabs_s(triton::arch::Instruction& inst) {
8671 auto& dst = inst.operands[0];
8672 auto& src = inst.operands[1];
8673
8674 /* Create the semantics */
8675 auto node = this->symbolicEngine->getOperandAst(inst, src);
8676
8677 /* Create symbolic expression */
8678 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVABS operation");
8679
8680 /* Spread taint */
8681 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8682
8683 /* Update the symbolic control flow */
8684 this->controlFlow_s(inst);
8685 }
8686
8687
8688 void x86Semantics::movapd_s(triton::arch::Instruction& inst) {
8689 auto& dst = inst.operands[0];
8690 auto& src = inst.operands[1];
8691
8692 /* Create the semantics */
8693 auto node = this->symbolicEngine->getOperandAst(inst, src);
8694
8695 /* Create symbolic expression */
8696 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVAPD operation");
8697
8698 /* Spread taint */
8699 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8700
8701 /* Update the symbolic control flow */
8702 this->controlFlow_s(inst);
8703 }
8704
8705
8706 void x86Semantics::movaps_s(triton::arch::Instruction& inst) {
8707 auto& dst = inst.operands[0];
8708 auto& src = inst.operands[1];
8709
8710 /* Create the semantics */
8711 auto node = this->symbolicEngine->getOperandAst(inst, src);
8712
8713 /* Create symbolic expression */
8714 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVAPS operation");
8715
8716 /* Spread taint */
8717 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8718
8719 /* Update the symbolic control flow */
8720 this->controlFlow_s(inst);
8721 }
8722
8723
8724 void x86Semantics::movbe_s(triton::arch::Instruction& inst) {
8725 auto &dst = inst.operands[0];
8726 auto &src = inst.operands[1];
8727
8728 /* Create symbolic operands */
8729 auto op = this->symbolicEngine->getOperandAst(inst, src);
8730
8731 /* Create the semantics */
8732 std::vector<triton::ast::SharedAbstractNode> exprs;
8733 for (size_t i = 0; i < src.getSize(); ++i) {
8734 exprs.push_back(this->astCtxt->extract(triton::bitsize::byte * i + (triton::bitsize::byte - 1),
8736 op));
8737 }
8738 auto node = this->astCtxt->concat(exprs);
8739
8740 /* Create symbolic expression */
8741 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVBE operation");
8742
8743 /* Spread taint */
8744 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8745
8746 /* Update the symbolic control flow */
8747 this->controlFlow_s(inst);
8748 }
8749
8750
8751 void x86Semantics::movd_s(triton::arch::Instruction& inst) {
8752 auto& dst = inst.operands[0];
8753 auto& src = inst.operands[1];
8754
8755 /* Create symbolic operands */
8756 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
8757
8758 /* Create the semantics */
8759 triton::ast::SharedAbstractNode node = nullptr;
8760
8761 switch (dst.getBitSize()) {
8762 /* GPR 32-bits */
8764 node = this->astCtxt->extract(triton::bitsize::dword-1, 0, op2);
8765 break;
8766
8767 /* MMX 64-bits */
8769 node = this->astCtxt->zx(triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::dword-1, 0, op2));
8770 break;
8771
8772 /* XMM 128-bits */
8774 node = this->astCtxt->zx(triton::bitsize::qword + triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::dword-1, 0, op2));
8775 break;
8776 }
8777
8778 /* Create symbolic expression */
8779 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVD operation");
8780
8781 /* Update the x87 FPU Tag Word */
8782 if (dst.getBitSize() == triton::bitsize::qword) {
8783 this->updateFTW(inst, expr);
8784 }
8785
8786 /* Spread taint */
8787 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8788
8789 /* Update the symbolic control flow */
8790 this->controlFlow_s(inst);
8791 }
8792
8793
8794 void x86Semantics::movddup_s(triton::arch::Instruction& inst) {
8795 auto& dst = inst.operands[0];
8796 auto& src = inst.operands[1];
8797
8798 /* Create symbolic operands */
8799 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
8800
8801 /* Create the semantics */
8802 auto node = this->astCtxt->concat(this->astCtxt->extract(triton::bitsize::qword-1, 0, op2), this->astCtxt->extract(triton::bitsize::qword-1, 0, op2));
8803
8804 /* Create symbolic expression */
8805 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVDDUP operation");
8806
8807 /* Spread taint */
8808 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8809
8810 /* Update the symbolic control flow */
8811 this->controlFlow_s(inst);
8812 }
8813
8814
8815 void x86Semantics::movdq2q_s(triton::arch::Instruction& inst) {
8816 auto& dst = inst.operands[0];
8817 auto& src = inst.operands[1];
8818
8819 /* Create symbolic operands */
8820 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
8821
8822 /* Create the semantics */
8823 auto node = this->astCtxt->extract(triton::bitsize::qword-1, 0, op2);
8824
8825 /* Create symbolic expression */
8826 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVDQ2Q operation");
8827
8828 /* Spread taint */
8829 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8830
8831 /* Update the symbolic control flow */
8832 this->controlFlow_s(inst);
8833 }
8834
8835
8836 void x86Semantics::movdqa_s(triton::arch::Instruction& inst) {
8837 auto& dst = inst.operands[0];
8838 auto& src = inst.operands[1];
8839
8840 /* Create the semantics */
8841 auto node = this->symbolicEngine->getOperandAst(inst, src);
8842
8843 /* Create symbolic expression */
8844 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVDQA operation");
8845
8846 /* Spread taint */
8847 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8848
8849 /* Update the symbolic control flow */
8850 this->controlFlow_s(inst);
8851 }
8852
8853
8854 void x86Semantics::movdqu_s(triton::arch::Instruction& inst) {
8855 auto& dst = inst.operands[0];
8856 auto& src = inst.operands[1];
8857
8858 /* Create the semantics */
8859 auto node = this->symbolicEngine->getOperandAst(inst, src);
8860
8861 /* Create symbolic expression */
8862 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVDQU operation");
8863
8864 /* Spread taint */
8865 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8866
8867 /* Update the symbolic control flow */
8868 this->controlFlow_s(inst);
8869 }
8870
8871
8872 void x86Semantics::movhlps_s(triton::arch::Instruction& inst) {
8873 auto& dst = inst.operands[0];
8874 auto& src = inst.operands[1];
8875
8876 /* Create symbolic operands */
8877 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
8878 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
8879
8880 /* Create the semantics */
8881 auto node = this->astCtxt->concat(
8882 this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, op1), /* Destination[127..64] unchanged */
8883 this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, op2) /* Destination[63..0] = Source[127..64]; */
8884 );
8885
8886 /* Create symbolic expression */
8887 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVHLPS operation");
8888
8889 /* Spread taint */
8890 expr->isTainted = this->taintEngine->taintUnion(dst, src);
8891
8892 /* Update the symbolic control flow */
8893 this->controlFlow_s(inst);
8894 }
8895
8896
8897 void x86Semantics::movhpd_s(triton::arch::Instruction& inst) {
8898 auto& dst = inst.operands[0];
8899 auto& src = inst.operands[1];
8900
8901 /* Create symbolic operands */
8902 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
8903 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
8904
8905 /* Create the semantics */
8906 triton::ast::SharedAbstractNode node = nullptr;
8907
8908 /* xmm, m64 */
8909 if (dst.getSize() == triton::size::dqword) {
8910 node = this->astCtxt->concat(
8911 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2), /* Destination[127..64] = Source */
8912 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op1) /* Destination[63..0] unchanged */
8913 );
8914 }
8915
8916 /* m64, xmm */
8917 else {
8918 node = this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, op2); /* Destination[63..00] = Source[127..64] */
8919 }
8920
8921 /* Create symbolic expression */
8922 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVHPD operation");
8923
8924 /* Spread taint */
8925 expr->isTainted = this->taintEngine->taintUnion(dst, src);
8926
8927 /* Update the symbolic control flow */
8928 this->controlFlow_s(inst);
8929 }
8930
8931
8932 void x86Semantics::movhps_s(triton::arch::Instruction& inst) {
8933 auto& dst = inst.operands[0];
8934 auto& src = inst.operands[1];
8935
8936 /* Create symbolic operands */
8937 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
8938 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
8939
8940 /* Create the semantics */
8941 triton::ast::SharedAbstractNode node = nullptr;
8942
8943 /* xmm, m64 */
8944 if (dst.getSize() == triton::size::dqword) {
8945 node = this->astCtxt->concat(
8946 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2), /* Destination[127..64] = Source */
8947 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op1) /* Destination[63..0] unchanged */
8948 );
8949 }
8950
8951 /* m64, xmm */
8952 else {
8953 node = this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, op2); /* Destination[63..00] = Source[127..64] */
8954 }
8955
8956 /* Create symbolic expression */
8957 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVHPS operation");
8958
8959 /* Spread taint */
8960 expr->isTainted = this->taintEngine->taintUnion(dst, src);
8961
8962 /* Update the symbolic control flow */
8963 this->controlFlow_s(inst);
8964 }
8965
8966
8967 void x86Semantics::movlhps_s(triton::arch::Instruction& inst) {
8968 auto& dst = inst.operands[0];
8969 auto& src = inst.operands[1];
8970
8971 /* Create symbolic operands */
8972 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
8973 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
8974
8975 /* Create the semantics */
8976 auto node = this->astCtxt->concat(
8977 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2), /* Destination[127..64] = Source[63..0] */
8978 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op1) /* Destination[63..0] unchanged */
8979 );
8980
8981 /* Create symbolic expression */
8982 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVLHPS operation");
8983
8984 /* Spread taint */
8985 expr->isTainted = this->taintEngine->taintUnion(dst, src);
8986
8987 /* Update the symbolic control flow */
8988 this->controlFlow_s(inst);
8989 }
8990
8991
8992 void x86Semantics::movlpd_s(triton::arch::Instruction& inst) {
8993 auto& dst = inst.operands[0];
8994 auto& src = inst.operands[1];
8995
8996 /* Create symbolic operands */
8997 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
8998 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
8999
9000 /* Create the semantics */
9001 triton::ast::SharedAbstractNode node = nullptr;
9002
9003 /* xmm, m64 */
9004 if (dst.getSize() == triton::size::dqword) {
9005 node = this->astCtxt->concat(
9006 this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, op1), /* Destination[127..64] unchanged */
9007 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2) /* Destination[63..0] = Source */
9008 );
9009 }
9010
9011 /* m64, xmm */
9012 else {
9013 node = this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2); /* Destination = Source[63..00] */
9014 }
9015
9016 /* Create symbolic expression */
9017 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVLPD operation");
9018
9019 /* Spread taint */
9020 expr->isTainted = this->taintEngine->taintUnion(dst, src);
9021
9022 /* Update the symbolic control flow */
9023 this->controlFlow_s(inst);
9024 }
9025
9026
9027 void x86Semantics::movlps_s(triton::arch::Instruction& inst) {
9028 auto& dst = inst.operands[0];
9029 auto& src = inst.operands[1];
9030
9031 /* Create symbolic operands */
9032 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
9033 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9034
9035 /* Create the semantics */
9036 triton::ast::SharedAbstractNode node = nullptr;
9037
9038 /* xmm, m64 */
9039 if (dst.getSize() == triton::size::dqword) {
9040 node = this->astCtxt->concat(
9041 this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, op1), /* Destination[127..64] unchanged */
9042 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2) /* Destination[63..0] = Source */
9043 );
9044 }
9045
9046 /* m64, xmm */
9047 else {
9048 node = this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2); /* Destination = Source[63..00] */
9049 }
9050
9051 /* Create symbolic expression */
9052 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVLPS operation");
9053
9054 /* Spread taint */
9055 expr->isTainted = this->taintEngine->taintUnion(dst, src);
9056
9057 /* Update the symbolic control flow */
9058 this->controlFlow_s(inst);
9059 }
9060
9061
9062 void x86Semantics::movmskpd_s(triton::arch::Instruction& inst) {
9063 auto& dst = inst.operands[0];
9064 auto& src = inst.operands[1];
9065
9066 /* Create symbolic operands */
9067 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9068
9069 /* Create the semantics */
9070 auto node = this->astCtxt->zx(30, /* Destination[2..31] = 0 */
9071 this->astCtxt->concat(
9072 this->astCtxt->extract(127, 127, op2), /* Destination[1] = Source[127]; */
9073 this->astCtxt->extract(63, 63, op2) /* Destination[0] = Source[63]; */
9074 )
9075 );
9076
9077 /* Create symbolic expression */
9078 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVMSKPD operation");
9079
9080 /* Spread taint */
9081 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9082
9083 /* Update the symbolic control flow */
9084 this->controlFlow_s(inst);
9085 }
9086
9087
9088 void x86Semantics::movmskps_s(triton::arch::Instruction& inst) {
9089 auto& dst = inst.operands[0];
9090 auto& src = inst.operands[1];
9091
9092 /* Create symbolic operands */
9093 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9094
9095 /* Create the semantics */
9096 std::vector<triton::ast::SharedAbstractNode> signs;
9097 signs.reserve(4);
9098
9099 signs.push_back(this->astCtxt->extract(127, 127, op2)); /* Destination[3] = Source[127]; */
9100 signs.push_back(this->astCtxt->extract(95, 95, op2)); /* Destination[2] = Source[95]; */
9101 signs.push_back(this->astCtxt->extract(63, 63, op2)); /* Destination[1] = Source[63]; */
9102 signs.push_back(this->astCtxt->extract(31, 31, op2)); /* Destination[0] = Source[31]; */
9103
9104 auto node = this->astCtxt->zx(28, this->astCtxt->concat(signs));
9105
9106 /* Create symbolic expression */
9107 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVMSKPS operation");
9108
9109 /* Spread taint */
9110 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9111
9112 /* Update the symbolic control flow */
9113 this->controlFlow_s(inst);
9114 }
9115
9116
9117 void x86Semantics::movntdq_s(triton::arch::Instruction& inst) {
9118 auto& dst = inst.operands[0];
9119 auto& src = inst.operands[1];
9120
9121 /* Create the semantics */
9122 auto node = this->symbolicEngine->getOperandAst(inst, src);
9123
9124 /* Create symbolic expression */
9125 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVNTDQ operation");
9126
9127 /* Spread taint */
9128 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9129
9130 /* Update the symbolic control flow */
9131 this->controlFlow_s(inst);
9132 }
9133
9134
9135 void x86Semantics::movnti_s(triton::arch::Instruction& inst) {
9136 auto& dst = inst.operands[0];
9137 auto& src = inst.operands[1];
9138
9139 /* Create the semantics */
9140 auto node = this->symbolicEngine->getOperandAst(inst, src);
9141
9142 /* Create symbolic expression */
9143 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVNTI operation");
9144
9145 /* Spread taint */
9146 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9147
9148 /* Update the symbolic control flow */
9149 this->controlFlow_s(inst);
9150 }
9151
9152
9153 void x86Semantics::movntpd_s(triton::arch::Instruction& inst) {
9154 auto& dst = inst.operands[0];
9155 auto& src = inst.operands[1];
9156
9157 /* Create the semantics */
9158 auto node = this->symbolicEngine->getOperandAst(inst, src);
9159
9160 /* Create symbolic expression */
9161 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVNTPD operation");
9162
9163 /* Spread taint */
9164 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9165
9166 /* Update the symbolic control flow */
9167 this->controlFlow_s(inst);
9168 }
9169
9170
9171 void x86Semantics::movntps_s(triton::arch::Instruction& inst) {
9172 auto& dst = inst.operands[0];
9173 auto& src = inst.operands[1];
9174
9175 /* Create the semantics */
9176 auto node = this->symbolicEngine->getOperandAst(inst, src);
9177
9178 /* Create symbolic expression */
9179 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVNTPS operation");
9180
9181 /* Spread taint */
9182 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9183
9184 /* Update the symbolic control flow */
9185 this->controlFlow_s(inst);
9186 }
9187
9188
9189 void x86Semantics::movntq_s(triton::arch::Instruction& inst) {
9190 auto& dst = inst.operands[0];
9191 auto& src = inst.operands[1];
9192
9193 /* Create the semantics */
9194 auto node = this->symbolicEngine->getOperandAst(inst, src);
9195
9196 /* Create symbolic expression */
9197 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVNTQ operation");
9198
9199 /* Spread taint */
9200 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9201
9202 /* Update the symbolic control flow */
9203 this->controlFlow_s(inst);
9204 }
9205
9206
9207 void x86Semantics::movshdup_s(triton::arch::Instruction& inst) {
9208 auto& dst = inst.operands[0];
9209 auto& src = inst.operands[1];
9210
9211 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9212
9213 /* Create the semantics */
9214 std::vector<triton::ast::SharedAbstractNode> bytes;
9215 bytes.reserve(4);
9216
9217 bytes.push_back(this->astCtxt->extract(127, 96, op2));
9218 bytes.push_back(this->astCtxt->extract(127, 96, op2));
9219 bytes.push_back(this->astCtxt->extract(63, 32, op2));
9220 bytes.push_back(this->astCtxt->extract(63, 32, op2));
9221
9222 auto node = this->astCtxt->concat(bytes);
9223
9224 /* Create symbolic expression */
9225 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSHDUP operation");
9226
9227 /* Spread taint */
9228 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9229
9230 /* Update the symbolic control flow */
9231 this->controlFlow_s(inst);
9232 }
9233
9234
9235 void x86Semantics::movsldup_s(triton::arch::Instruction& inst) {
9236 auto& dst = inst.operands[0];
9237 auto& src = inst.operands[1];
9238
9239 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9240
9241 /* Create the semantics */
9242 std::vector<triton::ast::SharedAbstractNode> bytes;
9243 bytes.reserve(4);
9244
9245 bytes.push_back(this->astCtxt->extract(95, 64, op2));
9246 bytes.push_back(this->astCtxt->extract(95, 64, op2));
9247 bytes.push_back(this->astCtxt->extract(31, 0, op2));
9248 bytes.push_back(this->astCtxt->extract(31, 0, op2));
9249
9250 auto node = this->astCtxt->concat(bytes);
9251
9252 /* Create symbolic expression */
9253 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSLDUP operation");
9254
9255 /* Spread taint */
9256 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9257
9258 /* Update the symbolic control flow */
9259 this->controlFlow_s(inst);
9260 }
9261
9262
9263 void x86Semantics::movq_s(triton::arch::Instruction& inst) {
9264 auto& dst = inst.operands[0];
9265 auto& src = inst.operands[1];
9266
9267 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9268
9269 /* Create the semantics */
9270 triton::ast::SharedAbstractNode node = nullptr;
9271
9272 /* when operating on MMX technology registers and memory locations */
9274 node = op2;
9275 }
9276
9277 /* when source and destination operands are XMM registers */
9279 node = this->astCtxt->concat(
9280 this->astCtxt->extract(triton::bitsize::dqword-1, triton::bitsize::qword, this->symbolicEngine->getOperandAst(inst, dst)),
9281 this->astCtxt->extract(triton::bitsize::qword-1, 0, op2)
9282 );
9283 }
9284
9285 /* when source operand is XMM register and destination operand is memory location */
9286 else if (dst.getBitSize() < src.getBitSize()) {
9287 node = this->astCtxt->extract(triton::bitsize::qword-1, 0, op2);
9288 }
9289
9290 /* when source operand is memory location and destination operand is XMM register */
9291 else if (dst.getBitSize() > src.getBitSize()) {
9292 node = this->astCtxt->zx(triton::bitsize::qword, op2);
9293 }
9294
9295 /* Invalid operation */
9296 else {
9297 throw triton::exceptions::Semantics("x86Semantics::movq_s(): Invalid operation.");
9298 }
9299
9300 /* Create symbolic expression */
9301 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVQ operation");
9302
9303 /* Update the x87 FPU Tag Word */
9305 this->updateFTW(inst, expr);
9306 }
9307
9308 /* Spread taint */
9310 expr->isTainted = this->taintEngine->taintUnion(dst, src);
9311 else
9312 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9313
9314 /* Update the symbolic control flow */
9315 this->controlFlow_s(inst);
9316 }
9317
9318
9319 void x86Semantics::movq2dq_s(triton::arch::Instruction& inst) {
9320 auto& dst = inst.operands[0];
9321 auto& src = inst.operands[1];
9322
9323 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9324
9325 /* Create the semantics */
9326 auto node = this->astCtxt->zx(triton::bitsize::qword, op2);
9327
9328 /* Create symbolic expression */
9329 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVQ2DQ operation");
9330
9331 /* TODO @fvrmatteo: the x87 FPU top-of-stack pointer is set to 0 and the x87 FPU tag word is set to all 0s [valid] */
9332
9333 /* Spread taint */
9334 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9335
9336 /* Update the symbolic control flow */
9337 this->controlFlow_s(inst);
9338 }
9339
9340
9341 void x86Semantics::movsb_s(triton::arch::Instruction& inst) {
9342 auto& dst = inst.operands[0];
9343 auto& src = inst.operands[1];
9344 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
9345 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
9346 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
9347 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
9348
9349 /* Check if there is a REP prefix and a counter to zero */
9350 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
9351 this->controlFlow_s(inst);
9352 return;
9353 }
9354
9355 /* Create symbolic operands */
9356 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9357 auto op2 = this->symbolicEngine->getOperandAst(inst, index1);
9358 auto op3 = this->symbolicEngine->getOperandAst(inst, index2);
9359 auto op4 = this->symbolicEngine->getOperandAst(inst, df);
9360
9361 /* Create the semantics */
9362 auto node1 = op1;
9363 auto node2 = this->astCtxt->ite(
9364 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
9365 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::byte, index1.getBitSize())),
9366 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::byte, index1.getBitSize()))
9367 );
9368 auto node3 = this->astCtxt->ite(
9369 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
9370 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::byte, index2.getBitSize())),
9371 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::byte, index2.getBitSize()))
9372 );
9373
9374 /* Create symbolic expression */
9375 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "MOVSB operation");
9376 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (DI) operation");
9377 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (SI) operation");
9378
9379 /* Spread taint */
9380 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
9381 expr2->isTainted = this->taintEngine->taintUnion(index1, index1);
9382 expr3->isTainted = this->taintEngine->taintUnion(index2, index2);
9383
9384 /* Update the symbolic control flow */
9385 this->controlFlow_s(inst);
9386 }
9387
9388
9389 void x86Semantics::movsd_s(triton::arch::Instruction& inst) {
9390 auto& dst = inst.operands[0];
9391 auto& src = inst.operands[1];
9392 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
9393 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
9394 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
9395 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
9396
9397 /* Check if there is a REP prefix and a counter to zero */
9398 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
9399 this->controlFlow_s(inst);
9400 return;
9401 }
9402
9403 /*
9404 * F2 0F 10 /r MOVSD xmm1, xmm2
9405 * F2 0F 10 /r MOVSD xmm1, m64
9406 */
9407 if (dst.getBitSize() == triton::bitsize::dqword) {
9408 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9409 auto op2 = this->symbolicEngine->getOperandAst(dst);
9410
9411 auto node = this->astCtxt->concat(
9412 this->astCtxt->extract(127, 64, op2),
9413 this->astCtxt->extract(63, 0, op1)
9414 );
9415
9416 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSD operation");
9417 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9418 }
9419
9420 /*
9421 * F2 0F 11 /r MOVSD m64, xmm2
9422 */
9424 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9425 auto node = this->astCtxt->extract(63, 0, op1);
9426 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSD operation");
9427 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9428 }
9429
9430 /* A5 MOVSD */
9431 else {
9432 /* Create symbolic operands */
9433 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9434 auto op2 = this->symbolicEngine->getOperandAst(inst, index1);
9435 auto op3 = this->symbolicEngine->getOperandAst(inst, index2);
9436 auto op4 = this->symbolicEngine->getOperandAst(inst, df);
9437
9438 /* Create the semantics */
9439 auto node1 = op1;
9440 auto node2 = this->astCtxt->ite(
9441 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
9442 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::dword, index1.getBitSize())),
9443 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::dword, index1.getBitSize()))
9444 );
9445 auto node3 = this->astCtxt->ite(
9446 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
9447 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::dword, index2.getBitSize())),
9448 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::dword, index2.getBitSize()))
9449 );
9450
9451 /* Create symbolic expression */
9452 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "MOVSD operation");
9453 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (DI) operation");
9454 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (SI) operation");
9455
9456 /* Spread taint */
9457 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
9458 expr2->isTainted = this->taintEngine->taintUnion(index1, index1);
9459 expr3->isTainted = this->taintEngine->taintUnion(index2, index2);
9460 }
9461
9462 /* Update the symbolic control flow */
9463 this->controlFlow_s(inst);
9464 }
9465
9466
9467 void x86Semantics::movupd_s(triton::arch::Instruction& inst) {
9468 auto& dst = inst.operands[0];
9469 auto& src = inst.operands[1];
9470
9471 /* Create the semantics */
9472 auto node = this->symbolicEngine->getOperandAst(inst, src);
9473
9474 /* Create symbolic expression */
9475 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVUPD operation");
9476
9477 /* Spread taint */
9478 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9479
9480 /* Update the symbolic control flow */
9481 this->controlFlow_s(inst);
9482 }
9483
9484
9485 void x86Semantics::movups_s(triton::arch::Instruction& inst) {
9486 auto& dst = inst.operands[0];
9487 auto& src = inst.operands[1];
9488
9489 /* Create the semantics */
9490 auto node = this->symbolicEngine->getOperandAst(inst, src);
9491
9492 /* Create symbolic expression */
9493 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVUPS operation");
9494
9495 /* Spread taint */
9496 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9497
9498 /* Update the symbolic control flow */
9499 this->controlFlow_s(inst);
9500 }
9501
9502
9503 void x86Semantics::movss_s(triton::arch::Instruction& inst) {
9504 auto& dst = inst.operands[0];
9505 auto& src = inst.operands[1];
9506
9507 /* Create symbolic operands */
9508 auto op = this->symbolicEngine->getOperandAst(inst, src);
9509
9510 /* Create the semantics */
9511 auto node = op;
9512 if (src.getType() == OP_REG) {
9513 node = this->astCtxt->extract(triton::bitsize::dword - 1, 0, node);
9514 if (dst.getType() == OP_REG) {
9515 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
9516 auto upper = this->astCtxt->extract(triton::bitsize::dqword - 1, triton::bitsize::dword, op1);
9517 node = this->astCtxt->concat(upper, node);
9518 }
9519 }
9520
9521 /* Create symbolic expression */
9522 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSS operation");
9523
9524 /* Spread taint */
9525 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9526
9527 /* Update the symbolic control flow */
9528 this->controlFlow_s(inst);
9529 }
9530
9531
9532 void x86Semantics::movsq_s(triton::arch::Instruction& inst) {
9533 auto& dst = inst.operands[0];
9534 auto& src = inst.operands[1];
9535 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
9536 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
9537 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
9538 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
9539
9540 /* Check if there is a REP prefix and a counter to zero */
9541 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
9542 this->controlFlow_s(inst);
9543 return;
9544 }
9545
9546 /* Create symbolic operands */
9547 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9548 auto op2 = this->symbolicEngine->getOperandAst(inst, index1);
9549 auto op3 = this->symbolicEngine->getOperandAst(inst, index2);
9550 auto op4 = this->symbolicEngine->getOperandAst(inst, df);
9551
9552 /* Create the semantics */
9553 auto node1 = op1;
9554 auto node2 = this->astCtxt->ite(
9555 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
9556 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::qword, index1.getBitSize())),
9557 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::qword, index1.getBitSize()))
9558 );
9559 auto node3 = this->astCtxt->ite(
9560 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
9561 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::qword, index2.getBitSize())),
9562 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::qword, index2.getBitSize()))
9563 );
9564
9565 /* Create symbolic expression */
9566 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "MOVSQ operation");
9567 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (DI) operation");
9568 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (SI) operation");
9569
9570 /* Spread taint */
9571 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
9572 expr2->isTainted = this->taintEngine->taintUnion(index1, index1);
9573 expr3->isTainted = this->taintEngine->taintUnion(index2, index2);
9574
9575 /* Update the symbolic control flow */
9576 this->controlFlow_s(inst);
9577 }
9578
9579
9580 void x86Semantics::movsw_s(triton::arch::Instruction& inst) {
9581 auto& dst = inst.operands[0];
9582 auto& src = inst.operands[1];
9583 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
9584 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
9585 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
9586 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
9587
9588 /* Check if there is a REP prefix and a counter to zero */
9589 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
9590 this->controlFlow_s(inst);
9591 return;
9592 }
9593
9594 /* Create symbolic operands */
9595 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9596 auto op2 = this->symbolicEngine->getOperandAst(inst, index1);
9597 auto op3 = this->symbolicEngine->getOperandAst(inst, index2);
9598 auto op4 = this->symbolicEngine->getOperandAst(inst, df);
9599
9600 /* Create the semantics */
9601 auto node1 = op1;
9602 auto node2 = this->astCtxt->ite(
9603 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
9604 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::word, index1.getBitSize())),
9605 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::word, index1.getBitSize()))
9606 );
9607 auto node3 = this->astCtxt->ite(
9608 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
9609 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::word, index2.getBitSize())),
9610 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::word, index2.getBitSize()))
9611 );
9612
9613 /* Create symbolic expression */
9614 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "MOVSW operation");
9615 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (DI) operation");
9616 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (SI) operation");
9617
9618 /* Spread taint */
9619 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
9620 expr2->isTainted = this->taintEngine->taintUnion(index1, index1);
9621 expr3->isTainted = this->taintEngine->taintUnion(index2, index2);
9622
9623 /* Update the symbolic control flow */
9624 this->controlFlow_s(inst);
9625 }
9626
9627
9628 void x86Semantics::movsx_s(triton::arch::Instruction& inst) {
9629 auto& dst = inst.operands[0];
9630 auto& src = inst.operands[1];
9631
9632 /* Create symbolic operands */
9633 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9634
9635 /* Create the semantics */
9636 auto node = this->astCtxt->sx(dst.getBitSize() - src.getBitSize(), op1);
9637
9638 /* Create symbolic expression */
9639 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSX operation");
9640
9641 /* Spread taint */
9642 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9643
9644 /* Update the symbolic control flow */
9645 this->controlFlow_s(inst);
9646 }
9647
9648
9649 void x86Semantics::movsxd_s(triton::arch::Instruction& inst) {
9650 auto& dst = inst.operands[0];
9651 auto& src = inst.operands[1];
9652
9653 /* Create symbolic operands */
9654 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9655
9656 /* Create the semantics */
9657 auto node = this->astCtxt->sx(dst.getBitSize() - src.getBitSize(), op1);
9658
9659 /* Create symbolic expression */
9660 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSXD operation");
9661
9662 /* Spread taint */
9663 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9664
9665 /* Update the symbolic control flow */
9666 this->controlFlow_s(inst);
9667 }
9668
9669
9670 void x86Semantics::movzx_s(triton::arch::Instruction& inst) {
9671 auto& dst = inst.operands[0];
9672 auto& src = inst.operands[1];
9673
9674 /* Create symbolic operands */
9675 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9676
9677 /* Create the semantics */
9678 auto node = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), op1);
9679
9680 /* Create symbolic expression */
9681 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVZX operation");
9682
9683 /* Spread taint */
9684 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9685
9686 /* Update the symbolic control flow */
9687 this->controlFlow_s(inst);
9688 }
9689
9690
9691 void x86Semantics::mul_s(triton::arch::Instruction& inst) {
9692 auto& src2 = inst.operands[0];
9693
9694 switch (src2.getSize()) {
9695
9696 /* AX = AL * r/m8 */
9697 case triton::size::byte: {
9698 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
9699 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
9700 /* Create symbolic operands */
9701 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
9702 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
9703 /* Create the semantics */
9704 auto node = this->astCtxt->bvmul(this->astCtxt->zx(triton::bitsize::byte, op1), this->astCtxt->zx(triton::bitsize::byte, op2));
9705 /* Create symbolic expression */
9706 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MUL operation");
9707 /* Apply the taint */
9708 expr->isTainted = this->taintEngine->taintUnion(dst, src2);
9709 /* Update symbolic flags */
9710 auto ah = this->astCtxt->extract((triton::bitsize::word - 1), triton::bitsize::byte, node);
9711 this->cfMul_s(inst, expr, src2, ah);
9712 this->ofMul_s(inst, expr, src2, ah);
9713 break;
9714 }
9715
9716 /* DX:AX = AX * r/m16 */
9717 case triton::size::word: {
9718 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
9719 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DX));
9720 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
9721 /* Create symbolic operands */
9722 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
9723 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
9724 /* Create symbolic expression for ax */
9725 auto ax = this->astCtxt->bvmul(op1, op2);
9726 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, ax, dst1, "MUL operation");
9727 /* Apply the taint */
9728 expr1->isTainted = this->taintEngine->taintUnion(dst1, src2);
9729 /* Create symbolic expression for dx */
9730 auto node = this->astCtxt->bvmul(this->astCtxt->zx(triton::bitsize::word, op1), this->astCtxt->zx(triton::bitsize::word, op2));
9731 auto dx = this->astCtxt->extract((triton::bitsize::dword - 1), triton::bitsize::word, node);
9732 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, dx, dst2, "MUL operation");
9733 /* Apply the taint */
9734 expr2->isTainted = this->taintEngine->taintUnion(dst2, src2);
9735 expr2->isTainted = this->taintEngine->taintUnion(dst2, src1);
9736 /* Update symbolic flags */
9737 this->cfMul_s(inst, expr2, src2, dx);
9738 this->ofMul_s(inst, expr2, src2, dx);
9739 break;
9740 }
9741
9742 /* EDX:EAX = EAX * r/m32 */
9743 case triton::size::dword: {
9744 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
9745 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
9746 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
9747 /* Create symbolic operands */
9748 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
9749 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
9750 /* Create symbolic expression for eax */
9751 auto eax = this->astCtxt->bvmul(op1, op2);
9752 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, eax, dst1, "MUL operation");
9753 /* Apply the taint */
9754 expr1->isTainted = this->taintEngine->taintUnion(dst1, src2);
9755 /* Create symbolic expression for edx */
9756 auto node = this->astCtxt->bvmul(this->astCtxt->zx(triton::bitsize::dword, op1), this->astCtxt->zx(triton::bitsize::dword, op2));
9757 auto edx = this->astCtxt->extract((triton::bitsize::qword - 1), triton::bitsize::dword, node);
9758 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, edx, dst2, "MUL operation");
9759 /* Apply the taint */
9760 expr2->isTainted = this->taintEngine->taintUnion(dst2, src2);
9761 expr2->isTainted = this->taintEngine->taintUnion(dst2, src1);
9762 /* Update symbolic flags */
9763 this->cfMul_s(inst, expr2, src2, edx);
9764 this->ofMul_s(inst, expr2, src2, edx);
9765 break;
9766 }
9767
9768 /* RDX:RAX = RAX * r/m64 */
9769 case triton::size::qword: {
9770 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX));
9771 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX));
9772 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX));
9773 /* Create symbolic operands */
9774 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
9775 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
9776 /* Create the semantics */
9777 /* Create symbolic expression for eax */
9778 auto rax = this->astCtxt->bvmul(op1, op2);
9779 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, rax, dst1, "MUL operation");
9780 /* Apply the taint */
9781 expr1->isTainted = this->taintEngine->taintUnion(dst1, src2);
9782 /* Create symbolic expression for rdx */
9783 auto node = this->astCtxt->bvmul(this->astCtxt->zx(triton::bitsize::qword, op1), this->astCtxt->zx(triton::bitsize::qword, op2));
9784 auto rdx = this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, node);
9785 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, rdx, dst2, "MUL operation");
9786 /* Apply the taint */
9787 expr2->isTainted = this->taintEngine->taintUnion(dst2, src2);
9788 expr2->isTainted = this->taintEngine->taintUnion(dst2, src1);
9789 /* Update symbolic flags */
9790 this->cfMul_s(inst, expr2, src2, rdx);
9791 this->ofMul_s(inst, expr2, src2, rdx);
9792 break;
9793 }
9794
9795 }
9796
9797 /* Tag undefined flags */
9798 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
9799 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
9800 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
9801 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF));
9802
9803 /* Update the symbolic control flow */
9804 this->controlFlow_s(inst);
9805 }
9806
9807
9808 void x86Semantics::mulx_s(triton::arch::Instruction& inst) {
9809 switch (inst.operands[0].getSize()) {
9810
9811 /* r32a, r32b, r/m32 */
9812 case triton::size::dword: {
9813 auto& dst1 = inst.operands[0];
9814 auto& dst2 = inst.operands[1];
9815 auto src1 = inst.operands[2];
9816 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
9817
9818 /* Create symbolic operands */
9819 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
9820 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
9821
9822 /* Create the semantics */
9823 auto node = this->astCtxt->bvmul(this->astCtxt->zx(triton::bitsize::dword, op1), this->astCtxt->zx(triton::bitsize::dword, op2));
9824 auto node1 = this->astCtxt->bvmul(op1, op2);
9825 auto node2 = this->astCtxt->extract((triton::bitsize::qword - 1), triton::bitsize::dword, node);
9826
9827 /* Create symbolic expression */
9828 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst2, "MULX operation");
9829 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst1, "MULX operation");
9830
9831 /* Apply the taint */
9832 expr1->isTainted = this->taintEngine->taintUnion(dst2, src1);
9833 expr1->isTainted = this->taintEngine->taintUnion(dst2, src2);
9834
9835 expr2->isTainted = this->taintEngine->taintUnion(dst1, src1);
9836 expr2->isTainted = this->taintEngine->taintUnion(dst1, src2);
9837 break;
9838 }
9839
9840 /* r64a, r64b, r/m64 */
9841 case triton::size::qword: {
9842 auto& dst1 = inst.operands[0];
9843 auto& dst2 = inst.operands[1];
9844 auto src1 = inst.operands[2];
9845 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX));
9846
9847 /* Create symbolic operands */
9848 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
9849 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
9850
9851 /* Create the semantics */
9852 auto node = this->astCtxt->bvmul(this->astCtxt->zx(triton::bitsize::qword, op1), this->astCtxt->zx(triton::bitsize::qword, op2));
9853 auto node1 = this->astCtxt->bvmul(op1, op2);
9854 auto node2 = this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, node);
9855
9856 /* Create symbolic expression for eax */
9857 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst2, "MULX operation");
9858 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst1, "MULX operation");
9859
9860 /* Apply the taint */
9861 expr1->isTainted = this->taintEngine->taintUnion(dst2, src1);
9862 expr1->isTainted = this->taintEngine->taintUnion(dst2, src2);
9863
9864 expr2->isTainted = this->taintEngine->taintUnion(dst1, src1);
9865 expr2->isTainted = this->taintEngine->taintUnion(dst1, src2);
9866 break;
9867 }
9868
9869 }
9870
9871 /* Update the symbolic control flow */
9872 this->controlFlow_s(inst);
9873 }
9874
9875
9876 void x86Semantics::neg_s(triton::arch::Instruction& inst) {
9877 auto& src = inst.operands[0];
9878
9879 /* Create symbolic operands */
9880 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9881
9882 /* Create the semantics */
9883 auto node = this->astCtxt->bvneg(op1);
9884
9885 /* Create symbolic expression */
9886 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, src, "NEG operation");
9887
9888 /* Apply the taint */
9889 expr->isTainted = this->taintEngine->taintUnion(src, src);
9890
9891 /* Update symbolic flags */
9892 this->afNeg_s(inst, expr, src, op1);
9893 this->cfNeg_s(inst, expr, src, op1);
9894 this->ofNeg_s(inst, expr, src, op1);
9895 this->pf_s(inst, expr, src);
9896 this->sf_s(inst, expr, src);
9897 this->zf_s(inst, expr, src);
9898
9899 /* Update the symbolic control flow */
9900 this->controlFlow_s(inst);
9901 }
9902
9903
9904 void x86Semantics::nop_s(triton::arch::Instruction& inst) {
9905 /* Update the symbolic control flow */
9906 this->controlFlow_s(inst);
9907 }
9908
9909
9910 void x86Semantics::not_s(triton::arch::Instruction& inst) {
9911 auto& src = inst.operands[0];
9912
9913 /* Create symbolic operands */
9914 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9915
9916 /* Create the semantics */
9917 auto node = this->astCtxt->bvnot(op1);
9918
9919 /* Create symbolic expression */
9920 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, src, "NOT operation");
9921
9922 /* Apply the taint */
9923 expr->isTainted = this->taintEngine->taintUnion(src, src);
9924
9925 /* Update the symbolic control flow */
9926 this->controlFlow_s(inst);
9927 }
9928
9929
9930 void x86Semantics::or_s(triton::arch::Instruction& inst) {
9931 auto& dst = inst.operands[0];
9932 auto& src = inst.operands[1];
9933
9934 /* Create symbolic operands */
9935 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
9936 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9937
9938 /* Create the semantics */
9939 auto node = this->astCtxt->bvor(op1, op2);
9940
9941 /* Create symbolic expression */
9942 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "OR operation");
9943
9944 /* Apply the taint */
9945 expr->isTainted = this->taintEngine->taintUnion(dst, src);
9946
9947 /* Update symbolic flags */
9948 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag");
9949 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
9950 this->pf_s(inst, expr, dst);
9951 this->sf_s(inst, expr, dst);
9952 this->zf_s(inst, expr, dst);
9953
9954 /* Tag undefined flags */
9955 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
9956
9957 /* Update the symbolic control flow */
9958 this->controlFlow_s(inst);
9959 }
9960
9961
9962 void x86Semantics::orpd_s(triton::arch::Instruction& inst) {
9963 auto& dst = inst.operands[0];
9964 auto& src = inst.operands[1];
9965
9966 /* Create symbolic operands */
9967 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
9968 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9969
9970 /* Create the semantics */
9971 auto node = this->astCtxt->bvor(op1, op2);
9972
9973 /* Create symbolic expression */
9974 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ORPD operation");
9975
9976 /* Apply the taint */
9977 expr->isTainted = this->taintEngine->taintUnion(dst, src);
9978
9979 /* Update the symbolic control flow */
9980 this->controlFlow_s(inst);
9981 }
9982
9983
9984 void x86Semantics::orps_s(triton::arch::Instruction& inst) {
9985 auto& dst = inst.operands[0];
9986 auto& src = inst.operands[1];
9987
9988 /* Create symbolic operands */
9989 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
9990 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9991
9992 /* Create the semantics */
9993 auto node = this->astCtxt->bvor(op1, op2);
9994
9995 /* Create symbolic expression */
9996 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ORPS operation");
9997
9998 /* Apply the taint */
9999 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10000
10001 /* Update the symbolic control flow */
10002 this->controlFlow_s(inst);
10003 }
10004
10005
10006 void x86Semantics::packuswb_s(triton::arch::Instruction& inst) {
10007 auto& dst = inst.operands[0];
10008 auto& src = inst.operands[1];
10009
10010 /* Create symbolic operands */
10011 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10012 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10013
10014 /* Create the semantics */
10015 std::vector<triton::ast::SharedAbstractNode> pck;
10016 pck.reserve(dst.getSize());
10017
10018 std::vector<triton::ast::SharedAbstractNode> ops{op2, op1};
10019 for (triton::uint32 i = 0; i < ops.size(); i++) {
10020 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
10021 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
10023 auto signed_word = this->astCtxt->extract(high, low, ops[i]);
10024 pck.push_back(this->astCtxt->ite(
10025 this->astCtxt->bvsge(signed_word, this->astCtxt->bv(0xff, triton::bitsize::word)),
10026 this->astCtxt->bv(0xff, triton::bitsize::byte),
10027 this->astCtxt->ite(
10028 this->astCtxt->bvsle(signed_word, this->astCtxt->bv(0x00, triton::bitsize::word)),
10029 this->astCtxt->bv(0x00, triton::bitsize::byte),
10030 this->astCtxt->extract(triton::bitsize::byte - 1, 0, signed_word)))
10031 );
10032 }
10033 }
10034
10035 auto node = this->astCtxt->concat(pck);
10036
10037 /* Create symbolic expression */
10038 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PACKUSWB operation");
10039
10040 /* Apply the taint */
10041 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10042
10043 /* Update the symbolic control flow */
10044 this->controlFlow_s(inst);
10045 }
10046
10047
10048 void x86Semantics::packssdw_s(triton::arch::Instruction& inst) {
10049 auto& dst = inst.operands[0];
10050 auto& src = inst.operands[1];
10051
10052 /* Create symbolic operands */
10053 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10054 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10055
10056 /* Create the semantics */
10057 std::vector<triton::ast::SharedAbstractNode> pck;
10058 pck.reserve(dst.getSize() / triton::size::word);
10059
10060 std::vector<triton::ast::SharedAbstractNode> ops{op2, op1};
10061
10062 for (triton::uint32 idx = 0; idx < ops.size(); ++idx) {
10063 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::dword; ++i) {
10064 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::dword);
10066 auto signed_dword = this->astCtxt->extract(high, low, ops[idx]);
10067 pck.push_back(this->astCtxt->ite(
10068 this->astCtxt->bvsge(signed_dword, this->astCtxt->bv(0x7fff, triton::bitsize::dword)),
10069 this->astCtxt->bv(0x7fff, triton::bitsize::word),
10070 this->astCtxt->ite(
10071 this->astCtxt->bvsle(signed_dword, this->astCtxt->bv(0xffff8000, triton::bitsize::dword)),
10072 this->astCtxt->bv(0x8000, triton::bitsize::word),
10073 this->astCtxt->extract(triton::bitsize::word - 1, 0, signed_dword)))
10074 );
10075 }
10076 }
10077
10078 auto node = this->astCtxt->concat(pck);
10079
10080 /* Create symbolic expression */
10081 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PACKSSDW operation");
10082
10083 /* Apply the taint */
10084 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10085
10086 /* Update the symbolic control flow */
10087 this->controlFlow_s(inst);
10088 }
10089
10090
10091 void x86Semantics::packsswb_s(triton::arch::Instruction& inst) {
10092 auto& dst = inst.operands[0];
10093 auto& src = inst.operands[1];
10094
10095 /* Create symbolic operands */
10096 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10097 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10098
10099 /* Create the semantics */
10100 std::vector<triton::ast::SharedAbstractNode> pck;
10101 pck.reserve(dst.getSize());
10102
10103 std::vector<triton::ast::SharedAbstractNode> ops{op2, op1};
10104 for (triton::uint32 i = 0; i < ops.size(); i++) {
10105 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
10106 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
10108 auto signed_word = this->astCtxt->extract(high, low, ops[i]);
10109 pck.push_back(this->astCtxt->ite(
10110 this->astCtxt->bvsge(signed_word, this->astCtxt->bv(0x007f, triton::bitsize::word)),
10111 this->astCtxt->bv(0x7f, triton::bitsize::byte),
10112 this->astCtxt->ite(
10113 this->astCtxt->bvsle(signed_word, this->astCtxt->bv(0xff80, triton::bitsize::word)),
10114 this->astCtxt->bv(0x80, triton::bitsize::byte),
10115 this->astCtxt->extract(triton::bitsize::byte - 1, 0, signed_word)))
10116 );
10117 }
10118 }
10119
10120 auto node = this->astCtxt->concat(pck);
10121
10122 /* Create symbolic expression */
10123 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PACKSSWB operation");
10124
10125 /* Apply the taint */
10126 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10127
10128 /* Update the symbolic control flow */
10129 this->controlFlow_s(inst);
10130 }
10131
10132
10133 void x86Semantics::paddb_s(triton::arch::Instruction& inst) {
10134 auto& dst = inst.operands[0];
10135 auto& src = inst.operands[1];
10136
10137 /* Create symbolic operands */
10138 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10139 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10140
10141 /* Create the semantics */
10142 std::vector<triton::ast::SharedAbstractNode> packed;
10143 packed.reserve(16);
10144
10145 switch (dst.getBitSize()) {
10146
10147 /* XMM */
10149 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(127, 120, op1), this->astCtxt->extract(127, 120, op2)));
10150 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(119, 112, op1), this->astCtxt->extract(119, 112, op2)));
10151 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(111, 104, op1), this->astCtxt->extract(111, 104, op2)));
10152 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(103, 96, op1), this->astCtxt->extract(103, 96, op2)));
10153 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(95, 88, op1), this->astCtxt->extract(95, 88, op2)));
10154 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(87, 80, op1), this->astCtxt->extract(87, 80, op2)));
10155 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(79, 72, op1), this->astCtxt->extract(79, 72, op2)));
10156 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(71, 64, op1), this->astCtxt->extract(71, 64, op2)));
10157
10158 /* MMX */
10160 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(63, 56, op1), this->astCtxt->extract(63, 56, op2)));
10161 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(55, 48, op1), this->astCtxt->extract(55, 48, op2)));
10162 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(47, 40, op1), this->astCtxt->extract(47, 40, op2)));
10163 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(39, 32, op1), this->astCtxt->extract(39, 32, op2)));
10164 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(31, 24, op1), this->astCtxt->extract(31, 24, op2)));
10165 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(23, 16, op1), this->astCtxt->extract(23, 16, op2)));
10166 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(15, 8, op1), this->astCtxt->extract(15, 8, op2)));
10167 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(7, 0, op1), this->astCtxt->extract(7, 0, op2)));
10168 break;
10169
10170 default:
10171 throw triton::exceptions::Semantics("x86Semantics::paddb_s(): Invalid operand size.");
10172
10173 }
10174
10175 auto node = this->astCtxt->concat(packed);
10176
10177 /* Create symbolic expression */
10178 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PADDB operation");
10179
10180 /* Update the x87 FPU Tag Word */
10181 if (dst.getBitSize() == triton::bitsize::qword) {
10182 this->updateFTW(inst, expr);
10183 }
10184
10185 /* Spread taint */
10186 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10187
10188 /* Update the symbolic control flow */
10189 this->controlFlow_s(inst);
10190 }
10191
10192
10193 void x86Semantics::paddd_s(triton::arch::Instruction& inst) {
10194 auto& dst = inst.operands[0];
10195 auto& src = inst.operands[1];
10196
10197 /* Create symbolic operands */
10198 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10199 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10200
10201 /* Create the semantics */
10202 std::vector<triton::ast::SharedAbstractNode> packed;
10203 packed.reserve(4);
10204
10205 switch (dst.getBitSize()) {
10206
10207 /* XMM */
10209 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(127, 96, op1), this->astCtxt->extract(127, 96, op2)));
10210 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(95, 64, op1), this->astCtxt->extract(95, 64, op2)));
10211
10212 /* MMX */
10214 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(63, 32, op1), this->astCtxt->extract(63, 32, op2)));
10215 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(31, 0, op1), this->astCtxt->extract(31, 0, op2)));
10216 break;
10217
10218 default:
10219 throw triton::exceptions::Semantics("x86Semantics::paddd_s(): Invalid operand size.");
10220
10221 }
10222
10223 auto node = this->astCtxt->concat(packed);
10224
10225 /* Create symbolic expression */
10226 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PADDD operation");
10227
10228 /* Update the x87 FPU Tag Word */
10229 if (dst.getBitSize() == triton::bitsize::qword) {
10230 this->updateFTW(inst, expr);
10231 }
10232
10233 /* Spread taint */
10234 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10235
10236 /* Update the symbolic control flow */
10237 this->controlFlow_s(inst);
10238 }
10239
10240
10241 void x86Semantics::paddq_s(triton::arch::Instruction& inst) {
10242 auto& dst = inst.operands[0];
10243 auto& src = inst.operands[1];
10244
10245 /* Create symbolic operands */
10246 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10247 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10248
10249 /* Create the semantics */
10250 std::vector<triton::ast::SharedAbstractNode> packed;
10251 packed.reserve(2);
10252
10253 switch (dst.getBitSize()) {
10254
10255 /* XMM */
10257 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(127, 64, op1), this->astCtxt->extract(127, 64, op2)));
10258
10259 /* MMX */
10261 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(63, 0, op1), this->astCtxt->extract(63, 0, op2)));
10262 break;
10263
10264 default:
10265 throw triton::exceptions::Semantics("x86Semantics::paddq_s(): Invalid operand size.");
10266
10267 }
10268
10269 auto node = this->astCtxt->concat(packed);
10270
10271 /* Create symbolic expression */
10272 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PADDQ operation");
10273
10274 /* Update the x87 FPU Tag Word */
10275 if (dst.getBitSize() == triton::bitsize::qword) {
10276 this->updateFTW(inst, expr);
10277 }
10278
10279 /* Spread taint */
10280 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10281
10282 /* Update the symbolic control flow */
10283 this->controlFlow_s(inst);
10284 }
10285
10286
10287 void x86Semantics::paddw_s(triton::arch::Instruction& inst) {
10288 auto& dst = inst.operands[0];
10289 auto& src = inst.operands[1];
10290
10291 /* Create symbolic operands */
10292 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10293 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10294
10295 /* Create the semantics */
10296 std::vector<triton::ast::SharedAbstractNode> packed;
10297 packed.reserve(8);
10298
10299 switch (dst.getBitSize()) {
10300
10301 /* XMM */
10303 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(127, 112, op1), this->astCtxt->extract(127, 112, op2)));
10304 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(111, 96, op1), this->astCtxt->extract(111, 96, op2)));
10305 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(95, 80, op1), this->astCtxt->extract(95, 80, op2)));
10306 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(79, 64, op1), this->astCtxt->extract(79, 64, op2)));
10307
10308 /* MMX */
10310 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(63, 48, op1), this->astCtxt->extract(63, 48, op2)));
10311 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(47, 32, op1), this->astCtxt->extract(47, 32, op2)));
10312 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(31, 16, op1), this->astCtxt->extract(31, 16, op2)));
10313 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(15, 0, op1), this->astCtxt->extract(15, 0, op2)));
10314 break;
10315
10316 default:
10317 throw triton::exceptions::Semantics("x86Semantics::paddw_s(): Invalid operand size.");
10318
10319 }
10320
10321 auto node = this->astCtxt->concat(packed);
10322
10323 /* Create symbolic expression */
10324 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PADDW operation");
10325
10326 /* Update the x87 FPU Tag Word */
10327 if (dst.getBitSize() == triton::bitsize::qword) {
10328 this->updateFTW(inst, expr);
10329 }
10330
10331 /* Spread taint */
10332 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10333
10334 /* Update the symbolic control flow */
10335 this->controlFlow_s(inst);
10336 }
10337
10338
10339 void x86Semantics::palignr_s(triton::arch::Instruction& inst) {
10340 auto& dst = inst.operands[0];
10341 auto& src1 = inst.operands[1];
10342 auto& src2 = inst.operands[2];
10343
10344 /* Create symbolic operands */
10345 auto size = 2 * dst.getBitSize();
10346 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10347 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
10348 auto op3 = this->astCtxt->zx(size - src2.getBitSize(), this->symbolicEngine->getOperandAst(inst, src2));
10349
10350 /* Create the semantics */
10351 auto node = this->astCtxt->extract(
10352 dst.getBitSize() - 1, 0,
10353 this->astCtxt->bvlshr(
10354 this->astCtxt->concat(op1, op2),
10355 this->astCtxt->bvmul(
10356 this->astCtxt->ite(
10357 this->astCtxt->bvuge(op3, this->astCtxt->bv(2 * dst.getSize(), size)),
10358 this->astCtxt->bv(2 * dst.getSize(), size),
10359 op3),
10360 this->astCtxt->bv(triton::bitsize::byte, size)
10361 )));
10362
10363 /* Create symbolic expression */
10364 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PALIGNR operation");
10365
10366 /* Spread taint */
10367 expr->isTainted = this->taintEngine->taintUnion(dst, src1);
10368
10369 /* Update the symbolic control flow */
10370 this->controlFlow_s(inst);
10371 }
10372
10373
10374 void x86Semantics::pand_s(triton::arch::Instruction& inst) {
10375 auto& dst = inst.operands[0];
10376 auto& src = inst.operands[1];
10377
10378 /* Create symbolic operands */
10379 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10380 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10381
10382 /* Create the semantics */
10383 auto node = this->astCtxt->bvand(op1, op2);
10384
10385 /* Create symbolic expression */
10386 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PAND operation");
10387
10388 /* Update the x87 FPU Tag Word */
10389 this->updateFTW(inst, expr);
10390
10391 /* Spread taint */
10392 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10393
10394 /* Update the symbolic control flow */
10395 this->controlFlow_s(inst);
10396 }
10397
10398
10399 void x86Semantics::pandn_s(triton::arch::Instruction& inst) {
10400 auto& dst = inst.operands[0];
10401 auto& src = inst.operands[1];
10402
10403 /* Create symbolic operands */
10404 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10405 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10406
10407 /* Create the semantics */
10408 auto node = this->astCtxt->bvand(this->astCtxt->bvnot(op1), op2);
10409
10410 /* Create symbolic expression */
10411 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PANDN operation");
10412
10413 /* Update the x87 FPU Tag Word */
10414 this->updateFTW(inst, expr);
10415
10416 /* Spread taint */
10417 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10418
10419 /* Update the symbolic control flow */
10420 this->controlFlow_s(inst);
10421 }
10422
10423
10424 void x86Semantics::pause_s(triton::arch::Instruction& inst) {
10425 /* Update the symbolic control flow */
10426 this->controlFlow_s(inst);
10427 }
10428
10429
10430 void x86Semantics::pavgb_s(triton::arch::Instruction& inst) {
10431 auto& dst = inst.operands[0];
10432 auto& src = inst.operands[1];
10433
10434 /* Create symbolic operands */
10435 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10436 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10437
10438 /* Create the semantics */
10439 std::vector<triton::ast::SharedAbstractNode> pck;
10440 pck.reserve(dst.getSize());
10441
10442 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
10443 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
10445 pck.push_back(
10446 this->astCtxt->extract(triton::bitsize::byte-1, 0,
10447 this->astCtxt->bvlshr(
10448 this->astCtxt->bvadd(
10449 this->astCtxt->bvadd(
10450 this->astCtxt->zx(1, this->astCtxt->extract(high, low, op1)),
10451 this->astCtxt->zx(1, this->astCtxt->extract(high, low, op2))
10452 ),
10453 this->astCtxt->bv(1, triton::bitsize::byte+1)
10454 ),
10455 this->astCtxt->bv(1, triton::bitsize::byte+1)
10456 )
10457 )
10458 );
10459 }
10460
10461 auto node = this->astCtxt->concat(pck);
10462
10463 /* Create symbolic expression */
10464 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PAVGB operation");
10465
10466 /* Spread taint */
10467 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10468
10469 /* Update the symbolic control flow */
10470 this->controlFlow_s(inst);
10471 }
10472
10473
10474 void x86Semantics::pavgw_s(triton::arch::Instruction& inst) {
10475 auto& dst = inst.operands[0];
10476 auto& src = inst.operands[1];
10477
10478 /* Create symbolic operands */
10479 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10480 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10481
10482 /* Create the semantics */
10483 std::vector<triton::ast::SharedAbstractNode> pck;
10484 pck.reserve(dst.getSize());
10485
10486 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
10487 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
10489 pck.push_back(
10490 this->astCtxt->extract(triton::bitsize::word-1, 0,
10491 this->astCtxt->bvlshr(
10492 this->astCtxt->bvadd(
10493 this->astCtxt->bvadd(
10494 this->astCtxt->zx(1, this->astCtxt->extract(high, low, op1)),
10495 this->astCtxt->zx(1, this->astCtxt->extract(high, low, op2))
10496 ),
10497 this->astCtxt->bv(1, triton::bitsize::word+1)
10498 ),
10499 this->astCtxt->bv(1, triton::bitsize::word+1)
10500 )
10501 )
10502 );
10503 }
10504
10505 auto node = this->astCtxt->concat(pck);
10506
10507 /* Create symbolic expression */
10508 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PAVGW operation");
10509
10510 /* Spread taint */
10511 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10512
10513 /* Update the symbolic control flow */
10514 this->controlFlow_s(inst);
10515 }
10516
10517
10518 void x86Semantics::pcmpeqb_s(triton::arch::Instruction& inst) {
10519 auto& dst = inst.operands[0];
10520 auto& src = inst.operands[1];
10521
10522 /* Create symbolic operands */
10523 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10524 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10525
10526 /* Create the semantics */
10527 std::vector<triton::ast::SharedAbstractNode> pck;
10528 pck.reserve(dst.getSize());
10529
10530 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
10531 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
10533 pck.push_back(this->astCtxt->ite(
10534 this->astCtxt->equal(
10535 this->astCtxt->extract(high, low, op1),
10536 this->astCtxt->extract(high, low, op2)),
10537 this->astCtxt->bv(0xff, triton::bitsize::byte),
10538 this->astCtxt->bv(0x00, triton::bitsize::byte))
10539 );
10540 }
10541
10542 auto node = this->astCtxt->concat(pck);
10543
10544 /* Create symbolic expression */
10545 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PCMPEQB operation");
10546
10547 /* Apply the taint */
10548 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10549
10550 /* Update the symbolic control flow */
10551 this->controlFlow_s(inst);
10552 }
10553
10554
10555 void x86Semantics::pcmpeqd_s(triton::arch::Instruction& inst) {
10556 auto& dst = inst.operands[0];
10557 auto& src = inst.operands[1];
10558
10559 /* Create symbolic operands */
10560 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10561 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10562
10563 /* Create the semantics */
10564 std::vector<triton::ast::SharedAbstractNode> pck;
10565 pck.reserve(dst.getSize() / triton::size::dword);
10566
10567 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) {
10568 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword);
10570 pck.push_back(this->astCtxt->ite(
10571 this->astCtxt->equal(
10572 this->astCtxt->extract(high, low, op1),
10573 this->astCtxt->extract(high, low, op2)),
10574 this->astCtxt->bv(0xffffffff, triton::bitsize::dword),
10575 this->astCtxt->bv(0x00000000, triton::bitsize::dword))
10576 );
10577 }
10578
10579 auto node = this->astCtxt->concat(pck);
10580
10581 /* Create symbolic expression */
10582 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PCMPEQD operation");
10583
10584 /* Apply the taint */
10585 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10586
10587 /* Update the symbolic control flow */
10588 this->controlFlow_s(inst);
10589 }
10590
10591
10592 void x86Semantics::pcmpeqw_s(triton::arch::Instruction& inst) {
10593 auto& dst = inst.operands[0];
10594 auto& src = inst.operands[1];
10595
10596 /* Create symbolic operands */
10597 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10598 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10599
10600 /* Create the semantics */
10601 std::vector<triton::ast::SharedAbstractNode> pck;
10602 pck.reserve(dst.getSize() / triton::size::word);
10603
10604 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
10605 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
10607 pck.push_back(this->astCtxt->ite(
10608 this->astCtxt->equal(
10609 this->astCtxt->extract(high, low, op1),
10610 this->astCtxt->extract(high, low, op2)),
10611 this->astCtxt->bv(0xffff, triton::bitsize::word),
10612 this->astCtxt->bv(0x0000, triton::bitsize::word))
10613 );
10614 }
10615
10616 auto node = this->astCtxt->concat(pck);
10617
10618 /* Create symbolic expression */
10619 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PCMPEQW operation");
10620
10621 /* Apply the taint */
10622 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10623
10624 /* Update the symbolic control flow */
10625 this->controlFlow_s(inst);
10626 }
10627
10628
10629 void x86Semantics::pcmpgtb_s(triton::arch::Instruction& inst) {
10630 auto& dst = inst.operands[0];
10631 auto& src = inst.operands[1];
10632
10633 /* Create symbolic operands */
10634 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10635 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10636
10637 /* Create the semantics */
10638 std::vector<triton::ast::SharedAbstractNode> pck;
10639 pck.reserve(dst.getSize());
10640
10641 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
10642 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
10644 pck.push_back(this->astCtxt->ite(
10645 this->astCtxt->bvsgt(
10646 this->astCtxt->extract(high, low, op1),
10647 this->astCtxt->extract(high, low, op2)),
10648 this->astCtxt->bv(0xff, triton::bitsize::byte),
10649 this->astCtxt->bv(0x00, triton::bitsize::byte))
10650 );
10651 }
10652
10653 auto node = this->astCtxt->concat(pck);
10654
10655 /* Create symbolic expression */
10656 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PCMPGTB operation");
10657
10658 /* Apply the taint */
10659 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10660
10661 /* Update the symbolic control flow */
10662 this->controlFlow_s(inst);
10663 }
10664
10665
10666 void x86Semantics::pcmpgtd_s(triton::arch::Instruction& inst) {
10667 auto& dst = inst.operands[0];
10668 auto& src = inst.operands[1];
10669
10670 /* Create symbolic operands */
10671 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10672 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10673
10674 /* Create the semantics */
10675 std::vector<triton::ast::SharedAbstractNode> pck;
10676 pck.reserve(dst.getSize());
10677
10678 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) {
10679 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword);
10681 pck.push_back(this->astCtxt->ite(
10682 this->astCtxt->bvsgt(
10683 this->astCtxt->extract(high, low, op1),
10684 this->astCtxt->extract(high, low, op2)),
10685 this->astCtxt->bv(0xffffffff, triton::bitsize::dword),
10686 this->astCtxt->bv(0x00000000, triton::bitsize::dword))
10687 );
10688 }
10689
10690 auto node = this->astCtxt->concat(pck);
10691
10692 /* Create symbolic expression */
10693 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PCMPGTD operation");
10694
10695 /* Apply the taint */
10696 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10697
10698 /* Update the symbolic control flow */
10699 this->controlFlow_s(inst);
10700 }
10701
10702
10703 void x86Semantics::pcmpgtw_s(triton::arch::Instruction& inst) {
10704 auto& dst = inst.operands[0];
10705 auto& src = inst.operands[1];
10706
10707 /* Create symbolic operands */
10708 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10709 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10710
10711 /* Create the semantics */
10712 std::vector<triton::ast::SharedAbstractNode> pck;
10713 pck.reserve(dst.getSize());
10714
10715 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
10716 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
10718 pck.push_back(this->astCtxt->ite(
10719 this->astCtxt->bvsgt(
10720 this->astCtxt->extract(high, low, op1),
10721 this->astCtxt->extract(high, low, op2)),
10722 this->astCtxt->bv(0xffff, triton::bitsize::word),
10723 this->astCtxt->bv(0x0000, triton::bitsize::word))
10724 );
10725 }
10726
10727 auto node = this->astCtxt->concat(pck);
10728
10729 /* Create symbolic expression */
10730 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PCMPGTW operation");
10731
10732 /* Apply the taint */
10733 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10734
10735 /* Update the symbolic control flow */
10736 this->controlFlow_s(inst);
10737 }
10738
10739
10740 void x86Semantics::pmaxsb_s(triton::arch::Instruction& inst) {
10741 auto& dst = inst.operands[0];
10742 auto& src = inst.operands[1];
10743
10744 /* Create symbolic operands */
10745 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10746 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10747
10748 /* Create the semantics */
10749 std::vector<triton::ast::SharedAbstractNode> pck;
10750 pck.reserve(dst.getSize());
10751
10752 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
10753 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
10755 pck.push_back(this->astCtxt->ite(
10756 this->astCtxt->bvsle(
10757 this->astCtxt->extract(high, low, op1),
10758 this->astCtxt->extract(high, low, op2)),
10759 this->astCtxt->extract(high, low, op2),
10760 this->astCtxt->extract(high, low, op1))
10761 );
10762 }
10763
10764 auto node = this->astCtxt->concat(pck);
10765
10766 /* Create symbolic expression */
10767 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMAXSB operation");
10768
10769 /* Apply the taint */
10770 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10771
10772 /* Update the symbolic control flow */
10773 this->controlFlow_s(inst);
10774 }
10775
10776
10777 void x86Semantics::pextrb_s(triton::arch::Instruction& inst) {
10778 auto& dst = inst.operands[0];
10779 auto& src1 = inst.operands[1];
10780 auto& src2 = inst.operands[2];
10781
10782 /* Create symbolic operands */
10783 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10784 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
10785 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
10786
10787 auto node = this->astCtxt->extract(triton::bitsize::byte - 1, 0,
10788 this->astCtxt->bvlshr(
10789 op2,
10790 this->astCtxt->bv(((op3->evaluate() & 0x0f) * triton::bitsize::byte), op2->getBitvectorSize())
10791 )
10792 );
10793
10794 /* Create symbolic expression */
10795 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PEXTRB operation");
10796
10797 /* Apply the taint */
10798 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
10799
10800 /* Update the symbolic control flow */
10801 this->controlFlow_s(inst);
10802 }
10803
10804
10805 void x86Semantics::pextrd_s(triton::arch::Instruction& inst) {
10806 auto& dst = inst.operands[0];
10807 auto& src1 = inst.operands[1];
10808 auto& src2 = inst.operands[2];
10809
10810 /* Create symbolic operands */
10811 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10812 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
10813 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
10814
10815 auto node = this->astCtxt->extract(triton::bitsize::dword - 1, 0,
10816 this->astCtxt->bvlshr(
10817 op2,
10818 this->astCtxt->bv(((op3->evaluate() & 0x3) * triton::bitsize::dword), op2->getBitvectorSize())
10819 )
10820 );
10821
10822 /* Create symbolic expression */
10823 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PEXTRD operation");
10824
10825 /* Apply the taint */
10826 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
10827
10828 /* Update the symbolic control flow */
10829 this->controlFlow_s(inst);
10830 }
10831
10832
10833 void x86Semantics::pextrq_s(triton::arch::Instruction& inst) {
10834 auto& dst = inst.operands[0];
10835 auto& src1 = inst.operands[1];
10836 auto& src2 = inst.operands[2];
10837
10838 /* Create symbolic operands */
10839 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10840 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
10841 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
10842
10843 auto node = this->astCtxt->extract(triton::bitsize::qword - 1, 0,
10844 this->astCtxt->bvlshr(
10845 op2,
10846 this->astCtxt->bv(((op3->evaluate() & 0x1) * triton::bitsize::qword), op2->getBitvectorSize())
10847 )
10848 );
10849
10850 /* Create symbolic expression */
10851 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PEXTRQ operation");
10852
10853 /* Apply the taint */
10854 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
10855
10856 /* Update the symbolic control flow */
10857 this->controlFlow_s(inst);
10858 }
10859
10860
10861 void x86Semantics::pextrw_s(triton::arch::Instruction& inst) {
10862 triton::uint32 count = 0;
10863 auto& dst = inst.operands[0];
10864 auto& src1 = inst.operands[1];
10865 auto& src2 = inst.operands[2];
10866
10867 /*
10868 * When specifying a word location in an MMX technology register, the
10869 * 2 least-significant bits of the count operand specify the location;
10870 * for an XMM register, the 3 least-significant bits specify the
10871 * location.
10872 */
10873 if (src1.getBitSize() == triton::bitsize::qword) {
10874 count = 0x03;
10875 }
10876 else {
10877 count = 0x07;
10878 }
10879
10880 /* Create symbolic operands */
10881 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10882 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
10883 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
10884
10885 auto node = this->astCtxt->extract(triton::bitsize::word - 1, 0,
10886 this->astCtxt->bvlshr(
10887 op2,
10888 this->astCtxt->bv(((op3->evaluate() & count) * triton::bitsize::word), op2->getBitvectorSize())
10889 )
10890 );
10891
10892 /* Create symbolic expression */
10893 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PEXTRW operation");
10894
10895 /* Apply the taint */
10896 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
10897
10898 /* Update the symbolic control flow */
10899 this->controlFlow_s(inst);
10900 }
10901
10902
10903 void x86Semantics::pinsrb_s(triton::arch::Instruction& inst) {
10904 auto& dst = inst.operands[0];
10905 auto& src1 = inst.operands[1];
10906 auto& src2 = inst.operands[2];
10907
10908 /* Create symbolic operands */
10909 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10910 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
10911 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
10912
10913 // SEL = COUNT[3:0];
10914 // MASK = (0FFH << (SEL * 8));
10915 triton::uint64 sel = static_cast<triton::uint64>(op3->evaluate()) & 0x0f;
10916 triton::uint128 mask = 0xff;
10917 mask = mask << (sel * 8);
10918
10919 // TEMP = ((SRC[7:0] << (SEL * 8)) AND MASK);
10920 auto temp = this->astCtxt->bvand(
10921 this->astCtxt->bvshl(
10922 this->astCtxt->zx(120, this->astCtxt->extract(7, 0, op2)),
10923 this->astCtxt->bv(sel * 8, 128)
10924 ),
10925 this->astCtxt->bv(mask, 128)
10926 );
10927
10928 // DEST = ((DEST AND NOT MASK) OR TEMP);
10929 auto node = this->astCtxt->bvor(
10930 this->astCtxt->bvand(
10931 op1,
10932 this->astCtxt->bvnot(this->astCtxt->bv(mask, 128))
10933 ),
10934 temp
10935 );
10936
10937 /* Create symbolic expression */
10938 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PINSRB operation");
10939
10940 /* Apply the taint */
10941 expr->isTainted = this->taintEngine->taintUnion(dst, src1);
10942
10943 /* Update the symbolic control flow */
10944 this->controlFlow_s(inst);
10945 }
10946
10947
10948 void x86Semantics::pinsrd_s(triton::arch::Instruction& inst) {
10949 auto& dst = inst.operands[0];
10950 auto& src1 = inst.operands[1];
10951 auto& src2 = inst.operands[2];
10952
10953 /* Create symbolic operands */
10954 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10955 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
10956 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
10957
10958 // SEL = COUNT[1:0];
10959 // MASK = (0FFFFFFFFH << (SEL * 32));
10960 triton::uint64 sel = static_cast<triton::uint64>(op3->evaluate()) & 0x03;
10961 triton::uint128 mask = 0xffffffff;
10962 mask = mask << (sel * 32);
10963
10964 // TEMP = ((SRC[31:0] << (SEL * 32)) AND MASK);
10965 auto temp = this->astCtxt->bvand(
10966 this->astCtxt->bvshl(
10967 this->astCtxt->zx(96, this->astCtxt->extract(31, 0, op2)),
10968 this->astCtxt->bv(sel * 32, 128)
10969 ),
10970 this->astCtxt->bv(mask, 128)
10971 );
10972
10973 // DEST = ((DEST AND NOT MASK) OR TEMP);
10974 auto node = this->astCtxt->bvor(
10975 this->astCtxt->bvand(
10976 op1,
10977 this->astCtxt->bvnot(this->astCtxt->bv(mask, 128))
10978 ),
10979 temp
10980 );
10981
10982 /* Create symbolic expression */
10983 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PINSRD operation");
10984
10985 /* Apply the taint */
10986 expr->isTainted = this->taintEngine->taintUnion(dst, src1);
10987
10988 /* Update the symbolic control flow */
10989 this->controlFlow_s(inst);
10990 }
10991
10992
10993 void x86Semantics::pinsrq_s(triton::arch::Instruction& inst) {
10994 auto& dst = inst.operands[0];
10995 auto& src1 = inst.operands[1];
10996 auto& src2 = inst.operands[2];
10997
10998 /* Create symbolic operands */
10999 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11000 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
11001 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
11002
11003 // SEL = COUNT[0:0];
11004 // MASK = (0FFFFFFFFFFFFFFFFH << (SEL * 64));
11005 triton::uint64 sel = static_cast<triton::uint64>(op3->evaluate()) & 0x1;
11006 triton::uint128 mask = 0xffffffffffffffff;
11007 mask = mask << (sel * 64);
11008
11009 // TEMP = ((SRC[63:0] << (SEL * 64)) AND MASK);
11010 auto temp = this->astCtxt->bvand(
11011 this->astCtxt->bvshl(
11012 this->astCtxt->zx(64, this->astCtxt->extract(63, 0, op2)),
11013 this->astCtxt->bv(sel * 64, 128)
11014 ),
11015 this->astCtxt->bv(mask, 128)
11016 );
11017
11018 // DEST = ((DEST AND NOT MASK) OR TEMP);
11019 auto node = this->astCtxt->bvor(
11020 this->astCtxt->bvand(
11021 op1,
11022 this->astCtxt->bvnot(this->astCtxt->bv(mask, 128))
11023 ),
11024 temp
11025 );
11026
11027 /* Create symbolic expression */
11028 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PINSRQ operation");
11029
11030 /* Apply the taint */
11031 expr->isTainted = this->taintEngine->taintUnion(dst, src1);
11032
11033 /* Update the symbolic control flow */
11034 this->controlFlow_s(inst);
11035 }
11036
11037
11038 void x86Semantics::pinsrw_s(triton::arch::Instruction& inst) {
11039 triton::uint128 mask = 0xffff;
11040 triton::uint64 sel = 0;
11041 auto& dst = inst.operands[0];
11042 auto& src1 = inst.operands[1];
11043 auto& src2 = inst.operands[2];
11044
11045 /* Create symbolic operands */
11046 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11047 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
11048 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
11049
11050 /*
11051 * PINSRW (with 64-bit source operand)
11052 *
11053 * SEL = COUNT AND 3H;
11054 * CASE (Determine word position) {
11055 * if SEL == 0: MASK = 000000000000FFFFH;
11056 * if SEL == 1: MASK = 00000000FFFF0000H;
11057 * if SEL == 2: MASK = 0000FFFF00000000H;
11058 * if SEL == 3: MASK = FFFF000000000000H;
11059 * }
11060 */
11061 if (dst.getBitSize() == triton::bitsize::qword) {
11062 sel = static_cast<triton::uint64>(op3->evaluate()) & 0x3;
11063 switch (sel) {
11064 case 1: mask = mask << 16; break;
11065 case 2: mask = mask << 32; break;
11066 case 3: mask = mask << 48; break;
11067 }
11068 }
11069
11070 /*
11071 * PINSRW (with 128-bit source operand)
11072 *
11073 * SEL ← COUNT AND 7H;
11074 * CASE (Determine word position) {
11075 * SEL == 0: MASK = 0000000000000000000000000000FFFFH;
11076 * SEL == 1: MASK = 000000000000000000000000FFFF0000H;
11077 * SEL == 2: MASK = 00000000000000000000FFFF00000000H;
11078 * SEL == 3: MASK = 0000000000000000FFFF000000000000H;
11079 * SEL == 4: MASK = 000000000000FFFF0000000000000000H;
11080 * SEL == 5: MASK = 00000000FFFF00000000000000000000H;
11081 * SEL == 6: MASK = 0000FFFF000000000000000000000000H;
11082 * SEL == 7: MASK = FFFF0000000000000000000000000000H;
11083 * }
11084 */
11085 else {
11086 sel = static_cast<triton::uint64>(op3->evaluate()) & 0x7;
11087 switch (sel) {
11088 case 1: mask = mask << 16; break;
11089 case 2: mask = mask << 32; break;
11090 case 3: mask = mask << 48; break;
11091 case 4: mask = mask << 64; break;
11092 case 5: mask = mask << 80; break;
11093 case 6: mask = mask << 96; break;
11094 case 7: mask = mask << 112; break;
11095 }
11096 }
11097
11098 // TEMP = ((SRC << (SEL ∗ 16)) AND MASK);
11099 auto temp = this->astCtxt->bvand(
11100 this->astCtxt->bvshl(
11101 this->astCtxt->zx(112, this->astCtxt->extract(15, 0, op2)),
11102 this->astCtxt->bv(sel * 16, 128)
11103 ),
11104 this->astCtxt->bv(mask, 128)
11105 );
11106
11107 // DEST = ((DEST AND NOT MASK) OR TEMP);
11108 auto node = this->astCtxt->bvor(
11109 this->astCtxt->bvand(
11110 op1,
11111 this->astCtxt->bvnot(this->astCtxt->bv(mask, 128))
11112 ),
11113 temp
11114 );
11115
11116 /* Create symbolic expression */
11117 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PINSRW operation");
11118
11119 /* Apply the taint */
11120 expr->isTainted = this->taintEngine->taintUnion(dst, src1);
11121
11122 /* Update the symbolic control flow */
11123 this->controlFlow_s(inst);
11124 }
11125
11126
11127 void x86Semantics::pmaddwd_s(triton::arch::Instruction& inst) {
11128 auto& dst = inst.operands[0];
11129 auto& src = inst.operands[1];
11130
11131 /* Create symbolic operands */
11132 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11133 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11134
11135 /* Create the semantics */
11136 std::vector<triton::ast::SharedAbstractNode> pck;
11137 pck.reserve(dst.getSize() / triton::size::dword);
11138
11139 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; i += 2) {
11140 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
11142 auto node1 = this->astCtxt->bvmul(
11143 this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op1)),
11144 this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op2))
11145 );
11146 high -= triton::bitsize::word;
11147 low -= triton::bitsize::word;
11148 auto node2 = this->astCtxt->bvmul(
11149 this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op1)),
11150 this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op2))
11151 );
11152 pck.push_back(this->astCtxt->bvadd(node1, node2));
11153 }
11154
11155 auto node = this->astCtxt->concat(pck);
11156
11157 /* Create symbolic expression */
11158 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMADDWD operation");
11159
11160 /* Apply the taint */
11161 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11162
11163 /* Update the symbolic control flow */
11164 this->controlFlow_s(inst);
11165 }
11166
11167
11168 void x86Semantics::pmaxsd_s(triton::arch::Instruction& inst) {
11169 auto& dst = inst.operands[0];
11170 auto& src = inst.operands[1];
11171
11172 /* Create symbolic operands */
11173 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11174 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11175
11176 /* Create the semantics */
11177 std::vector<triton::ast::SharedAbstractNode> pck;
11178 pck.reserve(dst.getSize());
11179
11180 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) {
11181 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword);
11183 pck.push_back(this->astCtxt->ite(
11184 this->astCtxt->bvsle(
11185 this->astCtxt->extract(high, low, op1),
11186 this->astCtxt->extract(high, low, op2)),
11187 this->astCtxt->extract(high, low, op2),
11188 this->astCtxt->extract(high, low, op1))
11189 );
11190 }
11191
11192 auto node = this->astCtxt->concat(pck);
11193
11194 /* Create symbolic expression */
11195 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMAXSD operation");
11196
11197 /* Apply the taint */
11198 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11199
11200 /* Update the symbolic control flow */
11201 this->controlFlow_s(inst);
11202 }
11203
11204
11205 void x86Semantics::pmaxsw_s(triton::arch::Instruction& inst) {
11206 auto& dst = inst.operands[0];
11207 auto& src = inst.operands[1];
11208
11209 /* Create symbolic operands */
11210 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11211 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11212
11213 /* Create the semantics */
11214 std::vector<triton::ast::SharedAbstractNode> pck;
11215 pck.reserve(dst.getSize());
11216
11217 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
11218 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
11220 pck.push_back(this->astCtxt->ite(
11221 this->astCtxt->bvsle(
11222 this->astCtxt->extract(high, low, op1),
11223 this->astCtxt->extract(high, low, op2)),
11224 this->astCtxt->extract(high, low, op2),
11225 this->astCtxt->extract(high, low, op1))
11226 );
11227 }
11228
11229 auto node = this->astCtxt->concat(pck);
11230
11231 /* Create symbolic expression */
11232 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMAXSW operation");
11233
11234 /* Apply the taint */
11235 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11236
11237 /* Update the symbolic control flow */
11238 this->controlFlow_s(inst);
11239 }
11240
11241
11242 void x86Semantics::pmaxub_s(triton::arch::Instruction& inst) {
11243 auto& dst = inst.operands[0];
11244 auto& src = inst.operands[1];
11245
11246 /* Create symbolic operands */
11247 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11248 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11249
11250 /* Create the semantics */
11251 std::vector<triton::ast::SharedAbstractNode> pck;
11252 pck.reserve(dst.getSize());
11253
11254 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
11255 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
11257 pck.push_back(this->astCtxt->ite(
11258 this->astCtxt->bvule(
11259 this->astCtxt->extract(high, low, op1),
11260 this->astCtxt->extract(high, low, op2)),
11261 this->astCtxt->extract(high, low, op2),
11262 this->astCtxt->extract(high, low, op1))
11263 );
11264 }
11265
11266 auto node = this->astCtxt->concat(pck);
11267
11268 /* Create symbolic expression */
11269 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMAXUB operation");
11270
11271 /* Apply the taint */
11272 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11273
11274 /* Update the symbolic control flow */
11275 this->controlFlow_s(inst);
11276 }
11277
11278
11279 void x86Semantics::pmaxud_s(triton::arch::Instruction& inst) {
11280 auto& dst = inst.operands[0];
11281 auto& src = inst.operands[1];
11282
11283 /* Create symbolic operands */
11284 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11285 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11286
11287 /* Create the semantics */
11288 std::vector<triton::ast::SharedAbstractNode> pck;
11289 pck.reserve(dst.getSize());
11290
11291 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) {
11292 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword);
11294 pck.push_back(this->astCtxt->ite(
11295 this->astCtxt->bvule(
11296 this->astCtxt->extract(high, low, op1),
11297 this->astCtxt->extract(high, low, op2)),
11298 this->astCtxt->extract(high, low, op2),
11299 this->astCtxt->extract(high, low, op1))
11300 );
11301 }
11302
11303 auto node = this->astCtxt->concat(pck);
11304
11305 /* Create symbolic expression */
11306 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMAXUD operation");
11307
11308 /* Apply the taint */
11309 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11310
11311 /* Update the symbolic control flow */
11312 this->controlFlow_s(inst);
11313 }
11314
11315
11316 void x86Semantics::pmaxuw_s(triton::arch::Instruction& inst) {
11317 auto& dst = inst.operands[0];
11318 auto& src = inst.operands[1];
11319
11320 /* Create symbolic operands */
11321 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11322 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11323
11324 /* Create the semantics */
11325 std::vector<triton::ast::SharedAbstractNode> pck;
11326 pck.reserve(dst.getSize());
11327
11328 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
11329 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
11331 pck.push_back(this->astCtxt->ite(
11332 this->astCtxt->bvule(
11333 this->astCtxt->extract(high, low, op1),
11334 this->astCtxt->extract(high, low, op2)),
11335 this->astCtxt->extract(high, low, op2),
11336 this->astCtxt->extract(high, low, op1))
11337 );
11338 }
11339
11340 auto node = this->astCtxt->concat(pck);
11341
11342 /* Create symbolic expression */
11343 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMAXUW operation");
11344
11345 /* Apply the taint */
11346 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11347
11348 /* Update the symbolic control flow */
11349 this->controlFlow_s(inst);
11350 }
11351
11352
11353 void x86Semantics::pminsb_s(triton::arch::Instruction& inst) {
11354 auto& dst = inst.operands[0];
11355 auto& src = inst.operands[1];
11356
11357 /* Create symbolic operands */
11358 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11359 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11360
11361 /* Create the semantics */
11362 std::vector<triton::ast::SharedAbstractNode> pck;
11363 pck.reserve(dst.getSize());
11364
11365 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
11366 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
11368 pck.push_back(this->astCtxt->ite(
11369 this->astCtxt->bvsge(
11370 this->astCtxt->extract(high, low, op1),
11371 this->astCtxt->extract(high, low, op2)),
11372 this->astCtxt->extract(high, low, op2),
11373 this->astCtxt->extract(high, low, op1))
11374 );
11375 }
11376
11377 auto node = this->astCtxt->concat(pck);
11378
11379 /* Create symbolic expression */
11380 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMINSB operation");
11381
11382 /* Apply the taint */
11383 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11384
11385 /* Update the symbolic control flow */
11386 this->controlFlow_s(inst);
11387 }
11388
11389
11390 void x86Semantics::pminsd_s(triton::arch::Instruction& inst) {
11391 auto& dst = inst.operands[0];
11392 auto& src = inst.operands[1];
11393
11394 /* Create symbolic operands */
11395 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11396 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11397
11398 /* Create the semantics */
11399 std::vector<triton::ast::SharedAbstractNode> pck;
11400 pck.reserve(dst.getSize());
11401
11402 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) {
11403 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword);
11405 pck.push_back(this->astCtxt->ite(
11406 this->astCtxt->bvsge(
11407 this->astCtxt->extract(high, low, op1),
11408 this->astCtxt->extract(high, low, op2)),
11409 this->astCtxt->extract(high, low, op2),
11410 this->astCtxt->extract(high, low, op1))
11411 );
11412 }
11413
11414 auto node = this->astCtxt->concat(pck);
11415
11416 /* Create symbolic expression */
11417 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMINSD operation");
11418
11419 /* Apply the taint */
11420 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11421
11422 /* Update the symbolic control flow */
11423 this->controlFlow_s(inst);
11424 }
11425
11426
11427 void x86Semantics::pminsw_s(triton::arch::Instruction& inst) {
11428 auto& dst = inst.operands[0];
11429 auto& src = inst.operands[1];
11430
11431 /* Create symbolic operands */
11432 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11433 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11434
11435 /* Create the semantics */
11436 std::vector<triton::ast::SharedAbstractNode> pck;
11437 pck.reserve(dst.getSize());
11438
11439 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
11440 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
11442 pck.push_back(this->astCtxt->ite(
11443 this->astCtxt->bvsge(
11444 this->astCtxt->extract(high, low, op1),
11445 this->astCtxt->extract(high, low, op2)),
11446 this->astCtxt->extract(high, low, op2),
11447 this->astCtxt->extract(high, low, op1))
11448 );
11449 }
11450
11451 auto node = this->astCtxt->concat(pck);
11452
11453 /* Create symbolic expression */
11454 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMINSW operation");
11455
11456 /* Apply the taint */
11457 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11458
11459 /* Update the symbolic control flow */
11460 this->controlFlow_s(inst);
11461 }
11462
11463
11464 void x86Semantics::pminub_s(triton::arch::Instruction& inst) {
11465 auto& dst = inst.operands[0];
11466 auto& src = inst.operands[1];
11467
11468 /* Create symbolic operands */
11469 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11470 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11471
11472 /* Create the semantics */
11473 std::vector<triton::ast::SharedAbstractNode> pck;
11474 pck.reserve(dst.getSize());
11475
11476 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
11477 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
11479 pck.push_back(this->astCtxt->ite(
11480 this->astCtxt->bvuge(
11481 this->astCtxt->extract(high, low, op1),
11482 this->astCtxt->extract(high, low, op2)),
11483 this->astCtxt->extract(high, low, op2),
11484 this->astCtxt->extract(high, low, op1))
11485 );
11486 }
11487
11488 auto node = this->astCtxt->concat(pck);
11489
11490 /* Create symbolic expression */
11491 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMINUB operation");
11492
11493 /* Apply the taint */
11494 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11495
11496 /* Update the symbolic control flow */
11497 this->controlFlow_s(inst);
11498 }
11499
11500
11501 void x86Semantics::pminud_s(triton::arch::Instruction& inst) {
11502 auto& dst = inst.operands[0];
11503 auto& src = inst.operands[1];
11504
11505 /* Create symbolic operands */
11506 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11507 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11508
11509 /* Create the semantics */
11510 std::vector<triton::ast::SharedAbstractNode> pck;
11511 pck.reserve(dst.getSize());
11512
11513 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) {
11514 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword);
11516 pck.push_back(this->astCtxt->ite(
11517 this->astCtxt->bvuge(
11518 this->astCtxt->extract(high, low, op1),
11519 this->astCtxt->extract(high, low, op2)),
11520 this->astCtxt->extract(high, low, op2),
11521 this->astCtxt->extract(high, low, op1))
11522 );
11523 }
11524
11525 auto node = this->astCtxt->concat(pck);
11526
11527 /* Create symbolic expression */
11528 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMINUD operation");
11529
11530 /* Apply the taint */
11531 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11532
11533 /* Update the symbolic control flow */
11534 this->controlFlow_s(inst);
11535 }
11536
11537
11538 void x86Semantics::pminuw_s(triton::arch::Instruction& inst) {
11539 auto& dst = inst.operands[0];
11540 auto& src = inst.operands[1];
11541
11542 /* Create symbolic operands */
11543 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11544 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11545
11546 /* Create the semantics */
11547 std::vector<triton::ast::SharedAbstractNode> pck;
11548 pck.reserve(dst.getSize());
11549
11550 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
11551 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
11553 pck.push_back(this->astCtxt->ite(
11554 this->astCtxt->bvuge(
11555 this->astCtxt->extract(high, low, op1),
11556 this->astCtxt->extract(high, low, op2)),
11557 this->astCtxt->extract(high, low, op2),
11558 this->astCtxt->extract(high, low, op1))
11559 );
11560 }
11561
11562 auto node = this->astCtxt->concat(pck);
11563
11564 /* Create symbolic expression */
11565 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMINUW operation");
11566
11567 /* Apply the taint */
11568 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11569
11570 /* Update the symbolic control flow */
11571 this->controlFlow_s(inst);
11572 }
11573
11574
11575 void x86Semantics::pmovmskb_s(triton::arch::Instruction& inst) {
11576 auto& dst = inst.operands[0];
11577 auto& src = inst.operands[1];
11578
11579 /* Create symbolic operands */
11580 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11581
11582 /* Create the semantics */
11583 std::vector<triton::ast::SharedAbstractNode> mskb;
11584 mskb.reserve(16);
11585
11586 switch (src.getSize()) {
11588 mskb.push_back(this->astCtxt->extract(127, 127, op2));
11589 mskb.push_back(this->astCtxt->extract(119, 119, op2));
11590 mskb.push_back(this->astCtxt->extract(111, 111, op2));
11591 mskb.push_back(this->astCtxt->extract(103, 103, op2));
11592 mskb.push_back(this->astCtxt->extract(95, 95, op2));
11593 mskb.push_back(this->astCtxt->extract(87, 87, op2));
11594 mskb.push_back(this->astCtxt->extract(79, 79, op2));
11595 mskb.push_back(this->astCtxt->extract(71, 71, op2));
11596
11598 mskb.push_back(this->astCtxt->extract(63, 63, op2));
11599 mskb.push_back(this->astCtxt->extract(55, 55, op2));
11600 mskb.push_back(this->astCtxt->extract(47, 47, op2));
11601 mskb.push_back(this->astCtxt->extract(39, 39, op2));
11602 mskb.push_back(this->astCtxt->extract(31, 31, op2));
11603 mskb.push_back(this->astCtxt->extract(23, 23, op2));
11604 mskb.push_back(this->astCtxt->extract(15, 15, op2));
11605 mskb.push_back(this->astCtxt->extract(7, 7, op2));
11606 }
11607
11608 auto node = this->astCtxt->zx(
11609 dst.getBitSize() - static_cast<triton::uint32>(mskb.size()),
11610 this->astCtxt->concat(mskb)
11611 );
11612
11613 /* Create symbolic expression */
11614 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVMSKB operation");
11615
11616 /* Apply the taint */
11617 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11618
11619 /* Update the symbolic control flow */
11620 this->controlFlow_s(inst);
11621 }
11622
11623
11624 void x86Semantics::pmovsxbd_s(triton::arch::Instruction& inst) {
11625 auto& dst = inst.operands[0];
11626 auto& src = inst.operands[1];
11627
11628 /* Create symbolic operands */
11629 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11630
11631 /* Create the semantics */
11632 std::vector<triton::ast::SharedAbstractNode> pck;
11633 pck.reserve(4);
11634
11635 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(31, 24, op2)));
11636 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(23, 16, op2)));
11637 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2)));
11638 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2)));
11639
11640 auto node = this->astCtxt->concat(pck);
11641
11642 /* Create symbolic expression */
11643 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVSXBD operation");
11644
11645 /* Apply the taint */
11646 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11647
11648 /* Update the symbolic control flow */
11649 this->controlFlow_s(inst);
11650 }
11651
11652
11653 void x86Semantics::pmovsxbq_s(triton::arch::Instruction& inst) {
11654 auto& dst = inst.operands[0];
11655 auto& src = inst.operands[1];
11656
11657 /* Create symbolic operands */
11658 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11659
11660 /* Create the semantics */
11661 std::vector<triton::ast::SharedAbstractNode> pck;
11662 pck.reserve(2);
11663
11664 pck.push_back(this->astCtxt->sx(triton::bitsize::qword - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2)));
11665 pck.push_back(this->astCtxt->sx(triton::bitsize::qword - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2)));
11666
11667 auto node = this->astCtxt->concat(pck);
11668
11669 /* Create symbolic expression */
11670 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVSXBQ operation");
11671
11672 /* Apply the taint */
11673 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11674
11675 /* Update the symbolic control flow */
11676 this->controlFlow_s(inst);
11677 }
11678
11679
11680 void x86Semantics::pmovsxbw_s(triton::arch::Instruction& inst) {
11681 auto& dst = inst.operands[0];
11682 auto& src = inst.operands[1];
11683
11684 /* Create symbolic operands */
11685 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11686
11687 /* Create the semantics */
11688 std::vector<triton::ast::SharedAbstractNode> pck;
11689 pck.reserve(8);
11690
11691 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(63, 56, op2)));
11692 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(55, 48, op2)));
11693 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(47, 40, op2)));
11694 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(39, 32, op2)));
11695 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(31, 24, op2)));
11696 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(23, 16, op2)));
11697 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2)));
11698 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2)));
11699
11700 auto node = this->astCtxt->concat(pck);
11701
11702 /* Create symbolic expression */
11703 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVSXBW operation");
11704
11705 /* Apply the taint */
11706 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11707
11708 /* Update the symbolic control flow */
11709 this->controlFlow_s(inst);
11710 }
11711
11712
11713 void x86Semantics::pmovsxdq_s(triton::arch::Instruction& inst) {
11714 auto& dst = inst.operands[0];
11715 auto& src = inst.operands[1];
11716
11717 /* Create symbolic operands */
11718 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11719
11720 /* Create the semantics */
11721 std::vector<triton::ast::SharedAbstractNode> pck;
11722 pck.reserve(2);
11723
11724 pck.push_back(this->astCtxt->sx(triton::bitsize::qword - triton::bitsize::dword, this->astCtxt->extract(63, 32, op2)));
11725 pck.push_back(this->astCtxt->sx(triton::bitsize::qword - triton::bitsize::dword, this->astCtxt->extract(31, 0, op2)));
11726
11727 auto node = this->astCtxt->concat(pck);
11728
11729 /* Create symbolic expression */
11730 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVSXDQ operation");
11731
11732 /* Apply the taint */
11733 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11734
11735 /* Update the symbolic control flow */
11736 this->controlFlow_s(inst);
11737 }
11738
11739
11740 void x86Semantics::pmovsxwd_s(triton::arch::Instruction& inst) {
11741 auto& dst = inst.operands[0];
11742 auto& src = inst.operands[1];
11743
11744 /* Create symbolic operands */
11745 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11746
11747 /* Create the semantics */
11748 std::vector<triton::ast::SharedAbstractNode> pck;
11749 pck.reserve(4);
11750
11751 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(63, 48, op2)));
11752 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(47, 32, op2)));
11753 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(31, 16, op2)));
11754 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(15, 0, op2)));
11755
11756 auto node = this->astCtxt->concat(pck);
11757
11758 /* Create symbolic expression */
11759 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVSXWD operation");
11760
11761 /* Apply the taint */
11762 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11763
11764 /* Update the symbolic control flow */
11765 this->controlFlow_s(inst);
11766 }
11767
11768
11769 void x86Semantics::pmovsxwq_s(triton::arch::Instruction& inst) {
11770 auto& dst = inst.operands[0];
11771 auto& src = inst.operands[1];
11772
11773 /* Create symbolic operands */
11774 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11775
11776 /* Create the semantics */
11777 std::vector<triton::ast::SharedAbstractNode> pck;
11778 pck.reserve(2);
11779
11780 pck.push_back(this->astCtxt->sx(triton::bitsize::qword - triton::bitsize::word, this->astCtxt->extract(31, 16, op2)));
11781 pck.push_back(this->astCtxt->sx(triton::bitsize::qword - triton::bitsize::word, this->astCtxt->extract(15, 0, op2)));
11782
11783 auto node = this->astCtxt->concat(pck);
11784
11785 /* Create symbolic expression */
11786 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVSXWQ operation");
11787
11788 /* Apply the taint */
11789 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11790
11791 /* Update the symbolic control flow */
11792 this->controlFlow_s(inst);
11793 }
11794
11795
11796 void x86Semantics::pmovzxbd_s(triton::arch::Instruction& inst) {
11797 auto& dst = inst.operands[0];
11798 auto& src = inst.operands[1];
11799
11800 /* Create symbolic operands */
11801 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11802
11803 /* Create the semantics */
11804 std::vector<triton::ast::SharedAbstractNode> pck;
11805 pck.reserve(4);
11806
11807 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(31, 24, op2)));
11808 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(23, 16, op2)));
11809 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2)));
11810 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2)));
11811
11812 auto node = this->astCtxt->concat(pck);
11813
11814 /* Create symbolic expression */
11815 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVZXBD operation");
11816
11817 /* Apply the taint */
11818 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11819
11820 /* Update the symbolic control flow */
11821 this->controlFlow_s(inst);
11822 }
11823
11824
11825 void x86Semantics::pmovzxbq_s(triton::arch::Instruction& inst) {
11826 auto& dst = inst.operands[0];
11827 auto& src = inst.operands[1];
11828
11829 /* Create symbolic operands */
11830 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11831
11832 /* Create the semantics */
11833 std::vector<triton::ast::SharedAbstractNode> pck;
11834 pck.reserve(2);
11835
11836 pck.push_back(this->astCtxt->zx(triton::bitsize::qword - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2)));
11837 pck.push_back(this->astCtxt->zx(triton::bitsize::qword - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2)));
11838
11839 auto node = this->astCtxt->concat(pck);
11840
11841 /* Create symbolic expression */
11842 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVZXBQ operation");
11843
11844 /* Apply the taint */
11845 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11846
11847 /* Update the symbolic control flow */
11848 this->controlFlow_s(inst);
11849 }
11850
11851
11852 void x86Semantics::pmovzxbw_s(triton::arch::Instruction& inst) {
11853 auto& dst = inst.operands[0];
11854 auto& src = inst.operands[1];
11855
11856 /* Create symbolic operands */
11857 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11858
11859 /* Create the semantics */
11860 std::vector<triton::ast::SharedAbstractNode> pck;
11861 pck.reserve(8);
11862
11863 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(63, 56, op2)));
11864 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(55, 48, op2)));
11865 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(47, 40, op2)));
11866 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(39, 32, op2)));
11867 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(31, 24, op2)));
11868 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(23, 16, op2)));
11869 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2)));
11870 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2)));
11871
11872 auto node = this->astCtxt->concat(pck);
11873
11874 /* Create symbolic expression */
11875 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVZXBW operation");
11876
11877 /* Apply the taint */
11878 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11879
11880 /* Update the symbolic control flow */
11881 this->controlFlow_s(inst);
11882 }
11883
11884
11885 void x86Semantics::pmovzxdq_s(triton::arch::Instruction& inst) {
11886 auto& dst = inst.operands[0];
11887 auto& src = inst.operands[1];
11888
11889 /* Create symbolic operands */
11890 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11891
11892 /* Create the semantics */
11893 std::vector<triton::ast::SharedAbstractNode> pck;
11894 pck.reserve(2);
11895
11896 pck.push_back(this->astCtxt->zx(triton::bitsize::qword - triton::bitsize::dword, this->astCtxt->extract(63, 32, op2)));
11897 pck.push_back(this->astCtxt->zx(triton::bitsize::qword - triton::bitsize::dword, this->astCtxt->extract(31, 0, op2)));
11898
11899 auto node = this->astCtxt->concat(pck);
11900
11901 /* Create symbolic expression */
11902 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVZXDQ operation");
11903
11904 /* Apply the taint */
11905 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11906
11907 /* Update the symbolic control flow */
11908 this->controlFlow_s(inst);
11909 }
11910
11911
11912 void x86Semantics::pmovzxwd_s(triton::arch::Instruction& inst) {
11913 auto& dst = inst.operands[0];
11914 auto& src = inst.operands[1];
11915
11916 /* Create symbolic operands */
11917 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11918
11919 /* Create the semantics */
11920 std::vector<triton::ast::SharedAbstractNode> pck;
11921 pck.reserve(4);
11922
11923 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(63, 48, op2)));
11924 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(47, 32, op2)));
11925 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(31, 16, op2)));
11926 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(15, 0, op2)));
11927
11928 auto node = this->astCtxt->concat(pck);
11929
11930 /* Create symbolic expression */
11931 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVZXWD operation");
11932
11933 /* Apply the taint */
11934 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11935
11936 /* Update the symbolic control flow */
11937 this->controlFlow_s(inst);
11938 }
11939
11940
11941 void x86Semantics::pmovzxwq_s(triton::arch::Instruction& inst) {
11942 auto& dst = inst.operands[0];
11943 auto& src = inst.operands[1];
11944
11945 /* Create symbolic operands */
11946 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11947
11948 /* Create the semantics */
11949 std::vector<triton::ast::SharedAbstractNode> pck;
11950 pck.reserve(2);
11951
11952 pck.push_back(this->astCtxt->zx(triton::bitsize::qword - triton::bitsize::word, this->astCtxt->extract(31, 16, op2)));
11953 pck.push_back(this->astCtxt->zx(triton::bitsize::qword - triton::bitsize::word, this->astCtxt->extract(15, 0, op2)));
11954
11955 auto node = this->astCtxt->concat(pck);
11956
11957 /* Create symbolic expression */
11958 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVZXWQ operation");
11959
11960 /* Apply the taint */
11961 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11962
11963 /* Update the symbolic control flow */
11964 this->controlFlow_s(inst);
11965 }
11966
11967
11968 void x86Semantics::pmulhw_s(triton::arch::Instruction& inst) {
11969 auto& dst = inst.operands[0];
11970 auto& src = inst.operands[1];
11971
11972 /* Create symbolic operands */
11973 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11974 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11975
11976 /* Create the semantics */
11977 std::vector<triton::ast::SharedAbstractNode> pck;
11978 pck.reserve(dst.getSize() / triton::size::word);
11979
11980 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; ++i) {
11981 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
11983 auto n1 = this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op1));
11984 auto n2 = this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op2));
11985 auto node = this->astCtxt->extract(triton::bitsize::dword - 1, triton::bitsize::word, this->astCtxt->bvmul(n1, n2));
11986 pck.push_back(node);
11987 }
11988 auto node = this->astCtxt->concat(pck);
11989
11990 /* Create symbolic expression */
11991 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMULHW operation");
11992
11993 /* Apply the taint */
11994 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11995
11996 /* Update the symbolic control flow */
11997 this->controlFlow_s(inst);
11998 }
11999
12000
12001 void x86Semantics::pmulld_s(triton::arch::Instruction& inst) {
12002 auto& dst = inst.operands[0];
12003 auto& src = inst.operands[1];
12004
12005 /* Create symbolic operands */
12006 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12007 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12008
12009 /* Create the semantics */
12010 std::vector<triton::ast::SharedAbstractNode> pck;
12011 pck.reserve(dst.getSize() / triton::size::dword);
12012
12013 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::dword; ++i) {
12014 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::dword);
12016 auto n1 = this->astCtxt->sx(triton::bitsize::dword, this->astCtxt->extract(high, low, op1));
12017 auto n2 = this->astCtxt->sx(triton::bitsize::dword, this->astCtxt->extract(high, low, op2));
12018 auto node = this->astCtxt->extract(triton::bitsize::dword - 1, 0, this->astCtxt->bvmul(n1, n2));
12019 pck.push_back(node);
12020 }
12021 auto node = this->astCtxt->concat(pck);
12022
12023 /* Create symbolic expression */
12024 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMULLD operation");
12025
12026 /* Apply the taint */
12027 expr->isTainted = this->taintEngine->taintUnion(dst, src);
12028
12029 /* Update the symbolic control flow */
12030 this->controlFlow_s(inst);
12031 }
12032
12033
12034 void x86Semantics::pmullw_s(triton::arch::Instruction& inst) {
12035 auto& dst = inst.operands[0];
12036 auto& src = inst.operands[1];
12037
12038 /* Create symbolic operands */
12039 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12040 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12041
12042 /* Create the semantics */
12043 std::vector<triton::ast::SharedAbstractNode> pck;
12044 pck.reserve(dst.getSize() / triton::size::word);
12045
12046 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; ++i) {
12047 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
12049 auto n1 = this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op1));
12050 auto n2 = this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op2));
12051 auto node = this->astCtxt->extract(triton::bitsize::word - 1, 0, this->astCtxt->bvmul(n1, n2));
12052 pck.push_back(node);
12053 }
12054 auto node = this->astCtxt->concat(pck);
12055
12056 /* Create symbolic expression */
12057 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMULLW operation");
12058
12059 /* Apply the taint */
12060 expr->isTainted = this->taintEngine->taintUnion(dst, src);
12061
12062 /* Update the symbolic control flow */
12063 this->controlFlow_s(inst);
12064 }
12065
12066
12067 void x86Semantics::pmuludq_s(triton::arch::Instruction& inst) {
12068 triton::ast::SharedAbstractNode node = nullptr;
12069 auto& dst = inst.operands[0];
12070 auto& src = inst.operands[1];
12071
12072 /* Create symbolic operands */
12073 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12074 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12075
12076 /* Create the semantics */
12077 switch (dst.getBitSize()) {
12079 auto n1 = this->astCtxt->zx(triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::dword-1, 0, op1));
12080 auto n2 = this->astCtxt->zx(triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::dword-1, 0, op2));
12081 node = this->astCtxt->bvmul(n1, n2);
12082 break;
12083 }
12084
12086 std::vector<triton::ast::SharedAbstractNode> pck;
12087 pck.reserve(2);
12088
12089 auto n1 = this->astCtxt->zx(triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::dword-1, 0, op1));
12090 auto n2 = this->astCtxt->zx(triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::dword-1, 0, op2));
12091
12092 auto n3 = this->astCtxt->zx(triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::qword+triton::bitsize::dword-1, triton::bitsize::qword, op1));
12093 auto n4 = this->astCtxt->zx(triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::qword+triton::bitsize::dword-1, triton::bitsize::qword, op2));
12094
12095 pck.push_back(this->astCtxt->bvmul(n3, n4));
12096 pck.push_back(this->astCtxt->bvmul(n1, n2));
12097
12098 node = this->astCtxt->concat(pck);
12099 break;
12100 }
12101
12102 default:
12103 throw triton::exceptions::Semantics("x86Semantics::pmuludq_s(): Invalid operand size.");
12104 }
12105
12106 /* Create symbolic expression */
12107 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMULUDQ operation");
12108
12109 /* Apply the taint */
12110 expr->isTainted = this->taintEngine->taintUnion(dst, src);
12111
12112 /* Update the symbolic control flow */
12113 this->controlFlow_s(inst);
12114 return;
12115 }
12116
12117
12118 void x86Semantics::popcnt_s(triton::arch::Instruction& inst) {
12119 auto& dst = inst.operands[0];
12120 auto& src = inst.operands[1];
12121
12122 /* Create symbolic operands */
12123 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12124 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12125
12126 /* Create the semantics */
12127 auto node = this->astCtxt->bv(0, dst.getBitSize());
12128 for (triton::uint32 i = 0; i < src.getBitSize(); ++i) {
12129 node = this->astCtxt->bvadd(
12130 node,
12131 this->astCtxt->zx(dst.getBitSize() - 1, this->astCtxt->extract(i, i, op2))
12132 );
12133 }
12134
12135 /* Create symbolic expression */
12136 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "POPCNT operation");
12137
12138 /* Spread taint */
12139 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
12140
12141 /* Update the symbolic control flow */
12142 this->controlFlow_s(inst);
12143 }
12144
12145
12146 void x86Semantics::pop_s(triton::arch::Instruction& inst) {
12147 bool stackRelative = false;
12148 auto stack = this->architecture->getStackPointer();
12149 auto stackValue = static_cast<triton::uint64>(this->architecture->getConcreteRegisterValue(stack));
12150 auto& dst = inst.operands[0];
12152
12153 /* Create symbolic operands */
12154 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
12155
12156 /* Create the semantics */
12157 auto node = op1;
12158
12159 /*
12160 * Create the semantics - side effect
12161 *
12162 * Intel: If the ESP register is used as a base register for addressing a destination operand in
12163 * memory, the POP instruction computes the effective address of the operand after it increments
12164 * the ESP register.
12165 */
12166 if (dst.getType() == triton::arch::OP_MEM) {
12168 /* Check if the base register is the stack pointer */
12169 if (this->architecture->isRegisterValid(base) && this->architecture->getParentRegister(base) == stack) {
12170 /* Align the stack */
12171 alignAddStack_s(inst, src.getSize());
12172 /* Re-initialize the memory access */
12173 this->symbolicEngine->initLeaAst(dst.getMemory());
12174 stackRelative = true;
12175 }
12176 }
12177
12178 /*
12179 * Create the semantics - side effect
12180 *
12181 * Don't increment SP if the destination register is SP.
12182 */
12183 else if (dst.getType() == triton::arch::OP_REG) {
12184 if (this->architecture->getParentRegister(dst.getRegister()) == stack) {
12185 stackRelative = true;
12186 }
12187 }
12188
12189 /* Create symbolic expression */
12190 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "POP operation");
12191
12192 /* Spread taint */
12193 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
12194
12195 /* Create the semantics - side effect */
12196 if (!stackRelative)
12197 alignAddStack_s(inst, src.getSize());
12198
12199 /* Update the symbolic control flow */
12200 this->controlFlow_s(inst);
12201 }
12202
12203
12204 void x86Semantics::popal_s(triton::arch::Instruction& inst) {
12205 auto stack = this->architecture->getStackPointer();
12206 auto stackValue = static_cast<triton::uint64>(this->architecture->getConcreteRegisterValue(stack));
12207 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDI));
12208 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ESI));
12209 auto dst3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EBP));
12210 auto dst4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EBX));
12211 auto dst5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
12212 auto dst6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ECX));
12213 auto dst7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
12214 auto src1 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 0), stack.getSize()));
12215 auto src2 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 1), stack.getSize()));
12216 auto src3 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 2), stack.getSize()));
12217 /* stack.getSize() * 3 (ESP) is voluntarily omitted */
12218 auto src4 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 4), stack.getSize()));
12219 auto src5 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 5), stack.getSize()));
12220 auto src6 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 6), stack.getSize()));
12221 auto src7 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 7), stack.getSize()));
12222
12223 /* Create symbolic operands and semantics */
12224 auto node1 = this->symbolicEngine->getOperandAst(inst, src1);
12225 auto node2 = this->symbolicEngine->getOperandAst(inst, src2);
12226 auto node3 = this->symbolicEngine->getOperandAst(inst, src3);
12227 auto node4 = this->symbolicEngine->getOperandAst(inst, src4);
12228 auto node5 = this->symbolicEngine->getOperandAst(inst, src5);
12229 auto node6 = this->symbolicEngine->getOperandAst(inst, src6);
12230 auto node7 = this->symbolicEngine->getOperandAst(inst, src7);
12231
12232 /* Create symbolic expression */
12233 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1, "POPAL EDI operation");
12234 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "POPAL ESI operation");
12235 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3, "POPAL EBP operation");
12236 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4, "POPAL EBX operation");
12237 auto expr5 = this->symbolicEngine->createSymbolicExpression(inst, node5, dst5, "POPAL EDX operation");
12238 auto expr6 = this->symbolicEngine->createSymbolicExpression(inst, node6, dst6, "POPAL ECX operation");
12239 auto expr7 = this->symbolicEngine->createSymbolicExpression(inst, node7, dst7, "POPAL EAX operation");
12240
12241 /* Spread taint */
12242 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src1);
12243 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src2);
12244 expr3->isTainted = this->taintEngine->taintAssignment(dst3, src3);
12245 expr4->isTainted = this->taintEngine->taintAssignment(dst4, src4);
12246 expr5->isTainted = this->taintEngine->taintAssignment(dst5, src5);
12247 expr6->isTainted = this->taintEngine->taintAssignment(dst6, src6);
12248 expr7->isTainted = this->taintEngine->taintAssignment(dst7, src7);
12249
12250 /* Create the semantics - side effect */
12251 alignAddStack_s(inst, stack.getSize() * 8);
12252
12253 /* Update the symbolic control flow */
12254 this->controlFlow_s(inst);
12255 }
12256
12257
12258 void x86Semantics::popf_s(triton::arch::Instruction& inst) {
12259 auto stack = this->architecture->getStackPointer();
12260 auto stackValue = static_cast<triton::uint64>(this->architecture->getConcreteRegisterValue(stack));
12261 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
12262 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
12263 auto dst3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF));
12264 auto dst4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
12265 auto dst5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
12266 auto dst6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_TF));
12267 auto dst7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_IF));
12268 auto dst8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
12269 auto dst9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
12270 auto dst10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_NT));
12271 auto src = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize()));
12272
12273 /* Create symbolic operands */
12274 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
12275
12276 /* Create the semantics */
12277 auto node1 = this->astCtxt->extract(0, 0, op1);
12278 auto node2 = this->astCtxt->extract(2, 2, op1);
12279 auto node3 = this->astCtxt->extract(4, 4, op1);
12280 auto node4 = this->astCtxt->extract(6, 6, op1);
12281 auto node5 = this->astCtxt->extract(7, 7, op1);
12282 auto node6 = this->astCtxt->extract(8, 8, op1);
12283 auto node7 = this->astCtxt->bvtrue(); /* IF true? */
12284 auto node8 = this->astCtxt->extract(10, 10, op1);
12285 auto node9 = this->astCtxt->extract(11, 11, op1);
12286 /* IOPL don't support */
12287 auto node10 = this->astCtxt->extract(14, 14, op1);
12288
12289 /* Create symbolic expression */
12290 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1.getRegister(), "POPF CF operation");
12291 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2.getRegister(), "POPF PF operation");
12292 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3.getRegister(), "POPF AF operation");
12293 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4.getRegister(), "POPF ZF operation");
12294 auto expr5 = this->symbolicEngine->createSymbolicExpression(inst, node5, dst5.getRegister(), "POPF SF operation");
12295 auto expr6 = this->symbolicEngine->createSymbolicExpression(inst, node6, dst6.getRegister(), "POPF TF operation");
12296 auto expr7 = this->symbolicEngine->createSymbolicExpression(inst, node7, dst7.getRegister(), "POPF IF operation");
12297 auto expr8 = this->symbolicEngine->createSymbolicExpression(inst, node8, dst8.getRegister(), "POPF DF operation");
12298 auto expr9 = this->symbolicEngine->createSymbolicExpression(inst, node9, dst9.getRegister(), "POPF OF operation");
12299 auto expr10 = this->symbolicEngine->createSymbolicExpression(inst, node10, dst10.getRegister(), "POPF NT operation");
12300
12301 /* Spread taint */
12302 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src);
12303 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src);
12304 expr3->isTainted = this->taintEngine->taintAssignment(dst3, src);
12305 expr4->isTainted = this->taintEngine->taintAssignment(dst4, src);
12306 expr5->isTainted = this->taintEngine->taintAssignment(dst5, src);
12307 expr6->isTainted = this->taintEngine->taintAssignment(dst6, src);
12308 expr7->isTainted = this->taintEngine->taintAssignment(dst7, src);
12309 expr8->isTainted = this->taintEngine->taintAssignment(dst8, src);
12310 expr9->isTainted = this->taintEngine->taintAssignment(dst9, src);
12311 expr10->isTainted = this->taintEngine->taintAssignment(dst10, src);
12312
12313 /* Create the semantics - side effect */
12314 alignAddStack_s(inst, src.getSize());
12315
12316 /* Update the symbolic control flow */
12317 this->controlFlow_s(inst);
12318 }
12319
12320
12321 void x86Semantics::popfd_s(triton::arch::Instruction& inst) {
12322 auto stack = this->architecture->getStackPointer();
12323 auto stackValue = static_cast<triton::uint64>(this->architecture->getConcreteRegisterValue(stack));
12324 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
12325 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
12326 auto dst3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF));
12327 auto dst4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
12328 auto dst5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
12329 auto dst6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_TF));
12330 auto dst7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_IF));
12331 auto dst8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
12332 auto dst9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
12333 auto dst10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_NT));
12334 auto dst11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RF));
12335 auto dst12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AC));
12336 auto dst13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ID));
12337 auto src = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize()));
12338
12339 /* Create symbolic operands */
12340 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
12341
12342 /* Create the semantics */
12343 auto node1 = this->astCtxt->extract(0, 0, op1);
12344 auto node2 = this->astCtxt->extract(2, 2, op1);
12345 auto node3 = this->astCtxt->extract(4, 4, op1);
12346 auto node4 = this->astCtxt->extract(6, 6, op1);
12347 auto node5 = this->astCtxt->extract(7, 7, op1);
12348 auto node6 = this->astCtxt->extract(8, 8, op1);
12349 auto node7 = this->astCtxt->bvtrue(); /* IF true? */
12350 auto node8 = this->astCtxt->extract(10, 10, op1);
12351 auto node9 = this->astCtxt->extract(11, 11, op1);
12352 /* IOPL don't support */
12353 auto node10 = this->astCtxt->extract(14, 14, op1);
12354 auto node11 = this->astCtxt->bvfalse(); /* RF clear */
12355 /* VM not changed */
12356 auto node12 = this->astCtxt->extract(18, 18, op1);
12357 /* VIP not changed */
12358 /* VIF not changed */
12359 auto node13 = this->astCtxt->extract(21, 21, op1);
12360
12361 /* Create symbolic expression */
12362 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1.getRegister(), "POPFD CF operation");
12363 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2.getRegister(), "POPFD PF operation");
12364 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3.getRegister(), "POPFD AF operation");
12365 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4.getRegister(), "POPFD ZF operation");
12366 auto expr5 = this->symbolicEngine->createSymbolicExpression(inst, node5, dst5.getRegister(), "POPFD SF operation");
12367 auto expr6 = this->symbolicEngine->createSymbolicExpression(inst, node6, dst6.getRegister(), "POPFD TF operation");
12368 auto expr7 = this->symbolicEngine->createSymbolicExpression(inst, node7, dst7.getRegister(), "POPFD IF operation");
12369 auto expr8 = this->symbolicEngine->createSymbolicExpression(inst, node8, dst8.getRegister(), "POPFD DF operation");
12370 auto expr9 = this->symbolicEngine->createSymbolicExpression(inst, node9, dst9.getRegister(), "POPFD OF operation");
12371 auto expr10 = this->symbolicEngine->createSymbolicExpression(inst, node10, dst10.getRegister(), "POPFD NT operation");
12372 auto expr11 = this->symbolicEngine->createSymbolicExpression(inst, node11, dst11.getRegister(), "POPFD RF operation");
12373 auto expr12 = this->symbolicEngine->createSymbolicExpression(inst, node12, dst12.getRegister(), "POPFD AC operation");
12374 auto expr13 = this->symbolicEngine->createSymbolicExpression(inst, node13, dst13.getRegister(), "POPFD ID operation");
12375
12376 /* Spread taint */
12377 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src);
12378 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src);
12379 expr3->isTainted = this->taintEngine->taintAssignment(dst3, src);
12380 expr4->isTainted = this->taintEngine->taintAssignment(dst4, src);
12381 expr5->isTainted = this->taintEngine->taintAssignment(dst5, src);
12382 expr6->isTainted = this->taintEngine->taintAssignment(dst6, src);
12383 expr7->isTainted = this->taintEngine->taintAssignment(dst7, src);
12384 expr8->isTainted = this->taintEngine->taintAssignment(dst8, src);
12385 expr9->isTainted = this->taintEngine->taintAssignment(dst9, src);
12386 expr10->isTainted = this->taintEngine->taintAssignment(dst10, src);
12387 expr11->isTainted = this->taintEngine->taintAssignment(dst11, src);
12388 expr12->isTainted = this->taintEngine->taintAssignment(dst12, src);
12389 expr13->isTainted = this->taintEngine->taintAssignment(dst13, src);
12390
12391 /* Create the semantics - side effect */
12392 alignAddStack_s(inst, src.getSize());
12393
12394 /* Update the symbolic control flow */
12395 this->controlFlow_s(inst);
12396 }
12397
12398
12399 void x86Semantics::popfq_s(triton::arch::Instruction& inst) {
12400 auto stack = this->architecture->getStackPointer();
12401 auto stackValue = static_cast<triton::uint64>(this->architecture->getConcreteRegisterValue(stack));
12402 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
12403 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
12404 auto dst3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF));
12405 auto dst4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
12406 auto dst5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
12407 auto dst6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_TF));
12408 auto dst7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_IF));
12409 auto dst8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
12410 auto dst9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
12411 auto dst10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_NT));
12412 auto dst11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RF));
12413 auto dst12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AC));
12414 auto dst13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ID));
12415 auto src = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize()));
12416
12417 /* Create symbolic operands */
12418 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
12419
12420 /* Create the semantics */
12421 auto node1 = this->astCtxt->extract(0, 0, op1);
12422 auto node2 = this->astCtxt->extract(2, 2, op1);
12423 auto node3 = this->astCtxt->extract(4, 4, op1);
12424 auto node4 = this->astCtxt->extract(6, 6, op1);
12425 auto node5 = this->astCtxt->extract(7, 7, op1);
12426 auto node6 = this->astCtxt->extract(8, 8, op1);
12427 auto node7 = this->astCtxt->bvtrue(); /* IF true? */
12428 auto node8 = this->astCtxt->extract(10, 10, op1);
12429 auto node9 = this->astCtxt->extract(11, 11, op1);
12430 /* IOPL don't support */
12431 auto node10 = this->astCtxt->extract(14, 14, op1);
12432 auto node11 = this->astCtxt->bvfalse(); /* RF clear */
12433 /* VM not changed */
12434 auto node12 = this->astCtxt->extract(18, 18, op1);
12435 /* VIP not changed */
12436 /* VIF not changed */
12437 auto node13 = this->astCtxt->extract(21, 21, op1);
12438
12439 /* Create symbolic expression */
12440 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1.getRegister(), "POPFQ CF operation");
12441 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2.getRegister(), "POPFQ PF operation");
12442 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3.getRegister(), "POPFQ AF operation");
12443 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4.getRegister(), "POPFQ ZF operation");
12444 auto expr5 = this->symbolicEngine->createSymbolicExpression(inst, node5, dst5.getRegister(), "POPFQ SF operation");
12445 auto expr6 = this->symbolicEngine->createSymbolicExpression(inst, node6, dst6.getRegister(), "POPFQ TF operation");
12446 auto expr7 = this->symbolicEngine->createSymbolicExpression(inst, node7, dst7.getRegister(), "POPFQ IF operation");
12447 auto expr8 = this->symbolicEngine->createSymbolicExpression(inst, node8, dst8.getRegister(), "POPFQ DF operation");
12448 auto expr9 = this->symbolicEngine->createSymbolicExpression(inst, node9, dst9.getRegister(), "POPFQ OF operation");
12449 auto expr10 = this->symbolicEngine->createSymbolicExpression(inst, node10, dst10.getRegister(), "POPFD NT operation");
12450 auto expr11 = this->symbolicEngine->createSymbolicExpression(inst, node11, dst11.getRegister(), "POPFD RF operation");
12451 auto expr12 = this->symbolicEngine->createSymbolicExpression(inst, node12, dst12.getRegister(), "POPFD AC operation");
12452 auto expr13 = this->symbolicEngine->createSymbolicExpression(inst, node13, dst13.getRegister(), "POPFD ID operation");
12453
12454 /* Spread taint */
12455 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src);
12456 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src);
12457 expr3->isTainted = this->taintEngine->taintAssignment(dst3, src);
12458 expr4->isTainted = this->taintEngine->taintAssignment(dst4, src);
12459 expr5->isTainted = this->taintEngine->taintAssignment(dst5, src);
12460 expr6->isTainted = this->taintEngine->taintAssignment(dst6, src);
12461 expr7->isTainted = this->taintEngine->taintAssignment(dst7, src);
12462 expr8->isTainted = this->taintEngine->taintAssignment(dst8, src);
12463 expr9->isTainted = this->taintEngine->taintAssignment(dst9, src);
12464 expr10->isTainted = this->taintEngine->taintAssignment(dst10, src);
12465 expr11->isTainted = this->taintEngine->taintAssignment(dst11, src);
12466 expr12->isTainted = this->taintEngine->taintAssignment(dst12, src);
12467 expr13->isTainted = this->taintEngine->taintAssignment(dst13, src);
12468
12469 /* Create the semantics - side effect */
12470 alignAddStack_s(inst, src.getSize());
12471
12472 /* Update the symbolic control flow */
12473 this->controlFlow_s(inst);
12474 }
12475
12476
12477 void x86Semantics::por_s(triton::arch::Instruction& inst) {
12478 auto& dst = inst.operands[0];
12479 auto& src = inst.operands[1];
12480
12481 /* Create symbolic operands */
12482 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12483 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12484
12485 /* Create the semantics */
12486 auto node = this->astCtxt->bvor(op1, op2);
12487
12488 /* Create symbolic expression */
12489 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "POR operation");
12490
12491 /* Update the x87 FPU Tag Word */
12492 this->updateFTW(inst, expr);
12493
12494 /* Spread taint */
12495 expr->isTainted = this->taintEngine->taintUnion(dst, src);
12496
12497 /* Update the symbolic control flow */
12498 this->controlFlow_s(inst);
12499 }
12500
12501
12502 void x86Semantics::prefetchx_s(triton::arch::Instruction& inst) {
12503 auto& src = inst.operands[0];
12504
12505 /* Only specify that the instruction performs an implicit memory read */
12506 this->symbolicEngine->getOperandAst(inst, src);
12507
12508 /* Update the symbolic control flow */
12509 this->controlFlow_s(inst);
12510 }
12511
12512
12513 void x86Semantics::pshufb_s(triton::arch::Instruction& inst) {
12514 auto& dst = inst.operands[0];
12515 auto& src = inst.operands[1];
12516
12517 /* Create symbolic operands */
12518 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12519 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12520
12521 std::vector<triton::ast::SharedAbstractNode> pack;
12522 pack.reserve(dst.getSize());
12523
12524 /* Create the semantics */
12525 for (int i = dst.getBitSize(); i > 0;) {
12526 i -= 8;
12527 int control = i+7;
12528 int index_low = i;
12529 int index_high = i+(dst.getSize() == 8 ? 2 : 3);
12530 pack.push_back(
12531 this->astCtxt->bvmul(
12532 this->astCtxt->zx(triton::bitsize::byte-1, this->astCtxt->bvnot(
12533 this->astCtxt->extract(control, control, op2))),
12534 this->astCtxt->extract(triton::bitsize::byte-1, 0,
12535 this->astCtxt->bvlshr(
12536 op1,
12537 this->astCtxt->bvmul(
12538 this->astCtxt->zx(triton::bitsize::dqword-(index_high-index_low)-1,
12539 this->astCtxt->extract(index_high, index_low, op2)),
12540 this->astCtxt->bv(8, triton::bitsize::dqword))))));
12541 }
12542
12543 auto node = this->astCtxt->concat(pack);
12544
12545 /* Create symbolic expression */
12546 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSHUFD operation");
12547
12548 /* Spread taint */
12549 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
12550
12551 /* Update the symbolic control flow */
12552 this->controlFlow_s(inst);
12553 }
12554
12555
12556 void x86Semantics::pshufd_s(triton::arch::Instruction& inst) {
12557 auto& dst = inst.operands[0];
12558 auto& src = inst.operands[1];
12559 auto& ord = inst.operands[2];
12560
12561 /* Create symbolic operands */
12562 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12563 auto op3 = this->symbolicEngine->getOperandAst(inst, ord);
12564
12565 /* Create the semantics */
12566 std::vector<triton::ast::SharedAbstractNode> pack;
12567 pack.reserve(4);
12568
12569 pack.push_back(
12570 this->astCtxt->extract(31, 0,
12571 this->astCtxt->bvlshr(
12572 op2,
12573 this->astCtxt->bvmul(
12574 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(7, 6, op3)),
12575 this->astCtxt->bv(32, triton::bitsize::dqword)
12576 )
12577 )
12578 )
12579 );
12580 pack.push_back(
12581 this->astCtxt->extract(31, 0,
12582 this->astCtxt->bvlshr(
12583 op2,
12584 this->astCtxt->bvmul(
12585 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(5, 4, op3)),
12586 this->astCtxt->bv(32, triton::bitsize::dqword)
12587 )
12588 )
12589 )
12590 );
12591 pack.push_back(
12592 this->astCtxt->extract(31, 0,
12593 this->astCtxt->bvlshr(
12594 op2,
12595 this->astCtxt->bvmul(
12596 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(3, 2, op3)),
12597 this->astCtxt->bv(32, triton::bitsize::dqword)
12598 )
12599 )
12600 )
12601 );
12602 pack.push_back(
12603 this->astCtxt->extract(31, 0,
12604 this->astCtxt->bvlshr(
12605 op2,
12606 this->astCtxt->bvmul(
12607 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(1, 0, op3)),
12608 this->astCtxt->bv(32, triton::bitsize::dqword)
12609 )
12610 )
12611 )
12612 );
12613
12614 auto node = this->astCtxt->concat(pack);
12615
12616 /* Create symbolic expression */
12617 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSHUFD operation");
12618
12619 /* Spread taint */
12620 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
12621
12622 /* Update the symbolic control flow */
12623 this->controlFlow_s(inst);
12624 }
12625
12626
12627 void x86Semantics::pshufhw_s(triton::arch::Instruction& inst) {
12628 auto& dst = inst.operands[0];
12629 auto& src = inst.operands[1];
12630 auto& ord = inst.operands[2];
12631
12632 /* Create symbolic operands */
12633 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12634 auto op3 = this->symbolicEngine->getOperandAst(inst, ord);
12635
12636 /* Create the semantics */
12637 std::vector<triton::ast::SharedAbstractNode> pack;
12638 pack.reserve(5);
12639
12640 pack.push_back(
12641 this->astCtxt->extract(79, 64,
12642 this->astCtxt->bvlshr(
12643 op2,
12644 this->astCtxt->bvmul(
12645 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(7, 6, op3)),
12646 this->astCtxt->bv(16, triton::bitsize::dqword)
12647 )
12648 )
12649 )
12650 );
12651 pack.push_back(
12652 this->astCtxt->extract(79, 64,
12653 this->astCtxt->bvlshr(
12654 op2,
12655 this->astCtxt->bvmul(
12656 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(5, 4, op3)),
12657 this->astCtxt->bv(16, triton::bitsize::dqword)
12658 )
12659 )
12660 )
12661 );
12662 pack.push_back(
12663 this->astCtxt->extract(79, 64,
12664 this->astCtxt->bvlshr(
12665 op2,
12666 this->astCtxt->bvmul(
12667 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(3, 2, op3)),
12668 this->astCtxt->bv(16, triton::bitsize::dqword)
12669 )
12670 )
12671 )
12672 );
12673 pack.push_back(
12674 this->astCtxt->extract(79, 64,
12675 this->astCtxt->bvlshr(
12676 op2,
12677 this->astCtxt->bvmul(
12678 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(1, 0, op3)),
12679 this->astCtxt->bv(16, triton::bitsize::dqword)
12680 )
12681 )
12682 )
12683 );
12684 pack.push_back(
12685 this->astCtxt->extract(63, 0, op2)
12686 );
12687
12688 auto node = this->astCtxt->concat(pack);
12689
12690 /* Create symbolic expression */
12691 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSHUFHW operation");
12692
12693 /* Spread taint */
12694 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
12695
12696 /* Update the symbolic control flow */
12697 this->controlFlow_s(inst);
12698 }
12699
12700
12701 void x86Semantics::pshuflw_s(triton::arch::Instruction& inst) {
12702 auto& dst = inst.operands[0];
12703 auto& src = inst.operands[1];
12704 auto& ord = inst.operands[2];
12705
12706 /* Create symbolic operands */
12707 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12708 auto op3 = this->symbolicEngine->getOperandAst(inst, ord);
12709
12710 /* Create the semantics */
12711 std::vector<triton::ast::SharedAbstractNode> pack;
12712 pack.reserve(5);
12713
12714 pack.push_back(
12715 this->astCtxt->extract(127, 64, op2)
12716 );
12717 pack.push_back(
12718 this->astCtxt->extract(15, 0,
12719 this->astCtxt->bvlshr(
12720 op2,
12721 this->astCtxt->bvmul(
12722 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(7, 6, op3)),
12723 this->astCtxt->bv(16, triton::bitsize::dqword)
12724 )
12725 )
12726 )
12727 );
12728 pack.push_back(
12729 this->astCtxt->extract(15, 0,
12730 this->astCtxt->bvlshr(
12731 op2,
12732 this->astCtxt->bvmul(
12733 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(5, 4, op3)),
12734 this->astCtxt->bv(16, triton::bitsize::dqword)
12735 )
12736 )
12737 )
12738 );
12739 pack.push_back(
12740 this->astCtxt->extract(15, 0,
12741 this->astCtxt->bvlshr(
12742 op2,
12743 this->astCtxt->bvmul(
12744 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(3, 2, op3)),
12745 this->astCtxt->bv(16, triton::bitsize::dqword)
12746 )
12747 )
12748 )
12749 );
12750 pack.push_back(
12751 this->astCtxt->extract(15, 0,
12752 this->astCtxt->bvlshr(
12753 op2,
12754 this->astCtxt->bvmul(
12755 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(1, 0, op3)),
12756 this->astCtxt->bv(16, triton::bitsize::dqword)
12757 )
12758 )
12759 )
12760 );
12761
12762 auto node = this->astCtxt->concat(pack);
12763
12764 /* Create symbolic expression */
12765 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSHUFLW operation");
12766
12767 /* Spread taint */
12768 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
12769
12770 /* Update the symbolic control flow */
12771 this->controlFlow_s(inst);
12772 }
12773
12774
12775 void x86Semantics::pshufw_s(triton::arch::Instruction& inst) {
12776 auto& dst = inst.operands[0];
12777 auto& src = inst.operands[1];
12778 auto& ord = inst.operands[2];
12779
12780 /* Create symbolic operands */
12781 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12782 auto op3 = this->symbolicEngine->getOperandAst(inst, ord);
12783
12784 /* Create the semantics */
12785 std::vector<triton::ast::SharedAbstractNode> pack;
12786 pack.reserve(4);
12787
12788 pack.push_back(
12789 this->astCtxt->extract(15, 0,
12790 this->astCtxt->bvlshr(
12791 op2,
12792 this->astCtxt->bvmul(
12793 this->astCtxt->zx(triton::bitsize::qword-2, this->astCtxt->extract(7, 6, op3)),
12794 this->astCtxt->bv(16, triton::bitsize::qword)
12795 )
12796 )
12797 )
12798 );
12799 pack.push_back(
12800 this->astCtxt->extract(15, 0,
12801 this->astCtxt->bvlshr(
12802 op2,
12803 this->astCtxt->bvmul(
12804 this->astCtxt->zx(triton::bitsize::qword-2, this->astCtxt->extract(5, 4, op3)),
12805 this->astCtxt->bv(16, triton::bitsize::qword)
12806 )
12807 )
12808 )
12809 );
12810 pack.push_back(
12811 this->astCtxt->extract(15, 0,
12812 this->astCtxt->bvlshr(
12813 op2,
12814 this->astCtxt->bvmul(
12815 this->astCtxt->zx(triton::bitsize::qword-2, this->astCtxt->extract(3, 2, op3)),
12816 this->astCtxt->bv(16, triton::bitsize::qword)
12817 )
12818 )
12819 )
12820 );
12821 pack.push_back(
12822 this->astCtxt->extract(15, 0,
12823 this->astCtxt->bvlshr(
12824 op2,
12825 this->astCtxt->bvmul(
12826 this->astCtxt->zx(triton::bitsize::qword-2, this->astCtxt->extract(1, 0, op3)),
12827 this->astCtxt->bv(16, triton::bitsize::qword)
12828 )
12829 )
12830 )
12831 );
12832
12833 auto node = this->astCtxt->concat(pack);
12834
12835 /* Create symbolic expression */
12836 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSHUFW operation");
12837
12838 /* Spread taint */
12839 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
12840
12841 /* Update the symbolic control flow */
12842 this->controlFlow_s(inst);
12843 }
12844
12845
12846 void x86Semantics::pslld_s(triton::arch::Instruction& inst) {
12847 auto& dst = inst.operands[0];
12848 auto& src = inst.operands[1];
12849
12850 /* Create symbolic operands */
12851 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12852 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
12853
12854 /* Create the semantics */
12855 std::vector<triton::ast::SharedAbstractNode> packed;
12856 packed.reserve(4);
12857
12858 switch (dst.getBitSize()) {
12859 /* XMM */
12861 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(127, 96, op1), this->astCtxt->extract(31, 0, op2)));
12862 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract( 95, 64, op1), this->astCtxt->extract(31, 0, op2)));
12863
12864 /* MMX */
12866 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(63, 32, op1), this->astCtxt->extract(31, 0, op2)));
12867 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(31, 0, op1), this->astCtxt->extract(31, 0, op2)));
12868 break;
12869
12870 default:
12871 throw triton::exceptions::Semantics("x86Semantics::pslld_s(): Invalid operand size.");
12872 }
12873
12874 auto node = this->astCtxt->concat(packed);
12875
12876 /* Create symbolic expression */
12877 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSLLD operation");
12878
12879 /* Update the x87 FPU Tag Word */
12880 if (dst.getBitSize() == triton::bitsize::qword) {
12881 this->updateFTW(inst, expr);
12882 }
12883
12884 /* Spread taint */
12885 expr->isTainted = this->taintEngine->taintUnion(dst, src);
12886
12887 /* Update the symbolic control flow */
12888 this->controlFlow_s(inst);
12889 }
12890
12891
12892 void x86Semantics::pslldq_s(triton::arch::Instruction& inst) {
12893 auto& dst = inst.operands[0];
12894 auto& src = inst.operands[1];
12895
12896 /* Create symbolic operands */
12897 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12898 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
12899
12900 /* Create the semantics */
12901 auto node = this->astCtxt->bvshl(
12902 op1,
12903 this->astCtxt->bvmul(
12904 this->astCtxt->ite(
12905 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::word, dst.getBitSize())),
12906 this->astCtxt->bv(triton::bitsize::word, dst.getBitSize()),
12907 op2
12908 ),
12909 this->astCtxt->bv(triton::size::qword, dst.getBitSize())
12910 )
12911 );
12912
12913 /* Create symbolic expression */
12914 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSLLDQ operation");
12915
12916 /* Spread taint */
12917 expr->isTainted = this->taintEngine->taintUnion(dst, src);
12918
12919 /* Update the symbolic control flow */
12920 this->controlFlow_s(inst);
12921 }
12922
12923
12924 void x86Semantics::psllq_s(triton::arch::Instruction& inst) {
12925 auto& dst = inst.operands[0];
12926 auto& src = inst.operands[1];
12927
12928 /* Create symbolic operands */
12929 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12930 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
12931
12932 /* Create the semantics */
12934
12935 std::vector<triton::ast::SharedAbstractNode> packed;
12936 packed.reserve(2);
12937
12938 switch (dst.getBitSize()) {
12939 /* XMM */
12941 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(127, 64, op1), this->astCtxt->extract(63, 0, op2)));
12942 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract( 63, 0, op1), this->astCtxt->extract(63, 0, op2)));
12943 node = this->astCtxt->concat(packed);
12944 break;
12945
12946 /* MMX */
12948 /* MMX register is only one QWORD so it's a simple shl */
12949 node = this->astCtxt->bvshl(op1, op2);
12950 break;
12951
12952 default:
12953 throw triton::exceptions::Semantics("x86Semantics::psllq_s(): Invalid operand size.");
12954 }
12955
12956 /* Create symbolic expression */
12957 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSLLQ operation");
12958
12959 /* Update the x87 FPU Tag Word */
12960 if (dst.getBitSize() == triton::bitsize::qword) {
12961 this->updateFTW(inst, expr);
12962 }
12963
12964 /* Spread taint */
12965 expr->isTainted = this->taintEngine->taintUnion(dst, src);
12966
12967 /* Update the symbolic control flow */
12968 this->controlFlow_s(inst);
12969 }
12970
12971
12972 void x86Semantics::psllw_s(triton::arch::Instruction& inst) {
12973 auto& dst = inst.operands[0];
12974 auto& src = inst.operands[1];
12975
12976 /* Create symbolic operands */
12977 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12978 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
12979
12980 /* Create the semantics */
12981 std::vector<triton::ast::SharedAbstractNode> packed;
12982 packed.reserve(8);
12983
12984 switch (dst.getBitSize()) {
12985 /* XMM */
12987 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(127, 112, op1), this->astCtxt->extract(15, 0, op2)));
12988 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(111, 96, op1), this->astCtxt->extract(15, 0, op2)));
12989 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract( 95, 80, op1), this->astCtxt->extract(15, 0, op2)));
12990 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract( 79, 64, op1), this->astCtxt->extract(15, 0, op2)));
12991
12992 /* MMX */
12994 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(63, 48, op1), this->astCtxt->extract(15, 0, op2)));
12995 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(47, 32, op1), this->astCtxt->extract(15, 0, op2)));
12996 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(31, 16, op1), this->astCtxt->extract(15, 0, op2)));
12997 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(15, 0, op1), this->astCtxt->extract(15, 0, op2)));
12998 break;
12999
13000 default:
13001 throw triton::exceptions::Semantics("x86Semantics::psllw_s(): Invalid operand size.");
13002 }
13003
13004 auto node = this->astCtxt->concat(packed);
13005
13006 /* Create symbolic expression */
13007 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSLLW operation");
13008
13009 /* Update the x87 FPU Tag Word */
13010 if (dst.getBitSize() == triton::bitsize::qword) {
13011 this->updateFTW(inst, expr);
13012 }
13013
13014 /* Spread taint */
13015 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13016
13017 /* Update the symbolic control flow */
13018 this->controlFlow_s(inst);
13019 }
13020
13021
13022 void x86Semantics::psrad_s(triton::arch::Instruction& inst) {
13023 auto& dst = inst.operands[0];
13024 auto& src = inst.operands[1];
13025
13026 /* Create symbolic operands */
13027 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13028 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13029
13030 /* Create the semantics */
13031 std::vector<triton::ast::SharedAbstractNode> pck;
13032 pck.reserve(dst.getSize() / triton::size::dword);
13033
13034 auto shift = this->astCtxt->ite(
13035 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::dword, src.getBitSize())),
13036 this->astCtxt->bv(triton::bitsize::dword, src.getBitSize()),
13037 op2
13038 );
13039
13040 if (shift->getBitvectorSize() < triton::bitsize::dword) {
13041 shift = this->astCtxt->zx(triton::bitsize::dword - shift->getBitvectorSize(), shift);
13042 }
13043 else {
13044 shift = this->astCtxt->extract(triton::bitsize::dword - 1, 0, shift);
13045 }
13046
13047 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::dword; ++i) {
13048 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::dword);
13050 pck.push_back(this->astCtxt->bvashr(this->astCtxt->extract(high, low, op1), shift));
13051 }
13052 auto node = this->astCtxt->concat(pck);
13053
13054 /* Create symbolic expression */
13055 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSRAD operation");
13056
13057 /* Spread taint */
13058 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13059
13060 /* Update the symbolic control flow */
13061 this->controlFlow_s(inst);
13062 }
13063
13064
13065 void x86Semantics::psraw_s(triton::arch::Instruction& inst) {
13066 auto& dst = inst.operands[0];
13067 auto& src = inst.operands[1];
13068
13069 /* Create symbolic operands */
13070 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13071 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13072
13073 /* Create the semantics */
13074 std::vector<triton::ast::SharedAbstractNode> pck;
13075 pck.reserve(dst.getSize() / triton::size::word);
13076
13077 auto shift = this->astCtxt->ite(
13078 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::word, src.getBitSize())),
13079 this->astCtxt->bv(triton::bitsize::word, src.getBitSize()),
13080 op2
13081 );
13082
13083 if (shift->getBitvectorSize() < triton::bitsize::word) {
13084 shift = this->astCtxt->zx(triton::bitsize::word - shift->getBitvectorSize(), shift);
13085 }
13086 else {
13087 shift = this->astCtxt->extract(triton::bitsize::word - 1, 0, shift);
13088 }
13089
13090 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; ++i) {
13091 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
13093 pck.push_back(this->astCtxt->bvashr(this->astCtxt->extract(high, low, op1), shift));
13094 }
13095 auto node = this->astCtxt->concat(pck);
13096
13097 /* Create symbolic expression */
13098 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSRAW operation");
13099
13100 /* Spread taint */
13101 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13102
13103 /* Update the symbolic control flow */
13104 this->controlFlow_s(inst);
13105 }
13106
13107
13108 void x86Semantics::psrld_s(triton::arch::Instruction& inst) {
13109 auto& dst = inst.operands[0];
13110 auto& src = inst.operands[1];
13111
13112 /* Create symbolic operands */
13113 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13114 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
13115
13116 /* Create the semantics */
13117 std::vector<triton::ast::SharedAbstractNode> packed;
13118 packed.reserve(4);
13119
13120 switch (dst.getBitSize()) {
13121 /* XMM */
13123 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(127, 96, op1), this->astCtxt->extract(31, 0, op2)));
13124 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract( 95, 64, op1), this->astCtxt->extract(31, 0, op2)));
13125
13126 /* MMX */
13128 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(63, 32, op1), this->astCtxt->extract(31, 0, op2)));
13129 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(31, 0, op1), this->astCtxt->extract(31, 0, op2)));
13130 break;
13131
13132 default:
13133 throw triton::exceptions::Semantics("x86Semantics::psrld_s(): Invalid operand size.");
13134 }
13135
13136 auto node = this->astCtxt->concat(packed);
13137
13138 /* Create symbolic expression */
13139 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSRLD operation");
13140
13141 /* Update the x87 FPU Tag Word */
13142 if (dst.getBitSize() == triton::bitsize::qword) {
13143 this->updateFTW(inst, expr);
13144 }
13145
13146 /* Spread taint */
13147 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13148
13149 /* Update the symbolic control flow */
13150 this->controlFlow_s(inst);
13151 }
13152
13153
13154 void x86Semantics::psrldq_s(triton::arch::Instruction& inst) {
13155 auto& dst = inst.operands[0];
13156 auto& src = inst.operands[1];
13157
13158 /* Create symbolic operands */
13159 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13160 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
13161
13162 /* Create the semantics */
13163 auto node = this->astCtxt->bvlshr(
13164 op1,
13165 this->astCtxt->bvmul(
13166 this->astCtxt->ite(
13167 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::word, dst.getBitSize())),
13168 this->astCtxt->bv(triton::bitsize::word, dst.getBitSize()),
13169 op2
13170 ),
13171 this->astCtxt->bv(triton::size::qword, dst.getBitSize())
13172 )
13173 );
13174
13175 /* Create symbolic expression */
13176 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSRLDQ operation");
13177
13178 /* Spread taint */
13179 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13180
13181 /* Update the symbolic control flow */
13182 this->controlFlow_s(inst);
13183 }
13184
13185
13186 void x86Semantics::psrlq_s(triton::arch::Instruction& inst) {
13187 auto& dst = inst.operands[0];
13188 auto& src = inst.operands[1];
13189
13190 /* Create symbolic operands */
13191 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13192 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
13193
13194 /* Create the semantics */
13196
13197 std::vector<triton::ast::SharedAbstractNode> packed;
13198 packed.reserve(2);
13199
13200 switch (dst.getBitSize()) {
13201 /* XMM */
13203 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(127, 64, op1), this->astCtxt->extract(63, 0, op2)));
13204 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract( 63, 0, op1), this->astCtxt->extract(63, 0, op2)));
13205 node = this->astCtxt->concat(packed);
13206 break;
13207
13208 /* MMX */
13210 /* MMX register is only one QWORD so it's a simple shr */
13211 node = this->astCtxt->bvlshr(op1, op2);
13212 break;
13213
13214 default:
13215 throw triton::exceptions::Semantics("x86Semantics::psrlq_s(): Invalid operand size.");
13216 }
13217
13218 /* Create symbolic expression */
13219 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSRLQ operation");
13220
13221 /* Update the x87 FPU Tag Word */
13222 if (dst.getBitSize() == triton::bitsize::qword) {
13223 this->updateFTW(inst, expr);
13224 }
13225
13226 /* Spread taint */
13227 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13228
13229 /* Update the symbolic control flow */
13230 this->controlFlow_s(inst);
13231 }
13232
13233
13234 void x86Semantics::psrlw_s(triton::arch::Instruction& inst) {
13235 auto& dst = inst.operands[0];
13236 auto& src = inst.operands[1];
13237
13238 /* Create symbolic operands */
13239 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13240 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
13241
13242 /* Create the semantics */
13243 std::vector<triton::ast::SharedAbstractNode> packed;
13244 packed.reserve(8);
13245
13246 switch (dst.getBitSize()) {
13247 /* XMM */
13249 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(127, 112, op1), this->astCtxt->extract(15, 0, op2)));
13250 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(111, 96, op1), this->astCtxt->extract(15, 0, op2)));
13251 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract( 95, 80, op1), this->astCtxt->extract(15, 0, op2)));
13252 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract( 79, 64, op1), this->astCtxt->extract(15, 0, op2)));
13253
13254 /* MMX */
13256 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(63, 48, op1), this->astCtxt->extract(15, 0, op2)));
13257 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(47, 32, op1), this->astCtxt->extract(15, 0, op2)));
13258 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(31, 16, op1), this->astCtxt->extract(15, 0, op2)));
13259 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(15, 0, op1), this->astCtxt->extract(15, 0, op2)));
13260 break;
13261
13262 default:
13263 throw triton::exceptions::Semantics("x86Semantics::psrlw_s(): Invalid operand size.");
13264 }
13265
13266 auto node = this->astCtxt->concat(packed);
13267
13268 /* Create symbolic expression */
13269 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSRLW operation");
13270
13271 /* Update the x87 FPU Tag Word */
13272 if (dst.getBitSize() == triton::bitsize::qword) {
13273 this->updateFTW(inst, expr);
13274 }
13275
13276 /* Spread taint */
13277 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13278
13279 /* Update the symbolic control flow */
13280 this->controlFlow_s(inst);
13281 }
13282
13283
13284 void x86Semantics::psubb_s(triton::arch::Instruction& inst) {
13285 auto& dst = inst.operands[0];
13286 auto& src = inst.operands[1];
13287
13288 /* Create symbolic operands */
13289 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13290 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13291
13292 /* Create the semantics */
13293 std::vector<triton::ast::SharedAbstractNode> packed;
13294 packed.reserve(16);
13295
13296 switch (dst.getBitSize()) {
13297
13298 /* XMM */
13300 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(127, 120, op1), this->astCtxt->extract(127, 120, op2)));
13301 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(119, 112, op1), this->astCtxt->extract(119, 112, op2)));
13302 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(111, 104, op1), this->astCtxt->extract(111, 104, op2)));
13303 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(103, 96, op1), this->astCtxt->extract(103, 96, op2)));
13304 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(95, 88, op1), this->astCtxt->extract(95, 88, op2)));
13305 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(87, 80, op1), this->astCtxt->extract(87, 80, op2)));
13306 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(79, 72, op1), this->astCtxt->extract(79, 72, op2)));
13307 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(71, 64, op1), this->astCtxt->extract(71, 64, op2)));
13308
13309 /* MMX */
13311 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(63, 56, op1), this->astCtxt->extract(63, 56, op2)));
13312 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(55, 48, op1), this->astCtxt->extract(55, 48, op2)));
13313 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(47, 40, op1), this->astCtxt->extract(47, 40, op2)));
13314 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(39, 32, op1), this->astCtxt->extract(39, 32, op2)));
13315 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(31, 24, op1), this->astCtxt->extract(31, 24, op2)));
13316 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(23, 16, op1), this->astCtxt->extract(23, 16, op2)));
13317 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(15, 8, op1), this->astCtxt->extract(15, 8, op2)));
13318 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(7, 0, op1), this->astCtxt->extract(7, 0, op2)));
13319 break;
13320
13321 default:
13322 throw triton::exceptions::Semantics("x86Semantics::psubb_s(): Invalid operand size.");
13323
13324 }
13325
13326 auto node = this->astCtxt->concat(packed);
13327
13328 /* Create symbolic expression */
13329 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSUBB operation");
13330
13331 /* Update the x87 FPU Tag Word */
13332 if (dst.getBitSize() == triton::bitsize::qword) {
13333 this->updateFTW(inst, expr);
13334 }
13335
13336 /* Spread taint */
13337 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13338
13339 /* Update the symbolic control flow */
13340 this->controlFlow_s(inst);
13341 }
13342
13343
13344 void x86Semantics::psubd_s(triton::arch::Instruction& inst) {
13345 auto& dst = inst.operands[0];
13346 auto& src = inst.operands[1];
13347
13348 /* Create symbolic operands */
13349 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13350 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13351
13352 /* Create the semantics */
13353 std::vector<triton::ast::SharedAbstractNode> packed;
13354 packed.reserve(4);
13355
13356 switch (dst.getBitSize()) {
13357
13358 /* XMM */
13360 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(127, 96, op1), this->astCtxt->extract(127, 96, op2)));
13361 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(95, 64, op1), this->astCtxt->extract(95, 64, op2)));
13362
13363 /* MMX */
13365 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(63, 32, op1), this->astCtxt->extract(63, 32, op2)));
13366 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(31, 0, op1), this->astCtxt->extract(31, 0, op2)));
13367 break;
13368
13369 default:
13370 throw triton::exceptions::Semantics("x86Semantics::psubd_s(): Invalid operand size.");
13371
13372 }
13373
13374 auto node = this->astCtxt->concat(packed);
13375
13376 /* Create symbolic expression */
13377 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSUBD operation");
13378
13379 /* Update the x87 FPU Tag Word */
13380 if (dst.getBitSize() == triton::bitsize::qword) {
13381 this->updateFTW(inst, expr);
13382 }
13383
13384 /* Spread taint */
13385 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13386
13387 /* Update the symbolic control flow */
13388 this->controlFlow_s(inst);
13389 }
13390
13391
13392 void x86Semantics::psubq_s(triton::arch::Instruction& inst) {
13393 auto& dst = inst.operands[0];
13394 auto& src = inst.operands[1];
13395
13396 /* Create symbolic operands */
13397 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13398 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13399
13400 /* Create the semantics */
13401 std::vector<triton::ast::SharedAbstractNode> packed;
13402 packed.reserve(2);
13403
13404 switch (dst.getBitSize()) {
13405
13406 /* XMM */
13408 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(127, 64, op1), this->astCtxt->extract(127, 64, op2)));
13409
13410 /* MMX */
13412 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(63, 0, op1), this->astCtxt->extract(63, 0, op2)));
13413 break;
13414
13415 default:
13416 throw triton::exceptions::Semantics("x86Semantics::psubq_s(): Invalid operand size.");
13417
13418 }
13419
13420 auto node = this->astCtxt->concat(packed);
13421
13422 /* Create symbolic expression */
13423 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSUBQ operation");
13424
13425 /* Update the x87 FPU Tag Word */
13426 if (dst.getBitSize() == triton::bitsize::qword) {
13427 this->updateFTW(inst, expr);
13428 }
13429
13430 /* Spread taint */
13431 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13432
13433 /* Update the symbolic control flow */
13434 this->controlFlow_s(inst);
13435 }
13436
13437
13438 void x86Semantics::psubw_s(triton::arch::Instruction& inst) {
13439 auto& dst = inst.operands[0];
13440 auto& src = inst.operands[1];
13441
13442 /* Create symbolic operands */
13443 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13444 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13445
13446 /* Create the semantics */
13447 std::vector<triton::ast::SharedAbstractNode> packed;
13448 packed.reserve(8);
13449
13450 switch (dst.getBitSize()) {
13451
13452 /* XMM */
13454 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(127, 112, op1), this->astCtxt->extract(127, 112, op2)));
13455 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(111, 96, op1), this->astCtxt->extract(111, 96, op2)));
13456 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(95, 80, op1), this->astCtxt->extract(95, 80, op2)));
13457 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(79, 64, op1), this->astCtxt->extract(79, 64, op2)));
13458
13459 /* MMX */
13461 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(63, 48, op1), this->astCtxt->extract(63, 48, op2)));
13462 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(47, 32, op1), this->astCtxt->extract(47, 32, op2)));
13463 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(31, 16, op1), this->astCtxt->extract(31, 16, op2)));
13464 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(15, 0, op1), this->astCtxt->extract(15, 0, op2)));
13465 break;
13466
13467 default:
13468 throw triton::exceptions::Semantics("x86Semantics::psubw_s(): Invalid operand size.");
13469
13470 }
13471
13472 auto node = this->astCtxt->concat(packed);
13473
13474 /* Create symbolic expression */
13475 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSUBW operation");
13476
13477 /* Update the x87 FPU Tag Word */
13478 if (dst.getBitSize() == triton::bitsize::qword) {
13479 this->updateFTW(inst, expr);
13480 }
13481
13482 /* Spread taint */
13483 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13484
13485 /* Update the symbolic control flow */
13486 this->controlFlow_s(inst);
13487 }
13488
13489
13490 void x86Semantics::ptest_s(triton::arch::Instruction& inst) {
13491 auto& src1 = inst.operands[0];
13492 auto& src2 = inst.operands[1];
13493
13494 /* Create symbolic operands */
13495 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
13496 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
13497
13498 /* Create the semantics */
13499 auto node1 = this->astCtxt->bvand(op1, op2);
13500 auto node2 = this->astCtxt->bvand(op1, this->astCtxt->bvnot(op2));
13501
13502 /* Create symbolic expression */
13503 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "PTEST operation");
13504 auto expr2 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node2, "PTEST operation");
13505
13506 /* Spread taint */
13507 expr1->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2);
13508 expr2->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2);
13509
13510 /* Update symbolic flags */
13511 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_AF), "Clears adjust flag");
13512 this->cfPtest_s(inst, expr2, src1, true);
13513 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
13514 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_PF), "Clears parity flag");
13515 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_SF), "Clears sign flag");
13516 this->zf_s(inst, expr1, src1, true);
13517
13518 /* Update the symbolic control flow */
13519 this->controlFlow_s(inst);
13520 }
13521
13522
13523 void x86Semantics::punpckhbw_s(triton::arch::Instruction& inst) {
13524 auto& dst = inst.operands[0];
13525 auto& src = inst.operands[1];
13526
13527 /* Create symbolic operands */
13528 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13529 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13530
13531 /* Create the semantics */
13532 std::vector<triton::ast::SharedAbstractNode> unpack;
13533 unpack.reserve(24);
13534
13535 switch (dst.getBitSize()) {
13536
13537 /* MMX */
13539 unpack.push_back(this->astCtxt->extract(63, 56, op2));
13540 unpack.push_back(this->astCtxt->extract(63, 56, op1));
13541 unpack.push_back(this->astCtxt->extract(55, 48, op2));
13542 unpack.push_back(this->astCtxt->extract(55, 48, op1));
13543 unpack.push_back(this->astCtxt->extract(47, 40, op2));
13544 unpack.push_back(this->astCtxt->extract(55, 40, op1));
13545 unpack.push_back(this->astCtxt->extract(39, 32, op2));
13546 unpack.push_back(this->astCtxt->extract(39, 32, op1));
13547 break;
13548
13549 /* XMM */
13551 unpack.push_back(this->astCtxt->extract(127, 120, op2));
13552 unpack.push_back(this->astCtxt->extract(127, 120, op1));
13553 unpack.push_back(this->astCtxt->extract(119, 112, op2));
13554 unpack.push_back(this->astCtxt->extract(119, 112, op1));
13555 unpack.push_back(this->astCtxt->extract(111, 104, op2));
13556 unpack.push_back(this->astCtxt->extract(111, 104, op1));
13557 unpack.push_back(this->astCtxt->extract(103, 96, op2));
13558 unpack.push_back(this->astCtxt->extract(103, 96, op1));
13559 unpack.push_back(this->astCtxt->extract(95, 88, op2));
13560 unpack.push_back(this->astCtxt->extract(95, 88, op1));
13561 unpack.push_back(this->astCtxt->extract(87, 80, op2));
13562 unpack.push_back(this->astCtxt->extract(87, 80, op1));
13563 unpack.push_back(this->astCtxt->extract(79, 72, op2));
13564 unpack.push_back(this->astCtxt->extract(79, 72, op1));
13565 unpack.push_back(this->astCtxt->extract(71, 64, op2));
13566 unpack.push_back(this->astCtxt->extract(71, 64, op1));
13567 break;
13568
13569 default:
13570 throw triton::exceptions::Semantics("x86Semantics::punpckhbw_s(): Invalid operand size.");
13571 }
13572
13573 auto node = this->astCtxt->concat(unpack);
13574
13575 /* Create symbolic expression */
13576 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKHBW operation");
13577
13578 /* Update the x87 FPU Tag Word */
13579 if (dst.getBitSize() == triton::bitsize::qword) {
13580 this->updateFTW(inst, expr);
13581 }
13582
13583 /* Apply the taint */
13584 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13585
13586 /* Update the symbolic control flow */
13587 this->controlFlow_s(inst);
13588 }
13589
13590
13591 void x86Semantics::punpckhdq_s(triton::arch::Instruction& inst) {
13592 auto& dst = inst.operands[0];
13593 auto& src = inst.operands[1];
13594
13595 /* Create symbolic operands */
13596 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13597 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13598
13599 /* Create the semantics */
13600 std::vector<triton::ast::SharedAbstractNode> unpack;
13601 unpack.reserve(6);
13602
13603 switch (dst.getBitSize()) {
13604
13605 /* MMX */
13607 unpack.push_back(this->astCtxt->extract(63, 32, op2));
13608 unpack.push_back(this->astCtxt->extract(63, 32, op1));
13609 break;
13610
13611 /* XMM */
13613 unpack.push_back(this->astCtxt->extract(127, 96, op2));
13614 unpack.push_back(this->astCtxt->extract(127, 96, op1));
13615 unpack.push_back(this->astCtxt->extract(95, 64, op2));
13616 unpack.push_back(this->astCtxt->extract(95, 64, op1));
13617 break;
13618
13619 default:
13620 throw triton::exceptions::Semantics("x86Semantics::punpckhdq_s(): Invalid operand size.");
13621 }
13622
13623 auto node = this->astCtxt->concat(unpack);
13624
13625 /* Create symbolic expression */
13626 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKHDQ operation");
13627
13628 /* Update the x87 FPU Tag Word */
13629 if (dst.getBitSize() == triton::bitsize::qword) {
13630 this->updateFTW(inst, expr);
13631 }
13632
13633 /* Apply the taint */
13634 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13635
13636 /* Update the symbolic control flow */
13637 this->controlFlow_s(inst);
13638 }
13639
13640
13641 void x86Semantics::punpckhqdq_s(triton::arch::Instruction& inst) {
13642 auto& dst = inst.operands[0];
13643 auto& src = inst.operands[1];
13644
13645 /* Create symbolic operands */
13646 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13647 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13648
13649 /* Create the semantics */
13650 std::vector<triton::ast::SharedAbstractNode> unpack;
13651 unpack.reserve(2);
13652
13653 switch (dst.getBitSize()) {
13654
13655 /* XMM */
13657 unpack.push_back(this->astCtxt->extract(127, 64, op2));
13658 unpack.push_back(this->astCtxt->extract(127, 64, op1));
13659 break;
13660
13661 default:
13662 throw triton::exceptions::Semantics("x86Semantics::punpckhqdq_s(): Invalid operand size.");
13663 }
13664
13665 auto node = this->astCtxt->concat(unpack);
13666
13667 /* Create symbolic expression */
13668 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKHQDQ operation");
13669
13670 /* Apply the taint */
13671 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13672
13673 /* Update the symbolic control flow */
13674 this->controlFlow_s(inst);
13675 }
13676
13677
13678 void x86Semantics::punpckhwd_s(triton::arch::Instruction& inst) {
13679 auto& dst = inst.operands[0];
13680 auto& src = inst.operands[1];
13681
13682 /* Create symbolic operands */
13683 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13684 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13685
13686 /* Create the semantics */
13687 std::vector<triton::ast::SharedAbstractNode> unpack;
13688 unpack.reserve(12);
13689
13690 switch (dst.getBitSize()) {
13691
13692 /* MMX */
13694 unpack.push_back(this->astCtxt->extract(63, 48, op2));
13695 unpack.push_back(this->astCtxt->extract(63, 48, op1));
13696 unpack.push_back(this->astCtxt->extract(47, 32, op2));
13697 unpack.push_back(this->astCtxt->extract(47, 32, op1));
13698 break;
13699
13700 /* XMM */
13702 unpack.push_back(this->astCtxt->extract(127, 112, op2));
13703 unpack.push_back(this->astCtxt->extract(127, 112, op1));
13704 unpack.push_back(this->astCtxt->extract(111, 96, op2));
13705 unpack.push_back(this->astCtxt->extract(111, 96, op1));
13706 unpack.push_back(this->astCtxt->extract(95, 80, op2));
13707 unpack.push_back(this->astCtxt->extract(95, 80, op1));
13708 unpack.push_back(this->astCtxt->extract(79, 64, op2));
13709 unpack.push_back(this->astCtxt->extract(79, 64, op1));
13710 break;
13711
13712 default:
13713 throw triton::exceptions::Semantics("x86Semantics::punpckhwd_s(): Invalid operand size.");
13714 }
13715
13716 auto node = this->astCtxt->concat(unpack);
13717
13718 /* Create symbolic expression */
13719 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKHWD operation");
13720
13721 /* Update the x87 FPU Tag Word */
13722 if (dst.getBitSize() == triton::bitsize::qword) {
13723 this->updateFTW(inst, expr);
13724 }
13725
13726 /* Apply the taint */
13727 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13728
13729 /* Update the symbolic control flow */
13730 this->controlFlow_s(inst);
13731 }
13732
13733
13734 void x86Semantics::punpcklbw_s(triton::arch::Instruction& inst) {
13735 auto& dst = inst.operands[0];
13736 auto& src = inst.operands[1];
13737
13738 /* Create symbolic operands */
13739 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13740 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13741
13742 /* Create the semantics */
13743 std::vector<triton::ast::SharedAbstractNode> unpack;
13744 unpack.reserve(24);
13745
13746 switch (dst.getBitSize()) {
13747
13748 /* MMX */
13750 unpack.push_back(this->astCtxt->extract(31, 24, op2));
13751 unpack.push_back(this->astCtxt->extract(31, 24, op1));
13752 unpack.push_back(this->astCtxt->extract(23, 16, op2));
13753 unpack.push_back(this->astCtxt->extract(23, 16, op1));
13754 unpack.push_back(this->astCtxt->extract(15, 8, op2));
13755 unpack.push_back(this->astCtxt->extract(15, 8, op1));
13756 unpack.push_back(this->astCtxt->extract(7, 0, op2));
13757 unpack.push_back(this->astCtxt->extract(7, 0, op1));
13758 break;
13759
13760 /* XMM */
13762 unpack.push_back(this->astCtxt->extract(63, 56, op2));
13763 unpack.push_back(this->astCtxt->extract(63, 56, op1));
13764 unpack.push_back(this->astCtxt->extract(55, 48, op2));
13765 unpack.push_back(this->astCtxt->extract(55, 48, op1));
13766 unpack.push_back(this->astCtxt->extract(47, 40, op2));
13767 unpack.push_back(this->astCtxt->extract(47, 40, op1));
13768 unpack.push_back(this->astCtxt->extract(39, 32, op2));
13769 unpack.push_back(this->astCtxt->extract(39, 32, op1));
13770 unpack.push_back(this->astCtxt->extract(31, 24, op2));
13771 unpack.push_back(this->astCtxt->extract(31, 24, op1));
13772 unpack.push_back(this->astCtxt->extract(23, 16, op2));
13773 unpack.push_back(this->astCtxt->extract(23, 16, op1));
13774 unpack.push_back(this->astCtxt->extract(15, 8, op2));
13775 unpack.push_back(this->astCtxt->extract(15, 8, op1));
13776 unpack.push_back(this->astCtxt->extract(7, 0, op2));
13777 unpack.push_back(this->astCtxt->extract(7, 0, op1));
13778 break;
13779
13780 default:
13781 throw triton::exceptions::Semantics("x86Semantics::punpcklbw_s(): Invalid operand size.");
13782 }
13783
13784 auto node = this->astCtxt->concat(unpack);
13785
13786 /* Create symbolic expression */
13787 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKLBW operation");
13788
13789 /* Update the x87 FPU Tag Word */
13790 if (dst.getBitSize() == triton::bitsize::qword) {
13791 this->updateFTW(inst, expr);
13792 }
13793
13794 /* Apply the taint */
13795 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13796
13797 /* Update the symbolic control flow */
13798 this->controlFlow_s(inst);
13799 }
13800
13801
13802 void x86Semantics::punpckldq_s(triton::arch::Instruction& inst) {
13803 auto& dst = inst.operands[0];
13804 auto& src = inst.operands[1];
13805
13806 /* Create symbolic operands */
13807 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13808 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13809
13810 /* Create the semantics */
13811 std::vector<triton::ast::SharedAbstractNode> unpack;
13812 unpack.reserve(6);
13813
13814 switch (dst.getBitSize()) {
13815
13816 /* MMX */
13818 unpack.push_back(this->astCtxt->extract(31, 0, op2));
13819 unpack.push_back(this->astCtxt->extract(31, 0, op1));
13820 break;
13821
13822 /* XMM */
13824 unpack.push_back(this->astCtxt->extract(63, 32, op2));
13825 unpack.push_back(this->astCtxt->extract(63, 32, op1));
13826 unpack.push_back(this->astCtxt->extract(31, 0, op2));
13827 unpack.push_back(this->astCtxt->extract(31, 0, op1));
13828 break;
13829
13830 default:
13831 throw triton::exceptions::Semantics("x86Semantics::punpckldq_s(): Invalid operand size.");
13832 }
13833
13834 auto node = this->astCtxt->concat(unpack);
13835
13836 /* Create symbolic expression */
13837 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKLDQ operation");
13838
13839 /* Update the x87 FPU Tag Word */
13840 if (dst.getBitSize() == triton::bitsize::qword) {
13841 this->updateFTW(inst, expr);
13842 }
13843
13844 /* Apply the taint */
13845 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13846
13847 /* Update the symbolic control flow */
13848 this->controlFlow_s(inst);
13849 }
13850
13851
13852 void x86Semantics::punpcklqdq_s(triton::arch::Instruction& inst) {
13853 auto& dst = inst.operands[0];
13854 auto& src = inst.operands[1];
13855
13856 /* Create symbolic operands */
13857 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13858 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13859
13860 /* Create the semantics */
13861 std::vector<triton::ast::SharedAbstractNode> unpack;
13862 unpack.reserve(2);
13863
13864 switch (dst.getBitSize()) {
13865
13866 /* XMM */
13868 unpack.push_back(this->astCtxt->extract(63, 0, op2));
13869 unpack.push_back(this->astCtxt->extract(63, 0, op1));
13870 break;
13871
13872 default:
13873 throw triton::exceptions::Semantics("x86Semantics::punpcklqdq_s(): Invalid operand size.");
13874 }
13875
13876 auto node = this->astCtxt->concat(unpack);
13877
13878 /* Create symbolic expression */
13879 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKLQDQ operation");
13880
13881 /* Apply the taint */
13882 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13883
13884 /* Update the symbolic control flow */
13885 this->controlFlow_s(inst);
13886 }
13887
13888
13889 void x86Semantics::punpcklwd_s(triton::arch::Instruction& inst) {
13890 auto& dst = inst.operands[0];
13891 auto& src = inst.operands[1];
13892
13893 /* Create symbolic operands */
13894 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13895 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13896
13897 /* Create the semantics */
13898 std::vector<triton::ast::SharedAbstractNode> unpack;
13899 unpack.reserve(12);
13900
13901 switch (dst.getBitSize()) {
13902
13903 /* MMX */
13905 unpack.push_back(this->astCtxt->extract(31, 16, op2));
13906 unpack.push_back(this->astCtxt->extract(31, 16, op1));
13907 unpack.push_back(this->astCtxt->extract(15, 0, op2));
13908 unpack.push_back(this->astCtxt->extract(15, 0, op1));
13909 break;
13910
13911 /* XMM */
13913 unpack.push_back(this->astCtxt->extract(63, 48, op2));
13914 unpack.push_back(this->astCtxt->extract(63, 48, op1));
13915 unpack.push_back(this->astCtxt->extract(47, 32, op2));
13916 unpack.push_back(this->astCtxt->extract(47, 32, op1));
13917 unpack.push_back(this->astCtxt->extract(31, 16, op2));
13918 unpack.push_back(this->astCtxt->extract(31, 16, op1));
13919 unpack.push_back(this->astCtxt->extract(15, 0, op2));
13920 unpack.push_back(this->astCtxt->extract(15, 0, op1));
13921 break;
13922
13923 default:
13924 throw triton::exceptions::Semantics("x86Semantics::punpcklwd_s(): Invalid operand size.");
13925 }
13926
13927 auto node = this->astCtxt->concat(unpack);
13928
13929 /* Create symbolic expression */
13930 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKLWD operation");
13931
13932 /* Update the x87 FPU Tag Word */
13933 if (dst.getBitSize() == triton::bitsize::qword) {
13934 this->updateFTW(inst, expr);
13935 }
13936
13937 /* Apply the taint */
13938 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13939
13940 /* Update the symbolic control flow */
13941 this->controlFlow_s(inst);
13942 }
13943
13944
13945 void x86Semantics::push_s(triton::arch::Instruction& inst) {
13946 auto& src = inst.operands[0];
13947 auto stack = this->architecture->getStackPointer();
13948 triton::uint32 size = stack.getSize();
13949
13950 /* If it's an immediate source, the memory access is always based on the arch size */
13951 if (src.getType() != triton::arch::OP_IMM)
13952 size = src.getSize();
13953
13954 /* Create symbolic operands */
13955 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
13956
13957 /* Create the semantics - side effect */
13958 auto stackValue = alignSubStack_s(inst, size);
13959 auto dst = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, size));
13960
13961 /* Create the semantics */
13962 auto node = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), op1);
13963
13964 /* Create symbolic expression */
13965 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUSH operation");
13966
13967 /* Spread taint */
13968 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
13969
13970 /* Update the symbolic control flow */
13971 this->controlFlow_s(inst);
13972 }
13973
13974
13975 void x86Semantics::pushal_s(triton::arch::Instruction& inst) {
13976 auto stack = this->architecture->getStackPointer();
13977 auto stackValue = static_cast<triton::uint64>(this->architecture->getConcreteRegisterValue(stack));
13978 auto dst1 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 1), stack.getSize()));
13979 auto dst2 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 2), stack.getSize()));
13980 auto dst3 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 3), stack.getSize()));
13981 auto dst4 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 4), stack.getSize()));
13982 auto dst5 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 5), stack.getSize()));
13983 auto dst6 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 6), stack.getSize()));
13984 auto dst7 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 7), stack.getSize()));
13985 auto dst8 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 8), stack.getSize()));
13986 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
13987 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ECX));
13988 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
13989 auto src4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EBX));
13990 auto src5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ESP));
13991 auto src6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EBP));
13992 auto src7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ESI));
13993 auto src8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDI));
13994
13995 /* Create symbolic operands */
13996 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
13997 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
13998 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
13999 auto op4 = this->symbolicEngine->getOperandAst(inst, src4);
14000 auto op5 = this->symbolicEngine->getOperandAst(inst, src5);
14001 auto op6 = this->symbolicEngine->getOperandAst(inst, src6);
14002 auto op7 = this->symbolicEngine->getOperandAst(inst, src7);
14003 auto op8 = this->symbolicEngine->getOperandAst(inst, src8);
14004
14005 /* Create the semantics */
14006 auto node1 = this->astCtxt->zx(dst1.getBitSize() - src1.getBitSize(), op1);
14007 auto node2 = this->astCtxt->zx(dst2.getBitSize() - src2.getBitSize(), op2);
14008 auto node3 = this->astCtxt->zx(dst3.getBitSize() - src3.getBitSize(), op3);
14009 auto node4 = this->astCtxt->zx(dst4.getBitSize() - src4.getBitSize(), op4);
14010 auto node5 = this->astCtxt->zx(dst5.getBitSize() - src5.getBitSize(), op5);
14011 auto node6 = this->astCtxt->zx(dst6.getBitSize() - src6.getBitSize(), op6);
14012 auto node7 = this->astCtxt->zx(dst7.getBitSize() - src7.getBitSize(), op7);
14013 auto node8 = this->astCtxt->zx(dst8.getBitSize() - src8.getBitSize(), op8);
14014
14015 /* Create symbolic expression */
14016 alignSubStack_s(inst, 32);
14017 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1, "PUSHAL EAX operation");
14018 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "PUSHAL ECX operation");
14019 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3, "PUSHAL EDX operation");
14020 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4, "PUSHAL EBX operation");
14021 auto expr5 = this->symbolicEngine->createSymbolicExpression(inst, node5, dst5, "PUSHAL ESP operation");
14022 auto expr6 = this->symbolicEngine->createSymbolicExpression(inst, node6, dst6, "PUSHAL EBP operation");
14023 auto expr7 = this->symbolicEngine->createSymbolicExpression(inst, node7, dst7, "PUSHAL ESI operation");
14024 auto expr8 = this->symbolicEngine->createSymbolicExpression(inst, node8, dst8, "PUSHAL EDI operation");
14025
14026 /* Spread taint */
14027 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src1);
14028 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src2);
14029 expr3->isTainted = this->taintEngine->taintAssignment(dst3, src3);
14030 expr4->isTainted = this->taintEngine->taintAssignment(dst4, src4);
14031 expr5->isTainted = this->taintEngine->taintAssignment(dst5, src5);
14032 expr6->isTainted = this->taintEngine->taintAssignment(dst6, src6);
14033 expr7->isTainted = this->taintEngine->taintAssignment(dst7, src7);
14034 expr8->isTainted = this->taintEngine->taintAssignment(dst8, src8);
14035
14036 /* Update the symbolic control flow */
14037 this->controlFlow_s(inst);
14038 }
14039
14040
14041 void x86Semantics::pushfd_s(triton::arch::Instruction& inst) {
14042 auto stack = this->architecture->getStackPointer();
14043
14044 /* Create the semantics - side effect */
14045 auto stackValue = alignSubStack_s(inst, stack.getSize());
14046 auto dst = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize()));
14047 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
14048 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
14049 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF));
14050 auto src4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
14051 auto src5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
14052 auto src6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_TF));
14053 auto src7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_IF));
14054 auto src8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
14055 auto src9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
14056 auto src10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_NT));
14057 auto src11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AC));
14058 auto src12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_VIF));
14059 auto src13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_VIP));
14060 auto src14 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ID));
14061
14062 /* Create symbolic operands */
14063 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
14064 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
14065 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
14066 auto op4 = this->symbolicEngine->getOperandAst(inst, src4);
14067 auto op5 = this->symbolicEngine->getOperandAst(inst, src5);
14068 auto op6 = this->symbolicEngine->getOperandAst(inst, src6);
14069 auto op7 = this->symbolicEngine->getOperandAst(inst, src7);
14070 auto op8 = this->symbolicEngine->getOperandAst(inst, src8);
14071 auto op9 = this->symbolicEngine->getOperandAst(inst, src9);
14072 auto op10 = this->symbolicEngine->getOperandAst(inst, src10);
14073 auto op11 = this->symbolicEngine->getOperandAst(inst, src11);
14074 auto op12 = this->symbolicEngine->getOperandAst(inst, src12);
14075 auto op13 = this->symbolicEngine->getOperandAst(inst, src13);
14076 auto op14 = this->symbolicEngine->getOperandAst(inst, src14);
14077
14078 /* Create the semantics */
14079 std::vector<triton::ast::SharedAbstractNode> eflags;
14080 eflags.reserve(22);
14081
14082 eflags.push_back(op14);
14083 eflags.push_back(op13);
14084 eflags.push_back(op12);
14085 eflags.push_back(op11);
14086 eflags.push_back(this->astCtxt->bvfalse()); /* vm */
14087 eflags.push_back(this->astCtxt->bvfalse()); /* rf */
14088 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */
14089 eflags.push_back(op10);
14090 eflags.push_back(this->astCtxt->bvfalse()); /* iopl */
14091 eflags.push_back(this->astCtxt->bvfalse()); /* iopl */
14092 eflags.push_back(op9);
14093 eflags.push_back(op8);
14094 eflags.push_back(op7);
14095 eflags.push_back(op6);
14096 eflags.push_back(op5);
14097 eflags.push_back(op4);
14098 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */
14099 eflags.push_back(op3);
14100 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */
14101 eflags.push_back(op2);
14102 eflags.push_back(this->astCtxt->bvtrue()); /* Reserved */
14103 eflags.push_back(op1);
14104
14105 auto node = this->astCtxt->zx(
14106 dst.getBitSize() - static_cast<triton::uint32>(eflags.size()),
14107 this->astCtxt->concat(eflags)
14108 );
14109
14110 /* Create symbolic expression */
14111 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUSHFD operation");
14112
14113 /* Spread taint */
14114 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
14115 expr->isTainted = this->taintEngine->taintUnion(dst, src2);
14116 expr->isTainted = this->taintEngine->taintUnion(dst, src3);
14117 expr->isTainted = this->taintEngine->taintUnion(dst, src4);
14118 expr->isTainted = this->taintEngine->taintUnion(dst, src5);
14119 expr->isTainted = this->taintEngine->taintUnion(dst, src6);
14120 expr->isTainted = this->taintEngine->taintUnion(dst, src7);
14121 expr->isTainted = this->taintEngine->taintUnion(dst, src8);
14122 expr->isTainted = this->taintEngine->taintUnion(dst, src9);
14123 expr->isTainted = this->taintEngine->taintUnion(dst, src10);
14124 expr->isTainted = this->taintEngine->taintUnion(dst, src11);
14125 expr->isTainted = this->taintEngine->taintUnion(dst, src12);
14126 expr->isTainted = this->taintEngine->taintUnion(dst, src13);
14127 expr->isTainted = this->taintEngine->taintUnion(dst, src14);
14128
14129 /* Update the symbolic control flow */
14130 this->controlFlow_s(inst);
14131 }
14132
14133
14134 void x86Semantics::pushfq_s(triton::arch::Instruction& inst) {
14135 auto stack = this->architecture->getStackPointer();
14136
14137 /* Create the semantics - side effect */
14138 auto stackValue = alignSubStack_s(inst, stack.getSize());
14139 auto dst = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize()));
14140 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
14141 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
14142 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF));
14143 auto src4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
14144 auto src5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
14145 auto src6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_TF));
14146 auto src7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_IF));
14147 auto src8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
14148 auto src9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
14149 auto src10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_NT));
14150 auto src11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AC));
14151 auto src12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_VIF));
14152 auto src13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_VIP));
14153 auto src14 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ID));
14154
14155 /* Create symbolic operands */
14156 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
14157 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
14158 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
14159 auto op4 = this->symbolicEngine->getOperandAst(inst, src4);
14160 auto op5 = this->symbolicEngine->getOperandAst(inst, src5);
14161 auto op6 = this->symbolicEngine->getOperandAst(inst, src6);
14162 auto op7 = this->symbolicEngine->getOperandAst(inst, src7);
14163 auto op8 = this->symbolicEngine->getOperandAst(inst, src8);
14164 auto op9 = this->symbolicEngine->getOperandAst(inst, src9);
14165 auto op10 = this->symbolicEngine->getOperandAst(inst, src10);
14166 auto op11 = this->symbolicEngine->getOperandAst(inst, src11);
14167 auto op12 = this->symbolicEngine->getOperandAst(inst, src12);
14168 auto op13 = this->symbolicEngine->getOperandAst(inst, src13);
14169 auto op14 = this->symbolicEngine->getOperandAst(inst, src14);
14170
14171 /* Create the semantics */
14172 std::vector<triton::ast::SharedAbstractNode> eflags;
14173 eflags.reserve(22);
14174
14175 eflags.push_back(op14);
14176 eflags.push_back(op13);
14177 eflags.push_back(op12);
14178 eflags.push_back(op11);
14179 eflags.push_back(this->astCtxt->bvfalse()); /* vm */
14180 eflags.push_back(this->astCtxt->bvfalse()); /* rf */
14181 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */
14182 eflags.push_back(op10);
14183 eflags.push_back(this->astCtxt->bvfalse()); /* iopl */
14184 eflags.push_back(this->astCtxt->bvfalse()); /* iopl */
14185 eflags.push_back(op9);
14186 eflags.push_back(op8);
14187 eflags.push_back(op7);
14188 eflags.push_back(op6);
14189 eflags.push_back(op5);
14190 eflags.push_back(op4);
14191 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */
14192 eflags.push_back(op3);
14193 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */
14194 eflags.push_back(op2);
14195 eflags.push_back(this->astCtxt->bvtrue()); /* Reserved */
14196 eflags.push_back(op1);
14197
14198 auto node = this->astCtxt->zx(
14199 dst.getBitSize() - static_cast<triton::uint32>(eflags.size()),
14200 this->astCtxt->concat(eflags)
14201 );
14202
14203 /* Create symbolic expression */
14204 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUSHFQ operation");
14205
14206 /* Spread taint */
14207 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
14208 expr->isTainted = this->taintEngine->taintUnion(dst, src2);
14209 expr->isTainted = this->taintEngine->taintUnion(dst, src3);
14210 expr->isTainted = this->taintEngine->taintUnion(dst, src4);
14211 expr->isTainted = this->taintEngine->taintUnion(dst, src5);
14212 expr->isTainted = this->taintEngine->taintUnion(dst, src6);
14213 expr->isTainted = this->taintEngine->taintUnion(dst, src7);
14214 expr->isTainted = this->taintEngine->taintUnion(dst, src8);
14215 expr->isTainted = this->taintEngine->taintUnion(dst, src9);
14216 expr->isTainted = this->taintEngine->taintUnion(dst, src10);
14217 expr->isTainted = this->taintEngine->taintUnion(dst, src11);
14218 expr->isTainted = this->taintEngine->taintUnion(dst, src12);
14219 expr->isTainted = this->taintEngine->taintUnion(dst, src13);
14220 expr->isTainted = this->taintEngine->taintUnion(dst, src14);
14221
14222 /* Update the symbolic control flow */
14223 this->controlFlow_s(inst);
14224 }
14225
14226
14227 void x86Semantics::pxor_s(triton::arch::Instruction& inst) {
14228 auto& dst = inst.operands[0];
14229 auto& src = inst.operands[1];
14230
14231 /* Create symbolic operands */
14232 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14233 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14234
14235 /* Create the semantics */
14236 auto node = this->astCtxt->bvxor(op1, op2);
14237
14238 /* Create symbolic expression */
14239 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PXOR operation");
14240
14241 /* Update the x87 FPU Tag Word */
14242 this->updateFTW(inst, expr);
14243
14244 /* Spread taint */
14245 if (dst.getType() == OP_REG && src.getRegister() == dst.getRegister())
14246 this->taintEngine->setTaint(src, false);
14247 else
14248 expr->isTainted = this->taintEngine->taintUnion(dst, src);
14249
14250 /* Update the symbolic control flow */
14251 this->controlFlow_s(inst);
14252 }
14253
14254
14255 void x86Semantics::rcl_s(triton::arch::Instruction& inst) {
14256 auto& dst = inst.operands[0];
14257 auto& src = inst.operands[1];
14258 auto srcCf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
14259
14260 /* Create symbolic operands */
14261 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14262 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14263 auto op2bis = this->symbolicEngine->getOperandAst(src);
14264 auto op3 = this->symbolicEngine->getOperandAst(inst, srcCf);
14265
14266 switch (dst.getBitSize()) {
14267 /* Mask: 0x1f without MOD */
14269 op2 = this->astCtxt->bvand(
14270 op2,
14271 this->astCtxt->bv(triton::bitsize::qword-1, src.getBitSize())
14272 );
14273 break;
14274
14275 /* Mask: 0x1f without MOD */
14277 op2 = this->astCtxt->bvand(
14278 op2,
14279 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())
14280 );
14281 break;
14282
14283 /* Mask: 0x1f MOD size + 1 */
14286 op2 = this->astCtxt->bvsmod(
14287 this->astCtxt->bvand(
14288 op2,
14289 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())),
14290 this->astCtxt->bv(dst.getBitSize()+1, src.getBitSize())
14291 );
14292 break;
14293
14294 default:
14295 throw triton::exceptions::Semantics("x86Semantics::rcl_s(): Invalid destination size");
14296 }
14297
14298 /* Create the semantics */
14299 auto node1 = this->astCtxt->bvrol(
14300 this->astCtxt->concat(op3, op1),
14301 this->astCtxt->zx(((op1->getBitvectorSize() + op3->getBitvectorSize()) - op2->getBitvectorSize()), op2)
14302 );
14303
14304 /* Create symbolic expression */
14305 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "RCL tempory operation");
14306
14307 /* Spread taint */
14308 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
14309
14310 /* Create the semantics */
14311 auto node2 = this->astCtxt->extract(dst.getBitSize()-1, 0, node1);
14312
14313 /* Create symbolic expression */
14314 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "RCL operation");
14315
14316 /* Spread taint */
14317 expr2->isTainted = this->taintEngine->taintUnion(dst, src);
14318 expr2->isTainted = this->taintEngine->taintUnion(dst, srcCf);
14319
14320 /* Update symbolic flags */
14321 this->cfRcl_s(inst, expr2, node1, op2bis);
14322 this->ofRol_s(inst, expr2, dst, op2bis); /* Same as ROL */
14323
14324 /* Tag undefined flags */
14325 if (op2->evaluate() > 1) {
14326 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
14327 }
14328
14329 /* Update the symbolic control flow */
14330 this->controlFlow_s(inst);
14331 }
14332
14333
14334 void x86Semantics::rcr_s(triton::arch::Instruction& inst) {
14335 auto& dst = inst.operands[0];
14336 auto& src = inst.operands[1];
14337 auto srcCf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
14338
14339 /* Create symbolic operands */
14340 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14341 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14342 auto op3 = this->symbolicEngine->getOperandAst(inst, srcCf);
14343
14344 switch (dst.getBitSize()) {
14345 /* Mask: 0x3f without MOD */
14347 op2 = this->astCtxt->bvand(
14348 op2,
14349 this->astCtxt->bv(triton::bitsize::qword-1, src.getBitSize())
14350 );
14351 break;
14352
14353 /* Mask: 0x1f without MOD */
14355 op2 = this->astCtxt->bvand(
14356 op2,
14357 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())
14358 );
14359 break;
14360
14361 /* Mask: 0x1f MOD size + 1 */
14364 op2 = this->astCtxt->bvsmod(
14365 this->astCtxt->bvand(
14366 op2,
14367 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())),
14368 this->astCtxt->bv(dst.getBitSize()+1, src.getBitSize())
14369 );
14370 break;
14371
14372 default:
14373 throw triton::exceptions::Semantics("x86Semantics::rcr_s(): Invalid destination size");
14374 }
14375
14376 /* Create the semantics */
14377 auto node1 = this->astCtxt->bvror(
14378 this->astCtxt->concat(op3, op1),
14379 this->astCtxt->zx(((op1->getBitvectorSize() + op3->getBitvectorSize()) - op2->getBitvectorSize()), op2)
14380 );
14381
14382 /* Create symbolic expression */
14383 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "RCR tempory operation");
14384
14385 /* Spread taint */
14386 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
14387
14388 /* Create the semantics */
14389 auto node2 = this->astCtxt->extract(dst.getBitSize()-1, 0, node1);
14390
14391 /* Create symbolic expression */
14392 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "RCR operation");
14393
14394 /* Spread taint */
14395 expr2->isTainted = this->taintEngine->taintUnion(dst, src);
14396 expr2->isTainted = this->taintEngine->taintUnion(dst, srcCf);
14397
14398 /* Update symbolic flags */
14399 this->ofRcr_s(inst, expr2, dst, op1, op2); /* OF must be set before CF */
14400 this->cfRcr_s(inst, expr2, dst, node1, op2);
14401
14402 /* Tag undefined flags */
14403 if (op2->evaluate() > 1) {
14404 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
14405 }
14406
14407 /* Update the symbolic control flow */
14408 this->controlFlow_s(inst);
14409 }
14410
14411
14412 void x86Semantics::rdtsc_s(triton::arch::Instruction& inst) {
14413 auto src = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_TSC));
14414 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
14415 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
14416
14417 /* Create symbolic operands */
14418 auto op = this->symbolicEngine->getOperandAst(inst, src);
14419 auto high = this->astCtxt->extract((triton::bitsize::qword - 1), triton::bitsize::dword, op);
14420 auto low = this->astCtxt->extract((triton::bitsize::dword - 1), 0, op);
14421
14422 /* Create symbolic expression */
14423 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, high, dst1, "RDTSC EDX operation");
14424 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, low, dst2, "RDTSC EAX operation");
14425
14426 /* Spread taint */
14427 expr1->isTainted = this->taintEngine->taintUnion(dst1, src);
14428 expr2->isTainted = this->taintEngine->taintUnion(dst2, src);
14429
14430 /* Update the symbolic control flow */
14431 this->controlFlow_s(inst);
14432 }
14433
14434
14435 void x86Semantics::ret_s(triton::arch::Instruction& inst) {
14436 auto stack = this->architecture->getStackPointer();
14437 auto stackValue = static_cast<triton::uint64>(this->architecture->getConcreteRegisterValue(stack));
14438 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
14439 auto sp = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize()));
14440
14441 /* Create symbolic operands */
14442 auto op1 = this->symbolicEngine->getOperandAst(inst, sp);
14443
14444 /* Create the semantics */
14445 auto node = op1;
14446
14447 /* Create symbolic expression */
14448 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
14449
14450 /* Spread taint */
14451 expr->isTainted = this->taintEngine->taintAssignment(pc, sp);
14452
14453 /* Create the semantics - side effect */
14454 alignAddStack_s(inst, sp.getSize());
14455
14456 /* Create the semantics - side effect */
14457 if (inst.operands.size() > 0) {
14458 auto offset = inst.operands[0].getImmediate();
14459 this->symbolicEngine->getImmediateAst(inst, offset);
14460 alignAddStack_s(inst, static_cast<triton::uint32>(offset.getValue()));
14461 }
14462
14463 /* Create the path constraint */
14464 this->symbolicEngine->pushPathConstraint(inst, expr);
14465 }
14466
14467
14468 void x86Semantics::rol_s(triton::arch::Instruction& inst) {
14469 auto& dst = inst.operands[0];
14470 auto& src = inst.operands[1];
14471
14472 /* Create symbolic operands */
14473 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14474 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14475 auto op2bis = this->symbolicEngine->getOperandAst(src);
14476
14477 switch (dst.getBitSize()) {
14478 /* Mask 0x3f MOD size */
14480 op2 = this->astCtxt->bvsmod(
14481 this->astCtxt->bvand(
14482 op2,
14483 this->astCtxt->bv(triton::bitsize::qword-1, src.getBitSize())),
14484 this->astCtxt->bv(dst.getBitSize(), src.getBitSize())
14485 );
14486
14487 op2bis = this->astCtxt->bvand(
14488 op2bis,
14489 this->astCtxt->bv(triton::bitsize::qword-1, src.getBitSize())
14490 );
14491 break;
14492
14493 /* Mask 0x1f MOD size */
14497 op2 = this->astCtxt->bvsmod(
14498 this->astCtxt->bvand(
14499 op2,
14500 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())),
14501 this->astCtxt->bv(dst.getBitSize(), src.getBitSize())
14502 );
14503
14504 op2bis = this->astCtxt->bvand(
14505 op2bis,
14506 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())
14507 );
14508 break;
14509
14510 default:
14511 throw triton::exceptions::Semantics("x86Semantics::rol_s(): Invalid destination size");
14512 }
14513
14514 /* Create the semantics */
14515 auto node = this->astCtxt->bvrol(
14516 op1,
14517 this->astCtxt->zx(op1->getBitvectorSize() - op2->getBitvectorSize(), op2)
14518 );
14519
14520 /* Create symbolic expression */
14521 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ROL operation");
14522
14523 /* Spread taint */
14524 expr->isTainted = this->taintEngine->taintUnion(dst, src);
14525
14526 /* Update symbolic flags */
14527 this->cfRol_s(inst, expr, dst, op2bis);
14528 this->ofRol_s(inst, expr, dst, op2bis);
14529
14530 /* Tag undefined flags */
14531 if (op2->evaluate() > 1) {
14532 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
14533 }
14534
14535 /* Update the symbolic control flow */
14536 this->controlFlow_s(inst);
14537 }
14538
14539
14540 void x86Semantics::ror_s(triton::arch::Instruction& inst) {
14541 auto& dst = inst.operands[0];
14542 auto& src = inst.operands[1];
14543
14544 /* Create symbolic operands */
14545 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14546 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14547 auto op2bis = this->symbolicEngine->getOperandAst(src);
14548
14549 switch (dst.getBitSize()) {
14550 /* Mask 0x3f MOD size */
14552 op2 = this->astCtxt->bvsmod(
14553 this->astCtxt->bvand(
14554 op2,
14555 this->astCtxt->bv(triton::bitsize::qword-1, src.getBitSize())),
14556 this->astCtxt->bv(dst.getBitSize(), src.getBitSize())
14557 );
14558
14559 op2bis = this->astCtxt->bvand(
14560 op2bis,
14561 this->astCtxt->bv(triton::bitsize::qword-1, src.getBitSize())
14562 );
14563 break;
14564
14565 /* Mask 0x1f MOD size */
14569 op2 = this->astCtxt->bvsmod(
14570 this->astCtxt->bvand(
14571 op2,
14572 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())),
14573 this->astCtxt->bv(dst.getBitSize(), src.getBitSize())
14574 );
14575
14576 op2bis = this->astCtxt->bvand(
14577 op2bis,
14578 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())
14579 );
14580 break;
14581
14582 default:
14583 throw triton::exceptions::Semantics("x86Semantics::ror_s(): Invalid destination size");
14584 }
14585
14586 /* Create the semantics */
14587 auto node = this->astCtxt->bvror(
14588 op1,
14589 this->astCtxt->zx(op1->getBitvectorSize() - op2->getBitvectorSize(), op2)
14590 );
14591
14592 /* Create symbolic expression */
14593 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ROR operation");
14594
14595 /* Spread taint */
14596 expr->isTainted = this->taintEngine->taintUnion(dst, src);
14597
14598 /* Update symbolic flags */
14599 this->cfRor_s(inst, expr, dst, op2);
14600 this->ofRor_s(inst, expr, dst, op2bis);
14601
14602 /* Tag undefined flags */
14603 if (op2->evaluate() > 1) {
14604 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
14605 }
14606
14607 /* Update the symbolic control flow */
14608 this->controlFlow_s(inst);
14609 }
14610
14611
14612 void x86Semantics::rorx_s(triton::arch::Instruction& inst) {
14613 auto& dst = inst.operands[0];
14614 auto& src1 = inst.operands[1];
14615 auto& src2 = inst.operands[2];
14616
14617 /* Create symbolic operands */
14618 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
14619 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
14620
14621 switch (dst.getBitSize()) {
14622 /* Mask 0x3f MOD size */
14624 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, src2.getBitSize()));
14625 break;
14626
14627 /* Mask 0x1f MOD size */
14629 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, src2.getBitSize()));
14630 break;
14631
14632 default:
14633 throw triton::exceptions::Semantics("x86Semantics::rorx_s(): Invalid destination size");
14634 }
14635
14636 /* Create the semantics */
14637 auto node = this->astCtxt->bvror(
14638 op1,
14639 this->astCtxt->zx(op1->getBitvectorSize() - op2->getBitvectorSize(), op2)
14640 );
14641
14642 /* Create symbolic expression */
14643 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "RORX operation");
14644
14645 /* Spread taint */
14646 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
14647 expr->isTainted |= this->taintEngine->taintUnion(dst, src2);
14648
14649 /* Update the symbolic control flow */
14650 this->controlFlow_s(inst);
14651 }
14652
14653
14654 void x86Semantics::sahf_s(triton::arch::Instruction& inst) {
14655 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
14656 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
14657 auto dst3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF));
14658 auto dst4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
14659 auto dst5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
14660 auto src = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AH));
14661
14662 /* Create symbolic operands */
14663 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
14664
14665 /* Create the semantics */
14666 auto node1 = this->astCtxt->extract(7, 7, op1);
14667 auto node2 = this->astCtxt->extract(6, 6, op1);
14668 auto node3 = this->astCtxt->extract(4, 4, op1);
14669 auto node4 = this->astCtxt->extract(2, 2, op1);
14670 auto node5 = this->astCtxt->extract(0, 0, op1);
14671
14672 /* Create symbolic expression */
14673 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1.getRegister(), "SAHF SF operation");
14674 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2.getRegister(), "SAHF ZF operation");
14675 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3.getRegister(), "SAHF AF operation");
14676 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4.getRegister(), "SAHF PF operation");
14677 auto expr5 = this->symbolicEngine->createSymbolicExpression(inst, node5, dst5.getRegister(), "SAHF CF operation");
14678
14679 /* Spread taint */
14680 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src);
14681 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src);
14682 expr3->isTainted = this->taintEngine->taintAssignment(dst3, src);
14683 expr4->isTainted = this->taintEngine->taintAssignment(dst4, src);
14684 expr5->isTainted = this->taintEngine->taintAssignment(dst5, src);
14685
14686 /* Update the symbolic control flow */
14687 this->controlFlow_s(inst);
14688 }
14689
14690
14691 void x86Semantics::sar_s(triton::arch::Instruction& inst) {
14692 auto& dst = inst.operands[0];
14693 auto& src = inst.operands[1];
14694
14695 /* Create symbolic operands */
14696 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14697 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
14698
14700 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, dst.getBitSize()));
14701 else
14702 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, dst.getBitSize()));
14703
14704 /* Create the semantics */
14705 auto node = this->astCtxt->bvashr(op1, op2);
14706
14707 /* Create symbolic expression */
14708 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SAR operation");
14709
14710 /* Spread taint */
14711 expr->isTainted = this->taintEngine->taintUnion(dst, src);
14712
14713 /* Update symbolic flags */
14714 this->cfSar_s(inst, expr, dst, op1, op2);
14715 this->ofSar_s(inst, expr, dst, op2);
14716 this->pfShl_s(inst, expr, dst, op2); /* Same that shl */
14717 this->sfShl_s(inst, expr, dst, op2); /* Same that shl */
14718 this->zfShl_s(inst, expr, dst, op2); /* Same that shl */
14719
14720 /* Tag undefined flags */
14721 if (op2->evaluate() != 0) {
14722 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
14723 }
14724
14725 if (op2->evaluate() > 1) {
14726 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
14727 }
14728
14729 /* Update the symbolic control flow */
14730 this->controlFlow_s(inst);
14731 }
14732
14733
14734 void x86Semantics::sarx_s(triton::arch::Instruction& inst) {
14735 auto& dst = inst.operands[0];
14736 auto& src1 = inst.operands[1];
14737 auto& src2 = inst.operands[2];
14738
14739 /* Create symbolic operands */
14740 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
14741 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
14742
14743 switch (dst.getBitSize()) {
14744 /* Mask 0x3f MOD size */
14746 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, src2.getBitSize()));
14747 break;
14748
14749 /* Mask 0x1f MOD size */
14751 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, src2.getBitSize()));
14752 break;
14753
14754 default:
14755 throw triton::exceptions::Semantics("x86Semantics::sarx_s(): Invalid destination size");
14756 }
14757
14758 /* Create the semantics */
14759 auto node = this->astCtxt->bvashr(op1, op2);
14760
14761 /* Create symbolic expression */
14762 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SARX operation");
14763
14764 /* Spread taint */
14765 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
14766 expr->isTainted |= this->taintEngine->taintUnion(dst, src2);
14767
14768 /* Update the symbolic control flow */
14769 this->controlFlow_s(inst);
14770 }
14771
14772
14773 void x86Semantics::sbb_s(triton::arch::Instruction& inst) {
14774 auto& dst = inst.operands[0];
14775 auto& src = inst.operands[1];
14776 auto srcCf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
14777
14778 /* Create symbolic operands */
14779 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14780 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14781 auto op3 = this->astCtxt->zx(src.getBitSize()-1, this->symbolicEngine->getOperandAst(inst, srcCf));
14782
14783 /* Create the semantics */
14784 auto node = this->astCtxt->bvsub(op1, this->astCtxt->bvadd(op2, op3));
14785
14786 /* Create symbolic expression */
14787 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SBB operation");
14788
14789 /* Spread taint */
14790 expr->isTainted = this->taintEngine->taintUnion(dst, src);
14791 expr->isTainted = this->taintEngine->taintUnion(dst, srcCf);
14792
14793 /* Update symbolic flags */
14794 this->af_s(inst, expr, dst, op1, op2);
14795 this->cfSub_s(inst, expr, dst, op1, op2);
14796 this->ofSub_s(inst, expr, dst, op1, op2);
14797 this->pf_s(inst, expr, dst);
14798 this->sf_s(inst, expr, dst);
14799 this->zf_s(inst, expr, dst);
14800
14801 /* Update the symbolic control flow */
14802 this->controlFlow_s(inst);
14803 }
14804
14805
14806 void x86Semantics::scasb_s(triton::arch::Instruction& inst) {
14807 auto& dst = inst.operands[0];
14808 auto& src = inst.operands[1];
14809 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
14810 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
14811 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
14812
14813 /* If the REP prefix is defined, convert REP into REPE */
14816
14817 /* Check if there is a REP prefix and a counter to zero */
14818 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
14819 this->controlFlow_s(inst);
14820 return;
14821 }
14822
14823 /* Create symbolic operands */
14824 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14825 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14826 auto op3 = this->symbolicEngine->getOperandAst(inst, index);
14827 auto op4 = this->symbolicEngine->getOperandAst(inst, df);
14828
14829 /* Create the semantics */
14830 auto node1 = this->astCtxt->bvsub(op1, op2);
14831 auto node2 = this->astCtxt->ite(
14832 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
14833 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::byte, index.getBitSize())),
14834 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::byte, index.getBitSize()))
14835 );
14836
14837 /* Create symbolic expression */
14838 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "SCASB operation");
14839 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
14840
14841 /* Spread taint */
14842 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
14843 expr2->isTainted = this->taintEngine->taintUnion(index, index);
14844
14845 /* Update symbolic flags */
14846 this->af_s(inst, expr1, dst, op1, op2, true);
14847 this->cfSub_s(inst, expr1, dst, op1, op2, true);
14848 this->ofSub_s(inst, expr1, dst, op1, op2, true);
14849 this->pf_s(inst, expr1, dst, true);
14850 this->sf_s(inst, expr1, dst, true);
14851 this->zf_s(inst, expr1, dst, true);
14852
14853 /* Update the symbolic control flow */
14854 this->controlFlow_s(inst);
14855 }
14856
14857
14858 void x86Semantics::scasd_s(triton::arch::Instruction& inst) {
14859 auto& dst = inst.operands[0];
14860 auto& src = inst.operands[1];
14861 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
14862 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
14863 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
14864
14865 /* If the REP prefix is defined, convert REP into REPE */
14868
14869 /* Check if there is a REP prefix and a counter to zero */
14870 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
14871 this->controlFlow_s(inst);
14872 return;
14873 }
14874
14875 /* Create symbolic operands */
14876 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14877 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14878 auto op3 = this->symbolicEngine->getOperandAst(inst, index);
14879 auto op4 = this->symbolicEngine->getOperandAst(inst, df);
14880
14881 /* Create the semantics */
14882 auto node1 = this->astCtxt->bvsub(op1, op2);
14883 auto node2 = this->astCtxt->ite(
14884 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
14885 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::dword, index.getBitSize())),
14886 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::dword, index.getBitSize()))
14887 );
14888
14889 /* Create symbolic expression */
14890 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "SCASD operation");
14891 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
14892
14893 /* Spread taint */
14894 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
14895 expr2->isTainted = this->taintEngine->taintUnion(index, index);
14896
14897 /* Update symbolic flags */
14898 this->af_s(inst, expr1, dst, op1, op2, true);
14899 this->cfSub_s(inst, expr1, dst, op1, op2, true);
14900 this->ofSub_s(inst, expr1, dst, op1, op2, true);
14901 this->pf_s(inst, expr1, dst, true);
14902 this->sf_s(inst, expr1, dst, true);
14903 this->zf_s(inst, expr1, dst, true);
14904
14905 /* Update the symbolic control flow */
14906 this->controlFlow_s(inst);
14907 }
14908
14909
14910 void x86Semantics::scasq_s(triton::arch::Instruction& inst) {
14911 auto& dst = inst.operands[0];
14912 auto& src = inst.operands[1];
14913 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
14914 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
14915 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
14916
14917 /* If the REP prefix is defined, convert REP into REPE */
14920
14921 /* Check if there is a REP prefix and a counter to zero */
14922 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
14923 this->controlFlow_s(inst);
14924 return;
14925 }
14926
14927 /* Create symbolic operands */
14928 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14929 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14930 auto op3 = this->symbolicEngine->getOperandAst(inst, index);
14931 auto op4 = this->symbolicEngine->getOperandAst(inst, df);
14932
14933 /* Create the semantics */
14934 auto node1 = this->astCtxt->bvsub(op1, op2);
14935 auto node2 = this->astCtxt->ite(
14936 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
14937 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::qword, index.getBitSize())),
14938 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::qword, index.getBitSize()))
14939 );
14940
14941 /* Create symbolic expression */
14942 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "SCASQ operation");
14943 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
14944
14945 /* Spread taint */
14946 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
14947 expr2->isTainted = this->taintEngine->taintUnion(index, index);
14948
14949 /* Update symbolic flags */
14950 this->af_s(inst, expr1, dst, op1, op2, true);
14951 this->cfSub_s(inst, expr1, dst, op1, op2, true);
14952 this->ofSub_s(inst, expr1, dst, op1, op2, true);
14953 this->pf_s(inst, expr1, dst, true);
14954 this->sf_s(inst, expr1, dst, true);
14955 this->zf_s(inst, expr1, dst, true);
14956
14957 /* Update the symbolic control flow */
14958 this->controlFlow_s(inst);
14959 }
14960
14961
14962 void x86Semantics::scasw_s(triton::arch::Instruction& inst) {
14963 auto& dst = inst.operands[0];
14964 auto& src = inst.operands[1];
14965 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
14966 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
14967 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
14968
14969 /* If the REP prefix is defined, convert REP into REPE */
14972
14973 /* Check if there is a REP prefix and a counter to zero */
14974 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
14975 this->controlFlow_s(inst);
14976 return;
14977 }
14978
14979 /* Create symbolic operands */
14980 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14981 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14982 auto op3 = this->symbolicEngine->getOperandAst(inst, index);
14983 auto op4 = this->symbolicEngine->getOperandAst(inst, df);
14984
14985 /* Create the semantics */
14986 auto node1 = this->astCtxt->bvsub(op1, op2);
14987 auto node2 = this->astCtxt->ite(
14988 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
14989 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::word, index.getBitSize())),
14990 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::word, index.getBitSize()))
14991 );
14992
14993 /* Create symbolic expression */
14994 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "SCASW operation");
14995 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
14996
14997 /* Spread taint */
14998 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
14999 expr2->isTainted = this->taintEngine->taintUnion(index, index);
15000
15001 /* Update symbolic flags */
15002 this->af_s(inst, expr1, dst, op1, op2, true);
15003 this->cfSub_s(inst, expr1, dst, op1, op2, true);
15004 this->ofSub_s(inst, expr1, dst, op1, op2, true);
15005 this->pf_s(inst, expr1, dst, true);
15006 this->sf_s(inst, expr1, dst, true);
15007 this->zf_s(inst, expr1, dst, true);
15008
15009 /* Update the symbolic control flow */
15010 this->controlFlow_s(inst);
15011 }
15012
15013
15014 void x86Semantics::seta_s(triton::arch::Instruction& inst) {
15015 auto& dst = inst.operands[0];
15016 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
15017 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
15018
15019 /* Create symbolic operands */
15020 auto op2 = this->symbolicEngine->getOperandAst(inst, cf);
15021 auto op3 = this->symbolicEngine->getOperandAst(inst, zf);
15022
15023 /* Create the semantics */
15024 auto node = this->astCtxt->ite(
15025 this->astCtxt->equal(
15026 this->astCtxt->bvand(
15027 this->astCtxt->bvnot(op2),
15028 this->astCtxt->bvnot(op3)
15029 ),
15030 this->astCtxt->bvtrue()
15031 ),
15032 this->astCtxt->bv(1, dst.getBitSize()),
15033 this->astCtxt->bv(0, dst.getBitSize())
15034 );
15035
15036 /* Create symbolic expression */
15037 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETA operation");
15038
15039 /* Set condition flag */
15040 if (op2->evaluate().is_zero() && op3->evaluate().is_zero()) {
15041 inst.setConditionTaken(true);
15042 }
15043
15044 /* Spread taint */
15045 expr->isTainted = this->taintEngine->taintAssignment(dst, cf);
15046 expr->isTainted = this->taintEngine->taintUnion(dst, zf);
15047
15048 /* Update the symbolic control flow */
15049 this->controlFlow_s(inst);
15050 }
15051
15052
15053 void x86Semantics::setae_s(triton::arch::Instruction& inst) {
15054 auto& dst = inst.operands[0];
15055 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
15056
15057 /* Create symbolic operands */
15058 auto op2 = this->symbolicEngine->getOperandAst(inst, cf);
15059
15060 /* Create the semantics */
15061 auto node = this->astCtxt->ite(
15062 this->astCtxt->equal(op2, this->astCtxt->bvfalse()),
15063 this->astCtxt->bv(1, dst.getBitSize()),
15064 this->astCtxt->bv(0, dst.getBitSize())
15065 );
15066
15067 /* Create symbolic expression */
15068 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETAE operation");
15069
15070 /* Set condition flag */
15071 if (op2->evaluate().is_zero()) {
15072 inst.setConditionTaken(true);
15073 }
15074
15075 /* Spread taint */
15076 expr->isTainted = this->taintEngine->taintAssignment(dst, cf);
15077
15078 /* Update the symbolic control flow */
15079 this->controlFlow_s(inst);
15080 }
15081
15082
15083 void x86Semantics::setb_s(triton::arch::Instruction& inst) {
15084 auto& dst = inst.operands[0];
15085 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
15086
15087 /* Create symbolic operands */
15088 auto op2 = this->symbolicEngine->getOperandAst(inst, cf);
15089
15090 /* Create the semantics */
15091 auto node = this->astCtxt->ite(
15092 this->astCtxt->equal(op2, this->astCtxt->bvtrue()),
15093 this->astCtxt->bv(1, dst.getBitSize()),
15094 this->astCtxt->bv(0, dst.getBitSize())
15095 );
15096
15097 /* Create symbolic expression */
15098 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETB operation");
15099
15100 /* Set condition flag */
15101 if (!op2->evaluate().is_zero()) {
15102 inst.setConditionTaken(true);
15103 }
15104
15105 /* Spread taint */
15106 expr->isTainted = this->taintEngine->taintAssignment(dst, cf);
15107
15108 /* Update the symbolic control flow */
15109 this->controlFlow_s(inst);
15110 }
15111
15112
15113 void x86Semantics::setbe_s(triton::arch::Instruction& inst) {
15114 auto& dst = inst.operands[0];
15115 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
15116 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
15117
15118 /* Create symbolic operands */
15119 auto op2 = this->symbolicEngine->getOperandAst(inst, cf);
15120 auto op3 = this->symbolicEngine->getOperandAst(inst, zf);
15121
15122 /* Create the semantics */
15123 auto node = this->astCtxt->ite(
15124 this->astCtxt->equal(this->astCtxt->bvor(op2, op3), this->astCtxt->bvtrue()),
15125 this->astCtxt->bv(1, dst.getBitSize()),
15126 this->astCtxt->bv(0, dst.getBitSize())
15127 );
15128
15129 /* Create symbolic expression */
15130 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETBE operation");
15131
15132 /* Set condition flag */
15133 if (!op2->evaluate().is_zero() || !op3->evaluate().is_zero()) {
15134 inst.setConditionTaken(true);
15135 }
15136
15137 /* Spread taint */
15138 expr->isTainted = this->taintEngine->taintAssignment(dst, cf);
15139 expr->isTainted = this->taintEngine->taintUnion(dst, zf);
15140
15141 /* Update the symbolic control flow */
15142 this->controlFlow_s(inst);
15143 }
15144
15145
15146 void x86Semantics::sete_s(triton::arch::Instruction& inst) {
15147 auto& dst = inst.operands[0];
15148 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
15149
15150 /* Create symbolic operands */
15151 auto op2 = this->symbolicEngine->getOperandAst(inst, zf);
15152
15153 /* Create the semantics */
15154 auto node = this->astCtxt->ite(
15155 this->astCtxt->equal(op2, this->astCtxt->bvtrue()),
15156 this->astCtxt->bv(1, dst.getBitSize()),
15157 this->astCtxt->bv(0, dst.getBitSize())
15158 );
15159
15160 /* Create symbolic expression */
15161 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETE operation");
15162
15163 /* Set condition flag */
15164 if (!op2->evaluate().is_zero()) {
15165 inst.setConditionTaken(true);
15166 }
15167
15168 /* Spread taint */
15169 expr->isTainted = this->taintEngine->taintAssignment(dst, zf);
15170
15171 /* Update the symbolic control flow */
15172 this->controlFlow_s(inst);
15173 }
15174
15175
15176 void x86Semantics::setg_s(triton::arch::Instruction& inst) {
15177 auto& dst = inst.operands[0];
15178 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
15179 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
15180 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
15181
15182 /* Create symbolic operands */
15183 auto op2 = this->symbolicEngine->getOperandAst(inst, sf);
15184 auto op3 = this->symbolicEngine->getOperandAst(inst, of);
15185 auto op4 = this->symbolicEngine->getOperandAst(inst, zf);
15186
15187 /* Create the semantics */
15188 auto node = this->astCtxt->ite(
15189 this->astCtxt->equal(this->astCtxt->bvor(this->astCtxt->bvxor(op2, op3), op4), this->astCtxt->bvfalse()),
15190 this->astCtxt->bv(1, dst.getBitSize()),
15191 this->astCtxt->bv(0, dst.getBitSize())
15192 );
15193
15194 /* Create symbolic expression */
15195 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETG operation");
15196
15197 /* Set condition flag */
15198 if ((op2->evaluate().is_zero() == op3->evaluate().is_zero()) && op4->evaluate().is_zero()) {
15199 inst.setConditionTaken(true);
15200 }
15201
15202 /* Spread taint */
15203 expr->isTainted = this->taintEngine->taintAssignment(dst, sf);
15204 expr->isTainted = this->taintEngine->taintUnion(dst, of);
15205 expr->isTainted = this->taintEngine->taintUnion(dst, zf);
15206
15207 /* Update the symbolic control flow */
15208 this->controlFlow_s(inst);
15209 }
15210
15211
15212 void x86Semantics::setge_s(triton::arch::Instruction& inst) {
15213 auto& dst = inst.operands[0];
15214 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
15215 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
15216
15217 /* Create symbolic operands */
15218 auto op2 = this->symbolicEngine->getOperandAst(inst, sf);
15219 auto op3 = this->symbolicEngine->getOperandAst(inst, of);
15220
15221 /* Create the semantics */
15222 auto node = this->astCtxt->ite(
15223 this->astCtxt->equal(op2, op3),
15224 this->astCtxt->bv(1, dst.getBitSize()),
15225 this->astCtxt->bv(0, dst.getBitSize())
15226 );
15227
15228 /* Create symbolic expression */
15229 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETGE operation");
15230
15231 /* Set condition flag */
15232 if (op2->evaluate().is_zero() == op3->evaluate().is_zero()) {
15233 inst.setConditionTaken(true);
15234 }
15235
15236 /* Spread taint */
15237 expr->isTainted = this->taintEngine->taintAssignment(dst, sf);
15238 expr->isTainted = this->taintEngine->taintUnion(dst, of);
15239
15240 /* Update the symbolic control flow */
15241 this->controlFlow_s(inst);
15242 }
15243
15244
15245 void x86Semantics::setl_s(triton::arch::Instruction& inst) {
15246 auto& dst = inst.operands[0];
15247 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
15248 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
15249
15250 /* Create symbolic operands */
15251 auto op2 = this->symbolicEngine->getOperandAst(inst, sf);
15252 auto op3 = this->symbolicEngine->getOperandAst(inst, of);
15253
15254 /* Create the semantics */
15255 auto node = this->astCtxt->ite(
15256 this->astCtxt->equal(this->astCtxt->bvxor(op2, op3), this->astCtxt->bvtrue()),
15257 this->astCtxt->bv(1, dst.getBitSize()),
15258 this->astCtxt->bv(0, dst.getBitSize())
15259 );
15260
15261 /* Create symbolic expression */
15262 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETL operation");
15263
15264 /* Set condition flag */
15265 if (op2->evaluate().is_zero() != op3->evaluate().is_zero()) {
15266 inst.setConditionTaken(true);
15267 }
15268
15269 /* Spread taint */
15270 expr->isTainted = this->taintEngine->taintAssignment(dst, sf);
15271 expr->isTainted = this->taintEngine->taintUnion(dst, of);
15272
15273 /* Update the symbolic control flow */
15274 this->controlFlow_s(inst);
15275 }
15276
15277
15278 void x86Semantics::setle_s(triton::arch::Instruction& inst) {
15279 auto& dst = inst.operands[0];
15280 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
15281 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
15282 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
15283
15284 /* Create symbolic operands */
15285 auto op2 = this->symbolicEngine->getOperandAst(inst, sf);
15286 auto op3 = this->symbolicEngine->getOperandAst(inst, of);
15287 auto op4 = this->symbolicEngine->getOperandAst(inst, zf);
15288
15289 /* Create the semantics */
15290 auto node = this->astCtxt->ite(
15291 this->astCtxt->equal(this->astCtxt->bvor(this->astCtxt->bvxor(op2, op3), op4), this->astCtxt->bvtrue()),
15292 this->astCtxt->bv(1, dst.getBitSize()),
15293 this->astCtxt->bv(0, dst.getBitSize())
15294 );
15295
15296 /* Create symbolic expression */
15297 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETLE operation");
15298
15299 /* Set condition flag */
15300 if ((op2->evaluate().is_zero() != op3->evaluate().is_zero()) || !op4->evaluate().is_zero()) {
15301 inst.setConditionTaken(true);
15302 }
15303
15304 /* Spread taint */
15305 expr->isTainted = this->taintEngine->taintAssignment(dst, sf);
15306 expr->isTainted = this->taintEngine->taintUnion(dst, of);
15307 expr->isTainted = this->taintEngine->taintUnion(dst, zf);
15308
15309 /* Update the symbolic control flow */
15310 this->controlFlow_s(inst);
15311 }
15312
15313
15314 void x86Semantics::setne_s(triton::arch::Instruction& inst) {
15315 auto& dst = inst.operands[0];
15316 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
15317
15318 /* Create symbolic operands */
15319 auto op2 = this->symbolicEngine->getOperandAst(inst, zf);
15320
15321 /* Create the semantics */
15322 auto node = this->astCtxt->ite(
15323 this->astCtxt->equal(op2, this->astCtxt->bvfalse()),
15324 this->astCtxt->bv(1, dst.getBitSize()),
15325 this->astCtxt->bv(0, dst.getBitSize())
15326 );
15327
15328 /* Create symbolic expression */
15329 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETNE operation");
15330
15331 /* Set condition flag */
15332 if (op2->evaluate().is_zero()) {
15333 inst.setConditionTaken(true);
15334 }
15335
15336 /* Spread taint */
15337 expr->isTainted = this->taintEngine->taintAssignment(dst, zf);
15338
15339 /* Update the symbolic control flow */
15340 this->controlFlow_s(inst);
15341 }
15342
15343
15344 void x86Semantics::setno_s(triton::arch::Instruction& inst) {
15345 auto& dst = inst.operands[0];
15346 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
15347
15348 /* Create symbolic operands */
15349 auto op2 = this->symbolicEngine->getOperandAst(inst, of);
15350
15351 /* Create the semantics */
15352 auto node = this->astCtxt->ite(
15353 this->astCtxt->equal(op2, this->astCtxt->bvfalse()),
15354 this->astCtxt->bv(1, dst.getBitSize()),
15355 this->astCtxt->bv(0, dst.getBitSize())
15356 );
15357
15358 /* Create symbolic expression */
15359 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETNO operation");
15360
15361 /* Set condition flag */
15362 if (op2->evaluate().is_zero()) {
15363 inst.setConditionTaken(true);
15364 }
15365
15366 /* Spread taint */
15367 expr->isTainted = this->taintEngine->taintAssignment(dst, of);
15368
15369 /* Update the symbolic control flow */
15370 this->controlFlow_s(inst);
15371 }
15372
15373
15374 void x86Semantics::setnp_s(triton::arch::Instruction& inst) {
15375 auto& dst = inst.operands[0];
15376 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
15377
15378 /* Create symbolic operands */
15379 auto op2 = this->symbolicEngine->getOperandAst(inst, pf);
15380
15381 /* Create the semantics */
15382 auto node = this->astCtxt->ite(
15383 this->astCtxt->equal(op2, this->astCtxt->bvfalse()),
15384 this->astCtxt->bv(1, dst.getBitSize()),
15385 this->astCtxt->bv(0, dst.getBitSize())
15386 );
15387
15388 /* Create symbolic expression */
15389 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETNP operation");
15390
15391 /* Set condition flag */
15392 if (op2->evaluate().is_zero()) {
15393 inst.setConditionTaken(true);
15394 }
15395
15396 /* Spread taint */
15397 expr->isTainted = this->taintEngine->taintAssignment(dst, pf);
15398
15399 /* Update the symbolic control flow */
15400 this->controlFlow_s(inst);
15401 }
15402
15403
15404 void x86Semantics::setns_s(triton::arch::Instruction& inst) {
15405 auto& dst = inst.operands[0];
15406 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
15407
15408 /* Create symbolic operands */
15409 auto op2 = this->symbolicEngine->getOperandAst(inst, sf);
15410
15411 /* Create the semantics */
15412 auto node = this->astCtxt->ite(
15413 this->astCtxt->equal(op2, this->astCtxt->bvfalse()),
15414 this->astCtxt->bv(1, dst.getBitSize()),
15415 this->astCtxt->bv(0, dst.getBitSize())
15416 );
15417
15418 /* Create symbolic expression */
15419 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETNS operation");
15420
15421 /* Set condition flag */
15422 if (op2->evaluate().is_zero()) {
15423 inst.setConditionTaken(true);
15424 }
15425
15426 /* Spread taint */
15427 expr->isTainted = this->taintEngine->taintAssignment(dst, sf);
15428
15429 /* Update the symbolic control flow */
15430 this->controlFlow_s(inst);
15431 }
15432
15433
15434 void x86Semantics::seto_s(triton::arch::Instruction& inst) {
15435 auto& dst = inst.operands[0];
15436 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
15437
15438 /* Create symbolic operands */
15439 auto op2 = this->symbolicEngine->getOperandAst(inst, of);
15440
15441 /* Create the semantics */
15442 auto node = this->astCtxt->ite(
15443 this->astCtxt->equal(op2, this->astCtxt->bvtrue()),
15444 this->astCtxt->bv(1, dst.getBitSize()),
15445 this->astCtxt->bv(0, dst.getBitSize())
15446 );
15447
15448 /* Create symbolic expression */
15449 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETO operation");
15450
15451 /* Set condition flag */
15452 if (!op2->evaluate().is_zero()) {
15453 inst.setConditionTaken(true);
15454 }
15455
15456 /* Spread taint */
15457 expr->isTainted = this->taintEngine->taintAssignment(dst, of);
15458
15459 /* Update the symbolic control flow */
15460 this->controlFlow_s(inst);
15461 }
15462
15463
15464 void x86Semantics::setp_s(triton::arch::Instruction& inst) {
15465 auto& dst = inst.operands[0];
15466 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
15467
15468 /* Create symbolic operands */
15469 auto op2 = this->symbolicEngine->getOperandAst(inst, pf);
15470
15471 /* Create the semantics */
15472 auto node = this->astCtxt->ite(
15473 this->astCtxt->equal(op2, this->astCtxt->bvtrue()),
15474 this->astCtxt->bv(1, dst.getBitSize()),
15475 this->astCtxt->bv(0, dst.getBitSize())
15476 );
15477
15478 /* Create symbolic expression */
15479 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETP operation");
15480
15481 /* Set condition flag */
15482 if (!op2->evaluate().is_zero()) {
15483 inst.setConditionTaken(true);
15484 }
15485
15486 /* Spread taint */
15487 expr->isTainted = this->taintEngine->taintAssignment(dst, pf);
15488
15489 /* Update the symbolic control flow */
15490 this->controlFlow_s(inst);
15491 }
15492
15493
15494 void x86Semantics::sets_s(triton::arch::Instruction& inst) {
15495 auto& dst = inst.operands[0];
15496 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
15497
15498 /* Create symbolic operands */
15499 auto op2 = this->symbolicEngine->getOperandAst(inst, sf);
15500
15501 /* Create the semantics */
15502 auto node = this->astCtxt->ite(
15503 this->astCtxt->equal(op2, this->astCtxt->bvtrue()),
15504 this->astCtxt->bv(1, dst.getBitSize()),
15505 this->astCtxt->bv(0, dst.getBitSize())
15506 );
15507
15508 /* Create symbolic expression */
15509 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETS operation");
15510
15511 /* Set condition flag */
15512 if (!op2->evaluate().is_zero()) {
15513 inst.setConditionTaken(true);
15514 }
15515
15516 /* Spread taint */
15517 expr->isTainted = this->taintEngine->taintAssignment(dst, sf);
15518
15519 /* Update the symbolic control flow */
15520 this->controlFlow_s(inst);
15521 }
15522
15523
15524 void x86Semantics::sfence_s(triton::arch::Instruction& inst) {
15525 /* Update the symbolic control flow */
15526 this->controlFlow_s(inst);
15527 }
15528
15529
15530 void x86Semantics::shl_s(triton::arch::Instruction& inst) {
15531 auto& dst = inst.operands[0];
15532 auto& src = inst.operands[1];
15533
15534 /* Create symbolic operands */
15535 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
15536 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
15537 auto op2bis = op2;
15538
15540 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, dst.getBitSize()));
15541 else
15542 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, dst.getBitSize()));
15543
15544 /* Create the semantics */
15545 auto node = this->astCtxt->bvshl(op1, op2);
15546
15547 /* Create symbolic expression */
15548 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SHL operation");
15549
15550 /* Spread taint */
15551 expr->isTainted = this->taintEngine->taintUnion(dst, src);
15552
15553 /* Update symbolic flags */
15554 this->cfShl_s(inst, expr, dst, op1, op2);
15555 this->ofShl_s(inst, expr, dst, op1, op2);
15556 this->pfShl_s(inst, expr, dst, op2);
15557 this->sfShl_s(inst, expr, dst, op2);
15558 this->zfShl_s(inst, expr, dst, op2);
15559
15560 /* Tag undefined flags */
15561 if (op2->evaluate() != 0) {
15562 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
15563 }
15564
15565 if (op2bis->evaluate() > dst.getBitSize()) {
15566 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
15567 }
15568
15569 if (op2->evaluate() > 1) {
15570 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
15571 }
15572
15573 /* Update the symbolic control flow */
15574 this->controlFlow_s(inst);
15575 }
15576
15577
15578 void x86Semantics::shld_s(triton::arch::Instruction& inst) {
15579 auto& dst = inst.operands[0];
15580 auto& src1 = inst.operands[1];
15581 auto& src2 = inst.operands[2];
15582
15583 /* Create symbolic operands */
15584 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
15585 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
15586 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
15587 auto op3bis = op3;
15588
15589 switch (dst.getBitSize()) {
15590 /* Mask 0x3f MOD size */
15592 op3 = this->astCtxt->bvsmod(
15593 this->astCtxt->bvand(
15594 op3,
15595 this->astCtxt->bv(triton::bitsize::qword-1, src2.getBitSize())),
15596 this->astCtxt->bv(dst.getBitSize(), src2.getBitSize())
15597 );
15598 break;
15599
15600 /* Mask 0x1f MOD size */
15603 op3 = this->astCtxt->bvsmod(
15604 this->astCtxt->bvand(
15605 op3,
15606 this->astCtxt->bv(triton::bitsize::dword-1, src2.getBitSize())),
15607 this->astCtxt->bv(triton::bitsize::dword, src2.getBitSize())
15608 );
15609 break;
15610
15611 default:
15612 throw triton::exceptions::Semantics("x86Semantics::shld_s(): Invalid destination size");
15613 }
15614
15615 /* Create the semantics */
15616 auto node = this->astCtxt->extract(
15617 dst.getBitSize()-1, 0,
15618 this->astCtxt->bvrol(
15619 this->astCtxt->concat(op2, op1),
15620 this->astCtxt->zx(((op1->getBitvectorSize() + op2->getBitvectorSize()) - op3->getBitvectorSize()), op3)
15621 )
15622 );
15623
15624 /* Create symbolic expression */
15625 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SHLD operation");
15626
15627 /* Spread taint */
15628 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
15629 expr->isTainted |= this->taintEngine->taintUnion(dst, src2);
15630
15631 /* Update symbolic flags */
15632 this->cfShld_s(inst, expr, dst, op1, op2, op3);
15633 this->ofShld_s(inst, expr, dst, op1, op2, op3);
15634 this->pfShl_s(inst, expr, dst, op3); /* Same that shl */
15635 this->sfShld_s(inst, expr, dst, op1, op2, op3);
15636 this->zfShl_s(inst, expr, dst, op3); /* Same that shl */
15637
15638 /* Tag undefined flags */
15639 if (op3->evaluate() != 0) {
15640 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
15641 }
15642
15643 if (op3->evaluate() > 1) {
15644 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
15645 }
15646
15647 if (op3bis->evaluate() > dst.getBitSize()) {
15648 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
15649 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
15650 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
15651 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
15652 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
15653 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF));
15654 if (dst.getType() == triton::arch::OP_REG)
15655 this->undefined_s(inst, dst.getRegister());
15656 }
15657
15658 /* Update the symbolic control flow */
15659 this->controlFlow_s(inst);
15660 }
15661
15662
15663 void x86Semantics::shlx_s(triton::arch::Instruction& inst) {
15664 auto& dst = inst.operands[0];
15665 auto& src1 = inst.operands[1];
15666 auto& src2 = inst.operands[2];
15667
15668 /* Create symbolic operands */
15669 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
15670 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
15671
15672 switch (dst.getBitSize()) {
15673 /* Mask 0x3f MOD size */
15675 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, src2.getBitSize()));
15676 break;
15677
15678 /* Mask 0x1f MOD size */
15680 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, src2.getBitSize()));
15681 break;
15682
15683 default:
15684 throw triton::exceptions::Semantics("x86Semantics::shlx_s(): Invalid destination size");
15685 }
15686
15687 /* Create the semantics */
15688 auto node = this->astCtxt->bvshl(op1, op2);
15689
15690 /* Create symbolic expression */
15691 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SHLX operation");
15692
15693 /* Spread taint */
15694 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
15695 expr->isTainted |= this->taintEngine->taintUnion(dst, src2);
15696
15697 /* Update the symbolic control flow */
15698 this->controlFlow_s(inst);
15699 }
15700
15701
15702 void x86Semantics::shr_s(triton::arch::Instruction& inst) {
15703 auto& dst = inst.operands[0];
15704 auto& src = inst.operands[1];
15705
15706 /* Create symbolic operands */
15707 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
15708 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
15709 auto op2bis = op2;
15710
15712 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, dst.getBitSize()));
15713 else
15714 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, dst.getBitSize()));
15715
15716 /* Create the semantics */
15717 auto node = this->astCtxt->bvlshr(op1, op2);
15718
15719 /* Create symbolic expression */
15720 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SHR operation");
15721
15722 /* Spread taint */
15723 expr->isTainted = this->taintEngine->taintUnion(dst, src);
15724
15725 /* Update symbolic flags */
15726 this->cfShr_s(inst, expr, dst, op1, op2);
15727 this->ofShr_s(inst, expr, dst, op1, op2);
15728 this->pfShl_s(inst, expr, dst, op2); /* Same that shl */
15729 this->sfShl_s(inst, expr, dst, op2); /* Same that shl */
15730 this->zfShl_s(inst, expr, dst, op2); /* Same that shl */
15731
15732 /* Tag undefined flags */
15733 if (op2->evaluate() != 0) {
15734 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
15735 }
15736
15737 if (op2bis->evaluate() > dst.getBitSize()) {
15738 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
15739 }
15740
15741 if (op2->evaluate() > 1) {
15742 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
15743 }
15744
15745 /* Update the symbolic control flow */
15746 this->controlFlow_s(inst);
15747 }
15748
15749
15750 void x86Semantics::shrd_s(triton::arch::Instruction& inst) {
15751 auto& dst = inst.operands[0];
15752 auto& src1 = inst.operands[1];
15753 auto& src2 = inst.operands[2];
15754
15755 /* Create symbolic operands */
15756 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
15757 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
15758 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
15759 auto op3bis = op3;
15760
15761 switch (dst.getBitSize()) {
15762 /* Mask 0x3f MOD size */
15764 op3 = this->astCtxt->bvsmod(
15765 this->astCtxt->bvand(
15766 op3,
15767 this->astCtxt->bv(triton::bitsize::qword-1, src2.getBitSize())),
15768 this->astCtxt->bv(dst.getBitSize(), src2.getBitSize())
15769 );
15770 break;
15771
15772 /* Mask 0x1f MOD size */
15775 op3 = this->astCtxt->bvsmod(
15776 this->astCtxt->bvand(
15777 op3,
15778 this->astCtxt->bv(triton::bitsize::dword-1, src2.getBitSize())),
15779 this->astCtxt->bv(triton::bitsize::dword, src2.getBitSize())
15780 );
15781 break;
15782
15783 default:
15784 throw triton::exceptions::Semantics("x86Semantics::shrd_s(): Invalid destination size");
15785 }
15786
15787 /* Create the semantics */
15788 auto node = this->astCtxt->extract(
15789 dst.getBitSize()-1, 0,
15790 this->astCtxt->bvror(
15791 this->astCtxt->concat(op2, op1),
15792 this->astCtxt->zx(((op1->getBitvectorSize() + op2->getBitvectorSize()) - op3->getBitvectorSize()), op3)
15793 )
15794 );
15795
15796 /* Create symbolic expression */
15797 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SHRD operation");
15798
15799 /* Spread taint */
15800 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
15801 expr->isTainted |= this->taintEngine->taintUnion(dst, src2);
15802
15803 /* Update symbolic flags */
15804 this->cfShrd_s(inst, expr, dst, op1, op2, op3);
15805 this->ofShrd_s(inst, expr, dst, op1, op2, op3);
15806 this->pfShl_s(inst, expr, dst, op3); /* Same that shl */
15807 this->sfShrd_s(inst, expr, dst, op1, op2, op3);
15808 this->zfShl_s(inst, expr, dst, op3); /* Same that shl */
15809
15810 /* Tag undefined flags */
15811 if (op3->evaluate() != 0) {
15812 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
15813 }
15814
15815 if (op3->evaluate() > 1) {
15816 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
15817 }
15818
15819 if (op3bis->evaluate() > dst.getBitSize()) {
15820 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
15821 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
15822 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
15823 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
15824 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
15825 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF));
15826 if (dst.getType() == triton::arch::OP_REG)
15827 this->undefined_s(inst, dst.getRegister());
15828 }
15829
15830 /* Update the symbolic control flow */
15831 this->controlFlow_s(inst);
15832 }
15833
15834
15835 void x86Semantics::shrx_s(triton::arch::Instruction& inst) {
15836 auto& dst = inst.operands[0];
15837 auto& src1 = inst.operands[1];
15838 auto& src2 = inst.operands[2];
15839
15840 /* Create symbolic operands */
15841 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
15842 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
15843
15844 switch (dst.getBitSize()) {
15845 /* Mask 0x3f MOD size */
15847 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, src2.getBitSize()));
15848 break;
15849
15850 /* Mask 0x1f MOD size */
15852 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, src2.getBitSize()));
15853 break;
15854
15855 default:
15856 throw triton::exceptions::Semantics("x86Semantics::shrx_s(): Invalid destination size");
15857 }
15858
15859 /* Create the semantics */
15860 auto node = this->astCtxt->bvlshr(op1, op2);
15861
15862 /* Create symbolic expression */
15863 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SHRX operation");
15864
15865 /* Spread taint */
15866 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
15867 expr->isTainted |= this->taintEngine->taintUnion(dst, src2);
15868
15869 /* Update the symbolic control flow */
15870 this->controlFlow_s(inst);
15871 }
15872
15873
15874 void x86Semantics::stc_s(triton::arch::Instruction& inst) {
15875 this->setFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Sets carry flag");
15876 /* Update the symbolic control flow */
15877 this->controlFlow_s(inst);
15878 }
15879
15880
15881 void x86Semantics::std_s(triton::arch::Instruction& inst) {
15882 this->setFlag_s(inst, this->architecture->getRegister(ID_REG_X86_DF), "Sets direction flag");
15883 /* Update the symbolic control flow */
15884 this->controlFlow_s(inst);
15885 }
15886
15887
15888 void x86Semantics::sti_s(triton::arch::Instruction& inst) {
15889 this->setFlag_s(inst, this->architecture->getRegister(ID_REG_X86_IF), "Sets interrupt flag");
15890 /* Update the symbolic control flow */
15891 this->controlFlow_s(inst);
15892 }
15893
15894
15895 void x86Semantics::stmxcsr_s(triton::arch::Instruction& inst) {
15896 auto& dst = inst.operands[0];
15897 auto src = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR));
15898
15899 /* Create symbolic operands */
15900 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
15901
15902 /* Create the semantics */
15903 auto node = this->astCtxt->extract(triton::bitsize::dword-1, 0, op2);
15904
15905 /* Create symbolic expression */
15906 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "STMXCSR operation");
15907
15908 /* Spread taint */
15909 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
15910
15911 /* Update the symbolic control flow */
15912 this->controlFlow_s(inst);
15913 }
15914
15915
15916 void x86Semantics::stosb_s(triton::arch::Instruction& inst) {
15917 auto& dst = inst.operands[0];
15918 auto& src = inst.operands[1];
15919 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
15920 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
15921 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
15922
15923 /* Check if there is a REP prefix and a counter to zero */
15924 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
15925 this->controlFlow_s(inst);
15926 return;
15927 }
15928
15929 /* Create symbolic operands */
15930 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
15931 auto op2 = this->symbolicEngine->getOperandAst(inst, index);
15932 auto op3 = this->symbolicEngine->getOperandAst(inst, df);
15933
15934 /* Create the semantics */
15935 auto node1 = op1;
15936 auto node2 = this->astCtxt->ite(
15937 this->astCtxt->equal(op3, this->astCtxt->bvfalse()),
15938 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::byte, index.getBitSize())),
15939 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::byte, index.getBitSize()))
15940 );
15941
15942 /* Create symbolic expression */
15943 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "STOSB operation");
15944 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
15945
15946 /* Spread taint */
15947 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
15948 expr2->isTainted = this->taintEngine->taintUnion(index, index);
15949
15950 /* Update the symbolic control flow */
15951 this->controlFlow_s(inst);
15952 }
15953
15954
15955 void x86Semantics::stosd_s(triton::arch::Instruction& inst) {
15956 auto& dst = inst.operands[0];
15957 auto& src = inst.operands[1];
15958 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
15959 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
15960 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
15961
15962 /* Check if there is a REP prefix and a counter to zero */
15963 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
15964 this->controlFlow_s(inst);
15965 return;
15966 }
15967
15968 /* Create symbolic operands */
15969 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
15970 auto op2 = this->symbolicEngine->getOperandAst(inst, index);
15971 auto op3 = this->symbolicEngine->getOperandAst(inst, df);
15972
15973 /* Create the semantics */
15974 auto node1 = op1;
15975 auto node2 = this->astCtxt->ite(
15976 this->astCtxt->equal(op3, this->astCtxt->bvfalse()),
15977 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::dword, index.getBitSize())),
15978 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::dword, index.getBitSize()))
15979 );
15980
15981 /* Create symbolic expression */
15982 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "STOSD operation");
15983 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
15984
15985 /* Spread taint */
15986 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
15987 expr2->isTainted = this->taintEngine->taintUnion(index, index);
15988
15989 /* Update the symbolic control flow */
15990 this->controlFlow_s(inst);
15991 }
15992
15993
15994 void x86Semantics::stosq_s(triton::arch::Instruction& inst) {
15995 auto& dst = inst.operands[0];
15996 auto& src = inst.operands[1];
15997 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
15998 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
15999 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
16000
16001 /* Check if there is a REP prefix and a counter to zero */
16002 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
16003 this->controlFlow_s(inst);
16004 return;
16005 }
16006
16007 /* Create symbolic operands */
16008 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
16009 auto op2 = this->symbolicEngine->getOperandAst(inst, index);
16010 auto op3 = this->symbolicEngine->getOperandAst(inst, df);
16011
16012 /* Create the semantics */
16013 auto node1 = op1;
16014 auto node2 = this->astCtxt->ite(
16015 this->astCtxt->equal(op3, this->astCtxt->bvfalse()),
16016 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::qword, index.getBitSize())),
16017 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::qword, index.getBitSize()))
16018 );
16019
16020 /* Create symbolic expression */
16021 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "STOSQ operation");
16022 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
16023
16024 /* Spread taint */
16025 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
16026 expr2->isTainted = this->taintEngine->taintUnion(index, index);
16027
16028 /* Update the symbolic control flow */
16029 this->controlFlow_s(inst);
16030 }
16031
16032
16033 void x86Semantics::stosw_s(triton::arch::Instruction& inst) {
16034 auto& dst = inst.operands[0];
16035 auto& src = inst.operands[1];
16036 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
16037 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
16038 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
16039
16040 /* Check if there is a REP prefix and a counter to zero */
16041 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
16042 this->controlFlow_s(inst);
16043 return;
16044 }
16045
16046 /* Create symbolic operands */
16047 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
16048 auto op2 = this->symbolicEngine->getOperandAst(inst, index);
16049 auto op3 = this->symbolicEngine->getOperandAst(inst, df);
16050
16051 /* Create the semantics */
16052 auto node1 = op1;
16053 auto node2 = this->astCtxt->ite(
16054 this->astCtxt->equal(op3, this->astCtxt->bvfalse()),
16055 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::word, index.getBitSize())),
16056 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::word, index.getBitSize()))
16057 );
16058
16059 /* Create symbolic expression */
16060 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "STOSW operation");
16061 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
16062
16063 /* Spread taint */
16064 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
16065 expr2->isTainted = this->taintEngine->taintUnion(index, index);
16066
16067 /* Update the symbolic control flow */
16068 this->controlFlow_s(inst);
16069 }
16070
16071
16072 void x86Semantics::sub_s(triton::arch::Instruction& inst) {
16073 auto& dst = inst.operands[0];
16074 auto& src = inst.operands[1];
16075
16076 /* Create symbolic operands */
16077 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
16078 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
16079
16080 /* Create the semantics */
16081 auto node = this->astCtxt->bvsub(op1, op2);
16082
16083 /* Create symbolic expression */
16084 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SUB operation");
16085
16086 /* Spread taint */
16087 expr->isTainted = this->taintEngine->taintUnion(dst, src);
16088
16089 /* Update symbolic flags */
16090 this->af_s(inst, expr, dst, op1, op2);
16091 this->cfSub_s(inst, expr, dst, op1, op2);
16092 this->ofSub_s(inst, expr, dst, op1, op2);
16093 this->pf_s(inst, expr, dst);
16094 this->sf_s(inst, expr, dst);
16095 this->zf_s(inst, expr, dst);
16096
16097 /* Update the symbolic control flow */
16098 this->controlFlow_s(inst);
16099 }
16100
16101
16102 void x86Semantics::syscall_s(triton::arch::Instruction& inst) {
16103 auto dst1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
16104 auto src1 = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
16105
16106 /* Create symbolic operands */
16107 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
16108
16109 /* Create the semantics */
16110 auto node1 = this->astCtxt->bvadd(op1, this->astCtxt->bv(inst.getSize(), src1.getBitSize()));
16111
16112 /* Create symbolic expression */
16113 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1, "SYSCALL RCX operation");
16114
16115 /* Spread taint */
16116 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src1);
16117
16118 /* 64-bit */
16119 if (src1.getBitSize() == 64) {
16120 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_R11));
16121 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EFLAGS));
16122 /* Create symbolic operands */
16123 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
16124 /* Create symbolic expression */
16125 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, op2, dst2, "SYSCALL R11 operation");
16126 /* Spread taint */
16127 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src2);
16128 }
16129
16130 /* Update the symbolic control flow */
16131 this->controlFlow_s(inst);
16132 }
16133
16134
16135 void x86Semantics::sysenter_s(triton::arch::Instruction& inst) {
16136 /* Update the symbolic control flow */
16137 this->controlFlow_s(inst);
16138 }
16139
16140
16141 void x86Semantics::test_s(triton::arch::Instruction& inst) {
16142 auto& src1 = inst.operands[0];
16143 auto& src2 = inst.operands[1];
16144
16145 /* Create symbolic operands */
16146 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
16147 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
16148
16149 /* Create the semantics */
16150 auto node = this->astCtxt->bvand(op1, op2);
16151
16152 /* Create symbolic expression */
16153 auto expr = this->symbolicEngine->createSymbolicVolatileExpression(inst, node, "TEST operation");
16154
16155 /* Spread taint */
16156 expr->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2);
16157
16158 /* Update symbolic flags */
16159 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
16160 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag");
16161 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
16162 this->pf_s(inst, expr, src1, true);
16163 this->sf_s(inst, expr, src1, true);
16164 this->zf_s(inst, expr, src1, true);
16165
16166 /* Update the symbolic control flow */
16167 this->controlFlow_s(inst);
16168 }
16169
16170
16171 void x86Semantics::tzcnt_s(triton::arch::Instruction& inst) {
16172 auto& dst = inst.operands[0];
16173 auto& src = inst.operands[1];
16174 auto bvSize1 = dst.getBitSize();
16175 auto bvSize2 = src.getBitSize();
16176
16177 /* Create symbolic operands */
16178 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
16179
16180 /* Create the semantics */
16181 triton::ast::SharedAbstractNode node = nullptr;
16182 switch (src.getSize()) {
16183 case triton::size::byte:
16184 node = this->astCtxt->ite(
16185 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)),
16186 this->astCtxt->bv(bvSize1, bvSize1),
16187 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
16188 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
16189 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
16190 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
16191 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
16192 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
16193 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
16194 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
16195 this->astCtxt->bv(0, bvSize1)
16196 ))))))))
16197 );
16198 break;
16199 case triton::size::word:
16200 node = this->astCtxt->ite(
16201 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)),
16202 this->astCtxt->bv(bvSize1, bvSize1),
16203 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
16204 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
16205 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
16206 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
16207 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
16208 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
16209 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
16210 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
16211 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
16212 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
16213 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
16214 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
16215 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
16216 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
16217 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
16218 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
16219 this->astCtxt->bv(0, bvSize1)
16220 ))))))))))))))))
16221 );
16222 break;
16224 node = this->astCtxt->ite(
16225 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)),
16226 this->astCtxt->bv(bvSize1, bvSize1),
16227 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
16228 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
16229 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
16230 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
16231 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
16232 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
16233 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
16234 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
16235 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
16236 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
16237 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
16238 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
16239 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
16240 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
16241 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
16242 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
16243 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(16, 16, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1),
16244 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(17, 17, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1),
16245 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(18, 18, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1),
16246 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(19, 19, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1),
16247 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(20, 20, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1),
16248 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(21, 21, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1),
16249 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(22, 22, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1),
16250 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(23, 23, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1),
16251 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(24, 24, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1),
16252 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(25, 25, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1),
16253 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(26, 26, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1),
16254 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(27, 27, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1),
16255 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(28, 28, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1),
16256 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(29, 29, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1),
16257 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(30, 30, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1),
16258 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(31, 31, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1),
16259 this->astCtxt->bv(0, bvSize1)
16260 ))))))))))))))))))))))))))))))))
16261 );
16262 break;
16264 node = this->astCtxt->ite(
16265 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)),
16266 this->astCtxt->bv(bvSize1, bvSize1),
16267 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
16268 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
16269 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
16270 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
16271 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
16272 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
16273 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
16274 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
16275 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
16276 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
16277 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
16278 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
16279 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
16280 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
16281 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
16282 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
16283 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(16, 16, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1),
16284 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(17, 17, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1),
16285 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(18, 18, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1),
16286 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(19, 19, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1),
16287 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(20, 20, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1),
16288 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(21, 21, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1),
16289 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(22, 22, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1),
16290 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(23, 23, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1),
16291 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(24, 24, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1),
16292 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(25, 25, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1),
16293 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(26, 26, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1),
16294 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(27, 27, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1),
16295 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(28, 28, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1),
16296 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(29, 29, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1),
16297 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(30, 30, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1),
16298 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(31, 31, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1),
16299 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(32, 32, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(32, bvSize1),
16300 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(33, 33, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(33, bvSize1),
16301 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(34, 34, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(34, bvSize1),
16302 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(35, 35, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(35, bvSize1),
16303 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(36, 36, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(36, bvSize1),
16304 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(37, 37, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(37, bvSize1),
16305 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(38, 38, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(38, bvSize1),
16306 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(39, 39, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(39, bvSize1),
16307 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(40, 40, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(40, bvSize1),
16308 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(41, 41, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(41, bvSize1),
16309 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(42, 42, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(42, bvSize1),
16310 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(43, 43, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(43, bvSize1),
16311 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(44, 44, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(44, bvSize1),
16312 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(45, 45, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(45, bvSize1),
16313 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(46, 46, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(46, bvSize1),
16314 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(47, 47, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(47, bvSize1),
16315 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(48, 48, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(48, bvSize1),
16316 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(49, 49, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(49, bvSize1),
16317 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(50, 50, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(50, bvSize1),
16318 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(51, 51, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(51, bvSize1),
16319 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(52, 52, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(52, bvSize1),
16320 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(53, 53, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(53, bvSize1),
16321 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(54, 54, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(54, bvSize1),
16322 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(55, 55, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(55, bvSize1),
16323 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(56, 56, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(56, bvSize1),
16324 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(57, 57, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(57, bvSize1),
16325 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(58, 58, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(58, bvSize1),
16326 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(59, 59, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(59, bvSize1),
16327 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(60, 60, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(60, bvSize1),
16328 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(61, 61, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(61, bvSize1),
16329 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(62, 62, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(62, bvSize1),
16330 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(63, 63, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(63, bvSize1),
16331 this->astCtxt->bv(0, bvSize1)
16332 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
16333 );
16334 break;
16335 default:
16336 throw triton::exceptions::Semantics("x86Semantics::tzcnt_s(): Invalid operand size.");
16337 }
16338
16339 /* Create symbolic expression */
16340 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "TZCNT operation");
16341
16342 /* Spread taint */
16343 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16344
16345 /* Update symbolic flags */
16346 this->cfTzcnt_s(inst, expr, src, op1);
16347 this->zf_s(inst, expr, src);
16348
16349 /* Tag undefined flags */
16350 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
16351 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
16352 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
16353 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
16354
16355 /* Update the symbolic control flow */
16356 this->controlFlow_s(inst);
16357 }
16358
16359
16360 void x86Semantics::unpckhpd_s(triton::arch::Instruction& inst) {
16361 auto& dst = inst.operands[0];
16362 auto& src = inst.operands[1];
16363
16364 /* Create symbolic operands */
16365 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
16366 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
16367
16368 /* Create the semantics */
16369 auto node = this->astCtxt->concat(
16370 this->astCtxt->extract(127, 64, op2),
16371 this->astCtxt->extract(127, 64, op1)
16372 );
16373
16374 /* Create symbolic expression */
16375 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "UNPCKHPD operation");
16376
16377 /* Spread taint */
16378 expr->isTainted = this->taintEngine->taintUnion(dst, src);
16379
16380 /* Update the symbolic control flow */
16381 this->controlFlow_s(inst);
16382 }
16383
16384
16385 void x86Semantics::unpckhps_s(triton::arch::Instruction& inst) {
16386 auto& dst = inst.operands[0];
16387 auto& src = inst.operands[1];
16388
16389 /* Create symbolic operands */
16390 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
16391 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
16392
16393 /* Create the semantics */
16394 std::vector<triton::ast::SharedAbstractNode> unpack;
16395 unpack.reserve(4);
16396
16397 unpack.push_back(this->astCtxt->extract(127, 96, op2));
16398 unpack.push_back(this->astCtxt->extract(127, 96, op1));
16399 unpack.push_back(this->astCtxt->extract(95, 64, op2));
16400 unpack.push_back(this->astCtxt->extract(95, 64, op1));
16401
16402 auto node = this->astCtxt->concat(unpack);
16403
16404 /* Create symbolic expression */
16405 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "UNPCKHPS operation");
16406
16407 /* Spread taint */
16408 expr->isTainted = this->taintEngine->taintUnion(dst, src);
16409
16410 /* Update the symbolic control flow */
16411 this->controlFlow_s(inst);
16412 }
16413
16414
16415 void x86Semantics::unpcklpd_s(triton::arch::Instruction& inst) {
16416 auto& dst = inst.operands[0];
16417 auto& src = inst.operands[1];
16418
16419 /* Create symbolic operands */
16420 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
16421 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
16422
16423 /* Create the semantics */
16424 auto node = this->astCtxt->concat(
16425 this->astCtxt->extract(63, 0, op2),
16426 this->astCtxt->extract(63, 0, op1)
16427 );
16428
16429 /* Create symbolic expression */
16430 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "UNPCKLPD operation");
16431
16432 /* Spread taint */
16433 expr->isTainted = this->taintEngine->taintUnion(dst, src);
16434
16435 /* Update the symbolic control flow */
16436 this->controlFlow_s(inst);
16437 }
16438
16439
16440 void x86Semantics::unpcklps_s(triton::arch::Instruction& inst) {
16441 auto& dst = inst.operands[0];
16442 auto& src = inst.operands[1];
16443
16444 /* Create symbolic operands */
16445 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
16446 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
16447
16448 /* Create the semantics */
16449 std::vector<triton::ast::SharedAbstractNode> unpack;
16450 unpack.reserve(4);
16451
16452 unpack.push_back(this->astCtxt->extract(63, 32, op2));
16453 unpack.push_back(this->astCtxt->extract(63, 32, op1));
16454 unpack.push_back(this->astCtxt->extract(31, 0, op2));
16455 unpack.push_back(this->astCtxt->extract(31, 0, op1));
16456
16457 auto node = this->astCtxt->concat(unpack);
16458
16459 /* Create symbolic expression */
16460 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "UNPCKLPS operation");
16461
16462 /* Spread taint */
16463 expr->isTainted = this->taintEngine->taintUnion(dst, src);
16464
16465 /* Update the symbolic control flow */
16466 this->controlFlow_s(inst);
16467 }
16468
16469
16470 void x86Semantics::verr_s(triton::arch::Instruction& inst) {
16471 auto& src = inst.operands[0];
16472 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
16473
16474 /* Link the source to the instruction */
16475 this->symbolicEngine->getOperandAst(inst, src);
16476
16477 /* Create the semantics */
16478 auto node = this->astCtxt->bvtrue();
16479
16480 /* Create symbolic expression */
16481 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VERR operation");
16482
16483 /* Spread taint */
16484 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16485
16486 /* Update the symbolic control flow */
16487 this->controlFlow_s(inst);
16488 }
16489
16490
16491 void x86Semantics::verw_s(triton::arch::Instruction& inst) {
16492 auto& src = inst.operands[0];
16493 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
16494
16495 /* Link the source to the instruction */
16496 this->symbolicEngine->getOperandAst(inst, src);
16497
16498 /* Create the semantics */
16499 auto node = this->astCtxt->bvtrue();
16500
16501 /* Create symbolic expression */
16502 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VERW operation");
16503
16504 /* Spread taint */
16505 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16506
16507 /* Update the symbolic control flow */
16508 this->controlFlow_s(inst);
16509 }
16510
16511
16512 void x86Semantics::vextracti128_s(triton::arch::Instruction& inst) {
16513 auto& dst = inst.operands[0];
16514 auto& src1 = inst.operands[1];
16515 auto& src2 = inst.operands[2];
16516
16517 /* Create symbolic operands */
16518 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
16519 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
16520
16521 /* Create the semantics */
16523 if (op2->evaluate() & 0b00000001) {
16524 node = this->astCtxt->extract(255, 128, op1);
16525 } else {
16526 node = this->astCtxt->extract(127, 0, op1);
16527 }
16528
16529 /* Create symbolic expression */
16530 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VEXTRACTI128 operation");
16531
16532 /* Spread taint */
16533 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
16534
16535 /* Update the symbolic control flow */
16536 this->controlFlow_s(inst);
16537 }
16538
16539
16540 void x86Semantics::vmovd_s(triton::arch::Instruction& inst) {
16541 auto& dst = inst.operands[0];
16542 auto& src = inst.operands[1];
16543
16544 /* Create symbolic operands */
16545 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
16546
16547 /* Create the semantics */
16548 auto node = this->astCtxt->extract(triton::bitsize::dword-1, 0, op2);
16549
16550 /* Create symbolic expression */
16551 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVD operation");
16552
16553 /* Spread taint */
16554 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16555
16556 /* Update the symbolic control flow */
16557 this->controlFlow_s(inst);
16558 }
16559
16560
16561 void x86Semantics::vmovdqa_s(triton::arch::Instruction& inst) {
16562 auto& dst = inst.operands[0];
16563 auto& src = inst.operands[1];
16564
16565 /* Create the semantics */
16566 auto node = this->symbolicEngine->getOperandAst(inst, src);
16567
16568 /* Create symbolic expression */
16569 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVDQA operation");
16570
16571 /* Spread taint */
16572 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16573
16574 /* Update the symbolic control flow */
16575 this->controlFlow_s(inst);
16576 }
16577
16578
16579 void x86Semantics::vmovdqu_s(triton::arch::Instruction& inst) {
16580 auto& dst = inst.operands[0];
16581 auto& src = inst.operands[1];
16582
16583 /* Create the semantics */
16584 auto node = this->symbolicEngine->getOperandAst(inst, src);
16585
16586 /* Create symbolic expression */
16587 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVDQU operation");
16588
16589 /* Spread taint */
16590 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16591
16592 /* Update the symbolic control flow */
16593 this->controlFlow_s(inst);
16594 }
16595
16596
16597 void x86Semantics::vmovntdq_s(triton::arch::Instruction& inst) {
16598 auto& dst = inst.operands[0];
16599 auto& src = inst.operands[1];
16600
16601 /* Create the semantics */
16602 auto node = this->symbolicEngine->getOperandAst(inst, src);
16603
16604 /* Create symbolic expression */
16605 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVNTDQ operation");
16606
16607 /* Spread taint */
16608 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16609
16610 /* Update the symbolic control flow */
16611 this->controlFlow_s(inst);
16612 }
16613
16614
16615 void x86Semantics::vmovq_s(triton::arch::Instruction& inst) {
16616 auto& dst = inst.operands[0];
16617 auto& src = inst.operands[1];
16618
16619 /* Create symbolic operands */
16620 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
16621
16622 /* Create the semantics */
16623 auto node = this->astCtxt->extract(triton::bitsize::qword-1, 0, op2);
16624
16625 /* Create symbolic expression */
16626 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVQ operation");
16627
16628 /* Spread taint */
16629 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16630
16631 /* Update the symbolic control flow */
16632 this->controlFlow_s(inst);
16633 }
16634
16635
16636 void x86Semantics::vmovsd_s(triton::arch::Instruction& inst) {
16637 /* Move scalar double-precision floating-point value */
16638 if (inst.operands.size() == 2) {
16639 auto& dst = inst.operands[0];
16640 auto& src = inst.operands[1];
16641
16642 /* Create symbolic operands */
16643 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
16644 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
16645
16646 /* Create the semantics */
16648 if (dst.getSize() == triton::size::dqword && src.getSize() == triton::size::qword) {
16649 /* VEX.LIG.F2.0F.WIG 10 /r VMOVSD xmm1, m64 */
16650 node = op2;
16651 }
16652 else if (dst.getSize() == triton::size::qword && src.getSize() == triton::size::dqword) {
16653 /* VEX.LIG.F2.0F.WIG 11 /r VMOVSD m64, xmm1 */
16654 node = this->astCtxt->extract(triton::bitsize::qword - 1, 0, op2);
16655 }
16656 else {
16657 throw triton::exceptions::Semantics("x86Semantics::vmovsd_s(): Invalid operand size.");
16658 }
16659
16660 /* Create symbolic expression */
16661 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVSD operation");
16662
16663 /* Spread taint */
16664 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16665 }
16666
16667 /* Merge scalar double-precision floating-point value
16668 *
16669 * VEX.NDS.LIG.F2.0F.WIG 10 /r VMOVSD xmm1, xmm2, xmm3
16670 * VEX.NDS.LIG.F2.0F.WIG 11 /r VMOVSD xmm1, xmm2, xmm3
16671 */
16672 else if (inst.operands.size() == 3) {
16673 auto& dst = inst.operands[0];
16674 auto& src1 = inst.operands[1];
16675 auto& src2 = inst.operands[2];
16676
16677 /* Create symbolic operands */
16678 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
16679 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
16680 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
16681
16682 /* Create the semantics */
16683 auto node = this->astCtxt->concat(
16684 this->astCtxt->extract(triton::bitsize::dqword - 1, triton::bitsize::qword, op2),
16685 this->astCtxt->extract(triton::bitsize::qword - 1, 0, op3)
16686 );
16687
16688 /* Create symbolic expression */
16689 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVSD operation");
16690
16691 /* Spread taint */
16692 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
16693 }
16694
16695 /* Update the symbolic control flow */
16696 this->controlFlow_s(inst);
16697 }
16698
16699
16700 void x86Semantics::vmovaps_s(triton::arch::Instruction& inst) {
16701 auto& dst = inst.operands[0];
16702 auto& src = inst.operands[1];
16703
16704 /* Create the semantics */
16705 auto node = this->symbolicEngine->getOperandAst(inst, src);
16706
16707 /* Create symbolic expression */
16708 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVAPS operation");
16709
16710 /* Spread taint */
16711 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16712
16713 /* Update the symbolic control flow */
16714 this->controlFlow_s(inst);
16715 }
16716
16717
16718 void x86Semantics::vmovups_s(triton::arch::Instruction& inst) {
16719 auto& dst = inst.operands[0];
16720 auto& src = inst.operands[1];
16721
16722 /* Create the semantics */
16723 auto node = this->symbolicEngine->getOperandAst(inst, src);
16724
16725 /* Create symbolic expression */
16726 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVUPS operation");
16727
16728 /* Spread taint */
16729 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16730
16731 /* Update the symbolic control flow */
16732 this->controlFlow_s(inst);
16733 }
16734
16735
16736 void x86Semantics::vpackuswb_s(triton::arch::Instruction& inst) {
16737 auto& dst = inst.operands[0];
16738 auto& src1 = inst.operands[1];
16739 auto& src2 = inst.operands[2];
16740
16741 /* Create symbolic operands */
16742 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
16743 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
16744
16745 /* Create the semantics */
16746 std::vector<triton::ast::SharedAbstractNode> pck;
16747 pck.reserve(dst.getSize());
16748
16749 std::vector<triton::ast::SharedAbstractNode> ops{op2, op1};
16750 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
16751 for (triton::uint32 idx = 0; idx < ops.size(); ++idx) {
16752 for (triton::uint32 i = triton::size::qword * k; i < triton::size::qword * (k + 1); ++i) {
16753 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
16755 auto signed_word = this->astCtxt->extract(high, low, ops[idx]);
16756 pck.push_back(this->astCtxt->ite(
16757 this->astCtxt->bvsge(signed_word, this->astCtxt->bv(0xff, triton::bitsize::word)),
16758 this->astCtxt->bv(0xff, triton::bitsize::byte),
16759 this->astCtxt->ite(
16760 this->astCtxt->bvsle(signed_word, this->astCtxt->bv(0x00, triton::bitsize::word)),
16761 this->astCtxt->bv(0x00, triton::bitsize::byte),
16762 this->astCtxt->extract(triton::bitsize::byte - 1, 0, signed_word)))
16763 );
16764 }
16765 }
16766 }
16767
16768 auto node = this->astCtxt->concat(pck);
16769
16770 /* Create symbolic expression */
16771 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPACKUSWB operation");
16772
16773 /* Apply the taint */
16774 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
16775
16776 /* Update the symbolic control flow */
16777 this->controlFlow_s(inst);
16778 }
16779
16780
16781 void x86Semantics::vpackssdw_s(triton::arch::Instruction& inst) {
16782 auto& dst = inst.operands[0];
16783 auto& src1 = inst.operands[1];
16784 auto& src2 = inst.operands[2];
16785
16786 /* Create symbolic operands */
16787 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
16788 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
16789
16790 /* Create the semantics */
16791 std::vector<triton::ast::SharedAbstractNode> pck;
16792 pck.reserve(dst.getSize() / triton::size::word);
16793
16794 std::vector<triton::ast::SharedAbstractNode> ops{op2, op1};
16795 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
16796 for (triton::uint32 idx = 0; idx < ops.size(); ++idx) {
16797 for (triton::uint32 i = triton::size::dword * k; i < triton::size::dword * (k + 1); ++i) {
16798 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::dword);
16800 auto signed_dword = this->astCtxt->extract(high, low, ops[idx]);
16801 pck.push_back(this->astCtxt->ite(
16802 this->astCtxt->bvsge(signed_dword, this->astCtxt->bv(0x7fff, triton::bitsize::dword)),
16803 this->astCtxt->bv(0x7fff, triton::bitsize::word),
16804 this->astCtxt->ite(
16805 this->astCtxt->bvsle(signed_dword, this->astCtxt->bv(0xffff8000, triton::bitsize::dword)),
16806 this->astCtxt->bv(0x8000, triton::bitsize::word),
16807 this->astCtxt->extract(triton::bitsize::word - 1, 0, signed_dword)))
16808 );
16809 }
16810 }
16811 }
16812
16813 auto node = this->astCtxt->concat(pck);
16814
16815 /* Create symbolic expression */
16816 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPACKSSDW operation");
16817
16818 /* Apply the taint */
16819 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
16820
16821 /* Update the symbolic control flow */
16822 this->controlFlow_s(inst);
16823 }
16824
16825
16826 void x86Semantics::vpacksswb_s(triton::arch::Instruction& inst) {
16827 auto& dst = inst.operands[0];
16828 auto& src1 = inst.operands[1];
16829 auto& src2 = inst.operands[2];
16830
16831 /* Create symbolic operands */
16832 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
16833 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
16834
16835 /* Create the semantics */
16836 std::vector<triton::ast::SharedAbstractNode> pck;
16837 pck.reserve(dst.getSize());
16838
16839 std::vector<triton::ast::SharedAbstractNode> ops{op2, op1};
16840 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
16841 for (triton::uint32 idx = 0; idx < ops.size(); ++idx) {
16842 for (triton::uint32 i = triton::size::qword * k; i < triton::size::qword * (k + 1); ++i) {
16843 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
16845 auto signed_word = this->astCtxt->extract(high, low, ops[idx]);
16846 pck.push_back(this->astCtxt->ite(
16847 this->astCtxt->bvsge(signed_word, this->astCtxt->bv(0x007f, triton::bitsize::word)),
16848 this->astCtxt->bv(0x7f, triton::bitsize::byte),
16849 this->astCtxt->ite(
16850 this->astCtxt->bvsle(signed_word, this->astCtxt->bv(0xff80, triton::bitsize::word)),
16851 this->astCtxt->bv(0x80, triton::bitsize::byte),
16852 this->astCtxt->extract(triton::bitsize::byte - 1, 0, signed_word)))
16853 );
16854 }
16855 }
16856 }
16857
16858 auto node = this->astCtxt->concat(pck);
16859
16860 /* Create symbolic expression */
16861 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPACKSSWB operation");
16862
16863 /* Apply the taint */
16864 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
16865
16866 /* Update the symbolic control flow */
16867 this->controlFlow_s(inst);
16868 }
16869
16870
16871 void x86Semantics::vpaddb_s(triton::arch::Instruction& inst) {
16872 auto& dst = inst.operands[0];
16873 auto& src1 = inst.operands[1];
16874 auto& src2 = inst.operands[2];
16875
16876 /* Create symbolic operands */
16877 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
16878 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
16879
16880 /* Create the semantics */
16881 std::vector<triton::ast::SharedAbstractNode> pck;
16882 pck.reserve(dst.getSize() / triton::size::byte);
16883
16884 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::byte; ++i) {
16885 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::byte);
16887 pck.push_back(this->astCtxt->bvadd(this->astCtxt->extract(high, low, op1), this->astCtxt->extract(high, low, op2)));
16888 }
16889 auto node = this->astCtxt->concat(pck);
16890
16891 /* Create symbolic expression */
16892 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPADDB operation");
16893
16894 /* Spread taint */
16895 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
16896
16897 /* Update the symbolic control flow */
16898 this->controlFlow_s(inst);
16899 }
16900
16901
16902 void x86Semantics::vpaddd_s(triton::arch::Instruction& inst) {
16903 auto& dst = inst.operands[0];
16904 auto& src1 = inst.operands[1];
16905 auto& src2 = inst.operands[2];
16906
16907 /* Create symbolic operands */
16908 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
16909 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
16910
16911 /* Create the semantics */
16912 std::vector<triton::ast::SharedAbstractNode> pck;
16913 pck.reserve(dst.getSize() / triton::size::dword);
16914
16915 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::dword; ++i) {
16916 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::dword);
16918 pck.push_back(this->astCtxt->bvadd(this->astCtxt->extract(high, low, op1), this->astCtxt->extract(high, low, op2)));
16919 }
16920 auto node = this->astCtxt->concat(pck);
16921
16922 /* Create symbolic expression */
16923 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPADDD operation");
16924
16925 /* Spread taint */
16926 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
16927
16928 /* Update the symbolic control flow */
16929 this->controlFlow_s(inst);
16930 }
16931
16932
16933 void x86Semantics::vpaddw_s(triton::arch::Instruction& inst) {
16934 auto& dst = inst.operands[0];
16935 auto& src1 = inst.operands[1];
16936 auto& src2 = inst.operands[2];
16937
16938 /* Create symbolic operands */
16939 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
16940 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
16941
16942 /* Create the semantics */
16943 std::vector<triton::ast::SharedAbstractNode> pck;
16944 pck.reserve(dst.getSize() / triton::size::word);
16945
16946 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; ++i) {
16947 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
16949 pck.push_back(this->astCtxt->bvadd(this->astCtxt->extract(high, low, op1), this->astCtxt->extract(high, low, op2)));
16950 }
16951 auto node = this->astCtxt->concat(pck);
16952
16953 /* Create symbolic expression */
16954 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPADDW operation");
16955
16956 /* Spread taint */
16957 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
16958
16959 /* Update the symbolic control flow */
16960 this->controlFlow_s(inst);
16961 }
16962
16963
16964 void x86Semantics::vpand_s(triton::arch::Instruction& inst) {
16965 auto& dst = inst.operands[0];
16966 auto& src1 = inst.operands[1];
16967 auto& src2 = inst.operands[2];
16968
16969 /* Create symbolic operands */
16970 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
16971 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
16972
16973 /* Create the semantics */
16974 auto node = this->astCtxt->bvand(op2, op3);
16975
16976 /* Create symbolic expression */
16977 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPAND operation");
16978
16979 /* Spread taint */
16980 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
16981
16982 /* Update the symbolic control flow */
16983 this->controlFlow_s(inst);
16984 }
16985
16986
16987 void x86Semantics::vpandn_s(triton::arch::Instruction& inst) {
16988 auto& dst = inst.operands[0];
16989 auto& src1 = inst.operands[1];
16990 auto& src2 = inst.operands[2];
16991
16992 /* Create symbolic operands */
16993 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
16994 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
16995
16996 /* Create the semantics */
16997 auto node = this->astCtxt->bvand(this->astCtxt->bvnot(op2), op3);
16998
16999 /* Create symbolic expression */
17000 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPANDN operation");
17001
17002 /* Spread taint */
17003 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17004
17005 /* Update the symbolic control flow */
17006 this->controlFlow_s(inst);
17007 }
17008
17009
17010 void x86Semantics::vperm2i128_s(triton::arch::Instruction& inst) {
17011 auto& dst = inst.operands[0];
17012 auto& src1 = inst.operands[1];
17013 auto& src2 = inst.operands[2];
17014 auto& src3 = inst.operands[3];
17015
17016 /* Create symbolic operands */
17017 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17018 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17019 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
17020
17021 /* Create the semantics */
17022 std::deque<triton::arch::OperandWrapper> taint;
17023 auto permute = [&] (triton::uint8 control) {
17024 switch (control) {
17025 case 0:
17026 taint.push_back(src1);
17027 return this->astCtxt->extract(127, 0, op1);
17028 case 1:
17029 taint.push_back(src1);
17030 return this->astCtxt->extract(255, 128, op1);
17031 case 2:
17032 taint.push_back(src2);
17033 return this->astCtxt->extract(127, 0, op2);
17034 case 3:
17035 default:
17036 taint.push_back(src2);
17037 return this->astCtxt->extract(255, 128, op2);
17038 }
17039 };
17040
17041 auto ctrl = static_cast<triton::uint8>(op3->evaluate());
17042 auto high = permute((ctrl >> 4) & 0b00000011);
17043 auto low = permute(ctrl & 0b00000011);
17044
17045 if (ctrl & 0b00001000) {
17046 low = this->astCtxt->bv(0, 128);
17047 taint.pop_back();
17048 }
17049
17050 if (ctrl & 0b10000000) {
17051 high = this->astCtxt->bv(0, 128);
17052 taint.pop_front();
17053 }
17054
17055 auto node = this->astCtxt->concat(high, low);
17056
17057 /* Create symbolic expression */
17058 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPERM2I128 operation");
17059
17060 /* Spread taint */
17061 if (taint.empty()) {
17062 this->taintEngine->setTaint(dst, false);
17063 } else if (taint.size() == 1) {
17064 expr->isTainted = this->taintEngine->taintAssignment(dst, taint[0]);
17065 } else {
17066 expr->isTainted = this->taintEngine->taintAssignment(dst, taint[0]) | this->taintEngine->taintUnion(dst, taint[0]);
17067 }
17068
17069 /* Update the symbolic control flow */
17070 this->controlFlow_s(inst);
17071 }
17072
17073
17074 void x86Semantics::vpermq_s(triton::arch::Instruction& inst) {
17075 auto& dst = inst.operands[0];
17076 auto& src1 = inst.operands[1];
17077 auto& src2 = inst.operands[2];
17078
17079 /* Create symbolic operands */
17080 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17081 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17082
17083 /* Create the semantics */
17084 std::vector<triton::ast::SharedAbstractNode> pck;
17085 pck.reserve(dst.getSize() / triton::size::byte);
17086
17087 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::qword; ++i) {
17088 auto high = triton::bitsize::byte - 1 - 2 * i;
17089 auto shift = this->astCtxt->bvmul(
17090 this->astCtxt->bv(triton::bitsize::qword, src1.getBitSize()),
17091 this->astCtxt->zx(src1.getBitSize() - 2,
17092 this->astCtxt->extract(high, high - 1, op2)));
17093 pck.push_back(this->astCtxt->extract(triton::bitsize::qword - 1, 0, this->astCtxt->bvlshr(op1, shift)));
17094 }
17095
17096 auto node = this->astCtxt->concat(pck);
17097
17098 /* Create symbolic expression */
17099 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPERMQ operation");
17100
17101 /* Spread taint */
17102 expr->isTainted = this->taintEngine->taintUnion(dst, src1);
17103
17104 /* Update the symbolic control flow */
17105 this->controlFlow_s(inst);
17106 }
17107
17108
17109 void x86Semantics::vpextrb_s(triton::arch::Instruction& inst) {
17110 auto& dst = inst.operands[0];
17111 auto& src1 = inst.operands[1];
17112 auto& src2 = inst.operands[2];
17113
17114 /* Create symbolic operands */
17115 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
17116 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
17117 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
17118
17119 auto node = this->astCtxt->extract(7, 0,
17120 this->astCtxt->bvlshr(
17121 op2,
17122 this->astCtxt->bv(((op3->evaluate() & 0x0f) * 8), op2->getBitvectorSize())
17123 )
17124 );
17125
17126 /* Create symbolic expression */
17127 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPEXTRB operation");
17128
17129 /* Apply the taint */
17130 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
17131
17132 /* Update the symbolic control flow */
17133 this->controlFlow_s(inst);
17134 }
17135
17136
17137 void x86Semantics::vpextrd_s(triton::arch::Instruction& inst) {
17138 auto& dst = inst.operands[0];
17139 auto& src1 = inst.operands[1];
17140 auto& src2 = inst.operands[2];
17141
17142 /* Create symbolic operands */
17143 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
17144 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
17145 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
17146
17147 auto node = this->astCtxt->extract(triton::bitsize::dword - 1, 0,
17148 this->astCtxt->bvlshr(
17149 op2,
17150 this->astCtxt->bv(((op3->evaluate() & 0x3) * triton::bitsize::dword), op2->getBitvectorSize())
17151 )
17152 );
17153
17154 /* Create symbolic expression */
17155 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPEXTRD operation");
17156
17157 /* Apply the taint */
17158 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
17159
17160 /* Update the symbolic control flow */
17161 this->controlFlow_s(inst);
17162 }
17163
17164
17165 void x86Semantics::vpextrq_s(triton::arch::Instruction& inst) {
17166 auto& dst = inst.operands[0];
17167 auto& src1 = inst.operands[1];
17168 auto& src2 = inst.operands[2];
17169
17170 /* Create symbolic operands */
17171 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
17172 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
17173 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
17174
17175 auto node = this->astCtxt->extract(triton::bitsize::qword - 1, 0,
17176 this->astCtxt->bvlshr(
17177 op2,
17178 this->astCtxt->bv(((op3->evaluate() & 0x1) * triton::bitsize::qword), op2->getBitvectorSize())
17179 )
17180 );
17181
17182 /* Create symbolic expression */
17183 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPEXTRQ operation");
17184
17185 /* Apply the taint */
17186 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
17187
17188 /* Update the symbolic control flow */
17189 this->controlFlow_s(inst);
17190 }
17191
17192
17193 void x86Semantics::vpextrw_s(triton::arch::Instruction& inst) {
17194 triton::uint32 count = 0;
17195 auto& dst = inst.operands[0];
17196 auto& src1 = inst.operands[1];
17197 auto& src2 = inst.operands[2];
17198
17199 /*
17200 * When specifying a word location in an MMX technology register, the
17201 * 2 least-significant bits of the count operand specify the location;
17202 * for an XMM register, the 3 least-significant bits specify the
17203 * location.
17204 */
17205 if (src1.getBitSize() == triton::bitsize::qword) {
17206 count = 0x03;
17207 }
17208 else {
17209 count = 0x07;
17210 }
17211
17212 /* Create symbolic operands */
17213 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
17214 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
17215 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
17216
17217 auto node = this->astCtxt->extract(triton::bitsize::word - 1, 0,
17218 this->astCtxt->bvlshr(
17219 op2,
17220 this->astCtxt->bv(((op3->evaluate() & count) * triton::bitsize::word), op2->getBitvectorSize())
17221 )
17222 );
17223
17224 /* Create symbolic expression */
17225 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPEXTRW operation");
17226
17227 /* Apply the taint */
17228 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
17229
17230 /* Update the symbolic control flow */
17231 this->controlFlow_s(inst);
17232 }
17233
17234
17235 void x86Semantics::vpbroadcastb_s(triton::arch::Instruction& inst) {
17236 auto &dst = inst.operands[0];
17237 auto &src = inst.operands[1];
17238
17239 /* Create symbolic operands */
17240 auto op = this->symbolicEngine->getOperandAst(inst, src);
17241
17242 /* Create the semantics */
17243 auto src_node = this->astCtxt->extract(triton::bitsize::byte - 1, 0, op);
17244 std::vector<triton::ast::SharedAbstractNode> exprs(dst.getSize(), src_node);
17245 auto node = this->astCtxt->concat(exprs);
17246
17247 /* Create symbolic expression */
17248 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPBROADCASTB operation");
17249
17250 /* Spread taint */
17251 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
17252
17253 /* Update the symbolic control flow */
17254 this->controlFlow_s(inst);
17255 }
17256
17257
17258 void x86Semantics::vpcmpeqb_s(triton::arch::Instruction& inst) {
17259 auto& dst = inst.operands[0];
17260 auto& src1 = inst.operands[1];
17261 auto& src2 = inst.operands[2];
17262
17263 /* Create symbolic operands */
17264 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17265 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17266
17267 /* Create the semantics */
17268 std::vector<triton::ast::SharedAbstractNode> pck;
17269 pck.reserve(dst.getSize());
17270
17271 for (triton::uint32 index = 0; index < src1.getSize(); index++) {
17272 uint32 high = (src1.getBitSize() - 1) - (index * triton::bitsize::byte);
17273 uint32 low = (src1.getBitSize() - triton::bitsize::byte) - (index * triton::bitsize::byte);
17274 pck.push_back(this->astCtxt->ite(
17275 this->astCtxt->equal(
17276 this->astCtxt->extract(high, low, op1),
17277 this->astCtxt->extract(high, low, op2)),
17278 this->astCtxt->bv(0xff, triton::bitsize::byte),
17279 this->astCtxt->bv(0x00, triton::bitsize::byte))
17280 );
17281 }
17282
17283 auto node = this->astCtxt->concat(pck);
17284
17285 /* Create symbolic expression */
17286 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPCMPEQB operation");
17287
17288 /* Apply the taint */
17289 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17290
17291 /* Update the symbolic control flow */
17292 this->controlFlow_s(inst);
17293 }
17294
17295
17296 void x86Semantics::vpcmpeqd_s(triton::arch::Instruction& inst) {
17297 auto& dst = inst.operands[0];
17298 auto& src1 = inst.operands[1];
17299 auto& src2 = inst.operands[2];
17300
17301 /* Create symbolic operands */
17302 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17303 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17304
17305 /* Create the semantics */
17306 std::vector<triton::ast::SharedAbstractNode> pck;
17307 pck.reserve(dst.getSize() / triton::size::dword);
17308
17309 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) {
17310 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword);
17312 pck.push_back(this->astCtxt->ite(
17313 this->astCtxt->equal(
17314 this->astCtxt->extract(high, low, op1),
17315 this->astCtxt->extract(high, low, op2)),
17316 this->astCtxt->bv(0xffffffff, triton::bitsize::dword),
17317 this->astCtxt->bv(0x00000000, triton::bitsize::dword))
17318 );
17319 }
17320
17321 auto node = this->astCtxt->concat(pck);
17322
17323 /* Create symbolic expression */
17324 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPCMPEQD operation");
17325
17326 /* Apply the taint */
17327 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17328
17329 /* Update the symbolic control flow */
17330 this->controlFlow_s(inst);
17331 }
17332
17333
17334 void x86Semantics::vpcmpeqq_s(triton::arch::Instruction& inst) {
17335 auto& dst = inst.operands[0];
17336 auto& src1 = inst.operands[1];
17337 auto& src2 = inst.operands[2];
17338
17339 /* Create symbolic operands */
17340 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17341 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17342
17343 /* Create the semantics */
17344 std::vector<triton::ast::SharedAbstractNode> pck;
17345 pck.reserve(dst.getSize() / triton::size::qword);
17346
17347 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::qword; index++) {
17348 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::qword);
17350 pck.push_back(this->astCtxt->ite(
17351 this->astCtxt->equal(
17352 this->astCtxt->extract(high, low, op1),
17353 this->astCtxt->extract(high, low, op2)),
17354 this->astCtxt->bv(0xffffffffffffffff, triton::bitsize::qword),
17355 this->astCtxt->bv(0x0000000000000000, triton::bitsize::qword))
17356 );
17357 }
17358
17359 auto node = this->astCtxt->concat(pck);
17360
17361 /* Create symbolic expression */
17362 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPCMPEQQ operation");
17363
17364 /* Apply the taint */
17365 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17366
17367 /* Update the symbolic control flow */
17368 this->controlFlow_s(inst);
17369 }
17370
17371
17372 void x86Semantics::vpcmpeqw_s(triton::arch::Instruction& inst) {
17373 auto& dst = inst.operands[0];
17374 auto& src1 = inst.operands[1];
17375 auto& src2 = inst.operands[2];
17376
17377 /* Create symbolic operands */
17378 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17379 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17380
17381 /* Create the semantics */
17382 std::vector<triton::ast::SharedAbstractNode> pck;
17383 pck.reserve(dst.getSize() / triton::size::word);
17384
17385 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
17386 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
17388 pck.push_back(this->astCtxt->ite(
17389 this->astCtxt->equal(
17390 this->astCtxt->extract(high, low, op1),
17391 this->astCtxt->extract(high, low, op2)),
17392 this->astCtxt->bv(0xffff, triton::bitsize::word),
17393 this->astCtxt->bv(0x0000, triton::bitsize::word))
17394 );
17395 }
17396
17397 auto node = this->astCtxt->concat(pck);
17398
17399 /* Create symbolic expression */
17400 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPCMPEQW operation");
17401
17402 /* Apply the taint */
17403 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17404
17405 /* Update the symbolic control flow */
17406 this->controlFlow_s(inst);
17407 }
17408
17409
17410 void x86Semantics::vpcmpgtb_s(triton::arch::Instruction& inst) {
17411 auto& dst = inst.operands[0];
17412 auto& src1 = inst.operands[1];
17413 auto& src2 = inst.operands[2];
17414
17415 /* Create symbolic operands */
17416 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17417 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17418
17419 /* Create the semantics */
17420 std::vector<triton::ast::SharedAbstractNode> pck;
17421 pck.reserve(dst.getSize());
17422
17423 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
17424 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
17426 pck.push_back(this->astCtxt->ite(
17427 this->astCtxt->bvsgt(
17428 this->astCtxt->extract(high, low, op1),
17429 this->astCtxt->extract(high, low, op2)),
17430 this->astCtxt->bv(0xff, triton::bitsize::byte),
17431 this->astCtxt->bv(0x00, triton::bitsize::byte))
17432 );
17433 }
17434
17435 auto node = this->astCtxt->concat(pck);
17436
17437 /* Create symbolic expression */
17438 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPCMPGTB operation");
17439
17440 /* Apply the taint */
17441 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17442
17443 /* Update the symbolic control flow */
17444 this->controlFlow_s(inst);
17445 }
17446
17447
17448 void x86Semantics::vpcmpgtd_s(triton::arch::Instruction& inst) {
17449 auto& dst = inst.operands[0];
17450 auto& src1 = inst.operands[1];
17451 auto& src2 = inst.operands[2];
17452
17453 /* Create symbolic operands */
17454 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17455 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17456
17457 /* Create the semantics */
17458 std::vector<triton::ast::SharedAbstractNode> pck;
17459 pck.reserve(dst.getSize() / triton::size::dword);
17460
17461 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) {
17462 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword);
17464 pck.push_back(this->astCtxt->ite(
17465 this->astCtxt->bvsgt(
17466 this->astCtxt->extract(high, low, op1),
17467 this->astCtxt->extract(high, low, op2)),
17468 this->astCtxt->bv(0xffffffff, triton::bitsize::dword),
17469 this->astCtxt->bv(0x00000000, triton::bitsize::dword))
17470 );
17471 }
17472
17473 auto node = this->astCtxt->concat(pck);
17474
17475 /* Create symbolic expression */
17476 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPCMPGTD operation");
17477
17478 /* Apply the taint */
17479 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17480
17481 /* Update the symbolic control flow */
17482 this->controlFlow_s(inst);
17483 }
17484
17485
17486 void x86Semantics::vpcmpgtw_s(triton::arch::Instruction& inst) {
17487 auto& dst = inst.operands[0];
17488 auto& src1 = inst.operands[1];
17489 auto& src2 = inst.operands[2];
17490
17491 /* Create symbolic operands */
17492 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17493 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17494
17495 /* Create the semantics */
17496 std::vector<triton::ast::SharedAbstractNode> pck;
17497 pck.reserve(dst.getSize() / triton::size::word);
17498
17499 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
17500 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
17502 pck.push_back(this->astCtxt->ite(
17503 this->astCtxt->bvsgt(
17504 this->astCtxt->extract(high, low, op1),
17505 this->astCtxt->extract(high, low, op2)),
17506 this->astCtxt->bv(0xffff, triton::bitsize::word),
17507 this->astCtxt->bv(0x0000, triton::bitsize::word))
17508 );
17509 }
17510
17511 auto node = this->astCtxt->concat(pck);
17512
17513 /* Create symbolic expression */
17514 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPCMPGTW operation");
17515
17516 /* Apply the taint */
17517 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17518
17519 /* Update the symbolic control flow */
17520 this->controlFlow_s(inst);
17521 }
17522
17523
17524 void x86Semantics::vpmaddwd_s(triton::arch::Instruction& inst) {
17525 auto& dst = inst.operands[0];
17526 auto& src1 = inst.operands[1];
17527 auto& src2 = inst.operands[2];
17528
17529 /* Create symbolic operands */
17530 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17531 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17532
17533 /* Create the semantics */
17534 std::vector<triton::ast::SharedAbstractNode> pck;
17535 pck.reserve(dst.getSize() / triton::size::dword);
17536
17537 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; i += 2) {
17538 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
17540 auto node1 = this->astCtxt->bvmul(
17541 this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op1)),
17542 this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op2))
17543 );
17544 high -= triton::bitsize::word;
17545 low -= triton::bitsize::word;
17546 auto node2 = this->astCtxt->bvmul(
17547 this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op1)),
17548 this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op2))
17549 );
17550 pck.push_back(this->astCtxt->bvadd(node1, node2));
17551 }
17552
17553 auto node = this->astCtxt->concat(pck);
17554
17555 /* Create symbolic expression */
17556 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPMADDWD operation");
17557
17558 /* Apply the taint */
17559 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17560
17561 /* Update the symbolic control flow */
17562 this->controlFlow_s(inst);
17563 }
17564
17565
17566 void x86Semantics::vpmovmskb_s(triton::arch::Instruction& inst) {
17567 auto& dst = inst.operands[0];
17568 auto& src = inst.operands[1];
17569
17570 /* Create symbolic operands */
17571 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
17572
17573 /* Create the semantics */
17574 std::vector<triton::ast::SharedAbstractNode> mskb;
17575 mskb.reserve(32);
17576
17577 switch (src.getSize()) {
17579 mskb.push_back(this->astCtxt->extract(255, 255, op2));
17580 mskb.push_back(this->astCtxt->extract(247, 247, op2));
17581 mskb.push_back(this->astCtxt->extract(239, 239, op2));
17582 mskb.push_back(this->astCtxt->extract(231, 231, op2));
17583 mskb.push_back(this->astCtxt->extract(223, 223, op2));
17584 mskb.push_back(this->astCtxt->extract(215, 215, op2));
17585 mskb.push_back(this->astCtxt->extract(207, 207, op2));
17586 mskb.push_back(this->astCtxt->extract(199, 199, op2));
17587 mskb.push_back(this->astCtxt->extract(191, 191, op2));
17588 mskb.push_back(this->astCtxt->extract(183, 183, op2));
17589 mskb.push_back(this->astCtxt->extract(175, 175, op2));
17590 mskb.push_back(this->astCtxt->extract(167, 167, op2));
17591 mskb.push_back(this->astCtxt->extract(159, 159, op2));
17592 mskb.push_back(this->astCtxt->extract(151, 151, op2));
17593 mskb.push_back(this->astCtxt->extract(143, 143, op2));
17594 mskb.push_back(this->astCtxt->extract(135, 135, op2));
17595
17597 mskb.push_back(this->astCtxt->extract(127, 127, op2));
17598 mskb.push_back(this->astCtxt->extract(119, 119, op2));
17599 mskb.push_back(this->astCtxt->extract(111, 111, op2));
17600 mskb.push_back(this->astCtxt->extract(103, 103, op2));
17601 mskb.push_back(this->astCtxt->extract(95 , 95 , op2));
17602 mskb.push_back(this->astCtxt->extract(87 , 87 , op2));
17603 mskb.push_back(this->astCtxt->extract(79 , 79 , op2));
17604 mskb.push_back(this->astCtxt->extract(71 , 71 , op2));
17605 mskb.push_back(this->astCtxt->extract(63 , 63 , op2));
17606 mskb.push_back(this->astCtxt->extract(55 , 55 , op2));
17607 mskb.push_back(this->astCtxt->extract(47 , 47 , op2));
17608 mskb.push_back(this->astCtxt->extract(39 , 39 , op2));
17609 mskb.push_back(this->astCtxt->extract(31 , 31 , op2));
17610 mskb.push_back(this->astCtxt->extract(23 , 23 , op2));
17611 mskb.push_back(this->astCtxt->extract(15 , 15 , op2));
17612 mskb.push_back(this->astCtxt->extract(7 , 7 , op2));
17613 break;
17614
17615 default:
17616 throw triton::exceptions::Semantics("x86Semantics::vpmovmskb_s(): Invalid operand size.");
17617 }
17618
17619 auto node = this->astCtxt->zx(
17620 dst.getBitSize() - static_cast<triton::uint32>(mskb.size()),
17621 this->astCtxt->concat(mskb)
17622 );
17623
17624 /* Create symbolic expression */
17625 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPMOVMSKB operation");
17626
17627 /* Apply the taint */
17628 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
17629
17630 /* Update the symbolic control flow */
17631 this->controlFlow_s(inst);
17632 }
17633
17634
17635 void x86Semantics::vpminub_s(triton::arch::Instruction& inst) {
17636 auto& dst = inst.operands[0];
17637 auto& src1 = inst.operands[1];
17638 auto& src2 = inst.operands[2];
17639
17640 /* Create symbolic operands */
17641 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17642 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17643
17644 /* Create the semantics */
17645 std::vector<triton::ast::SharedAbstractNode> pck;
17646 pck.reserve(dst.getSize());
17647
17648 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
17649 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
17651 pck.push_back(this->astCtxt->ite(
17652 this->astCtxt->bvuge(
17653 this->astCtxt->extract(high, low, op1),
17654 this->astCtxt->extract(high, low, op2)),
17655 this->astCtxt->extract(high, low, op2),
17656 this->astCtxt->extract(high, low, op1))
17657 );
17658 }
17659
17660 auto node = this->astCtxt->concat(pck);
17661
17662 /* Create symbolic expression */
17663 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPMINUB operation");
17664
17665 /* Apply the taint */
17666 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17667
17668 /* Update the symbolic control flow */
17669 this->controlFlow_s(inst);
17670 }
17671
17672
17673 void x86Semantics::vpmulhw_s(triton::arch::Instruction& inst) {
17674 auto& dst = inst.operands[0];
17675 auto& src1 = inst.operands[1];
17676 auto& src2 = inst.operands[2];
17677
17678 /* Create symbolic operands */
17679 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17680 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17681
17682 /* Create the semantics */
17683 std::vector<triton::ast::SharedAbstractNode> pck;
17684 pck.reserve(dst.getSize() / triton::size::word);
17685
17686 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; ++i) {
17687 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
17689 auto n1 = this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op1));
17690 auto n2 = this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op2));
17691 auto node = this->astCtxt->extract(triton::bitsize::dword - 1, triton::bitsize::word, this->astCtxt->bvmul(n1, n2));
17692 pck.push_back(node);
17693 }
17694 auto node = this->astCtxt->concat(pck);
17695
17696 /* Create symbolic expression */
17697 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPMULHW operation");
17698
17699 /* Apply the taint */
17700 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17701
17702 /* Update the symbolic control flow */
17703 this->controlFlow_s(inst);
17704 }
17705
17706
17707 void x86Semantics::vpmullw_s(triton::arch::Instruction& inst) {
17708 auto& dst = inst.operands[0];
17709 auto& src1 = inst.operands[1];
17710 auto& src2 = inst.operands[2];
17711
17712 /* Create symbolic operands */
17713 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17714 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17715
17716 /* Create the semantics */
17717 std::vector<triton::ast::SharedAbstractNode> pck;
17718 pck.reserve(dst.getSize() / triton::size::word);
17719
17720 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; ++i) {
17721 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
17723 auto n1 = this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op1));
17724 auto n2 = this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op2));
17725 auto node = this->astCtxt->extract(triton::bitsize::word - 1, 0, this->astCtxt->bvmul(n1, n2));
17726 pck.push_back(node);
17727 }
17728 auto node = this->astCtxt->concat(pck);
17729
17730 /* Create symbolic expression */
17731 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPMULLW operation");
17732
17733 /* Apply the taint */
17734 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17735
17736 /* Update the symbolic control flow */
17737 this->controlFlow_s(inst);
17738 }
17739
17740
17741 void x86Semantics::vpor_s(triton::arch::Instruction& inst) {
17742 auto& dst = inst.operands[0];
17743 auto& src1 = inst.operands[1];
17744 auto& src2 = inst.operands[2];
17745
17746 /* Create symbolic operands */
17747 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
17748 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
17749
17750 /* Create the semantics */
17751 auto node = this->astCtxt->bvor(op2, op3);
17752
17753 /* Create symbolic expression */
17754 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPOR operation");
17755
17756 /* Spread taint */
17757 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17758
17759 /* Update the symbolic control flow */
17760 this->controlFlow_s(inst);
17761 }
17762
17763
17764 void x86Semantics::vpshufd_s(triton::arch::Instruction& inst) {
17765 auto& dst = inst.operands[0];
17766 auto& src = inst.operands[1];
17767 auto& ord = inst.operands[2];
17768 triton::uint32 dstSize = dst.getBitSize();
17769
17770 /* Create symbolic operands */
17771 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
17772 auto op3 = this->symbolicEngine->getOperandAst(inst, ord);
17773
17774 /* Create the semantics */
17775 std::vector<triton::ast::SharedAbstractNode> pack;
17776 pack.reserve(8);
17777
17778 switch (dstSize) {
17779
17780 /* YMM */
17782 pack.push_back(
17783 this->astCtxt->extract(31, 0,
17784 this->astCtxt->bvlshr(
17785 op2,
17786 this->astCtxt->bvmul(
17787 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(7, 6, op3)),
17788 this->astCtxt->bv(32, dstSize)
17789 )
17790 )
17791 )
17792 );
17793 pack.push_back(
17794 this->astCtxt->extract(31, 0,
17795 this->astCtxt->bvlshr(
17796 op2,
17797 this->astCtxt->bvmul(
17798 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(5, 4, op3)),
17799 this->astCtxt->bv(32, dstSize)
17800 )
17801 )
17802 )
17803 );
17804 pack.push_back(
17805 this->astCtxt->extract(31, 0,
17806 this->astCtxt->bvlshr(
17807 op2,
17808 this->astCtxt->bvmul(
17809 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(3, 2, op3)),
17810 this->astCtxt->bv(32, dstSize)
17811 )
17812 )
17813 )
17814 );
17815 pack.push_back(
17816 this->astCtxt->extract(31, 0,
17817 this->astCtxt->bvlshr(
17818 op2,
17819 this->astCtxt->bvmul(
17820 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(1, 0, op3)),
17821 this->astCtxt->bv(32, dstSize)
17822 )
17823 )
17824 )
17825 );
17826
17827 /* XMM */
17829 pack.push_back(
17830 this->astCtxt->extract(31, 0,
17831 this->astCtxt->bvlshr(
17832 op2,
17833 this->astCtxt->bvmul(
17834 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(7, 6, op3)),
17835 this->astCtxt->bv(32, dstSize)
17836 )
17837 )
17838 )
17839 );
17840 pack.push_back(
17841 this->astCtxt->extract(31, 0,
17842 this->astCtxt->bvlshr(
17843 op2,
17844 this->astCtxt->bvmul(
17845 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(5, 4, op3)),
17846 this->astCtxt->bv(32, dstSize)
17847 )
17848 )
17849 )
17850 );
17851 pack.push_back(
17852 this->astCtxt->extract(31, 0,
17853 this->astCtxt->bvlshr(
17854 op2,
17855 this->astCtxt->bvmul(
17856 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(3, 2, op3)),
17857 this->astCtxt->bv(32, dstSize)
17858 )
17859 )
17860 )
17861 );
17862 pack.push_back(
17863 this->astCtxt->extract(31, 0,
17864 this->astCtxt->bvlshr(
17865 op2,
17866 this->astCtxt->bvmul(
17867 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(1, 0, op3)),
17868 this->astCtxt->bv(32, dstSize)
17869 )
17870 )
17871 )
17872 );
17873 break;
17874
17875 default:
17876 throw triton::exceptions::Semantics("x86Semantics::vpshufd_s(): Invalid operand size.");
17877 }
17878
17879 auto node = this->astCtxt->concat(pack);
17880
17881 /* Create symbolic expression */
17882 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSHUFD operation");
17883
17884 /* Spread taint */
17885 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
17886
17887 /* Update the symbolic control flow */
17888 this->controlFlow_s(inst);
17889 }
17890
17891
17892 void x86Semantics::vpsignw_s(triton::arch::Instruction& inst) {
17893 auto& dst = inst.operands[0];
17894 auto& src1 = inst.operands[1];
17895 auto& src2 = inst.operands[2];
17896
17897 /* Create symbolic operands */
17898 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17899 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17900
17901 /* Create the semantics */
17902 std::vector<triton::ast::SharedAbstractNode> pck;
17903 pck.reserve(dst.getSize() / triton::size::word);
17904
17905 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
17906 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
17908 auto val = this->astCtxt->extract(high, low, op2);
17909 pck.push_back(this->astCtxt->ite(
17910 this->astCtxt->bvsgt(val, this->astCtxt->bv(0, triton::bitsize::word)),
17911 this->astCtxt->extract(high, low, op1),
17912 this->astCtxt->ite(
17913 this->astCtxt->bvslt(val, this->astCtxt->bv(0, triton::bitsize::word)),
17914 this->astCtxt->bvneg(this->astCtxt->extract(high, low, op1)),
17915 this->astCtxt->bv(0, triton::bitsize::word)))
17916 );
17917 }
17918
17919 auto node = this->astCtxt->concat(pck);
17920
17921 /* Create symbolic expression */
17922 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSIGNW operation");
17923
17924 /* Spread taint */
17925 this->taintEngine->setTaint(dst, false);
17926
17927 /* Update the symbolic control flow */
17928 this->controlFlow_s(inst);
17929 }
17930
17931
17932 void x86Semantics::vpslldq_s(triton::arch::Instruction& inst) {
17933 auto& dst = inst.operands[0];
17934 auto& src1 = inst.operands[1];
17935 auto& src2 = inst.operands[2];
17936
17937 /* Create symbolic operands */
17938 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17939 auto op2 = this->astCtxt->zx(triton::bitsize::dqword - src2.getBitSize(), this->symbolicEngine->getOperandAst(inst, src2));
17940
17941 /* Create the semantics */
17943
17944 std::vector<triton::ast::SharedAbstractNode> pck;
17945 pck.reserve(dst.getSize() / triton::size::dqword);
17946
17947 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dqword; index++) {
17948 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dqword);
17950 pck.push_back(this->astCtxt->bvshl(
17951 this->astCtxt->extract(high, low, op1),
17952 this->astCtxt->bvmul(
17953 this->astCtxt->ite(
17954 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::word, triton::bitsize::dqword)),
17956 op2
17957 ),
17959 )
17960 ));
17961 }
17962
17963 node = pck.size() > 1 ? this->astCtxt->concat(pck) : pck[0];
17964
17965 /* Create symbolic expression */
17966 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSLLDQ operation");
17967
17968 /* Spread taint */
17969 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17970
17971 /* Update the symbolic control flow */
17972 this->controlFlow_s(inst);
17973 }
17974
17975
17976 void x86Semantics::vpsllw_s(triton::arch::Instruction& inst) {
17977 auto& dst = inst.operands[0];
17978 auto& src1 = inst.operands[1];
17979 auto& src2 = inst.operands[2];
17980
17981 /* Create symbolic operands */
17982 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17983 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17984
17985 /* Create the semantics */
17986 std::vector<triton::ast::SharedAbstractNode> pck;
17987 pck.reserve(dst.getSize() / triton::size::word);
17988
17989 auto shift = this->astCtxt->ite(
17990 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::word, src2.getBitSize())),
17991 this->astCtxt->bv(triton::bitsize::word, src2.getBitSize()),
17992 op2
17993 );
17994
17995 if (shift->getBitvectorSize() < triton::bitsize::word) {
17996 shift = this->astCtxt->zx(triton::bitsize::word - shift->getBitvectorSize(), shift);
17997 }
17998 else {
17999 shift = this->astCtxt->extract(triton::bitsize::word - 1, 0, shift);
18000 }
18001
18002 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; ++i) {
18003 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
18005 pck.push_back(this->astCtxt->bvshl(this->astCtxt->extract(high, low, op1), shift));
18006 }
18007 auto node = this->astCtxt->concat(pck);
18008
18009 /* Create symbolic expression */
18010 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSLLW operation");
18011
18012 /* Spread taint */
18013 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18014
18015 /* Update the symbolic control flow */
18016 this->controlFlow_s(inst);
18017 }
18018
18019
18020 void x86Semantics::vpsrad_s(triton::arch::Instruction& inst) {
18021 auto& dst = inst.operands[0];
18022 auto& src1 = inst.operands[1];
18023 auto& src2 = inst.operands[2];
18024
18025 /* Create symbolic operands */
18026 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18027 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18028
18029 /* Create the semantics */
18030 std::vector<triton::ast::SharedAbstractNode> pck;
18031 pck.reserve(dst.getSize() / triton::size::dword);
18032
18033 auto shift = this->astCtxt->ite(
18034 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::dword, src2.getBitSize())),
18035 this->astCtxt->bv(triton::bitsize::dword, src2.getBitSize()),
18036 op2
18037 );
18038
18039 if (shift->getBitvectorSize() < triton::bitsize::dword) {
18040 shift = this->astCtxt->zx(triton::bitsize::dword - shift->getBitvectorSize(), shift);
18041 }
18042 else {
18043 shift = this->astCtxt->extract(triton::bitsize::dword - 1, 0, shift);
18044 }
18045
18046 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::dword; ++i) {
18047 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::dword);
18049 pck.push_back(this->astCtxt->bvashr(this->astCtxt->extract(high, low, op1), shift));
18050 }
18051 auto node = this->astCtxt->concat(pck);
18052
18053 /* Create symbolic expression */
18054 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSRAD operation");
18055
18056 /* Spread taint */
18057 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18058
18059 /* Update the symbolic control flow */
18060 this->controlFlow_s(inst);
18061 }
18062
18063
18064 void x86Semantics::vpsraw_s(triton::arch::Instruction& inst) {
18065 auto& dst = inst.operands[0];
18066 auto& src1 = inst.operands[1];
18067 auto& src2 = inst.operands[2];
18068
18069 /* Create symbolic operands */
18070 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18071 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18072
18073 /* Create the semantics */
18074 std::vector<triton::ast::SharedAbstractNode> pck;
18075 pck.reserve(dst.getSize() / triton::size::word);
18076
18077 auto shift = this->astCtxt->ite(
18078 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::word, src2.getBitSize())),
18079 this->astCtxt->bv(triton::bitsize::word, src2.getBitSize()),
18080 op2
18081 );
18082
18083 if (shift->getBitvectorSize() < triton::bitsize::word) {
18084 shift = this->astCtxt->zx(triton::bitsize::word - shift->getBitvectorSize(), shift);
18085 }
18086 else {
18087 shift = this->astCtxt->extract(triton::bitsize::word - 1, 0, shift);
18088 }
18089
18090 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; ++i) {
18091 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
18093 pck.push_back(this->astCtxt->bvashr(this->astCtxt->extract(high, low, op1), shift));
18094 }
18095 auto node = this->astCtxt->concat(pck);
18096
18097 /* Create symbolic expression */
18098 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSRAW operation");
18099
18100 /* Spread taint */
18101 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18102
18103 /* Update the symbolic control flow */
18104 this->controlFlow_s(inst);
18105 }
18106
18107
18108 void x86Semantics::vpsrldq_s(triton::arch::Instruction& inst) {
18109 auto& dst = inst.operands[0];
18110 auto& src1 = inst.operands[1];
18111 auto& src2 = inst.operands[2];
18112
18113 /* Create symbolic operands */
18114 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18115 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18116
18117 /* Create the semantics */
18118 std::vector<triton::ast::SharedAbstractNode> pck;
18119 pck.reserve(dst.getSize() / triton::size::dqword);
18120
18121 auto shift = this->astCtxt->ite(
18122 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::word, src2.getBitSize())),
18123 this->astCtxt->bv(triton::bitsize::word, src2.getBitSize()),
18124 op2
18125 );
18126
18127 if (shift->getBitvectorSize() < triton::bitsize::dqword) {
18128 shift = this->astCtxt->zx(triton::bitsize::dqword - shift->getBitvectorSize(), shift);
18129 }
18130 else {
18131 shift = this->astCtxt->extract(triton::bitsize::dqword - 1, 0, shift);
18132 }
18133 shift = this->astCtxt->bvmul(shift, this->astCtxt->bv(triton::bitsize::byte, triton::bitsize::dqword));
18134
18135 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::dqword; ++i) {
18136 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::dqword);
18138 pck.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(high, low, op1), shift));
18139 }
18140 auto node = pck.size() > 1 ? this->astCtxt->concat(pck) : pck[0];
18141
18142 /* Create symbolic expression */
18143 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSRLDQ operation");
18144
18145 /* Spread taint */
18146 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18147
18148 /* Update the symbolic control flow */
18149 this->controlFlow_s(inst);
18150 }
18151
18152
18153 void x86Semantics::vpsrlw_s(triton::arch::Instruction& inst) {
18154 auto& dst = inst.operands[0];
18155 auto& src1 = inst.operands[1];
18156 auto& src2 = inst.operands[2];
18157
18158 /* Create symbolic operands */
18159 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18160 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18161
18162 /* Create the semantics */
18163 std::vector<triton::ast::SharedAbstractNode> pck;
18164 pck.reserve(dst.getSize() / triton::size::word);
18165
18166 auto shift = this->astCtxt->ite(
18167 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::word, src2.getBitSize())),
18168 this->astCtxt->bv(triton::bitsize::word, src2.getBitSize()),
18169 op2
18170 );
18171
18172 if (shift->getBitvectorSize() < triton::bitsize::word) {
18173 shift = this->astCtxt->zx(triton::bitsize::word - shift->getBitvectorSize(), shift);
18174 }
18175 else {
18176 shift = this->astCtxt->extract(triton::bitsize::word - 1, 0, shift);
18177 }
18178
18179 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; ++i) {
18180 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
18182 pck.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(high, low, op1), shift));
18183 }
18184 auto node = this->astCtxt->concat(pck);
18185
18186 /* Create symbolic expression */
18187 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSRLW operation");
18188
18189 /* Spread taint */
18190 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18191
18192 /* Update the symbolic control flow */
18193 this->controlFlow_s(inst);
18194 }
18195
18196
18197 void x86Semantics::vpsubb_s(triton::arch::Instruction& inst) {
18198 auto& dst = inst.operands[0];
18199 auto& src1 = inst.operands[1];
18200 auto& src2 = inst.operands[2];
18201
18202 /* Create symbolic operands */
18203 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18204 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18205
18206 /* Create the semantics */
18207 std::vector<triton::ast::SharedAbstractNode> pck;
18208 pck.reserve(dst.getSize());
18209
18210 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
18211 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
18213 pck.push_back(this->astCtxt->bvsub(
18214 this->astCtxt->extract(high, low, op1),
18215 this->astCtxt->extract(high, low, op2))
18216 );
18217 }
18218
18219 auto node = this->astCtxt->concat(pck);
18220
18221 /* Create symbolic expression */
18222 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSUBB operation");
18223
18224 /* Apply the taint */
18225 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18226
18227 /* Update the symbolic control flow */
18228 this->controlFlow_s(inst);
18229 }
18230
18231
18232 void x86Semantics::vpsubd_s(triton::arch::Instruction& inst) {
18233 auto& dst = inst.operands[0];
18234 auto& src1 = inst.operands[1];
18235 auto& src2 = inst.operands[2];
18236
18237 /* Create symbolic operands */
18238 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18239 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18240
18241 /* Create the semantics */
18242 std::vector<triton::ast::SharedAbstractNode> pck;
18243 pck.reserve(dst.getSize() / triton::size::dword);
18244
18245 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) {
18246 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword);
18248 pck.push_back(this->astCtxt->bvsub(
18249 this->astCtxt->extract(high, low, op1),
18250 this->astCtxt->extract(high, low, op2))
18251 );
18252 }
18253
18254 auto node = this->astCtxt->concat(pck);
18255
18256 /* Create symbolic expression */
18257 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSUBD operation");
18258
18259 /* Apply the taint */
18260 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18261
18262 /* Update the symbolic control flow */
18263 this->controlFlow_s(inst);
18264 }
18265
18266
18267 void x86Semantics::vpsubq_s(triton::arch::Instruction& inst) {
18268 auto& dst = inst.operands[0];
18269 auto& src1 = inst.operands[1];
18270 auto& src2 = inst.operands[2];
18271
18272 /* Create symbolic operands */
18273 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18274 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18275
18276 /* Create the semantics */
18277 std::vector<triton::ast::SharedAbstractNode> pck;
18278 pck.reserve(dst.getSize() / triton::size::qword);
18279
18280 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::qword; index++) {
18281 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::qword);
18283 pck.push_back(this->astCtxt->bvsub(
18284 this->astCtxt->extract(high, low, op1),
18285 this->astCtxt->extract(high, low, op2))
18286 );
18287 }
18288
18289 auto node = this->astCtxt->concat(pck);
18290
18291 /* Create symbolic expression */
18292 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSUBQ operation");
18293
18294 /* Apply the taint */
18295 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18296
18297 /* Update the symbolic control flow */
18298 this->controlFlow_s(inst);
18299 }
18300
18301
18302 void x86Semantics::vpsubw_s(triton::arch::Instruction& inst) {
18303 auto& dst = inst.operands[0];
18304 auto& src1 = inst.operands[1];
18305 auto& src2 = inst.operands[2];
18306
18307 /* Create symbolic operands */
18308 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18309 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18310
18311 /* Create the semantics */
18312 std::vector<triton::ast::SharedAbstractNode> pck;
18313 pck.reserve(dst.getSize() / triton::size::word);
18314
18315 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
18316 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
18318 pck.push_back(this->astCtxt->bvsub(
18319 this->astCtxt->extract(high, low, op1),
18320 this->astCtxt->extract(high, low, op2))
18321 );
18322 }
18323
18324 auto node = this->astCtxt->concat(pck);
18325
18326 /* Create symbolic expression */
18327 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSUBW operation");
18328
18329 /* Apply the taint */
18330 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18331
18332 /* Update the symbolic control flow */
18333 this->controlFlow_s(inst);
18334 }
18335
18336
18337 void x86Semantics::vptest_s(triton::arch::Instruction& inst) {
18338 auto& src1 = inst.operands[0];
18339 auto& src2 = inst.operands[1];
18340
18341 /* Create symbolic operands */
18342 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18343 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18344
18345 /* Create the semantics */
18346 auto node1 = this->astCtxt->bvand(op1, op2);
18347 auto node2 = this->astCtxt->bvand(op1, this->astCtxt->bvnot(op2));
18348
18349 /* Create symbolic expression */
18350 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "VPTEST operation");
18351 auto expr2 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node2, "VPTEST operation");
18352
18353 /* Spread taint */
18354 expr1->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2);
18355 expr2->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2);
18356
18357 /* Update symbolic flags */
18358 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_AF), "Clears adjust flag");
18359 this->cfPtest_s(inst, expr2, src1, true);
18360 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
18361 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_PF), "Clears parity flag");
18362 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_SF), "Clears sign flag");
18363 this->zf_s(inst, expr1, src1, true);
18364
18365 /* Update the symbolic control flow */
18366 this->controlFlow_s(inst);
18367 }
18368
18369
18370 void x86Semantics::vpunpckhbw_s(triton::arch::Instruction& inst) {
18371 auto& dst = inst.operands[0];
18372 auto& src1 = inst.operands[1];
18373 auto& src2 = inst.operands[2];
18374
18375 /* Create symbolic operands */
18376 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18377 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18378
18379 /* Create the semantics */
18380 std::vector<triton::ast::SharedAbstractNode> unpack;
18381 unpack.reserve(dst.getSize());
18382
18383 uint32 start_index = dst.getBitSize();
18384 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
18385 start_index -= k * triton::bitsize::dqword;
18387 uint32 high = (start_index - 1) - (i * triton::bitsize::byte);
18388 uint32 low = (start_index - triton::bitsize::byte) - (i * triton::bitsize::byte);
18389 unpack.push_back(this->astCtxt->extract(high, low, op2));
18390 unpack.push_back(this->astCtxt->extract(high, low, op1));
18391 }
18392 }
18393
18394 auto node = this->astCtxt->concat(unpack);
18395
18396 /* Create symbolic expression */
18397 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPUNPCKHBW operation");
18398
18399 /* Apply the taint */
18400 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18401
18402 /* Update the symbolic control flow */
18403 this->controlFlow_s(inst);
18404 }
18405
18406
18407 void x86Semantics::vpunpckhdq_s(triton::arch::Instruction& inst) {
18408 auto& dst = inst.operands[0];
18409 auto& src1 = inst.operands[1];
18410 auto& src2 = inst.operands[2];
18411
18412 /* Create symbolic operands */
18413 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18414 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18415
18416 /* Create the semantics */
18417 std::vector<triton::ast::SharedAbstractNode> unpack;
18418 unpack.reserve(dst.getSize() / triton::size::dword);
18419
18420 uint32 start_index = dst.getBitSize();
18421 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
18422 start_index -= k * triton::bitsize::dqword;
18424 uint32 high = (start_index - 1) - (i * triton::bitsize::dword);
18425 uint32 low = (start_index - triton::bitsize::dword) - (i * triton::bitsize::dword);
18426 unpack.push_back(this->astCtxt->extract(high, low, op2));
18427 unpack.push_back(this->astCtxt->extract(high, low, op1));
18428 }
18429 }
18430
18431 auto node = this->astCtxt->concat(unpack);
18432
18433 /* Create symbolic expression */
18434 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPUNPCKHDQ operation");
18435
18436 /* Apply the taint */
18437 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18438
18439 /* Update the symbolic control flow */
18440 this->controlFlow_s(inst);
18441 }
18442
18443
18444 void x86Semantics::vpunpckhqdq_s(triton::arch::Instruction& inst) {
18445 auto& dst = inst.operands[0];
18446 auto& src1 = inst.operands[1];
18447 auto& src2 = inst.operands[2];
18448
18449 /* Create symbolic operands */
18450 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18451 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18452
18453 /* Create the semantics */
18454 std::vector<triton::ast::SharedAbstractNode> unpack;
18455 unpack.reserve(dst.getSize() / triton::size::qword);
18456
18457 uint32 start_index = dst.getBitSize();
18458 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
18459 start_index -= k * triton::bitsize::dqword;
18461 uint32 high = (start_index - 1) - (i * triton::bitsize::qword);
18462 uint32 low = (start_index - triton::bitsize::qword) - (i * triton::bitsize::qword);
18463 unpack.push_back(this->astCtxt->extract(high, low, op2));
18464 unpack.push_back(this->astCtxt->extract(high, low, op1));
18465 }
18466 }
18467
18468 auto node = this->astCtxt->concat(unpack);
18469
18470 /* Create symbolic expression */
18471 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPUNPCKHQDQ operation");
18472
18473 /* Apply the taint */
18474 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18475
18476 /* Update the symbolic control flow */
18477 this->controlFlow_s(inst);
18478 }
18479
18480
18481 void x86Semantics::vpunpckhwd_s(triton::arch::Instruction& inst) {
18482 auto& dst = inst.operands[0];
18483 auto& src1 = inst.operands[1];
18484 auto& src2 = inst.operands[2];
18485
18486 /* Create symbolic operands */
18487 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18488 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18489
18490 /* Create the semantics */
18491 std::vector<triton::ast::SharedAbstractNode> unpack;
18492 unpack.reserve(dst.getSize() / triton::size::word);
18493
18494 uint32 start_index = dst.getBitSize();
18495 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
18496 start_index -= k * triton::bitsize::dqword;
18498 uint32 high = (start_index - 1) - (i * triton::bitsize::word);
18499 uint32 low = (start_index - triton::bitsize::word) - (i * triton::bitsize::word);
18500 unpack.push_back(this->astCtxt->extract(high, low, op2));
18501 unpack.push_back(this->astCtxt->extract(high, low, op1));
18502 }
18503 }
18504
18505 auto node = this->astCtxt->concat(unpack);
18506
18507 /* Create symbolic expression */
18508 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPUNPCKHWD operation");
18509
18510 /* Apply the taint */
18511 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18512
18513 /* Update the symbolic control flow */
18514 this->controlFlow_s(inst);
18515 }
18516
18517
18518 void x86Semantics::vpunpcklbw_s(triton::arch::Instruction& inst) {
18519 auto& dst = inst.operands[0];
18520 auto& src1 = inst.operands[1];
18521 auto& src2 = inst.operands[2];
18522
18523 /* Create symbolic operands */
18524 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18525 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18526
18527 /* Create the semantics */
18528 std::vector<triton::ast::SharedAbstractNode> unpack;
18529 unpack.reserve(dst.getSize());
18530
18531 uint32 start_index = dst.getBitSize() - triton::bitsize::qword;
18532 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
18533 start_index -= k * triton::bitsize::dqword;
18535 uint32 high = (start_index - 1) - (i * triton::bitsize::byte);
18536 uint32 low = (start_index - triton::bitsize::byte) - (i * triton::bitsize::byte);
18537 unpack.push_back(this->astCtxt->extract(high, low, op2));
18538 unpack.push_back(this->astCtxt->extract(high, low, op1));
18539 }
18540 }
18541
18542 auto node = this->astCtxt->concat(unpack);
18543
18544 /* Create symbolic expression */
18545 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPUNPCKLBW operation");
18546
18547 /* Apply the taint */
18548 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18549
18550 /* Update the symbolic control flow */
18551 this->controlFlow_s(inst);
18552 }
18553
18554
18555 void x86Semantics::vpunpckldq_s(triton::arch::Instruction& inst) {
18556 auto& dst = inst.operands[0];
18557 auto& src1 = inst.operands[1];
18558 auto& src2 = inst.operands[2];
18559
18560 /* Create symbolic operands */
18561 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18562 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18563
18564 /* Create the semantics */
18565 std::vector<triton::ast::SharedAbstractNode> unpack;
18566 unpack.reserve(dst.getSize() / triton::size::dword);
18567
18568 uint32 start_index = dst.getBitSize() - triton::bitsize::qword;
18569 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
18570 start_index -= k * triton::bitsize::dqword;
18572 uint32 high = (start_index - 1) - (i * triton::bitsize::dword);
18573 uint32 low = (start_index - triton::bitsize::dword) - (i * triton::bitsize::dword);
18574 unpack.push_back(this->astCtxt->extract(high, low, op2));
18575 unpack.push_back(this->astCtxt->extract(high, low, op1));
18576 }
18577 }
18578
18579 auto node = this->astCtxt->concat(unpack);
18580
18581 /* Create symbolic expression */
18582 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPUNPCKLDQ operation");
18583
18584 /* Apply the taint */
18585 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18586
18587 /* Update the symbolic control flow */
18588 this->controlFlow_s(inst);
18589 }
18590
18591
18592 void x86Semantics::vpunpcklqdq_s(triton::arch::Instruction& inst) {
18593 auto& dst = inst.operands[0];
18594 auto& src1 = inst.operands[1];
18595 auto& src2 = inst.operands[2];
18596
18597 /* Create symbolic operands */
18598 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18599 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18600
18601 /* Create the semantics */
18602 std::vector<triton::ast::SharedAbstractNode> unpack;
18603 unpack.reserve(dst.getSize() / triton::size::qword);
18604
18605 uint32 start_index = dst.getBitSize() - triton::bitsize::qword;
18606 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
18607 start_index -= k * triton::bitsize::dqword;
18609 uint32 high = (start_index - 1) - (i * triton::bitsize::qword);
18610 uint32 low = (start_index - triton::bitsize::qword) - (i * triton::bitsize::qword);
18611 unpack.push_back(this->astCtxt->extract(high, low, op2));
18612 unpack.push_back(this->astCtxt->extract(high, low, op1));
18613 }
18614 }
18615
18616 auto node = this->astCtxt->concat(unpack);
18617
18618 /* Create symbolic expression */
18619 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPUNPCKLQDQ operation");
18620
18621 /* Apply the taint */
18622 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18623
18624 /* Update the symbolic control flow */
18625 this->controlFlow_s(inst);
18626 }
18627
18628
18629 void x86Semantics::vpunpcklwd_s(triton::arch::Instruction& inst) {
18630 auto& dst = inst.operands[0];
18631 auto& src1 = inst.operands[1];
18632 auto& src2 = inst.operands[2];
18633
18634 /* Create symbolic operands */
18635 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18636 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18637
18638 /* Create the semantics */
18639 std::vector<triton::ast::SharedAbstractNode> unpack;
18640 unpack.reserve(dst.getSize() / triton::size::word);
18641
18642 uint32 start_index = dst.getBitSize() - triton::bitsize::qword;
18643 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
18644 start_index -= k * triton::bitsize::dqword;
18646 uint32 high = (start_index - 1) - (i * triton::bitsize::word);
18647 uint32 low = (start_index - triton::bitsize::word) - (i * triton::bitsize::word);
18648 unpack.push_back(this->astCtxt->extract(high, low, op2));
18649 unpack.push_back(this->astCtxt->extract(high, low, op1));
18650 }
18651 }
18652
18653 auto node = this->astCtxt->concat(unpack);
18654
18655 /* Create symbolic expression */
18656 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPUNPCKLWD operation");
18657
18658 /* Apply the taint */
18659 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18660
18661 /* Update the symbolic control flow */
18662 this->controlFlow_s(inst);
18663 }
18664
18665
18666 void x86Semantics::vpxor_s(triton::arch::Instruction& inst) {
18667 auto& dst = inst.operands[0];
18668 auto& src1 = inst.operands[1];
18669 auto& src2 = inst.operands[2];
18670
18671 /* Create symbolic operands */
18672 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
18673 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
18674
18675 /* Create the semantics */
18676 auto node = this->astCtxt->bvxor(op2, op3);
18677
18678 /* Create symbolic expression */
18679 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPXOR operation");
18680
18681 /* Spread taint */
18682 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18683
18684 /* Update the symbolic control flow */
18685 this->controlFlow_s(inst);
18686 }
18687
18688
18689 void x86Semantics::vxorps_s(triton::arch::Instruction& inst) {
18690 auto& dst = inst.operands[0];
18691 auto& src1 = inst.operands[1];
18692 auto& src2 = inst.operands[2];
18693
18694 /* Create symbolic operands */
18695 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18696 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18697
18698 /* Create the semantics */
18699 auto node = this->astCtxt->bvxor(op1, op2);
18700
18701 /* Create symbolic expression */
18702 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VXORPS operation");
18703
18704 /* Apply the taint */
18705 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18706
18707 /* Update the symbolic control flow */
18708 this->controlFlow_s(inst);
18709 }
18710
18711
18712 void x86Semantics::wait_s(triton::arch::Instruction& inst) {
18713 /* Update the symbolic control flow */
18714 this->controlFlow_s(inst);
18715 }
18716
18717
18718 void x86Semantics::wbinvd_s(triton::arch::Instruction& inst) {
18719 /* Update the symbolic control flow */
18720 this->controlFlow_s(inst);
18721 }
18722
18723
18724 void x86Semantics::xadd_s(triton::arch::Instruction& inst) {
18725 auto& dst = inst.operands[0];
18726 auto& src = inst.operands[1];
18727 bool dstT = this->taintEngine->isTainted(dst);
18728
18729 /* Create symbolic operands */
18730 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
18731 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
18732
18733 /* Create the semantics */
18734 auto node = this->astCtxt->bvadd(op1, op2);
18735
18736 /* Create symbolic expression */
18737 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, op1, src, "XADD operation");
18738 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "XADD operation");
18739
18740 /* Spread taint */
18741 expr2->isTainted = this->taintEngine->taintUnion(dst, src);
18742 expr1->isTainted = this->taintEngine->setTaint(src, dstT);
18743
18744 /* Update symbolic flags */
18745 this->af_s(inst, expr2, dst, op1, op2);
18746 this->cfAdd_s(inst, expr2, dst, op1, op2);
18747 this->ofAdd_s(inst, expr2, dst, op1, op2);
18748 this->pf_s(inst, expr2, dst);
18749 this->sf_s(inst, expr2, dst);
18750 this->zf_s(inst, expr2, dst);
18751
18752 /* Update the symbolic control flow */
18753 this->controlFlow_s(inst);
18754 }
18755
18756
18757 void x86Semantics::xchg_s(triton::arch::Instruction& inst) {
18758 auto& dst = inst.operands[0];
18759 auto& src = inst.operands[1];
18760 bool dstT = this->taintEngine->isTainted(dst);
18761 bool srcT = this->taintEngine->isTainted(src);
18762
18763 /* Create symbolic operands */
18764 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
18765 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
18766
18767 /* Create the semantics */
18768 auto node1 = op2;
18769 auto node2 = op1;
18770
18771 /* Create symbolic expression */
18772 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "XCHG operation");
18773 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, src, "XCHG operation");
18774
18775 /* Spread taint */
18776 expr1->isTainted = this->taintEngine->setTaint(dst, srcT);
18777 expr2->isTainted = this->taintEngine->setTaint(src, dstT);
18778
18779 /* Update the symbolic control flow */
18780 this->controlFlow_s(inst);
18781 }
18782
18783
18784 void x86Semantics::xor_s(triton::arch::Instruction& inst) {
18785 auto& dst = inst.operands[0];
18786 auto& src = inst.operands[1];
18787
18788 /* Create symbolic operands */
18789 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
18790 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
18791
18792 /* Create the semantics */
18793 auto node = this->astCtxt->bvxor(op1, op2);
18794
18795 /* Create symbolic expression */
18796 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "XOR operation");
18797
18798 /* Spread taint */
18799 /* clear taint if the registers are the same */
18800 if (dst.getType() == OP_REG && src.getRegister() == dst.getRegister())
18801 this->taintEngine->setTaint(src, false);
18802 else
18803 expr->isTainted = this->taintEngine->taintUnion(dst, src);
18804
18805 /* Update symbolic flags */
18806 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
18807 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag");
18808 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
18809 this->pf_s(inst, expr, dst);
18810 this->sf_s(inst, expr, dst);
18811 this->zf_s(inst, expr, dst);
18812
18813 /* Update the symbolic control flow */
18814 this->controlFlow_s(inst);
18815 }
18816
18817
18818 void x86Semantics::xorpd_s(triton::arch::Instruction& inst) {
18819 auto& dst = inst.operands[0];
18820 auto& src = inst.operands[1];
18821
18822 /* Create symbolic operands */
18823 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
18824 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
18825
18826 /* Create the semantics */
18827 auto node = this->astCtxt->bvxor(op1, op2);
18828
18829 /* Create symbolic expression */
18830 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "XORPD operation");
18831
18832 /* Spread taint */
18833 expr->isTainted = this->taintEngine->taintUnion(dst, src);
18834
18835 /* Update the symbolic control flow */
18836 this->controlFlow_s(inst);
18837 }
18838
18839
18840 void x86Semantics::xorps_s(triton::arch::Instruction& inst) {
18841 auto& dst = inst.operands[0];
18842 auto& src = inst.operands[1];
18843
18844 /* Create symbolic operands */
18845 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
18846 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
18847
18848 /* Create the semantics */
18849 auto node = this->astCtxt->bvxor(op1, op2);
18850
18851 /* Create symbolic expression */
18852 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "XORPS operation");
18853
18854 /* Spread taint */
18855 expr->isTainted = this->taintEngine->taintUnion(dst, src);
18856
18857 /* Update the symbolic control flow */
18858 this->controlFlow_s(inst);
18859 }
18860
18861 }; /* x86 namespace */
18862 }; /* arch namespace */
18863}; /* triton namespace */
The abstract architecture class.
TRITON_EXPORT const triton::arch::Register & getRegister(triton::arch::register_e id) const
Returns register from id.
TRITON_EXPORT const triton::arch::Register & getStackPointer(void) const
Returns the stack pointer register.
TRITON_EXPORT const triton::arch::Register & getProgramCounter(void) const
Returns the program counter register.
TRITON_EXPORT triton::uint512 getConcreteRegisterValue(const triton::arch::Register &reg, bool execCallbacks=true) const
Returns the concrete value of a register.
TRITON_EXPORT bool isRegisterValid(triton::arch::register_e regId) const
Returns true if the register ID is a register or a flag.
TRITON_EXPORT triton::arch::architecture_e getArchitecture(void) const
Returns the kind of architecture as triton::arch::architecture_e.
TRITON_EXPORT const triton::arch::Register & getParentRegister(triton::arch::register_e id) const
Returns parent register from id.
This class is used to represent an immediate.
Definition immediate.hpp:37
This class is used to represent an instruction.
TRITON_EXPORT triton::uint32 getSize(void) const
Returns the size of the instruction.
TRITON_EXPORT void setConditionTaken(bool flag)
Sets flag to define if the condition is taken or not.
TRITON_EXPORT void setPrefix(triton::arch::x86::prefix_e prefix)
Sets the prefix of the instruction (mainly for X86).
TRITON_EXPORT triton::uint32 getType(void) const
Returns the type of the instruction.
TRITON_EXPORT void removeReadRegister(const triton::arch::Register &reg)
Removes a read register.
TRITON_EXPORT triton::uint64 getAddress(void) const
Returns the address of the instruction.
TRITON_EXPORT void setUndefinedRegister(const triton::arch::Register &reg)
Sets an undefined register.
std::vector< triton::arch::OperandWrapper > operands
A list of operands.
TRITON_EXPORT void removeWrittenRegister(const triton::arch::Register &reg)
Removes a written register.
TRITON_EXPORT triton::arch::x86::prefix_e getPrefix(void) const
Returns the prefix of the instruction (mainly for X86).
TRITON_EXPORT triton::uint64 getNextAddress(void) const
Returns the next address of the instruction.
This class is used to represent a memory access.
TRITON_EXPORT const triton::arch::Register & getConstBaseRegister(void) const
LEA - Returns the base register operand.
TRITON_EXPORT triton::uint64 getAddress(void) const
Returns the address of the memory.
This class is used as operand wrapper.
TRITON_EXPORT triton::arch::Register & getRegister(void)
Returns the register operand.
TRITON_EXPORT triton::uint32 getLow(void) const
Returns the lower bit position of the abstract operand.
TRITON_EXPORT triton::arch::operand_e getType(void) const
Returns the abstract type of the operand.
TRITON_EXPORT triton::uint32 getSize(void) const
Returns the abstract size (in bytes) of the operand.
TRITON_EXPORT triton::arch::MemoryAccess & getMemory(void)
Returns the memory operand.
TRITON_EXPORT const triton::arch::Register & getConstRegister(void) const
Returns the register operand.
TRITON_EXPORT triton::uint32 getHigh(void) const
Returns the highest bit position of the abstract operand.
TRITON_EXPORT triton::uint32 getBitSize(void) const
Returns the abstract size (in bits) of the operand.
This class is used when an instruction has a register operand.
Definition register.hpp:44
TRITON_EXPORT triton::arch::register_e getId(void) const
Returns the id of the register.
Definition register.cpp:53
TRITON_EXPORT triton::uint32 getSize(void) const
Returns the size (in bytes) of the register.
Definition register.cpp:68
TRITON_EXPORT x86Semantics(triton::arch::Architecture *architecture, triton::engines::symbolic::SymbolicEngine *symbolicEngine, triton::engines::taint::TaintEngine *taintEngine, const triton::modes::SharedModes &modes, const triton::ast::SharedAstContext &astCtxt)
Constructor.
TRITON_EXPORT triton::arch::exception_e buildSemantics(triton::arch::Instruction &inst)
Builds the semantics of the instruction. Returns triton::arch::NO_FAULT if succeed.
TRITON_EXPORT void pushPathConstraint(const triton::arch::Instruction &inst, const triton::engines::symbolic::SharedSymbolicExpression &expr)
Pushs constraints of a branch instruction to the path predicate.
TRITON_EXPORT const SharedSymbolicExpression & createSymbolicRegisterExpression(triton::arch::Instruction &inst, const triton::ast::SharedAbstractNode &node, const triton::arch::Register &reg, const std::string &comment="")
Returns the new symbolic register expression expression and links this expression to the instruction.
TRITON_EXPORT const SharedSymbolicExpression & createSymbolicVolatileExpression(triton::arch::Instruction &inst, const triton::ast::SharedAbstractNode &node, const std::string &comment="")
Returns the new symbolic volatile expression expression and links this expression to the instruction.
TRITON_EXPORT void initLeaAst(triton::arch::MemoryAccess &mem, bool force=true)
Initializes the effective address of a memory access.
TRITON_EXPORT triton::ast::SharedAbstractNode getRegisterAst(const triton::arch::Register &reg)
Returns the AST corresponding to the register.
TRITON_EXPORT const SharedSymbolicExpression & createSymbolicExpression(triton::arch::Instruction &inst, const triton::ast::SharedAbstractNode &node, const triton::arch::OperandWrapper &dst, const std::string &comment="")
Returns the new symbolic expression and links this expression to the instruction.
TRITON_EXPORT triton::ast::SharedAbstractNode getImmediateAst(const triton::arch::Immediate &imm)
Returns the AST corresponding to the immediate.
TRITON_EXPORT void concretizeRegister(const triton::arch::Register &reg)
Concretizes a specific symbolic register.
TRITON_EXPORT triton::ast::SharedAbstractNode getOperandAst(const triton::arch::OperandWrapper &op)
Returns the AST corresponding to the operand.
TRITON_EXPORT bool setTaint(const triton::arch::OperandWrapper &op, bool flag)
Sets the flag (taint or untaint) to an abstract operand (Register or Memory).
TRITON_EXPORT bool untaintMemory(triton::uint64 addr)
Untaints an address. Returns !TAINTED if the address has been untainted correctly....
TRITON_EXPORT bool isTainted(const triton::arch::OperandWrapper &op) const
Abstract taint verification. Returns true if the operand is tainted.
TRITON_EXPORT bool taintUnion(const triton::arch::OperandWrapper &op1, const triton::arch::OperandWrapper &op2)
Abstract union tainting.
TRITON_EXPORT bool setTaintRegister(const triton::arch::Register &reg, bool flag)
Sets the flag (taint or untaint) to a register.
TRITON_EXPORT bool taintAssignment(const triton::arch::OperandWrapper &op1, const triton::arch::OperandWrapper &op2)
Abstract assignment tainting.
TRITON_EXPORT bool isRegisterTainted(const triton::arch::Register &reg) const
Returns true if the register is tainted.
The exception class used by all semantics.
std::shared_ptr< triton::ast::AbstractNode > SharedAbstractNode
Shared Abstract Node.
Definition ast.hpp:59
std::shared_ptr< triton::ast::AstContext > SharedAstContext
Shared AST context.
Definition ast.hpp:65
constexpr triton::uint32 byte
byte size in bit
Definition cpuSize.hpp:60
constexpr triton::uint32 dword
dword size in bit
Definition cpuSize.hpp:64
constexpr triton::uint32 qword
qword size in bit
Definition cpuSize.hpp:66
constexpr triton::uint32 word
word size in bit
Definition cpuSize.hpp:62
constexpr triton::uint32 dqword
dqword size in bit
Definition cpuSize.hpp:70
constexpr triton::uint32 qqword
qqword size in bit
Definition cpuSize.hpp:72
std::shared_ptr< triton::modes::Modes > SharedModes
Shared Modes.
Definition modes.hpp:66
@ CONCRETIZE_UNDEFINED_REGISTERS
[symbolic] Concretize every registers tagged as undefined (see #750).
constexpr triton::uint32 dword
dword size in byte
Definition cpuSize.hpp:34
constexpr triton::uint32 word
word size in byte
Definition cpuSize.hpp:32
constexpr triton::uint32 dqword
dqword size in byte
Definition cpuSize.hpp:40
constexpr triton::uint32 byte
byte size in byte
Definition cpuSize.hpp:30
constexpr triton::uint32 qword
qword size in byte
Definition cpuSize.hpp:36
constexpr triton::uint32 qqword
qqword size in byte
Definition cpuSize.hpp:42
std::shared_ptr< triton::engines::symbolic::SymbolicExpression > SharedSymbolicExpression
Shared Symbolic Expression.
Definition ast.hpp:40
const bool UNTAINTED
Defines an untainted item.
std::uint64_t uint64
unisgned 64-bits
std::uint32_t uint32
unisgned 32-bits
std::uint8_t uint8
unisgned 8-bits
@ ID_INS_VPBROADCASTB
VPBROADCASTB.
@ ID_INS_VPUNPCKHQDQ
VPUNPCKHQDQ.
@ ID_INS_PREFETCHT2
PREFETCHT2.
@ ID_INS_PREFETCHNTA
PREFETCHNTA.
@ ID_INS_PUNPCKLQDQ
PUNPCKLQDQ.
@ ID_INS_PREFETCHT0
PREFETCHT0.
@ ID_INS_CMPXCHG16B
CMPXCHG16B.
@ ID_INS_VEXTRACTI128
VEXTRACTI128.
@ ID_INS_VPUNPCKLQDQ
VPUNPCKLQDQ.
@ ID_INS_PREFETCHT1
PREFETCHT1.
@ ID_INS_PUNPCKHQDQ
PUNPCKHQDQ.
@ ID_PREFIX_REPNE
REPNE.
@ ID_PREFIX_INVALID
invalid
The Triton namespace.