first prototype (very WIP)

This commit is contained in:
Daniel S. 2022-02-07 23:29:15 +01:00
parent 913d090d3b
commit a95e1c09cf

82
main.py Normal file
View file

@ -0,0 +1,82 @@
import sys
import esprima
import operator as OP
import esprima.nodes as N
def eval_binex(op, lhs, rhs):
return {"*": OP.mul, "+": OP.add,"-": OP.sub}[op](lhs, rhs)
def eval_unex(op,val):
return {"-":OP.neg,"!":OP.not_}[op](val)
class Emulator(object):
def __init__(self, code):
self.ret_cache = {}
self.funcs = {}
self.edges = set()
self.ast = esprima.parseModule(code, delegate=self)
def __call__(self, node, meta):
self.pos = meta
attr_name = "visit_" + node.type
func = getattr(self, attr_name,None)
if callable(func):
return func(node)
else:
# print("UNIMPL:",node.type)
pass
return node
def visit_VariableDeclaration(self,node):
return node
def visit_FunctionDeclaration(self,node):
if node.body.type=="BlockStatement":
body=node.body.body
if len(body)==1 and body[0].type=="ReturnStatement" and body[0].argument.type=="CallExpression":
arg=body[0].argument
print("EDGE:",node.id.name,"->",arg.callee.name)
self.edges.add((node.id.name,arg.callee.name))
self.funcs.setdefault(node.id.name,[]).append(node)
return node
def visit_CallExpression(self,node):
const_args=all([a.type=="Literal" for a in node.arguments])
if node.callee.type=="Identifier" and const_args:
print("CALL",node.callee.name,[a.value for a in node.arguments])
return node
def visit_Literal(self,node):
return node
def visit_UnaryExpression(self,node):
if node.argument.type=="Literal":
val=eval_unex(node.operator,node.argument.value)
node = N.Literal(val, hex(val))
return node
def visit_BinaryExpression(self, node):
if node.left.type == "Literal" and node.right.type == "Literal":
if isinstance(node.left.value,(int,float)) and isinstance(node.right.value,(int,float)):
val = eval_binex(node.operator, node.left.value, node.right.value)
node = N.Literal(val, hex(val))
return node
def visit_Identifier(self, node):
# print("Ident", node.name)
return node
# def deobf(node,meta):
# if node.type=="Identifier":
# if node.name.find("_0x")!=-1:
# node.name=idents.setdefault(node.name,f"var_{len(idents)}")
# return node
# if node.type=="BinaryExpression" and node.left.type=="Literal" and node.right.type=="Literal":
# return simplify_binex(node)
code = open(sys.argv[1]).read()
emu = Emulator(code)
print("EDGES:",len(emu.edges))
print("FUNCS:",len(emu.funcs))
# print(emu.ast)