📄 symtab.c
字号:
if (e1->SubSection == sstGlobalTypes)
{
*typetab = dbg->info + e1->lfo;
break;
}
e1++;
}
*symtab = dbg->info + e->lfo + sizeof(OMFSymHash);
*offset = offs;
return TRUE;
}
else
return FALSE;
}
e++;
}
}
return 0;
}
//-------------------------------------------------------------------------
PROCSYM32 *FindFunctionSymbol(int Address)
{
char *symtab;
DEBUG_INFO *dbg = DebugProcess.dbg_info;
int offset;
DLL_INFO *dll;
dll = DebugProcess.dll_info;
while (dll && (unsigned)dll->base <= (unsigned)Address)
{
dbg = dll->dbg_info;
dll = dll->next;
}
if (dbg && FindFunctionByAddress(dbg, &symtab, &offset, Address - dbg->base,
Address - dbg->base))
{
PROCSYM32 *p = symtab + offset;
return p;
}
return 0;
}
//-------------------------------------------------------------------------
int FindFunctionName(char *buf, int Address)
{
char *symtab;
DEBUG_INFO *dbg = DebugProcess.dbg_info;
int offset;
DLL_INFO *dll;
buf[0] = 0;
dll = DebugProcess.dll_info;
while (dll && (unsigned)dll->base <= (unsigned)Address)
{
dbg = dll->dbg_info;
dll = dll->next;
}
if (dbg && FindFunctionByAddress(dbg, &symtab, &offset, Address - dbg->base,
Address - dbg->base))
{
PROCSYM32 *p = symtab + offset;
getname(buf, p->name);
return 1;
}
return 0;
}
//-------------------------------------------------------------------------
char *LookupType(char *typetab, int typenum)
{
OMFGlobalTypes *p = typetab;
int offset;
typenum -= CV_FIRST_NONPRIM;
if (typenum < 0 || typenum >= p->cTypes)
return 0;
offset = p->typeOffset[typenum] + (char*) &p->cTypes - typetab;
return offset + typetab;
}
//-------------------------------------------------------------------------
int GetNumericLeaf(short *ptr)
{
int val = *(ptr);
if (val < LF_NUMERIC)
return val;
// LF_LONG is the only thing we are supporting
return *(int*)(ptr + 1);
}
//-------------------------------------------------------------------------
int GetNumericLeafSize(short *ptr)
{
int val = *(ptr);
if (val < LF_NUMERIC)
return 2;
// LF_LONG is the only thing we are supporting
return 5;
}
//-------------------------------------------------------------------------
void GetStructInfo(char *typetab, short *type, VARINFO *var)
{
short *typeptr = LookupType(typetab, ((lfStructure*)(type + 1))->field);
VARINFO **v = &var->subtype;
if (!typeptr)
return ;
while (*(typeptr + 1) == LF_FIELDLIST)
{
int done = FALSE;
int len;
len = *typeptr - 2;
typeptr += 2;
while (len && !done)
{
VARINFO *vx;
int xlen;
char *nmptr;
switch (*typeptr)
{
case LF_MEMBER:
vx = *v = calloc(sizeof(VARINFO), 1);
if (!vx)
return ;
vx->thread = var->thread;
v = &(*v)->link;
vx->offset = GetNumericLeaf(&((lfMember*)typeptr)->offset);
vx->address = var->address + vx->offset;
vx->type = ((lfMember*)typeptr)->index;
DeclType(typetab, vx);
xlen = sizeof(lfMember) - CV_ZEROLEN;
if ((*(short*)((char*)typeptr) + xlen) < LF_NUMERIC)
xlen += 2;
else
xlen += 6;
nmptr = (char*)typeptr + xlen;
strncpy(vx->membername, nmptr + 1, *nmptr);
vx->membername[ *nmptr] = 0;
xlen += *nmptr + 1;
if ((*(((char*)typeptr) + xlen) &0xf0) == 0xf0)
xlen += *(((char*)typeptr) + xlen) &15;
(char*)typeptr += xlen;
break;
case LF_INDEX:
typeptr = LookupType(typetab, ((lfIndex*)typeptr)->index);
done = TRUE;
break;
default:
return ;
}
}
}
}
//-------------------------------------------------------------------------
int basictypesize(int type)
{
if (CV_MODE(type) != CV_TM_DIRECT)
return 4;
switch (CV_TYPE(type))
{
case CV_SIGNED:
case CV_UNSIGNED:
case CV_BOOLEAN:
return 1 << CV_SUBT(type);
case CV_REAL:
case CV_IMAGINARY:
switch (CV_SUBT(type))
{
case CV_RC_REAL32:
return 4;
case CV_RC_REAL64:
return 8;
default:
return 10;
}
break;
case CV_COMPLEX:
switch (CV_SUBT(type))
{
case CV_RC_REAL32:
return 8;
case CV_RC_REAL64:
return 16;
default:
return 20;
}
break;
case CV_INT:
return 1 << (CV_SUBT(type) / 2);
}
return 0;
}
//-------------------------------------------------------------------------
void GetArrayInfo(char *typetab, short *type, VARINFO *var)
{
int i = 0, z = 0;
VARINFO **nextptr = &var->subtype;
while (i < var->arraysize)
{
VARINFO *vx = calloc(sizeof(VARINFO), 1);
if (!vx)
return ;
vx->thread = var->thread;
vx->offset = i;
vx->address = var->address;
if (var->vararray && var->vararraylist && var->vararraylevel < var
->vararraylist[0] - 1)
{
vx->vararraylevel = var->vararraylevel + 1;
vx->vararraylist = var->vararraylist;
vx->vararray = TRUE;
vx->array = TRUE;
}
vx->type = var->type;
sprintf(vx->membername, "%s[%d]", var->membername, z++);
i += var->itemsize = DeclType(typetab, vx);
*nextptr = vx;
nextptr = &vx->link;
}
}
//-------------------------------------------------------------------------
void GetVararrayInfo(char *typetab, short *type, VARINFO *var)
{
int aa[100];
if (ReadValue(var->address + 4, aa, 4, &var->thread->regs) == 4)
{
ReadValue(var->address + 8, aa + 1, (aa[0] + 1) *4, &var->thread->regs);
}
else
aa[0] = 0;
if (aa[0] > 98)
aa[0] = 0;
ReadValue(var->address, &var->address, 4, &var->thread->regs);
var->vararraylisttofree = var->vararraylist = calloc((aa[0] + 2), sizeof
(int));
if (var->vararraylist)
memcpy(var->vararraylist, aa, (aa[0] + 2) *sizeof(int));
}
//-------------------------------------------------------------------------
void GetPointerInfo(char *typetab, VARINFO *v)
{
VARINFO *vx = calloc(sizeof(VARINFO), 1);
if (!vx)
return ;
v->subtype = vx;
vx->type = v->type;
vx->thread = v->thread;
sprintf(vx->membername, "*%s", v->membername);
DeclType(typetab, vx);
}
//-------------------------------------------------------------------------
int DeclType(char *typetab, VARINFO *v)
{
short *typeptr;
char *p;
if (v->vararray && v->vararraylist)
{
v->arraysize = v->vararraylist[v->vararraylevel + 1];
GetArrayInfo(typetab, typeptr, v);
return v->arraysize;
}
if (CV_IS_PRIMITIVE(v->type))
{
if (CV_TYP_IS_PTR(v->type))
{
v->pointer = TRUE;
v->type = CV_NEWMODE(v->type, CV_TM_DIRECT);
v->subtype = 0;
return 4;
}
return basictypesize(v->type);
}
typeptr = LookupType(typetab, v->type);
if (!typeptr)
return 0;
v->typetab = typeptr;
switch (typeptr[1])
{
case LF_POINTER:
v->pointer = TRUE;
v->type = ((lfPointer*)(typeptr + 1))->u.utype;
v->typetab = LookupType(typetab, v->type);
v->subtype = 0;
return 4;
case LF_ARRAY:
v->array = TRUE;
v->type = ((lfArray*)(typeptr + 1))->elemtype;
v->arraysize = GetNumericLeaf(&((lfArray*)(typeptr + 1))->data);
GetArrayInfo(typetab, typeptr, v);
return v->arraysize;
case LF_VARARRAY:
v->array = TRUE;
v->vararray = TRUE;
v->type = ((lfArray*)(typeptr + 1))->elemtype;
GetVararrayInfo(typetab, typeptr, v);
v->arraysize = DeclType(typetab, v);
return v->arraysize;
case LF_UNION:
v->unionx = TRUE;
GetStructInfo(typetab, typeptr, v);
v->arraysize = GetNumericLeaf(((lfUnion*)(typeptr + 1))->data);
p = (char*)(((lfUnion*)(typeptr + 1))->data) + GetNumericLeafSize((
(lfUnion*)(typeptr + 1))->data);
memcpy(v->structtag, p + 1, *p);
return GetNumericLeaf(((lfUnion*)(typeptr + 1))->data);
case LF_STRUCTURE:
case LF_CLASS:
v->structure = TRUE;
GetStructInfo(typetab, typeptr, v);
v->arraysize = GetNumericLeaf(((lfClass*)(typeptr + 1))->data);
p = (char*)(((lfClass*)(typeptr + 1))->data) + GetNumericLeafSize((
(lfClass*)(typeptr + 1))->data);
memcpy(v->structtag, p + 1, *p);
return GetNumericLeaf(((lfClass*)(typeptr + 1))->data);
case LF_ENUM:
v->enumx = TRUE;
v->type = ((lfEnum*)(typeptr + 1))->utype;
v->typetab = LookupType(typetab, ((lfEnum*)(typeptr + 1))->field);
p = (char*)(((lfEnum*)(typeptr + 1))->Name);
memcpy(v->structtag, p + 1, *p);
return basictypesize(v->type);
case LF_BITFIELD:
// Should only appear in structures
v->bitfield = TRUE;
v->bitstart = ((lfBitfield*)(typeptr + 1))->position;
v->bitlength = ((lfBitfield*)(typeptr + 1))->length;
v->type = ((lfBitfield*)(typeptr + 1))->type;
return 0;
}
return 0;
}
//-------------------------------------------------------------------------
VARINFO *GetVarInfo(DEBUG_INFO *dbg, char *typetab, char *symtab, int offset,
char *name, int ebp, THREAD *thread)
{
SYMTYPE *s = symtab + offset;
VARINFO *v = calloc(sizeof(VARINFO), 1);
if (!v)
return 0;
strcpy(v->membername, name);
v->thread = thread;
switch (s->rectyp)
{
case S_BPREL32:
v->address = ((BPRELSYM32*)s)->off + ebp;
v->type = ((BPRELSYM32*)s)->typind;
break;
case S_REGISTER:
v->inreg = TRUE;
v->outofscopereg = ebp != thread->regs.Ebp;
v->address = ((REGSYM*)s)->reg;
v->type = ((REGSYM*)s)->typind;
break;
case S_LDATA32:
case S_GDATA32:
v->address = ((DATASYM32*)s)->off + dbg->base;
v->type = ((DATASYM32*)s)->typind;
break;
case S_LPROC32:
case S_GPROC32:
v->address = ((PROCSYM32*)s)->off + dbg->base;
v->type = T_PVOID;
break;
case S_UDT:
v->udt = TRUE;
v->type = ((UDTSYM*)s)->typind;
v->address = 0;
break;
case S_LABEL32:
v->constant = TRUE;
v->type = T_PVOID;
v->ival = ((LABELSYM32*)s)->off + dbg->base;
break;
default:
free(v);
return 0;
}
DeclType(typetab, v);
return v;
}
//-------------------------------------------------------------------------
void FreeVarInfo(VARINFO *info)
{
while (info)
{
VARINFO *chain = info->link;
FreeVarInfo(info->subtype);
if (info->vararraylisttofree)
free(info->vararraylisttofree);
free(info);
info = chain;
}
}
//-------------------------------------------------------------------------
int ReadValue(int address, void *val, int size, CONTEXT *regs)
{
int len;
if (address < 0x1000 && regs)
{
// register
switch (address)
{
case CV_REG_AL:
*(char*)val = regs->Eax &0xff;
return 1;
case CV_REG_CL:
*(char*)val = regs->Ecx &0xff;
return 1;
case CV_REG_DL:
*(char*)val = regs->Edx &0xff;
return 1;
case CV_REG_BL:
*(char*)val = regs->Ebx &0xff;
return 1;
case CV_REG_AH:
*(char*)val = (regs->Eax >> 8) &0xff;
return 1;
case CV_REG_CH:
*(char*)val = (regs->Ecx >> 8) &0xff;
return 1;
case CV_REG_DH:
*(char*)val = (regs->Edx >> 8) &0xff;
return 1;
case CV_REG_BH:
*(char*)val = (regs->Ebx >> 8) &0xff;
return 1;
case CV_REG_AX:
*(short*)val = regs->Eax &0xffff;
return 2;
case CV_REG_CX:
*(short*)val = regs->Ecx &0xffff;
return 2;
case CV_REG_DX:
*(short*)val = regs->Edx &0xffff;
return 2;
case CV_REG_BX:
*(short*)val = regs->Ebx &0xffff;
return 2;
case CV_REG_SP:
*(short*)val = regs->Esp &0xffff;
return 2;
case CV_REG_BP:
*(short*)val = regs->Ebp &0xffff;
return 2;
case CV_REG_SI:
*(short*)val = regs->Esi &0xffff;
return 2;
case CV_REG_DI:
*(short*)val = regs->Edi &0xffff;
return 2;
case CV_REG_EAX:
*(int*)val = regs->Eax;
return 4;
case CV_REG_ECX:
*(int*)val = regs->Ecx;
return 4;
case CV_REG_EDX:
*(int*)val = regs->Edx;
return 4;
case CV_REG_EBX:
*(int*)val = regs->Ebx;
return 4;
case CV_REG_ESP:
*(int*)val = regs->Esp;
return 4;
case CV_REG_EBP:
*(int*)val = regs->Ebp;
return 4;
case CV_REG_ESI:
*(int*)val = regs->Esi;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -