/Patterns/Expressions.py

https://github.com/sibears/HRAST
Python | 275 lines | 204 code | 70 blank | 1 comment | 51 complexity | a0ea3b3bf01d43d3eacae6ffe8777a9d MD5 | raw file
  1. # -*- coding: utf-8 -*-
  2. import sys
  3. import Patterns as p
  4. import Nodes
  5. class BindExpr(p.Pattern):
  6. def __init__(self, type, expr_pattern):
  7. super(BindExpr, self).__init__()
  8. self.type = type
  9. self.pattern = expr_pattern
  10. def check(self, expr, ctx):
  11. if self.pattern.check(expr, ctx):
  12. ctx.ctx.save_expr(self.type, expr)
  13. return True
  14. return False
  15. class VarName(p.Pattern):
  16. def __init__(self, name):
  17. super(VarName, self).__init__()
  18. self.name = name
  19. def check(self, expr, ctx):
  20. return ctx.ctx.get_var_name(expr.idx) == self.name
  21. class VarExpr(p.UnaryExpr):
  22. def __init__(self, name=p.AnyPattern()):
  23. super(VarExpr, self).__init__(name)
  24. def check(self, expr, ctx):
  25. return expr.opname == "var" and super(VarExpr, self).check(expr.v, ctx)
  26. class MemRefGlobalBind(p.Pattern):
  27. def __init__(self, name):
  28. super(MemRefGlobalBind, self).__init__()
  29. self.name = name
  30. def check(self, expr, ctx):
  31. if expr.opname == "memref":
  32. if expr.x.opname == "obj":
  33. if ctx.ctx.has_memref(self.name):
  34. return ctx.ctx.get_memref(self.name).idx == expr.x.obj_ea
  35. else:
  36. ctx.ctx.save_memref(self.name, expr.x.obj_ea, expr.m)
  37. return True
  38. return False
  39. class MemptrExpr(p.Pattern):
  40. def __init__(self, x, offset = -1, size = -1):
  41. super(MemptrExpr, self).__init__()
  42. self.x = x
  43. self.offset = offset
  44. self.size = size
  45. def check(self, expr, ctx):
  46. if expr.opname == "memptr":
  47. if self.offset != -1 and self.offset != expr.m:
  48. return False
  49. if self.size != -1 and self.size != expr.ptrsize:
  50. return False
  51. return self.x.check(expr.x, ctx)
  52. return False
  53. class MemrefExpr(p.Pattern):
  54. def __init__(self, x, offset = -1):
  55. super(MemrefExpr, self).__init__()
  56. self.x = x
  57. self.offset = offset
  58. def check(self, expr, ctx):
  59. if expr.opname == "memref":
  60. if self.offset != -1 and self.offset != expr.m:
  61. return False
  62. return self.x.check(expr.x, ctx)
  63. return False
  64. class PtrExpr(p.Pattern):
  65. def __init__(self, x, size = -1):
  66. super(PtrExpr, self).__init__()
  67. self.x = x
  68. self.size = size
  69. def check(self, expr, ctx):
  70. if expr.opname == "ptr":
  71. if self.size != -1 and self.size != expr.ptrsize:
  72. return False
  73. return self.x.check(expr.x, ctx)
  74. return False
  75. class MemRefIdxGlobalBind(p.Pattern):
  76. def __init__(self, name):
  77. super(MemRefIdxGlobalBind, self).__init__()
  78. self.name = name
  79. def check(self, expr, ctx):
  80. if expr.opname == "memref":
  81. if expr.x.opname == "idx" and expr.x.x.opname =="obj":
  82. if ctx.ctx.has_memref(self.name):
  83. return ctx.ctx.get_memref(self.name).idx == expr.x.x.obj_ea
  84. else:
  85. ctx.ctx.save_memref(self.name, expr.x.x.obj_ea, expr.m)
  86. return True
  87. return False
  88. class VarBind(p.UnaryExpr):
  89. def __init__(self, name):
  90. super(VarBind, self).__init__(p.AnyPattern())
  91. self.name = name
  92. def check(self, expr, ctx):
  93. if expr.opname == "var":
  94. if ctx.ctx.has_var(self.name):
  95. return ctx.ctx.get_var(self.name).idx == expr.v.idx
  96. else:
  97. ctx.ctx.save_var(self.name, expr.v.idx, expr.type, expr.v.mba)
  98. return True
  99. return False
  100. class ObjBind(p.UnaryExpr):
  101. def __init__(self, name):
  102. super(ObjBind, self).__init__(p.AnyPattern())
  103. self.name = name
  104. def check(self, expr, ctx):
  105. if expr.opname == "obj":
  106. if ctx.ctx.has_obj(self.name):
  107. return ctx.ctx.get_obj(self.name).addr == expr.obj_ea
  108. else:
  109. ctx.ctx.save_obj(self.name, expr.obj_ea, expr.type)
  110. return True
  111. return False
  112. class CallExpr(p.Pattern):
  113. def __init__(self, fcn, args):
  114. super(CallExpr, self).__init__()
  115. self.fcn = fcn
  116. self.args = args
  117. def check(self, expr, ctx):
  118. if expr.opname == "call" and self.fcn.check(expr.x, ctx):
  119. res = True
  120. ln = len(self.args)
  121. idx = 0
  122. for i in expr.a:
  123. if idx >= ln:
  124. return False
  125. res = res and self.args[idx].check(i, ctx)
  126. idx += 1
  127. return res
  128. return False
  129. class CallExprExactArgs(p.Pattern):
  130. def __init__(self, fcn, args):
  131. super(CallExprExactArgs, self).__init__()
  132. self.fcn = fcn
  133. self.args = args
  134. def check(self, expr, ctx):
  135. if expr.opname == "call" and self.fcn.check(expr.x, ctx):
  136. res = True
  137. ln = len(self.args)
  138. idx = 0
  139. for i in expr.a:
  140. if idx >= ln:
  141. return False
  142. res = res and self.args[idx].check(i, ctx)
  143. idx += 1
  144. if idx == ln:
  145. return res
  146. return False
  147. class ObjConcrete(p.Pattern):
  148. def __init__(self, addr):
  149. super(ObjConcrete, self).__init__()
  150. self.addr = addr
  151. def check(self, expr, ctx):
  152. if expr.opname == "obj":
  153. if expr.obj_ea == self.addr:
  154. return True
  155. return False
  156. class NumberConcrete(p.Pattern):
  157. def __init__(self, num):
  158. super(NumberConcrete, self).__init__()
  159. self.val = num
  160. def check(self, expr, ctx):
  161. return expr._value == self.val
  162. class NumberExpr(p.UnaryExpr):
  163. def __init__(self, num=p.AnyPattern()):
  164. super(NumberExpr, self).__init__(num)
  165. def check(self, expr, ctx):
  166. if expr.opname == "num":
  167. return super(NumberExpr, self).check(expr.n, ctx)
  168. return False
  169. class HelperExpr(p.Pattern):
  170. def __init__(self, name = None):
  171. super(HelperExpr, self).__init__()
  172. self.name = name
  173. def check(self, expr, ctx):
  174. if expr.opname == "helper":
  175. if self.name is not None:
  176. return expr.helper == self.name
  177. return True
  178. return False
  179. class CastExpr(p.Pattern):
  180. def __init__(self, inner, cast_type=None):
  181. super(CastExpr, self).__init__()
  182. self.cast_type = cast_type
  183. self.inner = inner
  184. def check(self, expr, ctx):
  185. if expr.opname == "cast":
  186. if self.cast_type is not None and expr.type.dstr() != self.cast_type:
  187. return False
  188. res = self.inner.check(expr.x, ctx)
  189. return res
  190. return False
  191. def BinaryGen(name, opname, BaseClass=p.BinaryExpr):
  192. def check(self, expr, ctx):
  193. return expr.opname == opname and super(type(self), self).check(expr, ctx)
  194. newclass = type(name, (BaseClass,), {"check": check})
  195. return newclass
  196. def UnaryGen(name, opname, BaseClass=p.UnaryExpr):
  197. def check(self, expr, ctx):
  198. return expr.opname == opname and super(type(self), self).check(expr.x, ctx)
  199. newclass = type(name, (BaseClass,), {"check": check})
  200. return newclass
  201. module = sys.modules[__name__]
  202. for i in Nodes.TWO_OP:
  203. setattr(module, i[0] + "Expr", BinaryGen(i[0] + "Expr", i[1]))
  204. for i in Nodes.ONE_OP:
  205. setattr(module, i[0] + "Expr", UnaryGen(i[0] + "Expr", i[1]))