当前位置: 首页 > article >正文

设备内存指纹

一、前端通过获取Navigator.deviceMemory来查询系统内存。

二、Navigator.deviceMemory

1、navigator_device_memory.idl接口定义:

// https://github.com/w3c/device-memory#the-web-exposed-api

interface mixin NavigatorDeviceMemory {
    [HighEntropy=Direct,MeasureAs=NavigatorDeviceMemory,SecureContext]
    readonly attribute float deviceMemory;
};

2、v8_navigator

out\Debug\gen\third_party\blink\renderer\bindings\modules\v8\v8_navigator.cc

void DeviceMemoryAttributeGetCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
  
RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT(info.GetIsolate(), "Blink_Navigator_deviceMemory_Getter");
BLINK_BINDINGS_TRACE_EVENT("Navigator.deviceMemory.get");
// [HighEntropy]
const Dactyloscoper::HighEntropyTracer  high_entropy_tracer("Navigator.deviceMemory.get", info);
v8::Isolate* isolate = info.GetIsolate();
v8::Local<v8::Context> current_context = isolate->GetCurrentContext();
ExecutionContext* current_execution_context = ExecutionContext::From(current_context);
// [Measure], [MeasureAs]
UseCounter::Count(current_execution_context, WebFeature::kNavigatorDeviceMemory);



v8::Local<v8::Object> v8_receiver = info.This();
Navigator* blink_receiver = V8Navigator::ToWrappableUnsafe(isolate, v8_receiver);
auto&& return_value = blink_receiver->deviceMemory();
bindings::V8SetReturnValue(info, return_value, bindings::V8ReturnValue::PrimitiveType<float>());
// [HighEntropy=Direct]
Dactyloscoper::RecordDirectSurface(current_execution_context, WebFeature::kNavigatorDeviceMemory, return_value);
}

3、接口实现c++:

third_party\blink\renderer\core\frame\navigator_device_memory.h

third_party\blink\renderer\core\frame\navigator_device_memory.cc

namespace blink {

float NavigatorDeviceMemory::deviceMemory() const {
  return ApproximatedDeviceMemory::GetApproximatedDeviceMemory();
}

}  // namespace blink

third_party\blink\common\device_memory\approximated_device_memory.cc

namespace blink {

// static
float ApproximatedDeviceMemory::approximated_device_memory_gb_ = 0.0;
int64_t ApproximatedDeviceMemory::physical_memory_mb_ = 0;

// static
void ApproximatedDeviceMemory::Initialize() {
  if (approximated_device_memory_gb_ > 0.0)
    return;
  DCHECK_EQ(0, physical_memory_mb_);
  physical_memory_mb_ = ::base::SysInfo::AmountOfPhysicalMemoryMB();
  CalculateAndSetApproximatedDeviceMemory();
}

// static
float ApproximatedDeviceMemory::GetApproximatedDeviceMemory() {
  return approximated_device_memory_gb_;
}

// static
void ApproximatedDeviceMemory::CalculateAndSetApproximatedDeviceMemory() {
  // The calculations in this method are described in the specification:
  // https://w3c.github.io/device-memory/.
  DCHECK_GT(physical_memory_mb_, 0);
  int lower_bound = physical_memory_mb_;
  int power = 0;

  // Extract the most-significant-bit and its location.
  while (lower_bound > 1) {
    lower_bound >>= 1;
    power++;
  }
  // The remaining should always be equal to exactly 1.
  DCHECK_EQ(lower_bound, 1);

  int64_t upper_bound = lower_bound + 1;
  lower_bound = lower_bound << power;
  upper_bound = upper_bound << power;

  // Find the closest bound, and convert it to GB.
  if (physical_memory_mb_ - lower_bound <= upper_bound - physical_memory_mb_)
    approximated_device_memory_gb_ = static_cast<float>(lower_bound) / 1024.0;
  else
    approximated_device_memory_gb_ = static_cast<float>(upper_bound) / 1024.0;

  // Max-limit the reported value to 8GB to reduce fingerprintability of
  // high-spec machines.
  if (approximated_device_memory_gb_ > 8)
    approximated_device_memory_gb_ = 8.0;
}

// static
void ApproximatedDeviceMemory::SetPhysicalMemoryMBForTesting(
    int64_t physical_memory_mb) {
  physical_memory_mb_ = physical_memory_mb;
  CalculateAndSetApproximatedDeviceMemory();
}

}  // namespace blink

三、调用堆栈:

Navigator.deviceMemory 调用c++NavigatorDeviceMemory::deviceMemory()接口 返回内存大小指纹。

注意:当系统内存大于8GB时候浏览器默认是8G

四、总结:

修改内存指纹只需要在NavigatorDeviceMemory::deviceMemory()函数里面修改即可。

五、看下效果:

本人机器64G内存,浏览器默认指纹显示8G,将其改为18G编译看下效果。


http://www.kler.cn/a/418648.html

相关文章:

  • 算法训练营day22(二叉树08:二叉搜索树的最近公共祖先,插入,删除)
  • C++中输入 不定长数据的方法
  • 使用Dify与BGE-M3搭建RAG(检索增强生成)应用-改进一,使用工作流代替Agnet
  • C语言零基础——简单的排序算法(4种)
  • 哪些行业对六西格玛管理方法的需求较大?
  • 【linux学习指南】Linux进程信号产生(三) 硬件异常除零出错?野指针异常?core文件
  • 利用Python爬虫精准获取淘宝商品详情的深度解析
  • ros sensor_msgs::Imu详细介绍 Eigen::Vector3d 详细介绍
  • MySQL的一些常用函数
  • ARM实现URAT通信,看门狗中断,裸机开发
  • 开发一套ERP 第八弹 RUst 插入数据
  • docker服务容器化
  • VR眼镜可视化编程:开启医疗信息系统新纪元
  • [保姆式教程]使用labelimg2软件标注定向目标检测数据和格式转换
  • MATLAB中inputdlg函数用法
  • 【开源免费】基于SpringBoot+Vue.JS服装生产管理系统(JAVA毕业设计)
  • Java中的请求重发机制:详细解读与实现
  • nginx 代理 web service 提供 soap + xml 服务
  • 【H2O2|全栈】Node.js(2)
  • Solon (Spring 的替代方案)永久商用免费
  • Android 图形系统之五:Gralloc
  • 第十三章 使用 DHCP 动态管理主机地址
  • Spring集成Mybatis的实现
  • 基于rpcapd与wireshark的远程实时抓包的方法
  • 【CSS in Depth 2 精译_900】附录B:CSS 预处理器简介
  • IAR Embedded Workbench for Arm 使用技巧