Unity的代码加密是一个有点麻烦的事情,相对iOS的IL2CPP,安卓里直接存放的dll很容易被ILSpy这种工具打开。网上有一些资料,如Unity3D研究院之Android加密DLL与破解DLL .SO,常见的思路都是修改mono源代码后重新编译;但是这样有一个麻烦的地方在于每次升级Unity版本之后都需要重新编译对应版本的libmono.so出来…
后来Unite 2016的时候和朋友聊天,学到了一个新思路——直接用Hook的方式来解密,这样就可以直接使用Unity自带的libmono.so解决问题~具体一点,使用了Cydia Substrate的API来劫持mono API
MSImageRef
image
=
MSGetImageByName
(
);
if
(
image
==
NULL
)
return
1
;
void
*
ptr
=
MSFindSymbol
(
image
,
);
if
(
ptr
==
NULL
)
return
2
;
MSHookFunction
(
ptr
,
(
void
*)&
oldPtr
,
(
void
**)&
newPtr
);
|
由于非常简单就不展开解释了…反正就三个函数MSGetImageByName, MSFindSymbol, MSHookFunction的事儿
至于怎么接入,网上也有不少资料,我主要参考的是Substrate - hooking C on Android。需要注意的是很多教程是介绍如何劫持别的App,需要root;但是我们劫持的是自己,所以不用那么麻烦。
最后再给个踩坑经验提示:Java那边必须显示、按顺序加载库,不然的话其实在绝大多数机型上依然能正常工作、但有些手机会crash。
public
class Misc
{
static
{
System
.
loadLibrary
(
"mono"
);
System
.
loadLibrary
(
"substrate"
);
System
.
loadLibrary
(
"soulgame"
);
}
public static native int decrypt()
;
}
|
咳咳,最后的最后是必须注意的点:Android 7.0开始Hook方式将直接导致App崩溃 NDK Apps Linking to Platform Libraries
Starting in Android 7.0, the system prevents apps from dynamically linking against non-NDK libraries, which may cause your app to crash.
所以,我享受了一段时间不用每个版本编译mono之后也被逼回去了…当然你也不能说这个没有用啦,毕竟Android 7.0的占有率目前还是很低的(逃
更新 今天有朋友在群里遇到一个问题,有一个可能是使用了雨松MONO博客里的混淆方法导致的(依然是Android 7.0相关)。
dlopen failed
:
"libmono.so"
.
dynamic
section header was
not
found
|