User avatar
RaspbianUser1
Posts: 841
Joined: Thu Mar 05, 2020 6:34 pm
Location: ~/

Re: [solved]Reading command inputted

Fri May 07, 2021 8:37 pm

Interesting list, these are programming concepts which need to be stopped I assume

thanks for them
Running with a Raspberry Pi 4B 4GB with Raspberry Pi OS with MATE Desktop
Why not overclock, push some more performance out of your computer!
Think before you delete something a stranger on the internet told you to.

User avatar
jahboater
Posts: 7034
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: [solved]Reading command inputted

Fri May 07, 2021 9:06 pm

RaspbianUser1 wrote:
Fri May 07, 2021 8:04 pm
I am aware of that but wanted to create a c version,
That's a good idea, and very educational.

All this talk of buffers and concatenating strings. There is no need for it.

You are concatenating all the arguments and then passing the string to system() - and then your program exits.
Which will unpick them again and create a new argv "edge vector" to pass to the program which is crazy.
Kind of slow, and you have all the nitpickers complaining about buffer allocation etc.
Furthermore, it creates two more processes (a shell and the new program).

Instead of system() you could call execv() instead, and simply pass "argv" directly to it.
Something like this should do it:

Code: Select all

execv( argv[1], argv + 2 );
See "man execv"

Much much faster, no extra processes created, and no messing with argv concatenation .....
(exec replaces the current process with the new process).

Note, do check that argc is > 2, if not simply return.

User avatar
RaspbianUser1
Posts: 841
Joined: Thu Mar 05, 2020 6:34 pm
Location: ~/

Re: [solved]Reading command inputted

Fri May 07, 2021 9:20 pm

Ill look into it, however will my current method be faster than using a bash script to do the same thing
Running with a Raspberry Pi 4B 4GB with Raspberry Pi OS with MATE Desktop
Why not overclock, push some more performance out of your computer!
Think before you delete something a stranger on the internet told you to.

Heater
Posts: 18199
Joined: Tue Jul 17, 2012 3:02 pm

Re: [solved]Reading command inputted

Fri May 07, 2021 9:26 pm

RaspbianUser1 wrote:
Fri May 07, 2021 8:37 pm
Interesting list, these are programming concepts which need to be stopped I assume
That is best. If your program runs into doing any of those bad things will happen:
1) The program immediately crashes
2) The program immediately produces wrong results.
3) The program produces correct results and continues only to crash some time later.
4) The program produces correct results and continues only to cause the results of your code to be wrong some time later.
5) You never see your program produce wrong results or crash. But some cunning black hat hacker finds where your code can go wrong and contrives input to make it so so for their advantage. An "exploit". Which you might never know about until bad things are going on.

Or some variation of all of the above. Often hard to debug. The best outcome would be 1). If you are lucky.

What to do:
1) Write your C code very carefully and bear in mind these possible mistakes all along the way.
2) Have your compiler issue as many warnings as possible. Using "-Wall" is the minimum. I'll leave it to others to suggest further warning options. Be sure your code compiles with no warnings.
3) Use tools like "address sanitiser", "memory sanitiser", "thread sanitiser", "valgrind" to check your code for possible undefined behaviour.

Or give up on this can of worms and program in Rust. But that is another story...
Memory in C++ is a leaky abstraction .

User avatar
jahboater
Posts: 7034
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: [solved]Reading command inputted

Fri May 07, 2021 9:34 pm

Heater wrote:
Fri May 07, 2021 9:26 pm
If your program runs into doing any of those bad things will happen:
1) The program immediately crashes
2) The program immediately produces wrong results.
3) The program produces correct results and continues only to crash some time later.
4) The program produces correct results and continues only to cause the results of your code to be wrong some time later.
5) You never see your program produce wrong results or crash. But some cunning black hat hacker finds where your code can go wrong and contrives input to make it so so for their advantage. An "exploit". Which you might never know about until bad things are going on.
You forgot the nasal daemons .....

User avatar
manu2007
Posts: 36
Joined: Fri Apr 02, 2021 1:13 pm

Re: [solved]Reading command inputted

Fri May 07, 2021 9:35 pm

RaspbianUser1 wrote:
Fri May 07, 2021 7:41 pm

Code: Select all

#include <stdlib.h>
#include <string.h>
char command[4096];
int main(int argc, char **argv)
{
for (int i=1; i<argc; i++){
    strcat(strcat(command,argv[i])," ");
    
}
command[strlen(command) - 1] = '\0';

system(command);
}
that is the full program
If you run it without arguments, you'll have some troubles since the command buffer is not initialized.

After declaration you need to put an empty string in it like so ::

Code: Select all

char command[4096];
command[0] = '\0';
Because, if there is no arguments given, you won't enter the for loop and then "strlen(command)" will crash.

User avatar
jahboater
Posts: 7034
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: [solved]Reading command inputted

Fri May 07, 2021 10:05 pm

RaspbianUser1 wrote:
Fri May 07, 2021 9:20 pm
however will my current method be faster than using a bash script to do the same thing
I would guess it would be similar.
Note you can do

Code: Select all

exec $@
in bash too.

System() is very slow. It starts a shell process to interpret the command line (unpicking the string again into another argv :))
Then it starts the new program and waits for it to finish.

User avatar
RaspbianUser1
Posts: 841
Joined: Thu Mar 05, 2020 6:34 pm
Location: ~/

Re: [solved]Reading command inputted

Fri May 07, 2021 10:07 pm

I will implement this however, just running the binary does nothing

Doesn’t return anything

My make file turns the binary into a file called ./$ which is moved to /usr/bin
Running with a Raspberry Pi 4B 4GB with Raspberry Pi OS with MATE Desktop
Why not overclock, push some more performance out of your computer!
Think before you delete something a stranger on the internet told you to.

User avatar
jahboater
Posts: 7034
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: [solved]Reading command inputted

Fri May 07, 2021 10:21 pm

I suggest the shell script "exec $@" which works better than the C one.
Forget make!

Simply create a file called "run" by typing:

Code: Select all

echo 'exec $@' >run
Then make it executable by typing:

Code: Select all

chmod +x run
All done!

Try it by typing:

Code: Select all

./run ls -x
for example.

You may copy the little file "run" into ~/bin or somewhere on your path, so that you don't have to keep adding ./ in front of it.

As a little optimization, bash is huge. You don't need anything that powerful, so use the shell called "dash" instead which is smaller and faster. Add the line #!/bin/dash to the start of your "run" file.

User avatar
RaspbianUser1
Posts: 841
Joined: Thu Mar 05, 2020 6:34 pm
Location: ~/

Re: [solved]Reading command inputted

Fri May 07, 2021 10:41 pm

The purpose of the code is to remove $ in commands...

I didn't want a shell version and I still don't, however thanks for the input :)
Running with a Raspberry Pi 4B 4GB with Raspberry Pi OS with MATE Desktop
Why not overclock, push some more performance out of your computer!
Think before you delete something a stranger on the internet told you to.

User avatar
jahboater
Posts: 7034
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: [solved]Reading command inputted

Fri May 07, 2021 10:46 pm

RaspbianUser1 wrote:
Fri May 07, 2021 10:41 pm
The purpose of the code is to remove $ in commands...
Can you give some examples?
I mean examples of what the user would give and what should actually be executed.

It doesn't sound the same as

for( int i = 1; i < argc; ++i )

where it simply skips the first argument.

User avatar
RaspbianUser1
Posts: 841
Joined: Thu Mar 05, 2020 6:34 pm
Location: ~/

Re: [solved]Reading command inputted

Fri May 07, 2021 10:55 pm

Ok, this code aims to remove the $ from the start of commands, throughout this I have mentioned ./a.out however replace that with $ (./$)
then that file is moved to /usr/bin then whenever the user enters a command that starts with $, the $ is removed since it is argc[0]

Take a look at https://opensource.com/article/20/4/in ... thon-linux
then look at the listed commands, they have a $ before them to indicate shell but instead they often just become an annoyance when copying the commands

PS:Ignore the topic, just needed to search for a guide


Edit:

Bash wants the command

sudo apt update

not

$ sudo apt update
Running with a Raspberry Pi 4B 4GB with Raspberry Pi OS with MATE Desktop
Why not overclock, push some more performance out of your computer!
Think before you delete something a stranger on the internet told you to.

GlowInTheDark
Posts: 1713
Joined: Sat Nov 09, 2019 12:14 pm

Re: [solved]Reading command inputted

Fri May 07, 2021 11:00 pm

Code: Select all

awk 'sub(/^\$ */,"") 1' file > newfile
GitD's list of things that are not ready for prime time:
1) IPv6
2) 64 bit OSes
3) USB 3
4) Bluetooth

Loves Linux; loves to dance.

User avatar
RaspbianUser1
Posts: 841
Joined: Thu Mar 05, 2020 6:34 pm
Location: ~/

Re: [solved]Reading command inputted

Fri May 07, 2021 11:07 pm

again, I don't want a bash version, I can do that in 5 letters!

char command[4096] = {'\0'};

I couldn't get the

command[0] = '\0' to work.

Here's the error VS provides

a value of type \"int\" cannot be used to initialize an entity of type \"char [4096]\"",
Running with a Raspberry Pi 4B 4GB with Raspberry Pi OS with MATE Desktop
Why not overclock, push some more performance out of your computer!
Think before you delete something a stranger on the internet told you to.

User avatar
RaspbianUser1
Posts: 841
Joined: Thu Mar 05, 2020 6:34 pm
Location: ~/

Re: [solved]Reading command inputted

Fri May 07, 2021 11:13 pm

It all works!!! It has since the beginning!!!

All I want to do now is make it a little better
Running with a Raspberry Pi 4B 4GB with Raspberry Pi OS with MATE Desktop
Why not overclock, push some more performance out of your computer!
Think before you delete something a stranger on the internet told you to.

User avatar
jahboater
Posts: 7034
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: [solved]Reading command inputted

Fri May 07, 2021 11:16 pm

So you want to create a command actually called $ !!!

Note you cant assume the space after the $, though it is normal.
Export PS1='$'

Then you could have:
$sudo apt get
Last edited by jahboater on Fri May 07, 2021 11:25 pm, edited 1 time in total.

User avatar
RaspbianUser1
Posts: 841
Joined: Thu Mar 05, 2020 6:34 pm
Location: ~/

Re: [solved]Reading command inputted

Fri May 07, 2021 11:21 pm

I don't think that PS1 is a good idea, that would break a lot of things, anyway, most guides wouldn't gave it as 1 word ($sudo)

So my way is perfectly fine, all I want is to fix the way to buffer overflow possibility
Running with a Raspberry Pi 4B 4GB with Raspberry Pi OS with MATE Desktop
Why not overclock, push some more performance out of your computer!
Think before you delete something a stranger on the internet told you to.

User avatar
jahboater
Posts: 7034
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: [solved]Reading command inputted

Fri May 07, 2021 11:28 pm

RaspbianUser1 wrote:
Fri May 07, 2021 11:21 pm
So my way is perfectly fine, all I want is to fix the way to buffer overflow possibility
What wrong with this? Its much faster than the strcat(strcat(), " ") stuff which is O(N^2) or worse.
You can see the test for buffer overflow:

Code: Select all

  if( BUFSIZE - total_len < len + 1 )
  {
    fprintf(stderr, "argument list too long\n");
    exit(EXIT_FAILURE);
  }
and change it to whatever you like.

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum { BUFSIZE=8096 };

int
main( int argc, const char *argv[] )
{
  char buf[BUFSIZE];
  size_t total_len = 0;
  for( int i = 1; i < argc; ++i )
  {
    const size_t len = strlen(argv[i]);
    if( BUFSIZE - total_len < len + 1 )
    {
      fprintf(stderr, "argument list too long\n");
      exit(EXIT_FAILURE);
    }
    memcpy(buf + total_len, argv[i], len);
    total_len += len;
    buf[total_len++] = ' ';
  }
  buf[total_len] = '\0';

    // use it
  puts(buf);
}
Note that on Linux you have up to 8MB of stack space by default.

dsyleixa123
Posts: 1435
Joined: Mon Jun 11, 2018 11:22 am

Re: [solved]Reading command inputted

Sat May 08, 2021 7:36 am

RaspbianUser1 wrote:
Fri May 07, 2021 11:07 pm
I couldn't get the

command[0] = '\0' to work.

Here's the error VS provides

a value of type \"int\" cannot be used to initialize an entity of type \"char [4096]\"",
use
command[0] = 0;

dsyleixa123
Posts: 1435
Joined: Mon Jun 11, 2018 11:22 am

Re: [solved]Reading command inputted

Sat May 08, 2021 8:51 am

just to mention, C (stdio) often uses int for reading characters from input, not char:

Code: Select all

#include <stdio.h>

int main ()
{
  int c;
  puts ("Enter text. Include a dot ('.') in a sentence to exit:");
  do {
    c=getchar();
    putchar (c);
  } while (c != '.');
  return 0;
}
so as to a buffer used for input strings, perhaps it would be then like

Code: Select all

int buff[4096]; 

User avatar
jahboater
Posts: 7034
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: [solved]Reading command inputted

Sat May 08, 2021 9:16 am

dsyleixa123 wrote:
Sat May 08, 2021 7:36 am
RaspbianUser1 wrote:
Fri May 07, 2021 11:07 pm
I couldn't get the

command[0] = '\0' to work.

Here's the error VS provides

a value of type \"int\" cannot be used to initialize an entity of type \"char [4096]\"",
use
command[0] = 0;
I think the reported problem is missing the "char".
There is nothing wrong with:

Code: Select all

char command[4096];
command[0] = '\0';
but

Code: Select all

char command[4096] = '\0';
will fail. It needs curly brackets as in "= { '\0' };"
- which is not usually done as only the first character need be set.
( {0} will emit a call to memset(), or similar, to zero all 4096 characters in the buffer).

Also '\0' and 0 are the same thing (both integer literals).

Heater
Posts: 18199
Joined: Tue Jul 17, 2012 3:02 pm

Re: [solved]Reading command inputted

Sat May 08, 2021 10:15 am

dsyleixa123 wrote:
Sat May 08, 2021 8:51 am
just to mention, C (stdio) often uses int for reading characters from input, not char:

Code: Select all

#include <stdio.h>

int main ()
{
  int c;
  puts ("Enter text. Include a dot ('.') in a sentence to exit:");
  do {
    c=getchar();
    putchar (c);
  } while (c != '.');
  return 0;
}
so as to a buffer used for input strings, perhaps it would be then like

Code: Select all

int buff[4096]; 
No. That is a wrong interpretation of what is going on with getchar().

Under usual circumstances getchar() returns representations of characters. Those characters all fit in the number range 0 to 255. So you only need the low 8 bits of the returned int.

Of course sometimes getchar() can't get any more characters, end of file, or some error has occurred. There is no way to indicate that number range 0 to 255 as those values are all valid characters. So getchar() has to return something with a value outside the range 0-255. It returns EOF.

We conclude then that saving the output of getchar() into an int array is of no use. It only wastes memory. Plus those EOF are not any kind valid character for strings.

Unless, that is, you want to actually store a history of the failures of getchar(). Which seems unlikely.
Memory in C++ is a leaky abstraction .

User avatar
jahboater
Posts: 7034
Joined: Wed Feb 04, 2015 6:38 pm
Location: Wonderful West Dorset

Re: [solved]Reading command inputted

Sat May 08, 2021 10:44 am

Heater wrote:
Sat May 08, 2021 10:15 am
We conclude then that saving the output of getchar() into an int array is of no use. It only wastes memory. Plus those EOF are not any kind valid character for strings.
Plus it wont compile when you come to use that "int" array.
printf, system, etc etc all expect an array of chars.

Code: Select all

try.c:34:10: error: passing argument 1 of 'system' from incompatible pointer type
   34 |   system(buf);
      |          ^~~
      |          |
      |          int *
In file included from try.c:2:
/usr/include/stdlib.h:716:32: note: expected 'const char *' but argument is of type 'int *'
  716 | extern int system (const char *__command) __wur;
      |                    ~~~~~~~~~~~~^~~~~~~~~
wchar_t is a different matter.

dsyleixa123
Posts: 1435
Joined: Mon Jun 11, 2018 11:22 am

Re: [solved]Reading command inputted

Sat May 08, 2021 10:45 am

thanks for your clearifications!

User avatar
RaspbianUser1
Posts: 841
Joined: Thu Mar 05, 2020 6:34 pm
Location: ~/

Re: [solved]Reading command inputted

Sat May 08, 2021 1:03 pm

Code: Select all

#include <stdlib.h>
#include <string.h>
char command[8096] = {'\0'};
int main(int argc, char **argv)
{
for (int i=1; i<argc; i++){
    strcat(strcat(command,argv[i])," ");
    
}
command[strlen(command) - 1] = '\0';

system(command);
}
This is the current code, please refer to this


Changing the 8096 to something like 5 then running ./a.out echo "2131323" still would give the expected outcome, as if I just open a terminal and did it, the size doesn't seem to matter!

Also I am having trouble getting the bufferoverflow vulnerability code to work, something about len not being a thing, I have stdio and stdlib already included
Running with a Raspberry Pi 4B 4GB with Raspberry Pi OS with MATE Desktop
Why not overclock, push some more performance out of your computer!
Think before you delete something a stranger on the internet told you to.

Return to “C/C++”