how to insert unique ID into binary file that created after compilation?

Discussion in 'C Programming' started by pristo, Nov 8, 2005.

  1. pristo

    pristo Guest

    hello All,
    how can i insert unique ID into binary file (that created by compiler)?
    (so after compiling i can to identify the src that i use)

    thx
    pristo, Nov 8, 2005
    #1
    1. Advertising

  2. In article <>,
    pristo <> wrote:
    >hello All,
    >how can i insert unique ID into binary file (that created by compiler)?
    >(so after compiling i can to identify the src that i use)


    Not portable. Can't discuss it here. Blah, blah, blah.
    Kenny McCormack, Nov 8, 2005
    #2
    1. Advertising

  3. pristo

    Eric Sosman Guest

    pristo wrote On 11/08/05 11:36,:
    > hello All,
    > how can i insert unique ID into binary file (that created by compiler)?
    > (so after compiling i can to identify the src that i use)


    In portable C, the closest you can come is to create
    a static variable initialized with the ID you desire. The
    source file name, date, and time are often used for this:

    static const char version_info[] =
    "@@@ VERSION INFO @@@"
    " Compiled from " __FILE__
    " on " __DATE__
    " at " __TIME__;

    Many systems have utilities that can extract and display
    the string constants from an executable or object file,
    and ways to separate the "@@@ VERSION INFO @@@" strings
    from the others (on Unix systems, you could use `strings'
    and `grep'). Some source-management systems can be made
    to provide part or all of the data, which could automate
    the inclusion of a version identifier for each file. Of
    course, all such utilities are not part of the C language,
    and will vary from system to system.

    A disadvantage of this technique is that some compilers
    will issue diagnostic messages about variables that are
    declared but not used; such compilers are likely to complain
    about the `version_info' variable.

    --
    Eric Sosman, Nov 8, 2005
    #3
  4. >how can i insert unique ID into binary file (that created by compiler)?
    >(so after compiling i can to identify the src that i use)


    One common method of inserting an ID is:

    static char rcsid[] = "$Id: foo.c,v 1.7 2005/11/08 12:01:32 root Exp $";

    A compiler might give a warning about an unreferenced variable (and
    might be smart enough to try to discard it): so reference it, for
    example, make "foo -V" print out the version string.

    The method of INSERTING the id is portable. The method of extracting
    it isn't, but locating such a string is fairly easy and makes few
    assumptions beyond the file being a raw binary file: scan until
    you see a $, followed by a known keyword, followed by a colon, then
    output the stuff from a $ to the next $. I think if non-text
    characters (whatever that means) or newlines are encountered between
    the two $, it's not output. I've never seen the program that
    extracts the headers have a false match, although constructing a
    failure case is easy.

    RCS and CVS (source code control systems) will even maintain the
    strings for you with a current version, time stamp, and user who
    last checked it in. You actually put in:
    static char rcsid[] = "$Id$";
    and RCS or CVS will expand it for you.

    Gordon L. Burditt
    Gordon Burditt, Nov 8, 2005
    #4
  5. pristo

    CarlosB Guest

    If you want to mark the binary file that is generated by more than one
    source code: e.g (main.c, other.c, etc.) which will cause more than one
    rcsid, and you want one unique mark for the whole binary, a good way to
    do this is creating your own marker, something like the piece of code
    below: (notice that I'm not testing for i/o, string or any other errors
    in this example).

    typedef struct tagFooter {
    BYTE area1[10];
    BYTE area2[10];
    } _FOOTER;
    #define size_footer sizeof(_FOOTER)

    int main(int argc,char **argv)
    {
    FILE *f;
    int size;
    _FOOTER myInfo;

    if(argc < 3) {
    /* we expect to receive at least 2 parameters from command line */
    return(1);
    }
    strcpy(myinfo.area1,argv[1]);
    strcpy(myinfo.area2,argv[2]);

    f=fopen("myfile.bin","wb");
    fseek(f,0,SEEK_END);
    fwrite(&myinfo,size_footer ,1,f);
    fclose(f);
    return(0);
    }

    Instead of getting the values from command line, you could put a CRC
    check or anything you desire to use. Also It's pretty easy to create a
    program to show the footer information for a marked file.

    Hope this can help you.
    CarlosB, Nov 8, 2005
    #5
  6. pristo

    pristo Guest

    first thx to all for helping,
    i try use your suggestion but its seem that the compiler is optmize the
    variable.
    i write the code for embdded system and i dont have interface to print
    the version out
    so how can i cause the compiler think that i use the variable and not
    to optmize it?

    Pristo
    pristo, Nov 8, 2005
    #6
  7. >If you want to mark the binary file that is generated by more than one
    >source code: e.g (main.c, other.c, etc.) which will cause more than one
    >rcsid,


    Nothing wrong with more than one ID, if you make them static.
    Often that's the whole point: you get the version number of
    everything that was used to create the executable.

    >and you want one unique mark for the whole binary, a good way to


    A common way to deal with this is to use the RCS ID in the version.c
    file or the one in the main program as the primary ID, and that's
    the one that the -V flag prints.

    >do this is creating your own marker, something like the piece of code
    >below: (notice that I'm not testing for i/o, string or any other errors
    >in this example).


    Appending random crap to an executable may destroy it. Particularly
    if the executable has a checksum, digital signature, or other
    integrity check. Also, the program doing it *SHOULD* be flagged
    as a virus.

    There's no guarantee that SEEK_END on a binary file will work.
    (Some OS such as CP/M only keep file sizes in sectors, so
    there may be unwritten stuff at the end of the last sector in
    a binary file, with no way to tell how much of it is unwritten.)

    Gordon L. Burditt

    >
    >typedef struct tagFooter {
    > BYTE area1[10];
    > BYTE area2[10];
    >} _FOOTER;
    >#define size_footer sizeof(_FOOTER)
    >
    >int main(int argc,char **argv)
    >{
    > FILE *f;
    > int size;
    > _FOOTER myInfo;
    >
    > if(argc < 3) {
    > /* we expect to receive at least 2 parameters from command line */
    > return(1);
    > }
    > strcpy(myinfo.area1,argv[1]);
    > strcpy(myinfo.area2,argv[2]);
    >
    > f=fopen("myfile.bin","wb");
    > fseek(f,0,SEEK_END);
    > fwrite(&myinfo,size_footer ,1,f);
    > fclose(f);
    > return(0);
    >}
    >
    >Instead of getting the values from command line, you could put a CRC
    >check or anything you desire to use. Also It's pretty easy to create a
    >program to show the footer information for a marked file.
    >
    >Hope this can help you.
    >
    Gordon Burditt, Nov 8, 2005
    #7
  8. pristo

    pristo Guest

    thx for helping.
    i try use your solution
    and its seen that the copiler optimize the variable,
    i write for embedded system and i dont have interface for print the
    version out
    how can i cause the compiler not to optmize this constant?

    thx
    pristo, Nov 8, 2005
    #8
  9. In article <>,
    pristo <> wrote:
    >i try use your suggestion but its seem that the compiler is optmize the
    >variable.
    >i write the code for embdded system and i dont have interface to print
    >the version out
    >so how can i cause the compiler think that i use the variable and not
    >to optmize it?


    Sometimes declaring the variable as volatile is enough to get the
    compiler to leave it alone even if it isn't used. Sometimes
    simple tricks like taking its strlen() are enough. It depends on
    how smart the compiler is about finding "dead code" and "dead variables".
    --
    If you lie to the compiler, it will get its revenge. -- Eric Sosman
    Walter Roberson, Nov 8, 2005
    #9
  10. pristo

    Skarmander Guest

    pristo wrote:
    > thx for helping.
    > i try use your solution
    > and its seen that the copiler optimize the variable,
    > i write for embedded system and i dont have interface for print the
    > version out
    > how can i cause the compiler not to optmize this constant?
    >

    Please quote the relevant parts of posts your reply to.

    Your compiler or linker may have an option that tells it to emit statics
    even if they're not used. For gcc, it is notable that
    -fkeep-static-consts does *not* do the trick in general; this only works
    if you're not optimizing. Consult your documentation.

    Otherwise, you'll have to try and outsmart your compiler (this is
    generally a bad idea, but it may be the only option). That is, involve
    the constant in expressions that are too complicated for the compiler to
    detect as going unused or evaluating to a constant.

    If you find such an expression, it may be a good idea to encapsulate it
    in a function, otherwise it'll look very mysterious.

    S.
    Skarmander, Nov 8, 2005
    #10
  11. pristo

    Skarmander Guest

    Skarmander wrote:
    > pristo wrote:
    >
    >> thx for helping.
    >> i try use your solution
    >> and its seen that the copiler optimize the variable,
    >> i write for embedded system and i dont have interface for print the
    >> version out
    >> how can i cause the compiler not to optmize this constant?
    >>

    > Please quote the relevant parts of posts your reply to.
    >

    ....you reply to.

    S.
    --
    I hate typo fixes, but sometimes they're necessary
    Skarmander, Nov 8, 2005
    #11
  12. pristo

    Eric Sosman Guest

    Skarmander wrote On 11/08/05 16:01,:
    > pristo wrote:
    >
    >>thx for helping.
    >>i try use your solution
    >>and its seen that the copiler optimize the variable,
    >>i write for embedded system and i dont have interface for print the
    >>version out
    >>how can i cause the compiler not to optmize this constant?
    >>

    >
    > Please quote the relevant parts of posts your reply to.
    >
    > Your compiler or linker may have an option that tells it to emit statics
    > even if they're not used. For gcc, it is notable that
    > -fkeep-static-consts does *not* do the trick in general; this only works
    > if you're not optimizing. Consult your documentation.


    Also check your documentation to see whether your compiler
    already "fingerprints" its outputs, and whether tools to display
    the fingerprints exist. Such things aren't part of the C language,
    but since you seem to be concerned with just one particular C
    implementation you might as well use whatever it offers.

    --
    Eric Sosman, Nov 8, 2005
    #12
  13. On 8 Nov 2005 12:26:02 -0800, in comp.lang.c , "pristo"
    <> wrote:

    >so how can i cause the compiler think that i use the variable and not
    >to optmize it?


    Use it in your code.

    Or search the documentation for compiler flags to disable optimisation
    for that specific object. There may be pragmas.
    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

    ----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
    Mark McIntyre, Nov 8, 2005
    #13
  14. pristo

    Alan Balmer Guest

    On Tue, 08 Nov 2005 19:20:34 -0000, (Gordon
    Burditt) wrote:

    >>how can i insert unique ID into binary file (that created by compiler)?
    >>(so after compiling i can to identify the src that i use)

    >
    >One common method of inserting an ID is:
    >
    >static char rcsid[] = "$Id: foo.c,v 1.7 2005/11/08 12:01:32 root Exp $";


    It's not a bad idea to use a format recognized by the Unix "what"
    command. Excerpt from man page:

    The what command searches the given files for all occurrences of the
    pattern that get(1) substitutes for %Z% (currently @(#) at this
    printing) and prints out what follows until the first ", >, new-line,
    \, or null character. For example, if the C program in file f.c
    contains

    char ident[] = "@(#)identification information";

    Then you can write a portable version of "what" to go along with it
    :)
    >
    >A compiler might give a warning about an unreferenced variable (and
    >might be smart enough to try to discard it): so reference it, for
    >example, make "foo -V" print out the version string.
    >
    >The method of INSERTING the id is portable. The method of extracting
    >it isn't, but locating such a string is fairly easy and makes few
    >assumptions beyond the file being a raw binary file: scan until
    >you see a $, followed by a known keyword, followed by a colon, then
    >output the stuff from a $ to the next $. I think if non-text
    >characters (whatever that means) or newlines are encountered between
    >the two $, it's not output. I've never seen the program that
    >extracts the headers have a false match, although constructing a
    >failure case is easy.
    >
    >RCS and CVS (source code control systems) will even maintain the
    >strings for you with a current version, time stamp, and user who
    >last checked it in. You actually put in:
    >static char rcsid[] = "$Id$";
    >and RCS or CVS will expand it for you.
    >
    > Gordon L. Burditt

    --
    Al Balmer
    Balmer Consulting
    Alan Balmer, Nov 8, 2005
    #14
  15. Re: how to insert unique ID into binary file that created aftercompilation?

    Alan Balmer <> writes:
    > On Tue, 08 Nov 2005 19:20:34 -0000, (Gordon
    > Burditt) wrote:
    >
    >>>how can i insert unique ID into binary file (that created by compiler)?
    >>>(so after compiling i can to identify the src that i use)

    >>
    >>One common method of inserting an ID is:
    >>
    >>static char rcsid[] = "$Id: foo.c,v 1.7 2005/11/08 12:01:32 root Exp $";

    >
    > It's not a bad idea to use a format recognized by the Unix "what"
    > command.


    <OT>
    The "what" command is part of SCCS, a mostly obsolete source control
    system that isn't even installed on a lot of Unix-like systems.
    See also RCS, CVS, and "ident".
    </OT>

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Nov 9, 2005
    #15
  16. pristo

    CarlosB Guest

    > Appending random crap to an executable may destroy it.

    The random "crap" you mention is just an example on how to implement a
    digital signature, as this binary file belongs to him. Besides this,
    the "rcsid" example requires a control version system, which cannot be
    the case.

    > There's no guarantee that SEEK_END on a binary file will work.


    Sorry my friend, but the issue with SEEK_END is with text files, not
    binary.
    CarlosB, Nov 9, 2005
    #16
  17. pristo

    Alan Balmer Guest

    On Wed, 09 Nov 2005 00:50:59 GMT, Keith Thompson <>
    wrote:

    >Alan Balmer <> writes:
    >> On Tue, 08 Nov 2005 19:20:34 -0000, (Gordon
    >> Burditt) wrote:
    >>
    >>>>how can i insert unique ID into binary file (that created by compiler)?
    >>>>(so after compiling i can to identify the src that i use)
    >>>
    >>>One common method of inserting an ID is:
    >>>
    >>>static char rcsid[] = "$Id: foo.c,v 1.7 2005/11/08 12:01:32 root Exp $";

    >>
    >> It's not a bad idea to use a format recognized by the Unix "what"
    >> command.

    >
    ><OT>
    >The "what" command is part of SCCS, a mostly obsolete source control
    >system that isn't even installed on a lot of Unix-like systems.
    >See also RCS, CVS, and "ident".
    ></OT>

    <Still OT>
    It's a standalone command, not dependent on SCCS. Our HP-UX systems
    always have it, but never have SCCS (or RCV or CVS, for that matter.)
    It's probably available for most Unix systems (all of which have stuff
    available which may or may not be installed.)

    What's more, it's a very useful command, and as I suggested, not hard
    to implement yourself. Better, imo, than inventing a new format with
    no meaning to anyone else.
    --
    Al Balmer
    Balmer Consulting
    Alan Balmer, Nov 9, 2005
    #17
  18. In article <>,
    CarlosB <> wrote:
    [without proper attribution to another poster]

    >> There's no guarantee that SEEK_END on a binary file will work.


    >Sorry my friend, but the issue with SEEK_END is with text files, not
    >binary.


    C89 4.9.9.2 The fseek Function

    A binary stream need not meaningfully support
    fseek calls with a whence value of SEEK_END.

    For a text stream, either offset ahall be zero, or offset shall be
    a value returned by an earlier call to the ftell function on the same
    stream and whence shall be SEEK_SET.

    --
    I was very young in those days, but I was also rather dim.
    -- Christopher Priest
    Walter Roberson, Nov 9, 2005
    #18
  19. pristo

    Jordan Abel Guest

    On 2005-11-08, Gordon Burditt <> wrote:
    > There's no guarantee that SEEK_END on a binary file will work.
    > (Some OS such as CP/M only keep file sizes in sectors, so
    > there may be unwritten stuff at the end of the last sector in
    > a binary file, with no way to tell how much of it is unwritten.)


    But those will be null bytes. You could always decide "that is part of
    the file for purposes of what i'm doing" - just keep in mind that there
    also may be extra null bytes after whatever _you_ wrote.
    Jordan Abel, Nov 9, 2005
    #19
  20. pristo

    Alan Balmer Guest

    On Wed, 9 Nov 2005 19:36:20 +0000 (UTC), Jordan Abel
    <> wrote:

    >On 2005-11-08, Gordon Burditt <> wrote:
    >> There's no guarantee that SEEK_END on a binary file will work.
    >> (Some OS such as CP/M only keep file sizes in sectors, so
    >> there may be unwritten stuff at the end of the last sector in
    >> a binary file, with no way to tell how much of it is unwritten.)

    >
    >But those will be null bytes. You could always decide "that is part of
    >the file for purposes of what i'm doing" - just keep in mind that there
    >also may be extra null bytes after whatever _you_ wrote.


    They won't necessarily be null. Even if they are, how do you know they
    weren't written on purpose, and part of the data?
    --
    Al Balmer
    Balmer Consulting
    Alan Balmer, Nov 9, 2005
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris Petersen

    Insert file date created into a variable

    Chris Petersen, Nov 5, 2003, in forum: Perl
    Replies:
    1
    Views:
    504
    Eric J. Roode
    Nov 5, 2003
  2. ToshiBoy
    Replies:
    6
    Views:
    832
    ToshiBoy
    Aug 12, 2008
  3. Replies:
    5
    Views:
    247
  4. Chris Petersen

    Insert file date created into a variable

    Chris Petersen, Nov 5, 2003, in forum: Perl Misc
    Replies:
    5
    Views:
    124
    Steve Grazzini
    Nov 6, 2003
  5. Token Type
    Replies:
    9
    Views:
    340
    Chris Angelico
    Sep 9, 2012
Loading...

Share This Page