Can anyone explain this assembly code

This is a shellcode to exploit the bufferoverflow vulnerability. this sets the setuid(0) and spawns a shell using execve()

  • xor %ebx,%ebx */
  • lea 0x17(%ebx),%eax */
  • int $0x80 */
  • push %ebx */
  • push $0x68732f6e */
  • push $0x69622f2f */
  • mov %esp,%ebx */
  • push %eax */
  • push %ebx */
  • mov %esp,%ecx */
  • cltd */
  • mov $0xb,%al */
  • int $0x80
  • this is the way i have interpreted it...

  • Xoring to make ebx value 0
  • adds 23 to 0 and loads effective addr to eax. for setuid()
  • 3.interrupt

    4.push ebx

    5.push address //y this address only????

    6.push address //same question

    12 mov execve sys call into al

    13 interrupt

    Can anyone explain the entire steps clearly??


    int is the opcode for triggering a software interrupt. Software interrupts are numbered (from 0 to 255) and handled by the kernel. On Linux systems, interrupt 128 (0x80) is the conventional entry point for system calls. The kernel expects the system call arguments in the registers; in particular, the %eax register identifies which system call we are talking about.

  • Set %ebx to 0
  • Compute %ebx+23 and store the result in %eax (the opcode is lea as "load effective address" but not memory access is involved; this is just a devious way of making an addition).
  • System call. %eax contains 23, which means that the system call is setuid . That system call uses one argument (the target UID), to be found in %ebx, which conveniently contains 0 at that point (it was set in the first instruction). Note: upon return, registers are unmodified, except for %eax which contains the returned value of the system call, normally 0 (if the call was a success).
  • Push %ebx on the stack (which is still 0).
  • Push $0x68732f6e on the stack.
  • Push $0x69622f2f on the stack. Since the stack grows "down" and since the x86 processors use little endian encoding, the effect of instructions 4 to 6 is that %esp (the stack pointer) now points at a sequence of twelve bytes, of values 2f 2f 62 69 6e 2f 73 68 00 00 00 00 (in hexadecimal). That's the encoding of the "//bin/sh" string (with a terminating zero, and three extra zeros afterwards).
  • Move %esp to %ebx. Now %ebx contains a pointer to the "//bin/sh" string which was built above.
  • Push %eax on the stack (%eax is 0 at that point, it is the returned status from setuid ).
  • Push %ebx on the stack (pointer to "//bin/sh"). Instructions 8 and 9 build on the stack an array of two pointers, the first being the pointer to "//bin/sh" and the second a NULL pointer. That array is what the execve system call will use as second argument.
  • Move %esp to %ecx. Now %ecx points to the array built with instructions 8 and 9.
  • Sign-extend %eax into %edx:%eax. cltd is the AT&T syntax for what the Intel documentations call cdq . Since %eax is zero at that point, this sets %edx to zero too.
  • Set %al (the least significant byte of %eax) to 11. Since %eax was zero, the whole value of %eax is now 11.
  • System call. The value of %eax (11) identifies the system call as execve . execve expects three arguments, in %ebx (pointer to a string naming the file to execute), %ecx (pointer to an array of pointers to strings, which are the program arguments, the first one being a copy of the program name, to be used by the invoked program itself) and %edx (pointer to an array of pointers to strings, which are the environment variables; Linux tolerates that value to be NULL, for an empty environment), respectively.
  • So the code first calls setuid(0) , then calls execve("//bin/sh", x, 0) where x points to an array of two pointers, first one being a pointer to "//bin/sh", while the other is NULL.

    This code is quite convoluted because it wants to avoid zeros: when assembled into binary opcodes, the sequence of instruction uses only non-zero bytes. For instance, if the 12th instruction had been movl $0xb,%eax (setting the whole of %eax to 11), then the binary representation of that opcode would have contained three bytes of value 0. The lack of zero makes that sequence usable as the contents of a zero-terminated C string. This is meant for attacking buggy programs through buffer overflows, of course.

    链接地址: http://www.djcxy.com/p/72448.html

    上一篇: 为什么我的选择排序代码不工作?

    下一篇: 任何人都可以解释这汇编代码