node/lib/metasm/metasm/decompile.rb
def fix_pointer_arithmetic(scope)
		walk_ce(scope, true) { |ce|
			if ce.lexpr and ce.lexpr.type.pointer? and [:&, :>>, :<<].include? ce.op
				ce.lexpr = C::CExpression[[ce.lexpr], C::BaseType.new(:int)]
			end

			if ce.op == :+ and ce.lexpr and ((ce.lexpr.type.integral? and ce.rexpr.type.pointer?) or (ce.rexpr.type.pointer? and ce.rexpr.type.pointed.untypedef.kind_of? C::Union))
				ce.rexpr, ce.lexpr = ce.lexpr, ce.rexpr
			end

			if ce.op == :* and not ce.lexpr and ce.rexpr.type.pointer? and ce.rexpr.type.pointed.untypedef.kind_of? C::Struct
				s = ce.rexpr.type.pointed.untypedef
				m = s.members.to_a.find { |m_| s.offsetof(@c_parser, m_.name) == 0 }
				if sizeof(m) != sizeof(ce)
					ce.rexpr = C::CExpression[[ce.rexpr, C::Pointer.new(s)], C::Pointer.new(ce.type)]
					next
				end
				# *structptr => structptr->member
				ce.lexpr = ce.rexpr
				ce.op = :'->'
				ce.rexpr = m.name
				ce.type = m.type
				next
			elsif ce.op == :'=' and ce.lexpr.type.untypedef.kind_of? C::Struct
				s = ce.lexpr.type.untypedef
				m = s.members.to_a.find { |m_| s.offsetof(@c_parser, m_.name) == 0 }
				ce.lexpr = C::CExpression.new(ce.lexpr, :'.', m.name, m.type)
				ce.type = m.type
				next
			end

			if ce.op == :+ and ce.lexpr and ce.lexpr.type.pointer? and not ce.type.pointer?
				ce.type = ce.lexpr.type
			end

			if ce.op == :& and not ce.lexpr and ce.rexpr.kind_of? C::CExpression and ce.rexpr.op == :* and not ce.rexpr.lexpr
				ce.replace C::CExpression[ce.rexpr.rexpr]
			end

			next if not ce.lexpr or not ce.lexpr.type.pointer?
			if ce.op == :+ and (s = ce.lexpr.type.pointed.untypedef).kind_of? C::Union and ce.rexpr.kind_of? C::CExpression and not ce.rexpr.op and
					ce.rexpr.rexpr.kind_of? ::Integer and o = ce.rexpr.rexpr
				# structptr + 4 => &structptr->member
				ce.replace structoffset(s, ce.lexpr, o, nil)
			elsif [:+, :-, :'+=', :'-='].include? ce.op and ce.rexpr.kind_of? C::CExpression and ((not ce.rexpr.op and i = ce.rexpr.rexpr) or
					(ce.rexpr.op == :* and i = ce.rexpr.lexpr and ((i.kind_of? C::CExpression and not i.op and i = i.rexpr) or true))) and
					i.kind_of? ::Integer and psz = sizeof(nil, ce.lexpr.type.pointed) and i % psz == 0
				# ptr += 4 => ptr += 1
				if not ce.rexpr.op
					ce.rexpr.rexpr /= psz
				else
					ce.rexpr.lexpr.rexpr /= psz
					if ce.rexpr.lexpr.rexpr == 1
						ce.rexpr = ce.rexpr.rexpr
					end
				end
				ce.type = ce.lexpr.type

			elsif (ce.op == :+ or ce.op == :-) and sizeof(nil, ce.lexpr.type.pointed) != 1
				# ptr+x => (ptrtype*)(((__int8*)ptr)+x)
				# XXX create struct ?
				ce.rexpr = C::CExpression[ce.rexpr, C::BaseType.new(:int)] if not ce.rexpr.type.integral?
				if sizeof(nil, ce.lexpr.type.pointed) != 1
					ptype = ce.lexpr.type
					p = C::CExpression[[ce.lexpr], C::Pointer.new(C::BaseType.new(:__int8))]
					ce.replace C::CExpression[[p, ce.op, ce.rexpr, p.type], ptype]
				end
			end
		}
	end
# fix pointer arithmetic (eg int foo += 4  =>  int* foo += 1)
# use struct member access (eg *(structptr+8)  =>  structptr->bla)
# must be run only once, right after type setting
fix pointer arithmetic
use struct member access   =>  structptr->bla)
must be run only once, right after type setting
fix pointer arithmetic use struct member access = > structptr - > bla ) must be run only once right after type setting
def fix_pointer_arithmetic(scope)
		walk_ce(scope, true) { |ce|
			if ce.lexpr and ce.lexpr.type.pointer? and [:&, :>>, :<<].include? ce.op
				ce.lexpr = C::CExpression[[ce.lexpr], C::BaseType.new(:int)]
			end
			if ce.op == :+ and ce.lexpr and ((ce.lexpr.type.integral? and ce.rexpr.type.pointer?) or (ce.rexpr.type.pointer? and ce.rexpr.type.pointed.untypedef.kind_of? C::Union))
				ce.rexpr, ce.lexpr = ce.lexpr, ce.rexpr
			end
			if ce.op == :* and not ce.lexpr and ce.rexpr.type.pointer? and ce.rexpr.type.pointed.untypedef.kind_of? C::Struct
				s = ce.rexpr.type.pointed.untypedef
				m = s.members.to_a.find { |m_| s.offsetof(@c_parser, m_.name) == 0 }
				if sizeof(m) != sizeof(ce)
					ce.rexpr = C::CExpression[[ce.rexpr, C::Pointer.new(s)], C::Pointer.new(ce.type)]
					next
				end
				ce.lexpr = ce.rexpr
				ce.op = :'->'
				ce.rexpr = m.name
				ce.type = m.type
				next
			elsif ce.op == :'=' and ce.lexpr.type.untypedef.kind_of? C::Struct
				s = ce.lexpr.type.untypedef
				m = s.members.to_a.find { |m_| s.offsetof(@c_parser, m_.name) == 0 }
				ce.lexpr = C::CExpression.new(ce.lexpr, :'.', m.name, m.type)
				ce.type = m.type
				next
			end
			if ce.op == :+ and ce.lexpr and ce.lexpr.type.pointer? and not ce.type.pointer?
				ce.type = ce.lexpr.type
			end
			if ce.op == :& and not ce.lexpr and ce.rexpr.kind_of? C::CExpression and ce.rexpr.op == :* and not ce.rexpr.lexpr
				ce.replace C::CExpression[ce.rexpr.rexpr]
			end
			next if not ce.lexpr or not ce.lexpr.type.pointer?
			if ce.op == :+ and (s = ce.lexpr.type.pointed.untypedef).kind_of? C::Union and ce.rexpr.kind_of? C::CExpression and not ce.rexpr.op and
					ce.rexpr.rexpr.kind_of? ::Integer and o = ce.rexpr.rexpr
				ce.replace structoffset(s, ce.lexpr, o, nil)
			elsif [:+, :-, :'+=', :'-='].include? ce.op and ce.rexpr.kind_of? C::CExpression and ((not ce.rexpr.op and i = ce.rexpr.rexpr) or
					(ce.rexpr.op == :* and i = ce.rexpr.lexpr and ((i.kind_of? C::CExpression and not i.op and i = i.rexpr) or true))) and
					i.kind_of? ::Integer and psz = sizeof(nil, ce.lexpr.type.pointed) and i % psz == 0
				if not ce.rexpr.op
					ce.rexpr.rexpr /= psz
				else
					ce.rexpr.lexpr.rexpr /= psz
					if ce.rexpr.lexpr.rexpr == 1
						ce.rexpr = ce.rexpr.rexpr
					end
				end
				ce.type = ce.lexpr.type
			elsif (ce.op == :+ or ce.op == :-) and sizeof(nil, ce.lexpr.type.pointed) != 1
				ce.rexpr = C::CExpression[ce.rexpr, C::BaseType.new(:int)] if not ce.rexpr.type.integral?
				if sizeof(nil, ce.lexpr.type.pointed) != 1
					ptype = ce.lexpr.type
					p = C::CExpression[[ce.lexpr], C::Pointer.new(C::BaseType.new(:__int8))]
					ce.replace C::CExpression[[p, ce.op, ce.rexpr, p.type], ptype]
				end
			end
		}
	end
def fix_pointer_arithmetic ( scope ) walk_ce ( scope , true ) { | ce | if ce . lexpr and ce . lexpr . type . pointer? and [ :& , :>> , :<< ] . include? ce . op ce . lexpr = C :: CExpression [ [ ce . lexpr ] , C :: BaseType . new ( :int ) ] end if ce . op == :+ and ce . lexpr and ( ( ce . lexpr . type . integral? and ce . rexpr . type . pointer? ) or ( ce . rexpr . type . pointer? and ce . rexpr . type . pointed . untypedef . kind_of? C :: Union ) ) ce . rexpr , ce . lexpr = ce . lexpr , ce . rexpr end if ce . op == :* and not ce . lexpr and ce . rexpr . type . pointer? and ce . rexpr . type . pointed . untypedef . kind_of? C :: Struct s = ce . rexpr . type . pointed . untypedef m = s . members . to_a . find { | m_ | s . offsetof ( @c_parser , m_ . name ) == 0 } if sizeof ( m ) != sizeof ( ce ) ce . rexpr = C :: CExpression [ [ ce . rexpr , C :: Pointer . new ( s ) ] , C :: Pointer . new ( ce . type ) ] next end ce . lexpr = ce . rexpr ce . op = :' -> ' ce . rexpr = m . name ce . type = m . type next elsif ce . op == :' = ' and ce . lexpr . type . untypedef . kind_of? C :: Struct s = ce . lexpr . type . untypedef m = s . members . to_a . find { | m_ | s . offsetof ( @c_parser , m_ . name ) == 0 } ce . lexpr = C :: CExpression . new ( ce . lexpr , :' . ' , m . name , m . type ) ce . type = m . type next end if ce . op == :+ and ce . lexpr and ce . lexpr . type . pointer? and not ce . type . pointer? ce . type = ce . lexpr . type end if ce . op == :& and not ce . lexpr and ce . rexpr . kind_of? C :: CExpression and ce . rexpr . op == :* and not ce . rexpr . lexpr ce . replace C :: CExpression [ ce . rexpr . rexpr ] end next if not ce . lexpr or not ce . lexpr . type . pointer? if ce . op == :+ and ( s = ce . lexpr . type . pointed . untypedef ) . kind_of? C :: Union and ce . rexpr . kind_of? C :: CExpression and not ce . rexpr . op and ce . rexpr . rexpr . kind_of? :: Integer and o = ce . rexpr . rexpr ce . replace structoffset ( s , ce . lexpr , o , nil ) elsif [ :+ , :- , :' += ' , :' -= ' ] . include? ce . op and ce . rexpr . kind_of? C :: CExpression and ( ( not ce . rexpr . op and i = ce . rexpr . rexpr ) or ( ce . rexpr . op == :* and i = ce . rexpr . lexpr and ( ( i . kind_of? C :: CExpression and not i . op and i = i . rexpr ) or true ) ) ) and i . kind_of? :: Integer and psz = sizeof ( nil , ce . lexpr . type . pointed ) and i % psz == 0 if not ce . rexpr . op ce . rexpr . rexpr /= psz else ce . rexpr . lexpr . rexpr /= psz if ce . rexpr . lexpr . rexpr == 1 ce . rexpr = ce . rexpr . rexpr end end ce . type = ce . lexpr . type elsif ( ce . op == :+ or ce . op == :- ) and sizeof ( nil , ce . lexpr . type . pointed ) != 1 ce . rexpr = C :: CExpression [ ce . rexpr , C :: BaseType . new ( :int ) ] if not ce . rexpr . type . integral? if sizeof ( nil , ce . lexpr . type . pointed ) != 1 ptype = ce . lexpr . type p = C :: CExpression [ [ ce . lexpr ] , C :: Pointer . new ( C :: BaseType . new ( :__int8 ) ) ] ce . replace C :: CExpression [ [ p , ce . op , ce . rexpr , p . type ] , ptype ] end end } end
fix pointer arithmetic (eg int foo += 4  =>  int* foo += 1)
use struct member access (eg *(structptr+8)  =>  structptr->bla)
must be run only once, right after type setting
fix pointer arithmetic ( eg int foo + = 4 = > int * foo + = 1 ) use struct member access ( eg * ( structptr + 8 ) = > structptr - > bla ) must be run only once right after type setting
# *structptr => structptr->member # structptr + 4 => &structptr->member # ptr += 4 => ptr += 1 # ptr+x => (ptrtype*)(((__int8*)ptr)+x) # XXX create struct ?
scope