能力值:
( LV7,RANK:100 )
|
-
-
9 楼
// Script.cpp: implementation of the CScript class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MDebug.h"
#include "Script.h"
#include "MainFrm.h"
#include "ScriptGetInputDlg.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define CHAR_ISDIGIT(c) ((c)>='0' && (c)<='9')
#define CHAR_ISCHAR(c) (((c)>='a' && (c)<='z') || ((c)>='A' && (c)<='Z'))
#define CHAR_ISHEXCHAR(c) (CHAR_ISDIGIT(c) || ((c)>='a' && (c)<='f') || ((c)>='A' && (c)<='F'))
#define CHAR_ISBLANK(c) ((c)==' '||(c)=='\t')
#define CHAR_ISEND(c) ((c)=='\0'||(c)=='\r'||(c)=='\n')
#define CHAR_ISMATHOPR(c) ((c)=='+'||(c)=='-'||(c)=='*'||(c)=='/'||(c)=='^'||(c)=='&'||(c)=='|')
#define TOHEXCHAR(c) CHAR_ISDIGIT(c) ? ((c)-'0') : ((c)-'A'+0xA)
#define ISFULLWORDCHAR(x) (((x)>='a'&&(x)<='z') || ((x)>='A'&&(x)<='Z') || CHAR_ISDIGIT(x) || (x) == '_' || (x) == '$')
#define SKIPBLANK(x) while((*x) == ' ' || (*x) == '\t'){(x)++;} //跳过空格和tab
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;
}
|