metasm 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/BUGS +11 -0
- data/CREDITS +17 -0
- data/README +270 -0
- data/TODO +114 -0
- data/doc/code_organisation.txt +146 -0
- data/doc/const_missing.txt +16 -0
- data/doc/core_classes.txt +75 -0
- data/doc/feature_list.txt +53 -0
- data/doc/index.txt +59 -0
- data/doc/install_notes.txt +170 -0
- data/doc/style.css +3 -0
- data/doc/use_cases.txt +18 -0
- data/lib/metasm.rb +80 -0
- data/lib/metasm/arm.rb +12 -0
- data/lib/metasm/arm/debug.rb +39 -0
- data/lib/metasm/arm/decode.rb +167 -0
- data/lib/metasm/arm/encode.rb +77 -0
- data/lib/metasm/arm/main.rb +75 -0
- data/lib/metasm/arm/opcodes.rb +177 -0
- data/lib/metasm/arm/parse.rb +130 -0
- data/lib/metasm/arm/render.rb +55 -0
- data/lib/metasm/compile_c.rb +1457 -0
- data/lib/metasm/dalvik.rb +8 -0
- data/lib/metasm/dalvik/decode.rb +196 -0
- data/lib/metasm/dalvik/main.rb +60 -0
- data/lib/metasm/dalvik/opcodes.rb +366 -0
- data/lib/metasm/decode.rb +213 -0
- data/lib/metasm/decompile.rb +2659 -0
- data/lib/metasm/disassemble.rb +2068 -0
- data/lib/metasm/disassemble_api.rb +1280 -0
- data/lib/metasm/dynldr.rb +1329 -0
- data/lib/metasm/encode.rb +333 -0
- data/lib/metasm/exe_format/a_out.rb +194 -0
- data/lib/metasm/exe_format/autoexe.rb +82 -0
- data/lib/metasm/exe_format/bflt.rb +189 -0
- data/lib/metasm/exe_format/coff.rb +455 -0
- data/lib/metasm/exe_format/coff_decode.rb +901 -0
- data/lib/metasm/exe_format/coff_encode.rb +1078 -0
- data/lib/metasm/exe_format/dex.rb +457 -0
- data/lib/metasm/exe_format/dol.rb +145 -0
- data/lib/metasm/exe_format/elf.rb +923 -0
- data/lib/metasm/exe_format/elf_decode.rb +979 -0
- data/lib/metasm/exe_format/elf_encode.rb +1375 -0
- data/lib/metasm/exe_format/macho.rb +827 -0
- data/lib/metasm/exe_format/main.rb +228 -0
- data/lib/metasm/exe_format/mz.rb +164 -0
- data/lib/metasm/exe_format/nds.rb +172 -0
- data/lib/metasm/exe_format/pe.rb +437 -0
- data/lib/metasm/exe_format/serialstruct.rb +246 -0
- data/lib/metasm/exe_format/shellcode.rb +114 -0
- data/lib/metasm/exe_format/xcoff.rb +167 -0
- data/lib/metasm/gui.rb +23 -0
- data/lib/metasm/gui/cstruct.rb +373 -0
- data/lib/metasm/gui/dasm_coverage.rb +199 -0
- data/lib/metasm/gui/dasm_decomp.rb +369 -0
- data/lib/metasm/gui/dasm_funcgraph.rb +103 -0
- data/lib/metasm/gui/dasm_graph.rb +1354 -0
- data/lib/metasm/gui/dasm_hex.rb +543 -0
- data/lib/metasm/gui/dasm_listing.rb +599 -0
- data/lib/metasm/gui/dasm_main.rb +906 -0
- data/lib/metasm/gui/dasm_opcodes.rb +291 -0
- data/lib/metasm/gui/debug.rb +1228 -0
- data/lib/metasm/gui/gtk.rb +884 -0
- data/lib/metasm/gui/qt.rb +495 -0
- data/lib/metasm/gui/win32.rb +3004 -0
- data/lib/metasm/gui/x11.rb +621 -0
- data/lib/metasm/ia32.rb +14 -0
- data/lib/metasm/ia32/compile_c.rb +1523 -0
- data/lib/metasm/ia32/debug.rb +193 -0
- data/lib/metasm/ia32/decode.rb +1167 -0
- data/lib/metasm/ia32/decompile.rb +564 -0
- data/lib/metasm/ia32/encode.rb +314 -0
- data/lib/metasm/ia32/main.rb +233 -0
- data/lib/metasm/ia32/opcodes.rb +872 -0
- data/lib/metasm/ia32/parse.rb +327 -0
- data/lib/metasm/ia32/render.rb +91 -0
- data/lib/metasm/main.rb +1193 -0
- data/lib/metasm/mips.rb +11 -0
- data/lib/metasm/mips/compile_c.rb +7 -0
- data/lib/metasm/mips/decode.rb +253 -0
- data/lib/metasm/mips/encode.rb +51 -0
- data/lib/metasm/mips/main.rb +72 -0
- data/lib/metasm/mips/opcodes.rb +443 -0
- data/lib/metasm/mips/parse.rb +51 -0
- data/lib/metasm/mips/render.rb +43 -0
- data/lib/metasm/os/gnu_exports.rb +270 -0
- data/lib/metasm/os/linux.rb +1112 -0
- data/lib/metasm/os/main.rb +1686 -0
- data/lib/metasm/os/remote.rb +527 -0
- data/lib/metasm/os/windows.rb +2027 -0
- data/lib/metasm/os/windows_exports.rb +745 -0
- data/lib/metasm/parse.rb +876 -0
- data/lib/metasm/parse_c.rb +3938 -0
- data/lib/metasm/pic16c/decode.rb +42 -0
- data/lib/metasm/pic16c/main.rb +17 -0
- data/lib/metasm/pic16c/opcodes.rb +68 -0
- data/lib/metasm/ppc.rb +11 -0
- data/lib/metasm/ppc/decode.rb +264 -0
- data/lib/metasm/ppc/decompile.rb +251 -0
- data/lib/metasm/ppc/encode.rb +51 -0
- data/lib/metasm/ppc/main.rb +129 -0
- data/lib/metasm/ppc/opcodes.rb +410 -0
- data/lib/metasm/ppc/parse.rb +52 -0
- data/lib/metasm/preprocessor.rb +1277 -0
- data/lib/metasm/render.rb +130 -0
- data/lib/metasm/sh4.rb +8 -0
- data/lib/metasm/sh4/decode.rb +336 -0
- data/lib/metasm/sh4/main.rb +292 -0
- data/lib/metasm/sh4/opcodes.rb +381 -0
- data/lib/metasm/x86_64.rb +12 -0
- data/lib/metasm/x86_64/compile_c.rb +1025 -0
- data/lib/metasm/x86_64/debug.rb +59 -0
- data/lib/metasm/x86_64/decode.rb +268 -0
- data/lib/metasm/x86_64/encode.rb +264 -0
- data/lib/metasm/x86_64/main.rb +135 -0
- data/lib/metasm/x86_64/opcodes.rb +118 -0
- data/lib/metasm/x86_64/parse.rb +68 -0
- data/misc/bottleneck.rb +61 -0
- data/misc/cheader-findpppath.rb +58 -0
- data/misc/hexdiff.rb +74 -0
- data/misc/hexdump.rb +55 -0
- data/misc/metasm-all.rb +13 -0
- data/misc/objdiff.rb +47 -0
- data/misc/objscan.rb +40 -0
- data/misc/pdfparse.rb +661 -0
- data/misc/ppc_pdf2oplist.rb +192 -0
- data/misc/tcp_proxy_hex.rb +84 -0
- data/misc/txt2html.rb +440 -0
- data/samples/a.out.rb +31 -0
- data/samples/asmsyntax.rb +77 -0
- data/samples/bindiff.rb +555 -0
- data/samples/compilation-steps.rb +49 -0
- data/samples/cparser_makestackoffset.rb +55 -0
- data/samples/dasm-backtrack.rb +38 -0
- data/samples/dasmnavig.rb +318 -0
- data/samples/dbg-apihook.rb +228 -0
- data/samples/dbghelp.rb +143 -0
- data/samples/disassemble-gui.rb +102 -0
- data/samples/disassemble.rb +133 -0
- data/samples/dump_upx.rb +95 -0
- data/samples/dynamic_ruby.rb +1929 -0
- data/samples/elf_list_needed.rb +46 -0
- data/samples/elf_listexports.rb +33 -0
- data/samples/elfencode.rb +25 -0
- data/samples/exeencode.rb +128 -0
- data/samples/factorize-headers-elfimports.rb +77 -0
- data/samples/factorize-headers-peimports.rb +109 -0
- data/samples/factorize-headers.rb +43 -0
- data/samples/gdbclient.rb +583 -0
- data/samples/generate_libsigs.rb +102 -0
- data/samples/hotfix_gtk_dbg.rb +59 -0
- data/samples/install_win_env.rb +78 -0
- data/samples/lindebug.rb +924 -0
- data/samples/linux_injectsyscall.rb +95 -0
- data/samples/machoencode.rb +31 -0
- data/samples/metasm-shell.rb +91 -0
- data/samples/pe-hook.rb +69 -0
- data/samples/pe-ia32-cpuid.rb +203 -0
- data/samples/pe-mips.rb +35 -0
- data/samples/pe-shutdown.rb +78 -0
- data/samples/pe-testrelocs.rb +51 -0
- data/samples/pe-testrsrc.rb +24 -0
- data/samples/pe_listexports.rb +31 -0
- data/samples/peencode.rb +19 -0
- data/samples/peldr.rb +494 -0
- data/samples/preprocess-flatten.rb +19 -0
- data/samples/r0trace.rb +308 -0
- data/samples/rubstop.rb +399 -0
- data/samples/scan_pt_gnu_stack.rb +54 -0
- data/samples/scanpeexports.rb +62 -0
- data/samples/shellcode-c.rb +40 -0
- data/samples/shellcode-dynlink.rb +146 -0
- data/samples/source.asm +34 -0
- data/samples/struct_offset.rb +47 -0
- data/samples/testpe.rb +32 -0
- data/samples/testraw.rb +45 -0
- data/samples/win32genloader.rb +132 -0
- data/samples/win32hooker-advanced.rb +169 -0
- data/samples/win32hooker.rb +96 -0
- data/samples/win32livedasm.rb +33 -0
- data/samples/win32remotescan.rb +133 -0
- data/samples/wintrace.rb +92 -0
- data/tests/all.rb +8 -0
- data/tests/dasm.rb +39 -0
- data/tests/dynldr.rb +35 -0
- data/tests/encodeddata.rb +132 -0
- data/tests/ia32.rb +82 -0
- data/tests/mips.rb +116 -0
- data/tests/parse_c.rb +239 -0
- data/tests/preprocessor.rb +269 -0
- data/tests/x86_64.rb +62 -0
- metadata +255 -0
@@ -0,0 +1,51 @@
|
|
1
|
+
# This file is part of Metasm, the Ruby assembly manipulation suite
|
2
|
+
# Copyright (C) 2006-2009 Yoann GUILLOT
|
3
|
+
#
|
4
|
+
# Licence is LGPL, see LICENCE in the top-level directory
|
5
|
+
|
6
|
+
|
7
|
+
require 'metasm/mips/opcodes'
|
8
|
+
require 'metasm/parse'
|
9
|
+
|
10
|
+
module Metasm
|
11
|
+
class MIPS
|
12
|
+
def parse_arg_valid?(op, sym, arg)
|
13
|
+
# special case for lw reg, imm32(reg) ? (pseudo-instr, need to convert to 'lui t0, up imm32 ori t0 down imm32 add t0, reg lw reg, 0(t0)
|
14
|
+
case sym
|
15
|
+
when :rs, :rt, :rd; arg.kind_of? Reg
|
16
|
+
when :sa, :i16, :i20, :i26; arg.kind_of? Expression
|
17
|
+
when :rs_i16; arg.kind_of? Memref
|
18
|
+
when :ft; arg.kind_of? FpReg
|
19
|
+
else raise "internal error: mips arg #{sym.inspect}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def parse_argument(pgm)
|
24
|
+
pgm.skip_space
|
25
|
+
return if not tok = pgm.nexttok
|
26
|
+
if tok.type == :string and Reg.s_to_i[tok.raw]
|
27
|
+
pgm.readtok
|
28
|
+
arg = Reg.new Reg.s_to_i[tok.raw]
|
29
|
+
elsif tok.type == :string and FpReg.s_to_i[tok.raw]
|
30
|
+
pgm.readtok
|
31
|
+
arg = FpReg.new FpReg.s_to_i[tok.raw]
|
32
|
+
else
|
33
|
+
arg = Expression.parse pgm
|
34
|
+
pgm.skip_space
|
35
|
+
# check memory indirection: 'off(base reg)' # XXX scaled index ?
|
36
|
+
if arg and pgm.nexttok and pgm.nexttok.type == :punct and pgm.nexttok.raw == '('
|
37
|
+
pgm.readtok
|
38
|
+
pgm.skip_space_eol
|
39
|
+
ntok = pgm.readtok
|
40
|
+
raise tok, "Invalid base #{ntok}" unless ntok and ntok.type == :string and Reg.s_to_i[ntok.raw]
|
41
|
+
base = Reg.new Reg.s_to_i[ntok.raw]
|
42
|
+
pgm.skip_space_eol
|
43
|
+
ntok = pgm.readtok
|
44
|
+
raise tok, "Invalid memory reference, ')' expected" if not ntok or ntok.type != :punct or ntok.raw != ')'
|
45
|
+
arg = Memref.new base, arg
|
46
|
+
end
|
47
|
+
end
|
48
|
+
arg
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# This file is part of Metasm, the Ruby assembly manipulation suite
|
2
|
+
# Copyright (C) 2006-2009 Yoann GUILLOT
|
3
|
+
#
|
4
|
+
# Licence is LGPL, see LICENCE in the top-level directory
|
5
|
+
|
6
|
+
|
7
|
+
require 'metasm/mips/opcodes'
|
8
|
+
require 'metasm/render'
|
9
|
+
|
10
|
+
module Metasm
|
11
|
+
class MIPS
|
12
|
+
class Reg
|
13
|
+
include Renderable
|
14
|
+
def render ; [self.class.i_to_s[@i]] end
|
15
|
+
end
|
16
|
+
class FpReg
|
17
|
+
include Renderable
|
18
|
+
def render ; [self.class.i_to_s[@i]] end
|
19
|
+
end
|
20
|
+
class Memref
|
21
|
+
include Renderable
|
22
|
+
def render ; [@offset, '(', @base, ')'] end
|
23
|
+
end
|
24
|
+
|
25
|
+
def render_instruction(i)
|
26
|
+
r = []
|
27
|
+
r << i.opname
|
28
|
+
if not i.args.empty?
|
29
|
+
r << ' '
|
30
|
+
if (a = i.args.first).kind_of? Expression and a.op == :- and a.lexpr.kind_of? String and a.rexpr.kind_of? String and opcode_list_byname[i.opname].first.props[:setip]
|
31
|
+
# jmp foo is stored as jmp foo - bar ; bar:
|
32
|
+
r << a.lexpr
|
33
|
+
else
|
34
|
+
i.args.each { |a_|
|
35
|
+
r << a_ << ', '
|
36
|
+
}
|
37
|
+
r.pop
|
38
|
+
end
|
39
|
+
end
|
40
|
+
r
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,270 @@
|
|
1
|
+
# This file is part of Metasm, the Ruby assembly manipulation suite
|
2
|
+
# Copyright (C) 2006-2009 Yoann GUILLOT
|
3
|
+
#
|
4
|
+
# Licence is LGPL, see LICENCE in the top-level directory
|
5
|
+
|
6
|
+
|
7
|
+
module Metasm
|
8
|
+
class GNUExports
|
9
|
+
# exported symbol name => exporting library name for common libraries
|
10
|
+
# used by ELF#automagic_symbols
|
11
|
+
EXPORT = {}
|
12
|
+
# see samples/elf_listexports for the generator of this data
|
13
|
+
data = <<EOL # XXX libraries do not support __END__/DATA...
|
14
|
+
libc.so.6
|
15
|
+
_IO_adjust_column _IO_adjust_wcolumn _IO_default_doallocate _IO_default_finish _IO_default_pbackfail _IO_default_uflow _IO_default_xsgetn _IO_default_xsputn
|
16
|
+
_IO_do_write _IO_do_write _IO_doallocbuf _IO_fclose _IO_fclose _IO_fdopen _IO_fdopen _IO_feof _IO_ferror _IO_fflush _IO_fgetpos _IO_fgetpos _IO_fgetpos64
|
17
|
+
_IO_fgetpos64 _IO_fgets _IO_file_attach _IO_file_attach _IO_file_close _IO_file_close_it _IO_file_close_it _IO_file_doallocate _IO_file_finish _IO_file_fopen
|
18
|
+
_IO_file_fopen _IO_file_init _IO_file_init _IO_file_open _IO_file_overflow _IO_file_overflow _IO_file_read _IO_file_seek _IO_file_seekoff _IO_file_seekoff
|
19
|
+
_IO_file_setbuf _IO_file_setbuf _IO_file_stat _IO_file_sync _IO_file_sync _IO_file_underflow _IO_file_underflow _IO_file_write _IO_file_write _IO_file_xsputn
|
20
|
+
_IO_file_xsputn _IO_flockfile _IO_flush_all _IO_flush_all_linebuffered _IO_fopen _IO_fopen _IO_fputs _IO_fread _IO_free_backup_area _IO_free_wbackup_area
|
21
|
+
_IO_fsetpos _IO_fsetpos _IO_fsetpos64 _IO_fsetpos64 _IO_ftell _IO_ftrylockfile _IO_funlockfile _IO_fwrite _IO_getc _IO_getline _IO_getline_info _IO_gets
|
22
|
+
_IO_init _IO_init_marker _IO_init_wmarker _IO_iter_begin _IO_iter_end _IO_iter_file _IO_iter_next _IO_least_wmarker _IO_link_in _IO_list_lock
|
23
|
+
_IO_list_resetlock _IO_list_unlock _IO_marker_delta _IO_marker_difference _IO_padn _IO_peekc_locked _IO_popen _IO_popen _IO_printf _IO_proc_close
|
24
|
+
_IO_proc_close _IO_proc_open _IO_proc_open _IO_putc _IO_puts _IO_remove_marker _IO_seekmark _IO_seekoff _IO_seekpos _IO_seekwmark _IO_setb _IO_setbuffer
|
25
|
+
_IO_setvbuf _IO_sgetn _IO_sprintf _IO_sputbackc _IO_sputbackwc _IO_sscanf _IO_str_init_readonly _IO_str_init_static _IO_str_overflow _IO_str_pbackfail
|
26
|
+
_IO_str_seekoff _IO_str_underflow _IO_sungetc _IO_sungetwc _IO_switch_to_get_mode _IO_switch_to_main_wget_area _IO_switch_to_wbackup_area
|
27
|
+
_IO_switch_to_wget_mode _IO_un_link _IO_ungetc _IO_unsave_markers _IO_unsave_wmarkers _IO_vfprintf _IO_vfscanf _IO_vsprintf _IO_wdefault_doallocate
|
28
|
+
_IO_wdefault_finish _IO_wdefault_pbackfail _IO_wdefault_uflow _IO_wdefault_xsgetn _IO_wdefault_xsputn _IO_wdo_write _IO_wdoallocbuf _IO_wfile_overflow
|
29
|
+
_IO_wfile_seekoff _IO_wfile_sync _IO_wfile_underflow _IO_wfile_xsputn _IO_wmarker_delta _IO_wsetb _Unwind_Find_FDE __adjtimex __argz_count __argz_next
|
30
|
+
__argz_stringify __asprintf __assert __assert_fail __assert_perror_fail __backtrace __backtrace_symbols __backtrace_symbols_fd __bsd_getpgrp __bzero
|
31
|
+
__chk_fail __clone __cmpdi2 __cmsg_nxthdr __confstr_chk __ctype_b_loc __ctype_tolower_loc __ctype_toupper_loc __cxa_atexit __cxa_finalize
|
32
|
+
__cyg_profile_func_enter __cyg_profile_func_exit __dcgettext __default_morecore __deregister_frame __deregister_frame_info __deregister_frame_info_bases
|
33
|
+
__dgettext __divdi3 __dup2 __duplocale __endmntent __errno_location __fbufsize __ffs __fgets_chk __fgets_unlocked_chk __fgetws_chk __fgetws_unlocked_chk
|
34
|
+
__finite __finitef __finitel __fixunsdfdi __fixunsxfdi __flbf __floatdidf __fork __fpending __fprintf_chk __fpurge __frame_state_for __freadable __freading
|
35
|
+
__freelocale __fsetlocking __fwprintf_chk __fwritable __fwriting __fxstat __fxstat64 __fxstat64 __fxstatat __fxstatat64 __gai_sigqueue __gconv_get_alias_db
|
36
|
+
__gconv_get_cache __gconv_get_modules_db __getcwd_chk __getdomainname_chk __getgroups_chk __gethostname_chk __getlogin_r_chk __getmntent_r __getpagesize
|
37
|
+
__getpgid __getpid __gets_chk __gettimeofday __getwd_chk __gmtime_r __h_errno_location __internal_endnetgrent __internal_getnetgrent_r __internal_setnetgrent
|
38
|
+
__isalnum_l __isalpha_l __isblank_l __iscntrl_l __isctype __isdigit_l __isgraph_l __isinf __isinff __isinfl __islower_l __isnan __isnanf __isnanl __isprint_l
|
39
|
+
__ispunct_l __isspace_l __isupper_l __iswalnum_l __iswalpha_l __iswblank_l __iswcntrl_l __iswctype __iswctype_l __iswdigit_l __iswgraph_l __iswlower_l
|
40
|
+
__iswprint_l __iswpunct_l __iswspace_l __iswupper_l __iswxdigit_l __isxdigit_l __ivaliduser __libc_allocate_rtsig __libc_allocate_rtsig_private __libc_calloc
|
41
|
+
__libc_current_sigrtmax __libc_current_sigrtmax_private __libc_current_sigrtmin __libc_current_sigrtmin_private __libc_dl_error_tsd __libc_dlclose
|
42
|
+
__libc_dlopen_mode __libc_dlsym __libc_fatal __libc_fork __libc_free __libc_freeres __libc_init_first __libc_longjmp __libc_mallinfo __libc_malloc
|
43
|
+
__libc_mallopt __libc_memalign __libc_msgrcv __libc_msgsnd __libc_pthread_init __libc_pvalloc __libc_pwrite __libc_realloc __libc_sa_len __libc_siglongjmp
|
44
|
+
__libc_start_main __libc_system __libc_thread_freeres __libc_valloc __lxstat __lxstat64 __lxstat64 __mbrlen __mbrtowc __mbsnrtowcs_chk __mbsrtowcs_chk
|
45
|
+
__mbstowcs_chk __memcpy_by2 __memcpy_by4 __memcpy_c __memcpy_chk __memcpy_g __memmove_chk __mempcpy __mempcpy_by2 __mempcpy_by4 __mempcpy_byn __mempcpy_chk
|
46
|
+
__mempcpy_small __memset_cc __memset_ccn_by2 __memset_ccn_by4 __memset_cg __memset_chk __memset_gcn_by2 __memset_gcn_by4 __memset_gg __moddi3 __modify_ldt
|
47
|
+
__monstartup __newlocale __nl_langinfo_l __nss_configure_lookup __nss_database_lookup __nss_disable_nscd __nss_group_lookup __nss_hostname_digits_dots
|
48
|
+
__nss_hosts_lookup __nss_lookup_function __nss_next __nss_passwd_lookup __nss_services_lookup __open_catalog __overflow __pipe __poll __pread64_chk
|
49
|
+
__pread_chk __printf_chk __printf_fp __profile_frequency __ptsname_r_chk __rawmemchr __read_chk __readlink_chk __readlinkat_chk __realpath_chk __recv_chk
|
50
|
+
__recvfrom_chk __register_atfork __register_frame __register_frame_info __register_frame_info_bases __register_frame_info_table
|
51
|
+
__register_frame_info_table_bases __register_frame_table __res_iclose __res_init __res_maybe_init __res_nclose __res_ninit __res_randomid __res_state
|
52
|
+
__rpc_thread_createerr __rpc_thread_svc_fdset __rpc_thread_svc_max_pollfd __rpc_thread_svc_pollfd __sbrk __sched_cpucount __sched_get_priority_max
|
53
|
+
__sched_get_priority_min __sched_getparam __sched_getscheduler __sched_setscheduler __sched_yield __secure_getenv __select __setmntent __setpgid __sigaddset
|
54
|
+
__sigdelset __sigismember __signbit __signbitf __signbitl __sigpause __sigsetjmp __sigsuspend __snprintf_chk __sprintf_chk __stack_chk_fail __statfs __stpcpy
|
55
|
+
__stpcpy_chk __stpcpy_g __stpcpy_small __stpncpy __stpncpy_chk __strcasecmp __strcasecmp_l __strcasestr __strcat_c __strcat_chk __strcat_g __strchr_c
|
56
|
+
__strchr_g __strchrnul_c __strchrnul_g __strcmp_gg __strcoll_l __strcpy_chk __strcpy_g __strcpy_small __strcspn_c1 __strcspn_c2 __strcspn_c3 __strcspn_cg
|
57
|
+
__strcspn_g __strdup __strerror_r __strfmon_l __strftime_l __strlen_g __strncasecmp_l __strncat_chk __strncat_g __strncmp_g __strncpy_by2 __strncpy_by4
|
58
|
+
__strncpy_byn __strncpy_chk __strncpy_gg __strndup __strpbrk_c2 __strpbrk_c3 __strpbrk_cg __strpbrk_g __strrchr_c __strrchr_g __strsep_1c __strsep_2c
|
59
|
+
__strsep_3c __strsep_g __strspn_c1 __strspn_c2 __strspn_c3 __strspn_cg __strspn_g __strstr_cg __strstr_g __strtod_internal __strtof_internal __strtok_r
|
60
|
+
__strtok_r_1c __strtol_internal __strtold_internal __strtoll_internal __strtoq_internal __strtoul_internal __strtoull_internal __strtouq_internal __strverscmp
|
61
|
+
__strxfrm_l __swprintf_chk __sysconf __sysctl __syslog_chk __sysv_signal __tolower_l __toupper_l __towctrans __towctrans_l __towlower_l __towupper_l
|
62
|
+
__ttyname_r_chk __ucmpdi2 __udivdi3 __uflow __umoddi3 __underflow __uselocale __vfork __vfprintf_chk __vfscanf __vfwprintf_chk __vprintf_chk __vsnprintf_chk
|
63
|
+
__vsprintf_chk __vswprintf_chk __vsyslog_chk __vwprintf_chk __waitpid __wcpcpy_chk __wcpncpy_chk __wcrtomb_chk __wcscasecmp_l __wcscat_chk __wcscoll_l
|
64
|
+
__wcscpy_chk __wcsftime_l __wcsncasecmp_l __wcsncat_chk __wcsncpy_chk __wcsnrtombs_chk __wcsrtombs_chk __wcstod_internal __wcstof_internal __wcstol_internal
|
65
|
+
__wcstold_internal __wcstoll_internal __wcstombs_chk __wcstoul_internal __wcstoull_internal __wcsxfrm_l __wctomb_chk __wctrans_l __wctype_l __wmemcpy_chk
|
66
|
+
__wmemmove_chk __wmempcpy_chk __wmemset_chk __woverflow __wprintf_chk __wuflow __wunderflow __xmknod __xmknodat __xpg_basename __xpg_strerror_r __xstat
|
67
|
+
__xstat64 __xstat64 _authenticate _dl_addr _dl_mcount_wrapper _dl_mcount_wrapper_check _dl_sym _dl_vsym _exit _mcleanup _mcount _nss_files_parse_grent
|
68
|
+
_nss_files_parse_pwent _nss_files_parse_spent _obstack_allocated_p _obstack_begin _obstack_begin_1 _obstack_free _obstack_memory_used _obstack_newchunk
|
69
|
+
_rpc_dtablesize _seterr_reply _setjmp _tolower _toupper a64l abort abs acct addseverity alarm alphasort alphasort64 alphasort64 argz_delete asctime atexit
|
70
|
+
atof atoi atol atoll authdes_create authdes_getucred authdes_pk_create authnone_create authunix_create authunix_create_default basename bcopy bdflush bind
|
71
|
+
bindresvport bsearch callrpc capget capset catclose catgets catopen cbc_crypt cfgetispeed cfgetospeed cfmakeraw cfsetispeed cfsetospeed cfsetspeed chflags
|
72
|
+
chown chown chroot clearerr clearerr_unlocked clnt_broadcast clnt_create clnt_pcreateerror clnt_perrno clnt_perror clnt_spcreateerror clnt_sperrno
|
73
|
+
clnt_sperror clntraw_create clnttcp_create clntudp_bufcreate clntudp_create clntunix_create clock closelog confstr creat64 create_module ctermid ctime ctime_r
|
74
|
+
cuserid daemon delete_module des_setparity difftime dirfd dirname div dprintf drand48 drand48_r dysize ecb_crypt ecvt ecvt_r endaliasent endfsent endgrent
|
75
|
+
endhostent endnetent endnetgrent endprotoent endpwent endrpcent endservent endspent endttyent endusershell endutxent envz_add envz_entry envz_get envz_merge
|
76
|
+
envz_remove envz_strip epoll_create epoll_ctl epoll_pwait epoll_wait erand48 err errx ether_aton ether_aton_r ether_hostton ether_line ether_ntoa ether_ntoa_r
|
77
|
+
ether_ntohost execl execle execlp execv execvp exit faccessat fattach fchflags fchmodat fchownat fclose fclose fcvt fcvt_r fdatasync fdetach fdopen fdopen
|
78
|
+
feof_unlocked ferror_unlocked fexecve fflush_unlocked ffs ffsll fgetgrent fgetpos fgetpos fgetpos64 fgetpos64 fgetpwent fgets_unlocked fgetspent fgetws
|
79
|
+
fgetws_unlocked fgetxattr fileno flistxattr fmemopen fmtmsg fnmatch fnmatch fopen fopen fopencookie fopencookie fprintf fputc fputc_unlocked fputs_unlocked
|
80
|
+
fputwc fputwc_unlocked fputws fputws_unlocked fread_unlocked free freeaddrinfo freeifaddrs fremovexattr freopen freopen64 fscanf fseek fseeko fseeko64 fsetpos
|
81
|
+
fsetpos fsetpos64 fsetpos64 fsetxattr fstatvfs ftello ftello64 ftime ftok fts_children fts_close fts_open fts_read fts_set ftw ftw64 futimens futimesat fwide
|
82
|
+
fwrite_unlocked fwscanf gai_strerror gcvt get_current_dir_name get_kernel_syms get_myaddress getaddrinfo getaliasbyname getaliasbyname_r getaliasbyname_r
|
83
|
+
getaliasent getaliasent_r getaliasent_r getchar getchar_unlocked getdate getdirentries getdirentries64 getdomainname getenv getfsent getfsfile getfsspec
|
84
|
+
getgrent getgrent_r getgrent_r getgrgid getgrgid_r getgrgid_r getgrnam getgrnam_r getgrnam_r getgrouplist gethostbyaddr gethostbyaddr_r gethostbyaddr_r
|
85
|
+
gethostbyname gethostbyname2 gethostbyname2_r gethostbyname2_r gethostbyname_r gethostbyname_r gethostent gethostent_r gethostent_r gethostid getifaddrs
|
86
|
+
getipv4sourcefilter getloadavg getlogin getlogin_r getmntent getmsg getnameinfo getnetbyaddr getnetbyaddr_r getnetbyaddr_r getnetbyname getnetbyname_r
|
87
|
+
getnetbyname_r getnetent getnetent_r getnetent_r getnetgrent getnetname getopt getopt_long getopt_long_only getpass getpgrp getpid getpmsg getpriority
|
88
|
+
getprotobyname getprotobyname_r getprotobyname_r getprotobynumber getprotobynumber_r getprotobynumber_r getprotoent getprotoent_r getprotoent_r getpublickey
|
89
|
+
getpwent getpwent_r getpwent_r getpwnam getpwnam_r getpwnam_r getpwuid getpwuid_r getpwuid_r getrlimit getrlimit getrlimit64 getrlimit64 getrpcbyname
|
90
|
+
getrpcbyname_r getrpcbyname_r getrpcbynumber getrpcbynumber_r getrpcbynumber_r getrpcent getrpcent_r getrpcent_r getrpcport getsecretkey getservbyname
|
91
|
+
getservbyname_r getservbyname_r getservbyport getservbyport_r getservbyport_r getservent getservent_r getservent_r getsid getsockname getsourcefilter getspent
|
92
|
+
getspent_r getspent_r getspnam getspnam_r getspnam_r getsubopt getttyent getttynam getusershell getutmp getutmpx getutxent getutxid getutxline getw getwchar
|
93
|
+
getwchar_unlocked getwd getxattr glob glob64 glob64 globfree globfree64 gmtime gnu_dev_major gnu_dev_makedev gnu_dev_minor grantpt gtty hcreate hcreate_r
|
94
|
+
hdestroy_r herror host2netname hsearch hsearch_r hstrerror htonl htons iconv iconv_close iconv_open if_freenameindex if_indextoname if_nameindex
|
95
|
+
if_nametoindex inet6_opt_append inet6_opt_find inet6_opt_finish inet6_opt_get_val inet6_opt_init inet6_opt_next inet6_opt_set_val inet6_option_alloc
|
96
|
+
inet6_option_append inet6_option_find inet6_option_init inet6_option_next inet6_option_space inet6_rth_add inet6_rth_getaddr inet6_rth_init inet6_rth_reverse
|
97
|
+
inet6_rth_segments inet6_rth_space inet_addr inet_lnaof inet_makeaddr inet_netof inet_network inet_nsap_addr inet_nsap_ntoa inet_ntoa inet_ntop inet_pton
|
98
|
+
init_module initgroups innetgr inotify_add_watch inotify_init inotify_rm_watch insque ioperm iopl iruserok iruserok_af isalnum isalpha isascii isastream
|
99
|
+
isblank iscntrl isdigit isfdtype isgraph islower isprint ispunct isspace isupper isxdigit jrand48 key_decryptsession key_decryptsession_pk key_encryptsession
|
100
|
+
key_encryptsession_pk key_gendes key_get_conv key_secretkey_is_set key_setnet key_setsecret killpg klogctl l64a labs lchmod lcong48 ldiv lfind lgetxattr
|
101
|
+
linkat listen listxattr llabs lldiv llistxattr localeconv localeconv localtime lockf lockf64 lrand48 lrand48_r lremovexattr lsearch lsetxattr lutimes madvise
|
102
|
+
malloc mblen mbstowcs mbtowc mcheck mcheck_check_all mcheck_pedantic memcmp memcpy memfrob memmem memmove mempcpy memset mincore mkdirat mkdtemp mkfifo
|
103
|
+
mkfifoat mkstemp mkstemp64 mktemp mktime mlock mlockall mprobe mrand48 mrand48_r msgctl msgctl msgget mtrace munlock munlockall muntrace netname2host
|
104
|
+
netname2user nfsservctl nftw nftw nftw64 nftw64 nice nl_langinfo nrand48 ntp_gettime obstack_free open_memstream open_wmemstream openlog parse_printf_format
|
105
|
+
passwd2des pclose pclose perror pivot_root pmap_getmaps pmap_getport pmap_rmtcall pmap_set pmap_unset popen popen posix_fadvise posix_fadvise64
|
106
|
+
posix_fadvise64 posix_fallocate posix_fallocate64 posix_fallocate64 posix_madvise posix_spawn posix_spawn_file_actions_addclose
|
107
|
+
posix_spawn_file_actions_adddup2 posix_spawn_file_actions_addopen posix_spawn_file_actions_destroy posix_spawn_file_actions_init posix_spawnattr_destroy
|
108
|
+
posix_spawnattr_getflags posix_spawnattr_getpgroup posix_spawnattr_getschedparam posix_spawnattr_getschedpolicy posix_spawnattr_getsigdefault
|
109
|
+
posix_spawnattr_getsigmask posix_spawnattr_init posix_spawnattr_setflags posix_spawnattr_setpgroup posix_spawnattr_setschedparam
|
110
|
+
posix_spawnattr_setschedpolicy posix_spawnattr_setsigdefault posix_spawnattr_setsigmask posix_spawnp ppoll printf printf_size printf_size_info psignal
|
111
|
+
pthread_attr_destroy pthread_attr_getdetachstate pthread_attr_getinheritsched pthread_attr_getschedparam pthread_attr_getschedpolicy pthread_attr_getscope
|
112
|
+
pthread_attr_init pthread_attr_init pthread_attr_setdetachstate pthread_attr_setinheritsched pthread_attr_setschedparam pthread_attr_setschedpolicy
|
113
|
+
pthread_attr_setscope pthread_cond_broadcast pthread_cond_broadcast pthread_cond_destroy pthread_cond_destroy pthread_cond_init pthread_cond_init
|
114
|
+
pthread_cond_signal pthread_cond_signal pthread_cond_timedwait pthread_cond_timedwait pthread_cond_wait pthread_cond_wait pthread_condattr_destroy
|
115
|
+
pthread_condattr_init pthread_equal pthread_exit pthread_getschedparam pthread_mutex_destroy pthread_mutex_init pthread_mutex_lock pthread_mutex_unlock
|
116
|
+
pthread_self pthread_setcanceltype pthread_setschedparam ptrace ptsname putc_unlocked putchar putchar_unlocked putenv putgrent putmsg putpmsg putpwent
|
117
|
+
putspent pututxline putw putwc putwc_unlocked putwchar putwchar_unlocked qecvt qecvt_r qfcvt qfcvt_r qgcvt qsort query_module quotactl raise rand rand_r rcmd
|
118
|
+
rcmd_af readdir64 readdir64 readdir64_r readdir64_r readlinkat realloc realpath realpath reboot regexec regexec registerrpc remove removexattr remque rename
|
119
|
+
renameat revoke rewind rewinddir rexec rexec_af rpmatch rresvport rresvport_af rtime ruserok ruserok_af ruserpass scandir scandir64 scandir64 scanf
|
120
|
+
sched_getaffinity sched_getaffinity sched_getcpu sched_setaffinity sched_setaffinity seed48 seekdir semctl semctl semget semop semtimedop sendfile sendfile64
|
121
|
+
setaliasent setbuf setdomainname setegid seteuid setfsent setfsgid setfsuid setgrent setgroups sethostent sethostid sethostname setipv4sourcefilter setjmp
|
122
|
+
setlinebuf setlocale setlogin setlogmask setnetent setnetgrent setpgrp setpriority setprotoent setpwent setrlimit setrlimit setrlimit64 setrpcent setservent
|
123
|
+
setsockopt setsourcefilter setspent setttyent setusershell setutxent setxattr sgetspent shmat shmctl shmctl shmdt shmget sigaddset sigandset sigdelset
|
124
|
+
sigemptyset sigfillset siggetmask sighold sigignore siginterrupt sigisemptyset sigismember sigorset sigpending sigrelse sigset sigstack sockatmark splice
|
125
|
+
sprintf srand48 sscanf sstk statvfs stime strcat strchr strcmp strcoll strcpy strcspn strerror strerror_l strfmon strfry strftime strlen strncat strncmp
|
126
|
+
strncpy strnlen strpbrk strptime strrchr strsignal strspn strstr strtoimax strtok strtol strtoll strtoul strtoull strtoumax strxfrm stty svc_exit svc_getreq
|
127
|
+
svc_getreq_common svc_getreq_poll svc_getreqset svc_register svc_run svc_sendreply svc_unregister svcerr_auth svcerr_decode svcerr_noproc svcerr_noprog
|
128
|
+
svcerr_progvers svcerr_systemerr svcerr_weakauth svcfd_create svcraw_create svctcp_create svcudp_bufcreate svcudp_create svcudp_enablecache svcunix_create
|
129
|
+
svcunixfd_create swab swprintf swscanf symlinkat sync sync_file_range syscall sysinfo syslog tcflow tcflush tcgetpgrp tcgetsid tcsendbreak tcsetattr tcsetpgrp
|
130
|
+
tee telldir tempnam time timegm tmpfile tmpfile tmpfile64 tmpnam tmpnam_r toascii tolower toupper towlower towupper tr_break truncate64 ttyname ttyslot ualarm
|
131
|
+
ungetwc unlinkat unlockpt unshare updwtmpx uselib user2netname usleep ustat utime utimensat utmpxname verr verrx versionsort versionsort64 versionsort64
|
132
|
+
vfprintf vhangup vlimit vm86 vm86 vmsplice vprintf vswscanf vsyslog vtimes vwarn vwarnx vwprintf vwscanf warn warnx wcschr wcscmp wcscpy wcscspn wcsdup
|
133
|
+
wcsftime wcsncat wcsncmp wcspbrk wcsrchr wcsspn wcsstr wcstoimax wcstok wcstol wcstoll wcstombs wcstoul wcstoull wcstoumax wcswidth wcsxfrm wctob wctomb
|
134
|
+
wcwidth wmemchr wmemcmp wmemset wordexp wordfree wprintf wscanf xdecrypt xdr_accepted_reply xdr_array xdr_authdes_cred xdr_authdes_verf xdr_authunix_parms
|
135
|
+
xdr_bool xdr_bytes xdr_callhdr xdr_callmsg xdr_char xdr_cryptkeyarg xdr_cryptkeyarg2 xdr_cryptkeyres xdr_des_block xdr_double xdr_enum xdr_float xdr_free
|
136
|
+
xdr_getcredres xdr_hyper xdr_int xdr_int16_t xdr_int32_t xdr_int64_t xdr_int8_t xdr_key_netstarg xdr_key_netstres xdr_keybuf xdr_keystatus xdr_long
|
137
|
+
xdr_longlong_t xdr_netnamestr xdr_netobj xdr_opaque xdr_opaque_auth xdr_pmap xdr_pmaplist xdr_pointer xdr_quad_t xdr_reference xdr_rejected_reply xdr_replymsg
|
138
|
+
xdr_rmtcall_args xdr_rmtcallres xdr_short xdr_sizeof xdr_string xdr_u_char xdr_u_hyper xdr_u_int xdr_u_long xdr_u_longlong_t xdr_u_quad_t xdr_u_short
|
139
|
+
xdr_uint16_t xdr_uint32_t xdr_uint64_t xdr_uint8_t xdr_union xdr_unixcred xdr_vector xdr_void xdr_wrapstring xdrmem_create xdrrec_create xdrrec_endofrecord
|
140
|
+
xdrrec_eof xdrrec_skiprecord xdrstdio_create xencrypt xprt_register xprt_unregister
|
141
|
+
_Exit _IO_fprintf __close __connect __ctype_get_mb_cur_max __fcntl __getdelim __isascii_l __lseek __nanosleep __open __open64 __pread64 __pwrite64 __read
|
142
|
+
__send __sigaction __toascii_l __vsnprintf __vsscanf __wait __write __xpg_sigpause _flushlbf _longjmp accept access addmntent adjtime adjtimex advance
|
143
|
+
argp_error argp_failure argp_help argp_parse argp_state_help argp_usage argz_add argz_add_sep argz_append argz_count argz_create argz_create_sep argz_extract
|
144
|
+
argz_insert argz_next argz_replace argz_stringify asctime_r asprintf backtrace backtrace_symbols backtrace_symbols_fd bcmp bind_textdomain_codeset
|
145
|
+
bindtextdomain brk bsd_signal btowc bzero calloc canonicalize_file_name cfree chdir chmod clearenv clone close closedir connect copysign copysignf copysignl
|
146
|
+
creat dcgettext dcngettext dgettext dl_iterate_phdr dngettext dup dup2 duplocale eaccess endmntent endutent erand48_r error error_at_line euidaccess execve
|
147
|
+
fchdir fchmod fchown fcloseall fcntl fdatasync fdopendir feof ferror fflush ffsl fgetc fgetc_unlocked fgetgrent_r fgetpwent_r fgets fgetspent_r fgetwc
|
148
|
+
fgetwc_unlocked fileno_unlocked finite finitef finitel flock flockfile fopen64 fork fpathconf fputs fread freelocale frexp frexpf frexpl fstatfs fstatfs64
|
149
|
+
fstatvfs64 fsync ftell ftruncate ftruncate64 ftrylockfile funlockfile futimes fwprintf fwrite get_avphys_pages get_nprocs get_nprocs_conf get_phys_pages getc
|
150
|
+
getc_unlocked getcontext getcwd getdate_r getdelim getdtablesize getegid geteuid getgid getgroups gethostname getitimer getline getmntent_r getnetgrent_r
|
151
|
+
getpagesize getpeername getpgid getppid getpt getpw getresgid getresuid getrusage gets getsockopt gettext gettimeofday getuid getutent getutent_r getutid
|
152
|
+
getutid_r getutline getutline_r getwc getwc_unlocked glob_pattern_p gmtime_r gnu_get_libc_release gnu_get_libc_version group_member gsignal hasmntopt hdestroy
|
153
|
+
imaxabs imaxdiv index inet_aton initstate initstate_r ioctl isalnum_l isalpha_l isatty isblank_l iscntrl_l isctype isdigit_l isgraph_l isinf isinff isinfl
|
154
|
+
islower_l isnan isnanf isnanl isprint_l ispunct_l isspace_l isupper_l iswalnum iswalnum_l iswalpha iswalpha_l iswblank iswblank_l iswcntrl iswcntrl_l iswctype
|
155
|
+
iswctype_l iswdigit iswdigit_l iswgraph iswgraph_l iswlower iswlower_l iswprint iswprint_l iswpunct iswpunct_l iswspace iswspace_l iswupper iswupper_l
|
156
|
+
iswxdigit iswxdigit_l isxdigit_l jrand48_r kill lchown lckpwdf lcong48_r ldexp ldexpf ldexpl link llseek localtime_r longjmp lseek lseek64 makecontext
|
157
|
+
mallinfo malloc_get_state malloc_set_state malloc_stats malloc_trim malloc_usable_size mallopt mbrlen mbrtowc mbsinit mbsnrtowcs mbsrtowcs mcount memalign
|
158
|
+
memccpy memchr memrchr mkdir mmap mmap64 modf modff modfl modify_ldt moncontrol monstartup mount mprotect mremap msgrcv msgsnd msync munmap nanosleep
|
159
|
+
newlocale ngettext nl_langinfo_l nrand48_r ntohl ntohs ntp_adjtime obstack_printf obstack_vprintf on_exit open open64 openat openat64 opendir pathconf pause
|
160
|
+
personality pipe pipe2 poll posix_memalign posix_openpt prctl pread pread64 profil pselect pthread_setcancelstate ptsname_r putc puts pututline pvalloc pwrite
|
161
|
+
pwrite64 random random_r rawmemchr re_comp re_compile_fastmap re_compile_pattern re_exec re_match re_match_2 re_search re_search_2 re_set_registers
|
162
|
+
re_set_syntax read readahead readdir readdir_r readlink readv recv recvfrom recvmsg regcomp regerror regfree register_printf_function remap_file_pages
|
163
|
+
res_init rindex rmdir sbrk scalbln scalblnf scalblnl scalbn scalbnf scalbnl sched_get_priority_max sched_get_priority_min sched_getparam sched_getscheduler
|
164
|
+
sched_rr_get_interval sched_setparam sched_setscheduler sched_yield seed48_r select send sendmsg sendto setbuffer setcontext setenv setgid setitimer setmntent
|
165
|
+
setpgid setregid setresgid setresuid setreuid setsid setstate setstate_r settimeofday setuid setutent setvbuf sgetspent_r shutdown sigaction sigaltstack
|
166
|
+
sigblock siglongjmp signal sigpause sigprocmask sigqueue sigreturn sigsetmask sigsuspend sigtimedwait sigvec sigwait sigwaitinfo sleep snprintf socket
|
167
|
+
socketpair sprofil srand srand48_r srandom srandom_r ssignal statfs statfs64 statvfs64 step stpcpy stpncpy strcasecmp strcasecmp_l strcasestr strchrnul
|
168
|
+
strcoll_l strdup strerror_r strfmon_l strftime_l strncasecmp strncasecmp_l strndup strptime_l strsep strtod_l strtof_l strtok_r strtol_l strtold_l strtoll_l
|
169
|
+
strtoq strtoul_l strtoull_l strtouq strverscmp strxfrm_l swapcontext swapoff swapon symlink sysconf sysctl system sysv_signal tcdrain tcgetattr tdelete
|
170
|
+
tdestroy textdomain tfind timelocal times tolower_l toupper_l towctrans towctrans_l towlower_l towupper_l truncate tsearch ttyname_r twalk tzset ulckpwdf
|
171
|
+
ulimit umask umount umount2 uname ungetc unlink unsetenv updwtmp uselocale utimes utmpname valloc vasprintf vdprintf vfork vfscanf vfwprintf vfwscanf vscanf
|
172
|
+
vsnprintf vsprintf vsscanf vswprintf wait wait3 wait4 waitid waitpid wcpcpy wcpncpy wcrtomb wcscasecmp wcscasecmp_l wcscat wcschrnul wcscoll wcscoll_l
|
173
|
+
wcsftime_l wcslen wcsncasecmp wcsncasecmp_l wcsncpy wcsnlen wcsnrtombs wcsrtombs wcstod_l wcstof_l wcstol_l wcstold_l wcstoll_l wcstoq wcstoul_l wcstoull_l
|
174
|
+
wcstouq wcswcs wcsxfrm_l wctrans wctrans_l wctype wctype_l wmemcpy wmemmove wmempcpy write writev
|
175
|
+
libdl.so.2
|
176
|
+
dladdr dladdr1 dlclose dlerror dlinfo dlmopen dlopen dlopen dlsym dlvsym
|
177
|
+
libruby1.8.so.1.8
|
178
|
+
Init_Array Init_Bignum Init_Binding Init_Comparable Init_Dir Init_Enumerable Init_Enumerator Init_Exception Init_File Init_GC Init_Hash Init_IO Init_Math
|
179
|
+
Init_Numeric Init_Object Init_Precision Init_Proc Init_Random Init_Range Init_Regexp Init_String Init_Struct Init_Thread Init_Time Init_eval Init_ext
|
180
|
+
Init_heap Init_load Init_marshal Init_pack Init_process Init_signal Init_stack Init_sym Init_syserr Init_var_tables Init_version _fini _init dln_find_exe
|
181
|
+
dln_find_file dln_load dtoa freedtoa is_ruby_native_thread posix_nativethread_signal rb_Array rb_Float rb_Integer rb_String rb_add_event_hook rb_add_method
|
182
|
+
rb_alias rb_alias_variable rb_any_to_s rb_apply rb_ary_aref rb_ary_assoc rb_ary_clear rb_ary_cmp rb_ary_concat rb_ary_delete rb_ary_delete_at rb_ary_dup
|
183
|
+
rb_ary_each rb_ary_entry rb_ary_freeze rb_ary_includes rb_ary_join rb_ary_new rb_ary_new2 rb_ary_new3 rb_ary_new4 rb_ary_plus rb_ary_pop rb_ary_push
|
184
|
+
rb_ary_rassoc rb_ary_reverse rb_ary_shift rb_ary_sort rb_ary_sort_bang rb_ary_store rb_ary_to_ary rb_ary_to_s rb_ary_unshift rb_assoc_new rb_attr rb_attr_get
|
185
|
+
rb_autoload rb_autoload_load rb_autoload_p rb_backref_get rb_backref_set rb_backtrace rb_big2dbl rb_big2ll rb_big2long rb_big2str rb_big2str0 rb_big2ull
|
186
|
+
rb_big2ulong rb_big2ulong_pack rb_big_2comp rb_big_and rb_big_clone rb_big_divmod rb_big_lshift rb_big_minus rb_big_mul rb_big_mul0 rb_big_norm rb_big_or
|
187
|
+
rb_big_plus rb_big_pow rb_big_rand rb_big_rshift rb_big_xor rb_block_call rb_block_dup rb_block_given_p rb_block_proc rb_bug rb_call_inits rb_call_super
|
188
|
+
rb_catch rb_check_array_type rb_check_backtrace rb_check_convert_type rb_check_frozen rb_check_inheritable rb_check_safe_obj rb_check_safe_str
|
189
|
+
rb_check_string_type rb_check_to_integer rb_check_type rb_class2name rb_class_boot rb_class_inherited rb_class_inherited_p rb_class_init_copy
|
190
|
+
rb_class_instance_methods rb_class_name rb_class_new rb_class_new_instance rb_class_path rb_class_private_instance_methods rb_class_protected_instance_methods
|
191
|
+
rb_class_public_instance_methods rb_class_real rb_clear_cache rb_clear_cache_by_class rb_cmperr rb_cmpint rb_compile_cstr rb_compile_error
|
192
|
+
rb_compile_error_append rb_compile_file rb_compile_string rb_const_defined rb_const_defined_at rb_const_defined_from rb_const_get rb_const_get_at
|
193
|
+
rb_const_get_from rb_const_list rb_const_set rb_convert_type rb_copy_generic_ivar rb_copy_node_scope rb_cstr2inum rb_cstr_to_dbl rb_cstr_to_inum rb_cv_get
|
194
|
+
rb_cv_set rb_cvar_defined rb_cvar_get rb_cvar_set rb_data_object_alloc rb_dbl2big rb_dbl_cmp rb_define_alias rb_define_alloc_func rb_define_attr
|
195
|
+
rb_define_class rb_define_class_id rb_define_class_under rb_define_class_variable rb_define_const rb_define_global_const rb_define_global_function
|
196
|
+
rb_define_hooked_variable rb_define_method rb_define_method_id rb_define_module rb_define_module_function rb_define_module_id rb_define_module_under
|
197
|
+
rb_define_private_method rb_define_protected_method rb_define_readonly_variable rb_define_singleton_method rb_define_variable rb_define_virtual_variable
|
198
|
+
rb_detach_process rb_disable_super rb_during_gc rb_dvar_curr rb_dvar_defined rb_dvar_push rb_dvar_ref rb_each rb_enable_super rb_ensure rb_enumeratorize
|
199
|
+
rb_env_path_tainted rb_eof_error rb_eql rb_equal rb_error_frozen rb_eval_cmd rb_eval_string rb_eval_string_protect rb_eval_string_wrap rb_exc_fatal
|
200
|
+
rb_exc_jump rb_exc_new rb_exc_new2 rb_exc_new3 rb_exc_raise rb_exec_end_proc rb_exec_recursive rb_exit rb_extend_object rb_f_abort rb_f_exec rb_f_exit
|
201
|
+
rb_f_global_variables rb_f_kill rb_f_lambda rb_f_require rb_f_sprintf rb_f_trace_var rb_f_untrace_var rb_fatal rb_fdopen rb_file_const rb_file_expand_path
|
202
|
+
rb_file_open rb_file_s_expand_path rb_file_sysopen rb_find_file rb_find_file_ext rb_fix2int rb_fix2str rb_float_new rb_fopen rb_frame_last_func
|
203
|
+
rb_frame_this_func rb_free_generic_ivar rb_frozen_class_p rb_funcall rb_funcall2 rb_funcall3 rb_funcall_rescue rb_gc rb_gc_abort_threads
|
204
|
+
rb_gc_call_finalizer_at_exit rb_gc_copy_finalizer rb_gc_disable rb_gc_enable rb_gc_finalize_deferred rb_gc_force_recycle rb_gc_mark rb_gc_mark_frame
|
205
|
+
rb_gc_mark_global_tbl rb_gc_mark_locations rb_gc_mark_maybe rb_gc_mark_parser rb_gc_mark_threads rb_gc_mark_trap_list rb_gc_register_address rb_gc_start
|
206
|
+
rb_gc_unregister_address rb_generic_ivar_table rb_genrand_int32 rb_genrand_real rb_get_kcode rb_getc rb_gets rb_glob rb_global_entry rb_global_variable
|
207
|
+
rb_gv_get rb_gv_set rb_gvar_defined rb_gvar_get rb_gvar_set rb_hash rb_hash_aref rb_hash_aset rb_hash_delete rb_hash_delete_if rb_hash_foreach rb_hash_freeze
|
208
|
+
rb_hash_lookup rb_hash_new rb_hash_reject_bang rb_hash_select rb_hash_values_at rb_id2name rb_id_attrset rb_include_module rb_inspect rb_inspecting_p
|
209
|
+
rb_int2big rb_int2inum rb_intern rb_interrupt rb_invalid_str rb_io_addstr rb_io_binmode rb_io_check_closed rb_io_check_initialized rb_io_check_readable
|
210
|
+
rb_io_check_writable rb_io_close rb_io_eof rb_io_flags_mode rb_io_fptr_finalize rb_io_fread rb_io_fwrite rb_io_getc rb_io_gets rb_io_mode_flags
|
211
|
+
rb_io_modenum_flags rb_io_print rb_io_printf rb_io_puts rb_io_set_nonblock rb_io_synchronized rb_io_taint_check rb_io_unbuffered rb_io_ungetc
|
212
|
+
rb_io_wait_readable rb_io_wait_writable rb_io_write rb_is_class_id rb_is_const_id rb_is_instance_id rb_is_junk_id rb_is_local_id rb_iter_break rb_iterate
|
213
|
+
rb_iterator_p rb_iv_get rb_iv_set rb_ivar_defined rb_ivar_get rb_ivar_set rb_jump_tag rb_kcode rb_kcode_reset_option rb_kcode_set_option rb_lastline_get
|
214
|
+
rb_lastline_set rb_ll2big rb_ll2inum rb_load rb_load_fail rb_load_file rb_load_protect rb_loaderror rb_make_metaclass rb_mark_end_proc rb_mark_generic_ivar
|
215
|
+
rb_mark_generic_ivar_tbl rb_mark_hash rb_mark_set rb_mark_tbl rb_marshal_dump rb_marshal_load rb_match_busy rb_mem_clear rb_memcicmp rb_memcmp rb_memerror
|
216
|
+
rb_memsearch rb_method_boundp rb_method_dup rb_method_node rb_mod_ancestors rb_mod_class_variables rb_mod_const_at rb_mod_const_missing rb_mod_const_of
|
217
|
+
rb_mod_constants rb_mod_include_p rb_mod_included_modules rb_mod_init_copy rb_mod_module_eval rb_mod_module_exec rb_mod_name rb_mod_remove_const
|
218
|
+
rb_mod_remove_cvar rb_module_new rb_name_class rb_name_error rb_need_block rb_newobj rb_node_newnode rb_notimplement rb_num2dbl rb_num2fix rb_num2int
|
219
|
+
rb_num2ll rb_num2long rb_num2ull rb_num2ulong rb_num_coerce_bin rb_num_coerce_cmp rb_num_coerce_relop rb_num_zerodiv rb_obj_alloc rb_obj_as_string
|
220
|
+
rb_obj_call_init rb_obj_class rb_obj_classname rb_obj_clone rb_obj_dup rb_obj_freeze rb_obj_id rb_obj_id_obsolete rb_obj_infect rb_obj_init_copy
|
221
|
+
rb_obj_instance_eval rb_obj_instance_exec rb_obj_instance_variables rb_obj_is_instance_of rb_obj_is_kind_of rb_obj_method rb_obj_remove_instance_variable
|
222
|
+
rb_obj_respond_to rb_obj_singleton_methods rb_obj_taint rb_obj_tainted rb_obj_tap rb_obj_type rb_obj_untaint rb_p rb_parser_append_print rb_parser_while_loop
|
223
|
+
rb_path2class rb_path_check rb_path_end rb_path_last_separator rb_path_next rb_path_skip_prefix rb_proc_call rb_proc_exec rb_proc_new rb_proc_times rb_protect
|
224
|
+
rb_protect_inspect rb_provide rb_provided rb_quad_pack rb_quad_unpack rb_raise rb_range_beg_len rb_range_new rb_read_check rb_read_pending
|
225
|
+
rb_reg_adjust_startpos rb_reg_eqq rb_reg_last_match rb_reg_match rb_reg_match2 rb_reg_match_last rb_reg_match_post rb_reg_match_pre rb_reg_mbclen2 rb_reg_new
|
226
|
+
rb_reg_nth_defined rb_reg_nth_match rb_reg_options rb_reg_quote rb_reg_regcomp rb_reg_regsub rb_reg_search rb_remove_event_hook rb_remove_method rb_require
|
227
|
+
rb_require_safe rb_rescue rb_rescue2 rb_reserved_word rb_respond_to rb_scan_args rb_secure rb_secure_update rb_set_class_path rb_set_end_proc rb_set_kcode
|
228
|
+
rb_set_safe_level rb_singleton_class rb_singleton_class_attached rb_singleton_class_clone rb_source_filename rb_str2cstr rb_str2inum rb_str_append
|
229
|
+
rb_str_associate rb_str_associated rb_str_buf_append rb_str_buf_cat rb_str_buf_cat2 rb_str_buf_new rb_str_buf_new2 rb_str_cat rb_str_cat2 rb_str_cmp
|
230
|
+
rb_str_concat rb_str_dump rb_str_dup rb_str_dup_frozen rb_str_format rb_str_freeze rb_str_hash rb_str_inspect rb_str_intern rb_str_locktmp rb_str_modify
|
231
|
+
rb_str_new rb_str_new2 rb_str_new3 rb_str_new4 rb_str_new5 rb_str_plus rb_str_resize rb_str_set_len rb_str_setter rb_str_split rb_str_substr rb_str_times
|
232
|
+
rb_str_tmp_new rb_str_to_dbl rb_str_to_inum rb_str_to_str rb_str_unlocktmp rb_str_update rb_str_upto rb_string_value rb_string_value_cstr rb_string_value_ptr
|
233
|
+
rb_struct_alloc rb_struct_aref rb_struct_aset rb_struct_define rb_struct_getmember rb_struct_iv_get rb_struct_members rb_struct_new rb_struct_s_members
|
234
|
+
rb_svar rb_sym_all_symbols rb_sym_interned_p rb_symname_p rb_sys_fail rb_sys_warning rb_syswait rb_tainted_str_new rb_tainted_str_new2 rb_thread_alive_p
|
235
|
+
rb_thread_alone rb_thread_atfork rb_thread_create rb_thread_current rb_thread_fd_close rb_thread_fd_writable rb_thread_group rb_thread_interrupt
|
236
|
+
rb_thread_join rb_thread_kill rb_thread_list rb_thread_local_aref rb_thread_local_aset rb_thread_main rb_thread_polling rb_thread_reset_raised rb_thread_run
|
237
|
+
rb_thread_schedule rb_thread_select rb_thread_set_raised rb_thread_signal_exit rb_thread_signal_raise rb_thread_sleep rb_thread_sleep_forever
|
238
|
+
rb_thread_start_timer rb_thread_stop rb_thread_stop_timer rb_thread_trap_eval rb_thread_wait_fd rb_thread_wait_for rb_thread_wakeup rb_thread_wakeup_alive
|
239
|
+
rb_throw rb_time_interval rb_time_new rb_time_timeval rb_to_id rb_to_int rb_trap_exec rb_trap_exit rb_trap_restore_mask rb_uint2big rb_uint2inum rb_ull2big
|
240
|
+
rb_ull2inum rb_undef rb_undef_alloc_func rb_undef_method rb_values_at rb_waitpid rb_warn rb_warning rb_with_disable_interrupt rb_write_error rb_write_error2
|
241
|
+
rb_yield rb_yield_splat rb_yield_values re_mbc_startpos re_set_syntax ruby_brace_expand ruby_brace_glob ruby_cleanup ruby_default_signal ruby_each_words
|
242
|
+
ruby_exec ruby_finalize ruby_float_step ruby_getcwd ruby_glob ruby_incpush ruby_init ruby_init_ext ruby_init_loadpath ruby_init_stack ruby_native_thread_kill
|
243
|
+
ruby_options ruby_parser_stack_on_heap ruby_posix_signal ruby_process_options ruby_prog_init ruby_qsort ruby_re_adjust_startpos ruby_re_compile_fastmap
|
244
|
+
ruby_re_compile_pattern ruby_re_copy_registers ruby_re_free_pattern ruby_re_free_registers ruby_re_match ruby_re_mbcinit ruby_re_search ruby_re_set_casetable
|
245
|
+
ruby_run ruby_scan_hex ruby_scan_oct ruby_script ruby_set_argv ruby_set_current_source ruby_set_stack_size ruby_setenv ruby_show_copyright ruby_show_version
|
246
|
+
ruby_signal_name ruby_stack_check ruby_stack_length ruby_stop ruby_strdup ruby_strtod ruby_unsetenv ruby_xcalloc ruby_xfree ruby_xmalloc ruby_xrealloc
|
247
|
+
ruby_yyparse st_add_direct st_cleanup_safe st_copy st_delete st_delete_safe st_foreach st_foreach_safe st_free_table st_init_numtable
|
248
|
+
st_init_numtable_with_size st_init_strtable st_init_strtable_with_size st_init_table st_init_table_with_size st_insert st_lookup
|
249
|
+
rb_argv rb_argv0 rb_cArray rb_cBignum rb_cBinding rb_cClass rb_cCont rb_cData rb_cDir rb_cEnumerator rb_cFalseClass rb_cFile rb_cFixnum rb_cFloat rb_cHash
|
250
|
+
rb_cIO rb_cInteger rb_cMatch rb_cMethod rb_cModule rb_cNameErrorMesg rb_cNilClass rb_cNumeric rb_cObject rb_cProc rb_cRange rb_cRegexp rb_cStat rb_cString
|
251
|
+
rb_cStruct rb_cSymbol rb_cThread rb_cTime rb_cTrueClass rb_cUnboundMethod rb_class_tbl rb_curr_thread rb_default_rs rb_deferr rb_eArgError rb_eEOFError
|
252
|
+
rb_eException rb_eFatal rb_eFloatDomainError rb_eIOError rb_eIndexError rb_eInterrupt rb_eLoadError rb_eLocalJumpError rb_eNameError rb_eNoMemError
|
253
|
+
rb_eNoMethodError rb_eNotImpError rb_eRangeError rb_eRegexpError rb_eRuntimeError rb_eScriptError rb_eSecurityError rb_eSignal rb_eStandardError
|
254
|
+
rb_eStopIteration rb_eSyntaxError rb_eSysStackError rb_eSystemCallError rb_eSystemExit rb_eThreadError rb_eTypeError rb_eZeroDivError rb_fs rb_gc_stack_start
|
255
|
+
rb_global_tbl rb_last_status rb_load_path rb_mComparable rb_mEnumerable rb_mErrno rb_mFConst rb_mFileTest rb_mGC rb_mKernel rb_mMath rb_mPrecision rb_mProcGID
|
256
|
+
rb_mProcID_Syscall rb_mProcUID rb_mProcess rb_main_thread rb_origenviron rb_output_fs rb_output_rs rb_progname rb_prohibit_interrupt rb_rs rb_stderr rb_stdin
|
257
|
+
rb_stdout rb_thread_critical rb_thread_pending rb_trap_immediate rb_trap_pending re_mbctab ruby__end__seen ruby_class ruby_copyright ruby_cref
|
258
|
+
ruby_current_node ruby_debug ruby_description ruby_digitmap ruby_dln_librefs ruby_dyna_vars ruby_errinfo ruby_eval_tree ruby_eval_tree_begin ruby_frame
|
259
|
+
ruby_gc_stress ruby_ignorecase ruby_in_compile ruby_in_eval ruby_inplace_mode ruby_nerrs ruby_patchlevel ruby_platform ruby_release_date ruby_safe_level
|
260
|
+
ruby_sandbox_restore ruby_sandbox_save ruby_scope ruby_sourcefile ruby_sourceline ruby_top_cref ruby_top_self ruby_verbose ruby_version ruby_yychar
|
261
|
+
ruby_yydebug ruby_yylval
|
262
|
+
EOL
|
263
|
+
curlibname = nil
|
264
|
+
data.each_line { |l|
|
265
|
+
list = l.split
|
266
|
+
curlibname = list.shift if l[0, 1] != ' '
|
267
|
+
list.each { |export| EXPORT[export] = curlibname }
|
268
|
+
}
|
269
|
+
end
|
270
|
+
end
|
@@ -0,0 +1,1112 @@
|
|
1
|
+
# This file is part of Metasm, the Ruby assembly manipulation suite
|
2
|
+
# Copyright (C) 2006-2009 Yoann GUILLOT
|
3
|
+
#
|
4
|
+
# Licence is LGPL, see LICENCE in the top-level directory
|
5
|
+
|
6
|
+
|
7
|
+
require 'metasm/os/main'
|
8
|
+
|
9
|
+
module Metasm
|
10
|
+
class PTrace
|
11
|
+
attr_accessor :buf, :pid
|
12
|
+
|
13
|
+
def self.open(target)
|
14
|
+
ptrace = new(target)
|
15
|
+
return ptrace if not block_given?
|
16
|
+
ret = yield ptrace
|
17
|
+
ptrace.detach
|
18
|
+
ret
|
19
|
+
end
|
20
|
+
|
21
|
+
# calls PTRACE_TRACEME on the current (ruby) process
|
22
|
+
def self.traceme
|
23
|
+
new(::Process.pid, false).traceme
|
24
|
+
end
|
25
|
+
|
26
|
+
# creates a ptraced process (target = path)
|
27
|
+
# or opens a running process (target = pid)
|
28
|
+
# values for do_attach:
|
29
|
+
# :create => always fork+traceme+exec+wait
|
30
|
+
# :attach => always attach
|
31
|
+
# false/nil => same as attach, without actually calling PT_ATTACH (usefull if we're already tracing pid)
|
32
|
+
# anything else: try to attach if pid is numeric (using Integer()), else create
|
33
|
+
def initialize(target, do_attach=true)
|
34
|
+
begin
|
35
|
+
raise ArgumentError if do_attach == :create
|
36
|
+
@pid = Integer(target)
|
37
|
+
tweak_for_pid(@pid)
|
38
|
+
return if not do_attach
|
39
|
+
attach
|
40
|
+
rescue ArgumentError, TypeError
|
41
|
+
raise if do_attach == :attach or not do_attach
|
42
|
+
did_exec = true
|
43
|
+
if not @pid = fork
|
44
|
+
tweak_for_pid(::Process.pid)
|
45
|
+
traceme
|
46
|
+
::Process.exec(*target)
|
47
|
+
exit!(0)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
wait
|
51
|
+
raise "could not exec #{target}" if $?.exited?
|
52
|
+
tweak_for_pid(@pid) if did_exec
|
53
|
+
puts "Ptrace: attached to #@pid" if $DEBUG
|
54
|
+
end
|
55
|
+
|
56
|
+
def wait
|
57
|
+
::Process.wait(@pid, ::Process::WALL)
|
58
|
+
end
|
59
|
+
|
60
|
+
attr_accessor :reg_off, :intsize, :syscallnr, :syscallreg
|
61
|
+
attr_accessor :packint, :packuint, :host_intsize, :host_syscallnr
|
62
|
+
# setup the variables according to the target
|
63
|
+
def tweak_for_pid(pid=@pid)
|
64
|
+
# use these for our syscalls PTRACE
|
65
|
+
case LinOS.open_process(::Process.pid).cpu.shortname
|
66
|
+
when 'ia32'
|
67
|
+
@packint = 'l'
|
68
|
+
@packuint = 'L'
|
69
|
+
@host_intsize = 4
|
70
|
+
@host_syscallnr = SYSCALLNR_I386
|
71
|
+
@reg_off = REGS_I386
|
72
|
+
when 'x64'
|
73
|
+
@packint = 'q'
|
74
|
+
@packuint = 'Q'
|
75
|
+
@host_intsize = 8
|
76
|
+
@host_syscallnr = SYSCALLNR_X86_64
|
77
|
+
@reg_off = REGS_X86_64
|
78
|
+
else raise 'unsupported architecture'
|
79
|
+
end
|
80
|
+
|
81
|
+
# use these to interpret the child state
|
82
|
+
tgcpu = LinOS.open_process(pid).cpu
|
83
|
+
case tgcpu.shortname
|
84
|
+
when 'ia32'
|
85
|
+
@syscallreg = 'ORIG_EAX'
|
86
|
+
@syscallnr = SYSCALLNR_I386
|
87
|
+
@intsize = 4
|
88
|
+
when 'x64'
|
89
|
+
@syscallreg = 'ORIG_RAX'
|
90
|
+
@syscallnr = SYSCALLNR_X86_64
|
91
|
+
@intsize = 8
|
92
|
+
else raise 'unsupported target architecture'
|
93
|
+
end
|
94
|
+
|
95
|
+
cp = tgcpu.new_cparser
|
96
|
+
cp.parse SIGINFO_C
|
97
|
+
@siginfo = cp.alloc_c_struct('siginfo')
|
98
|
+
|
99
|
+
# buffer used in ptrace syscalls
|
100
|
+
@buf = [0].pack(@packint)
|
101
|
+
@bufptr = str_ptr(@buf)
|
102
|
+
end
|
103
|
+
|
104
|
+
def str_ptr(str)
|
105
|
+
[str].pack('P').unpack(@packint).first
|
106
|
+
end
|
107
|
+
|
108
|
+
# interpret the value turned as an unsigned long
|
109
|
+
def bufval
|
110
|
+
@buf.unpack(@packint).first
|
111
|
+
end
|
112
|
+
|
113
|
+
# reads a memory range
|
114
|
+
def readmem(off, len)
|
115
|
+
decal = off % @host_intsize
|
116
|
+
buf = ''
|
117
|
+
if decal > 0
|
118
|
+
off -= decal
|
119
|
+
peekdata(off)
|
120
|
+
off += @host_intsize
|
121
|
+
buf << @buf[decal...@host_intsize]
|
122
|
+
end
|
123
|
+
offend = off + len
|
124
|
+
while off < offend
|
125
|
+
peekdata(off)
|
126
|
+
buf << @buf[0, @host_intsize]
|
127
|
+
off += @host_intsize
|
128
|
+
end
|
129
|
+
buf[0, len]
|
130
|
+
end
|
131
|
+
|
132
|
+
def writemem(off, str)
|
133
|
+
decal = off % @host_intsize
|
134
|
+
if decal > 0
|
135
|
+
off -= decal
|
136
|
+
peekdata(off)
|
137
|
+
str = @buf[0...decal] + str
|
138
|
+
end
|
139
|
+
decal = str.length % @host_intsize
|
140
|
+
if decal > 0
|
141
|
+
peekdata(off+str.length-decal)
|
142
|
+
str += @buf[decal...@host_intsize]
|
143
|
+
end
|
144
|
+
i = 0
|
145
|
+
while i < str.length
|
146
|
+
pokedata(off+i, str[i, @host_intsize])
|
147
|
+
i += @host_intsize
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# linux/ptrace.h
|
152
|
+
COMMAND = {
|
153
|
+
'TRACEME' => 0, 'PEEKTEXT' => 1,
|
154
|
+
'PEEKDATA' => 2, 'PEEKUSR' => 3,
|
155
|
+
'POKETEXT' => 4, 'POKEDATA' => 5,
|
156
|
+
'POKEUSR' => 6, 'CONT' => 7,
|
157
|
+
'KILL' => 8, 'SINGLESTEP' => 9,
|
158
|
+
'ATTACH' => 16, 'DETACH' => 17,
|
159
|
+
'SYSCALL' => 24,
|
160
|
+
|
161
|
+
# arch/x86/include/ptrace-abi.h
|
162
|
+
'GETREGS' => 12, 'SETREGS' => 13,
|
163
|
+
'GETFPREGS' => 14, 'SETFPREGS' => 15,
|
164
|
+
'GETFPXREGS' => 18, 'SETFPXREGS' => 19,
|
165
|
+
'OLDSETOPTIONS' => 21, 'GET_THREAD_AREA' => 25,
|
166
|
+
'SET_THREAD_AREA' => 26, 'ARCH_PRCTL' => 30,
|
167
|
+
'SYSEMU' => 31, 'SYSEMU_SINGLESTEP'=> 32,
|
168
|
+
'SINGLEBLOCK' => 33,
|
169
|
+
# 0x4200-0x4300 are reserved for architecture-independent additions.
|
170
|
+
'SETOPTIONS' => 0x4200, 'GETEVENTMSG' => 0x4201,
|
171
|
+
'GETSIGINFO' => 0x4202, 'SETSIGINFO' => 0x4203
|
172
|
+
}
|
173
|
+
|
174
|
+
OPTIONS = {
|
175
|
+
# options set using PTRACE_SETOPTIONS
|
176
|
+
'TRACESYSGOOD' => 0x01, 'TRACEFORK' => 0x02,
|
177
|
+
'TRACEVFORK' => 0x04, 'TRACECLONE' => 0x08,
|
178
|
+
'TRACEEXEC' => 0x10, 'TRACEVFORKDONE'=> 0x20,
|
179
|
+
'TRACEEXIT' => 0x40
|
180
|
+
}
|
181
|
+
|
182
|
+
WAIT_EXTENDEDRESULT = {
|
183
|
+
# Wait extended result codes for the above trace options.
|
184
|
+
'EVENT_FORK' => 1, 'EVENT_VFORK' => 2,
|
185
|
+
'EVENT_CLONE' => 3, 'EVENT_EXEC' => 4,
|
186
|
+
'EVENT_VFORK_DONE' => 5, 'EVENT_EXIT' => 6
|
187
|
+
}
|
188
|
+
WAIT_EXTENDEDRESULT.update WAIT_EXTENDEDRESULT.invert
|
189
|
+
|
190
|
+
|
191
|
+
# block trace
|
192
|
+
BTS_O = { 'TRACE' => 1, 'SCHED' => 2, 'SIGNAL' => 4, 'ALLOC' => 8 }
|
193
|
+
BTS = { 'CONFIG' => 40, 'STATUS' => 41, 'SIZE' => 42,
|
194
|
+
'GET' => 43, 'CLEAR' => 44, 'DRAIN' => 45 }
|
195
|
+
|
196
|
+
REGS_I386 = {
|
197
|
+
'EBX' => 0, 'ECX' => 1, 'EDX' => 2, 'ESI' => 3,
|
198
|
+
'EDI' => 4, 'EBP' => 5, 'EAX' => 6, 'DS' => 7,
|
199
|
+
'ES' => 8, 'FS' => 9, 'GS' => 10, 'ORIG_EAX' => 11,
|
200
|
+
'EIP' => 12, 'CS' => 13, 'EFL' => 14, 'UESP'=> 15,
|
201
|
+
'EFLAGS' => 14, 'ESP' => 15,
|
202
|
+
'SS' => 16,
|
203
|
+
# from ptrace.c in kernel source & asm-i386/user.h
|
204
|
+
'DR0' => 63, 'DR1' => 64, 'DR2' => 65, 'DR3' => 66,
|
205
|
+
'DR4' => 67, 'DR5' => 68, 'DR6' => 69, 'DR7' => 70
|
206
|
+
}
|
207
|
+
|
208
|
+
REGS_X86_64 = {
|
209
|
+
'R15' => 0, 'R14' => 1, 'R13' => 2, 'R12' => 3,
|
210
|
+
'RBP' => 4, 'RBX' => 5, 'R11' => 6, 'R10' => 7,
|
211
|
+
'R9' => 8, 'R8' => 9, 'RAX' => 10, 'RCX' => 11,
|
212
|
+
'RDX' => 12, 'RSI' => 13, 'RDI' => 14, 'ORIG_RAX' => 15,
|
213
|
+
'RIP' => 16, 'CS' => 17, 'RFLAGS' => 18, 'RSP' => 19,
|
214
|
+
'SS' => 20, 'FS_BASE' => 21, 'GS_BASE' => 22, 'DS' => 23,
|
215
|
+
'ES' => 24, 'FS' => 25, 'GS' => 26,
|
216
|
+
#'FP_VALID' => 27,
|
217
|
+
#'387_XWD' => 28, '387_RIP' => 29, '387_RDP' => 30, '387_MXCSR' => 31,
|
218
|
+
#'FP0' => 32, 'FP1' => 34, 'FP2' => 36, 'FP3' => 38,
|
219
|
+
#'FP4' => 40, 'FP5' => 42, 'FP6' => 44, 'FP7' => 46,
|
220
|
+
#'XMM0' => 48, 'XMM1' => 52, 'XMM2' => 56, 'XMM3' => 60,
|
221
|
+
#'XMM4' => 64, 'XMM5' => 68, 'XMM6' => 72, 'XMM7' => 76,
|
222
|
+
#'FPAD0' => 80, 'FPAD11' => 91,
|
223
|
+
#'TSZ' => 92, 'DSZ' => 93, 'SSZ' => 94, 'CODE' => 95,
|
224
|
+
#'STK' => 96, 'SIG' => 97, 'PAD' => 98, 'U_AR0' => 99,
|
225
|
+
#'FPPTR' => 100, 'MAGIC' => 101, 'COMM0' => 102, 'COMM1' => 103,
|
226
|
+
#'COMM2' => 104, 'COMM3' => 105,
|
227
|
+
'DR0' => 106, 'DR1' => 107, 'DR2' => 108, 'DR3' => 109,
|
228
|
+
'DR4' => 110, 'DR5' => 111, 'DR6' => 112, 'DR7' => 113,
|
229
|
+
#'ERROR_CODE' => 114, 'FAULT_ADDR' => 115
|
230
|
+
}
|
231
|
+
|
232
|
+
SYSCALLNR_I386 = %w[restart_syscall exit fork read write open close waitpid creat link unlink execve chdir time
|
233
|
+
mknod chmod lchown break oldstat lseek getpid mount umount setuid getuid stime ptrace alarm oldfstat
|
234
|
+
pause utime stty gtty access nice ftime sync kill rename mkdir rmdir dup pipe times prof brk setgid
|
235
|
+
getgid signal geteuid getegid acct umount2 lock ioctl fcntl mpx setpgid ulimit oldolduname umask
|
236
|
+
chroot ustat dup2 getppid getpgrp setsid sigaction sgetmask ssetmask setreuid setregid sigsuspend
|
237
|
+
sigpending sethostname setrlimit getrlimit getrusage gettimeofday settimeofday getgroups setgroups
|
238
|
+
select symlink oldlstat readlink uselib swapon reboot readdir mmap munmap truncate ftruncate fchmod
|
239
|
+
fchown getpriority setpriority profil statfs fstatfs ioperm socketcall syslog setitimer getitimer
|
240
|
+
stat lstat fstat olduname iopl vhangup idle vm86old wait4 swapoff sysinfo ipc fsync sigreturn
|
241
|
+
clone setdomainname uname modify_ldt adjtimex mprotect sigprocmask create_module init_module
|
242
|
+
delete_module get_kernel_syms quotactl getpgid fchdir bdflush sysfs personality afs_syscall setfsuid
|
243
|
+
setfsgid _llseek getdents _newselect flock msync readv writev getsid fdatasync _sysctl mlock
|
244
|
+
munlock mlockall munlockall sched_setparam sched_getparam sched_setscheduler sched_getscheduler
|
245
|
+
sched_yield sched_get_priority_max sched_get_priority_min sched_rr_get_interval nanosleep mremap
|
246
|
+
setresuid getresuid vm86 query_module poll nfsservctl setresgid getresgid prctl rt_sigreturn
|
247
|
+
rt_sigaction rt_sigprocmask rt_sigpending rt_sigtimedwait rt_sigqueueinfo rt_sigsuspend pread64
|
248
|
+
pwrite64 chown getcwd capget capset sigaltstack sendfile getpmsg putpmsg vfork ugetrlimit mmap2
|
249
|
+
truncate64 ftruncate64 stat64 lstat64 fstat64 lchown32 getuid32 getgid32 geteuid32 getegid32
|
250
|
+
setreuid32 setregid32 getgroups32 setgroups32 fchown32 setresuid32 getresuid32 setresgid32
|
251
|
+
getresgid32 chown32 setuid32 setgid32 setfsuid32 setfsgid32 pivot_root mincore madvise getdents64
|
252
|
+
fcntl64 sys_222 sys_223 gettid readahead setxattr lsetxattr fsetxattr getxattr lgetxattr fgetxattr
|
253
|
+
listxattr llistxattr flistxattr removexattr lremovexattr fremovexattr tkill sendfile64 futex
|
254
|
+
sched_setaffinity sched_getaffinity set_thread_area get_thread_area io_setup io_destroy io_getevents
|
255
|
+
io_submit io_cancel fadvise64 sys_251 exit_group lookup_dcookie epoll_create epoll_ctl epoll_wait
|
256
|
+
remap_file_pages set_tid_address timer_create timer_settime timer_gettime timer_getoverrun
|
257
|
+
timer_delete clock_settime clock_gettime clock_getres clock_nanosleep statfs64 fstatfs64 tgkill
|
258
|
+
utimes fadvise64_64 vserver mbind get_mempolicy set_mempolicy mq_open mq_unlink mq_timedsend
|
259
|
+
mq_timedreceive mq_notify mq_getsetattr kexec_load waitid sys_setaltroot add_key request_key keyctl
|
260
|
+
ioprio_set ioprio_get inotify_init inotify_add_watch inotify_rm_watch migrate_pages openat mkdirat
|
261
|
+
mknodat fchownat futimesat fstatat64 unlinkat renameat linkat symlinkat readlinkat fchmodat
|
262
|
+
faccessat pselect6 ppoll unshare set_robust_list get_robust_list splice sync_file_range tee vmsplice
|
263
|
+
move_pages getcpu epoll_pwait utimensat signalfd timerfd eventfd fallocate timerfd_settime
|
264
|
+
timerfd_gettime signalfd4 eventfd2 epoll_create1 dup3 pipe2 inotify_init1 preadv pwritev
|
265
|
+
rt_tg_sigqueueinfo perf_counter_open].inject({}) { |h, sc| h.update sc => h.length }
|
266
|
+
SYSCALLNR_I386.update SYSCALLNR_I386.invert
|
267
|
+
|
268
|
+
SYSCALLNR_X86_64 = %w[read write open close stat fstat lstat poll lseek mmap mprotect munmap brk rt_sigaction
|
269
|
+
rt_sigprocmask rt_sigreturn ioctl pread64 pwrite64 readv writev access pipe select sched_yield
|
270
|
+
mremap msync mincore madvise shmget shmat shmctl dup dup2 pause nanosleep getitimer alarm
|
271
|
+
setitimer getpid sendfile socket connect accept sendto recvfrom sendmsg recvmsg shutdown
|
272
|
+
bind listen getsockname getpeername socketpair setsockopt getsockopt clone fork vfork execve
|
273
|
+
exit wait4 kill uname semget semop semctl shmdt msgget msgsnd msgrcv msgctl fcntl flock
|
274
|
+
fsync fdatasync truncate ftruncate getdents getcwd chdir fchdir rename mkdir rmdir creat
|
275
|
+
link unlink symlink readlink chmod fchmod chown fchown lchown umask gettimeofday getrlimit
|
276
|
+
getrusage sysinfo times ptrace getuid syslog getgid setuid setgid geteuid getegid setpgid
|
277
|
+
getppid getpgrp setsid setreuid setregid getgroups setgroups setresuid getresuid setresgid
|
278
|
+
getresgid getpgid setfsuid setfsgid getsid capget capset rt_sigpending rt_sigtimedwait
|
279
|
+
rt_sigqueueinfo rt_sigsuspend sigaltstack utime mknod uselib personality ustat statfs fstatfs
|
280
|
+
sysfs getpriority setpriority sched_setparam sched_getparam sched_setscheduler sched_getscheduler
|
281
|
+
sched_get_priority_max sched_get_priority_min sched_rr_get_interval mlock munlock mlockall
|
282
|
+
munlockall vhangup modify_ldt pivot_root _sysctl prctl arch_prctl adjtimex setrlimit chroot sync
|
283
|
+
acct settimeofday mount umount2 swapon swapoff reboot sethostname setdomainname iopl ioperm
|
284
|
+
create_module init_module delete_module get_kernel_syms query_module quotactl nfsservctl getpmsg
|
285
|
+
putpmsg afs_syscall tuxcall security gettid readahead setxattr lsetxattr fsetxattr getxattr
|
286
|
+
lgetxattr fgetxattr listxattr llistxattr flistxattr removexattr lremovexattr fremovexattr tkill time
|
287
|
+
futex sched_setaffinity sched_getaffinity set_thread_area io_setup io_destroy io_getevents io_submit
|
288
|
+
io_cancel get_thread_area lookup_dcookie epoll_create epoll_ctl_old epoll_wait_old remap_file_pages
|
289
|
+
getdents64 set_tid_address restart_syscall semtimedop fadvise64 timer_create timer_settime
|
290
|
+
timer_gettime timer_getoverrun timer_delete clock_settime clock_gettime clock_getres clock_nanosleep
|
291
|
+
exit_group epoll_wait epoll_ctl tgkill utimes vserver mbind set_mempolicy get_mempolicy mq_open
|
292
|
+
mq_unlink mq_timedsend mq_timedreceive mq_notify mq_getsetattr kexec_load waitid add_key request_key
|
293
|
+
keyctl ioprio_set ioprio_get inotify_init inotify_add_watch inotify_rm_watch migrate_pages openat
|
294
|
+
mkdirat mknodat fchownat futimesat newfstatat unlinkat renameat linkat symlinkat readlinkat
|
295
|
+
fchmodat faccessat pselect6 ppoll unshare set_robust_list get_robust_list splice tee sync_file_range
|
296
|
+
vmsplice move_pages utimensat epoll_pwait signalfd timerfd_create eventfd fallocate timerfd_settime
|
297
|
+
timerfd_gettime accept4 signalfd4 eventfd2 epoll_create1 dup3 pipe2 inotify_init1 preadv pwritev
|
298
|
+
rt_tgsigqueueinfo perf_counter_open].inject({}) { |h, sc| h.update sc => h.length }
|
299
|
+
SYSCALLNR_X86_64.update SYSCALLNR_X86_64.invert
|
300
|
+
|
301
|
+
SIGNAL = Signal.list.dup
|
302
|
+
SIGNAL.delete SIGNAL.index(0)
|
303
|
+
SIGNAL['TRAP'] ||= 5 # windows+gdbremote
|
304
|
+
SIGNAL.update SIGNAL.invert
|
305
|
+
|
306
|
+
# include/asm-generic/errno-base.h
|
307
|
+
ERRNO = %w[ERR0 EPERM ENOENT ESRCH EINTR EIO ENXIO E2BIG ENOEXEC EBADF ECHILD EAGAIN ENOMEM EACCES EFAULT
|
308
|
+
ENOTBLK EBUSY EEXIST EXDEV ENODEV ENOTDIR EISDIR EINVAL ENFILE EMFILE ENOTTY ETXTBSY EFBIG ENOSPC
|
309
|
+
ESPIPE EROFS EMLINK EPIPE EDOM ERANGE].inject({}) { |h, e| h.update e => h.length }
|
310
|
+
ERRNO.update ERRNO.invert
|
311
|
+
|
312
|
+
SIGINFO = {
|
313
|
+
# user-generated signal
|
314
|
+
'DETHREAD' => -7, # execve killing threads
|
315
|
+
'TKILL' => -6, 'SIGIO' => -5, 'ASYNCIO' => -4, 'MESGQ' => -3,
|
316
|
+
'TIMER' => -2, 'QUEUE' => -1, 'USER' => 0, 'KERNEL' => 0x80,
|
317
|
+
# ILL
|
318
|
+
'ILLOPC' => 1, 'ILLOPN' => 2, 'ILLADR' => 3, 'ILLTRP' => 4,
|
319
|
+
'PRVOPC' => 5, 'PRVREG' => 6, 'COPROC' => 7, 'BADSTK' => 8,
|
320
|
+
# FPE
|
321
|
+
'INTDIV' => 1, 'INTOVF' => 2, 'FLTDIV' => 3, 'FLTOVF' => 4,
|
322
|
+
'FLTUND' => 5, 'FLTRES' => 6, 'FLTINV' => 7, 'FLTSUB' => 8,
|
323
|
+
# SEGV
|
324
|
+
'MAPERR' => 1, 'ACCERR' => 2,
|
325
|
+
# BUS
|
326
|
+
'ADRALN' => 1, 'ADRERR' => 2, 'OBJERR' => 3, 'MCEERR_AR' => 4,
|
327
|
+
'MCEERR_AO' => 5,
|
328
|
+
# TRAP
|
329
|
+
'BRKPT' => 1, 'TRACE' => 2, 'BRANCH' => 3, 'HWBKPT' => 4,
|
330
|
+
# CHLD
|
331
|
+
'EXITED' => 1, 'KILLED' => 2, 'DUMPED' => 3, 'TRAPPED' => 4,
|
332
|
+
'STOPPED' => 5, 'CONTINUED' => 6,
|
333
|
+
# POLL
|
334
|
+
'POLL_IN' => 1, 'POLL_OUT' => 2, 'POLL_MSG' => 3, 'POLL_ERR' => 4,
|
335
|
+
'POLL_PRI' => 5, 'POLL_HUP' => 6
|
336
|
+
}
|
337
|
+
|
338
|
+
SIGINFO_C = <<EOS
|
339
|
+
typedef __int32 __pid_t;
|
340
|
+
typedef unsigned __int32 __uid_t;
|
341
|
+
typedef uintptr_t sigval_t;
|
342
|
+
typedef long __clock_t;
|
343
|
+
|
344
|
+
typedef struct siginfo {
|
345
|
+
int si_signo;
|
346
|
+
int si_errno;
|
347
|
+
int si_code;
|
348
|
+
// int pad64;
|
349
|
+
union {
|
350
|
+
int _pad[128/4-3]; /* total >= 128b */
|
351
|
+
|
352
|
+
struct { /* kill(). */
|
353
|
+
__pid_t si_pid; /* Sending process ID. */
|
354
|
+
__uid_t si_uid; /* Real user ID of sending process. */
|
355
|
+
} _kill;
|
356
|
+
struct { /* POSIX.1b timers. */
|
357
|
+
int si_tid; /* Timer ID. */
|
358
|
+
int si_overrun; /* Overrun count. */
|
359
|
+
sigval_t si_sigval; /* Signal value. */
|
360
|
+
} _timer;
|
361
|
+
struct { /* POSIX.1b signals. */
|
362
|
+
__pid_t si_pid; /* Sending process ID. */
|
363
|
+
__uid_t si_uid; /* Real user ID of sending process. */
|
364
|
+
sigval_t si_sigval; /* Signal value. */
|
365
|
+
} _rt;
|
366
|
+
struct { /* SIGCHLD. */
|
367
|
+
__pid_t si_pid; /* Which child. */
|
368
|
+
__uid_t si_uid; /* Real user ID of sending process. */
|
369
|
+
int si_status; /* Exit value or signal. */
|
370
|
+
__clock_t si_utime;
|
371
|
+
__clock_t si_stime;
|
372
|
+
} _sigchld;
|
373
|
+
struct { /* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
|
374
|
+
uintptr_t si_addr; /* Faulting insn/memory ref. */
|
375
|
+
} _sigfault;
|
376
|
+
struct { /* SIGPOLL. */
|
377
|
+
long int si_band; /* Band event for SIGPOLL. */
|
378
|
+
int si_fd;
|
379
|
+
} _sigpoll;
|
380
|
+
};
|
381
|
+
} siginfo_t;
|
382
|
+
EOS
|
383
|
+
|
384
|
+
def sys_ptrace(req, pid, addr, data)
|
385
|
+
data = str_ptr(data) if data.kind_of?(String)
|
386
|
+
addr = [addr].pack(@packint).unpack(@packint).first
|
387
|
+
data = [data].pack(@packint).unpack(@packint).first
|
388
|
+
Kernel.syscall(@host_syscallnr['ptrace'], req, pid, addr, data)
|
389
|
+
end
|
390
|
+
|
391
|
+
def traceme
|
392
|
+
sys_ptrace(COMMAND['TRACEME'], 0, 0, 0)
|
393
|
+
end
|
394
|
+
|
395
|
+
def peektext(addr)
|
396
|
+
sys_ptrace(COMMAND['PEEKTEXT'], @pid, addr, @bufptr)
|
397
|
+
@buf
|
398
|
+
end
|
399
|
+
|
400
|
+
def peekdata(addr)
|
401
|
+
sys_ptrace(COMMAND['PEEKDATA'], @pid, addr, @bufptr)
|
402
|
+
@buf
|
403
|
+
end
|
404
|
+
|
405
|
+
def peekusr(addr)
|
406
|
+
sys_ptrace(COMMAND['PEEKUSR'], @pid, @host_intsize*addr, @bufptr)
|
407
|
+
bufval & ((1 << ([@host_intsize, @intsize].min*8)) - 1)
|
408
|
+
end
|
409
|
+
|
410
|
+
def poketext(addr, data)
|
411
|
+
sys_ptrace(COMMAND['POKETEXT'], @pid, addr, data.unpack(@packint).first)
|
412
|
+
end
|
413
|
+
|
414
|
+
def pokedata(addr, data)
|
415
|
+
sys_ptrace(COMMAND['POKEDATA'], @pid, addr, data.unpack(@packint).first)
|
416
|
+
end
|
417
|
+
|
418
|
+
def pokeusr(addr, data)
|
419
|
+
sys_ptrace(COMMAND['POKEUSR'], @pid, @host_intsize*addr, data)
|
420
|
+
end
|
421
|
+
|
422
|
+
def getregs(buf=nil)
|
423
|
+
buf ||= [0].pack('C')*512
|
424
|
+
sys_ptrace(COMMAND['GETREGS'], @pid, 0, buf)
|
425
|
+
buf
|
426
|
+
end
|
427
|
+
def setregs(buf)
|
428
|
+
sys_ptrace(COMMAND['SETREGS'], @pid, 0, buf)
|
429
|
+
end
|
430
|
+
|
431
|
+
def getfpregs(buf=nil)
|
432
|
+
buf ||= [0].pack('C')*1024
|
433
|
+
sys_ptrace(COMMAND['GETFPREGS'], @pid, 0, buf)
|
434
|
+
buf
|
435
|
+
end
|
436
|
+
def setfpregs(buf)
|
437
|
+
sys_ptrace(COMMAND['SETFPREGS'], @pid, 0, buf)
|
438
|
+
end
|
439
|
+
|
440
|
+
def getfpxregs(buf=nil)
|
441
|
+
buf ||= [0].pack('C')*512
|
442
|
+
sys_ptrace(COMMAND['GETFPXREGS'], @pid, 0, buf)
|
443
|
+
buf
|
444
|
+
end
|
445
|
+
def setfpxregs(buf)
|
446
|
+
sys_ptrace(COMMAND['SETFPXREGS'], @pid, 0, buf)
|
447
|
+
end
|
448
|
+
|
449
|
+
def get_thread_area(addr)
|
450
|
+
sys_ptrace(COMMAND['GET_THREAD_AREA'], @pid, addr, @bufptr)
|
451
|
+
bufval
|
452
|
+
end
|
453
|
+
def set_thread_area(addr, data)
|
454
|
+
sys_ptrace(COMMAND['SET_THREAD_AREA'], @pid, addr, data)
|
455
|
+
end
|
456
|
+
|
457
|
+
def prctl(addr, data)
|
458
|
+
sys_ptrace(COMMAND['ARCH_PRCTL'], @pid, addr, data)
|
459
|
+
end
|
460
|
+
|
461
|
+
def cont(sig = nil)
|
462
|
+
sig ||= 0
|
463
|
+
sys_ptrace(COMMAND['CONT'], @pid, 0, sig)
|
464
|
+
end
|
465
|
+
|
466
|
+
def kill
|
467
|
+
sys_ptrace(COMMAND['KILL'], @pid, 0, 0)
|
468
|
+
end
|
469
|
+
|
470
|
+
def singlestep(sig = nil)
|
471
|
+
sig ||= 0
|
472
|
+
sys_ptrace(COMMAND['SINGLESTEP'], @pid, 0, sig)
|
473
|
+
end
|
474
|
+
|
475
|
+
def singleblock(sig = nil)
|
476
|
+
sig ||= 0
|
477
|
+
sys_ptrace(COMMAND['SINGLEBLOCK'], @pid, 0, sig)
|
478
|
+
end
|
479
|
+
|
480
|
+
def syscall(sig = nil)
|
481
|
+
sig ||= 0
|
482
|
+
sys_ptrace(COMMAND['SYSCALL'], @pid, 0, sig)
|
483
|
+
end
|
484
|
+
|
485
|
+
def attach
|
486
|
+
sys_ptrace(COMMAND['ATTACH'], @pid, 0, 0)
|
487
|
+
end
|
488
|
+
|
489
|
+
def detach
|
490
|
+
sys_ptrace(COMMAND['DETACH'], @pid, 0, 0)
|
491
|
+
end
|
492
|
+
|
493
|
+
def setoptions(*opt)
|
494
|
+
opt = opt.inject(0) { |b, o| b |= o.kind_of?(Integer) ? o : OPTIONS[o] }
|
495
|
+
sys_ptrace(COMMAND['SETOPTIONS'], @pid, 0, opt)
|
496
|
+
end
|
497
|
+
|
498
|
+
# retrieve pid of cld for EVENT_CLONE/FORK, exitcode for EVENT_EXIT
|
499
|
+
def geteventmsg
|
500
|
+
sys_ptrace(COMMAND['GETEVENTMSG'], @pid, 0, @bufptr)
|
501
|
+
bufval
|
502
|
+
end
|
503
|
+
|
504
|
+
def getsiginfo
|
505
|
+
sys_ptrace(COMMAND['GETSIGINFO'], @pid, 0, @siginfo.str)
|
506
|
+
@siginfo
|
507
|
+
end
|
508
|
+
|
509
|
+
def setsiginfo(si=@siginfo)
|
510
|
+
si = si.str if si.respond_to?(:str)
|
511
|
+
sys_ptrace(COMMAND['SETSIGINFO'], @pid, 0, si)
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
515
|
+
class LinOS < OS
|
516
|
+
class Process < OS::Process
|
517
|
+
# returns/create a LinuxRemoteString
|
518
|
+
def memory
|
519
|
+
@memory ||= LinuxRemoteString.new(pid)
|
520
|
+
end
|
521
|
+
attr_writer :memory
|
522
|
+
|
523
|
+
def debugger
|
524
|
+
@debugger ||= LinDebugger.new(@pid)
|
525
|
+
end
|
526
|
+
attr_writer :debugger
|
527
|
+
|
528
|
+
# returns the list of loaded Modules, incl start address & path
|
529
|
+
# read from /proc/pid/maps
|
530
|
+
def modules
|
531
|
+
list = []
|
532
|
+
seen = {}
|
533
|
+
File.readlines("/proc/#{pid}/maps").each { |l|
|
534
|
+
# 08048000-08064000 r-xp 000000 08:01 4234 /usr/bin/true
|
535
|
+
l = l.split
|
536
|
+
next if l.length < 6 or seen[l[-1]]
|
537
|
+
seen[l[-1]] = true
|
538
|
+
m = Module.new
|
539
|
+
m.addr = l[0].to_i(16)
|
540
|
+
m.path = l[-1]
|
541
|
+
list << m
|
542
|
+
}
|
543
|
+
list
|
544
|
+
rescue
|
545
|
+
[]
|
546
|
+
end
|
547
|
+
|
548
|
+
# return a list of [addr_start, length, perms, file]
|
549
|
+
def mappings
|
550
|
+
list = []
|
551
|
+
File.readlines("/proc/#{pid}/maps").each { |l|
|
552
|
+
l = l.split
|
553
|
+
addrstart, addrend = l[0].split('-').map { |i| i.to_i 16 }
|
554
|
+
list << [addrstart, addrend-addrstart, l[1], l[5]]
|
555
|
+
}
|
556
|
+
list
|
557
|
+
rescue
|
558
|
+
[]
|
559
|
+
end
|
560
|
+
|
561
|
+
# returns a list of threads sharing this process address space
|
562
|
+
# read from /proc/pid/task/
|
563
|
+
def threads
|
564
|
+
Dir.entries("/proc/#{pid}/task/").grep(/^\d+$/).map { |tid| tid.to_i }
|
565
|
+
rescue
|
566
|
+
# TODO handle pthread stuff (eg 2.4 kernels)
|
567
|
+
[pid]
|
568
|
+
end
|
569
|
+
|
570
|
+
# return the invocation commandline, from /proc/pid/cmdline
|
571
|
+
# this is manipulable by the target itself
|
572
|
+
def cmdline
|
573
|
+
@cmdline ||= File.read("/proc/#{pid}/cmdline") rescue ''
|
574
|
+
end
|
575
|
+
attr_writer :cmdline
|
576
|
+
|
577
|
+
def path
|
578
|
+
cmdline.split(0.chr)[0]
|
579
|
+
end
|
580
|
+
|
581
|
+
# returns the address size of the process, based on its #cpu
|
582
|
+
def addrsz
|
583
|
+
cpu.size
|
584
|
+
end
|
585
|
+
|
586
|
+
# returns the CPU for the process, by reading /proc/pid/exe
|
587
|
+
def cpu
|
588
|
+
e = ELF.load_file("/proc/#{pid}/exe")
|
589
|
+
# dont decode shdr/phdr, this is 2x faster for repeated debugger spawn
|
590
|
+
e.decode_header(0, false, false)
|
591
|
+
e.cpu
|
592
|
+
end
|
593
|
+
|
594
|
+
def terminate
|
595
|
+
kill
|
596
|
+
end
|
597
|
+
|
598
|
+
def kill(signr=9)
|
599
|
+
::Process.kill(signr, @pid)
|
600
|
+
end
|
601
|
+
end
|
602
|
+
|
603
|
+
class << self
|
604
|
+
# returns an array of Processes, with pid/module listing
|
605
|
+
def list_processes
|
606
|
+
Dir.entries('/proc').grep(/^\d+$/).map { |pid| Process.new(pid.to_i) }
|
607
|
+
end
|
608
|
+
|
609
|
+
# return a Process for the specified pid if it exists in /proc
|
610
|
+
def open_process(pid)
|
611
|
+
Process.new(pid) if check_process(pid)
|
612
|
+
end
|
613
|
+
|
614
|
+
def check_process(pid)
|
615
|
+
File.directory?("/proc/#{pid}")
|
616
|
+
end
|
617
|
+
|
618
|
+
# create a LinDebugger on the target pid/binary
|
619
|
+
def create_debugger(path)
|
620
|
+
LinDebugger.new(path)
|
621
|
+
end
|
622
|
+
end # class << self
|
623
|
+
end
|
624
|
+
|
625
|
+
class LinuxRemoteString < VirtualString
|
626
|
+
attr_accessor :pid, :readfd
|
627
|
+
attr_accessor :dbg
|
628
|
+
|
629
|
+
# returns a virtual string proxying the specified process memory range
|
630
|
+
# reads are cached (4096 aligned bytes read at once), from /proc/pid/mem
|
631
|
+
# writes are done directly by ptrace
|
632
|
+
def initialize(pid, addr_start=0, length=nil, dbg=nil)
|
633
|
+
@pid = pid
|
634
|
+
length ||= 1 << (dbg ? dbg.cpu.size : (LinOS.open_process(@pid).addrsz rescue 32))
|
635
|
+
@readfd = File.open("/proc/#@pid/mem", 'rb') rescue nil
|
636
|
+
@dbg = dbg if dbg
|
637
|
+
super(addr_start, length)
|
638
|
+
end
|
639
|
+
|
640
|
+
def dup(addr = @addr_start, len = @length)
|
641
|
+
self.class.new(@pid, addr, len, dbg)
|
642
|
+
end
|
643
|
+
|
644
|
+
def do_ptrace
|
645
|
+
if dbg
|
646
|
+
dbg.switch_context(@pid) {
|
647
|
+
# XXX tid ?
|
648
|
+
yield dbg.ptrace if dbg.state == :stopped
|
649
|
+
}
|
650
|
+
else
|
651
|
+
PTrace.open(@pid) { |ptrace| yield ptrace }
|
652
|
+
end
|
653
|
+
end
|
654
|
+
|
655
|
+
def rewrite_at(addr, data)
|
656
|
+
# target must be stopped
|
657
|
+
do_ptrace { |ptrace| ptrace.writemem(addr, data) }
|
658
|
+
end
|
659
|
+
|
660
|
+
def get_page(addr, len=@pagelength)
|
661
|
+
do_ptrace { |ptrace|
|
662
|
+
begin
|
663
|
+
if readfd and addr < (1<<63)
|
664
|
+
# 1<<63: ruby seek = 'too big to fit longlong', linux read = EINVAL
|
665
|
+
@readfd.pos = addr
|
666
|
+
@readfd.read len
|
667
|
+
elsif addr < (1<<(ptrace.host_intsize*8))
|
668
|
+
# can reach 1<<64 with peek_data only if ptrace accepts 64bit args
|
669
|
+
ptrace.readmem(addr, len)
|
670
|
+
end
|
671
|
+
rescue Errno::EIO, Errno::ESRCH
|
672
|
+
nil
|
673
|
+
end
|
674
|
+
}
|
675
|
+
end
|
676
|
+
end
|
677
|
+
|
678
|
+
module ::Process
|
679
|
+
WALL = 0x40000000 if not defined? WALL
|
680
|
+
WCLONE = 0x80000000 if not defined? WCLONE
|
681
|
+
end
|
682
|
+
|
683
|
+
# this class implements a high-level API over the ptrace debugging primitives
|
684
|
+
class LinDebugger < Debugger
|
685
|
+
# ptrace is per-process or per-thread ?
|
686
|
+
attr_accessor :ptrace, :continuesignal, :has_pax_mprotect, :target_syscall
|
687
|
+
attr_accessor :callback_syscall, :callback_branch, :callback_exec
|
688
|
+
|
689
|
+
def initialize(pidpath=nil)
|
690
|
+
super()
|
691
|
+
@pid_stuff_list << :has_pax_mprotect << :ptrace << :breaking << :os_process
|
692
|
+
@tid_stuff_list << :continuesignal << :saved_csig << :ctx << :target_syscall
|
693
|
+
|
694
|
+
# by default, break on all signals except SIGWINCH (terminal resize notification)
|
695
|
+
@pass_all_exceptions = lambda { |e| e[:signal] == 'WINCH' }
|
696
|
+
|
697
|
+
@callback_syscall = lambda { |i| log "syscall #{i[:syscall]}" }
|
698
|
+
@callback_exec = lambda { |i| log "execve #{os_process.path}" }
|
699
|
+
|
700
|
+
return if not pidpath
|
701
|
+
|
702
|
+
begin
|
703
|
+
pid = Integer(pidpath)
|
704
|
+
attach(pid)
|
705
|
+
rescue ArgumentError
|
706
|
+
create_process(pidpath)
|
707
|
+
end
|
708
|
+
end
|
709
|
+
|
710
|
+
def shortname; 'lindbg'; end
|
711
|
+
|
712
|
+
# attach to a running process and all its threads
|
713
|
+
def attach(pid, do_attach=:attach)
|
714
|
+
pt = PTrace.new(pid, do_attach)
|
715
|
+
set_context(pt.pid, pt.pid) # swapout+init_newpid
|
716
|
+
log "attached #@pid"
|
717
|
+
list_threads.each { |tid| attach_thread(tid) if tid != @pid }
|
718
|
+
end
|
719
|
+
|
720
|
+
# create a process and debug it
|
721
|
+
def create_process(path)
|
722
|
+
pt = PTrace.new(path, :create)
|
723
|
+
# TODO save path, allow restart etc
|
724
|
+
set_context(pt.pid, pt.pid) # swapout+init_newpid
|
725
|
+
log "attached #@pid"
|
726
|
+
end
|
727
|
+
|
728
|
+
def initialize_cpu
|
729
|
+
@cpu = os_process.cpu
|
730
|
+
# need to init @ptrace here, before init_dasm calls gui.swapin
|
731
|
+
@ptrace = PTrace.new(@pid, false)
|
732
|
+
if @cpu.size == 64 and @ptrace.reg_off['EAX']
|
733
|
+
hack_64_32
|
734
|
+
end
|
735
|
+
set_tid @pid
|
736
|
+
set_thread_options
|
737
|
+
end
|
738
|
+
|
739
|
+
def initialize_memory
|
740
|
+
@memory = os_process.memory = LinuxRemoteString.new(@pid, 0, nil, self)
|
741
|
+
end
|
742
|
+
|
743
|
+
def os_process
|
744
|
+
@os_process ||= LinOS.open_process(@pid)
|
745
|
+
end
|
746
|
+
|
747
|
+
def list_threads
|
748
|
+
os_process.threads
|
749
|
+
end
|
750
|
+
|
751
|
+
def list_processes
|
752
|
+
LinOS.list_processes
|
753
|
+
end
|
754
|
+
|
755
|
+
def check_pid(pid)
|
756
|
+
LinOS.check_process(pid)
|
757
|
+
end
|
758
|
+
|
759
|
+
def mappings
|
760
|
+
os_process.mappings
|
761
|
+
end
|
762
|
+
|
763
|
+
def modules
|
764
|
+
os_process.modules
|
765
|
+
end
|
766
|
+
|
767
|
+
# we're a 32bit process debugging a 64bit target
|
768
|
+
# the ptrace kernel interface we use only allow us a 32bit-like target access
|
769
|
+
# with this we advertize the cpu as having eax..edi registers (the only one we
|
770
|
+
# can access), while still decoding x64 instructions (whose addr < 4G)
|
771
|
+
def hack_64_32
|
772
|
+
log "WARNING: debugging a 64bit process from a 32bit debugger is a very bad idea !"
|
773
|
+
@cpu.instance_eval {
|
774
|
+
ia32 = Ia32.new
|
775
|
+
@dbg_register_pc = ia32.dbg_register_pc
|
776
|
+
@dbg_register_flags = ia32.dbg_register_flags
|
777
|
+
@dbg_register_list = ia32.dbg_register_list
|
778
|
+
@dbg_register_size = ia32.dbg_register_size
|
779
|
+
}
|
780
|
+
end
|
781
|
+
|
782
|
+
# attach a thread of the current process
|
783
|
+
def attach_thread(tid)
|
784
|
+
set_tid tid
|
785
|
+
@ptrace.pid = tid
|
786
|
+
@ptrace.attach
|
787
|
+
@state = :stopped # no need to wait()
|
788
|
+
log "attached thread #{tid}"
|
789
|
+
set_thread_options
|
790
|
+
end
|
791
|
+
|
792
|
+
# set the debugee ptrace options (notify clone/exec/exit, and fork/vfork depending on @trace_children)
|
793
|
+
def set_thread_options
|
794
|
+
opts = %w[TRACESYSGOOD TRACECLONE TRACEEXEC TRACEEXIT]
|
795
|
+
opts += %w[TRACEFORK TRACEVFORK TRACEVFORKDONE] if trace_children
|
796
|
+
@ptrace.pid = @tid
|
797
|
+
@ptrace.setoptions(*opts)
|
798
|
+
end
|
799
|
+
|
800
|
+
# update the current pid relative to tracing children (@trace_children only effects newly traced pid/tid)
|
801
|
+
def do_trace_children
|
802
|
+
each_tid { set_thread_options }
|
803
|
+
end
|
804
|
+
|
805
|
+
def invalidate
|
806
|
+
@ctx = nil
|
807
|
+
super()
|
808
|
+
end
|
809
|
+
|
810
|
+
# a hash of the current thread context
|
811
|
+
# TODO keys = :gpr, :fpu, :xmm, :dr ; val = AllocCStruct
|
812
|
+
# include accessors for st0/xmm12 (@ptrace.getfpregs.unpack etc)
|
813
|
+
def ctx
|
814
|
+
@ctx ||= {}
|
815
|
+
end
|
816
|
+
|
817
|
+
def get_reg_value(r)
|
818
|
+
raise "bad register #{r}" if not k = @ptrace.reg_off[r.to_s.upcase]
|
819
|
+
return ctx[r] || 0 if @state != :stopped
|
820
|
+
@ptrace.pid = @tid
|
821
|
+
ctx[r] ||= @ptrace.peekusr(k)
|
822
|
+
rescue Errno::ESRCH
|
823
|
+
0
|
824
|
+
end
|
825
|
+
def set_reg_value(r, v)
|
826
|
+
raise "bad register #{r}" if not k = @ptrace.reg_off[r.to_s.upcase]
|
827
|
+
ctx[r] = v
|
828
|
+
return if @state != :stopped
|
829
|
+
@ptrace.pid = @tid
|
830
|
+
@ptrace.pokeusr(k, v)
|
831
|
+
end
|
832
|
+
|
833
|
+
def update_waitpid(status)
|
834
|
+
invalidate
|
835
|
+
@continuesignal = 0
|
836
|
+
@state = :stopped # allow get_reg (for eg pt_syscall)
|
837
|
+
info = { :status => status }
|
838
|
+
if status.exited?
|
839
|
+
info.update :exitcode => status.exitstatus
|
840
|
+
if @tid == @pid # XXX
|
841
|
+
evt_endprocess info
|
842
|
+
else
|
843
|
+
evt_endthread info
|
844
|
+
end
|
845
|
+
elsif status.signaled?
|
846
|
+
info.update :signal => (PTrace::SIGNAL[status.termsig] || status.termsig)
|
847
|
+
if @tid == @pid
|
848
|
+
evt_endprocess info
|
849
|
+
else
|
850
|
+
evt_endthread info
|
851
|
+
end
|
852
|
+
elsif status.stopped?
|
853
|
+
sig = status.stopsig & 0x7f
|
854
|
+
signame = PTrace::SIGNAL[sig]
|
855
|
+
if signame == 'TRAP'
|
856
|
+
if status.stopsig & 0x80 > 0
|
857
|
+
# XXX int80 in x64 => syscallnr32 ?
|
858
|
+
evt_syscall info.update(:syscall => @ptrace.syscallnr[get_reg_value(@ptrace.syscallreg)])
|
859
|
+
|
860
|
+
elsif (status >> 16) > 0
|
861
|
+
case o = PTrace::WAIT_EXTENDEDRESULT[status >> 16]
|
862
|
+
when 'EVENT_FORK', 'EVENT_VFORK'
|
863
|
+
# parent notification of a fork
|
864
|
+
# child receives STOP (may have already happened)
|
865
|
+
#cld = @ptrace.geteventmsg
|
866
|
+
resume_badbreak
|
867
|
+
|
868
|
+
when 'EVENT_CLONE'
|
869
|
+
#cld = @ptrace.geteventmsg
|
870
|
+
resume_badbreak
|
871
|
+
|
872
|
+
when 'EVENT_EXIT'
|
873
|
+
info.update :exitcode => @ptrace.geteventmsg
|
874
|
+
if @tid == @pid
|
875
|
+
evt_endprocess info
|
876
|
+
else
|
877
|
+
evt_endthread info
|
878
|
+
end
|
879
|
+
|
880
|
+
when 'EVENT_VFORKDONE'
|
881
|
+
resume_badbreak
|
882
|
+
|
883
|
+
when 'EVENT_EXEC'
|
884
|
+
evt_exec info
|
885
|
+
end
|
886
|
+
|
887
|
+
else
|
888
|
+
si = @ptrace.getsiginfo
|
889
|
+
case si.si_code
|
890
|
+
when PTrace::SIGINFO['BRKPT'],
|
891
|
+
PTrace::SIGINFO['KERNEL'] # \xCC prefer KERNEL to BRKPT
|
892
|
+
evt_bpx
|
893
|
+
when PTrace::SIGINFO['TRACE']
|
894
|
+
evt_singlestep # singlestep/singleblock
|
895
|
+
when PTrace::SIGINFO['BRANCH']
|
896
|
+
evt_branch # XXX BTS?
|
897
|
+
when PTrace::SIGINFO['HWBKPT']
|
898
|
+
evt_hwbp
|
899
|
+
else
|
900
|
+
@saved_csig = @continuesignal = sig
|
901
|
+
info.update :signal => signame, :type => "SIG#{signame}"
|
902
|
+
evt_exception info
|
903
|
+
end
|
904
|
+
end
|
905
|
+
|
906
|
+
elsif signame == 'STOP' and @info == 'new'
|
907
|
+
# new thread break on creation (eg after fork + TRACEFORK)
|
908
|
+
if @pid == @tid
|
909
|
+
attach(@pid, false)
|
910
|
+
evt_newprocess info
|
911
|
+
else
|
912
|
+
evt_newthread info
|
913
|
+
end
|
914
|
+
|
915
|
+
elsif signame == 'STOP' and @breaking
|
916
|
+
@state = :stopped
|
917
|
+
@info = 'break'
|
918
|
+
@breaking = nil
|
919
|
+
|
920
|
+
else
|
921
|
+
@saved_csig = @continuesignal = sig
|
922
|
+
info.update :signal => signame, :type => "SIG#{signame}"
|
923
|
+
if signame == 'SEGV'
|
924
|
+
# need more data on access violation (for bpm)
|
925
|
+
info.update :type => 'access violation'
|
926
|
+
si = @ptrace.getsiginfo
|
927
|
+
access = case si.si_code
|
928
|
+
when PTrace::SIGINFO['MAPERR']; :r # XXX write access to unmapped => ?
|
929
|
+
when PTrace::SIGINFO['ACCERR']; :w
|
930
|
+
end
|
931
|
+
info.update :fault_addr => si.si_addr, :fault_access => access
|
932
|
+
end
|
933
|
+
evt_exception info
|
934
|
+
end
|
935
|
+
else
|
936
|
+
log "unknown wait status #{status.inspect}"
|
937
|
+
evt_exception info.update(:type => "unknown wait #{status.inspect}")
|
938
|
+
end
|
939
|
+
end
|
940
|
+
|
941
|
+
def set_tid_findpid(tid)
|
942
|
+
return if tid == @tid
|
943
|
+
if tid != @pid and pr = list_processes.find { |p| p.threads.include? tid }
|
944
|
+
set_pid pr.pid
|
945
|
+
end
|
946
|
+
set_tid tid
|
947
|
+
end
|
948
|
+
|
949
|
+
def do_check_target
|
950
|
+
return unless t = ::Process.waitpid(-1, ::Process::WNOHANG | ::Process::WALL)
|
951
|
+
# XXX all threads may have stopped, wait them now ?
|
952
|
+
set_tid_findpid t
|
953
|
+
update_waitpid $?
|
954
|
+
rescue ::Errno::ECHILD
|
955
|
+
end
|
956
|
+
|
957
|
+
def do_wait_target
|
958
|
+
t = ::Process.waitpid(-1, ::Process::WALL)
|
959
|
+
set_tid_findpid t
|
960
|
+
update_waitpid $?
|
961
|
+
rescue ::Errno::ECHILD
|
962
|
+
end
|
963
|
+
|
964
|
+
def do_continue
|
965
|
+
@ptrace.pid = tid
|
966
|
+
@ptrace.cont(@continuesignal)
|
967
|
+
end
|
968
|
+
|
969
|
+
def do_singlestep(*a)
|
970
|
+
@ptrace.pid = tid
|
971
|
+
@ptrace.singlestep(@continuesignal)
|
972
|
+
end
|
973
|
+
|
974
|
+
# use the PT_SYSCALL to break on next syscall
|
975
|
+
# regexp allowed to wait a specific syscall
|
976
|
+
def syscall(arg=nil)
|
977
|
+
arg = nil if arg and arg.strip == ''
|
978
|
+
return if not check_pre_run(:syscall, arg)
|
979
|
+
@target_syscall = arg
|
980
|
+
@ptrace.pid = @tid
|
981
|
+
@ptrace.syscall(@continuesignal)
|
982
|
+
end
|
983
|
+
|
984
|
+
def syscall_wait(*a, &b)
|
985
|
+
syscall(*a, &b)
|
986
|
+
wait_target
|
987
|
+
end
|
988
|
+
|
989
|
+
# use the PT_SINGLEBLOCK to execute until the next branch
|
990
|
+
def singleblock
|
991
|
+
# record as singlestep to avoid evt_singlestep -> evt_exception
|
992
|
+
# step or block doesn't matter much here anyway
|
993
|
+
return if not check_pre_run(:singlestep)
|
994
|
+
@ptrace.pid = @tid
|
995
|
+
@ptrace.singleblock(@continuesignal)
|
996
|
+
end
|
997
|
+
|
998
|
+
def singleblock_wait(*a, &b)
|
999
|
+
singleblock(*a, &b)
|
1000
|
+
wait_target
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
# woke up from a PT_SYSCALL
|
1004
|
+
def evt_syscall(info={})
|
1005
|
+
@state = :stopped
|
1006
|
+
@info = "syscall #{info[:syscall]}"
|
1007
|
+
|
1008
|
+
callback_syscall[info] if callback_syscall
|
1009
|
+
|
1010
|
+
if @target_syscall and info[:syscall] !~ /^#@target_syscall$/i
|
1011
|
+
resume_badbreak
|
1012
|
+
else
|
1013
|
+
@target_syscall = nil
|
1014
|
+
end
|
1015
|
+
end
|
1016
|
+
|
1017
|
+
# SIGTRAP + SIGINFO_TRAP_BRANCH = ?
|
1018
|
+
def evt_branch(info={})
|
1019
|
+
@state = :stopped
|
1020
|
+
@info = "branch"
|
1021
|
+
|
1022
|
+
callback_branch[info] if callback_branch
|
1023
|
+
end
|
1024
|
+
|
1025
|
+
# called during sys_execve in the new process
|
1026
|
+
def evt_exec(info={})
|
1027
|
+
@state = :stopped
|
1028
|
+
@info = "#{info[:exec]} execve"
|
1029
|
+
|
1030
|
+
initialize_newpid
|
1031
|
+
# XXX will receive a SIGTRAP, could hide it..
|
1032
|
+
|
1033
|
+
callback_exec[info] if callback_exec
|
1034
|
+
# calling continue() here will loop back to TRAP+INFO_EXEC
|
1035
|
+
end
|
1036
|
+
|
1037
|
+
def break
|
1038
|
+
@breaking = true
|
1039
|
+
kill 'STOP'
|
1040
|
+
end
|
1041
|
+
|
1042
|
+
def kill(sig=nil)
|
1043
|
+
return if not tid
|
1044
|
+
# XXX tkill ?
|
1045
|
+
::Process.kill(sig2signr(sig), tid)
|
1046
|
+
rescue Errno::ESRCH
|
1047
|
+
end
|
1048
|
+
|
1049
|
+
def pass_current_exception(bool=true)
|
1050
|
+
if bool
|
1051
|
+
@continuesignal = @saved_csig
|
1052
|
+
else
|
1053
|
+
@continuesignal = 0
|
1054
|
+
end
|
1055
|
+
end
|
1056
|
+
|
1057
|
+
def sig2signr(sig)
|
1058
|
+
case sig
|
1059
|
+
when nil, ''; 9
|
1060
|
+
when Integer; sig
|
1061
|
+
when String
|
1062
|
+
sig = sig.upcase.sub(/^SIG_?/, '')
|
1063
|
+
PTrace::SIGNAL[sig] || Integer(sig)
|
1064
|
+
else raise "unhandled signal #{sig.inspect}"
|
1065
|
+
end
|
1066
|
+
end
|
1067
|
+
|
1068
|
+
# stop debugging the current process
|
1069
|
+
def detach
|
1070
|
+
del_all_breakpoints
|
1071
|
+
each_tid {
|
1072
|
+
@ptrace.pid = @tid
|
1073
|
+
@ptrace.detach
|
1074
|
+
@delete_thread = true
|
1075
|
+
}
|
1076
|
+
del_pid
|
1077
|
+
end
|
1078
|
+
|
1079
|
+
def bpx(addr, *a, &b)
|
1080
|
+
return hwbp(addr, :x, 1, *a, &b) if @has_pax_mprotect
|
1081
|
+
super(addr, *a, &b)
|
1082
|
+
end
|
1083
|
+
|
1084
|
+
# handles exceptions from PaX-style mprotect restrictions on bpx,
|
1085
|
+
# transmute them to hwbp on the fly
|
1086
|
+
def do_enable_bp(b)
|
1087
|
+
super(b)
|
1088
|
+
rescue ::Errno::EIO
|
1089
|
+
if b.type == :bpx
|
1090
|
+
@memory[b.address, 1] # check if we can read
|
1091
|
+
# didn't raise: it's a PaX-style config
|
1092
|
+
@has_pax_mprotect = true
|
1093
|
+
b.del
|
1094
|
+
hwbp(b.address, :x, 1, b.oneshot, b.condition, &b.action)
|
1095
|
+
log 'PaX: bpx->hwbp'
|
1096
|
+
else raise
|
1097
|
+
end
|
1098
|
+
end
|
1099
|
+
|
1100
|
+
def ui_command_setup(ui)
|
1101
|
+
ui.new_command('syscall', 'waits for the target to do a syscall using PT_SYSCALL') { |arg| ui.wrap_run { syscall arg } }
|
1102
|
+
ui.keyboard_callback[:f6] = lambda { ui.wrap_run { syscall } }
|
1103
|
+
|
1104
|
+
ui.new_command('signal_cont', 'set/get the continue signal (0 == unset)') { |arg|
|
1105
|
+
case arg.to_s.strip
|
1106
|
+
when ''; log "#{@continuesignal} (#{PTrace::SIGNAL[@continuesignal]})"
|
1107
|
+
else @continuesignal = sig2signr(arg)
|
1108
|
+
end
|
1109
|
+
}
|
1110
|
+
end
|
1111
|
+
end
|
1112
|
+
end
|