Hi Roman,
Bolshakov, Roman wrote:
I also studied that in the spring. You can find a lot of details on the page: http://www.acsu.buffalo.edu/~charngda/elf.html
Very good reference this, thank you - I'll look into it in more detail
over the weekend! OK, in a nutshell, what I am after is, basically, two
things:
1. Find the portion of the kernel code, which is responsible for the
initial loading the file for execution (i.e. when I type "iptables" from
the command line for example). This will help me to modify that code so
that the file which is about to be loaded is "verified" first and raise
a security exception if something is wrong with it.
2. Once I've done that, if there is a possibility to identify all .so
(shared objects) on which this executable depends (by looking at its
headers for example), I could do the same as step 1 above for all
dependent .so files. If not, then I'll have to pass control to ld.so and
intercept the point prior to where these .so are about to be loaded, so
that I could do the verification - as in step one above, but for the
shared objects. If everything checks out, then I'll pass control over to
ld.so.
I am guessing the picture when statically compiled executables are run
is more or less the same with the exception of loading тхе shared
libraries, as they are included as part of the file which needs to be
executed - am I correct in thinking that?
Dynamic linker is loaded by kernel after the kernel reads ELF headers.
And it is precisely at that point I need to take control to "verify" the
executable and, if possible, all .so files on which this file depends.
Then it passes control to the entry point of the linker. If you use glibc the entry point is named _dl_start. So, in general, you need to make breakpoint on _dl_start.
I guess I would need to do that only if I could not find the .so files
on which this executable depends, otherwise the verification could be
done much earlier and I could then let ld.so do its job, right?