Пример #1
0
Error ValidateDestroyImageKHR(const Display *display, const Image *image)
{
    ANGLE_TRY(ValidateImage(display, image));

    if (!display->getExtensions().imageBase && !display->getExtensions().image)
    {
        // It is out of spec what happens when calling an extension function when the extension is
        // not available.
        // EGL_BAD_DISPLAY seems like a reasonable error.
        return Error(EGL_BAD_DISPLAY);
    }

    return Error(EGL_SUCCESS);
}
Пример #2
0
HiresTexture* HiresTexture::Load(const std::string& basename,
                                 std::function<u8*(size_t)> request_buffer_delegate,
                                 bool cacheresult)
{
  if (s_textureMap.size() == 0)
  {
    return nullptr;
  }
  HiresTextureCache::iterator iter = s_textureMap.find(basename);
  if (iter == s_textureMap.end())
  {
    return nullptr;
  }
  HiresTextureCacheItem& current = iter->second;
  if (current.maps[MapType::color].size() == 0)
  {
    return nullptr;
  }
  // First level is mandatory
  if (current.maps[MapType::color][0].path.size() == 0)
  {
    return nullptr;
  }
  HiresTexture* ret = nullptr;
  u8* buffer_pointer;
  u32 maxwidth = 0;
  u32 maxheight = 0;
  bool last_level_is_dds = false;
  bool allocated_data = false;
  bool mipmapsize_included = false;
  size_t material_mat_index =
      current.maps[MapType::color].size() == current.maps[MapType::normal].size() &&
              current.maps[MapType::normal].size() != current.maps[MapType::material].size() ?
          MapType::normal :
          MapType::material;
  size_t emissive_index = MapType::emissive;
  bool nrm_posible =
      current.maps[MapType::color].size() == current.maps[material_mat_index].size() &&
      g_ActiveConfig.HiresMaterialMapsEnabled();
  bool emissive_posible =
      current.maps[MapType::color].size() == current.maps[emissive_index].size() &&
      g_ActiveConfig.HiresMaterialMapsEnabled();
  size_t remaining_buffer_size = 0;
  size_t total_buffer_size = 0;
  std::function<u8*(size_t, bool)> first_level_function = [&](size_t requiredsize,
                                                              bool mipmapsincluded) {
    // Allocate double side buffer if we are going to load normal maps
    allocated_data = true;
    mipmapsize_included = mipmapsincluded;
    // Pre allocate space for the textures and potetially all the posible mip levels
    if (current.maps[MapType::color].size() > 1 && !mipmapsincluded)
    {
      requiredsize = (requiredsize * 4) / 3;
    }
    requiredsize *=
        (nrm_posible && emissive_posible ? 3 : (nrm_posible || emissive_posible ? 2 : 1));
    total_buffer_size = requiredsize;
    remaining_buffer_size = total_buffer_size;
    return request_buffer_delegate(requiredsize);
  };
  std::function<u8*(size_t, bool)> allocation_function = [&](size_t requiredsize,
                                                             bool mipmapsincluded) {
    // is required size is biguer that the remaining size on the packed buffer just reject
    if (requiredsize > remaining_buffer_size)
    {
      return static_cast<u8*>(nullptr);
    }
    // just return the pointer to pack the textures in a single buffer.
    return buffer_pointer;
  };
  for (size_t level = 0; level < current.maps[MapType::color].size(); level++)
  {
    const hires_mip_level& item = current.maps[MapType::color][level];
    ImageLoaderParams imgInfo =
        LoadMipLevel(item, level == 0 ? first_level_function : allocation_function, cacheresult);
    imgInfo.releaseresourcesonerror = cacheresult;
    nrm_posible = nrm_posible && current.maps[material_mat_index][level].path.size() > 0;
    emissive_posible = emissive_posible && current.maps[emissive_index][level].path.size() > 0;
    bool ddsfile = item.is_compressed && TexDecoder::IsCompressed(imgInfo.resultTex);
    if ((level > 0 && ddsfile != last_level_is_dds) || imgInfo.dst == nullptr ||
        imgInfo.resultTex == PC_TEX_FMT_NONE)
    {
      // don't give support to mixed formats
      if (allocated_data && cacheresult && imgInfo.dst != nullptr)
      {
        delete[] imgInfo.dst;
      }
      break;
    }
    last_level_is_dds = ddsfile;
    if (level == 0)
    {
      ret = new HiresTexture();
      ret->has_arbitrary_mips = current.has_arbitrary_mips;
      ret->m_format = imgInfo.resultTex;
      ret->m_width = maxwidth = imgInfo.Width;
      ret->m_height = maxheight = imgInfo.Height;
      if (cacheresult)
      {
        ret->m_cached_data.reset(imgInfo.dst);
        ret->m_cached_data_size = total_buffer_size;
      }
    }
    else
    {
      if (!ValidateImage(imgInfo, level, maxwidth, maxheight, ret->m_format, "color"))
        break;
    }
    ret->m_levels++;
    if (ddsfile)
    {
      u32 requiredsize = TextureUtil::GetTextureSizeInBytes(maxwidth, maxheight, imgInfo.resultTex);
      buffer_pointer = imgInfo.dst + requiredsize;
      remaining_buffer_size -= requiredsize;
    }
    else
    {
      buffer_pointer = imgInfo.dst + imgInfo.data_size;
      remaining_buffer_size -= imgInfo.data_size;
    }

    if (imgInfo.nummipmaps > 0)
    {
      // Give priority to load dds with packed levels
      ret->m_levels = imgInfo.nummipmaps + 1;
      if (nrm_posible || emissive_posible)
      {
        SkipMipData(ret->m_levels, imgInfo.Width, imgInfo.Height, ret->m_format, buffer_pointer,
                    remaining_buffer_size);
      }
      break;
    }

    // no more mipmaps available
    if (maxwidth == 1 && maxheight == 1)
      break;
    maxwidth = std::max(maxwidth >> 1, 1u);
    maxheight = std::max(maxheight >> 1, 1u);
  }
  if (nrm_posible)
  {
    for (size_t level = 0; level < current.maps[material_mat_index].size(); level++)
    {
      const hires_mip_level& item = current.maps[material_mat_index][level];
      ImageLoaderParams imgInfo = LoadMipLevel(item, allocation_function, cacheresult);
      bool ddsfile = item.is_compressed && TexDecoder::IsCompressed(imgInfo.resultTex);
      if ((level > 0 && ddsfile != last_level_is_dds) || imgInfo.dst == nullptr ||
          imgInfo.resultTex == PC_TEX_FMT_NONE)
      {
        // don't give support to mixed formats
        break;
      }
      if (g_ActiveConfig.bHiresMaterialMapsBuild && imgInfo.resultTex == PC_TEX_FMT_RGBA32)
      {
        BuildMaterial(current, imgInfo, level);
      }
      if (level == 0)
      {
        maxwidth = imgInfo.Width;
        maxheight = imgInfo.Height;
        if (!ValidateImage(imgInfo, level, ret->m_width, ret->m_height, ret->m_format, "normal"))
          break;
      }
      else
      {
        if (!ValidateImage(imgInfo, level, maxwidth, maxheight, ret->m_format, "normal"))
          break;
      }
      ret->m_nrm_levels++;
      if (ddsfile)
      {
        u32 requiredsize =
            TextureUtil::GetTextureSizeInBytes(maxwidth, maxheight, imgInfo.resultTex);
        buffer_pointer = imgInfo.dst + requiredsize;
        remaining_buffer_size -= requiredsize;
      }
      else
      {
        buffer_pointer = imgInfo.dst + imgInfo.data_size;
        remaining_buffer_size -= imgInfo.data_size;
      }
      if (imgInfo.nummipmaps > 0)
      {
        // Give priority to load dds with packed levels
        ret->m_nrm_levels = imgInfo.nummipmaps + 1;
        if (emissive_posible)
        {
          SkipMipData(ret->m_nrm_levels, imgInfo.Width, imgInfo.Height, ret->m_format,
                      buffer_pointer, remaining_buffer_size);
        }
        break;
      }
      // no more mipmaps available
      if (maxwidth == 1 && maxheight == 1)
        break;
      maxwidth = std::max(maxwidth >> 1, 1u);
      maxheight = std::max(maxheight >> 1, 1u);
    }
  }
  if (emissive_posible)
  {
    for (size_t level = 0; level < current.maps[emissive_index].size(); level++)
    {
      const hires_mip_level& item = current.maps[emissive_index][level];
      ImageLoaderParams imgInfo = LoadMipLevel(item, allocation_function, cacheresult);
      bool ddsfile = item.is_compressed && TexDecoder::IsCompressed(imgInfo.resultTex);
      if ((level > 0 && ddsfile != last_level_is_dds) || imgInfo.dst == nullptr ||
          imgInfo.resultTex == PC_TEX_FMT_NONE)
      {
        // don't give support to mixed formats
        break;
      }
      if (level == 0)
      {
        maxwidth = imgInfo.Width;
        maxheight = imgInfo.Height;
        if (!ValidateImage(imgInfo, level, ret->m_width, ret->m_height, ret->m_format, "normal"))
          break;
      }
      else
      {
        if (!ValidateImage(imgInfo, level, maxwidth, maxheight, ret->m_format, "normal"))
          break;
      }
      ret->m_lum_levels++;
      if (ddsfile)
      {
        u32 requiredsize =
            TextureUtil::GetTextureSizeInBytes(maxwidth, maxheight, imgInfo.resultTex);
        buffer_pointer = imgInfo.dst + requiredsize;
        remaining_buffer_size -= requiredsize;
      }
      else
      {
        buffer_pointer = imgInfo.dst + imgInfo.data_size;
        remaining_buffer_size -= imgInfo.data_size;
      }
      if (imgInfo.nummipmaps > 0)
      {
        // Give priority to load dds with packed levels
        ret->m_lum_levels = imgInfo.nummipmaps + 1;
        break;
      }
      // no more mipmaps available
      if (maxwidth == 1 && maxheight == 1)
        break;
      maxwidth = std::max(maxwidth >> 1, 1u);
      maxheight = std::max(maxheight >> 1, 1u);
    }
  }
  if (ret != nullptr)
  {
    u32 levels = ret->m_levels;
    // Disable normal map if the size or levels are different
    if (ret->m_nrm_levels != levels)
    {
      ret->m_nrm_levels = 0;
    }
    if (ret->m_lum_levels != levels)
    {
      ret->m_lum_levels = 0;
    }
  }
  return ret;
}
Пример #3
0
/// <summary>
/// Injection routine
/// </summary>
/// <param name="path">Image path</param>
/// <param name="init">Initizliation routine/param>
/// <param name="arg">Initizliation routine argument</param>
/// <returns>Error code</returns>
DWORD MainDlg::InjectWorker( std::wstring path, std::string init, std::wstring arg )
{
    blackbone::Thread *pThread = nullptr;
    const blackbone::ModuleData* mod = nullptr;
    PROCESS_INFORMATION pi = { 0 };
    wchar_t cmdline[256] = { 0 };
    HWND hCombo = GetDlgItem( _hMainDlg, IDC_THREADS );
    DWORD thdId = (DWORD)ComboBox_GetItemData( hCombo, ComboBox_GetCurSel( hCombo ) );
    bool bManual = ComboBox_GetCurSel( GetDlgItem( _hMainDlg, IDC_OP_TYPE ) ) == 1;
    
    GetDlgItemTextW( _hMainDlg, IDC_CMDLINE, cmdline, ARRAYSIZE( cmdline ) );  

    // Check export
    if (ValidateInit( init.c_str() ) != STATUS_SUCCESS)
        return ERROR_CANCELLED;

    // Create new process
    if (_newProcess)
    {
        STARTUPINFOW si = { 0 };
        si.cb = sizeof(si);

        if (!CreateProcessW( _procPath.c_str(), cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ))
        {
            MessageBoxW( _hMainDlg, L"Failed to create new process", L"Error", MB_ICONERROR );
            return GetLastError();
        }

        thdId = 0;

        // Wait for process to initialize loader
        Sleep( 1 );

        AttachToProcess( pi.dwProcessId );
    }

    // Final sanity check
    if (ValidateImage( path.c_str(), init.c_str() ) != ERROR_SUCCESS)
    {
        if (_newProcess)
            TerminateProcess( pi.hProcess, 0 );

        return ERROR_CANCELLED;
    }
        
    // Normal inject
    if (bManual == false)
    {
        if (_imagePE.IsPureManaged())
        {
            DWORD code = 0;

            if (!_proc.modules().InjectPureIL( blackbone::ImageNET::GetImageRuntimeVer( path.c_str() ),
                path, blackbone::Utils::AnsiToWstring( init ), arg, code ))
            {
                if (_newProcess)
                    TerminateProcess( pi.hProcess, 0 );

                MessageBoxW( _hMainDlg, L"Failed to inject image", L"Error", MB_ICONERROR );
                return ERROR_FUNCTION_FAILED;
            }
        }
        else if (!_newProcess && thdId != 0)
        {
            pThread = _proc.threads().get( thdId );
            if (pThread == nullptr)
            {
                if (_newProcess)
                    TerminateProcess( pi.hProcess, 0 );

                MessageBoxW( _hMainDlg, L"Selected thread does not exist", L"Error", MB_ICONERROR );
                return ERROR_NOT_FOUND;
            }

            // Load 
            auto pLoadLib = _proc.modules().GetExport( _proc.modules().GetModule( L"kernel32.dll" ), "LoadLibraryW" ).procAddress;
            blackbone::RemoteFunction<decltype(&LoadLibraryW)> pfn( _proc, (decltype(&LoadLibraryW))pLoadLib, path.c_str() );
            decltype(pfn)::ReturnType junk = 0;
            pfn.Call( junk, pThread );

            mod = _proc.modules().GetModule( path );
        }
        else
            mod = _proc.modules().Inject( path );
    }
    // Manual map
    else
    {
        thdId = 0;
        int flags = blackbone::RebaseProcess | blackbone::NoDelayLoad | MmapFlags();

        mod = _proc.mmap().MapImage( path, flags );
    }

    if (mod == 0 && !_imagePE.IsPureManaged())
    {
        if (_newProcess)
            TerminateProcess( pi.hProcess, 0 );

        MessageBoxW( _hMainDlg, L"Failed to inject image", L"Error", MB_ICONERROR );
        return ERROR_NOT_FOUND;
    }

    // Call init for native image
    if (!init.empty() && !_imagePE.IsPureManaged())
    {
        auto fnPtr = _proc.modules().GetExport( mod, init.c_str() ).procAddress;

        if (thdId == 0)
        {
            auto argMem = _proc.memory().Allocate( 0x1000, PAGE_READWRITE );
            argMem.Write( 0, arg.length() * sizeof(wchar_t)+2, arg.c_str() );

            _proc.remote().ExecDirect( fnPtr, argMem.ptr() );
        }
        else
        {
            pThread = _proc.threads().get( thdId );
            if (pThread == nullptr)
            {
                if (_newProcess)
                    TerminateProcess( pi.hProcess, 0 );

                MessageBoxW( _hMainDlg, L"Selected thread does not exist", L"Error", MB_ICONERROR );
                return ERROR_NOT_FOUND;
            }

            blackbone::RemoteFunction<int( _stdcall* )(const wchar_t*)> pfn( _proc, (int( _stdcall* )(const wchar_t*))fnPtr, arg.c_str() );
            int junk = 0;

            pfn.Call( junk, pThread );
        }
    }

    // Unlink module if required
    if (!_imagePE.IsPureManaged() && !bManual && Button_GetCheck( GetDlgItem( _hMainDlg, IDC_UNLINK ) ))
        if (_proc.modules().Unlink( mod ) == false)
            MessageBoxW( _hMainDlg, L"Failed to unlink module", L"Error", MB_ICONERROR );

    // MessageBoxW( _hMainDlg, L"Successfully injected", L"Info", MB_ICONINFORMATION );
    //ResumeThread( pi.hThread );

    return ERROR_SUCCESS;
}