radareorg / ideas

4 stars 1 forks source link

Add d subcommand to manipulate process environment variables #205

Open radare opened 6 years ago

radare commented 6 years ago

like it's done already in r2frida

radare commented 6 years ago

we can handle /proc/pid/environ on linux, on other platforms we can parse the stack, asuming the environment is filled at the end of the dm where SP is pointing to. walking backwards until a NULL ( 4, 8 bytes) is found then parse a null terminated string array to process those k=v items

radare commented 6 years ago

that's an OS-specific thing, that works on linux and mac like this, but windows is different(R)

leberus commented 6 years ago

I'm sorry but I'm not familiar with r2frida. What's this "d" subcommand supposed to do? Maybe you can write a tiny example so I can get an idea.

I'd mind taking a look at this.

radare commented 6 years ago

i think the debugger is pretty broken right now. we should focus on pushing the testsuite for the debuggers, at least on linux because it is segfaulting and hanging all the time when im trying to use it lately :(

On 4 Feb 2018, at 13:22, leberus notifications@github.com wrote:

I'm sorry but I'm not familiar with r2frida. What's this "d" subcommand supposed to do? Maybe you can write a tiny example so I can get an idea.

I'd mind taking a look at this.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/radare/radare2/issues/8864#issuecomment-362902784, or mute the thread https://github.com/notifications/unsubscribe-auth/AA3-lnpQfoN083AVSt3XUW3FU3iMYrgmks5tRaELgaJpZM4QnSsn.

leberus commented 6 years ago

Would you mind sharing some binary samples so I can take a look at the issue. (segfaulting/hanging), I'd like to push that forward. Not sure the best to "push" the debugging testsuite (some ideas?) You cced me in radareorg/radare2#9263 but that worked for me.

radare commented 6 years ago

strangely i cant reproduce them now :D

On 12 Feb 2018, at 08:06, Oscar Salvador notifications@github.com wrote:

Would you mind sharing some binary samples so I can take a look at the issue. (segfaulting/hanging), I'd like to push that forward. Not sure the best to "push" the debugging testsuite (some ideas?) You cced me in radareorg/radare2#9263 https://github.com/radare/radare2/issues/9263 but that worked for me.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/radare/radare2/issues/8864#issuecomment-364931809, or mute the thread https://github.com/notifications/unsubscribe-auth/AA3-lntQWVIxLaKHLRpKehI8kOhMVZgiks5tUEVLgaJpZM4QnSsn.

leberus commented 6 years ago

Ok, just let me know if you find any issue related to the debugger on linux. And know that we cleared this up, may I ask the question again?

I'm sorry but I'm not familiar with r2frida.
What's this "d" subcommand supposed to do? Maybe you can write a tiny example so I can get an idea.
radare commented 6 years ago

manipulate the environment variables of the process at runtime.

this is, assuming SP and BP, walk up the stack and find the env vars who are the begining of the map, then parse the null terminated strings and allow to read (or write) those variables at runtime using this ‘d’ subcommand.

On 13 Feb 2018, at 11:44, Oscar Salvador notifications@github.com wrote:

Ok, just let me know if you find any issue related to the debugger on linux. And know that we cleared this up, may I ask the question again?

I'm sorry but I'm not familiar with r2frida. What's this "d" subcommand supposed to do? Maybe you can write a tiny example so I can get an idea. — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/radare/radare2/issues/8864#issuecomment-365224823, or mute the thread https://github.com/notifications/unsubscribe-auth/AA3-loIUyKhycTEBcoPxbdoDr4ADJkQNks5tUWd2gaJpZM4QnSsn.

leberus commented 6 years ago

yes, i guessed that. I'm working on this, i'll keep you posted.

radare commented 6 years ago

Awesome

On 19 Feb 2018, at 14:59, Oscar Salvador notifications@github.com wrote:

yes, i guessed that. I'm working on this, i'll keep you posted.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

leberus commented 6 years ago

Just wanted to show that I am working on it here

[0x7f7d9d0e31f0]> dz?
|Usage: dz Environment commands
| dz                          Show all environment variables
| dzl                         Show all environment variables (long output)
| dzg [env_name]              Show [env_name]
| dzgl [env_name]             Show [env_name] (long output)
| dzs [env_name]=[env_value]  Set [env_name] to [env_value]
[0x7f7d9d0e31f0]> dz
XDG_VTNR=7
LESSKEY=/etc/lesskey.bin
MANPATH=/usr/local/man:/usr/local/share/man:/usr/share/man
NNTPSERVER=news
SSH_AGENT_PID=3387
XDG_SESSION_ID=2
...
...
[0x7f7d9d0e31f0]> dzl
XDG_VTNR=7 [0x7ffc2e18bf18 - (modified? n)]
LESSKEY=/etc/lesskey.bin [0x7ffc2e18bf20 - (modified? n)]
MANPATH=/usr/local/man:/usr/local/share/man:/usr/share/man [0x7ffc2e18bf28 - (modified? n)]
NNTPSERVER=news [0x7ffc2e18bf30 - (modified? n)]
SSH_AGENT_PID=3387 [0x7ffc2e18bf38 - (modified? n)]
XDG_SESSION_ID=2 [0x7ffc2e18bf40 - (modified? n)]
...
...
[0x7f7d9d0e31f0]> dzgl GUAKE_TAB_UUID
r_debug_env_name_get: name: GUAKE_TAB_UUID, true
GUAKE_TAB_UUID=9609ed57-6eca-461a-8aa9-b4c4df0eeada [0x7ffc2e18c168 - (modified? n)]

# cat  env.c
void func(void)
{
    int a = 6;
    int b = a + 2;
}

int main(void)
{
    printf ("Getting env WINDOWPATH\n");
    char *env = getenv ("WINDOWPATH");

    if (env == NULL) {
        printf ("WINDOWPATH == NULL\n");
        return 1;
    }

    printf ("val: %s\n", env);

    func();

    printf ("Getting env WINDOWPATH\n");
    env = getenv ("WINDOWPATH");
    if (env == NULL) {
        printf ("env == NULL\n");
    }

    printf ("env: %s\n", env);

    return 0;
}

alvador@d104:~> r2 -d ./env
[0x7f6d29bcb1f0]> db sym.func
[0x7f6d29bcb1f0]> dz
...
WINDOWPATH=7
...
[0x7f6d29bcb1f0]> dc
Getting env WINDOWPATH
val: 7
hit breakpoint at: 4005dd
[0x004005dd]> dzs WINDOWPATH=10
r_debug_env_name_set: WINDOWPATH=10
hit breakpoint at: 40063b
ra0=0x7f6d29de7000
r_debug_env_name_set: env->addr: 0x7ffe493120e0
r_debug_env_name_set: map->addr: 0x7f6d29de7000
[0x004005dd]> dc
Getting env WINDOWPATH
env: 10
[0x7f6d298e14a9]>

Still quite a lot of work to do and refactor stuff and so on, but moving forward.

radare commented 6 years ago

awesome!

On 2 Mar 2018, at 11:58, Oscar Salvador notifications@github.com wrote:

Just wanted to show that I am working on it here https://github.com/leberus/radare2/commit/85134495cbfc70dfff5fd6261a11acfa960cec4f [0x7f7d9d0e31f0]> dz? |Usage: dz Environment commands | dz Show all environment variables | dzl Show all environment variables (long output) | dzg [env_name] Show [env_name] | dzgl [env_name] Show [env_name] (long output) | dzs [env_name]=[env_value] Set [env_name] to [env_value] [0x7f7d9d0e31f0]> dz XDG_VTNR=7 LESSKEY=/etc/lesskey.bin MANPATH=/usr/local/man:/usr/local/share/man:/usr/share/man NNTPSERVER=news SSH_AGENT_PID=3387 XDG_SESSION_ID=2 ... ... [0x7f7d9d0e31f0]> dzl XDG_VTNR=7 [0x7ffc2e18bf18 - (modified? n)] LESSKEY=/etc/lesskey.bin [0x7ffc2e18bf20 - (modified? n)] MANPATH=/usr/local/man:/usr/local/share/man:/usr/share/man [0x7ffc2e18bf28 - (modified? n)] NNTPSERVER=news [0x7ffc2e18bf30 - (modified? n)] SSH_AGENT_PID=3387 [0x7ffc2e18bf38 - (modified? n)] XDG_SESSION_ID=2 [0x7ffc2e18bf40 - (modified? n)] ... ... [0x7f7d9d0e31f0]> dzgl GUAKE_TAB_UUID r_debug_env_name_get: name: GUAKE_TAB_UUID, true GUAKE_TAB_UUID=9609ed57-6eca-461a-8aa9-b4c4df0eeada [0x7ffc2e18c168 - (modified? n)]

cat env.c

void func(void) { int a = 6; int b = a + 2; }

int main(void) { printf ("Getting env WINDOWPATH\n"); char *env = getenv ("WINDOWPATH");

if (env == NULL) { printf ("WINDOWPATH == NULL\n"); return 1; }

printf ("val: %s\n", env);

func();

printf ("Getting env WINDOWPATH\n"); env = getenv ("WINDOWPATH"); if (env == NULL) { printf ("env == NULL\n"); }

printf ("env: %s\n", env);

return 0; }

alvador@d104:~> r2 -d ./env [0x7f6d29bcb1f0]> db sym.func [0x7f6d29bcb1f0]> dz ... WINDOWPATH=7 ... [0x7f6d29bcb1f0]> dc Getting env WINDOWPATH val: 7 hit breakpoint at: 4005dd [0x004005dd]> dzs WINDOWPATH=10 r_debug_env_name_set: WINDOWPATH=10 hit breakpoint at: 40063b ra0=0x7f6d29de7000 r_debug_env_name_set: env->addr: 0x7ffe493120e0 r_debug_env_name_set: map->addr: 0x7f6d29de7000 [0x004005dd]> dc Getting env WINDOWPATH env: 10 [0x7f6d298e14a9]> Still quite a lot of work to do and refactor stuff and so on, but moving forward.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/radare/radare2/issues/8864#issuecomment-369890985, or mute the thread https://github.com/notifications/unsubscribe-auth/AA3-lvQ2XZ_4XOFYm90PxHpBErOLnSxLks5taSXHgaJpZM4QnSsn.

leberus commented 6 years ago

Hi, I'd like to talk about what I am currently doing to see if we agree or I need to take another way.

env is an array of pointers

1) At first shot, I parse /proc/pid/env to get all env strings
2) I go to the end of the stack and for each env I do:

Taking into account that  env is an array of pointers, 
I want to get the addr of the pointer, that points the string:

 2a) Search backwards env=value to get the addr where the string is located
 2b) Once I get the addr of the string, I search backwards that addr to get the pointer of that addr
 2c) Save in a struct: key, value, pointer of the addr, etc.

Printing the env is a matter of walkingthrough the struct Now let's talk about how I am dealing with modify env variables

1) Let's say we want to modify "myenv=envvalue" to "myenv=newvalue", 
and the pointer of that string addr is 0xffeeaa
2) I allocate a new memory area on the debugged process (dbg->h->allocate_map). 
Addr of the new mmap is 0xffddea
3) I copy the "myenv=envvalue" to 0xffddea and I swap the pointers in the stack (env), 
so where before there was a 0xffeeaa, now there is a 0xffddea
4) I keep track where current position of the mmap is, so in case we modify a new var we append it there
5) In case that mmap is fully written, and we want to modify another env var, we allocate another on and so son

This is working, but I am asking this because I am not sure if we would be better off dealing with regg code and executing "setenv()" in the debugged process by calling regg code (maybe that was preferred). There is a comment that regg* code only supports x86 assembly? so if that is true that might limit us.

Thoughts?

@radare

radare commented 6 years ago

will be good to have some generic code to do all this stuff, and yeah, via r_egg calling setenv() can be probably the cleaner way to do that, but we probably need to improve dx and such. if you are in the mood, that would be a good thing to improve

radare commented 6 years ago

ping @leberus

ret2libc commented 4 years ago

This issue has been moved from radareorg/radare2 to radareorg/ideas as we are trying to clean our backlog and this issue has probably been created a long while ago. This is an effort to help contributors understand what are the actionable items they can work on, prioritize issues better and help users find active/duplicated issues more easily. If this is not an enhancement/improvement/general idea but a bug, feel free to ask for re-transfer to main repo. Thanks for your understanding and contribution with this issue.