NAKANO Kouichi
knuck****@f8*****
2002年 5月 16日 (木) 22:24:45 JST
なかのです。 > もしアーカイブのサイズが4KB以下の場合は、そのまま.rubyセク > ションに埋め込めばいいのですが、4KBを越える場合、.rubyセク > ションのサイズを拡大する必要があります。このセクションサイ > ズの拡大が、面倒なのです。というか、はっきり言って無理です。 実は私はこの線で作業してます。 私としてはあと一歩の気がしてるんですが、何がそんなに面倒 なのでしょう。私が何かすごいことを見逃しているのかもしれ ません。 要は、.rubyセクションよりも後ろに位置するセクションのヘッ ダのVirtualSize、VirtualAdress、PointerToRawData、 SizeOfRawDataをずれた分だけインクリメントすればいいんです よね?SectionAlignmentを考慮して。 あとは、オプショナルヘッダを書き換える必要もありそうです が、それはこれからやろうとしてました。 まだ実行はできませんが、dumpbinやバイナリエディタで見る限 りではではセクションに関しては予期した結果を得ています。 オプショナルヘッダとはずれてるんですが...。 これだけではだめでしょうか?私も実験段階なんで自信ないで す。 末尾にパッチ付けます。(実験段階のまとまりのないコードで非 常に恥ずかしいんですが) > 末尾に.rubyセクションが位置していれば、そのまま拡大するこ > ともできますが、実際には末尾に位置することはないので拡大す > ることはできません。 同じ思考をたどりました。 > そこで、リンカによって確保された.rubyセクションは棄てるこ > とにして、コアの末尾に領域を確保し、そこを.rubyセクション > としようと思います。これによって4KBの制限を越えることがで > きます。 これはこれでシンプルでいい気もします。 以下パッチ。(送ってもらったソースに対するパッチです) Index: r2e.rb =================================================================== RCS file: /usr/local/cvsrepos/exerb/package/r2e.rb,v retrieving revision 1.2 diff -c -r1.2 r2e.rb *** r2e.rb 2002/05/14 10:48:28 1.2 --- r2e.rb 2002/05/16 13:12:08 *************** *** 7,12 **** --- 7,15 ---- # R2E Module module R2E + class ExerbError < Exception + end + #==================================================================# # Archive Class class Archive *************** *** 583,589 **** end def output(io) ! io.print(@binary) end def analyze --- 586,592 ---- end def output(io) ! io.print(pack) end def analyze *************** *** 604,609 **** --- 607,629 ---- @sections = Sections.new(@binary, @pe_header) end + def insert!(archive) + @sections.replace('.ruby', archive, @binary, section_alignment) + end + + def pack + @binary[@pe_header.offset_to_section_headers, @pe_header.number_of_sections * 40] =****@secti*****_headers + return @binary + end + + def section_alignment + @binary[offset_to_section_alignment, 4].unpack('L')[0] + end + + def offset_to_section_alignment + @offset_to_pe + @pe_header.size_of_pe_signature + @pe_header.size + 32 + end + end # Core *************** *** 611,617 **** # PEHeader Class class PEHeader ! attr_accessor :number_of_sections, :size_of_optional_header def initialize(core, offset) @offset_to_me = offset --- 631,637 ---- # PEHeader Class class PEHeader ! attr_reader :number_of_sections, :size_of_optional_header def initialize(core, offset) @offset_to_me = offset *************** *** 634,639 **** --- 654,663 ---- def offset_to_section_headers return @offset_to_me + size_of_pe_signature + 20 + size_of_optional_header end + + def size + 20 + end end #================================================================# *************** *** 650,660 **** def size_of_section_header return 40 end ! def show ! @sections.each { |section| ! puts section.show } end end --- 674,726 ---- def size_of_section_header return 40 end + + def replace(section_name, archive, binary, alignment) + section = section_named section_name + if section == nil + raise ExerbError, "no section nemed #{section_name}" + end + increment = section.replace(archive, binary, alignment) + next_sections = next_section_by_pointer_of section + next_sections.each{ |next_section| + next_section.move_pointer!(increment[0]) + } + next_sections = next_section_by_address_of section + next_sections.each{ |next_section| + next_section.move_address!(increment[1]) + } + end + + def section_named(section_name) + @sections.find { |item| item.name.index(section_name) } + end + + def next_section_by_pointer_of(section) + retur****@secti*****_all{ |item| section.header.pointer_to_raw_data < item.header.pointer_to_raw_data } + end + + def next_section_by_address_of(section) + retur****@secti*****_all{ |item| section.header.virtual_address < item.header.virtual_address } + end + + def pack_bodies_to(binary) + end + + def packed_headers + packed = '' + @sections.each{ |section| + packed.concat section.header.pack + } + return packed + end ! def packed_bodies ! sorted =****@secti*****{ |x, y| x.header.pinter_to_raw_data - y.header.pointer_to_raw_data } ! packed = '' ! sorted.each{ |section| ! packed.concat section.body } + return packed end end *************** *** 665,671 **** #================================================================# # a header of Section class Header ! attr_accessor :name, :pointer_to_raw_data, :size_of_raw_data def initialize(core, offset) @name = core[offset, 8] @virtual_size = core[offset + 8, 4].unpack('L')[0] --- 731,737 ---- #================================================================# # a header of Section class Header ! attr_accessor :name, :pointer_to_raw_data, :size_of_raw_data, :virtual_size, :virtual_address def initialize(core, offset) @name = core[offset, 8] @virtual_size = core[offset + 8, 4].unpack('L')[0] *************** *** 678,698 **** @number_of_line_numbers = core[offset + 34, 2].unpack('S')[0] @characteristics = core[offset + 36, 4].unpack('L')[0] end - end - - #================================================================# - # a body of Section - class Body - attr_accessor :body ! def initialize(core, header) ! @body = core[header.pointer_to_raw_data, header.size_of_raw_data] end end def initialize(core, offset) @header = Header.new(core, offset) ! @body = Body.new(core, @header) end end --- 744,809 ---- @number_of_line_numbers = core[offset + 34, 2].unpack('S')[0] @characteristics = core[offset + 36, 4].unpack('L')[0] end ! def pack ! packed = @name ! packed.concat [@virtual_size].pack('L') ! packed.concat [@virtual_address].pack('L') ! packed.concat [@size_of_raw_data].pack('L') ! packed.concat [@pointer_to_raw_data].pack('L') ! packed.concat [@pointer_to_relocations].pack('L') ! packed.concat [@pointer_to_line_numbers].pack('L') ! packed.concat [@number_of_relocations].pack('S') ! packed.concat [@number_of_line_numbers].pack('S') ! packed.concat [@characteristics].pack('L') ! return packed end end + attr_accessor :header + def initialize(core, offset) @header = Header.new(core, offset) ! @body = core[@header.pointer_to_raw_data, @header.size_of_raw_data] ! end ! ! def name ! retur****@heade***** ! end ! ! def replace(archive, binary, alignment) ! aligned_size = self.aligned_size(archive.size, alignment) ! increment = aligned_size -****@heade*****_of_raw_data ! old_size =****@body***** ! archive.output self ! new_size =****@body***** ! @header.virtual_size =****@body***** ! @body.concat("\0" * (aligned_size -****@body*****)) if aligned_size -****@body***** > 0 ! binary[@header.pointer_to_raw_data, @header.size_of_raw_data] = @body ! if increment > 0 ! @header.size_of_raw_data = aligned_size ! end ! return [increment, self.aligned_size(new_size - old_size, alignment)] ! end ! ! def move_pointer!(distance) ! @header.pointer_to_raw_data += distance if distance > 0 ! end ! ! def move_address!(virtual_distance) ! @header.virtual_address += virtual_distance if virtual_distance > 0 ! end ! ! def print(binary) ! @body = binary ! end ! ! def aligned_size(size, alignment) ! result = (size / alignment + 1) * alignment ! if size % alignment == 0 ! result -= alignment ! end ! return result end end *************** *** 706,711 **** --- 817,823 ---- def initialize(archive, core) @archive = archive @core = core + @core.insert! archive end #==============================================================# *************** *** 717,726 **** end def output(io) ! @core.archive_offset =****@core***** ! @core.archive_size =****@archi***** @core.output(io) ! @archive.output(io) end def output_to_file(filepath) --- 829,838 ---- end def output(io) ! #@core.archive_offset =****@core***** ! #@core.archive_size =****@archi***** @core.output(io) ! #@archive.output(io) end def output_to_file(filepath)