Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

382 lines
8.8 KiB

  1. /////////////////////////////////////////////////////////////////
  2. //
  3. // File Modified by RogerJ, 03/09/00
  4. //
  5. /////////////////////////////////////////////////////////////////
  6. #include "wudetect.h"
  7. const TCHAR DET_TYPE_FILEVERSION[] = TEXT("FileVer");
  8. const TCHAR DET_TYPE_REGKEYEXISTS[] = TEXT("RegKeyExists");
  9. const TCHAR DET_TYPE_REGKEYSUBSTR[] = TEXT("RegKeySubStr");
  10. const TCHAR DET_TYPE_REGKEYBINARY[] = TEXT("RegKeyBinary");
  11. const TCHAR DET_TYPE_REGKEYVERSION[] = TEXT("RegKeyVersion");
  12. const TCHAR DET_TYPE_40BITSEC[] = TEXT("40BitSec");
  13. void CExpressionParser::vSkipWS(void)
  14. {
  15. while ( ( *m_pch==' ' ) || ( *m_pch=='\t') )
  16. {
  17. m_pch++;
  18. }
  19. }
  20. bool CExpressionParser::fGetCurToken( PARSE_TOKEN_TYPE & tok,
  21. TOKEN_IDENTIFIER *grTokens,
  22. int nSize)
  23. {
  24. bool fError = true;
  25. int index;
  26. vSkipWS();
  27. TCHAR *pchStart = m_pch;
  28. for ( index = 0; index < nSize; index++ )
  29. {
  30. TCHAR *pchTok = grTokens[index].pszTok;
  31. while ( ( *pchTok==*m_pch ) && ( *pchTok!='\0' ) && ( *m_pch!='\0' ) )
  32. {
  33. m_pch++;
  34. pchTok++;
  35. }
  36. if ( *pchTok=='\0' )
  37. {
  38. // match
  39. fError = false;
  40. tok = grTokens[index].tok;
  41. break;
  42. }
  43. else if ( *m_pch == '\0' )
  44. {
  45. fError = false;
  46. tok = TOKEN_DONE;
  47. }
  48. }
  49. if ( (pchStart == m_pch) && (TOKEN_DONE != tok) )
  50. {
  51. // we haven't moved at all so this must be a variable.
  52. fError = false;
  53. tok = TOKEN_VARIABLE;
  54. }
  55. //done:
  56. return fError;
  57. }
  58. bool CExpressionParser::fGetCurTermToken(PARSE_TOKEN_TYPE & tok)
  59. {
  60. static TOKEN_IDENTIFIER grTermTokens[] = {
  61. {TEXT("("), TOKEN_LEFTPAREN},
  62. {TEXT(")"), TOKEN_RIGHTPAREN},
  63. {TEXT("!"), TOKEN_NOT}
  64. };
  65. bool fError = fGetCurToken(tok, grTermTokens, sizeof(grTermTokens)/sizeof(TOKEN_IDENTIFIER));
  66. if ( !fError && (TOKEN_DONE == tok) )
  67. {
  68. fError = true;
  69. }
  70. return fError;
  71. }
  72. bool CExpressionParser::fGetCurExprToken(PARSE_TOKEN_TYPE & tok)
  73. {
  74. static TOKEN_IDENTIFIER grExprTokens[] = {
  75. {TEXT("&&"), TOKEN_AND},
  76. {TEXT("||"), TOKEN_OR}
  77. };
  78. return fGetCurToken(tok, grExprTokens, sizeof(grExprTokens)/sizeof(TOKEN_IDENTIFIER));
  79. }
  80. bool CExpressionParser::fGetVariable(TCHAR *pszVariable)
  81. {
  82. bool fError = false;
  83. TCHAR *pchEnd = m_pch;
  84. while ( _istdigit(*pchEnd) || _istalpha(*pchEnd) )
  85. {
  86. pchEnd++;
  87. }
  88. if ( pchEnd == m_pch )
  89. {
  90. fError = true;
  91. }
  92. else
  93. {
  94. // pointers in IA64 is 64 bits. The third argument of this function
  95. // requires an int (32 bits). Since the variable name should be always
  96. // has a length within 32 bits, a static cast should have no problem.
  97. lstrcpyn(pszVariable, m_pch, (int)(pchEnd - m_pch + 1));
  98. m_pch = pchEnd;
  99. }
  100. return fError;
  101. }
  102. /////////////////////////////////////////////////////////////////////////////
  103. // fGetCifEntry
  104. // Get an entry from the CIF file.
  105. /////////////////////////////////////////////////////////////////////////////
  106. /////////////////////////////////////////////////////////////////////////////
  107. //
  108. // Class CExpressionParser
  109. // Function fGetCifEntry
  110. //---------------------------------------------------------------------------
  111. //
  112. // Return Value --- TRUE if Successfully retrieved CIF file value
  113. // FALSE if failed
  114. // Parameter
  115. // TCHAR* pszParamName --- [IN] Name of the CIF file
  116. // TCHAR* pszParamValue --- [OUT] Value of the CIF file
  117. // DWORD cbParamValue --- size of the pszParamValue in TCHAR
  118. // NOTE: This function calls GetCustomData to retrieve the value of CIF file
  119. // GetCustomData is defined in inseng.h which takes only ANSI strings.
  120. // Thus, UNICODE version of this function needed to convert parameters
  121. // to and from ANSI compatibles.
  122. //
  123. /////////////////////////////////////////////////////////////////////////////
  124. //
  125. // Modified by RogerJ, 03/09/00
  126. // Original Creator Unknown (YanL?)
  127. // Modification --- UNICODE and Win64 enabled
  128. //
  129. /////////////////////////////////////////////////////////////////////////////
  130. bool CExpressionParser::fGetCifEntry(
  131. TCHAR *pszParamName,
  132. TCHAR *pszParamValue,
  133. DWORD cbParamValue)
  134. // pszParamName is [IN], pszParamValue is [OUT], the function GetCustomData requires
  135. // LPSTR for both parameters, string conversion is necessary in the UNICODE case
  136. {
  137. #ifdef _UNICODE
  138. bool fSucceed;
  139. int nLengthOfpszParamName;
  140. char *pszParamNameANSI;
  141. char *pszParamValueANSI;
  142. nLengthOfpszParamName = lstrlen(pszParamName)+1; // including the NULL character
  143. //
  144. // NTBUG9#161019 PREFIX:leaking memory - waltw 8/16/00
  145. // Free ANSI buffers before return in all cases via unicodeExit.
  146. // Also fixed potentially dangerous conversion of uninitialized [OUT] parameter
  147. // and wasteful conversion of [IN] parameter
  148. //
  149. pszParamValueANSI = (char *) malloc(cbParamValue*sizeof(char));
  150. pszParamNameANSI = (char *) malloc(sizeof(char)*nLengthOfpszParamName);
  151. if ((NULL == pszParamValueANSI) || (NULL == pszParamNameANSI))
  152. {
  153. fSucceed = FALSE;
  154. goto unicodeExit;
  155. }
  156. // do UNICODE to ANSI string conversion
  157. wcstombs(pszParamNameANSI,pszParamName,nLengthOfpszParamName);
  158. // wcstombs(pszParamValueANSI,pszParamValue,cbParamValue); // Uninitialized [OUT] buffer - don't convert!
  159. // make actual function call
  160. fSucceed= (ERROR_SUCCESS == m_pDetection->pCifComp->GetCustomData(pszParamNameANSI,
  161. pszParamValueANSI,
  162. cbParamValue));
  163. // do ANSI to UNICODE string conversion
  164. // mbstowcs(pszParamName,pszParamNameANSI,nLengthOfpszParamName); // [IN] param not modified by GetCustomData
  165. mbstowcs(pszParamValue,pszParamValueANSI,cbParamValue);
  166. unicodeExit:
  167. if (NULL != pszParamValueANSI)
  168. {
  169. free(pszParamValueANSI);
  170. }
  171. if (NULL != pszParamNameANSI)
  172. {
  173. free(pszParamNameANSI);
  174. }
  175. return fSucceed;
  176. #else
  177. return (ERROR_SUCCESS == m_pDetection->pCifComp->GetCustomData(pszParamName,
  178. pszParamValue,
  179. cbParamValue));
  180. #endif
  181. }
  182. bool CExpressionParser::fPerformDetection(TCHAR * pszVariable, bool & fResult)
  183. {
  184. bool fError = false;
  185. TCHAR szBuf[MAX_PATH];
  186. TCHAR szDetection[MAX_PATH];
  187. if ( fGetCifEntry(pszVariable, szBuf, sizeof(szBuf)/sizeof(TCHAR)) )
  188. {
  189. if ( GetStringField2(szBuf, 0, szDetection, sizeof(szDetection)/sizeof(TCHAR)) != 0)
  190. {
  191. if ( lstrcmpi(szDetection, DET_TYPE_FILEVERSION) == 0 )
  192. {
  193. fResult = fDetectFileVer(szBuf);
  194. }
  195. else if ( lstrcmpi(szDetection, DET_TYPE_REGKEYEXISTS) == 0 )
  196. {
  197. fResult = fDetectRegKeyExists(szBuf);
  198. }
  199. else if ( lstrcmpi(szDetection, DET_TYPE_REGKEYSUBSTR) == 0 )
  200. {
  201. fResult = fDetectRegSubStr(szBuf);
  202. }
  203. else if ( lstrcmpi(szDetection, DET_TYPE_REGKEYBINARY) == 0 )
  204. {
  205. fResult = fDetectRegBinary(szBuf);
  206. }
  207. else if ( lstrcmpi(szDetection, DET_TYPE_REGKEYVERSION) == 0 )
  208. {
  209. fResult = fDetectRegKeyVersion(szBuf);
  210. }
  211. else if ( lstrcmpi(szDetection, DET_TYPE_40BITSEC) == 0 )
  212. {
  213. fResult = fDetect40BitSecurity(szBuf);
  214. }
  215. }
  216. }
  217. return fError;
  218. }
  219. bool CExpressionParser::fEvalTerm(bool & fResult, bool fSkip)
  220. {
  221. PARSE_TOKEN_TYPE tok;
  222. bool fError = fGetCurTermToken(tok);
  223. if ( fError ) goto done;
  224. if ( TOKEN_LEFTPAREN == tok )
  225. {
  226. fError = fEvalExpr(fResult);
  227. if ( fError ) goto done;
  228. fError = fGetCurTermToken(tok);
  229. if ( fError ) goto done;
  230. if ( TOKEN_RIGHTPAREN != tok )
  231. {
  232. fError = true;
  233. }
  234. }
  235. else if ( TOKEN_NOT == tok )
  236. {
  237. fError = fEvalTerm(fResult, false);
  238. if ( fError ) goto done;
  239. fResult = !fResult;
  240. }
  241. else // TOKEN_VARIABLE == tok
  242. {
  243. TCHAR szVariable[MAX_PATH];
  244. fError = fGetVariable(szVariable);
  245. if ( fError ) goto done;
  246. if ( !fSkip )
  247. {
  248. fError = fPerformDetection(szVariable, fResult);
  249. if ( fError ) goto done;
  250. }
  251. }
  252. done:
  253. return fError;
  254. }
  255. HRESULT CExpressionParser::fEvalExpression(TCHAR * pszExpr,
  256. bool * pfResult)
  257. {
  258. HRESULT hr = S_OK;
  259. m_pch = pszExpr;
  260. if ( fEvalExpr(*pfResult) )
  261. {
  262. hr = E_FAIL;
  263. }
  264. return hr;
  265. }
  266. bool CExpressionParser::fEvalExpr(bool & fResult)
  267. {
  268. bool fTmpResult;
  269. PARSE_TOKEN_TYPE tok;
  270. bool fError = fEvalTerm(fResult, false);
  271. if ( fError ) goto done;
  272. while ( TRUE )
  273. {
  274. fError = fGetCurExprToken(tok);
  275. if ( fError ) goto done;
  276. if ( TOKEN_AND == tok )
  277. {
  278. fError = fEvalTerm(fTmpResult, !fResult);
  279. if ( fError ) goto done;
  280. if ( fResult )
  281. {
  282. fResult = fResult && fTmpResult;
  283. }
  284. }
  285. else if ( TOKEN_OR == tok )
  286. {
  287. fError = fEvalTerm(fTmpResult, fResult);
  288. if ( fError ) goto done;
  289. if ( !fResult )
  290. {
  291. fResult = fResult || fTmpResult;
  292. }
  293. }
  294. else // if ( TOKEN_DONE == tok )
  295. {
  296. break;
  297. }
  298. }
  299. done:
  300. return fError;
  301. }
  302. // The codes Under this line is not compiled, so they are not UNICODE ready
  303. #if 0
  304. void Evaluate(TCHAR *pszExpr)
  305. {
  306. bool fResult;
  307. HRESULT hr = fEvalExpression(pszExpr, &fResult);
  308. if ( FAILED(hr) )
  309. printf("%s == ERROR\n", pszExpr);
  310. else
  311. printf("%s == %c\n", pszExpr, fResult ? 'T' : 'F');
  312. }
  313. int main()
  314. {
  315. Evaluate(TEXT("((T && F) || !F || T)"));
  316. Evaluate(TEXT("F || F || (T && T && F)"));
  317. Evaluate(TEXT("((T && F) || !F || T)"));
  318. Evaluate(TEXT(""));
  319. Evaluate(TEXT("T"));
  320. Evaluate(TEXT("F||T"));
  321. Evaluate(TEXT("!F"));
  322. return 0;
  323. }
  324. #endif