def inject(sysnr, *args)
sysnr = syscallnr[sysnr] || sysnr
syscall
puts '[*] waiting syscall'
Process.waitpid(@pid)
savedctx = CTX.inject({}) { |ctx, reg| ctx.update reg => peekusr(REGS_I386[reg]) }
eip = (savedctx['EIP'] - 2) & 0xffffffff
fu = readmem(eip, 2)
if fu == "\xcd\x80"
mode = :int80
elsif fu == "\xeb\xf3" and readmem(eip-14, 7).unpack('H*').first == "51525589e50f34"
mode = :sysenter
elsif fu == "\x0f\x05"
mode = :syscall
else
puts 'unhandled syscall convention, aborting, code = ' + readmem(eip-4, 8).unpack('H*').first
cont
return self
end
if args.length > 5
puts 'too may arguments, unsupported, aborting'
else
puts "[*] hooking #{syscallnr.index(savedctx['ORIG_EAX'])}"
esp_ptr = savedctx['ESP']
write_string = lambda { |s|
esp_ptr -= s.length
esp_ptr &= 0xffff_fff0
writemem(esp_ptr, s)
[esp_ptr].pack('L').unpack('l').first
}
set_arg = lambda { |a|
case a
when String; write_string[a + 0.chr]
when Array; write_string[a.map { |aa| set_arg[aa] }.pack('L*')]
else a
end
}
args.zip(CTX).map { |arg, reg|
pokeusr(REGS_I386[reg], set_arg[arg])
}
pokeusr(REGS_I386['ORIG_EAX'], sysnr)
syscall
Process.waitpid(@pid)
retval = peekusr(REGS_I386['EAX'])
puts "[*] retval: #{'%X' % retval}#{" (Errno::#{ERRNO.index(-retval)})" if retval < 0}"
if syscallnr.index(sysnr) == 'execve' and retval >= 0
cont
return self
end
savedctx['EIP'] -= 2
savedctx['EAX'] = savedctx['ORIG_EAX']
savedctx.each { |reg, val| pokeusr(REGS_I386[reg], val) }
end
self
end