├── .gitignore ├── BUGS ├── COPYING ├── CREDITS ├── README.rst ├── TODO ├── doc ├── Makefile ├── conf.py ├── devdoc.rst ├── examples.rst ├── index.rst ├── intro.rst ├── reference.rst └── tracy.dot ├── gentoo └── sys-libs │ └── tracy │ ├── Manifest │ └── tracy-9999.ebuild ├── research └── abi-proposal │ └── ABI ├── src ├── .gitignore ├── BROKEN_WITH_ABI ├── Makefile ├── arch │ ├── amd64 │ │ ├── arch.c │ │ ├── arch.h │ │ └── syscalls.h │ ├── arm │ │ ├── arch.c │ │ ├── arch.h │ │ └── syscalls.h │ ├── ppc │ │ ├── arch.c │ │ ├── arch.h │ │ └── syscalls.h │ └── x86 │ │ ├── arch.c │ │ ├── arch.h │ │ └── syscalls.h ├── def_signals.h ├── ll.c ├── ll.h ├── pytracy.py ├── revwr.py ├── rules.mk ├── soxy │ ├── Makefile │ ├── README │ ├── app │ │ ├── Makefile │ │ ├── README │ │ ├── county.c │ │ ├── dotty.c │ │ ├── fork.c │ │ ├── get-request.c │ │ ├── ll_test.c │ │ ├── loggy.c │ │ └── mmap.c │ ├── soxy.c │ └── soxy.h ├── tests │ ├── abi-tests │ │ ├── cd80.c │ │ ├── syscall.c │ │ └── sysenter.c │ ├── abi.c │ ├── async-inject.c │ ├── attach-detach.c │ ├── attach-execve.c │ ├── attach.c │ ├── base.c │ ├── bash.c │ ├── bounce.c │ ├── deny.c │ ├── faketime.c │ ├── fork-prog.c │ ├── fork.c │ ├── fuzz-write.c │ ├── getpid.c │ ├── hello.c │ ├── inject-simple.c │ ├── llseek.c │ ├── metronome.c │ ├── raw-clone.c │ ├── read_stdin.c │ ├── redirect.c │ ├── rwmem.c │ ├── sig_suppress.c │ ├── thread-simple-prog.c │ ├── thread-simple.c │ ├── vfork-prog.c │ └── wxorx.c ├── tracy-event.c ├── tracy-mem.c ├── tracy-modification.c ├── tracy-safe-fork.c ├── tracy.c ├── tracy.h ├── tracyarch.h ├── tracyfs.py ├── trampy.c ├── trampy.h └── zipjail │ ├── Makefile │ ├── README.rst │ ├── tests │ ├── Makefile │ ├── execv.c │ ├── fork.c │ ├── longpath.c │ ├── mkdir.c │ ├── mkdir2.c │ ├── multithread.c │ ├── openat.c │ ├── relative.c │ ├── relative2.c │ ├── simple.7z │ ├── simple.ace │ ├── simple.rar │ ├── simple.zip │ ├── symlink.c │ ├── unlink.c │ └── unlink2.c │ └── zipjail.c └── university-work ├── TODO └── report ├── Makefile ├── WORK.bas ├── WORK.merlijn ├── post.dot ├── pre.dot ├── ptrace.dot ├── ptrace2.dot ├── report.bib ├── report.tex └── tracy.dot /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.o 3 | src/arch/*/syscall*.h 4 | src/libtracy.a 5 | src/libtracy.so 6 | src/zipjail/zipjail 7 | src/zipjail/tests/*.out 8 | -------------------------------------------------------------------------------- /BUGS: -------------------------------------------------------------------------------- 1 | Known bugs: 2 | 3 | * Python bindings are currently broken because of the ABI change 4 | * ABI detection on amd64 is not race safe. This should not be a problem 5 | for almost anyone, except when they're writing secure jails. 6 | 7 | * No BSD support yet. I will try a FreeBSD port sometime soon. 8 | * No support for MIPS, PPC64, ARM64 9 | * No 'proper' tests 10 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2004 Sam Hocevar 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /CREDITS: -------------------------------------------------------------------------------- 1 | Bas Weelinck (meridion) - Tracy 2 | Erik Kooistra - PPC32 support 3 | Ilja Kamps (Ikarus) - Concept 4 | Jurriaan Bremer (skier_)- Soxy 5 | Merlijn Wajer (Wizzup) - Soxy & Tracy 6 | Stephan van Schaik - Gentoo ebuild 7 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Tracy, a system call tracer and injector 2 | ======================================== 3 | 4 | Presented is a uniform interface to trace the behaviour of programs 5 | by means of the system calls they perform. Tracing by the user is done without 6 | regard to kernel version, operating system or processor architecture. 7 | The interface, called Tracy, provides a means to watch, modify, augment 8 | and restrict program execution in a controlled environment. 9 | 10 | If you wish to use Tracy in a project but do not want the project to be 11 | GPL, contact me for possible licensing options. 12 | 13 | Currently supported architectures (In decreasing order of testing): 14 | 15 | * amd64 16 | * x86 17 | * arm 18 | * ppc32 19 | 20 | With support for the following C libraries: 21 | 22 | * glibc 23 | * musl 24 | 25 | 26 | Website 27 | ======= 28 | 29 | See http://hetgrotebos.org/wiki/Tracy for the homepage. 30 | 31 | 32 | 33 | Examples 34 | ======== 35 | 36 | C API 37 | ----- 38 | 39 | .. code-block:: C 40 | 41 | #include 42 | #include "tracy.h" 43 | 44 | int hook_write(struct tracy_event * e) { 45 | if (e->child->pre_syscall) { 46 | if(e->args.a0 == 1) { 47 | return TRACY_HOOK_DENY; 48 | } 49 | } 50 | 51 | return TRACY_HOOK_CONTINUE; 52 | } 53 | 54 | int main(int argc, char** argv) { 55 | struct tracy * tracy; 56 | 57 | tracy = tracy_init(TRACY_TRACE_CHILDREN | TRACY_VERBOSE); 58 | 59 | if (tracy_set_hook(tracy, "write", TRACY_ABI_NATIVE, hook_write)) { 60 | fprintf(stderr, "Could not hook write\n"); 61 | return EXIT_FAILURE; 62 | } 63 | 64 | if (argc < 2) { 65 | printf("Usage: ./example \n"); 66 | return EXIT_FAILURE; 67 | } 68 | 69 | argv++; argc--; 70 | 71 | if (!tracy_exec(tracy, argv)) { 72 | perror("tracy_exec"); 73 | return EXIT_FAILURE; 74 | } 75 | 76 | tracy_main(tracy); 77 | 78 | tracy_free(tracy); 79 | 80 | return EXIT_SUCCESS; 81 | } 82 | 83 | 84 | Python API 85 | ---------- 86 | 87 | (EXAMPLE OUTDATED) 88 | 89 | .. code-block:: python 90 | 91 | from pytracy import Tracy, Child, TRACE_CHILDREN 92 | import sys 93 | 94 | 95 | class Reverser(Tracy): 96 | """Reverses written data to file descriptors.""" 97 | 98 | def __init__(self, options=0): 99 | Tracy.__init__(self, TRACE_CHILDREN | options) 100 | self.hook('write', self._handle_write) 101 | 102 | def _handle_write(self, e, a, pre): 103 | c = Child.from_event(e) 104 | if pre and a.a0 in (1, 2): 105 | buf = c.read(a.a1, a.a2) 106 | if buf: 107 | c.write(a.a1, buf[::-1]) 108 | 109 | if __name__ == '__main__': 110 | t = Reverser() 111 | t.execute(*sys.argv[1:]) 112 | t.main() 113 | 114 | .. ** 115 | 116 | Work In Progress 117 | ================ 118 | 119 | Tracy is still work in progress, although already quite useful for certain 120 | tasks. We're working W^X support for safe tracing with multiple ABIs and 121 | BSD support. 122 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | * Sync documentation with tracy.h and recent developments 2 | * Add TRACY_DETACH_CHILD to signal hook. But that needs some more thought - we 3 | need to pass the signal to the child if we are going to detach, etc. 4 | * Look at src/BROKEN_WITH_ABI and fix appropriately. 5 | * Decide whether TRACY_HOOK_ABORT should kill all processes regardless if we 6 | started them or attached to them, or that it should detach ones that we 7 | attached to and kill the rest, etc... 8 | 9 | * Add support for loading relocatable code in the binary. Some kind of modules? 10 | Would be awesome. Load dl in the process? 11 | * Add python module (compiled from C, not ctypes; maybe a high level wrapper 12 | around the C module, but no ctypes). For python API. 13 | 14 | * Add support for injection/modification with a different ABI than current. 15 | 16 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # Internal variables. 11 | PAPEROPT_a4 = -D latex_paper_size=a4 12 | PAPEROPT_letter = -D latex_paper_size=letter 13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 14 | 15 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest 16 | 17 | help: 18 | @echo "Please use \`make ' where is one of" 19 | @echo " html to make standalone HTML files" 20 | @echo " dirhtml to make HTML files named index.html in directories" 21 | @echo " singlehtml to make a single large HTML file" 22 | @echo " pickle to make pickle files" 23 | @echo " json to make JSON files" 24 | @echo " htmlhelp to make HTML files and a HTML help project" 25 | @echo " qthelp to make HTML files and a qthelp project" 26 | @echo " devhelp to make HTML files and a Devhelp project" 27 | @echo " epub to make an epub" 28 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 29 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 30 | @echo " text to make text files" 31 | @echo " man to make manual pages" 32 | @echo " changes to make an overview of all changed/added/deprecated items" 33 | @echo " linkcheck to check all external links for integrity" 34 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 35 | 36 | clean: 37 | -rm -rf $(BUILDDIR)/* 38 | 39 | html: 40 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 41 | @echo 42 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 43 | 44 | dirhtml: 45 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 46 | @echo 47 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 48 | 49 | singlehtml: 50 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 51 | @echo 52 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 53 | 54 | pickle: 55 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 56 | @echo 57 | @echo "Build finished; now you can process the pickle files." 58 | 59 | json: 60 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 61 | @echo 62 | @echo "Build finished; now you can process the JSON files." 63 | 64 | htmlhelp: 65 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 66 | @echo 67 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 68 | ".hhp project file in $(BUILDDIR)/htmlhelp." 69 | 70 | qthelp: 71 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 72 | @echo 73 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 74 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 75 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Tracy.qhcp" 76 | @echo "To view the help file:" 77 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Tracy.qhc" 78 | 79 | devhelp: 80 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 81 | @echo 82 | @echo "Build finished." 83 | @echo "To view the help file:" 84 | @echo "# mkdir -p $$HOME/.local/share/devhelp/Tracy" 85 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Tracy" 86 | @echo "# devhelp" 87 | 88 | epub: 89 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 90 | @echo 91 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 92 | 93 | latex: 94 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 95 | @echo 96 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 97 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 98 | "(use \`make latexpdf' here to do that automatically)." 99 | 100 | latexpdf: 101 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 102 | @echo "Running LaTeX files through pdflatex..." 103 | make -C $(BUILDDIR)/latex all-pdf 104 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 105 | 106 | text: 107 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 108 | @echo 109 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 110 | 111 | man: 112 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 113 | @echo 114 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 115 | 116 | changes: 117 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 118 | @echo 119 | @echo "The overview file is in $(BUILDDIR)/changes." 120 | 121 | linkcheck: 122 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 123 | @echo 124 | @echo "Link check complete; look for any errors in the above output " \ 125 | "or in $(BUILDDIR)/linkcheck/output.txt." 126 | 127 | doctest: 128 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 129 | @echo "Testing of doctests in the sources finished, look at the " \ 130 | "results in $(BUILDDIR)/doctest/output.txt." 131 | -------------------------------------------------------------------------------- /doc/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Tracy documentation build configuration file, created by 4 | # sphinx-quickstart on Mon Mar 19 11:35:38 2012. 5 | # 6 | # This file is execfile()d with the current directory set to its containing dir. 7 | # 8 | # Note that not all possible configuration values are present in this 9 | # autogenerated file. 10 | # 11 | # All configuration values have a default; values that are commented out 12 | # serve to show the default. 13 | 14 | import sys, os 15 | 16 | # If extensions (or modules to document with autodoc) are in another directory, 17 | # add these directories to sys.path here. If the directory is relative to the 18 | # documentation root, use os.path.abspath to make it absolute, like shown here. 19 | #sys.path.insert(0, os.path.abspath('.')) 20 | 21 | # -- General configuration ----------------------------------------------------- 22 | 23 | # If your documentation needs a minimal Sphinx version, state it here. 24 | #needs_sphinx = '1.0' 25 | 26 | # Add any Sphinx extension module names here, as strings. They can be extensions 27 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. 28 | extensions = ['sphinx.ext.autodoc'] 29 | 30 | # Add any paths that contain templates here, relative to this directory. 31 | templates_path = ['_templates'] 32 | 33 | # The suffix of source filenames. 34 | source_suffix = '.rst' 35 | 36 | # The encoding of source files. 37 | #source_encoding = 'utf-8-sig' 38 | 39 | # The master toctree document. 40 | master_doc = 'index' 41 | 42 | # General information about the project. 43 | project = u'Tracy' 44 | copyright = u'2012,2013,2014 Merlijn Wajer, Bas Weelinck' 45 | 46 | # The version info for the project you're documenting, acts as replacement for 47 | # |version| and |release|, also used in various other places throughout the 48 | # built documents. 49 | # 50 | # The short X.Y version. 51 | version = '0.07' 52 | # The full version, including alpha/beta/rc tags. 53 | release = '0.07' 54 | 55 | # The language for content autogenerated by Sphinx. Refer to documentation 56 | # for a list of supported languages. 57 | #language = None 58 | 59 | # There are two options for replacing |today|: either, you set today to some 60 | # non-false value, then it is used: 61 | #today = '' 62 | # Else, today_fmt is used as the format for a strftime call. 63 | #today_fmt = '%B %d, %Y' 64 | 65 | # List of patterns, relative to source directory, that match files and 66 | # directories to ignore when looking for source files. 67 | exclude_patterns = ['_build'] 68 | 69 | # The reST default role (used for this markup: `text`) to use for all documents. 70 | #default_role = None 71 | 72 | # If true, '()' will be appended to :func: etc. cross-reference text. 73 | #add_function_parentheses = True 74 | 75 | # If true, the current module name will be prepended to all description 76 | # unit titles (such as .. function::). 77 | #add_module_names = True 78 | 79 | # If true, sectionauthor and moduleauthor directives will be shown in the 80 | # output. They are ignored by default. 81 | #show_authors = False 82 | 83 | # The name of the Pygments (syntax highlighting) style to use. 84 | pygments_style = 'sphinx' 85 | 86 | # A list of ignored prefixes for module index sorting. 87 | #modindex_common_prefix = [] 88 | 89 | 90 | # -- Options for HTML output --------------------------------------------------- 91 | 92 | # The theme to use for HTML and HTML Help pages. See the documentation for 93 | # a list of builtin themes. 94 | html_theme = 'nature' 95 | 96 | # Theme options are theme-specific and customize the look and feel of a theme 97 | # further. For a list of options available for each theme, see the 98 | # documentation. 99 | #html_theme_options = {} 100 | 101 | # Add any paths that contain custom themes here, relative to this directory. 102 | #html_theme_path = [] 103 | 104 | # The name for this set of Sphinx documents. If None, it defaults to 105 | # " v documentation". 106 | #html_title = None 107 | 108 | # A shorter title for the navigation bar. Default is the same as html_title. 109 | #html_short_title = None 110 | 111 | # The name of an image file (relative to this directory) to place at the top 112 | # of the sidebar. 113 | #html_logo = None 114 | 115 | # The name of an image file (within the static path) to use as favicon of the 116 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 117 | # pixels large. 118 | #html_favicon = None 119 | 120 | # Add any paths that contain custom static files (such as style sheets) here, 121 | # relative to this directory. They are copied after the builtin static files, 122 | # so a file named "default.css" will overwrite the builtin "default.css". 123 | html_static_path = ['_static'] 124 | 125 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 126 | # using the given strftime format. 127 | #html_last_updated_fmt = '%b %d, %Y' 128 | 129 | # If true, SmartyPants will be used to convert quotes and dashes to 130 | # typographically correct entities. 131 | #html_use_smartypants = True 132 | 133 | # Custom sidebar templates, maps document names to template names. 134 | #html_sidebars = {} 135 | 136 | # Additional templates that should be rendered to pages, maps page names to 137 | # template names. 138 | #html_additional_pages = {} 139 | 140 | # If false, no module index is generated. 141 | #html_domain_indices = True 142 | 143 | # If false, no index is generated. 144 | #html_use_index = True 145 | 146 | # If true, the index is split into individual pages for each letter. 147 | #html_split_index = False 148 | 149 | # If true, links to the reST sources are added to the pages. 150 | #html_show_sourcelink = True 151 | 152 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 153 | #html_show_sphinx = True 154 | 155 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 156 | #html_show_copyright = True 157 | 158 | # If true, an OpenSearch description file will be output, and all pages will 159 | # contain a tag referring to it. The value of this option must be the 160 | # base URL from which the finished HTML is served. 161 | #html_use_opensearch = '' 162 | 163 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 164 | #html_file_suffix = None 165 | 166 | # Output file base name for HTML help builder. 167 | htmlhelp_basename = 'Tracydoc' 168 | 169 | 170 | # -- Options for LaTeX output -------------------------------------------------- 171 | 172 | # The paper size ('letter' or 'a4'). 173 | #latex_paper_size = 'letter' 174 | 175 | # The font size ('10pt', '11pt' or '12pt'). 176 | #latex_font_size = '10pt' 177 | 178 | # Grouping the document tree into LaTeX files. List of tuples 179 | # (source start file, target name, title, author, documentclass [howto/manual]). 180 | latex_documents = [ 181 | ('index', 'Tracy.tex', u'Tracy Documentation', 182 | u'Merlijn Wajer, Bas Weelinck', 'manual'), 183 | ] 184 | 185 | # The name of an image file (relative to this directory) to place at the top of 186 | # the title page. 187 | #latex_logo = None 188 | 189 | # For "manual" documents, if this is true, then toplevel headings are parts, 190 | # not chapters. 191 | #latex_use_parts = False 192 | 193 | # If true, show page references after internal links. 194 | #latex_show_pagerefs = False 195 | 196 | # If true, show URL addresses after external links. 197 | #latex_show_urls = False 198 | 199 | # Additional stuff for the LaTeX preamble. 200 | #latex_preamble = '' 201 | 202 | # Documents to append as an appendix to all manuals. 203 | #latex_appendices = [] 204 | 205 | # If false, no module index is generated. 206 | #latex_domain_indices = True 207 | 208 | 209 | # -- Options for manual page output -------------------------------------------- 210 | 211 | # One entry per manual page. List of tuples 212 | # (source start file, name, description, authors, manual section). 213 | man_pages = [ 214 | ('index', 'tracy', u'Tracy Documentation', 215 | [u'Merlijn Wajer, Bas Weelinck'], 1) 216 | ] 217 | 218 | 219 | # -- Options for Epub output --------------------------------------------------- 220 | 221 | # Bibliographic Dublin Core info. 222 | epub_title = u'Tracy' 223 | epub_author = u'Merlijn Wajer, Bas Weelinck' 224 | epub_publisher = u'Merlijn Wajer, Bas Weelinck' 225 | epub_copyright = u'2012,2013,2014, Merlijn Wajer, Bas Weelinck' 226 | 227 | # The language of the text. It defaults to the language option 228 | # or en if the language is not set. 229 | #epub_language = '' 230 | 231 | # The scheme of the identifier. Typical schemes are ISBN or URL. 232 | #epub_scheme = '' 233 | 234 | # The unique identifier of the text. This can be a ISBN number 235 | # or the project homepage. 236 | #epub_identifier = '' 237 | 238 | # A unique identification for the text. 239 | #epub_uid = '' 240 | 241 | # HTML files that should be inserted before the pages created by sphinx. 242 | # The format is a list of tuples containing the path and title. 243 | #epub_pre_files = [] 244 | 245 | # HTML files shat should be inserted after the pages created by sphinx. 246 | # The format is a list of tuples containing the path and title. 247 | #epub_post_files = [] 248 | 249 | # A list of files that should not be packed into the epub file. 250 | #epub_exclude_files = [] 251 | 252 | # The depth of the table of contents in toc.ncx. 253 | #epub_tocdepth = 3 254 | 255 | # Allow duplicate toc entries. 256 | #epub_tocdup = True 257 | -------------------------------------------------------------------------------- /doc/devdoc.rst: -------------------------------------------------------------------------------- 1 | Developer Documentation 2 | ======================= 3 | 4 | First and foremost documentation are the comments in the code and the paper in 5 | report/ 6 | 7 | 8 | -------------------------------------------------------------------------------- /doc/examples.rst: -------------------------------------------------------------------------------- 1 | API Example 2 | =========== 3 | 4 | Below are some examples of the Tracy API. If you are looking for the API 5 | reference, skip to the next chapter. 6 | 7 | Creating a Tracy instance 8 | ------------------------- 9 | 10 | .. code-block:: c 11 | 12 | struct tracy *tracy; 13 | 14 | tracy = tracy_init(options); 15 | 16 | .. ** 17 | 18 | Tracy options 19 | ~~~~~~~~~~~~~ 20 | 21 | Tracy has several options that affect the tracing process. 22 | Options are passed to :ref:`rtracy_init` in a bitwise manner. 23 | 24 | The following tracy options are available: 25 | 26 | - **TRACY_TRACE_CHILDREN** 27 | 28 | If this option is set, tracy will automatically trace all children of the 29 | process. 30 | 31 | - **TRACY_VERBOSE** 32 | 33 | Tracy will be verbose and print information about events and internal logic. 34 | 35 | - **TRACY_VERBOSE_SIGNAL** 36 | 37 | Tracy will print information relating to signals. 38 | 39 | - **TRACY_VERBOSE_SYSCALL** 40 | 41 | Tracy will print information relating to system calls. 42 | 43 | - **TRACY_MEMORY_FALLBACK** 44 | 45 | Enables a ptrace based (slow) memory fallback if the fast memory access 46 | method is not available. 47 | 48 | - **TRACY_USE_SAFE_TRACE** 49 | 50 | Enables experimental tracing of all created children. Instead of relying on 51 | Linux' mechanism to automatically trace all created children, we utilise our 52 | own safe tracing mechanism. Theoretically this should also work on BSD 53 | platforms, but has not yet been tested. 54 | 55 | Tracing a process 56 | ~~~~~~~~~~~~~~~~~ 57 | 58 | To start a process, use :ref:`rtracy_exec`. Pass a **NULL** terminated 59 | string array as **argv**. 60 | 61 | .. code-block:: c 62 | 63 | int main(int argc, char** argv) { 64 | struct tracy *tracy; 65 | 66 | tracy = tracy_init(TRACY_TRACE_CHILDREN | TRACY_VERBOSE | 67 | TRACY_VERBOSE_SIGNAL | TRACY_VERBOSE_SYSCALL); 68 | 69 | if (argc < 2) { 70 | printf("Usage: ./example \n"); 71 | return EXIT_FAILURE; 72 | } 73 | 74 | argv++; argc--; 75 | 76 | /* Start child */ 77 | if (!tracy_exec(tracy, argc, argv)) { 78 | perror("tracy_exec"); 79 | return EXIT_FAILURE; 80 | } 81 | 82 | /* Default event-loop */ 83 | tracy_main(tracy); 84 | 85 | /* Free tracy */ 86 | tracy_free(tracy); 87 | 88 | return 0; 89 | 90 | } 91 | 92 | .. ** 93 | 94 | Handling Tracy events 95 | --------------------- 96 | 97 | Generally, you shouldn't care about the specifics of tracy events 98 | and you can just use `tracy_main`_ instead. However, now follows 99 | a quick description of each event in Tracy's event system. 100 | 101 | - **TRACY_EVENT_SYSCALL** 102 | 103 | This event indicates that a tracee is trying to perform 104 | (or has just performed) a system call. 105 | 106 | - **TRACY_EVENT_SIGNAL** 107 | 108 | This event indicates that a signal is to be delivered 109 | to a tracee. 110 | 111 | - **TRACY_EVENT_INTERNAL** 112 | 113 | This indicates an internal event in Tracy. This event is used 114 | in asynchronous system calls and possibly other features in the 115 | future. 116 | 117 | - **TRACY_EVENT_QUIT** 118 | 119 | This indicates that a tracee has been stopped or killed. 120 | 121 | - **TRACY_EVENT_NONE** 122 | 123 | A none event is returned on error, or simply when there are no tracees 124 | left. 125 | 126 | tracy_main 127 | ~~~~~~~~~~ 128 | 129 | The :ref:`rtracy_main` procedure is the default way to use Tracy events. 130 | The method does not return until all children have died. It honours the 131 | signal and system call hooks, but does not provide a lot of control over 132 | the event system. If you need more direct control, you could write your own 133 | version of :ref:`rtracy_main`. 134 | 135 | Your own event loop 136 | ~~~~~~~~~~~~~~~~~~~ 137 | 138 | A very simple version: 139 | 140 | .. code-block:: c 141 | 142 | int tracy_main(struct tracy * tracy) { 143 | struct tracy_event * e; 144 | 145 | main_loop_go_on = 1; 146 | 147 | while (main_loop_go_on) { 148 | e = tracy_wait_event(tracy, -1); 149 | if (!e) { 150 | fprintf(stderr, "tracy_main: tracy_wait_Event returned NULL\n"); 151 | continue; 152 | } 153 | 154 | if (e->type == TRACY_EVENT_NONE) { 155 | break; 156 | } else if (e->type == TRACY_EVENT_INTERNAL) { 157 | } else if (e->type == TRACY_EVENT_SIGNAL) { 158 | } else if (e->type == TRACY_EVENT_SYSCALL) { 159 | } else if (e->type == TRACY_EVENT_QUIT) { 160 | printf(_b("EVENT_QUIT from %d with signal %s (%ld)\n"), 161 | e->child->pid, get_signal_name(e->signal_num), 162 | e->signal_num); 163 | if (e->child->pid == tracy->fpid) { 164 | printf(_g("Our first child died.\n")); 165 | } 166 | 167 | tracy_remove_child(e->child); 168 | continue; 169 | } 170 | 171 | if (!tracy_children_count(tracy)) { 172 | break; 173 | } 174 | 175 | tracy_continue(e, 0); 176 | } 177 | 178 | return 0; 179 | } 180 | 181 | 182 | Tracy hooks 183 | ----------- 184 | 185 | Tracy allows one hooking into any signal sent to a tracee as 186 | well as any system call executed by a tracee. 187 | The return values of the hooks (callbacks) determine the action that 188 | tracy will take. 189 | 190 | See `Signal hook`_ and `System call hooks`_ for examples. 191 | 192 | Signal hook 193 | ~~~~~~~~~~~ 194 | 195 | Tracy allows hooking into signals as well. One can hook 196 | into any signal to a tracee like this: 197 | 198 | .. code-block:: c 199 | 200 | int hook_sig(struct tracy_event * e) { 201 | if (e->signal_num == SIGTERM) { 202 | return TRACY_HOOK_SUPPRESS; 203 | } 204 | return TRACY_HOOK_CONTINUE; 205 | } 206 | 207 | struct tracy * t = tracy_init(...); 208 | tracy_set_signal_hook(t, hook_sig); 209 | 210 | 211 | System call hooks 212 | ~~~~~~~~~~~~~~~~~ 213 | 214 | .. code-block:: c 215 | 216 | int hook_write(struct tracy_event * e) { 217 | if (e->child->pre_syscall) { 218 | printf("Pre-write system call\n"); 219 | } else { 220 | printf("Pre-write system call\n"); 221 | } 222 | return TRACY_HOOK_CONTINUE; 223 | } 224 | 225 | struct tracy * t = tracy_init(...); 226 | tracy_set_hook(t, "write", TRACY_NATIVE_ABI, hook_write); 227 | 228 | Hook return values 229 | ~~~~~~~~~~~~~~~~~~ 230 | 231 | - **TRACY_HOOK_CONTINUE** 232 | 233 | Return this inside a hook when you want the execution to resume normally. 234 | 235 | - **TRACY_HOOK_KILL_CHILD** 236 | 237 | Return this inside a hook if you want the child to be killed on hook return. 238 | 239 | - **TRACY_HOOK_ABORT** 240 | 241 | Return this to completely kill tracy. Currently tracy will kill all the 242 | children and then generate a **TRACY_EVENT_NONE**. 243 | 244 | Currently tracy kills its own process as well by calling exit(). 245 | 246 | - **TRACY_HOOK_SUPPRESS** 247 | 248 | Return this *only* from a signal hook. This will cause the signal that 249 | would normally be sent to be suppressed instead. 250 | 251 | * **TRACY_HOOK_DETACH_CHILD** 252 | 253 | Return this if the child should be detached. Only valid for syscall hooks. 254 | 255 | - **TRACY_HOOK_DENY** 256 | 257 | Return this **only** from a system call hook. This will cause the 258 | current system call to be denied. 259 | 260 | The system call will be replaced by a getpid(2) and the return value will 261 | be set to **-ENOSYS**. 262 | 263 | System call modification 264 | ------------------------ 265 | 266 | Changing the arguments 267 | ~~~~~~~~~~~~~~~~~~~~~~ 268 | 269 | .. code-block:: c 270 | 271 | int hook_write(struct tracy_event * e) { 272 | struct tracy_sc_args a; 273 | 274 | if (e->child->pre_syscall) { 275 | if (e->args.a0 == 2) { 276 | memcpy(&a, &(e->args), sizeof(struct tracy_sc_args)); 277 | a.a0 = 1; 278 | if (tracy_modify_syscall_args(e->child, a.syscall, &a)) { 279 | return TRACY_HOOK_ABORT; 280 | } 281 | } 282 | } 283 | 284 | return TRACY_HOOK_CONTINUE; 285 | } 286 | 287 | 288 | Denying a system call 289 | ~~~~~~~~~~~~~~~~~~~~~ 290 | 291 | .. code-block:: c 292 | 293 | int hook_write(struct tracy_event * e) { 294 | if (e->child->pre_syscall) { 295 | if(e->args.a0 == 1) { 296 | printf("Denying write to stdout\n"); 297 | return TRACY_HOOK_DENY; 298 | } 299 | 300 | return TRACY_HOOK_CONTINUE; 301 | } 302 | 303 | 304 | System call injection 305 | --------------------- 306 | 307 | Synchronous injection 308 | ~~~~~~~~~~~~~~~~~~~~~ 309 | 310 | .. code-block:: c 311 | 312 | int _write(struct tracy_event * e) { 313 | long ret; 314 | if (tracy_inject_syscall(e->child, get_syscall_number_abi("write", e->abi), &(e->args), &ret)) 315 | return TRACY_HOOK_ABORT; 316 | 317 | printf("Returned: %ld\n", ret); 318 | 319 | return TRACY_HOOK_CONTINUE; 320 | } 321 | 322 | Asynchronous injection 323 | ~~~~~~~~~~~~~~~~~~~~~~ 324 | 325 | .. code-block:: c 326 | 327 | int _write(struct tracy_event * e) { 328 | if (e->child->inj.injected) { 329 | printf("We just injected something. Result: %ld\n", e->args.return_code); 330 | return 0; 331 | } 332 | 333 | if (tracy_inject_syscall_async(e->child, get_syscall_number_abi("write", e->abi), &(e->args), &_write)) 334 | return TRACY_HOOK_ABORT; 335 | 336 | return TRACY_HOOK_CONTINUE; 337 | } 338 | 339 | Cleaning up 340 | ----------- 341 | 342 | 343 | -------------------------------------------------------------------------------- /doc/index.rst: -------------------------------------------------------------------------------- 1 | .. Tracy documentation master file, created by 2 | sphinx-quickstart on Mon Mar 19 11:35:38 2012. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to Tracy's documentation! 7 | ================================= 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | 12 | intro.rst 13 | examples.rst 14 | reference.rst 15 | devdoc.rst 16 | 17 | Indices and tables 18 | ================== 19 | 20 | * :ref:`genindex` 21 | * :ref:`modindex` 22 | * :ref:`search` 23 | 24 | -------------------------------------------------------------------------------- /doc/intro.rst: -------------------------------------------------------------------------------- 1 | Introduction to Tracy 2 | ===================== 3 | 4 | Tracy is a library written in C that makes it easy to trace, modify and inject 5 | system calls on Linux. Currently the only supported platform is Linux, 6 | but we are working on supporting other platforms. 7 | 8 | While Tracy has been in development for quite a while, there's still some issues 9 | to be ironed out before we will make an 'official' release. 10 | 11 | Motivation 12 | ---------- 13 | 14 | Cross platform system call tracing is not a fun task; especially since ptrace 15 | differs quite a bit per platform and operating system. We aimed to create a 16 | mostly cross platform tracing library with additional features such as system 17 | call modification and injection. A more detailed motivation (amongst other 18 | things) can be found in the report we wrote on Tracy. 19 | 20 | Limitations 21 | ----------- 22 | 23 | Tracy is still under heavy development and we may break the API a few more 24 | times. Regardless, current main 'limitations' are: 25 | 26 | - Tracy in general needs more testing; any kind of application using Tracy 27 | helps, as well as writing actual tests. 28 | - Platform support is currently limited to Linux. 29 | 30 | Source code 31 | ----------- 32 | 33 | Source code can currently be found on github: 34 | 35 | git clone git://github.com/MerlijnWajer/tracy.git 36 | 37 | Contributing 38 | ------------ 39 | 40 | You can find us at: 41 | 42 | - Our mailing list tracy@ the free mailing list website: freelists.org 43 | - Our IRC channel: #tracy on freenode.net 44 | - Our Bug tracker (currently github; will be migrated later) 45 | -------------------------------------------------------------------------------- /doc/reference.rst: -------------------------------------------------------------------------------- 1 | API Reference 2 | ============= 3 | 4 | This section contains documentation on all public functions exported by Tracy. 5 | 6 | Tracy instance 7 | ~~~~~~~~~~~~~~ 8 | 9 | A Tracy instance is required for all tracy functions; make sure you 10 | only create and initialise one. 11 | Creating more than one instance in one process 12 | (especially: using them) is madness and should not be done. 13 | 14 | .. _rtracy_init: 15 | 16 | tracy_init 17 | ---------- 18 | .. code-block:: c 19 | 20 | struct tracy *tracy_init(long opt); 21 | 22 | 23 | tracy_init creates the tracy structure and returns a pointer to this structure 24 | on success. Current possible options for *opt*: 25 | 26 | - *TRACY_TRACY_CHILDREN* (Trace children of the tracee created with fork, 27 | vfork or clone.) 28 | - *TRACY_USE_SAFE_TRACE* (Do not rely on Linux' auto-trace on fork abilities 29 | and instead use our own safe implementation.) 30 | - *TRACY_MEMORY_FALLBACK* (Use fallback mechanism is fast memory access fails.) 31 | - *TRACY_VERBOSE* 32 | (Tracy will be verbose and print information about events and internal 33 | logic.) 34 | - *TRACY_VERBOSE_SIGNAL* 35 | (Tracy will print information relating to signals.) 36 | - *TRACY_VERBOSE_SYSCALL* 37 | (Tracy will print information relating to system calls.) 38 | 39 | 40 | Multiple options can be passed by using the OR operator. 41 | 42 | Returns the tracy instance created. 43 | 44 | tracy_free 45 | ---------- 46 | 47 | .. code-block:: c 48 | 49 | void tracy_free(struct tracy *t); 50 | 51 | 52 | tracy_free frees all the data associated with tracy: 53 | 54 | - Any children being traced are either detached (if we attached) or killed 55 | if tracy started them. 56 | 57 | 58 | tracy_quit 59 | ---------- 60 | 61 | .. code-block:: c 62 | 63 | void tracy_quit(struct tracy* t, int exitcode); 64 | 65 | tracy_quit frees all the structures, kills or detaches from all the 66 | children and then calls exit() with *exitcode*. Use tracy_free if you want to 67 | gracefully free tracy. 68 | 69 | .. _rtracy_main: 70 | 71 | tracy_main 72 | ---------- 73 | 74 | .. code-block:: c 75 | 76 | int tracy_main(struct tracy *tracy); 77 | 78 | 79 | 80 | tracy_main is a simple tracy-event loop. 81 | Helper for RAD Tracy deployment 82 | 83 | .. _rtracy_exec: 84 | 85 | tracy_exec 86 | --------------- 87 | 88 | .. code-block:: c 89 | 90 | struct tracy_child *tracy_exec(struct tracy *t, char** argv); 91 | 92 | 93 | tracy_exec is the function tracy offers to actually start tracing a 94 | process. tracy_exec safely forks, asks to be traced in the child and 95 | then executes the given process with possible arguments. 96 | 97 | Returns the first tracy_child. You don't really need to store this as each 98 | event will be directly coupled to a child. 99 | 100 | tracy_attach 101 | ------------ 102 | 103 | .. code-block:: c 104 | 105 | struct tracy_child *tracy_attach(struct tracy *t, pid_t pid); 106 | 107 | 108 | tracy_attach attaches to a running process specified by pid. 109 | 110 | Returns the structure of the attached child. 111 | 112 | Events 113 | ~~~~~~ 114 | 115 | tracy_wait_event 116 | ---------------- 117 | 118 | .. code-block:: c 119 | 120 | struct tracy_event *tracy_wait_event(struct tracy *t, pid_t pid); 121 | 122 | 123 | tracy_wait_event waits for an event to occur on any child when pid is -1; 124 | else on a specific child. 125 | 126 | tracy_wait_event will detect any new children and automatically add them to 127 | the appropriate datastructures. 128 | 129 | An *event* is either a signal or a system call. tracy_wait_event populates 130 | events with the right data; arguments; system call number, etc. 131 | 132 | Returns an event pointer or NULL. 133 | 134 | If NULL is returned, you should probably kill all the children and stop 135 | tracy; NULL indicates something went wrong internally such as the inability 136 | to allocate memory or an unsolvable ptrace error. 137 | 138 | tracy_continue 139 | -------------- 140 | 141 | .. code-block:: c 142 | 143 | int tracy_continue(struct tracy_event *s, int sigoverride); 144 | 145 | 146 | 147 | tracy_continue continues the execution of the child that owns event *s*. 148 | If the event was caused by a signal to the child, the signal 149 | is passed along to the child, unless *sigoverride* is set to nonzero. 150 | 151 | tracy_kill_child 152 | ---------------- 153 | 154 | tracy_kill_child attemps to kill the child *c*; it does so using ptrace with 155 | the PTRACE_KILL argument. 156 | 157 | Return 0 upon success, -1 upon failure. 158 | 159 | tracy_detach_child 160 | ------------------- 161 | 162 | .. code-block:: c 163 | 164 | int tracy_detach_child(struct tracy_child *c); 165 | 166 | 167 | tracy_detach_child attempts to detach from child *c*. 168 | Returns 0 upon success; -1 upon failure. 169 | 170 | 171 | get_syscall_name_abi 172 | -------------------- 173 | 174 | .. code-block:: c 175 | 176 | char* get_syscall_name_abi(int syscall, int abi); 177 | 178 | 179 | get_syscall_number_abi 180 | ---------------------- 181 | 182 | .. code-block:: c 183 | 184 | char* get_syscall_number_abi(char * syscall, int abi); 185 | 186 | 187 | get_signal_name 188 | --------------- 189 | 190 | .. code-block:: c 191 | 192 | char* get_signal_name(int signal); 193 | 194 | 195 | Hooks 196 | ~~~~~ 197 | 198 | tracy_set_hook 199 | -------------- 200 | 201 | .. code-block:: c 202 | 203 | int tracy_set_hook(struct tracy *t, char *syscall, long abi, tracy_hook_func func); 204 | 205 | Set the hook for a system call with the given ABI. If you want to hook a system 206 | call on multiple ABIs, you need to call tracy_set_hook for each ABI. 207 | Valid values for *abi* depend on the platform, but **TRACY_ABI_NATIVE** is 208 | always available and is the sane choice unless you are trying to mix several 209 | ABIs. 210 | 211 | Hook functions should return: 212 | 213 | * TRACY_HOOK_CONTINUE if everything is fine. 214 | * TRACY_HOOK_DETACH_CHILD if the child should be detached. 215 | * TRACY_HOOK_KILL_CHILD if the child should be killed. 216 | * TRACY_HOOK_ABORT if tracy should kill all childs and quit. 217 | 218 | Returns 0 on success, -1 on failure. 219 | 220 | tracy_unset_hook 221 | ---------------- 222 | 223 | .. code-block:: c 224 | 225 | int tracy_unset_hook(struct tracy *t, char *syscall, long abi); 226 | 227 | Unset the specified syscall hook. 228 | 229 | Returns 0 on success, -1 on failure. 230 | 231 | tracy_set_signal_hook 232 | --------------------- 233 | 234 | .. code-block:: c 235 | 236 | int tracy_set_signal_hook(struct tracy *t, tracy_hook_func f); 237 | 238 | Set the signal hook. Called on each signal[1]. 239 | 240 | Returns 0 on success. 241 | 242 | [1] Called on every signal that the tracy user should recieve, 243 | the SIGTRAP's from ptrace are not sent, and neither is the first 244 | SIGSTOP. 245 | Possible return values by the tracy_hook_func for the signal: 246 | 247 | * TRACY_HOOK_CONTINUE will send the signal and proceed as normal 248 | * TRACY_HOOK_SUPPRESS will not send a signal and process as normal 249 | * TRACY_HOOK_KILL_CHILD if the child should be killed. 250 | * TRACY_HOOK_ABORT if tracy should kill all childs and quit. 251 | 252 | 253 | tracy_set_default_hook 254 | ---------------------- 255 | 256 | .. code-block:: c 257 | 258 | int tracy_set_default_hook(struct tracy *t, tracy_hook_func f); 259 | 260 | 261 | 262 | tracy_set_default_hook 263 | 264 | Set the default hook. (Called when a syscall occurs and no hook is installed 265 | for the system call. *func* is the function to be set as hook. 266 | 267 | Returns 0 on success. 268 | 269 | 270 | tracy_execute_hook 271 | ------------------ 272 | 273 | .. code-block:: c 274 | 275 | int tracy_execute_hook(struct tracy *t, char *syscall, struct tracy_event *e); 276 | 277 | 278 | 279 | Returns the return value of the hook. Hooks should return: 280 | 281 | * TRACY_HOOK_CONTINUE if everything is fine. 282 | * TRACY_HOOK_DETACH_CHILD if the child should be detached. 283 | * TRACY_HOOK_KILL_CHILD if the child should be killed. 284 | * TRACY_HOOK_ABORT if tracy should kill all childs and quit. 285 | * TRACY_HOOK_NOHOOK is no hook is in place for this system call. 286 | 287 | 288 | Memory manipulation 289 | ~~~~~~~~~~~~~~~~~~~ 290 | 291 | tracy_read_mem 292 | -------------- 293 | 294 | .. code-block:: c 295 | 296 | ssize_t tracy_read_mem(struct tracy_child *c, tracy_parent_addr_t dest, tracy_child_addr_t src, size_t n); 297 | 298 | 299 | 300 | tracy_write_mem 301 | ---------------- 302 | 303 | .. code-block:: c 304 | 305 | ssize_t tracy_write_mem(struct tracy_child *c, tracy_child_addr_t dest, tracy_parent_addr_t src, size_t n); 306 | 307 | 308 | 309 | System call injection 310 | ~~~~~~~~~~~~~~~~~~~~~ 311 | 312 | tracy_inject_syscall 313 | -------------------- 314 | 315 | .. code-block:: c 316 | 317 | int tracy_inject_syscall(struct tracy_child *child, long syscall_number, struct tracy_sc_args *a, long *return_code); 318 | 319 | 320 | 321 | Inject a system call in process defined by tracy_child *child*. 322 | The syscall_number is the number of the system call; use 323 | `get_syscall_number_abi`_ to get the right number. 324 | *a* is a pointer to the system 325 | call arguments. The *return_code* will be set to the return code of the 326 | system call. 327 | 328 | Returns 0 on success; -1 on failure. 329 | 330 | tracy_inject_syscall_async 331 | -------------------------- 332 | 333 | .. code-block:: c 334 | 335 | int tracy_inject_syscall_async(struct tracy_child *child, long syscall_number, struct tracy_sc_args *a, tracy_hook_func callback); 336 | 337 | 338 | 339 | Inject a system call in process defined by tracy_child *child*. 340 | The syscall_number is the number of the system call; use 341 | `get_syscall_number_abi`_ to get the right number. 342 | *a* is a pointer to the system call arguments. 343 | 344 | The injection will be asynchronous; meaning that this function will return 345 | before the injection has finished. To be notified when injection has 346 | finished, pass a value other than NULL as *callback*. 347 | 348 | System call modification 349 | ~~~~~~~~~~~~~~~~~~~~~~~~ 350 | 351 | tracy_modify_syscall_args 352 | ------------------------- 353 | 354 | .. code-block:: c 355 | 356 | int tracy_modify_syscall_args(struct tracy_child *child, long syscall_number, struct tracy_sc_args *a); 357 | 358 | 359 | 360 | This function allows you to change the system call number and arguments of a 361 | paused child. You can use it to change a0..a5 362 | 363 | Changes the system call number to *syscall_number* and if *a* is not NULL, 364 | changes the argument registers of the system call to the contents of *a*. 365 | 366 | Returns 0 on success, -1 on failure. 367 | 368 | tracy_modify_syscall_regs 369 | ------------------------- 370 | 371 | .. code-block:: c 372 | 373 | int tracy_modify_syscall_regs(struct tracy_child *child, long syscall_number, struct tracy_sc_args *a); 374 | 375 | 376 | 377 | This function allows you to change the system call number and arguments of a 378 | paused child. 379 | Changes the system call number to *syscall_number* and if *a* is not NULL, 380 | changes the registers of the system call to the contents of *a*. These 381 | registers currently include: ip, sp, return_code. 382 | 383 | Changing the IP is particularly important when doing system call injection. 384 | Make sure that you set it to the right value when passing args to this 385 | function. 386 | 387 | Returns 0 on success, -1 on failure. 388 | 389 | 390 | tracy_deny_syscall 391 | ------------------ 392 | 393 | .. code-block:: c 394 | 395 | int tracy_deny_syscall(struct tracy_child* child); 396 | 397 | tracy_mmap 398 | ---------- 399 | 400 | .. code-block:: c 401 | 402 | int tracy_mmap(struct tracy_child *child, tracy_child_addr_t *ret, tracy_child_addr_t addr, size_t length, int prot, int flags, int fd, off_t pgoffset); 403 | 404 | 405 | tracy_munmap 406 | ------------ 407 | 408 | .. code-block:: c 409 | 410 | int tracy_munmap(struct tracy_child *child, long *ret, tracy_child_addr_t addr, size_t length); 411 | 412 | 413 | -------------------------------------------------------------------------------- /doc/tracy.dot: -------------------------------------------------------------------------------- 1 | digraph totaltracy { 2 | subgraph child { 3 | node [style=filled, color="#aaaaaa"] 4 | 5 | trace -> execve -> execution -> { syscall ; signal } 6 | 7 | execution -> execution 8 | 9 | syscall [label="System Call"] 10 | signal [label="Signal"] 11 | 12 | syscallexe [label="Execute System Call"] 13 | } 14 | 15 | subgraph tracy { 16 | node [style=filled,color=white] 17 | style=filled 18 | color=grey 19 | 20 | 21 | waitevent -> eventchld 22 | eventchld [label="Event from child"] 23 | eventchld -> {pre_syscall ; post_syscall ; got_signal} 24 | 25 | got_signal -> signal_anal 26 | 27 | pre_start_injection [label="Change system call number and registers"] 28 | pre_stop_injection [label="Reset system call number, registers and Program Counter"] 29 | pre_syscall -> pre_start_injection -> internal_event -> 30 | pre_stop_injection -> pre_syscall 31 | 32 | post_start_injection [label="Change Program Counter"] 33 | post_start_injection_2 [label="Set system call number and registers"] 34 | post_stop_injection [label="Save and reset return value"] 35 | 36 | post_syscall -> post_start_injection -> post_start_injection_2 -> 37 | post_stop_injection -> post_syscall 38 | 39 | } 40 | 41 | fork -> {trace ; waitevent} 42 | 43 | signal_anal -> { signal ; execution } 44 | pre_syscall -> syscallexe 45 | post_syscall -> execution 46 | 47 | { signal ; syscall ; syscallexe } -> eventchld 48 | 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /gentoo/sys-libs/tracy/Manifest: -------------------------------------------------------------------------------- 1 | EBUILD tracy-9999.ebuild 589 SHA256 f3a916281803dc2c0f43e1618dde1d20cb1c48dc216cff503c510ee0fa356315 SHA512 adc7c618e81555307e880f286adb824ca71fcab65f673e315f2efc769670c4f6dd70f859b9459d6290edb88e17b0f2b05d7f94be4db6a695b500858028ec93ea WHIRLPOOL 61eb61514510cc7e5c572859a30b24772721e7c05de285091c64ff7cc09ffee34df25706f06c3dceb6c337ba6171c7597c8a5b90530e39fb8a2eae63fec11127 2 | -------------------------------------------------------------------------------- /gentoo/sys-libs/tracy/tracy-9999.ebuild: -------------------------------------------------------------------------------- 1 | # Copyright 1999-2013 Gentoo Foundation 2 | # Distributed under the terms of the GNU General Public License v2 3 | # $Header: $ 4 | 5 | EAPI=4 6 | 7 | inherit eutils git-2 8 | 9 | DESCRIPTION="Tracy, a system call tracer and injector." 10 | HOMEPAGE="http://wizzup.org/tracy" 11 | SRC_URI="" 12 | 13 | EGIT_REPO_URI="git://github.com/MerlijnWajer/tracy.git" 14 | 15 | LICENSE="GPL-3" 16 | SLOT="0" 17 | KEYWORDS="~amd64 ~arm ~x86" 18 | IUSE="" 19 | 20 | DEPEND="" 21 | RDEPEND="${DEPEND}" 22 | 23 | src_unpack() { 24 | git-2_src_unpack 25 | } 26 | 27 | src_compile() { 28 | cd src && emake 29 | } 30 | 31 | src_install() { 32 | dolib.a src/libtracy.a 33 | dolib.so src/libtracy.so 34 | 35 | insinto /usr/include/tracy 36 | doins src/*.h 37 | } 38 | 39 | -------------------------------------------------------------------------------- /research/abi-proposal/ABI: -------------------------------------------------------------------------------- 1 | ABI Proposal 2 | ============ 3 | 4 | File layout 5 | ----------- 6 | 7 | ABI information: 8 | 9 | arch//arch.h 10 | 11 | ABI detection: 12 | 13 | arch//arch.c 14 | 15 | Syscall definitions: 16 | 17 | arch//syscalls.h 18 | 19 | Generates syscall per abi: 20 | 21 | arch//syscall_.h 22 | 23 | Events 24 | ------ 25 | 26 | The tracy_event structure will be modified with at least an extra variable 27 | describing the current ABI of the event. This can then be used to determine if 28 | the event is hooked; as well as when modifying or injecting system calls. 29 | 30 | struct tracy_event { 31 | ... 32 | 33 | int abi; 34 | } 35 | 36 | Translating syscall numbers to/from strings 37 | ------------------------------------------- 38 | 39 | get_syscall_{name,number} will take an additional argument: int abi. 40 | 41 | Hooking 42 | ------- 43 | 44 | A process is able to mix ABIs. There are several questions we need to tackle: 45 | 46 | 1) What events do we report (by default)? 47 | 2) What do we do with unreported events (by default)? 48 | 49 | Reporting 50 | ********* 51 | 52 | The API could be something like this: 53 | 54 | hook("write", func, TRACY_ABI_NATIVE); 55 | 56 | And: 57 | 58 | hook("write", func, TRACY_ABI_ALL); 59 | 60 | Rationale for TRACY_ABI_NATIVE as default: 61 | It is very hard to work with mixed ABIs, especially in the case with (for 62 | example) a 32 bit and 64 bit ABI. For this reason we believe it would be 63 | best to (by default) only stick to the native ABI for hooking / reporting. 64 | 65 | Unreported Events 66 | ***************** 67 | 68 | In the case that the programmer uses TRACY_ABI_NATIVE; and a non-native system 69 | call is made, we need to decide what to do: 70 | 71 | 1) Do not report any event 72 | 2) Automagically "deny" the system call 73 | 74 | Rationale for 1: 75 | Not reporting any events seems like the most sane option; as this is simply 76 | what the user specified; he only wanted NATIVE events. 77 | 78 | Modification 79 | ------------ 80 | 81 | TODO: Add an ABI option for specifying the ABI. This will require either jumping 82 | to our own code (meaning we have to inject some); or simply temporarily 83 | overriding the instruction we are at (which is not safe, at all) 84 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | def_syscalls.h 2 | -------------------------------------------------------------------------------- /src/BROKEN_WITH_ABI: -------------------------------------------------------------------------------- 1 | tracy-safe-fork / internal_syscall: 2 | - grep for SYS_ and __NR_ ; these can never be valid for multiple ABIs. 3 | 4 | tracy_mmap / tracy_munmap 5 | - should work, but may have problems with 64 bit program using 32 bit abi 6 | (temporarily), because we will probably want to use a 64 bit mmap. 7 | 8 | Python bindings need to be updated. (Go bindings? ☺) 9 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean check-inject tests 2 | 3 | CFLAGS+=-std=gnu99 -pedantic -Wall -Wextra -Werror -Wno-unused-result -pipe 4 | CFLAGS+=-D_POSIX_SOURCE -D_GNU_SOURCE 5 | CFLAGS+=-pthread -fPIC 6 | 7 | 8 | LDFLAGS+=-rdynamic -pthread 9 | 10 | # To build statically, simply do: LDFLAGS=-static make ... 11 | 12 | #CFLAGS+=-O2 13 | #CFLAGS+=-m32 14 | #LDFLAGS+=-m32 15 | 16 | build ?= debug 17 | 18 | include rules.mk 19 | 20 | TRACY_HS=tracy.h ll.h tracyarch.h 21 | TRACY_OS=tracy.o tracy-mem.o tracy-safe-fork.o tracy-modification.o \ 22 | tracy-event.o ll.o trampy.o 23 | 24 | 25 | uname_M = $(shell sh -c 'uname -m 2>/dev/null || echo not') 26 | 27 | arch= 28 | ifeq ($(uname_M),armv5tel) 29 | arch="arm" 30 | else ifeq ($(uname_M),armv7l) 31 | arch="arm" 32 | else ifeq ($(uname_M),x86_64) 33 | arch="x86_64" 34 | else ifeq ($(uname_M),i686) 35 | arch="i686" 36 | else ifeq ($(uname_M),ppc) 37 | arch="ppc" 38 | endif 39 | 40 | 41 | ifeq ($(arch), "x86_64") 42 | ARCH_HS=arch/amd64/arch.h arch/amd64/syscalls.h 43 | ARCH_OS=arch/amd64/arch.o 44 | else ifeq ($(arch), "arm") 45 | ARCH_HS=arch/arm/arch.h arch/arm/syscalls.h 46 | ARCH_OS=arch/arm/arch.o 47 | else ifeq ($(arch), "i686") 48 | ARCH_HS=arch/x86/arch.h arch/x86/syscalls.h 49 | ARCH_OS=arch/x86/arch.o 50 | else ifeq ($(arch), "ppc") 51 | ARCH_HS=arch/ppc/arch.h arch/ppc/syscalls.h 52 | ARCH_OS=arch/ppc/arch.o 53 | else 54 | ARCH_HS= 55 | ARCH_OS= 56 | endif 57 | 58 | default: libtracy.a libtracy.so $(TRACY_OS) $(ARCH_OS) 59 | 60 | 61 | # default is no longer tests 62 | 63 | libtracy.a: $(TRACY_OS) $(ARCH_OS) 64 | ar cr $@ $^ 65 | 66 | libtracy.so: $(TRACY_OS) $(ARCH_OS) 67 | $(CC) -shared -o $@ $^ $(CFLAGS) 68 | 69 | test_binaries=tests/hello tests/base tests/inject-simple \ 70 | tests/thread-simple tests/thread-simple-prog tests/fork \ 71 | tests/fork-prog tests/vfork-prog tests/bounce tests/bash \ 72 | tests/raw-clone tests/deny tests/attach tests/metronome \ 73 | tests/sig_suppress tests/async-inject tests/redirect tests/wxorx \ 74 | tests/abi tests/attach-detach tests/fuzz-write tests/attach-execve \ 75 | tests/faketime tests/llseek 76 | #tests/rwmem 77 | 78 | 79 | tests: $(test_binaries) 80 | #tests/rwmem: tests/rwmem.o $(TRACY_OS) $(ARCH_OS) 81 | tests/wxorx: tests/wxorx.o $(TRACY_OS) $(ARCH_OS) 82 | tests/abi: tests/abi.o $(TRACY_OS) $(ARCH_OS) 83 | tests/base: tests/base.o $(TRACY_OS) $(ARCH_OS) 84 | tests/sig_suppress: tests/sig_suppress.o $(TRACY_OS) $(ARCH_OS) 85 | tests/async-inject: tests/async-inject.o $(TRACY_OS) $(ARCH_OS) 86 | tests/redirect: tests/redirect.o $(TRACY_OS) $(ARCH_OS) 87 | tests/bash: tests/bash.o $(TRACY_OS) $(ARCH_OS) 88 | tests/deny: tests/deny.o $(TRACY_OS) $(ARCH_OS) 89 | tests/inject-simple: tests/inject-simple.o $(TRACY_OS) $(ARCH_OS) 90 | tests/thread-simple: tests/thread-simple.o $(TRACY_OS) $(ARCH_OS) 91 | tests/thread-simple-prog: tests/thread-simple-prog.o 92 | tests/fork: tests/fork.o $(TRACY_OS) $(ARCH_OS) 93 | tests/bounce: tests/bounce.o trampy.o 94 | tests/attach: tests/attach.o $(TRACY_OS) $(ARCH_OS) 95 | tests/attach-detach: tests/attach-detach.o $(TRACY_OS) $(ARCH_OS) 96 | tests/attach-execve: tests/attach-execve.o $(TRACY_OS) $(ARCH_OS) 97 | tests/fuzz-write: tests/fuzz-write.o $(TRACY_OS) $(ARCH_OS) 98 | tests/llseek: tests/llseek.o $(TRACY_OS) $(ARCH_OS) 99 | tests/metronome: tests/metronome.o 100 | tests/faketime: tests/faketime.o $(TRACY_OS) $(ARCH_OS) 101 | 102 | #check-rwmem: tests/rwmem tests/hello 103 | # tests/rwmem tests/hello 104 | 105 | # Tracy core 106 | tracy.o: def_syscalls.h def_signals.h $(TRACY_HS) $(ARCH_HS) 107 | tracy-mem.o: $(TRACY_HS) 108 | tracy-safe-fork.o: trampy.h $(TRACY_HS) 109 | tracy-modification.o: $(TRACY_HS) 110 | ll.o: ll.h 111 | 112 | # Tracy dependent test files. 113 | tests/redirect.o: $(TRACY_HS) 114 | tests/wxorx.o: $(TRACY_HS) 115 | tests/bash.o: $(TRACY_HS) 116 | tests/abi.o: $(TRACY_HS) 117 | tests/deny.o: $(TRACY_HS) 118 | tests/sig_suppress.o: $(TRACY_HS) 119 | tests/async-inject.o: $(TRACY_HS) 120 | tests/base.o: $(TRACY_HS) 121 | tests/inject-simple.o: $(TRACY_HS) 122 | tests/thread-simple.o: $(TRACY_HS) 123 | tests/fork.o: $(TRACY_HS) 124 | #tests/rwmem.o: $(TRACY_HS) 125 | tests/bouce.o: trampy.h 126 | tests/attach.o: $(TRACY_HS) 127 | tests/attach-execve.o: $(TRACY_HS) 128 | tests/attach-detach.o: $(TRACY_HS) 129 | tests/fuzz-write.o: $(TRACY_HS) 130 | tests/faketime.o: $(TRACY_HS) 131 | tests/llseek.o: $(TRACY_HS) 132 | 133 | def_syscalls.h: 134 | echo "#include " | $(CC) $(CFLAGS) - -E -P -dM \ 135 | | grep "define SYS" | cut -f2 -d" " | \ 136 | sed 's/SYS_//;s/\(.*\)/DEF_SYSCALL(&)/' > def_syscalls.h 137 | 138 | 139 | # XXX: Depending on uname -m is bad because it doesn't allow us to build tracy 140 | # for say x86. (Although I don't think you want that on amd64, because of ABI 141 | # mixing) Still, we need a build option for it. Like make platform=amd64 142 | 143 | ifeq ($(arch),"x86_64") 144 | # 145 | # *** AMD64 *** 146 | # 147 | arch/amd64/arch.o: $(TRACY_HS) arch/amd64/syscalls.h 148 | arch/amd64/syscalls.h: $(TRACY_HS) arch/amd64/syscall_amd64.h \ 149 | arch/amd64/syscall_x86.h arch/amd64/syscall_x32.h 150 | 151 | arch/amd64/syscall_amd64.h: 152 | echo "#include " | $(CC) $(CFLAGS) - -E -P -dM | \ 153 | grep "define SYS" | cut -f2 -d" " | \ 154 | ( echo "#define DEF_SYSCALL(NAME) {#NAME, SYS_ ## NAME}," ; \ 155 | sed 's/SYS_//;s/\(.*\)/DEF_SYSCALL(&)/' ; echo "{NULL, -1}") \ 156 | | $(CC) $(CFLAGS) - -E -P | ( echo "#include " ; cat ) \ 157 | | grep -v '# ' | $(CC) $(CFLAGS) -E -P - | grep '{.*' \ 158 | > arch/amd64/syscall_amd64.h 159 | arch/amd64/syscall_x86.h: 160 | echo "#include " | $(CC) $(CFLAGS) - -E -P -m32 -dM | \ 161 | grep "define SYS" | cut -f2 -d" " | \ 162 | ( echo "#define DEF_SYSCALL(NAME) {#NAME, SYS_ ## NAME}," ; \ 163 | sed 's/SYS_//;s/\(.*\)/DEF_SYSCALL(&)/' ; echo "{NULL, -1}") \ 164 | | $(CC) $(CFLAGS) - -E -P -m32 | ( echo "#include " ; cat ) \ 165 | | grep -v '# ' | $(CC) $(CFLAGS) - -E -P -m32 | grep '{.*' \ 166 | > arch/amd64/syscall_x86.h 167 | arch/amd64/syscall_x32.h: 168 | echo "#include " | $(CC) $(CFLAGS) - -E -P -mx32 -dM | \ 169 | grep "define SYS" | cut -f2 -d" " | \ 170 | ( echo "#define DEF_SYSCALL(NAME) {#NAME, SYS_ ## NAME}," ; \ 171 | sed 's/SYS_//;s/\(.*\)/DEF_SYSCALL(&)/' ; echo "{NULL, -1}") \ 172 | | $(CC) $(CFLAGS) - -E -P -mx32 | ( echo "#include " ; cat ) \ 173 | | grep -v '# ' | $(CC) $(CFLAGS) - -E -P -mx32 | grep '{.*' \ 174 | > arch/amd64/syscall_x32.h 175 | else ifeq ($(arch),"arm") 176 | # 177 | # *** ARM *** 178 | # 179 | arch/arm/arch.o: $(TRACY_HS) arch/arm/syscalls.h 180 | arch/arm/syscalls.h: $(TRACY_HS) arch/arm/syscall_eabi.h 181 | 182 | arch/arm/syscall_eabi.h: 183 | echo "#include " | $(CC) $(CFLAGS) - -E -P -dM | \ 184 | grep "define SYS" | cut -f2 -d" " \ 185 | | ( echo "#define DEF_SYSCALL(NAME) {#NAME, SYS_ ## NAME}," ; \ 186 | sed 's/SYS_//;s/\(.*\)/DEF_SYSCALL(&)/' ; echo "{NULL, -1}") \ 187 | | $(CC) $(CFLAGS) - -E -P | ( echo "#include " ; cat ) \ 188 | | grep -v '# '| $(CC) $(CFLAGS) -E -P - | grep '{.*' \ 189 | > arch/arm/syscall_eabi.h 190 | else ifeq ($(arch),"i686") 191 | # 192 | # *** x86 *** 193 | # 194 | arch/x86/arch.o: $(TRACY_HS) arch/x86/syscalls.h 195 | arch/x86/syscalls.h: $(TRACY_HS) arch/x86/syscall_x86.h 196 | 197 | arch/x86/syscall_x86.h: 198 | echo "#include " | $(CC) $(CFLAGS) - -E -P -dM | \ 199 | grep "define SYS" | cut -f2 -d" " \ 200 | | ( echo "#define DEF_SYSCALL(NAME) {#NAME, SYS_ ## NAME}," ; \ 201 | sed 's/SYS_//;s/\(.*\)/DEF_SYSCALL(&)/' ; echo "{NULL, -1}") \ 202 | | $(CC) $(CFLAGS) - -E -P | ( echo "#include " ; cat ) \ 203 | | grep -v '# '| $(CC) $(CFLAGS) -E -P - | grep '{.*' \ 204 | > arch/x86/syscall_x86.h 205 | else ifeq ($(arch),"ppc") 206 | # 207 | # *** ppc *** 208 | # 209 | arch/ppc/arch.o: $(TRACY_HS) arch/ppc/syscalls.h 210 | arch/ppc/syscalls.h: $(TRACY_HS) arch/ppc/syscall_ppc.h 211 | 212 | arch/ppc/syscall_ppc.h: 213 | echo "#include " | $(CC) $(CFLAGS) - -E -P -dM | \ 214 | grep "define SYS" | cut -f2 -d" " \ 215 | | ( echo "#define DEF_SYSCALL(NAME) {#NAME, SYS_ ## NAME}," ; \ 216 | sed 's/SYS_//;s/\(.*\)/DEF_SYSCALL(&)/' ; echo "{NULL, -1}") \ 217 | | $(CC) $(CFLAGS) - -E -P | ( echo "#include " ; cat ) \ 218 | | grep -v '# '| $(CC) $(CFLAGS) -E -P - | grep '{.*' \ 219 | > arch/ppc/syscall_ppc.h 220 | 221 | endif 222 | 223 | clean: 224 | rm *.o *.a *.so def_syscalls.h tests/*.o -f $(test_binaries) \ 225 | arch/amd64/syscall_*.h arch/amd64/*.o \ 226 | arch/arm/syscall_*.h arch/arm/*.o \ 227 | arch/x86/syscall_*.h arch/x86/*.o \ 228 | arch/ppc/syscall_*.h arch/ppc/*.o 229 | -------------------------------------------------------------------------------- /src/arch/amd64/arch.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../../tracy.h" 4 | 5 | #define T_SYSCALL 0x050f 6 | #define T_INT0x80 0x80cd 7 | #define T_SYSENTER 0x340f 8 | 9 | int get_abi(struct tracy_event *s) { 10 | unsigned long sysinstr; 11 | struct TRACY_REGS_NAME a; 12 | 13 | /* TRACY_SYSCALL_OPSIZE should not be larger than sizeof(unsigned long) */ 14 | TRACY_BUILD_BUG(sizeof(unsigned long) < TRACY_SYSCALL_OPSIZE) 15 | 16 | 17 | if (tracy_read_mem(s->child, &sysinstr, (char*)s->args.ip - TRACY_SYSCALL_OPSIZE, 18 | sizeof(char) * TRACY_SYSCALL_OPSIZE) < TRACY_SYSCALL_OPSIZE) 19 | return -1; 20 | 21 | sysinstr &= ((1 << (TRACY_SYSCALL_OPSIZE * 8)) - 1); 22 | PTRACE_CHECK(PTRACE_GETREGS, s->child->pid, 0, &a, -1); 23 | 24 | #if 0 25 | printf("CS = %lx; sysinstr = %lx; ip = %lx\n", a.cs, sysinstr, s->args.ip); 26 | #endif 27 | 28 | if (a.cs == 0x23) { 29 | return TRACY_ABI_X86; 30 | } 31 | if (a.cs == 0x33) { 32 | switch (sysinstr) { 33 | case T_SYSCALL: 34 | return TRACY_ABI_AMD64; 35 | 36 | case T_SYSENTER: 37 | case T_INT0x80: 38 | return TRACY_ABI_X86; 39 | } 40 | } 41 | 42 | return -1; 43 | } 44 | 45 | long get_reg(struct TRACY_REGS_NAME *r, int reg, int abi) { 46 | switch (abi) { 47 | case TRACY_ABI_AMD64: 48 | case TRACY_ABI_X32: 49 | switch (reg) { 50 | case 0: 51 | return r->rdi; 52 | break; 53 | case 1: 54 | return r->rsi; 55 | break; 56 | case 2: 57 | return r->rdx; 58 | break; 59 | case 3: 60 | return r->r10; 61 | break; 62 | case 4: 63 | return r->r8; 64 | break; 65 | case 5: 66 | return r->r9; 67 | break; 68 | } 69 | 70 | break; 71 | case TRACY_ABI_X86: 72 | switch (reg) { 73 | case 0: 74 | return r->rbx; 75 | break; 76 | case 1: 77 | return r->rcx; 78 | break; 79 | case 2: 80 | return r->rdx; 81 | break; 82 | case 3: 83 | return r->rsi; 84 | break; 85 | case 4: 86 | return r->rdi; 87 | break; 88 | case 5: 89 | return r->rbp; 90 | break; 91 | } 92 | break; 93 | } 94 | 95 | #pragma message "get_reg: return -1 could also be a valid register value, maybe do something else?" 96 | /* We should never reach this */ 97 | return -1; 98 | } 99 | 100 | long set_reg(struct TRACY_REGS_NAME *r, int reg, int abi, long val) { 101 | switch (abi) { 102 | case TRACY_ABI_AMD64: 103 | case TRACY_ABI_X32: 104 | switch (reg) { 105 | case 0: 106 | r->rdi = val; 107 | break; 108 | case 1: 109 | r->rsi = val; 110 | break; 111 | case 2: 112 | r->rdx = val; 113 | break; 114 | case 3: 115 | r->r10 = val; 116 | break; 117 | case 4: 118 | r->r8 = val; 119 | break; 120 | case 5: 121 | r->r9 = val; 122 | break; 123 | } 124 | break; 125 | 126 | case TRACY_ABI_X86: 127 | switch (reg) { 128 | case 0: 129 | r->rbx = val; 130 | break; 131 | case 1: 132 | r->rcx = val; 133 | break; 134 | case 2: 135 | r->rdx = val; 136 | break; 137 | case 3: 138 | r->rsi = val; 139 | break; 140 | case 4: 141 | r->rdi = val; 142 | break; 143 | case 5: 144 | r->rbp = val; 145 | break; 146 | } 147 | break; 148 | 149 | } 150 | return 0; 151 | 152 | } 153 | -------------------------------------------------------------------------------- /src/arch/amd64/arch.h: -------------------------------------------------------------------------------- 1 | #define TRACY_REGS_NAME user_regs_struct 2 | /* pt_regs doesn't work - user_regs_struct has more fields */ 3 | 4 | #define TRACY_SYSCALL_OPSIZE 2 5 | 6 | #define TRACY_SYSCALL_REGISTER orig_rax 7 | #define TRACY_SYSCALL_N rax 8 | 9 | #define TRACY_RETURN_CODE rax 10 | #define TRACY_IP_REG rip 11 | 12 | #define TRACY_STACK_POINTER rsp 13 | 14 | #define TRACY_NR_MMAP __NR_mmap 15 | 16 | /* Register used to pass trampy code the tracer PID */ 17 | #define TRAMPY_PID_REG r8 18 | #define TRAMPY_PID_ARG a4 19 | 20 | /* 21 | * TODO: 22 | * - Implement x32 in arch/amd64/arch.c 23 | */ 24 | #define TRACY_ABI_COUNT 3 25 | 26 | #define TRACY_ABI_AMD64 0 27 | #define TRACY_ABI_X86 1 28 | #define TRACY_ABI_X32 2 29 | 30 | #define TRACY_ABI_NATIVE TRACY_ABI_AMD64 31 | 32 | 33 | struct tracy_event; 34 | 35 | int get_abi(struct tracy_event *s); 36 | long get_reg(struct TRACY_REGS_NAME *r, int reg, int abi); 37 | long set_reg(struct TRACY_REGS_NAME *r, int reg, int abi, long val); 38 | -------------------------------------------------------------------------------- /src/arch/amd64/syscalls.h: -------------------------------------------------------------------------------- 1 | static struct tracy_abi_syscall amd64_sc[] = { 2 | #include "syscall_amd64.h" 3 | }; 4 | 5 | static struct tracy_abi_syscall x86_sc[] = { 6 | #include "syscall_x86.h" 7 | }; 8 | 9 | static struct tracy_abi_syscall x32_sc[] = { 10 | #include "syscall_x32.h" 11 | }; 12 | 13 | struct tracy_abi_syscall* syscalls_abi[TRACY_ABI_COUNT] = { 14 | amd64_sc, 15 | x86_sc, 16 | x32_sc 17 | }; 18 | -------------------------------------------------------------------------------- /src/arch/arm/arch.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../../tracy.h" 4 | 5 | int get_abi(struct tracy_event *s) { 6 | (void)s; 7 | 8 | return 0; 9 | } 10 | 11 | long get_reg(struct TRACY_REGS_NAME *r, int reg, int abi) { 12 | switch (abi) { 13 | case TRACY_ABI_EABI: 14 | case TRACY_ABI_OABI: 15 | switch (reg) { 16 | case 0: 17 | return r->ARM_r0; 18 | break; 19 | case 1: 20 | return r->ARM_r1; 21 | break; 22 | case 2: 23 | return r->ARM_r2; 24 | break; 25 | case 3: 26 | return r->ARM_r3; 27 | break; 28 | case 4: 29 | return r->ARM_r4; 30 | break; 31 | case 5: 32 | return r->ARM_r5; 33 | break; 34 | } 35 | 36 | break; 37 | } 38 | 39 | /* We should never reach this */ 40 | return -1; 41 | } 42 | 43 | long set_reg(struct TRACY_REGS_NAME *r, int reg, int abi, long val) { 44 | switch (abi) { 45 | case TRACY_ABI_EABI: 46 | case TRACY_ABI_OABI: 47 | switch (reg) { 48 | case 0: 49 | r->ARM_r0 = val; 50 | break; 51 | case 1: 52 | r->ARM_r1 = val; 53 | break; 54 | case 2: 55 | r->ARM_r2 = val; 56 | break; 57 | case 3: 58 | r->ARM_r3 = val; 59 | break; 60 | case 4: 61 | r->ARM_r4 = val; 62 | break; 63 | case 5: 64 | r->ARM_r5 = val; 65 | break; 66 | } 67 | break; 68 | 69 | } 70 | return 0; 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/arch/arm/arch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * See this for more info on ARM: 3 | * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0041c/ch09s02s02.html 4 | */ 5 | #define TRACY_REGS_NAME pt_regs 6 | 7 | /* Unsure about some of the registers */ 8 | #define TRACY_SYSCALL_OPSIZE 8 9 | 10 | /* ARM EABI puts System call number in r7 */ 11 | #define TRACY_SYSCALL_REGISTER ARM_r7 12 | #define TRACY_SYSCALL_N ARM_r7 13 | 14 | #define TRACY_RETURN_CODE ARM_r0 15 | 16 | #define TRACY_IP_REG ARM_pc 17 | 18 | #define TRACY_STACK_POINTER ARM_sp 19 | 20 | /* 21 | * ARM does nasty stuff 22 | * http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=3105/4 23 | */ 24 | 25 | #define TRACY_NR_MMAP __NR_mmap2 26 | 27 | /* Register used to pass trampy code the tracer PID */ 28 | #define TRAMPY_PID_REG ARM_r4 29 | #define TRAMPY_PID_ARG a4 30 | 31 | 32 | /* TODO: OABI */ 33 | #define TRACY_ABI_COUNT 2 34 | 35 | #define TRACY_ABI_EABI 0 36 | #define TRACY_ABI_OABI 1 37 | 38 | #define TRACY_ABI_NATIVE TRACY_ABI_EABI 39 | 40 | struct tracy_event; 41 | 42 | int get_abi(struct tracy_event *s); 43 | long get_reg(struct TRACY_REGS_NAME *r, int reg, int abi); 44 | long set_reg(struct TRACY_REGS_NAME *r, int reg, int abi, long val); 45 | -------------------------------------------------------------------------------- /src/arch/arm/syscalls.h: -------------------------------------------------------------------------------- 1 | static struct tracy_abi_syscall eabi_sc[] = { 2 | #include "syscall_eabi.h" 3 | }; 4 | 5 | 6 | struct tracy_abi_syscall* syscalls_abi[TRACY_ABI_COUNT] = { 7 | eabi_sc, 8 | }; 9 | -------------------------------------------------------------------------------- /src/arch/ppc/arch.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../../tracy.h" 4 | 5 | int get_abi(struct tracy_event *s) { 6 | (void)s; 7 | 8 | return 0; 9 | } 10 | 11 | long get_reg(struct TRACY_REGS_NAME *r, int reg, int abi) { 12 | switch (abi) { 13 | case TRACY_ABI_PPC: 14 | switch (reg) { 15 | case 0: 16 | return r->gpr[3]; 17 | break; 18 | case 1: 19 | return r->gpr[4]; 20 | break; 21 | case 2: 22 | return r->gpr[5]; 23 | break; 24 | case 3: 25 | return r->gpr[6]; 26 | break; 27 | case 4: 28 | return r->gpr[7]; 29 | break; 30 | case 5: 31 | return r->gpr[8]; 32 | break; 33 | } 34 | 35 | break; 36 | } 37 | 38 | /* We should never reach this */ 39 | return -1; 40 | } 41 | 42 | long set_reg(struct TRACY_REGS_NAME *r, int reg, int abi, long val) { 43 | switch (abi) { 44 | case TRACY_ABI_PPC: 45 | switch (reg) { 46 | case 0: 47 | r->gpr[3] = val; 48 | break; 49 | case 1: 50 | r->gpr[4] = val; 51 | break; 52 | case 2: 53 | r->gpr[5] = val; 54 | break; 55 | case 3: 56 | r->gpr[6] = val; 57 | break; 58 | case 4: 59 | r->gpr[7] = val; 60 | break; 61 | case 5: 62 | r->gpr[8] = val; 63 | break; 64 | } 65 | break; 66 | 67 | } 68 | return 0; 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/arch/ppc/arch.h: -------------------------------------------------------------------------------- 1 | #define TRACY_REGS_NAME pt_regs 2 | 3 | #define TRACY_SYSCALL_OPSIZE 4 4 | 5 | #define TRACY_SYSCALL_REGISTER gpr[0] 6 | #define TRACY_SYSCALL_N orig_gpr3 7 | 8 | #define TRACY_RETURN_CODE result 9 | 10 | #define TRACY_IP_REG link 11 | 12 | #define TRACY_STACK_POINTER gpr[1] 13 | 14 | #define TRACY_NR_MMAP __NR_mmap2 15 | 16 | /* Register used to pass trampy code the tracer PID */ 17 | #define TRAMPY_PID_REG gpr[9] /*TODO :fix this*/ 18 | #define TRAMPY_PID_ARG a4 19 | 20 | 21 | #define TRACY_ABI_COUNT 1 22 | 23 | #define TRACY_ABI_PPC 0 24 | 25 | #define TRACY_ABI_NATIVE TRACY_ABI_PPC 26 | 27 | struct tracy_event; 28 | 29 | int get_abi(struct tracy_event *s); 30 | long get_reg(struct TRACY_REGS_NAME *r, int reg, int abi); 31 | long set_reg(struct TRACY_REGS_NAME *r, int reg, int abi, long val); 32 | -------------------------------------------------------------------------------- /src/arch/ppc/syscalls.h: -------------------------------------------------------------------------------- 1 | static struct tracy_abi_syscall ppc_sc[] = { 2 | #include "syscall_ppc.h" 3 | }; 4 | 5 | 6 | struct tracy_abi_syscall* syscalls_abi[TRACY_ABI_COUNT] = { 7 | ppc_sc, 8 | }; 9 | -------------------------------------------------------------------------------- /src/arch/x86/arch.c: -------------------------------------------------------------------------------- 1 | #include "../../tracy.h" 2 | 3 | int get_abi(struct tracy_event *s) { 4 | (void)s; 5 | return TRACY_ABI_NATIVE; 6 | } 7 | 8 | long get_reg(struct TRACY_REGS_NAME *r, int reg, int abi) { 9 | (void) abi; 10 | /* We have only one ABI */ 11 | 12 | switch (reg) { 13 | case 0: 14 | return r->ebx; 15 | break; 16 | case 1: 17 | return r->ecx; 18 | break; 19 | case 2: 20 | return r->edx; 21 | break; 22 | case 3: 23 | return r->esi; 24 | break; 25 | case 4: 26 | return r->edi; 27 | break; 28 | case 5: 29 | return r->ebp; 30 | break; 31 | } 32 | 33 | return -1; 34 | } 35 | 36 | long set_reg(struct TRACY_REGS_NAME *r, int reg, int abi, long val) { 37 | (void) abi; 38 | /* We have only one ABI */ 39 | 40 | switch (reg) { 41 | case 0: 42 | r->ebx = val; 43 | break; 44 | case 1: 45 | r->ecx = val; 46 | break; 47 | case 2: 48 | r->edx = val; 49 | break; 50 | case 3: 51 | r->esi = val; 52 | break; 53 | case 4: 54 | r->edi = val; 55 | break; 56 | case 5: 57 | r->ebp = val; 58 | break; 59 | } 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /src/arch/x86/arch.h: -------------------------------------------------------------------------------- 1 | #define TRACY_REGS_NAME user_regs_struct /* pt_regs doesn't work */ 2 | 3 | #define TRACY_SYSCALL_OPSIZE 2 4 | 5 | #define TRACY_SYSCALL_REGISTER orig_eax 6 | #define TRACY_SYSCALL_N eax 7 | 8 | #define TRACY_RETURN_CODE eax 9 | #define TRACY_IP_REG eip 10 | 11 | #define TRACY_STACK_POINTER esp 12 | 13 | #define TRACY_NR_MMAP __NR_mmap2 14 | 15 | /* Register used to pass trampy code the tracer PID */ 16 | #define TRAMPY_PID_REG ebp 17 | #define TRAMPY_PID_ARG a5 18 | 19 | #define TRACY_ABI_COUNT 1 20 | 21 | #define TRACY_ABI_X86 0 22 | 23 | #define TRACY_ABI_NATIVE TRACY_ABI_X86 24 | 25 | struct tracy_event; 26 | 27 | int get_abi(struct tracy_event *s); 28 | 29 | long get_reg(struct TRACY_REGS_NAME *r, int reg, int abi); 30 | long set_reg(struct TRACY_REGS_NAME *r, int reg, int abi, long val); 31 | -------------------------------------------------------------------------------- /src/arch/x86/syscalls.h: -------------------------------------------------------------------------------- 1 | static struct tracy_abi_syscall x86_sc[] = { 2 | #include "syscall_x86.h" 3 | }; 4 | 5 | 6 | struct tracy_abi_syscall* syscalls_abi[TRACY_ABI_COUNT] = { 7 | x86_sc 8 | }; 9 | 10 | -------------------------------------------------------------------------------- /src/def_signals.h: -------------------------------------------------------------------------------- 1 | DEF_SIGNAL(SIGBUS) 2 | DEF_SIGNAL(SIGTTIN) 3 | DEF_SIGNAL(SIGTTOU) 4 | DEF_SIGNAL(SIGPROF) 5 | DEF_SIGNAL(SIGALRM) 6 | DEF_SIGNAL(SIGFPE) 7 | DEF_SIGNAL(SIGSTKFLT) 8 | DEF_SIGNAL(SIGUSR1) 9 | DEF_SIGNAL(SIGURG) 10 | DEF_SIGNAL(SIGIO) 11 | DEF_SIGNAL(SIGQUIT) 12 | DEF_SIGNAL(SIGABRT) 13 | DEF_SIGNAL(SIGTRAP) 14 | DEF_SIGNAL(SIGVTALRM) 15 | DEF_SIGNAL(SIGSEGV) 16 | DEF_SIGNAL(SIGCONT) 17 | DEF_SIGNAL(SIGPIPE) 18 | DEF_SIGNAL(SIGWINCH) 19 | DEF_SIGNAL(SIGXFSZ) 20 | DEF_SIGNAL(SIGHUP) 21 | DEF_SIGNAL(SIGCHLD) 22 | DEF_SIGNAL(SIGSYS) 23 | DEF_SIGNAL(SIGSTOP) 24 | DEF_SIGNAL(SIGUSR2) 25 | DEF_SIGNAL(SIGTSTP) 26 | DEF_SIGNAL(SIGKILL) 27 | DEF_SIGNAL(SIGXCPU) 28 | DEF_SIGNAL(SIGPWR) 29 | DEF_SIGNAL(SIGILL) 30 | DEF_SIGNAL(SIGINT) 31 | DEF_SIGNAL(SIGTERM) 32 | -------------------------------------------------------------------------------- /src/ll.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #include 18 | 19 | #include "ll.h" 20 | 21 | struct tracy_ll* ll_init(void) { 22 | struct tracy_ll* ll = malloc(sizeof(struct tracy_ll)); 23 | ll->head = NULL; 24 | 25 | return ll; 26 | } 27 | 28 | int ll_free(struct tracy_ll* ll) { 29 | if(ll->head) 30 | while (ll->head->next) { 31 | ll_del(ll, ll->head->next->id); 32 | } 33 | 34 | if (ll->head) { 35 | ll_del(ll, ll->head->id); 36 | } 37 | 38 | return 0; 39 | } 40 | 41 | int ll_add(struct tracy_ll* ll, int id, void* d) { 42 | struct tracy_ll_item *t, *tt; 43 | 44 | t = ll_find(ll, id); 45 | if (t) 46 | return -1; 47 | 48 | t = malloc(sizeof(struct tracy_ll_item)); 49 | t->data = d; 50 | t->id = id; 51 | t->prev = NULL; 52 | t->next = NULL; 53 | 54 | if (!ll->head) { 55 | ll->head = t; 56 | } else { 57 | tt = ll->head; 58 | 59 | while(tt->next) { 60 | tt = tt->next; 61 | } 62 | 63 | tt->next = t; 64 | t->prev = tt; 65 | } 66 | 67 | return 0; 68 | } 69 | 70 | int ll_del(struct tracy_ll* ll, int id) { 71 | struct tracy_ll_item *t = ll_find(ll, id); 72 | 73 | if(t) { 74 | if (t->prev) 75 | t->prev->next = t->next; 76 | if (t->next) 77 | t->next->prev = t->prev; 78 | 79 | if (ll->head == t) { 80 | if (t->next) { 81 | ll->head = t->next; 82 | } else { 83 | ll->head = NULL; 84 | free(t); 85 | return 0; 86 | } 87 | } 88 | 89 | free(t); 90 | return 0; 91 | } 92 | 93 | return -1; 94 | } 95 | 96 | struct tracy_ll_item* ll_find(struct tracy_ll* ll, int id) { 97 | struct tracy_ll_item *t; 98 | 99 | t = ll->head; 100 | 101 | while (t) { 102 | if (t->id == id) 103 | return t; 104 | t = t->next; 105 | } 106 | 107 | return NULL; 108 | } 109 | -------------------------------------------------------------------------------- /src/ll.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #ifndef LL_H 18 | #define LL_H 19 | 20 | struct tracy_ll_item { 21 | void* data; 22 | int id; 23 | struct tracy_ll_item* prev; 24 | struct tracy_ll_item* next; 25 | }; 26 | 27 | struct tracy_ll { 28 | struct tracy_ll_item *head; 29 | }; 30 | 31 | struct tracy_ll* ll_init(void); 32 | int ll_free(struct tracy_ll* ll); 33 | 34 | int ll_add(struct tracy_ll* ll, int id, void* d); 35 | int ll_del(struct tracy_ll* ll, int id); 36 | struct tracy_ll_item *ll_find(struct tracy_ll* ll, int id); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/revwr.py: -------------------------------------------------------------------------------- 1 | from pytracy import Tracy, Child, TRACE_CHILDREN 2 | import sys 3 | 4 | 5 | class Reverser(Tracy): 6 | """Reverses written data to file descriptors.""" 7 | 8 | def __init__(self, options=0): 9 | Tracy.__init__(self, TRACE_CHILDREN | options) 10 | self.hook('write', self._handle_write) 11 | 12 | def _handle_write(self, e, a, pre): 13 | c = Child.from_event(e) 14 | if pre and a.a0 in (1, 2): 15 | buf = c.read(a.a1, a.a2) 16 | if buf: 17 | c.write(a.a1, buf[::-1]) 18 | 19 | if __name__ == '__main__': 20 | t = Reverser() 21 | t.execute(*sys.argv[1:]) 22 | t.main() 23 | -------------------------------------------------------------------------------- /src/rules.mk: -------------------------------------------------------------------------------- 1 | ifeq "$(build)" "debug" 2 | CFLAGS += -ggdb 3 | else ifeq "$(build)" "release" 4 | CFLAGS += -O2 -fomit-frame-pointer 5 | else 6 | $(error unknown build setting: '$(build)') 7 | endif 8 | -------------------------------------------------------------------------------- /src/soxy/Makefile: -------------------------------------------------------------------------------- 1 | 2 | .PHONY: clean default tests 3 | 4 | CFLAGS+=-std=c99 -pedantic -Wall -Wextra -pipe #-Werror 5 | #CFLAGS+=-ansi -pedantic -Wall -Wextra -pipe #-Werror 6 | CFLAGS+=-I ../ 7 | CFLAGS+=-D_POSIX_SOURCE 8 | CFLAGS+=-D_GNU_SOURCE 9 | CFLAGS+=-ggdb -pthread 10 | #CFLAGS+=-O2 11 | #CFLAGS+=-m32 12 | 13 | LDFLAGS+=-rdynamic 14 | 15 | BINARY=soxy 16 | 17 | default: soxy 18 | 19 | OBJECTS:=../libtracy.a 20 | TESTS:=tst/fork tst/mmap 21 | 22 | tests: $(TESTS) 23 | 24 | soxy: soxy.c $(OBJECTS) 25 | $(CC) soxy.c $(CFLAGS) $(OBJECTS) $(LDFLAGS) -o soxy -I.. 26 | 27 | clean: 28 | rm *.o soxy -f $(TESTS) 29 | -------------------------------------------------------------------------------- /src/soxy/README: -------------------------------------------------------------------------------- 1 | Soxy, your favourite proxy 2 | ========================== 3 | 4 | Soxy is a proxy that transparently provides a proxy for any kind of application. 5 | Under the hood it uses system call interception (with ptrace) to transparently 6 | redirect any traffic to the proxy server. 7 | 8 | Features: 9 | - IPv4. 10 | - TCP. 11 | 12 | Future work: 13 | - VPN variant of soxy. (ptrace-based vpn) 14 | -------------------------------------------------------------------------------- /src/soxy/app/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean check-inject 2 | 3 | CFLAGS+=-ansi -pedantic -Wall -Wextra -Werror 4 | CFLAGS+=-D_POSIX_SOURCE 5 | CFLAGS+=-ggdb 6 | CFLAGS+=-pthread 7 | CFLAGS+=-I ../tracy 8 | #CFLAGS+=-O2 9 | #CFLAGS+=-m32 10 | 11 | TESTS=ll_test loggy dotty county 12 | 13 | default: $(TESTS) 14 | 15 | ll_test: ll_test.c 16 | $(CC) ll_test.c ../tracy/ll.o $(CFLAGS) $(LDFLAGS) -o ll_test 17 | 18 | loggy: loggy.c 19 | $(CC) loggy.c ../tracy/libtracy.a $(CFLAGS) $(LDFLAGS) -o loggy 20 | 21 | dotty: dotty.c 22 | $(CC) dotty.c ../tracy/libtracy.a $(CFLAGS) $(LDFLAGS) -o dotty 23 | 24 | county: county.c 25 | $(CC) county.c ../tracy/libtracy.a $(CFLAGS) $(LDFLAGS) -o county 26 | 27 | 28 | clean: 29 | rm *.o ll_test loggy dotty county wxorx -f 30 | -------------------------------------------------------------------------------- /src/soxy/app/README: -------------------------------------------------------------------------------- 1 | Most files in here are outdated, not functional and contain lots of bugs, 2 | including design bugs. We are aware of these and will fix them if we feel like 3 | it. 4 | 5 | -------------------------------------------------------------------------------- /src/soxy/app/county.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | 18 | /* 19 | * County. 20 | * 21 | */ 22 | 23 | #define _GNU_SOURCE 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #include "tracy.h" 31 | #include "ll.h" 32 | 33 | /* For __NR_ */ 34 | #include 35 | 36 | #include 37 | 38 | struct tracy_ll * ll; 39 | 40 | int all(struct tracy_event *e) { 41 | struct tracy_ll_item *i; 42 | long syscall; 43 | 44 | if(e->child->pre_syscall) 45 | return TRACY_HOOK_CONTINUE; 46 | 47 | syscall = e->syscall_num; 48 | 49 | i = ll_find(ll, syscall); 50 | if (i) { 51 | i->data = (void*)((long)(i->data) + 1); 52 | } else { 53 | ll_add(ll, syscall, (void*)1); 54 | } 55 | 56 | return TRACY_HOOK_CONTINUE; 57 | } 58 | 59 | static void print_stats(void) { 60 | struct tracy_ll_item *cur; 61 | cur = ll->head; 62 | 63 | while (cur) { 64 | printf("Syscall: %s called %ld times.\n", get_syscall_name(cur->id), 65 | (long)cur->data); 66 | 67 | cur = cur->next; 68 | } 69 | 70 | return; 71 | } 72 | 73 | int main(int argc, char** argv) { 74 | struct tracy *tracy; 75 | 76 | ll = ll_init(); 77 | tracy = tracy_init(TRACY_TRACE_CHILDREN); 78 | 79 | if (argc < 2) { 80 | printf("Usage: county \n"); 81 | return EXIT_FAILURE; 82 | } 83 | 84 | if (tracy_set_default_hook(tracy, all)) { 85 | printf("Failed to hook default hook.\n"); 86 | return EXIT_FAILURE; 87 | } 88 | 89 | argv++; argc--; 90 | if (!tracy_exec(tracy, argv)) { 91 | perror("tracy_exec returned NULL"); 92 | return EXIT_FAILURE; 93 | } 94 | 95 | tracy_main(tracy); 96 | 97 | tracy_free(tracy); 98 | 99 | print_stats(); 100 | 101 | ll_free(ll); 102 | 103 | return 0; 104 | } 105 | -------------------------------------------------------------------------------- /src/soxy/app/dotty.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | /* Dotty. 18 | * 19 | * Generate .dot files from system calls made by processes. 20 | * 21 | * Dotty is: very incomplete, has quite as few bugs, doesn't trace fork(2) and 22 | * vfork(2), at least not in the graph, and the .dot output becomes quite 23 | * useless after the .dot file grows to extreme proportions. 24 | * 25 | */ 26 | 27 | #define _GNU_SOURCE 28 | #include 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | #include "tracy.h" 35 | #include "ll.h" 36 | 37 | /* For __NR_ */ 38 | #include 39 | 40 | #include 41 | 42 | FILE* dot; 43 | 44 | int foo(struct tracy_event *e) { 45 | long count; 46 | 47 | if (!e->child->pre_syscall) { 48 | printf("clone: %ld\n", e->args.return_code); 49 | e->child->custom = (void*) ((long)e->child->custom + 1); 50 | count = (long) e->child->custom; 51 | fprintf(dot, "pid_%d_%ld [label=\"%s\"]\n", e->child->pid, count - 1, get_syscall_name(e->syscall_num)); 52 | fprintf(dot, "pid_%d_%ld -> pid_%d_%ld\n", e->child->pid, count - 1, e->child->pid, count); 53 | fprintf(dot, "pid_%d_%ld -> pid_%ld_%ld\n", e->child->pid, count, e->args.return_code, 0l); 54 | 55 | } else { 56 | e->child->custom = (void*) ((long)e->child->custom + 1); 57 | count = (long) e->child->custom; 58 | fprintf(dot, "pid_%d_%ld [label=\"%s\"]\n", e->child->pid, count - 1, get_syscall_name(e->syscall_num)); 59 | fprintf(dot, "pid_%d_%ld -> pid_%d_%ld\n", e->child->pid, count - 1, e->child->pid, count); 60 | } 61 | 62 | return 0; 63 | } 64 | 65 | int all(struct tracy_event *e) { 66 | long count; 67 | 68 | e->child->custom = (void*) ((long)e->child->custom + 1); 69 | count = (long) e->child->custom; 70 | if (count == 1) { 71 | fprintf(dot, "pid_%d_%ld\n", e->child->pid, count - 1); 72 | fprintf(dot, "pid_%d_%ld -> pid_%d_%ld\n", e->child->pid, count - 1, e->child->pid, count); 73 | } 74 | fprintf(dot, "pid_%d_%ld [label=\"%s\"]\n", e->child->pid, count - 1, get_syscall_name(e->syscall_num)); 75 | fprintf(dot, "pid_%d_%ld -> pid_%d_%ld\n", e->child->pid, count - 1, e->child->pid, count); 76 | 77 | return 0; 78 | } 79 | 80 | int main(int argc, char** argv) { 81 | struct tracy *tracy; 82 | 83 | tracy = tracy_init(TRACY_TRACE_CHILDREN); 84 | 85 | if (argc < 2) { 86 | printf("Usage: dotty \n"); 87 | return EXIT_FAILURE; 88 | } 89 | 90 | if (tracy_set_hook(tracy, "clone", foo)) { 91 | printf("Failed to hook write syscall.\n"); 92 | return EXIT_FAILURE; 93 | } 94 | 95 | if (tracy_set_default_hook(tracy, all)) { 96 | printf("Failed to hook default hook.\n"); 97 | return EXIT_FAILURE; 98 | } 99 | 100 | argv++; argc--; 101 | if (!tracy_exec(tracy, argv)) { 102 | perror("tracy_exec returned NULL"); 103 | return EXIT_FAILURE; 104 | } 105 | 106 | dot = fopen("out.dot", "w+"); 107 | fprintf(dot, "digraph generated {\n"); 108 | 109 | tracy_main(tracy); 110 | 111 | tracy_free(tracy); 112 | 113 | fprintf(dot, "}\n"); 114 | fclose(dot); 115 | 116 | return 0; 117 | } 118 | -------------------------------------------------------------------------------- /src/soxy/app/fork.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #define _GNU_SOURCE 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | int main () { 26 | pid_t pid; 27 | int foo; 28 | printf("f: Hello\n"); 29 | 30 | /* pid = fork(); */ 31 | puts("Executing fork() in a safe environment now"); 32 | pid = syscall(__NR_fork); 33 | puts("Done with fork in a safe environment... we're free of the endless loop."); 34 | 35 | if (!pid) { 36 | printf("f: You should not yet see this\n"); 37 | } else { 38 | /* sleep(5); */ 39 | printf("f: See this first\n"); 40 | wait(&foo); 41 | printf("f: Child is dead\n"); 42 | } 43 | 44 | printf("f: Done\n"); 45 | 46 | return 0; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /src/soxy/app/get-request.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | if(argc < 4) { 13 | fprintf(stderr, "Usage: %s \n", argv[0]); 14 | return EXIT_FAILURE; 15 | } 16 | 17 | int fd, len; struct sockaddr_in addr; char buf[256]; 18 | 19 | fd = socket(AF_INET, SOCK_STREAM, 0); 20 | 21 | snprintf(buf, sizeof(buf), "GET / HTTP/1.0\r\nHost: %s\r\n\r\n", argv[1]); 22 | 23 | addr.sin_family = AF_INET; 24 | addr.sin_addr.s_addr = inet_addr(argv[2]); 25 | addr.sin_port = htons(atoi(argv[3])); 26 | 27 | connect(fd, (struct sockaddr *) &addr, sizeof(addr)); 28 | 29 | send(fd, buf, strlen(buf), 0); 30 | 31 | while ((len = recv(fd, buf, 1, 0)) > 0) { 32 | fwrite(buf, len, 1, stdout); 33 | } 34 | close(fd); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /src/soxy/app/ll_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #include 18 | #include 19 | #include 20 | 21 | #include "ll.h" 22 | 23 | int main() { 24 | struct tracy_ll *l; 25 | struct tracy_ll_item *t; 26 | char *s, *s2, *s3; 27 | 28 | s = malloc(sizeof(char) * 10); 29 | s2 = malloc(sizeof(char) * 10); 30 | s3 = malloc(sizeof(char) * 10); 31 | 32 | l = ll_init(); 33 | 34 | strcpy(s, "hello"); 35 | strcpy(s2, "world"); 36 | strcpy(s3, "forty-two"); 37 | ll_add(l, 0, s); 38 | ll_add(l, 1, s2); 39 | ll_add(l, 2, s3); 40 | printf("Inserting clone results: %d\n", ll_add(l, 2, s3)); 41 | 42 | t = ll_find(l, 0); 43 | printf("LL(0) says %s\n", (char*)t->data); 44 | printf("LL(0)->next says %s\n", (char*)t->next->data); 45 | printf("LL(0)->next->next says %s\n", (char*)t->next->next->data); 46 | printf("LL(0)->next->next->prev->prev says %s\n", (char*)t->next->next->prev->prev->data); 47 | 48 | 49 | ll_del(l, 0); 50 | printf("Deleting 0\n"); 51 | 52 | ll_del(l, 2); 53 | ll_del(l, 1); 54 | ll_del(l, 3); 55 | 56 | t = ll_find(l, 1); 57 | if (t) 58 | printf("LL(1) says %s\n", (char*)t->data); 59 | 60 | 61 | ll_free(l); 62 | 63 | return 0; 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/soxy/app/loggy.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #define _GNU_SOURCE 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "tracy.h" 25 | #include "ll.h" 26 | 27 | /* For __NR_ */ 28 | #include 29 | 30 | /* For MAX_PATH */ 31 | #include 32 | 33 | /* For O_RDONLY */ 34 | #include 35 | 36 | /* File descriptors overwrite each other atm if a child has the same fd, 37 | * this is bad. Needs a different way to log. */ 38 | FILE *logs[1024]; 39 | 40 | int fc; 41 | 42 | /* We'd better just hook into write(), close(), recv*() and others. */ 43 | int log_open(struct tracy_event *e) { 44 | int fd; 45 | char *s; 46 | 47 | if (e->child->pre_syscall) { 48 | 49 | if (e->args.a1 == O_RDONLY) { 50 | printf("Opened read only\n"); 51 | return 0; 52 | } 53 | 54 | s = malloc(sizeof(char) * PATH_MAX); 55 | tracy_read_mem(e->child, (void*)s, (void*)e->args.a0, sizeof(char) * PATH_MAX); 56 | 57 | printf("Opening %s.\n", s); 58 | free(s); 59 | return 0; 60 | } 61 | 62 | fd = e->args.return_code; 63 | if (fd < 1) 64 | return 0; 65 | 66 | if (e->args.a1 == O_RDONLY) { 67 | return 0; 68 | } 69 | 70 | s = malloc(sizeof(char) * 25); 71 | snprintf(s, 25, "%04d%06d%010d.txt", fd, fc++, e->child->pid); 72 | 73 | logs[fd] = fopen(s, "w+"); 74 | printf("Opening for fd %d\n", fd); 75 | free(s); 76 | 77 | return 0; 78 | } 79 | 80 | int log_socket(struct tracy_event *e) { 81 | int fd; 82 | char *s; 83 | 84 | if (e->child->pre_syscall) 85 | return 0; 86 | 87 | fd = e->args.return_code; 88 | if (fd < 1) 89 | return 0; 90 | 91 | s = malloc(sizeof(char) * 25); 92 | snprintf(s, 25, "%04d%06d%010d.txt", fd, fc++, e->child->pid); 93 | 94 | logs[fd] = fopen(s, "w+"); 95 | printf("Opening for fd (socket) %d\n", fd); 96 | free(s); 97 | 98 | return 0; 99 | } 100 | 101 | int log_close(struct tracy_event *e) { 102 | int fd; 103 | if (!e->child->pre_syscall) 104 | return 0; 105 | 106 | if (e->args.return_code != 0) { 107 | printf("Close returned != 0\n"); 108 | return 0; 109 | } 110 | 111 | fd = e->args.a0; 112 | 113 | printf("close call for fd: %d\n", fd); 114 | 115 | if (!logs[fd]) { 116 | printf("Application bug: closing already closed fd\n"); 117 | return 0; 118 | } 119 | 120 | fclose(logs[fd]); 121 | logs[fd] = NULL; 122 | 123 | return 0; 124 | } 125 | 126 | int log_write(struct tracy_event *e) { 127 | int len, fd; 128 | char* str; 129 | 130 | if (!e->child->pre_syscall) 131 | return 0; 132 | 133 | fd = e->args.a0; 134 | 135 | len = e->args.a2; 136 | str = malloc(sizeof(char) * len); 137 | 138 | tracy_read_mem(e->child, (void*)str, (void*)e->args.a1, sizeof(char) * len); 139 | 140 | /* printf("write call for fd: %ld, str: %s, len: %ld\n", 141 | e->args.a0, str, e->args.a2); */ 142 | 143 | /* printf("Going to write: %s\n", str); */ 144 | if (logs[fd]) 145 | fwrite(str, sizeof(char), len, logs[fd]); 146 | 147 | free(str); 148 | 149 | return 0; 150 | } 151 | 152 | int main(int argc, char** argv) { 153 | struct tracy *tracy; 154 | 155 | fc = 0; 156 | logs[1] = fopen("stdout.txt", "w+"); 157 | logs[2] = fopen("stderr.txt", "w+"); 158 | 159 | tracy = tracy_init(TRACY_TRACE_CHILDREN); 160 | 161 | if (argc < 2) { 162 | printf("Usage: loggy \n"); 163 | return EXIT_FAILURE; 164 | } 165 | 166 | if (tracy_set_hook(tracy, "write", log_write)) { 167 | printf("failed to hook write syscall.\n"); 168 | return EXIT_FAILURE; 169 | } 170 | 171 | if (tracy_set_hook(tracy, "open", log_open)) { 172 | printf("failed to hook open syscall.\n"); 173 | return EXIT_FAILURE; 174 | } 175 | 176 | if (tracy_set_hook(tracy, "socket", log_socket)) { 177 | printf("failed to hook open syscall.\n"); 178 | return EXIT_FAILURE; 179 | } 180 | 181 | if (tracy_set_hook(tracy, "close", log_close)) { 182 | printf("failed to hook close syscall.\n"); 183 | return EXIT_FAILURE; 184 | } 185 | 186 | argv++; argc--; 187 | if (!tracy_exec(tracy, argv)) { 188 | perror("tracy_exec returned NULL"); 189 | return EXIT_FAILURE; 190 | } 191 | 192 | tracy_main(tracy); 193 | 194 | tracy_free(tracy); 195 | 196 | return 0; 197 | } 198 | -------------------------------------------------------------------------------- /src/soxy/app/mmap.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #define _GNU_SOURCE 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | /* For __NR_ */ 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | int foo() { 31 | void *child_addr; 32 | 33 | child_addr = mmap(NULL, sysconf(_SC_PAGESIZE), 34 | PROT_READ, MAP_PRIVATE | MAP_ANON, 35 | -1, 0 36 | ); 37 | 38 | printf("CHILD MMAP LOLOL: %p\n", child_addr); 39 | 40 | return 0; 41 | } 42 | int main() { 43 | foo(); 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /src/soxy/soxy.h: -------------------------------------------------------------------------------- 1 | 2 | typedef struct _proxy_t { 3 | /* temporary map allocated in the child, used during connecting to 4 | the proxy server. */ 5 | tracy_child_addr_t map; 6 | 7 | /* the address of the proxy in use */ 8 | struct in_addr addr; 9 | unsigned short port; 10 | 11 | /* temporary return value */ 12 | int return_code; 13 | int change_return_code; 14 | } proxy_t; 15 | 16 | typedef struct __attribute__((packed)) _soxy_ipv4_request_t { 17 | unsigned char ver; 18 | unsigned char cmd; 19 | unsigned char rsv; 20 | unsigned char atyp; 21 | struct in_addr addr; 22 | unsigned short port; 23 | } soxy_ipv4_request_t; 24 | 25 | typedef struct __attribute__((packed)) _soxy_ipv6_request_t { 26 | unsigned char ver; 27 | unsigned char cmd; 28 | unsigned char rsv; 29 | unsigned char atyp; 30 | struct in6_addr addr; 31 | unsigned short port; 32 | } soxy_ipv6_request_t; 33 | 34 | typedef struct __attribute__((packed)) _soxy_ipv4_reply_t { 35 | unsigned char ver; 36 | unsigned char rep; 37 | unsigned char rsv; 38 | unsigned char atyp; 39 | struct in_addr addr; 40 | unsigned short port; 41 | } soxy_ipv4_reply_t; 42 | 43 | 44 | static int soxy_hook_socket(struct tracy_event *e); 45 | static int soxy_hook_connect(struct tracy_event *e); 46 | static int soxy_connect(struct tracy_event *e, int sockfd, 47 | const struct sockaddr *addr, socklen_t addrlen); 48 | static int soxy_connect_proxy_server(struct tracy_event *e, int fd); 49 | static int soxy_connect_addr(struct tracy_event *e, int fd, 50 | struct sockaddr *addr); 51 | -------------------------------------------------------------------------------- /src/tests/abi-tests/cd80.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | int pid; 5 | 6 | __asm__( 7 | "int $0x80" 8 | : 9 | "=a"(pid) 10 | : 11 | "a"(20) 12 | ); 13 | 14 | printf("Pid: %d\n", pid); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /src/tests/abi-tests/syscall.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | int pid; 5 | 6 | __asm__( 7 | "syscall" 8 | : 9 | "=a"(pid) 10 | : 11 | "a"(20) 12 | ); 13 | 14 | printf("Pid: %d\n", pid); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /src/tests/abi-tests/sysenter.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | int pid; 5 | 6 | __asm__( 7 | "sysenter" 8 | : 9 | "=a"(pid) 10 | : 11 | "a"(20) 12 | ); 13 | 14 | printf("Pid: %d\n", pid); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /src/tests/abi.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #include "../tracy.h" 18 | #include "../ll.h" 19 | 20 | #include 21 | #include 22 | 23 | /* For __NR_ */ 24 | #include 25 | #include 26 | 27 | #define T_SYSCALL 0x0f05 28 | #define T_INT0x80 0x0f34 29 | #define T_SYSENTER 0xcd80 30 | 31 | int abi_detect(struct tracy_event *s) { 32 | #ifdef __x86_64__ 33 | struct TRACY_REGS_NAME a; 34 | char *buf; 35 | unsigned long sysinstr; 36 | #endif 37 | 38 | #ifdef __i386__ 39 | puts("x86"); 40 | #endif 41 | 42 | 43 | #ifdef __x86_64__ 44 | buf = malloc(sizeof(char) * sizeof(unsigned long)); 45 | tracy_read_mem(s->child, buf, (char*)s->args.ip - TRACY_SYSCALL_OPSIZE, 46 | sizeof(char) * TRACY_SYSCALL_OPSIZE); 47 | 48 | buf[0] ^= buf[1]; 49 | buf[1] ^= buf[0]; 50 | buf[0] ^= buf[1]; 51 | sysinstr = *(unsigned long*)buf; 52 | 53 | 54 | PTRACE_CHECK(PTRACE_GETREGS, s->child->pid, 0, &a, -1); 55 | #if 0 56 | if (a.cs == 0x33) { 57 | puts("amd64"); 58 | } else if(a.cs == 0x23) { 59 | puts("x86"); 60 | } 61 | #endif 62 | printf("sysinstr: %lx\n", sysinstr); 63 | if (a.cs == 0x23) { 64 | /* Always 32 bit ABI */ 65 | puts("x86"); 66 | } 67 | if (a.cs == 0x33) { 68 | if (sysinstr == T_SYSCALL) { 69 | puts("amd64"); 70 | } else if ((sysinstr == T_SYSENTER) || (sysinstr == T_INT0x80)) { 71 | puts("x86"); 72 | } 73 | } 74 | #endif 75 | tracy_debug_current(s->child); 76 | 77 | return TRACY_HOOK_CONTINUE; 78 | } 79 | 80 | int main(int argc, char** argv) { 81 | struct tracy *tracy; 82 | 83 | 84 | /* Tracy options */ 85 | tracy = tracy_init(TRACY_TRACE_CHILDREN | TRACY_MEMORY_FALLBACK); 86 | /* 87 | tracy = tracy_init(TRACY_TRACE_CHILDREN | TRACY_VERBOSE | 88 | TRACY_VERBOSE_SIGNAL | TRACY_VERBOSE_SYSCALL); 89 | */ 90 | 91 | if (argc < 2) { 92 | printf("Usage: ./example \n"); 93 | return EXIT_FAILURE; 94 | } 95 | 96 | argv++; argc--; 97 | 98 | tracy_set_default_hook(tracy, abi_detect); 99 | 100 | /* Start child */ 101 | if (!tracy_exec(tracy, argv)) { 102 | perror("tracy_exec"); 103 | return EXIT_FAILURE; 104 | } 105 | 106 | /* Main event-loop */ 107 | tracy_main(tracy); 108 | 109 | tracy_free(tracy); 110 | 111 | return EXIT_SUCCESS; 112 | } 113 | -------------------------------------------------------------------------------- /src/tests/async-inject.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #include "../tracy.h" 18 | #include "../ll.h" 19 | 20 | #include 21 | #include 22 | 23 | /* For __NR_ */ 24 | #include 25 | #include 26 | 27 | int _write(struct tracy_event *e) { 28 | if (e->child->inj.injected) { 29 | printf("We just injected something. Result: %ld\n", e->args.return_code); 30 | return 0; 31 | } 32 | 33 | if (tracy_inject_syscall_async(e->child, __NR_write, &(e->args), &_write)) 34 | return TRACY_HOOK_ABORT; 35 | 36 | return TRACY_HOOK_CONTINUE; 37 | } 38 | 39 | int main(int argc, char** argv) { 40 | struct tracy *tracy; 41 | 42 | /* Tracy options */ 43 | tracy = tracy_init(TRACY_TRACE_CHILDREN | TRACY_VERBOSE | 44 | TRACY_VERBOSE_SIGNAL | TRACY_VERBOSE_SYSCALL); 45 | 46 | tracy_set_hook(tracy, "write", TRACY_ABI_NATIVE, &_write); 47 | 48 | if (argc < 2) { 49 | printf("Usage: ./example \n"); 50 | return EXIT_FAILURE; 51 | } 52 | 53 | argv++; argc--; 54 | 55 | /* Start child */ 56 | if (!tracy_exec(tracy, argv)) { 57 | perror("tracy_exec"); 58 | return EXIT_FAILURE; 59 | } 60 | 61 | /* Main event-loop */ 62 | tracy_main(tracy); 63 | 64 | tracy_free(tracy); 65 | 66 | return EXIT_SUCCESS; 67 | } 68 | -------------------------------------------------------------------------------- /src/tests/attach-detach.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #include "../tracy.h" 18 | 19 | #include 20 | #include 21 | 22 | /* For __NR_ */ 23 | #include 24 | #include 25 | 26 | int hook(struct tracy_event *e) { 27 | (void)e; 28 | puts("Hooked write() a system call. Detaching..."); 29 | 30 | return TRACY_HOOK_DETACH_CHILD; 31 | } 32 | 33 | int main(int argc, char** argv) { 34 | struct tracy *tracy; 35 | pid_t pid; 36 | char *endptr; 37 | 38 | /* Tracy options */ 39 | tracy = tracy_init(TRACY_TRACE_CHILDREN); 40 | 41 | /* Only a PID is required */ 42 | if (argc != 2) { 43 | printf("Usage: %s \n", argv[0]); 44 | return EXIT_FAILURE; 45 | } 46 | 47 | /* Parse PID */ 48 | pid = (int)strtol(argv[1], &endptr, 10); 49 | if (endptr[0]) { 50 | fprintf(stderr, "Invalid PID value\n"); 51 | tracy_free(tracy); 52 | return EXIT_FAILURE; 53 | } 54 | 55 | /* Start child */ 56 | if (!tracy_attach(tracy, pid)) { 57 | perror("tracy_attach"); 58 | tracy_free(tracy); 59 | return EXIT_FAILURE; 60 | } 61 | 62 | tracy_set_hook(tracy, "write", TRACY_ABI_NATIVE, hook); 63 | /*tracy_set_default_hook(tracy, hook);*/ 64 | 65 | /* Main event-loop */ 66 | tracy_main(tracy); 67 | 68 | /* Clean up */ 69 | tracy_free(tracy); 70 | 71 | return EXIT_SUCCESS; 72 | } 73 | -------------------------------------------------------------------------------- /src/tests/attach-execve.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #include "../tracy.h" 18 | 19 | #include 20 | #include 21 | 22 | /* For __NR_ */ 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | int inject_execve(struct tracy_event *e) { 29 | struct tracy_sc_args a; 30 | tracy_child_addr_t mmap_ret = NULL; 31 | long ret; 32 | char *s; 33 | 34 | ret = tracy_mmap(e->child, &mmap_ret, NULL, 4096, PROT_WRITE|PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 35 | tracy_write_mem(e->child, mmap_ret, (tracy_parent_addr_t)"/bin/ls", 8 * sizeof(char)); 36 | /*tracy_write_mem(e->child, mmap_ret, (tracy_parent_addr_t)"/usr/bin/wmii", 15 * sizeof(char));*/ 37 | 38 | printf("Tracy ret: %ld\n", ret); 39 | printf("Tracy ptr: %lx\n", (unsigned long)mmap_ret); 40 | 41 | s = malloc(sizeof(char) * 8); 42 | tracy_read_mem(e->child, (tracy_parent_addr_t)s, mmap_ret, 8 * sizeof(char)); 43 | printf("String: %s\n", s); 44 | 45 | 46 | a.a0 = (unsigned long) mmap_ret; 47 | a.a1 = (long) NULL; 48 | a.a2 = (long) NULL; 49 | 50 | /* 51 | int execve(const char *filename, char *const argv[], 52 | char *const envp[]);*/ 53 | 54 | 55 | tracy_inject_syscall(e->child, __NR_execve, &a, &ret); 56 | printf("Return code: %ld\n", ret); 57 | 58 | return TRACY_HOOK_CONTINUE; 59 | } 60 | 61 | int main(int argc, char** argv) { 62 | struct tracy *tracy; 63 | pid_t pid; 64 | char *endptr; 65 | 66 | /* Tracy options */ 67 | #if 0 68 | tracy = tracy_init(TRACY_TRACE_CHILDREN); 69 | #else 70 | tracy = tracy_init(TRACY_TRACE_CHILDREN | TRACY_VERBOSE | TRACY_VERBOSE_SYSCALL | TRACY_VERBOSE_SIGNAL); 71 | #endif 72 | 73 | /* Only a PID is required */ 74 | if (argc != 2) { 75 | printf("Usage: %s \n", argv[0]); 76 | return EXIT_FAILURE; 77 | } 78 | 79 | /* Parse PID */ 80 | pid = (int)strtol(argv[1], &endptr, 10); 81 | if (endptr[0]) { 82 | fprintf(stderr, "Invalid PID value\n"); 83 | tracy_free(tracy); 84 | return EXIT_FAILURE; 85 | } 86 | 87 | tracy_set_default_hook(tracy, inject_execve); 88 | 89 | /* Start child */ 90 | if (!tracy_attach(tracy, pid)) { 91 | perror("tracy_attach"); 92 | tracy_free(tracy); 93 | return EXIT_FAILURE; 94 | } 95 | 96 | /* Main event-loop */ 97 | tracy_main(tracy); 98 | 99 | /* Clean up */ 100 | tracy_free(tracy); 101 | 102 | return EXIT_SUCCESS; 103 | } 104 | -------------------------------------------------------------------------------- /src/tests/attach.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #include "../tracy.h" 18 | 19 | #include 20 | #include 21 | 22 | /* For __NR_ */ 23 | #include 24 | #include 25 | 26 | int main(int argc, char** argv) { 27 | struct tracy *tracy; 28 | pid_t pid; 29 | char *endptr; 30 | 31 | /* Tracy options */ 32 | #if 0 33 | tracy = tracy_init(TRACY_TRACE_CHILDREN); 34 | #else 35 | tracy = tracy_init(TRACY_TRACE_CHILDREN); 36 | #endif 37 | 38 | /* Only a PID is required */ 39 | if (argc != 2) { 40 | printf("Usage: %s \n", argv[0]); 41 | return EXIT_FAILURE; 42 | } 43 | 44 | /* Parse PID */ 45 | pid = (int)strtol(argv[1], &endptr, 10); 46 | if (endptr[0]) { 47 | fprintf(stderr, "Invalid PID value\n"); 48 | tracy_free(tracy); 49 | return EXIT_FAILURE; 50 | } 51 | 52 | /* Start child */ 53 | if (!tracy_attach(tracy, pid)) { 54 | perror("tracy_attach"); 55 | tracy_free(tracy); 56 | return EXIT_FAILURE; 57 | } 58 | 59 | /* Main event-loop */ 60 | tracy_main(tracy); 61 | 62 | /* Clean up */ 63 | tracy_free(tracy); 64 | 65 | return EXIT_SUCCESS; 66 | } 67 | -------------------------------------------------------------------------------- /src/tests/base.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #include "../tracy.h" 18 | #include "../ll.h" 19 | 20 | #include 21 | #include 22 | 23 | /* For __NR_ */ 24 | #include 25 | #include 26 | 27 | int main(int argc, char** argv) { 28 | struct tracy *tracy; 29 | pid_t pid; 30 | char *endptr; 31 | 32 | /* Tracy options */ 33 | tracy = tracy_init(TRACY_TRACE_CHILDREN | TRACY_VERBOSE | 34 | TRACY_VERBOSE_SIGNAL | TRACY_VERBOSE_SYSCALL); 35 | 36 | if (argc != 2) { 37 | printf("Usage: ./example \n"); 38 | return EXIT_FAILURE; 39 | } 40 | 41 | /* Parse PID */ 42 | pid = (int)strtol(argv[1], &endptr, 10); 43 | if (endptr[0]) { 44 | argv++; argc--; 45 | 46 | /* Start child */ 47 | if (!tracy_exec(tracy, argv)) { 48 | perror("tracy_exec"); 49 | return EXIT_FAILURE; 50 | } 51 | } else { 52 | /* Start child */ 53 | if (!tracy_attach(tracy, pid)) { 54 | perror("tracy_attach"); 55 | tracy_free(tracy); 56 | return EXIT_FAILURE; 57 | } 58 | } 59 | 60 | 61 | /* Main event-loop */ 62 | tracy_main(tracy); 63 | 64 | tracy_free(tracy); 65 | 66 | return EXIT_SUCCESS; 67 | } 68 | -------------------------------------------------------------------------------- /src/tests/bash.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #include "../tracy.h" 18 | #include "../ll.h" 19 | 20 | #include 21 | #include 22 | 23 | /* For __NR_ */ 24 | #include 25 | #include 26 | 27 | int main(int argc, char** argv) { 28 | struct tracy *tracy; 29 | 30 | /* Tracy options */ 31 | tracy = tracy_init(TRACY_TRACE_CHILDREN); 32 | /*tracy = tracy_init(TRACY_TRACE_CHILDREN | TRACY_VERBOSE);*/ 33 | 34 | if (argc < 2) { 35 | printf("Usage: ./example \n"); 36 | return EXIT_FAILURE; 37 | } 38 | 39 | argv++; argc--; 40 | 41 | /* Start child */ 42 | if (!tracy_exec(tracy, argv)) { 43 | perror("tracy_exec"); 44 | return EXIT_FAILURE; 45 | } 46 | 47 | /* Main event-loop */ 48 | tracy_main(tracy); 49 | 50 | tracy_free(tracy); 51 | 52 | return EXIT_SUCCESS; 53 | } 54 | -------------------------------------------------------------------------------- /src/tests/bounce.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "../trampy.h" 7 | 8 | static void _handle_sigusr1(int sig, siginfo_t *info, void *p) 9 | { 10 | printf("Received signal %d from process %d, pointer %p\n", sig, 11 | info->si_pid, p); 12 | 13 | exit(EXIT_SUCCESS); 14 | return; 15 | } 16 | 17 | int main() 18 | { 19 | pid_t pid; 20 | void *safe_entry; 21 | struct sigaction s; 22 | 23 | pid = getpid(); 24 | printf("My PID is: %d\n", pid); 25 | safe_entry= trampy_get_safe_entry(); 26 | 27 | s.sa_sigaction = _handle_sigusr1; 28 | sigemptyset(&s.sa_mask); 29 | s.sa_flags = SA_SIGINFO; 30 | sigaction(SIGUSR1, &s, NULL); 31 | 32 | #ifdef __i386__ 33 | __asm__( 34 | "call *%%eax" 35 | :: 36 | "a"(safe_entry), 37 | "D"(pid) 38 | ); 39 | #elif defined(__x86_64__) 40 | __asm__( 41 | "mov %%rdx, %%r8\n" 42 | "call *%%rax" 43 | :: 44 | "a"(safe_entry), 45 | "rdx"(pid) 46 | ); 47 | #elif defined(__arm__) 48 | __asm__( 49 | "ldr r0, %0\n" 50 | "ldr r4, %1\n" 51 | "mov pc, r0" 52 | :: 53 | "Q"(safe_entry), 54 | "Q"(pid) 55 | ); 56 | #endif 57 | 58 | return 0; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /src/tests/deny.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #include "../tracy.h" 18 | #include "../ll.h" 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | /* For __NR_ */ 25 | #include 26 | #include 27 | 28 | int hook_write(struct tracy_event *e) { 29 | if (e->child->pre_syscall) { 30 | if(e->args.a0 == 1) { 31 | printf("Denying write to stdout\n"); 32 | return TRACY_HOOK_DENY; 33 | } 34 | } else { 35 | } 36 | 37 | return TRACY_HOOK_CONTINUE; 38 | } 39 | 40 | int main(int argc, char** argv) { 41 | struct tracy *tracy; 42 | 43 | /* Tracy options */ 44 | /*tracy = tracy_init(TRACY_TRACE_CHILDREN);*/ 45 | tracy = tracy_init(TRACY_TRACE_CHILDREN); 46 | 47 | if (tracy_set_hook(tracy, "write", TRACY_ABI_NATIVE, hook_write)) { 48 | fprintf(stderr, "Could not hook getpid\n"); 49 | return EXIT_FAILURE; 50 | } 51 | 52 | if (argc < 2) { 53 | printf("Usage: ./example \n"); 54 | return EXIT_FAILURE; 55 | } 56 | 57 | argv++; argc--; 58 | 59 | /* Start child */ 60 | if (!tracy_exec(tracy, argv)) { 61 | perror("tracy_exec"); 62 | return EXIT_FAILURE; 63 | } 64 | 65 | /* Main event-loop */ 66 | tracy_main(tracy); 67 | 68 | tracy_free(tracy); 69 | 70 | return EXIT_SUCCESS; 71 | } 72 | -------------------------------------------------------------------------------- /src/tests/faketime.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | 18 | #include "../tracy.h" 19 | #include "../ll.h" 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | /* TODO 29 | * We need to think/implement the timezone value for gettimeofday 30 | * We need to implement clock_getres(2) still 31 | * 32 | * http://www.catb.org/esr/time-programming/ 33 | */ 34 | 35 | #define set_hook(NAME) \ 36 | if (tracy_set_hook(tracy, #NAME, TRACY_ABI_NATIVE, hook_##NAME)) { \ 37 | printf("Could not hook "#NAME" syscall\n"); \ 38 | return EXIT_FAILURE; \ 39 | } 40 | 41 | /* 42 | int hook_stat(struct tracy_event *e) { 43 | if (e->child->pre_syscall) { 44 | e->child->custom = (void*) tracy_read_string(e->child, (tracy_child_addr_t)e->args.a0); 45 | } else { 46 | printf("stat: %s → %ld\n", (char*)e->child->custom, e->args.return_code); 47 | } 48 | 49 | return TRACY_HOOK_CONTINUE; 50 | } 51 | */ 52 | 53 | int hook_open(struct tracy_event *e) { 54 | if (e->child->pre_syscall) { 55 | e->child->custom = (void*) tracy_read_string(e->child, (tracy_child_addr_t)e->args.a0); 56 | } else { 57 | printf("open: %s → %ld\n", (char*)e->child->custom, e->args.return_code); 58 | } 59 | 60 | return TRACY_HOOK_CONTINUE; 61 | } 62 | 63 | /* TODO: Test hook_time -- but it should work */ 64 | int hook_time(struct tracy_event *e) { 65 | time_t t; 66 | 67 | if (e->child->pre_syscall) { 68 | e->child->custom = (void*)e->args.a0; 69 | } else { 70 | t = 42; 71 | if (e->child->custom) { 72 | tracy_write_mem(e->child, (tracy_child_addr_t)e->child->custom, 73 | (tracy_parent_addr_t)&t, sizeof(time_t)); 74 | } 75 | 76 | e->args.return_code = t; 77 | } 78 | return TRACY_HOOK_CONTINUE; 79 | } 80 | 81 | int hook_clock_gettime(struct tracy_event *e) { 82 | struct timespec tp = {2000, 0}; 83 | int err; 84 | 85 | if (e->child->pre_syscall) { 86 | if (e->args.a0 == CLOCK_REALTIME || e->args.a0 == CLOCK_REALTIME_COARSE) { 87 | e->child->custom = (void*)e->args.a1; 88 | } else { 89 | e->child->custom = NULL; 90 | } 91 | } else { 92 | if (e->child->custom) { 93 | err = tracy_write_mem(e->child, (tracy_child_addr_t)e->child->custom, 94 | (tracy_parent_addr_t)&tp, sizeof(struct timespec)); 95 | 96 | if (err < 0) { 97 | fprintf(stderr, "tracy_write_mem returned %d\n", err); 98 | tracy_kill_child(e->child); 99 | } 100 | } 101 | } 102 | 103 | return TRACY_HOOK_CONTINUE; 104 | } 105 | 106 | int hook_gettimeofday(struct tracy_event *e) { 107 | struct timeval tv = {1700, 0}; 108 | int err; 109 | 110 | if (e->child->pre_syscall) { 111 | e->child->custom = (void*)e->args.a0; 112 | } else { 113 | if (e->child->custom) { 114 | err = tracy_write_mem(e->child, (tracy_child_addr_t)e->child->custom, 115 | (tracy_parent_addr_t)&tv, sizeof(struct timeval)); 116 | if (err < 0) { 117 | fprintf(stderr, "tracy_write_mem returned %d\n", err); 118 | tracy_kill_child(e->child); 119 | } 120 | } 121 | } 122 | 123 | return TRACY_HOOK_CONTINUE; 124 | } 125 | 126 | 127 | /* 128 | * {"statfs", (0 + 99)}, 129 | * {"fstatat64", (0 +327)}, 130 | * {"lstat64", (0 +196)}, 131 | * {"fstat64", (0 +197)}, 132 | * {"fstatfs", (0 +100)}, 133 | * {"statfs64", (0 +266)}, 134 | * {"lstat", (0 +107)}, 135 | * {"fstatfs64", (0 +267)}, 136 | * {"stat", (0 +106)}, 137 | * {"stat64", (0 +195)}, 138 | * {"ustat", (0 + 62)}, 139 | * {"fstat", (0 +108)}, 140 | */ 141 | #define stat_str stat64 142 | 143 | int hook_fstat64(struct tracy_event *e) { 144 | struct stat_str st; 145 | int ret; 146 | struct timespec ts = {0, 0}; 147 | 148 | /*fprintf(stderr, "hook_fstat64\n");*/ 149 | if (e->child->pre_syscall) { 150 | e->child->custom = (void*)e->args.a1; 151 | /*fprintf(stderr, "fd/ptr: %lx\n", e->args.a0);*/ 152 | } else { 153 | if (e->child->custom && !e->args.return_code) { 154 | ret = tracy_read_mem(e->child, (tracy_parent_addr_t)&st, 155 | (tracy_child_addr_t)e->child->custom, 156 | sizeof(struct stat_str)); 157 | if (ret != sizeof(struct stat_str)) { 158 | fprintf(stderr, "tracy_read_mem failed: %d\n", ret); 159 | return TRACY_HOOK_CONTINUE; 160 | } else { 161 | /*st.st_mode = 0;*/ 162 | st.st_mtime = ts.tv_sec; 163 | st.st_atime = ts.tv_sec; 164 | st.st_ctime = ts.tv_sec; 165 | ret = tracy_write_mem(e->child, (tracy_child_addr_t)e->child->custom, 166 | (tracy_parent_addr_t)&st, sizeof(struct stat_str)); 167 | if (ret != sizeof(struct stat_str)) { 168 | fprintf(stderr, "tracy_read_mem failed: %d\n", ret); 169 | } 170 | } 171 | 172 | } 173 | } 174 | return TRACY_HOOK_CONTINUE; 175 | } 176 | 177 | int hook_stat64(struct tracy_event *e) { 178 | /*fprintf(stderr, "hook_stat64 -> hook_fstat64\n");*/ 179 | return hook_fstat64(e); 180 | } 181 | 182 | int hook_lstat64(struct tracy_event *e) { 183 | /*fprintf(stderr, "hook_lstat64 -> hook_fstat64\n");*/ 184 | return hook_fstat64(e); 185 | } 186 | 187 | 188 | int main(int argc, char** argv) { 189 | struct tracy *tracy; 190 | 191 | /* Tracy options */ 192 | tracy = tracy_init(TRACY_TRACE_CHILDREN); 193 | #if 0 194 | tracy = tracy_init(TRACY_TRACE_CHILDREN | TRACY_VERBOSE | 195 | TRACY_VERBOSE_SIGNAL | TRACY_VERBOSE_SYSCALL); 196 | #endif 197 | 198 | if (argc < 2) { 199 | printf("Usage: ./example [arguments]\n"); 200 | return EXIT_FAILURE; 201 | } 202 | 203 | /* Hooks */ 204 | 205 | /*set_hook(stat);*/ 206 | set_hook(open); 207 | set_hook(time); 208 | set_hook(clock_gettime); 209 | set_hook(gettimeofday); 210 | set_hook(stat64); 211 | set_hook(lstat64); 212 | set_hook(fstat64); 213 | 214 | argv++; argc--; 215 | 216 | /* Start child */ 217 | if (!tracy_exec(tracy, argv)) { 218 | perror("tracy_exec"); 219 | return EXIT_FAILURE; 220 | } 221 | 222 | /* Main event-loop */ 223 | tracy_main(tracy); 224 | 225 | tracy_free(tracy); 226 | 227 | return EXIT_SUCCESS; 228 | } 229 | -------------------------------------------------------------------------------- /src/tests/fork-prog.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | 10 | int main (int argc, char *argv[]) { 11 | int child; 12 | 13 | /* If a second argument is given 14 | * fork by means of clone 15 | */ 16 | if (argc == 2 && !strcmp("-c", argv[1])) { 17 | puts("Fork by clone(2)"); 18 | child = fork(); 19 | } else { 20 | puts("Fork by fork(2)"); 21 | child = syscall(__NR_fork); 22 | } 23 | 24 | if (child == -1) { 25 | printf("Fork failed: %d.\n", getpid()); 26 | return EXIT_FAILURE; 27 | } 28 | 29 | if (child) { 30 | printf("We are the parent: %d.\n", getpid()); 31 | } else { 32 | printf("We are the child: %d.\n", getpid()); 33 | } 34 | 35 | return EXIT_SUCCESS; 36 | } 37 | -------------------------------------------------------------------------------- /src/tests/fork.c: -------------------------------------------------------------------------------- 1 | #include "../tracy.h" 2 | #include "../ll.h" 3 | 4 | #include 5 | #include 6 | 7 | /* For __NR_ */ 8 | #include 9 | #include 10 | 11 | int main(int argc, char** argv) { 12 | struct tracy *tracy; 13 | 14 | /* Tracy options */ 15 | tracy = tracy_init(TRACY_TRACE_CHILDREN | TRACY_USE_SAFE_TRACE \ 16 | | TRACY_VERBOSE_SYSCALL); 17 | 18 | if (argc < 2) { 19 | printf("Usage: ./example \n"); 20 | return EXIT_FAILURE; 21 | } 22 | 23 | argv++; argc--; 24 | 25 | /* Start child */ 26 | if (!tracy_exec(tracy, argv)) { 27 | perror("tracy_exec"); 28 | return EXIT_FAILURE; 29 | } 30 | 31 | /* Main event-loop */ 32 | tracy_main(tracy); 33 | 34 | tracy_free(tracy); 35 | 36 | return EXIT_SUCCESS; 37 | } 38 | -------------------------------------------------------------------------------- /src/tests/fuzz-write.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | 18 | 19 | #include "../tracy.h" 20 | #include "../ll.h" 21 | 22 | #include 23 | #include 24 | 25 | /* For __NR_ */ 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | #define set_hook(NAME) \ 32 | if (tracy_set_hook(tracy, #NAME, TRACY_ABI_NATIVE, hook_##NAME)) { \ 33 | printf("Could not hook "#NAME" syscall\n"); \ 34 | return EXIT_FAILURE; \ 35 | } 36 | 37 | int hook_write(struct tracy_event *e) { 38 | long ret; 39 | int i; 40 | 41 | char *s; 42 | int count, rc; 43 | 44 | if (e->child->pre_syscall) { 45 | count = e->args.a2; 46 | s = malloc(sizeof(char)*(count+1)); 47 | rc = tracy_read_mem(e->child, s, (tracy_child_addr_t)e->args.a1, count); 48 | s[count] = '\0'; 49 | /*printf("tracy_read_mem returned: %d\n", rc);*/ 50 | 51 | for(i = 0; i < count >> 1; i++) { 52 | s[i] ^= s[count-i]; 53 | s[count-i] ^= s[i]; 54 | s[i] ^= s[count-i]; 55 | } 56 | 57 | rc = tracy_write_mem(e->child, (tracy_child_addr_t)e->args.a1, 58 | (tracy_parent_addr_t) s, count * sizeof(char)); 59 | /*printf("tracy_write_mem returned: %d\n", rc);*/ 60 | 61 | 62 | /*tracy_inject_syscall(e->child, __NR_write, &(e->args), &ret);*/ 63 | /*printf("wr Return code: %ld\n", ret);*/ 64 | (void)ret; 65 | (void)rc; 66 | 67 | free(s); 68 | } else { 69 | } 70 | return TRACY_HOOK_CONTINUE; 71 | } 72 | 73 | int main(int argc, char** argv) { 74 | struct tracy *tracy; 75 | 76 | /* Tracy options */ 77 | tracy = tracy_init(TRACY_TRACE_CHILDREN | TRACY_VERBOSE); 78 | 79 | if (argc < 2) { 80 | printf("Usage: ./tracy-inject-simple \n"); 81 | return EXIT_FAILURE; 82 | } 83 | 84 | /* Hooks */ 85 | set_hook(write); 86 | 87 | argv++; argc--; 88 | 89 | /* Start child */ 90 | if (!tracy_exec(tracy, argv)) { 91 | perror("tracy_exec"); 92 | return EXIT_FAILURE; 93 | } 94 | 95 | /* Main event-loop */ 96 | tracy_main(tracy); 97 | 98 | tracy_free(tracy); 99 | 100 | return EXIT_SUCCESS; 101 | } 102 | -------------------------------------------------------------------------------- /src/tests/getpid.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() { 7 | pid_t t; 8 | t = getpid(); 9 | printf("t: %d\n", t); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /src/tests/hello.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #include 18 | 19 | int main() 20 | { 21 | puts("Hello, world."); 22 | 23 | return 0; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /src/tests/inject-simple.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #include "../tracy.h" 18 | #include "../ll.h" 19 | 20 | #include 21 | #include 22 | 23 | /* For __NR_ */ 24 | #include 25 | #include 26 | 27 | #define set_hook(NAME) \ 28 | if (tracy_set_hook(tracy, #NAME, TRACY_ABI_NATIVE, hook_##NAME)) { \ 29 | printf("Could not hook "#NAME" syscall\n"); \ 30 | return EXIT_FAILURE; \ 31 | } 32 | 33 | int hook_write(struct tracy_event *e) { 34 | long ret; 35 | int i; 36 | 37 | if (e->child->pre_syscall) { 38 | printf("PRE-write\n"); 39 | for (i = 0; i < 10; i++) { 40 | tracy_inject_syscall(e->child, __NR_getpid, NULL, &ret); 41 | printf("Return code: %ld\n", ret); 42 | } 43 | } else { 44 | printf("POST-write\n"); 45 | for (i = 0; i < 10; i++) { 46 | tracy_inject_syscall(e->child, __NR_getpid, NULL, &ret); 47 | printf("Return code: %ld\n", ret); 48 | } 49 | } 50 | return TRACY_HOOK_CONTINUE; 51 | } 52 | 53 | int main(int argc, char** argv) { 54 | struct tracy *tracy; 55 | 56 | /* Tracy options */ 57 | tracy = tracy_init(TRACY_TRACE_CHILDREN | TRACY_VERBOSE); 58 | 59 | if (argc < 2) { 60 | printf("Usage: ./tracy-inject-simple \n"); 61 | return EXIT_FAILURE; 62 | } 63 | 64 | /* Hooks */ 65 | set_hook(write); 66 | 67 | argv++; argc--; 68 | 69 | /* Start child */ 70 | if (!tracy_exec(tracy, argv)) { 71 | perror("tracy_exec"); 72 | return EXIT_FAILURE; 73 | } 74 | 75 | /* Main event-loop */ 76 | tracy_main(tracy); 77 | 78 | tracy_free(tracy); 79 | 80 | return EXIT_SUCCESS; 81 | } 82 | -------------------------------------------------------------------------------- /src/tests/llseek.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #include "../tracy.h" 18 | #include "../ll.h" 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | /* For __NR_ */ 25 | #include 26 | #include 27 | 28 | /* Mmap stuffs */ 29 | #include 30 | 31 | static int child__llseek(struct tracy_child *child, int fd, unsigned long offset_hi, unsigned long offset_lo, loff_t* result, int whence) { 32 | struct tracy_sc_args a; 33 | long llseek_nr; 34 | long ret; 35 | 36 | fprintf(stderr, "%s(%u, %lu, %lu, %p, %u)\n", __func__, fd, offset_hi, offset_lo, (void*)result, whence); 37 | 38 | a.a0 = (long) fd; 39 | a.a1 = (long) offset_hi; 40 | a.a2 = (long) offset_lo; 41 | a.a3 = (long) NULL; 42 | a.a3 = (long) result; 43 | a.a4 = (long) whence; 44 | 45 | /* DEBUG LOL */ 46 | a.a5 = (long) 0x42; 47 | 48 | printf("Should be: %lx %lx %lx %lx %lx %lx\n", a.a0, a.a1, a.a2, a.a3, a.a4, a.a5); 49 | 50 | llseek_nr = get_syscall_number_abi("_llseek", child->event.abi); 51 | if (tracy_inject_syscall(child, llseek_nr, &a, &ret)) { 52 | fprintf(stderr, "Injection error!\n"); 53 | return -1; 54 | } 55 | 56 | return ret; 57 | } 58 | 59 | loff_t child_lseek64(struct tracy_child *child, int fd, off64_t off, int whence) 60 | { 61 | loff_t result; 62 | int rc; 63 | int ret; 64 | 65 | tracy_child_addr_t mmap_ret = NULL; 66 | long munmap_ret = 0; 67 | 68 | ret = tracy_mmap(child, &mmap_ret, NULL, 4096, PROT_WRITE|PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 69 | printf("Tracy ret: %d\n", ret); 70 | printf("Tracy ptr: %lx\n", (unsigned long)mmap_ret); 71 | 72 | if ((rc=child__llseek(child, fd, (unsigned long)(off >> 32),(unsigned long)(off), (loff_t*)mmap_ret, whence)) < 0 ){ 73 | /*if ((rc=child__llseek(child, fd, (unsigned long)(off >> 32),(unsigned long)(off), &result, whence)) < 0 ){*/ 74 | fprintf(stderr, "llseek64_error: %d\n", rc); 75 | return -1; 76 | } 77 | 78 | ret = tracy_read_mem(child, &result, mmap_ret, sizeof(loff_t)); 79 | /* XXX: Check return value of iets dergelijks */ 80 | printf("tracy_read_mem ret: %d\n", ret); 81 | 82 | ret = tracy_munmap(child, &munmap_ret, mmap_ret, 4096); 83 | printf("tracy_munmap ret: %d\n", ret); 84 | 85 | 86 | return result; 87 | } 88 | 89 | int hook_open(struct tracy_event *e) { 90 | loff_t rc; 91 | 92 | if (e->child->pre_syscall) { 93 | /*printf("open()\n");*/ 94 | } else { 95 | int fd = e->args.return_code; 96 | if(fd<=2) { 97 | goto cont; 98 | } 99 | 100 | printf("fd=%d\n", fd); 101 | rc = child_lseek64(e->child, fd, 0x100, SEEK_CUR); 102 | printf("rc=%lld\n", (long long int) rc); 103 | 104 | return TRACY_HOOK_CONTINUE; 105 | /*return TRACY_HOOK_ABORT;*/ 106 | } 107 | 108 | cont: 109 | return TRACY_HOOK_CONTINUE; 110 | } 111 | 112 | int main(int argc, char** argv) { 113 | struct tracy *tracy; 114 | 115 | /* Tracy options */ 116 | tracy = tracy_init(TRACY_TRACE_CHILDREN); 117 | 118 | if (tracy_set_hook(tracy, "open", TRACY_ABI_NATIVE, hook_open)) { 119 | fprintf(stderr, "Could not hook open\n"); 120 | return EXIT_FAILURE; 121 | } 122 | 123 | if (argc < 2) { 124 | printf("Usage: ./example \n"); 125 | return EXIT_FAILURE; 126 | } 127 | 128 | argv++; argc--; 129 | 130 | /* Start child */ 131 | if (!tracy_exec(tracy, argv)) { 132 | perror("tracy_exec"); 133 | return EXIT_FAILURE; 134 | } 135 | 136 | /* Main event-loop */ 137 | tracy_main(tracy); 138 | 139 | tracy_free(tracy); 140 | 141 | return EXIT_SUCCESS; 142 | } 143 | -------------------------------------------------------------------------------- /src/tests/metronome.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | int ticktock = 1; 7 | 8 | while (1) { 9 | if (ticktock) { 10 | puts("Tick"); 11 | } else { 12 | puts("Tock"); 13 | } 14 | sleep(1); 15 | ticktock = !ticktock; 16 | } 17 | 18 | return 0; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /src/tests/raw-clone.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | pid_t tid; 9 | 10 | /* glibc's getpid implements a cache 11 | * which will cause incorrect results 12 | * when calling clone(2) directly 13 | */ 14 | static pid_t no_cache_getpid() 15 | { 16 | pid_t pid; 17 | 18 | #if defined(__x86_64__) || defined(__arm__) || defined(__powerpc__) 19 | pid = syscall(__NR_getpid); 20 | #elif defined(__i386__) 21 | __asm__( 22 | "int $0x80" 23 | : 24 | "=a"(pid) 25 | : 26 | "a"(__NR_getpid) 27 | ); 28 | #endif 29 | 30 | return pid; 31 | } 32 | 33 | /* This application executes a raw clone(2) syscall to study 34 | * its return values in both parent and child. 35 | * For now this test is i386 only. 36 | */ 37 | int main() 38 | { 39 | int rval; 40 | pid_t pid = 0; 41 | tid = no_cache_getpid(); 42 | 43 | printf("Test initial PID (and TID) is %d\n", tid); 44 | 45 | #if defined(__x86_64__) 46 | rval = syscall(__NR_clone, CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, 0, 0, &tid); 47 | #elif defined(__powerpc__) 48 | rval = syscall(__NR_clone, CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, 0, 0, &tid); 49 | #elif defined(__arm__) 50 | /* FIXME */ 51 | rval = syscall(__NR_clone, CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, 0, 0, &tid); 52 | #elif defined(__i386__) 53 | __asm__( 54 | "push %%esi\n" 55 | "push %%edi\n" 56 | "xor %%esi, %%esi\n" 57 | "mov %5, %%edi\n" 58 | "int $0x80\n" 59 | "pop %%edi\n" 60 | "pop %%esi\n" 61 | : 62 | "=a"(rval) 63 | : 64 | "a"(__NR_clone), 65 | /* Same clone arguments as glibc's fork() */ 66 | "b"(CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD), 67 | "c"(0), /* Child stack (not necessary for fork) */ 68 | "d"(0), 69 | "i"(&tid) /* Child thread ID pointer */ 70 | ); 71 | #endif 72 | 73 | pid = no_cache_getpid(); 74 | printf("In %d return value is: %d\n", pid, rval); 75 | printf("In %d, TID is: %d\n", pid, tid); 76 | 77 | return 0; 78 | } 79 | 80 | -------------------------------------------------------------------------------- /src/tests/read_stdin.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #include "../tracy.h" 18 | #include "../ll.h" 19 | 20 | #include 21 | #include 22 | 23 | /* For __NR_ */ 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | int prev = 0; 30 | 31 | int hook_read(struct tracy_event *e) { 32 | char *buf; 33 | size_t bufsize; 34 | 35 | if (e->child->pre_syscall) { 36 | if (e->args.a0 == 0) { 37 | e->child->custom = (void*)e->args.a1; 38 | prev = 1; 39 | } else { 40 | prev = 0; 41 | } 42 | } else { 43 | if (prev) { 44 | bufsize = e->args.return_code; 45 | 46 | if ((ssize_t)bufsize < 0) { 47 | strerror(-bufsize); 48 | return TRACY_HOOK_CONTINUE; 49 | } 50 | 51 | buf = malloc(sizeof(char) * (bufsize + 1)); 52 | 53 | /*printf("Reading memory now. Count: %d From %lx To %lx\n", bufsize, 54 | (long)ptr, (long)buf); 55 | */ 56 | 57 | tracy_read_mem(e->child, buf, e->child->custom, bufsize); 58 | 59 | buf[bufsize-1] = '\0'; 60 | printf("%s\n", buf); 61 | 62 | free(buf); 63 | 64 | return TRACY_HOOK_CONTINUE; 65 | } 66 | } 67 | 68 | return TRACY_HOOK_CONTINUE; 69 | } 70 | 71 | int main(int argc, char** argv) { 72 | struct tracy *tracy; 73 | int pid; 74 | 75 | /* Tracy options */ 76 | tracy = tracy_init(TRACY_TRACE_CHILDREN); 77 | tracy_set_hook(tracy, "read", TRACY_ABI_NATIVE, hook_read); 78 | #ifdef __x86_64__ 79 | tracy_set_hook(tracy, "read", TRACY_ABI_X86, hook_read); 80 | #endif 81 | /*tracy = tracy_init(TRACY_TRACE_CHILDREN | TRACY_VERBOSE);*/ 82 | 83 | if (argc < 2) { 84 | printf("Usage: ./example \n"); 85 | return EXIT_FAILURE; 86 | } 87 | 88 | argv++; argc--; 89 | while(argc--) { 90 | pid = atoi((const char *)argv[0]); 91 | printf("Going to attach to %d\n", pid); 92 | 93 | if (!tracy_attach(tracy, pid)) { 94 | perror("tracy_exec"); 95 | return EXIT_FAILURE; 96 | } 97 | argv++; 98 | } 99 | 100 | 101 | /* Main event-loop */ 102 | tracy_main(tracy); 103 | 104 | tracy_free(tracy); 105 | 106 | return EXIT_SUCCESS; 107 | } 108 | -------------------------------------------------------------------------------- /src/tests/redirect.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #include "../tracy.h" 18 | #include "../ll.h" 19 | 20 | #include 21 | #include 22 | 23 | /* For __NR_ */ 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | int hook_write(struct tracy_event *e) { 30 | struct tracy_sc_args a; 31 | 32 | if (e->child->pre_syscall) { 33 | if (e->args.a0 == 2) { 34 | memcpy(&a, &(e->args), sizeof(struct tracy_sc_args)); 35 | a.a0 = 1; 36 | if (tracy_modify_syscall_args(e->child, a.syscall, &a)) { 37 | return TRACY_HOOK_ABORT; 38 | } 39 | } 40 | } 41 | 42 | return TRACY_HOOK_CONTINUE; 43 | } 44 | 45 | int main(int argc, char** argv) { 46 | struct tracy *tracy; 47 | 48 | /* Tracy options */ 49 | tracy = tracy_init(TRACY_TRACE_CHILDREN); 50 | tracy_set_hook(tracy, "write", TRACY_ABI_NATIVE, hook_write); 51 | #ifdef __x86_64__ 52 | tracy_set_hook(tracy, "write", TRACY_ABI_X86, hook_write); 53 | #endif 54 | /*tracy = tracy_init(TRACY_TRACE_CHILDREN | TRACY_VERBOSE);*/ 55 | 56 | if (argc < 2) { 57 | printf("Usage: ./example \n"); 58 | return EXIT_FAILURE; 59 | } 60 | 61 | argv++; argc--; 62 | 63 | /* Start child */ 64 | if (!tracy_exec(tracy, argv)) { 65 | perror("tracy_exec"); 66 | return EXIT_FAILURE; 67 | } 68 | 69 | /* Main event-loop */ 70 | tracy_main(tracy); 71 | 72 | tracy_free(tracy); 73 | 74 | return EXIT_SUCCESS; 75 | } 76 | -------------------------------------------------------------------------------- /src/tests/rwmem.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include "../ll.h" 24 | #include "../tracy.h" 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | 33 | /* For __NR_ */ 34 | #include 35 | 36 | /* XXX: Currently the actual kicking in of the memory fallback is not tested 37 | * because we do not simulate a failure of the open syscall used 38 | * to access the specific /proc//mem file. We could in the future 39 | * use Tracy itself to trace a test, simulating a failure of the PPM 40 | * API. 41 | */ 42 | 43 | static int use_ptrace_mem = 0; 44 | static int force_mem_fallback = 0; 45 | 46 | void cat_file(char *file); 47 | 48 | static ssize_t read_mem(struct tracy_child *c, tracy_parent_addr_t dest, 49 | tracy_child_addr_t src, size_t n) 50 | { 51 | if (use_ptrace_mem) 52 | return tracy_peek_mem(c, dest, src, n); 53 | return tracy_read_mem(c, dest, src, n); 54 | } 55 | 56 | static ssize_t write_mem(struct tracy_child *c, tracy_child_addr_t dest, 57 | tracy_parent_addr_t src, size_t n) 58 | { 59 | if (use_ptrace_mem) 60 | return tracy_poke_mem(c, dest, src, n); 61 | return tracy_write_mem(c, dest, src, n); 62 | } 63 | 64 | static 65 | /* write syscall hook args layout: 66 | * e->args.a0: file descriptor 67 | * e->args.a1: data pointer 68 | * e->args.a2: data length 69 | */ 70 | int foo(struct tracy_event *e) { 71 | int len, i; 72 | char *str; 73 | long word; 74 | char wstr[5]; 75 | char child_maps_path[20]; 76 | 77 | static int dump_maps_once = 1; 78 | 79 | if (!e->child->pre_syscall) 80 | return 0; 81 | 82 | if (dump_maps_once) { 83 | sprintf(child_maps_path, "/proc/%i/maps", e->child->pid); 84 | cat_file(child_maps_path); 85 | perror(child_maps_path); 86 | 87 | /* This once block is also used for forcing the memory fallback 88 | * if required 89 | */ 90 | if (force_mem_fallback) 91 | e->child->mem_fallback = 1; 92 | dump_maps_once = 0; 93 | } 94 | 95 | #if 0 96 | printf("In hook for function call \"write\"(%ld)\n", e->syscall_num); 97 | printf("Argument 0 (fd) for write: %ld\n", e->args.a0); 98 | printf("Argument 1 (str) for write: %p\n", (void*)e->args.a1); 99 | printf("Argument 2 (len) for write: %ld\n", e->args.a2); 100 | #endif 101 | 102 | len = e->args.a2; 103 | str = malloc(sizeof(char) * 4096); 104 | 105 | /* Read memory */ 106 | printf("Requested %lu bytes to read.\n", (unsigned long)(sizeof(char) 107 | * len)); 108 | if ((i = read_mem(e->child, str, (void*)e->args.a1, sizeof(char) * len)) < 0) 109 | perror("read_mem"); 110 | printf("Read %d bytes.\n", i); 111 | 112 | /* Python style string dump */ 113 | if (i > 0) { 114 | printf("Data: '"); 115 | for (i = 0; i < len; i++) { 116 | if (isprint(str[i])) 117 | printf("%c", str[i]); 118 | else 119 | printf("\\x%02x", str[i] & 0xff); 120 | } 121 | printf("'\n"); 122 | } 123 | 124 | /* Peek single word at same address */ 125 | if(tracy_peek_word(e->child, e->args.a1, &word) < 0) 126 | perror("tracy_peek_word"); 127 | 128 | for (i = 0; i < 4; i++) 129 | wstr[i] = (char)((word >> i * 8) & 0xff); 130 | 131 | wstr[i] = '\0'; 132 | printf("Data by peek word: %p, '%s'\n", (void*)word, wstr); 133 | 134 | strfry(str); 135 | printf("Requested %lu bytes to write.\n", (unsigned long)(sizeof(char) 136 | * len)); 137 | if ((i = write_mem(e->child, (void*)e->args.a1, str, sizeof(char) * len)) < 0) 138 | perror("write_mem"); 139 | printf("Wrote %d bytes.\n", i); 140 | 141 | free(str); 142 | 143 | word = 0x6f6c6f6c; /* "lolo" */ 144 | if (tracy_poke_word(e->child, e->args.a1, word) < 0) 145 | perror("tracy_poke_word"); 146 | 147 | #if 0 148 | e->args.a2 = strlen(newmsg); 149 | 150 | /* 151 | * This will not work, because the child cannot access our memory. 152 | * SHM? 153 | */ 154 | /* e->args.a1 = (long)stephen; */ 155 | 156 | /* This is allowed, of course */ 157 | e->args.a2 = strlen(stephen); 158 | 159 | printf("Modify_registers: %d.\n", modify_registers(e)); 160 | 161 | /* Don't let flushing bully us */ 162 | fflush(NULL); 163 | #endif 164 | 165 | return 0; 166 | } 167 | 168 | void cat_file(char *file) 169 | { 170 | int r; 171 | int fd; 172 | char buf[128]; 173 | 174 | fd = open(file, O_RDONLY, 0); 175 | if (fd < 0) 176 | return; 177 | 178 | while ((r = read(fd, buf, 128)) > 0) 179 | fwrite(buf, 1, r, stdout); 180 | 181 | close(fd); 182 | return; 183 | } 184 | 185 | int main(int argc, char** argv) { 186 | struct tracy *tracy; 187 | const char *program_name = argv[0]; 188 | 189 | tracy = tracy_init(0); 190 | 191 | if (tracy_set_hook(tracy, "write", foo)) { 192 | printf("Failed to hook write syscall.\n"); 193 | return EXIT_FAILURE; 194 | } 195 | 196 | argv++; argc--; 197 | 198 | /* Switch the ptrace API on */ 199 | if (argc) { 200 | if (!strcmp(argv[0], "-p")) { 201 | puts("test-rwmem: Switching to ptrace API"); 202 | use_ptrace_mem = 1; 203 | argv++; argc--; 204 | } 205 | } 206 | 207 | /* Force use of fallback mechanism (also ptrace) */ 208 | if (argc) { 209 | if (!strcmp(argv[0], "-f")) { 210 | puts("test-rwmem: Forcing use of memory fallback"); 211 | force_mem_fallback = 1; 212 | argv++; argc--; 213 | } 214 | } 215 | 216 | if (!argc) { 217 | printf("Usage: %s [-p] \n", 218 | program_name); 219 | return EXIT_FAILURE; 220 | } 221 | 222 | if (!tracy_exec(tracy, argv)) { 223 | perror("tracy_exec returned NULL"); 224 | return EXIT_FAILURE; 225 | } 226 | 227 | tracy_main(tracy); 228 | 229 | tracy_free(tracy); 230 | 231 | /* Most of the times newlines get shuffled in between, so for 232 | * shell clarity's sake, write a newline */ 233 | puts(""); 234 | 235 | return 0; 236 | } 237 | -------------------------------------------------------------------------------- /src/tests/sig_suppress.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | #include "../tracy.h" 18 | #include "../ll.h" 19 | 20 | #include 21 | #include 22 | 23 | /* For __NR_ */ 24 | #include 25 | #include 26 | 27 | int sig_hook(struct tracy_event *e) { 28 | if (e->signal_num == SIGTERM) { 29 | fprintf(stderr, "Supressing SIGTERM\n"); 30 | return TRACY_HOOK_SUPPRESS; 31 | } 32 | return TRACY_HOOK_CONTINUE; 33 | } 34 | 35 | int main(int argc, char** argv) { 36 | struct tracy *tracy; 37 | 38 | /* Tracy options */ 39 | tracy = tracy_init(TRACY_TRACE_CHILDREN); 40 | /*| TRACY_VERBOSE | 41 | TRACY_VERBOSE_SIGNAL | TRACY_VERBOSE_SYSCALL); 42 | */ 43 | 44 | tracy_set_signal_hook(tracy, sig_hook); 45 | 46 | if (argc < 2) { 47 | printf("Usage: ./example \n"); 48 | return EXIT_FAILURE; 49 | } 50 | 51 | argv++; argc--; 52 | 53 | /* Start child */ 54 | if (!tracy_exec(tracy, argv)) { 55 | perror("tracy_exec"); 56 | return EXIT_FAILURE; 57 | } 58 | 59 | /* Main event-loop */ 60 | tracy_main(tracy); 61 | 62 | tracy_free(tracy); 63 | 64 | return EXIT_SUCCESS; 65 | } 66 | -------------------------------------------------------------------------------- /src/tests/thread-simple-prog.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | void* thread_start() { 7 | printf("Hello\n"); 8 | return EXIT_SUCCESS; 9 | } 10 | 11 | int main() { 12 | pthread_t t; 13 | int ret; 14 | 15 | ret = 0; 16 | 17 | pthread_create(&t, NULL, &thread_start, NULL); 18 | 19 | pthread_join(t, (void*)&ret); 20 | 21 | printf("Thread return value: %d\n", ret); 22 | 23 | return EXIT_SUCCESS; 24 | } 25 | -------------------------------------------------------------------------------- /src/tests/thread-simple.c: -------------------------------------------------------------------------------- 1 | #include "../tracy.h" 2 | #include "../ll.h" 3 | 4 | #include 5 | #include 6 | 7 | /* For __NR_ */ 8 | #include 9 | #include 10 | 11 | #define set_hook(NAME) \ 12 | if (tracy_set_hook(tracy, #NAME, TRACY_ABI_NATIVE, hook_##NAME)) { \ 13 | printf("Could not hook "#NAME" syscall\n"); \ 14 | return EXIT_FAILURE; \ 15 | } 16 | 17 | int hook_write(struct tracy_event *e) { 18 | (void) e; 19 | return TRACY_HOOK_CONTINUE; 20 | } 21 | 22 | int main(int argc, char** argv) { 23 | struct tracy *tracy; 24 | 25 | /* Tracy options */ 26 | /*tracy = tracy_init(TRACY_TRACE_CHILDREN);*/ 27 | tracy = tracy_init(TRACY_TRACE_CHILDREN | TRACY_VERBOSE); 28 | 29 | if (argc < 2) { 30 | printf("Usage: ./tracy-inject-simple \n"); 31 | return EXIT_FAILURE; 32 | } 33 | 34 | /* Hooks */ 35 | set_hook(write); 36 | 37 | argv++; argc--; 38 | 39 | /* Start child */ 40 | if (!tracy_exec(tracy, argv)) { 41 | perror("tracy_exec"); 42 | return EXIT_FAILURE; 43 | } 44 | 45 | /* Main event-loop */ 46 | tracy_main(tracy); 47 | 48 | tracy_free(tracy); 49 | 50 | return EXIT_SUCCESS; 51 | } 52 | -------------------------------------------------------------------------------- /src/tests/vfork-prog.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | static int dat_shared_mem = 0; 13 | static int child_func(void *parg); 14 | 15 | int main (int argc, char *argv[]) { 16 | char *stack = NULL; 17 | pid_t child; 18 | 19 | if (argc == 2 && !strcmp("-c", argv[1])) { 20 | /* 64 kiB stack */ 21 | stack = malloc(sizeof(char) * 64 * 1024); 22 | 23 | if (!stack) { 24 | perror("malloc failed"); 25 | return EXIT_FAILURE; 26 | } 27 | 28 | /* vfork by means of clone */ 29 | puts("Using clone(2) to vfork"); 30 | #if 0 31 | child = clone(child_func, stack + 64 * 1024, CLONE_VFORK | SIGCHLD, NULL); 32 | #else 33 | child = clone(child_func, stack + 64 * 1024, CLONE_VFORK, NULL); 34 | #endif 35 | } else { 36 | /* vfork by vfork */ 37 | puts("Using vfork(2)"); 38 | child = vfork(); 39 | } 40 | 41 | if (child == -1) { 42 | fprintf(stderr, "Fork failed: %d: %s\n", getpid(), strerror(errno)); 43 | return EXIT_FAILURE; 44 | } 45 | 46 | if (child) { 47 | printf("We are the parent: %d.\n", getpid()); 48 | if (dat_shared_mem) 49 | puts("Memory was shared"); 50 | else 51 | puts("Memory was NOT shared"); 52 | } else { 53 | child_func(NULL); 54 | } 55 | 56 | return EXIT_SUCCESS; 57 | } 58 | 59 | 60 | static int child_func(void *parg) 61 | { 62 | (void)parg; 63 | printf("We are the child: %d.\n", getpid()); 64 | dat_shared_mem = 42; 65 | _exit(0); 66 | } 67 | 68 | -------------------------------------------------------------------------------- /src/tests/wxorx.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "../ll.h" 7 | #include "../tracy.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | /* TODO 16 | * 17 | * - Keep track of mem map perms (tracy_child_mem in ll) 18 | * - Determine where segfault took place: 19 | * * Determine if we need to swap flags, and restart op without signal 20 | * * Pass signal if not our/perms fault 21 | * 22 | * Hook: mmap, munmap, mprotect, mremap 23 | * 24 | */ 25 | 26 | struct tracy_child_mem { 27 | long start, size; 28 | long perms; 29 | long offset; 30 | }; 31 | 32 | /* void *mmap(void *addr, size_t length, int prot, int flags, 33 | int fd, off_t offset); */ 34 | int hook_mmap(struct tracy_event *e) { 35 | (void) e; 36 | 37 | /* Pre: check flags/prot */ 38 | /* Post: add to managed list */ 39 | 40 | return TRACY_HOOK_CONTINUE; 41 | } 42 | 43 | /* int munmap(void *addr, size_t length); */ 44 | int hook_munmap(struct tracy_event *e) { 45 | (void) e; 46 | 47 | /* Post: Remove from list */ 48 | 49 | return TRACY_HOOK_CONTINUE; 50 | } 51 | 52 | /* int mprotect(void *addr, size_t len, int prot); */ 53 | int hook_mprotect(struct tracy_event *e) { 54 | (void) e; 55 | 56 | /* Check prot */ 57 | 58 | return TRACY_HOOK_CONTINUE; 59 | } 60 | 61 | /* address, perms, offset, dev, inode, pathname */ 62 | static int parse_maps(struct tracy_child *c) { 63 | char proc_maps_path[19]; 64 | FILE* fd; 65 | 66 | /* TODO: Put the char* on stack instead of heap? */ 67 | char *buf, *flags, *dev, *pathname; 68 | long inode; 69 | unsigned int start, end, offset; 70 | 71 | sprintf(proc_maps_path, "/proc/%d/maps", c->pid); 72 | printf("Opening %s\n", proc_maps_path); 73 | fd = fopen(proc_maps_path, "r"); 74 | 75 | buf = malloc(4096 * 10); 76 | flags = malloc(4); 77 | dev = malloc(5); 78 | pathname = malloc(4096 * 10); 79 | 80 | while (fgets(buf, 4096 * 10, fd) != NULL) { 81 | sscanf(buf, "%x-%x %4s %x %5s %ld %s", &start, &end, flags, &offset, 82 | dev, &inode, pathname); 83 | printf("start: %x, end: %x, flags: %4s, offset: %x, dev: %5s," 84 | "inode: %ld, path: %s\n", start, end, flags, offset, dev, inode, pathname); 85 | } 86 | 87 | free(buf); 88 | free(flags); 89 | free(dev); 90 | free(pathname); 91 | 92 | return 0; 93 | } 94 | 95 | int signal_hook(struct tracy_event *e) { 96 | if (e->signal_num == SIGSEGV) { 97 | puts("Segfault detected!"); 98 | printf("pid: %d\n", e->child->pid); 99 | 100 | /* 101 | printf("Signal code: %d\n", e->siginfo.si_code); 102 | printf("Signal Status: %d\n", e->siginfo.si_status); 103 | printf("Sending pid, if any: %d\n", e->siginfo.si_pid); 104 | */ 105 | 106 | /* kill(getpid(), SIGSEGV) will have si_code = 0 */ 107 | if (e->siginfo.si_code > 0) { 108 | printf("App Addr: %lx\n", (unsigned long)e->siginfo.si_addr); 109 | } else { 110 | puts("Normal signal"); 111 | } 112 | } 113 | 114 | return TRACY_HOOK_CONTINUE; 115 | } 116 | 117 | static void child_create(struct tracy_child *child) { 118 | child->custom = ll_init(); 119 | puts("New child!"); 120 | parse_maps(child); 121 | /* child->mem_fallback = 1; */ 122 | } 123 | 124 | int main (int argc, char** argv) { 125 | struct tracy *tracy; 126 | 127 | tracy = tracy_init(TRACY_TRACE_CHILDREN | TRACY_VERBOSE); 128 | 129 | 130 | /* Set hooks here */ 131 | tracy->se.child_create = &child_create; 132 | 133 | if (tracy_set_signal_hook(tracy, signal_hook)) { 134 | printf("failed to hook signals.\n"); 135 | return EXIT_FAILURE; 136 | } 137 | 138 | if (tracy_set_hook(tracy, "mmap", TRACY_ABI_NATIVE, hook_mmap)) { 139 | printf("failed to hook mmap syscall.\n"); 140 | return EXIT_FAILURE; 141 | } 142 | 143 | if (tracy_set_hook(tracy, "munmap", TRACY_ABI_NATIVE, hook_munmap)) { 144 | printf("failed to hook munmap syscall.\n"); 145 | return EXIT_FAILURE; 146 | } 147 | 148 | if (tracy_set_hook(tracy, "mprotect", TRACY_ABI_NATIVE, hook_mprotect)) { 149 | printf("failed to hook mprotectsyscall.\n"); 150 | return EXIT_FAILURE; 151 | } 152 | 153 | /* Execute program */ 154 | argv++; argc--; 155 | if (!tracy_exec(tracy, argv)) { 156 | perror("tracy_exec returned NULL"); 157 | return EXIT_FAILURE; 158 | } 159 | 160 | tracy_main(tracy); 161 | tracy_free(tracy); 162 | 163 | return EXIT_SUCCESS; 164 | } 165 | -------------------------------------------------------------------------------- /src/tracyarch.h: -------------------------------------------------------------------------------- 1 | #ifdef __x86_64__ 2 | #include "arch/amd64/arch.h" 3 | #endif 4 | #ifdef __arm__ 5 | #include "arch/arm/arch.h" 6 | #endif 7 | #ifdef __ppc__ 8 | #include "arch/ppc/arch.h" 9 | #endif 10 | #ifdef __i386__ 11 | #include "arch/x86/arch.h" 12 | #endif 13 | #ifdef __powerpc__ 14 | #include "arch/ppc/arch.h" 15 | #endif 16 | -------------------------------------------------------------------------------- /src/tracyfs.py: -------------------------------------------------------------------------------- 1 | from pytracy import Tracy, Child, TRACE_CHILDREN 2 | import sys 3 | 4 | 5 | class File: 6 | def __init__(self, contents): 7 | self.contents = contents 8 | self.offset = 0 9 | 10 | def seek(self, offset, mode): 11 | pass 12 | 13 | def read(self, size): 14 | buf = self.contents[self.offset:self.offset+size] 15 | self.offset += len(buf) 16 | return buf 17 | 18 | 19 | class TracyFS(Tracy): 20 | """Tracy Virtual File System.""" 21 | 22 | def __init__(self, options=0): 23 | Tracy.__init__(self, TRACE_CHILDREN | options) 24 | self.files = {} 25 | self.fds = {} 26 | self.event_to_fds = {} 27 | 28 | self.hook('open', self._handle_open) 29 | self.hook('seek', self._handle_seek) 30 | self.hook('read', self._handle_read) 31 | self.hook('close', self._handle_close) 32 | 33 | def add_file(self, fname, contents): 34 | self.files[fname] = contents 35 | 36 | def get_fd(self): 37 | for idx, fd in enumerate(self.fds): 38 | if fd is None: 39 | return 0x13371337 + idx 40 | return 0x13371337 + len(self.fds) 41 | 42 | def _handle_open(self, e, a, pre): 43 | if pre: 44 | fname = Child.from_event(e).read_string(a.a0) 45 | if fname in self.files: 46 | fd = self.get_fd() 47 | self.fds[fd] = self.files[fname] 48 | self.event_to_fds[Child.from_event(e)] = fd 49 | elif Child.from_event(e) in self.event_to_fds: 50 | fd = self.event_to_fds.pop(Child.from_event(e)) 51 | a.return_code = fd 52 | Child.from_event(e).modify_regs(a.syscall, a) 53 | 54 | def _handle_seek(self, e, a, pre): 55 | pass 56 | 57 | def _handle_read(self, e, a, pre): 58 | print 'read', pre, a.a0 59 | if not pre and a.a0 in self.fds: 60 | print a.a0, a.a1, a.a2 61 | buf = self.fds[a.a0].read(a.a2) 62 | Child.from_event(e).write(a.a1, buf) 63 | a.return_code = len(buf) 64 | Child.from_event(e).modify_regs(a.syscall, a) 65 | 66 | def _handle_close(self, e, a, pre): 67 | pass 68 | 69 | if __name__ == '__main__': 70 | fs = TracyFS() 71 | 72 | fs.add_file('/tracy/w00p', File('wizz0p')) 73 | 74 | fs.execute(*sys.argv[1:]) 75 | fs.main() 76 | -------------------------------------------------------------------------------- /src/trampy.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | 18 | /* trampy.c provides a piece of PAC (Position Agnostic Code) that can be 19 | * injected into traced processes to securily fork them. That is, 20 | * it throws the traced process and its newly forked child into a loop 21 | * allowing tracy to attach to the child and afterwards restore both processes 22 | * as if nothing happened, save for the original syscall. 23 | * 24 | * XXX: Trampy will NOT work when compiled with -fPIC (position independent code) 25 | * due to its modification of %ebx on x86 architectures, in fact it probably 26 | * won't even compile as GCC tends to complain about inline assembly modifying 27 | * the PIC base-register. 28 | * This might need to be fixed in the future or perhaps we would even want 29 | * pure assembly instead of inlining. ;-) 30 | */ 31 | 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | #ifdef __linux__ 38 | #ifdef __x86_64__ 39 | /* x86_64 performs syscalls using the syscall instruction, 40 | * the syscall number is stored within the RAX register 41 | */ 42 | #define SET_SYSCALL "i" 43 | #define INLINE_ARG0 "i" 44 | #define INLINE_ARG1 "i" 45 | #define LOAD_TRACER_PID \ 46 | "mov %1, %%rsi\n" \ 47 | "mov %%r8, %%rdi\n" 48 | #define ENTER_KERNEL \ 49 | "mov %0, %%rax\n" \ 50 | "syscall\n" 51 | 52 | #elif defined(__i386__) 53 | /* x86 performs syscalls using the 0x80 interrupt, 54 | * the syscall number is stored within the EAX register 55 | * The tracer stores its PID in the EDI register which can then 56 | * be used by the child to inform the tracer of its existence. 57 | */ 58 | #define SET_SYSCALL "a" 59 | #define INLINE_ARG0 "b" 60 | #define INLINE_ARG1 "c" 61 | #define LOAD_TRACER_PID "mov %%ebp, %%ebx\n" 62 | #define ENTER_KERNEL "int $0x80\n" 63 | 64 | #elif defined(__arm__) 65 | /* ARM performs syscalls using the SWI instruction, 66 | * on ARM there are to ABIs the old (OABI), and the new 67 | * (EABI), in the OABI the syscall number is stored as part 68 | * of the instruction. In EABI the instruction part is set 69 | * to 1, aka "restart_syscall", and the actual syscall number 70 | * is stored in register 'r7'. 71 | * 72 | * Furthermore OABI defines a base to which the syscall number 73 | * is added. This base is statically defined in the ARM-GLibc source 74 | * so we should be fine. 75 | * 76 | * Trampy kills two birds with one stone by setting the instruction 77 | * part to the correct OABI value and storing the EABI syscall 78 | * value in r7, theoretically Trampy should work without change 79 | * on OABI and EABI. 80 | */ 81 | #define SET_SYSCALL(VAL) \ 82 | "n"(VAL + TRACY_SWI_BASE), \ 83 | "n"(VAL) 84 | #define INLINE_ARG0 "b" 85 | #define INLINE_ARG1 "i" 86 | /* On ARM, since we cannot load into specific registers, 87 | * we have to cheat a little by also loading the signal 88 | * number during the LOAD_TRACER_PID command. 89 | */ 90 | #define LOAD_TRACER_PID \ 91 | "mov r0, r4\n" \ 92 | "mov r1, %2\n" 93 | #define ENTER_KERNEL \ 94 | "mov r7, %1\n" \ 95 | "swi %0\n" 96 | /* OABI SWI_BASE */ 97 | #define TRACY_SWI_BASE (0x900000) 98 | #elif defined(__powerpc__) 99 | /* On powerpc the syscall number is stored in r0, 100 | * the arguments in r3-r9 we use r30 for the storing of the pid 101 | */ 102 | #define SET_SYSCALL "i" 103 | #define INLINE_ARG0 "i" 104 | #define INLINE_ARG1 "i" 105 | #define LOAD_TRACER_PID "li 31, %1\n" 106 | #define ENTER_KERNEL \ 107 | "li 0, %0\n" \ 108 | "sc\n" 109 | #else 110 | #error Architecture not supported by Trampy on Linux 111 | 112 | #endif 113 | #else 114 | #error Only Linux is currently supported by Trampy. 115 | #endif 116 | 117 | /* This macro inlines assembly, executing the specified 118 | * syscall without any arguments. 119 | */ 120 | #define MAKE_SYSCALL(CALL_NR) \ 121 | __asm__( \ 122 | ENTER_KERNEL \ 123 | ::SET_SYSCALL(CALL_NR) \ 124 | ) 125 | 126 | /* This macro inlines a kill(2) syscall that will inform the 127 | * tracer of the child's existence 128 | * 129 | * LOAD_TRACER_PID executes an instruction that will copy the 130 | * tracer's PID from a specific register set by the tracer 131 | * into the first argument register of the kill(2) syscall. 132 | * 133 | * INLINE_ARG1 stores the SIGUSR1 signal value into the second argument 134 | * register completing kill(2)'s arguments. (ARG1 because of zero index) 135 | */ 136 | #define SEND_TRACER_SIGNAL() \ 137 | __asm__( \ 138 | LOAD_TRACER_PID \ 139 | ENTER_KERNEL \ 140 | ::SET_SYSCALL(SYS_kill), \ 141 | INLINE_ARG1(SIGUSR1) \ 142 | ) 143 | 144 | /* Trampy internal declarations */ 145 | int __trampy_safe_entry(void); 146 | static int __trampy_size_sym(); 147 | 148 | /* This function yields the size of the assembly to be injected */ 149 | size_t trampy_get_code_size(void) { 150 | union { 151 | int (*func)(void); 152 | size_t off; 153 | } start, stop; 154 | 155 | start.func = __trampy_safe_entry; 156 | stop.func = __trampy_size_sym; 157 | 158 | return stop.off - start.off; 159 | } 160 | 161 | /* This function returns a pointer to the assembly entry */ 162 | void *trampy_get_safe_entry(void) { 163 | union { 164 | int (*func)(void); 165 | void *ptr; 166 | } _fcast; 167 | 168 | _fcast.func = __trampy_safe_entry; 169 | return _fcast.ptr; 170 | } 171 | 172 | /* This function is simply a container for the assembly loop 173 | * below, which is the actual code to be injected upon safe process 174 | * forking/cloning 175 | */ 176 | void __trampy_container_func() { 177 | /* Setup a label, which we can hook */ 178 | __asm__(""\ 179 | "__trampy_safe_entry:\n" 180 | ); 181 | 182 | /* This syscall is to be replaced with the 183 | * appropriate fork/clone/vfork. 184 | */ 185 | MAKE_SYSCALL(SYS_sched_yield); 186 | 187 | /* This syscall will only occur in the child as the 188 | * parent is restored to its original position after 189 | * executing the previous fork/clone/vfork syscall. 190 | * 191 | * We send the tracing process SIGUSR1 to inform it 192 | * of the child's existence. The tracer then attaches 193 | * and repositions the child to its original syscall 194 | * position. 195 | * 196 | * The child can obtain the PID of the tracing process 197 | * by reading a specific register. The tracer will have 198 | * written its PID there. To find out which register, see 199 | * the macro's at the start of the Trampy file. 200 | * 201 | * XXX: We do not do any error handling in case the kill 202 | * fails. 203 | */ 204 | SEND_TRACER_SIGNAL(); 205 | 206 | #if 0 207 | /* Break stuff for libSegFault */ 208 | #ifdef __arm__ 209 | __asm__("mov pc, #0\n"); 210 | #elif defined(__i386__) || defined(__x86_64__) 211 | __asm__("hlt\n"); 212 | #endif 213 | #endif 214 | 215 | /* Now the child keeps making sched_yield syscalls until 216 | * the tracer restores it. 217 | */ 218 | while(1) { 219 | MAKE_SYSCALL(SYS_sched_yield); 220 | } 221 | 222 | return; 223 | } 224 | 225 | /* This function (symbol) is used to compute 226 | * the size of the injected assembly */ 227 | static int __trampy_size_sym() { 228 | return 42; 229 | } 230 | 231 | -------------------------------------------------------------------------------- /src/trampy.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | /* Trampy is Tracy's secure entry point that can be injected in 18 | * child processes. 19 | * 20 | * It performs a busy wait, non-stop performing a schedule yield. 21 | * This busy wait therefore should not use up much CPU time since the process 22 | * immediately stops execution upon starting. In theory this should result 23 | * in the tracer being given control of the child ASAP. 24 | */ 25 | 26 | /* This function returns a pointer indicating the position of the entry code. */ 27 | void *trampy_get_safe_entry(void); 28 | 29 | /* This function retuns the code size in bytes. 30 | * 31 | * The entry point is not guaranteed to work unless at least this many 32 | * bytes are copied. 33 | */ 34 | size_t trampy_get_code_size(void); 35 | 36 | -------------------------------------------------------------------------------- /src/zipjail/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean default 2 | 3 | CFLAGS += -std=c99 -pedantic -Wall -Wextra -pipe 4 | CFLAGS += -D_POSIX_SOURCE -D_GNU_SOURCE -pthread -static -s 5 | 6 | LDFLAGS += -rdynamic 7 | 8 | BINARY = zipjail 9 | 10 | default: zipjail 11 | 12 | OBJECTS:=../libtracy.a 13 | 14 | zipjail: zipjail.c $(OBJECTS) 15 | $(CC) zipjail.c $(CFLAGS) $(OBJECTS) $(LDFLAGS) -o zipjail -I.. 16 | 17 | clean: 18 | rm -f *.o zipjail 19 | -------------------------------------------------------------------------------- /src/zipjail/README.rst: -------------------------------------------------------------------------------- 1 | ZipJail 2 | ======= 3 | 4 | ZipJail is a usermode sandbox for unpacking archives using the ``unzip``, 5 | ``rar``, ``7z``, and ``unace`` utilities. Through the use of the ``tracy`` 6 | library it limits the attack surfaces to an absolute minimum in case a 7 | malicious archive tries to exploit known or unknown vulnerabilities in said 8 | archive tools. 9 | 10 | **Motivation behind this small wrapper utility** may be found in the 11 | `Security`_ chapter, below in this document. 12 | 13 | Usage 14 | ===== 15 | 16 | The ``zipjail`` command itself requires two parameters followed by the command 17 | that should be executed and jailed (i.e., sandboxed). The two parameters 18 | belonging to ``zipjail`` define the filepath to the archive and the output 19 | directory to which file writes should be restricted. 20 | 21 | .. code-block:: bash 22 | 23 | $ zipjail 24 | zipjail 0.3.1 - safe unpacking of potentially unsafe archives. 25 | Copyright (C) 2016, Jurriaan Bremer . 26 | Based on Tracy by Merlijn Wajer and Bas Weelinck. 27 | (https://github.com/MerlijnWajer/tracy) 28 | 29 | Usage: zipjail [-v] 30 | input: input archive file 31 | output: directory to extract files to 32 | verbose: some verbosity 33 | 34 | Please refer to the README for the exact usage. 35 | 36 | Following we will demonstrate ``zipjail``'s usage based on an input file 37 | called ``archive.zip`` and the output directory ``/tmp/unpacked/``. 38 | 39 | Unzip 40 | ^^^^^ 41 | 42 | In order to run ``zipjail`` with ``unzip`` the command-line should be 43 | constructed as follows. 44 | 45 | .. code-block:: bash 46 | 47 | $ zipjail file.zip /tmp/unpacked unzip -o -d /tmp/unpacked file.zip 48 | 49 | Rar 50 | ^^^ 51 | 52 | Just like for the ``7z`` command we require setting the multithreaded count 53 | for the ``rar`` command. It should be noted that ``unrar`` version 54 | ``5.00 beta 8`` does not support the multithreaded option and thus ``zipjail`` 55 | is not capable of running with that version. So far we have only tested that 56 | ``zipjail`` works with ``rar`` version ``4.20``. Its usage is as follows. 57 | 58 | .. code-block:: bash 59 | 60 | $ zipjail file.rar /tmp/unpacked rar x -mt1 file.rar /tmp/unpacked 61 | 62 | 7z 63 | ^^ 64 | 65 | Running ``zipjail`` with ``7z`` may be done as follows. Note that we pass 66 | along the ``-mmt=off`` option which disables multithreaded decompression for 67 | ``bzip2`` targets. By keeping ``zipjail``'s sandboxing single-threaded we keep 68 | its logic easy and secure (using multithreading race conditions would be 69 | fairly trivial). In fact, as per our unittests, trying to instantiate 70 | multithreading (e.g., through ``pthread``, which internally invokes the 71 | ``clone(2)`` system call) is blocked completely. (Also note that the directory 72 | provided to ``7z``'s ``-o`` parameter should be added right away without 73 | additional whitespaces). 74 | 75 | .. code-block:: bash 76 | 77 | $ zipjail file.7z /tmp/unpacked 7z x -mmt=off -o/tmp/unpacked file.7z 78 | 79 | unace 80 | ^^^^^ 81 | 82 | Another utility, another command-line. This time, for ``unace``, which handles 83 | ``.ace`` files, the command-line is fairly straightforward except for the 84 | input file path and the directory path that are passed along. The file path 85 | must be an absolute path and the directory path needs to be slash-terminated, 86 | i.e., the path should finish off with a forward slash. 87 | 88 | .. code-block:: bash 89 | 90 | $ zipjail /tmp/file.ace /tmp/unpacked unace x /tmp/file.ace /tmp/unpacked/ 91 | 92 | It should be noted that only ``unace`` version ``2.5`` is supported as the 93 | older versions don't support either the command-line arguments or the ``.ace`` 94 | samples that are actually being used in-the-wild. Installing this particular 95 | version may be done through ``sudo apt install unace-nonfree``. 96 | 97 | Security 98 | ======== 99 | 100 | Given its security implications (and use in, e.g., `Cuckoo Sandbox`_) it is of 101 | utmost importance that ``zipjail`` is completely secure. Therefore, may you 102 | locate a potential security issue, please reach out to us at 103 | ``jbr@cuckoo.sh``. 104 | 105 | There has been some public research into vulnerabilities and exploits aiming 106 | at archive implementations in particular. Following is a non-complete list of 107 | such papers (feel free to reach out to add your research): 108 | 109 | * `PlayingWithFire by Felix Wilhelm, directory traversal through symlinks bug 110 | leading to RCE in FireEye MPS appliance 111 | `_. 112 | * `Various 7-Zip vulnerabilities, by Cisco Talos 113 | `_. 114 | * `Various libarchive vulnerabilities, by Cisco Talos 115 | `_. 116 | 117 | .. _`Cuckoo Sandbox`: https://github.com/cuckoosandbox/cuckoo 118 | -------------------------------------------------------------------------------- /src/zipjail/tests/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean default 2 | 3 | CFLAGS += -std=c99 -pedantic -Wall -Wextra -pipe 4 | CFLAGS += -D_POSIX_SOURCE 5 | CFLAGS += -D_GNU_SOURCE 6 | CFLAGS += -ggdb -pthread 7 | 8 | SOURCE=$(wildcard *.c) 9 | BINARY32=$(SOURCE:%.c=%-x86.out) 10 | BINARY64=$(SOURCE:%.c=%-x64.out) 11 | RESULTS=$(BINARY32:%.out=%.result) 12 | RESULTS+=$(BINARY64:%.out=%.result) 13 | WORKDIR=/tmp/zipjail-workingdir 14 | 15 | default: $(BINARY32) $(BINARY64) $(RESULTS) unpack 16 | 17 | %-x86.out: %.c 18 | $(CC) $^ $(CFLAGS) $(LDFLAGS) -o $@ -m32 19 | 20 | %-x64.out: %.c 21 | $(CC) $^ $(CFLAGS) $(LDFLAGS) -o $@ 22 | 23 | %.result: %.out 24 | touch /tmp/zipjail-input 25 | rm -rf $(WORKDIR) /tmp/zipjail-dirtydir 26 | mkdir -p $(WORKDIR) 27 | echo hello > $(WORKDIR)/a.c 28 | echo world > $(WORKDIR)/a.py 29 | ! ../zipjail /tmp/zipjail-input /tmp/zipjail-dirtydir ./$^ 30 | 31 | unpack: 32 | rm -rf /tmp/zipjail-simple 33 | ../zipjail simple.zip /tmp/zipjail-simple unzip -o -d /tmp/zipjail-simple simple.zip 34 | rm -rf /tmp/zipjail-simple 35 | ../zipjail simple.rar /tmp/zipjail-simple rar x -mt1 simple.rar /tmp/zipjail-simple 36 | rm -rf /tmp/zipjail-simple 37 | ../zipjail simple.7z /tmp/zipjail-simple 7z x -mmt=off -o/tmp/zipjail-simple simple.7z 38 | rm -rf /tmp/zipjail-simple 39 | ../zipjail $(abspath simple.ace) /tmp/zipjail-simple unace x simple.ace /tmp/zipjail-simple/ 40 | 41 | clean: 42 | rm -f $(BINARY32) $(BINARY64) 43 | -------------------------------------------------------------------------------- /src/zipjail/tests/execv.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | 18 | /* 19 | * We don't allow execve. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | int main() 29 | { 30 | close(open("/tmp/zipjail-input", O_RDONLY)); 31 | 32 | execl("/bin/sh", "/bin/sh", "-c", "echo this is exec", NULL); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /src/zipjail/tests/fork.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | 18 | /* 19 | * We don't allow forking. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | int main() 29 | { 30 | close(open("/tmp/zipjail-input", O_RDONLY)); 31 | 32 | if(fork() == 0) { 33 | printf("this is child\n"); 34 | } 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /src/zipjail/tests/longpath.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | 18 | /* 19 | * We don't allow "extremely" long paths which we don't expect. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | static const char *A255SL = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/"; 31 | 32 | int main() 33 | { 34 | close(open("/tmp/zipjail-input", O_RDONLY)); 35 | 36 | static char longpath[0x10000]; 37 | 38 | strcpy(longpath, "/tmp/zipjail-dirtydir/"); 39 | 40 | for (int i = 0; i < 10; i++) { 41 | strcat(longpath, A255SL); 42 | mkdir(longpath, 0777); 43 | } 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /src/zipjail/tests/mkdir.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | 18 | /* 19 | * We don't allow mkdir() outside of the dirty directory. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | int main() 29 | { 30 | close(open("/tmp/zipjail-input", O_RDONLY)); 31 | 32 | mkdir("/tmp/zipjail-dirtydir/../zipjail-workingdir/foo", 0775); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /src/zipjail/tests/mkdir2.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | 18 | /* 19 | * We don't allow mkdir() outside of the dirty directory. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | int main() 29 | { 30 | close(open("/tmp/zipjail-input", O_RDONLY)); 31 | 32 | mkdir("/tmp/zipjail-workingdir/foo", 0775); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /src/zipjail/tests/multithread.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | 18 | /* 19 | * We don't allow the unpacking process to use multithreading as, firstly, 20 | * it's not required for unzip and/or 7z x, and secondly, it would allow race 21 | * conditions to occur in our sandbox. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | void *echo(void *arg) 32 | { 33 | (void) arg; 34 | 35 | printf("self => %p\n", (void *) pthread_self()); 36 | return NULL; 37 | } 38 | 39 | int main() 40 | { 41 | close(open("/tmp/zipjail-input", O_RDONLY)); 42 | 43 | pthread_t t1, t2; 44 | 45 | pthread_create(&t1, NULL, &echo, NULL); 46 | pthread_create(&t2, NULL, &echo, NULL); 47 | 48 | pthread_join(t1, NULL); 49 | pthread_join(t2, NULL); 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /src/zipjail/tests/openat.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | 18 | /* 19 | * For now, we don't allow directory traversal in openat. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | int main() 29 | { 30 | close(open("/tmp/zipjail-input", O_RDONLY, 0)); 31 | 32 | openat(AT_FDCWD, "/tmp/zipjail-dirtydir/../zipjail-workingdir/a.py", O_WRONLY, 0); 33 | } 34 | -------------------------------------------------------------------------------- /src/zipjail/tests/relative.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | 18 | /* 19 | * For now, we don't allow the creation of symbolic links. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | int main() 29 | { 30 | close(open("/tmp/zipjail-input", O_RDONLY, 0)); 31 | 32 | open("/tmp/zipjail-dirtydir/../zipjail-workingdir/a.py", O_WRONLY, 0); 33 | } 34 | -------------------------------------------------------------------------------- /src/zipjail/tests/relative2.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | 18 | /* 19 | * Don't allow directory traversal in open. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | int main() 29 | { 30 | close(open("/tmp/zipjail-input", O_RDONLY, 0)); 31 | 32 | open("/tmp/zipjail-dirtydir/../zipjail-workingdir/x.py", O_WRONLY, 0); 33 | } 34 | -------------------------------------------------------------------------------- /src/zipjail/tests/simple.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MerlijnWajer/tracy/111f48350e8070b055f4b67091c2cc6151fa7449/src/zipjail/tests/simple.7z -------------------------------------------------------------------------------- /src/zipjail/tests/simple.ace: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MerlijnWajer/tracy/111f48350e8070b055f4b67091c2cc6151fa7449/src/zipjail/tests/simple.ace -------------------------------------------------------------------------------- /src/zipjail/tests/simple.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MerlijnWajer/tracy/111f48350e8070b055f4b67091c2cc6151fa7449/src/zipjail/tests/simple.rar -------------------------------------------------------------------------------- /src/zipjail/tests/simple.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MerlijnWajer/tracy/111f48350e8070b055f4b67091c2cc6151fa7449/src/zipjail/tests/simple.zip -------------------------------------------------------------------------------- /src/zipjail/tests/symlink.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | 18 | /* 19 | * For now, we don't allow the creation of symbolic links. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | int main() 29 | { 30 | close(open("/tmp/zipjail-input", O_RDONLY)); 31 | 32 | symlink("/tmp/zipjail-workingdir", "/tmp/zipjail-dirtydir/hello"); 33 | } 34 | -------------------------------------------------------------------------------- /src/zipjail/tests/unlink.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | 18 | /* 19 | * We don't allow unlink outside of the dirty directory. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | int main() 29 | { 30 | close(open("/tmp/zipjail-input", O_RDONLY)); 31 | 32 | unlink("/tmp/zipjail-workingdir/a.c"); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /src/zipjail/tests/unlink2.c: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of Tracy. 3 | 4 | Tracy is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Tracy is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Tracy. If not, see . 16 | */ 17 | 18 | /* 19 | * We don't allow unlink outside of the dirty directory. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | int main() 29 | { 30 | close(open("/tmp/zipjail-input", O_RDONLY)); 31 | 32 | unlink("/tmp/zipjail-dirtydir/../zipjail-workingdir/a.c"); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /university-work/TODO: -------------------------------------------------------------------------------- 1 | Tracy: 2 | 3 | [X M ] Intercept system calls with ptrace(2) 4 | [X M ] Hook system calls 5 | [X MB] Read/Write system call arguments 6 | [X MB] Inject system calls 7 | [X M ] Asynchronous system call injection. 8 | [X M ] Modify (and deny) system calls 9 | [X B] Efficiently read(and write?) child memory. (Use mmap and shared memory) 10 | [/ B] Efficiently share (allow read) memory with the child (Use mmap and shared 11 | Memory) 12 | [X M ] Means to conveniently store data per child/pid. (void* in tracy_child) 13 | [X B] (Optional) Attaching to running processes 14 | [X MB] (Optional) Trace children as well. Default on Linux, needs hacks to work 15 | on *BSD, Solaris. 16 | [X M ] Finish code that tests for fails. (Do we kill all childs on some 17 | failures?) 18 | [X M ] Implement deny i.c.w. return code -ENOSYS, perhaps 19 | "unimplement_syscall"? 20 | 21 | [X B] Add interrupt handler to tracy_main(). 22 | [X M ] Documentation for tracy. (in sphinx and code) 23 | 24 | [/ MB] API support for threads. (Not in tracy, but for threaded tracees) 25 | 26 | Optional: 27 | [ ] System call injection by signal. (Requires some changes to the injection 28 | functions as we can't use the current value of the PC) 29 | 30 | Soxy: 31 | 32 | [XJ ] Working implementation of SOCKS 5 protocol 33 | [XJMB] Hook some system calls, and perform required operations. We want to hook at 34 | least: read(2), write(2), connect(2), getsockname(2), socket(2). 35 | [XJMB] Keep track of FDs of sockets that we opened. 36 | [XJ M] Implement support for IPv4 (IPv6 optional) 37 | [XJ M] Implement support for TCP (UDP optional) 38 | [ M ] Implement support for rule-based proxifying. 39 | 40 | Documentation / Report 41 | 42 | [XJMB] Proposal 43 | [X M ] Tracy motivation 44 | [X M ] Tracy API 45 | [X M ] Tracy design decisions (ptrace caveats, platform support, arch support) 46 | [ JMB] Soxy motivation 47 | [ JMB] Soxy usage 48 | [ JMB] Soxy design decisions 49 | 50 | [X M ] Final report 51 | [X M ] Motivation Chapter 52 | [X M ] Theory (ptrace explanation) 53 | [X MB] Implementation (Tracy design decisions) 54 | [/J ] Soxy 55 | [X M ] Caveats / Discussion 56 | [X M ] Conclusion 57 | [X M ] Future work 58 | [X M ] Related work 59 | [X M ] References 60 | -------------------------------------------------------------------------------- /university-work/report/Makefile: -------------------------------------------------------------------------------- 1 | 2 | .PHONY: default clean report 3 | 4 | default: report 5 | 6 | report: dot 7 | texi2pdf report.tex 8 | 9 | clean: 10 | rm *.pdf -f 11 | 12 | dot: ptrace1 ptrace2 pre post 13 | 14 | ptrace1: ptrace.dot 15 | dot -Tpng ptrace.dot > ptrace.png 16 | 17 | pre: pre.dot 18 | dot -Tpng pre.dot > pre.png 19 | 20 | post: post.dot 21 | dot -Tpng post.dot > post.png 22 | 23 | ptrace2: ptrace2.dot 24 | dot -Tpng ptrace2.dot > ptrace2.png 25 | 26 | -------------------------------------------------------------------------------- /university-work/report/WORK.bas: -------------------------------------------------------------------------------- 1 | 2 | ----------------- Per maand ------------------ 3 | 4 | Programmeer/Debug werk volgens time tracker: 5 | Feb: 11 uur en 22 min 6 | Mar: 20 uur en 09 min 7 | May: 9 uur en 30 min 8 | Jun: 26 uur en 34 min 9 | Jul: 12 uur en 43 min 10 | 11 | Totaal: 80 uur en 18 min 12 | 13 | -------------- Inschattingen ------------------ 14 | 15 | Niet geregistreerde programmeer uren: 7 uur. 16 | IRC Overleg: 9 uur. 17 | UvA bijeenkomsten: 8 uur. 18 | Schrijven/Controleren verslag: 10 uur. 19 | Overig: 15 uur. 20 | - Safe-fork uitwerking. 21 | - W^X concept. 22 | - Memory runtime capability concept. 23 | - Memory PPM onderzoek. 24 | 25 | In samenwerking met Merlijn werken: 29 uur: 26 | - Programmeren: 20 uur 27 | - Verslag controleren/schrijven: 9 uur. 28 | 29 | -------------- 30 | 31 | Eind uren totaal: 158 uren 32 | 33 | -------------------------------------------------------------------------------- /university-work/report/WORK.merlijn: -------------------------------------------------------------------------------- 1 | Hours worked: 335 (Approximately...) 2 | 3 | Proposal: 15 hours. 4 | 5 | Documentation: 6 | - Sphinx: 15 hours. 7 | - Documentation for tracy: 5 hours (15 July - 19 July) 8 | 9 | Meetings: 10 | - 2 x 2 hours. 11 | - 4 hours. 12 | 13 | Code: (Time spent writing only) 14 | - Initial work. Getting tracing to work: 15 hours. (23-25 Feb) 15 | - Pre-post tracking, datastructures, etc: 5 hours. (25 Feb) 16 | - Initial ARM support: 10 hours. (25 Feb) 17 | - Signal handling: 2 hours. (26 Feb) 18 | - System call hooking: 2 hours. (26 Feb) 19 | - Memory and register reading: 5 hours. (26 Feb) 20 | - Working system call injection: 14 hours. (28 Feb - 3 March) 21 | - Asynchronous injection: 10 hours. (9 March) 22 | - Architecture fixes, deny functionality: 8 hours. (10-15 March) 23 | - Small features and fixes: 3 hours. (19 March) 24 | - Safe-fork: 7 hours: (13 March) 25 | - child_create event: 1 hour. (18 April) 26 | - Cleaning up children: 3 hours. (27 April) 27 | - Tracy-kill fixes: 2 hours. (12 May) 28 | - Tracy debug functions: 4 hours. (15 May) 29 | - Fix POST-inject bug: 8 hours - yes, really. (15 May) 30 | - Signals: A study in man ptrace: 4 hours. (18 May) 31 | - Bash bug: 2 hours. (11 June) 32 | - safe-fork-fix-1: clone quirks: 8 hours. (13-15 June) 33 | - Source clean up and fixes: 5 hours. (15 July - 16 July) 34 | - Debug improvements + bugfix for safe-fork: 1 hour. (20 July) 35 | - Asynchronous sockets for soxy: 1 hour. (6 Aug) 36 | - ARM support for soxy, tracy ARM fixes: 8 hours. (6-9 Aug) 37 | - Change modification API design flaw, ARM injection and modification 38 | works a lot better now. Excerpt from bug: 39 | Right now tracy_modify_syscall will always override the first argument with the return code. This is problematic; since the user will have to set the return_code to the value of the first argument. We need to think of a way to allow a user to set specific registers only. Also, make sure that people also will not be able to set the IP,SP,PC etc by accident. Currently the IP is always set as well, which is silly. 40 | 4 hours. (9 Aug) 41 | 42 | 43 | Report: 44 | - Initial work on report: 25 hours. (16 March - 1 April) 45 | - Bibliography, more work on the report: 4 hours. (21 June - 24 June) 46 | - More text in the report: 4 hours. (04 July - 06 July) 47 | - Fixes, Ch. 3, Ch. 5: 25 hours. (15 July - 19 July) 48 | - Signal section: 1 hour. (20 July) 49 | - Ptrace performance chapter: 2 hours. (21 July) 50 | - Rewrites, new intro: 6 hours (31 July) 51 | - More work on Ch. 1: 4 hours. (1 Aug) 52 | - QA: 8 hours. (4 Aug) 53 | - Small changes: 2 hours. (5-6 Aug) 54 | - QA, Future work: 6 hours. (12 Aug) 55 | - QA, Threads: 6 hours. (13 Aug) 56 | - Discussion: 6 hours. (14 Aug) 57 | - Report QA: 6 hours. (16-17 Aug) 58 | - Soxy rewrite: 10 hours. (17-19 Aug) 59 | 60 | Tracy tests: 61 | - Loggy: 3 hours. (11 March) 62 | - Dotty: 4 hours. (19 March) 63 | 64 | - Simple tests: 6 hours. (Date and time varies) 65 | 66 | Time spent contemplating: 67 | - Tracy framework/API (10 hours) 68 | - System call injection (10-15 hours) 69 | - Code injection (10 hours) 70 | -------------------------------------------------------------------------------- /university-work/report/post.dot: -------------------------------------------------------------------------------- 1 | digraph pre { 2 | "Post system call" -> "Store registers" -> "Modify IP/PC" -> 3 | "Resume to Pre" -> "Pre system call" -> "Modify registers" -> 4 | "Resume to Post" -> "Store result" -> "Restore registers" -> 5 | "Post system call" 6 | } 7 | -------------------------------------------------------------------------------- /university-work/report/pre.dot: -------------------------------------------------------------------------------- 1 | digraph pre { 2 | "Pre system call" -> "Store registers" -> "Modify registers" -> 3 | "Resume to Post" -> "Post system call" -> "Store result" -> 4 | "Modify IP/PC" -> "Resume to Pre" -> "Restore registers" -> 5 | "Pre system call" 6 | } 7 | -------------------------------------------------------------------------------- /university-work/report/ptrace.dot: -------------------------------------------------------------------------------- 1 | digraph ptrace { 2 | size="10,10" 3 | cp -> stuff 4 | 5 | execution -> syscall 6 | execution [label="Execution of Tracee"] 7 | 8 | cp[label="Controlling Process", shape=box] 9 | 10 | 11 | stuff [shape=record, label="{Read/Write Memory\n | Change registers}", rank=max] 12 | 13 | stuff -> execution [label="Continue execution"] 14 | syscall -> cp 15 | 16 | syscall [label="System Call (before and after)"] 17 | } 18 | -------------------------------------------------------------------------------- /university-work/report/ptrace2.dot: -------------------------------------------------------------------------------- 1 | digraph ptrace { 2 | 3 | subgraph cp { 4 | node [style=filled, color=white] 5 | style=filled 6 | label = "Controlling process" 7 | b0 [label="..."] 8 | 9 | b0 -> b1 10 | b1 [shape=record, label="{Read/Write Memory\n | Change registers}"] 11 | 12 | b1 -> b2 13 | b2 [label="..."] 14 | b2 -> b3 15 | b3 [label="..."] 16 | b3 -> b4 17 | b4 [label="..."] 18 | 19 | b4 -> b5 20 | b5 [shape=record, label="{Read/Write Memory\n | Change registers}"] 21 | b5 -> b6 22 | b6 [label="..."] 23 | 24 | } 25 | 26 | 27 | subgraph tracee { 28 | node [style=filled] 29 | a0 [label="..."] 30 | a0 -> syscall 31 | a1 [label="\"] 32 | syscall -> a1 33 | 34 | a1 -> a2 -> a3 -> a4 -> a5 -> a6 35 | a2 [label="Start system call"] 36 | 37 | a3 [label="Suspend until system\ncall returns"] 38 | 39 | a4 [label="Finished system call"] 40 | 41 | a5 [label="\"] 42 | 43 | a6 [label="Continue execution"] 44 | 45 | label= "tracee" 46 | color=blue 47 | } 48 | 49 | syscall -> b1 50 | b2 -> a2 51 | a4 -> b5 52 | b5 -> a6 53 | 54 | } 55 | -------------------------------------------------------------------------------- /university-work/report/report.bib: -------------------------------------------------------------------------------- 1 | @inproceedings{Noordende_asecure, 2 | author = {Guido Van ’t Noordende and Ádám Balogh and Rutger Hofman and Frances M. T. Brazier and Andrew S. Tanenbaum}, 3 | title = {A secure jailing system for confining untrusted applications}, 4 | booktitle = {International Conference on Security and Cryptography (SECRYPT)}, 5 | year = {2007} 6 | } 7 | @misc{strace, 8 | title = "strace", 9 | howpublished ="\url{http://sourceforge.net/projects/strace/}" 10 | } 11 | 12 | @misc{golang, 13 | title = "Go Language", 14 | howpublished ="\url{http://golang.org/}" 15 | } 16 | @misc{gdb, 17 | title = "GNU Debugger", 18 | howpublished ="\url{http://sourceware.org/gdb/}" 19 | } 20 | @misc{socks5, 21 | title = "SOCKS 5", 22 | howpublished ="\url{http://www.ietf.org/rfc/rfc1928.txt}" 23 | } 24 | @misc{int80h, 25 | title = "2.1. Default Calling Convention", 26 | howpublished ="\url{http://www.int80h.org/bsdasm/#default-calling-convention}" 27 | } 28 | @misc{posix, 29 | title = "POSIX - Portable Operating System IX", 30 | howpublished ="\url{}" 31 | } 32 | @misc{bsdasm, 33 | title = "FreeBSD Assembly Language Programming", 34 | howpublished ="\url{http://www.int80h.org/bsdasm/#where-errno}" 35 | } 36 | -------------------------------------------------------------------------------- /university-work/report/tracy.dot: -------------------------------------------------------------------------------- 1 | digraph tracy { 2 | node [shape=record]; 3 | 4 | subgraph subtracy { 5 | node [fillcolor="#F05050", style=filled] 6 | 7 | tracy 8 | tracy_childs [shape=record, label=" C_0 | … | C_n"] 9 | tracy_hooks [shape=record, label=" H_0 | … | H_n"] 10 | fpid [label="fpid"] 11 | tracy -> tracy_childs:f0 12 | tracy -> tracy_hooks:f0 13 | tracy -> fpid 14 | } 15 | 16 | subgraph tracychild { 17 | node [fillcolor="#A05050", style=filled] 18 | 19 | child 20 | child -> {type; pre_syscall; mem_fd; denied_nr; inj} 21 | 22 | } 23 | 24 | subgraph tracyevent { 25 | node [fillcolor="#509050", style=filled] 26 | 27 | te [label="type"] 28 | event -> {te; syscall_num; signal_num} 29 | } 30 | 31 | subgraph tracyargs { 32 | node [fillcolor="#A0A0A0", style=filled] 33 | 34 | arg -> {a0; a1; a2; a3; a4; a5; return_code; syscall; ip; sp} 35 | 36 | } 37 | 38 | subgraph tracyinj { 39 | node [fillcolor="#C0C0C0", style=filled] 40 | 41 | inj -> {injecting ; injected ; pre ; syscall_num; callback} 42 | 43 | reg [shape=record, label="r_0 | … | r_n"] 44 | inj -> reg 45 | 46 | } 47 | 48 | tracy_childs:f1 -> child 49 | 50 | child -> tracy 51 | child -> event 52 | 53 | event -> child 54 | event -> arg 55 | } 56 | --------------------------------------------------------------------------------