bool khPresenceMask::GetEstimatedPresence(const khTileAddr &addr) const {
  assert(addr.level < NumFusionLevels);
  if (levels[addr.level]) {
    return levels[addr.level]->GetPresence(addr.row, addr.col);
  } else if (addr.level >= endLevel) {
    // reach up to maxLevel (endLevel-1) and check the single tile there
    khTileAddr maxAddr(addr.MinifiedToLevel(endLevel-1));
    return levels[maxAddr.level]->GetPresence(maxAddr.row, maxAddr.col);
  } else {
    assert(addr.level < beginLevel);
    // reach down to beginLevel and traverse all tiles there
    // stop as soon as we find a hit
    khLevelCoverage minCoverage(addr.MagnifiedToLevel(beginLevel));
    khExtents<uint32> tocheck =
      khExtents<uint32>::Intersection(minCoverage.extents,
                                      levels[beginLevel]->extents);
    for (uint32 row = tocheck.beginRow(); row < tocheck.endRow(); ++row) {
      for (uint32 col = tocheck.beginCol(); col < tocheck.endCol(); ++col) {
        if (levels[beginLevel]->GetPresence(row, col)) {
          return true;
        }
      }
    }
  }
  return false;
}
示例#2
0
/// <summary>
/// Enumerate valid memory regions
/// </summary>
/// <param name="includeFree">If true - non-allocated regions will be included in list</param>
/// <returns>Found regions</returns>
std::vector<MEMORY_BASIC_INFORMATION64> Native::EnumRegions( bool includeFree /*= false*/ )
{
    MEMORY_BASIC_INFORMATION64 mbi = { 0 };
    std::vector<MEMORY_BASIC_INFORMATION64> results;

    for (ptr_t memptr = minAddr(); memptr < maxAddr(); memptr = mbi.BaseAddress + mbi.RegionSize)
    {
        auto status = VirtualQueryExT( memptr, &mbi );

        if (status == STATUS_INVALID_PARAMETER || status == STATUS_ACCESS_DENIED)
            break;
        else if (status != STATUS_SUCCESS)
            continue;

        // Filter, if required
        if (includeFree || mbi.State & (MEM_COMMIT | MEM_RESERVE))
            results.emplace_back( mbi );
    }

    return results;
}
示例#3
0
/// <summary>
/// Enum pages containing valid PE headers
/// </summary>
/// <param name="result">Found modules</param>
/// <returns>Sections count</returns>
std::vector<ModuleDataPtr> Native::EnumPEHeaders()
{
    MEMORY_BASIC_INFORMATION64 mbi = { 0 };
    uint8_t buf[0x1000];
    ptr_t lastBase = 0;
    std::vector<ModuleDataPtr> result;

    for (ptr_t memptr = minAddr(); memptr < maxAddr(); memptr = mbi.BaseAddress + mbi.RegionSize)
    {
        auto status = VirtualQueryExT( memptr, &mbi );

        if (status == STATUS_INVALID_PARAMETER || status == STATUS_ACCESS_DENIED || status == STATUS_PROCESS_IS_TERMINATING)
            break;
        else if (status != STATUS_SUCCESS)
            continue;

        // Filter regions
        if (mbi.State != MEM_COMMIT ||
            mbi.AllocationProtect == PAGE_NOACCESS ||
            mbi.AllocationProtect & PAGE_GUARD ||
            lastBase == mbi.AllocationBase)
        {
            continue;
        }

        ModuleData data;

        IMAGE_DOS_HEADER* phdrDos = reinterpret_cast<PIMAGE_DOS_HEADER>(buf);
        IMAGE_NT_HEADERS32 *phdrNt32 = nullptr;
        IMAGE_NT_HEADERS64 *phdrNt64 = nullptr;

        if (ReadProcessMemoryT( mbi.AllocationBase, buf, 0x1000 ) != STATUS_SUCCESS)
            continue;

        phdrNt32 = reinterpret_cast<PIMAGE_NT_HEADERS32>(buf + phdrDos->e_lfanew);
        phdrNt64 = reinterpret_cast<PIMAGE_NT_HEADERS64>(phdrNt32);

        if (phdrDos->e_magic != IMAGE_DOS_SIGNATURE || phdrNt32->Signature != IMAGE_NT_SIGNATURE)
            continue;

        if (phdrNt32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
        {
            data.size = phdrNt32->OptionalHeader.SizeOfImage;
            data.type = mt_mod32;
        }
        else if (phdrNt32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
        {
            data.size = phdrNt64->OptionalHeader.SizeOfImage;
            data.type = mt_mod64;
        }

        data.baseAddress = mbi.AllocationBase;
        data.ldrPtr = 0;
        data.manual = false;

        // Try to get section name
        _UNICODE_STRING_T<DWORD64>* ustr = (decltype(ustr))buf;
        status = VirtualQueryExT( mbi.AllocationBase, MemorySectionName, ustr, sizeof(buf) );

        if (status == STATUS_SUCCESS)
        {
            // Hack for x86 OS
            if (_wowBarrier.x86OS == true)
            {
                _UNICODE_STRING_T<DWORD>* ustr32 = reinterpret_cast<_UNICODE_STRING_T<DWORD>*>(ustr);
                data.fullPath = Utils::ToLower( reinterpret_cast<wchar_t*>((uintptr_t)ustr32->Buffer) );
            }
            else
                data.fullPath = Utils::ToLower( reinterpret_cast<wchar_t*>((uintptr_t)ustr->Buffer) );

            data.name = Utils::StripPath( data.fullPath );
        }
        else
        {
            wchar_t name[64] = { 0 };
            wsprintfW( name, L"Unknown_0x%I64x", data.baseAddress );

            data.fullPath = name;
            data.name = data.fullPath;
        }

        result.emplace_back( std::make_shared<const ModuleData>( data ) );

        lastBase = mbi.AllocationBase;
    }

    return result;
}
示例#4
0
/// <summary>
/// Enum process section objects
/// </summary>
/// <param name="result">Found modules</param>
/// <returns>Sections count</returns>
std::vector<ModuleDataPtr> Native::EnumSections()
{
    MEMORY_BASIC_INFORMATION64 mbi = { 0 };
    ptr_t lastBase = 0;
    std::vector<ModuleDataPtr> result;

    for (ptr_t memptr = minAddr(); memptr < maxAddr(); memptr = mbi.BaseAddress + mbi.RegionSize)
    {
        auto status = VirtualQueryExT( memptr, &mbi );

        if (status == STATUS_INVALID_PARAMETER || status == STATUS_ACCESS_DENIED || status == STATUS_PROCESS_IS_TERMINATING)
            break;
        else if (status != STATUS_SUCCESS)
            continue;

        // Filter non-section regions
        if (mbi.State != MEM_COMMIT || mbi.Type != SEC_IMAGE || lastBase == mbi.AllocationBase)
            continue;

        uint8_t buf[0x1000] = { 0 };
        _UNICODE_STRING_T<uint64_t>* ustr = (decltype(ustr))(buf + 0x800);

        status = VirtualQueryExT( mbi.AllocationBase, MemorySectionName, ustr, sizeof(buf) / 2 );

        // Get additional 
        if (NT_SUCCESS( status ))
        {
            ModuleData data;

            IMAGE_DOS_HEADER* phdrDos = reinterpret_cast<PIMAGE_DOS_HEADER>(buf);
            IMAGE_NT_HEADERS32 *phdrNt32 = nullptr;
            IMAGE_NT_HEADERS64 *phdrNt64 = nullptr;

            if (ReadProcessMemoryT( mbi.AllocationBase, buf, 0x800 ) != STATUS_SUCCESS)
                continue;

            phdrNt32 = reinterpret_cast<PIMAGE_NT_HEADERS32>(buf + phdrDos->e_lfanew);
            phdrNt64 = reinterpret_cast<PIMAGE_NT_HEADERS64>(phdrNt32);

            // If no PE header present
            if (phdrDos->e_magic != IMAGE_DOS_SIGNATURE || phdrNt32->Signature != IMAGE_NT_SIGNATURE)
            {
                // Iterate until region end
                MEMORY_BASIC_INFORMATION64 mbi2 = { 0 };
                for (ptr_t memptr2 = mbi.AllocationBase; memptr2 < maxAddr(); memptr2 = mbi2.BaseAddress + mbi2.RegionSize)
                    if (!NT_SUCCESS( VirtualQueryExT( memptr2, &mbi2 ) ) || mbi2.Type != SEC_IMAGE)
                    {
                        data.size = static_cast<uint32_t>(mbi2.BaseAddress - mbi.AllocationBase);
                        break;
                    }

                data.type = mt_unknown;
            }
            else if( phdrNt32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC )
            {
                data.size = phdrNt32->OptionalHeader.SizeOfImage;
                data.type = mt_mod32;
            }
            else if (phdrNt32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
            {
                data.size = phdrNt64->OptionalHeader.SizeOfImage;
                data.type = mt_mod64;
            }
            else 
                continue;

            // Hack for x86 OS
            if (_wowBarrier.x86OS == true)
            {
                _UNICODE_STRING_T<DWORD>* ustr32 = reinterpret_cast<_UNICODE_STRING_T<DWORD>*>(ustr);
                data.fullPath = Utils::ToLower( reinterpret_cast<wchar_t*>((uintptr_t)ustr32->Buffer) );
            }
            else
                data.fullPath = Utils::ToLower( reinterpret_cast<wchar_t*>((uintptr_t)ustr->Buffer) );

            data.name = Utils::StripPath( data.fullPath );
            data.baseAddress = mbi.AllocationBase;
            data.ldrPtr = 0;
            data.manual = false;

            result.emplace_back( std::make_shared<const ModuleData>( data ) );
        }

        lastBase = mbi.AllocationBase;
    }

    return result;
}