X7ROOT File Manager
Current Path:
/usr/libexec
usr
/
libexec
/
📁
..
📄
abrt-action-generate-machine-id
(5.69 KB)
📄
abrt-action-install-debuginfo-to-abrt-cache
(14.98 KB)
📄
abrt-action-ureport
(5.7 KB)
📄
abrt-gdb-exploitable
(27.43 KB)
📄
abrt-handle-event
(15.01 KB)
📄
abrt-hook-ccpp
(31.14 KB)
📄
accounts-daemon
(171.16 KB)
📁
anaconda
📄
anydesk
(11.62 MB)
📄
at-spi-bus-launcher
(23.97 KB)
📄
at-spi2-registryd
(89.33 KB)
📁
awk
📁
bluetooth
📄
boltd
(263.39 KB)
📄
camel-gpg-photo-saver
(11.43 KB)
📄
camel-index-control-1.2
(11.29 KB)
📄
camel-lock-helper-1.2
(15.41 KB)
📄
cc-remote-login-helper
(11.11 KB)
📄
chrony-helper
(6.37 KB)
📁
clufter-0.77.1
📄
colord
(329.13 KB)
📄
colord-session
(57.31 KB)
📄
copy_jdk_configs.lua
(9.37 KB)
📄
copy_jdk_configs_fixFiles.sh
(7.17 KB)
📁
coreutils
📄
cups-pk-helper-mechanism
(123.97 KB)
📁
dbus-1
📄
dconf-service
(83.03 KB)
📄
dleyna-server-service
(11.13 KB)
📁
dovecot
📄
ebtables
(1.66 KB)
📄
empathy-auth-client
(28.01 KB)
📄
empathy-call
(187 KB)
📄
empathy-chat
(104.3 KB)
📄
evinced
(40.96 KB)
📄
evolution-addressbook-factory
(11.41 KB)
📄
evolution-addressbook-factory-subprocess
(15.68 KB)
📄
evolution-calendar-factory
(11.41 KB)
📄
evolution-calendar-factory-subprocess
(15.68 KB)
📁
evolution-data-server
📄
evolution-scan-gconf-tree-xml
(52.88 KB)
📄
evolution-source-registry
(114.1 KB)
📄
evolution-user-prompter
(15.56 KB)
📁
fcoe
📄
fence_kdump_send
(15.2 KB)
📁
file-roller
📄
flatpak-bwrap
(52.53 KB)
📄
flatpak-dbus-proxy
(44.97 KB)
📄
flatpak-portal
(91.18 KB)
📄
flatpak-session-helper
(663.18 KB)
📄
flatpak-system-helper
(675.24 KB)
📄
fprintd
(45.24 KB)
📁
fwupd
📁
fwupdate
📄
gam_server
(90.73 KB)
📁
gcc
📄
gcm-helper-exiv
(19.73 KB)
📄
gconf-defaults-mechanism
(32.64 KB)
📄
gconfd-2
(48.7 KB)
📄
gcr-prompter
(11.4 KB)
📄
gcr-ssh-askpass
(44.38 KB)
📄
gdm-disable-wayland
(11.08 KB)
📄
gdm-host-chooser
(43.77 KB)
📄
gdm-session-worker
(274.13 KB)
📄
gdm-simple-chooser
(47.88 KB)
📄
gdm-wayland-session
(64.63 KB)
📄
gdm-x-session
(80.96 KB)
📁
gedit
📄
generate-rndc-key.sh
(546 B)
📄
geoclue
(269.93 KB)
📁
getconf
📁
git-core
📄
glib-pacrunner
(15.73 KB)
📄
gnome-boxes-search-provider
(128.76 KB)
📄
gnome-calculator-search-provider
(28.14 KB)
📄
gnome-contacts-search-provider
(181.12 KB)
📄
gnome-control-center-search-provider
(49.56 KB)
📄
gnome-initial-setup
(936.95 KB)
📄
gnome-initial-setup-copy-worker
(11.2 KB)
📄
gnome-rr-debug
(11.38 KB)
📄
gnome-session-binary
(291.61 KB)
📄
gnome-session-check-accelerated
(11.33 KB)
📄
gnome-session-check-accelerated-gl-helper
(15.44 KB)
📄
gnome-session-check-accelerated-gles-helper
(11.31 KB)
📄
gnome-session-failed
(19.8 KB)
📄
gnome-shell-calendar-server
(36.76 KB)
📄
gnome-shell-hotplug-sniffer
(28.16 KB)
📄
gnome-shell-perf-helper
(15.76 KB)
📄
gnome-shell-portal-helper
(2.06 MB)
📄
gnome-software-cmd
(261.79 KB)
📄
gnome-software-restarter
(11.18 KB)
📁
gnome-system-monitor
📄
gnome-terminal-migration
(40.66 KB)
📄
gnome-terminal-server
(345.11 KB)
📄
gnome-tweak-tool-lid-inhibitor
(1.51 KB)
📄
gnome-welcome-tour
(440 B)
📄
gnupg-pcsc-wrapper
(19.3 KB)
📄
goa-daemon
(45.23 KB)
📄
goa-identity-service
(141.66 KB)
📄
gom-gdata-miner
(28.18 KB)
📄
gom-owncloud-miner
(19.96 KB)
📄
gom-zpj-miner
(15.66 KB)
📄
gpg-check-pattern
(102.95 KB)
📄
gpg-preset-passphrase
(86.39 KB)
📄
gpg-protect-tool
(185.57 KB)
📄
gpg2keys_curl
(44.81 KB)
📄
gpg2keys_finger
(61.34 KB)
📄
gpg2keys_hkp
(53 KB)
📄
gpg2keys_ldap
(61.02 KB)
📄
grepconf.sh
(253 B)
📁
grubby
📄
gsd-a11y-settings
(15.85 KB)
📄
gsd-account
(99.5 KB)
📄
gsd-backlight-helper
(11.3 KB)
📄
gsd-clipboard
(28.41 KB)
📄
gsd-color
(79.23 KB)
📄
gsd-datetime
(62.84 KB)
📄
gsd-disk-utility-notify
(15.72 KB)
📄
gsd-dummy
(15.87 KB)
📄
gsd-housekeeping
(45.71 KB)
📄
gsd-keyboard
(28.59 KB)
📄
gsd-locate-pointer
(32.41 KB)
📄
gsd-media-keys
(211.83 KB)
📄
gsd-mouse
(20.13 KB)
📄
gsd-power
(91.17 KB)
📄
gsd-print-notifications
(40.91 KB)
📄
gsd-printer
(27.86 KB)
📄
gsd-rfkill
(41.13 KB)
📄
gsd-screensaver-proxy
(24.08 KB)
📄
gsd-sharing
(28.5 KB)
📄
gsd-smartcard
(95.89 KB)
📄
gsd-sound
(20.2 KB)
📄
gsd-wacom
(62.37 KB)
📄
gsd-wacom-led-helper
(11.27 KB)
📄
gsd-wacom-oled-helper
(15.33 KB)
📄
gsd-xsettings
(59.34 KB)
📄
gst-install-plugins-helper
(19.68 KB)
📁
gstreamer-0.10
📁
gstreamer-1.0
📄
gvfs-afc-volume-monitor
(90.86 KB)
📄
gvfs-goa-volume-monitor
(95.33 KB)
📄
gvfs-gphoto2-volume-monitor
(95.09 KB)
📄
gvfs-mtp-volume-monitor
(90.95 KB)
📄
gvfs-udisks2-volume-monitor
(171.29 KB)
📄
gvfsd
(32.57 KB)
📄
gvfsd-admin
(36.86 KB)
📄
gvfsd-afc
(61.3 KB)
📄
gvfsd-afp
(127.95 KB)
📄
gvfsd-afp-browse
(107.2 KB)
📄
gvfsd-archive
(32.65 KB)
📄
gvfsd-burn
(32.46 KB)
📄
gvfsd-cdda
(32.48 KB)
📄
gvfsd-computer
(41.01 KB)
📄
gvfsd-dav
(99.82 KB)
📄
gvfsd-dnssd
(32.58 KB)
📄
gvfsd-ftp
(94.51 KB)
📄
gvfsd-fuse
(41.08 KB)
📄
gvfsd-google
(65.78 KB)
📄
gvfsd-gphoto2
(65.6 KB)
📄
gvfsd-http
(40.98 KB)
📄
gvfsd-localtest
(44.63 KB)
📄
gvfsd-metadata
(78.63 KB)
📄
gvfsd-mtp
(69.56 KB)
📄
gvfsd-network
(32.63 KB)
📄
gvfsd-recent
(32.56 KB)
📄
gvfsd-sftp
(99.01 KB)
📄
gvfsd-smb
(48.93 KB)
📄
gvfsd-smb-browse
(65.65 KB)
📄
gvfsd-trash
(49.48 KB)
📁
heartbeat
📄
httpd-ssl-pass-dialog
(81 B)
📁
hypervkvpd
📄
ibus-dconf
(19.75 KB)
📄
ibus-engine-chewing
(97.91 KB)
📄
ibus-engine-hangul
(32.59 KB)
📄
ibus-engine-kkc
(62.29 KB)
📄
ibus-engine-libpinyin
(204.85 KB)
📄
ibus-engine-m17n
(36.52 KB)
📄
ibus-engine-rawcode
(19.75 KB)
📄
ibus-engine-sayura
(16.55 KB)
📄
ibus-engine-simple
(11.47 KB)
📄
ibus-engine-table
(1.4 KB)
📄
ibus-portal
(78.53 KB)
📄
ibus-setup-hangul
(902 B)
📄
ibus-setup-kkc
(82.04 KB)
📄
ibus-setup-libpinyin
(1.04 KB)
📄
ibus-setup-m17n
(28.23 KB)
📄
ibus-ui-emojier
(103.55 KB)
📄
ibus-ui-gtk3
(278.48 KB)
📄
ibus-x11
(93.1 KB)
📄
imsettings-check
(15.3 KB)
📄
imsettings-daemon
(57.24 KB)
📄
imsettings-functions
(6.71 KB)
📄
imsettings-target-checker.sh
(2.82 KB)
📁
initial-setup
📁
initscripts
📁
ipsec
📄
iscsi-mark-root-nodes
(852 B)
📁
kde4
📄
ksmctl
(7.11 KB)
📁
libinput
📄
libvirt-guests.sh
(15.85 KB)
📄
libvirt_iohelper
(410.68 KB)
📄
libvirt_leaseshelper
(414.67 KB)
📄
libvirt_parthelper
(414.67 KB)
📁
linux-boot-probes
📁
lm_sensors
📁
lsm.d
📁
man-db
📄
mariadb-prepare-db-dir
(6.02 KB)
📄
mariadb-wait-ready
(1.71 KB)
📄
mbim-proxy
(15.21 KB)
📁
microcode_ctl
📄
mission-control-5
(374.55 KB)
📄
mlx4-setup.sh
(2.48 KB)
📄
mutter-restart-helper
(11.08 KB)
📄
mysqld
(13.64 MB)
📄
netcf-transaction.sh
(7.21 KB)
📄
newns
(7.03 KB)
📄
nm-dhcp-helper
(15.12 KB)
📄
nm-dispatcher
(47.7 KB)
📄
nm-iface-helper
(839.36 KB)
📄
nm-ifdown
(155 B)
📄
nm-ifup
(153 B)
📄
nm-libreswan-auth-dialog
(19.7 KB)
📄
nm-libreswan-service
(70.81 KB)
📄
nm-libreswan-service-helper
(36.78 KB)
📄
ntpdate-wrapper
(806 B)
📁
oddjob
📄
openipmi-helper
(12.54 KB)
📁
openldap
📁
openssh
📁
os-probes
📁
p11-kit
📁
p7zip
📁
pacemaker
📄
packagekit-direct
(99.72 KB)
📄
packagekitd
(293.48 KB)
📄
pk-command-not-found
(40.55 KB)
📄
pk-gstreamer-install
(19.68 KB)
📄
pk-offline-update
(32.16 KB)
📄
platform-python
(6.98 KB)
📁
plymouth
📁
postfix
📁
proftpd
📁
psacct
📁
pulse
📄
qemu-bridge-helper
(15 KB)
📄
qemu-kvm
(5.02 MB)
📄
qmi-proxy
(11.24 KB)
📄
rdma-init-kernel
(5.59 KB)
📄
rdma-set-sriov-vf
(3.05 KB)
📄
rtkit-daemon
(59.64 KB)
📁
selinux
📄
setup-named-chroot.sh
(2.63 KB)
📁
smartmontools
📁
spice-gtk-x86_64
📁
sudo
📄
sushi-start
(15.5 KB)
📁
systemtap
📄
telepathy-gabble
(1 MB)
📄
telepathy-haze
(199.66 KB)
📄
telepathy-logger
(11.27 KB)
📄
telepathy-salut
(583.88 KB)
📄
totem-gallery-thumbnailer
(32.24 KB)
📄
tracker-extract
(91.48 KB)
📄
tracker-miner-apps
(32.4 KB)
📄
tracker-miner-fs
(127.7 KB)
📄
tracker-miner-user-guides
(28.46 KB)
📄
tracker-store
(139.55 KB)
📄
tracker-writeback
(41.11 KB)
📄
truescale-serdes.cmds
(8.5 KB)
📁
tuned
📁
udisks2
📄
upowerd
(247.37 KB)
📄
urlgrabber-ext-down
(2.54 KB)
📁
usermin
📁
utempter
📄
vino-server
(281.09 KB)
📄
virt-what-cpuid-helper
(7.02 KB)
📁
virtuoso
📁
webkit2gtk-4.0
📁
webkitgtk3
📁
webmin
📄
xdg-desktop-portal
(557.36 KB)
📄
xdg-desktop-portal-gtk
(567.41 KB)
📄
xdg-document-portal
(174.6 KB)
📄
xdg-permission-store
(95.98 KB)
📄
xf86-video-intel-backlight-helper
(7.13 KB)
📄
xinputinfo.sh
(3.74 KB)
Editing: abrt-gdb-exploitable
#!/usr/bin/python # This is a GDB plugin. # Usage: # gdb --batch -ex 'python execfile("THIS_FILE")' -ex run -ex abrt-exploitable PROG # or # gdb --batch -ex 'python execfile("THIS_FILE")' -ex 'core COREDUMP' -ex abrt-exploitable import sys import os import signal import re import gettext import locale import gdb GETTEXT_PROGNAME = "abrt" _ = gettext.lgettext def init_gettext(): try: locale.setlocale(locale.LC_ALL, "") except locale.Error: os.environ['LC_ALL'] = 'C' locale.setlocale(locale.LC_ALL, "") # Defeat "AttributeError: 'module' object has no attribute 'nl_langinfo'" try: gettext.bind_textdomain_codeset(GETTEXT_PROGNAME, locale.nl_langinfo(locale.CODESET)) except AttributeError: pass gettext.bindtextdomain(GETTEXT_PROGNAME, '/usr/share/locale') gettext.textdomain(GETTEXT_PROGNAME) _WRITES_ALWAYS = -1 _WRITES_IF_MEMREF = -2 _x86_writing_instr = { # insn:N, where N: # -1: this insn always writes to memory # -2: writes to memory if any operand is a memory operand # 2: writes to memory if 2nd (or later) operand is a memory operand # # Two-operand insns "add": 2, "adc": 2, "sub": 2, "sbb": 2, "and": 2, "xor": 2, "or": 2, "xadd": 2, "cmpxchg": 2, # One-operand insns. Can use 1 or _WRITES_IF_MEMREF "inc": _WRITES_IF_MEMREF, "dec": _WRITES_IF_MEMREF, "neg": _WRITES_IF_MEMREF, "not": _WRITES_IF_MEMREF, "pop": _WRITES_IF_MEMREF, # "Set byte on condition". One-operand insns. "seta": _WRITES_IF_MEMREF, "setae": _WRITES_IF_MEMREF, "setb": _WRITES_IF_MEMREF, "setbe": _WRITES_IF_MEMREF, "setc": _WRITES_IF_MEMREF, "sete": _WRITES_IF_MEMREF, "setg": _WRITES_IF_MEMREF, "setge": _WRITES_IF_MEMREF, "setl": _WRITES_IF_MEMREF, "setle": _WRITES_IF_MEMREF, "setna": _WRITES_IF_MEMREF, "setnae": _WRITES_IF_MEMREF, "setnb": _WRITES_IF_MEMREF, "setnbe": _WRITES_IF_MEMREF, "setnc": _WRITES_IF_MEMREF, "setne": _WRITES_IF_MEMREF, "setng": _WRITES_IF_MEMREF, "setnge": _WRITES_IF_MEMREF, "setnl": _WRITES_IF_MEMREF, "setnle": _WRITES_IF_MEMREF, "setno": _WRITES_IF_MEMREF, "setnp": _WRITES_IF_MEMREF, "setns": _WRITES_IF_MEMREF, "setnz": _WRITES_IF_MEMREF, "seto": _WRITES_IF_MEMREF, "setp": _WRITES_IF_MEMREF, "setpe": _WRITES_IF_MEMREF, "setpo": _WRITES_IF_MEMREF, "sets": _WRITES_IF_MEMREF, "setz": _WRITES_IF_MEMREF, # Shifts. # sarl $2,(%rcx) # sarl (%rax) - *implicit* operand (shift count) 1. # shld 11,%ecx,(%rdi) - *third* operand is r/m. # Luckily, any memory operand is a destination, can use _WRITES_IF_MEMREF. "shl": _WRITES_IF_MEMREF, "shr": _WRITES_IF_MEMREF, "sal": _WRITES_IF_MEMREF, "sar": _WRITES_IF_MEMREF, "rol": _WRITES_IF_MEMREF, "ror": _WRITES_IF_MEMREF, "rcl": _WRITES_IF_MEMREF, "rcr": _WRITES_IF_MEMREF, "shld": _WRITES_IF_MEMREF, "shrd": _WRITES_IF_MEMREF, # Bit tests. Any memory operand is a destination, can use _WRITES_IF_MEMREF. "bts": _WRITES_IF_MEMREF, "btr": _WRITES_IF_MEMREF, "btc": _WRITES_IF_MEMREF, # One-operand (register pair is another, implicit operand). "cmpxchg8b": _WRITES_IF_MEMREF, "cmpxchg16b": _WRITES_IF_MEMREF, # Either mem operand indicates write to mem. "xchg": _WRITES_IF_MEMREF, # String store insns. # Look similar to widening signed move "movs[bwl][wlq]", # but aliasing doesn't happen since widening move has two siffixes "movs": _WRITES_ALWAYS, "stos": _WRITES_ALWAYS, # Widening moves never store to mem. # May look like we need to list them because otherwise they get caught # by "movXXX", but thankfully their 2nd operand is never a memory reference, # which "movXXX" wildcard checks. #"mov[sz][bwl][wlq]":0, # One-operand insn. # These are system insns, but they do NOT cause exception in userspace. "smsw": _WRITES_IF_MEMREF, "sgdt": _WRITES_IF_MEMREF, "sidt": _WRITES_IF_MEMREF, "sldt": _WRITES_IF_MEMREF, "str": _WRITES_IF_MEMREF, # FPU/SIMD madness follows. # FPU store insns. One-operand. "fsts": _WRITES_IF_MEMREF, "fstl": _WRITES_IF_MEMREF, #"fstt" doesn't exist "fstps": _WRITES_IF_MEMREF, "fstpl": _WRITES_IF_MEMREF, "fstpt": _WRITES_IF_MEMREF, # Saving state. One-operand insns. "fstcw": _WRITES_IF_MEMREF, "fnstcw": _WRITES_IF_MEMREF, "fstsw": _WRITES_IF_MEMREF, "fnstsw": _WRITES_IF_MEMREF, "fstenv": _WRITES_IF_MEMREF, "fnstenv": _WRITES_IF_MEMREF, "fsave": _WRITES_IF_MEMREF, "fnsave": _WRITES_IF_MEMREF, "fxsave": _WRITES_IF_MEMREF, "xsave": _WRITES_IF_MEMREF, "xsaveopt": _WRITES_IF_MEMREF, "fsave64": _WRITES_IF_MEMREF, "fnsave64": _WRITES_IF_MEMREF, "fxsave64": _WRITES_IF_MEMREF, "xsave64": _WRITES_IF_MEMREF, "xsaveopt64": _WRITES_IF_MEMREF, "stmxcsr": _WRITES_IF_MEMREF, "vstmxcsr": _WRITES_IF_MEMREF, # SIMD store insns. # Three-operand insns. Any memory operand is a destination. "vcvtps2ph": _WRITES_IF_MEMREF, "extractps": _WRITES_IF_MEMREF, "vextractps": _WRITES_IF_MEMREF, #[v]extractpd does not exist "vextractf128": _WRITES_IF_MEMREF, "vextracti128": _WRITES_IF_MEMREF, "pextr": _WRITES_IF_MEMREF, # covers pextr[bwq] "pextrd": _WRITES_IF_MEMREF, "vpextr": _WRITES_IF_MEMREF, "vpextrd": _WRITES_IF_MEMREF, "vmaskmovpd": _WRITES_IF_MEMREF, "vmaskmovps": _WRITES_IF_MEMREF, "vpmaskmovd": _WRITES_IF_MEMREF, "vpmaskmovq": _WRITES_IF_MEMREF, # These insns have implicit (%edi) dest operand: "maskmovq": _WRITES_ALWAYS, # mmx version "maskmovdqu": _WRITES_ALWAYS, "vmaskmovdqu": _WRITES_ALWAYS, # check binutils/gas/testsuite/gas/i386/* for more weird insns # Instruction Set Reference, A-M and N-Z: # http://download.intel.com/products/processor/manual/253666.pdf # http://download.intel.com/products/processor/manual/253667.pdf # SSE4: # http://software.intel.com/sites/default/files/m/0/3/c/d/4/18187-d9156103.pdf # Instruction Set Extensions: # http://download-software.intel.com/sites/default/files/319433-014.pdf # Xeon Phi: # http://download-software.intel.com/sites/default/files/forum/278102/327364001en.pdf #"[v]movXXX" - special-cased in the code "mov": 2 # Note: stack-writing instructions are omitted } _x86_pushing_instr = ( "push", "pusha", "pushf", "enter", "call", "lcall" ) _x86_intdiv_instr = ("div", "idiv") _x86_jumping_instr = ( "jmp", # indirect jumps/calls with garbage data "call", # call: also possible that stack is exhausted (infinite recursion) "ljmp", "lcall", # Yes, lret/iret isn't used in normal userspace code, # but it does work (compile with "gcc -nostartfiles -nostdlib -m32"): # #_start: .globl _start # pushf # push %cs # push $next # iret # lret or ret would work too #next: # movl $42, %ebx # movl $1, %eax # int $0x80 # exit(42) # "iret", "lret", "ret" ) # stack was smashed if we crash on one of these _x86_return_instr = ("iret", "lret", "ret") _x86_mem_op1_regex = re.compile("^((-?0x)|[(])") _x86_mem_op2_regex = re.compile("[,:]((-?0x)|[(])") def _x86_fetch_insn_from_table(ins, table): if not ins: return None if ins in table: if type(table) == dict: return table[ins] return ins # Drop common byte/word/long/quad suffix and try again if ins[-1] in ("b", "w", "l", "q"): ins = ins[:-1] if ins in table: if type(table) == dict: return table[ins] return ins return None class SignalAndInsn: def x86_instruction_is_store(self): operand = _x86_fetch_insn_from_table(self.mnemonic, _x86_writing_instr) if not operand: if not self.mnemonic: return False # There are far too many SSE store instructions, # don't want to pollute the table with them. # Special-case the check for MOVxxx # and its SIMD cousins VMOVxxx: if self.mnemonic[:3] != "mov" and self.mnemonic[:4] != "vmov": return False operand = 2 if operand == _WRITES_ALWAYS: # no need to check operands, it's a write return True # Memory operands look like this: [%seg:][[-]0xHEXNUM][(%reg[,...])] # Careful with immediate operands which are $0xHEXNUM # and FPU register references which are st(N). if _x86_mem_op1_regex.search(self.operands): mem_op_pos = 0 else: match = _x86_mem_op2_regex.search(self.operands) if not match: return False # no memory operands mem_op_pos = match.start() + 1 if operand == _WRITES_IF_MEMREF: # any mem operand indicates write return True comma = self.operands.find(",") if mem_op_pos < comma: # "%cs:0x0(%rax,%rax,1),foo" - 1st operand is memory # "%cs:0x0(%rax),foo" - 1st operand is memory memory_operand = 1 elif comma < 0: # "%cs:0x0(%rax)" - 1st operand is memory memory_operand = 1 else: # mem_op_pos is after comma # "foo,%cs:0x0(%rax,%rax,1)" - 2nd operand is memory # (It also can be a third, fourth etc operand) memory_operand = 2 if operand == memory_operand: return True return False def x86_get_instruction(self): try: # just "disassemble $pc" won't work if $pc doesn't point # inside a known function raw_instructions = gdb.execute("disassemble $pc,$pc+32", to_string=True) except gdb.error: # For example, if tracee already exited normally. # Another observed case is if $pc points to unmapped area. # We get "Python Exception <class 'gdb.error'> No registers" return instructions = [] current = None for line in raw_instructions.split("\n"): # line can be: # "Dump of assembler code from 0xAAAA to 0xBBBB:" # "[=>] 0x00000000004004dc[ <+0>]: push %rbp" # (" <+0>" part is present when we run on a live process, # on coredump it is absent) # "End of assembler dump." # "" (empty line) if line.startswith("=>"): line = line[2:] current = len(instructions) line = line.split(":", 1) if len(line) < 2: # no ":"? continue line = line[1] # drop "foo:" line = line.strip() # drop leading/trailing whitespace if line: instructions.append(line) if current == None: # we determined that $pc points to a bad address, # which is an interesting fact. return # There can be a disasm comment: "insn op,op,op # comment"; # strip it, and whitespace on both ends: t = instructions[current].split("#", 1)[0].strip() self.current_instruction = t # Strip prefixes: while True: t = t.split(None, 1) self.mnemonic = t[0] if len(t) < 2: break if self.mnemonic.startswith("rex."): t = t[1] continue if self.mnemonic in ( "data32", "data16", "addr32", "addr16", "rex", "cs", "ds", "es", "ss", "fs", "gs", "lock", "rep", "repz", "repnz", "xacquire", "xrelease" ): t = t[1] continue # First word isn't a prefix -> we found the insn word self.operands = t[1] break self.instruction_is_pushing = (_x86_fetch_insn_from_table(self.mnemonic, _x86_pushing_instr) is not None) self.instruction_is_division = (_x86_fetch_insn_from_table(self.mnemonic, _x86_intdiv_instr) is not None) self.instruction_is_branch = (_x86_fetch_insn_from_table(self.mnemonic, _x86_jumping_instr) is not None) self.instruction_is_return = (_x86_fetch_insn_from_table(self.mnemonic, _x86_return_instr) is not None) self.instruction_is_store = self.x86_instruction_is_store() def ppc_get_instruction(self): try: # just "disassemble $pc" won't work if $pc doesn't point # inside a known function raw_instructions = gdb.execute("disassemble $pc,$pc+32", to_string=True) except gdb.error: # For example, if tracee already exited normally. # Another observed case is if $pc points to unmapped area. # We get "Python Exception <class 'gdb.error'> No registers" return instructions = [] current = None for line in raw_instructions.split("\n"): # line can be: # "Dump of assembler code from 0xAAAA to 0xBBBB:" # "[=>] 0x00000000004004dc[ <+0>]: push %rbp" # (" <+0>" part is present when we run on a live process, # on coredump it is absent) # "End of assembler dump." # "" (empty line) if line.startswith("=>"): line = line[2:] current = len(instructions) line = line.split(":", 1) if len(line) < 2: # no ":"? continue line = line[1] # drop "foo:" line = line.strip() # drop leading/trailing whitespace if line: instructions.append(line) if current is None: # we determined that $pc points to a bad address, # which is an interesting fact. return # There can be a disasm comment: "insn op,op,op # comment"; # strip it, and whitespace on both ends: t = instructions[current].split("#", 1)[0].strip() self.current_instruction = t # Split it into mnemonic and operands t = t.split(None, 1) self.mnemonic = t[0] if len(t) > 1: self.operands = t[1] self.instruction_is_store = self.mnemonic.startswith("st") self.instruction_is_branch = self.mnemonic.startswith("b") self.instruction_is_pushing = (self.instruction_is_store and "(r1)" in self.operands) # Looks like div[o] insns on ppc don't cause exceptions # (need to check whether, and how, FPE is generated) #self.instruction_is_division = # On ppc, return insn is b[cond]lr. TODO: is cond form ever used by gcc? self.instruction_is_return = (self.mnemonic == "blr") def get_instruction(self): self.current_instruction = None self.mnemonic = None self.operands = "" self.instruction_is_division = None self.instruction_is_store = None self.instruction_is_pushing = None self.instruction_is_return = None self.instruction_is_branch = None try: arch = gdb.execute("show architecture", to_string=True) # Examples of the string we get: # The target architecture is set automatically (currently i386) # The target architecture is set automatically (currently i386:x86-64) # The target architecture is set automatically (currently powerpc:common64) if " i386" in arch: return self.x86_get_instruction() if " powerpc" in arch: return self.ppc_get_instruction() except gdb.error: return def get_signal(self): self.signo = None self.si_code = None try: # Requires new kernels which record complete siginfo # in coredumps (Linux 3.9 still don't have it), # and new gdb: sig = gdb.parse_and_eval("$_siginfo.si_signo") code = gdb.parse_and_eval("$_siginfo.si_code") # Requires patched gdb: #sig = gdb.parse_and_eval("$_signo") # # type(sig) = <type 'gdb.Value'>, convert to plain int: self.signo = int(sig) self.si_code = int(code) except gdb.error: # "Python Exception <class 'gdb.error'> # Attempt to extract a component of a value that is not a structure" # Possible reasons why $_siginfo doesn't exist: # program is still running, program exited normally, # we work with a coredump from an old kernel. # # Lets see whether we are running from the abrt and it # provided us with signal number. Horrible hack :( # try: self.signo = int(os.environ["SIGNO_OF_THE_COREDUMP"]) except KeyError: return False return True #Our initial set of testing will use the list Apple included in their #CrashWrangler announcement: # #Exploitable if: # Crash on write instruction # Crash executing invalid address # Crash calling an invalid address # Crash accessing an uninitialized or freed pointer as indicated by # using the MallocScribble environment variable # Illegal instruction exception # Abort due to -fstack-protector, _FORTIFY_SOURCE, heap corruption # detected # Stack trace of crashing thread contains certain functions such as # malloc, free, szone_error, objc_MsgSend, etc. def is_exploitable(self): self.exploitable_rating = 3 self.exploitable_desc = "" # siginfo.si_code: # If <= 0, then it's not a crash: # SI_ASYNCNL = -60 /* asynch name lookup completion */ # SI_TKILL = -6 /* tkill (and tgkill?) */ # SI_SIGIO = -5 /* queued SIGIO */ # SI_ASYNCIO = -4 /* AIO completion */ # SI_MESGQ = -3 /* real time mesq state change */ # SI_TIMER = -2 /* timer expiration (timer_create() with SIGEV_SIGNAL) */ # SI_QUEUE = -1 /* sigqueue */ # SI_USER = 0 /* kill, sigsend */ # Crashes have si_code > 0: # testDivideByZero: SIGFPE si_code=FPE_INTDIV(1), si_addr=0x40054a # x86-64 opcode 0x62: SIGILL si_code=ILL_ILLOPN(2), si_addr=0x40053f # x86-64 priv.insn.: SIGSEGV si_code=SI_KERNEL(128), si_addr=0 # testExecuteInvalid: SIGSEGV si_code=SEGV_MAPERR(1), si_addr=0x1c2404000 # testStackBufferOverflow ("ret" to bad address): # SIGSEGV si_code=SI_KERNEL(128), si_addr=0 # testStackRecursion: SIGSEGV si_code=SEGV_MAPERR(1), si_addr=0x7fff4c216d28 # testWriteRandom: SIGSEGV si_code=SEGV_MAPERR(1), si_addr=0x1eb004004 # However: # Keyboard signals (^C INT, ^\ QUIT, ^Z TSTP) also have si_code=SI_KERNEL. # SIGWINCH has si_code=SI_KERNEL. # SIGALRM from alarm(N) has si_code=SI_KERNEL. # Surprisingly, SIGPIPE has si_code=SI_USER! if self.si_code is not None: # Filter out user-generated signals: if self.si_code == -6 or self.si_code == -1: # SI_TKILL/SI_QUEUE self.exploitable_rating = 0 self.exploitable_desc = _("Signal sent by userspace code") return if self.si_code < 0: self.exploitable_rating = 0 self.exploitable_desc = _("Signal sent by timer/IO/async event") return # Unfortunately, this isn't reliable to flag user-sent signals: # not only SIGPIPE, but some other kernel signals have SI_USER # (grep kernel sources for "send_sig(sig, ..., 0)"). # At least we know it's not a crash. if self.si_code == 0: # SI_USER self.exploitable_rating = 0 self.exploitable_desc = _("Signal has siginfo.si_code = SI_USER") # Special case (a kernel buglet?) if self.signo == signal.SIGPIPE: self.exploitable_desc = _("Signal due to write to closed pipe") return # And kernel-generated ones: if self.si_code == 0x80: # SI_KERNEL if self.signo in (signal.SIGINT, signal.SIGQUIT, signal.SIGTSTP): self.exploitable_rating = 0 self.exploitable_desc = _("Signal sent by keyboard") return if self.signo in (signal.SIGTTIN, signal.SIGTTOU, signal.SIGHUP): self.exploitable_rating = 0 self.exploitable_desc = _("Job control signal sent by kernel") return if self.signo == signal.SIGWINCH: self.exploitable_rating = 0 self.exploitable_desc = _("Signal sent by window resize") return if self.signo == signal.SIGALRM: self.exploitable_rating = 0 self.exploitable_desc = _("Signal sent by alarm(N) expiration") return # else: Can't rule out "crash" signal: may be FPE/ILL/BUS/SEGV. # Fall through into signo/insn analysis. # else: We are here if signal was not from user and not SI_KERNEL. # Fall through into signo/insn analysis. # else: We are here if si_code isn't known. # Fall through into signo/insn analysis. # Guessing here... it might be kill(2) as well. # Should I add "Likely ..." to the descriptions? if self.signo in (signal.SIGINT, signal.SIGQUIT, signal.SIGTSTP): self.exploitable_rating = 0 self.exploitable_desc = _("Signal sent by keyboard") return if self.signo in (signal.SIGTTIN, signal.SIGTTOU, signal.SIGHUP): self.exploitable_rating = 0 self.exploitable_desc = _("Job control signal sent by kernel") return if self.signo == signal.SIGPIPE: self.exploitable_rating = 0 self.exploitable_desc = _("Signal due to write to broken pipe") return if self.signo == signal.SIGWINCH: self.exploitable_rating = 0 self.exploitable_desc = _("Signal sent by window resize") return if self.signo == signal.SIGALRM: self.exploitable_rating = 0 self.exploitable_desc = _("Signal sent by alarm(N) expiration") return # Which signals can coredump? # SIGABRT Abort signal from abort(3) # SIGQUIT Quit from keyboard # SIGXCPU CPU time limit exceeded # SIGXFSZ File size limit exceeded # SIGTRAP Trace/breakpoint trap # SIGSYS Bad argument to routine (SVr4) # SIGFPE Floating point exception # SIGILL Illegal Instruction # SIGSEGV Invalid memory reference # SIGBUS Bus error (bad memory access) if self.signo == signal.SIGABRT: self.exploitable_rating = 0 self.exploitable_desc = _("ABRT signal (abort() was called?)") return # Already handled above: #if self.signo == signal.SIGQUIT: # self.exploitable_rating = 0 # self.exploitable_desc = _("QUIT signal (Ctrl-\\ pressed?)") # return if self.signo == signal.SIGXCPU: self.exploitable_rating = 0 self.exploitable_desc = _("XCPU signal (over CPU time limit)") return if self.signo == signal.SIGXFSZ: self.exploitable_rating = 0 self.exploitable_desc = _("XFSZ signal (over file size limit)") return if self.signo == signal.SIGTRAP: self.exploitable_rating = 0 self.exploitable_desc = _("TRAP signal (can be a bug in a debugger/tracer)") return if self.signo == signal.SIGSYS: self.exploitable_rating = 1 self.exploitable_desc = _("SYS signal (unknown syscall was called?)") return if self.signo == signal.SIGFPE: self.exploitable_rating = 1 self.exploitable_desc = _("Arithmetic exception") # 1 is FPE_INTDIV if self.si_code == 1 or self.instruction_is_division: self.exploitable_rating = 0 self.exploitable_desc = _("Division by zero") return if self.signo == signal.SIGILL: self.exploitable_rating = 5 self.exploitable_desc = _("Illegal instruction (jump to a random address?)") return if self.signo != signal.SIGSEGV and self.signo != signal.SIGBUS: self.exploitable_rating = 2 # Pity that we can't give a more descriptive explanation self.exploitable_desc = _("Non-crash related signal") return if self.instruction_is_pushing: self.exploitable_rating = 4 self.exploitable_desc = _("Stack overflow") return if self.instruction_is_store: self.exploitable_rating = 6 self.exploitable_desc = _("Write to an invalid address") return if self.instruction_is_return: self.exploitable_rating = 7 self.exploitable_desc = _("Subroutine return to an invalid address (corrupted stack?)") return # Note: we check "ret" first, _then_ jumps. # Corrupted stack is different from corrupted data. if self.instruction_is_branch: self.exploitable_rating = 6 self.exploitable_desc = _("Jump to an invalid address") return if not self.current_instruction: self.exploitable_rating = 6 self.exploitable_desc = _("Jump to an invalid address") return if self.signo == signal.SIGBUS: self.exploitable_rating = 5 self.exploitable_desc = _("Access past the end of mapped file, invalid address, unaligned access, etc") return # default values remain (e.g. description is "") class AbrtExploitable(gdb.Command): "Analyze a crash to determine exploitability" def __init__(self): super(AbrtExploitable, self).__init__( "abrt-exploitable", gdb.COMMAND_SUPPORT, # command class gdb.COMPLETE_NONE, # completion method False # => it's not a prefix command ) init_gettext() # Called when the command is invoked from GDB def invoke(self, args, from_tty): si = SignalAndInsn() if not si.get_signal(): sys.stderr.write(_("Can't get signal no and do exploitability analysis\n")) return si.get_instruction() min_rating = 0 if args: args = args.split(None, 1) min_rating = int(args[0]) si.is_exploitable() if si.exploitable_desc: if si.exploitable_rating >= min_rating: f = sys.stdout if args and len(args) > 1: f = open(args[1], 'w') f.write(_("Likely crash reason: ") + si.exploitable_desc + "\n") f.write(_("Exploitable rating (0-9 scale): ") + str(si.exploitable_rating) + "\n") if si.current_instruction: f.write(_("Current instruction: ") + si.current_instruction + "\n") else: sys.stderr.write(_("Exploitability analysis came up empty\n")) AbrtExploitable()
Upload File
Create Folder