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