文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>如何得到一个函数的代码大小

如何得到一个函数的代码大小

时间:2006-11-27  来源:tthacker

                                如何得到一个函数的代码长度
                                       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 <[email protected]>

*/

#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 <elf-file> <symbol>\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[i].sh_name,".symtab") == 0 ){
            symtab_off = (unsigned int)shdr[i].sh_offset;
            symtab_num = (int )(shdr[i].sh_size / shdr[i].sh_entsize);
            printf("[+] .Symtab Off : 0x%x num :%d\n",symtab_off,symtab_num);
        }

        if( strcmp(buffer + shdr[i].sh_name,".strtab") == 0){
            strtab_off = (unsigned int)shdr[i].sh_offset;
            strtab_size = (unsigned int)shdr[i].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[i].st_name,function) ){
                printf("[+] Found %s!\n",function);
                printf("[+] Size :%d!\n", symtab_ptr[i].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;
}

相关阅读 更多 +
排行榜 更多 +
风度

风度

游戏工具 下载
大姨妈月经提醒

大姨妈月经提醒

健康医疗 下载
海岸线小说网

海岸线小说网

浏览阅读 下载