libTriton version 1.0 build 1590
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
420namespace triton {
421 namespace arch {
422 namespace x86 {
423
427 const triton::modes::SharedModes& modes,
428 const triton::ast::SharedAstContext& astCtxt) : modes(modes), astCtxt(astCtxt) {
429
430 this->architecture = architecture;
431 this->exception = triton::arch::NO_FAULT;
432 this->symbolicEngine = symbolicEngine;
433 this->taintEngine = taintEngine;
434
435 if (architecture == nullptr)
436 throw triton::exceptions::Semantics("x86Semantics::x86Semantics(): The architecture API must be defined.");
437
438 if (this->symbolicEngine == nullptr)
439 throw triton::exceptions::Semantics("x86Semantics::x86Semantics(): The symbolic engine API must be defined.");
440
441 if (this->taintEngine == nullptr)
442 throw triton::exceptions::Semantics("x86Semantics::x86Semantics(): The taint engines API must be defined.");
443 }
444
445
447 this->exception = triton::arch::NO_FAULT;
448 switch (inst.getType()) {
449 case ID_INS_AAA: this->aaa_s(inst); break;
450 case ID_INS_AAD: this->aad_s(inst); break;
451 case ID_INS_AAM: this->aam_s(inst); break;
452 case ID_INS_AAS: this->aas_s(inst); break;
453 case ID_INS_ADC: this->adc_s(inst); break;
454 case ID_INS_ADCX: this->adcx_s(inst); break;
455 case ID_INS_ADD: this->add_s(inst); break;
456 case ID_INS_AND: this->and_s(inst); break;
457 case ID_INS_ANDN: this->andn_s(inst); break;
458 case ID_INS_ANDNPD: this->andnpd_s(inst); break;
459 case ID_INS_ANDNPS: this->andnps_s(inst); break;
460 case ID_INS_ANDPD: this->andpd_s(inst); break;
461 case ID_INS_ANDPS: this->andps_s(inst); break;
462 case ID_INS_BEXTR: this->bextr_s(inst); break;
463 case ID_INS_BLSI: this->blsi_s(inst); break;
464 case ID_INS_BLSMSK: this->blsmsk_s(inst); break;
465 case ID_INS_BLSR: this->blsr_s(inst); break;
466 case ID_INS_BSF: this->bsf_s(inst); break;
467 case ID_INS_BSR: this->bsr_s(inst); break;
468 case ID_INS_BSWAP: this->bswap_s(inst); break;
469 case ID_INS_BT: this->bt_s(inst); break;
470 case ID_INS_BTC: this->btc_s(inst); break;
471 case ID_INS_BTR: this->btr_s(inst); break;
472 case ID_INS_BTS: this->bts_s(inst); break;
473 case ID_INS_CALL: this->call_s(inst); break;
474 case ID_INS_CBW: this->cbw_s(inst); break;
475 case ID_INS_CDQ: this->cdq_s(inst); break;
476 case ID_INS_CDQE: this->cdqe_s(inst); break;
477 case ID_INS_CLC: this->clc_s(inst); break;
478 case ID_INS_CLD: this->cld_s(inst); break;
479 case ID_INS_CLFLUSH: this->clflush_s(inst); break;
480 case ID_INS_CLTS: this->clts_s(inst); break;
481 case ID_INS_CLI: this->cli_s(inst); break;
482 case ID_INS_CMC: this->cmc_s(inst); break;
483 case ID_INS_CMOVA: this->cmova_s(inst); break;
484 case ID_INS_CMOVAE: this->cmovae_s(inst); break;
485 case ID_INS_CMOVB: this->cmovb_s(inst); break;
486 case ID_INS_CMOVBE: this->cmovbe_s(inst); break;
487 case ID_INS_CMOVE: this->cmove_s(inst); break;
488 case ID_INS_CMOVG: this->cmovg_s(inst); break;
489 case ID_INS_CMOVGE: this->cmovge_s(inst); break;
490 case ID_INS_CMOVL: this->cmovl_s(inst); break;
491 case ID_INS_CMOVLE: this->cmovle_s(inst); break;
492 case ID_INS_CMOVNE: this->cmovne_s(inst); break;
493 case ID_INS_CMOVNO: this->cmovno_s(inst); break;
494 case ID_INS_CMOVNP: this->cmovnp_s(inst); break;
495 case ID_INS_CMOVNS: this->cmovns_s(inst); break;
496 case ID_INS_CMOVO: this->cmovo_s(inst); break;
497 case ID_INS_CMOVP: this->cmovp_s(inst); break;
498 case ID_INS_CMOVS: this->cmovs_s(inst); break;
499 case ID_INS_CMP: this->cmp_s(inst); break;
500 case ID_INS_CMPSB: this->cmpsb_s(inst); break;
501 case ID_INS_CMPSD: this->cmpsd_s(inst); break;
502 case ID_INS_CMPSQ: this->cmpsq_s(inst); break;
503 case ID_INS_CMPSW: this->cmpsw_s(inst); break;
504 case ID_INS_CMPXCHG: this->cmpxchg_s(inst); break;
505 case ID_INS_CMPXCHG16B: this->cmpxchg16b_s(inst); break;
506 case ID_INS_CMPXCHG8B: this->cmpxchg8b_s(inst); break;
507 case ID_INS_CPUID: this->cpuid_s(inst); break;
508 case ID_INS_CQO: this->cqo_s(inst); break;
509 case ID_INS_CWD: this->cwd_s(inst); break;
510 case ID_INS_CWDE: this->cwde_s(inst); break;
511 case ID_INS_DEC: this->dec_s(inst); break;
512 case ID_INS_DIV: this->div_s(inst); break;
513 case ID_INS_ENDBR32: this->endbr32_s(inst); break;
514 case ID_INS_ENDBR64: this->endbr64_s(inst); break;
515 case ID_INS_EXTRACTPS: this->extractps_s(inst); break;
516 case ID_INS_FXRSTOR64: this->fxrstor64_s(inst); break;
517 case ID_INS_FXRSTOR: this->fxrstor_s(inst); break;
518 case ID_INS_FXSAVE64: this->fxsave64_s(inst); break;
519 case ID_INS_FXSAVE: this->fxsave_s(inst); break;
520 case ID_INS_IDIV: this->idiv_s(inst); break;
521 case ID_INS_IMUL: this->imul_s(inst); break;
522 case ID_INS_INC: this->inc_s(inst); break;
523 case ID_INS_INVD: this->invd_s(inst); break;
524 case ID_INS_INVLPG: this->invlpg_s(inst); break;
525 case ID_INS_JA: this->ja_s(inst); break;
526 case ID_INS_JAE: this->jae_s(inst); break;
527 case ID_INS_JB: this->jb_s(inst); break;
528 case ID_INS_JBE: this->jbe_s(inst); break;
529 case ID_INS_JCXZ: this->jcxz_s(inst); break;
530 case ID_INS_JE: this->je_s(inst); break;
531 case ID_INS_JECXZ: this->jecxz_s(inst); break;
532 case ID_INS_JG: this->jg_s(inst); break;
533 case ID_INS_JGE: this->jge_s(inst); break;
534 case ID_INS_JL: this->jl_s(inst); break;
535 case ID_INS_JLE: this->jle_s(inst); break;
536 case ID_INS_JMP: this->jmp_s(inst); break;
537 case ID_INS_JNE: this->jne_s(inst); break;
538 case ID_INS_JNO: this->jno_s(inst); break;
539 case ID_INS_JNP: this->jnp_s(inst); break;
540 case ID_INS_JNS: this->jns_s(inst); break;
541 case ID_INS_JO: this->jo_s(inst); break;
542 case ID_INS_JP: this->jp_s(inst); break;
543 case ID_INS_JRCXZ: this->jrcxz_s(inst); break;
544 case ID_INS_JS: this->js_s(inst); break;
545 case ID_INS_LAHF: this->lahf_s(inst); break;
546 case ID_INS_LDDQU: this->lddqu_s(inst); break;
547 case ID_INS_LDMXCSR: this->ldmxcsr_s(inst); break;
548 case ID_INS_LEA: this->lea_s(inst); break;
549 case ID_INS_LEAVE: this->leave_s(inst); break;
550 case ID_INS_LFENCE: this->lfence_s(inst); break;
551 case ID_INS_LODSB: this->lodsb_s(inst); break;
552 case ID_INS_LODSD: this->lodsd_s(inst); break;
553 case ID_INS_LODSQ: this->lodsq_s(inst); break;
554 case ID_INS_LODSW: this->lodsw_s(inst); break;
555 case ID_INS_LOOP: this->loop_s(inst); break;
556 case ID_INS_LZCNT: this->lzcnt_s(inst); break;
557 case ID_INS_INT3: this->int3_s(inst); break;
558 case ID_INS_MFENCE: this->mfence_s(inst); break;
559 case ID_INS_MOV: this->mov_s(inst); break;
560 case ID_INS_MOVABS: this->movabs_s(inst); break;
561 case ID_INS_MOVAPD: this->movapd_s(inst); break;
562 case ID_INS_MOVAPS: this->movaps_s(inst); break;
563 case ID_INS_MOVBE: this->movbe_s(inst); break;
564 case ID_INS_MOVD: this->movd_s(inst); break;
565 case ID_INS_MOVDDUP: this->movddup_s(inst); break;
566 case ID_INS_MOVDQ2Q: this->movdq2q_s(inst); break;
567 case ID_INS_MOVDQA: this->movdqa_s(inst); break;
568 case ID_INS_MOVDQU: this->movdqu_s(inst); break;
569 case ID_INS_MOVHLPS: this->movhlps_s(inst); break;
570 case ID_INS_MOVHPD: this->movhpd_s(inst); break;
571 case ID_INS_MOVHPS: this->movhps_s(inst); break;
572 case ID_INS_MOVLHPS: this->movlhps_s(inst); break;
573 case ID_INS_MOVLPD: this->movlpd_s(inst); break;
574 case ID_INS_MOVLPS: this->movlps_s(inst); break;
575 case ID_INS_MOVMSKPD: this->movmskpd_s(inst); break;
576 case ID_INS_MOVMSKPS: this->movmskps_s(inst); break;
577 case ID_INS_MOVNTDQ: this->movntdq_s(inst); break;
578 case ID_INS_MOVNTI: this->movnti_s(inst); break;
579 case ID_INS_MOVNTPD: this->movntpd_s(inst); break;
580 case ID_INS_MOVNTPS: this->movntps_s(inst); break;
581 case ID_INS_MOVNTQ: this->movntq_s(inst); break;
582 case ID_INS_MOVQ2DQ: this->movq2dq_s(inst); break;
583 case ID_INS_MOVQ: this->movq_s(inst); break;
584 case ID_INS_MOVSB: this->movsb_s(inst); break;
585 case ID_INS_MOVSD: this->movsd_s(inst); break;
586 case ID_INS_MOVSHDUP: this->movshdup_s(inst); break;
587 case ID_INS_MOVSLDUP: this->movsldup_s(inst); break;
588 case ID_INS_MOVUPD: this->movupd_s(inst); break;
589 case ID_INS_MOVUPS: this->movups_s(inst); break;
590 case ID_INS_MOVSS: this->movss_s(inst); break;
591 case ID_INS_MOVSQ: this->movsq_s(inst); break;
592 case ID_INS_MOVSW: this->movsw_s(inst); break;
593 case ID_INS_MOVSX: this->movsx_s(inst); break;
594 case ID_INS_MOVSXD: this->movsxd_s(inst); break;
595 case ID_INS_MOVZX: this->movzx_s(inst); break;
596 case ID_INS_MUL: this->mul_s(inst); break;
597 case ID_INS_MULX: this->mulx_s(inst); break;
598 case ID_INS_NEG: this->neg_s(inst); break;
599 case ID_INS_NOP: this->nop_s(inst); break;
600 case ID_INS_NOT: this->not_s(inst); break;
601 case ID_INS_OR: this->or_s(inst); break;
602 case ID_INS_ORPD: this->orpd_s(inst); break;
603 case ID_INS_ORPS: this->orps_s(inst); break;
604 case ID_INS_PACKUSWB: this->packuswb_s(inst); break;
605 case ID_INS_PACKSSDW: this->packssdw_s(inst); break;
606 case ID_INS_PACKSSWB: this->packsswb_s(inst); break;
607 case ID_INS_PADDB: this->paddb_s(inst); break;
608 case ID_INS_PADDD: this->paddd_s(inst); break;
609 case ID_INS_PADDQ: this->paddq_s(inst); break;
610 case ID_INS_PADDW: this->paddw_s(inst); break;
611 case ID_INS_PALIGNR: this->palignr_s(inst); break;
612 case ID_INS_PAND: this->pand_s(inst); break;
613 case ID_INS_PANDN: this->pandn_s(inst); break;
614 case ID_INS_PAUSE: this->pause_s(inst); break;
615 case ID_INS_PAVGB: this->pavgb_s(inst); break;
616 case ID_INS_PAVGW: this->pavgw_s(inst); break;
617 case ID_INS_PCMPEQB: this->pcmpeqb_s(inst); break;
618 case ID_INS_PCMPEQD: this->pcmpeqd_s(inst); break;
619 case ID_INS_PCMPEQW: this->pcmpeqw_s(inst); break;
620 case ID_INS_PCMPGTB: this->pcmpgtb_s(inst); break;
621 case ID_INS_PCMPGTD: this->pcmpgtd_s(inst); break;
622 case ID_INS_PCMPGTW: this->pcmpgtw_s(inst); break;
623 case ID_INS_PEXTRB: this->pextrb_s(inst); break;
624 case ID_INS_PEXTRD: this->pextrd_s(inst); break;
625 case ID_INS_PEXTRQ: this->pextrq_s(inst); break;
626 case ID_INS_PEXTRW: this->pextrw_s(inst); break;
627 case ID_INS_PINSRB: this->pinsrb_s(inst); break;
628 case ID_INS_PINSRD: this->pinsrd_s(inst); break;
629 case ID_INS_PINSRQ: this->pinsrq_s(inst); break;
630 case ID_INS_PINSRW: this->pinsrw_s(inst); break;
631 case ID_INS_PMADDWD: this->pmaddwd_s(inst); break;
632 case ID_INS_PMAXSB: this->pmaxsb_s(inst); break;
633 case ID_INS_PMAXSD: this->pmaxsd_s(inst); break;
634 case ID_INS_PMAXSW: this->pmaxsw_s(inst); break;
635 case ID_INS_PMAXUB: this->pmaxub_s(inst); break;
636 case ID_INS_PMAXUD: this->pmaxud_s(inst); break;
637 case ID_INS_PMAXUW: this->pmaxuw_s(inst); break;
638 case ID_INS_PMINSB: this->pminsb_s(inst); break;
639 case ID_INS_PMINSD: this->pminsd_s(inst); break;
640 case ID_INS_PMINSW: this->pminsw_s(inst); break;
641 case ID_INS_PMINUB: this->pminub_s(inst); break;
642 case ID_INS_PMINUD: this->pminud_s(inst); break;
643 case ID_INS_PMINUW: this->pminuw_s(inst); break;
644 case ID_INS_PMOVMSKB: this->pmovmskb_s(inst); break;
645 case ID_INS_PMOVSXBD: this->pmovsxbd_s(inst); break;
646 case ID_INS_PMOVSXBQ: this->pmovsxbq_s(inst); break;
647 case ID_INS_PMOVSXBW: this->pmovsxbw_s(inst); break;
648 case ID_INS_PMOVSXDQ: this->pmovsxdq_s(inst); break;
649 case ID_INS_PMOVSXWD: this->pmovsxwd_s(inst); break;
650 case ID_INS_PMOVSXWQ: this->pmovsxwq_s(inst); break;
651 case ID_INS_PMOVZXBD: this->pmovzxbd_s(inst); break;
652 case ID_INS_PMOVZXBQ: this->pmovzxbq_s(inst); break;
653 case ID_INS_PMOVZXBW: this->pmovzxbw_s(inst); break;
654 case ID_INS_PMOVZXDQ: this->pmovzxdq_s(inst); break;
655 case ID_INS_PMOVZXWD: this->pmovzxwd_s(inst); break;
656 case ID_INS_PMOVZXWQ: this->pmovzxwq_s(inst); break;
657 case ID_INS_PMULHW: this->pmulhw_s(inst); break;
658 case ID_INS_PMULLD: this->pmulld_s(inst); break;
659 case ID_INS_PMULLW: this->pmullw_s(inst); break;
660 case ID_INS_PMULUDQ: this->pmuludq_s(inst); break;
661 case ID_INS_POPCNT: this->popcnt_s(inst); break;
662 case ID_INS_POP: this->pop_s(inst); break;
663 case ID_INS_POPAL: this->popal_s(inst); break;
664 case ID_INS_POPF: this->popf_s(inst); break;
665 case ID_INS_POPFD: this->popfd_s(inst); break;
666 case ID_INS_POPFQ: this->popfq_s(inst); break;
667 case ID_INS_POR: this->por_s(inst); break;
668 case ID_INS_PREFETCH: this->prefetchx_s(inst); break;
669 case ID_INS_PREFETCHNTA: this->prefetchx_s(inst); break;
670 case ID_INS_PREFETCHT0: this->prefetchx_s(inst); break;
671 case ID_INS_PREFETCHT1: this->prefetchx_s(inst); break;
672 case ID_INS_PREFETCHT2: this->prefetchx_s(inst); break;
673 case ID_INS_PREFETCHW: this->prefetchx_s(inst); break;
674 case ID_INS_PSHUFB: this->pshufb_s(inst); break;
675 case ID_INS_PSHUFD: this->pshufd_s(inst); break;
676 case ID_INS_PSHUFHW: this->pshufhw_s(inst); break;
677 case ID_INS_PSHUFLW: this->pshuflw_s(inst); break;
678 case ID_INS_PSHUFW: this->pshufw_s(inst); break;
679 case ID_INS_PSLLD: this->pslld_s(inst); break;
680 case ID_INS_PSLLDQ: this->pslldq_s(inst); break;
681 case ID_INS_PSLLQ: this->psllq_s(inst); break;
682 case ID_INS_PSLLW: this->psllw_s(inst); break;
683 case ID_INS_PSRAD: this->psrad_s(inst); break;
684 case ID_INS_PSRAW: this->psraw_s(inst); break;
685 case ID_INS_PSRLD: this->psrld_s(inst); break;
686 case ID_INS_PSRLDQ: this->psrldq_s(inst); break;
687 case ID_INS_PSRLQ: this->psrlq_s(inst); break;
688 case ID_INS_PSRLW: this->psrlw_s(inst); break;
689 case ID_INS_PSUBB: this->psubb_s(inst); break;
690 case ID_INS_PSUBD: this->psubd_s(inst); break;
691 case ID_INS_PSUBQ: this->psubq_s(inst); break;
692 case ID_INS_PSUBW: this->psubw_s(inst); break;
693 case ID_INS_PTEST: this->ptest_s(inst); break;
694 case ID_INS_PUNPCKHBW: this->punpckhbw_s(inst); break;
695 case ID_INS_PUNPCKHDQ: this->punpckhdq_s(inst); break;
696 case ID_INS_PUNPCKHQDQ: this->punpckhqdq_s(inst); break;
697 case ID_INS_PUNPCKHWD: this->punpckhwd_s(inst); break;
698 case ID_INS_PUNPCKLBW: this->punpcklbw_s(inst); break;
699 case ID_INS_PUNPCKLDQ: this->punpckldq_s(inst); break;
700 case ID_INS_PUNPCKLQDQ: this->punpcklqdq_s(inst); break;
701 case ID_INS_PUNPCKLWD: this->punpcklwd_s(inst); break;
702 case ID_INS_PUSH: this->push_s(inst); break;
703 case ID_INS_PUSHAL: this->pushal_s(inst); break;
704 case ID_INS_PUSHFD: this->pushfd_s(inst); break;
705 case ID_INS_PUSHFQ: this->pushfq_s(inst); break;
706 case ID_INS_PXOR: this->pxor_s(inst); break;
707 case ID_INS_RCL: this->rcl_s(inst); break;
708 case ID_INS_RCR: this->rcr_s(inst); break;
709 case ID_INS_RDTSC: this->rdtsc_s(inst); break;
710 case ID_INS_RET: this->ret_s(inst); break;
711 case ID_INS_ROL: this->rol_s(inst); break;
712 case ID_INS_ROR: this->ror_s(inst); break;
713 case ID_INS_RORX: this->rorx_s(inst); break;
714 case ID_INS_SAHF: this->sahf_s(inst); break;
715 case ID_INS_SAL: this->shl_s(inst); break;
716 case ID_INS_SAR: this->sar_s(inst); break;
717 case ID_INS_SARX: this->sarx_s(inst); break;
718 case ID_INS_SBB: this->sbb_s(inst); break;
719 case ID_INS_SCASB: this->scasb_s(inst); break;
720 case ID_INS_SCASD: this->scasd_s(inst); break;
721 case ID_INS_SCASQ: this->scasq_s(inst); break;
722 case ID_INS_SCASW: this->scasw_s(inst); break;
723 case ID_INS_SETA: this->seta_s(inst); break;
724 case ID_INS_SETAE: this->setae_s(inst); break;
725 case ID_INS_SETB: this->setb_s(inst); break;
726 case ID_INS_SETBE: this->setbe_s(inst); break;
727 case ID_INS_SETE: this->sete_s(inst); break;
728 case ID_INS_SETG: this->setg_s(inst); break;
729 case ID_INS_SETGE: this->setge_s(inst); break;
730 case ID_INS_SETL: this->setl_s(inst); break;
731 case ID_INS_SETLE: this->setle_s(inst); break;
732 case ID_INS_SETNE: this->setne_s(inst); break;
733 case ID_INS_SETNO: this->setno_s(inst); break;
734 case ID_INS_SETNP: this->setnp_s(inst); break;
735 case ID_INS_SETNS: this->setns_s(inst); break;
736 case ID_INS_SETO: this->seto_s(inst); break;
737 case ID_INS_SETP: this->setp_s(inst); break;
738 case ID_INS_SETS: this->sets_s(inst); break;
739 case ID_INS_SFENCE: this->sfence_s(inst); break;
740 case ID_INS_SHL: this->shl_s(inst); break;
741 case ID_INS_SHLD: this->shld_s(inst); break;
742 case ID_INS_SHLX: this->shlx_s(inst); break;
743 case ID_INS_SHR: this->shr_s(inst); break;
744 case ID_INS_SHRD: this->shrd_s(inst); break;
745 case ID_INS_SHRX: this->shrx_s(inst); break;
746 case ID_INS_STC: this->stc_s(inst); break;
747 case ID_INS_STD: this->std_s(inst); break;
748 case ID_INS_STI: this->sti_s(inst); break;
749 case ID_INS_STMXCSR: this->stmxcsr_s(inst); break;
750 case ID_INS_STOSB: this->stosb_s(inst); break;
751 case ID_INS_STOSD: this->stosd_s(inst); break;
752 case ID_INS_STOSQ: this->stosq_s(inst); break;
753 case ID_INS_STOSW: this->stosw_s(inst); break;
754 case ID_INS_SUB: this->sub_s(inst); break;
755 case ID_INS_SYSCALL: this->syscall_s(inst); break;
756 case ID_INS_SYSENTER: this->sysenter_s(inst); break;
757 case ID_INS_TEST: this->test_s(inst); break;
758 case ID_INS_TZCNT: this->tzcnt_s(inst); break;
759 case ID_INS_UNPCKHPD: this->unpckhpd_s(inst); break;
760 case ID_INS_UNPCKHPS: this->unpckhps_s(inst); break;
761 case ID_INS_UNPCKLPD: this->unpcklpd_s(inst); break;
762 case ID_INS_UNPCKLPS: this->unpcklps_s(inst); break;
763 case ID_INS_VERR: this->verr_s(inst); break;
764 case ID_INS_VERW: this->verw_s(inst); break;
765 case ID_INS_VEXTRACTI128: this->vextracti128_s(inst); break;
766 case ID_INS_VMOVD: this->vmovd_s(inst); break;
767 case ID_INS_VMOVDQA: this->vmovdqa_s(inst); break;
768 case ID_INS_VMOVDQU: this->vmovdqu_s(inst); break;
769 case ID_INS_VMOVNTDQ: this->vmovntdq_s(inst); break;
770 case ID_INS_VMOVQ: this->vmovq_s(inst); break;
771 case ID_INS_VMOVSD: this->vmovsd_s(inst); break;
772 case ID_INS_VMOVAPS: this->vmovaps_s(inst); break;
773 case ID_INS_VMOVUPS: this->vmovups_s(inst); break;
774 case ID_INS_VPACKUSWB: this->vpackuswb_s(inst); break;
775 case ID_INS_VPACKSSDW: this->vpackssdw_s(inst); break;
776 case ID_INS_VPACKSSWB: this->vpacksswb_s(inst); break;
777 case ID_INS_VPADDB: this->vpaddb_s(inst); break;
778 case ID_INS_VPADDD: this->vpaddd_s(inst); break;
779 case ID_INS_VPADDW: this->vpaddw_s(inst); break;
780 case ID_INS_VPAND: this->vpand_s(inst); break;
781 case ID_INS_VPANDN: this->vpandn_s(inst); break;
782 case ID_INS_VPERM2I128: this->vperm2i128_s(inst); break;
783 case ID_INS_VPERMQ: this->vpermq_s(inst); break;
784 case ID_INS_VPEXTRB: this->vpextrb_s(inst); break;
785 case ID_INS_VPEXTRD: this->vpextrd_s(inst); break;
786 case ID_INS_VPEXTRQ: this->vpextrq_s(inst); break;
787 case ID_INS_VPEXTRW: this->vpextrw_s(inst); break;
788 case ID_INS_VPBROADCASTB: this->vpbroadcastb_s(inst); break;
789 case ID_INS_VPCMPEQB: this->vpcmpeqb_s(inst); break;
790 case ID_INS_VPCMPEQD: this->vpcmpeqd_s(inst); break;
791 case ID_INS_VPCMPEQQ: this->vpcmpeqq_s(inst); break;
792 case ID_INS_VPCMPEQW: this->vpcmpeqw_s(inst); break;
793 case ID_INS_VPCMPGTB: this->vpcmpgtb_s(inst); break;
794 case ID_INS_VPCMPGTD: this->vpcmpgtd_s(inst); break;
795 case ID_INS_VPCMPGTW: this->vpcmpgtw_s(inst); break;
796 case ID_INS_VPMADDWD: this->vpmaddwd_s(inst); break;
797 case ID_INS_VPMOVMSKB: this->vpmovmskb_s(inst); break;
798 case ID_INS_VPMINUB: this->vpminub_s(inst); break;
799 case ID_INS_VPMULHW: this->vpmulhw_s(inst); break;
800 case ID_INS_VPMULLW: this->vpmullw_s(inst); break;
801 case ID_INS_VPOR: this->vpor_s(inst); break;
802 case ID_INS_VPSHUFD: this->vpshufd_s(inst); break;
803 case ID_INS_VPSIGNW: this->vpsignw_s(inst); break;
804 case ID_INS_VPSLLDQ: this->vpslldq_s(inst); break;
805 case ID_INS_VPSLLW: this->vpsllw_s(inst); break;
806 case ID_INS_VPSRAD: this->vpsrad_s(inst); break;
807 case ID_INS_VPSRAW: this->vpsraw_s(inst); break;
808 case ID_INS_VPSRLDQ: this->vpsrldq_s(inst); break;
809 case ID_INS_VPSRLW: this->vpsrlw_s(inst); break;
810 case ID_INS_VPSUBB: this->vpsubb_s(inst); break;
811 case ID_INS_VPSUBD: this->vpsubd_s(inst); break;
812 case ID_INS_VPSUBQ: this->vpsubq_s(inst); break;
813 case ID_INS_VPSUBW: this->vpsubw_s(inst); break;
814 case ID_INS_VPTEST: this->vptest_s(inst); break;
815 case ID_INS_VPUNPCKHBW: this->vpunpckhbw_s(inst); break;
816 case ID_INS_VPUNPCKHDQ: this->vpunpckhdq_s(inst); break;
817 case ID_INS_VPUNPCKHQDQ: this->vpunpckhqdq_s(inst); break;
818 case ID_INS_VPUNPCKHWD: this->vpunpckhwd_s(inst); break;
819 case ID_INS_VPUNPCKLBW: this->vpunpcklbw_s(inst); break;
820 case ID_INS_VPUNPCKLDQ: this->vpunpckldq_s(inst); break;
821 case ID_INS_VPUNPCKLQDQ: this->vpunpcklqdq_s(inst); break;
822 case ID_INS_VPUNPCKLWD: this->vpunpcklwd_s(inst); break;
823 case ID_INS_VPXOR: this->vpxor_s(inst); break;
824 case ID_INS_VXORPS: this->vxorps_s(inst); break;
825 case ID_INS_WAIT: this->wait_s(inst); break;
826 case ID_INS_WBINVD: this->wbinvd_s(inst); break;
827 case ID_INS_XADD: this->xadd_s(inst); break;
828 case ID_INS_XCHG: this->xchg_s(inst); break;
829 case ID_INS_XOR: this->xor_s(inst); break;
830 case ID_INS_XORPD: this->xorpd_s(inst); break;
831 case ID_INS_XORPS: this->xorps_s(inst); break;
832 default:
833 this->exception = triton::arch::FAULT_UD;
834 break;
835 }
836 return this->exception;
837 }
838
839
840 triton::uint64 x86Semantics::alignAddStack_s(triton::arch::Instruction& inst, triton::uint32 delta) {
841 auto dst = triton::arch::OperandWrapper(this->architecture->getStackPointer());
842
843 /* Create symbolic operands */
844 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
845 auto op2 = this->astCtxt->bv(delta, dst.getBitSize());
846
847 /* Create the semantics */
848 auto node = this->astCtxt->bvadd(op1, op2);
849
850 /* Create symbolic expression */
851 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "Stack alignment");
852
853 /* Spread taint */
854 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
855
856 /* Return the new stack value */
857 return static_cast<triton::uint64>(node->evaluate());
858 }
859
860
861 triton::uint64 x86Semantics::alignSubStack_s(triton::arch::Instruction& inst, triton::uint32 delta) {
862 auto dst = triton::arch::OperandWrapper(this->architecture->getStackPointer());
863
864 /* Create symbolic operands */
865 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
866 auto op2 = this->astCtxt->bv(delta, dst.getBitSize());
867
868 /* Create the semantics */
869 auto node = this->astCtxt->bvsub(op1, op2);
870
871 /* Create symbolic expression */
872 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "Stack alignment");
873
874 /* Spread taint */
875 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
876
877 /* Return the new stack value */
878 return static_cast<triton::uint64>(node->evaluate());
879 }
880
881
882 void x86Semantics::clearFlag_s(triton::arch::Instruction& inst, const triton::arch::Register& flag, std::string comment) {
883 /* Create the semantics */
884 auto node = this->astCtxt->bv(0, 1);
885
886 /* Create symbolic expression */
887 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, flag, comment);
888
889 /* Spread taint */
890 expr->isTainted = this->taintEngine->setTaintRegister(flag, triton::engines::taint::UNTAINTED);
891 }
892
893
894 void x86Semantics::setFlag_s(triton::arch::Instruction& inst, const triton::arch::Register& flag, std::string comment) {
895 /* Create the semantics */
896 auto node = this->astCtxt->bv(1, 1);
897
898 /* Create symbolic expression */
899 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, flag, comment);
900
901 /* Spread taint */
902 expr->isTainted = this->taintEngine->setTaintRegister(flag, triton::engines::taint::UNTAINTED);
903 }
904
905
906 void x86Semantics::undefined_s(triton::arch::Instruction& inst, const triton::arch::Register& reg) {
907 if (this->modes->isModeEnabled(triton::modes::CONCRETIZE_UNDEFINED_REGISTERS)) {
908 this->symbolicEngine->concretizeRegister(reg);
909 }
910 /* Tell that the instruction defines a register as undefined and untaint */
911 inst.setUndefinedRegister(reg);
913 }
914
915
916 void x86Semantics::controlFlow_s(triton::arch::Instruction& inst) {
917 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
918 auto counter = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
919 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
920
921 switch (inst.getPrefix()) {
922
924 /* Create symbolic operands */
925 auto op1 = this->symbolicEngine->getOperandAst(inst, counter);
926
927 /* Create the semantics for Counter */
928 auto node1 = this->astCtxt->ite(
929 this->astCtxt->equal(op1, this->astCtxt->bv(0, counter.getBitSize())),
930 op1,
931 this->astCtxt->bvsub(op1, this->astCtxt->bv(1, counter.getBitSize()))
932 );
933
934 /* Create the semantics for PC */
935 auto node2 = this->astCtxt->ite(
936 this->astCtxt->equal(node1, this->astCtxt->bv(0, counter.getBitSize())),
937 this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize()),
938 this->astCtxt->bv(inst.getAddress(), pc.getBitSize())
939 );
940
941 /* Create symbolic expression */
942 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, counter, "Counter operation");
943 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, pc, "Program Counter");
944
945 /* Spread taint for PC */
946 expr1->isTainted = this->taintEngine->taintUnion(counter, counter);
947 expr2->isTainted = this->taintEngine->taintAssignment(pc, counter);
948 break;
949 }
950
952 /* Create symbolic operands */
953 auto op1 = this->symbolicEngine->getOperandAst(inst, counter);
954 auto op2 = this->symbolicEngine->getOperandAst(inst, zf);
955
956 /* Create the semantics for Counter */
957 auto node1 = this->astCtxt->ite(
958 this->astCtxt->equal(op1, this->astCtxt->bv(0, counter.getBitSize())),
959 op1,
960 this->astCtxt->bvsub(op1, this->astCtxt->bv(1, counter.getBitSize()))
961 );
962
963 /* Create the semantics for PC */
964 auto node2 = this->astCtxt->ite(
965 this->astCtxt->lor(
966 this->astCtxt->equal(node1, this->astCtxt->bv(0, counter.getBitSize())),
967 this->astCtxt->equal(op2, this->astCtxt->bvfalse())
968 ),
969 this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize()),
970 this->astCtxt->bv(inst.getAddress(), pc.getBitSize())
971 );
972
973 /* Create symbolic expression */
974 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, counter, "Counter operation");
975 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, pc, "Program Counter");
976
977 /* Spread taint */
978 expr1->isTainted = this->taintEngine->taintUnion(counter, counter);
979 expr2->isTainted = this->taintEngine->taintAssignment(pc, counter);
980 break;
981 }
982
984 /* Create symbolic operands */
985 auto op1 = this->symbolicEngine->getOperandAst(inst, counter);
986 auto op2 = this->symbolicEngine->getOperandAst(inst, zf);
987
988 /* Create the semantics for Counter */
989 auto node1 = this->astCtxt->ite(
990 this->astCtxt->equal(op1, this->astCtxt->bv(0, counter.getBitSize())),
991 op1,
992 this->astCtxt->bvsub(op1, this->astCtxt->bv(1, counter.getBitSize()))
993 );
994
995 /* Create the semantics for PC */
996 auto node2 = this->astCtxt->ite(
997 this->astCtxt->lor(
998 this->astCtxt->equal(node1, this->astCtxt->bv(0, counter.getBitSize())),
999 this->astCtxt->equal(op2, this->astCtxt->bvtrue())
1000 ),
1001 this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize()),
1002 this->astCtxt->bv(inst.getAddress(), pc.getBitSize())
1003 );
1004
1005 /* Create symbolic expression */
1006 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, counter, "Counter operation");
1007 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, pc, "Program Counter");
1008
1009 /* Spread taint */
1010 expr1->isTainted = this->taintEngine->taintUnion(counter, counter);
1011 expr2->isTainted = this->taintEngine->taintAssignment(pc, counter);
1012 break;
1013 }
1014
1015 default: {
1016 /* Create the semantics */
1017 auto node = this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize());
1018
1019 /* Create symbolic expression */
1020 auto expr = this->symbolicEngine->createSymbolicRegisterExpression(inst, node, this->architecture->getProgramCounter(), "Program Counter");
1021
1022 /* Spread taint */
1023 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getProgramCounter(), triton::engines::taint::UNTAINTED);
1024 break;
1025 }
1026 }
1027 }
1028
1029
1031 void x86Semantics::updateFTW(triton::arch::Instruction& inst, const triton::engines::symbolic::SharedSymbolicExpression& parent) {
1032 /* Fetch the STX registers */
1033 auto st0 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST0));
1034 auto st1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST1));
1035 auto st2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST2));
1036 auto st3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST3));
1037 auto st4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST4));
1038 auto st5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST5));
1039 auto st6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST6));
1040 auto st7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST7));
1041
1042 /* Fetch the STX ASTs */
1043 auto st0_ast = this->symbolicEngine->getOperandAst(inst, st0);
1044 auto st1_ast = this->symbolicEngine->getOperandAst(inst, st1);
1045 auto st2_ast = this->symbolicEngine->getOperandAst(inst, st2);
1046 auto st3_ast = this->symbolicEngine->getOperandAst(inst, st3);
1047 auto st4_ast = this->symbolicEngine->getOperandAst(inst, st4);
1048 auto st5_ast = this->symbolicEngine->getOperandAst(inst, st5);
1049 auto st6_ast = this->symbolicEngine->getOperandAst(inst, st6);
1050 auto st7_ast = this->symbolicEngine->getOperandAst(inst, st7);
1051
1052 /* Extract the fraction from the STX registers */
1053 auto fraction_st0 = this->astCtxt->extract(62, 0, st0_ast);
1054 auto fraction_st1 = this->astCtxt->extract(62, 0, st1_ast);
1055 auto fraction_st2 = this->astCtxt->extract(62, 0, st2_ast);
1056 auto fraction_st3 = this->astCtxt->extract(62, 0, st3_ast);
1057 auto fraction_st4 = this->astCtxt->extract(62, 0, st4_ast);
1058 auto fraction_st5 = this->astCtxt->extract(62, 0, st5_ast);
1059 auto fraction_st6 = this->astCtxt->extract(62, 0, st6_ast);
1060 auto fraction_st7 = this->astCtxt->extract(62, 0, st7_ast);
1061
1062 /* Extract the integer bit from the STX registers */
1063 auto integer_st0 = this->astCtxt->extract(63, 63, st0_ast);
1064 auto integer_st1 = this->astCtxt->extract(63, 63, st1_ast);
1065 auto integer_st2 = this->astCtxt->extract(63, 63, st2_ast);
1066 auto integer_st3 = this->astCtxt->extract(63, 63, st3_ast);
1067 auto integer_st4 = this->astCtxt->extract(63, 63, st4_ast);
1068 auto integer_st5 = this->astCtxt->extract(63, 63, st5_ast);
1069 auto integer_st6 = this->astCtxt->extract(63, 63, st6_ast);
1070 auto integer_st7 = this->astCtxt->extract(63, 63, st7_ast);
1071
1072 /* Extract the exponent from the STX registers */
1073 auto exponent_st0 = this->astCtxt->extract(79, 64, st0_ast);
1074 auto exponent_st1 = this->astCtxt->extract(79, 64, st1_ast);
1075 auto exponent_st2 = this->astCtxt->extract(79, 64, st2_ast);
1076 auto exponent_st3 = this->astCtxt->extract(79, 64, st3_ast);
1077 auto exponent_st4 = this->astCtxt->extract(79, 64, st4_ast);
1078 auto exponent_st5 = this->astCtxt->extract(79, 64, st5_ast);
1079 auto exponent_st6 = this->astCtxt->extract(79, 64, st6_ast);
1080 auto exponent_st7 = this->astCtxt->extract(79, 64, st7_ast);
1081
1082 /* Exponent All Zeros */
1083 auto ea0_st0 = this->astCtxt->equal(exponent_st0, this->astCtxt->bv(0x0000, 16));
1084 auto ea0_st1 = this->astCtxt->equal(exponent_st1, this->astCtxt->bv(0x0000, 16));
1085 auto ea0_st2 = this->astCtxt->equal(exponent_st2, this->astCtxt->bv(0x0000, 16));
1086 auto ea0_st3 = this->astCtxt->equal(exponent_st3, this->astCtxt->bv(0x0000, 16));
1087 auto ea0_st4 = this->astCtxt->equal(exponent_st4, this->astCtxt->bv(0x0000, 16));
1088 auto ea0_st5 = this->astCtxt->equal(exponent_st5, this->astCtxt->bv(0x0000, 16));
1089 auto ea0_st6 = this->astCtxt->equal(exponent_st6, this->astCtxt->bv(0x0000, 16));
1090 auto ea0_st7 = this->astCtxt->equal(exponent_st7, this->astCtxt->bv(0x0000, 16));
1091
1092 /* Exponent All Ones */
1093 auto ea1_st0 = this->astCtxt->equal(exponent_st0, this->astCtxt->bv(0xFFFF, 16));
1094 auto ea1_st1 = this->astCtxt->equal(exponent_st1, this->astCtxt->bv(0xFFFF, 16));
1095 auto ea1_st2 = this->astCtxt->equal(exponent_st2, this->astCtxt->bv(0xFFFF, 16));
1096 auto ea1_st3 = this->astCtxt->equal(exponent_st3, this->astCtxt->bv(0xFFFF, 16));
1097 auto ea1_st4 = this->astCtxt->equal(exponent_st4, this->astCtxt->bv(0xFFFF, 16));
1098 auto ea1_st5 = this->astCtxt->equal(exponent_st5, this->astCtxt->bv(0xFFFF, 16));
1099 auto ea1_st6 = this->astCtxt->equal(exponent_st6, this->astCtxt->bv(0xFFFF, 16));
1100 auto ea1_st7 = this->astCtxt->equal(exponent_st7, this->astCtxt->bv(0xFFFF, 16));
1101
1102 /* Exponent Neither All Zeroes Or Ones */
1103 auto ena01_st0 = this->astCtxt->equal(this->astCtxt->lor(ea0_st0, ea1_st0), this->astCtxt->bvfalse());
1104 auto ena01_st1 = this->astCtxt->equal(this->astCtxt->lor(ea0_st1, ea1_st1), this->astCtxt->bvfalse());
1105 auto ena01_st2 = this->astCtxt->equal(this->astCtxt->lor(ea0_st2, ea1_st2), this->astCtxt->bvfalse());
1106 auto ena01_st3 = this->astCtxt->equal(this->astCtxt->lor(ea0_st3, ea1_st3), this->astCtxt->bvfalse());
1107 auto ena01_st4 = this->astCtxt->equal(this->astCtxt->lor(ea0_st4, ea1_st4), this->astCtxt->bvfalse());
1108 auto ena01_st5 = this->astCtxt->equal(this->astCtxt->lor(ea0_st5, ea1_st5), this->astCtxt->bvfalse());
1109 auto ena01_st6 = this->astCtxt->equal(this->astCtxt->lor(ea0_st6, ea1_st6), this->astCtxt->bvfalse());
1110 auto ena01_st7 = this->astCtxt->equal(this->astCtxt->lor(ea0_st7, ea1_st7), this->astCtxt->bvfalse());
1111
1112 /* Integer Bit 0 */
1113 auto ib0_st0 = this->astCtxt->equal(integer_st0, this->astCtxt->bv(0, 1));
1114 auto ib0_st1 = this->astCtxt->equal(integer_st1, this->astCtxt->bv(0, 1));
1115 auto ib0_st2 = this->astCtxt->equal(integer_st2, this->astCtxt->bv(0, 1));
1116 auto ib0_st3 = this->astCtxt->equal(integer_st3, this->astCtxt->bv(0, 1));
1117 auto ib0_st4 = this->astCtxt->equal(integer_st4, this->astCtxt->bv(0, 1));
1118 auto ib0_st5 = this->astCtxt->equal(integer_st5, this->astCtxt->bv(0, 1));
1119 auto ib0_st6 = this->astCtxt->equal(integer_st6, this->astCtxt->bv(0, 1));
1120 auto ib0_st7 = this->astCtxt->equal(integer_st7, this->astCtxt->bv(0, 1));
1121
1122 /* Fraction All Zeroes */
1123 auto fa0_st0 = this->astCtxt->equal(fraction_st0, this->astCtxt->bv(0, 63));
1124 auto fa0_st1 = this->astCtxt->equal(fraction_st1, this->astCtxt->bv(0, 63));
1125 auto fa0_st2 = this->astCtxt->equal(fraction_st2, this->astCtxt->bv(0, 63));
1126 auto fa0_st3 = this->astCtxt->equal(fraction_st3, this->astCtxt->bv(0, 63));
1127 auto fa0_st4 = this->astCtxt->equal(fraction_st4, this->astCtxt->bv(0, 63));
1128 auto fa0_st5 = this->astCtxt->equal(fraction_st5, this->astCtxt->bv(0, 63));
1129 auto fa0_st6 = this->astCtxt->equal(fraction_st6, this->astCtxt->bv(0, 63));
1130 auto fa0_st7 = this->astCtxt->equal(fraction_st7, this->astCtxt->bv(0, 63));
1131
1132 /* Determine the x87 FPU Tag Word (Diagram at page 379 of the AMD Architecture Programmer's Manual, Volume 2: System Programming) */
1133 auto db_1_0 = this->astCtxt->ite(ea0_st0,
1134 this->astCtxt->ite(ib0_st0,
1135 this->astCtxt->ite(fa0_st0,
1136 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
1137 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
1138 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
1139 this->astCtxt->ite(ena01_st0,
1140 this->astCtxt->ite(ib0_st0,
1141 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
1142 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
1143 this->astCtxt->bv(2, 2))); // 'Exponent All 1'
1144
1145 auto db_3_2 = this->astCtxt->ite(ea0_st1,
1146 this->astCtxt->ite(ib0_st1,
1147 this->astCtxt->ite(fa0_st1,
1148 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
1149 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
1150 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
1151 this->astCtxt->ite(ena01_st1,
1152 this->astCtxt->ite(ib0_st1,
1153 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
1154 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
1155 this->astCtxt->bv(2, 2))); // 'Exponent All 1'
1156
1157 auto db_5_4 = this->astCtxt->ite(ea0_st2,
1158 this->astCtxt->ite(ib0_st2,
1159 this->astCtxt->ite(fa0_st2,
1160 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
1161 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
1162 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
1163 this->astCtxt->ite(ena01_st2,
1164 this->astCtxt->ite(ib0_st2,
1165 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
1166 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
1167 this->astCtxt->bv(2, 2))); // 'Exponent All 1'
1168
1169 auto db_7_6 = this->astCtxt->ite(ea0_st3,
1170 this->astCtxt->ite(ib0_st3,
1171 this->astCtxt->ite(fa0_st3,
1172 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
1173 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
1174 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
1175 this->astCtxt->ite(ena01_st3,
1176 this->astCtxt->ite(ib0_st3,
1177 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
1178 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
1179 this->astCtxt->bv(2, 2))); // 'Exponent All 1'
1180
1181 auto db_9_8 = this->astCtxt->ite(ea0_st4,
1182 this->astCtxt->ite(ib0_st4,
1183 this->astCtxt->ite(fa0_st4,
1184 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
1185 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
1186 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
1187 this->astCtxt->ite(ena01_st4,
1188 this->astCtxt->ite(ib0_st4,
1189 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
1190 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
1191 this->astCtxt->bv(2, 2))); // 'Exponent All 1'
1192
1193 auto db_11_10 = this->astCtxt->ite(ea0_st5,
1194 this->astCtxt->ite(ib0_st5,
1195 this->astCtxt->ite(fa0_st5,
1196 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
1197 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
1198 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
1199 this->astCtxt->ite(ena01_st5,
1200 this->astCtxt->ite(ib0_st5,
1201 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
1202 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
1203 this->astCtxt->bv(2, 2))); // 'Exponent All 1'
1204
1205 auto db_13_12 = this->astCtxt->ite(ea0_st6,
1206 this->astCtxt->ite(ib0_st6,
1207 this->astCtxt->ite(fa0_st6,
1208 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
1209 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
1210 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
1211 this->astCtxt->ite(ena01_st6,
1212 this->astCtxt->ite(ib0_st6,
1213 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
1214 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
1215 this->astCtxt->bv(2, 2))); // 'Exponent All 1'
1216
1217 auto db_15_14 = this->astCtxt->ite(ea0_st7,
1218 this->astCtxt->ite(ib0_st7,
1219 this->astCtxt->ite(fa0_st7,
1220 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
1221 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
1222 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
1223 this->astCtxt->ite(ena01_st7,
1224 this->astCtxt->ite(ib0_st7,
1225 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
1226 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
1227 this->astCtxt->bv(2, 2))); // 'Exponent All 1'
1228
1229 /* Restore the x87 FPU Tag Word */
1230 auto node = this->astCtxt->concat(db_15_14,
1231 this->astCtxt->concat(db_13_12,
1232 this->astCtxt->concat(db_11_10,
1233 this->astCtxt->concat(db_9_8,
1234 this->astCtxt->concat(db_7_6,
1235 this->astCtxt->concat(db_5_4,
1236 this->astCtxt->concat(db_3_2, db_1_0)))))));
1237
1238 /* Create the symbolic expression */
1239 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_FTW), "x87 FPU Tag Word");
1240
1241 /* Spread the taint from the parent to the child */
1242 auto st0_taint = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_ST0));
1243 auto st1_taint = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_ST1));
1244 auto st2_taint = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_ST2));
1245 auto st3_taint = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_ST3));
1246 auto st4_taint = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_ST4));
1247 auto st5_taint = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_ST5));
1248 auto st6_taint = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_ST6));
1249 auto st7_taint = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_ST7));
1250
1251 auto is_ftw_tainted = st0_taint | st1_taint | st2_taint | st3_taint |
1252 st4_taint | st5_taint | st6_taint | st7_taint;
1253
1254 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_FTW), is_ftw_tainted);
1255 }
1256
1257
1258 void x86Semantics::af_s(triton::arch::Instruction& inst,
1263 bool vol) {
1264
1265 auto bvSize = dst.getBitSize();
1266 auto low = vol ? 0 : dst.getLow();
1267 auto high = vol ? bvSize-1 : dst.getHigh();
1268
1269 /*
1270 * Create the semantic.
1271 * af = 0x10 == (0x10 & (regDst ^ op1 ^ op2))
1272 */
1273 auto node = this->astCtxt->ite(
1274 this->astCtxt->equal(
1275 this->astCtxt->bv(0x10, bvSize),
1276 this->astCtxt->bvand(
1277 this->astCtxt->bv(0x10, bvSize),
1278 this->astCtxt->bvxor(
1279 this->astCtxt->extract(high, low, this->astCtxt->reference(parent)),
1280 this->astCtxt->bvxor(op1, op2)
1281 )
1282 )
1283 ),
1284 this->astCtxt->bv(1, 1),
1285 this->astCtxt->bv(0, 1)
1286 );
1287
1288 /* Create the symbolic expression */
1289 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_AF), "Adjust flag");
1290
1291 /* Spread the taint from the parent to the child */
1292 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_AF), parent->isTainted);
1293 }
1294
1295
1296 void x86Semantics::afAaa_s(triton::arch::Instruction& inst,
1301 bool vol) {
1302
1303 auto bvSize = dst.getBitSize();
1304
1305 /*
1306 * Create the semantic.
1307 * af = 1 if ((AL AND 0FH) > 9) or (AF = 1) then 0
1308 */
1309 auto node = this->astCtxt->ite(
1310 this->astCtxt->lor(
1311 this->astCtxt->bvugt(
1312 this->astCtxt->bvand(op1, this->astCtxt->bv(0xf, bvSize)),
1313 this->astCtxt->bv(9, bvSize)
1314 ),
1315 this->astCtxt->equal(op3, this->astCtxt->bvtrue())
1316 ),
1317 this->astCtxt->bv(1, 1),
1318 this->astCtxt->bv(0, 1)
1319 );
1320
1321 /* Create the symbolic expression */
1322 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_AF), "Adjust flag");
1323
1324 /* Spread the taint from the parent to the child */
1325 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_AF), parent->isTainted);
1326 }
1327
1328
1329 void x86Semantics::afNeg_s(triton::arch::Instruction& inst,
1333 bool vol) {
1334
1335 auto bvSize = dst.getBitSize();
1336 auto low = vol ? 0 : dst.getLow();
1337 auto high = vol ? bvSize-1 : dst.getHigh();
1338
1339 /*
1340 * Create the semantic.
1341 * af = 0x10 == (0x10 & (op1 ^ regDst))
1342 */
1343 auto node = this->astCtxt->ite(
1344 this->astCtxt->equal(
1345 this->astCtxt->bv(0x10, bvSize),
1346 this->astCtxt->bvand(
1347 this->astCtxt->bv(0x10, bvSize),
1348 this->astCtxt->bvxor(
1349 op1,
1350 this->astCtxt->extract(high, low, this->astCtxt->reference(parent))
1351 )
1352 )
1353 ),
1354 this->astCtxt->bv(1, 1),
1355 this->astCtxt->bv(0, 1)
1356 );
1357
1358 /* Create the symbolic expression */
1359 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_AF), "Adjust flag");
1360
1361 /* Spread the taint from the parent to the child */
1362 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_AF), parent->isTainted);
1363 }
1364
1365
1366 void x86Semantics::cfAaa_s(triton::arch::Instruction& inst,
1371 bool vol) {
1372
1373 auto bvSize = dst.getBitSize();
1374
1375 /*
1376 * Create the semantic.
1377 * cf = 1 if ((AL AND 0FH) > 9) or (AF = 1) then 0
1378 */
1379 auto node = this->astCtxt->ite(
1380 this->astCtxt->lor(
1381 this->astCtxt->bvugt(
1382 this->astCtxt->bvand(op1, this->astCtxt->bv(0xf, bvSize)),
1383 this->astCtxt->bv(9, bvSize)
1384 ),
1385 this->astCtxt->equal(op3, this->astCtxt->bvtrue())
1386 ),
1387 this->astCtxt->bv(1, 1),
1388 this->astCtxt->bv(0, 1)
1389 );
1390
1391 /* Create the symbolic expression */
1392 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1393
1394 /* Spread the taint from the parent to the child */
1395 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1396 }
1397
1398
1399 void x86Semantics::cfAdd_s(triton::arch::Instruction& inst,
1404 bool vol) {
1405
1406 auto bvSize = dst.getBitSize();
1407 auto low = vol ? 0 : dst.getLow();
1408 auto high = vol ? bvSize-1 : dst.getHigh();
1409
1410 /*
1411 * Create the semantic.
1412 * cf = MSB((op1 & op2) ^ ((op1 ^ op2 ^ parent) & (op1 ^ op2)));
1413 */
1414 auto node = this->astCtxt->extract(bvSize-1, bvSize-1,
1415 this->astCtxt->bvxor(
1416 this->astCtxt->bvand(op1, op2),
1417 this->astCtxt->bvand(
1418 this->astCtxt->bvxor(
1419 this->astCtxt->bvxor(op1, op2),
1420 this->astCtxt->extract(high, low, this->astCtxt->reference(parent))
1421 ),
1422 this->astCtxt->bvxor(op1, op2))
1423 )
1424 );
1425
1426 /* Create the symbolic expression */
1427 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1428
1429 /* Spread the taint from the parent to the child */
1430 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1431 }
1432
1433
1434 void x86Semantics::cfBlsi_s(triton::arch::Instruction& inst,
1438 bool vol) {
1439
1440 /*
1441 * Create the semantic.
1442 * cf = 0 if op1 == 0 else 1
1443 */
1444 auto node = this->astCtxt->ite(
1445 this->astCtxt->equal(
1446 op1,
1447 this->astCtxt->bv(0, dst.getBitSize())
1448 ),
1449 this->astCtxt->bv(0, 1),
1450 this->astCtxt->bv(1, 1)
1451 );
1452
1453 /* Create the symbolic expression */
1454 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1455
1456 /* Spread the taint from the parent to the child */
1457 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1458 }
1459
1460
1461 void x86Semantics::cfBlsmsk_s(triton::arch::Instruction& inst,
1465 bool vol) {
1466
1467 /*
1468 * Create the semantic.
1469 * cf = 1 if op1 == 0 else 0
1470 */
1471 auto node = this->astCtxt->ite(
1472 this->astCtxt->equal(
1473 op1,
1474 this->astCtxt->bv(0, dst.getBitSize())
1475 ),
1476 this->astCtxt->bv(1, 1),
1477 this->astCtxt->bv(0, 1)
1478 );
1479
1480 /* Create the symbolic expression */
1481 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1482
1483 /* Spread the taint from the parent to the child */
1484 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1485 }
1486
1487
1488 void x86Semantics::cfBlsr_s(triton::arch::Instruction& inst,
1492 bool vol) {
1493
1494 /*
1495 * Create the semantic.
1496 * cf = 1 if op1 == 0 else 0
1497 */
1498 auto node = this->astCtxt->ite(
1499 this->astCtxt->equal(
1500 op1,
1501 this->astCtxt->bv(0, dst.getBitSize())
1502 ),
1503 this->astCtxt->bv(1, 1),
1504 this->astCtxt->bv(0, 1)
1505 );
1506
1507 /* Create the symbolic expression */
1508 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1509
1510 /* Spread the taint from the parent to the child */
1511 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1512 }
1513
1514
1515 void x86Semantics::cfImul_s(triton::arch::Instruction& inst,
1520 bool vol) {
1521
1522 /*
1523 * Create the semantic.
1524 * cf = 0 if sx(dst) == node else 1
1525 */
1526 auto node = this->astCtxt->ite(
1527 this->astCtxt->equal(
1528 this->astCtxt->sx(dst.getBitSize(), op1),
1529 res
1530 ),
1531 this->astCtxt->bv(0, 1),
1532 this->astCtxt->bv(1, 1)
1533 );
1534
1535 /* Create the symbolic expression */
1536 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1537
1538 /* Spread the taint from the parent to the child */
1539 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1540 }
1541
1542
1543 void x86Semantics::cfLzcnt_s(triton::arch::Instruction& inst,
1547 bool vol) {
1548
1549 auto bvSize = src.getBitSize();
1550 auto low = vol ? 0 : src.getLow();
1551 auto high = vol ? bvSize-1 : src.getHigh();
1552
1553 /*
1554 * Create the semantic.
1555 * cf = 0 == parent
1556 */
1557 auto node = this->astCtxt->ite(
1558 this->astCtxt->equal(
1559 this->astCtxt->extract(high, low, op1),
1560 this->astCtxt->bv(0, bvSize)
1561 ),
1562 this->astCtxt->bv(1, 1),
1563 this->astCtxt->bv(0, 1)
1564 );
1565
1566 /* Create the symbolic expression */
1567 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1568
1569 /* Spread the taint from the parent to the child */
1570 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1571 }
1572
1573
1574 void x86Semantics::cfMul_s(triton::arch::Instruction& inst,
1578 bool vol) {
1579
1580 /*
1581 * Create the semantic.
1582 * cf = 0 if op1 == 0 else 1
1583 */
1584 auto node = this->astCtxt->ite(
1585 this->astCtxt->equal(
1586 op1,
1587 this->astCtxt->bv(0, dst.getBitSize())
1588 ),
1589 this->astCtxt->bv(0, 1),
1590 this->astCtxt->bv(1, 1)
1591 );
1592
1593 /* Create the symbolic expression */
1594 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1595
1596 /* Spread the taint from the parent to the child */
1597 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1598 }
1599
1600
1601 void x86Semantics::cfNeg_s(triton::arch::Instruction& inst,
1605 bool vol) {
1606
1607 /*
1608 * Create the semantic.
1609 * cf = 0 if op1 == 0 else 1
1610 */
1611 auto node = this->astCtxt->ite(
1612 this->astCtxt->equal(
1613 op1,
1614 this->astCtxt->bv(0, dst.getBitSize())
1615 ),
1616 this->astCtxt->bv(0, 1),
1617 this->astCtxt->bv(1, 1)
1618 );
1619
1620 /* Create the symbolic expression */
1621 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1622
1623 /* Spread the taint from the parent to the child */
1624 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1625 }
1626
1627
1628 void x86Semantics::cfPtest_s(triton::arch::Instruction& inst,
1631 bool vol) {
1632
1633 auto bvSize = dst.getBitSize();
1634 auto low = vol ? 0 : dst.getLow();
1635 auto high = vol ? bvSize-1 : dst.getHigh();
1636
1637 /*
1638 * Create the semantic.
1639 * cf = 0 == regDst
1640 */
1641 auto node = this->astCtxt->ite(
1642 this->astCtxt->equal(
1643 this->astCtxt->extract(high, low, this->astCtxt->reference(parent)),
1644 this->astCtxt->bv(0, bvSize)
1645 ),
1646 this->astCtxt->bv(1, 1),
1647 this->astCtxt->bv(0, 1)
1648 );
1649
1650 /* Create the symbolic expression */
1651 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
1652
1653 /* Spread the taint from the parent to the child */
1654 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
1655 }
1656
1657
1658 void x86Semantics::cfRcl_s(triton::arch::Instruction& inst,
1660 const triton::ast::SharedAbstractNode& result,
1662 bool vol) {
1663
1664 auto bvSize = op2->getBitvectorSize();
1665 auto high = result->getBitvectorSize() - 1;
1666 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
1667
1668 auto node = this->astCtxt->ite(
1669 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)),
1670 this->symbolicEngine->getOperandAst(cf),
1671 this->astCtxt->extract(high, high, result)
1672 );
1673
1674 /* Create the symbolic expression */
1675 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag");
1676
1677 if (op2->evaluate()) {
1678 /* Spread the taint from the parent to the child */
1679 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted);
1680 }
1681 else {
1682 inst.removeWrittenRegister(cf.getConstRegister());
1683 }
1684 }
1685
1686
1687 void x86Semantics::cfRcr_s(triton::arch::Instruction& inst,
1690 const triton::ast::SharedAbstractNode& result,
1692 bool vol) {
1693
1694 auto bvSize = op2->getBitvectorSize();
1695 auto high = result->getBitvectorSize() - 1;
1696 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
1697
1698 auto node = this->astCtxt->ite(
1699 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)),
1700 this->symbolicEngine->getOperandAst(cf),
1701 this->astCtxt->extract(high, high, result) /* yes it's should be LSB, but here it's a trick :-) */
1702 );
1703
1704 /* Create the symbolic expression */
1705 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag");
1706
1707 if (op2->evaluate()) {
1708 /* Spread the taint from the parent to the child */
1709 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted);
1710 }
1711 else {
1712 inst.removeWrittenRegister(cf.getConstRegister());
1713 }
1714 }
1715
1716
1717 void x86Semantics::cfRol_s(triton::arch::Instruction& inst,
1721 bool vol) {
1722
1723 auto bvSize = op2->getBitvectorSize();
1724 auto low = vol ? 0 : dst.getLow();
1725 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
1726
1727 auto node = this->astCtxt->ite(
1728 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)),
1729 this->symbolicEngine->getOperandAst(cf),
1730 this->astCtxt->extract(low, low, this->astCtxt->reference(parent))
1731 );
1732
1733 /* Create the symbolic expression */
1734 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag");
1735
1736 if (op2->evaluate()) {
1737 /* Spread the taint from the parent to the child */
1738 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted);
1739 }
1740 else {
1741 inst.removeWrittenRegister(cf.getConstRegister());
1742 }
1743 }
1744
1745
1746 void x86Semantics::cfRor_s(triton::arch::Instruction& inst,
1750 bool vol) {
1751
1752 auto bvSize = op2->getBitvectorSize();
1753 auto high = vol ? bvSize-1 : dst.getHigh();
1754 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
1755
1756 auto node = this->astCtxt->ite(
1757 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)),
1758 this->symbolicEngine->getOperandAst(cf),
1759 this->astCtxt->extract(high, high, this->astCtxt->reference(parent))
1760 );
1761
1762 /* Create the symbolic expression */
1763 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag");
1764
1765 if (op2->evaluate()) {
1766 /* Spread the taint from the parent to the child */
1767 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted);
1768 }
1769 else {
1770 inst.removeWrittenRegister(cf.getConstRegister());
1771 }
1772 }
1773
1774
1775 void x86Semantics::cfSar_s(triton::arch::Instruction& inst,
1780 bool vol) {
1781
1782 auto bvSize = dst.getBitSize();
1783 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
1784
1785 /*
1786 * Create the semantic.
1787 * if op2 != 0:
1788 * if op2 > bvSize:
1789 * cf.id = ((op1 >> (bvSize - 1)) & 1)
1790 * else:
1791 * cf.id = ((op1 >> (op2 - 1)) & 1)
1792 */
1793 auto node = this->astCtxt->ite(
1794 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)),
1795 this->symbolicEngine->getOperandAst(cf),
1796 this->astCtxt->ite(
1797 this->astCtxt->bvugt(op2, this->astCtxt->bv(bvSize, bvSize)),
1798 this->astCtxt->extract(0, 0, this->astCtxt->bvlshr(op1, this->astCtxt->bvsub(this->astCtxt->bv(bvSize, bvSize), this->astCtxt->bv(1, bvSize)))),
1799 this->astCtxt->extract(0, 0, this->astCtxt->bvlshr(op1, this->astCtxt->bvsub(op2, this->astCtxt->bv(1, bvSize))))
1800 )
1801 );
1802
1803 /* Create the symbolic expression */
1804 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag");
1805
1806 if (op2->evaluate()) {
1807 /* Spread the taint from the parent to the child */
1808 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted);
1809 }
1810 else {
1811 inst.removeWrittenRegister(cf.getConstRegister());
1812 }
1813 }
1814
1815
1816 void x86Semantics::cfShl_s(triton::arch::Instruction& inst,
1821 bool vol) {
1822
1823 auto bvSize = dst.getBitSize();
1824 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
1825
1826 /*
1827 * Create the semantic.
1828 * cf = (op1 >> ((bvSize - op2) & 1) if op2 != 0
1829 */
1830 auto node = this->astCtxt->ite(
1831 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)),
1832 this->symbolicEngine->getOperandAst(cf),
1833 this->astCtxt->extract(0, 0,
1834 this->astCtxt->bvlshr(
1835 op1,
1836 this->astCtxt->bvsub(
1837 this->astCtxt->bv(bvSize, bvSize),
1838 op2
1839 )
1840 )
1841 )
1842 );
1843
1844 /* Create the symbolic expression */
1845 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag");
1846
1847 if (op2->evaluate()) {
1848 /* Spread the taint from the parent to the child */
1849 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted);
1850 }
1851 else {
1852 inst.removeWrittenRegister(cf.getConstRegister());
1853 }
1854 }
1855
1856
1857 void x86Semantics::cfShld_s(triton::arch::Instruction& inst,
1863 bool vol) {
1864
1865 auto bv1Size = op1->getBitvectorSize();
1866 auto bv2Size = op2->getBitvectorSize();
1867 auto bv3Size = op3->getBitvectorSize();
1868 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
1869
1870 /*
1871 * Create the semantic.
1872 * cf = MSB(rol(op3, concat(op2,op1))) if op3 != 0
1873 */
1874 auto node = this->astCtxt->ite(
1875 this->astCtxt->equal(op3, this->astCtxt->bv(0, bv3Size)),
1876 this->symbolicEngine->getOperandAst(cf),
1877 this->astCtxt->extract(
1878 dst.getBitSize(), dst.getBitSize(),
1879 this->astCtxt->bvrol(
1880 this->astCtxt->concat(op2, op1),
1881 this->astCtxt->zx(((bv1Size + bv2Size) - bv3Size), op3)
1882 )
1883 )
1884 );
1885
1886 /* Create the symbolic expression */
1887 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag");
1888
1889 if (op3->evaluate()) {
1890 /* Spread the taint from the parent to the child */
1891 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted);
1892 }
1893 else {
1894 inst.removeWrittenRegister(cf.getConstRegister());
1895 }
1896 }
1897
1898
1899 void x86Semantics::cfShr_s(triton::arch::Instruction& inst,
1904 bool vol) {
1905
1906 auto bvSize = dst.getBitSize();
1907 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
1908
1909 /*
1910 * Create the semantic.
1911 * cf = ((op1 >> (op2 - 1)) & 1) if op2 != 0
1912 */
1913 auto node = this->astCtxt->ite(
1914 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)),
1915 this->symbolicEngine->getOperandAst(cf),
1916 this->astCtxt->extract(0, 0,
1917 this->astCtxt->bvlshr(
1918 op1,
1919 this->astCtxt->bvsub(
1920 op2,
1921 this->astCtxt->bv(1, bvSize))
1922 )
1923 )
1924 );
1925
1926 /* Create the symbolic expression */
1927 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag");
1928
1929 if (op2->evaluate()) {
1930 /* Spread the taint from the parent to the child */
1931 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted);
1932 }
1933 else {
1934 inst.removeWrittenRegister(cf.getConstRegister());
1935 }
1936 }
1937
1938
1939 void x86Semantics::cfShrd_s(triton::arch::Instruction& inst,
1945 bool vol) {
1946
1947 auto bvSize = dst.getBitSize();
1948 auto bv1Size = op1->getBitvectorSize();
1949 auto bv2Size = op2->getBitvectorSize();
1950 auto bv3Size = op3->getBitvectorSize();
1951 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
1952
1953 /*
1954 * Create the semantic.
1955 * cf = MSB(ror(op3, concat(op2,op1))) if op3 != 0
1956 */
1957 auto node = this->astCtxt->ite(
1958 this->astCtxt->equal(op3, this->astCtxt->bv(0, bv3Size)),
1959 this->symbolicEngine->getOperandAst(cf),
1960 this->astCtxt->extract(
1961 (bvSize * 2) - 1, (bvSize * 2) - 1,
1962 this->astCtxt->bvror(
1963 this->astCtxt->concat(op2, op1),
1964 this->astCtxt->zx(((bv1Size + bv2Size) - bv3Size), op3)
1965 )
1966 )
1967 );
1968
1969 /* Create the symbolic expression */
1970 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag");
1971
1972 if (op3->evaluate()) {
1973 /* Spread the taint from the parent to the child */
1974 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted);
1975 }
1976 else {
1977 inst.removeWrittenRegister(cf.getConstRegister());
1978 }
1979 }
1980
1981
1982 void x86Semantics::cfSub_s(triton::arch::Instruction& inst,
1987 bool vol) {
1988
1989 auto bvSize = dst.getBitSize();
1990 auto low = vol ? 0 : dst.getLow();
1991 auto high = vol ? bvSize-1 : dst.getHigh();
1992
1993 /*
1994 * Create the semantic.
1995 * cf = extract(bvSize, bvSize (((op1 ^ op2 ^ res) ^ ((op1 ^ res) & (op1 ^ op2)))))
1996 */
1997 auto node = this->astCtxt->extract(bvSize-1, bvSize-1,
1998 this->astCtxt->bvxor(
1999 this->astCtxt->bvxor(op1, this->astCtxt->bvxor(op2, this->astCtxt->extract(high, low, this->astCtxt->reference(parent)))),
2000 this->astCtxt->bvand(
2001 this->astCtxt->bvxor(op1, this->astCtxt->extract(high, low, this->astCtxt->reference(parent))),
2002 this->astCtxt->bvxor(op1, op2)
2003 )
2004 )
2005 );
2006
2007 /* Create the symbolic expression */
2008 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
2009
2010 /* Spread the taint from the parent to the child */
2011 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
2012 }
2013
2014
2015 void x86Semantics::cfTzcnt_s(triton::arch::Instruction& inst,
2019 bool vol) {
2020
2021 auto bvSize = src.getBitSize();
2022 auto low = vol ? 0 : src.getLow();
2023 auto high = vol ? bvSize-1 : src.getHigh();
2024
2025 /*
2026 * Create the semantic.
2027 * cf = 0 == parent
2028 */
2029 auto node = this->astCtxt->ite(
2030 this->astCtxt->equal(
2031 this->astCtxt->extract(high, low, op1),
2032 this->astCtxt->bv(0, bvSize)
2033 ),
2034 this->astCtxt->bv(1, 1),
2035 this->astCtxt->bv(0, 1)
2036 );
2037
2038 /* Create the symbolic expression */
2039 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag");
2040
2041 /* Spread the taint from the parent to the child */
2042 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted);
2043 }
2044
2045
2046 void x86Semantics::ofAdd_s(triton::arch::Instruction& inst,
2051 bool vol) {
2052
2053 auto bvSize = dst.getBitSize();
2054 auto low = vol ? 0 : dst.getLow();
2055 auto high = vol ? bvSize-1 : dst.getHigh();
2056
2057 /*
2058 * Create the semantic.
2059 * of = MSB((op1 ^ ~op2) & (op1 ^ regDst))
2060 */
2061 auto node = this->astCtxt->extract(bvSize-1, bvSize-1,
2062 this->astCtxt->bvand(
2063 this->astCtxt->bvxor(op1, this->astCtxt->bvnot(op2)),
2064 this->astCtxt->bvxor(op1, this->astCtxt->extract(high, low, this->astCtxt->reference(parent)))
2065 )
2066 );
2067
2068 /* Create the symbolic expression */
2069 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_OF), "Overflow flag");
2070
2071 /* Spread the taint from the parent to the child */
2072 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_OF), parent->isTainted);
2073 }
2074
2075
2076 void x86Semantics::ofImul_s(triton::arch::Instruction& inst,
2081 bool vol) {
2082 /*
2083 * Create the semantic.
2084 * of = 0 if sx(dst) == node else 1
2085 */
2086 auto node = this->astCtxt->ite(
2087 this->astCtxt->equal(
2088 this->astCtxt->sx(dst.getBitSize(), op1),
2089 res
2090 ),
2091 this->astCtxt->bv(0, 1),
2092 this->astCtxt->bv(1, 1)
2093 );
2094
2095 /* Create the symbolic expression */
2096 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_OF), "Overflow flag");
2097
2098 /* Spread the taint from the parent to the child */
2099 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_OF), parent->isTainted);
2100 }
2101
2102
2103 void x86Semantics::ofMul_s(triton::arch::Instruction& inst,
2107 bool vol) {
2108
2109 /*
2110 * Create the semantic.
2111 * of = 0 if up == 0 else 1
2112 */
2113 auto node = this->astCtxt->ite(
2114 this->astCtxt->equal(
2115 op1,
2116 this->astCtxt->bv(0, dst.getBitSize())
2117 ),
2118 this->astCtxt->bv(0, 1),
2119 this->astCtxt->bv(1, 1)
2120 );
2121
2122 /* Create the symbolic expression */
2123 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_OF), "Overflow flag");
2124
2125 /* Spread the taint from the parent to the child */
2126 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_OF), parent->isTainted);
2127 }
2128
2129
2130 void x86Semantics::ofNeg_s(triton::arch::Instruction& inst,
2134 bool vol) {
2135
2136 auto bvSize = dst.getBitSize();
2137 auto low = vol ? 0 : dst.getLow();
2138 auto high = vol ? bvSize-1 : dst.getHigh();
2139
2140 /*
2141 * Create the semantic.
2142 * of = (res & op1) >> (bvSize - 1) & 1
2143 */
2144 auto node = this->astCtxt->extract(0, 0,
2145 this->astCtxt->bvlshr(
2146 this->astCtxt->bvand(this->astCtxt->extract(high, low, this->astCtxt->reference(parent)), op1),
2147 this->astCtxt->bvsub(this->astCtxt->bv(bvSize, bvSize), this->astCtxt->bv(1, bvSize))
2148 )
2149 );
2150
2151 /* Create the symbolic expression */
2152 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_OF), "Overflow flag");
2153
2154 /* Spread the taint from the parent to the child */
2155 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_OF), parent->isTainted);
2156 }
2157
2158
2159 void x86Semantics::ofRol_s(triton::arch::Instruction& inst,
2163 bool vol) {
2164
2165 auto bvSize = dst.getBitSize();
2166 auto high = vol ? bvSize-1 : dst.getHigh();
2167 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
2168 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
2169
2170 auto node = this->astCtxt->ite(
2171 this->astCtxt->equal(this->astCtxt->zx(bvSize - op2->getBitvectorSize(), op2), this->astCtxt->bv(1, bvSize)),
2172 this->astCtxt->bvxor(
2173 this->astCtxt->extract(high, high, this->astCtxt->reference(parent)),
2174 this->symbolicEngine->getOperandAst(inst, cf)
2175 ),
2176 this->symbolicEngine->getOperandAst(of)
2177 );
2178
2179 /* Create the symbolic expression */
2180 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag");
2181
2182 if (op2->evaluate()) {
2183 /* Spread the taint from the parent to the child */
2184 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted);
2185 }
2186 else {
2187 inst.removeReadRegister(cf.getConstRegister());
2188 inst.removeWrittenRegister(of.getConstRegister());
2189 }
2190 }
2191
2192
2193 void x86Semantics::ofRor_s(triton::arch::Instruction& inst,
2197 bool vol) {
2198
2199 auto bvSize = op2->getBitvectorSize();
2200 auto high = vol ? bvSize-1 : dst.getHigh();
2201 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
2202
2203 auto node = this->astCtxt->ite(
2204 this->astCtxt->equal(op2, this->astCtxt->bv(1, bvSize)),
2205 this->astCtxt->bvxor(
2206 this->astCtxt->extract(high, high, this->astCtxt->reference(parent)),
2207 this->astCtxt->extract(high-1, high-1, this->astCtxt->reference(parent))
2208 ),
2209 this->symbolicEngine->getOperandAst(of)
2210 );
2211
2212 /* Create the symbolic expression */
2213 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag");
2214
2215 if (op2->evaluate()) {
2216 /* Spread the taint from the parent to the child */
2217 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted);
2218 }
2219 else {
2220 inst.removeWrittenRegister(of.getConstRegister());
2221 }
2222 }
2223
2224
2225 void x86Semantics::ofRcr_s(triton::arch::Instruction& inst,
2230 bool vol) {
2231
2232 auto bvSize = op2->getBitvectorSize();
2233 auto high = dst.getBitSize()-1;
2234 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
2235 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
2236
2237 auto node = this->astCtxt->ite(
2238 this->astCtxt->equal(op2, this->astCtxt->bv(1, bvSize)),
2239 this->astCtxt->bvxor(
2240 this->astCtxt->extract(high, high, op1),
2241 this->symbolicEngine->getOperandAst(inst, cf)
2242 ),
2243 this->symbolicEngine->getOperandAst(of)
2244 );
2245
2246 /* Create the symbolic expression */
2247 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag");
2248
2249 if (op2->evaluate()) {
2250 /* Spread the taint from the parent to the child */
2251 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted);
2252 }
2253 else {
2254 inst.removeReadRegister(cf.getConstRegister());
2255 inst.removeWrittenRegister(of.getConstRegister());
2256 }
2257 }
2258
2259
2260 void x86Semantics::ofSar_s(triton::arch::Instruction& inst,
2264 bool vol) {
2265
2266 auto bvSize = dst.getBitSize();
2267 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
2268
2269 /*
2270 * Create the semantic.
2271 * of = 0 if op2 == 1
2272 */
2273 auto node = this->astCtxt->ite(
2274 this->astCtxt->land(
2275 this->astCtxt->equal(
2276 /* #672 */
2277 this->astCtxt->reference(parent),
2278 this->astCtxt->reference(parent)
2279 /* ---- */
2280 ),
2281 this->astCtxt->equal(
2282 op2,
2283 this->astCtxt->bv(1, bvSize)
2284 )
2285 ),
2286 this->astCtxt->bv(0, 1),
2287 this->symbolicEngine->getOperandAst(of)
2288 );
2289
2290 /* Create the symbolic expression */
2291 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag");
2292
2293 if (op2->evaluate()) {
2294 /* Spread the taint from the parent to the child */
2295 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted);
2296 }
2297 else {
2298 inst.removeWrittenRegister(of.getConstRegister());
2299 }
2300 }
2301
2302
2303 void x86Semantics::ofShl_s(triton::arch::Instruction& inst,
2308 bool vol) {
2309
2310 auto bvSize = dst.getBitSize();
2311 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
2312
2313 /*
2314 * Create the semantic.
2315 * of = ((op1 >> (bvSize - 1)) ^ (op1 >> (bvSize - 2))) & 1; if op2 == 1
2316 */
2317 auto node = this->astCtxt->ite(
2318 this->astCtxt->equal(
2319 op2,
2320 this->astCtxt->bv(1, bvSize)),
2321 this->astCtxt->extract(0, 0,
2322 this->astCtxt->bvxor(
2323 this->astCtxt->bvlshr(op1, this->astCtxt->bvsub(this->astCtxt->bv(bvSize, bvSize), this->astCtxt->bv(1, bvSize))),
2324 this->astCtxt->bvlshr(op1, this->astCtxt->bvsub(this->astCtxt->bv(bvSize, bvSize), this->astCtxt->bv(2, bvSize)))
2325 )
2326 ),
2327 this->symbolicEngine->getOperandAst(of)
2328 );
2329
2330 /* Create the symbolic expression */
2331 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag");
2332
2333 if (op2->evaluate()) {
2334 /* Spread the taint from the parent to the child */
2335 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted);
2336 }
2337 else {
2338 inst.removeWrittenRegister(of.getConstRegister());
2339 }
2340 }
2341
2342
2343 void x86Semantics::ofShld_s(triton::arch::Instruction& inst,
2349 bool vol) {
2350
2351 auto bvSize = dst.getBitSize();
2352 auto bv1Size = op1->getBitvectorSize();
2353 auto bv2Size = op2->getBitvectorSize();
2354 auto bv3Size = op3->getBitvectorSize();
2355 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
2356
2357 /*
2358 * Create the semantic.
2359 * of = MSB(rol(op3, concat(op2,op1))) ^ MSB(op1); if op3 == 1
2360 */
2361 auto node = this->astCtxt->ite(
2362 this->astCtxt->equal(
2363 this->astCtxt->zx(bvSize - bv3Size, op3),
2364 this->astCtxt->bv(1, bvSize)),
2365 this->astCtxt->bvxor(
2366 this->astCtxt->extract(
2367 bvSize-1, bvSize-1,
2368 this->astCtxt->bvrol(
2369 this->astCtxt->concat(op2, op1),
2370 this->astCtxt->zx(((bv1Size + bv2Size) - bv3Size), op3)
2371 )
2372 ),
2373 this->astCtxt->extract(bvSize-1, bvSize-1, op1)
2374 ),
2375 this->symbolicEngine->getOperandAst(of)
2376 );
2377
2378 /* Create the symbolic expression */
2379 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag");
2380
2381 if (op3->evaluate()) {
2382 /* Spread the taint from the parent to the child */
2383 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted);
2384 }
2385 else {
2386 inst.removeWrittenRegister(of.getConstRegister());
2387 }
2388 }
2389
2390
2391 void x86Semantics::ofShr_s(triton::arch::Instruction& inst,
2396 bool vol) {
2397
2398 auto bvSize = dst.getBitSize();
2399 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
2400
2401 /*
2402 * Create the semantic.
2403 * of = ((op1 >> (bvSize - 1)) & 1) if op2 == 1
2404 */
2405 auto node = this->astCtxt->ite(
2406 this->astCtxt->equal(
2407 op2,
2408 this->astCtxt->bv(1, bvSize)),
2409 this->astCtxt->extract(0, 0, this->astCtxt->bvlshr(op1, this->astCtxt->bvsub(this->astCtxt->bv(bvSize, bvSize), this->astCtxt->bv(1, bvSize)))),
2410 this->symbolicEngine->getOperandAst(of)
2411 );
2412
2413 /* Create the symbolic expression */
2414 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag");
2415
2416 if (op2->evaluate()) {
2417 /* Spread the taint from the parent to the child */
2418 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted);
2419 }
2420 else {
2421 inst.removeWrittenRegister(of.getConstRegister());
2422 }
2423 }
2424
2425
2426 void x86Semantics::ofShrd_s(triton::arch::Instruction& inst,
2432 bool vol) {
2433
2434 auto bvSize = dst.getBitSize();
2435 auto bv1Size = op1->getBitvectorSize();
2436 auto bv2Size = op2->getBitvectorSize();
2437 auto bv3Size = op3->getBitvectorSize();
2438 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
2439
2440 /*
2441 * Create the semantic.
2442 * of = MSB(ror(op3, concat(op2,op1))) ^ MSB(op1); if op3 == 1
2443 */
2444 auto node = this->astCtxt->ite(
2445 this->astCtxt->equal(
2446 this->astCtxt->zx(bvSize - op3->getBitvectorSize(), op3),
2447 this->astCtxt->bv(1, bvSize)),
2448 this->astCtxt->bvxor(
2449 this->astCtxt->extract(
2450 bvSize - 1, bvSize - 1,
2451 this->astCtxt->bvror(
2452 this->astCtxt->concat(op2, op1),
2453 this->astCtxt->zx(((bv1Size + bv2Size) - bv3Size), op3)
2454 )
2455 ),
2456 this->astCtxt->extract(dst.getBitSize()-1, dst.getBitSize()-1, op1)
2457 ),
2458 this->symbolicEngine->getOperandAst(of)
2459 );
2460
2461 /* Create the symbolic expression */
2462 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag");
2463
2464 if (op3->evaluate()) {
2465 /* Spread the taint from the parent to the child */
2466 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted);
2467 }
2468 else {
2469 inst.removeWrittenRegister(of.getConstRegister());
2470 }
2471 }
2472
2473
2474 void x86Semantics::ofSub_s(triton::arch::Instruction& inst,
2479 bool vol) {
2480
2481 auto bvSize = dst.getBitSize();
2482 auto low = vol ? 0 : dst.getLow();
2483 auto high = vol ? bvSize-1 : dst.getHigh();
2484
2485 /*
2486 * Create the semantic.
2487 * of = high:bool((op1 ^ op2) & (op1 ^ regDst))
2488 */
2489 auto node = this->astCtxt->extract(bvSize-1, bvSize-1,
2490 this->astCtxt->bvand(
2491 this->astCtxt->bvxor(op1, op2),
2492 this->astCtxt->bvxor(op1, this->astCtxt->extract(high, low, this->astCtxt->reference(parent)))
2493 )
2494 );
2495
2496 /* Create the symbolic expression */
2497 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_OF), "Overflow flag");
2498
2499 /* Spread the taint from the parent to the child */
2500 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_OF), parent->isTainted);
2501 }
2502
2503
2504 void x86Semantics::pf_s(triton::arch::Instruction& inst,
2507 bool vol) {
2508
2509 auto low = vol ? 0 : dst.getLow();
2510 auto high = vol ? triton::bitsize::byte-1 : !low ? triton::bitsize::byte-1 : triton::bitsize::word-1;
2511
2512 /*
2513 * Create the semantics.
2514 *
2515 * pf is set to one if there is an even number of bit set to 1 in the least
2516 * significant byte of the result.
2517 */
2518 auto node = this->astCtxt->bv(1, 1);
2519 for (triton::uint32 counter = 0; counter <= triton::bitsize::byte-1; counter++) {
2520 node = this->astCtxt->bvxor(node, this->astCtxt->extract(counter, counter, this->astCtxt->reference(parent)));
2521 }
2522
2523 /* Create the symbolic expression */
2524 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_PF), "Parity flag");
2525
2526 /* Spread the taint from the parent to the child */
2527 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_PF), parent->isTainted);
2528 }
2529
2530
2531 void x86Semantics::pfShl_s(triton::arch::Instruction& inst,
2535 bool vol) {
2536
2537 auto bvSize = dst.getBitSize();
2538 auto low = vol ? 0 : dst.getLow();
2539 auto high = vol ? triton::bitsize::byte-1 : !low ? triton::bitsize::byte-1 : triton::bitsize::word-1;
2540 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
2541
2542 /*
2543 * Create the semantics.
2544 * pf if op2 != 0
2545 */
2546 auto node1 = this->astCtxt->bv(1, 1);
2547 for (triton::uint32 counter = 0; counter <= triton::bitsize::byte-1; counter++) {
2548 node1 = this->astCtxt->bvxor(node1, this->astCtxt->extract(counter, counter, this->astCtxt->reference(parent)));
2549 }
2550
2551 auto node2 = this->astCtxt->ite(
2552 this->astCtxt->equal(this->astCtxt->zx(bvSize - op2->getBitvectorSize(), op2), this->astCtxt->bv(0, bvSize)),
2553 this->symbolicEngine->getOperandAst(pf),
2554 node1
2555 );
2556
2557 /* Create the symbolic expression */
2558 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, pf.getConstRegister(), "Parity flag");
2559
2560 if (op2->evaluate()) {
2561 /* Spread the taint from the parent to the child */
2562 expr->isTainted = this->taintEngine->setTaintRegister(pf.getConstRegister(), parent->isTainted);
2563 }
2564 else {
2565 inst.removeWrittenRegister(pf.getConstRegister());
2566 }
2567 }
2568
2569
2570 void x86Semantics::sf_s(triton::arch::Instruction& inst,
2573 bool vol) {
2574
2575 auto bvSize = dst.getBitSize();
2576 auto high = vol ? bvSize-1 : dst.getHigh();
2577
2578 /*
2579 * Create the semantic.
2580 * sf = high:bool(regDst)
2581 */
2582 auto node = this->astCtxt->extract(high, high, this->astCtxt->reference(parent));
2583
2584 /* Create the symbolic expression */
2585 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_SF), "Sign flag");
2586
2587 /* Spread the taint from the parent to the child */
2588 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_SF), parent->isTainted);
2589 }
2590
2591
2592 void x86Semantics::sfShl_s(triton::arch::Instruction& inst,
2596 bool vol) {
2597
2598 auto bvSize = dst.getBitSize();
2599 auto high = vol ? bvSize-1 : dst.getHigh();
2600 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
2601
2602 /*
2603 * Create the semantic.
2604 * sf if op2 != 0
2605 */
2606 auto node = this->astCtxt->ite(
2607 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)),
2608 this->symbolicEngine->getOperandAst(sf),
2609 this->astCtxt->extract(high, high, this->astCtxt->reference(parent))
2610 );
2611
2612 /* Create the symbolic expression */
2613 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, sf.getConstRegister(), "Sign flag");
2614
2615 if (op2->evaluate()) {
2616 /* Spread the taint from the parent to the child */
2617 expr->isTainted = this->taintEngine->setTaintRegister(sf.getConstRegister(), parent->isTainted);
2618 }
2619 else {
2620 inst.removeWrittenRegister(sf.getConstRegister());
2621 }
2622 }
2623
2624
2625 void x86Semantics::sfShld_s(triton::arch::Instruction& inst,
2631 bool vol) {
2632
2633 auto bvSize = dst.getBitSize();
2634 auto bv1Size = op1->getBitvectorSize();
2635 auto bv2Size = op2->getBitvectorSize();
2636 auto bv3Size = op3->getBitvectorSize();
2637 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
2638
2639 /*
2640 * Create the semantic.
2641 * MSB(rol(op3, concat(op2,op1))) if op3 != 0
2642 */
2643 auto node = this->astCtxt->ite(
2644 this->astCtxt->equal(op3, this->astCtxt->bv(0, bv3Size)),
2645 this->symbolicEngine->getOperandAst(sf),
2646 this->astCtxt->extract(
2647 bvSize-1, bvSize-1,
2648 this->astCtxt->bvrol(
2649 this->astCtxt->concat(op2, op1),
2650 this->astCtxt->zx(((bv1Size + bv2Size) - bv3Size), op3)
2651 )
2652 )
2653 );
2654
2655 /* Create the symbolic expression */
2656 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, sf.getConstRegister(), "Sign flag");
2657
2658 if (op3->evaluate()) {
2659 /* Spread the taint from the parent to the child */
2660 expr->isTainted = this->taintEngine->setTaintRegister(sf.getConstRegister(), parent->isTainted);
2661 }
2662 else {
2663 inst.removeWrittenRegister(sf.getConstRegister());
2664 }
2665 }
2666
2667
2668 void x86Semantics::sfShrd_s(triton::arch::Instruction& inst,
2674 bool vol) {
2675
2676 auto bvSize = dst.getBitSize();
2677 auto bv1Size = op1->getBitvectorSize();
2678 auto bv2Size = op2->getBitvectorSize();
2679 auto bv3Size = op3->getBitvectorSize();
2680 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
2681
2682 /*
2683 * Create the semantic.
2684 * MSB(ror(op3, concat(op2,op1))) if op3 != 0
2685 */
2686 auto node = this->astCtxt->ite(
2687 this->astCtxt->equal(op3, this->astCtxt->bv(0, bv3Size)),
2688 this->symbolicEngine->getOperandAst(sf),
2689 this->astCtxt->extract(
2690 bvSize - 1, bvSize - 1,
2691 this->astCtxt->bvror(
2692 this->astCtxt->concat(op2, op1),
2693 this->astCtxt->zx(((bv1Size + bv2Size) - bv3Size), op3)
2694 )
2695 )
2696 );
2697
2698 /* Create the symbolic expression */
2699 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, sf.getConstRegister(), "Sign flag");
2700
2701 if (op3->evaluate()) {
2702 /* Spread the taint from the parent to the child */
2703 expr->isTainted = this->taintEngine->setTaintRegister(sf.getConstRegister(), parent->isTainted);
2704 }
2705 else {
2706 inst.removeWrittenRegister(sf.getConstRegister());
2707 }
2708 }
2709
2710
2711 void x86Semantics::zf_s(triton::arch::Instruction& inst,
2714 bool vol) {
2715
2716 auto bvSize = dst.getBitSize();
2717 auto low = vol ? 0 : dst.getLow();
2718 auto high = vol ? bvSize-1 : dst.getHigh();
2719
2720 /*
2721 * Create the semantic.
2722 * zf = 0 == regDst
2723 */
2724 auto node = this->astCtxt->ite(
2725 this->astCtxt->equal(
2726 this->astCtxt->extract(high, low, this->astCtxt->reference(parent)),
2727 this->astCtxt->bv(0, bvSize)
2728 ),
2729 this->astCtxt->bv(1, 1),
2730 this->astCtxt->bv(0, 1)
2731 );
2732
2733 /* Create the symbolic expression */
2734 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_ZF), "Zero flag");
2735
2736 /* Spread the taint from the parent to the child */
2737 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_ZF), parent->isTainted);
2738 }
2739
2740
2741 void x86Semantics::zfBsf_s(triton::arch::Instruction& inst,
2745 bool vol) {
2746
2747 /*
2748 * Create the semantic.
2749 * zf = 1 if op2 == 0 else 0
2750 */
2751 auto node = this->astCtxt->ite(
2752 this->astCtxt->equal(op2, this->astCtxt->bv(0, src.getBitSize())),
2753 this->astCtxt->bvtrue(),
2754 this->astCtxt->bvfalse()
2755 );
2756
2757 /* Create the symbolic expression */
2758 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_ZF), "Zero flag");
2759
2760 /* Spread the taint from the parent to the child */
2761 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_ZF), parent->isTainted);
2762 }
2763
2764
2765 void x86Semantics::zfShl_s(triton::arch::Instruction& inst,
2769 bool vol) {
2770
2771 auto bvSize = dst.getBitSize();
2772 auto low = vol ? 0 : dst.getLow();
2773 auto high = vol ? bvSize-1 : dst.getHigh();
2774 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
2775
2776 /*
2777 * Create the semantic.
2778 * zf if op2 != 0
2779 */
2780 auto node = this->astCtxt->ite(
2781 this->astCtxt->equal(this->astCtxt->zx(bvSize - op2->getBitvectorSize(), op2), this->astCtxt->bv(0, bvSize)),
2782 this->symbolicEngine->getOperandAst(zf),
2783 this->astCtxt->ite(
2784 this->astCtxt->equal(
2785 this->astCtxt->extract(high, low, this->astCtxt->reference(parent)),
2786 this->astCtxt->bv(0, bvSize)
2787 ),
2788 this->astCtxt->bv(1, 1),
2789 this->astCtxt->bv(0, 1)
2790 )
2791 );
2792
2793 /* Create the symbolic expression */
2794 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, zf.getConstRegister(), "Zero flag");
2795
2796 if (op2->evaluate()) {
2797 /* Spread the taint from the parent to the child */
2798 expr->isTainted = this->taintEngine->setTaintRegister(zf.getConstRegister(), parent->isTainted);
2799 }
2800 else {
2801 inst.removeWrittenRegister(zf.getConstRegister());
2802 }
2803 }
2804
2805
2806 void x86Semantics::aaa_s(triton::arch::Instruction& inst) {
2807 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
2808 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AH));
2809 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF));
2810 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
2811 auto dsttmp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
2812
2813 /* Create symbolic operands */
2814 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
2815 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
2816 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
2817
2818 /* Create the semantics */
2819 auto node = this->astCtxt->ite(
2820 // if
2821 this->astCtxt->lor(
2822 this->astCtxt->bvugt(
2823 this->astCtxt->bvand(op1, this->astCtxt->bv(0xf, src1.getBitSize())),
2824 this->astCtxt->bv(9, src1.getBitSize())
2825 ),
2826 this->astCtxt->equal(op3, this->astCtxt->bvtrue())
2827 ),
2828 // then
2829 this->astCtxt->concat(
2830 this->astCtxt->bvadd(op2, this->astCtxt->bv(1, src2.getBitSize())),
2831 this->astCtxt->bvand(
2832 this->astCtxt->bvadd(op1, this->astCtxt->bv(6, src1.getBitSize())),
2833 this->astCtxt->bv(0xf, src1.getBitSize())
2834 )
2835 ),
2836 // else
2837 this->astCtxt->concat(
2838 op2,
2839 this->astCtxt->bvand(op1, this->astCtxt->bv(0xf, src1.getBitSize()))
2840 )
2841 );
2842
2843 /* Create symbolic expression */
2844 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "AAA operation");
2845
2846 /* Spread taint */
2847 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
2848
2849 /* Update symbolic flags */
2850 this->afAaa_s(inst, expr, dsttmp, op1, op3);
2851 this->cfAaa_s(inst, expr, dsttmp, op1, op3);
2852
2853 /* Tag undefined flags */
2854 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
2855 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
2856 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
2857 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF));
2858
2859 /* Update the symbolic control flow */
2860 this->controlFlow_s(inst);
2861 }
2862
2863
2864 void x86Semantics::aad_s(triton::arch::Instruction& inst) {
2866 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
2867 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AH));
2868 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
2869 auto dsttmp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
2870
2871 /* D5 ib */
2872 if (inst.operands.size() == 1)
2873 src1 = inst.operands[0];
2874
2875 /* Create symbolic operands */
2876 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
2877 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
2878 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
2879
2880 /* Create the semantics */
2881 auto node = this->astCtxt->zx(
2883 this->astCtxt->bvadd(
2884 op2,
2885 this->astCtxt->bvmul(op3, op1)
2886 )
2887 );
2888
2889 /* Create symbolic expression */
2890 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "AAD operation");
2891
2892 /* Spread taint */
2893 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
2894
2895 /* Update symbolic flags */
2896 this->pf_s(inst, expr, dsttmp);
2897 this->sf_s(inst, expr, dsttmp);
2898 this->zf_s(inst, expr, dsttmp);
2899
2900 /* Tag undefined flags */
2901 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
2902 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
2903 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
2904
2905 /* Update the symbolic control flow */
2906 this->controlFlow_s(inst);
2907 }
2908
2909
2910 void x86Semantics::aam_s(triton::arch::Instruction& inst) {
2912 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
2913 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
2914 auto dsttmp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
2915
2916 /* D4 ib */
2917 if (inst.operands.size() == 1)
2918 src1 = inst.operands[0];
2919
2920 /* Create symbolic operands */
2921 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
2922 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
2923
2924 /* Create the semantics */
2925 auto node = this->astCtxt->concat(
2926 this->astCtxt->bvudiv(op2, op1),
2927 this->astCtxt->bvurem(op2, op1)
2928 );
2929
2930 /* Create symbolic expression */
2931 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "AAM operation");
2932
2933 /* Spread taint */
2934 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
2935
2936 /* Update symbolic flags */
2937 this->pf_s(inst, expr, dsttmp);
2938 this->sf_s(inst, expr, dsttmp);
2939 this->zf_s(inst, expr, dsttmp);
2940
2941 /* Tag undefined flags */
2942 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
2943 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
2944 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
2945
2946 /* Update the symbolic control flow */
2947 this->controlFlow_s(inst);
2948 }
2949
2950
2951 void x86Semantics::aas_s(triton::arch::Instruction& inst) {
2952 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
2953 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AH));
2954 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF));
2955 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
2956 auto dsttmp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
2957
2958 /* Create symbolic operands */
2959 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
2960 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
2961 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
2962
2963 /* Create the semantics */
2964 auto node = this->astCtxt->ite(
2965 // if
2966 this->astCtxt->lor(
2967 this->astCtxt->bvugt(
2968 this->astCtxt->bvand(op1, this->astCtxt->bv(0xf, src1.getBitSize())),
2969 this->astCtxt->bv(9, src1.getBitSize())
2970 ),
2971 this->astCtxt->equal(op3, this->astCtxt->bvtrue())
2972 ),
2973 // then
2974 this->astCtxt->concat(
2975 this->astCtxt->bvsub(op2, this->astCtxt->bv(1, src2.getBitSize())),
2976 this->astCtxt->bvand(
2977 this->astCtxt->bvsub(op1, this->astCtxt->bv(6, src1.getBitSize())),
2978 this->astCtxt->bv(0xf, src1.getBitSize())
2979 )
2980 ),
2981 // else
2982 this->astCtxt->concat(
2983 op2,
2984 this->astCtxt->bvand(op1, this->astCtxt->bv(0xf, src1.getBitSize()))
2985 )
2986 );
2987
2988 /* Create symbolic expression */
2989 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "AAS operation");
2990
2991 /* Spread taint */
2992 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
2993
2994 /* Update symbolic flags */
2995 this->afAaa_s(inst, expr, dsttmp, op1, op3);
2996 this->cfAaa_s(inst, expr, dsttmp, op1, op3);
2997
2998 /* Tag undefined flags */
2999 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
3000 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
3001 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
3002 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF));
3003
3004 /* Update the symbolic control flow */
3005 this->controlFlow_s(inst);
3006 }
3007
3008
3009 void x86Semantics::adc_s(triton::arch::Instruction& inst) {
3010 auto& dst = inst.operands[0];
3011 auto& src = inst.operands[1];
3012 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
3013
3014 /* Create symbolic operands */
3015 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3016 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3017 auto op3 = this->symbolicEngine->getOperandAst(inst, cf);
3018
3019 /* Create the semantics */
3020 auto node = this->astCtxt->bvadd(this->astCtxt->bvadd(op1, op2), this->astCtxt->zx(dst.getBitSize()-1, op3));
3021
3022 /* Create symbolic expression */
3023 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ADC operation");
3024
3025 /* Spread taint */
3026 expr->isTainted = this->taintEngine->taintUnion(dst, src);
3027 expr->isTainted = this->taintEngine->taintUnion(dst, cf);
3028
3029 /* Update symbolic flags */
3030 this->af_s(inst, expr, dst, op1, op2);
3031 this->cfAdd_s(inst, expr, dst, op1, op2);
3032 this->ofAdd_s(inst, expr, dst, op1, op2);
3033 this->pf_s(inst, expr, dst);
3034 this->sf_s(inst, expr, dst);
3035 this->zf_s(inst, expr, dst);
3036
3037 /* Update the symbolic control flow */
3038 this->controlFlow_s(inst);
3039 }
3040
3041
3042 void x86Semantics::adcx_s(triton::arch::Instruction& inst) {
3043 auto& dst = inst.operands[0];
3044 auto& src = inst.operands[1];
3045 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
3046
3047 /* Create symbolic operands */
3048 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3049 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3050 auto op3 = this->symbolicEngine->getOperandAst(inst, cf);
3051
3052 /* Create the semantics */
3053 auto node = this->astCtxt->bvadd(this->astCtxt->bvadd(op1, op2), this->astCtxt->zx(dst.getBitSize()-1, op3));
3054
3055 /* Create symbolic expression */
3056 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ADCX operation");
3057
3058 /* Spread taint */
3059 expr->isTainted = this->taintEngine->taintUnion(dst, src);
3060 expr->isTainted = this->taintEngine->taintUnion(dst, cf);
3061
3062 /* Update symbolic flags */
3063 this->cfAdd_s(inst, expr, dst, op1, op2);
3064
3065 /* Update the symbolic control flow */
3066 this->controlFlow_s(inst);
3067 }
3068
3069
3070 void x86Semantics::add_s(triton::arch::Instruction& inst) {
3071 auto& dst = inst.operands[0];
3072 auto& src = inst.operands[1];
3073
3074 /* Create symbolic operands */
3075 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3076 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3077
3078 /* Create the semantics */
3079 auto node = this->astCtxt->bvadd(op1, op2);
3080
3081 /* Create symbolic expression */
3082 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ADD operation");
3083
3084 /* Spread taint */
3085 expr->isTainted = this->taintEngine->taintUnion(dst, src);
3086
3087 /* Update symbolic flags */
3088 this->af_s(inst, expr, dst, op1, op2);
3089 this->cfAdd_s(inst, expr, dst, op1, op2);
3090 this->ofAdd_s(inst, expr, dst, op1, op2);
3091 this->pf_s(inst, expr, dst);
3092 this->sf_s(inst, expr, dst);
3093 this->zf_s(inst, expr, dst);
3094
3095 /* Update the symbolic control flow */
3096 this->controlFlow_s(inst);
3097 }
3098
3099
3100 void x86Semantics::and_s(triton::arch::Instruction& inst) {
3101 auto& dst = inst.operands[0];
3102 auto& src = inst.operands[1];
3103
3104 /* Create symbolic operands */
3105 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3106 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3107
3108 /* Create the semantics */
3109 auto node = this->astCtxt->bvand(op1, op2);
3110
3111 /* Create symbolic expression */
3112 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "AND operation");
3113
3114 /* Spread taint */
3115 expr->isTainted = this->taintEngine->taintUnion(dst, src);
3116
3117 /* Update symbolic flags */
3118 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag");
3119 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
3120 this->pf_s(inst, expr, dst);
3121 this->sf_s(inst, expr, dst);
3122 this->zf_s(inst, expr, dst);
3123
3124 /* Tag undefined flags */
3125 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
3126
3127 /* Update the symbolic control flow */
3128 this->controlFlow_s(inst);
3129 }
3130
3131
3132 void x86Semantics::andn_s(triton::arch::Instruction& inst) {
3133 auto& dst = inst.operands[0];
3134 auto& src1 = inst.operands[1];
3135 auto& src2 = inst.operands[2];
3136
3137 /* Create symbolic operands */
3138 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
3139 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
3140
3141 /* Create the semantics */
3142 auto node = this->astCtxt->bvand(this->astCtxt->bvnot(op2), op3);
3143
3144 /* Create symbolic expression */
3145 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ANDN operation");
3146
3147 /* Spread taint */
3148 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
3149
3150 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag");
3151 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
3152 this->sf_s(inst, expr, dst);
3153 this->zf_s(inst, expr, dst);
3154
3155 /* Update the symbolic control flow */
3156 this->controlFlow_s(inst);
3157 }
3158
3159
3160 void x86Semantics::andnpd_s(triton::arch::Instruction& inst) {
3161 auto& dst = inst.operands[0];
3162 auto& src = inst.operands[1];
3163
3164 /* Create symbolic operands */
3165 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3166 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3167
3168 /* Create the semantics */
3169 auto node = this->astCtxt->bvand(this->astCtxt->bvnot(op1), op2);
3170
3171 /* Create symbolic expression */
3172 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ANDNPD operation");
3173
3174 /* Spread taint */
3175 expr->isTainted = this->taintEngine->taintUnion(dst, src);
3176
3177 /* Update the symbolic control flow */
3178 this->controlFlow_s(inst);
3179 }
3180
3181
3182 void x86Semantics::andnps_s(triton::arch::Instruction& inst) {
3183 auto& dst = inst.operands[0];
3184 auto& src = inst.operands[1];
3185
3186 /* Create symbolic operands */
3187 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3188 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3189
3190 /* Create the semantics */
3191 auto node = this->astCtxt->bvand(this->astCtxt->bvnot(op1), op2);
3192
3193 /* Create symbolic expression */
3194 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ANDNPS operation");
3195
3196 /* Spread taint */
3197 expr->isTainted = this->taintEngine->taintUnion(dst, src);
3198
3199 /* Update the symbolic control flow */
3200 this->controlFlow_s(inst);
3201 }
3202
3203
3204 void x86Semantics::andpd_s(triton::arch::Instruction& inst) {
3205 auto& dst = inst.operands[0];
3206 auto& src = inst.operands[1];
3207
3208 /* Create symbolic operands */
3209 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3210 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3211
3212 /* Create the semantics */
3213 auto node = this->astCtxt->bvand(op1, op2);
3214
3215 /* Create symbolic expression */
3216 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ANDPD operation");
3217
3218 /* Spread taint */
3219 expr->isTainted = this->taintEngine->taintUnion(dst, src);
3220
3221 /* Update the symbolic control flow */
3222 this->controlFlow_s(inst);
3223 }
3224
3225
3226 void x86Semantics::andps_s(triton::arch::Instruction& inst) {
3227 auto& dst = inst.operands[0];
3228 auto& src = inst.operands[1];
3229
3230 /* Create symbolic operands */
3231 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3232 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3233
3234 /* Create the semantics */
3235 auto node = this->astCtxt->bvand(op1, op2);
3236
3237 /* Create symbolic expression */
3238 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ANDPS operation");
3239
3240 /* Spread taint */
3241 expr->isTainted = this->taintEngine->taintUnion(dst, src);
3242
3243 /* Update the symbolic control flow */
3244 this->controlFlow_s(inst);
3245 }
3246
3247
3248 void x86Semantics::bextr_s(triton::arch::Instruction& inst) {
3249 auto& dst = inst.operands[0];
3250 auto& src1 = inst.operands[1];
3251 auto& src2 = inst.operands[2];
3252
3253 /* Create symbolic operands */
3254 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
3255 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
3256
3257 /* Create the semantics */
3258 auto node = this->astCtxt->bvand(
3259 this->astCtxt->bvlshr(
3260 op1,
3261 this->astCtxt->zx(src1.getBitSize() - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2))
3262 ),
3263 this->astCtxt->bvsub(
3264 this->astCtxt->bvshl(
3265 this->astCtxt->bv(1, src1.getBitSize()),
3266 this->astCtxt->zx(src1.getBitSize() - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2))
3267 ),
3268 this->astCtxt->bv(1, src1.getBitSize())
3269 )
3270 );
3271
3272 /* Create symbolic expression */
3273 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "BEXTR operation");
3274
3275 /* Spread taint */
3276 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
3277
3278 /* Update symbolic flags */
3279 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag");
3280 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
3281 this->zf_s(inst, expr, dst);
3282
3283 /* Update the symbolic control flow */
3284 this->controlFlow_s(inst);
3285 }
3286
3287
3288 void x86Semantics::blsi_s(triton::arch::Instruction& inst) {
3289 auto& dst = inst.operands[0];
3290 auto& src = inst.operands[1];
3291
3292 /* Create symbolic operands */
3293 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
3294
3295 /* Create the semantics */
3296 auto node = this->astCtxt->bvand(this->astCtxt->bvneg(op1), op1);
3297
3298 /* Create symbolic expression */
3299 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "BLSI operation");
3300
3301 /* Spread taint */
3302 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
3303
3304 /* Update symbolic flags */
3305 this->cfBlsi_s(inst, expr, src, op1);
3306 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
3307 this->sf_s(inst, expr, dst);
3308 this->zf_s(inst, expr, dst);
3309
3310 /* Update the symbolic control flow */
3311 this->controlFlow_s(inst);
3312 }
3313
3314
3315 void x86Semantics::blsmsk_s(triton::arch::Instruction& inst) {
3316 auto& dst = inst.operands[0];
3317 auto& src = inst.operands[1];
3318
3319 /* Create symbolic operands */
3320 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
3321
3322 /* Create the semantics */
3323 auto node = this->astCtxt->bvxor(
3324 this->astCtxt->bvsub(op1, this->astCtxt->bv(1, src.getBitSize())),
3325 op1
3326 );
3327
3328 /* Create symbolic expression */
3329 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "BLSMSK operation");
3330
3331 /* Spread taint */
3332 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
3333
3334 /* Update symbolic flags */
3335 this->cfBlsmsk_s(inst, expr, src, op1);
3336 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
3337 this->sf_s(inst, expr, dst);
3338 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_ZF), "Clears zero flag");
3339
3340 /* Update the symbolic control flow */
3341 this->controlFlow_s(inst);
3342 }
3343
3344
3345 void x86Semantics::blsr_s(triton::arch::Instruction& inst) {
3346 auto& dst = inst.operands[0];
3347 auto& src = inst.operands[1];
3348
3349 /* Create symbolic operands */
3350 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
3351
3352 /* Create the semantics */
3353 auto node = this->astCtxt->bvand(
3354 this->astCtxt->bvsub(op1, this->astCtxt->bv(1, src.getBitSize())),
3355 op1
3356 );
3357
3358 /* Create symbolic expression */
3359 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "BLSR operation");
3360
3361 /* Spread taint */
3362 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
3363
3364 /* Update symbolic flags */
3365 this->cfBlsr_s(inst, expr, src, op1);
3366 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
3367 this->sf_s(inst, expr, dst);
3368 this->zf_s(inst, expr, dst);
3369
3370 /* Update the symbolic control flow */
3371 this->controlFlow_s(inst);
3372 }
3373
3374
3375 void x86Semantics::bsf_s(triton::arch::Instruction& inst) {
3376 auto& dst = inst.operands[0];
3377 auto& src = inst.operands[1];
3378 auto bvSize1 = dst.getBitSize();
3379 auto bvSize2 = src.getBitSize();
3380
3381 /* Create symbolic operands */
3382 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3383 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3384
3385 /* Create the semantics */
3386 triton::ast::SharedAbstractNode node = nullptr;
3387 switch (src.getSize()) {
3388 case triton::size::byte:
3389 node = this->astCtxt->ite(
3390 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSF only if op2 != 0 */
3391 op1,
3392 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
3393 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
3394 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
3395 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
3396 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
3397 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
3398 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
3399 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
3400 this->astCtxt->bv(0, bvSize1)
3401 ))))))))
3402 );
3403 break;
3404 case triton::size::word:
3405 node = this->astCtxt->ite(
3406 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSF only if op2 != 0 */
3407 op1,
3408 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
3409 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
3410 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
3411 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
3412 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
3413 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
3414 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
3415 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
3416 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
3417 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
3418 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
3419 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
3420 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
3421 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
3422 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
3423 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
3424 this->astCtxt->bv(0, bvSize1)
3425 ))))))))))))))))
3426 );
3427 break;
3429 node = this->astCtxt->ite(
3430 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSF only if op2 != 0 */
3431 op1,
3432 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
3433 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
3434 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
3435 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
3436 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
3437 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
3438 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
3439 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
3440 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
3441 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
3442 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
3443 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
3444 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
3445 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
3446 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
3447 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
3448 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(16, 16, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1),
3449 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(17, 17, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1),
3450 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(18, 18, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1),
3451 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(19, 19, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1),
3452 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(20, 20, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1),
3453 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(21, 21, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1),
3454 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(22, 22, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1),
3455 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(23, 23, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1),
3456 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(24, 24, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1),
3457 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(25, 25, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1),
3458 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(26, 26, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1),
3459 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(27, 27, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1),
3460 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(28, 28, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1),
3461 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(29, 29, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1),
3462 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(30, 30, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1),
3463 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(31, 31, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1),
3464 this->astCtxt->bv(0, bvSize1)
3465 ))))))))))))))))))))))))))))))))
3466 );
3467 break;
3469 node = this->astCtxt->ite(
3470 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSF only if op2 != 0 */
3471 op1,
3472 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
3473 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
3474 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
3475 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
3476 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
3477 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
3478 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
3479 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
3480 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
3481 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
3482 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
3483 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
3484 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
3485 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
3486 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
3487 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
3488 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(16, 16, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1),
3489 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(17, 17, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1),
3490 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(18, 18, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1),
3491 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(19, 19, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1),
3492 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(20, 20, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1),
3493 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(21, 21, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1),
3494 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(22, 22, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1),
3495 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(23, 23, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1),
3496 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(24, 24, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1),
3497 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(25, 25, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1),
3498 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(26, 26, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1),
3499 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(27, 27, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1),
3500 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(28, 28, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1),
3501 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(29, 29, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1),
3502 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(30, 30, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1),
3503 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(31, 31, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1),
3504 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(32, 32, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(32, bvSize1),
3505 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(33, 33, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(33, bvSize1),
3506 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(34, 34, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(34, bvSize1),
3507 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(35, 35, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(35, bvSize1),
3508 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(36, 36, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(36, bvSize1),
3509 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(37, 37, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(37, bvSize1),
3510 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(38, 38, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(38, bvSize1),
3511 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(39, 39, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(39, bvSize1),
3512 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(40, 40, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(40, bvSize1),
3513 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(41, 41, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(41, bvSize1),
3514 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(42, 42, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(42, bvSize1),
3515 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(43, 43, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(43, bvSize1),
3516 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(44, 44, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(44, bvSize1),
3517 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(45, 45, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(45, bvSize1),
3518 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(46, 46, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(46, bvSize1),
3519 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(47, 47, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(47, bvSize1),
3520 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(48, 48, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(48, bvSize1),
3521 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(49, 49, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(49, bvSize1),
3522 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(50, 50, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(50, bvSize1),
3523 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(51, 51, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(51, bvSize1),
3524 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(52, 52, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(52, bvSize1),
3525 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(53, 53, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(53, bvSize1),
3526 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(54, 54, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(54, bvSize1),
3527 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(55, 55, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(55, bvSize1),
3528 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(56, 56, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(56, bvSize1),
3529 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(57, 57, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(57, bvSize1),
3530 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(58, 58, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(58, bvSize1),
3531 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(59, 59, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(59, bvSize1),
3532 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(60, 60, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(60, bvSize1),
3533 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(61, 61, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(61, bvSize1),
3534 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(62, 62, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(62, bvSize1),
3535 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(63, 63, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(63, bvSize1),
3536 this->astCtxt->bv(0, bvSize1)
3537 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
3538 );
3539 break;
3540 default:
3541 throw triton::exceptions::Semantics("x86Semantics::bsf_s(): Invalid operand size.");
3542 }
3543
3544 /* Create symbolic expression */
3545 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "BSF operation");
3546
3547 /* Spread taint */
3548 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
3549
3550 /* Update symbolic flags */
3551 this->zfBsf_s(inst, expr, src, op2);
3552
3553 /* Tag undefined flags */
3554 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
3555 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
3556 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
3557 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
3558 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
3559
3560 /* Update the symbolic control flow */
3561 this->controlFlow_s(inst);
3562 }
3563
3564
3565 void x86Semantics::bsr_s(triton::arch::Instruction& inst) {
3566 auto& dst = inst.operands[0];
3567 auto& src = inst.operands[1];
3568 auto bvSize1 = dst.getBitSize();
3569 auto bvSize2 = src.getBitSize();
3570
3571 /* Create symbolic operands */
3572 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
3573 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3574
3575 /* Create the semantics */
3576 triton::ast::SharedAbstractNode node = nullptr;
3577 switch (src.getSize()) {
3578 case triton::size::byte:
3579 node = this->astCtxt->ite(
3580 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSR only if op2 != 0 */
3581 op1,
3582 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
3583 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
3584 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
3585 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
3586 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
3587 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
3588 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
3589 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
3590 this->astCtxt->bv(0, bvSize1)
3591 ))))))))
3592 );
3593 break;
3594 case triton::size::word:
3595 node = this->astCtxt->ite(
3596 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSR only if op2 != 0 */
3597 op1,
3598 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
3599 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
3600 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
3601 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
3602 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
3603 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
3604 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
3605 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
3606 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
3607 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
3608 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
3609 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
3610 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
3611 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
3612 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
3613 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
3614 this->astCtxt->bv(0, bvSize1)
3615 ))))))))))))))))
3616 );
3617 break;
3619 node = this->astCtxt->ite(
3620 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSR only if op2 != 0 */
3621 op1,
3622 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(31, 31, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1),
3623 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(30, 30, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1),
3624 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(29, 29, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1),
3625 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(28, 28, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1),
3626 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(27, 27, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1),
3627 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(26, 26, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1),
3628 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(25, 25, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1),
3629 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(24, 24, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1),
3630 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(23, 23, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1),
3631 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(22, 22, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1),
3632 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(21, 21, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1),
3633 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(20, 20, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1),
3634 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(19, 19, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1),
3635 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(18, 18, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1),
3636 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(17, 17, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1),
3637 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(16, 16, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1),
3638 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
3639 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
3640 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
3641 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
3642 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
3643 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
3644 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
3645 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
3646 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
3647 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
3648 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
3649 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
3650 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
3651 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
3652 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
3653 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
3654 this->astCtxt->bv(0, bvSize1)
3655 ))))))))))))))))))))))))))))))))
3656 );
3657 break;
3659 node = this->astCtxt->ite(
3660 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSR only if op2 != 0 */
3661 op1,
3662 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(63, 63, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(63, bvSize1),
3663 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(62, 62, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(62, bvSize1),
3664 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(61, 61, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(61, bvSize1),
3665 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(60, 60, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(60, bvSize1),
3666 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(59, 59, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(59, bvSize1),
3667 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(58, 58, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(58, bvSize1),
3668 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(57, 57, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(57, bvSize1),
3669 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(56, 56, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(56, bvSize1),
3670 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(55, 55, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(55, bvSize1),
3671 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(54, 54, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(54, bvSize1),
3672 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(53, 53, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(53, bvSize1),
3673 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(52, 52, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(52, bvSize1),
3674 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(51, 51, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(51, bvSize1),
3675 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(50, 50, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(50, bvSize1),
3676 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(49, 49, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(49, bvSize1),
3677 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(48, 48, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(48, bvSize1),
3678 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(47, 47, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(47, bvSize1),
3679 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(46, 46, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(46, bvSize1),
3680 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(45, 45, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(45, bvSize1),
3681 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(44, 44, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(44, bvSize1),
3682 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(43, 43, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(43, bvSize1),
3683 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(42, 42, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(42, bvSize1),
3684 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(41, 41, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(41, bvSize1),
3685 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(40, 40, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(40, bvSize1),
3686 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(39, 39, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(39, bvSize1),
3687 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(38, 38, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(38, bvSize1),
3688 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(37, 37, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(37, bvSize1),
3689 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(36, 36, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(36, bvSize1),
3690 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(35, 35, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(35, bvSize1),
3691 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(34, 34, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(34, bvSize1),
3692 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(33, 33, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(33, bvSize1),
3693 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(32, 32, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(32, bvSize1),
3694 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(31, 31, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1),
3695 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(30, 30, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1),
3696 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(29, 29, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1),
3697 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(28, 28, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1),
3698 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(27, 27, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1),
3699 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(26, 26, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1),
3700 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(25, 25, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1),
3701 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(24, 24, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1),
3702 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(23, 23, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1),
3703 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(22, 22, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1),
3704 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(21, 21, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1),
3705 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(20, 20, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1),
3706 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(19, 19, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1),
3707 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(18, 18, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1),
3708 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(17, 17, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1),
3709 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(16, 16, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1),
3710 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
3711 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
3712 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
3713 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
3714 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
3715 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
3716 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
3717 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
3718 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
3719 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
3720 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
3721 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
3722 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
3723 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
3724 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
3725 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
3726 this->astCtxt->bv(0, bvSize1)
3727 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
3728 );
3729 break;
3730 default:
3731 throw triton::exceptions::Semantics("x86Semantics::bsr_s(): Invalid operand size.");
3732 }
3733
3734 /* Create symbolic expression */
3735 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "BSR operation");
3736
3737 /* Spread taint */
3738 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
3739
3740 /* Update symbolic flags */
3741 this->zfBsf_s(inst, expr, src, op2); /* same as bsf */
3742
3743 /* Tag undefined flags */
3744 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
3745 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
3746 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
3747 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
3748 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
3749
3750 /* Update the symbolic control flow */
3751 this->controlFlow_s(inst);
3752 }
3753
3754
3755 void x86Semantics::bswap_s(triton::arch::Instruction& inst) {
3756 auto& src = inst.operands[0];
3757
3758 /* Create symbolic operands */
3759 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
3760
3761 /* Create the semantics */
3762 std::list<triton::ast::SharedAbstractNode> bytes;
3763 switch (src.getSize()) {
3765 bytes.push_front(this->astCtxt->extract(63, 56, op1));
3766 bytes.push_front(this->astCtxt->extract(55, 48, op1));
3767 bytes.push_front(this->astCtxt->extract(47, 40, op1));
3768 bytes.push_front(this->astCtxt->extract(39, 32, op1));
3770 bytes.push_front(this->astCtxt->extract(31, 24, op1));
3771 bytes.push_front(this->astCtxt->extract(23, 16, op1));
3772 bytes.push_front(this->astCtxt->extract(15, 8, op1));
3773 bytes.push_front(this->astCtxt->extract(7, 0, op1));
3774 break;
3775 case triton::size::word:
3776 // See #1131
3777 bytes.push_front(this->astCtxt->bv(0, 8));
3778 bytes.push_front(this->astCtxt->bv(0, 8));
3779 break;
3780 default:
3781 throw triton::exceptions::Semantics("x86Semantics::bswap_s(): Invalid operand size.");
3782 }
3783
3784 auto node = this->astCtxt->concat(bytes);
3785
3786 /* Create symbolic expression */
3787 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, src, "BSWAP operation");
3788
3789 /* Spread taint */
3790 expr->isTainted = this->taintEngine->taintAssignment(src, src);
3791
3792 /* Tag undefined registers */
3793 if (src.getSize() == triton::size::word) {
3794 // When the BSWAP instruction references a 16-bit register, the result is undefined.
3795 this->undefined_s(inst, src.getRegister());
3796 }
3797
3798 /* Update the symbolic control flow */
3799 this->controlFlow_s(inst);
3800 }
3801
3802
3803 void x86Semantics::bt_s(triton::arch::Instruction& inst) {
3804 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
3805 auto& src1 = inst.operands[0];
3806 auto& src2 = inst.operands[1];
3807
3808 /* Create symbolic operands */
3809 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
3810 auto op2 = this->astCtxt->zx(src1.getBitSize() - src2.getBitSize(), this->symbolicEngine->getOperandAst(inst, src2));
3811
3812 /* Create the semantics */
3813 auto node = this->astCtxt->extract(0, 0,
3814 this->astCtxt->bvlshr(
3815 op1,
3816 this->astCtxt->bvsmod(
3817 op2,
3818 this->astCtxt->bv(src1.getBitSize(), src1.getBitSize())
3819 )
3820 )
3821 );
3822
3823 /* Create symbolic expression */
3824 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "BT operation");
3825
3826 /* Spread taint */
3827 expr->isTainted = this->taintEngine->taintUnion(dst, src1);
3828 expr->isTainted = this->taintEngine->taintUnion(dst, src2);
3829
3830 /* Tag undefined flags */
3831 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
3832 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
3833 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
3834 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
3835
3836 /* Update the symbolic control flow */
3837 this->controlFlow_s(inst);
3838 }
3839
3840
3841 void x86Semantics::btc_s(triton::arch::Instruction& inst) {
3842 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
3843 auto& dst2 = inst.operands[0];
3844 auto& src1 = inst.operands[1];
3845
3846 /* Create symbolic operands */
3847 auto op1 = this->symbolicEngine->getOperandAst(inst, dst2);
3848 auto op2 = this->astCtxt->zx(dst2.getBitSize() - src1.getBitSize(), this->symbolicEngine->getOperandAst(inst, src1));
3849
3850 /* Create the semantics */
3851 auto node1 = this->astCtxt->extract(0, 0,
3852 this->astCtxt->bvlshr(
3853 op1,
3854 this->astCtxt->bvsmod(
3855 op2,
3856 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize())
3857 )
3858 )
3859 );
3860 auto node2 = this->astCtxt->ite(
3861 this->astCtxt->equal(node1, this->astCtxt->bvfalse()),
3862 /* BTS */
3863 this->astCtxt->bvor(
3864 op1,
3865 this->astCtxt->bvshl(
3866 this->astCtxt->bv(1, dst2.getBitSize()),
3867 this->astCtxt->bvsmod(
3868 op2,
3869 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize())
3870 )
3871 )
3872 ),
3873 /* BTR */
3874 this->astCtxt->bvand(
3875 op1,
3876 this->astCtxt->bvsub(
3877 op1,
3878 this->astCtxt->bvshl(
3879 this->astCtxt->bv(1, dst2.getBitSize()),
3880 this->astCtxt->bvsmod(
3881 op2,
3882 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize())
3883 )
3884 )
3885 )
3886 )
3887 );
3888
3889 /* Create symbolic expression */
3890 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, this->architecture->getRegister(ID_REG_X86_CF), "BTC carry operation");
3891 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "BTC complement operation");
3892
3893 /* Spread taint */
3894 expr1->isTainted = this->taintEngine->taintUnion(dst1, dst2);
3895 expr1->isTainted = this->taintEngine->taintUnion(dst1, src1);
3896 expr2->isTainted = this->taintEngine->taintUnion(dst2, src1);
3897
3898 /* Tag undefined flags */
3899 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
3900 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
3901 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
3902 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
3903
3904 /* Update the symbolic control flow */
3905 this->controlFlow_s(inst);
3906 }
3907
3908
3909 void x86Semantics::btr_s(triton::arch::Instruction& inst) {
3910 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
3911 auto& dst2 = inst.operands[0];
3912 auto& src1 = inst.operands[1];
3913
3914 /* Create symbolic operands */
3915 auto op1 = this->symbolicEngine->getOperandAst(inst, dst2);
3916 auto op2 = this->astCtxt->zx(dst2.getBitSize() - src1.getBitSize(), this->symbolicEngine->getOperandAst(inst, src1));
3917
3918 /* Create the semantics */
3919 auto node1 = this->astCtxt->extract(0, 0,
3920 this->astCtxt->bvlshr(
3921 op1,
3922 this->astCtxt->bvsmod(
3923 op2,
3924 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize())
3925 )
3926 )
3927 );
3928 auto node2 = this->astCtxt->ite(
3929 this->astCtxt->equal(node1, this->astCtxt->bvfalse()),
3930 op1,
3931 this->astCtxt->bvand(
3932 op1,
3933 this->astCtxt->bvsub(
3934 op1,
3935 this->astCtxt->bvshl(
3936 this->astCtxt->bv(1, dst2.getBitSize()),
3937 this->astCtxt->bvsmod(
3938 op2,
3939 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize())
3940 )
3941 )
3942 )
3943 )
3944 );
3945
3946 /* Create symbolic expression */
3947 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, this->architecture->getRegister(ID_REG_X86_CF), "BTR carry operation");
3948 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "BTR reset operation");
3949
3950 /* Spread taint */
3951 expr1->isTainted = this->taintEngine->taintUnion(dst1, dst2);
3952 expr1->isTainted = this->taintEngine->taintUnion(dst1, src1);
3953 expr2->isTainted = this->taintEngine->taintUnion(dst2, src1);
3954
3955 /* Tag undefined flags */
3956 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
3957 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
3958 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
3959 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
3960
3961 /* Update the symbolic control flow */
3962 this->controlFlow_s(inst);
3963 }
3964
3965
3966 void x86Semantics::bts_s(triton::arch::Instruction& inst) {
3967 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
3968 auto& dst2 = inst.operands[0];
3969 auto& src1 = inst.operands[1];
3970
3971 /* Create symbolic operands */
3972 auto op1 = this->symbolicEngine->getOperandAst(inst, dst2);
3973 auto op2 = this->astCtxt->zx(dst2.getBitSize() - src1.getBitSize(), this->symbolicEngine->getOperandAst(inst, src1));
3974
3975 /* Create the semantics */
3976 auto node1 = this->astCtxt->extract(0, 0,
3977 this->astCtxt->bvlshr(
3978 op1,
3979 this->astCtxt->bvsmod(
3980 op2,
3981 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize())
3982 )
3983 )
3984 );
3985 auto node2 = this->astCtxt->bvor(
3986 op1,
3987 this->astCtxt->bvshl(
3988 this->astCtxt->bv(1, dst2.getBitSize()),
3989 this->astCtxt->bvsmod(
3990 op2,
3991 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize())
3992 )
3993 )
3994 );
3995
3996 /* Create symbolic expression */
3997 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, this->architecture->getRegister(ID_REG_X86_CF), "BTS carry operation");
3998 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "BTS set operation");
3999
4000 /* Spread taint */
4001 expr1->isTainted = this->taintEngine->taintUnion(dst1, dst2);
4002 expr1->isTainted = this->taintEngine->taintUnion(dst1, src1);
4003 expr2->isTainted = this->taintEngine->taintUnion(dst2, src1);
4004
4005 /* Tag undefined flags */
4006 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
4007 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
4008 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
4009 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
4010
4011 /* Update the symbolic control flow */
4012 this->controlFlow_s(inst);
4013 }
4014
4015
4016 void x86Semantics::call_s(triton::arch::Instruction& inst) {
4017 auto& src = inst.operands[0];
4018
4019 /* Create symbolic operands */
4020 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
4021
4022 /* Create the semantics - side effect */
4023 auto stack = this->architecture->getStackPointer();
4024 auto stackValue = alignSubStack_s(inst, stack.getSize());
4025 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
4026 auto sp = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize()));
4027
4028 auto node1 = this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize());
4029
4030 /* Create the semantics */
4031 auto node2 = op1;
4032
4033 /* Create the symbolic expression */
4034 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, sp, "Saved Program Counter");
4035
4036 /* Create symbolic expression */
4037 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, pc, "Program Counter");
4038
4039 /* Spread taint */
4040 expr1->isTainted = this->taintEngine->untaintMemory(sp.getMemory());
4041 expr2->isTainted = this->taintEngine->taintAssignment(pc, src);
4042
4043 /* Create the path constraint */
4044 this->symbolicEngine->pushPathConstraint(inst, expr2);
4045 }
4046
4047
4048 void x86Semantics::cbw_s(triton::arch::Instruction& inst) {
4049 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
4050
4051 /* Create symbolic operands */
4052 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4053
4054 /* Create the semantics */
4055 auto node = this->astCtxt->sx(triton::bitsize::byte, this->astCtxt->extract(triton::bitsize::byte-1, 0, op1));
4056
4057 /* Create symbolic expression */
4058 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CBW operation");
4059
4060 /* Spread taint */
4061 expr->isTainted = this->taintEngine->taintAssignment(dst, dst);
4062
4063 /* Update the symbolic control flow */
4064 this->controlFlow_s(inst);
4065 }
4066
4067
4068 void x86Semantics::cdq_s(triton::arch::Instruction& inst) {
4069 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
4070 auto src = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
4071
4072 /* Create symbolic operands */
4073 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
4074
4075 /* Create the semantics - TMP = 64 bitvec (EDX:EAX) */
4076 auto node1 = this->astCtxt->sx(triton::bitsize::dword, op1);
4077
4078 /* Create symbolic expression */
4079 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "Temporary variable");
4080
4081 /* Spread taint */
4082 expr1->isTainted = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_EAX));
4083
4084 /* Create the semantics - EDX = TMP[63...32] */
4085 auto node2 = this->astCtxt->extract(triton::bitsize::qword-1, triton::bitsize::dword, this->astCtxt->reference(expr1));
4086
4087 /* Create symbolic expression */
4088 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "CDQ operation");
4089
4090 /* Spread taint */
4091 expr2->isTainted = this->taintEngine->taintAssignment(dst, src);
4092
4093 /* Update the symbolic control flow */
4094 this->controlFlow_s(inst);
4095 }
4096
4097
4098 void x86Semantics::cdqe_s(triton::arch::Instruction& inst) {
4099 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX));
4100
4101 /* Create symbolic operands */
4102 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4103
4104 /* Create the semantics */
4105 auto node = this->astCtxt->sx(triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::dword-1, 0, op1));
4106
4107 /* Create symbolic expression */
4108 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CDQE operation");
4109
4110 /* Spread taint */
4111 expr->isTainted = this->taintEngine->taintAssignment(dst, dst);
4112
4113 /* Update the symbolic control flow */
4114 this->controlFlow_s(inst);
4115 }
4116
4117
4118 void x86Semantics::clc_s(triton::arch::Instruction& inst) {
4119 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag");
4120 /* Update the symbolic control flow */
4121 this->controlFlow_s(inst);
4122 }
4123
4124
4125 void x86Semantics::cld_s(triton::arch::Instruction& inst) {
4126 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_DF), "Clears direction flag");
4127 /* Update the symbolic control flow */
4128 this->controlFlow_s(inst);
4129 }
4130
4131
4132 void x86Semantics::clflush_s(triton::arch::Instruction& inst) {
4133 /* Update the symbolic control flow */
4134 this->controlFlow_s(inst);
4135 }
4136
4137
4138 void x86Semantics::clts_s(triton::arch::Instruction& inst) {
4139 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CR0));
4140
4141 /* Create symbolic operands */
4142 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4143
4144 /* Create the semantics */
4145 triton::ast::SharedAbstractNode node = nullptr;
4146
4147 switch (dst.getBitSize()) {
4149 node = this->astCtxt->bvand(op1, this->astCtxt->bv(0xfffffffffffffff7, triton::bitsize::qword));
4150 break;
4152 node = this->astCtxt->bvand(op1, this->astCtxt->bv(0xfffffff7, triton::bitsize::dword));
4153 break;
4154 default:
4155 throw triton::exceptions::Semantics("x86Semantics::clts_s(): Invalid operand size.");
4156 }
4157
4158 /* Create symbolic expression */
4159 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CLTS operation");
4160
4161 /* Spread taint */
4162 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4163
4164 /* Update the symbolic control flow */
4165 this->controlFlow_s(inst);
4166 }
4167
4168
4169 void x86Semantics::cli_s(triton::arch::Instruction& inst) {
4170 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_IF), "Clears interrupt flag");
4171 /* Update the symbolic control flow */
4172 this->controlFlow_s(inst);
4173 }
4174
4175
4176 void x86Semantics::cmc_s(triton::arch::Instruction& inst) {
4177 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
4178
4179 /* Create symbolic operands */
4180 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4181
4182 /* Create the semantics */
4183 auto node = this->astCtxt->bvnot(op1);
4184
4185 /* Create symbolic expression */
4186 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst.getRegister(), "CMC operation");
4187
4188 /* Spread taint */
4189 expr->isTainted = this->taintEngine->taintAssignment(dst, dst);
4190
4191 /* Update the symbolic control flow */
4192 this->controlFlow_s(inst);
4193 }
4194
4195
4196 void x86Semantics::cmova_s(triton::arch::Instruction& inst) {
4197 auto& dst = inst.operands[0];
4198 auto& src = inst.operands[1];
4199 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
4200 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
4201
4202 /* Create symbolic operands */
4203 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4204 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4205 auto op3 = this->symbolicEngine->getOperandAst(inst, cf);
4206 auto op4 = this->symbolicEngine->getOperandAst(inst, zf);
4207
4208 /* Create the semantics */
4209 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvand(this->astCtxt->bvnot(op3), this->astCtxt->bvnot(op4)), this->astCtxt->bvtrue()), op2, op1);
4210
4211 /* Create symbolic expression */
4212 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVA operation");
4213
4214 /* Spread taint and condition flag */
4215 if (op3->evaluate().is_zero() && op4->evaluate().is_zero()) {
4216 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4217 inst.setConditionTaken(true);
4218 }
4219 else {
4220 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4221 }
4222
4223 expr->isTainted |= this->taintEngine->isTainted(cf) || this->taintEngine->isTainted(zf);
4224
4225 /* Update the symbolic control flow */
4226 this->controlFlow_s(inst);
4227 }
4228
4229
4230 void x86Semantics::cmovae_s(triton::arch::Instruction& inst) {
4231 auto& dst = inst.operands[0];
4232 auto& src = inst.operands[1];
4233 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
4234
4235 /* Create symbolic operands */
4236 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4237 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4238 auto op3 = this->symbolicEngine->getOperandAst(inst, cf);
4239
4240 /* Create the semantics */
4241 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvfalse()), op2, op1);
4242
4243 /* Create symbolic expression */
4244 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVAE operation");
4245
4246 /* Spread taint and condition flag */
4247 if (op3->evaluate().is_zero()) {
4248 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4249 inst.setConditionTaken(true);
4250 }
4251 else {
4252 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4253 }
4254
4255 expr->isTainted |= this->taintEngine->isTainted(cf);
4256
4257 /* Update the symbolic control flow */
4258 this->controlFlow_s(inst);
4259 }
4260
4261
4262 void x86Semantics::cmovb_s(triton::arch::Instruction& inst) {
4263 auto& dst = inst.operands[0];
4264 auto& src = inst.operands[1];
4265 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
4266
4267 /* Create symbolic operands */
4268 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4269 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4270 auto op3 = this->symbolicEngine->getOperandAst(inst, cf);
4271
4272 /* Create the semantics */
4273 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvtrue()), op2, op1);
4274
4275 /* Create symbolic expression */
4276 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVB operation");
4277
4278 /* Spread taint and condition flag */
4279 if (!op3->evaluate().is_zero()) {
4280 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4281 inst.setConditionTaken(true);
4282 }
4283 else {
4284 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4285 }
4286
4287 expr->isTainted |= this->taintEngine->isTainted(cf);
4288
4289 /* Update the symbolic control flow */
4290 this->controlFlow_s(inst);
4291 }
4292
4293
4294 void x86Semantics::cmovbe_s(triton::arch::Instruction& inst) {
4295 auto& dst = inst.operands[0];
4296 auto& src = inst.operands[1];
4297 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
4298 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
4299
4300 /* Create symbolic operands */
4301 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4302 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4303 auto op3 = this->symbolicEngine->getOperandAst(inst, cf);
4304 auto op4 = this->symbolicEngine->getOperandAst(inst, zf);
4305
4306 /* Create the semantics */
4307 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvor(op3, op4), this->astCtxt->bvtrue()), op2, op1);
4308
4309 /* Create symbolic expression */
4310 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVBE operation");
4311
4312 /* Spread taint and condition flag */
4313 if (!op3->evaluate().is_zero() || !op4->evaluate().is_zero()) {
4314 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4315 inst.setConditionTaken(true);
4316 }
4317 else {
4318 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4319 }
4320
4321 expr->isTainted |= this->taintEngine->isTainted(cf) || this->taintEngine->isTainted(zf);
4322
4323 /* Update the symbolic control flow */
4324 this->controlFlow_s(inst);
4325 }
4326
4327
4328 void x86Semantics::cmove_s(triton::arch::Instruction& inst) {
4329 auto& dst = inst.operands[0];
4330 auto& src = inst.operands[1];
4331 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
4332
4333 /* Create symbolic operands */
4334 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4335 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4336 auto op3 = this->symbolicEngine->getOperandAst(inst, zf);
4337
4338 /* Create the semantics */
4339 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvtrue()), op2, op1);
4340
4341 /* Create symbolic expression */
4342 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVE operation");
4343
4344 /* Spread taint and condition flag */
4345 if (!op3->evaluate().is_zero()) {
4346 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4347 inst.setConditionTaken(true);
4348 }
4349 else {
4350 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4351 }
4352
4353 expr->isTainted |= this->taintEngine->isTainted(zf);
4354
4355 /* Update the symbolic control flow */
4356 this->controlFlow_s(inst);
4357 }
4358
4359
4360 void x86Semantics::cmovg_s(triton::arch::Instruction& inst) {
4361 auto& dst = inst.operands[0];
4362 auto& src = inst.operands[1];
4363 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
4364 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
4365 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
4366
4367 /* Create symbolic operands */
4368 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4369 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4370 auto op3 = this->symbolicEngine->getOperandAst(inst, sf);
4371 auto op4 = this->symbolicEngine->getOperandAst(inst, of);
4372 auto op5 = this->symbolicEngine->getOperandAst(inst, zf);
4373
4374 /* Create the semantics */
4375 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvor(this->astCtxt->bvxor(op3, op4), op5), this->astCtxt->bvfalse()), op2, op1);
4376
4377 /* Create symbolic expression */
4378 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVG operation");
4379
4380 /* Spread taint and condition flag */
4381 if ((op3->evaluate().is_zero() == op4->evaluate().is_zero()) && op5->evaluate().is_zero()) {
4382 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4383 inst.setConditionTaken(true);
4384 }
4385 else {
4386 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4387 }
4388
4389 expr->isTainted |= this->taintEngine->isTainted(sf) || this->taintEngine->isTainted(of) || this->taintEngine->isTainted(zf);
4390
4391 /* Update the symbolic control flow */
4392 this->controlFlow_s(inst);
4393 }
4394
4395
4396 void x86Semantics::cmovge_s(triton::arch::Instruction& inst) {
4397 auto& dst = inst.operands[0];
4398 auto& src = inst.operands[1];
4399 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
4400 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
4401
4402 /* Create symbolic operands */
4403 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4404 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4405 auto op3 = this->symbolicEngine->getOperandAst(inst, sf);
4406 auto op4 = this->symbolicEngine->getOperandAst(inst, of);
4407
4408 /* Create the semantics */
4409 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, op4), op2, op1);
4410
4411 /* Create symbolic expression */
4412 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVGE operation");
4413
4414 /* Spread taint and condition flag */
4415 if (op3->evaluate().is_zero() == op4->evaluate().is_zero()) {
4416 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4417 inst.setConditionTaken(true);
4418 }
4419 else {
4420 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4421 }
4422
4423 expr->isTainted |= this->taintEngine->isTainted(sf) || this->taintEngine->isTainted(of);
4424
4425 /* Update the symbolic control flow */
4426 this->controlFlow_s(inst);
4427 }
4428
4429
4430 void x86Semantics::cmovl_s(triton::arch::Instruction& inst) {
4431 auto& dst = inst.operands[0];
4432 auto& src = inst.operands[1];
4433 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
4434 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
4435
4436 /* Create symbolic operands */
4437 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4438 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4439 auto op3 = this->symbolicEngine->getOperandAst(inst, sf);
4440 auto op4 = this->symbolicEngine->getOperandAst(inst, of);
4441
4442 /* Create the semantics */
4443 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvxor(op3, op4), this->astCtxt->bvtrue()), op2, op1);
4444
4445 /* Create symbolic expression */
4446 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVL operation");
4447
4448 /* Spread taint and condition flag */
4449 if (op3->evaluate().is_zero() != op4->evaluate().is_zero()) {
4450 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4451 inst.setConditionTaken(true);
4452 }
4453 else {
4454 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4455 }
4456
4457 expr->isTainted |= this->taintEngine->isTainted(sf) || this->taintEngine->isTainted(of);
4458
4459
4460 /* Update the symbolic control flow */
4461 this->controlFlow_s(inst);
4462 }
4463
4464
4465 void x86Semantics::cmovle_s(triton::arch::Instruction& inst) {
4466 auto& dst = inst.operands[0];
4467 auto& src = inst.operands[1];
4468 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
4469 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
4470 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
4471
4472 /* Create symbolic operands */
4473 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4474 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4475 auto op3 = this->symbolicEngine->getOperandAst(inst, sf);
4476 auto op4 = this->symbolicEngine->getOperandAst(inst, of);
4477 auto op5 = this->symbolicEngine->getOperandAst(inst, zf);
4478
4479 /* Create the semantics */
4480 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvor(this->astCtxt->bvxor(op3, op4), op5), this->astCtxt->bvtrue()), op2, op1);
4481
4482 /* Create symbolic expression */
4483 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVBE operation");
4484
4485 /* Spread taint and condition flag */
4486 if ((op3->evaluate().is_zero() != op4->evaluate().is_zero()) || !op5->evaluate().is_zero()) {
4487 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4488 inst.setConditionTaken(true);
4489 }
4490 else {
4491 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4492 }
4493
4494 expr->isTainted |= this->taintEngine->isTainted(sf) || this->taintEngine->isTainted(of) || this->taintEngine->isTainted(zf);
4495
4496 /* Update the symbolic control flow */
4497 this->controlFlow_s(inst);
4498 }
4499
4500
4501 void x86Semantics::cmovne_s(triton::arch::Instruction& inst) {
4502 auto& dst = inst.operands[0];
4503 auto& src = inst.operands[1];
4504 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
4505
4506 /* Create symbolic operands */
4507 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4508 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4509 auto op3 = this->symbolicEngine->getOperandAst(inst, zf);
4510
4511 /* Create the semantics */
4512 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvfalse()), op2, op1);
4513
4514 /* Create symbolic expression */
4515 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVNE operation");
4516
4517 /* Spread taint and condition flag */
4518 if (op3->evaluate().is_zero()) {
4519 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4520 inst.setConditionTaken(true);
4521 }
4522 else {
4523 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4524 }
4525
4526 expr->isTainted |= this->taintEngine->isTainted(zf);
4527
4528 /* Update the symbolic control flow */
4529 this->controlFlow_s(inst);
4530 }
4531
4532
4533 void x86Semantics::cmovno_s(triton::arch::Instruction& inst) {
4534 auto& dst = inst.operands[0];
4535 auto& src = inst.operands[1];
4536 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
4537
4538 /* Create symbolic operands */
4539 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4540 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4541 auto op3 = this->symbolicEngine->getOperandAst(inst, of);
4542
4543 /* Create the semantics */
4544 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvfalse()), op2, op1);
4545
4546 /* Create symbolic expression */
4547 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVNO operation");
4548
4549 /* Spread taint and condition flag */
4550 if (op3->evaluate().is_zero()) {
4551 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4552 inst.setConditionTaken(true);
4553 }
4554 else {
4555 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4556 }
4557
4558 expr->isTainted |= this->taintEngine->isTainted(of);
4559
4560 /* Update the symbolic control flow */
4561 this->controlFlow_s(inst);
4562 }
4563
4564
4565 void x86Semantics::cmovnp_s(triton::arch::Instruction& inst) {
4566 auto& dst = inst.operands[0];
4567 auto& src = inst.operands[1];
4568 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
4569
4570 /* Create symbolic operands */
4571 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4572 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4573 auto op3 = this->symbolicEngine->getOperandAst(inst, pf);
4574
4575 /* Create the semantics */
4576 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvfalse()), op2, op1);
4577
4578 /* Create symbolic expression */
4579 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVNP operation");
4580
4581 /* Spread taint and condition flag */
4582 if (op3->evaluate().is_zero()) {
4583 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4584 inst.setConditionTaken(true);
4585 }
4586 else {
4587 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4588 }
4589
4590 expr->isTainted |= this->taintEngine->isTainted(pf);
4591
4592 /* Update the symbolic control flow */
4593 this->controlFlow_s(inst);
4594 }
4595
4596
4597 void x86Semantics::cmovns_s(triton::arch::Instruction& inst) {
4598 auto& dst = inst.operands[0];
4599 auto& src = inst.operands[1];
4600 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
4601
4602 /* Create symbolic operands */
4603 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4604 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4605 auto op3 = this->symbolicEngine->getOperandAst(inst, sf);
4606
4607 /* Create the semantics */
4608 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvfalse()), op2, op1);
4609
4610 /* Create symbolic expression */
4611 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVNS operation");
4612
4613 /* Spread taint and condition flag */
4614 if (op3->evaluate().is_zero()) {
4615 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4616 inst.setConditionTaken(true);
4617 }
4618 else {
4619 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4620 }
4621
4622 expr->isTainted |= this->taintEngine->isTainted(sf);
4623
4624 /* Update the symbolic control flow */
4625 this->controlFlow_s(inst);
4626 }
4627
4628
4629 void x86Semantics::cmovo_s(triton::arch::Instruction& inst) {
4630 auto& dst = inst.operands[0];
4631 auto& src = inst.operands[1];
4632 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
4633
4634 /* Create symbolic operands */
4635 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4636 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4637 auto op3 = this->symbolicEngine->getOperandAst(inst, of);
4638
4639 /* Create the semantics */
4640 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvtrue()), op2, op1);
4641
4642 /* Create symbolic expression */
4643 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVO operation");
4644
4645 /* Spread taint and condition flag */
4646 if (!op3->evaluate().is_zero()) {
4647 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4648 inst.setConditionTaken(true);
4649 }
4650 else {
4651 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4652 }
4653
4654 expr->isTainted |= this->taintEngine->isTainted(of);
4655
4656 /* Update the symbolic control flow */
4657 this->controlFlow_s(inst);
4658 }
4659
4660
4661 void x86Semantics::cmovp_s(triton::arch::Instruction& inst) {
4662 auto& dst = inst.operands[0];
4663 auto& src = inst.operands[1];
4664 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
4665
4666 /* Create symbolic operands */
4667 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4668 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4669 auto op3 = this->symbolicEngine->getOperandAst(inst, pf);
4670
4671 /* Create the semantics */
4672 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvtrue()), op2, op1);
4673
4674 /* Create symbolic expression */
4675 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVP operation");
4676
4677 /* Spread taint and condition flag */
4678 if (!op3->evaluate().is_zero()) {
4679 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4680 inst.setConditionTaken(true);
4681 }
4682 else {
4683 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4684 }
4685
4686 expr->isTainted |= this->taintEngine->isTainted(pf);
4687
4688 /* Update the symbolic control flow */
4689 this->controlFlow_s(inst);
4690 }
4691
4692
4693 void x86Semantics::cmovs_s(triton::arch::Instruction& inst) {
4694 auto& dst = inst.operands[0];
4695 auto& src = inst.operands[1];
4696 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
4697
4698 /* Create symbolic operands */
4699 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4700 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4701 auto op3 = this->symbolicEngine->getOperandAst(inst, sf);
4702
4703 /* Create the semantics */
4704 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvtrue()), op2, op1);
4705
4706 /* Create symbolic expression */
4707 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVS operation");
4708
4709 /* Spread taint and condition flag */
4710 if (!op3->evaluate().is_zero()) {
4711 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4712 inst.setConditionTaken(true);
4713 }
4714 else {
4715 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
4716 }
4717
4718 expr->isTainted |= this->taintEngine->isTainted(sf);
4719
4720 /* Update the symbolic control flow */
4721 this->controlFlow_s(inst);
4722 }
4723
4724
4725 void x86Semantics::cmp_s(triton::arch::Instruction& inst) {
4726 auto& dst = inst.operands[0];
4727 auto& src = inst.operands[1];
4728
4729 /* Create symbolic operands */
4730 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4731 auto op2 = this->astCtxt->sx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
4732
4733 /* Create the semantics */
4734 auto node = this->astCtxt->bvsub(op1, op2);
4735
4736 /* Create symbolic expression */
4737 auto expr = this->symbolicEngine->createSymbolicVolatileExpression(inst, node, "CMP operation");
4738
4739 /* Spread taint */
4740 expr->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
4741
4742 /* Update symbolic flags */
4743 this->af_s(inst, expr, dst, op1, op2, true);
4744 this->cfSub_s(inst, expr, dst, op1, op2, true);
4745 this->ofSub_s(inst, expr, dst, op1, op2, true);
4746 this->pf_s(inst, expr, dst, true);
4747 this->sf_s(inst, expr, dst, true);
4748 this->zf_s(inst, expr, dst, true);
4749
4750 /* Update the symbolic control flow */
4751 this->controlFlow_s(inst);
4752 }
4753
4754
4755 void x86Semantics::cmpsb_s(triton::arch::Instruction& inst) {
4756 auto& dst = inst.operands[0];
4757 auto& src = inst.operands[1];
4758 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
4759 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
4760 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
4761 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
4762
4763 /* If the REP prefix is defined, convert REP into REPE */
4766
4767 /* Check if there is a REP prefix and a counter to zero */
4768 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
4769 this->controlFlow_s(inst);
4770 return;
4771 }
4772
4773 /* Create symbolic operands */
4774 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4775 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4776 auto op3 = this->symbolicEngine->getOperandAst(inst, index1);
4777 auto op4 = this->symbolicEngine->getOperandAst(inst, index2);
4778 auto op5 = this->symbolicEngine->getOperandAst(inst, df);
4779
4780 /* Create the semantics */
4781 auto node1 = this->astCtxt->bvsub(op1, op2);
4782 auto node2 = this->astCtxt->ite(
4783 this->astCtxt->equal(op5, this->astCtxt->bvfalse()),
4784 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::byte, index1.getBitSize())),
4785 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::byte, index1.getBitSize()))
4786 );
4787 auto node3 = this->astCtxt->ite(
4788 this->astCtxt->equal(op5, this->astCtxt->bvfalse()),
4789 this->astCtxt->bvadd(op4, this->astCtxt->bv(triton::size::byte, index2.getBitSize())),
4790 this->astCtxt->bvsub(op4, this->astCtxt->bv(triton::size::byte, index2.getBitSize()))
4791 );
4792
4793 /* Create symbolic expression */
4794 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMPSB operation");
4795 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (SI) operation");
4796 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (DI) operation");
4797
4798 /* Spread taint */
4799 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
4800 expr2->isTainted = this->taintEngine->taintUnion(index1, index1);
4801 expr3->isTainted = this->taintEngine->taintUnion(index2, index2);
4802
4803 /* Update symbolic flags */
4804 this->af_s(inst, expr1, dst, op1, op2, true);
4805 this->cfSub_s(inst, expr1, dst, op1, op2, true);
4806 this->ofSub_s(inst, expr1, dst, op1, op2, true);
4807 this->pf_s(inst, expr1, dst, true);
4808 this->sf_s(inst, expr1, dst, true);
4809 this->zf_s(inst, expr1, dst, true);
4810
4811 /* Update the symbolic control flow */
4812 this->controlFlow_s(inst);
4813 }
4814
4815
4816 void x86Semantics::cmpsd_s(triton::arch::Instruction& inst) {
4817 auto& dst = inst.operands[0];
4818 auto& src = inst.operands[1];
4819 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
4820 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
4821 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
4822 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
4823
4824 /* If the REP prefix is defined, convert REP into REPE */
4827
4828 /* Check if there is a REP prefix and a counter to zero */
4829 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
4830 this->controlFlow_s(inst);
4831 return;
4832 }
4833
4834 /* Create symbolic operands */
4835 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4836 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4837 auto op3 = this->symbolicEngine->getOperandAst(inst, index1);
4838 auto op4 = this->symbolicEngine->getOperandAst(inst, index2);
4839 auto op5 = this->symbolicEngine->getOperandAst(inst, df);
4840
4841 /* Create the semantics */
4842 auto node1 = this->astCtxt->bvsub(op1, op2);
4843 auto node2 = this->astCtxt->ite(
4844 this->astCtxt->equal(op5, this->astCtxt->bvfalse()),
4845 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::dword, index1.getBitSize())),
4846 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::dword, index1.getBitSize()))
4847 );
4848 auto node3 = this->astCtxt->ite(
4849 this->astCtxt->equal(op5, this->astCtxt->bvfalse()),
4850 this->astCtxt->bvadd(op4, this->astCtxt->bv(triton::size::dword, index2.getBitSize())),
4851 this->astCtxt->bvsub(op4, this->astCtxt->bv(triton::size::dword, index2.getBitSize()))
4852 );
4853
4854 /* Create symbolic expression */
4855 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMPSD operation");
4856 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (SI) operation");
4857 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (DI) operation");
4858
4859 /* Spread taint */
4860 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
4861 expr2->isTainted = this->taintEngine->taintUnion(index1, index1);
4862 expr3->isTainted = this->taintEngine->taintUnion(index2, index2);
4863
4864 /* Update symbolic flags */
4865 this->af_s(inst, expr1, dst, op1, op2, true);
4866 this->cfSub_s(inst, expr1, dst, op1, op2, true);
4867 this->ofSub_s(inst, expr1, dst, op1, op2, true);
4868 this->pf_s(inst, expr1, dst, true);
4869 this->sf_s(inst, expr1, dst, true);
4870 this->zf_s(inst, expr1, dst, true);
4871
4872 /* Update the symbolic control flow */
4873 this->controlFlow_s(inst);
4874 }
4875
4876
4877 void x86Semantics::cmpsq_s(triton::arch::Instruction& inst) {
4878 auto& dst = inst.operands[0];
4879 auto& src = inst.operands[1];
4880 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
4881 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
4882 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
4883 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
4884
4885 /* If the REP prefix is defined, convert REP into REPE */
4888
4889 /* Check if there is a REP prefix and a counter to zero */
4890 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
4891 this->controlFlow_s(inst);
4892 return;
4893 }
4894
4895 /* Create symbolic operands */
4896 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4897 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4898 auto op3 = this->symbolicEngine->getOperandAst(inst, index1);
4899 auto op4 = this->symbolicEngine->getOperandAst(inst, index2);
4900 auto op5 = this->symbolicEngine->getOperandAst(inst, df);
4901
4902 /* Create the semantics */
4903 auto node1 = this->astCtxt->bvsub(op1, op2);
4904 auto node2 = this->astCtxt->ite(
4905 this->astCtxt->equal(op5, this->astCtxt->bvfalse()),
4906 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::qword, index1.getBitSize())),
4907 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::qword, index1.getBitSize()))
4908 );
4909 auto node3 = this->astCtxt->ite(
4910 this->astCtxt->equal(op5, this->astCtxt->bvfalse()),
4911 this->astCtxt->bvadd(op4, this->astCtxt->bv(triton::size::qword, index2.getBitSize())),
4912 this->astCtxt->bvsub(op4, this->astCtxt->bv(triton::size::qword, index2.getBitSize()))
4913 );
4914
4915 /* Create symbolic expression */
4916 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMPSQ operation");
4917 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (SI) operation");
4918 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (DI) operation");
4919
4920 /* Spread taint */
4921 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
4922 expr2->isTainted = this->taintEngine->taintUnion(index1, index1);
4923 expr3->isTainted = this->taintEngine->taintUnion(index2, index2);
4924
4925 /* Update symbolic flags */
4926 this->af_s(inst, expr1, dst, op1, op2, true);
4927 this->cfSub_s(inst, expr1, dst, op1, op2, true);
4928 this->ofSub_s(inst, expr1, dst, op1, op2, true);
4929 this->pf_s(inst, expr1, dst, true);
4930 this->sf_s(inst, expr1, dst, true);
4931 this->zf_s(inst, expr1, dst, true);
4932
4933 /* Update the symbolic control flow */
4934 this->controlFlow_s(inst);
4935 }
4936
4937
4938 void x86Semantics::cmpsw_s(triton::arch::Instruction& inst) {
4939 auto& dst = inst.operands[0];
4940 auto& src = inst.operands[1];
4941 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
4942 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
4943 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
4944 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
4945
4946 /* If the REP prefix is defined, convert REP into REPE */
4949
4950 /* Check if there is a REP prefix and a counter to zero */
4951 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
4952 this->controlFlow_s(inst);
4953 return;
4954 }
4955
4956 /* Create symbolic operands */
4957 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
4958 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4959 auto op3 = this->symbolicEngine->getOperandAst(inst, index1);
4960 auto op4 = this->symbolicEngine->getOperandAst(inst, index2);
4961 auto op5 = this->symbolicEngine->getOperandAst(inst, df);
4962
4963 /* Create the semantics */
4964 auto node1 = this->astCtxt->bvsub(op1, op2);
4965 auto node2 = this->astCtxt->ite(
4966 this->astCtxt->equal(op5, this->astCtxt->bvfalse()),
4967 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::word, index1.getBitSize())),
4968 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::word, index1.getBitSize()))
4969 );
4970 auto node3 = this->astCtxt->ite(
4971 this->astCtxt->equal(op5, this->astCtxt->bvfalse()),
4972 this->astCtxt->bvadd(op4, this->astCtxt->bv(triton::size::word, index2.getBitSize())),
4973 this->astCtxt->bvsub(op4, this->astCtxt->bv(triton::size::word, index2.getBitSize()))
4974 );
4975
4976 /* Create symbolic expression */
4977 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMPSW operation");
4978 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (SI) operation");
4979 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (DI) operation");
4980
4981 /* Spread taint */
4982 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
4983 expr2->isTainted = this->taintEngine->taintUnion(index1, index1);
4984 expr3->isTainted = this->taintEngine->taintUnion(index2, index2);
4985
4986 /* Update symbolic flags */
4987 this->af_s(inst, expr1, dst, op1, op2, true);
4988 this->cfSub_s(inst, expr1, dst, op1, op2, true);
4989 this->ofSub_s(inst, expr1, dst, op1, op2, true);
4990 this->pf_s(inst, expr1, dst, true);
4991 this->sf_s(inst, expr1, dst, true);
4992 this->zf_s(inst, expr1, dst, true);
4993
4994 /* Update the symbolic control flow */
4995 this->controlFlow_s(inst);
4996 }
4997
4998
4999 void x86Semantics::cmpxchg_s(triton::arch::Instruction& inst) {
5000 auto& src1 = inst.operands[0];
5001 auto& src2 = inst.operands[1];
5002
5003 /* Create the tempory accumulator */
5004 triton::arch::OperandWrapper accumulator(this->architecture->getRegister(ID_REG_X86_AL));
5005 triton::arch::OperandWrapper accumulatorp(this->architecture->getParentRegister(ID_REG_X86_AL));
5006
5007 switch (src1.getSize()) {
5008 case triton::size::word:
5009 accumulator.setRegister(arch::Register(this->architecture->getRegister(ID_REG_X86_AX)));
5010 break;
5012 accumulator.setRegister(arch::Register(this->architecture->getRegister(ID_REG_X86_EAX)));
5013 break;
5015 accumulator.setRegister(arch::Register(this->architecture->getRegister(ID_REG_X86_RAX)));
5016 break;
5017 }
5018
5019 /* Create symbolic operands */
5020 auto op1 = this->symbolicEngine->getOperandAst(inst, accumulator);
5021 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
5022 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
5023 auto op1p = this->symbolicEngine->getOperandAst(accumulatorp);
5024 auto op2p = this->symbolicEngine->getRegisterAst((src1.getType() == triton::arch::OP_REG ? Register(this->architecture->getParentRegister(src1.getRegister())) : accumulatorp.getRegister()));
5025 auto op3p = this->symbolicEngine->getRegisterAst((src1.getType() == triton::arch::OP_REG ? Register(this->architecture->getParentRegister(src2.getRegister())) : accumulatorp.getRegister()));
5026
5027 /* Create the semantics */
5028 auto nodeq = this->astCtxt->equal(op1, op2);
5029 auto node1 = this->astCtxt->bvsub(op1, op2);
5030 auto node2 = this->astCtxt->ite(nodeq, op3, op2);
5031 auto node3 = this->astCtxt->ite(nodeq, op1, op2);
5032 auto node2p = this->astCtxt->ite(nodeq, op3p, op2p);
5033 auto node3p = this->astCtxt->ite(nodeq, op1p, op2p);
5034
5035 /* Create symbolic expression */
5036 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMP operation");
5037 auto expr2 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node2, "Temporary operation");
5038 auto expr3 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node2p, "Temporary operation");
5039 auto expr4 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node3, "Temporary operation");
5040 auto expr5 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node3p, "Temporary operation");
5041
5044
5045 /* Destination */
5046 if (nodeq->evaluate() == false && src1.getType() == triton::arch::OP_REG) {
5047 const auto& src1p = this->architecture->getParentRegister(src1.getRegister());
5048 expr6 = this->symbolicEngine->createSymbolicRegisterExpression(inst, node2p, src1p, "XCHG operation");
5049 } else
5050 expr6 = this->symbolicEngine->createSymbolicExpression(inst, node2, src1, "XCHG operation");
5051
5052 /* Accumulator */
5053 if (nodeq->evaluate() == true)
5054 expr7 = this->symbolicEngine->createSymbolicExpression(inst, node3p, accumulatorp, "XCHG operation");
5055 else
5056 expr7 = this->symbolicEngine->createSymbolicExpression(inst, node3, accumulator, "XCHG operation");
5057
5058 /* Spread taint */
5059 expr1->isTainted = this->taintEngine->isTainted(accumulator) | this->taintEngine->isTainted(src1);
5060 expr2->isTainted = expr1->isTainted;
5061 expr3->isTainted = expr1->isTainted;
5062 expr4->isTainted = expr1->isTainted;
5063 expr5->isTainted = expr1->isTainted;
5064 expr6->isTainted = this->taintEngine->taintAssignment(src1, src2);
5065 expr7->isTainted = this->taintEngine->taintAssignment(accumulator, src1);
5066
5067 /* Update symbolic flags */
5068 this->af_s(inst, expr1, accumulator, op1, op2, true);
5069 this->cfSub_s(inst, expr1, accumulator, op1, op2, true);
5070 this->ofSub_s(inst, expr1, accumulator, op1, op2, true);
5071 this->pf_s(inst, expr1, accumulator, true);
5072 this->sf_s(inst, expr1, accumulator, true);
5073 this->zf_s(inst, expr1, accumulator, true);
5074
5075 /* Update the symbolic control flow */
5076 this->controlFlow_s(inst);
5077 }
5078
5079
5080 void x86Semantics::cmpxchg16b_s(triton::arch::Instruction& inst) {
5081 auto& src1 = inst.operands[0];
5082 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX));
5083 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX));
5084 auto src4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RCX));
5085 auto src5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RBX));
5086
5087 /* Create symbolic operands */
5088 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
5089 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
5090 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
5091 auto op4 = this->symbolicEngine->getOperandAst(inst, src4);
5092 auto op5 = this->symbolicEngine->getOperandAst(inst, src5);
5093
5094 /* Create the semantics */
5095 /* CMP8B */
5096 auto node1 = this->astCtxt->bvsub(this->astCtxt->concat(op2, op3), op1);
5097 /* Destination */
5098 auto node2 = this->astCtxt->ite(this->astCtxt->equal(node1, this->astCtxt->bv(0, triton::bitsize::dqword)), this->astCtxt->concat(op4, op5), op1);
5099 /* EDX:EAX */
5100 auto node3 = this->astCtxt->ite(this->astCtxt->equal(node1, this->astCtxt->bv(0, triton::bitsize::dqword)), this->astCtxt->concat(op2, op3), op1);
5101
5102 /* Create symbolic expression */
5103 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMP operation");
5104 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, src1, "XCHG16B memory operation");
5105 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(127, 64, node3), src2, "XCHG16B RDX operation");
5106 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(63, 0, node3), src3, "XCHG16B RAX operation");
5107
5108 /* Spread taint */
5109 expr1->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(src3);
5110 expr2->isTainted = this->taintEngine->setTaint(src1, this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(src3));
5111 expr3->isTainted = this->taintEngine->taintAssignment(src2, src1);
5112 expr4->isTainted = this->taintEngine->taintAssignment(src3, src1);
5113
5114 /* Update symbolic flags */
5115 this->zf_s(inst, expr1, src1, true);
5116
5117 /* Update the symbolic control flow */
5118 this->controlFlow_s(inst);
5119 }
5120
5121
5122 void x86Semantics::cmpxchg8b_s(triton::arch::Instruction& inst) {
5123 auto& src1 = inst.operands[0];
5124 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
5125 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
5126 auto src4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ECX));
5127 auto src5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EBX));
5128 auto src2p = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_EDX));
5129 auto src3p = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_EAX));
5130
5131 /* Create symbolic operands */
5132 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
5133 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
5134 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
5135 auto op4 = this->symbolicEngine->getOperandAst(inst, src4);
5136 auto op5 = this->symbolicEngine->getOperandAst(inst, src5);
5137 auto op2p = this->symbolicEngine->getOperandAst(inst, src2p);
5138 auto op3p = this->symbolicEngine->getOperandAst(inst, src3p);
5139
5140 /* Create the semantics */
5141 /* CMP8B */
5142 auto node1 = this->astCtxt->bvsub(this->astCtxt->concat(op2, op3), op1);
5143 /* Destination */
5144 auto node2 = this->astCtxt->ite(this->astCtxt->equal(node1, this->astCtxt->bv(0, triton::bitsize::qword)), this->astCtxt->concat(op4, op5), op1);
5145 /* EDX:EAX */
5146 auto node3 = this->astCtxt->ite(this->astCtxt->equal(node1, this->astCtxt->bv(0, triton::bitsize::qword)), this->astCtxt->concat(op2, op3), op1);
5147 auto node3p = this->astCtxt->ite(
5148 this->astCtxt->equal(
5149 node1,
5150 this->astCtxt->bv(0, triton::bitsize::qword)),
5151 this->astCtxt->concat(op2p, op3p),
5152 this->astCtxt->zx(src2p.getBitSize() + src3p.getBitSize() - src1.getBitSize(), op1)
5153 );
5154
5155 /* Create symbolic expression */
5156 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMP operation");
5157 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, src1, "XCHG8B memory operation");
5158 auto expr3 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node3, "Temporary operation");
5159 auto expr4 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node3p, "Temporary operation");
5160
5163
5164 /* EDX */
5165 if (node1->evaluate() == 0)
5166 expr5 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract((src2p.getBitSize() * 2 - 1), src2p.getBitSize(), node3p), src2p, "XCHG8B EDX operation");
5167 else
5168 expr5 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(63, 32, node3), src2, "XCHG8B EDX operation");
5169
5170 /* EAX */
5171 if (node1->evaluate() == 0)
5172 expr6 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(src2p.getBitSize() - 1, 0, node3p), src3p, "XCHG8B EAX operation");
5173 else
5174 expr6 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(31, 0, node3), src3, "XCHG8B EAX operation");
5175
5176 /* Spread taint */
5177 expr1->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(src3);
5178 expr2->isTainted = this->taintEngine->setTaint(src1, this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(src3));
5179 expr3->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(src3);
5180 expr4->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(src3);
5181 expr5->isTainted = this->taintEngine->taintAssignment(src2, src1);
5182 expr6->isTainted = this->taintEngine->taintAssignment(src3, src1);
5183
5184 /* Update symbolic flags */
5185 this->zf_s(inst, expr1, src1, true);
5186
5187 /* Update the symbolic control flow */
5188 this->controlFlow_s(inst);
5189 }
5190
5191
5192 void x86Semantics::cpuid_s(triton::arch::Instruction& inst) {
5193 auto src = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_AX));
5194 auto dst1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_AX));
5195 auto dst2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_BX));
5196 auto dst3 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
5197 auto dst4 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DX));
5198
5199 /* Create symbolic operands */
5200 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
5201
5202 /* Create the semantics */
5203 triton::ast::SharedAbstractNode node1 = nullptr;
5204 triton::ast::SharedAbstractNode node2 = nullptr;
5205 triton::ast::SharedAbstractNode node3 = nullptr;
5206 triton::ast::SharedAbstractNode node4 = nullptr;
5207
5208 /* In this case, we concretize the AX option */
5209 switch (static_cast<triton::uint32>(op1->evaluate())) {
5210 case 0:
5211 node1 = this->astCtxt->bv(0x0000000d, dst1.getBitSize());
5212 node2 = this->astCtxt->bv(0x756e6547, dst2.getBitSize());
5213 node3 = this->astCtxt->bv(0x6c65746e, dst3.getBitSize());
5214 node4 = this->astCtxt->bv(0x49656e69, dst4.getBitSize());
5215 break;
5216 case 1:
5217 node1 = this->astCtxt->bv(0x000306a9, dst1.getBitSize());
5218 node2 = this->astCtxt->bv(0x02100800, dst2.getBitSize());
5219 node3 = this->astCtxt->bv(0x7fbae3ff, dst3.getBitSize());
5220 node4 = this->astCtxt->bv(0xbfebfbff, dst4.getBitSize());
5221 break;
5222 case 2:
5223 node1 = this->astCtxt->bv(0x76035a01, dst1.getBitSize());
5224 node2 = this->astCtxt->bv(0x00f0b2ff, dst2.getBitSize());
5225 node3 = this->astCtxt->bv(0x00000000, dst3.getBitSize());
5226 node4 = this->astCtxt->bv(0x00ca0000, dst4.getBitSize());
5227 break;
5228 case 3:
5229 node1 = this->astCtxt->bv(0x00000000, dst1.getBitSize());
5230 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize());
5231 node3 = this->astCtxt->bv(0x00000000, dst3.getBitSize());
5232 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize());
5233 break;
5234 case 4:
5235 node1 = this->astCtxt->bv(0x1c004121, dst1.getBitSize());
5236 node2 = this->astCtxt->bv(0x01c0003f, dst2.getBitSize());
5237 node3 = this->astCtxt->bv(0x0000003f, dst3.getBitSize());
5238 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize());
5239 break;
5240 case 5:
5241 node1 = this->astCtxt->bv(0x00000040, dst1.getBitSize());
5242 node2 = this->astCtxt->bv(0x00000040, dst2.getBitSize());
5243 node3 = this->astCtxt->bv(0x00000003, dst3.getBitSize());
5244 node4 = this->astCtxt->bv(0x00021120, dst4.getBitSize());
5245 break;
5246 case 0x80000000:
5247 node1 = this->astCtxt->bv(0x80000008, dst1.getBitSize());
5248 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize());
5249 node3 = this->astCtxt->bv(0x00000000, dst3.getBitSize());
5250 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize());
5251 break;
5252 case 0x80000001:
5253 node1 = this->astCtxt->bv(0x00000000, dst1.getBitSize());
5254 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize());
5255 node3 = this->astCtxt->bv(0x00000001, dst3.getBitSize());
5256 node4 = this->astCtxt->bv(0x28100800, dst4.getBitSize());
5257 break;
5258 case 0x80000002:
5259 node1 = this->astCtxt->bv(0x20202020, dst1.getBitSize());
5260 node2 = this->astCtxt->bv(0x49202020, dst2.getBitSize());
5261 node3 = this->astCtxt->bv(0x6c65746e, dst3.getBitSize());
5262 node4 = this->astCtxt->bv(0x20295228, dst4.getBitSize());
5263 break;
5264 case 0x80000003:
5265 node1 = this->astCtxt->bv(0x65726f43, dst1.getBitSize());
5266 node2 = this->astCtxt->bv(0x294d5428, dst2.getBitSize());
5267 node3 = this->astCtxt->bv(0x2d376920, dst3.getBitSize());
5268 node4 = this->astCtxt->bv(0x30323533, dst4.getBitSize());
5269 break;
5270 case 0x80000004:
5271 node1 = this->astCtxt->bv(0x5043204d, dst1.getBitSize());
5272 node2 = this->astCtxt->bv(0x20402055, dst2.getBitSize());
5273 node3 = this->astCtxt->bv(0x30392e32, dst3.getBitSize());
5274 node4 = this->astCtxt->bv(0x007a4847, dst4.getBitSize());
5275 break;
5276 case 0x80000005:
5277 node1 = this->astCtxt->bv(0x00000000, dst1.getBitSize());
5278 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize());
5279 node3 = this->astCtxt->bv(0x00000000, dst3.getBitSize());
5280 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize());
5281 break;
5282 case 0x80000006:
5283 node1 = this->astCtxt->bv(0x00000000, dst1.getBitSize());
5284 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize());
5285 node3 = this->astCtxt->bv(0x01006040, dst3.getBitSize());
5286 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize());
5287 break;
5288 case 0x80000007:
5289 node1 = this->astCtxt->bv(0x00000000, dst1.getBitSize());
5290 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize());
5291 node3 = this->astCtxt->bv(0x00000000, dst3.getBitSize());
5292 node4 = this->astCtxt->bv(0x00000100, dst4.getBitSize());
5293 break;
5294 case 0x80000008:
5295 node1 = this->astCtxt->bv(0x00003024, dst1.getBitSize());
5296 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize());
5297 node3 = this->astCtxt->bv(0x00000000, dst3.getBitSize());
5298 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize());
5299 break;
5300 default:
5301 node1 = this->astCtxt->bv(0x00000007, dst1.getBitSize());
5302 node2 = this->astCtxt->bv(0x00000340, dst2.getBitSize());
5303 node3 = this->astCtxt->bv(0x00000340, dst3.getBitSize());
5304 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize());
5305 break;
5306 }
5307
5308 /* Create symbolic expression */
5309 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1, "CPUID AX operation");
5310 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "CPUID BX operation");
5311 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3, "CPUID CX operation");
5312 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4, "CPUID DX operation");
5313
5314 /* Spread taint */
5315 expr1->isTainted = this->taintEngine->setTaintRegister(this->architecture->getParentRegister(ID_REG_X86_AX), false);
5316 expr2->isTainted = this->taintEngine->setTaintRegister(this->architecture->getParentRegister(ID_REG_X86_BX), false);
5317 expr3->isTainted = this->taintEngine->setTaintRegister(this->architecture->getParentRegister(ID_REG_X86_CX), false);
5318 expr4->isTainted = this->taintEngine->setTaintRegister(this->architecture->getParentRegister(ID_REG_X86_DX), false);
5319
5320 /* Update the symbolic control flow */
5321 this->controlFlow_s(inst);
5322 }
5323
5324
5325 void x86Semantics::cqo_s(triton::arch::Instruction& inst) {
5326 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX));
5327 auto src = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX));
5328
5329 /* Create symbolic operands */
5330 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
5331
5332 /* Create the semantics - TMP = 128 bitvec (RDX:RAX) */
5333 auto node1 = this->astCtxt->sx(triton::bitsize::qword, op1);
5334
5335 /* Create symbolic expression */
5336 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "Temporary variable");
5337
5338 /* Spread taint */
5339 expr1->isTainted = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_RAX));
5340
5341 /* Create the semantics - RDX = TMP[127...64] */
5342 auto node2 = this->astCtxt->extract(triton::bitsize::dqword-1, triton::bitsize::qword, this->astCtxt->reference(expr1));
5343
5344 /* Create symbolic expression */
5345 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "CQO operation");
5346
5347 /* Spread taint */
5348 expr2->isTainted = this->taintEngine->taintAssignment(dst, src);
5349
5350 /* Update the symbolic control flow */
5351 this->controlFlow_s(inst);
5352 }
5353
5354
5355 void x86Semantics::cwd_s(triton::arch::Instruction& inst) {
5356 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DX));
5357 auto src = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
5358
5359 /* Create symbolic operands */
5360 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
5361
5362 /* Create the semantics - TMP = 32 bitvec (DX:AX) */
5363 auto node1 = this->astCtxt->sx(triton::bitsize::word, op1);
5364
5365 /* Create symbolic expression */
5366 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "Temporary variable");
5367
5368 /* Spread taint */
5369 expr1->isTainted = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_AX));
5370
5371 /* Create the semantics - DX = TMP[31...16] */
5372 auto node2 = this->astCtxt->extract(triton::bitsize::dword-1, triton::bitsize::word, this->astCtxt->reference(expr1));
5373
5374 /* Create symbolic expression */
5375 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "CWD operation");
5376
5377 /* Spread taint */
5378 expr2->isTainted = this->taintEngine->taintAssignment(dst, src);
5379
5380 /* Update the symbolic control flow */
5381 this->controlFlow_s(inst);
5382 }
5383
5384
5385 void x86Semantics::cwde_s(triton::arch::Instruction& inst) {
5386 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
5387
5388 /* Create symbolic operands */
5389 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
5390
5391 /* Create the semantics */
5392 auto node = this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(triton::bitsize::word-1, 0, op1));
5393
5394 /* Create symbolic expression */
5395 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CWDE operation");
5396
5397 /* Spread taint */
5398 expr->isTainted = this->taintEngine->taintAssignment(dst, dst);
5399
5400 /* Update the symbolic control flow */
5401 this->controlFlow_s(inst);
5402 }
5403
5404
5405 void x86Semantics::dec_s(triton::arch::Instruction& inst) {
5406 auto& dst = inst.operands[0];
5407
5408 /* Create symbolic operands */
5409 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
5410 auto op2 = this->astCtxt->bv(1, dst.getBitSize());
5411
5412 /* Create the semantics */
5413 auto node = this->astCtxt->bvsub(op1, op2);
5414
5415 /* Create symbolic expression */
5416 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "DEC operation");
5417
5418 /* Spread taint */
5419 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
5420
5421 /* Update symbolic flags */
5422 this->af_s(inst, expr, dst, op1, op2);
5423 this->ofSub_s(inst, expr, dst, op1, op2);
5424 this->pf_s(inst, expr, dst);
5425 this->sf_s(inst, expr, dst);
5426 this->zf_s(inst, expr, dst);
5427
5428 /* Update the symbolic control flow */
5429 this->controlFlow_s(inst);
5430 }
5431
5432
5433 void x86Semantics::div_s(triton::arch::Instruction& inst) {
5434 auto& src = inst.operands[0];
5435
5436 /* Create symbolic operands */
5437 auto divisor = this->symbolicEngine->getOperandAst(inst, src);
5438
5439 /* Create symbolic expression */
5440 switch (src.getSize()) {
5441
5442 case triton::size::byte: {
5443 /* AX */
5444 auto ax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
5445 auto dividend = this->symbolicEngine->getOperandAst(inst, ax);
5446 /* res = AX / Source */
5447 auto result = this->astCtxt->bvudiv(dividend, this->astCtxt->zx(triton::bitsize::byte, divisor));
5448 /* mod = AX % Source */
5449 auto mod = this->astCtxt->bvurem(dividend, this->astCtxt->zx(triton::bitsize::byte, divisor));
5450 /* AH = mod */
5451 /* AL = res */
5452 auto node = this->astCtxt->concat(
5453 this->astCtxt->extract((triton::bitsize::byte - 1), 0, mod), /* AH = mod */
5454 this->astCtxt->extract((triton::bitsize::byte - 1), 0, result) /* AL = res */
5455 );
5456 /* Create symbolic expression */
5457 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, ax, "DIV operation");
5458 /* Apply the taint */
5459 expr->isTainted = this->taintEngine->taintUnion(ax, src);
5460 /* Divide error */
5461 if (result->evaluate() > 0xff) {
5462 this->exception = triton::arch::FAULT_DE;
5463 return;
5464 }
5465 break;
5466 }
5467
5468 case triton::size::word: {
5469 /* DX:AX */
5470 auto dx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DX));
5471 auto ax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
5472 auto dividend = this->astCtxt->concat(this->symbolicEngine->getOperandAst(inst, dx), this->symbolicEngine->getOperandAst(inst, ax));
5473 /* res = DX:AX / Source */
5474 auto temp = this->astCtxt->bvudiv(dividend, this->astCtxt->zx(triton::bitsize::word, divisor));
5475 auto result = this->astCtxt->extract((triton::bitsize::word - 1), 0, temp);
5476 /* mod = DX:AX % Source */
5477 auto mod = this->astCtxt->extract((triton::bitsize::word - 1), 0, this->astCtxt->bvurem(dividend, this->astCtxt->zx(triton::bitsize::word, divisor)));
5478 /* Create the symbolic expression for AX */
5479 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, result, ax, "DIV operation");
5480 /* Apply the taint for AX */
5481 expr1->isTainted = this->taintEngine->taintUnion(ax, src);
5482 /* Create the symbolic expression for DX */
5483 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, mod, dx, "DIV operation");
5484 /* Apply the taint for DX */
5485 expr2->isTainted = this->taintEngine->taintUnion(dx, src);
5486 /* Divide error */
5487 if (temp->evaluate() > 0xffff) {
5488 this->exception = triton::arch::FAULT_DE;
5489 return;
5490 }
5491 break;
5492 }
5493
5494 case triton::size::dword: {
5495 /* EDX:EAX */
5496 auto edx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
5497 auto eax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
5498 auto dividend = this->astCtxt->concat(this->symbolicEngine->getOperandAst(inst, edx), this->symbolicEngine->getOperandAst(inst, eax));
5499 /* res = EDX:EAX / Source */
5500 auto temp = this->astCtxt->bvudiv(dividend, this->astCtxt->zx(triton::bitsize::dword, divisor));
5501 auto result = this->astCtxt->extract((triton::bitsize::dword - 1), 0, temp);
5502 /* mod = EDX:EAX % Source */
5503 auto mod = this->astCtxt->extract((triton::bitsize::dword - 1), 0, this->astCtxt->bvurem(dividend, this->astCtxt->zx(triton::bitsize::dword, divisor)));
5504 /* Create the symbolic expression for EAX */
5505 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, result, eax, "DIV operation");
5506 /* Apply the taint for EAX */
5507 expr1->isTainted = this->taintEngine->taintUnion(eax, src);
5508 /* Create the symbolic expression for EDX */
5509 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, mod, edx, "DIV operation");
5510 /* Apply the taint for EDX */
5511 expr2->isTainted = this->taintEngine->taintUnion(edx, src);
5512 /* Divide error */
5513 if (temp->evaluate() > 0xffffffff) {
5514 this->exception = triton::arch::FAULT_DE;
5515 return;
5516 }
5517 break;
5518 }
5519
5520 case triton::size::qword: {
5521 /* RDX:RAX */
5522 auto rdx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX));
5523 auto rax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX));
5524 auto dividend = this->astCtxt->concat(this->symbolicEngine->getOperandAst(inst, rdx), this->symbolicEngine->getOperandAst(inst, rax));
5525 /* res = RDX:RAX / Source */
5526 auto temp = this->astCtxt->bvudiv(dividend, this->astCtxt->zx(triton::bitsize::qword, divisor));
5527 auto result = this->astCtxt->extract((triton::bitsize::qword - 1), 0, temp);
5528 /* mod = RDX:RAX % Source */
5529 auto mod = this->astCtxt->extract((triton::bitsize::qword - 1), 0, this->astCtxt->bvurem(dividend, this->astCtxt->zx(triton::bitsize::qword, divisor)));
5530 /* Create the symbolic expression for RAX */
5531 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, result, rax, "DIV operation");
5532 /* Apply the taint for EAX */
5533 expr1->isTainted = this->taintEngine->taintUnion(rax, src);
5534 /* Create the symbolic expression for RDX */
5535 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, mod, rdx, "DIV operation");
5536 /* Apply the taint for EDX */
5537 expr2->isTainted = this->taintEngine->taintUnion(rdx, src);
5538 /* Divide error */
5539 if (temp->evaluate() > 0xffffffffffffffff) {
5540 this->exception = triton::arch::FAULT_DE;
5541 return;
5542 }
5543 break;
5544 }
5545
5546 }
5547
5548 /* Tag undefined flags */
5549 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
5550 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
5551 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
5552 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
5553 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
5554 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF));
5555
5556 /* Return an exception if the divisor is zero */
5557 if (divisor->evaluate() == 0) {
5558 this->exception = triton::arch::FAULT_DE;
5559 return;
5560 }
5561
5562 /* Update the symbolic control flow */
5563 this->controlFlow_s(inst);
5564 }
5565
5566
5567 void x86Semantics::endbr32_s(triton::arch::Instruction& inst) {
5568 /* Update the symbolic control flow */
5569 this->controlFlow_s(inst);
5570 }
5571
5572
5573 void x86Semantics::endbr64_s(triton::arch::Instruction& inst) {
5574 /* Update the symbolic control flow */
5575 this->controlFlow_s(inst);
5576 }
5577
5578
5579 void x86Semantics::extractps_s(triton::arch::Instruction& inst) {
5580 auto& dst = inst.operands[0];
5581 auto& src1 = inst.operands[1];
5582 auto& src2 = inst.operands[2];
5583
5584 /* Create symbolic operands */
5585 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
5586 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
5587
5588 /* Create the semantics */
5589 auto node = this->astCtxt->extract(triton::bitsize::dword-1, 0,
5590 this->astCtxt->bvlshr(
5591 op2,
5592 this->astCtxt->bvmul(
5593 this->astCtxt->zx(126, this->astCtxt->extract(1, 0, op3)),
5595 )
5596 )
5597 );
5598
5599 switch (dst.getBitSize()) {
5601 break;
5603 node = this->astCtxt->zx(triton::bitsize::dword, node);
5604 break;
5605 default:
5606 throw triton::exceptions::Semantics("x86Semantics::extractps_s(): Invalid destination operand.");
5607 }
5608
5609 /* Create symbolic expression */
5610 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "EXTRACTPS operation");
5611
5612 /* Spread taint */
5613 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
5614
5615 /* Update the symbolic control flow */
5616 this->controlFlow_s(inst);
5617 }
5618
5619
5620 void x86Semantics::fxrstor_s(triton::arch::Instruction& inst) {
5621 /* Fetch the current architecture */
5622 auto arch = this->architecture->getArchitecture();
5623
5624 /* Determine if we are executing in 64 bit mode */
5625 auto is64bits = arch == triton::arch::architecture_e::ARCH_X86_64;
5626
5627 /* Fetch the memory operand */
5628 auto& dst = inst.operands[0];
5629 auto& mem = dst.getMemory();
5630 auto m512byte = mem.getAddress();
5631
5632 /* Check if the address is on a 16-byte boundary */
5633 if (m512byte & 0xF) {
5634 this->exception = triton::arch::FAULT_GP;
5635 return;
5636 }
5637
5638 /* Fetch the FPU, STX, SSE, EFER and CS implicit operands */
5639 auto fcw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FCW));
5640 auto fsw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FSW));
5641 auto ftw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FTW));
5642 auto fop = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FOP));
5643 auto fip = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FIP));
5644 auto fcs = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FCS));
5645 auto fdp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FDP));
5646 auto fds = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FDS));
5647 auto mxcsr = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR));
5648 auto mxcsr_mask = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR_MASK));
5649 auto st0 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST0));
5650 auto st1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST1));
5651 auto st2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST2));
5652 auto st3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST3));
5653 auto st4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST4));
5654 auto st5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST5));
5655 auto st6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST6));
5656 auto st7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST7));
5657 auto xmm0 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM0));
5658 auto xmm1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM1));
5659 auto xmm2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM2));
5660 auto xmm3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM3));
5661 auto xmm4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM4));
5662 auto xmm5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM5));
5663 auto xmm6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM6));
5664 auto xmm7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM7));
5665 auto ffxsr = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EFER_FFXSR));
5666 auto cs = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CS));
5667
5668 /* Fetch the implicit memory slots for the 'Non-64-bit Mode Layout' */
5669 auto fcw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 0, fcw.getSize()));
5670 auto fsw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 2, fsw.getSize()));
5671 auto ftw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 4, ftw.getSize() / 2));
5672 auto fop_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 6, fop.getSize()));
5673 auto fip_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 8, fip.getSize() / 2));
5674 auto fcs_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 12, fcs.getSize()));
5675 auto fdp_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 16, fdp.getSize() / 2));
5676 auto fds_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 20, fds.getSize()));
5677 auto mxcsr_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 24, mxcsr.getSize()));
5678 auto mxcsr_mask_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 28, mxcsr_mask.getSize()));
5679 auto st0_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 32, st0.getSize()));
5680 auto st1_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 48, st1.getSize()));
5681 auto st2_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 64, st2.getSize()));
5682 auto st3_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 80, st3.getSize()));
5683 auto st4_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 96, st4.getSize()));
5684 auto st5_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 112, st5.getSize()));
5685 auto st6_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 128, st6.getSize()));
5686 auto st7_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 144, st7.getSize()));
5687 auto xmm0_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 160, xmm0.getSize()));
5688 auto xmm1_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 176, xmm1.getSize()));
5689 auto xmm2_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 192, xmm2.getSize()));
5690 auto xmm3_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 208, xmm3.getSize()));
5691 auto xmm4_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 224, xmm4.getSize()));
5692 auto xmm5_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 240, xmm5.getSize()));
5693 auto xmm6_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 256, xmm6.getSize()));
5694 auto xmm7_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 272, xmm7.getSize()));
5695
5696 /* Create the symbolic operands */
5697 auto fcw_ast = this->symbolicEngine->getOperandAst(inst, fcw_addr);
5698 auto fsw_ast = this->symbolicEngine->getOperandAst(inst, fsw_addr);
5699 auto ftw_ast = this->symbolicEngine->getOperandAst(inst, ftw_addr);
5700 auto fop_ast = this->symbolicEngine->getOperandAst(inst, fop_addr);
5701 auto fip_ast = this->astCtxt->zx(triton::bitsize::dword, this->symbolicEngine->getOperandAst(inst, fip_addr));
5702 auto fcs_ast = this->symbolicEngine->getOperandAst(inst, fcs_addr);
5703 auto fdp_ast = this->astCtxt->zx(triton::bitsize::dword, this->symbolicEngine->getOperandAst(inst, fdp_addr));
5704 auto fds_ast = this->symbolicEngine->getOperandAst(inst, fds_addr);
5705 auto mxcsr_ast = this->symbolicEngine->getOperandAst(inst, mxcsr_addr);
5706 auto mxcsr_mask_ast = this->symbolicEngine->getOperandAst(inst, mxcsr_mask_addr);
5707 auto st0_ast = this->symbolicEngine->getOperandAst(inst, st0_addr);
5708 auto st1_ast = this->symbolicEngine->getOperandAst(inst, st1_addr);
5709 auto st2_ast = this->symbolicEngine->getOperandAst(inst, st2_addr);
5710 auto st3_ast = this->symbolicEngine->getOperandAst(inst, st3_addr);
5711 auto st4_ast = this->symbolicEngine->getOperandAst(inst, st4_addr);
5712 auto st5_ast = this->symbolicEngine->getOperandAst(inst, st5_addr);
5713 auto st6_ast = this->symbolicEngine->getOperandAst(inst, st6_addr);
5714 auto st7_ast = this->symbolicEngine->getOperandAst(inst, st7_addr);
5715 auto xmm0_ast = this->symbolicEngine->getOperandAst(inst, xmm0_addr);
5716 auto xmm1_ast = this->symbolicEngine->getOperandAst(inst, xmm1_addr);
5717 auto xmm2_ast = this->symbolicEngine->getOperandAst(inst, xmm2_addr);
5718 auto xmm3_ast = this->symbolicEngine->getOperandAst(inst, xmm3_addr);
5719 auto xmm4_ast = this->symbolicEngine->getOperandAst(inst, xmm4_addr);
5720 auto xmm5_ast = this->symbolicEngine->getOperandAst(inst, xmm5_addr);
5721 auto xmm6_ast = this->symbolicEngine->getOperandAst(inst, xmm6_addr);
5722 auto xmm7_ast = this->symbolicEngine->getOperandAst(inst, xmm7_addr);
5723 auto ffxsr_ast = this->symbolicEngine->getOperandAst(inst, ffxsr);
5724 auto cs_ast = this->symbolicEngine->getOperandAst(inst, cs);
5725
5726 /* Fetch the original values for the XMM0-XMM7 registers */
5727 auto xmm0_orig = this->symbolicEngine->getOperandAst(inst, xmm0);
5728 auto xmm1_orig = this->symbolicEngine->getOperandAst(inst, xmm1);
5729 auto xmm2_orig = this->symbolicEngine->getOperandAst(inst, xmm2);
5730 auto xmm3_orig = this->symbolicEngine->getOperandAst(inst, xmm3);
5731 auto xmm4_orig = this->symbolicEngine->getOperandAst(inst, xmm4);
5732 auto xmm5_orig = this->symbolicEngine->getOperandAst(inst, xmm5);
5733 auto xmm6_orig = this->symbolicEngine->getOperandAst(inst, xmm6);
5734 auto xmm7_orig = this->symbolicEngine->getOperandAst(inst, xmm7);
5735
5736 /* Check if we are running in CPL = 0 (ring 0) and if the FFXSR bit is set in EFER */
5737 auto cpl = this->astCtxt->equal(this->astCtxt->extract(1, 0, cs_ast), this->astCtxt->bv(0, 2));
5738 auto ffx = this->astCtxt->equal(ffxsr_ast, this->astCtxt->bv(1, 1));
5739 auto b64 = this->astCtxt->equal(this->astCtxt->bv(is64bits, 1), this->astCtxt->bv(1, 1));
5740 auto is_fast = this->astCtxt->land(this->astCtxt->land(cpl, ffx), b64);
5741
5742 /* Apply the fast restore logic if needed */
5743 xmm0_ast = this->astCtxt->ite(is_fast, xmm0_orig, xmm0_ast);
5744 xmm1_ast = this->astCtxt->ite(is_fast, xmm1_orig, xmm1_ast);
5745 xmm2_ast = this->astCtxt->ite(is_fast, xmm2_orig, xmm2_ast);
5746 xmm3_ast = this->astCtxt->ite(is_fast, xmm3_orig, xmm3_ast);
5747 xmm4_ast = this->astCtxt->ite(is_fast, xmm4_orig, xmm4_ast);
5748 xmm5_ast = this->astCtxt->ite(is_fast, xmm5_orig, xmm5_ast);
5749 xmm6_ast = this->astCtxt->ite(is_fast, xmm6_orig, xmm6_ast);
5750 xmm7_ast = this->astCtxt->ite(is_fast, xmm7_orig, xmm7_ast);
5751
5752 /* Fetch the abridged x87 FPU Tag Word Encoded Bits */
5753 auto eb_1_0 = this->astCtxt->extract(0, 0, ftw_ast);
5754 auto eb_3_2 = this->astCtxt->extract(1, 1, ftw_ast);
5755 auto eb_5_4 = this->astCtxt->extract(2, 2, ftw_ast);
5756 auto eb_7_6 = this->astCtxt->extract(3, 3, ftw_ast);
5757 auto eb_9_8 = this->astCtxt->extract(4, 4, ftw_ast);
5758 auto eb_11_10 = this->astCtxt->extract(5, 5, ftw_ast);
5759 auto eb_13_12 = this->astCtxt->extract(6, 6, ftw_ast);
5760 auto eb_15_14 = this->astCtxt->extract(7, 7, ftw_ast);
5761
5762 /* Extract the fraction from the STX registers */
5763 auto fraction_st0 = this->astCtxt->extract(62, 0, st0_ast);
5764 auto fraction_st1 = this->astCtxt->extract(62, 0, st1_ast);
5765 auto fraction_st2 = this->astCtxt->extract(62, 0, st2_ast);
5766 auto fraction_st3 = this->astCtxt->extract(62, 0, st3_ast);
5767 auto fraction_st4 = this->astCtxt->extract(62, 0, st4_ast);
5768 auto fraction_st5 = this->astCtxt->extract(62, 0, st5_ast);
5769 auto fraction_st6 = this->astCtxt->extract(62, 0, st6_ast);
5770 auto fraction_st7 = this->astCtxt->extract(62, 0, st7_ast);
5771
5772 /* Extract the integer bit from the STX registers */
5773 auto integer_st0 = this->astCtxt->extract(63, 63, st0_ast);
5774 auto integer_st1 = this->astCtxt->extract(63, 63, st1_ast);
5775 auto integer_st2 = this->astCtxt->extract(63, 63, st2_ast);
5776 auto integer_st3 = this->astCtxt->extract(63, 63, st3_ast);
5777 auto integer_st4 = this->astCtxt->extract(63, 63, st4_ast);
5778 auto integer_st5 = this->astCtxt->extract(63, 63, st5_ast);
5779 auto integer_st6 = this->astCtxt->extract(63, 63, st6_ast);
5780 auto integer_st7 = this->astCtxt->extract(63, 63, st7_ast);
5781
5782 /* Extract the exponent from the STX registers */
5783 auto exponent_st0 = this->astCtxt->extract(79, 64, st0_ast);
5784 auto exponent_st1 = this->astCtxt->extract(79, 64, st1_ast);
5785 auto exponent_st2 = this->astCtxt->extract(79, 64, st2_ast);
5786 auto exponent_st3 = this->astCtxt->extract(79, 64, st3_ast);
5787 auto exponent_st4 = this->astCtxt->extract(79, 64, st4_ast);
5788 auto exponent_st5 = this->astCtxt->extract(79, 64, st5_ast);
5789 auto exponent_st6 = this->astCtxt->extract(79, 64, st6_ast);
5790 auto exponent_st7 = this->astCtxt->extract(79, 64, st7_ast);
5791
5792 /* Exponent All Zeros */
5793 auto ea0_st0 = this->astCtxt->equal(exponent_st0, this->astCtxt->bv(0x0000, 16));
5794 auto ea0_st1 = this->astCtxt->equal(exponent_st1, this->astCtxt->bv(0x0000, 16));
5795 auto ea0_st2 = this->astCtxt->equal(exponent_st2, this->astCtxt->bv(0x0000, 16));
5796 auto ea0_st3 = this->astCtxt->equal(exponent_st3, this->astCtxt->bv(0x0000, 16));
5797 auto ea0_st4 = this->astCtxt->equal(exponent_st4, this->astCtxt->bv(0x0000, 16));
5798 auto ea0_st5 = this->astCtxt->equal(exponent_st5, this->astCtxt->bv(0x0000, 16));
5799 auto ea0_st6 = this->astCtxt->equal(exponent_st6, this->astCtxt->bv(0x0000, 16));
5800 auto ea0_st7 = this->astCtxt->equal(exponent_st7, this->astCtxt->bv(0x0000, 16));
5801
5802 /* Exponent All Ones */
5803 auto ea1_st0 = this->astCtxt->equal(exponent_st0, this->astCtxt->bv(0xFFFF, 16));
5804 auto ea1_st1 = this->astCtxt->equal(exponent_st1, this->astCtxt->bv(0xFFFF, 16));
5805 auto ea1_st2 = this->astCtxt->equal(exponent_st2, this->astCtxt->bv(0xFFFF, 16));
5806 auto ea1_st3 = this->astCtxt->equal(exponent_st3, this->astCtxt->bv(0xFFFF, 16));
5807 auto ea1_st4 = this->astCtxt->equal(exponent_st4, this->astCtxt->bv(0xFFFF, 16));
5808 auto ea1_st5 = this->astCtxt->equal(exponent_st5, this->astCtxt->bv(0xFFFF, 16));
5809 auto ea1_st6 = this->astCtxt->equal(exponent_st6, this->astCtxt->bv(0xFFFF, 16));
5810 auto ea1_st7 = this->astCtxt->equal(exponent_st7, this->astCtxt->bv(0xFFFF, 16));
5811
5812 /* Exponent Neither All Zeroes Or Ones */
5813 auto ena01_st0 = this->astCtxt->equal(this->astCtxt->lor(ea0_st0, ea1_st0), this->astCtxt->bvfalse());
5814 auto ena01_st1 = this->astCtxt->equal(this->astCtxt->lor(ea0_st1, ea1_st1), this->astCtxt->bvfalse());
5815 auto ena01_st2 = this->astCtxt->equal(this->astCtxt->lor(ea0_st2, ea1_st2), this->astCtxt->bvfalse());
5816 auto ena01_st3 = this->astCtxt->equal(this->astCtxt->lor(ea0_st3, ea1_st3), this->astCtxt->bvfalse());
5817 auto ena01_st4 = this->astCtxt->equal(this->astCtxt->lor(ea0_st4, ea1_st4), this->astCtxt->bvfalse());
5818 auto ena01_st5 = this->astCtxt->equal(this->astCtxt->lor(ea0_st5, ea1_st5), this->astCtxt->bvfalse());
5819 auto ena01_st6 = this->astCtxt->equal(this->astCtxt->lor(ea0_st6, ea1_st6), this->astCtxt->bvfalse());
5820 auto ena01_st7 = this->astCtxt->equal(this->astCtxt->lor(ea0_st7, ea1_st7), this->astCtxt->bvfalse());
5821
5822 /* Integer Bit 0 */
5823 auto ib0_st0 = this->astCtxt->equal(integer_st0, this->astCtxt->bv(0, 1));
5824 auto ib0_st1 = this->astCtxt->equal(integer_st1, this->astCtxt->bv(0, 1));
5825 auto ib0_st2 = this->astCtxt->equal(integer_st2, this->astCtxt->bv(0, 1));
5826 auto ib0_st3 = this->astCtxt->equal(integer_st3, this->astCtxt->bv(0, 1));
5827 auto ib0_st4 = this->astCtxt->equal(integer_st4, this->astCtxt->bv(0, 1));
5828 auto ib0_st5 = this->astCtxt->equal(integer_st5, this->astCtxt->bv(0, 1));
5829 auto ib0_st6 = this->astCtxt->equal(integer_st6, this->astCtxt->bv(0, 1));
5830 auto ib0_st7 = this->astCtxt->equal(integer_st7, this->astCtxt->bv(0, 1));
5831
5832 /* Fraction All Zeroes */
5833 auto fa0_st0 = this->astCtxt->equal(fraction_st0, this->astCtxt->bv(0, 63));
5834 auto fa0_st1 = this->astCtxt->equal(fraction_st1, this->astCtxt->bv(0, 63));
5835 auto fa0_st2 = this->astCtxt->equal(fraction_st2, this->astCtxt->bv(0, 63));
5836 auto fa0_st3 = this->astCtxt->equal(fraction_st3, this->astCtxt->bv(0, 63));
5837 auto fa0_st4 = this->astCtxt->equal(fraction_st4, this->astCtxt->bv(0, 63));
5838 auto fa0_st5 = this->astCtxt->equal(fraction_st5, this->astCtxt->bv(0, 63));
5839 auto fa0_st6 = this->astCtxt->equal(fraction_st6, this->astCtxt->bv(0, 63));
5840 auto fa0_st7 = this->astCtxt->equal(fraction_st7, this->astCtxt->bv(0, 63));
5841
5842 /* Determine the x87 FPU Tag Word (Diagram at page 379 of the AMD Architecture Programmer's Manual, Volume 2: System Programming) */
5843 auto db_1_0 = this->astCtxt->ite(this->astCtxt->equal(eb_1_0, this->astCtxt->bv(0, 1)),
5844 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
5845 this->astCtxt->ite(ea0_st0,
5846 this->astCtxt->ite(ib0_st0,
5847 this->astCtxt->ite(fa0_st0,
5848 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
5849 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
5850 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
5851 this->astCtxt->ite(ena01_st0,
5852 this->astCtxt->ite(ib0_st0,
5853 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
5854 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
5855 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
5856
5857 auto db_3_2 = this->astCtxt->ite(this->astCtxt->equal(eb_3_2, this->astCtxt->bv(0, 1)),
5858 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
5859 this->astCtxt->ite(ea0_st1,
5860 this->astCtxt->ite(ib0_st1,
5861 this->astCtxt->ite(fa0_st1,
5862 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
5863 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
5864 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
5865 this->astCtxt->ite(ena01_st1,
5866 this->astCtxt->ite(ib0_st1,
5867 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
5868 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
5869 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
5870
5871 auto db_5_4 = this->astCtxt->ite(this->astCtxt->equal(eb_5_4, this->astCtxt->bv(0, 1)),
5872 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
5873 this->astCtxt->ite(ea0_st2,
5874 this->astCtxt->ite(ib0_st2,
5875 this->astCtxt->ite(fa0_st2,
5876 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
5877 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
5878 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
5879 this->astCtxt->ite(ena01_st2,
5880 this->astCtxt->ite(ib0_st2,
5881 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
5882 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
5883 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
5884
5885 auto db_7_6 = this->astCtxt->ite(this->astCtxt->equal(eb_7_6, this->astCtxt->bv(0, 1)),
5886 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
5887 this->astCtxt->ite(ea0_st3,
5888 this->astCtxt->ite(ib0_st3,
5889 this->astCtxt->ite(fa0_st3,
5890 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
5891 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
5892 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
5893 this->astCtxt->ite(ena01_st3,
5894 this->astCtxt->ite(ib0_st3,
5895 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
5896 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
5897 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
5898
5899 auto db_9_8 = this->astCtxt->ite(this->astCtxt->equal(eb_9_8, this->astCtxt->bv(0, 1)),
5900 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
5901 this->astCtxt->ite(ea0_st4,
5902 this->astCtxt->ite(ib0_st4,
5903 this->astCtxt->ite(fa0_st4,
5904 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
5905 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
5906 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
5907 this->astCtxt->ite(ena01_st4,
5908 this->astCtxt->ite(ib0_st4,
5909 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
5910 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
5911 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
5912
5913 auto db_11_10 = this->astCtxt->ite(this->astCtxt->equal(eb_11_10, this->astCtxt->bv(0, 1)),
5914 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
5915 this->astCtxt->ite(ea0_st5,
5916 this->astCtxt->ite(ib0_st5,
5917 this->astCtxt->ite(fa0_st5,
5918 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
5919 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
5920 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
5921 this->astCtxt->ite(ena01_st5,
5922 this->astCtxt->ite(ib0_st5,
5923 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
5924 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
5925 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
5926
5927 auto db_13_12 = this->astCtxt->ite(this->astCtxt->equal(eb_13_12, this->astCtxt->bv(0, 1)),
5928 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
5929 this->astCtxt->ite(ea0_st6,
5930 this->astCtxt->ite(ib0_st6,
5931 this->astCtxt->ite(fa0_st6,
5932 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
5933 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
5934 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
5935 this->astCtxt->ite(ena01_st6,
5936 this->astCtxt->ite(ib0_st6,
5937 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
5938 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
5939 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
5940
5941 auto db_15_14 = this->astCtxt->ite(this->astCtxt->equal(eb_15_14, this->astCtxt->bv(0, 1)),
5942 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
5943 this->astCtxt->ite(ea0_st7,
5944 this->astCtxt->ite(ib0_st7,
5945 this->astCtxt->ite(fa0_st7,
5946 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
5947 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
5948 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
5949 this->astCtxt->ite(ena01_st7,
5950 this->astCtxt->ite(ib0_st7,
5951 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
5952 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
5953 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
5954
5955 /* Restore the x87 FPU Tag Word */
5956 auto uftw_ast = this->astCtxt->concat(db_15_14,
5957 this->astCtxt->concat(db_13_12,
5958 this->astCtxt->concat(db_11_10,
5959 this->astCtxt->concat(db_9_8,
5960 this->astCtxt->concat(db_7_6,
5961 this->astCtxt->concat(db_5_4,
5962 this->astCtxt->concat(db_3_2, db_1_0)))))));
5963
5964 /* Craft the symbolic expressions */
5965 auto fcw_expr = this->symbolicEngine->createSymbolicExpression(inst, fcw_ast, fcw, "FXRSTOR FCW operation");
5966 auto fsw_expr = this->symbolicEngine->createSymbolicExpression(inst, fsw_ast, fsw, "FXRSTOR FSW operation");
5967 auto ftw_expr = this->symbolicEngine->createSymbolicExpression(inst, uftw_ast, ftw, "FXRSTOR Updated FTW operation");
5968 auto fop_expr = this->symbolicEngine->createSymbolicExpression(inst, fop_ast, fop, "FXRSTOR FOP operation");
5969 auto fip_expr = this->symbolicEngine->createSymbolicExpression(inst, fip_ast, fip, "FXRSTOR FIP operation");
5970 auto fcs_expr = this->symbolicEngine->createSymbolicExpression(inst, fcs_ast, fcs, "FXRSTOR FCS operation");
5971 auto fdp_expr = this->symbolicEngine->createSymbolicExpression(inst, fdp_ast, fdp, "FXRSTOR FDP operation");
5972 auto fds_expr = this->symbolicEngine->createSymbolicExpression(inst, fds_ast, fds, "FXRSTOR FDS operation");
5973 auto mxcsr_expr = this->symbolicEngine->createSymbolicExpression(inst, mxcsr_ast, mxcsr, "FXRSTOR MXCSR operation");
5974 auto mxcsr_mask_expr = this->symbolicEngine->createSymbolicExpression(inst, mxcsr_mask_ast, mxcsr_mask, "FXRSTOR MXCSR_MASK operation");
5975 auto st0_expr = this->symbolicEngine->createSymbolicExpression(inst, st0_ast, st0, "FXRSTOR ST0 operation");
5976 auto st1_expr = this->symbolicEngine->createSymbolicExpression(inst, st1_ast, st1, "FXRSTOR ST1 operation");
5977 auto st2_expr = this->symbolicEngine->createSymbolicExpression(inst, st2_ast, st2, "FXRSTOR ST2 operation");
5978 auto st3_expr = this->symbolicEngine->createSymbolicExpression(inst, st3_ast, st3, "FXRSTOR ST3 operation");
5979 auto st4_expr = this->symbolicEngine->createSymbolicExpression(inst, st4_ast, st4, "FXRSTOR ST4 operation");
5980 auto st5_expr = this->symbolicEngine->createSymbolicExpression(inst, st5_ast, st5, "FXRSTOR ST5 operation");
5981 auto st6_expr = this->symbolicEngine->createSymbolicExpression(inst, st6_ast, st6, "FXRSTOR ST6 operation");
5982 auto st7_expr = this->symbolicEngine->createSymbolicExpression(inst, st7_ast, st7, "FXRSTOR ST7 operation");
5983 auto xmm0_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm0_ast, xmm0, "FXRSTOR XMM0 operation");
5984 auto xmm1_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm1_ast, xmm1, "FXRSTOR XMM1 operation");
5985 auto xmm2_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm2_ast, xmm2, "FXRSTOR XMM2 operation");
5986 auto xmm3_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm3_ast, xmm3, "FXRSTOR XMM3 operation");
5987 auto xmm4_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm4_ast, xmm4, "FXRSTOR XMM4 operation");
5988 auto xmm5_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm5_ast, xmm5, "FXRSTOR XMM5 operation");
5989 auto xmm6_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm6_ast, xmm6, "FXRSTOR XMM6 operation");
5990 auto xmm7_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm7_ast, xmm7, "FXRSTOR XMM7 operation");
5991
5992 /* Spread the taint */
5993 fcw_expr->isTainted = this->taintEngine->taintAssignment(fcw, fcw_addr);
5994 fsw_expr->isTainted = this->taintEngine->taintAssignment(fsw, fsw_addr);
5995 ftw_expr->isTainted = this->taintEngine->taintAssignment(ftw, ftw_addr);
5996 fop_expr->isTainted = this->taintEngine->taintAssignment(fop, fop_addr);
5997 fip_expr->isTainted = this->taintEngine->taintAssignment(fip, fip_addr);
5998 fcs_expr->isTainted = this->taintEngine->taintAssignment(fcs, fcs_addr);
5999 fdp_expr->isTainted = this->taintEngine->taintAssignment(fdp, fdp_addr);
6000 fds_expr->isTainted = this->taintEngine->taintAssignment(fds, fds_addr);
6001 mxcsr_expr->isTainted = this->taintEngine->taintAssignment(mxcsr, mxcsr_addr);
6002 mxcsr_mask_expr->isTainted = this->taintEngine->taintAssignment(mxcsr_mask, mxcsr_mask_addr);
6003 st0_expr->isTainted = this->taintEngine->taintAssignment(st0, st0_addr);
6004 st1_expr->isTainted = this->taintEngine->taintAssignment(st1, st1_addr);
6005 st2_expr->isTainted = this->taintEngine->taintAssignment(st2, st2_addr);
6006 st3_expr->isTainted = this->taintEngine->taintAssignment(st3, st3_addr);
6007 st4_expr->isTainted = this->taintEngine->taintAssignment(st4, st4_addr);
6008 st5_expr->isTainted = this->taintEngine->taintAssignment(st5, st5_addr);
6009 st6_expr->isTainted = this->taintEngine->taintAssignment(st6, st6_addr);
6010 st7_expr->isTainted = this->taintEngine->taintAssignment(st7, st7_addr);
6011 xmm0_expr->isTainted = this->taintEngine->taintAssignment(xmm0, xmm0_addr);
6012 xmm1_expr->isTainted = this->taintEngine->taintAssignment(xmm1, xmm1_addr);
6013 xmm2_expr->isTainted = this->taintEngine->taintAssignment(xmm2, xmm2_addr);
6014 xmm3_expr->isTainted = this->taintEngine->taintAssignment(xmm3, xmm3_addr);
6015 xmm4_expr->isTainted = this->taintEngine->taintAssignment(xmm4, xmm4_addr);
6016 xmm5_expr->isTainted = this->taintEngine->taintAssignment(xmm5, xmm5_addr);
6017 xmm6_expr->isTainted = this->taintEngine->taintAssignment(xmm6, xmm6_addr);
6018 xmm7_expr->isTainted = this->taintEngine->taintAssignment(xmm7, xmm7_addr);
6019
6020 /* Additional semantics, symbolic expressions and tainting for the '64-bit Mode Layout (with REX.W = 0)' */
6021 if (is64bits) {
6022 auto xmm8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM8));
6023 auto xmm9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM9));
6024 auto xmm10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM10));
6025 auto xmm11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM11));
6026 auto xmm12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM12));
6027 auto xmm13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM13));
6028 auto xmm14 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM14));
6029 auto xmm15 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM15));
6030
6031 auto xmm8_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 288, xmm8.getSize()));
6032 auto xmm9_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 304, xmm9.getSize()));
6033 auto xmm10_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 320, xmm10.getSize()));
6034 auto xmm11_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 336, xmm11.getSize()));
6035 auto xmm12_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 352, xmm12.getSize()));
6036 auto xmm13_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 368, xmm13.getSize()));
6037 auto xmm14_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 384, xmm14.getSize()));
6038 auto xmm15_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 400, xmm15.getSize()));
6039
6040 auto xmm8_ast = this->symbolicEngine->getOperandAst(inst, xmm8_addr);
6041 auto xmm9_ast = this->symbolicEngine->getOperandAst(inst, xmm9_addr);
6042 auto xmm10_ast = this->symbolicEngine->getOperandAst(inst, xmm10_addr);
6043 auto xmm11_ast = this->symbolicEngine->getOperandAst(inst, xmm11_addr);
6044 auto xmm12_ast = this->symbolicEngine->getOperandAst(inst, xmm12_addr);
6045 auto xmm13_ast = this->symbolicEngine->getOperandAst(inst, xmm13_addr);
6046 auto xmm14_ast = this->symbolicEngine->getOperandAst(inst, xmm14_addr);
6047 auto xmm15_ast = this->symbolicEngine->getOperandAst(inst, xmm15_addr);
6048
6049 /* Fetch the original values for the XMM8-XMM15 registers */
6050 auto xmm8_orig = this->symbolicEngine->getOperandAst(inst, xmm8);
6051 auto xmm9_orig = this->symbolicEngine->getOperandAst(inst, xmm9);
6052 auto xmm10_orig = this->symbolicEngine->getOperandAst(inst, xmm10);
6053 auto xmm11_orig = this->symbolicEngine->getOperandAst(inst, xmm11);
6054 auto xmm12_orig = this->symbolicEngine->getOperandAst(inst, xmm12);
6055 auto xmm13_orig = this->symbolicEngine->getOperandAst(inst, xmm13);
6056 auto xmm14_orig = this->symbolicEngine->getOperandAst(inst, xmm14);
6057 auto xmm15_orig = this->symbolicEngine->getOperandAst(inst, xmm15);
6058
6059 /* Apply the fast restore logic if needed */
6060 xmm8_ast = this->astCtxt->ite(is_fast, xmm8_orig, xmm8_ast);
6061 xmm9_ast = this->astCtxt->ite(is_fast, xmm9_orig, xmm9_ast);
6062 xmm10_ast = this->astCtxt->ite(is_fast, xmm10_orig, xmm10_ast);
6063 xmm11_ast = this->astCtxt->ite(is_fast, xmm11_orig, xmm11_ast);
6064 xmm12_ast = this->astCtxt->ite(is_fast, xmm12_orig, xmm12_ast);
6065 xmm13_ast = this->astCtxt->ite(is_fast, xmm13_orig, xmm13_ast);
6066 xmm14_ast = this->astCtxt->ite(is_fast, xmm14_orig, xmm14_ast);
6067 xmm15_ast = this->astCtxt->ite(is_fast, xmm15_orig, xmm15_ast);
6068
6069 auto xmm8_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm8_ast, xmm8, "FXRSTOR XMM8 operation");
6070 auto xmm9_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm9_ast, xmm9, "FXRSTOR XMM9 operation");
6071 auto xmm10_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm10_ast, xmm10, "FXRSTOR XMM10 operation");
6072 auto xmm11_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm11_ast, xmm11, "FXRSTOR XMM11 operation");
6073 auto xmm12_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm12_ast, xmm12, "FXRSTOR XMM12 operation");
6074 auto xmm13_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm13_ast, xmm13, "FXRSTOR XMM13 operation");
6075 auto xmm14_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm14_ast, xmm14, "FXRSTOR XMM14 operation");
6076 auto xmm15_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm15_ast, xmm15, "FXRSTOR XMM15 operation");
6077
6078 xmm8_expr->isTainted = this->taintEngine->taintAssignment(xmm8, xmm8_addr);
6079 xmm9_expr->isTainted = this->taintEngine->taintAssignment(xmm9, xmm9_addr);
6080 xmm10_expr->isTainted = this->taintEngine->taintAssignment(xmm10, xmm10_addr);
6081 xmm11_expr->isTainted = this->taintEngine->taintAssignment(xmm11, xmm11_addr);
6082 xmm12_expr->isTainted = this->taintEngine->taintAssignment(xmm12, xmm12_addr);
6083 xmm13_expr->isTainted = this->taintEngine->taintAssignment(xmm13, xmm13_addr);
6084 xmm14_expr->isTainted = this->taintEngine->taintAssignment(xmm14, xmm14_addr);
6085 xmm15_expr->isTainted = this->taintEngine->taintAssignment(xmm15, xmm15_addr);
6086 }
6087
6088 /* Update the symbolic control flow */
6089 this->controlFlow_s(inst);
6090 }
6091
6092
6093 void x86Semantics::fxrstor64_s(triton::arch::Instruction& inst) {
6094 /* Fetch the memory operand */
6095 auto& dst = inst.operands[0];
6096 auto& mem = dst.getMemory();
6097 auto m512byte = mem.getAddress();
6098
6099 /* Check if the address is on a 16-byte boundary */
6100 if (m512byte & 0xF) {
6101 this->exception = triton::arch::FAULT_GP;
6102 return;
6103 }
6104
6105 /* Fetch the FPU, STX, SSE, EFER and CS implicit operands */
6106 auto fcw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FCW));
6107 auto fsw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FSW));
6108 auto ftw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FTW));
6109 auto fop = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FOP));
6110 auto fip = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FIP));
6111 auto fcs = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FCS));
6112 auto fdp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FDP));
6113 auto fds = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FDS));
6114 auto mxcsr = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR));
6115 auto mxcsr_mask = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR_MASK));
6116 auto st0 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST0));
6117 auto st1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST1));
6118 auto st2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST2));
6119 auto st3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST3));
6120 auto st4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST4));
6121 auto st5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST5));
6122 auto st6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST6));
6123 auto st7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST7));
6124 auto xmm0 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM0));
6125 auto xmm1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM1));
6126 auto xmm2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM2));
6127 auto xmm3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM3));
6128 auto xmm4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM4));
6129 auto xmm5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM5));
6130 auto xmm6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM6));
6131 auto xmm7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM7));
6132 auto xmm8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM8));
6133 auto xmm9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM9));
6134 auto xmm10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM10));
6135 auto xmm11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM11));
6136 auto xmm12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM12));
6137 auto xmm13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM13));
6138 auto xmm14 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM14));
6139 auto xmm15 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM15));
6140 auto ffxsr = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EFER_FFXSR));
6141 auto cs = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CS));
6142
6143 /* Fetch the implicit memory slots for the '64-bit Mode Layout (with REX.W = 1)' */
6144 auto fcw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 0, fcw.getSize()));
6145 auto fsw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 2, fsw.getSize()));
6146 auto ftw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 4, ftw.getSize() / 2));
6147 auto fop_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 6, fop.getSize()));
6148 auto fip_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 8, fip.getSize()));
6149 auto fcs_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 12, fcs.getSize()));
6150 auto fdp_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 16, fdp.getSize()));
6151 auto fds_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 20, fds.getSize()));
6152 auto mxcsr_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 24, mxcsr.getSize()));
6153 auto mxcsr_mask_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 28, mxcsr_mask.getSize()));
6154 auto st0_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 32, st0.getSize()));
6155 auto st1_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 48, st1.getSize()));
6156 auto st2_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 64, st2.getSize()));
6157 auto st3_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 80, st3.getSize()));
6158 auto st4_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 96, st4.getSize()));
6159 auto st5_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 112, st5.getSize()));
6160 auto st6_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 128, st6.getSize()));
6161 auto st7_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 144, st7.getSize()));
6162 auto xmm0_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 160, xmm0.getSize()));
6163 auto xmm1_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 176, xmm1.getSize()));
6164 auto xmm2_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 192, xmm2.getSize()));
6165 auto xmm3_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 208, xmm3.getSize()));
6166 auto xmm4_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 224, xmm4.getSize()));
6167 auto xmm5_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 240, xmm5.getSize()));
6168 auto xmm6_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 256, xmm6.getSize()));
6169 auto xmm7_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 272, xmm7.getSize()));
6170 auto xmm8_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 288, xmm8.getSize()));
6171 auto xmm9_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 304, xmm9.getSize()));
6172 auto xmm10_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 320, xmm10.getSize()));
6173 auto xmm11_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 336, xmm11.getSize()));
6174 auto xmm12_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 352, xmm12.getSize()));
6175 auto xmm13_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 368, xmm13.getSize()));
6176 auto xmm14_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 384, xmm14.getSize()));
6177 auto xmm15_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 400, xmm15.getSize()));
6178
6179 /* Create the symbolic operands */
6180 auto fcw_ast = this->symbolicEngine->getOperandAst(inst, fcw_addr);
6181 auto fsw_ast = this->symbolicEngine->getOperandAst(inst, fsw_addr);
6182 auto ftw_ast = this->symbolicEngine->getOperandAst(inst, ftw_addr);
6183 auto fop_ast = this->symbolicEngine->getOperandAst(inst, fop_addr);
6184 auto fip_ast = this->symbolicEngine->getOperandAst(inst, fip_addr);
6185 auto fcs_ast = this->symbolicEngine->getOperandAst(inst, fcs_addr);
6186 auto fdp_ast = this->symbolicEngine->getOperandAst(inst, fdp_addr);
6187 auto fds_ast = this->symbolicEngine->getOperandAst(inst, fds_addr);
6188 auto mxcsr_ast = this->symbolicEngine->getOperandAst(inst, mxcsr_addr);
6189 auto mxcsr_mask_ast = this->symbolicEngine->getOperandAst(inst, mxcsr_mask_addr);
6190 auto st0_ast = this->symbolicEngine->getOperandAst(inst, st0_addr);
6191 auto st1_ast = this->symbolicEngine->getOperandAst(inst, st1_addr);
6192 auto st2_ast = this->symbolicEngine->getOperandAst(inst, st2_addr);
6193 auto st3_ast = this->symbolicEngine->getOperandAst(inst, st3_addr);
6194 auto st4_ast = this->symbolicEngine->getOperandAst(inst, st4_addr);
6195 auto st5_ast = this->symbolicEngine->getOperandAst(inst, st5_addr);
6196 auto st6_ast = this->symbolicEngine->getOperandAst(inst, st6_addr);
6197 auto st7_ast = this->symbolicEngine->getOperandAst(inst, st7_addr);
6198 auto xmm0_ast = this->symbolicEngine->getOperandAst(inst, xmm0_addr);
6199 auto xmm1_ast = this->symbolicEngine->getOperandAst(inst, xmm1_addr);
6200 auto xmm2_ast = this->symbolicEngine->getOperandAst(inst, xmm2_addr);
6201 auto xmm3_ast = this->symbolicEngine->getOperandAst(inst, xmm3_addr);
6202 auto xmm4_ast = this->symbolicEngine->getOperandAst(inst, xmm4_addr);
6203 auto xmm5_ast = this->symbolicEngine->getOperandAst(inst, xmm5_addr);
6204 auto xmm6_ast = this->symbolicEngine->getOperandAst(inst, xmm6_addr);
6205 auto xmm7_ast = this->symbolicEngine->getOperandAst(inst, xmm7_addr);
6206 auto xmm8_ast = this->symbolicEngine->getOperandAst(inst, xmm8_addr);
6207 auto xmm9_ast = this->symbolicEngine->getOperandAst(inst, xmm9_addr);
6208 auto xmm10_ast = this->symbolicEngine->getOperandAst(inst, xmm10_addr);
6209 auto xmm11_ast = this->symbolicEngine->getOperandAst(inst, xmm11_addr);
6210 auto xmm12_ast = this->symbolicEngine->getOperandAst(inst, xmm12_addr);
6211 auto xmm13_ast = this->symbolicEngine->getOperandAst(inst, xmm13_addr);
6212 auto xmm14_ast = this->symbolicEngine->getOperandAst(inst, xmm14_addr);
6213 auto xmm15_ast = this->symbolicEngine->getOperandAst(inst, xmm15_addr);
6214 auto ffxsr_ast = this->symbolicEngine->getOperandAst(inst, ffxsr);
6215 auto cs_ast = this->symbolicEngine->getOperandAst(inst, cs);
6216
6217 /* Fetch the original values for the XMM0-XMM15 registers */
6218 auto xmm0_orig = this->symbolicEngine->getOperandAst(inst, xmm0);
6219 auto xmm1_orig = this->symbolicEngine->getOperandAst(inst, xmm1);
6220 auto xmm2_orig = this->symbolicEngine->getOperandAst(inst, xmm2);
6221 auto xmm3_orig = this->symbolicEngine->getOperandAst(inst, xmm3);
6222 auto xmm4_orig = this->symbolicEngine->getOperandAst(inst, xmm4);
6223 auto xmm5_orig = this->symbolicEngine->getOperandAst(inst, xmm5);
6224 auto xmm6_orig = this->symbolicEngine->getOperandAst(inst, xmm6);
6225 auto xmm7_orig = this->symbolicEngine->getOperandAst(inst, xmm7);
6226 auto xmm8_orig = this->symbolicEngine->getOperandAst(inst, xmm8);
6227 auto xmm9_orig = this->symbolicEngine->getOperandAst(inst, xmm9);
6228 auto xmm10_orig = this->symbolicEngine->getOperandAst(inst, xmm10);
6229 auto xmm11_orig = this->symbolicEngine->getOperandAst(inst, xmm11);
6230 auto xmm12_orig = this->symbolicEngine->getOperandAst(inst, xmm12);
6231 auto xmm13_orig = this->symbolicEngine->getOperandAst(inst, xmm13);
6232 auto xmm14_orig = this->symbolicEngine->getOperandAst(inst, xmm14);
6233 auto xmm15_orig = this->symbolicEngine->getOperandAst(inst, xmm15);
6234
6235 /* Check if we are running in CPL = 0 (ring 0) and if the FFXSR bit is set in EFER */
6236 auto cpl = this->astCtxt->equal(this->astCtxt->extract(1, 0, cs_ast), this->astCtxt->bv(0, 2));
6237 auto ffx = this->astCtxt->equal(ffxsr_ast, this->astCtxt->bv(1, 1));
6238 auto is_fast = this->astCtxt->land(cpl, ffx);
6239
6240 /* Apply the fast restore logic if needed */
6241 xmm0_ast = this->astCtxt->ite(is_fast, xmm0_orig, xmm0_ast);
6242 xmm1_ast = this->astCtxt->ite(is_fast, xmm1_orig, xmm1_ast);
6243 xmm2_ast = this->astCtxt->ite(is_fast, xmm2_orig, xmm2_ast);
6244 xmm3_ast = this->astCtxt->ite(is_fast, xmm3_orig, xmm3_ast);
6245 xmm4_ast = this->astCtxt->ite(is_fast, xmm4_orig, xmm4_ast);
6246 xmm5_ast = this->astCtxt->ite(is_fast, xmm5_orig, xmm5_ast);
6247 xmm6_ast = this->astCtxt->ite(is_fast, xmm6_orig, xmm6_ast);
6248 xmm7_ast = this->astCtxt->ite(is_fast, xmm7_orig, xmm7_ast);
6249 xmm8_ast = this->astCtxt->ite(is_fast, xmm8_orig, xmm8_ast);
6250 xmm9_ast = this->astCtxt->ite(is_fast, xmm9_orig, xmm9_ast);
6251 xmm10_ast = this->astCtxt->ite(is_fast, xmm10_orig, xmm10_ast);
6252 xmm11_ast = this->astCtxt->ite(is_fast, xmm11_orig, xmm11_ast);
6253 xmm12_ast = this->astCtxt->ite(is_fast, xmm12_orig, xmm12_ast);
6254 xmm13_ast = this->astCtxt->ite(is_fast, xmm13_orig, xmm13_ast);
6255 xmm14_ast = this->astCtxt->ite(is_fast, xmm14_orig, xmm14_ast);
6256 xmm15_ast = this->astCtxt->ite(is_fast, xmm15_orig, xmm15_ast);
6257
6258 /* Fetch the abridged x87 FPU Tag Word Encoded Bits */
6259 auto eb_1_0 = this->astCtxt->extract(0, 0, ftw_ast);
6260 auto eb_3_2 = this->astCtxt->extract(1, 1, ftw_ast);
6261 auto eb_5_4 = this->astCtxt->extract(2, 2, ftw_ast);
6262 auto eb_7_6 = this->astCtxt->extract(3, 3, ftw_ast);
6263 auto eb_9_8 = this->astCtxt->extract(4, 4, ftw_ast);
6264 auto eb_11_10 = this->astCtxt->extract(5, 5, ftw_ast);
6265 auto eb_13_12 = this->astCtxt->extract(6, 6, ftw_ast);
6266 auto eb_15_14 = this->astCtxt->extract(7, 7, ftw_ast);
6267
6268 /* Extract the fraction from the STX registers */
6269 auto fraction_st0 = this->astCtxt->extract(62, 0, st0_ast);
6270 auto fraction_st1 = this->astCtxt->extract(62, 0, st1_ast);
6271 auto fraction_st2 = this->astCtxt->extract(62, 0, st2_ast);
6272 auto fraction_st3 = this->astCtxt->extract(62, 0, st3_ast);
6273 auto fraction_st4 = this->astCtxt->extract(62, 0, st4_ast);
6274 auto fraction_st5 = this->astCtxt->extract(62, 0, st5_ast);
6275 auto fraction_st6 = this->astCtxt->extract(62, 0, st6_ast);
6276 auto fraction_st7 = this->astCtxt->extract(62, 0, st7_ast);
6277
6278 /* Extract the integer bit from the STX registers */
6279 auto integer_st0 = this->astCtxt->extract(63, 63, st0_ast);
6280 auto integer_st1 = this->astCtxt->extract(63, 63, st1_ast);
6281 auto integer_st2 = this->astCtxt->extract(63, 63, st2_ast);
6282 auto integer_st3 = this->astCtxt->extract(63, 63, st3_ast);
6283 auto integer_st4 = this->astCtxt->extract(63, 63, st4_ast);
6284 auto integer_st5 = this->astCtxt->extract(63, 63, st5_ast);
6285 auto integer_st6 = this->astCtxt->extract(63, 63, st6_ast);
6286 auto integer_st7 = this->astCtxt->extract(63, 63, st7_ast);
6287
6288 /* Extract the exponent from the STX registers */
6289 auto exponent_st0 = this->astCtxt->extract(79, 64, st0_ast);
6290 auto exponent_st1 = this->astCtxt->extract(79, 64, st1_ast);
6291 auto exponent_st2 = this->astCtxt->extract(79, 64, st2_ast);
6292 auto exponent_st3 = this->astCtxt->extract(79, 64, st3_ast);
6293 auto exponent_st4 = this->astCtxt->extract(79, 64, st4_ast);
6294 auto exponent_st5 = this->astCtxt->extract(79, 64, st5_ast);
6295 auto exponent_st6 = this->astCtxt->extract(79, 64, st6_ast);
6296 auto exponent_st7 = this->astCtxt->extract(79, 64, st7_ast);
6297
6298 /* Exponent All Zeros */
6299 auto ea0_st0 = this->astCtxt->equal(exponent_st0, this->astCtxt->bv(0x0000, 16));
6300 auto ea0_st1 = this->astCtxt->equal(exponent_st1, this->astCtxt->bv(0x0000, 16));
6301 auto ea0_st2 = this->astCtxt->equal(exponent_st2, this->astCtxt->bv(0x0000, 16));
6302 auto ea0_st3 = this->astCtxt->equal(exponent_st3, this->astCtxt->bv(0x0000, 16));
6303 auto ea0_st4 = this->astCtxt->equal(exponent_st4, this->astCtxt->bv(0x0000, 16));
6304 auto ea0_st5 = this->astCtxt->equal(exponent_st5, this->astCtxt->bv(0x0000, 16));
6305 auto ea0_st6 = this->astCtxt->equal(exponent_st6, this->astCtxt->bv(0x0000, 16));
6306 auto ea0_st7 = this->astCtxt->equal(exponent_st7, this->astCtxt->bv(0x0000, 16));
6307
6308 /* Exponent All Ones */
6309 auto ea1_st0 = this->astCtxt->equal(exponent_st0, this->astCtxt->bv(0xFFFF, 16));
6310 auto ea1_st1 = this->astCtxt->equal(exponent_st1, this->astCtxt->bv(0xFFFF, 16));
6311 auto ea1_st2 = this->astCtxt->equal(exponent_st2, this->astCtxt->bv(0xFFFF, 16));
6312 auto ea1_st3 = this->astCtxt->equal(exponent_st3, this->astCtxt->bv(0xFFFF, 16));
6313 auto ea1_st4 = this->astCtxt->equal(exponent_st4, this->astCtxt->bv(0xFFFF, 16));
6314 auto ea1_st5 = this->astCtxt->equal(exponent_st5, this->astCtxt->bv(0xFFFF, 16));
6315 auto ea1_st6 = this->astCtxt->equal(exponent_st6, this->astCtxt->bv(0xFFFF, 16));
6316 auto ea1_st7 = this->astCtxt->equal(exponent_st7, this->astCtxt->bv(0xFFFF, 16));
6317
6318 /* Exponent Neither All Zeroes Or Ones */
6319 auto ena01_st0 = this->astCtxt->equal(this->astCtxt->lor(ea0_st0, ea1_st0), this->astCtxt->bvfalse());
6320 auto ena01_st1 = this->astCtxt->equal(this->astCtxt->lor(ea0_st1, ea1_st1), this->astCtxt->bvfalse());
6321 auto ena01_st2 = this->astCtxt->equal(this->astCtxt->lor(ea0_st2, ea1_st2), this->astCtxt->bvfalse());
6322 auto ena01_st3 = this->astCtxt->equal(this->astCtxt->lor(ea0_st3, ea1_st3), this->astCtxt->bvfalse());
6323 auto ena01_st4 = this->astCtxt->equal(this->astCtxt->lor(ea0_st4, ea1_st4), this->astCtxt->bvfalse());
6324 auto ena01_st5 = this->astCtxt->equal(this->astCtxt->lor(ea0_st5, ea1_st5), this->astCtxt->bvfalse());
6325 auto ena01_st6 = this->astCtxt->equal(this->astCtxt->lor(ea0_st6, ea1_st6), this->astCtxt->bvfalse());
6326 auto ena01_st7 = this->astCtxt->equal(this->astCtxt->lor(ea0_st7, ea1_st7), this->astCtxt->bvfalse());
6327
6328 /* Integer Bit 0 */
6329 auto ib0_st0 = this->astCtxt->equal(integer_st0, this->astCtxt->bv(0, 1));
6330 auto ib0_st1 = this->astCtxt->equal(integer_st1, this->astCtxt->bv(0, 1));
6331 auto ib0_st2 = this->astCtxt->equal(integer_st2, this->astCtxt->bv(0, 1));
6332 auto ib0_st3 = this->astCtxt->equal(integer_st3, this->astCtxt->bv(0, 1));
6333 auto ib0_st4 = this->astCtxt->equal(integer_st4, this->astCtxt->bv(0, 1));
6334 auto ib0_st5 = this->astCtxt->equal(integer_st5, this->astCtxt->bv(0, 1));
6335 auto ib0_st6 = this->astCtxt->equal(integer_st6, this->astCtxt->bv(0, 1));
6336 auto ib0_st7 = this->astCtxt->equal(integer_st7, this->astCtxt->bv(0, 1));
6337
6338 /* Fraction All Zeroes */
6339 auto fa0_st0 = this->astCtxt->equal(fraction_st0, this->astCtxt->bv(0, 63));
6340 auto fa0_st1 = this->astCtxt->equal(fraction_st1, this->astCtxt->bv(0, 63));
6341 auto fa0_st2 = this->astCtxt->equal(fraction_st2, this->astCtxt->bv(0, 63));
6342 auto fa0_st3 = this->astCtxt->equal(fraction_st3, this->astCtxt->bv(0, 63));
6343 auto fa0_st4 = this->astCtxt->equal(fraction_st4, this->astCtxt->bv(0, 63));
6344 auto fa0_st5 = this->astCtxt->equal(fraction_st5, this->astCtxt->bv(0, 63));
6345 auto fa0_st6 = this->astCtxt->equal(fraction_st6, this->astCtxt->bv(0, 63));
6346 auto fa0_st7 = this->astCtxt->equal(fraction_st7, this->astCtxt->bv(0, 63));
6347
6348 /* Determine the x87 FPU Tag Word (Diagram at page 379 of the AMD Architecture Programmer's Manual, Volume 2: System Programming) */
6349 auto db_1_0 = this->astCtxt->ite(this->astCtxt->equal(eb_1_0, this->astCtxt->bv(0, 1)),
6350 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
6351 this->astCtxt->ite(ea0_st0,
6352 this->astCtxt->ite(ib0_st0,
6353 this->astCtxt->ite(fa0_st0,
6354 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
6355 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
6356 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
6357 this->astCtxt->ite(ena01_st0,
6358 this->astCtxt->ite(ib0_st0,
6359 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
6360 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
6361 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
6362
6363 auto db_3_2 = this->astCtxt->ite(this->astCtxt->equal(eb_3_2, this->astCtxt->bv(0, 1)),
6364 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
6365 this->astCtxt->ite(ea0_st1,
6366 this->astCtxt->ite(ib0_st1,
6367 this->astCtxt->ite(fa0_st1,
6368 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
6369 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
6370 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
6371 this->astCtxt->ite(ena01_st1,
6372 this->astCtxt->ite(ib0_st1,
6373 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
6374 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
6375 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
6376
6377 auto db_5_4 = this->astCtxt->ite(this->astCtxt->equal(eb_5_4, this->astCtxt->bv(0, 1)),
6378 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
6379 this->astCtxt->ite(ea0_st2,
6380 this->astCtxt->ite(ib0_st2,
6381 this->astCtxt->ite(fa0_st2,
6382 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
6383 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
6384 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
6385 this->astCtxt->ite(ena01_st2,
6386 this->astCtxt->ite(ib0_st2,
6387 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
6388 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
6389 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
6390
6391 auto db_7_6 = this->astCtxt->ite(this->astCtxt->equal(eb_7_6, this->astCtxt->bv(0, 1)),
6392 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
6393 this->astCtxt->ite(ea0_st3,
6394 this->astCtxt->ite(ib0_st3,
6395 this->astCtxt->ite(fa0_st3,
6396 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
6397 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
6398 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
6399 this->astCtxt->ite(ena01_st3,
6400 this->astCtxt->ite(ib0_st3,
6401 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
6402 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
6403 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
6404
6405 auto db_9_8 = this->astCtxt->ite(this->astCtxt->equal(eb_9_8, this->astCtxt->bv(0, 1)),
6406 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
6407 this->astCtxt->ite(ea0_st4,
6408 this->astCtxt->ite(ib0_st4,
6409 this->astCtxt->ite(fa0_st4,
6410 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
6411 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
6412 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
6413 this->astCtxt->ite(ena01_st4,
6414 this->astCtxt->ite(ib0_st4,
6415 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
6416 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
6417 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
6418
6419 auto db_11_10 = this->astCtxt->ite(this->astCtxt->equal(eb_11_10, this->astCtxt->bv(0, 1)),
6420 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
6421 this->astCtxt->ite(ea0_st5,
6422 this->astCtxt->ite(ib0_st5,
6423 this->astCtxt->ite(fa0_st5,
6424 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
6425 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
6426 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
6427 this->astCtxt->ite(ena01_st5,
6428 this->astCtxt->ite(ib0_st5,
6429 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
6430 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
6431 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
6432
6433 auto db_13_12 = this->astCtxt->ite(this->astCtxt->equal(eb_13_12, this->astCtxt->bv(0, 1)),
6434 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
6435 this->astCtxt->ite(ea0_st6,
6436 this->astCtxt->ite(ib0_st6,
6437 this->astCtxt->ite(fa0_st6,
6438 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
6439 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
6440 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
6441 this->astCtxt->ite(ena01_st6,
6442 this->astCtxt->ite(ib0_st6,
6443 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
6444 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
6445 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
6446
6447 auto db_15_14 = this->astCtxt->ite(this->astCtxt->equal(eb_15_14, this->astCtxt->bv(0, 1)),
6448 this->astCtxt->bv(3, 2), // Encoded x87 FPU Tag Bit = 0
6449 this->astCtxt->ite(ea0_st7,
6450 this->astCtxt->ite(ib0_st7,
6451 this->astCtxt->ite(fa0_st7,
6452 this->astCtxt->bv(1, 2), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction All 0'
6453 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 0' + 'Fraction Not All 0'
6454 this->astCtxt->bv(2, 2)), // 'Exponent All 0' + 'Integer Bit 1'
6455 this->astCtxt->ite(ena01_st7,
6456 this->astCtxt->ite(ib0_st7,
6457 this->astCtxt->bv(2, 2), // 'Exponent Not All 0/1' + 'Integer Bit 0'
6458 this->astCtxt->bv(0, 2)), // 'Exponent Not All 0/1' + 'Integer Bit 1'
6459 this->astCtxt->bv(2, 2)))); // 'Exponent All 1'
6460
6461 /* Restore the x87 FPU Tag Word */
6462 auto uftw_ast = this->astCtxt->concat(db_15_14,
6463 this->astCtxt->concat(db_13_12,
6464 this->astCtxt->concat(db_11_10,
6465 this->astCtxt->concat(db_9_8,
6466 this->astCtxt->concat(db_7_6,
6467 this->astCtxt->concat(db_5_4,
6468 this->astCtxt->concat(db_3_2, db_1_0)))))));
6469
6470 /* Craft the symbolic expressions */
6471 auto fcw_expr = this->symbolicEngine->createSymbolicExpression(inst, fcw_ast, fcw, "FXRSTOR64 FCW operation");
6472 auto fsw_expr = this->symbolicEngine->createSymbolicExpression(inst, fsw_ast, fsw, "FXRSTOR64 FSW operation");
6473 auto ftw_expr = this->symbolicEngine->createSymbolicExpression(inst, uftw_ast, ftw, "FXRSTOR64 Updated FTW operation");
6474 auto fop_expr = this->symbolicEngine->createSymbolicExpression(inst, fop_ast, fop, "FXRSTOR64 FOP operation");
6475 auto fip_expr = this->symbolicEngine->createSymbolicExpression(inst, fip_ast, fip, "FXRSTOR64 FIP operation");
6476 auto fcs_expr = this->symbolicEngine->createSymbolicExpression(inst, fcs_ast, fcs, "FXRSTOR64 FCS operation");
6477 auto fdp_expr = this->symbolicEngine->createSymbolicExpression(inst, fdp_ast, fdp, "FXRSTOR64 FDP operation");
6478 auto fds_expr = this->symbolicEngine->createSymbolicExpression(inst, fds_ast, fds, "FXRSTOR64 FDS operation");
6479 auto mxcsr_expr = this->symbolicEngine->createSymbolicExpression(inst, mxcsr_ast, mxcsr, "FXRSTOR64 MXCSR operation");
6480 auto mxcsr_mask_expr = this->symbolicEngine->createSymbolicExpression(inst, mxcsr_mask_ast, mxcsr_mask, "FXRSTOR64 MXCSR_MASK operation");
6481 auto st0_expr = this->symbolicEngine->createSymbolicExpression(inst, st0_ast, st0, "FXRSTOR64 ST0 operation");
6482 auto st1_expr = this->symbolicEngine->createSymbolicExpression(inst, st1_ast, st1, "FXRSTOR64 ST1 operation");
6483 auto st2_expr = this->symbolicEngine->createSymbolicExpression(inst, st2_ast, st2, "FXRSTOR64 ST2 operation");
6484 auto st3_expr = this->symbolicEngine->createSymbolicExpression(inst, st3_ast, st3, "FXRSTOR64 ST3 operation");
6485 auto st4_expr = this->symbolicEngine->createSymbolicExpression(inst, st4_ast, st4, "FXRSTOR64 ST4 operation");
6486 auto st5_expr = this->symbolicEngine->createSymbolicExpression(inst, st5_ast, st5, "FXRSTOR64 ST5 operation");
6487 auto st6_expr = this->symbolicEngine->createSymbolicExpression(inst, st6_ast, st6, "FXRSTOR64 ST6 operation");
6488 auto st7_expr = this->symbolicEngine->createSymbolicExpression(inst, st7_ast, st7, "FXRSTOR64 ST7 operation");
6489 auto xmm0_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm0_ast, xmm0, "FXRSTOR64 XMM0 operation");
6490 auto xmm1_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm1_ast, xmm1, "FXRSTOR64 XMM1 operation");
6491 auto xmm2_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm2_ast, xmm2, "FXRSTOR64 XMM2 operation");
6492 auto xmm3_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm3_ast, xmm3, "FXRSTOR64 XMM3 operation");
6493 auto xmm4_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm4_ast, xmm4, "FXRSTOR64 XMM4 operation");
6494 auto xmm5_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm5_ast, xmm5, "FXRSTOR64 XMM5 operation");
6495 auto xmm6_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm6_ast, xmm6, "FXRSTOR64 XMM6 operation");
6496 auto xmm7_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm7_ast, xmm7, "FXRSTOR64 XMM7 operation");
6497 auto xmm8_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm8_ast, xmm8, "FXRSTOR64 XMM8 operation");
6498 auto xmm9_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm9_ast, xmm9, "FXRSTOR64 XMM9 operation");
6499 auto xmm10_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm10_ast, xmm10, "FXRSTOR64 XMM10 operation");
6500 auto xmm11_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm11_ast, xmm11, "FXRSTOR64 XMM11 operation");
6501 auto xmm12_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm12_ast, xmm12, "FXRSTOR64 XMM12 operation");
6502 auto xmm13_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm13_ast, xmm13, "FXRSTOR64 XMM13 operation");
6503 auto xmm14_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm14_ast, xmm14, "FXRSTOR64 XMM14 operation");
6504 auto xmm15_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm15_ast, xmm15, "FXRSTOR64 XMM15 operation");
6505
6506 /* Spread the taint */
6507 fcw_expr->isTainted = this->taintEngine->taintAssignment(fcw, fcw_addr);
6508 fsw_expr->isTainted = this->taintEngine->taintAssignment(fsw, fsw_addr);
6509 ftw_expr->isTainted = this->taintEngine->taintAssignment(ftw, ftw_addr);
6510 fop_expr->isTainted = this->taintEngine->taintAssignment(fop, fop_addr);
6511 fip_expr->isTainted = this->taintEngine->taintAssignment(fip, fip_addr);
6512 fcs_expr->isTainted = this->taintEngine->taintAssignment(fcs, fcs_addr);
6513 fdp_expr->isTainted = this->taintEngine->taintAssignment(fdp, fdp_addr);
6514 fds_expr->isTainted = this->taintEngine->taintAssignment(fds, fds_addr);
6515 mxcsr_expr->isTainted = this->taintEngine->taintAssignment(mxcsr, mxcsr_addr);
6516 mxcsr_mask_expr->isTainted = this->taintEngine->taintAssignment(mxcsr_mask, mxcsr_mask_addr);
6517 st0_expr->isTainted = this->taintEngine->taintAssignment(st0, st0_addr);
6518 st1_expr->isTainted = this->taintEngine->taintAssignment(st1, st1_addr);
6519 st2_expr->isTainted = this->taintEngine->taintAssignment(st2, st2_addr);
6520 st3_expr->isTainted = this->taintEngine->taintAssignment(st3, st3_addr);
6521 st4_expr->isTainted = this->taintEngine->taintAssignment(st4, st4_addr);
6522 st5_expr->isTainted = this->taintEngine->taintAssignment(st5, st5_addr);
6523 st6_expr->isTainted = this->taintEngine->taintAssignment(st6, st6_addr);
6524 st7_expr->isTainted = this->taintEngine->taintAssignment(st7, st7_addr);
6525 xmm0_expr->isTainted = this->taintEngine->taintAssignment(xmm0, xmm0_addr);
6526 xmm1_expr->isTainted = this->taintEngine->taintAssignment(xmm1, xmm1_addr);
6527 xmm2_expr->isTainted = this->taintEngine->taintAssignment(xmm2, xmm2_addr);
6528 xmm3_expr->isTainted = this->taintEngine->taintAssignment(xmm3, xmm3_addr);
6529 xmm4_expr->isTainted = this->taintEngine->taintAssignment(xmm4, xmm4_addr);
6530 xmm5_expr->isTainted = this->taintEngine->taintAssignment(xmm5, xmm5_addr);
6531 xmm6_expr->isTainted = this->taintEngine->taintAssignment(xmm6, xmm6_addr);
6532 xmm7_expr->isTainted = this->taintEngine->taintAssignment(xmm7, xmm7_addr);
6533 xmm8_expr->isTainted = this->taintEngine->taintAssignment(xmm8, xmm8_addr);
6534 xmm9_expr->isTainted = this->taintEngine->taintAssignment(xmm9, xmm9_addr);
6535 xmm10_expr->isTainted = this->taintEngine->taintAssignment(xmm10, xmm10_addr);
6536 xmm11_expr->isTainted = this->taintEngine->taintAssignment(xmm11, xmm11_addr);
6537 xmm12_expr->isTainted = this->taintEngine->taintAssignment(xmm12, xmm12_addr);
6538 xmm13_expr->isTainted = this->taintEngine->taintAssignment(xmm13, xmm13_addr);
6539 xmm14_expr->isTainted = this->taintEngine->taintAssignment(xmm14, xmm14_addr);
6540 xmm15_expr->isTainted = this->taintEngine->taintAssignment(xmm15, xmm15_addr);
6541
6542 /* Update the symbolic control flow */
6543 this->controlFlow_s(inst);
6544 }
6545
6546
6547 void x86Semantics::fxsave_s(triton::arch::Instruction& inst) {
6548 /* Fetch the current architecture */
6549 auto arch = this->architecture->getArchitecture();
6550
6551 /* Determine if we are executing in 64 bit mode */
6552 auto is64bits = arch == triton::arch::architecture_e::ARCH_X86_64;
6553
6554 /* Fetch the memory operand */
6555 auto& dst = inst.operands[0];
6556 auto& mem = dst.getMemory();
6557 auto m512byte = mem.getAddress();
6558
6559 /* Check if the address is on a 16-byte boundary */
6560 if (m512byte & 0xF) {
6561 this->exception = triton::arch::FAULT_GP;
6562 return;
6563 }
6564
6565 /* Fetch the FPU, STX, SSE, EFER and CS implicit operands */
6566 auto fcw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FCW));
6567 auto fsw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FSW));
6568 auto ftw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FTW));
6569 auto fop = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FOP));
6570 auto fip = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FIP));
6571 auto fcs = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FCS));
6572 auto fdp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FDP));
6573 auto fds = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FDS));
6574 auto mxcsr = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR));
6575 auto mxcsr_mask = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR_MASK));
6576 auto st0 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST0));
6577 auto st1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST1));
6578 auto st2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST2));
6579 auto st3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST3));
6580 auto st4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST4));
6581 auto st5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST5));
6582 auto st6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST6));
6583 auto st7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST7));
6584 auto xmm0 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM0));
6585 auto xmm1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM1));
6586 auto xmm2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM2));
6587 auto xmm3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM3));
6588 auto xmm4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM4));
6589 auto xmm5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM5));
6590 auto xmm6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM6));
6591 auto xmm7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM7));
6592 auto ffxsr = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EFER_FFXSR));
6593 auto cs = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CS));
6594
6595 /* Create the symbolic operands */
6596 auto fcw_ast = this->symbolicEngine->getOperandAst(inst, fcw);
6597 auto fsw_ast = this->symbolicEngine->getOperandAst(inst, fsw);
6598 auto ftw_ast = this->symbolicEngine->getOperandAst(inst, ftw);
6599 auto fop_ast = this->symbolicEngine->getOperandAst(inst, fop);
6600 auto fip_ast = this->astCtxt->extract(triton::bitsize::dword - 1, 0, this->symbolicEngine->getOperandAst(inst, fip));
6601 auto fcs_ast = this->symbolicEngine->getOperandAst(inst, fcs);
6602 auto fdp_ast = this->astCtxt->extract(triton::bitsize::dword - 1, 0, this->symbolicEngine->getOperandAst(inst, fdp));
6603 auto fds_ast = this->symbolicEngine->getOperandAst(inst, fds);
6604 auto mxcsr_ast = this->symbolicEngine->getOperandAst(inst, mxcsr);
6605 auto mxcsr_mask_ast = this->symbolicEngine->getOperandAst(inst, mxcsr_mask);
6606 auto st0_ast = this->symbolicEngine->getOperandAst(inst, st0);
6607 auto st1_ast = this->symbolicEngine->getOperandAst(inst, st1);
6608 auto st2_ast = this->symbolicEngine->getOperandAst(inst, st2);
6609 auto st3_ast = this->symbolicEngine->getOperandAst(inst, st3);
6610 auto st4_ast = this->symbolicEngine->getOperandAst(inst, st4);
6611 auto st5_ast = this->symbolicEngine->getOperandAst(inst, st5);
6612 auto st6_ast = this->symbolicEngine->getOperandAst(inst, st6);
6613 auto st7_ast = this->symbolicEngine->getOperandAst(inst, st7);
6614 auto xmm0_ast = this->symbolicEngine->getOperandAst(inst, xmm0);
6615 auto xmm1_ast = this->symbolicEngine->getOperandAst(inst, xmm1);
6616 auto xmm2_ast = this->symbolicEngine->getOperandAst(inst, xmm2);
6617 auto xmm3_ast = this->symbolicEngine->getOperandAst(inst, xmm3);
6618 auto xmm4_ast = this->symbolicEngine->getOperandAst(inst, xmm4);
6619 auto xmm5_ast = this->symbolicEngine->getOperandAst(inst, xmm5);
6620 auto xmm6_ast = this->symbolicEngine->getOperandAst(inst, xmm6);
6621 auto xmm7_ast = this->symbolicEngine->getOperandAst(inst, xmm7);
6622 auto ffxsr_ast = this->symbolicEngine->getOperandAst(inst, ffxsr);
6623 auto cs_ast = this->symbolicEngine->getOperandAst(inst, cs);
6624
6625 /*
6626 Calculate the abridged x87 FPU Tag Word (from 2 bytes to 1 byte encoding)
6627 - Two-bit values of 00, 01, and 10 are encoded as a 1
6628 - A two-bit value of 11 is encoded as a 0
6629 */
6630 auto eb_1_0 = this->astCtxt->ite(
6631 this->astCtxt->equal(this->astCtxt->extract(1, 0, ftw_ast), this->astCtxt->bv(3, 2)),
6632 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6633
6634 auto eb_3_2 = this->astCtxt->ite(
6635 this->astCtxt->equal(this->astCtxt->extract(3, 2, ftw_ast), this->astCtxt->bv(3, 2)),
6636 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6637
6638 auto eb_5_4 = this->astCtxt->ite(
6639 this->astCtxt->equal(this->astCtxt->extract(5, 4, ftw_ast), this->astCtxt->bv(3, 2)),
6640 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6641
6642 auto eb_7_6 = this->astCtxt->ite(
6643 this->astCtxt->equal(this->astCtxt->extract(7, 6, ftw_ast), this->astCtxt->bv(3, 2)),
6644 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6645
6646 auto eb_9_8 = this->astCtxt->ite(
6647 this->astCtxt->equal(this->astCtxt->extract(9, 8, ftw_ast), this->astCtxt->bv(3, 2)),
6648 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6649
6650 auto eb_11_10 = this->astCtxt->ite(
6651 this->astCtxt->equal(this->astCtxt->extract(11, 10, ftw_ast), this->astCtxt->bv(3, 2)),
6652 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6653
6654 auto eb_13_12 = this->astCtxt->ite(
6655 this->astCtxt->equal(this->astCtxt->extract(13, 12, ftw_ast), this->astCtxt->bv(3, 2)),
6656 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6657
6658 auto eb_15_14 = this->astCtxt->ite(
6659 this->astCtxt->equal(this->astCtxt->extract(15, 14, ftw_ast), this->astCtxt->bv(3, 2)),
6660 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6661
6662 auto aftw_ast = this->astCtxt->concat(eb_15_14,
6663 this->astCtxt->concat(eb_13_12,
6664 this->astCtxt->concat(eb_11_10,
6665 this->astCtxt->concat(eb_9_8,
6666 this->astCtxt->concat(eb_7_6,
6667 this->astCtxt->concat(eb_5_4,
6668 this->astCtxt->concat(eb_3_2, eb_1_0)))))));
6669
6670 /* Fetch the implicit memory slots for the 'Non-64-bit Mode Layout' */
6671 auto fcw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 0, fcw.getSize()));
6672 auto fsw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 2, fsw.getSize()));
6673 auto ftw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 4, ftw.getSize() / 2));
6674 auto fop_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 6, fop.getSize()));
6675 auto fip_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 8, fip.getSize() / 2));
6676 auto fcs_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 12, fcs.getSize()));
6677 auto fdp_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 16, fdp.getSize() / 2));
6678 auto fds_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 20, fds.getSize()));
6679 auto mxcsr_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 24, mxcsr.getSize()));
6680 auto mxcsr_mask_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 28, mxcsr_mask.getSize()));
6681 auto st0_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 32, st0.getSize()));
6682 auto st1_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 48, st1.getSize()));
6683 auto st2_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 64, st2.getSize()));
6684 auto st3_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 80, st3.getSize()));
6685 auto st4_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 96, st4.getSize()));
6686 auto st5_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 112, st5.getSize()));
6687 auto st6_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 128, st6.getSize()));
6688 auto st7_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 144, st7.getSize()));
6689 auto xmm0_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 160, xmm0.getSize()));
6690 auto xmm1_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 176, xmm1.getSize()));
6691 auto xmm2_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 192, xmm2.getSize()));
6692 auto xmm3_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 208, xmm3.getSize()));
6693 auto xmm4_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 224, xmm4.getSize()));
6694 auto xmm5_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 240, xmm5.getSize()));
6695 auto xmm6_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 256, xmm6.getSize()));
6696 auto xmm7_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 272, xmm7.getSize()));
6697
6698 /* Fetch the original values of the XMM0-XMM7 memory spaces */
6699 auto xmm0_orig = this->symbolicEngine->getOperandAst(xmm0_addr);
6700 auto xmm1_orig = this->symbolicEngine->getOperandAst(xmm1_addr);
6701 auto xmm2_orig = this->symbolicEngine->getOperandAst(xmm2_addr);
6702 auto xmm3_orig = this->symbolicEngine->getOperandAst(xmm3_addr);
6703 auto xmm4_orig = this->symbolicEngine->getOperandAst(xmm4_addr);
6704 auto xmm5_orig = this->symbolicEngine->getOperandAst(xmm5_addr);
6705 auto xmm6_orig = this->symbolicEngine->getOperandAst(xmm6_addr);
6706 auto xmm7_orig = this->symbolicEngine->getOperandAst(xmm7_addr);
6707
6708 /* Check if we are running in CPL = 0 (ring 0) and if the FFXSR bit is set in EFER */
6709 auto cpl = this->astCtxt->equal(this->astCtxt->extract(1, 0, cs_ast), this->astCtxt->bv(0, 2));
6710 auto ffx = this->astCtxt->equal(ffxsr_ast, this->astCtxt->bv(1, 1));
6711 auto b64 = this->astCtxt->equal(this->astCtxt->bv(is64bits, 1), this->astCtxt->bv(1, 1));
6712 auto is_fast = this->astCtxt->land(this->astCtxt->land(cpl, ffx), b64);
6713
6714 /* Apply the fast save logic if needed */
6715 xmm0_ast = this->astCtxt->ite(is_fast, xmm0_orig, xmm0_ast);
6716 xmm1_ast = this->astCtxt->ite(is_fast, xmm1_orig, xmm1_ast);
6717 xmm2_ast = this->astCtxt->ite(is_fast, xmm2_orig, xmm2_ast);
6718 xmm3_ast = this->astCtxt->ite(is_fast, xmm3_orig, xmm3_ast);
6719 xmm4_ast = this->astCtxt->ite(is_fast, xmm4_orig, xmm4_ast);
6720 xmm5_ast = this->astCtxt->ite(is_fast, xmm5_orig, xmm5_ast);
6721 xmm6_ast = this->astCtxt->ite(is_fast, xmm6_orig, xmm6_ast);
6722 xmm7_ast = this->astCtxt->ite(is_fast, xmm7_orig, xmm7_ast);
6723
6724 /* Craft the symbolic expressions */
6725 auto fcw_expr = this->symbolicEngine->createSymbolicExpression(inst, fcw_ast, fcw_addr, "FXSAVE FCW operation");
6726 auto fsw_expr = this->symbolicEngine->createSymbolicExpression(inst, fsw_ast, fsw_addr, "FXSAVE FSW operation");
6727 auto ftw_expr = this->symbolicEngine->createSymbolicExpression(inst, aftw_ast, ftw_addr, "FXSAVE Abridged FTW operation");
6728 auto fop_expr = this->symbolicEngine->createSymbolicExpression(inst, fop_ast, fop_addr, "FXSAVE FOP operation");
6729 auto fip_expr = this->symbolicEngine->createSymbolicExpression(inst, fip_ast, fip_addr, "FXSAVE FIP operation");
6730 auto fcs_expr = this->symbolicEngine->createSymbolicExpression(inst, fcs_ast, fcs_addr, "FXSAVE FCS operation");
6731 auto fdp_expr = this->symbolicEngine->createSymbolicExpression(inst, fdp_ast, fdp_addr, "FXSAVE FDP operation");
6732 auto fds_expr = this->symbolicEngine->createSymbolicExpression(inst, fds_ast, fds_addr, "FXSAVE FDS operation");
6733 auto mxcsr_expr = this->symbolicEngine->createSymbolicExpression(inst, mxcsr_ast, mxcsr_addr, "FXSAVE MXCSR operation");
6734 auto mxcsr_mask_expr = this->symbolicEngine->createSymbolicExpression(inst, mxcsr_mask_ast, mxcsr_mask_addr, "FXSAVE MXCSR_MASK operation");
6735 auto st0_expr = this->symbolicEngine->createSymbolicExpression(inst, st0_ast, st0_addr, "FXSAVE ST0 operation");
6736 auto st1_expr = this->symbolicEngine->createSymbolicExpression(inst, st1_ast, st1_addr, "FXSAVE ST1 operation");
6737 auto st2_expr = this->symbolicEngine->createSymbolicExpression(inst, st2_ast, st2_addr, "FXSAVE ST2 operation");
6738 auto st3_expr = this->symbolicEngine->createSymbolicExpression(inst, st3_ast, st3_addr, "FXSAVE ST3 operation");
6739 auto st4_expr = this->symbolicEngine->createSymbolicExpression(inst, st4_ast, st4_addr, "FXSAVE ST4 operation");
6740 auto st5_expr = this->symbolicEngine->createSymbolicExpression(inst, st5_ast, st5_addr, "FXSAVE ST5 operation");
6741 auto st6_expr = this->symbolicEngine->createSymbolicExpression(inst, st6_ast, st6_addr, "FXSAVE ST6 operation");
6742 auto st7_expr = this->symbolicEngine->createSymbolicExpression(inst, st7_ast, st7_addr, "FXSAVE ST7 operation");
6743 auto xmm0_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm0_ast, xmm0_addr, "FXSAVE XMM0 operation");
6744 auto xmm1_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm1_ast, xmm1_addr, "FXSAVE XMM1 operation");
6745 auto xmm2_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm2_ast, xmm2_addr, "FXSAVE XMM2 operation");
6746 auto xmm3_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm3_ast, xmm3_addr, "FXSAVE XMM3 operation");
6747 auto xmm4_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm4_ast, xmm4_addr, "FXSAVE XMM4 operation");
6748 auto xmm5_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm5_ast, xmm5_addr, "FXSAVE XMM5 operation");
6749 auto xmm6_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm6_ast, xmm6_addr, "FXSAVE XMM6 operation");
6750 auto xmm7_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm7_ast, xmm7_addr, "FXSAVE XMM7 operation");
6751
6752 /* Spread the taint */
6753 fcw_expr->isTainted = this->taintEngine->taintAssignment(fcw_addr, fcw);
6754 fsw_expr->isTainted = this->taintEngine->taintAssignment(fsw_addr, fsw);
6755 ftw_expr->isTainted = this->taintEngine->taintAssignment(ftw_addr, ftw);
6756 fop_expr->isTainted = this->taintEngine->taintAssignment(fop_addr, fop);
6757 fip_expr->isTainted = this->taintEngine->taintAssignment(fip_addr, fip);
6758 fcs_expr->isTainted = this->taintEngine->taintAssignment(fcs_addr, fcs);
6759 fdp_expr->isTainted = this->taintEngine->taintAssignment(fdp_addr, fdp);
6760 fds_expr->isTainted = this->taintEngine->taintAssignment(fds_addr, fds);
6761 mxcsr_expr->isTainted = this->taintEngine->taintAssignment(mxcsr_addr, mxcsr);
6762 mxcsr_mask_expr->isTainted = this->taintEngine->taintAssignment(mxcsr_mask_addr, mxcsr_mask);
6763 st0_expr->isTainted = this->taintEngine->taintAssignment(st0_addr, st0);
6764 st1_expr->isTainted = this->taintEngine->taintAssignment(st1_addr, st1);
6765 st2_expr->isTainted = this->taintEngine->taintAssignment(st2_addr, st2);
6766 st3_expr->isTainted = this->taintEngine->taintAssignment(st3_addr, st3);
6767 st4_expr->isTainted = this->taintEngine->taintAssignment(st4_addr, st4);
6768 st5_expr->isTainted = this->taintEngine->taintAssignment(st5_addr, st5);
6769 st6_expr->isTainted = this->taintEngine->taintAssignment(st6_addr, st6);
6770 st7_expr->isTainted = this->taintEngine->taintAssignment(st7_addr, st7);
6771 xmm0_expr->isTainted = this->taintEngine->taintAssignment(xmm0_addr, xmm0);
6772 xmm1_expr->isTainted = this->taintEngine->taintAssignment(xmm1_addr, xmm1);
6773 xmm2_expr->isTainted = this->taintEngine->taintAssignment(xmm2_addr, xmm2);
6774 xmm3_expr->isTainted = this->taintEngine->taintAssignment(xmm3_addr, xmm3);
6775 xmm4_expr->isTainted = this->taintEngine->taintAssignment(xmm4_addr, xmm4);
6776 xmm5_expr->isTainted = this->taintEngine->taintAssignment(xmm5_addr, xmm5);
6777 xmm6_expr->isTainted = this->taintEngine->taintAssignment(xmm6_addr, xmm6);
6778 xmm7_expr->isTainted = this->taintEngine->taintAssignment(xmm7_addr, xmm7);
6779
6780 /* Additional semantics, symbolic expressions and tainting for the '64-bit Mode Layout (with REX.W = 0)' */
6781 if (is64bits) {
6782 auto xmm8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM8));
6783 auto xmm9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM9));
6784 auto xmm10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM10));
6785 auto xmm11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM11));
6786 auto xmm12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM12));
6787 auto xmm13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM13));
6788 auto xmm14 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM14));
6789 auto xmm15 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM15));
6790
6791 auto xmm8_ast = this->symbolicEngine->getOperandAst(inst, xmm8);
6792 auto xmm9_ast = this->symbolicEngine->getOperandAst(inst, xmm9);
6793 auto xmm10_ast = this->symbolicEngine->getOperandAst(inst, xmm10);
6794 auto xmm11_ast = this->symbolicEngine->getOperandAst(inst, xmm11);
6795 auto xmm12_ast = this->symbolicEngine->getOperandAst(inst, xmm12);
6796 auto xmm13_ast = this->symbolicEngine->getOperandAst(inst, xmm13);
6797 auto xmm14_ast = this->symbolicEngine->getOperandAst(inst, xmm14);
6798 auto xmm15_ast = this->symbolicEngine->getOperandAst(inst, xmm15);
6799
6800 auto xmm8_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 288, xmm8.getSize()));
6801 auto xmm9_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 304, xmm9.getSize()));
6802 auto xmm10_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 320, xmm10.getSize()));
6803 auto xmm11_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 336, xmm11.getSize()));
6804 auto xmm12_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 352, xmm12.getSize()));
6805 auto xmm13_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 368, xmm13.getSize()));
6806 auto xmm14_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 384, xmm14.getSize()));
6807 auto xmm15_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 400, xmm15.getSize()));
6808
6809 /* Fetch the original values of the XMM8-XMM15 memory spaces */
6810 auto xmm8_orig = this->symbolicEngine->getOperandAst(xmm8_addr);
6811 auto xmm9_orig = this->symbolicEngine->getOperandAst(xmm9_addr);
6812 auto xmm10_orig = this->symbolicEngine->getOperandAst(xmm10_addr);
6813 auto xmm11_orig = this->symbolicEngine->getOperandAst(xmm11_addr);
6814 auto xmm12_orig = this->symbolicEngine->getOperandAst(xmm12_addr);
6815 auto xmm13_orig = this->symbolicEngine->getOperandAst(xmm13_addr);
6816 auto xmm14_orig = this->symbolicEngine->getOperandAst(xmm14_addr);
6817 auto xmm15_orig = this->symbolicEngine->getOperandAst(xmm15_addr);
6818
6819 /* Check if we are running in CPL = 0 (ring 0) and if the FFXSR bit is set in EFER */
6820 auto cpl = this->astCtxt->equal(this->astCtxt->extract(1, 0, cs_ast), this->astCtxt->bv(0, 2));
6821 auto ffx = this->astCtxt->equal(ffxsr_ast, this->astCtxt->bv(1, 1));
6822 auto is_fast = this->astCtxt->land(cpl, ffx);
6823
6824 /* Apply the fast save logic if needed */
6825 xmm8_ast = this->astCtxt->ite(is_fast, xmm8_orig, xmm8_ast);
6826 xmm9_ast = this->astCtxt->ite(is_fast, xmm9_orig, xmm9_ast);
6827 xmm10_ast = this->astCtxt->ite(is_fast, xmm10_orig, xmm10_ast);
6828 xmm11_ast = this->astCtxt->ite(is_fast, xmm11_orig, xmm11_ast);
6829 xmm12_ast = this->astCtxt->ite(is_fast, xmm12_orig, xmm12_ast);
6830 xmm13_ast = this->astCtxt->ite(is_fast, xmm13_orig, xmm13_ast);
6831 xmm14_ast = this->astCtxt->ite(is_fast, xmm14_orig, xmm14_ast);
6832 xmm15_ast = this->astCtxt->ite(is_fast, xmm15_orig, xmm15_ast);
6833
6834 auto xmm8_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm8_ast, xmm8_addr, "FXSAVE XMM8 operation");
6835 auto xmm9_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm9_ast, xmm9_addr, "FXSAVE XMM9 operation");
6836 auto xmm10_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm10_ast, xmm10_addr, "FXSAVE XMM10 operation");
6837 auto xmm11_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm11_ast, xmm11_addr, "FXSAVE XMM11 operation");
6838 auto xmm12_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm12_ast, xmm12_addr, "FXSAVE XMM12 operation");
6839 auto xmm13_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm13_ast, xmm13_addr, "FXSAVE XMM13 operation");
6840 auto xmm14_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm14_ast, xmm14_addr, "FXSAVE XMM14 operation");
6841 auto xmm15_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm15_ast, xmm15_addr, "FXSAVE XMM15 operation");
6842
6843 xmm8_expr->isTainted = this->taintEngine->taintAssignment(xmm8_addr, xmm8);
6844 xmm9_expr->isTainted = this->taintEngine->taintAssignment(xmm9_addr, xmm9);
6845 xmm10_expr->isTainted = this->taintEngine->taintAssignment(xmm10_addr, xmm10);
6846 xmm11_expr->isTainted = this->taintEngine->taintAssignment(xmm11_addr, xmm11);
6847 xmm12_expr->isTainted = this->taintEngine->taintAssignment(xmm12_addr, xmm12);
6848 xmm13_expr->isTainted = this->taintEngine->taintAssignment(xmm13_addr, xmm13);
6849 xmm14_expr->isTainted = this->taintEngine->taintAssignment(xmm14_addr, xmm14);
6850 xmm15_expr->isTainted = this->taintEngine->taintAssignment(xmm15_addr, xmm15);
6851 }
6852
6853 /* Update the symbolic control flow */
6854 this->controlFlow_s(inst);
6855 }
6856
6857
6858 void x86Semantics::fxsave64_s(triton::arch::Instruction& inst) {
6859 /* Fetch the memory operand */
6860 auto& dst = inst.operands[0];
6861 auto& mem = dst.getMemory();
6862 auto m512byte = mem.getAddress();
6863
6864 /* Check if the address is on a 16-byte boundary */
6865 if (m512byte & 0xF) {
6866 this->exception = triton::arch::FAULT_GP;
6867 return;
6868 }
6869
6870 /* Fetch the FPU, STX, SSE, EFER and CS implicit operands */
6871 auto fcw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FCW));
6872 auto fsw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FSW));
6873 auto ftw = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FTW));
6874 auto fop = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FOP));
6875 auto fip = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FIP));
6876 auto fcs = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FCS));
6877 auto fdp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FDP));
6878 auto fds = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_FDS));
6879 auto mxcsr = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR));
6880 auto mxcsr_mask = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR_MASK));
6881 auto st0 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST0));
6882 auto st1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST1));
6883 auto st2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST2));
6884 auto st3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST3));
6885 auto st4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST4));
6886 auto st5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST5));
6887 auto st6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST6));
6888 auto st7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ST7));
6889 auto xmm0 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM0));
6890 auto xmm1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM1));
6891 auto xmm2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM2));
6892 auto xmm3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM3));
6893 auto xmm4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM4));
6894 auto xmm5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM5));
6895 auto xmm6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM6));
6896 auto xmm7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM7));
6897 auto xmm8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM8));
6898 auto xmm9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM9));
6899 auto xmm10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM10));
6900 auto xmm11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM11));
6901 auto xmm12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM12));
6902 auto xmm13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM13));
6903 auto xmm14 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM14));
6904 auto xmm15 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_XMM15));
6905 auto ffxsr = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EFER_FFXSR));
6906 auto cs = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CS));
6907
6908 /* Create the symbolic operands */
6909 auto fcw_ast = this->symbolicEngine->getOperandAst(inst, fcw);
6910 auto fsw_ast = this->symbolicEngine->getOperandAst(inst, fsw);
6911 auto ftw_ast = this->symbolicEngine->getOperandAst(inst, ftw);
6912 auto fop_ast = this->symbolicEngine->getOperandAst(inst, fop);
6913 auto fip_ast = this->symbolicEngine->getOperandAst(inst, fip);
6914 auto fcs_ast = this->symbolicEngine->getOperandAst(inst, fcs);
6915 auto fdp_ast = this->symbolicEngine->getOperandAst(inst, fdp);
6916 auto fds_ast = this->symbolicEngine->getOperandAst(inst, fds);
6917 auto mxcsr_ast = this->symbolicEngine->getOperandAst(inst, mxcsr);
6918 auto mxcsr_mask_ast = this->symbolicEngine->getOperandAst(inst, mxcsr_mask);
6919 auto st0_ast = this->symbolicEngine->getOperandAst(inst, st0);
6920 auto st1_ast = this->symbolicEngine->getOperandAst(inst, st1);
6921 auto st2_ast = this->symbolicEngine->getOperandAst(inst, st2);
6922 auto st3_ast = this->symbolicEngine->getOperandAst(inst, st3);
6923 auto st4_ast = this->symbolicEngine->getOperandAst(inst, st4);
6924 auto st5_ast = this->symbolicEngine->getOperandAst(inst, st5);
6925 auto st6_ast = this->symbolicEngine->getOperandAst(inst, st6);
6926 auto st7_ast = this->symbolicEngine->getOperandAst(inst, st7);
6927 auto xmm0_ast = this->symbolicEngine->getOperandAst(inst, xmm0);
6928 auto xmm1_ast = this->symbolicEngine->getOperandAst(inst, xmm1);
6929 auto xmm2_ast = this->symbolicEngine->getOperandAst(inst, xmm2);
6930 auto xmm3_ast = this->symbolicEngine->getOperandAst(inst, xmm3);
6931 auto xmm4_ast = this->symbolicEngine->getOperandAst(inst, xmm4);
6932 auto xmm5_ast = this->symbolicEngine->getOperandAst(inst, xmm5);
6933 auto xmm6_ast = this->symbolicEngine->getOperandAst(inst, xmm6);
6934 auto xmm7_ast = this->symbolicEngine->getOperandAst(inst, xmm7);
6935 auto xmm8_ast = this->symbolicEngine->getOperandAst(inst, xmm8);
6936 auto xmm9_ast = this->symbolicEngine->getOperandAst(inst, xmm9);
6937 auto xmm10_ast = this->symbolicEngine->getOperandAst(inst, xmm10);
6938 auto xmm11_ast = this->symbolicEngine->getOperandAst(inst, xmm11);
6939 auto xmm12_ast = this->symbolicEngine->getOperandAst(inst, xmm12);
6940 auto xmm13_ast = this->symbolicEngine->getOperandAst(inst, xmm13);
6941 auto xmm14_ast = this->symbolicEngine->getOperandAst(inst, xmm14);
6942 auto xmm15_ast = this->symbolicEngine->getOperandAst(inst, xmm15);
6943 auto ffxsr_ast = this->symbolicEngine->getOperandAst(inst, ffxsr);
6944 auto cs_ast = this->symbolicEngine->getOperandAst(inst, cs);
6945
6946 /*
6947 Calculate the abridged x87 FPU Tag Word (from 2 bytes to 1 byte encoding)
6948 - Two-bit values of 00, 01, and 10 are encoded as a 1
6949 - A two-bit value of 11 is encoded as a 0
6950 */
6951 auto eb_1_0 = this->astCtxt->ite(
6952 this->astCtxt->equal(this->astCtxt->extract(1, 0, ftw_ast), this->astCtxt->bv(3, 2)),
6953 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6954
6955 auto eb_3_2 = this->astCtxt->ite(
6956 this->astCtxt->equal(this->astCtxt->extract(3, 2, ftw_ast), this->astCtxt->bv(3, 2)),
6957 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6958
6959 auto eb_5_4 = this->astCtxt->ite(
6960 this->astCtxt->equal(this->astCtxt->extract(5, 4, ftw_ast), this->astCtxt->bv(3, 2)),
6961 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6962
6963 auto eb_7_6 = this->astCtxt->ite(
6964 this->astCtxt->equal(this->astCtxt->extract(7, 6, ftw_ast), this->astCtxt->bv(3, 2)),
6965 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6966
6967 auto eb_9_8 = this->astCtxt->ite(
6968 this->astCtxt->equal(this->astCtxt->extract(9, 8, ftw_ast), this->astCtxt->bv(3, 2)),
6969 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6970
6971 auto eb_11_10 = this->astCtxt->ite(
6972 this->astCtxt->equal(this->astCtxt->extract(11, 10, ftw_ast), this->astCtxt->bv(3, 2)),
6973 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6974
6975 auto eb_13_12 = this->astCtxt->ite(
6976 this->astCtxt->equal(this->astCtxt->extract(13, 12, ftw_ast), this->astCtxt->bv(3, 2)),
6977 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6978
6979 auto eb_15_14 = this->astCtxt->ite(
6980 this->astCtxt->equal(this->astCtxt->extract(15, 14, ftw_ast), this->astCtxt->bv(3, 2)),
6981 this->astCtxt->bv(0, 1), this->astCtxt->bv(1, 1));
6982
6983 auto aftw_ast = this->astCtxt->concat(eb_15_14,
6984 this->astCtxt->concat(eb_13_12,
6985 this->astCtxt->concat(eb_11_10,
6986 this->astCtxt->concat(eb_9_8,
6987 this->astCtxt->concat(eb_7_6,
6988 this->astCtxt->concat(eb_5_4,
6989 this->astCtxt->concat(eb_3_2, eb_1_0)))))));
6990
6991 /* Fetch the implicit memory slots for the '64-bit Mode Layout (with REX.W = 1)' */
6992 auto fcw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 0, fcw.getSize()));
6993 auto fsw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 2, fsw.getSize()));
6994 auto ftw_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 4, ftw.getSize() / 2));
6995 auto fop_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 6, fop.getSize()));
6996 auto fip_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 8, fip.getSize()));
6997 auto fcs_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 12, fcs.getSize()));
6998 auto fdp_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 16, fdp.getSize()));
6999 auto fds_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 20, fds.getSize()));
7000 auto mxcsr_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 24, mxcsr.getSize()));
7001 auto mxcsr_mask_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 28, mxcsr_mask.getSize()));
7002 auto st0_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 32, st0.getSize()));
7003 auto st1_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 48, st1.getSize()));
7004 auto st2_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 64, st2.getSize()));
7005 auto st3_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 80, st3.getSize()));
7006 auto st4_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 96, st4.getSize()));
7007 auto st5_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 112, st5.getSize()));
7008 auto st6_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 128, st6.getSize()));
7009 auto st7_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 144, st7.getSize()));
7010 auto xmm0_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 160, xmm0.getSize()));
7011 auto xmm1_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 176, xmm1.getSize()));
7012 auto xmm2_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 192, xmm2.getSize()));
7013 auto xmm3_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 208, xmm3.getSize()));
7014 auto xmm4_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 224, xmm4.getSize()));
7015 auto xmm5_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 240, xmm5.getSize()));
7016 auto xmm6_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 256, xmm6.getSize()));
7017 auto xmm7_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 272, xmm7.getSize()));
7018 auto xmm8_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 288, xmm8.getSize()));
7019 auto xmm9_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 304, xmm9.getSize()));
7020 auto xmm10_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 320, xmm10.getSize()));
7021 auto xmm11_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 336, xmm11.getSize()));
7022 auto xmm12_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 352, xmm12.getSize()));
7023 auto xmm13_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 368, xmm13.getSize()));
7024 auto xmm14_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 384, xmm14.getSize()));
7025 auto xmm15_addr = triton::arch::OperandWrapper(triton::arch::MemoryAccess(m512byte + 400, xmm15.getSize()));
7026
7027 /* Fetch the original values of the XMM0-XMM7 memory spaces */
7028 auto xmm0_orig = this->symbolicEngine->getOperandAst(xmm0_addr);
7029 auto xmm1_orig = this->symbolicEngine->getOperandAst(xmm1_addr);
7030 auto xmm2_orig = this->symbolicEngine->getOperandAst(xmm2_addr);
7031 auto xmm3_orig = this->symbolicEngine->getOperandAst(xmm3_addr);
7032 auto xmm4_orig = this->symbolicEngine->getOperandAst(xmm4_addr);
7033 auto xmm5_orig = this->symbolicEngine->getOperandAst(xmm5_addr);
7034 auto xmm6_orig = this->symbolicEngine->getOperandAst(xmm6_addr);
7035 auto xmm7_orig = this->symbolicEngine->getOperandAst(xmm7_addr);
7036 auto xmm8_orig = this->symbolicEngine->getOperandAst(xmm8_addr);
7037 auto xmm9_orig = this->symbolicEngine->getOperandAst(xmm9_addr);
7038 auto xmm10_orig = this->symbolicEngine->getOperandAst(xmm10_addr);
7039 auto xmm11_orig = this->symbolicEngine->getOperandAst(xmm11_addr);
7040 auto xmm12_orig = this->symbolicEngine->getOperandAst(xmm12_addr);
7041 auto xmm13_orig = this->symbolicEngine->getOperandAst(xmm13_addr);
7042 auto xmm14_orig = this->symbolicEngine->getOperandAst(xmm14_addr);
7043 auto xmm15_orig = this->symbolicEngine->getOperandAst(xmm15_addr);
7044
7045 /* Check if we are running in CPL = 0 (ring 0) and if the FFXSR bit is set in EFER */
7046 auto cpl = this->astCtxt->equal(this->astCtxt->extract(1, 0, cs_ast), this->astCtxt->bv(0, 2));
7047 auto ffx = this->astCtxt->equal(ffxsr_ast, this->astCtxt->bv(1, 1));
7048 auto is_fast = this->astCtxt->land(cpl, ffx);
7049
7050 /* Apply the fast save logic if needed */
7051 xmm0_ast = this->astCtxt->ite(is_fast, xmm0_orig, xmm0_ast);
7052 xmm1_ast = this->astCtxt->ite(is_fast, xmm1_orig, xmm1_ast);
7053 xmm2_ast = this->astCtxt->ite(is_fast, xmm2_orig, xmm2_ast);
7054 xmm3_ast = this->astCtxt->ite(is_fast, xmm3_orig, xmm3_ast);
7055 xmm4_ast = this->astCtxt->ite(is_fast, xmm4_orig, xmm4_ast);
7056 xmm5_ast = this->astCtxt->ite(is_fast, xmm5_orig, xmm5_ast);
7057 xmm6_ast = this->astCtxt->ite(is_fast, xmm6_orig, xmm6_ast);
7058 xmm7_ast = this->astCtxt->ite(is_fast, xmm7_orig, xmm7_ast);
7059 xmm8_ast = this->astCtxt->ite(is_fast, xmm8_orig, xmm8_ast);
7060 xmm9_ast = this->astCtxt->ite(is_fast, xmm9_orig, xmm9_ast);
7061 xmm10_ast = this->astCtxt->ite(is_fast, xmm10_orig, xmm10_ast);
7062 xmm11_ast = this->astCtxt->ite(is_fast, xmm11_orig, xmm11_ast);
7063 xmm12_ast = this->astCtxt->ite(is_fast, xmm12_orig, xmm12_ast);
7064 xmm13_ast = this->astCtxt->ite(is_fast, xmm13_orig, xmm13_ast);
7065 xmm14_ast = this->astCtxt->ite(is_fast, xmm14_orig, xmm14_ast);
7066 xmm15_ast = this->astCtxt->ite(is_fast, xmm15_orig, xmm15_ast);
7067
7068 /* Craft the symbolic expressions */
7069 auto fcw_expr = this->symbolicEngine->createSymbolicExpression(inst, fcw_ast, fcw_addr, "FXSAVE64 FCW operation");
7070 auto fsw_expr = this->symbolicEngine->createSymbolicExpression(inst, fsw_ast, fsw_addr, "FXSAVE64 FSW operation");
7071 auto ftw_expr = this->symbolicEngine->createSymbolicExpression(inst, aftw_ast, ftw_addr, "FXSAVE64 Abridged FTW operation");
7072 auto fop_expr = this->symbolicEngine->createSymbolicExpression(inst, fop_ast, fop_addr, "FXSAVE64 FOP operation");
7073 auto fip_expr = this->symbolicEngine->createSymbolicExpression(inst, fip_ast, fip_addr, "FXSAVE64 FIP operation");
7074 auto fcs_expr = this->symbolicEngine->createSymbolicExpression(inst, fcs_ast, fcs_addr, "FXSAVE64 FCS operation");
7075 auto fdp_expr = this->symbolicEngine->createSymbolicExpression(inst, fdp_ast, fdp_addr, "FXSAVE64 FDP operation");
7076 auto fds_expr = this->symbolicEngine->createSymbolicExpression(inst, fds_ast, fds_addr, "FXSAVE64 FDS operation");
7077 auto mxcsr_expr = this->symbolicEngine->createSymbolicExpression(inst, mxcsr_ast, mxcsr_addr, "FXSAVE64 MXCSR operation");
7078 auto mxcsr_mask_expr = this->symbolicEngine->createSymbolicExpression(inst, mxcsr_mask_ast, mxcsr_mask_addr, "FXSAVE64 MXCSR_MASK operation");
7079 auto st0_expr = this->symbolicEngine->createSymbolicExpression(inst, st0_ast, st0_addr, "FXSAVE64 ST0 operation");
7080 auto st1_expr = this->symbolicEngine->createSymbolicExpression(inst, st1_ast, st1_addr, "FXSAVE64 ST1 operation");
7081 auto st2_expr = this->symbolicEngine->createSymbolicExpression(inst, st2_ast, st2_addr, "FXSAVE64 ST2 operation");
7082 auto st3_expr = this->symbolicEngine->createSymbolicExpression(inst, st3_ast, st3_addr, "FXSAVE64 ST3 operation");
7083 auto st4_expr = this->symbolicEngine->createSymbolicExpression(inst, st4_ast, st4_addr, "FXSAVE64 ST4 operation");
7084 auto st5_expr = this->symbolicEngine->createSymbolicExpression(inst, st5_ast, st5_addr, "FXSAVE64 ST5 operation");
7085 auto st6_expr = this->symbolicEngine->createSymbolicExpression(inst, st6_ast, st6_addr, "FXSAVE64 ST6 operation");
7086 auto st7_expr = this->symbolicEngine->createSymbolicExpression(inst, st7_ast, st7_addr, "FXSAVE64 ST7 operation");
7087 auto xmm0_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm0_ast, xmm0_addr, "FXSAVE64 XMM0 operation");
7088 auto xmm1_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm1_ast, xmm1_addr, "FXSAVE64 XMM1 operation");
7089 auto xmm2_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm2_ast, xmm2_addr, "FXSAVE64 XMM2 operation");
7090 auto xmm3_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm3_ast, xmm3_addr, "FXSAVE64 XMM3 operation");
7091 auto xmm4_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm4_ast, xmm4_addr, "FXSAVE64 XMM4 operation");
7092 auto xmm5_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm5_ast, xmm5_addr, "FXSAVE64 XMM5 operation");
7093 auto xmm6_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm6_ast, xmm6_addr, "FXSAVE64 XMM6 operation");
7094 auto xmm7_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm7_ast, xmm7_addr, "FXSAVE64 XMM7 operation");
7095 auto xmm8_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm8_ast, xmm8_addr, "FXSAVE64 XMM8 operation");
7096 auto xmm9_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm9_ast, xmm9_addr, "FXSAVE64 XMM9 operation");
7097 auto xmm10_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm10_ast, xmm10_addr, "FXSAVE64 XMM10 operation");
7098 auto xmm11_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm11_ast, xmm11_addr, "FXSAVE64 XMM11 operation");
7099 auto xmm12_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm12_ast, xmm12_addr, "FXSAVE64 XMM12 operation");
7100 auto xmm13_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm13_ast, xmm13_addr, "FXSAVE64 XMM13 operation");
7101 auto xmm14_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm14_ast, xmm14_addr, "FXSAVE64 XMM14 operation");
7102 auto xmm15_expr = this->symbolicEngine->createSymbolicExpression(inst, xmm15_ast, xmm15_addr, "FXSAVE64 XMM15 operation");
7103
7104 /* Spread the taint */
7105 fcw_expr->isTainted = this->taintEngine->taintAssignment(fcw_addr, fcw);
7106 fsw_expr->isTainted = this->taintEngine->taintAssignment(fsw_addr, fsw);
7107 ftw_expr->isTainted = this->taintEngine->taintAssignment(ftw_addr, ftw);
7108 fop_expr->isTainted = this->taintEngine->taintAssignment(fop_addr, fop);
7109 fip_expr->isTainted = this->taintEngine->taintAssignment(fip_addr, fip);
7110 fcs_expr->isTainted = this->taintEngine->taintAssignment(fcs_addr, fcs);
7111 fdp_expr->isTainted = this->taintEngine->taintAssignment(fdp_addr, fdp);
7112 fds_expr->isTainted = this->taintEngine->taintAssignment(fds_addr, fds);
7113 mxcsr_expr->isTainted = this->taintEngine->taintAssignment(mxcsr_addr, mxcsr);
7114 mxcsr_mask_expr->isTainted = this->taintEngine->taintAssignment(mxcsr_mask_addr, mxcsr_mask);
7115 st0_expr->isTainted = this->taintEngine->taintAssignment(st0_addr, st0);
7116 st1_expr->isTainted = this->taintEngine->taintAssignment(st1_addr, st1);
7117 st2_expr->isTainted = this->taintEngine->taintAssignment(st2_addr, st2);
7118 st3_expr->isTainted = this->taintEngine->taintAssignment(st3_addr, st3);
7119 st4_expr->isTainted = this->taintEngine->taintAssignment(st4_addr, st4);
7120 st5_expr->isTainted = this->taintEngine->taintAssignment(st5_addr, st5);
7121 st6_expr->isTainted = this->taintEngine->taintAssignment(st6_addr, st6);
7122 st7_expr->isTainted = this->taintEngine->taintAssignment(st7_addr, st7);
7123 xmm0_expr->isTainted = this->taintEngine->taintAssignment(xmm0_addr, xmm0);
7124 xmm1_expr->isTainted = this->taintEngine->taintAssignment(xmm1_addr, xmm1);
7125 xmm2_expr->isTainted = this->taintEngine->taintAssignment(xmm2_addr, xmm2);
7126 xmm3_expr->isTainted = this->taintEngine->taintAssignment(xmm3_addr, xmm3);
7127 xmm4_expr->isTainted = this->taintEngine->taintAssignment(xmm4_addr, xmm4);
7128 xmm5_expr->isTainted = this->taintEngine->taintAssignment(xmm5_addr, xmm5);
7129 xmm6_expr->isTainted = this->taintEngine->taintAssignment(xmm6_addr, xmm6);
7130 xmm7_expr->isTainted = this->taintEngine->taintAssignment(xmm7_addr, xmm7);
7131 xmm8_expr->isTainted = this->taintEngine->taintAssignment(xmm8_addr, xmm8);
7132 xmm9_expr->isTainted = this->taintEngine->taintAssignment(xmm9_addr, xmm9);
7133 xmm10_expr->isTainted = this->taintEngine->taintAssignment(xmm10_addr, xmm10);
7134 xmm11_expr->isTainted = this->taintEngine->taintAssignment(xmm11_addr, xmm11);
7135 xmm12_expr->isTainted = this->taintEngine->taintAssignment(xmm12_addr, xmm12);
7136 xmm13_expr->isTainted = this->taintEngine->taintAssignment(xmm13_addr, xmm13);
7137 xmm14_expr->isTainted = this->taintEngine->taintAssignment(xmm14_addr, xmm14);
7138 xmm15_expr->isTainted = this->taintEngine->taintAssignment(xmm15_addr, xmm15);
7139
7140 /* Update the symbolic control flow */
7141 this->controlFlow_s(inst);
7142 }
7143
7144
7145 void x86Semantics::idiv_s(triton::arch::Instruction& inst) {
7146 auto& src = inst.operands[0];
7147
7148 /* Create symbolic operands */
7149 auto divisor = this->symbolicEngine->getOperandAst(inst, src);
7150
7151 /* Create symbolic expression */
7152 switch (src.getSize()) {
7153
7154 case triton::size::byte: {
7155 /* AX */
7156 auto ax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
7157 auto dividend = this->symbolicEngine->getOperandAst(inst, ax);
7158 /* res = AX / Source */
7159 auto result = this->astCtxt->bvsdiv(dividend, this->astCtxt->sx(triton::bitsize::byte, divisor));
7160 /* mod = AX % Source */
7161 auto mod = this->astCtxt->bvsmod(dividend, this->astCtxt->sx(triton::bitsize::byte, divisor));
7162 /* AH = mod */
7163 /* AL = res */
7164 auto node = this->astCtxt->concat(
7165 this->astCtxt->extract((triton::bitsize::byte - 1), 0, mod), /* AH = mod */
7166 this->astCtxt->extract((triton::bitsize::byte - 1), 0, result) /* AL = res */
7167 );
7168 /* Create symbolic expression */
7169 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, ax, "IDIV operation");
7170 /* Apply the taint */
7171 expr->isTainted = this->taintEngine->taintUnion(ax, src);
7172 break;
7173 }
7174
7175 case triton::size::word: {
7176 /* DX:AX */
7177 auto dx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DX));
7178 auto ax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
7179 auto dividend = this->astCtxt->concat(this->symbolicEngine->getOperandAst(inst, dx), this->symbolicEngine->getOperandAst(inst, ax));
7180 /* res = DX:AX / Source */
7181 auto temp = this->astCtxt->bvsdiv(dividend, this->astCtxt->sx(triton::bitsize::word, divisor));
7182 auto result = this->astCtxt->extract((triton::bitsize::word - 1), 0, temp);
7183 /* mod = DX:AX % Source */
7184 auto mod = this->astCtxt->extract((triton::bitsize::word - 1), 0, this->astCtxt->bvsmod(dividend, this->astCtxt->sx(triton::bitsize::word, divisor)));
7185 /* Create the symbolic expression for AX */
7186 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, result, ax, "IDIV operation");
7187 /* Apply the taint for AX */
7188 expr1->isTainted = this->taintEngine->taintUnion(ax, src);
7189 /* Create the symbolic expression for DX */
7190 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, mod, dx, "IDIV operation");
7191 /* Apply the taint for DX */
7192 expr2->isTainted = this->taintEngine->taintUnion(dx, src);
7193 break;
7194 }
7195
7196 case triton::size::dword: {
7197 /* EDX:EAX */
7198 auto edx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
7199 auto eax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
7200 auto dividend = this->astCtxt->concat(this->symbolicEngine->getOperandAst(inst, edx), this->symbolicEngine->getOperandAst(inst, eax));
7201 /* res = EDX:EAX / Source */
7202 auto temp = this->astCtxt->bvsdiv(dividend, this->astCtxt->sx(triton::bitsize::dword, divisor));
7203 auto result = this->astCtxt->extract((triton::bitsize::dword - 1), 0, temp);
7204 /* mod = EDX:EAX % Source */
7205 auto mod = this->astCtxt->extract((triton::bitsize::dword - 1), 0, this->astCtxt->bvsmod(dividend, this->astCtxt->sx(triton::bitsize::dword, divisor)));
7206 /* Create the symbolic expression for EAX */
7207 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, result, eax, "IDIV operation");
7208 /* Apply the taint for EAX */
7209 expr1->isTainted = this->taintEngine->taintUnion(eax, src);
7210 /* Create the symbolic expression for EDX */
7211 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, mod, edx, "IDIV operation");
7212 /* Apply the taint for EDX */
7213 expr2->isTainted = this->taintEngine->taintUnion(edx, src);
7214 break;
7215 }
7216
7217 case triton::size::qword: {
7218 /* RDX:RAX */
7219 auto rdx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX));
7220 auto rax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX));
7221 auto dividend = this->astCtxt->concat(this->symbolicEngine->getOperandAst(inst, rdx), this->symbolicEngine->getOperandAst(inst, rax));
7222 /* res = RDX:RAX / Source */
7223 auto temp = this->astCtxt->bvsdiv(dividend, this->astCtxt->sx(triton::bitsize::qword, divisor));
7224 auto result = this->astCtxt->extract((triton::bitsize::qword - 1), 0, temp);
7225 /* mod = RDX:RAX % Source */
7226 auto mod = this->astCtxt->extract((triton::bitsize::qword - 1), 0, this->astCtxt->bvsmod(dividend, this->astCtxt->sx(triton::bitsize::qword, divisor)));
7227 /* Create the symbolic expression for RAX */
7228 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, result, rax, "IDIV operation");
7229 /* Apply the taint for EAX */
7230 expr1->isTainted = this->taintEngine->taintUnion(rax, src);
7231 /* Create the symbolic expression for RDX */
7232 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, mod, rdx, "IDIV operation");
7233 /* Apply the taint for EDX */
7234 expr2->isTainted = this->taintEngine->taintUnion(rdx, src);
7235 break;
7236 }
7237
7238 }
7239
7240 /* Tag undefined flags */
7241 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
7242 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
7243 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
7244 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
7245 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
7246 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF));
7247
7248 /* Return an exception if the divisor is zero */
7249 if (divisor->evaluate() == 0) {
7250 this->exception = triton::arch::FAULT_DE;
7251 return;
7252 }
7253
7254 /* Update the symbolic control flow */
7255 this->controlFlow_s(inst);
7256 }
7257
7258
7259 void x86Semantics::imul_s(triton::arch::Instruction& inst) {
7260 switch (inst.operands.size()) {
7261
7262 /* one operand */
7263 case 1: {
7264 auto& src = inst.operands[0];
7265
7266 /* size of the Operand */
7267 switch (src.getSize()) {
7268
7269 /* dst = AX */
7270 case triton::size::byte: {
7271 auto ax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
7272 auto al = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
7273 auto op1 = this->symbolicEngine->getOperandAst(inst, al);
7274 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
7275 auto node = this->astCtxt->bvmul(this->astCtxt->sx(triton::bitsize::byte, op1), this->astCtxt->sx(triton::bitsize::byte, op2));
7276 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, ax, "IMUL operation");
7277 expr->isTainted = this->taintEngine->taintUnion(ax, src);
7278 this->cfImul_s(inst, expr, al, this->astCtxt->bvmul(op1, op2), node);
7279 this->ofImul_s(inst, expr, al, this->astCtxt->bvmul(op1, op2), node);
7280 break;
7281 }
7282
7283 /* dst = DX:AX */
7284 case triton::size::word: {
7285 auto ax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
7286 auto dx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DX));
7287 auto op1 = this->symbolicEngine->getOperandAst(inst, ax);
7288 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
7289 auto node1 = this->astCtxt->bvmul(op1, op2);
7290 auto node2 = this->astCtxt->bvmul(this->astCtxt->sx(triton::bitsize::word, op1), this->astCtxt->sx(triton::bitsize::word, op2));
7291 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, ax, "IMUL operation");
7292 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(triton::bitsize::dword-1, triton::bitsize::word, node2), dx, "IMUL operation");
7293 expr1->isTainted = this->taintEngine->taintUnion(ax, src);
7294 expr2->isTainted = this->taintEngine->taintUnion(dx, ax);
7295 this->cfImul_s(inst, expr1, ax, node1, node2);
7296 this->ofImul_s(inst, expr1, ax, node1, node2);
7297 break;
7298 }
7299
7300 /* dst = EDX:EAX */
7301 case triton::size::dword: {
7302 auto eax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
7303 auto edx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
7304 auto op1 = this->symbolicEngine->getOperandAst(inst, eax);
7305 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
7306 auto node1 = this->astCtxt->bvmul(op1, op2);
7307 auto node2 = this->astCtxt->bvmul(this->astCtxt->sx(triton::bitsize::dword, op1), this->astCtxt->sx(triton::bitsize::dword, op2));
7308 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, eax, "IMUL operation");
7309 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(triton::bitsize::qword-1, triton::bitsize::dword, node2), edx, "IMUL operation");
7310 expr1->isTainted = this->taintEngine->taintUnion(eax, src);
7311 expr2->isTainted = this->taintEngine->taintUnion(edx, eax);
7312 this->cfImul_s(inst, expr1, eax, node1, node2);
7313 this->ofImul_s(inst, expr1, eax, node1, node2);
7314 break;
7315 }
7316
7317 /* dst = RDX:RAX */
7318 case triton::size::qword: {
7319 auto rax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX));
7320 auto rdx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX));
7321 auto op1 = this->symbolicEngine->getOperandAst(inst, rax);
7322 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
7323 auto node1 = this->astCtxt->bvmul(op1, op2);
7324 auto node2 = this->astCtxt->bvmul(this->astCtxt->sx(triton::bitsize::qword, op1), this->astCtxt->sx(triton::bitsize::qword, op2));
7325 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, rax, "IMUL operation");
7326 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(triton::bitsize::dqword-1, triton::bitsize::qword, node2), rdx, "IMUL operation");
7327 expr1->isTainted = this->taintEngine->taintUnion(rax, src);
7328 expr2->isTainted = this->taintEngine->taintUnion(rdx, rax);
7329 this->cfImul_s(inst, expr1, rax, node1, node2);
7330 this->ofImul_s(inst, expr1, rax, node1, node2);
7331 break;
7332 }
7333
7334 }
7335 break;
7336 }
7337
7338 /* two operands */
7339 case 2: {
7340 auto& dst = inst.operands[0];
7341 auto& src = inst.operands[1];
7342 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
7343 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
7344 auto node1 = this->astCtxt->bvmul(op1, op2);
7345 auto node2 = this->astCtxt->bvmul(this->astCtxt->sx(dst.getBitSize(), op1), this->astCtxt->sx(src.getBitSize(), op2));
7346 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "IMUL operation");
7347 expr->isTainted = this->taintEngine->taintUnion(dst, src);
7348 this->cfImul_s(inst, expr, dst, node1, node2);
7349 this->ofImul_s(inst, expr, dst, node1, node2);
7350 break;
7351 }
7352
7353 /* three operands */
7354 case 3: {
7355 auto& dst = inst.operands[0];
7356 auto& src1 = inst.operands[1];
7357 auto& src2 = inst.operands[2];
7358 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
7359 auto op3 = this->astCtxt->sx(src1.getBitSize() - src2.getBitSize(), this->symbolicEngine->getOperandAst(inst, src2));
7360 auto node1 = this->astCtxt->bvmul(op2, op3);
7361 auto node2 = this->astCtxt->bvmul(this->astCtxt->sx(src1.getBitSize(), op2), this->astCtxt->sx(src2.getBitSize(), op3));
7362 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "IMUL operation");
7363 expr->isTainted = this->taintEngine->setTaint(dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
7364 this->cfImul_s(inst, expr, dst, node1, node2);
7365 this->ofImul_s(inst, expr, dst, node1, node2);
7366 break;
7367 }
7368
7369 }
7370
7371 /* Tag undefined flags */
7372 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
7373 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
7374 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
7375 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF));
7376
7377 /* Update the symbolic control flow */
7378 this->controlFlow_s(inst);
7379 }
7380
7381
7382 void x86Semantics::inc_s(triton::arch::Instruction& inst) {
7383 auto& dst = inst.operands[0];
7384
7385 /* Create symbolic operands */
7386 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
7387 auto op2 = this->astCtxt->bv(1, dst.getBitSize());
7388
7389 /* Create the semantics */
7390 auto node = this->astCtxt->bvadd(op1, op2);
7391
7392 /* Create symbolic expression */
7393 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "INC operation");
7394
7395 /* Spread taint */
7396 expr->isTainted = this->taintEngine->taintUnion(dst, dst);
7397
7398 /* Update symbolic flags */
7399 this->af_s(inst, expr, dst, op1, op2);
7400 this->ofAdd_s(inst, expr, dst, op1, op2);
7401 this->pf_s(inst, expr, dst);
7402 this->sf_s(inst, expr, dst);
7403 this->zf_s(inst, expr, dst);
7404
7405 /* Update the symbolic control flow */
7406 this->controlFlow_s(inst);
7407 }
7408
7409
7410 void x86Semantics::invd_s(triton::arch::Instruction& inst) {
7411 /* Update the symbolic control flow */
7412 this->controlFlow_s(inst);
7413 }
7414
7415
7416 void x86Semantics::invlpg_s(triton::arch::Instruction& inst) {
7417 /* Update the symbolic control flow */
7418 this->controlFlow_s(inst);
7419 }
7420
7421
7422 void x86Semantics::ja_s(triton::arch::Instruction& inst) {
7423 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7424 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
7425 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
7426 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7427 auto& srcImm2 = inst.operands[0];
7428
7429 /* Create symbolic operands */
7430 auto op1 = this->symbolicEngine->getOperandAst(inst, cf);
7431 auto op2 = this->symbolicEngine->getOperandAst(inst, zf);
7432 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7433 auto op4 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7434
7435 /* Create the semantics */
7436 auto node = this->astCtxt->ite(
7437 this->astCtxt->equal(
7438 this->astCtxt->bvand(
7439 this->astCtxt->bvnot(op1),
7440 this->astCtxt->bvnot(op2)
7441 ),
7442 this->astCtxt->bvtrue()
7443 ), op4, op3);
7444
7445 /* Create symbolic expression */
7446 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7447
7448 /* Set condition flag */
7449 if (op1->evaluate().is_zero() && op2->evaluate().is_zero())
7450 inst.setConditionTaken(true);
7451
7452 /* Spread taint */
7453 expr->isTainted = this->taintEngine->taintAssignment(pc, cf);
7454 expr->isTainted = this->taintEngine->taintUnion(pc, zf);
7455
7456 /* Create the path constraint */
7457 this->symbolicEngine->pushPathConstraint(inst, expr);
7458 }
7459
7460
7461 void x86Semantics::jae_s(triton::arch::Instruction& inst) {
7462 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7463 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
7464 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7465 auto& srcImm2 = inst.operands[0];
7466
7467 /* Create symbolic operands */
7468 auto op1 = this->symbolicEngine->getOperandAst(inst, cf);
7469 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7470 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7471
7472 /* Create the semantics */
7473 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvfalse()), op3, op2);
7474
7475 /* Create symbolic expression */
7476 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7477
7478 /* Set condition flag */
7479 if (op1->evaluate().is_zero())
7480 inst.setConditionTaken(true);
7481
7482 /* Spread taint */
7483 expr->isTainted = this->taintEngine->taintAssignment(pc, cf);
7484
7485 /* Create the path constraint */
7486 this->symbolicEngine->pushPathConstraint(inst, expr);
7487 }
7488
7489
7490 void x86Semantics::jb_s(triton::arch::Instruction& inst) {
7491 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7492 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
7493 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7494 auto& srcImm2 = inst.operands[0];
7495
7496 /* Create symbolic operands */
7497 auto op1 = this->symbolicEngine->getOperandAst(inst, cf);
7498 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7499 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7500
7501 /* Create the semantics */
7502 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvtrue()), op3, op2);
7503
7504 /* Create symbolic expression */
7505 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7506
7507 /* Set condition flag */
7508 if (!op1->evaluate().is_zero())
7509 inst.setConditionTaken(true);
7510
7511 /* Spread taint */
7512 expr->isTainted = this->taintEngine->taintAssignment(pc, cf);
7513
7514 /* Create the path constraint */
7515 this->symbolicEngine->pushPathConstraint(inst, expr);
7516 }
7517
7518
7519 void x86Semantics::jbe_s(triton::arch::Instruction& inst) {
7520 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7521 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
7522 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
7523 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7524 auto& srcImm2 = inst.operands[0];
7525
7526 /* Create symbolic operands */
7527 auto op1 = this->symbolicEngine->getOperandAst(inst, cf);
7528 auto op2 = this->symbolicEngine->getOperandAst(inst, zf);
7529 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7530 auto op4 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7531
7532 /* Create the semantics */
7533 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvor(op1, op2), this->astCtxt->bvtrue()), op4, op3);
7534
7535 /* Create symbolic expression */
7536 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7537
7538 /* Set condition flag */
7539 if (!op1->evaluate().is_zero() || !op2->evaluate().is_zero())
7540 inst.setConditionTaken(true);
7541
7542 /* Spread taint */
7543 expr->isTainted = this->taintEngine->taintAssignment(pc, cf);
7544 expr->isTainted = this->taintEngine->taintUnion(pc, zf);
7545
7546 /* Create the path constraint */
7547 this->symbolicEngine->pushPathConstraint(inst, expr);
7548 }
7549
7550
7551 void x86Semantics::jcxz_s(triton::arch::Instruction& inst) {
7552 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7553 auto cx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CX));
7554 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7555 auto& srcImm2 = inst.operands[0];
7556
7557 /* Create symbolic operands */
7558 auto op1 = this->symbolicEngine->getOperandAst(inst, cx);
7559 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7560 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7561
7562 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bv(0, triton::bitsize::word)), op3, op2);
7563
7564 /* Create symbolic expression */
7565 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7566
7567 /* Set condition flag */
7568 if (!op1->evaluate().is_zero())
7569 inst.setConditionTaken(true);
7570
7571 /* Spread taint */
7572 expr->isTainted = this->taintEngine->taintAssignment(pc, cx);
7573
7574 /* Create the path constraint */
7575 this->symbolicEngine->pushPathConstraint(inst, expr);
7576 }
7577
7578
7579 void x86Semantics::je_s(triton::arch::Instruction& inst) {
7580 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7581 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
7582 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7583 auto& srcImm2 = inst.operands[0];
7584
7585 /* Create symbolic operands */
7586 auto op1 = this->symbolicEngine->getOperandAst(inst, zf);
7587 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7588 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7589
7590 /* Create the semantics */
7591 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvtrue()), op3, op2);
7592
7593 /* Create symbolic expression */
7594 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7595
7596 /* Set condition flag */
7597 if (!op1->evaluate().is_zero())
7598 inst.setConditionTaken(true);
7599
7600 /* Spread taint */
7601 expr->isTainted = this->taintEngine->taintAssignment(pc, zf);
7602
7603 /* Create the path constraint */
7604 this->symbolicEngine->pushPathConstraint(inst, expr);
7605 }
7606
7607
7608 void x86Semantics::jecxz_s(triton::arch::Instruction& inst) {
7609 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7610 auto ecx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ECX));
7611 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7612 auto& srcImm2 = inst.operands[0];
7613
7614 /* Create symbolic operands */
7615 auto op1 = this->symbolicEngine->getOperandAst(inst, ecx);
7616 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7617 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7618
7619 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bv(0, triton::bitsize::dword)), op3, op2);
7620
7621 /* Create symbolic expression */
7622 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7623
7624 /* Set condition flag */
7625 if (!op1->evaluate().is_zero())
7626 inst.setConditionTaken(true);
7627
7628 /* Spread taint */
7629 expr->isTainted = this->taintEngine->taintAssignment(pc, ecx);
7630
7631 /* Create the path constraint */
7632 this->symbolicEngine->pushPathConstraint(inst, expr);
7633 }
7634
7635
7636 void x86Semantics::jg_s(triton::arch::Instruction& inst) {
7637 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7638 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
7639 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
7640 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
7641 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7642 auto& srcImm2 = inst.operands[0];
7643
7644 /* Create symbolic operands */
7645 auto op1 = this->symbolicEngine->getOperandAst(inst, sf);
7646 auto op2 = this->symbolicEngine->getOperandAst(inst, of);
7647 auto op3 = this->symbolicEngine->getOperandAst(inst, zf);
7648 auto op4 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7649 auto op5 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7650
7651 /* Create the semantics */
7652 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvor(this->astCtxt->bvxor(op1, op2), op3), this->astCtxt->bvfalse()), op5, op4);
7653
7654 /* Create symbolic expression */
7655 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7656
7657 /* Set condition flag */
7658 if ((op1->evaluate().is_zero() == op2->evaluate().is_zero()) && op3->evaluate().is_zero())
7659 inst.setConditionTaken(true);
7660
7661 /* Spread taint */
7662 expr->isTainted = this->taintEngine->taintAssignment(pc, sf);
7663 expr->isTainted = this->taintEngine->taintUnion(pc, of);
7664 expr->isTainted = this->taintEngine->taintUnion(pc, zf);
7665
7666 /* Create the path constraint */
7667 this->symbolicEngine->pushPathConstraint(inst, expr);
7668 }
7669
7670
7671 void x86Semantics::jge_s(triton::arch::Instruction& inst) {
7672 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7673 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
7674 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
7675 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7676 auto& srcImm2 = inst.operands[0];
7677
7678 /* Create symbolic operands */
7679 auto op1 = this->symbolicEngine->getOperandAst(inst, sf);
7680 auto op2 = this->symbolicEngine->getOperandAst(inst, of);
7681 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7682 auto op4 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7683
7684 /* Create the semantics */
7685 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, op2), op4, op3);
7686
7687 /* Create symbolic expression */
7688 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7689
7690 /* Set condition flag */
7691 if (op1->evaluate().is_zero() == op2->evaluate().is_zero())
7692 inst.setConditionTaken(true);
7693
7694 /* Spread taint */
7695 expr->isTainted = this->taintEngine->taintAssignment(pc, sf);
7696 expr->isTainted = this->taintEngine->taintUnion(pc, of);
7697
7698 /* Create the path constraint */
7699 this->symbolicEngine->pushPathConstraint(inst, expr);
7700 }
7701
7702
7703 void x86Semantics::jl_s(triton::arch::Instruction& inst) {
7704 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7705 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
7706 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
7707 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7708 auto& srcImm2 = inst.operands[0];
7709
7710 /* Create symbolic operands */
7711 auto op1 = this->symbolicEngine->getOperandAst(inst, sf);
7712 auto op2 = this->symbolicEngine->getOperandAst(inst, of);
7713 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7714 auto op4 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7715
7716 /* Create the semantics */
7717 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvxor(op1, op2), this->astCtxt->bvtrue()), op4, op3);
7718
7719 /* Create symbolic expression */
7720 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7721
7722 /* Set condition flag */
7723 if (op1->evaluate().is_zero() != op2->evaluate().is_zero())
7724 inst.setConditionTaken(true);
7725
7726 /* Spread taint */
7727 expr->isTainted = this->taintEngine->taintAssignment(pc, sf);
7728 expr->isTainted = this->taintEngine->taintUnion(pc, of);
7729
7730 /* Create the path constraint */
7731 this->symbolicEngine->pushPathConstraint(inst, expr);
7732 }
7733
7734
7735 void x86Semantics::jle_s(triton::arch::Instruction& inst) {
7736 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7737 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
7738 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
7739 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
7740 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7741 auto& srcImm2 = inst.operands[0];
7742
7743 /* Create symbolic operands */
7744 auto op1 = this->symbolicEngine->getOperandAst(inst, sf);
7745 auto op2 = this->symbolicEngine->getOperandAst(inst, of);
7746 auto op3 = this->symbolicEngine->getOperandAst(inst, zf);
7747 auto op4 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7748 auto op5 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7749
7750 /* Create the semantics */
7751 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvor(this->astCtxt->bvxor(op1, op2), op3), this->astCtxt->bvtrue()), op5, op4);
7752
7753 /* Create symbolic expression */
7754 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7755
7756 /* Set condition flag */
7757 if ((op1->evaluate().is_zero() != op2->evaluate().is_zero()) || !op3->evaluate().is_zero())
7758 inst.setConditionTaken(true);
7759
7760 /* Spread taint */
7761 expr->isTainted = this->taintEngine->taintAssignment(pc, sf);
7762 expr->isTainted = this->taintEngine->taintUnion(pc, of);
7763 expr->isTainted = this->taintEngine->taintUnion(pc, zf);
7764
7765 /* Create the path constraint */
7766 this->symbolicEngine->pushPathConstraint(inst, expr);
7767 }
7768
7769
7770 void x86Semantics::jmp_s(triton::arch::Instruction& inst) {
7771 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7772 auto& src = inst.operands[0];
7773
7774 /* Create symbolic operands */
7775 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
7776
7777 /* Create the semantics */
7778 auto node = op1;
7779
7780 /* Create symbolic expression */
7781 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7782
7783 /* Set condition flag */
7784 inst.setConditionTaken(true);
7785
7786 /* Spread taint */
7787 expr->isTainted = this->taintEngine->taintAssignment(pc, src);
7788
7789 /* Create the path constraint */
7790 this->symbolicEngine->pushPathConstraint(inst, expr);
7791 }
7792
7793
7794 void x86Semantics::jne_s(triton::arch::Instruction& inst) {
7795 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7796 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
7797 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7798 auto& srcImm2 = inst.operands[0];
7799
7800 /* Create symbolic operands */
7801 auto op1 = this->symbolicEngine->getOperandAst(inst, zf);
7802 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7803 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7804
7805 /* Create the semantics */
7806 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvfalse()), op3, op2);
7807
7808 /* Create symbolic expression */
7809 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7810
7811 /* Set condition flag */
7812 if (op1->evaluate().is_zero())
7813 inst.setConditionTaken(true);
7814
7815 /* Spread taint */
7816 expr->isTainted = this->taintEngine->taintAssignment(pc, zf);
7817
7818 /* Create the path constraint */
7819 this->symbolicEngine->pushPathConstraint(inst, expr);
7820 }
7821
7822
7823 void x86Semantics::jno_s(triton::arch::Instruction& inst) {
7824 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7825 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
7826 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7827 auto& srcImm2 = inst.operands[0];
7828
7829 /* Create symbolic operands */
7830 auto op1 = this->symbolicEngine->getOperandAst(inst, of);
7831 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7832 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7833
7834 /* Create the semantics */
7835 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvfalse()), op3, op2);
7836
7837 /* Create symbolic expression */
7838 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7839
7840 /* Set condition flag */
7841 if (op1->evaluate().is_zero())
7842 inst.setConditionTaken(true);
7843
7844 /* Spread taint */
7845 expr->isTainted = this->taintEngine->taintAssignment(pc, of);
7846
7847 /* Create the path constraint */
7848 this->symbolicEngine->pushPathConstraint(inst, expr);
7849 }
7850
7851
7852 void x86Semantics::jnp_s(triton::arch::Instruction& inst) {
7853 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7854 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
7855 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7856 auto& srcImm2 = inst.operands[0];
7857
7858 /* Create symbolic operands */
7859 auto op1 = this->symbolicEngine->getOperandAst(inst, pf);
7860 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7861 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7862
7863 /* Create the semantics */
7864 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvfalse()), op3, op2);
7865
7866 /* Create symbolic expression */
7867 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7868
7869 /* Set condition flag */
7870 if (op1->evaluate().is_zero())
7871 inst.setConditionTaken(true);
7872
7873 /* Spread taint */
7874 expr->isTainted = this->taintEngine->taintAssignment(pc, pf);
7875
7876 /* Create the path constraint */
7877 this->symbolicEngine->pushPathConstraint(inst, expr);
7878 }
7879
7880
7881 void x86Semantics::jns_s(triton::arch::Instruction& inst) {
7882 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7883 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
7884 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7885 auto& srcImm2 = inst.operands[0];
7886
7887 /* Create symbolic operands */
7888 auto op1 = this->symbolicEngine->getOperandAst(inst, sf);
7889 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7890 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7891
7892 /* Create the semantics */
7893 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvfalse()), op3, op2);
7894
7895 /* Create symbolic expression */
7896 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7897
7898 /* Set condition flag */
7899 if (op1->evaluate().is_zero())
7900 inst.setConditionTaken(true);
7901
7902 /* Spread taint */
7903 expr->isTainted = this->taintEngine->taintAssignment(pc, sf);
7904
7905 /* Create the path constraint */
7906 this->symbolicEngine->pushPathConstraint(inst, expr);
7907 }
7908
7909
7910 void x86Semantics::jo_s(triton::arch::Instruction& inst) {
7911 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7912 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
7913 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7914 auto& srcImm2 = inst.operands[0];
7915
7916 /* Create symbolic operands */
7917 auto op1 = this->symbolicEngine->getOperandAst(inst, of);
7918 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7919 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7920
7921 /* Create the semantics */
7922 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvtrue()), op3, op2);
7923
7924 /* Create symbolic expression */
7925 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7926
7927 /* Set condition flag */
7928 if (!op1->evaluate().is_zero())
7929 inst.setConditionTaken(true);
7930
7931 /* Spread taint */
7932 expr->isTainted = this->taintEngine->taintAssignment(pc, of);
7933
7934 /* Create the path constraint */
7935 this->symbolicEngine->pushPathConstraint(inst, expr);
7936 }
7937
7938
7939 void x86Semantics::jp_s(triton::arch::Instruction& inst) {
7940 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7941 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
7942 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7943 auto& srcImm2 = inst.operands[0];
7944
7945 /* Create symbolic operands */
7946 auto op1 = this->symbolicEngine->getOperandAst(inst, pf);
7947 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7948 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7949
7950 /* Create the semantics */
7951 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvtrue()), op3, op2);
7952
7953 /* Create symbolic expression */
7954 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7955
7956 /* Set condition flag */
7957 if (!op1->evaluate().is_zero())
7958 inst.setConditionTaken(true);
7959
7960 /* Spread taint */
7961 expr->isTainted = this->taintEngine->taintAssignment(pc, pf);
7962
7963 /* Create the path constraint */
7964 this->symbolicEngine->pushPathConstraint(inst, expr);
7965 }
7966
7967
7968 void x86Semantics::jrcxz_s(triton::arch::Instruction& inst) {
7969 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7970 auto rcx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RCX));
7971 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
7972 auto& srcImm2 = inst.operands[0];
7973
7974 /* Create symbolic operands */
7975 auto op1 = this->symbolicEngine->getOperandAst(inst, rcx);
7976 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
7977 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
7978
7979 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bv(0, triton::bitsize::qword)), op3, op2);
7980
7981 /* Create symbolic expression */
7982 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
7983
7984 /* Set condition flag */
7985 if (!op1->evaluate().is_zero())
7986 inst.setConditionTaken(true);
7987
7988 /* Spread taint */
7989 expr->isTainted = this->taintEngine->taintAssignment(pc, rcx);
7990
7991 /* Create the path constraint */
7992 this->symbolicEngine->pushPathConstraint(inst, expr);
7993 }
7994
7995
7996 void x86Semantics::js_s(triton::arch::Instruction& inst) {
7997 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
7998 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
7999 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize()));
8000 auto& srcImm2 = inst.operands[0];
8001
8002 /* Create symbolic operands */
8003 auto op1 = this->symbolicEngine->getOperandAst(inst, sf);
8004 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1);
8005 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2);
8006
8007 /* Create the semantics */
8008 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvtrue()), op3, op2);
8009
8010 /* Create symbolic expression */
8011 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
8012
8013 /* Set condition flag */
8014 if (!op1->evaluate().is_zero())
8015 inst.setConditionTaken(true);
8016
8017 /* Spread taint */
8018 expr->isTainted = this->taintEngine->taintAssignment(pc, sf);
8019
8020 /* Create the path constraint */
8021 this->symbolicEngine->pushPathConstraint(inst, expr);
8022 }
8023
8024
8025 void x86Semantics::lahf_s(triton::arch::Instruction& inst) {
8026 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AH));
8027 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
8028 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
8029 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF));
8030 auto src4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
8031 auto src5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
8032
8033 /* Create symbolic operands */
8034 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
8035 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
8036 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
8037 auto op4 = this->symbolicEngine->getOperandAst(inst, src4);
8038 auto op5 = this->symbolicEngine->getOperandAst(inst, src5);
8039
8040 /* Create the semantics */
8041 std::vector<triton::ast::SharedAbstractNode> flags;
8042 flags.reserve(8);
8043
8044 flags.push_back(op1);
8045 flags.push_back(op2);
8046 flags.push_back(this->astCtxt->bvfalse());
8047 flags.push_back(op3);
8048 flags.push_back(this->astCtxt->bvfalse());
8049 flags.push_back(op4);
8050 flags.push_back(this->astCtxt->bvtrue());
8051 flags.push_back(op5);
8052
8053 auto node = this->astCtxt->concat(flags);
8054
8055 /* Create symbolic expression */
8056 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "LAHF operation");
8057
8058 /* Spread taint */
8059 this->taintEngine->taintUnion(dst, src1);
8060 this->taintEngine->taintUnion(dst, src2);
8061 this->taintEngine->taintUnion(dst, src3);
8062 this->taintEngine->taintUnion(dst, src4);
8063 expr->isTainted = this->taintEngine->taintUnion(dst, src5);
8064
8065 /* Update the symbolic control flow */
8066 this->controlFlow_s(inst);
8067 }
8068
8069
8070 void x86Semantics::lddqu_s(triton::arch::Instruction& inst) {
8071 auto& dst = inst.operands[0];
8072 auto& src = inst.operands[1];
8073
8074 /* Create the semantics */
8075 auto node = this->symbolicEngine->getOperandAst(inst, src);
8076
8077 /* Create symbolic expression */
8078 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "LDDQU operation");
8079
8080 /* Spread taint */
8081 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8082
8083 /* Update the symbolic control flow */
8084 this->controlFlow_s(inst);
8085 }
8086
8087
8088 void x86Semantics::ldmxcsr_s(triton::arch::Instruction& inst) {
8089 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR));
8090 auto& src = inst.operands[0];
8091
8092 /* Create the semantics */
8093 auto node = this->symbolicEngine->getOperandAst(inst, src);
8094
8095 /* Create symbolic expression */
8096 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "LDMXCSR operation");
8097
8098 /* Spread taint */
8099 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8100
8101 /* Update the symbolic control flow */
8102 this->controlFlow_s(inst);
8103 }
8104
8105
8106 void x86Semantics::lea_s(triton::arch::Instruction& inst) {
8107 auto& dst = inst.operands[0].getRegister();
8108 auto& srcDisp = inst.operands[1].getMemory().getDisplacement();
8109 auto& srcBase = inst.operands[1].getMemory().getBaseRegister();
8110 auto& srcIndex = inst.operands[1].getMemory().getIndexRegister();
8111 auto& srcScale = inst.operands[1].getMemory().getScale();
8112 triton::uint32 leaSize = 0;
8113
8114 /* Setup LEA size */
8115 if (this->architecture->isRegisterValid(srcBase))
8116 leaSize = srcBase.getBitSize();
8117 else if (this->architecture->isRegisterValid(srcIndex))
8118 leaSize = srcIndex.getBitSize();
8119 else
8120 leaSize = srcDisp.getBitSize();
8121
8122 /* Create symbolic operands */
8123
8124 /* Displacement */
8125 auto op2 = this->symbolicEngine->getImmediateAst(inst, srcDisp);
8126 if (leaSize > srcDisp.getBitSize())
8127 op2 = this->astCtxt->zx(leaSize - srcDisp.getBitSize(), op2);
8128
8129 /* Base */
8130 triton::ast::SharedAbstractNode op3 = nullptr;
8131 if (this->architecture->isRegisterValid(srcBase))
8132 op3 = this->symbolicEngine->getRegisterAst(inst, srcBase);
8133 else
8134 op3 = this->astCtxt->bv(0, leaSize);
8135
8136 /* Base with PC */
8137 if (this->architecture->isRegisterValid(srcBase) && (this->architecture->getParentRegister(srcBase) == this->architecture->getProgramCounter()))
8138 op3 = this->astCtxt->bvadd(op3, this->astCtxt->bv(inst.getSize(), leaSize));
8139
8140 /* Index */
8141 triton::ast::SharedAbstractNode op4 = nullptr;
8142 if (this->architecture->isRegisterValid(srcIndex))
8143 op4 = this->symbolicEngine->getRegisterAst(inst, srcIndex);
8144 else
8145 op4 = this->astCtxt->bv(0, leaSize);
8146
8147 /* Scale */
8148 auto op5 = this->symbolicEngine->getImmediateAst(inst, srcScale);
8149 if (leaSize > srcScale.getBitSize())
8150 op5 = this->astCtxt->zx(leaSize - srcScale.getBitSize(), op5);
8151
8152 /* Create the semantics */
8153 /* Effective address = Displacement + BaseReg + IndexReg * Scale */
8154 auto node = this->astCtxt->bvadd(op2, this->astCtxt->bvadd(op3, this->astCtxt->bvmul(op4, op5)));
8155
8156 if (dst.getBitSize() > leaSize)
8157 node = this->astCtxt->zx(dst.getBitSize() - leaSize, node);
8158
8159 if (dst.getBitSize() < leaSize)
8160 node = this->astCtxt->extract(dst.getHigh(), dst.getLow(), node);
8161
8162 /* Create symbolic expression */
8163 auto expr = this->symbolicEngine->createSymbolicRegisterExpression(inst, node, dst, "LEA operation");
8164
8165 /* Spread taint */
8166 expr->isTainted = this->taintEngine->setTaint(dst, this->taintEngine->isTainted(srcBase) | this->taintEngine->isTainted(srcIndex));
8167
8168 /* Update the symbolic control flow */
8169 this->controlFlow_s(inst);
8170 }
8171
8172
8173 void x86Semantics::leave_s(triton::arch::Instruction& inst) {
8174 auto stack = this->architecture->getStackPointer();
8175 auto base = this->architecture->getParentRegister(ID_REG_X86_BP);
8176 auto baseValue = static_cast<triton::uint64>(this->architecture->getConcreteRegisterValue(base));
8177 auto bp1 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(baseValue, base.getSize()));
8178 auto bp2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_BP));
8179 auto sp = triton::arch::OperandWrapper(stack);
8180
8181 /* Create symbolic operands */
8182 auto op1 = this->symbolicEngine->getOperandAst(inst, bp2);
8183
8184 /* RSP = RBP */
8185 auto node1 = op1;
8186
8187 /* Create the symbolic expression */
8188 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, sp, "Stack Pointer");
8189
8190 /* Spread taint */
8191 expr1->isTainted = this->taintEngine->taintAssignment(sp, bp2);
8192
8193 /* Create symbolic operands */
8194 auto op2 = this->symbolicEngine->getOperandAst(inst, bp1);
8195
8196 /* RBP = pop() */
8197 auto node2 = op2;
8198
8199 /* Create the symbolic expression */
8200 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, bp2, "Stack Top Pointer");
8201
8202 /* Spread taint */
8203 expr2->isTainted = this->taintEngine->taintAssignment(bp2, bp1);
8204
8205 /* Create the semantics - side effect */
8206 alignAddStack_s(inst, bp1.getSize());
8207
8208 /* Update the symbolic control flow */
8209 this->controlFlow_s(inst);
8210 }
8211
8212
8213 void x86Semantics::lfence_s(triton::arch::Instruction& inst) {
8214 /* Update the symbolic control flow */
8215 this->controlFlow_s(inst);
8216 }
8217
8218
8219 void x86Semantics::lodsb_s(triton::arch::Instruction& inst) {
8220 auto& dst = inst.operands[0];
8221 auto& src = inst.operands[1];
8222 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
8223 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
8224 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
8225
8226 /* Check if there is a REP prefix and a counter to zero */
8227 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
8228 this->controlFlow_s(inst);
8229 return;
8230 }
8231
8232 /* Create symbolic operands */
8233 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
8234 auto op2 = this->symbolicEngine->getOperandAst(inst, index);
8235 auto op3 = this->symbolicEngine->getOperandAst(inst, df);
8236
8237 /* Create the semantics */
8238 auto node1 = op1;
8239 auto node2 = this->astCtxt->ite(
8240 this->astCtxt->equal(op3, this->astCtxt->bvfalse()),
8241 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::byte, index.getBitSize())),
8242 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::byte, index.getBitSize()))
8243 );
8244
8245 /* Create symbolic expression */
8246 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "LODSB operation");
8247 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
8248
8249 /* Spread taint */
8250 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
8251 expr2->isTainted = this->taintEngine->taintUnion(index, index);
8252
8253 /* Update the symbolic control flow */
8254 this->controlFlow_s(inst);
8255 }
8256
8257
8258 void x86Semantics::lodsd_s(triton::arch::Instruction& inst) {
8259 auto& dst = inst.operands[0];
8260 auto& src = inst.operands[1];
8261 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
8262 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
8263 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
8264
8265 /* Check if there is a REP prefix and a counter to zero */
8266 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
8267 this->controlFlow_s(inst);
8268 return;
8269 }
8270
8271 /* Create symbolic operands */
8272 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
8273 auto op2 = this->symbolicEngine->getOperandAst(inst, index);
8274 auto op3 = this->symbolicEngine->getOperandAst(inst, df);
8275
8276 /* Create the semantics */
8277 auto node1 = op1;
8278 auto node2 = this->astCtxt->ite(
8279 this->astCtxt->equal(op3, this->astCtxt->bvfalse()),
8280 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::dword, index.getBitSize())),
8281 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::dword, index.getBitSize()))
8282 );
8283
8284 /* Create symbolic expression */
8285 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "LODSD operation");
8286 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
8287
8288 /* Spread taint */
8289 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
8290 expr2->isTainted = this->taintEngine->taintUnion(index, index);
8291
8292 /* Update the symbolic control flow */
8293 this->controlFlow_s(inst);
8294 }
8295
8296
8297 void x86Semantics::lodsq_s(triton::arch::Instruction& inst) {
8298 auto& dst = inst.operands[0];
8299 auto& src = inst.operands[1];
8300 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
8301 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
8302 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
8303
8304 /* Check if there is a REP prefix and a counter to zero */
8305 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
8306 this->controlFlow_s(inst);
8307 return;
8308 }
8309
8310 /* Create symbolic operands */
8311 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
8312 auto op2 = this->symbolicEngine->getOperandAst(inst, index);
8313 auto op3 = this->symbolicEngine->getOperandAst(inst, df);
8314
8315 /* Create the semantics */
8316 auto node1 = op1;
8317 auto node2 = this->astCtxt->ite(
8318 this->astCtxt->equal(op3, this->astCtxt->bvfalse()),
8319 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::qword, index.getBitSize())),
8320 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::qword, index.getBitSize()))
8321 );
8322
8323 /* Create symbolic expression */
8324 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "LODSQ operation");
8325 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
8326
8327 /* Spread taint */
8328 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
8329 expr2->isTainted = this->taintEngine->taintUnion(index, index);
8330
8331 /* Update the symbolic control flow */
8332 this->controlFlow_s(inst);
8333 }
8334
8335
8336 void x86Semantics::lodsw_s(triton::arch::Instruction& inst) {
8337 auto& dst = inst.operands[0];
8338 auto& src = inst.operands[1];
8339 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
8340 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
8341 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
8342
8343 /* Check if there is a REP prefix and a counter to zero */
8344 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
8345 this->controlFlow_s(inst);
8346 return;
8347 }
8348
8349 /* Create symbolic operands */
8350 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
8351 auto op2 = this->symbolicEngine->getOperandAst(inst, index);
8352 auto op3 = this->symbolicEngine->getOperandAst(inst, df);
8353
8354 /* Create the semantics */
8355 auto node1 = op1;
8356 auto node2 = this->astCtxt->ite(
8357 this->astCtxt->equal(op3, this->astCtxt->bvfalse()),
8358 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::word, index.getBitSize())),
8359 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::word, index.getBitSize()))
8360 );
8361
8362 /* Create symbolic expression */
8363 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "LODSW operation");
8364 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
8365
8366 /* Spread taint */
8367 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
8368 expr2->isTainted = this->taintEngine->taintUnion(index, index);
8369
8370 /* Update the symbolic control flow */
8371 this->controlFlow_s(inst);
8372 }
8373
8374
8375 void x86Semantics::loop_s(triton::arch::Instruction& inst) {
8376 auto count = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
8377 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
8378 auto& src = inst.operands[0];
8379
8380 /* Create symbolic operands */
8381 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
8382 auto op2 = this->symbolicEngine->getOperandAst(inst, count);
8383
8384 /* Create the semantics */
8385 auto node1 = this->astCtxt->ite(
8386 this->astCtxt->equal(op2, this->astCtxt->bv(0, op2->getBitvectorSize())),
8387 this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize()),
8388 op1
8389 );
8390
8391 /* Create symbolic expression */
8392 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, pc, "Program Counter");
8393
8394 /* Set condition flag */
8395 if (op2->evaluate()) {
8396 inst.setConditionTaken(true);
8397 /* Spread taint */
8398 expr1->isTainted = this->taintEngine->taintAssignment(pc, count);
8399 }
8400 else {
8401 expr1->isTainted = this->taintEngine->taintAssignment(pc, src);
8402 }
8403
8404 /* Create the semantics */
8405 auto node2 = this->astCtxt->bvsub(op2, this->astCtxt->bv(1, op2->getBitvectorSize()));
8406
8407 /* Create symbolic expression */
8408 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, count, "LOOP counter operation");
8409
8410 /* Create the path constraint */
8411 this->symbolicEngine->pushPathConstraint(inst, expr1);
8412 }
8413
8414
8415 void x86Semantics::lzcnt_s(triton::arch::Instruction& inst) {
8416 auto& dst = inst.operands[0];
8417 auto& src = inst.operands[1];
8418 auto bvSize1 = dst.getBitSize();
8419 auto bvSize2 = src.getBitSize();
8420
8421 /* Create symbolic operands */
8422 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
8423
8424 /* Create the semantics */
8425 triton::ast::SharedAbstractNode node = nullptr;
8426 switch (src.getSize()) {
8427 case triton::size::byte:
8428 node = this->astCtxt->ite(
8429 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)),
8430 this->astCtxt->bv(bvSize2, bvSize1),
8431 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 1, bvSize2 - 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
8432 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 2, bvSize2 - 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
8433 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 3, bvSize2 - 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
8434 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 4, bvSize2 - 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
8435 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 5, bvSize2 - 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
8436 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 6, bvSize2 - 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
8437 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 7, bvSize2 - 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
8438 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 8, bvSize2 - 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
8439 this->astCtxt->bv(8, bvSize1))))))))));
8440 break;
8441 case triton::size::word:
8442 node = this->astCtxt->ite(
8443 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)),
8444 this->astCtxt->bv(bvSize2, bvSize1),
8445 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 1, bvSize2 - 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
8446 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 2, bvSize2 - 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
8447 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 3, bvSize2 - 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
8448 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 4, bvSize2 - 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
8449 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 5, bvSize2 - 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
8450 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 6, bvSize2 - 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
8451 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 7, bvSize2 - 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
8452 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 8, bvSize2 - 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
8453 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 9, bvSize2 - 9, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
8454 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 10, bvSize2 - 10, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
8455 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 11, bvSize2 - 11, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
8456 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 12, bvSize2 - 12, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
8457 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 13, bvSize2 - 13, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
8458 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 14, bvSize2 - 14, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
8459 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 15, bvSize2 - 15, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
8460 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 16, bvSize2 - 16, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
8461 this->astCtxt->bv(16, bvSize1))))))))))))))))));
8462 break;
8464 node = this->astCtxt->ite(
8465 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)),
8466 this->astCtxt->bv(bvSize2, bvSize1),
8467 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 1, bvSize2 - 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
8468 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 2, bvSize2 - 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
8469 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 3, bvSize2 - 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
8470 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 4, bvSize2 - 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
8471 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 5, bvSize2 - 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
8472 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 6, bvSize2 - 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
8473 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 7, bvSize2 - 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
8474 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 8, bvSize2 - 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
8475 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 9, bvSize2 - 9, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
8476 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 10, bvSize2 - 10, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
8477 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 11, bvSize2 - 11, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
8478 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 12, bvSize2 - 12, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
8479 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 13, bvSize2 - 13, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
8480 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 14, bvSize2 - 14, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
8481 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 15, bvSize2 - 15, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
8482 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 16, bvSize2 - 16, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
8483 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 17, bvSize2 - 17, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1),
8484 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 18, bvSize2 - 18, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1),
8485 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 19, bvSize2 - 19, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1),
8486 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 20, bvSize2 - 20, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1),
8487 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 21, bvSize2 - 21, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1),
8488 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 22, bvSize2 - 22, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1),
8489 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 23, bvSize2 - 23, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1),
8490 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 24, bvSize2 - 24, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1),
8491 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 25, bvSize2 - 25, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1),
8492 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 26, bvSize2 - 26, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1),
8493 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 27, bvSize2 - 27, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1),
8494 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 28, bvSize2 - 28, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1),
8495 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 29, bvSize2 - 29, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1),
8496 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 30, bvSize2 - 30, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1),
8497 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 31, bvSize2 - 31, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1),
8498 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 32, bvSize2 - 32, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1),
8499 this->astCtxt->bv(32, bvSize1))))))))))))))))))))))))))))))))));
8500 break;
8502 node = this->astCtxt->ite(
8503 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)),
8504 this->astCtxt->bv(bvSize2, bvSize1),
8505 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 1, bvSize2 - 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
8506 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 2, bvSize2 - 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
8507 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 3, bvSize2 - 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
8508 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 4, bvSize2 - 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
8509 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 5, bvSize2 - 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
8510 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 6, bvSize2 - 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
8511 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 7, bvSize2 - 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
8512 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 8, bvSize2 - 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
8513 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 9, bvSize2 - 9, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
8514 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 10, bvSize2 - 10, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
8515 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 11, bvSize2 - 11, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
8516 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 12, bvSize2 - 12, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
8517 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 13, bvSize2 - 13, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
8518 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 14, bvSize2 - 14, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
8519 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 15, bvSize2 - 15, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
8520 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 16, bvSize2 - 16, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
8521 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 17, bvSize2 - 17, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1),
8522 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 18, bvSize2 - 18, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1),
8523 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 19, bvSize2 - 19, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1),
8524 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 20, bvSize2 - 20, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1),
8525 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 21, bvSize2 - 21, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1),
8526 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 22, bvSize2 - 22, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1),
8527 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 23, bvSize2 - 23, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1),
8528 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 24, bvSize2 - 24, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1),
8529 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 25, bvSize2 - 25, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1),
8530 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 26, bvSize2 - 26, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1),
8531 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 27, bvSize2 - 27, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1),
8532 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 28, bvSize2 - 28, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1),
8533 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 29, bvSize2 - 29, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1),
8534 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 30, bvSize2 - 30, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1),
8535 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 31, bvSize2 - 31, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1),
8536 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 32, bvSize2 - 32, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1),
8537 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 33, bvSize2 - 33, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(32, bvSize1),
8538 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 34, bvSize2 - 34, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(33, bvSize1),
8539 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 35, bvSize2 - 35, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(34, bvSize1),
8540 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 36, bvSize2 - 36, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(35, bvSize1),
8541 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 37, bvSize2 - 37, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(36, bvSize1),
8542 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 38, bvSize2 - 38, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(37, bvSize1),
8543 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 39, bvSize2 - 39, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(38, bvSize1),
8544 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 40, bvSize2 - 40, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(39, bvSize1),
8545 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 41, bvSize2 - 41, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(40, bvSize1),
8546 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 42, bvSize2 - 42, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(41, bvSize1),
8547 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 43, bvSize2 - 43, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(42, bvSize1),
8548 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 44, bvSize2 - 44, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(43, bvSize1),
8549 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 45, bvSize2 - 45, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(44, bvSize1),
8550 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 46, bvSize2 - 46, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(45, bvSize1),
8551 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 47, bvSize2 - 47, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(46, bvSize1),
8552 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 48, bvSize2 - 48, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(47, bvSize1),
8553 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 49, bvSize2 - 49, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(48, bvSize1),
8554 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 50, bvSize2 - 50, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(49, bvSize1),
8555 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 51, bvSize2 - 51, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(50, bvSize1),
8556 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 52, bvSize2 - 52, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(51, bvSize1),
8557 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 53, bvSize2 - 53, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(52, bvSize1),
8558 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 54, bvSize2 - 54, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(53, bvSize1),
8559 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 55, bvSize2 - 55, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(54, bvSize1),
8560 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 56, bvSize2 - 56, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(55, bvSize1),
8561 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 57, bvSize2 - 57, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(56, bvSize1),
8562 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 58, bvSize2 - 58, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(57, bvSize1),
8563 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 59, bvSize2 - 59, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(58, bvSize1),
8564 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 60, bvSize2 - 60, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(59, bvSize1),
8565 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 61, bvSize2 - 61, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(60, bvSize1),
8566 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 62, bvSize2 - 62, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(61, bvSize1),
8567 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 63, bvSize2 - 63, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(62, bvSize1),
8568 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 64, bvSize2 - 64, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(63, bvSize1),
8569 this->astCtxt->bv(64, bvSize1))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));
8570 break;
8571 default:
8572 throw triton::exceptions::Semantics("x86Semantics::lzcnt_s(): Invalid operand size.");
8573 }
8574
8575 /* Create symbolic expression */
8576 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "LZCNT operation");
8577
8578 /* Spread taint */
8579 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8580
8581 /* Update symbolic flags */
8582 this->cfLzcnt_s(inst, expr, src, op1);
8583 this->zf_s(inst, expr, src);
8584
8585 /* Tag undefined flags */
8586 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
8587 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
8588 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
8589 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
8590
8591 /* Update the symbolic control flow */
8592 this->controlFlow_s(inst);
8593 }
8594
8595
8596 void x86Semantics::int3_s(triton::arch::Instruction& inst) {
8597 /* Return a breakpoint fault */
8598 this->exception = triton::arch::FAULT_BP;
8599 }
8600
8601
8602 void x86Semantics::mfence_s(triton::arch::Instruction& inst) {
8603 /* Update the symbolic control flow */
8604 this->controlFlow_s(inst);
8605 }
8606
8607
8608 void x86Semantics::mov_s(triton::arch::Instruction& inst) {
8609 auto& dst = inst.operands[0];
8610 auto& src = inst.operands[1];
8611 bool undef = false;
8612
8613 /* Create the semantics */
8614 auto node = this->symbolicEngine->getOperandAst(inst, src);
8615
8616 /*
8617 * Special cases:
8618 *
8619 * Triton defines segment registers as 32 or 64 bits vector to
8620 * avoid to simulate the GDT which allows users to directly define
8621 * their segments offset.
8622 *
8623 * The code below, handles the case: MOV r/m{16/32/64}, Sreg
8624 */
8625 if (src.getType() == triton::arch::OP_REG) {
8626 uint32 id = src.getConstRegister().getId();
8627 if (id >= triton::arch::ID_REG_X86_CS && id <= triton::arch::ID_REG_X86_SS) {
8628 node = this->astCtxt->extract(dst.getBitSize()-1, 0, node);
8629 }
8630 if (id >= triton::arch::ID_REG_X86_CR0 && id <= triton::arch::ID_REG_X86_CR15) {
8631 undef = true;
8632 }
8633 }
8634
8635 /*
8636 * The code below, handles the case: MOV Sreg, r/m{16/32/64}
8637 */
8638 if (dst.getType() == triton::arch::OP_REG) {
8639 uint32 id = dst.getConstRegister().getId();
8640 if (id >= triton::arch::ID_REG_X86_CS && id <= triton::arch::ID_REG_X86_SS) {
8641 node = this->astCtxt->extract(triton::bitsize::word-1, 0, node);
8642 }
8643 if (id >= triton::arch::ID_REG_X86_CR0 && id <= triton::arch::ID_REG_X86_CR15) {
8644 undef = true;
8645 }
8646 }
8647
8648 /* Create symbolic expression */
8649 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOV operation");
8650
8651 /* Spread taint */
8652 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8653
8654 /* Tag undefined flags */
8655 if (undef) {
8656 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
8657 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
8658 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
8659 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
8660 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
8661 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF));
8662 }
8663
8664 /* Update the symbolic control flow */
8665 this->controlFlow_s(inst);
8666 }
8667
8668
8669 void x86Semantics::movabs_s(triton::arch::Instruction& inst) {
8670 auto& dst = inst.operands[0];
8671 auto& src = inst.operands[1];
8672
8673 /* Create the semantics */
8674 auto node = this->symbolicEngine->getOperandAst(inst, src);
8675
8676 /* Create symbolic expression */
8677 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVABS operation");
8678
8679 /* Spread taint */
8680 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8681
8682 /* Update the symbolic control flow */
8683 this->controlFlow_s(inst);
8684 }
8685
8686
8687 void x86Semantics::movapd_s(triton::arch::Instruction& inst) {
8688 auto& dst = inst.operands[0];
8689 auto& src = inst.operands[1];
8690
8691 /* Create the semantics */
8692 auto node = this->symbolicEngine->getOperandAst(inst, src);
8693
8694 /* Create symbolic expression */
8695 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVAPD operation");
8696
8697 /* Spread taint */
8698 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8699
8700 /* Update the symbolic control flow */
8701 this->controlFlow_s(inst);
8702 }
8703
8704
8705 void x86Semantics::movaps_s(triton::arch::Instruction& inst) {
8706 auto& dst = inst.operands[0];
8707 auto& src = inst.operands[1];
8708
8709 /* Create the semantics */
8710 auto node = this->symbolicEngine->getOperandAst(inst, src);
8711
8712 /* Create symbolic expression */
8713 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVAPS operation");
8714
8715 /* Spread taint */
8716 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8717
8718 /* Update the symbolic control flow */
8719 this->controlFlow_s(inst);
8720 }
8721
8722
8723 void x86Semantics::movbe_s(triton::arch::Instruction& inst) {
8724 auto &dst = inst.operands[0];
8725 auto &src = inst.operands[1];
8726
8727 /* Create symbolic operands */
8728 auto op = this->symbolicEngine->getOperandAst(inst, src);
8729
8730 /* Create the semantics */
8731 std::vector<triton::ast::SharedAbstractNode> exprs;
8732 for (size_t i = 0; i < src.getSize(); ++i) {
8733 exprs.push_back(this->astCtxt->extract(triton::bitsize::byte * i + (triton::bitsize::byte - 1),
8735 op));
8736 }
8737 auto node = this->astCtxt->concat(exprs);
8738
8739 /* Create symbolic expression */
8740 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVBE operation");
8741
8742 /* Spread taint */
8743 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8744
8745 /* Update the symbolic control flow */
8746 this->controlFlow_s(inst);
8747 }
8748
8749
8750 void x86Semantics::movd_s(triton::arch::Instruction& inst) {
8751 auto& dst = inst.operands[0];
8752 auto& src = inst.operands[1];
8753
8754 /* Create symbolic operands */
8755 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
8756
8757 /* Create the semantics */
8758 triton::ast::SharedAbstractNode node = nullptr;
8759
8760 switch (dst.getBitSize()) {
8761 /* GPR 32-bits */
8763 node = this->astCtxt->extract(triton::bitsize::dword-1, 0, op2);
8764 break;
8765
8766 /* MMX 64-bits */
8768 node = this->astCtxt->zx(triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::dword-1, 0, op2));
8769 break;
8770
8771 /* XMM 128-bits */
8773 node = this->astCtxt->zx(triton::bitsize::qword + triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::dword-1, 0, op2));
8774 break;
8775 }
8776
8777 /* Create symbolic expression */
8778 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVD operation");
8779
8780 /* Update the x87 FPU Tag Word */
8781 if (dst.getBitSize() == triton::bitsize::qword) {
8782 this->updateFTW(inst, expr);
8783 }
8784
8785 /* Spread taint */
8786 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8787
8788 /* Update the symbolic control flow */
8789 this->controlFlow_s(inst);
8790 }
8791
8792
8793 void x86Semantics::movddup_s(triton::arch::Instruction& inst) {
8794 auto& dst = inst.operands[0];
8795 auto& src = inst.operands[1];
8796
8797 /* Create symbolic operands */
8798 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
8799
8800 /* Create the semantics */
8801 auto node = this->astCtxt->concat(this->astCtxt->extract(triton::bitsize::qword-1, 0, op2), this->astCtxt->extract(triton::bitsize::qword-1, 0, op2));
8802
8803 /* Create symbolic expression */
8804 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVDDUP operation");
8805
8806 /* Spread taint */
8807 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8808
8809 /* Update the symbolic control flow */
8810 this->controlFlow_s(inst);
8811 }
8812
8813
8814 void x86Semantics::movdq2q_s(triton::arch::Instruction& inst) {
8815 auto& dst = inst.operands[0];
8816 auto& src = inst.operands[1];
8817
8818 /* Create symbolic operands */
8819 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
8820
8821 /* Create the semantics */
8822 auto node = this->astCtxt->extract(triton::bitsize::qword-1, 0, op2);
8823
8824 /* Create symbolic expression */
8825 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVDQ2Q operation");
8826
8827 /* Spread taint */
8828 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8829
8830 /* Update the symbolic control flow */
8831 this->controlFlow_s(inst);
8832 }
8833
8834
8835 void x86Semantics::movdqa_s(triton::arch::Instruction& inst) {
8836 auto& dst = inst.operands[0];
8837 auto& src = inst.operands[1];
8838
8839 /* Create the semantics */
8840 auto node = this->symbolicEngine->getOperandAst(inst, src);
8841
8842 /* Create symbolic expression */
8843 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVDQA operation");
8844
8845 /* Spread taint */
8846 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8847
8848 /* Update the symbolic control flow */
8849 this->controlFlow_s(inst);
8850 }
8851
8852
8853 void x86Semantics::movdqu_s(triton::arch::Instruction& inst) {
8854 auto& dst = inst.operands[0];
8855 auto& src = inst.operands[1];
8856
8857 /* Create the semantics */
8858 auto node = this->symbolicEngine->getOperandAst(inst, src);
8859
8860 /* Create symbolic expression */
8861 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVDQU operation");
8862
8863 /* Spread taint */
8864 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
8865
8866 /* Update the symbolic control flow */
8867 this->controlFlow_s(inst);
8868 }
8869
8870
8871 void x86Semantics::movhlps_s(triton::arch::Instruction& inst) {
8872 auto& dst = inst.operands[0];
8873 auto& src = inst.operands[1];
8874
8875 /* Create symbolic operands */
8876 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
8877 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
8878
8879 /* Create the semantics */
8880 auto node = this->astCtxt->concat(
8881 this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, op1), /* Destination[127..64] unchanged */
8882 this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, op2) /* Destination[63..0] = Source[127..64]; */
8883 );
8884
8885 /* Create symbolic expression */
8886 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVHLPS operation");
8887
8888 /* Spread taint */
8889 expr->isTainted = this->taintEngine->taintUnion(dst, src);
8890
8891 /* Update the symbolic control flow */
8892 this->controlFlow_s(inst);
8893 }
8894
8895
8896 void x86Semantics::movhpd_s(triton::arch::Instruction& inst) {
8897 auto& dst = inst.operands[0];
8898 auto& src = inst.operands[1];
8899
8900 /* Create symbolic operands */
8901 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
8902 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
8903
8904 /* Create the semantics */
8905 triton::ast::SharedAbstractNode node = nullptr;
8906
8907 /* xmm, m64 */
8908 if (dst.getSize() == triton::size::dqword) {
8909 node = this->astCtxt->concat(
8910 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2), /* Destination[127..64] = Source */
8911 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op1) /* Destination[63..0] unchanged */
8912 );
8913 }
8914
8915 /* m64, xmm */
8916 else {
8917 node = this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, op2); /* Destination[63..00] = Source[127..64] */
8918 }
8919
8920 /* Create symbolic expression */
8921 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVHPD operation");
8922
8923 /* Spread taint */
8924 expr->isTainted = this->taintEngine->taintUnion(dst, src);
8925
8926 /* Update the symbolic control flow */
8927 this->controlFlow_s(inst);
8928 }
8929
8930
8931 void x86Semantics::movhps_s(triton::arch::Instruction& inst) {
8932 auto& dst = inst.operands[0];
8933 auto& src = inst.operands[1];
8934
8935 /* Create symbolic operands */
8936 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
8937 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
8938
8939 /* Create the semantics */
8940 triton::ast::SharedAbstractNode node = nullptr;
8941
8942 /* xmm, m64 */
8943 if (dst.getSize() == triton::size::dqword) {
8944 node = this->astCtxt->concat(
8945 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2), /* Destination[127..64] = Source */
8946 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op1) /* Destination[63..0] unchanged */
8947 );
8948 }
8949
8950 /* m64, xmm */
8951 else {
8952 node = this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, op2); /* Destination[63..00] = Source[127..64] */
8953 }
8954
8955 /* Create symbolic expression */
8956 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVHPS operation");
8957
8958 /* Spread taint */
8959 expr->isTainted = this->taintEngine->taintUnion(dst, src);
8960
8961 /* Update the symbolic control flow */
8962 this->controlFlow_s(inst);
8963 }
8964
8965
8966 void x86Semantics::movlhps_s(triton::arch::Instruction& inst) {
8967 auto& dst = inst.operands[0];
8968 auto& src = inst.operands[1];
8969
8970 /* Create symbolic operands */
8971 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
8972 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
8973
8974 /* Create the semantics */
8975 auto node = this->astCtxt->concat(
8976 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2), /* Destination[127..64] = Source[63..0] */
8977 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op1) /* Destination[63..0] unchanged */
8978 );
8979
8980 /* Create symbolic expression */
8981 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVLHPS operation");
8982
8983 /* Spread taint */
8984 expr->isTainted = this->taintEngine->taintUnion(dst, src);
8985
8986 /* Update the symbolic control flow */
8987 this->controlFlow_s(inst);
8988 }
8989
8990
8991 void x86Semantics::movlpd_s(triton::arch::Instruction& inst) {
8992 auto& dst = inst.operands[0];
8993 auto& src = inst.operands[1];
8994
8995 /* Create symbolic operands */
8996 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
8997 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
8998
8999 /* Create the semantics */
9000 triton::ast::SharedAbstractNode node = nullptr;
9001
9002 /* xmm, m64 */
9003 if (dst.getSize() == triton::size::dqword) {
9004 node = this->astCtxt->concat(
9005 this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, op1), /* Destination[127..64] unchanged */
9006 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2) /* Destination[63..0] = Source */
9007 );
9008 }
9009
9010 /* m64, xmm */
9011 else {
9012 node = this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2); /* Destination = Source[63..00] */
9013 }
9014
9015 /* Create symbolic expression */
9016 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVLPD operation");
9017
9018 /* Spread taint */
9019 expr->isTainted = this->taintEngine->taintUnion(dst, src);
9020
9021 /* Update the symbolic control flow */
9022 this->controlFlow_s(inst);
9023 }
9024
9025
9026 void x86Semantics::movlps_s(triton::arch::Instruction& inst) {
9027 auto& dst = inst.operands[0];
9028 auto& src = inst.operands[1];
9029
9030 /* Create symbolic operands */
9031 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
9032 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9033
9034 /* Create the semantics */
9035 triton::ast::SharedAbstractNode node = nullptr;
9036
9037 /* xmm, m64 */
9038 if (dst.getSize() == triton::size::dqword) {
9039 node = this->astCtxt->concat(
9040 this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, op1), /* Destination[127..64] unchanged */
9041 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2) /* Destination[63..0] = Source */
9042 );
9043 }
9044
9045 /* m64, xmm */
9046 else {
9047 node = this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2); /* Destination = Source[63..00] */
9048 }
9049
9050 /* Create symbolic expression */
9051 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVLPS operation");
9052
9053 /* Spread taint */
9054 expr->isTainted = this->taintEngine->taintUnion(dst, src);
9055
9056 /* Update the symbolic control flow */
9057 this->controlFlow_s(inst);
9058 }
9059
9060
9061 void x86Semantics::movmskpd_s(triton::arch::Instruction& inst) {
9062 auto& dst = inst.operands[0];
9063 auto& src = inst.operands[1];
9064
9065 /* Create symbolic operands */
9066 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9067
9068 /* Create the semantics */
9069 auto node = this->astCtxt->zx(30, /* Destination[2..31] = 0 */
9070 this->astCtxt->concat(
9071 this->astCtxt->extract(127, 127, op2), /* Destination[1] = Source[127]; */
9072 this->astCtxt->extract(63, 63, op2) /* Destination[0] = Source[63]; */
9073 )
9074 );
9075
9076 /* Create symbolic expression */
9077 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVMSKPD operation");
9078
9079 /* Spread taint */
9080 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9081
9082 /* Update the symbolic control flow */
9083 this->controlFlow_s(inst);
9084 }
9085
9086
9087 void x86Semantics::movmskps_s(triton::arch::Instruction& inst) {
9088 auto& dst = inst.operands[0];
9089 auto& src = inst.operands[1];
9090
9091 /* Create symbolic operands */
9092 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9093
9094 /* Create the semantics */
9095 std::vector<triton::ast::SharedAbstractNode> signs;
9096 signs.reserve(4);
9097
9098 signs.push_back(this->astCtxt->extract(127, 127, op2)); /* Destination[3] = Source[127]; */
9099 signs.push_back(this->astCtxt->extract(95, 95, op2)); /* Destination[2] = Source[95]; */
9100 signs.push_back(this->astCtxt->extract(63, 63, op2)); /* Destination[1] = Source[63]; */
9101 signs.push_back(this->astCtxt->extract(31, 31, op2)); /* Destination[0] = Source[31]; */
9102
9103 auto node = this->astCtxt->zx(28, this->astCtxt->concat(signs));
9104
9105 /* Create symbolic expression */
9106 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVMSKPS operation");
9107
9108 /* Spread taint */
9109 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9110
9111 /* Update the symbolic control flow */
9112 this->controlFlow_s(inst);
9113 }
9114
9115
9116 void x86Semantics::movntdq_s(triton::arch::Instruction& inst) {
9117 auto& dst = inst.operands[0];
9118 auto& src = inst.operands[1];
9119
9120 /* Create the semantics */
9121 auto node = this->symbolicEngine->getOperandAst(inst, src);
9122
9123 /* Create symbolic expression */
9124 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVNTDQ operation");
9125
9126 /* Spread taint */
9127 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9128
9129 /* Update the symbolic control flow */
9130 this->controlFlow_s(inst);
9131 }
9132
9133
9134 void x86Semantics::movnti_s(triton::arch::Instruction& inst) {
9135 auto& dst = inst.operands[0];
9136 auto& src = inst.operands[1];
9137
9138 /* Create the semantics */
9139 auto node = this->symbolicEngine->getOperandAst(inst, src);
9140
9141 /* Create symbolic expression */
9142 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVNTI operation");
9143
9144 /* Spread taint */
9145 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9146
9147 /* Update the symbolic control flow */
9148 this->controlFlow_s(inst);
9149 }
9150
9151
9152 void x86Semantics::movntpd_s(triton::arch::Instruction& inst) {
9153 auto& dst = inst.operands[0];
9154 auto& src = inst.operands[1];
9155
9156 /* Create the semantics */
9157 auto node = this->symbolicEngine->getOperandAst(inst, src);
9158
9159 /* Create symbolic expression */
9160 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVNTPD operation");
9161
9162 /* Spread taint */
9163 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9164
9165 /* Update the symbolic control flow */
9166 this->controlFlow_s(inst);
9167 }
9168
9169
9170 void x86Semantics::movntps_s(triton::arch::Instruction& inst) {
9171 auto& dst = inst.operands[0];
9172 auto& src = inst.operands[1];
9173
9174 /* Create the semantics */
9175 auto node = this->symbolicEngine->getOperandAst(inst, src);
9176
9177 /* Create symbolic expression */
9178 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVNTPS operation");
9179
9180 /* Spread taint */
9181 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9182
9183 /* Update the symbolic control flow */
9184 this->controlFlow_s(inst);
9185 }
9186
9187
9188 void x86Semantics::movntq_s(triton::arch::Instruction& inst) {
9189 auto& dst = inst.operands[0];
9190 auto& src = inst.operands[1];
9191
9192 /* Create the semantics */
9193 auto node = this->symbolicEngine->getOperandAst(inst, src);
9194
9195 /* Create symbolic expression */
9196 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVNTQ operation");
9197
9198 /* Spread taint */
9199 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9200
9201 /* Update the symbolic control flow */
9202 this->controlFlow_s(inst);
9203 }
9204
9205
9206 void x86Semantics::movshdup_s(triton::arch::Instruction& inst) {
9207 auto& dst = inst.operands[0];
9208 auto& src = inst.operands[1];
9209
9210 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9211
9212 /* Create the semantics */
9213 std::vector<triton::ast::SharedAbstractNode> bytes;
9214 bytes.reserve(4);
9215
9216 bytes.push_back(this->astCtxt->extract(127, 96, op2));
9217 bytes.push_back(this->astCtxt->extract(127, 96, op2));
9218 bytes.push_back(this->astCtxt->extract(63, 32, op2));
9219 bytes.push_back(this->astCtxt->extract(63, 32, op2));
9220
9221 auto node = this->astCtxt->concat(bytes);
9222
9223 /* Create symbolic expression */
9224 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSHDUP operation");
9225
9226 /* Spread taint */
9227 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9228
9229 /* Update the symbolic control flow */
9230 this->controlFlow_s(inst);
9231 }
9232
9233
9234 void x86Semantics::movsldup_s(triton::arch::Instruction& inst) {
9235 auto& dst = inst.operands[0];
9236 auto& src = inst.operands[1];
9237
9238 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9239
9240 /* Create the semantics */
9241 std::vector<triton::ast::SharedAbstractNode> bytes;
9242 bytes.reserve(4);
9243
9244 bytes.push_back(this->astCtxt->extract(95, 64, op2));
9245 bytes.push_back(this->astCtxt->extract(95, 64, op2));
9246 bytes.push_back(this->astCtxt->extract(31, 0, op2));
9247 bytes.push_back(this->astCtxt->extract(31, 0, op2));
9248
9249 auto node = this->astCtxt->concat(bytes);
9250
9251 /* Create symbolic expression */
9252 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSLDUP operation");
9253
9254 /* Spread taint */
9255 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9256
9257 /* Update the symbolic control flow */
9258 this->controlFlow_s(inst);
9259 }
9260
9261
9262 void x86Semantics::movq_s(triton::arch::Instruction& inst) {
9263 auto& dst = inst.operands[0];
9264 auto& src = inst.operands[1];
9265
9266 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9267
9268 /* Create the semantics */
9269 triton::ast::SharedAbstractNode node = nullptr;
9270
9271 /* when operating on MMX technology registers and memory locations */
9273 node = op2;
9274 }
9275
9276 /* when source and destination operands are XMM registers */
9278 node = this->astCtxt->concat(
9279 this->astCtxt->extract(triton::bitsize::dqword-1, triton::bitsize::qword, this->symbolicEngine->getOperandAst(inst, dst)),
9280 this->astCtxt->extract(triton::bitsize::qword-1, 0, op2)
9281 );
9282 }
9283
9284 /* when source operand is XMM register and destination operand is memory location */
9285 else if (dst.getBitSize() < src.getBitSize()) {
9286 node = this->astCtxt->extract(triton::bitsize::qword-1, 0, op2);
9287 }
9288
9289 /* when source operand is memory location and destination operand is XMM register */
9290 else if (dst.getBitSize() > src.getBitSize()) {
9291 node = this->astCtxt->zx(triton::bitsize::qword, op2);
9292 }
9293
9294 /* Invalid operation */
9295 else {
9296 throw triton::exceptions::Semantics("x86Semantics::movq_s(): Invalid operation.");
9297 }
9298
9299 /* Create symbolic expression */
9300 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVQ operation");
9301
9302 /* Update the x87 FPU Tag Word */
9304 this->updateFTW(inst, expr);
9305 }
9306
9307 /* Spread taint */
9309 expr->isTainted = this->taintEngine->taintUnion(dst, src);
9310 else
9311 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9312
9313 /* Update the symbolic control flow */
9314 this->controlFlow_s(inst);
9315 }
9316
9317
9318 void x86Semantics::movq2dq_s(triton::arch::Instruction& inst) {
9319 auto& dst = inst.operands[0];
9320 auto& src = inst.operands[1];
9321
9322 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9323
9324 /* Create the semantics */
9325 auto node = this->astCtxt->zx(triton::bitsize::qword, op2);
9326
9327 /* Create symbolic expression */
9328 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVQ2DQ operation");
9329
9330 /* 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] */
9331
9332 /* Spread taint */
9333 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9334
9335 /* Update the symbolic control flow */
9336 this->controlFlow_s(inst);
9337 }
9338
9339
9340 void x86Semantics::movsb_s(triton::arch::Instruction& inst) {
9341 auto& dst = inst.operands[0];
9342 auto& src = inst.operands[1];
9343 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
9344 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
9345 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
9346 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
9347
9348 /* Check if there is a REP prefix and a counter to zero */
9349 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
9350 this->controlFlow_s(inst);
9351 return;
9352 }
9353
9354 /* Create symbolic operands */
9355 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9356 auto op2 = this->symbolicEngine->getOperandAst(inst, index1);
9357 auto op3 = this->symbolicEngine->getOperandAst(inst, index2);
9358 auto op4 = this->symbolicEngine->getOperandAst(inst, df);
9359
9360 /* Create the semantics */
9361 auto node1 = op1;
9362 auto node2 = this->astCtxt->ite(
9363 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
9364 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::byte, index1.getBitSize())),
9365 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::byte, index1.getBitSize()))
9366 );
9367 auto node3 = this->astCtxt->ite(
9368 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
9369 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::byte, index2.getBitSize())),
9370 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::byte, index2.getBitSize()))
9371 );
9372
9373 /* Create symbolic expression */
9374 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "MOVSB operation");
9375 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (DI) operation");
9376 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (SI) operation");
9377
9378 /* Spread taint */
9379 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
9380 expr2->isTainted = this->taintEngine->taintUnion(index1, index1);
9381 expr3->isTainted = this->taintEngine->taintUnion(index2, index2);
9382
9383 /* Update the symbolic control flow */
9384 this->controlFlow_s(inst);
9385 }
9386
9387
9388 void x86Semantics::movsd_s(triton::arch::Instruction& inst) {
9389 auto& dst = inst.operands[0];
9390 auto& src = inst.operands[1];
9391 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
9392 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
9393 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
9394 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
9395
9396 /* Check if there is a REP prefix and a counter to zero */
9397 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
9398 this->controlFlow_s(inst);
9399 return;
9400 }
9401
9402 /*
9403 * F2 0F 10 /r MOVSD xmm1, xmm2
9404 * F2 0F 10 /r MOVSD xmm1, m64
9405 */
9406 if (dst.getBitSize() == triton::bitsize::dqword) {
9407 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9408 auto op2 = this->symbolicEngine->getOperandAst(dst);
9409
9410 auto node = this->astCtxt->concat(
9411 this->astCtxt->extract(127, 64, op2),
9412 this->astCtxt->extract(63, 0, op1)
9413 );
9414
9415 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSD operation");
9416 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9417 }
9418
9419 /*
9420 * F2 0F 11 /r MOVSD m64, xmm2
9421 */
9423 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9424 auto node = this->astCtxt->extract(63, 0, op1);
9425 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSD operation");
9426 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9427 }
9428
9429 /* A5 MOVSD */
9430 else {
9431 /* Create symbolic operands */
9432 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9433 auto op2 = this->symbolicEngine->getOperandAst(inst, index1);
9434 auto op3 = this->symbolicEngine->getOperandAst(inst, index2);
9435 auto op4 = this->symbolicEngine->getOperandAst(inst, df);
9436
9437 /* Create the semantics */
9438 auto node1 = op1;
9439 auto node2 = this->astCtxt->ite(
9440 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
9441 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::dword, index1.getBitSize())),
9442 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::dword, index1.getBitSize()))
9443 );
9444 auto node3 = this->astCtxt->ite(
9445 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
9446 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::dword, index2.getBitSize())),
9447 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::dword, index2.getBitSize()))
9448 );
9449
9450 /* Create symbolic expression */
9451 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "MOVSD operation");
9452 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (DI) operation");
9453 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (SI) operation");
9454
9455 /* Spread taint */
9456 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
9457 expr2->isTainted = this->taintEngine->taintUnion(index1, index1);
9458 expr3->isTainted = this->taintEngine->taintUnion(index2, index2);
9459 }
9460
9461 /* Update the symbolic control flow */
9462 this->controlFlow_s(inst);
9463 }
9464
9465
9466 void x86Semantics::movupd_s(triton::arch::Instruction& inst) {
9467 auto& dst = inst.operands[0];
9468 auto& src = inst.operands[1];
9469
9470 /* Create the semantics */
9471 auto node = this->symbolicEngine->getOperandAst(inst, src);
9472
9473 /* Create symbolic expression */
9474 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVUPD operation");
9475
9476 /* Spread taint */
9477 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9478
9479 /* Update the symbolic control flow */
9480 this->controlFlow_s(inst);
9481 }
9482
9483
9484 void x86Semantics::movups_s(triton::arch::Instruction& inst) {
9485 auto& dst = inst.operands[0];
9486 auto& src = inst.operands[1];
9487
9488 /* Create the semantics */
9489 auto node = this->symbolicEngine->getOperandAst(inst, src);
9490
9491 /* Create symbolic expression */
9492 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVUPS operation");
9493
9494 /* Spread taint */
9495 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9496
9497 /* Update the symbolic control flow */
9498 this->controlFlow_s(inst);
9499 }
9500
9501
9502 void x86Semantics::movss_s(triton::arch::Instruction& inst) {
9503 auto& dst = inst.operands[0];
9504 auto& src = inst.operands[1];
9505
9506 /* Create symbolic operands */
9507 auto op = this->symbolicEngine->getOperandAst(inst, src);
9508
9509 /* Create the semantics */
9510 auto node = op;
9511 if (src.getType() == OP_REG) {
9512 node = this->astCtxt->extract(triton::bitsize::dword - 1, 0, node);
9513 if (dst.getType() == OP_REG) {
9514 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
9515 auto upper = this->astCtxt->extract(triton::bitsize::dqword - 1, triton::bitsize::dword, op1);
9516 node = this->astCtxt->concat(upper, node);
9517 }
9518 }
9519
9520 /* Create symbolic expression */
9521 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSS operation");
9522
9523 /* Spread taint */
9524 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9525
9526 /* Update the symbolic control flow */
9527 this->controlFlow_s(inst);
9528 }
9529
9530
9531 void x86Semantics::movsq_s(triton::arch::Instruction& inst) {
9532 auto& dst = inst.operands[0];
9533 auto& src = inst.operands[1];
9534 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
9535 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
9536 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
9537 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
9538
9539 /* Check if there is a REP prefix and a counter to zero */
9540 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
9541 this->controlFlow_s(inst);
9542 return;
9543 }
9544
9545 /* Create symbolic operands */
9546 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9547 auto op2 = this->symbolicEngine->getOperandAst(inst, index1);
9548 auto op3 = this->symbolicEngine->getOperandAst(inst, index2);
9549 auto op4 = this->symbolicEngine->getOperandAst(inst, df);
9550
9551 /* Create the semantics */
9552 auto node1 = op1;
9553 auto node2 = this->astCtxt->ite(
9554 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
9555 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::qword, index1.getBitSize())),
9556 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::qword, index1.getBitSize()))
9557 );
9558 auto node3 = this->astCtxt->ite(
9559 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
9560 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::qword, index2.getBitSize())),
9561 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::qword, index2.getBitSize()))
9562 );
9563
9564 /* Create symbolic expression */
9565 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "MOVSQ operation");
9566 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (DI) operation");
9567 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (SI) operation");
9568
9569 /* Spread taint */
9570 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
9571 expr2->isTainted = this->taintEngine->taintUnion(index1, index1);
9572 expr3->isTainted = this->taintEngine->taintUnion(index2, index2);
9573
9574 /* Update the symbolic control flow */
9575 this->controlFlow_s(inst);
9576 }
9577
9578
9579 void x86Semantics::movsw_s(triton::arch::Instruction& inst) {
9580 auto& dst = inst.operands[0];
9581 auto& src = inst.operands[1];
9582 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
9583 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI));
9584 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
9585 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
9586
9587 /* Check if there is a REP prefix and a counter to zero */
9588 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
9589 this->controlFlow_s(inst);
9590 return;
9591 }
9592
9593 /* Create symbolic operands */
9594 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9595 auto op2 = this->symbolicEngine->getOperandAst(inst, index1);
9596 auto op3 = this->symbolicEngine->getOperandAst(inst, index2);
9597 auto op4 = this->symbolicEngine->getOperandAst(inst, df);
9598
9599 /* Create the semantics */
9600 auto node1 = op1;
9601 auto node2 = this->astCtxt->ite(
9602 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
9603 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::word, index1.getBitSize())),
9604 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::word, index1.getBitSize()))
9605 );
9606 auto node3 = this->astCtxt->ite(
9607 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
9608 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::word, index2.getBitSize())),
9609 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::word, index2.getBitSize()))
9610 );
9611
9612 /* Create symbolic expression */
9613 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "MOVSW operation");
9614 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (DI) operation");
9615 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (SI) operation");
9616
9617 /* Spread taint */
9618 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
9619 expr2->isTainted = this->taintEngine->taintUnion(index1, index1);
9620 expr3->isTainted = this->taintEngine->taintUnion(index2, index2);
9621
9622 /* Update the symbolic control flow */
9623 this->controlFlow_s(inst);
9624 }
9625
9626
9627 void x86Semantics::movsx_s(triton::arch::Instruction& inst) {
9628 auto& dst = inst.operands[0];
9629 auto& src = inst.operands[1];
9630
9631 /* Create symbolic operands */
9632 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9633
9634 /* Create the semantics */
9635 auto node = this->astCtxt->sx(dst.getBitSize() - src.getBitSize(), op1);
9636
9637 /* Create symbolic expression */
9638 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSX operation");
9639
9640 /* Spread taint */
9641 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9642
9643 /* Update the symbolic control flow */
9644 this->controlFlow_s(inst);
9645 }
9646
9647
9648 void x86Semantics::movsxd_s(triton::arch::Instruction& inst) {
9649 auto& dst = inst.operands[0];
9650 auto& src = inst.operands[1];
9651
9652 /* Create symbolic operands */
9653 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9654
9655 /* Create the semantics */
9656 auto node = this->astCtxt->sx(dst.getBitSize() - src.getBitSize(), op1);
9657
9658 /* Create symbolic expression */
9659 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSXD operation");
9660
9661 /* Spread taint */
9662 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9663
9664 /* Update the symbolic control flow */
9665 this->controlFlow_s(inst);
9666 }
9667
9668
9669 void x86Semantics::movzx_s(triton::arch::Instruction& inst) {
9670 auto& dst = inst.operands[0];
9671 auto& src = inst.operands[1];
9672
9673 /* Create symbolic operands */
9674 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9675
9676 /* Create the semantics */
9677 auto node = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), op1);
9678
9679 /* Create symbolic expression */
9680 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVZX operation");
9681
9682 /* Spread taint */
9683 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
9684
9685 /* Update the symbolic control flow */
9686 this->controlFlow_s(inst);
9687 }
9688
9689
9690 void x86Semantics::mul_s(triton::arch::Instruction& inst) {
9691 auto& src2 = inst.operands[0];
9692
9693 switch (src2.getSize()) {
9694
9695 /* AX = AL * r/m8 */
9696 case triton::size::byte: {
9697 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
9698 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL));
9699 /* Create symbolic operands */
9700 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
9701 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
9702 /* Create the semantics */
9703 auto node = this->astCtxt->bvmul(this->astCtxt->zx(triton::bitsize::byte, op1), this->astCtxt->zx(triton::bitsize::byte, op2));
9704 /* Create symbolic expression */
9705 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MUL operation");
9706 /* Apply the taint */
9707 expr->isTainted = this->taintEngine->taintUnion(dst, src2);
9708 /* Update symbolic flags */
9709 auto ah = this->astCtxt->extract((triton::bitsize::word - 1), triton::bitsize::byte, node);
9710 this->cfMul_s(inst, expr, src2, ah);
9711 this->ofMul_s(inst, expr, src2, ah);
9712 break;
9713 }
9714
9715 /* DX:AX = AX * r/m16 */
9716 case triton::size::word: {
9717 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
9718 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DX));
9719 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX));
9720 /* Create symbolic operands */
9721 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
9722 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
9723 /* Create symbolic expression for ax */
9724 auto ax = this->astCtxt->bvmul(op1, op2);
9725 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, ax, dst1, "MUL operation");
9726 /* Apply the taint */
9727 expr1->isTainted = this->taintEngine->taintUnion(dst1, src2);
9728 /* Create symbolic expression for dx */
9729 auto node = this->astCtxt->bvmul(this->astCtxt->zx(triton::bitsize::word, op1), this->astCtxt->zx(triton::bitsize::word, op2));
9730 auto dx = this->astCtxt->extract((triton::bitsize::dword - 1), triton::bitsize::word, node);
9731 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, dx, dst2, "MUL operation");
9732 /* Apply the taint */
9733 expr2->isTainted = this->taintEngine->taintUnion(dst2, src2);
9734 expr2->isTainted = this->taintEngine->taintUnion(dst2, src1);
9735 /* Update symbolic flags */
9736 this->cfMul_s(inst, expr2, src2, dx);
9737 this->ofMul_s(inst, expr2, src2, dx);
9738 break;
9739 }
9740
9741 /* EDX:EAX = EAX * r/m32 */
9742 case triton::size::dword: {
9743 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
9744 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
9745 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
9746 /* Create symbolic operands */
9747 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
9748 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
9749 /* Create symbolic expression for eax */
9750 auto eax = this->astCtxt->bvmul(op1, op2);
9751 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, eax, dst1, "MUL operation");
9752 /* Apply the taint */
9753 expr1->isTainted = this->taintEngine->taintUnion(dst1, src2);
9754 /* Create symbolic expression for edx */
9755 auto node = this->astCtxt->bvmul(this->astCtxt->zx(triton::bitsize::dword, op1), this->astCtxt->zx(triton::bitsize::dword, op2));
9756 auto edx = this->astCtxt->extract((triton::bitsize::qword - 1), triton::bitsize::dword, node);
9757 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, edx, dst2, "MUL operation");
9758 /* Apply the taint */
9759 expr2->isTainted = this->taintEngine->taintUnion(dst2, src2);
9760 expr2->isTainted = this->taintEngine->taintUnion(dst2, src1);
9761 /* Update symbolic flags */
9762 this->cfMul_s(inst, expr2, src2, edx);
9763 this->ofMul_s(inst, expr2, src2, edx);
9764 break;
9765 }
9766
9767 /* RDX:RAX = RAX * r/m64 */
9768 case triton::size::qword: {
9769 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX));
9770 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX));
9771 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX));
9772 /* Create symbolic operands */
9773 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
9774 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
9775 /* Create the semantics */
9776 /* Create symbolic expression for eax */
9777 auto rax = this->astCtxt->bvmul(op1, op2);
9778 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, rax, dst1, "MUL operation");
9779 /* Apply the taint */
9780 expr1->isTainted = this->taintEngine->taintUnion(dst1, src2);
9781 /* Create symbolic expression for rdx */
9782 auto node = this->astCtxt->bvmul(this->astCtxt->zx(triton::bitsize::qword, op1), this->astCtxt->zx(triton::bitsize::qword, op2));
9783 auto rdx = this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, node);
9784 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, rdx, dst2, "MUL operation");
9785 /* Apply the taint */
9786 expr2->isTainted = this->taintEngine->taintUnion(dst2, src2);
9787 expr2->isTainted = this->taintEngine->taintUnion(dst2, src1);
9788 /* Update symbolic flags */
9789 this->cfMul_s(inst, expr2, src2, rdx);
9790 this->ofMul_s(inst, expr2, src2, rdx);
9791 break;
9792 }
9793
9794 }
9795
9796 /* Tag undefined flags */
9797 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
9798 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
9799 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
9800 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF));
9801
9802 /* Update the symbolic control flow */
9803 this->controlFlow_s(inst);
9804 }
9805
9806
9807 void x86Semantics::mulx_s(triton::arch::Instruction& inst) {
9808 switch (inst.operands[0].getSize()) {
9809
9810 /* r32a, r32b, r/m32 */
9811 case triton::size::dword: {
9812 auto& dst1 = inst.operands[0];
9813 auto& dst2 = inst.operands[1];
9814 auto src1 = inst.operands[2];
9815 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
9816
9817 /* Create symbolic operands */
9818 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
9819 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
9820
9821 /* Create the semantics */
9822 auto node = this->astCtxt->bvmul(this->astCtxt->zx(triton::bitsize::dword, op1), this->astCtxt->zx(triton::bitsize::dword, op2));
9823 auto node1 = this->astCtxt->bvmul(op1, op2);
9824 auto node2 = this->astCtxt->extract((triton::bitsize::qword - 1), triton::bitsize::dword, node);
9825
9826 /* Create symbolic expression */
9827 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst2, "MULX operation");
9828 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst1, "MULX operation");
9829
9830 /* Apply the taint */
9831 expr1->isTainted = this->taintEngine->taintUnion(dst2, src1);
9832 expr1->isTainted = this->taintEngine->taintUnion(dst2, src2);
9833
9834 expr2->isTainted = this->taintEngine->taintUnion(dst1, src1);
9835 expr2->isTainted = this->taintEngine->taintUnion(dst1, src2);
9836 break;
9837 }
9838
9839 /* r64a, r64b, r/m64 */
9840 case triton::size::qword: {
9841 auto& dst1 = inst.operands[0];
9842 auto& dst2 = inst.operands[1];
9843 auto src1 = inst.operands[2];
9844 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX));
9845
9846 /* Create symbolic operands */
9847 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
9848 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
9849
9850 /* Create the semantics */
9851 auto node = this->astCtxt->bvmul(this->astCtxt->zx(triton::bitsize::qword, op1), this->astCtxt->zx(triton::bitsize::qword, op2));
9852 auto node1 = this->astCtxt->bvmul(op1, op2);
9853 auto node2 = this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, node);
9854
9855 /* Create symbolic expression for eax */
9856 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst2, "MULX operation");
9857 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst1, "MULX operation");
9858
9859 /* Apply the taint */
9860 expr1->isTainted = this->taintEngine->taintUnion(dst2, src1);
9861 expr1->isTainted = this->taintEngine->taintUnion(dst2, src2);
9862
9863 expr2->isTainted = this->taintEngine->taintUnion(dst1, src1);
9864 expr2->isTainted = this->taintEngine->taintUnion(dst1, src2);
9865 break;
9866 }
9867
9868 }
9869
9870 /* Update the symbolic control flow */
9871 this->controlFlow_s(inst);
9872 }
9873
9874
9875 void x86Semantics::neg_s(triton::arch::Instruction& inst) {
9876 auto& src = inst.operands[0];
9877
9878 /* Create symbolic operands */
9879 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9880
9881 /* Create the semantics */
9882 auto node = this->astCtxt->bvneg(op1);
9883
9884 /* Create symbolic expression */
9885 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, src, "NEG operation");
9886
9887 /* Apply the taint */
9888 expr->isTainted = this->taintEngine->taintUnion(src, src);
9889
9890 /* Update symbolic flags */
9891 this->afNeg_s(inst, expr, src, op1);
9892 this->cfNeg_s(inst, expr, src, op1);
9893 this->ofNeg_s(inst, expr, src, op1);
9894 this->pf_s(inst, expr, src);
9895 this->sf_s(inst, expr, src);
9896 this->zf_s(inst, expr, src);
9897
9898 /* Update the symbolic control flow */
9899 this->controlFlow_s(inst);
9900 }
9901
9902
9903 void x86Semantics::nop_s(triton::arch::Instruction& inst) {
9904 /* Update the symbolic control flow */
9905 this->controlFlow_s(inst);
9906 }
9907
9908
9909 void x86Semantics::not_s(triton::arch::Instruction& inst) {
9910 auto& src = inst.operands[0];
9911
9912 /* Create symbolic operands */
9913 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
9914
9915 /* Create the semantics */
9916 auto node = this->astCtxt->bvnot(op1);
9917
9918 /* Create symbolic expression */
9919 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, src, "NOT operation");
9920
9921 /* Apply the taint */
9922 expr->isTainted = this->taintEngine->taintUnion(src, src);
9923
9924 /* Update the symbolic control flow */
9925 this->controlFlow_s(inst);
9926 }
9927
9928
9929 void x86Semantics::or_s(triton::arch::Instruction& inst) {
9930 auto& dst = inst.operands[0];
9931 auto& src = inst.operands[1];
9932
9933 /* Create symbolic operands */
9934 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
9935 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9936
9937 /* Create the semantics */
9938 auto node = this->astCtxt->bvor(op1, op2);
9939
9940 /* Create symbolic expression */
9941 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "OR operation");
9942
9943 /* Apply the taint */
9944 expr->isTainted = this->taintEngine->taintUnion(dst, src);
9945
9946 /* Update symbolic flags */
9947 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag");
9948 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
9949 this->pf_s(inst, expr, dst);
9950 this->sf_s(inst, expr, dst);
9951 this->zf_s(inst, expr, dst);
9952
9953 /* Tag undefined flags */
9954 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
9955
9956 /* Update the symbolic control flow */
9957 this->controlFlow_s(inst);
9958 }
9959
9960
9961 void x86Semantics::orpd_s(triton::arch::Instruction& inst) {
9962 auto& dst = inst.operands[0];
9963 auto& src = inst.operands[1];
9964
9965 /* Create symbolic operands */
9966 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
9967 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9968
9969 /* Create the semantics */
9970 auto node = this->astCtxt->bvor(op1, op2);
9971
9972 /* Create symbolic expression */
9973 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ORPD operation");
9974
9975 /* Apply the taint */
9976 expr->isTainted = this->taintEngine->taintUnion(dst, src);
9977
9978 /* Update the symbolic control flow */
9979 this->controlFlow_s(inst);
9980 }
9981
9982
9983 void x86Semantics::orps_s(triton::arch::Instruction& inst) {
9984 auto& dst = inst.operands[0];
9985 auto& src = inst.operands[1];
9986
9987 /* Create symbolic operands */
9988 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
9989 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
9990
9991 /* Create the semantics */
9992 auto node = this->astCtxt->bvor(op1, op2);
9993
9994 /* Create symbolic expression */
9995 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ORPS operation");
9996
9997 /* Apply the taint */
9998 expr->isTainted = this->taintEngine->taintUnion(dst, src);
9999
10000 /* Update the symbolic control flow */
10001 this->controlFlow_s(inst);
10002 }
10003
10004
10005 void x86Semantics::packuswb_s(triton::arch::Instruction& inst) {
10006 auto& dst = inst.operands[0];
10007 auto& src = inst.operands[1];
10008
10009 /* Create symbolic operands */
10010 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10011 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10012
10013 /* Create the semantics */
10014 std::vector<triton::ast::SharedAbstractNode> pck;
10015 pck.reserve(dst.getSize());
10016
10017 std::vector<triton::ast::SharedAbstractNode> ops{op2, op1};
10018 for (triton::uint32 i = 0; i < ops.size(); i++) {
10019 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
10020 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
10022 auto signed_word = this->astCtxt->extract(high, low, ops[i]);
10023 pck.push_back(this->astCtxt->ite(
10024 this->astCtxt->bvsge(signed_word, this->astCtxt->bv(0xff, triton::bitsize::word)),
10025 this->astCtxt->bv(0xff, triton::bitsize::byte),
10026 this->astCtxt->ite(
10027 this->astCtxt->bvsle(signed_word, this->astCtxt->bv(0x00, triton::bitsize::word)),
10028 this->astCtxt->bv(0x00, triton::bitsize::byte),
10029 this->astCtxt->extract(triton::bitsize::byte - 1, 0, signed_word)))
10030 );
10031 }
10032 }
10033
10034 auto node = this->astCtxt->concat(pck);
10035
10036 /* Create symbolic expression */
10037 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PACKUSWB operation");
10038
10039 /* Apply the taint */
10040 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10041
10042 /* Update the symbolic control flow */
10043 this->controlFlow_s(inst);
10044 }
10045
10046
10047 void x86Semantics::packssdw_s(triton::arch::Instruction& inst) {
10048 auto& dst = inst.operands[0];
10049 auto& src = inst.operands[1];
10050
10051 /* Create symbolic operands */
10052 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10053 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10054
10055 /* Create the semantics */
10056 std::vector<triton::ast::SharedAbstractNode> pck;
10057 pck.reserve(dst.getSize() / triton::size::word);
10058
10059 std::vector<triton::ast::SharedAbstractNode> ops{op2, op1};
10060
10061 for (triton::uint32 idx = 0; idx < ops.size(); ++idx) {
10062 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::dword; ++i) {
10063 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::dword);
10065 auto signed_dword = this->astCtxt->extract(high, low, ops[idx]);
10066 pck.push_back(this->astCtxt->ite(
10067 this->astCtxt->bvsge(signed_dword, this->astCtxt->bv(0x7fff, triton::bitsize::dword)),
10068 this->astCtxt->bv(0x7fff, triton::bitsize::word),
10069 this->astCtxt->ite(
10070 this->astCtxt->bvsle(signed_dword, this->astCtxt->bv(0xffff8000, triton::bitsize::dword)),
10071 this->astCtxt->bv(0x8000, triton::bitsize::word),
10072 this->astCtxt->extract(triton::bitsize::word - 1, 0, signed_dword)))
10073 );
10074 }
10075 }
10076
10077 auto node = this->astCtxt->concat(pck);
10078
10079 /* Create symbolic expression */
10080 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PACKSSDW operation");
10081
10082 /* Apply the taint */
10083 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10084
10085 /* Update the symbolic control flow */
10086 this->controlFlow_s(inst);
10087 }
10088
10089
10090 void x86Semantics::packsswb_s(triton::arch::Instruction& inst) {
10091 auto& dst = inst.operands[0];
10092 auto& src = inst.operands[1];
10093
10094 /* Create symbolic operands */
10095 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10096 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10097
10098 /* Create the semantics */
10099 std::vector<triton::ast::SharedAbstractNode> pck;
10100 pck.reserve(dst.getSize());
10101
10102 std::vector<triton::ast::SharedAbstractNode> ops{op2, op1};
10103 for (triton::uint32 i = 0; i < ops.size(); i++) {
10104 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
10105 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
10107 auto signed_word = this->astCtxt->extract(high, low, ops[i]);
10108 pck.push_back(this->astCtxt->ite(
10109 this->astCtxt->bvsge(signed_word, this->astCtxt->bv(0x007f, triton::bitsize::word)),
10110 this->astCtxt->bv(0x7f, triton::bitsize::byte),
10111 this->astCtxt->ite(
10112 this->astCtxt->bvsle(signed_word, this->astCtxt->bv(0xff80, triton::bitsize::word)),
10113 this->astCtxt->bv(0x80, triton::bitsize::byte),
10114 this->astCtxt->extract(triton::bitsize::byte - 1, 0, signed_word)))
10115 );
10116 }
10117 }
10118
10119 auto node = this->astCtxt->concat(pck);
10120
10121 /* Create symbolic expression */
10122 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PACKSSWB operation");
10123
10124 /* Apply the taint */
10125 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10126
10127 /* Update the symbolic control flow */
10128 this->controlFlow_s(inst);
10129 }
10130
10131
10132 void x86Semantics::paddb_s(triton::arch::Instruction& inst) {
10133 auto& dst = inst.operands[0];
10134 auto& src = inst.operands[1];
10135
10136 /* Create symbolic operands */
10137 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10138 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10139
10140 /* Create the semantics */
10141 std::vector<triton::ast::SharedAbstractNode> packed;
10142 packed.reserve(16);
10143
10144 switch (dst.getBitSize()) {
10145
10146 /* XMM */
10148 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(127, 120, op1), this->astCtxt->extract(127, 120, op2)));
10149 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(119, 112, op1), this->astCtxt->extract(119, 112, op2)));
10150 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(111, 104, op1), this->astCtxt->extract(111, 104, op2)));
10151 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(103, 96, op1), this->astCtxt->extract(103, 96, op2)));
10152 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(95, 88, op1), this->astCtxt->extract(95, 88, op2)));
10153 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(87, 80, op1), this->astCtxt->extract(87, 80, op2)));
10154 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(79, 72, op1), this->astCtxt->extract(79, 72, op2)));
10155 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(71, 64, op1), this->astCtxt->extract(71, 64, op2)));
10156
10157 /* MMX */
10159 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(63, 56, op1), this->astCtxt->extract(63, 56, op2)));
10160 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(55, 48, op1), this->astCtxt->extract(55, 48, op2)));
10161 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(47, 40, op1), this->astCtxt->extract(47, 40, op2)));
10162 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(39, 32, op1), this->astCtxt->extract(39, 32, op2)));
10163 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(31, 24, op1), this->astCtxt->extract(31, 24, op2)));
10164 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(23, 16, op1), this->astCtxt->extract(23, 16, op2)));
10165 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(15, 8, op1), this->astCtxt->extract(15, 8, op2)));
10166 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(7, 0, op1), this->astCtxt->extract(7, 0, op2)));
10167 break;
10168
10169 default:
10170 throw triton::exceptions::Semantics("x86Semantics::paddb_s(): Invalid operand size.");
10171
10172 }
10173
10174 auto node = this->astCtxt->concat(packed);
10175
10176 /* Create symbolic expression */
10177 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PADDB operation");
10178
10179 /* Update the x87 FPU Tag Word */
10180 if (dst.getBitSize() == triton::bitsize::qword) {
10181 this->updateFTW(inst, expr);
10182 }
10183
10184 /* Spread taint */
10185 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10186
10187 /* Update the symbolic control flow */
10188 this->controlFlow_s(inst);
10189 }
10190
10191
10192 void x86Semantics::paddd_s(triton::arch::Instruction& inst) {
10193 auto& dst = inst.operands[0];
10194 auto& src = inst.operands[1];
10195
10196 /* Create symbolic operands */
10197 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10198 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10199
10200 /* Create the semantics */
10201 std::vector<triton::ast::SharedAbstractNode> packed;
10202 packed.reserve(4);
10203
10204 switch (dst.getBitSize()) {
10205
10206 /* XMM */
10208 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(127, 96, op1), this->astCtxt->extract(127, 96, op2)));
10209 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(95, 64, op1), this->astCtxt->extract(95, 64, op2)));
10210
10211 /* MMX */
10213 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(63, 32, op1), this->astCtxt->extract(63, 32, op2)));
10214 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(31, 0, op1), this->astCtxt->extract(31, 0, op2)));
10215 break;
10216
10217 default:
10218 throw triton::exceptions::Semantics("x86Semantics::paddd_s(): Invalid operand size.");
10219
10220 }
10221
10222 auto node = this->astCtxt->concat(packed);
10223
10224 /* Create symbolic expression */
10225 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PADDD operation");
10226
10227 /* Update the x87 FPU Tag Word */
10228 if (dst.getBitSize() == triton::bitsize::qword) {
10229 this->updateFTW(inst, expr);
10230 }
10231
10232 /* Spread taint */
10233 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10234
10235 /* Update the symbolic control flow */
10236 this->controlFlow_s(inst);
10237 }
10238
10239
10240 void x86Semantics::paddq_s(triton::arch::Instruction& inst) {
10241 auto& dst = inst.operands[0];
10242 auto& src = inst.operands[1];
10243
10244 /* Create symbolic operands */
10245 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10246 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10247
10248 /* Create the semantics */
10249 std::vector<triton::ast::SharedAbstractNode> packed;
10250 packed.reserve(2);
10251
10252 switch (dst.getBitSize()) {
10253
10254 /* XMM */
10256 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(127, 64, op1), this->astCtxt->extract(127, 64, op2)));
10257
10258 /* MMX */
10260 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(63, 0, op1), this->astCtxt->extract(63, 0, op2)));
10261 break;
10262
10263 default:
10264 throw triton::exceptions::Semantics("x86Semantics::paddq_s(): Invalid operand size.");
10265
10266 }
10267
10268 auto node = this->astCtxt->concat(packed);
10269
10270 /* Create symbolic expression */
10271 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PADDQ operation");
10272
10273 /* Update the x87 FPU Tag Word */
10274 if (dst.getBitSize() == triton::bitsize::qword) {
10275 this->updateFTW(inst, expr);
10276 }
10277
10278 /* Spread taint */
10279 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10280
10281 /* Update the symbolic control flow */
10282 this->controlFlow_s(inst);
10283 }
10284
10285
10286 void x86Semantics::paddw_s(triton::arch::Instruction& inst) {
10287 auto& dst = inst.operands[0];
10288 auto& src = inst.operands[1];
10289
10290 /* Create symbolic operands */
10291 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10292 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10293
10294 /* Create the semantics */
10295 std::vector<triton::ast::SharedAbstractNode> packed;
10296 packed.reserve(8);
10297
10298 switch (dst.getBitSize()) {
10299
10300 /* XMM */
10302 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(127, 112, op1), this->astCtxt->extract(127, 112, op2)));
10303 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(111, 96, op1), this->astCtxt->extract(111, 96, op2)));
10304 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(95, 80, op1), this->astCtxt->extract(95, 80, op2)));
10305 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(79, 64, op1), this->astCtxt->extract(79, 64, op2)));
10306
10307 /* MMX */
10309 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(63, 48, op1), this->astCtxt->extract(63, 48, op2)));
10310 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(47, 32, op1), this->astCtxt->extract(47, 32, op2)));
10311 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(31, 16, op1), this->astCtxt->extract(31, 16, op2)));
10312 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(15, 0, op1), this->astCtxt->extract(15, 0, op2)));
10313 break;
10314
10315 default:
10316 throw triton::exceptions::Semantics("x86Semantics::paddw_s(): Invalid operand size.");
10317
10318 }
10319
10320 auto node = this->astCtxt->concat(packed);
10321
10322 /* Create symbolic expression */
10323 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PADDW operation");
10324
10325 /* Update the x87 FPU Tag Word */
10326 if (dst.getBitSize() == triton::bitsize::qword) {
10327 this->updateFTW(inst, expr);
10328 }
10329
10330 /* Spread taint */
10331 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10332
10333 /* Update the symbolic control flow */
10334 this->controlFlow_s(inst);
10335 }
10336
10337
10338 void x86Semantics::palignr_s(triton::arch::Instruction& inst) {
10339 auto& dst = inst.operands[0];
10340 auto& src1 = inst.operands[1];
10341 auto& src2 = inst.operands[2];
10342
10343 /* Create symbolic operands */
10344 auto size = 2 * dst.getBitSize();
10345 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10346 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
10347 auto op3 = this->astCtxt->zx(size - src2.getBitSize(), this->symbolicEngine->getOperandAst(inst, src2));
10348
10349 /* Create the semantics */
10350 auto node = this->astCtxt->extract(
10351 dst.getBitSize() - 1, 0,
10352 this->astCtxt->bvlshr(
10353 this->astCtxt->concat(op1, op2),
10354 this->astCtxt->bvmul(
10355 this->astCtxt->ite(
10356 this->astCtxt->bvuge(op3, this->astCtxt->bv(2 * dst.getSize(), size)),
10357 this->astCtxt->bv(2 * dst.getSize(), size),
10358 op3),
10359 this->astCtxt->bv(triton::bitsize::byte, size)
10360 )));
10361
10362 /* Create symbolic expression */
10363 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PALIGNR operation");
10364
10365 /* Spread taint */
10366 expr->isTainted = this->taintEngine->taintUnion(dst, src1);
10367
10368 /* Update the symbolic control flow */
10369 this->controlFlow_s(inst);
10370 }
10371
10372
10373 void x86Semantics::pand_s(triton::arch::Instruction& inst) {
10374 auto& dst = inst.operands[0];
10375 auto& src = inst.operands[1];
10376
10377 /* Create symbolic operands */
10378 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10379 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10380
10381 /* Create the semantics */
10382 auto node = this->astCtxt->bvand(op1, op2);
10383
10384 /* Create symbolic expression */
10385 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PAND operation");
10386
10387 /* Update the x87 FPU Tag Word */
10388 this->updateFTW(inst, expr);
10389
10390 /* Spread taint */
10391 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10392
10393 /* Update the symbolic control flow */
10394 this->controlFlow_s(inst);
10395 }
10396
10397
10398 void x86Semantics::pandn_s(triton::arch::Instruction& inst) {
10399 auto& dst = inst.operands[0];
10400 auto& src = inst.operands[1];
10401
10402 /* Create symbolic operands */
10403 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10404 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10405
10406 /* Create the semantics */
10407 auto node = this->astCtxt->bvand(this->astCtxt->bvnot(op1), op2);
10408
10409 /* Create symbolic expression */
10410 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PANDN operation");
10411
10412 /* Update the x87 FPU Tag Word */
10413 this->updateFTW(inst, expr);
10414
10415 /* Spread taint */
10416 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10417
10418 /* Update the symbolic control flow */
10419 this->controlFlow_s(inst);
10420 }
10421
10422
10423 void x86Semantics::pause_s(triton::arch::Instruction& inst) {
10424 /* Update the symbolic control flow */
10425 this->controlFlow_s(inst);
10426 }
10427
10428
10429 void x86Semantics::pavgb_s(triton::arch::Instruction& inst) {
10430 auto& dst = inst.operands[0];
10431 auto& src = inst.operands[1];
10432
10433 /* Create symbolic operands */
10434 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10435 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10436
10437 /* Create the semantics */
10438 std::vector<triton::ast::SharedAbstractNode> pck;
10439 pck.reserve(dst.getSize());
10440
10441 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
10442 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
10444 pck.push_back(
10445 this->astCtxt->extract(triton::bitsize::byte-1, 0,
10446 this->astCtxt->bvlshr(
10447 this->astCtxt->bvadd(
10448 this->astCtxt->bvadd(
10449 this->astCtxt->zx(1, this->astCtxt->extract(high, low, op1)),
10450 this->astCtxt->zx(1, this->astCtxt->extract(high, low, op2))
10451 ),
10452 this->astCtxt->bv(1, triton::bitsize::byte+1)
10453 ),
10454 this->astCtxt->bv(1, triton::bitsize::byte+1)
10455 )
10456 )
10457 );
10458 }
10459
10460 auto node = this->astCtxt->concat(pck);
10461
10462 /* Create symbolic expression */
10463 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PAVGB operation");
10464
10465 /* Spread taint */
10466 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10467
10468 /* Update the symbolic control flow */
10469 this->controlFlow_s(inst);
10470 }
10471
10472
10473 void x86Semantics::pavgw_s(triton::arch::Instruction& inst) {
10474 auto& dst = inst.operands[0];
10475 auto& src = inst.operands[1];
10476
10477 /* Create symbolic operands */
10478 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10479 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10480
10481 /* Create the semantics */
10482 std::vector<triton::ast::SharedAbstractNode> pck;
10483 pck.reserve(dst.getSize());
10484
10485 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
10486 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
10488 pck.push_back(
10489 this->astCtxt->extract(triton::bitsize::word-1, 0,
10490 this->astCtxt->bvlshr(
10491 this->astCtxt->bvadd(
10492 this->astCtxt->bvadd(
10493 this->astCtxt->zx(1, this->astCtxt->extract(high, low, op1)),
10494 this->astCtxt->zx(1, this->astCtxt->extract(high, low, op2))
10495 ),
10496 this->astCtxt->bv(1, triton::bitsize::word+1)
10497 ),
10498 this->astCtxt->bv(1, triton::bitsize::word+1)
10499 )
10500 )
10501 );
10502 }
10503
10504 auto node = this->astCtxt->concat(pck);
10505
10506 /* Create symbolic expression */
10507 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PAVGW operation");
10508
10509 /* Spread taint */
10510 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10511
10512 /* Update the symbolic control flow */
10513 this->controlFlow_s(inst);
10514 }
10515
10516
10517 void x86Semantics::pcmpeqb_s(triton::arch::Instruction& inst) {
10518 auto& dst = inst.operands[0];
10519 auto& src = inst.operands[1];
10520
10521 /* Create symbolic operands */
10522 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10523 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10524
10525 /* Create the semantics */
10526 std::vector<triton::ast::SharedAbstractNode> pck;
10527 pck.reserve(dst.getSize());
10528
10529 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
10530 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
10532 pck.push_back(this->astCtxt->ite(
10533 this->astCtxt->equal(
10534 this->astCtxt->extract(high, low, op1),
10535 this->astCtxt->extract(high, low, op2)),
10536 this->astCtxt->bv(0xff, triton::bitsize::byte),
10537 this->astCtxt->bv(0x00, triton::bitsize::byte))
10538 );
10539 }
10540
10541 auto node = this->astCtxt->concat(pck);
10542
10543 /* Create symbolic expression */
10544 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PCMPEQB operation");
10545
10546 /* Apply the taint */
10547 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10548
10549 /* Update the symbolic control flow */
10550 this->controlFlow_s(inst);
10551 }
10552
10553
10554 void x86Semantics::pcmpeqd_s(triton::arch::Instruction& inst) {
10555 auto& dst = inst.operands[0];
10556 auto& src = inst.operands[1];
10557
10558 /* Create symbolic operands */
10559 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10560 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10561
10562 /* Create the semantics */
10563 std::vector<triton::ast::SharedAbstractNode> pck;
10564 pck.reserve(dst.getSize() / triton::size::dword);
10565
10566 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) {
10567 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword);
10569 pck.push_back(this->astCtxt->ite(
10570 this->astCtxt->equal(
10571 this->astCtxt->extract(high, low, op1),
10572 this->astCtxt->extract(high, low, op2)),
10573 this->astCtxt->bv(0xffffffff, triton::bitsize::dword),
10574 this->astCtxt->bv(0x00000000, triton::bitsize::dword))
10575 );
10576 }
10577
10578 auto node = this->astCtxt->concat(pck);
10579
10580 /* Create symbolic expression */
10581 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PCMPEQD operation");
10582
10583 /* Apply the taint */
10584 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10585
10586 /* Update the symbolic control flow */
10587 this->controlFlow_s(inst);
10588 }
10589
10590
10591 void x86Semantics::pcmpeqw_s(triton::arch::Instruction& inst) {
10592 auto& dst = inst.operands[0];
10593 auto& src = inst.operands[1];
10594
10595 /* Create symbolic operands */
10596 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10597 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10598
10599 /* Create the semantics */
10600 std::vector<triton::ast::SharedAbstractNode> pck;
10601 pck.reserve(dst.getSize() / triton::size::word);
10602
10603 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
10604 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
10606 pck.push_back(this->astCtxt->ite(
10607 this->astCtxt->equal(
10608 this->astCtxt->extract(high, low, op1),
10609 this->astCtxt->extract(high, low, op2)),
10610 this->astCtxt->bv(0xffff, triton::bitsize::word),
10611 this->astCtxt->bv(0x0000, triton::bitsize::word))
10612 );
10613 }
10614
10615 auto node = this->astCtxt->concat(pck);
10616
10617 /* Create symbolic expression */
10618 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PCMPEQW operation");
10619
10620 /* Apply the taint */
10621 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10622
10623 /* Update the symbolic control flow */
10624 this->controlFlow_s(inst);
10625 }
10626
10627
10628 void x86Semantics::pcmpgtb_s(triton::arch::Instruction& inst) {
10629 auto& dst = inst.operands[0];
10630 auto& src = inst.operands[1];
10631
10632 /* Create symbolic operands */
10633 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10634 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10635
10636 /* Create the semantics */
10637 std::vector<triton::ast::SharedAbstractNode> pck;
10638 pck.reserve(dst.getSize());
10639
10640 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
10641 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
10643 pck.push_back(this->astCtxt->ite(
10644 this->astCtxt->bvsgt(
10645 this->astCtxt->extract(high, low, op1),
10646 this->astCtxt->extract(high, low, op2)),
10647 this->astCtxt->bv(0xff, triton::bitsize::byte),
10648 this->astCtxt->bv(0x00, triton::bitsize::byte))
10649 );
10650 }
10651
10652 auto node = this->astCtxt->concat(pck);
10653
10654 /* Create symbolic expression */
10655 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PCMPGTB operation");
10656
10657 /* Apply the taint */
10658 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10659
10660 /* Update the symbolic control flow */
10661 this->controlFlow_s(inst);
10662 }
10663
10664
10665 void x86Semantics::pcmpgtd_s(triton::arch::Instruction& inst) {
10666 auto& dst = inst.operands[0];
10667 auto& src = inst.operands[1];
10668
10669 /* Create symbolic operands */
10670 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10671 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10672
10673 /* Create the semantics */
10674 std::vector<triton::ast::SharedAbstractNode> pck;
10675 pck.reserve(dst.getSize());
10676
10677 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) {
10678 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword);
10680 pck.push_back(this->astCtxt->ite(
10681 this->astCtxt->bvsgt(
10682 this->astCtxt->extract(high, low, op1),
10683 this->astCtxt->extract(high, low, op2)),
10684 this->astCtxt->bv(0xffffffff, triton::bitsize::dword),
10685 this->astCtxt->bv(0x00000000, triton::bitsize::dword))
10686 );
10687 }
10688
10689 auto node = this->astCtxt->concat(pck);
10690
10691 /* Create symbolic expression */
10692 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PCMPGTD operation");
10693
10694 /* Apply the taint */
10695 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10696
10697 /* Update the symbolic control flow */
10698 this->controlFlow_s(inst);
10699 }
10700
10701
10702 void x86Semantics::pcmpgtw_s(triton::arch::Instruction& inst) {
10703 auto& dst = inst.operands[0];
10704 auto& src = inst.operands[1];
10705
10706 /* Create symbolic operands */
10707 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10708 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10709
10710 /* Create the semantics */
10711 std::vector<triton::ast::SharedAbstractNode> pck;
10712 pck.reserve(dst.getSize());
10713
10714 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
10715 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
10717 pck.push_back(this->astCtxt->ite(
10718 this->astCtxt->bvsgt(
10719 this->astCtxt->extract(high, low, op1),
10720 this->astCtxt->extract(high, low, op2)),
10721 this->astCtxt->bv(0xffff, triton::bitsize::word),
10722 this->astCtxt->bv(0x0000, triton::bitsize::word))
10723 );
10724 }
10725
10726 auto node = this->astCtxt->concat(pck);
10727
10728 /* Create symbolic expression */
10729 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PCMPGTW operation");
10730
10731 /* Apply the taint */
10732 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10733
10734 /* Update the symbolic control flow */
10735 this->controlFlow_s(inst);
10736 }
10737
10738
10739 void x86Semantics::pmaxsb_s(triton::arch::Instruction& inst) {
10740 auto& dst = inst.operands[0];
10741 auto& src = inst.operands[1];
10742
10743 /* Create symbolic operands */
10744 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10745 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
10746
10747 /* Create the semantics */
10748 std::vector<triton::ast::SharedAbstractNode> pck;
10749 pck.reserve(dst.getSize());
10750
10751 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
10752 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
10754 pck.push_back(this->astCtxt->ite(
10755 this->astCtxt->bvsle(
10756 this->astCtxt->extract(high, low, op1),
10757 this->astCtxt->extract(high, low, op2)),
10758 this->astCtxt->extract(high, low, op2),
10759 this->astCtxt->extract(high, low, op1))
10760 );
10761 }
10762
10763 auto node = this->astCtxt->concat(pck);
10764
10765 /* Create symbolic expression */
10766 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMAXSB operation");
10767
10768 /* Apply the taint */
10769 expr->isTainted = this->taintEngine->taintUnion(dst, src);
10770
10771 /* Update the symbolic control flow */
10772 this->controlFlow_s(inst);
10773 }
10774
10775
10776 void x86Semantics::pextrb_s(triton::arch::Instruction& inst) {
10777 auto& dst = inst.operands[0];
10778 auto& src1 = inst.operands[1];
10779 auto& src2 = inst.operands[2];
10780
10781 /* Create symbolic operands */
10782 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10783 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
10784 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
10785
10786 auto node = this->astCtxt->extract(triton::bitsize::byte - 1, 0,
10787 this->astCtxt->bvlshr(
10788 op2,
10789 this->astCtxt->bv(((op3->evaluate() & 0x0f) * triton::bitsize::byte), op2->getBitvectorSize())
10790 )
10791 );
10792
10793 /* Create symbolic expression */
10794 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PEXTRB operation");
10795
10796 /* Apply the taint */
10797 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
10798
10799 /* Update the symbolic control flow */
10800 this->controlFlow_s(inst);
10801 }
10802
10803
10804 void x86Semantics::pextrd_s(triton::arch::Instruction& inst) {
10805 auto& dst = inst.operands[0];
10806 auto& src1 = inst.operands[1];
10807 auto& src2 = inst.operands[2];
10808
10809 /* Create symbolic operands */
10810 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10811 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
10812 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
10813
10814 auto node = this->astCtxt->extract(triton::bitsize::dword - 1, 0,
10815 this->astCtxt->bvlshr(
10816 op2,
10817 this->astCtxt->bv(((op3->evaluate() & 0x3) * triton::bitsize::dword), op2->getBitvectorSize())
10818 )
10819 );
10820
10821 /* Create symbolic expression */
10822 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PEXTRD operation");
10823
10824 /* Apply the taint */
10825 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
10826
10827 /* Update the symbolic control flow */
10828 this->controlFlow_s(inst);
10829 }
10830
10831
10832 void x86Semantics::pextrq_s(triton::arch::Instruction& inst) {
10833 auto& dst = inst.operands[0];
10834 auto& src1 = inst.operands[1];
10835 auto& src2 = inst.operands[2];
10836
10837 /* Create symbolic operands */
10838 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10839 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
10840 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
10841
10842 auto node = this->astCtxt->extract(triton::bitsize::qword - 1, 0,
10843 this->astCtxt->bvlshr(
10844 op2,
10845 this->astCtxt->bv(((op3->evaluate() & 0x1) * triton::bitsize::qword), op2->getBitvectorSize())
10846 )
10847 );
10848
10849 /* Create symbolic expression */
10850 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PEXTRQ operation");
10851
10852 /* Apply the taint */
10853 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
10854
10855 /* Update the symbolic control flow */
10856 this->controlFlow_s(inst);
10857 }
10858
10859
10860 void x86Semantics::pextrw_s(triton::arch::Instruction& inst) {
10861 triton::uint32 count = 0;
10862 auto& dst = inst.operands[0];
10863 auto& src1 = inst.operands[1];
10864 auto& src2 = inst.operands[2];
10865
10866 /*
10867 * When specifying a word location in an MMX technology register, the
10868 * 2 least-significant bits of the count operand specify the location;
10869 * for an XMM register, the 3 least-significant bits specify the
10870 * location.
10871 */
10872 if (src1.getBitSize() == triton::bitsize::qword) {
10873 count = 0x03;
10874 }
10875 else {
10876 count = 0x07;
10877 }
10878
10879 /* Create symbolic operands */
10880 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10881 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
10882 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
10883
10884 auto node = this->astCtxt->extract(triton::bitsize::word - 1, 0,
10885 this->astCtxt->bvlshr(
10886 op2,
10887 this->astCtxt->bv(((op3->evaluate() & count) * triton::bitsize::word), op2->getBitvectorSize())
10888 )
10889 );
10890
10891 /* Create symbolic expression */
10892 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PEXTRW operation");
10893
10894 /* Apply the taint */
10895 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
10896
10897 /* Update the symbolic control flow */
10898 this->controlFlow_s(inst);
10899 }
10900
10901
10902 void x86Semantics::pinsrb_s(triton::arch::Instruction& inst) {
10903 auto& dst = inst.operands[0];
10904 auto& src1 = inst.operands[1];
10905 auto& src2 = inst.operands[2];
10906
10907 /* Create symbolic operands */
10908 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10909 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
10910 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
10911
10912 // SEL = COUNT[3:0];
10913 // MASK = (0FFH << (SEL * 8));
10914 triton::uint64 sel = static_cast<triton::uint64>(op3->evaluate()) & 0x0f;
10915 triton::uint128 mask = 0xff;
10916 mask = mask << (sel * 8);
10917
10918 // TEMP = ((SRC[7:0] << (SEL * 8)) AND MASK);
10919 auto temp = this->astCtxt->bvand(
10920 this->astCtxt->bvshl(
10921 this->astCtxt->zx(120, this->astCtxt->extract(7, 0, op2)),
10922 this->astCtxt->bv(sel * 8, 128)
10923 ),
10924 this->astCtxt->bv(mask, 128)
10925 );
10926
10927 // DEST = ((DEST AND NOT MASK) OR TEMP);
10928 auto node = this->astCtxt->bvor(
10929 this->astCtxt->bvand(
10930 op1,
10931 this->astCtxt->bvnot(this->astCtxt->bv(mask, 128))
10932 ),
10933 temp
10934 );
10935
10936 /* Create symbolic expression */
10937 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PINSRB operation");
10938
10939 /* Apply the taint */
10940 expr->isTainted = this->taintEngine->taintUnion(dst, src1);
10941
10942 /* Update the symbolic control flow */
10943 this->controlFlow_s(inst);
10944 }
10945
10946
10947 void x86Semantics::pinsrd_s(triton::arch::Instruction& inst) {
10948 auto& dst = inst.operands[0];
10949 auto& src1 = inst.operands[1];
10950 auto& src2 = inst.operands[2];
10951
10952 /* Create symbolic operands */
10953 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10954 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
10955 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
10956
10957 // SEL = COUNT[1:0];
10958 // MASK = (0FFFFFFFFH << (SEL * 32));
10959 triton::uint64 sel = static_cast<triton::uint64>(op3->evaluate()) & 0x03;
10960 triton::uint128 mask = 0xffffffff;
10961 mask = mask << (sel * 32);
10962
10963 // TEMP = ((SRC[31:0] << (SEL * 32)) AND MASK);
10964 auto temp = this->astCtxt->bvand(
10965 this->astCtxt->bvshl(
10966 this->astCtxt->zx(96, this->astCtxt->extract(31, 0, op2)),
10967 this->astCtxt->bv(sel * 32, 128)
10968 ),
10969 this->astCtxt->bv(mask, 128)
10970 );
10971
10972 // DEST = ((DEST AND NOT MASK) OR TEMP);
10973 auto node = this->astCtxt->bvor(
10974 this->astCtxt->bvand(
10975 op1,
10976 this->astCtxt->bvnot(this->astCtxt->bv(mask, 128))
10977 ),
10978 temp
10979 );
10980
10981 /* Create symbolic expression */
10982 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PINSRD operation");
10983
10984 /* Apply the taint */
10985 expr->isTainted = this->taintEngine->taintUnion(dst, src1);
10986
10987 /* Update the symbolic control flow */
10988 this->controlFlow_s(inst);
10989 }
10990
10991
10992 void x86Semantics::pinsrq_s(triton::arch::Instruction& inst) {
10993 auto& dst = inst.operands[0];
10994 auto& src1 = inst.operands[1];
10995 auto& src2 = inst.operands[2];
10996
10997 /* Create symbolic operands */
10998 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
10999 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
11000 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
11001
11002 // SEL = COUNT[0:0];
11003 // MASK = (0FFFFFFFFFFFFFFFFH << (SEL * 64));
11004 triton::uint64 sel = static_cast<triton::uint64>(op3->evaluate()) & 0x1;
11005 triton::uint128 mask = 0xffffffffffffffff;
11006 mask = mask << (sel * 64);
11007
11008 // TEMP = ((SRC[63:0] << (SEL * 64)) AND MASK);
11009 auto temp = this->astCtxt->bvand(
11010 this->astCtxt->bvshl(
11011 this->astCtxt->zx(64, this->astCtxt->extract(63, 0, op2)),
11012 this->astCtxt->bv(sel * 64, 128)
11013 ),
11014 this->astCtxt->bv(mask, 128)
11015 );
11016
11017 // DEST = ((DEST AND NOT MASK) OR TEMP);
11018 auto node = this->astCtxt->bvor(
11019 this->astCtxt->bvand(
11020 op1,
11021 this->astCtxt->bvnot(this->astCtxt->bv(mask, 128))
11022 ),
11023 temp
11024 );
11025
11026 /* Create symbolic expression */
11027 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PINSRQ operation");
11028
11029 /* Apply the taint */
11030 expr->isTainted = this->taintEngine->taintUnion(dst, src1);
11031
11032 /* Update the symbolic control flow */
11033 this->controlFlow_s(inst);
11034 }
11035
11036
11037 void x86Semantics::pinsrw_s(triton::arch::Instruction& inst) {
11038 triton::uint128 mask = 0xffff;
11039 triton::uint64 sel = 0;
11040 auto& dst = inst.operands[0];
11041 auto& src1 = inst.operands[1];
11042 auto& src2 = inst.operands[2];
11043
11044 /* Create symbolic operands */
11045 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11046 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
11047 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
11048
11049 /*
11050 * PINSRW (with 64-bit source operand)
11051 *
11052 * SEL = COUNT AND 3H;
11053 * CASE (Determine word position) {
11054 * if SEL == 0: MASK = 000000000000FFFFH;
11055 * if SEL == 1: MASK = 00000000FFFF0000H;
11056 * if SEL == 2: MASK = 0000FFFF00000000H;
11057 * if SEL == 3: MASK = FFFF000000000000H;
11058 * }
11059 */
11060 if (dst.getBitSize() == triton::bitsize::qword) {
11061 sel = static_cast<triton::uint64>(op3->evaluate()) & 0x3;
11062 switch (sel) {
11063 case 1: mask = mask << 16; break;
11064 case 2: mask = mask << 32; break;
11065 case 3: mask = mask << 48; break;
11066 }
11067 }
11068
11069 /*
11070 * PINSRW (with 128-bit source operand)
11071 *
11072 * SEL ← COUNT AND 7H;
11073 * CASE (Determine word position) {
11074 * SEL == 0: MASK = 0000000000000000000000000000FFFFH;
11075 * SEL == 1: MASK = 000000000000000000000000FFFF0000H;
11076 * SEL == 2: MASK = 00000000000000000000FFFF00000000H;
11077 * SEL == 3: MASK = 0000000000000000FFFF000000000000H;
11078 * SEL == 4: MASK = 000000000000FFFF0000000000000000H;
11079 * SEL == 5: MASK = 00000000FFFF00000000000000000000H;
11080 * SEL == 6: MASK = 0000FFFF000000000000000000000000H;
11081 * SEL == 7: MASK = FFFF0000000000000000000000000000H;
11082 * }
11083 */
11084 else {
11085 sel = static_cast<triton::uint64>(op3->evaluate()) & 0x7;
11086 switch (sel) {
11087 case 1: mask = mask << 16; break;
11088 case 2: mask = mask << 32; break;
11089 case 3: mask = mask << 48; break;
11090 case 4: mask = mask << 64; break;
11091 case 5: mask = mask << 80; break;
11092 case 6: mask = mask << 96; break;
11093 case 7: mask = mask << 112; break;
11094 }
11095 }
11096
11097 // TEMP = ((SRC << (SEL ∗ 16)) AND MASK);
11098 auto temp = this->astCtxt->bvand(
11099 this->astCtxt->bvshl(
11100 this->astCtxt->zx(112, this->astCtxt->extract(15, 0, op2)),
11101 this->astCtxt->bv(sel * 16, 128)
11102 ),
11103 this->astCtxt->bv(mask, 128)
11104 );
11105
11106 // DEST = ((DEST AND NOT MASK) OR TEMP);
11107 auto node = this->astCtxt->bvor(
11108 this->astCtxt->bvand(
11109 op1,
11110 this->astCtxt->bvnot(this->astCtxt->bv(mask, 128))
11111 ),
11112 temp
11113 );
11114
11115 /* Create symbolic expression */
11116 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PINSRW operation");
11117
11118 /* Apply the taint */
11119 expr->isTainted = this->taintEngine->taintUnion(dst, src1);
11120
11121 /* Update the symbolic control flow */
11122 this->controlFlow_s(inst);
11123 }
11124
11125
11126 void x86Semantics::pmaddwd_s(triton::arch::Instruction& inst) {
11127 auto& dst = inst.operands[0];
11128 auto& src = inst.operands[1];
11129
11130 /* Create symbolic operands */
11131 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11132 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11133
11134 /* Create the semantics */
11135 std::vector<triton::ast::SharedAbstractNode> pck;
11136 pck.reserve(dst.getSize() / triton::size::dword);
11137
11138 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; i += 2) {
11139 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
11141 auto node1 = this->astCtxt->bvmul(
11142 this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op1)),
11143 this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op2))
11144 );
11145 high -= triton::bitsize::word;
11146 low -= triton::bitsize::word;
11147 auto node2 = this->astCtxt->bvmul(
11148 this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op1)),
11149 this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op2))
11150 );
11151 pck.push_back(this->astCtxt->bvadd(node1, node2));
11152 }
11153
11154 auto node = this->astCtxt->concat(pck);
11155
11156 /* Create symbolic expression */
11157 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMADDWD operation");
11158
11159 /* Apply the taint */
11160 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11161
11162 /* Update the symbolic control flow */
11163 this->controlFlow_s(inst);
11164 }
11165
11166
11167 void x86Semantics::pmaxsd_s(triton::arch::Instruction& inst) {
11168 auto& dst = inst.operands[0];
11169 auto& src = inst.operands[1];
11170
11171 /* Create symbolic operands */
11172 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11173 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11174
11175 /* Create the semantics */
11176 std::vector<triton::ast::SharedAbstractNode> pck;
11177 pck.reserve(dst.getSize());
11178
11179 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) {
11180 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword);
11182 pck.push_back(this->astCtxt->ite(
11183 this->astCtxt->bvsle(
11184 this->astCtxt->extract(high, low, op1),
11185 this->astCtxt->extract(high, low, op2)),
11186 this->astCtxt->extract(high, low, op2),
11187 this->astCtxt->extract(high, low, op1))
11188 );
11189 }
11190
11191 auto node = this->astCtxt->concat(pck);
11192
11193 /* Create symbolic expression */
11194 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMAXSD operation");
11195
11196 /* Apply the taint */
11197 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11198
11199 /* Update the symbolic control flow */
11200 this->controlFlow_s(inst);
11201 }
11202
11203
11204 void x86Semantics::pmaxsw_s(triton::arch::Instruction& inst) {
11205 auto& dst = inst.operands[0];
11206 auto& src = inst.operands[1];
11207
11208 /* Create symbolic operands */
11209 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11210 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11211
11212 /* Create the semantics */
11213 std::vector<triton::ast::SharedAbstractNode> pck;
11214 pck.reserve(dst.getSize());
11215
11216 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
11217 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
11219 pck.push_back(this->astCtxt->ite(
11220 this->astCtxt->bvsle(
11221 this->astCtxt->extract(high, low, op1),
11222 this->astCtxt->extract(high, low, op2)),
11223 this->astCtxt->extract(high, low, op2),
11224 this->astCtxt->extract(high, low, op1))
11225 );
11226 }
11227
11228 auto node = this->astCtxt->concat(pck);
11229
11230 /* Create symbolic expression */
11231 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMAXSW operation");
11232
11233 /* Apply the taint */
11234 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11235
11236 /* Update the symbolic control flow */
11237 this->controlFlow_s(inst);
11238 }
11239
11240
11241 void x86Semantics::pmaxub_s(triton::arch::Instruction& inst) {
11242 auto& dst = inst.operands[0];
11243 auto& src = inst.operands[1];
11244
11245 /* Create symbolic operands */
11246 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11247 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11248
11249 /* Create the semantics */
11250 std::vector<triton::ast::SharedAbstractNode> pck;
11251 pck.reserve(dst.getSize());
11252
11253 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
11254 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
11256 pck.push_back(this->astCtxt->ite(
11257 this->astCtxt->bvule(
11258 this->astCtxt->extract(high, low, op1),
11259 this->astCtxt->extract(high, low, op2)),
11260 this->astCtxt->extract(high, low, op2),
11261 this->astCtxt->extract(high, low, op1))
11262 );
11263 }
11264
11265 auto node = this->astCtxt->concat(pck);
11266
11267 /* Create symbolic expression */
11268 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMAXUB operation");
11269
11270 /* Apply the taint */
11271 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11272
11273 /* Update the symbolic control flow */
11274 this->controlFlow_s(inst);
11275 }
11276
11277
11278 void x86Semantics::pmaxud_s(triton::arch::Instruction& inst) {
11279 auto& dst = inst.operands[0];
11280 auto& src = inst.operands[1];
11281
11282 /* Create symbolic operands */
11283 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11284 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11285
11286 /* Create the semantics */
11287 std::vector<triton::ast::SharedAbstractNode> pck;
11288 pck.reserve(dst.getSize());
11289
11290 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) {
11291 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword);
11293 pck.push_back(this->astCtxt->ite(
11294 this->astCtxt->bvule(
11295 this->astCtxt->extract(high, low, op1),
11296 this->astCtxt->extract(high, low, op2)),
11297 this->astCtxt->extract(high, low, op2),
11298 this->astCtxt->extract(high, low, op1))
11299 );
11300 }
11301
11302 auto node = this->astCtxt->concat(pck);
11303
11304 /* Create symbolic expression */
11305 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMAXUD operation");
11306
11307 /* Apply the taint */
11308 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11309
11310 /* Update the symbolic control flow */
11311 this->controlFlow_s(inst);
11312 }
11313
11314
11315 void x86Semantics::pmaxuw_s(triton::arch::Instruction& inst) {
11316 auto& dst = inst.operands[0];
11317 auto& src = inst.operands[1];
11318
11319 /* Create symbolic operands */
11320 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11321 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11322
11323 /* Create the semantics */
11324 std::vector<triton::ast::SharedAbstractNode> pck;
11325 pck.reserve(dst.getSize());
11326
11327 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
11328 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
11330 pck.push_back(this->astCtxt->ite(
11331 this->astCtxt->bvule(
11332 this->astCtxt->extract(high, low, op1),
11333 this->astCtxt->extract(high, low, op2)),
11334 this->astCtxt->extract(high, low, op2),
11335 this->astCtxt->extract(high, low, op1))
11336 );
11337 }
11338
11339 auto node = this->astCtxt->concat(pck);
11340
11341 /* Create symbolic expression */
11342 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMAXUW operation");
11343
11344 /* Apply the taint */
11345 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11346
11347 /* Update the symbolic control flow */
11348 this->controlFlow_s(inst);
11349 }
11350
11351
11352 void x86Semantics::pminsb_s(triton::arch::Instruction& inst) {
11353 auto& dst = inst.operands[0];
11354 auto& src = inst.operands[1];
11355
11356 /* Create symbolic operands */
11357 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11358 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11359
11360 /* Create the semantics */
11361 std::vector<triton::ast::SharedAbstractNode> pck;
11362 pck.reserve(dst.getSize());
11363
11364 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
11365 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
11367 pck.push_back(this->astCtxt->ite(
11368 this->astCtxt->bvsge(
11369 this->astCtxt->extract(high, low, op1),
11370 this->astCtxt->extract(high, low, op2)),
11371 this->astCtxt->extract(high, low, op2),
11372 this->astCtxt->extract(high, low, op1))
11373 );
11374 }
11375
11376 auto node = this->astCtxt->concat(pck);
11377
11378 /* Create symbolic expression */
11379 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMINSB operation");
11380
11381 /* Apply the taint */
11382 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11383
11384 /* Update the symbolic control flow */
11385 this->controlFlow_s(inst);
11386 }
11387
11388
11389 void x86Semantics::pminsd_s(triton::arch::Instruction& inst) {
11390 auto& dst = inst.operands[0];
11391 auto& src = inst.operands[1];
11392
11393 /* Create symbolic operands */
11394 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11395 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11396
11397 /* Create the semantics */
11398 std::vector<triton::ast::SharedAbstractNode> pck;
11399 pck.reserve(dst.getSize());
11400
11401 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) {
11402 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword);
11404 pck.push_back(this->astCtxt->ite(
11405 this->astCtxt->bvsge(
11406 this->astCtxt->extract(high, low, op1),
11407 this->astCtxt->extract(high, low, op2)),
11408 this->astCtxt->extract(high, low, op2),
11409 this->astCtxt->extract(high, low, op1))
11410 );
11411 }
11412
11413 auto node = this->astCtxt->concat(pck);
11414
11415 /* Create symbolic expression */
11416 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMINSD operation");
11417
11418 /* Apply the taint */
11419 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11420
11421 /* Update the symbolic control flow */
11422 this->controlFlow_s(inst);
11423 }
11424
11425
11426 void x86Semantics::pminsw_s(triton::arch::Instruction& inst) {
11427 auto& dst = inst.operands[0];
11428 auto& src = inst.operands[1];
11429
11430 /* Create symbolic operands */
11431 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11432 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11433
11434 /* Create the semantics */
11435 std::vector<triton::ast::SharedAbstractNode> pck;
11436 pck.reserve(dst.getSize());
11437
11438 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
11439 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
11441 pck.push_back(this->astCtxt->ite(
11442 this->astCtxt->bvsge(
11443 this->astCtxt->extract(high, low, op1),
11444 this->astCtxt->extract(high, low, op2)),
11445 this->astCtxt->extract(high, low, op2),
11446 this->astCtxt->extract(high, low, op1))
11447 );
11448 }
11449
11450 auto node = this->astCtxt->concat(pck);
11451
11452 /* Create symbolic expression */
11453 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMINSW operation");
11454
11455 /* Apply the taint */
11456 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11457
11458 /* Update the symbolic control flow */
11459 this->controlFlow_s(inst);
11460 }
11461
11462
11463 void x86Semantics::pminub_s(triton::arch::Instruction& inst) {
11464 auto& dst = inst.operands[0];
11465 auto& src = inst.operands[1];
11466
11467 /* Create symbolic operands */
11468 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11469 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11470
11471 /* Create the semantics */
11472 std::vector<triton::ast::SharedAbstractNode> pck;
11473 pck.reserve(dst.getSize());
11474
11475 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
11476 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
11478 pck.push_back(this->astCtxt->ite(
11479 this->astCtxt->bvuge(
11480 this->astCtxt->extract(high, low, op1),
11481 this->astCtxt->extract(high, low, op2)),
11482 this->astCtxt->extract(high, low, op2),
11483 this->astCtxt->extract(high, low, op1))
11484 );
11485 }
11486
11487 auto node = this->astCtxt->concat(pck);
11488
11489 /* Create symbolic expression */
11490 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMINUB operation");
11491
11492 /* Apply the taint */
11493 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11494
11495 /* Update the symbolic control flow */
11496 this->controlFlow_s(inst);
11497 }
11498
11499
11500 void x86Semantics::pminud_s(triton::arch::Instruction& inst) {
11501 auto& dst = inst.operands[0];
11502 auto& src = inst.operands[1];
11503
11504 /* Create symbolic operands */
11505 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11506 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11507
11508 /* Create the semantics */
11509 std::vector<triton::ast::SharedAbstractNode> pck;
11510 pck.reserve(dst.getSize());
11511
11512 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) {
11513 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword);
11515 pck.push_back(this->astCtxt->ite(
11516 this->astCtxt->bvuge(
11517 this->astCtxt->extract(high, low, op1),
11518 this->astCtxt->extract(high, low, op2)),
11519 this->astCtxt->extract(high, low, op2),
11520 this->astCtxt->extract(high, low, op1))
11521 );
11522 }
11523
11524 auto node = this->astCtxt->concat(pck);
11525
11526 /* Create symbolic expression */
11527 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMINUD operation");
11528
11529 /* Apply the taint */
11530 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11531
11532 /* Update the symbolic control flow */
11533 this->controlFlow_s(inst);
11534 }
11535
11536
11537 void x86Semantics::pminuw_s(triton::arch::Instruction& inst) {
11538 auto& dst = inst.operands[0];
11539 auto& src = inst.operands[1];
11540
11541 /* Create symbolic operands */
11542 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11543 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11544
11545 /* Create the semantics */
11546 std::vector<triton::ast::SharedAbstractNode> pck;
11547 pck.reserve(dst.getSize());
11548
11549 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
11550 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
11552 pck.push_back(this->astCtxt->ite(
11553 this->astCtxt->bvuge(
11554 this->astCtxt->extract(high, low, op1),
11555 this->astCtxt->extract(high, low, op2)),
11556 this->astCtxt->extract(high, low, op2),
11557 this->astCtxt->extract(high, low, op1))
11558 );
11559 }
11560
11561 auto node = this->astCtxt->concat(pck);
11562
11563 /* Create symbolic expression */
11564 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMINUW operation");
11565
11566 /* Apply the taint */
11567 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11568
11569 /* Update the symbolic control flow */
11570 this->controlFlow_s(inst);
11571 }
11572
11573
11574 void x86Semantics::pmovmskb_s(triton::arch::Instruction& inst) {
11575 auto& dst = inst.operands[0];
11576 auto& src = inst.operands[1];
11577
11578 /* Create symbolic operands */
11579 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11580
11581 /* Create the semantics */
11582 std::vector<triton::ast::SharedAbstractNode> mskb;
11583 mskb.reserve(16);
11584
11585 switch (src.getSize()) {
11587 mskb.push_back(this->astCtxt->extract(127, 127, op2));
11588 mskb.push_back(this->astCtxt->extract(119, 119, op2));
11589 mskb.push_back(this->astCtxt->extract(111, 111, op2));
11590 mskb.push_back(this->astCtxt->extract(103, 103, op2));
11591 mskb.push_back(this->astCtxt->extract(95, 95, op2));
11592 mskb.push_back(this->astCtxt->extract(87, 87, op2));
11593 mskb.push_back(this->astCtxt->extract(79, 79, op2));
11594 mskb.push_back(this->astCtxt->extract(71, 71, op2));
11595
11597 mskb.push_back(this->astCtxt->extract(63, 63, op2));
11598 mskb.push_back(this->astCtxt->extract(55, 55, op2));
11599 mskb.push_back(this->astCtxt->extract(47, 47, op2));
11600 mskb.push_back(this->astCtxt->extract(39, 39, op2));
11601 mskb.push_back(this->astCtxt->extract(31, 31, op2));
11602 mskb.push_back(this->astCtxt->extract(23, 23, op2));
11603 mskb.push_back(this->astCtxt->extract(15, 15, op2));
11604 mskb.push_back(this->astCtxt->extract(7, 7, op2));
11605 }
11606
11607 auto node = this->astCtxt->zx(
11608 dst.getBitSize() - static_cast<triton::uint32>(mskb.size()),
11609 this->astCtxt->concat(mskb)
11610 );
11611
11612 /* Create symbolic expression */
11613 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVMSKB operation");
11614
11615 /* Apply the taint */
11616 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11617
11618 /* Update the symbolic control flow */
11619 this->controlFlow_s(inst);
11620 }
11621
11622
11623 void x86Semantics::pmovsxbd_s(triton::arch::Instruction& inst) {
11624 auto& dst = inst.operands[0];
11625 auto& src = inst.operands[1];
11626
11627 /* Create symbolic operands */
11628 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11629
11630 /* Create the semantics */
11631 std::vector<triton::ast::SharedAbstractNode> pck;
11632 pck.reserve(4);
11633
11634 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(31, 24, op2)));
11635 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(23, 16, op2)));
11636 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2)));
11637 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2)));
11638
11639 auto node = this->astCtxt->concat(pck);
11640
11641 /* Create symbolic expression */
11642 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVSXBD operation");
11643
11644 /* Apply the taint */
11645 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11646
11647 /* Update the symbolic control flow */
11648 this->controlFlow_s(inst);
11649 }
11650
11651
11652 void x86Semantics::pmovsxbq_s(triton::arch::Instruction& inst) {
11653 auto& dst = inst.operands[0];
11654 auto& src = inst.operands[1];
11655
11656 /* Create symbolic operands */
11657 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11658
11659 /* Create the semantics */
11660 std::vector<triton::ast::SharedAbstractNode> pck;
11661 pck.reserve(2);
11662
11663 pck.push_back(this->astCtxt->sx(triton::bitsize::qword - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2)));
11664 pck.push_back(this->astCtxt->sx(triton::bitsize::qword - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2)));
11665
11666 auto node = this->astCtxt->concat(pck);
11667
11668 /* Create symbolic expression */
11669 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVSXBQ operation");
11670
11671 /* Apply the taint */
11672 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11673
11674 /* Update the symbolic control flow */
11675 this->controlFlow_s(inst);
11676 }
11677
11678
11679 void x86Semantics::pmovsxbw_s(triton::arch::Instruction& inst) {
11680 auto& dst = inst.operands[0];
11681 auto& src = inst.operands[1];
11682
11683 /* Create symbolic operands */
11684 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11685
11686 /* Create the semantics */
11687 std::vector<triton::ast::SharedAbstractNode> pck;
11688 pck.reserve(8);
11689
11690 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(63, 56, op2)));
11691 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(55, 48, op2)));
11692 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(47, 40, op2)));
11693 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(39, 32, op2)));
11694 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(31, 24, op2)));
11695 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(23, 16, op2)));
11696 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2)));
11697 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2)));
11698
11699 auto node = this->astCtxt->concat(pck);
11700
11701 /* Create symbolic expression */
11702 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVSXBW operation");
11703
11704 /* Apply the taint */
11705 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11706
11707 /* Update the symbolic control flow */
11708 this->controlFlow_s(inst);
11709 }
11710
11711
11712 void x86Semantics::pmovsxdq_s(triton::arch::Instruction& inst) {
11713 auto& dst = inst.operands[0];
11714 auto& src = inst.operands[1];
11715
11716 /* Create symbolic operands */
11717 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11718
11719 /* Create the semantics */
11720 std::vector<triton::ast::SharedAbstractNode> pck;
11721 pck.reserve(2);
11722
11723 pck.push_back(this->astCtxt->sx(triton::bitsize::qword - triton::bitsize::dword, this->astCtxt->extract(63, 32, op2)));
11724 pck.push_back(this->astCtxt->sx(triton::bitsize::qword - triton::bitsize::dword, this->astCtxt->extract(31, 0, op2)));
11725
11726 auto node = this->astCtxt->concat(pck);
11727
11728 /* Create symbolic expression */
11729 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVSXDQ operation");
11730
11731 /* Apply the taint */
11732 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11733
11734 /* Update the symbolic control flow */
11735 this->controlFlow_s(inst);
11736 }
11737
11738
11739 void x86Semantics::pmovsxwd_s(triton::arch::Instruction& inst) {
11740 auto& dst = inst.operands[0];
11741 auto& src = inst.operands[1];
11742
11743 /* Create symbolic operands */
11744 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11745
11746 /* Create the semantics */
11747 std::vector<triton::ast::SharedAbstractNode> pck;
11748 pck.reserve(4);
11749
11750 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(63, 48, op2)));
11751 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(47, 32, op2)));
11752 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(31, 16, op2)));
11753 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(15, 0, op2)));
11754
11755 auto node = this->astCtxt->concat(pck);
11756
11757 /* Create symbolic expression */
11758 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVSXWD operation");
11759
11760 /* Apply the taint */
11761 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11762
11763 /* Update the symbolic control flow */
11764 this->controlFlow_s(inst);
11765 }
11766
11767
11768 void x86Semantics::pmovsxwq_s(triton::arch::Instruction& inst) {
11769 auto& dst = inst.operands[0];
11770 auto& src = inst.operands[1];
11771
11772 /* Create symbolic operands */
11773 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11774
11775 /* Create the semantics */
11776 std::vector<triton::ast::SharedAbstractNode> pck;
11777 pck.reserve(2);
11778
11779 pck.push_back(this->astCtxt->sx(triton::bitsize::qword - triton::bitsize::word, this->astCtxt->extract(31, 16, op2)));
11780 pck.push_back(this->astCtxt->sx(triton::bitsize::qword - triton::bitsize::word, this->astCtxt->extract(15, 0, op2)));
11781
11782 auto node = this->astCtxt->concat(pck);
11783
11784 /* Create symbolic expression */
11785 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVSXWQ operation");
11786
11787 /* Apply the taint */
11788 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11789
11790 /* Update the symbolic control flow */
11791 this->controlFlow_s(inst);
11792 }
11793
11794
11795 void x86Semantics::pmovzxbd_s(triton::arch::Instruction& inst) {
11796 auto& dst = inst.operands[0];
11797 auto& src = inst.operands[1];
11798
11799 /* Create symbolic operands */
11800 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11801
11802 /* Create the semantics */
11803 std::vector<triton::ast::SharedAbstractNode> pck;
11804 pck.reserve(4);
11805
11806 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(31, 24, op2)));
11807 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(23, 16, op2)));
11808 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2)));
11809 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2)));
11810
11811 auto node = this->astCtxt->concat(pck);
11812
11813 /* Create symbolic expression */
11814 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVZXBD operation");
11815
11816 /* Apply the taint */
11817 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11818
11819 /* Update the symbolic control flow */
11820 this->controlFlow_s(inst);
11821 }
11822
11823
11824 void x86Semantics::pmovzxbq_s(triton::arch::Instruction& inst) {
11825 auto& dst = inst.operands[0];
11826 auto& src = inst.operands[1];
11827
11828 /* Create symbolic operands */
11829 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11830
11831 /* Create the semantics */
11832 std::vector<triton::ast::SharedAbstractNode> pck;
11833 pck.reserve(2);
11834
11835 pck.push_back(this->astCtxt->zx(triton::bitsize::qword - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2)));
11836 pck.push_back(this->astCtxt->zx(triton::bitsize::qword - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2)));
11837
11838 auto node = this->astCtxt->concat(pck);
11839
11840 /* Create symbolic expression */
11841 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVZXBQ operation");
11842
11843 /* Apply the taint */
11844 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11845
11846 /* Update the symbolic control flow */
11847 this->controlFlow_s(inst);
11848 }
11849
11850
11851 void x86Semantics::pmovzxbw_s(triton::arch::Instruction& inst) {
11852 auto& dst = inst.operands[0];
11853 auto& src = inst.operands[1];
11854
11855 /* Create symbolic operands */
11856 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11857
11858 /* Create the semantics */
11859 std::vector<triton::ast::SharedAbstractNode> pck;
11860 pck.reserve(8);
11861
11862 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(63, 56, op2)));
11863 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(55, 48, op2)));
11864 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(47, 40, op2)));
11865 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(39, 32, op2)));
11866 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(31, 24, op2)));
11867 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(23, 16, op2)));
11868 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2)));
11869 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2)));
11870
11871 auto node = this->astCtxt->concat(pck);
11872
11873 /* Create symbolic expression */
11874 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVZXBW operation");
11875
11876 /* Apply the taint */
11877 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11878
11879 /* Update the symbolic control flow */
11880 this->controlFlow_s(inst);
11881 }
11882
11883
11884 void x86Semantics::pmovzxdq_s(triton::arch::Instruction& inst) {
11885 auto& dst = inst.operands[0];
11886 auto& src = inst.operands[1];
11887
11888 /* Create symbolic operands */
11889 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11890
11891 /* Create the semantics */
11892 std::vector<triton::ast::SharedAbstractNode> pck;
11893 pck.reserve(2);
11894
11895 pck.push_back(this->astCtxt->zx(triton::bitsize::qword - triton::bitsize::dword, this->astCtxt->extract(63, 32, op2)));
11896 pck.push_back(this->astCtxt->zx(triton::bitsize::qword - triton::bitsize::dword, this->astCtxt->extract(31, 0, op2)));
11897
11898 auto node = this->astCtxt->concat(pck);
11899
11900 /* Create symbolic expression */
11901 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVZXDQ operation");
11902
11903 /* Apply the taint */
11904 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11905
11906 /* Update the symbolic control flow */
11907 this->controlFlow_s(inst);
11908 }
11909
11910
11911 void x86Semantics::pmovzxwd_s(triton::arch::Instruction& inst) {
11912 auto& dst = inst.operands[0];
11913 auto& src = inst.operands[1];
11914
11915 /* Create symbolic operands */
11916 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11917
11918 /* Create the semantics */
11919 std::vector<triton::ast::SharedAbstractNode> pck;
11920 pck.reserve(4);
11921
11922 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(63, 48, op2)));
11923 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(47, 32, op2)));
11924 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(31, 16, op2)));
11925 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(15, 0, op2)));
11926
11927 auto node = this->astCtxt->concat(pck);
11928
11929 /* Create symbolic expression */
11930 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVZXWD operation");
11931
11932 /* Apply the taint */
11933 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11934
11935 /* Update the symbolic control flow */
11936 this->controlFlow_s(inst);
11937 }
11938
11939
11940 void x86Semantics::pmovzxwq_s(triton::arch::Instruction& inst) {
11941 auto& dst = inst.operands[0];
11942 auto& src = inst.operands[1];
11943
11944 /* Create symbolic operands */
11945 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11946
11947 /* Create the semantics */
11948 std::vector<triton::ast::SharedAbstractNode> pck;
11949 pck.reserve(2);
11950
11951 pck.push_back(this->astCtxt->zx(triton::bitsize::qword - triton::bitsize::word, this->astCtxt->extract(31, 16, op2)));
11952 pck.push_back(this->astCtxt->zx(triton::bitsize::qword - triton::bitsize::word, this->astCtxt->extract(15, 0, op2)));
11953
11954 auto node = this->astCtxt->concat(pck);
11955
11956 /* Create symbolic expression */
11957 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVZXWQ operation");
11958
11959 /* Apply the taint */
11960 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
11961
11962 /* Update the symbolic control flow */
11963 this->controlFlow_s(inst);
11964 }
11965
11966
11967 void x86Semantics::pmulhw_s(triton::arch::Instruction& inst) {
11968 auto& dst = inst.operands[0];
11969 auto& src = inst.operands[1];
11970
11971 /* Create symbolic operands */
11972 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
11973 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
11974
11975 /* Create the semantics */
11976 std::vector<triton::ast::SharedAbstractNode> pck;
11977 pck.reserve(dst.getSize() / triton::size::word);
11978
11979 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; ++i) {
11980 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
11982 auto n1 = this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op1));
11983 auto n2 = this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op2));
11984 auto node = this->astCtxt->extract(triton::bitsize::dword - 1, triton::bitsize::word, this->astCtxt->bvmul(n1, n2));
11985 pck.push_back(node);
11986 }
11987 auto node = this->astCtxt->concat(pck);
11988
11989 /* Create symbolic expression */
11990 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMULHW operation");
11991
11992 /* Apply the taint */
11993 expr->isTainted = this->taintEngine->taintUnion(dst, src);
11994
11995 /* Update the symbolic control flow */
11996 this->controlFlow_s(inst);
11997 }
11998
11999
12000 void x86Semantics::pmulld_s(triton::arch::Instruction& inst) {
12001 auto& dst = inst.operands[0];
12002 auto& src = inst.operands[1];
12003
12004 /* Create symbolic operands */
12005 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12006 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12007
12008 /* Create the semantics */
12009 std::vector<triton::ast::SharedAbstractNode> pck;
12010 pck.reserve(dst.getSize() / triton::size::dword);
12011
12012 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::dword; ++i) {
12013 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::dword);
12015 auto n1 = this->astCtxt->sx(triton::bitsize::dword, this->astCtxt->extract(high, low, op1));
12016 auto n2 = this->astCtxt->sx(triton::bitsize::dword, this->astCtxt->extract(high, low, op2));
12017 auto node = this->astCtxt->extract(triton::bitsize::dword - 1, 0, this->astCtxt->bvmul(n1, n2));
12018 pck.push_back(node);
12019 }
12020 auto node = this->astCtxt->concat(pck);
12021
12022 /* Create symbolic expression */
12023 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMULLD operation");
12024
12025 /* Apply the taint */
12026 expr->isTainted = this->taintEngine->taintUnion(dst, src);
12027
12028 /* Update the symbolic control flow */
12029 this->controlFlow_s(inst);
12030 }
12031
12032
12033 void x86Semantics::pmullw_s(triton::arch::Instruction& inst) {
12034 auto& dst = inst.operands[0];
12035 auto& src = inst.operands[1];
12036
12037 /* Create symbolic operands */
12038 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12039 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12040
12041 /* Create the semantics */
12042 std::vector<triton::ast::SharedAbstractNode> pck;
12043 pck.reserve(dst.getSize() / triton::size::word);
12044
12045 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; ++i) {
12046 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
12048 auto n1 = this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op1));
12049 auto n2 = this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op2));
12050 auto node = this->astCtxt->extract(triton::bitsize::word - 1, 0, this->astCtxt->bvmul(n1, n2));
12051 pck.push_back(node);
12052 }
12053 auto node = this->astCtxt->concat(pck);
12054
12055 /* Create symbolic expression */
12056 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMULLW operation");
12057
12058 /* Apply the taint */
12059 expr->isTainted = this->taintEngine->taintUnion(dst, src);
12060
12061 /* Update the symbolic control flow */
12062 this->controlFlow_s(inst);
12063 }
12064
12065
12066 void x86Semantics::pmuludq_s(triton::arch::Instruction& inst) {
12067 triton::ast::SharedAbstractNode node = nullptr;
12068 auto& dst = inst.operands[0];
12069 auto& src = inst.operands[1];
12070
12071 /* Create symbolic operands */
12072 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12073 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12074
12075 /* Create the semantics */
12076 switch (dst.getBitSize()) {
12078 auto n1 = this->astCtxt->zx(triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::dword-1, 0, op1));
12079 auto n2 = this->astCtxt->zx(triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::dword-1, 0, op2));
12080 node = this->astCtxt->bvmul(n1, n2);
12081 break;
12082 }
12083
12085 std::vector<triton::ast::SharedAbstractNode> pck;
12086 pck.reserve(2);
12087
12088 auto n1 = this->astCtxt->zx(triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::dword-1, 0, op1));
12089 auto n2 = this->astCtxt->zx(triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::dword-1, 0, op2));
12090
12091 auto n3 = this->astCtxt->zx(triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::qword+triton::bitsize::dword-1, triton::bitsize::qword, op1));
12092 auto n4 = this->astCtxt->zx(triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::qword+triton::bitsize::dword-1, triton::bitsize::qword, op2));
12093
12094 pck.push_back(this->astCtxt->bvmul(n3, n4));
12095 pck.push_back(this->astCtxt->bvmul(n1, n2));
12096
12097 node = this->astCtxt->concat(pck);
12098 break;
12099 }
12100
12101 default:
12102 throw triton::exceptions::Semantics("x86Semantics::pmuludq_s(): Invalid operand size.");
12103 }
12104
12105 /* Create symbolic expression */
12106 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMULUDQ operation");
12107
12108 /* Apply the taint */
12109 expr->isTainted = this->taintEngine->taintUnion(dst, src);
12110
12111 /* Update the symbolic control flow */
12112 this->controlFlow_s(inst);
12113 return;
12114 }
12115
12116
12117 void x86Semantics::popcnt_s(triton::arch::Instruction& inst) {
12118 auto& dst = inst.operands[0];
12119 auto& src = inst.operands[1];
12120
12121 /* Create symbolic operands */
12122 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12123 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12124
12125 /* Create the semantics */
12126 auto node = this->astCtxt->bv(0, dst.getBitSize());
12127 for (triton::uint32 i = 0; i < src.getBitSize(); ++i) {
12128 node = this->astCtxt->bvadd(
12129 node,
12130 this->astCtxt->zx(dst.getBitSize() - 1, this->astCtxt->extract(i, i, op2))
12131 );
12132 }
12133
12134 /* Create symbolic expression */
12135 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "POPCNT operation");
12136
12137 /* Spread taint */
12138 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
12139
12140 /* Update the symbolic control flow */
12141 this->controlFlow_s(inst);
12142 }
12143
12144
12145 void x86Semantics::pop_s(triton::arch::Instruction& inst) {
12146 bool stackRelative = false;
12147 auto stack = this->architecture->getStackPointer();
12148 auto stackValue = static_cast<triton::uint64>(this->architecture->getConcreteRegisterValue(stack));
12149 auto& dst = inst.operands[0];
12151
12152 /* Create symbolic operands */
12153 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
12154
12155 /* Create the semantics */
12156 auto node = op1;
12157
12158 /*
12159 * Create the semantics - side effect
12160 *
12161 * Intel: If the ESP register is used as a base register for addressing a destination operand in
12162 * memory, the POP instruction computes the effective address of the operand after it increments
12163 * the ESP register.
12164 */
12165 if (dst.getType() == triton::arch::OP_MEM) {
12167 /* Check if the base register is the stack pointer */
12168 if (this->architecture->isRegisterValid(base) && this->architecture->getParentRegister(base) == stack) {
12169 /* Align the stack */
12170 alignAddStack_s(inst, src.getSize());
12171 /* Re-initialize the memory access */
12172 this->symbolicEngine->initLeaAst(dst.getMemory());
12173 stackRelative = true;
12174 }
12175 }
12176
12177 /*
12178 * Create the semantics - side effect
12179 *
12180 * Don't increment SP if the destination register is SP.
12181 */
12182 else if (dst.getType() == triton::arch::OP_REG) {
12183 if (this->architecture->getParentRegister(dst.getRegister()) == stack) {
12184 stackRelative = true;
12185 }
12186 }
12187
12188 /* Create symbolic expression */
12189 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "POP operation");
12190
12191 /* Spread taint */
12192 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
12193
12194 /* Create the semantics - side effect */
12195 if (!stackRelative)
12196 alignAddStack_s(inst, src.getSize());
12197
12198 /* Update the symbolic control flow */
12199 this->controlFlow_s(inst);
12200 }
12201
12202
12203 void x86Semantics::popal_s(triton::arch::Instruction& inst) {
12204 auto stack = this->architecture->getStackPointer();
12205 auto stackValue = static_cast<triton::uint64>(this->architecture->getConcreteRegisterValue(stack));
12206 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDI));
12207 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ESI));
12208 auto dst3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EBP));
12209 auto dst4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EBX));
12210 auto dst5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
12211 auto dst6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ECX));
12212 auto dst7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
12213 auto src1 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 0), stack.getSize()));
12214 auto src2 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 1), stack.getSize()));
12215 auto src3 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 2), stack.getSize()));
12216 /* stack.getSize() * 3 (ESP) is voluntarily omitted */
12217 auto src4 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 4), stack.getSize()));
12218 auto src5 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 5), stack.getSize()));
12219 auto src6 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 6), stack.getSize()));
12220 auto src7 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 7), stack.getSize()));
12221
12222 /* Create symbolic operands and semantics */
12223 auto node1 = this->symbolicEngine->getOperandAst(inst, src1);
12224 auto node2 = this->symbolicEngine->getOperandAst(inst, src2);
12225 auto node3 = this->symbolicEngine->getOperandAst(inst, src3);
12226 auto node4 = this->symbolicEngine->getOperandAst(inst, src4);
12227 auto node5 = this->symbolicEngine->getOperandAst(inst, src5);
12228 auto node6 = this->symbolicEngine->getOperandAst(inst, src6);
12229 auto node7 = this->symbolicEngine->getOperandAst(inst, src7);
12230
12231 /* Create symbolic expression */
12232 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1, "POPAL EDI operation");
12233 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "POPAL ESI operation");
12234 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3, "POPAL EBP operation");
12235 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4, "POPAL EBX operation");
12236 auto expr5 = this->symbolicEngine->createSymbolicExpression(inst, node5, dst5, "POPAL EDX operation");
12237 auto expr6 = this->symbolicEngine->createSymbolicExpression(inst, node6, dst6, "POPAL ECX operation");
12238 auto expr7 = this->symbolicEngine->createSymbolicExpression(inst, node7, dst7, "POPAL EAX operation");
12239
12240 /* Spread taint */
12241 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src1);
12242 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src2);
12243 expr3->isTainted = this->taintEngine->taintAssignment(dst3, src3);
12244 expr4->isTainted = this->taintEngine->taintAssignment(dst4, src4);
12245 expr5->isTainted = this->taintEngine->taintAssignment(dst5, src5);
12246 expr6->isTainted = this->taintEngine->taintAssignment(dst6, src6);
12247 expr7->isTainted = this->taintEngine->taintAssignment(dst7, src7);
12248
12249 /* Create the semantics - side effect */
12250 alignAddStack_s(inst, stack.getSize() * 8);
12251
12252 /* Update the symbolic control flow */
12253 this->controlFlow_s(inst);
12254 }
12255
12256
12257 void x86Semantics::popf_s(triton::arch::Instruction& inst) {
12258 auto stack = this->architecture->getStackPointer();
12259 auto stackValue = static_cast<triton::uint64>(this->architecture->getConcreteRegisterValue(stack));
12260 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
12261 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
12262 auto dst3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF));
12263 auto dst4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
12264 auto dst5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
12265 auto dst6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_TF));
12266 auto dst7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_IF));
12267 auto dst8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
12268 auto dst9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
12269 auto dst10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_NT));
12270 auto src = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize()));
12271
12272 /* Create symbolic operands */
12273 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
12274
12275 /* Create the semantics */
12276 auto node1 = this->astCtxt->extract(0, 0, op1);
12277 auto node2 = this->astCtxt->extract(2, 2, op1);
12278 auto node3 = this->astCtxt->extract(4, 4, op1);
12279 auto node4 = this->astCtxt->extract(6, 6, op1);
12280 auto node5 = this->astCtxt->extract(7, 7, op1);
12281 auto node6 = this->astCtxt->extract(8, 8, op1);
12282 auto node7 = this->astCtxt->bvtrue(); /* IF true? */
12283 auto node8 = this->astCtxt->extract(10, 10, op1);
12284 auto node9 = this->astCtxt->extract(11, 11, op1);
12285 /* IOPL don't support */
12286 auto node10 = this->astCtxt->extract(14, 14, op1);
12287
12288 /* Create symbolic expression */
12289 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1.getRegister(), "POPF CF operation");
12290 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2.getRegister(), "POPF PF operation");
12291 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3.getRegister(), "POPF AF operation");
12292 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4.getRegister(), "POPF ZF operation");
12293 auto expr5 = this->symbolicEngine->createSymbolicExpression(inst, node5, dst5.getRegister(), "POPF SF operation");
12294 auto expr6 = this->symbolicEngine->createSymbolicExpression(inst, node6, dst6.getRegister(), "POPF TF operation");
12295 auto expr7 = this->symbolicEngine->createSymbolicExpression(inst, node7, dst7.getRegister(), "POPF IF operation");
12296 auto expr8 = this->symbolicEngine->createSymbolicExpression(inst, node8, dst8.getRegister(), "POPF DF operation");
12297 auto expr9 = this->symbolicEngine->createSymbolicExpression(inst, node9, dst9.getRegister(), "POPF OF operation");
12298 auto expr10 = this->symbolicEngine->createSymbolicExpression(inst, node10, dst10.getRegister(), "POPF NT operation");
12299
12300 /* Spread taint */
12301 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src);
12302 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src);
12303 expr3->isTainted = this->taintEngine->taintAssignment(dst3, src);
12304 expr4->isTainted = this->taintEngine->taintAssignment(dst4, src);
12305 expr5->isTainted = this->taintEngine->taintAssignment(dst5, src);
12306 expr6->isTainted = this->taintEngine->taintAssignment(dst6, src);
12307 expr7->isTainted = this->taintEngine->taintAssignment(dst7, src);
12308 expr8->isTainted = this->taintEngine->taintAssignment(dst8, src);
12309 expr9->isTainted = this->taintEngine->taintAssignment(dst9, src);
12310 expr10->isTainted = this->taintEngine->taintAssignment(dst10, src);
12311
12312 /* Create the semantics - side effect */
12313 alignAddStack_s(inst, src.getSize());
12314
12315 /* Update the symbolic control flow */
12316 this->controlFlow_s(inst);
12317 }
12318
12319
12320 void x86Semantics::popfd_s(triton::arch::Instruction& inst) {
12321 auto stack = this->architecture->getStackPointer();
12322 auto stackValue = static_cast<triton::uint64>(this->architecture->getConcreteRegisterValue(stack));
12323 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
12324 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
12325 auto dst3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF));
12326 auto dst4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
12327 auto dst5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
12328 auto dst6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_TF));
12329 auto dst7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_IF));
12330 auto dst8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
12331 auto dst9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
12332 auto dst10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_NT));
12333 auto dst11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RF));
12334 auto dst12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AC));
12335 auto dst13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ID));
12336 auto src = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize()));
12337
12338 /* Create symbolic operands */
12339 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
12340
12341 /* Create the semantics */
12342 auto node1 = this->astCtxt->extract(0, 0, op1);
12343 auto node2 = this->astCtxt->extract(2, 2, op1);
12344 auto node3 = this->astCtxt->extract(4, 4, op1);
12345 auto node4 = this->astCtxt->extract(6, 6, op1);
12346 auto node5 = this->astCtxt->extract(7, 7, op1);
12347 auto node6 = this->astCtxt->extract(8, 8, op1);
12348 auto node7 = this->astCtxt->bvtrue(); /* IF true? */
12349 auto node8 = this->astCtxt->extract(10, 10, op1);
12350 auto node9 = this->astCtxt->extract(11, 11, op1);
12351 /* IOPL don't support */
12352 auto node10 = this->astCtxt->extract(14, 14, op1);
12353 auto node11 = this->astCtxt->bvfalse(); /* RF clear */
12354 /* VM not changed */
12355 auto node12 = this->astCtxt->extract(18, 18, op1);
12356 /* VIP not changed */
12357 /* VIF not changed */
12358 auto node13 = this->astCtxt->extract(21, 21, op1);
12359
12360 /* Create symbolic expression */
12361 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1.getRegister(), "POPFD CF operation");
12362 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2.getRegister(), "POPFD PF operation");
12363 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3.getRegister(), "POPFD AF operation");
12364 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4.getRegister(), "POPFD ZF operation");
12365 auto expr5 = this->symbolicEngine->createSymbolicExpression(inst, node5, dst5.getRegister(), "POPFD SF operation");
12366 auto expr6 = this->symbolicEngine->createSymbolicExpression(inst, node6, dst6.getRegister(), "POPFD TF operation");
12367 auto expr7 = this->symbolicEngine->createSymbolicExpression(inst, node7, dst7.getRegister(), "POPFD IF operation");
12368 auto expr8 = this->symbolicEngine->createSymbolicExpression(inst, node8, dst8.getRegister(), "POPFD DF operation");
12369 auto expr9 = this->symbolicEngine->createSymbolicExpression(inst, node9, dst9.getRegister(), "POPFD OF operation");
12370 auto expr10 = this->symbolicEngine->createSymbolicExpression(inst, node10, dst10.getRegister(), "POPFD NT operation");
12371 auto expr11 = this->symbolicEngine->createSymbolicExpression(inst, node11, dst11.getRegister(), "POPFD RF operation");
12372 auto expr12 = this->symbolicEngine->createSymbolicExpression(inst, node12, dst12.getRegister(), "POPFD AC operation");
12373 auto expr13 = this->symbolicEngine->createSymbolicExpression(inst, node13, dst13.getRegister(), "POPFD ID operation");
12374
12375 /* Spread taint */
12376 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src);
12377 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src);
12378 expr3->isTainted = this->taintEngine->taintAssignment(dst3, src);
12379 expr4->isTainted = this->taintEngine->taintAssignment(dst4, src);
12380 expr5->isTainted = this->taintEngine->taintAssignment(dst5, src);
12381 expr6->isTainted = this->taintEngine->taintAssignment(dst6, src);
12382 expr7->isTainted = this->taintEngine->taintAssignment(dst7, src);
12383 expr8->isTainted = this->taintEngine->taintAssignment(dst8, src);
12384 expr9->isTainted = this->taintEngine->taintAssignment(dst9, src);
12385 expr10->isTainted = this->taintEngine->taintAssignment(dst10, src);
12386 expr11->isTainted = this->taintEngine->taintAssignment(dst11, src);
12387 expr12->isTainted = this->taintEngine->taintAssignment(dst12, src);
12388 expr13->isTainted = this->taintEngine->taintAssignment(dst13, src);
12389
12390 /* Create the semantics - side effect */
12391 alignAddStack_s(inst, src.getSize());
12392
12393 /* Update the symbolic control flow */
12394 this->controlFlow_s(inst);
12395 }
12396
12397
12398 void x86Semantics::popfq_s(triton::arch::Instruction& inst) {
12399 auto stack = this->architecture->getStackPointer();
12400 auto stackValue = static_cast<triton::uint64>(this->architecture->getConcreteRegisterValue(stack));
12401 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
12402 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
12403 auto dst3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF));
12404 auto dst4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
12405 auto dst5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
12406 auto dst6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_TF));
12407 auto dst7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_IF));
12408 auto dst8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
12409 auto dst9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
12410 auto dst10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_NT));
12411 auto dst11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RF));
12412 auto dst12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AC));
12413 auto dst13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ID));
12414 auto src = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize()));
12415
12416 /* Create symbolic operands */
12417 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
12418
12419 /* Create the semantics */
12420 auto node1 = this->astCtxt->extract(0, 0, op1);
12421 auto node2 = this->astCtxt->extract(2, 2, op1);
12422 auto node3 = this->astCtxt->extract(4, 4, op1);
12423 auto node4 = this->astCtxt->extract(6, 6, op1);
12424 auto node5 = this->astCtxt->extract(7, 7, op1);
12425 auto node6 = this->astCtxt->extract(8, 8, op1);
12426 auto node7 = this->astCtxt->bvtrue(); /* IF true? */
12427 auto node8 = this->astCtxt->extract(10, 10, op1);
12428 auto node9 = this->astCtxt->extract(11, 11, op1);
12429 /* IOPL don't support */
12430 auto node10 = this->astCtxt->extract(14, 14, op1);
12431 auto node11 = this->astCtxt->bvfalse(); /* RF clear */
12432 /* VM not changed */
12433 auto node12 = this->astCtxt->extract(18, 18, op1);
12434 /* VIP not changed */
12435 /* VIF not changed */
12436 auto node13 = this->astCtxt->extract(21, 21, op1);
12437
12438 /* Create symbolic expression */
12439 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1.getRegister(), "POPFQ CF operation");
12440 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2.getRegister(), "POPFQ PF operation");
12441 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3.getRegister(), "POPFQ AF operation");
12442 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4.getRegister(), "POPFQ ZF operation");
12443 auto expr5 = this->symbolicEngine->createSymbolicExpression(inst, node5, dst5.getRegister(), "POPFQ SF operation");
12444 auto expr6 = this->symbolicEngine->createSymbolicExpression(inst, node6, dst6.getRegister(), "POPFQ TF operation");
12445 auto expr7 = this->symbolicEngine->createSymbolicExpression(inst, node7, dst7.getRegister(), "POPFQ IF operation");
12446 auto expr8 = this->symbolicEngine->createSymbolicExpression(inst, node8, dst8.getRegister(), "POPFQ DF operation");
12447 auto expr9 = this->symbolicEngine->createSymbolicExpression(inst, node9, dst9.getRegister(), "POPFQ OF operation");
12448 auto expr10 = this->symbolicEngine->createSymbolicExpression(inst, node10, dst10.getRegister(), "POPFD NT operation");
12449 auto expr11 = this->symbolicEngine->createSymbolicExpression(inst, node11, dst11.getRegister(), "POPFD RF operation");
12450 auto expr12 = this->symbolicEngine->createSymbolicExpression(inst, node12, dst12.getRegister(), "POPFD AC operation");
12451 auto expr13 = this->symbolicEngine->createSymbolicExpression(inst, node13, dst13.getRegister(), "POPFD ID operation");
12452
12453 /* Spread taint */
12454 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src);
12455 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src);
12456 expr3->isTainted = this->taintEngine->taintAssignment(dst3, src);
12457 expr4->isTainted = this->taintEngine->taintAssignment(dst4, src);
12458 expr5->isTainted = this->taintEngine->taintAssignment(dst5, src);
12459 expr6->isTainted = this->taintEngine->taintAssignment(dst6, src);
12460 expr7->isTainted = this->taintEngine->taintAssignment(dst7, src);
12461 expr8->isTainted = this->taintEngine->taintAssignment(dst8, src);
12462 expr9->isTainted = this->taintEngine->taintAssignment(dst9, src);
12463 expr10->isTainted = this->taintEngine->taintAssignment(dst10, src);
12464 expr11->isTainted = this->taintEngine->taintAssignment(dst11, src);
12465 expr12->isTainted = this->taintEngine->taintAssignment(dst12, src);
12466 expr13->isTainted = this->taintEngine->taintAssignment(dst13, src);
12467
12468 /* Create the semantics - side effect */
12469 alignAddStack_s(inst, src.getSize());
12470
12471 /* Update the symbolic control flow */
12472 this->controlFlow_s(inst);
12473 }
12474
12475
12476 void x86Semantics::por_s(triton::arch::Instruction& inst) {
12477 auto& dst = inst.operands[0];
12478 auto& src = inst.operands[1];
12479
12480 /* Create symbolic operands */
12481 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12482 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12483
12484 /* Create the semantics */
12485 auto node = this->astCtxt->bvor(op1, op2);
12486
12487 /* Create symbolic expression */
12488 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "POR operation");
12489
12490 /* Update the x87 FPU Tag Word */
12491 this->updateFTW(inst, expr);
12492
12493 /* Spread taint */
12494 expr->isTainted = this->taintEngine->taintUnion(dst, src);
12495
12496 /* Update the symbolic control flow */
12497 this->controlFlow_s(inst);
12498 }
12499
12500
12501 void x86Semantics::prefetchx_s(triton::arch::Instruction& inst) {
12502 auto& src = inst.operands[0];
12503
12504 /* Only specify that the instruction performs an implicit memory read */
12505 this->symbolicEngine->getOperandAst(inst, src);
12506
12507 /* Update the symbolic control flow */
12508 this->controlFlow_s(inst);
12509 }
12510
12511
12512 void x86Semantics::pshufb_s(triton::arch::Instruction& inst) {
12513 auto& dst = inst.operands[0];
12514 auto& src = inst.operands[1];
12515
12516 /* Create symbolic operands */
12517 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12518 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12519
12520 std::vector<triton::ast::SharedAbstractNode> pack;
12521 pack.reserve(dst.getSize());
12522
12523 /* Create the semantics */
12524 for (int i = dst.getBitSize(); i > 0;) {
12525 i -= 8;
12526 int control = i+7;
12527 int index_low = i;
12528 int index_high = i+(dst.getSize() == 8 ? 2 : 3);
12529 pack.push_back(
12530 this->astCtxt->bvmul(
12531 this->astCtxt->zx(triton::bitsize::byte-1, this->astCtxt->bvnot(
12532 this->astCtxt->extract(control, control, op2))),
12533 this->astCtxt->extract(triton::bitsize::byte-1, 0,
12534 this->astCtxt->bvlshr(
12535 op1,
12536 this->astCtxt->bvmul(
12537 this->astCtxt->zx(triton::bitsize::dqword-(index_high-index_low)-1,
12538 this->astCtxt->extract(index_high, index_low, op2)),
12539 this->astCtxt->bv(8, triton::bitsize::dqword))))));
12540 }
12541
12542 auto node = this->astCtxt->concat(pack);
12543
12544 /* Create symbolic expression */
12545 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSHUFD operation");
12546
12547 /* Spread taint */
12548 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
12549
12550 /* Update the symbolic control flow */
12551 this->controlFlow_s(inst);
12552 }
12553
12554
12555 void x86Semantics::pshufd_s(triton::arch::Instruction& inst) {
12556 auto& dst = inst.operands[0];
12557 auto& src = inst.operands[1];
12558 auto& ord = inst.operands[2];
12559
12560 /* Create symbolic operands */
12561 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12562 auto op3 = this->symbolicEngine->getOperandAst(inst, ord);
12563
12564 /* Create the semantics */
12565 std::vector<triton::ast::SharedAbstractNode> pack;
12566 pack.reserve(4);
12567
12568 pack.push_back(
12569 this->astCtxt->extract(31, 0,
12570 this->astCtxt->bvlshr(
12571 op2,
12572 this->astCtxt->bvmul(
12573 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(7, 6, op3)),
12574 this->astCtxt->bv(32, triton::bitsize::dqword)
12575 )
12576 )
12577 )
12578 );
12579 pack.push_back(
12580 this->astCtxt->extract(31, 0,
12581 this->astCtxt->bvlshr(
12582 op2,
12583 this->astCtxt->bvmul(
12584 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(5, 4, op3)),
12585 this->astCtxt->bv(32, triton::bitsize::dqword)
12586 )
12587 )
12588 )
12589 );
12590 pack.push_back(
12591 this->astCtxt->extract(31, 0,
12592 this->astCtxt->bvlshr(
12593 op2,
12594 this->astCtxt->bvmul(
12595 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(3, 2, op3)),
12596 this->astCtxt->bv(32, triton::bitsize::dqword)
12597 )
12598 )
12599 )
12600 );
12601 pack.push_back(
12602 this->astCtxt->extract(31, 0,
12603 this->astCtxt->bvlshr(
12604 op2,
12605 this->astCtxt->bvmul(
12606 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(1, 0, op3)),
12607 this->astCtxt->bv(32, triton::bitsize::dqword)
12608 )
12609 )
12610 )
12611 );
12612
12613 auto node = this->astCtxt->concat(pack);
12614
12615 /* Create symbolic expression */
12616 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSHUFD operation");
12617
12618 /* Spread taint */
12619 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
12620
12621 /* Update the symbolic control flow */
12622 this->controlFlow_s(inst);
12623 }
12624
12625
12626 void x86Semantics::pshufhw_s(triton::arch::Instruction& inst) {
12627 auto& dst = inst.operands[0];
12628 auto& src = inst.operands[1];
12629 auto& ord = inst.operands[2];
12630
12631 /* Create symbolic operands */
12632 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12633 auto op3 = this->symbolicEngine->getOperandAst(inst, ord);
12634
12635 /* Create the semantics */
12636 std::vector<triton::ast::SharedAbstractNode> pack;
12637 pack.reserve(5);
12638
12639 pack.push_back(
12640 this->astCtxt->extract(79, 64,
12641 this->astCtxt->bvlshr(
12642 op2,
12643 this->astCtxt->bvmul(
12644 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(7, 6, op3)),
12645 this->astCtxt->bv(16, triton::bitsize::dqword)
12646 )
12647 )
12648 )
12649 );
12650 pack.push_back(
12651 this->astCtxt->extract(79, 64,
12652 this->astCtxt->bvlshr(
12653 op2,
12654 this->astCtxt->bvmul(
12655 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(5, 4, op3)),
12656 this->astCtxt->bv(16, triton::bitsize::dqword)
12657 )
12658 )
12659 )
12660 );
12661 pack.push_back(
12662 this->astCtxt->extract(79, 64,
12663 this->astCtxt->bvlshr(
12664 op2,
12665 this->astCtxt->bvmul(
12666 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(3, 2, op3)),
12667 this->astCtxt->bv(16, triton::bitsize::dqword)
12668 )
12669 )
12670 )
12671 );
12672 pack.push_back(
12673 this->astCtxt->extract(79, 64,
12674 this->astCtxt->bvlshr(
12675 op2,
12676 this->astCtxt->bvmul(
12677 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(1, 0, op3)),
12678 this->astCtxt->bv(16, triton::bitsize::dqword)
12679 )
12680 )
12681 )
12682 );
12683 pack.push_back(
12684 this->astCtxt->extract(63, 0, op2)
12685 );
12686
12687 auto node = this->astCtxt->concat(pack);
12688
12689 /* Create symbolic expression */
12690 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSHUFHW operation");
12691
12692 /* Spread taint */
12693 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
12694
12695 /* Update the symbolic control flow */
12696 this->controlFlow_s(inst);
12697 }
12698
12699
12700 void x86Semantics::pshuflw_s(triton::arch::Instruction& inst) {
12701 auto& dst = inst.operands[0];
12702 auto& src = inst.operands[1];
12703 auto& ord = inst.operands[2];
12704
12705 /* Create symbolic operands */
12706 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12707 auto op3 = this->symbolicEngine->getOperandAst(inst, ord);
12708
12709 /* Create the semantics */
12710 std::vector<triton::ast::SharedAbstractNode> pack;
12711 pack.reserve(5);
12712
12713 pack.push_back(
12714 this->astCtxt->extract(127, 64, op2)
12715 );
12716 pack.push_back(
12717 this->astCtxt->extract(15, 0,
12718 this->astCtxt->bvlshr(
12719 op2,
12720 this->astCtxt->bvmul(
12721 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(7, 6, op3)),
12722 this->astCtxt->bv(16, triton::bitsize::dqword)
12723 )
12724 )
12725 )
12726 );
12727 pack.push_back(
12728 this->astCtxt->extract(15, 0,
12729 this->astCtxt->bvlshr(
12730 op2,
12731 this->astCtxt->bvmul(
12732 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(5, 4, op3)),
12733 this->astCtxt->bv(16, triton::bitsize::dqword)
12734 )
12735 )
12736 )
12737 );
12738 pack.push_back(
12739 this->astCtxt->extract(15, 0,
12740 this->astCtxt->bvlshr(
12741 op2,
12742 this->astCtxt->bvmul(
12743 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(3, 2, op3)),
12744 this->astCtxt->bv(16, triton::bitsize::dqword)
12745 )
12746 )
12747 )
12748 );
12749 pack.push_back(
12750 this->astCtxt->extract(15, 0,
12751 this->astCtxt->bvlshr(
12752 op2,
12753 this->astCtxt->bvmul(
12754 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(1, 0, op3)),
12755 this->astCtxt->bv(16, triton::bitsize::dqword)
12756 )
12757 )
12758 )
12759 );
12760
12761 auto node = this->astCtxt->concat(pack);
12762
12763 /* Create symbolic expression */
12764 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSHUFLW operation");
12765
12766 /* Spread taint */
12767 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
12768
12769 /* Update the symbolic control flow */
12770 this->controlFlow_s(inst);
12771 }
12772
12773
12774 void x86Semantics::pshufw_s(triton::arch::Instruction& inst) {
12775 auto& dst = inst.operands[0];
12776 auto& src = inst.operands[1];
12777 auto& ord = inst.operands[2];
12778
12779 /* Create symbolic operands */
12780 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
12781 auto op3 = this->symbolicEngine->getOperandAst(inst, ord);
12782
12783 /* Create the semantics */
12784 std::vector<triton::ast::SharedAbstractNode> pack;
12785 pack.reserve(4);
12786
12787 pack.push_back(
12788 this->astCtxt->extract(15, 0,
12789 this->astCtxt->bvlshr(
12790 op2,
12791 this->astCtxt->bvmul(
12792 this->astCtxt->zx(triton::bitsize::qword-2, this->astCtxt->extract(7, 6, op3)),
12793 this->astCtxt->bv(16, triton::bitsize::qword)
12794 )
12795 )
12796 )
12797 );
12798 pack.push_back(
12799 this->astCtxt->extract(15, 0,
12800 this->astCtxt->bvlshr(
12801 op2,
12802 this->astCtxt->bvmul(
12803 this->astCtxt->zx(triton::bitsize::qword-2, this->astCtxt->extract(5, 4, op3)),
12804 this->astCtxt->bv(16, triton::bitsize::qword)
12805 )
12806 )
12807 )
12808 );
12809 pack.push_back(
12810 this->astCtxt->extract(15, 0,
12811 this->astCtxt->bvlshr(
12812 op2,
12813 this->astCtxt->bvmul(
12814 this->astCtxt->zx(triton::bitsize::qword-2, this->astCtxt->extract(3, 2, op3)),
12815 this->astCtxt->bv(16, triton::bitsize::qword)
12816 )
12817 )
12818 )
12819 );
12820 pack.push_back(
12821 this->astCtxt->extract(15, 0,
12822 this->astCtxt->bvlshr(
12823 op2,
12824 this->astCtxt->bvmul(
12825 this->astCtxt->zx(triton::bitsize::qword-2, this->astCtxt->extract(1, 0, op3)),
12826 this->astCtxt->bv(16, triton::bitsize::qword)
12827 )
12828 )
12829 )
12830 );
12831
12832 auto node = this->astCtxt->concat(pack);
12833
12834 /* Create symbolic expression */
12835 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSHUFW operation");
12836
12837 /* Spread taint */
12838 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
12839
12840 /* Update the symbolic control flow */
12841 this->controlFlow_s(inst);
12842 }
12843
12844
12845 void x86Semantics::pslld_s(triton::arch::Instruction& inst) {
12846 auto& dst = inst.operands[0];
12847 auto& src = inst.operands[1];
12848
12849 /* Create symbolic operands */
12850 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12851 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
12852
12853 /* Create the semantics */
12854 std::vector<triton::ast::SharedAbstractNode> packed;
12855 packed.reserve(4);
12856
12857 switch (dst.getBitSize()) {
12858 /* XMM */
12860 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(127, 96, op1), this->astCtxt->extract(31, 0, op2)));
12861 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract( 95, 64, op1), this->astCtxt->extract(31, 0, op2)));
12862
12863 /* MMX */
12865 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(63, 32, op1), this->astCtxt->extract(31, 0, op2)));
12866 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(31, 0, op1), this->astCtxt->extract(31, 0, op2)));
12867 break;
12868
12869 default:
12870 throw triton::exceptions::Semantics("x86Semantics::pslld_s(): Invalid operand size.");
12871 }
12872
12873 auto node = this->astCtxt->concat(packed);
12874
12875 /* Create symbolic expression */
12876 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSLLD operation");
12877
12878 /* Update the x87 FPU Tag Word */
12879 if (dst.getBitSize() == triton::bitsize::qword) {
12880 this->updateFTW(inst, expr);
12881 }
12882
12883 /* Spread taint */
12884 expr->isTainted = this->taintEngine->taintUnion(dst, src);
12885
12886 /* Update the symbolic control flow */
12887 this->controlFlow_s(inst);
12888 }
12889
12890
12891 void x86Semantics::pslldq_s(triton::arch::Instruction& inst) {
12892 auto& dst = inst.operands[0];
12893 auto& src = inst.operands[1];
12894
12895 /* Create symbolic operands */
12896 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12897 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
12898
12899 /* Create the semantics */
12900 auto node = this->astCtxt->bvshl(
12901 op1,
12902 this->astCtxt->bvmul(
12903 this->astCtxt->ite(
12904 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::word, dst.getBitSize())),
12905 this->astCtxt->bv(triton::bitsize::word, dst.getBitSize()),
12906 op2
12907 ),
12908 this->astCtxt->bv(triton::size::qword, dst.getBitSize())
12909 )
12910 );
12911
12912 /* Create symbolic expression */
12913 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSLLDQ operation");
12914
12915 /* Spread taint */
12916 expr->isTainted = this->taintEngine->taintUnion(dst, src);
12917
12918 /* Update the symbolic control flow */
12919 this->controlFlow_s(inst);
12920 }
12921
12922
12923 void x86Semantics::psllq_s(triton::arch::Instruction& inst) {
12924 auto& dst = inst.operands[0];
12925 auto& src = inst.operands[1];
12926
12927 /* Create symbolic operands */
12928 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12929 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
12930
12931 /* Create the semantics */
12933
12934 std::vector<triton::ast::SharedAbstractNode> packed;
12935 packed.reserve(2);
12936
12937 switch (dst.getBitSize()) {
12938 /* XMM */
12940 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(127, 64, op1), this->astCtxt->extract(63, 0, op2)));
12941 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract( 63, 0, op1), this->astCtxt->extract(63, 0, op2)));
12942 node = this->astCtxt->concat(packed);
12943 break;
12944
12945 /* MMX */
12947 /* MMX register is only one QWORD so it's a simple shl */
12948 node = this->astCtxt->bvshl(op1, op2);
12949 break;
12950
12951 default:
12952 throw triton::exceptions::Semantics("x86Semantics::psllq_s(): Invalid operand size.");
12953 }
12954
12955 /* Create symbolic expression */
12956 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSLLQ operation");
12957
12958 /* Update the x87 FPU Tag Word */
12959 if (dst.getBitSize() == triton::bitsize::qword) {
12960 this->updateFTW(inst, expr);
12961 }
12962
12963 /* Spread taint */
12964 expr->isTainted = this->taintEngine->taintUnion(dst, src);
12965
12966 /* Update the symbolic control flow */
12967 this->controlFlow_s(inst);
12968 }
12969
12970
12971 void x86Semantics::psllw_s(triton::arch::Instruction& inst) {
12972 auto& dst = inst.operands[0];
12973 auto& src = inst.operands[1];
12974
12975 /* Create symbolic operands */
12976 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
12977 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
12978
12979 /* Create the semantics */
12980 std::vector<triton::ast::SharedAbstractNode> packed;
12981 packed.reserve(8);
12982
12983 switch (dst.getBitSize()) {
12984 /* XMM */
12986 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(127, 112, op1), this->astCtxt->extract(15, 0, op2)));
12987 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(111, 96, op1), this->astCtxt->extract(15, 0, op2)));
12988 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract( 95, 80, op1), this->astCtxt->extract(15, 0, op2)));
12989 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract( 79, 64, op1), this->astCtxt->extract(15, 0, op2)));
12990
12991 /* MMX */
12993 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(63, 48, op1), this->astCtxt->extract(15, 0, op2)));
12994 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(47, 32, op1), this->astCtxt->extract(15, 0, op2)));
12995 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(31, 16, op1), this->astCtxt->extract(15, 0, op2)));
12996 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(15, 0, op1), this->astCtxt->extract(15, 0, op2)));
12997 break;
12998
12999 default:
13000 throw triton::exceptions::Semantics("x86Semantics::psllw_s(): Invalid operand size.");
13001 }
13002
13003 auto node = this->astCtxt->concat(packed);
13004
13005 /* Create symbolic expression */
13006 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSLLW operation");
13007
13008 /* Update the x87 FPU Tag Word */
13009 if (dst.getBitSize() == triton::bitsize::qword) {
13010 this->updateFTW(inst, expr);
13011 }
13012
13013 /* Spread taint */
13014 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13015
13016 /* Update the symbolic control flow */
13017 this->controlFlow_s(inst);
13018 }
13019
13020
13021 void x86Semantics::psrad_s(triton::arch::Instruction& inst) {
13022 auto& dst = inst.operands[0];
13023 auto& src = inst.operands[1];
13024
13025 /* Create symbolic operands */
13026 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13027 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13028
13029 /* Create the semantics */
13030 std::vector<triton::ast::SharedAbstractNode> pck;
13031 pck.reserve(dst.getSize() / triton::size::dword);
13032
13033 auto shift = this->astCtxt->ite(
13034 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::dword, src.getBitSize())),
13035 this->astCtxt->bv(triton::bitsize::dword, src.getBitSize()),
13036 op2
13037 );
13038
13039 if (shift->getBitvectorSize() < triton::bitsize::dword) {
13040 shift = this->astCtxt->zx(triton::bitsize::dword - shift->getBitvectorSize(), shift);
13041 }
13042 else {
13043 shift = this->astCtxt->extract(triton::bitsize::dword - 1, 0, shift);
13044 }
13045
13046 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::dword; ++i) {
13047 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::dword);
13049 pck.push_back(this->astCtxt->bvashr(this->astCtxt->extract(high, low, op1), shift));
13050 }
13051 auto node = this->astCtxt->concat(pck);
13052
13053 /* Create symbolic expression */
13054 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSRAD operation");
13055
13056 /* Spread taint */
13057 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13058
13059 /* Update the symbolic control flow */
13060 this->controlFlow_s(inst);
13061 }
13062
13063
13064 void x86Semantics::psraw_s(triton::arch::Instruction& inst) {
13065 auto& dst = inst.operands[0];
13066 auto& src = inst.operands[1];
13067
13068 /* Create symbolic operands */
13069 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13070 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13071
13072 /* Create the semantics */
13073 std::vector<triton::ast::SharedAbstractNode> pck;
13074 pck.reserve(dst.getSize() / triton::size::word);
13075
13076 auto shift = this->astCtxt->ite(
13077 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::word, src.getBitSize())),
13078 this->astCtxt->bv(triton::bitsize::word, src.getBitSize()),
13079 op2
13080 );
13081
13082 if (shift->getBitvectorSize() < triton::bitsize::word) {
13083 shift = this->astCtxt->zx(triton::bitsize::word - shift->getBitvectorSize(), shift);
13084 }
13085 else {
13086 shift = this->astCtxt->extract(triton::bitsize::word - 1, 0, shift);
13087 }
13088
13089 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; ++i) {
13090 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
13092 pck.push_back(this->astCtxt->bvashr(this->astCtxt->extract(high, low, op1), shift));
13093 }
13094 auto node = this->astCtxt->concat(pck);
13095
13096 /* Create symbolic expression */
13097 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSRAW operation");
13098
13099 /* Spread taint */
13100 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13101
13102 /* Update the symbolic control flow */
13103 this->controlFlow_s(inst);
13104 }
13105
13106
13107 void x86Semantics::psrld_s(triton::arch::Instruction& inst) {
13108 auto& dst = inst.operands[0];
13109 auto& src = inst.operands[1];
13110
13111 /* Create symbolic operands */
13112 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13113 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
13114
13115 /* Create the semantics */
13116 std::vector<triton::ast::SharedAbstractNode> packed;
13117 packed.reserve(4);
13118
13119 switch (dst.getBitSize()) {
13120 /* XMM */
13122 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(127, 96, op1), this->astCtxt->extract(31, 0, op2)));
13123 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract( 95, 64, op1), this->astCtxt->extract(31, 0, op2)));
13124
13125 /* MMX */
13127 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(63, 32, op1), this->astCtxt->extract(31, 0, op2)));
13128 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(31, 0, op1), this->astCtxt->extract(31, 0, op2)));
13129 break;
13130
13131 default:
13132 throw triton::exceptions::Semantics("x86Semantics::psrld_s(): Invalid operand size.");
13133 }
13134
13135 auto node = this->astCtxt->concat(packed);
13136
13137 /* Create symbolic expression */
13138 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSRLD operation");
13139
13140 /* Update the x87 FPU Tag Word */
13141 if (dst.getBitSize() == triton::bitsize::qword) {
13142 this->updateFTW(inst, expr);
13143 }
13144
13145 /* Spread taint */
13146 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13147
13148 /* Update the symbolic control flow */
13149 this->controlFlow_s(inst);
13150 }
13151
13152
13153 void x86Semantics::psrldq_s(triton::arch::Instruction& inst) {
13154 auto& dst = inst.operands[0];
13155 auto& src = inst.operands[1];
13156
13157 /* Create symbolic operands */
13158 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13159 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
13160
13161 /* Create the semantics */
13162 auto node = this->astCtxt->bvlshr(
13163 op1,
13164 this->astCtxt->bvmul(
13165 this->astCtxt->ite(
13166 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::word, dst.getBitSize())),
13167 this->astCtxt->bv(triton::bitsize::word, dst.getBitSize()),
13168 op2
13169 ),
13170 this->astCtxt->bv(triton::size::qword, dst.getBitSize())
13171 )
13172 );
13173
13174 /* Create symbolic expression */
13175 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSRLDQ operation");
13176
13177 /* Spread taint */
13178 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13179
13180 /* Update the symbolic control flow */
13181 this->controlFlow_s(inst);
13182 }
13183
13184
13185 void x86Semantics::psrlq_s(triton::arch::Instruction& inst) {
13186 auto& dst = inst.operands[0];
13187 auto& src = inst.operands[1];
13188
13189 /* Create symbolic operands */
13190 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13191 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
13192
13193 /* Create the semantics */
13195
13196 std::vector<triton::ast::SharedAbstractNode> packed;
13197 packed.reserve(2);
13198
13199 switch (dst.getBitSize()) {
13200 /* XMM */
13202 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(127, 64, op1), this->astCtxt->extract(63, 0, op2)));
13203 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract( 63, 0, op1), this->astCtxt->extract(63, 0, op2)));
13204 node = this->astCtxt->concat(packed);
13205 break;
13206
13207 /* MMX */
13209 /* MMX register is only one QWORD so it's a simple shr */
13210 node = this->astCtxt->bvlshr(op1, op2);
13211 break;
13212
13213 default:
13214 throw triton::exceptions::Semantics("x86Semantics::psrlq_s(): Invalid operand size.");
13215 }
13216
13217 /* Create symbolic expression */
13218 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSRLQ operation");
13219
13220 /* Update the x87 FPU Tag Word */
13221 if (dst.getBitSize() == triton::bitsize::qword) {
13222 this->updateFTW(inst, expr);
13223 }
13224
13225 /* Spread taint */
13226 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13227
13228 /* Update the symbolic control flow */
13229 this->controlFlow_s(inst);
13230 }
13231
13232
13233 void x86Semantics::psrlw_s(triton::arch::Instruction& inst) {
13234 auto& dst = inst.operands[0];
13235 auto& src = inst.operands[1];
13236
13237 /* Create symbolic operands */
13238 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13239 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
13240
13241 /* Create the semantics */
13242 std::vector<triton::ast::SharedAbstractNode> packed;
13243 packed.reserve(8);
13244
13245 switch (dst.getBitSize()) {
13246 /* XMM */
13248 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(127, 112, op1), this->astCtxt->extract(15, 0, op2)));
13249 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(111, 96, op1), this->astCtxt->extract(15, 0, op2)));
13250 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract( 95, 80, op1), this->astCtxt->extract(15, 0, op2)));
13251 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract( 79, 64, op1), this->astCtxt->extract(15, 0, op2)));
13252
13253 /* MMX */
13255 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(63, 48, op1), this->astCtxt->extract(15, 0, op2)));
13256 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(47, 32, op1), this->astCtxt->extract(15, 0, op2)));
13257 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(31, 16, op1), this->astCtxt->extract(15, 0, op2)));
13258 packed.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(15, 0, op1), this->astCtxt->extract(15, 0, op2)));
13259 break;
13260
13261 default:
13262 throw triton::exceptions::Semantics("x86Semantics::psrlw_s(): Invalid operand size.");
13263 }
13264
13265 auto node = this->astCtxt->concat(packed);
13266
13267 /* Create symbolic expression */
13268 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSRLW operation");
13269
13270 /* Update the x87 FPU Tag Word */
13271 if (dst.getBitSize() == triton::bitsize::qword) {
13272 this->updateFTW(inst, expr);
13273 }
13274
13275 /* Spread taint */
13276 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13277
13278 /* Update the symbolic control flow */
13279 this->controlFlow_s(inst);
13280 }
13281
13282
13283 void x86Semantics::psubb_s(triton::arch::Instruction& inst) {
13284 auto& dst = inst.operands[0];
13285 auto& src = inst.operands[1];
13286
13287 /* Create symbolic operands */
13288 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13289 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13290
13291 /* Create the semantics */
13292 std::vector<triton::ast::SharedAbstractNode> packed;
13293 packed.reserve(16);
13294
13295 switch (dst.getBitSize()) {
13296
13297 /* XMM */
13299 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(127, 120, op1), this->astCtxt->extract(127, 120, op2)));
13300 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(119, 112, op1), this->astCtxt->extract(119, 112, op2)));
13301 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(111, 104, op1), this->astCtxt->extract(111, 104, op2)));
13302 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(103, 96, op1), this->astCtxt->extract(103, 96, op2)));
13303 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(95, 88, op1), this->astCtxt->extract(95, 88, op2)));
13304 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(87, 80, op1), this->astCtxt->extract(87, 80, op2)));
13305 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(79, 72, op1), this->astCtxt->extract(79, 72, op2)));
13306 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(71, 64, op1), this->astCtxt->extract(71, 64, op2)));
13307
13308 /* MMX */
13310 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(63, 56, op1), this->astCtxt->extract(63, 56, op2)));
13311 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(55, 48, op1), this->astCtxt->extract(55, 48, op2)));
13312 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(47, 40, op1), this->astCtxt->extract(47, 40, op2)));
13313 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(39, 32, op1), this->astCtxt->extract(39, 32, op2)));
13314 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(31, 24, op1), this->astCtxt->extract(31, 24, op2)));
13315 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(23, 16, op1), this->astCtxt->extract(23, 16, op2)));
13316 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(15, 8, op1), this->astCtxt->extract(15, 8, op2)));
13317 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(7, 0, op1), this->astCtxt->extract(7, 0, op2)));
13318 break;
13319
13320 default:
13321 throw triton::exceptions::Semantics("x86Semantics::psubb_s(): Invalid operand size.");
13322
13323 }
13324
13325 auto node = this->astCtxt->concat(packed);
13326
13327 /* Create symbolic expression */
13328 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSUBB operation");
13329
13330 /* Update the x87 FPU Tag Word */
13331 if (dst.getBitSize() == triton::bitsize::qword) {
13332 this->updateFTW(inst, expr);
13333 }
13334
13335 /* Spread taint */
13336 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13337
13338 /* Update the symbolic control flow */
13339 this->controlFlow_s(inst);
13340 }
13341
13342
13343 void x86Semantics::psubd_s(triton::arch::Instruction& inst) {
13344 auto& dst = inst.operands[0];
13345 auto& src = inst.operands[1];
13346
13347 /* Create symbolic operands */
13348 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13349 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13350
13351 /* Create the semantics */
13352 std::vector<triton::ast::SharedAbstractNode> packed;
13353 packed.reserve(4);
13354
13355 switch (dst.getBitSize()) {
13356
13357 /* XMM */
13359 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(127, 96, op1), this->astCtxt->extract(127, 96, op2)));
13360 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(95, 64, op1), this->astCtxt->extract(95, 64, op2)));
13361
13362 /* MMX */
13364 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(63, 32, op1), this->astCtxt->extract(63, 32, op2)));
13365 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(31, 0, op1), this->astCtxt->extract(31, 0, op2)));
13366 break;
13367
13368 default:
13369 throw triton::exceptions::Semantics("x86Semantics::psubd_s(): Invalid operand size.");
13370
13371 }
13372
13373 auto node = this->astCtxt->concat(packed);
13374
13375 /* Create symbolic expression */
13376 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSUBD operation");
13377
13378 /* Update the x87 FPU Tag Word */
13379 if (dst.getBitSize() == triton::bitsize::qword) {
13380 this->updateFTW(inst, expr);
13381 }
13382
13383 /* Spread taint */
13384 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13385
13386 /* Update the symbolic control flow */
13387 this->controlFlow_s(inst);
13388 }
13389
13390
13391 void x86Semantics::psubq_s(triton::arch::Instruction& inst) {
13392 auto& dst = inst.operands[0];
13393 auto& src = inst.operands[1];
13394
13395 /* Create symbolic operands */
13396 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13397 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13398
13399 /* Create the semantics */
13400 std::vector<triton::ast::SharedAbstractNode> packed;
13401 packed.reserve(2);
13402
13403 switch (dst.getBitSize()) {
13404
13405 /* XMM */
13407 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(127, 64, op1), this->astCtxt->extract(127, 64, op2)));
13408
13409 /* MMX */
13411 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(63, 0, op1), this->astCtxt->extract(63, 0, op2)));
13412 break;
13413
13414 default:
13415 throw triton::exceptions::Semantics("x86Semantics::psubq_s(): Invalid operand size.");
13416
13417 }
13418
13419 auto node = this->astCtxt->concat(packed);
13420
13421 /* Create symbolic expression */
13422 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSUBQ operation");
13423
13424 /* Update the x87 FPU Tag Word */
13425 if (dst.getBitSize() == triton::bitsize::qword) {
13426 this->updateFTW(inst, expr);
13427 }
13428
13429 /* Spread taint */
13430 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13431
13432 /* Update the symbolic control flow */
13433 this->controlFlow_s(inst);
13434 }
13435
13436
13437 void x86Semantics::psubw_s(triton::arch::Instruction& inst) {
13438 auto& dst = inst.operands[0];
13439 auto& src = inst.operands[1];
13440
13441 /* Create symbolic operands */
13442 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13443 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13444
13445 /* Create the semantics */
13446 std::vector<triton::ast::SharedAbstractNode> packed;
13447 packed.reserve(8);
13448
13449 switch (dst.getBitSize()) {
13450
13451 /* XMM */
13453 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(127, 112, op1), this->astCtxt->extract(127, 112, op2)));
13454 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(111, 96, op1), this->astCtxt->extract(111, 96, op2)));
13455 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(95, 80, op1), this->astCtxt->extract(95, 80, op2)));
13456 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(79, 64, op1), this->astCtxt->extract(79, 64, op2)));
13457
13458 /* MMX */
13460 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(63, 48, op1), this->astCtxt->extract(63, 48, op2)));
13461 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(47, 32, op1), this->astCtxt->extract(47, 32, op2)));
13462 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(31, 16, op1), this->astCtxt->extract(31, 16, op2)));
13463 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(15, 0, op1), this->astCtxt->extract(15, 0, op2)));
13464 break;
13465
13466 default:
13467 throw triton::exceptions::Semantics("x86Semantics::psubw_s(): Invalid operand size.");
13468
13469 }
13470
13471 auto node = this->astCtxt->concat(packed);
13472
13473 /* Create symbolic expression */
13474 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSUBW operation");
13475
13476 /* Update the x87 FPU Tag Word */
13477 if (dst.getBitSize() == triton::bitsize::qword) {
13478 this->updateFTW(inst, expr);
13479 }
13480
13481 /* Spread taint */
13482 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13483
13484 /* Update the symbolic control flow */
13485 this->controlFlow_s(inst);
13486 }
13487
13488
13489 void x86Semantics::ptest_s(triton::arch::Instruction& inst) {
13490 auto& src1 = inst.operands[0];
13491 auto& src2 = inst.operands[1];
13492
13493 /* Create symbolic operands */
13494 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
13495 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
13496
13497 /* Create the semantics */
13498 auto node1 = this->astCtxt->bvand(op1, op2);
13499 auto node2 = this->astCtxt->bvand(op1, this->astCtxt->bvnot(op2));
13500
13501 /* Create symbolic expression */
13502 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "PTEST operation");
13503 auto expr2 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node2, "PTEST operation");
13504
13505 /* Spread taint */
13506 expr1->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2);
13507 expr2->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2);
13508
13509 /* Update symbolic flags */
13510 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_AF), "Clears adjust flag");
13511 this->cfPtest_s(inst, expr2, src1, true);
13512 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
13513 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_PF), "Clears parity flag");
13514 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_SF), "Clears sign flag");
13515 this->zf_s(inst, expr1, src1, true);
13516
13517 /* Update the symbolic control flow */
13518 this->controlFlow_s(inst);
13519 }
13520
13521
13522 void x86Semantics::punpckhbw_s(triton::arch::Instruction& inst) {
13523 auto& dst = inst.operands[0];
13524 auto& src = inst.operands[1];
13525
13526 /* Create symbolic operands */
13527 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13528 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13529
13530 /* Create the semantics */
13531 std::vector<triton::ast::SharedAbstractNode> unpack;
13532 unpack.reserve(24);
13533
13534 switch (dst.getBitSize()) {
13535
13536 /* MMX */
13538 unpack.push_back(this->astCtxt->extract(63, 56, op2));
13539 unpack.push_back(this->astCtxt->extract(63, 56, op1));
13540 unpack.push_back(this->astCtxt->extract(55, 48, op2));
13541 unpack.push_back(this->astCtxt->extract(55, 48, op1));
13542 unpack.push_back(this->astCtxt->extract(47, 40, op2));
13543 unpack.push_back(this->astCtxt->extract(55, 40, op1));
13544 unpack.push_back(this->astCtxt->extract(39, 32, op2));
13545 unpack.push_back(this->astCtxt->extract(39, 32, op1));
13546 break;
13547
13548 /* XMM */
13550 unpack.push_back(this->astCtxt->extract(127, 120, op2));
13551 unpack.push_back(this->astCtxt->extract(127, 120, op1));
13552 unpack.push_back(this->astCtxt->extract(119, 112, op2));
13553 unpack.push_back(this->astCtxt->extract(119, 112, op1));
13554 unpack.push_back(this->astCtxt->extract(111, 104, op2));
13555 unpack.push_back(this->astCtxt->extract(111, 104, op1));
13556 unpack.push_back(this->astCtxt->extract(103, 96, op2));
13557 unpack.push_back(this->astCtxt->extract(103, 96, op1));
13558 unpack.push_back(this->astCtxt->extract(95, 88, op2));
13559 unpack.push_back(this->astCtxt->extract(95, 88, op1));
13560 unpack.push_back(this->astCtxt->extract(87, 80, op2));
13561 unpack.push_back(this->astCtxt->extract(87, 80, op1));
13562 unpack.push_back(this->astCtxt->extract(79, 72, op2));
13563 unpack.push_back(this->astCtxt->extract(79, 72, op1));
13564 unpack.push_back(this->astCtxt->extract(71, 64, op2));
13565 unpack.push_back(this->astCtxt->extract(71, 64, op1));
13566 break;
13567
13568 default:
13569 throw triton::exceptions::Semantics("x86Semantics::punpckhbw_s(): Invalid operand size.");
13570 }
13571
13572 auto node = this->astCtxt->concat(unpack);
13573
13574 /* Create symbolic expression */
13575 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKHBW operation");
13576
13577 /* Update the x87 FPU Tag Word */
13578 if (dst.getBitSize() == triton::bitsize::qword) {
13579 this->updateFTW(inst, expr);
13580 }
13581
13582 /* Apply the taint */
13583 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13584
13585 /* Update the symbolic control flow */
13586 this->controlFlow_s(inst);
13587 }
13588
13589
13590 void x86Semantics::punpckhdq_s(triton::arch::Instruction& inst) {
13591 auto& dst = inst.operands[0];
13592 auto& src = inst.operands[1];
13593
13594 /* Create symbolic operands */
13595 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13596 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13597
13598 /* Create the semantics */
13599 std::vector<triton::ast::SharedAbstractNode> unpack;
13600 unpack.reserve(6);
13601
13602 switch (dst.getBitSize()) {
13603
13604 /* MMX */
13606 unpack.push_back(this->astCtxt->extract(63, 32, op2));
13607 unpack.push_back(this->astCtxt->extract(63, 32, op1));
13608 break;
13609
13610 /* XMM */
13612 unpack.push_back(this->astCtxt->extract(127, 96, op2));
13613 unpack.push_back(this->astCtxt->extract(127, 96, op1));
13614 unpack.push_back(this->astCtxt->extract(95, 64, op2));
13615 unpack.push_back(this->astCtxt->extract(95, 64, op1));
13616 break;
13617
13618 default:
13619 throw triton::exceptions::Semantics("x86Semantics::punpckhdq_s(): Invalid operand size.");
13620 }
13621
13622 auto node = this->astCtxt->concat(unpack);
13623
13624 /* Create symbolic expression */
13625 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKHDQ operation");
13626
13627 /* Update the x87 FPU Tag Word */
13628 if (dst.getBitSize() == triton::bitsize::qword) {
13629 this->updateFTW(inst, expr);
13630 }
13631
13632 /* Apply the taint */
13633 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13634
13635 /* Update the symbolic control flow */
13636 this->controlFlow_s(inst);
13637 }
13638
13639
13640 void x86Semantics::punpckhqdq_s(triton::arch::Instruction& inst) {
13641 auto& dst = inst.operands[0];
13642 auto& src = inst.operands[1];
13643
13644 /* Create symbolic operands */
13645 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13646 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13647
13648 /* Create the semantics */
13649 std::vector<triton::ast::SharedAbstractNode> unpack;
13650 unpack.reserve(2);
13651
13652 switch (dst.getBitSize()) {
13653
13654 /* XMM */
13656 unpack.push_back(this->astCtxt->extract(127, 64, op2));
13657 unpack.push_back(this->astCtxt->extract(127, 64, op1));
13658 break;
13659
13660 default:
13661 throw triton::exceptions::Semantics("x86Semantics::punpckhqdq_s(): Invalid operand size.");
13662 }
13663
13664 auto node = this->astCtxt->concat(unpack);
13665
13666 /* Create symbolic expression */
13667 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKHQDQ operation");
13668
13669 /* Apply the taint */
13670 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13671
13672 /* Update the symbolic control flow */
13673 this->controlFlow_s(inst);
13674 }
13675
13676
13677 void x86Semantics::punpckhwd_s(triton::arch::Instruction& inst) {
13678 auto& dst = inst.operands[0];
13679 auto& src = inst.operands[1];
13680
13681 /* Create symbolic operands */
13682 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13683 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13684
13685 /* Create the semantics */
13686 std::vector<triton::ast::SharedAbstractNode> unpack;
13687 unpack.reserve(12);
13688
13689 switch (dst.getBitSize()) {
13690
13691 /* MMX */
13693 unpack.push_back(this->astCtxt->extract(63, 48, op2));
13694 unpack.push_back(this->astCtxt->extract(63, 48, op1));
13695 unpack.push_back(this->astCtxt->extract(47, 32, op2));
13696 unpack.push_back(this->astCtxt->extract(47, 32, op1));
13697 break;
13698
13699 /* XMM */
13701 unpack.push_back(this->astCtxt->extract(127, 112, op2));
13702 unpack.push_back(this->astCtxt->extract(127, 112, op1));
13703 unpack.push_back(this->astCtxt->extract(111, 96, op2));
13704 unpack.push_back(this->astCtxt->extract(111, 96, op1));
13705 unpack.push_back(this->astCtxt->extract(95, 80, op2));
13706 unpack.push_back(this->astCtxt->extract(95, 80, op1));
13707 unpack.push_back(this->astCtxt->extract(79, 64, op2));
13708 unpack.push_back(this->astCtxt->extract(79, 64, op1));
13709 break;
13710
13711 default:
13712 throw triton::exceptions::Semantics("x86Semantics::punpckhwd_s(): Invalid operand size.");
13713 }
13714
13715 auto node = this->astCtxt->concat(unpack);
13716
13717 /* Create symbolic expression */
13718 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKHWD operation");
13719
13720 /* Update the x87 FPU Tag Word */
13721 if (dst.getBitSize() == triton::bitsize::qword) {
13722 this->updateFTW(inst, expr);
13723 }
13724
13725 /* Apply the taint */
13726 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13727
13728 /* Update the symbolic control flow */
13729 this->controlFlow_s(inst);
13730 }
13731
13732
13733 void x86Semantics::punpcklbw_s(triton::arch::Instruction& inst) {
13734 auto& dst = inst.operands[0];
13735 auto& src = inst.operands[1];
13736
13737 /* Create symbolic operands */
13738 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13739 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13740
13741 /* Create the semantics */
13742 std::vector<triton::ast::SharedAbstractNode> unpack;
13743 unpack.reserve(24);
13744
13745 switch (dst.getBitSize()) {
13746
13747 /* MMX */
13749 unpack.push_back(this->astCtxt->extract(31, 24, op2));
13750 unpack.push_back(this->astCtxt->extract(31, 24, op1));
13751 unpack.push_back(this->astCtxt->extract(23, 16, op2));
13752 unpack.push_back(this->astCtxt->extract(23, 16, op1));
13753 unpack.push_back(this->astCtxt->extract(15, 8, op2));
13754 unpack.push_back(this->astCtxt->extract(15, 8, op1));
13755 unpack.push_back(this->astCtxt->extract(7, 0, op2));
13756 unpack.push_back(this->astCtxt->extract(7, 0, op1));
13757 break;
13758
13759 /* XMM */
13761 unpack.push_back(this->astCtxt->extract(63, 56, op2));
13762 unpack.push_back(this->astCtxt->extract(63, 56, op1));
13763 unpack.push_back(this->astCtxt->extract(55, 48, op2));
13764 unpack.push_back(this->astCtxt->extract(55, 48, op1));
13765 unpack.push_back(this->astCtxt->extract(47, 40, op2));
13766 unpack.push_back(this->astCtxt->extract(47, 40, op1));
13767 unpack.push_back(this->astCtxt->extract(39, 32, op2));
13768 unpack.push_back(this->astCtxt->extract(39, 32, op1));
13769 unpack.push_back(this->astCtxt->extract(31, 24, op2));
13770 unpack.push_back(this->astCtxt->extract(31, 24, op1));
13771 unpack.push_back(this->astCtxt->extract(23, 16, op2));
13772 unpack.push_back(this->astCtxt->extract(23, 16, op1));
13773 unpack.push_back(this->astCtxt->extract(15, 8, op2));
13774 unpack.push_back(this->astCtxt->extract(15, 8, op1));
13775 unpack.push_back(this->astCtxt->extract(7, 0, op2));
13776 unpack.push_back(this->astCtxt->extract(7, 0, op1));
13777 break;
13778
13779 default:
13780 throw triton::exceptions::Semantics("x86Semantics::punpcklbw_s(): Invalid operand size.");
13781 }
13782
13783 auto node = this->astCtxt->concat(unpack);
13784
13785 /* Create symbolic expression */
13786 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKLBW operation");
13787
13788 /* Update the x87 FPU Tag Word */
13789 if (dst.getBitSize() == triton::bitsize::qword) {
13790 this->updateFTW(inst, expr);
13791 }
13792
13793 /* Apply the taint */
13794 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13795
13796 /* Update the symbolic control flow */
13797 this->controlFlow_s(inst);
13798 }
13799
13800
13801 void x86Semantics::punpckldq_s(triton::arch::Instruction& inst) {
13802 auto& dst = inst.operands[0];
13803 auto& src = inst.operands[1];
13804
13805 /* Create symbolic operands */
13806 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13807 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13808
13809 /* Create the semantics */
13810 std::vector<triton::ast::SharedAbstractNode> unpack;
13811 unpack.reserve(6);
13812
13813 switch (dst.getBitSize()) {
13814
13815 /* MMX */
13817 unpack.push_back(this->astCtxt->extract(31, 0, op2));
13818 unpack.push_back(this->astCtxt->extract(31, 0, op1));
13819 break;
13820
13821 /* XMM */
13823 unpack.push_back(this->astCtxt->extract(63, 32, op2));
13824 unpack.push_back(this->astCtxt->extract(63, 32, op1));
13825 unpack.push_back(this->astCtxt->extract(31, 0, op2));
13826 unpack.push_back(this->astCtxt->extract(31, 0, op1));
13827 break;
13828
13829 default:
13830 throw triton::exceptions::Semantics("x86Semantics::punpckldq_s(): Invalid operand size.");
13831 }
13832
13833 auto node = this->astCtxt->concat(unpack);
13834
13835 /* Create symbolic expression */
13836 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKLDQ operation");
13837
13838 /* Update the x87 FPU Tag Word */
13839 if (dst.getBitSize() == triton::bitsize::qword) {
13840 this->updateFTW(inst, expr);
13841 }
13842
13843 /* Apply the taint */
13844 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13845
13846 /* Update the symbolic control flow */
13847 this->controlFlow_s(inst);
13848 }
13849
13850
13851 void x86Semantics::punpcklqdq_s(triton::arch::Instruction& inst) {
13852 auto& dst = inst.operands[0];
13853 auto& src = inst.operands[1];
13854
13855 /* Create symbolic operands */
13856 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13857 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13858
13859 /* Create the semantics */
13860 std::vector<triton::ast::SharedAbstractNode> unpack;
13861 unpack.reserve(2);
13862
13863 switch (dst.getBitSize()) {
13864
13865 /* XMM */
13867 unpack.push_back(this->astCtxt->extract(63, 0, op2));
13868 unpack.push_back(this->astCtxt->extract(63, 0, op1));
13869 break;
13870
13871 default:
13872 throw triton::exceptions::Semantics("x86Semantics::punpcklqdq_s(): Invalid operand size.");
13873 }
13874
13875 auto node = this->astCtxt->concat(unpack);
13876
13877 /* Create symbolic expression */
13878 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKLQDQ operation");
13879
13880 /* Apply the taint */
13881 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13882
13883 /* Update the symbolic control flow */
13884 this->controlFlow_s(inst);
13885 }
13886
13887
13888 void x86Semantics::punpcklwd_s(triton::arch::Instruction& inst) {
13889 auto& dst = inst.operands[0];
13890 auto& src = inst.operands[1];
13891
13892 /* Create symbolic operands */
13893 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
13894 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
13895
13896 /* Create the semantics */
13897 std::vector<triton::ast::SharedAbstractNode> unpack;
13898 unpack.reserve(12);
13899
13900 switch (dst.getBitSize()) {
13901
13902 /* MMX */
13904 unpack.push_back(this->astCtxt->extract(31, 16, op2));
13905 unpack.push_back(this->astCtxt->extract(31, 16, op1));
13906 unpack.push_back(this->astCtxt->extract(15, 0, op2));
13907 unpack.push_back(this->astCtxt->extract(15, 0, op1));
13908 break;
13909
13910 /* XMM */
13912 unpack.push_back(this->astCtxt->extract(63, 48, op2));
13913 unpack.push_back(this->astCtxt->extract(63, 48, op1));
13914 unpack.push_back(this->astCtxt->extract(47, 32, op2));
13915 unpack.push_back(this->astCtxt->extract(47, 32, op1));
13916 unpack.push_back(this->astCtxt->extract(31, 16, op2));
13917 unpack.push_back(this->astCtxt->extract(31, 16, op1));
13918 unpack.push_back(this->astCtxt->extract(15, 0, op2));
13919 unpack.push_back(this->astCtxt->extract(15, 0, op1));
13920 break;
13921
13922 default:
13923 throw triton::exceptions::Semantics("x86Semantics::punpcklwd_s(): Invalid operand size.");
13924 }
13925
13926 auto node = this->astCtxt->concat(unpack);
13927
13928 /* Create symbolic expression */
13929 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKLWD operation");
13930
13931 /* Update the x87 FPU Tag Word */
13932 if (dst.getBitSize() == triton::bitsize::qword) {
13933 this->updateFTW(inst, expr);
13934 }
13935
13936 /* Apply the taint */
13937 expr->isTainted = this->taintEngine->taintUnion(dst, src);
13938
13939 /* Update the symbolic control flow */
13940 this->controlFlow_s(inst);
13941 }
13942
13943
13944 void x86Semantics::push_s(triton::arch::Instruction& inst) {
13945 auto& src = inst.operands[0];
13946 auto stack = this->architecture->getStackPointer();
13947 triton::uint32 size = stack.getSize();
13948
13949 /* If it's an immediate source, the memory access is always based on the arch size */
13950 if (src.getType() != triton::arch::OP_IMM)
13951 size = src.getSize();
13952
13953 /* Create symbolic operands */
13954 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
13955
13956 /* Create the semantics - side effect */
13957 auto stackValue = alignSubStack_s(inst, size);
13958 auto dst = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, size));
13959
13960 /* Create the semantics */
13961 auto node = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), op1);
13962
13963 /* Create symbolic expression */
13964 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUSH operation");
13965
13966 /* Spread taint */
13967 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
13968
13969 /* Update the symbolic control flow */
13970 this->controlFlow_s(inst);
13971 }
13972
13973
13974 void x86Semantics::pushal_s(triton::arch::Instruction& inst) {
13975 auto stack = this->architecture->getStackPointer();
13976 auto stackValue = static_cast<triton::uint64>(this->architecture->getConcreteRegisterValue(stack));
13977 auto dst1 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 1), stack.getSize()));
13978 auto dst2 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 2), stack.getSize()));
13979 auto dst3 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 3), stack.getSize()));
13980 auto dst4 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 4), stack.getSize()));
13981 auto dst5 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 5), stack.getSize()));
13982 auto dst6 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 6), stack.getSize()));
13983 auto dst7 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 7), stack.getSize()));
13984 auto dst8 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 8), stack.getSize()));
13985 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
13986 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ECX));
13987 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
13988 auto src4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EBX));
13989 auto src5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ESP));
13990 auto src6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EBP));
13991 auto src7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ESI));
13992 auto src8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDI));
13993
13994 /* Create symbolic operands */
13995 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
13996 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
13997 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
13998 auto op4 = this->symbolicEngine->getOperandAst(inst, src4);
13999 auto op5 = this->symbolicEngine->getOperandAst(inst, src5);
14000 auto op6 = this->symbolicEngine->getOperandAst(inst, src6);
14001 auto op7 = this->symbolicEngine->getOperandAst(inst, src7);
14002 auto op8 = this->symbolicEngine->getOperandAst(inst, src8);
14003
14004 /* Create the semantics */
14005 auto node1 = this->astCtxt->zx(dst1.getBitSize() - src1.getBitSize(), op1);
14006 auto node2 = this->astCtxt->zx(dst2.getBitSize() - src2.getBitSize(), op2);
14007 auto node3 = this->astCtxt->zx(dst3.getBitSize() - src3.getBitSize(), op3);
14008 auto node4 = this->astCtxt->zx(dst4.getBitSize() - src4.getBitSize(), op4);
14009 auto node5 = this->astCtxt->zx(dst5.getBitSize() - src5.getBitSize(), op5);
14010 auto node6 = this->astCtxt->zx(dst6.getBitSize() - src6.getBitSize(), op6);
14011 auto node7 = this->astCtxt->zx(dst7.getBitSize() - src7.getBitSize(), op7);
14012 auto node8 = this->astCtxt->zx(dst8.getBitSize() - src8.getBitSize(), op8);
14013
14014 /* Create symbolic expression */
14015 alignSubStack_s(inst, 32);
14016 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1, "PUSHAL EAX operation");
14017 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "PUSHAL ECX operation");
14018 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3, "PUSHAL EDX operation");
14019 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4, "PUSHAL EBX operation");
14020 auto expr5 = this->symbolicEngine->createSymbolicExpression(inst, node5, dst5, "PUSHAL ESP operation");
14021 auto expr6 = this->symbolicEngine->createSymbolicExpression(inst, node6, dst6, "PUSHAL EBP operation");
14022 auto expr7 = this->symbolicEngine->createSymbolicExpression(inst, node7, dst7, "PUSHAL ESI operation");
14023 auto expr8 = this->symbolicEngine->createSymbolicExpression(inst, node8, dst8, "PUSHAL EDI operation");
14024
14025 /* Spread taint */
14026 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src1);
14027 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src2);
14028 expr3->isTainted = this->taintEngine->taintAssignment(dst3, src3);
14029 expr4->isTainted = this->taintEngine->taintAssignment(dst4, src4);
14030 expr5->isTainted = this->taintEngine->taintAssignment(dst5, src5);
14031 expr6->isTainted = this->taintEngine->taintAssignment(dst6, src6);
14032 expr7->isTainted = this->taintEngine->taintAssignment(dst7, src7);
14033 expr8->isTainted = this->taintEngine->taintAssignment(dst8, src8);
14034
14035 /* Update the symbolic control flow */
14036 this->controlFlow_s(inst);
14037 }
14038
14039
14040 void x86Semantics::pushfd_s(triton::arch::Instruction& inst) {
14041 auto stack = this->architecture->getStackPointer();
14042
14043 /* Create the semantics - side effect */
14044 auto stackValue = alignSubStack_s(inst, stack.getSize());
14045 auto dst = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize()));
14046 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
14047 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
14048 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF));
14049 auto src4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
14050 auto src5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
14051 auto src6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_TF));
14052 auto src7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_IF));
14053 auto src8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
14054 auto src9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
14055 auto src10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_NT));
14056 auto src11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AC));
14057 auto src12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_VIF));
14058 auto src13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_VIP));
14059 auto src14 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ID));
14060
14061 /* Create symbolic operands */
14062 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
14063 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
14064 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
14065 auto op4 = this->symbolicEngine->getOperandAst(inst, src4);
14066 auto op5 = this->symbolicEngine->getOperandAst(inst, src5);
14067 auto op6 = this->symbolicEngine->getOperandAst(inst, src6);
14068 auto op7 = this->symbolicEngine->getOperandAst(inst, src7);
14069 auto op8 = this->symbolicEngine->getOperandAst(inst, src8);
14070 auto op9 = this->symbolicEngine->getOperandAst(inst, src9);
14071 auto op10 = this->symbolicEngine->getOperandAst(inst, src10);
14072 auto op11 = this->symbolicEngine->getOperandAst(inst, src11);
14073 auto op12 = this->symbolicEngine->getOperandAst(inst, src12);
14074 auto op13 = this->symbolicEngine->getOperandAst(inst, src13);
14075 auto op14 = this->symbolicEngine->getOperandAst(inst, src14);
14076
14077 /* Create the semantics */
14078 std::vector<triton::ast::SharedAbstractNode> eflags;
14079 eflags.reserve(22);
14080
14081 eflags.push_back(op14);
14082 eflags.push_back(op13);
14083 eflags.push_back(op12);
14084 eflags.push_back(op11);
14085 eflags.push_back(this->astCtxt->bvfalse()); /* vm */
14086 eflags.push_back(this->astCtxt->bvfalse()); /* rf */
14087 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */
14088 eflags.push_back(op10);
14089 eflags.push_back(this->astCtxt->bvfalse()); /* iopl */
14090 eflags.push_back(this->astCtxt->bvfalse()); /* iopl */
14091 eflags.push_back(op9);
14092 eflags.push_back(op8);
14093 eflags.push_back(op7);
14094 eflags.push_back(op6);
14095 eflags.push_back(op5);
14096 eflags.push_back(op4);
14097 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */
14098 eflags.push_back(op3);
14099 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */
14100 eflags.push_back(op2);
14101 eflags.push_back(this->astCtxt->bvtrue()); /* Reserved */
14102 eflags.push_back(op1);
14103
14104 auto node = this->astCtxt->zx(
14105 dst.getBitSize() - static_cast<triton::uint32>(eflags.size()),
14106 this->astCtxt->concat(eflags)
14107 );
14108
14109 /* Create symbolic expression */
14110 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUSHFD operation");
14111
14112 /* Spread taint */
14113 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
14114 expr->isTainted = this->taintEngine->taintUnion(dst, src2);
14115 expr->isTainted = this->taintEngine->taintUnion(dst, src3);
14116 expr->isTainted = this->taintEngine->taintUnion(dst, src4);
14117 expr->isTainted = this->taintEngine->taintUnion(dst, src5);
14118 expr->isTainted = this->taintEngine->taintUnion(dst, src6);
14119 expr->isTainted = this->taintEngine->taintUnion(dst, src7);
14120 expr->isTainted = this->taintEngine->taintUnion(dst, src8);
14121 expr->isTainted = this->taintEngine->taintUnion(dst, src9);
14122 expr->isTainted = this->taintEngine->taintUnion(dst, src10);
14123 expr->isTainted = this->taintEngine->taintUnion(dst, src11);
14124 expr->isTainted = this->taintEngine->taintUnion(dst, src12);
14125 expr->isTainted = this->taintEngine->taintUnion(dst, src13);
14126 expr->isTainted = this->taintEngine->taintUnion(dst, src14);
14127
14128 /* Update the symbolic control flow */
14129 this->controlFlow_s(inst);
14130 }
14131
14132
14133 void x86Semantics::pushfq_s(triton::arch::Instruction& inst) {
14134 auto stack = this->architecture->getStackPointer();
14135
14136 /* Create the semantics - side effect */
14137 auto stackValue = alignSubStack_s(inst, stack.getSize());
14138 auto dst = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize()));
14139 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
14140 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
14141 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF));
14142 auto src4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
14143 auto src5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
14144 auto src6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_TF));
14145 auto src7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_IF));
14146 auto src8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
14147 auto src9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
14148 auto src10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_NT));
14149 auto src11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AC));
14150 auto src12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_VIF));
14151 auto src13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_VIP));
14152 auto src14 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ID));
14153
14154 /* Create symbolic operands */
14155 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
14156 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
14157 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
14158 auto op4 = this->symbolicEngine->getOperandAst(inst, src4);
14159 auto op5 = this->symbolicEngine->getOperandAst(inst, src5);
14160 auto op6 = this->symbolicEngine->getOperandAst(inst, src6);
14161 auto op7 = this->symbolicEngine->getOperandAst(inst, src7);
14162 auto op8 = this->symbolicEngine->getOperandAst(inst, src8);
14163 auto op9 = this->symbolicEngine->getOperandAst(inst, src9);
14164 auto op10 = this->symbolicEngine->getOperandAst(inst, src10);
14165 auto op11 = this->symbolicEngine->getOperandAst(inst, src11);
14166 auto op12 = this->symbolicEngine->getOperandAst(inst, src12);
14167 auto op13 = this->symbolicEngine->getOperandAst(inst, src13);
14168 auto op14 = this->symbolicEngine->getOperandAst(inst, src14);
14169
14170 /* Create the semantics */
14171 std::vector<triton::ast::SharedAbstractNode> eflags;
14172 eflags.reserve(22);
14173
14174 eflags.push_back(op14);
14175 eflags.push_back(op13);
14176 eflags.push_back(op12);
14177 eflags.push_back(op11);
14178 eflags.push_back(this->astCtxt->bvfalse()); /* vm */
14179 eflags.push_back(this->astCtxt->bvfalse()); /* rf */
14180 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */
14181 eflags.push_back(op10);
14182 eflags.push_back(this->astCtxt->bvfalse()); /* iopl */
14183 eflags.push_back(this->astCtxt->bvfalse()); /* iopl */
14184 eflags.push_back(op9);
14185 eflags.push_back(op8);
14186 eflags.push_back(op7);
14187 eflags.push_back(op6);
14188 eflags.push_back(op5);
14189 eflags.push_back(op4);
14190 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */
14191 eflags.push_back(op3);
14192 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */
14193 eflags.push_back(op2);
14194 eflags.push_back(this->astCtxt->bvtrue()); /* Reserved */
14195 eflags.push_back(op1);
14196
14197 auto node = this->astCtxt->zx(
14198 dst.getBitSize() - static_cast<triton::uint32>(eflags.size()),
14199 this->astCtxt->concat(eflags)
14200 );
14201
14202 /* Create symbolic expression */
14203 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUSHFQ operation");
14204
14205 /* Spread taint */
14206 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
14207 expr->isTainted = this->taintEngine->taintUnion(dst, src2);
14208 expr->isTainted = this->taintEngine->taintUnion(dst, src3);
14209 expr->isTainted = this->taintEngine->taintUnion(dst, src4);
14210 expr->isTainted = this->taintEngine->taintUnion(dst, src5);
14211 expr->isTainted = this->taintEngine->taintUnion(dst, src6);
14212 expr->isTainted = this->taintEngine->taintUnion(dst, src7);
14213 expr->isTainted = this->taintEngine->taintUnion(dst, src8);
14214 expr->isTainted = this->taintEngine->taintUnion(dst, src9);
14215 expr->isTainted = this->taintEngine->taintUnion(dst, src10);
14216 expr->isTainted = this->taintEngine->taintUnion(dst, src11);
14217 expr->isTainted = this->taintEngine->taintUnion(dst, src12);
14218 expr->isTainted = this->taintEngine->taintUnion(dst, src13);
14219 expr->isTainted = this->taintEngine->taintUnion(dst, src14);
14220
14221 /* Update the symbolic control flow */
14222 this->controlFlow_s(inst);
14223 }
14224
14225
14226 void x86Semantics::pxor_s(triton::arch::Instruction& inst) {
14227 auto& dst = inst.operands[0];
14228 auto& src = inst.operands[1];
14229
14230 /* Create symbolic operands */
14231 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14232 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14233
14234 /* Create the semantics */
14235 auto node = this->astCtxt->bvxor(op1, op2);
14236
14237 /* Create symbolic expression */
14238 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PXOR operation");
14239
14240 /* Update the x87 FPU Tag Word */
14241 this->updateFTW(inst, expr);
14242
14243 /* Spread taint */
14244 if (dst.getType() == OP_REG && src.getRegister() == dst.getRegister())
14245 this->taintEngine->setTaint(src, false);
14246 else
14247 expr->isTainted = this->taintEngine->taintUnion(dst, src);
14248
14249 /* Update the symbolic control flow */
14250 this->controlFlow_s(inst);
14251 }
14252
14253
14254 void x86Semantics::rcl_s(triton::arch::Instruction& inst) {
14255 auto& dst = inst.operands[0];
14256 auto& src = inst.operands[1];
14257 auto srcCf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
14258
14259 /* Create symbolic operands */
14260 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14261 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14262 auto op2bis = this->symbolicEngine->getOperandAst(src);
14263 auto op3 = this->symbolicEngine->getOperandAst(inst, srcCf);
14264
14265 switch (dst.getBitSize()) {
14266 /* Mask: 0x1f without MOD */
14268 op2 = this->astCtxt->bvand(
14269 op2,
14270 this->astCtxt->bv(triton::bitsize::qword-1, src.getBitSize())
14271 );
14272 break;
14273
14274 /* Mask: 0x1f without MOD */
14276 op2 = this->astCtxt->bvand(
14277 op2,
14278 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())
14279 );
14280 break;
14281
14282 /* Mask: 0x1f MOD size + 1 */
14285 op2 = this->astCtxt->bvsmod(
14286 this->astCtxt->bvand(
14287 op2,
14288 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())),
14289 this->astCtxt->bv(dst.getBitSize()+1, src.getBitSize())
14290 );
14291 break;
14292
14293 default:
14294 throw triton::exceptions::Semantics("x86Semantics::rcl_s(): Invalid destination size");
14295 }
14296
14297 /* Create the semantics */
14298 auto node1 = this->astCtxt->bvrol(
14299 this->astCtxt->concat(op3, op1),
14300 this->astCtxt->zx(((op1->getBitvectorSize() + op3->getBitvectorSize()) - op2->getBitvectorSize()), op2)
14301 );
14302
14303 /* Create symbolic expression */
14304 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "RCL tempory operation");
14305
14306 /* Spread taint */
14307 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
14308
14309 /* Create the semantics */
14310 auto node2 = this->astCtxt->extract(dst.getBitSize()-1, 0, node1);
14311
14312 /* Create symbolic expression */
14313 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "RCL operation");
14314
14315 /* Spread taint */
14316 expr2->isTainted = this->taintEngine->taintUnion(dst, src);
14317 expr2->isTainted = this->taintEngine->taintUnion(dst, srcCf);
14318
14319 /* Update symbolic flags */
14320 this->cfRcl_s(inst, expr2, node1, op2bis);
14321 this->ofRol_s(inst, expr2, dst, op2bis); /* Same as ROL */
14322
14323 /* Tag undefined flags */
14324 if (op2->evaluate() > 1) {
14325 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
14326 }
14327
14328 /* Update the symbolic control flow */
14329 this->controlFlow_s(inst);
14330 }
14331
14332
14333 void x86Semantics::rcr_s(triton::arch::Instruction& inst) {
14334 auto& dst = inst.operands[0];
14335 auto& src = inst.operands[1];
14336 auto srcCf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
14337
14338 /* Create symbolic operands */
14339 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14340 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14341 auto op3 = this->symbolicEngine->getOperandAst(inst, srcCf);
14342
14343 switch (dst.getBitSize()) {
14344 /* Mask: 0x3f without MOD */
14346 op2 = this->astCtxt->bvand(
14347 op2,
14348 this->astCtxt->bv(triton::bitsize::qword-1, src.getBitSize())
14349 );
14350 break;
14351
14352 /* Mask: 0x1f without MOD */
14354 op2 = this->astCtxt->bvand(
14355 op2,
14356 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())
14357 );
14358 break;
14359
14360 /* Mask: 0x1f MOD size + 1 */
14363 op2 = this->astCtxt->bvsmod(
14364 this->astCtxt->bvand(
14365 op2,
14366 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())),
14367 this->astCtxt->bv(dst.getBitSize()+1, src.getBitSize())
14368 );
14369 break;
14370
14371 default:
14372 throw triton::exceptions::Semantics("x86Semantics::rcr_s(): Invalid destination size");
14373 }
14374
14375 /* Create the semantics */
14376 auto node1 = this->astCtxt->bvror(
14377 this->astCtxt->concat(op3, op1),
14378 this->astCtxt->zx(((op1->getBitvectorSize() + op3->getBitvectorSize()) - op2->getBitvectorSize()), op2)
14379 );
14380
14381 /* Create symbolic expression */
14382 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "RCR tempory operation");
14383
14384 /* Spread taint */
14385 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
14386
14387 /* Create the semantics */
14388 auto node2 = this->astCtxt->extract(dst.getBitSize()-1, 0, node1);
14389
14390 /* Create symbolic expression */
14391 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "RCR operation");
14392
14393 /* Spread taint */
14394 expr2->isTainted = this->taintEngine->taintUnion(dst, src);
14395 expr2->isTainted = this->taintEngine->taintUnion(dst, srcCf);
14396
14397 /* Update symbolic flags */
14398 this->ofRcr_s(inst, expr2, dst, op1, op2); /* OF must be set before CF */
14399 this->cfRcr_s(inst, expr2, dst, node1, op2);
14400
14401 /* Tag undefined flags */
14402 if (op2->evaluate() > 1) {
14403 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
14404 }
14405
14406 /* Update the symbolic control flow */
14407 this->controlFlow_s(inst);
14408 }
14409
14410
14411 void x86Semantics::rdtsc_s(triton::arch::Instruction& inst) {
14412 auto src = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_TSC));
14413 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX));
14414 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX));
14415
14416 /* Create symbolic operands */
14417 auto op = this->symbolicEngine->getOperandAst(inst, src);
14418 auto high = this->astCtxt->extract((triton::bitsize::qword - 1), triton::bitsize::dword, op);
14419 auto low = this->astCtxt->extract((triton::bitsize::dword - 1), 0, op);
14420
14421 /* Create symbolic expression */
14422 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, high, dst1, "RDTSC EDX operation");
14423 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, low, dst2, "RDTSC EAX operation");
14424
14425 /* Spread taint */
14426 expr1->isTainted = this->taintEngine->taintUnion(dst1, src);
14427 expr2->isTainted = this->taintEngine->taintUnion(dst2, src);
14428
14429 /* Update the symbolic control flow */
14430 this->controlFlow_s(inst);
14431 }
14432
14433
14434 void x86Semantics::ret_s(triton::arch::Instruction& inst) {
14435 auto stack = this->architecture->getStackPointer();
14436 auto stackValue = static_cast<triton::uint64>(this->architecture->getConcreteRegisterValue(stack));
14437 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
14438 auto sp = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize()));
14439
14440 /* Create symbolic operands */
14441 auto op1 = this->symbolicEngine->getOperandAst(inst, sp);
14442
14443 /* Create the semantics */
14444 auto node = op1;
14445
14446 /* Create symbolic expression */
14447 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter");
14448
14449 /* Spread taint */
14450 expr->isTainted = this->taintEngine->taintAssignment(pc, sp);
14451
14452 /* Create the semantics - side effect */
14453 alignAddStack_s(inst, sp.getSize());
14454
14455 /* Create the semantics - side effect */
14456 if (inst.operands.size() > 0) {
14457 auto offset = inst.operands[0].getImmediate();
14458 this->symbolicEngine->getImmediateAst(inst, offset);
14459 alignAddStack_s(inst, static_cast<triton::uint32>(offset.getValue()));
14460 }
14461
14462 /* Create the path constraint */
14463 this->symbolicEngine->pushPathConstraint(inst, expr);
14464 }
14465
14466
14467 void x86Semantics::rol_s(triton::arch::Instruction& inst) {
14468 auto& dst = inst.operands[0];
14469 auto& src = inst.operands[1];
14470
14471 /* Create symbolic operands */
14472 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14473 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14474 auto op2bis = this->symbolicEngine->getOperandAst(src);
14475
14476 switch (dst.getBitSize()) {
14477 /* Mask 0x3f MOD size */
14479 op2 = this->astCtxt->bvsmod(
14480 this->astCtxt->bvand(
14481 op2,
14482 this->astCtxt->bv(triton::bitsize::qword-1, src.getBitSize())),
14483 this->astCtxt->bv(dst.getBitSize(), src.getBitSize())
14484 );
14485
14486 op2bis = this->astCtxt->bvand(
14487 op2bis,
14488 this->astCtxt->bv(triton::bitsize::qword-1, src.getBitSize())
14489 );
14490 break;
14491
14492 /* Mask 0x1f MOD size */
14496 op2 = this->astCtxt->bvsmod(
14497 this->astCtxt->bvand(
14498 op2,
14499 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())),
14500 this->astCtxt->bv(dst.getBitSize(), src.getBitSize())
14501 );
14502
14503 op2bis = this->astCtxt->bvand(
14504 op2bis,
14505 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())
14506 );
14507 break;
14508
14509 default:
14510 throw triton::exceptions::Semantics("x86Semantics::rol_s(): Invalid destination size");
14511 }
14512
14513 /* Create the semantics */
14514 auto node = this->astCtxt->bvrol(
14515 op1,
14516 this->astCtxt->zx(op1->getBitvectorSize() - op2->getBitvectorSize(), op2)
14517 );
14518
14519 /* Create symbolic expression */
14520 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ROL operation");
14521
14522 /* Spread taint */
14523 expr->isTainted = this->taintEngine->taintUnion(dst, src);
14524
14525 /* Update symbolic flags */
14526 this->cfRol_s(inst, expr, dst, op2bis);
14527 this->ofRol_s(inst, expr, dst, op2bis);
14528
14529 /* Tag undefined flags */
14530 if (op2->evaluate() > 1) {
14531 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
14532 }
14533
14534 /* Update the symbolic control flow */
14535 this->controlFlow_s(inst);
14536 }
14537
14538
14539 void x86Semantics::ror_s(triton::arch::Instruction& inst) {
14540 auto& dst = inst.operands[0];
14541 auto& src = inst.operands[1];
14542
14543 /* Create symbolic operands */
14544 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14545 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14546 auto op2bis = this->symbolicEngine->getOperandAst(src);
14547
14548 switch (dst.getBitSize()) {
14549 /* Mask 0x3f MOD size */
14551 op2 = this->astCtxt->bvsmod(
14552 this->astCtxt->bvand(
14553 op2,
14554 this->astCtxt->bv(triton::bitsize::qword-1, src.getBitSize())),
14555 this->astCtxt->bv(dst.getBitSize(), src.getBitSize())
14556 );
14557
14558 op2bis = this->astCtxt->bvand(
14559 op2bis,
14560 this->astCtxt->bv(triton::bitsize::qword-1, src.getBitSize())
14561 );
14562 break;
14563
14564 /* Mask 0x1f MOD size */
14568 op2 = this->astCtxt->bvsmod(
14569 this->astCtxt->bvand(
14570 op2,
14571 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())),
14572 this->astCtxt->bv(dst.getBitSize(), src.getBitSize())
14573 );
14574
14575 op2bis = this->astCtxt->bvand(
14576 op2bis,
14577 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())
14578 );
14579 break;
14580
14581 default:
14582 throw triton::exceptions::Semantics("x86Semantics::ror_s(): Invalid destination size");
14583 }
14584
14585 /* Create the semantics */
14586 auto node = this->astCtxt->bvror(
14587 op1,
14588 this->astCtxt->zx(op1->getBitvectorSize() - op2->getBitvectorSize(), op2)
14589 );
14590
14591 /* Create symbolic expression */
14592 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ROR operation");
14593
14594 /* Spread taint */
14595 expr->isTainted = this->taintEngine->taintUnion(dst, src);
14596
14597 /* Update symbolic flags */
14598 this->cfRor_s(inst, expr, dst, op2);
14599 this->ofRor_s(inst, expr, dst, op2bis);
14600
14601 /* Tag undefined flags */
14602 if (op2->evaluate() > 1) {
14603 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
14604 }
14605
14606 /* Update the symbolic control flow */
14607 this->controlFlow_s(inst);
14608 }
14609
14610
14611 void x86Semantics::rorx_s(triton::arch::Instruction& inst) {
14612 auto& dst = inst.operands[0];
14613 auto& src1 = inst.operands[1];
14614 auto& src2 = inst.operands[2];
14615
14616 /* Create symbolic operands */
14617 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
14618 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
14619
14620 switch (dst.getBitSize()) {
14621 /* Mask 0x3f MOD size */
14623 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, src2.getBitSize()));
14624 break;
14625
14626 /* Mask 0x1f MOD size */
14628 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, src2.getBitSize()));
14629 break;
14630
14631 default:
14632 throw triton::exceptions::Semantics("x86Semantics::rorx_s(): Invalid destination size");
14633 }
14634
14635 /* Create the semantics */
14636 auto node = this->astCtxt->bvror(
14637 op1,
14638 this->astCtxt->zx(op1->getBitvectorSize() - op2->getBitvectorSize(), op2)
14639 );
14640
14641 /* Create symbolic expression */
14642 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "RORX operation");
14643
14644 /* Spread taint */
14645 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
14646 expr->isTainted |= this->taintEngine->taintUnion(dst, src2);
14647
14648 /* Update the symbolic control flow */
14649 this->controlFlow_s(inst);
14650 }
14651
14652
14653 void x86Semantics::sahf_s(triton::arch::Instruction& inst) {
14654 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
14655 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
14656 auto dst3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF));
14657 auto dst4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
14658 auto dst5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
14659 auto src = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AH));
14660
14661 /* Create symbolic operands */
14662 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
14663
14664 /* Create the semantics */
14665 auto node1 = this->astCtxt->extract(7, 7, op1);
14666 auto node2 = this->astCtxt->extract(6, 6, op1);
14667 auto node3 = this->astCtxt->extract(4, 4, op1);
14668 auto node4 = this->astCtxt->extract(2, 2, op1);
14669 auto node5 = this->astCtxt->extract(0, 0, op1);
14670
14671 /* Create symbolic expression */
14672 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1.getRegister(), "SAHF SF operation");
14673 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2.getRegister(), "SAHF ZF operation");
14674 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3.getRegister(), "SAHF AF operation");
14675 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4.getRegister(), "SAHF PF operation");
14676 auto expr5 = this->symbolicEngine->createSymbolicExpression(inst, node5, dst5.getRegister(), "SAHF CF operation");
14677
14678 /* Spread taint */
14679 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src);
14680 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src);
14681 expr3->isTainted = this->taintEngine->taintAssignment(dst3, src);
14682 expr4->isTainted = this->taintEngine->taintAssignment(dst4, src);
14683 expr5->isTainted = this->taintEngine->taintAssignment(dst5, src);
14684
14685 /* Update the symbolic control flow */
14686 this->controlFlow_s(inst);
14687 }
14688
14689
14690 void x86Semantics::sar_s(triton::arch::Instruction& inst) {
14691 auto& dst = inst.operands[0];
14692 auto& src = inst.operands[1];
14693
14694 /* Create symbolic operands */
14695 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14696 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
14697
14699 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, dst.getBitSize()));
14700 else
14701 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, dst.getBitSize()));
14702
14703 /* Create the semantics */
14704 auto node = this->astCtxt->bvashr(op1, op2);
14705
14706 /* Create symbolic expression */
14707 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SAR operation");
14708
14709 /* Spread taint */
14710 expr->isTainted = this->taintEngine->taintUnion(dst, src);
14711
14712 /* Update symbolic flags */
14713 this->cfSar_s(inst, expr, dst, op1, op2);
14714 this->ofSar_s(inst, expr, dst, op2);
14715 this->pfShl_s(inst, expr, dst, op2); /* Same that shl */
14716 this->sfShl_s(inst, expr, dst, op2); /* Same that shl */
14717 this->zfShl_s(inst, expr, dst, op2); /* Same that shl */
14718
14719 /* Tag undefined flags */
14720 if (op2->evaluate() != 0) {
14721 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
14722 }
14723
14724 if (op2->evaluate() > 1) {
14725 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
14726 }
14727
14728 /* Update the symbolic control flow */
14729 this->controlFlow_s(inst);
14730 }
14731
14732
14733 void x86Semantics::sarx_s(triton::arch::Instruction& inst) {
14734 auto& dst = inst.operands[0];
14735 auto& src1 = inst.operands[1];
14736 auto& src2 = inst.operands[2];
14737
14738 /* Create symbolic operands */
14739 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
14740 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
14741
14742 switch (dst.getBitSize()) {
14743 /* Mask 0x3f MOD size */
14745 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, src2.getBitSize()));
14746 break;
14747
14748 /* Mask 0x1f MOD size */
14750 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, src2.getBitSize()));
14751 break;
14752
14753 default:
14754 throw triton::exceptions::Semantics("x86Semantics::sarx_s(): Invalid destination size");
14755 }
14756
14757 /* Create the semantics */
14758 auto node = this->astCtxt->bvashr(op1, op2);
14759
14760 /* Create symbolic expression */
14761 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SARX operation");
14762
14763 /* Spread taint */
14764 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
14765 expr->isTainted |= this->taintEngine->taintUnion(dst, src2);
14766
14767 /* Update the symbolic control flow */
14768 this->controlFlow_s(inst);
14769 }
14770
14771
14772 void x86Semantics::sbb_s(triton::arch::Instruction& inst) {
14773 auto& dst = inst.operands[0];
14774 auto& src = inst.operands[1];
14775 auto srcCf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
14776
14777 /* Create symbolic operands */
14778 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14779 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14780 auto op3 = this->astCtxt->zx(src.getBitSize()-1, this->symbolicEngine->getOperandAst(inst, srcCf));
14781
14782 /* Create the semantics */
14783 auto node = this->astCtxt->bvsub(op1, this->astCtxt->bvadd(op2, op3));
14784
14785 /* Create symbolic expression */
14786 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SBB operation");
14787
14788 /* Spread taint */
14789 expr->isTainted = this->taintEngine->taintUnion(dst, src);
14790 expr->isTainted = this->taintEngine->taintUnion(dst, srcCf);
14791
14792 /* Update symbolic flags */
14793 this->af_s(inst, expr, dst, op1, op2);
14794 this->cfSub_s(inst, expr, dst, op1, op2);
14795 this->ofSub_s(inst, expr, dst, op1, op2);
14796 this->pf_s(inst, expr, dst);
14797 this->sf_s(inst, expr, dst);
14798 this->zf_s(inst, expr, dst);
14799
14800 /* Update the symbolic control flow */
14801 this->controlFlow_s(inst);
14802 }
14803
14804
14805 void x86Semantics::scasb_s(triton::arch::Instruction& inst) {
14806 auto& dst = inst.operands[0];
14807 auto& src = inst.operands[1];
14808 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
14809 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
14810 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
14811
14812 /* If the REP prefix is defined, convert REP into REPE */
14815
14816 /* Check if there is a REP prefix and a counter to zero */
14817 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
14818 this->controlFlow_s(inst);
14819 return;
14820 }
14821
14822 /* Create symbolic operands */
14823 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14824 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14825 auto op3 = this->symbolicEngine->getOperandAst(inst, index);
14826 auto op4 = this->symbolicEngine->getOperandAst(inst, df);
14827
14828 /* Create the semantics */
14829 auto node1 = this->astCtxt->bvsub(op1, op2);
14830 auto node2 = this->astCtxt->ite(
14831 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
14832 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::byte, index.getBitSize())),
14833 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::byte, index.getBitSize()))
14834 );
14835
14836 /* Create symbolic expression */
14837 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "SCASB operation");
14838 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
14839
14840 /* Spread taint */
14841 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
14842 expr2->isTainted = this->taintEngine->taintUnion(index, index);
14843
14844 /* Update symbolic flags */
14845 this->af_s(inst, expr1, dst, op1, op2, true);
14846 this->cfSub_s(inst, expr1, dst, op1, op2, true);
14847 this->ofSub_s(inst, expr1, dst, op1, op2, true);
14848 this->pf_s(inst, expr1, dst, true);
14849 this->sf_s(inst, expr1, dst, true);
14850 this->zf_s(inst, expr1, dst, true);
14851
14852 /* Update the symbolic control flow */
14853 this->controlFlow_s(inst);
14854 }
14855
14856
14857 void x86Semantics::scasd_s(triton::arch::Instruction& inst) {
14858 auto& dst = inst.operands[0];
14859 auto& src = inst.operands[1];
14860 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
14861 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
14862 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
14863
14864 /* If the REP prefix is defined, convert REP into REPE */
14867
14868 /* Check if there is a REP prefix and a counter to zero */
14869 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
14870 this->controlFlow_s(inst);
14871 return;
14872 }
14873
14874 /* Create symbolic operands */
14875 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14876 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14877 auto op3 = this->symbolicEngine->getOperandAst(inst, index);
14878 auto op4 = this->symbolicEngine->getOperandAst(inst, df);
14879
14880 /* Create the semantics */
14881 auto node1 = this->astCtxt->bvsub(op1, op2);
14882 auto node2 = this->astCtxt->ite(
14883 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
14884 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::dword, index.getBitSize())),
14885 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::dword, index.getBitSize()))
14886 );
14887
14888 /* Create symbolic expression */
14889 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "SCASD operation");
14890 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
14891
14892 /* Spread taint */
14893 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
14894 expr2->isTainted = this->taintEngine->taintUnion(index, index);
14895
14896 /* Update symbolic flags */
14897 this->af_s(inst, expr1, dst, op1, op2, true);
14898 this->cfSub_s(inst, expr1, dst, op1, op2, true);
14899 this->ofSub_s(inst, expr1, dst, op1, op2, true);
14900 this->pf_s(inst, expr1, dst, true);
14901 this->sf_s(inst, expr1, dst, true);
14902 this->zf_s(inst, expr1, dst, true);
14903
14904 /* Update the symbolic control flow */
14905 this->controlFlow_s(inst);
14906 }
14907
14908
14909 void x86Semantics::scasq_s(triton::arch::Instruction& inst) {
14910 auto& dst = inst.operands[0];
14911 auto& src = inst.operands[1];
14912 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
14913 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
14914 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
14915
14916 /* If the REP prefix is defined, convert REP into REPE */
14919
14920 /* Check if there is a REP prefix and a counter to zero */
14921 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
14922 this->controlFlow_s(inst);
14923 return;
14924 }
14925
14926 /* Create symbolic operands */
14927 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14928 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14929 auto op3 = this->symbolicEngine->getOperandAst(inst, index);
14930 auto op4 = this->symbolicEngine->getOperandAst(inst, df);
14931
14932 /* Create the semantics */
14933 auto node1 = this->astCtxt->bvsub(op1, op2);
14934 auto node2 = this->astCtxt->ite(
14935 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
14936 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::qword, index.getBitSize())),
14937 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::qword, index.getBitSize()))
14938 );
14939
14940 /* Create symbolic expression */
14941 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "SCASQ operation");
14942 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
14943
14944 /* Spread taint */
14945 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
14946 expr2->isTainted = this->taintEngine->taintUnion(index, index);
14947
14948 /* Update symbolic flags */
14949 this->af_s(inst, expr1, dst, op1, op2, true);
14950 this->cfSub_s(inst, expr1, dst, op1, op2, true);
14951 this->ofSub_s(inst, expr1, dst, op1, op2, true);
14952 this->pf_s(inst, expr1, dst, true);
14953 this->sf_s(inst, expr1, dst, true);
14954 this->zf_s(inst, expr1, dst, true);
14955
14956 /* Update the symbolic control flow */
14957 this->controlFlow_s(inst);
14958 }
14959
14960
14961 void x86Semantics::scasw_s(triton::arch::Instruction& inst) {
14962 auto& dst = inst.operands[0];
14963 auto& src = inst.operands[1];
14964 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
14965 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
14966 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
14967
14968 /* If the REP prefix is defined, convert REP into REPE */
14971
14972 /* Check if there is a REP prefix and a counter to zero */
14973 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
14974 this->controlFlow_s(inst);
14975 return;
14976 }
14977
14978 /* Create symbolic operands */
14979 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
14980 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
14981 auto op3 = this->symbolicEngine->getOperandAst(inst, index);
14982 auto op4 = this->symbolicEngine->getOperandAst(inst, df);
14983
14984 /* Create the semantics */
14985 auto node1 = this->astCtxt->bvsub(op1, op2);
14986 auto node2 = this->astCtxt->ite(
14987 this->astCtxt->equal(op4, this->astCtxt->bvfalse()),
14988 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::word, index.getBitSize())),
14989 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::word, index.getBitSize()))
14990 );
14991
14992 /* Create symbolic expression */
14993 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "SCASW operation");
14994 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
14995
14996 /* Spread taint */
14997 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src);
14998 expr2->isTainted = this->taintEngine->taintUnion(index, index);
14999
15000 /* Update symbolic flags */
15001 this->af_s(inst, expr1, dst, op1, op2, true);
15002 this->cfSub_s(inst, expr1, dst, op1, op2, true);
15003 this->ofSub_s(inst, expr1, dst, op1, op2, true);
15004 this->pf_s(inst, expr1, dst, true);
15005 this->sf_s(inst, expr1, dst, true);
15006 this->zf_s(inst, expr1, dst, true);
15007
15008 /* Update the symbolic control flow */
15009 this->controlFlow_s(inst);
15010 }
15011
15012
15013 void x86Semantics::seta_s(triton::arch::Instruction& inst) {
15014 auto& dst = inst.operands[0];
15015 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
15016 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
15017
15018 /* Create symbolic operands */
15019 auto op2 = this->symbolicEngine->getOperandAst(inst, cf);
15020 auto op3 = this->symbolicEngine->getOperandAst(inst, zf);
15021
15022 /* Create the semantics */
15023 auto node = this->astCtxt->ite(
15024 this->astCtxt->equal(
15025 this->astCtxt->bvand(
15026 this->astCtxt->bvnot(op2),
15027 this->astCtxt->bvnot(op3)
15028 ),
15029 this->astCtxt->bvtrue()
15030 ),
15031 this->astCtxt->bv(1, dst.getBitSize()),
15032 this->astCtxt->bv(0, dst.getBitSize())
15033 );
15034
15035 /* Create symbolic expression */
15036 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETA operation");
15037
15038 /* Set condition flag */
15039 if (op2->evaluate().is_zero() && op3->evaluate().is_zero()) {
15040 inst.setConditionTaken(true);
15041 }
15042
15043 /* Spread taint */
15044 expr->isTainted = this->taintEngine->taintAssignment(dst, cf);
15045 expr->isTainted = this->taintEngine->taintUnion(dst, zf);
15046
15047 /* Update the symbolic control flow */
15048 this->controlFlow_s(inst);
15049 }
15050
15051
15052 void x86Semantics::setae_s(triton::arch::Instruction& inst) {
15053 auto& dst = inst.operands[0];
15054 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
15055
15056 /* Create symbolic operands */
15057 auto op2 = this->symbolicEngine->getOperandAst(inst, cf);
15058
15059 /* Create the semantics */
15060 auto node = this->astCtxt->ite(
15061 this->astCtxt->equal(op2, this->astCtxt->bvfalse()),
15062 this->astCtxt->bv(1, dst.getBitSize()),
15063 this->astCtxt->bv(0, dst.getBitSize())
15064 );
15065
15066 /* Create symbolic expression */
15067 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETAE operation");
15068
15069 /* Set condition flag */
15070 if (op2->evaluate().is_zero()) {
15071 inst.setConditionTaken(true);
15072 }
15073
15074 /* Spread taint */
15075 expr->isTainted = this->taintEngine->taintAssignment(dst, cf);
15076
15077 /* Update the symbolic control flow */
15078 this->controlFlow_s(inst);
15079 }
15080
15081
15082 void x86Semantics::setb_s(triton::arch::Instruction& inst) {
15083 auto& dst = inst.operands[0];
15084 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
15085
15086 /* Create symbolic operands */
15087 auto op2 = this->symbolicEngine->getOperandAst(inst, cf);
15088
15089 /* Create the semantics */
15090 auto node = this->astCtxt->ite(
15091 this->astCtxt->equal(op2, this->astCtxt->bvtrue()),
15092 this->astCtxt->bv(1, dst.getBitSize()),
15093 this->astCtxt->bv(0, dst.getBitSize())
15094 );
15095
15096 /* Create symbolic expression */
15097 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETB operation");
15098
15099 /* Set condition flag */
15100 if (!op2->evaluate().is_zero()) {
15101 inst.setConditionTaken(true);
15102 }
15103
15104 /* Spread taint */
15105 expr->isTainted = this->taintEngine->taintAssignment(dst, cf);
15106
15107 /* Update the symbolic control flow */
15108 this->controlFlow_s(inst);
15109 }
15110
15111
15112 void x86Semantics::setbe_s(triton::arch::Instruction& inst) {
15113 auto& dst = inst.operands[0];
15114 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF));
15115 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
15116
15117 /* Create symbolic operands */
15118 auto op2 = this->symbolicEngine->getOperandAst(inst, cf);
15119 auto op3 = this->symbolicEngine->getOperandAst(inst, zf);
15120
15121 /* Create the semantics */
15122 auto node = this->astCtxt->ite(
15123 this->astCtxt->equal(this->astCtxt->bvor(op2, op3), this->astCtxt->bvtrue()),
15124 this->astCtxt->bv(1, dst.getBitSize()),
15125 this->astCtxt->bv(0, dst.getBitSize())
15126 );
15127
15128 /* Create symbolic expression */
15129 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETBE operation");
15130
15131 /* Set condition flag */
15132 if (!op2->evaluate().is_zero() || !op3->evaluate().is_zero()) {
15133 inst.setConditionTaken(true);
15134 }
15135
15136 /* Spread taint */
15137 expr->isTainted = this->taintEngine->taintAssignment(dst, cf);
15138 expr->isTainted = this->taintEngine->taintUnion(dst, zf);
15139
15140 /* Update the symbolic control flow */
15141 this->controlFlow_s(inst);
15142 }
15143
15144
15145 void x86Semantics::sete_s(triton::arch::Instruction& inst) {
15146 auto& dst = inst.operands[0];
15147 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
15148
15149 /* Create symbolic operands */
15150 auto op2 = this->symbolicEngine->getOperandAst(inst, zf);
15151
15152 /* Create the semantics */
15153 auto node = this->astCtxt->ite(
15154 this->astCtxt->equal(op2, this->astCtxt->bvtrue()),
15155 this->astCtxt->bv(1, dst.getBitSize()),
15156 this->astCtxt->bv(0, dst.getBitSize())
15157 );
15158
15159 /* Create symbolic expression */
15160 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETE operation");
15161
15162 /* Set condition flag */
15163 if (!op2->evaluate().is_zero()) {
15164 inst.setConditionTaken(true);
15165 }
15166
15167 /* Spread taint */
15168 expr->isTainted = this->taintEngine->taintAssignment(dst, zf);
15169
15170 /* Update the symbolic control flow */
15171 this->controlFlow_s(inst);
15172 }
15173
15174
15175 void x86Semantics::setg_s(triton::arch::Instruction& inst) {
15176 auto& dst = inst.operands[0];
15177 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
15178 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
15179 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
15180
15181 /* Create symbolic operands */
15182 auto op2 = this->symbolicEngine->getOperandAst(inst, sf);
15183 auto op3 = this->symbolicEngine->getOperandAst(inst, of);
15184 auto op4 = this->symbolicEngine->getOperandAst(inst, zf);
15185
15186 /* Create the semantics */
15187 auto node = this->astCtxt->ite(
15188 this->astCtxt->equal(this->astCtxt->bvor(this->astCtxt->bvxor(op2, op3), op4), this->astCtxt->bvfalse()),
15189 this->astCtxt->bv(1, dst.getBitSize()),
15190 this->astCtxt->bv(0, dst.getBitSize())
15191 );
15192
15193 /* Create symbolic expression */
15194 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETG operation");
15195
15196 /* Set condition flag */
15197 if ((op2->evaluate().is_zero() == op3->evaluate().is_zero()) && op4->evaluate().is_zero()) {
15198 inst.setConditionTaken(true);
15199 }
15200
15201 /* Spread taint */
15202 expr->isTainted = this->taintEngine->taintAssignment(dst, sf);
15203 expr->isTainted = this->taintEngine->taintUnion(dst, of);
15204 expr->isTainted = this->taintEngine->taintUnion(dst, zf);
15205
15206 /* Update the symbolic control flow */
15207 this->controlFlow_s(inst);
15208 }
15209
15210
15211 void x86Semantics::setge_s(triton::arch::Instruction& inst) {
15212 auto& dst = inst.operands[0];
15213 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
15214 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
15215
15216 /* Create symbolic operands */
15217 auto op2 = this->symbolicEngine->getOperandAst(inst, sf);
15218 auto op3 = this->symbolicEngine->getOperandAst(inst, of);
15219
15220 /* Create the semantics */
15221 auto node = this->astCtxt->ite(
15222 this->astCtxt->equal(op2, op3),
15223 this->astCtxt->bv(1, dst.getBitSize()),
15224 this->astCtxt->bv(0, dst.getBitSize())
15225 );
15226
15227 /* Create symbolic expression */
15228 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETGE operation");
15229
15230 /* Set condition flag */
15231 if (op2->evaluate().is_zero() == op3->evaluate().is_zero()) {
15232 inst.setConditionTaken(true);
15233 }
15234
15235 /* Spread taint */
15236 expr->isTainted = this->taintEngine->taintAssignment(dst, sf);
15237 expr->isTainted = this->taintEngine->taintUnion(dst, of);
15238
15239 /* Update the symbolic control flow */
15240 this->controlFlow_s(inst);
15241 }
15242
15243
15244 void x86Semantics::setl_s(triton::arch::Instruction& inst) {
15245 auto& dst = inst.operands[0];
15246 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
15247 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
15248
15249 /* Create symbolic operands */
15250 auto op2 = this->symbolicEngine->getOperandAst(inst, sf);
15251 auto op3 = this->symbolicEngine->getOperandAst(inst, of);
15252
15253 /* Create the semantics */
15254 auto node = this->astCtxt->ite(
15255 this->astCtxt->equal(this->astCtxt->bvxor(op2, op3), this->astCtxt->bvtrue()),
15256 this->astCtxt->bv(1, dst.getBitSize()),
15257 this->astCtxt->bv(0, dst.getBitSize())
15258 );
15259
15260 /* Create symbolic expression */
15261 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETL operation");
15262
15263 /* Set condition flag */
15264 if (op2->evaluate().is_zero() != op3->evaluate().is_zero()) {
15265 inst.setConditionTaken(true);
15266 }
15267
15268 /* Spread taint */
15269 expr->isTainted = this->taintEngine->taintAssignment(dst, sf);
15270 expr->isTainted = this->taintEngine->taintUnion(dst, of);
15271
15272 /* Update the symbolic control flow */
15273 this->controlFlow_s(inst);
15274 }
15275
15276
15277 void x86Semantics::setle_s(triton::arch::Instruction& inst) {
15278 auto& dst = inst.operands[0];
15279 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
15280 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
15281 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
15282
15283 /* Create symbolic operands */
15284 auto op2 = this->symbolicEngine->getOperandAst(inst, sf);
15285 auto op3 = this->symbolicEngine->getOperandAst(inst, of);
15286 auto op4 = this->symbolicEngine->getOperandAst(inst, zf);
15287
15288 /* Create the semantics */
15289 auto node = this->astCtxt->ite(
15290 this->astCtxt->equal(this->astCtxt->bvor(this->astCtxt->bvxor(op2, op3), op4), this->astCtxt->bvtrue()),
15291 this->astCtxt->bv(1, dst.getBitSize()),
15292 this->astCtxt->bv(0, dst.getBitSize())
15293 );
15294
15295 /* Create symbolic expression */
15296 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETLE operation");
15297
15298 /* Set condition flag */
15299 if ((op2->evaluate().is_zero() != op3->evaluate().is_zero()) || !op4->evaluate().is_zero()) {
15300 inst.setConditionTaken(true);
15301 }
15302
15303 /* Spread taint */
15304 expr->isTainted = this->taintEngine->taintAssignment(dst, sf);
15305 expr->isTainted = this->taintEngine->taintUnion(dst, of);
15306 expr->isTainted = this->taintEngine->taintUnion(dst, zf);
15307
15308 /* Update the symbolic control flow */
15309 this->controlFlow_s(inst);
15310 }
15311
15312
15313 void x86Semantics::setne_s(triton::arch::Instruction& inst) {
15314 auto& dst = inst.operands[0];
15315 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
15316
15317 /* Create symbolic operands */
15318 auto op2 = this->symbolicEngine->getOperandAst(inst, zf);
15319
15320 /* Create the semantics */
15321 auto node = this->astCtxt->ite(
15322 this->astCtxt->equal(op2, this->astCtxt->bvfalse()),
15323 this->astCtxt->bv(1, dst.getBitSize()),
15324 this->astCtxt->bv(0, dst.getBitSize())
15325 );
15326
15327 /* Create symbolic expression */
15328 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETNE operation");
15329
15330 /* Set condition flag */
15331 if (op2->evaluate().is_zero()) {
15332 inst.setConditionTaken(true);
15333 }
15334
15335 /* Spread taint */
15336 expr->isTainted = this->taintEngine->taintAssignment(dst, zf);
15337
15338 /* Update the symbolic control flow */
15339 this->controlFlow_s(inst);
15340 }
15341
15342
15343 void x86Semantics::setno_s(triton::arch::Instruction& inst) {
15344 auto& dst = inst.operands[0];
15345 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
15346
15347 /* Create symbolic operands */
15348 auto op2 = this->symbolicEngine->getOperandAst(inst, of);
15349
15350 /* Create the semantics */
15351 auto node = this->astCtxt->ite(
15352 this->astCtxt->equal(op2, this->astCtxt->bvfalse()),
15353 this->astCtxt->bv(1, dst.getBitSize()),
15354 this->astCtxt->bv(0, dst.getBitSize())
15355 );
15356
15357 /* Create symbolic expression */
15358 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETNO operation");
15359
15360 /* Set condition flag */
15361 if (op2->evaluate().is_zero()) {
15362 inst.setConditionTaken(true);
15363 }
15364
15365 /* Spread taint */
15366 expr->isTainted = this->taintEngine->taintAssignment(dst, of);
15367
15368 /* Update the symbolic control flow */
15369 this->controlFlow_s(inst);
15370 }
15371
15372
15373 void x86Semantics::setnp_s(triton::arch::Instruction& inst) {
15374 auto& dst = inst.operands[0];
15375 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
15376
15377 /* Create symbolic operands */
15378 auto op2 = this->symbolicEngine->getOperandAst(inst, pf);
15379
15380 /* Create the semantics */
15381 auto node = this->astCtxt->ite(
15382 this->astCtxt->equal(op2, this->astCtxt->bvfalse()),
15383 this->astCtxt->bv(1, dst.getBitSize()),
15384 this->astCtxt->bv(0, dst.getBitSize())
15385 );
15386
15387 /* Create symbolic expression */
15388 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETNP operation");
15389
15390 /* Set condition flag */
15391 if (op2->evaluate().is_zero()) {
15392 inst.setConditionTaken(true);
15393 }
15394
15395 /* Spread taint */
15396 expr->isTainted = this->taintEngine->taintAssignment(dst, pf);
15397
15398 /* Update the symbolic control flow */
15399 this->controlFlow_s(inst);
15400 }
15401
15402
15403 void x86Semantics::setns_s(triton::arch::Instruction& inst) {
15404 auto& dst = inst.operands[0];
15405 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
15406
15407 /* Create symbolic operands */
15408 auto op2 = this->symbolicEngine->getOperandAst(inst, sf);
15409
15410 /* Create the semantics */
15411 auto node = this->astCtxt->ite(
15412 this->astCtxt->equal(op2, this->astCtxt->bvfalse()),
15413 this->astCtxt->bv(1, dst.getBitSize()),
15414 this->astCtxt->bv(0, dst.getBitSize())
15415 );
15416
15417 /* Create symbolic expression */
15418 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETNS operation");
15419
15420 /* Set condition flag */
15421 if (op2->evaluate().is_zero()) {
15422 inst.setConditionTaken(true);
15423 }
15424
15425 /* Spread taint */
15426 expr->isTainted = this->taintEngine->taintAssignment(dst, sf);
15427
15428 /* Update the symbolic control flow */
15429 this->controlFlow_s(inst);
15430 }
15431
15432
15433 void x86Semantics::seto_s(triton::arch::Instruction& inst) {
15434 auto& dst = inst.operands[0];
15435 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF));
15436
15437 /* Create symbolic operands */
15438 auto op2 = this->symbolicEngine->getOperandAst(inst, of);
15439
15440 /* Create the semantics */
15441 auto node = this->astCtxt->ite(
15442 this->astCtxt->equal(op2, this->astCtxt->bvtrue()),
15443 this->astCtxt->bv(1, dst.getBitSize()),
15444 this->astCtxt->bv(0, dst.getBitSize())
15445 );
15446
15447 /* Create symbolic expression */
15448 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETO operation");
15449
15450 /* Set condition flag */
15451 if (!op2->evaluate().is_zero()) {
15452 inst.setConditionTaken(true);
15453 }
15454
15455 /* Spread taint */
15456 expr->isTainted = this->taintEngine->taintAssignment(dst, of);
15457
15458 /* Update the symbolic control flow */
15459 this->controlFlow_s(inst);
15460 }
15461
15462
15463 void x86Semantics::setp_s(triton::arch::Instruction& inst) {
15464 auto& dst = inst.operands[0];
15465 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF));
15466
15467 /* Create symbolic operands */
15468 auto op2 = this->symbolicEngine->getOperandAst(inst, pf);
15469
15470 /* Create the semantics */
15471 auto node = this->astCtxt->ite(
15472 this->astCtxt->equal(op2, this->astCtxt->bvtrue()),
15473 this->astCtxt->bv(1, dst.getBitSize()),
15474 this->astCtxt->bv(0, dst.getBitSize())
15475 );
15476
15477 /* Create symbolic expression */
15478 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETP operation");
15479
15480 /* Set condition flag */
15481 if (!op2->evaluate().is_zero()) {
15482 inst.setConditionTaken(true);
15483 }
15484
15485 /* Spread taint */
15486 expr->isTainted = this->taintEngine->taintAssignment(dst, pf);
15487
15488 /* Update the symbolic control flow */
15489 this->controlFlow_s(inst);
15490 }
15491
15492
15493 void x86Semantics::sets_s(triton::arch::Instruction& inst) {
15494 auto& dst = inst.operands[0];
15495 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF));
15496
15497 /* Create symbolic operands */
15498 auto op2 = this->symbolicEngine->getOperandAst(inst, sf);
15499
15500 /* Create the semantics */
15501 auto node = this->astCtxt->ite(
15502 this->astCtxt->equal(op2, this->astCtxt->bvtrue()),
15503 this->astCtxt->bv(1, dst.getBitSize()),
15504 this->astCtxt->bv(0, dst.getBitSize())
15505 );
15506
15507 /* Create symbolic expression */
15508 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETS operation");
15509
15510 /* Set condition flag */
15511 if (!op2->evaluate().is_zero()) {
15512 inst.setConditionTaken(true);
15513 }
15514
15515 /* Spread taint */
15516 expr->isTainted = this->taintEngine->taintAssignment(dst, sf);
15517
15518 /* Update the symbolic control flow */
15519 this->controlFlow_s(inst);
15520 }
15521
15522
15523 void x86Semantics::sfence_s(triton::arch::Instruction& inst) {
15524 /* Update the symbolic control flow */
15525 this->controlFlow_s(inst);
15526 }
15527
15528
15529 void x86Semantics::shl_s(triton::arch::Instruction& inst) {
15530 auto& dst = inst.operands[0];
15531 auto& src = inst.operands[1];
15532
15533 /* Create symbolic operands */
15534 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
15535 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
15536 auto op2bis = op2;
15537
15539 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, dst.getBitSize()));
15540 else
15541 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, dst.getBitSize()));
15542
15543 /* Create the semantics */
15544 auto node = this->astCtxt->bvshl(op1, op2);
15545
15546 /* Create symbolic expression */
15547 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SHL operation");
15548
15549 /* Spread taint */
15550 expr->isTainted = this->taintEngine->taintUnion(dst, src);
15551
15552 /* Update symbolic flags */
15553 this->cfShl_s(inst, expr, dst, op1, op2);
15554 this->ofShl_s(inst, expr, dst, op1, op2);
15555 this->pfShl_s(inst, expr, dst, op2);
15556 this->sfShl_s(inst, expr, dst, op2);
15557 this->zfShl_s(inst, expr, dst, op2);
15558
15559 /* Tag undefined flags */
15560 if (op2->evaluate() != 0) {
15561 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
15562 }
15563
15564 if (op2bis->evaluate() > dst.getBitSize()) {
15565 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
15566 }
15567
15568 if (op2->evaluate() > 1) {
15569 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
15570 }
15571
15572 /* Update the symbolic control flow */
15573 this->controlFlow_s(inst);
15574 }
15575
15576
15577 void x86Semantics::shld_s(triton::arch::Instruction& inst) {
15578 auto& dst = inst.operands[0];
15579 auto& src1 = inst.operands[1];
15580 auto& src2 = inst.operands[2];
15581
15582 /* Create symbolic operands */
15583 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
15584 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
15585 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
15586 auto op3bis = op3;
15587
15588 switch (dst.getBitSize()) {
15589 /* Mask 0x3f MOD size */
15591 op3 = this->astCtxt->bvsmod(
15592 this->astCtxt->bvand(
15593 op3,
15594 this->astCtxt->bv(triton::bitsize::qword-1, src2.getBitSize())),
15595 this->astCtxt->bv(dst.getBitSize(), src2.getBitSize())
15596 );
15597 break;
15598
15599 /* Mask 0x1f MOD size */
15602 op3 = this->astCtxt->bvsmod(
15603 this->astCtxt->bvand(
15604 op3,
15605 this->astCtxt->bv(triton::bitsize::dword-1, src2.getBitSize())),
15606 this->astCtxt->bv(triton::bitsize::dword, src2.getBitSize())
15607 );
15608 break;
15609
15610 default:
15611 throw triton::exceptions::Semantics("x86Semantics::shld_s(): Invalid destination size");
15612 }
15613
15614 /* Create the semantics */
15615 auto node = this->astCtxt->extract(
15616 dst.getBitSize()-1, 0,
15617 this->astCtxt->bvrol(
15618 this->astCtxt->concat(op2, op1),
15619 this->astCtxt->zx(((op1->getBitvectorSize() + op2->getBitvectorSize()) - op3->getBitvectorSize()), op3)
15620 )
15621 );
15622
15623 /* Create symbolic expression */
15624 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SHLD operation");
15625
15626 /* Spread taint */
15627 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
15628 expr->isTainted |= this->taintEngine->taintUnion(dst, src2);
15629
15630 /* Update symbolic flags */
15631 this->cfShld_s(inst, expr, dst, op1, op2, op3);
15632 this->ofShld_s(inst, expr, dst, op1, op2, op3);
15633 this->pfShl_s(inst, expr, dst, op3); /* Same that shl */
15634 this->sfShld_s(inst, expr, dst, op1, op2, op3);
15635 this->zfShl_s(inst, expr, dst, op3); /* Same that shl */
15636
15637 /* Tag undefined flags */
15638 if (op3->evaluate() != 0) {
15639 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
15640 }
15641
15642 if (op3->evaluate() > 1) {
15643 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
15644 }
15645
15646 if (op3bis->evaluate() > dst.getBitSize()) {
15647 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
15648 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
15649 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
15650 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
15651 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
15652 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF));
15653 if (dst.getType() == triton::arch::OP_REG)
15654 this->undefined_s(inst, dst.getRegister());
15655 }
15656
15657 /* Update the symbolic control flow */
15658 this->controlFlow_s(inst);
15659 }
15660
15661
15662 void x86Semantics::shlx_s(triton::arch::Instruction& inst) {
15663 auto& dst = inst.operands[0];
15664 auto& src1 = inst.operands[1];
15665 auto& src2 = inst.operands[2];
15666
15667 /* Create symbolic operands */
15668 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
15669 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
15670
15671 switch (dst.getBitSize()) {
15672 /* Mask 0x3f MOD size */
15674 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, src2.getBitSize()));
15675 break;
15676
15677 /* Mask 0x1f MOD size */
15679 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, src2.getBitSize()));
15680 break;
15681
15682 default:
15683 throw triton::exceptions::Semantics("x86Semantics::shlx_s(): Invalid destination size");
15684 }
15685
15686 /* Create the semantics */
15687 auto node = this->astCtxt->bvshl(op1, op2);
15688
15689 /* Create symbolic expression */
15690 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SHLX operation");
15691
15692 /* Spread taint */
15693 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
15694 expr->isTainted |= this->taintEngine->taintUnion(dst, src2);
15695
15696 /* Update the symbolic control flow */
15697 this->controlFlow_s(inst);
15698 }
15699
15700
15701 void x86Semantics::shr_s(triton::arch::Instruction& inst) {
15702 auto& dst = inst.operands[0];
15703 auto& src = inst.operands[1];
15704
15705 /* Create symbolic operands */
15706 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
15707 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src));
15708 auto op2bis = op2;
15709
15711 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, dst.getBitSize()));
15712 else
15713 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, dst.getBitSize()));
15714
15715 /* Create the semantics */
15716 auto node = this->astCtxt->bvlshr(op1, op2);
15717
15718 /* Create symbolic expression */
15719 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SHR operation");
15720
15721 /* Spread taint */
15722 expr->isTainted = this->taintEngine->taintUnion(dst, src);
15723
15724 /* Update symbolic flags */
15725 this->cfShr_s(inst, expr, dst, op1, op2);
15726 this->ofShr_s(inst, expr, dst, op1, op2);
15727 this->pfShl_s(inst, expr, dst, op2); /* Same that shl */
15728 this->sfShl_s(inst, expr, dst, op2); /* Same that shl */
15729 this->zfShl_s(inst, expr, dst, op2); /* Same that shl */
15730
15731 /* Tag undefined flags */
15732 if (op2->evaluate() != 0) {
15733 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
15734 }
15735
15736 if (op2bis->evaluate() > dst.getBitSize()) {
15737 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
15738 }
15739
15740 if (op2->evaluate() > 1) {
15741 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
15742 }
15743
15744 /* Update the symbolic control flow */
15745 this->controlFlow_s(inst);
15746 }
15747
15748
15749 void x86Semantics::shrd_s(triton::arch::Instruction& inst) {
15750 auto& dst = inst.operands[0];
15751 auto& src1 = inst.operands[1];
15752 auto& src2 = inst.operands[2];
15753
15754 /* Create symbolic operands */
15755 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
15756 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
15757 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
15758 auto op3bis = op3;
15759
15760 switch (dst.getBitSize()) {
15761 /* Mask 0x3f MOD size */
15763 op3 = this->astCtxt->bvsmod(
15764 this->astCtxt->bvand(
15765 op3,
15766 this->astCtxt->bv(triton::bitsize::qword-1, src2.getBitSize())),
15767 this->astCtxt->bv(dst.getBitSize(), src2.getBitSize())
15768 );
15769 break;
15770
15771 /* Mask 0x1f MOD size */
15774 op3 = this->astCtxt->bvsmod(
15775 this->astCtxt->bvand(
15776 op3,
15777 this->astCtxt->bv(triton::bitsize::dword-1, src2.getBitSize())),
15778 this->astCtxt->bv(triton::bitsize::dword, src2.getBitSize())
15779 );
15780 break;
15781
15782 default:
15783 throw triton::exceptions::Semantics("x86Semantics::shrd_s(): Invalid destination size");
15784 }
15785
15786 /* Create the semantics */
15787 auto node = this->astCtxt->extract(
15788 dst.getBitSize()-1, 0,
15789 this->astCtxt->bvror(
15790 this->astCtxt->concat(op2, op1),
15791 this->astCtxt->zx(((op1->getBitvectorSize() + op2->getBitvectorSize()) - op3->getBitvectorSize()), op3)
15792 )
15793 );
15794
15795 /* Create symbolic expression */
15796 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SHRD operation");
15797
15798 /* Spread taint */
15799 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
15800 expr->isTainted |= this->taintEngine->taintUnion(dst, src2);
15801
15802 /* Update symbolic flags */
15803 this->cfShrd_s(inst, expr, dst, op1, op2, op3);
15804 this->ofShrd_s(inst, expr, dst, op1, op2, op3);
15805 this->pfShl_s(inst, expr, dst, op3); /* Same that shl */
15806 this->sfShrd_s(inst, expr, dst, op1, op2, op3);
15807 this->zfShl_s(inst, expr, dst, op3); /* Same that shl */
15808
15809 /* Tag undefined flags */
15810 if (op3->evaluate() != 0) {
15811 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
15812 }
15813
15814 if (op3->evaluate() > 1) {
15815 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
15816 }
15817
15818 if (op3bis->evaluate() > dst.getBitSize()) {
15819 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
15820 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF));
15821 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
15822 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
15823 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
15824 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF));
15825 if (dst.getType() == triton::arch::OP_REG)
15826 this->undefined_s(inst, dst.getRegister());
15827 }
15828
15829 /* Update the symbolic control flow */
15830 this->controlFlow_s(inst);
15831 }
15832
15833
15834 void x86Semantics::shrx_s(triton::arch::Instruction& inst) {
15835 auto& dst = inst.operands[0];
15836 auto& src1 = inst.operands[1];
15837 auto& src2 = inst.operands[2];
15838
15839 /* Create symbolic operands */
15840 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
15841 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
15842
15843 switch (dst.getBitSize()) {
15844 /* Mask 0x3f MOD size */
15846 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, src2.getBitSize()));
15847 break;
15848
15849 /* Mask 0x1f MOD size */
15851 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, src2.getBitSize()));
15852 break;
15853
15854 default:
15855 throw triton::exceptions::Semantics("x86Semantics::shrx_s(): Invalid destination size");
15856 }
15857
15858 /* Create the semantics */
15859 auto node = this->astCtxt->bvlshr(op1, op2);
15860
15861 /* Create symbolic expression */
15862 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SHRX operation");
15863
15864 /* Spread taint */
15865 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
15866 expr->isTainted |= this->taintEngine->taintUnion(dst, src2);
15867
15868 /* Update the symbolic control flow */
15869 this->controlFlow_s(inst);
15870 }
15871
15872
15873 void x86Semantics::stc_s(triton::arch::Instruction& inst) {
15874 this->setFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Sets carry flag");
15875 /* Update the symbolic control flow */
15876 this->controlFlow_s(inst);
15877 }
15878
15879
15880 void x86Semantics::std_s(triton::arch::Instruction& inst) {
15881 this->setFlag_s(inst, this->architecture->getRegister(ID_REG_X86_DF), "Sets direction flag");
15882 /* Update the symbolic control flow */
15883 this->controlFlow_s(inst);
15884 }
15885
15886
15887 void x86Semantics::sti_s(triton::arch::Instruction& inst) {
15888 this->setFlag_s(inst, this->architecture->getRegister(ID_REG_X86_IF), "Sets interrupt flag");
15889 /* Update the symbolic control flow */
15890 this->controlFlow_s(inst);
15891 }
15892
15893
15894 void x86Semantics::stmxcsr_s(triton::arch::Instruction& inst) {
15895 auto& dst = inst.operands[0];
15896 auto src = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR));
15897
15898 /* Create symbolic operands */
15899 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
15900
15901 /* Create the semantics */
15902 auto node = this->astCtxt->extract(triton::bitsize::dword-1, 0, op2);
15903
15904 /* Create symbolic expression */
15905 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "STMXCSR operation");
15906
15907 /* Spread taint */
15908 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
15909
15910 /* Update the symbolic control flow */
15911 this->controlFlow_s(inst);
15912 }
15913
15914
15915 void x86Semantics::stosb_s(triton::arch::Instruction& inst) {
15916 auto& dst = inst.operands[0];
15917 auto& src = inst.operands[1];
15918 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
15919 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
15920 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
15921
15922 /* Check if there is a REP prefix and a counter to zero */
15923 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
15924 this->controlFlow_s(inst);
15925 return;
15926 }
15927
15928 /* Create symbolic operands */
15929 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
15930 auto op2 = this->symbolicEngine->getOperandAst(inst, index);
15931 auto op3 = this->symbolicEngine->getOperandAst(inst, df);
15932
15933 /* Create the semantics */
15934 auto node1 = op1;
15935 auto node2 = this->astCtxt->ite(
15936 this->astCtxt->equal(op3, this->astCtxt->bvfalse()),
15937 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::byte, index.getBitSize())),
15938 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::byte, index.getBitSize()))
15939 );
15940
15941 /* Create symbolic expression */
15942 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "STOSB operation");
15943 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
15944
15945 /* Spread taint */
15946 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
15947 expr2->isTainted = this->taintEngine->taintUnion(index, index);
15948
15949 /* Update the symbolic control flow */
15950 this->controlFlow_s(inst);
15951 }
15952
15953
15954 void x86Semantics::stosd_s(triton::arch::Instruction& inst) {
15955 auto& dst = inst.operands[0];
15956 auto& src = inst.operands[1];
15957 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
15958 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
15959 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
15960
15961 /* Check if there is a REP prefix and a counter to zero */
15962 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
15963 this->controlFlow_s(inst);
15964 return;
15965 }
15966
15967 /* Create symbolic operands */
15968 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
15969 auto op2 = this->symbolicEngine->getOperandAst(inst, index);
15970 auto op3 = this->symbolicEngine->getOperandAst(inst, df);
15971
15972 /* Create the semantics */
15973 auto node1 = op1;
15974 auto node2 = this->astCtxt->ite(
15975 this->astCtxt->equal(op3, this->astCtxt->bvfalse()),
15976 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::dword, index.getBitSize())),
15977 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::dword, index.getBitSize()))
15978 );
15979
15980 /* Create symbolic expression */
15981 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "STOSD operation");
15982 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
15983
15984 /* Spread taint */
15985 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
15986 expr2->isTainted = this->taintEngine->taintUnion(index, index);
15987
15988 /* Update the symbolic control flow */
15989 this->controlFlow_s(inst);
15990 }
15991
15992
15993 void x86Semantics::stosq_s(triton::arch::Instruction& inst) {
15994 auto& dst = inst.operands[0];
15995 auto& src = inst.operands[1];
15996 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
15997 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
15998 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
15999
16000 /* Check if there is a REP prefix and a counter to zero */
16001 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
16002 this->controlFlow_s(inst);
16003 return;
16004 }
16005
16006 /* Create symbolic operands */
16007 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
16008 auto op2 = this->symbolicEngine->getOperandAst(inst, index);
16009 auto op3 = this->symbolicEngine->getOperandAst(inst, df);
16010
16011 /* Create the semantics */
16012 auto node1 = op1;
16013 auto node2 = this->astCtxt->ite(
16014 this->astCtxt->equal(op3, this->astCtxt->bvfalse()),
16015 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::qword, index.getBitSize())),
16016 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::qword, index.getBitSize()))
16017 );
16018
16019 /* Create symbolic expression */
16020 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "STOSQ operation");
16021 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
16022
16023 /* Spread taint */
16024 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
16025 expr2->isTainted = this->taintEngine->taintUnion(index, index);
16026
16027 /* Update the symbolic control flow */
16028 this->controlFlow_s(inst);
16029 }
16030
16031
16032 void x86Semantics::stosw_s(triton::arch::Instruction& inst) {
16033 auto& dst = inst.operands[0];
16034 auto& src = inst.operands[1];
16035 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI));
16036 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
16037 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF));
16038
16039 /* Check if there is a REP prefix and a counter to zero */
16040 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && this->symbolicEngine->getOperandAst(cx)->evaluate().is_zero()) {
16041 this->controlFlow_s(inst);
16042 return;
16043 }
16044
16045 /* Create symbolic operands */
16046 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
16047 auto op2 = this->symbolicEngine->getOperandAst(inst, index);
16048 auto op3 = this->symbolicEngine->getOperandAst(inst, df);
16049
16050 /* Create the semantics */
16051 auto node1 = op1;
16052 auto node2 = this->astCtxt->ite(
16053 this->astCtxt->equal(op3, this->astCtxt->bvfalse()),
16054 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::word, index.getBitSize())),
16055 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::word, index.getBitSize()))
16056 );
16057
16058 /* Create symbolic expression */
16059 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "STOSW operation");
16060 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation");
16061
16062 /* Spread taint */
16063 expr1->isTainted = this->taintEngine->taintAssignment(dst, src);
16064 expr2->isTainted = this->taintEngine->taintUnion(index, index);
16065
16066 /* Update the symbolic control flow */
16067 this->controlFlow_s(inst);
16068 }
16069
16070
16071 void x86Semantics::sub_s(triton::arch::Instruction& inst) {
16072 auto& dst = inst.operands[0];
16073 auto& src = inst.operands[1];
16074
16075 /* Create symbolic operands */
16076 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
16077 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
16078
16079 /* Create the semantics */
16080 auto node = this->astCtxt->bvsub(op1, op2);
16081
16082 /* Create symbolic expression */
16083 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SUB operation");
16084
16085 /* Spread taint */
16086 expr->isTainted = this->taintEngine->taintUnion(dst, src);
16087
16088 /* Update symbolic flags */
16089 this->af_s(inst, expr, dst, op1, op2);
16090 this->cfSub_s(inst, expr, dst, op1, op2);
16091 this->ofSub_s(inst, expr, dst, op1, op2);
16092 this->pf_s(inst, expr, dst);
16093 this->sf_s(inst, expr, dst);
16094 this->zf_s(inst, expr, dst);
16095
16096 /* Update the symbolic control flow */
16097 this->controlFlow_s(inst);
16098 }
16099
16100
16101 void x86Semantics::syscall_s(triton::arch::Instruction& inst) {
16102 auto dst1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX));
16103 auto src1 = triton::arch::OperandWrapper(this->architecture->getProgramCounter());
16104
16105 /* Create symbolic operands */
16106 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
16107
16108 /* Create the semantics */
16109 auto node1 = this->astCtxt->bvadd(op1, this->astCtxt->bv(inst.getSize(), src1.getBitSize()));
16110
16111 /* Create symbolic expression */
16112 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1, "SYSCALL RCX operation");
16113
16114 /* Spread taint */
16115 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src1);
16116
16117 /* 64-bit */
16118 if (src1.getBitSize() == 64) {
16119 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_R11));
16120 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EFLAGS));
16121 /* Create symbolic operands */
16122 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
16123 /* Create symbolic expression */
16124 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, op2, dst2, "SYSCALL R11 operation");
16125 /* Spread taint */
16126 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src2);
16127 }
16128
16129 /* Update the symbolic control flow */
16130 this->controlFlow_s(inst);
16131 }
16132
16133
16134 void x86Semantics::sysenter_s(triton::arch::Instruction& inst) {
16135 /* Update the symbolic control flow */
16136 this->controlFlow_s(inst);
16137 }
16138
16139
16140 void x86Semantics::test_s(triton::arch::Instruction& inst) {
16141 auto& src1 = inst.operands[0];
16142 auto& src2 = inst.operands[1];
16143
16144 /* Create symbolic operands */
16145 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
16146 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
16147
16148 /* Create the semantics */
16149 auto node = this->astCtxt->bvand(op1, op2);
16150
16151 /* Create symbolic expression */
16152 auto expr = this->symbolicEngine->createSymbolicVolatileExpression(inst, node, "TEST operation");
16153
16154 /* Spread taint */
16155 expr->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2);
16156
16157 /* Update symbolic flags */
16158 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
16159 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag");
16160 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
16161 this->pf_s(inst, expr, src1, true);
16162 this->sf_s(inst, expr, src1, true);
16163 this->zf_s(inst, expr, src1, true);
16164
16165 /* Update the symbolic control flow */
16166 this->controlFlow_s(inst);
16167 }
16168
16169
16170 void x86Semantics::tzcnt_s(triton::arch::Instruction& inst) {
16171 auto& dst = inst.operands[0];
16172 auto& src = inst.operands[1];
16173 auto bvSize1 = dst.getBitSize();
16174 auto bvSize2 = src.getBitSize();
16175
16176 /* Create symbolic operands */
16177 auto op1 = this->symbolicEngine->getOperandAst(inst, src);
16178
16179 /* Create the semantics */
16180 triton::ast::SharedAbstractNode node = nullptr;
16181 switch (src.getSize()) {
16182 case triton::size::byte:
16183 node = this->astCtxt->ite(
16184 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)),
16185 this->astCtxt->bv(bvSize1, bvSize1),
16186 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
16187 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
16188 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
16189 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
16190 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
16191 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
16192 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
16193 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
16194 this->astCtxt->bv(0, bvSize1)
16195 ))))))))
16196 );
16197 break;
16198 case triton::size::word:
16199 node = this->astCtxt->ite(
16200 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)),
16201 this->astCtxt->bv(bvSize1, bvSize1),
16202 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
16203 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
16204 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
16205 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
16206 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
16207 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
16208 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
16209 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
16210 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
16211 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
16212 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
16213 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
16214 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
16215 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
16216 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
16217 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
16218 this->astCtxt->bv(0, bvSize1)
16219 ))))))))))))))))
16220 );
16221 break;
16223 node = this->astCtxt->ite(
16224 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)),
16225 this->astCtxt->bv(bvSize1, bvSize1),
16226 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
16227 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
16228 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
16229 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
16230 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
16231 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
16232 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
16233 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
16234 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
16235 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
16236 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
16237 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
16238 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
16239 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
16240 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
16241 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
16242 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(16, 16, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1),
16243 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(17, 17, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1),
16244 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(18, 18, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1),
16245 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(19, 19, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1),
16246 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(20, 20, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1),
16247 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(21, 21, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1),
16248 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(22, 22, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1),
16249 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(23, 23, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1),
16250 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(24, 24, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1),
16251 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(25, 25, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1),
16252 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(26, 26, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1),
16253 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(27, 27, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1),
16254 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(28, 28, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1),
16255 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(29, 29, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1),
16256 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(30, 30, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1),
16257 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(31, 31, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1),
16258 this->astCtxt->bv(0, bvSize1)
16259 ))))))))))))))))))))))))))))))))
16260 );
16261 break;
16263 node = this->astCtxt->ite(
16264 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)),
16265 this->astCtxt->bv(bvSize1, bvSize1),
16266 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1),
16267 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1),
16268 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1),
16269 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1),
16270 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1),
16271 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1),
16272 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1),
16273 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1),
16274 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1),
16275 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1),
16276 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1),
16277 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1),
16278 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1),
16279 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1),
16280 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1),
16281 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1),
16282 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(16, 16, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1),
16283 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(17, 17, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1),
16284 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(18, 18, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1),
16285 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(19, 19, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1),
16286 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(20, 20, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1),
16287 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(21, 21, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1),
16288 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(22, 22, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1),
16289 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(23, 23, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1),
16290 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(24, 24, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1),
16291 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(25, 25, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1),
16292 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(26, 26, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1),
16293 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(27, 27, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1),
16294 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(28, 28, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1),
16295 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(29, 29, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1),
16296 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(30, 30, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1),
16297 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(31, 31, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1),
16298 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(32, 32, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(32, bvSize1),
16299 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(33, 33, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(33, bvSize1),
16300 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(34, 34, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(34, bvSize1),
16301 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(35, 35, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(35, bvSize1),
16302 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(36, 36, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(36, bvSize1),
16303 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(37, 37, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(37, bvSize1),
16304 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(38, 38, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(38, bvSize1),
16305 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(39, 39, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(39, bvSize1),
16306 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(40, 40, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(40, bvSize1),
16307 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(41, 41, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(41, bvSize1),
16308 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(42, 42, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(42, bvSize1),
16309 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(43, 43, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(43, bvSize1),
16310 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(44, 44, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(44, bvSize1),
16311 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(45, 45, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(45, bvSize1),
16312 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(46, 46, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(46, bvSize1),
16313 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(47, 47, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(47, bvSize1),
16314 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(48, 48, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(48, bvSize1),
16315 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(49, 49, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(49, bvSize1),
16316 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(50, 50, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(50, bvSize1),
16317 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(51, 51, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(51, bvSize1),
16318 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(52, 52, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(52, bvSize1),
16319 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(53, 53, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(53, bvSize1),
16320 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(54, 54, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(54, bvSize1),
16321 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(55, 55, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(55, bvSize1),
16322 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(56, 56, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(56, bvSize1),
16323 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(57, 57, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(57, bvSize1),
16324 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(58, 58, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(58, bvSize1),
16325 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(59, 59, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(59, bvSize1),
16326 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(60, 60, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(60, bvSize1),
16327 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(61, 61, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(61, bvSize1),
16328 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(62, 62, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(62, bvSize1),
16329 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(63, 63, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(63, bvSize1),
16330 this->astCtxt->bv(0, bvSize1)
16331 ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
16332 );
16333 break;
16334 default:
16335 throw triton::exceptions::Semantics("x86Semantics::tzcnt_s(): Invalid operand size.");
16336 }
16337
16338 /* Create symbolic expression */
16339 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "TZCNT operation");
16340
16341 /* Spread taint */
16342 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16343
16344 /* Update symbolic flags */
16345 this->cfTzcnt_s(inst, expr, src, op1);
16346 this->zf_s(inst, expr, src);
16347
16348 /* Tag undefined flags */
16349 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF));
16350 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF));
16351 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF));
16352 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
16353
16354 /* Update the symbolic control flow */
16355 this->controlFlow_s(inst);
16356 }
16357
16358
16359 void x86Semantics::unpckhpd_s(triton::arch::Instruction& inst) {
16360 auto& dst = inst.operands[0];
16361 auto& src = inst.operands[1];
16362
16363 /* Create symbolic operands */
16364 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
16365 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
16366
16367 /* Create the semantics */
16368 auto node = this->astCtxt->concat(
16369 this->astCtxt->extract(127, 64, op2),
16370 this->astCtxt->extract(127, 64, op1)
16371 );
16372
16373 /* Create symbolic expression */
16374 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "UNPCKHPD operation");
16375
16376 /* Spread taint */
16377 expr->isTainted = this->taintEngine->taintUnion(dst, src);
16378
16379 /* Update the symbolic control flow */
16380 this->controlFlow_s(inst);
16381 }
16382
16383
16384 void x86Semantics::unpckhps_s(triton::arch::Instruction& inst) {
16385 auto& dst = inst.operands[0];
16386 auto& src = inst.operands[1];
16387
16388 /* Create symbolic operands */
16389 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
16390 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
16391
16392 /* Create the semantics */
16393 std::vector<triton::ast::SharedAbstractNode> unpack;
16394 unpack.reserve(4);
16395
16396 unpack.push_back(this->astCtxt->extract(127, 96, op2));
16397 unpack.push_back(this->astCtxt->extract(127, 96, op1));
16398 unpack.push_back(this->astCtxt->extract(95, 64, op2));
16399 unpack.push_back(this->astCtxt->extract(95, 64, op1));
16400
16401 auto node = this->astCtxt->concat(unpack);
16402
16403 /* Create symbolic expression */
16404 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "UNPCKHPS operation");
16405
16406 /* Spread taint */
16407 expr->isTainted = this->taintEngine->taintUnion(dst, src);
16408
16409 /* Update the symbolic control flow */
16410 this->controlFlow_s(inst);
16411 }
16412
16413
16414 void x86Semantics::unpcklpd_s(triton::arch::Instruction& inst) {
16415 auto& dst = inst.operands[0];
16416 auto& src = inst.operands[1];
16417
16418 /* Create symbolic operands */
16419 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
16420 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
16421
16422 /* Create the semantics */
16423 auto node = this->astCtxt->concat(
16424 this->astCtxt->extract(63, 0, op2),
16425 this->astCtxt->extract(63, 0, op1)
16426 );
16427
16428 /* Create symbolic expression */
16429 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "UNPCKLPD operation");
16430
16431 /* Spread taint */
16432 expr->isTainted = this->taintEngine->taintUnion(dst, src);
16433
16434 /* Update the symbolic control flow */
16435 this->controlFlow_s(inst);
16436 }
16437
16438
16439 void x86Semantics::unpcklps_s(triton::arch::Instruction& inst) {
16440 auto& dst = inst.operands[0];
16441 auto& src = inst.operands[1];
16442
16443 /* Create symbolic operands */
16444 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
16445 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
16446
16447 /* Create the semantics */
16448 std::vector<triton::ast::SharedAbstractNode> unpack;
16449 unpack.reserve(4);
16450
16451 unpack.push_back(this->astCtxt->extract(63, 32, op2));
16452 unpack.push_back(this->astCtxt->extract(63, 32, op1));
16453 unpack.push_back(this->astCtxt->extract(31, 0, op2));
16454 unpack.push_back(this->astCtxt->extract(31, 0, op1));
16455
16456 auto node = this->astCtxt->concat(unpack);
16457
16458 /* Create symbolic expression */
16459 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "UNPCKLPS operation");
16460
16461 /* Spread taint */
16462 expr->isTainted = this->taintEngine->taintUnion(dst, src);
16463
16464 /* Update the symbolic control flow */
16465 this->controlFlow_s(inst);
16466 }
16467
16468
16469 void x86Semantics::verr_s(triton::arch::Instruction& inst) {
16470 auto& src = inst.operands[0];
16471 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
16472
16473 /* Link the source to the instruction */
16474 this->symbolicEngine->getOperandAst(inst, src);
16475
16476 /* Create the semantics */
16477 auto node = this->astCtxt->bvtrue();
16478
16479 /* Create symbolic expression */
16480 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VERR operation");
16481
16482 /* Spread taint */
16483 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16484
16485 /* Update the symbolic control flow */
16486 this->controlFlow_s(inst);
16487 }
16488
16489
16490 void x86Semantics::verw_s(triton::arch::Instruction& inst) {
16491 auto& src = inst.operands[0];
16492 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF));
16493
16494 /* Link the source to the instruction */
16495 this->symbolicEngine->getOperandAst(inst, src);
16496
16497 /* Create the semantics */
16498 auto node = this->astCtxt->bvtrue();
16499
16500 /* Create symbolic expression */
16501 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VERW operation");
16502
16503 /* Spread taint */
16504 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16505
16506 /* Update the symbolic control flow */
16507 this->controlFlow_s(inst);
16508 }
16509
16510
16511 void x86Semantics::vextracti128_s(triton::arch::Instruction& inst) {
16512 auto& dst = inst.operands[0];
16513 auto& src1 = inst.operands[1];
16514 auto& src2 = inst.operands[2];
16515
16516 /* Create symbolic operands */
16517 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
16518 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
16519
16520 /* Create the semantics */
16522 if (op2->evaluate() & 0b00000001) {
16523 node = this->astCtxt->extract(255, 128, op1);
16524 } else {
16525 node = this->astCtxt->extract(127, 0, op1);
16526 }
16527
16528 /* Create symbolic expression */
16529 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VEXTRACTI128 operation");
16530
16531 /* Spread taint */
16532 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
16533
16534 /* Update the symbolic control flow */
16535 this->controlFlow_s(inst);
16536 }
16537
16538
16539 void x86Semantics::vmovd_s(triton::arch::Instruction& inst) {
16540 auto& dst = inst.operands[0];
16541 auto& src = inst.operands[1];
16542
16543 /* Create symbolic operands */
16544 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
16545
16546 /* Create the semantics */
16547 auto node = this->astCtxt->extract(triton::bitsize::dword-1, 0, op2);
16548
16549 /* Create symbolic expression */
16550 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVD operation");
16551
16552 /* Spread taint */
16553 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16554
16555 /* Update the symbolic control flow */
16556 this->controlFlow_s(inst);
16557 }
16558
16559
16560 void x86Semantics::vmovdqa_s(triton::arch::Instruction& inst) {
16561 auto& dst = inst.operands[0];
16562 auto& src = inst.operands[1];
16563
16564 /* Create the semantics */
16565 auto node = this->symbolicEngine->getOperandAst(inst, src);
16566
16567 /* Create symbolic expression */
16568 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVDQA operation");
16569
16570 /* Spread taint */
16571 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16572
16573 /* Update the symbolic control flow */
16574 this->controlFlow_s(inst);
16575 }
16576
16577
16578 void x86Semantics::vmovdqu_s(triton::arch::Instruction& inst) {
16579 auto& dst = inst.operands[0];
16580 auto& src = inst.operands[1];
16581
16582 /* Create the semantics */
16583 auto node = this->symbolicEngine->getOperandAst(inst, src);
16584
16585 /* Create symbolic expression */
16586 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVDQU operation");
16587
16588 /* Spread taint */
16589 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16590
16591 /* Update the symbolic control flow */
16592 this->controlFlow_s(inst);
16593 }
16594
16595
16596 void x86Semantics::vmovntdq_s(triton::arch::Instruction& inst) {
16597 auto& dst = inst.operands[0];
16598 auto& src = inst.operands[1];
16599
16600 /* Create the semantics */
16601 auto node = this->symbolicEngine->getOperandAst(inst, src);
16602
16603 /* Create symbolic expression */
16604 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVNTDQ operation");
16605
16606 /* Spread taint */
16607 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16608
16609 /* Update the symbolic control flow */
16610 this->controlFlow_s(inst);
16611 }
16612
16613
16614 void x86Semantics::vmovq_s(triton::arch::Instruction& inst) {
16615 auto& dst = inst.operands[0];
16616 auto& src = inst.operands[1];
16617
16618 /* Create symbolic operands */
16619 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
16620
16621 /* Create the semantics */
16622 auto node = this->astCtxt->extract(triton::bitsize::qword-1, 0, op2);
16623
16624 /* Create symbolic expression */
16625 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVQ operation");
16626
16627 /* Spread taint */
16628 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16629
16630 /* Update the symbolic control flow */
16631 this->controlFlow_s(inst);
16632 }
16633
16634
16635 void x86Semantics::vmovsd_s(triton::arch::Instruction& inst) {
16636 /* Move scalar double-precision floating-point value */
16637 if (inst.operands.size() == 2) {
16638 auto& dst = inst.operands[0];
16639 auto& src = inst.operands[1];
16640
16641 /* Create symbolic operands */
16642 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
16643 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
16644
16645 /* Create the semantics */
16647 if (dst.getSize() == triton::size::dqword && src.getSize() == triton::size::qword) {
16648 /* VEX.LIG.F2.0F.WIG 10 /r VMOVSD xmm1, m64 */
16649 node = op2;
16650 }
16651 else if (dst.getSize() == triton::size::qword && src.getSize() == triton::size::dqword) {
16652 /* VEX.LIG.F2.0F.WIG 11 /r VMOVSD m64, xmm1 */
16653 node = this->astCtxt->extract(triton::bitsize::qword - 1, 0, op2);
16654 }
16655 else {
16656 throw triton::exceptions::Semantics("x86Semantics::vmovsd_s(): Invalid operand size.");
16657 }
16658
16659 /* Create symbolic expression */
16660 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVSD operation");
16661
16662 /* Spread taint */
16663 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16664 }
16665
16666 /* Merge scalar double-precision floating-point value
16667 *
16668 * VEX.NDS.LIG.F2.0F.WIG 10 /r VMOVSD xmm1, xmm2, xmm3
16669 * VEX.NDS.LIG.F2.0F.WIG 11 /r VMOVSD xmm1, xmm2, xmm3
16670 */
16671 else if (inst.operands.size() == 3) {
16672 auto& dst = inst.operands[0];
16673 auto& src1 = inst.operands[1];
16674 auto& src2 = inst.operands[2];
16675
16676 /* Create symbolic operands */
16677 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
16678 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
16679 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
16680
16681 /* Create the semantics */
16682 auto node = this->astCtxt->concat(
16683 this->astCtxt->extract(triton::bitsize::dqword - 1, triton::bitsize::qword, op2),
16684 this->astCtxt->extract(triton::bitsize::qword - 1, 0, op3)
16685 );
16686
16687 /* Create symbolic expression */
16688 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVSD operation");
16689
16690 /* Spread taint */
16691 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
16692 }
16693
16694 /* Update the symbolic control flow */
16695 this->controlFlow_s(inst);
16696 }
16697
16698
16699 void x86Semantics::vmovaps_s(triton::arch::Instruction& inst) {
16700 auto& dst = inst.operands[0];
16701 auto& src = inst.operands[1];
16702
16703 /* Create the semantics */
16704 auto node = this->symbolicEngine->getOperandAst(inst, src);
16705
16706 /* Create symbolic expression */
16707 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVAPS operation");
16708
16709 /* Spread taint */
16710 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16711
16712 /* Update the symbolic control flow */
16713 this->controlFlow_s(inst);
16714 }
16715
16716
16717 void x86Semantics::vmovups_s(triton::arch::Instruction& inst) {
16718 auto& dst = inst.operands[0];
16719 auto& src = inst.operands[1];
16720
16721 /* Create the semantics */
16722 auto node = this->symbolicEngine->getOperandAst(inst, src);
16723
16724 /* Create symbolic expression */
16725 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVUPS operation");
16726
16727 /* Spread taint */
16728 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
16729
16730 /* Update the symbolic control flow */
16731 this->controlFlow_s(inst);
16732 }
16733
16734
16735 void x86Semantics::vpackuswb_s(triton::arch::Instruction& inst) {
16736 auto& dst = inst.operands[0];
16737 auto& src1 = inst.operands[1];
16738 auto& src2 = inst.operands[2];
16739
16740 /* Create symbolic operands */
16741 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
16742 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
16743
16744 /* Create the semantics */
16745 std::vector<triton::ast::SharedAbstractNode> pck;
16746 pck.reserve(dst.getSize());
16747
16748 std::vector<triton::ast::SharedAbstractNode> ops{op2, op1};
16749 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
16750 for (triton::uint32 idx = 0; idx < ops.size(); ++idx) {
16751 for (triton::uint32 i = triton::size::qword * k; i < triton::size::qword * (k + 1); ++i) {
16752 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
16754 auto signed_word = this->astCtxt->extract(high, low, ops[idx]);
16755 pck.push_back(this->astCtxt->ite(
16756 this->astCtxt->bvsge(signed_word, this->astCtxt->bv(0xff, triton::bitsize::word)),
16757 this->astCtxt->bv(0xff, triton::bitsize::byte),
16758 this->astCtxt->ite(
16759 this->astCtxt->bvsle(signed_word, this->astCtxt->bv(0x00, triton::bitsize::word)),
16760 this->astCtxt->bv(0x00, triton::bitsize::byte),
16761 this->astCtxt->extract(triton::bitsize::byte - 1, 0, signed_word)))
16762 );
16763 }
16764 }
16765 }
16766
16767 auto node = this->astCtxt->concat(pck);
16768
16769 /* Create symbolic expression */
16770 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPACKUSWB operation");
16771
16772 /* Apply the taint */
16773 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
16774
16775 /* Update the symbolic control flow */
16776 this->controlFlow_s(inst);
16777 }
16778
16779
16780 void x86Semantics::vpackssdw_s(triton::arch::Instruction& inst) {
16781 auto& dst = inst.operands[0];
16782 auto& src1 = inst.operands[1];
16783 auto& src2 = inst.operands[2];
16784
16785 /* Create symbolic operands */
16786 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
16787 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
16788
16789 /* Create the semantics */
16790 std::vector<triton::ast::SharedAbstractNode> pck;
16791 pck.reserve(dst.getSize() / triton::size::word);
16792
16793 std::vector<triton::ast::SharedAbstractNode> ops{op2, op1};
16794 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
16795 for (triton::uint32 idx = 0; idx < ops.size(); ++idx) {
16796 for (triton::uint32 i = triton::size::dword * k; i < triton::size::dword * (k + 1); ++i) {
16797 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::dword);
16799 auto signed_dword = this->astCtxt->extract(high, low, ops[idx]);
16800 pck.push_back(this->astCtxt->ite(
16801 this->astCtxt->bvsge(signed_dword, this->astCtxt->bv(0x7fff, triton::bitsize::dword)),
16802 this->astCtxt->bv(0x7fff, triton::bitsize::word),
16803 this->astCtxt->ite(
16804 this->astCtxt->bvsle(signed_dword, this->astCtxt->bv(0xffff8000, triton::bitsize::dword)),
16805 this->astCtxt->bv(0x8000, triton::bitsize::word),
16806 this->astCtxt->extract(triton::bitsize::word - 1, 0, signed_dword)))
16807 );
16808 }
16809 }
16810 }
16811
16812 auto node = this->astCtxt->concat(pck);
16813
16814 /* Create symbolic expression */
16815 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPACKSSDW operation");
16816
16817 /* Apply the taint */
16818 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
16819
16820 /* Update the symbolic control flow */
16821 this->controlFlow_s(inst);
16822 }
16823
16824
16825 void x86Semantics::vpacksswb_s(triton::arch::Instruction& inst) {
16826 auto& dst = inst.operands[0];
16827 auto& src1 = inst.operands[1];
16828 auto& src2 = inst.operands[2];
16829
16830 /* Create symbolic operands */
16831 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
16832 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
16833
16834 /* Create the semantics */
16835 std::vector<triton::ast::SharedAbstractNode> pck;
16836 pck.reserve(dst.getSize());
16837
16838 std::vector<triton::ast::SharedAbstractNode> ops{op2, op1};
16839 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
16840 for (triton::uint32 idx = 0; idx < ops.size(); ++idx) {
16841 for (triton::uint32 i = triton::size::qword * k; i < triton::size::qword * (k + 1); ++i) {
16842 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
16844 auto signed_word = this->astCtxt->extract(high, low, ops[idx]);
16845 pck.push_back(this->astCtxt->ite(
16846 this->astCtxt->bvsge(signed_word, this->astCtxt->bv(0x007f, triton::bitsize::word)),
16847 this->astCtxt->bv(0x7f, triton::bitsize::byte),
16848 this->astCtxt->ite(
16849 this->astCtxt->bvsle(signed_word, this->astCtxt->bv(0xff80, triton::bitsize::word)),
16850 this->astCtxt->bv(0x80, triton::bitsize::byte),
16851 this->astCtxt->extract(triton::bitsize::byte - 1, 0, signed_word)))
16852 );
16853 }
16854 }
16855 }
16856
16857 auto node = this->astCtxt->concat(pck);
16858
16859 /* Create symbolic expression */
16860 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPACKSSWB operation");
16861
16862 /* Apply the taint */
16863 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
16864
16865 /* Update the symbolic control flow */
16866 this->controlFlow_s(inst);
16867 }
16868
16869
16870 void x86Semantics::vpaddb_s(triton::arch::Instruction& inst) {
16871 auto& dst = inst.operands[0];
16872 auto& src1 = inst.operands[1];
16873 auto& src2 = inst.operands[2];
16874
16875 /* Create symbolic operands */
16876 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
16877 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
16878
16879 /* Create the semantics */
16880 std::vector<triton::ast::SharedAbstractNode> pck;
16881 pck.reserve(dst.getSize() / triton::size::byte);
16882
16883 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::byte; ++i) {
16884 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::byte);
16886 pck.push_back(this->astCtxt->bvadd(this->astCtxt->extract(high, low, op1), this->astCtxt->extract(high, low, op2)));
16887 }
16888 auto node = this->astCtxt->concat(pck);
16889
16890 /* Create symbolic expression */
16891 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPADDB operation");
16892
16893 /* Spread taint */
16894 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
16895
16896 /* Update the symbolic control flow */
16897 this->controlFlow_s(inst);
16898 }
16899
16900
16901 void x86Semantics::vpaddd_s(triton::arch::Instruction& inst) {
16902 auto& dst = inst.operands[0];
16903 auto& src1 = inst.operands[1];
16904 auto& src2 = inst.operands[2];
16905
16906 /* Create symbolic operands */
16907 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
16908 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
16909
16910 /* Create the semantics */
16911 std::vector<triton::ast::SharedAbstractNode> pck;
16912 pck.reserve(dst.getSize() / triton::size::dword);
16913
16914 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::dword; ++i) {
16915 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::dword);
16917 pck.push_back(this->astCtxt->bvadd(this->astCtxt->extract(high, low, op1), this->astCtxt->extract(high, low, op2)));
16918 }
16919 auto node = this->astCtxt->concat(pck);
16920
16921 /* Create symbolic expression */
16922 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPADDD operation");
16923
16924 /* Spread taint */
16925 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
16926
16927 /* Update the symbolic control flow */
16928 this->controlFlow_s(inst);
16929 }
16930
16931
16932 void x86Semantics::vpaddw_s(triton::arch::Instruction& inst) {
16933 auto& dst = inst.operands[0];
16934 auto& src1 = inst.operands[1];
16935 auto& src2 = inst.operands[2];
16936
16937 /* Create symbolic operands */
16938 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
16939 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
16940
16941 /* Create the semantics */
16942 std::vector<triton::ast::SharedAbstractNode> pck;
16943 pck.reserve(dst.getSize() / triton::size::word);
16944
16945 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; ++i) {
16946 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
16948 pck.push_back(this->astCtxt->bvadd(this->astCtxt->extract(high, low, op1), this->astCtxt->extract(high, low, op2)));
16949 }
16950 auto node = this->astCtxt->concat(pck);
16951
16952 /* Create symbolic expression */
16953 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPADDW operation");
16954
16955 /* Spread taint */
16956 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
16957
16958 /* Update the symbolic control flow */
16959 this->controlFlow_s(inst);
16960 }
16961
16962
16963 void x86Semantics::vpand_s(triton::arch::Instruction& inst) {
16964 auto& dst = inst.operands[0];
16965 auto& src1 = inst.operands[1];
16966 auto& src2 = inst.operands[2];
16967
16968 /* Create symbolic operands */
16969 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
16970 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
16971
16972 /* Create the semantics */
16973 auto node = this->astCtxt->bvand(op2, op3);
16974
16975 /* Create symbolic expression */
16976 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPAND operation");
16977
16978 /* Spread taint */
16979 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
16980
16981 /* Update the symbolic control flow */
16982 this->controlFlow_s(inst);
16983 }
16984
16985
16986 void x86Semantics::vpandn_s(triton::arch::Instruction& inst) {
16987 auto& dst = inst.operands[0];
16988 auto& src1 = inst.operands[1];
16989 auto& src2 = inst.operands[2];
16990
16991 /* Create symbolic operands */
16992 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
16993 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
16994
16995 /* Create the semantics */
16996 auto node = this->astCtxt->bvand(this->astCtxt->bvnot(op2), op3);
16997
16998 /* Create symbolic expression */
16999 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPANDN operation");
17000
17001 /* Spread taint */
17002 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17003
17004 /* Update the symbolic control flow */
17005 this->controlFlow_s(inst);
17006 }
17007
17008
17009 void x86Semantics::vperm2i128_s(triton::arch::Instruction& inst) {
17010 auto& dst = inst.operands[0];
17011 auto& src1 = inst.operands[1];
17012 auto& src2 = inst.operands[2];
17013 auto& src3 = inst.operands[3];
17014
17015 /* Create symbolic operands */
17016 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17017 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17018 auto op3 = this->symbolicEngine->getOperandAst(inst, src3);
17019
17020 /* Create the semantics */
17021 std::deque<triton::arch::OperandWrapper> taint;
17022 auto permute = [&] (triton::uint8 control) {
17023 switch (control) {
17024 case 0:
17025 taint.push_back(src1);
17026 return this->astCtxt->extract(127, 0, op1);
17027 case 1:
17028 taint.push_back(src1);
17029 return this->astCtxt->extract(255, 128, op1);
17030 case 2:
17031 taint.push_back(src2);
17032 return this->astCtxt->extract(127, 0, op2);
17033 case 3:
17034 default:
17035 taint.push_back(src2);
17036 return this->astCtxt->extract(255, 128, op2);
17037 }
17038 };
17039
17040 auto ctrl = static_cast<triton::uint8>(op3->evaluate());
17041 auto high = permute((ctrl >> 4) & 0b00000011);
17042 auto low = permute(ctrl & 0b00000011);
17043
17044 if (ctrl & 0b00001000) {
17045 low = this->astCtxt->bv(0, 128);
17046 taint.pop_back();
17047 }
17048
17049 if (ctrl & 0b10000000) {
17050 high = this->astCtxt->bv(0, 128);
17051 taint.pop_front();
17052 }
17053
17054 auto node = this->astCtxt->concat(high, low);
17055
17056 /* Create symbolic expression */
17057 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPERM2I128 operation");
17058
17059 /* Spread taint */
17060 if (taint.empty()) {
17061 this->taintEngine->setTaint(dst, false);
17062 } else if (taint.size() == 1) {
17063 expr->isTainted = this->taintEngine->taintAssignment(dst, taint[0]);
17064 } else {
17065 expr->isTainted = this->taintEngine->taintAssignment(dst, taint[0]) | this->taintEngine->taintUnion(dst, taint[0]);
17066 }
17067
17068 /* Update the symbolic control flow */
17069 this->controlFlow_s(inst);
17070 }
17071
17072
17073 void x86Semantics::vpermq_s(triton::arch::Instruction& inst) {
17074 auto& dst = inst.operands[0];
17075 auto& src1 = inst.operands[1];
17076 auto& src2 = inst.operands[2];
17077
17078 /* Create symbolic operands */
17079 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17080 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17081
17082 /* Create the semantics */
17083 std::vector<triton::ast::SharedAbstractNode> pck;
17084 pck.reserve(dst.getSize() / triton::size::byte);
17085
17086 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::qword; ++i) {
17087 auto high = triton::bitsize::byte - 1 - 2 * i;
17088 auto shift = this->astCtxt->bvmul(
17089 this->astCtxt->bv(triton::bitsize::qword, src1.getBitSize()),
17090 this->astCtxt->zx(src1.getBitSize() - 2,
17091 this->astCtxt->extract(high, high - 1, op2)));
17092 pck.push_back(this->astCtxt->extract(triton::bitsize::qword - 1, 0, this->astCtxt->bvlshr(op1, shift)));
17093 }
17094
17095 auto node = this->astCtxt->concat(pck);
17096
17097 /* Create symbolic expression */
17098 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPERMQ operation");
17099
17100 /* Spread taint */
17101 expr->isTainted = this->taintEngine->taintUnion(dst, src1);
17102
17103 /* Update the symbolic control flow */
17104 this->controlFlow_s(inst);
17105 }
17106
17107
17108 void x86Semantics::vpextrb_s(triton::arch::Instruction& inst) {
17109 auto& dst = inst.operands[0];
17110 auto& src1 = inst.operands[1];
17111 auto& src2 = inst.operands[2];
17112
17113 /* Create symbolic operands */
17114 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
17115 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
17116 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
17117
17118 auto node = this->astCtxt->extract(7, 0,
17119 this->astCtxt->bvlshr(
17120 op2,
17121 this->astCtxt->bv(((op3->evaluate() & 0x0f) * 8), op2->getBitvectorSize())
17122 )
17123 );
17124
17125 /* Create symbolic expression */
17126 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPEXTRB operation");
17127
17128 /* Apply the taint */
17129 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
17130
17131 /* Update the symbolic control flow */
17132 this->controlFlow_s(inst);
17133 }
17134
17135
17136 void x86Semantics::vpextrd_s(triton::arch::Instruction& inst) {
17137 auto& dst = inst.operands[0];
17138 auto& src1 = inst.operands[1];
17139 auto& src2 = inst.operands[2];
17140
17141 /* Create symbolic operands */
17142 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
17143 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
17144 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
17145
17146 auto node = this->astCtxt->extract(triton::bitsize::dword - 1, 0,
17147 this->astCtxt->bvlshr(
17148 op2,
17149 this->astCtxt->bv(((op3->evaluate() & 0x3) * triton::bitsize::dword), op2->getBitvectorSize())
17150 )
17151 );
17152
17153 /* Create symbolic expression */
17154 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPEXTRD operation");
17155
17156 /* Apply the taint */
17157 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
17158
17159 /* Update the symbolic control flow */
17160 this->controlFlow_s(inst);
17161 }
17162
17163
17164 void x86Semantics::vpextrq_s(triton::arch::Instruction& inst) {
17165 auto& dst = inst.operands[0];
17166 auto& src1 = inst.operands[1];
17167 auto& src2 = inst.operands[2];
17168
17169 /* Create symbolic operands */
17170 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
17171 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
17172 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
17173
17174 auto node = this->astCtxt->extract(triton::bitsize::qword - 1, 0,
17175 this->astCtxt->bvlshr(
17176 op2,
17177 this->astCtxt->bv(((op3->evaluate() & 0x1) * triton::bitsize::qword), op2->getBitvectorSize())
17178 )
17179 );
17180
17181 /* Create symbolic expression */
17182 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPEXTRQ operation");
17183
17184 /* Apply the taint */
17185 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
17186
17187 /* Update the symbolic control flow */
17188 this->controlFlow_s(inst);
17189 }
17190
17191
17192 void x86Semantics::vpextrw_s(triton::arch::Instruction& inst) {
17193 triton::uint32 count = 0;
17194 auto& dst = inst.operands[0];
17195 auto& src1 = inst.operands[1];
17196 auto& src2 = inst.operands[2];
17197
17198 /*
17199 * When specifying a word location in an MMX technology register, the
17200 * 2 least-significant bits of the count operand specify the location;
17201 * for an XMM register, the 3 least-significant bits specify the
17202 * location.
17203 */
17204 if (src1.getBitSize() == triton::bitsize::qword) {
17205 count = 0x03;
17206 }
17207 else {
17208 count = 0x07;
17209 }
17210
17211 /* Create symbolic operands */
17212 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
17213 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
17214 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
17215
17216 auto node = this->astCtxt->extract(triton::bitsize::word - 1, 0,
17217 this->astCtxt->bvlshr(
17218 op2,
17219 this->astCtxt->bv(((op3->evaluate() & count) * triton::bitsize::word), op2->getBitvectorSize())
17220 )
17221 );
17222
17223 /* Create symbolic expression */
17224 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPEXTRW operation");
17225
17226 /* Apply the taint */
17227 expr->isTainted = this->taintEngine->taintAssignment(dst, src1);
17228
17229 /* Update the symbolic control flow */
17230 this->controlFlow_s(inst);
17231 }
17232
17233
17234 void x86Semantics::vpbroadcastb_s(triton::arch::Instruction& inst) {
17235 auto &dst = inst.operands[0];
17236 auto &src = inst.operands[1];
17237
17238 /* Create symbolic operands */
17239 auto op = this->symbolicEngine->getOperandAst(inst, src);
17240
17241 /* Create the semantics */
17242 auto src_node = this->astCtxt->extract(triton::bitsize::byte - 1, 0, op);
17243 std::vector<triton::ast::SharedAbstractNode> exprs(dst.getSize(), src_node);
17244 auto node = this->astCtxt->concat(exprs);
17245
17246 /* Create symbolic expression */
17247 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPBROADCASTB operation");
17248
17249 /* Spread taint */
17250 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
17251
17252 /* Update the symbolic control flow */
17253 this->controlFlow_s(inst);
17254 }
17255
17256
17257 void x86Semantics::vpcmpeqb_s(triton::arch::Instruction& inst) {
17258 auto& dst = inst.operands[0];
17259 auto& src1 = inst.operands[1];
17260 auto& src2 = inst.operands[2];
17261
17262 /* Create symbolic operands */
17263 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17264 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17265
17266 /* Create the semantics */
17267 std::vector<triton::ast::SharedAbstractNode> pck;
17268 pck.reserve(dst.getSize());
17269
17270 for (triton::uint32 index = 0; index < src1.getSize(); index++) {
17271 uint32 high = (src1.getBitSize() - 1) - (index * triton::bitsize::byte);
17272 uint32 low = (src1.getBitSize() - triton::bitsize::byte) - (index * triton::bitsize::byte);
17273 pck.push_back(this->astCtxt->ite(
17274 this->astCtxt->equal(
17275 this->astCtxt->extract(high, low, op1),
17276 this->astCtxt->extract(high, low, op2)),
17277 this->astCtxt->bv(0xff, triton::bitsize::byte),
17278 this->astCtxt->bv(0x00, triton::bitsize::byte))
17279 );
17280 }
17281
17282 auto node = this->astCtxt->concat(pck);
17283
17284 /* Create symbolic expression */
17285 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPCMPEQB operation");
17286
17287 /* Apply the taint */
17288 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17289
17290 /* Update the symbolic control flow */
17291 this->controlFlow_s(inst);
17292 }
17293
17294
17295 void x86Semantics::vpcmpeqd_s(triton::arch::Instruction& inst) {
17296 auto& dst = inst.operands[0];
17297 auto& src1 = inst.operands[1];
17298 auto& src2 = inst.operands[2];
17299
17300 /* Create symbolic operands */
17301 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17302 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17303
17304 /* Create the semantics */
17305 std::vector<triton::ast::SharedAbstractNode> pck;
17306 pck.reserve(dst.getSize() / triton::size::dword);
17307
17308 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) {
17309 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword);
17311 pck.push_back(this->astCtxt->ite(
17312 this->astCtxt->equal(
17313 this->astCtxt->extract(high, low, op1),
17314 this->astCtxt->extract(high, low, op2)),
17315 this->astCtxt->bv(0xffffffff, triton::bitsize::dword),
17316 this->astCtxt->bv(0x00000000, triton::bitsize::dword))
17317 );
17318 }
17319
17320 auto node = this->astCtxt->concat(pck);
17321
17322 /* Create symbolic expression */
17323 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPCMPEQD operation");
17324
17325 /* Apply the taint */
17326 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17327
17328 /* Update the symbolic control flow */
17329 this->controlFlow_s(inst);
17330 }
17331
17332
17333 void x86Semantics::vpcmpeqq_s(triton::arch::Instruction& inst) {
17334 auto& dst = inst.operands[0];
17335 auto& src1 = inst.operands[1];
17336 auto& src2 = inst.operands[2];
17337
17338 /* Create symbolic operands */
17339 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17340 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17341
17342 /* Create the semantics */
17343 std::vector<triton::ast::SharedAbstractNode> pck;
17344 pck.reserve(dst.getSize() / triton::size::qword);
17345
17346 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::qword; index++) {
17347 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::qword);
17349 pck.push_back(this->astCtxt->ite(
17350 this->astCtxt->equal(
17351 this->astCtxt->extract(high, low, op1),
17352 this->astCtxt->extract(high, low, op2)),
17353 this->astCtxt->bv(0xffffffffffffffff, triton::bitsize::qword),
17354 this->astCtxt->bv(0x0000000000000000, triton::bitsize::qword))
17355 );
17356 }
17357
17358 auto node = this->astCtxt->concat(pck);
17359
17360 /* Create symbolic expression */
17361 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPCMPEQQ operation");
17362
17363 /* Apply the taint */
17364 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17365
17366 /* Update the symbolic control flow */
17367 this->controlFlow_s(inst);
17368 }
17369
17370
17371 void x86Semantics::vpcmpeqw_s(triton::arch::Instruction& inst) {
17372 auto& dst = inst.operands[0];
17373 auto& src1 = inst.operands[1];
17374 auto& src2 = inst.operands[2];
17375
17376 /* Create symbolic operands */
17377 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17378 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17379
17380 /* Create the semantics */
17381 std::vector<triton::ast::SharedAbstractNode> pck;
17382 pck.reserve(dst.getSize() / triton::size::word);
17383
17384 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
17385 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
17387 pck.push_back(this->astCtxt->ite(
17388 this->astCtxt->equal(
17389 this->astCtxt->extract(high, low, op1),
17390 this->astCtxt->extract(high, low, op2)),
17391 this->astCtxt->bv(0xffff, triton::bitsize::word),
17392 this->astCtxt->bv(0x0000, triton::bitsize::word))
17393 );
17394 }
17395
17396 auto node = this->astCtxt->concat(pck);
17397
17398 /* Create symbolic expression */
17399 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPCMPEQW operation");
17400
17401 /* Apply the taint */
17402 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17403
17404 /* Update the symbolic control flow */
17405 this->controlFlow_s(inst);
17406 }
17407
17408
17409 void x86Semantics::vpcmpgtb_s(triton::arch::Instruction& inst) {
17410 auto& dst = inst.operands[0];
17411 auto& src1 = inst.operands[1];
17412 auto& src2 = inst.operands[2];
17413
17414 /* Create symbolic operands */
17415 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17416 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17417
17418 /* Create the semantics */
17419 std::vector<triton::ast::SharedAbstractNode> pck;
17420 pck.reserve(dst.getSize());
17421
17422 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
17423 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
17425 pck.push_back(this->astCtxt->ite(
17426 this->astCtxt->bvsgt(
17427 this->astCtxt->extract(high, low, op1),
17428 this->astCtxt->extract(high, low, op2)),
17429 this->astCtxt->bv(0xff, triton::bitsize::byte),
17430 this->astCtxt->bv(0x00, triton::bitsize::byte))
17431 );
17432 }
17433
17434 auto node = this->astCtxt->concat(pck);
17435
17436 /* Create symbolic expression */
17437 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPCMPGTB operation");
17438
17439 /* Apply the taint */
17440 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17441
17442 /* Update the symbolic control flow */
17443 this->controlFlow_s(inst);
17444 }
17445
17446
17447 void x86Semantics::vpcmpgtd_s(triton::arch::Instruction& inst) {
17448 auto& dst = inst.operands[0];
17449 auto& src1 = inst.operands[1];
17450 auto& src2 = inst.operands[2];
17451
17452 /* Create symbolic operands */
17453 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17454 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17455
17456 /* Create the semantics */
17457 std::vector<triton::ast::SharedAbstractNode> pck;
17458 pck.reserve(dst.getSize() / triton::size::dword);
17459
17460 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) {
17461 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword);
17463 pck.push_back(this->astCtxt->ite(
17464 this->astCtxt->bvsgt(
17465 this->astCtxt->extract(high, low, op1),
17466 this->astCtxt->extract(high, low, op2)),
17467 this->astCtxt->bv(0xffffffff, triton::bitsize::dword),
17468 this->astCtxt->bv(0x00000000, triton::bitsize::dword))
17469 );
17470 }
17471
17472 auto node = this->astCtxt->concat(pck);
17473
17474 /* Create symbolic expression */
17475 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPCMPGTD operation");
17476
17477 /* Apply the taint */
17478 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17479
17480 /* Update the symbolic control flow */
17481 this->controlFlow_s(inst);
17482 }
17483
17484
17485 void x86Semantics::vpcmpgtw_s(triton::arch::Instruction& inst) {
17486 auto& dst = inst.operands[0];
17487 auto& src1 = inst.operands[1];
17488 auto& src2 = inst.operands[2];
17489
17490 /* Create symbolic operands */
17491 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17492 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17493
17494 /* Create the semantics */
17495 std::vector<triton::ast::SharedAbstractNode> pck;
17496 pck.reserve(dst.getSize() / triton::size::word);
17497
17498 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
17499 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
17501 pck.push_back(this->astCtxt->ite(
17502 this->astCtxt->bvsgt(
17503 this->astCtxt->extract(high, low, op1),
17504 this->astCtxt->extract(high, low, op2)),
17505 this->astCtxt->bv(0xffff, triton::bitsize::word),
17506 this->astCtxt->bv(0x0000, triton::bitsize::word))
17507 );
17508 }
17509
17510 auto node = this->astCtxt->concat(pck);
17511
17512 /* Create symbolic expression */
17513 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPCMPGTW operation");
17514
17515 /* Apply the taint */
17516 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17517
17518 /* Update the symbolic control flow */
17519 this->controlFlow_s(inst);
17520 }
17521
17522
17523 void x86Semantics::vpmaddwd_s(triton::arch::Instruction& inst) {
17524 auto& dst = inst.operands[0];
17525 auto& src1 = inst.operands[1];
17526 auto& src2 = inst.operands[2];
17527
17528 /* Create symbolic operands */
17529 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17530 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17531
17532 /* Create the semantics */
17533 std::vector<triton::ast::SharedAbstractNode> pck;
17534 pck.reserve(dst.getSize() / triton::size::dword);
17535
17536 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; i += 2) {
17537 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
17539 auto node1 = this->astCtxt->bvmul(
17540 this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op1)),
17541 this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op2))
17542 );
17543 high -= triton::bitsize::word;
17544 low -= triton::bitsize::word;
17545 auto node2 = this->astCtxt->bvmul(
17546 this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op1)),
17547 this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op2))
17548 );
17549 pck.push_back(this->astCtxt->bvadd(node1, node2));
17550 }
17551
17552 auto node = this->astCtxt->concat(pck);
17553
17554 /* Create symbolic expression */
17555 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPMADDWD operation");
17556
17557 /* Apply the taint */
17558 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17559
17560 /* Update the symbolic control flow */
17561 this->controlFlow_s(inst);
17562 }
17563
17564
17565 void x86Semantics::vpmovmskb_s(triton::arch::Instruction& inst) {
17566 auto& dst = inst.operands[0];
17567 auto& src = inst.operands[1];
17568
17569 /* Create symbolic operands */
17570 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
17571
17572 /* Create the semantics */
17573 std::vector<triton::ast::SharedAbstractNode> mskb;
17574 mskb.reserve(32);
17575
17576 switch (src.getSize()) {
17578 mskb.push_back(this->astCtxt->extract(255, 255, op2));
17579 mskb.push_back(this->astCtxt->extract(247, 247, op2));
17580 mskb.push_back(this->astCtxt->extract(239, 239, op2));
17581 mskb.push_back(this->astCtxt->extract(231, 231, op2));
17582 mskb.push_back(this->astCtxt->extract(223, 223, op2));
17583 mskb.push_back(this->astCtxt->extract(215, 215, op2));
17584 mskb.push_back(this->astCtxt->extract(207, 207, op2));
17585 mskb.push_back(this->astCtxt->extract(199, 199, op2));
17586 mskb.push_back(this->astCtxt->extract(191, 191, op2));
17587 mskb.push_back(this->astCtxt->extract(183, 183, op2));
17588 mskb.push_back(this->astCtxt->extract(175, 175, op2));
17589 mskb.push_back(this->astCtxt->extract(167, 167, op2));
17590 mskb.push_back(this->astCtxt->extract(159, 159, op2));
17591 mskb.push_back(this->astCtxt->extract(151, 151, op2));
17592 mskb.push_back(this->astCtxt->extract(143, 143, op2));
17593 mskb.push_back(this->astCtxt->extract(135, 135, op2));
17594
17596 mskb.push_back(this->astCtxt->extract(127, 127, op2));
17597 mskb.push_back(this->astCtxt->extract(119, 119, op2));
17598 mskb.push_back(this->astCtxt->extract(111, 111, op2));
17599 mskb.push_back(this->astCtxt->extract(103, 103, op2));
17600 mskb.push_back(this->astCtxt->extract(95 , 95 , op2));
17601 mskb.push_back(this->astCtxt->extract(87 , 87 , op2));
17602 mskb.push_back(this->astCtxt->extract(79 , 79 , op2));
17603 mskb.push_back(this->astCtxt->extract(71 , 71 , op2));
17604 mskb.push_back(this->astCtxt->extract(63 , 63 , op2));
17605 mskb.push_back(this->astCtxt->extract(55 , 55 , op2));
17606 mskb.push_back(this->astCtxt->extract(47 , 47 , op2));
17607 mskb.push_back(this->astCtxt->extract(39 , 39 , op2));
17608 mskb.push_back(this->astCtxt->extract(31 , 31 , op2));
17609 mskb.push_back(this->astCtxt->extract(23 , 23 , op2));
17610 mskb.push_back(this->astCtxt->extract(15 , 15 , op2));
17611 mskb.push_back(this->astCtxt->extract(7 , 7 , op2));
17612 break;
17613
17614 default:
17615 throw triton::exceptions::Semantics("x86Semantics::vpmovmskb_s(): Invalid operand size.");
17616 }
17617
17618 auto node = this->astCtxt->zx(
17619 dst.getBitSize() - static_cast<triton::uint32>(mskb.size()),
17620 this->astCtxt->concat(mskb)
17621 );
17622
17623 /* Create symbolic expression */
17624 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPMOVMSKB operation");
17625
17626 /* Apply the taint */
17627 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
17628
17629 /* Update the symbolic control flow */
17630 this->controlFlow_s(inst);
17631 }
17632
17633
17634 void x86Semantics::vpminub_s(triton::arch::Instruction& inst) {
17635 auto& dst = inst.operands[0];
17636 auto& src1 = inst.operands[1];
17637 auto& src2 = inst.operands[2];
17638
17639 /* Create symbolic operands */
17640 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17641 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17642
17643 /* Create the semantics */
17644 std::vector<triton::ast::SharedAbstractNode> pck;
17645 pck.reserve(dst.getSize());
17646
17647 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
17648 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
17650 pck.push_back(this->astCtxt->ite(
17651 this->astCtxt->bvuge(
17652 this->astCtxt->extract(high, low, op1),
17653 this->astCtxt->extract(high, low, op2)),
17654 this->astCtxt->extract(high, low, op2),
17655 this->astCtxt->extract(high, low, op1))
17656 );
17657 }
17658
17659 auto node = this->astCtxt->concat(pck);
17660
17661 /* Create symbolic expression */
17662 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPMINUB operation");
17663
17664 /* Apply the taint */
17665 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17666
17667 /* Update the symbolic control flow */
17668 this->controlFlow_s(inst);
17669 }
17670
17671
17672 void x86Semantics::vpmulhw_s(triton::arch::Instruction& inst) {
17673 auto& dst = inst.operands[0];
17674 auto& src1 = inst.operands[1];
17675 auto& src2 = inst.operands[2];
17676
17677 /* Create symbolic operands */
17678 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17679 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17680
17681 /* Create the semantics */
17682 std::vector<triton::ast::SharedAbstractNode> pck;
17683 pck.reserve(dst.getSize() / triton::size::word);
17684
17685 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; ++i) {
17686 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
17688 auto n1 = this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op1));
17689 auto n2 = this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op2));
17690 auto node = this->astCtxt->extract(triton::bitsize::dword - 1, triton::bitsize::word, this->astCtxt->bvmul(n1, n2));
17691 pck.push_back(node);
17692 }
17693 auto node = this->astCtxt->concat(pck);
17694
17695 /* Create symbolic expression */
17696 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPMULHW operation");
17697
17698 /* Apply the taint */
17699 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17700
17701 /* Update the symbolic control flow */
17702 this->controlFlow_s(inst);
17703 }
17704
17705
17706 void x86Semantics::vpmullw_s(triton::arch::Instruction& inst) {
17707 auto& dst = inst.operands[0];
17708 auto& src1 = inst.operands[1];
17709 auto& src2 = inst.operands[2];
17710
17711 /* Create symbolic operands */
17712 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17713 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17714
17715 /* Create the semantics */
17716 std::vector<triton::ast::SharedAbstractNode> pck;
17717 pck.reserve(dst.getSize() / triton::size::word);
17718
17719 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; ++i) {
17720 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
17722 auto n1 = this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op1));
17723 auto n2 = this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(high, low, op2));
17724 auto node = this->astCtxt->extract(triton::bitsize::word - 1, 0, this->astCtxt->bvmul(n1, n2));
17725 pck.push_back(node);
17726 }
17727 auto node = this->astCtxt->concat(pck);
17728
17729 /* Create symbolic expression */
17730 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPMULLW operation");
17731
17732 /* Apply the taint */
17733 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17734
17735 /* Update the symbolic control flow */
17736 this->controlFlow_s(inst);
17737 }
17738
17739
17740 void x86Semantics::vpor_s(triton::arch::Instruction& inst) {
17741 auto& dst = inst.operands[0];
17742 auto& src1 = inst.operands[1];
17743 auto& src2 = inst.operands[2];
17744
17745 /* Create symbolic operands */
17746 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
17747 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
17748
17749 /* Create the semantics */
17750 auto node = this->astCtxt->bvor(op2, op3);
17751
17752 /* Create symbolic expression */
17753 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPOR operation");
17754
17755 /* Spread taint */
17756 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17757
17758 /* Update the symbolic control flow */
17759 this->controlFlow_s(inst);
17760 }
17761
17762
17763 void x86Semantics::vpshufd_s(triton::arch::Instruction& inst) {
17764 auto& dst = inst.operands[0];
17765 auto& src = inst.operands[1];
17766 auto& ord = inst.operands[2];
17767 triton::uint32 dstSize = dst.getBitSize();
17768
17769 /* Create symbolic operands */
17770 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
17771 auto op3 = this->symbolicEngine->getOperandAst(inst, ord);
17772
17773 /* Create the semantics */
17774 std::vector<triton::ast::SharedAbstractNode> pack;
17775 pack.reserve(8);
17776
17777 switch (dstSize) {
17778
17779 /* YMM */
17781 pack.push_back(
17782 this->astCtxt->extract(31, 0,
17783 this->astCtxt->bvlshr(
17784 op2,
17785 this->astCtxt->bvmul(
17786 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(7, 6, op3)),
17787 this->astCtxt->bv(32, dstSize)
17788 )
17789 )
17790 )
17791 );
17792 pack.push_back(
17793 this->astCtxt->extract(31, 0,
17794 this->astCtxt->bvlshr(
17795 op2,
17796 this->astCtxt->bvmul(
17797 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(5, 4, op3)),
17798 this->astCtxt->bv(32, dstSize)
17799 )
17800 )
17801 )
17802 );
17803 pack.push_back(
17804 this->astCtxt->extract(31, 0,
17805 this->astCtxt->bvlshr(
17806 op2,
17807 this->astCtxt->bvmul(
17808 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(3, 2, op3)),
17809 this->astCtxt->bv(32, dstSize)
17810 )
17811 )
17812 )
17813 );
17814 pack.push_back(
17815 this->astCtxt->extract(31, 0,
17816 this->astCtxt->bvlshr(
17817 op2,
17818 this->astCtxt->bvmul(
17819 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(1, 0, op3)),
17820 this->astCtxt->bv(32, dstSize)
17821 )
17822 )
17823 )
17824 );
17825
17826 /* XMM */
17828 pack.push_back(
17829 this->astCtxt->extract(31, 0,
17830 this->astCtxt->bvlshr(
17831 op2,
17832 this->astCtxt->bvmul(
17833 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(7, 6, op3)),
17834 this->astCtxt->bv(32, dstSize)
17835 )
17836 )
17837 )
17838 );
17839 pack.push_back(
17840 this->astCtxt->extract(31, 0,
17841 this->astCtxt->bvlshr(
17842 op2,
17843 this->astCtxt->bvmul(
17844 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(5, 4, op3)),
17845 this->astCtxt->bv(32, dstSize)
17846 )
17847 )
17848 )
17849 );
17850 pack.push_back(
17851 this->astCtxt->extract(31, 0,
17852 this->astCtxt->bvlshr(
17853 op2,
17854 this->astCtxt->bvmul(
17855 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(3, 2, op3)),
17856 this->astCtxt->bv(32, dstSize)
17857 )
17858 )
17859 )
17860 );
17861 pack.push_back(
17862 this->astCtxt->extract(31, 0,
17863 this->astCtxt->bvlshr(
17864 op2,
17865 this->astCtxt->bvmul(
17866 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(1, 0, op3)),
17867 this->astCtxt->bv(32, dstSize)
17868 )
17869 )
17870 )
17871 );
17872 break;
17873
17874 default:
17875 throw triton::exceptions::Semantics("x86Semantics::vpshufd_s(): Invalid operand size.");
17876 }
17877
17878 auto node = this->astCtxt->concat(pack);
17879
17880 /* Create symbolic expression */
17881 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSHUFD operation");
17882
17883 /* Spread taint */
17884 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
17885
17886 /* Update the symbolic control flow */
17887 this->controlFlow_s(inst);
17888 }
17889
17890
17891 void x86Semantics::vpsignw_s(triton::arch::Instruction& inst) {
17892 auto& dst = inst.operands[0];
17893 auto& src1 = inst.operands[1];
17894 auto& src2 = inst.operands[2];
17895
17896 /* Create symbolic operands */
17897 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17898 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17899
17900 /* Create the semantics */
17901 std::vector<triton::ast::SharedAbstractNode> pck;
17902 pck.reserve(dst.getSize() / triton::size::word);
17903
17904 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
17905 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
17907 auto val = this->astCtxt->extract(high, low, op2);
17908 pck.push_back(this->astCtxt->ite(
17909 this->astCtxt->bvsgt(val, this->astCtxt->bv(0, triton::bitsize::word)),
17910 this->astCtxt->extract(high, low, op1),
17911 this->astCtxt->ite(
17912 this->astCtxt->bvslt(val, this->astCtxt->bv(0, triton::bitsize::word)),
17913 this->astCtxt->bvneg(this->astCtxt->extract(high, low, op1)),
17914 this->astCtxt->bv(0, triton::bitsize::word)))
17915 );
17916 }
17917
17918 auto node = this->astCtxt->concat(pck);
17919
17920 /* Create symbolic expression */
17921 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSIGNW operation");
17922
17923 /* Spread taint */
17924 this->taintEngine->setTaint(dst, false);
17925
17926 /* Update the symbolic control flow */
17927 this->controlFlow_s(inst);
17928 }
17929
17930
17931 void x86Semantics::vpslldq_s(triton::arch::Instruction& inst) {
17932 auto& dst = inst.operands[0];
17933 auto& src1 = inst.operands[1];
17934 auto& src2 = inst.operands[2];
17935
17936 /* Create symbolic operands */
17937 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17938 auto op2 = this->astCtxt->zx(triton::bitsize::dqword - src2.getBitSize(), this->symbolicEngine->getOperandAst(inst, src2));
17939
17940 /* Create the semantics */
17942
17943 std::vector<triton::ast::SharedAbstractNode> pck;
17944 pck.reserve(dst.getSize() / triton::size::dqword);
17945
17946 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dqword; index++) {
17947 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dqword);
17949 pck.push_back(this->astCtxt->bvshl(
17950 this->astCtxt->extract(high, low, op1),
17951 this->astCtxt->bvmul(
17952 this->astCtxt->ite(
17953 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::word, triton::bitsize::dqword)),
17955 op2
17956 ),
17958 )
17959 ));
17960 }
17961
17962 node = pck.size() > 1 ? this->astCtxt->concat(pck) : pck[0];
17963
17964 /* Create symbolic expression */
17965 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSLLDQ operation");
17966
17967 /* Spread taint */
17968 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
17969
17970 /* Update the symbolic control flow */
17971 this->controlFlow_s(inst);
17972 }
17973
17974
17975 void x86Semantics::vpsllw_s(triton::arch::Instruction& inst) {
17976 auto& dst = inst.operands[0];
17977 auto& src1 = inst.operands[1];
17978 auto& src2 = inst.operands[2];
17979
17980 /* Create symbolic operands */
17981 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
17982 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
17983
17984 /* Create the semantics */
17985 std::vector<triton::ast::SharedAbstractNode> pck;
17986 pck.reserve(dst.getSize() / triton::size::word);
17987
17988 auto shift = this->astCtxt->ite(
17989 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::word, src2.getBitSize())),
17990 this->astCtxt->bv(triton::bitsize::word, src2.getBitSize()),
17991 op2
17992 );
17993
17994 if (shift->getBitvectorSize() < triton::bitsize::word) {
17995 shift = this->astCtxt->zx(triton::bitsize::word - shift->getBitvectorSize(), shift);
17996 }
17997 else {
17998 shift = this->astCtxt->extract(triton::bitsize::word - 1, 0, shift);
17999 }
18000
18001 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; ++i) {
18002 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
18004 pck.push_back(this->astCtxt->bvshl(this->astCtxt->extract(high, low, op1), shift));
18005 }
18006 auto node = this->astCtxt->concat(pck);
18007
18008 /* Create symbolic expression */
18009 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSLLW operation");
18010
18011 /* Spread taint */
18012 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18013
18014 /* Update the symbolic control flow */
18015 this->controlFlow_s(inst);
18016 }
18017
18018
18019 void x86Semantics::vpsrad_s(triton::arch::Instruction& inst) {
18020 auto& dst = inst.operands[0];
18021 auto& src1 = inst.operands[1];
18022 auto& src2 = inst.operands[2];
18023
18024 /* Create symbolic operands */
18025 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18026 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18027
18028 /* Create the semantics */
18029 std::vector<triton::ast::SharedAbstractNode> pck;
18030 pck.reserve(dst.getSize() / triton::size::dword);
18031
18032 auto shift = this->astCtxt->ite(
18033 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::dword, src2.getBitSize())),
18034 this->astCtxt->bv(triton::bitsize::dword, src2.getBitSize()),
18035 op2
18036 );
18037
18038 if (shift->getBitvectorSize() < triton::bitsize::dword) {
18039 shift = this->astCtxt->zx(triton::bitsize::dword - shift->getBitvectorSize(), shift);
18040 }
18041 else {
18042 shift = this->astCtxt->extract(triton::bitsize::dword - 1, 0, shift);
18043 }
18044
18045 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::dword; ++i) {
18046 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::dword);
18048 pck.push_back(this->astCtxt->bvashr(this->astCtxt->extract(high, low, op1), shift));
18049 }
18050 auto node = this->astCtxt->concat(pck);
18051
18052 /* Create symbolic expression */
18053 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSRAD operation");
18054
18055 /* Spread taint */
18056 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18057
18058 /* Update the symbolic control flow */
18059 this->controlFlow_s(inst);
18060 }
18061
18062
18063 void x86Semantics::vpsraw_s(triton::arch::Instruction& inst) {
18064 auto& dst = inst.operands[0];
18065 auto& src1 = inst.operands[1];
18066 auto& src2 = inst.operands[2];
18067
18068 /* Create symbolic operands */
18069 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18070 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18071
18072 /* Create the semantics */
18073 std::vector<triton::ast::SharedAbstractNode> pck;
18074 pck.reserve(dst.getSize() / triton::size::word);
18075
18076 auto shift = this->astCtxt->ite(
18077 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::word, src2.getBitSize())),
18078 this->astCtxt->bv(triton::bitsize::word, src2.getBitSize()),
18079 op2
18080 );
18081
18082 if (shift->getBitvectorSize() < triton::bitsize::word) {
18083 shift = this->astCtxt->zx(triton::bitsize::word - shift->getBitvectorSize(), shift);
18084 }
18085 else {
18086 shift = this->astCtxt->extract(triton::bitsize::word - 1, 0, shift);
18087 }
18088
18089 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; ++i) {
18090 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
18092 pck.push_back(this->astCtxt->bvashr(this->astCtxt->extract(high, low, op1), shift));
18093 }
18094 auto node = this->astCtxt->concat(pck);
18095
18096 /* Create symbolic expression */
18097 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSRAW operation");
18098
18099 /* Spread taint */
18100 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18101
18102 /* Update the symbolic control flow */
18103 this->controlFlow_s(inst);
18104 }
18105
18106
18107 void x86Semantics::vpsrldq_s(triton::arch::Instruction& inst) {
18108 auto& dst = inst.operands[0];
18109 auto& src1 = inst.operands[1];
18110 auto& src2 = inst.operands[2];
18111
18112 /* Create symbolic operands */
18113 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18114 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18115
18116 /* Create the semantics */
18117 std::vector<triton::ast::SharedAbstractNode> pck;
18118 pck.reserve(dst.getSize() / triton::size::dqword);
18119
18120 auto shift = this->astCtxt->ite(
18121 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::word, src2.getBitSize())),
18122 this->astCtxt->bv(triton::bitsize::word, src2.getBitSize()),
18123 op2
18124 );
18125
18126 if (shift->getBitvectorSize() < triton::bitsize::dqword) {
18127 shift = this->astCtxt->zx(triton::bitsize::dqword - shift->getBitvectorSize(), shift);
18128 }
18129 else {
18130 shift = this->astCtxt->extract(triton::bitsize::dqword - 1, 0, shift);
18131 }
18132 shift = this->astCtxt->bvmul(shift, this->astCtxt->bv(triton::bitsize::byte, triton::bitsize::dqword));
18133
18134 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::dqword; ++i) {
18135 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::dqword);
18137 pck.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(high, low, op1), shift));
18138 }
18139 auto node = pck.size() > 1 ? this->astCtxt->concat(pck) : pck[0];
18140
18141 /* Create symbolic expression */
18142 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSRLDQ operation");
18143
18144 /* Spread taint */
18145 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18146
18147 /* Update the symbolic control flow */
18148 this->controlFlow_s(inst);
18149 }
18150
18151
18152 void x86Semantics::vpsrlw_s(triton::arch::Instruction& inst) {
18153 auto& dst = inst.operands[0];
18154 auto& src1 = inst.operands[1];
18155 auto& src2 = inst.operands[2];
18156
18157 /* Create symbolic operands */
18158 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18159 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18160
18161 /* Create the semantics */
18162 std::vector<triton::ast::SharedAbstractNode> pck;
18163 pck.reserve(dst.getSize() / triton::size::word);
18164
18165 auto shift = this->astCtxt->ite(
18166 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::word, src2.getBitSize())),
18167 this->astCtxt->bv(triton::bitsize::word, src2.getBitSize()),
18168 op2
18169 );
18170
18171 if (shift->getBitvectorSize() < triton::bitsize::word) {
18172 shift = this->astCtxt->zx(triton::bitsize::word - shift->getBitvectorSize(), shift);
18173 }
18174 else {
18175 shift = this->astCtxt->extract(triton::bitsize::word - 1, 0, shift);
18176 }
18177
18178 for (triton::uint32 i = 0; i < dst.getSize() / triton::size::word; ++i) {
18179 uint32 high = (dst.getBitSize() - 1) - (i * triton::bitsize::word);
18181 pck.push_back(this->astCtxt->bvlshr(this->astCtxt->extract(high, low, op1), shift));
18182 }
18183 auto node = this->astCtxt->concat(pck);
18184
18185 /* Create symbolic expression */
18186 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSRLW operation");
18187
18188 /* Spread taint */
18189 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18190
18191 /* Update the symbolic control flow */
18192 this->controlFlow_s(inst);
18193 }
18194
18195
18196 void x86Semantics::vpsubb_s(triton::arch::Instruction& inst) {
18197 auto& dst = inst.operands[0];
18198 auto& src1 = inst.operands[1];
18199 auto& src2 = inst.operands[2];
18200
18201 /* Create symbolic operands */
18202 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18203 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18204
18205 /* Create the semantics */
18206 std::vector<triton::ast::SharedAbstractNode> pck;
18207 pck.reserve(dst.getSize());
18208
18209 for (triton::uint32 index = 0; index < dst.getSize(); index++) {
18210 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte);
18212 pck.push_back(this->astCtxt->bvsub(
18213 this->astCtxt->extract(high, low, op1),
18214 this->astCtxt->extract(high, low, op2))
18215 );
18216 }
18217
18218 auto node = this->astCtxt->concat(pck);
18219
18220 /* Create symbolic expression */
18221 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSUBB operation");
18222
18223 /* Apply the taint */
18224 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18225
18226 /* Update the symbolic control flow */
18227 this->controlFlow_s(inst);
18228 }
18229
18230
18231 void x86Semantics::vpsubd_s(triton::arch::Instruction& inst) {
18232 auto& dst = inst.operands[0];
18233 auto& src1 = inst.operands[1];
18234 auto& src2 = inst.operands[2];
18235
18236 /* Create symbolic operands */
18237 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18238 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18239
18240 /* Create the semantics */
18241 std::vector<triton::ast::SharedAbstractNode> pck;
18242 pck.reserve(dst.getSize() / triton::size::dword);
18243
18244 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) {
18245 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword);
18247 pck.push_back(this->astCtxt->bvsub(
18248 this->astCtxt->extract(high, low, op1),
18249 this->astCtxt->extract(high, low, op2))
18250 );
18251 }
18252
18253 auto node = this->astCtxt->concat(pck);
18254
18255 /* Create symbolic expression */
18256 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSUBD operation");
18257
18258 /* Apply the taint */
18259 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18260
18261 /* Update the symbolic control flow */
18262 this->controlFlow_s(inst);
18263 }
18264
18265
18266 void x86Semantics::vpsubq_s(triton::arch::Instruction& inst) {
18267 auto& dst = inst.operands[0];
18268 auto& src1 = inst.operands[1];
18269 auto& src2 = inst.operands[2];
18270
18271 /* Create symbolic operands */
18272 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18273 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18274
18275 /* Create the semantics */
18276 std::vector<triton::ast::SharedAbstractNode> pck;
18277 pck.reserve(dst.getSize() / triton::size::qword);
18278
18279 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::qword; index++) {
18280 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::qword);
18282 pck.push_back(this->astCtxt->bvsub(
18283 this->astCtxt->extract(high, low, op1),
18284 this->astCtxt->extract(high, low, op2))
18285 );
18286 }
18287
18288 auto node = this->astCtxt->concat(pck);
18289
18290 /* Create symbolic expression */
18291 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSUBQ operation");
18292
18293 /* Apply the taint */
18294 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18295
18296 /* Update the symbolic control flow */
18297 this->controlFlow_s(inst);
18298 }
18299
18300
18301 void x86Semantics::vpsubw_s(triton::arch::Instruction& inst) {
18302 auto& dst = inst.operands[0];
18303 auto& src1 = inst.operands[1];
18304 auto& src2 = inst.operands[2];
18305
18306 /* Create symbolic operands */
18307 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18308 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18309
18310 /* Create the semantics */
18311 std::vector<triton::ast::SharedAbstractNode> pck;
18312 pck.reserve(dst.getSize() / triton::size::word);
18313
18314 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) {
18315 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word);
18317 pck.push_back(this->astCtxt->bvsub(
18318 this->astCtxt->extract(high, low, op1),
18319 this->astCtxt->extract(high, low, op2))
18320 );
18321 }
18322
18323 auto node = this->astCtxt->concat(pck);
18324
18325 /* Create symbolic expression */
18326 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSUBW operation");
18327
18328 /* Apply the taint */
18329 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18330
18331 /* Update the symbolic control flow */
18332 this->controlFlow_s(inst);
18333 }
18334
18335
18336 void x86Semantics::vptest_s(triton::arch::Instruction& inst) {
18337 auto& src1 = inst.operands[0];
18338 auto& src2 = inst.operands[1];
18339
18340 /* Create symbolic operands */
18341 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18342 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18343
18344 /* Create the semantics */
18345 auto node1 = this->astCtxt->bvand(op1, op2);
18346 auto node2 = this->astCtxt->bvand(op1, this->astCtxt->bvnot(op2));
18347
18348 /* Create symbolic expression */
18349 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "VPTEST operation");
18350 auto expr2 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node2, "VPTEST operation");
18351
18352 /* Spread taint */
18353 expr1->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2);
18354 expr2->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2);
18355
18356 /* Update symbolic flags */
18357 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_AF), "Clears adjust flag");
18358 this->cfPtest_s(inst, expr2, src1, true);
18359 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
18360 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_PF), "Clears parity flag");
18361 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_SF), "Clears sign flag");
18362 this->zf_s(inst, expr1, src1, true);
18363
18364 /* Update the symbolic control flow */
18365 this->controlFlow_s(inst);
18366 }
18367
18368
18369 void x86Semantics::vpunpckhbw_s(triton::arch::Instruction& inst) {
18370 auto& dst = inst.operands[0];
18371 auto& src1 = inst.operands[1];
18372 auto& src2 = inst.operands[2];
18373
18374 /* Create symbolic operands */
18375 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18376 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18377
18378 /* Create the semantics */
18379 std::vector<triton::ast::SharedAbstractNode> unpack;
18380 unpack.reserve(dst.getSize());
18381
18382 uint32 start_index = dst.getBitSize();
18383 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
18384 start_index -= k * triton::bitsize::dqword;
18386 uint32 high = (start_index - 1) - (i * triton::bitsize::byte);
18387 uint32 low = (start_index - triton::bitsize::byte) - (i * triton::bitsize::byte);
18388 unpack.push_back(this->astCtxt->extract(high, low, op2));
18389 unpack.push_back(this->astCtxt->extract(high, low, op1));
18390 }
18391 }
18392
18393 auto node = this->astCtxt->concat(unpack);
18394
18395 /* Create symbolic expression */
18396 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPUNPCKHBW operation");
18397
18398 /* Apply the taint */
18399 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18400
18401 /* Update the symbolic control flow */
18402 this->controlFlow_s(inst);
18403 }
18404
18405
18406 void x86Semantics::vpunpckhdq_s(triton::arch::Instruction& inst) {
18407 auto& dst = inst.operands[0];
18408 auto& src1 = inst.operands[1];
18409 auto& src2 = inst.operands[2];
18410
18411 /* Create symbolic operands */
18412 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18413 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18414
18415 /* Create the semantics */
18416 std::vector<triton::ast::SharedAbstractNode> unpack;
18417 unpack.reserve(dst.getSize() / triton::size::dword);
18418
18419 uint32 start_index = dst.getBitSize();
18420 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
18421 start_index -= k * triton::bitsize::dqword;
18423 uint32 high = (start_index - 1) - (i * triton::bitsize::dword);
18424 uint32 low = (start_index - triton::bitsize::dword) - (i * triton::bitsize::dword);
18425 unpack.push_back(this->astCtxt->extract(high, low, op2));
18426 unpack.push_back(this->astCtxt->extract(high, low, op1));
18427 }
18428 }
18429
18430 auto node = this->astCtxt->concat(unpack);
18431
18432 /* Create symbolic expression */
18433 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPUNPCKHDQ operation");
18434
18435 /* Apply the taint */
18436 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18437
18438 /* Update the symbolic control flow */
18439 this->controlFlow_s(inst);
18440 }
18441
18442
18443 void x86Semantics::vpunpckhqdq_s(triton::arch::Instruction& inst) {
18444 auto& dst = inst.operands[0];
18445 auto& src1 = inst.operands[1];
18446 auto& src2 = inst.operands[2];
18447
18448 /* Create symbolic operands */
18449 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18450 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18451
18452 /* Create the semantics */
18453 std::vector<triton::ast::SharedAbstractNode> unpack;
18454 unpack.reserve(dst.getSize() / triton::size::qword);
18455
18456 uint32 start_index = dst.getBitSize();
18457 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
18458 start_index -= k * triton::bitsize::dqword;
18460 uint32 high = (start_index - 1) - (i * triton::bitsize::qword);
18461 uint32 low = (start_index - triton::bitsize::qword) - (i * triton::bitsize::qword);
18462 unpack.push_back(this->astCtxt->extract(high, low, op2));
18463 unpack.push_back(this->astCtxt->extract(high, low, op1));
18464 }
18465 }
18466
18467 auto node = this->astCtxt->concat(unpack);
18468
18469 /* Create symbolic expression */
18470 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPUNPCKHQDQ operation");
18471
18472 /* Apply the taint */
18473 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18474
18475 /* Update the symbolic control flow */
18476 this->controlFlow_s(inst);
18477 }
18478
18479
18480 void x86Semantics::vpunpckhwd_s(triton::arch::Instruction& inst) {
18481 auto& dst = inst.operands[0];
18482 auto& src1 = inst.operands[1];
18483 auto& src2 = inst.operands[2];
18484
18485 /* Create symbolic operands */
18486 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18487 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18488
18489 /* Create the semantics */
18490 std::vector<triton::ast::SharedAbstractNode> unpack;
18491 unpack.reserve(dst.getSize() / triton::size::word);
18492
18493 uint32 start_index = dst.getBitSize();
18494 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
18495 start_index -= k * triton::bitsize::dqword;
18497 uint32 high = (start_index - 1) - (i * triton::bitsize::word);
18498 uint32 low = (start_index - triton::bitsize::word) - (i * triton::bitsize::word);
18499 unpack.push_back(this->astCtxt->extract(high, low, op2));
18500 unpack.push_back(this->astCtxt->extract(high, low, op1));
18501 }
18502 }
18503
18504 auto node = this->astCtxt->concat(unpack);
18505
18506 /* Create symbolic expression */
18507 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPUNPCKHWD operation");
18508
18509 /* Apply the taint */
18510 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18511
18512 /* Update the symbolic control flow */
18513 this->controlFlow_s(inst);
18514 }
18515
18516
18517 void x86Semantics::vpunpcklbw_s(triton::arch::Instruction& inst) {
18518 auto& dst = inst.operands[0];
18519 auto& src1 = inst.operands[1];
18520 auto& src2 = inst.operands[2];
18521
18522 /* Create symbolic operands */
18523 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18524 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18525
18526 /* Create the semantics */
18527 std::vector<triton::ast::SharedAbstractNode> unpack;
18528 unpack.reserve(dst.getSize());
18529
18530 uint32 start_index = dst.getBitSize() - triton::bitsize::qword;
18531 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
18532 start_index -= k * triton::bitsize::dqword;
18534 uint32 high = (start_index - 1) - (i * triton::bitsize::byte);
18535 uint32 low = (start_index - triton::bitsize::byte) - (i * triton::bitsize::byte);
18536 unpack.push_back(this->astCtxt->extract(high, low, op2));
18537 unpack.push_back(this->astCtxt->extract(high, low, op1));
18538 }
18539 }
18540
18541 auto node = this->astCtxt->concat(unpack);
18542
18543 /* Create symbolic expression */
18544 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPUNPCKLBW operation");
18545
18546 /* Apply the taint */
18547 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18548
18549 /* Update the symbolic control flow */
18550 this->controlFlow_s(inst);
18551 }
18552
18553
18554 void x86Semantics::vpunpckldq_s(triton::arch::Instruction& inst) {
18555 auto& dst = inst.operands[0];
18556 auto& src1 = inst.operands[1];
18557 auto& src2 = inst.operands[2];
18558
18559 /* Create symbolic operands */
18560 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18561 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18562
18563 /* Create the semantics */
18564 std::vector<triton::ast::SharedAbstractNode> unpack;
18565 unpack.reserve(dst.getSize() / triton::size::dword);
18566
18567 uint32 start_index = dst.getBitSize() - triton::bitsize::qword;
18568 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
18569 start_index -= k * triton::bitsize::dqword;
18571 uint32 high = (start_index - 1) - (i * triton::bitsize::dword);
18572 uint32 low = (start_index - triton::bitsize::dword) - (i * triton::bitsize::dword);
18573 unpack.push_back(this->astCtxt->extract(high, low, op2));
18574 unpack.push_back(this->astCtxt->extract(high, low, op1));
18575 }
18576 }
18577
18578 auto node = this->astCtxt->concat(unpack);
18579
18580 /* Create symbolic expression */
18581 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPUNPCKLDQ operation");
18582
18583 /* Apply the taint */
18584 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18585
18586 /* Update the symbolic control flow */
18587 this->controlFlow_s(inst);
18588 }
18589
18590
18591 void x86Semantics::vpunpcklqdq_s(triton::arch::Instruction& inst) {
18592 auto& dst = inst.operands[0];
18593 auto& src1 = inst.operands[1];
18594 auto& src2 = inst.operands[2];
18595
18596 /* Create symbolic operands */
18597 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18598 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18599
18600 /* Create the semantics */
18601 std::vector<triton::ast::SharedAbstractNode> unpack;
18602 unpack.reserve(dst.getSize() / triton::size::qword);
18603
18604 uint32 start_index = dst.getBitSize() - triton::bitsize::qword;
18605 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
18606 start_index -= k * triton::bitsize::dqword;
18608 uint32 high = (start_index - 1) - (i * triton::bitsize::qword);
18609 uint32 low = (start_index - triton::bitsize::qword) - (i * triton::bitsize::qword);
18610 unpack.push_back(this->astCtxt->extract(high, low, op2));
18611 unpack.push_back(this->astCtxt->extract(high, low, op1));
18612 }
18613 }
18614
18615 auto node = this->astCtxt->concat(unpack);
18616
18617 /* Create symbolic expression */
18618 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPUNPCKLQDQ operation");
18619
18620 /* Apply the taint */
18621 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18622
18623 /* Update the symbolic control flow */
18624 this->controlFlow_s(inst);
18625 }
18626
18627
18628 void x86Semantics::vpunpcklwd_s(triton::arch::Instruction& inst) {
18629 auto& dst = inst.operands[0];
18630 auto& src1 = inst.operands[1];
18631 auto& src2 = inst.operands[2];
18632
18633 /* Create symbolic operands */
18634 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18635 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18636
18637 /* Create the semantics */
18638 std::vector<triton::ast::SharedAbstractNode> unpack;
18639 unpack.reserve(dst.getSize() / triton::size::word);
18640
18641 uint32 start_index = dst.getBitSize() - triton::bitsize::qword;
18642 for (triton::uint32 k = 0; k < dst.getSize() / triton::size::dqword; ++k) {
18643 start_index -= k * triton::bitsize::dqword;
18645 uint32 high = (start_index - 1) - (i * triton::bitsize::word);
18646 uint32 low = (start_index - triton::bitsize::word) - (i * triton::bitsize::word);
18647 unpack.push_back(this->astCtxt->extract(high, low, op2));
18648 unpack.push_back(this->astCtxt->extract(high, low, op1));
18649 }
18650 }
18651
18652 auto node = this->astCtxt->concat(unpack);
18653
18654 /* Create symbolic expression */
18655 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPUNPCKLWD operation");
18656
18657 /* Apply the taint */
18658 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18659
18660 /* Update the symbolic control flow */
18661 this->controlFlow_s(inst);
18662 }
18663
18664
18665 void x86Semantics::vpxor_s(triton::arch::Instruction& inst) {
18666 auto& dst = inst.operands[0];
18667 auto& src1 = inst.operands[1];
18668 auto& src2 = inst.operands[2];
18669
18670 /* Create symbolic operands */
18671 auto op2 = this->symbolicEngine->getOperandAst(inst, src1);
18672 auto op3 = this->symbolicEngine->getOperandAst(inst, src2);
18673
18674 /* Create the semantics */
18675 auto node = this->astCtxt->bvxor(op2, op3);
18676
18677 /* Create symbolic expression */
18678 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPXOR operation");
18679
18680 /* Spread taint */
18681 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18682
18683 /* Update the symbolic control flow */
18684 this->controlFlow_s(inst);
18685 }
18686
18687
18688 void x86Semantics::vxorps_s(triton::arch::Instruction& inst) {
18689 auto& dst = inst.operands[0];
18690 auto& src1 = inst.operands[1];
18691 auto& src2 = inst.operands[2];
18692
18693 /* Create symbolic operands */
18694 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
18695 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
18696
18697 /* Create the semantics */
18698 auto node = this->astCtxt->bvxor(op1, op2);
18699
18700 /* Create symbolic expression */
18701 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VXORPS operation");
18702
18703 /* Apply the taint */
18704 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2);
18705
18706 /* Update the symbolic control flow */
18707 this->controlFlow_s(inst);
18708 }
18709
18710
18711 void x86Semantics::wait_s(triton::arch::Instruction& inst) {
18712 /* Update the symbolic control flow */
18713 this->controlFlow_s(inst);
18714 }
18715
18716
18717 void x86Semantics::wbinvd_s(triton::arch::Instruction& inst) {
18718 /* Update the symbolic control flow */
18719 this->controlFlow_s(inst);
18720 }
18721
18722
18723 void x86Semantics::xadd_s(triton::arch::Instruction& inst) {
18724 auto& dst = inst.operands[0];
18725 auto& src = inst.operands[1];
18726 bool dstT = this->taintEngine->isTainted(dst);
18727
18728 /* Create symbolic operands */
18729 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
18730 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
18731
18732 /* Create the semantics */
18733 auto node = this->astCtxt->bvadd(op1, op2);
18734
18735 /* Create symbolic expression */
18736 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, op1, src, "XADD operation");
18737 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "XADD operation");
18738
18739 /* Spread taint */
18740 expr2->isTainted = this->taintEngine->taintUnion(dst, src);
18741 expr1->isTainted = this->taintEngine->setTaint(src, dstT);
18742
18743 /* Update symbolic flags */
18744 this->af_s(inst, expr2, dst, op1, op2);
18745 this->cfAdd_s(inst, expr2, dst, op1, op2);
18746 this->ofAdd_s(inst, expr2, dst, op1, op2);
18747 this->pf_s(inst, expr2, dst);
18748 this->sf_s(inst, expr2, dst);
18749 this->zf_s(inst, expr2, dst);
18750
18751 /* Update the symbolic control flow */
18752 this->controlFlow_s(inst);
18753 }
18754
18755
18756 void x86Semantics::xchg_s(triton::arch::Instruction& inst) {
18757 auto& dst = inst.operands[0];
18758 auto& src = inst.operands[1];
18759 bool dstT = this->taintEngine->isTainted(dst);
18760 bool srcT = this->taintEngine->isTainted(src);
18761
18762 /* Create symbolic operands */
18763 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
18764 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
18765
18766 /* Create the semantics */
18767 auto node1 = op2;
18768 auto node2 = op1;
18769
18770 /* Create symbolic expression */
18771 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "XCHG operation");
18772 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, src, "XCHG operation");
18773
18774 /* Spread taint */
18775 expr1->isTainted = this->taintEngine->setTaint(dst, srcT);
18776 expr2->isTainted = this->taintEngine->setTaint(src, dstT);
18777
18778 /* Update the symbolic control flow */
18779 this->controlFlow_s(inst);
18780 }
18781
18782
18783 void x86Semantics::xor_s(triton::arch::Instruction& inst) {
18784 auto& dst = inst.operands[0];
18785 auto& src = inst.operands[1];
18786
18787 /* Create symbolic operands */
18788 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
18789 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
18790
18791 /* Create the semantics */
18792 auto node = this->astCtxt->bvxor(op1, op2);
18793
18794 /* Create symbolic expression */
18795 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "XOR operation");
18796
18797 /* Spread taint */
18798 /* clear taint if the registers are the same */
18799 if (dst.getType() == OP_REG && src.getRegister() == dst.getRegister())
18800 this->taintEngine->setTaint(src, false);
18801 else
18802 expr->isTainted = this->taintEngine->taintUnion(dst, src);
18803
18804 /* Update symbolic flags */
18805 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF));
18806 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag");
18807 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag");
18808 this->pf_s(inst, expr, dst);
18809 this->sf_s(inst, expr, dst);
18810 this->zf_s(inst, expr, dst);
18811
18812 /* Update the symbolic control flow */
18813 this->controlFlow_s(inst);
18814 }
18815
18816
18817 void x86Semantics::xorpd_s(triton::arch::Instruction& inst) {
18818 auto& dst = inst.operands[0];
18819 auto& src = inst.operands[1];
18820
18821 /* Create symbolic operands */
18822 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
18823 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
18824
18825 /* Create the semantics */
18826 auto node = this->astCtxt->bvxor(op1, op2);
18827
18828 /* Create symbolic expression */
18829 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "XORPD operation");
18830
18831 /* Spread taint */
18832 expr->isTainted = this->taintEngine->taintUnion(dst, src);
18833
18834 /* Update the symbolic control flow */
18835 this->controlFlow_s(inst);
18836 }
18837
18838
18839 void x86Semantics::xorps_s(triton::arch::Instruction& inst) {
18840 auto& dst = inst.operands[0];
18841 auto& src = inst.operands[1];
18842
18843 /* Create symbolic operands */
18844 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
18845 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
18846
18847 /* Create the semantics */
18848 auto node = this->astCtxt->bvxor(op1, op2);
18849
18850 /* Create symbolic expression */
18851 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "XORPS operation");
18852
18853 /* Spread taint */
18854 expr->isTainted = this->taintEngine->taintUnion(dst, src);
18855
18856 /* Update the symbolic control flow */
18857 this->controlFlow_s(inst);
18858 }
18859
18860 }; /* x86 namespace */
18861 }; /* arch namespace */
18862}; /* 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.
math::wide_integer::uint128_t uint128
unsigned 128-bits
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.