⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 watchwnd.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 3 页
字号:
        watchinfo_list[watchinfo_count].ebp = ebp;
        watchinfo_list[watchinfo_count].cursoreip = cursoreip;
        watchinfo_list[watchinfo_count++].typetab = typetab;
        RefreshItem(&watchinfo_list[watchinfo_count - 1], var->address);
        InsertSubTree(0, previous, var, watchinfo_count - 1);
    }
}

//-------------------------------------------------------------------------

void RenumberDeleteItems(VARINFO *v)
{
    while (v)
    {
        v->watchindex--;
        if (v->subtype)
            RenumberDeleteItems(v->subtype);
        v = v->link;
    }
}

//-------------------------------------------------------------------------

void DeleteItem(POINT *pt)
{
    int i;
    WATCHINFO *x;
    TV_HITTESTINFO t;
    HTREEITEM titem;
    TV_ITEM item;
    VARINFO *v;

    ScreenToClient(hwndTree, pt);
    t.pt =  *pt;
    titem = TreeView_HitTest(hwndTree, &t);
    if (titem)
    {
        int c;
        item.mask = TVIF_PARAM;
        item.hItem = titem;
        TreeView_GetItem(hwndTree, &item);
        v = (VARINFO*)item.lParam;
        x = &watchinfo_list[c = v->watchindex];
        FreeTree(x->info);
        FreeVarInfo(x->info);
        for (i = c; i < watchinfo_count - 1; i++)
        {
            watchinfo_list[i] = watchinfo_list[i + 1];
            RenumberDeleteItems(watchinfo_list[i].info);
        }
        watchinfo_count--;
    }
}

//-------------------------------------------------------------------------

void DeleteAllItems(void)
{
    int i;
    TreeView_DeleteAllItems(hwndTree);
    for (i = 0; i < watchinfo_count; i++)
        FreeVarInfo(watchinfo_list[i].info);
    watchinfo_count = 0;
}

//-------------------------------------------------------------------------

void Unscope(WATCHINFO *wi)
{
    if (!wi->info->outofscope)
    {
        wi->info->outofscope = TRUE;
        //      FreeTree(wi->info->subtype) ;
    }
}

//-------------------------------------------------------------------------

void Rescope(WATCHINFO *wi, int index)
{
    if (wi->info->outofscope)
    {
        wi->info->outofscope = FALSE;
        //      InsertSubTree(wi->info->hTreeItem,0,wi->info->subtype, index) ;
    }
}

//-------------------------------------------------------------------------

void RefreshItems(void)
{
    int i;
    char *types,  *syms;
    int offset, offset1;
    DEBUG_INFO *dbg;
    for (i = 0; i < watchinfo_count; i++)
    {
        WATCHINFO *wi = &watchinfo_list[i];
        int level;
        offset = wi->cursoreip;
        offset1 = findStackedFunction(offset, &wi->ebp, &level, &wi->info
            ->thread);
        if (!FindSymbol(&wi->dbg_info, &wi->typetab, &wi->symtab, &offset,
            offset1, offset, (char*)wi->info->membername))
        {
            Unscope(wi);
            offset = 0;
        }
        else
        {
            VARINFO *x = GetVarInfo(wi->dbg_info, wi->typetab, wi->symtab,
                offset, wi->info->membername, wi->ebp, wi->info->thread);
            wi->info->outofscopereg = x->outofscopereg;
            if (x->outofscopereg)
            {
                Unscope(wi);
                offset = 0;
            }
            else
            {
                Rescope(wi, i);
                offset = x->address;
            }
            FreeVarInfo(x);
        }
        RefreshItem(wi, offset);
    }
    InvalidateRect(hwndTree, 0, 0);
}

//-------------------------------------------------------------------------

void ExpandPointer(VARINFO *v, int code)
{
    if (v->pointer)
    {
        if (code == TVE_EXPAND)
        {
            int val;
            int outofscope = !ReadValue(v->address, &val, 4, v->inreg ? &v
                ->thread->regs: 0) || !val;
            if (!v->subtype)
            {
                TreeView_DeleteItem(hwndTree, v->hTreeHolder);
                GetPointerInfo(watchinfo_list[v->watchindex].typetab, v);
                InsertSubTree(v->hTreeItem, 0, v->subtype, v->watchindex);
                //			TreeView_Expand(hwndTree, v->hTreeItem, TVE_EXPAND) ;
            }
            RefreshAddresses(v->subtype, val, outofscope);
            RefreshData(watchinfo_list[v->watchindex].typetab, v);
        }
        else if (code == TVE_COLLAPSE)
        {
            if (v->subtype)
            {
                FreeTree(v->subtype);
                FreeVarInfo(v->subtype);
                v->subtype = 0;
                v->hTreeHolder = InsertItem(v->hTreeItem, TVI_LAST, v);
            }
        }
    }
}

//-------------------------------------------------------------------------

int WriteValue(int address, void *value, int size, CONTEXT *regs)
{
    int len;
    if (address < 0x1000)
    {
        // register
        int val = *(int*)value;
        switch (address)
        {
            case CV_REG_AL:
                regs->Eax &= 0xffffff00;
                regs->Eax |= (unsigned char)val;
                return 1;
            case CV_REG_CL:
                regs->Ecx &= 0xffffff00;
                regs->Ecx |= (unsigned char)val;
                return 1;
            case CV_REG_DL:
                regs->Edx &= 0xffffff00;
                regs->Edx |= (unsigned char)val;
                return 1;
            case CV_REG_BL:
                regs->Ebx &= 0xffffff00;
                regs->Ebx |= (unsigned char)val;
                return 1;
            case CV_REG_AH:
                regs->Eax &= 0xffff00ff;
                regs->Eax |= ((unsigned char)val) << 8;
                return 1;
            case CV_REG_CH:
                regs->Ecx &= 0xffff00ff;
                regs->Ecx |= ((unsigned char)val) << 8;
                return 1;
            case CV_REG_DH:
                regs->Edx &= 0xffff00ff;
                regs->Edx |= ((unsigned char)val) << 8;
                return 1;
            case CV_REG_BH:
                regs->Ebx &= 0xffff00ff;
                regs->Ebx |= ((unsigned char)val) << 8;
                return 1;
            case CV_REG_AX:
                regs->Eax &= 0xffff0000;
                regs->Eax |= (unsigned short)val;
                return 2;
            case CV_REG_CX:
                regs->Ecx &= 0xffff0000;
                regs->Ecx |= (unsigned short)val;
                return 2;
            case CV_REG_DX:
                regs->Edx &= 0xffff0000;
                regs->Edx |= (unsigned short)val;
                return 2;
            case CV_REG_BX:
                regs->Ebx &= 0xffff0000;
                regs->Ebx |= (unsigned short)val;
                return 2;
            case CV_REG_SP:
                regs->Esp &= 0xffff0000;
                regs->Esp |= (unsigned short)val;
                return 2;
            case CV_REG_BP:
                regs->Ebp &= 0xffff0000;
                regs->Ebp |= (unsigned short)val;
                return 2;
            case CV_REG_SI:
                regs->Esi &= 0xffff0000;
                regs->Esi |= (unsigned short)val;
                return 2;
            case CV_REG_DI:
                regs->Edi &= 0xffff0000;
                regs->Edi |= (unsigned short)val;
                return 2;
            case CV_REG_EAX:
                regs->Eax = val;
                return 4;
            case CV_REG_ECX:
                regs->Ecx = val;
                return 4;
            case CV_REG_EDX:
                regs->Edx = val;
                return 4;
            case CV_REG_EBX:
                regs->Ebx = val;
                return 4;
            case CV_REG_ESP:
                regs->Esp = val;
                return 4;
            case CV_REG_EBP:
                regs->Ebp = val;
                return 4;
            case CV_REG_ESI:
                regs->Esi = val;
                return 4;
            case CV_REG_EDI:
                regs->Edi = val;
                return 4;
            case CV_REG_ST0:
                // not supported
            case CV_REG_ST1:
            case CV_REG_ST2:
            case CV_REG_ST3:
            case CV_REG_ST4:
            case CV_REG_ST5:
            case CV_REG_ST6:
            case CV_REG_ST7:
                return 0;
        }
    }
    else
    {
        WriteProcessMemory(DebugProcess.hProcess, (LPVOID)address, (LPVOID)
            value, size, &len);
        return len;
    }
}

//-------------------------------------------------------------------------

int InputEnum(char *typetab, VARINFO *info, char *text)
{
    int signedtype;
    int v;
    short *typeptr = info->typetab;
    while (*(typeptr + 1) == LF_FIELDLIST)
    {
        int done = FALSE;
        int len =  *typeptr - 2;
        typeptr += 2;
        while (len > 0 && !done)
        {
            int xlen;
            int rv;
            char *nmptr;
            switch (*typeptr)
            {
                case LF_ENUMERATE:
                    xlen = sizeof(lfEnumerate) - 1;
                    if (v < LF_NUMERIC)
                        xlen += 2;
                    else
                        xlen += 6;
                    nmptr = ((char*)typeptr) + xlen;
                    rv = GetNumericLeaf(&((lfEnumerate*)typeptr)->value);
                    {
                        char buf1[256];
                        memset(buf1, 0, 256);
                        strncpy(buf1, nmptr + 1,  *nmptr);
                        if (!strcmp(buf1, text))
                            return rv;
                    }
                    xlen +=  *nmptr + 1;
                    if ((*((char*)typeptr + xlen) &0xf0) == 0xf0)
                        xlen += *((char*)typeptr + xlen) &15;
                    (char*)typeptr += xlen;
                    len -= xlen;
                    break;
                case LF_INDEX:
                    typeptr = LookupType(typetab, ((lfIndex*)typeptr)->index);
                    done = TRUE;
                    break;
                default:
                    return 0;
            }
        }
    }
    return 0;
}

//-------------------------------------------------------------------------

void ChangeData(VARINFO *info, char *text)
{
    if (CV_TYP_IS_REAL(info->type) || CV_TYP_IS_IMAGINARY(info->type))
    {
        float v;
        double v2;
        char data[10];
        sscanf(text, "%f", &v);
        switch (info->type)
        {
            case T_REAL32:
            case T_IMAGINARY32:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -