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…
	
	Add table
		Add a link
		
	
		Reference in a new issue