locked
Toolhelp32 in 64-bit process displays incorrect values for user heap item addresses.

    Вопрос

  • If you build for 64-bit and execute the following code, you will notice that the values for heap item addresses in the user-created heap are incorrect (the values for heaps created by the system are correct). Examining the addresses in a debugger will reveal that Toolhelp32 reports addresses inside the accounting(?) block for the heap.  The program is essentially the Toolhelp32 sample with the addition of a user-created heap, i.e., from calling HeapCreate.

    // Toolhelp32TestNative.cpp : Defines the entry point for the console application.
    //
    #include "stdafx.h"

    #include <windows.h>
    #include <tlhelp32.h>
    #include <stdio.h>
    #include <process.h>

    FILE *f;

    int _tmain(int argc, _TCHAR* argv[])
    {
     PVOID pMyArray[ 0x10 ];
     HANDLE hMyHeap = ::HeapCreate( 0, 0x1000, 0x1000 );
     for( int i = 0; i < 0x10; ++i )
     {
      int iCnt = i + 1;
      pMyArray[ i ] = ::HeapAlloc( hMyHeap, 0, iCnt * 0x10 );
      ::memset( pMyArray[ i ], iCnt, iCnt * 0x10 );
     }
     ::HeapFree( hMyHeap, 0, pMyArray[ 5 ] );
     pMyArray[ 5 ] = ::HeapAlloc( hMyHeap, 0, 0x400 );
     ::memset( pMyArray[ 5 ], 0xaa, 0x400 );
     ::HeapFree( hMyHeap, 0, pMyArray[ 6 ] );
     ::HeapFree( hMyHeap, 0, pMyArray[ 4 ] );
     pMyArray[ 4 ] = ::HeapAlloc( hMyHeap, 0, 6 * 0x10 );
     ::memset( pMyArray[ 4 ], 0x05, 6 * 0x10 );

     ::fopen_s( &f, "t.txt", "w" );

     HEAPLIST32 hl;
     HANDLE hHeapSnap = ::CreateToolhelp32Snapshot( TH32CS_SNAPHEAPLIST, ::GetCurrentProcessId() );
     hl.dwSize = sizeof( HEAPLIST32 );
     if ( hHeapSnap == INVALID_HANDLE_VALUE )
     {
      ::fprintf( f, "CreateToolhelp32Snapshot failed (%d)\n", ::GetLastError() );
      return 1;
     }
     int iHeapCount = 0;
     int iBlockCount = 0;
     if( ::Heap32ListFirst( hHeapSnap, &hl ) )
     {
      do
      {
       HEAPENTRY32 he;
       ::ZeroMemory( &he, sizeof( HEAPENTRY32 ) );
       he.dwSize = sizeof( HEAPENTRY32 );
       iHeapCount++;
       if( ::Heap32First( &he, GetCurrentProcessId(), hl.th32HeapID ) )
       {
        if( ( hl.dwFlags & HF32_DEFAULT )== HF32_DEFAULT )
        {
         ::fprintf( f, "\nHeap Count: %d\tHeap ID: %16X\tdefault\n", iHeapCount, hl.th32HeapID );
        }
        else
        {
         ::fprintf( f, "\nHeap Count: %d\tHeap ID: %16X\n", iHeapCount, hl.th32HeapID );
        }
        do
        {
         iBlockCount++;
         ::fprintf( f, "BlockCount: %d\tBlock address: %p\tBlock size: %16X\tBlock Flags: %x\tLock Count: %x\tReserved: %x\n", iBlockCount, he.dwAddress, he.dwBlockSize, he.dwFlags, he.dwLockCount, he.dwResvd );
         he.dwSize = sizeof( HEAPENTRY32 );
        } while( ::Heap32Next( &he ) );
       }
       hl.dwSize = sizeof( HEAPLIST32 );
      } while( ::Heap32ListNext( hHeapSnap, &hl ) );
     }
     else
     {
      ::fprintf( f, "Cannot list first heap (%16X)\n", ::GetLastError() );
     }
     ::CloseHandle(hHeapSnap);
     for( int i = 0; i < 0x10; ++i )
     {
      ::fprintf( f, "Block %d: %p\n", i + 1, pMyArray[ i ] );
     }
     ::HeapDestroy( hMyHeap );
     ::fclose( f );
     ::system( "type t.txt" );
     return 0;
    }

    1 марта 2012 г. 17:24

Все ответы

  • We are doing some research of this issue and will get back to you once we have any update information.

    Best Regards,
    Rocky Yue[MSFT]
    MSDN Community Support | Feedback to us

    5 марта 2012 г. 9:27
  • which value do you think is not correct, can you give more details about the issue?

    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.

    Regards,
    Jacky Wu
    Microsoft Online Community Support


    9 марта 2012 г. 5:12
  • Did you build and run the example program included in the initial post?

    On my Windows 7 system, the Toolhelp32 output (debug-mode) produces 6 heaps, the last heap being the one created by the call to HeapCreate at the start of the program, i.e., the user-created heap and the remainder are heaps created by the Windows loader. The "Block address" values for this, the 6th heap, are different from the values produced by the loop at the end of the program.  Here is my output:

    Heap Count: 6 Heap ID:          1C10000
    BlockCount: 384 Block address: 0000000001C10010 Block size:               20 Block Flags: 1 Lock Count: 0 Reserved: 1
    BlockCount: 385 Block address: 0000000001C10030 Block size:               30 Block Flags: 1 Lock Count: 0 Reserved: 2
    BlockCount: 386 Block address: 0000000001C10060 Block size:               40 Block Flags: 1 Lock Count: 0 Reserved: 3
    BlockCount: 387 Block address: 0000000001C100A0 Block size:               50 Block Flags: 1 Lock Count: 0 Reserved: 4
    BlockCount: 388 Block address: 0000000001C100F0 Block size:               70 Block Flags: 1 Lock Count: 0 Reserved: 5
    BlockCount: 389 Block address: 0000000001C10160 Block size:               E0 Block Flags: 1 Lock Count: 0 Reserved: 6
    BlockCount: 390 Block address: 0000000001C10240 Block size:               90 Block Flags: 1 Lock Count: 0 Reserved: 7
    BlockCount: 391 Block address: 0000000001C102D0 Block size:               A0 Block Flags: 1 Lock Count: 0 Reserved: 8
    BlockCount: 392 Block address: 0000000001C10370 Block size:               B0 Block Flags: 1 Lock Count: 0 Reserved: 9
    BlockCount: 393 Block address: 0000000001C10420 Block size:               C0 Block Flags: 1 Lock Count: 0 Reserved: a
    BlockCount: 394 Block address: 0000000001C104E0 Block size:               D0 Block Flags: 1 Lock Count: 0 Reserved: b
    BlockCount: 395 Block address: 0000000001C105B0 Block size:               E0 Block Flags: 1 Lock Count: 0 Reserved: c
    BlockCount: 396 Block address: 0000000001C10690 Block size:               F0 Block Flags: 1 Lock Count: 0 Reserved: d
    BlockCount: 397 Block address: 0000000001C10780 Block size:              100 Block Flags: 1 Lock Count: 0 Reserved: e
    BlockCount: 398 Block address: 0000000001C10880 Block size:              110 Block Flags: 1 Lock Count: 0 Reserved: f
    BlockCount: 399 Block address: 0000000001C10990 Block size:              410 Block Flags: 1 Lock Count: 0 Reserved: 10
    BlockCount: 400 Block address: 0000000001C10DA0 Block size:              7B0 Block Flags: 1 Lock Count: 0 Reserved: 11
    BlockCount: 401 Block address: 0000000001C11550 Block size:                0 Block Flags: 2 Lock Count: 0 Reserved: 12
    Block 1: 0000000001C10A90
    Block 2: 0000000001C10AB0
    Block 3: 0000000001C10AE0
    Block 4: 0000000001C10B20
    Block 5: 0000000001C10B70
    Block 6: 0000000001C11410
    Block 7: 0000000001C10C40
    Block 8: 0000000001C10CC0
    Block 9: 0000000001C10D50
    Block 10: 0000000001C10DF0
    Block 11: 0000000001C10EA0
    Block 12: 0000000001C10F60
    Block 13: 0000000001C11030
    Block 14: 0000000001C11110
    Block 15: 0000000001C11200
    Block 16: 0000000001C11300

    The loop output is correct; the Toolhelp32 values for "Block address" are incorrect. I have checked the values from Toolhelp32 for the other 5 heaps and these "Block address" values appear to be correct.

    9 марта 2012 г. 12:37
  • Your question falls into the paid support category which requires a more in-depth level of support. Please visit the below link to see the various paid support options that are available to better meet your needs.

    http://support.microsoft.com/default.aspx?id=fh;en-us;offerprophone


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.

    Regards,
    Jacky Wu
    Microsoft Online Community Support

    21 мая 2012 г. 2:19