Which environment variables the app is using - c

I have binary executable file compiled from C-source and I know that it uses some of UNIX system environment variables. Unfortunately I have no documentation and decompiling/reverse-engineering is very difficult.
Is there a way to find which env variables the app tries to read in runtime?
I mean, if C's getenv reads some file to get variable values or does a system call, it is possible. So, can I do it?

strings(1) might help you to identify the names of the envrionment variables.
– Blagovest Buyukliev

One can use a debugger, set a breakpoint on getenv, and inspect the function argument. This is possible even without debug information (albeit more difficult, since it requires knowledge of the calling convention).

Related

fopen() function with a dynamic location in C

I just want to learn that how can I open a file with fopen() function from a dynamic location. I mean, for example it will be a system file and in another computer, this file can be in another location. So if I will set my location in my code not dynamically, my program will not work in another computer. So how Can I set the location dynamically for my program will find this file wherever it is?
You can (and often should) pass program arguments to your main, thru the conventional int argc, char**argv formal arguments of your main. See also this.
(I am focusing on Linux, but you could adapt my answer to other OSes and platforms)
So you would use some convention to pass that file path (not a location, that word usually refers to memory addresses) to your program (often thru the command line starting your program). See also this answer.
You could use (at least on Linux) getopt_long(3) to parse program arguments. But there are other ways, and you can process the arguments of main explicitly.
You could also use some environment variable to pass that information. You'll query it with getenv(3). Read also environ(7).
Many programs have configuration files (whose path is wired into the program but often can be given by program arguments or by environment variables) and are parsing them to find relevant file paths.
And you could even consider some other inter-process communication to pass a file path to your program. After all, a file path is just some string (with restrictions and interpretations explained in path_resolution(7)). There are many ways to pass some data to a program.
Read also about globbing, notably glob(7). On Unix, the shell is expanding the program arguments. You may want to use functions like glob(3) or wordexp(3) on something obtained elsewhere (e.g. in some configuration file) to get similar expansion.
BTW, be sure, when using fopen, to check against its failure. You'll probably use perror like here.
Look also into the source code of several free software projects (perhaps on github) for inspiration.
I would suggest you to use the environment variables, In a PC set your file location as environment variable. then read the environment variable value in your program, then open the file. This idea works both in linux and windows however you have adopt the code based on the OS to read the environment variables.
Besides specifying file location at runtime through command line arguments, environment variables or configuration files, you can implement a PATH-like logic:
Possible locations for your file are set in an environment variable:
export MY_FILE_PATH=/usr/bin:/bin:/opt/bin:$HOME/bin
Your program reads that environment variable, parses its contents and checks existence of file in each specified path, with fopen() return status.

Win32, WinMain vs custom Entry Point (huge size difference), why?

As topic says.
I noticed that if i use WinMain or any other default Entry Point, a C application can be like 70kb.
But if i just specify a custom Entry Point, say "RawMain", int RawMain().
Then the file will be like 6kb.
So i am wondering, why is this, what does it add/reference to the file?
I could understand there being some small difference in size, but the difference is huge for an empty application.
Thanks!
When building for windows in most environments, the actual program entry point will be provided by a function in a small runtime library. That will do some environment preparation and then call a function you provide, such as main, wmain, WinMain, etc.
The code that runs before your user-provided main function includes running global C++ constructors, enabling TLS variables, initializing global mutexes so that standard-library calls work properly in a multithreaded environment, setting up the standard locale, and other stuff.
One thing that setting the entry point does is starts the linker with an undefined symbol with the name you give the entry point, so for example, if you're using mingw32, the linker will start assuming that it needs to link libmingw32.a and with the undefined symbol __tmainCRTStartup.
The linker will find (hopefully) __tmainCRTStartup in libmingw32.a, and include the object file crtexe.o which contains it, along with anything else needed to satisfy undefined symbols emanating from crtexe.o, which is where the extra size comes from.
When you set your own entry point, you override this, and just set the linker to look for whatever function you specify. You get a smaller executable, but you have to be careful that features you're using don't rely on any of the global initialization that would be done by the runtime's startup function.

Is there a way to pass command line arguments to custom entry point (C / C++)

I used -Wl,-e to change the entry point of a C program, is there a way to still get command line arguments?
Thanks in advance
Globals like _argc/_argv are provided by the compiler's runtime and thus require the compiler's default entry point to set them up. If you use your own entry point, you are bypassing all runtime initializations, so you will have to resort to platform-specific APIs to access the command-line parameters (GetCommandLine() on Windows, read from /proc/self/cmdline on Linux, etc).
– Remy Lebeau

setenv() to update PATH environment variable

i want to write a C program to append a string to PATH Environment variable.
something like "export PATH=$PATH:$HOME/mylib"
i have C code like this
setenv("PATH", "$PATH:$HOME/mylib",1); //which does not work.
other work arround i thought was get PATH and HOME using getenv() and create a memory in heap then append them using strcat().
I might have to update PATH many times in my code: so this is a tiresome process.
is there any alternative?
Thanks
The $FOO syntax, which expands to the value of the environment variable with the name FOO, is a feature of the shell; it's not directly available in C.
Your system may provide the wordexp() function, which gives you similar functionality in C.
But since you're just expanding two environment variables with fixed names ("HOME" and "PATH"), it makes more sense to use the portable getenv() function and a little string processing. (You might consider using sprintf or snprintf rather than strcat.)
NOTE: If you're only using the updated $PATH internally in your program, you can stop reading here.
Hopefully you're not expecting any changes to $PATH to be available on the command line after your program finishes running. Your running C program is most likely a child process of your interactive shell. Environment variables are inherited by child processes; they don't propagate back to parent proceses.
If that's what you're trying to do, you can have your program print the new PATH value to stdout, and then have the shell evaluate it:
PATH=`your-program`
Or it can print the command(s) to set one or more environment variables:
eval `your-program`
(In bash, you can use $(your-program) as well as `your-program`.)
No there is no alternative. You have to build the literal string and pass it to setenv.
There is no other option immediately available. You can write a separate function to handle this, if you need to do it several times.

Help with using LD_PRELOAD

I want to create a library with a modified version of printf and then call LD_PRELOAD so when my program calls printf it uses my version. Can someone explain to me how to use LD_PRELOAD and if there is a something special I need to do in my code or my library?
You just set the environment variable LD_PRELOAD to the full path to the replacement library. Since all programs you launch after that point will attempt to use this library, you may want to make a wrapper script that sets LD_PRELOAD then calls the program you want to run.
As far as I know first of all the program cannot have changed evective uid or gid (so called suid or guid programs).
It should be used only for specific purposes such as debugging. As far as I recall you may shadow functions in C (in elf?). However both techniques - LD_PRELOAD and shadowing should be deal with extream care. I remember discovering bug in shadowing g_malloc in gpgme code (or other related to gpg) as the GLib internals changed.
The simple answer is - don't do it. The more complicated - do it if and only if you have to - and usually you don't (unless you write some sort of debugging software).
That seems like a bad idea. Why not name your version of printf something else?

Resources