From a95e1c09cf90d29de6d1644a9fee87b3e44717d6 Mon Sep 17 00:00:00 2001 From: Daniel Seiller Date: Mon, 7 Feb 2022 23:29:15 +0100 Subject: [PATCH] first prototype (very WIP) --- main.py | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 main.py diff --git a/main.py b/main.py new file mode 100644 index 0000000..04d53c8 --- /dev/null +++ b/main.py @@ -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)