|
|
/////////////////////////////////////////////////////////////////
//
// File Modified by RogerJ, 03/09/00
//
/////////////////////////////////////////////////////////////////
#include "wudetect.h"
const TCHAR DET_TYPE_FILEVERSION[] = TEXT("FileVer"); const TCHAR DET_TYPE_REGKEYEXISTS[] = TEXT("RegKeyExists"); const TCHAR DET_TYPE_REGKEYSUBSTR[] = TEXT("RegKeySubStr"); const TCHAR DET_TYPE_REGKEYBINARY[] = TEXT("RegKeyBinary"); const TCHAR DET_TYPE_REGKEYVERSION[] = TEXT("RegKeyVersion"); const TCHAR DET_TYPE_40BITSEC[] = TEXT("40BitSec");
void CExpressionParser::vSkipWS(void) { while ( ( *m_pch==' ' ) || ( *m_pch=='\t') ) { m_pch++; } }
bool CExpressionParser::fGetCurToken( PARSE_TOKEN_TYPE & tok, TOKEN_IDENTIFIER *grTokens, int nSize) { bool fError = true; int index;
vSkipWS();
TCHAR *pchStart = m_pch;
for ( index = 0; index < nSize; index++ ) { TCHAR *pchTok = grTokens[index].pszTok; while ( ( *pchTok==*m_pch ) && ( *pchTok!='\0' ) && ( *m_pch!='\0' ) ) { m_pch++; pchTok++; }
if ( *pchTok=='\0' ) { // match
fError = false; tok = grTokens[index].tok; break; } else if ( *m_pch == '\0' ) { fError = false; tok = TOKEN_DONE; } }
if ( (pchStart == m_pch) && (TOKEN_DONE != tok) ) { // we haven't moved at all so this must be a variable.
fError = false; tok = TOKEN_VARIABLE; }
//done:
return fError; }
bool CExpressionParser::fGetCurTermToken(PARSE_TOKEN_TYPE & tok) { static TOKEN_IDENTIFIER grTermTokens[] = { {TEXT("("), TOKEN_LEFTPAREN}, {TEXT(")"), TOKEN_RIGHTPAREN}, {TEXT("!"), TOKEN_NOT} };
bool fError = fGetCurToken(tok, grTermTokens, sizeof(grTermTokens)/sizeof(TOKEN_IDENTIFIER));
if ( !fError && (TOKEN_DONE == tok) ) { fError = true; }
return fError; }
bool CExpressionParser::fGetCurExprToken(PARSE_TOKEN_TYPE & tok) { static TOKEN_IDENTIFIER grExprTokens[] = { {TEXT("&&"), TOKEN_AND}, {TEXT("||"), TOKEN_OR} };
return fGetCurToken(tok, grExprTokens, sizeof(grExprTokens)/sizeof(TOKEN_IDENTIFIER)); }
bool CExpressionParser::fGetVariable(TCHAR *pszVariable) { bool fError = false; TCHAR *pchEnd = m_pch;
while ( _istdigit(*pchEnd) || _istalpha(*pchEnd) ) { pchEnd++; }
if ( pchEnd == m_pch ) { fError = true; } else { // pointers in IA64 is 64 bits. The third argument of this function
// requires an int (32 bits). Since the variable name should be always
// has a length within 32 bits, a static cast should have no problem.
lstrcpyn(pszVariable, m_pch, (int)(pchEnd - m_pch + 1)); m_pch = pchEnd; }
return fError; }
/////////////////////////////////////////////////////////////////////////////
// fGetCifEntry
// Get an entry from the CIF file.
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
// Class CExpressionParser
// Function fGetCifEntry
//---------------------------------------------------------------------------
//
// Return Value --- TRUE if Successfully retrieved CIF file value
// FALSE if failed
// Parameter
// TCHAR* pszParamName --- [IN] Name of the CIF file
// TCHAR* pszParamValue --- [OUT] Value of the CIF file
// DWORD cbParamValue --- size of the pszParamValue in TCHAR
// NOTE: This function calls GetCustomData to retrieve the value of CIF file
// GetCustomData is defined in inseng.h which takes only ANSI strings.
// Thus, UNICODE version of this function needed to convert parameters
// to and from ANSI compatibles.
//
/////////////////////////////////////////////////////////////////////////////
//
// Modified by RogerJ, 03/09/00
// Original Creator Unknown (YanL?)
// Modification --- UNICODE and Win64 enabled
//
/////////////////////////////////////////////////////////////////////////////
bool CExpressionParser::fGetCifEntry( TCHAR *pszParamName, TCHAR *pszParamValue, DWORD cbParamValue) // pszParamName is [IN], pszParamValue is [OUT], the function GetCustomData requires
// LPSTR for both parameters, string conversion is necessary in the UNICODE case
{ #ifdef _UNICODE
bool fSucceed; int nLengthOfpszParamName; char *pszParamNameANSI; char *pszParamValueANSI;
nLengthOfpszParamName = lstrlen(pszParamName)+1; // including the NULL character
//
// NTBUG9#161019 PREFIX:leaking memory - waltw 8/16/00
// Free ANSI buffers before return in all cases via unicodeExit.
// Also fixed potentially dangerous conversion of uninitialized [OUT] parameter
// and wasteful conversion of [IN] parameter
//
pszParamValueANSI = (char *) malloc(cbParamValue*sizeof(char)); pszParamNameANSI = (char *) malloc(sizeof(char)*nLengthOfpszParamName); if ((NULL == pszParamValueANSI) || (NULL == pszParamNameANSI)) { fSucceed = FALSE; goto unicodeExit; }
// do UNICODE to ANSI string conversion
wcstombs(pszParamNameANSI,pszParamName,nLengthOfpszParamName); // wcstombs(pszParamValueANSI,pszParamValue,cbParamValue); // Uninitialized [OUT] buffer - don't convert!
// make actual function call
fSucceed= (ERROR_SUCCESS == m_pDetection->pCifComp->GetCustomData(pszParamNameANSI, pszParamValueANSI, cbParamValue)); // do ANSI to UNICODE string conversion
// mbstowcs(pszParamName,pszParamNameANSI,nLengthOfpszParamName); // [IN] param not modified by GetCustomData
mbstowcs(pszParamValue,pszParamValueANSI,cbParamValue);
unicodeExit: if (NULL != pszParamValueANSI) { free(pszParamValueANSI); }
if (NULL != pszParamNameANSI) { free(pszParamNameANSI); }
return fSucceed;
#else
return (ERROR_SUCCESS == m_pDetection->pCifComp->GetCustomData(pszParamName, pszParamValue, cbParamValue)); #endif
}
bool CExpressionParser::fPerformDetection(TCHAR * pszVariable, bool & fResult) { bool fError = false; TCHAR szBuf[MAX_PATH]; TCHAR szDetection[MAX_PATH]; if ( fGetCifEntry(pszVariable, szBuf, sizeof(szBuf)/sizeof(TCHAR)) ) { if ( GetStringField2(szBuf, 0, szDetection, sizeof(szDetection)/sizeof(TCHAR)) != 0) { if ( lstrcmpi(szDetection, DET_TYPE_FILEVERSION) == 0 ) { fResult = fDetectFileVer(szBuf); } else if ( lstrcmpi(szDetection, DET_TYPE_REGKEYEXISTS) == 0 ) { fResult = fDetectRegKeyExists(szBuf); } else if ( lstrcmpi(szDetection, DET_TYPE_REGKEYSUBSTR) == 0 ) { fResult = fDetectRegSubStr(szBuf); } else if ( lstrcmpi(szDetection, DET_TYPE_REGKEYBINARY) == 0 ) { fResult = fDetectRegBinary(szBuf); } else if ( lstrcmpi(szDetection, DET_TYPE_REGKEYVERSION) == 0 ) { fResult = fDetectRegKeyVersion(szBuf); } else if ( lstrcmpi(szDetection, DET_TYPE_40BITSEC) == 0 ) { fResult = fDetect40BitSecurity(szBuf); } } }
return fError; }
bool CExpressionParser::fEvalTerm(bool & fResult, bool fSkip) { PARSE_TOKEN_TYPE tok;
bool fError = fGetCurTermToken(tok); if ( fError ) goto done;
if ( TOKEN_LEFTPAREN == tok ) { fError = fEvalExpr(fResult); if ( fError ) goto done; fError = fGetCurTermToken(tok); if ( fError ) goto done;
if ( TOKEN_RIGHTPAREN != tok ) { fError = true; } } else if ( TOKEN_NOT == tok ) { fError = fEvalTerm(fResult, false); if ( fError ) goto done;
fResult = !fResult; } else // TOKEN_VARIABLE == tok
{ TCHAR szVariable[MAX_PATH];
fError = fGetVariable(szVariable); if ( fError ) goto done; if ( !fSkip ) { fError = fPerformDetection(szVariable, fResult); if ( fError ) goto done; } }
done: return fError; }
HRESULT CExpressionParser::fEvalExpression(TCHAR * pszExpr, bool * pfResult) { HRESULT hr = S_OK; m_pch = pszExpr;
if ( fEvalExpr(*pfResult) ) { hr = E_FAIL; }
return hr; }
bool CExpressionParser::fEvalExpr(bool & fResult) { bool fTmpResult; PARSE_TOKEN_TYPE tok; bool fError = fEvalTerm(fResult, false); if ( fError ) goto done; while ( TRUE ) { fError = fGetCurExprToken(tok); if ( fError ) goto done;
if ( TOKEN_AND == tok ) { fError = fEvalTerm(fTmpResult, !fResult); if ( fError ) goto done;
if ( fResult ) { fResult = fResult && fTmpResult; } } else if ( TOKEN_OR == tok ) { fError = fEvalTerm(fTmpResult, fResult); if ( fError ) goto done;
if ( !fResult ) { fResult = fResult || fTmpResult; } } else // if ( TOKEN_DONE == tok )
{ break; } }
done: return fError; }
// The codes Under this line is not compiled, so they are not UNICODE ready
#if 0
void Evaluate(TCHAR *pszExpr) { bool fResult; HRESULT hr = fEvalExpression(pszExpr, &fResult);
if ( FAILED(hr) ) printf("%s == ERROR\n", pszExpr); else printf("%s == %c\n", pszExpr, fResult ? 'T' : 'F'); }
int main() { Evaluate(TEXT("((T && F) || !F || T)")); Evaluate(TEXT("F || F || (T && T && F)")); Evaluate(TEXT("((T && F) || !F || T)")); Evaluate(TEXT("")); Evaluate(TEXT("T")); Evaluate(TEXT("F||T")); Evaluate(TEXT("!F"));
return 0; } #endif
|