免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1146 | 回复: 0
打印 上一主题 下一主题

如何得到一个函数的代码大小 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-11-27 08:35 |只看该作者 |倒序浏览
                                如何得到一个函数的代码长度
                                       by wzt
        
1,如何得到一个elf文件的符号长度
    相关信息请看:
   
http://www.whitecell.org/forums/viewthread.php?tid=298

   
2,我用的方法就是直接从elf文件中读取这个符号的数据结构。

1).建立elf文件的映象到内存,这样对elf文件的操作比较方便。
2).从elf头中读取section table header的相关信息。
3).从section table header中得到.shstrtab节的地址和大小。将其拷贝到一个内存缓冲区A中。
4).遍历节,根据sh_name在A中的偏移,得到节的名字,如果节名为.symtab或者.strtab,记录
他们的地址,偏移,如果是表的话,则计算表的大小。
5).将.strtab节拷贝到内存缓冲区B中。
6).遍厉符号表,根据st_name在B中的偏移,得到符号表的名字。如果是你要找的符号表,记录它
   的相关信息即可。

3,具体代码如下:


/*
    ELF Reader V 0.0.5 Show ELF Information
    by wzt
*/
#include stdio.h>
#include string.h>
#include stdlib.h>
#include unistd.h>
#include fcntl.h>
#include elf.h>
#include sys/stat.h>
#include sys/mman.h>
#define BUFFER    1024
void usage(char *pro);
void info_elf(char *elf_file,char *function);
void usage(char *pro)
{
    fprintf(stdout,"Relf V 0.0.5 by wzt\r\n");
    fprintf(stdout,"\nusage:\r\n");
    fprintf(stdout,"%s  \r\n",pro);
    exit(0);
}
void info_elf(char *elf_file,char *function)
{
    Elf32_Ehdr *ehdr = NULL;
    Elf32_Phdr *phdr = NULL;
    Elf32_Shdr *shdr = NULL;
    Elf32_Shdr        *shstrtab = NULL;
    Elf32_Sym        *dynsym_ptr = NULL;
    Elf32_Sym *symtab_ptr = NULL;
    Elf32_Sym        *dynstr_ptr = NULL;
    char            *Real_strtab = NULL;
    char            *dynstr = NULL;
    char            *strtab_ptr = NULL;
    char            buffer[BUFFER];
    char            dynstr_buffer[2048];   
    char            strtab_buffer[4096];        
    int fd,i;
    int phdr_len;
    int shdr_len;
    int                symtab_off,symtab_num;
    int                dynsym_off,dynsym_size,dynsym_num;
    int                dynstr_off,dynstr_size;
    int                shstrtab_off,shstrtab_len,shstrtab_num;
    unsigned int    strtab_off,strtab_size;
    fd = open(elf_file,O_RDWR);
    if( fd == -1 ){
        perror("elf_file");
        exit(1);
    }
    if( fstat(fd,&stat) == -1 ){
        perror("fstat");
        exit(1);
    }
    ehdr = mmap(0, stat.st_size, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
    if(ehdr == MAP_FAILED) {
        perror("mmap ehdr");
        goto err;
    }
    if(ehdr->e_ident[EI_MAG0] != 0x7f
    || ehdr->e_ident[EI_MAG1] != 'E'
    || ehdr->e_ident[EI_MAG2] != 'L'
    || ehdr->e_ident[EI_MAG3] != 'F'
    || ehdr->e_ident[EI_CLASS] != ELFCLASS32
    || ehdr->e_ident[EI_DATA] != ELFDATA2LSB
    || ehdr->e_ident[EI_VERSION] != EV_CURRENT
    || ehdr->e_type != ET_EXEC
    || ehdr->e_machine != EM_386
    || ehdr->e_version != EV_CURRENT
    ) {
   
        printf("File type not supported\n");
        goto err;
    }        
    phdr = (Elf32_Phdr *)( (unsigned long)ehdr + ehdr->e_phoff );
    shdr = (Elf32_Shdr *)( (unsigned long)ehdr + ehdr->e_shoff );
// 节名表所在的节在文件中的地址
    shstrtab = &shdr[ehdr->e_shstrndx];
// 节名表在文件中的偏移
    shstrtab_off = (unsigned int)shstrtab->sh_offset;
// 节名表的长度
    shstrtab_len = shstrtab->sh_size;
// 节名表在内存中的实际地址
    Real_strtab = (char *)( (unsigned long)ehdr + shstrtab_off );
    printf("[+] .Shstrtab Size :%x,%d\n",shstrtab->sh_size,shstrtab->sh_name);
    printf("[+] .Shstrtab Off: %x\n",shstrtab_off);
// 将节名表拷贝到缓冲区中
    memcpy(buffer,Real_strtab,shstrtab_len + 1);
    for(i = 0 ; i  (int)ehdr->e_shnum ; i++){
        if( strcmp(buffer + shdr.sh_name,".symtab") == 0 ){
            symtab_off = (unsigned int)shdr.sh_offset;
            symtab_num = (int )(shdr.sh_size / shdr.sh_entsize);
            printf("[+] .Symtab Off : 0x%x num :%d\n",symtab_off,symtab_num);
        }
        if( strcmp(buffer + shdr.sh_name,".strtab") == 0){
            strtab_off = (unsigned int)shdr.sh_offset;
            strtab_size = (unsigned int)shdr.sh_size;
            printf("[+] .Strtab Off : 0x%x num : %d\n",strtab_off,strtab_size);
        }
    }
// 将strtab节读到缓冲区中
    strtab_ptr = (char *)( (unsigned long)ehdr + strtab_off );
   
    memcpy(strtab_buffer,strtab_ptr,strtab_size + 1);
    symtab_ptr = (Elf32_Sym *)( (unsigned long)ehdr + symtab_off );
    for(i = 0; i symtab_num; i++){
        if( !strcmp(strtab_buffer + symtab_ptr.st_name,function) ){
                printf("[+] Found %s!\n",function);
                printf("[+] Size :%d!\n", symtab_ptr.st_size);
                break;
        }
    }
    err:
    if (ehdr)
        munmap(ehdr, stat.st_size);
    if (fd != -1)
        close(fd);
}
int main(int argc,char **argv)
{
    if( argc == 1 ){
        usage(argv[0]);
    }
    info_elf(argv[1],argv[2]);
    return 0;
}


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/15780/showart_206536.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP