148 lines
4.2 KiB
Ruby
Executable File
148 lines
4.2 KiB
Ruby
Executable File
#
|
|
# File:: dumpbin.rb
|
|
# Description:: Analyses COFF format executable
|
|
# If the text segment is > 32MB it will error.
|
|
# Author:: Derek Ward <derek.ward@rockstarnorth.com>
|
|
# Date:: 25th May 2012
|
|
#
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Uses / Requires
|
|
#-----------------------------------------------------------------------------
|
|
require 'pipeline/config/projects'
|
|
require 'pipeline/os/getopt'
|
|
include Pipeline
|
|
require 'systemu'
|
|
require 'fileutils'
|
|
require 'dl'
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Constants
|
|
#-----------------------------------------------------------------------------
|
|
|
|
OPTIONS = [
|
|
[ "--help", "-h", OS::Getopt::BOOLEAN, "display usage information." ],
|
|
[ "--section", "-s", OS::Getopt::OPTIONAL, "section name in executable." ],
|
|
[ "--max_size", "-m", OS::Getopt::OPTIONAL, "max size of section" ],
|
|
]
|
|
|
|
TRAILING_DESC = 'dumpbin command to run'
|
|
|
|
DEFAULT_SIZE = (32*1024*1024)
|
|
DEFAULT_SECTION = ".text"
|
|
|
|
# Message box constants
|
|
|
|
BUTTONS_OK = 0
|
|
BUTTONS_OKCANCEL = 1
|
|
BUTTONS_ABORTRETRYIGNORE = 2
|
|
BUTTONS_YESNO = 4
|
|
|
|
CLICKED_OK = 1
|
|
CLICKED_CANCEL = 2
|
|
CLICKED_ABORT = 3
|
|
CLICKED_RETRY = 4
|
|
CLICKED_IGNORE = 5
|
|
CLICKED_YES = 6
|
|
CLICKED_NO = 7
|
|
|
|
ICON_HAND = 16
|
|
ICON_QUESTION = 32
|
|
ICON_EXCLAMATION = 48
|
|
ICON_ASTERISK = 64
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Monkey Patch string class
|
|
#-----------------------------------------------------------------------------
|
|
|
|
class String
|
|
def convert_base(from, to)
|
|
self.to_i(from).to_s(to)
|
|
end
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Message Box
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def message_box(txt='', title='', buttons=0, icon=0)
|
|
user32 = DL.dlopen('user32')
|
|
msgbox = user32['MessageBoxA', 'ILSSI']
|
|
r, rs = msgbox.call(0, txt, title, buttons+icon)
|
|
return r
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Application entry point
|
|
#-----------------------------------------------------------------------------
|
|
|
|
if __FILE__ == $0
|
|
|
|
error_count = 0
|
|
|
|
begin
|
|
g_AppName = File::basename( __FILE__, '.rb' )
|
|
g_ProjectName = ''
|
|
g_BranchName = ''
|
|
g_Project = nil
|
|
|
|
#---------------------------------------------------------------------
|
|
# Parse Command Line.
|
|
#---------------------------------------------------------------------
|
|
opts, trailing = OS::Getopt.getopts( OPTIONS )
|
|
|
|
if ( opts['help'] )
|
|
puts OS::Getopt.usage( OPTIONS )
|
|
puts ("Press Enter to continue...")
|
|
$stdin.getc( )
|
|
Process.exit! 1
|
|
end
|
|
|
|
if ( ( 0 == trailing.size ) ) then
|
|
$stderr.puts 'No trailing file arguments specified. Exiting.'
|
|
puts OS::Getopt.usage( OPTIONS, { 'files' => TRAILING_DESC } )
|
|
Process.exit( 2 )
|
|
end
|
|
|
|
max_size = ( nil == opts['max_size'] ) ? DEFAULT_SIZE : opts['max_size']
|
|
section = ( nil == opts['section'] ) ? DEFAULT_SECTION : opts['section']
|
|
|
|
puts "Running #{trailing[0]}"
|
|
status, stdout, stderr = systemu( trailing[0] )
|
|
#puts "returned #{status.exitstatus}"
|
|
if ( status.exited? and ( 0 == status.exitstatus ) )
|
|
stdout.each do |line|
|
|
#puts line
|
|
regexp = Regexp.new("\\s*(\\S+)\\s+\\" + section)
|
|
if ( line =~ regexp )
|
|
size = $1.convert_base(16,10).to_i
|
|
puts ("Code size is #{size/1024}K")
|
|
if (size >= max_size)
|
|
error_str = "ERROR : .text segment is too big #{size} ( Max Size = #{max_size} ) \n*** DO NOT RUN THIS CODE IT CAN LEAD TO UNPREDICTABLE BEHAVIOUR ***"
|
|
$stderr.puts error_str
|
|
$stderr.puts stdout
|
|
message_box( error_str, "POST BUILD ERROR", BUTTONS_OK, ICON_EXCLAMATION)
|
|
Process.exit!(-1)
|
|
end
|
|
end
|
|
end
|
|
Process.exit!(0)
|
|
else
|
|
puts stdout.to_s
|
|
Process.exit!(-1)
|
|
end
|
|
|
|
rescue Exception => ex
|
|
$stderr.puts "Unhandled exception: #{ex.message}"
|
|
$stderr.puts "Backtrace:"
|
|
ex.backtrace.each { |m| $stderr.puts "\t#{m}" }
|
|
Process.exit -1
|
|
end
|
|
|
|
ret_code = ( error_count > 0 ) ? -1 : 0
|
|
|
|
Process.exit! ret_code
|
|
|
|
end #if __FILE__ == $0
|
|
|