How this function call works???

J

Java Böy

could some body help me what's happening here...

thanks..

char sc[] =
"\x31\xc0" /* xor %eax, %eax */
"\x50" /* push %eax */
"\x68\x2f\x2f\x73\x68" /* push $0x68732f2f */
"\x68\x2f\x62\x69\x6e" /* push $0x6e69622f */
"\x89\xe3" /* mov %esp,%ebx */
"\x50" /* push %eax */
"\x53" /* push %ebx */
"\x89\xe1" /* mov %esp,%ecx */
"\x31\xd2" /* xor %edx,%edx */
"\xb0\x0b" /* mov $0xb,%al */
"\xcd\x80"; /* int $0x80 */

main()
{
void (*fp) (void); // what is happening at this line

fp = (void *)sc;
fp();
}
 
J

Jens Schicke

Java Böy said:
could some body help me what's happening here...

char sc[] =
"\x31\xc0" /* xor %eax, %eax */ [...]
"\xcd\x80"; /* int $0x80 */

main()
{
void (*fp) (void); // what is happening at this line

This line declares the variable fp as an pointer to an function of void
which returns void.
fp = (void *)sc;
fp();
}

Let me give you an example (hopefully) easier to understand:

#include <stdio.h>

void foo(void)
{
printf("Hallo Welt\n");
}

int main(void)
{
void (*f)(void); // declare a pointer to a function

f = foo; // assign the address of foo to the pointer f
f(); // call the function f points to -> foo

return 0;
}

The additional problem with the program given by you is that the
function is not declared as one, but as a array of chars char sc[] =...
This array is initialized with some 80x86 assembler hexcodes which end
int some linux kernel call I don't know... Hopefully it will terminate
the program for there is no return instruction in the function.

BTW: main doesn't need to be a function either :)

long long main = 0xC300000000B8; // int main(void) { return 0; }
 
J

Jack Klein

could some body help me what's happening here...

thanks..

char sc[] =
"\x31\xc0" /* xor %eax, %eax */
"\x50" /* push %eax */
"\x68\x2f\x2f\x73\x68" /* push $0x68732f2f */
"\x68\x2f\x62\x69\x6e" /* push $0x6e69622f */
"\x89\xe3" /* mov %esp,%ebx */
"\x50" /* push %eax */
"\x53" /* push %ebx */
"\x89\xe1" /* mov %esp,%ecx */
"\x31\xd2" /* xor %edx,%edx */
"\xb0\x0b" /* mov $0xb,%al */
"\xcd\x80"; /* int $0x80 */

main()

The current C standard requires that main() be defined with a return
type of int.
{
void (*fp) (void); // what is happening at this line

Defines fp to be a pointer to a function that takes no arguments and
returns nothing.
fp = (void *)sc;

This is undefined behavior. There is no cast from pointer to char to
pointer to function of any kind defined in C. At this point you do
not have a C program anymore.

Whatever happens when you attempt to call an array of characters via a
pointer to a function has nothing to do with C. On many platforms it
will just plain crash. If you want to find out what someone expected
it to do on one particular compiler, you might try asking in a group
that discusses that particular compiler.

As far as the C language is concerned, anything that happens during or
after the assignment of the array to the function pointer is just as
correct or incorrect as anything else.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
J

Jack Klein

Java Böy said:
could some body help me what's happening here...

char sc[] =
"\x31\xc0" /* xor %eax, %eax */ [...]
"\xcd\x80"; /* int $0x80 */

main()
{
void (*fp) (void); // what is happening at this line

This line declares the variable fp as an pointer to an function of void
which returns void.
fp = (void *)sc;
fp();
}

Let me give you an example (hopefully) easier to understand:

#include <stdio.h>

void foo(void)
{
printf("Hallo Welt\n");
}

int main(void)
{
void (*f)(void); // declare a pointer to a function

f = foo; // assign the address of foo to the pointer f
f(); // call the function f points to -> foo

return 0;
}

The additional problem with the program given by you is that the
function is not declared as one, but as a array of chars char sc[] =...
This array is initialized with some 80x86 assembler hexcodes which end
int some linux kernel call I don't know... Hopefully it will terminate
the program for there is no return instruction in the function.

BTW: main doesn't need to be a function either :)

We discuss the C language here. If you want to spout bullsh*t, go
somewhere else.
long long main = 0xC300000000B8; // int main(void) { return 0; }

If you think the above is C, you are brain-damaged.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
J

Jeff

Jack Klein said:
Java Böy said:
could some body help me what's happening here...

char sc[] =
"\x31\xc0" /* xor %eax, %eax */ [...]
"\xcd\x80"; /* int $0x80 */

main()
{
void (*fp) (void); // what is happening at this line

This line declares the variable fp as an pointer to an function of void
which returns void.
fp = (void *)sc;
fp();
}

Let me give you an example (hopefully) easier to understand:

#include <stdio.h>

void foo(void)
{
printf("Hallo Welt\n");
}

int main(void)
{
void (*f)(void); // declare a pointer to a function

f = foo; // assign the address of foo to the pointer f
f(); // call the function f points to -> foo

return 0;
}

The additional problem with the program given by you is that the
function is not declared as one, but as a array of chars char sc[] =...
This array is initialized with some 80x86 assembler hexcodes which end
int some linux kernel call I don't know... Hopefully it will terminate
the program for there is no return instruction in the function.

BTW: main doesn't need to be a function either :)

We discuss the C language here. If you want to spout bullsh*t, go
somewhere else.

Don't flame.
 
J

Jeff

Java Böy said:
could some body help me what's happening here...

thanks..

char sc[] =
"\x31\xc0" /* xor %eax, %eax */
"\x50" /* push %eax */
"\x68\x2f\x2f\x73\x68" /* push $0x68732f2f */
"\x68\x2f\x62\x69\x6e" /* push $0x6e69622f */
"\x89\xe3" /* mov %esp,%ebx */
"\x50" /* push %eax */
"\x53" /* push %ebx */
"\x89\xe1" /* mov %esp,%ecx */
"\x31\xd2" /* xor %edx,%edx */
"\xb0\x0b" /* mov $0xb,%al */
"\xcd\x80"; /* int $0x80 */

Assembly code is platform specific, you can ask in somewhere talking about
assembly programming and they will give you the great idea about what it
dose.
main()
{
void (*fp) (void); // what is happening at this line

fp is "pointer of function" which return void and take no parameter.
 
D

Dan Pop

could some body help me what's happening here...

char sc[] =
"\x31\xc0" /* xor %eax, %eax */
"\x50" /* push %eax */
"\x68\x2f\x2f\x73\x68" /* push $0x68732f2f */
"\x68\x2f\x62\x69\x6e" /* push $0x6e69622f */
"\x89\xe3" /* mov %esp,%ebx */
"\x50" /* push %eax */
"\x53" /* push %ebx */
"\x89\xe1" /* mov %esp,%ecx */
"\x31\xd2" /* xor %edx,%edx */
"\xb0\x0b" /* mov $0xb,%al */
"\xcd\x80"; /* int $0x80 */

main()
{
void (*fp) (void); // what is happening at this line

fp = (void *)sc;
fp();
}

Did you actually try to compile this piece of shit as a C program?
After removing the // comment, this is what I get:

fangorn:~/tmp 2075> gcc -ansi -pedantic test.c
test.c: In function `main':
test.c:18: warning: ANSI forbids assignment between function pointer and `void *'
fangorn:~/tmp 2076> icc test.c
test.c
test.c(18): warning #556: a value of type "void *" cannot be assigned to an entity of type "void (*)(void)"
fp = (void *)sc;
^
So, what could you expect from this program?

Dan
 
D

Dan Pop

In said:
could some body help me what's happening here...

thanks..

char sc[] =
"\x31\xc0" /* xor %eax, %eax */
"\x50" /* push %eax */
"\x68\x2f\x2f\x73\x68" /* push $0x68732f2f */
"\x68\x2f\x62\x69\x6e" /* push $0x6e69622f */
"\x89\xe3" /* mov %esp,%ebx */
"\x50" /* push %eax */
"\x53" /* push %ebx */
"\x89\xe1" /* mov %esp,%ecx */
"\x31\xd2" /* xor %edx,%edx */
"\xb0\x0b" /* mov $0xb,%al */
"\xcd\x80"; /* int $0x80 */

main()

The current C standard requires that main() be defined with a return
type of int.

And, pray tell, what is the return type of main in this program?
Defines fp to be a pointer to a function that takes no arguments and
returns nothing.


This is undefined behavior.
Wrong!

There is no cast from pointer to char to
pointer to function of any kind defined in C.

No such cast is used in this program, either. I can only see a cast
from char pointer to void pointer, which is perfectly OK.

I can also see a constraint violation, in the attempt to assing a void
pointer to a function pointer and this is NOT undefined behaviour: a
diagnostic is required.
At this point you do not have a C program anymore.

I'm afraid that this piece of junk still qualifies as a conforming C
program. Otherwise he wouldn't have posted it here.

Dan
 
G

goose

Java Böy said:
could some body help me what's happening here...

i'll try
thanks..

char sc[] =
"\x31\xc0" /* xor %eax, %eax */
"\x50" /* push %eax */
"\x68\x2f\x2f\x73\x68" /* push $0x68732f2f */
"\x68\x2f\x62\x69\x6e" /* push $0x6e69622f */
"\x89\xe3" /* mov %esp,%ebx */
"\x50" /* push %eax */
"\x53" /* push %ebx */
"\x89\xe1" /* mov %esp,%ecx */
"\x31\xd2" /* xor %edx,%edx */
"\xb0\x0b" /* mov $0xb,%al */
"\xcd\x80"; /* int $0x80 */

this declares an array of char

int main (void)
{
void (*fp) (void); // what is happening at this line

fp is declared as a pointer to a function returning void
and taking no arguments.
fp = (void *)sc;

this is rather stupidly assigning a pointer to char to a pointer
to a function returning void and taking no arguments.

I think that this might even be undefined behaviour.

and if it isn't, then this almost definitely is.


imho, this piece of code is probably some programmers crappy attempt
at job security. why not just call the function ????

goose,
 
D

Dan Pop

Java Böy said:
could some body help me what's happening here...

thanks..

char sc[] =
"\x31\xc0" /* xor %eax, %eax */
"\x50" /* push %eax */
"\x68\x2f\x2f\x73\x68" /* push $0x68732f2f */
"\x68\x2f\x62\x69\x6e" /* push $0x6e69622f */
"\x89\xe3" /* mov %esp,%ebx */
"\x50" /* push %eax */
"\x53" /* push %ebx */
"\x89\xe1" /* mov %esp,%ecx */
"\x31\xd2" /* xor %edx,%edx */
"\xb0\x0b" /* mov $0xb,%al */
"\xcd\x80"; /* int $0x80 */

main()
{
void (*fp) (void); // what is happening at this line

fp = (void *)sc;
fp();
}
Just for your information, I think your code (including the assembly part) *is not illegal* in C,
in fact

From ISO/IEC 9899:1999

Do you have the slightest clue about the connection between J.5 and the
normative part of the C99 standard?
1 A pointer to an object or to void may be cast to a pointer to a function, allowing data to
be invoked as a function (6.5.4).

Where can you see such a cast in the OP's code? Are you visually impaired
or merely a patent idiot?
From line 1 "allowing data to be invoked as a function"

What about it?

And what about the following quote from the *normative* part of the same
standard:

6.5.16.1 Simple assignment

Constraints

1 One of the following shall hold:93)

- the left operand has qualified or unqualified arithmetic type
and the right has arithmetic type;

- the left operand has a qualified or unqualified version of a
structure or union type compatible with the type of the right;

- both operands are pointers to qualified or unqualified versions
of compatible types, and the type pointed to by the left has
all the qualifiers of the type pointed to by the right;

- one operand is a pointer to an object or incomplete type and
the other is a pointer to a qualified or unqualified version
of void, and the type pointed to by the left has all the
qualifiers of the type pointed to by the right;

- the left operand is a pointer and the right is a null pointer
constant; or

- the left operand has type _Bool and the right is a pointer.

Which of these alternatives is matched by fp = (void *)sc; ?
Any idea about what happens when a constraint is violated?

If the line in question was:

fp = (void(*)(void))sc; /* no 6.5.16.1 constraint violation */

the code would have invoked undefined behaviour and the quote from J.5.7
would have explained why such code *may* work on *certain*
implementations (still without giving it *any* legitimation).

It doesn't hurt to get a clue before posting irrelevant quotes from the
standard!

Dan
 
J

Jeff

Dan Pop said:
Java Böy said:
could some body help me what's happening here...

thanks..

char sc[] =
"\x31\xc0" /* xor %eax, %eax */
"\x50" /* push %eax */
"\x68\x2f\x2f\x73\x68" /* push $0x68732f2f */
"\x68\x2f\x62\x69\x6e" /* push $0x6e69622f */
"\x89\xe3" /* mov %esp,%ebx */
"\x50" /* push %eax */
"\x53" /* push %ebx */
"\x89\xe1" /* mov %esp,%ecx */
"\x31\xd2" /* xor %edx,%edx */
"\xb0\x0b" /* mov $0xb,%al */
"\xcd\x80"; /* int $0x80 */

main()
{
void (*fp) (void); // what is happening at this line

fp = (void *)sc;
fp();
}
Just for your information, I think your code (including the assembly part) *is not illegal* in C,
in fact

From ISO/IEC 9899:1999

Do you have the slightest clue about the connection between J.5 and the
normative part of the C99 standard?
1 A pointer to an object or to void may be cast to a pointer to a function, allowing data to
be invoked as a function (6.5.4).

Where can you see such a cast in the OP's code? Are you visually impaired
or merely a patent idiot?
From line 1 "allowing data to be invoked as a function"

What about it?

And what about the following quote from the *normative* part of the same
standard:

6.5.16.1 Simple assignment

Constraints

1 One of the following shall hold:93)

- the left operand has qualified or unqualified arithmetic type
and the right has arithmetic type;

- the left operand has a qualified or unqualified version of a
structure or union type compatible with the type of the right;

- both operands are pointers to qualified or unqualified versions
of compatible types, and the type pointed to by the left has
all the qualifiers of the type pointed to by the right;

- one operand is a pointer to an object or incomplete type and
the other is a pointer to a qualified or unqualified version
of void, and the type pointed to by the left has all the
qualifiers of the type pointed to by the right;

- the left operand is a pointer and the right is a null pointer
constant; or

- the left operand has type _Bool and the right is a pointer.

Which of these alternatives is matched by fp = (void *)sc; ?
Any idea about what happens when a constraint is violated?

If the line in question was:

fp = (void(*)(void))sc; /* no 6.5.16.1 constraint violation */

the code would have invoked undefined behaviour and the quote from J.5.7
would have explained why such code *may* work on *certain*
implementations (still without giving it *any* legitimation).

It doesn't hurt to get a clue before posting irrelevant quotes from the
standard!

Dan

I understand what is the problem. Thank you for your explanation.
 
D

Derk Gwen

#
#
# could some body help me what's happening here...
#
# char sc[] =
# "\x31\xc0" /* xor %eax, %eax */
# "\x50" /* push %eax */
# "\x68\x2f\x2f\x73\x68" /* push $0x68732f2f */
# "\x68\x2f\x62\x69\x6e" /* push $0x6e69622f */
# "\x89\xe3" /* mov %esp,%ebx */
# "\x50" /* push %eax */
# "\x53" /* push %ebx */
# "\x89\xe1" /* mov %esp,%ecx */
# "\x31\xd2" /* xor %edx,%edx */
# "\xb0\x0b" /* mov $0xb,%al */
# "\xcd\x80"; /* int $0x80 */
#
# main()
# {
# void (*fp) (void); // what is happening at this line
#
# fp = (void *)sc;
# fp();
# }

It's a hand-coded system or bios interrupt call. You can probably
get more information about the call from an intel newsgroup.
Rather than use some kind 'asm' insert or separate assembly file,
someone figured out all the opcodes and inserted them into the
char array. The data pointer to this is forced into a code pointer
and then the code is executed with a function call mechanism.

The code is, of course, machine specific. And to some degree so
is converting a data pointer to a code pointer: on some machines
they are very different creatures.
 
C

Chris Torek

It's a hand-coded system or bios interrupt call. You can probably
get more information about the call from an intel newsgroup. ...
The code is, of course, machine specific. And to some degree so
is converting a data pointer to a code pointer: on some machines
they are very different creatures.

Oddly enough, one of those machines is the very machine for which
it is written: the Intel IA32.

If the CPU's registers were set up so as to deter certain forms of
viruses, the code would not work at all. Fortunately for the
original author, however, most people prefer to get the wrong
answer as fast as possible. :)
 
X

Xenos

Why is everyone in these newsgroups so friggin nasty and mean? This is why
usenet has gone to crap and it is now virtually useless as a mechanism for a
newby to get any kind of help.


Dan Pop said:
could some body help me what's happening here...

thanks..

char sc[] =
"\x31\xc0" /* xor %eax, %eax */
"\x50" /* push %eax */
"\x68\x2f\x2f\x73\x68" /* push $0x68732f2f */
"\x68\x2f\x62\x69\x6e" /* push $0x6e69622f */
"\x89\xe3" /* mov %esp,%ebx */
"\x50" /* push %eax */
"\x53" /* push %ebx */
"\x89\xe1" /* mov %esp,%ecx */
"\x31\xd2" /* xor %edx,%edx */
"\xb0\x0b" /* mov $0xb,%al */
"\xcd\x80"; /* int $0x80 */

main()
{
void (*fp) (void); // what is happening at this line

fp = (void *)sc;
fp();
}
Just for your information, I think your code (including the assembly part) *is not illegal* in C,
in fact

From ISO/IEC 9899:1999

Do you have the slightest clue about the connection between J.5 and the
normative part of the C99 standard?
1 A pointer to an object or to void may be cast to a pointer to a function, allowing data to
be invoked as a function (6.5.4).

Where can you see such a cast in the OP's code? Are you visually impaired
or merely a patent idiot?
From line 1 "allowing data to be invoked as a function"

What about it?

And what about the following quote from the *normative* part of the same
standard:

6.5.16.1 Simple assignment

Constraints

1 One of the following shall hold:93)

- the left operand has qualified or unqualified arithmetic type
and the right has arithmetic type;

- the left operand has a qualified or unqualified version of a
structure or union type compatible with the type of the right;

- both operands are pointers to qualified or unqualified versions
of compatible types, and the type pointed to by the left has
all the qualifiers of the type pointed to by the right;

- one operand is a pointer to an object or incomplete type and
the other is a pointer to a qualified or unqualified version
of void, and the type pointed to by the left has all the
qualifiers of the type pointed to by the right;

- the left operand is a pointer and the right is a null pointer
constant; or

- the left operand has type _Bool and the right is a pointer.

Which of these alternatives is matched by fp = (void *)sc; ?
Any idea about what happens when a constraint is violated?

If the line in question was:

fp = (void(*)(void))sc; /* no 6.5.16.1 constraint violation */

the code would have invoked undefined behaviour and the quote from J.5.7
would have explained why such code *may* work on *certain*
implementations (still without giving it *any* legitimation).

It doesn't hurt to get a clue before posting irrelevant quotes from the
standard!

Dan
 
J

Joona I Palaste

Xenos said:
Why is everyone in these newsgroups so friggin nasty and mean? This is why
usenet has gone to crap and it is now virtually useless as a mechanism for a
newby to get any kind of help.

1) That's Dan Pop. He's the nastiest guy around here. We others are
a little friendlier. A *little*.
2) Don't top-post, please. And try to trim quotes.
3) We have to be nasty sometimes to preserve proper topicality.

(snip a very long bit of text that Xenos didn't bother to comment on,
but felt it was worth it to include nonetheless)

(snip Dan Pop's signature, which is merely superfluous baggage in quoted
replies)

--
/-- Joona Palaste ([email protected]) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"That's no raisin - it's an ALIEN!"
- Tourist in MTV's Oddities
 
J

Joona I Palaste

You don't feel it's possible to preserve topicality pleasantly?

I did say "sometimes".

--
/-- Joona Palaste ([email protected]) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"As we all know, the hardware for the PC is great, but the software sucks."
- Petro Tyschtschenko
 
C

Chris Dollin

Xenos wrote:

[WRT one of Dab Pop's replies]
Why is everyone in these newsgroups so friggin nasty and mean?

Why is the sun made of green cheese?

Not everyone here is "friggin nasty and mean", despite the temptations.
This is
why usenet has gone to crap and it is now virtually useless as a mechanism
for a newby to get any kind of help.

Well, I disagree. Places in usenet also turn to crap because conversations
are allowed to stray arbitrarily off-topic, core competance gets lost,
and the noise dominates the signal. For a technical newsgroup, this is
even *less* helpful to newbies.

Dan's reply was his normal model of politeness and decorum, but Dan
is not "everyone", and his technical content, if he's not furiously
trying to wriggle out of a corner or taking a joke too seriously [1],
is bang-on. Given that newsgroups are exchange-of-text, not face-to-face,
I'd rather have accurate information than not.

[1] That's my reading; it's *only* my opinion.
 
D

Derk Gwen

# Why is everyone in these newsgroups so friggin nasty and mean?

"Assholes do vex me"
Robin Williams
 
D

Dan Pop

In said:
# cat foo.c
int main = 0xC3C031;
# gcc -W -Wall -pedantic -ansi foo.c
foo.c:1: warning: `main' is usually a function
#

To me it looks like valid ansi-C,

If it's valid ANSI C, please explain to the rest of us its meaning,
according to the ANSI C standard. What can I expect from this program
when running it on a SPARC/Solaris or POWER/AIX system?

Let's see:

mentor:~/tmp 8> uname -a
SunOS mentor 5.8 Generic_108528-11 sun4u sparc
mentor:~/tmp 9> cat test.c
int main = 0xC3C031;
mentor:~/tmp 10> gcc -Wall test.c
test.c:1: warning: `main' is usually a function
mentor:~/tmp 11> ./a.out
Illegal instruction (core dumped)
at least the gcc thinks of it as such...

On the contrary, gcc has clearly expressed its doubts.

Dan
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top