示例#1
0
/*
 * Adds a destructor to a block.
 */
dip_status VMAddDtor( imp_image_handle *ii, virt_mem start,
                      void ( *dtor )( imp_image_handle *ii, void *user ),
                      void *user )
{
    unsigned            dir_idx;
    unsigned            pg_idx;
    virt_page           *pg;

    /* locate the block. */
    dir_idx = GET_DIR( start );
    if( ii->virt[dir_idx] != NULL ) {
        pg_idx = GET_PAGE( start );
        pg = ii->virt[dir_idx][pg_idx];
        if( pg != NULL ) {
            /* create a new dtor node and link it in */
            vm_dtor *node = DCAlloc( sizeof( *node ) );
            if( node != NULL ) {
                node->user = user;
                node->dtor = dtor;
                node->next = pg->block->first_dtor;
                pg->block->first_dtor = node;
                return( DS_OK );
            }
            return( DS_ERR | DS_NO_MEM );
        }
    }

    return( DS_ERR | DS_FAIL );
}
示例#2
0
const critbit__extnode_t *critbit__lookup(const critbit__node_t *n,
        const void            *key,
        size_t                 keylen)
{
    const unsigned char *ukey    = key;
    const unsigned char *ukeyend = ukey + keylen;
    int                  dir;

    for (; IS_INTERNAL(n); n = n->child[dir])
        dir = GET_DIR(ukey, ukeyend, n->byte, n->otherbits);

    return FROM_STORE(n);
}
示例#3
0
DWORD WINAPI GetK32ProcAddress(int ord)
{
    static HANDLE hmod = 0;
    IMAGE_NT_HEADERS *hdr;
    IMAGE_EXPORT_DIRECTORY *exp;
    DWORD *AddrFunc;
    WORD enewhdr, *pw;
    int did_load = 0, i;
    BYTE *moddb;

    if (hmod == 0)      // one-time static init
        hmod = GetModuleHandle("KERNEL32");
    if (hmod == 0)      // still
        return 0;
    
    moddb = (BYTE *) hmod;
    pw = (WORD *) &moddb[0];
    if (*pw != EMAGIC)              
        return 0;
    pw = (WORD *) &moddb[ENEWHDR];
    enewhdr = *pw;
    pw = (WORD *) &moddb[enewhdr];
    if (*pw != PEMAGIC)             
        return 0;
    hdr = (IMAGE_NT_HEADERS *) pw;
    
    // Note: offset from moddb, *NOT* from hdr!
    exp = (IMAGE_EXPORT_DIRECTORY *) (((DWORD) moddb) +
        ((DWORD) GET_DIR(IMAGE_DIRECTORY_ENTRY_EXPORT)));
    AddrFunc = (DWORD *) (moddb + (DWORD) exp->AddressOfFunctions);

    // should verify that e.g.:
    // GetProcAddress(hmod, "VirtualAlloc") == GetK32ProcAddress(710);
    
    ord--;  // table is 0-based, ordinals are 1-based
    if (ord < exp->NumberOfFunctions)
        return ((DWORD) (moddb + AddrFunc[ord]));
    else
        return 0;
}
示例#4
0
void *VMBlock( imp_image_handle *iih, virt_mem start, size_t len )
{
    unsigned            dir_idx;
    unsigned            pg_idx;
    unsigned            tmp_idx;
    unsigned            i;
    unsigned            j;
    unsigned            num_pages;
    virt_mem            pg_start;
    virt_page           *pg;
    virt_page           *zero;
    loaded_block        *block;

    dir_idx = GET_DIR( start );
    if( iih->virt[dir_idx] == NULL ) {
        if( !InitPageDir( iih, dir_idx ) ) {
            return( NULL );
        }
    }
    pg_idx = GET_PAGE( start );
    len += start % VM_PAGE_SIZE;
    pg_start = start & ~(virt_mem)(VM_PAGE_SIZE - 1);
    pg = iih->virt[dir_idx][pg_idx];
    if( pg == NULL || ( pg->block->len - pg->offset ) < len ) {
        /* unloaded previously loaded block */
        if( pg != NULL ) {
            tmp_idx = dir_idx;
            /* find first page of the block */
            i = pg_idx;
            for( ;; ) {
                iih->virt[tmp_idx][i] = NULL;
                if( pg->offset == 0 )
                    break;
                if( i == 0 ) {
                    --tmp_idx;
                    i = DIR_SIZE;
                }
                --i;
                --pg;
            }
            DCFree( pg );
        }
        num_pages = BLOCK_FACTOR( len, VM_PAGE_SIZE );
        pg = DCAlloc( num_pages * ( sizeof( *pg ) + VM_PAGE_SIZE ) + sizeof( loaded_block ) - 1 );
        if( pg == NULL ) {
            DCStatus( DS_ERR | DS_NO_MEM );
            return( NULL );
        }
        /* set up new page table entries */
        block = (loaded_block *)&pg[num_pages];
        tmp_idx = dir_idx;
        for( j = pg_idx, i = 0; i < num_pages; ++j, ++i ) {
            pg[i].block = block;
            pg[i].offset = i * VM_PAGE_SIZE;
            if( j >= DIR_SIZE ) {
                ++tmp_idx;
                j = 0;
            }
            if( iih->virt[tmp_idx] == NULL ) {
                if( !InitPageDir( iih, tmp_idx ) ) {
                    /* unwind the setup already done */
                    num_pages = i;
                    for( i = 0; i < num_pages; ++i, ++pg_idx ) {
                        if( pg_idx >= DIR_SIZE ) {
                            ++dir_idx;
                            pg_idx = 0;
                        }
                        iih->virt[dir_idx][pg_idx] = NULL;
                    }
                    DCFree( pg );
                    return( NULL );
                }
            }
            if( iih->virt[tmp_idx][j] != NULL ) {
                /*
                    We just ran into another allocated block, so we have
                    to kill all the pages mapped in by it. We know that
                    if the page pointer is non-NULL, it will be offset==0
                    since KillPages will clean out the others.
                */
                KillPages( iih, tmp_idx, j );
            }
            iih->virt[tmp_idx][j] = &pg[i];
        }
        /* read in new block */
        len = num_pages * VM_PAGE_SIZE;
        block->len = len;
        pg_start += iih->bias;
        if( DCSeek( iih->sym_fp, pg_start, DIG_ORG ) ) {
            DCStatus( DS_ERR | DS_FSEEK_FAILED );
            return( NULL );
        }
        /* last block might be a short read */
        if( DCRead( iih->sym_fp, pg->block->data, len ) == DIG_RW_ERROR ) {
            DCStatus( DS_ERR | DS_FREAD_FAILED );
            return( NULL );
        }
        pg = iih->virt[dir_idx][pg_idx];
    }
    ++TimeStamp;
    if( TimeStamp == 0 ) {
        /* deal with wrap-around */
        for( iih = ImageList; iih != NULL; iih = iih->next_image ) {
            if( iih->virt != NULL ) {
                for( i = iih->vm_dir_num; i-- > 0; ) {
                    if( iih->virt[i] != NULL ) {
                        for( j = DIR_SIZE; j-- > 0; ) {
                            zero = iih->virt[i][j];
                            if( zero != NULL ) {
                                zero->block->time_stamp = 0;
                            }
                        }
                    }
                }
            }
        }
        ++TimeStamp;
    }
    pg->block->time_stamp = TimeStamp;
    return( &pg->block->data[(start & (VM_PAGE_SIZE - 1)) + pg->offset] );
}