1. 程式人生 > >Android安全之NDK的程式碼混淆 -- Ollvm

Android安全之NDK的程式碼混淆 -- Ollvm

安卓開發者交流群歡迎您加入
418263790

關鍵程式碼放JNI (C/C++)裡真的很安全嗎?

很多Android開發者都認為 把關鍵程式碼放到C/C++裡 然後打包靜態庫 然後破解者就無法破解
我想說 你太嫩了

不信? 舉個例子:

編寫以下jnil例子

#include <jni.h>
#include "android_log.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h> 

jint JNICALL
Java_com_test_Test(JNIEnv *env, jclass t,jint k) {
 int
key = 8; return key^k;//假設這是個演算法 }

然後使用ndk編譯

ubuntu@ubuntu:~/桌面/Android/project/AndroidNDK-master/jni$ ndk-build
[armeabi-v7a] Compile thumb  : SecShell <= test.c
[armeabi-v7a] SharedLibrary  : libSecShell.so
[armeabi-v7a] Install        : libSecShell.so => libs/armeabi-v7a/libSecShell.so
ubuntu@ubuntu
:~/桌面/Android/project/AndroidNDK-master/jni$
得到so檔案 然後開啟 IDA pro(反彙編工具) 沒有的百度下載

可以看到 我們的jni函式名: Java_com_test_Test
這裡寫圖片描述
點進去

然後按F5 檢視虛擬碼
這裡寫圖片描述

//IDA-pro 虛擬碼效果
int __fastcall Java_com_test_Test(int a1, int a2, int a3)
{
  return a3 ^ 8;
}

如圖 a3則是jint k , int key=8 於是相當於 k^8, 則為a3^8;
看到了吧 so的程式碼都能看到了 和我們的jni沒編譯前的程式碼基本一致, 你還覺得jni安全麼

插句話: 在 Android上實現OLLVM的資料實在太少了 不是寫的不全 或者寫的不知道是從哪裡抄來的 等等 好像寫這些高階文章 害怕我們學會似的 寫一半又故意留一半沒說 這還讓我們怎麼學習啊?看你裝B嗎? … 我實在看不慣才寫下了這篇文章 因此,轉載請註明出處!!!

因此 本文就是為了解決這個問題 使用 OLLVM對c程式碼進行混淆(類似java的混淆,但又不一樣)

環境:windows+vmware虛擬機器
Ubuntu 64位:

先貼一段從官網copy過來的,對OLLVM的說明

  • Obfuscator-LLVM is a project initiated in June 2010 by the information security group of the University of Applied Sciences and Arts Western Switzerland of Yverdon-les-Bains (HEIG-VD).
    The aim of this project is to provide an open-source fork of the LLVM compilation suite able to provide increased software security through code obfuscation and tamper-proofing. As we currently mostly work at the Intermediate Representation (IR) level, our tool is compatible with all programming languages (C, C++, Objective-C, Ada and Fortran) and target platforms (x86, x86-64, PowerPC, PowerPC-64, ARM, Thumb, SPARC, Alpha, CellSPU, MIPS, MSP430, SystemZ, and XCore) currently supported by LLVM.

安裝Linux下的NDK環境、cmake 、git 並配置好環境

這個參考我另一篇帖子FFmpeg For Android 系列 這裡我就不重複講了

編譯LLVM

先從git倉庫拉下來 拉不了的請到官網自己下下來然後解壓(後面的版本3.6.1直接看分支 拿最新的就好):

$ git clone -b obfuscator https://github.com/obfuscator-llvm/obfuscator.git

然後建立build目錄 並進行編譯

$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE:String=Release ../obfuscator/
$ make -j5

如果錯誤提示:沒有這個路徑,那就這樣

$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE:String=Release ../../obfuscator/
$ make -j5

注意這個obfuscator資料夾名 如果你下載的是另一個名字 那麼上面的命令要改成你的名字…
輸入 make -j5後 就開始編譯 ,然後等吧 等到100% 即可 編譯可能需要半小時左右…

編譯完成後
進入 你的NDK/toolchains下 比如我的是:

/home/ubuntu/桌面/Android/NDK/android-ndk-r10e/toolchains

然後找到arm-linux-androideabi-clang3.5 如果你沒找到 那就找arm-linux-androideabi-clang3.4或 arm-linux-androideabi-clang3.3 …懂了吧? 要記住 等會要用

/home/ubuntu/桌面/Android/NDK/android-ndk-r10e/toolchains/arm-linux-androideabi-clang3.5

進去把config.mk和setup.mk 兩個檔案 複製到

//config.mk和setup.mk 兩個檔案複製到這裡,沒有這個資料夾就自己建立
/toolchains/arm-linux-androideabi-clang3.4-obfuscator/

編輯arm-linux-androideabi-clang3.4-obfuscator/setup.mk檔案
將檔案裡面的:

TARGET_CC := $(LLVM_TOOLCHAIN_PREFIX)clang$(HOST_EXEEXT)
TARGET_CXX := $(LLVM_TOOLCHAIN_PREFIX)clang++$(HOST_EXEEXT)

修改為 注意路徑 不要照抄

LLVM_TOOLCHAIN_PATH :=這裡填你剛才編譯的LLVM的路徑/build/bin/
TARGET_CC := $(LLVM_TOOLCHAIN_PATH)clang$(HOST_EXEEXT)
TARGET_CXX := $(LLVM_TOOLCHAIN_PATH)clang++$(HOST_EXEEXT)

至此 ollvm已經和ndk聯絡起來了 那麼我們可以使用ollvm進行混淆c/c++了

建立jni工程

新建
Android.mk 檔案 內容為

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libSecShell
LOCAL_LDLIBS := -lm -llog 
LOCAL_SRC_FILES := test.c
LOCAL_CFLAGS := -mllvm -bcf -mllvm -boguscf-prob=100 -mllvm -boguscf-loop=1 -mllvm -sub -mllvm -fla -mllvm -perFLA=100

include $(BUILD_SHARED_LIBRARY)

這些命令請參看官方文件 本文後面有連結 -mllvm -bcf -mllvm -boguscf-prob=100 -mllvm -boguscf-loop=1 -mllvm -sub -mllvm -fla -mllvm -perFLA=100

解釋:這句是開啟級別更高的混淆

LOCAL_CFLAGS := -mllvm -bcf -mllvm -boguscf-prob=100 -mllvm -boguscf-loop=1 -mllvm -sub -mllvm -fla -mllvm -perFLA=100

Application.mk檔案內容如下

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
APP_ABI := armeabi-v7a
NDK_TOOLCHAIN_VERSION :=  clang3.4-obfuscator
APP_PLATFORM=android-14
include $(BUILD_EXECUTABLE)

解釋:clang3.4-obfuscator為剛才你複製的arm-linux-androideabi-clang3.4-obfuscator的資料夾字尾名稱 這樣ndk就會通過setup.mk裡找到obfuscator/build/bin/下的clang進行混淆編譯

然後 和普通NDK命令一樣 編譯jni工程

cd yourProject/jni
ndk-build

編譯so後 重新使用IDA pro反彙編這個so檔案,檢視c/c++程式碼 如下….

//IDA-pro  進行OLLVM混淆-虛擬碼效果
//尷尬了 一個普通的演算法突然混淆成這樣 大大增加了破解者的破解難度!!!
//....反正我是看不懂了...
unsigned int __fastcall Java_com_test_Test(int a1, int a2, int a3)
{
  signed int v3; // [email protected]
  signed int v4; // [email protected]
  unsigned int v5; // [email protected]
  signed int v6; // [email protected]
  bool v7; // [email protected]
  signed int v8; // [email protected]
  unsigned int v9; // [email protected]
  signed int v10; // [email protected]
  signed int v11; // [email protected]
  unsigned __int8 v13; // [sp+2h] [bp-16h]@3
  unsigned __int8 v14; // [sp+3h] [bp-15h]@5
  unsigned int v15; // [sp+4h] [bp-14h]@0

  v3 = 0;
  v4 = 0;
  v5 = x * ~-x & (x * ~-x ^ 0xFFFFFFFE);
  if ( !v5 )
    v4 = 1;
  v13 = v4;
  if ( y < 10 )
    v3 = 1;
  v6 = 0;
  v14 = v3;
  if ( v5 )
    v5 = 1;
  if ( y > 9 )
    v6 = 1;
  v7 = ((v6 | v5) ^ 1 | v4 ^ v3) == 0;
  v8 = -1313485305;
  v9 = a3 & 0xFFFFFFF7 | 8 * (((unsigned int)~a3 >> 3) & 1);
  v10 = -1265641972;
  if ( !v7 )
    v10 = 1153232101;
  while ( 1 )
  {
    v11 = v8;
    if ( v8 > 1153232100 )
      break;
    v8 = -1766943702;
    if ( v11 != -1265641972 )
    {
      if ( v11 == -1766943702 )
      {
        v15 = v9;
        v8 = v10;
      }
      else
      {
        if ( v11 != -1313485305 )
          goto LABEL_22;
        v8 = -1265641972;
        if ( ((unsigned __int8)(v13 & v14) | v13 ^ v14) & 1 )
          v8 = -1766943702;
      }
    }
  }
  if ( v8 != 1153232101 )
  {
    while ( 1 )
LABEL_22:
      ;
  }
  return v15;
}

以上就是混淆效果
你再看看原來沒混淆的

//IDA-pro 未進行OLLVM混淆-虛擬碼效果
int __fastcall Java_com_test_Test(int a1, int a2, int a3)
{
  return a3 ^ 8;
}

這就是區別 當然可能會導致運算速度降低 但至今未發現有什麼問題

參考

相關推薦

Android安全NDK程式碼混淆 -- Ollvm

安卓開發者交流群歡迎您加入 418263790 關鍵程式碼放JNI (C/C++)裡真的很安全嗎? 很多Android開發者都認為 把關鍵程式碼放到C/C++裡 然後打包靜態庫 然後破解者就無法破解 我想說 你太嫩了 不信? 舉個例子:

Android apk 簽名及程式碼混淆、資原始檔混淆、加固整套流程

準備:*.ks  proguard-android.txt', 'proguard-rules.pro(取一) 上述是簽名檔案及混淆檔案 通過AS進行混淆簽名打包apk 將該apk進行解壓可看出只是程式碼進行了混淆但是資原始檔沒有進行混淆 下面進行資原始檔進行混淆,也是通

Android 微信支付 程式碼混淆後打包,導致不能支付的原因

程式碼混淆: -libraryjars libs/libammsdk.jar -keep class com.tencent.** { *;} 如果您的專案中也引用了dom4j.jar,那麼就新增上下

Android安全allowBackup屬性的含義和危險性

一、前言 今天在開發的過程中遇到一個問題,就是關於AndroidManifest.xml中的allowBackup屬性,也算是自己之前對這個屬性的不瞭解,加上IDE的自動生成程式碼,沒太注意這個屬性,但是沒想到這個屬性會直接導致隱私資料的丟失。下面就來看一下這個屬性的影響到

Android開發——常用的程式碼混淆配置

前言 在Android開發當中,必不可少的是混淆配置。可是我們要做程式碼混淆呢?我來跟大家分享一下我開發的時候做程式碼混淆檔案配置吧! 程式碼混淆的好處 程式碼混淆,增加逆向之後的解讀的難度; 精簡程式碼,刪掉沒有用到的程式碼,減小apk的體積。

Android開發中的程式碼混淆

前言   程式碼混淆是在apk功能基本開發完成後進行的程式碼保護操作,混淆後的apk通過dex轉jar進行反編譯後,混淆部分的類名、方法名全部為英文字母,使反編譯者難以理解程式碼,達到程式碼保護的目的 gradle檔案配置   專案的build.g

Android 專案如何新增程式碼混淆

在網上搜“程式碼混淆”關鍵詞,可以看到n多教程。包括本篇部落格,大部分重要內容也是從網上各位大神的部落格裡面看到然後摘取和總結出來的。雖然網上都有,但是對於我個人來說,很難找到一篇部落格概括完全的,所以還是總結一下,也算是學習的紀錄。首先看看程式碼混淆是什麼。 總的來說,程式碼混淆有兩種重要功能。其一,混淆程

Android安全DM-verity中的Device Mapper機制分析

我們想法: 能不能將多個硬碟,對映成一個邏輯的硬碟,那樣我們程式就不用關心複雜的地址問題了,也不用關係是哪個device了? DM-raid技術RAID全稱為獨立磁碟冗餘陣列(Redundant Array of Independent Disks) 將某個地址段的資料進行加密,只有授權方式才可訪問,比

安全程式設計Android APK打包程式碼混淆

第一步:在專案工程目錄下的proguard-rules.pro檔案中配置自定義的混淆規則 #注意: #1.引用外部的jar包 如果不是自己寫的最好不混淆它們,因為外部jar包有可能已經混淆過 #2.不要混淆XML佈局中使用的自定義控制元件類,混淆後加載佈局會報找不到該控制

Android安全防護旅---帶你把Apk混淆成中文語言程式碼

一、前言最近想爆破一個app,沒有加殼,簡單的使用Jadx開啟檢視原始碼,結果把我逗樂了,程式碼中既然都是中文,而且是一些比較奇葩的中文字句,如圖所示:瞬間感覺懵逼了,這app真會玩,我們知道因為Jav

android程式碼混淆Gson解析為null

自古英雄不問出處,奈何我卻不是英雄! 如果你的專案中用到了Gson。並且你的程式在混淆之後執行後發現獲取了資料,但是在看解析成Gson的時候都是null,那麼你就要加上下面的程式碼。這裡要注意最後一行。這個是你javabean物件的路徑 -keepattrib

六、Android安全機制NDK實現防鉤子簽名校驗

//對公鑰MD5後進行比對驗證 void MD5_Check(char *src) { char buff[3] = {'\0'}; char hex[33] = {'\0'}; unsigned char digest[MD5_DIGEST_LENGTH]; MD5_CTX ctx; MD5_Ini

Android開發程式碼混淆

應用混淆(ProGuard) ProGuard是一個免費的JAVA類檔案壓縮,優化,混淆器。 它探測並刪除沒有使用的類,欄位,方法和屬性,它刪除沒有用的說明並使用位元組碼得到最大優化,它使用無意義的名字重新命名類,欄位和方法。 我們先來介紹下ProGuard 我們為啥要使用ProGu

iOS 安全程式碼混淆

這裡主要說的是Objective-C的程式碼混淆,其實關於Objective-C的程式碼混淆文章在網上可以找到很多,這裡推薦一下念茜大神的部落格,還有一個寫的不錯的文章 iOS 對原始碼進行混淆.在我接觸程式碼混淆的時候基本上就是通過這兩個文章學會使用的.

android學習程式碼混淆小結

之前一直沒有對程式碼混淆有一個很明確的認識,今天重新對程式碼混淆做了一番瞭解,並記錄一下在Androidstudio上是如何做程式碼混淆的。 第一步: buildTypes { release { minifyEnabled true prog

[ios]安全攻防程式碼混淆的一個小工具

看了“念茜”的這篇文章: http://blog.csdn.net/yiyaaixuexi/article/details/29201699 覺得非常好,不過裡面提到一個func.list的檔案。 規則: 建立函式名列表func.list,寫入待混淆的函式名,如:-(voi

Android程式碼混淆混淆規則

        因為Android是使用Java開發的,所以開發者可以使用ProGuard對程式碼進行混淆。SDK已經集成了ProGuard工具,開發者可以從SDK目錄下的\tools\proguard目錄中進行檢視。         ProGuard是一個免費的Java

Android安全防護旅---只需要這幾行程式碼Android程式專案變得更加安全

我們在編碼美麗微信公眾號已經弄過了很多app了,不管是協議還是外掛,我們都是那麼一路走過來了,在操作的過程中也發現了很多問題就是應用不在乎安全問題帶來的後果,因為安全始終都是不可忽視的問題,辛辛苦苦寫的程式碼被人看的體無完膚對不起自己也對不起公司,所以如果你做了這幾件事至少可

使用Android Studo開發NDKGradle的配置(能debug C代碼)

lose service ng- services lba new import dev android 配置: 用的版本號是AS1.5(也能夠嘗試更高版本號)。 Gradle地址是distributionUrl=https\://services.gradle.org

Android 打包 + 程式碼混淆

一:打包生成一個 Apk            生成一個 Apk 是比較簡單的,直接使用 Android Stuido 的打包工具就可以快速的生成一個 Apk 檔案,在這裡多插一句題外話吧,嘿嘿,就是關於使用多渠道打包和一套程式碼打