Advertisement
Guest User

Untitled

a guest
Feb 8th, 2016
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.18 KB | None | 0 0
  1. //
  2. // debugger.cpp
  3. //
  4. // The MSEC Debugger Functions
  5. //
  6. //
  7. // Developed by the Microsoft Security Engineering Center (MSEC)
  8. // Copyright 2008-2013, Microsoft Corporation
  9. //
  10. // Microsoft Public License (Ms-PL)
  11. // This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.
  12. //
  13. // Definitions
  14. // The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor's patent claims that read directly on its contribution.
  15. // Grant of Rights
  16. // (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
  17. // (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
  18. // Conditions and Limitations
  19. // (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
  20. // (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
  21. // (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
  22. // (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
  23. // (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees, or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
  24. //
  25.  
  26. #define DEBUGGER_MODULE
  27. #include "stdafx.h"
  28.  
  29. #include "debugger.h"
  30. #include "utility.h"
  31.  
  32.  
  33. // global variable used to hold the user include aditions list
  34. LPSTR* _lppszAditionalExcludeSymbols = NULL;
  35. // global variable used to check for initialization
  36. BOOL _bInitialized = FALSE;
  37.  
  38.  
  39. ///
  40. // Find a register flag, and return the value. This function returns false if no such flag could be found
  41. bool
  42. GetProcessorFlagByName( const DEBUGGER_CONTROLS &objControls, PCWSTR pwzFlag )
  43. {
  44. ULONG iRegister;
  45. DEBUG_VALUE objRegister;
  46.  
  47. if( objControls.pDebugRegisters->GetIndexByNameWide( pwzFlag, &iRegister ) == S_OK )
  48. {
  49. if( objControls.pDebugRegisters->GetValue( iRegister, &objRegister ) == S_OK )
  50. {
  51. return (objRegister.I64 != 0);
  52. }
  53. }
  54.  
  55. return( false );
  56. }
  57.  
  58.  
  59. /// Calculate the stack hash given a stack to work from
  60. void
  61. CalculateStackHash( const DEBUGGER_CONTROLS& objDebugger, ULONG cStackFrames, __in_ecount(cStackFrames) DEBUG_STACK_FRAME* pStackFrames, HASHING_MODE eHashMode, __out ULONG* pdwMajorHash, __out ULONG* pdwMinorHash )
  62. {
  63.  
  64.  
  65. CalculateStackHash( objDebugger, cStackFrames, pStackFrames,eHashMode, NULL, NULL, NULL, pdwMajorHash, pdwMinorHash );
  66. }
  67.  
  68.  
  69. void CalculateStackHash( const DEBUGGER_CONTROLS& objDebugger,
  70. ULONG cStackFrames,
  71. __in_ecount(cStackFrames) DEBUG_STACK_FRAME* pStackFrames,
  72. HASHING_MODE eHashMode,
  73. _Out_writes_opt_(cStackFrames) bool* pfUnknownStackFrames,
  74. _Out_writes_opt_(cStackFrames) bool* pfExcludedStackFrames,
  75. __out_opt bool *pfStackContainsUnknownSymbols,
  76. __out ULONG* pdwMajorHash,
  77. __out ULONG* pdwMinorHash )
  78. {
  79. // Initialize the hashes
  80. *pdwMajorHash = 0UL;
  81. *pdwMinorHash = 0UL;
  82.  
  83. DetermineUnknownandExcludedFrames( objDebugger,
  84. cStackFrames,
  85. pStackFrames,
  86. pfUnknownStackFrames,
  87. pfExcludedStackFrames,
  88. pfStackContainsUnknownSymbols);
  89.  
  90. switch (eHashMode)
  91. {
  92. case CUSTOMV1:
  93. CalculateHashCustomV1(objDebugger,cStackFrames,pStackFrames,pdwMajorHash,pdwMinorHash);
  94. break;
  95. case CUSTOMV2:
  96. CalculateHashCustomV2(objDebugger,cStackFrames,pStackFrames,pdwMajorHash,pdwMinorHash);
  97. break;
  98. case SHA256:
  99. CalculateHashSHA256(objDebugger,cStackFrames,pStackFrames,pdwMajorHash,pdwMinorHash);
  100. break;
  101. }
  102.  
  103. }
  104.  
  105. void
  106. DetermineUnknownandExcludedFrames(const DEBUGGER_CONTROLS& objDebugger, ULONG cStackFrames, __in_ecount(cStackFrames) DEBUG_STACK_FRAME* pStackFrames, _Out_writes_opt_(cStackFrames) bool* pfUnknownStackFrames,_Out_writes_opt_(cStackFrames) bool* pfExcludedStackFrames, __out_opt bool *pfStackContainsUnknownSymbols )
  107. {
  108. CHAR pszName[128];
  109. ULONG cchName;
  110. ULONG64 offDisplacement;
  111. ULONG64 offInstructionPointer;
  112. pszName[127]=0;
  113.  
  114. if( pfStackContainsUnknownSymbols )
  115. {
  116. *pfStackContainsUnknownSymbols = false;
  117. }
  118.  
  119. // Initialize the hashes
  120. objDebugger.pDebugRegisters->GetInstructionOffset( &offInstructionPointer );
  121.  
  122.  
  123. // Iterate through the stack frames, constructing the hash
  124. for (ULONG iFrame =0; iFrame < cStackFrames; iFrame++)
  125. {
  126. HRESULT dwResult = objDebugger.pDebugSymbols->GetNameByOffset(pStackFrames[iFrame].InstructionOffset, pszName, 127, (PULONG)&cchName, (PULONG64)&offDisplacement);
  127.  
  128. if( dwResult == E_FAIL )
  129. {
  130. if( pfStackContainsUnknownSymbols )
  131. {
  132. *pfStackContainsUnknownSymbols = true;
  133. }
  134.  
  135. if( pfUnknownStackFrames )
  136. {
  137. pfUnknownStackFrames[iFrame] = true;
  138. }
  139. }
  140. else
  141. {
  142. if( pfUnknownStackFrames )
  143. {
  144. pfUnknownStackFrames[iFrame] = false;
  145. }
  146. }
  147.  
  148. if( !IsSymbolExcluded( pszName ) )
  149. {
  150.  
  151. if( pfExcludedStackFrames )
  152. {
  153. pfExcludedStackFrames[iFrame] = false;
  154. }
  155. }
  156. else
  157. {
  158. if( pfExcludedStackFrames )
  159. {
  160. pfExcludedStackFrames[iFrame] = true;
  161. }
  162. }
  163. }
  164. }
  165.  
  166. void
  167. CalculateHashCustomV1(const DEBUGGER_CONTROLS& objDebugger,ULONG cStackFrames,__in_ecount(cStackFrames) DEBUG_STACK_FRAME* pStackFrames, __inout ULONG* pdwMajorHash, __inout ULONG* pdwMinorHash ){
  168.  
  169. CHAR pszName[128];
  170. CHAR pszDisplacement[16];
  171. ULONG cchName;
  172. ULONG64 offDisplacement;
  173.  
  174. ULONG dwSalt = 0;
  175. ULONG cHash = 0;
  176. pszName[127]=0;
  177.  
  178. // Initialize the hashes
  179. *pdwMajorHash = 0UL;
  180. *pdwMinorHash = 0UL;
  181.  
  182. // Iterate through the stack frames, constructing the hash
  183. for (ULONG iFrame =0; iFrame < cStackFrames; iFrame++)
  184. {
  185. HRESULT dwResult = objDebugger.pDebugSymbols->GetNameByOffset(pStackFrames[iFrame].InstructionOffset, pszName, 127, (PULONG)&cchName, (PULONG64)&offDisplacement);
  186.  
  187. if( dwResult == E_FAIL )
  188. {
  189. strcpy_s( pszName, "Unknown" );
  190. offDisplacement = 0;
  191. } else {
  192. _strlwr_s( pszName );
  193. }
  194.  
  195. if( !IsSymbolExcluded( pszName ) )
  196. {
  197. for (int iBuffer = 0; pszName[iBuffer] != 0 && (ULONG)iBuffer < cchName; iBuffer++)
  198. {
  199. *pdwMinorHash ^= ((ULONG)pszName[iBuffer] << (dwSalt * 8));
  200.  
  201.  
  202. if (cHash < MAJOR_HASH_STACK_DEPTH )
  203. {
  204. *pdwMajorHash ^= ((ULONG)pszName[iBuffer] << (dwSalt * 8));
  205. }
  206.  
  207. dwSalt = (dwSalt + 1) % 4;
  208.  
  209. }
  210.  
  211. // update the hash count
  212. ++cHash;
  213.  
  214. // add displacement for the long hash, mixing in frame number
  215. *pdwMinorHash ^= ((ULONG)'+' << (dwSalt * 8));
  216.  
  217. _ltoa_s((LONG)offDisplacement, pszDisplacement, sizeof(pszDisplacement), 16);
  218.  
  219. for (int iBuffer = 0; pszDisplacement[iBuffer] != 0 && iBuffer < 16; iBuffer++)
  220. {
  221. *pdwMinorHash ^= ((ULONG)pszDisplacement[iBuffer] << (dwSalt * 8));
  222. }
  223.  
  224.  
  225. }
  226. }
  227. }
  228.  
  229. void
  230. CalculateHashCustomV2(const DEBUGGER_CONTROLS& objDebugger,ULONG cStackFrames,__in_ecount(cStackFrames) DEBUG_STACK_FRAME* pStackFrames, __inout ULONG* pdwMajorHash, __inout ULONG* pdwMinorHash ){
  231.  
  232. CHAR pszName[128];
  233. ULONG cchName;
  234. ULONG64 offDisplacement;
  235.  
  236. ULONG cHash = 0;
  237. pszName[127]=0;
  238.  
  239. // Initialize the hashes
  240. *pdwMajorHash = 0UL;
  241. *pdwMinorHash = 0UL;
  242.  
  243. // Iterate through the stack frames, constructing the hash
  244. for (ULONG iFrame =0; iFrame < cStackFrames; iFrame++)
  245. {
  246. HRESULT dwResult = objDebugger.pDebugSymbols->GetNameByOffset(pStackFrames[iFrame].InstructionOffset, pszName, 127, (PULONG)&cchName, (PULONG64)&offDisplacement);
  247.  
  248. if( dwResult == E_FAIL )
  249. {
  250. strcpy_s( pszName, "Unknown" );
  251. offDisplacement = 0;
  252. }
  253.  
  254. if( !IsSymbolExcluded( pszName ) )
  255. {
  256. for (int iBuffer = 0; pszName[iBuffer] != 0 && (ULONG)iBuffer < cchName; iBuffer++)
  257. {
  258. *pdwMinorHash = ROL(*pdwMinorHash,5) ^ (ULONG) ::tolower( pszName[iBuffer] );
  259.  
  260. if (cHash < MAJOR_HASH_STACK_DEPTH )
  261. {
  262. *pdwMajorHash = ROL(*pdwMajorHash,5) ^ (ULONG) ::tolower(pszName[iBuffer] );
  263. }
  264.  
  265. }
  266. // add displacement for the long hash, mixing in frame number
  267. *pdwMinorHash ^= offDisplacement * (iFrame + 1);
  268.  
  269. // update the hash count
  270. ++cHash;
  271. }
  272. }
  273. }
  274.  
  275. void
  276. CalculateHashSHA256(const DEBUGGER_CONTROLS& objDebugger,ULONG cStackFrames,__in_ecount(cStackFrames) DEBUG_STACK_FRAME* pStackFrames ,__inout ULONG* pdwMajorHash, __inout ULONG* pdwMinorHash )
  277. {
  278.  
  279. CHAR pszName[128];
  280. size_t cchName;
  281. ULONG64 offDisplacement;
  282.  
  283. ULONG cHash = 0;
  284.  
  285. CHAR buffer[65];
  286. CHAR * bufferSeperator ="+0x";
  287.  
  288. pszName[127]=0;
  289. // Initialize the hashes
  290. *pdwMajorHash = 0UL;
  291. *pdwMinorHash = 0UL;
  292.  
  293. HCRYPTPROV hProv = 0;
  294. HCRYPTHASH hMajorHash = 0;
  295. HCRYPTHASH hMinorHash = 0;
  296. DWORD rgbHash[8];
  297. DWORD cbHash = sizeof(rgbHash);
  298.  
  299. if(!CryptAcquireContext(&hProv,
  300. NULL,
  301. NULL,
  302. PROV_RSA_AES,
  303. CRYPT_VERIFYCONTEXT))
  304. {
  305. OutputDebugStringA("HASH : FAIL : CryptAcquireContext");
  306. goto cleanup;
  307. }
  308.  
  309. if(!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hMajorHash))
  310. {
  311. OutputDebugStringA("HASH : FAIL : CryptCreateHash");
  312. goto cleanup;
  313. }
  314. if(!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hMinorHash))
  315. {
  316. OutputDebugStringA("HASH : FAIL : CryptCreateHash");
  317. goto cleanup;
  318. }
  319.  
  320.  
  321. // Iterate through the stack frames, constructing the hash
  322. for (ULONG iFrame =0; iFrame < cStackFrames; iFrame++)
  323. {
  324. HRESULT dwResult = objDebugger.pDebugSymbols->GetNameByOffset(pStackFrames[iFrame].InstructionOffset, pszName, 127, (PULONG)&cchName, (PULONG64)&offDisplacement);
  325.  
  326. if( dwResult == E_FAIL )
  327. {
  328. strcpy_s( pszName, "Unknown" );
  329. offDisplacement = 0;
  330. }
  331.  
  332. if( !IsSymbolExcluded( pszName ) )
  333. {
  334.  
  335. cchName = strnlen_s(pszName,_countof(pszName));
  336.  
  337. // get hash of the symbol part of the frame for minor
  338. if(!CryptHashData(hMinorHash,(const BYTE *) pszName,(DWORD)cchName* sizeof(CHAR), 0)) {
  339. OutputDebugStringA("HASH : FAIL : CryptHashData");
  340. goto cleanup;
  341. }
  342.  
  343. // get hash of the symbol part of the frame for major
  344. if (cHash < MAJOR_HASH_STACK_DEPTH ){
  345. if(!CryptHashData(hMajorHash,(const BYTE *) pszName, (DWORD)cchName* sizeof(CHAR), 0)) {
  346. OutputDebugStringA("HASH : FAIL : CryptHashData");
  347. goto cleanup;
  348. }
  349. }
  350.  
  351.  
  352.  
  353. if (offDisplacement != 0){
  354.  
  355.  
  356. // get has of the seperator of the symbol and displacement
  357. if(!CryptHashData(hMinorHash,(const BYTE *) bufferSeperator, sizeof(bufferSeperator), 0)) {
  358. OutputDebugStringA("HASH : FAIL : CryptHashData");
  359. goto cleanup;
  360. }
  361.  
  362.  
  363. _ui64toa_s(offDisplacement,buffer,sizeof(buffer),16);
  364.  
  365. size_t bufferSize = strnlen_s(buffer,_countof(buffer));
  366.  
  367. // get has of displacement viewed as a string. This way it should be the same if a person copies the frame from a debug session;
  368. if(!CryptHashData(hMinorHash,(const BYTE *) buffer, (DWORD)bufferSize * sizeof(CHAR), 0)) {
  369. OutputDebugStringA("HASH : FAIL : CryptHashData");
  370. goto cleanup;
  371. }
  372. }
  373. }
  374. // update the hash count
  375. ++cHash;
  376. }
  377.  
  378. if (!CryptGetHashParam(hMinorHash, HP_HASHVAL, (BYTE *)rgbHash, &cbHash, 0)){
  379. OutputDebugStringA("HASH : FAIL : CryptGetHashParam");
  380. goto cleanup;
  381. }
  382. for (int i = 0; (DWORD)i < _countof(rgbHash); i++)
  383. *pdwMinorHash ^= rgbHash[i];
  384.  
  385. if (!CryptGetHashParam(hMajorHash, HP_HASHVAL, (BYTE *)rgbHash, &cbHash, 0)){
  386. OutputDebugStringA("HASH : FAIL : CryptGetHashParam");
  387. goto cleanup;
  388. }
  389.  
  390. for (int i = 0; (DWORD)i < _countof(rgbHash); i++)
  391. *pdwMajorHash ^= rgbHash[i];
  392.  
  393. cleanup:
  394. if (hMajorHash)
  395. {
  396. if (!CryptDestroyHash(hMajorHash)){
  397. OutputDebugStringA("HASH : FAIL : CryptDestroyHash");
  398. }
  399. }
  400. if (hMinorHash)
  401. {
  402. if(!CryptDestroyHash(hMinorHash)){
  403. OutputDebugStringA("HASH : FAIL : CryptDestroyHash");
  404. }
  405. }
  406. if (hProv)
  407. {
  408. if(!CryptReleaseContext(hProv, 0)){
  409. OutputDebugStringA("HASH : FAIL : CryptReleaseContext");
  410. }
  411. }
  412. }
  413.  
  414.  
  415. bool
  416. LoadCustomExcludeList(HMODULE hModule)
  417. {
  418.  
  419.  
  420. if (_bInitialized)
  421. return FALSE;
  422.  
  423. CHAR lpFileName [MAX_PATH];
  424. DWORD cFileName = GetModuleFileNameA(hModule,lpFileName,_countof(lpFileName));
  425. if (cFileName == 0)
  426. {
  427. return FALSE;
  428. }
  429. LPSTR lpszLastIndex= strrchr(lpFileName,L'\\');
  430. if (lpszLastIndex == NULL)
  431. {
  432. return FALSE;
  433. }
  434.  
  435. int spaceLeft = _countof(lpFileName) + lstrlenA(lpszLastIndex) - lstrlenA(lpFileName) -1;
  436. if (spaceLeft <= lstrlenA("\\Exploitable.ini"))
  437. {
  438. return FALSE;
  439. }
  440.  
  441. errno_t error = strncpy_s(lpszLastIndex,spaceLeft,"\\Exploitable.ini",_countof("\\Exploitable.ini"));
  442. if (error != 0)
  443. {
  444. return FALSE;
  445. }
  446.  
  447. LPSTR * ppszFilterList = NULL;
  448. LPSTR lpSectionHeapBuffer = NULL;
  449. const int MAX_SECTION_SIZE = 32767; //max possible size according to msdn GetPrivateProfileSectionA
  450. LPSTR lpSectionBuffer = new CHAR[MAX_SECTION_SIZE];
  451.  
  452. if (lpSectionBuffer == NULL)
  453. {
  454. goto fail;
  455. }
  456.  
  457. DWORD cSectionBuffer = GetPrivateProfileSectionA("HashExcludePatterns",lpSectionBuffer,MAX_SECTION_SIZE,lpFileName);
  458.  
  459. if (cSectionBuffer <= 2 || cSectionBuffer == (MAX_SECTION_SIZE-2)) //no entries or, buffer is not big enough
  460. {
  461. goto fail;
  462. }
  463.  
  464.  
  465. lpSectionHeapBuffer = new CHAR [cSectionBuffer+1];
  466.  
  467. if (lpSectionHeapBuffer == NULL)
  468. {
  469. goto fail;
  470. }
  471.  
  472.  
  473. error = memcpy_s(lpSectionHeapBuffer,(cSectionBuffer+1) * sizeof(CHAR),lpSectionBuffer,cSectionBuffer+1 );
  474. if (error != 0)
  475. {
  476. goto fail;
  477. }
  478.  
  479. if (lpSectionBuffer !=NULL)
  480. {
  481. delete [] lpSectionBuffer;
  482. lpSectionBuffer = NULL;
  483. }
  484.  
  485. lpSectionHeapBuffer[cSectionBuffer] = NULL;
  486. lpSectionHeapBuffer[cSectionBuffer-1] = NULL;
  487.  
  488.  
  489. int cLineCount = 0;
  490. for (DWORD index = 0; index <= cSectionBuffer; index++)
  491. {
  492. if (lpSectionHeapBuffer[index] == NULL)
  493. ++cLineCount;
  494. }
  495.  
  496. ppszFilterList = new LPSTR [cLineCount];
  497.  
  498. if (!ppszFilterList)
  499. {
  500. goto fail;
  501. }
  502. int cLineIndex = 0;
  503. LPSTR token = lpSectionHeapBuffer;
  504. while( *token != NULL )
  505. {
  506. ppszFilterList[cLineIndex++] = token;
  507. token += (lstrlenA(token)+1) * sizeof(CHAR);
  508. }
  509.  
  510. ppszFilterList[cLineCount-1] = NULL;
  511.  
  512. _lppszAditionalExcludeSymbols = ppszFilterList;
  513. return TRUE;
  514.  
  515. fail:
  516.  
  517. if (lpSectionBuffer) {
  518. delete [] lpSectionBuffer;
  519. lpSectionBuffer = NULL;
  520. }
  521.  
  522. if (lpSectionHeapBuffer){
  523. delete[] lpSectionHeapBuffer;
  524. lpSectionHeapBuffer = NULL;
  525. }
  526. if (ppszFilterList){
  527. delete[] ppszFilterList;
  528. ppszFilterList = NULL;
  529. }
  530.  
  531. return FALSE;
  532. }
  533.  
  534. void UnloadCustomExcludeList(){
  535. if (_bInitialized)
  536. {
  537. if (_lppszAditionalExcludeSymbols)
  538. {
  539. if (*_lppszAditionalExcludeSymbols){
  540. free(*_lppszAditionalExcludeSymbols);
  541. *_lppszAditionalExcludeSymbols = NULL;
  542. }
  543. free(_lppszAditionalExcludeSymbols);
  544. _lppszAditionalExcludeSymbols = NULL;
  545. }
  546. _bInitialized = false;
  547. }
  548. }
  549.  
  550.  
  551. ///
  552. // Determine whether or not a symbol is excluded from the hash algorithm or blame assignment
  553. bool
  554. IsSymbolExcluded( PCSTR pszSymbol )
  555. {
  556.  
  557.  
  558.  
  559.  
  560. // Check Hardcoded List
  561. PCSTR *ppszExcludedSymbols = EXCLUDED_SYMBOLS;
  562.  
  563. while( *ppszExcludedSymbols != NULL )
  564. {
  565. if( wildcmp( *ppszExcludedSymbols, pszSymbol ) )
  566. {
  567. return( true );
  568. }
  569.  
  570. ppszExcludedSymbols++;
  571. }
  572.  
  573. //check for aditional entries
  574. if (_lppszAditionalExcludeSymbols )
  575. {
  576. LPSTR * ppszAditionalExcludedSymbols = _lppszAditionalExcludeSymbols;
  577. while( *ppszAditionalExcludedSymbols != NULL )
  578. {
  579. if( wildcmp( *ppszAditionalExcludedSymbols, pszSymbol ) )
  580. {
  581. return( true );
  582. }
  583.  
  584. ppszAditionalExcludedSymbols++;
  585. }
  586. }
  587.  
  588. return( false );
  589. }
  590.  
  591. // Get the value (or address of for larger items) of a symbol as a 64 bit value
  592. bool
  593. GetSymbolValue( const DEBUGGER_CONTROLS& objDebugger, ULONG iStackFrame, PCSTR pszSymbol, PULONG64 pqwValue )
  594. {
  595. ULONG iPreviousScopeIndex;
  596. PDEBUG_SYMBOL_GROUP2 pSymbolGroup = NULL;
  597. PSTR pszSymbolBuffer = NULL;
  598. size_t cSymbolBuffer = 0;
  599. bool returnVal = false;
  600.  
  601. if( pszSymbol == NULL )
  602. {
  603. return( returnVal );
  604. }
  605.  
  606. if( pqwValue == NULL )
  607. {
  608. return( returnVal );
  609. }
  610.  
  611. *pqwValue = 0UL;
  612.  
  613. // Cache the current scope index so that we can restore it on the way out
  614. HRESULT hResult = objDebugger.pDebugSymbols->GetCurrentScopeFrameIndex( &iPreviousScopeIndex );
  615.  
  616. if( hResult != S_OK )
  617. {
  618. return( returnVal );
  619. }
  620.  
  621.  
  622.  
  623. // From this point on, everything is done inside of the try/finally block, to allow us to manage
  624. // memory and scope on the way out if we hit failure conditions
  625. __try
  626. {
  627. cSymbolBuffer = strlen( pszSymbol ) + 1;
  628.  
  629. if( cSymbolBuffer != 0 )
  630. {
  631. pszSymbolBuffer = new char[cSymbolBuffer];
  632. }
  633. else
  634. {
  635. __leave;
  636. }
  637.  
  638. hResult = objDebugger.pDebugSymbols->SetScopeFrameByIndex( iStackFrame );
  639.  
  640. if( (hResult != S_OK) && (hResult != S_FALSE) )
  641. {
  642. __leave;
  643. }
  644.  
  645. // Get the symbol group for the scope
  646. hResult = objDebugger.pDebugSymbols->GetScopeSymbolGroup2( DEBUG_SCOPE_GROUP_ALL, NULL, &pSymbolGroup );
  647.  
  648. if( hResult != S_OK )
  649. {
  650. __leave;
  651. }
  652.  
  653. // And now iterate to find the symbol with the specified name
  654. ULONG cSymbols;
  655.  
  656. hResult = pSymbolGroup->GetNumberSymbols( &cSymbols );
  657.  
  658. if( hResult != S_OK )
  659. {
  660. __leave;
  661. }
  662.  
  663. bool fSymbolFound = false;
  664. ULONG iSymbol =0;
  665. for( ULONG iSearchSymbol = 0; iSearchSymbol < cSymbols && !fSymbolFound; iSearchSymbol++ )
  666. {
  667. hResult = pSymbolGroup->GetSymbolName( iSearchSymbol, pszSymbolBuffer, (ULONG) cSymbolBuffer, NULL );
  668.  
  669. if( hResult == S_OK )
  670. {
  671. if( strcmp( pszSymbol, pszSymbolBuffer ) == 0 )
  672. {
  673. iSymbol = iSearchSymbol;
  674. fSymbolFound = true;
  675. }
  676. }
  677. }
  678.  
  679. if( !fSymbolFound )
  680. {
  681. __leave;
  682. }
  683.  
  684. // Now, given the symbol, it's time to look up the value
  685.  
  686. // Now we check to see if it's in a register. If it is, we're going to use the
  687. // register
  688. ULONG iRegister;
  689. hResult = pSymbolGroup->GetSymbolRegister( iSymbol, &iRegister );
  690.  
  691. if( hResult == S_OK )
  692. {
  693. DEBUG_VALUE objValue;
  694.  
  695. hResult = objDebugger.pDebugRegisters->GetValue( iRegister, &objValue );
  696.  
  697. if( hResult != S_OK )
  698. {
  699. __leave;
  700. }
  701.  
  702. switch( objValue.Type )
  703. {
  704. case DEBUG_VALUE_INT8:
  705. *pqwValue = (ULONG64) objValue.I8;
  706. break;
  707.  
  708. case DEBUG_VALUE_INT16:
  709. *pqwValue = (ULONG64) objValue.I16;
  710. break;
  711.  
  712. case DEBUG_VALUE_INT32:
  713. *pqwValue = (ULONG64) objValue.I32;
  714. break;
  715.  
  716. case DEBUG_VALUE_INT64:
  717. *pqwValue = (ULONG64) objValue.I64;
  718. break;
  719.  
  720. default:
  721. __leave;
  722. }
  723.  
  724. returnVal = true;
  725. __leave;
  726. }
  727.  
  728. // Otherwise, we need to pull the value from memory
  729.  
  730. // First we determine the size
  731. ULONG cbSymbolValue;
  732.  
  733. hResult = pSymbolGroup->GetSymbolSize( iSymbol, &cbSymbolValue );
  734.  
  735. if( hResult != S_OK )
  736. {
  737. __leave;
  738. }
  739.  
  740. // If the symbol size is larger than our UINT64, we're going to assume it is a
  741. // pointer and return that. Otherwise, we'll return the contents
  742. if( cbSymbolValue > sizeof( UINT64 ) )
  743. {
  744. hResult = pSymbolGroup->GetSymbolOffset( iSymbol, pqwValue );
  745.  
  746. returnVal =( hResult == S_OK );
  747. __leave;
  748. }
  749. else
  750. {
  751. UINT64 offSymbol;
  752.  
  753. hResult = pSymbolGroup->GetSymbolOffset( iSymbol, &offSymbol );
  754.  
  755. if( hResult != S_OK )
  756. {
  757. __leave;
  758. }
  759.  
  760. // Note that we are assuming a Little-Endian byte order here
  761. hResult = objDebugger.pDebugDataSpaces->ReadVirtual( offSymbol,
  762. (PVOID) pqwValue,
  763. cbSymbolValue,
  764. NULL );
  765.  
  766. returnVal =( hResult == S_OK );
  767. __leave;
  768. }
  769. }
  770. __finally
  771. {
  772. if( pSymbolGroup != NULL )
  773. {
  774. pSymbolGroup->Release();
  775. }
  776.  
  777. if( pszSymbolBuffer != NULL )
  778. {
  779. delete[] pszSymbolBuffer;
  780. }
  781.  
  782. objDebugger.pDebugSymbols->SetScopeFrameByIndex( iPreviousScopeIndex );
  783. }
  784.  
  785. return( returnVal );
  786. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement