从网上下载十万个为什么的 APK 安装包后,直接改成ZIP进行解压。因为网上文章说神之刃 是 妙趣横生 的自研引擎,所以直接来看Libs文件夹吧。

Libs文件夹里面有4个不同CPU类型的子文件夹,只有 armeabi-v7a 中存在引擎相关的SO动态链接库文件。

Messiah引擎 nga_神之刃


看到这五个SO文件,给我这个半吊子游戏开发者造成的迷惑来说不亚于太阳从西边出来。

为什么这么说?

libcheck.so  libentryex.so 这两个应该是腾讯的三方SDK所有。

libgnustl_shared.so 这个文件应该是使用了C++所以会有。

那么游戏所有的就只有 libmqcj.so  libcompress.so 这两个动态链接库了。

直觉告诉我,这两个动态链接库不可能是游戏主要的动态链接库文件。

至于SO文件的大小,Unity的 libunity.so + libmono.so 是14M,就连NDK的Sample都有47KB。难道十万个为什么整个游戏框架只有58+6KB?这明显不可能的。

文章出自

进一步,反编译APK,查看Manifest文件和Java源代码。



上面是十万个为什么的Manifest文件,从中可以看出:

com.mqgame.lib.SLaunchActivity  这个是游戏的启动Activity 。 

com.mqgame.lib.SNativeActivity   这个是NativiActivity ,并且指定动态链接库 mqcj ,就是上面6KB的那个文件。


来分析反编译出来的Java源代码。

首先来看 com.mqgame.lib.SLaunchActivity ,这个Activity 在游戏中就是 资源准备的界面。女王大人。

Messiah引擎 nga_bc_02

if (localIterator.hasNext())
      {
        localRunningTaskInfo = (ActivityManager.RunningTaskInfo)localIterator.next();
        if ((localRunningTaskInfo.topActivity.getPackageName().equals(getPackageName())) || (localRunningTaskInfo.baseActivity.getPackageName().equals(getPackageName())))
          if ((localRunningTaskInfo.topActivity.getClassName().equals("com.mqgame.lib.SNativeActivity")) || (localRunningTaskInfo.baseActivity.getClassName().equals("com.mqgame.lib.SNativeActivity")))
            if (localRunningTaskInfo.numRunning >= 1)
            {
              Log.d("sog_debug", "SOGActivity:Relaunch native");
              localIntent2 = getIntent();
              if (localIntent2 != null)
              {
                localIntent2.setClass(this, SNativeActivity.class);
                label194: localIntent2.setFlags(131072);
                startActivity(localIntent2);
                finish();
              }
            }
      }



然后在加载任务执行完毕后,跳转到 SNativeActivity 。

在SNativeActivity中看到有一个 preRun函数

文章出自

public boolean preRun()
  {
    int i = 1;
    label323: int j;
    do
    {
      try
      {
        LinkedList localLinkedList = new LinkedList();
        localLinkedList.add(new String("gnustl_shared"));
        localLinkedList.add(new String("openal"));
        localLinkedList.add(new String("compress"));
        localLinkedList.add(new String("script"));
        localLinkedList.add(new String("iconv"));
        localLinkedList.add(new String("ogg"));
        localLinkedList.add(new String("vorbis"));
        localLinkedList.add(new String("vorbisfile"));
        localLinkedList.add(new String("curl"));
        localLinkedList.add(new String("autoupdater"));
        localLinkedList.add(new String("speex"));
        localLinkedList.add(new String("mqcj"));
        Iterator localIterator = localLinkedList.iterator();
        while (true)
        {
          if (!localIterator.hasNext())
            break label323;
          String str1 = (String)localIterator.next();
          str2 = new String(SUtility.getLibPath() + File.separator + "lib" + str1 + ".so");
          if (new File(str2).exists())
            break;
          System.loadLibrary(str1);
        }
      }
      catch (Exception localException)
      {
        while (true)
        {
          String str2;
          localException.printStackTrace();
          SUtility.appendLog(localException.toString());
          i = 0;
          return i;
          System.load(str2);
        }
      }
      catch (Error localError)
      {
        localError.printStackTrace();
        SUtility.appendLog(localError.toString());
        return i;
      }
      VoiceManager.init(this);
      SUtility.bNativeEntered = true;
      j = Settings.System.getInt(getContentResolver(), "accelerometer_rotation", 0);
    }
    while ((Build.VERSION.SDK_INT < 9) || (j != i));
    setRequestedOrientation(6);
    return i;
  }

从代码上来理解,应该存在两个目录用于存放SO文件。

首先从默认的Libs目录查找,然后从第二个Libs文件夹中寻找是不是有这个SO文件,如果有就使用第二个的SO。于是开始在SDK卡中寻找。却没有搜索到,看样子并没有解压到SDK卡中。那就应该是解压到了APP的默认应用文件夹了。于是去找了一个Root的手机来安装游戏。

。。。。。。。文章出自

在玩游戏的时候正好电脑上开着Eclipse,看到了以下Log:

03-29 16:14:07.582: D/SOG(8950): Ready to show Game
03-29 16:14:07.587: D/dalvikvm(8950): Trying to load lib /data/app-lib/com.linekong.cjad.lk-1/libgnustl_shared.so 0x421565f0
03-29 16:14:07.597: D/dalvikvm(8950): Added shared lib /data/app-lib/com.linekong.cjad.lk-1/libgnustl_shared.so 0x421565f0
03-29 16:14:07.597: D/dalvikvm(8950): No JNI_OnLoad found in /data/app-lib/com.linekong.cjad.lk-1/libgnustl_shared.so 0x421565f0, skipping init
03-29 16:14:07.597: D/SOG_DEBUG(8950): Loading liberary from inner gnustl_shared
03-29 16:14:07.597: D/dalvikvm(8950): Trying to load lib /data/app-lib/com.linekong.cjad.lk-1/libcompress.so 0x421565f0
03-29 16:14:07.602: D/dalvikvm(2087): GC_CONCURRENT freed 24K, 28% free 17104K/23584K, paused 2ms+2ms, total 22ms
03-29 16:14:07.602: D/dalvikvm(2087): WAIT_FOR_CONCURRENT_GC blocked 19ms
03-29 16:14:07.607: D/dalvikvm(8950): Added shared lib /data/app-lib/com.linekong.cjad.lk-1/libcompress.so 0x421565f0
03-29 16:14:07.607: D/dalvikvm(8950): No JNI_OnLoad found in /data/app-lib/com.linekong.cjad.lk-1/libcompress.so 0x421565f0, skipping init
03-29 16:14:07.607: D/SOG_DEBUG(8950): Loading liberary from inner compress
03-29 16:14:07.607: D/dalvikvm(8950): Trying to load lib /data/data/com.linekong.cjad.lk/files/libs/libcurl.so 0x421565f0
03-29 16:14:07.607: D/dalvikvm(8950): GC_CONCURRENT freed 253K, 6% free 5156K/5480K, paused 6ms+2ms, total 17ms
03-29 16:14:07.612: D/dalvikvm(8950): Added shared lib /data/data/com.linekong.cjad.lk/files/libs/libcurl.so 0x421565f0
03-29 16:14:07.612: D/dalvikvm(8950): No JNI_OnLoad found in /data/data/com.linekong.cjad.lk/files/libs/libcurl.so 0x421565f0, skipping init
03-29 16:14:07.612: D/SOG_DEBUG(8950): Loading liberary from path:/data/data/com.linekong.cjad.lk/files/libs/libcurl.so
03-29 16:14:07.612: D/dalvikvm(8950): Trying to load lib /data/data/com.linekong.cjad.lk/files/libs/libautoupdater.so 0x421565f0
03-29 16:14:07.642: D/dalvikvm(8950): Added shared lib /data/data/com.linekong.cjad.lk/files/libs/libautoupdater.so 0x421565f0
03-29 16:14:07.642: D/dalvikvm(8950): No JNI_OnLoad found in /data/data/com.linekong.cjad.lk/files/libs/libautoupdater.so 0x421565f0, skipping init
03-29 16:14:07.642: D/SOG_DEBUG(8950): Loading liberary from path:/data/data/com.linekong.cjad.lk/files/libs/libautoupdater.so
03-29 16:14:07.677: D/libEGL(8950): loaded /system/lib/egl/libEGL_mali.so
03-29 16:14:07.677: D/libEGL(8950): loaded /system/lib/egl/libGLESv1_CM_mali.so
03-29 16:14:07.682: D/libEGL(8950): loaded /system/lib/egl/libGLESv2_mali.so
03-29 16:14:07.687: E/(8950): Device driver API match
03-29 16:14:07.687: E/(8950): Device driver API version: 401
03-29 16:14:07.687: E/(8950): User space API version: 401 
03-29 16:14:07.687: E/(8950): mali: REVISION=Linux-r4p0-00rel0 BUILD_DATE=Tue Jul  8 00:03:51 CST 2014 
03-29 16:14:07.687: W/linker(8950): libion.so has text relocations. This is wasting memory and is a security risk. Please fix.
03-29 16:14:07.687: V/WindowAnimator(1979): No window is displayed, unset the SET_ORIENTATION_CHANGE_COMPLETE flag
03-29 16:14:07.742: D/OpenGLRenderer(8950): Enabling debug mode 0
03-29 16:14:07.757: D/SOG(8950): Total:1090 Sub:1080 SceenX:1280 SceenY:800 dX:76 dy:43 nProcess X:160 nProcess Width:770 LocaltionShow:0
03-29 16:14:07.782: D/dalvikvm(8950): GC_FOR_ALLOC freed 64K, 7% free 5140K/5480K, paused 9ms, total 9ms
03-29 16:14:07.787: I/dalvikvm-heap(8950): Grow heap (frag case) to 6.647MB for 1638544-byte allocation
03-29 16:14:07.797: D/dalvikvm(8950): GC_FOR_ALLOC freed <1K, 5% free 6740K/7084K, paused 13ms, total 13ms
03-29 16:14:07.812: D/dalvikvm(8950): GC_CONCURRENT freed 2K, 5% free 6771K/7084K, paused 1ms+2ms, total 16ms
03-29 16:14:07.817: D/sog_debug(8950): launch service
03-29 16:14:07.817: D/SOG(8661): sog service shutdown
03-29 16:14:07.817: D/SOG(8661): sog service startuping
03-29 16:14:07.817: D/Service Loading(8661): /data/data/com.linekong.cjad.lk/files/libs/libgnustl_shared.so
03-29 16:14:07.817: D/dalvikvm(8661): Trying to load lib /data/app-lib/com.linekong.cjad.lk-1/libgnustl_shared.so 0x421512b0
03-29 16:14:07.817: D/dalvikvm(8661): Shared lib '/data/app-lib/com.linekong.cjad.lk-1/libgnustl_shared.so' already loaded in same CL 0x421512b0
03-29 16:14:07.817: D/Service Loading(8661): /data/data/com.linekong.cjad.lk/files/libs/libcompress.so
03-29 16:14:07.817: D/dalvikvm(8661): Trying to load lib /data/app-lib/com.linekong.cjad.lk-1/libcompress.so 0x421512b0
03-29 16:14:07.817: D/dalvikvm(8661): Shared lib '/data/app-lib/com.linekong.cjad.lk-1/libcompress.so' already loaded in same CL 0x421512b0
03-29 16:14:07.817: D/Service Loading(8661): /data/data/com.linekong.cjad.lk/files/libs/libscript.so
03-29 16:14:07.822: D/dalvikvm(8661): Trying to load lib /data/data/com.linekong.cjad.lk/files/libs/libscript.so 0x421512b0
03-29 16:14:07.822: D/sog_debug(8950): launch game
03-29 16:14:07.822: D/dalvikvm(8661): Shared lib '/data/data/com.linekong.cjad.lk/files/libs/libscript.so' already loaded in same CL 0x421512b0
03-29 16:14:07.822: D/Service Loading(8661): /data/data/com.linekong.cjad.lk/files/libs/libiconv.so
03-29 16:14:07.822: D/dalvikvm(8661): Trying to load lib /data/data/com.linekong.cjad.lk/files/libs/libiconv.so 0x421512b0
03-29 16:14:07.822: D/dalvikvm(8661): Shared lib '/data/data/com.linekong.cjad.lk/files/libs/libiconv.so' already loaded in same CL 0x421512b0
03-29 16:14:07.822: D/Service Loading(8661): /data/data/com.linekong.cjad.lk/files/libs/libcurl.so
03-29 16:14:07.822: D/dalvikvm(8661): Trying to load lib /data/data/com.linekong.cjad.lk/files/libs/libcurl.so 0x421512b0
03-29 16:14:07.822: D/dalvikvm(8661): Shared lib '/data/data/com.linekong.cjad.lk/files/libs/libcurl.so' already loaded in same CL 0x421512b0
03-29 16:14:07.822: D/Service Loading(8661): /data/data/com.linekong.cjad.lk/files/libs/libpush.so
03-29 16:14:07.822: D/dalvikvm(8661): Trying to load lib /data/data/com.linekong.cjad.lk/files/libs/libpush.so 0x421512b0
03-29 16:14:07.822: D/dalvikvm(8661): Shared lib '/data/data/com.linekong.cjad.lk/files/libs/libpush.so' already loaded in same CL 0x421512b0

03-29 16:14:08.417: D/dalvikvm(8950): Trying to load lib /data/app-lib/com.linekong.cjad.lk-1/libgnustl_shared.so 0x421565f0
03-29 16:14:08.417: D/dalvikvm(8950): Shared lib '/data/app-lib/com.linekong.cjad.lk-1/libgnustl_shared.so' already loaded in same CL 0x421565f0
03-29 16:14:08.417: D/dalvikvm(8950): Trying to load lib /data/data/com.linekong.cjad.lk/files/libs/libopenal.so 0x421565f0
03-29 16:14:08.422: D/dalvikvm(8950): Added shared lib /data/data/com.linekong.cjad.lk/files/libs/libopenal.so 0x421565f0
03-29 16:14:08.422: D/dalvikvm(8950): Trying to load lib /data/app-lib/com.linekong.cjad.lk-1/libcompress.so 0x421565f0
03-29 16:14:08.422: D/dalvikvm(8950): Shared lib '/data/app-lib/com.linekong.cjad.lk-1/libcompress.so' already loaded in same CL 0x421565f0
03-29 16:14:08.422: D/dalvikvm(8950): Trying to load lib /data/data/com.linekong.cjad.lk/files/libs/libscript.so 0x421565f0
03-29 16:14:08.422: D/dalvikvm(8950): Added shared lib /data/data/com.linekong.cjad.lk/files/libs/libscript.so 0x421565f0
03-29 16:14:08.422: D/dalvikvm(8950): No JNI_OnLoad found in /data/data/com.linekong.cjad.lk/files/libs/libscript.so 0x421565f0, skipping init
03-29 16:14:08.422: D/dalvikvm(8950): Trying to load lib /data/data/com.linekong.cjad.lk/files/libs/libiconv.so 0x421565f0
03-29 16:14:08.422: D/dalvikvm(8950): Added shared lib /data/data/com.linekong.cjad.lk/files/libs/libiconv.so 0x421565f0
03-29 16:14:08.422: D/dalvikvm(8950): No JNI_OnLoad found in /data/data/com.linekong.cjad.lk/files/libs/libiconv.so 0x421565f0, skipping init
03-29 16:14:08.422: D/dalvikvm(8950): Trying to load lib /data/data/com.linekong.cjad.lk/files/libs/libogg.so 0x421565f0
03-29 16:14:08.427: D/dalvikvm(8950): Added shared lib /data/data/com.linekong.cjad.lk/files/libs/libogg.so 0x421565f0
03-29 16:14:08.427: D/dalvikvm(8950): No JNI_OnLoad found in /data/data/com.linekong.cjad.lk/files/libs/libogg.so 0x421565f0, skipping init
03-29 16:14:08.427: D/dalvikvm(8950): Trying to load lib /data/data/com.linekong.cjad.lk/files/libs/libvorbis.so 0x421565f0
03-29 16:14:08.427: D/dalvikvm(8950): Added shared lib /data/data/com.linekong.cjad.lk/files/libs/libvorbis.so 0x421565f0
03-29 16:14:08.427: D/dalvikvm(8950): No JNI_OnLoad found in /data/data/com.linekong.cjad.lk/files/libs/libvorbis.so 0x421565f0, skipping init
03-29 16:14:08.427: D/dalvikvm(8950): Trying to load lib /data/data/com.linekong.cjad.lk/files/libs/libvorbisfile.so 0x421565f0
03-29 16:14:08.427: D/dalvikvm(8950): Added shared lib /data/data/com.linekong.cjad.lk/files/libs/libvorbisfile.so 0x421565f0
03-29 16:14:08.427: D/dalvikvm(8950): No JNI_OnLoad found in /data/data/com.linekong.cjad.lk/files/libs/libvorbisfile.so 0x421565f0, skipping init
03-29 16:14:08.427: D/dalvikvm(8950): Trying to load lib /data/data/com.linekong.cjad.lk/files/libs/libcurl.so 0x421565f0
03-29 16:14:08.427: D/dalvikvm(8950): Shared lib '/data/data/com.linekong.cjad.lk/files/libs/libcurl.so' already loaded in same CL 0x421565f0
03-29 16:14:08.427: D/dalvikvm(8950): Trying to load lib /data/data/com.linekong.cjad.lk/files/libs/libautoupdater.so 0x421565f0
03-29 16:14:08.427: D/dalvikvm(8950): Shared lib '/data/data/com.linekong.cjad.lk/files/libs/libautoupdater.so' already loaded in same CL 0x421565f0
03-29 16:14:08.427: D/dalvikvm(8950): Trying to load lib /data/data/com.linekong.cjad.lk/files/libs/libspeex.so 0x421565f0
03-29 16:14:08.432: D/dalvikvm(8950): Added shared lib /data/data/com.linekong.cjad.lk/files/libs/libspeex.so 0x421565f0
03-29 16:14:08.432: D/dalvikvm(8950): No JNI_OnLoad found in /data/data/com.linekong.cjad.lk/files/libs/libspeex.so 0x421565f0, skipping init
03-29 16:14:08.432: D/dalvikvm(8950): Trying to load lib /data/data/com.linekong.cjad.lk/files/libs/libmqcj.so 0x421565f0
03-29 16:14:08.502: D/dalvikvm(8950): Added shared lib /data/data/com.linekong.cjad.lk/files/libs/libmqcj.so 0x421565f0
03-29 16:14:08.502: W/Looper(8950): Looper already prepared for this thread with a different value for the ALOOPER_PREPARE_ALLOW_NON_CALLBACKS option.
03-29 16:14:08.507: V/VoiceManager(8950): VoiceManager Init Finished!
03-29 16:14:08.712: I/MemTotal:        1723840 kB MemFree:          357384 kB(8950): 	
03-29 16:14:08.712: I/MemTotal:        1723840 kB MemFree:          357384 kB(8950): MemTotal:	
03-29 16:14:08.712: I/MemTotal:        1723840 kB MemFree:          357384 kB(8950): 1723840	
03-29 16:14:08.712: I/MemTotal:        1723840 kB MemFree:          357384 kB(8950): kB	
03-29 16:14:08.712: I/MemTotal:        1723840 kB MemFree:          357384 kB(8950): MemFree:	
03-29 16:14:08.712: I/MemTotal:        1723840 kB MemFree:          357384 kB(8950): 357384	
03-29 16:14:08.712: I/MemTotal:        1723840 kB MemFree:          357384 kB(8950): kB


文章出自


顿时一切都明了了。

游戏分别从以下两个目录加载了SO文件

1、工程中的Libs文件夹,就是 /data/app-lib/,使用system.loadLibrary()加载

2、默认应用文件夹 /data/data/com.linekong.cjad.lk/files 中的 libs/* ,使用system.load() 加载

文章出自

在Root过的手机上安装ES文件管理器后,在/data/data/com.linekong.cjad.lk/files/libs中找到了游戏所使用的SO,如下

Messiah引擎 nga_十万个为什么_03

文章出自 文章出自

那么为什么要把Libs先压缩然后又解压出来呢,直接放到项目工程的Libs目录中不就好了?我想到的有以下两条原因:

1、其实这正也正式Cocos2d-x这么火的原因之一 --- 热更新。出了Bug?那就更新一下换一个SO吧……

2、江湖传言,有一种黑科技能将SO文件的压缩比率比APK默认压缩方法再提高50%。。。好吧其实就是7ZIP采用的LZMA压缩算法。

我们使用十万个为什么的几个SO来测试一下,看看默认放在项目Libs里面 和 使用7ZIP压缩之后放到Assets里面的文件大小差距吧。

这是游戏的SO文件,总共11M。

Messiah引擎 nga_神之刃_04

文章出自

Messiah引擎 nga_神之刃_05

这是三种出包方式,把上面的SO文件直接放到Libs、使用ZIP压缩后放到Assets 、使用7ZIP压缩后放到Assets。

从中可以看出,7ZIP 当之无愧的压缩界黑科技。之前也有同行辟谣,蓝港所谓的内部高压缩算法其实就是LZMA,这下我也有理由相信了。


十万个为什么的资源后缀名是SPK,比如这个music.spk ,应该就是音乐了。我们把它改成 7Z后缀,然后解压。

居然直接就解压了……截图为证……这下子确认蓝港使用的就是LZMA压缩算法了……

Messiah引擎 nga_bc_06