11

Is it possible to execute a process whose argc = 0? I need to execute a program but it is extremely important for its argc to be equal to 0. Is there a way to do that? I tried to put 2^32 arguments in the command line so that it appears as if argc = 0 but there is a maximum limit to the number of arguments.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
Keeto
  • 4,074
  • 9
  • 35
  • 58
  • 4
    what exactly are you trying to achieve? I mean, maybe there's another, simpler way to do it. – Aziz Nov 13 '11 at 18:48
  • 1
    What is your operating system, and how are you executing this process? Is it user-activated or are you calling from another process? – ibid Nov 13 '11 at 18:49
  • 2
    Can't you just set `argc = 0` as the first line of `main()`? – Carl Norum Nov 13 '11 at 18:49
  • 3
    also, this is related: http://stackoverflow.com/questions/2794150/when-can-argv0-have-null – Aziz Nov 13 '11 at 18:49
  • I have no control over the source code. But I know that in the source code, it exits if argc != 0. I am on linux ubuntu. I can activate it or I can call it from another process. – Keeto Nov 13 '11 at 18:52
  • Thanks Aziz for the link, i think it might help – Keeto Nov 13 '11 at 18:55
  • You could modify the binary with a debugger/hex editor and that would make really short work of it. – Seth Carnegie Nov 13 '11 at 18:59
  • I wouldn't trust a program that breaks if `argc != 0`. That kind of implies that the person who developed it didn't even try running it once, let alone do any real testing. – ruakh Nov 13 '11 at 20:35

3 Answers3

15

You can write a program that calls exec directly; that allows you to specify the command-line arguments (including the program name) and lack thereof.

ibid
  • 3,891
  • 22
  • 17
  • Great, it works. But any idea how to pass arguments and still leave argc=0 – Keeto Nov 13 '11 at 19:29
  • 4
    `argc` indicates the number of arguments (plus one, for the program name), so no, that's not possible. – ibid Nov 13 '11 at 19:32
11

You may use linux system call execve().

int execve(const char *filename, char *const argv[], char *const envp[]);

You may pass the filename of executable and a null pointer as the argv[] to execute the binary and the argc will be zero.

It is my test code:

#include <stdio.h>
#include <unistd.h>

int main(void) {
    char *argv[] = { NULL };
    execv("./target", argv);
    // execv is correct, look up https://linux.die.net/man/3/execv
    return 0;
}

And the strace result is:

execve("./target", [], [/* 20 vars */]) = 0

You could use envp[] to pass the arguments you defined anyways.

Furthermore, you could use assembly language to reach your goal (argc == 0 but you still need to pass arguments). I assume that you are using a 32-bits x86 environment.

The concept is that:

  • store 0x0b ($SYS_execve) into %eax
  • put the address of argv[] into %ebx
  • put the address of envp[] into %ecx
  • then use int 0x80 to do a system call

The memory structure is shown below:

+--------------------------------------------------+     
|               +----------------------------------|-----+
v               v               v------------------|-----|-----+
[arg_0][\0][...][arg_1][\0][...][arg_2][\0][...][ptr0][ptr1][ptr2][\0]
                                                ^
                                                |   (argv[] = NULL)
                                                +--- envp

I am wondering that if you were doing the lab assignment of the course provided by Prof. Taesoo Kim (GATech). Course Link: https://tc.gtisc.gatech.edu/cs6265

Or is it a hacker CTF (catch-the-flag contest) problem?

vegafish
  • 425
  • 1
  • 5
  • 12
4

You could write a C program that spawns/execs the other program with no argv, like:

#include <spawn.h>
#include <stdlib.h>

int main(int argc, char** argv, char** envp)
{
    pid_t pid;
    char* zero_argv[] = {NULL};
    posix_spawn(&pid, "./that_app", NULL, NULL, zero_argv, envp);

    int status;
    waitpid(&pid, &status, NULL);
    return 0;
}
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005