{"id":17968317,"url":"https://github.com/david942j/rbelftools","last_synced_at":"2025-05-16T09:06:22.801Z","repository":{"id":18597699,"uuid":"84724427","full_name":"david942j/rbelftools","owner":"david942j","description":"ELF parser library implemented in pure Ruby!","archived":false,"fork":false,"pushed_at":"2025-03-23T12:07:13.000Z","size":951,"stargazers_count":46,"open_issues_count":4,"forks_count":14,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-12T23:29:50.799Z","etag":null,"topics":["elf","elf-parser","elf-patcher","pwntools","ruby","segment","segments-parser"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/david942j.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-03-12T12:39:33.000Z","updated_at":"2025-03-23T12:07:17.000Z","dependencies_parsed_at":"2024-01-13T12:17:40.532Z","dependency_job_id":"3856eed8-9fc2-497c-9bfc-e4c2129737dd","html_url":"https://github.com/david942j/rbelftools","commit_stats":{"total_commits":122,"total_committers":8,"mean_commits":15.25,"dds":"0.30327868852459017","last_synced_commit":"473781bdffed7f3f0ae78ee2de4cbf57b1d101c1"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/david942j%2Frbelftools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/david942j%2Frbelftools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/david942j%2Frbelftools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/david942j%2Frbelftools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/david942j","download_url":"https://codeload.github.com/david942j/rbelftools/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254501558,"owners_count":22081528,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elf","elf-parser","elf-patcher","pwntools","ruby","segment","segments-parser"],"created_at":"2024-10-29T14:20:58.181Z","updated_at":"2025-05-16T09:06:17.794Z","avatar_url":"https://github.com/david942j.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://github.com/david942j/rbelftools/workflows/build/badge.svg)](https://github.com/david942j/rbelftools/actions)\n[![Code Climate](https://codeclimate.com/github/david942j/rbelftools/badges/gpa.svg)](https://codeclimate.com/github/david942j/rbelftools)\n[![Issue Count](https://codeclimate.com/github/david942j/rbelftools/badges/issue_count.svg)](https://codeclimate.com/github/david942j/rbelftools)\n[![Test Coverage](https://codeclimate.com/github/david942j/rbelftools/badges/coverage.svg)](https://codeclimate.com/github/david942j/rbelftools/coverage)\n[![Inline docs](https://inch-ci.org/github/david942j/rbelftools.svg?branch=master)](https://inch-ci.org/github/david942j/rbelftools)\n[![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](https://www.rubydoc.info/github/david942j/rbelftools/)\n[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](http://choosealicense.com/licenses/mit/)\n\n# rbelftools\nPure Ruby library for parsing and patching ELF files.\n\n# Introduction\n\nAn ELF parser implemented in pure Ruby. This work is inspired by [pyelftools](https://github.com/eliben/pyelftools) by [Eli Bendersky](https://github.com/eliben).\n\nThe original motivation to create this gem is to be a dependency of [pwntools-ruby](https://github.com/peter50216/pwntools-ruby). Since ELF parser is not an easy work, it should not be implemented directly in pwntools.\n\nNow rbelftools is also used by the [Homebrew](https://github.com/Homebrew/brew) project: https://github.com/Homebrew/brew/tree/master/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/elftools-1.1.3/lib\n\n**rbelftools**'s target is to create a nice ELF parsing library in Ruby. More features remain a work in progress.\n\n# Install\n\nAvailable on RubyGems.org!\n```bash\ngem install elftools\n```\n\n# Features\n\n- [x] Supports both big and little endian\n- [x] ELF parser\n- [x] ELF headers patcher\n\nSee example usage for more details.\n\n# Example Usage\n\n## Start from a file object\n```ruby\nrequire 'elftools'\n\nelf = ELFTools::ELFFile.new(File.open('spec/files/amd64.elf'))\n#=\u003e #\u003cELFTools::ELFFile:0x00560b147f8328 @elf_class=64, @endian=:little, @stream=#\u003cFile:spec/files/amd64\u003e\u003e\n\nelf.machine\n#=\u003e 'Advanced Micro Devices X86-64'\n\nelf.build_id\n#=\u003e '73ab62cb7bc9959ce053c2b711322158708cdc07'\n```\n\n## Sections\n\n```ruby\nelf.section_by_name('.dynstr')\n#=\u003e\n# #\u003cELFTools::Sections::StrTabSection:0x00560b148cef40\n# @header=\n#  {:sh_name=\u003e86,\n#   :sh_type=\u003e3,\n#   :sh_flags=\u003e2,\n#   :sh_addr=\u003e4195224,\n#   :sh_offset=\u003e920,\n#   :sh_size=\u003e113,\n#   :sh_link=\u003e0,\n#   :sh_info=\u003e0,\n#   :sh_addralign=\u003e1,\n#   :sh_entsize=\u003e0},\n# @name=\".dynstr\"\u003e\n```\n```ruby\nelf.sections.map(\u0026:name).join(' ')\n#=\u003e \" .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss .comment .shstrtab .symtab .strtab\"\n```\n```ruby\nelf.section_by_name('.note.gnu.build-id').data\n#=\u003e \"\\x04\\x00\\x00\\x00\\x14\\x00\\x00\\x00\\x03\\x00\\x00\\x00GNU\\x00s\\xABb\\xCB{\\xC9\\x95\\x9C\\xE0S\\xC2\\xB7\\x112!Xp\\x8C\\xDC\\a\"\n```\n\n## Symbols\n\n```ruby\nsymtab_section = elf.section_by_name('.symtab')\nsymtab_section.num_symbols\n#=\u003e 75\n\nsymtab_section.symbol_by_name('puts@@GLIBC_2.2.5')\n#=\u003e\n# #\u003cELFTools::Sections::Symbol:0x00560b14af67a0\n#  @header={:st_name=\u003e348, :st_info=\u003e18, :st_other=\u003e0, :st_shndx=\u003e0, :st_value=\u003e0, :st_size=\u003e0},\n#  @name=\"puts@@GLIBC_2.2.5\"\u003e\n\nsymbols = symtab_section.symbols # Array of symbols\nsymbols.map(\u0026:name).reject(\u0026:empty?).first(5).join(' ')\n#=\u003e \"crtstuff.c __JCR_LIST__ deregister_tm_clones register_tm_clones __do_global_dtors_aux\"\n```\n\n## Segments\n\n```ruby\nelf.segment_by_type(:note)\n#=\u003e\n# #\u003cELFTools::Segments::NoteSegment:0x00555beaafe218\n# @header=\n#  {:p_type=\u003e4,\n#   :p_flags=\u003e4,\n#   :p_offset=\u003e624,\n#   :p_vaddr=\u003e624,\n#   :p_paddr=\u003e624,\n#   :p_filesz=\u003e68,\n#   :p_memsz=\u003e68,\n#   :p_align=\u003e4}\u003e\n\nelf.segment_by_type(:interp).interp_name\n#=\u003e \"/lib64/ld-linux-x86-64.so.2\"\n```\n\n## Relocations\n```ruby\nelf = ELFTools::ELFFile.new(File.open('spec/files/amd64.elf'))\n# Use relocation to get plt names.\nrela_section = elf.sections_by_type(:rela).last\nrela_section.name\n#=\u003e \".rela.plt\"\nrelocations = rela_section.relocations\nrelocations.map { |r| '%x' % r.header.r_info }\n#=\u003e [\"100000007\", \"200000007\", \"300000007\", \"400000007\", \"500000007\", \"700000007\"]\nsymtab = elf.section_at(rela_section.header.sh_link) # get the symbol table section\nrelocations.map { |r| symtab.symbol_at(r.symbol_index).name }\n#=\u003e [\"puts\", \"__stack_chk_fail\", \"printf\", \"__libc_start_main\", \"fgets\", \"scanf\"]\n```\n\n## Patch\n\nPatch ELF is so easy!\n\nAll kinds of headers (i.e. `Ehdr`, `Shdr`, `Phdr`, etc.) can be patched.\nPatched slots will not be applied on the opened file.\nInvoke `elf.save(filename)` to save the patched ELF into `filename`.\n\n```ruby\nelf = ELFTools::ELFFile.new(File.open('spec/files/amd64.elf'))\nelf.machine\n#=\u003e \"Advanced Micro Devices X86-64\"\nelf.header.e_machine = 40\nelf.machine\n#=\u003e \"ARM\"\n\ninterp_segment = elf.segment_by_type(:interp)\ninterp_segment.interp_name\n#=\u003e \"/lib64/ld-linux-x86-64.so.2\"\ninterp_segment.header.p_filesz\n#=\u003e 28\ninterp_segment.header.p_filesz = 20\ninterp_segment.interp_name\n#=\u003e \"/lib64/ld-linux-x86\"\n\n# save the patched ELF\nelf.save('elf.patched')\n\n# in bash\n# $ file elf.patched\n# elf.patched: ELF 64-bit LSB executable, ARM, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86, for GNU...\n```\n\n# Why rbelftools\n\n1. Fully documented   \n   Always important for an Open-Source project. Online document is [here](http://www.rubydoc.info/github/david942j/rbelftools/master/frames)\n2. Fully tested   \n   Of course.\n3. Lazy loading on everything   \n   To use **rbelftools**, passing the stream object of an ELF file.\n   **rbelftools** will read the stream object **as least times as possible** when parsing\n   the file. Most information will not be fetched until you need it, which makes\n   **rbelftools** efficient.\n4. To be a library   \n   **rbelftools** is designed to be a library for further usage.\n   It will _not_ add any too trivial features.\n   For example, to check whether NX is disabled, **rbelftools** provides\n   `!elf.segment_by_type(:gnu_stack).executable?` but not `elf.nx?`\n5. Section and segment parser   \n   Providing common sections and segments parser. For example, `.symtab`, `.shstrtab`\n   `.dynamic` sections and `INTERP`, `DYNAMIC` segments, etc.\n\n# Development\n```bash\ngit clone https://github.com/david942j/rbelftools\ncd rbelftools\nbundle\nbundle exec rake\n```\nAny comments or suggestions are welcome!\n\n# Cross Platform\n**rbelftools** can be used and has been fully tested on all platforms include Linux, OSX, and Windows!\n\n# License\nMIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavid942j%2Frbelftools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavid942j%2Frbelftools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavid942j%2Frbelftools/lists"}