first prototype (very WIP)
This commit is contained in:
parent
913d090d3b
commit
a95e1c09cf
1 changed files with 82 additions and 0 deletions
82
main.py
Normal file
82
main.py
Normal 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)
|
Loading…
Reference in a new issue