如果你想了解代码层面的原理,请看这篇面向开发者的文档:https://hu60.cn/q.php/bbs.topic.103013.html
如果你有一个编译好的修改版Wine内建DLL,你想把它放进别的Wine创建的容器里当做原生DLL加载,你会发现根本做不到。无论如何设置函数库顶替,Wine都会认出这是个内建DLL,从而拒绝加载。如果设置函数库顶替为“原生先于内建”,Wine会加载位于自身lib文件夹里的DLL,如果设置函数库顶替为“原生”,Wine会报告找不到这个DLL。
Wine是如何识别出这是个内建DLL的呢,对你的DLL运行如下命令,就会发现真相:
strings xxx.dll | grep DLL
原来Wine在DLL里面放了一个字符串标记Wine builtin DLL
,只要检测到这个标记存在,就视其为内建DLL,无论放在哪里都不会作为原生DLL加载。
所以解决方法也很简单,用十六进制编辑器打开你的DLL,找到Wine builtin DLL
,把它改成等长的其他字符串就可以,比如改成Win32 native DLL
。只要Wine检测不到Wine builtin DLL
字符串,就会把它作为原生DLL加载了。
可以使用以下命令进行修改,以dwmapi.dll
为例:
f='./dwmapi.dll'; mv "$f" "$f.origin"; perl -pe 's/Wine builtin DLL/Win32 native DLL/g' < "$f.origin" > "$f";
原始文件会备份为dwmapi.dll.origin
,修改后的dwmapi.dll
中字符串变成Win32 native DLL
。
游戏是通过调用dwmapi.dll
来检测DWM功能是否打开的,所以只要该DLL始终报告“DWM已打开”,就可以绕过游戏的DWM功能检测。
把下面的dwmapi.dll
放进Wine容器的drive_c/windows/system32
或drive_c/windows/syswow64
文件夹,然后设置函数库顶替:dwmapi
=原生,就能绕过DWM检测了。
选中游戏,点击“启动”按钮旁边的🍷图标,选择“Wine设置”。
切换到“函数库顶替”选项卡,在输入框内输入“dwmapi”,然后点击添加。
在列表中找到并选中刚添加的“dwmapi”,点“编辑”,然后选择“原生”,点击“确定”。
@SCV,不行,因为wine安装目录lib文件夹里的dll会被优先使用,除非你先把这里的dll删掉,位于wine容器里的内建dll才有机会加载。但是这样就修改了wine安装,影响了其他程序。
由于无法调整这个加载顺序,想在不修改wine的情况下实现加载其他dll,只能伪装成“原生”。