1

Is there a way to access a variable initialized in one code from another code. For eg. my code1.c is as follows,

# include <stdio.h>
int main()
{
    int a=4;
    sleep(99);
    printf("%d\n", a);
    return 0;
}

Now, is there any way that I can access the value of a from inside another C code (code2.c)? I am assuming, I have all the knowledge of the variable which I want to access, but I don't have any information about its address in the RAM. So, is there any way?

I know about the extern, what I am asking for here is a sort of backdoor. Like, kind of searching for the variable in the RAM based on some properties.

Armali
  • 18,255
  • 14
  • 57
  • 171
TrigonaMinima
  • 1,828
  • 1
  • 23
  • 35
  • 1
    You can use `extern` key . Click here: http://stackoverflow.com/questions/10422034/when-to-use-extern-in-c – webpersistence Mar 28 '15 at 13:04
  • See [this SO article](http://stackoverflow.com/questions/1433204/how-do-i-use-extern-to-share-variables-between-source-files-in-c) – Tim Biegeleisen Mar 28 '15 at 13:05
  • Your example is not good - that `a` might not exist at all, because it is unused and optimized out. Perhaps you can provide a better example. Then, what do you mean by _another C code_ - another function within the same program, or a separate executable program? Also, an answer to your question is highly dependent on the operating system, so you should provide this information. – Armali Sep 18 '15 at 09:36
  • @Armali I have edited the code. And another C code means a separate executable program. And, I am not exactly sure how this is highly dependent on the OS, but I am working on Ubuntu. – TrigonaMinima Sep 19 '15 at 20:02
  • I reinserted a delay to give us time to run the other program. – Armali Sep 28 '15 at 13:04

3 Answers3

1

Your example has one caveat, set aside possible optimizations that would make the variable to dissapear: variable a only exists while the function is being executed and has not yet finished.

Well, given that the function is main() it shouldn't be a problem, at least, for standard C programs, so if you have a program like this:

# include <stdio.h>
int main()
{
    int a=4;
    printf("%d\n", a);
    return 0;
}

Chances are that this code will call some functions. If one of them needs to access a to read and write to it, just pass a pointer to a as an argument to the function.

# include <stdio.h>
int main()
{
    int a=4;
    somefunction(&a);
    printf("%d\n", a);
    return 0;
}

void somefunction (int *n)
{
    /* Whatever you do with *n you are actually
       doing it with a */
    *n++; /* actually increments a */
}

But if the function that needs to access a is deep in the function call stack, all the parent functions need to pass the pointer to a even if they don't use it, adding clutter and lowering the readability of code.

The usual solution is to declare a as global, making it accessible to every function in your code. If that scenario is to be avoided, you can make a visible only for the functions that need to access it. To do that, you need to have a single source code file with all the functions that need to use a. Then, declare a as static global variable. So, only the functions that are written in the same source file will know about a, and no pointer will be needed. It doesn't matter if the functions are very nested in the function call stack. Intermediate functions won't need to pass any additional information to make a nested function to know about a

So, you would have code1.c with main() and all the functions that need to access a

/* code1.c */

# include <stdio.h>

static int a;
void somefunction (void);

int main()
{
    a=4;
    somefunction();
    printf("%d\n", a);
    return 0;
}

void somefunction (void)
{
    a++;
}

/* end of code1.c */

About trying to figure out where in RAM is a specific variable stored: Kind of. You can travel across function stack frames from yours to the main() stack frame, and inside those stack frames lie the local variables of each function, but there is no sumplementary information in RAM about what variable is located at what position, and the compiler may choose to put it wherever it likes within the stack frame (or even in a register, so there would be no trace of it in RAM, except for push and pops from/to general registers, which would be even harder to follow).

So unless that variable has a non trivial value, it's the only local variable in its stack frame, compiler optimizations have been disabled, your code is aware of the architecture and calling conventions being used, and the variable is declared as volatile to stop being stored in a CPU register, I think there is no safe and/or portable way to find it out.

OTOH, if your program has been compiled with -g flag, you might be able to read debugging information from within your program and find out where in the stack frame the variable is, and crawl through it to find it.

mcleod_ideafix
  • 11,128
  • 2
  • 24
  • 32
  • I want to know if one can access the value of a in another C code (code2.c). Not with static or extern, but kind of accessing the RAM contents and finding the value of ```a```. – TrigonaMinima Sep 19 '15 at 20:37
  • Answered in the answer itself, as the text was too large for a comment – mcleod_ideafix Sep 19 '15 at 21:07
0

code1.c:

#include <stdio.h>

void doSomething(); // so that we can use the function from code2.c

int a = 4; // global variable accessible in all functions defined after this point

int main()
{
    printf("main says %d\n", a);
    doSomething();
    printf("main says %d\n", a);
    return 0;
}

code2.c

#include <stdio.h>

extern int a; // gain access to variable from code1.c

void doSomething()
{
    a = 3;
    printf("doSomething says %d\n", a);
}

output:

main says 4
doSomething says 3
main says 3

You can use extern int a; in every file in which you must use a (code2.c in this case), except for the file in which it is declared without extern (code1.c in this case). For this approach to work you must declare your a variable globally (not inside a function).

danieltm64
  • 471
  • 2
  • 4
  • I knew about ```extern```, I am sorry I didn't state that explicitly in the question but I am asking for a sort of backdoor for reading the value of ```a``` from the memory stack? – TrigonaMinima Mar 29 '15 at 08:16
0

One approach is to have the separate executable have the same stack layout as the program in question (since the variable is placed on the stack, and we need the relative address of the variable), therefore compile it with the same or similar compiler version and options, as much as possible.
On Linux, we can read the running code's data with ptrace(PTRACE_PEEKDATA, pid, …). Since on current Linux systems the start address of the stack varies, we have to account for that; fortunately, this address can be obtained from the 28th field of /proc/…/stat.
The following program (compiled with cc Debian 4.4.5-8 and no code generator option on Linux 2.6.32) works; the pid of the running program has to be specified as the program argument.

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ptrace.h>

void *startstack(char *pid)
{   // The address of the start (i. e. bottom) of the stack.
    char str[FILENAME_MAX];
    FILE *fp = fopen(strcat(strcat(strcpy(str, "/proc/"), pid), "/stat"), "r");
    if (!fp) perror(str), exit(1);
    if (!fgets(str, sizeof str, fp)) exit(1);
    fclose(fp);
    unsigned long address;
    int i = 28; char *s = str; while (--i) s += strcspn(s, " ") + 1;
    sscanf(s, "%lu", &address);
    return (void *)address;
}

static int access(void *a, char *pidstr)
{
    if (!pidstr) return 1;
    int pid = atoi(pidstr);
    if (ptrace(PTRACE_ATTACH, pid, 0, 0) < 0) return perror("PTRACE_ATTACH"), 1;
    int status;
    // wait for program being signaled as stopped
    if (wait(&status) < 0) return perror("wait"), 1;
    // relocate variable address to stack of program in question
    a = a-startstack("self")+startstack(pidstr);
    int val;
    if (errno = 0, val = ptrace(PTRACE_PEEKDATA, pid, a, 0), errno)
        return perror("PTRACE_PEEKDATA"), 1;
    printf("%d\n", val);
    return 0;
}

int main(int argc, char *argv[])
{
    int a;
    return access(&a, argv[1]);
}

Another, more demanding approach would be as mcleod_ideafix indicated at the end of his answer to implement the bulk of a debugger and use the debug information (provided its presence) to locate the variable.

Armali
  • 18,255
  • 14
  • 57
  • 171