0

The content of the '.text' section is accessed using code like this:

1) For the application which is loaded into memory (i.e. executing):

//accessing code in memory
        PIMAGE_DOS_HEADER pDOSHeader = NULL;
        pDOSHeader = static_cast<PIMAGE_DOS_HEADER>( (void*)hModule);
        ...

        PIMAGE_NT_HEADERS pNTHeader = reinterpret_cast<PIMAGE_NT_HEADERS>((byte*)hModule + pDOSHeader->e_lfanew );
        ...
        PIMAGE_FILE_HEADER pFileHeader = reinterpret_cast<PIMAGE_FILE_HEADER>((byte*)&pNTHeader->FileHeader );
        ...
          PIMAGE_OPTIONAL_HEADER pOptionalHeader = 
            reinterpret_cast<PIMAGE_OPTIONAL_HEADER>((byte*)&pNTHeader->OptionalHeader );
        ...
            PIMAGE_SECTION_HEADER pSectionHeader = reinterpret_cast<PIMAGE_SECTION_HEADER>(
            (byte*)&pNTHeader->OptionalHeader +
            pNTHeader->FileHeader.SizeOfOptionalHeader );

        //so iterate headers and select one with right name
        const char TEXT[] = ".text";
        const char BSSTEXT[] = ".textbss";
        unsigned int nSectionCount = pNTHeader->FileHeader.NumberOfSections;
        char szSectionName[ IMAGE_SIZEOF_SHORT_NAME + 1 ];
        szSectionName[ IMAGE_SIZEOF_SHORT_NAME ] = '\0';
        for( unsigned int i = 0; i < nSectionCount; i++ )
        {
            memcpy( szSectionName, pSectionHeader->Name,
                    IMAGE_SIZEOF_SHORT_NAME );

            if( 0 == strncmp( TEXT, szSectionName,
                              IMAGE_SIZEOF_SHORT_NAME ) )
            {
                break;
            }
            pSectionHeader++;
        }

        pVirtualAddress = (void*)(pSectionHeader->VirtualAddress);
        dwCodeSize = pSectionHeader->Misc.VirtualSize;

        //seems resonable: To calculate the real starting address of a given section in memory, 
        //add the base address of the image to the section's VirtualAddress stored in this field.
        pCodeStart = (void*)(((byte*)hModule) +(size_t)((byte*)pVirtualAddress) );
        pCodeEnd = (void*)((byte*)pCodeStart + dwCodeSize); 

2) For the application file read from hdd and mapped into memory:

 //loading code from file and mapping 
      hFile = CreateFile( filename, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
      ...        
      hFileMapping = CreateFileMapping( hFile, NULL, PAGE_READONLY ),0, 0, NULL );
      ...
      pBaseAddress = MapViewOfFile( hFileMapping, FILE_MAP_READ, 0, 0, 0 );
      ...
      PIMAGE_DOS_HEADER pDOSHeader = static_cast<PIMAGE_DOS_HEADER>( pBaseAddress);
      ...
      PIMAGE_NT_HEADERS pNTHeader = reinterpret_cast<PIMAGE_NT_HEADERS>(
            (PBYTE)_pBaseAddress() + pDOSHeader->e_lfanew );
      ...       
      PIMAGE_FILE_HEADER pFileHeader = reinterpret_cast<PIMAGE_FILE_HEADER>(
            (PBYTE)&pNTHeader->FileHeader );
      ...
          PIMAGE_OPTIONAL_HEADER pOptionalHeader = 
            reinterpret_cast<PIMAGE_OPTIONAL_HEADER>(
            (PBYTE)&pNTHeader->OptionalHeader );

      PIMAGE_SECTION_HEADER pSectionHeader = 
            reinterpret_cast<PIMAGE_SECTION_HEADER>(
            (PBYTE)&pNTHeader->OptionalHeader +
            pNTHeader->FileHeader.SizeOfOptionalHeader );


      DWORD dwEntryPoint = pNTHeader->OptionalHeader.AddressOfEntryPoint;
      UINT nSectionCount = pNTHeader->FileHeader.NumberOfSections;

      const char TEXT[] = ".text";
      const char BSSTEXT[] = ".textbss";
      char szSectionName[ IMAGE_SIZEOF_SHORT_NAME + 1 ];
      szSectionName[ IMAGE_SIZEOF_SHORT_NAME ] = '\0';
      for( unsigned int i = 0; i < nSectionCount; i++ )
      {
           memcpy( szSectionName, pSectionHeader->Name,
                   IMAGE_SIZEOF_SHORT_NAME );

           if( 0 == strncmp( TEXT, szSectionName,
                             IMAGE_SIZEOF_SHORT_NAME ) )
            {
                break;
            }
            pSectionHeader++;
       }

       // Use this when probing On Disk. It is where things
       //   are on disk - not where they will be in memory            
       dwRawData = pSectionHeader->PointerToRawData;

       // Use this when probing On Disk. It is where things
       //   are on disk - not where they will be in memory
       pCodeStart = (void*)((byte*)pBaseAddress +
           pSectionHeader->PointerToRawData );


       pEntryPoint = (void*)(((byte*)pBaseAddress) + dwEntryPoint);

       dwCodeSize = pSectionHeader->Misc.VirtualSize;
       pCodeEnd = (void*)((byte*)pCodeStart + pSectionHeader->Misc.VirtualSize );

If the application is built with Visual Studio, all the bytes between pCodeStart and pCodeEnd are matching in both cases.

But if the application is built with GCC (MinGW) some bytes which are following pCodeStart and prior pCodeEnd are the same but somewhere in the middle some different bytes are appearing.

Why does it happen?

4

0 回答 0