metasm 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|