Interface EmuSyscallLibrary<T>

Type Parameters:
T - the type of data processed by the system calls, typically byte[]
All Superinterfaces:
PcodeUseropLibrary<T>
All Known Implementing Classes:
AbstractEmuLinuxSyscallUseropLibrary, AbstractEmuUnixSyscallUseropLibrary, AnnotatedEmuSyscallUseropLibrary, EmuLinuxAmd64SyscallUseropLibrary, EmuLinuxX86SyscallUseropLibrary, TaintFileReadsLinuxAmd64SyscallLibrary

public interface EmuSyscallLibrary<T> extends PcodeUseropLibrary<T>
A library of system calls

A system call library is a collection of p-code executable routines, invoked by a system call dispatcher. That dispatcher is represented by emu_syscall(PcodeExecutor, PcodeUseropLibrary, PcodeOp, Varnode), and is exported as a Sleigh userop. If this interface is "mixed in" with AnnotatedPcodeUseropLibrary, that userop is automatically included in the userop library. The simplest means of implementing a syscall library is probably via AnnotatedEmuSyscallUseropLibrary. It implements this interface and extends AnnotatedPcodeUseropLibrary. In addition, it provides its own annotation system for exporting userops as system calls.

  • Field Details

  • Method Details

    • loadSyscallNumberMap

      static Map<Long,String> loadSyscallNumberMap(String dataFileName) throws IOException
      Derive a syscall number to name map from the specification in a given file.
      Parameters:
      dataFileName - the file name to be found in a modules data directory
      Returns:
      the map
      Throws:
      IOException - if the file could not be read
    • loadSyscallFunctionMap

      static Map<Long,Function> loadSyscallFunctionMap(Program program)
      Scrape functions from the given program's "syscall" space.
      Parameters:
      program - the program
      Returns:
      a map of syscall number to function
    • loadSyscallNumberMap

      static Map<Long,String> loadSyscallNumberMap(Program program)
      Derive a syscall number to name map by scraping functions in the program's "syscall" space.
      Parameters:
      program - the program, likely analyzed for system calls already
      Returns:
      the map
    • loadSyscallConventionMap

      static Map<Long, PrototypeModel> loadSyscallConventionMap(Program program)
      Derive a syscall number to calling convention map by scraping functions in the program's "syscall" space.
      Parameters:
      program - the program whose "syscall" space to scrape
      Returns:
      the map of syscall number to calling convention
    • emu_rt_syscall

      default void emu_rt_syscall(PcodeExecutor<T> executor, PcodeUseropLibrary<T> library, long syscallNumber)
      A Java-callback implementation of "emu_syscall" that reads the syscall number and dispatches to the appropriate system call implementation at run time.

      This is the normal behavior for the interpretation-based p-code emulator anyway. However, for an execution engine that attempts to resolve system calls "just in time," it may be necessary to explicitly defer to this implementation to prevent any further attempt to resolve the system call, when it becomes impossible to do so.

      Parameters:
      executor - the executor
      library - the p-code userop library (often including exported system calls)
      syscallNumber - the system call number
    • emu_syscall

      default void emu_syscall(PcodeExecutor<T> executor, PcodeUseropLibrary<T> library, PcodeOp op, Varnode syscallNumber)
      The entry point for executing a system call on the given executor

      The executor's state must already be prepared according to the relevant system calling conventions. The extended or composed library must provide the "syscall" and/or other relevant userops defined in the Sleigh. That "syscall" userop should invoke this userop, passing the system call number then place the result where it belongs according to the target ABI.

      Parameters:
      executor - the executor
      library - the library
      op - the callother userop
      syscallNumber - the varnode containing the syscall number
      Implementation Notes:
      At run time, the logic here will do exactly as it says. For the interpretation-based emulator, nothing special happens. We read the system call number and defer to emu_rt_syscall(PcodeExecutor, PcodeUseropLibrary, long), which looks it up and executes it. The try-catch for ConcretionError appears totally useless.

      For the JIT-accelerated emulator, things are more interesting. Because AnnotatedPcodeUseropLibrary.PcodeUserop.canInline() is set here, we receive this callback during the decode phase of the translation. We read the system call number and defer to emu_rt_syscall(PcodeExecutor, PcodeUseropLibrary, long) as before. (Note that AnnotatedPcodeUseropLibrary.PcodeUserop.canInline() being false does not prevent us from invoking it from Java, even though the engine is currently trying to inline us.) The try-catch thus protects the attempt to concretize the syscall number. During decode, T := MaskedBytes, so if the syscall turns out to be a constant (which it often does), then we can dispatch it at decode time. That syscall (or at least the logic that reads arguments and stores the result) can thus be inlined. If concretization fails, then we fall back to invoking {#emu_rt_syscall} at run time.

    • getSyscalls

      Get the map of syscalls by number

      Note this method will be invoked for every interpreted syscall, so it should be a simple accessor. Any computations needed to create the map should be done ahead of time.

      Returns:
      the system call map