From 6158b58569fd099989ceba00c30a56d130faa837 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Wed, 12 Oct 2022 22:01:01 -0500 Subject: [PATCH] readelferislinks utility for parsing ERIS ELF notes --- doc/deferred-linking.md | 2 +- overlay/default.nix | 3 ++ packages/readelferislinks/default.nix | 17 +++++++ .../readelferislinks/src/readelferislinks.nim | 47 +++++++++++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 packages/readelferislinks/default.nix create mode 100644 packages/readelferislinks/src/readelferislinks.nim diff --git a/doc/deferred-linking.md b/doc/deferred-linking.md index ebaf5f5..ec2c7dc 100644 --- a/doc/deferred-linking.md +++ b/doc/deferred-linking.md @@ -21,4 +21,4 @@ The format of the CBOR data within the `.note.eris-links` section is a the self- #6.55799({ * tstr => #6.276(bstr) }) ``` -At this time of writing there is no utility for dumping the note into a human readable format. +This repository contains a `readelferislinks` utility for extracting the note into a textual format. diff --git a/overlay/default.nix b/overlay/default.nix index 84f0869..3c103e8 100644 --- a/overlay/default.nix +++ b/overlay/default.nix @@ -214,6 +214,9 @@ in nullPkgs // { # Patch to fix a bug in rewriting the .dynstr section. ] prev.patchelf; + readelferislinks = + final.nimPackages.callPackage ../packages/readelferislinks { }; + rsync = overrideHost { enableACLs = false; popt = null; diff --git a/packages/readelferislinks/default.nix b/packages/readelferislinks/default.nix new file mode 100644 index 0000000..2372c92 --- /dev/null +++ b/packages/readelferislinks/default.nix @@ -0,0 +1,17 @@ +{ lib, buildNimPackage, cbor, eris }: + +buildNimPackage rec { + pname = "readelferislinks"; + version = "20221012"; + nimBinOnly = true; + src = ./src; + preConfigure = '' + cat << EOF > ${pname}.nimble + bin = @["${pname}"] + EOF + ''; + buildInputs = [ cbor eris ]; + meta = { + description = "Utility for parsing ERIS links within an ELF binary"; + }; +} diff --git a/packages/readelferislinks/src/readelferislinks.nim b/packages/readelferislinks/src/readelferislinks.nim new file mode 100644 index 0000000..594615f --- /dev/null +++ b/packages/readelferislinks/src/readelferislinks.nim @@ -0,0 +1,47 @@ +# SPDX-FileCopyrightText: ☭ 2022 Emery Hemingway +# SPDX-License-Identifier: GPL-3.0-or-later.txt + +import std/[os, streams, tables] +import cbor, eris + +proc atChar(strm: Stream; c: char): bool = + if strm.atEnd: + quit "reached end of stream without finding ELF note" + c == strm.readChar() + +proc scanUntil(strm: Stream; pat: string) = + while true: + block patLoop: + for c in pat: + if not strm.atChar(c): break patLoop + return + +proc parseStream(strm: Stream) = + # TODO: write an ELF parser. + strm.scanUntil("Sigil\x00\x00\x00\xD9\xD9\xF7") + # scan for the ELF tag owner and the self-describing CBOR tag + let node = strm.readCbor() + if node.kind == cborUnsigned and node.uint == 0: discard + elif node.kind != cborMap: + quit("unrecognized CBOR data: " & $node) + else: + for key, val in node.map: + if key.kind != cborText or val.kind != cborBytes or not val.hasTag(erisCborTag): + quit("Unrecognized note data " & $node) + let cap = parseCap(val.bytes) + stdout.writeLine cap, " ", key.text + +proc main = + var args = commandLineParams() + if args.len == 0: + args.add "-" + for arg in args: + var str = + if arg == "-": + newFileStream(stdin) + else: + openFileStream(arg) + parseStream(str) + close(str) + +main()