Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where are the null-terminated strings when converting from C to assembly?

Tags:

c

linux

x86

gcc

I made two programs to output two strings, one in assembly and the other one in C. This is the program in assembly:

.section .data
string1:
.ascii "Hola\0"
string2:
.ascii "Adios\0"

.section .text
.globl _start
_start:

pushl $string1
call puts
addl $4, %esp

pushl $string2
call puts
addl $4, %esp

movl $1, %eax
movl $0, %ebx
int $0x80

I build the program with

as test.s -o test.o
ld -dynamic-linker /lib/ld-linux.so.2 -o test test.o -lc

And the output is as expected

Hola
Adios

This is the C program:

#include <stdio.h>
int main(void)
{
    puts("Hola");
    puts("Adios");
    return 0;
}

And I get the expected output, but when converting this C program to assembly with gcc -S (OS is Debian 32 bit) the output assembly source code does not include the null character in both strings, as you can see here:

    .file   "testc.c"
    .section    .rodata
.LC0:
    .string "Hola"
.LC1:
    .string "Adios"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    leal    4(%esp), %ecx
    .cfi_def_cfa 1, 0
    andl    $-16, %esp
    pushl   -4(%ecx)
    pushl   %ebp
    .cfi_escape 0x10,0x5,0x2,0x75,0
    movl    %esp, %ebp
    pushl   %ecx
    .cfi_escape 0xf,0x3,0x75,0x7c,0x6
    subl    $4, %esp
    subl    $12, %esp
    pushl   $.LC0
    call    puts
    addl    $16, %esp
    subl    $12, %esp
    pushl   $.LC1
    call    puts
    addl    $16, %esp
    movl    $0, %eax
    movl    -4(%ebp), %ecx
    .cfi_def_cfa 1, 0
    leave
    .cfi_restore 5
    leal    -4(%ecx), %esp
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Debian 4.9.2-10) 4.9.2"
    .section    .note.GNU-stack,"",@progbits

My two questions are:

1) Why the gcc generated assembly code does not append the null character at the end of both strings? I thought that C did this automatically.

2) If I skip the null characters in my hand made assembly code i get this output:

HolaAdios
Adios

I understand why I get the "HolaAdios" part at the first line, but why does the program end successfully after the "Adios" part if it is not null-terminated?

like image 385
saga.x Avatar asked Aug 09 '16 11:08

saga.x


1 Answers

  1. .string always appends a null terminator, as seen here.
  2. Well, you can check it yourself. puts just continues until it sees a null byte. \x00s are very common, there must be one nearby so it works (probably due to section alignment of .rodata).
like image 152
Armitage.apk Avatar answered Nov 15 '22 18:11

Armitage.apk