Miasm2
 All Classes Namespaces Files Functions Variables Typedefs Properties Macros
C.py
Go to the documentation of this file.
1 from miasm2.ir.translators.translator import Translator
2 from miasm2.core import asmbloc
3 from miasm2.expression.modint import size2mask
4 
5 
7  "Translate a Miasm expression to an equivalent C code"
8 
9  # Implemented language
10  __LANG__ = "C"
11 
12  # Operations translation
13  dct_shift = {'a>>': "right_arith",
14  '>>': "right_logic",
15  '<<': "left_logic",
16  'a<<': "left_logic",
17  }
18  dct_rot = {'<<<': 'rot_left',
19  '>>>': 'rot_right',
20  }
21  dct_div = {'div8': "div_op",
22  'div16': "div_op",
23  'div32': "div_op",
24  'idiv32': "div_op", # XXX to test
25  '<<<c_rez': 'rcl_rez_op',
26  '<<<c_cf': 'rcl_cf_op',
27  '>>>c_rez': 'rcr_rez_op',
28  '>>>c_cf': 'rcr_cf_op',
29  }
30 
31 
32  def from_ExprId(self, expr):
33  if isinstance(expr.name, asmbloc.asm_label):
34  return "0x%x" % expr.name.offset
35  return str(expr)
36 
37  def from_ExprInt(self, expr):
38  return "0x%x" % expr.arg.arg
39 
40  def from_ExprAff(self, expr):
41  return "%s = %s" % tuple(map(self.from_expr, (expr.dst, expr.src)))
42 
43  def from_ExprCond(self, expr):
44  return "(%s?%s:%s)" % tuple(map(self.from_expr,
45  (expr.cond, expr.src1, expr.src2)))
46 
47  def from_ExprMem(self, expr):
48  return "MEM_LOOKUP_%.2d(jitcpu, %s)" % (expr.size,
49  self.from_expr(expr.arg))
50 
51  def from_ExprOp(self, expr):
52  if len(expr.args) == 1:
53  if expr.op == 'parity':
54  return "parity(%s&0x%x)" % (self.from_expr(expr.args[0]),
55  size2mask(expr.args[0].size))
56  elif expr.op in ['bsr', 'bsf']:
57  return "x86_%s(%s, 0x%x)" % (expr.op,
58  self.from_expr(expr.args[0]),
59  expr.args[0].size)
60  elif expr.op == '!':
61  return "(~ %s)&0x%x" % (self.from_expr(expr.args[0]),
62  size2mask(expr.args[0].size))
63  elif expr.op in ["hex2bcd", "bcd2hex"]:
64  return "%s_%d(%s)" % (expr.op, expr.args[0].size,
65  self.from_expr(expr.args[0]))
66  elif (expr.op.startswith("double_to_") or
67  expr.op.endswith("_to_double") or
68  expr.op.startswith("access_") or
69  expr.op.startswith("load_") or
70  expr.op in ["-", "ftan", "frndint", "f2xm1",
71  "fsin", "fsqrt", "fabs", "fcos"]):
72  return "%s(%s)" % (expr.op, self.from_expr(expr.args[0]))
73  else:
74  raise NotImplementedError('Unknown op: %r' % expr.op)
75 
76  elif len(expr.args) == 2:
77  if expr.op == "==":
78  return '(((%s&0x%x) == (%s&0x%x))?1:0)' % (
79  self.from_expr(expr.args[0]), size2mask(expr.args[0].size),
80  self.from_expr(expr.args[1]), size2mask(expr.args[1].size))
81  elif expr.op in self.dct_shift:
82  return 'shift_%s_%.2d(%s , %s)' % (self.dct_shift[expr.op],
83  expr.args[0].size,
84  self.from_expr(expr.args[0]),
85  self.from_expr(expr.args[1]))
86  elif expr.is_associative() or expr.op in ["%", "/"]:
87  oper = ['(%s&0x%x)' % (self.from_expr(arg), size2mask(arg.size))
88  for arg in expr.args]
89  oper = str(expr.op).join(oper)
90  return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size))
91  elif expr.op in ['-']:
92  return '(((%s&0x%x) %s (%s&0x%x))&0x%x)' % (
93  self.from_expr(expr.args[0]), size2mask(expr.args[0].size),
94  str(expr.op),
95  self.from_expr(expr.args[1]), size2mask(expr.args[1].size),
96  size2mask(expr.args[0].size))
97  elif expr.op in self.dct_rot:
98  return '(%s(%s, %s, %s) &0x%x)' % (self.dct_rot[expr.op],
99  expr.args[0].size,
100  self.from_expr(expr.args[0]),
101  self.from_expr(expr.args[1]),
102  size2mask(expr.args[0].size))
103  elif (expr.op.startswith('cpuid') or
104  expr.op.startswith("fcom") or
105  expr.op in ["fadd", "fsub", "fdiv", 'fmul', "fscale"]):
106  return "%s(%s, %s)" % (expr.op, self.from_expr(expr.args[0]),
107  self.from_expr(expr.args[1]))
108  elif expr.op == "segm":
109  return "segm2addr(jitcpu, %s, %s)" % (
110  self.from_expr(expr.args[0]), self.from_expr(expr.args[1]))
111  elif expr.op in ['udiv', 'umod', 'idiv', 'imod']:
112  return '%s%d((vm_cpu_t*)jitcpu->cpu, %s, %s)' % (expr.op,
113  expr.args[0].size,
114  self.from_expr(expr.args[0]),
115  self.from_expr(expr.args[1]))
116  elif expr.op in ["bcdadd", "bcdadd_cf"]:
117  return "%s_%d(%s, %s)" % (expr.op, expr.args[0].size,
118  self.from_expr(expr.args[0]),
119  self.from_expr(expr.args[1]))
120  else:
121  raise NotImplementedError('Unknown op: %r' % expr.op)
122 
123  elif len(expr.args) == 3 and expr.op in self.dct_div:
124  return '(%s(%s, %s, %s, %s) &0x%x)' % (self.dct_div[expr.op],
125  expr.args[0].size,
126  self.from_expr(expr.args[0]),
127  self.from_expr(expr.args[1]),
128  self.from_expr(expr.args[2]),
129  size2mask(expr.args[0].size))
130 
131  elif len(expr.args) >= 3 and expr.is_associative(): # ?????
132  oper = ['(%s&0x%x)' % (self.from_expr(arg), size2mask(arg.size))
133  for arg in expr.args]
134  oper = str(expr.op).join(oper)
135  return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size))
136 
137  else:
138  raise NotImplementedError('Unknown op: %s' % expr.op)
139 
140  def from_ExprSlice(self, expr):
141  # XXX check mask for 64 bit & 32 bit compat
142  return "((%s>>%d) & 0x%X)" % (self.from_expr(expr.arg),
143  expr.start,
144  (1 << (expr.stop - expr.start)) - 1)
145 
146  def from_ExprCompose(self, expr):
147  out = []
148  # XXX check mask for 64 bit & 32 bit compat
149  dst_cast = "uint%d_t" % expr.size
150  for x in expr.args:
151  out.append("(((%s)(%s & 0x%X)) << %d)" % (dst_cast,
152  self.from_expr(x[0]),
153  (1 << (x[2] - x[1])) - 1,
154  x[1]))
155  out = ' | '.join(out)
156  return '(' + out + ')'
157 
158 
159 # Register the class
160 Translator.register(TranslatorC)