Пример #1
0
mad_status GetDisasmPrev( address *a )
{
    mad_disasm_data dd;
    addr_off        start;
    addr_off        curr_off;
    addr_off        prev;
    unsigned        backup;
    int             big;

    DbgAddr = *a;
    big = BIG_SEG( DbgAddr );
    backup = ( big ) ? 0x40 : 0x20;
    curr_off = DbgAddr.mach.offset;
    DbgAddr.mach.offset = (curr_off <= backup) ? 0 : (curr_off - backup);
    InitCache( DbgAddr, curr_off - DbgAddr.mach.offset );
    for( start = DbgAddr.mach.offset; start < curr_off; ++start ) {
        DbgAddr.mach.offset = start;
        for( ;; ) {
            prev = DbgAddr.mach.offset;
            DoCode( &dd, big );
            if( dd.ins.size == 0 )
                break;      /* invalid address */
            DbgAddr.mach.offset += dd.ins.size;
            if( DbgAddr.mach.offset == curr_off ) {
                a->mach.offset = prev;
                return( MS_OK );
            }
            if( DbgAddr.mach.offset > curr_off ) break;
            if( DbgAddr.mach.offset < start ) break; /* wrapped around segment */
        }
    }
    /* Couldn't sync instruction stream */
    return( MS_FAIL );
}
Пример #2
0
mad_status MADIMPENTRY( CallBuildFrame )( mad_string call, address ret, address rtn, const mad_registers *in, mad_registers *out )
{
    unsigned    dec;
    unsigned_32 value;
    address     sp;

    dec = BIG_SEG( rtn ) ? 4 : 2;
    if( call == MAD_MSTR_NIL ) {
        call = (dec == 2) ? MAD_MSTR_FAR : MAD_MSTR_NEAR;
    }
    out->x86 = in->x86;
    sp = GetRegSP( out );
    switch( call ) {
    case MAD_MSTR_INTERRUPT:
        sp.mach.offset -= dec;
        value = out->x86.cpu.efl;
        MCWriteMem( sp, dec, &value );
        /* fall through */
    case MAD_MSTR_FAR:
        sp.mach.offset -= dec;
        value = ret.mach.segment;
        MCWriteMem( sp, dec, &value );
        /* fall through */
    case MAD_MSTR_NEAR:
        sp.mach.offset -= dec;
        value = ret.mach.offset;
        MCWriteMem( sp, dec, &value );
        break;
    }
    out->x86.cpu.esp = sp.mach.offset;
    out->x86.cpu.cs  = rtn.mach.segment;
    out->x86.cpu.eip = rtn.mach.offset;
    return( MS_OK );
}
Пример #3
0
const mad_reg_info *MADIMPENTRY( CallReturnReg )( mad_string call, address rtn )
{
    /* unused parameters */ (void)call;

    if( BIG_SEG( rtn ) ) {
        return( &CPU_eax.info );
    } else {
        return( &CPU_ax.info );
    }
}
Пример #4
0
char *ToSegStr( addr_off value, addr_seg seg, addr_off addr )
{
    address             memaddr;
    mad_type_handle     th;

    addr = addr;

    memaddr.mach.segment = seg;
    memaddr.mach.offset  = value;
    MCAddrSection( &memaddr );
    th = BIG_SEG( memaddr ) ? X86T_F32_PTR : X86T_F16_PTR;
    MCAddrToString( memaddr, th, MLK_MEMORY, sizeof( ScratchBuff ) - 1, ScratchBuff );
    return( ScratchBuff );
}
Пример #5
0
mad_status MADIMPENTRY( UnexpectedBreak )( mad_registers *mr, char *buff, size_t *buff_size_p )
{
    address     a;
    union {
        byte            b[9];
        addr32_ptr      a32;
        addr48_ptr      a48;
    }           data;
    size_t      buff_size;
    size_t      len;

    buff_size = *buff_size_p;
    *buff_size_p = 0;
    if( buff_size > 0 )
        buff[0] = '\0';
    a = GetRegIP( mr );
    memset( &data, 0, sizeof( data ) );
    MCReadMem( a, sizeof( data.b ), data.b );
    if( data.b[0] != BRK_POINT )
        return( MS_FAIL );
    mr->x86.cpu.eip += 1;
    if( data.b[1] != JMP_SHORT )
        return( MS_OK );
    if( memcmp( data.b + 3, "WVIDEO", 6 ) != 0 )
        return( MS_OK );
    a = GetRegSP( mr );
    MCReadMem( a, sizeof( addr_ptr ), &data );
    if( BIG_SEG( a ) ) {
        a.mach = data.a48;
    } else {
        ConvAddr32ToAddr48( data.a32, a.mach );
    }
    len = 0;
    while( MCReadMem( a, sizeof( data.b[0] ), data.b ) != 0 ) {
        a.mach.offset++;
        if( len + 1 < buff_size )
            buff[len] = data.b[0];
        if( data.b[0] == '\0' )
            break;
        ++len;
    }
    *buff_size_p = len;
    if( buff_size > 0 ) {
        --buff_size;
        if( buff_size > len )
            buff_size = len;
        buff[buff_size] = '\0';
    }
    return( MS_OK );
}
Пример #6
0
void MADIMPENTRY( AddrAdd )( address *a, long b, mad_address_format af )
{
    unsigned    over;

    a->mach.offset += b;
    if( !BIG_SEG( *a ) ) {
        if( a->mach.offset > 0xffff ) {
            if( af != MAF_OFFSET ) {
                over = a->mach.offset >> (16 - MCSystemConfig()->huge_shift);
                a->mach.segment += (addr_seg)over;
            }
            a->mach.offset &= 0xffff;
        }
    }
Пример #7
0
mad_type_handle DIGENTRY MITypeDefault( mad_type_kind tk, mad_address_format af, const mad_registers *mr, const address *ap )
{
    int         big;

    if( tk & MAS_IO ) {
        switch( tk & MTK_ALL ) {
        case MTK_BASIC:
        case MTK_INTEGER:
            return( X86T_BYTE );
        case MTK_ADDRESS:
            return( X86T_N16_PTR );
        }
        return( MAD_NIL_TYPE_HANDLE );
    }
    if( ap != NULL ) {
        big = BIG_SEG( *ap );
    } else if( mr != NULL ) {
        big = BIG_SEG( GetRegIP( mr ) );
    } else {
        big = ( ( MCSystemConfig()->cpu & X86_CPU_MASK ) >= X86_386);
    }
    switch( tk & MTK_ALL ) {
    case MTK_BASIC:
        return( X86T_BYTE );
    case MTK_INTEGER:
        return( big ? X86T_DWORD : X86T_WORD );
    case MTK_ADDRESS:
        if( big ) {
            return( (af == MAF_OFFSET) ? X86T_N32_PTR : X86T_F32_PTR );
        } else {
            return( (af == MAF_OFFSET) ? X86T_N16_PTR : X86T_F16_PTR );
        }
    case MTK_FLOAT:
        return( X86T_DOUBLE );
    }
    return( MAD_NIL_TYPE_HANDLE );
}
Пример #8
0
mad_status              DIGENTRY MIUnexpectedBreak( mad_registers *mr, unsigned *maxp, char *buff )
{
    address     a;
    union {
        byte            b[9];
        addr32_ptr      a32;
        addr48_ptr      a48;
    }           data;
    unsigned    max;
    unsigned    len;

    max = *maxp;
    *maxp = 0;
    if( max > 0 )
        buff[0] = '\0';
    a = GetRegIP( mr );
    memset( &data, 0, sizeof( data ) );
    MCReadMem( a, sizeof( data.b ), &data );
    if( data.b[0] != BRK_POINT )
        return( MS_FAIL );
    mr->x86.cpu.eip += 1;
    if( data.b[1] != JMP_SHORT )
        return( MS_OK );
    if( memcmp( &data.b[3], "WVIDEO", 6 ) != 0 )
        return( MS_OK );
    a = GetRegSP( mr );
    MCReadMem( a, sizeof( addr_ptr ), &data );
    if( BIG_SEG( a ) ) {
        a.mach = data.a48;
    } else {
        ConvAddr32ToAddr48( data.a32, a.mach );
    }
    len = 0;
    for( ;; ) {
        if( MCReadMem( a, sizeof( data.b[0] ), &data.b[0] ) == 0 )
            break;
        a.mach.offset++;
        if( len < max )
            buff[len] = data.b[0];
        if( data.b[0] == '\0' )
            break;
        ++len;
    }
    if( max > 0 )
        buff[max] = '\0';
    *maxp = len;
    return( MS_OK );
}
Пример #9
0
char *JmpLabel( unsigned long addr, addr_off off )
{
    address             memaddr;
    mad_type_handle     th;
    char                *p;

    off = off;

    memaddr = DbgAddr;
    memaddr.mach.offset = addr;
    th = ( BIG_SEG( memaddr ) ) ? X86T_N32_PTR : X86T_N16_PTR;
    #define PREFIX_STR "CS:"
    #define PREFIX_LEN (sizeof(PREFIX_STR)-1)
    p = &ScratchBuff[ PREFIX_LEN ];
    if( MCAddrToString( memaddr, th, MLK_CODE, sizeof( ScratchBuff ) - 1 - PREFIX_LEN, p ) != MS_OK ) {
        p -= PREFIX_LEN;
        memcpy( p, PREFIX_STR, PREFIX_LEN );
    }
    return( p );
}
Пример #10
0
mad_status MADIMPENTRY( CallUpStackLevel )( mad_call_up_data *cud,
                                const address *startp,
                                unsigned rtn_characteristics,
                                long return_disp,
                                const mad_registers *in,
                                address *execution,
                                address *frame,
                                address *stack,
                                mad_registers **out )
{
    address             prev_sp_value;
    address             start;

    /* unused parameters */ (void)cud; (void)in;

    *out = NULL;
    Is32BitSegment = BIG_SEG( *execution );
    start = *startp;
    if( MCSystemConfig()->os == MAD_OS_WINDOWS && !Is32BitSegment ) {
        memset( &start, 0, sizeof( start ) );
    }
    prev_sp_value = *stack;
    if( start.mach.segment == 0 && start.mach.offset == 0 ) {
        if( Is32BitSegment ) return( MS_FAIL );
        if( !BPTraceBack( execution, frame, stack ) ) return( MS_FAIL );
    } else {
        if( return_disp != -1L ) {
            SymbolicTraceBack( &start, rtn_characteristics, return_disp,
                        execution, frame, stack );
        } else {
            if( !HeuristicTraceBack( &prev_sp_value, &start,
                                execution, frame, stack ) ) return( MS_FAIL );
        }
    }
    if( stack->mach.offset <= prev_sp_value.mach.offset ) return( MS_FAIL );
    return( MS_OK );
}