libTriton version 1.0 build 1590
Loading...
Searching...
No Matches
arm32Semantics.cpp
Go to the documentation of this file.
1
2/*
3** Copyright (C) - Triton
4**
5** This program is under the terms of the Apache License 2.0.
6*/
7
8#include <utility>
9
10#include <triton/arm32Cpu.hpp>
13#include <triton/astContext.hpp>
14#include <triton/cpuSize.hpp>
15#include <triton/exceptions.hpp>
16
17
18
107namespace triton {
108 namespace arch {
109 namespace arm {
110 namespace arm32 {
111
115 const triton::ast::SharedAstContext& astCtxt) : astCtxt(astCtxt) {
116
117 this->architecture = architecture;
118 this->exception = triton::arch::NO_FAULT;
119 this->symbolicEngine = symbolicEngine;
120 this->taintEngine = taintEngine;
121
122 if (architecture == nullptr)
123 throw triton::exceptions::Semantics("Arm32Semantics::Arm32Semantics(): The architecture API must be defined.");
124
125 if (this->symbolicEngine == nullptr)
126 throw triton::exceptions::Semantics("Arm32Semantics::Arm32Semantics(): The symbolic engine API must be defined.");
127
128 if (this->taintEngine == nullptr)
129 throw triton::exceptions::Semantics("Arm32Semantics::Arm32Semantics(): The taint engines API must be defined.");
130 }
131
132
134 this->exception = triton::arch::NO_FAULT;
135 switch (inst.getType()) {
136 case ID_INS_ADC: this->adc_s(inst); break;
137 case ID_INS_ADD: this->add_s(inst); break;
138 case ID_INS_ADDW: this->add_s(inst); break;
139 case ID_INS_ADR: this->adr_s(inst); break;
140 case ID_INS_AND: this->and_s(inst); break;
141 case ID_INS_ASR: this->asr_s(inst); break;
142 case ID_INS_B: this->b_s(inst); break;
143 case ID_INS_BFC: this->bfc_s(inst); break;
144 case ID_INS_BFI: this->bfi_s(inst); break;
145 case ID_INS_BIC: this->bic_s(inst); break;
146 case ID_INS_BL: this->bl_s(inst, false); break;
147 case ID_INS_BLX: this->bl_s(inst, true); break;
148 case ID_INS_BX: this->bx_s(inst); break;
149 case ID_INS_CBNZ: this->cbnz_s(inst); break;
150 case ID_INS_CBZ: this->cbz_s(inst); break;
151 case ID_INS_CLZ: this->clz_s(inst); break;
152 case ID_INS_CMN: this->cmn_s(inst); break;
153 case ID_INS_CMP: this->cmp_s(inst); break;
154 case ID_INS_EOR: this->eor_s(inst); break;
155 case ID_INS_HINT: this->nop_s(inst); break;
156 case ID_INS_IT: this->it_s(inst); break;
157 case ID_INS_LDM: this->ldm_s(inst); break;
158 case ID_INS_LDR: this->ldr_s(inst); break;
159 case ID_INS_LDRB: this->ldrb_s(inst); break;
160 case ID_INS_LDRD: this->ldrd_s(inst); break;
161 case ID_INS_LDREX: this->ldrex_s(inst); break;
162 case ID_INS_LDRH: this->ldrh_s(inst); break;
163 case ID_INS_LDRSB: this->ldrsb_s(inst); break;
164 case ID_INS_LDRSH: this->ldrsh_s(inst); break;
165 case ID_INS_LSL: this->lsl_s(inst); break;
166 case ID_INS_LSR: this->lsr_s(inst); break;
167 case ID_INS_MLA: this->mla_s(inst); break;
168 case ID_INS_MLS: this->mls_s(inst); break;
169 case ID_INS_MOV: this->mov_s(inst); break;
170 case ID_INS_MOVT: this->movt_s(inst); break;
171 case ID_INS_MOVW: this->mov_s(inst); break;
172 case ID_INS_MUL: this->mul_s(inst); break;
173 case ID_INS_MVN: this->mvn_s(inst); break;
174 case ID_INS_NOP: this->nop_s(inst); break;
175 case ID_INS_ORN: this->orn_s(inst); break;
176 case ID_INS_ORR: this->orr_s(inst); break;
177 case ID_INS_POP: this->pop_s(inst); break;
178 case ID_INS_PUSH: this->push_s(inst); break;
179 case ID_INS_RBIT: this->rbit_s(inst); break;
180 case ID_INS_REV16: this->rev16_s(inst); break;
181 case ID_INS_REV: this->rev_s(inst); break;
182 case ID_INS_ROR: this->ror_s(inst); break;
183 case ID_INS_RRX: this->rrx_s(inst); break;
184 case ID_INS_RSB: this->rsb_s(inst); break;
185 case ID_INS_RSC: this->rsc_s(inst); break;
186 case ID_INS_SBC: this->sbc_s(inst); break;
187 case ID_INS_SBFX: this->sbfx_s(inst); break;
188 case ID_INS_SDIV: this->sdiv_s(inst); break;
189 case ID_INS_SMLABB: this->smlabb_s(inst); break;
190 case ID_INS_SMLABT: this->smlabt_s(inst); break;
191 case ID_INS_SMLATB: this->smlatb_s(inst); break;
192 case ID_INS_SMLATT: this->smlatt_s(inst); break;
193 case ID_INS_SMULL: this->smull_s(inst); break;
194 case ID_INS_STM: this->stm_s(inst); break;
195 case ID_INS_STMIB: this->stmib_s(inst); break;
196 case ID_INS_STR: this->str_s(inst); break;
197 case ID_INS_STRB: this->strb_s(inst); break;
198 case ID_INS_STRD: this->strd_s(inst); break;
199 case ID_INS_STREX: this->strex_s(inst); break;
200 case ID_INS_STRH: this->strh_s(inst); break;
201 case ID_INS_SUB: this->sub_s(inst); break;
202 case ID_INS_SUBW: this->sub_s(inst); break;
203 case ID_INS_SXTB: this->sxtb_s(inst); break;
204 case ID_INS_SXTH: this->sxth_s(inst); break;
205 case ID_INS_TBB: this->tbb_s(inst); break;
206 case ID_INS_TBH: this->tbh_s(inst); break;
207 case ID_INS_TEQ: this->teq_s(inst); break;
208 case ID_INS_TST: this->tst_s(inst); break;
209 case ID_INS_UBFX: this->ubfx_s(inst); break;
210 case ID_INS_UDIV: this->udiv_s(inst); break;
211 case ID_INS_UMULL: this->umull_s(inst); break;
212 case ID_INS_UXTB: this->uxtb_s(inst); break;
213 case ID_INS_UXTH: this->uxth_s(inst); break;
214 default:
215 this->exception = triton::arch::FAULT_UD;
216 break;
217 }
218 return this->exception;
219 }
220
221
222 inline triton::ast::SharedAbstractNode Arm32Semantics::buildConditionalSemantics(triton::arch::Instruction& inst,
224 const triton::ast::SharedAbstractNode& opNode) {
225 /* IMPORTANT NOTE The condition node should be built first, before
226 * any other node that may use the flags. The reason for this is that
227 * the condition node require the original values of the flags,
228 * otherwise the result would not be as the expected.
229 */
230 auto condNode = this->getCodeConditionAst(inst);
231 auto thenNode = opNode;
232 auto elseNode = this->symbolicEngine->getOperandAst(inst, dst);
233
234 if (dst.getRegister().getId() == ID_REG_ARM32_PC) {
235 thenNode = this->clearISSB(opNode);
236 }
237
238 return this->astCtxt->ite(condNode, thenNode, elseNode);
239 }
240
241
242 inline void Arm32Semantics::updateExecutionState(triton::arch::OperandWrapper& dst, const triton::ast::SharedAbstractNode& node) {
243 /* NOTE: In case the PC register is used as the destination operand,
244 * check whether there is a mode switch.
245 */
246 if (dst.getRegister().getId() == ID_REG_ARM32_PC) {
247 this->exchangeInstructionSet(dst, node);
248 }
249 }
250
251
252 inline void Arm32Semantics::exchangeInstructionSet(triton::arch::OperandWrapper& op, const triton::ast::SharedAbstractNode& node) {
253 bool state = false;
254
255 /* NOTE: There are two possibilities, depending on the operand. If it
256 * is an immediate, there is a mode switch (that is, if it is currently
257 * in ARM mode it switches to Thumb and the other way around). In
258 * case the operand is a register, it switches mode according to the
259 * instruction set selection bit (LSB) of the register.
260 */
261
262 switch (op.getType()) {
264 state = !this->architecture->isThumb();
265 break;
267 state = (node->evaluate() & 0x1) == 0x1;
268 break;
269 default:
270 throw triton::exceptions::Semantics("Arm32Semantics::Arm32Semantics(): Invalid operand type.");
271 }
272
273 this->architecture->setThumb(state);
274 }
275
276
277 inline triton::ast::SharedAbstractNode Arm32Semantics::adjustISSB(const triton::ast::SharedAbstractNode& node) {
278 /* Set instruction set selection bit (LSB) according to the current
279 * execution mode.
280 */
281 auto thumb = this->architecture->isThumb();
282 return this->astCtxt->bvor(node, this->astCtxt->bv(thumb ? 1 : 0, node->getBitvectorSize()));
283 }
284
285
286 inline triton::ast::SharedAbstractNode Arm32Semantics::clearISSB(const triton::ast::SharedAbstractNode& node) {
287 /* Clear instruction set selection bit (LSB). */
288 auto mask = this->astCtxt->bv(node->getBitvectorMask()-1, node->getBitvectorSize());
289 return this->astCtxt->bvand(node, mask);
290 }
291
292
293 triton::uint32 Arm32Semantics::ror(triton::uint32 value, triton::uint32 count) {
294 const triton::uint32 mask = 0x1f;
295 triton::uint32 sr_count = count & mask;
296 triton::uint32 sl_count = 32 - count;
297 return (value >> sr_count) | (value << sl_count);
298 }
299
300
301 inline triton::ast::SharedAbstractNode Arm32Semantics::getArm32SourceBaseOperandAst(triton::arch::Instruction& inst, triton::arch::OperandWrapper& op) {
302 /* NOTE: This is a hacky way to obtain the ast of the operand
303 * without the shift. This has to be done before building the
304 * semantics (the current value is needed, not the new one).
305 */
306 /* TODO (cnheitman): Discuss. Should we deal with this here (and in
307 * this way) or move it to the Symbolic Engine. See also
308 * `getArm32SourceOperandAst` and its use of `getShiftAst`.
309 */
310 if (op.getType() == triton::arch::OP_REG) {
311 auto opBase = triton::arch::OperandWrapper(op.getRegister());
312 opBase.getRegister().setShiftType(triton::arch::arm::ID_SHIFT_INVALID);
313 return this->symbolicEngine->getOperandAst(inst, opBase);
314 }
315
316 throw triton::exceptions::Semantics("Arm32Semantics::getArm32SourceBaseOperandAst(): Invalid operand type.");
317 }
318
319
320 inline triton::ast::SharedAbstractNode Arm32Semantics::getArm32SourceOperandAst(triton::arch::Instruction& inst, triton::arch::OperandWrapper& op) {
321 /* This function is a wrapper for the getOperandAst function. It makes
322 * sure to provide the correct value when reading the PC register. For
323 * more information, refer to "PC, the program counter" description
324 * within the "ARM core registers" section in the reference manual.
325 */
326 auto thumb = this->architecture->isThumb();
327 auto offset = thumb ? 4 : 8;
328 auto node = this->symbolicEngine->getOperandAst(inst, op);
329
330 if (op.getType() == triton::arch::OP_REG && op.getRegister().getId() == ID_REG_ARM32_PC) {
331 /* NOTE: PC always points to the address to the current instruction
332 * plus: a) 8 in case of ARM mode, or b) 4 in case of Thumb. It is
333 * also aligned to 4 bytes. For more information, refer to section
334 * "Use of labels in UAL instruction syntax" of the reference
335 * manual.
336 */
337 node = this->astCtxt->bv(inst.getAddress() + offset, op.getBitSize());
338
339 /* Shift AST if it's a shift operand */
340 /* TODO: Clean this and check if we can use the pcRelative thing
341 * used for x86.
342 */
344 node = this->symbolicEngine->getShiftAst(static_cast<const triton::arch::arm::ArmOperandProperties>(op.getRegister()), node);
345 }
346 }
347
348 return node;
349 }
350
351
352 triton::uint64 Arm32Semantics::alignAddStack_s(triton::arch::Instruction& inst, const triton::ast::SharedAbstractNode& cond, triton::uint32 delta) {
353 auto dst = triton::arch::OperandWrapper(this->architecture->getStackPointer());
354
355 /* Create symbolic operands */
356 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
357 auto op2 = this->astCtxt->bv(delta, dst.getBitSize());
358
359 /* Create the semantics */
360 auto node = this->astCtxt->ite(
361 cond,
362 this->astCtxt->bvadd(op1, op2),
363 op1
364 );
365
366 /* Create symbolic expression */
367 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "Stack alignment");
368
369 /* Spread taint */
370 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->taintUnion(dst, dst));
371
372 /* Return the new stack value */
373 return static_cast<triton::uint64>(node->evaluate());
374 }
375
376
377 triton::uint64 Arm32Semantics::alignSubStack_s(triton::arch::Instruction& inst, const triton::ast::SharedAbstractNode& cond, triton::uint32 delta) {
378 auto dst = triton::arch::OperandWrapper(this->architecture->getStackPointer());
379
380 /* Create symbolic operands */
381 auto op1 = this->symbolicEngine->getOperandAst(inst, dst);
382 auto op2 = this->astCtxt->bv(delta, dst.getBitSize());
383
384 /* Create the semantics */
385 auto node = this->astCtxt->ite(
386 cond,
387 this->astCtxt->bvsub(op1, op2),
388 op1
389 );
390
391 /* Create symbolic expression */
392 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "Stack alignment");
393
394 /* Spread taint */
395 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->taintUnion(dst, dst));
396
397 /* Return the new stack value */
398 return static_cast<triton::uint64>(node->evaluate());
399 }
400
401
402 void Arm32Semantics::controlFlow_s(triton::arch::Instruction& inst) {
403 auto pc = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_ARM32_PC));
404
405 /* Create the semantics */
406 auto node = this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize());
407
408 /* Create symbolic expression */
409 auto expr = this->symbolicEngine->createSymbolicRegisterExpression(inst, node, this->architecture->getParentRegister(ID_REG_ARM32_PC), "Program Counter");
410
411 /* Spread taint */
412 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getParentRegister(ID_REG_ARM32_PC), triton::engines::taint::UNTAINTED);
413 }
414
415
416 void Arm32Semantics::controlFlow_s(triton::arch::Instruction& inst,
419 /* NOTE: This version of Arm32Semantics::controlFlow_s should only be
420 * used for instructions that use a destination register. In that case,
421 * it checks whether the destination is the PC and acts accordingly.
422 * For example: ADD, SUB, etc.
423 */
424 auto pc = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_ARM32_PC));
425
427
428 /* Create the semantics */
429 if (cond->evaluate() == true && dst.getRegister().getId() == ID_REG_ARM32_PC) {
430 node = this->symbolicEngine->getOperandAst(inst, pc);
431 } else {
432 node = this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize());
433 }
434
435 /* Create symbolic expression */
436 auto expr = this->symbolicEngine->createSymbolicRegisterExpression(inst, node, this->architecture->getParentRegister(ID_REG_ARM32_PC), "Program Counter");
437
438 /* Spread taint */
439 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getParentRegister(ID_REG_ARM32_PC), triton::engines::taint::UNTAINTED);
440 }
441
442
443 void Arm32Semantics::controlFlow_s(triton::arch::Instruction& inst,
447
448 /* NOTE: This version of Arm32Semantics::controlFlow_s should only be
449 * used for instructions that use two destination registers. In that
450 * case, it checks whether any of the destination register is the PC
451 * and acts accordingly.
452 * For example: SMULL.
453 */
454 auto pc = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_ARM32_PC));
455
457
458 /* Create the semantics */
459 if (cond->evaluate() == true && (dst1.getRegister().getId() == ID_REG_ARM32_PC || dst2.getRegister().getId() == ID_REG_ARM32_PC)) {
460 node = this->symbolicEngine->getOperandAst(inst, pc);
461 } else {
462 node = this->astCtxt->bv(inst.getNextAddress(), pc.getBitSize());
463 }
464
465 /* Create symbolic expression */
466 auto expr = this->symbolicEngine->createSymbolicRegisterExpression(inst, node, this->architecture->getParentRegister(ID_REG_ARM32_PC), "Program Counter");
467
468 /* Spread taint */
469 expr->isTainted = this->taintEngine->setTaintRegister(this->architecture->getParentRegister(ID_REG_ARM32_PC), triton::engines::taint::UNTAINTED);
470 }
471
472
473 triton::ast::SharedAbstractNode Arm32Semantics::getCodeConditionAst(triton::arch::Instruction& inst) {
474
475 switch (inst.getCodeCondition()) {
476 // Always. Any flags. This suffix is normally omitted.
478 return this->astCtxt->equal(this->astCtxt->bvtrue(), this->astCtxt->bvtrue());
479 }
480
481 // Equal. Z set.
483 auto z = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_Z)));
484 return this->astCtxt->equal(z, this->astCtxt->bvtrue());
485 }
486
487 // Signed >=. N and V the same.
489 auto n = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_N)));
490 auto v = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_V)));
491 return this->astCtxt->equal(n, v);
492 }
493
494 // Signed >. Z clear, N and V the same.
496 auto z = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_Z)));
497 auto n = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_N)));
498 auto v = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_V)));
499 return this->astCtxt->land(
500 this->astCtxt->equal(z, this->astCtxt->bvfalse()),
501 this->astCtxt->equal(n, v)
502 );
503 }
504
505 // Higher (unsigned >). C set and Z clear.
507 auto c = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_C)));
508 auto z = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_Z)));
509 return this->astCtxt->land(
510 this->astCtxt->equal(c, this->astCtxt->bvtrue()),
511 this->astCtxt->equal(z, this->astCtxt->bvfalse())
512 );
513 }
514
515 // Higher or same (unsigned >=). C set.
517 auto c = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_C)));
518 return this->astCtxt->equal(c, this->astCtxt->bvtrue());
519 }
520
521 // Signed <=. Z set or N and V differ.
523 auto z = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_Z)));
524 auto n = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_N)));
525 auto v = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_V)));
526 return this->astCtxt->lor(
527 this->astCtxt->equal(z, this->astCtxt->bvtrue()),
528 this->astCtxt->lnot(this->astCtxt->equal(n, v))
529 );
530 }
531
532 // Lower (unsigned <). C clear.
534 auto c = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_C)));
535 return this->astCtxt->equal(c, this->astCtxt->bvfalse());
536 }
537
538 // Lower or same (unsigned <=). C clear or Z set.
540 auto c = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_C)));
541 auto z = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_Z)));
542 return this->astCtxt->lor(
543 this->astCtxt->equal(c, this->astCtxt->bvfalse()),
544 this->astCtxt->equal(z, this->astCtxt->bvtrue())
545 );
546 }
547
548 // Signed <. N and V differ.
550 auto n = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_N)));
551 auto v = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_V)));
552 return this->astCtxt->lnot(this->astCtxt->equal(n, v));
553 }
554
555 // Negative. N set.
557 auto n = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_N)));
558 return this->astCtxt->equal(n, this->astCtxt->bvtrue());
559 }
560
561 // Not equal. Z clear.
563 auto z = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_Z)));
564 return this->astCtxt->equal(z, this->astCtxt->bvfalse());
565 }
566
567 // Positive or zero. N clear.
569 auto n = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_N)));
570 return this->astCtxt->equal(n, this->astCtxt->bvfalse());
571 }
572
573 // No overflow. V clear.
575 auto v = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_V)));
576 return this->astCtxt->equal(v, this->astCtxt->bvfalse());
577 }
578
579 // Overflow. V set.
581 auto v = this->symbolicEngine->getOperandAst(inst, triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_V)));
582 return this->astCtxt->equal(v, this->astCtxt->bvtrue());
583 }
584
585 default:
586 /* The instruction don't use condition, so just return the 'true' node */
587 return this->astCtxt->equal(this->astCtxt->bvtrue(), this->astCtxt->bvtrue());
588 }
589 }
590
591
592 bool Arm32Semantics::getCodeConditionTaintState(const triton::arch::Instruction& inst) {
593 switch (inst.getCodeCondition()) {
594 // Always. Any flags. This suffix is normally omitted.
596 return false;
597 }
598
599 // Equal. Z set.
600 // Not equal. Z clear.
603 auto z = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_Z));
604 return this->taintEngine->isTainted(z);
605 }
606
607 // Signed >=. N and V the same.
608 // Signed <. N and V differ.
611 auto n = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_N));
612 auto v = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_V));
613 return this->taintEngine->isTainted(n) | this->taintEngine->isTainted(v);
614 }
615
616 // Signed >. Z clear, N and V the same.
617 // Signed <=. Z set, N and V differ.
620 auto z = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_Z));
621 auto n = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_N));
622 auto v = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_V));
623 return this->taintEngine->isTainted(z) | this->taintEngine->isTainted(n) | this->taintEngine->isTainted(v);
624 }
625
626 // Higher (unsigned >). C set and Z clear.
627 // Lower or same (unsigned <=). C clear or Z set.
630 auto c = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_C));
631 auto z = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_Z));
632 return this->taintEngine->isTainted(c) | this->taintEngine->isTainted(z);
633 }
634
635 // Higher or same (unsigned >=). C set.
636 // Lower (unsigned <). C clear.
639 auto c = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_C));
640 return this->taintEngine->isTainted(c);
641 }
642
643 // Negative. N set.
644 // Positive or zero. N clear.
647 auto n = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_N));
648 return this->taintEngine->isTainted(n);
649 }
650
651 // No overflow. V clear.
652 // Overflow. V set.
655 auto v = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_V));
656 return this->taintEngine->isTainted(v);
657 }
658
659 default:
660 return false;
661 }
662 }
663
664
665 void Arm32Semantics::spreadTaint(triton::arch::Instruction& inst,
668 const triton::arch::OperandWrapper& operand,
669 bool taint) {
670
671 if (this->getCodeConditionTaintState(inst) == true) {
672 expr->isTainted = this->taintEngine->setTaint(operand, true);
673 }
674 else if (cond->evaluate() == true) {
675 expr->isTainted = this->taintEngine->setTaint(operand, taint);
676 inst.setConditionTaken(true);
677 }
678 else {
679 expr->isTainted = this->taintEngine->isTainted(operand);
680 }
681 }
682
683
684 void Arm32Semantics::nf_s(triton::arch::Instruction& inst,
688
689 auto nf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_N));
690 auto high = dst.getHigh();
691
692 /*
693 * Create the semantic, considering conditional execution.
694 * nf = MSB(result)
695 */
696 auto node1 = this->astCtxt->extract(high, high, this->astCtxt->reference(parent));
697 auto node2 = this->symbolicEngine->getOperandAst(nf);
698 auto node3 = this->astCtxt->ite(cond, node1, node2);
699
700 /* Create the symbolic expression */
701 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node3, nf, "Negative flag");
702
703 /* Spread the taint from the parent to the child */
704 this->spreadTaint(inst, cond, expr, nf, parent->isTainted);
705 }
706
707
708 void Arm32Semantics::zf_s(triton::arch::Instruction& inst,
712
713 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_Z));
714 auto bvSize = dst.getBitSize();
715 auto low = dst.getLow();
716 auto high = dst.getHigh();
717
718 /*
719 * Create the semantic, considering conditional execution.
720 * zf = 0 == result
721 */
722 auto node1 = this->astCtxt->ite(
723 this->astCtxt->equal(
724 this->astCtxt->extract(high, low, this->astCtxt->reference(parent)),
725 this->astCtxt->bv(0, bvSize)
726 ),
727 this->astCtxt->bv(1, 1),
728 this->astCtxt->bv(0, 1)
729 );
730 auto node2 = this->symbolicEngine->getOperandAst(zf);
731 auto node3 = this->astCtxt->ite(cond, node1, node2);
732
733 /* Create the symbolic expression */
734 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node3, zf, "Zero flag");
735
736 /* Spread the taint from the parent to the child */
737 this->spreadTaint(inst, cond, expr, zf, parent->isTainted);
738 }
739
740
741 void Arm32Semantics::cfAdd_s(triton::arch::Instruction& inst,
747
748 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_C));
749 auto bvSize = dst.getBitSize();
750 auto low = dst.getLow();
751 auto high = dst.getHigh();
752
753 /*
754 * Create the semantic, considering conditional execution.
755 * cf = MSB((op1 & op2) ^ ((op1 ^ op2 ^ result) & (op1 ^ op2)));
756 */
757 auto node1 = this->astCtxt->extract(bvSize-1, bvSize-1,
758 this->astCtxt->bvxor(
759 this->astCtxt->bvand(op1, op2),
760 this->astCtxt->bvand(
761 this->astCtxt->bvxor(
762 this->astCtxt->bvxor(op1, op2),
763 this->astCtxt->extract(high, low, this->astCtxt->reference(parent))
764 ),
765 this->astCtxt->bvxor(op1, op2))
766 )
767 );
768 auto node2 = this->symbolicEngine->getOperandAst(cf);
769 auto node3 = this->astCtxt->ite(cond, node1, node2);
770
771 /* Create the symbolic expression */
772 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node3, cf, "Carry flag");
773
774 /* Spread the taint from the parent to the child */
775 this->spreadTaint(inst, cond, expr, cf, parent->isTainted);
776 }
777
778
779 void Arm32Semantics::cfSub_s(triton::arch::Instruction& inst,
785
786 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_C));
787 auto bvSize = dst.getBitSize();
788 auto low = dst.getLow();
789 auto high = dst.getHigh();
790
791 /*
792 * Create the semantic.
793 * cf = (MSB(((op1 ^ op2 ^ result) ^ ((op1 ^ result) & (op1 ^ op2))))) ^ 1
794 */
795 auto node1 = this->astCtxt->bvxor(
796 this->astCtxt->extract(bvSize-1, bvSize-1,
797 this->astCtxt->bvxor(
798 this->astCtxt->bvxor(op1, this->astCtxt->bvxor(op2, this->astCtxt->extract(high, low, this->astCtxt->reference(parent)))),
799 this->astCtxt->bvand(
800 this->astCtxt->bvxor(op1, this->astCtxt->extract(high, low, this->astCtxt->reference(parent))),
801 this->astCtxt->bvxor(op1, op2)
802 )
803 )
804 ),
805 this->astCtxt->bvtrue()
806 );
807 auto node2 = this->symbolicEngine->getOperandAst(cf);
808 auto node3 = this->astCtxt->ite(cond, node1, node2);
809
810 /* Create the symbolic expression */
811 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node3, cf, "Carry flag");
812
813 /* Spread the taint from the parent to the child */
814 this->spreadTaint(inst, cond, expr, cf, parent->isTainted);
815 }
816
817
818 void Arm32Semantics::nfSmull_s(triton::arch::Instruction& inst,
824
825 auto nf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_N));
826 auto high = dst2.getHigh();
827
828 /*
829 * Create the semantic, considering conditional execution.
830 * nf = MSB(result)
831 */
832 auto node1 = this->astCtxt->extract(high, high, this->astCtxt->reference(parent2));
833 auto node2 = this->symbolicEngine->getOperandAst(nf);
834 auto node3 = this->astCtxt->ite(cond, node1, node2);
835
836 /* Create the symbolic expression */
837 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node3, nf, "Negative flag");
838
839 /* Spread the taint from the parent to the child */
840 this->spreadTaint(inst, cond, expr, nf, parent1->isTainted | parent2->isTainted);
841 }
842
843
844 void Arm32Semantics::zfSmull_s(triton::arch::Instruction& inst,
850
851 auto zf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_Z));
852 auto bvSize = dst1.getBitSize();
853 auto low = dst1.getLow();
854 auto high = dst1.getHigh();
855
856 /*
857 * Create the semantic, considering conditional execution.
858 * zf = 0 == result
859 */
860 auto node1 = this->astCtxt->ite(
861 this->astCtxt->land(
862 this->astCtxt->equal(
863 this->astCtxt->extract(high, low, this->astCtxt->reference(parent1)),
864 this->astCtxt->bv(0, bvSize)
865 ),
866 this->astCtxt->equal(
867 this->astCtxt->extract(high, low, this->astCtxt->reference(parent2)),
868 this->astCtxt->bv(0, bvSize)
869 )
870 ),
871 this->astCtxt->bv(1, 1),
872 this->astCtxt->bv(0, 1)
873 );
874 auto node2 = this->symbolicEngine->getOperandAst(zf);
875 auto node3 = this->astCtxt->ite(cond, node1, node2);
876
877 /* Create the symbolic expression */
878 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node3, zf, "Zero flag");
879
880 /* Spread the taint from the parent to the child */
881 this->spreadTaint(inst, cond, expr, zf, parent1->isTainted | parent2->isTainted);
882 }
883
884
885 void Arm32Semantics::vfAdd_s(triton::arch::Instruction& inst,
891
892 auto vf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_V));
893 auto bvSize = dst.getBitSize();
894 auto low = dst.getLow();
895 auto high = dst.getHigh();
896
897 /*
898 * Create the semantic, considering conditional execution.
899 * vf = MSB((op1 ^ ~op2) & (op1 ^ result))
900 */
901 auto node1 = this->astCtxt->extract(bvSize-1, bvSize-1,
902 this->astCtxt->bvand(
903 this->astCtxt->bvxor(op1, this->astCtxt->bvnot(op2)),
904 this->astCtxt->bvxor(op1, this->astCtxt->extract(high, low, this->astCtxt->reference(parent)))
905 )
906 );
907 auto node2 = this->symbolicEngine->getOperandAst(vf);
908 auto node3 = this->astCtxt->ite(cond, node1, node2);
909
910 /* Create the symbolic expression */
911 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node3, vf, "Overflow flag");
912
913 /* Spread the taint from the parent to the child */
914 this->spreadTaint(inst, cond, expr, vf, parent->isTainted);
915 }
916
917
918 void Arm32Semantics::vfSub_s(triton::arch::Instruction& inst,
924
925 auto vf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_V));
926 auto bvSize = dst.getBitSize();
927 auto low = dst.getLow();
928 auto high = dst.getHigh();
929
930 /*
931 * Create the semantic.
932 * vf = MSB((op1 ^ op2) & (op1 ^ result))
933 */
934 auto node1 = this->astCtxt->extract(bvSize-1, bvSize-1,
935 this->astCtxt->bvand(
936 this->astCtxt->bvxor(op1, op2),
937 this->astCtxt->bvxor(op1, this->astCtxt->extract(high, low, this->astCtxt->reference(parent)))
938 )
939 );
940 auto node2 = this->symbolicEngine->getOperandAst(vf);
941 auto node3 = this->astCtxt->ite(cond, node1, node2);
942
943 /* Create the symbolic expression */
944 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node3, vf, "Overflow flag");
945
946 /* Spread the taint from the parent to the child */
947 this->spreadTaint(inst, cond, expr, vf, parent->isTainted);
948 }
949
950
951 void Arm32Semantics::adc_s(triton::arch::Instruction& inst) {
952 auto& dst = inst.operands[0];
953 auto& src1 = inst.operands[1];
954 auto& src2 = inst.operands[2];
955 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_C));
956
957 /* Process modified immediate constants (expand immediate) */
958 /* For more information, look for "Modified immediate constants in ARM
959 * instructions" in the reference manual. For example:
960 * "adc r0, r0, #16, #20".
961 */
962 if (inst.operands.size() == 4) {
963 auto src3 = inst.operands[3];
964
965 if (src2.getType() == OP_IMM && src3.getType() == OP_IMM) {
966 auto size = src2.getSize();
967 auto value = static_cast<triton::uint32>(src2.getImmediate().getValue());
968 auto shift = static_cast<triton::uint32>(src3.getImmediate().getValue());
969
970 /* Replace src2 with the expanded immediate */
971 src2 = triton::arch::OperandWrapper(triton::arch::Immediate(this->ror(value, shift), size));
972 } else {
973 throw triton::exceptions::Semantics("Arm32Semantics::adc_s(): Invalid operand type.");
974 }
975 }
976
977 /* Create symbolic operands */
978 auto op1 = this->getArm32SourceOperandAst(inst, src1);
979 auto op2 = this->getArm32SourceOperandAst(inst, src2);
980 auto op3 = this->getArm32SourceOperandAst(inst, cf);
981
982 /* Create the semantics */
983 auto node1 = this->astCtxt->bvadd(
984 this->astCtxt->bvadd(op1, op2),
985 this->astCtxt->zx(dst.getBitSize()-1, op3)
986 );
987 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
988
989 /* Create symbolic expression */
990 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "ADC(S) operation");
991
992 /* Get condition code node */
993 auto cond = this->getCodeConditionAst(inst);
994
995 /* Spread taint */
996 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(cf));
997
998 /* Update symbolic flags */
999 if (inst.isUpdateFlag() == true) {
1000 this->cfAdd_s(inst, cond, expr, dst, op1, op2);
1001 this->nf_s(inst, cond, expr, dst);
1002 this->vfAdd_s(inst, cond, expr, dst, op1, op2);
1003 this->zf_s(inst, cond, expr, dst);
1004 }
1005
1006 /* Update condition flag */
1007 if (cond->evaluate() == true) {
1008 inst.setConditionTaken(true);
1009
1010 /* Update execution mode accordingly. */
1011 this->updateExecutionState(dst, node1);
1012 }
1013
1014 /* Update the symbolic control flow */
1015 this->controlFlow_s(inst, cond, dst);
1016 }
1017
1018
1019 void Arm32Semantics::add_s(triton::arch::Instruction& inst) {
1020 auto& dst = inst.operands[0];
1021 auto& src1 = inst.operands[1];
1022 auto& src2 = inst.operands[2];
1023
1024 /* Process modified immediate constants (expand immediate) */
1025 /* For more information, look for "Modified immediate constants in ARM
1026 * instructions" in the reference manual. For example:
1027 * "add r0, r0, #16, #20".
1028 */
1029 if (inst.operands.size() == 4) {
1030 auto src3 = inst.operands[3];
1031
1032 if (src2.getType() == OP_IMM && src3.getType() == OP_IMM) {
1033 auto size = src2.getSize();
1034 auto value = static_cast<triton::uint32>(src2.getImmediate().getValue());
1035 auto shift = static_cast<triton::uint32>(src3.getImmediate().getValue());
1036
1037 /* Replace src2 with the expanded immediate */
1038 src2 = triton::arch::OperandWrapper(triton::arch::Immediate(this->ror(value, shift), size));
1039 } else {
1040 throw triton::exceptions::Semantics("Arm32Semantics::add_s(): Invalid operand type.");
1041 }
1042 }
1043
1044 /* Create symbolic operands */
1045 auto op1 = this->getArm32SourceOperandAst(inst, src1);
1046 auto op2 = this->getArm32SourceOperandAst(inst, src2);
1047
1048 /* Create the semantics */
1049 auto node1 = this->astCtxt->bvadd(op1, op2);
1050 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
1051
1052 /* Create symbolic expression */
1053 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "ADD(S) operation");
1054
1055 /* Get condition code node */
1056 auto cond = this->getCodeConditionAst(inst);
1057
1058 /* Spread taint */
1059 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
1060
1061 /* Update symbolic flags */
1062 if (inst.isUpdateFlag() == true) {
1063 this->cfAdd_s(inst, cond, expr, dst, op1, op2);
1064 this->nf_s(inst, cond, expr, dst);
1065 this->vfAdd_s(inst, cond, expr, dst, op1, op2);
1066 this->zf_s(inst, cond, expr, dst);
1067 }
1068
1069 /* Update condition flag */
1070 if (cond->evaluate() == true) {
1071 inst.setConditionTaken(true);
1072
1073 /* Update execution mode accordingly. */
1074 this->updateExecutionState(dst, node1);
1075 }
1076
1077 /* Update the symbolic control flow */
1078 this->controlFlow_s(inst, cond, dst);
1079 }
1080
1081
1082 void Arm32Semantics::adr_s(triton::arch::Instruction& inst) {
1083 auto& dst = inst.operands[0];
1084 auto& src = inst.operands[1];
1085 auto pc = triton::arch::OperandWrapper(this->architecture->getParentRegister(ID_REG_ARM32_PC));
1086
1087 /*
1088 * Note: Here we deal only with the Thumb version of ADR. For the ARM
1089 * version, Capstone decodes it as an ADD and adds pc as an explicit
1090 * operand.
1091 */
1092
1093 /* Create symbolic operands */
1094 auto op1 = this->getArm32SourceOperandAst(inst, src);
1095 auto op2 = this->getArm32SourceOperandAst(inst, pc);
1096
1097 /* Create the semantics */
1098 auto node1 = this->astCtxt->bvadd(op1, op2);
1099 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
1100
1101 /* Create symbolic expression */
1102 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "ADR operation");
1103
1104 /* Get condition code node */
1105 auto cond = this->getCodeConditionAst(inst);
1106
1107 /* Spread taint */
1108 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src) | this->taintEngine->isTainted(pc));
1109
1110 /* Update the symbolic control flow */
1111 this->controlFlow_s(inst);
1112 }
1113
1114
1115 void Arm32Semantics::and_s(triton::arch::Instruction& inst) {
1116 auto& dst = inst.operands[0];
1117 auto& src1 = inst.operands[1];
1118 auto& src2 = inst.operands[2];
1119
1120 /* Process modified immediate constants (expand immediate) */
1121 /* For more information, look for "Modified immediate constants in ARM
1122 * instructions" in the reference manual. For example:
1123 * "and r0, r0, #16, #20".
1124 */
1125 if (inst.operands.size() == 4) {
1126 auto src3 = inst.operands[3];
1127
1128 if (src2.getType() == OP_IMM && src3.getType() == OP_IMM) {
1129 auto size = src2.getSize();
1130 auto value = static_cast<triton::uint32>(src2.getImmediate().getValue());
1131 auto shift = static_cast<triton::uint32>(src3.getImmediate().getValue());
1132
1133 /* Replace src2 with the expanded immediate */
1134 src2 = triton::arch::OperandWrapper(triton::arch::Immediate(this->ror(value, shift), size));
1135 } else {
1136 throw triton::exceptions::Semantics("Arm32Semantics::and_s(): Invalid operand type.");
1137 }
1138 }
1139
1140 /* Create symbolic operands */
1141 auto op1 = this->getArm32SourceOperandAst(inst, src1);
1142 auto op2 = this->getArm32SourceOperandAst(inst, src2);
1143
1144 /* Create the semantics */
1145 auto node1 = this->astCtxt->bvand(op1, op2);
1146 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
1147
1148 /* Create symbolic expression */
1149 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "AND(S) operation");
1150
1151 /* Get condition code node */
1152 auto cond = this->getCodeConditionAst(inst);
1153
1154 /* Spread taint */
1155 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
1156
1157 /* Update symbolic flags */
1158 if (inst.isUpdateFlag() == true) {
1159 this->cfBitwise_s(inst, cond, expr, src2);
1160 this->nf_s(inst, cond, expr, dst);
1161 this->zf_s(inst, cond, expr, dst);
1162 }
1163
1164 /* Update condition flag */
1165 if (cond->evaluate() == true) {
1166 inst.setConditionTaken(true);
1167
1168 /* Update execution mode accordingly. */
1169 this->updateExecutionState(dst, node1);
1170 }
1171
1172 /* Update the symbolic control flow */
1173 this->controlFlow_s(inst, cond, dst);
1174 }
1175
1176
1177 void Arm32Semantics::asr_s(triton::arch::Instruction& inst) {
1178 auto& dst = inst.operands[0];
1179 auto& src1 = inst.operands[1];
1180
1181 /* Create symbolic operands */
1182 auto op1base = this->getArm32SourceBaseOperandAst(inst, src1);
1183 auto op1 = this->getArm32SourceOperandAst(inst, src1);
1184
1185 /* Create the semantics */
1187
1188 /* Two-operand version: ASR {<Rd>,} <Rm>, #<imm>. Here #<imm> is
1189 * interpreted as a shift value for <Rm>, which is handled directly
1190 * by the getArm32SourceOperandAst function. */
1191 if (inst.operands.size() == 2) {
1192 node1 = op1;
1193 }
1194 /* Three-operand version: ASR {<Rd>,} <Rn>, <Rm>. Here <Rm> is a
1195 * regular register and holds the value to shift the <Rn> register.
1196 * The operation must be explicitly done here.
1197 */
1198 else {
1199 auto& src2 = inst.operands[2];
1200
1201 auto op2 = this->getArm32SourceOperandAst(inst, src2);
1202
1203 node1 = this->astCtxt->bvashr(
1204 op1,
1205 this->astCtxt->zx(
1207 this->astCtxt->extract(7, 0, op2)
1208 )
1209 );
1210 }
1211
1212 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
1213
1214 /* Create symbolic expression */
1215 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "ASR(S) operation");
1216
1217 /* Get condition code node */
1218 auto cond = this->getCodeConditionAst(inst);
1219
1220 /* Spread taint */
1221 auto taint = this->taintEngine->isTainted(src1);
1222
1223 if (inst.operands.size() == 3) {
1224 auto& src2 = inst.operands[2];
1225
1226 taint |= this->taintEngine->isTainted(src2);
1227 }
1228
1229 this->spreadTaint(inst, cond, expr, dst, taint);
1230
1231 /* Update symbolic flags */
1232 if (inst.isUpdateFlag() == true) {
1233 auto& src = inst.operands.size() == 2 ? inst.operands[1] : inst.operands[2];
1234
1235 this->cfAsr_s(inst, cond, expr, op1base, src);
1236 this->nf_s(inst, cond, expr, dst);
1237 this->zf_s(inst, cond, expr, dst);
1238 }
1239
1240 /* Update condition flag */
1241 if (cond->evaluate() == true) {
1242 inst.setConditionTaken(true);
1243
1244 /* Update execution mode accordingly. */
1245 this->updateExecutionState(dst, node2);
1246 }
1247
1248 /* Update the symbolic control flow */
1249 this->controlFlow_s(inst, cond, dst);
1250 }
1251
1252
1253 void Arm32Semantics::b_s(triton::arch::Instruction& inst) {
1254 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_PC));
1255 auto& src = inst.operands[0];
1256
1257 /* Create symbolic operands */
1258 auto op1 = this->getArm32SourceOperandAst(inst, src);
1259 auto op2 = this->astCtxt->bv(inst.getNextAddress(), dst.getBitSize());
1260
1261 /* Create the semantics */
1262 auto cond = this->getCodeConditionAst(inst);
1263 auto pcNode = this->astCtxt->ite(cond, op1, op2);
1264
1265 /* Create symbolic expression */
1266 auto expr = this->symbolicEngine->createSymbolicExpression(inst, pcNode, dst, "B operation - Program Counter");
1267
1268 /* Spread taint */
1269 this->spreadTaint(inst, cond, expr, dst, this->getCodeConditionTaintState(inst));
1270
1271 /* Update condition flag */
1272 if (cond->evaluate() == true) {
1273 inst.setConditionTaken(true);
1274 }
1275
1276 /* Create the path constraint */
1277 this->symbolicEngine->pushPathConstraint(inst, expr);
1278 }
1279
1280
1281 void Arm32Semantics::bfc_s(triton::arch::Instruction& inst) {
1282 auto& dst = inst.operands[0]; // Reg
1283 auto& src1 = inst.operands[1]; // Imm (Lsb)
1284 auto& src2 = inst.operands[2]; // Imm (Width)
1285 auto lsb = static_cast<uint32>(src1.getImmediate().getValue());
1286 auto width = static_cast<uint32>(src2.getImmediate().getValue());
1287
1288 if (lsb + width > dst.getBitSize())
1289 throw triton::exceptions::Semantics("Arm32Semantics::bfc_s(): Invalid lsb and width.");
1290
1291 /* Create symbolic operands */
1292 auto opDst = this->symbolicEngine->getOperandAst(inst, dst);
1293
1294 /* Create the semantics */
1295 std::vector<triton::ast::SharedAbstractNode> chunks;
1296 chunks.reserve(3);
1297
1298 /* Upper chunk (from dst register). */
1299 if (lsb + width < dst.getBitSize()) {
1300 chunks.push_back(this->astCtxt->extract(dst.getBitSize() - 1, lsb + width, opDst));
1301 }
1302
1303 /* Middle chunk (zeroes). */
1304 chunks.push_back(this->astCtxt->bv(0, width));
1305
1306 /* Lower chunk (from dst register). */
1307 if (lsb > 0) {
1308 chunks.push_back(this->astCtxt->extract(lsb - 1, 0, opDst));
1309 }
1310
1311 auto node1 = chunks.size() == 1 ? chunks[0] : this->astCtxt->concat(chunks);
1312 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
1313
1314 /* Create symbolic expression */
1315 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "BFC operation");
1316
1317 /* Get condition code node */
1318 auto cond = this->getCodeConditionAst(inst);
1319
1320 /* Spread taint */
1321 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1));
1322
1323 /* Update the symbolic control flow */
1324 this->controlFlow_s(inst);
1325 }
1326
1327
1328 void Arm32Semantics::bfi_s(triton::arch::Instruction& inst) {
1329 auto& dst = inst.operands[0]; // Reg
1330 auto& src1 = inst.operands[1]; // Reg
1331 auto& src2 = inst.operands[2]; // Imm (Lsb)
1332 auto& src3 = inst.operands[3]; // Imm (Width)
1333 auto lsb = static_cast<uint32>(src2.getImmediate().getValue());
1334 auto width = static_cast<uint32>(src3.getImmediate().getValue());
1335
1336 if (lsb + width > dst.getBitSize())
1337 throw triton::exceptions::Semantics("Arm32Semantics::bfi_s(): Invalid lsb and width.");
1338
1339 /* Create symbolic operands */
1340 auto op = this->symbolicEngine->getOperandAst(inst, src1);
1341 auto opDst = this->symbolicEngine->getOperandAst(inst, dst);
1342
1343 /* Create the semantics */
1344 std::vector<triton::ast::SharedAbstractNode> chunks;
1345 chunks.reserve(3);
1346
1347 /* Upper chunk (from dst register). */
1348 if (lsb + width < dst.getBitSize()) {
1349 chunks.push_back(this->astCtxt->extract(dst.getBitSize() - 1, lsb + width, opDst));
1350 }
1351
1352 /* Middle chunk (from src register). */
1353 chunks.push_back(this->astCtxt->extract(width - 1, 0, op));
1354
1355 /* Lower chunk (from dst register). */
1356 if (lsb > 0) {
1357 chunks.push_back(this->astCtxt->extract(lsb - 1, 0, opDst));
1358 }
1359
1360 auto node1 = chunks.size() == 1 ? chunks[0] : this->astCtxt->concat(chunks);
1361 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
1362
1363 /* Create symbolic expression */
1364 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "BFI operation");
1365
1366 /* Get condition code node */
1367 auto cond = this->getCodeConditionAst(inst);
1368
1369 /* Spread taint */
1370 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1));
1371
1372 /* Update the symbolic control flow */
1373 this->controlFlow_s(inst);
1374 }
1375
1376
1377 void Arm32Semantics::bic_s(triton::arch::Instruction& inst) {
1378 auto& dst = inst.operands[0];
1379 auto& src1 = inst.operands[1];
1380 auto& src2 = inst.operands[2];
1381
1382 /* Process modified immediate constants (expand immediate) */
1383 /* For more information, look for "Modified immediate constants in ARM
1384 * instructions" in the reference manual. For example:
1385 * "bic r0, r0, #16, #20".
1386 */
1387 if (inst.operands.size() == 4) {
1388 auto src3 = inst.operands[3];
1389
1390 if (src2.getType() == OP_IMM && src3.getType() == OP_IMM) {
1391 auto size = src2.getSize();
1392 auto value = static_cast<triton::uint32>(src2.getImmediate().getValue());
1393 auto shift = static_cast<triton::uint32>(src3.getImmediate().getValue());
1394
1395 /* Replace src2 with the expanded immediate */
1396 src2 = triton::arch::OperandWrapper(triton::arch::Immediate(this->ror(value, shift), size));
1397 } else {
1398 throw triton::exceptions::Semantics("Arm32Semantics::bic_s(): Invalid operand type.");
1399 }
1400 }
1401
1402 /* Create symbolic operands */
1403 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
1404 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
1405
1406 /* Create the semantics */
1407 auto node1 = this->astCtxt->bvand(op1, this->astCtxt->bvnot(op2));
1408 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
1409
1410 /* Create symbolic expression */
1411 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "BIC(S) operation");
1412
1413 /* Get condition code node */
1414 auto cond = this->getCodeConditionAst(inst);
1415
1416 /* Spread taint */
1417 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
1418
1419 /* Update symbolic flags */
1420 if (inst.isUpdateFlag() == true) {
1421 this->cfBitwise_s(inst, cond, expr, src2);
1422 this->nf_s(inst, cond, expr, dst);
1423 this->zf_s(inst, cond, expr, dst);
1424 }
1425
1426 /* Update condition flag */
1427 if (cond->evaluate() == true) {
1428 inst.setConditionTaken(true);
1429
1430 /* Update execution mode accordingly. */
1431 this->updateExecutionState(dst, node1);
1432 }
1433
1434 /* Update the symbolic control flow */
1435 this->controlFlow_s(inst, cond, dst);
1436 }
1437
1438
1439 void Arm32Semantics::bl_s(triton::arch::Instruction& inst, bool exchange) {
1440 auto dst1 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_R14));
1441 auto dst2 = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_PC));
1442 auto& src = inst.operands[0];
1443
1444 /* Create symbolic operands */
1445 auto op1 = this->getArm32SourceOperandAst(inst, src);
1446 auto op2 = this->symbolicEngine->getOperandAst(inst, dst1);
1447 auto op3 = this->symbolicEngine->getOperandAst(inst, dst2);
1448 auto op4 = this->astCtxt->bv(inst.getNextAddress(), dst2.getBitSize());
1449
1450 /* Create the semantics */
1451 auto cond = this->getCodeConditionAst(inst);
1452
1453 /* Create semantics for the Link register */
1454 /* If the condition holds, the value of LR is equal to PC plus the
1455 * size of the current instruction (i.e. the address of the next
1456 * instruction). Additionally, the instruction set selection bit
1457 * (LSB) is set accordindly. If the condition does not hold, the value
1458 * of LR remains the same.
1459 */
1460 auto instSize = this->astCtxt->bv(inst.getSize(), dst2.getBitSize());
1461 auto lrNode = this->astCtxt->ite(cond, this->adjustISSB(this->astCtxt->bvadd(op3, instSize)), op2);
1462
1463 /* Create semantics for the Program Counter register */
1464 /* If the conditions holds, the value of PC is equal to the operand
1465 * of the instruction. Also, clear the instruction set selection bit
1466 * (LSB). If the condition does not hold, the value of PC is equal to
1467 * the next instruction.
1468 */
1469 auto pcNode = this->astCtxt->ite(cond, this->clearISSB(op1), op4);
1470
1471 /* Create symbolic expression */
1472 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, lrNode, dst1, "BL(X) operation - Link Register");
1473 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, pcNode, dst2, "BL(X) operation - Program Counter");
1474
1475 /* Spread taint */
1476 this->spreadTaint(inst, cond, expr1, dst1, this->getCodeConditionTaintState(inst));
1477 this->spreadTaint(inst, cond, expr2, dst2, this->getCodeConditionTaintState(inst));
1478
1479 /* Update condition flag */
1480 if (cond->evaluate() == true) {
1481 inst.setConditionTaken(true);
1482
1483 if (exchange) {
1484 this->exchangeInstructionSet(src, op1);
1485 }
1486 }
1487
1488 /* Create the path constraint */
1489 this->symbolicEngine->pushPathConstraint(inst, expr2);
1490 }
1491
1492
1493 void Arm32Semantics::bx_s(triton::arch::Instruction& inst) {
1494 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_PC));
1495 auto& src = inst.operands[0];
1496
1497 /* Create symbolic operands */
1498 auto op1 = this->getArm32SourceOperandAst(inst, src);
1499 auto op2 = this->astCtxt->bv(inst.getNextAddress(), dst.getBitSize());
1500
1501 /* Create the semantics */
1502 auto cond = this->getCodeConditionAst(inst);
1503
1504 /* If the conditions holds, the value of PC is equal to the operand
1505 * of the instruction. Also, clear the instruction set selection bit
1506 * (LSB). If the condition does not hold, the value of PC is equal to
1507 * the next instruction.
1508 */
1509 auto node = this->astCtxt->ite(cond, this->clearISSB(op1), op2);
1510
1511 /* Create symbolic expression */
1512 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "BX operation - Program Counter");
1513
1514 /* Spread taint */
1515 this->spreadTaint(inst, cond, expr, dst, this->getCodeConditionTaintState(inst));
1516
1517 /* Update condition flag */
1518 if (cond->evaluate() == true) {
1519 inst.setConditionTaken(true);
1520
1521 this->exchangeInstructionSet(src, op1);
1522 }
1523
1524 /* Create the path constraint */
1525 this->symbolicEngine->pushPathConstraint(inst, expr);
1526 }
1527
1528
1529 void Arm32Semantics::cbz_s(triton::arch::Instruction& inst) {
1530 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_PC));
1531 auto& src1 = inst.operands[0];
1532 auto& src2 = inst.operands[1];
1533
1534 /* Create symbolic operands */
1535 auto op1 = this->getArm32SourceOperandAst(inst, src1);
1536 auto op2 = this->getArm32SourceOperandAst(inst, src2);
1537 auto op3 = this->astCtxt->bv(inst.getNextAddress(), dst.getBitSize());
1538
1539 /* Create the semantics */
1540 auto pcNode = this->astCtxt->ite(
1541 this->astCtxt->equal(
1542 op1,
1543 this->astCtxt->bv(0, op1->getBitvectorSize())
1544 ),
1545 op2,
1546 op3
1547 );
1548
1549 /* Create symbolic expression */
1550 auto expr = this->symbolicEngine->createSymbolicExpression(inst, pcNode, dst, "CBZ operation - Program Counter");
1551
1552 /* Spread taint */
1553 expr->isTainted = this->taintEngine->setTaint(dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
1554
1555 /* Set condition flag */
1556 if (op1->evaluate() == 0) {
1557 inst.setConditionTaken(true);
1558 }
1559
1560 /* Create the path constraint */
1561 this->symbolicEngine->pushPathConstraint(inst, expr);
1562 }
1563
1564
1565 void Arm32Semantics::cbnz_s(triton::arch::Instruction& inst) {
1566 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_PC));
1567 auto& src1 = inst.operands[0];
1568 auto& src2 = inst.operands[1];
1569
1570 /* Create symbolic operands */
1571 auto op1 = this->getArm32SourceOperandAst(inst, src1);
1572 auto op2 = this->getArm32SourceOperandAst(inst, src2);
1573 auto op3 = this->astCtxt->bv(inst.getNextAddress(), dst.getBitSize());
1574
1575 /* Create the semantics */
1576 auto pcNode = this->astCtxt->ite(
1577 this->astCtxt->equal(
1578 op1,
1579 this->astCtxt->bv(0, op1->getBitvectorSize())
1580 ),
1581 op3,
1582 op2
1583 );
1584
1585 /* Create symbolic expression */
1586 auto expr = this->symbolicEngine->createSymbolicExpression(inst, pcNode, dst, "CBNZ operation - Program Counter");
1587
1588 /* Spread taint */
1589 expr->isTainted = this->taintEngine->setTaint(dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
1590
1591 /* Set condition flag */
1592 if (op1->evaluate() == 0) {
1593 inst.setConditionTaken(true);
1594 }
1595
1596 /* Create the path constraint */
1597 this->symbolicEngine->pushPathConstraint(inst, expr);
1598 }
1599
1600
1601 void Arm32Semantics::clz_s(triton::arch::Instruction& inst) {
1602 auto& dst = inst.operands[0];
1603 auto& src = inst.operands[1];
1604 auto bvSize = dst.getBitSize();
1605
1606 /* Create symbolic operands */
1607 auto op = this->getArm32SourceOperandAst(inst, src);
1608
1609 /* Create the semantics */
1610 auto node1 = this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(31, 31, op), this->astCtxt->bvtrue()), this->astCtxt->bv(0, bvSize),
1611 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(30, 30, op), this->astCtxt->bvtrue()), this->astCtxt->bv(1, bvSize),
1612 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(29, 29, op), this->astCtxt->bvtrue()), this->astCtxt->bv(2, bvSize),
1613 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(28, 28, op), this->astCtxt->bvtrue()), this->astCtxt->bv(3, bvSize),
1614 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(27, 27, op), this->astCtxt->bvtrue()), this->astCtxt->bv(4, bvSize),
1615 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(26, 26, op), this->astCtxt->bvtrue()), this->astCtxt->bv(5, bvSize),
1616 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(25, 25, op), this->astCtxt->bvtrue()), this->astCtxt->bv(6, bvSize),
1617 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(24, 24, op), this->astCtxt->bvtrue()), this->astCtxt->bv(7, bvSize),
1618 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(23, 23, op), this->astCtxt->bvtrue()), this->astCtxt->bv(8, bvSize),
1619 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(22, 22, op), this->astCtxt->bvtrue()), this->astCtxt->bv(9, bvSize),
1620 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(21, 21, op), this->astCtxt->bvtrue()), this->astCtxt->bv(10, bvSize),
1621 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(20, 20, op), this->astCtxt->bvtrue()), this->astCtxt->bv(11, bvSize),
1622 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(19, 19, op), this->astCtxt->bvtrue()), this->astCtxt->bv(12, bvSize),
1623 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(18, 18, op), this->astCtxt->bvtrue()), this->astCtxt->bv(13, bvSize),
1624 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(17, 17, op), this->astCtxt->bvtrue()), this->astCtxt->bv(14, bvSize),
1625 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(16, 16, op), this->astCtxt->bvtrue()), this->astCtxt->bv(15, bvSize),
1626 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(15, 15, op), this->astCtxt->bvtrue()), this->astCtxt->bv(16, bvSize),
1627 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(14, 14, op), this->astCtxt->bvtrue()), this->astCtxt->bv(17, bvSize),
1628 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(13, 13, op), this->astCtxt->bvtrue()), this->astCtxt->bv(18, bvSize),
1629 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(12, 12, op), this->astCtxt->bvtrue()), this->astCtxt->bv(19, bvSize),
1630 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(11, 11, op), this->astCtxt->bvtrue()), this->astCtxt->bv(20, bvSize),
1631 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(10, 10, op), this->astCtxt->bvtrue()), this->astCtxt->bv(21, bvSize),
1632 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(9, 9, op), this->astCtxt->bvtrue()), this->astCtxt->bv(22, bvSize),
1633 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(8, 8, op), this->astCtxt->bvtrue()), this->astCtxt->bv(23, bvSize),
1634 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(7, 7, op), this->astCtxt->bvtrue()), this->astCtxt->bv(24, bvSize),
1635 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(6, 6, op), this->astCtxt->bvtrue()), this->astCtxt->bv(25, bvSize),
1636 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(5, 5, op), this->astCtxt->bvtrue()), this->astCtxt->bv(26, bvSize),
1637 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(4, 4, op), this->astCtxt->bvtrue()), this->astCtxt->bv(27, bvSize),
1638 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(3, 3, op), this->astCtxt->bvtrue()), this->astCtxt->bv(28, bvSize),
1639 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(2, 2, op), this->astCtxt->bvtrue()), this->astCtxt->bv(29, bvSize),
1640 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(1, 1, op), this->astCtxt->bvtrue()), this->astCtxt->bv(30, bvSize),
1641 this->astCtxt->ite(this->astCtxt->equal(this->astCtxt->extract(0, 0, op), this->astCtxt->bvtrue()), this->astCtxt->bv(31, bvSize),
1642 this->astCtxt->bv(32, bvSize)
1643 ))))))))))))))))))))))))))))))));
1644 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
1645
1646 /* Create symbolic expression */
1647 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "CLZ operation");
1648
1649 /* Get condition code node */
1650 auto cond = this->getCodeConditionAst(inst);
1651
1652 /* Spread taint */
1653 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
1654
1655 /* Update condition flag */
1656 if (cond->evaluate() == true) {
1657 inst.setConditionTaken(true);
1658 }
1659
1660 /* Update the symbolic control flow */
1661 this->controlFlow_s(inst, cond, dst);
1662 }
1663
1664
1665 void Arm32Semantics::cmn_s(triton::arch::Instruction& inst) {
1666 auto& src1 = inst.operands[0];
1667 auto& src2 = inst.operands[1];
1668
1669 /* Create symbolic operands */
1670 auto op1 = this->getArm32SourceOperandAst(inst, src1);
1671 auto op2 = this->getArm32SourceOperandAst(inst, src2);
1672
1673 /* Create the semantics */
1674 auto cond = this->getCodeConditionAst(inst);
1675 auto node1 = this->astCtxt->bvadd(op1, op2);
1676
1677 /* Create symbolic expression */
1678 auto expr = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMN operation");
1679
1680 /* Spread taint */
1681 if (cond->evaluate() == true) {
1682 expr->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2);
1683 }
1684
1685 /* Update symbolic flags */
1686 this->cfAdd_s(inst, cond, expr, src1, op1, op2);
1687 this->nf_s(inst, cond, expr, src1);
1688 this->vfAdd_s(inst, cond, expr, src1, op1, op2);
1689 this->zf_s(inst, cond, expr, src1);
1690
1691 /* Update condition flag */
1692 if (cond->evaluate() == true) {
1693 inst.setConditionTaken(true);
1694 }
1695
1696 /* Update the symbolic control flow */
1697 this->controlFlow_s(inst);
1698 }
1699
1700
1701 void Arm32Semantics::cmp_s(triton::arch::Instruction& inst) {
1702 auto& src1 = inst.operands[0];
1703 auto& src2 = inst.operands[1];
1704
1705 /* Create symbolic operands */
1706 auto op1 = this->getArm32SourceOperandAst(inst, src1);
1707 auto op2 = this->getArm32SourceOperandAst(inst, src2);
1708
1709 /* Create the semantics */
1710 auto cond = this->getCodeConditionAst(inst);
1711 auto node1 = this->astCtxt->bvsub(op1, op2);
1712
1713 /* Create symbolic expression */
1714 auto expr = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "CMP operation");
1715
1716 /* Spread taint */
1717 if (cond->evaluate() == true) {
1718 expr->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2);
1719 }
1720
1721 /* Update symbolic flags */
1722 this->cfSub_s(inst, cond, expr, src1, op1, op2);
1723 this->nf_s(inst, cond, expr, src1);
1724 this->vfSub_s(inst, cond, expr, src1, op1, op2);
1725 this->zf_s(inst, cond, expr, src1);
1726
1727 /* Update condition flag */
1728 if (cond->evaluate() == true) {
1729 inst.setConditionTaken(true);
1730 }
1731
1732 /* Update the symbolic control flow */
1733 this->controlFlow_s(inst);
1734 }
1735
1736
1737 void Arm32Semantics::eor_s(triton::arch::Instruction& inst) {
1738 auto& dst = inst.operands[0];
1739 auto& src1 = inst.operands[1];
1740 auto& src2 = inst.operands[2];
1741
1742 /* Process modified immediate constants (expand immediate) */
1743 /* For more information, look for "Modified immediate constants in ARM
1744 * instructions" in the reference manual. For example:
1745 * "eor r0, r0, #16, #20".
1746 */
1747 if (inst.operands.size() == 4) {
1748 auto src3 = inst.operands[3];
1749
1750 if (src2.getType() == OP_IMM && src3.getType() == OP_IMM) {
1751 auto size = src2.getSize();
1752 auto value = static_cast<triton::uint32>(src2.getImmediate().getValue());
1753 auto shift = static_cast<triton::uint32>(src3.getImmediate().getValue());
1754
1755 /* Replace src2 with the expanded immediate */
1756 src2 = triton::arch::OperandWrapper(triton::arch::Immediate(this->ror(value, shift), size));
1757 } else {
1758 throw triton::exceptions::Semantics("Arm32Semantics::eor_s(): Invalid operand type.");
1759 }
1760 }
1761
1762 /* Create symbolic operands */
1763 auto op1 = this->getArm32SourceOperandAst(inst, src1);
1764 auto op2 = this->getArm32SourceOperandAst(inst, src2);
1765
1766 /* Create the semantics */
1767 auto node1 = this->astCtxt->bvxor(op1, op2);
1768 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
1769
1770 /* Create symbolic expression */
1771 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "EOR(S) operation");
1772
1773 /* Get condition code node */
1774 auto cond = this->getCodeConditionAst(inst);
1775
1776 /* Spread taint */
1777 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
1778
1779 /* Update symbolic flags */
1780 if (inst.isUpdateFlag() == true) {
1781 this->cfBitwise_s(inst, cond, expr, src2);
1782 this->nf_s(inst, cond, expr, dst);
1783 this->zf_s(inst, cond, expr, dst);
1784 }
1785
1786 /* Update condition flag */
1787 if (cond->evaluate() == true) {
1788 inst.setConditionTaken(true);
1789
1790 /* Update execution mode accordingly. */
1791 this->updateExecutionState(dst, node1);
1792 }
1793
1794 /* Update the symbolic control flow */
1795 this->controlFlow_s(inst, cond, dst);
1796 }
1797
1798
1799 void Arm32Semantics::it_s(triton::arch::Instruction& inst) {
1800 /* NOTE There are no semantics to add here (beyond updating the
1801 * program counter). All the processing is done in the disassembly
1802 * method (Arm32Cpu::disassembly).
1803 */
1804
1805 /* Update the symbolic control flow */
1806 this->controlFlow_s(inst);
1807 }
1808
1809
1810 void Arm32Semantics::ldm_s(triton::arch::Instruction& inst) {
1811 auto& base = inst.operands[0];
1813
1814 /* Create symbolic operands */
1815 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
1816
1817 /* Create the semantics */
1818 auto cond = this->getCodeConditionAst(inst);
1819
1820 bool updateControlFlow = true;
1821
1822 for (unsigned int i = 1; i < inst.operands.size(); i++) {
1823 auto& dst = inst.operands[i];
1824
1825 /* Compute memory address */
1826 auto addr = static_cast<triton::uint64>(baseNode->evaluate()) + size * (i - 1);
1828
1829 /* Create symbolic operands */
1830 auto op2 = this->getArm32SourceOperandAst(inst, src);
1831 auto op3 = this->getArm32SourceOperandAst(inst, dst);
1832
1833 /* Create the semantics */
1834 auto node1 = op2;
1835
1836 /* In case PC is one of the destination registers, clear ISSB
1837 * (instruction set selection bit) from the value that will be
1838 * assigned to it.
1839 */
1840 if (dst.getRegister().getId() == ID_REG_ARM32_PC) {
1841 node1 = this->clearISSB(op2);
1842 }
1843
1844 auto node2 = this->astCtxt->ite(cond, node1, op3);
1845
1846 /* Create symbolic expression */
1847 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "LDM operation - LOAD access");
1848
1849 /* Spread taint */
1850 this->spreadTaint(inst, cond, expr1, dst, this->taintEngine->isTainted(base) | this->taintEngine->isTainted(src));
1851
1852 /* If PC was modified, do not update the control flow at the end of
1853 * the function.
1854 */
1855 if (cond->evaluate() == true && dst.getRegister().getId() == ID_REG_ARM32_PC) {
1856 updateControlFlow = false;
1857
1858 /* Update execution mode accordingly. */
1859 this->updateExecutionState(dst, op2);
1860 }
1861 }
1862
1863 if (inst.isWriteBack() == true) {
1864 /* Create the semantics of the base register */
1865 auto node1 = this->astCtxt->ite(
1866 cond,
1867 this->astCtxt->bvadd(
1868 baseNode,
1869 this->astCtxt->bv((inst.operands.size() - 1) * size, base.getBitSize())
1870 ),
1871 baseNode
1872 );
1873
1874 /* Create symbolic expression */
1875 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node1, base, "LDM operation - Base register computation");
1876
1877 /* Spread taint */
1878 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base));
1879 }
1880
1881 /* Update condition flag */
1882 if (cond->evaluate() == true) {
1883 inst.setConditionTaken(true);
1884 }
1885
1886 /* Update the symbolic control flow */
1887 if (updateControlFlow) {
1888 this->controlFlow_s(inst);
1889 }
1890 }
1891
1892
1893 void Arm32Semantics::ldr_s(triton::arch::Instruction& inst) {
1894 auto& dst = inst.operands[0];
1895 auto& src = inst.operands[1];
1896
1897 /* Create symbolic operands */
1898 auto op = this->getArm32SourceOperandAst(inst, src);
1899
1900 /* Create the semantics */
1901 auto node1 = this->buildConditionalSemantics(inst, dst, op);
1902
1903 /* Create symbolic expression */
1904 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "LDR operation - LOAD access");
1905
1906 /* Get condition code node */
1907 auto cond = this->getCodeConditionAst(inst);
1908
1909 /* Spread taint */
1910 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
1911
1912 /* Optional behavior. Post-indexed computation of the base register */
1913 /* NOTE: There are two possible cases here:
1914 * - LDR <Rt>, [<Rn>], #+/-<imm>
1915 * - LDR <Rt>, [<Rn>], +/-<Rm>
1916 */
1917 if (inst.operands.size() == 3) {
1918 if (inst.operands[2].getType() == OP_IMM) {
1919 auto& imm = inst.operands[2].getImmediate();
1920 auto& base = src.getMemory().getBaseRegister();
1921
1922 /* Create symbolic operands of the post computation */
1923 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
1924 auto immNode = this->symbolicEngine->getOperandAst(inst, imm);
1925
1926 /* Create the semantics of the base register */
1927 auto thenNode = this->astCtxt->bvadd(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode));
1928
1929 if (imm.isSubtracted() == true) {
1930 thenNode = this->astCtxt->bvsub(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode));
1931 }
1932
1933 auto node2 = this->astCtxt->ite(cond, thenNode, baseNode);
1934
1935 /* Create symbolic expression */
1936 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, base, "LDR operation - Post-indexed base register computation");
1937
1938 /* Spread taint */
1939 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base));
1940 } else {
1941 auto& reg = inst.operands[2].getRegister();
1942 auto& base = src.getMemory().getBaseRegister();
1943
1944 /* Create symbolic operands of the post computation */
1945 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
1946 auto regNode = this->symbolicEngine->getOperandAst(inst, reg);
1947
1948 /* Create the semantics of the base register */
1949 auto thenNode = this->astCtxt->bvadd(baseNode, regNode);
1950
1951 if (reg.isSubtracted() == true) {
1952 thenNode = this->astCtxt->bvsub(baseNode, regNode);
1953 }
1954
1955 auto node2 = this->astCtxt->ite(cond, thenNode, baseNode);
1956
1957 /* Create symbolic expression */
1958 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, base, "LDR operation - Post-indexed base register computation");
1959
1960 /* Spread taint */
1961 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base));
1962 }
1963 }
1964
1965 /* Optional behavior. Pre-indexed computation of the base register */
1966 /* LDR <Rt>, [<Rn>, #+/-<imm>]! */
1967 else if (inst.operands.size() == 2 && inst.isWriteBack() == true) {
1968 auto& base = src.getMemory().getBaseRegister();
1969
1970 /* Create symbolic operands of the post computation */
1971 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
1972
1973 /* Create the semantics of the base register */
1974 auto node3 = this->astCtxt->ite(cond, src.getMemory().getLeaAst(), baseNode);
1975
1976 /* Create symbolic expression */
1977 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, base, "LDR operation - Pre-indexed base register computation");
1978
1979 /* Spread taint */
1980 this->spreadTaint(inst, cond, expr3, base, this->taintEngine->isTainted(base));
1981 }
1982
1983 /* Update condition flag */
1984 if (cond->evaluate() == true) {
1985 inst.setConditionTaken(true);
1986
1987 /* Update execution mode accordingly. */
1988 this->updateExecutionState(dst, op);
1989 }
1990
1991 /* Update the symbolic control flow */
1992 this->controlFlow_s(inst, cond, dst);
1993 }
1994
1995
1996 void Arm32Semantics::ldrb_s(triton::arch::Instruction& inst) {
1997 auto& dst = inst.operands[0];
1998 auto& src = inst.operands[1];
1999
2000 /* Create symbolic operands */
2001 auto op = this->symbolicEngine->getOperandAst(inst, src);
2002
2003 /* Create the semantics */
2004 auto node1 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), op);
2005 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
2006
2007 /* Create symbolic expression */
2008 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "LDRB operation - LOAD access");
2009
2010 /* Get condition code node */
2011 auto cond = this->getCodeConditionAst(inst);
2012
2013 /* Spread taint */
2014 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
2015
2016 /* Optional behavior. Post-indexed computation of the base register */
2017 /* NOTE: There are two possible cases here:
2018 * - LDRB <Rt>, [<Rn>], #+/-<imm>
2019 * - LDRB <Rt>, [<Rn>], +/-<Rm>
2020 */
2021 if (inst.operands.size() == 3) {
2022 if (inst.operands[2].getType() == OP_IMM) {
2023 auto& imm = inst.operands[2].getImmediate();
2024 auto& base = src.getMemory().getBaseRegister();
2025
2026 /* Create symbolic operands of the post computation */
2027 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
2028 auto immNode = this->symbolicEngine->getOperandAst(inst, imm);
2029
2030 /* Create the semantics of the base register */
2031 auto thenNode = this->astCtxt->bvadd(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode));
2032
2033 if (imm.isSubtracted() == true) {
2034 thenNode = this->astCtxt->bvsub(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode));
2035 }
2036
2037 auto node2 = this->astCtxt->ite(cond, thenNode, baseNode);
2038
2039 /* Create symbolic expression */
2040 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, base, "LDRB operation - Post-indexed base register computation");
2041
2042 /* Spread taint */
2043 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base));
2044 } else {
2045 auto& reg = inst.operands[2].getRegister();
2046 auto& base = src.getMemory().getBaseRegister();
2047
2048 /* Create symbolic operands of the post computation */
2049 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
2050 auto regNode = this->symbolicEngine->getOperandAst(inst, reg);
2051
2052 /* Create the semantics of the base register */
2053 auto thenNode = this->astCtxt->bvadd(baseNode, regNode);
2054
2055 if (reg.isSubtracted() == true) {
2056 thenNode = this->astCtxt->bvsub(baseNode, regNode);
2057 }
2058
2059 auto node2 = this->astCtxt->ite(cond, thenNode, baseNode);
2060
2061 /* Create symbolic expression */
2062 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, base, "LDRB operation - Post-indexed base register computation");
2063
2064 /* Spread taint */
2065 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base));
2066 }
2067 }
2068
2069 /* Optional behavior. Pre-indexed computation of the base register */
2070 /* LDR <Rt>, [<Rn>, #+/-<imm>]! */
2071 else if (inst.operands.size() == 2 && inst.isWriteBack() == true) {
2072 auto& base = src.getMemory().getBaseRegister();
2073
2074 /* Create symbolic operands of the post computation */
2075 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
2076
2077 /* Create the semantics of the base register */
2078 auto node3 = this->astCtxt->ite(cond, src.getMemory().getLeaAst(), baseNode);
2079
2080 /* Create symbolic expression */
2081 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, base, "LDRB operation - Pre-indexed base register computation");
2082
2083 /* Spread taint */
2084 this->spreadTaint(inst, cond, expr3, base, this->taintEngine->isTainted(base));
2085 }
2086
2087 /* Update condition flag */
2088 if (cond->evaluate() == true) {
2089 inst.setConditionTaken(true);
2090
2091 /* Update execution mode accordingly. */
2092 this->updateExecutionState(dst, node1);
2093 }
2094
2095 /* Update the symbolic control flow */
2096 this->controlFlow_s(inst, cond, dst);
2097 }
2098
2099
2100 void Arm32Semantics::ldrh_s(triton::arch::Instruction& inst) {
2101 auto& dst = inst.operands[0];
2102 auto& src = inst.operands[1];
2103
2104 /* Create symbolic operands */
2105 auto op = this->symbolicEngine->getOperandAst(inst, src);
2106
2107 /* Create the semantics */
2108 auto node1 = this->astCtxt->zx(dst.getBitSize() - src.getBitSize(), op);
2109 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
2110
2111 /* Create symbolic expression */
2112 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "LDRH operation - LOAD access");
2113
2114 /* Get condition code node */
2115 auto cond = this->getCodeConditionAst(inst);
2116
2117 /* Spread taint */
2118 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
2119
2120 /* Optional behavior. Post-indexed computation of the base register */
2121 /* NOTE: There are two possible cases here:
2122 * - LDRB <Rt>, [<Rn>], #+/-<imm>
2123 * - LDRB <Rt>, [<Rn>], +/-<Rm>
2124 */
2125 if (inst.operands.size() == 3) {
2126 if (inst.operands[2].getType() == OP_IMM) {
2127 auto& imm = inst.operands[2].getImmediate();
2128 auto& base = src.getMemory().getBaseRegister();
2129
2130 /* Create symbolic operands of the post computation */
2131 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
2132 auto immNode = this->symbolicEngine->getOperandAst(inst, imm);
2133
2134 /* Create the semantics of the base register */
2135 auto thenNode = this->astCtxt->bvadd(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode));
2136
2137 if (imm.isSubtracted() == true) {
2138 thenNode = this->astCtxt->bvsub(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode));
2139 }
2140
2141 auto node2 = this->astCtxt->ite(cond, thenNode, baseNode);
2142
2143 /* Create symbolic expression */
2144 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, base, "LDRH operation - Post-indexed base register computation");
2145
2146 /* Spread taint */
2147 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base));
2148 } else {
2149 auto& reg = inst.operands[2].getRegister();
2150 auto& base = src.getMemory().getBaseRegister();
2151
2152 /* Create symbolic operands of the post computation */
2153 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
2154 auto regNode = this->symbolicEngine->getOperandAst(inst, reg);
2155
2156 /* Create the semantics of the base register */
2157 auto thenNode = this->astCtxt->bvadd(baseNode, regNode);
2158
2159 if (reg.isSubtracted() == true) {
2160 thenNode = this->astCtxt->bvsub(baseNode, regNode);
2161 }
2162
2163 auto node2 = this->astCtxt->ite(cond, thenNode, baseNode);
2164
2165 /* Create symbolic expression */
2166 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, base, "LDRH operation - Post-indexed base register computation");
2167
2168 /* Spread taint */
2169 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base));
2170 }
2171 }
2172
2173 /* Optional behavior. Pre-indexed computation of the base register */
2174 /* LDR <Rt>, [<Rn>, #+/-<imm>]! */
2175 else if (inst.operands.size() == 2 && inst.isWriteBack() == true) {
2176 auto& base = src.getMemory().getBaseRegister();
2177
2178 /* Create symbolic operands of the post computation */
2179 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
2180
2181 /* Create the semantics of the base register */
2182 auto node3 = this->astCtxt->ite(cond, src.getMemory().getLeaAst(), baseNode);
2183
2184 /* Create symbolic expression */
2185 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, base, "LDRH operation - Pre-indexed base register computation");
2186
2187 /* Spread taint */
2188 this->spreadTaint(inst, cond, expr3, base, this->taintEngine->isTainted(base));
2189 }
2190
2191 /* Update condition flag */
2192 if (cond->evaluate() == true) {
2193 inst.setConditionTaken(true);
2194
2195 /* Update execution mode accordingly. */
2196 this->updateExecutionState(dst, node1);
2197 }
2198
2199 /* Update the symbolic control flow */
2200 this->controlFlow_s(inst, cond, dst);
2201 }
2202
2203
2204 void Arm32Semantics::ldrsb_s(triton::arch::Instruction& inst) {
2205 auto& dst = inst.operands[0];
2206 auto& src = inst.operands[1];
2207
2208 /* Create symbolic operands */
2209 auto op = this->symbolicEngine->getOperandAst(inst, src);
2210
2211 /* Create the semantics */
2212 auto node1 = this->astCtxt->sx(dst.getBitSize() - src.getBitSize(), op);
2213 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
2214
2215 /* Create symbolic expression */
2216 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "LDRSB operation - LOAD access");
2217
2218 /* Get condition code node */
2219 auto cond = this->getCodeConditionAst(inst);
2220
2221 /* Spread taint */
2222 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
2223
2224 /* Optional behavior. Post-indexed computation of the base register */
2225 /* NOTE: There are two possible cases here:
2226 * - LDRB <Rt>, [<Rn>], #+/-<imm>
2227 * - LDRB <Rt>, [<Rn>], +/-<Rm>
2228 */
2229 if (inst.operands.size() == 3) {
2230 if (inst.operands[2].getType() == OP_IMM) {
2231 auto& imm = inst.operands[2].getImmediate();
2232 auto& base = src.getMemory().getBaseRegister();
2233
2234 /* Create symbolic operands of the post computation */
2235 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
2236 auto immNode = this->symbolicEngine->getOperandAst(inst, imm);
2237
2238 /* Create the semantics of the base register */
2239 auto thenNode = this->astCtxt->bvadd(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode));
2240
2241 if (imm.isSubtracted() == true) {
2242 thenNode = this->astCtxt->bvsub(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode));
2243 }
2244
2245 auto node2 = this->astCtxt->ite(cond, thenNode, baseNode);
2246
2247 /* Create symbolic expression */
2248 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, base, "LDRSB operation - Post-indexed base register computation");
2249
2250 /* Spread taint */
2251 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base));
2252 } else {
2253 auto& reg = inst.operands[2].getRegister();
2254 auto& base = src.getMemory().getBaseRegister();
2255
2256 /* Create symbolic operands of the post computation */
2257 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
2258 auto regNode = this->symbolicEngine->getOperandAst(inst, reg);
2259
2260 /* Create the semantics of the base register */
2261 auto thenNode = this->astCtxt->bvadd(baseNode, regNode);
2262
2263 if (reg.isSubtracted() == true) {
2264 thenNode = this->astCtxt->bvsub(baseNode, regNode);
2265 }
2266
2267 auto node2 = this->astCtxt->ite(cond, thenNode, baseNode);
2268
2269 /* Create symbolic expression */
2270 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, base, "LDRSB operation - Post-indexed base register computation");
2271
2272 /* Spread taint */
2273 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base));
2274 }
2275 }
2276
2277 /* Optional behavior. Pre-indexed computation of the base register */
2278 /* LDR <Rt>, [<Rn>, #+/-<imm>]! */
2279 else if (inst.operands.size() == 2 && inst.isWriteBack() == true) {
2280 auto& base = src.getMemory().getBaseRegister();
2281
2282 /* Create symbolic operands of the post computation */
2283 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
2284
2285 /* Create the semantics of the base register */
2286 auto node3 = this->astCtxt->ite(cond, src.getMemory().getLeaAst(), baseNode);
2287
2288 /* Create symbolic expression */
2289 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, base, "LDRB operation - Pre-indexed base register computation");
2290
2291 /* Spread taint */
2292 this->spreadTaint(inst, cond, expr3, base, this->taintEngine->isTainted(base));
2293 }
2294
2295 /* Update condition flag */
2296 if (cond->evaluate() == true) {
2297 inst.setConditionTaken(true);
2298
2299 /* Update execution mode accordingly. */
2300 this->updateExecutionState(dst, node1);
2301 }
2302
2303 /* Update the symbolic control flow */
2304 this->controlFlow_s(inst, cond, dst);
2305 }
2306
2307
2308 void Arm32Semantics::ldrd_s(triton::arch::Instruction& inst) {
2309 auto& dst1 = inst.operands[0];
2310 auto& dst2 = inst.operands[1];
2311 auto& base = inst.operands[2];
2313
2314 /* Compute memory address */
2315 auto addr1 = base.getMemory().getAddress() + size * 0;
2317
2318 auto addr2 = base.getMemory().getAddress() + size * 1;
2320
2321 /* Create symbolic operands */
2322 auto op1 = this->getArm32SourceOperandAst(inst, src1);
2323 auto op2 = this->getArm32SourceOperandAst(inst, dst1);
2324 auto op3 = this->getArm32SourceOperandAst(inst, src2);
2325 auto op4 = this->getArm32SourceOperandAst(inst, dst2);
2326
2327 /* Create the semantics */
2328 auto cond = this->getCodeConditionAst(inst);
2329 auto node1 = this->astCtxt->ite(cond, op1, op2);
2330 auto node2 = this->astCtxt->ite(cond, op3, op4);
2331
2332 /* Create symbolic expression */
2333 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1, "LDRD operation - LOAD access");
2334 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "LDRD operation - LOAD access");
2335
2336 /* Spread taint */
2337 this->spreadTaint(inst, cond, expr1, dst1, this->taintEngine->isTainted(base) | this->taintEngine->isTainted(src1));
2338 this->spreadTaint(inst, cond, expr2, dst2, this->taintEngine->isTainted(base) | this->taintEngine->isTainted(src2));
2339
2340 /* Optional behavior. Post-indexed computation of the base register */
2341 /* LDRD <Rt>, [<Rn>], #+/-<imm> */
2342 if (inst.operands.size() == 4) {
2343 auto& imm = inst.operands[3].getImmediate();
2344 auto& base = inst.operands[2].getMemory().getBaseRegister();
2345
2346 /* Create symbolic operands of the post computation */
2347 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
2348 auto immNode = this->symbolicEngine->getOperandAst(inst, imm);
2349
2350 /* Create the semantics of the base register */
2352
2353 if(imm.isSubtracted()) {
2354 node2 = this->astCtxt->ite(
2355 cond,
2356 this->astCtxt->bvsub(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode)),
2357 baseNode
2358 );
2359 } else {
2360 node2 = this->astCtxt->ite(
2361 cond,
2362 this->astCtxt->bvadd(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode)),
2363 baseNode
2364 );
2365 }
2366
2367 /* Create symbolic expression */
2368 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, base, "LDRD operation - Post-indexed base register computation");
2369
2370 /* Spread taint */
2371 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base));
2372 }
2373
2374 /* Optional behavior. Pre-indexed computation of the base register */
2375 /* LDRD <Rt>, [<Rn>, #+/-<imm>]! */
2376 else if (inst.operands.size() == 3 && inst.isWriteBack() == true) {
2377 auto& base = inst.operands[2].getMemory().getBaseRegister();
2378
2379 /* Create symbolic operands of the post computation */
2380 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
2381
2382 /* Create the semantics of the base register */
2383 auto node3 = this->astCtxt->ite(cond, inst.operands[2].getMemory().getLeaAst(), baseNode);
2384
2385 /* Create symbolic expression */
2386 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, base, "LDRD operation - Pre-indexed base register computation");
2387
2388 /* Spread taint */
2389 this->spreadTaint(inst, cond, expr3, base, this->taintEngine->isTainted(base));
2390 }
2391
2392 /* Update condition flag */
2393 if (cond->evaluate() == true) {
2394 inst.setConditionTaken(true);
2395
2396 /* Update execution mode accordingly. */
2397 this->updateExecutionState(dst1, op1);
2398 this->updateExecutionState(dst2, op2);
2399 }
2400
2401 /* Update the symbolic control flow */
2402 this->controlFlow_s(inst, cond, dst1, dst2);
2403 }
2404
2405
2406 void Arm32Semantics::ldrex_s(triton::arch::Instruction& inst) {
2407 /* NOTE This is a simplified version of the semantics of this
2408 * instruction. We only check for a global exclusive memory
2409 * access flag.
2410 */
2411 auto& dst = inst.operands[0];
2412 auto& src = inst.operands[1];
2413
2414 /* Create symbolic operands */
2415 auto op = this->getArm32SourceOperandAst(inst, src);
2416
2417 /* Create the semantics */
2418 auto node1 = this->buildConditionalSemantics(inst, dst, op);
2419
2420 /* Create symbolic expression */
2421 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "LDREX operation");
2422
2423 /* Get condition code node */
2424 auto cond = this->getCodeConditionAst(inst);
2425
2426 /* Spread taint */
2427 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
2428
2429 /* Update exclusive memory access tag */
2430 this->architecture->setMemoryExclusiveTag(src.getConstMemory(), true);
2431
2432 /* Update condition flag */
2433 if (cond->evaluate() == true) {
2434 inst.setConditionTaken(true);
2435
2436 /* Update execution mode accordingly. */
2437 this->updateExecutionState(dst, op);
2438 }
2439
2440 /* Update the symbolic control flow */
2441 this->controlFlow_s(inst, cond, dst);
2442 }
2443
2444
2445 void Arm32Semantics::ldrsh_s(triton::arch::Instruction& inst) {
2446 auto& dst = inst.operands[0];
2447 auto& src = inst.operands[1];
2448
2449 /* Create symbolic operands */
2450 auto op = this->symbolicEngine->getOperandAst(inst, src);
2451
2452 /* Create the semantics */
2453 auto node1 = this->astCtxt->sx(dst.getBitSize() - src.getBitSize(), op);
2454 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
2455
2456 /* Create symbolic expression */
2457 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "LDRSH operation - LOAD access");
2458
2459 /* Get condition code node */
2460 auto cond = this->getCodeConditionAst(inst);
2461
2462 /* Spread taint */
2463 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
2464
2465 /* Optional behavior. Post-indexed computation of the base register */
2466 /* NOTE: There are two possible cases here:
2467 * - LDRB <Rt>, [<Rn>], #+/-<imm>
2468 * - LDRB <Rt>, [<Rn>], +/-<Rm>
2469 */
2470 if (inst.operands.size() == 3) {
2471 if (inst.operands[2].getType() == OP_IMM) {
2472 auto& imm = inst.operands[2].getImmediate();
2473 auto& base = src.getMemory().getBaseRegister();
2474
2475 /* Create symbolic operands of the post computation */
2476 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
2477 auto immNode = this->symbolicEngine->getOperandAst(inst, imm);
2478
2479 /* Create the semantics of the base register */
2480 auto thenNode = this->astCtxt->bvadd(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode));
2481
2482 if (imm.isSubtracted() == true) {
2483 thenNode = this->astCtxt->bvsub(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode));
2484 }
2485
2486 auto node2 = this->astCtxt->ite(cond, thenNode, baseNode);
2487
2488 /* Create symbolic expression */
2489 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, base, "LDRSH operation - Post-indexed base register computation");
2490
2491 /* Spread taint */
2492 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base));
2493 } else {
2494 auto& reg = inst.operands[2].getRegister();
2495 auto& base = src.getMemory().getBaseRegister();
2496
2497 /* Create symbolic operands of the post computation */
2498 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
2499 auto regNode = this->symbolicEngine->getOperandAst(inst, reg);
2500
2501 /* Create the semantics of the base register */
2502 auto thenNode = this->astCtxt->bvadd(baseNode, regNode);
2503
2504 if (reg.isSubtracted() == true) {
2505 thenNode = this->astCtxt->bvsub(baseNode, regNode);
2506 }
2507
2508 auto node2 = this->astCtxt->ite(cond, thenNode, baseNode);
2509
2510 /* Create symbolic expression */
2511 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, base, "LDRSH operation - Post-indexed base register computation");
2512
2513 /* Spread taint */
2514 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base));
2515 }
2516 }
2517
2518 /* Optional behavior. Pre-indexed computation of the base register */
2519 /* LDR <Rt>, [<Rn>, #+/-<imm>]! */
2520 else if (inst.operands.size() == 2 && inst.isWriteBack() == true) {
2521 auto& base = src.getMemory().getBaseRegister();
2522
2523 /* Create symbolic operands of the post computation */
2524 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
2525
2526 /* Create the semantics of the base register */
2527 auto node3 = this->astCtxt->ite(cond, src.getMemory().getLeaAst(), baseNode);
2528
2529 /* Create symbolic expression */
2530 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, base, "LDRB operation - Pre-indexed base register computation");
2531
2532 /* Spread taint */
2533 this->spreadTaint(inst, cond, expr3, base, this->taintEngine->isTainted(base));
2534 }
2535
2536 /* Update condition flag */
2537 if (cond->evaluate() == true) {
2538 inst.setConditionTaken(true);
2539
2540 /* Update execution mode accordingly. */
2541 this->updateExecutionState(dst, node1);
2542 }
2543
2544 /* Update the symbolic control flow */
2545 this->controlFlow_s(inst, cond, dst);
2546 }
2547
2548
2549 void Arm32Semantics::lsl_s(triton::arch::Instruction& inst) {
2550 auto& dst = inst.operands[0];
2551 auto& src1 = inst.operands[1];
2552
2553 /* Create symbolic operands */
2554 auto op1base = this->getArm32SourceBaseOperandAst(inst, src1);
2555 auto op1 = this->getArm32SourceOperandAst(inst, src1);
2556
2557 /* Create the semantics */
2559
2560 /* Two-operand version: LSL {<Rd>,} <Rm>, #<imm>. Here #<imm> is
2561 * interpreted as a shift value for <Rm>, which is handled directly
2562 * by the getArm32SourceOperandAst function. */
2563 if (inst.operands.size() == 2) {
2564 node1 = op1;
2565 }
2566 /* Three-operand version: LSL {<Rd>,} <Rn>, <Rm>. Here <Rm> is a
2567 * regular register and holds the value to shift the <Rn> register.
2568 * The operation must be explicitly done here.
2569 */
2570 else {
2571 auto& src2 = inst.operands[2];
2572
2573 auto op2 = this->getArm32SourceOperandAst(inst, src2);
2574
2575 node1 = this->astCtxt->bvshl(
2576 op1,
2577 this->astCtxt->zx(
2579 this->astCtxt->extract(7, 0, op2)
2580 )
2581 );
2582 }
2583
2584 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
2585
2586 /* Create symbolic expression */
2587 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "LSL(S) operation");
2588
2589 /* Get condition code node */
2590 auto cond = this->getCodeConditionAst(inst);
2591
2592 /* Spread taint */
2593 auto taint = this->taintEngine->isTainted(src1);
2594
2595 if (inst.operands.size() == 3) {
2596 auto& src2 = inst.operands[2];
2597
2598 taint |= this->taintEngine->isTainted(src2);
2599 }
2600
2601 this->spreadTaint(inst, cond, expr, dst, taint);
2602
2603 /* Update symbolic flags */
2604 if (inst.isUpdateFlag() == true) {
2605 auto& src = inst.operands.size() == 2 ? inst.operands[1] : inst.operands[2];
2606
2607 this->cfLsl_s(inst, cond, expr, op1base, src);
2608 this->nf_s(inst, cond, expr, dst);
2609 this->zf_s(inst, cond, expr, dst);
2610 }
2611
2612 /* Update condition flag */
2613 if (cond->evaluate() == true) {
2614 inst.setConditionTaken(true);
2615
2616 /* Update execution mode accordingly. */
2617 this->updateExecutionState(dst, node2);
2618 }
2619
2620 /* Update the symbolic control flow */
2621 this->controlFlow_s(inst, cond, dst);
2622 }
2623
2624
2625 void Arm32Semantics::lsr_s(triton::arch::Instruction& inst) {
2626 auto& dst = inst.operands[0];
2627 auto& src1 = inst.operands[1];
2628
2629 /* Create symbolic operands */
2630 auto op1base = this->getArm32SourceBaseOperandAst(inst, src1);
2631 auto op1 = this->getArm32SourceOperandAst(inst, src1);
2632
2633 /* Create the semantics */
2635
2636 /* Two-operand version: ASR {<Rd>,} <Rm>, #<imm>. Here #<imm> is
2637 * interpreted as a shift value for <Rm>, which is handled directly
2638 * by the getArm32SourceOperandAst function. */
2639 if (inst.operands.size() == 2) {
2640 node1 = op1;
2641 }
2642 /* Three-operand version: ASR {<Rd>,} <Rn>, <Rm>. Here <Rm> is a
2643 * regular register and holds the value to shift the <Rn> register.
2644 * The operation must be explicitly done here.
2645 */
2646 else {
2647 auto& src2 = inst.operands[2];
2648
2649 auto op2 = this->getArm32SourceOperandAst(inst, src2);
2650
2651 node1 = this->astCtxt->bvlshr(
2652 op1,
2653 this->astCtxt->zx(
2655 this->astCtxt->extract(7, 0, op2)
2656 )
2657 );
2658 }
2659
2660 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
2661
2662 /* Create symbolic expression */
2663 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "LSR(S) operation");
2664
2665 /* Get condition code node */
2666 auto cond = this->getCodeConditionAst(inst);
2667
2668 /* Spread taint */
2669 auto taint = this->taintEngine->isTainted(src1);
2670
2671 if (inst.operands.size() == 3) {
2672 auto& src2 = inst.operands[2];
2673
2674 taint |= this->taintEngine->isTainted(src2);
2675 }
2676
2677 this->spreadTaint(inst, cond, expr, dst, taint);
2678
2679 /* Update symbolic flags */
2680 if (inst.isUpdateFlag() == true) {
2681 auto& src = inst.operands.size() == 2 ? inst.operands[1] : inst.operands[2];
2682
2683 this->cfLsr_s(inst, cond, expr, op1base, src);
2684 this->nf_s(inst, cond, expr, dst);
2685 this->zf_s(inst, cond, expr, dst);
2686 }
2687
2688 /* Update condition flag */
2689 if (cond->evaluate() == true) {
2690 inst.setConditionTaken(true);
2691
2692 /* Update execution mode accordingly. */
2693 this->updateExecutionState(dst, node2);
2694 }
2695
2696 /* Update the symbolic control flow */
2697 this->controlFlow_s(inst, cond, dst);
2698 }
2699
2700
2701 void Arm32Semantics::mla_s(triton::arch::Instruction& inst) {
2702 auto& dst = inst.operands[0];
2703 auto& src1 = inst.operands[1];
2704 auto& src2 = inst.operands[2];
2705 auto& src3 = inst.operands[3];
2706 auto bvSize = dst.getBitSize();
2707
2708 /* Create symbolic operands */
2709 auto op1 = this->getArm32SourceOperandAst(inst, src1);
2710 auto op2 = this->getArm32SourceOperandAst(inst, src2);
2711 auto op3 = this->getArm32SourceOperandAst(inst, src3);
2712
2713 /* Create the semantics */
2714 auto mla = this->astCtxt->bvadd(
2715 this->astCtxt->bvmul(
2716 this->astCtxt->sx(2*bvSize, op1),
2717 this->astCtxt->sx(2*bvSize, op2)
2718 ),
2719 this->astCtxt->sx(2*bvSize, op3)
2720 );
2721 auto lower = this->astCtxt->extract(bvSize-1, 0, mla);
2722 auto node1 = this->buildConditionalSemantics(inst, dst, lower);
2723
2724 /* Create symbolic expression */
2725 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "MLA(S) operation");
2726
2727 /* Get condition code node */
2728 auto cond = node1->getChildren()[0];
2729
2730 /* Spread taint */
2731 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
2732
2733 /* Update symbolic flags */
2734 if (inst.isUpdateFlag() == true) {
2735 this->nf_s(inst, cond, expr, dst);
2736 this->zf_s(inst, cond, expr, dst);
2737 }
2738
2739 /* Update condition flag */
2740 if (cond->evaluate() == true) {
2741 inst.setConditionTaken(true);
2742 }
2743
2744 /* Update the symbolic control flow */
2745 this->controlFlow_s(inst, cond, dst);
2746 }
2747
2748
2749 void Arm32Semantics::mls_s(triton::arch::Instruction& inst) {
2750 auto& dst = inst.operands[0];
2751 auto& src1 = inst.operands[1];
2752 auto& src2 = inst.operands[2];
2753 auto& src3 = inst.operands[3];
2754 auto bvSize = dst.getBitSize();
2755
2756 /* Create symbolic operands */
2757 auto op1 = this->getArm32SourceOperandAst(inst, src1);
2758 auto op2 = this->getArm32SourceOperandAst(inst, src2);
2759 auto op3 = this->getArm32SourceOperandAst(inst, src3);
2760
2761 /* Create the semantics */
2762 auto mls = this->astCtxt->bvsub(
2763 this->astCtxt->sx(2*bvSize, op3),
2764 this->astCtxt->bvmul(
2765 this->astCtxt->sx(2*bvSize, op1),
2766 this->astCtxt->sx(2*bvSize, op2)
2767 )
2768 );
2769 auto lower = this->astCtxt->extract(bvSize-1, 0, mls);
2770 auto node1 = this->buildConditionalSemantics(inst, dst, lower);
2771
2772 /* Create symbolic expression */
2773 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "MLS operation");
2774
2775 /* Get condition code node */
2776 auto cond = node1->getChildren()[0];
2777
2778 /* Spread taint */
2779 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
2780
2781 /* Update condition flag */
2782 if (cond->evaluate() == true) {
2783 inst.setConditionTaken(true);
2784 }
2785
2786 /* Update the symbolic control flow */
2787 this->controlFlow_s(inst, cond, dst);
2788 }
2789
2790
2791 void Arm32Semantics::mov_s(triton::arch::Instruction& inst) {
2792 auto& dst = inst.operands[0];
2793 auto& src = inst.operands[1];
2794
2795 /* Create symbolic operands */
2796 auto op1 = this->getArm32SourceOperandAst(inst, dst);
2797 auto op2 = this->getArm32SourceOperandAst(inst, src);
2798
2799 /* Create the semantics */
2800 auto node = this->buildConditionalSemantics(inst, dst, op2);
2801
2802 /* Create symbolic expression */
2803 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "MOV(s) operation");
2804
2805 /* Get condition code node */
2806 auto cond = this->getCodeConditionAst(inst);
2807
2808 /* Spread taint */
2809 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
2810
2811 /* Update symbolic flags */
2812 if (inst.isUpdateFlag() == true) {
2813 this->nf_s(inst, cond, expr, dst);
2814 this->zf_s(inst, cond, expr, dst);
2815
2816 /* NOTE: The following if statement was added to properly handle
2817 * the case when PC is the destination register when the S suffix is
2818 * present (e.g.: 'movseq pc, r4'). The manual is not clear in this
2819 * case. We arrived to this solution after testing and comparing the
2820 * behavior against UC.
2821 */
2822 if (dst.getRegister().getId() == ID_REG_ARM32_PC) {
2823 this->cfAdd_s(inst, cond, expr, dst, op1, op2);
2824 this->vfAdd_s(inst, cond, expr, dst, op1, op2);
2825 }
2826 }
2827
2828 /* Update condition flag */
2829 if (cond->evaluate() == true) {
2830 inst.setConditionTaken(true);
2831
2832 /* Update execution mode accordingly. */
2833 this->updateExecutionState(dst, op2);
2834 }
2835
2836 /* Update the symbolic control flow */
2837 this->controlFlow_s(inst, cond, dst);
2838 }
2839
2840
2841 void Arm32Semantics::movt_s(triton::arch::Instruction& inst) {
2842 auto& dst = inst.operands[0];
2843 auto& src = inst.operands[1];
2844
2845 /* Special behavior: Define that the size of the imm access is 16 bits */
2846 src.getImmediate().setBits(15, 0);
2847
2848 /* Create symbolic operands */
2849 auto dstOp = this->getArm32SourceOperandAst(inst, dst);
2850 auto srcOp = this->getArm32SourceOperandAst(inst, src);
2851
2852 /* Create the semantics */
2853 auto node1 = this->astCtxt->concat(srcOp, this->astCtxt->extract(15, 0, dstOp));
2854 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
2855
2856 /* Create symbolic expression */
2857 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "MOVT operation");
2858
2859 /* Get condition code node */
2860 auto cond = this->getCodeConditionAst(inst);
2861
2862 /* Spread taint */
2863 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
2864
2865 /* Update symbolic flags */
2866 if (inst.isUpdateFlag() == true) {
2867 this->nf_s(inst, cond, expr, dst);
2868 this->zf_s(inst, cond, expr, dst);
2869 }
2870
2871 /* Update condition flag */
2872 if (cond->evaluate() == true) {
2873 inst.setConditionTaken(true);
2874 }
2875
2876 /* Update the symbolic control flow */
2877 this->controlFlow_s(inst, cond, dst);
2878 }
2879
2880
2881 void Arm32Semantics::mul_s(triton::arch::Instruction& inst) {
2882 auto& dst = inst.operands[0];
2883 auto& src1 = inst.operands[1];
2884 auto& src2 = inst.operands[2];
2885 auto bvSize = dst.getBitSize();
2886
2887 /* Create symbolic operands */
2888 auto op1 = this->getArm32SourceOperandAst(inst, src1);
2889 auto op2 = this->getArm32SourceOperandAst(inst, src2);
2890
2891 /* Create the semantics */
2892 auto mul = this->astCtxt->bvmul(
2893 this->astCtxt->sx(2*bvSize, op1),
2894 this->astCtxt->sx(2*bvSize, op2)
2895 );
2896 auto lower = this->astCtxt->extract(bvSize-1, 0, mul);
2897 auto node1 = this->buildConditionalSemantics(inst, dst, lower);
2898
2899 /* Create symbolic expression */
2900 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "MUL(S) operation");
2901
2902 /* Get condition code node */
2903 auto cond = this->getCodeConditionAst(inst);
2904
2905 /* Spread taint */
2906 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
2907
2908 /* Update symbolic flags */
2909 if (inst.isUpdateFlag() == true) {
2910 this->nf_s(inst, cond, expr, dst);
2911 this->zf_s(inst, cond, expr, dst);
2912 }
2913
2914 /* Update condition flag */
2915 if (cond->evaluate() == true) {
2916 inst.setConditionTaken(true);
2917 }
2918
2919 /* Update the symbolic control flow */
2920 this->controlFlow_s(inst, cond, dst);
2921 }
2922
2923
2924 void Arm32Semantics::mvn_s(triton::arch::Instruction& inst) {
2925 auto& dst = inst.operands[0];
2926 auto& src = inst.operands[1];
2927
2928 /* Create symbolic operands */
2929 auto op = this->getArm32SourceOperandAst(inst, src);
2930
2931 /* Create the semantics */
2932 auto node1 = this->astCtxt->bvnot(op);
2933 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
2934
2935 /* Create symbolic expression */
2936 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "MVN(S) operation");
2937
2938 /* Get condition code node */
2939 auto cond = this->getCodeConditionAst(inst);
2940
2941 /* Spread taint */
2942 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
2943
2944 /* Update symbolic flags */
2945 if (inst.isUpdateFlag() == true) {
2946 this->cfBitwise_s(inst, cond, expr, src);
2947 this->nf_s(inst, cond, expr, dst);
2948 this->zf_s(inst, cond, expr, dst);
2949 }
2950
2951 /* Update condition flag */
2952 if (cond->evaluate() == true) {
2953 inst.setConditionTaken(true);
2954
2955 /* Update execution mode accordingly. */
2956 this->updateExecutionState(dst, node1);
2957 }
2958
2959 /* Update the symbolic control flow */
2960 this->controlFlow_s(inst, cond, dst);
2961 }
2962
2963
2964 void Arm32Semantics::nop_s(triton::arch::Instruction& inst) {
2965 /* Update the symbolic control flow */
2966 this->controlFlow_s(inst);
2967 }
2968
2969
2970 void Arm32Semantics::orn_s(triton::arch::Instruction& inst) {
2971 auto& dst = inst.operands[0];
2972 auto& src1 = inst.operands[1];
2973 auto& src2 = inst.operands[2];
2974
2975 /* Create symbolic operands */
2976 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
2977 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
2978
2979 /* Create the semantics */
2980 auto node1 = this->astCtxt->bvor(op1, this->astCtxt->bvnot(op2));
2981 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
2982
2983 /* Get condition code node */
2984 auto cond = this->getCodeConditionAst(inst);
2985
2986 /* Create symbolic expression */
2987 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "ORN operation");
2988
2989 /* Spread taint */
2990 this->spreadTaint(inst,cond ,expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
2991
2992 /* Update the symbolic control flow */
2993 this->controlFlow_s(inst);
2994 }
2995
2996
2997 void Arm32Semantics::orr_s(triton::arch::Instruction& inst) {
2998 auto& dst = inst.operands[0];
2999 auto& src1 = inst.operands[1];
3000 auto& src2 = inst.operands[2];
3001
3002 /* Process modified immediate constants (expand immediate) */
3003 /* For more information, look for "Modified immediate constants in ARM
3004 * instructions" in the reference manual. For example:
3005 * "orr r0, r0, #16, #20".
3006 */
3007 if (inst.operands.size() == 4) {
3008 auto src3 = inst.operands[3];
3009
3010 if (src2.getType() == OP_IMM && src3.getType() == OP_IMM) {
3011 auto size = src2.getSize();
3012 auto value = static_cast<triton::uint32>(src2.getImmediate().getValue());
3013 auto shift = static_cast<triton::uint32>(src3.getImmediate().getValue());
3014
3015 /* Replace src2 with the expanded immediate */
3016 src2 = triton::arch::OperandWrapper(triton::arch::Immediate(this->ror(value, shift), size));
3017 } else {
3018 throw triton::exceptions::Semantics("Arm32Semantics::orr_s(): Invalid operand type.");
3019 }
3020 }
3021
3022 /* Create symbolic operands */
3023 auto op1 = this->getArm32SourceOperandAst(inst, src1);
3024 auto op2 = this->getArm32SourceOperandAst(inst, src2);
3025
3026 /* Create the semantics */
3027 auto node1 = this->astCtxt->bvor(op1, op2);
3028 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
3029
3030 /* Create symbolic expression */
3031 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "OOR(S) operation");
3032
3033 /* Get condition code node */
3034 auto cond = this->getCodeConditionAst(inst);
3035
3036 /* Spread taint */
3037 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
3038
3039 /* Update symbolic flags */
3040 if (inst.isUpdateFlag() == true) {
3041 this->cfBitwise_s(inst, cond, expr, src2);
3042 this->nf_s(inst, cond, expr, dst);
3043 this->zf_s(inst, cond, expr, dst);
3044 }
3045
3046 /* Update condition flag */
3047 if (cond->evaluate() == true) {
3048 inst.setConditionTaken(true);
3049
3050 /* Update execution mode accordingly. */
3051 this->updateExecutionState(dst, node1);
3052 }
3053
3054 /* Update the symbolic control flow */
3055 this->controlFlow_s(inst, cond, dst);
3056 }
3057
3058
3059 void Arm32Semantics::pop_s(triton::arch::Instruction& inst) {
3060 auto stack = this->architecture->getStackPointer();
3061 triton::uint32 size = stack.getSize();
3062
3063 /* Create the semantics */
3064 auto cond = this->getCodeConditionAst(inst);
3065
3066 bool updateControlFlow = true;
3067
3068 for (uint8_t i = 0; i < inst.operands.size(); i++) {
3069 auto& dst = inst.operands[i];
3070 auto stack = this->architecture->getStackPointer();
3071 auto stackValue = static_cast<triton::uint64>(this->architecture->getConcreteRegisterValue(stack));
3072 auto src = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, size));
3073
3074 /* Create symbolic operands */
3075 auto op1 = this->getArm32SourceOperandAst(inst, dst);
3076 auto op2 = this->getArm32SourceOperandAst(inst, src);
3077
3078 /* Create the semantics */
3079 auto node1 = op2;
3080
3081 /* In case PC is one of the destination registers, clear ISSB
3082 * (instruction set selection bit) from the value that will be
3083 * assigned to it.
3084 */
3085 if (dst.getRegister().getId() == ID_REG_ARM32_PC) {
3086 node1 = this->clearISSB(op2);
3087 }
3088
3089 auto node2 = this->astCtxt->ite(cond, node1, op1);
3090
3091 /* Create symbolic expression */
3092 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "POP operation - Pop register");
3093
3094 /* Spread taint */
3095 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
3096
3097 /* Align stack */
3098 alignAddStack_s(inst, cond, size);
3099
3100 /* If PC was modified, do not update the control flow at the end of
3101 * the function.
3102 */
3103 if (cond->evaluate() == true && dst.getRegister().getId() == ID_REG_ARM32_PC) {
3104 updateControlFlow = false;
3105
3106 /* Update execution mode accordingly. */
3107 this->updateExecutionState(dst, op2);
3108 }
3109 }
3110
3111 /* Update the symbolic control flow */
3112 if (updateControlFlow) {
3113 this->controlFlow_s(inst);
3114 }
3115 }
3116
3117
3118 void Arm32Semantics::push_s(triton::arch::Instruction& inst) {
3119 auto stack = this->architecture->getStackPointer();
3120 triton::uint32 size = stack.getSize();
3121 triton::usize nuop = inst.operands.size() - 1;
3122
3123 /* Create the semantics */
3124 auto cond = this->getCodeConditionAst(inst);
3125
3126 for (triton::uint32 i = 0; i <= nuop; i++) {
3127 auto& src = inst.operands[nuop - i];
3128
3129 /* Create symbolic operands */
3130 auto op = this->getArm32SourceOperandAst(inst, src);
3131
3132 /* Create the semantics - side effect */
3133 auto stackValue = alignSubStack_s(inst, cond, size);
3134 auto dst = triton::arch::OperandWrapper(triton::arch::MemoryAccess(stackValue, size));
3135
3136 /* Create the semantics */
3137 auto node = this->astCtxt->ite(cond, op, this->astCtxt->bv(stackValue, op->getBitvectorSize()));
3138
3139 /* Create symbolic expression */
3140 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "PUSH operation - Push register");
3141
3142 /* Spread taint */
3143 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
3144 }
3145
3146 /* Update the symbolic control flow */
3147 this->controlFlow_s(inst);
3148 }
3149
3150
3151 void Arm32Semantics::rbit_s(triton::arch::Instruction& inst) {
3152 auto& dst = inst.operands[0];
3153 auto& src = inst.operands[1];
3154
3155 /* Create symbolic operands */
3156 auto op = this->symbolicEngine->getOperandAst(inst, src);
3157
3158 /* Create the semantics */
3159 std::vector<triton::ast::SharedAbstractNode> bits;
3160 bits.reserve(src.getBitSize());
3161
3162 for (triton::uint32 index = 0; index < src.getBitSize(); index++) {
3163 bits.push_back(this->astCtxt->extract(index, index, op));
3164 }
3165
3166 auto node1 = this->astCtxt->concat(bits);
3167 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
3168
3169 /* Get condition code node */
3170 auto cond = this->getCodeConditionAst(inst);
3171
3172 /* Create symbolic expression */
3173 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "RBIT operation");
3174
3175 /* Spread taint */
3176 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
3177
3178 /* Update the symbolic control flow */
3179 this->controlFlow_s(inst);
3180 }
3181
3182
3183 void Arm32Semantics::rev16_s(triton::arch::Instruction& inst) {
3184 auto& dst = inst.operands[0];
3185 auto& src = inst.operands[1];
3186
3187 /* Create symbolic operands */
3188 auto op = this->symbolicEngine->getOperandAst(inst, src);
3189
3190 /* Create the semantics */
3191 std::vector<triton::ast::SharedAbstractNode> bits;
3192 bits.reserve(8);
3193
3194 switch(src.getSize()) {
3196 bits.push_back(this->astCtxt->extract(23, 16, op));
3197 bits.push_back(this->astCtxt->extract(31, 24, op));
3198 bits.push_back(this->astCtxt->extract(7, 0, op));
3199 bits.push_back(this->astCtxt->extract(15, 8, op));
3200 break;
3201
3202 default:
3203 throw triton::exceptions::Semantics("Arm32Semantic::rev16_s(): Invalid operand size.");
3204 }
3205
3206 auto node1 = this->astCtxt->concat(bits);
3207 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
3208
3209 /* Get condition code node */
3210 auto cond = this->getCodeConditionAst(inst);
3211
3212 /* Create symbolic expression */
3213 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "REV16 operation");
3214
3215 /* Spread taint */
3216 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
3217
3218 /* Update the symbolic control flow */
3219 this->controlFlow_s(inst);
3220 }
3221
3222
3223 void Arm32Semantics::rev_s(triton::arch::Instruction& inst) {
3224 auto& dst = inst.operands[0];
3225 auto& src = inst.operands[1];
3226
3227 /* Create symbolic operands */
3228 auto op = this->getArm32SourceOperandAst(inst, src);
3229
3230 /* Create the semantics */
3231 std::list<triton::ast::SharedAbstractNode> bits;
3232
3233 bits.push_front(this->astCtxt->extract(31, 24, op));
3234 bits.push_front(this->astCtxt->extract(23, 16, op));
3235 bits.push_front(this->astCtxt->extract(15, 8, op));
3236 bits.push_front(this->astCtxt->extract(7, 0, op));
3237
3238 auto node1 = this->astCtxt->concat(bits);
3239 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
3240
3241 /* Create symbolic expression */
3242 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "REV operation");
3243
3244 /* Get condition code node */
3245 auto cond = this->getCodeConditionAst(inst);
3246
3247 /* Spread taint */
3248 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
3249
3250 /* Update condition flag */
3251 if (cond->evaluate() == true) {
3252 inst.setConditionTaken(true);
3253
3254 /* Update execution mode accordingly. */
3255 this->updateExecutionState(dst, node1);
3256 }
3257
3258 /* Update the symbolic control flow */
3259 this->controlFlow_s(inst, cond, dst);
3260 }
3261
3262
3263 void Arm32Semantics::ror_s(triton::arch::Instruction& inst) {
3264 auto& dst = inst.operands[0];
3265 auto& src1 = inst.operands[1];
3266
3267 /* Create symbolic operands */
3268 auto op1base = this->getArm32SourceBaseOperandAst(inst, src1);
3269 auto op1 = this->getArm32SourceOperandAst(inst, src1);
3270
3271 /* Create the semantics */
3273
3274 /* Two-operand version: ASR {<Rd>,} <Rm>, #<imm>. Here #<imm> is
3275 * interpreted as a shift value for <Rm>, which is handled directly
3276 * by the getArm32SourceOperandAst function. */
3277 if (inst.operands.size() == 2) {
3278 node1 = op1;
3279 }
3280 /* Three-operand version: ASR {<Rd>,} <Rn>, <Rm>. Here <Rm> is a
3281 * regular register and holds the value to shift the <Rn> register.
3282 * The operation must be explicitly done here.
3283 */
3284 else {
3285 auto& src2 = inst.operands[2];
3286
3287 auto op2 = this->getArm32SourceOperandAst(inst, src2);
3288
3289 node1 = this->astCtxt->bvror(
3290 op1,
3291 this->astCtxt->zx(
3293 this->astCtxt->extract(7, 0, op2)
3294 )
3295 );
3296 }
3297
3298 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
3299
3300 /* Create symbolic expression */
3301 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "ROR(S) operation");
3302
3303 /* Get condition code node */
3304 auto cond = this->getCodeConditionAst(inst);
3305
3306 /* Spread taint */
3307 auto taint = this->taintEngine->isTainted(src1);
3308
3309 if (inst.operands.size() == 3) {
3310 auto& src2 = inst.operands[2];
3311
3312 taint |= this->taintEngine->isTainted(src2);
3313 }
3314
3315 this->spreadTaint(inst, cond, expr, dst, taint);
3316
3317 /* Update symbolic flags */
3318 if (inst.isUpdateFlag() == true) {
3319 auto& src = inst.operands.size() == 2 ? inst.operands[1] : inst.operands[2];
3320
3321 this->cfRor_s(inst, cond, expr, op1base, src);
3322 this->nf_s(inst, cond, expr, dst);
3323 this->zf_s(inst, cond, expr, dst);
3324 }
3325
3326 /* Update condition flag */
3327 if (cond->evaluate() == true) {
3328 inst.setConditionTaken(true);
3329
3330 /* Update execution mode accordingly. */
3331 this->updateExecutionState(dst, node2);
3332 }
3333
3334 /* Update the symbolic control flow */
3335 this->controlFlow_s(inst, cond, dst);
3336 }
3337
3338
3339 void Arm32Semantics::rrx_s(triton::arch::Instruction& inst) {
3340 auto& dst = inst.operands[0];
3341 auto& src = inst.operands[1];
3342 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_C));
3343
3344 /* Create symbolic operands */
3345 auto op1base = this->getArm32SourceBaseOperandAst(inst, src);
3346 auto op1 = this->getArm32SourceOperandAst(inst, src);
3347 auto op2 = this->getArm32SourceOperandAst(inst, cf);
3348
3349 /* Create the semantics */
3350 auto node1 = this->astCtxt->extract(
3351 op1->getBitvectorSize(),
3352 1,
3353 this->astCtxt->bvror(
3354 this->astCtxt->concat(op1, op2),
3355 1
3356 )
3357 );
3358 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
3359
3360 /* Create symbolic expression */
3361 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "RRX(S) operation");
3362
3363 /* Get condition code node */
3364 auto cond = this->getCodeConditionAst(inst);
3365
3366 /* Spread taint */
3367 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
3368
3369 /* Update symbolic flags */
3370 if (inst.isUpdateFlag() == true) {
3371 this->cfRrx_s(inst, cond, expr, op1base, src);
3372 this->nf_s(inst, cond, expr, dst);
3373 this->zf_s(inst, cond, expr, dst);
3374 }
3375
3376 /* Update condition flag */
3377 if (cond->evaluate() == true) {
3378 inst.setConditionTaken(true);
3379
3380 /* Update execution mode accordingly. */
3381 this->updateExecutionState(dst, node2);
3382 }
3383
3384 /* Update the symbolic control flow */
3385 this->controlFlow_s(inst, cond, dst);
3386 }
3387
3388
3389 void Arm32Semantics::rsb_s(triton::arch::Instruction& inst) {
3390 auto& dst = inst.operands[0];
3391 auto& src1 = inst.operands[1];
3392 auto& src2 = inst.operands[2];
3393
3394 /* Process modified immediate constants (expand immediate) */
3395 /* For more information, look for "Modified immediate constants in ARM
3396 * instructions" in the reference manual. For example:
3397 * "rsb r0, r0, #16, #20".
3398 */
3399 if (inst.operands.size() == 4) {
3400 auto src3 = inst.operands[3];
3401
3402 if (src2.getType() == OP_IMM && src3.getType() == OP_IMM) {
3403 auto size = src2.getSize();
3404 auto value = static_cast<triton::uint32>(src2.getImmediate().getValue());
3405 auto shift = static_cast<triton::uint32>(src3.getImmediate().getValue());
3406
3407 /* Replace src2 with the expanded immediate */
3408 src2 = triton::arch::OperandWrapper(triton::arch::Immediate(this->ror(value, shift), size));
3409 } else {
3410 throw triton::exceptions::Semantics("Arm32Semantics::rsb_s(): Invalid operand type.");
3411 }
3412 }
3413
3414 /* Create symbolic operands */
3415 auto op1 = this->getArm32SourceOperandAst(inst, src1);
3416 auto op2 = this->getArm32SourceOperandAst(inst, src2);
3417
3418 /* Create the semantics */
3419 auto node1 = this->astCtxt->bvsub(op2, op1);
3420 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
3421
3422 /* Create symbolic expression */
3423 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "RSB(S) operation");
3424
3425 /* Get condition code node */
3426 auto cond = this->getCodeConditionAst(inst);
3427
3428 /* Spread taint */
3429 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
3430
3431 /* Update symbolic flags */
3432 if (inst.isUpdateFlag() == true) {
3433 this->cfSub_s(inst, cond, expr, dst, op2, op1);
3434 this->nf_s(inst, cond, expr, dst);
3435 this->vfSub_s(inst, cond, expr, dst, op2, op1);
3436 this->zf_s(inst, cond, expr, dst);
3437 }
3438
3439 /* Update condition flag */
3440 if (cond->evaluate() == true) {
3441 inst.setConditionTaken(true);
3442
3443 /* Update execution mode accordingly. */
3444 this->updateExecutionState(dst, node1);
3445 }
3446
3447 /* Update the symbolic control flow */
3448 this->controlFlow_s(inst, cond, dst);
3449 }
3450
3451
3452 void Arm32Semantics::rsc_s(triton::arch::Instruction& inst) {
3453 auto& dst = inst.operands[0];
3454 auto& src1 = inst.operands[1];
3455 auto& src2 = inst.operands[2];
3456 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_C));
3457
3458 /* Process modified immediate constants (expand immediate) */
3459 /* For more information, look for "Modified immediate constants in ARM
3460 * instructions" in the reference manual. For example:
3461 * "rsc r0, r0, #16, #20".
3462 */
3463 if (inst.operands.size() == 4) {
3464 auto src3 = inst.operands[3];
3465
3466 if (src2.getType() == OP_IMM && src3.getType() == OP_IMM) {
3467 auto size = src2.getSize();
3468 auto value = static_cast<triton::uint32>(src2.getImmediate().getValue());
3469 auto shift = static_cast<triton::uint32>(src3.getImmediate().getValue());
3470
3471 /* Replace src2 with the expanded immediate */
3472 src2 = triton::arch::OperandWrapper(triton::arch::Immediate(this->ror(value, shift), size));
3473 } else {
3474 throw triton::exceptions::Semantics("Arm32Semantics::rsc_s(): Invalid operand type.");
3475 }
3476 }
3477
3478 /* Create symbolic operands */
3479 auto op1 = this->getArm32SourceOperandAst(inst, src1);
3480 auto op2 = this->getArm32SourceOperandAst(inst, src2);
3481 auto op3 = this->getArm32SourceOperandAst(inst, cf);
3482
3483 /* Create the semantics */
3484 auto node1 = this->astCtxt->bvadd(
3485 this->astCtxt->bvadd(op2, this->astCtxt->bvnot(op1)),
3486 this->astCtxt->zx(dst.getBitSize()-1, op3)
3487 );
3488 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
3489
3490 /* Create symbolic expression */
3491 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "RSB(S) operation");
3492
3493 /* Get condition code node */
3494 auto cond = this->getCodeConditionAst(inst);
3495
3496 /* Spread taint */
3497 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(cf));
3498
3499 /* Update symbolic flags */
3500 if (inst.isUpdateFlag() == true) {
3501 this->cfSub_s(inst, cond, expr, dst, op2, op1);
3502 this->nf_s(inst, cond, expr, dst);
3503 this->vfSub_s(inst, cond, expr, dst, op2, op1);
3504 this->zf_s(inst, cond, expr, dst);
3505 }
3506
3507 /* Update condition flag */
3508 if (cond->evaluate() == true) {
3509 inst.setConditionTaken(true);
3510
3511 /* Update execution mode accordingly. */
3512 this->updateExecutionState(dst, node1);
3513 }
3514
3515 /* Update the symbolic control flow */
3516 this->controlFlow_s(inst, cond, dst);
3517 }
3518
3519
3520 void Arm32Semantics::sbc_s(triton::arch::Instruction& inst) {
3521 auto& dst = inst.operands[0];
3522 auto& src1 = inst.operands[1];
3523 auto& src2 = inst.operands[2];
3524 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_C));
3525
3526 /* Process modified immediate constants (expand immediate) */
3527 /* For more information, look for "Modified immediate constants in ARM
3528 * instructions" in the reference manual. For example:
3529 * "sbc r0, r0, #16, #20".
3530 */
3531 if (inst.operands.size() == 4) {
3532 auto src3 = inst.operands[3];
3533
3534 if (src2.getType() == OP_IMM && src3.getType() == OP_IMM) {
3535 auto size = src2.getSize();
3536 auto value = static_cast<triton::uint32>(src2.getImmediate().getValue());
3537 auto shift = static_cast<triton::uint32>(src3.getImmediate().getValue());
3538
3539 /* Replace src2 with the expanded immediate */
3540 src2 = triton::arch::OperandWrapper(triton::arch::Immediate(this->ror(value, shift), size));
3541 } else {
3542 throw triton::exceptions::Semantics("Arm32Semantics::sbc_s(): Invalid operand type.");
3543 }
3544 }
3545
3546 /* Create symbolic operands */
3547 auto op1 = this->getArm32SourceOperandAst(inst, src1);
3548 auto op2 = this->getArm32SourceOperandAst(inst, src2);
3549 auto op3 = this->getArm32SourceOperandAst(inst, cf);
3550
3551 /* Create the semantics */
3552 auto node1 = this->astCtxt->bvadd(
3553 this->astCtxt->bvadd(op1, this->astCtxt->bvnot(op2)),
3554 this->astCtxt->zx(dst.getBitSize()-1, op3)
3555 );
3556 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
3557
3558 /* Create symbolic expression */
3559 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "SBC(S) operation");
3560
3561 /* Get condition code node */
3562 auto cond = this->getCodeConditionAst(inst);
3563
3564 /* Spread taint */
3565 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2) | this->taintEngine->isTainted(cf));
3566
3567 /* Update symbolic flags */
3568 if (inst.isUpdateFlag() == true) {
3569 /* NOTE: The following if statement was added to properly handle
3570 * the case when PC is the destination register when the S suffix is
3571 * present (e.g.: 'subseq pc, r4'). The manual is not clear in this
3572 * case. We arrived to this solution after testing and comparing the
3573 * behavior against UC.
3574 */
3575 if (dst.getRegister().getId() != ID_REG_ARM32_PC) {
3576 this->cfSub_s(inst, cond, expr, dst, op1, op2);
3577 }
3578 this->nf_s(inst, cond, expr, dst);
3579 this->vfSub_s(inst, cond, expr, dst, op1, op2);
3580 this->zf_s(inst, cond, expr, dst);
3581 }
3582
3583 /* Update condition flag */
3584 if (cond->evaluate() == true) {
3585 inst.setConditionTaken(true);
3586
3587 /* Update execution mode accordingly. */
3588 this->updateExecutionState(dst, node1);
3589 }
3590
3591 /* Update the symbolic control flow */
3592 this->controlFlow_s(inst, cond, dst);
3593 }
3594
3595
3596 void Arm32Semantics::sbfx_s(triton::arch::Instruction& inst) {
3597 auto& dst = inst.operands[0];
3598 auto& src1 = inst.operands[1];
3599 auto& src2 = inst.operands[2];
3600 auto& src3 = inst.operands[3];
3601 auto lsb = static_cast<uint32>(src2.getImmediate().getValue());
3602 auto width = static_cast<uint32>(src3.getImmediate().getValue());
3603
3604 if (lsb + width > dst.getBitSize())
3605 throw triton::exceptions::Semantics("Arm32Semantics::sbfx_s(): Invalid lsb and width.");
3606
3607 /* Create symbolic operands */
3608 auto op = this->symbolicEngine->getOperandAst(inst, src1);
3609
3610 /* Create the semantics */
3611 auto node1 = this->astCtxt->sx(dst.getBitSize() - width, this->astCtxt->extract(lsb+width-1, lsb, op));
3612 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
3613
3614 /* Create symbolic expression */
3615 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "SBFX operation");
3616
3617 /* Get condition code node */
3618 auto cond = this->getCodeConditionAst(inst);
3619
3620 /* Spread taint */
3621 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1));
3622
3623 /* Update the symbolic control flow */
3624 this->controlFlow_s(inst);
3625 }
3626
3627
3628 void Arm32Semantics::sdiv_s(triton::arch::Instruction& inst) {
3629 auto& dst = inst.operands[0];
3630 auto& src1 = inst.operands[1];
3631 auto& src2 = inst.operands[2];
3632
3633 /* Create symbolic operands */
3634 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
3635 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
3636
3637 /* Create the semantics */
3638 auto node1 = this->astCtxt->ite(
3639 this->astCtxt->equal(op2, this->astCtxt->bv(0, op2->getBitvectorSize())),
3640 this->astCtxt->bv(0, dst.getBitSize()),
3641 this->astCtxt->bvsdiv(op1, op2)
3642 );
3643 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
3644
3645 /* Create symbolic expression */
3646 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "SDIV operation");
3647
3648 /* Get condition code node */
3649 auto cond = this->getCodeConditionAst(inst);
3650
3651 /* Spread taint */
3652 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
3653
3654 /* Update the symbolic control flow */
3655 this->controlFlow_s(inst);
3656 }
3657
3658
3659 void Arm32Semantics::smlabb_s(triton::arch::Instruction& inst) {
3660 auto& dst = inst.operands[0];
3661 auto& src1 = inst.operands[1];
3662 auto& src2 = inst.operands[2];
3663 auto& src3 = inst.operands[3];
3664 auto bvSize = dst.getBitSize();
3665
3666 /* Create symbolic operands */
3667 auto op1 = this->getArm32SourceOperandAst(inst, src1);
3668 auto op2 = this->getArm32SourceOperandAst(inst, src2);
3669 auto op3 = this->getArm32SourceOperandAst(inst, src3);
3670
3671 /* Create the semantics */
3672 auto smla = this->astCtxt->bvadd(
3673 this->astCtxt->bvmul(
3674 this->astCtxt->sx(2*bvSize + 16, this->astCtxt->extract(15, 0, op1)),
3675 this->astCtxt->sx(2*bvSize + 16, this->astCtxt->extract(15, 0, op2))
3676 ),
3677 this->astCtxt->sx(2*bvSize, op3)
3678 );
3679 auto lower = this->astCtxt->extract(bvSize-1, 0, smla);
3680 auto node1 = this->buildConditionalSemantics(inst, dst, lower);
3681
3682 /* Create symbolic expression */
3683 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "SMLABB operation");
3684
3685 /* Get condition code node */
3686 auto cond = node1->getChildren()[0];
3687
3688 /* Spread taint */
3689 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
3690
3691 /* Update condition flag */
3692 if (cond->evaluate() == true) {
3693 inst.setConditionTaken(true);
3694 }
3695
3696 /* Update the symbolic control flow */
3697 this->controlFlow_s(inst, cond, dst);
3698 }
3699
3700
3701 void Arm32Semantics::smlabt_s(triton::arch::Instruction& inst) {
3702 auto& dst = inst.operands[0];
3703 auto& src1 = inst.operands[1];
3704 auto& src2 = inst.operands[2];
3705 auto& src3 = inst.operands[3];
3706 auto bvSize = dst.getBitSize();
3707
3708 /* Create symbolic operands */
3709 auto op1 = this->getArm32SourceOperandAst(inst, src1);
3710 auto op2 = this->getArm32SourceOperandAst(inst, src2);
3711 auto op3 = this->getArm32SourceOperandAst(inst, src3);
3712
3713 /* Create the semantics */
3714 auto smla = this->astCtxt->bvadd(
3715 this->astCtxt->bvmul(
3716 this->astCtxt->sx(2*bvSize + 16, this->astCtxt->extract(15, 0, op1)),
3717 this->astCtxt->sx(2*bvSize + 16, this->astCtxt->extract(31, 16, op2))
3718 ),
3719 this->astCtxt->sx(2*bvSize, op3)
3720 );
3721 auto lower = this->astCtxt->extract(bvSize-1, 0, smla);
3722 auto node1 = this->buildConditionalSemantics(inst, dst, lower);
3723
3724 /* Create symbolic expression */
3725 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "SMLABT operation");
3726
3727 /* Get condition code node */
3728 auto cond = node1->getChildren()[0];
3729
3730 /* Spread taint */
3731 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
3732
3733 /* Update condition flag */
3734 if (cond->evaluate() == true) {
3735 inst.setConditionTaken(true);
3736 }
3737
3738 /* Update the symbolic control flow */
3739 this->controlFlow_s(inst, cond, dst);
3740 }
3741
3742
3743 void Arm32Semantics::smlatb_s(triton::arch::Instruction& inst) {
3744 auto& dst = inst.operands[0];
3745 auto& src1 = inst.operands[1];
3746 auto& src2 = inst.operands[2];
3747 auto& src3 = inst.operands[3];
3748 auto bvSize = dst.getBitSize();
3749
3750 /* Create symbolic operands */
3751 auto op1 = this->getArm32SourceOperandAst(inst, src1);
3752 auto op2 = this->getArm32SourceOperandAst(inst, src2);
3753 auto op3 = this->getArm32SourceOperandAst(inst, src3);
3754
3755 /* Create the semantics */
3756 auto smla = this->astCtxt->bvadd(
3757 this->astCtxt->bvmul(
3758 this->astCtxt->sx(2*bvSize + 16, this->astCtxt->extract(31, 16, op1)),
3759 this->astCtxt->sx(2*bvSize + 16, this->astCtxt->extract(15, 0, op2))
3760 ),
3761 this->astCtxt->sx(2*bvSize, op3)
3762 );
3763 auto lower = this->astCtxt->extract(bvSize-1, 0, smla);
3764 auto node1 = this->buildConditionalSemantics(inst, dst, lower);
3765
3766 /* Create symbolic expression */
3767 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "SMLATB operation");
3768
3769 /* Get condition code node */
3770 auto cond = node1->getChildren()[0];
3771
3772 /* Spread taint */
3773 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
3774
3775 /* Update condition flag */
3776 if (cond->evaluate() == true) {
3777 inst.setConditionTaken(true);
3778 }
3779
3780 /* Update the symbolic control flow */
3781 this->controlFlow_s(inst, cond, dst);
3782 }
3783
3784
3785 void Arm32Semantics::smlatt_s(triton::arch::Instruction& inst) {
3786 auto& dst = inst.operands[0];
3787 auto& src1 = inst.operands[1];
3788 auto& src2 = inst.operands[2];
3789 auto& src3 = inst.operands[3];
3790 auto bvSize = dst.getBitSize();
3791
3792 /* Create symbolic operands */
3793 auto op1 = this->getArm32SourceOperandAst(inst, src1);
3794 auto op2 = this->getArm32SourceOperandAst(inst, src2);
3795 auto op3 = this->getArm32SourceOperandAst(inst, src3);
3796
3797 /* Create the semantics */
3798 auto smla = this->astCtxt->bvadd(
3799 this->astCtxt->bvmul(
3800 this->astCtxt->sx(2*bvSize + 16, this->astCtxt->extract(31, 16, op1)),
3801 this->astCtxt->sx(2*bvSize + 16, this->astCtxt->extract(31, 16, op2))
3802 ),
3803 this->astCtxt->sx(2*bvSize, op3)
3804 );
3805 auto lower = this->astCtxt->extract(bvSize-1, 0, smla);
3806 auto node1 = this->buildConditionalSemantics(inst, dst, lower);
3807
3808 /* Create symbolic expression */
3809 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "SMLATT operation");
3810
3811 /* Get condition code node */
3812 auto cond = node1->getChildren()[0];
3813
3814 /* Spread taint */
3815 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
3816
3817 /* Update condition flag */
3818 if (cond->evaluate() == true) {
3819 inst.setConditionTaken(true);
3820 }
3821
3822 /* Update the symbolic control flow */
3823 this->controlFlow_s(inst, cond, dst);
3824 }
3825
3826
3827 void Arm32Semantics::smull_s(triton::arch::Instruction& inst) {
3828 auto& dst1 = inst.operands[0];
3829 auto& dst2 = inst.operands[1];
3830 auto& src1 = inst.operands[2];
3831 auto& src2 = inst.operands[3];
3832
3833 /* Create symbolic operands */
3834 auto op1 = this->getArm32SourceOperandAst(inst, src1);
3835 auto op2 = this->getArm32SourceOperandAst(inst, src2);
3836
3837 /* Create the semantics */
3838 auto cond = this->getCodeConditionAst(inst);
3839 auto mul = this->astCtxt->bvmul(
3840 this->astCtxt->sx(triton::bitsize::qword, op1),
3841 this->astCtxt->sx(triton::bitsize::qword, op2)
3842 );
3843 auto lower = this->astCtxt->extract(triton::bitsize::dword-1, 0, mul);
3844 auto upper = this->astCtxt->extract(triton::bitsize::qword-1, triton::bitsize::dword, mul);
3845 auto node1 = this->astCtxt->ite(cond, lower, this->symbolicEngine->getOperandAst(inst, dst1));
3846 auto node2 = this->astCtxt->ite(cond, upper, this->symbolicEngine->getOperandAst(inst, dst2));
3847
3848 /* Create symbolic expression */
3849 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1, "SMULL(S) operation - Lower 32 bits of the result.");
3850 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "SMULL(S) operation - Upper 32 bits of the result.");
3851
3852 /* Spread taint */
3853 this->spreadTaint(inst, cond, expr1, dst1, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
3854 this->spreadTaint(inst, cond, expr2, dst2, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
3855
3856 /* Update symbolic flags */
3857 if (inst.isUpdateFlag() == true) {
3858 this->nfSmull_s(inst, cond, expr1, expr2, dst1, dst2);
3859 this->zfSmull_s(inst, cond, expr1, expr2, dst1, dst2);
3860 }
3861
3862 /* Update condition flag */
3863 if (cond->evaluate() == true) {
3864 inst.setConditionTaken(true);
3865
3866 /* Update execution mode accordingly. */
3867 /* NOTE: The invocations are done in the order the manual says
3868 * the instruction updates each register. Examples for this case
3869 * could be:
3870 * - smull pc, r1, r2, r3
3871 * - smull pc, pc, r2, r3
3872 */
3873 this->updateExecutionState(dst2, upper);
3874 this->updateExecutionState(dst1, lower);
3875 }
3876
3877 /* Update the symbolic control flow */
3878 this->controlFlow_s(inst, cond, dst1, dst2);
3879 }
3880
3881
3882 void Arm32Semantics::stm_s(triton::arch::Instruction& inst) {
3883 auto& base = inst.operands[0];
3885
3886 /* Create symbolic operands */
3887 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
3888
3889 /* Create the semantics */
3890 auto cond = this->getCodeConditionAst(inst);
3891
3892 for (unsigned int i = 1; i < inst.operands.size(); i++) {
3893 auto& src = inst.operands[i];
3894
3895 /* Compute memory address */
3896 auto addr = static_cast<triton::uint64>(baseNode->evaluate()) + size * (i-1);
3898
3899 /* Create symbolic operands */
3900 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3901 auto op3 = this->symbolicEngine->getOperandAst(inst, dst);
3902
3903 /* Create the semantics */
3904 auto node = this->astCtxt->ite(cond, op2, op3);
3905
3906 /* Create symbolic expression */
3907 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "STM operation - STORE access");
3908
3909 /* Spread taint */
3910 this->spreadTaint(inst, cond, expr1, dst, this->taintEngine->isTainted(base) | this->taintEngine->isTainted(src));
3911 }
3912
3913 if (inst.isWriteBack() == true) {
3914 /* Create the semantics of the base register */
3915 auto node = this->astCtxt->ite(
3916 cond,
3917 this->astCtxt->bvadd(
3918 baseNode,
3919 this->astCtxt->bv((inst.operands.size() - 1) * size, base.getBitSize())
3920 ),
3921 baseNode
3922 );
3923
3924 /* Create symbolic expression */
3925 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node, base, "STM operation - Base register computation");
3926
3927 /* Spread taint */
3928 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base));
3929 }
3930
3931 /* Update condition flag */
3932 if (cond->evaluate() == true) {
3933 inst.setConditionTaken(true);
3934 }
3935
3936 /* Update the symbolic control flow */
3937 this->controlFlow_s(inst);
3938 }
3939
3940
3941 void Arm32Semantics::stmib_s(triton::arch::Instruction& inst) {
3942 auto& base = inst.operands[0];
3944
3945 /* Create symbolic operands */
3946 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
3947
3948 /* Create the semantics */
3949 auto cond = this->getCodeConditionAst(inst);
3950
3951 for (unsigned int i = 1; i < inst.operands.size(); i++) {
3952 auto& src = inst.operands[i];
3953
3954 /* Compute memory address */
3955 auto addr = static_cast<triton::uint64>(baseNode->evaluate()) + size * i;
3957
3958 /* Create symbolic operands */
3959 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
3960 auto op3 = this->symbolicEngine->getOperandAst(inst, dst);
3961
3962 /* Create the semantics */
3963 auto node = this->astCtxt->ite(cond, op2, op3);
3964
3965 /* Create symbolic expression */
3966 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "STMIB operation - STORE access");
3967
3968 /* Spread taint */
3969 this->spreadTaint(inst, cond, expr1, dst, this->taintEngine->isTainted(base) | this->taintEngine->isTainted(src));
3970 }
3971
3972 if (inst.isWriteBack() == true) {
3973 /* Create the semantics of the base register */
3974 auto node1 = this->astCtxt->ite(
3975 cond,
3976 this->astCtxt->bvadd(
3977 baseNode,
3978 this->astCtxt->bv((inst.operands.size() - 1) * size, base.getBitSize())
3979 ),
3980 baseNode
3981 );
3982
3983 /* Create symbolic expression */
3984 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node1, base, "STMIB operation - Base register computation");
3985
3986 /* Spread taint */
3987 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base));
3988 }
3989
3990 /* Update condition flag */
3991 if (cond->evaluate() == true) {
3992 inst.setConditionTaken(true);
3993 }
3994
3995 /* Update the symbolic control flow */
3996 this->controlFlow_s(inst);
3997 }
3998
3999
4000 void Arm32Semantics::str_s(triton::arch::Instruction& inst) {
4001 auto& src = inst.operands[0];
4002 auto& dst = inst.operands[1];
4003
4004 /* Create symbolic operands */
4005 auto op = this->getArm32SourceOperandAst(inst, src);
4006
4007 /* Create the semantics */
4008 auto node1 = this->buildConditionalSemantics(inst, dst, op);
4009
4010 /* Create symbolic expression */
4011 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "STR operation - STORE access");
4012
4013 /* Get condition code node */
4014 auto cond = this->getCodeConditionAst(inst);
4015
4016 /* Spread taint */
4017 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
4018
4019 /* Optional behavior. Post-indexed computation of the base register. */
4020 /* STR <Rt>, [<Rn>], #+/-<imm> */
4021 if (inst.operands.size() == 3) {
4022 auto& imm = inst.operands[2].getImmediate();
4023 auto& base = dst.getMemory().getBaseRegister();
4024
4025 /* Create symbolic operands of the post computation */
4026 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
4027 auto immNode = this->symbolicEngine->getOperandAst(inst, imm);
4028
4029 /* Create the semantics of the base register */
4030 auto thenNode = this->astCtxt->bvadd(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode));
4031
4032 if (imm.isSubtracted() == true) {
4033 thenNode = this->astCtxt->bvsub(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode));
4034 }
4035
4036 auto node2 = this->astCtxt->ite(cond, thenNode, baseNode);
4037
4038 /* Create symbolic expression */
4039 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, base, "STR operation - Base register computation");
4040
4041 /* Spread taint */
4042 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base));
4043 }
4044
4045 /* Optional behavior. Pre-indexed computation of the base register. */
4046 /* STR <Rt>, [<Rn>, #+/-<imm>]! */
4047 else if (inst.operands.size() == 2 && inst.isWriteBack() == true) {
4048 auto& base = dst.getMemory().getBaseRegister();
4049
4050 /* Create symbolic operands of the post computation */
4051 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
4052
4053 /* Create the semantics of the base register */
4054 auto node3 = this->astCtxt->ite(cond, dst.getMemory().getLeaAst(), baseNode);
4055
4056 /* Create symbolic expression */
4057 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, base, "STR operation - Base register computation");
4058
4059 /* Spread taint */
4060 this->spreadTaint(inst, cond, expr3, base, this->taintEngine->isTainted(base));
4061 }
4062
4063 /* Update condition flag */
4064 if (cond->evaluate() == true) {
4065 inst.setConditionTaken(true);
4066 }
4067
4068 /* Update the symbolic control flow */
4069 this->controlFlow_s(inst);
4070 }
4071
4072
4073 void Arm32Semantics::strb_s(triton::arch::Instruction& inst) {
4074 auto& src = inst.operands[0];
4075 auto& dst = inst.operands[1];
4076
4077 /* Create symbolic operands */
4078 auto op = this->getArm32SourceOperandAst(inst, src);
4079
4080 /* Create the semantics */
4081 auto node = this->astCtxt->extract(7, 0, op);
4082 auto node1 = this->buildConditionalSemantics(inst, dst, node);
4083
4084 /* Create symbolic expression */
4085 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "STRB operation - STORE access");
4086
4087 /* Get condition code node */
4088 auto cond = this->getCodeConditionAst(inst);
4089
4090 /* Spread taint */
4091 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
4092
4093 /* Optional behavior. Post-indexed computation of the base register. */
4094 /* STRB <Rt>, [<Rn>], #+/-<imm> */
4095 if (inst.operands.size() == 3) {
4096 auto& imm = inst.operands[2].getImmediate();
4097 auto& base = dst.getMemory().getBaseRegister();
4098
4099 /* Create symbolic operands of the post computation */
4100 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
4101 auto immNode = this->symbolicEngine->getOperandAst(inst, imm);
4102
4103 /* Create the semantics of the base register */
4104 auto thenNode = this->astCtxt->bvadd(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode));
4105
4106 if (imm.isSubtracted() == true) {
4107 thenNode = this->astCtxt->bvsub(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode));
4108 }
4109
4110 auto node2 = this->astCtxt->ite(cond, thenNode, baseNode);
4111
4112 /* Create symbolic expression */
4113 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, base, "STRB operation - Base register computation");
4114
4115 /* Spread taint */
4116 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base));
4117 }
4118
4119 /* Optional behavior. Pre-indexed computation of the base register. */
4120 /* STRB <Rt>, [<Rn>, #+/-<imm>]! */
4121 else if (inst.operands.size() == 2 && inst.isWriteBack() == true) {
4122 auto& base = dst.getMemory().getBaseRegister();
4123
4124 /* Create symbolic operands of the post computation */
4125 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
4126
4127 /* Create the semantics of the base register */
4128 auto node3 = this->astCtxt->ite(cond, dst.getMemory().getLeaAst(), baseNode);
4129
4130 /* Create symbolic expression */
4131 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, base, "STRB operation - Base register computation");
4132
4133 /* Spread taint */
4134 this->spreadTaint(inst, cond, expr3, base, this->taintEngine->isTainted(base));
4135 }
4136
4137 /* Update condition flag */
4138 if (cond->evaluate() == true) {
4139 inst.setConditionTaken(true);
4140 }
4141
4142 /* Update the symbolic control flow */
4143 this->controlFlow_s(inst);
4144 }
4145
4146
4147 void Arm32Semantics::strd_s(triton::arch::Instruction& inst) {
4148 auto& base = inst.operands[2];
4150
4151 /* Create the semantics */
4152 auto cond = this->getCodeConditionAst(inst);
4153
4154 for (unsigned int i = 0; i < 2; i++) {
4155 auto& src = inst.operands[i];
4156
4157 /* Compute memory address */
4158 auto addr = base.getMemory().getAddress() + size * i;
4160
4161 /* Create symbolic operands */
4162 auto op2 = this->symbolicEngine->getOperandAst(inst, src);
4163 auto op3 = this->symbolicEngine->getOperandAst(inst, dst);
4164
4165 /* Create the semantics */
4166 auto node = this->astCtxt->ite(cond, op2, op3);
4167
4168 /* Create symbolic expression */
4169 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node, dst, "STRD operation - STORE access");
4170
4171 /* Spread taint */
4172 this->spreadTaint(inst, cond, expr1, dst, this->taintEngine->isTainted(base) | this->taintEngine->isTainted(src));
4173 }
4174
4175 /* Optional behavior. Post-indexed computation of the base register. */
4176 /* NOTE: There are two possible cases here:
4177 * - STRD <Rt>, <Rt2>, [<Rn>], #+/-<imm>
4178 * - STRD <Rt>, <Rt2>, [<Rn>], +/-<Rm>
4179 */
4180 if (inst.operands.size() == 4) {
4181 if (inst.operands[3].getType() == OP_IMM) {
4182 auto& imm = inst.operands[3].getImmediate();
4183 auto& base = inst.operands[2].getMemory().getBaseRegister();
4184
4185 /* Create symbolic operands of the post computation */
4186 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
4187 auto immNode = this->symbolicEngine->getOperandAst(inst, imm);
4188
4189 /* Create the semantics of the base register */
4190 auto thenNode = this->astCtxt->bvadd(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode));
4191
4192 if (imm.isSubtracted() == true) {
4193 thenNode = this->astCtxt->bvsub(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode));
4194 }
4195
4196 auto node2 = this->astCtxt->ite(cond, thenNode, baseNode);
4197
4198 /* Create symbolic expression */
4199 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, base, "STRD operation - Base register computation");
4200
4201 /* Spread taint */
4202 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base));
4203 } else {
4204 auto& reg = inst.operands[3].getRegister();
4205 auto& base = inst.operands[2].getMemory().getBaseRegister();
4206
4207 /* Create symbolic operands of the post computation */
4208 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
4209 auto regNode = this->symbolicEngine->getOperandAst(inst, reg);
4210
4211 /* Create the semantics of the base register */
4212 auto thenNode = this->astCtxt->bvadd(baseNode, regNode);
4213
4214 if (reg.isSubtracted() == true) {
4215 thenNode = this->astCtxt->bvsub(baseNode, regNode);
4216 }
4217
4218 auto node2 = this->astCtxt->ite(cond, thenNode, baseNode);
4219
4220 /* Create symbolic expression */
4221 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, base, "STRD operation - Base register computation");
4222
4223 /* Spread taint */
4224 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base) | this->taintEngine->isTainted(reg));
4225 }
4226 }
4227
4228 /* Optional behavior. Pre-indexed computation of the base register. */
4229 /* STR <Rt>, <Rt2>, [<Rn>, #+/-<imm>]! */
4230 else if (inst.operands.size() == 3 && inst.isWriteBack() == true) {
4231 auto& base = inst.operands[2].getMemory().getBaseRegister();
4232
4233 /* Create symbolic operands of the post computation */
4234 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
4235
4236 /* Create the semantics of the base register */
4237 auto node3 = this->astCtxt->ite(cond, inst.operands[2].getMemory().getLeaAst(), baseNode);
4238
4239 /* Create symbolic expression */
4240 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, base, "STRD operation - Base register computation");
4241
4242 /* Spread taint */
4243 this->spreadTaint(inst, cond, expr3, base, this->taintEngine->isTainted(base));
4244 }
4245
4246 /* Update condition flag */
4247 if (cond->evaluate() == true) {
4248 inst.setConditionTaken(true);
4249 }
4250
4251 /* Update the symbolic control flow */
4252 this->controlFlow_s(inst);
4253 }
4254
4255
4256 void Arm32Semantics::strex_s(triton::arch::Instruction& inst) {
4257 /* NOTE This is a simplified version of the semantics of this
4258 * instruction. We only check for a global exclusive memory
4259 * access flag.
4260 */
4261 auto& dst1 = inst.operands[0];
4262 auto& src = inst.operands[1];
4263 auto& dst2 = inst.operands[2];
4264
4265 /* Create symbolic operands */
4266 auto op1 = this->getArm32SourceOperandAst(inst, src);
4267 auto op2 = this->symbolicEngine->getOperandAst(inst, dst2);
4268
4269 /* Check whether there is exclusive access */
4270 auto status = this->astCtxt->bv(this->architecture->isMemoryExclusive(dst2.getConstMemory()) ? 0 : 1, dst1.getBitSize());
4271
4272 /* Create the semantics */
4273 auto cond = this->getCodeConditionAst(inst);
4274 auto node1 = this->astCtxt->ite(cond, status, this->symbolicEngine->getOperandAst(inst, dst1));
4275 auto node2 = this->architecture->isMemoryExclusive(dst2.getConstMemory()) == true ?
4276 this->astCtxt->ite(cond, op1, op2) :
4277 this->astCtxt->ite(cond, op2, op2);
4278
4279 /* Create symbolic expression */
4280 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1, "STREX operation - write status");
4281 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "STREX operation - STORE access");
4282
4283 /* Spread taint */
4284 this->spreadTaint(inst, cond, expr2, dst2, this->taintEngine->isTainted(src));
4285
4286 /* Update exclusive memory access tag */
4287 this->architecture->setMemoryExclusiveTag(dst2.getConstMemory(), false);
4288
4289 /* Update condition flag */
4290 if (cond->evaluate() == true) {
4291 inst.setConditionTaken(true);
4292 }
4293
4294 /* Update the symbolic control flow */
4295 this->controlFlow_s(inst);
4296 }
4297
4298
4299 void Arm32Semantics::strh_s(triton::arch::Instruction& inst) {
4300 auto& src = inst.operands[0];
4301 auto& dst = inst.operands[1];
4302
4303 /* Create symbolic operands */
4304 auto op = this->getArm32SourceOperandAst(inst, src);
4305
4306 /* Create the semantics */
4307 auto node1 = this->astCtxt->extract(15, 0, op);
4308 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
4309
4310 /* Create symbolic expression */
4311 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "STRH operation - STORE access");
4312
4313 /* Get condition code node */
4314 auto cond = this->getCodeConditionAst(inst);
4315
4316 /* Spread taint */
4317 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
4318
4319 /* Optional behavior. Post-indexed computation of the base register. */
4320 /* STRH <Rt>, [<Rn>], #+/-<imm>; STRH <Rt>, [<Rn>], +/-<Rm>*/
4321 if (inst.operands.size() == 3) {
4322 if (inst.operands[2].getType() == OP_IMM) {
4323 auto& imm = inst.operands[2].getImmediate();
4324 auto& base = dst.getMemory().getBaseRegister();
4325
4326 /* Create symbolic operands of the post computation */
4327 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
4328 auto immNode = this->symbolicEngine->getOperandAst(inst, imm);
4329
4330 /* Create the semantics of the base register */
4331 auto thenNode = this->astCtxt->bvadd(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode));
4332
4333 if (imm.isSubtracted() == true) {
4334 thenNode = this->astCtxt->bvsub(baseNode, this->astCtxt->sx(base.getBitSize() - imm.getBitSize(), immNode));
4335 }
4336
4337 auto node2 = this->astCtxt->ite(cond, thenNode, baseNode);
4338
4339 /* Create symbolic expression */
4340 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, base, "STRH operation - Base register computation");
4341
4342 /* Spread taint */
4343 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base));
4344 } else {
4345 auto& reg = inst.operands[2].getRegister();
4346 auto& base = dst.getMemory().getBaseRegister();
4347
4348 /* Create symbolic operands of the post computation */
4349 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
4350 auto regNode = this->symbolicEngine->getOperandAst(inst, reg);
4351
4352 /* Create the semantics of the base register */
4353 auto thenNode = this->astCtxt->bvadd(baseNode, regNode);
4354
4355 if (reg.isSubtracted() == true) {
4356 thenNode = this->astCtxt->bvsub(baseNode, regNode);
4357 }
4358
4359 auto node2 = this->astCtxt->ite(cond, thenNode, baseNode);
4360
4361 /* Create symbolic expression */
4362 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, base, "STRH operation - Base register computation");
4363
4364 /* Spread taint */
4365 this->spreadTaint(inst, cond, expr2, base, this->taintEngine->isTainted(base) | this->taintEngine->isTainted(reg));
4366 }
4367 }
4368
4369 /* Optional behavior. Pre-indexed computation of the base register. */
4370 /* STRH <Rt>, [<Rn>, #+/-<imm>]! */
4371 else if (inst.operands.size() == 2 && inst.isWriteBack() == true) {
4372 auto& base = dst.getMemory().getBaseRegister();
4373
4374 /* Create symbolic operands of the post computation */
4375 auto baseNode = this->symbolicEngine->getOperandAst(inst, base);
4376
4377 /* Create the semantics of the base register */
4378 auto node3 = this->astCtxt->ite(cond, dst.getMemory().getLeaAst(), baseNode);
4379
4380 /* Create symbolic expression */
4381 auto expr3 = this->symbolicEngine->createSymbolicExpression(inst, node3, base, "STRH operation - Base register computation");
4382
4383 /* Spread taint */
4384 this->spreadTaint(inst, cond, expr3, base, this->taintEngine->isTainted(base));
4385 }
4386
4387 /* Update condition flag */
4388 if (cond->evaluate() == true) {
4389 inst.setConditionTaken(true);
4390 }
4391
4392 /* Update the symbolic control flow */
4393 this->controlFlow_s(inst, cond, dst);
4394 }
4395
4396
4397 void Arm32Semantics::sub_s(triton::arch::Instruction& inst) {
4398 auto& dst = inst.operands[0];
4399 auto& src1 = inst.operands[1];
4400 auto& src2 = inst.operands[2];
4401
4402 /* Process modified immediate constants (expand immediate) */
4403 /* For more information, look for "Modified immediate constants in ARM
4404 * instructions" in the reference manual. For example:
4405 * "sub r0, r0, #16, #20".
4406 */
4407 if (inst.operands.size() == 4) {
4408 auto src3 = inst.operands[3];
4409
4410 if (src2.getType() == OP_IMM && src3.getType() == OP_IMM) {
4411 auto size = src2.getSize();
4412 auto value = static_cast<triton::uint32>(src2.getImmediate().getValue());
4413 auto shift = static_cast<triton::uint32>(src3.getImmediate().getValue());
4414
4415 /* Replace src2 with the expanded immediate */
4416 src2 = triton::arch::OperandWrapper(triton::arch::Immediate(this->ror(value, shift), size));
4417 } else {
4418 throw triton::exceptions::Semantics("Arm32Semantics::sub_s(): Invalid operand type.");
4419 }
4420 }
4421
4422 /* Create symbolic operands */
4423 auto op1 = this->getArm32SourceOperandAst(inst, src1);
4424 auto op2 = this->getArm32SourceOperandAst(inst, src2);
4425
4426 /* Create the semantics */
4427 auto node1 = this->astCtxt->bvsub(op1, op2);
4428 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
4429
4430 /* Create symbolic expression */
4431 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "SUB(S) operation");
4432
4433 /* Get condition code node */
4434 auto cond = this->getCodeConditionAst(inst);
4435
4436 /* Spread taint */
4437 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
4438
4439 /* Update symbolic flags */
4440 if (inst.isUpdateFlag() == true) {
4441 /* NOTE: The following if statement was added to properly handle
4442 * the case when PC is the destination register when the S suffix is
4443 * present (e.g.: 'subseq pc, r4'). The manual is not clear in this
4444 * case. We arrived to this solution after testing and comparing the
4445 * behavior against UC.
4446 */
4447 if (dst.getRegister().getId() != ID_REG_ARM32_PC) {
4448 this->cfSub_s(inst, cond, expr, dst, op1, op2);
4449 }
4450 this->nf_s(inst, cond, expr, dst);
4451 this->vfSub_s(inst, cond, expr, dst, op1, op2);
4452 this->zf_s(inst, cond, expr, dst);
4453 }
4454
4455 /* Update condition flag */
4456 if (cond->evaluate() == true) {
4457 inst.setConditionTaken(true);
4458
4459 /* Update execution mode accordingly. */
4460 this->updateExecutionState(dst, node1);
4461 }
4462
4463 /* Update the symbolic control flow */
4464 this->controlFlow_s(inst, cond, dst);
4465 }
4466
4467
4468 void Arm32Semantics::sxtb_s(triton::arch::Instruction& inst) {
4469 auto& dst = inst.operands[0];
4470 auto& src = inst.operands[1];
4471
4472 /* Create symbolic operands */
4473 auto op = this->symbolicEngine->getOperandAst(inst, src);
4474
4475 /* Create the semantics */
4476 auto node1 = this->astCtxt->sx(dst.getBitSize() - 8, this->astCtxt->extract(7, 0, op));
4477 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
4478
4479 /* Create symbolic expression */
4480 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "SXTB operation");
4481
4482 /* Get condition code node */
4483 auto cond = this->getCodeConditionAst(inst);
4484
4485 /* Spread taint */
4486 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
4487
4488 /* Update the symbolic control flow */
4489 this->controlFlow_s(inst);
4490 }
4491
4492
4493 void Arm32Semantics::sxth_s(triton::arch::Instruction& inst) {
4494 auto& dst = inst.operands[0];
4495 auto& src = inst.operands[1];
4496
4497 /* Create symbolic operands */
4498 auto op = this->symbolicEngine->getOperandAst(inst, src);
4499
4500 /* Create the semantics */
4501 auto node1 = this->astCtxt->sx(dst.getBitSize() - 16, this->astCtxt->extract(15, 0, op));
4502 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
4503
4504 /* Create symbolic expression */
4505 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "SXTH operation");
4506
4507 /* Get condition code node */
4508 auto cond = this->getCodeConditionAst(inst);
4509
4510 /* Spread taint */
4511 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
4512
4513 /* Update the symbolic control flow */
4514 this->controlFlow_s(inst);
4515 }
4516
4517
4518 void Arm32Semantics::tst_s(triton::arch::Instruction& inst) {
4519 auto& src1 = inst.operands[0];
4520 auto& src2 = inst.operands[1];
4521
4522 /* Create symbolic operands */
4523 auto op1 = this->getArm32SourceOperandAst(inst, src1);
4524 auto op2 = this->getArm32SourceOperandAst(inst, src2);
4525
4526 /* Create the semantics */
4527 auto cond = this->getCodeConditionAst(inst);
4528 auto node1 = this->astCtxt->bvand(op1, op2);
4529
4530 /* Create symbolic expression */
4531 auto expr = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "TST operation");
4532
4533 /* Spread taint */
4534 if (cond->evaluate() == true) {
4535 expr->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2);
4536 }
4537
4538 /* Update symbolic flags */
4539 this->cfBitwise_s(inst, cond, expr, src2);
4540 this->nf_s(inst, cond, expr, src1);
4541 this->zf_s(inst, cond, expr, src1);
4542
4543 /* Update condition flag */
4544 if (cond->evaluate() == true) {
4545 inst.setConditionTaken(true);
4546 }
4547
4548 /* Update the symbolic control flow */
4549 this->controlFlow_s(inst);
4550 }
4551
4552
4553 void Arm32Semantics::tbb_s(triton::arch::Instruction& inst) {
4554 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_PC));
4555 auto& src = inst.operands[0];
4556 auto bvSize = dst.getBitSize();
4557
4558 /* Create symbolic operands */
4559 auto pcNode = this->astCtxt->bv(inst.getNextAddress(), dst.getBitSize());
4560 auto opNode = this->getArm32SourceOperandAst(inst, src);
4561
4562 /* Create the semantics */
4563 auto node1 = this->astCtxt->bvadd(
4564 pcNode,
4565 this->astCtxt->bvmul(
4566 this->astCtxt->bv(2, bvSize),
4567 this->astCtxt->zx(bvSize - src.getMemory().getBitSize(), opNode)
4568 )
4569 );
4570
4571 /* Create symbolic expression */
4572 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "TBB operation - Program Counter");
4573
4574 /* Spread taint */
4575 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4576
4577 /* Set condition flag */
4578 inst.setConditionTaken(true);
4579
4580 /* Create the path constraint */
4581 this->symbolicEngine->pushPathConstraint(inst, expr);
4582 }
4583
4584
4585 void Arm32Semantics::tbh_s(triton::arch::Instruction& inst) {
4586 auto dst = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_PC));
4587 auto& src = inst.operands[0];
4588 auto bvSize = dst.getBitSize();
4589
4590 /* Create symbolic operands */
4591 auto pcNode = this->astCtxt->bv(inst.getNextAddress(), dst.getBitSize());
4592 auto opNode = this->getArm32SourceOperandAst(inst, src);
4593
4594 /* Create the semantics */
4595 auto node1 = this->astCtxt->bvadd(
4596 pcNode,
4597 this->astCtxt->bvmul(
4598 this->astCtxt->bv(2, bvSize),
4599 this->astCtxt->zx(bvSize - src.getMemory().getBitSize(), opNode)
4600 )
4601 );
4602
4603 /* Create symbolic expression */
4604 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node1, dst, "TBH operation - Program Counter");
4605
4606 /* Spread taint */
4607 expr->isTainted = this->taintEngine->taintAssignment(dst, src);
4608
4609 /* Set condition flag */
4610 inst.setConditionTaken(true);
4611
4612 /* Create the path constraint */
4613 this->symbolicEngine->pushPathConstraint(inst, expr);
4614 }
4615
4616
4617 void Arm32Semantics::teq_s(triton::arch::Instruction& inst) {
4618 auto& src1 = inst.operands[0];
4619 auto& src2 = inst.operands[1];
4620
4621 /* Create symbolic operands */
4622 auto op1 = this->getArm32SourceOperandAst(inst, src1);
4623 auto op2 = this->getArm32SourceOperandAst(inst, src2);
4624
4625 /* Create the semantics */
4626 auto cond = this->getCodeConditionAst(inst);
4627 auto node1 = this->astCtxt->bvxor(op1, op2);
4628
4629 /* Create symbolic expression */
4630 auto expr = this->symbolicEngine->createSymbolicVolatileExpression(inst, node1, "TEQ operation");
4631
4632 /* Spread taint */
4633 if (cond->evaluate() == true) {
4634 expr->isTainted = this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2);
4635 }
4636
4637 /* Update symbolic flags */
4638 this->cfBitwise_s(inst, cond, expr, src2);
4639 this->nf_s(inst, cond, expr, src1);
4640 this->zf_s(inst, cond, expr, src1);
4641
4642 /* Update condition flag */
4643 if (cond->evaluate() == true) {
4644 inst.setConditionTaken(true);
4645 }
4646
4647 /* Update the symbolic control flow */
4648 this->controlFlow_s(inst);
4649 }
4650
4651
4652 void Arm32Semantics::ubfx_s(triton::arch::Instruction& inst) {
4653 auto& dst = inst.operands[0];
4654 auto& src1 = inst.operands[1];
4655 auto& src2 = inst.operands[2];
4656 auto& src3 = inst.operands[3];
4657 auto lsb = static_cast<uint32>(src2.getImmediate().getValue());
4658 auto width = static_cast<uint32>(src3.getImmediate().getValue());
4659
4660 if (lsb + width > dst.getBitSize())
4661 throw triton::exceptions::Semantics("Arm32Semantics::ubfx_s(): Invalid lsb and width.");
4662
4663 /* Create symbolic operands */
4664 auto op = this->symbolicEngine->getOperandAst(inst, src1);
4665
4666 /* Create the semantics */
4667 auto node1 = this->astCtxt->zx(dst.getBitSize() - width, this->astCtxt->extract(lsb+width-1, lsb, op));
4668 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
4669
4670 /* Create symbolic expression */
4671 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "UBFX operation");
4672
4673 /* Get condition code node */
4674 auto cond = this->getCodeConditionAst(inst);
4675
4676 /* Spread taint */
4677 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1));
4678
4679 /* Update the symbolic control flow */
4680 this->controlFlow_s(inst);
4681 }
4682
4683
4684 void Arm32Semantics::udiv_s(triton::arch::Instruction& inst) {
4685 auto& dst = inst.operands[0];
4686 auto& src1 = inst.operands[1];
4687 auto& src2 = inst.operands[2];
4688
4689 /* Create symbolic operands */
4690 auto op1 = this->symbolicEngine->getOperandAst(inst, src1);
4691 auto op2 = this->symbolicEngine->getOperandAst(inst, src2);
4692
4693 /* Create the semantics */
4694 auto node1 = this->astCtxt->ite(
4695 this->astCtxt->equal(op2, this->astCtxt->bv(0, op2->getBitvectorSize())),
4696 this->astCtxt->bv(0, dst.getBitSize()),
4697 this->astCtxt->bvudiv(op1, op2)
4698 );
4699 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
4700
4701 /* Create symbolic expression */
4702 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "UDIV operation");
4703
4704 /* Get condition code node */
4705 auto cond = this->getCodeConditionAst(inst);
4706
4707 /* Spread taint */
4708 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
4709
4710 /* Update the symbolic control flow */
4711 this->controlFlow_s(inst);
4712 }
4713
4714
4715 void Arm32Semantics::umull_s(triton::arch::Instruction& inst) {
4716 auto& dst1 = inst.operands[0];
4717 auto& dst2 = inst.operands[1];
4718 auto& src1 = inst.operands[2];
4719 auto& src2 = inst.operands[3];
4720
4721 /* Create symbolic operands */
4722 auto op1 = this->getArm32SourceOperandAst(inst, src1);
4723 auto op2 = this->getArm32SourceOperandAst(inst, src2);
4724
4725 /* Create the semantics */
4726 auto cond = this->getCodeConditionAst(inst);
4727 auto mul = this->astCtxt->bvmul(
4728 this->astCtxt->zx(triton::bitsize::qword, op1),
4729 this->astCtxt->zx(triton::bitsize::qword, op2)
4730 );
4731 auto lower = this->astCtxt->extract(triton::bitsize::dword-1, 0, mul);
4732 auto upper = this->astCtxt->extract(triton::bitsize::qword-1, triton::bitsize::dword, mul);
4733 auto node1 = this->astCtxt->ite(cond, lower, this->symbolicEngine->getOperandAst(inst, dst1));
4734 auto node2 = this->astCtxt->ite(cond, upper, this->symbolicEngine->getOperandAst(inst, dst2));
4735
4736 /* Create symbolic expression */
4737 auto expr1 = this->symbolicEngine->createSymbolicExpression(inst, node1, dst1, "UMULL(S) operation - Lower 32 bits of the result.");
4738 auto expr2 = this->symbolicEngine->createSymbolicExpression(inst, node2, dst2, "UMULL(S) operation - Upper 32 bits of the result.");
4739
4740 /* Spread taint */
4741 this->spreadTaint(inst, cond, expr1, dst1, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
4742 this->spreadTaint(inst, cond, expr2, dst2, this->taintEngine->isTainted(src1) | this->taintEngine->isTainted(src2));
4743
4744 /* Update symbolic flags */
4745 if (inst.isUpdateFlag() == true) {
4746 this->nfSmull_s(inst, cond, expr1, expr2, dst1, dst2);
4747 this->zfSmull_s(inst, cond, expr1, expr2, dst1, dst2);
4748 }
4749
4750 /* Update condition flag */
4751 if (cond->evaluate() == true) {
4752 inst.setConditionTaken(true);
4753
4754 /* Update execution mode accordingly. */
4755 /* NOTE: The invocations are done in the order the manual says
4756 * the instruction updates each register. Examples for this case
4757 * could be:
4758 * - smull pc, r1, r2, r3
4759 * - smull pc, pc, r2, r3
4760 */
4761 this->updateExecutionState(dst2, upper);
4762 this->updateExecutionState(dst1, lower);
4763 }
4764
4765 /* Update the symbolic control flow */
4766 this->controlFlow_s(inst, cond, dst1, dst2);
4767 }
4768
4769
4770 void Arm32Semantics::uxtb_s(triton::arch::Instruction& inst) {
4771 auto& dst = inst.operands[0];
4772 auto& src = inst.operands[1];
4773
4774 /* Create symbolic operands */
4775 auto op = this->symbolicEngine->getOperandAst(inst, src);
4776
4777 /* Create the semantics */
4778 auto node1 = this->astCtxt->zx(dst.getBitSize() - 8, this->astCtxt->extract(7, 0, op));
4779 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
4780
4781 /* Create symbolic expression */
4782 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "UXTB operation");
4783
4784 /* Get condition code node */
4785 auto cond = this->getCodeConditionAst(inst);
4786
4787 /* Spread taint */
4788 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
4789
4790 /* Update the symbolic control flow */
4791 this->controlFlow_s(inst);
4792 }
4793
4794
4795 void Arm32Semantics::uxth_s(triton::arch::Instruction& inst) {
4796 auto& dst = inst.operands[0];
4797 auto& src = inst.operands[1];
4798
4799 /* Create symbolic operands */
4800 auto op = this->symbolicEngine->getOperandAst(inst, src);
4801
4802 /* Create the semantics */
4803 auto node1 = this->astCtxt->zx(dst.getBitSize() - 16, this->astCtxt->extract(15, 0, op));
4804 auto node2 = this->buildConditionalSemantics(inst, dst, node1);
4805
4806 /* Create symbolic expression */
4807 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node2, dst, "UXTH operation");
4808
4809 /* Get condition code node */
4810 auto cond = this->getCodeConditionAst(inst);
4811
4812 /* Spread taint */
4813 this->spreadTaint(inst, cond, expr, dst, this->taintEngine->isTainted(src));
4814
4815 /* Update the symbolic control flow */
4816 this->controlFlow_s(inst);
4817 }
4818
4819
4820 void Arm32Semantics::cfBitwise_s(triton::arch::Instruction& inst,
4824
4825 /* NOTE: This function builds the semantics for updating the carry
4826 * flag for all bitwise instructions: AND, BIC, EOR, MVN, ORN, ORR,
4827 * and TST. The way the carry flag is updated depends on the type of
4828 * operand (and in the case of a register operand, it even depends
4829 * whether it is shifted or not). For more information refer to the
4830 * manual to any of the aforementioned instructions.
4831 */
4832
4833 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_C));
4834
4835 /* Create symbolic operands */
4836 auto op = this->getArm32SourceOperandAst(inst, src);
4837
4838 /* Create the semantics */
4839 triton::ast::SharedAbstractNode node = nullptr;
4841 triton::ast::SharedAbstractNode shiftAmount = nullptr;
4842
4843 switch (src.getType()) {
4844 case triton::arch::OP_IMM: {
4845 /* For instance, this applies to: AND{S}{<c>}{<q>} {<Rd>,} <Rn>, #<const> */
4846
4847 /* From the instruction decoding:
4848 * - (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
4849 *
4850 * From ARMExpandImm_C():
4851 * - unrotated_value = ZeroExtend(imm12<7:0>, 32);
4852 * - (imm32, carry_out) = Shift_C(unrotated_value, SRType_ROR, 2*UInt(imm12<11:8>), carry_in);
4853 */
4854
4855 node = this->astCtxt->zx(triton::bitsize::dword-8, this->astCtxt->extract(7, 0, op));
4857 shiftAmount = this->astCtxt->bv(
4858 2 * (src.getImmediate().getValue() & 0x00000f00),
4859 node->getBitvectorSize()
4860 );
4861 break;
4862 }
4863
4864 case triton::arch::OP_REG: {
4865 /* For instance, this applies to: AND{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm>, <type> <Rs> */
4867 /* From the instruction operation:
4868 * - shift_n = UInt(R[s]<7:0>);
4869 * - (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
4870 */
4871
4872 auto shift = static_cast<const triton::arch::arm::ArmOperandProperties>(src.getRegister());
4873
4874 node = this->getArm32SourceBaseOperandAst(inst, src);
4875 shiftAmount = this->getShiftCAmountAst(shift);
4876 shiftType = this->getShiftCBaseType(shift);
4877 }
4878
4879 /* For instance, this applies to: AND{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {, <shift>} */
4880 else {
4881 /* From the instruction decoding:
4882 * - (shift_t, shift_n) = (SRType_LSL, 0);
4883 * - (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
4884 */
4885
4886 node = op;
4888 shiftAmount = this->astCtxt->bv(0, op->getBitvectorSize());
4889 }
4890 break;
4891 }
4892
4893 default:
4894 throw triton::exceptions::Semantics("Arm32Semantics::cfBitwise_s(): Invalid operand type.");
4895 }
4896
4897 /* Create the semantics */
4898 auto node1 = this->getShiftCAst(node, shiftType, shiftAmount);
4899 auto node2 = this->symbolicEngine->getOperandAst(cf);
4900 auto node3 = this->astCtxt->ite(cond, node1, node2);
4901
4902 /* Create symbolic expression */
4903 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node3, cf, "Carry flag");
4904
4905 /* Spread the taint from the parent to the child */
4906 this->spreadTaint(inst, cond, expr, cf, parent->isTainted);
4907 }
4908
4909
4910 void Arm32Semantics::cfShift_s(triton::arch::Instruction& inst,
4915 const triton::arch::arm::shift_e type) {
4916
4917 /* NOTE: This function builds the semantics for updating the carry
4918 * flag for all shift instructions: ASR, LSL, LSR, ROR, and RRX. The
4919 * way the carry flag is updated depends on the type of operand (and
4920 * in the case of a register operand, it even depends whether it is
4921 * shifted or not). For more information refer to the manual to any
4922 * of the aforementioned instructions.
4923 */
4924
4925 /* IMPORTANT: We assume that op1 is a register without its shift. */
4926
4927 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_C));
4928
4929 /* Create the semantics */
4930 triton::ast::SharedAbstractNode node = nullptr;
4931 triton::arch::arm::shift_e shiftType = type;
4932 triton::ast::SharedAbstractNode shiftAmount = nullptr;
4933
4934 switch (src.getType()) {
4935 case triton::arch::OP_IMM: {
4936 /* For instance, this applies to: ASR{S}{<c>}{<q>} {<Rd>,} <Rm>, #<imm> */
4937
4938 /* IMPORTANT: This case ONLY seems to apply to the Thumb version
4939 * of the shift instructions. Empirically determined, the
4940 * reference manual doesn't seem to provide information about
4941 * this.
4942 */
4943 shiftAmount = this->astCtxt->bv(src.getImmediate().getValue(), op1->getBitvectorSize());
4944 break;
4945 }
4946
4947 case triton::arch::OP_REG: {
4948 /* From the instruction operation:
4949 * - shift_n = UInt(R[m]<7:0>);
4950 * - (result, carry) = Shift_C(R[n], SRType_XXX, shift_n, APSR.C);
4951 *
4952 * where 'SRType_XXX' varies according to the instruction (for instance,
4953 * SRType_ASR in case it is an ASR instruction).
4954 */
4955
4956 /* For instance, this applies to: ASR{S}{<c>}{<q>} {<Rd>,} <Rm>, #<imm> */
4958 auto shift = static_cast<const triton::arch::arm::ArmOperandProperties>(src.getRegister());
4959
4960 shiftAmount = this->getShiftCAmountAst(shift);
4961 shiftType = this->getShiftCBaseType(shift);
4962 }
4963
4964 /* For instance, this applies to: ASR{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm> */
4965 else {
4966 /* Create symbolic operands */
4967 auto op2 = this->getArm32SourceOperandAst(inst, src);
4968
4969 /* Create the semantics */
4970 shiftAmount = this->astCtxt->zx(triton::bitsize::dword-8, this->astCtxt->extract(7, 0, op2));
4971
4972 /* Special case for instruction RRX. */
4973 if (type == triton::arch::arm::ID_SHIFT_RRX) {
4974 shiftAmount = this->astCtxt->bv(1, op1->getBitvectorSize());
4975 }
4976 }
4977 break;
4978 }
4979
4980 default:
4981 throw triton::exceptions::Semantics("Arm32Semantics::cfShift_s(): Invalid operand type.");
4982 }
4983
4984 /* Create the semantics */
4985 auto node1 = this->getShiftCAst(op1, shiftType, shiftAmount);
4986 auto node2 = this->symbolicEngine->getOperandAst(cf);
4987 auto node3 = this->astCtxt->ite(cond, node1, node2);
4988
4989 /* Create symbolic expression */
4990 auto expr = this->symbolicEngine->createSymbolicExpression(inst, node3, cf, "Carry flag");
4991
4992 /* Spread the taint from the parent to the child */
4993 this->spreadTaint(inst, cond, expr, cf, parent->isTainted);
4994 }
4995
4996
4997 void Arm32Semantics::cfAsr_s(triton::arch::Instruction& inst,
5002
5003 this->cfShift_s(inst, cond, parent, op1, src, triton::arch::arm::ID_SHIFT_ASR);
5004 }
5005
5006
5007 void Arm32Semantics::cfLsl_s(triton::arch::Instruction& inst,
5012
5013 this->cfShift_s(inst, cond, parent, op1, src, triton::arch::arm::ID_SHIFT_LSL);
5014 }
5015
5016
5017 void Arm32Semantics::cfLsr_s(triton::arch::Instruction& inst,
5022
5023 this->cfShift_s(inst, cond, parent, op1, src, triton::arch::arm::ID_SHIFT_LSR);
5024 }
5025
5026
5027 void Arm32Semantics::cfRor_s(triton::arch::Instruction& inst,
5032
5033 this->cfShift_s(inst, cond, parent, op1, src, triton::arch::arm::ID_SHIFT_ROR);
5034 }
5035
5036
5037 void Arm32Semantics::cfRrx_s(triton::arch::Instruction& inst,
5042
5043 this->cfShift_s(inst, cond, parent, op1, src, triton::arch::arm::ID_SHIFT_RRX);
5044 }
5045
5046
5047 triton::ast::SharedAbstractNode Arm32Semantics::getShiftCAst(const triton::ast::SharedAbstractNode& node,
5048 const triton::arch::arm::shift_e type,
5049 const triton::ast::SharedAbstractNode& shiftAmount) {
5050
5051 /* NOTE This function implements the Shift_C function from the
5052 * reference manual:
5053 *
5054 * (bits(N), bit) Shift_C(bits(N) value, SRType type, integer amount, bit carry_in)
5055 *
5056 * However, it only returns the carry out. Check the reference manual
5057 * for more information.
5058 */
5059
5060 /* NOTE This function slightly overlaps with SymbolicEngine::getShiftAst. */
5061
5062 auto cf = triton::arch::OperandWrapper(this->architecture->getRegister(ID_REG_ARM32_C));
5063
5064 /* Set carry out node to the current value of the carry (carry in). */
5065 triton::ast::SharedAbstractNode carryOutNode = this->symbolicEngine->getOperandAst(cf);
5066
5067 if (shiftAmount->evaluate() == 0)
5068 return carryOutNode;
5069
5070 switch (type) {
5072 carryOutNode = this->astCtxt->extract(
5073 0,
5074 0,
5075 this->astCtxt->bvashr(
5076 node,
5077 this->astCtxt->bvsub(
5078 shiftAmount,
5079 this->astCtxt->bv(1, shiftAmount->getBitvectorSize())
5080 )
5081 )
5082 );
5083 break;
5084 }
5085
5087 carryOutNode = this->astCtxt->extract(
5090 this->astCtxt->bvshl(
5091 this->astCtxt->zx(node->getBitvectorSize()+1, node),
5092 this->astCtxt->zx(node->getBitvectorSize()+1, shiftAmount)
5093 )
5094 );
5095 break;
5096 }
5097
5099 carryOutNode = this->astCtxt->extract(
5100 0,
5101 0,
5102 this->astCtxt->bvlshr(
5103 node,
5104 this->astCtxt->bvsub(
5105 shiftAmount,
5106 this->astCtxt->bv(1, shiftAmount->getBitvectorSize())
5107 )
5108 )
5109 );
5110 break;
5111 }
5112
5114 carryOutNode = this->astCtxt->extract(
5117 this->astCtxt->bvror(
5118 node,
5119 this->astCtxt->bvurem(
5120 shiftAmount,
5121 this->astCtxt->bv(triton::bitsize::dword, shiftAmount->getBitvectorSize())
5122 )
5123 )
5124 );
5125 break;
5126 }
5127
5129 carryOutNode = this->astCtxt->extract(0, 0, node);
5130 break;
5131 }
5132
5133 default:
5134 throw triton::exceptions::Semantics("Arm32Semantics::getShiftCAst(): Invalid shift operand.");
5135 }
5136
5137 return carryOutNode;
5138 }
5139
5140
5141 triton::arch::arm::shift_e Arm32Semantics::getShiftCBaseType(const triton::arch::arm::ArmOperandProperties& shift) {
5143
5144 switch (shift.getShiftType()) {
5150 type = shift.getShiftType();
5151 break;
5152
5155 break;
5156
5159 break;
5160
5163 break;
5164
5167 break;
5168
5170 /* NOTE: Capstone considers this as a viable shift operand but
5171 * according to the ARM manual this is not possible.
5172 */
5173 throw triton::exceptions::Semantics("Arm32Semantics::getShiftCBasicType(): ID_SHIFT_RRX_REG is an invalid shift operand.");
5174
5175 default:
5176 throw triton::exceptions::Semantics("Arm32Semantics::getShiftCBasicType(): Invalid shift operand.");
5177 }
5178
5179 return type;
5180 }
5181
5182
5183 triton::ast::SharedAbstractNode Arm32Semantics::getShiftCAmountAst(const triton::arch::arm::ArmOperandProperties& shift) {
5184 auto imm = shift.getShiftImmediate();
5185 auto reg = shift.getShiftRegister();
5186
5188 triton::ast::SharedAbstractNode immShiftAmount = this->astCtxt->bv(imm, triton::bitsize::dword);
5189 triton::ast::SharedAbstractNode regShiftAmount = nullptr;
5190
5191 if (reg != triton::arch::ID_REG_INVALID) {
5192 auto op = this->symbolicEngine->getRegisterAst(this->architecture->getRegister(reg));
5193 regShiftAmount = this->astCtxt->zx(
5194 this->architecture->getRegister(reg).getBitSize()-8,
5195 this->astCtxt->extract(7, 0, op)
5196 );
5197 }
5198
5199 switch (shift.getShiftType()) {
5205 amount = immShiftAmount;
5206 break;
5207
5212 amount = regShiftAmount;
5213 break;
5214
5216 /* NOTE: Capstone considers this as a viable shift operand but
5217 * according to the ARM manual this is not possible.
5218 */
5219 throw triton::exceptions::Semantics("Arm32Semantics::getShiftCAmountAst(): ID_SHIFT_RRX_REG is an invalid shift operand.");
5220
5221 default:
5222 throw triton::exceptions::Semantics("Arm32Semantics::getShiftCAmountAst(): Invalid shift operand.");
5223 }
5224
5225 return amount;
5226 }
5227
5228
5229 }; /* arm32 namespace */
5230 }; /* arm namespace */
5231 }; /* arch namespace */
5232}; /* triton namespace */
The abstract architecture class.
TRITON_EXPORT const triton::arch::Register & getRegister(triton::arch::register_e id) const
Returns register from id.
TRITON_EXPORT void setThumb(bool state)
Sets CPU state to Thumb mode. Only valid for Arm32.
TRITON_EXPORT const triton::arch::Register & getStackPointer(void) const
Returns the stack pointer register.
TRITON_EXPORT bool isMemoryExclusive(const triton::arch::MemoryAccess &mem) const
Returns true if the memory access is tagged as exclusive. Only valid for Arm32 and AArch64.
TRITON_EXPORT void setMemoryExclusiveTag(const triton::arch::MemoryAccess &mem, bool tag)
Sets exclusive memory access tag. Only valid for Arm32 and AArch64.
TRITON_EXPORT triton::uint512 getConcreteRegisterValue(const triton::arch::Register &reg, bool execCallbacks=true) const
Returns the concrete value of a register.
TRITON_EXPORT bool isThumb(void) const
Returns true if the execution mode is Thumb. Only valid for Arm32.
TRITON_EXPORT const triton::arch::Register & getParentRegister(triton::arch::register_e id) const
Returns parent register from id.
This class is used to represent an immediate.
Definition immediate.hpp:37
TRITON_EXPORT triton::uint64 getValue(void) const
Returns the value of the operand.
Definition immediate.cpp:34
This class is used to represent an instruction.
TRITON_EXPORT triton::uint32 getSize(void) const
Returns the size of the instruction.
TRITON_EXPORT bool isWriteBack(void) const
Returns true if the instruction performs a write back. Mainly used for AArch64 instructions like LDR.
TRITON_EXPORT void setConditionTaken(bool flag)
Sets flag to define if the condition is taken or not.
TRITON_EXPORT triton::uint32 getType(void) const
Returns the type of the instruction.
TRITON_EXPORT triton::uint64 getAddress(void) const
Returns the address of the instruction.
std::vector< triton::arch::OperandWrapper > operands
A list of operands.
TRITON_EXPORT bool isUpdateFlag(void) const
Returns true if the instruction updates flags. Mainly used for AArch64 instructions like ADDS.
TRITON_EXPORT triton::arch::arm::condition_e getCodeCondition(void) const
Returns the code codition of the instruction (mainly for AArch64).
TRITON_EXPORT triton::uint64 getNextAddress(void) const
Returns the next address of the instruction.
This class is used to represent a memory access.
TRITON_EXPORT triton::ast::SharedAbstractNode getLeaAst(void) const
Returns the AST of the memory access (LEA).
TRITON_EXPORT triton::arch::Register & getBaseRegister(void)
LEA - Returns the base register operand.
This class is used as operand wrapper.
TRITON_EXPORT triton::arch::Register & getRegister(void)
Returns the register operand.
TRITON_EXPORT triton::uint32 getLow(void) const
Returns the lower bit position of the abstract operand.
TRITON_EXPORT triton::arch::operand_e getType(void) const
Returns the abstract type of the operand.
TRITON_EXPORT const triton::arch::MemoryAccess & getConstMemory(void) const
Returns the memory operand as const.
TRITON_EXPORT triton::arch::MemoryAccess & getMemory(void)
Returns the memory operand.
TRITON_EXPORT triton::uint32 getHigh(void) const
Returns the highest bit position of the abstract operand.
TRITON_EXPORT triton::uint32 getBitSize(void) const
Returns the abstract size (in bits) of the operand.
TRITON_EXPORT triton::arch::Immediate & getImmediate(void)
Returns the immediate operand.
TRITON_EXPORT triton::uint32 getBitSize(void) const
Returns the size (in bits) of the register.
Definition register.cpp:63
TRITON_EXPORT triton::arch::register_e getId(void) const
Returns the id of the register.
Definition register.cpp:53
TRITON_EXPORT triton::uint32 getSize(void) const
Returns the size (in bytes) of the register.
Definition register.cpp:68
This class is used to represent specific properties of an Arm operand.
TRITON_EXPORT triton::arch::arm::shift_e getShiftType(void) const
Returns the type of the shift.
TRITON_EXPORT triton::arch::register_e getShiftRegister(void) const
Returns the value of the shift register.
TRITON_EXPORT triton::uint32 getShiftImmediate(void) const
Returns the value of the shift immediate.
TRITON_EXPORT Arm32Semantics(triton::arch::Architecture *architecture, triton::engines::symbolic::SymbolicEngine *symbolicEngine, triton::engines::taint::TaintEngine *taintEngine, const triton::ast::SharedAstContext &astCtxt)
Constructor.
TRITON_EXPORT triton::arch::exception_e buildSemantics(triton::arch::Instruction &inst)
Builds the semantics of the instruction. Returns triton::arch::NO_FAULT if succeed.
TRITON_EXPORT void pushPathConstraint(const triton::arch::Instruction &inst, const triton::engines::symbolic::SharedSymbolicExpression &expr)
Pushs constraints of a branch instruction to the path predicate.
TRITON_EXPORT const SharedSymbolicExpression & createSymbolicRegisterExpression(triton::arch::Instruction &inst, const triton::ast::SharedAbstractNode &node, const triton::arch::Register &reg, const std::string &comment="")
Returns the new symbolic register expression expression and links this expression to the instruction.
triton::ast::SharedAbstractNode getShiftAst(const triton::arch::arm::ArmOperandProperties &shift, const triton::ast::SharedAbstractNode &node)
Returns the AST corresponding to the shift operation. Mainly used for Arm32 operands.
TRITON_EXPORT const SharedSymbolicExpression & createSymbolicVolatileExpression(triton::arch::Instruction &inst, const triton::ast::SharedAbstractNode &node, const std::string &comment="")
Returns the new symbolic volatile expression expression and links this expression to the instruction.
TRITON_EXPORT triton::ast::SharedAbstractNode getRegisterAst(const triton::arch::Register &reg)
Returns the AST corresponding to the register.
TRITON_EXPORT const SharedSymbolicExpression & createSymbolicExpression(triton::arch::Instruction &inst, const triton::ast::SharedAbstractNode &node, const triton::arch::OperandWrapper &dst, const std::string &comment="")
Returns the new symbolic expression and links this expression to the instruction.
TRITON_EXPORT triton::ast::SharedAbstractNode getOperandAst(const triton::arch::OperandWrapper &op)
Returns the AST corresponding to the operand.
TRITON_EXPORT bool setTaint(const triton::arch::OperandWrapper &op, bool flag)
Sets the flag (taint or untaint) to an abstract operand (Register or Memory).
TRITON_EXPORT bool isTainted(const triton::arch::OperandWrapper &op) const
Abstract taint verification. Returns true if the operand is tainted.
TRITON_EXPORT bool taintUnion(const triton::arch::OperandWrapper &op1, const triton::arch::OperandWrapper &op2)
Abstract union tainting.
TRITON_EXPORT bool setTaintRegister(const triton::arch::Register &reg, bool flag)
Sets the flag (taint or untaint) to a register.
TRITON_EXPORT bool taintAssignment(const triton::arch::OperandWrapper &op1, const triton::arch::OperandWrapper &op2)
Abstract assignment tainting.
The exception class used by all semantics.
@ ID_REG_INVALID
invalid = 0
Definition archEnums.hpp:65
shift_e
Types of shift.
@ ID_SHIFT_LSR
Logical Shift Right (immediate)
@ ID_SHIFT_LSR_REG
Logical Shift Right (register)
@ ID_SHIFT_ASR
Arithmetic Shift Right (immediate)
@ ID_SHIFT_ROR_REG
Rotate Right (register)
@ ID_SHIFT_ROR
Rotate Right (immediate)
@ ID_SHIFT_ASR_REG
Arithmetic Shift Right (register)
@ ID_SHIFT_RRX
Rotate Right with Extend (immediate)
@ ID_SHIFT_RRX_REG
Rotate Right with Extend (register)
@ ID_SHIFT_LSL_REG
Logical Shift Left (register)
@ ID_SHIFT_INVALID
invalid
@ ID_SHIFT_LSL
Logical Shift Left (immediate)
@ ID_CONDITION_HS
Higher or same (unsigned >=). C set.
@ ID_CONDITION_PL
Positive or zero. N clear.
@ ID_CONDITION_VC
No overflow. V clear.
@ ID_CONDITION_LE
Signed <=. Z set, N and V differ.
@ ID_CONDITION_VS
Overflow. V set.
@ ID_CONDITION_MI
Negative. N set.
@ ID_CONDITION_GE
Signed >=. N and V the same.
@ ID_CONDITION_GT
Signed >. Z clear, N and V the same.
@ ID_CONDITION_HI
Higher (unsigned >). C set and Z clear.
@ ID_CONDITION_NE
Not equal. Z clear.
@ ID_CONDITION_AL
Always. Any flags. This suffix is normally omitted.
@ ID_CONDITION_LO
Lower (unsigned <). C clear.
@ ID_CONDITION_LT
Signed <. N and V differ.
@ ID_CONDITION_LS
Lower or same (unsigned <=). C clear or Z set.
@ ID_CONDITION_EQ
Equal. Z set.
std::shared_ptr< triton::ast::AbstractNode > SharedAbstractNode
Shared Abstract Node.
Definition ast.hpp:59
std::shared_ptr< triton::ast::AstContext > SharedAstContext
Shared AST context.
Definition ast.hpp:65
constexpr triton::uint32 dword
dword size in bit
Definition cpuSize.hpp:64
constexpr triton::uint32 qword
qword size in bit
Definition cpuSize.hpp:66
constexpr triton::uint32 dword
dword size in byte
Definition cpuSize.hpp:34
std::shared_ptr< triton::engines::symbolic::SymbolicExpression > SharedSymbolicExpression
Shared Symbolic Expression.
Definition ast.hpp:40
const bool UNTAINTED
Defines an untainted item.
std::size_t usize
unsigned MAX_INT 32 or 64 bits according to the CPU.
std::uint64_t uint64
unisgned 64-bits
std::uint32_t uint32
unisgned 32-bits
The Triton namespace.