All pastes #995961 Raw Edit

Mine

public text v1 · immutable
#995961 ·published 2008-04-24 16:45 UTC
rendered paste body
using NObfs.Tree;
using NObfs.Dump;
using System;

namespace NObfs {
	public module NObfs {
		public Main() : void {
			def Expr(expr : NExpr) {
				| Var(var) => var : object
				| Number(num) => num : object
				| x => x
			}
			
			def FindAssign(tree, var) : NExpr {
				Walk(
					tree,
					fun(expr : NExpr) {
						| Assign(left, right) =>
							match(left) {
								| Var(var_) when var_ == var => right
								| _ => null
							}
						| _ => null
					}
				) :> NExpr
			}
			
			def FindAllAssigns(tree, var) : list [object] {
				WalkAll(
					tree,
					fun(expr : NExpr) {
						| Assign(left, _) =>
							match(left) {
								| Var(var_) when var_ == var => expr
								| _ => null
							}
						| _ => null
					}
				)
			}
			
			def tree = Dump.DumpTree;
			// NExpr.Print(tree)
			
			def stateDeobfsVar = Walk(
				tree,
				fun(expr : NExpr) {
					| Switch(expr, _) => Expr(expr)
					| _ => null
				}
			) :> string;
			Console.WriteLine(
				"Deobfs state == {0}",
				stateDeobfsVar
			);
			
			def (stateObfsVar, stateOff) = match(FindAssign(tree, stateDeobfsVar)) {
				| Arith(type_, left, right) =>
					(
						Expr(left) :> string,
						match(type_) {
							| Add =>   Expr(right) :> long
							| Sub => -(Expr(right) :> long)
							| _ => throw Exception("WTF?")
						}
					)
				| _ => throw Exception("Uh?")
			}
			Console.WriteLine(
				"Obfs state == {0}",
				stateObfsVar
			);
			Console.WriteLine(
				"State offset == {0}",
				stateOff
			);
			
			def initialState = (Expr(FindAssign(tree, stateObfsVar)) :> long + stateOff) :> uint;
			Console.WriteLine(
				"Initial state == {0}",
				initialState
			);
			
			def Evaluate(expr : NExpr, stack) {
				match(expr) {
					| Number(num) => num
					| x => throw Exception(String.Format("Unknown type {0}", x))
				}
			}
			
			def DefyLogic(state, stack) : void {
				def case = Walk(
					tree,
					fun(expr : NExpr) {
						| Case(values, _) when values.Contains(initialState) => expr
						| _ => null
					}
				) :> NExpr;
				def stack = case :: stack;
				def stateExpr = FindAssign(case, stateObfsVar);
				def nextState = (Evaluate(stateExpr, stack) + stateOff) :> uint;
				DefyLogic(nextState, stack);
			}
			
			DefyLogic(initialState, []);
		}
		
		Walk(tree : NExpr, func : NExpr -> object) : object {
			def WalkList(exprs, func) {
				match(exprs) {
					| [] => null
					| head :: tail =>
						def ret = Walk(head, func);
						if(ret == null)
							WalkList(tail, func)
						else
							ret
				}
			}
			
			def ret = func(tree);
			if(ret == null) {
				match(tree) {
					| Loc(_, body)
					| Case(_, body)
					| While(_, body) => Walk(body, func)
					
					| Switch(_, body)
					| Block(body) => WalkList(body, func)
					
					| If(_, then, else_) =>
						def ret = Walk(then, func);
						if(ret == null)
							Walk(else_, func)
						else
							ret
					| _ => null
				}
			} else
				ret
		}
		
		WalkAll(tree : NExpr, func : NExpr -> object, mutable accum : list [object] = null) : list [object] {
			def WalkList(exprs, func, accum) {
				match(exprs) {
					| [] => accum
					| head :: tail =>
						WalkList(
							tail,
							func,
							WalkAll(head, func, accum)
						)
				}
			}
			
			when(accum == null)
				accum = [];
			
			def ret = func(tree);
			unless(ret == null)
				accum = ret :: accum;
				
			match(tree) {
				| Loc(_, body)
				| Case(_, body)
				| While(_, body) => WalkAll(body, func, accum)
				
				| Switch(_, body)
				| Block(body) => WalkList(body, func, accum)
				
				| If(_, then, else_) =>
					WalkAll(
						else_, 
						func,
						WalkAll(
							then,
							func,
							accum
						)
					)
				| _ => accum
			}
		}
	}
}