• Welcome to Valhalla Legends Archive.
 

Basic function call

Started by FrostWraith, January 17, 2008, 11:33 AM

Previous topic - Next topic

FrostWraith

So I have been studying up on x86 asm lately and have been using Visual Studio to compile it, since I am planning to use both C and asm together.  There really is no reason for me doing this other than from a learning perspective.  I decided I wanted to make a printf call in asm.  I tried my own code and Microsofts example of this and it just will not work.  It crashes every time.  When i debug, it breaks at the first "pop ebx".  If anyone could show me what I am doing wrong, and not telling me to change compilers because this is for school,  that would be great!
#include <stdio.h>

char format[] = "%s %s\n";
char hello[] = "Hello";
char world[] = "world";

int main(void)
{
   __asm
   {
      mov  eax, offset world
      push eax
      mov  eax, offset hello
      push eax
      mov  eax, offset format
      push eax
      call printf
      //clean up the stack so that main can exit cleanly
      //use the unused register ebx to do the cleanup
      pop  ebx
      pop  ebx
      pop  ebx
   }
}

brew

What version of visual studio are you using? Are you sure that ebx is unused? Try replacing those last three pops with add esp, 12.
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

FrostWraith

#2
I've tried on both VS 2005 and 2008.  Your suggestions doesn't work either.  Should I try setting ebx to zero when starting?

Heres what I get in debug:
First-chance exception at 0x004182bc in test.exe: 0xC0000005: Access violation writing location 0x00001024.
Unhandled exception at 0x004182bc in test.exe: 0xC0000005: Access violation writing location 0x00001024.

which naturally is the call to printf
__imp__printf:
004182BC  adc         byte ptr [edx+1023h],bl

UserLoser

pop ebx x 3 doesnt look right to me, how can you pop it if you never pushed it

brew

#4
Quote from: UserLoser on January 17, 2008, 01:22 PM
pop ebx x 3 doesnt look right to me, how can you pop it if you never pushed it
hes cleaning up his stack from the call to printf.. or are you just trying to troll?

frostwraith: setting edx to zero isn't going to help a bit, see how it's adding an offset to edx and getting what's at that location? look:
Quote
Access violation writing location 0x00001024.
the call itself looks perfectly fine. And it works perfect for me (I use MSVC6).
edx was obviously 1 at the time of calling.
That line of code that is right under the label __imp__printf doesn't look quite right, for a few reasons:
1. If it were valid, it should have been push ebp
2. How on earth could a function assume a value already in a register, unless it's __fastcall? And I know it isn't.
3. adc byte ptr [edx + 1023h], bl... that's somewhat random. maybe if it were a mov, and part of a loop, that'd make more sense. but it just isn't.
4. that instruction is exactly 4 bytes long

My conclusion:
printf is dynamically linked. when you call printf, you're calling that label. it just so happens that there aren't any valid instructions at that label, but instead the address to the real printf.
Solution: try call dword ptr [printf]
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

FrostWraith

Thanks a lot!  That did the trick.  I do understand why that works now, but am unsure why the original code failed.

brew

Quote from: FrostWraith on January 17, 2008, 03:21 PM
Thanks a lot!  That did the trick.  I do understand why that works now, but am unsure why the original code failed.
Because your linker uses the slower but simpler method of putting printf's address in a call table, and filling in the addresses later. MSVC6 knows exactly where printf is at the time it compiled, so the raw printf call works just fine. Not so with your compiler.
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

FrostWraith

Well you would think that even in Visual Studio 2008 that Microsoft would have been able to think of this.  But once again, lets not get into a flame war about MS.

Kp

Quote from: brew on January 17, 2008, 02:55 PM
Quote from: UserLoser on January 17, 2008, 01:22 PM
pop ebx x 3 doesnt look right to me, how can you pop it if you never pushed it
hes cleaning up his stack from the call to printf.. or are you just trying to troll?

UserLoser was trying to put him on the right track.  Do you know what happens when you overwrite ebx in an assembly block?
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

brew

Quote from: Kp on January 17, 2008, 06:38 PM
Quote from: brew on January 17, 2008, 02:55 PM
Quote from: UserLoser on January 17, 2008, 01:22 PM
pop ebx x 3 doesnt look right to me, how can you pop it if you never pushed it
hes cleaning up his stack from the call to printf.. or are you just trying to troll?

UserLoser was trying to put him on the right track.  Do you know what happens when you overwrite ebx in an assembly block?
Sure, overwriting ebx is not a very good idea, but IIRC the compiler does save the value of ebx and/or accommodates the rest of the code for its modification across that function. Blame whoever put that assembly on msdn :P
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

UserLoser

Quote from: brew on January 17, 2008, 02:55 PM
Quote from: UserLoser on January 17, 2008, 01:22 PM
pop ebx x 3 doesnt look right to me, how can you pop it if you never pushed it
hes cleaning up his stack from the call to printf.. or are you just trying to troll?

don't reply to my posts, thanks.

brew

Quote from: UserLoser on January 19, 2008, 01:59 AM
don't reply to my posts, thanks.
ha ha ha ha
i just replied to your post. again.
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P