Discussion:
Creating .note sections
Ceri Storey
2003-04-20 21:30:10 UTC
Permalink
How do people reccomend I go about programmaticly adding a .note section
to an already-existing (ELF format) binary *and* have it's type set to
PT_NOTE? Is it possible to just create the section normally, then
somehow patch the section type later sensibly?

I've tried looking at the source code for GNU ld etc. But to be honest,
It's got me flummoxed. Well, I've found a reference in the linker script
lexer, but it's going to take a while to dig through.

Thanks in advance for your help ... :)
--
Ceri Storey <***@necrofish.org.uk>
Ceri Storey
2003-04-23 12:31:05 UTC
Permalink
Post by Ceri Storey
How do people reccomend I go about programmaticly adding a .note section
to an already-existing (ELF format) binary *and* have it's type set to
Well, i've figured out that the backed will set any sections who's name
begins with ".note" to type PT_NOTE, so that's sorted. Unfourtunately,
the code segfaults _bfd_elf_strtab_emit () after I call bfd_close ().

The code I'm using to add the section is as follows:

sec = bfd_make_section(thebfd, buf);
if (sec == NULL) {
bfd_perror("make section");
exit(1);
}

printf("set section size: %#016llx\n", (unsigned long long)sectsz);

if (!bfd_set_section_size(thebfd, sec, sectsz)) {
bfd_perror("set section size");
exit(1);
}

sec->output_section = sec;
sec->output_offset = 0;

if (!bfd_set_section_flags(thebfd, sec,
SEC_HAS_CONTENTS | SEC_READONLY | SEC_IN_MEMORY)) {
bfd_perror("set section flags");
exit(1);
}

if (!bfd_set_section_contents(thebfd, sec, sigsect, 0, sectsz)) {
bfd_perror("set section contents");
exit(1);
}

}
--
Ceri Storey <***@necrofish.org.uk>
Nick Clifton
2003-04-24 09:37:19 UTC
Permalink
Hi Ceri,
Post by Ceri Storey
How do people reccomend I go about programmaticly adding a .note
section to an already-existing (ELF format) binary
If you are doing this at assembly-time, it is quite straight forward.
See md_begin() in gas/config/tc-arm.c for an example.

If you are doing this at link-time, then it is probably easiest to add
the section into the linker script being used.

If you are doing this post-link time, then you might like to consider
using "objcopy --add-section" to do the hard work for you. Just
create the section's contents, write them to a file, and then invoke
objcopy.
Unfourtunately, the code segfaults _bfd_elf_strtab_emit () after I
call bfd_close ().
Presumably you have altered or created a symbol table but not
initialised the pointers correctly. Without a working example it is
hard to say. The code you included in your email looked OK in
general, so I would say that you are on the right track.

Cheers
Nick
Ceri Storey
2003-04-24 10:06:26 UTC
Permalink
Post by Nick Clifton
If you are doing this post-link time, then you might like to consider
using "objcopy --add-section" to do the hard work for you. Just
create the section's contents, write them to a file, and then invoke
objcopy.
That's a brilliant idea, thanks.
Post by Nick Clifton
Presumably you have altered or created a symbol table but not
initialised the pointers correctly. Without a working example it is
hard to say. The code you included in your email looked OK in
general, so I would say that you are on the right track.
I'm not doing anything with symbols /at all/, which is really very very
odd.

Cheers.
--
Ceri Storey <***@necrofish.org.uk>
Ceri Storey
2003-04-24 10:16:57 UTC
Permalink
Post by Nick Clifton
If you are doing this post-link time, then you might like to consider
using "objcopy --add-section" to do the hard work for you. Just
create the section's contents, write them to a file, and then invoke
objcopy.
Okay, that works, could you tell me how I would then add an equivalent
ELF segment section? Would I have to manually craft the program headers,
and use bfd_record_phdr?

Thanks again.
--
Ceri Storey <***@necrofish.org.uk>
Nick Clifton
2003-04-24 10:29:15 UTC
Permalink
Hi Ceri,
Post by Ceri Storey
Okay, that works, could you tell me how I would then add an equivalent
ELF segment section? Would I have to manually craft the program headers,
and use bfd_record_phdr?
Hang on a sec, you have to be careful with terminology here. A
"section" is a single region in a program executable or object file.
It has attributes, a name, and usually, some contents as well. A
"segment" is a collection of sections. Segments also have attributes,
but no names. Segments are used by the loader to simplify the process
of moving sections from an executable in some kind of file storage (ie
hard disk) into memory. ELF object files do not contain segments,
only ELF executables do. There is no such thing as a "segment
section".

Anyway, I assume that you mean "How do I add a new segment to an ELF
executable ?". The answer is basically yes, you would have to craft
the program headers yourself. Actually the easiest way to do this
would be to use a linker script to specify the segments explicitly when
creating the ELF executable in the first place.

But why should you want to create your own segments ? Normally the
linker (or objcopy) will take care of this for you.

Cheers
Nick
Ceri Storey
2003-04-24 13:13:17 UTC
Permalink
Post by Nick Clifton
But why should you want to create your own segments ? Normally the
linker (or objcopy) will take care of this for you.
I'm attempting to create a digital signature based executable
verification system for NetBSD, like Microsoft's Authenticode.

What I'm doing is creating a signature of all the non-note sections of
an executable, then writing this back into a PT_NOTE segment of the
executable, which is then checked by the kernel when the executable is run.
(Phew).

I could use the section table, but I'd rather avoid any additional
complexity in kernel space.

Admittedly it's not exactly a pleasant way of doing it..
--
Ceri Storey <***@necrofish.org.uk>
Ian Lance Taylor
2003-04-24 17:19:35 UTC
Permalink
Post by Ceri Storey
Post by Nick Clifton
But why should you want to create your own segments ? Normally the
linker (or objcopy) will take care of this for you.
I'm attempting to create a digital signature based executable
verification system for NetBSD, like Microsoft's Authenticode.
What I'm doing is creating a signature of all the non-note sections of
an executable, then writing this back into a PT_NOTE segment of the
executable, which is then checked by the kernel when the executable is run.
(Phew).
I could use the section table, but I'd rather avoid any additional
complexity in kernel space.
Admittedly it's not exactly a pleasant way of doing it..
That's interesting. I assume that the section has a fixed size. That
suggests that you could create the section in some object file, with
zero contents, or you could add it at link time with zero contents.
The linker should create a PT_NOTE segment for each loadable .note
section, so everything should look right. Then you can compute the
signature.

The trick of course is then to put the signature into the file. The
sneaky way is to objdump to get the file offset of the section, and
use some sort of binary editor to put the bytes in place.

Or you could write a --change-section for objcopy, along the lines of
--add-section. For such a section, you would simply change
copy_section() to use the specified contents instead of calling
bfd_get_section-contents().

Ian
Ceri Storey
2003-04-24 18:14:16 UTC
Permalink
Post by Ian Lance Taylor
That's interesting. I assume that the section has a fixed size. That
Pretty much.
Post by Ian Lance Taylor
[...]
Thanks all, but I've decided that libelf is a better solution, if rather
more low level. I'm just concentrating on getting it working, for the
moment :)
--
Ceri Storey <***@necrofish.org.uk>
Ian Lance Taylor
2003-04-24 21:41:15 UTC
Permalink
Post by Ceri Storey
Post by Ian Lance Taylor
That's interesting. I assume that the section has a fixed size. That
Pretty much.
Post by Ian Lance Taylor
[...]
Thanks all, but I've decided that libelf is a better solution, if rather
more low level. I'm just concentrating on getting it working, for the
moment :)
The problem with adding the section after the executable has been
linked is that you want the section to go into a loadable segment, but
the linker didn't make space for it. You're going to have to refiddle
the loadable segments, which means that you're going to have to move
sections around in virtual memory space and also in the file itsefl.
It may be that libelf will take care of all that for you; I haven't
used it.

This issue is why I recommended creating an empty loadable section of
the right size, so the linker puts it in a loadable segment for you
and you don't have to fuss with adjusting the segments.

Ian

Loading...