LinuxQuestions.org
Register a domain and help support LQ
Go Back   LinuxQuestions.org > Blogs > rainbowsally
User Name
Password

Notices

Rate this Entry

Frankenstein (bash) Meets GodziRRa (C/C++).

Posted 01-25-2012 at 03:57 AM by rainbowsally
Updated 08-06-2014 at 11:34 AM by rainbowsally

Frankenstein (bash) Meets GodziRRa (C/C++).

Changelog: Mar 31, 2012.
Added path correction noted by ntubski. Commandline was:
file-sig file-sig
should be:
./file-sig file-sig

[Thanks.]

Features:
  • Simple C program embedded in a bash script.
  • Program that doesn't print a newline at the end of a string.
  • Compiling without superuser privileges.
  • Ethical concerns.

Requires:
  • bash
  • gcc

Bash is so screwy it feels like you have to hack it to get it to work at times. Once it works it always does the same thing every time so it's reliable once you have managed to crack the "security system" which consists of 'the docs' (aka TFM).

So there's bash in one corner.

In the other corner we have C.

Who needs it?

Well, "bash may need it", is the answer. And C can be used, even included as source, embedded in bash programs.

Don't believe me. Here...

Let's read the first 4 bytes of a file and print it out in modified ascii (for unprintable characters) which bash cannot do on its own.

Need proof that bash needs help? :-) Compare this... and plug your ears if it's a large binary file.

'echo "$(<largebinaryfile)"'

But here's a sketch of a C program that can handle it easily.
Code:
char buf[4];                // a place to hold the file data
FILE* fp;                   // a file pointer
fp = fopen(argv[1], "r");   // open first arg for reading.
fread(buf, 1, 4, fp);       // datasize = byte, get 4 of 'em
fclose(fp);                 // done with the file
dump(buf, 4);               // print it out
What the above is missing is only a
1. check to see if the parameter is a valid file, which bash can do
2. the code for the dump, which C can do
3. an error code from C, which can be any number, meaning anything you like but only a zero return value always means "OK" or (paradoxically) "true" for a value returned to a shell.

Let's fill out the code in a stand-alone C program then let's embed it in a bash script so it compiles on the fly and cleans up when done.

[Mark this spot. It's the text you need to copy/paste into the bash script in a moment.]

file: file-sig.c (initial test version -- mostly useless except for ELF sigs.)
Code:
// file-sig.c
#include <stdio.h>
#include <string.h>
#include <malloc.h>
 
int main(int argc, char** argv)
{
  char buf[4];                // a place to hold the file data
  FILE* fp;                   // a file pointer
  fp = fopen(argv[1], "r");   // open first arg for reading.
  fread(buf, 1, 4, fp);       // datasize = byte, get 4 of 'em
  fclose(fp);                 // done with the file
//  dump(buf, 4);
  // print it out
  int i;
  for(i = 0; i < 4; i++)
    if(isprint(buf[i])) printf("%c", buf[i]);
    else printf(".");
  return 0;
}
Here's what it does when it reads its own sig.
Code:
$> file-sig file-sig
.ELF
The first "file-sig" above is to run the program the second is the name of the file to check which is itself.

Now to embed this in a bash script all we need to do is write the C file, compile it, run it, and then delete both files.
Code:
#!/bin/sh
# This prints out 4 bytes of a file sig

# write the C file
cat << _EOF > file-sig.c
[COPY AND PASTE THE C FILE VERBATIM HERE]
_EOF

# compile it.
gcc file-sig.c -o file-sig

# run it with a valid input param so it doesn't crash.
# we know file-sig will exist so let's do that again.
./file-sig file-sig

echo " <- The ELF signature from an executable binary.
  ---------------------------------------------
  Eh?  Eh?? Well?  What do you think?
  Godzilla meets Frankenstein?  Kinda fun, no?.  :-)
 "

# cleanup... Nah...  Let's leave the files hanging around
# this time.
I know what you're thinking...

Is this LEGAL? Ethical? Open a typical 'configure' script with an editor and find "main" in those files. You can answer that question yourself.

WARNING: Minor rant ahead.

[We're SUPPOSED to be able to do this. Where's the ethics in dumbing down these systems to make it harder to actually get any work out of them? So let's get back on track (you KDE distros!) so we don't have to have two different linuxes installed just to do anything interesting. After all, who do you think is going to fix KDE so it can run an executable when you press ENTER on it? Or when you click on a binary (even gui app)? Obviously not you guys. You broke it. Want a bug report? Here it is. Use the systems you are developing and you won't need the bug reports.]

End of rant. It's safe again. :-)

------------
Notes:

I used a utility to create a clickable IDE launcher and generate my makefile for the first cut. (How I made it clickable is a long story, but older KDE's do that without modification.)

Here's how it was done.
Code:
$> autobake new c-32            # creates an intermediate makefile template, 32 bits.
$> autobake edit                # changed the name of the output program from "main" to
$> autobake create main         # write a simple main program for starters.
File extension for file-sig.<ext> ('c' or 'cpp'): c     
                                # I entered 'c' above.
$> autobake create dirs         # create default source folder and place to put object files
$> autobake create ide          # create the clickable kdevelop3 launcher
$> autobake bake                # and finally generating the makefile from the sources
At this point 'make' generates an executable but it doesn't do much because the C file is just enough to print a hello message or something.

If that looks easier than using cmake or automake, I might have something you'd be interested in. Hang tight for a while. It's currently customized for my old suse 10.0 and a gui toolkit I wrote (well, it's in transition actually).

But if you want to give an old version a spin, you can mess with it yourself and try to get it working for your system. Hopefully the README is up to date.
http://rainbowsally.org/rainbowsally/tkf/ftl/ about 75% down the page.

Sold "as-is". No refunds. ;-)

PS. The above C program demo for this blog entry (not cleaned up) could be expanded to discover the sig of all kinds of files, png,jpeg, xpm, and even oddball binaries like deb packages which are "<arch>" (an 'ar' library archive, it's true).

If you enjoy this kind of activity, tell KDE to put the brakes on. Following Windows over a cliff may not be as smart as they think.

.
Posted in Uncategorized
Views 6356 Comments 2
« Prev     Main     Next »
Total Comments 2

Comments

  1. Old Comment
    You shouldn't assume "." is in $PATH.
    Code:
    # run it with a valid input param so it doesn't crash.
    # we know file-sig will exist so let's do that again.
    ./file-sig file-sig
    Posted 02-04-2012 at 10:24 PM by ntubski ntubski is offline
  2. Old Comment
    Thanks!
    Posted 03-31-2012 at 04:38 AM by rainbowsally rainbowsally is offline
 

  



All times are GMT -5. The time now is 04:02 PM.

Main Menu
Advertisement

My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration