Chinaunix首页 | 论坛 | 博客
  • 博客访问: 498716
  • 博文数量: 223
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2145
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-01 10:23
个人简介

该坚持的时候坚持,该妥协的时候妥协,该放弃的时候放弃

文章分类

全部博文(223)

文章存档

2017年(56)

2016年(118)

2015年(3)

2014年(46)

我的朋友

分类: C/C++

2014-09-09 22:23:49

wld_start

/*

 *  wld_start

 *

 *  Repeat the actions the kernel would do when loading a dynamically linked .so

 *  Load the binary and then its ELF interpreter.

 *  Note, we assume that the binary is a dynamically linked ELF shared object.

 */

void* wld_start( void **stack )

{

    long i, *pargc;

    char **argv, **p;

    char *interp, *reserve = NULL;

    struct wld_auxv new_av[12], delete_av[3], *av;

    struct wld_link_map main_binary_map, ld_so_map;

    struct wine_preload_info **wine_main_preload_info;

 

    pargc = *stack;  = (long int *) 0xbffff320

    argv = (char **)pargc + 1;  = (char **) 0xbffff324

    if (*pargc < 2) fatal_error( "Usage: %s wine_binary [args]\n", argv[0] ); ×pargc =3

 

    /* skip over the parameters */

    p = argv + *pargc + 1;    = (char **) 0xbffff334

遍历了系统的环境,看有没有匹配的

    /* skip over the environment */

    while (*p)

    {

        static const char res[] = "WINEPRELOADRESERVE=";

        if (!wld_strncmp( *p, res, sizeof(res)-1 )) reserve = *p + sizeof(res) - 1;

        p++;

    }

一直到*p为0,p+1是第二个p结构,av是在p后面的struct wld_auxv *

    av = (struct wld_auxv *)(p+1);  = (struct wld_auxv *) 0xbffff3e8

    page_size = get_auxiliary( av, AT_PAGESZ, 4096 );  = 4096

    page_mask = page_size - 1;   = 4095

设置起始和结束地址

    preloader_start = (char *)_start - ((unsigned long)_start & page_mask);

    preloader_end = (char *)((unsigned long)(_end + page_mask) & ~page_mask);

没用到

#ifdef DUMP_AUX_INFO

    wld_printf( "stack = %p\n", *stack );

    for( i = 0; i < *pargc; i++ ) wld_printf("argv[%lx] = %s\n", i, argv[i]);

    dump_auxiliary( av );

#endif

第一次= {{addr = 0x0, size = 65536}, {addr = 0x10000, size = 1048576}, {

    addr = 0x110000, size = 1743716352}, {addr = 0x7f000000, size = 50331648}, 

  {addr = 0x0, size = 0}, {addr = 0x0, size = 0}}

保留wine的存储需要,把一些空间移去。然后保留了原来的空间

    /* reserve memory that Wine needs */

    if (reserve) preload_reserve( reserve );  =0

    for (i = 0; preload_info[i].size; i++)

    {

        if ((char *)av >= (char *)preload_info[i].addr &&

            (char *)pargc <= (char *)preload_info[i].addr + preload_info[i].size)

        {

            remove_preload_range( i );

            i--;

        }

        else if (wld_mmap( preload_info[i].addr, preload_info[i].size, PROT_NONE,

                           MAP_FIXED | MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, -1, 0 ) == (void *)-1)

        {

这里addr第一次为0

            /* don't warn for low 64k */

            if (preload_info[i].addr >= (void *)0x10000)

                wld_printf( "preloader: Warning: failed to reserve range %p-%p\n",

                            preload_info[i].addr, (char *)preload_info[i].addr + preload_info[i].size );

preload_info的内容整体往移了

            remove_preload_range( i );

            i--;

        }

    }

 

    /* add an executable page at the top of the address space to defeat

     * broken no-exec protections that play with the code selector limit */

    if (is_addr_reserved( (char *)0x80000000 - page_size ))

        wld_mprotect( (char *)0x80000000 - page_size, page_size, PROT_EXEC | PROT_READ );


    /* load the main binary */

    map_so_lib( argv[1], &main_binary_map );

 

    /* load the ELF interpreter */

    interp = (char *)main_binary_map.l_addr + main_binary_map.l_interp;

    map_so_lib( interp, &ld_so_map );

 

    /* store pointer to the preload info into the appropriate main binary variable */

    wine_main_preload_info = find_symbol( main_binary_map.l_phdr, main_binary_map.l_phnum,

                                          "wine_main_preload_info", STT_OBJECT );

    if (wine_main_preload_info) *wine_main_preload_info = preload_info;

    else wld_printf( "wine_main_preload_info not found\n" );

 这里设置了新的辅助变量

#define SET_NEW_AV(n,type,val) new_av[n].a_type = (type); new_av[n].a_un.a_val = (val);

    SET_NEW_AV( 0, AT_PHDR, (unsigned long)main_binary_map.l_phdr );

    SET_NEW_AV( 1, AT_PHENT, sizeof(ElfW(Phdr)) );

    SET_NEW_AV( 2, AT_PHNUM, main_binary_map.l_phnum );

    SET_NEW_AV( 3, AT_PAGESZ, page_size );

    SET_NEW_AV( 4, AT_BASE, ld_so_map.l_addr );

    SET_NEW_AV( 5, AT_FLAGS, get_auxiliary( av, AT_FLAGS, 0 ) );

    SET_NEW_AV( 6, AT_ENTRY, main_binary_map.l_entry );

    SET_NEW_AV( 7, AT_UID, get_auxiliary( av, AT_UID, wld_getuid() ) );

    SET_NEW_AV( 8, AT_EUID, get_auxiliary( av, AT_EUID, wld_geteuid() ) );

    SET_NEW_AV( 9, AT_GID, get_auxiliary( av, AT_GID, wld_getgid() ) );

    SET_NEW_AV(10, AT_EGID, get_auxiliary( av, AT_EGID, wld_getegid() ) );

    SET_NEW_AV(11, AT_NULL, 0 );

#undef SET_NEW_AV

 

    i = 0;

    /* delete sysinfo values if addresses conflict */

    if (is_in_preload_range( av, AT_SYSINFO ) || is_in_preload_range( av, AT_SYSINFO_EHDR ))

    {

        delete_av[i++].a_type = AT_SYSINFO;

        delete_av[i++].a_type = AT_SYSINFO_EHDR;

    }

    delete_av[i].a_type = AT_NULL;

 

    /* get rid of first argument */

    set_process_name( *pargc, argv );

    pargc[1] = pargc[0] - 1;

    *stack = pargc + 1;

 

    set_auxiliary_values( av, new_av, delete_av, stack );

 

#ifdef DUMP_AUX_INFO

    wld_printf("new stack = %p\n", *stack);

    wld_printf("jumping to %p\n", (void *)ld_so_map.l_entry);

#endif

 返回ld-linux.so.2的程序入口地址

    return (void *)ld_so_map.l_entry;

}

阅读(923) | 评论(0) | 转发(0) |
0

上一篇:preloader_exec整理

下一篇:umask函数linux

给主人留下些什么吧!~~