-
Notifications
You must be signed in to change notification settings - Fork 23
Open
Description
I'd like to better understand how the module info is inserted by the linker and how it is found by this tool.
What I understand so far: The binary is read from disk, format-specific (ELF, Mach-O, PE) libraries are used to extract certain sections (e.g. the read-only data), a magic sequence of bytes is searched for indicating the start and end of the module information.
How I've tried to understand it:
- Spent a couple hours doing a shallow read of
cmd/link
, mostlycmd/link/internal/ld
andcmd/link/internal/sym
. I grokked that there's aModuledata
symbol for each object file. Couldn't find where module info was written to the final binary though. Most of the module-related code I found seemed related to shared libraries (I only care about static binaries for now). - Disassembled some go binaries and used
nm
/objdump
/od
to poke around at the symbol table and try to discover more info. Was able to find the go runtime version by referencing the_runtime.buildVersion
in the symbol table (mostly thanks to this article). I found a few promising symbols (runtime.findmoduledatap
,runtime.firstmoduledata
,runtime.lastmoduledatap
). I even succeeded in finding portions of the module info text (i.e. theh1
hash). - Searched for the magic module info start/stop values (defined here) by converting the binary to hex and searching (using both little- and big-endian).
I'm clearly out of my depth here, but I'd like to understand how this works, specifically:
- Where in the linker is this module info inserted?
- Where are the magic values coming from?
This is all in the context of doing security audits on dependencies (go list -m all
leaves a lot to be desired for this use case). I'll feel more comfortable if I can explain how this works better :)
Metadata
Metadata
Assignees
Labels
No labels