summaryrefslogtreecommitdiff
path: root/plugins/python
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2010-03-31 21:12:35 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2010-03-31 21:12:35 (GMT)
commit7cbdd17b441b35d48624956aa438bde69f18bc37 (patch)
tree438af8d0a994d6e203cf66ea91cf336bb071ee44 /plugins/python
parentd5e55f2ad015781bd7bee0e3216e47d6218e0841 (diff)
Implemented first steps to a Python plugins support.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@146 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'plugins/python')
-rw-r--r--plugins/python/lnxsyscalls/lnxsyscalls.py517
1 files changed, 517 insertions, 0 deletions
diff --git a/plugins/python/lnxsyscalls/lnxsyscalls.py b/plugins/python/lnxsyscalls/lnxsyscalls.py
new file mode 100644
index 0000000..92d5763
--- /dev/null
+++ b/plugins/python/lnxsyscalls/lnxsyscalls.py
@@ -0,0 +1,517 @@
+#!/usr/bin/python
+
+from pyoida import Plugin
+from pyoida.analysis import RenderingOptions
+from pyoida.arch import ArchProcessorType
+
+
+class SysCallDB():
+ """xxx"""
+
+ def __init__(self):
+
+ self.__syscalls = [
+ "__NR_restart_syscall",
+ "__NR_exit",
+ "__NR_fork",
+ "__NR_read",
+ "__NR_write",
+ "__NR_open",
+ "__NR_close",
+ "__NR_waitpid",
+ "__NR_creat",
+ "__NR_link",
+ "__NR_unlink",
+ "__NR_execve",
+ "__NR_chdir",
+ "__NR_time",
+ "__NR_mknod",
+ "__NR_chmod",
+ "__NR_lchown",
+ "__NR_break",
+ "__NR_oldstat",
+ "__NR_lseek",
+ "__NR_getpid",
+ "__NR_mount",
+ "__NR_umount",
+ "__NR_setuid",
+ "__NR_getuid",
+ "__NR_stime",
+ "__NR_ptrace",
+ "__NR_alarm",
+ "__NR_oldfstat",
+ "__NR_pause",
+ "__NR_utime",
+ "__NR_stty",
+ "__NR_gtty",
+ "__NR_access",
+ "__NR_nice",
+ "__NR_ftime",
+ "__NR_sync",
+ "__NR_kill",
+ "__NR_rename",
+ "__NR_mkdir",
+ "__NR_rmdir",
+ "__NR_dup",
+ "__NR_pipe",
+ "__NR_times",
+ "__NR_prof",
+ "__NR_brk",
+ "__NR_setgid",
+ "__NR_getgid",
+ "__NR_signal",
+ "__NR_geteuid",
+ "__NR_getegid",
+ "__NR_acct",
+ "__NR_umount2",
+ "__NR_lock",
+ "__NR_ioctl",
+ "__NR_fcntl",
+ "__NR_mpx",
+ "__NR_setpgid",
+ "__NR_ulimit",
+ "__NR_oldolduname",
+ "__NR_umask",
+ "__NR_chroot",
+ "__NR_ustat",
+ "__NR_dup2",
+ "__NR_getppid",
+ "__NR_getpgrp",
+ "__NR_setsid",
+ "__NR_sigaction",
+ "__NR_sgetmask",
+ "__NR_ssetmask",
+ "__NR_setreuid",
+ "__NR_setregid",
+ "__NR_sigsuspend",
+ "__NR_sigpending",
+ "__NR_sethostname",
+ "__NR_setrlimit",
+ "__NR_getrlimit",
+ "__NR_getrusage",
+ "__NR_gettimeofday",
+ "__NR_settimeofday",
+ "__NR_getgroups",
+ "__NR_setgroups",
+ "__NR_select",
+ "__NR_symlink",
+ "__NR_oldlstat",
+ "__NR_readlink",
+ "__NR_uselib",
+ "__NR_swapon",
+ "__NR_reboot",
+ "__NR_readdir",
+ "__NR_mmap",
+ "__NR_munmap",
+ "__NR_truncate",
+ "__NR_ftruncate",
+ "__NR_fchmod",
+ "__NR_fchown",
+ "__NR_getpriority",
+ "__NR_setpriority",
+ "__NR_profil",
+ "__NR_statfs",
+ "__NR_fstatfs",
+ "__NR_ioperm",
+ "__NR_socketcall",
+ "__NR_syslog",
+ "__NR_setitimer",
+ "__NR_getitimer",
+ "__NR_stat",
+ "__NR_lstat",
+ "__NR_fstat",
+ "__NR_olduname",
+ "__NR_iopl",
+ "__NR_vhangup",
+ "__NR_idle",
+ "__NR_vm86old",
+ "__NR_wait4",
+ "__NR_swapoff",
+ "__NR_sysinfo",
+ "__NR_ipc",
+ "__NR_fsync",
+ "__NR_sigreturn",
+ "__NR_clone",
+ "__NR_setdomainname",
+ "__NR_uname",
+ "__NR_modify_ldt",
+ "__NR_adjtimex",
+ "__NR_mprotect",
+ "__NR_sigprocmask",
+ "__NR_create_module",
+ "__NR_init_module",
+ "__NR_delete_module",
+ "__NR_get_kernel_syms",
+ "__NR_quotactl",
+ "__NR_getpgid",
+ "__NR_fchdir",
+ "__NR_bdflush",
+ "__NR_sysfs",
+ "__NR_personality",
+ "__NR_afs_syscall",
+ "__NR_setfsuid",
+ "__NR_setfsgid",
+ "__NR__llseek",
+ "__NR_getdents",
+ "__NR__newselect",
+ "__NR_flock",
+ "__NR_msync",
+ "__NR_readv",
+ "__NR_writev",
+ "__NR_getsid",
+ "__NR_fdatasync",
+ "__NR__sysctl",
+ "__NR_mlock",
+ "__NR_munlock",
+ "__NR_mlockall",
+ "__NR_munlockall",
+ "__NR_sched_setparam",
+ "__NR_sched_getparam",
+ "__NR_sched_setscheduler",
+ "__NR_sched_getscheduler",
+ "__NR_sched_yield",
+ "__NR_sched_get_priority_max",
+ "__NR_sched_get_priority_min",
+ "__NR_sched_rr_get_interval",
+ "__NR_nanosleep",
+ "__NR_mremap",
+ "__NR_setresuid",
+ "__NR_getresuid",
+ "__NR_vm86",
+ "__NR_query_module",
+ "__NR_poll",
+ "__NR_nfsservctl",
+ "__NR_setresgid",
+ "__NR_getresgid",
+ "__NR_prctl",
+ "__NR_rt_sigreturn",
+ "__NR_rt_sigaction",
+ "__NR_rt_sigprocmask",
+ "__NR_rt_sigpending",
+ "__NR_rt_sigtimedwait",
+ "__NR_rt_sigqueueinfo",
+ "__NR_rt_sigsuspend",
+ "__NR_pread64",
+ "__NR_pwrite64",
+ "__NR_chown",
+ "__NR_getcwd",
+ "__NR_capget",
+ "__NR_capset",
+ "__NR_sigaltstack",
+ "__NR_sendfile",
+ "__NR_getpmsg",
+ "__NR_putpmsg",
+ "__NR_vfork",
+ "__NR_ugetrlimit",
+ "__NR_mmap2",
+ "__NR_truncate64",
+ "__NR_ftruncate64",
+ "__NR_stat64",
+ "__NR_lstat64",
+ "__NR_fstat64",
+ "__NR_lchown32",
+ "__NR_getuid32",
+ "__NR_getgid32",
+ "__NR_geteuid32",
+ "__NR_getegid32",
+ "__NR_setreuid32",
+ "__NR_setregid32",
+ "__NR_getgroups32",
+ "__NR_setgroups32",
+ "__NR_fchown32",
+ "__NR_setresuid32",
+ "__NR_getresuid32",
+ "__NR_setresgid32",
+ "__NR_getresgid32",
+ "__NR_chown32",
+ "__NR_setuid32",
+ "__NR_setgid32",
+ "__NR_setfsuid32",
+ "__NR_setfsgid32",
+ "__NR_pivot_root",
+ "__NR_mincore",
+ "__NR_madvise",
+ "__NR_madvise1",
+ "__NR_getdents64",
+ "__NR_fcntl64",
+ "__NR_unused",
+ "__NR_gettid",
+ "__NR_readahead",
+ "__NR_setxattr",
+ "__NR_lsetxattr",
+ "__NR_fsetxattr",
+ "__NR_getxattr",
+ "__NR_lgetxattr",
+ "__NR_fgetxattr",
+ "__NR_listxattr",
+ "__NR_llistxattr",
+ "__NR_flistxattr",
+ "__NR_removexattr",
+ "__NR_lremovexattr",
+ "__NR_fremovexattr",
+ "__NR_tkill",
+ "__NR_sendfile64",
+ "__NR_futex",
+ "__NR_sched_setaffinity",
+ "__NR_sched_getaffinity",
+ "__NR_set_thread_area",
+ "__NR_get_thread_area",
+ "__NR_io_setup",
+ "__NR_io_destroy",
+ "__NR_io_getevents",
+ "__NR_io_submit",
+ "__NR_io_cancel",
+ "__NR_fadvise64",
+ "__NR_unused",
+ "__NR_exit_group",
+ "__NR_lookup_dcookie",
+ "__NR_epoll_create",
+ "__NR_epoll_ctl",
+ "__NR_epoll_wait",
+ "__NR_remap_file_pages",
+ "__NR_set_tid_address",
+ "__NR_timer_create",
+ "__NR_timer_settime",
+ "__NR_timer_gettime",
+ "__NR_timer_getoverrun",
+ "__NR_timer_delete",
+ "__NR_clock_settime",
+ "__NR_clock_gettime",
+ "__NR_clock_getres",
+ "__NR_clock_nanosleep",
+ "__NR_statfs64",
+ "__NR_fstatfs64",
+ "__NR_tgkill",
+ "__NR_utimes",
+ "__NR_fadvise64_64",
+ "__NR_vserver",
+ "__NR_mbind",
+ "__NR_get_mempolicy",
+ "__NR_set_mempolicy",
+ "__NR_mq_open",
+ "__NR_mq_unlink",
+ "__NR_mq_timedsend",
+ "__NR_mq_timedreceive",
+ "__NR_mq_notify",
+ "__NR_mq_getsetattr",
+ "__NR_kexec_load",
+ "__NR_waitid",
+ "__NR_sys_setaltroot",
+ "__NR_add_key",
+ "__NR_request_key",
+ "__NR_keyctl",
+ "__NR_ioprio_set",
+ "__NR_ioprio_get",
+ "__NR_inotify_init",
+ "__NR_inotify_add_watch",
+ "__NR_inotify_rm_watch",
+ "__NR_migrate_pages",
+ "__NR_openat",
+ "__NR_mkdirat",
+ "__NR_mknodat",
+ "__NR_fchownat",
+ "__NR_futimesat",
+ "__NR_fstatat64",
+ "__NR_unlinkat",
+ "__NR_renameat",
+ "__NR_linkat",
+ "__NR_symlinkat",
+ "__NR_readlinkat",
+ "__NR_fchmodat",
+ "__NR_faccessat",
+ "__NR_pselect6",
+ "__NR_ppoll",
+ "__NR_unshare",
+ "__NR_set_robust_list",
+ "__NR_get_robust_list",
+ "__NR_splice",
+ "__NR_sync_file_range",
+ "__NR_tee",
+ "__NR_vmsplice",
+ "__NR_move_pages",
+ "__NR_getcpu",
+ "__NR_epoll_pwait",
+ "__NR_utimensat",
+ "__NR_signalfd",
+ "__NR_timerfd_create",
+ "__NR_eventfd",
+ "__NR_fallocate",
+ "__NR_timerfd_settime",
+ "__NR_timerfd_gettime",
+ "__NR_signalfd4",
+ "__NR_eventfd2",
+ "__NR_epoll_create1",
+ "__NR_dup3",
+ "__NR_pipe2",
+ "__NR_inotify_init1",
+ "__NR_preadv",
+ "__NR_pwritev",
+ "__NR_rt_tgsigqueueinfo",
+ "__NR_perf_event_open"
+ ]
+
+ self.__args = {
+ "sys_restart_syscall" : [],
+ "sys_exit" : ["int error_code"],
+ "sys_write" : ["unsigned int fd", "const char __user *buf", "size_t count"]
+ }
+
+ def get_syscall_name(self, index):
+ """Convert a syscall index into a human name."""
+
+ return self.__syscalls[index]
+
+
+ def get_syscall_args(self, name):
+ """Provide the function name, the needed registers and the used arguments of a syscall."""
+
+ name = name.replace("__NR_", "sys_")
+
+ try:
+ args = self.__args[name]
+ except:
+ return None
+
+ targets = {}
+
+ if len(args) >= 4:
+
+ pass
+
+ else:
+
+ registers = ["ebx", "ecx", "edx", "esi", "edi"]
+
+ i = 0
+
+ for val in args:
+ targets[registers[i]] = val
+ i = i + 1
+
+ return [name, targets]
+
+
+
+
+class LinuxSysCallsPlugin(Plugin):
+ """A simple example class"""
+
+
+
+ def __rendering_options(self, binary):
+ """Build the options needed to get the ASM code only."""
+
+ exe = binary.get_format()
+
+ ropts = RenderingOptions(exe)
+
+ ropts.show_code(True)
+ ropts.show_address = False
+
+ return ropts
+
+ def __is_syscall(self, code):
+ """Tell weither the ASM line of code is a syscall or not."""
+
+ result = False
+
+ if code.find("int") != -1:
+
+ list = code.split("\t")
+
+ if len(list) == 2:
+ result = list == ["int", "0x80"]
+
+ return result
+
+ def __find_used_register(self, ropts, start, target):
+ """Look for a given register used to supply argument for a syscall."""
+
+ for found in reversed(start):
+
+ code = found.get_text(ropts)
+ parts = code.expandtabs(1).replace(",", "").split(" ")
+
+ # Next registers are used by a new interruption
+ if parts[0] == "int":
+ continue
+
+ # No operand
+ if len(parts) == 1:
+ continue
+
+ # Only simple cases are processed...
+ if parts[1] == target:
+ if len(parts) == 2:
+ return None
+ else:
+ return [found, parts[2]]
+
+ return None
+
+ def run(self, binary):
+ """Resolve all registers / interruptions involved in a syscall."""
+
+ db = SysCallDB()
+
+ ropts = self.__rendering_options(binary)
+
+ lines = binary.get_lines()
+
+ for line in lines:
+ code = line.get_text(ropts)
+ if self.__is_syscall(code):
+
+ # What kind of syscall ?
+
+ line_eax = self.__find_used_register(ropts, line, "eax")
+
+ if line_eax is None:
+ line.comment = "== UNIX Syscall =="
+ continue
+
+ index = int(line_eax[1], 16)
+ name = db.get_syscall_name(index)
+
+ line_eax[0].comment = name
+
+ # What function / arguments ?
+
+ targets = db.get_syscall_args(name)
+
+ if targets == None:
+
+ line.comment = "== UNIX Syscall =="
+ continue
+
+ else:
+
+ line.comment = "== UNIX Syscall to %s() ==" % (targets[0])
+
+ for reg, arg in targets[1].items():
+
+ found = self.__find_used_register(ropts, line, reg)
+
+ if found != None:
+ found[0].comment = arg
+
+
+
+
+
+
+def get_instance(binary):
+
+ print " --- toto from Python ---"
+
+
+
+ a = LinuxSysCallsPlugin()
+
+ a.run(binary)
+
+ return Plugin.PGA_CODE_PROCESS
+
+
+
+