//
Script.cpp: implementation of the CScript class.
//
//////////////////////////////////////////////////////////////////////
static char THIS_FILE[]=__FILE__;
typedef int (CScript::*PARSECMD)(int nCmd, TOKEN* argv[], int argc);
typedef struct _CMDDESC
{
const char* maincmd;
//
主命令名称
int argc;
//
参数数量,如果是-1,表示不确定可变
PARSECMD handler;
const char* help;
const char* usage;
}CMDDESC;
CMDDESC g_cmddesc[] =
{
{
"h"
, -1, CScript::CMD_Help},
{
"?"
, -1, CScript::CMD_Help},
{
"help"
, -1, CScript::CMD_Help},
{
"ver"
, 0, CScript::CMD_Ver,
"显示MDebug版本信息"
},
{
"exit"
, 0, CScript::CMD_exit,
"退出MDebug"
},
{
"cls"
, 0, CScript::CMD_CLS,
"清空输出窗口"
},
{
"sleep"
, 1, CScript::CMD_sleep,
"Sleep"
,
"Milliseconds"
},
{
"print"
, 1, CScript::CMD_PRINT,
"向输出窗口打印"
,
"expression"
},
{
"log"
, 1, CScript::CMD_PRINT,
"向输出窗口打印"
,
"expression"
},
{
"msg"
, 1, CScript::CMD_MSG,
"显示一个消息框"
,
"expression"
},
{
"YESNO"
, 1, CScript::CMD_YESNO,
"显示一个YES NO 选择消息框"
,
"expression"
},
{
"getstr"
, 0, CScript::CMD_getstr,
"显示一个对话框,要求用户输入字符串"
,},
{
"getint"
, 0, CScript::CMD_getint,
"显示一个对话框,要求用户输入一个16进制整数"
},
{
"findprocess"
, 1, CScript::CMD_findprocess,
"根据进程名称找进程的pid, 结果保存到result"
,
"process_name"
},
{
"loaddll"
, 1, CScript::CMD_loaddll,
"向被调试进程远程加载dll"
,
"dllname"
},
{
"alloc"
, 1, CScript::CMD_alloc,
"向被调试进程分配内存,result 保存分配的内存地址"
,
"size"
},
{
"readdata"
, 2, CScript::CMD_readdata,
"读内存数据,并将结果保存到result中"
,
"addr, size"
},
{
"readstr"
, 1, CScript::CMD_readstr,
"读内存中的字符串,并将结果保存到result中"
,
"addr"
},
{
"readwstr"
, 1, CScript::CMD_readwstr,
"读内存中的unicode字符串,并将结果保存到result中"
,
"addr"
},
{
"openfile"
, -1,CScript::CMD_openfile,
"打开PE文件进行调试,即使用户在选项中没有选择“打开PE文件后立即开始调试”,openfile指令也会立即开始调试"
,
"filepath [,param]"
},
{
"stop"
, 0, CScript::CMD_stop,
"停止调试"
},
{
"pause"
, 0, CScript::CMD_pause,
"暂停调试"
},
{
"restart"
, 0, CScript::CMD_restart,
"重新开始调试"
},
{
"dettach"
, 0, CScript::CMD_dettach,
"脱离调试运行"
},
{
"attach"
, 1, CScript::CMD_attach,
"attach 活动进程"
,
"processid"
},
{
"g"
, -1,CScript::CMD_run,
"开始调试或运行"
,
"[,addr]"
},
{
"run"
, -1,CScript::CMD_run,
"开始调试或运行"
,
"[,addr]"
},
{
"t"
, 0, CScript::CMD_t,
"单步进入"
},
{
"p"
, 0, CScript::CMD_p,
"单步跳过"
},
{
"gret"
, 0, CScript::CMD_gret,
"运行到返回处"
},
//
运行到返回处
{
"gout"
, 0, CScript::CMD_gret,
"运行到返回处"
},
//
运行到返回处
{
"GetModuleBase"
, 1, CScript::CMD_GetModuleBase,
"取被调试进程的特定模块的基地址,将结果保存到result"
,
"modulename"
},
{
"GetModuleSize"
, 1, CScript::CMD_GetModuleSize,
"取被调试进程的特定模块的大小,将结果保存到result"
,
"modulename"
},
{
"bc"
, 1, CScript::CMD_bc,
"删除断点"
,
"addr / *"
},
{
"bp"
, -1,CScript::CMD_bp,
"设置断点"
,
"addr [,\"condition\"]"
},
{
"bph"
, 1, CScript::CMD_bph,
"设置硬件执行断点"
,
"addr"
},
{
"bphr"
, -1,CScript::CMD_bphr,
"设置硬件读内存断点"
,
"addr [,len]"
},
{
"bphw"
, -1,CScript::CMD_bphw,
"设置硬件写内存断点"
,
"addr [,len]"
},
{
"strlen"
, 1, CScript::CMD_strlen,
"计算字符串长度,并将结果保存到result"
,
"expression"
},
{
"strcat"
, 2, CScript::CMD_strcat,
"字符串连接,strcat 的第一个参数必须是变量"
,
"dst, src"
},
{
"strcmp"
, 2, CScript::CMD_strcmp,
"字符串比较,并将比较结果保存到result中。如果相同,result值=0"
,
"str1, str2"
},
{
"strcmpi"
, 2, CScript::CMD_strcmpi,
"字符串比较(忽略大小写),并将比较结果保存到result中。如果相同,result值=0"
,
"str1, str2"
},
{
"strstr"
, 2, CScript::CMD_strstr,
"字符串查找,并将查找到的结果保存到result中。result保存的是匹配到的第一个字符串"
,
"str1, str2"
},
{
"strstri"
, 2, CScript::CMD_strstri,
"字符串查找(忽略大小写),并将查找到的结果保存到result中。result保存的是匹配到的第一个字符串"
,
"str1, str2"
},
{
"strupr"
, 1, CScript::CMD_strupr,
"将字符串转换为大写, 参数必须是变量"
,
"str"
},
{
"strlwr"
, 1, CScript::CMD_strlwr,
"将字符串转换为小写, 参数必须是变量"
,
"str"
},
};
char* g_reservedword[] =
{
"if"
,
"while"
,
"var"
,
"result"
,
"break"
,
"continue"
};
CVariant::CVariant()
{
memset(m_szVarName, 0, VARNAMESIZE);
m_type = MYVARIANT_EMPTY;
m_nDataSize = 0;
m_value = 0;
}
CVariant::CVariant(const char* pszVarName)
{
memset(m_szVarName, 0, VARNAMESIZE);
m_type = MYVARIANT_EMPTY;
m_nDataSize = 0;
m_value = 0;
strncpy(m_szVarName, pszVarName, VARNAMESIZE);
}
CVariant::~CVariant()
{
Release();
}
void CVariant::SetInt(unsigned __int64
v
)
{
ASSERT(m_type == MYVARIANT_EMPTY);
m_value =
v
;
m_type = MYVARIANT_INT;
}
void CVariant::SetAnsiString(const char* str)
{
ASSERT(m_type == MYVARIANT_EMPTY);
ASSERT(str != NULL);
int len = strlen(str);
m_str = new char[len+2];
if
(m_str != NULL)
{
strcpy(m_str, str);
m_type = MYVARIANT_STR;
}
}
void CVariant::SetUnicodeString(const char* str)
{
ASSERT(m_type == MYVARIANT_EMPTY);
ASSERT(str != NULL);
int len = 10 + MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
m_wstr = new WCHAR[len];
if
(m_wstr != NULL)
{
memset(m_wstr, 0, len*sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, str, -1, m_wstr, len);
m_type = MYVARIANT_WCHAR;
}
}
void CVariant::SetUnicodeString2(const WCHAR* wstr)
{
ASSERT(m_type == MYVARIANT_EMPTY);
ASSERT(wstr != NULL);
int len = 2 + wcslen(wstr);
m_wstr = new WCHAR[len];
if
(m_wstr != NULL)
{
wcscpy(m_wstr, wstr);
m_type = MYVARIANT_WCHAR;
}
}
void CVariant::SetUnicodeStringToAnsiString(const WCHAR* wstr)
{
int len = 2 + WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
m_str = new char[len];
if
(m_str != NULL)
{
memset(m_str, 0, len);
WideCharToMultiByte(CP_ACP, 0, wstr, -1, m_str, len, NULL,NULL);
m_type = MYVARIANT_STR;
}
}
void CVariant::SetHexBytes(BYTE* pData, int len)
{
ASSERT(pData != NULL);
ASSERT(m_type == MYVARIANT_EMPTY);
m_pdata = new BYTE[len];
if
(m_pdata != NULL)
{
memcpy(m_pdata, pData, len);
m_type = MYVARIANT_BYTES;
m_nDataSize = len;
}
}
//
= 操作
void CVariant::Assign(const CVariant* pvar)
{
ASSERT(pvar != NULL);
Release();
m_type = pvar->m_type;
m_nDataSize = pvar->m_nDataSize;
strcpy(m_szVarName, pvar->m_szVarName);
if
(m_type == MYVARIANT_INT)
{
m_value = pvar->m_value;
}
else
if
(m_type == MYVARIANT_WCHAR)
{
m_wstr = new WCHAR[wcslen(pvar->m_wstr) + 1];
wcscpy(m_wstr, pvar->m_wstr);
}
else
if
(m_type == MYVARIANT_STR)
{
m_str = new char[strlen(pvar->m_str) + 1];
strcpy(m_str, pvar->m_str);
}
else
if
(m_type == MYVARIANT_BYTES)
{
m_pdata = new BYTE[m_nDataSize+2];
memcpy(m_pdata, pvar->m_pdata, m_nDataSize);
}
else
if
(m_type == MYVARIANT_EMPTY)
{
m_value = 0;
}
else
{
ASSERT(0);
m_value = 0;
}
}
void CVariant::Release()
{
if
(m_type == MYVARIANT_STR)
{
delete[] m_str;
m_str = NULL;
}
else
if
(m_type == MYVARIANT_WCHAR)
{
delete[] m_wstr;
m_wstr = NULL;
}
else
if
(m_type == MYVARIANT_BYTES)
{
delete[] m_pdata;
m_pdata = NULL;
}
else
{
}
m_type = MYVARIANT_EMPTY;
m_value = 0;
}
//////////////////////////////////////////////////////////////////////
//
Construction
/Destruction
//////////////////////////////////////////////////////////////////////
CScript::CScript()
{
m_pDebugThread = &((CVDebugApp*)AfxGetApp())->m_DebugThread;
m_pszCopy = NULL;
m_pLines = NULL;
m_nLines = 0;
m_pbRunning = NULL;
m_pbDebugging = NULL;
m_bIsCmdLine = TRUE;
m_phEvent = NULL;
m_phDebugEvent = NULL;
m_pScriptView = NULL;
m_result.SetName(
"result"
);
m_errLine = -1;
m_MemExpression.m_pScript = this;
m_pApp = (CVDebugApp*)AfxGetApp();
m_pMainframe = (CMainFrame*)m_pApp->m_pMainWnd;
ASSERT(m_pMainframe != NULL);
}
CScript::~CScript()
{
if
(m_pszCopy != NULL)
delete[] m_pszCopy;
if
(m_pLines!=NULL)
{
for
(int i=0; i<m_nLines; i++)
{
ReleaseTokenChain(m_pLines[i].pHead);
}
delete[] m_pLines;
}
POSITION pos = m_varList.GetHeadPosition();
while
(pos != NULL)
{
CVariant* pv = m_varList.GetNext(pos);
delete pv;
}
m_varList.RemoveAll();
m_result.Release();
pos = m_ifwhile.GetHeadPosition();
while
(pos != NULL)
{
IF_WHILE_BRACE* pifwhile = m_ifwhile.GetNext(pos);
delete pifwhile;
}
m_ifwhile.RemoveAll();
}
int CScript::GetLineCount(const char *pszScript)
{
int nLines = 0;
char* p = (char*)pszScript;
while
(1)
{
if
(*p ==
'\n'
|| *p == 0)
nLines++;
if
(*p == 0)
break
;
p++;
}
return
nLines;
}
/*
寻找下一个双引号, 引号前面不能为\
如果没有找到,返回 NULL, 否则返回引号后的下一个字符开头的字符串
如果是
"\\...\\"
...
*/
const char* CScript::FindNextDoubleQuote(const char *pszText)
{
ASSERT(pszText != NULL);
char* t = (char*)pszText;
char* pret = NULL;
while
(*t != 0)
{
if
(*t ==
'\\'
)
{
t+=2;
}
else
if
(*t ==
'\"'
)
{
pret = t+1;
break
;
}
else
{
t++;
}
}
return
pret;
/*
char* t = strchr(pszText,
'"'
);
while
(t != NULL && t[-1] ==
'\\'
)
{
t = strchr(t+1,
'"'
);
}
return
(t == NULL) ? NULL : t+1;
*/
}
/*
去掉注释, 将注释部分换成空格
如果是
" "
内有注释符号,就不能去掉
注释包括
//
, /* * /
*/
void CScript::DeleteComment(IN OUT char *pszBuff, int nLen)
{
char* pszStart = pszBuff;
while
(*pszStart != 0)
{
if
(pszStart[0] ==
'\"'
&& pszStart[-1] !=
'\\'
)
{
//
找下一个 "
const char* t = FindNextDoubleQuote(pszStart+1);
if
(t == NULL)
{
break
;
//
语法不通?
}
pszStart = (char*)t;
}
else
if
(pszStart[0] ==
'/'
&& pszStart[1] ==
'/'
)
{
while
(pszStart[0] !=
'\r'
&& pszStart[0] !=
'\n'
&& pszStart[0] != 0)
{
pszStart[0] =
' '
;
pszStart++;
}
}
else
if
(pszStart[0] ==
'/'
&& pszStart[1] ==
'*'
)
{
char* t = strstr(pszStart+2,
"*/"
);
if
(t == NULL)
{
break
;
//
语法不通?
}
t+=2;
for
(;pszStart<t; pszStart++)
{
//
如果是 换行 就不去掉
if
(pszStart[0] !=
'\r'
&& pszStart[0] !=
'\n'
)
{
pszStart[0] =
' '
;
}
}
}
else
{
pszStart++;
}
}
}
void CScript::SaveToLines(char *pszStr)
{
int nLines = 0;
char* p = (char*)pszStr;
m_pLines[nLines].pszLine = p;
while
(1)
{
if
(*p == 0)
break
;
if
(*p ==
'\n'
|| *p == 0)
{
*p = 0;
nLines++;
m_pLines[nLines].pszLine = p+1;
}
p++;
}
//
去掉最后的 ;
}
/*
从当前的token移到当前token结束
*/
char* CScript::MoveToTokenEnd(char* p)
{
ASSERT(p != NULL);
ASSERT(!CHAR_ISEND(*p));
ASSERT(!CHAR_ISBLANK(*p));
if
(!ISFULLWORDCHAR(*p))
{
if
(*p ==
'\"'
|| *p ==
'\''
)
{
if
(*p ==
'\"'
)
{
char* x = (char*)FindNextDoubleQuote(p+1);
if
(x == NULL)
{
m_sErrInfo =
"字符串缺少\""
;
}
return
x;
}
else
{
char* x = strchr(p+1,
'\''
);
if
(x == NULL)
{
m_sErrInfo =
"字符符号缺少\'"
;
return
NULL;
}
return
x+1;
}
}
return
p+1;
}
while
(ISFULLWORDCHAR(*p))
{
p++;
}
return
p;
}
//
插入到最后
void CScript::AddNewToken(LINE* pLine, TOKEN* pToken)
{
if
(pLine->pHead == NULL)
{
//
还没有
pToken->pNext = pToken->pPrev = NULL;
pLine->pHead = pLine->pTail = pToken;
}
else
if
(pLine->pHead == pLine->pTail)
{
//
只有一个
pLine->pTail = pToken;
pToken->pNext = NULL;
pToken->pPrev = pLine->pHead;
pLine->pHead->pNext = pToken;
}
else
{
pToken->pNext = NULL;
pLine->pTail->pNext = pToken;
pToken->pPrev = pLine->pTail;
pLine->pTail = pToken;
}
}
/*
读取脚本语句的每个token
连续的词: _,$,数字,字母
分隔:空格,tab
*/
int CScript::InitLineToken(LINE* pLine)
{
ASSERT(pLine->pszLine != NULL);
char* p = (char*)pLine->pszLine;
SKIPBLANK(p);
if
(CHAR_ISEND(*p))
return
0;
while
(1)
{
SKIPBLANK(p);
if
(CHAR_ISEND(*p))
break
;
char* pnext = MoveToTokenEnd(p);
if
(pnext == NULL)
{
return
-1;
}
TOKEN* tk = new TOKEN;
memset(tk, 0, sizeof(TOKEN));
tk->pszToken = new char[pnext-p + 1];
strncpy(tk->pszToken, p, pnext-p);
tk->pszToken[pnext-p] = 0;
AddNewToken(pLine, tk);
p = pnext;
}
return
0;
}
int CScript::GetTokenCount(const TOKEN* pTokenHead)
{
int i = 0;
TOKEN* p = (TOKEN*)pTokenHead;
while
(p != NULL)
{
p = p->pNext;
i++;
}
return
i;
}
//
判断是否是关键字
BOOL CScript::IsReservedWord(const char* str)
{
//
是否是命令
for
(int i=0;i<sizeof(g_cmddesc)
/sizeof
(g_cmddesc[0]); i++)
{
if
(strcmpi(g_cmddesc[i].maincmd, str) == 0)
{
return
TRUE;
}
}
//
是否是寄存器
if
(m_MemExpression.IsValidRegString(str) || m_MemExpression.IsValidRegString2(str))
{
return
TRUE;
}
//
其他关键字
for
(i=0;i<sizeof(g_reservedword)
/sizeof
(g_reservedword[0]); i++)
{
if
(strcmpi(g_reservedword[i], str) == 0)
{
return
TRUE;
}
}
return
FALSE;
}
/*
判断变量名称是否合法
如果合法, pbIsReservedName 保存是否是reserved名称
必须字母或_开头
*/
BOOL CScript::IsValidVarDeclare(const char* pszVarName, OUT BOOL* pbIsReservedName)
{
ASSERT(pszVarName != NULL);
ASSERT(pszVarName[0] != 0);
ASSERT(pbIsReservedName != NULL);
*pbIsReservedName = FALSE;
if
(CHAR_ISCHAR(pszVarName[0]) || pszVarName[0] ==
'_'
)
{
char* p = (char*)pszVarName+1;
while
(*p)
{
if
(CHAR_ISCHAR(*p) || CHAR_ISDIGIT(*p) || *p ==
'_'
)
{
}
else
{
return
FALSE;
}
p++;
}
//
判断是否是保留字
//
if
(IsReservedWord(pszVarName))
{
*pbIsReservedName = TRUE;
return
FALSE;
}
return
TRUE;
}
return
FALSE;
}
/*
将字符串
"...."
转为字符串,去掉2边的 "
*/
char* CScript::String2String(const char* str)
{
ASSERT(str != NULL);
ASSERT(str[0] ==
'\"'
);
char* pEnd = (char*)FindNextDoubleQuote(str+1);
if
(pEnd == NULL)
return
NULL;
int nMaxLen = pEnd - str +2;
char* pBuff = new char[nMaxLen];
if
(pBuff == NULL)
return
NULL;
memset(pBuff, 0, nMaxLen);
int c = 0;
char* p = (char*)str + 1;
while
(p < pEnd-1)
{
if
(p[0] ==
'\\'
&& p[1] ==
'\"'
)
{
pBuff[c++] =
'\"'
;
p+=2;
}
else
{
pBuff[c++] = *p;
p++;
}
}
return
pBuff;
}
/*
将字符串
"aabbccdd..."
转为16进制字符串,去掉2边的 "
如果不是2的倍数,就在前面加0
*/
BYTE* CScript::String2HexBytes(const char* str, OUT int* plen)
{
ASSERT(str != NULL);
ASSERT(str[0] ==
'\"'
);
char* pEnd = (char*)FindNextDoubleQuote(str+1);
if
(pEnd == NULL)
return
NULL;
int nMax = (pEnd - 1) - (str+1);
if
(nMax < 0)
return
NULL;
BYTE* pData = new BYTE[nMax];
if
(pData == NULL)
return
NULL;
memset(pData, 0, nMax);
int c = 0;
char* p = (char*)str + 1;
if
(nMax % 2)
{
if
(!CHAR_ISHEXCHAR(p[0]))
{
delete[] pData;
return
NULL;
}
BYTE x = TOHEXCHAR(toupper(*p));
pData[c++] = x;
p++;
}
while
(p < pEnd-1)
{
char c1 = toupper(*p);
p++;
char c2 = toupper(*p);
p++;
if
(!CHAR_ISHEXCHAR(c1) || !CHAR_ISHEXCHAR(c2))
{
delete[] pData;
return
NULL;
}
BYTE b1 = TOHEXCHAR(c1);
BYTE b2 = TOHEXCHAR(c2);
pData[c++] = (b1 << 4) | b2;
}
*plen = c;
return
pData;
}
/*判断是不是
exp1 X exp2 的形式
X 表示:
>
<
!=
==
>=
<=
<<
>>
*/
/*
BOOL CScript::ParseExtraExpression(const char* str, OUT DWORD* pdwValue)
{
ASSERT(str != NULL);
ASSERT(pdwValue != NULL);
char* p = (char*)str;
while
(*p)
{
if
(*p ==
'>'
|| *p ==
'<'
|| *p ==
'!'
|| *p ==
'='
)
break
;
p++;
}
if
(*p == 0 || p == str || p[1] == 0)
//
在第一个或最后一个或没有找到
return
FALSE;
const char* poper = p;
char* pright = p;
if
(*p ==
'='
|| *p ==
'<'
|| *p ==
'>'
)
pright++;
if
(pright[0] == 0)
return
FALSE;
DWORD dwLeft = 0;
DWORD dwRight = 0;
CString sLeft(str, poper-str);
if
(!m_MemExpression.ParseExpression(sLeft, &dwLeft))
return
FALSE;
if
(!m_MemExpression.ParseExpression(pright, &dwRight))
return
FALSE;
if
(poper[0] ==
'<'
&& poper[1] ==
'<'
)
{
*pdwValue = (dwLeft << dwRight);
}
else
if
(poper[0] ==
'>'
&& poper[1] ==
'>'
)
{
*pdwValue = (dwLeft >> dwRight);
}
else
if
(poper[0] ==
'>'
&& poper[1] ==
'='
)
{
*pdwValue = (dwLeft >= dwRight);
}
else
if
(poper[0] ==
'<'
&& poper[1] ==
'='
)
{
*pdwValue = (dwLeft <= dwRight);
}
else
if
(poper[0] ==
'='
&& poper[1] ==
'='
)
{
*pdwValue = (dwLeft == dwRight);
}
else
if
(poper[0] ==
'!'
&& poper[1] ==
'='
)
{
*pdwValue = (dwLeft != dwRight);
}
else
if
(poper[0] ==
'>'
)
{
*pdwValue = (dwLeft > dwRight);
}
else
if
(poper[0] ==
'<'
)
{
*pdwValue = (dwLeft < dwRight);
}
else
{
ASSERT(0);
*pdwValue = 0;
}
return
TRUE;
}
*/
/*
pToken开始的列表是否是普通表达式?如果是,返回1 , pdwValue保存值
*/
BOOL CScript::ParseNormalTokenExpression(const TOKEN* pToken, OUT DWORD* pdwValue, OUT CString* pErrmsg)
{
ASSERT(pToken!=NULL);
ASSERT(pdwValue!=NULL);
//
if
(!m_pDebugThread->IsDebugging())
//
{
//
return
FALSE;
//
}
int nBuffer = 0;
TOKEN* t = (TOKEN*)pToken;
while
(t != NULL)
{
nBuffer += (strlen(t->pszToken) + 4);
t = t->pNext;
}
char* str = new char[nBuffer];
if
(str == NULL)
return
NULL;
memset(str, 0, nBuffer);
t = (TOKEN*)pToken;
while
(t != NULL)
{
strcat(str, t->pszToken);
//
如果是非符号类的,在token后面加空格
char ch = t->pszToken[0];
if
(CHAR_ISCHAR(ch) || CHAR_ISDIGIT(ch) || ch ==
'_'
)
{
strcat(str,
" "
);
}
t = t->pNext;
}
DWORD dwAddr;
if
(m_MemExpression.ParseExpression(str, &dwAddr)/* ||
(dwAddr = m_MemExpression.GetModuleStruFromFunctionName(str)) != 0*/)
{
delete[] str;
str = NULL;
*pdwValue = dwAddr;
return
TRUE;
}
else
{
/*
if
(ParseExtraExpression(str, pdwValue))
{
delete[] str;
str = NULL;
return
TRUE;
}
*/
if
(pErrmsg != NULL)
{
*pErrmsg = m_MemExpression.m_szErrinfo;
}
}
delete[] str;
str = NULL;
return
FALSE;
}
const CVariant* CScript::SearchVariant(const char* pszVarName)
{
ASSERT(pszVarName != NULL);
POSITION pos = m_varList.GetHeadPosition();
while
(pos != NULL)
{
CVariant* pv = m_varList.GetNext(pos);
if
(strcmpi(pv->GetVarName(), pszVarName) == 0)
{
return
pv;
}
}
//
判断是否是内部变量
if
(strcmpi(pszVarName,
"result"
) == 0)
{
return
&m_result;
}
return
NULL;
}
CVariant** CScript::GetAllVariant(OUT int* count)
{
int c = m_varList.GetCount() + 1;
CVariant** p = new CVariant*[c];
int i=0;
POSITION pos = m_varList.GetHeadPosition();
while
(pos != NULL)
{
CVariant* pv = m_varList.GetNext(pos);
p[i++] = pv;
}
p[i] = &m_result;
*count = c;
return
p;
}
/*
token是表达式,可以是以下形式:
'...'
"string"
L
"string"
H
"xxyyzz"
其他var名称
普通表达式 / api名称
如果合法,返回 CVariant*
*/
CVariant* CScript::TokenToVariant(const TOKEN* pToken, OUT CString* pErrmsg)
{
ASSERT(pToken != NULL);
ASSERT(pToken->pszToken != NULL);
ASSERT(pToken->pszToken[0]);
DWORD dwValue = 0;
CVariant* tmpvar = NULL;
int nTokens = GetTokenCount(pToken);
char cbFirst = pToken->pszToken[0];
if
(cbFirst ==
'\''
&& nTokens == 1)
{
//
'...'
, 里面最多取8位
ASSERT(strchr(pToken->pszToken + 1,
'\''
) != NULL);
if
(nTokens != 1)
return
NULL;
unsigned __int64
v
= 0;
char* p = pToken->pszToken+1;
if
(*p ==
'\''
)
return
NULL;
while
(*p != 0 && *p !=
'\''
)
{
v
<<= 8;
BYTE c = *p;
v
|= c;
p++;
}
CVariant* pv = new CVariant;
pv->SetInt(
v
);
return
pv;
}
else
if
(cbFirst ==
'\"'
)
{
//
"..."
ansi字符串
ASSERT(strchr(pToken->pszToken + 1,
'\"'
) != NULL);
if
(nTokens != 1)
return
NULL;
char* str = String2String(pToken->pszToken);
if
(str == NULL)
return
NULL;
CVariant* pv = new CVariant;
pv->SetAnsiString(str);
delete[] str;
return
pv;
}
else
if
(cbFirst ==
'L'
&&
nTokens == 2 &&
GetNextToken((TOKEN*)pToken)->pszToken[0] ==
'\"'
)
//L
本身可以作为变量名称
{
//L
"..."
unicode 字符串
TOKEN* tk = GetNextToken((TOKEN*)pToken);
char* str = String2String(tk->pszToken);
if
(str == NULL)
return
NULL;
CVariant* pv = new CVariant;
pv->SetUnicodeString(str);
delete[] str;
return
pv;
}
else
if
(cbFirst ==
'H'
&&
nTokens == 2 &&
GetNextToken((TOKEN*)pToken)->pszToken[0] ==
'\"'
)
//L
本身可以作为变量名称
{
//H
"..."
HEX 字符串
TOKEN* tk = GetNextToken((TOKEN*)pToken);
int len = 0;
BYTE* pData = String2HexBytes(tk->pszToken, &len);
if
(pData == NULL)
return
NULL;
CVariant* pv = new CVariant;
pv->SetHexBytes(pData, len);
delete[] pData;
return
pv;
}
else
if
(nTokens == 1 && (tmpvar = (CVariant*)SearchVariant(pToken->pszToken)))
{
//
var xx
//
var yy = xx;
CVariant* pv = new CVariant;
pv->Assign(tmpvar);
return
pv;
}
else
if
(pToken->pNext == NULL && CHAR_ISDIGIT(pToken->pszToken[0]) && m_MemExpression.IsValidDigitString(pToken->pszToken))
{
//16
进制数据
DWORD
v
;
sscanf(pToken->pszToken,
"%x"
, &
v
);
CVariant* pv = new CVariant;
pv->SetInt(
v
);
return
pv;
}
else
if
(ParseNormalTokenExpression(pToken, &dwValue, pErrmsg))
{
//
普通表达式(就是内存地址框中的表达式)
CVariant* pv = new CVariant;
pv->SetInt(dwValue);
return
pv;
}
else
{
}
return
NULL;
}
/*
判断是否是var定义
pbValid: 如果是var定义,保存 var = 后面的表达式是否合法
var定义规则:
var xxx
var xxx = yyy
*/
BOOL CScript::TokenIs_VarDeclare(const TOKEN* pTokenHead, int nTokens, OUT BOOL* pbValid)
{
ASSERT(pTokenHead != NULL);
ASSERT(nTokens > 0);
*pbValid = FALSE;
TOKEN* k = (TOKEN*)pTokenHead;
if
(strcmpi(k->pszToken,
"var"
) == 0)
{
//var
...
k = k->pNext;
if
(k != NULL)
{
//var
xxx ...
//
变量名称
BOOL bIsReservedName = FALSE;
if
(IsValidVarDeclare(k->pszToken, &bIsReservedName))
{
const char* pszVarName = k->pszToken;
//
判断是否已经定义
if
(SearchVariant(pszVarName) != NULL)
{
m_sErrInfo.Format(
"\'%s\' 已定义"
, pszVarName);
return
TRUE;
}
k = k->pNext;
//
可能是var xxx
if
(k == NULL)
{
*pbValid = TRUE;
//
加入列表
CVariant* pvar = new CVariant(pszVarName);
m_varList.AddTail(pvar);
return
TRUE;
//var
xxx
}
//
必须是 var xxx =
if
(k->pszToken[0] ==
'='
&& k->pszToken[1] == 0)
{
k = k->pNext;
//var
xxx = ...
if
(k != NULL)
{
CString sErrmsg2;
CVariant* ptmpvar = TokenToVariant(k, &sErrmsg2);
if
(ptmpvar != NULL)
{
*pbValid = TRUE;
//
加入列表
CVariant* pvar = new CVariant;
pvar->Assign(ptmpvar);
pvar->SetName(pszVarName);
m_varList.AddTail(pvar);
delete ptmpvar;
return
TRUE;
}
else
{
m_sErrInfo =
"赋值表达式错误"
;
if
(!sErrmsg2.IsEmpty())
{
m_sErrInfo +=
"\r\n"
;
m_sErrInfo += sErrmsg2;
}
}
}
else
{
//var
xxx =
m_sErrInfo =
"语法错误"
;
}
}
else
{
m_sErrInfo =
"语法错误"
;
}
}
else
{
if
(bIsReservedName)
m_sErrInfo.Format(
"变量 '%s' 是关键字"
, k->pszToken);
else
m_sErrInfo =
"变量名称不合法"
;
}
}
else
{
m_sErrInfo =
"语法错误"
;
}
return
TRUE;
}
return
FALSE;
}
const TOKEN* CScript::SearchToken(const TOKEN* pToken, const char* pszToken)
{
ASSERT(pszToken != NULL);
ASSERT(pToken!=NULL);
TOKEN* t = (TOKEN*)pToken;
while
(t != NULL)
{
if
(strcmp(t->pszToken, pszToken) == 0)
{
return
t;
}
t = t->pNext;
}
return
NULL;
}
TOKEN* CScript::AllocNewToken(const char* pszToken)
{
TOKEN* p = new TOKEN;
p->pNext = p->pPrev = NULL;
p->pszToken = NULL;
if
(pszToken != NULL)
{
p->pszToken = new char[strlen(pszToken) + 2];
strcpy(p->pszToken, pszToken);
}
return
p;
}
/*
复制token链, 不包括pTokenEnd
*/
TOKEN* CScript::CopyTokenChain(const TOKEN* pTokenStart, const TOKEN* pTokenEnd)
{
ASSERT(pTokenEnd != NULL);
ASSERT(pTokenStart != NULL);
LINE virtualline;
virtualline.pHead = NULL;
virtualline.pTail = NULL;
virtualline.pszLine = NULL;
TOKEN* p = (TOKEN*)pTokenStart;
while
(p != NULL && p != pTokenEnd)
{
TOKEN* t = AllocNewToken(p->pszToken);
AddNewToken(&virtualline, t);
p = p->pNext;
}
return
virtualline.pHead;
}
TOKEN* CScript::CloneTokenChain(const TOKEN* pTokenStart)
{
ASSERT(pTokenStart != NULL);
LINE virtualline;
virtualline.pHead = NULL;
virtualline.pTail = NULL;
virtualline.pszLine = NULL;
TOKEN* p = (TOKEN*)pTokenStart;
while
(p != NULL)
{
TOKEN* t = AllocNewToken(p->pszToken);
AddNewToken(&virtualline, t);
p = p->pNext;
}
return
virtualline.pHead;
}
void CScript::ReleaseTokenChain(TOKEN* pToken)
{
while
(pToken != NULL)
{
if
(pToken->pszToken != NULL)
{
delete[] pToken->pszToken;
pToken->pszToken = NULL;
}
TOKEN* t = pToken;
pToken = pToken->pNext;
delete t;
}
}
/*
(E)AX
(E)BX
(E)CX
(E)DX
(E)SI
(E)DI
(E)SP
(E)BP
EIP
AL AH
BL BH
CL CH
DL DH
*/
void CScript::SetRegValue(const char* pszRegName, DWORD dwValue)
{
ASSERT(pszRegName != NULL);
ASSERT(m_MemExpression.IsValidRegString(pszRegName) || m_MemExpression.IsValidRegString2(pszRegName));
int len = strlen(pszRegName);
if
(len != 2 && len != 3)
{
ASSERT(0);
return
;
}
CONTEXT con;
if
(!m_pDebugThread->SingleDebugGetThreadContext(m_pDebugThread->GetCurrentSingleDebuggingThreadID(), &con))
return
;
char ch1 = tolower(pszRegName[0]);
char ch2 = tolower(pszRegName[1]);
char ch3 = tolower(pszRegName[2]);
char ch4 = tolower(pszRegName[3]);
if
(ch1 ==
'e'
)
{
//32bits
if
(ch2 ==
'a'
&& ch3 ==
'x'
)
{
con.Eax = dwValue;
}
else
if
(ch2 ==
'b'
&& ch3 ==
'x'
)
{
con.Ebx = dwValue;
}
else
if
(ch2 ==
'c'
&& ch3 ==
'x'
)
{
con.Ecx = dwValue;
}
else
if
(ch2 ==
'd'
&& ch3 ==
'x'
)
{
con.Edx = dwValue;
}
else
if
(ch2 ==
's'
&& ch3 ==
'i'
)
{
con.Esi = dwValue;
}
else
if
(ch2 ==
'd'
&& ch3 ==
'i'
)
{
con.Edi = dwValue;
}
else
if
(ch2 ==
's'
&& ch3 ==
'p'
)
{
con.Esp = dwValue;
}
else
if
(ch2 ==
'b'
&& ch3 ==
'p'
)
{
con.Ebp = dwValue;
}
else
if
(ch2 ==
'i'
&& ch3 ==
'p'
)
{
con.Eip = dwValue;
}
else
{
}
}
else
if
(ch2 ==
'l'
|| ch2 ==
'h'
)
{
//8bits
if
(ch1 ==
'a'
&& ch2 ==
'l'
)
{
con.Eax &= 0xFFFFFF00;
con.Eax |= (dwValue & 0xff);
}
if
(ch1 ==
'b'
&& ch2 ==
'l'
)
{
con.Ebx &= 0xFFFFFF00;
con.Ebx |= (dwValue & 0xff);
}
if
(ch1 ==
'c'
&& ch2 ==
'l'
)
{
con.Ecx &= 0xFFFFFF00;
con.Ecx |= (dwValue & 0xff);
}
if
(ch1 ==
'd'
&& ch2 ==
'l'
)
{
con.Edx &= 0xFFFFFF00;
con.Edx |= (dwValue & 0xff);
}
if
(ch1 ==
'a'
&& ch2 ==
'h'
)
{
con.Eax &= 0xFFFF00FF;
con.Eax |= ((dwValue<<8) & 0x0000FF00);
}
if
(ch1 ==
'b'
&& ch2 ==
'h'
)
{
con.Ebx &= 0xFFFF00FF;
con.Ebx |= ((dwValue<<8) & 0x0000FF00);
}
if
(ch1 ==
'c'
&& ch2 ==
'h'
)
{
con.Ecx &= 0xFFFF00FF;
con.Ecx |= ((dwValue<<8) & 0x0000FF00);
}
if
(ch1 ==
'd'
&& ch2 ==
'h'
)
{
con.Edx &= 0xFFFF00FF;
con.Edx |= ((dwValue<<8) & 0x0000FF00);
}
}
else
{
//16
bits
if
(ch1 ==
'a'
&& ch2 ==
'x'
)
{
con.Eax &= 0xFFFF0000;
con.Eax |= (WORD)dwValue;
}
if
(ch1 ==
'b'
&& ch2 ==
'x'
)
{
con.Ebx &= 0xFFFF0000;
con.Ebx |= (WORD)dwValue;
}
if
(ch1 ==
'c'
&& ch2 ==
'x'
)
{
con.Ecx &= 0xFFFF0000;
con.Ecx |= (WORD)dwValue;
}
if
(ch1 ==
'd'
&& ch2 ==
'x'
)
{
con.Edx &= 0xFFFF0000;
con.Edx |= (WORD)dwValue;
}
if
(ch1 ==
's'
&& ch2 ==
'i'
)
{
con.Esi &= 0xFFFF0000;
con.Esi |= (WORD)dwValue;
}
if
(ch1 ==
'd'
&& ch2 ==
'i'
)
{
con.Edi &= 0xFFFF0000;
con.Edi |= (WORD)dwValue;
}
if
(ch1 ==
's'
&& ch2 ==
'p'
)
{
con.Esp &= 0xFFFF0000;
con.Esp |= (WORD)dwValue;
}
if
(ch1 ==
'b'
&& ch2 ==
'p'
)
{
con.Ebp &= 0xFFFF0000;
con.Ebp |= (WORD)dwValue;
}
}
m_pDebugThread->SingleDebugSetThreadContext(m_pDebugThread->GetCurrentSingleDebuggingThreadID(), &con);
}
/*
判断token是否是 内存表示的开始
[...]
或
BYTE[...]
WORD[...]
DWORD[...]
QWORD[...]
如果是,返回内存的长度,(1,2,4,8)
否则返回-1
*/
int CScript::TokenisPointerStart(const TOKEN* pToken, int nTokens)
{
ASSERT(pToken != NULL);
if
(nTokens < 3)
return
-1;
if
(pToken->pszToken[0] ==
'['
&& pToken->pszToken[1] == 0)
{
//
没有前缀
return
sizeof(DWORD);
}
if
(pToken->pNext->pszToken[0] ==
'['
&& pToken->pNext->pszToken[1] == 0 && nTokens >= 4)
{
//
xxx [...
if
(strcmpi(pToken->pszToken,
"BYTE"
) == 0)
{
return
sizeof(BYTE);
}
else
if
(strcmpi(pToken->pszToken,
"WORD"
) == 0)
{
return
sizeof(WORD);
}
else
if
(strcmpi(pToken->pszToken,
"DWORD"
) == 0)
{
return
sizeof(DWORD);
}
else
if
(strcmpi(pToken->pszToken,
"QWORD"
) == 0)
{
return
sizeof(__int64);
}
else
{
return
-1;
}
}
return
-1;
}
/*
是否是赋值语句
reg = ...
[exp] = ...
[varname] = ...
varname = ...
*/
BOOL CScript::TokenIs_Assign(const TOKEN* pTokenHead, int nTokens, OUT BOOL* pbValid)
{
ASSERT(pTokenHead != NULL);
ASSERT(nTokens > 0);
if
(nTokens < 3)
return
FALSE;
*pbValid = FALSE;
const TOKEN* psep = SearchToken(pTokenHead,
"="
);
if
(psep == NULL)
return
FALSE;
if
(psep == pTokenHead || psep->pNext == NULL)
return
FALSE;
//
可能是 ==, != , <=, >=
{
if
(psep->pNext->pszToken[0] ==
'='
&& psep->pNext->pszToken[1] == 0)
{
//
==
return
FALSE;
}
char* pprev = psep->pPrev->pszToken;
if
((pprev[0] ==
'!'
|| pprev[0] ==
'<'
|| pprev[0] ==
'>'
) && pprev[1] == 0)
{
//
!=, <= , >=
return
FALSE;
}
}
//
先处理=后面
CString sErrmsg2;
CVariant* ptmpvar = TokenToVariant(psep->pNext, &sErrmsg2);
if
(ptmpvar == NULL)
{
if
(psep->pNext->pNext == NULL)
{
m_sErrInfo.Format(
"\'%s\' 未定义"
, psep->pNext->pszToken);
}
else
{
m_sErrInfo =
"'=' 后面的表达式非法"
;
if
(!sErrmsg2.IsEmpty())
{
m_sErrInfo +=
"\r\n"
;
m_sErrInfo += sErrmsg2;
}
}
return
TRUE;
}
CVariant* ptmpexistvar = NULL;
int nPointerSize = -1;
//
再处理=前面
TOKEN* pLeft = CopyTokenChain(pTokenHead, psep);
if
(pLeft == NULL)
{
delete ptmpvar;
m_sErrInfo =
"内部错误"
;
return
TRUE;
}
int nLeftTokens = GetTokenCount(pLeft);
ASSERT(nLeftTokens > 0);
if
(nLeftTokens == 1 &&
(m_MemExpression.IsValidRegString(pLeft->pszToken) || m_MemExpression.IsValidRegString2(pLeft->pszToken)))
{
//
寄存器
//
reg = ...
if
(ptmpvar->GetType() != MYVARIANT_INT)
{
delete ptmpvar;
ReleaseTokenChain(pLeft);
m_sErrInfo =
"试图将寄存器赋值为非整形数据"
;
return
TRUE;
}
*pbValid = TRUE;
if
(!m_pDebugThread->IsDebugging())
{
delete ptmpvar;
ReleaseTokenChain(pLeft);
return
TRUE;
}
SetRegValue(pLeft->pszToken, (DWORD)ptmpvar->GetValue());
delete ptmpvar;
ReleaseTokenChain(pLeft);
//
刷新寄存器窗口
RefreshRegAndMemory();
return
TRUE;
}
else
if
(nLeftTokens == 1 && (ptmpexistvar = (CVariant*)SearchVariant(pLeft->pszToken)))
{
//var
变量
//
var_xx = ...
CString sName = ptmpexistvar->GetVarName();
ptmpexistvar->Assign(ptmpvar);
ptmpexistvar->SetName(sName);
*pbValid = TRUE;
delete ptmpvar;
ReleaseTokenChain(pLeft);
return
TRUE;
}
else
if
((nPointerSize = TokenisPointerStart(pLeft, nLeftTokens)) > 0)
{
//
[xxxx] = ...
const TOKEN* pLast = GetLastToken(pLeft);
ASSERT(pLast != NULL);
if
(pLast->pszToken[0] !=
']'
&& pLast->pszToken[1] != 0)
{
delete ptmpvar;
ReleaseTokenChain(pLeft);
m_sErrInfo =
"赋值语法错误"
;
return
TRUE;
}
const BOOL bHasPrifix = (pLeft->pszToken[0] !=
'['
);
TOKEN* pPointer = CopyTokenChain(
bHasPrifix ? pLeft->pNext->pNext : pLeft->pNext,
pLast);
ASSERT(pPointer != NULL);
ReleaseTokenChain(pLeft);
pLeft = NULL;
CString sErrmsg2;
CVariant* pPVer = TokenToVariant(pPointer);
if
(pPVer == NULL || pPVer->GetType() != MYVARIANT_INT)
{
//
[..]内的语法错误
delete ptmpvar;
delete pPVer;
ReleaseTokenChain(pPointer);
m_sErrInfo =
"赋值语法错误"
;
if
(!sErrmsg2.IsEmpty())
{
m_sErrInfo +=
"\r\n"
;
m_sErrInfo += sErrmsg2;
}
return
TRUE;
}
ReleaseTokenChain(pLeft);
ReleaseTokenChain(pPointer);
*pbValid = TRUE;
if
(ptmpvar->GetType() == MYVARIANT_INT || ptmpvar->GetType() == MYVARIANT_EMPTY)
{
unsigned __int64
v
= ptmpvar->GetValue();
m_pDebugThread->WriteDbgProcessMemory((LPVOID)pPVer->GetValue(), &
v
, nPointerSize);
}
else
{
int len = 0;
LPVOID Buff = NULL;
if
(ptmpvar->GetType() == MYVARIANT_STR)
{
len = 1 + strlen(ptmpvar->GetAnsiString());
Buff = (LPVOID)ptmpvar->GetAnsiString();
}
else
if
(ptmpvar->GetType() == MYVARIANT_WCHAR)
{
len = 2 + 2 * wcslen(ptmpvar->GetUnicodeString());
Buff = (LPVOID)ptmpvar->GetUnicodeString();
}
else
{
ASSERT(ptmpvar->GetType() == MYVARIANT_BYTES);
Buff = (LPVOID)ptmpvar->GetHexBytes(&len);
}
m_pDebugThread->WriteDbgProcessMemory((LPVOID)pPVer->GetValue(), Buff, len);
}
delete ptmpvar;
//
刷新内存
RefreshRegAndMemory();
return
TRUE;
}
else
{
//
语法错误
if
(nLeftTokens == 1)
{
if
((CHAR_ISDIGIT(pLeft->pszToken[0]) && m_MemExpression.IsValidDigitString(pLeft->pszToken))
|| pLeft->pszToken[0] ==
'\"'
|| pLeft->pszToken[0] ==
'\''
)
{
m_sErrInfo =
"语法错误:不能向静态数据赋值"
;
}
else
{
m_sErrInfo.Format(
"\'%s\' 未定义"
, pLeft->pszToken);
}
}
else
{
m_sErrInfo =
"错误的赋值语句"
;
}
delete ptmpvar;
ReleaseTokenChain(pLeft);
return
TRUE;
}
}
void CScript::RefreshRegAndMemory()
{
UINT dwTID = m_pDebugThread->GetCurrentSingleDebuggingThreadID();
CONTEXT context;
m_pDebugThread->SingleDebugGetThreadContext(dwTID, &context);
m_pDebugThread->DisplayRegisterAndMemory(dwTID, &context);
m_pDebugThread->GetAsmView()->m_dwEflags = context.EFlags;
m_pDebugThread->GetAsmView()->PostMessage(MSG_REFRESH_SHOW,0, context.Eip);
}
/*
标号和c语言相同
LABEL:
*/
BOOL CScript::TokenIs_Label(const TOKEN* pTokenHead, int nTokens)
{
ASSERT(pTokenHead != NULL);
ASSERT(nTokens > 0);
if
(nTokens != 2)
return
FALSE;
ASSERT(pTokenHead->pNext);
if
(pTokenHead->pNext->pszToken[0] ==
':'
&& pTokenHead->pNext->pszToken[1] == 0)
{
}
else
{
return
FALSE;
}
//xxxxx
:
BOOL bReserved = FALSE;
if
(!IsValidVarDeclare(pTokenHead->pszToken, &bReserved))
{
if
(bReserved)
{
m_sErrInfo =
"关键字作为标号"
;
}
return
FALSE;
}
return
TRUE;
}
/*
goto label
*/
BOOL CScript::TokenIs_goto(const TOKEN* pTokenHead, int nTokens, OUT int* nDestLine)
{
ASSERT(pTokenHead != NULL);
if
(strcmpi(pTokenHead->pszToken,
"goto"
) != 0)
return
FALSE;
if
(nTokens != 2)
{
m_sErrInfo =
"语法错误"
;
return
TRUE;
}
*nDestLine = -1;
BOOL bReserved = FALSE;
if
(!IsValidVarDeclare(pTokenHead->pNext->pszToken, &bReserved))
{
if
(bReserved)
{
m_sErrInfo =
"关键字作为goto语句标号"
;
}
else
{
m_sErrInfo.Format(
"\'%s\' 不是合法的goto语句标号"
, pTokenHead->pNext->pszToken);
}
return
TRUE;
}
//
寻找目标
for
(int i=0; i<m_nLines; i++)
{
if
(m_pLines[i].pHead != NULL &&
TokenIs_Label(m_pLines[i].pHead, GetTokenCount(m_pLines[i].pHead)))
{
if
(strcmpi(pTokenHead->pNext->pszToken, m_pLines[i].pHead->pszToken) == 0)
{
*nDestLine = i;
return
TRUE;
}
}
}
m_sErrInfo.Format(
"标号 \'%s\' 未定义"
, pTokenHead->pNext->pszToken);
return
TRUE;
}
/*
if_or_while: 返回 LINEIS_IF
/LINEIS_WHILE
*/
BOOL CScript::TokenIs_if_while(const TOKEN* pTokenHead, int nTokens,
OUT int* if_or_while, OUT DWORD* pdwResult)
{
ASSERT(pTokenHead != NULL);
int iw = -1;
*if_or_while = -1;
if
(strcmpi(pTokenHead->pszToken,
"if"
) == 0)
{
iw = LINEIS_IF;
}
else
if
(strcmpi(pTokenHead->pszToken,
"while"
) == 0)
{
iw = LINEIS_WHILE;
}
else
{
return
FALSE;
}
if
(pTokenHead->pNext == NULL)
{
m_sErrInfo =
"语法错误"
;
return
TRUE;
}
TOKEN* pToken = (TOKEN*)pTokenHead->pNext;
CString sErrmsg2;
CVariant* ptmpvar = TokenToVariant(pToken, &sErrmsg2);
if
(ptmpvar == NULL)
{
if
(pToken->pNext == NULL)
{
m_sErrInfo.Format(
"\'%s\' 未定义"
, pToken->pszToken);
}
else
{
m_sErrInfo =
"表达式非法"
;
if
(!sErrmsg2.IsEmpty())
{
m_sErrInfo +=
"\r\n"
;
m_sErrInfo += sErrmsg2;
}
}
return
TRUE;
}
if
(ptmpvar->GetType() != MYVARIANT_INT && ptmpvar->GetType() != MYVARIANT_EMPTY)
{
delete ptmpvar;
m_sErrInfo =
"表达式不是整数"
;
return
TRUE;
}
*pdwResult = (DWORD)ptmpvar->GetValue();
delete ptmpvar;
*if_or_while = iw;
return
TRUE;
}
/*
break
或
continue
*/
BOOL CScript::TokenIs_break_continue(const TOKEN* pTokenHead, int nTokens, OUT BOOL* pbValid, IN OUT int* line)
{
ASSERT(nTokens > 0);
BOOL bIsBreak = TRUE;
if
(strcmpi(pTokenHead->pszToken,
"break"
) == 0)
{
bIsBreak = TRUE;
}
else
if
(strcmpi(pTokenHead->pszToken,
"continue"
) == 0)
{
bIsBreak = FALSE;
}
else
{
return
FALSE;
}
*pbValid = FALSE;
if
(nTokens != 1)
{
m_sErrInfo.Format(
"'%s' 语法错误"
, bIsBreak ?
"break"
:
"continue"
);
return
TRUE;
}
//
从下一行开始,找
'}'
for
(int i=(*line) + 1; i<m_nLines; i++)
{
if
(LineIsBrace(i) == 2)
{
//
找对应的 ifwhile结构
IF_WHILE_BRACE* pifwhile = NULL;
POSITION pos = m_ifwhile.GetHeadPosition();
while
(pos != NULL)
{
IF_WHILE_BRACE* ptmp = m_ifwhile.GetNext(pos);
if
(ptmp->nPairLine == i && ptmp->if_or_while == LINEIS_WHILE)
{
pifwhile = ptmp;
break
;
}
}
if
(pifwhile != NULL)
{
//
找到对应的 {
*pbValid = TRUE;
if
(bIsBreak)
*line = i + 1;
else
*line = pifwhile->nLine;
return
TRUE;
}
}
}
m_sErrInfo.Format(
"'%s' 语法错误:未找到对应的while"
, bIsBreak ?
"break"
:
"continue"
);
return
TRUE;
}
char* Bytes2Str(LPVOID pData, int len, int nBlanks, int nBytesPerLine)
{
if
(nBlanks <= 0)
nBlanks = 1;
if
(nBytesPerLine <= 0)
nBytesPerLine = 16;
int nLine = (len
/nBytesPerLine
) + 2;
int nBuffer = ((2 + nBlanks) * nBytesPerLine + 2) * nLine;
char* str = new char[nBuffer];
if
(str == NULL)
return
NULL;
memset(str, 0, nBuffer);
char* p = str;
BYTE* data = (BYTE*)pData;
for
(int i=0; i<len; i++)
{
if
(i != 0 && (i%nBytesPerLine) == 0)
{
//
加上回车换行
strcpy(p,
"\r\n"
);
p+=2;
}
sprintf(p,
"%02X"
, data[i]);
p+=2;
memset(p,
' '
, nBlanks);
p+=nBlanks;
}
return
str;
}
void CScript::CMDprintHelp(int n)
{
CMDDESC* desc = &g_cmddesc[n];
CString s = desc->maincmd;
if
(desc->help != NULL)
{
s +=
"\n"
;
s +=
" "
;
s += desc->help;
if
(desc->usage != NULL)
{
s +=
"\n"
;
s +=
" Usage:\n"
;
s +=
" "
;
s += desc->maincmd;
s +=
" "
;
s += desc->usage;
}
}
s +=
"\n"
;
AddLog(s);
}
//
如果参数是1,显示对应的帮助信息
int CScript::CMD_Help(int nCmd, TOKEN* argv[], int argc)
{
if
(argc == 1)
{
if
(strcmpi(argv[0]->pszToken,
"var"
) == 0)
{
AddLog(
"var\n 变量定义"
);
}
else
{
//
是否是命令
int n = -1;
for
(int i=0;i<sizeof(g_cmddesc)
/sizeof
(g_cmddesc[0]); i++)
{
if
(strcmpi(g_cmddesc[i].maincmd, argv[0]->pszToken) == 0)
{
n = i;
break
;
}
}
if
(n >= 0)
{
CMDprintHelp(n);
}
}
}
else
{
AddLog(
"var\n 变量定义\n"
);
AddLog(
"if\n 判断\n"
);
AddLog(
"while\n 循环\n"
);
AddLog(
"break\n 跳出while循环\n"
);
AddLog(
"continue\n 执行while循环\n"
);
AddLog(
"goto\n 跳转到标号处\n"
);
for
(int i=0; i<sizeof(g_cmddesc) / sizeof(g_cmddesc[0]); i++)
{
CMDprintHelp(i);
}
CString s;
s.Format(
"要获取更详细信息,请访问 http://www.mdebug.org/scripthelp.htm\n\n如果要显示单个帮助,请在 %s 后面加上相应的命令"
,
g_cmddesc[nCmd].maincmd);
AddLog(s);
}
return
0;
}
//
无参数
int CScript::CMD_exit(int nCmd, TOKEN* argv[], int argc)
{
m_pMainframe->SendMessage(WM_CLOSE);
return
0;
}
//
无参数
int CScript::CMD_Ver(int nCmd, TOKEN* argv[], int argc)
{
char buff[128];
sprintf(buff, STRING_VDEBUG_VERSION, __DATE__);
AddLog(buff);
return
0;
}
//
无参数
int CScript::CMD_CLS(int nCmd, TOKEN* argv[], int argc)
{
CMainFrame* p = (CMainFrame*)AfxGetApp()->m_pMainWnd;
p->m_OutPutDlg.m_EditDbgOutput.Empty();
return
0;
}
/*
第一个参数必须是合法的variant,取得第一个参数
*/
CVariant* CScript::CMDGetCVariant(int nCmd, TOKEN* pToken, int len, OUT CString* pErrmsg)
{
ASSERT(pErrmsg != NULL);
ASSERT(nCmd >= 0);
if
(pToken == NULL)
{
pErrmsg->Format(
"%s 语法错误"
, g_cmddesc[nCmd].maincmd);
return
NULL;
}
CString sErrmsg2;
CVariant* ptmpvar = TokenToVariant(pToken, &sErrmsg2);
if
(ptmpvar == NULL)
{
if
(pToken->pNext == NULL)
{
pErrmsg->Format(
"\'%s\' 未定义"
, pToken->pszToken);
}
else
{
pErrmsg->Format(
"%s 后面的表达式非法"
, g_cmddesc[nCmd].maincmd);
if
(!sErrmsg2.IsEmpty())
{
*pErrmsg +=
"\r\n"
;
*pErrmsg += sErrmsg2;
}
}
return
NULL;
}
return
ptmpvar;
}
/*
参数必须是合法的string variant,取得参数
*/
WCHAR* CScript::CMDGetStringVariant(int nCmd, TOKEN* pToken, int len, OUT CString* pErrmsg)
{
CVariant* pvar = CMDGetCVariant(nCmd, pToken, len, pErrmsg);
if
(pvar == NULL)
return
NULL;
if
(pvar->GetType() != MYVARIANT_WCHAR && pvar->GetType() != MYVARIANT_STR)
{
*pErrmsg =
"表达式类型不是字符串"
;
delete pvar;
pvar = NULL;
return
NULL;
}
if
(pvar->GetType() == MYVARIANT_WCHAR)
{
int len = 1 + wcslen(pvar->GetUnicodeString());
WCHAR* p = new WCHAR[len];
if
(p == NULL)
{
*pErrmsg =
"内部错误"
;
delete pvar;
return
NULL;
}
wcscpy(p, pvar->GetUnicodeString());
delete pvar;
return
p;
}
else
{
int len = 1 + MultiByteToWideChar(CP_ACP, 0, pvar->GetAnsiString(), -1, NULL, 0);
WCHAR* p = new WCHAR[len];
if
(p == NULL)
{
*pErrmsg =
"内部错误"
;
delete pvar;
return
NULL;
}
memset(p, 0, sizeof(WCHAR)*len);
MultiByteToWideChar(CP_ACP, 0, pvar->GetAnsiString(), -1, p, len);
delete pvar;
return
p;
}
}
/*
参数必须是合法的 int variant,取得参数
*/
unsigned __int64 CScript::CMDGetintVariant(int nCmd, TOKEN* pToken, int len, OUT CString* pErrmsg, OUT BOOL* pbValid)
{
*pbValid = FALSE;
CVariant* pvar = CMDGetCVariant(nCmd, pToken, len, pErrmsg);
if
(pvar == NULL)
return
0;
if
(pvar->GetType() != MYVARIANT_EMPTY && pvar->GetType() != MYVARIANT_INT)
{
*pErrmsg =
"表达式类型不是整数"
;
delete pvar;
pvar = NULL;
return
0;
}
*pbValid = TRUE;
unsigned __int64
v
= (pvar->GetType() == MYVARIANT_EMPTY) ? 0 : pvar->GetValue();
delete pvar;
return
v
;
}
CString CScript::GetValueOfVar(CVariant* ptmpvar)
{
CString s;
switch(ptmpvar->GetType())
{
case
MYVARIANT_EMPTY:
s =
"0"
;
break
;
case
MYVARIANT_INT:
s.Format(
"0x%I64X"
, ptmpvar->GetValue());
break
;
case
MYVARIANT_STR:
s.Format(
"%s"
, ptmpvar->GetAnsiString());
break
;
case
MYVARIANT_WCHAR:
s.Format(
"%S"
, ptmpvar->GetUnicodeString());
break
;
case
MYVARIANT_BYTES:
{
int len;
const BYTE* pBytes = ptmpvar->GetHexBytes(&len);
len = (len > 0x1000) ? 0x1000 : len;
char* p = Bytes2Str((LPVOID)pBytes, len, 0,0);
if
(p != NULL)
{
s.Format(
"%s"
, p);
delete[] p;
}
}
break
;
default:
ASSERT(0);
break
;
}
return
s;
}
/*
print <表达式>
*/
int CScript::CMD_PRINT(int nCmd, TOKEN* argv[], int argc)
{
CVariant* ptmpvar = CMDGetCVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo);
if
(ptmpvar == NULL)
return
-1;
CString s = GetValueOfVar(ptmpvar);
delete ptmpvar;
AddLog(s);
return
0;
}
//msg
"message"
//
和 print 相同
int CScript::CMD_MSG(int nCmd, TOKEN* argv[], int argc)
{
CVariant* ptmpvar = CMDGetCVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo);
if
(ptmpvar == NULL)
return
-1;
CString s;
switch(ptmpvar->GetType())
{
case
MYVARIANT_EMPTY:
s =
"0"
;
break
;
case
MYVARIANT_INT:
s.Format(
"0x%I64X"
, ptmpvar->GetValue());
break
;
case
MYVARIANT_STR:
s.Format(
"%s"
, ptmpvar->GetAnsiString());
break
;
case
MYVARIANT_WCHAR:
s.Format(
"%S"
, ptmpvar->GetUnicodeString());
break
;
case
MYVARIANT_BYTES:
{
int len;
const BYTE* pBytes = ptmpvar->GetHexBytes(&len);
len = (len > 0x1000) ? 0x1000 : len;
char* p = Bytes2Str((LPVOID)pBytes, len, 0,0);
if
(p != NULL)
{
s.Format(
"%s"
, p);
delete[] p;
}
}
break
;
default:
ASSERT(0);
break
;
}
delete ptmpvar;
AfxMessageBox(s, MB_ICONINFORMATION);
return
0;
}
/*
YESNO <string>
*/
int CScript::CMD_YESNO(int nCmd, TOKEN* argv[], int argc)
{
WCHAR* pname = CMDGetStringVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo);
if
(pname == NULL)
return
-1;
m_result.Release();
if
(MessageBoxW(m_pMainframe->GetSafeHwnd(), pname, L
"请确认"
, MB_YESNO|MB_ICONQUESTION) == IDYES)
{
m_result.SetInt(1);
}
else
{
m_result.SetInt(0);
}
delete[] pname;
return
0;
}
//
无参数
int CScript::CMD_getstr(int nCmd, TOKEN* argv[], int argc)
{
CScriptGetInputDlg dlg;
dlg.m_sTitle =
"请输入字符串"
;
dlg.DoModal();
m_result.Release();
m_result.SetAnsiString(dlg.m_string);
return
0;
}
//
无参数
int CScript::CMD_getint(int nCmd, TOKEN* argv[], int argc)
{
CScriptGetInputDlg dlg;
dlg.m_sTitle =
"请输入16进制数字"
;
dlg.DoModal();
DWORD
v
= 0;
sscanf(dlg.m_string,
"%X"
, &
v
);
m_result.Release();
m_result.SetInt(
v
);
return
0;
}
//
找进程,result返回pid
//findprocess
<processname>
int CScript::CMD_findprocess(int nCmd, TOKEN* argv[], int argc)
{
WCHAR* pname = CMDGetStringVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo);
if
(pname == NULL)
return
-1;
DWORD pid = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if
(hSnap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32W ppe = {0};
ppe.dwSize = sizeof(ppe);
BOOL b = Process32FirstW(hSnap, &ppe);
while
(b)
{
if
(wcsicmp(ppe.szExeFile, pname) == 0)
{
pid = ppe.th32ProcessID;
break
;
}
b = Process32NextW(hSnap, &ppe);
}
CloseHandle(hSnap);
}
m_result.Release();
m_result.SetInt((DWORD)pid);
delete[] pname;
return
0;
}
//
等待,直到允许用户输入命令
void CScript::WaitforWaitingUserInput()
{
if
(m_bIsCmdLine)
//
如果是在命令行,就不等待
{
Sleep(50);
return
;
}
const BOOL bDebugging = m_pDebugThread->IsDebugging();
ResetEvent(*m_phEvent);
while
(!m_pDebugThread->IsWaitingForCommand())
{
if
(WaitForSingleObject(*m_phEvent, 50) == WAIT_OBJECT_0)
{
break
;
}
if
(m_pbRunning)
{
if
(!(*m_pbRunning))
{
break
;
}
}
if
(bDebugging)
{
if
(!m_pDebugThread->IsDebugging())
{
//
调试结束,就没有必要等待了
//
退出
if
(m_pbRunning)
{
*m_pbRunning = FALSE;
}
break
;
}
}
}
Sleep(5);
}
//
打开文件进行调试
//openfile
<path> [,arg]
int CScript::CMD_openfile(int nCmd, TOKEN* argv[], int argc)
{
if
(argc != 1 && argc != 2)
{
m_sErrInfo =
"语法错误"
;
return
-1;
}
WCHAR* pwszPath = CMDGetStringVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo);
if
(pwszPath == NULL)
{
return
-1;
}
WCHAR* pwszArgv = NULL;
if
(argc == 2)
{
pwszArgv = CMDGetStringVariant(nCmd, argv[1], GetTokenCount(argv[1]), &m_sErrInfo);
if
(pwszArgv == NULL)
{
delete[] pwszPath;
return
-1;
}
}
if
(GetFileAttributesW(pwszPath) == -1)
{
m_sErrInfo.Format(
"文件 '%S' 不存在"
, pwszPath);
delete[] pwszPath;
delete[] pwszArgv;
return
-1;
}
CString sFilePath(pwszPath);
const BOOL bOpt = m_pApp->m_DebugThread.m_bStartDebugWhenPEFileOpened;
m_pApp->m_DebugThread.m_bStartDebugWhenPEFileOpened = FALSE;
m_pApp->OpenDocumentFile(sFilePath);
m_pApp->m_DebugThread.m_bStartDebugWhenPEFileOpened = bOpt;
int r = 0;
if
(m_pApp->m_bOpenPEDocumentSucc)
{
//
打开的是pe文件,并且打开成功
if
(pwszArgv != NULL)
{
m_pApp->m_DebugThread.m_sExeParam = pwszArgv;
}
m_pApp->m_pMainWnd->SendMessage(WM_COMMAND, ID_DBGCMD_GO);
//
等待,直到用户输入界面
WaitforWaitingUserInput();
}
else
{
m_sErrInfo =
"打开PE文件失败"
;
r = -1;
}
delete[] pwszPath;
delete[] pwszArgv;
return
r;
}
//loaddll
<path> 向目标进程加载dll
int CScript::CMD_loaddll(int nCmd, TOKEN* argv[], int argc)
{
ASSERT(argc == 1);
if
(!m_pDebugThread->IsDebugging())
return
0;
WCHAR* pname = CMDGetStringVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo);
if
(pname == NULL)
return
-1;
CString sName(pname);
delete[] pname;
CString sErr;
if
(m_pDebugThread->InjectDll(sName, &sErr) && m_pDebugThread->IsRunning())
{
Sleep(200);
}
return
0;
}
//alloc
<size> 向目标进程分配内存
int CScript::CMD_alloc(int nCmd, TOKEN* argv[], int argc)
{
ASSERT(argc == 1);
if
(!m_pDebugThread->IsDebugging())
{
m_result.Release();
m_result.SetInt(0);
return
0;
}
BOOL bValid = TRUE;
int ms = (int)CMDGetintVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo, &bValid);
if
(!bValid)
return
-1;
int nPages = ms
/0x1000
;
if
(nPages <= 0)
{
nPages = 1;
}
m_result.Release();
m_result.SetInt((DWORD)m_pDebugThread->DbgVirtualAllocEx(NULL, nPages * 0x1000));
return
0;
}
/*
readdata <addr>, <size>
*/
int CScript::CMD_readdata(int nCmd, TOKEN* argv[], int argc)
{
ASSERT(argc == 2);
BOOL bValid = TRUE;
const DWORD dwAddr = (DWORD)CMDGetintVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo, &bValid);
if
(!bValid)
return
-1;
bValid = TRUE;
const int nReadCount = (int)CMDGetintVariant(nCmd, argv[1], GetTokenCount(argv[1]), &m_sErrInfo, &bValid);
if
(!bValid)
return
-1;
//
const DWORD dwPageBase = dwAddr & 0xFFFFF000;
const DWORD dwPageEnd = ((dwAddr + nReadCount) | 0xFFF) + 1;
const int nPages = (dwPageEnd - dwPageBase) / 0x1000;
WORD* pBuffer = new WORD[nPages * 0x1000];
if
(pBuffer == NULL)
{
m_result.Release();
return
0;
}
memset(pBuffer, 0, nPages * 0x1000 * sizeof(WORD));
m_pDebugThread->InternalReadPages(dwPageBase, nPages, pBuffer);
int k = dwAddr - dwPageBase;
BYTE* pRet = new BYTE[nReadCount];
if
(pRet == NULL)
{
delete[] pBuffer;
m_result.Release();
return
0;
}
memset(pRet, 0, nReadCount);
for
(int i=0; i<nReadCount; i++)
{
WORD c = pBuffer[k+i];
if
(c >> 8)
break
;
pRet[i] = (BYTE)c;
}
m_result.Release();
m_result.SetHexBytes(pRet, i);
delete[] pRet;
delete[] pBuffer;
return
0;
}
/*
//
!!! 此版本读取不超过8M !!!!
*/
int CScript::CMDReadAnsiOrUnicodeStringFromMemory(int nCmd, TOKEN* argv[], int argc, BOOL bUnicode)
{
if
(!m_pDebugThread->IsDebugging())
return
0;
BOOL bValid = TRUE;
const DWORD dwAddr = (DWORD)CMDGetintVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo, &bValid);
if
(!bValid)
return
-1;
const nReadCount = 0x00800000;
const DWORD dwPageBase = dwAddr & 0xFFFFF000;
const DWORD dwPageEnd = ((dwAddr + nReadCount) | 0xFFF) + 1;
const int nPages = (dwPageEnd - dwPageBase) / 0x1000;
WORD* pBuffer = new WORD[nPages * 0x1000];
if
(pBuffer == NULL)
{
m_result.Release();
return
0;
}
memset(pBuffer, 0, nPages * 0x1000 * sizeof(WORD));
m_pDebugThread->InternalReadPages(dwPageBase, nPages, pBuffer);
int k = dwAddr - dwPageBase;
BYTE* pRet = new BYTE[nReadCount + 2];
if
(pRet == NULL)
{
delete[] pBuffer;
m_result.Release();
return
0;
}
memset(pRet, 0, nReadCount + 2);
for
(int i=0; i<nReadCount; i++)
{
WORD c = pBuffer[k+i];
if
(c >> 8)
break
;
pRet[i] = (BYTE)c;
if
(pRet[i] == 0 && !bUnicode)
break
;
}
m_result.Release();
if
(bUnicode)
{
m_result.SetUnicodeString2((WCHAR*)pRet);
}
else
{
m_result.SetAnsiString((char*)pRet);
}
delete[] pRet;
delete[] pBuffer;
return
0;
}
/*
readstr <addr>
*/
int CScript::CMD_readstr(int nCmd, TOKEN* argv[], int argc)
{
return
CMDReadAnsiOrUnicodeStringFromMemory(nCmd, argv, argc, FALSE);
}
/*
readwstr <addr>
*/
int CScript::CMD_readwstr(int nCmd, TOKEN* argv[], int argc)
{
return
CMDReadAnsiOrUnicodeStringFromMemory(nCmd, argv, argc, TRUE);
}
//sleep
<毫秒>
int CScript::CMD_sleep(int nCmd, TOKEN* argv[], int argc)
{
ASSERT(argc == 1);
BOOL bValid = TRUE;
int ms = (int)CMDGetintVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo, &bValid);
if
(!bValid)
return
-1;
if
(ms == 0)
return
0;
if
(ms < 100)
{
Sleep(ms);
return
0;
}
int elips = 100;
int
times
= ms
/elips
;
for
(int i=0; i<
times
; i++)
{
Sleep(elips);
if
(m_pbRunning)
{
if
(!(*m_pbRunning))
{
break
;
}
}
}
return
0;
}
/*
CMD_GetModuleBase <name or path>
*/
int CScript::CMD_GetModuleBase(int nCmd, TOKEN* argv[], int argc)
{
if
(!m_pDebugThread->IsDebugging())
return
0;
WCHAR* pname = CMDGetStringVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo);
if
(pname == NULL)
return
-1;
CString sNameOrPath(pname);
delete[] pname;
pname = NULL;
LoadedModule* pMod = m_pDebugThread->GetModuleStruFromLoadedModuleFilePath(sNameOrPath);
if
(pMod == NULL)
{
pMod = m_pDebugThread->GetModuleStruFromLoadedModuleFileName(sNameOrPath);
}
if
(pMod == NULL)
return
0;
m_result.Release();
m_result.SetInt((DWORD)pMod->lpModuleBase);
return
0;
}
/*
CMD_GetModuleBase <name or path>
*/
int CScript::CMD_GetModuleSize(int nCmd, TOKEN* argv[], int argc)
{
if
(!m_pDebugThread->IsDebugging())
return
0;
WCHAR* pname = CMDGetStringVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo);
if
(pname == NULL)
return
-1;
CString sNameOrPath(pname);
delete[] pname;
pname = NULL;
LoadedModule* pMod = m_pDebugThread->GetModuleStruFromLoadedModuleFilePath(sNameOrPath);
if
(pMod == NULL)
{
pMod = m_pDebugThread->GetModuleStruFromLoadedModuleFileName(sNameOrPath);
}
if
(pMod == NULL)
return
0;
m_result.Release();
m_result.SetInt(pMod->dwModuleSize);
return
0;
}
/*
删除断点,包括硬件断点
bc
* : 删除所有
bc
addr
*/
int CScript::CMD_bc(int nCmd, TOKEN* argv[], int argc)
{
ASSERT(argc == 1);
if
(!m_pDebugThread->IsDebugging())
return
0;
if
(argv[0]->pszToken[0] ==
'*'
&& argv[0]->pszToken[1] == 0)
{
//bc
*
m_pDebugThread->DeleteAllHardBP();
m_pDebugThread->RemoveAllBP();
}
else
{
//bc
addr
BOOL bValid = TRUE;
unsigned __int64 addr = CMDGetintVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo, &bValid);
if
(!bValid)
return
-1;
//
如果设置了硬件执行断点,那么删除硬件执行断点
if
(m_pDebugThread->IsHardExeBPSetted((DWORD)addr))
{
m_pDebugThread->DeleteHardBP((DWORD)addr);
}
if
(m_pDebugThread->IsBPSetted((DWORD)addr))
{
//
虽然有断点,但是有可能是调试器自用断点。
if
(!m_pDebugThread->IsDebugInternalBP((DWORD)addr))
{
m_pDebugThread->RemoveBP((DWORD)addr);
}
}
}
//
更新bpview,如果bpview已经建立的话
if
(m_pMainframe->m_pBreakPointView != NULL)
{
if
(::IsWindow(m_pMainframe->m_pBreakPointView->GetSafeHwnd()))
{
m_pMainframe->m_pBreakPointView->Refresh();
}
}
if
(m_pMainframe->m_pAsmView != NULL)
{
m_pMainframe->m_pAsmView->Invalidate();
}
return
0;
}
//bp
<addr> [,condition] F9断点
int CScript::CMD_bp(int nCmd, TOKEN* argv[], int argc)
{
if
(argc <= 0)
{
m_sErrInfo =
"语法错误"
;
return
-1;
}
if
(!m_pDebugThread->IsDebugging())
return
0;
BOOL bValid = TRUE;
unsigned __int64 addr = CMDGetintVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo, &bValid);
if
(!bValid)
return
-1;
char* pszCondition = NULL;
CString sCondition;
if
(argc > 1)
{
WCHAR* pcondition = CMDGetStringVariant(nCmd, argv[1], GetTokenCount(argv[1]), &m_sErrInfo);
if
(pcondition == NULL)
{
if
(!m_sErrInfo.IsEmpty())
{
m_sErrInfo +=
", "
;
}
m_sErrInfo +=
"断点条件2边必须用引号"
;
return
-1;
}
sCondition = pcondition;
delete[] pcondition;
pszCondition = (char*)(const char*)sCondition;
}
if
(m_pDebugThread->AddBP((DWORD)addr, NULL, pszCondition, NULL, NULL, NULL, NULL))
{
//
更新bpview,如果bpview已经建立的话
if
(m_pMainframe->m_pBreakPointView != NULL)
{
if
(::IsWindow(m_pMainframe->m_pBreakPointView->GetSafeHwnd()))
{
//
pMain->m_pBreakPointView->Refresh();
m_pMainframe->m_pBreakPointView->OnBPHasAdded((DWORD)addr);
}
}
if
(m_pMainframe->m_pAsmView != NULL)
{
m_pMainframe->m_pAsmView->Invalidate();
}
}
return
0;
}
//bph
addr 硬件执行断点
int CScript::CMD_bph(int nCmd, TOKEN* argv[], int argc)
{
if
(!m_pDebugThread->IsDebugging())
return
0;
BOOL bValid = TRUE;
unsigned __int64 addr = CMDGetintVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo, &bValid);
if
(!bValid)
return
-1;
m_pDebugThread->SetHardBP((DWORD)addr, 0, 0);
//execute
//
更新bpview,如果bpview已经建立的话
if
(m_pMainframe->m_pBreakPointView != NULL)
{
if
(::IsWindow(m_pMainframe->m_pBreakPointView->GetSafeHwnd()))
{
m_pMainframe->m_pBreakPointView->Refresh();
}
}
if
(m_pMainframe->m_pAsmView != NULL)
{
m_pMainframe->m_pAsmView->Invalidate();
}
return
0;
}
//r
= 0, w = 1
int CScript::CMDbphrw(int nCmd, TOKEN* argv[], int argc, int rw)
{
ASSERT(argc >= 1);
if
(!m_pDebugThread->IsDebugging())
return
0;
if
(argc != 1 && argc != 2)
{
m_sErrInfo =
"语法错误"
;
return
-1;
}
BOOL bValid = TRUE;
unsigned __int64 addr = CMDGetintVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo, &bValid);
if
(!bValid)
return
-1;
int size = 0;
if
(argc == 2)
{
bValid = TRUE;
unsigned __int64 len = CMDGetintVariant(nCmd, argv[1], GetTokenCount(argv[1]), &m_sErrInfo, &bValid);
if
(!bValid)
return
-1;
//1
,2,4
if
(len != 1 && len != 2 && len != 4)
{
m_sErrInfo =
"硬件内存断点的长度必须是1/2/4"
;
return
-1;
}
if
(len == 2)
size = 1;
else
if
(len == 4)
size = 3;
else
size = 0;
}
m_pDebugThread->SetHardBP((DWORD)addr, (rw == 0 ? 3 : 1), size);
//
更新bpview,如果bpview已经建立的话
if
(m_pMainframe->m_pBreakPointView != NULL)
{
if
(::IsWindow(m_pMainframe->m_pBreakPointView->GetSafeHwnd()))
{
m_pMainframe->m_pBreakPointView->Refresh();
}
}
return
0;
}
//bphr
<addr> [,size] 硬件读内存断点
int CScript::CMD_bphr(int nCmd, TOKEN* argv[], int argc)
{
return
CMDbphrw(nCmd, argv, argc, 0);
}
//bphw
<addr> [,size] 硬件写内存断点
int CScript::CMD_bphw(int nCmd, TOKEN* argv[], int argc)
{
return
CMDbphrw(nCmd, argv, argc, 1);
}
/*
g [addr]
*/
int CScript::CMD_run(int nCmd, TOKEN* argv[], int argc)
{
ASSERT(argc == 0 || argc == 1);
if
(m_pDebugThread->m_sDebuggingFileName.IsEmpty())
{
m_sErrInfo =
"PE文件尚未打开"
;
return
-1;
}
if
(argc == 0)
{
m_pApp->m_pMainWnd->SendMessage(WM_COMMAND, ID_DBGCMD_GO);
//
等待,直到用户输入界面
WaitforWaitingUserInput();
return
0;
}
else
{
if
(!CanStep())
{
m_sErrInfo =
"进程处于运行状态"
;
return
-1;
}
BOOL bValid = TRUE;
unsigned __int64 pid = CMDGetintVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo, &bValid);
if
(!bValid)
return
-1;
m_pDebugThread->DebugRunTo((DWORD)pid);
//
等待,直到用户输入界面
WaitforWaitingUserInput();
return
0;
}
}
/*
*/
int CScript::CMD_stop(int nCmd, TOKEN* argv[], int argc)
{
if
(m_pApp->m_bEnabledCmds[ENABLE_DBGCMD_STOP])
{
m_pMainframe->SendMessage(WM_COMMAND, ID_DBGCMD_STOP);
}
return
0;
}
int CScript::CMD_pause(int nCmd, TOKEN* argv[], int argc)
{
if
(m_pApp->m_bEnabledCmds[ENABLE_DBGCMD_PAUSE])
{
m_pMainframe->SendMessage(WM_COMMAND, ID_DBGCMD_PAUSE);
}
return
0;
}
int CScript::CMD_restart(int nCmd, TOKEN* argv[], int argc)
{
if
(m_pDebugThread->m_sDebuggingFileName.IsEmpty())
{
m_sErrInfo =
"PE文件尚未打开"
;
return
-1;
}
if
(!m_pApp->m_bEnabledCmds[ENABLE_DBGCMD_STOP])
{
m_sErrInfo =
"程序尚未运行"
;
return
-1;
}
m_pMainframe->SendMessage(WM_COMMAND, ID_DBGCMD_RESTART);
//
等待,直到用户输入界面
WaitforWaitingUserInput();
return
0;
}
int CScript::CMD_dettach(int nCmd, TOKEN* argv[], int argc)
{
ASSERT(argc == 0);
if
(m_pDebugThread->IsDebugging())
{
m_pMainframe->SendMessage(WM_COMMAND, ID_DBGMENU_DETACH);
}
return
0;
}
//attach
<pid>
int CScript::CMD_attach(int nCmd, TOKEN* argv[], int argc)
{
ASSERT(argc == 1);
if
(m_pDebugThread->IsDebugging())
{
m_sErrInfo =
"不能在调试状态附加进程"
;
return
-1;
}
BOOL bValid = TRUE;
unsigned __int64 pid = CMDGetintVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo, &bValid);
if
(!bValid)
return
-1;
if
(!m_pApp->DebugProcess((DWORD)pid))
{
m_sErrInfo =
"attach 失败"
;
return
-1;
}
//
等待,直到用户输入界面
WaitforWaitingUserInput();
return
0;
}
//
判断是否可以进行单步控制
BOOL CScript::CanStep()
{
if
(m_pMainframe->m_pAsmView == NULL)
return
FALSE;
else
{
return
(!m_pDebugThread->IsRunning());
}
}
//f11
int CScript::CMD_t(int nCmd, TOKEN* argv[], int argc)
{
ASSERT(argc == 0);
if
(CanStep())
{
m_pMainframe->SendMessage(WM_COMMAND, ID_DBGCMD_STEPINTO);
WaitforWaitingUserInput();
}
return
0;
}
//f10
int CScript::CMD_p(int nCmd, TOKEN* argv[], int argc)
{
ASSERT(argc == 0);
if
(CanStep())
{
m_pMainframe->SendMessage(WM_COMMAND, ID_DBGCMD_STEPOVER);
WaitforWaitingUserInput();
}
return
0;
}
//
运行到返回处
int CScript::CMD_gret(int nCmd, TOKEN* argv[], int argc)
{
ASSERT(argc == 0);
if
(CanStep())
{
m_pMainframe->SendMessage(WM_COMMAND, ID_DBGCMD_STEPOUT);
WaitforWaitingUserInput();
}
return
0;
}
//strlen
<string>
int CScript::CMD_strlen(int nCmd, TOKEN* argv[], int argc)
{
WCHAR* pstr = CMDGetStringVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo);
if
(pstr == NULL)
return
-1;
m_result.Release();
m_result.SetInt(wcslen(pstr));
delete[] pstr;
return
0;
}
/*
strcat var_dst, src
//
第一个参数必须是变量
*/
int CScript::CMD_strcat(int nCmd, TOKEN* argv[], int argc)
{
ASSERT(argc == 2);
if
(GetTokenCount(argv[0]) != 1)
{
m_sErrInfo =
"语法错误:strcat 第一个参数必须是变量"
;
return
-1;
}
CVariant* pdst = (CVariant*)SearchVariant(argv[0]->pszToken);
if
(pdst == NULL)
{
m_sErrInfo =
"语法错误:strcat 第一个参数必须是变量"
;
return
-1;
}
if
(pdst->GetType() != MYVARIANT_STR && pdst->GetType() != MYVARIANT_WCHAR)
{
m_sErrInfo =
"错误:strcat 第一个参数类型不是字符串"
;
return
-1;
}
WCHAR* pstrdst = CMDGetStringVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo);
if
(pstrdst == NULL)
return
-1;
WCHAR* pstr = CMDGetStringVariant(nCmd, argv[1], GetTokenCount(argv[1]), &m_sErrInfo);
if
(pstr == NULL)
{
delete[] pstrdst;
return
-1;
}
int len = wcslen(pstrdst) + 2 + wcslen(pstr) + 2;
WCHAR* pwszNew = new WCHAR[len];
if
(pwszNew == NULL)
{
delete[] pstrdst;
delete[] pstr;
m_sErrInfo =
"内部错误"
;
return
-1;
}
wcscpy(pwszNew, pstrdst);
wcscat(pwszNew, pstr);
delete[] pstrdst;
delete[] pstr;
pstrdst = pstr = NULL;
if
(pdst->GetType() == MYVARIANT_WCHAR)
{
pdst->Release();
pdst->SetUnicodeString2(pwszNew);
}
else
{
pdst->Release();
pdst->SetUnicodeStringToAnsiString(pwszNew);
}
delete[] pwszNew;
return
0;
}
/*
strcmp str1, str2
*/
int CScript::CMDstrcmpx(int nCmd, TOKEN* argv[], int argc, int i)
{
ASSERT(argc == 2);
WCHAR* pstr1 = CMDGetStringVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo);
if
(pstr1 == NULL)
return
-1;
WCHAR* pstr2 = CMDGetStringVariant(nCmd, argv[1], GetTokenCount(argv[1]), &m_sErrInfo);
if
(pstr2 == NULL)
{
delete[] pstr1;
return
-1;
}
int r = (i == 0) ? wcscmp(pstr1, pstr2) : wcsicmp(pstr1, pstr2);
m_result.Release();
m_result.SetInt(r);
delete[] pstr1;
delete[] pstr2;
return
0;
}
int CScript::CMD_strcmp(int nCmd, TOKEN* argv[], int argc)
{
return
CMDstrcmpx(nCmd, argv, argc, 0);
}
int CScript::CMD_strcmpi(int nCmd, TOKEN* argv[], int argc)
{
return
CMDstrcmpx(nCmd, argv, argc, 1);
}
/*
strstr str1, str2
*/
int CScript::CMDstrstrx(int nCmd, TOKEN* argv[], int argc, int i)
{
ASSERT(argc == 2);
WCHAR* pstr1 = CMDGetStringVariant(nCmd, argv[0], GetTokenCount(argv[0]), &m_sErrInfo);
if
(pstr1 == NULL)
return
-1;
WCHAR* pstr2 = CMDGetStringVariant(nCmd, argv[1], GetTokenCount(argv[1]), &m_sErrInfo);
if
(pstr2 == NULL)
{
delete[] pstr1;
return
-1;
}
WCHAR* r;
if
(i == 0)
{
r = wcsstr(pstr1, pstr2);
}
else
{
wcslwr(pstr1);
wcslwr(pstr2);
r = wcsstr(pstr1, pstr2);
}
m_result.Release();
if
(r == NULL)
m_result.SetUnicodeString2(L
""
);
else
m_result.SetUnicodeString2(r);
return
0;
}
int CScript::CMD_strstr(int nCmd, TOKEN* argv[], int argc)
{
return
CMDstrstrx(nCmd, argv, argc, 0);
}
int CScript::CMD_strstri(int nCmd, TOKEN* argv[], int argc)
{
return
CMDstrstrx(nCmd, argv, argc, 1);
}
//strupr
string
int CScript::CMDstruprlwr(int nCmd, TOKEN* argv[], int argc, int i)
{
ASSERT(argc == 1);
if
(GetTokenCount(argv[0]) != 1)
{
m_sErrInfo =
"语法错误:第一个参数必须是变量"
;
return
-1;
}
CVariant* pdst = (CVariant*)SearchVariant(argv[0]->pszToken);
if
(pdst == NULL)
{
m_sErrInfo =
"语法错误:第一个参数必须是变量"
;
return
-1;
}
if
(pdst->GetType() != MYVARIANT_STR && pdst->GetType() != MYVARIANT_WCHAR)
{
m_sErrInfo =
"错误:第一个参数类型不是字符串"
;
return
-1;
}
if
(i == 0)
{
if
(pdst->GetType() == MYVARIANT_WCHAR)
{
wcslwr((WCHAR*)pdst->GetUnicodeString());
}
else
{
strlwr((char*)pdst->GetAnsiString());
}
}
else
{
if
(pdst->GetType() == MYVARIANT_WCHAR)
{
wcsupr((WCHAR*)pdst->GetUnicodeString());
}
else
{
strupr((char*)pdst->GetAnsiString());
}
}
return
0;
}
int CScript::CMD_strlwr(int nCmd, TOKEN* argv[], int argc)
{
return
CMDstruprlwr(nCmd, argv, argc, 0);
}
int CScript::CMD_strupr(int nCmd, TOKEN* argv[], int argc)
{
return
CMDstruprlwr(nCmd, argv, argc, 1);
}
void CScript::AddLog(const char* pszText)
{
m_pDebugThread->AddLog(pszText);
}
TOKEN** CScript::Convertoargv(const TOKEN* pTokenHead, int nTokens, OUT int* pargc, OUT BOOL* pbValid)
{
ASSERT(nTokens >= 0);
ASSERT(pargc != NULL);
if
(pTokenHead == NULL || nTokens == 0)
{
*pargc = 0;
*pbValid = TRUE;
return
NULL;
}
BOOL bFail = FALSE;
TOKEN** pMaxToken = new TOKEN*[nTokens];
if
(pMaxToken == NULL)
{
*pargc = 0;
*pbValid = FALSE;
m_sErrInfo =
"内部错误"
;
return
NULL;
}
int argc = 0;
TOKEN* p = (TOKEN*)pTokenHead;
while
(p != NULL)
{
const TOKEN* pt = SearchToken(p,
","
);
if
(pt == p)
{
bFail = TRUE;
break
;
}
pMaxToken[argc] = (pt == NULL) ? CloneTokenChain(p) : CopyTokenChain(p, pt);
argc++;
if
(pt == NULL)
{
break
;
}
p = pt->pNext;
}
if
(bFail)
{
for
(int i=0; i<argc; i++)
{
ReleaseTokenChain(pMaxToken[i]);
}
delete[] pMaxToken;
*pbValid = FALSE;
m_sErrInfo =
"语法错误"
;
return
NULL;
}
*pbValid = TRUE;
*pargc = argc;
return
pMaxToken;
}
/*
cmd [arg1], [arg2], [arg3], ...
*/
int CScript::ExecNormalCmd(const TOKEN* pTokenHead, int nTokens)
{
ASSERT(pTokenHead != NULL);
ASSERT(nTokens > 0);
for
(int i=0; i<sizeof(g_cmddesc) / sizeof(g_cmddesc[0]); i++)
{
if
(strcmpi(pTokenHead->pszToken, g_cmddesc[i].maincmd) == 0)
{
//
按照
','
进行分割
int argc = 0;
BOOL bValid = TRUE;
TOKEN** pTokenargv = Convertoargv(pTokenHead->pNext, nTokens-1, &argc, &bValid);
if
(!bValid)
{
return
-1;
}
int r = -1;
if
(g_cmddesc[i].argc >= 0 && g_cmddesc[i].argc != argc)
{
if
(g_cmddesc[i].argc == 0)
{
m_sErrInfo.Format(
"语法错误:'%s' 命令无参数"
, g_cmddesc[i].maincmd);
}
else
{
m_sErrInfo.Format(
"语法错误:'%s' 命令的参数数量应该为 %d"
, g_cmddesc[i].maincmd, g_cmddesc[i].argc);
}
}
else
{
r = (this->*g_cmddesc[i].handler)(i, pTokenargv, argc);
}
//
释放
for
(int k=0; k<argc; k++)
{
ReleaseTokenChain(pTokenargv[k]);
}
if
(pTokenargv != NULL)
{
delete[] pTokenargv;
pTokenargv = NULL;
}
return
r;
}
}
m_sErrInfo.Format(
"非法指令: \'%s\'"
, pTokenHead->pszToken);
return
-1;
}
int CScript::ScanToken(const TOKEN* pTokenHead)
{
ASSERT(pTokenHead != NULL);
//
{ 或 } 必须占一行
if
(pTokenHead->pNext != NULL &&
(pTokenHead->pszToken[0] ==
'{'
|| pTokenHead->pszToken[0] ==
'}'
))
{
m_sErrInfo =
"\'{\' 或 \'}\' 必须独占一行"
;
return
-1;
}
//
扫描有无非法字符
TOKEN* pToken = (TOKEN*)pTokenHead;
while
(pToken != NULL)
{
char ch = pToken->pszToken[0];
if
(ch ==
';'
|| ch ==
'`'
|| ch ==
'@'
|| ch ==
'#'
)
{
m_sErrInfo.Format(
"非法字符 '%c'"
, ch);
return
-1;
}
pToken = pToken->pNext;
}
return
0;
}
//
取下一个有效的行(就是非空行)
int CScript::GetNextEffectLine(int nLine)
{
nLine++;
while
(nLine < m_nLines)
{
if
(m_pLines[nLine].pHead != NULL)
{
return
nLine;
}
nLine++;
}
return
-1;
}
/*
当前行nLine是{, 找下面的对应的 }下面的一行
例如:
{
//nLine
} => 返回这一行
{
//nLine
{
}
} => 返回这一行
*/
int CScript::GetNextPairBraceLine(int nLine)
{
ASSERT(nLine >= 0);
ASSERT(LineIsBrace(nLine));
int k = 0;
while
(nLine < m_nLines)
{
int n = LineIsBrace(nLine);
if
(n == 1)
k++;
if
(n == 2)
k--;
if
(k <= 0)
{
ASSERT(k == 0);
break
;
}
nLine++;
}
if
(nLine >= m_nLines)
return
-1;
ASSERT(LineIsBrace(nLine) == 2);
return
nLine;
}
/*
判断该行是否是 { 或 }
如果是 {返回1, 如果是 }返回2,否则返回0
*/
int CScript::LineIsBrace(int nLine)
{
ASSERT(nLine < m_nLines);
if
(nLine < 0 || nLine >= m_nLines)
return
0;
if
(m_pLines[nLine].pHead == NULL)
return
0;
if
(m_pLines[nLine].pHead->pNext != NULL)
return
0;
char ch = m_pLines[nLine].pHead->pszToken[0];
char ch1 = m_pLines[nLine].pHead->pszToken[1];
if
(ch1 != 0)
return
0;
if
(ch ==
'{'
)
return
1;
else
if
(ch ==
'}'
)
return
2;
else
return
0;
}
/*
执行
if
/while
会有嵌套
if
/while
(..)后面必须是:
{
...
...
if
/while
()
{
...
...
if
/while
()
{
...
...
}
}
}
*/
int CScript::Exec_if_or_while(int if_or_while, BOOL bJmp, IN OUT int* line)
{
ASSERT(if_or_while >= 0);
ASSERT(line != NULL);
const char* pszWord = (if_or_while == LINEIS_IF) ?
"if"
:
"while"
;
//
下一行必须是 {
//
取下一行
int nNextLine = GetNextEffectLine(*line);
if
(nNextLine < 0 || LineIsBrace(nNextLine) != 1)
{
m_sErrInfo.Format(
"语法错误: %s 后面一行必须为 '{'"
, pszWord);
return
-1;
}
//nNextLine
是 { 所在的行
int n = GetNextPairBraceLine(nNextLine);
if
(n < 0)
{
m_sErrInfo.Format(
"语法错误: %s 缺少 '}'"
, pszWord);
return
-1;
}
if
(bJmp)
{
//
执行
if
/while
里面的代码
IF_WHILE_BRACE* pifwhilebrace = new IF_WHILE_BRACE;
pifwhilebrace->if_or_while = if_or_while;
pifwhilebrace->nLine = (*line);
pifwhilebrace->nPairLine = n;
m_ifwhile.AddTail(pifwhilebrace);
*line = nNextLine + 1;
//
执行 { 的下一行
return
0;
}
else
{
//
不执行
if
/while
里面的代码,跳到{ } 外面
*line = n + 1;
return
0;
}
}
/*
处理 } 行
*/
int CScript::ParseRightBrace(IN OUT int* line)
{
ASSERT(LineIsBrace(*line) == 2);
//
找对应的 ifwhile结构
IF_WHILE_BRACE* pifwhile = NULL;
POSITION pos = m_ifwhile.GetHeadPosition();
while
(pos != NULL)
{
IF_WHILE_BRACE* ptmp = m_ifwhile.GetNext(pos);
if
(ptmp->nPairLine == *line)
{
pifwhile = ptmp;
break
;
}
}
if
(pifwhile == NULL)
{
m_sErrInfo =
"语法错误:'}' 位置非法"
;
return
-1;
}
if
(pifwhile->if_or_while == LINEIS_IF)
{
//
执行下一行
(*line)++;
return
0;
}
else
{
ASSERT(pifwhile->if_or_while == LINEIS_WHILE);
//
执行
while
所在行
*line = pifwhile->nLine;
return
0;
}
}
/*
执行一行
*/
int CScript::ExecToken(const TOKEN* pTokenHead, IN OUT int* line)
{
int nTokens = GetTokenCount(pTokenHead);
if
(nTokens == 0)
//
空行
{
(*line)++;
return
0;
}
//
判断是否是var定义,如果是,将变量名称保存起来
BOOL bValid = TRUE;
if
(TokenIs_VarDeclare(pTokenHead, nTokens, &bValid))
{
if
(!bValid)
{
return
-1;
}
(*line)++;
return
0;
}
//
判断是否是赋值语句
if
(TokenIs_Assign(pTokenHead, nTokens, &bValid))
{
if
(!bValid)
{
return
-1;
}
(*line)++;
return
0;
}
//
判断是否是标号
if
(TokenIs_Label(pTokenHead, nTokens))
{
(*line)++;
return
0;
}
//
判断是否是goto
int gotodest = -1;
if
(TokenIs_goto(pTokenHead, nTokens, &gotodest))
{
if
(gotodest < 0)
{
return
-1;
}
*line = gotodest;
return
0;
}
//if/while
int if_or_while = -1;
DWORD dwTemp = 0;
if
(TokenIs_if_while(pTokenHead, nTokens, &if_or_while, &dwTemp))
{
if
(if_or_while < 0)
{
return
-1;
}
return
Exec_if_or_while(if_or_while, (dwTemp != 0), line);
}
//
{ 或 }
if
(LineIsBrace(*line) == 1)
{
//
是 {
m_sErrInfo =
"语法错误:'{' 位置非法"
;
return
-1;
}
if
(LineIsBrace(*line) == 2)
{
//
是 }
if
(ParseRightBrace(line) < 0)
{
return
-1;
}
return
0;
}
//
判断是否是
break
/continue
bValid = TRUE;
if
(TokenIs_break_continue(pTokenHead, nTokens, &bValid, line))
{
if
(!bValid)
{
return
-1;
}
//
return
0;
}
//
执行普通的cmd
if
(ExecNormalCmd(pTokenHead, nTokens) < 0)
{
return
-1;
}
(*line)++;
return
0;
}
int CScript::ExeScript(const char* pszScript, int nLen)
{
ASSERT(pszScript != NULL);
ASSERT(nLen > 0);
m_pszCopy = new char[nLen+1];
if
(m_pszCopy == NULL)
{
m_sErrInfo =
"内存不足"
;
return
-1;
}
strcpy(m_pszCopy, pszScript);
DeleteComment(m_pszCopy, nLen);
m_nLines = GetLineCount(m_pszCopy);
ASSERT(m_nLines > 0);
//
申请内存保存每一行
m_pLines = new LINE[m_nLines];
if
(m_pLines == NULL)
{
m_sErrInfo =
"内存不足"
;
return
-1;
}
memset(m_pLines, 0, sizeof(LINE)*m_nLines);
SaveToLines(m_pszCopy);
//
初始化收集token
for
(int i=0; i<m_nLines; i++)
{
if
(InitLineToken(&m_pLines[i]) != 0)
{
m_errLine = i;
return
-1;
}
}
//
扫描
for
(i=0; i<m_nLines; i++)
{
m_sErrInfo.Empty();
if
(m_pLines[i].pHead != NULL &&
ScanToken(m_pLines[i].pHead) != 0)
{
m_errLine = i;
return
-1;
}
}
BOOL bDebugging = FALSE;
//
如果从调试状态转到非调试状态,那么退出执行
//
开始执行
i = 0;
while
(i < m_nLines && (m_pbRunning == NULL || *m_pbRunning))
{
if
(m_pDebugThread->IsDebugging())
{
bDebugging = TRUE;
}
if
(bDebugging && !m_pDebugThread->IsDebugging())
{
break
;
}
//
跳过空行
if
(m_pLines[i].pHead == NULL)
{
i++;
continue
;
}
if
(m_pScriptView != NULL)
{
//
判断是否是断点
if
(m_pScriptView->LineIsBP(i))
{
*m_pbDebugging = TRUE;
}
m_pScriptView->m_nCurrentLine = i;
if
(*m_pbDebugging)
{
m_pScriptView->SetLineVisible(i);
m_pScriptView->m_pLeftWnd->Invalidate();
}
}
if
(*m_pbDebugging)
{
ASSERT(m_phDebugEvent != NULL);
//
单步调试
ResetEvent(*m_phDebugEvent);
WaitForSingleObject(*m_phDebugEvent, INFINITE);
if
(!(*m_pbRunning))
{
break
;
}
if
(bDebugging && !m_pDebugThread->IsDebugging())
{
break
;
}
}
m_sErrInfo.Empty();
if
(ExecToken(m_pLines[i].pHead, &i) != 0)
{
m_errLine = i;
return
-1;
}
}
return
0;
}