Hacker News new | past | comments | ask | show | jobs | submit login

it only works because you're skipping over environment variables:

    char **argv = &stack;
    char **envp = __environ = argv + ( 1 * sizeof( void* ) );
let's say argv = 0x8, then according to this code, on x86_64, envp = 0x48 (0x8 + sizeof(void * ) * sizeof(char *)). here's a sample stack where argc = 1:

    stack:
    [0x0]  = 1 (argc)
    [0x8]  = "program path"
    [0x10] = 0
    [0x18] = "FOO1=FOO1"
    [0x20] = "FOO2=FOO2"
    [0x28] = "FOO3=FOO3"
    [0x30] = "FOO4=FOO4"
    [0x38] = "FOO5=FOO5"
    [0x40] = "FOO6=FOO6"
    [0x48] = "FOO7=FOO7"
    ...
since you set envp to 0x48 it now points to FOO7=FOO7, you've inadvertently skipped FOO1-FOO6. if argc = 2, then envp would point to FOO6 and you skipped FOO1-FOO5.

try this with your code, pass 8 arguments to your test. the environment will point to the last element in argv and then terminate, completely missing the actual environment. again, that's only the behavior on x86, on x86_64, passing any argument will cause a segfault.




I think I've fixed it [0]. Ran into the issue where gcc was kindly re-aligning the stack to 16-bytes on i386 for no good reason (stack was already aligned?!?!). But that's fixed. Just hope gcc on i386 doesn't stop doing `sub ESP, 0x1C` upon entry to _start.

[0] https://github.com/lpsantil/rt0/blob/master/lib/00_start.c




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: