views:

53

answers:

3

how can i write a string (eg. "Hello") to stdout from the stack? without, data-segments, that is.

void main() {
    __asm__(
                "movl  $0x4, %eax   \n\t"
                "movl  $0x1, %ebx   \n\t"
            //   put "Hello" on the stack and load its address into %ecx
                "movl  $0x5, %edx   \n\t"
                "int   $0x80        \n\t"

                "movl  $0x1, %eax   \n\t"
                "movl  $0x0, %ebx   \n\t"
                "int   $0x80        \n\t"
             );
}

thanks in advance

A: 
int main() {
        char *hello = "Hello world!\n";
        __asm__("\
                movl $4, %%eax\n\
                movl $0, %%ebx\n\
                push %0\n\
                pop %%ecx\n\
                movl $13,%%edx\n\
                int $0x80" : :"g"(hello));
        return 0;
}

I don't understand the stack part. Why dont't use `movl %0,%%ecx'?

Victor Marzo
because i don't want the string to be stored in one of the data segments, but rather have it right on the stack. it's pretty much an academic question.
guest
A: 

how can i write a string (eg. "Hello") to stdout from the stack? without, data-segments, that is.

Something along the lines:

  1. Allocate buffer on stack, say 8 bytes. (Check how GCC alloca() does that.)
  2. Create the string in the buffer. "Hello" bytewise is 48 65 6c 6c 6f 00 00 00 (aligned, padded with zeros). The two 32bit constants - 0x6c6c6548 and 0x0000006f - should suffice to represent the string.
  3. Pass the address of the buffer to the write syscall.
  4. Restore the stack pointer where it was before (if needed).

Can't be more precise as I'm not very up-to-date on the GCC inline asm and x86 ABI.

Dummy00001
thanks for the tip with `alloca()`! seems to be exactly what i was looking for. just wondering, though, what would be the best way to get the string into the stack? currently i'm doing something like `*(p+0) = 'H'; *(p+1) = 'e'; etc..`.
guest
@gues: Why bytes? As I wrote above, you can use 32bit constants with the `mov` to fill the buffer (do not have 32bit system to peek the proper syntax). To generate constants one can use command like that: `echo -n Hello | od -t x4`.
Dummy00001
+2  A: 

Answer 1:

int main()
{
    const char* string = "hello";  // string is not in a data segment, it's in the text segment
    fputs(string, stdout);
    return 0;
}

Answer 2:

int main()
{
    char[6] string = "hello";  // Space for string allocated on stack
    fputs(string, stdout);
    return 0;
}

With gcc the second answer seems to generate the following:

main:      
    leal    4(%esp), %ecx
    andl    $-16, %esp
    pushl   -4(%ecx)
    pushl   %ebp
    movl    %esp, %ebp
    pushl   %ecx
    subl    $36, %esp
    movl    $1819043176, -10(%ebp) ;<< hell
    movw    $111, -6(%ebp)         ;<< o\0
    movl    stdout, %eax
    movl    %eax, 4(%esp)
    leal    -10(%ebp), %eax
    movl    %eax, (%esp)
    call    fputs
    movl    $0, %eax
    addl    $36, %esp
    popl    %ecx
    popl    %ebp
    leal    -4(%ecx), %esp

which clearly only uses the stack.

JeremyP