a copy-on-write copy of dasm address space (continuous segment only)
# File samples/dasm-plugins/selfmodify.rb, line 17 def initialize(dasm) @dasm = dasm @startaddr = 0 @data = '' end
return a substring, either from the local cache or from dasm handles overlap
# File samples/dasm-plugins/selfmodify.rb, line 25 def [](addr, len) if @data.empty? s, e = @dasm.get_section_at(addr) return if not s return s.read(len) end raddr = addr - @base rstart = @startaddr - @base if raddr >= rstart and raddr+len <= rstart+@data.length @data[0, raddr+len-rstart] else s, e = @dasm.get_section_at(addr) return if not s obuf = s.read(len) len = obuf.length if raddr < rstart and raddr+len > rstart olen = [raddr+len-rstart, @data.length].min obuf[rstart-raddr, olen] = @data[0, olen] elsif raddr < rstart+@data.length and raddr+len > rstart+@data.length obuf[0, rstart+@data.length-raddr] = @data[raddr-rstart, rstart+@data.length-raddr] end obuf end end
set a substring value in the cache
# File samples/dasm-plugins/selfmodify.rb, line 51 def []=(addr, len, newdata) raise 'len mismatch' if len != newdata.length if @data.empty? @base = @startaddr = addr @data << newdata return end raddr = addr - @base rstart = @startaddr - @base if raddr+newdata.length < rstart s, e = @dasm.get_section_at(addr) raise if not s obuf = s.read(rstart-(raddr+newdata.length)) raise if obuf.length != rstart-(raddr+newdata.length) newdata += obuf elsif raddr > rstart+@data.length s, e = @dasm.get_section_at(@startaddr+@data.length) raise if not s obuf = s.read(raddr-(rstart+@data.length)) raise if obuf.length != raddr-(rstart+@data.length) @data += obuf end if raddr < rstart @data = newdata + @data[raddr+newdata.length-rstart..-1].to_s @startaddr = addr else @data[raddr-rstart, newdata.length] = newdata end end