Ejemplo n.º 1
0
void CvOneWayDescriptor::Allocate(int pose_count, CvSize size, int nChannels)
{
	m_pose_count = pose_count;
	m_samples = new IplImage* [m_pose_count];
	m_pca_coeffs = new CvMat* [m_pose_count];
	m_patch_size = cvSize(size.width/2, size.height/2);

	if(!m_transforms)
	{
		m_affine_poses = new CvAffinePose[m_pose_count];
	}

	int length = m_pca_dim_low;//roi.width*roi.height;
	for(int i = 0; i < m_pose_count; i++)
	{
		m_samples[i] = cvCreateImage(cvSize(size.width/2, size.height/2), IPL_DEPTH_32F, nChannels);
		m_pca_coeffs[i] = cvCreateMat(1, length, CV_32FC1);
	}

	m_input_patch = cvCreateImage(GetPatchSize(), IPL_DEPTH_8U, 1);
	m_train_patch = cvCreateImage(GetInputPatchSize(), IPL_DEPTH_8U, 1);
}
Ejemplo n.º 2
0
void CvOneWayDescriptor::EstimatePosePCA(CvArr* patch, int& pose_idx, float& distance, CvMat* avg, CvMat* eigenvectors) const
{
	if(avg == 0)
	{
		// do not use pca
		if (!CV_IS_MAT(patch))
		{
			EstimatePose((IplImage*)patch, pose_idx, distance);
		}
		else
		{

		}
		return;
	}
	CvRect roi;
	if (!CV_IS_MAT(patch))
	{
		roi = cvGetImageROI((IplImage*)patch);
		if(roi.width != GetPatchSize().width || roi.height != GetPatchSize().height)
		{
			cvResize(patch, m_input_patch);
			patch = m_input_patch;
			roi = cvGetImageROI((IplImage*)patch);
		}
	}

	CvMat* pca_coeffs = cvCreateMat(1, m_pca_dim_low, CV_32FC1);

	if (CV_IS_MAT(patch))
	{
		cvCopy((CvMat*)patch, pca_coeffs);
	}
	else
	{
		IplImage* patch_32f = cvCreateImage(cvSize(roi.width, roi.height), IPL_DEPTH_32F, 1);
		float sum = cvSum(patch).val[0];
		cvConvertScale(patch, patch_32f, 1.0f/sum);
		ProjectPCASample(patch_32f, avg, eigenvectors, pca_coeffs);
		cvReleaseImage(&patch_32f);
	}


	distance = 1e10;
	pose_idx = -1;

	for(int i = 0; i < m_pose_count; i++)
	{
		float dist = cvNorm(m_pca_coeffs[i], pca_coeffs);
		//		float dist = 0;
		//		float data1, data2;
		//		//CvMat* pose_pca_coeffs = m_pca_coeffs[i];
		//		for (int x=0; x < pca_coeffs->width; x++)
		//			for (int y =0 ; y < pca_coeffs->height; y++)
		//			{
		//				data1 = ((float*)(pca_coeffs->data.ptr + pca_coeffs->step*x))[y];
		//				data2 = ((float*)(m_pca_coeffs[i]->data.ptr + m_pca_coeffs[i]->step*x))[y];
		//				dist+=(data1-data2)*(data1-data2);
		//			}
		////#if 1
		//		for (int j = 0; j < m_pca_dim_low; j++)
		//		{
		//			dist += (pose_pca_coeffs->data.fl[j]- pca_coeffs->data.fl[j])*(pose_pca_coeffs->data.fl[j]- pca_coeffs->data.fl[j]);
		//		}
		//#else
		//		for (int j = 0; j <= m_pca_dim_low - 4; j += 4)
		//		{
		//			dist += (pose_pca_coeffs->data.fl[j]- pca_coeffs->data.fl[j])*
		//				(pose_pca_coeffs->data.fl[j]- pca_coeffs->data.fl[j]);
		//			dist += (pose_pca_coeffs->data.fl[j+1]- pca_coeffs->data.fl[j+1])*
		//				(pose_pca_coeffs->data.fl[j+1]- pca_coeffs->data.fl[j+1]);
		//			dist += (pose_pca_coeffs->data.fl[j+2]- pca_coeffs->data.fl[j+2])*
		//				(pose_pca_coeffs->data.fl[j+2]- pca_coeffs->data.fl[j+2]);
		//			dist += (pose_pca_coeffs->data.fl[j+3]- pca_coeffs->data.fl[j+3])*
		//				(pose_pca_coeffs->data.fl[j+3]- pca_coeffs->data.fl[j+3]);
		//		}
		//#endif
		if(dist < distance)
		{
			distance = dist;
			pose_idx = i;
		}
	}

	cvReleaseMat(&pca_coeffs);
}
Ejemplo n.º 3
0
  virtual void Apply() override
  {
    if (applied_)
    {
      return;
    }

    if (detached_)
    {
      HADESMEM_DETAIL_ASSERT(false);
      return;
    }

    // Reset the trampolines here because we don't do it in remove, otherwise
    // there's a potential race condition where we want to unhook and unload
    // safely, so we unhook the function, then try waiting on our ref count to
    // become zero, but we haven't actually called the trampoline yet, so we end
    // up jumping to the memory we just free'd!
    trampoline_ = nullptr;
    trampolines_.clear();
    stub_gate_ = nullptr;

    SuspendedProcess const suspended_process{process_->GetId()};

    std::uint32_t const kMaxInstructionLen = 15;
    std::uint32_t const kTrampSize = kMaxInstructionLen * 3;

    trampoline_ = std::make_unique<Allocator>(*process_, kTrampSize);
    auto tramp_cur = static_cast<std::uint8_t*>(trampoline_->GetBase());

    auto const detour_raw = detour_.target<DetourFuncRawT>();
    if (detour_raw || detour_)
    {
      HADESMEM_DETAIL_TRACE_FORMAT_A(
        "Target = %p, Detour = %p, Trampoline = %p.",
        target_,
        detour_raw,
        trampoline_->GetBase());
    }
    else
    {
      HADESMEM_DETAIL_TRACE_FORMAT_A(
        "Target = %p, Detour = INVALID, Trampoline = %p.",
        target_,
        trampoline_->GetBase());
    }

    auto const buffer =
      ReadVector<std::uint8_t>(*process_, target_, kTrampSize);

    ud_t ud_obj;
    ud_init(&ud_obj);
    ud_set_input_buffer(&ud_obj, buffer.data(), buffer.size());
    ud_set_syntax(&ud_obj, UD_SYN_INTEL);
    ud_set_pc(&ud_obj, reinterpret_cast<std::uint64_t>(target_));
#if defined(HADESMEM_DETAIL_ARCH_X64)
    ud_set_mode(&ud_obj, 64);
#elif defined(HADESMEM_DETAIL_ARCH_X86)
    ud_set_mode(&ud_obj, 32);
#else
#error "[HadesMem] Unsupported architecture."
#endif

    stub_gate_ = detail::AllocatePageNear(*process_, target_);

    std::size_t const patch_size = GetPatchSize();

    std::uint32_t instr_size = 0;
    do
    {
      std::uint32_t const len = ud_disassemble(&ud_obj);
      if (len == 0)
      {
        HADESMEM_DETAIL_THROW_EXCEPTION(Error{}
                                        << ErrorString{"Disassembly failed."});
      }

#if !defined(HADESMEM_NO_TRACE)
      char const* const asm_str = ud_insn_asm(&ud_obj);
      char const* const asm_bytes_str = ud_insn_hex(&ud_obj);
      HADESMEM_DETAIL_TRACE_FORMAT_A(
        "%s. [%s].",
        (asm_str ? asm_str : "Invalid."),
        (asm_bytes_str ? asm_bytes_str : "Invalid."));
#endif

      ud_operand_t const* const op = ud_insn_opr(&ud_obj, 0);
      bool is_jimm = op && op->type == UD_OP_JIMM;
      // Handle JMP QWORD PTR [RIP+Rel32]. Necessary for hook chain support.
      bool is_jmem = op && op->type == UD_OP_MEM && op->base == UD_R_RIP &&
                     op->index == UD_NONE && op->scale == 0 && op->size == 0x40;
      if ((ud_obj.mnemonic == UD_Ijmp || ud_obj.mnemonic == UD_Icall) && op &&
          (is_jimm || is_jmem))
      {
        std::uint16_t const size = is_jimm ? op->size : op->offset;
        HADESMEM_DETAIL_TRACE_FORMAT_A("Operand/offset size is %hu.", size);
        std::int64_t const insn_target = [&]() -> std::int64_t
        {
          switch (size)
          {
          case sizeof(std::int8_t) * CHAR_BIT:
            return op->lval.sbyte;
          case sizeof(std::int16_t) * CHAR_BIT:
            return op->lval.sword;
          case sizeof(std::int32_t) * CHAR_BIT:
            return op->lval.sdword;
          case sizeof(std::int64_t) * CHAR_BIT:
            return op->lval.sqword;
          default:
            HADESMEM_DETAIL_ASSERT(false);
            HADESMEM_DETAIL_THROW_EXCEPTION(
              Error{} << ErrorString{"Unknown instruction size."});
          }
        }();

        auto const resolve_rel =
          [](std::uint64_t base, std::int64_t target, std::uint32_t insn_len)
        {
          return reinterpret_cast<std::uint8_t*>(
                   static_cast<std::uintptr_t>(base)) +
                 target + insn_len;
        };

        std::uint64_t const insn_base = ud_insn_off(&ud_obj);
        std::uint32_t const insn_len = ud_insn_len(&ud_obj);

        auto const resolved_target =
          resolve_rel(insn_base, insn_target, insn_len);
        void* const jump_target =
          is_jimm ? resolved_target : Read<void*>(*process_, resolved_target);
        HADESMEM_DETAIL_TRACE_FORMAT_A("Jump/call target = %p.", jump_target);
        if (ud_obj.mnemonic == UD_Ijmp)
        {
          HADESMEM_DETAIL_TRACE_A("Writing resolved jump.");
          tramp_cur += detail::WriteJump(
            *process_, tramp_cur, jump_target, true, &trampolines_);
        }
        else
        {
          HADESMEM_DETAIL_ASSERT(ud_obj.mnemonic == UD_Icall);
          HADESMEM_DETAIL_TRACE_A("Writing resolved call.");
          tramp_cur +=
            detail::WriteCall(*process_, tramp_cur, jump_target, trampolines_);
        }
      }
      else
      {
        std::uint8_t const* const raw = ud_insn_ptr(&ud_obj);
        Write(*process_, tramp_cur, raw, raw + len);
        tramp_cur += len;
      }

      instr_size += len;
    } while (instr_size < patch_size);

    HADESMEM_DETAIL_TRACE_A("Writing jump back to original code.");

    tramp_cur +=
      detail::WriteJump(*process_,
                        tramp_cur,
                        reinterpret_cast<std::uint8_t*>(target_) + instr_size,
                        true,
                        &trampolines_);

    FlushInstructionCache(
      *process_, trampoline_->GetBase(), trampoline_->GetSize());

    detail::WriteStubGate<TargetFuncT>(*process_,
                                       stub_gate_->GetBase(),
                                       &*stub_,
                                       &GetOriginalArbitraryUserPtrPtr);

    orig_ = ReadVector<std::uint8_t>(*process_, target_, patch_size);

    detail::VerifyPatchThreads(process_->GetId(), target_, orig_.size());

    WritePatch();

    FlushInstructionCache(*process_, target_, instr_size);

    applied_ = true;
  }