Search code examples
cstringasprintf

asprintf - how to get string input in C


I am reading the book "21 century C" (first editon) and find a interesting program using asprintf to get the string without using malloc /size of for string length or space allocation. Please read the attached image from the same book to understand the context.Following program also from book. The program compile run and NOT taking string input from keyboard instead getting following message. Question is : Why the program doesn't take string input from keboard instead the showing long (unusual) error message?

#define _GNU_SOURCE  // stdio.h to include asprintf
#include <stdlib.h>
#include <stdio.h>

void get_strings(char const *in) {
    char *cmd;
    asprintf(&cmd, "strings %s", in);
    if (system(cmd))
        fprintf(stderr, "Something went Wrong  %s.\n", cmd);
    free(cmd);
} 

int main(int argc, char **argv) {
    get_strings(argv[0]);   
    //return 0;
}

When the run the program the output is :

/lib64/ld-linux-x86-64.so.2
libc.so.6
__stack_chk_fail
asprintf
stderr
system
fprintf
__libc_start_main
free
__gmon_start__
GLIBC_2.4
GLIBC_2.2.5
UH-X
AWAVA
AUATL
[]A\A]A^A_
strings %s
Something  went Wrong  %s.
;*3$"
GCC: (Ubuntu 5.3.1-14ubuntu2) 5.3.1 20160413
crtstuff.c
__JCR_LIST__
deregister_tm_clones
__do_global_dtors_aux
completed.7585
__do_global_dtors_aux_fini_array_entry
frame_dummy
__frame_dummy_init_array_entry
get_strings.c
__FRAME_END__
__JCR_END__
__init_array_end
_DYNAMIC
__init_array_start
__GNU_EH_FRAME_HDR
_GLOBAL_OFFSET_TABLE_
__libc_csu_fini
free@@GLIBC_2.2.5
_ITM_deregisterTMCloneTable
_edata
__stack_chk_fail@@GLIBC_2.4
system@@GLIBC_2.2.5
get_strings
__libc_start_main@@GLIBC_2.2.5
__data_start
fprintf@@GLIBC_2.2.5
__gmon_start__
__dso_handle
_IO_stdin_used
__libc_csu_init
__bss_start
asprintf@@GLIBC_2.2.5
main
_Jv_RegisterClasses
__TMC_END__
_ITM_registerTMCloneTable
stderr@@GLIBC_2.2.5
.symtab
.strtab
.shstrtab
.interp
.note.ABI-tag
.note.gnu.build-id
.gnu.hash
.dynsym
.dynstr
.gnu.version
.gnu.version_r
.rela.dyn
.rela.plt
.init
.plt.got
.text
.fini
.rodata
.eh_frame_hdr
.eh_frame
.init_array
.fini_array
.jcr
.dynamic
.got.plt
.data
.bss
.comment


------------------
(program exited with code: 0)
Press return to continue

**I running it on Linux Mint 18. GCC version -5.3.1
Build setting - gcc -Wall   -c "%f"
Compile -       gcc -Wall   -o "%e"   "%f"**

enter image description here


Solution

  • The purpose of the program is not to get input from the user: it uses the system() function to run the strings program with its own name as the only argument.

    If you are running on a Unix environment, the strings program scans files for printable strings. The output you observe is more of less expected: your program executable as produced by gcc contains many printable strings:

    • you can spot the string literal present in the source code: Something went Wrong %s.
    • numerous symbol names to be resolved dynamically at load time
    • debugging information, such as the name of the source file: crtstuff.c
    • section names starting with .
    • there are also some random items ([]A\A]A^A_, ;*3$"...) that are just sequences of printable characters present in the executable file code or binary data, mistakenly interpreted by string as C strings because they are followed by a null byte.