node/lib/metasm/metasm/decompile.rb
# patches instruction's backtrace_binding to replace things referring to a static stack offset from func start by :frameptr+off
patches instruction's backtrace_binding to replace things referring to a static stack offset from func start by :frameptr+off
patches instruction ' s backtrace_binding to replace things referring to a static stack offset from func start by : frameptr + off
def makestackvars(funcstart, blocks)
		blockstart = nil
		cache_di = nil
		cache = {}	
		tovar = lambda { |di, e, i_s|
			case e
			when Expression; Expression[tovar[di, e.lexpr, i_s], e.op, tovar[di, e.rexpr, i_s]].reduce
			when Indirection; Indirection[tovar[di, e.target, i_s], e.len, e.origin]
			when :frameptr; e
			when ::Symbol
				cache.clear if cache_di != di ; cache_di = di
				vals = cache[[e, i_s, 0]] ||= @dasm.backtrace(e, di.address, :snapshot_addr => blockstart,
						:include_start => i_s, :no_check => true, :terminals => [:frameptr])
				if vals.length == 1 and ee = vals.first and ee.kind_of? Expression and (ee == Expression[:frameptr] or
						(ee.lexpr == :frameptr and ee.op == :+ and ee.rexpr.kind_of? ::Integer) or
						(not ee.lexpr and ee.op == :+ and ee.rexpr.kind_of? Indirection and eep = ee.rexpr.pointer and
						(eep == Expression[:frameptr] or (eep.lexpr == :frameptr and eep.op == :+ and eep.rexpr.kind_of? ::Integer))))
					ee
				else
				vals = cache[[e, i_s, 1]] ||= @dasm.backtrace(e, di.address, :snapshot_addr => funcstart,
						:include_start => i_s, :no_check => true, :terminals => [:frameptr])
				if vals.length == 1 and ee = vals.first and (ee.kind_of? Expression and (ee == Expression[:frameptr] or
						(ee.lexpr == :frameptr and ee.op == :+ and ee.rexpr.kind_of? ::Integer)))
					ee
				else e
				end
				end
			else e
			end
		}
		repl_bind = {}	
		@dasm.cpu.decompile_makestackvars(@dasm, funcstart, blocks) { |block|
			block.list.each { |di|
				bd = di.backtrace_binding ||= @dasm.cpu.get_backtrace_binding(di)
				newbd = repl_bind[di] = {}
				bd.each { |k, v|
					k = tovar[di, k, true] if k.kind_of? Indirection
					next if k == Expression[:frameptr] or (k.kind_of? Expression and k.lexpr == :frameptr and k.op == :+ and k.rexpr.kind_of? ::Integer)
					newbd[k] = tovar[di, v, false]
				}
			}
		}
		repl_bind.each { |di, bd| di.backtrace_binding = bd }
	end
def makestackvars ( funcstart , blocks ) blockstart = nil cache_di = nil cache = { } tovar = lambda { | di , e , i_s | case e when Expression ; Expression [ tovar [ di , e . lexpr , i_s ] , e . op , tovar [ di , e . rexpr , i_s ] ] . reduce when Indirection ; Indirection [ tovar [ di , e . target , i_s ] , e . len , e . origin ] when :frameptr ; e when :: Symbol cache . clear if cache_di != di ; cache_di = di vals = cache [ [ e , i_s , 0 ] ] ||= @dasm . backtrace ( e , di . address , :snapshot_addr => blockstart , :include_start => i_s , :no_check => true , :terminals => [ :frameptr ] ) if vals . length == 1 and ee = vals . first and ee . kind_of? Expression and ( ee == Expression [ :frameptr ] or ( ee . lexpr == :frameptr and ee . op == :+ and ee . rexpr . kind_of? :: Integer ) or ( not ee . lexpr and ee . op == :+ and ee . rexpr . kind_of? Indirection and eep = ee . rexpr . pointer and ( eep == Expression [ :frameptr ] or ( eep . lexpr == :frameptr and eep . op == :+ and eep . rexpr . kind_of? :: Integer ) ) ) ) ee else vals = cache [ [ e , i_s , 1 ] ] ||= @dasm . backtrace ( e , di . address , :snapshot_addr => funcstart , :include_start => i_s , :no_check => true , :terminals => [ :frameptr ] ) if vals . length == 1 and ee = vals . first and ( ee . kind_of? Expression and ( ee == Expression [ :frameptr ] or ( ee . lexpr == :frameptr and ee . op == :+ and ee . rexpr . kind_of? :: Integer ) ) ) ee else e end end else e end } repl_bind = { } @dasm . cpu . decompile_makestackvars ( @dasm , funcstart , blocks ) { | block | block . list . each { | di | bd = di . backtrace_binding ||= @dasm . cpu . get_backtrace_binding ( di ) newbd = repl_bind [ di ] = { } bd . each { | k , v | k = tovar [ di , k , true ] if k . kind_of? Indirection next if k == Expression [ :frameptr ] or ( k . kind_of? Expression and k . lexpr == :frameptr and k . op == :+ and k . rexpr . kind_of? :: Integer ) newbd [ k ] = tovar [ di , v , false ] } } } repl_bind . each { | di , bd | di . backtrace_binding = bd } end
patches instruction's backtrace_binding to replace things referring to a static stack offset from func start by :frameptr+off
patches instruction ' s backtrace_binding to replace things referring to a static stack offset from func start by : frameptr + off
# [i_s, e, type] => backtrace # backtrace only to blockstart first # fallback on full run (could restart from blockstart with ee, but may reevaluate addr_binding.. # must not change bt_bindings until everything is backtracked # di => bt_bd
funcstart
blocks