Your comments to mov DWORD[ebx+8], ebx
and mov DWORD[ebx+12], eax
are wrong, or at least misleading.
The bytes at label 'shell' are '/bin/sh', which makes 7 bytes, and mov BYTE[ebx+7], al
terminates this string wih a null byte.
The next statement, mov DWORD[ebx+8], ebx
, moves the content of ebx - which is a pointer to shell - to the 4 bytes behind shell.
After that, mov DWORD[ebx+12], eax
moves a zero to the 4 next bytes. So we have the following memory layout, where bxbxbxbx
is the address of the start of this memory block:
bx value=bx, points to /bin/sh
| ___________
v / \
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| / | b | i | n | / | s | h |\0 |bx |bx |bx |bx | 0 | 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
The two LEA instructions move the address of (bx+8) and (bx+12) to cx and dx, respectively. You could replace them with MOV CX, BX; ADD CX, 8; MOV DX, BX; ADD DX,12
.
bx
|
v
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| / | b | i | n | / | s | h |\0 |bx |bx |bx |bx | 0 | 0 | 0 | 0 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
^ ^
cx dx
Now if you look at execvp:
The first argument, in bx, is a pointer to a string containing the name of the file to execute. That's /bin/sh
.
The second argument, in cx, is a pointer to an array of strings to pass to the program to be executed as argv. Here, this consists of a pointer to "/bin/sh", and a NULL pointer. The NULL pointer is used as array terminator (see execve docs), as there's no explicit array length.
The third argument, in dx, is the pointer to the environment for the new process - as it's a pointer to a NULL pointer, the new process doesn't inherit any environment variables from you.