是否可以编写一个程序来掩盖计算机上安装的字体集,因此字体列表将显示为“普通的香草”并且在创建〜独特的指纹方面没有多大价值? https://panopticlick.eff.org/
2 回答
在某些浏览器中可能对此有一些支持,但是对于任何浏览器,您都可以拦截用于枚举字体列表的 winapi 调用。
基本上,您编写一个将加载到浏览器进程中的 dll,然后它将拦截浏览器在枚举字体时将对操作系统进行的调用。只需查找 windows 中的哪些函数用于枚举字体,并在您的 dll 中伪造它们。(虽然这可能是一些工作,因为您将不得不重写字体枚举逻辑)。
此外,有些浏览器可能只是读取注册表来枚举字体,而不使用专门的字体函数,在这种情况下,您将不得不拦截 registry-winapi 函数,并确保它们报告您想要的字体列表。
要将您的 dll 加载到目标进程中,您可以使用 Windows 挂钩,或使用 .exe 文件编辑器将您的 dll 添加到浏览器的 exe 文件的导入表中。注册表中还有一个特殊的地方,如果你在那里添加一个 dll,它将被加载到系统中的每个进程。(然后你必须检查浏览器进程,然后只拦截 api 调用,这样不是系统上的每个程序都会得到伪造的字体列表)。
此外,浏览器可能会在另一个进程中运行一些插件、activex 控件、java 或类似的东西(例如,chrome 在不同进程中运行每个选项卡),所以我会检查每个进程的父进程,如果你看到它已经被浏览器启动了,在那个过程中也拦截了字体列表。这样,目标网页将无法通过 flash、插件、java 或其他任何方式获取真正的字体列表。
可以在此处找到拦截 winapi 调用的良好开端:http: //www.codeproject.com/KB/system/InterceptWinAPICalls.aspx
所以这是一种可靠的方法,虽然不能在一小时内完成,但也不是太复杂。
当然,这不仅会让你的字体列表变得虚假,还会让浏览器看不到并且能够显示不在列表中的字体。
当然,这一切都适用于 Windows,但在其他操作系统上肯定有类似的方法可以做到这一点。
另外,值得注意的是,如果您禁用了 javascript 和插件(flash),我认为网页无法读取字体列表。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Font detector</title>
<style type="text/css" media="screen">
#font_detector_box{ visibility: hidden; }
#font_detector_box span.font{ padding: 0px; margin: 0px; border: none; font-size: 10px; letter-spacing: 1px; }
</style>
</head>
<body>
<h1>Font Detection Page</h1>
<p>This page is a sample for font detection tecniques</p>
<h2>List of fonts installed on your machine</h2>
<span id="font_list_display">
</span>
<!-- Invisible div -->
<div id="font_detector_box">
<span class="font family_Arial" style="font-family: Arial, Verdana !important">mmm</span>
<span class="font family_Comics_Sans_MS" style="font-family: Comic Sans MS, Arial !important">mmm</span>
<span class="font family_Georgia" style="font-family: Georgia, Arial !important">mmm</span>
<span class="font family_Helvetica" style="font-family: Helvetica, Verdana !important">mmm</span>
<span class="font family_Verdana" style="font-family: Verdana, Arial !important">mmm</span>
<span class="font family_Times_New_Roman" style="font-family: Times New Roman, Arial !important">mmm</span>
</div>
</body>
<script type="text/javascript"src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type="text/javascript">
var fontMeasures = new Array( );
//Web safe
fontMeasures["Arial"] = new Array( "30px", "13px" );
fontMeasures["Comics_Sans_MS"] = new Array( "27px" , "14px" );
fontMeasures["Georgia"] = new Array( "33px" , "13px" );
fontMeasures["Helvetica"] = new Array( "30px" , "13px" );
fontMeasures["Verdana"] = new Array( "36px" , "12px" );
fontMeasures["Times_New_Roman"] = new Array( "27px" , "12px" );
var msg = "";
$( ".font" , "#font_detector_box" ).each( function( ){
var fontFamily = $( this ).attr( "class" ).toString( ).replace( "font " , "" ).replace( "family_" , "" );
var width = $( this ).css( "width" );
var height = $( this ).css( "height" );
//alert( width + height );
if( fontMeasures[fontFamily][0] === width && fontMeasures[fontFamily][1] === height ){
var family = fontFamily.replace( /_/g , " " );
msg += '<span class="font-family: '+ family + ';">' + family + '</span> <br/>';
}
});
$( "#font_list_display" ).html( msg );
</script>
</html>