📄 watchwnd.c
字号:
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 + -