1 //! \file 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> 9 #include <triton/exceptions.hpp> 10 #include <triton/x86Semantics.hpp> 11 #include <triton/x86Specifications.hpp> 12 #include <triton/astContext.hpp> 13 14 15 16 /*! \page SMT_Semantics_Supported_page SMT Semantics Supported 17 \brief [**internal**] All information about the supported semantics. 18 19 - \ref SMT_aarch64_Semantics_Supported_page 20 - \ref SMT_arm32_Semantics_Supported_page 21 - \ref SMT_x86_Semantics_Supported_page 22 23 */ 24 25 26 /*! \page SMT_x86_Semantics_Supported_page x86 and x86-64 SMT semantics supported 27 \brief [**internal**] List of the supported semantics for the x86 and x86-64 architectures. 28 29 30 Mnemonic | Extensions | Description 31 -----------------------------|------------|------------ 32 AAA | | ASCII Adjust After Addition 33 AAD | | ASCII Adjust AX Before Division 34 AAM | | ASCII Adjust AX After Multiply 35 AAS | | ASCII Adjust AL After Subtraction 36 ADC | | Add with Carry 37 ADCX | adx | Unsigned Integer Addition of Two Operands with Carry Flag 38 ADD | | Add 39 AND | | Logical AND 40 ANDN | bmi1 | Logical AND NOT 41 ANDNPD | sse2 | Bitwise Logical AND NOT of Packed Double-Precision Floating-Point Values 42 ANDNPS | sse1 | Bitwise Logical AND NOT of Packed Single-Precision Floating-Point Values 43 ANDPD | sse2 | Bitwise Logical AND of Packed Double-Precision Floating-Point Values 44 ANDPS | sse1 | Bitwise Logical AND of Packed Single-Precision Floating-Point Values 45 BEXTR | bmi1/tbm | Bit Field Extract 46 BLSI | bmi1 | Extract Lowest Set Isolated Bit 47 BLSMSK | bmi1 | Get Mask Up to Lowest Set Bit 48 BLSR | bmi1 | Reset Lowest Set Bit 49 BSF | | Bit Scan Forward 50 BSR | | Bit Scan Reverse 51 BSWAP | | Byte Swap 52 BT | | Bit Test 53 BTC | | Bit Test and Complement 54 BTR | | Bit Test and Reset 55 BTS | | Bit Test and Set 56 CALL | | Call Procedure 57 CBW | | Convert byte (al) to word (ax) 58 CDQ | | Convert dword (eax) to qword (edx:eax) 59 CDQE | | Convert dword (eax) to qword (rax) 60 CLC | | Clear Carry Flag 61 CLD | | Clear Direction Flag 62 CLFLUSH | sse2 | Flush Cache Line 63 CLI | | Clear Interrupt Flag 64 CLTS | | Clear Task-Switched Flag in CR0 65 CMC | | Complement Carry Flag 66 CMOVA | | Move if not below 67 CMOVAE | | Move if not below or equal 68 CMOVB | | Move if below 69 CMOVBE | | Move if below or equal 70 CMOVE | | Move if zero 71 CMOVG | | Move if not less 72 CMOVGE | | Move if not less or equal 73 CMOVL | | Move if less 74 CMOVLE | | Move if less or equal 75 CMOVNE | | Move if not zero 76 CMOVNO | | Move if not overflow 77 CMOVNP | | Move if not parity 78 CMOVNS | | Move if not sign 79 CMOVO | | Move if overflow 80 CMOVP | | Move if parity 81 CMOVS | | Move if sign 82 CMP | | Compare Two Operands 83 CMPSB | | Compare byte at address 84 CMPSD | | Compare doubleword at address 85 CMPSQ | | Compare quadword at address 86 CMPSW | | Compare word at address 87 CMPXCHG | | Compare and Exchange 88 CMPXCHG16B | | Compare and Exchange 16 Bytes 89 CMPXCHG8B | | Compare and Exchange 8 Bytes 90 CPUID | | CPU Identification 91 CQO | | Convert qword (rax) to oword (rdx:rax) 92 CWD | | Convert word (ax) to dword (dx:ax) 93 CWDE | | Convert word (ax) to dword (eax) 94 DEC | | Decrement by 1 95 DIV | | Unsigned Divide 96 ENDBR32 | | No Operation 97 ENDBR64 | | No Operation 98 EXTRACTPS | sse4.1 | Extract Packed Single Precision Floating-Point Value 99 IDIV | | Signed Divide 100 IMUL | | Signed Multiply 101 INC | | Increment by 1 102 INVD | | Invalidate Internal Caches 103 INVLPG | | Invalidate TLB Entry 104 JA | | Jump if not below (Jump if above) 105 JAE | | Jump if not below or equal (Jump if above or equal) 106 JB | | Jump if below 107 JBE | | Jump if below or equal 108 JCXZ | | Jump if cx is zero 109 JE | | Jump if zero (Jump if equal) 110 JECXZ | | Jump if ecx is zero 111 JG | | Jump if not less or equal (Jump if greater) 112 JGE | | Jump if not less (Jump if not less) 113 JL | | Jump if less 114 JLE | | Jump if less or equal 115 JMP | | Jump 116 JNE | | Jump if not equal 117 JNO | | Jump if not overflow 118 JNP | | Jump if not parity 119 JNS | | Jump if not sign 120 JO | | Jump if overflow 121 JP | | Jump if parity 122 JRCXZ | | Jump if rcx is zero 123 JS | | Jump if sign 124 LAHF | | Load Status Flags into AH Register 125 LDDQU | sse3 | Load Unaligned Integer 128 Bits 126 LDMXCSR | sse1 | Load MXCSR Register 127 LEA | | Load Effective Address 128 LEAVE | | High Level Procedure Exit 129 LFENCE | sse2 | Load Fence 130 LODSB | | Load byte at address 131 LODSD | | Load doubleword at address 132 LODSQ | | Load quadword at address 133 LODSW | | Load word at address 134 LOOP | | Loop According to ECX Counter 135 LZCNT | | Count the Number of Leading Zero Bits 136 MFENCE | sse2 | Memory Fence 137 MOV | | Move 138 MOVABS | | Move 139 MOVAPD | sse2 | Move Aligned Packed Double-Precision Floating-Point Values 140 MOVAPS | sse1 | Move Aligned Packed Single-Precision Floating-Point Values 141 MOVD | mmx/sse2 | Move Doubleword 142 MOVDDUP | sse3 | Move One Double-FP and Duplicate 143 MOVDQ2Q | sse2 | Move Quadword from XMM to MMX Technology Register 144 MOVDQA | sse2 | Move Aligned Double Quadword 145 MOVDQU | sse2 | Move Unaligned Double Quadword 146 MOVHLPS | sse1 | Move Packed Single-Precision Floating-Point Values High to Low 147 MOVHPD | sse2 | Move High Packed Double-Precision Floating-Point Values 148 MOVHPS | sse1 | Move High Packed Single-Precision Floating-Point Values 149 MOVLHPS | sse1 | Move Packed Single-Precision Floating-Point Values Low to High 150 MOVLPD | sse2 | Move Low Packed Double-Precision Floating-Point Values 151 MOVLPS | sse1 | Move Low Packed Single-Precision Floating-Point Values 152 MOVMSKPD | sse2 | Extract Packed Double-Precision Floating-Point Sign Mask 153 MOVMSKPS | sse1 | Extract Packed Single-Precision Floating-Point Sign Mask 154 MOVNTDQ | sse2 | Store Double Quadword Using Non-Temporal Hint 155 MOVNTI | sse2 | Store Doubleword Using Non-Temporal Hint 156 MOVNTPD | sse2 | Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint 157 MOVNTPS | sse1 | Store Packed Single-Precision Floating-Point Values Using Non-Temporal Hint 158 MOVNTQ | sse1 | Store of Quadword Using Non-Temporal Hint 159 MOVQ | mmx/sse2 | Move Quadword 160 MOVQ2DQ | sse2 | Move Quadword from MMX Technology to XMM Register 161 MOVSB | | Move byte at address 162 MOVSD | | Move doubleword at address 163 MOVSHDUP | sse3 | Move Packed Single-FP High and Duplicate 164 MOVSLDUP | sse3 | Move Packed Single-FP Low and Duplicate 165 MOVSQ | | Move quadword at address 166 MOVSW | | Move word at address 167 MOVSX | | Move with Sign-Extension 168 MOVSXD | | Move with Sign-Extension 169 MOVUPD | see2 | Move Unaligned Packed Double-Precision Floating- Point Values 170 MOVUPS | see1 | Move Unaligned Packed Single-Precision Floating- Point Values 171 MOVZX | | Move with Zero-Extend 172 MUL | | Unsigned Multiply 173 MULX | bmi2 | Unsigned Multiply Without Affecting Flags 174 NEG | | Two's Complement Negation 175 NOP | | No Operation 176 NOT | | One's Complement Negation 177 OR | | Logical Inclusive OR 178 ORPD | sse2 | Bitwise Logical OR of Double-Precision Floating-Point Values 179 ORPS | sse1 | Bitwise Logical OR of Single-Precision Floating-Point Values 180 PADDB | mmx/sse2 | Add packed byte integers 181 PADDD | mmx/sse2 | Add packed doubleword integers 182 PADDQ | mmx/sse2 | Add packed quadword integers 183 PADDW | mmx/sse2 | Add packed word integers 184 PAND | mmx/sse2 | Logical AND 185 PANDN | mmx/sse2 | Logical AND NOT 186 PAUSE | sse2 | Spin Loop Hint 187 PAVGB | sse1 | Average Packed Unsigned Byte Integers 188 PAVGW | sse1 | Average Packed Unsigned Word Integers 189 PCMPEQB | mmx/sse2 | Compare Packed Data for Equal (bytes) 190 PCMPEQD | mmx/sse2 | Compare Packed Data for Equal (dwords) 191 PCMPEQW | mmx/sse2 | Compare Packed Data for Equal (words) 192 PCMPGTB | mmx/sse2 | Compare Packed Data for Greater Than (bytes) 193 PCMPGTD | mmx/sse2 | Compare Packed Data for Greater Than (dwords) 194 PCMPGTW | mmx/sse2 | Compare Packed Data for Greater Than (words) 195 PEXTRB | sse4.1 | Extract Byte 196 PEXTRD | sse4.1 | Extract Dword 197 PEXTRQ | sse4.1 | Extract Qword 198 PEXTRW | sse4.1 | Extract Word 199 PINSRB | sse4.1 | Insert Byte 200 PINSRD | sse4.1 | Insert Dword 201 PINSRQ | sse4.1 | Insert Qword 202 PINSRW | sse2 | Insert Word 203 PMAXSB | sse4.1 | Maximum of Packed Signed Byte Integers 204 PMAXSD | sse4.1 | Maximum of Packed Signed Doubleword Integers 205 PMAXSW | sse1 | Maximum of Packed Signed Word Integers 206 PMAXUB | sse1 | Maximum of Packed Unsigned Byte Integers 207 PMAXUD | sse4.1 | Maximum of Packed Unsigned Doubleword Integers 208 PMAXUW | sse4.1 | Maximum of Packed Unsigned Word Integers 209 PMINSB | sse4.1 | Minimum of Packed Signed Byte Integers 210 PMINSD | sse4.1 | Minimum of Packed Signed Doubleword Integers 211 PMINSW | sse1 | Minimum of Packed Signed Word Integers 212 PMINUB | sse1 | Minimum of Packed Unsigned Byte Integers 213 PMINUD | sse4.1 | Minimum of Packed Unsigned Doubleword Integers 214 PMINUW | sse4.1 | Minimum of Packed Unsigned Word Integers 215 PMOVMSKB | sse1 | Move Byte Mask 216 PMOVSXBD | sse4.1 | Sign Extend 4 Packed Signed 8-bit Integers 217 PMOVSXBQ | sse4.1 | Sign Extend 2 Packed Signed 8-bit Integers 218 PMOVSXBW | sse4.1 | Sign Extend 8 Packed Signed 8-bit Integers 219 PMOVSXDQ | sse4.1 | Sign Extend 2 Packed Signed 32-bit Integers 220 PMOVSXWD | sse4.1 | Sign Extend 4 Packed Signed 16-bit Integers 221 PMOVSXWQ | sse4.1 | Sign Extend 2 Packed Signed 16-bit Integers 222 PMOVZXBD | sse4.1 | Zero Extend 4 Packed Signed 8-bit Integers 223 PMOVZXBQ | sse4.1 | Zero Extend 2 Packed Signed 8-bit Integers 224 PMOVZXBW | sse4.1 | Zero Extend 8 Packed Signed 8-bit Integers 225 PMOVZXDQ | sse4.1 | Zero Extend 2 Packed Signed 32-bit Integers 226 PMOVZXWD | sse4.1 | Zero Extend 4 Packed Signed 16-bit Integers 227 PMOVZXWQ | sse4.1 | Zero Extend 2 Packed Signed 16-bit Integers 228 POP | | Pop a Value from the Stack 229 POPAL/POPAD | | Pop All General-Purpose Registers 230 POPF | | Pop Stack into lower 16-bit of EFLAGS Register 231 POPFD | | Pop Stack into EFLAGS Register 232 POPFQ | | Pop Stack into RFLAGS Register 233 POR | mmx/sse2 | Bitwise Logical OR 234 PREFETCH | 3DNow | Move data from m8 closer to the processor without expecting to write back 235 PREFETCHNTA | mmx/sse1 | Move data from m8 closer to the processor using NTA hint 236 PREFETCHT0 | mmx/sse1 | Move data from m8 closer to the processor using T0 hint 237 PREFETCHT1 | mmx/sse1 | Move data from m8 closer to the processor using T1 hint 238 PREFETCHT2 | mmx/sse1 | Move data from m8 closer to the processor using T2 hint 239 PREFETCHW | 3DNow | Move data from m8 closer to the processor in anticipation of a write 240 PSHUFD | sse2 | Shuffle Packed Doublewords 241 PSHUFHW | sse2 | Shuffle Packed High Words 242 PSHUFLW | sse2 | Shuffle Packed Low Words 243 PSHUFW | sse1 | Shuffle Packed Words 244 PSLLD | mmx/ssed2 | Shift Doubleword Left Logical 245 PSLLDQ | sse2 | Shift Double Quadword Left Logical 246 PSLLQ | mmx/ssed2 | Shift Quadword Left Logical 247 PSLLW | mmx/ssed2 | Shift Word Left Logical 248 PSRLDQ | sse2 | Shift Double Quadword Right Logical 249 PSUBB | mmx/sse2 | Subtract packed byte integers 250 PSUBD | mmx/sse2 | Subtract packed doubleword integers 251 PSUBQ | mmx/sse2 | Subtract packed quadword integers 252 PSUBW | mmx/sse2 | Subtract packed word integers 253 PTEST | sse4.1 | Logical Compare 254 PUNPCKHBW | mmx,sse2 | Unpack High Data (Unpack and interleave high-order bytes) 255 PUNPCKHDQ | mmx,sse2 | Unpack High Data (Unpack and interleave high-order doublewords) 256 PUNPCKHQDQ | sse2 | Unpack High Data (Unpack and interleave high-order quadwords) 257 PUNPCKHWD | mmx,sse2 | Unpack High Data (Unpack and interleave high-order words) 258 PUNPCKLBW | mmx,sse2 | Unpack Low Data (Unpack and interleave low-order bytes) 259 PUNPCKLDQ | mmx,sse2 | Unpack Low Data (Unpack and interleave low-order doublewords) 260 PUNPCKLQDQ | sse2 | Unpack Low Data (Unpack and interleave low-order quadwords) 261 PUNPCKLWD | mmx,sse2 | Unpack Low Data (Unpack and interleave low-order words) 262 PUSH | | Push a Value onto the Stack 263 PUSHAL/PUSHAD | | Push All General-Purpose Registers 264 PUSHFD | | Push EFLAGS Register onto the Stack 265 PUSHFQ | | Push RFLAGS Register onto the Stack 266 PXOR | mmx/sse2 | Logical Exclusive OR 267 RCL | | Rotate Left with Carry 268 RCR | | Rotate Right with Carry 269 RDTSC | | Read Time-Stamp Counter 270 RET | | Return from Procedure 271 ROL | | Rotate Left 272 ROR | | Rotate Right 273 RORX | bmi2 | Rotate Right Logical Without Affecting Flags 274 SAHF | | Store AH into Flags 275 SAL | | Shift Left 276 SAR | | Shift Right Signed 277 SARX | bmi2 | Shift arithmetic right without affecting flags 278 SBB | | Integer Subtraction with Borrow 279 SCASB | | Scan byte at address 280 SCASD | | Scan doubleword at address 281 SCASQ | | Scan quadword at address 282 SCASW | | Scan word at address 283 SETA | | Set byte if above 284 SETAE | | Set byte if above or equal 285 SETB | | Set byte if below 286 SETBE | | Set byte if below or equal 287 SETE | | Set byte if zero 288 SETG | | Set byte if greater 289 SETGE | | Set byte if greater or equal 290 SETL | | Set byte if less 291 SETLE | | Set byte if less or equal 292 SETNE | | Set byte if not zero 293 SETNO | | Set byte if not overflow 294 SETNP | | Set byte if not parity 295 SETNS | | Set byte if not sign 296 SETO | | Set byte if overflow 297 SETP | | Set byte if parity 298 SETS | | Set byte if sign 299 SFENCE | sse1 | Store Fence 300 SHL | | Shift Left 301 SHLD | | Double-precision Shift Left 302 SHLX | bmi2 | Shift Logical Left Without Affecting Flags 303 SHR | | Shift Right Unsigned 304 SHRD | | Double Precision Shift Right 305 SHRX | bmi2 | Shift Logical Right Without Affecting Flags 306 STC | | Set Carry Flag 307 STD | | Set Direction Flag 308 STI | | Set Interrupt Flag 309 STMXCSR | sse1 | Store MXCSR Register State 310 STOSB | | Store byte at address 311 STOSD | | Store doubleword at address 312 STOSQ | | Store quadword at address 313 STOSW | | Store word at address 314 SUB | | Subtract 315 SYSCALL | | Fast System Call 316 SYSENTER | | Fast System Call 317 TEST | | Logical Compare 318 TZCNT | bmi1 | Count the Number of Trailing Zero Bits 319 UNPCKHPD | sse2 | Unpack and Interleave High Packed Double- Precision Floating-Point Values 320 UNPCKHPS | sse1 | Unpack and Interleave High Packed Single-Precision Floating-Point Values 321 UNPCKLPD | sse2 | Unpack and Interleave Low Packed Double-Precision Floating-Point Values 322 UNPCKLPS | sse1 | Unpack and Interleave Low Packed Single-Precision Floating-Point Values 323 VMOVDQA | avx | VEX Move aligned packed integer values 324 VMOVDQU | avx | VEX Move unaligned packed integer values 325 VPAND | avx/avx2 | VEX Logical AND 326 VPANDN | avx/avx2 | VEX Logical AND NOT 327 VPEXTRB | avx/avx2 | VEX Extract Byte 328 VPEXTRD | avx/avx2 | VEX Extract Dword 329 VPEXTRQ | avx/avx2 | VEX Extract Qword 330 VPEXTRW | avx/avx2 | VEX Extract Word 331 VPMOVMSKB | avx/avx2 | VEX Move Byte Mask 332 VPOR | avx/avx2 | VEX Logical OR 333 VPSHUFD | avx/avx2 | VEX Shuffle Packed Doublewords 334 VPTEST | avx | VEX Logical Compare 335 VPXOR | avx/avx2 | VEX Logical XOR 336 WAIT | | Wait 337 WBINVD | | Write Back and Invalidate Cache 338 XADD | | Exchange and Add 339 XCHG | | Exchange Register/Memory with Register 340 XOR | | Logical Exclusive OR 341 XORPD | sse2 | Bitwise Logical XOR for Double-Precision Floating-Point Values 342 XORPS | sse1 | Bitwise Logical XOR for Single-Precision Floating-Point Values 343 344 */ 345 346 347 348 namespace triton { 349 namespace arch { 350 namespace x86 { 351 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)352 x86Semantics::x86Semantics(triton::arch::Architecture* architecture, 353 triton::engines::symbolic::SymbolicEngine* symbolicEngine, 354 triton::engines::taint::TaintEngine* taintEngine, 355 const triton::modes::SharedModes& modes, 356 const triton::ast::SharedAstContext& astCtxt) : modes(modes), astCtxt(astCtxt) { 357 358 this->architecture = architecture; 359 this->symbolicEngine = symbolicEngine; 360 this->taintEngine = taintEngine; 361 362 if (architecture == nullptr) 363 throw triton::exceptions::Semantics("x86Semantics::x86Semantics(): The architecture API must be defined."); 364 365 if (this->symbolicEngine == nullptr) 366 throw triton::exceptions::Semantics("x86Semantics::x86Semantics(): The symbolic engine API must be defined."); 367 368 if (this->taintEngine == nullptr) 369 throw triton::exceptions::Semantics("x86Semantics::x86Semantics(): The taint engines API must be defined."); 370 } 371 372 buildSemantics(triton::arch::Instruction & inst)373 bool x86Semantics::buildSemantics(triton::arch::Instruction& inst) { 374 switch (inst.getType()) { 375 case ID_INS_AAA: this->aaa_s(inst); break; 376 case ID_INS_AAD: this->aad_s(inst); break; 377 case ID_INS_AAM: this->aam_s(inst); break; 378 case ID_INS_AAS: this->aas_s(inst); break; 379 case ID_INS_ADC: this->adc_s(inst); break; 380 case ID_INS_ADCX: this->adcx_s(inst); break; 381 case ID_INS_ADD: this->add_s(inst); break; 382 case ID_INS_AND: this->and_s(inst); break; 383 case ID_INS_ANDN: this->andn_s(inst); break; 384 case ID_INS_ANDNPD: this->andnpd_s(inst); break; 385 case ID_INS_ANDNPS: this->andnps_s(inst); break; 386 case ID_INS_ANDPD: this->andpd_s(inst); break; 387 case ID_INS_ANDPS: this->andps_s(inst); break; 388 case ID_INS_BEXTR: this->bextr_s(inst); break; 389 case ID_INS_BLSI: this->blsi_s(inst); break; 390 case ID_INS_BLSMSK: this->blsmsk_s(inst); break; 391 case ID_INS_BLSR: this->blsr_s(inst); break; 392 case ID_INS_BSF: this->bsf_s(inst); break; 393 case ID_INS_BSR: this->bsr_s(inst); break; 394 case ID_INS_BSWAP: this->bswap_s(inst); break; 395 case ID_INS_BT: this->bt_s(inst); break; 396 case ID_INS_BTC: this->btc_s(inst); break; 397 case ID_INS_BTR: this->btr_s(inst); break; 398 case ID_INS_BTS: this->bts_s(inst); break; 399 case ID_INS_CALL: this->call_s(inst); break; 400 case ID_INS_CBW: this->cbw_s(inst); break; 401 case ID_INS_CDQ: this->cdq_s(inst); break; 402 case ID_INS_CDQE: this->cdqe_s(inst); break; 403 case ID_INS_CLC: this->clc_s(inst); break; 404 case ID_INS_CLD: this->cld_s(inst); break; 405 case ID_INS_CLFLUSH: this->clflush_s(inst); break; 406 case ID_INS_CLTS: this->clts_s(inst); break; 407 case ID_INS_CLI: this->cli_s(inst); break; 408 case ID_INS_CMC: this->cmc_s(inst); break; 409 case ID_INS_CMOVA: this->cmova_s(inst); break; 410 case ID_INS_CMOVAE: this->cmovae_s(inst); break; 411 case ID_INS_CMOVB: this->cmovb_s(inst); break; 412 case ID_INS_CMOVBE: this->cmovbe_s(inst); break; 413 case ID_INS_CMOVE: this->cmove_s(inst); break; 414 case ID_INS_CMOVG: this->cmovg_s(inst); break; 415 case ID_INS_CMOVGE: this->cmovge_s(inst); break; 416 case ID_INS_CMOVL: this->cmovl_s(inst); break; 417 case ID_INS_CMOVLE: this->cmovle_s(inst); break; 418 case ID_INS_CMOVNE: this->cmovne_s(inst); break; 419 case ID_INS_CMOVNO: this->cmovno_s(inst); break; 420 case ID_INS_CMOVNP: this->cmovnp_s(inst); break; 421 case ID_INS_CMOVNS: this->cmovns_s(inst); break; 422 case ID_INS_CMOVO: this->cmovo_s(inst); break; 423 case ID_INS_CMOVP: this->cmovp_s(inst); break; 424 case ID_INS_CMOVS: this->cmovs_s(inst); break; 425 case ID_INS_CMP: this->cmp_s(inst); break; 426 case ID_INS_CMPSB: this->cmpsb_s(inst); break; 427 case ID_INS_CMPSD: this->cmpsd_s(inst); break; 428 case ID_INS_CMPSQ: this->cmpsq_s(inst); break; 429 case ID_INS_CMPSW: this->cmpsw_s(inst); break; 430 case ID_INS_CMPXCHG: this->cmpxchg_s(inst); break; 431 case ID_INS_CMPXCHG16B: this->cmpxchg16b_s(inst); break; 432 case ID_INS_CMPXCHG8B: this->cmpxchg8b_s(inst); break; 433 case ID_INS_CPUID: this->cpuid_s(inst); break; 434 case ID_INS_CQO: this->cqo_s(inst); break; 435 case ID_INS_CWD: this->cwd_s(inst); break; 436 case ID_INS_CWDE: this->cwde_s(inst); break; 437 case ID_INS_DEC: this->dec_s(inst); break; 438 case ID_INS_DIV: this->div_s(inst); break; 439 case ID_INS_ENDBR32: this->endbr32_s(inst); break; 440 case ID_INS_ENDBR64: this->endbr64_s(inst); break; 441 case ID_INS_EXTRACTPS: this->extractps_s(inst); break; 442 case ID_INS_IDIV: this->idiv_s(inst); break; 443 case ID_INS_IMUL: this->imul_s(inst); break; 444 case ID_INS_INC: this->inc_s(inst); break; 445 case ID_INS_INVD: this->invd_s(inst); break; 446 case ID_INS_INVLPG: this->invlpg_s(inst); break; 447 case ID_INS_JA: this->ja_s(inst); break; 448 case ID_INS_JAE: this->jae_s(inst); break; 449 case ID_INS_JB: this->jb_s(inst); break; 450 case ID_INS_JBE: this->jbe_s(inst); break; 451 case ID_INS_JCXZ: this->jcxz_s(inst); break; 452 case ID_INS_JE: this->je_s(inst); break; 453 case ID_INS_JECXZ: this->jecxz_s(inst); break; 454 case ID_INS_JG: this->jg_s(inst); break; 455 case ID_INS_JGE: this->jge_s(inst); break; 456 case ID_INS_JL: this->jl_s(inst); break; 457 case ID_INS_JLE: this->jle_s(inst); break; 458 case ID_INS_JMP: this->jmp_s(inst); break; 459 case ID_INS_JNE: this->jne_s(inst); break; 460 case ID_INS_JNO: this->jno_s(inst); break; 461 case ID_INS_JNP: this->jnp_s(inst); break; 462 case ID_INS_JNS: this->jns_s(inst); break; 463 case ID_INS_JO: this->jo_s(inst); break; 464 case ID_INS_JP: this->jp_s(inst); break; 465 case ID_INS_JRCXZ: this->jrcxz_s(inst); break; 466 case ID_INS_JS: this->js_s(inst); break; 467 case ID_INS_LAHF: this->lahf_s(inst); break; 468 case ID_INS_LDDQU: this->lddqu_s(inst); break; 469 case ID_INS_LDMXCSR: this->ldmxcsr_s(inst); break; 470 case ID_INS_LEA: this->lea_s(inst); break; 471 case ID_INS_LEAVE: this->leave_s(inst); break; 472 case ID_INS_LFENCE: this->lfence_s(inst); break; 473 case ID_INS_LODSB: this->lodsb_s(inst); break; 474 case ID_INS_LODSD: this->lodsd_s(inst); break; 475 case ID_INS_LODSQ: this->lodsq_s(inst); break; 476 case ID_INS_LODSW: this->lodsw_s(inst); break; 477 case ID_INS_LOOP: this->loop_s(inst); break; 478 case ID_INS_LZCNT: this->lzcnt_s(inst); break; 479 case ID_INS_MFENCE: this->mfence_s(inst); break; 480 case ID_INS_MOV: this->mov_s(inst); break; 481 case ID_INS_MOVABS: this->movabs_s(inst); break; 482 case ID_INS_MOVAPD: this->movapd_s(inst); break; 483 case ID_INS_MOVAPS: this->movaps_s(inst); break; 484 case ID_INS_MOVD: this->movd_s(inst); break; 485 case ID_INS_MOVDDUP: this->movddup_s(inst); break; 486 case ID_INS_MOVDQ2Q: this->movdq2q_s(inst); break; 487 case ID_INS_MOVDQA: this->movdqa_s(inst); break; 488 case ID_INS_MOVDQU: this->movdqu_s(inst); break; 489 case ID_INS_MOVHLPS: this->movhlps_s(inst); break; 490 case ID_INS_MOVHPD: this->movhpd_s(inst); break; 491 case ID_INS_MOVHPS: this->movhps_s(inst); break; 492 case ID_INS_MOVLHPS: this->movlhps_s(inst); break; 493 case ID_INS_MOVLPD: this->movlpd_s(inst); break; 494 case ID_INS_MOVLPS: this->movlps_s(inst); break; 495 case ID_INS_MOVMSKPD: this->movmskpd_s(inst); break; 496 case ID_INS_MOVMSKPS: this->movmskps_s(inst); break; 497 case ID_INS_MOVNTDQ: this->movntdq_s(inst); break; 498 case ID_INS_MOVNTI: this->movnti_s(inst); break; 499 case ID_INS_MOVNTPD: this->movntpd_s(inst); break; 500 case ID_INS_MOVNTPS: this->movntps_s(inst); break; 501 case ID_INS_MOVNTQ: this->movntq_s(inst); break; 502 case ID_INS_MOVQ2DQ: this->movq2dq_s(inst); break; 503 case ID_INS_MOVQ: this->movq_s(inst); break; 504 case ID_INS_MOVSB: this->movsb_s(inst); break; 505 case ID_INS_MOVSD: this->movsd_s(inst); break; 506 case ID_INS_MOVSHDUP: this->movshdup_s(inst); break; 507 case ID_INS_MOVSLDUP: this->movsldup_s(inst); break; 508 case ID_INS_MOVSQ: this->movsq_s(inst); break; 509 case ID_INS_MOVSW: this->movsw_s(inst); break; 510 case ID_INS_MOVSX: this->movsx_s(inst); break; 511 case ID_INS_MOVSXD: this->movsxd_s(inst); break; 512 case ID_INS_MOVUPD: this->movupd_s(inst); break; 513 case ID_INS_MOVUPS: this->movups_s(inst); break; 514 case ID_INS_MOVZX: this->movzx_s(inst); break; 515 case ID_INS_MUL: this->mul_s(inst); break; 516 case ID_INS_MULX: this->mulx_s(inst); break; 517 case ID_INS_NEG: this->neg_s(inst); break; 518 case ID_INS_NOP: this->nop_s(inst); break; 519 case ID_INS_NOT: this->not_s(inst); break; 520 case ID_INS_OR: this->or_s(inst); break; 521 case ID_INS_ORPD: this->orpd_s(inst); break; 522 case ID_INS_ORPS: this->orps_s(inst); break; 523 case ID_INS_PADDB: this->paddb_s(inst); break; 524 case ID_INS_PADDD: this->paddd_s(inst); break; 525 case ID_INS_PADDQ: this->paddq_s(inst); break; 526 case ID_INS_PADDW: this->paddw_s(inst); break; 527 case ID_INS_PAND: this->pand_s(inst); break; 528 case ID_INS_PANDN: this->pandn_s(inst); break; 529 case ID_INS_PAUSE: this->pause_s(inst); break; 530 case ID_INS_PAVGB: this->pavgb_s(inst); break; 531 case ID_INS_PAVGW: this->pavgw_s(inst); break; 532 case ID_INS_PCMPEQB: this->pcmpeqb_s(inst); break; 533 case ID_INS_PCMPEQD: this->pcmpeqd_s(inst); break; 534 case ID_INS_PCMPEQW: this->pcmpeqw_s(inst); break; 535 case ID_INS_PCMPGTB: this->pcmpgtb_s(inst); break; 536 case ID_INS_PCMPGTD: this->pcmpgtd_s(inst); break; 537 case ID_INS_PCMPGTW: this->pcmpgtw_s(inst); break; 538 case ID_INS_PEXTRB: this->pextrb_s(inst); break; 539 case ID_INS_PEXTRD: this->pextrd_s(inst); break; 540 case ID_INS_PEXTRQ: this->pextrq_s(inst); break; 541 case ID_INS_PEXTRW: this->pextrw_s(inst); break; 542 case ID_INS_PINSRB: this->pinsrb_s(inst); break; 543 case ID_INS_PINSRD: this->pinsrd_s(inst); break; 544 case ID_INS_PINSRQ: this->pinsrq_s(inst); break; 545 case ID_INS_PINSRW: this->pinsrw_s(inst); break; 546 case ID_INS_PMAXSB: this->pmaxsb_s(inst); break; 547 case ID_INS_PMAXSD: this->pmaxsd_s(inst); break; 548 case ID_INS_PMAXSW: this->pmaxsw_s(inst); break; 549 case ID_INS_PMAXUB: this->pmaxub_s(inst); break; 550 case ID_INS_PMAXUD: this->pmaxud_s(inst); break; 551 case ID_INS_PMAXUW: this->pmaxuw_s(inst); break; 552 case ID_INS_PMINSB: this->pminsb_s(inst); break; 553 case ID_INS_PMINSD: this->pminsd_s(inst); break; 554 case ID_INS_PMINSW: this->pminsw_s(inst); break; 555 case ID_INS_PMINUB: this->pminub_s(inst); break; 556 case ID_INS_PMINUD: this->pminud_s(inst); break; 557 case ID_INS_PMINUW: this->pminuw_s(inst); break; 558 case ID_INS_PMOVMSKB: this->pmovmskb_s(inst); break; 559 case ID_INS_PMOVSXBD: this->pmovsxbd_s(inst); break; 560 case ID_INS_PMOVSXBQ: this->pmovsxbq_s(inst); break; 561 case ID_INS_PMOVSXBW: this->pmovsxbw_s(inst); break; 562 case ID_INS_PMOVSXDQ: this->pmovsxdq_s(inst); break; 563 case ID_INS_PMOVSXWD: this->pmovsxwd_s(inst); break; 564 case ID_INS_PMOVSXWQ: this->pmovsxwq_s(inst); break; 565 case ID_INS_PMOVZXBD: this->pmovzxbd_s(inst); break; 566 case ID_INS_PMOVZXBQ: this->pmovzxbq_s(inst); break; 567 case ID_INS_PMOVZXBW: this->pmovzxbw_s(inst); break; 568 case ID_INS_PMOVZXDQ: this->pmovzxdq_s(inst); break; 569 case ID_INS_PMOVZXWD: this->pmovzxwd_s(inst); break; 570 case ID_INS_PMOVZXWQ: this->pmovzxwq_s(inst); break; 571 case ID_INS_POP: this->pop_s(inst); break; 572 case ID_INS_POPAL: this->popal_s(inst); break; 573 case ID_INS_POPF: this->popf_s(inst); break; 574 case ID_INS_POPFD: this->popfd_s(inst); break; 575 case ID_INS_POPFQ: this->popfq_s(inst); break; 576 case ID_INS_POR: this->por_s(inst); break; 577 case ID_INS_PREFETCH: this->prefetchx_s(inst); break; 578 case ID_INS_PREFETCHNTA: this->prefetchx_s(inst); break; 579 case ID_INS_PREFETCHT0: this->prefetchx_s(inst); break; 580 case ID_INS_PREFETCHT1: this->prefetchx_s(inst); break; 581 case ID_INS_PREFETCHT2: this->prefetchx_s(inst); break; 582 case ID_INS_PREFETCHW: this->prefetchx_s(inst); break; 583 case ID_INS_PSHUFD: this->pshufd_s(inst); break; 584 case ID_INS_PSHUFHW: this->pshufhw_s(inst); break; 585 case ID_INS_PSHUFLW: this->pshuflw_s(inst); break; 586 case ID_INS_PSHUFW: this->pshufw_s(inst); break; 587 case ID_INS_PSLLD: this->pslld_s(inst); break; 588 case ID_INS_PSLLDQ: this->pslldq_s(inst); break; 589 case ID_INS_PSLLQ: this->psllq_s(inst); break; 590 case ID_INS_PSLLW: this->psllw_s(inst); break; 591 case ID_INS_PSRLDQ: this->psrldq_s(inst); break; 592 case ID_INS_PSUBB: this->psubb_s(inst); break; 593 case ID_INS_PSUBD: this->psubd_s(inst); break; 594 case ID_INS_PSUBQ: this->psubq_s(inst); break; 595 case ID_INS_PSUBW: this->psubw_s(inst); break; 596 case ID_INS_PTEST: this->ptest_s(inst); break; 597 case ID_INS_PUNPCKHBW: this->punpckhbw_s(inst); break; 598 case ID_INS_PUNPCKHDQ: this->punpckhdq_s(inst); break; 599 case ID_INS_PUNPCKHQDQ: this->punpckhqdq_s(inst); break; 600 case ID_INS_PUNPCKHWD: this->punpckhwd_s(inst); break; 601 case ID_INS_PUNPCKLBW: this->punpcklbw_s(inst); break; 602 case ID_INS_PUNPCKLDQ: this->punpckldq_s(inst); break; 603 case ID_INS_PUNPCKLQDQ: this->punpcklqdq_s(inst); break; 604 case ID_INS_PUNPCKLWD: this->punpcklwd_s(inst); break; 605 case ID_INS_PUSH: this->push_s(inst); break; 606 case ID_INS_PUSHAL: this->pushal_s(inst); break; 607 case ID_INS_PUSHFD: this->pushfd_s(inst); break; 608 case ID_INS_PUSHFQ: this->pushfq_s(inst); break; 609 case ID_INS_PXOR: this->pxor_s(inst); break; 610 case ID_INS_RCL: this->rcl_s(inst); break; 611 case ID_INS_RCR: this->rcr_s(inst); break; 612 case ID_INS_RDTSC: this->rdtsc_s(inst); break; 613 case ID_INS_RET: this->ret_s(inst); break; 614 case ID_INS_ROL: this->rol_s(inst); break; 615 case ID_INS_ROR: this->ror_s(inst); break; 616 case ID_INS_RORX: this->rorx_s(inst); break; 617 case ID_INS_SAHF: this->sahf_s(inst); break; 618 case ID_INS_SAL: this->shl_s(inst); break; 619 case ID_INS_SAR: this->sar_s(inst); break; 620 case ID_INS_SARX: this->sarx_s(inst); break; 621 case ID_INS_SBB: this->sbb_s(inst); break; 622 case ID_INS_SCASB: this->scasb_s(inst); break; 623 case ID_INS_SCASD: this->scasd_s(inst); break; 624 case ID_INS_SCASQ: this->scasq_s(inst); break; 625 case ID_INS_SCASW: this->scasw_s(inst); break; 626 case ID_INS_SETA: this->seta_s(inst); break; 627 case ID_INS_SETAE: this->setae_s(inst); break; 628 case ID_INS_SETB: this->setb_s(inst); break; 629 case ID_INS_SETBE: this->setbe_s(inst); break; 630 case ID_INS_SETE: this->sete_s(inst); break; 631 case ID_INS_SETG: this->setg_s(inst); break; 632 case ID_INS_SETGE: this->setge_s(inst); break; 633 case ID_INS_SETL: this->setl_s(inst); break; 634 case ID_INS_SETLE: this->setle_s(inst); break; 635 case ID_INS_SETNE: this->setne_s(inst); break; 636 case ID_INS_SETNO: this->setno_s(inst); break; 637 case ID_INS_SETNP: this->setnp_s(inst); break; 638 case ID_INS_SETNS: this->setns_s(inst); break; 639 case ID_INS_SETO: this->seto_s(inst); break; 640 case ID_INS_SETP: this->setp_s(inst); break; 641 case ID_INS_SETS: this->sets_s(inst); break; 642 case ID_INS_SFENCE: this->sfence_s(inst); break; 643 case ID_INS_SHL: this->shl_s(inst); break; 644 case ID_INS_SHLD: this->shld_s(inst); break; 645 case ID_INS_SHLX: this->shlx_s(inst); break; 646 case ID_INS_SHR: this->shr_s(inst); break; 647 case ID_INS_SHRD: this->shrd_s(inst); break; 648 case ID_INS_SHRX: this->shrx_s(inst); break; 649 case ID_INS_STC: this->stc_s(inst); break; 650 case ID_INS_STD: this->std_s(inst); break; 651 case ID_INS_STI: this->sti_s(inst); break; 652 case ID_INS_STMXCSR: this->stmxcsr_s(inst); break; 653 case ID_INS_STOSB: this->stosb_s(inst); break; 654 case ID_INS_STOSD: this->stosd_s(inst); break; 655 case ID_INS_STOSQ: this->stosq_s(inst); break; 656 case ID_INS_STOSW: this->stosw_s(inst); break; 657 case ID_INS_SUB: this->sub_s(inst); break; 658 case ID_INS_SYSCALL: this->syscall_s(inst); break; 659 case ID_INS_SYSENTER: this->sysenter_s(inst); break; 660 case ID_INS_TEST: this->test_s(inst); break; 661 case ID_INS_TZCNT: this->tzcnt_s(inst); break; 662 case ID_INS_UNPCKHPD: this->unpckhpd_s(inst); break; 663 case ID_INS_UNPCKHPS: this->unpckhps_s(inst); break; 664 case ID_INS_UNPCKLPD: this->unpcklpd_s(inst); break; 665 case ID_INS_UNPCKLPS: this->unpcklps_s(inst); break; 666 case ID_INS_VMOVDQA: this->vmovdqa_s(inst); break; 667 case ID_INS_VMOVDQU: this->vmovdqu_s(inst); break; 668 case ID_INS_VPAND: this->vpand_s(inst); break; 669 case ID_INS_VPANDN: this->vpandn_s(inst); break; 670 case ID_INS_VPEXTRB: this->vpextrb_s(inst); break; 671 case ID_INS_VPEXTRD: this->vpextrd_s(inst); break; 672 case ID_INS_VPEXTRQ: this->vpextrq_s(inst); break; 673 case ID_INS_VPEXTRW: this->vpextrw_s(inst); break; 674 case ID_INS_VPMOVMSKB: this->vpmovmskb_s(inst); break; 675 case ID_INS_VPOR: this->vpor_s(inst); break; 676 case ID_INS_VPSHUFD: this->vpshufd_s(inst); break; 677 case ID_INS_VPTEST: this->vptest_s(inst); break; 678 case ID_INS_VPXOR: this->vpxor_s(inst); break; 679 case ID_INS_WAIT: this->wait_s(inst); break; 680 case ID_INS_WBINVD: this->wbinvd_s(inst); break; 681 case ID_INS_XADD: this->xadd_s(inst); break; 682 case ID_INS_XCHG: this->xchg_s(inst); break; 683 case ID_INS_XOR: this->xor_s(inst); break; 684 case ID_INS_XORPD: this->xorpd_s(inst); break; 685 case ID_INS_XORPS: this->xorps_s(inst); break; 686 default: 687 return false; 688 } 689 return true; 690 } 691 692 alignAddStack_s(triton::arch::Instruction & inst,triton::uint32 delta)693 triton::uint64 x86Semantics::alignAddStack_s(triton::arch::Instruction& inst, triton::uint32 delta) { 694 auto dst = triton::arch::OperandWrapper(this->architecture->getStackPointer()); 695 696 /* Create symbolic operands */ 697 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 698 auto op2 = this->astCtxt->bv(delta, dst.getBitSize()); 699 700 /* Create the semantics */ 701 auto node = this->astCtxt->bvadd(op1, op2); 702 703 /* Create symbolic expression */ 704 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "Stack alignment"); 705 706 /* Spread taint */ 707 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 708 709 /* Return the new stack value */ 710 return node->evaluate().convert_to<triton::uint64>(); 711 } 712 713 alignSubStack_s(triton::arch::Instruction & inst,triton::uint32 delta)714 triton::uint64 x86Semantics::alignSubStack_s(triton::arch::Instruction& inst, triton::uint32 delta) { 715 auto dst = triton::arch::OperandWrapper(this->architecture->getStackPointer()); 716 717 /* Create symbolic operands */ 718 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 719 auto op2 = this->astCtxt->bv(delta, dst.getBitSize()); 720 721 /* Create the semantics */ 722 auto node = this->astCtxt->bvsub(op1, op2); 723 724 /* Create symbolic expression */ 725 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "Stack alignment"); 726 727 /* Spread taint */ 728 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 729 730 /* Return the new stack value */ 731 return node->evaluate().convert_to<triton::uint64>(); 732 } 733 734 clearFlag_s(triton::arch::Instruction & inst,const triton::arch::Register & flag,std::string comment)735 void x86Semantics::clearFlag_s(triton::arch::Instruction& inst, const triton::arch::Register& flag, std::string comment) { 736 /* Create the semantics */ 737 auto node = this->astCtxt->bv(0, 1); 738 739 /* Create symbolic expression */ 740 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, flag, comment); 741 742 /* Spread taint */ 743 expr->isTainted = this->taintEngine->setTaintRegister(flag, triton::engines::taint::UNTAINTED); 744 } 745 746 setFlag_s(triton::arch::Instruction & inst,const triton::arch::Register & flag,std::string comment)747 void x86Semantics::setFlag_s(triton::arch::Instruction& inst, const triton::arch::Register& flag, std::string comment) { 748 /* Create the semantics */ 749 auto node = this->astCtxt->bv(1, 1); 750 751 /* Create symbolic expression */ 752 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, flag, comment); 753 754 /* Spread taint */ 755 expr->isTainted = this->taintEngine->setTaintRegister(flag, triton::engines::taint::UNTAINTED); 756 } 757 758 undefined_s(triton::arch::Instruction & inst,const triton::arch::Register & reg)759 void x86Semantics::undefined_s(triton::arch::Instruction& inst, const triton::arch::Register& reg) { 760 if (this->modes->isModeEnabled(triton::modes::CONCRETIZE_UNDEFINED_REGISTERS)) { 761 this->symbolicEngine->concretizeRegister(reg); 762 } 763 /* Tell that the instruction defines a register as undefined and untaint */ 764 inst.setUndefinedRegister(reg); 765 this->taintEngine->setTaintRegister(reg, triton::engines::taint::UNTAINTED); 766 } 767 768 controlFlow_s(triton::arch::Instruction & inst)769 void x86Semantics::controlFlow_s(triton::arch::Instruction& inst) { 770 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 771 auto counter = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 772 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 773 774 switch (inst.getPrefix()) { 775 776 case triton::arch::x86::ID_PREFIX_REP: { 777 /* Create symbolic operands */ 778 auto op1 = this->symbolicEngine->getOperandAst(inst, counter); 779 780 /* Create the semantics for Counter */ 781 auto node1 = this->astCtxt->ite( 782 this->astCtxt->equal(op1, this->astCtxt->bv(0, counter.getBitSize())), 783 op1, 784 this->astCtxt->bvsub(op1, this->astCtxt->bv(1, counter.getBitSize())) 785 ); 786 787 /* Create the semantics for PC */ 788 auto node2 = this->astCtxt->ite( 789 this->astCtxt->equal(node1, this->astCtxt->bv(0, counter.getBitSize())), 790 this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize()), 791 this->astCtxt->bv(inst.getAddress(), pc.getBitSize()) 792 ); 793 794 /* Create symbolic expression */ 795 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, counter, "Counter operation"); 796 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, pc, "Program Counter"); 797 798 /* Spread taint for PC */ 799 expr1->isTainted = this->taintEngine->taintUnion(counter, counter); 800 expr2->isTainted = this->taintEngine->taintAssignment(pc, counter); 801 break; 802 } 803 804 case triton::arch::x86::ID_PREFIX_REPE: { 805 /* Create symbolic operands */ 806 auto op1 = this->symbolicEngine->getOperandAst(inst, counter); 807 auto op2 = this->symbolicEngine->getOperandAst(inst, zf); 808 809 /* Create the semantics for Counter */ 810 auto node1 = this->astCtxt->ite( 811 this->astCtxt->equal(op1, this->astCtxt->bv(0, counter.getBitSize())), 812 op1, 813 this->astCtxt->bvsub(op1, this->astCtxt->bv(1, counter.getBitSize())) 814 ); 815 816 /* Create the semantics for PC */ 817 auto node2 = this->astCtxt->ite( 818 this->astCtxt->lor( 819 this->astCtxt->equal(node1, this->astCtxt->bv(0, counter.getBitSize())), 820 this->astCtxt->equal(op2, this->astCtxt->bvfalse()) 821 ), 822 this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize()), 823 this->astCtxt->bv(inst.getAddress(), pc.getBitSize()) 824 ); 825 826 /* Create symbolic expression */ 827 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, counter, "Counter operation"); 828 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, pc, "Program Counter"); 829 830 /* Spread taint */ 831 expr1->isTainted = this->taintEngine->taintUnion(counter, counter); 832 expr2->isTainted = this->taintEngine->taintAssignment(pc, counter); 833 break; 834 } 835 836 case triton::arch::x86::ID_PREFIX_REPNE: { 837 /* Create symbolic operands */ 838 auto op1 = this->symbolicEngine->getOperandAst(inst, counter); 839 auto op2 = this->symbolicEngine->getOperandAst(inst, zf); 840 841 /* Create the semantics for Counter */ 842 auto node1 = this->astCtxt->ite( 843 this->astCtxt->equal(op1, this->astCtxt->bv(0, counter.getBitSize())), 844 op1, 845 this->astCtxt->bvsub(op1, this->astCtxt->bv(1, counter.getBitSize())) 846 ); 847 848 /* Create the semantics for PC */ 849 auto node2 = this->astCtxt->ite( 850 this->astCtxt->lor( 851 this->astCtxt->equal(node1, this->astCtxt->bv(0, counter.getBitSize())), 852 this->astCtxt->equal(op2, this->astCtxt->bvtrue()) 853 ), 854 this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize()), 855 this->astCtxt->bv(inst.getAddress(), pc.getBitSize()) 856 ); 857 858 /* Create symbolic expression */ 859 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, counter, "Counter operation"); 860 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, pc, "Program Counter"); 861 862 /* Spread taint */ 863 expr1->isTainted = this->taintEngine->taintUnion(counter, counter); 864 expr2->isTainted = this->taintEngine->taintAssignment(pc, counter); 865 break; 866 } 867 868 default: { 869 /* Create the semantics */ 870 auto node = this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize()); 871 872 /* Create symbolic expression */ 873 auto expr = this->symbolicEngine->createSymbolicRegisterExpression(inst, node, this->architecture->getProgramCounter(), "Program Counter"); 874 875 /* Spread taint */ 876 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getProgramCounter(), triton::engines::taint::UNTAINTED); 877 break; 878 } 879 } 880 } 881 882 af_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & op2,bool vol)883 void x86Semantics::af_s(triton::arch::Instruction& inst, 884 const triton::engines::symbolic::SharedSymbolicExpression& parent, 885 triton::arch::OperandWrapper& dst, 886 const triton::ast::SharedAbstractNode& op1, 887 const triton::ast::SharedAbstractNode& op2, 888 bool vol) { 889 890 auto bvSize = dst.getBitSize(); 891 auto low = vol ? 0 : dst.getLow(); 892 auto high = vol ? bvSize-1 : dst.getHigh(); 893 894 /* 895 * Create the semantic. 896 * af = 0x10 == (0x10 & (regDst ^ op1 ^ op2)) 897 */ 898 auto node = this->astCtxt->ite( 899 this->astCtxt->equal( 900 this->astCtxt->bv(0x10, bvSize), 901 this->astCtxt->bvand( 902 this->astCtxt->bv(0x10, bvSize), 903 this->astCtxt->bvxor( 904 this->astCtxt->extract(high, low, this->astCtxt->reference(parent)), 905 this->astCtxt->bvxor(op1, op2) 906 ) 907 ) 908 ), 909 this->astCtxt->bv(1, 1), 910 this->astCtxt->bv(0, 1) 911 ); 912 913 /* Create the symbolic expression */ 914 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_AF), "Adjust flag"); 915 916 /* Spread the taint from the parent to the child */ 917 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_AF), parent->isTainted); 918 } 919 920 afAaa_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & op3,bool vol)921 void x86Semantics::afAaa_s(triton::arch::Instruction& inst, 922 const triton::engines::symbolic::SharedSymbolicExpression& parent, 923 triton::arch::OperandWrapper& dst, 924 const triton::ast::SharedAbstractNode& op1, 925 const triton::ast::SharedAbstractNode& op3, 926 bool vol) { 927 928 auto bvSize = dst.getBitSize(); 929 930 /* 931 * Create the semantic. 932 * af = 1 if ((AL AND 0FH) > 9) or (AF = 1) then 0 933 */ 934 auto node = this->astCtxt->ite( 935 this->astCtxt->lor( 936 this->astCtxt->bvugt( 937 this->astCtxt->bvand(op1, this->astCtxt->bv(0xf, bvSize)), 938 this->astCtxt->bv(9, bvSize) 939 ), 940 this->astCtxt->equal(op3, this->astCtxt->bvtrue()) 941 ), 942 this->astCtxt->bv(1, 1), 943 this->astCtxt->bv(0, 1) 944 ); 945 946 /* Create the symbolic expression */ 947 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_AF), "Adjust flag"); 948 949 /* Spread the taint from the parent to the child */ 950 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_AF), parent->isTainted); 951 } 952 953 afNeg_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,bool vol)954 void x86Semantics::afNeg_s(triton::arch::Instruction& inst, 955 const triton::engines::symbolic::SharedSymbolicExpression& parent, 956 triton::arch::OperandWrapper& dst, 957 const triton::ast::SharedAbstractNode& op1, 958 bool vol) { 959 960 auto bvSize = dst.getBitSize(); 961 auto low = vol ? 0 : dst.getLow(); 962 auto high = vol ? bvSize-1 : dst.getHigh(); 963 964 /* 965 * Create the semantic. 966 * af = 0x10 == (0x10 & (op1 ^ regDst)) 967 */ 968 auto node = this->astCtxt->ite( 969 this->astCtxt->equal( 970 this->astCtxt->bv(0x10, bvSize), 971 this->astCtxt->bvand( 972 this->astCtxt->bv(0x10, bvSize), 973 this->astCtxt->bvxor( 974 op1, 975 this->astCtxt->extract(high, low, this->astCtxt->reference(parent)) 976 ) 977 ) 978 ), 979 this->astCtxt->bv(1, 1), 980 this->astCtxt->bv(0, 1) 981 ); 982 983 /* Create the symbolic expression */ 984 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_AF), "Adjust flag"); 985 986 /* Spread the taint from the parent to the child */ 987 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_AF), parent->isTainted); 988 } 989 990 cfAaa_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & op3,bool vol)991 void x86Semantics::cfAaa_s(triton::arch::Instruction& inst, 992 const triton::engines::symbolic::SharedSymbolicExpression& parent, 993 triton::arch::OperandWrapper& dst, 994 const triton::ast::SharedAbstractNode& op1, 995 const triton::ast::SharedAbstractNode& op3, 996 bool vol) { 997 998 auto bvSize = dst.getBitSize(); 999 1000 /* 1001 * Create the semantic. 1002 * cf = 1 if ((AL AND 0FH) > 9) or (AF = 1) then 0 1003 */ 1004 auto node = this->astCtxt->ite( 1005 this->astCtxt->lor( 1006 this->astCtxt->bvugt( 1007 this->astCtxt->bvand(op1, this->astCtxt->bv(0xf, bvSize)), 1008 this->astCtxt->bv(9, bvSize) 1009 ), 1010 this->astCtxt->equal(op3, this->astCtxt->bvtrue()) 1011 ), 1012 this->astCtxt->bv(1, 1), 1013 this->astCtxt->bv(0, 1) 1014 ); 1015 1016 /* Create the symbolic expression */ 1017 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag"); 1018 1019 /* Spread the taint from the parent to the child */ 1020 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted); 1021 } 1022 1023 cfAdd_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & op2,bool vol)1024 void x86Semantics::cfAdd_s(triton::arch::Instruction& inst, 1025 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1026 triton::arch::OperandWrapper& dst, 1027 const triton::ast::SharedAbstractNode& op1, 1028 const triton::ast::SharedAbstractNode& op2, 1029 bool vol) { 1030 1031 auto bvSize = dst.getBitSize(); 1032 auto low = vol ? 0 : dst.getLow(); 1033 auto high = vol ? bvSize-1 : dst.getHigh(); 1034 1035 /* 1036 * Create the semantic. 1037 * cf = MSB((op1 & op2) ^ ((op1 ^ op2 ^ parent) & (op1 ^ op2))); 1038 */ 1039 auto node = this->astCtxt->extract(bvSize-1, bvSize-1, 1040 this->astCtxt->bvxor( 1041 this->astCtxt->bvand(op1, op2), 1042 this->astCtxt->bvand( 1043 this->astCtxt->bvxor( 1044 this->astCtxt->bvxor(op1, op2), 1045 this->astCtxt->extract(high, low, this->astCtxt->reference(parent)) 1046 ), 1047 this->astCtxt->bvxor(op1, op2)) 1048 ) 1049 ); 1050 1051 /* Create the symbolic expression */ 1052 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag"); 1053 1054 /* Spread the taint from the parent to the child */ 1055 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted); 1056 } 1057 1058 cfBlsi_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,bool vol)1059 void x86Semantics::cfBlsi_s(triton::arch::Instruction& inst, 1060 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1061 triton::arch::OperandWrapper& dst, 1062 const triton::ast::SharedAbstractNode& op1, 1063 bool vol) { 1064 1065 /* 1066 * Create the semantic. 1067 * cf = 0 if op1 == 0 else 1 1068 */ 1069 auto node = this->astCtxt->ite( 1070 this->astCtxt->equal( 1071 op1, 1072 this->astCtxt->bv(0, dst.getBitSize()) 1073 ), 1074 this->astCtxt->bv(0, 1), 1075 this->astCtxt->bv(1, 1) 1076 ); 1077 1078 /* Create the symbolic expression */ 1079 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag"); 1080 1081 /* Spread the taint from the parent to the child */ 1082 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted); 1083 } 1084 1085 cfBlsmsk_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,bool vol)1086 void x86Semantics::cfBlsmsk_s(triton::arch::Instruction& inst, 1087 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1088 triton::arch::OperandWrapper& dst, 1089 const triton::ast::SharedAbstractNode& op1, 1090 bool vol) { 1091 1092 /* 1093 * Create the semantic. 1094 * cf = 1 if op1 == 0 else 0 1095 */ 1096 auto node = this->astCtxt->ite( 1097 this->astCtxt->equal( 1098 op1, 1099 this->astCtxt->bv(0, dst.getBitSize()) 1100 ), 1101 this->astCtxt->bv(1, 1), 1102 this->astCtxt->bv(0, 1) 1103 ); 1104 1105 /* Create the symbolic expression */ 1106 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag"); 1107 1108 /* Spread the taint from the parent to the child */ 1109 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted); 1110 } 1111 1112 cfBlsr_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,bool vol)1113 void x86Semantics::cfBlsr_s(triton::arch::Instruction& inst, 1114 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1115 triton::arch::OperandWrapper& dst, 1116 const triton::ast::SharedAbstractNode& op1, 1117 bool vol) { 1118 1119 /* 1120 * Create the semantic. 1121 * cf = 1 if op1 == 0 else 0 1122 */ 1123 auto node = this->astCtxt->ite( 1124 this->astCtxt->equal( 1125 op1, 1126 this->astCtxt->bv(0, dst.getBitSize()) 1127 ), 1128 this->astCtxt->bv(1, 1), 1129 this->astCtxt->bv(0, 1) 1130 ); 1131 1132 /* Create the symbolic expression */ 1133 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag"); 1134 1135 /* Spread the taint from the parent to the child */ 1136 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted); 1137 } 1138 1139 cfImul_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & res,bool vol)1140 void x86Semantics::cfImul_s(triton::arch::Instruction& inst, 1141 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1142 triton::arch::OperandWrapper& dst, 1143 const triton::ast::SharedAbstractNode& op1, 1144 const triton::ast::SharedAbstractNode& res, 1145 bool vol) { 1146 1147 /* 1148 * Create the semantic. 1149 * cf = 0 if sx(dst) == node else 1 1150 */ 1151 auto node = this->astCtxt->ite( 1152 this->astCtxt->equal( 1153 this->astCtxt->sx(dst.getBitSize(), op1), 1154 res 1155 ), 1156 this->astCtxt->bv(0, 1), 1157 this->astCtxt->bv(1, 1) 1158 ); 1159 1160 /* Create the symbolic expression */ 1161 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag"); 1162 1163 /* Spread the taint from the parent to the child */ 1164 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted); 1165 } 1166 1167 cfLzcnt_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & src,const triton::ast::SharedAbstractNode & op1,bool vol)1168 void x86Semantics::cfLzcnt_s(triton::arch::Instruction& inst, 1169 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1170 triton::arch::OperandWrapper& src, 1171 const triton::ast::SharedAbstractNode& op1, 1172 bool vol) { 1173 1174 auto bvSize = src.getBitSize(); 1175 auto low = vol ? 0 : src.getLow(); 1176 auto high = vol ? bvSize-1 : src.getHigh(); 1177 1178 /* 1179 * Create the semantic. 1180 * cf = 0 == parent 1181 */ 1182 auto node = this->astCtxt->ite( 1183 this->astCtxt->equal( 1184 this->astCtxt->extract(high, low, op1), 1185 this->astCtxt->bv(0, bvSize) 1186 ), 1187 this->astCtxt->bv(1, 1), 1188 this->astCtxt->bv(0, 1) 1189 ); 1190 1191 /* Create the symbolic expression */ 1192 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag"); 1193 1194 /* Spread the taint from the parent to the child */ 1195 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted); 1196 } 1197 1198 cfMul_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,bool vol)1199 void x86Semantics::cfMul_s(triton::arch::Instruction& inst, 1200 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1201 triton::arch::OperandWrapper& dst, 1202 const triton::ast::SharedAbstractNode& op1, 1203 bool vol) { 1204 1205 /* 1206 * Create the semantic. 1207 * cf = 0 if op1 == 0 else 1 1208 */ 1209 auto node = this->astCtxt->ite( 1210 this->astCtxt->equal( 1211 op1, 1212 this->astCtxt->bv(0, dst.getBitSize()) 1213 ), 1214 this->astCtxt->bv(0, 1), 1215 this->astCtxt->bv(1, 1) 1216 ); 1217 1218 /* Create the symbolic expression */ 1219 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag"); 1220 1221 /* Spread the taint from the parent to the child */ 1222 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted); 1223 } 1224 1225 cfNeg_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,bool vol)1226 void x86Semantics::cfNeg_s(triton::arch::Instruction& inst, 1227 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1228 triton::arch::OperandWrapper& dst, 1229 const triton::ast::SharedAbstractNode& op1, 1230 bool vol) { 1231 1232 /* 1233 * Create the semantic. 1234 * cf = 0 if op1 == 0 else 1 1235 */ 1236 auto node = this->astCtxt->ite( 1237 this->astCtxt->equal( 1238 op1, 1239 this->astCtxt->bv(0, dst.getBitSize()) 1240 ), 1241 this->astCtxt->bv(0, 1), 1242 this->astCtxt->bv(1, 1) 1243 ); 1244 1245 /* Create the symbolic expression */ 1246 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag"); 1247 1248 /* Spread the taint from the parent to the child */ 1249 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted); 1250 } 1251 1252 cfPtest_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,bool vol)1253 void x86Semantics::cfPtest_s(triton::arch::Instruction& inst, 1254 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1255 triton::arch::OperandWrapper& dst, 1256 bool vol) { 1257 1258 auto bvSize = dst.getBitSize(); 1259 auto low = vol ? 0 : dst.getLow(); 1260 auto high = vol ? bvSize-1 : dst.getHigh(); 1261 1262 /* 1263 * Create the semantic. 1264 * cf = 0 == regDst 1265 */ 1266 auto node = this->astCtxt->ite( 1267 this->astCtxt->equal( 1268 this->astCtxt->extract(high, low, this->astCtxt->reference(parent)), 1269 this->astCtxt->bv(0, bvSize) 1270 ), 1271 this->astCtxt->bv(1, 1), 1272 this->astCtxt->bv(0, 1) 1273 ); 1274 1275 /* Create the symbolic expression */ 1276 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag"); 1277 1278 /* Spread the taint from the parent to the child */ 1279 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted); 1280 } 1281 1282 cfRcl_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,const triton::ast::SharedAbstractNode & result,const triton::ast::SharedAbstractNode & op2,bool vol)1283 void x86Semantics::cfRcl_s(triton::arch::Instruction& inst, 1284 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1285 const triton::ast::SharedAbstractNode& result, 1286 const triton::ast::SharedAbstractNode& op2, 1287 bool vol) { 1288 1289 auto bvSize = op2->getBitvectorSize(); 1290 auto high = result->getBitvectorSize() - 1; 1291 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 1292 1293 auto node = this->astCtxt->ite( 1294 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)), 1295 this->symbolicEngine->getOperandAst(cf), 1296 this->astCtxt->extract(high, high, result) 1297 ); 1298 1299 /* Create the symbolic expression */ 1300 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag"); 1301 1302 if (op2->evaluate()) { 1303 /* Spread the taint from the parent to the child */ 1304 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted); 1305 } 1306 else { 1307 inst.removeWrittenRegister(cf.getConstRegister()); 1308 } 1309 } 1310 1311 cfRcr_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & result,const triton::ast::SharedAbstractNode & op2,bool vol)1312 void x86Semantics::cfRcr_s(triton::arch::Instruction& inst, 1313 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1314 triton::arch::OperandWrapper& dst, 1315 const triton::ast::SharedAbstractNode& result, 1316 const triton::ast::SharedAbstractNode& op2, 1317 bool vol) { 1318 1319 auto bvSize = op2->getBitvectorSize(); 1320 auto high = result->getBitvectorSize() - 1; 1321 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 1322 1323 auto node = this->astCtxt->ite( 1324 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)), 1325 this->symbolicEngine->getOperandAst(cf), 1326 this->astCtxt->extract(high, high, result) /* yes it's should be LSB, but here it's a trick :-) */ 1327 ); 1328 1329 /* Create the symbolic expression */ 1330 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag"); 1331 1332 if (op2->evaluate()) { 1333 /* Spread the taint from the parent to the child */ 1334 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted); 1335 } 1336 else { 1337 inst.removeWrittenRegister(cf.getConstRegister()); 1338 } 1339 } 1340 1341 cfRol_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op2,bool vol)1342 void x86Semantics::cfRol_s(triton::arch::Instruction& inst, 1343 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1344 triton::arch::OperandWrapper& dst, 1345 const triton::ast::SharedAbstractNode& op2, 1346 bool vol) { 1347 1348 auto bvSize = op2->getBitvectorSize(); 1349 auto low = vol ? 0 : dst.getLow(); 1350 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 1351 1352 auto node = this->astCtxt->ite( 1353 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)), 1354 this->symbolicEngine->getOperandAst(cf), 1355 this->astCtxt->extract(low, low, this->astCtxt->reference(parent)) 1356 ); 1357 1358 /* Create the symbolic expression */ 1359 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag"); 1360 1361 if (op2->evaluate()) { 1362 /* Spread the taint from the parent to the child */ 1363 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted); 1364 } 1365 else { 1366 inst.removeWrittenRegister(cf.getConstRegister()); 1367 } 1368 } 1369 1370 cfRor_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op2,bool vol)1371 void x86Semantics::cfRor_s(triton::arch::Instruction& inst, 1372 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1373 triton::arch::OperandWrapper& dst, 1374 const triton::ast::SharedAbstractNode& op2, 1375 bool vol) { 1376 1377 auto bvSize = op2->getBitvectorSize(); 1378 auto high = vol ? bvSize-1 : dst.getHigh(); 1379 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 1380 1381 auto node = this->astCtxt->ite( 1382 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)), 1383 this->symbolicEngine->getOperandAst(cf), 1384 this->astCtxt->extract(high, high, this->astCtxt->reference(parent)) 1385 ); 1386 1387 /* Create the symbolic expression */ 1388 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag"); 1389 1390 if (op2->evaluate()) { 1391 /* Spread the taint from the parent to the child */ 1392 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted); 1393 } 1394 else { 1395 inst.removeWrittenRegister(cf.getConstRegister()); 1396 } 1397 } 1398 1399 cfSar_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & op2,bool vol)1400 void x86Semantics::cfSar_s(triton::arch::Instruction& inst, 1401 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1402 triton::arch::OperandWrapper& dst, 1403 const triton::ast::SharedAbstractNode& op1, 1404 const triton::ast::SharedAbstractNode& op2, 1405 bool vol) { 1406 1407 auto bvSize = dst.getBitSize(); 1408 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 1409 1410 /* 1411 * Create the semantic. 1412 * if op2 != 0: 1413 * if op2 > bvSize: 1414 * cf.id = ((op1 >> (bvSize - 1)) & 1) 1415 * else: 1416 * cf.id = ((op1 >> (op2 - 1)) & 1) 1417 */ 1418 auto node = this->astCtxt->ite( 1419 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)), 1420 this->symbolicEngine->getOperandAst(cf), 1421 this->astCtxt->ite( 1422 this->astCtxt->bvugt(op2, this->astCtxt->bv(bvSize, bvSize)), 1423 this->astCtxt->extract(0, 0, this->astCtxt->bvlshr(op1, this->astCtxt->bvsub(this->astCtxt->bv(bvSize, bvSize), this->astCtxt->bv(1, bvSize)))), 1424 this->astCtxt->extract(0, 0, this->astCtxt->bvlshr(op1, this->astCtxt->bvsub(op2, this->astCtxt->bv(1, bvSize)))) 1425 ) 1426 ); 1427 1428 /* Create the symbolic expression */ 1429 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag"); 1430 1431 if (op2->evaluate()) { 1432 /* Spread the taint from the parent to the child */ 1433 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted); 1434 } 1435 else { 1436 inst.removeWrittenRegister(cf.getConstRegister()); 1437 } 1438 } 1439 1440 cfShl_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & op2,bool vol)1441 void x86Semantics::cfShl_s(triton::arch::Instruction& inst, 1442 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1443 triton::arch::OperandWrapper& dst, 1444 const triton::ast::SharedAbstractNode& op1, 1445 const triton::ast::SharedAbstractNode& op2, 1446 bool vol) { 1447 1448 auto bvSize = dst.getBitSize(); 1449 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 1450 1451 /* 1452 * Create the semantic. 1453 * cf = (op1 >> ((bvSize - op2) & 1) if op2 != 0 1454 */ 1455 auto node = this->astCtxt->ite( 1456 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)), 1457 this->symbolicEngine->getOperandAst(cf), 1458 this->astCtxt->extract(0, 0, 1459 this->astCtxt->bvlshr( 1460 op1, 1461 this->astCtxt->bvsub( 1462 this->astCtxt->bv(bvSize, bvSize), 1463 op2 1464 ) 1465 ) 1466 ) 1467 ); 1468 1469 /* Create the symbolic expression */ 1470 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag"); 1471 1472 if (op2->evaluate()) { 1473 /* Spread the taint from the parent to the child */ 1474 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted); 1475 } 1476 else { 1477 inst.removeWrittenRegister(cf.getConstRegister()); 1478 } 1479 } 1480 1481 cfShld_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & op2,const triton::ast::SharedAbstractNode & op3,bool vol)1482 void x86Semantics::cfShld_s(triton::arch::Instruction& inst, 1483 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1484 triton::arch::OperandWrapper& dst, 1485 const triton::ast::SharedAbstractNode& op1, 1486 const triton::ast::SharedAbstractNode& op2, 1487 const triton::ast::SharedAbstractNode& op3, 1488 bool vol) { 1489 1490 auto bv1Size = op1->getBitvectorSize(); 1491 auto bv2Size = op2->getBitvectorSize(); 1492 auto bv3Size = op3->getBitvectorSize(); 1493 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 1494 1495 /* 1496 * Create the semantic. 1497 * cf = MSB(rol(op3, concat(op2,op1))) if op3 != 0 1498 */ 1499 auto node = this->astCtxt->ite( 1500 this->astCtxt->equal(op3, this->astCtxt->bv(0, bv3Size)), 1501 this->symbolicEngine->getOperandAst(cf), 1502 this->astCtxt->extract( 1503 dst.getBitSize(), dst.getBitSize(), 1504 this->astCtxt->bvrol( 1505 this->astCtxt->concat(op2, op1), 1506 this->astCtxt->zx(((bv1Size + bv2Size) - bv3Size), op3) 1507 ) 1508 ) 1509 ); 1510 1511 /* Create the symbolic expression */ 1512 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag"); 1513 1514 if (op3->evaluate()) { 1515 /* Spread the taint from the parent to the child */ 1516 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted); 1517 } 1518 else { 1519 inst.removeWrittenRegister(cf.getConstRegister()); 1520 } 1521 } 1522 1523 cfShr_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & op2,bool vol)1524 void x86Semantics::cfShr_s(triton::arch::Instruction& inst, 1525 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1526 triton::arch::OperandWrapper& dst, 1527 const triton::ast::SharedAbstractNode& op1, 1528 const triton::ast::SharedAbstractNode& op2, 1529 bool vol) { 1530 1531 auto bvSize = dst.getBitSize(); 1532 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 1533 1534 /* 1535 * Create the semantic. 1536 * cf = ((op1 >> (op2 - 1)) & 1) if op2 != 0 1537 */ 1538 auto node = this->astCtxt->ite( 1539 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)), 1540 this->symbolicEngine->getOperandAst(cf), 1541 this->astCtxt->extract(0, 0, 1542 this->astCtxt->bvlshr( 1543 op1, 1544 this->astCtxt->bvsub( 1545 op2, 1546 this->astCtxt->bv(1, bvSize)) 1547 ) 1548 ) 1549 ); 1550 1551 /* Create the symbolic expression */ 1552 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag"); 1553 1554 if (op2->evaluate()) { 1555 /* Spread the taint from the parent to the child */ 1556 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted); 1557 } 1558 else { 1559 inst.removeWrittenRegister(cf.getConstRegister()); 1560 } 1561 } 1562 1563 cfShrd_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & op2,const triton::ast::SharedAbstractNode & op3,bool vol)1564 void x86Semantics::cfShrd_s(triton::arch::Instruction& inst, 1565 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1566 triton::arch::OperandWrapper& dst, 1567 const triton::ast::SharedAbstractNode& op1, 1568 const triton::ast::SharedAbstractNode& op2, 1569 const triton::ast::SharedAbstractNode& op3, 1570 bool vol) { 1571 1572 auto bvSize = dst.getBitSize(); 1573 auto bv1Size = op1->getBitvectorSize(); 1574 auto bv2Size = op2->getBitvectorSize(); 1575 auto bv3Size = op3->getBitvectorSize(); 1576 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 1577 1578 /* 1579 * Create the semantic. 1580 * cf = MSB(ror(op3, concat(op2,op1))) if op3 != 0 1581 */ 1582 auto node = this->astCtxt->ite( 1583 this->astCtxt->equal(op3, this->astCtxt->bv(0, bv3Size)), 1584 this->symbolicEngine->getOperandAst(cf), 1585 this->astCtxt->extract( 1586 (bvSize * 2) - 1, (bvSize * 2) - 1, 1587 this->astCtxt->bvror( 1588 this->astCtxt->concat(op2, op1), 1589 this->astCtxt->zx(((bv1Size + bv2Size) - bv3Size), op3) 1590 ) 1591 ) 1592 ); 1593 1594 /* Create the symbolic expression */ 1595 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, cf.getConstRegister(), "Carry flag"); 1596 1597 if (op3->evaluate()) { 1598 /* Spread the taint from the parent to the child */ 1599 expr->isTainted = this->taintEngine->setTaintRegister(cf.getConstRegister(), parent->isTainted); 1600 } 1601 else { 1602 inst.removeWrittenRegister(cf.getConstRegister()); 1603 } 1604 } 1605 1606 cfSub_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & op2,bool vol)1607 void x86Semantics::cfSub_s(triton::arch::Instruction& inst, 1608 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1609 triton::arch::OperandWrapper& dst, 1610 const triton::ast::SharedAbstractNode& op1, 1611 const triton::ast::SharedAbstractNode& op2, 1612 bool vol) { 1613 1614 auto bvSize = dst.getBitSize(); 1615 auto low = vol ? 0 : dst.getLow(); 1616 auto high = vol ? bvSize-1 : dst.getHigh(); 1617 1618 /* 1619 * Create the semantic. 1620 * cf = extract(bvSize, bvSize (((op1 ^ op2 ^ res) ^ ((op1 ^ res) & (op1 ^ op2))))) 1621 */ 1622 auto node = this->astCtxt->extract(bvSize-1, bvSize-1, 1623 this->astCtxt->bvxor( 1624 this->astCtxt->bvxor(op1, this->astCtxt->bvxor(op2, this->astCtxt->extract(high, low, this->astCtxt->reference(parent)))), 1625 this->astCtxt->bvand( 1626 this->astCtxt->bvxor(op1, this->astCtxt->extract(high, low, this->astCtxt->reference(parent))), 1627 this->astCtxt->bvxor(op1, op2) 1628 ) 1629 ) 1630 ); 1631 1632 /* Create the symbolic expression */ 1633 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag"); 1634 1635 /* Spread the taint from the parent to the child */ 1636 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted); 1637 } 1638 1639 cfTzcnt_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & src,const triton::ast::SharedAbstractNode & op1,bool vol)1640 void x86Semantics::cfTzcnt_s(triton::arch::Instruction& inst, 1641 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1642 triton::arch::OperandWrapper& src, 1643 const triton::ast::SharedAbstractNode& op1, 1644 bool vol) { 1645 1646 auto bvSize = src.getBitSize(); 1647 auto low = vol ? 0 : src.getLow(); 1648 auto high = vol ? bvSize-1 : src.getHigh(); 1649 1650 /* 1651 * Create the semantic. 1652 * cf = 0 == parent 1653 */ 1654 auto node = this->astCtxt->ite( 1655 this->astCtxt->equal( 1656 this->astCtxt->extract(high, low, op1), 1657 this->astCtxt->bv(0, bvSize) 1658 ), 1659 this->astCtxt->bv(1, 1), 1660 this->astCtxt->bv(0, 1) 1661 ); 1662 1663 /* Create the symbolic expression */ 1664 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "Carry flag"); 1665 1666 /* Spread the taint from the parent to the child */ 1667 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_CF), parent->isTainted); 1668 } 1669 1670 ofAdd_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & op2,bool vol)1671 void x86Semantics::ofAdd_s(triton::arch::Instruction& inst, 1672 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1673 triton::arch::OperandWrapper& dst, 1674 const triton::ast::SharedAbstractNode& op1, 1675 const triton::ast::SharedAbstractNode& op2, 1676 bool vol) { 1677 1678 auto bvSize = dst.getBitSize(); 1679 auto low = vol ? 0 : dst.getLow(); 1680 auto high = vol ? bvSize-1 : dst.getHigh(); 1681 1682 /* 1683 * Create the semantic. 1684 * of = MSB((op1 ^ ~op2) & (op1 ^ regDst)) 1685 */ 1686 auto node = this->astCtxt->extract(bvSize-1, bvSize-1, 1687 this->astCtxt->bvand( 1688 this->astCtxt->bvxor(op1, this->astCtxt->bvnot(op2)), 1689 this->astCtxt->bvxor(op1, this->astCtxt->extract(high, low, this->astCtxt->reference(parent))) 1690 ) 1691 ); 1692 1693 /* Create the symbolic expression */ 1694 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_OF), "Overflow flag"); 1695 1696 /* Spread the taint from the parent to the child */ 1697 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_OF), parent->isTainted); 1698 } 1699 1700 ofImul_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & res,bool vol)1701 void x86Semantics::ofImul_s(triton::arch::Instruction& inst, 1702 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1703 triton::arch::OperandWrapper& dst, 1704 const triton::ast::SharedAbstractNode& op1, 1705 const triton::ast::SharedAbstractNode& res, 1706 bool vol) { 1707 /* 1708 * Create the semantic. 1709 * of = 0 if sx(dst) == node else 1 1710 */ 1711 auto node = this->astCtxt->ite( 1712 this->astCtxt->equal( 1713 this->astCtxt->sx(dst.getBitSize(), op1), 1714 res 1715 ), 1716 this->astCtxt->bv(0, 1), 1717 this->astCtxt->bv(1, 1) 1718 ); 1719 1720 /* Create the symbolic expression */ 1721 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_OF), "Overflow flag"); 1722 1723 /* Spread the taint from the parent to the child */ 1724 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_OF), parent->isTainted); 1725 } 1726 1727 ofMul_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,bool vol)1728 void x86Semantics::ofMul_s(triton::arch::Instruction& inst, 1729 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1730 triton::arch::OperandWrapper& dst, 1731 const triton::ast::SharedAbstractNode& op1, 1732 bool vol) { 1733 1734 /* 1735 * Create the semantic. 1736 * of = 0 if up == 0 else 1 1737 */ 1738 auto node = this->astCtxt->ite( 1739 this->astCtxt->equal( 1740 op1, 1741 this->astCtxt->bv(0, dst.getBitSize()) 1742 ), 1743 this->astCtxt->bv(0, 1), 1744 this->astCtxt->bv(1, 1) 1745 ); 1746 1747 /* Create the symbolic expression */ 1748 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_OF), "Overflow flag"); 1749 1750 /* Spread the taint from the parent to the child */ 1751 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_OF), parent->isTainted); 1752 } 1753 1754 ofNeg_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,bool vol)1755 void x86Semantics::ofNeg_s(triton::arch::Instruction& inst, 1756 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1757 triton::arch::OperandWrapper& dst, 1758 const triton::ast::SharedAbstractNode& op1, 1759 bool vol) { 1760 1761 auto bvSize = dst.getBitSize(); 1762 auto low = vol ? 0 : dst.getLow(); 1763 auto high = vol ? bvSize-1 : dst.getHigh(); 1764 1765 /* 1766 * Create the semantic. 1767 * of = (res & op1) >> (bvSize - 1) & 1 1768 */ 1769 auto node = this->astCtxt->extract(0, 0, 1770 this->astCtxt->bvlshr( 1771 this->astCtxt->bvand(this->astCtxt->extract(high, low, this->astCtxt->reference(parent)), op1), 1772 this->astCtxt->bvsub(this->astCtxt->bv(bvSize, bvSize), this->astCtxt->bv(1, bvSize)) 1773 ) 1774 ); 1775 1776 /* Create the symbolic expression */ 1777 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_OF), "Overflow flag"); 1778 1779 /* Spread the taint from the parent to the child */ 1780 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_OF), parent->isTainted); 1781 } 1782 1783 ofRol_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op2,bool vol)1784 void x86Semantics::ofRol_s(triton::arch::Instruction& inst, 1785 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1786 triton::arch::OperandWrapper& dst, 1787 const triton::ast::SharedAbstractNode& op2, 1788 bool vol) { 1789 1790 auto bvSize = dst.getBitSize(); 1791 auto high = vol ? bvSize-1 : dst.getHigh(); 1792 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 1793 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 1794 1795 auto node = this->astCtxt->ite( 1796 this->astCtxt->equal(this->astCtxt->zx(bvSize - op2->getBitvectorSize(), op2), this->astCtxt->bv(1, bvSize)), 1797 this->astCtxt->bvxor( 1798 this->astCtxt->extract(high, high, this->astCtxt->reference(parent)), 1799 this->symbolicEngine->getOperandAst(inst, cf) 1800 ), 1801 this->symbolicEngine->getOperandAst(of) 1802 ); 1803 1804 /* Create the symbolic expression */ 1805 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag"); 1806 1807 if (op2->evaluate()) { 1808 /* Spread the taint from the parent to the child */ 1809 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted); 1810 } 1811 else { 1812 inst.removeReadRegister(cf.getConstRegister()); 1813 inst.removeWrittenRegister(of.getConstRegister()); 1814 } 1815 } 1816 1817 ofRor_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op2,bool vol)1818 void x86Semantics::ofRor_s(triton::arch::Instruction& inst, 1819 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1820 triton::arch::OperandWrapper& dst, 1821 const triton::ast::SharedAbstractNode& op2, 1822 bool vol) { 1823 1824 auto bvSize = op2->getBitvectorSize(); 1825 auto high = vol ? bvSize-1 : dst.getHigh(); 1826 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 1827 1828 auto node = this->astCtxt->ite( 1829 this->astCtxt->equal(op2, this->astCtxt->bv(1, bvSize)), 1830 this->astCtxt->bvxor( 1831 this->astCtxt->extract(high, high, this->astCtxt->reference(parent)), 1832 this->astCtxt->extract(high-1, high-1, this->astCtxt->reference(parent)) 1833 ), 1834 this->symbolicEngine->getOperandAst(of) 1835 ); 1836 1837 /* Create the symbolic expression */ 1838 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag"); 1839 1840 if (op2->evaluate()) { 1841 /* Spread the taint from the parent to the child */ 1842 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted); 1843 } 1844 else { 1845 inst.removeWrittenRegister(of.getConstRegister()); 1846 } 1847 } 1848 1849 ofRcr_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & op2,bool vol)1850 void x86Semantics::ofRcr_s(triton::arch::Instruction& inst, 1851 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1852 triton::arch::OperandWrapper& dst, 1853 const triton::ast::SharedAbstractNode& op1, 1854 const triton::ast::SharedAbstractNode& op2, 1855 bool vol) { 1856 1857 auto bvSize = op2->getBitvectorSize(); 1858 auto high = dst.getBitSize()-1; 1859 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 1860 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 1861 1862 auto node = this->astCtxt->ite( 1863 this->astCtxt->equal(op2, this->astCtxt->bv(1, bvSize)), 1864 this->astCtxt->bvxor( 1865 this->astCtxt->extract(high, high, op1), 1866 this->symbolicEngine->getOperandAst(inst, cf) 1867 ), 1868 this->symbolicEngine->getOperandAst(of) 1869 ); 1870 1871 /* Create the symbolic expression */ 1872 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag"); 1873 1874 if (op2->evaluate()) { 1875 /* Spread the taint from the parent to the child */ 1876 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted); 1877 } 1878 else { 1879 inst.removeReadRegister(cf.getConstRegister()); 1880 inst.removeWrittenRegister(of.getConstRegister()); 1881 } 1882 } 1883 1884 ofSar_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op2,bool vol)1885 void x86Semantics::ofSar_s(triton::arch::Instruction& inst, 1886 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1887 triton::arch::OperandWrapper& dst, 1888 const triton::ast::SharedAbstractNode& op2, 1889 bool vol) { 1890 1891 auto bvSize = dst.getBitSize(); 1892 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 1893 1894 /* 1895 * Create the semantic. 1896 * of = 0 if op2 == 1 1897 */ 1898 auto node = this->astCtxt->ite( 1899 this->astCtxt->land( 1900 this->astCtxt->equal( 1901 /* #672 */ 1902 this->astCtxt->reference(parent), 1903 this->astCtxt->reference(parent) 1904 /* ---- */ 1905 ), 1906 this->astCtxt->equal( 1907 op2, 1908 this->astCtxt->bv(1, bvSize) 1909 ) 1910 ), 1911 this->astCtxt->bv(0, 1), 1912 this->symbolicEngine->getOperandAst(of) 1913 ); 1914 1915 /* Create the symbolic expression */ 1916 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag"); 1917 1918 if (op2->evaluate()) { 1919 /* Spread the taint from the parent to the child */ 1920 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted); 1921 } 1922 else { 1923 inst.removeWrittenRegister(of.getConstRegister()); 1924 } 1925 } 1926 1927 ofShl_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & op2,bool vol)1928 void x86Semantics::ofShl_s(triton::arch::Instruction& inst, 1929 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1930 triton::arch::OperandWrapper& dst, 1931 const triton::ast::SharedAbstractNode& op1, 1932 const triton::ast::SharedAbstractNode& op2, 1933 bool vol) { 1934 1935 auto bvSize = dst.getBitSize(); 1936 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 1937 1938 /* 1939 * Create the semantic. 1940 * of = ((op1 >> (bvSize - 1)) ^ (op1 >> (bvSize - 2))) & 1; if op2 == 1 1941 */ 1942 auto node = this->astCtxt->ite( 1943 this->astCtxt->equal( 1944 op2, 1945 this->astCtxt->bv(1, bvSize)), 1946 this->astCtxt->extract(0, 0, 1947 this->astCtxt->bvxor( 1948 this->astCtxt->bvlshr(op1, this->astCtxt->bvsub(this->astCtxt->bv(bvSize, bvSize), this->astCtxt->bv(1, bvSize))), 1949 this->astCtxt->bvlshr(op1, this->astCtxt->bvsub(this->astCtxt->bv(bvSize, bvSize), this->astCtxt->bv(2, bvSize))) 1950 ) 1951 ), 1952 this->symbolicEngine->getOperandAst(of) 1953 ); 1954 1955 /* Create the symbolic expression */ 1956 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag"); 1957 1958 if (op2->evaluate()) { 1959 /* Spread the taint from the parent to the child */ 1960 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted); 1961 } 1962 else { 1963 inst.removeWrittenRegister(of.getConstRegister()); 1964 } 1965 } 1966 1967 ofShld_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & op2,const triton::ast::SharedAbstractNode & op3,bool vol)1968 void x86Semantics::ofShld_s(triton::arch::Instruction& inst, 1969 const triton::engines::symbolic::SharedSymbolicExpression& parent, 1970 triton::arch::OperandWrapper& dst, 1971 const triton::ast::SharedAbstractNode& op1, 1972 const triton::ast::SharedAbstractNode& op2, 1973 const triton::ast::SharedAbstractNode& op3, 1974 bool vol) { 1975 1976 auto bvSize = dst.getBitSize(); 1977 auto bv1Size = op1->getBitvectorSize(); 1978 auto bv2Size = op2->getBitvectorSize(); 1979 auto bv3Size = op3->getBitvectorSize(); 1980 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 1981 1982 /* 1983 * Create the semantic. 1984 * of = MSB(rol(op3, concat(op2,op1))) ^ MSB(op1); if op3 == 1 1985 */ 1986 auto node = this->astCtxt->ite( 1987 this->astCtxt->equal( 1988 this->astCtxt->zx(bvSize - bv3Size, op3), 1989 this->astCtxt->bv(1, bvSize)), 1990 this->astCtxt->bvxor( 1991 this->astCtxt->extract( 1992 bvSize-1, bvSize-1, 1993 this->astCtxt->bvrol( 1994 this->astCtxt->concat(op2, op1), 1995 this->astCtxt->zx(((bv1Size + bv2Size) - bv3Size), op3) 1996 ) 1997 ), 1998 this->astCtxt->extract(bvSize-1, bvSize-1, op1) 1999 ), 2000 this->symbolicEngine->getOperandAst(of) 2001 ); 2002 2003 /* Create the symbolic expression */ 2004 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag"); 2005 2006 if (op3->evaluate()) { 2007 /* Spread the taint from the parent to the child */ 2008 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted); 2009 } 2010 else { 2011 inst.removeWrittenRegister(of.getConstRegister()); 2012 } 2013 } 2014 2015 ofShr_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & op2,bool vol)2016 void x86Semantics::ofShr_s(triton::arch::Instruction& inst, 2017 const triton::engines::symbolic::SharedSymbolicExpression& parent, 2018 triton::arch::OperandWrapper& dst, 2019 const triton::ast::SharedAbstractNode& op1, 2020 const triton::ast::SharedAbstractNode& op2, 2021 bool vol) { 2022 2023 auto bvSize = dst.getBitSize(); 2024 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 2025 2026 /* 2027 * Create the semantic. 2028 * of = ((op1 >> (bvSize - 1)) & 1) if op2 == 1 2029 */ 2030 auto node = this->astCtxt->ite( 2031 this->astCtxt->equal( 2032 op2, 2033 this->astCtxt->bv(1, bvSize)), 2034 this->astCtxt->extract(0, 0, this->astCtxt->bvlshr(op1, this->astCtxt->bvsub(this->astCtxt->bv(bvSize, bvSize), this->astCtxt->bv(1, bvSize)))), 2035 this->symbolicEngine->getOperandAst(of) 2036 ); 2037 2038 /* Create the symbolic expression */ 2039 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag"); 2040 2041 if (op2->evaluate()) { 2042 /* Spread the taint from the parent to the child */ 2043 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted); 2044 } 2045 else { 2046 inst.removeWrittenRegister(of.getConstRegister()); 2047 } 2048 } 2049 2050 ofShrd_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & op2,const triton::ast::SharedAbstractNode & op3,bool vol)2051 void x86Semantics::ofShrd_s(triton::arch::Instruction& inst, 2052 const triton::engines::symbolic::SharedSymbolicExpression& parent, 2053 triton::arch::OperandWrapper& dst, 2054 const triton::ast::SharedAbstractNode& op1, 2055 const triton::ast::SharedAbstractNode& op2, 2056 const triton::ast::SharedAbstractNode& op3, 2057 bool vol) { 2058 2059 auto bvSize = dst.getBitSize(); 2060 auto bv1Size = op1->getBitvectorSize(); 2061 auto bv2Size = op2->getBitvectorSize(); 2062 auto bv3Size = op3->getBitvectorSize(); 2063 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 2064 2065 /* 2066 * Create the semantic. 2067 * of = MSB(ror(op3, concat(op2,op1))) ^ MSB(op1); if op3 == 1 2068 */ 2069 auto node = this->astCtxt->ite( 2070 this->astCtxt->equal( 2071 this->astCtxt->zx(bvSize - op3->getBitvectorSize(), op3), 2072 this->astCtxt->bv(1, bvSize)), 2073 this->astCtxt->bvxor( 2074 this->astCtxt->extract( 2075 bvSize - 1, bvSize - 1, 2076 this->astCtxt->bvror( 2077 this->astCtxt->concat(op2, op1), 2078 this->astCtxt->zx(((bv1Size + bv2Size) - bv3Size), op3) 2079 ) 2080 ), 2081 this->astCtxt->extract(dst.getBitSize()-1, dst.getBitSize()-1, op1) 2082 ), 2083 this->symbolicEngine->getOperandAst(of) 2084 ); 2085 2086 /* Create the symbolic expression */ 2087 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, of.getConstRegister(), "Overflow flag"); 2088 2089 if (op3->evaluate()) { 2090 /* Spread the taint from the parent to the child */ 2091 expr->isTainted = this->taintEngine->setTaintRegister(of.getConstRegister(), parent->isTainted); 2092 } 2093 else { 2094 inst.removeWrittenRegister(of.getConstRegister()); 2095 } 2096 } 2097 2098 ofSub_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & op2,bool vol)2099 void x86Semantics::ofSub_s(triton::arch::Instruction& inst, 2100 const triton::engines::symbolic::SharedSymbolicExpression& parent, 2101 triton::arch::OperandWrapper& dst, 2102 const triton::ast::SharedAbstractNode& op1, 2103 const triton::ast::SharedAbstractNode& op2, 2104 bool vol) { 2105 2106 auto bvSize = dst.getBitSize(); 2107 auto low = vol ? 0 : dst.getLow(); 2108 auto high = vol ? bvSize-1 : dst.getHigh(); 2109 2110 /* 2111 * Create the semantic. 2112 * of = high:bool((op1 ^ op2) & (op1 ^ regDst)) 2113 */ 2114 auto node = this->astCtxt->extract(bvSize-1, bvSize-1, 2115 this->astCtxt->bvand( 2116 this->astCtxt->bvxor(op1, op2), 2117 this->astCtxt->bvxor(op1, this->astCtxt->extract(high, low, this->astCtxt->reference(parent))) 2118 ) 2119 ); 2120 2121 /* Create the symbolic expression */ 2122 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_OF), "Overflow flag"); 2123 2124 /* Spread the taint from the parent to the child */ 2125 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_OF), parent->isTainted); 2126 } 2127 2128 pf_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,bool vol)2129 void x86Semantics::pf_s(triton::arch::Instruction& inst, 2130 const triton::engines::symbolic::SharedSymbolicExpression& parent, 2131 triton::arch::OperandWrapper& dst, 2132 bool vol) { 2133 2134 auto low = vol ? 0 : dst.getLow(); 2135 auto high = vol ? triton::bitsize::byte-1 : !low ? triton::bitsize::byte-1 : triton::bitsize::word-1; 2136 2137 /* 2138 * Create the semantics. 2139 * 2140 * pf is set to one if there is an even number of bit set to 1 in the least 2141 * significant byte of the result. 2142 */ 2143 auto node = this->astCtxt->bv(1, 1); 2144 for (triton::uint32 counter = 0; counter <= triton::bitsize::byte-1; counter++) { 2145 node = this->astCtxt->bvxor( 2146 node, 2147 this->astCtxt->extract(0, 0, 2148 this->astCtxt->bvlshr( 2149 this->astCtxt->extract(high, low, this->astCtxt->reference(parent)), 2150 this->astCtxt->bv(counter, triton::bitsize::byte) 2151 ) 2152 ) 2153 ); 2154 } 2155 2156 /* Create the symbolic expression */ 2157 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_PF), "Parity flag"); 2158 2159 /* Spread the taint from the parent to the child */ 2160 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_PF), parent->isTainted); 2161 } 2162 2163 pfShl_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op2,bool vol)2164 void x86Semantics::pfShl_s(triton::arch::Instruction& inst, 2165 const triton::engines::symbolic::SharedSymbolicExpression& parent, 2166 triton::arch::OperandWrapper& dst, 2167 const triton::ast::SharedAbstractNode& op2, 2168 bool vol) { 2169 2170 auto bvSize = dst.getBitSize(); 2171 auto low = vol ? 0 : dst.getLow(); 2172 auto high = vol ? triton::bitsize::byte-1 : !low ? triton::bitsize::byte-1 : triton::bitsize::word-1; 2173 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF)); 2174 2175 /* 2176 * Create the semantics. 2177 * pf if op2 != 0 2178 */ 2179 auto node1 = this->astCtxt->bv(1, 1); 2180 for (triton::uint32 counter = 0; counter <= triton::bitsize::byte-1; counter++) { 2181 node1 = this->astCtxt->bvxor( 2182 node1, 2183 this->astCtxt->extract(0, 0, 2184 this->astCtxt->bvlshr( 2185 this->astCtxt->extract(high, low, this->astCtxt->reference(parent)), 2186 this->astCtxt->bv(counter, triton::bitsize::byte) 2187 ) 2188 ) 2189 ); 2190 } 2191 2192 auto node2 = this->astCtxt->ite( 2193 this->astCtxt->equal(this->astCtxt->zx(bvSize - op2->getBitvectorSize(), op2), this->astCtxt->bv(0, bvSize)), 2194 this->symbolicEngine->getOperandAst(pf), 2195 node1 2196 ); 2197 2198 /* Create the symbolic expression */ 2199 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, pf.getConstRegister(), "Parity flag"); 2200 2201 if (op2->evaluate()) { 2202 /* Spread the taint from the parent to the child */ 2203 expr->isTainted = this->taintEngine->setTaintRegister(pf.getConstRegister(), parent->isTainted); 2204 } 2205 else { 2206 inst.removeWrittenRegister(pf.getConstRegister()); 2207 } 2208 } 2209 2210 sf_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,bool vol)2211 void x86Semantics::sf_s(triton::arch::Instruction& inst, 2212 const triton::engines::symbolic::SharedSymbolicExpression& parent, 2213 triton::arch::OperandWrapper& dst, 2214 bool vol) { 2215 2216 auto bvSize = dst.getBitSize(); 2217 auto high = vol ? bvSize-1 : dst.getHigh(); 2218 2219 /* 2220 * Create the semantic. 2221 * sf = high:bool(regDst) 2222 */ 2223 auto node = this->astCtxt->extract(high, high, this->astCtxt->reference(parent)); 2224 2225 /* Create the symbolic expression */ 2226 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_SF), "Sign flag"); 2227 2228 /* Spread the taint from the parent to the child */ 2229 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_SF), parent->isTainted); 2230 } 2231 2232 sfShl_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op2,bool vol)2233 void x86Semantics::sfShl_s(triton::arch::Instruction& inst, 2234 const triton::engines::symbolic::SharedSymbolicExpression& parent, 2235 triton::arch::OperandWrapper& dst, 2236 const triton::ast::SharedAbstractNode& op2, 2237 bool vol) { 2238 2239 auto bvSize = dst.getBitSize(); 2240 auto high = vol ? bvSize-1 : dst.getHigh(); 2241 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 2242 2243 /* 2244 * Create the semantic. 2245 * sf if op2 != 0 2246 */ 2247 auto node = this->astCtxt->ite( 2248 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize)), 2249 this->symbolicEngine->getOperandAst(sf), 2250 this->astCtxt->extract(high, high, this->astCtxt->reference(parent)) 2251 ); 2252 2253 /* Create the symbolic expression */ 2254 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, sf.getConstRegister(), "Sign flag"); 2255 2256 if (op2->evaluate()) { 2257 /* Spread the taint from the parent to the child */ 2258 expr->isTainted = this->taintEngine->setTaintRegister(sf.getConstRegister(), parent->isTainted); 2259 } 2260 else { 2261 inst.removeWrittenRegister(sf.getConstRegister()); 2262 } 2263 } 2264 2265 sfShld_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & op2,const triton::ast::SharedAbstractNode & op3,bool vol)2266 void x86Semantics::sfShld_s(triton::arch::Instruction& inst, 2267 const triton::engines::symbolic::SharedSymbolicExpression& parent, 2268 triton::arch::OperandWrapper& dst, 2269 const triton::ast::SharedAbstractNode& op1, 2270 const triton::ast::SharedAbstractNode& op2, 2271 const triton::ast::SharedAbstractNode& op3, 2272 bool vol) { 2273 2274 auto bvSize = dst.getBitSize(); 2275 auto bv1Size = op1->getBitvectorSize(); 2276 auto bv2Size = op2->getBitvectorSize(); 2277 auto bv3Size = op3->getBitvectorSize(); 2278 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 2279 2280 /* 2281 * Create the semantic. 2282 * MSB(rol(op3, concat(op2,op1))) if op3 != 0 2283 */ 2284 auto node = this->astCtxt->ite( 2285 this->astCtxt->equal(op3, this->astCtxt->bv(0, bv3Size)), 2286 this->symbolicEngine->getOperandAst(sf), 2287 this->astCtxt->extract( 2288 bvSize-1, bvSize-1, 2289 this->astCtxt->bvrol( 2290 this->astCtxt->concat(op2, op1), 2291 this->astCtxt->zx(((bv1Size + bv2Size) - bv3Size), op3) 2292 ) 2293 ) 2294 ); 2295 2296 /* Create the symbolic expression */ 2297 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, sf.getConstRegister(), "Sign flag"); 2298 2299 if (op3->evaluate()) { 2300 /* Spread the taint from the parent to the child */ 2301 expr->isTainted = this->taintEngine->setTaintRegister(sf.getConstRegister(), parent->isTainted); 2302 } 2303 else { 2304 inst.removeWrittenRegister(sf.getConstRegister()); 2305 } 2306 } 2307 2308 sfShrd_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op1,const triton::ast::SharedAbstractNode & op2,const triton::ast::SharedAbstractNode & op3,bool vol)2309 void x86Semantics::sfShrd_s(triton::arch::Instruction& inst, 2310 const triton::engines::symbolic::SharedSymbolicExpression& parent, 2311 triton::arch::OperandWrapper& dst, 2312 const triton::ast::SharedAbstractNode& op1, 2313 const triton::ast::SharedAbstractNode& op2, 2314 const triton::ast::SharedAbstractNode& op3, 2315 bool vol) { 2316 2317 auto bvSize = dst.getBitSize(); 2318 auto bv1Size = op1->getBitvectorSize(); 2319 auto bv2Size = op2->getBitvectorSize(); 2320 auto bv3Size = op3->getBitvectorSize(); 2321 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 2322 2323 /* 2324 * Create the semantic. 2325 * MSB(ror(op3, concat(op2,op1))) if op3 != 0 2326 */ 2327 auto node = this->astCtxt->ite( 2328 this->astCtxt->equal(op3, this->astCtxt->bv(0, bv3Size)), 2329 this->symbolicEngine->getOperandAst(sf), 2330 this->astCtxt->extract( 2331 bvSize - 1, bvSize - 1, 2332 this->astCtxt->bvror( 2333 this->astCtxt->concat(op2, op1), 2334 this->astCtxt->zx(((bv1Size + bv2Size) - bv3Size), op3) 2335 ) 2336 ) 2337 ); 2338 2339 /* Create the symbolic expression */ 2340 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, sf.getConstRegister(), "Sign flag"); 2341 2342 if (op3->evaluate()) { 2343 /* Spread the taint from the parent to the child */ 2344 expr->isTainted = this->taintEngine->setTaintRegister(sf.getConstRegister(), parent->isTainted); 2345 } 2346 else { 2347 inst.removeWrittenRegister(sf.getConstRegister()); 2348 } 2349 } 2350 2351 zf_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,bool vol)2352 void x86Semantics::zf_s(triton::arch::Instruction& inst, 2353 const triton::engines::symbolic::SharedSymbolicExpression& parent, 2354 triton::arch::OperandWrapper& dst, 2355 bool vol) { 2356 2357 auto bvSize = dst.getBitSize(); 2358 auto low = vol ? 0 : dst.getLow(); 2359 auto high = vol ? bvSize-1 : dst.getHigh(); 2360 2361 /* 2362 * Create the semantic. 2363 * zf = 0 == regDst 2364 */ 2365 auto node = this->astCtxt->ite( 2366 this->astCtxt->equal( 2367 this->astCtxt->extract(high, low, this->astCtxt->reference(parent)), 2368 this->astCtxt->bv(0, bvSize) 2369 ), 2370 this->astCtxt->bv(1, 1), 2371 this->astCtxt->bv(0, 1) 2372 ); 2373 2374 /* Create the symbolic expression */ 2375 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_ZF), "Zero flag"); 2376 2377 /* Spread the taint from the parent to the child */ 2378 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_ZF), parent->isTainted); 2379 } 2380 2381 zfBsf_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & src,const triton::ast::SharedAbstractNode & op2,bool vol)2382 void x86Semantics::zfBsf_s(triton::arch::Instruction& inst, 2383 const triton::engines::symbolic::SharedSymbolicExpression& parent, 2384 triton::arch::OperandWrapper& src, 2385 const triton::ast::SharedAbstractNode& op2, 2386 bool vol) { 2387 2388 /* 2389 * Create the semantic. 2390 * zf = 1 if op2 == 0 else 0 2391 */ 2392 auto node = this->astCtxt->ite( 2393 this->astCtxt->equal(op2, this->astCtxt->bv(0, src.getBitSize())), 2394 this->astCtxt->bvtrue(), 2395 this->astCtxt->bvfalse() 2396 ); 2397 2398 /* Create the symbolic expression */ 2399 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_ZF), "Zero flag"); 2400 2401 /* Spread the taint from the parent to the child */ 2402 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getRegister(ID_REG_X86_ZF), parent->isTainted); 2403 } 2404 2405 zfShl_s(triton::arch::Instruction & inst,const triton::engines::symbolic::SharedSymbolicExpression & parent,triton::arch::OperandWrapper & dst,const triton::ast::SharedAbstractNode & op2,bool vol)2406 void x86Semantics::zfShl_s(triton::arch::Instruction& inst, 2407 const triton::engines::symbolic::SharedSymbolicExpression& parent, 2408 triton::arch::OperandWrapper& dst, 2409 const triton::ast::SharedAbstractNode& op2, 2410 bool vol) { 2411 2412 auto bvSize = dst.getBitSize(); 2413 auto low = vol ? 0 : dst.getLow(); 2414 auto high = vol ? bvSize-1 : dst.getHigh(); 2415 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 2416 2417 /* 2418 * Create the semantic. 2419 * zf if op2 != 0 2420 */ 2421 auto node = this->astCtxt->ite( 2422 this->astCtxt->equal(this->astCtxt->zx(bvSize - op2->getBitvectorSize(), op2), this->astCtxt->bv(0, bvSize)), 2423 this->symbolicEngine->getOperandAst(zf), 2424 this->astCtxt->ite( 2425 this->astCtxt->equal( 2426 this->astCtxt->extract(high, low, this->astCtxt->reference(parent)), 2427 this->astCtxt->bv(0, bvSize) 2428 ), 2429 this->astCtxt->bv(1, 1), 2430 this->astCtxt->bv(0, 1) 2431 ) 2432 ); 2433 2434 /* Create the symbolic expression */ 2435 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, zf.getConstRegister(), "Zero flag"); 2436 2437 if (op2->evaluate()) { 2438 /* Spread the taint from the parent to the child */ 2439 expr->isTainted = this->taintEngine->setTaintRegister(zf.getConstRegister(), parent->isTainted); 2440 } 2441 else { 2442 inst.removeWrittenRegister(zf.getConstRegister()); 2443 } 2444 } 2445 2446 aaa_s(triton::arch::Instruction & inst)2447 void x86Semantics::aaa_s(triton::arch::Instruction& inst) { 2448 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL)); 2449 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AH)); 2450 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF)); 2451 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX)); 2452 auto dsttmp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL)); 2453 2454 /* Create symbolic operands */ 2455 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 2456 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 2457 auto op3 = this->symbolicEngine->getOperandAst(inst, src3); 2458 2459 /* Create the semantics */ 2460 auto node = this->astCtxt->ite( 2461 // if 2462 this->astCtxt->lor( 2463 this->astCtxt->bvugt( 2464 this->astCtxt->bvand(op1, this->astCtxt->bv(0xf, src1.getBitSize())), 2465 this->astCtxt->bv(9, src1.getBitSize()) 2466 ), 2467 this->astCtxt->equal(op3, this->astCtxt->bvtrue()) 2468 ), 2469 // then 2470 this->astCtxt->concat( 2471 this->astCtxt->bvadd(op2, this->astCtxt->bv(1, src2.getBitSize())), 2472 this->astCtxt->bvand( 2473 this->astCtxt->bvadd(op1, this->astCtxt->bv(6, src1.getBitSize())), 2474 this->astCtxt->bv(0xf, src1.getBitSize()) 2475 ) 2476 ), 2477 // else 2478 this->astCtxt->concat( 2479 op2, 2480 this->astCtxt->bvand(op1, this->astCtxt->bv(0xf, src1.getBitSize())) 2481 ) 2482 ); 2483 2484 /* Create symbolic expression */ 2485 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "AAA operation"); 2486 2487 /* Spread taint */ 2488 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 2489 2490 /* Update symbolic flags */ 2491 this->afAaa_s(inst, expr, dsttmp, op1, op3); 2492 this->cfAaa_s(inst, expr, dsttmp, op1, op3); 2493 2494 /* Tag undefined flags */ 2495 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 2496 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF)); 2497 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF)); 2498 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF)); 2499 2500 /* Update the symbolic control flow */ 2501 this->controlFlow_s(inst); 2502 } 2503 2504 aad_s(triton::arch::Instruction & inst)2505 void x86Semantics::aad_s(triton::arch::Instruction& inst) { 2506 auto src1 = triton::arch::OperandWrapper(triton::arch::Immediate(0x0a, triton::size::byte)); /* D5 0A */ 2507 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL)); 2508 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AH)); 2509 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX)); 2510 auto dsttmp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL)); 2511 2512 /* D5 ib */ 2513 if (inst.operands.size() == 1) 2514 src1 = inst.operands[0]; 2515 2516 /* Create symbolic operands */ 2517 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 2518 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 2519 auto op3 = this->symbolicEngine->getOperandAst(inst, src3); 2520 2521 /* Create the semantics */ 2522 auto node = this->astCtxt->zx( 2523 triton::bitsize::byte, 2524 this->astCtxt->bvadd( 2525 op2, 2526 this->astCtxt->bvmul(op3, op1) 2527 ) 2528 ); 2529 2530 /* Create symbolic expression */ 2531 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "AAD operation"); 2532 2533 /* Spread taint */ 2534 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 2535 2536 /* Update symbolic flags */ 2537 this->pf_s(inst, expr, dsttmp); 2538 this->sf_s(inst, expr, dsttmp); 2539 this->zf_s(inst, expr, dsttmp); 2540 2541 /* Tag undefined flags */ 2542 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 2543 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF)); 2544 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 2545 2546 /* Update the symbolic control flow */ 2547 this->controlFlow_s(inst); 2548 } 2549 2550 aam_s(triton::arch::Instruction & inst)2551 void x86Semantics::aam_s(triton::arch::Instruction& inst) { 2552 auto src1 = triton::arch::OperandWrapper(triton::arch::Immediate(0x0a, triton::size::byte)); /* D4 0A */ 2553 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL)); 2554 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX)); 2555 auto dsttmp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL)); 2556 2557 /* D4 ib */ 2558 if (inst.operands.size() == 1) 2559 src1 = inst.operands[0]; 2560 2561 /* Create symbolic operands */ 2562 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 2563 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 2564 2565 /* Create the semantics */ 2566 auto node = this->astCtxt->concat( 2567 this->astCtxt->bvudiv(op2, op1), 2568 this->astCtxt->bvurem(op2, op1) 2569 ); 2570 2571 /* Create symbolic expression */ 2572 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "AAM operation"); 2573 2574 /* Spread taint */ 2575 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 2576 2577 /* Update symbolic flags */ 2578 this->pf_s(inst, expr, dsttmp); 2579 this->sf_s(inst, expr, dsttmp); 2580 this->zf_s(inst, expr, dsttmp); 2581 2582 /* Tag undefined flags */ 2583 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 2584 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF)); 2585 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 2586 2587 /* Update the symbolic control flow */ 2588 this->controlFlow_s(inst); 2589 } 2590 2591 aas_s(triton::arch::Instruction & inst)2592 void x86Semantics::aas_s(triton::arch::Instruction& inst) { 2593 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL)); 2594 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AH)); 2595 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF)); 2596 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX)); 2597 auto dsttmp = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL)); 2598 2599 /* Create symbolic operands */ 2600 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 2601 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 2602 auto op3 = this->symbolicEngine->getOperandAst(inst, src3); 2603 2604 /* Create the semantics */ 2605 auto node = this->astCtxt->ite( 2606 // if 2607 this->astCtxt->lor( 2608 this->astCtxt->bvugt( 2609 this->astCtxt->bvand(op1, this->astCtxt->bv(0xf, src1.getBitSize())), 2610 this->astCtxt->bv(9, src1.getBitSize()) 2611 ), 2612 this->astCtxt->equal(op3, this->astCtxt->bvtrue()) 2613 ), 2614 // then 2615 this->astCtxt->concat( 2616 this->astCtxt->bvsub(op2, this->astCtxt->bv(1, src2.getBitSize())), 2617 this->astCtxt->bvand( 2618 this->astCtxt->bvsub(op1, this->astCtxt->bv(6, src1.getBitSize())), 2619 this->astCtxt->bv(0xf, src1.getBitSize()) 2620 ) 2621 ), 2622 // else 2623 this->astCtxt->concat( 2624 op2, 2625 this->astCtxt->bvand(op1, this->astCtxt->bv(0xf, src1.getBitSize())) 2626 ) 2627 ); 2628 2629 /* Create symbolic expression */ 2630 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "AAS operation"); 2631 2632 /* Spread taint */ 2633 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 2634 2635 /* Update symbolic flags */ 2636 this->afAaa_s(inst, expr, dsttmp, op1, op3); 2637 this->cfAaa_s(inst, expr, dsttmp, op1, op3); 2638 2639 /* Tag undefined flags */ 2640 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 2641 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF)); 2642 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF)); 2643 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF)); 2644 2645 /* Update the symbolic control flow */ 2646 this->controlFlow_s(inst); 2647 } 2648 2649 adc_s(triton::arch::Instruction & inst)2650 void x86Semantics::adc_s(triton::arch::Instruction& inst) { 2651 auto& dst = inst.operands[0]; 2652 auto& src = inst.operands[1]; 2653 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 2654 2655 /* Create symbolic operands */ 2656 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 2657 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 2658 auto op3 = this->symbolicEngine->getOperandAst(inst, cf); 2659 2660 /* Create the semantics */ 2661 auto node = this->astCtxt->bvadd(this->astCtxt->bvadd(op1, op2), this->astCtxt->zx(dst.getBitSize()-1, op3)); 2662 2663 /* Create symbolic expression */ 2664 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ADC operation"); 2665 2666 /* Spread taint */ 2667 expr->isTainted = this->taintEngine->taintUnion(dst, src); 2668 expr->isTainted = this->taintEngine->taintUnion(dst, cf); 2669 2670 /* Update symbolic flags */ 2671 this->af_s(inst, expr, dst, op1, op2); 2672 this->cfAdd_s(inst, expr, dst, op1, op2); 2673 this->ofAdd_s(inst, expr, dst, op1, op2); 2674 this->pf_s(inst, expr, dst); 2675 this->sf_s(inst, expr, dst); 2676 this->zf_s(inst, expr, dst); 2677 2678 /* Update the symbolic control flow */ 2679 this->controlFlow_s(inst); 2680 } 2681 2682 adcx_s(triton::arch::Instruction & inst)2683 void x86Semantics::adcx_s(triton::arch::Instruction& inst) { 2684 auto& dst = inst.operands[0]; 2685 auto& src = inst.operands[1]; 2686 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 2687 2688 /* Create symbolic operands */ 2689 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 2690 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 2691 auto op3 = this->symbolicEngine->getOperandAst(inst, cf); 2692 2693 /* Create the semantics */ 2694 auto node = this->astCtxt->bvadd(this->astCtxt->bvadd(op1, op2), this->astCtxt->zx(dst.getBitSize()-1, op3)); 2695 2696 /* Create symbolic expression */ 2697 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ADCX operation"); 2698 2699 /* Spread taint */ 2700 expr->isTainted = this->taintEngine->taintUnion(dst, src); 2701 expr->isTainted = this->taintEngine->taintUnion(dst, cf); 2702 2703 /* Update symbolic flags */ 2704 this->cfAdd_s(inst, expr, dst, op1, op2); 2705 2706 /* Update the symbolic control flow */ 2707 this->controlFlow_s(inst); 2708 } 2709 2710 add_s(triton::arch::Instruction & inst)2711 void x86Semantics::add_s(triton::arch::Instruction& inst) { 2712 auto& dst = inst.operands[0]; 2713 auto& src = inst.operands[1]; 2714 2715 /* Create symbolic operands */ 2716 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 2717 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 2718 2719 /* Create the semantics */ 2720 auto node = this->astCtxt->bvadd(op1, op2); 2721 2722 /* Create symbolic expression */ 2723 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ADD operation"); 2724 2725 /* Spread taint */ 2726 expr->isTainted = this->taintEngine->taintUnion(dst, src); 2727 2728 /* Update symbolic flags */ 2729 this->af_s(inst, expr, dst, op1, op2); 2730 this->cfAdd_s(inst, expr, dst, op1, op2); 2731 this->ofAdd_s(inst, expr, dst, op1, op2); 2732 this->pf_s(inst, expr, dst); 2733 this->sf_s(inst, expr, dst); 2734 this->zf_s(inst, expr, dst); 2735 2736 /* Update the symbolic control flow */ 2737 this->controlFlow_s(inst); 2738 } 2739 2740 and_s(triton::arch::Instruction & inst)2741 void x86Semantics::and_s(triton::arch::Instruction& inst) { 2742 auto& dst = inst.operands[0]; 2743 auto& src = inst.operands[1]; 2744 2745 /* Create symbolic operands */ 2746 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 2747 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 2748 2749 /* Create the semantics */ 2750 auto node = this->astCtxt->bvand(op1, op2); 2751 2752 /* Create symbolic expression */ 2753 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "AND operation"); 2754 2755 /* Spread taint */ 2756 expr->isTainted = this->taintEngine->taintUnion(dst, src); 2757 2758 /* Update symbolic flags */ 2759 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag"); 2760 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag"); 2761 this->pf_s(inst, expr, dst); 2762 this->sf_s(inst, expr, dst); 2763 this->zf_s(inst, expr, dst); 2764 2765 /* Tag undefined flags */ 2766 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 2767 2768 /* Update the symbolic control flow */ 2769 this->controlFlow_s(inst); 2770 } 2771 2772 andn_s(triton::arch::Instruction & inst)2773 void x86Semantics::andn_s(triton::arch::Instruction& inst) { 2774 auto& dst = inst.operands[0]; 2775 auto& src1 = inst.operands[1]; 2776 auto& src2 = inst.operands[2]; 2777 2778 /* Create symbolic operands */ 2779 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 2780 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 2781 2782 /* Create the semantics */ 2783 auto node = this->astCtxt->bvand(this->astCtxt->bvnot(op2), op3); 2784 2785 /* Create symbolic expression */ 2786 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ANDN operation"); 2787 2788 /* Spread taint */ 2789 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2); 2790 2791 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag"); 2792 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag"); 2793 this->sf_s(inst, expr, dst); 2794 this->zf_s(inst, expr, dst); 2795 2796 /* Update the symbolic control flow */ 2797 this->controlFlow_s(inst); 2798 } 2799 2800 andnpd_s(triton::arch::Instruction & inst)2801 void x86Semantics::andnpd_s(triton::arch::Instruction& inst) { 2802 auto& dst = inst.operands[0]; 2803 auto& src = inst.operands[1]; 2804 2805 /* Create symbolic operands */ 2806 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 2807 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 2808 2809 /* Create the semantics */ 2810 auto node = this->astCtxt->bvand(this->astCtxt->bvnot(op1), op2); 2811 2812 /* Create symbolic expression */ 2813 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ANDNPD operation"); 2814 2815 /* Spread taint */ 2816 expr->isTainted = this->taintEngine->taintUnion(dst, src); 2817 2818 /* Update the symbolic control flow */ 2819 this->controlFlow_s(inst); 2820 } 2821 2822 andnps_s(triton::arch::Instruction & inst)2823 void x86Semantics::andnps_s(triton::arch::Instruction& inst) { 2824 auto& dst = inst.operands[0]; 2825 auto& src = inst.operands[1]; 2826 2827 /* Create symbolic operands */ 2828 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 2829 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 2830 2831 /* Create the semantics */ 2832 auto node = this->astCtxt->bvand(this->astCtxt->bvnot(op1), op2); 2833 2834 /* Create symbolic expression */ 2835 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ANDNPS operation"); 2836 2837 /* Spread taint */ 2838 expr->isTainted = this->taintEngine->taintUnion(dst, src); 2839 2840 /* Update the symbolic control flow */ 2841 this->controlFlow_s(inst); 2842 } 2843 2844 andpd_s(triton::arch::Instruction & inst)2845 void x86Semantics::andpd_s(triton::arch::Instruction& inst) { 2846 auto& dst = inst.operands[0]; 2847 auto& src = inst.operands[1]; 2848 2849 /* Create symbolic operands */ 2850 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 2851 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 2852 2853 /* Create the semantics */ 2854 auto node = this->astCtxt->bvand(op1, op2); 2855 2856 /* Create symbolic expression */ 2857 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ANDPD operation"); 2858 2859 /* Spread taint */ 2860 expr->isTainted = this->taintEngine->taintUnion(dst, src); 2861 2862 /* Update the symbolic control flow */ 2863 this->controlFlow_s(inst); 2864 } 2865 2866 andps_s(triton::arch::Instruction & inst)2867 void x86Semantics::andps_s(triton::arch::Instruction& inst) { 2868 auto& dst = inst.operands[0]; 2869 auto& src = inst.operands[1]; 2870 2871 /* Create symbolic operands */ 2872 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 2873 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 2874 2875 /* Create the semantics */ 2876 auto node = this->astCtxt->bvand(op1, op2); 2877 2878 /* Create symbolic expression */ 2879 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ANDPS operation"); 2880 2881 /* Spread taint */ 2882 expr->isTainted = this->taintEngine->taintUnion(dst, src); 2883 2884 /* Update the symbolic control flow */ 2885 this->controlFlow_s(inst); 2886 } 2887 2888 bextr_s(triton::arch::Instruction & inst)2889 void x86Semantics::bextr_s(triton::arch::Instruction& inst) { 2890 auto& dst = inst.operands[0]; 2891 auto& src1 = inst.operands[1]; 2892 auto& src2 = inst.operands[2]; 2893 2894 /* Create symbolic operands */ 2895 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 2896 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 2897 2898 /* Create the semantics */ 2899 auto node = this->astCtxt->bvand( 2900 this->astCtxt->bvlshr( 2901 op1, 2902 this->astCtxt->zx(src1.getBitSize() - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2)) 2903 ), 2904 this->astCtxt->bvsub( 2905 this->astCtxt->bvshl( 2906 this->astCtxt->bv(1, src1.getBitSize()), 2907 this->astCtxt->zx(src1.getBitSize() - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2)) 2908 ), 2909 this->astCtxt->bv(1, src1.getBitSize()) 2910 ) 2911 ); 2912 2913 /* Create symbolic expression */ 2914 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "BEXTR operation"); 2915 2916 /* Spread taint */ 2917 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2); 2918 2919 /* Update symbolic flags */ 2920 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag"); 2921 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag"); 2922 this->zf_s(inst, expr, dst); 2923 2924 /* Update the symbolic control flow */ 2925 this->controlFlow_s(inst); 2926 } 2927 2928 blsi_s(triton::arch::Instruction & inst)2929 void x86Semantics::blsi_s(triton::arch::Instruction& inst) { 2930 auto& dst = inst.operands[0]; 2931 auto& src = inst.operands[1]; 2932 2933 /* Create symbolic operands */ 2934 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 2935 2936 /* Create the semantics */ 2937 auto node = this->astCtxt->bvand(this->astCtxt->bvneg(op1), op1); 2938 2939 /* Create symbolic expression */ 2940 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "BLSI operation"); 2941 2942 /* Spread taint */ 2943 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 2944 2945 /* Update symbolic flags */ 2946 this->cfBlsi_s(inst, expr, src, op1); 2947 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag"); 2948 this->sf_s(inst, expr, dst); 2949 this->zf_s(inst, expr, dst); 2950 2951 /* Update the symbolic control flow */ 2952 this->controlFlow_s(inst); 2953 } 2954 2955 blsmsk_s(triton::arch::Instruction & inst)2956 void x86Semantics::blsmsk_s(triton::arch::Instruction& inst) { 2957 auto& dst = inst.operands[0]; 2958 auto& src = inst.operands[1]; 2959 2960 /* Create symbolic operands */ 2961 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 2962 2963 /* Create the semantics */ 2964 auto node = this->astCtxt->bvxor( 2965 this->astCtxt->bvsub(op1, this->astCtxt->bv(1, src.getBitSize())), 2966 op1 2967 ); 2968 2969 /* Create symbolic expression */ 2970 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "BLSMSK operation"); 2971 2972 /* Spread taint */ 2973 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 2974 2975 /* Update symbolic flags */ 2976 this->cfBlsmsk_s(inst, expr, src, op1); 2977 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag"); 2978 this->sf_s(inst, expr, dst); 2979 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_ZF), "Clears zero flag"); 2980 2981 /* Update the symbolic control flow */ 2982 this->controlFlow_s(inst); 2983 } 2984 2985 blsr_s(triton::arch::Instruction & inst)2986 void x86Semantics::blsr_s(triton::arch::Instruction& inst) { 2987 auto& dst = inst.operands[0]; 2988 auto& src = inst.operands[1]; 2989 2990 /* Create symbolic operands */ 2991 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 2992 2993 /* Create the semantics */ 2994 auto node = this->astCtxt->bvand( 2995 this->astCtxt->bvsub(op1, this->astCtxt->bv(1, src.getBitSize())), 2996 op1 2997 ); 2998 2999 /* Create symbolic expression */ 3000 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "BLSR operation"); 3001 3002 /* Spread taint */ 3003 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 3004 3005 /* Update symbolic flags */ 3006 this->cfBlsr_s(inst, expr, src, op1); 3007 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag"); 3008 this->sf_s(inst, expr, dst); 3009 this->zf_s(inst, expr, dst); 3010 3011 /* Update the symbolic control flow */ 3012 this->controlFlow_s(inst); 3013 } 3014 3015 bsf_s(triton::arch::Instruction & inst)3016 void x86Semantics::bsf_s(triton::arch::Instruction& inst) { 3017 auto& dst = inst.operands[0]; 3018 auto& src = inst.operands[1]; 3019 auto bvSize1 = dst.getBitSize(); 3020 auto bvSize2 = src.getBitSize(); 3021 3022 /* Create symbolic operands */ 3023 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 3024 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 3025 3026 /* Create the semantics */ 3027 triton::ast::SharedAbstractNode node = nullptr; 3028 switch (src.getSize()) { 3029 case triton::size::byte: 3030 node = this->astCtxt->ite( 3031 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSF only if op2 != 0 */ 3032 op1, 3033 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1), 3034 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1), 3035 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1), 3036 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1), 3037 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1), 3038 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1), 3039 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1), 3040 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1), 3041 this->astCtxt->bv(0, bvSize1) 3042 )))))))) 3043 ); 3044 break; 3045 case triton::size::word: 3046 node = this->astCtxt->ite( 3047 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSF only if op2 != 0 */ 3048 op1, 3049 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1), 3050 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1), 3051 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1), 3052 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1), 3053 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1), 3054 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1), 3055 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1), 3056 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1), 3057 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1), 3058 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1), 3059 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1), 3060 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1), 3061 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1), 3062 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1), 3063 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1), 3064 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1), 3065 this->astCtxt->bv(0, bvSize1) 3066 )))))))))))))))) 3067 ); 3068 break; 3069 case triton::size::dword: 3070 node = this->astCtxt->ite( 3071 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSF only if op2 != 0 */ 3072 op1, 3073 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1), 3074 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1), 3075 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1), 3076 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1), 3077 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1), 3078 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1), 3079 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1), 3080 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1), 3081 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1), 3082 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1), 3083 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1), 3084 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1), 3085 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1), 3086 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1), 3087 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1), 3088 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1), 3089 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(16, 16, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1), 3090 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(17, 17, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1), 3091 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(18, 18, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1), 3092 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(19, 19, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1), 3093 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(20, 20, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1), 3094 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(21, 21, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1), 3095 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(22, 22, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1), 3096 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(23, 23, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1), 3097 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(24, 24, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1), 3098 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(25, 25, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1), 3099 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(26, 26, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1), 3100 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(27, 27, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1), 3101 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(28, 28, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1), 3102 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(29, 29, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1), 3103 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(30, 30, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1), 3104 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(31, 31, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1), 3105 this->astCtxt->bv(0, bvSize1) 3106 )))))))))))))))))))))))))))))))) 3107 ); 3108 break; 3109 case triton::size::qword: 3110 node = this->astCtxt->ite( 3111 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSF only if op2 != 0 */ 3112 op1, 3113 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1), 3114 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1), 3115 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1), 3116 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1), 3117 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1), 3118 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1), 3119 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1), 3120 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1), 3121 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1), 3122 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1), 3123 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1), 3124 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1), 3125 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1), 3126 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1), 3127 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1), 3128 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1), 3129 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(16, 16, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1), 3130 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(17, 17, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1), 3131 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(18, 18, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1), 3132 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(19, 19, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1), 3133 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(20, 20, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1), 3134 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(21, 21, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1), 3135 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(22, 22, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1), 3136 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(23, 23, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1), 3137 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(24, 24, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1), 3138 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(25, 25, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1), 3139 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(26, 26, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1), 3140 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(27, 27, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1), 3141 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(28, 28, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1), 3142 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(29, 29, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1), 3143 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(30, 30, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1), 3144 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(31, 31, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1), 3145 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(32, 32, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(32, bvSize1), 3146 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(33, 33, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(33, bvSize1), 3147 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(34, 34, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(34, bvSize1), 3148 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(35, 35, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(35, bvSize1), 3149 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(36, 36, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(36, bvSize1), 3150 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(37, 37, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(37, bvSize1), 3151 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(38, 38, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(38, bvSize1), 3152 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(39, 39, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(39, bvSize1), 3153 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(40, 40, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(40, bvSize1), 3154 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(41, 41, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(41, bvSize1), 3155 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(42, 42, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(42, bvSize1), 3156 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(43, 43, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(43, bvSize1), 3157 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(44, 44, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(44, bvSize1), 3158 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(45, 45, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(45, bvSize1), 3159 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(46, 46, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(46, bvSize1), 3160 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(47, 47, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(47, bvSize1), 3161 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(48, 48, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(48, bvSize1), 3162 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(49, 49, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(49, bvSize1), 3163 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(50, 50, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(50, bvSize1), 3164 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(51, 51, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(51, bvSize1), 3165 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(52, 52, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(52, bvSize1), 3166 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(53, 53, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(53, bvSize1), 3167 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(54, 54, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(54, bvSize1), 3168 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(55, 55, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(55, bvSize1), 3169 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(56, 56, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(56, bvSize1), 3170 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(57, 57, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(57, bvSize1), 3171 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(58, 58, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(58, bvSize1), 3172 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(59, 59, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(59, bvSize1), 3173 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(60, 60, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(60, bvSize1), 3174 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(61, 61, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(61, bvSize1), 3175 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(62, 62, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(62, bvSize1), 3176 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(63, 63, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(63, bvSize1), 3177 this->astCtxt->bv(0, bvSize1) 3178 )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) 3179 ); 3180 break; 3181 default: 3182 throw triton::exceptions::Semantics("x86Semantics::bsf_s(): Invalid operand size."); 3183 } 3184 3185 /* Create symbolic expression */ 3186 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "BSF operation"); 3187 3188 /* Spread taint */ 3189 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 3190 3191 /* Update symbolic flags */ 3192 this->zfBsf_s(inst, expr, src, op2); 3193 3194 /* Tag undefined flags */ 3195 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 3196 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF)); 3197 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 3198 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF)); 3199 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF)); 3200 3201 /* Update the symbolic control flow */ 3202 this->controlFlow_s(inst); 3203 } 3204 3205 bsr_s(triton::arch::Instruction & inst)3206 void x86Semantics::bsr_s(triton::arch::Instruction& inst) { 3207 auto& dst = inst.operands[0]; 3208 auto& src = inst.operands[1]; 3209 auto bvSize1 = dst.getBitSize(); 3210 auto bvSize2 = src.getBitSize(); 3211 3212 /* Create symbolic operands */ 3213 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 3214 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 3215 3216 /* Create the semantics */ 3217 triton::ast::SharedAbstractNode node = nullptr; 3218 switch (src.getSize()) { 3219 case triton::size::byte: 3220 node = this->astCtxt->ite( 3221 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSR only if op2 != 0 */ 3222 op1, 3223 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1), 3224 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1), 3225 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1), 3226 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1), 3227 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1), 3228 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1), 3229 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1), 3230 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1), 3231 this->astCtxt->bv(0, bvSize1) 3232 )))))))) 3233 ); 3234 break; 3235 case triton::size::word: 3236 node = this->astCtxt->ite( 3237 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSR only if op2 != 0 */ 3238 op1, 3239 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1), 3240 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1), 3241 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1), 3242 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1), 3243 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1), 3244 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1), 3245 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1), 3246 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1), 3247 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1), 3248 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1), 3249 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1), 3250 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1), 3251 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1), 3252 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1), 3253 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1), 3254 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1), 3255 this->astCtxt->bv(0, bvSize1) 3256 )))))))))))))))) 3257 ); 3258 break; 3259 case triton::size::dword: 3260 node = this->astCtxt->ite( 3261 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSR only if op2 != 0 */ 3262 op1, 3263 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(31, 31, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1), 3264 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(30, 30, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1), 3265 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(29, 29, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1), 3266 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(28, 28, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1), 3267 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(27, 27, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1), 3268 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(26, 26, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1), 3269 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(25, 25, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1), 3270 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(24, 24, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1), 3271 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(23, 23, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1), 3272 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(22, 22, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1), 3273 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(21, 21, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1), 3274 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(20, 20, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1), 3275 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(19, 19, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1), 3276 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(18, 18, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1), 3277 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(17, 17, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1), 3278 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(16, 16, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1), 3279 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1), 3280 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1), 3281 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1), 3282 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1), 3283 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1), 3284 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1), 3285 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1), 3286 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1), 3287 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1), 3288 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1), 3289 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1), 3290 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1), 3291 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1), 3292 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1), 3293 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1), 3294 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1), 3295 this->astCtxt->bv(0, bvSize1) 3296 )))))))))))))))))))))))))))))))) 3297 ); 3298 break; 3299 case triton::size::qword: 3300 node = this->astCtxt->ite( 3301 this->astCtxt->equal(op2, this->astCtxt->bv(0, bvSize2)), /* Apply BSR only if op2 != 0 */ 3302 op1, 3303 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(63, 63, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(63, bvSize1), 3304 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(62, 62, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(62, bvSize1), 3305 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(61, 61, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(61, bvSize1), 3306 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(60, 60, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(60, bvSize1), 3307 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(59, 59, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(59, bvSize1), 3308 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(58, 58, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(58, bvSize1), 3309 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(57, 57, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(57, bvSize1), 3310 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(56, 56, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(56, bvSize1), 3311 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(55, 55, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(55, bvSize1), 3312 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(54, 54, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(54, bvSize1), 3313 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(53, 53, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(53, bvSize1), 3314 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(52, 52, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(52, bvSize1), 3315 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(51, 51, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(51, bvSize1), 3316 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(50, 50, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(50, bvSize1), 3317 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(49, 49, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(49, bvSize1), 3318 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(48, 48, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(48, bvSize1), 3319 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(47, 47, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(47, bvSize1), 3320 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(46, 46, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(46, bvSize1), 3321 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(45, 45, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(45, bvSize1), 3322 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(44, 44, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(44, bvSize1), 3323 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(43, 43, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(43, bvSize1), 3324 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(42, 42, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(42, bvSize1), 3325 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(41, 41, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(41, bvSize1), 3326 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(40, 40, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(40, bvSize1), 3327 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(39, 39, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(39, bvSize1), 3328 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(38, 38, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(38, bvSize1), 3329 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(37, 37, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(37, bvSize1), 3330 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(36, 36, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(36, bvSize1), 3331 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(35, 35, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(35, bvSize1), 3332 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(34, 34, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(34, bvSize1), 3333 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(33, 33, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(33, bvSize1), 3334 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(32, 32, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(32, bvSize1), 3335 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(31, 31, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1), 3336 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(30, 30, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1), 3337 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(29, 29, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1), 3338 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(28, 28, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1), 3339 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(27, 27, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1), 3340 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(26, 26, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1), 3341 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(25, 25, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1), 3342 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(24, 24, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1), 3343 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(23, 23, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1), 3344 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(22, 22, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1), 3345 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(21, 21, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1), 3346 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(20, 20, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1), 3347 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(19, 19, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1), 3348 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(18, 18, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1), 3349 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(17, 17, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1), 3350 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(16, 16, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1), 3351 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1), 3352 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1), 3353 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1), 3354 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1), 3355 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1), 3356 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1), 3357 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1), 3358 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1), 3359 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1), 3360 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1), 3361 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1), 3362 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1), 3363 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1), 3364 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1), 3365 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1), 3366 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op2), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1), 3367 this->astCtxt->bv(0, bvSize1) 3368 )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) 3369 ); 3370 break; 3371 default: 3372 throw triton::exceptions::Semantics("x86Semantics::bsr_s(): Invalid operand size."); 3373 } 3374 3375 /* Create symbolic expression */ 3376 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "BSR operation"); 3377 3378 /* Spread taint */ 3379 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 3380 3381 /* Update symbolic flags */ 3382 this->zfBsf_s(inst, expr, src, op2); /* same as bsf */ 3383 3384 /* Tag undefined flags */ 3385 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 3386 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF)); 3387 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 3388 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF)); 3389 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF)); 3390 3391 /* Update the symbolic control flow */ 3392 this->controlFlow_s(inst); 3393 } 3394 3395 bswap_s(triton::arch::Instruction & inst)3396 void x86Semantics::bswap_s(triton::arch::Instruction& inst) { 3397 auto& src = inst.operands[0]; 3398 3399 /* Create symbolic operands */ 3400 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 3401 3402 /* Create the semantics */ 3403 std::list<triton::ast::SharedAbstractNode> bytes; 3404 switch (src.getSize()) { 3405 case triton::size::qword: 3406 bytes.push_front(this->astCtxt->extract(63, 56, op1)); 3407 bytes.push_front(this->astCtxt->extract(55, 48, op1)); 3408 bytes.push_front(this->astCtxt->extract(47, 40, op1)); 3409 bytes.push_front(this->astCtxt->extract(39, 32, op1)); 3410 case triton::size::dword: 3411 bytes.push_front(this->astCtxt->extract(31, 24, op1)); 3412 bytes.push_front(this->astCtxt->extract(23, 16, op1)); 3413 case triton::size::word: 3414 bytes.push_front(this->astCtxt->extract(15, 8, op1)); 3415 bytes.push_front(this->astCtxt->extract(7, 0, op1)); 3416 break; 3417 default: 3418 throw triton::exceptions::Semantics("x86Semantics::bswap_s(): Invalid operand size."); 3419 } 3420 3421 auto node = this->astCtxt->concat(bytes); 3422 3423 /* Create symbolic expression */ 3424 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, src, "BSWAP operation"); 3425 3426 /* Spread taint */ 3427 expr->isTainted = this->taintEngine->taintAssignment(src, src); 3428 3429 /* Tag undefined registers */ 3430 if (src.getSize() == triton::size::word) { 3431 // When the BSWAP instruction references a 16-bit register, the result is undefined. 3432 this->undefined_s(inst, src.getRegister()); 3433 } 3434 3435 /* Update the symbolic control flow */ 3436 this->controlFlow_s(inst); 3437 } 3438 3439 bt_s(triton::arch::Instruction & inst)3440 void x86Semantics::bt_s(triton::arch::Instruction& inst) { 3441 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 3442 auto& src1 = inst.operands[0]; 3443 auto& src2 = inst.operands[1]; 3444 3445 /* Create symbolic operands */ 3446 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 3447 auto op2 = this->astCtxt->zx(src1.getBitSize() - src2.getBitSize(), this->symbolicEngine->getOperandAst(inst, src2)); 3448 3449 /* Create the semantics */ 3450 auto node = this->astCtxt->extract(0, 0, 3451 this->astCtxt->bvlshr( 3452 op1, 3453 this->astCtxt->bvsmod( 3454 op2, 3455 this->astCtxt->bv(src1.getBitSize(), src1.getBitSize()) 3456 ) 3457 ) 3458 ); 3459 3460 /* Create symbolic expression */ 3461 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, this->architecture->getRegister(ID_REG_X86_CF), "BT operation"); 3462 3463 /* Spread taint */ 3464 expr->isTainted = this->taintEngine->taintUnion(dst, src1); 3465 expr->isTainted = this->taintEngine->taintUnion(dst, src2); 3466 3467 /* Tag undefined flags */ 3468 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 3469 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 3470 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF)); 3471 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF)); 3472 3473 /* Update the symbolic control flow */ 3474 this->controlFlow_s(inst); 3475 } 3476 3477 btc_s(triton::arch::Instruction & inst)3478 void x86Semantics::btc_s(triton::arch::Instruction& inst) { 3479 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 3480 auto& dst2 = inst.operands[0]; 3481 auto& src1 = inst.operands[1]; 3482 3483 /* Create symbolic operands */ 3484 auto op1 = this->symbolicEngine->getOperandAst(inst, dst2); 3485 auto op2 = this->astCtxt->zx(dst2.getBitSize() - src1.getBitSize(), this->symbolicEngine->getOperandAst(inst, src1)); 3486 3487 /* Create the semantics */ 3488 auto node1 = this->astCtxt->extract(0, 0, 3489 this->astCtxt->bvlshr( 3490 op1, 3491 this->astCtxt->bvsmod( 3492 op2, 3493 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize()) 3494 ) 3495 ) 3496 ); 3497 auto node2 = this->astCtxt->ite( 3498 this->astCtxt->equal(node1, this->astCtxt->bvfalse()), 3499 /* BTS */ 3500 this->astCtxt->bvor( 3501 op1, 3502 this->astCtxt->bvshl( 3503 this->astCtxt->bv(1, dst2.getBitSize()), 3504 this->astCtxt->bvsmod( 3505 op2, 3506 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize()) 3507 ) 3508 ) 3509 ), 3510 /* BTR */ 3511 this->astCtxt->bvand( 3512 op1, 3513 this->astCtxt->bvsub( 3514 op1, 3515 this->astCtxt->bvshl( 3516 this->astCtxt->bv(1, dst2.getBitSize()), 3517 this->astCtxt->bvsmod( 3518 op2, 3519 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize()) 3520 ) 3521 ) 3522 ) 3523 ) 3524 ); 3525 3526 /* Create symbolic expression */ 3527 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, this->architecture->getRegister(ID_REG_X86_CF), "BTC carry operation"); 3528 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "BTC complement operation"); 3529 3530 /* Spread taint */ 3531 expr1->isTainted = this->taintEngine->taintUnion(dst1, dst2); 3532 expr1->isTainted = this->taintEngine->taintUnion(dst1, src1); 3533 expr2->isTainted = this->taintEngine->taintUnion(dst2, src1); 3534 3535 /* Tag undefined flags */ 3536 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 3537 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 3538 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF)); 3539 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF)); 3540 3541 /* Update the symbolic control flow */ 3542 this->controlFlow_s(inst); 3543 } 3544 3545 btr_s(triton::arch::Instruction & inst)3546 void x86Semantics::btr_s(triton::arch::Instruction& inst) { 3547 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 3548 auto& dst2 = inst.operands[0]; 3549 auto& src1 = inst.operands[1]; 3550 3551 /* Create symbolic operands */ 3552 auto op1 = this->symbolicEngine->getOperandAst(inst, dst2); 3553 auto op2 = this->astCtxt->zx(dst2.getBitSize() - src1.getBitSize(), this->symbolicEngine->getOperandAst(inst, src1)); 3554 3555 /* Create the semantics */ 3556 auto node1 = this->astCtxt->extract(0, 0, 3557 this->astCtxt->bvlshr( 3558 op1, 3559 this->astCtxt->bvsmod( 3560 op2, 3561 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize()) 3562 ) 3563 ) 3564 ); 3565 auto node2 = this->astCtxt->ite( 3566 this->astCtxt->equal(node1, this->astCtxt->bvfalse()), 3567 op1, 3568 this->astCtxt->bvand( 3569 op1, 3570 this->astCtxt->bvsub( 3571 op1, 3572 this->astCtxt->bvshl( 3573 this->astCtxt->bv(1, dst2.getBitSize()), 3574 this->astCtxt->bvsmod( 3575 op2, 3576 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize()) 3577 ) 3578 ) 3579 ) 3580 ) 3581 ); 3582 3583 /* Create symbolic expression */ 3584 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, this->architecture->getRegister(ID_REG_X86_CF), "BTR carry operation"); 3585 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "BTR reset operation"); 3586 3587 /* Spread taint */ 3588 expr1->isTainted = this->taintEngine->taintUnion(dst1, dst2); 3589 expr1->isTainted = this->taintEngine->taintUnion(dst1, src1); 3590 expr2->isTainted = this->taintEngine->taintUnion(dst2, src1); 3591 3592 /* Tag undefined flags */ 3593 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 3594 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 3595 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF)); 3596 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF)); 3597 3598 /* Update the symbolic control flow */ 3599 this->controlFlow_s(inst); 3600 } 3601 3602 bts_s(triton::arch::Instruction & inst)3603 void x86Semantics::bts_s(triton::arch::Instruction& inst) { 3604 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 3605 auto& dst2 = inst.operands[0]; 3606 auto& src1 = inst.operands[1]; 3607 3608 /* Create symbolic operands */ 3609 auto op1 = this->symbolicEngine->getOperandAst(inst, dst2); 3610 auto op2 = this->astCtxt->zx(dst2.getBitSize() - src1.getBitSize(), this->symbolicEngine->getOperandAst(inst, src1)); 3611 3612 /* Create the semantics */ 3613 auto node1 = this->astCtxt->extract(0, 0, 3614 this->astCtxt->bvlshr( 3615 op1, 3616 this->astCtxt->bvsmod( 3617 op2, 3618 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize()) 3619 ) 3620 ) 3621 ); 3622 auto node2 = this->astCtxt->bvor( 3623 op1, 3624 this->astCtxt->bvshl( 3625 this->astCtxt->bv(1, dst2.getBitSize()), 3626 this->astCtxt->bvsmod( 3627 op2, 3628 this->astCtxt->bv(dst2.getBitSize(), dst2.getBitSize()) 3629 ) 3630 ) 3631 ); 3632 3633 /* Create symbolic expression */ 3634 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, this->architecture->getRegister(ID_REG_X86_CF), "BTS carry operation"); 3635 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "BTS set operation"); 3636 3637 /* Spread taint */ 3638 expr1->isTainted = this->taintEngine->taintUnion(dst1, dst2); 3639 expr1->isTainted = this->taintEngine->taintUnion(dst1, src1); 3640 expr2->isTainted = this->taintEngine->taintUnion(dst2, src1); 3641 3642 /* Tag undefined flags */ 3643 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 3644 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 3645 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF)); 3646 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF)); 3647 3648 /* Update the symbolic control flow */ 3649 this->controlFlow_s(inst); 3650 } 3651 3652 call_s(triton::arch::Instruction & inst)3653 void x86Semantics::call_s(triton::arch::Instruction& inst) { 3654 auto stack = this->architecture->getStackPointer(); 3655 3656 /* Create the semantics - side effect */ 3657 auto stackValue = alignSubStack_s(inst, stack.getSize()); 3658 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 3659 auto sp = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize())); 3660 auto& src = inst.operands[0]; 3661 3662 /* Create symbolic operands */ 3663 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 3664 3665 /* Create the semantics - side effect */ 3666 auto node1 = this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize()); 3667 3668 /* Create the semantics */ 3669 auto node2 = op1; 3670 3671 /* Create the symbolic expression */ 3672 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, sp, "Saved Program Counter"); 3673 3674 /* Create symbolic expression */ 3675 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, pc, "Program Counter"); 3676 3677 /* Spread taint */ 3678 expr1->isTainted = this->taintEngine->untaintMemory(sp.getMemory()); 3679 expr2->isTainted = this->taintEngine->taintAssignment(pc, src); 3680 3681 /* Create the path constraint */ 3682 this->symbolicEngine->pushPathConstraint(inst, expr2); 3683 } 3684 3685 cbw_s(triton::arch::Instruction & inst)3686 void x86Semantics::cbw_s(triton::arch::Instruction& inst) { 3687 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX)); 3688 3689 /* Create symbolic operands */ 3690 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 3691 3692 /* Create the semantics */ 3693 auto node = this->astCtxt->sx(triton::bitsize::byte, this->astCtxt->extract(triton::bitsize::byte-1, 0, op1)); 3694 3695 /* Create symbolic expression */ 3696 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CBW operation"); 3697 3698 /* Spread taint */ 3699 expr->isTainted = this->taintEngine->taintAssignment(dst, dst); 3700 3701 /* Update the symbolic control flow */ 3702 this->controlFlow_s(inst); 3703 } 3704 3705 cdq_s(triton::arch::Instruction & inst)3706 void x86Semantics::cdq_s(triton::arch::Instruction& inst) { 3707 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX)); 3708 auto src = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX)); 3709 3710 /* Create symbolic operands */ 3711 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 3712 3713 /* Create the semantics - TMP = 64 bitvec (EDX:EAX) */ 3714 auto node1 = this->astCtxt->sx(triton::bitsize::dword, op1); 3715 3716 /* Create symbolic expression */ 3717 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "Temporary variable"); 3718 3719 /* Spread taint */ 3720 expr1->isTainted = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_EAX)); 3721 3722 /* Create the semantics - EDX = TMP[63...32] */ 3723 auto node2 = this->astCtxt->extract(triton::bitsize::qword-1, triton::bitsize::dword, this->astCtxt->reference(expr1)); 3724 3725 /* Create symbolic expression */ 3726 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "CDQ operation"); 3727 3728 /* Spread taint */ 3729 expr2->isTainted = this->taintEngine->taintAssignment(dst, src); 3730 3731 /* Update the symbolic control flow */ 3732 this->controlFlow_s(inst); 3733 } 3734 3735 cdqe_s(triton::arch::Instruction & inst)3736 void x86Semantics::cdqe_s(triton::arch::Instruction& inst) { 3737 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX)); 3738 3739 /* Create symbolic operands */ 3740 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 3741 3742 /* Create the semantics */ 3743 auto node = this->astCtxt->sx(triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::dword-1, 0, op1)); 3744 3745 /* Create symbolic expression */ 3746 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CDQE operation"); 3747 3748 /* Spread taint */ 3749 expr->isTainted = this->taintEngine->taintAssignment(dst, dst); 3750 3751 /* Update the symbolic control flow */ 3752 this->controlFlow_s(inst); 3753 } 3754 3755 clc_s(triton::arch::Instruction & inst)3756 void x86Semantics::clc_s(triton::arch::Instruction& inst) { 3757 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag"); 3758 /* Update the symbolic control flow */ 3759 this->controlFlow_s(inst); 3760 } 3761 3762 cld_s(triton::arch::Instruction & inst)3763 void x86Semantics::cld_s(triton::arch::Instruction& inst) { 3764 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_DF), "Clears direction flag"); 3765 /* Update the symbolic control flow */ 3766 this->controlFlow_s(inst); 3767 } 3768 3769 clflush_s(triton::arch::Instruction & inst)3770 void x86Semantics::clflush_s(triton::arch::Instruction& inst) { 3771 /* Update the symbolic control flow */ 3772 this->controlFlow_s(inst); 3773 } 3774 3775 clts_s(triton::arch::Instruction & inst)3776 void x86Semantics::clts_s(triton::arch::Instruction& inst) { 3777 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CR0)); 3778 3779 /* Create symbolic operands */ 3780 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 3781 3782 /* Create the semantics */ 3783 triton::ast::SharedAbstractNode node = nullptr; 3784 3785 switch (dst.getBitSize()) { 3786 case triton::bitsize::qword: 3787 node = this->astCtxt->bvand(op1, this->astCtxt->bv(0xfffffffffffffff7, triton::bitsize::qword)); 3788 break; 3789 case triton::bitsize::dword: 3790 node = this->astCtxt->bvand(op1, this->astCtxt->bv(0xfffffff7, triton::bitsize::dword)); 3791 break; 3792 default: 3793 throw triton::exceptions::Semantics("x86Semantics::clts_s(): Invalid operand size."); 3794 } 3795 3796 /* Create symbolic expression */ 3797 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CLTS operation"); 3798 3799 /* Spread taint */ 3800 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 3801 3802 /* Update the symbolic control flow */ 3803 this->controlFlow_s(inst); 3804 } 3805 3806 cli_s(triton::arch::Instruction & inst)3807 void x86Semantics::cli_s(triton::arch::Instruction& inst) { 3808 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_IF), "Clears interrupt flag"); 3809 /* Update the symbolic control flow */ 3810 this->controlFlow_s(inst); 3811 } 3812 3813 cmc_s(triton::arch::Instruction & inst)3814 void x86Semantics::cmc_s(triton::arch::Instruction& inst) { 3815 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 3816 3817 /* Create symbolic operands */ 3818 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 3819 3820 /* Create the semantics */ 3821 auto node = this->astCtxt->bvnot(op1); 3822 3823 /* Create symbolic expression */ 3824 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst.getRegister(), "CMC operation"); 3825 3826 /* Spread taint */ 3827 expr->isTainted = this->taintEngine->taintAssignment(dst, dst); 3828 3829 /* Update the symbolic control flow */ 3830 this->controlFlow_s(inst); 3831 } 3832 3833 cmova_s(triton::arch::Instruction & inst)3834 void x86Semantics::cmova_s(triton::arch::Instruction& inst) { 3835 auto& dst = inst.operands[0]; 3836 auto& src = inst.operands[1]; 3837 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 3838 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 3839 3840 /* Create symbolic operands */ 3841 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 3842 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 3843 auto op3 = this->symbolicEngine->getOperandAst(inst, cf); 3844 auto op4 = this->symbolicEngine->getOperandAst(inst, zf); 3845 3846 /* Create the semantics */ 3847 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvand(this->astCtxt->bvnot(op3), this->astCtxt->bvnot(op4)), this->astCtxt->bvtrue()), op2, op1); 3848 3849 /* Create symbolic expression */ 3850 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVA operation"); 3851 3852 /* Spread taint and condition flag */ 3853 if (op3->evaluate().is_zero() && op4->evaluate().is_zero()) { 3854 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 3855 inst.setConditionTaken(true); 3856 } 3857 else { 3858 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 3859 } 3860 3861 expr->isTainted |= this->taintEngine->isTainted(cf) || this->taintEngine->isTainted(zf); 3862 3863 /* Update the symbolic control flow */ 3864 this->controlFlow_s(inst); 3865 } 3866 3867 cmovae_s(triton::arch::Instruction & inst)3868 void x86Semantics::cmovae_s(triton::arch::Instruction& inst) { 3869 auto& dst = inst.operands[0]; 3870 auto& src = inst.operands[1]; 3871 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 3872 3873 /* Create symbolic operands */ 3874 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 3875 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 3876 auto op3 = this->symbolicEngine->getOperandAst(inst, cf); 3877 3878 /* Create the semantics */ 3879 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvfalse()), op2, op1); 3880 3881 /* Create symbolic expression */ 3882 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVAE operation"); 3883 3884 /* Spread taint and condition flag */ 3885 if (op3->evaluate().is_zero()) { 3886 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 3887 inst.setConditionTaken(true); 3888 } 3889 else { 3890 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 3891 } 3892 3893 expr->isTainted |= this->taintEngine->isTainted(cf); 3894 3895 /* Update the symbolic control flow */ 3896 this->controlFlow_s(inst); 3897 } 3898 3899 cmovb_s(triton::arch::Instruction & inst)3900 void x86Semantics::cmovb_s(triton::arch::Instruction& inst) { 3901 auto& dst = inst.operands[0]; 3902 auto& src = inst.operands[1]; 3903 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 3904 3905 /* Create symbolic operands */ 3906 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 3907 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 3908 auto op3 = this->symbolicEngine->getOperandAst(inst, cf); 3909 3910 /* Create the semantics */ 3911 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvtrue()), op2, op1); 3912 3913 /* Create symbolic expression */ 3914 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVB operation"); 3915 3916 /* Spread taint and condition flag */ 3917 if (!op3->evaluate().is_zero()) { 3918 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 3919 inst.setConditionTaken(true); 3920 } 3921 else { 3922 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 3923 } 3924 3925 expr->isTainted |= this->taintEngine->isTainted(cf); 3926 3927 /* Update the symbolic control flow */ 3928 this->controlFlow_s(inst); 3929 } 3930 3931 cmovbe_s(triton::arch::Instruction & inst)3932 void x86Semantics::cmovbe_s(triton::arch::Instruction& inst) { 3933 auto& dst = inst.operands[0]; 3934 auto& src = inst.operands[1]; 3935 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 3936 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 3937 3938 /* Create symbolic operands */ 3939 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 3940 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 3941 auto op3 = this->symbolicEngine->getOperandAst(inst, cf); 3942 auto op4 = this->symbolicEngine->getOperandAst(inst, zf); 3943 3944 /* Create the semantics */ 3945 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvor(op3, op4), this->astCtxt->bvtrue()), op2, op1); 3946 3947 /* Create symbolic expression */ 3948 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVBE operation"); 3949 3950 /* Spread taint and condition flag */ 3951 if (!op3->evaluate().is_zero() || !op4->evaluate().is_zero()) { 3952 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 3953 inst.setConditionTaken(true); 3954 } 3955 else { 3956 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 3957 } 3958 3959 expr->isTainted |= this->taintEngine->isTainted(cf) || this->taintEngine->isTainted(zf); 3960 3961 /* Update the symbolic control flow */ 3962 this->controlFlow_s(inst); 3963 } 3964 3965 cmove_s(triton::arch::Instruction & inst)3966 void x86Semantics::cmove_s(triton::arch::Instruction& inst) { 3967 auto& dst = inst.operands[0]; 3968 auto& src = inst.operands[1]; 3969 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 3970 3971 /* Create symbolic operands */ 3972 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 3973 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 3974 auto op3 = this->symbolicEngine->getOperandAst(inst, zf); 3975 3976 /* Create the semantics */ 3977 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvtrue()), op2, op1); 3978 3979 /* Create symbolic expression */ 3980 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVE operation"); 3981 3982 /* Spread taint and condition flag */ 3983 if (!op3->evaluate().is_zero()) { 3984 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 3985 inst.setConditionTaken(true); 3986 } 3987 else { 3988 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 3989 } 3990 3991 expr->isTainted |= this->taintEngine->isTainted(zf); 3992 3993 /* Update the symbolic control flow */ 3994 this->controlFlow_s(inst); 3995 } 3996 3997 cmovg_s(triton::arch::Instruction & inst)3998 void x86Semantics::cmovg_s(triton::arch::Instruction& inst) { 3999 auto& dst = inst.operands[0]; 4000 auto& src = inst.operands[1]; 4001 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 4002 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 4003 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 4004 4005 /* Create symbolic operands */ 4006 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 4007 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 4008 auto op3 = this->symbolicEngine->getOperandAst(inst, sf); 4009 auto op4 = this->symbolicEngine->getOperandAst(inst, of); 4010 auto op5 = this->symbolicEngine->getOperandAst(inst, zf); 4011 4012 /* Create the semantics */ 4013 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvor(this->astCtxt->bvxor(op3, op4), op5), this->astCtxt->bvfalse()), op2, op1); 4014 4015 /* Create symbolic expression */ 4016 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVG operation"); 4017 4018 /* Spread taint and condition flag */ 4019 if ((op3->evaluate().is_zero() == op4->evaluate().is_zero()) && op5->evaluate().is_zero()) { 4020 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 4021 inst.setConditionTaken(true); 4022 } 4023 else { 4024 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 4025 } 4026 4027 expr->isTainted |= this->taintEngine->isTainted(sf) || this->taintEngine->isTainted(of) || this->taintEngine->isTainted(zf); 4028 4029 /* Update the symbolic control flow */ 4030 this->controlFlow_s(inst); 4031 } 4032 4033 cmovge_s(triton::arch::Instruction & inst)4034 void x86Semantics::cmovge_s(triton::arch::Instruction& inst) { 4035 auto& dst = inst.operands[0]; 4036 auto& src = inst.operands[1]; 4037 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 4038 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 4039 4040 /* Create symbolic operands */ 4041 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 4042 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 4043 auto op3 = this->symbolicEngine->getOperandAst(inst, sf); 4044 auto op4 = this->symbolicEngine->getOperandAst(inst, of); 4045 4046 /* Create the semantics */ 4047 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, op4), op2, op1); 4048 4049 /* Create symbolic expression */ 4050 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVGE operation"); 4051 4052 /* Spread taint and condition flag */ 4053 if (op3->evaluate().is_zero() == op4->evaluate().is_zero()) { 4054 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 4055 inst.setConditionTaken(true); 4056 } 4057 else { 4058 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 4059 } 4060 4061 expr->isTainted |= this->taintEngine->isTainted(sf) || this->taintEngine->isTainted(of); 4062 4063 /* Update the symbolic control flow */ 4064 this->controlFlow_s(inst); 4065 } 4066 4067 cmovl_s(triton::arch::Instruction & inst)4068 void x86Semantics::cmovl_s(triton::arch::Instruction& inst) { 4069 auto& dst = inst.operands[0]; 4070 auto& src = inst.operands[1]; 4071 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 4072 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 4073 4074 /* Create symbolic operands */ 4075 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 4076 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 4077 auto op3 = this->symbolicEngine->getOperandAst(inst, sf); 4078 auto op4 = this->symbolicEngine->getOperandAst(inst, of); 4079 4080 /* Create the semantics */ 4081 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvxor(op3, op4), this->astCtxt->bvtrue()), op2, op1); 4082 4083 /* Create symbolic expression */ 4084 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVL operation"); 4085 4086 /* Spread taint and condition flag */ 4087 if (op3->evaluate().is_zero() != op4->evaluate().is_zero()) { 4088 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 4089 inst.setConditionTaken(true); 4090 } 4091 else { 4092 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 4093 } 4094 4095 expr->isTainted |= this->taintEngine->isTainted(sf) || this->taintEngine->isTainted(of); 4096 4097 4098 /* Update the symbolic control flow */ 4099 this->controlFlow_s(inst); 4100 } 4101 4102 cmovle_s(triton::arch::Instruction & inst)4103 void x86Semantics::cmovle_s(triton::arch::Instruction& inst) { 4104 auto& dst = inst.operands[0]; 4105 auto& src = inst.operands[1]; 4106 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 4107 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 4108 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 4109 4110 /* Create symbolic operands */ 4111 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 4112 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 4113 auto op3 = this->symbolicEngine->getOperandAst(inst, sf); 4114 auto op4 = this->symbolicEngine->getOperandAst(inst, of); 4115 auto op5 = this->symbolicEngine->getOperandAst(inst, zf); 4116 4117 /* Create the semantics */ 4118 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvor(this->astCtxt->bvxor(op3, op4), op5), this->astCtxt->bvtrue()), op2, op1); 4119 4120 /* Create symbolic expression */ 4121 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVBE operation"); 4122 4123 /* Spread taint and condition flag */ 4124 if ((op3->evaluate().is_zero() != op4->evaluate().is_zero()) || !op5->evaluate().is_zero()) { 4125 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 4126 inst.setConditionTaken(true); 4127 } 4128 else { 4129 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 4130 } 4131 4132 expr->isTainted |= this->taintEngine->isTainted(sf) || this->taintEngine->isTainted(of) || this->taintEngine->isTainted(zf); 4133 4134 /* Update the symbolic control flow */ 4135 this->controlFlow_s(inst); 4136 } 4137 4138 cmovne_s(triton::arch::Instruction & inst)4139 void x86Semantics::cmovne_s(triton::arch::Instruction& inst) { 4140 auto& dst = inst.operands[0]; 4141 auto& src = inst.operands[1]; 4142 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 4143 4144 /* Create symbolic operands */ 4145 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 4146 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 4147 auto op3 = this->symbolicEngine->getOperandAst(inst, zf); 4148 4149 /* Create the semantics */ 4150 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvfalse()), op2, op1); 4151 4152 /* Create symbolic expression */ 4153 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVNE operation"); 4154 4155 /* Spread taint and condition flag */ 4156 if (op3->evaluate().is_zero()) { 4157 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 4158 inst.setConditionTaken(true); 4159 } 4160 else { 4161 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 4162 } 4163 4164 expr->isTainted |= this->taintEngine->isTainted(zf); 4165 4166 /* Update the symbolic control flow */ 4167 this->controlFlow_s(inst); 4168 } 4169 4170 cmovno_s(triton::arch::Instruction & inst)4171 void x86Semantics::cmovno_s(triton::arch::Instruction& inst) { 4172 auto& dst = inst.operands[0]; 4173 auto& src = inst.operands[1]; 4174 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 4175 4176 /* Create symbolic operands */ 4177 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 4178 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 4179 auto op3 = this->symbolicEngine->getOperandAst(inst, of); 4180 4181 /* Create the semantics */ 4182 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvfalse()), op2, op1); 4183 4184 /* Create symbolic expression */ 4185 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVNO operation"); 4186 4187 /* Spread taint and condition flag */ 4188 if (op3->evaluate().is_zero()) { 4189 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 4190 inst.setConditionTaken(true); 4191 } 4192 else { 4193 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 4194 } 4195 4196 expr->isTainted |= this->taintEngine->isTainted(of); 4197 4198 /* Update the symbolic control flow */ 4199 this->controlFlow_s(inst); 4200 } 4201 4202 cmovnp_s(triton::arch::Instruction & inst)4203 void x86Semantics::cmovnp_s(triton::arch::Instruction& inst) { 4204 auto& dst = inst.operands[0]; 4205 auto& src = inst.operands[1]; 4206 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF)); 4207 4208 /* Create symbolic operands */ 4209 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 4210 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 4211 auto op3 = this->symbolicEngine->getOperandAst(inst, pf); 4212 4213 /* Create the semantics */ 4214 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvfalse()), op2, op1); 4215 4216 /* Create symbolic expression */ 4217 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVNP operation"); 4218 4219 /* Spread taint and condition flag */ 4220 if (op3->evaluate().is_zero()) { 4221 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 4222 inst.setConditionTaken(true); 4223 } 4224 else { 4225 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 4226 } 4227 4228 expr->isTainted |= this->taintEngine->isTainted(pf); 4229 4230 /* Update the symbolic control flow */ 4231 this->controlFlow_s(inst); 4232 } 4233 4234 cmovns_s(triton::arch::Instruction & inst)4235 void x86Semantics::cmovns_s(triton::arch::Instruction& inst) { 4236 auto& dst = inst.operands[0]; 4237 auto& src = inst.operands[1]; 4238 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 4239 4240 /* Create symbolic operands */ 4241 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 4242 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 4243 auto op3 = this->symbolicEngine->getOperandAst(inst, sf); 4244 4245 /* Create the semantics */ 4246 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvfalse()), op2, op1); 4247 4248 /* Create symbolic expression */ 4249 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVNS operation"); 4250 4251 /* Spread taint and condition flag */ 4252 if (op3->evaluate().is_zero()) { 4253 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 4254 inst.setConditionTaken(true); 4255 } 4256 else { 4257 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 4258 } 4259 4260 expr->isTainted |= this->taintEngine->isTainted(sf); 4261 4262 /* Update the symbolic control flow */ 4263 this->controlFlow_s(inst); 4264 } 4265 4266 cmovo_s(triton::arch::Instruction & inst)4267 void x86Semantics::cmovo_s(triton::arch::Instruction& inst) { 4268 auto& dst = inst.operands[0]; 4269 auto& src = inst.operands[1]; 4270 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 4271 4272 /* Create symbolic operands */ 4273 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 4274 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 4275 auto op3 = this->symbolicEngine->getOperandAst(inst, of); 4276 4277 /* Create the semantics */ 4278 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvtrue()), op2, op1); 4279 4280 /* Create symbolic expression */ 4281 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVO operation"); 4282 4283 /* Spread taint and condition flag */ 4284 if (!op3->evaluate().is_zero()) { 4285 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 4286 inst.setConditionTaken(true); 4287 } 4288 else { 4289 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 4290 } 4291 4292 expr->isTainted |= this->taintEngine->isTainted(of); 4293 4294 /* Update the symbolic control flow */ 4295 this->controlFlow_s(inst); 4296 } 4297 4298 cmovp_s(triton::arch::Instruction & inst)4299 void x86Semantics::cmovp_s(triton::arch::Instruction& inst) { 4300 auto& dst = inst.operands[0]; 4301 auto& src = inst.operands[1]; 4302 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF)); 4303 4304 /* Create symbolic operands */ 4305 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 4306 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 4307 auto op3 = this->symbolicEngine->getOperandAst(inst, pf); 4308 4309 /* Create the semantics */ 4310 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvtrue()), op2, op1); 4311 4312 /* Create symbolic expression */ 4313 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVP operation"); 4314 4315 /* Spread taint and condition flag */ 4316 if (!op3->evaluate().is_zero()) { 4317 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 4318 inst.setConditionTaken(true); 4319 } 4320 else { 4321 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 4322 } 4323 4324 expr->isTainted |= this->taintEngine->isTainted(pf); 4325 4326 /* Update the symbolic control flow */ 4327 this->controlFlow_s(inst); 4328 } 4329 4330 cmovs_s(triton::arch::Instruction & inst)4331 void x86Semantics::cmovs_s(triton::arch::Instruction& inst) { 4332 auto& dst = inst.operands[0]; 4333 auto& src = inst.operands[1]; 4334 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 4335 4336 /* Create symbolic operands */ 4337 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 4338 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 4339 auto op3 = this->symbolicEngine->getOperandAst(inst, sf); 4340 4341 /* Create the semantics */ 4342 auto node = this->astCtxt->ite(this->astCtxt->equal(op3, this->astCtxt->bvtrue()), op2, op1); 4343 4344 /* Create symbolic expression */ 4345 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CMOVS operation"); 4346 4347 /* Spread taint and condition flag */ 4348 if (!op3->evaluate().is_zero()) { 4349 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 4350 inst.setConditionTaken(true); 4351 } 4352 else { 4353 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 4354 } 4355 4356 expr->isTainted |= this->taintEngine->isTainted(sf); 4357 4358 /* Update the symbolic control flow */ 4359 this->controlFlow_s(inst); 4360 } 4361 4362 cmp_s(triton::arch::Instruction & inst)4363 void x86Semantics::cmp_s(triton::arch::Instruction& inst) { 4364 auto& dst = inst.operands[0]; 4365 auto& src = inst.operands[1]; 4366 4367 /* Create symbolic operands */ 4368 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 4369 auto op2 = this->astCtxt->sx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src)); 4370 4371 /* Create the semantics */ 4372 auto node = this->astCtxt->bvsub(op1, op2); 4373 4374 /* Create symbolic expression */ 4375 auto expr = this->symbolicEngine->createSymbolicVolatileExpression(inst, node, "CMP operation"); 4376 4377 /* Spread taint */ 4378 expr->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src); 4379 4380 /* Update symbolic flags */ 4381 this->af_s(inst, expr, dst, op1, op2, true); 4382 this->cfSub_s(inst, expr, dst, op1, op2, true); 4383 this->ofSub_s(inst, expr, dst, op1, op2, true); 4384 this->pf_s(inst, expr, dst, true); 4385 this->sf_s(inst, expr, dst, true); 4386 this->zf_s(inst, expr, dst, true); 4387 4388 /* Update the symbolic control flow */ 4389 this->controlFlow_s(inst); 4390 } 4391 4392 cmpsb_s(triton::arch::Instruction & inst)4393 void x86Semantics::cmpsb_s(triton::arch::Instruction& inst) { 4394 auto& dst = inst.operands[0]; 4395 auto& src = inst.operands[1]; 4396 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI)); 4397 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI)); 4398 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 4399 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 4400 4401 /* If the REP prefix is defined, convert REP into REPE */ 4402 if (inst.getPrefix() == triton::arch::x86::ID_PREFIX_REP) 4403 inst.setPrefix(triton::arch::x86::ID_PREFIX_REPE); 4404 4405 /* Check if there is a REP prefix and a counter to zero */ 4406 auto cnt = this->symbolicEngine->getOperandAst(cx); 4407 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 4408 this->controlFlow_s(inst); 4409 return; 4410 } 4411 4412 /* Create symbolic operands */ 4413 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 4414 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 4415 auto op3 = this->symbolicEngine->getOperandAst(inst, index1); 4416 auto op4 = this->symbolicEngine->getOperandAst(inst, index2); 4417 auto op5 = this->symbolicEngine->getOperandAst(inst, df); 4418 4419 /* Create the semantics */ 4420 auto node1 = this->astCtxt->bvsub(op1, op2); 4421 auto node2 = this->astCtxt->ite( 4422 this->astCtxt->equal(op5, this->astCtxt->bvfalse()), 4423 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::byte, index1.getBitSize())), 4424 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::byte, index1.getBitSize())) 4425 ); 4426 auto node3 = this->astCtxt->ite( 4427 this->astCtxt->equal(op5, this->astCtxt->bvfalse()), 4428 this->astCtxt->bvadd(op4, this->astCtxt->bv(triton::size::byte, index2.getBitSize())), 4429 this->astCtxt->bvsub(op4, this->astCtxt->bv(triton::size::byte, index2.getBitSize())) 4430 ); 4431 4432 /* Create symbolic expression */ 4433 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMPSB operation"); 4434 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (SI) operation"); 4435 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (DI) operation"); 4436 4437 /* Spread taint */ 4438 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src); 4439 expr2->isTainted = this->taintEngine->taintUnion(index1, index1); 4440 expr3->isTainted = this->taintEngine->taintUnion(index2, index2); 4441 4442 /* Update symbolic flags */ 4443 this->af_s(inst, expr1, dst, op1, op2, true); 4444 this->cfSub_s(inst, expr1, dst, op1, op2, true); 4445 this->ofSub_s(inst, expr1, dst, op1, op2, true); 4446 this->pf_s(inst, expr1, dst, true); 4447 this->sf_s(inst, expr1, dst, true); 4448 this->zf_s(inst, expr1, dst, true); 4449 4450 /* Update the symbolic control flow */ 4451 this->controlFlow_s(inst); 4452 } 4453 4454 cmpsd_s(triton::arch::Instruction & inst)4455 void x86Semantics::cmpsd_s(triton::arch::Instruction& inst) { 4456 auto& dst = inst.operands[0]; 4457 auto& src = inst.operands[1]; 4458 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI)); 4459 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI)); 4460 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 4461 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 4462 4463 /* If the REP prefix is defined, convert REP into REPE */ 4464 if (inst.getPrefix() == triton::arch::x86::ID_PREFIX_REP) 4465 inst.setPrefix(triton::arch::x86::ID_PREFIX_REPE); 4466 4467 /* Check if there is a REP prefix and a counter to zero */ 4468 auto cnt = this->symbolicEngine->getOperandAst(cx); 4469 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 4470 this->controlFlow_s(inst); 4471 return; 4472 } 4473 4474 /* Create symbolic operands */ 4475 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 4476 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 4477 auto op3 = this->symbolicEngine->getOperandAst(inst, index1); 4478 auto op4 = this->symbolicEngine->getOperandAst(inst, index2); 4479 auto op5 = this->symbolicEngine->getOperandAst(inst, df); 4480 4481 /* Create the semantics */ 4482 auto node1 = this->astCtxt->bvsub(op1, op2); 4483 auto node2 = this->astCtxt->ite( 4484 this->astCtxt->equal(op5, this->astCtxt->bvfalse()), 4485 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::dword, index1.getBitSize())), 4486 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::dword, index1.getBitSize())) 4487 ); 4488 auto node3 = this->astCtxt->ite( 4489 this->astCtxt->equal(op5, this->astCtxt->bvfalse()), 4490 this->astCtxt->bvadd(op4, this->astCtxt->bv(triton::size::dword, index2.getBitSize())), 4491 this->astCtxt->bvsub(op4, this->astCtxt->bv(triton::size::dword, index2.getBitSize())) 4492 ); 4493 4494 /* Create symbolic expression */ 4495 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMPSD operation"); 4496 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (SI) operation"); 4497 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (DI) operation"); 4498 4499 /* Spread taint */ 4500 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src); 4501 expr2->isTainted = this->taintEngine->taintUnion(index1, index1); 4502 expr3->isTainted = this->taintEngine->taintUnion(index2, index2); 4503 4504 /* Update symbolic flags */ 4505 this->af_s(inst, expr1, dst, op1, op2, true); 4506 this->cfSub_s(inst, expr1, dst, op1, op2, true); 4507 this->ofSub_s(inst, expr1, dst, op1, op2, true); 4508 this->pf_s(inst, expr1, dst, true); 4509 this->sf_s(inst, expr1, dst, true); 4510 this->zf_s(inst, expr1, dst, true); 4511 4512 /* Update the symbolic control flow */ 4513 this->controlFlow_s(inst); 4514 } 4515 4516 cmpsq_s(triton::arch::Instruction & inst)4517 void x86Semantics::cmpsq_s(triton::arch::Instruction& inst) { 4518 auto& dst = inst.operands[0]; 4519 auto& src = inst.operands[1]; 4520 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI)); 4521 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI)); 4522 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 4523 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 4524 4525 /* If the REP prefix is defined, convert REP into REPE */ 4526 if (inst.getPrefix() == triton::arch::x86::ID_PREFIX_REP) 4527 inst.setPrefix(triton::arch::x86::ID_PREFIX_REPE); 4528 4529 /* Check if there is a REP prefix and a counter to zero */ 4530 auto cnt = this->symbolicEngine->getOperandAst(cx); 4531 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 4532 this->controlFlow_s(inst); 4533 return; 4534 } 4535 4536 /* Create symbolic operands */ 4537 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 4538 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 4539 auto op3 = this->symbolicEngine->getOperandAst(inst, index1); 4540 auto op4 = this->symbolicEngine->getOperandAst(inst, index2); 4541 auto op5 = this->symbolicEngine->getOperandAst(inst, df); 4542 4543 /* Create the semantics */ 4544 auto node1 = this->astCtxt->bvsub(op1, op2); 4545 auto node2 = this->astCtxt->ite( 4546 this->astCtxt->equal(op5, this->astCtxt->bvfalse()), 4547 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::qword, index1.getBitSize())), 4548 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::qword, index1.getBitSize())) 4549 ); 4550 auto node3 = this->astCtxt->ite( 4551 this->astCtxt->equal(op5, this->astCtxt->bvfalse()), 4552 this->astCtxt->bvadd(op4, this->astCtxt->bv(triton::size::qword, index2.getBitSize())), 4553 this->astCtxt->bvsub(op4, this->astCtxt->bv(triton::size::qword, index2.getBitSize())) 4554 ); 4555 4556 /* Create symbolic expression */ 4557 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMPSQ operation"); 4558 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (SI) operation"); 4559 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (DI) operation"); 4560 4561 /* Spread taint */ 4562 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src); 4563 expr2->isTainted = this->taintEngine->taintUnion(index1, index1); 4564 expr3->isTainted = this->taintEngine->taintUnion(index2, index2); 4565 4566 /* Update symbolic flags */ 4567 this->af_s(inst, expr1, dst, op1, op2, true); 4568 this->cfSub_s(inst, expr1, dst, op1, op2, true); 4569 this->ofSub_s(inst, expr1, dst, op1, op2, true); 4570 this->pf_s(inst, expr1, dst, true); 4571 this->sf_s(inst, expr1, dst, true); 4572 this->zf_s(inst, expr1, dst, true); 4573 4574 /* Update the symbolic control flow */ 4575 this->controlFlow_s(inst); 4576 } 4577 4578 cmpsw_s(triton::arch::Instruction & inst)4579 void x86Semantics::cmpsw_s(triton::arch::Instruction& inst) { 4580 auto& dst = inst.operands[0]; 4581 auto& src = inst.operands[1]; 4582 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI)); 4583 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI)); 4584 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 4585 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 4586 4587 /* If the REP prefix is defined, convert REP into REPE */ 4588 if (inst.getPrefix() == triton::arch::x86::ID_PREFIX_REP) 4589 inst.setPrefix(triton::arch::x86::ID_PREFIX_REPE); 4590 4591 /* Check if there is a REP prefix and a counter to zero */ 4592 auto cnt = this->symbolicEngine->getOperandAst(cx); 4593 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 4594 this->controlFlow_s(inst); 4595 return; 4596 } 4597 4598 /* Create symbolic operands */ 4599 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 4600 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 4601 auto op3 = this->symbolicEngine->getOperandAst(inst, index1); 4602 auto op4 = this->symbolicEngine->getOperandAst(inst, index2); 4603 auto op5 = this->symbolicEngine->getOperandAst(inst, df); 4604 4605 /* Create the semantics */ 4606 auto node1 = this->astCtxt->bvsub(op1, op2); 4607 auto node2 = this->astCtxt->ite( 4608 this->astCtxt->equal(op5, this->astCtxt->bvfalse()), 4609 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::word, index1.getBitSize())), 4610 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::word, index1.getBitSize())) 4611 ); 4612 auto node3 = this->astCtxt->ite( 4613 this->astCtxt->equal(op5, this->astCtxt->bvfalse()), 4614 this->astCtxt->bvadd(op4, this->astCtxt->bv(triton::size::word, index2.getBitSize())), 4615 this->astCtxt->bvsub(op4, this->astCtxt->bv(triton::size::word, index2.getBitSize())) 4616 ); 4617 4618 /* Create symbolic expression */ 4619 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMPSW operation"); 4620 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (SI) operation"); 4621 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (DI) operation"); 4622 4623 /* Spread taint */ 4624 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src); 4625 expr2->isTainted = this->taintEngine->taintUnion(index1, index1); 4626 expr3->isTainted = this->taintEngine->taintUnion(index2, index2); 4627 4628 /* Update symbolic flags */ 4629 this->af_s(inst, expr1, dst, op1, op2, true); 4630 this->cfSub_s(inst, expr1, dst, op1, op2, true); 4631 this->ofSub_s(inst, expr1, dst, op1, op2, true); 4632 this->pf_s(inst, expr1, dst, true); 4633 this->sf_s(inst, expr1, dst, true); 4634 this->zf_s(inst, expr1, dst, true); 4635 4636 /* Update the symbolic control flow */ 4637 this->controlFlow_s(inst); 4638 } 4639 4640 cmpxchg_s(triton::arch::Instruction & inst)4641 void x86Semantics::cmpxchg_s(triton::arch::Instruction& inst) { 4642 auto& src1 = inst.operands[0]; 4643 auto& src2 = inst.operands[1]; 4644 4645 /* Create the tempory accumulator */ 4646 triton::arch::OperandWrapper accumulator(this->architecture->getRegister(ID_REG_X86_AL)); 4647 triton::arch::OperandWrapper accumulatorp(this->architecture->getParentRegister(ID_REG_X86_AL)); 4648 4649 switch (src1.getSize()) { 4650 case triton::size::word: 4651 accumulator.setRegister(arch::Register(this->architecture->getRegister(ID_REG_X86_AX))); 4652 break; 4653 case triton::size::dword: 4654 accumulator.setRegister(arch::Register(this->architecture->getRegister(ID_REG_X86_EAX))); 4655 break; 4656 case triton::size::qword: 4657 accumulator.setRegister(arch::Register(this->architecture->getRegister(ID_REG_X86_RAX))); 4658 break; 4659 } 4660 4661 /* Create symbolic operands */ 4662 auto op1 = this->symbolicEngine->getOperandAst(inst, accumulator); 4663 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 4664 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 4665 auto op1p = this->symbolicEngine->getOperandAst(accumulatorp); 4666 auto op2p = this->symbolicEngine->getRegisterAst((src1.getType() == triton::arch::OP_REG ? Register(this->architecture->getParentRegister(src1.getRegister())) : accumulatorp.getRegister())); 4667 auto op3p = this->symbolicEngine->getRegisterAst((src1.getType() == triton::arch::OP_REG ? Register(this->architecture->getParentRegister(src2.getRegister())) : accumulatorp.getRegister())); 4668 4669 /* Create the semantics */ 4670 auto nodeq = this->astCtxt->equal(op1, op2); 4671 auto node1 = this->astCtxt->bvsub(op1, op2); 4672 auto node2 = this->astCtxt->ite(nodeq, op3, op2); 4673 auto node3 = this->astCtxt->ite(nodeq, op1, op2); 4674 auto node2p = this->astCtxt->ite(nodeq, op3p, op2p); 4675 auto node3p = this->astCtxt->ite(nodeq, op1p, op2p); 4676 4677 /* Create symbolic expression */ 4678 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMP operation"); 4679 auto expr2 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node2, "Temporary operation"); 4680 auto expr3 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node2p, "Temporary operation"); 4681 auto expr4 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node3, "Temporary operation"); 4682 auto expr5 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node3p, "Temporary operation"); 4683 4684 triton::engines::symbolic::SharedSymbolicExpression expr6 = nullptr; 4685 triton::engines::symbolic::SharedSymbolicExpression expr7 = nullptr; 4686 4687 /* Destination */ 4688 if (nodeq->evaluate() == false && src1.getType() == triton::arch::OP_REG) { 4689 const auto& src1p = this->architecture->getParentRegister(src1.getRegister()); 4690 expr6 = this->symbolicEngine->createSymbolicRegisterExpression(inst, node2p, src1p, "XCHG operation"); 4691 } else 4692 expr6 = this->symbolicEngine->createSymbolicExpression(inst, node2, src1, "XCHG operation"); 4693 4694 /* Accumulator */ 4695 if (nodeq->evaluate() == true) 4696 expr7 = this->symbolicEngine->createSymbolicExpression(inst, node3p, accumulatorp, "XCHG operation"); 4697 else 4698 expr7 = this->symbolicEngine->createSymbolicExpression(inst, node3, accumulator, "XCHG operation"); 4699 4700 /* Spread taint */ 4701 expr1->isTainted = this->taintEngine->isTainted(accumulator) | this->taintEngine->isTainted(src1); 4702 expr2->isTainted = expr1->isTainted; 4703 expr3->isTainted = expr1->isTainted; 4704 expr4->isTainted = expr1->isTainted; 4705 expr5->isTainted = expr1->isTainted; 4706 expr6->isTainted = this->taintEngine->taintAssignment(src1, src2); 4707 expr7->isTainted = this->taintEngine->taintAssignment(accumulator, src1); 4708 4709 /* Update symbolic flags */ 4710 this->af_s(inst, expr1, accumulator, op1, op2, true); 4711 this->cfSub_s(inst, expr1, accumulator, op1, op2, true); 4712 this->ofSub_s(inst, expr1, accumulator, op1, op2, true); 4713 this->pf_s(inst, expr1, accumulator, true); 4714 this->sf_s(inst, expr1, accumulator, true); 4715 this->zf_s(inst, expr1, accumulator, true); 4716 4717 /* Update the symbolic control flow */ 4718 this->controlFlow_s(inst); 4719 } 4720 4721 cmpxchg16b_s(triton::arch::Instruction & inst)4722 void x86Semantics::cmpxchg16b_s(triton::arch::Instruction& inst) { 4723 auto& src1 = inst.operands[0]; 4724 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX)); 4725 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX)); 4726 auto src4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RCX)); 4727 auto src5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RBX)); 4728 4729 /* Create symbolic operands */ 4730 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 4731 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 4732 auto op3 = this->symbolicEngine->getOperandAst(inst, src3); 4733 auto op4 = this->symbolicEngine->getOperandAst(inst, src4); 4734 auto op5 = this->symbolicEngine->getOperandAst(inst, src5); 4735 4736 /* Create the semantics */ 4737 /* CMP8B */ 4738 auto node1 = this->astCtxt->bvsub(this->astCtxt->concat(op2, op3), op1); 4739 /* Destination */ 4740 auto node2 = this->astCtxt->ite(this->astCtxt->equal(node1, this->astCtxt->bv(0, triton::bitsize::dqword)), this->astCtxt->concat(op4, op5), op1); 4741 /* EDX:EAX */ 4742 auto node3 = this->astCtxt->ite(this->astCtxt->equal(node1, this->astCtxt->bv(0, triton::bitsize::dqword)), this->astCtxt->concat(op2, op3), op1); 4743 4744 /* Create symbolic expression */ 4745 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMP operation"); 4746 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, src1, "XCHG16B memory operation"); 4747 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(127, 64, node3), src2, "XCHG16B RDX operation"); 4748 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(63, 0, node3), src3, "XCHG16B RAX operation"); 4749 4750 /* Spread taint */ 4751 expr1->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(src3); 4752 expr2->isTainted = this->taintEngine->setTaint(src1, this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(src3)); 4753 expr3->isTainted = this->taintEngine->taintAssignment(src2, src1); 4754 expr4->isTainted = this->taintEngine->taintAssignment(src3, src1); 4755 4756 /* Update symbolic flags */ 4757 this->zf_s(inst, expr1, src1, true); 4758 4759 /* Update the symbolic control flow */ 4760 this->controlFlow_s(inst); 4761 } 4762 4763 cmpxchg8b_s(triton::arch::Instruction & inst)4764 void x86Semantics::cmpxchg8b_s(triton::arch::Instruction& inst) { 4765 auto& src1 = inst.operands[0]; 4766 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX)); 4767 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX)); 4768 auto src4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ECX)); 4769 auto src5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EBX)); 4770 auto src2p = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_EDX)); 4771 auto src3p = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_EAX)); 4772 4773 /* Create symbolic operands */ 4774 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 4775 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 4776 auto op3 = this->symbolicEngine->getOperandAst(inst, src3); 4777 auto op4 = this->symbolicEngine->getOperandAst(inst, src4); 4778 auto op5 = this->symbolicEngine->getOperandAst(inst, src5); 4779 auto op2p = this->symbolicEngine->getOperandAst(inst, src2p); 4780 auto op3p = this->symbolicEngine->getOperandAst(inst, src3p); 4781 4782 /* Create the semantics */ 4783 /* CMP8B */ 4784 auto node1 = this->astCtxt->bvsub(this->astCtxt->concat(op2, op3), op1); 4785 /* Destination */ 4786 auto node2 = this->astCtxt->ite(this->astCtxt->equal(node1, this->astCtxt->bv(0, triton::bitsize::qword)), this->astCtxt->concat(op4, op5), op1); 4787 /* EDX:EAX */ 4788 auto node3 = this->astCtxt->ite(this->astCtxt->equal(node1, this->astCtxt->bv(0, triton::bitsize::qword)), this->astCtxt->concat(op2, op3), op1); 4789 auto node3p = this->astCtxt->ite( 4790 this->astCtxt->equal( 4791 node1, 4792 this->astCtxt->bv(0, triton::bitsize::qword)), 4793 this->astCtxt->concat(op2p, op3p), 4794 this->astCtxt->zx(src2p.getBitSize() + src3p.getBitSize() - src1.getBitSize(), op1) 4795 ); 4796 4797 /* Create symbolic expression */ 4798 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMP operation"); 4799 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, src1, "XCHG8B memory operation"); 4800 auto expr3 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node3, "Temporary operation"); 4801 auto expr4 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node3p, "Temporary operation"); 4802 4803 triton::engines::symbolic::SharedSymbolicExpression expr5 = nullptr; 4804 triton::engines::symbolic::SharedSymbolicExpression expr6 = nullptr; 4805 4806 /* EDX */ 4807 if (node1->evaluate() == 0) 4808 expr5 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract((src2p.getBitSize() * 2 - 1), src2p.getBitSize(), node3p), src2p, "XCHG8B EDX operation"); 4809 else 4810 expr5 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(63, 32, node3), src2, "XCHG8B EDX operation"); 4811 4812 /* EAX */ 4813 if (node1->evaluate() == 0) 4814 expr6 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(src2p.getBitSize() - 1, 0, node3p), src3p, "XCHG8B EAX operation"); 4815 else 4816 expr6 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(31, 0, node3), src3, "XCHG8B EAX operation"); 4817 4818 /* Spread taint */ 4819 expr1->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(src3); 4820 expr2->isTainted = this->taintEngine->setTaint(src1, this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(src3)); 4821 expr3->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(src3); 4822 expr4->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(src3); 4823 expr5->isTainted = this->taintEngine->taintAssignment(src2, src1); 4824 expr6->isTainted = this->taintEngine->taintAssignment(src3, src1); 4825 4826 /* Update symbolic flags */ 4827 this->zf_s(inst, expr1, src1, true); 4828 4829 /* Update the symbolic control flow */ 4830 this->controlFlow_s(inst); 4831 } 4832 4833 cpuid_s(triton::arch::Instruction & inst)4834 void x86Semantics::cpuid_s(triton::arch::Instruction& inst) { 4835 auto src = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_AX)); 4836 auto dst1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_AX)); 4837 auto dst2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_BX)); 4838 auto dst3 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 4839 auto dst4 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DX)); 4840 4841 /* Create symbolic operands */ 4842 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 4843 4844 /* Create the semantics */ 4845 triton::ast::SharedAbstractNode node1 = nullptr; 4846 triton::ast::SharedAbstractNode node2 = nullptr; 4847 triton::ast::SharedAbstractNode node3 = nullptr; 4848 triton::ast::SharedAbstractNode node4 = nullptr; 4849 4850 /* In this case, we concretize the AX option */ 4851 switch (op1->evaluate().convert_to<triton::uint32>()) { 4852 case 0: 4853 node1 = this->astCtxt->bv(0x0000000d, dst1.getBitSize()); 4854 node2 = this->astCtxt->bv(0x756e6547, dst2.getBitSize()); 4855 node3 = this->astCtxt->bv(0x6c65746e, dst3.getBitSize()); 4856 node4 = this->astCtxt->bv(0x49656e69, dst4.getBitSize()); 4857 break; 4858 case 1: 4859 node1 = this->astCtxt->bv(0x000306a9, dst1.getBitSize()); 4860 node2 = this->astCtxt->bv(0x02100800, dst2.getBitSize()); 4861 node3 = this->astCtxt->bv(0x7fbae3ff, dst3.getBitSize()); 4862 node4 = this->astCtxt->bv(0xbfebfbff, dst4.getBitSize()); 4863 break; 4864 case 2: 4865 node1 = this->astCtxt->bv(0x76035a01, dst1.getBitSize()); 4866 node2 = this->astCtxt->bv(0x00f0b2ff, dst2.getBitSize()); 4867 node3 = this->astCtxt->bv(0x00000000, dst3.getBitSize()); 4868 node4 = this->astCtxt->bv(0x00ca0000, dst4.getBitSize()); 4869 break; 4870 case 3: 4871 node1 = this->astCtxt->bv(0x00000000, dst1.getBitSize()); 4872 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize()); 4873 node3 = this->astCtxt->bv(0x00000000, dst3.getBitSize()); 4874 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize()); 4875 break; 4876 case 4: 4877 node1 = this->astCtxt->bv(0x1c004121, dst1.getBitSize()); 4878 node2 = this->astCtxt->bv(0x01c0003f, dst2.getBitSize()); 4879 node3 = this->astCtxt->bv(0x0000003f, dst3.getBitSize()); 4880 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize()); 4881 break; 4882 case 5: 4883 node1 = this->astCtxt->bv(0x00000040, dst1.getBitSize()); 4884 node2 = this->astCtxt->bv(0x00000040, dst2.getBitSize()); 4885 node3 = this->astCtxt->bv(0x00000003, dst3.getBitSize()); 4886 node4 = this->astCtxt->bv(0x00021120, dst4.getBitSize()); 4887 break; 4888 case 0x80000000: 4889 node1 = this->astCtxt->bv(0x80000008, dst1.getBitSize()); 4890 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize()); 4891 node3 = this->astCtxt->bv(0x00000000, dst3.getBitSize()); 4892 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize()); 4893 break; 4894 case 0x80000001: 4895 node1 = this->astCtxt->bv(0x00000000, dst1.getBitSize()); 4896 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize()); 4897 node3 = this->astCtxt->bv(0x00000001, dst3.getBitSize()); 4898 node4 = this->astCtxt->bv(0x28100800, dst4.getBitSize()); 4899 break; 4900 case 0x80000002: 4901 node1 = this->astCtxt->bv(0x20202020, dst1.getBitSize()); 4902 node2 = this->astCtxt->bv(0x49202020, dst2.getBitSize()); 4903 node3 = this->astCtxt->bv(0x6c65746e, dst3.getBitSize()); 4904 node4 = this->astCtxt->bv(0x20295228, dst4.getBitSize()); 4905 break; 4906 case 0x80000003: 4907 node1 = this->astCtxt->bv(0x65726f43, dst1.getBitSize()); 4908 node2 = this->astCtxt->bv(0x294d5428, dst2.getBitSize()); 4909 node3 = this->astCtxt->bv(0x2d376920, dst3.getBitSize()); 4910 node4 = this->astCtxt->bv(0x30323533, dst4.getBitSize()); 4911 break; 4912 case 0x80000004: 4913 node1 = this->astCtxt->bv(0x5043204d, dst1.getBitSize()); 4914 node2 = this->astCtxt->bv(0x20402055, dst2.getBitSize()); 4915 node3 = this->astCtxt->bv(0x30392e32, dst3.getBitSize()); 4916 node4 = this->astCtxt->bv(0x007a4847, dst4.getBitSize()); 4917 break; 4918 case 0x80000005: 4919 node1 = this->astCtxt->bv(0x00000000, dst1.getBitSize()); 4920 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize()); 4921 node3 = this->astCtxt->bv(0x00000000, dst3.getBitSize()); 4922 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize()); 4923 break; 4924 case 0x80000006: 4925 node1 = this->astCtxt->bv(0x00000000, dst1.getBitSize()); 4926 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize()); 4927 node3 = this->astCtxt->bv(0x01006040, dst3.getBitSize()); 4928 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize()); 4929 break; 4930 case 0x80000007: 4931 node1 = this->astCtxt->bv(0x00000000, dst1.getBitSize()); 4932 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize()); 4933 node3 = this->astCtxt->bv(0x00000000, dst3.getBitSize()); 4934 node4 = this->astCtxt->bv(0x00000100, dst4.getBitSize()); 4935 break; 4936 case 0x80000008: 4937 node1 = this->astCtxt->bv(0x00003024, dst1.getBitSize()); 4938 node2 = this->astCtxt->bv(0x00000000, dst2.getBitSize()); 4939 node3 = this->astCtxt->bv(0x00000000, dst3.getBitSize()); 4940 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize()); 4941 break; 4942 default: 4943 node1 = this->astCtxt->bv(0x00000007, dst1.getBitSize()); 4944 node2 = this->astCtxt->bv(0x00000340, dst2.getBitSize()); 4945 node3 = this->astCtxt->bv(0x00000340, dst3.getBitSize()); 4946 node4 = this->astCtxt->bv(0x00000000, dst4.getBitSize()); 4947 break; 4948 } 4949 4950 /* Create symbolic expression */ 4951 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1, "CPUID AX operation"); 4952 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "CPUID BX operation"); 4953 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3, "CPUID CX operation"); 4954 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4, "CPUID DX operation"); 4955 4956 /* Spread taint */ 4957 expr1->isTainted = this->taintEngine->setTaintRegister(this->architecture->getParentRegister(ID_REG_X86_AX), false); 4958 expr2->isTainted = this->taintEngine->setTaintRegister(this->architecture->getParentRegister(ID_REG_X86_BX), false); 4959 expr3->isTainted = this->taintEngine->setTaintRegister(this->architecture->getParentRegister(ID_REG_X86_CX), false); 4960 expr4->isTainted = this->taintEngine->setTaintRegister(this->architecture->getParentRegister(ID_REG_X86_DX), false); 4961 4962 /* Update the symbolic control flow */ 4963 this->controlFlow_s(inst); 4964 } 4965 4966 cqo_s(triton::arch::Instruction & inst)4967 void x86Semantics::cqo_s(triton::arch::Instruction& inst) { 4968 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX)); 4969 auto src = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX)); 4970 4971 /* Create symbolic operands */ 4972 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 4973 4974 /* Create the semantics - TMP = 128 bitvec (RDX:RAX) */ 4975 auto node1 = this->astCtxt->sx(triton::bitsize::qword, op1); 4976 4977 /* Create symbolic expression */ 4978 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "Temporary variable"); 4979 4980 /* Spread taint */ 4981 expr1->isTainted = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_RAX)); 4982 4983 /* Create the semantics - RDX = TMP[127...64] */ 4984 auto node2 = this->astCtxt->extract(triton::bitsize::dqword-1, triton::bitsize::qword, this->astCtxt->reference(expr1)); 4985 4986 /* Create symbolic expression */ 4987 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "CQO operation"); 4988 4989 /* Spread taint */ 4990 expr2->isTainted = this->taintEngine->taintAssignment(dst, src); 4991 4992 /* Update the symbolic control flow */ 4993 this->controlFlow_s(inst); 4994 } 4995 4996 cwd_s(triton::arch::Instruction & inst)4997 void x86Semantics::cwd_s(triton::arch::Instruction& inst) { 4998 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DX)); 4999 auto src = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX)); 5000 5001 /* Create symbolic operands */ 5002 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 5003 5004 /* Create the semantics - TMP = 32 bitvec (DX:AX) */ 5005 auto node1 = this->astCtxt->sx(triton::bitsize::word, op1); 5006 5007 /* Create symbolic expression */ 5008 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "Temporary variable"); 5009 5010 /* Spread taint */ 5011 expr1->isTainted = this->taintEngine->isRegisterTainted(this->architecture->getRegister(ID_REG_X86_AX)); 5012 5013 /* Create the semantics - DX = TMP[31...16] */ 5014 auto node2 = this->astCtxt->extract(triton::bitsize::dword-1, triton::bitsize::word, this->astCtxt->reference(expr1)); 5015 5016 /* Create symbolic expression */ 5017 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "CWD operation"); 5018 5019 /* Spread taint */ 5020 expr2->isTainted = this->taintEngine->taintAssignment(dst, src); 5021 5022 /* Update the symbolic control flow */ 5023 this->controlFlow_s(inst); 5024 } 5025 5026 cwde_s(triton::arch::Instruction & inst)5027 void x86Semantics::cwde_s(triton::arch::Instruction& inst) { 5028 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX)); 5029 5030 /* Create symbolic operands */ 5031 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 5032 5033 /* Create the semantics */ 5034 auto node = this->astCtxt->sx(triton::bitsize::word, this->astCtxt->extract(triton::bitsize::word-1, 0, op1)); 5035 5036 /* Create symbolic expression */ 5037 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "CWDE operation"); 5038 5039 /* Spread taint */ 5040 expr->isTainted = this->taintEngine->taintAssignment(dst, dst); 5041 5042 /* Update the symbolic control flow */ 5043 this->controlFlow_s(inst); 5044 } 5045 5046 dec_s(triton::arch::Instruction & inst)5047 void x86Semantics::dec_s(triton::arch::Instruction& inst) { 5048 auto& dst = inst.operands[0]; 5049 5050 /* Create symbolic operands */ 5051 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 5052 auto op2 = this->astCtxt->bv(1, dst.getBitSize()); 5053 5054 /* Create the semantics */ 5055 auto node = this->astCtxt->bvsub(op1, op2); 5056 5057 /* Create symbolic expression */ 5058 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "DEC operation"); 5059 5060 /* Spread taint */ 5061 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 5062 5063 /* Update symbolic flags */ 5064 this->af_s(inst, expr, dst, op1, op2); 5065 this->ofSub_s(inst, expr, dst, op1, op2); 5066 this->pf_s(inst, expr, dst); 5067 this->sf_s(inst, expr, dst); 5068 this->zf_s(inst, expr, dst); 5069 5070 /* Update the symbolic control flow */ 5071 this->controlFlow_s(inst); 5072 } 5073 5074 div_s(triton::arch::Instruction & inst)5075 void x86Semantics::div_s(triton::arch::Instruction& inst) { 5076 auto& src = inst.operands[0]; 5077 5078 /* Create symbolic operands */ 5079 auto divisor = this->symbolicEngine->getOperandAst(inst, src); 5080 5081 /* Create symbolic expression */ 5082 switch (src.getSize()) { 5083 5084 case triton::size::byte: { 5085 /* AX */ 5086 auto ax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX)); 5087 auto dividend = this->symbolicEngine->getOperandAst(inst, ax); 5088 /* res = AX / Source */ 5089 auto result = this->astCtxt->bvudiv(dividend, this->astCtxt->zx(triton::bitsize::byte, divisor)); 5090 /* mod = AX % Source */ 5091 auto mod = this->astCtxt->bvurem(dividend, this->astCtxt->zx(triton::bitsize::byte, divisor)); 5092 /* AH = mod */ 5093 /* AL = res */ 5094 auto node = this->astCtxt->concat( 5095 this->astCtxt->extract((triton::bitsize::byte - 1), 0, mod), /* AH = mod */ 5096 this->astCtxt->extract((triton::bitsize::byte - 1), 0, result) /* AL = res */ 5097 ); 5098 /* Create symbolic expression */ 5099 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, ax, "DIV operation"); 5100 /* Apply the taint */ 5101 expr->isTainted = this->taintEngine->taintUnion(ax, src); 5102 break; 5103 } 5104 5105 case triton::size::word: { 5106 /* DX:AX */ 5107 auto dx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DX)); 5108 auto ax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX)); 5109 auto dividend = this->astCtxt->concat(this->symbolicEngine->getOperandAst(inst, dx), this->symbolicEngine->getOperandAst(inst, ax)); 5110 /* res = DX:AX / Source */ 5111 auto result = this->astCtxt->extract((triton::bitsize::word - 1), 0, this->astCtxt->bvudiv(dividend, this->astCtxt->zx(triton::bitsize::word, divisor))); 5112 /* mod = DX:AX % Source */ 5113 auto mod = this->astCtxt->extract((triton::bitsize::word - 1), 0, this->astCtxt->bvurem(dividend, this->astCtxt->zx(triton::bitsize::word, divisor))); 5114 /* Create the symbolic expression for AX */ 5115 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, result, ax, "DIV operation"); 5116 /* Apply the taint for AX */ 5117 expr1->isTainted = this->taintEngine->taintUnion(ax, src); 5118 /* Create the symbolic expression for DX */ 5119 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, mod, dx, "DIV operation"); 5120 /* Apply the taint for DX */ 5121 expr2->isTainted = this->taintEngine->taintUnion(dx, src); 5122 break; 5123 } 5124 5125 case triton::size::dword: { 5126 /* EDX:EAX */ 5127 auto edx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX)); 5128 auto eax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX)); 5129 auto dividend = this->astCtxt->concat(this->symbolicEngine->getOperandAst(inst, edx), this->symbolicEngine->getOperandAst(inst, eax)); 5130 /* res = EDX:EAX / Source */ 5131 auto result = this->astCtxt->extract((triton::bitsize::dword - 1), 0, this->astCtxt->bvudiv(dividend, this->astCtxt->zx(triton::bitsize::dword, divisor))); 5132 /* mod = EDX:EAX % Source */ 5133 auto mod = this->astCtxt->extract((triton::bitsize::dword - 1), 0, this->astCtxt->bvurem(dividend, this->astCtxt->zx(triton::bitsize::dword, divisor))); 5134 /* Create the symbolic expression for EAX */ 5135 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, result, eax, "DIV operation"); 5136 /* Apply the taint for EAX */ 5137 expr1->isTainted = this->taintEngine->taintUnion(eax, src); 5138 /* Create the symbolic expression for EDX */ 5139 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, mod, edx, "DIV operation"); 5140 /* Apply the taint for EDX */ 5141 expr2->isTainted = this->taintEngine->taintUnion(edx, src); 5142 break; 5143 } 5144 5145 case triton::size::qword: { 5146 /* RDX:RAX */ 5147 auto rdx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX)); 5148 auto rax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX)); 5149 auto dividend = this->astCtxt->concat(this->symbolicEngine->getOperandAst(inst, rdx), this->symbolicEngine->getOperandAst(inst, rax)); 5150 /* res = RDX:RAX / Source */ 5151 auto result = this->astCtxt->extract((triton::bitsize::qword - 1), 0, this->astCtxt->bvudiv(dividend, this->astCtxt->zx(triton::bitsize::qword, divisor))); 5152 /* mod = RDX:RAX % Source */ 5153 auto mod = this->astCtxt->extract((triton::bitsize::qword - 1), 0, this->astCtxt->bvurem(dividend, this->astCtxt->zx(triton::bitsize::qword, divisor))); 5154 /* Create the symbolic expression for RAX */ 5155 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, result, rax, "DIV operation"); 5156 /* Apply the taint for EAX */ 5157 expr1->isTainted = this->taintEngine->taintUnion(rax, src); 5158 /* Create the symbolic expression for RDX */ 5159 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, mod, rdx, "DIV operation"); 5160 /* Apply the taint for EDX */ 5161 expr2->isTainted = this->taintEngine->taintUnion(rdx, src); 5162 break; 5163 } 5164 5165 } 5166 5167 /* Tag undefined flags */ 5168 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 5169 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF)); 5170 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 5171 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF)); 5172 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF)); 5173 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF)); 5174 5175 /* Update the symbolic control flow */ 5176 this->controlFlow_s(inst); 5177 } 5178 5179 endbr32_s(triton::arch::Instruction & inst)5180 void x86Semantics::endbr32_s(triton::arch::Instruction& inst) { 5181 /* Update the symbolic control flow */ 5182 this->controlFlow_s(inst); 5183 } 5184 5185 endbr64_s(triton::arch::Instruction & inst)5186 void x86Semantics::endbr64_s(triton::arch::Instruction& inst) { 5187 /* Update the symbolic control flow */ 5188 this->controlFlow_s(inst); 5189 } 5190 5191 extractps_s(triton::arch::Instruction & inst)5192 void x86Semantics::extractps_s(triton::arch::Instruction& inst) { 5193 auto& dst = inst.operands[0]; 5194 auto& src1 = inst.operands[1]; 5195 auto& src2 = inst.operands[2]; 5196 5197 /* Create symbolic operands */ 5198 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 5199 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 5200 5201 /* Create the semantics */ 5202 auto node = this->astCtxt->extract(triton::bitsize::dword-1, 0, 5203 this->astCtxt->bvlshr( 5204 op2, 5205 this->astCtxt->bvmul( 5206 this->astCtxt->zx(126, this->astCtxt->extract(1, 0, op3)), 5207 this->astCtxt->bv(triton::bitsize::dword, triton::bitsize::dqword) 5208 ) 5209 ) 5210 ); 5211 5212 switch (dst.getBitSize()) { 5213 case triton::bitsize::dword: 5214 break; 5215 case triton::bitsize::qword: 5216 node = this->astCtxt->zx(triton::bitsize::dword, node); 5217 break; 5218 default: 5219 throw triton::exceptions::Semantics("x86Semantics::extractps_s(): Invalid destination operand."); 5220 } 5221 5222 /* Create symbolic expression */ 5223 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "EXTRACTPS operation"); 5224 5225 /* Spread taint */ 5226 expr->isTainted = this->taintEngine->taintAssignment(dst, src1); 5227 5228 /* Update the symbolic control flow */ 5229 this->controlFlow_s(inst); 5230 } 5231 5232 idiv_s(triton::arch::Instruction & inst)5233 void x86Semantics::idiv_s(triton::arch::Instruction& inst) { 5234 auto& src = inst.operands[0]; 5235 5236 /* Create symbolic operands */ 5237 auto divisor = this->symbolicEngine->getOperandAst(inst, src); 5238 5239 /* Create symbolic expression */ 5240 switch (src.getSize()) { 5241 5242 case triton::size::byte: { 5243 /* AX */ 5244 auto ax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX)); 5245 auto dividend = this->symbolicEngine->getOperandAst(inst, ax); 5246 /* res = AX / Source */ 5247 auto result = this->astCtxt->bvsdiv(dividend, this->astCtxt->sx(triton::bitsize::byte, divisor)); 5248 /* mod = AX % Source */ 5249 auto mod = this->astCtxt->bvsrem(dividend, this->astCtxt->sx(triton::bitsize::byte, divisor)); 5250 /* AH = mod */ 5251 /* AL = res */ 5252 auto node = this->astCtxt->concat( 5253 this->astCtxt->extract((triton::bitsize::byte - 1), 0, mod), /* AH = mod */ 5254 this->astCtxt->extract((triton::bitsize::byte - 1), 0, result) /* AL = res */ 5255 ); 5256 /* Create symbolic expression */ 5257 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, ax, "IDIV operation"); 5258 /* Apply the taint */ 5259 expr->isTainted = this->taintEngine->taintUnion(ax, src); 5260 break; 5261 } 5262 5263 case triton::size::word: { 5264 /* DX:AX */ 5265 auto dx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DX)); 5266 auto ax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX)); 5267 auto dividend = this->astCtxt->concat(this->symbolicEngine->getOperandAst(inst, dx), this->symbolicEngine->getOperandAst(inst, ax)); 5268 /* res = DX:AX / Source */ 5269 auto result = this->astCtxt->extract((triton::bitsize::word - 1), 0, this->astCtxt->bvsdiv(dividend, this->astCtxt->sx(triton::bitsize::word, divisor))); 5270 /* mod = DX:AX % Source */ 5271 auto mod = this->astCtxt->extract((triton::bitsize::word - 1), 0, this->astCtxt->bvsrem(dividend, this->astCtxt->sx(triton::bitsize::word, divisor))); 5272 /* Create the symbolic expression for AX */ 5273 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, result, ax, "IDIV operation"); 5274 /* Apply the taint for AX */ 5275 expr1->isTainted = this->taintEngine->taintUnion(ax, src); 5276 /* Create the symbolic expression for DX */ 5277 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, mod, dx, "IDIV operation"); 5278 /* Apply the taint for DX */ 5279 expr2->isTainted = this->taintEngine->taintUnion(dx, src); 5280 break; 5281 } 5282 5283 case triton::size::dword: { 5284 /* EDX:EAX */ 5285 auto edx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX)); 5286 auto eax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX)); 5287 auto dividend = this->astCtxt->concat(this->symbolicEngine->getOperandAst(inst, edx), this->symbolicEngine->getOperandAst(inst, eax)); 5288 /* res = EDX:EAX / Source */ 5289 auto result = this->astCtxt->extract((triton::bitsize::dword - 1), 0, this->astCtxt->bvsdiv(dividend, this->astCtxt->sx(triton::bitsize::dword, divisor))); 5290 /* mod = EDX:EAX % Source */ 5291 auto mod = this->astCtxt->extract((triton::bitsize::dword - 1), 0, this->astCtxt->bvsrem(dividend, this->astCtxt->sx(triton::bitsize::dword, divisor))); 5292 /* Create the symbolic expression for EAX */ 5293 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, result, eax, "IDIV operation"); 5294 /* Apply the taint for EAX */ 5295 expr1->isTainted = this->taintEngine->taintUnion(eax, src); 5296 /* Create the symbolic expression for EDX */ 5297 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, mod, edx, "IDIV operation"); 5298 /* Apply the taint for EDX */ 5299 expr2->isTainted = this->taintEngine->taintUnion(edx, src); 5300 break; 5301 } 5302 5303 case triton::size::qword: { 5304 /* RDX:RAX */ 5305 auto rdx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX)); 5306 auto rax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX)); 5307 auto dividend = this->astCtxt->concat(this->symbolicEngine->getOperandAst(inst, rdx), this->symbolicEngine->getOperandAst(inst, rax)); 5308 /* res = RDX:RAX / Source */ 5309 auto result = this->astCtxt->extract((triton::bitsize::qword - 1), 0, this->astCtxt->bvsdiv(dividend, this->astCtxt->sx(triton::bitsize::qword, divisor))); 5310 /* mod = RDX:RAX % Source */ 5311 auto mod = this->astCtxt->extract((triton::bitsize::qword - 1), 0, this->astCtxt->bvsrem(dividend, this->astCtxt->sx(triton::bitsize::qword, divisor))); 5312 /* Create the symbolic expression for RAX */ 5313 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, result, rax, "IDIV operation"); 5314 /* Apply the taint for EAX */ 5315 expr1->isTainted = this->taintEngine->taintUnion(rax, src); 5316 /* Create the symbolic expression for RDX */ 5317 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, mod, rdx, "IDIV operation"); 5318 /* Apply the taint for EDX */ 5319 expr2->isTainted = this->taintEngine->taintUnion(rdx, src); 5320 break; 5321 } 5322 5323 } 5324 5325 /* Tag undefined flags */ 5326 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 5327 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF)); 5328 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 5329 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF)); 5330 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF)); 5331 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF)); 5332 5333 /* Update the symbolic control flow */ 5334 this->controlFlow_s(inst); 5335 } 5336 5337 imul_s(triton::arch::Instruction & inst)5338 void x86Semantics::imul_s(triton::arch::Instruction& inst) { 5339 switch (inst.operands.size()) { 5340 5341 /* one operand */ 5342 case 1: { 5343 auto& src = inst.operands[0]; 5344 5345 /* size of the Operand */ 5346 switch (src.getSize()) { 5347 5348 /* dst = AX */ 5349 case triton::size::byte: { 5350 auto ax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX)); 5351 auto al = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL)); 5352 auto op1 = this->symbolicEngine->getOperandAst(inst, al); 5353 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 5354 auto node = this->astCtxt->bvmul(this->astCtxt->sx(triton::bitsize::byte, op1), this->astCtxt->sx(triton::bitsize::byte, op2)); 5355 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, ax, "IMUL operation"); 5356 expr->isTainted = this->taintEngine->taintUnion(ax, src); 5357 this->cfImul_s(inst, expr, al, this->astCtxt->bvmul(op1, op2), node); 5358 this->ofImul_s(inst, expr, al, this->astCtxt->bvmul(op1, op2), node); 5359 break; 5360 } 5361 5362 /* dst = DX:AX */ 5363 case triton::size::word: { 5364 auto ax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX)); 5365 auto dx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DX)); 5366 auto op1 = this->symbolicEngine->getOperandAst(inst, ax); 5367 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 5368 auto node = this->astCtxt->bvmul(this->astCtxt->sx(triton::bitsize::word, op1), this->astCtxt->sx(triton::bitsize::word, op2)); 5369 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(triton::bitsize::word-1, 0, node), ax, "IMUL operation"); 5370 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(triton::bitsize::dword-1, triton::bitsize::word, node), dx, "IMUL operation"); 5371 expr1->isTainted = this->taintEngine->taintUnion(ax, src); 5372 expr2->isTainted = this->taintEngine->taintUnion(dx, ax); 5373 this->cfImul_s(inst, expr1, ax, this->astCtxt->bvmul(op1, op2), node); 5374 this->ofImul_s(inst, expr1, ax, this->astCtxt->bvmul(op1, op2), node); 5375 break; 5376 } 5377 5378 /* dst = EDX:EAX */ 5379 case triton::size::dword: { 5380 auto eax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX)); 5381 auto edx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX)); 5382 auto op1 = this->symbolicEngine->getOperandAst(inst, eax); 5383 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 5384 auto node = this->astCtxt->bvmul(this->astCtxt->sx(triton::bitsize::dword, op1), this->astCtxt->sx(triton::bitsize::dword, op2)); 5385 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(triton::bitsize::dword-1, 0, node), eax, "IMUL operation"); 5386 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(triton::bitsize::qword-1, triton::bitsize::dword, node), edx, "IMUL operation"); 5387 expr1->isTainted = this->taintEngine->taintUnion(eax, src); 5388 expr2->isTainted = this->taintEngine->taintUnion(edx, eax); 5389 this->cfImul_s(inst, expr1, eax, this->astCtxt->bvmul(op1, op2), node); 5390 this->ofImul_s(inst, expr1, eax, this->astCtxt->bvmul(op1, op2), node); 5391 break; 5392 } 5393 5394 /* dst = RDX:RAX */ 5395 case triton::size::qword: { 5396 auto rax = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX)); 5397 auto rdx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX)); 5398 auto op1 = this->symbolicEngine->getOperandAst(inst, rax); 5399 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 5400 auto node = this->astCtxt->bvmul(this->astCtxt->sx(triton::bitsize::qword, op1), this->astCtxt->sx(triton::bitsize::qword, op2)); 5401 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(triton::bitsize::qword-1, 0, node), rax, "IMUL operation"); 5402 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(triton::bitsize::dqword-1, triton::bitsize::qword, node), rdx, "IMUL operation"); 5403 expr1->isTainted = this->taintEngine->taintUnion(rax, src); 5404 expr2->isTainted = this->taintEngine->taintUnion(rdx, rax); 5405 this->cfImul_s(inst, expr1, rax, this->astCtxt->bvmul(op1, op2), node); 5406 this->ofImul_s(inst, expr1, rax, this->astCtxt->bvmul(op1, op2), node); 5407 break; 5408 } 5409 5410 } 5411 break; 5412 } 5413 5414 /* two operands */ 5415 case 2: { 5416 auto& dst = inst.operands[0]; 5417 auto& src = inst.operands[1]; 5418 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 5419 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 5420 auto node = this->astCtxt->bvmul(this->astCtxt->sx(dst.getBitSize(), op1), this->astCtxt->sx(src.getBitSize(), op2)); 5421 auto expr = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(dst.getBitSize()-1, 0, node), dst, "IMUL operation"); 5422 expr->isTainted = this->taintEngine->taintUnion(dst, src); 5423 this->cfImul_s(inst, expr, dst, this->astCtxt->bvmul(op1, op2), node); 5424 this->ofImul_s(inst, expr, dst, this->astCtxt->bvmul(op1, op2), node); 5425 break; 5426 } 5427 5428 /* three operands */ 5429 case 3: { 5430 auto& dst = inst.operands[0]; 5431 auto& src1 = inst.operands[1]; 5432 auto& src2 = inst.operands[2]; 5433 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 5434 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 5435 auto node = this->astCtxt->bvmul(this->astCtxt->sx(src1.getBitSize(), op2), this->astCtxt->sx(src2.getBitSize(), op3)); 5436 auto expr = this->symbolicEngine->createSymbolicExpression(inst, this->astCtxt->extract(dst.getBitSize()-1, 0, node), dst, "IMUL operation"); 5437 expr->isTainted = this->taintEngine->setTaint(dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2)); 5438 this->cfImul_s(inst, expr, dst, this->astCtxt->bvmul(op2, op3), node); 5439 this->ofImul_s(inst, expr, dst, this->astCtxt->bvmul(op2, op3), node); 5440 break; 5441 } 5442 5443 } 5444 5445 /* Tag undefined flags */ 5446 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 5447 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF)); 5448 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF)); 5449 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF)); 5450 5451 /* Update the symbolic control flow */ 5452 this->controlFlow_s(inst); 5453 } 5454 5455 inc_s(triton::arch::Instruction & inst)5456 void x86Semantics::inc_s(triton::arch::Instruction& inst) { 5457 auto& dst = inst.operands[0]; 5458 5459 /* Create symbolic operands */ 5460 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 5461 auto op2 = this->astCtxt->bv(1, dst.getBitSize()); 5462 5463 /* Create the semantics */ 5464 auto node = this->astCtxt->bvadd(op1, op2); 5465 5466 /* Create symbolic expression */ 5467 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "INC operation"); 5468 5469 /* Spread taint */ 5470 expr->isTainted = this->taintEngine->taintUnion(dst, dst); 5471 5472 /* Update symbolic flags */ 5473 this->af_s(inst, expr, dst, op1, op2); 5474 this->ofAdd_s(inst, expr, dst, op1, op2); 5475 this->pf_s(inst, expr, dst); 5476 this->sf_s(inst, expr, dst); 5477 this->zf_s(inst, expr, dst); 5478 5479 /* Update the symbolic control flow */ 5480 this->controlFlow_s(inst); 5481 } 5482 5483 invd_s(triton::arch::Instruction & inst)5484 void x86Semantics::invd_s(triton::arch::Instruction& inst) { 5485 /* Update the symbolic control flow */ 5486 this->controlFlow_s(inst); 5487 } 5488 5489 invlpg_s(triton::arch::Instruction & inst)5490 void x86Semantics::invlpg_s(triton::arch::Instruction& inst) { 5491 /* Update the symbolic control flow */ 5492 this->controlFlow_s(inst); 5493 } 5494 5495 ja_s(triton::arch::Instruction & inst)5496 void x86Semantics::ja_s(triton::arch::Instruction& inst) { 5497 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 5498 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 5499 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 5500 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize())); 5501 auto& srcImm2 = inst.operands[0]; 5502 5503 /* Create symbolic operands */ 5504 auto op1 = this->symbolicEngine->getOperandAst(inst, cf); 5505 auto op2 = this->symbolicEngine->getOperandAst(inst, zf); 5506 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm1); 5507 auto op4 = this->symbolicEngine->getOperandAst(inst, srcImm2); 5508 5509 /* Create the semantics */ 5510 auto node = this->astCtxt->ite( 5511 this->astCtxt->equal( 5512 this->astCtxt->bvand( 5513 this->astCtxt->bvnot(op1), 5514 this->astCtxt->bvnot(op2) 5515 ), 5516 this->astCtxt->bvtrue() 5517 ), op4, op3); 5518 5519 /* Create symbolic expression */ 5520 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 5521 5522 /* Set condition flag */ 5523 if (op1->evaluate().is_zero() && op2->evaluate().is_zero()) 5524 inst.setConditionTaken(true); 5525 5526 /* Spread taint */ 5527 expr->isTainted = this->taintEngine->taintAssignment(pc, cf); 5528 expr->isTainted = this->taintEngine->taintUnion(pc, zf); 5529 5530 /* Create the path constraint */ 5531 this->symbolicEngine->pushPathConstraint(inst, expr); 5532 } 5533 5534 jae_s(triton::arch::Instruction & inst)5535 void x86Semantics::jae_s(triton::arch::Instruction& inst) { 5536 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 5537 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 5538 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize())); 5539 auto& srcImm2 = inst.operands[0]; 5540 5541 /* Create symbolic operands */ 5542 auto op1 = this->symbolicEngine->getOperandAst(inst, cf); 5543 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1); 5544 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2); 5545 5546 /* Create the semantics */ 5547 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvfalse()), op3, op2); 5548 5549 /* Create symbolic expression */ 5550 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 5551 5552 /* Set condition flag */ 5553 if (op1->evaluate().is_zero()) 5554 inst.setConditionTaken(true); 5555 5556 /* Spread taint */ 5557 expr->isTainted = this->taintEngine->taintAssignment(pc, cf); 5558 5559 /* Create the path constraint */ 5560 this->symbolicEngine->pushPathConstraint(inst, expr); 5561 } 5562 5563 jb_s(triton::arch::Instruction & inst)5564 void x86Semantics::jb_s(triton::arch::Instruction& inst) { 5565 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 5566 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 5567 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize())); 5568 auto& srcImm2 = inst.operands[0]; 5569 5570 /* Create symbolic operands */ 5571 auto op1 = this->symbolicEngine->getOperandAst(inst, cf); 5572 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1); 5573 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2); 5574 5575 /* Create the semantics */ 5576 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvtrue()), op3, op2); 5577 5578 /* Create symbolic expression */ 5579 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 5580 5581 /* Set condition flag */ 5582 if (!op1->evaluate().is_zero()) 5583 inst.setConditionTaken(true); 5584 5585 /* Spread taint */ 5586 expr->isTainted = this->taintEngine->taintAssignment(pc, cf); 5587 5588 /* Create the path constraint */ 5589 this->symbolicEngine->pushPathConstraint(inst, expr); 5590 } 5591 5592 jbe_s(triton::arch::Instruction & inst)5593 void x86Semantics::jbe_s(triton::arch::Instruction& inst) { 5594 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 5595 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 5596 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 5597 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize())); 5598 auto& srcImm2 = inst.operands[0]; 5599 5600 /* Create symbolic operands */ 5601 auto op1 = this->symbolicEngine->getOperandAst(inst, cf); 5602 auto op2 = this->symbolicEngine->getOperandAst(inst, zf); 5603 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm1); 5604 auto op4 = this->symbolicEngine->getOperandAst(inst, srcImm2); 5605 5606 /* Create the semantics */ 5607 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvor(op1, op2), this->astCtxt->bvtrue()), op4, op3); 5608 5609 /* Create symbolic expression */ 5610 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 5611 5612 /* Set condition flag */ 5613 if (!op1->evaluate().is_zero() || !op2->evaluate().is_zero()) 5614 inst.setConditionTaken(true); 5615 5616 /* Spread taint */ 5617 expr->isTainted = this->taintEngine->taintAssignment(pc, cf); 5618 expr->isTainted = this->taintEngine->taintUnion(pc, zf); 5619 5620 /* Create the path constraint */ 5621 this->symbolicEngine->pushPathConstraint(inst, expr); 5622 } 5623 5624 jcxz_s(triton::arch::Instruction & inst)5625 void x86Semantics::jcxz_s(triton::arch::Instruction& inst) { 5626 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 5627 auto cx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CX)); 5628 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize())); 5629 auto& srcImm2 = inst.operands[0]; 5630 5631 /* Create symbolic operands */ 5632 auto op1 = this->symbolicEngine->getOperandAst(inst, cx); 5633 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1); 5634 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2); 5635 5636 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bv(0, triton::bitsize::word)), op3, op2); 5637 5638 /* Create symbolic expression */ 5639 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 5640 5641 /* Set condition flag */ 5642 if (!op1->evaluate().is_zero()) 5643 inst.setConditionTaken(true); 5644 5645 /* Spread taint */ 5646 expr->isTainted = this->taintEngine->taintAssignment(pc, cx); 5647 5648 /* Create the path constraint */ 5649 this->symbolicEngine->pushPathConstraint(inst, expr); 5650 } 5651 5652 je_s(triton::arch::Instruction & inst)5653 void x86Semantics::je_s(triton::arch::Instruction& inst) { 5654 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 5655 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 5656 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize())); 5657 auto& srcImm2 = inst.operands[0]; 5658 5659 /* Create symbolic operands */ 5660 auto op1 = this->symbolicEngine->getOperandAst(inst, zf); 5661 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1); 5662 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2); 5663 5664 /* Create the semantics */ 5665 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvtrue()), op3, op2); 5666 5667 /* Create symbolic expression */ 5668 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 5669 5670 /* Set condition flag */ 5671 if (!op1->evaluate().is_zero()) 5672 inst.setConditionTaken(true); 5673 5674 /* Spread taint */ 5675 expr->isTainted = this->taintEngine->taintAssignment(pc, zf); 5676 5677 /* Create the path constraint */ 5678 this->symbolicEngine->pushPathConstraint(inst, expr); 5679 } 5680 5681 jecxz_s(triton::arch::Instruction & inst)5682 void x86Semantics::jecxz_s(triton::arch::Instruction& inst) { 5683 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 5684 auto ecx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ECX)); 5685 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize())); 5686 auto& srcImm2 = inst.operands[0]; 5687 5688 /* Create symbolic operands */ 5689 auto op1 = this->symbolicEngine->getOperandAst(inst, ecx); 5690 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1); 5691 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2); 5692 5693 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bv(0, triton::bitsize::dword)), op3, op2); 5694 5695 /* Create symbolic expression */ 5696 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 5697 5698 /* Set condition flag */ 5699 if (!op1->evaluate().is_zero()) 5700 inst.setConditionTaken(true); 5701 5702 /* Spread taint */ 5703 expr->isTainted = this->taintEngine->taintAssignment(pc, ecx); 5704 5705 /* Create the path constraint */ 5706 this->symbolicEngine->pushPathConstraint(inst, expr); 5707 } 5708 5709 jg_s(triton::arch::Instruction & inst)5710 void x86Semantics::jg_s(triton::arch::Instruction& inst) { 5711 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 5712 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 5713 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 5714 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 5715 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize())); 5716 auto& srcImm2 = inst.operands[0]; 5717 5718 /* Create symbolic operands */ 5719 auto op1 = this->symbolicEngine->getOperandAst(inst, sf); 5720 auto op2 = this->symbolicEngine->getOperandAst(inst, of); 5721 auto op3 = this->symbolicEngine->getOperandAst(inst, zf); 5722 auto op4 = this->symbolicEngine->getOperandAst(inst, srcImm1); 5723 auto op5 = this->symbolicEngine->getOperandAst(inst, srcImm2); 5724 5725 /* Create the semantics */ 5726 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvor(this->astCtxt->bvxor(op1, op2), op3), this->astCtxt->bvfalse()), op5, op4); 5727 5728 /* Create symbolic expression */ 5729 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 5730 5731 /* Set condition flag */ 5732 if ((op1->evaluate().is_zero() == op2->evaluate().is_zero()) && op3->evaluate().is_zero()) 5733 inst.setConditionTaken(true); 5734 5735 /* Spread taint */ 5736 expr->isTainted = this->taintEngine->taintAssignment(pc, sf); 5737 expr->isTainted = this->taintEngine->taintUnion(pc, of); 5738 expr->isTainted = this->taintEngine->taintUnion(pc, zf); 5739 5740 /* Create the path constraint */ 5741 this->symbolicEngine->pushPathConstraint(inst, expr); 5742 } 5743 5744 jge_s(triton::arch::Instruction & inst)5745 void x86Semantics::jge_s(triton::arch::Instruction& inst) { 5746 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 5747 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 5748 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 5749 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize())); 5750 auto& srcImm2 = inst.operands[0]; 5751 5752 /* Create symbolic operands */ 5753 auto op1 = this->symbolicEngine->getOperandAst(inst, sf); 5754 auto op2 = this->symbolicEngine->getOperandAst(inst, of); 5755 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm1); 5756 auto op4 = this->symbolicEngine->getOperandAst(inst, srcImm2); 5757 5758 /* Create the semantics */ 5759 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, op2), op4, op3); 5760 5761 /* Create symbolic expression */ 5762 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 5763 5764 /* Set condition flag */ 5765 if (op1->evaluate().is_zero() == op2->evaluate().is_zero()) 5766 inst.setConditionTaken(true); 5767 5768 /* Spread taint */ 5769 expr->isTainted = this->taintEngine->taintAssignment(pc, sf); 5770 expr->isTainted = this->taintEngine->taintUnion(pc, of); 5771 5772 /* Create the path constraint */ 5773 this->symbolicEngine->pushPathConstraint(inst, expr); 5774 } 5775 5776 jl_s(triton::arch::Instruction & inst)5777 void x86Semantics::jl_s(triton::arch::Instruction& inst) { 5778 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 5779 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 5780 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 5781 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize())); 5782 auto& srcImm2 = inst.operands[0]; 5783 5784 /* Create symbolic operands */ 5785 auto op1 = this->symbolicEngine->getOperandAst(inst, sf); 5786 auto op2 = this->symbolicEngine->getOperandAst(inst, of); 5787 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm1); 5788 auto op4 = this->symbolicEngine->getOperandAst(inst, srcImm2); 5789 5790 /* Create the semantics */ 5791 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvxor(op1, op2), this->astCtxt->bvtrue()), op4, op3); 5792 5793 /* Create symbolic expression */ 5794 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 5795 5796 /* Set condition flag */ 5797 if (op1->evaluate().is_zero() != op2->evaluate().is_zero()) 5798 inst.setConditionTaken(true); 5799 5800 /* Spread taint */ 5801 expr->isTainted = this->taintEngine->taintAssignment(pc, sf); 5802 expr->isTainted = this->taintEngine->taintUnion(pc, of); 5803 5804 /* Create the path constraint */ 5805 this->symbolicEngine->pushPathConstraint(inst, expr); 5806 } 5807 5808 jle_s(triton::arch::Instruction & inst)5809 void x86Semantics::jle_s(triton::arch::Instruction& inst) { 5810 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 5811 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 5812 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 5813 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 5814 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize())); 5815 auto& srcImm2 = inst.operands[0]; 5816 5817 /* Create symbolic operands */ 5818 auto op1 = this->symbolicEngine->getOperandAst(inst, sf); 5819 auto op2 = this->symbolicEngine->getOperandAst(inst, of); 5820 auto op3 = this->symbolicEngine->getOperandAst(inst, zf); 5821 auto op4 = this->symbolicEngine->getOperandAst(inst, srcImm1); 5822 auto op5 = this->symbolicEngine->getOperandAst(inst, srcImm2); 5823 5824 /* Create the semantics */ 5825 auto node = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->bvor(this->astCtxt->bvxor(op1, op2), op3), this->astCtxt->bvtrue()), op5, op4); 5826 5827 /* Create symbolic expression */ 5828 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 5829 5830 /* Set condition flag */ 5831 if ((op1->evaluate().is_zero() != op2->evaluate().is_zero()) || !op3->evaluate().is_zero()) 5832 inst.setConditionTaken(true); 5833 5834 /* Spread taint */ 5835 expr->isTainted = this->taintEngine->taintAssignment(pc, sf); 5836 expr->isTainted = this->taintEngine->taintUnion(pc, of); 5837 expr->isTainted = this->taintEngine->taintUnion(pc, zf); 5838 5839 /* Create the path constraint */ 5840 this->symbolicEngine->pushPathConstraint(inst, expr); 5841 } 5842 5843 jmp_s(triton::arch::Instruction & inst)5844 void x86Semantics::jmp_s(triton::arch::Instruction& inst) { 5845 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 5846 auto& src = inst.operands[0]; 5847 5848 /* Create symbolic operands */ 5849 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 5850 5851 /* Create the semantics */ 5852 auto node = op1; 5853 5854 /* Create symbolic expression */ 5855 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 5856 5857 /* Set condition flag */ 5858 inst.setConditionTaken(true); 5859 5860 /* Spread taint */ 5861 expr->isTainted = this->taintEngine->taintAssignment(pc, src); 5862 5863 /* Create the path constraint */ 5864 this->symbolicEngine->pushPathConstraint(inst, expr); 5865 } 5866 5867 jne_s(triton::arch::Instruction & inst)5868 void x86Semantics::jne_s(triton::arch::Instruction& inst) { 5869 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 5870 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 5871 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize())); 5872 auto& srcImm2 = inst.operands[0]; 5873 5874 /* Create symbolic operands */ 5875 auto op1 = this->symbolicEngine->getOperandAst(inst, zf); 5876 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1); 5877 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2); 5878 5879 /* Create the semantics */ 5880 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvfalse()), op3, op2); 5881 5882 /* Create symbolic expression */ 5883 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 5884 5885 /* Set condition flag */ 5886 if (op1->evaluate().is_zero()) 5887 inst.setConditionTaken(true); 5888 5889 /* Spread taint */ 5890 expr->isTainted = this->taintEngine->taintAssignment(pc, zf); 5891 5892 /* Create the path constraint */ 5893 this->symbolicEngine->pushPathConstraint(inst, expr); 5894 } 5895 5896 jno_s(triton::arch::Instruction & inst)5897 void x86Semantics::jno_s(triton::arch::Instruction& inst) { 5898 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 5899 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 5900 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize())); 5901 auto& srcImm2 = inst.operands[0]; 5902 5903 /* Create symbolic operands */ 5904 auto op1 = this->symbolicEngine->getOperandAst(inst, of); 5905 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1); 5906 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2); 5907 5908 /* Create the semantics */ 5909 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvfalse()), op3, op2); 5910 5911 /* Create symbolic expression */ 5912 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 5913 5914 /* Set condition flag */ 5915 if (op1->evaluate().is_zero()) 5916 inst.setConditionTaken(true); 5917 5918 /* Spread taint */ 5919 expr->isTainted = this->taintEngine->taintAssignment(pc, of); 5920 5921 /* Create the path constraint */ 5922 this->symbolicEngine->pushPathConstraint(inst, expr); 5923 } 5924 5925 jnp_s(triton::arch::Instruction & inst)5926 void x86Semantics::jnp_s(triton::arch::Instruction& inst) { 5927 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 5928 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF)); 5929 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize())); 5930 auto& srcImm2 = inst.operands[0]; 5931 5932 /* Create symbolic operands */ 5933 auto op1 = this->symbolicEngine->getOperandAst(inst, pf); 5934 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1); 5935 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2); 5936 5937 /* Create the semantics */ 5938 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvfalse()), op3, op2); 5939 5940 /* Create symbolic expression */ 5941 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 5942 5943 /* Set condition flag */ 5944 if (op1->evaluate().is_zero()) 5945 inst.setConditionTaken(true); 5946 5947 /* Spread taint */ 5948 expr->isTainted = this->taintEngine->taintAssignment(pc, pf); 5949 5950 /* Create the path constraint */ 5951 this->symbolicEngine->pushPathConstraint(inst, expr); 5952 } 5953 5954 jns_s(triton::arch::Instruction & inst)5955 void x86Semantics::jns_s(triton::arch::Instruction& inst) { 5956 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 5957 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 5958 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize())); 5959 auto& srcImm2 = inst.operands[0]; 5960 5961 /* Create symbolic operands */ 5962 auto op1 = this->symbolicEngine->getOperandAst(inst, sf); 5963 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1); 5964 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2); 5965 5966 /* Create the semantics */ 5967 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvfalse()), op3, op2); 5968 5969 /* Create symbolic expression */ 5970 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 5971 5972 /* Set condition flag */ 5973 if (op1->evaluate().is_zero()) 5974 inst.setConditionTaken(true); 5975 5976 /* Spread taint */ 5977 expr->isTainted = this->taintEngine->taintAssignment(pc, sf); 5978 5979 /* Create the path constraint */ 5980 this->symbolicEngine->pushPathConstraint(inst, expr); 5981 } 5982 5983 jo_s(triton::arch::Instruction & inst)5984 void x86Semantics::jo_s(triton::arch::Instruction& inst) { 5985 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 5986 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 5987 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize())); 5988 auto& srcImm2 = inst.operands[0]; 5989 5990 /* Create symbolic operands */ 5991 auto op1 = this->symbolicEngine->getOperandAst(inst, of); 5992 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1); 5993 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2); 5994 5995 /* Create the semantics */ 5996 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvtrue()), op3, op2); 5997 5998 /* Create symbolic expression */ 5999 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 6000 6001 /* Set condition flag */ 6002 if (!op1->evaluate().is_zero()) 6003 inst.setConditionTaken(true); 6004 6005 /* Spread taint */ 6006 expr->isTainted = this->taintEngine->taintAssignment(pc, of); 6007 6008 /* Create the path constraint */ 6009 this->symbolicEngine->pushPathConstraint(inst, expr); 6010 } 6011 6012 jp_s(triton::arch::Instruction & inst)6013 void x86Semantics::jp_s(triton::arch::Instruction& inst) { 6014 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 6015 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF)); 6016 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize())); 6017 auto& srcImm2 = inst.operands[0]; 6018 6019 /* Create symbolic operands */ 6020 auto op1 = this->symbolicEngine->getOperandAst(inst, pf); 6021 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1); 6022 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2); 6023 6024 /* Create the semantics */ 6025 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvtrue()), op3, op2); 6026 6027 /* Create symbolic expression */ 6028 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 6029 6030 /* Set condition flag */ 6031 if (!op1->evaluate().is_zero()) 6032 inst.setConditionTaken(true); 6033 6034 /* Spread taint */ 6035 expr->isTainted = this->taintEngine->taintAssignment(pc, pf); 6036 6037 /* Create the path constraint */ 6038 this->symbolicEngine->pushPathConstraint(inst, expr); 6039 } 6040 6041 jrcxz_s(triton::arch::Instruction & inst)6042 void x86Semantics::jrcxz_s(triton::arch::Instruction& inst) { 6043 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 6044 auto rcx = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RCX)); 6045 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize())); 6046 auto& srcImm2 = inst.operands[0]; 6047 6048 /* Create symbolic operands */ 6049 auto op1 = this->symbolicEngine->getOperandAst(inst, rcx); 6050 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1); 6051 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2); 6052 6053 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bv(0, triton::bitsize::qword)), op3, op2); 6054 6055 /* Create symbolic expression */ 6056 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 6057 6058 /* Set condition flag */ 6059 if (!op1->evaluate().is_zero()) 6060 inst.setConditionTaken(true); 6061 6062 /* Spread taint */ 6063 expr->isTainted = this->taintEngine->taintAssignment(pc, rcx); 6064 6065 /* Create the path constraint */ 6066 this->symbolicEngine->pushPathConstraint(inst, expr); 6067 } 6068 6069 js_s(triton::arch::Instruction & inst)6070 void x86Semantics::js_s(triton::arch::Instruction& inst) { 6071 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 6072 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 6073 auto srcImm1 = triton::arch::OperandWrapper(Immediate(inst.getNextAddress(), pc.getSize())); 6074 auto& srcImm2 = inst.operands[0]; 6075 6076 /* Create symbolic operands */ 6077 auto op1 = this->symbolicEngine->getOperandAst(inst, sf); 6078 auto op2 = this->symbolicEngine->getOperandAst(inst, srcImm1); 6079 auto op3 = this->symbolicEngine->getOperandAst(inst, srcImm2); 6080 6081 /* Create the semantics */ 6082 auto node = this->astCtxt->ite(this->astCtxt->equal(op1, this->astCtxt->bvtrue()), op3, op2); 6083 6084 /* Create symbolic expression */ 6085 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 6086 6087 /* Set condition flag */ 6088 if (!op1->evaluate().is_zero()) 6089 inst.setConditionTaken(true); 6090 6091 /* Spread taint */ 6092 expr->isTainted = this->taintEngine->taintAssignment(pc, sf); 6093 6094 /* Create the path constraint */ 6095 this->symbolicEngine->pushPathConstraint(inst, expr); 6096 } 6097 6098 lahf_s(triton::arch::Instruction & inst)6099 void x86Semantics::lahf_s(triton::arch::Instruction& inst) { 6100 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AH)); 6101 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 6102 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 6103 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF)); 6104 auto src4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF)); 6105 auto src5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 6106 6107 /* Create symbolic operands */ 6108 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 6109 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 6110 auto op3 = this->symbolicEngine->getOperandAst(inst, src3); 6111 auto op4 = this->symbolicEngine->getOperandAst(inst, src4); 6112 auto op5 = this->symbolicEngine->getOperandAst(inst, src5); 6113 6114 /* Create the semantics */ 6115 std::vector<triton::ast::SharedAbstractNode> flags; 6116 flags.reserve(8); 6117 6118 flags.push_back(op1); 6119 flags.push_back(op2); 6120 flags.push_back(this->astCtxt->bvfalse()); 6121 flags.push_back(op3); 6122 flags.push_back(this->astCtxt->bvfalse()); 6123 flags.push_back(op4); 6124 flags.push_back(this->astCtxt->bvtrue()); 6125 flags.push_back(op5); 6126 6127 auto node = this->astCtxt->concat(flags); 6128 6129 /* Create symbolic expression */ 6130 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "LAHF operation"); 6131 6132 /* Spread taint */ 6133 this->taintEngine->taintUnion(dst, src1); 6134 this->taintEngine->taintUnion(dst, src2); 6135 this->taintEngine->taintUnion(dst, src3); 6136 this->taintEngine->taintUnion(dst, src4); 6137 expr->isTainted = this->taintEngine->taintUnion(dst, src5); 6138 6139 /* Update the symbolic control flow */ 6140 this->controlFlow_s(inst); 6141 } 6142 6143 lddqu_s(triton::arch::Instruction & inst)6144 void x86Semantics::lddqu_s(triton::arch::Instruction& inst) { 6145 auto& dst = inst.operands[0]; 6146 auto& src = inst.operands[1]; 6147 6148 /* Create the semantics */ 6149 auto node = this->symbolicEngine->getOperandAst(inst, src); 6150 6151 /* Create symbolic expression */ 6152 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "LDDQU operation"); 6153 6154 /* Spread taint */ 6155 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 6156 6157 /* Update the symbolic control flow */ 6158 this->controlFlow_s(inst); 6159 } 6160 6161 ldmxcsr_s(triton::arch::Instruction & inst)6162 void x86Semantics::ldmxcsr_s(triton::arch::Instruction& inst) { 6163 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR)); 6164 auto& src = inst.operands[0]; 6165 6166 /* Create the semantics */ 6167 auto node = this->symbolicEngine->getOperandAst(inst, src); 6168 6169 /* Create symbolic expression */ 6170 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "LDMXCSR operation"); 6171 6172 /* Spread taint */ 6173 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 6174 6175 /* Update the symbolic control flow */ 6176 this->controlFlow_s(inst); 6177 } 6178 6179 lea_s(triton::arch::Instruction & inst)6180 void x86Semantics::lea_s(triton::arch::Instruction& inst) { 6181 auto& dst = inst.operands[0].getRegister(); 6182 auto& srcDisp = inst.operands[1].getMemory().getDisplacement(); 6183 auto& srcBase = inst.operands[1].getMemory().getBaseRegister(); 6184 auto& srcIndex = inst.operands[1].getMemory().getIndexRegister(); 6185 auto& srcScale = inst.operands[1].getMemory().getScale(); 6186 triton::uint32 leaSize = 0; 6187 6188 /* Setup LEA size */ 6189 if (this->architecture->isRegisterValid(srcBase)) 6190 leaSize = srcBase.getBitSize(); 6191 else if (this->architecture->isRegisterValid(srcIndex)) 6192 leaSize = srcIndex.getBitSize(); 6193 else 6194 leaSize = srcDisp.getBitSize(); 6195 6196 /* Create symbolic operands */ 6197 6198 /* Displacement */ 6199 auto op2 = this->symbolicEngine->getImmediateAst(inst, srcDisp); 6200 if (leaSize > srcDisp.getBitSize()) 6201 op2 = this->astCtxt->zx(leaSize - srcDisp.getBitSize(), op2); 6202 6203 /* Base */ 6204 triton::ast::SharedAbstractNode op3 = nullptr; 6205 if (this->architecture->isRegisterValid(srcBase)) 6206 op3 = this->symbolicEngine->getRegisterAst(inst, srcBase); 6207 else 6208 op3 = this->astCtxt->bv(0, leaSize); 6209 6210 /* Base with PC */ 6211 if (this->architecture->isRegisterValid(srcBase) && (this->architecture->getParentRegister(srcBase) == this->architecture->getProgramCounter())) 6212 op3 = this->astCtxt->bvadd(op3, this->astCtxt->bv(inst.getSize(), leaSize)); 6213 6214 /* Index */ 6215 triton::ast::SharedAbstractNode op4 = nullptr; 6216 if (this->architecture->isRegisterValid(srcIndex)) 6217 op4 = this->symbolicEngine->getRegisterAst(inst, srcIndex); 6218 else 6219 op4 = this->astCtxt->bv(0, leaSize); 6220 6221 /* Scale */ 6222 auto op5 = this->symbolicEngine->getImmediateAst(inst, srcScale); 6223 if (leaSize > srcScale.getBitSize()) 6224 op5 = this->astCtxt->zx(leaSize - srcScale.getBitSize(), op5); 6225 6226 /* Create the semantics */ 6227 /* Effective address = Displacement + BaseReg + IndexReg * Scale */ 6228 auto node = this->astCtxt->bvadd(op2, this->astCtxt->bvadd(op3, this->astCtxt->bvmul(op4, op5))); 6229 6230 if (dst.getBitSize() > leaSize) 6231 node = this->astCtxt->zx(dst.getBitSize() - leaSize, node); 6232 6233 if (dst.getBitSize() < leaSize) 6234 node = this->astCtxt->extract(dst.getHigh(), dst.getLow(), node); 6235 6236 /* Create symbolic expression */ 6237 auto expr = this->symbolicEngine->createSymbolicRegisterExpression(inst, node, dst, "LEA operation"); 6238 6239 /* Spread taint */ 6240 expr->isTainted = this->taintEngine->setTaint(dst, this->taintEngine->isTainted(srcBase) | this->taintEngine->isTainted(srcIndex)); 6241 6242 /* Update the symbolic control flow */ 6243 this->controlFlow_s(inst); 6244 } 6245 6246 leave_s(triton::arch::Instruction & inst)6247 void x86Semantics::leave_s(triton::arch::Instruction& inst) { 6248 auto stack = this->architecture->getStackPointer(); 6249 auto base = this->architecture->getParentRegister(ID_REG_X86_BP); 6250 auto baseValue = this->architecture->getConcreteRegisterValue(base).convert_to<triton::uint64>(); 6251 auto bp1 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(baseValue, base.getSize())); 6252 auto bp2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_BP)); 6253 auto sp = triton::arch::OperandWrapper(stack); 6254 6255 /* Create symbolic operands */ 6256 auto op1 = this->symbolicEngine->getOperandAst(inst, bp2); 6257 6258 /* RSP = RBP */ 6259 auto node1 = op1; 6260 6261 /* Create the symbolic expression */ 6262 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, sp, "Stack Pointer"); 6263 6264 /* Spread taint */ 6265 expr1->isTainted = this->taintEngine->taintAssignment(sp, bp2); 6266 6267 /* Create symbolic operands */ 6268 auto op2 = this->symbolicEngine->getOperandAst(inst, bp1); 6269 6270 /* RBP = pop() */ 6271 auto node2 = op2; 6272 6273 /* Create the symbolic expression */ 6274 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, bp2, "Stack Top Pointer"); 6275 6276 /* Spread taint */ 6277 expr2->isTainted = this->taintEngine->taintAssignment(bp2, bp1); 6278 6279 /* Create the semantics - side effect */ 6280 alignAddStack_s(inst, bp1.getSize()); 6281 6282 /* Update the symbolic control flow */ 6283 this->controlFlow_s(inst); 6284 } 6285 6286 lfence_s(triton::arch::Instruction & inst)6287 void x86Semantics::lfence_s(triton::arch::Instruction& inst) { 6288 /* Update the symbolic control flow */ 6289 this->controlFlow_s(inst); 6290 } 6291 6292 lodsb_s(triton::arch::Instruction & inst)6293 void x86Semantics::lodsb_s(triton::arch::Instruction& inst) { 6294 auto& dst = inst.operands[0]; 6295 auto& src = inst.operands[1]; 6296 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI)); 6297 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 6298 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 6299 6300 /* Check if there is a REP prefix and a counter to zero */ 6301 auto cnt = this->symbolicEngine->getOperandAst(cx); 6302 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 6303 this->controlFlow_s(inst); 6304 return; 6305 } 6306 6307 /* Create symbolic operands */ 6308 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 6309 auto op2 = this->symbolicEngine->getOperandAst(inst, index); 6310 auto op3 = this->symbolicEngine->getOperandAst(inst, df); 6311 6312 /* Create the semantics */ 6313 auto node1 = op1; 6314 auto node2 = this->astCtxt->ite( 6315 this->astCtxt->equal(op3, this->astCtxt->bvfalse()), 6316 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::byte, index.getBitSize())), 6317 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::byte, index.getBitSize())) 6318 ); 6319 6320 /* Create symbolic expression */ 6321 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "LODSB operation"); 6322 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation"); 6323 6324 /* Spread taint */ 6325 expr1->isTainted = this->taintEngine->taintAssignment(dst, src); 6326 expr2->isTainted = this->taintEngine->taintUnion(index, index); 6327 6328 /* Update the symbolic control flow */ 6329 this->controlFlow_s(inst); 6330 } 6331 6332 lodsd_s(triton::arch::Instruction & inst)6333 void x86Semantics::lodsd_s(triton::arch::Instruction& inst) { 6334 auto& dst = inst.operands[0]; 6335 auto& src = inst.operands[1]; 6336 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI)); 6337 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 6338 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 6339 6340 /* Check if there is a REP prefix and a counter to zero */ 6341 auto cnt = this->symbolicEngine->getOperandAst(cx); 6342 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 6343 this->controlFlow_s(inst); 6344 return; 6345 } 6346 6347 /* Create symbolic operands */ 6348 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 6349 auto op2 = this->symbolicEngine->getOperandAst(inst, index); 6350 auto op3 = this->symbolicEngine->getOperandAst(inst, df); 6351 6352 /* Create the semantics */ 6353 auto node1 = op1; 6354 auto node2 = this->astCtxt->ite( 6355 this->astCtxt->equal(op3, this->astCtxt->bvfalse()), 6356 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::dword, index.getBitSize())), 6357 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::dword, index.getBitSize())) 6358 ); 6359 6360 /* Create symbolic expression */ 6361 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "LODSD operation"); 6362 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation"); 6363 6364 /* Spread taint */ 6365 expr1->isTainted = this->taintEngine->taintAssignment(dst, src); 6366 expr2->isTainted = this->taintEngine->taintUnion(index, index); 6367 6368 /* Update the symbolic control flow */ 6369 this->controlFlow_s(inst); 6370 } 6371 6372 lodsq_s(triton::arch::Instruction & inst)6373 void x86Semantics::lodsq_s(triton::arch::Instruction& inst) { 6374 auto& dst = inst.operands[0]; 6375 auto& src = inst.operands[1]; 6376 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI)); 6377 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 6378 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 6379 6380 /* Check if there is a REP prefix and a counter to zero */ 6381 auto cnt = this->symbolicEngine->getOperandAst(cx); 6382 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 6383 this->controlFlow_s(inst); 6384 return; 6385 } 6386 6387 /* Create symbolic operands */ 6388 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 6389 auto op2 = this->symbolicEngine->getOperandAst(inst, index); 6390 auto op3 = this->symbolicEngine->getOperandAst(inst, df); 6391 6392 /* Create the semantics */ 6393 auto node1 = op1; 6394 auto node2 = this->astCtxt->ite( 6395 this->astCtxt->equal(op3, this->astCtxt->bvfalse()), 6396 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::qword, index.getBitSize())), 6397 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::qword, index.getBitSize())) 6398 ); 6399 6400 /* Create symbolic expression */ 6401 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "LODSQ operation"); 6402 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation"); 6403 6404 /* Spread taint */ 6405 expr1->isTainted = this->taintEngine->taintAssignment(dst, src); 6406 expr2->isTainted = this->taintEngine->taintUnion(index, index); 6407 6408 /* Update the symbolic control flow */ 6409 this->controlFlow_s(inst); 6410 } 6411 6412 lodsw_s(triton::arch::Instruction & inst)6413 void x86Semantics::lodsw_s(triton::arch::Instruction& inst) { 6414 auto& dst = inst.operands[0]; 6415 auto& src = inst.operands[1]; 6416 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI)); 6417 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 6418 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 6419 6420 /* Check if there is a REP prefix and a counter to zero */ 6421 auto cnt = this->symbolicEngine->getOperandAst(cx); 6422 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 6423 this->controlFlow_s(inst); 6424 return; 6425 } 6426 6427 /* Create symbolic operands */ 6428 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 6429 auto op2 = this->symbolicEngine->getOperandAst(inst, index); 6430 auto op3 = this->symbolicEngine->getOperandAst(inst, df); 6431 6432 /* Create the semantics */ 6433 auto node1 = op1; 6434 auto node2 = this->astCtxt->ite( 6435 this->astCtxt->equal(op3, this->astCtxt->bvfalse()), 6436 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::word, index.getBitSize())), 6437 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::word, index.getBitSize())) 6438 ); 6439 6440 /* Create symbolic expression */ 6441 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "LODSW operation"); 6442 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation"); 6443 6444 /* Spread taint */ 6445 expr1->isTainted = this->taintEngine->taintAssignment(dst, src); 6446 expr2->isTainted = this->taintEngine->taintUnion(index, index); 6447 6448 /* Update the symbolic control flow */ 6449 this->controlFlow_s(inst); 6450 } 6451 6452 loop_s(triton::arch::Instruction & inst)6453 void x86Semantics::loop_s(triton::arch::Instruction& inst) { 6454 auto count = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 6455 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 6456 auto& src = inst.operands[0]; 6457 6458 /* Create symbolic operands */ 6459 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 6460 auto op2 = this->symbolicEngine->getOperandAst(inst, count); 6461 6462 /* Create the semantics */ 6463 auto node1 = this->astCtxt->ite( 6464 this->astCtxt->equal(op2, this->astCtxt->bv(0, op2->getBitvectorSize())), 6465 this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize()), 6466 op1 6467 ); 6468 6469 /* Create symbolic expression */ 6470 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, pc, "Program Counter"); 6471 6472 /* Set condition flag */ 6473 if (op2->evaluate()) { 6474 inst.setConditionTaken(true); 6475 /* Spread taint */ 6476 expr1->isTainted = this->taintEngine->taintAssignment(pc, count); 6477 } 6478 else { 6479 expr1->isTainted = this->taintEngine->taintAssignment(pc, src); 6480 } 6481 6482 /* Create the semantics */ 6483 auto node2 = this->astCtxt->bvsub(op2, this->astCtxt->bv(1, op2->getBitvectorSize())); 6484 6485 /* Create symbolic expression */ 6486 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, count, "LOOP counter operation"); 6487 6488 /* Create the path constraint */ 6489 this->symbolicEngine->pushPathConstraint(inst, expr1); 6490 } 6491 6492 lzcnt_s(triton::arch::Instruction & inst)6493 void x86Semantics::lzcnt_s(triton::arch::Instruction& inst) { 6494 auto& dst = inst.operands[0]; 6495 auto& src = inst.operands[1]; 6496 auto bvSize1 = dst.getBitSize(); 6497 auto bvSize2 = src.getBitSize(); 6498 6499 /* Create symbolic operands */ 6500 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 6501 6502 /* Create the semantics */ 6503 triton::ast::SharedAbstractNode node = nullptr; 6504 switch (src.getSize()) { 6505 case triton::size::byte: 6506 node = this->astCtxt->ite( 6507 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)), 6508 this->astCtxt->bv(bvSize2, bvSize1), 6509 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 1, bvSize2 - 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1), 6510 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 2, bvSize2 - 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1), 6511 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 3, bvSize2 - 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1), 6512 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 4, bvSize2 - 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1), 6513 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 5, bvSize2 - 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1), 6514 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 6, bvSize2 - 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1), 6515 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 7, bvSize2 - 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1), 6516 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 8, bvSize2 - 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1), 6517 this->astCtxt->bv(8, bvSize1)))))))))); 6518 break; 6519 case triton::size::word: 6520 node = this->astCtxt->ite( 6521 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)), 6522 this->astCtxt->bv(bvSize2, bvSize1), 6523 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 1, bvSize2 - 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1), 6524 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 2, bvSize2 - 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1), 6525 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 3, bvSize2 - 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1), 6526 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 4, bvSize2 - 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1), 6527 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 5, bvSize2 - 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1), 6528 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 6, bvSize2 - 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1), 6529 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 7, bvSize2 - 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1), 6530 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 8, bvSize2 - 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1), 6531 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 9, bvSize2 - 9, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1), 6532 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 10, bvSize2 - 10, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1), 6533 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 11, bvSize2 - 11, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1), 6534 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 12, bvSize2 - 12, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1), 6535 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 13, bvSize2 - 13, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1), 6536 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 14, bvSize2 - 14, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1), 6537 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 15, bvSize2 - 15, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1), 6538 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 16, bvSize2 - 16, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1), 6539 this->astCtxt->bv(16, bvSize1)))))))))))))))))); 6540 break; 6541 case triton::size::dword: 6542 node = this->astCtxt->ite( 6543 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)), 6544 this->astCtxt->bv(bvSize2, bvSize1), 6545 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 1, bvSize2 - 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1), 6546 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 2, bvSize2 - 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1), 6547 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 3, bvSize2 - 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1), 6548 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 4, bvSize2 - 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1), 6549 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 5, bvSize2 - 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1), 6550 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 6, bvSize2 - 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1), 6551 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 7, bvSize2 - 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1), 6552 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 8, bvSize2 - 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1), 6553 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 9, bvSize2 - 9, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1), 6554 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 10, bvSize2 - 10, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1), 6555 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 11, bvSize2 - 11, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1), 6556 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 12, bvSize2 - 12, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1), 6557 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 13, bvSize2 - 13, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1), 6558 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 14, bvSize2 - 14, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1), 6559 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 15, bvSize2 - 15, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1), 6560 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 16, bvSize2 - 16, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1), 6561 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 17, bvSize2 - 17, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1), 6562 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 18, bvSize2 - 18, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1), 6563 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 19, bvSize2 - 19, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1), 6564 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 20, bvSize2 - 20, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1), 6565 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 21, bvSize2 - 21, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1), 6566 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 22, bvSize2 - 22, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1), 6567 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 23, bvSize2 - 23, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1), 6568 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 24, bvSize2 - 24, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1), 6569 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 25, bvSize2 - 25, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1), 6570 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 26, bvSize2 - 26, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1), 6571 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 27, bvSize2 - 27, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1), 6572 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 28, bvSize2 - 28, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1), 6573 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 29, bvSize2 - 29, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1), 6574 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 30, bvSize2 - 30, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1), 6575 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 31, bvSize2 - 31, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1), 6576 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 32, bvSize2 - 32, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1), 6577 this->astCtxt->bv(32, bvSize1)))))))))))))))))))))))))))))))))); 6578 break; 6579 case triton::size::qword: 6580 node = this->astCtxt->ite( 6581 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)), 6582 this->astCtxt->bv(bvSize2, bvSize1), 6583 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 1, bvSize2 - 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1), 6584 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 2, bvSize2 - 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1), 6585 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 3, bvSize2 - 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1), 6586 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 4, bvSize2 - 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1), 6587 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 5, bvSize2 - 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1), 6588 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 6, bvSize2 - 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1), 6589 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 7, bvSize2 - 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1), 6590 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 8, bvSize2 - 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1), 6591 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 9, bvSize2 - 9, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1), 6592 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 10, bvSize2 - 10, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1), 6593 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 11, bvSize2 - 11, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1), 6594 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 12, bvSize2 - 12, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1), 6595 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 13, bvSize2 - 13, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1), 6596 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 14, bvSize2 - 14, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1), 6597 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 15, bvSize2 - 15, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1), 6598 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 16, bvSize2 - 16, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1), 6599 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 17, bvSize2 - 17, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1), 6600 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 18, bvSize2 - 18, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1), 6601 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 19, bvSize2 - 19, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1), 6602 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 20, bvSize2 - 20, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1), 6603 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 21, bvSize2 - 21, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1), 6604 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 22, bvSize2 - 22, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1), 6605 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 23, bvSize2 - 23, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1), 6606 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 24, bvSize2 - 24, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1), 6607 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 25, bvSize2 - 25, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1), 6608 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 26, bvSize2 - 26, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1), 6609 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 27, bvSize2 - 27, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1), 6610 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 28, bvSize2 - 28, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1), 6611 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 29, bvSize2 - 29, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1), 6612 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 30, bvSize2 - 30, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1), 6613 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 31, bvSize2 - 31, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1), 6614 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 32, bvSize2 - 32, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1), 6615 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 33, bvSize2 - 33, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(32, bvSize1), 6616 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 34, bvSize2 - 34, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(33, bvSize1), 6617 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 35, bvSize2 - 35, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(34, bvSize1), 6618 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 36, bvSize2 - 36, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(35, bvSize1), 6619 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 37, bvSize2 - 37, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(36, bvSize1), 6620 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 38, bvSize2 - 38, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(37, bvSize1), 6621 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 39, bvSize2 - 39, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(38, bvSize1), 6622 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 40, bvSize2 - 40, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(39, bvSize1), 6623 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 41, bvSize2 - 41, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(40, bvSize1), 6624 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 42, bvSize2 - 42, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(41, bvSize1), 6625 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 43, bvSize2 - 43, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(42, bvSize1), 6626 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 44, bvSize2 - 44, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(43, bvSize1), 6627 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 45, bvSize2 - 45, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(44, bvSize1), 6628 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 46, bvSize2 - 46, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(45, bvSize1), 6629 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 47, bvSize2 - 47, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(46, bvSize1), 6630 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 48, bvSize2 - 48, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(47, bvSize1), 6631 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 49, bvSize2 - 49, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(48, bvSize1), 6632 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 50, bvSize2 - 50, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(49, bvSize1), 6633 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 51, bvSize2 - 51, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(50, bvSize1), 6634 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 52, bvSize2 - 52, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(51, bvSize1), 6635 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 53, bvSize2 - 53, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(52, bvSize1), 6636 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 54, bvSize2 - 54, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(53, bvSize1), 6637 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 55, bvSize2 - 55, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(54, bvSize1), 6638 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 56, bvSize2 - 56, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(55, bvSize1), 6639 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 57, bvSize2 - 57, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(56, bvSize1), 6640 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 58, bvSize2 - 58, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(57, bvSize1), 6641 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 59, bvSize2 - 59, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(58, bvSize1), 6642 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 60, bvSize2 - 60, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(59, bvSize1), 6643 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 61, bvSize2 - 61, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(60, bvSize1), 6644 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 62, bvSize2 - 62, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(61, bvSize1), 6645 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 63, bvSize2 - 63, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(62, bvSize1), 6646 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(bvSize2 - 64, bvSize2 - 64, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(63, bvSize1), 6647 this->astCtxt->bv(64, bvSize1)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))); 6648 break; 6649 default: 6650 throw triton::exceptions::Semantics("x86Semantics::lzcnt_s(): Invalid operand size."); 6651 } 6652 6653 /* Create symbolic expression */ 6654 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "LZCNT operation"); 6655 6656 /* Spread taint */ 6657 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 6658 6659 /* Update symbolic flags */ 6660 this->cfLzcnt_s(inst, expr, src, op1); 6661 this->zf_s(inst, expr, src); 6662 6663 /* Tag undefined flags */ 6664 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 6665 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF)); 6666 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF)); 6667 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 6668 6669 /* Update the symbolic control flow */ 6670 this->controlFlow_s(inst); 6671 } 6672 6673 mfence_s(triton::arch::Instruction & inst)6674 void x86Semantics::mfence_s(triton::arch::Instruction& inst) { 6675 /* Update the symbolic control flow */ 6676 this->controlFlow_s(inst); 6677 } 6678 6679 mov_s(triton::arch::Instruction & inst)6680 void x86Semantics::mov_s(triton::arch::Instruction& inst) { 6681 auto& dst = inst.operands[0]; 6682 auto& src = inst.operands[1]; 6683 bool undef = false; 6684 6685 /* Create the semantics */ 6686 auto node = this->symbolicEngine->getOperandAst(inst, src); 6687 6688 /* 6689 * Special cases: 6690 * 6691 * Triton defines segment registers as 32 or 64 bits vector to 6692 * avoid to simulate the GDT which allows users to directly define 6693 * their segments offset. 6694 * 6695 * The code below, handles the case: MOV r/m{16/32/64}, Sreg 6696 */ 6697 if (src.getType() == triton::arch::OP_REG) { 6698 uint32 id = src.getConstRegister().getId(); 6699 if (id >= triton::arch::ID_REG_X86_CS && id <= triton::arch::ID_REG_X86_SS) { 6700 node = this->astCtxt->extract(dst.getBitSize()-1, 0, node); 6701 } 6702 if (id >= triton::arch::ID_REG_X86_CR0 && id <= triton::arch::ID_REG_X86_CR15) { 6703 undef = true; 6704 } 6705 } 6706 6707 /* 6708 * The code below, handles the case: MOV Sreg, r/m{16/32/64} 6709 */ 6710 if (dst.getType() == triton::arch::OP_REG) { 6711 uint32 id = dst.getConstRegister().getId(); 6712 if (id >= triton::arch::ID_REG_X86_CS && id <= triton::arch::ID_REG_X86_SS) { 6713 node = this->astCtxt->extract(triton::bitsize::word-1, 0, node); 6714 } 6715 if (id >= triton::arch::ID_REG_X86_CR0 && id <= triton::arch::ID_REG_X86_CR15) { 6716 undef = true; 6717 } 6718 } 6719 6720 /* Create symbolic expression */ 6721 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOV operation"); 6722 6723 /* Spread taint */ 6724 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 6725 6726 /* Tag undefined flags */ 6727 if (undef) { 6728 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 6729 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF)); 6730 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 6731 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF)); 6732 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF)); 6733 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF)); 6734 } 6735 6736 /* Update the symbolic control flow */ 6737 this->controlFlow_s(inst); 6738 } 6739 6740 movabs_s(triton::arch::Instruction & inst)6741 void x86Semantics::movabs_s(triton::arch::Instruction& inst) { 6742 auto& dst = inst.operands[0]; 6743 auto& src = inst.operands[1]; 6744 6745 /* Create the semantics */ 6746 auto node = this->symbolicEngine->getOperandAst(inst, src); 6747 6748 /* Create symbolic expression */ 6749 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVABS operation"); 6750 6751 /* Spread taint */ 6752 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 6753 6754 /* Update the symbolic control flow */ 6755 this->controlFlow_s(inst); 6756 } 6757 6758 movapd_s(triton::arch::Instruction & inst)6759 void x86Semantics::movapd_s(triton::arch::Instruction& inst) { 6760 auto& dst = inst.operands[0]; 6761 auto& src = inst.operands[1]; 6762 6763 /* Create the semantics */ 6764 auto node = this->symbolicEngine->getOperandAst(inst, src); 6765 6766 /* Create symbolic expression */ 6767 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVAPD operation"); 6768 6769 /* Spread taint */ 6770 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 6771 6772 /* Update the symbolic control flow */ 6773 this->controlFlow_s(inst); 6774 } 6775 6776 movaps_s(triton::arch::Instruction & inst)6777 void x86Semantics::movaps_s(triton::arch::Instruction& inst) { 6778 auto& dst = inst.operands[0]; 6779 auto& src = inst.operands[1]; 6780 6781 /* Create the semantics */ 6782 auto node = this->symbolicEngine->getOperandAst(inst, src); 6783 6784 /* Create symbolic expression */ 6785 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVAPS operation"); 6786 6787 /* Spread taint */ 6788 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 6789 6790 /* Update the symbolic control flow */ 6791 this->controlFlow_s(inst); 6792 } 6793 6794 movd_s(triton::arch::Instruction & inst)6795 void x86Semantics::movd_s(triton::arch::Instruction& inst) { 6796 auto& dst = inst.operands[0]; 6797 auto& src = inst.operands[1]; 6798 6799 /* Create symbolic operands */ 6800 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 6801 6802 /* Create the semantics */ 6803 triton::ast::SharedAbstractNode node = nullptr; 6804 6805 switch (dst.getBitSize()) { 6806 /* GPR 32-bits */ 6807 case triton::bitsize::dword: 6808 node = this->astCtxt->extract(triton::bitsize::dword-1, 0, op2); 6809 break; 6810 6811 /* MMX 64-bits */ 6812 case triton::bitsize::qword: 6813 node = this->astCtxt->zx(triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::dword-1, 0, op2)); 6814 break; 6815 6816 /* XMM 128-bits */ 6817 case triton::bitsize::dqword: 6818 node = this->astCtxt->zx(triton::bitsize::qword + triton::bitsize::dword, this->astCtxt->extract(triton::bitsize::dword-1, 0, op2)); 6819 break; 6820 } 6821 6822 /* Create symbolic expression */ 6823 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVD operation"); 6824 6825 /* Spread taint */ 6826 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 6827 6828 /* Update the symbolic control flow */ 6829 this->controlFlow_s(inst); 6830 } 6831 6832 movddup_s(triton::arch::Instruction & inst)6833 void x86Semantics::movddup_s(triton::arch::Instruction& inst) { 6834 auto& dst = inst.operands[0]; 6835 auto& src = inst.operands[1]; 6836 6837 /* Create symbolic operands */ 6838 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 6839 6840 /* Create the semantics */ 6841 auto node = this->astCtxt->concat(this->astCtxt->extract(triton::bitsize::qword-1, 0, op2), this->astCtxt->extract(triton::bitsize::qword-1, 0, op2)); 6842 6843 /* Create symbolic expression */ 6844 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVDDUP operation"); 6845 6846 /* Spread taint */ 6847 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 6848 6849 /* Update the symbolic control flow */ 6850 this->controlFlow_s(inst); 6851 } 6852 6853 movdq2q_s(triton::arch::Instruction & inst)6854 void x86Semantics::movdq2q_s(triton::arch::Instruction& inst) { 6855 auto& dst = inst.operands[0]; 6856 auto& src = inst.operands[1]; 6857 6858 /* Create symbolic operands */ 6859 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 6860 6861 /* Create the semantics */ 6862 auto node = this->astCtxt->extract(triton::bitsize::qword-1, 0, op2); 6863 6864 /* Create symbolic expression */ 6865 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVDQ2Q operation"); 6866 6867 /* Spread taint */ 6868 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 6869 6870 /* Update the symbolic control flow */ 6871 this->controlFlow_s(inst); 6872 } 6873 6874 movdqa_s(triton::arch::Instruction & inst)6875 void x86Semantics::movdqa_s(triton::arch::Instruction& inst) { 6876 auto& dst = inst.operands[0]; 6877 auto& src = inst.operands[1]; 6878 6879 /* Create the semantics */ 6880 auto node = this->symbolicEngine->getOperandAst(inst, src); 6881 6882 /* Create symbolic expression */ 6883 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVDQA operation"); 6884 6885 /* Spread taint */ 6886 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 6887 6888 /* Update the symbolic control flow */ 6889 this->controlFlow_s(inst); 6890 } 6891 6892 movdqu_s(triton::arch::Instruction & inst)6893 void x86Semantics::movdqu_s(triton::arch::Instruction& inst) { 6894 auto& dst = inst.operands[0]; 6895 auto& src = inst.operands[1]; 6896 6897 /* Create the semantics */ 6898 auto node = this->symbolicEngine->getOperandAst(inst, src); 6899 6900 /* Create symbolic expression */ 6901 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVDQU operation"); 6902 6903 /* Spread taint */ 6904 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 6905 6906 /* Update the symbolic control flow */ 6907 this->controlFlow_s(inst); 6908 } 6909 6910 movhlps_s(triton::arch::Instruction & inst)6911 void x86Semantics::movhlps_s(triton::arch::Instruction& inst) { 6912 auto& dst = inst.operands[0]; 6913 auto& src = inst.operands[1]; 6914 6915 /* Create symbolic operands */ 6916 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 6917 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 6918 6919 /* Create the semantics */ 6920 auto node = this->astCtxt->concat( 6921 this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, op1), /* Destination[127..64] unchanged */ 6922 this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, op2) /* Destination[63..0] = Source[127..64]; */ 6923 ); 6924 6925 /* Create symbolic expression */ 6926 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVHLPS operation"); 6927 6928 /* Spread taint */ 6929 expr->isTainted = this->taintEngine->taintUnion(dst, src); 6930 6931 /* Update the symbolic control flow */ 6932 this->controlFlow_s(inst); 6933 } 6934 6935 movhpd_s(triton::arch::Instruction & inst)6936 void x86Semantics::movhpd_s(triton::arch::Instruction& inst) { 6937 auto& dst = inst.operands[0]; 6938 auto& src = inst.operands[1]; 6939 6940 /* Create symbolic operands */ 6941 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 6942 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 6943 6944 /* Create the semantics */ 6945 triton::ast::SharedAbstractNode node = nullptr; 6946 6947 /* xmm, m64 */ 6948 if (dst.getSize() == triton::size::dqword) { 6949 node = this->astCtxt->concat( 6950 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2), /* Destination[127..64] = Source */ 6951 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op1) /* Destination[63..0] unchanged */ 6952 ); 6953 } 6954 6955 /* m64, xmm */ 6956 else { 6957 node = this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, op2); /* Destination[63..00] = Source[127..64] */ 6958 } 6959 6960 /* Create symbolic expression */ 6961 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVHPD operation"); 6962 6963 /* Spread taint */ 6964 expr->isTainted = this->taintEngine->taintUnion(dst, src); 6965 6966 /* Update the symbolic control flow */ 6967 this->controlFlow_s(inst); 6968 } 6969 6970 movhps_s(triton::arch::Instruction & inst)6971 void x86Semantics::movhps_s(triton::arch::Instruction& inst) { 6972 auto& dst = inst.operands[0]; 6973 auto& src = inst.operands[1]; 6974 6975 /* Create symbolic operands */ 6976 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 6977 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 6978 6979 /* Create the semantics */ 6980 triton::ast::SharedAbstractNode node = nullptr; 6981 6982 /* xmm, m64 */ 6983 if (dst.getSize() == triton::size::dqword) { 6984 node = this->astCtxt->concat( 6985 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2), /* Destination[127..64] = Source */ 6986 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op1) /* Destination[63..0] unchanged */ 6987 ); 6988 } 6989 6990 /* m64, xmm */ 6991 else { 6992 node = this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, op2); /* Destination[63..00] = Source[127..64] */ 6993 } 6994 6995 /* Create symbolic expression */ 6996 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVHPS operation"); 6997 6998 /* Spread taint */ 6999 expr->isTainted = this->taintEngine->taintUnion(dst, src); 7000 7001 /* Update the symbolic control flow */ 7002 this->controlFlow_s(inst); 7003 } 7004 7005 movlhps_s(triton::arch::Instruction & inst)7006 void x86Semantics::movlhps_s(triton::arch::Instruction& inst) { 7007 auto& dst = inst.operands[0]; 7008 auto& src = inst.operands[1]; 7009 7010 /* Create symbolic operands */ 7011 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 7012 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 7013 7014 /* Create the semantics */ 7015 auto node = this->astCtxt->concat( 7016 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2), /* Destination[127..64] = Source[63..0] */ 7017 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op1) /* Destination[63..0] unchanged */ 7018 ); 7019 7020 /* Create symbolic expression */ 7021 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVLHPS operation"); 7022 7023 /* Spread taint */ 7024 expr->isTainted = this->taintEngine->taintUnion(dst, src); 7025 7026 /* Update the symbolic control flow */ 7027 this->controlFlow_s(inst); 7028 } 7029 7030 movlpd_s(triton::arch::Instruction & inst)7031 void x86Semantics::movlpd_s(triton::arch::Instruction& inst) { 7032 auto& dst = inst.operands[0]; 7033 auto& src = inst.operands[1]; 7034 7035 /* Create symbolic operands */ 7036 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 7037 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 7038 7039 /* Create the semantics */ 7040 triton::ast::SharedAbstractNode node = nullptr; 7041 7042 /* xmm, m64 */ 7043 if (dst.getSize() == triton::size::dqword) { 7044 node = this->astCtxt->concat( 7045 this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, op1), /* Destination[127..64] unchanged */ 7046 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2) /* Destination[63..0] = Source */ 7047 ); 7048 } 7049 7050 /* m64, xmm */ 7051 else { 7052 node = this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2); /* Destination = Source[63..00] */ 7053 } 7054 7055 /* Create symbolic expression */ 7056 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVLPD operation"); 7057 7058 /* Spread taint */ 7059 expr->isTainted = this->taintEngine->taintUnion(dst, src); 7060 7061 /* Update the symbolic control flow */ 7062 this->controlFlow_s(inst); 7063 } 7064 7065 movlps_s(triton::arch::Instruction & inst)7066 void x86Semantics::movlps_s(triton::arch::Instruction& inst) { 7067 auto& dst = inst.operands[0]; 7068 auto& src = inst.operands[1]; 7069 7070 /* Create symbolic operands */ 7071 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 7072 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 7073 7074 /* Create the semantics */ 7075 triton::ast::SharedAbstractNode node = nullptr; 7076 7077 /* xmm, m64 */ 7078 if (dst.getSize() == triton::size::dqword) { 7079 node = this->astCtxt->concat( 7080 this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, op1), /* Destination[127..64] unchanged */ 7081 this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2) /* Destination[63..0] = Source */ 7082 ); 7083 } 7084 7085 /* m64, xmm */ 7086 else { 7087 node = this->astCtxt->extract((triton::bitsize::qword - 1), 0, op2); /* Destination = Source[63..00] */ 7088 } 7089 7090 /* Create symbolic expression */ 7091 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVLPS operation"); 7092 7093 /* Spread taint */ 7094 expr->isTainted = this->taintEngine->taintUnion(dst, src); 7095 7096 /* Update the symbolic control flow */ 7097 this->controlFlow_s(inst); 7098 } 7099 7100 movmskpd_s(triton::arch::Instruction & inst)7101 void x86Semantics::movmskpd_s(triton::arch::Instruction& inst) { 7102 auto& dst = inst.operands[0]; 7103 auto& src = inst.operands[1]; 7104 7105 /* Create symbolic operands */ 7106 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 7107 7108 /* Create the semantics */ 7109 auto node = this->astCtxt->zx(30, /* Destination[2..31] = 0 */ 7110 this->astCtxt->concat( 7111 this->astCtxt->extract(127, 127, op2), /* Destination[1] = Source[127]; */ 7112 this->astCtxt->extract(63, 63, op2) /* Destination[0] = Source[63]; */ 7113 ) 7114 ); 7115 7116 /* Create symbolic expression */ 7117 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVMSKPD operation"); 7118 7119 /* Spread taint */ 7120 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 7121 7122 /* Update the symbolic control flow */ 7123 this->controlFlow_s(inst); 7124 } 7125 7126 movmskps_s(triton::arch::Instruction & inst)7127 void x86Semantics::movmskps_s(triton::arch::Instruction& inst) { 7128 auto& dst = inst.operands[0]; 7129 auto& src = inst.operands[1]; 7130 7131 /* Create symbolic operands */ 7132 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 7133 7134 /* Create the semantics */ 7135 std::vector<triton::ast::SharedAbstractNode> signs; 7136 signs.reserve(4); 7137 7138 signs.push_back(this->astCtxt->extract(127, 127, op2)); /* Destination[3] = Source[127]; */ 7139 signs.push_back(this->astCtxt->extract(95, 95, op2)); /* Destination[2] = Source[95]; */ 7140 signs.push_back(this->astCtxt->extract(63, 63, op2)); /* Destination[1] = Source[63]; */ 7141 signs.push_back(this->astCtxt->extract(31, 31, op2)); /* Destination[0] = Source[31]; */ 7142 7143 auto node = this->astCtxt->zx(28, this->astCtxt->concat(signs)); 7144 7145 /* Create symbolic expression */ 7146 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVMSKPS operation"); 7147 7148 /* Spread taint */ 7149 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 7150 7151 /* Update the symbolic control flow */ 7152 this->controlFlow_s(inst); 7153 } 7154 7155 movntdq_s(triton::arch::Instruction & inst)7156 void x86Semantics::movntdq_s(triton::arch::Instruction& inst) { 7157 auto& dst = inst.operands[0]; 7158 auto& src = inst.operands[1]; 7159 7160 /* Create the semantics */ 7161 auto node = this->symbolicEngine->getOperandAst(inst, src); 7162 7163 /* Create symbolic expression */ 7164 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVNTDQ operation"); 7165 7166 /* Spread taint */ 7167 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 7168 7169 /* Update the symbolic control flow */ 7170 this->controlFlow_s(inst); 7171 } 7172 7173 movnti_s(triton::arch::Instruction & inst)7174 void x86Semantics::movnti_s(triton::arch::Instruction& inst) { 7175 auto& dst = inst.operands[0]; 7176 auto& src = inst.operands[1]; 7177 7178 /* Create the semantics */ 7179 auto node = this->symbolicEngine->getOperandAst(inst, src); 7180 7181 /* Create symbolic expression */ 7182 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVNTI operation"); 7183 7184 /* Spread taint */ 7185 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 7186 7187 /* Update the symbolic control flow */ 7188 this->controlFlow_s(inst); 7189 } 7190 7191 movntpd_s(triton::arch::Instruction & inst)7192 void x86Semantics::movntpd_s(triton::arch::Instruction& inst) { 7193 auto& dst = inst.operands[0]; 7194 auto& src = inst.operands[1]; 7195 7196 /* Create the semantics */ 7197 auto node = this->symbolicEngine->getOperandAst(inst, src); 7198 7199 /* Create symbolic expression */ 7200 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVNTPD operation"); 7201 7202 /* Spread taint */ 7203 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 7204 7205 /* Update the symbolic control flow */ 7206 this->controlFlow_s(inst); 7207 } 7208 7209 movntps_s(triton::arch::Instruction & inst)7210 void x86Semantics::movntps_s(triton::arch::Instruction& inst) { 7211 auto& dst = inst.operands[0]; 7212 auto& src = inst.operands[1]; 7213 7214 /* Create the semantics */ 7215 auto node = this->symbolicEngine->getOperandAst(inst, src); 7216 7217 /* Create symbolic expression */ 7218 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVNTPS operation"); 7219 7220 /* Spread taint */ 7221 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 7222 7223 /* Update the symbolic control flow */ 7224 this->controlFlow_s(inst); 7225 } 7226 7227 movntq_s(triton::arch::Instruction & inst)7228 void x86Semantics::movntq_s(triton::arch::Instruction& inst) { 7229 auto& dst = inst.operands[0]; 7230 auto& src = inst.operands[1]; 7231 7232 /* Create the semantics */ 7233 auto node = this->symbolicEngine->getOperandAst(inst, src); 7234 7235 /* Create symbolic expression */ 7236 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVNTQ operation"); 7237 7238 /* Spread taint */ 7239 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 7240 7241 /* Update the symbolic control flow */ 7242 this->controlFlow_s(inst); 7243 } 7244 7245 movshdup_s(triton::arch::Instruction & inst)7246 void x86Semantics::movshdup_s(triton::arch::Instruction& inst) { 7247 auto& dst = inst.operands[0]; 7248 auto& src = inst.operands[1]; 7249 7250 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 7251 7252 /* Create the semantics */ 7253 std::vector<triton::ast::SharedAbstractNode> bytes; 7254 bytes.reserve(4); 7255 7256 bytes.push_back(this->astCtxt->extract(127, 96, op2)); 7257 bytes.push_back(this->astCtxt->extract(127, 96, op2)); 7258 bytes.push_back(this->astCtxt->extract(63, 32, op2)); 7259 bytes.push_back(this->astCtxt->extract(63, 32, op2)); 7260 7261 auto node = this->astCtxt->concat(bytes); 7262 7263 /* Create symbolic expression */ 7264 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSHDUP operation"); 7265 7266 /* Spread taint */ 7267 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 7268 7269 /* Update the symbolic control flow */ 7270 this->controlFlow_s(inst); 7271 } 7272 7273 movsldup_s(triton::arch::Instruction & inst)7274 void x86Semantics::movsldup_s(triton::arch::Instruction& inst) { 7275 auto& dst = inst.operands[0]; 7276 auto& src = inst.operands[1]; 7277 7278 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 7279 7280 /* Create the semantics */ 7281 std::vector<triton::ast::SharedAbstractNode> bytes; 7282 bytes.reserve(4); 7283 7284 bytes.push_back(this->astCtxt->extract(95, 64, op2)); 7285 bytes.push_back(this->astCtxt->extract(95, 64, op2)); 7286 bytes.push_back(this->astCtxt->extract(31, 0, op2)); 7287 bytes.push_back(this->astCtxt->extract(31, 0, op2)); 7288 7289 auto node = this->astCtxt->concat(bytes); 7290 7291 /* Create symbolic expression */ 7292 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSLDUP operation"); 7293 7294 /* Spread taint */ 7295 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 7296 7297 /* Update the symbolic control flow */ 7298 this->controlFlow_s(inst); 7299 } 7300 7301 movq_s(triton::arch::Instruction & inst)7302 void x86Semantics::movq_s(triton::arch::Instruction& inst) { 7303 auto& dst = inst.operands[0]; 7304 auto& src = inst.operands[1]; 7305 7306 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 7307 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 7308 7309 /* Create the semantics */ 7310 triton::ast::SharedAbstractNode node = nullptr; 7311 7312 /* when operating on MMX technology registers and memory locations */ 7313 if (dst.getBitSize() == triton::bitsize::qword && src.getBitSize() == triton::bitsize::qword) 7314 node = op2; 7315 7316 /* when source and destination operands are XMM registers */ 7317 else if (dst.getBitSize() == triton::bitsize::dqword && src.getBitSize() == triton::bitsize::dqword) 7318 node = this->astCtxt->concat( 7319 this->astCtxt->extract(triton::bitsize::dqword-1, triton::bitsize::qword, op1), 7320 this->astCtxt->extract(triton::bitsize::qword-1, 0, op2) 7321 ); 7322 7323 /* when source operand is XMM register and destination operand is memory location */ 7324 else if (dst.getBitSize() < src.getBitSize()) 7325 node = this->astCtxt->extract(triton::bitsize::qword-1, 0, op2); 7326 7327 /* when source operand is memory location and destination operand is XMM register */ 7328 else if (dst.getBitSize() > src.getBitSize()) 7329 node = this->astCtxt->zx(triton::bitsize::qword, op2); 7330 7331 /* Invalid operation */ 7332 else 7333 throw triton::exceptions::Semantics("x86Semantics::movq_s(): Invalid operation."); 7334 7335 /* Create symbolic expression */ 7336 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVQ operation"); 7337 7338 /* Spread taint */ 7339 if (dst.getBitSize() == triton::bitsize::dqword && src.getBitSize() == triton::bitsize::dqword) 7340 expr->isTainted = this->taintEngine->taintUnion(dst, src); 7341 else 7342 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 7343 7344 /* Update the symbolic control flow */ 7345 this->controlFlow_s(inst); 7346 } 7347 7348 movq2dq_s(triton::arch::Instruction & inst)7349 void x86Semantics::movq2dq_s(triton::arch::Instruction& inst) { 7350 auto& dst = inst.operands[0]; 7351 auto& src = inst.operands[1]; 7352 7353 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 7354 7355 /* Create the semantics */ 7356 auto node = this->astCtxt->zx(triton::bitsize::qword, op2); 7357 7358 /* Create symbolic expression */ 7359 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVQ2DQ operation"); 7360 7361 /* Spread taint */ 7362 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 7363 7364 /* Update the symbolic control flow */ 7365 this->controlFlow_s(inst); 7366 } 7367 7368 movsb_s(triton::arch::Instruction & inst)7369 void x86Semantics::movsb_s(triton::arch::Instruction& inst) { 7370 auto& dst = inst.operands[0]; 7371 auto& src = inst.operands[1]; 7372 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI)); 7373 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI)); 7374 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 7375 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 7376 7377 /* Check if there is a REP prefix and a counter to zero */ 7378 auto cnt = this->symbolicEngine->getOperandAst(cx); 7379 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 7380 this->controlFlow_s(inst); 7381 return; 7382 } 7383 7384 /* Create symbolic operands */ 7385 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 7386 auto op2 = this->symbolicEngine->getOperandAst(inst, index1); 7387 auto op3 = this->symbolicEngine->getOperandAst(inst, index2); 7388 auto op4 = this->symbolicEngine->getOperandAst(inst, df); 7389 7390 /* Create the semantics */ 7391 auto node1 = op1; 7392 auto node2 = this->astCtxt->ite( 7393 this->astCtxt->equal(op4, this->astCtxt->bvfalse()), 7394 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::byte, index1.getBitSize())), 7395 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::byte, index1.getBitSize())) 7396 ); 7397 auto node3 = this->astCtxt->ite( 7398 this->astCtxt->equal(op4, this->astCtxt->bvfalse()), 7399 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::byte, index2.getBitSize())), 7400 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::byte, index2.getBitSize())) 7401 ); 7402 7403 /* Create symbolic expression */ 7404 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "MOVSB operation"); 7405 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (DI) operation"); 7406 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (SI) operation"); 7407 7408 /* Spread taint */ 7409 expr1->isTainted = this->taintEngine->taintAssignment(dst, src); 7410 expr2->isTainted = this->taintEngine->taintUnion(index1, index1); 7411 expr3->isTainted = this->taintEngine->taintUnion(index2, index2); 7412 7413 /* Update the symbolic control flow */ 7414 this->controlFlow_s(inst); 7415 } 7416 7417 movsd_s(triton::arch::Instruction & inst)7418 void x86Semantics::movsd_s(triton::arch::Instruction& inst) { 7419 auto& dst = inst.operands[0]; 7420 auto& src = inst.operands[1]; 7421 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI)); 7422 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI)); 7423 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 7424 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 7425 7426 /* Check if there is a REP prefix and a counter to zero */ 7427 auto cnt = this->symbolicEngine->getOperandAst(cx); 7428 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 7429 this->controlFlow_s(inst); 7430 return; 7431 } 7432 7433 /* 7434 * F2 0F 10 /r MOVSD xmm1, xmm2 7435 * F2 0F 10 /r MOVSD xmm1, m64 7436 * F2 0F 11 /r MOVSD m64, xmm2 7437 */ 7438 if (dst.getBitSize() == triton::bitsize::dqword) { 7439 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 7440 auto op2 = this->symbolicEngine->getOperandAst(dst); 7441 7442 auto node = this->astCtxt->concat( 7443 this->astCtxt->extract(127, 64, op2), 7444 this->astCtxt->extract(63, 0, op1) 7445 ); 7446 7447 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSD operation"); 7448 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 7449 } 7450 7451 /* 7452 * F2 0F 11 /r MOVSD m64, xmm2 7453 */ 7454 else if (dst.getBitSize() == triton::bitsize::qword && src.getBitSize() == triton::bitsize::dqword) { 7455 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 7456 auto node = this->astCtxt->extract(63, 0, op1); 7457 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSD operation"); 7458 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 7459 } 7460 7461 /* A5 MOVSD */ 7462 else { 7463 /* Create symbolic operands */ 7464 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 7465 auto op2 = this->symbolicEngine->getOperandAst(inst, index1); 7466 auto op3 = this->symbolicEngine->getOperandAst(inst, index2); 7467 auto op4 = this->symbolicEngine->getOperandAst(inst, df); 7468 7469 /* Create the semantics */ 7470 auto node1 = op1; 7471 auto node2 = this->astCtxt->ite( 7472 this->astCtxt->equal(op4, this->astCtxt->bvfalse()), 7473 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::dword, index1.getBitSize())), 7474 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::dword, index1.getBitSize())) 7475 ); 7476 auto node3 = this->astCtxt->ite( 7477 this->astCtxt->equal(op4, this->astCtxt->bvfalse()), 7478 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::dword, index2.getBitSize())), 7479 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::dword, index2.getBitSize())) 7480 ); 7481 7482 /* Create symbolic expression */ 7483 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "MOVSD operation"); 7484 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (DI) operation"); 7485 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (SI) operation"); 7486 7487 /* Spread taint */ 7488 expr1->isTainted = this->taintEngine->taintAssignment(dst, src); 7489 expr2->isTainted = this->taintEngine->taintUnion(index1, index1); 7490 expr3->isTainted = this->taintEngine->taintUnion(index2, index2); 7491 } 7492 7493 /* Update the symbolic control flow */ 7494 this->controlFlow_s(inst); 7495 } 7496 7497 movupd_s(triton::arch::Instruction & inst)7498 void x86Semantics::movupd_s(triton::arch::Instruction& inst) { 7499 auto& dst = inst.operands[0]; 7500 auto& src = inst.operands[1]; 7501 7502 /* Create the semantics */ 7503 auto node = this->symbolicEngine->getOperandAst(inst, src); 7504 7505 /* Create symbolic expression */ 7506 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVUPD operation"); 7507 7508 /* Spread taint */ 7509 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 7510 7511 /* Update the symbolic control flow */ 7512 this->controlFlow_s(inst); 7513 } 7514 7515 movups_s(triton::arch::Instruction & inst)7516 void x86Semantics::movups_s(triton::arch::Instruction& inst) { 7517 auto& dst = inst.operands[0]; 7518 auto& src = inst.operands[1]; 7519 7520 /* Create the semantics */ 7521 auto node = this->symbolicEngine->getOperandAst(inst, src); 7522 7523 /* Create symbolic expression */ 7524 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVUPS operation"); 7525 7526 /* Spread taint */ 7527 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 7528 7529 /* Update the symbolic control flow */ 7530 this->controlFlow_s(inst); 7531 } 7532 7533 movsq_s(triton::arch::Instruction & inst)7534 void x86Semantics::movsq_s(triton::arch::Instruction& inst) { 7535 auto& dst = inst.operands[0]; 7536 auto& src = inst.operands[1]; 7537 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI)); 7538 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI)); 7539 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 7540 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 7541 7542 /* Check if there is a REP prefix and a counter to zero */ 7543 auto cnt = this->symbolicEngine->getOperandAst(cx); 7544 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 7545 this->controlFlow_s(inst); 7546 return; 7547 } 7548 7549 /* Create symbolic operands */ 7550 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 7551 auto op2 = this->symbolicEngine->getOperandAst(inst, index1); 7552 auto op3 = this->symbolicEngine->getOperandAst(inst, index2); 7553 auto op4 = this->symbolicEngine->getOperandAst(inst, df); 7554 7555 /* Create the semantics */ 7556 auto node1 = op1; 7557 auto node2 = this->astCtxt->ite( 7558 this->astCtxt->equal(op4, this->astCtxt->bvfalse()), 7559 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::qword, index1.getBitSize())), 7560 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::qword, index1.getBitSize())) 7561 ); 7562 auto node3 = this->astCtxt->ite( 7563 this->astCtxt->equal(op4, this->astCtxt->bvfalse()), 7564 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::qword, index2.getBitSize())), 7565 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::qword, index2.getBitSize())) 7566 ); 7567 7568 /* Create symbolic expression */ 7569 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "MOVSQ operation"); 7570 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (DI) operation"); 7571 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (SI) operation"); 7572 7573 /* Spread taint */ 7574 expr1->isTainted = this->taintEngine->taintAssignment(dst, src); 7575 expr2->isTainted = this->taintEngine->taintUnion(index1, index1); 7576 expr3->isTainted = this->taintEngine->taintUnion(index2, index2); 7577 7578 /* Update the symbolic control flow */ 7579 this->controlFlow_s(inst); 7580 } 7581 7582 movsw_s(triton::arch::Instruction & inst)7583 void x86Semantics::movsw_s(triton::arch::Instruction& inst) { 7584 auto& dst = inst.operands[0]; 7585 auto& src = inst.operands[1]; 7586 auto index1 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI)); 7587 auto index2 = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_SI)); 7588 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 7589 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 7590 7591 /* Check if there is a REP prefix and a counter to zero */ 7592 auto cnt = this->symbolicEngine->getOperandAst(cx); 7593 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 7594 this->controlFlow_s(inst); 7595 return; 7596 } 7597 7598 /* Create symbolic operands */ 7599 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 7600 auto op2 = this->symbolicEngine->getOperandAst(inst, index1); 7601 auto op3 = this->symbolicEngine->getOperandAst(inst, index2); 7602 auto op4 = this->symbolicEngine->getOperandAst(inst, df); 7603 7604 /* Create the semantics */ 7605 auto node1 = op1; 7606 auto node2 = this->astCtxt->ite( 7607 this->astCtxt->equal(op4, this->astCtxt->bvfalse()), 7608 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::word, index1.getBitSize())), 7609 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::word, index1.getBitSize())) 7610 ); 7611 auto node3 = this->astCtxt->ite( 7612 this->astCtxt->equal(op4, this->astCtxt->bvfalse()), 7613 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::word, index2.getBitSize())), 7614 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::word, index2.getBitSize())) 7615 ); 7616 7617 /* Create symbolic expression */ 7618 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "MOVSW operation"); 7619 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index1, "Index (DI) operation"); 7620 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, index2, "Index (SI) operation"); 7621 7622 /* Spread taint */ 7623 expr1->isTainted = this->taintEngine->taintAssignment(dst, src); 7624 expr2->isTainted = this->taintEngine->taintUnion(index1, index1); 7625 expr3->isTainted = this->taintEngine->taintUnion(index2, index2); 7626 7627 /* Update the symbolic control flow */ 7628 this->controlFlow_s(inst); 7629 } 7630 7631 movsx_s(triton::arch::Instruction & inst)7632 void x86Semantics::movsx_s(triton::arch::Instruction& inst) { 7633 auto& dst = inst.operands[0]; 7634 auto& src = inst.operands[1]; 7635 7636 /* Create symbolic operands */ 7637 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 7638 7639 /* Create the semantics */ 7640 auto node = this->astCtxt->sx(dst.getBitSize() - src.getBitSize(), op1); 7641 7642 /* Create symbolic expression */ 7643 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSX operation"); 7644 7645 /* Spread taint */ 7646 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 7647 7648 /* Update the symbolic control flow */ 7649 this->controlFlow_s(inst); 7650 } 7651 7652 movsxd_s(triton::arch::Instruction & inst)7653 void x86Semantics::movsxd_s(triton::arch::Instruction& inst) { 7654 auto& dst = inst.operands[0]; 7655 auto& src = inst.operands[1]; 7656 7657 /* Create symbolic operands */ 7658 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 7659 7660 /* Create the semantics */ 7661 auto node = this->astCtxt->sx(dst.getBitSize() - src.getBitSize(), op1); 7662 7663 /* Create symbolic expression */ 7664 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVSXD operation"); 7665 7666 /* Spread taint */ 7667 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 7668 7669 /* Update the symbolic control flow */ 7670 this->controlFlow_s(inst); 7671 } 7672 7673 movzx_s(triton::arch::Instruction & inst)7674 void x86Semantics::movzx_s(triton::arch::Instruction& inst) { 7675 auto& dst = inst.operands[0]; 7676 auto& src = inst.operands[1]; 7677 7678 /* Create symbolic operands */ 7679 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 7680 7681 /* Create the semantics */ 7682 auto node = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), op1); 7683 7684 /* Create symbolic expression */ 7685 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOVZX operation"); 7686 7687 /* Spread taint */ 7688 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 7689 7690 /* Update the symbolic control flow */ 7691 this->controlFlow_s(inst); 7692 } 7693 7694 mul_s(triton::arch::Instruction & inst)7695 void x86Semantics::mul_s(triton::arch::Instruction& inst) { 7696 auto& src2 = inst.operands[0]; 7697 7698 switch (src2.getSize()) { 7699 7700 /* AX = AL * r/m8 */ 7701 case triton::size::byte: { 7702 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX)); 7703 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AL)); 7704 /* Create symbolic operands */ 7705 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 7706 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 7707 /* Create the semantics */ 7708 auto node = this->astCtxt->bvmul(this->astCtxt->zx(triton::bitsize::byte, op1), this->astCtxt->zx(triton::bitsize::byte, op2)); 7709 /* Create symbolic expression */ 7710 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MUL operation"); 7711 /* Apply the taint */ 7712 expr->isTainted = this->taintEngine->taintUnion(dst, src2); 7713 /* Update symbolic flags */ 7714 auto ah = this->astCtxt->extract((triton::bitsize::word - 1), triton::bitsize::byte, node); 7715 this->cfMul_s(inst, expr, src2, ah); 7716 this->ofMul_s(inst, expr, src2, ah); 7717 break; 7718 } 7719 7720 /* DX:AX = AX * r/m16 */ 7721 case triton::size::word: { 7722 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX)); 7723 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DX)); 7724 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AX)); 7725 /* Create symbolic operands */ 7726 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 7727 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 7728 /* Create the semantics */ 7729 auto node = this->astCtxt->bvmul(this->astCtxt->zx(triton::bitsize::word, op1), this->astCtxt->zx(triton::bitsize::word, op2)); 7730 /* Create symbolic expression for ax */ 7731 auto ax = this->astCtxt->extract((triton::bitsize::word - 1), 0, node); 7732 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, ax, dst1, "MUL operation"); 7733 /* Apply the taint */ 7734 expr1->isTainted = this->taintEngine->taintUnion(dst1, src2); 7735 /* Create symbolic expression for dx */ 7736 auto dx = this->astCtxt->extract((triton::bitsize::dword - 1), triton::bitsize::word, node); 7737 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, dx, dst2, "MUL operation"); 7738 /* Apply the taint */ 7739 expr2->isTainted = this->taintEngine->taintUnion(dst2, src2); 7740 expr2->isTainted = this->taintEngine->taintUnion(dst2, src1); 7741 /* Update symbolic flags */ 7742 this->cfMul_s(inst, expr2, src2, dx); 7743 this->ofMul_s(inst, expr2, src2, dx); 7744 break; 7745 } 7746 7747 /* EDX:EAX = EAX * r/m32 */ 7748 case triton::size::dword: { 7749 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX)); 7750 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX)); 7751 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX)); 7752 /* Create symbolic operands */ 7753 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 7754 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 7755 /* Create the semantics */ 7756 auto node = this->astCtxt->bvmul(this->astCtxt->zx(triton::bitsize::dword, op1), this->astCtxt->zx(triton::bitsize::dword, op2)); 7757 /* Create symbolic expression for eax */ 7758 auto eax = this->astCtxt->extract((triton::bitsize::dword - 1), 0, node); 7759 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, eax, dst1, "MUL operation"); 7760 /* Apply the taint */ 7761 expr1->isTainted = this->taintEngine->taintUnion(dst1, src2); 7762 /* Create symbolic expression for edx */ 7763 auto edx = this->astCtxt->extract((triton::bitsize::qword - 1), triton::bitsize::dword, node); 7764 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, edx, dst2, "MUL operation"); 7765 /* Apply the taint */ 7766 expr2->isTainted = this->taintEngine->taintUnion(dst2, src2); 7767 expr2->isTainted = this->taintEngine->taintUnion(dst2, src1); 7768 /* Update symbolic flags */ 7769 this->cfMul_s(inst, expr2, src2, edx); 7770 this->ofMul_s(inst, expr2, src2, edx); 7771 break; 7772 } 7773 7774 /* RDX:RAX = RAX * r/m64 */ 7775 case triton::size::qword: { 7776 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX)); 7777 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX)); 7778 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RAX)); 7779 /* Create symbolic operands */ 7780 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 7781 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 7782 /* Create the semantics */ 7783 auto node = this->astCtxt->bvmul(this->astCtxt->zx(triton::bitsize::qword, op1), this->astCtxt->zx(triton::bitsize::qword, op2)); 7784 /* Create symbolic expression for eax */ 7785 auto rax = this->astCtxt->extract((triton::bitsize::qword - 1), 0, node); 7786 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, rax, dst1, "MUL operation"); 7787 /* Apply the taint */ 7788 expr1->isTainted = this->taintEngine->taintUnion(dst1, src2); 7789 /* Create symbolic expression for rdx */ 7790 auto rdx = this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, node); 7791 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, rdx, dst2, "MUL operation"); 7792 /* Apply the taint */ 7793 expr2->isTainted = this->taintEngine->taintUnion(dst2, src2); 7794 expr2->isTainted = this->taintEngine->taintUnion(dst2, src1); 7795 /* Update symbolic flags */ 7796 this->cfMul_s(inst, expr2, src2, rdx); 7797 this->ofMul_s(inst, expr2, src2, rdx); 7798 break; 7799 } 7800 7801 } 7802 7803 /* Tag undefined flags */ 7804 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 7805 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF)); 7806 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF)); 7807 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF)); 7808 7809 /* Update the symbolic control flow */ 7810 this->controlFlow_s(inst); 7811 } 7812 7813 mulx_s(triton::arch::Instruction & inst)7814 void x86Semantics::mulx_s(triton::arch::Instruction& inst) { 7815 switch (inst.operands[0].getSize()) { 7816 7817 /* r32a, r32b, r/m32 */ 7818 case triton::size::dword: { 7819 auto& dst1 = inst.operands[0]; 7820 auto& dst2 = inst.operands[1]; 7821 auto src1 = inst.operands[2]; 7822 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX)); 7823 7824 /* Create symbolic operands */ 7825 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 7826 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 7827 7828 /* Create the semantics */ 7829 auto node = this->astCtxt->bvmul(this->astCtxt->zx(triton::bitsize::dword, op1), this->astCtxt->zx(triton::bitsize::dword, op2)); 7830 auto node1 = this->astCtxt->extract((triton::bitsize::dword - 1), 0, node); 7831 auto node2 = this->astCtxt->extract((triton::bitsize::qword - 1), triton::bitsize::dword, node); 7832 7833 /* Create symbolic expression for eax */ 7834 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst2, "MULX operation"); 7835 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst1, "MULX operation"); 7836 7837 /* Apply the taint */ 7838 expr1->isTainted = this->taintEngine->taintUnion(dst2, src1); 7839 expr1->isTainted = this->taintEngine->taintUnion(dst2, src2); 7840 7841 expr2->isTainted = this->taintEngine->taintUnion(dst1, src1); 7842 expr2->isTainted = this->taintEngine->taintUnion(dst1, src2); 7843 break; 7844 } 7845 7846 /* r64a, r64b, r/m64 */ 7847 case triton::size::qword: { 7848 auto& dst1 = inst.operands[0]; 7849 auto& dst2 = inst.operands[1]; 7850 auto src1 = inst.operands[2]; 7851 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RDX)); 7852 7853 /* Create symbolic operands */ 7854 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 7855 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 7856 7857 /* Create the semantics */ 7858 auto node = this->astCtxt->bvmul(this->astCtxt->zx(triton::bitsize::qword, op1), this->astCtxt->zx(triton::bitsize::qword, op2)); 7859 auto node1 = this->astCtxt->extract((triton::bitsize::qword - 1), 0, node); 7860 auto node2 = this->astCtxt->extract((triton::bitsize::dqword - 1), triton::bitsize::qword, node); 7861 7862 /* Create symbolic expression for eax */ 7863 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst2, "MULX operation"); 7864 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst1, "MULX operation"); 7865 7866 /* Apply the taint */ 7867 expr1->isTainted = this->taintEngine->taintUnion(dst2, src1); 7868 expr1->isTainted = this->taintEngine->taintUnion(dst2, src2); 7869 7870 expr2->isTainted = this->taintEngine->taintUnion(dst1, src1); 7871 expr2->isTainted = this->taintEngine->taintUnion(dst1, src2); 7872 break; 7873 } 7874 7875 } 7876 7877 /* Update the symbolic control flow */ 7878 this->controlFlow_s(inst); 7879 } 7880 7881 neg_s(triton::arch::Instruction & inst)7882 void x86Semantics::neg_s(triton::arch::Instruction& inst) { 7883 auto& src = inst.operands[0]; 7884 7885 /* Create symbolic operands */ 7886 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 7887 7888 /* Create the semantics */ 7889 auto node = this->astCtxt->bvneg(op1); 7890 7891 /* Create symbolic expression */ 7892 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, src, "NEG operation"); 7893 7894 /* Apply the taint */ 7895 expr->isTainted = this->taintEngine->taintUnion(src, src); 7896 7897 /* Update symbolic flags */ 7898 this->afNeg_s(inst, expr, src, op1); 7899 this->cfNeg_s(inst, expr, src, op1); 7900 this->ofNeg_s(inst, expr, src, op1); 7901 this->pf_s(inst, expr, src); 7902 this->sf_s(inst, expr, src); 7903 this->zf_s(inst, expr, src); 7904 7905 /* Update the symbolic control flow */ 7906 this->controlFlow_s(inst); 7907 } 7908 7909 nop_s(triton::arch::Instruction & inst)7910 void x86Semantics::nop_s(triton::arch::Instruction& inst) { 7911 /* Update the symbolic control flow */ 7912 this->controlFlow_s(inst); 7913 } 7914 7915 not_s(triton::arch::Instruction & inst)7916 void x86Semantics::not_s(triton::arch::Instruction& inst) { 7917 auto& src = inst.operands[0]; 7918 7919 /* Create symbolic operands */ 7920 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 7921 7922 /* Create the semantics */ 7923 auto node = this->astCtxt->bvnot(op1); 7924 7925 /* Create symbolic expression */ 7926 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, src, "NOT operation"); 7927 7928 /* Apply the taint */ 7929 expr->isTainted = this->taintEngine->taintUnion(src, src); 7930 7931 /* Update the symbolic control flow */ 7932 this->controlFlow_s(inst); 7933 } 7934 7935 or_s(triton::arch::Instruction & inst)7936 void x86Semantics::or_s(triton::arch::Instruction& inst) { 7937 auto& dst = inst.operands[0]; 7938 auto& src = inst.operands[1]; 7939 7940 /* Create symbolic operands */ 7941 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 7942 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 7943 7944 /* Create the semantics */ 7945 auto node = this->astCtxt->bvor(op1, op2); 7946 7947 /* Create symbolic expression */ 7948 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "OR operation"); 7949 7950 /* Apply the taint */ 7951 expr->isTainted = this->taintEngine->taintUnion(dst, src); 7952 7953 /* Update symbolic flags */ 7954 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag"); 7955 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag"); 7956 this->pf_s(inst, expr, dst); 7957 this->sf_s(inst, expr, dst); 7958 this->zf_s(inst, expr, dst); 7959 7960 /* Tag undefined flags */ 7961 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 7962 7963 /* Update the symbolic control flow */ 7964 this->controlFlow_s(inst); 7965 } 7966 7967 orpd_s(triton::arch::Instruction & inst)7968 void x86Semantics::orpd_s(triton::arch::Instruction& inst) { 7969 auto& dst = inst.operands[0]; 7970 auto& src = inst.operands[1]; 7971 7972 /* Create symbolic operands */ 7973 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 7974 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 7975 7976 /* Create the semantics */ 7977 auto node = this->astCtxt->bvor(op1, op2); 7978 7979 /* Create symbolic expression */ 7980 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ORPD operation"); 7981 7982 /* Apply the taint */ 7983 expr->isTainted = this->taintEngine->taintUnion(dst, src); 7984 7985 /* Update the symbolic control flow */ 7986 this->controlFlow_s(inst); 7987 } 7988 7989 orps_s(triton::arch::Instruction & inst)7990 void x86Semantics::orps_s(triton::arch::Instruction& inst) { 7991 auto& dst = inst.operands[0]; 7992 auto& src = inst.operands[1]; 7993 7994 /* Create symbolic operands */ 7995 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 7996 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 7997 7998 /* Create the semantics */ 7999 auto node = this->astCtxt->bvor(op1, op2); 8000 8001 /* Create symbolic expression */ 8002 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ORPS operation"); 8003 8004 /* Apply the taint */ 8005 expr->isTainted = this->taintEngine->taintUnion(dst, src); 8006 8007 /* Update the symbolic control flow */ 8008 this->controlFlow_s(inst); 8009 } 8010 8011 paddb_s(triton::arch::Instruction & inst)8012 void x86Semantics::paddb_s(triton::arch::Instruction& inst) { 8013 auto& dst = inst.operands[0]; 8014 auto& src = inst.operands[1]; 8015 8016 /* Create symbolic operands */ 8017 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8018 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 8019 8020 /* Create the semantics */ 8021 std::vector<triton::ast::SharedAbstractNode> packed; 8022 packed.reserve(16); 8023 8024 switch (dst.getBitSize()) { 8025 8026 /* XMM */ 8027 case triton::bitsize::dqword: 8028 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(127, 120, op1), this->astCtxt->extract(127, 120, op2))); 8029 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(119, 112, op1), this->astCtxt->extract(119, 112, op2))); 8030 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(111, 104, op1), this->astCtxt->extract(111, 104, op2))); 8031 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(103, 96, op1), this->astCtxt->extract(103, 96, op2))); 8032 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(95, 88, op1), this->astCtxt->extract(95, 88, op2))); 8033 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(87, 80, op1), this->astCtxt->extract(87, 80, op2))); 8034 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(79, 72, op1), this->astCtxt->extract(79, 72, op2))); 8035 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(71, 64, op1), this->astCtxt->extract(71, 64, op2))); 8036 8037 /* MMX */ 8038 case triton::bitsize::qword: 8039 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(63, 56, op1), this->astCtxt->extract(63, 56, op2))); 8040 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(55, 48, op1), this->astCtxt->extract(55, 48, op2))); 8041 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(47, 40, op1), this->astCtxt->extract(47, 40, op2))); 8042 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(39, 32, op1), this->astCtxt->extract(39, 32, op2))); 8043 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(31, 24, op1), this->astCtxt->extract(31, 24, op2))); 8044 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(23, 16, op1), this->astCtxt->extract(23, 16, op2))); 8045 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(15, 8, op1), this->astCtxt->extract(15, 8, op2))); 8046 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(7, 0, op1), this->astCtxt->extract(7, 0, op2))); 8047 break; 8048 8049 default: 8050 throw triton::exceptions::Semantics("x86Semantics::paddb_s(): Invalid operand size."); 8051 8052 } 8053 8054 auto node = this->astCtxt->concat(packed); 8055 8056 /* Create symbolic expression */ 8057 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PADDB operation"); 8058 8059 /* Spread taint */ 8060 expr->isTainted = this->taintEngine->taintUnion(dst, src); 8061 8062 /* Update the symbolic control flow */ 8063 this->controlFlow_s(inst); 8064 } 8065 8066 paddd_s(triton::arch::Instruction & inst)8067 void x86Semantics::paddd_s(triton::arch::Instruction& inst) { 8068 auto& dst = inst.operands[0]; 8069 auto& src = inst.operands[1]; 8070 8071 /* Create symbolic operands */ 8072 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8073 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 8074 8075 /* Create the semantics */ 8076 std::vector<triton::ast::SharedAbstractNode> packed; 8077 packed.reserve(4); 8078 8079 switch (dst.getBitSize()) { 8080 8081 /* XMM */ 8082 case triton::bitsize::dqword: 8083 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(127, 96, op1), this->astCtxt->extract(127, 96, op2))); 8084 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(95, 64, op1), this->astCtxt->extract(95, 64, op2))); 8085 8086 /* MMX */ 8087 case triton::bitsize::qword: 8088 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(63, 32, op1), this->astCtxt->extract(63, 32, op2))); 8089 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(31, 0, op1), this->astCtxt->extract(31, 0, op2))); 8090 break; 8091 8092 default: 8093 throw triton::exceptions::Semantics("x86Semantics::paddd_s(): Invalid operand size."); 8094 8095 } 8096 8097 auto node = this->astCtxt->concat(packed); 8098 8099 /* Create symbolic expression */ 8100 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PADDD operation"); 8101 8102 /* Spread taint */ 8103 expr->isTainted = this->taintEngine->taintUnion(dst, src); 8104 8105 /* Update the symbolic control flow */ 8106 this->controlFlow_s(inst); 8107 } 8108 8109 paddq_s(triton::arch::Instruction & inst)8110 void x86Semantics::paddq_s(triton::arch::Instruction& inst) { 8111 auto& dst = inst.operands[0]; 8112 auto& src = inst.operands[1]; 8113 8114 /* Create symbolic operands */ 8115 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8116 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 8117 8118 /* Create the semantics */ 8119 std::vector<triton::ast::SharedAbstractNode> packed; 8120 packed.reserve(2); 8121 8122 switch (dst.getBitSize()) { 8123 8124 /* XMM */ 8125 case triton::bitsize::dqword: 8126 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(127, 64, op1), this->astCtxt->extract(127, 64, op2))); 8127 8128 /* MMX */ 8129 case triton::bitsize::qword: 8130 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(63, 0, op1), this->astCtxt->extract(63, 0, op2))); 8131 break; 8132 8133 default: 8134 throw triton::exceptions::Semantics("x86Semantics::paddq_s(): Invalid operand size."); 8135 8136 } 8137 8138 auto node = this->astCtxt->concat(packed); 8139 8140 /* Create symbolic expression */ 8141 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PADDQ operation"); 8142 8143 /* Spread taint */ 8144 expr->isTainted = this->taintEngine->taintUnion(dst, src); 8145 8146 /* Update the symbolic control flow */ 8147 this->controlFlow_s(inst); 8148 } 8149 8150 paddw_s(triton::arch::Instruction & inst)8151 void x86Semantics::paddw_s(triton::arch::Instruction& inst) { 8152 auto& dst = inst.operands[0]; 8153 auto& src = inst.operands[1]; 8154 8155 /* Create symbolic operands */ 8156 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8157 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 8158 8159 /* Create the semantics */ 8160 std::vector<triton::ast::SharedAbstractNode> packed; 8161 packed.reserve(8); 8162 8163 switch (dst.getBitSize()) { 8164 8165 /* XMM */ 8166 case triton::bitsize::dqword: 8167 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(127, 112, op1), this->astCtxt->extract(127, 112, op2))); 8168 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(111, 96, op1), this->astCtxt->extract(111, 96, op2))); 8169 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(95, 80, op1), this->astCtxt->extract(95, 80, op2))); 8170 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(79, 64, op1), this->astCtxt->extract(79, 64, op2))); 8171 8172 /* MMX */ 8173 case triton::bitsize::qword: 8174 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(63, 48, op1), this->astCtxt->extract(63, 48, op2))); 8175 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(47, 32, op1), this->astCtxt->extract(47, 32, op2))); 8176 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(31, 16, op1), this->astCtxt->extract(31, 16, op2))); 8177 packed.push_back(this->astCtxt->bvadd(this->astCtxt->extract(15, 0, op1), this->astCtxt->extract(15, 0, op2))); 8178 break; 8179 8180 default: 8181 throw triton::exceptions::Semantics("x86Semantics::paddw_s(): Invalid operand size."); 8182 8183 } 8184 8185 auto node = this->astCtxt->concat(packed); 8186 8187 /* Create symbolic expression */ 8188 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PADDW operation"); 8189 8190 /* Spread taint */ 8191 expr->isTainted = this->taintEngine->taintUnion(dst, src); 8192 8193 /* Update the symbolic control flow */ 8194 this->controlFlow_s(inst); 8195 } 8196 8197 pand_s(triton::arch::Instruction & inst)8198 void x86Semantics::pand_s(triton::arch::Instruction& inst) { 8199 auto& dst = inst.operands[0]; 8200 auto& src = inst.operands[1]; 8201 8202 /* Create symbolic operands */ 8203 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8204 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 8205 8206 /* Create the semantics */ 8207 auto node = this->astCtxt->bvand(op1, op2); 8208 8209 /* Create symbolic expression */ 8210 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PAND operation"); 8211 8212 /* Spread taint */ 8213 expr->isTainted = this->taintEngine->taintUnion(dst, src); 8214 8215 /* Update the symbolic control flow */ 8216 this->controlFlow_s(inst); 8217 } 8218 8219 pandn_s(triton::arch::Instruction & inst)8220 void x86Semantics::pandn_s(triton::arch::Instruction& inst) { 8221 auto& dst = inst.operands[0]; 8222 auto& src = inst.operands[1]; 8223 8224 /* Create symbolic operands */ 8225 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8226 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 8227 8228 /* Create the semantics */ 8229 auto node = this->astCtxt->bvand(this->astCtxt->bvnot(op1), op2); 8230 8231 /* Create symbolic expression */ 8232 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PANDN operation"); 8233 8234 /* Spread taint */ 8235 expr->isTainted = this->taintEngine->taintUnion(dst, src); 8236 8237 /* Update the symbolic control flow */ 8238 this->controlFlow_s(inst); 8239 } 8240 8241 pause_s(triton::arch::Instruction & inst)8242 void x86Semantics::pause_s(triton::arch::Instruction& inst) { 8243 /* Update the symbolic control flow */ 8244 this->controlFlow_s(inst); 8245 } 8246 8247 pavgb_s(triton::arch::Instruction & inst)8248 void x86Semantics::pavgb_s(triton::arch::Instruction& inst) { 8249 auto& dst = inst.operands[0]; 8250 auto& src = inst.operands[1]; 8251 8252 /* Create symbolic operands */ 8253 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8254 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 8255 8256 /* Create the semantics */ 8257 std::vector<triton::ast::SharedAbstractNode> pck; 8258 pck.reserve(dst.getSize()); 8259 8260 for (triton::uint32 index = 0; index < dst.getSize(); index++) { 8261 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte); 8262 uint32 low = (dst.getBitSize() - triton::bitsize::byte) - (index * triton::bitsize::byte); 8263 pck.push_back( 8264 this->astCtxt->extract(triton::bitsize::byte-1, 0, 8265 this->astCtxt->bvlshr( 8266 this->astCtxt->bvadd( 8267 this->astCtxt->bvadd( 8268 this->astCtxt->zx(1, this->astCtxt->extract(high, low, op1)), 8269 this->astCtxt->zx(1, this->astCtxt->extract(high, low, op2)) 8270 ), 8271 this->astCtxt->bv(1, triton::bitsize::byte+1) 8272 ), 8273 this->astCtxt->bv(1, triton::bitsize::byte+1) 8274 ) 8275 ) 8276 ); 8277 } 8278 8279 auto node = this->astCtxt->concat(pck); 8280 8281 /* Create symbolic expression */ 8282 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PAVGB operation"); 8283 8284 /* Spread taint */ 8285 expr->isTainted = this->taintEngine->taintUnion(dst, src); 8286 8287 /* Update the symbolic control flow */ 8288 this->controlFlow_s(inst); 8289 } 8290 8291 pavgw_s(triton::arch::Instruction & inst)8292 void x86Semantics::pavgw_s(triton::arch::Instruction& inst) { 8293 auto& dst = inst.operands[0]; 8294 auto& src = inst.operands[1]; 8295 8296 /* Create symbolic operands */ 8297 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8298 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 8299 8300 /* Create the semantics */ 8301 std::vector<triton::ast::SharedAbstractNode> pck; 8302 pck.reserve(dst.getSize()); 8303 8304 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) { 8305 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word); 8306 uint32 low = (dst.getBitSize() - triton::bitsize::word) - (index * triton::bitsize::word); 8307 pck.push_back( 8308 this->astCtxt->extract(triton::bitsize::word-1, 0, 8309 this->astCtxt->bvlshr( 8310 this->astCtxt->bvadd( 8311 this->astCtxt->bvadd( 8312 this->astCtxt->zx(1, this->astCtxt->extract(high, low, op1)), 8313 this->astCtxt->zx(1, this->astCtxt->extract(high, low, op2)) 8314 ), 8315 this->astCtxt->bv(1, triton::bitsize::word+1) 8316 ), 8317 this->astCtxt->bv(1, triton::bitsize::word+1) 8318 ) 8319 ) 8320 ); 8321 } 8322 8323 auto node = this->astCtxt->concat(pck); 8324 8325 /* Create symbolic expression */ 8326 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PAVGW operation"); 8327 8328 /* Spread taint */ 8329 expr->isTainted = this->taintEngine->taintUnion(dst, src); 8330 8331 /* Update the symbolic control flow */ 8332 this->controlFlow_s(inst); 8333 } 8334 8335 pcmpeqb_s(triton::arch::Instruction & inst)8336 void x86Semantics::pcmpeqb_s(triton::arch::Instruction& inst) { 8337 auto& dst = inst.operands[0]; 8338 auto& src = inst.operands[1]; 8339 8340 /* Create symbolic operands */ 8341 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8342 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 8343 8344 /* Create the semantics */ 8345 std::vector<triton::ast::SharedAbstractNode> pck; 8346 pck.reserve(dst.getSize()); 8347 8348 for (triton::uint32 index = 0; index < dst.getSize(); index++) { 8349 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte); 8350 uint32 low = (dst.getBitSize() - triton::bitsize::byte) - (index * triton::bitsize::byte); 8351 pck.push_back(this->astCtxt->ite( 8352 this->astCtxt->equal( 8353 this->astCtxt->extract(high, low, op1), 8354 this->astCtxt->extract(high, low, op2)), 8355 this->astCtxt->bv(0xff, triton::bitsize::byte), 8356 this->astCtxt->bv(0x00, triton::bitsize::byte)) 8357 ); 8358 } 8359 8360 auto node = this->astCtxt->concat(pck); 8361 8362 /* Create symbolic expression */ 8363 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PCMPEQB operation"); 8364 8365 /* Apply the taint */ 8366 expr->isTainted = this->taintEngine->taintUnion(dst, src); 8367 8368 /* Update the symbolic control flow */ 8369 this->controlFlow_s(inst); 8370 } 8371 8372 pcmpeqd_s(triton::arch::Instruction & inst)8373 void x86Semantics::pcmpeqd_s(triton::arch::Instruction& inst) { 8374 auto& dst = inst.operands[0]; 8375 auto& src = inst.operands[1]; 8376 8377 /* Create symbolic operands */ 8378 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8379 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 8380 8381 /* Create the semantics */ 8382 std::vector<triton::ast::SharedAbstractNode> pck; 8383 pck.reserve(dst.getSize()); 8384 8385 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) { 8386 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword); 8387 uint32 low = (dst.getBitSize() - triton::bitsize::dword) - (index * triton::bitsize::dword); 8388 pck.push_back(this->astCtxt->ite( 8389 this->astCtxt->equal( 8390 this->astCtxt->extract(high, low, op1), 8391 this->astCtxt->extract(high, low, op2)), 8392 this->astCtxt->bv(0xffffffff, triton::bitsize::dword), 8393 this->astCtxt->bv(0x00000000, triton::bitsize::dword)) 8394 ); 8395 } 8396 8397 auto node = this->astCtxt->concat(pck); 8398 8399 /* Create symbolic expression */ 8400 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PCMPEQD operation"); 8401 8402 /* Apply the taint */ 8403 expr->isTainted = this->taintEngine->taintUnion(dst, src); 8404 8405 /* Update the symbolic control flow */ 8406 this->controlFlow_s(inst); 8407 } 8408 8409 pcmpeqw_s(triton::arch::Instruction & inst)8410 void x86Semantics::pcmpeqw_s(triton::arch::Instruction& inst) { 8411 auto& dst = inst.operands[0]; 8412 auto& src = inst.operands[1]; 8413 8414 /* Create symbolic operands */ 8415 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8416 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 8417 8418 /* Create the semantics */ 8419 std::vector<triton::ast::SharedAbstractNode> pck; 8420 pck.reserve(dst.getSize()); 8421 8422 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) { 8423 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word); 8424 uint32 low = (dst.getBitSize() - triton::bitsize::word) - (index * triton::bitsize::word); 8425 pck.push_back(this->astCtxt->ite( 8426 this->astCtxt->equal( 8427 this->astCtxt->extract(high, low, op1), 8428 this->astCtxt->extract(high, low, op2)), 8429 this->astCtxt->bv(0xffff, triton::bitsize::word), 8430 this->astCtxt->bv(0x0000, triton::bitsize::word)) 8431 ); 8432 } 8433 8434 auto node = this->astCtxt->concat(pck); 8435 8436 /* Create symbolic expression */ 8437 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PCMPEQW operation"); 8438 8439 /* Apply the taint */ 8440 expr->isTainted = this->taintEngine->taintUnion(dst, src); 8441 8442 /* Update the symbolic control flow */ 8443 this->controlFlow_s(inst); 8444 } 8445 8446 pcmpgtb_s(triton::arch::Instruction & inst)8447 void x86Semantics::pcmpgtb_s(triton::arch::Instruction& inst) { 8448 auto& dst = inst.operands[0]; 8449 auto& src = inst.operands[1]; 8450 8451 /* Create symbolic operands */ 8452 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8453 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 8454 8455 /* Create the semantics */ 8456 std::vector<triton::ast::SharedAbstractNode> pck; 8457 pck.reserve(dst.getSize()); 8458 8459 for (triton::uint32 index = 0; index < dst.getSize(); index++) { 8460 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte); 8461 uint32 low = (dst.getBitSize() - triton::bitsize::byte) - (index * triton::bitsize::byte); 8462 pck.push_back(this->astCtxt->ite( 8463 this->astCtxt->bvsgt( 8464 this->astCtxt->extract(high, low, op1), 8465 this->astCtxt->extract(high, low, op2)), 8466 this->astCtxt->bv(0xff, triton::bitsize::byte), 8467 this->astCtxt->bv(0x00, triton::bitsize::byte)) 8468 ); 8469 } 8470 8471 auto node = this->astCtxt->concat(pck); 8472 8473 /* Create symbolic expression */ 8474 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PCMPGTB operation"); 8475 8476 /* Apply the taint */ 8477 expr->isTainted = this->taintEngine->taintUnion(dst, src); 8478 8479 /* Update the symbolic control flow */ 8480 this->controlFlow_s(inst); 8481 } 8482 8483 pcmpgtd_s(triton::arch::Instruction & inst)8484 void x86Semantics::pcmpgtd_s(triton::arch::Instruction& inst) { 8485 auto& dst = inst.operands[0]; 8486 auto& src = inst.operands[1]; 8487 8488 /* Create symbolic operands */ 8489 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8490 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 8491 8492 /* Create the semantics */ 8493 std::vector<triton::ast::SharedAbstractNode> pck; 8494 pck.reserve(dst.getSize()); 8495 8496 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) { 8497 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword); 8498 uint32 low = (dst.getBitSize() - triton::bitsize::dword) - (index * triton::bitsize::dword); 8499 pck.push_back(this->astCtxt->ite( 8500 this->astCtxt->bvsgt( 8501 this->astCtxt->extract(high, low, op1), 8502 this->astCtxt->extract(high, low, op2)), 8503 this->astCtxt->bv(0xffffffff, triton::bitsize::dword), 8504 this->astCtxt->bv(0x00000000, triton::bitsize::dword)) 8505 ); 8506 } 8507 8508 auto node = this->astCtxt->concat(pck); 8509 8510 /* Create symbolic expression */ 8511 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PCMPGTD operation"); 8512 8513 /* Apply the taint */ 8514 expr->isTainted = this->taintEngine->taintUnion(dst, src); 8515 8516 /* Update the symbolic control flow */ 8517 this->controlFlow_s(inst); 8518 } 8519 8520 pcmpgtw_s(triton::arch::Instruction & inst)8521 void x86Semantics::pcmpgtw_s(triton::arch::Instruction& inst) { 8522 auto& dst = inst.operands[0]; 8523 auto& src = inst.operands[1]; 8524 8525 /* Create symbolic operands */ 8526 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8527 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 8528 8529 /* Create the semantics */ 8530 std::vector<triton::ast::SharedAbstractNode> pck; 8531 pck.reserve(dst.getSize()); 8532 8533 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) { 8534 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word); 8535 uint32 low = (dst.getBitSize() - triton::bitsize::word) - (index * triton::bitsize::word); 8536 pck.push_back(this->astCtxt->ite( 8537 this->astCtxt->bvsgt( 8538 this->astCtxt->extract(high, low, op1), 8539 this->astCtxt->extract(high, low, op2)), 8540 this->astCtxt->bv(0xffff, triton::bitsize::word), 8541 this->astCtxt->bv(0x0000, triton::bitsize::word)) 8542 ); 8543 } 8544 8545 auto node = this->astCtxt->concat(pck); 8546 8547 /* Create symbolic expression */ 8548 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PCMPGTW operation"); 8549 8550 /* Apply the taint */ 8551 expr->isTainted = this->taintEngine->taintUnion(dst, src); 8552 8553 /* Update the symbolic control flow */ 8554 this->controlFlow_s(inst); 8555 } 8556 8557 pmaxsb_s(triton::arch::Instruction & inst)8558 void x86Semantics::pmaxsb_s(triton::arch::Instruction& inst) { 8559 auto& dst = inst.operands[0]; 8560 auto& src = inst.operands[1]; 8561 8562 /* Create symbolic operands */ 8563 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8564 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 8565 8566 /* Create the semantics */ 8567 std::vector<triton::ast::SharedAbstractNode> pck; 8568 pck.reserve(dst.getSize()); 8569 8570 for (triton::uint32 index = 0; index < dst.getSize(); index++) { 8571 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte); 8572 uint32 low = (dst.getBitSize() - triton::bitsize::byte) - (index * triton::bitsize::byte); 8573 pck.push_back(this->astCtxt->ite( 8574 this->astCtxt->bvsle( 8575 this->astCtxt->extract(high, low, op1), 8576 this->astCtxt->extract(high, low, op2)), 8577 this->astCtxt->extract(high, low, op2), 8578 this->astCtxt->extract(high, low, op1)) 8579 ); 8580 } 8581 8582 auto node = this->astCtxt->concat(pck); 8583 8584 /* Create symbolic expression */ 8585 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMAXSB operation"); 8586 8587 /* Apply the taint */ 8588 expr->isTainted = this->taintEngine->taintUnion(dst, src); 8589 8590 /* Update the symbolic control flow */ 8591 this->controlFlow_s(inst); 8592 } 8593 8594 pextrb_s(triton::arch::Instruction & inst)8595 void x86Semantics::pextrb_s(triton::arch::Instruction& inst) { 8596 auto& dst = inst.operands[0]; 8597 auto& src1 = inst.operands[1]; 8598 auto& src2 = inst.operands[2]; 8599 8600 /* Create symbolic operands */ 8601 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8602 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 8603 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 8604 8605 auto node = this->astCtxt->extract(triton::bitsize::byte - 1, 0, 8606 this->astCtxt->bvlshr( 8607 op2, 8608 this->astCtxt->bv(((op3->evaluate() & 0x0f) * triton::bitsize::byte), op2->getBitvectorSize()) 8609 ) 8610 ); 8611 8612 /* Create symbolic expression */ 8613 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PEXTRB operation"); 8614 8615 /* Apply the taint */ 8616 expr->isTainted = this->taintEngine->taintAssignment(dst, src1); 8617 8618 /* Update the symbolic control flow */ 8619 this->controlFlow_s(inst); 8620 } 8621 8622 pextrd_s(triton::arch::Instruction & inst)8623 void x86Semantics::pextrd_s(triton::arch::Instruction& inst) { 8624 auto& dst = inst.operands[0]; 8625 auto& src1 = inst.operands[1]; 8626 auto& src2 = inst.operands[2]; 8627 8628 /* Create symbolic operands */ 8629 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8630 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 8631 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 8632 8633 auto node = this->astCtxt->extract(triton::bitsize::dword - 1, 0, 8634 this->astCtxt->bvlshr( 8635 op2, 8636 this->astCtxt->bv(((op3->evaluate() & 0x3) * triton::bitsize::dword), op2->getBitvectorSize()) 8637 ) 8638 ); 8639 8640 /* Create symbolic expression */ 8641 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PEXTRD operation"); 8642 8643 /* Apply the taint */ 8644 expr->isTainted = this->taintEngine->taintAssignment(dst, src1); 8645 8646 /* Update the symbolic control flow */ 8647 this->controlFlow_s(inst); 8648 } 8649 8650 pextrq_s(triton::arch::Instruction & inst)8651 void x86Semantics::pextrq_s(triton::arch::Instruction& inst) { 8652 auto& dst = inst.operands[0]; 8653 auto& src1 = inst.operands[1]; 8654 auto& src2 = inst.operands[2]; 8655 8656 /* Create symbolic operands */ 8657 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8658 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 8659 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 8660 8661 auto node = this->astCtxt->extract(triton::bitsize::qword - 1, 0, 8662 this->astCtxt->bvlshr( 8663 op2, 8664 this->astCtxt->bv(((op3->evaluate() & 0x1) * triton::bitsize::qword), op2->getBitvectorSize()) 8665 ) 8666 ); 8667 8668 /* Create symbolic expression */ 8669 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PEXTRQ operation"); 8670 8671 /* Apply the taint */ 8672 expr->isTainted = this->taintEngine->taintAssignment(dst, src1); 8673 8674 /* Update the symbolic control flow */ 8675 this->controlFlow_s(inst); 8676 } 8677 8678 pextrw_s(triton::arch::Instruction & inst)8679 void x86Semantics::pextrw_s(triton::arch::Instruction& inst) { 8680 triton::uint32 count = 0; 8681 auto& dst = inst.operands[0]; 8682 auto& src1 = inst.operands[1]; 8683 auto& src2 = inst.operands[2]; 8684 8685 /* 8686 * When specifying a word location in an MMX technology register, the 8687 * 2 least-significant bits of the count operand specify the location; 8688 * for an XMM register, the 3 least-significant bits specify the 8689 * location. 8690 */ 8691 if (src1.getBitSize() == triton::bitsize::qword) { 8692 count = 0x03; 8693 } 8694 else { 8695 count = 0x07; 8696 } 8697 8698 /* Create symbolic operands */ 8699 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8700 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 8701 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 8702 8703 auto node = this->astCtxt->extract(triton::bitsize::word - 1, 0, 8704 this->astCtxt->bvlshr( 8705 op2, 8706 this->astCtxt->bv(((op3->evaluate() & count) * triton::bitsize::word), op2->getBitvectorSize()) 8707 ) 8708 ); 8709 8710 /* Create symbolic expression */ 8711 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PEXTRW operation"); 8712 8713 /* Apply the taint */ 8714 expr->isTainted = this->taintEngine->taintAssignment(dst, src1); 8715 8716 /* Update the symbolic control flow */ 8717 this->controlFlow_s(inst); 8718 } 8719 8720 pinsrb_s(triton::arch::Instruction & inst)8721 void x86Semantics::pinsrb_s(triton::arch::Instruction& inst) { 8722 auto& dst = inst.operands[0]; 8723 auto& src1 = inst.operands[1]; 8724 auto& src2 = inst.operands[2]; 8725 8726 /* Create symbolic operands */ 8727 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8728 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 8729 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 8730 8731 // SEL = COUNT[3:0]; 8732 // MASK = (0FFH << (SEL * 8)); 8733 triton::uint64 sel = op3->evaluate().convert_to<triton::uint64>() & 0x0f; 8734 triton::uint128 mask = 0xff; 8735 mask = mask << (sel * 8); 8736 8737 // TEMP = ((SRC[7:0] << (SEL * 8)) AND MASK); 8738 auto temp = this->astCtxt->bvand( 8739 this->astCtxt->bvshl( 8740 this->astCtxt->zx(120, this->astCtxt->extract(7, 0, op2)), 8741 this->astCtxt->bv(sel * 8, 128) 8742 ), 8743 this->astCtxt->bv(mask, 128) 8744 ); 8745 8746 // DEST = ((DEST AND NOT MASK) OR TEMP); 8747 auto node = this->astCtxt->bvor( 8748 this->astCtxt->bvand( 8749 op1, 8750 this->astCtxt->bvnot(this->astCtxt->bv(mask, 128)) 8751 ), 8752 temp 8753 ); 8754 8755 /* Create symbolic expression */ 8756 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PINSRB operation"); 8757 8758 /* Apply the taint */ 8759 expr->isTainted = this->taintEngine->taintUnion(dst, src1); 8760 8761 /* Update the symbolic control flow */ 8762 this->controlFlow_s(inst); 8763 } 8764 8765 pinsrd_s(triton::arch::Instruction & inst)8766 void x86Semantics::pinsrd_s(triton::arch::Instruction& inst) { 8767 auto& dst = inst.operands[0]; 8768 auto& src1 = inst.operands[1]; 8769 auto& src2 = inst.operands[2]; 8770 8771 /* Create symbolic operands */ 8772 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8773 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 8774 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 8775 8776 // SEL = COUNT[1:0]; 8777 // MASK = (0FFFFFFFFH << (SEL * 32)); 8778 triton::uint64 sel = op3->evaluate().convert_to<triton::uint64>() & 0x03; 8779 triton::uint128 mask = 0xffffffff; 8780 mask = mask << (sel * 32); 8781 8782 // TEMP = ((SRC[31:0] << (SEL * 32)) AND MASK); 8783 auto temp = this->astCtxt->bvand( 8784 this->astCtxt->bvshl( 8785 this->astCtxt->zx(96, this->astCtxt->extract(31, 0, op2)), 8786 this->astCtxt->bv(sel * 32, 128) 8787 ), 8788 this->astCtxt->bv(mask, 128) 8789 ); 8790 8791 // DEST = ((DEST AND NOT MASK) OR TEMP); 8792 auto node = this->astCtxt->bvor( 8793 this->astCtxt->bvand( 8794 op1, 8795 this->astCtxt->bvnot(this->astCtxt->bv(mask, 128)) 8796 ), 8797 temp 8798 ); 8799 8800 /* Create symbolic expression */ 8801 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PINSRD operation"); 8802 8803 /* Apply the taint */ 8804 expr->isTainted = this->taintEngine->taintUnion(dst, src1); 8805 8806 /* Update the symbolic control flow */ 8807 this->controlFlow_s(inst); 8808 } 8809 8810 pinsrq_s(triton::arch::Instruction & inst)8811 void x86Semantics::pinsrq_s(triton::arch::Instruction& inst) { 8812 auto& dst = inst.operands[0]; 8813 auto& src1 = inst.operands[1]; 8814 auto& src2 = inst.operands[2]; 8815 8816 /* Create symbolic operands */ 8817 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8818 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 8819 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 8820 8821 // SEL = COUNT[0:0]; 8822 // MASK = (0FFFFFFFFFFFFFFFFH << (SEL * 64)); 8823 triton::uint64 sel = op3->evaluate().convert_to<triton::uint64>() & 0x1; 8824 triton::uint128 mask = 0xffffffffffffffff; 8825 mask = mask << (sel * 64); 8826 8827 // TEMP = ((SRC[63:0] << (SEL * 64)) AND MASK); 8828 auto temp = this->astCtxt->bvand( 8829 this->astCtxt->bvshl( 8830 this->astCtxt->zx(64, this->astCtxt->extract(63, 0, op2)), 8831 this->astCtxt->bv(sel * 64, 128) 8832 ), 8833 this->astCtxt->bv(mask, 128) 8834 ); 8835 8836 // DEST = ((DEST AND NOT MASK) OR TEMP); 8837 auto node = this->astCtxt->bvor( 8838 this->astCtxt->bvand( 8839 op1, 8840 this->astCtxt->bvnot(this->astCtxt->bv(mask, 128)) 8841 ), 8842 temp 8843 ); 8844 8845 /* Create symbolic expression */ 8846 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PINSRQ operation"); 8847 8848 /* Apply the taint */ 8849 expr->isTainted = this->taintEngine->taintUnion(dst, src1); 8850 8851 /* Update the symbolic control flow */ 8852 this->controlFlow_s(inst); 8853 } 8854 8855 pinsrw_s(triton::arch::Instruction & inst)8856 void x86Semantics::pinsrw_s(triton::arch::Instruction& inst) { 8857 triton::uint128 mask = 0xffff; 8858 triton::uint64 sel = 0; 8859 auto& dst = inst.operands[0]; 8860 auto& src1 = inst.operands[1]; 8861 auto& src2 = inst.operands[2]; 8862 8863 /* Create symbolic operands */ 8864 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8865 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 8866 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 8867 8868 /* 8869 * PINSRW (with 64-bit source operand) 8870 * 8871 * SEL = COUNT AND 3H; 8872 * CASE (Determine word position) { 8873 * if SEL == 0: MASK = 000000000000FFFFH; 8874 * if SEL == 1: MASK = 00000000FFFF0000H; 8875 * if SEL == 2: MASK = 0000FFFF00000000H; 8876 * if SEL == 3: MASK = FFFF000000000000H; 8877 * } 8878 */ 8879 if (dst.getBitSize() == triton::bitsize::qword) { 8880 sel = op3->evaluate().convert_to<triton::uint64>() & 0x3; 8881 switch (sel) { 8882 case 1: mask = mask << 16; break; 8883 case 2: mask = mask << 32; break; 8884 case 3: mask = mask << 48; break; 8885 } 8886 } 8887 8888 /* 8889 * PINSRW (with 128-bit source operand) 8890 * 8891 * SEL ← COUNT AND 7H; 8892 * CASE (Determine word position) { 8893 * SEL == 0: MASK = 0000000000000000000000000000FFFFH; 8894 * SEL == 1: MASK = 000000000000000000000000FFFF0000H; 8895 * SEL == 2: MASK = 00000000000000000000FFFF00000000H; 8896 * SEL == 3: MASK = 0000000000000000FFFF000000000000H; 8897 * SEL == 4: MASK = 000000000000FFFF0000000000000000H; 8898 * SEL == 5: MASK = 00000000FFFF00000000000000000000H; 8899 * SEL == 6: MASK = 0000FFFF000000000000000000000000H; 8900 * SEL == 7: MASK = FFFF0000000000000000000000000000H; 8901 * } 8902 */ 8903 else { 8904 sel = op3->evaluate().convert_to<triton::uint64>() & 0x7; 8905 switch (sel) { 8906 case 1: mask = mask << 16; break; 8907 case 2: mask = mask << 32; break; 8908 case 3: mask = mask << 48; break; 8909 case 4: mask = mask << 64; break; 8910 case 5: mask = mask << 80; break; 8911 case 6: mask = mask << 96; break; 8912 case 7: mask = mask << 112; break; 8913 } 8914 } 8915 8916 // TEMP = ((SRC << (SEL ∗ 16)) AND MASK); 8917 auto temp = this->astCtxt->bvand( 8918 this->astCtxt->bvshl( 8919 this->astCtxt->zx(96, this->astCtxt->extract(31, 0, op2)), 8920 this->astCtxt->bv(sel * 16, 128) 8921 ), 8922 this->astCtxt->bv(mask, 128) 8923 ); 8924 8925 // DEST = ((DEST AND NOT MASK) OR TEMP); 8926 auto node = this->astCtxt->bvor( 8927 this->astCtxt->bvand( 8928 op1, 8929 this->astCtxt->bvnot(this->astCtxt->bv(mask, 128)) 8930 ), 8931 temp 8932 ); 8933 8934 /* Create symbolic expression */ 8935 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PINSRW operation"); 8936 8937 /* Apply the taint */ 8938 expr->isTainted = this->taintEngine->taintUnion(dst, src1); 8939 8940 /* Update the symbolic control flow */ 8941 this->controlFlow_s(inst); 8942 } 8943 8944 pmaxsd_s(triton::arch::Instruction & inst)8945 void x86Semantics::pmaxsd_s(triton::arch::Instruction& inst) { 8946 auto& dst = inst.operands[0]; 8947 auto& src = inst.operands[1]; 8948 8949 /* Create symbolic operands */ 8950 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8951 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 8952 8953 /* Create the semantics */ 8954 std::vector<triton::ast::SharedAbstractNode> pck; 8955 pck.reserve(dst.getSize()); 8956 8957 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) { 8958 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword); 8959 uint32 low = (dst.getBitSize() - triton::bitsize::dword) - (index * triton::bitsize::dword); 8960 pck.push_back(this->astCtxt->ite( 8961 this->astCtxt->bvsle( 8962 this->astCtxt->extract(high, low, op1), 8963 this->astCtxt->extract(high, low, op2)), 8964 this->astCtxt->extract(high, low, op2), 8965 this->astCtxt->extract(high, low, op1)) 8966 ); 8967 } 8968 8969 auto node = this->astCtxt->concat(pck); 8970 8971 /* Create symbolic expression */ 8972 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMAXSD operation"); 8973 8974 /* Apply the taint */ 8975 expr->isTainted = this->taintEngine->taintUnion(dst, src); 8976 8977 /* Update the symbolic control flow */ 8978 this->controlFlow_s(inst); 8979 } 8980 8981 pmaxsw_s(triton::arch::Instruction & inst)8982 void x86Semantics::pmaxsw_s(triton::arch::Instruction& inst) { 8983 auto& dst = inst.operands[0]; 8984 auto& src = inst.operands[1]; 8985 8986 /* Create symbolic operands */ 8987 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 8988 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 8989 8990 /* Create the semantics */ 8991 std::vector<triton::ast::SharedAbstractNode> pck; 8992 pck.reserve(dst.getSize()); 8993 8994 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) { 8995 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word); 8996 uint32 low = (dst.getBitSize() - triton::bitsize::word) - (index * triton::bitsize::word); 8997 pck.push_back(this->astCtxt->ite( 8998 this->astCtxt->bvsle( 8999 this->astCtxt->extract(high, low, op1), 9000 this->astCtxt->extract(high, low, op2)), 9001 this->astCtxt->extract(high, low, op2), 9002 this->astCtxt->extract(high, low, op1)) 9003 ); 9004 } 9005 9006 auto node = this->astCtxt->concat(pck); 9007 9008 /* Create symbolic expression */ 9009 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMAXSW operation"); 9010 9011 /* Apply the taint */ 9012 expr->isTainted = this->taintEngine->taintUnion(dst, src); 9013 9014 /* Update the symbolic control flow */ 9015 this->controlFlow_s(inst); 9016 } 9017 9018 pmaxub_s(triton::arch::Instruction & inst)9019 void x86Semantics::pmaxub_s(triton::arch::Instruction& inst) { 9020 auto& dst = inst.operands[0]; 9021 auto& src = inst.operands[1]; 9022 9023 /* Create symbolic operands */ 9024 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 9025 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9026 9027 /* Create the semantics */ 9028 std::vector<triton::ast::SharedAbstractNode> pck; 9029 pck.reserve(dst.getSize()); 9030 9031 for (triton::uint32 index = 0; index < dst.getSize(); index++) { 9032 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte); 9033 uint32 low = (dst.getBitSize() - triton::bitsize::byte) - (index * triton::bitsize::byte); 9034 pck.push_back(this->astCtxt->ite( 9035 this->astCtxt->bvule( 9036 this->astCtxt->extract(high, low, op1), 9037 this->astCtxt->extract(high, low, op2)), 9038 this->astCtxt->extract(high, low, op2), 9039 this->astCtxt->extract(high, low, op1)) 9040 ); 9041 } 9042 9043 auto node = this->astCtxt->concat(pck); 9044 9045 /* Create symbolic expression */ 9046 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMAXUB operation"); 9047 9048 /* Apply the taint */ 9049 expr->isTainted = this->taintEngine->taintUnion(dst, src); 9050 9051 /* Update the symbolic control flow */ 9052 this->controlFlow_s(inst); 9053 } 9054 9055 pmaxud_s(triton::arch::Instruction & inst)9056 void x86Semantics::pmaxud_s(triton::arch::Instruction& inst) { 9057 auto& dst = inst.operands[0]; 9058 auto& src = inst.operands[1]; 9059 9060 /* Create symbolic operands */ 9061 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 9062 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9063 9064 /* Create the semantics */ 9065 std::vector<triton::ast::SharedAbstractNode> pck; 9066 pck.reserve(dst.getSize()); 9067 9068 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) { 9069 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword); 9070 uint32 low = (dst.getBitSize() - triton::bitsize::dword) - (index * triton::bitsize::dword); 9071 pck.push_back(this->astCtxt->ite( 9072 this->astCtxt->bvule( 9073 this->astCtxt->extract(high, low, op1), 9074 this->astCtxt->extract(high, low, op2)), 9075 this->astCtxt->extract(high, low, op2), 9076 this->astCtxt->extract(high, low, op1)) 9077 ); 9078 } 9079 9080 auto node = this->astCtxt->concat(pck); 9081 9082 /* Create symbolic expression */ 9083 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMAXUD operation"); 9084 9085 /* Apply the taint */ 9086 expr->isTainted = this->taintEngine->taintUnion(dst, src); 9087 9088 /* Update the symbolic control flow */ 9089 this->controlFlow_s(inst); 9090 } 9091 9092 pmaxuw_s(triton::arch::Instruction & inst)9093 void x86Semantics::pmaxuw_s(triton::arch::Instruction& inst) { 9094 auto& dst = inst.operands[0]; 9095 auto& src = inst.operands[1]; 9096 9097 /* Create symbolic operands */ 9098 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 9099 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9100 9101 /* Create the semantics */ 9102 std::vector<triton::ast::SharedAbstractNode> pck; 9103 pck.reserve(dst.getSize()); 9104 9105 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) { 9106 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word); 9107 uint32 low = (dst.getBitSize() - triton::bitsize::word) - (index * triton::bitsize::word); 9108 pck.push_back(this->astCtxt->ite( 9109 this->astCtxt->bvule( 9110 this->astCtxt->extract(high, low, op1), 9111 this->astCtxt->extract(high, low, op2)), 9112 this->astCtxt->extract(high, low, op2), 9113 this->astCtxt->extract(high, low, op1)) 9114 ); 9115 } 9116 9117 auto node = this->astCtxt->concat(pck); 9118 9119 /* Create symbolic expression */ 9120 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMAXUW operation"); 9121 9122 /* Apply the taint */ 9123 expr->isTainted = this->taintEngine->taintUnion(dst, src); 9124 9125 /* Update the symbolic control flow */ 9126 this->controlFlow_s(inst); 9127 } 9128 9129 pminsb_s(triton::arch::Instruction & inst)9130 void x86Semantics::pminsb_s(triton::arch::Instruction& inst) { 9131 auto& dst = inst.operands[0]; 9132 auto& src = inst.operands[1]; 9133 9134 /* Create symbolic operands */ 9135 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 9136 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9137 9138 /* Create the semantics */ 9139 std::vector<triton::ast::SharedAbstractNode> pck; 9140 pck.reserve(dst.getSize()); 9141 9142 for (triton::uint32 index = 0; index < dst.getSize(); index++) { 9143 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte); 9144 uint32 low = (dst.getBitSize() - triton::bitsize::byte) - (index * triton::bitsize::byte); 9145 pck.push_back(this->astCtxt->ite( 9146 this->astCtxt->bvsge( 9147 this->astCtxt->extract(high, low, op1), 9148 this->astCtxt->extract(high, low, op2)), 9149 this->astCtxt->extract(high, low, op2), 9150 this->astCtxt->extract(high, low, op1)) 9151 ); 9152 } 9153 9154 auto node = this->astCtxt->concat(pck); 9155 9156 /* Create symbolic expression */ 9157 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMINSB operation"); 9158 9159 /* Apply the taint */ 9160 expr->isTainted = this->taintEngine->taintUnion(dst, src); 9161 9162 /* Update the symbolic control flow */ 9163 this->controlFlow_s(inst); 9164 } 9165 9166 pminsd_s(triton::arch::Instruction & inst)9167 void x86Semantics::pminsd_s(triton::arch::Instruction& inst) { 9168 auto& dst = inst.operands[0]; 9169 auto& src = inst.operands[1]; 9170 9171 /* Create symbolic operands */ 9172 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 9173 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9174 9175 /* Create the semantics */ 9176 std::vector<triton::ast::SharedAbstractNode> pck; 9177 pck.reserve(dst.getSize()); 9178 9179 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) { 9180 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword); 9181 uint32 low = (dst.getBitSize() - triton::bitsize::dword) - (index * triton::bitsize::dword); 9182 pck.push_back(this->astCtxt->ite( 9183 this->astCtxt->bvsge( 9184 this->astCtxt->extract(high, low, op1), 9185 this->astCtxt->extract(high, low, op2)), 9186 this->astCtxt->extract(high, low, op2), 9187 this->astCtxt->extract(high, low, op1)) 9188 ); 9189 } 9190 9191 auto node = this->astCtxt->concat(pck); 9192 9193 /* Create symbolic expression */ 9194 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMINSD operation"); 9195 9196 /* Apply the taint */ 9197 expr->isTainted = this->taintEngine->taintUnion(dst, src); 9198 9199 /* Update the symbolic control flow */ 9200 this->controlFlow_s(inst); 9201 } 9202 9203 pminsw_s(triton::arch::Instruction & inst)9204 void x86Semantics::pminsw_s(triton::arch::Instruction& inst) { 9205 auto& dst = inst.operands[0]; 9206 auto& src = inst.operands[1]; 9207 9208 /* Create symbolic operands */ 9209 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 9210 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9211 9212 /* Create the semantics */ 9213 std::vector<triton::ast::SharedAbstractNode> pck; 9214 pck.reserve(dst.getSize()); 9215 9216 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) { 9217 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word); 9218 uint32 low = (dst.getBitSize() - triton::bitsize::word) - (index * triton::bitsize::word); 9219 pck.push_back(this->astCtxt->ite( 9220 this->astCtxt->bvsge( 9221 this->astCtxt->extract(high, low, op1), 9222 this->astCtxt->extract(high, low, op2)), 9223 this->astCtxt->extract(high, low, op2), 9224 this->astCtxt->extract(high, low, op1)) 9225 ); 9226 } 9227 9228 auto node = this->astCtxt->concat(pck); 9229 9230 /* Create symbolic expression */ 9231 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMINSW operation"); 9232 9233 /* Apply the taint */ 9234 expr->isTainted = this->taintEngine->taintUnion(dst, src); 9235 9236 /* Update the symbolic control flow */ 9237 this->controlFlow_s(inst); 9238 } 9239 9240 pminub_s(triton::arch::Instruction & inst)9241 void x86Semantics::pminub_s(triton::arch::Instruction& inst) { 9242 auto& dst = inst.operands[0]; 9243 auto& src = inst.operands[1]; 9244 9245 /* Create symbolic operands */ 9246 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 9247 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9248 9249 /* Create the semantics */ 9250 std::vector<triton::ast::SharedAbstractNode> pck; 9251 pck.reserve(dst.getSize()); 9252 9253 for (triton::uint32 index = 0; index < dst.getSize(); index++) { 9254 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::byte); 9255 uint32 low = (dst.getBitSize() - triton::bitsize::byte) - (index * triton::bitsize::byte); 9256 pck.push_back(this->astCtxt->ite( 9257 this->astCtxt->bvuge( 9258 this->astCtxt->extract(high, low, op1), 9259 this->astCtxt->extract(high, low, op2)), 9260 this->astCtxt->extract(high, low, op2), 9261 this->astCtxt->extract(high, low, op1)) 9262 ); 9263 } 9264 9265 auto node = this->astCtxt->concat(pck); 9266 9267 /* Create symbolic expression */ 9268 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMINUB operation"); 9269 9270 /* Apply the taint */ 9271 expr->isTainted = this->taintEngine->taintUnion(dst, src); 9272 9273 /* Update the symbolic control flow */ 9274 this->controlFlow_s(inst); 9275 } 9276 9277 pminud_s(triton::arch::Instruction & inst)9278 void x86Semantics::pminud_s(triton::arch::Instruction& inst) { 9279 auto& dst = inst.operands[0]; 9280 auto& src = inst.operands[1]; 9281 9282 /* Create symbolic operands */ 9283 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 9284 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9285 9286 /* Create the semantics */ 9287 std::vector<triton::ast::SharedAbstractNode> pck; 9288 pck.reserve(dst.getSize()); 9289 9290 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::dword; index++) { 9291 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::dword); 9292 uint32 low = (dst.getBitSize() - triton::bitsize::dword) - (index * triton::bitsize::dword); 9293 pck.push_back(this->astCtxt->ite( 9294 this->astCtxt->bvuge( 9295 this->astCtxt->extract(high, low, op1), 9296 this->astCtxt->extract(high, low, op2)), 9297 this->astCtxt->extract(high, low, op2), 9298 this->astCtxt->extract(high, low, op1)) 9299 ); 9300 } 9301 9302 auto node = this->astCtxt->concat(pck); 9303 9304 /* Create symbolic expression */ 9305 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMINUD operation"); 9306 9307 /* Apply the taint */ 9308 expr->isTainted = this->taintEngine->taintUnion(dst, src); 9309 9310 /* Update the symbolic control flow */ 9311 this->controlFlow_s(inst); 9312 } 9313 9314 pminuw_s(triton::arch::Instruction & inst)9315 void x86Semantics::pminuw_s(triton::arch::Instruction& inst) { 9316 auto& dst = inst.operands[0]; 9317 auto& src = inst.operands[1]; 9318 9319 /* Create symbolic operands */ 9320 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 9321 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9322 9323 /* Create the semantics */ 9324 std::vector<triton::ast::SharedAbstractNode> pck; 9325 pck.reserve(dst.getSize()); 9326 9327 for (triton::uint32 index = 0; index < dst.getSize() / triton::size::word; index++) { 9328 uint32 high = (dst.getBitSize() - 1) - (index * triton::bitsize::word); 9329 uint32 low = (dst.getBitSize() - triton::bitsize::word) - (index * triton::bitsize::word); 9330 pck.push_back(this->astCtxt->ite( 9331 this->astCtxt->bvuge( 9332 this->astCtxt->extract(high, low, op1), 9333 this->astCtxt->extract(high, low, op2)), 9334 this->astCtxt->extract(high, low, op2), 9335 this->astCtxt->extract(high, low, op1)) 9336 ); 9337 } 9338 9339 auto node = this->astCtxt->concat(pck); 9340 9341 /* Create symbolic expression */ 9342 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMINUW operation"); 9343 9344 /* Apply the taint */ 9345 expr->isTainted = this->taintEngine->taintUnion(dst, src); 9346 9347 /* Update the symbolic control flow */ 9348 this->controlFlow_s(inst); 9349 } 9350 9351 pmovmskb_s(triton::arch::Instruction & inst)9352 void x86Semantics::pmovmskb_s(triton::arch::Instruction& inst) { 9353 auto& dst = inst.operands[0]; 9354 auto& src = inst.operands[1]; 9355 9356 /* Create symbolic operands */ 9357 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9358 9359 /* Create the semantics */ 9360 std::vector<triton::ast::SharedAbstractNode> mskb; 9361 mskb.reserve(16); 9362 9363 switch (src.getSize()) { 9364 case triton::size::dqword: 9365 mskb.push_back(this->astCtxt->extract(127, 127, op2)); 9366 mskb.push_back(this->astCtxt->extract(119, 119, op2)); 9367 mskb.push_back(this->astCtxt->extract(111, 111, op2)); 9368 mskb.push_back(this->astCtxt->extract(103, 103, op2)); 9369 mskb.push_back(this->astCtxt->extract(95, 95, op2)); 9370 mskb.push_back(this->astCtxt->extract(87, 87, op2)); 9371 mskb.push_back(this->astCtxt->extract(79, 79, op2)); 9372 mskb.push_back(this->astCtxt->extract(71, 71, op2)); 9373 9374 case triton::size::qword: 9375 mskb.push_back(this->astCtxt->extract(63, 63, op2)); 9376 mskb.push_back(this->astCtxt->extract(55, 55, op2)); 9377 mskb.push_back(this->astCtxt->extract(47, 47, op2)); 9378 mskb.push_back(this->astCtxt->extract(39, 39, op2)); 9379 mskb.push_back(this->astCtxt->extract(31, 31, op2)); 9380 mskb.push_back(this->astCtxt->extract(23, 23, op2)); 9381 mskb.push_back(this->astCtxt->extract(15, 15, op2)); 9382 mskb.push_back(this->astCtxt->extract(7, 7, op2)); 9383 } 9384 9385 auto node = this->astCtxt->zx( 9386 dst.getBitSize() - static_cast<triton::uint32>(mskb.size()), 9387 this->astCtxt->concat(mskb) 9388 ); 9389 9390 /* Create symbolic expression */ 9391 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVMSKB operation"); 9392 9393 /* Apply the taint */ 9394 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 9395 9396 /* Update the symbolic control flow */ 9397 this->controlFlow_s(inst); 9398 } 9399 9400 pmovsxbd_s(triton::arch::Instruction & inst)9401 void x86Semantics::pmovsxbd_s(triton::arch::Instruction& inst) { 9402 auto& dst = inst.operands[0]; 9403 auto& src = inst.operands[1]; 9404 9405 /* Create symbolic operands */ 9406 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9407 9408 /* Create the semantics */ 9409 std::vector<triton::ast::SharedAbstractNode> pck; 9410 pck.reserve(4); 9411 9412 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(31, 24, op2))); 9413 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(23, 16, op2))); 9414 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2))); 9415 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2))); 9416 9417 auto node = this->astCtxt->concat(pck); 9418 9419 /* Create symbolic expression */ 9420 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVSXBD operation"); 9421 9422 /* Apply the taint */ 9423 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 9424 9425 /* Update the symbolic control flow */ 9426 this->controlFlow_s(inst); 9427 } 9428 9429 pmovsxbq_s(triton::arch::Instruction & inst)9430 void x86Semantics::pmovsxbq_s(triton::arch::Instruction& inst) { 9431 auto& dst = inst.operands[0]; 9432 auto& src = inst.operands[1]; 9433 9434 /* Create symbolic operands */ 9435 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9436 9437 /* Create the semantics */ 9438 std::vector<triton::ast::SharedAbstractNode> pck; 9439 pck.reserve(2); 9440 9441 pck.push_back(this->astCtxt->sx(triton::bitsize::qword - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2))); 9442 pck.push_back(this->astCtxt->sx(triton::bitsize::qword - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2))); 9443 9444 auto node = this->astCtxt->concat(pck); 9445 9446 /* Create symbolic expression */ 9447 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVSXBQ operation"); 9448 9449 /* Apply the taint */ 9450 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 9451 9452 /* Update the symbolic control flow */ 9453 this->controlFlow_s(inst); 9454 } 9455 9456 pmovsxbw_s(triton::arch::Instruction & inst)9457 void x86Semantics::pmovsxbw_s(triton::arch::Instruction& inst) { 9458 auto& dst = inst.operands[0]; 9459 auto& src = inst.operands[1]; 9460 9461 /* Create symbolic operands */ 9462 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9463 9464 /* Create the semantics */ 9465 std::vector<triton::ast::SharedAbstractNode> pck; 9466 pck.reserve(8); 9467 9468 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(63, 56, op2))); 9469 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(55, 48, op2))); 9470 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(47, 40, op2))); 9471 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(39, 32, op2))); 9472 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(31, 24, op2))); 9473 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(23, 16, op2))); 9474 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2))); 9475 pck.push_back(this->astCtxt->sx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2))); 9476 9477 auto node = this->astCtxt->concat(pck); 9478 9479 /* Create symbolic expression */ 9480 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVSXBW operation"); 9481 9482 /* Apply the taint */ 9483 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 9484 9485 /* Update the symbolic control flow */ 9486 this->controlFlow_s(inst); 9487 } 9488 9489 pmovsxdq_s(triton::arch::Instruction & inst)9490 void x86Semantics::pmovsxdq_s(triton::arch::Instruction& inst) { 9491 auto& dst = inst.operands[0]; 9492 auto& src = inst.operands[1]; 9493 9494 /* Create symbolic operands */ 9495 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9496 9497 /* Create the semantics */ 9498 std::vector<triton::ast::SharedAbstractNode> pck; 9499 pck.reserve(2); 9500 9501 pck.push_back(this->astCtxt->sx(triton::bitsize::qword - triton::bitsize::dword, this->astCtxt->extract(63, 32, op2))); 9502 pck.push_back(this->astCtxt->sx(triton::bitsize::qword - triton::bitsize::dword, this->astCtxt->extract(31, 0, op2))); 9503 9504 auto node = this->astCtxt->concat(pck); 9505 9506 /* Create symbolic expression */ 9507 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVSXDQ operation"); 9508 9509 /* Apply the taint */ 9510 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 9511 9512 /* Update the symbolic control flow */ 9513 this->controlFlow_s(inst); 9514 } 9515 9516 pmovsxwd_s(triton::arch::Instruction & inst)9517 void x86Semantics::pmovsxwd_s(triton::arch::Instruction& inst) { 9518 auto& dst = inst.operands[0]; 9519 auto& src = inst.operands[1]; 9520 9521 /* Create symbolic operands */ 9522 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9523 9524 /* Create the semantics */ 9525 std::vector<triton::ast::SharedAbstractNode> pck; 9526 pck.reserve(4); 9527 9528 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(63, 48, op2))); 9529 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(47, 32, op2))); 9530 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(31, 16, op2))); 9531 pck.push_back(this->astCtxt->sx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(15, 0, op2))); 9532 9533 auto node = this->astCtxt->concat(pck); 9534 9535 /* Create symbolic expression */ 9536 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVSXWD operation"); 9537 9538 /* Apply the taint */ 9539 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 9540 9541 /* Update the symbolic control flow */ 9542 this->controlFlow_s(inst); 9543 } 9544 9545 pmovsxwq_s(triton::arch::Instruction & inst)9546 void x86Semantics::pmovsxwq_s(triton::arch::Instruction& inst) { 9547 auto& dst = inst.operands[0]; 9548 auto& src = inst.operands[1]; 9549 9550 /* Create symbolic operands */ 9551 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9552 9553 /* Create the semantics */ 9554 std::vector<triton::ast::SharedAbstractNode> pck; 9555 pck.reserve(2); 9556 9557 pck.push_back(this->astCtxt->sx(triton::bitsize::qword - triton::bitsize::word, this->astCtxt->extract(31, 16, op2))); 9558 pck.push_back(this->astCtxt->sx(triton::bitsize::qword - triton::bitsize::word, this->astCtxt->extract(15, 0, op2))); 9559 9560 auto node = this->astCtxt->concat(pck); 9561 9562 /* Create symbolic expression */ 9563 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVSXWQ operation"); 9564 9565 /* Apply the taint */ 9566 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 9567 9568 /* Update the symbolic control flow */ 9569 this->controlFlow_s(inst); 9570 } 9571 9572 pmovzxbd_s(triton::arch::Instruction & inst)9573 void x86Semantics::pmovzxbd_s(triton::arch::Instruction& inst) { 9574 auto& dst = inst.operands[0]; 9575 auto& src = inst.operands[1]; 9576 9577 /* Create symbolic operands */ 9578 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9579 9580 /* Create the semantics */ 9581 std::vector<triton::ast::SharedAbstractNode> pck; 9582 pck.reserve(4); 9583 9584 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(31, 24, op2))); 9585 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(23, 16, op2))); 9586 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2))); 9587 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2))); 9588 9589 auto node = this->astCtxt->concat(pck); 9590 9591 /* Create symbolic expression */ 9592 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVZXBD operation"); 9593 9594 /* Apply the taint */ 9595 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 9596 9597 /* Update the symbolic control flow */ 9598 this->controlFlow_s(inst); 9599 } 9600 9601 pmovzxbq_s(triton::arch::Instruction & inst)9602 void x86Semantics::pmovzxbq_s(triton::arch::Instruction& inst) { 9603 auto& dst = inst.operands[0]; 9604 auto& src = inst.operands[1]; 9605 9606 /* Create symbolic operands */ 9607 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9608 9609 /* Create the semantics */ 9610 std::vector<triton::ast::SharedAbstractNode> pck; 9611 pck.reserve(2); 9612 9613 pck.push_back(this->astCtxt->zx(triton::bitsize::qword - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2))); 9614 pck.push_back(this->astCtxt->zx(triton::bitsize::qword - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2))); 9615 9616 auto node = this->astCtxt->concat(pck); 9617 9618 /* Create symbolic expression */ 9619 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVZXBQ operation"); 9620 9621 /* Apply the taint */ 9622 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 9623 9624 /* Update the symbolic control flow */ 9625 this->controlFlow_s(inst); 9626 } 9627 9628 pmovzxbw_s(triton::arch::Instruction & inst)9629 void x86Semantics::pmovzxbw_s(triton::arch::Instruction& inst) { 9630 auto& dst = inst.operands[0]; 9631 auto& src = inst.operands[1]; 9632 9633 /* Create symbolic operands */ 9634 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9635 9636 /* Create the semantics */ 9637 std::vector<triton::ast::SharedAbstractNode> pck; 9638 pck.reserve(8); 9639 9640 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(63, 56, op2))); 9641 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(55, 48, op2))); 9642 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(47, 40, op2))); 9643 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(39, 32, op2))); 9644 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(31, 24, op2))); 9645 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(23, 16, op2))); 9646 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(15, 8, op2))); 9647 pck.push_back(this->astCtxt->zx(triton::bitsize::word - triton::bitsize::byte, this->astCtxt->extract(7, 0, op2))); 9648 9649 auto node = this->astCtxt->concat(pck); 9650 9651 /* Create symbolic expression */ 9652 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVZXBW operation"); 9653 9654 /* Apply the taint */ 9655 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 9656 9657 /* Update the symbolic control flow */ 9658 this->controlFlow_s(inst); 9659 } 9660 9661 pmovzxdq_s(triton::arch::Instruction & inst)9662 void x86Semantics::pmovzxdq_s(triton::arch::Instruction& inst) { 9663 auto& dst = inst.operands[0]; 9664 auto& src = inst.operands[1]; 9665 9666 /* Create symbolic operands */ 9667 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9668 9669 /* Create the semantics */ 9670 std::vector<triton::ast::SharedAbstractNode> pck; 9671 pck.reserve(2); 9672 9673 pck.push_back(this->astCtxt->zx(triton::bitsize::qword - triton::bitsize::dword, this->astCtxt->extract(63, 32, op2))); 9674 pck.push_back(this->astCtxt->zx(triton::bitsize::qword - triton::bitsize::dword, this->astCtxt->extract(31, 0, op2))); 9675 9676 auto node = this->astCtxt->concat(pck); 9677 9678 /* Create symbolic expression */ 9679 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVZXDQ operation"); 9680 9681 /* Apply the taint */ 9682 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 9683 9684 /* Update the symbolic control flow */ 9685 this->controlFlow_s(inst); 9686 } 9687 9688 pmovzxwd_s(triton::arch::Instruction & inst)9689 void x86Semantics::pmovzxwd_s(triton::arch::Instruction& inst) { 9690 auto& dst = inst.operands[0]; 9691 auto& src = inst.operands[1]; 9692 9693 /* Create symbolic operands */ 9694 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9695 9696 /* Create the semantics */ 9697 std::vector<triton::ast::SharedAbstractNode> pck; 9698 pck.reserve(4); 9699 9700 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(63, 48, op2))); 9701 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(47, 32, op2))); 9702 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(31, 16, op2))); 9703 pck.push_back(this->astCtxt->zx(triton::bitsize::dword - triton::bitsize::word, this->astCtxt->extract(15, 0, op2))); 9704 9705 auto node = this->astCtxt->concat(pck); 9706 9707 /* Create symbolic expression */ 9708 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVZXWD operation"); 9709 9710 /* Apply the taint */ 9711 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 9712 9713 /* Update the symbolic control flow */ 9714 this->controlFlow_s(inst); 9715 } 9716 9717 pmovzxwq_s(triton::arch::Instruction & inst)9718 void x86Semantics::pmovzxwq_s(triton::arch::Instruction& inst) { 9719 auto& dst = inst.operands[0]; 9720 auto& src = inst.operands[1]; 9721 9722 /* Create symbolic operands */ 9723 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 9724 9725 /* Create the semantics */ 9726 std::vector<triton::ast::SharedAbstractNode> pck; 9727 pck.reserve(2); 9728 9729 pck.push_back(this->astCtxt->zx(triton::bitsize::qword - triton::bitsize::word, this->astCtxt->extract(31, 16, op2))); 9730 pck.push_back(this->astCtxt->zx(triton::bitsize::qword - triton::bitsize::word, this->astCtxt->extract(15, 0, op2))); 9731 9732 auto node = this->astCtxt->concat(pck); 9733 9734 /* Create symbolic expression */ 9735 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PMOVZXWQ operation"); 9736 9737 /* Apply the taint */ 9738 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 9739 9740 /* Update the symbolic control flow */ 9741 this->controlFlow_s(inst); 9742 } 9743 9744 pop_s(triton::arch::Instruction & inst)9745 void x86Semantics::pop_s(triton::arch::Instruction& inst) { 9746 bool stackRelative = false; 9747 auto stack = this->architecture->getStackPointer(); 9748 auto stackValue = this->architecture->getConcreteRegisterValue(stack).convert_to<triton::uint64>(); 9749 auto& dst = inst.operands[0]; 9750 auto src = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, dst.getSize())); 9751 9752 /* Create symbolic operands */ 9753 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 9754 9755 /* Create the semantics */ 9756 auto node = op1; 9757 9758 /* 9759 * Create the semantics - side effect 9760 * 9761 * Intel: If the ESP register is used as a base register for addressing a destination operand in 9762 * memory, the POP instruction computes the effective address of the operand after it increments 9763 * the ESP register. 9764 */ 9765 if (dst.getType() == triton::arch::OP_MEM) { 9766 if (this->architecture->getParentRegister(dst.getMemory().getBaseRegister()) == stack) { 9767 /* Align the stack */ 9768 alignAddStack_s(inst, src.getSize()); 9769 9770 /* Re-initialize the memory access */ 9771 this->symbolicEngine->initLeaAst(dst.getMemory()); 9772 9773 stackRelative = true; 9774 } 9775 } 9776 9777 /* 9778 * Create the semantics - side effect 9779 * 9780 * Don't increment SP if the destination register is SP. 9781 */ 9782 else if (dst.getType() == triton::arch::OP_REG) { 9783 if (this->architecture->getParentRegister(dst.getRegister()) == stack) { 9784 stackRelative = true; 9785 } 9786 } 9787 9788 /* Create symbolic expression */ 9789 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "POP operation"); 9790 9791 /* Spread taint */ 9792 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 9793 9794 /* Create the semantics - side effect */ 9795 if (!stackRelative) 9796 alignAddStack_s(inst, src.getSize()); 9797 9798 /* Update the symbolic control flow */ 9799 this->controlFlow_s(inst); 9800 } 9801 9802 popal_s(triton::arch::Instruction & inst)9803 void x86Semantics::popal_s(triton::arch::Instruction& inst) { 9804 auto stack = this->architecture->getStackPointer(); 9805 auto stackValue = this->architecture->getConcreteRegisterValue(stack).convert_to<triton::uint64>(); 9806 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDI)); 9807 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ESI)); 9808 auto dst3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EBP)); 9809 auto dst4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EBX)); 9810 auto dst5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX)); 9811 auto dst6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ECX)); 9812 auto dst7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX)); 9813 auto src1 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 0), stack.getSize())); 9814 auto src2 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 1), stack.getSize())); 9815 auto src3 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 2), stack.getSize())); 9816 /* stack.getSize() * 3 (ESP) is voluntarily omitted */ 9817 auto src4 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 4), stack.getSize())); 9818 auto src5 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 5), stack.getSize())); 9819 auto src6 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 6), stack.getSize())); 9820 auto src7 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue+(stack.getSize() * 7), stack.getSize())); 9821 9822 /* Create symbolic operands and semantics */ 9823 auto node1 = this->symbolicEngine->getOperandAst(inst, src1); 9824 auto node2 = this->symbolicEngine->getOperandAst(inst, src2); 9825 auto node3 = this->symbolicEngine->getOperandAst(inst, src3); 9826 auto node4 = this->symbolicEngine->getOperandAst(inst, src4); 9827 auto node5 = this->symbolicEngine->getOperandAst(inst, src5); 9828 auto node6 = this->symbolicEngine->getOperandAst(inst, src6); 9829 auto node7 = this->symbolicEngine->getOperandAst(inst, src7); 9830 9831 /* Create symbolic expression */ 9832 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1, "POPAL EDI operation"); 9833 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "POPAL ESI operation"); 9834 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3, "POPAL EBP operation"); 9835 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4, "POPAL EBX operation"); 9836 auto expr5 = this->symbolicEngine->createSymbolicExpression(inst, node5, dst5, "POPAL EDX operation"); 9837 auto expr6 = this->symbolicEngine->createSymbolicExpression(inst, node6, dst6, "POPAL ECX operation"); 9838 auto expr7 = this->symbolicEngine->createSymbolicExpression(inst, node7, dst7, "POPAL EAX operation"); 9839 9840 /* Spread taint */ 9841 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src1); 9842 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src2); 9843 expr3->isTainted = this->taintEngine->taintAssignment(dst3, src3); 9844 expr4->isTainted = this->taintEngine->taintAssignment(dst4, src4); 9845 expr5->isTainted = this->taintEngine->taintAssignment(dst5, src5); 9846 expr6->isTainted = this->taintEngine->taintAssignment(dst6, src6); 9847 expr7->isTainted = this->taintEngine->taintAssignment(dst7, src7); 9848 9849 /* Create the semantics - side effect */ 9850 alignAddStack_s(inst, stack.getSize() * 8); 9851 9852 /* Update the symbolic control flow */ 9853 this->controlFlow_s(inst); 9854 } 9855 9856 popf_s(triton::arch::Instruction & inst)9857 void x86Semantics::popf_s(triton::arch::Instruction& inst) { 9858 auto stack = this->architecture->getStackPointer(); 9859 auto stackValue = this->architecture->getConcreteRegisterValue(stack).convert_to<triton::uint64>(); 9860 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 9861 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF)); 9862 auto dst3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF)); 9863 auto dst4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 9864 auto dst5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 9865 auto dst6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_TF)); 9866 auto dst7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_IF)); 9867 auto dst8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 9868 auto dst9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 9869 auto dst10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_NT)); 9870 auto src = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize())); 9871 9872 /* Create symbolic operands */ 9873 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 9874 9875 /* Create the semantics */ 9876 auto node1 = this->astCtxt->extract(0, 0, op1); 9877 auto node2 = this->astCtxt->extract(2, 2, op1); 9878 auto node3 = this->astCtxt->extract(4, 4, op1); 9879 auto node4 = this->astCtxt->extract(6, 6, op1); 9880 auto node5 = this->astCtxt->extract(7, 7, op1); 9881 auto node6 = this->astCtxt->extract(8, 8, op1); 9882 auto node7 = this->astCtxt->bvtrue(); /* IF true? */ 9883 auto node8 = this->astCtxt->extract(10, 10, op1); 9884 auto node9 = this->astCtxt->extract(11, 11, op1); 9885 /* IOPL don't support */ 9886 auto node10 = this->astCtxt->extract(14, 14, op1); 9887 9888 /* Create symbolic expression */ 9889 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1.getRegister(), "POPF CF operation"); 9890 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2.getRegister(), "POPF PF operation"); 9891 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3.getRegister(), "POPF AF operation"); 9892 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4.getRegister(), "POPF ZF operation"); 9893 auto expr5 = this->symbolicEngine->createSymbolicExpression(inst, node5, dst5.getRegister(), "POPF SF operation"); 9894 auto expr6 = this->symbolicEngine->createSymbolicExpression(inst, node6, dst6.getRegister(), "POPF TF operation"); 9895 auto expr7 = this->symbolicEngine->createSymbolicExpression(inst, node7, dst7.getRegister(), "POPF IF operation"); 9896 auto expr8 = this->symbolicEngine->createSymbolicExpression(inst, node8, dst8.getRegister(), "POPF DF operation"); 9897 auto expr9 = this->symbolicEngine->createSymbolicExpression(inst, node9, dst9.getRegister(), "POPF OF operation"); 9898 auto expr10 = this->symbolicEngine->createSymbolicExpression(inst, node10, dst10.getRegister(), "POPF NT operation"); 9899 9900 /* Spread taint */ 9901 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src); 9902 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src); 9903 expr3->isTainted = this->taintEngine->taintAssignment(dst3, src); 9904 expr4->isTainted = this->taintEngine->taintAssignment(dst4, src); 9905 expr5->isTainted = this->taintEngine->taintAssignment(dst5, src); 9906 expr6->isTainted = this->taintEngine->taintAssignment(dst6, src); 9907 expr7->isTainted = this->taintEngine->taintAssignment(dst7, src); 9908 expr8->isTainted = this->taintEngine->taintAssignment(dst8, src); 9909 expr9->isTainted = this->taintEngine->taintAssignment(dst9, src); 9910 expr10->isTainted = this->taintEngine->taintAssignment(dst10, src); 9911 9912 /* Create the semantics - side effect */ 9913 alignAddStack_s(inst, src.getSize()); 9914 9915 /* Update the symbolic control flow */ 9916 this->controlFlow_s(inst); 9917 } 9918 9919 popfd_s(triton::arch::Instruction & inst)9920 void x86Semantics::popfd_s(triton::arch::Instruction& inst) { 9921 auto stack = this->architecture->getStackPointer(); 9922 auto stackValue = this->architecture->getConcreteRegisterValue(stack).convert_to<triton::uint64>(); 9923 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 9924 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF)); 9925 auto dst3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF)); 9926 auto dst4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 9927 auto dst5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 9928 auto dst6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_TF)); 9929 auto dst7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_IF)); 9930 auto dst8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 9931 auto dst9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 9932 auto dst10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_NT)); 9933 auto dst11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RF)); 9934 auto dst12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AC)); 9935 auto dst13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ID)); 9936 auto src = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize())); 9937 9938 /* Create symbolic operands */ 9939 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 9940 9941 /* Create the semantics */ 9942 auto node1 = this->astCtxt->extract(0, 0, op1); 9943 auto node2 = this->astCtxt->extract(2, 2, op1); 9944 auto node3 = this->astCtxt->extract(4, 4, op1); 9945 auto node4 = this->astCtxt->extract(6, 6, op1); 9946 auto node5 = this->astCtxt->extract(7, 7, op1); 9947 auto node6 = this->astCtxt->extract(8, 8, op1); 9948 auto node7 = this->astCtxt->bvtrue(); /* IF true? */ 9949 auto node8 = this->astCtxt->extract(10, 10, op1); 9950 auto node9 = this->astCtxt->extract(11, 11, op1); 9951 /* IOPL don't support */ 9952 auto node10 = this->astCtxt->extract(14, 14, op1); 9953 auto node11 = this->astCtxt->bvfalse(); /* RF clear */ 9954 /* VM not changed */ 9955 auto node12 = this->astCtxt->extract(18, 18, op1); 9956 /* VIP not changed */ 9957 /* VIF not changed */ 9958 auto node13 = this->astCtxt->extract(21, 21, op1); 9959 9960 /* Create symbolic expression */ 9961 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1.getRegister(), "POPFD CF operation"); 9962 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2.getRegister(), "POPFD PF operation"); 9963 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3.getRegister(), "POPFD AF operation"); 9964 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4.getRegister(), "POPFD ZF operation"); 9965 auto expr5 = this->symbolicEngine->createSymbolicExpression(inst, node5, dst5.getRegister(), "POPFD SF operation"); 9966 auto expr6 = this->symbolicEngine->createSymbolicExpression(inst, node6, dst6.getRegister(), "POPFD TF operation"); 9967 auto expr7 = this->symbolicEngine->createSymbolicExpression(inst, node7, dst7.getRegister(), "POPFD IF operation"); 9968 auto expr8 = this->symbolicEngine->createSymbolicExpression(inst, node8, dst8.getRegister(), "POPFD DF operation"); 9969 auto expr9 = this->symbolicEngine->createSymbolicExpression(inst, node9, dst9.getRegister(), "POPFD OF operation"); 9970 auto expr10 = this->symbolicEngine->createSymbolicExpression(inst, node10, dst10.getRegister(), "POPFD NT operation"); 9971 auto expr11 = this->symbolicEngine->createSymbolicExpression(inst, node11, dst11.getRegister(), "POPFD RF operation"); 9972 auto expr12 = this->symbolicEngine->createSymbolicExpression(inst, node12, dst12.getRegister(), "POPFD AC operation"); 9973 auto expr13 = this->symbolicEngine->createSymbolicExpression(inst, node13, dst13.getRegister(), "POPFD ID operation"); 9974 9975 /* Spread taint */ 9976 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src); 9977 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src); 9978 expr3->isTainted = this->taintEngine->taintAssignment(dst3, src); 9979 expr4->isTainted = this->taintEngine->taintAssignment(dst4, src); 9980 expr5->isTainted = this->taintEngine->taintAssignment(dst5, src); 9981 expr6->isTainted = this->taintEngine->taintAssignment(dst6, src); 9982 expr7->isTainted = this->taintEngine->taintAssignment(dst7, src); 9983 expr8->isTainted = this->taintEngine->taintAssignment(dst8, src); 9984 expr9->isTainted = this->taintEngine->taintAssignment(dst9, src); 9985 expr10->isTainted = this->taintEngine->taintAssignment(dst10, src); 9986 expr11->isTainted = this->taintEngine->taintAssignment(dst11, src); 9987 expr12->isTainted = this->taintEngine->taintAssignment(dst12, src); 9988 expr13->isTainted = this->taintEngine->taintAssignment(dst13, src); 9989 9990 /* Create the semantics - side effect */ 9991 alignAddStack_s(inst, src.getSize()); 9992 9993 /* Update the symbolic control flow */ 9994 this->controlFlow_s(inst); 9995 } 9996 9997 popfq_s(triton::arch::Instruction & inst)9998 void x86Semantics::popfq_s(triton::arch::Instruction& inst) { 9999 auto stack = this->architecture->getStackPointer(); 10000 auto stackValue = this->architecture->getConcreteRegisterValue(stack).convert_to<triton::uint64>(); 10001 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 10002 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF)); 10003 auto dst3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF)); 10004 auto dst4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 10005 auto dst5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 10006 auto dst6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_TF)); 10007 auto dst7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_IF)); 10008 auto dst8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 10009 auto dst9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 10010 auto dst10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_NT)); 10011 auto dst11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RF)); 10012 auto dst12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AC)); 10013 auto dst13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ID)); 10014 auto src = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize())); 10015 10016 /* Create symbolic operands */ 10017 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 10018 10019 /* Create the semantics */ 10020 auto node1 = this->astCtxt->extract(0, 0, op1); 10021 auto node2 = this->astCtxt->extract(2, 2, op1); 10022 auto node3 = this->astCtxt->extract(4, 4, op1); 10023 auto node4 = this->astCtxt->extract(6, 6, op1); 10024 auto node5 = this->astCtxt->extract(7, 7, op1); 10025 auto node6 = this->astCtxt->extract(8, 8, op1); 10026 auto node7 = this->astCtxt->bvtrue(); /* IF true? */ 10027 auto node8 = this->astCtxt->extract(10, 10, op1); 10028 auto node9 = this->astCtxt->extract(11, 11, op1); 10029 /* IOPL don't support */ 10030 auto node10 = this->astCtxt->extract(14, 14, op1); 10031 auto node11 = this->astCtxt->bvfalse(); /* RF clear */ 10032 /* VM not changed */ 10033 auto node12 = this->astCtxt->extract(18, 18, op1); 10034 /* VIP not changed */ 10035 /* VIF not changed */ 10036 auto node13 = this->astCtxt->extract(21, 21, op1); 10037 10038 /* Create symbolic expression */ 10039 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1.getRegister(), "POPFQ CF operation"); 10040 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2.getRegister(), "POPFQ PF operation"); 10041 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3.getRegister(), "POPFQ AF operation"); 10042 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4.getRegister(), "POPFQ ZF operation"); 10043 auto expr5 = this->symbolicEngine->createSymbolicExpression(inst, node5, dst5.getRegister(), "POPFQ SF operation"); 10044 auto expr6 = this->symbolicEngine->createSymbolicExpression(inst, node6, dst6.getRegister(), "POPFQ TF operation"); 10045 auto expr7 = this->symbolicEngine->createSymbolicExpression(inst, node7, dst7.getRegister(), "POPFQ IF operation"); 10046 auto expr8 = this->symbolicEngine->createSymbolicExpression(inst, node8, dst8.getRegister(), "POPFQ DF operation"); 10047 auto expr9 = this->symbolicEngine->createSymbolicExpression(inst, node9, dst9.getRegister(), "POPFQ OF operation"); 10048 auto expr10 = this->symbolicEngine->createSymbolicExpression(inst, node10, dst10.getRegister(), "POPFD NT operation"); 10049 auto expr11 = this->symbolicEngine->createSymbolicExpression(inst, node11, dst11.getRegister(), "POPFD RF operation"); 10050 auto expr12 = this->symbolicEngine->createSymbolicExpression(inst, node12, dst12.getRegister(), "POPFD AC operation"); 10051 auto expr13 = this->symbolicEngine->createSymbolicExpression(inst, node13, dst13.getRegister(), "POPFD ID operation"); 10052 10053 /* Spread taint */ 10054 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src); 10055 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src); 10056 expr3->isTainted = this->taintEngine->taintAssignment(dst3, src); 10057 expr4->isTainted = this->taintEngine->taintAssignment(dst4, src); 10058 expr5->isTainted = this->taintEngine->taintAssignment(dst5, src); 10059 expr6->isTainted = this->taintEngine->taintAssignment(dst6, src); 10060 expr7->isTainted = this->taintEngine->taintAssignment(dst7, src); 10061 expr8->isTainted = this->taintEngine->taintAssignment(dst8, src); 10062 expr9->isTainted = this->taintEngine->taintAssignment(dst9, src); 10063 expr10->isTainted = this->taintEngine->taintAssignment(dst10, src); 10064 expr11->isTainted = this->taintEngine->taintAssignment(dst11, src); 10065 expr12->isTainted = this->taintEngine->taintAssignment(dst12, src); 10066 expr13->isTainted = this->taintEngine->taintAssignment(dst13, src); 10067 10068 /* Create the semantics - side effect */ 10069 alignAddStack_s(inst, src.getSize()); 10070 10071 /* Update the symbolic control flow */ 10072 this->controlFlow_s(inst); 10073 } 10074 10075 por_s(triton::arch::Instruction & inst)10076 void x86Semantics::por_s(triton::arch::Instruction& inst) { 10077 auto& dst = inst.operands[0]; 10078 auto& src = inst.operands[1]; 10079 10080 /* Create symbolic operands */ 10081 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 10082 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 10083 10084 /* Create the semantics */ 10085 auto node = this->astCtxt->bvor(op1, op2); 10086 10087 /* Create symbolic expression */ 10088 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "POR operation"); 10089 10090 /* Spread taint */ 10091 expr->isTainted = this->taintEngine->taintUnion(dst, src); 10092 10093 /* Update the symbolic control flow */ 10094 this->controlFlow_s(inst); 10095 } 10096 10097 prefetchx_s(triton::arch::Instruction & inst)10098 void x86Semantics::prefetchx_s(triton::arch::Instruction& inst) { 10099 auto& src = inst.operands[0]; 10100 10101 /* Only specify that the instruction performs an implicit memory read */ 10102 this->symbolicEngine->getOperandAst(inst, src); 10103 10104 /* Update the symbolic control flow */ 10105 this->controlFlow_s(inst); 10106 } 10107 10108 pshufd_s(triton::arch::Instruction & inst)10109 void x86Semantics::pshufd_s(triton::arch::Instruction& inst) { 10110 auto& dst = inst.operands[0]; 10111 auto& src = inst.operands[1]; 10112 auto& ord = inst.operands[2]; 10113 10114 /* Create symbolic operands */ 10115 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 10116 auto op3 = this->symbolicEngine->getOperandAst(inst, ord); 10117 10118 /* Create the semantics */ 10119 std::vector<triton::ast::SharedAbstractNode> pack; 10120 pack.reserve(4); 10121 10122 pack.push_back( 10123 this->astCtxt->extract(31, 0, 10124 this->astCtxt->bvlshr( 10125 op2, 10126 this->astCtxt->bvmul( 10127 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(7, 6, op3)), 10128 this->astCtxt->bv(32, triton::bitsize::dqword) 10129 ) 10130 ) 10131 ) 10132 ); 10133 pack.push_back( 10134 this->astCtxt->extract(31, 0, 10135 this->astCtxt->bvlshr( 10136 op2, 10137 this->astCtxt->bvmul( 10138 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(5, 4, op3)), 10139 this->astCtxt->bv(32, triton::bitsize::dqword) 10140 ) 10141 ) 10142 ) 10143 ); 10144 pack.push_back( 10145 this->astCtxt->extract(31, 0, 10146 this->astCtxt->bvlshr( 10147 op2, 10148 this->astCtxt->bvmul( 10149 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(3, 2, op3)), 10150 this->astCtxt->bv(32, triton::bitsize::dqword) 10151 ) 10152 ) 10153 ) 10154 ); 10155 pack.push_back( 10156 this->astCtxt->extract(31, 0, 10157 this->astCtxt->bvlshr( 10158 op2, 10159 this->astCtxt->bvmul( 10160 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(1, 0, op3)), 10161 this->astCtxt->bv(32, triton::bitsize::dqword) 10162 ) 10163 ) 10164 ) 10165 ); 10166 10167 auto node = this->astCtxt->concat(pack); 10168 10169 /* Create symbolic expression */ 10170 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSHUFD operation"); 10171 10172 /* Spread taint */ 10173 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 10174 10175 /* Update the symbolic control flow */ 10176 this->controlFlow_s(inst); 10177 } 10178 10179 pshufhw_s(triton::arch::Instruction & inst)10180 void x86Semantics::pshufhw_s(triton::arch::Instruction& inst) { 10181 auto& dst = inst.operands[0]; 10182 auto& src = inst.operands[1]; 10183 auto& ord = inst.operands[2]; 10184 10185 /* Create symbolic operands */ 10186 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 10187 auto op3 = this->symbolicEngine->getOperandAst(inst, ord); 10188 10189 /* Create the semantics */ 10190 std::vector<triton::ast::SharedAbstractNode> pack; 10191 pack.reserve(5); 10192 10193 pack.push_back( 10194 this->astCtxt->extract(79, 64, 10195 this->astCtxt->bvlshr( 10196 op2, 10197 this->astCtxt->bvmul( 10198 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(7, 6, op3)), 10199 this->astCtxt->bv(16, triton::bitsize::dqword) 10200 ) 10201 ) 10202 ) 10203 ); 10204 pack.push_back( 10205 this->astCtxt->extract(79, 64, 10206 this->astCtxt->bvlshr( 10207 op2, 10208 this->astCtxt->bvmul( 10209 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(5, 4, op3)), 10210 this->astCtxt->bv(16, triton::bitsize::dqword) 10211 ) 10212 ) 10213 ) 10214 ); 10215 pack.push_back( 10216 this->astCtxt->extract(79, 64, 10217 this->astCtxt->bvlshr( 10218 op2, 10219 this->astCtxt->bvmul( 10220 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(3, 2, op3)), 10221 this->astCtxt->bv(16, triton::bitsize::dqword) 10222 ) 10223 ) 10224 ) 10225 ); 10226 pack.push_back( 10227 this->astCtxt->extract(79, 64, 10228 this->astCtxt->bvlshr( 10229 op2, 10230 this->astCtxt->bvmul( 10231 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(1, 0, op3)), 10232 this->astCtxt->bv(16, triton::bitsize::dqword) 10233 ) 10234 ) 10235 ) 10236 ); 10237 pack.push_back( 10238 this->astCtxt->extract(63, 0, op2) 10239 ); 10240 10241 auto node = this->astCtxt->concat(pack); 10242 10243 /* Create symbolic expression */ 10244 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSHUFHW operation"); 10245 10246 /* Spread taint */ 10247 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 10248 10249 /* Update the symbolic control flow */ 10250 this->controlFlow_s(inst); 10251 } 10252 10253 pshuflw_s(triton::arch::Instruction & inst)10254 void x86Semantics::pshuflw_s(triton::arch::Instruction& inst) { 10255 auto& dst = inst.operands[0]; 10256 auto& src = inst.operands[1]; 10257 auto& ord = inst.operands[2]; 10258 10259 /* Create symbolic operands */ 10260 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 10261 auto op3 = this->symbolicEngine->getOperandAst(inst, ord); 10262 10263 /* Create the semantics */ 10264 std::vector<triton::ast::SharedAbstractNode> pack; 10265 pack.reserve(5); 10266 10267 pack.push_back( 10268 this->astCtxt->extract(127, 64, op2) 10269 ); 10270 pack.push_back( 10271 this->astCtxt->extract(15, 0, 10272 this->astCtxt->bvlshr( 10273 op2, 10274 this->astCtxt->bvmul( 10275 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(7, 6, op3)), 10276 this->astCtxt->bv(16, triton::bitsize::dqword) 10277 ) 10278 ) 10279 ) 10280 ); 10281 pack.push_back( 10282 this->astCtxt->extract(15, 0, 10283 this->astCtxt->bvlshr( 10284 op2, 10285 this->astCtxt->bvmul( 10286 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(5, 4, op3)), 10287 this->astCtxt->bv(16, triton::bitsize::dqword) 10288 ) 10289 ) 10290 ) 10291 ); 10292 pack.push_back( 10293 this->astCtxt->extract(15, 0, 10294 this->astCtxt->bvlshr( 10295 op2, 10296 this->astCtxt->bvmul( 10297 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(3, 2, op3)), 10298 this->astCtxt->bv(16, triton::bitsize::dqword) 10299 ) 10300 ) 10301 ) 10302 ); 10303 pack.push_back( 10304 this->astCtxt->extract(15, 0, 10305 this->astCtxt->bvlshr( 10306 op2, 10307 this->astCtxt->bvmul( 10308 this->astCtxt->zx(triton::bitsize::dqword-2, this->astCtxt->extract(1, 0, op3)), 10309 this->astCtxt->bv(16, triton::bitsize::dqword) 10310 ) 10311 ) 10312 ) 10313 ); 10314 10315 auto node = this->astCtxt->concat(pack); 10316 10317 /* Create symbolic expression */ 10318 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSHUFLW operation"); 10319 10320 /* Spread taint */ 10321 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 10322 10323 /* Update the symbolic control flow */ 10324 this->controlFlow_s(inst); 10325 } 10326 10327 pshufw_s(triton::arch::Instruction & inst)10328 void x86Semantics::pshufw_s(triton::arch::Instruction& inst) { 10329 auto& dst = inst.operands[0]; 10330 auto& src = inst.operands[1]; 10331 auto& ord = inst.operands[2]; 10332 10333 /* Create symbolic operands */ 10334 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 10335 auto op3 = this->symbolicEngine->getOperandAst(inst, ord); 10336 10337 /* Create the semantics */ 10338 std::vector<triton::ast::SharedAbstractNode> pack; 10339 pack.reserve(4); 10340 10341 pack.push_back( 10342 this->astCtxt->extract(15, 0, 10343 this->astCtxt->bvlshr( 10344 op2, 10345 this->astCtxt->bvmul( 10346 this->astCtxt->zx(triton::bitsize::qword-2, this->astCtxt->extract(7, 6, op3)), 10347 this->astCtxt->bv(16, triton::bitsize::qword) 10348 ) 10349 ) 10350 ) 10351 ); 10352 pack.push_back( 10353 this->astCtxt->extract(15, 0, 10354 this->astCtxt->bvlshr( 10355 op2, 10356 this->astCtxt->bvmul( 10357 this->astCtxt->zx(triton::bitsize::qword-2, this->astCtxt->extract(5, 4, op3)), 10358 this->astCtxt->bv(16, triton::bitsize::qword) 10359 ) 10360 ) 10361 ) 10362 ); 10363 pack.push_back( 10364 this->astCtxt->extract(15, 0, 10365 this->astCtxt->bvlshr( 10366 op2, 10367 this->astCtxt->bvmul( 10368 this->astCtxt->zx(triton::bitsize::qword-2, this->astCtxt->extract(3, 2, op3)), 10369 this->astCtxt->bv(16, triton::bitsize::qword) 10370 ) 10371 ) 10372 ) 10373 ); 10374 pack.push_back( 10375 this->astCtxt->extract(15, 0, 10376 this->astCtxt->bvlshr( 10377 op2, 10378 this->astCtxt->bvmul( 10379 this->astCtxt->zx(triton::bitsize::qword-2, this->astCtxt->extract(1, 0, op3)), 10380 this->astCtxt->bv(16, triton::bitsize::qword) 10381 ) 10382 ) 10383 ) 10384 ); 10385 10386 auto node = this->astCtxt->concat(pack); 10387 10388 /* Create symbolic expression */ 10389 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSHUFW operation"); 10390 10391 /* Spread taint */ 10392 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 10393 10394 /* Update the symbolic control flow */ 10395 this->controlFlow_s(inst); 10396 } 10397 10398 pslld_s(triton::arch::Instruction & inst)10399 void x86Semantics::pslld_s(triton::arch::Instruction& inst) { 10400 auto& dst = inst.operands[0]; 10401 auto& src = inst.operands[1]; 10402 10403 /* Create symbolic operands */ 10404 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 10405 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src)); 10406 10407 /* Create the semantics */ 10408 std::vector<triton::ast::SharedAbstractNode> packed; 10409 packed.reserve(4); 10410 10411 switch (dst.getBitSize()) { 10412 /* XMM */ 10413 case triton::bitsize::dqword: 10414 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(127, 96, op1), this->astCtxt->extract(31, 0, op2))); 10415 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract( 95, 64, op1), this->astCtxt->extract(31, 0, op2))); 10416 10417 /* MMX */ 10418 case triton::bitsize::qword: 10419 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(63, 32, op1), this->astCtxt->extract(31, 0, op2))); 10420 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(31, 0, op1), this->astCtxt->extract(31, 0, op2))); 10421 break; 10422 10423 default: 10424 throw triton::exceptions::Semantics("x86Semantics::pslld_s(): Invalid operand size."); 10425 } 10426 10427 auto node = this->astCtxt->concat(packed); 10428 10429 /* Create symbolic expression */ 10430 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSLLD operation"); 10431 10432 /* Spread taint */ 10433 expr->isTainted = this->taintEngine->taintUnion(dst, src); 10434 10435 /* Update the symbolic control flow */ 10436 this->controlFlow_s(inst); 10437 } 10438 10439 pslldq_s(triton::arch::Instruction & inst)10440 void x86Semantics::pslldq_s(triton::arch::Instruction& inst) { 10441 auto& dst = inst.operands[0]; 10442 auto& src = inst.operands[1]; 10443 10444 /* Create symbolic operands */ 10445 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 10446 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src)); 10447 10448 /* Create the semantics */ 10449 auto node = this->astCtxt->bvshl( 10450 op1, 10451 this->astCtxt->bvmul( 10452 this->astCtxt->ite( 10453 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::word, dst.getBitSize())), 10454 this->astCtxt->bv(triton::bitsize::word, dst.getBitSize()), 10455 op2 10456 ), 10457 this->astCtxt->bv(triton::size::qword, dst.getBitSize()) 10458 ) 10459 ); 10460 10461 /* Create symbolic expression */ 10462 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSLLDQ operation"); 10463 10464 /* Spread taint */ 10465 expr->isTainted = this->taintEngine->taintUnion(dst, src); 10466 10467 /* Update the symbolic control flow */ 10468 this->controlFlow_s(inst); 10469 } 10470 10471 psllq_s(triton::arch::Instruction & inst)10472 void x86Semantics::psllq_s(triton::arch::Instruction& inst) { 10473 auto& dst = inst.operands[0]; 10474 auto& src = inst.operands[1]; 10475 10476 /* Create symbolic operands */ 10477 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 10478 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src)); 10479 10480 /* Create the semantics */ 10481 triton::ast::SharedAbstractNode node; 10482 10483 std::vector<triton::ast::SharedAbstractNode> packed; 10484 packed.reserve(2); 10485 10486 switch (dst.getBitSize()) { 10487 /* XMM */ 10488 case triton::bitsize::dqword: 10489 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(127, 64, op1), this->astCtxt->extract(63, 0, op2))); 10490 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract( 63, 0, op1), this->astCtxt->extract(63, 0, op2))); 10491 node = this->astCtxt->concat(packed); 10492 break; 10493 10494 /* MMX */ 10495 case triton::bitsize::qword: 10496 /* MMX register is only one QWORD so it's a simple shl */ 10497 node = this->astCtxt->bvshl(op1, op2); 10498 break; 10499 10500 default: 10501 throw triton::exceptions::Semantics("x86Semantics::psllq_s(): Invalid operand size."); 10502 } 10503 10504 /* Create symbolic expression */ 10505 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSLLQ operation"); 10506 10507 /* Spread taint */ 10508 expr->isTainted = this->taintEngine->taintUnion(dst, src); 10509 10510 /* Update the symbolic control flow */ 10511 this->controlFlow_s(inst); 10512 } 10513 10514 psllw_s(triton::arch::Instruction & inst)10515 void x86Semantics::psllw_s(triton::arch::Instruction& inst) { 10516 auto& dst = inst.operands[0]; 10517 auto& src = inst.operands[1]; 10518 10519 /* Create symbolic operands */ 10520 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 10521 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src)); 10522 10523 /* Create the semantics */ 10524 std::vector<triton::ast::SharedAbstractNode> packed; 10525 packed.reserve(8); 10526 10527 switch (dst.getBitSize()) { 10528 /* XMM */ 10529 case triton::bitsize::dqword: 10530 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(127, 112, op1), this->astCtxt->extract(15, 0, op2))); 10531 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(111, 96, op1), this->astCtxt->extract(15, 0, op2))); 10532 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract( 95, 80, op1), this->astCtxt->extract(15, 0, op2))); 10533 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract( 79, 64, op1), this->astCtxt->extract(15, 0, op2))); 10534 10535 /* MMX */ 10536 case triton::bitsize::qword: 10537 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(63, 48, op1), this->astCtxt->extract(15, 0, op2))); 10538 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(47, 32, op1), this->astCtxt->extract(15, 0, op2))); 10539 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(31, 16, op1), this->astCtxt->extract(15, 0, op2))); 10540 packed.push_back(this->astCtxt->bvshl(this->astCtxt->extract(15, 0, op1), this->astCtxt->extract(15, 0, op2))); 10541 break; 10542 10543 default: 10544 throw triton::exceptions::Semantics("x86Semantics::psllw_s(): Invalid operand size."); 10545 } 10546 10547 auto node = this->astCtxt->concat(packed); 10548 10549 /* Create symbolic expression */ 10550 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSLLW operation"); 10551 10552 /* Spread taint */ 10553 expr->isTainted = this->taintEngine->taintUnion(dst, src); 10554 10555 /* Update the symbolic control flow */ 10556 this->controlFlow_s(inst); 10557 } 10558 10559 psrldq_s(triton::arch::Instruction & inst)10560 void x86Semantics::psrldq_s(triton::arch::Instruction& inst) { 10561 auto& dst = inst.operands[0]; 10562 auto& src = inst.operands[1]; 10563 10564 /* Create symbolic operands */ 10565 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 10566 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src)); 10567 10568 /* Create the semantics */ 10569 auto node = this->astCtxt->bvlshr( 10570 op1, 10571 this->astCtxt->bvmul( 10572 this->astCtxt->ite( 10573 this->astCtxt->bvuge(op2, this->astCtxt->bv(triton::bitsize::word, dst.getBitSize())), 10574 this->astCtxt->bv(triton::bitsize::word, dst.getBitSize()), 10575 op2 10576 ), 10577 this->astCtxt->bv(triton::size::qword, dst.getBitSize()) 10578 ) 10579 ); 10580 10581 /* Create symbolic expression */ 10582 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSRLDQ operation"); 10583 10584 /* Spread taint */ 10585 expr->isTainted = this->taintEngine->taintUnion(dst, src); 10586 10587 /* Update the symbolic control flow */ 10588 this->controlFlow_s(inst); 10589 } 10590 10591 psubb_s(triton::arch::Instruction & inst)10592 void x86Semantics::psubb_s(triton::arch::Instruction& inst) { 10593 auto& dst = inst.operands[0]; 10594 auto& src = inst.operands[1]; 10595 10596 /* Create symbolic operands */ 10597 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 10598 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 10599 10600 /* Create the semantics */ 10601 std::vector<triton::ast::SharedAbstractNode> packed; 10602 packed.reserve(16); 10603 10604 switch (dst.getBitSize()) { 10605 10606 /* XMM */ 10607 case triton::bitsize::dqword: 10608 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(127, 120, op1), this->astCtxt->extract(127, 120, op2))); 10609 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(119, 112, op1), this->astCtxt->extract(119, 112, op2))); 10610 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(111, 104, op1), this->astCtxt->extract(111, 104, op2))); 10611 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(103, 96, op1), this->astCtxt->extract(103, 96, op2))); 10612 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(95, 88, op1), this->astCtxt->extract(95, 88, op2))); 10613 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(87, 80, op1), this->astCtxt->extract(87, 80, op2))); 10614 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(79, 72, op1), this->astCtxt->extract(79, 72, op2))); 10615 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(71, 64, op1), this->astCtxt->extract(71, 64, op2))); 10616 10617 /* MMX */ 10618 case triton::bitsize::qword: 10619 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(63, 56, op1), this->astCtxt->extract(63, 56, op2))); 10620 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(55, 48, op1), this->astCtxt->extract(55, 48, op2))); 10621 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(47, 40, op1), this->astCtxt->extract(47, 40, op2))); 10622 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(39, 32, op1), this->astCtxt->extract(39, 32, op2))); 10623 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(31, 24, op1), this->astCtxt->extract(31, 24, op2))); 10624 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(23, 16, op1), this->astCtxt->extract(23, 16, op2))); 10625 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(15, 8, op1), this->astCtxt->extract(15, 8, op2))); 10626 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(7, 0, op1), this->astCtxt->extract(7, 0, op2))); 10627 break; 10628 10629 default: 10630 throw triton::exceptions::Semantics("x86Semantics::psubb_s(): Invalid operand size."); 10631 10632 } 10633 10634 auto node = this->astCtxt->concat(packed); 10635 10636 /* Create symbolic expression */ 10637 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSUBB operation"); 10638 10639 /* Spread taint */ 10640 expr->isTainted = this->taintEngine->taintUnion(dst, src); 10641 10642 /* Update the symbolic control flow */ 10643 this->controlFlow_s(inst); 10644 } 10645 10646 psubd_s(triton::arch::Instruction & inst)10647 void x86Semantics::psubd_s(triton::arch::Instruction& inst) { 10648 auto& dst = inst.operands[0]; 10649 auto& src = inst.operands[1]; 10650 10651 /* Create symbolic operands */ 10652 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 10653 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 10654 10655 /* Create the semantics */ 10656 std::vector<triton::ast::SharedAbstractNode> packed; 10657 packed.reserve(4); 10658 10659 switch (dst.getBitSize()) { 10660 10661 /* XMM */ 10662 case triton::bitsize::dqword: 10663 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(127, 96, op1), this->astCtxt->extract(127, 96, op2))); 10664 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(95, 64, op1), this->astCtxt->extract(95, 64, op2))); 10665 10666 /* MMX */ 10667 case triton::bitsize::qword: 10668 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(63, 32, op1), this->astCtxt->extract(63, 32, op2))); 10669 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(31, 0, op1), this->astCtxt->extract(31, 0, op2))); 10670 break; 10671 10672 default: 10673 throw triton::exceptions::Semantics("x86Semantics::psubd_s(): Invalid operand size."); 10674 10675 } 10676 10677 auto node = this->astCtxt->concat(packed); 10678 10679 /* Create symbolic expression */ 10680 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSUBD operation"); 10681 10682 /* Spread taint */ 10683 expr->isTainted = this->taintEngine->taintUnion(dst, src); 10684 10685 /* Update the symbolic control flow */ 10686 this->controlFlow_s(inst); 10687 } 10688 10689 psubq_s(triton::arch::Instruction & inst)10690 void x86Semantics::psubq_s(triton::arch::Instruction& inst) { 10691 auto& dst = inst.operands[0]; 10692 auto& src = inst.operands[1]; 10693 10694 /* Create symbolic operands */ 10695 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 10696 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 10697 10698 /* Create the semantics */ 10699 std::vector<triton::ast::SharedAbstractNode> packed; 10700 packed.reserve(2); 10701 10702 switch (dst.getBitSize()) { 10703 10704 /* XMM */ 10705 case triton::bitsize::dqword: 10706 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(127, 64, op1), this->astCtxt->extract(127, 64, op2))); 10707 10708 /* MMX */ 10709 case triton::bitsize::qword: 10710 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(63, 0, op1), this->astCtxt->extract(63, 0, op2))); 10711 break; 10712 10713 default: 10714 throw triton::exceptions::Semantics("x86Semantics::psubq_s(): Invalid operand size."); 10715 10716 } 10717 10718 auto node = this->astCtxt->concat(packed); 10719 10720 /* Create symbolic expression */ 10721 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSUBQ operation"); 10722 10723 /* Spread taint */ 10724 expr->isTainted = this->taintEngine->taintUnion(dst, src); 10725 10726 /* Update the symbolic control flow */ 10727 this->controlFlow_s(inst); 10728 } 10729 10730 psubw_s(triton::arch::Instruction & inst)10731 void x86Semantics::psubw_s(triton::arch::Instruction& inst) { 10732 auto& dst = inst.operands[0]; 10733 auto& src = inst.operands[1]; 10734 10735 /* Create symbolic operands */ 10736 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 10737 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 10738 10739 /* Create the semantics */ 10740 std::vector<triton::ast::SharedAbstractNode> packed; 10741 packed.reserve(8); 10742 10743 switch (dst.getBitSize()) { 10744 10745 /* XMM */ 10746 case triton::bitsize::dqword: 10747 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(127, 112, op1), this->astCtxt->extract(127, 112, op2))); 10748 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(111, 96, op1), this->astCtxt->extract(111, 96, op2))); 10749 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(95, 80, op1), this->astCtxt->extract(95, 80, op2))); 10750 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(79, 64, op1), this->astCtxt->extract(79, 64, op2))); 10751 10752 /* MMX */ 10753 case triton::bitsize::qword: 10754 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(63, 48, op1), this->astCtxt->extract(63, 48, op2))); 10755 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(47, 32, op1), this->astCtxt->extract(47, 32, op2))); 10756 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(31, 16, op1), this->astCtxt->extract(31, 16, op2))); 10757 packed.push_back(this->astCtxt->bvsub(this->astCtxt->extract(15, 0, op1), this->astCtxt->extract(15, 0, op2))); 10758 break; 10759 10760 default: 10761 throw triton::exceptions::Semantics("x86Semantics::psubw_s(): Invalid operand size."); 10762 10763 } 10764 10765 auto node = this->astCtxt->concat(packed); 10766 10767 /* Create symbolic expression */ 10768 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PSUBW operation"); 10769 10770 /* Spread taint */ 10771 expr->isTainted = this->taintEngine->taintUnion(dst, src); 10772 10773 /* Update the symbolic control flow */ 10774 this->controlFlow_s(inst); 10775 } 10776 10777 ptest_s(triton::arch::Instruction & inst)10778 void x86Semantics::ptest_s(triton::arch::Instruction& inst) { 10779 auto& src1 = inst.operands[0]; 10780 auto& src2 = inst.operands[1]; 10781 10782 /* Create symbolic operands */ 10783 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 10784 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 10785 10786 /* Create the semantics */ 10787 auto node1 = this->astCtxt->bvand(op1, op2); 10788 auto node2 = this->astCtxt->bvand(op1, this->astCtxt->bvnot(op2)); 10789 10790 /* Create symbolic expression */ 10791 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "PTEST operation"); 10792 auto expr2 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node2, "PTEST operation"); 10793 10794 /* Spread taint */ 10795 expr1->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2); 10796 expr2->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2); 10797 10798 /* Update symbolic flags */ 10799 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_AF), "Clears adjust flag"); 10800 this->cfPtest_s(inst, expr2, src1, true); 10801 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag"); 10802 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_PF), "Clears parity flag"); 10803 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_SF), "Clears sign flag"); 10804 this->zf_s(inst, expr1, src1, true); 10805 10806 /* Update the symbolic control flow */ 10807 this->controlFlow_s(inst); 10808 } 10809 10810 punpckhbw_s(triton::arch::Instruction & inst)10811 void x86Semantics::punpckhbw_s(triton::arch::Instruction& inst) { 10812 auto& dst = inst.operands[0]; 10813 auto& src = inst.operands[1]; 10814 10815 /* Create symbolic operands */ 10816 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 10817 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 10818 10819 /* Create the semantics */ 10820 std::vector<triton::ast::SharedAbstractNode> unpack; 10821 unpack.reserve(24); 10822 10823 switch (dst.getBitSize()) { 10824 10825 /* MMX */ 10826 case triton::bitsize::qword: 10827 unpack.push_back(this->astCtxt->extract(63, 56, op2)); 10828 unpack.push_back(this->astCtxt->extract(63, 56, op1)); 10829 unpack.push_back(this->astCtxt->extract(55, 48, op2)); 10830 unpack.push_back(this->astCtxt->extract(55, 48, op1)); 10831 unpack.push_back(this->astCtxt->extract(47, 40, op2)); 10832 unpack.push_back(this->astCtxt->extract(55, 40, op1)); 10833 unpack.push_back(this->astCtxt->extract(39, 32, op2)); 10834 unpack.push_back(this->astCtxt->extract(39, 32, op1)); 10835 break; 10836 10837 /* XMM */ 10838 case triton::bitsize::dqword: 10839 unpack.push_back(this->astCtxt->extract(127, 120, op2)); 10840 unpack.push_back(this->astCtxt->extract(127, 120, op1)); 10841 unpack.push_back(this->astCtxt->extract(119, 112, op2)); 10842 unpack.push_back(this->astCtxt->extract(119, 112, op1)); 10843 unpack.push_back(this->astCtxt->extract(111, 104, op2)); 10844 unpack.push_back(this->astCtxt->extract(111, 104, op1)); 10845 unpack.push_back(this->astCtxt->extract(103, 96, op2)); 10846 unpack.push_back(this->astCtxt->extract(103, 96, op1)); 10847 unpack.push_back(this->astCtxt->extract(95, 88, op2)); 10848 unpack.push_back(this->astCtxt->extract(95, 88, op1)); 10849 unpack.push_back(this->astCtxt->extract(87, 80, op2)); 10850 unpack.push_back(this->astCtxt->extract(87, 80, op1)); 10851 unpack.push_back(this->astCtxt->extract(79, 72, op2)); 10852 unpack.push_back(this->astCtxt->extract(79, 72, op1)); 10853 unpack.push_back(this->astCtxt->extract(71, 64, op2)); 10854 unpack.push_back(this->astCtxt->extract(71, 64, op1)); 10855 break; 10856 10857 default: 10858 throw triton::exceptions::Semantics("x86Semantics::punpckhbw_s(): Invalid operand size."); 10859 } 10860 10861 auto node = this->astCtxt->concat(unpack); 10862 10863 /* Create symbolic expression */ 10864 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKHBW operation"); 10865 10866 /* Apply the taint */ 10867 expr->isTainted = this->taintEngine->taintUnion(dst, src); 10868 10869 /* Update the symbolic control flow */ 10870 this->controlFlow_s(inst); 10871 } 10872 10873 punpckhdq_s(triton::arch::Instruction & inst)10874 void x86Semantics::punpckhdq_s(triton::arch::Instruction& inst) { 10875 auto& dst = inst.operands[0]; 10876 auto& src = inst.operands[1]; 10877 10878 /* Create symbolic operands */ 10879 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 10880 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 10881 10882 /* Create the semantics */ 10883 std::vector<triton::ast::SharedAbstractNode> unpack; 10884 unpack.reserve(6); 10885 10886 switch (dst.getBitSize()) { 10887 10888 /* MMX */ 10889 case triton::bitsize::qword: 10890 unpack.push_back(this->astCtxt->extract(63, 32, op2)); 10891 unpack.push_back(this->astCtxt->extract(63, 32, op1)); 10892 break; 10893 10894 /* XMM */ 10895 case triton::bitsize::dqword: 10896 unpack.push_back(this->astCtxt->extract(127, 96, op2)); 10897 unpack.push_back(this->astCtxt->extract(127, 96, op1)); 10898 unpack.push_back(this->astCtxt->extract(95, 64, op2)); 10899 unpack.push_back(this->astCtxt->extract(95, 64, op1)); 10900 break; 10901 10902 default: 10903 throw triton::exceptions::Semantics("x86Semantics::punpckhdq_s(): Invalid operand size."); 10904 } 10905 10906 auto node = this->astCtxt->concat(unpack); 10907 10908 /* Create symbolic expression */ 10909 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKHDQ operation"); 10910 10911 /* Apply the taint */ 10912 expr->isTainted = this->taintEngine->taintUnion(dst, src); 10913 10914 /* Update the symbolic control flow */ 10915 this->controlFlow_s(inst); 10916 } 10917 10918 punpckhqdq_s(triton::arch::Instruction & inst)10919 void x86Semantics::punpckhqdq_s(triton::arch::Instruction& inst) { 10920 auto& dst = inst.operands[0]; 10921 auto& src = inst.operands[1]; 10922 10923 /* Create symbolic operands */ 10924 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 10925 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 10926 10927 /* Create the semantics */ 10928 std::vector<triton::ast::SharedAbstractNode> unpack; 10929 unpack.reserve(2); 10930 10931 switch (dst.getBitSize()) { 10932 10933 /* XMM */ 10934 case triton::bitsize::dqword: 10935 unpack.push_back(this->astCtxt->extract(127, 64, op2)); 10936 unpack.push_back(this->astCtxt->extract(127, 64, op1)); 10937 break; 10938 10939 default: 10940 throw triton::exceptions::Semantics("x86Semantics::punpckhqdq_s(): Invalid operand size."); 10941 } 10942 10943 auto node = this->astCtxt->concat(unpack); 10944 10945 /* Create symbolic expression */ 10946 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKHQDQ operation"); 10947 10948 /* Apply the taint */ 10949 expr->isTainted = this->taintEngine->taintUnion(dst, src); 10950 10951 /* Update the symbolic control flow */ 10952 this->controlFlow_s(inst); 10953 } 10954 10955 punpckhwd_s(triton::arch::Instruction & inst)10956 void x86Semantics::punpckhwd_s(triton::arch::Instruction& inst) { 10957 auto& dst = inst.operands[0]; 10958 auto& src = inst.operands[1]; 10959 10960 /* Create symbolic operands */ 10961 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 10962 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 10963 10964 /* Create the semantics */ 10965 std::vector<triton::ast::SharedAbstractNode> unpack; 10966 unpack.reserve(12); 10967 10968 switch (dst.getBitSize()) { 10969 10970 /* MMX */ 10971 case triton::bitsize::qword: 10972 unpack.push_back(this->astCtxt->extract(63, 48, op2)); 10973 unpack.push_back(this->astCtxt->extract(63, 48, op1)); 10974 unpack.push_back(this->astCtxt->extract(47, 32, op2)); 10975 unpack.push_back(this->astCtxt->extract(47, 32, op1)); 10976 break; 10977 10978 /* XMM */ 10979 case triton::bitsize::dqword: 10980 unpack.push_back(this->astCtxt->extract(127, 112, op2)); 10981 unpack.push_back(this->astCtxt->extract(127, 112, op1)); 10982 unpack.push_back(this->astCtxt->extract(111, 96, op2)); 10983 unpack.push_back(this->astCtxt->extract(111, 96, op1)); 10984 unpack.push_back(this->astCtxt->extract(95, 80, op2)); 10985 unpack.push_back(this->astCtxt->extract(95, 80, op1)); 10986 unpack.push_back(this->astCtxt->extract(79, 64, op2)); 10987 unpack.push_back(this->astCtxt->extract(79, 64, op1)); 10988 break; 10989 10990 default: 10991 throw triton::exceptions::Semantics("x86Semantics::punpckhwd_s(): Invalid operand size."); 10992 } 10993 10994 auto node = this->astCtxt->concat(unpack); 10995 10996 /* Create symbolic expression */ 10997 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKHWD operation"); 10998 10999 /* Apply the taint */ 11000 expr->isTainted = this->taintEngine->taintUnion(dst, src); 11001 11002 /* Update the symbolic control flow */ 11003 this->controlFlow_s(inst); 11004 } 11005 11006 punpcklbw_s(triton::arch::Instruction & inst)11007 void x86Semantics::punpcklbw_s(triton::arch::Instruction& inst) { 11008 auto& dst = inst.operands[0]; 11009 auto& src = inst.operands[1]; 11010 11011 /* Create symbolic operands */ 11012 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 11013 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 11014 11015 /* Create the semantics */ 11016 std::vector<triton::ast::SharedAbstractNode> unpack; 11017 unpack.reserve(24); 11018 11019 switch (dst.getBitSize()) { 11020 11021 /* MMX */ 11022 case triton::bitsize::qword: 11023 unpack.push_back(this->astCtxt->extract(31, 24, op2)); 11024 unpack.push_back(this->astCtxt->extract(31, 24, op1)); 11025 unpack.push_back(this->astCtxt->extract(23, 16, op2)); 11026 unpack.push_back(this->astCtxt->extract(23, 16, op1)); 11027 unpack.push_back(this->astCtxt->extract(15, 8, op2)); 11028 unpack.push_back(this->astCtxt->extract(15, 8, op1)); 11029 unpack.push_back(this->astCtxt->extract(7, 0, op2)); 11030 unpack.push_back(this->astCtxt->extract(7, 0, op1)); 11031 break; 11032 11033 /* XMM */ 11034 case triton::bitsize::dqword: 11035 unpack.push_back(this->astCtxt->extract(63, 56, op2)); 11036 unpack.push_back(this->astCtxt->extract(63, 56, op1)); 11037 unpack.push_back(this->astCtxt->extract(55, 48, op2)); 11038 unpack.push_back(this->astCtxt->extract(55, 48, op1)); 11039 unpack.push_back(this->astCtxt->extract(47, 40, op2)); 11040 unpack.push_back(this->astCtxt->extract(47, 40, op1)); 11041 unpack.push_back(this->astCtxt->extract(39, 32, op2)); 11042 unpack.push_back(this->astCtxt->extract(39, 32, op1)); 11043 unpack.push_back(this->astCtxt->extract(31, 24, op2)); 11044 unpack.push_back(this->astCtxt->extract(31, 24, op1)); 11045 unpack.push_back(this->astCtxt->extract(23, 16, op2)); 11046 unpack.push_back(this->astCtxt->extract(23, 16, op1)); 11047 unpack.push_back(this->astCtxt->extract(15, 8, op2)); 11048 unpack.push_back(this->astCtxt->extract(15, 8, op1)); 11049 unpack.push_back(this->astCtxt->extract(7, 0, op2)); 11050 unpack.push_back(this->astCtxt->extract(7, 0, op1)); 11051 break; 11052 11053 default: 11054 throw triton::exceptions::Semantics("x86Semantics::punpcklbw_s(): Invalid operand size."); 11055 } 11056 11057 auto node = this->astCtxt->concat(unpack); 11058 11059 /* Create symbolic expression */ 11060 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKLBW operation"); 11061 11062 /* Apply the taint */ 11063 expr->isTainted = this->taintEngine->taintUnion(dst, src); 11064 11065 /* Update the symbolic control flow */ 11066 this->controlFlow_s(inst); 11067 } 11068 11069 punpckldq_s(triton::arch::Instruction & inst)11070 void x86Semantics::punpckldq_s(triton::arch::Instruction& inst) { 11071 auto& dst = inst.operands[0]; 11072 auto& src = inst.operands[1]; 11073 11074 /* Create symbolic operands */ 11075 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 11076 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 11077 11078 /* Create the semantics */ 11079 std::vector<triton::ast::SharedAbstractNode> unpack; 11080 unpack.reserve(6); 11081 11082 switch (dst.getBitSize()) { 11083 11084 /* MMX */ 11085 case triton::bitsize::qword: 11086 unpack.push_back(this->astCtxt->extract(31, 0, op2)); 11087 unpack.push_back(this->astCtxt->extract(31, 0, op1)); 11088 break; 11089 11090 /* XMM */ 11091 case triton::bitsize::dqword: 11092 unpack.push_back(this->astCtxt->extract(63, 32, op2)); 11093 unpack.push_back(this->astCtxt->extract(63, 32, op1)); 11094 unpack.push_back(this->astCtxt->extract(31, 0, op2)); 11095 unpack.push_back(this->astCtxt->extract(31, 0, op1)); 11096 break; 11097 11098 default: 11099 throw triton::exceptions::Semantics("x86Semantics::punpckldq_s(): Invalid operand size."); 11100 } 11101 11102 auto node = this->astCtxt->concat(unpack); 11103 11104 /* Create symbolic expression */ 11105 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKLDQ operation"); 11106 11107 /* Apply the taint */ 11108 expr->isTainted = this->taintEngine->taintUnion(dst, src); 11109 11110 /* Update the symbolic control flow */ 11111 this->controlFlow_s(inst); 11112 } 11113 11114 punpcklqdq_s(triton::arch::Instruction & inst)11115 void x86Semantics::punpcklqdq_s(triton::arch::Instruction& inst) { 11116 auto& dst = inst.operands[0]; 11117 auto& src = inst.operands[1]; 11118 11119 /* Create symbolic operands */ 11120 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 11121 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 11122 11123 /* Create the semantics */ 11124 std::vector<triton::ast::SharedAbstractNode> unpack; 11125 unpack.reserve(2); 11126 11127 switch (dst.getBitSize()) { 11128 11129 /* XMM */ 11130 case triton::bitsize::dqword: 11131 unpack.push_back(this->astCtxt->extract(63, 0, op2)); 11132 unpack.push_back(this->astCtxt->extract(63, 0, op1)); 11133 break; 11134 11135 default: 11136 throw triton::exceptions::Semantics("x86Semantics::punpcklqdq_s(): Invalid operand size."); 11137 } 11138 11139 auto node = this->astCtxt->concat(unpack); 11140 11141 /* Create symbolic expression */ 11142 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKLQDQ operation"); 11143 11144 /* Apply the taint */ 11145 expr->isTainted = this->taintEngine->taintUnion(dst, src); 11146 11147 /* Update the symbolic control flow */ 11148 this->controlFlow_s(inst); 11149 } 11150 11151 punpcklwd_s(triton::arch::Instruction & inst)11152 void x86Semantics::punpcklwd_s(triton::arch::Instruction& inst) { 11153 auto& dst = inst.operands[0]; 11154 auto& src = inst.operands[1]; 11155 11156 /* Create symbolic operands */ 11157 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 11158 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 11159 11160 /* Create the semantics */ 11161 std::vector<triton::ast::SharedAbstractNode> unpack; 11162 unpack.reserve(12); 11163 11164 switch (dst.getBitSize()) { 11165 11166 /* MMX */ 11167 case triton::bitsize::qword: 11168 unpack.push_back(this->astCtxt->extract(31, 16, op2)); 11169 unpack.push_back(this->astCtxt->extract(31, 16, op1)); 11170 unpack.push_back(this->astCtxt->extract(15, 0, op2)); 11171 unpack.push_back(this->astCtxt->extract(15, 0, op1)); 11172 break; 11173 11174 /* XMM */ 11175 case triton::bitsize::dqword: 11176 unpack.push_back(this->astCtxt->extract(63, 48, op2)); 11177 unpack.push_back(this->astCtxt->extract(63, 48, op1)); 11178 unpack.push_back(this->astCtxt->extract(47, 32, op2)); 11179 unpack.push_back(this->astCtxt->extract(47, 32, op1)); 11180 unpack.push_back(this->astCtxt->extract(31, 16, op2)); 11181 unpack.push_back(this->astCtxt->extract(31, 16, op1)); 11182 unpack.push_back(this->astCtxt->extract(15, 0, op2)); 11183 unpack.push_back(this->astCtxt->extract(15, 0, op1)); 11184 break; 11185 11186 default: 11187 throw triton::exceptions::Semantics("x86Semantics::punpcklwd_s(): Invalid operand size."); 11188 } 11189 11190 auto node = this->astCtxt->concat(unpack); 11191 11192 /* Create symbolic expression */ 11193 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUNPCKLWD operation"); 11194 11195 /* Apply the taint */ 11196 expr->isTainted = this->taintEngine->taintUnion(dst, src); 11197 11198 /* Update the symbolic control flow */ 11199 this->controlFlow_s(inst); 11200 } 11201 11202 push_s(triton::arch::Instruction & inst)11203 void x86Semantics::push_s(triton::arch::Instruction& inst) { 11204 auto& src = inst.operands[0]; 11205 auto stack = this->architecture->getStackPointer(); 11206 triton::uint32 size = stack.getSize(); 11207 11208 /* If it's an immediate source, the memory access is always based on the arch size */ 11209 if (src.getType() != triton::arch::OP_IMM) 11210 size = src.getSize(); 11211 11212 /* Create symbolic operands */ 11213 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 11214 11215 /* Create the semantics - side effect */ 11216 auto stackValue = alignSubStack_s(inst, size); 11217 auto dst = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, size)); 11218 11219 /* Create the semantics */ 11220 auto node = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), op1); 11221 11222 /* Create symbolic expression */ 11223 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUSH operation"); 11224 11225 /* Spread taint */ 11226 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 11227 11228 /* Update the symbolic control flow */ 11229 this->controlFlow_s(inst); 11230 } 11231 11232 pushal_s(triton::arch::Instruction & inst)11233 void x86Semantics::pushal_s(triton::arch::Instruction& inst) { 11234 auto stack = this->architecture->getStackPointer(); 11235 auto stackValue = this->architecture->getConcreteRegisterValue(stack).convert_to<triton::uint64>(); 11236 auto dst1 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 1), stack.getSize())); 11237 auto dst2 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 2), stack.getSize())); 11238 auto dst3 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 3), stack.getSize())); 11239 auto dst4 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 4), stack.getSize())); 11240 auto dst5 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 5), stack.getSize())); 11241 auto dst6 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 6), stack.getSize())); 11242 auto dst7 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 7), stack.getSize())); 11243 auto dst8 = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue-(stack.getSize() * 8), stack.getSize())); 11244 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX)); 11245 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ECX)); 11246 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX)); 11247 auto src4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EBX)); 11248 auto src5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ESP)); 11249 auto src6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EBP)); 11250 auto src7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ESI)); 11251 auto src8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDI)); 11252 11253 /* Create symbolic operands */ 11254 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 11255 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 11256 auto op3 = this->symbolicEngine->getOperandAst(inst, src3); 11257 auto op4 = this->symbolicEngine->getOperandAst(inst, src4); 11258 auto op5 = this->symbolicEngine->getOperandAst(inst, src5); 11259 auto op6 = this->symbolicEngine->getOperandAst(inst, src6); 11260 auto op7 = this->symbolicEngine->getOperandAst(inst, src7); 11261 auto op8 = this->symbolicEngine->getOperandAst(inst, src8); 11262 11263 /* Create the semantics */ 11264 auto node1 = this->astCtxt->zx(dst1.getBitSize() - src1.getBitSize(), op1); 11265 auto node2 = this->astCtxt->zx(dst2.getBitSize() - src2.getBitSize(), op2); 11266 auto node3 = this->astCtxt->zx(dst3.getBitSize() - src3.getBitSize(), op3); 11267 auto node4 = this->astCtxt->zx(dst4.getBitSize() - src4.getBitSize(), op4); 11268 auto node5 = this->astCtxt->zx(dst5.getBitSize() - src5.getBitSize(), op5); 11269 auto node6 = this->astCtxt->zx(dst6.getBitSize() - src6.getBitSize(), op6); 11270 auto node7 = this->astCtxt->zx(dst7.getBitSize() - src7.getBitSize(), op7); 11271 auto node8 = this->astCtxt->zx(dst8.getBitSize() - src8.getBitSize(), op8); 11272 11273 /* Create symbolic expression */ 11274 alignSubStack_s(inst, 32); 11275 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1, "PUSHAL EAX operation"); 11276 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "PUSHAL ECX operation"); 11277 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3, "PUSHAL EDX operation"); 11278 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4, "PUSHAL EBX operation"); 11279 auto expr5 = this->symbolicEngine->createSymbolicExpression(inst, node5, dst5, "PUSHAL ESP operation"); 11280 auto expr6 = this->symbolicEngine->createSymbolicExpression(inst, node6, dst6, "PUSHAL EBP operation"); 11281 auto expr7 = this->symbolicEngine->createSymbolicExpression(inst, node7, dst7, "PUSHAL ESI operation"); 11282 auto expr8 = this->symbolicEngine->createSymbolicExpression(inst, node8, dst8, "PUSHAL EDI operation"); 11283 11284 /* Spread taint */ 11285 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src1); 11286 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src2); 11287 expr3->isTainted = this->taintEngine->taintAssignment(dst3, src3); 11288 expr4->isTainted = this->taintEngine->taintAssignment(dst4, src4); 11289 expr5->isTainted = this->taintEngine->taintAssignment(dst5, src5); 11290 expr6->isTainted = this->taintEngine->taintAssignment(dst6, src6); 11291 expr7->isTainted = this->taintEngine->taintAssignment(dst7, src7); 11292 expr8->isTainted = this->taintEngine->taintAssignment(dst8, src8); 11293 11294 /* Update the symbolic control flow */ 11295 this->controlFlow_s(inst); 11296 } 11297 11298 pushfd_s(triton::arch::Instruction & inst)11299 void x86Semantics::pushfd_s(triton::arch::Instruction& inst) { 11300 auto stack = this->architecture->getStackPointer(); 11301 11302 /* Create the semantics - side effect */ 11303 auto stackValue = alignSubStack_s(inst, stack.getSize()); 11304 auto dst = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize())); 11305 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 11306 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF)); 11307 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF)); 11308 auto src4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 11309 auto src5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 11310 auto src6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_TF)); 11311 auto src7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_IF)); 11312 auto src8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 11313 auto src9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 11314 auto src10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_NT)); 11315 auto src11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AC)); 11316 auto src12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_VIF)); 11317 auto src13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_VIP)); 11318 auto src14 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ID)); 11319 11320 /* Create symbolic operands */ 11321 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 11322 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 11323 auto op3 = this->symbolicEngine->getOperandAst(inst, src3); 11324 auto op4 = this->symbolicEngine->getOperandAst(inst, src4); 11325 auto op5 = this->symbolicEngine->getOperandAst(inst, src5); 11326 auto op6 = this->symbolicEngine->getOperandAst(inst, src6); 11327 auto op7 = this->symbolicEngine->getOperandAst(inst, src7); 11328 auto op8 = this->symbolicEngine->getOperandAst(inst, src8); 11329 auto op9 = this->symbolicEngine->getOperandAst(inst, src9); 11330 auto op10 = this->symbolicEngine->getOperandAst(inst, src10); 11331 auto op11 = this->symbolicEngine->getOperandAst(inst, src11); 11332 auto op12 = this->symbolicEngine->getOperandAst(inst, src12); 11333 auto op13 = this->symbolicEngine->getOperandAst(inst, src13); 11334 auto op14 = this->symbolicEngine->getOperandAst(inst, src14); 11335 11336 /* Create the semantics */ 11337 std::vector<triton::ast::SharedAbstractNode> eflags; 11338 eflags.reserve(22); 11339 11340 eflags.push_back(op14); 11341 eflags.push_back(op13); 11342 eflags.push_back(op12); 11343 eflags.push_back(op11); 11344 eflags.push_back(this->astCtxt->bvfalse()); /* vm */ 11345 eflags.push_back(this->astCtxt->bvfalse()); /* rf */ 11346 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */ 11347 eflags.push_back(op10); 11348 eflags.push_back(this->astCtxt->bvfalse()); /* iopl */ 11349 eflags.push_back(this->astCtxt->bvfalse()); /* iopl */ 11350 eflags.push_back(op9); 11351 eflags.push_back(op8); 11352 eflags.push_back(op7); 11353 eflags.push_back(op6); 11354 eflags.push_back(op5); 11355 eflags.push_back(op4); 11356 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */ 11357 eflags.push_back(op3); 11358 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */ 11359 eflags.push_back(op2); 11360 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */ 11361 eflags.push_back(op1); 11362 11363 auto node = this->astCtxt->zx( 11364 dst.getBitSize() - static_cast<triton::uint32>(eflags.size()), 11365 this->astCtxt->concat(eflags) 11366 ); 11367 11368 /* Create symbolic expression */ 11369 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUSHFD operation"); 11370 11371 /* Spread taint */ 11372 expr->isTainted = this->taintEngine->taintAssignment(dst, src1); 11373 expr->isTainted = this->taintEngine->taintUnion(dst, src2); 11374 expr->isTainted = this->taintEngine->taintUnion(dst, src3); 11375 expr->isTainted = this->taintEngine->taintUnion(dst, src4); 11376 expr->isTainted = this->taintEngine->taintUnion(dst, src5); 11377 expr->isTainted = this->taintEngine->taintUnion(dst, src6); 11378 expr->isTainted = this->taintEngine->taintUnion(dst, src7); 11379 expr->isTainted = this->taintEngine->taintUnion(dst, src8); 11380 expr->isTainted = this->taintEngine->taintUnion(dst, src9); 11381 expr->isTainted = this->taintEngine->taintUnion(dst, src10); 11382 expr->isTainted = this->taintEngine->taintUnion(dst, src11); 11383 expr->isTainted = this->taintEngine->taintUnion(dst, src12); 11384 expr->isTainted = this->taintEngine->taintUnion(dst, src13); 11385 expr->isTainted = this->taintEngine->taintUnion(dst, src14); 11386 11387 /* Update the symbolic control flow */ 11388 this->controlFlow_s(inst); 11389 } 11390 11391 pushfq_s(triton::arch::Instruction & inst)11392 void x86Semantics::pushfq_s(triton::arch::Instruction& inst) { 11393 auto stack = this->architecture->getStackPointer(); 11394 11395 /* Create the semantics - side effect */ 11396 auto stackValue = alignSubStack_s(inst, stack.getSize()); 11397 auto dst = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize())); 11398 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 11399 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF)); 11400 auto src3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF)); 11401 auto src4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 11402 auto src5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 11403 auto src6 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_TF)); 11404 auto src7 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_IF)); 11405 auto src8 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 11406 auto src9 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 11407 auto src10 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_NT)); 11408 auto src11 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AC)); 11409 auto src12 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_VIF)); 11410 auto src13 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_VIP)); 11411 auto src14 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ID)); 11412 11413 /* Create symbolic operands */ 11414 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 11415 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 11416 auto op3 = this->symbolicEngine->getOperandAst(inst, src3); 11417 auto op4 = this->symbolicEngine->getOperandAst(inst, src4); 11418 auto op5 = this->symbolicEngine->getOperandAst(inst, src5); 11419 auto op6 = this->symbolicEngine->getOperandAst(inst, src6); 11420 auto op7 = this->symbolicEngine->getOperandAst(inst, src7); 11421 auto op8 = this->symbolicEngine->getOperandAst(inst, src8); 11422 auto op9 = this->symbolicEngine->getOperandAst(inst, src9); 11423 auto op10 = this->symbolicEngine->getOperandAst(inst, src10); 11424 auto op11 = this->symbolicEngine->getOperandAst(inst, src11); 11425 auto op12 = this->symbolicEngine->getOperandAst(inst, src12); 11426 auto op13 = this->symbolicEngine->getOperandAst(inst, src13); 11427 auto op14 = this->symbolicEngine->getOperandAst(inst, src14); 11428 11429 /* Create the semantics */ 11430 std::vector<triton::ast::SharedAbstractNode> eflags; 11431 eflags.reserve(22); 11432 11433 eflags.push_back(op14); 11434 eflags.push_back(op13); 11435 eflags.push_back(op12); 11436 eflags.push_back(op11); 11437 eflags.push_back(this->astCtxt->bvfalse()); /* vm */ 11438 eflags.push_back(this->astCtxt->bvfalse()); /* rf */ 11439 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */ 11440 eflags.push_back(op10); 11441 eflags.push_back(this->astCtxt->bvfalse()); /* iopl */ 11442 eflags.push_back(this->astCtxt->bvfalse()); /* iopl */ 11443 eflags.push_back(op9); 11444 eflags.push_back(op8); 11445 eflags.push_back(op7); 11446 eflags.push_back(op6); 11447 eflags.push_back(op5); 11448 eflags.push_back(op4); 11449 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */ 11450 eflags.push_back(op3); 11451 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */ 11452 eflags.push_back(op2); 11453 eflags.push_back(this->astCtxt->bvfalse()); /* Reserved */ 11454 eflags.push_back(op1); 11455 11456 auto node = this->astCtxt->zx( 11457 dst.getBitSize() - static_cast<triton::uint32>(eflags.size()), 11458 this->astCtxt->concat(eflags) 11459 ); 11460 11461 /* Create symbolic expression */ 11462 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUSHFQ operation"); 11463 11464 /* Spread taint */ 11465 expr->isTainted = this->taintEngine->taintAssignment(dst, src1); 11466 expr->isTainted = this->taintEngine->taintUnion(dst, src2); 11467 expr->isTainted = this->taintEngine->taintUnion(dst, src3); 11468 expr->isTainted = this->taintEngine->taintUnion(dst, src4); 11469 expr->isTainted = this->taintEngine->taintUnion(dst, src5); 11470 expr->isTainted = this->taintEngine->taintUnion(dst, src6); 11471 expr->isTainted = this->taintEngine->taintUnion(dst, src7); 11472 expr->isTainted = this->taintEngine->taintUnion(dst, src8); 11473 expr->isTainted = this->taintEngine->taintUnion(dst, src9); 11474 expr->isTainted = this->taintEngine->taintUnion(dst, src10); 11475 expr->isTainted = this->taintEngine->taintUnion(dst, src11); 11476 expr->isTainted = this->taintEngine->taintUnion(dst, src12); 11477 expr->isTainted = this->taintEngine->taintUnion(dst, src13); 11478 expr->isTainted = this->taintEngine->taintUnion(dst, src14); 11479 11480 /* Update the symbolic control flow */ 11481 this->controlFlow_s(inst); 11482 } 11483 11484 pxor_s(triton::arch::Instruction & inst)11485 void x86Semantics::pxor_s(triton::arch::Instruction& inst) { 11486 auto& dst = inst.operands[0]; 11487 auto& src = inst.operands[1]; 11488 11489 /* Create symbolic operands */ 11490 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 11491 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 11492 11493 /* Create the semantics */ 11494 auto node = this->astCtxt->bvxor(op1, op2); 11495 11496 /* Create symbolic expression */ 11497 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PXOR operation"); 11498 11499 /* Spread taint */ 11500 if (dst.getType() == OP_REG && src.getRegister() == dst.getRegister()) 11501 this->taintEngine->setTaint(src, false); 11502 else 11503 expr->isTainted = this->taintEngine->taintUnion(dst, src); 11504 11505 /* Update the symbolic control flow */ 11506 this->controlFlow_s(inst); 11507 } 11508 11509 rcl_s(triton::arch::Instruction & inst)11510 void x86Semantics::rcl_s(triton::arch::Instruction& inst) { 11511 auto& dst = inst.operands[0]; 11512 auto& src = inst.operands[1]; 11513 auto srcCf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 11514 11515 /* Create symbolic operands */ 11516 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 11517 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 11518 auto op2bis = this->symbolicEngine->getOperandAst(src); 11519 auto op3 = this->symbolicEngine->getOperandAst(inst, srcCf); 11520 11521 switch (dst.getBitSize()) { 11522 /* Mask: 0x1f without MOD */ 11523 case triton::bitsize::qword: 11524 op2 = this->astCtxt->bvand( 11525 op2, 11526 this->astCtxt->bv(triton::bitsize::qword-1, src.getBitSize()) 11527 ); 11528 break; 11529 11530 /* Mask: 0x1f without MOD */ 11531 case triton::bitsize::dword: 11532 op2 = this->astCtxt->bvand( 11533 op2, 11534 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize()) 11535 ); 11536 break; 11537 11538 /* Mask: 0x1f MOD size + 1 */ 11539 case triton::bitsize::word: 11540 case triton::bitsize::byte: 11541 op2 = this->astCtxt->bvsmod( 11542 this->astCtxt->bvand( 11543 op2, 11544 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())), 11545 this->astCtxt->bv(dst.getBitSize()+1, src.getBitSize()) 11546 ); 11547 break; 11548 11549 default: 11550 throw triton::exceptions::Semantics("x86Semantics::rcl_s(): Invalid destination size"); 11551 } 11552 11553 /* Create the semantics */ 11554 auto node1 = this->astCtxt->bvrol( 11555 this->astCtxt->concat(op3, op1), 11556 this->astCtxt->zx(((op1->getBitvectorSize() + op3->getBitvectorSize()) - op2->getBitvectorSize()), op2) 11557 ); 11558 11559 /* Create symbolic expression */ 11560 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "RCL tempory operation"); 11561 11562 /* Spread taint */ 11563 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src); 11564 11565 /* Create the semantics */ 11566 auto node2 = this->astCtxt->extract(dst.getBitSize()-1, 0, node1); 11567 11568 /* Create symbolic expression */ 11569 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "RCL operation"); 11570 11571 /* Spread taint */ 11572 expr2->isTainted = this->taintEngine->taintUnion(dst, src); 11573 expr2->isTainted = this->taintEngine->taintUnion(dst, srcCf); 11574 11575 /* Update symbolic flags */ 11576 this->cfRcl_s(inst, expr2, node1, op2bis); 11577 this->ofRol_s(inst, expr2, dst, op2bis); /* Same as ROL */ 11578 11579 /* Tag undefined flags */ 11580 if (op2->evaluate() > 1) { 11581 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 11582 } 11583 11584 /* Update the symbolic control flow */ 11585 this->controlFlow_s(inst); 11586 } 11587 11588 rcr_s(triton::arch::Instruction & inst)11589 void x86Semantics::rcr_s(triton::arch::Instruction& inst) { 11590 auto& dst = inst.operands[0]; 11591 auto& src = inst.operands[1]; 11592 auto srcCf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 11593 11594 /* Create symbolic operands */ 11595 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 11596 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 11597 auto op3 = this->symbolicEngine->getOperandAst(inst, srcCf); 11598 11599 switch (dst.getBitSize()) { 11600 /* Mask: 0x3f without MOD */ 11601 case triton::bitsize::qword: 11602 op2 = this->astCtxt->bvand( 11603 op2, 11604 this->astCtxt->bv(triton::bitsize::qword-1, src.getBitSize()) 11605 ); 11606 break; 11607 11608 /* Mask: 0x1f without MOD */ 11609 case triton::bitsize::dword: 11610 op2 = this->astCtxt->bvand( 11611 op2, 11612 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize()) 11613 ); 11614 break; 11615 11616 /* Mask: 0x1f MOD size + 1 */ 11617 case triton::bitsize::word: 11618 case triton::bitsize::byte: 11619 op2 = this->astCtxt->bvsmod( 11620 this->astCtxt->bvand( 11621 op2, 11622 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())), 11623 this->astCtxt->bv(dst.getBitSize()+1, src.getBitSize()) 11624 ); 11625 break; 11626 11627 default: 11628 throw triton::exceptions::Semantics("x86Semantics::rcr_s(): Invalid destination size"); 11629 } 11630 11631 /* Create the semantics */ 11632 auto node1 = this->astCtxt->bvror( 11633 this->astCtxt->concat(op3, op1), 11634 this->astCtxt->zx(((op1->getBitvectorSize() + op3->getBitvectorSize()) - op2->getBitvectorSize()), op2) 11635 ); 11636 11637 /* Create symbolic expression */ 11638 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "RCR tempory operation"); 11639 11640 /* Spread taint */ 11641 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src); 11642 11643 /* Create the semantics */ 11644 auto node2 = this->astCtxt->extract(dst.getBitSize()-1, 0, node1); 11645 11646 /* Create symbolic expression */ 11647 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "RCR operation"); 11648 11649 /* Spread taint */ 11650 expr2->isTainted = this->taintEngine->taintUnion(dst, src); 11651 expr2->isTainted = this->taintEngine->taintUnion(dst, srcCf); 11652 11653 /* Update symbolic flags */ 11654 this->ofRcr_s(inst, expr2, dst, op1, op2); /* OF must be set before CF */ 11655 this->cfRcr_s(inst, expr2, dst, node1, op2); 11656 11657 /* Tag undefined flags */ 11658 if (op2->evaluate() > 1) { 11659 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 11660 } 11661 11662 /* Update the symbolic control flow */ 11663 this->controlFlow_s(inst); 11664 } 11665 11666 rdtsc_s(triton::arch::Instruction & inst)11667 void x86Semantics::rdtsc_s(triton::arch::Instruction& inst) { 11668 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EDX)); 11669 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EAX)); 11670 11671 /* Create symbolic operands */ 11672 auto op1 = this->astCtxt->bv(0, dst1.getBitSize()); 11673 auto op2 = this->astCtxt->bv(this->symbolicEngine->getSymbolicExpressions().size(), dst2.getBitSize()); 11674 11675 /* Create symbolic expression */ 11676 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, op1, dst1, "RDTSC EDX operation"); 11677 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, op2, dst2, "RDTSC EAX operation"); 11678 11679 /* Spread taint */ 11680 expr1->isTainted = this->taintEngine->setTaint(dst1, triton::engines::taint::UNTAINTED); 11681 expr2->isTainted = this->taintEngine->setTaint(dst2, triton::engines::taint::UNTAINTED); 11682 11683 /* Update the symbolic control flow */ 11684 this->controlFlow_s(inst); 11685 } 11686 11687 ret_s(triton::arch::Instruction & inst)11688 void x86Semantics::ret_s(triton::arch::Instruction& inst) { 11689 auto stack = this->architecture->getStackPointer(); 11690 auto stackValue = this->architecture->getConcreteRegisterValue(stack).convert_to<triton::uint64>(); 11691 auto pc = triton::arch::OperandWrapper(this->architecture->getProgramCounter()); 11692 auto sp = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, stack.getSize())); 11693 11694 /* Create symbolic operands */ 11695 auto op1 = this->symbolicEngine->getOperandAst(inst, sp); 11696 11697 /* Create the semantics */ 11698 auto node = op1; 11699 11700 /* Create symbolic expression */ 11701 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, pc, "Program Counter"); 11702 11703 /* Spread taint */ 11704 expr->isTainted = this->taintEngine->taintAssignment(pc, sp); 11705 11706 /* Create the semantics - side effect */ 11707 alignAddStack_s(inst, sp.getSize()); 11708 11709 /* Create the semantics - side effect */ 11710 if (inst.operands.size() > 0) { 11711 auto offset = inst.operands[0].getImmediate(); 11712 this->symbolicEngine->getImmediateAst(inst, offset); 11713 alignAddStack_s(inst, static_cast<triton::uint32>(offset.getValue())); 11714 } 11715 11716 /* Create the path constraint */ 11717 this->symbolicEngine->pushPathConstraint(inst, expr); 11718 } 11719 11720 rol_s(triton::arch::Instruction & inst)11721 void x86Semantics::rol_s(triton::arch::Instruction& inst) { 11722 auto& dst = inst.operands[0]; 11723 auto& src = inst.operands[1]; 11724 11725 /* Create symbolic operands */ 11726 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 11727 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 11728 auto op2bis = this->symbolicEngine->getOperandAst(src); 11729 11730 switch (dst.getBitSize()) { 11731 /* Mask 0x3f MOD size */ 11732 case triton::bitsize::qword: 11733 op2 = this->astCtxt->bvsmod( 11734 this->astCtxt->bvand( 11735 op2, 11736 this->astCtxt->bv(triton::bitsize::qword-1, src.getBitSize())), 11737 this->astCtxt->bv(dst.getBitSize(), src.getBitSize()) 11738 ); 11739 11740 op2bis = this->astCtxt->bvand( 11741 op2bis, 11742 this->astCtxt->bv(triton::bitsize::qword-1, src.getBitSize()) 11743 ); 11744 break; 11745 11746 /* Mask 0x1f MOD size */ 11747 case triton::bitsize::dword: 11748 case triton::bitsize::word: 11749 case triton::bitsize::byte: 11750 op2 = this->astCtxt->bvsmod( 11751 this->astCtxt->bvand( 11752 op2, 11753 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())), 11754 this->astCtxt->bv(dst.getBitSize(), src.getBitSize()) 11755 ); 11756 11757 op2bis = this->astCtxt->bvand( 11758 op2bis, 11759 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize()) 11760 ); 11761 break; 11762 11763 default: 11764 throw triton::exceptions::Semantics("x86Semantics::rol_s(): Invalid destination size"); 11765 } 11766 11767 /* Create the semantics */ 11768 auto node = this->astCtxt->bvrol( 11769 op1, 11770 this->astCtxt->zx(op1->getBitvectorSize() - op2->getBitvectorSize(), op2) 11771 ); 11772 11773 /* Create symbolic expression */ 11774 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ROL operation"); 11775 11776 /* Spread taint */ 11777 expr->isTainted = this->taintEngine->taintUnion(dst, src); 11778 11779 /* Update symbolic flags */ 11780 this->cfRol_s(inst, expr, dst, op2bis); 11781 this->ofRol_s(inst, expr, dst, op2bis); 11782 11783 /* Tag undefined flags */ 11784 if (op2->evaluate() > 1) { 11785 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 11786 } 11787 11788 /* Update the symbolic control flow */ 11789 this->controlFlow_s(inst); 11790 } 11791 11792 ror_s(triton::arch::Instruction & inst)11793 void x86Semantics::ror_s(triton::arch::Instruction& inst) { 11794 auto& dst = inst.operands[0]; 11795 auto& src = inst.operands[1]; 11796 11797 /* Create symbolic operands */ 11798 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 11799 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 11800 auto op2bis = this->symbolicEngine->getOperandAst(src); 11801 11802 switch (dst.getBitSize()) { 11803 /* Mask 0x3f MOD size */ 11804 case triton::bitsize::qword: 11805 op2 = this->astCtxt->bvsmod( 11806 this->astCtxt->bvand( 11807 op2, 11808 this->astCtxt->bv(triton::bitsize::qword-1, src.getBitSize())), 11809 this->astCtxt->bv(dst.getBitSize(), src.getBitSize()) 11810 ); 11811 11812 op2bis = this->astCtxt->bvand( 11813 op2bis, 11814 this->astCtxt->bv(triton::bitsize::qword-1, src.getBitSize()) 11815 ); 11816 break; 11817 11818 /* Mask 0x1f MOD size */ 11819 case triton::bitsize::dword: 11820 case triton::bitsize::word: 11821 case triton::bitsize::byte: 11822 op2 = this->astCtxt->bvsmod( 11823 this->astCtxt->bvand( 11824 op2, 11825 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize())), 11826 this->astCtxt->bv(dst.getBitSize(), src.getBitSize()) 11827 ); 11828 11829 op2bis = this->astCtxt->bvand( 11830 op2bis, 11831 this->astCtxt->bv(triton::bitsize::dword-1, src.getBitSize()) 11832 ); 11833 break; 11834 11835 default: 11836 throw triton::exceptions::Semantics("x86Semantics::ror_s(): Invalid destination size"); 11837 } 11838 11839 /* Create the semantics */ 11840 auto node = this->astCtxt->bvror( 11841 op1, 11842 this->astCtxt->zx(op1->getBitvectorSize() - op2->getBitvectorSize(), op2) 11843 ); 11844 11845 /* Create symbolic expression */ 11846 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "ROR operation"); 11847 11848 /* Spread taint */ 11849 expr->isTainted = this->taintEngine->taintUnion(dst, src); 11850 11851 /* Update symbolic flags */ 11852 this->cfRor_s(inst, expr, dst, op2); 11853 this->ofRor_s(inst, expr, dst, op2bis); 11854 11855 /* Tag undefined flags */ 11856 if (op2->evaluate() > 1) { 11857 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 11858 } 11859 11860 /* Update the symbolic control flow */ 11861 this->controlFlow_s(inst); 11862 } 11863 11864 rorx_s(triton::arch::Instruction & inst)11865 void x86Semantics::rorx_s(triton::arch::Instruction& inst) { 11866 auto& dst = inst.operands[0]; 11867 auto& src1 = inst.operands[1]; 11868 auto& src2 = inst.operands[2]; 11869 11870 /* Create symbolic operands */ 11871 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 11872 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 11873 11874 switch (dst.getBitSize()) { 11875 /* Mask 0x3f MOD size */ 11876 case triton::bitsize::qword: 11877 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, src2.getBitSize())); 11878 break; 11879 11880 /* Mask 0x1f MOD size */ 11881 case triton::bitsize::dword: 11882 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, src2.getBitSize())); 11883 break; 11884 11885 default: 11886 throw triton::exceptions::Semantics("x86Semantics::rorx_s(): Invalid destination size"); 11887 } 11888 11889 /* Create the semantics */ 11890 auto node = this->astCtxt->bvror( 11891 op1, 11892 this->astCtxt->zx(op1->getBitvectorSize() - op2->getBitvectorSize(), op2) 11893 ); 11894 11895 /* Create symbolic expression */ 11896 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "RORX operation"); 11897 11898 /* Spread taint */ 11899 expr->isTainted = this->taintEngine->taintAssignment(dst, src1); 11900 expr->isTainted |= this->taintEngine->taintUnion(dst, src2); 11901 11902 /* Update the symbolic control flow */ 11903 this->controlFlow_s(inst); 11904 } 11905 11906 sahf_s(triton::arch::Instruction & inst)11907 void x86Semantics::sahf_s(triton::arch::Instruction& inst) { 11908 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 11909 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 11910 auto dst3 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AF)); 11911 auto dst4 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF)); 11912 auto dst5 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 11913 auto src = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_AH)); 11914 11915 /* Create symbolic operands */ 11916 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 11917 11918 /* Create the semantics */ 11919 auto node1 = this->astCtxt->extract(7, 7, op1); 11920 auto node2 = this->astCtxt->extract(6, 6, op1); 11921 auto node3 = this->astCtxt->extract(4, 4, op1); 11922 auto node4 = this->astCtxt->extract(2, 2, op1); 11923 auto node5 = this->astCtxt->extract(0, 0, op1); 11924 11925 /* Create symbolic expression */ 11926 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1.getRegister(), "SAHF SF operation"); 11927 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2.getRegister(), "SAHF ZF operation"); 11928 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst3.getRegister(), "SAHF AF operation"); 11929 auto expr4 = this->symbolicEngine->createSymbolicExpression(inst, node4, dst4.getRegister(), "SAHF PF operation"); 11930 auto expr5 = this->symbolicEngine->createSymbolicExpression(inst, node5, dst5.getRegister(), "SAHF CF operation"); 11931 11932 /* Spread taint */ 11933 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src); 11934 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src); 11935 expr3->isTainted = this->taintEngine->taintAssignment(dst3, src); 11936 expr4->isTainted = this->taintEngine->taintAssignment(dst4, src); 11937 expr5->isTainted = this->taintEngine->taintAssignment(dst5, src); 11938 11939 /* Update the symbolic control flow */ 11940 this->controlFlow_s(inst); 11941 } 11942 11943 sar_s(triton::arch::Instruction & inst)11944 void x86Semantics::sar_s(triton::arch::Instruction& inst) { 11945 auto& dst = inst.operands[0]; 11946 auto& src = inst.operands[1]; 11947 11948 /* Create symbolic operands */ 11949 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 11950 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src)); 11951 11952 if (dst.getBitSize() == triton::bitsize::qword) 11953 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, dst.getBitSize())); 11954 else 11955 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, dst.getBitSize())); 11956 11957 /* Create the semantics */ 11958 auto node = this->astCtxt->bvashr(op1, op2); 11959 11960 /* Create symbolic expression */ 11961 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SAR operation"); 11962 11963 /* Spread taint */ 11964 expr->isTainted = this->taintEngine->taintUnion(dst, src); 11965 11966 /* Update symbolic flags */ 11967 this->cfSar_s(inst, expr, dst, op1, op2); 11968 this->ofSar_s(inst, expr, dst, op2); 11969 this->pfShl_s(inst, expr, dst, op2); /* Same that shl */ 11970 this->sfShl_s(inst, expr, dst, op2); /* Same that shl */ 11971 this->zfShl_s(inst, expr, dst, op2); /* Same that shl */ 11972 11973 /* Tag undefined flags */ 11974 if (op2->evaluate() != 0) { 11975 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 11976 } 11977 11978 if (op2->evaluate() > 1) { 11979 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 11980 } 11981 11982 /* Update the symbolic control flow */ 11983 this->controlFlow_s(inst); 11984 } 11985 11986 sarx_s(triton::arch::Instruction & inst)11987 void x86Semantics::sarx_s(triton::arch::Instruction& inst) { 11988 auto& dst = inst.operands[0]; 11989 auto& src1 = inst.operands[1]; 11990 auto& src2 = inst.operands[2]; 11991 11992 /* Create symbolic operands */ 11993 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 11994 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 11995 11996 switch (dst.getBitSize()) { 11997 /* Mask 0x3f MOD size */ 11998 case triton::bitsize::qword: 11999 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, src2.getBitSize())); 12000 break; 12001 12002 /* Mask 0x1f MOD size */ 12003 case triton::bitsize::dword: 12004 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, src2.getBitSize())); 12005 break; 12006 12007 default: 12008 throw triton::exceptions::Semantics("x86Semantics::sarx_s(): Invalid destination size"); 12009 } 12010 12011 /* Create the semantics */ 12012 auto node = this->astCtxt->bvashr(op1, op2); 12013 12014 /* Create symbolic expression */ 12015 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SARX operation"); 12016 12017 /* Spread taint */ 12018 expr->isTainted = this->taintEngine->taintAssignment(dst, src1); 12019 expr->isTainted |= this->taintEngine->taintUnion(dst, src2); 12020 12021 /* Update the symbolic control flow */ 12022 this->controlFlow_s(inst); 12023 } 12024 12025 sbb_s(triton::arch::Instruction & inst)12026 void x86Semantics::sbb_s(triton::arch::Instruction& inst) { 12027 auto& dst = inst.operands[0]; 12028 auto& src = inst.operands[1]; 12029 auto srcCf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 12030 12031 /* Create symbolic operands */ 12032 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 12033 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 12034 auto op3 = this->astCtxt->zx(src.getBitSize()-1, this->symbolicEngine->getOperandAst(inst, srcCf)); 12035 12036 /* Create the semantics */ 12037 auto node = this->astCtxt->bvsub(op1, this->astCtxt->bvadd(op2, op3)); 12038 12039 /* Create symbolic expression */ 12040 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SBB operation"); 12041 12042 /* Spread taint */ 12043 expr->isTainted = this->taintEngine->taintUnion(dst, src); 12044 expr->isTainted = this->taintEngine->taintUnion(dst, srcCf); 12045 12046 /* Update symbolic flags */ 12047 this->af_s(inst, expr, dst, op1, op2); 12048 this->cfSub_s(inst, expr, dst, op1, op2); 12049 this->ofSub_s(inst, expr, dst, op1, op2); 12050 this->pf_s(inst, expr, dst); 12051 this->sf_s(inst, expr, dst); 12052 this->zf_s(inst, expr, dst); 12053 12054 /* Update the symbolic control flow */ 12055 this->controlFlow_s(inst); 12056 } 12057 12058 scasb_s(triton::arch::Instruction & inst)12059 void x86Semantics::scasb_s(triton::arch::Instruction& inst) { 12060 auto& dst = inst.operands[0]; 12061 auto& src = inst.operands[1]; 12062 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI)); 12063 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 12064 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 12065 12066 /* If the REP prefix is defined, convert REP into REPE */ 12067 if (inst.getPrefix() == triton::arch::x86::ID_PREFIX_REP) 12068 inst.setPrefix(triton::arch::x86::ID_PREFIX_REPE); 12069 12070 /* Check if there is a REP prefix and a counter to zero */ 12071 auto cnt = this->symbolicEngine->getOperandAst(cx); 12072 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 12073 this->controlFlow_s(inst); 12074 return; 12075 } 12076 12077 /* Create symbolic operands */ 12078 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 12079 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 12080 auto op3 = this->symbolicEngine->getOperandAst(inst, index); 12081 auto op4 = this->symbolicEngine->getOperandAst(inst, df); 12082 12083 /* Create the semantics */ 12084 auto node1 = this->astCtxt->bvsub(op1, op2); 12085 auto node2 = this->astCtxt->ite( 12086 this->astCtxt->equal(op4, this->astCtxt->bvfalse()), 12087 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::byte, index.getBitSize())), 12088 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::byte, index.getBitSize())) 12089 ); 12090 12091 /* Create symbolic expression */ 12092 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "SCASB operation"); 12093 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation"); 12094 12095 /* Spread taint */ 12096 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src); 12097 expr2->isTainted = this->taintEngine->taintUnion(index, index); 12098 12099 /* Update symbolic flags */ 12100 this->af_s(inst, expr1, dst, op1, op2, true); 12101 this->cfSub_s(inst, expr1, dst, op1, op2, true); 12102 this->ofSub_s(inst, expr1, dst, op1, op2, true); 12103 this->pf_s(inst, expr1, dst, true); 12104 this->sf_s(inst, expr1, dst, true); 12105 this->zf_s(inst, expr1, dst, true); 12106 12107 /* Update the symbolic control flow */ 12108 this->controlFlow_s(inst); 12109 } 12110 12111 scasd_s(triton::arch::Instruction & inst)12112 void x86Semantics::scasd_s(triton::arch::Instruction& inst) { 12113 auto& dst = inst.operands[0]; 12114 auto& src = inst.operands[1]; 12115 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI)); 12116 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 12117 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 12118 12119 /* If the REP prefix is defined, convert REP into REPE */ 12120 if (inst.getPrefix() == triton::arch::x86::ID_PREFIX_REP) 12121 inst.setPrefix(triton::arch::x86::ID_PREFIX_REPE); 12122 12123 /* Check if there is a REP prefix and a counter to zero */ 12124 auto cnt = this->symbolicEngine->getOperandAst(cx); 12125 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 12126 this->controlFlow_s(inst); 12127 return; 12128 } 12129 12130 /* Create symbolic operands */ 12131 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 12132 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 12133 auto op3 = this->symbolicEngine->getOperandAst(inst, index); 12134 auto op4 = this->symbolicEngine->getOperandAst(inst, df); 12135 12136 /* Create the semantics */ 12137 auto node1 = this->astCtxt->bvsub(op1, op2); 12138 auto node2 = this->astCtxt->ite( 12139 this->astCtxt->equal(op4, this->astCtxt->bvfalse()), 12140 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::dword, index.getBitSize())), 12141 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::dword, index.getBitSize())) 12142 ); 12143 12144 /* Create symbolic expression */ 12145 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "SCASD operation"); 12146 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation"); 12147 12148 /* Spread taint */ 12149 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src); 12150 expr2->isTainted = this->taintEngine->taintUnion(index, index); 12151 12152 /* Update symbolic flags */ 12153 this->af_s(inst, expr1, dst, op1, op2, true); 12154 this->cfSub_s(inst, expr1, dst, op1, op2, true); 12155 this->ofSub_s(inst, expr1, dst, op1, op2, true); 12156 this->pf_s(inst, expr1, dst, true); 12157 this->sf_s(inst, expr1, dst, true); 12158 this->zf_s(inst, expr1, dst, true); 12159 12160 /* Update the symbolic control flow */ 12161 this->controlFlow_s(inst); 12162 } 12163 12164 scasq_s(triton::arch::Instruction & inst)12165 void x86Semantics::scasq_s(triton::arch::Instruction& inst) { 12166 auto& dst = inst.operands[0]; 12167 auto& src = inst.operands[1]; 12168 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI)); 12169 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 12170 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 12171 12172 /* If the REP prefix is defined, convert REP into REPE */ 12173 if (inst.getPrefix() == triton::arch::x86::ID_PREFIX_REP) 12174 inst.setPrefix(triton::arch::x86::ID_PREFIX_REPE); 12175 12176 /* Check if there is a REP prefix and a counter to zero */ 12177 auto cnt = this->symbolicEngine->getOperandAst(cx); 12178 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 12179 this->controlFlow_s(inst); 12180 return; 12181 } 12182 12183 /* Create symbolic operands */ 12184 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 12185 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 12186 auto op3 = this->symbolicEngine->getOperandAst(inst, index); 12187 auto op4 = this->symbolicEngine->getOperandAst(inst, df); 12188 12189 /* Create the semantics */ 12190 auto node1 = this->astCtxt->bvsub(op1, op2); 12191 auto node2 = this->astCtxt->ite( 12192 this->astCtxt->equal(op4, this->astCtxt->bvfalse()), 12193 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::qword, index.getBitSize())), 12194 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::qword, index.getBitSize())) 12195 ); 12196 12197 /* Create symbolic expression */ 12198 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "SCASQ operation"); 12199 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation"); 12200 12201 /* Spread taint */ 12202 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src); 12203 expr2->isTainted = this->taintEngine->taintUnion(index, index); 12204 12205 /* Update symbolic flags */ 12206 this->af_s(inst, expr1, dst, op1, op2, true); 12207 this->cfSub_s(inst, expr1, dst, op1, op2, true); 12208 this->ofSub_s(inst, expr1, dst, op1, op2, true); 12209 this->pf_s(inst, expr1, dst, true); 12210 this->sf_s(inst, expr1, dst, true); 12211 this->zf_s(inst, expr1, dst, true); 12212 12213 /* Update the symbolic control flow */ 12214 this->controlFlow_s(inst); 12215 } 12216 12217 scasw_s(triton::arch::Instruction & inst)12218 void x86Semantics::scasw_s(triton::arch::Instruction& inst) { 12219 auto& dst = inst.operands[0]; 12220 auto& src = inst.operands[1]; 12221 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI)); 12222 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 12223 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 12224 12225 /* If the REP prefix is defined, convert REP into REPE */ 12226 if (inst.getPrefix() == triton::arch::x86::ID_PREFIX_REP) 12227 inst.setPrefix(triton::arch::x86::ID_PREFIX_REPE); 12228 12229 /* Check if there is a REP prefix and a counter to zero */ 12230 auto cnt = this->symbolicEngine->getOperandAst(cx); 12231 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 12232 this->controlFlow_s(inst); 12233 return; 12234 } 12235 12236 /* Create symbolic operands */ 12237 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 12238 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 12239 auto op3 = this->symbolicEngine->getOperandAst(inst, index); 12240 auto op4 = this->symbolicEngine->getOperandAst(inst, df); 12241 12242 /* Create the semantics */ 12243 auto node1 = this->astCtxt->bvsub(op1, op2); 12244 auto node2 = this->astCtxt->ite( 12245 this->astCtxt->equal(op4, this->astCtxt->bvfalse()), 12246 this->astCtxt->bvadd(op3, this->astCtxt->bv(triton::size::word, index.getBitSize())), 12247 this->astCtxt->bvsub(op3, this->astCtxt->bv(triton::size::word, index.getBitSize())) 12248 ); 12249 12250 /* Create symbolic expression */ 12251 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "SCASW operation"); 12252 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation"); 12253 12254 /* Spread taint */ 12255 expr1->isTainted = this->taintEngine->isTainted(dst) | this->taintEngine->isTainted(src); 12256 expr2->isTainted = this->taintEngine->taintUnion(index, index); 12257 12258 /* Update symbolic flags */ 12259 this->af_s(inst, expr1, dst, op1, op2, true); 12260 this->cfSub_s(inst, expr1, dst, op1, op2, true); 12261 this->ofSub_s(inst, expr1, dst, op1, op2, true); 12262 this->pf_s(inst, expr1, dst, true); 12263 this->sf_s(inst, expr1, dst, true); 12264 this->zf_s(inst, expr1, dst, true); 12265 12266 /* Update the symbolic control flow */ 12267 this->controlFlow_s(inst); 12268 } 12269 12270 seta_s(triton::arch::Instruction & inst)12271 void x86Semantics::seta_s(triton::arch::Instruction& inst) { 12272 auto& dst = inst.operands[0]; 12273 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 12274 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 12275 12276 /* Create symbolic operands */ 12277 auto op2 = this->symbolicEngine->getOperandAst(inst, cf); 12278 auto op3 = this->symbolicEngine->getOperandAst(inst, zf); 12279 12280 /* Create the semantics */ 12281 auto node = this->astCtxt->ite( 12282 this->astCtxt->equal( 12283 this->astCtxt->bvand( 12284 this->astCtxt->bvnot(op2), 12285 this->astCtxt->bvnot(op3) 12286 ), 12287 this->astCtxt->bvtrue() 12288 ), 12289 this->astCtxt->bv(1, dst.getBitSize()), 12290 this->astCtxt->bv(0, dst.getBitSize()) 12291 ); 12292 12293 /* Create symbolic expression */ 12294 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETA operation"); 12295 12296 /* Set condition flag */ 12297 if (op2->evaluate().is_zero() && op3->evaluate().is_zero()) { 12298 inst.setConditionTaken(true); 12299 } 12300 12301 /* Spread taint */ 12302 expr->isTainted = this->taintEngine->taintAssignment(dst, cf); 12303 expr->isTainted = this->taintEngine->taintUnion(dst, zf); 12304 12305 /* Update the symbolic control flow */ 12306 this->controlFlow_s(inst); 12307 } 12308 12309 setae_s(triton::arch::Instruction & inst)12310 void x86Semantics::setae_s(triton::arch::Instruction& inst) { 12311 auto& dst = inst.operands[0]; 12312 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 12313 12314 /* Create symbolic operands */ 12315 auto op2 = this->symbolicEngine->getOperandAst(inst, cf); 12316 12317 /* Create the semantics */ 12318 auto node = this->astCtxt->ite( 12319 this->astCtxt->equal(op2, this->astCtxt->bvfalse()), 12320 this->astCtxt->bv(1, dst.getBitSize()), 12321 this->astCtxt->bv(0, dst.getBitSize()) 12322 ); 12323 12324 /* Create symbolic expression */ 12325 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETAE operation"); 12326 12327 /* Set condition flag */ 12328 if (op2->evaluate().is_zero()) { 12329 inst.setConditionTaken(true); 12330 } 12331 12332 /* Spread taint */ 12333 expr->isTainted = this->taintEngine->taintAssignment(dst, cf); 12334 12335 /* Update the symbolic control flow */ 12336 this->controlFlow_s(inst); 12337 } 12338 12339 setb_s(triton::arch::Instruction & inst)12340 void x86Semantics::setb_s(triton::arch::Instruction& inst) { 12341 auto& dst = inst.operands[0]; 12342 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 12343 12344 /* Create symbolic operands */ 12345 auto op2 = this->symbolicEngine->getOperandAst(inst, cf); 12346 12347 /* Create the semantics */ 12348 auto node = this->astCtxt->ite( 12349 this->astCtxt->equal(op2, this->astCtxt->bvtrue()), 12350 this->astCtxt->bv(1, dst.getBitSize()), 12351 this->astCtxt->bv(0, dst.getBitSize()) 12352 ); 12353 12354 /* Create symbolic expression */ 12355 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETB operation"); 12356 12357 /* Set condition flag */ 12358 if (!op2->evaluate().is_zero()) { 12359 inst.setConditionTaken(true); 12360 } 12361 12362 /* Spread taint */ 12363 expr->isTainted = this->taintEngine->taintAssignment(dst, cf); 12364 12365 /* Update the symbolic control flow */ 12366 this->controlFlow_s(inst); 12367 } 12368 12369 setbe_s(triton::arch::Instruction & inst)12370 void x86Semantics::setbe_s(triton::arch::Instruction& inst) { 12371 auto& dst = inst.operands[0]; 12372 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_CF)); 12373 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 12374 12375 /* Create symbolic operands */ 12376 auto op2 = this->symbolicEngine->getOperandAst(inst, cf); 12377 auto op3 = this->symbolicEngine->getOperandAst(inst, zf); 12378 12379 /* Create the semantics */ 12380 auto node = this->astCtxt->ite( 12381 this->astCtxt->equal(this->astCtxt->bvor(op2, op3), this->astCtxt->bvtrue()), 12382 this->astCtxt->bv(1, dst.getBitSize()), 12383 this->astCtxt->bv(0, dst.getBitSize()) 12384 ); 12385 12386 /* Create symbolic expression */ 12387 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETBE operation"); 12388 12389 /* Set condition flag */ 12390 if (!op2->evaluate().is_zero() || !op3->evaluate().is_zero()) { 12391 inst.setConditionTaken(true); 12392 } 12393 12394 /* Spread taint */ 12395 expr->isTainted = this->taintEngine->taintAssignment(dst, cf); 12396 expr->isTainted = this->taintEngine->taintUnion(dst, zf); 12397 12398 /* Update the symbolic control flow */ 12399 this->controlFlow_s(inst); 12400 } 12401 12402 sete_s(triton::arch::Instruction & inst)12403 void x86Semantics::sete_s(triton::arch::Instruction& inst) { 12404 auto& dst = inst.operands[0]; 12405 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 12406 12407 /* Create symbolic operands */ 12408 auto op2 = this->symbolicEngine->getOperandAst(inst, zf); 12409 12410 /* Create the semantics */ 12411 auto node = this->astCtxt->ite( 12412 this->astCtxt->equal(op2, this->astCtxt->bvtrue()), 12413 this->astCtxt->bv(1, dst.getBitSize()), 12414 this->astCtxt->bv(0, dst.getBitSize()) 12415 ); 12416 12417 /* Create symbolic expression */ 12418 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETE operation"); 12419 12420 /* Set condition flag */ 12421 if (!op2->evaluate().is_zero()) { 12422 inst.setConditionTaken(true); 12423 } 12424 12425 /* Spread taint */ 12426 expr->isTainted = this->taintEngine->taintAssignment(dst, zf); 12427 12428 /* Update the symbolic control flow */ 12429 this->controlFlow_s(inst); 12430 } 12431 12432 setg_s(triton::arch::Instruction & inst)12433 void x86Semantics::setg_s(triton::arch::Instruction& inst) { 12434 auto& dst = inst.operands[0]; 12435 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 12436 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 12437 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 12438 12439 /* Create symbolic operands */ 12440 auto op2 = this->symbolicEngine->getOperandAst(inst, sf); 12441 auto op3 = this->symbolicEngine->getOperandAst(inst, of); 12442 auto op4 = this->symbolicEngine->getOperandAst(inst, zf); 12443 12444 /* Create the semantics */ 12445 auto node = this->astCtxt->ite( 12446 this->astCtxt->equal(this->astCtxt->bvor(this->astCtxt->bvxor(op2, op3), op4), this->astCtxt->bvfalse()), 12447 this->astCtxt->bv(1, dst.getBitSize()), 12448 this->astCtxt->bv(0, dst.getBitSize()) 12449 ); 12450 12451 /* Create symbolic expression */ 12452 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETG operation"); 12453 12454 /* Set condition flag */ 12455 if ((op2->evaluate().is_zero() == op3->evaluate().is_zero()) && op4->evaluate().is_zero()) { 12456 inst.setConditionTaken(true); 12457 } 12458 12459 /* Spread taint */ 12460 expr->isTainted = this->taintEngine->taintAssignment(dst, sf); 12461 expr->isTainted = this->taintEngine->taintUnion(dst, of); 12462 expr->isTainted = this->taintEngine->taintUnion(dst, zf); 12463 12464 /* Update the symbolic control flow */ 12465 this->controlFlow_s(inst); 12466 } 12467 12468 setge_s(triton::arch::Instruction & inst)12469 void x86Semantics::setge_s(triton::arch::Instruction& inst) { 12470 auto& dst = inst.operands[0]; 12471 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 12472 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 12473 12474 /* Create symbolic operands */ 12475 auto op2 = this->symbolicEngine->getOperandAst(inst, sf); 12476 auto op3 = this->symbolicEngine->getOperandAst(inst, of); 12477 12478 /* Create the semantics */ 12479 auto node = this->astCtxt->ite( 12480 this->astCtxt->equal(op2, op3), 12481 this->astCtxt->bv(1, dst.getBitSize()), 12482 this->astCtxt->bv(0, dst.getBitSize()) 12483 ); 12484 12485 /* Create symbolic expression */ 12486 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETGE operation"); 12487 12488 /* Set condition flag */ 12489 if (op2->evaluate().is_zero() == op3->evaluate().is_zero()) { 12490 inst.setConditionTaken(true); 12491 } 12492 12493 /* Spread taint */ 12494 expr->isTainted = this->taintEngine->taintAssignment(dst, sf); 12495 expr->isTainted = this->taintEngine->taintUnion(dst, of); 12496 12497 /* Update the symbolic control flow */ 12498 this->controlFlow_s(inst); 12499 } 12500 12501 setl_s(triton::arch::Instruction & inst)12502 void x86Semantics::setl_s(triton::arch::Instruction& inst) { 12503 auto& dst = inst.operands[0]; 12504 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 12505 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 12506 12507 /* Create symbolic operands */ 12508 auto op2 = this->symbolicEngine->getOperandAst(inst, sf); 12509 auto op3 = this->symbolicEngine->getOperandAst(inst, of); 12510 12511 /* Create the semantics */ 12512 auto node = this->astCtxt->ite( 12513 this->astCtxt->equal(this->astCtxt->bvxor(op2, op3), this->astCtxt->bvtrue()), 12514 this->astCtxt->bv(1, dst.getBitSize()), 12515 this->astCtxt->bv(0, dst.getBitSize()) 12516 ); 12517 12518 /* Create symbolic expression */ 12519 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETL operation"); 12520 12521 /* Set condition flag */ 12522 if (op2->evaluate().is_zero() != op3->evaluate().is_zero()) { 12523 inst.setConditionTaken(true); 12524 } 12525 12526 /* Spread taint */ 12527 expr->isTainted = this->taintEngine->taintAssignment(dst, sf); 12528 expr->isTainted = this->taintEngine->taintUnion(dst, of); 12529 12530 /* Update the symbolic control flow */ 12531 this->controlFlow_s(inst); 12532 } 12533 12534 setle_s(triton::arch::Instruction & inst)12535 void x86Semantics::setle_s(triton::arch::Instruction& inst) { 12536 auto& dst = inst.operands[0]; 12537 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 12538 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 12539 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 12540 12541 /* Create symbolic operands */ 12542 auto op2 = this->symbolicEngine->getOperandAst(inst, sf); 12543 auto op3 = this->symbolicEngine->getOperandAst(inst, of); 12544 auto op4 = this->symbolicEngine->getOperandAst(inst, zf); 12545 12546 /* Create the semantics */ 12547 auto node = this->astCtxt->ite( 12548 this->astCtxt->equal(this->astCtxt->bvor(this->astCtxt->bvxor(op2, op3), op4), this->astCtxt->bvtrue()), 12549 this->astCtxt->bv(1, dst.getBitSize()), 12550 this->astCtxt->bv(0, dst.getBitSize()) 12551 ); 12552 12553 /* Create symbolic expression */ 12554 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETLE operation"); 12555 12556 /* Set condition flag */ 12557 if ((op2->evaluate().is_zero() != op3->evaluate().is_zero()) || !op4->evaluate().is_zero()) { 12558 inst.setConditionTaken(true); 12559 } 12560 12561 /* Spread taint */ 12562 expr->isTainted = this->taintEngine->taintAssignment(dst, sf); 12563 expr->isTainted = this->taintEngine->taintUnion(dst, of); 12564 expr->isTainted = this->taintEngine->taintUnion(dst, zf); 12565 12566 /* Update the symbolic control flow */ 12567 this->controlFlow_s(inst); 12568 } 12569 12570 setne_s(triton::arch::Instruction & inst)12571 void x86Semantics::setne_s(triton::arch::Instruction& inst) { 12572 auto& dst = inst.operands[0]; 12573 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_ZF)); 12574 12575 /* Create symbolic operands */ 12576 auto op2 = this->symbolicEngine->getOperandAst(inst, zf); 12577 12578 /* Create the semantics */ 12579 auto node = this->astCtxt->ite( 12580 this->astCtxt->equal(op2, this->astCtxt->bvfalse()), 12581 this->astCtxt->bv(1, dst.getBitSize()), 12582 this->astCtxt->bv(0, dst.getBitSize()) 12583 ); 12584 12585 /* Create symbolic expression */ 12586 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETNE operation"); 12587 12588 /* Set condition flag */ 12589 if (op2->evaluate().is_zero()) { 12590 inst.setConditionTaken(true); 12591 } 12592 12593 /* Spread taint */ 12594 expr->isTainted = this->taintEngine->taintAssignment(dst, zf); 12595 12596 /* Update the symbolic control flow */ 12597 this->controlFlow_s(inst); 12598 } 12599 12600 setno_s(triton::arch::Instruction & inst)12601 void x86Semantics::setno_s(triton::arch::Instruction& inst) { 12602 auto& dst = inst.operands[0]; 12603 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 12604 12605 /* Create symbolic operands */ 12606 auto op2 = this->symbolicEngine->getOperandAst(inst, of); 12607 12608 /* Create the semantics */ 12609 auto node = this->astCtxt->ite( 12610 this->astCtxt->equal(op2, this->astCtxt->bvfalse()), 12611 this->astCtxt->bv(1, dst.getBitSize()), 12612 this->astCtxt->bv(0, dst.getBitSize()) 12613 ); 12614 12615 /* Create symbolic expression */ 12616 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETNO operation"); 12617 12618 /* Set condition flag */ 12619 if (op2->evaluate().is_zero()) { 12620 inst.setConditionTaken(true); 12621 } 12622 12623 /* Spread taint */ 12624 expr->isTainted = this->taintEngine->taintAssignment(dst, of); 12625 12626 /* Update the symbolic control flow */ 12627 this->controlFlow_s(inst); 12628 } 12629 12630 setnp_s(triton::arch::Instruction & inst)12631 void x86Semantics::setnp_s(triton::arch::Instruction& inst) { 12632 auto& dst = inst.operands[0]; 12633 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF)); 12634 12635 /* Create symbolic operands */ 12636 auto op2 = this->symbolicEngine->getOperandAst(inst, pf); 12637 12638 /* Create the semantics */ 12639 auto node = this->astCtxt->ite( 12640 this->astCtxt->equal(op2, this->astCtxt->bvfalse()), 12641 this->astCtxt->bv(1, dst.getBitSize()), 12642 this->astCtxt->bv(0, dst.getBitSize()) 12643 ); 12644 12645 /* Create symbolic expression */ 12646 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETNP operation"); 12647 12648 /* Set condition flag */ 12649 if (op2->evaluate().is_zero()) { 12650 inst.setConditionTaken(true); 12651 } 12652 12653 /* Spread taint */ 12654 expr->isTainted = this->taintEngine->taintAssignment(dst, pf); 12655 12656 /* Update the symbolic control flow */ 12657 this->controlFlow_s(inst); 12658 } 12659 12660 setns_s(triton::arch::Instruction & inst)12661 void x86Semantics::setns_s(triton::arch::Instruction& inst) { 12662 auto& dst = inst.operands[0]; 12663 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 12664 12665 /* Create symbolic operands */ 12666 auto op2 = this->symbolicEngine->getOperandAst(inst, sf); 12667 12668 /* Create the semantics */ 12669 auto node = this->astCtxt->ite( 12670 this->astCtxt->equal(op2, this->astCtxt->bvfalse()), 12671 this->astCtxt->bv(1, dst.getBitSize()), 12672 this->astCtxt->bv(0, dst.getBitSize()) 12673 ); 12674 12675 /* Create symbolic expression */ 12676 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETNS operation"); 12677 12678 /* Set condition flag */ 12679 if (op2->evaluate().is_zero()) { 12680 inst.setConditionTaken(true); 12681 } 12682 12683 /* Spread taint */ 12684 expr->isTainted = this->taintEngine->taintAssignment(dst, sf); 12685 12686 /* Update the symbolic control flow */ 12687 this->controlFlow_s(inst); 12688 } 12689 12690 seto_s(triton::arch::Instruction & inst)12691 void x86Semantics::seto_s(triton::arch::Instruction& inst) { 12692 auto& dst = inst.operands[0]; 12693 auto of = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_OF)); 12694 12695 /* Create symbolic operands */ 12696 auto op2 = this->symbolicEngine->getOperandAst(inst, of); 12697 12698 /* Create the semantics */ 12699 auto node = this->astCtxt->ite( 12700 this->astCtxt->equal(op2, this->astCtxt->bvtrue()), 12701 this->astCtxt->bv(1, dst.getBitSize()), 12702 this->astCtxt->bv(0, dst.getBitSize()) 12703 ); 12704 12705 /* Create symbolic expression */ 12706 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETO operation"); 12707 12708 /* Set condition flag */ 12709 if (!op2->evaluate().is_zero()) { 12710 inst.setConditionTaken(true); 12711 } 12712 12713 /* Spread taint */ 12714 expr->isTainted = this->taintEngine->taintAssignment(dst, of); 12715 12716 /* Update the symbolic control flow */ 12717 this->controlFlow_s(inst); 12718 } 12719 12720 setp_s(triton::arch::Instruction & inst)12721 void x86Semantics::setp_s(triton::arch::Instruction& inst) { 12722 auto& dst = inst.operands[0]; 12723 auto pf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_PF)); 12724 12725 /* Create symbolic operands */ 12726 auto op2 = this->symbolicEngine->getOperandAst(inst, pf); 12727 12728 /* Create the semantics */ 12729 auto node = this->astCtxt->ite( 12730 this->astCtxt->equal(op2, this->astCtxt->bvtrue()), 12731 this->astCtxt->bv(1, dst.getBitSize()), 12732 this->astCtxt->bv(0, dst.getBitSize()) 12733 ); 12734 12735 /* Create symbolic expression */ 12736 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETP operation"); 12737 12738 /* Set condition flag */ 12739 if (!op2->evaluate().is_zero()) { 12740 inst.setConditionTaken(true); 12741 } 12742 12743 /* Spread taint */ 12744 expr->isTainted = this->taintEngine->taintAssignment(dst, pf); 12745 12746 /* Update the symbolic control flow */ 12747 this->controlFlow_s(inst); 12748 } 12749 12750 sets_s(triton::arch::Instruction & inst)12751 void x86Semantics::sets_s(triton::arch::Instruction& inst) { 12752 auto& dst = inst.operands[0]; 12753 auto sf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_SF)); 12754 12755 /* Create symbolic operands */ 12756 auto op2 = this->symbolicEngine->getOperandAst(inst, sf); 12757 12758 /* Create the semantics */ 12759 auto node = this->astCtxt->ite( 12760 this->astCtxt->equal(op2, this->astCtxt->bvtrue()), 12761 this->astCtxt->bv(1, dst.getBitSize()), 12762 this->astCtxt->bv(0, dst.getBitSize()) 12763 ); 12764 12765 /* Create symbolic expression */ 12766 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SETS operation"); 12767 12768 /* Set condition flag */ 12769 if (!op2->evaluate().is_zero()) { 12770 inst.setConditionTaken(true); 12771 } 12772 12773 /* Spread taint */ 12774 expr->isTainted = this->taintEngine->taintAssignment(dst, sf); 12775 12776 /* Update the symbolic control flow */ 12777 this->controlFlow_s(inst); 12778 } 12779 12780 sfence_s(triton::arch::Instruction & inst)12781 void x86Semantics::sfence_s(triton::arch::Instruction& inst) { 12782 /* Update the symbolic control flow */ 12783 this->controlFlow_s(inst); 12784 } 12785 12786 shl_s(triton::arch::Instruction & inst)12787 void x86Semantics::shl_s(triton::arch::Instruction& inst) { 12788 auto& dst = inst.operands[0]; 12789 auto& src = inst.operands[1]; 12790 12791 /* Create symbolic operands */ 12792 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 12793 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src)); 12794 auto op2bis = op2; 12795 12796 if (dst.getBitSize() == triton::bitsize::qword) 12797 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, dst.getBitSize())); 12798 else 12799 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, dst.getBitSize())); 12800 12801 /* Create the semantics */ 12802 auto node = this->astCtxt->bvshl(op1, op2); 12803 12804 /* Create symbolic expression */ 12805 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SHL operation"); 12806 12807 /* Spread taint */ 12808 expr->isTainted = this->taintEngine->taintUnion(dst, src); 12809 12810 /* Update symbolic flags */ 12811 this->cfShl_s(inst, expr, dst, op1, op2); 12812 this->ofShl_s(inst, expr, dst, op1, op2); 12813 this->pfShl_s(inst, expr, dst, op2); 12814 this->sfShl_s(inst, expr, dst, op2); 12815 this->zfShl_s(inst, expr, dst, op2); 12816 12817 /* Tag undefined flags */ 12818 if (op2->evaluate() != 0) { 12819 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 12820 } 12821 12822 if (op2bis->evaluate() > dst.getBitSize()) { 12823 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF)); 12824 } 12825 12826 if (op2->evaluate() > 1) { 12827 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 12828 } 12829 12830 /* Update the symbolic control flow */ 12831 this->controlFlow_s(inst); 12832 } 12833 12834 shld_s(triton::arch::Instruction & inst)12835 void x86Semantics::shld_s(triton::arch::Instruction& inst) { 12836 auto& dst = inst.operands[0]; 12837 auto& src1 = inst.operands[1]; 12838 auto& src2 = inst.operands[2]; 12839 12840 /* Create symbolic operands */ 12841 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 12842 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 12843 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 12844 auto op3bis = op3; 12845 12846 switch (dst.getBitSize()) { 12847 /* Mask 0x3f MOD size */ 12848 case triton::bitsize::qword: 12849 op3 = this->astCtxt->bvsmod( 12850 this->astCtxt->bvand( 12851 op3, 12852 this->astCtxt->bv(triton::bitsize::qword-1, src2.getBitSize())), 12853 this->astCtxt->bv(dst.getBitSize(), src2.getBitSize()) 12854 ); 12855 break; 12856 12857 /* Mask 0x1f MOD size */ 12858 case triton::bitsize::dword: 12859 case triton::bitsize::word: 12860 op3 = this->astCtxt->bvsmod( 12861 this->astCtxt->bvand( 12862 op3, 12863 this->astCtxt->bv(triton::bitsize::dword-1, src2.getBitSize())), 12864 this->astCtxt->bv(triton::bitsize::dword, src2.getBitSize()) 12865 ); 12866 break; 12867 12868 default: 12869 throw triton::exceptions::Semantics("x86Semantics::shld_s(): Invalid destination size"); 12870 } 12871 12872 /* Create the semantics */ 12873 auto node = this->astCtxt->extract( 12874 dst.getBitSize()-1, 0, 12875 this->astCtxt->bvrol( 12876 this->astCtxt->concat(op2, op1), 12877 this->astCtxt->zx(((op1->getBitvectorSize() + op2->getBitvectorSize()) - op3->getBitvectorSize()), op3) 12878 ) 12879 ); 12880 12881 /* Create symbolic expression */ 12882 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SHLD operation"); 12883 12884 /* Spread taint */ 12885 expr->isTainted = this->taintEngine->taintAssignment(dst, src1); 12886 expr->isTainted |= this->taintEngine->taintUnion(dst, src2); 12887 12888 /* Update symbolic flags */ 12889 this->cfShld_s(inst, expr, dst, op1, op2, op3); 12890 this->ofShld_s(inst, expr, dst, op1, op2, op3); 12891 this->pfShl_s(inst, expr, dst, op3); /* Same that shl */ 12892 this->sfShld_s(inst, expr, dst, op1, op2, op3); 12893 this->zfShl_s(inst, expr, dst, op3); /* Same that shl */ 12894 12895 /* Tag undefined flags */ 12896 if (op3->evaluate() != 0) { 12897 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 12898 } 12899 12900 if (op3->evaluate() > 1) { 12901 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 12902 } 12903 12904 if (op3bis->evaluate() > dst.getBitSize()) { 12905 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 12906 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF)); 12907 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 12908 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF)); 12909 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF)); 12910 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF)); 12911 if (dst.getType() == triton::arch::OP_REG) 12912 this->undefined_s(inst, dst.getRegister()); 12913 } 12914 12915 /* Update the symbolic control flow */ 12916 this->controlFlow_s(inst); 12917 } 12918 12919 shlx_s(triton::arch::Instruction & inst)12920 void x86Semantics::shlx_s(triton::arch::Instruction& inst) { 12921 auto& dst = inst.operands[0]; 12922 auto& src1 = inst.operands[1]; 12923 auto& src2 = inst.operands[2]; 12924 12925 /* Create symbolic operands */ 12926 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 12927 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 12928 12929 switch (dst.getBitSize()) { 12930 /* Mask 0x3f MOD size */ 12931 case triton::bitsize::qword: 12932 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, src2.getBitSize())); 12933 break; 12934 12935 /* Mask 0x1f MOD size */ 12936 case triton::bitsize::dword: 12937 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, src2.getBitSize())); 12938 break; 12939 12940 default: 12941 throw triton::exceptions::Semantics("x86Semantics::shlx_s(): Invalid destination size"); 12942 } 12943 12944 /* Create the semantics */ 12945 auto node = this->astCtxt->bvshl(op1, op2); 12946 12947 /* Create symbolic expression */ 12948 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SHLX operation"); 12949 12950 /* Spread taint */ 12951 expr->isTainted = this->taintEngine->taintAssignment(dst, src1); 12952 expr->isTainted |= this->taintEngine->taintUnion(dst, src2); 12953 12954 /* Update the symbolic control flow */ 12955 this->controlFlow_s(inst); 12956 } 12957 12958 shr_s(triton::arch::Instruction & inst)12959 void x86Semantics::shr_s(triton::arch::Instruction& inst) { 12960 auto& dst = inst.operands[0]; 12961 auto& src = inst.operands[1]; 12962 12963 /* Create symbolic operands */ 12964 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 12965 auto op2 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), this->symbolicEngine->getOperandAst(inst, src)); 12966 auto op2bis = op2; 12967 12968 if (dst.getBitSize() == triton::bitsize::qword) 12969 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, dst.getBitSize())); 12970 else 12971 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, dst.getBitSize())); 12972 12973 /* Create the semantics */ 12974 auto node = this->astCtxt->bvlshr(op1, op2); 12975 12976 /* Create symbolic expression */ 12977 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SHR operation"); 12978 12979 /* Spread taint */ 12980 expr->isTainted = this->taintEngine->taintUnion(dst, src); 12981 12982 /* Update symbolic flags */ 12983 this->cfShr_s(inst, expr, dst, op1, op2); 12984 this->ofShr_s(inst, expr, dst, op1, op2); 12985 this->pfShl_s(inst, expr, dst, op2); /* Same that shl */ 12986 this->sfShl_s(inst, expr, dst, op2); /* Same that shl */ 12987 this->zfShl_s(inst, expr, dst, op2); /* Same that shl */ 12988 12989 /* Tag undefined flags */ 12990 if (op2->evaluate() != 0) { 12991 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 12992 } 12993 12994 if (op2bis->evaluate() > dst.getBitSize()) { 12995 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF)); 12996 } 12997 12998 if (op2->evaluate() > 1) { 12999 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 13000 } 13001 13002 /* Update the symbolic control flow */ 13003 this->controlFlow_s(inst); 13004 } 13005 13006 shrd_s(triton::arch::Instruction & inst)13007 void x86Semantics::shrd_s(triton::arch::Instruction& inst) { 13008 auto& dst = inst.operands[0]; 13009 auto& src1 = inst.operands[1]; 13010 auto& src2 = inst.operands[2]; 13011 13012 /* Create symbolic operands */ 13013 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 13014 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 13015 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 13016 auto op3bis = op3; 13017 13018 switch (dst.getBitSize()) { 13019 /* Mask 0x3f MOD size */ 13020 case triton::bitsize::qword: 13021 op3 = this->astCtxt->bvsmod( 13022 this->astCtxt->bvand( 13023 op3, 13024 this->astCtxt->bv(triton::bitsize::qword-1, src2.getBitSize())), 13025 this->astCtxt->bv(dst.getBitSize(), src2.getBitSize()) 13026 ); 13027 break; 13028 13029 /* Mask 0x1f MOD size */ 13030 case triton::bitsize::dword: 13031 case triton::bitsize::word: 13032 op3 = this->astCtxt->bvsmod( 13033 this->astCtxt->bvand( 13034 op3, 13035 this->astCtxt->bv(triton::bitsize::dword-1, src2.getBitSize())), 13036 this->astCtxt->bv(triton::bitsize::dword, src2.getBitSize()) 13037 ); 13038 break; 13039 13040 default: 13041 throw triton::exceptions::Semantics("x86Semantics::shrd_s(): Invalid destination size"); 13042 } 13043 13044 /* Create the semantics */ 13045 auto node = this->astCtxt->extract( 13046 dst.getBitSize()-1, 0, 13047 this->astCtxt->bvror( 13048 this->astCtxt->concat(op2, op1), 13049 this->astCtxt->zx(((op1->getBitvectorSize() + op2->getBitvectorSize()) - op3->getBitvectorSize()), op3) 13050 ) 13051 ); 13052 13053 /* Create symbolic expression */ 13054 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SHRD operation"); 13055 13056 /* Spread taint */ 13057 expr->isTainted = this->taintEngine->taintAssignment(dst, src1); 13058 expr->isTainted |= this->taintEngine->taintUnion(dst, src2); 13059 13060 /* Update symbolic flags */ 13061 this->cfShrd_s(inst, expr, dst, op1, op2, op3); 13062 this->ofShrd_s(inst, expr, dst, op1, op2, op3); 13063 this->pfShl_s(inst, expr, dst, op3); /* Same that shl */ 13064 this->sfShrd_s(inst, expr, dst, op1, op2, op3); 13065 this->zfShl_s(inst, expr, dst, op3); /* Same that shl */ 13066 13067 /* Tag undefined flags */ 13068 if (op3->evaluate() != 0) { 13069 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 13070 } 13071 13072 if (op3->evaluate() > 1) { 13073 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 13074 } 13075 13076 if (op3bis->evaluate() > dst.getBitSize()) { 13077 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 13078 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_CF)); 13079 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 13080 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF)); 13081 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF)); 13082 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_ZF)); 13083 if (dst.getType() == triton::arch::OP_REG) 13084 this->undefined_s(inst, dst.getRegister()); 13085 } 13086 13087 /* Update the symbolic control flow */ 13088 this->controlFlow_s(inst); 13089 } 13090 13091 shrx_s(triton::arch::Instruction & inst)13092 void x86Semantics::shrx_s(triton::arch::Instruction& inst) { 13093 auto& dst = inst.operands[0]; 13094 auto& src1 = inst.operands[1]; 13095 auto& src2 = inst.operands[2]; 13096 13097 /* Create symbolic operands */ 13098 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 13099 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 13100 13101 switch (dst.getBitSize()) { 13102 /* Mask 0x3f MOD size */ 13103 case triton::bitsize::qword: 13104 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::qword-1, src2.getBitSize())); 13105 break; 13106 13107 /* Mask 0x1f MOD size */ 13108 case triton::bitsize::dword: 13109 op2 = this->astCtxt->bvand(op2, this->astCtxt->bv(triton::bitsize::dword-1, src2.getBitSize())); 13110 break; 13111 13112 default: 13113 throw triton::exceptions::Semantics("x86Semantics::shrx_s(): Invalid destination size"); 13114 } 13115 13116 /* Create the semantics */ 13117 auto node = this->astCtxt->bvlshr(op1, op2); 13118 13119 /* Create symbolic expression */ 13120 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SHRX operation"); 13121 13122 /* Spread taint */ 13123 expr->isTainted = this->taintEngine->taintAssignment(dst, src1); 13124 expr->isTainted |= this->taintEngine->taintUnion(dst, src2); 13125 13126 /* Update the symbolic control flow */ 13127 this->controlFlow_s(inst); 13128 } 13129 13130 stc_s(triton::arch::Instruction & inst)13131 void x86Semantics::stc_s(triton::arch::Instruction& inst) { 13132 this->setFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Sets carry flag"); 13133 /* Update the symbolic control flow */ 13134 this->controlFlow_s(inst); 13135 } 13136 13137 std_s(triton::arch::Instruction & inst)13138 void x86Semantics::std_s(triton::arch::Instruction& inst) { 13139 this->setFlag_s(inst, this->architecture->getRegister(ID_REG_X86_DF), "Sets direction flag"); 13140 /* Update the symbolic control flow */ 13141 this->controlFlow_s(inst); 13142 } 13143 13144 sti_s(triton::arch::Instruction & inst)13145 void x86Semantics::sti_s(triton::arch::Instruction& inst) { 13146 this->setFlag_s(inst, this->architecture->getRegister(ID_REG_X86_IF), "Sets interrupt flag"); 13147 /* Update the symbolic control flow */ 13148 this->controlFlow_s(inst); 13149 } 13150 13151 stmxcsr_s(triton::arch::Instruction & inst)13152 void x86Semantics::stmxcsr_s(triton::arch::Instruction& inst) { 13153 auto& dst = inst.operands[0]; 13154 auto src = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_MXCSR)); 13155 13156 /* Create symbolic operands */ 13157 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 13158 13159 /* Create the semantics */ 13160 auto node = this->astCtxt->extract(triton::bitsize::dword-1, 0, op2); 13161 13162 /* Create symbolic expression */ 13163 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "STMXCSR operation"); 13164 13165 /* Spread taint */ 13166 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 13167 13168 /* Update the symbolic control flow */ 13169 this->controlFlow_s(inst); 13170 } 13171 13172 stosb_s(triton::arch::Instruction & inst)13173 void x86Semantics::stosb_s(triton::arch::Instruction& inst) { 13174 auto& dst = inst.operands[0]; 13175 auto& src = inst.operands[1]; 13176 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI)); 13177 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 13178 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 13179 13180 /* Check if there is a REP prefix and a counter to zero */ 13181 auto cnt = this->symbolicEngine->getOperandAst(cx); 13182 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 13183 this->controlFlow_s(inst); 13184 return; 13185 } 13186 13187 /* Create symbolic operands */ 13188 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 13189 auto op2 = this->symbolicEngine->getOperandAst(inst, index); 13190 auto op3 = this->symbolicEngine->getOperandAst(inst, df); 13191 13192 /* Create the semantics */ 13193 auto node1 = op1; 13194 auto node2 = this->astCtxt->ite( 13195 this->astCtxt->equal(op3, this->astCtxt->bvfalse()), 13196 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::byte, index.getBitSize())), 13197 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::byte, index.getBitSize())) 13198 ); 13199 13200 /* Create symbolic expression */ 13201 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "STOSB operation"); 13202 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation"); 13203 13204 /* Spread taint */ 13205 expr1->isTainted = this->taintEngine->taintAssignment(dst, src); 13206 expr2->isTainted = this->taintEngine->taintUnion(index, index); 13207 13208 /* Update the symbolic control flow */ 13209 this->controlFlow_s(inst); 13210 } 13211 13212 stosd_s(triton::arch::Instruction & inst)13213 void x86Semantics::stosd_s(triton::arch::Instruction& inst) { 13214 auto& dst = inst.operands[0]; 13215 auto& src = inst.operands[1]; 13216 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI)); 13217 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 13218 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 13219 13220 /* Check if there is a REP prefix and a counter to zero */ 13221 auto cnt = this->symbolicEngine->getOperandAst(cx); 13222 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 13223 this->controlFlow_s(inst); 13224 return; 13225 } 13226 13227 /* Create symbolic operands */ 13228 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 13229 auto op2 = this->symbolicEngine->getOperandAst(inst, index); 13230 auto op3 = this->symbolicEngine->getOperandAst(inst, df); 13231 13232 /* Create the semantics */ 13233 auto node1 = op1; 13234 auto node2 = this->astCtxt->ite( 13235 this->astCtxt->equal(op3, this->astCtxt->bvfalse()), 13236 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::dword, index.getBitSize())), 13237 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::dword, index.getBitSize())) 13238 ); 13239 13240 /* Create symbolic expression */ 13241 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "STOSD operation"); 13242 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation"); 13243 13244 /* Spread taint */ 13245 expr1->isTainted = this->taintEngine->taintAssignment(dst, src); 13246 expr2->isTainted = this->taintEngine->taintUnion(index, index); 13247 13248 /* Update the symbolic control flow */ 13249 this->controlFlow_s(inst); 13250 } 13251 13252 stosq_s(triton::arch::Instruction & inst)13253 void x86Semantics::stosq_s(triton::arch::Instruction& inst) { 13254 auto& dst = inst.operands[0]; 13255 auto& src = inst.operands[1]; 13256 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI)); 13257 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 13258 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 13259 13260 /* Check if there is a REP prefix and a counter to zero */ 13261 auto cnt = this->symbolicEngine->getOperandAst(cx); 13262 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 13263 this->controlFlow_s(inst); 13264 return; 13265 } 13266 13267 /* Create symbolic operands */ 13268 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 13269 auto op2 = this->symbolicEngine->getOperandAst(inst, index); 13270 auto op3 = this->symbolicEngine->getOperandAst(inst, df); 13271 13272 /* Create the semantics */ 13273 auto node1 = op1; 13274 auto node2 = this->astCtxt->ite( 13275 this->astCtxt->equal(op3, this->astCtxt->bvfalse()), 13276 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::qword, index.getBitSize())), 13277 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::qword, index.getBitSize())) 13278 ); 13279 13280 /* Create symbolic expression */ 13281 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "STOSQ operation"); 13282 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation"); 13283 13284 /* Spread taint */ 13285 expr1->isTainted = this->taintEngine->taintAssignment(dst, src); 13286 expr2->isTainted = this->taintEngine->taintUnion(index, index); 13287 13288 /* Update the symbolic control flow */ 13289 this->controlFlow_s(inst); 13290 } 13291 13292 stosw_s(triton::arch::Instruction & inst)13293 void x86Semantics::stosw_s(triton::arch::Instruction& inst) { 13294 auto& dst = inst.operands[0]; 13295 auto& src = inst.operands[1]; 13296 auto index = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_DI)); 13297 auto cx = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_X86_CX)); 13298 auto df = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_DF)); 13299 13300 /* Check if there is a REP prefix and a counter to zero */ 13301 auto cnt = this->symbolicEngine->getOperandAst(cx); 13302 if (inst.getPrefix() != triton::arch::x86::ID_PREFIX_INVALID && cnt->evaluate().is_zero()) { 13303 this->controlFlow_s(inst); 13304 return; 13305 } 13306 13307 /* Create symbolic operands */ 13308 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 13309 auto op2 = this->symbolicEngine->getOperandAst(inst, index); 13310 auto op3 = this->symbolicEngine->getOperandAst(inst, df); 13311 13312 /* Create the semantics */ 13313 auto node1 = op1; 13314 auto node2 = this->astCtxt->ite( 13315 this->astCtxt->equal(op3, this->astCtxt->bvfalse()), 13316 this->astCtxt->bvadd(op2, this->astCtxt->bv(triton::size::word, index.getBitSize())), 13317 this->astCtxt->bvsub(op2, this->astCtxt->bv(triton::size::word, index.getBitSize())) 13318 ); 13319 13320 /* Create symbolic expression */ 13321 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "STOSW operation"); 13322 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, index, "Index operation"); 13323 13324 /* Spread taint */ 13325 expr1->isTainted = this->taintEngine->taintAssignment(dst, src); 13326 expr2->isTainted = this->taintEngine->taintUnion(index, index); 13327 13328 /* Update the symbolic control flow */ 13329 this->controlFlow_s(inst); 13330 } 13331 13332 sub_s(triton::arch::Instruction & inst)13333 void x86Semantics::sub_s(triton::arch::Instruction& inst) { 13334 auto& dst = inst.operands[0]; 13335 auto& src = inst.operands[1]; 13336 13337 /* Create symbolic operands */ 13338 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 13339 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 13340 13341 /* Create the semantics */ 13342 auto node = this->astCtxt->bvsub(op1, op2); 13343 13344 /* Create symbolic expression */ 13345 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "SUB operation"); 13346 13347 /* Spread taint */ 13348 expr->isTainted = this->taintEngine->taintUnion(dst, src); 13349 13350 /* Update symbolic flags */ 13351 this->af_s(inst, expr, dst, op1, op2); 13352 this->cfSub_s(inst, expr, dst, op1, op2); 13353 this->ofSub_s(inst, expr, dst, op1, op2); 13354 this->pf_s(inst, expr, dst); 13355 this->sf_s(inst, expr, dst); 13356 this->zf_s(inst, expr, dst); 13357 13358 /* Update the symbolic control flow */ 13359 this->controlFlow_s(inst); 13360 } 13361 13362 syscall_s(triton::arch::Instruction & inst)13363 void x86Semantics::syscall_s(triton::arch::Instruction& inst) { 13364 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RCX)); 13365 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_R11)); 13366 auto src1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_RIP)); 13367 auto src2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_X86_EFLAGS)); 13368 13369 /* Create symbolic operands */ 13370 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 13371 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 13372 13373 /* Create the semantics */ 13374 auto node1 = this->astCtxt->bvadd(op1, this->astCtxt->bv(inst.getSize(), src1.getBitSize())); 13375 auto node2 = op2; 13376 13377 /* Create symbolic expression */ 13378 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1, "SYSCALL RCX operation"); 13379 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "SYSCALL R11 operation"); 13380 13381 /* Spread taint */ 13382 expr1->isTainted = this->taintEngine->taintAssignment(dst1, src1); 13383 expr2->isTainted = this->taintEngine->taintAssignment(dst2, src2); 13384 13385 /* Update the symbolic control flow */ 13386 this->controlFlow_s(inst); 13387 } 13388 13389 sysenter_s(triton::arch::Instruction & inst)13390 void x86Semantics::sysenter_s(triton::arch::Instruction& inst) { 13391 /* Update the symbolic control flow */ 13392 this->controlFlow_s(inst); 13393 } 13394 13395 test_s(triton::arch::Instruction & inst)13396 void x86Semantics::test_s(triton::arch::Instruction& inst) { 13397 auto& src1 = inst.operands[0]; 13398 auto& src2 = inst.operands[1]; 13399 13400 /* Create symbolic operands */ 13401 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 13402 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 13403 13404 /* Create the semantics */ 13405 auto node = this->astCtxt->bvand(op1, op2); 13406 13407 /* Create symbolic expression */ 13408 auto expr = this->symbolicEngine->createSymbolicVolatileExpression(inst, node, "TEST operation"); 13409 13410 /* Spread taint */ 13411 expr->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2); 13412 13413 /* Update symbolic flags */ 13414 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 13415 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag"); 13416 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag"); 13417 this->pf_s(inst, expr, src1, true); 13418 this->sf_s(inst, expr, src1, true); 13419 this->zf_s(inst, expr, src1, true); 13420 13421 /* Update the symbolic control flow */ 13422 this->controlFlow_s(inst); 13423 } 13424 13425 tzcnt_s(triton::arch::Instruction & inst)13426 void x86Semantics::tzcnt_s(triton::arch::Instruction& inst) { 13427 auto& dst = inst.operands[0]; 13428 auto& src = inst.operands[1]; 13429 auto bvSize1 = dst.getBitSize(); 13430 auto bvSize2 = src.getBitSize(); 13431 13432 /* Create symbolic operands */ 13433 auto op1 = this->symbolicEngine->getOperandAst(inst, src); 13434 13435 /* Create the semantics */ 13436 triton::ast::SharedAbstractNode node = nullptr; 13437 switch (src.getSize()) { 13438 case triton::size::byte: 13439 node = this->astCtxt->ite( 13440 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)), 13441 this->astCtxt->bv(bvSize1, bvSize1), 13442 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1), 13443 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1), 13444 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1), 13445 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1), 13446 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1), 13447 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1), 13448 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1), 13449 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1), 13450 this->astCtxt->bv(0, bvSize1) 13451 )))))))) 13452 ); 13453 break; 13454 case triton::size::word: 13455 node = this->astCtxt->ite( 13456 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)), 13457 this->astCtxt->bv(bvSize1, bvSize1), 13458 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1), 13459 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1), 13460 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1), 13461 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1), 13462 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1), 13463 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1), 13464 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1), 13465 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1), 13466 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1), 13467 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1), 13468 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1), 13469 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1), 13470 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1), 13471 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1), 13472 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1), 13473 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1), 13474 this->astCtxt->bv(0, bvSize1) 13475 )))))))))))))))) 13476 ); 13477 break; 13478 case triton::size::dword: 13479 node = this->astCtxt->ite( 13480 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)), 13481 this->astCtxt->bv(bvSize1, bvSize1), 13482 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1), 13483 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1), 13484 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1), 13485 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1), 13486 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1), 13487 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1), 13488 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1), 13489 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1), 13490 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1), 13491 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1), 13492 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1), 13493 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1), 13494 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1), 13495 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1), 13496 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1), 13497 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1), 13498 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(16, 16, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1), 13499 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(17, 17, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1), 13500 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(18, 18, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1), 13501 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(19, 19, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1), 13502 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(20, 20, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1), 13503 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(21, 21, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1), 13504 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(22, 22, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1), 13505 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(23, 23, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1), 13506 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(24, 24, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1), 13507 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(25, 25, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1), 13508 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(26, 26, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1), 13509 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(27, 27, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1), 13510 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(28, 28, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1), 13511 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(29, 29, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1), 13512 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(30, 30, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1), 13513 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(31, 31, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1), 13514 this->astCtxt->bv(0, bvSize1) 13515 )))))))))))))))))))))))))))))))) 13516 ); 13517 break; 13518 case triton::size::qword: 13519 node = this->astCtxt->ite( 13520 this->astCtxt->equal(op1, this->astCtxt->bv(0, bvSize2)), 13521 this->astCtxt->bv(bvSize1, bvSize1), 13522 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize1), 13523 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize1), 13524 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize1), 13525 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize1), 13526 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize1), 13527 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize1), 13528 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize1), 13529 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize1), 13530 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize1), 13531 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize1), 13532 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize1), 13533 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize1), 13534 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize1), 13535 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize1), 13536 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize1), 13537 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize1), 13538 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(16, 16, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize1), 13539 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(17, 17, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize1), 13540 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(18, 18, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize1), 13541 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(19, 19, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize1), 13542 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(20, 20, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize1), 13543 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(21, 21, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize1), 13544 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(22, 22, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize1), 13545 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(23, 23, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize1), 13546 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(24, 24, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize1), 13547 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(25, 25, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize1), 13548 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(26, 26, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize1), 13549 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(27, 27, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize1), 13550 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(28, 28, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize1), 13551 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(29, 29, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize1), 13552 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(30, 30, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize1), 13553 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(31, 31, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize1), 13554 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(32, 32, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(32, bvSize1), 13555 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(33, 33, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(33, bvSize1), 13556 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(34, 34, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(34, bvSize1), 13557 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(35, 35, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(35, bvSize1), 13558 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(36, 36, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(36, bvSize1), 13559 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(37, 37, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(37, bvSize1), 13560 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(38, 38, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(38, bvSize1), 13561 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(39, 39, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(39, bvSize1), 13562 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(40, 40, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(40, bvSize1), 13563 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(41, 41, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(41, bvSize1), 13564 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(42, 42, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(42, bvSize1), 13565 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(43, 43, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(43, bvSize1), 13566 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(44, 44, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(44, bvSize1), 13567 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(45, 45, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(45, bvSize1), 13568 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(46, 46, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(46, bvSize1), 13569 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(47, 47, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(47, bvSize1), 13570 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(48, 48, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(48, bvSize1), 13571 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(49, 49, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(49, bvSize1), 13572 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(50, 50, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(50, bvSize1), 13573 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(51, 51, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(51, bvSize1), 13574 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(52, 52, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(52, bvSize1), 13575 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(53, 53, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(53, bvSize1), 13576 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(54, 54, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(54, bvSize1), 13577 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(55, 55, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(55, bvSize1), 13578 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(56, 56, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(56, bvSize1), 13579 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(57, 57, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(57, bvSize1), 13580 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(58, 58, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(58, bvSize1), 13581 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(59, 59, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(59, bvSize1), 13582 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(60, 60, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(60, bvSize1), 13583 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(61, 61, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(61, bvSize1), 13584 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(62, 62, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(62, bvSize1), 13585 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(63, 63, op1), this->astCtxt->bvtrue()), this->astCtxt->bv(63, bvSize1), 13586 this->astCtxt->bv(0, bvSize1) 13587 )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) 13588 ); 13589 break; 13590 default: 13591 throw triton::exceptions::Semantics("x86Semantics::tzcnt_s(): Invalid operand size."); 13592 } 13593 13594 /* Create symbolic expression */ 13595 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "TZCNT operation"); 13596 13597 /* Spread taint */ 13598 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 13599 13600 /* Update symbolic flags */ 13601 this->cfTzcnt_s(inst, expr, src, op1); 13602 this->zf_s(inst, expr, src); 13603 13604 /* Tag undefined flags */ 13605 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_OF)); 13606 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_SF)); 13607 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_PF)); 13608 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 13609 13610 /* Update the symbolic control flow */ 13611 this->controlFlow_s(inst); 13612 } 13613 13614 unpckhpd_s(triton::arch::Instruction & inst)13615 void x86Semantics::unpckhpd_s(triton::arch::Instruction& inst) { 13616 auto& dst = inst.operands[0]; 13617 auto& src = inst.operands[1]; 13618 13619 /* Create symbolic operands */ 13620 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 13621 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 13622 13623 /* Create the semantics */ 13624 auto node = this->astCtxt->concat( 13625 this->astCtxt->extract(127, 64, op2), 13626 this->astCtxt->extract(127, 64, op1) 13627 ); 13628 13629 /* Create symbolic expression */ 13630 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "UNPCKHPD operation"); 13631 13632 /* Spread taint */ 13633 expr->isTainted = this->taintEngine->taintUnion(dst, src); 13634 13635 /* Update the symbolic control flow */ 13636 this->controlFlow_s(inst); 13637 } 13638 13639 unpckhps_s(triton::arch::Instruction & inst)13640 void x86Semantics::unpckhps_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(4); 13651 13652 unpack.push_back(this->astCtxt->extract(127, 96, op2)); 13653 unpack.push_back(this->astCtxt->extract(127, 96, op1)); 13654 unpack.push_back(this->astCtxt->extract(95, 64, op2)); 13655 unpack.push_back(this->astCtxt->extract(95, 64, op1)); 13656 13657 auto node = this->astCtxt->concat(unpack); 13658 13659 /* Create symbolic expression */ 13660 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "UNPCKHPS operation"); 13661 13662 /* Spread taint */ 13663 expr->isTainted = this->taintEngine->taintUnion(dst, src); 13664 13665 /* Update the symbolic control flow */ 13666 this->controlFlow_s(inst); 13667 } 13668 13669 unpcklpd_s(triton::arch::Instruction & inst)13670 void x86Semantics::unpcklpd_s(triton::arch::Instruction& inst) { 13671 auto& dst = inst.operands[0]; 13672 auto& src = inst.operands[1]; 13673 13674 /* Create symbolic operands */ 13675 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 13676 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 13677 13678 /* Create the semantics */ 13679 auto node = this->astCtxt->concat( 13680 this->astCtxt->extract(63, 0, op2), 13681 this->astCtxt->extract(63, 0, op1) 13682 ); 13683 13684 /* Create symbolic expression */ 13685 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "UNPCKLPD operation"); 13686 13687 /* Spread taint */ 13688 expr->isTainted = this->taintEngine->taintUnion(dst, src); 13689 13690 /* Update the symbolic control flow */ 13691 this->controlFlow_s(inst); 13692 } 13693 13694 unpcklps_s(triton::arch::Instruction & inst)13695 void x86Semantics::unpcklps_s(triton::arch::Instruction& inst) { 13696 auto& dst = inst.operands[0]; 13697 auto& src = inst.operands[1]; 13698 13699 /* Create symbolic operands */ 13700 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 13701 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 13702 13703 /* Create the semantics */ 13704 std::vector<triton::ast::SharedAbstractNode> unpack; 13705 unpack.reserve(4); 13706 13707 unpack.push_back(this->astCtxt->extract(63, 32, op2)); 13708 unpack.push_back(this->astCtxt->extract(63, 32, op1)); 13709 unpack.push_back(this->astCtxt->extract(31, 0, op2)); 13710 unpack.push_back(this->astCtxt->extract(31, 0, op1)); 13711 13712 auto node = this->astCtxt->concat(unpack); 13713 13714 /* Create symbolic expression */ 13715 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "UNPCKLPS operation"); 13716 13717 /* Spread taint */ 13718 expr->isTainted = this->taintEngine->taintUnion(dst, src); 13719 13720 /* Update the symbolic control flow */ 13721 this->controlFlow_s(inst); 13722 } 13723 13724 vmovdqa_s(triton::arch::Instruction & inst)13725 void x86Semantics::vmovdqa_s(triton::arch::Instruction& inst) { 13726 auto& dst = inst.operands[0]; 13727 auto& src = inst.operands[1]; 13728 13729 /* Create the semantics */ 13730 auto node = this->symbolicEngine->getOperandAst(inst, src); 13731 13732 /* Create symbolic expression */ 13733 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVDQA operation"); 13734 13735 /* Spread taint */ 13736 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 13737 13738 /* Update the symbolic control flow */ 13739 this->controlFlow_s(inst); 13740 } 13741 13742 vmovdqu_s(triton::arch::Instruction & inst)13743 void x86Semantics::vmovdqu_s(triton::arch::Instruction& inst) { 13744 auto& dst = inst.operands[0]; 13745 auto& src = inst.operands[1]; 13746 13747 /* Create the semantics */ 13748 auto node = this->symbolicEngine->getOperandAst(inst, src); 13749 13750 /* Create symbolic expression */ 13751 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VMOVDQU operation"); 13752 13753 /* Spread taint */ 13754 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 13755 13756 /* Update the symbolic control flow */ 13757 this->controlFlow_s(inst); 13758 } 13759 13760 vpand_s(triton::arch::Instruction & inst)13761 void x86Semantics::vpand_s(triton::arch::Instruction& inst) { 13762 auto& dst = inst.operands[0]; 13763 auto& src1 = inst.operands[1]; 13764 auto& src2 = inst.operands[2]; 13765 13766 /* Create symbolic operands */ 13767 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 13768 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 13769 13770 /* Create the semantics */ 13771 auto node = this->astCtxt->bvand(op2, op3); 13772 13773 /* Create symbolic expression */ 13774 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPAND operation"); 13775 13776 /* Spread taint */ 13777 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2); 13778 13779 /* Update the symbolic control flow */ 13780 this->controlFlow_s(inst); 13781 } 13782 13783 vpandn_s(triton::arch::Instruction & inst)13784 void x86Semantics::vpandn_s(triton::arch::Instruction& inst) { 13785 auto& dst = inst.operands[0]; 13786 auto& src1 = inst.operands[1]; 13787 auto& src2 = inst.operands[2]; 13788 13789 /* Create symbolic operands */ 13790 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 13791 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 13792 13793 /* Create the semantics */ 13794 auto node = this->astCtxt->bvand(this->astCtxt->bvnot(op2), op3); 13795 13796 /* Create symbolic expression */ 13797 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPANDN operation"); 13798 13799 /* Spread taint */ 13800 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2); 13801 13802 /* Update the symbolic control flow */ 13803 this->controlFlow_s(inst); 13804 } 13805 13806 vpextrb_s(triton::arch::Instruction & inst)13807 void x86Semantics::vpextrb_s(triton::arch::Instruction& inst) { 13808 auto& dst = inst.operands[0]; 13809 auto& src1 = inst.operands[1]; 13810 auto& src2 = inst.operands[2]; 13811 13812 /* Create symbolic operands */ 13813 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 13814 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 13815 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 13816 13817 auto node = this->astCtxt->extract(7, 0, 13818 this->astCtxt->bvlshr( 13819 op2, 13820 this->astCtxt->bv(((op3->evaluate() & 0x0f) * 8), op2->getBitvectorSize()) 13821 ) 13822 ); 13823 13824 /* Create symbolic expression */ 13825 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPEXTRB operation"); 13826 13827 /* Apply the taint */ 13828 expr->isTainted = this->taintEngine->taintAssignment(dst, src1); 13829 13830 /* Update the symbolic control flow */ 13831 this->controlFlow_s(inst); 13832 } 13833 13834 vpextrd_s(triton::arch::Instruction & inst)13835 void x86Semantics::vpextrd_s(triton::arch::Instruction& inst) { 13836 auto& dst = inst.operands[0]; 13837 auto& src1 = inst.operands[1]; 13838 auto& src2 = inst.operands[2]; 13839 13840 /* Create symbolic operands */ 13841 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 13842 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 13843 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 13844 13845 auto node = this->astCtxt->extract(triton::bitsize::dword - 1, 0, 13846 this->astCtxt->bvlshr( 13847 op2, 13848 this->astCtxt->bv(((op3->evaluate() & 0x3) * triton::bitsize::dword), op2->getBitvectorSize()) 13849 ) 13850 ); 13851 13852 /* Create symbolic expression */ 13853 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPEXTRD operation"); 13854 13855 /* Apply the taint */ 13856 expr->isTainted = this->taintEngine->taintAssignment(dst, src1); 13857 13858 /* Update the symbolic control flow */ 13859 this->controlFlow_s(inst); 13860 } 13861 13862 vpextrq_s(triton::arch::Instruction & inst)13863 void x86Semantics::vpextrq_s(triton::arch::Instruction& inst) { 13864 auto& dst = inst.operands[0]; 13865 auto& src1 = inst.operands[1]; 13866 auto& src2 = inst.operands[2]; 13867 13868 /* Create symbolic operands */ 13869 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 13870 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 13871 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 13872 13873 auto node = this->astCtxt->extract(triton::bitsize::qword - 1, 0, 13874 this->astCtxt->bvlshr( 13875 op2, 13876 this->astCtxt->bv(((op3->evaluate() & 0x1) * triton::bitsize::qword), op2->getBitvectorSize()) 13877 ) 13878 ); 13879 13880 /* Create symbolic expression */ 13881 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPEXTRQ operation"); 13882 13883 /* Apply the taint */ 13884 expr->isTainted = this->taintEngine->taintAssignment(dst, src1); 13885 13886 /* Update the symbolic control flow */ 13887 this->controlFlow_s(inst); 13888 } 13889 13890 vpextrw_s(triton::arch::Instruction & inst)13891 void x86Semantics::vpextrw_s(triton::arch::Instruction& inst) { 13892 triton::uint32 count = 0; 13893 auto& dst = inst.operands[0]; 13894 auto& src1 = inst.operands[1]; 13895 auto& src2 = inst.operands[2]; 13896 13897 /* 13898 * When specifying a word location in an MMX technology register, the 13899 * 2 least-significant bits of the count operand specify the location; 13900 * for an XMM register, the 3 least-significant bits specify the 13901 * location. 13902 */ 13903 if (src1.getBitSize() == triton::bitsize::qword) { 13904 count = 0x03; 13905 } 13906 else { 13907 count = 0x07; 13908 } 13909 13910 /* Create symbolic operands */ 13911 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 13912 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 13913 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 13914 13915 auto node = this->astCtxt->extract(triton::bitsize::word - 1, 0, 13916 this->astCtxt->bvlshr( 13917 op2, 13918 this->astCtxt->bv(((op3->evaluate() & count) * triton::bitsize::word), op2->getBitvectorSize()) 13919 ) 13920 ); 13921 13922 /* Create symbolic expression */ 13923 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPEXTRW operation"); 13924 13925 /* Apply the taint */ 13926 expr->isTainted = this->taintEngine->taintAssignment(dst, src1); 13927 13928 /* Update the symbolic control flow */ 13929 this->controlFlow_s(inst); 13930 } 13931 13932 vpmovmskb_s(triton::arch::Instruction & inst)13933 void x86Semantics::vpmovmskb_s(triton::arch::Instruction& inst) { 13934 auto& dst = inst.operands[0]; 13935 auto& src = inst.operands[1]; 13936 13937 /* Create symbolic operands */ 13938 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 13939 13940 /* Create the semantics */ 13941 std::vector<triton::ast::SharedAbstractNode> mskb; 13942 mskb.reserve(32); 13943 13944 switch (src.getSize()) { 13945 case triton::size::qqword: 13946 mskb.push_back(this->astCtxt->extract(255, 255, op2)); 13947 mskb.push_back(this->astCtxt->extract(247, 247, op2)); 13948 mskb.push_back(this->astCtxt->extract(239, 239, op2)); 13949 mskb.push_back(this->astCtxt->extract(231, 231, op2)); 13950 mskb.push_back(this->astCtxt->extract(223, 223, op2)); 13951 mskb.push_back(this->astCtxt->extract(215, 215, op2)); 13952 mskb.push_back(this->astCtxt->extract(207, 207, op2)); 13953 mskb.push_back(this->astCtxt->extract(199, 199, op2)); 13954 mskb.push_back(this->astCtxt->extract(191, 191, op2)); 13955 mskb.push_back(this->astCtxt->extract(183, 183, op2)); 13956 mskb.push_back(this->astCtxt->extract(175, 175, op2)); 13957 mskb.push_back(this->astCtxt->extract(167, 167, op2)); 13958 mskb.push_back(this->astCtxt->extract(159, 159, op2)); 13959 mskb.push_back(this->astCtxt->extract(151, 151, op2)); 13960 mskb.push_back(this->astCtxt->extract(143, 143, op2)); 13961 mskb.push_back(this->astCtxt->extract(135, 135, op2)); 13962 13963 case triton::size::dqword: 13964 mskb.push_back(this->astCtxt->extract(127, 127, op2)); 13965 mskb.push_back(this->astCtxt->extract(119, 119, op2)); 13966 mskb.push_back(this->astCtxt->extract(111, 111, op2)); 13967 mskb.push_back(this->astCtxt->extract(103, 103, op2)); 13968 mskb.push_back(this->astCtxt->extract(95 , 95 , op2)); 13969 mskb.push_back(this->astCtxt->extract(87 , 87 , op2)); 13970 mskb.push_back(this->astCtxt->extract(79 , 79 , op2)); 13971 mskb.push_back(this->astCtxt->extract(71 , 71 , op2)); 13972 mskb.push_back(this->astCtxt->extract(63 , 63 , op2)); 13973 mskb.push_back(this->astCtxt->extract(55 , 55 , op2)); 13974 mskb.push_back(this->astCtxt->extract(47 , 47 , op2)); 13975 mskb.push_back(this->astCtxt->extract(39 , 39 , op2)); 13976 mskb.push_back(this->astCtxt->extract(31 , 31 , op2)); 13977 mskb.push_back(this->astCtxt->extract(23 , 23 , op2)); 13978 mskb.push_back(this->astCtxt->extract(15 , 15 , op2)); 13979 mskb.push_back(this->astCtxt->extract(7 , 7 , op2)); 13980 break; 13981 13982 default: 13983 throw triton::exceptions::Semantics("x86Semantics::vpmovmskb_s(): Invalid operand size."); 13984 } 13985 13986 auto node = this->astCtxt->zx( 13987 dst.getBitSize() - static_cast<triton::uint32>(mskb.size()), 13988 this->astCtxt->concat(mskb) 13989 ); 13990 13991 /* Create symbolic expression */ 13992 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPMOVMSKB operation"); 13993 13994 /* Apply the taint */ 13995 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 13996 13997 /* Update the symbolic control flow */ 13998 this->controlFlow_s(inst); 13999 } 14000 14001 vpor_s(triton::arch::Instruction & inst)14002 void x86Semantics::vpor_s(triton::arch::Instruction& inst) { 14003 auto& dst = inst.operands[0]; 14004 auto& src1 = inst.operands[1]; 14005 auto& src2 = inst.operands[2]; 14006 14007 /* Create symbolic operands */ 14008 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 14009 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 14010 14011 /* Create the semantics */ 14012 auto node = this->astCtxt->bvor(op2, op3); 14013 14014 /* Create symbolic expression */ 14015 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPOR operation"); 14016 14017 /* Spread taint */ 14018 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2); 14019 14020 /* Update the symbolic control flow */ 14021 this->controlFlow_s(inst); 14022 } 14023 14024 vpshufd_s(triton::arch::Instruction & inst)14025 void x86Semantics::vpshufd_s(triton::arch::Instruction& inst) { 14026 auto& dst = inst.operands[0]; 14027 auto& src = inst.operands[1]; 14028 auto& ord = inst.operands[2]; 14029 triton::uint32 dstSize = dst.getBitSize(); 14030 14031 /* Create symbolic operands */ 14032 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 14033 auto op3 = this->symbolicEngine->getOperandAst(inst, ord); 14034 14035 /* Create the semantics */ 14036 std::vector<triton::ast::SharedAbstractNode> pack; 14037 pack.reserve(8); 14038 14039 switch (dstSize) { 14040 14041 /* YMM */ 14042 case triton::bitsize::qqword: 14043 pack.push_back( 14044 this->astCtxt->extract(31, 0, 14045 this->astCtxt->bvlshr( 14046 op2, 14047 this->astCtxt->bvmul( 14048 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(7, 6, op3)), 14049 this->astCtxt->bv(32, dstSize) 14050 ) 14051 ) 14052 ) 14053 ); 14054 pack.push_back( 14055 this->astCtxt->extract(31, 0, 14056 this->astCtxt->bvlshr( 14057 op2, 14058 this->astCtxt->bvmul( 14059 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(5, 4, op3)), 14060 this->astCtxt->bv(32, dstSize) 14061 ) 14062 ) 14063 ) 14064 ); 14065 pack.push_back( 14066 this->astCtxt->extract(31, 0, 14067 this->astCtxt->bvlshr( 14068 op2, 14069 this->astCtxt->bvmul( 14070 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(3, 2, op3)), 14071 this->astCtxt->bv(32, dstSize) 14072 ) 14073 ) 14074 ) 14075 ); 14076 pack.push_back( 14077 this->astCtxt->extract(31, 0, 14078 this->astCtxt->bvlshr( 14079 op2, 14080 this->astCtxt->bvmul( 14081 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(1, 0, op3)), 14082 this->astCtxt->bv(32, dstSize) 14083 ) 14084 ) 14085 ) 14086 ); 14087 14088 /* XMM */ 14089 case triton::bitsize::dqword: 14090 pack.push_back( 14091 this->astCtxt->extract(31, 0, 14092 this->astCtxt->bvlshr( 14093 op2, 14094 this->astCtxt->bvmul( 14095 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(7, 6, op3)), 14096 this->astCtxt->bv(32, dstSize) 14097 ) 14098 ) 14099 ) 14100 ); 14101 pack.push_back( 14102 this->astCtxt->extract(31, 0, 14103 this->astCtxt->bvlshr( 14104 op2, 14105 this->astCtxt->bvmul( 14106 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(5, 4, op3)), 14107 this->astCtxt->bv(32, dstSize) 14108 ) 14109 ) 14110 ) 14111 ); 14112 pack.push_back( 14113 this->astCtxt->extract(31, 0, 14114 this->astCtxt->bvlshr( 14115 op2, 14116 this->astCtxt->bvmul( 14117 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(3, 2, op3)), 14118 this->astCtxt->bv(32, dstSize) 14119 ) 14120 ) 14121 ) 14122 ); 14123 pack.push_back( 14124 this->astCtxt->extract(31, 0, 14125 this->astCtxt->bvlshr( 14126 op2, 14127 this->astCtxt->bvmul( 14128 this->astCtxt->zx(dstSize-2, this->astCtxt->extract(1, 0, op3)), 14129 this->astCtxt->bv(32, dstSize) 14130 ) 14131 ) 14132 ) 14133 ); 14134 break; 14135 14136 default: 14137 throw triton::exceptions::Semantics("x86Semantics::vpshufd_s(): Invalid operand size."); 14138 } 14139 14140 auto node = this->astCtxt->concat(pack); 14141 14142 /* Create symbolic expression */ 14143 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPSHUFD operation"); 14144 14145 /* Spread taint */ 14146 expr->isTainted = this->taintEngine->taintAssignment(dst, src); 14147 14148 /* Update the symbolic control flow */ 14149 this->controlFlow_s(inst); 14150 } 14151 14152 vptest_s(triton::arch::Instruction & inst)14153 void x86Semantics::vptest_s(triton::arch::Instruction& inst) { 14154 auto& src1 = inst.operands[0]; 14155 auto& src2 = inst.operands[1]; 14156 14157 /* Create symbolic operands */ 14158 auto op1 = this->symbolicEngine->getOperandAst(inst, src1); 14159 auto op2 = this->symbolicEngine->getOperandAst(inst, src2); 14160 14161 /* Create the semantics */ 14162 auto node1 = this->astCtxt->bvand(op1, op2); 14163 auto node2 = this->astCtxt->bvand(op1, this->astCtxt->bvnot(op2)); 14164 14165 /* Create symbolic expression */ 14166 auto expr1 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "VPTEST operation"); 14167 auto expr2 = this->symbolicEngine->createSymbolicVolatileExpression(inst, node2, "VPTEST operation"); 14168 14169 /* Spread taint */ 14170 expr1->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2); 14171 expr2->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2); 14172 14173 /* Update symbolic flags */ 14174 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_AF), "Clears adjust flag"); 14175 this->cfPtest_s(inst, expr2, src1, true); 14176 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag"); 14177 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_PF), "Clears parity flag"); 14178 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_SF), "Clears sign flag"); 14179 this->zf_s(inst, expr1, src1, true); 14180 14181 /* Update the symbolic control flow */ 14182 this->controlFlow_s(inst); 14183 } 14184 14185 vpxor_s(triton::arch::Instruction & inst)14186 void x86Semantics::vpxor_s(triton::arch::Instruction& inst) { 14187 auto& dst = inst.operands[0]; 14188 auto& src1 = inst.operands[1]; 14189 auto& src2 = inst.operands[2]; 14190 14191 /* Create symbolic operands */ 14192 auto op2 = this->symbolicEngine->getOperandAst(inst, src1); 14193 auto op3 = this->symbolicEngine->getOperandAst(inst, src2); 14194 14195 /* Create the semantics */ 14196 auto node = this->astCtxt->bvxor(op2, op3); 14197 14198 /* Create symbolic expression */ 14199 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "VPXOR operation"); 14200 14201 /* Spread taint */ 14202 expr->isTainted = this->taintEngine->taintAssignment(dst, src1) | this->taintEngine->taintUnion(dst, src2); 14203 14204 /* Update the symbolic control flow */ 14205 this->controlFlow_s(inst); 14206 } 14207 14208 wait_s(triton::arch::Instruction & inst)14209 void x86Semantics::wait_s(triton::arch::Instruction& inst) { 14210 /* Update the symbolic control flow */ 14211 this->controlFlow_s(inst); 14212 } 14213 14214 wbinvd_s(triton::arch::Instruction & inst)14215 void x86Semantics::wbinvd_s(triton::arch::Instruction& inst) { 14216 /* Update the symbolic control flow */ 14217 this->controlFlow_s(inst); 14218 } 14219 14220 xadd_s(triton::arch::Instruction & inst)14221 void x86Semantics::xadd_s(triton::arch::Instruction& inst) { 14222 auto& dst = inst.operands[0]; 14223 auto& src = inst.operands[1]; 14224 bool dstT = this->taintEngine->isTainted(dst); 14225 bool srcT = this->taintEngine->isTainted(src); 14226 14227 /* Create symbolic operands */ 14228 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 14229 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 14230 14231 /* Create the semantics */ 14232 auto node1 = op2; 14233 auto node2 = op1; 14234 14235 /* Create symbolic expression */ 14236 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "XCHG operation"); 14237 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, src, "XCHG operation"); 14238 14239 /* Spread taint */ 14240 expr1->isTainted = this->taintEngine->setTaint(dst, srcT); 14241 expr2->isTainted = this->taintEngine->setTaint(src, dstT); 14242 14243 /* Create symbolic operands */ 14244 op1 = this->symbolicEngine->getOperandAst(inst, dst); 14245 op2 = this->symbolicEngine->getOperandAst(inst, src); 14246 14247 /* Create the semantics */ 14248 auto node3 = this->astCtxt->bvadd(op1, op2); 14249 14250 /* Create symbolic expression */ 14251 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, dst, "ADD operation"); 14252 14253 /* Spread taint */ 14254 expr3->isTainted = this->taintEngine->taintUnion(dst, src); 14255 14256 /* Update symbolic flags */ 14257 this->af_s(inst, expr3, dst, op1, op2); 14258 this->cfAdd_s(inst, expr3, dst, op1, op2); 14259 this->ofAdd_s(inst, expr3, dst, op1, op2); 14260 this->pf_s(inst, expr3, dst); 14261 this->sf_s(inst, expr3, dst); 14262 this->zf_s(inst, expr3, dst); 14263 14264 /* Update the symbolic control flow */ 14265 this->controlFlow_s(inst); 14266 } 14267 14268 xchg_s(triton::arch::Instruction & inst)14269 void x86Semantics::xchg_s(triton::arch::Instruction& inst) { 14270 auto& dst = inst.operands[0]; 14271 auto& src = inst.operands[1]; 14272 bool dstT = this->taintEngine->isTainted(dst); 14273 bool srcT = this->taintEngine->isTainted(src); 14274 14275 /* Create symbolic operands */ 14276 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 14277 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 14278 14279 /* Create the semantics */ 14280 auto node1 = op2; 14281 auto node2 = op1; 14282 14283 /* Create symbolic expression */ 14284 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "XCHG operation"); 14285 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, src, "XCHG operation"); 14286 14287 /* Spread taint */ 14288 expr1->isTainted = this->taintEngine->setTaint(dst, srcT); 14289 expr2->isTainted = this->taintEngine->setTaint(src, dstT); 14290 14291 /* Update the symbolic control flow */ 14292 this->controlFlow_s(inst); 14293 } 14294 14295 xor_s(triton::arch::Instruction & inst)14296 void x86Semantics::xor_s(triton::arch::Instruction& inst) { 14297 auto& dst = inst.operands[0]; 14298 auto& src = inst.operands[1]; 14299 14300 /* Create symbolic operands */ 14301 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 14302 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 14303 14304 /* Create the semantics */ 14305 auto node = this->astCtxt->bvxor(op1, op2); 14306 14307 /* Create symbolic expression */ 14308 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "XOR operation"); 14309 14310 /* Spread taint */ 14311 /* clear taint if the registers are the same */ 14312 if (dst.getType() == OP_REG && src.getRegister() == dst.getRegister()) 14313 this->taintEngine->setTaint(src, false); 14314 else 14315 expr->isTainted = this->taintEngine->taintUnion(dst, src); 14316 14317 /* Update symbolic flags */ 14318 this->undefined_s(inst, this->architecture->getRegister(ID_REG_X86_AF)); 14319 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_CF), "Clears carry flag"); 14320 this->clearFlag_s(inst, this->architecture->getRegister(ID_REG_X86_OF), "Clears overflow flag"); 14321 this->pf_s(inst, expr, dst); 14322 this->sf_s(inst, expr, dst); 14323 this->zf_s(inst, expr, dst); 14324 14325 /* Update the symbolic control flow */ 14326 this->controlFlow_s(inst); 14327 } 14328 14329 xorpd_s(triton::arch::Instruction & inst)14330 void x86Semantics::xorpd_s(triton::arch::Instruction& inst) { 14331 auto& dst = inst.operands[0]; 14332 auto& src = inst.operands[1]; 14333 14334 /* Create symbolic operands */ 14335 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 14336 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 14337 14338 /* Create the semantics */ 14339 auto node = this->astCtxt->bvxor(op1, op2); 14340 14341 /* Create symbolic expression */ 14342 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "XORPD operation"); 14343 14344 /* Spread taint */ 14345 expr->isTainted = this->taintEngine->taintUnion(dst, src); 14346 14347 /* Update the symbolic control flow */ 14348 this->controlFlow_s(inst); 14349 } 14350 14351 xorps_s(triton::arch::Instruction & inst)14352 void x86Semantics::xorps_s(triton::arch::Instruction& inst) { 14353 auto& dst = inst.operands[0]; 14354 auto& src = inst.operands[1]; 14355 14356 /* Create symbolic operands */ 14357 auto op1 = this->symbolicEngine->getOperandAst(inst, dst); 14358 auto op2 = this->symbolicEngine->getOperandAst(inst, src); 14359 14360 /* Create the semantics */ 14361 auto node = this->astCtxt->bvxor(op1, op2); 14362 14363 /* Create symbolic expression */ 14364 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "XORPS operation"); 14365 14366 /* Spread taint */ 14367 expr->isTainted = this->taintEngine->taintUnion(dst, src); 14368 14369 /* Update the symbolic control flow */ 14370 this->controlFlow_s(inst); 14371 } 14372 14373 }; /* x86 namespace */ 14374 }; /* arch namespace */ 14375 }; /* triton namespace */ 14376