Presumably you don't know where you need to read. So you need to somehow search for the right signature. Why is the root password hash even in memory in the first place?
At any rate, there's probably some search pattern to try and locate the relevant address across a fairly large address space, you need to take into account the lack of accuracy as well. Once you found the location then you presumably know the right offset and just read it straight out.
> Why is the root password hash even in memory in the first place?
I'm very interested in the answer to that question as well, assuming it's true.
Lots of modern software goes to great lengths to ensure that any sensitive data is zeroed out from memory the second it's no longer needed. This includes efforts like modifying garbage collector behavior and preventing swapping so that this data really doesn't stick around a single moment longer than absolutely necessary.
If a standard Linux system really just keeps password hashes (root or not) in memory after loading them, I hope there's a very, very good reason for that. And I hope it's not "duh, we didn't think anyone would be able to read privileged memory".
If you want to get the root password hash into memory, just run sudo, or any other root process that reads /etc/shadow. It'll probably get it mapped into the file system cache, but it'll certainly get it mapped into that process's memory - albeit potentially temporarily.
I don't know that sudo takes any measures to protect that memory. You say "lots of modern software" but it's more like "the extreme minority of software" with regards to security effort.
That sounds about right, there's limited avenues for asking the file/page cache to get rid of data. It comes down to lots of suggesting to the FS cache that it's not needed, but it might linger either way.
Often optimizers will frustrate efforts to zero out sensitive data. It can be arbitrarily hard to make sure it happens. Your source code says "zero it", and the compiler, or even the CPU itself, says "nah, waste of time", and doesn't.
There's always ways to control this stuff adequately by setting the properties of memory ranges and the like. All CPU's have to support some equivalent of "volatile" because that's what memory-mapped hardware expects.
Compilers will often delete code that has volatile stores, if it thinks that would be OK. Not everybody agrees with this policy. But they are not who makes decisions about what compilers do.
There "are always ways", but not everybody always knows what they are, or even knows they need to know them. And, what you think ought to suffice too often does not.
How can a compiler remove a volatile store? There exists hardware where a store has a side effect, regardless of the value itself. For example, writing to a FIFO. That’s the entire point of volatile, no?
Right. In particular, a subsequent write to the same address may overwrite (part of) the cache line representing that bit of memory, pushing it to the back of the LRU line. This might happen over and over again, and that cache line then might not get flushed until the end of process's time slice. Anything out in memory backed by that cache line keeps its old value until the writeback finally happens.
At any rate, there's probably some search pattern to try and locate the relevant address across a fairly large address space, you need to take into account the lack of accuracy as well. Once you found the location then you presumably know the right offset and just read it straight out.