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 tree = Dump.DumpTree; // NExpr.Print(tree) def stateDeobfsVar = Walk( tree, fun(expr : NExpr) { | Switch(expr, _) => Expr(expr) | _ => null } ); Console.WriteLine( "Deobfs state == {0}", stateDeobfsVar ); def (stateObfsVar, stateOff) = Walk( tree, fun(expr : NExpr) { | Assign(left, right) => match(left) { | Var(var) when var == stateDeobfsVar => match(right) { | Arith(type_, left, right) => ( Expr(left) :> string, match(type_) { | Add => Expr(right) :> long | Sub => -(Expr(right) :> long) | _ => throw Exception("WTF?") } ) : object | _ => null } | _ => null } | _ => null } ) :> string * long; Console.WriteLine( "Obfs state == {0}", stateObfsVar ); Console.WriteLine( "State offset == {0}", stateOff ); } 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 WalkCases(exprs, func) { match(exprs) { | [] => null | (_, head) :: tail => def ret = Walk(head, func); if(ret == null) WalkCases(tail, func) else ret } } def ret = func(tree); if(ret == null) { match(tree) { | Loc(_, body) => Walk(body, func) | Block(exprs) => WalkList(exprs, func) | If(_, then, else_) => def ret = Walk(then, func); if(ret == null) Walk(else_, func) else ret | Switch(_, cases) => WalkCases(cases, func) | While(_, body) => Walk(body, func) | _ => null } } else ret } } }