node/lib/metasm/metasm/exe_format/elf_decode.rb
# returns a disassembler with a special decodedfunction for dlsym, __libc_start_main, and a default function (i386 only)
returns a disassembler with a special decodedfunction for dlsym, __libc_start_main, and a default function (i386 only)
returns a disassembler with a special decodedfunction for dlsym __libc_start_main and a default function ( i386 only )
def init_disassembler
		d = super()
		d.backtrace_maxblocks_data = 4
		if d.get_section_at(0)
			d.decoded[0] = true
			d.function[0] = @cpu.disassembler_default_func
		end
		case @cpu.shortname
		when 'ia32', 'x64'
			old_cp = d.c_parser
			d.c_parser = nil
			d.parse_c <<EOC
void *dlsym(int, char *);	// has special callback
// gcc's entrypoint, need pointers to reach main exe code (last callback)
void __libc_start_main(void(*)(), int, int, void(*)(), void(*)()) __attribute__((noreturn));
// standard noreturn, optimized by gcc
void __attribute__((noreturn)) exit(int);
void _exit __attribute__((noreturn))(int);
void abort(void) __attribute__((noreturn));
void __stack_chk_fail __attribute__((noreturn))(void);
EOC
			d.function[Expression['dlsym']] = dls = @cpu.decode_c_function_prototype(d.c_parser, 'dlsym')
			d.function[Expression['__libc_start_main']] = @cpu.decode_c_function_prototype(d.c_parser, '__libc_start_main')
			d.function[Expression['exit']] = @cpu.decode_c_function_prototype(d.c_parser, 'exit')
			d.function[Expression['_exit']] = @cpu.decode_c_function_prototype(d.c_parser, '_exit')
			d.function[Expression['abort']] = @cpu.decode_c_function_prototype(d.c_parser, 'abort')
			d.function[Expression['__stack_chk_fail']] = @cpu.decode_c_function_prototype(d.c_parser, '__stack_chk_fail')
			d.c_parser = old_cp
			dls.btbind_callback = lambda { |dasm, bind, funcaddr, calladdr, expr, origin, maxdepth|
				sz = @cpu.size/8
				raise 'dlsym call error' if not dasm.decoded[calladdr]
				if @cpu.shortname == 'x64'
					arg2 = :rsi
				else
					arg2 = Indirection.new(Expression[:esp, :+, 2*sz], sz, calladdr)
				end
				fnaddr = dasm.backtrace(arg2, calladdr, :include_start => true, :maxdepth => maxdepth)
				if fnaddr.kind_of? ::Array and fnaddr.length == 1 and s = dasm.get_section_at(fnaddr.first) and fn = s[0].read(64) and i = fn.index(?\0) and i > sz	
					bind = bind.merge @cpu.register_symbols[0] => Expression[fn[0, i]]
				end
				bind
			}
			df = d.function[:default] = @cpu.disassembler_default_func
			df.backtrace_binding[@cpu.register_symbols[4]] = Expression[@cpu.register_symbols[4], :+, @cpu.size/8]
			df.btbind_callback = nil
		when 'mips'
			(d.address_binding[@header.entry] ||= {})[:$t9] ||= Expression[@header.entry]
			@symbols.each { |s|
				next if s.shndx == 'UNDEF' or s.type != 'FUNC'
				(d.address_binding[s.value] ||= {})[:$t9] ||= Expression[s.value]
			}
			d.function[:default] = @cpu.disassembler_default_func
		when 'sh4'
			noret = DecodedFunction.new
			noret.noreturn = true
			%w[__stack_chk_fail abort exit].each { |fn|
				d.function[Expression[fn]] = noret
			}
			d.function[:default] = @cpu.disassembler_default_func
		end
		d
	end
def init_disassembler d = super ( ) d . backtrace_maxblocks_data = 4 if d . get_section_at ( 0 ) d . decoded [ 0 ] = true d . function [ 0 ] = @cpu . disassembler_default_func end case @cpu . shortname when 'ia32' , 'x64' old_cp = d . c_parser d . c_parser = nil d . parse_c <<EOC 
void *dlsym(int, char *);	// has special callback
// gcc's entrypoint, need pointers to reach main exe code (last callback)
void __libc_start_main(void(*)(), int, int, void(*)(), void(*)()) __attribute__((noreturn));
// standard noreturn, optimized by gcc
void __attribute__((noreturn)) exit(int);
void _exit __attribute__((noreturn))(int);
void abort(void) __attribute__((noreturn));
void __stack_chk_fail __attribute__((noreturn))(void);
 EOC d . function [ Expression [ 'dlsym' ] ] = dls = @cpu . decode_c_function_prototype ( d . c_parser , 'dlsym' ) d . function [ Expression [ '__libc_start_main' ] ] = @cpu . decode_c_function_prototype ( d . c_parser , '__libc_start_main' ) d . function [ Expression [ 'exit' ] ] = @cpu . decode_c_function_prototype ( d . c_parser , 'exit' ) d . function [ Expression [ '_exit' ] ] = @cpu . decode_c_function_prototype ( d . c_parser , '_exit' ) d . function [ Expression [ 'abort' ] ] = @cpu . decode_c_function_prototype ( d . c_parser , 'abort' ) d . function [ Expression [ '__stack_chk_fail' ] ] = @cpu . decode_c_function_prototype ( d . c_parser , '__stack_chk_fail' ) d . c_parser = old_cp dls . btbind_callback = lambda { | dasm , bind , funcaddr , calladdr , expr , origin , maxdepth | sz = @cpu . size / 8 raise 'dlsym call error' if not dasm . decoded [ calladdr ] if @cpu . shortname == 'x64' arg2 = :rsi else arg2 = Indirection . new ( Expression [ :esp , :+ , 2 * sz ] , sz , calladdr ) end fnaddr = dasm . backtrace ( arg2 , calladdr , :include_start => true , :maxdepth => maxdepth ) if fnaddr . kind_of? :: Array and fnaddr . length == 1 and s = dasm . get_section_at ( fnaddr . first ) and fn = s [ 0 ] . read ( 64 ) and i = fn . index ( ?\0 ) and i > sz bind = bind . merge @cpu . register_symbols [ 0 ] => Expression [ fn [ 0 , i ] ] end bind } df = d . function [ :default ] = @cpu . disassembler_default_func df . backtrace_binding [ @cpu . register_symbols [ 4 ] ] = Expression [ @cpu . register_symbols [ 4 ] , :+ , @cpu . size / 8 ] df . btbind_callback = nil when 'mips' ( d . address_binding [ @header . entry ] ||= { } ) [ :$t9 ] ||= Expression [ @header . entry ] @symbols . each { | s | next if s . shndx == 'UNDEF' or s . type != 'FUNC' ( d . address_binding [ s . value ] ||= { } ) [ :$t9 ] ||= Expression [ s . value ] } d . function [ :default ] = @cpu . disassembler_default_func when 'sh4' noret = DecodedFunction . new noret . noreturn = true %w[ __stack_chk_fail abort exit ] . each { | fn | d . function [ Expression [ fn ] ] = noret } d . function [ :default ] = @cpu . disassembler_default_func end d end
returns a disassembler with a special decodedfunction for dlsym, __libc_start_main, and a default function (i386 only)
returns a disassembler with a special decodedfunction for dlsym __libc_start_main and a default function ( i386 only )
# fixes call [constructor] => 0 # try to avoid ordinals