1

I am simply experimenting but have found a phenomena that I would be very appreciative if someone could try to explain.

I write a simple Hello World program in C. Use gcc to compile this program into a hello Unix Executable File, and can run it using ./hello. Neat.

I open this hello file, to see a series of 4 character segments (if someone wants to throw in a technical description for what I am seeing here also, I wouldn't complain.).

My question is, how come when I copy and paste all of these hexadecimal segments to a separate file, let's call test, and use chmod +x test, I do not get the same results running ./test as I do running ./hello?

Here is my C program:

#include <stdio.h>

int main(void)
{
    int a;
    a = 5;

    printf("Memory address: %p\n", (void*) &a);
    return 0;
}

then compiled to (first 20 lines only...)

cffa edfe 0700 0001 0300 0080 0200 0000
1000 0000 1005 0000 8500 2000 0000 0000
1900 0000 4800 0000 5f5f 5041 4745 5a45
524f 0000 0000 0000 0000 0000 0000 0000
0000 0000 0100 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 1900 0000 2802 0000
5f5f 5445 5854 0000 0000 0000 0000 0000
0000 0000 0100 0000 0010 0000 0000 0000
0000 0000 0000 0000 0010 0000 0000 0000
0700 0000 0500 0000 0600 0000 0000 0000
5f5f 7465 7874 0000 0000 0000 0000 0000
5f5f 5445 5854 0000 0000 0000 0000 0000
300f 0000 0100 0000 3800 0000 0000 0000
300f 0000 0400 0000 0000 0000 0000 0000
0004 0080 0000 0000 0000 0000 0000 0000
5f5f 7374 7562 7300 0000 0000 0000 0000
5f5f 5445 5854 0000 0000 0000 0000 0000
680f 0000 0100 0000 0600 0000 0000 0000
680f 0000 0100 0000 0000 0000 0000 0000

I copy this file exactly as is using a text editor.

Looking into it using diff, I realize there is a binary difference?

running ./test returns: (first 20 lines again)

./test: line 1: cffa: command not found
./test: line 2: 1000: command not found
./test: line 3: 1900: command not found
./test: line 4: 524f: command not found
./test: line 5: 0000: command not found
./test: line 6: 0000: command not found
./test: line 7: 0000: command not found
./test: line 8: 5f5f: command not found
./test: line 9: 0000: command not found
./test: line 10: 0000: command not found
./test: line 11: 0700: command not found
./test: line 12: 5f5f: command not found
./test: line 13: 5f5f: command not found
./test: line 14: 300f: command not found
./test: line 15: 300f: command not found
./test: line 16: 0004: command not found
./test: line 17: 5f5f: command not found
./test: line 18: 5f5f: command not found
./test: line 19: 680f: command not found
./test: line 20: 680f: command not found
  • Compare those files. What did you have as original, and what did you copy? (hint: if you see 0x0D then that is a way to display the value 13. You would need to copy that value, not the way it is represented on the screen). – Hennes Apr 29 '15 at 19:17
  • edited original question to help clarify. Thank you for the responses. – a_real_hero Apr 29 '15 at 19:25
  • The key phrase here is: "I copy this file exactly as is using a text editor." ...yeah, that's not going to work. Now, if you used a binary editor, that's another kettle of fish altogether. – michael May 3 '15 at 8:10
3

The hexadecimal codes represent bytes with those character values.

The following shows the actual characters (note that not all are printable characters to copy and paste):

cat ./hello

The following will redirect the output of ./hello to ./test

cat ./hello > ./test
chmod +x ./test
./test

Note: The following copies the executable explicitly:

cp ./hello ./test
  • this works, and is essentially what I was trying to do with the process of copying and pasting. To further my question to you, what exactly is printing out when I run cat? – a_real_hero Apr 29 '15 at 19:53
  • The compiler gcc generates binary (not human readable) machine code. Your hex editor displays the hex value for each byte. The cat command displays the character represented by the value of each byte. – Steven Apr 29 '15 at 20:36
2

Let me show you the first part of the working program.

The first 16 values in your working program are:

cffa edfe 0700 0001 0300 0080 0200 0000

cf is hexadecimal for the number 207.
fa is hex for the number 250

(See http://en.wikipedia.org/wiki/Hexadecimal for more information).

If you just cut and paste that line then you are copying a representation of that and not the actual values.

If you cut and paste those into a new file you are doing the equivalent of having an arrow in code, getting that translated into letters 'a r r o w' and copying the translation. In the process information is changed and you no longer have a working program.

What you do have is nothing more than a text file. And apparently your system falls back to trying to interpret that as a shell script when the executable bit is set but no ELF header or shebang interpreter is present.

  • interesting, you make good sense that the values that are in this new text file are not represented the same way as the values in the old file. Would there be a way to have or set an ELF header in order for this file to run? – a_real_hero Apr 29 '15 at 19:48
  • My main confusion stems from what exactly is happening with these hexadecimal numbers. I understand it all eventually boils down to binary. assembly is in there somewhere. Do you have any readings that could perhaps give a "big picture" look at how it all fits together at this lower level? again, apologies. I work in web dev and am trying to broaden my horizons – a_real_hero Apr 29 '15 at 19:49
  • to continue my question, is there a way I could have outputted that program in binary, and copied that binary to another file, and have that run? – a_real_hero Apr 29 '15 at 19:52
  • Very simplified: The CPU in your computer only understands machine code. That is written in binary patterns. These patterns are grouped (e.g. each 8 bits would be grouped as a byte and can have 256 different values. 2^8. The normal things we humans read on the screen are way less than 256 (a-z, A-Z, 0-9, etc). So it gets translated when you try to put it in human readable form. To copy it (and keep it working simply do not translate it to a human readable form or do some complicated dance to translate it back. The first is easier. – Hennes Apr 29 '15 at 19:55
  • Interesting! I know this question is just begging to be laughed at, but you are telling me, that in the grand scheme of things, a CPU is simply taking 11010110 00101001 and whatever and can determine what to do with those? (side clarification, 8bits = 1byte?) Secondly, I am going to have to read into compilers, but a compiler takes that helloworld.c program and turns it into assembly, and an assembly compiler turns it into binary? or what is the process there? by the way, THANK YOU – a_real_hero Apr 29 '15 at 20:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.