SlideShare ist ein Scribd-Unternehmen logo
1 von 42
Downloaden Sie, um offline zu lesen
Protecting your Android content
Erik Hemming
Unity Technologies
Mobile Mechanic & Lead Android Developer
4 Apr 2013 Page
About me
• Developer at Unity / Sweden
• 3 years of Unity for Android
• Used to make games
• Battlefield series
• Focus on mobiles and consoles
• Android / PSM / VITA & PS4
2
4 Apr 2013 Page
Agenda
• Unity on Android - what does it mean?
• Authentication with Google Play Licensing
• Application tampering detection
• Code Obfuscation
• Encryption of
• PlayerPrefs
• Scripts
• Assets
• Conclusion / Q&A
3
4 Apr 2013 Page
Unity on Android
4
4 Apr 2013 Page
Unity on Android (overview)
5
Linux Kernel
Android / Dalvik VM
Unity on Android
Mono VM
User script / “Game”
OS
App
4 Apr 2013 Page
Unity on Android (detail)
6
C# / Scripts
Dalvik (Java)
4 Apr 2013 Page
Unity on Android (detail)
7
AndroidJavaObject
java.lang.Object
4 Apr 2013 Page
AndroidJavaObject et al
• Script objects wrap Java objects
• AndroidJavaObject → java.lang.Object
• AndroidJavaClass → java.lang.Class
• AndroidJavaRunnable → java.lang.Runnable
• AndroidJavaProxy → java.lang.reflect.Proxy (in Unity 4.2)
• Automatically maps / instantiates Classes by name
• Methods / Fields are handled through reflection lookups
8
4 Apr 2013 Page 9
java.lang.String str = new java.lang.String("some string");
int hash = str.hashCode();
AndroidJavaObject jo =
        new AndroidJavaObject("java.lang.String", "some string");
int hash = jo.Call<int>("hashCode");
Java
C#
AndroidJavaObject (example)
4 Apr 2013 Page
Authentication with
Google Play Licensing
10
4 Apr 2013 Page
Authentication with
Google Play Licensing
• Provided by Google
• Only available for applications published on Play Store
• Online verification of purchase records
• If the device is offline the verification will “fail”
• Example code (LVL) provided by Google
• Don’t use as-is - very easy to find and hack
11
4 Apr 2013 Page
Verification Flow
• Application → {random number} → Google
• Google → {message, signature} → Application
• message = purchase status + random number + timestamp + (..)
• signature = RSA(message, private key)
• Verify that RSA(signature, public key) is a match for ‘message’
12
4 Apr 2013 Page
How to handle the offline case
• “Online check” == “Internet access”
• Don’t require constant internet access
• that would ruin the game experience while flying / roaming / etc.
• Instead do the checks only if network is available
• allow the app be used a week (or so) without being verified
• trust the app/user during that time.
• If your app has game elements that require internet connection,
make sure you also do a license check at that point.
13
4 Apr 2013 Page
Server Side Verification
• Application → {some number / data request} → Google
• Google → {message, signature} → Application
• Application → {message, signature} → Server
• Server → {application data} → Application
• Server only fulfill Client requests that have correct ‘signature’
14
4 Apr 2013 Page
Unity Plugin :
Google Play License Verification
• Written in C#
• Except for the small Service Binder (Java) - loaded dynamically
• Easy to embed / hide anywhere in your project
• Available on the Unity Asset Store
• Ready to be included into an existing project
• Original project hosted on GitHub
• Feel free to fork and improve
15
4 Apr 2013 Page
Application tampering
detection
16
4 Apr 2013 Page
Application tampering detection
• Why?
• A hacker would have to remove and/or alter licensing checks
• and thus change the code in your application
• Also possible to change code to gain in-game advantages
• Like changing the physics so that a car drives faster
• In general a very easy way to determine if you’ve been hacked
17
4 Apr 2013 Page
Application tampering detection
• Make sure the application is signed with your key
• Make sure the Java code (classes.dex) isn’t altered
• Make sure the Mono class library (mscorlib.dll) isn’t altered
• if the License check is done in C# we will rely on it
• Make sure your script code (Assembly-CSharp.dll) isn’t altered
• Needs to be done from Assembly-UnityScript.dll, or v.v.
• Make sure your native code (libunity.so / libmono.so / etc) isn’t
altered
18
4 Apr 2013 Page
Check the APK signature (Java)
19
// Retrieve the PackageManager and packageName (i.e. 'com.Company.Product')
Activity activity = com.unity3d.player.UnityPlayer.currentActivity;
PackageManager manager = activity.getPackageManager();
String name = activity.getPackageName();
// Fetch APK signature(s)
PackageInfo packageInfo = manager.getPackageInfo(name, PackageManager.GET_SIGNATURES);
Signature[] signatures = packageInfo.signatures;
// Process signatures (i.e. check their validity)
for (Signature signature : signatures)
{
    Log.i("signature", signature.toCharsString());
    Log.i("signature hash", Integer.toHexString(signature.hashCode()));
}
4 Apr 2013 Page
Check the APK signature (UnityScript)
20
// Retrieve the PackageManager and packageName (i.e. 'com.Company.Product')
var unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
var activity = unity.GetStatic.<AndroidJavaObject>("currentActivity");
var manager = activity.Call.<AndroidJavaObject>("getPackageManager");
var name = activity.Call.<String>("getPackageName");
// Fetch APK signature(s)
var GET_SIGNATURES = 64;    // PackageManager.GET_SIGNATURES
var packageInfo = manager.Call.<AndroidJavaObject>("getPackageInfo", name, GET_SIGNATURES);
var signatures = packageInfo.Get.<AndroidJavaObject[]>("signatures");
// Process signatures (i.e. check their validity)
for (var i = 0; i < signatures.length; ++i)
{
    Debug.Log("signature = " + signatures[i].Call.<String>("toCharsString"));
    Debug.Log("signature hash = " + signatures[i].Call.<int>("hashCode").ToString("X"));
}
4 Apr 2013 Page
Detect changes to ‘classes.dex’ (C#)
21
// Unity's WWW class supports reading 'jar:{archive-url}!/{entry}' on Android
string urlScheme = "jar:file://";
string apkPath = Application.dataPath;
string separator = "!/";
string entry = "classes.dex";
string url = urlScheme + apkPath + separator + entry;
// Read classes.dex inside package.apk
WWW www = new WWW(url);
yield return www;
// Calculate the MD5 sum of classes.dex contents
MD5 md5 = new MD5CryptoServiceProvider();
byte[] hash = md5.ComputeHash(www.bytes);
// Print MD5 sum
System.Text.StringBuilder sb = new System.Text.StringBuilder();
for (int i = 0; i < hash.Length; i++)
    sb.Append(hash[i].ToString("x2"));
Debug.Log("md5sum(classes.dex) = " + sb.ToString());
4 Apr 2013 Page
Native libs check (UnityScript)
22
// Retrieve main Activity
var unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
var activity = unity.GetStatic.<AndroidJavaObject>("currentActivity");
// Retrieve ApplicationInfo and nativeLibraryDir (N.B. API-9 or newer only!)
var info = activity.Call.<AndroidJavaObject>("getApplicationInfo");
var nativeLibraryDir = info.Get.<String>("nativeLibraryDir");
var unityPath = Path.Combine(nativeLibraryDir, "libunity.so");
var file = new FileStream(unityPath, FileMode.Open, FileAccess.Read);
var sha1 = new SHA1CryptoServiceProvider();
var hash = sha1.ComputeHash(file);
file.Close();
// Print SHA1 sum
var sb = new System.Text.StringBuilder();
for (var i = 0; i < hash.Length; i++)
    sb.Append(hash[i].ToString("x2"));
Debug.Log("sha1sum(libunity.so) = " + sb.ToString());
4 Apr 2013 Page
Code Obfuscation
23
4 Apr 2013 Page
Code Obfuscation
• Java Obfuscation
• Proguard
• C# Obfuscation
• Obfuscar
• Hides method/variable names
• but still very much readable code
• False sense of security
24
4 Apr 2013 Page
Java Obfuscation (before)
25
private void playVideo()
{
    doCleanUp();
    try
    {
        mMediaPlayer = new MediaPlayer();
        if (mIsURL)
        {
            mMediaPlayer.setDataSource(mContext, Uri.parse(mFileName));
        }
        else if (mVideoLength != 0)
        {
            FileInputStream file = new FileInputStream(mFileName);
            mMediaPlayer.setDataSource(file.getFD(), mVideoOffset, mVideoLength);
            file.close();
        }
        else
        {
(...)
4 Apr 2013 Page
Java Obfuscation (after)
26
private void a()
{
    b();
    try
    {
        this.r = new MediaPlayer();
        if (this.h)
        {
            this.r.setDataSource(this.b, Uri.parse(this.e));
        }
        else
        {
            if (this.j != 0L)
            {
                Object localObject = new FileInputStream(this.e);
                this.r.setDataSource(((FileInputStream)localObject).getFD(), this.i, this.j);
                ((FileInputStream)localObject).close();
            }
            else
            {
(...)
4 Apr 2013 Page
Encryption
27
4 Apr 2013 Page
Encryption of PlayerPrefs
• Why?
• Prevent simple cheating
• Prevent cracking IAB purchases (if you cache anything locally)
• In general good practice for sensitive data (like game progression)
• How?
• Encrypt key/values before inserting them in the PlayerPrefs
• Use a user-specific encryption, so prefs cannot be copied, but still shared
in a cloud
28
4 Apr 2013 Page
SetString(key, value, secret)
29
// Hide 'key' string
string key_string = MD5(key);
// Convert 'value' into a byte array
byte[] bytes = UTF8Encoding.UTF8.GetBytes(value);
// Encrypt 'value' with 3DES('secret')
TripleDES des = new TripleDESCryptoServiceProvider();
des.Key = secret;
des.Mode = CipherMode.ECB;
ICryptoTransform xform = des.CreateEncryptor();
byte[] encrypted = xform.TransformFinalBlock(bytes, 0, bytes.Length);
// Convert encrypted array into a "readable" string
string encrypted_string = Convert.ToBase64String(encrypted, 0, encrypted.Length);
// Set the { key, encrypted value } pair in regular PlayerPrefs
PlayerPrefs.SetString(key_string, encrypted_string);
4 Apr 2013 Page
value GetString(key, secret)
30
// Hide 'key' string
string key_string = MD5(key);
// Retrieve encrypted 'value' and Base64 decode it
string value = PlayerPrefs.GetString(key_string);
byte[] bytes = Convert.FromBase64String(value);
// Decrypt 'value' with 3DES('secret')
TripleDES des = new TripleDESCryptoServiceProvider();
des.Key = secret;
des.Mode = CipherMode.ECB;
ICryptoTransform xform = des.CreateDecryptor();
byte[] decrypted = xform.TransformFinalBlock(bytes, 0, bytes.Length);
// Return decrypted value as a proper string
return UTF8Encoding.UTF8.GetString(decrypted);
4 Apr 2013 Page
Encrypted SetString() / GetString()
31
// Generate a secret based on 'username'
string username = "Turrican II";
MD5 md5 = new MD5CryptoServiceProvider();
byte[] secret = md5.ComputeHash(UTF8Encoding.UTF8.GetBytes(username));
// Game progress { key, value } pair
string key = "unlocked levels";
string value = "the desert rocks,traps,secret dungeons,the wall,the final challenge,the final fight";
// Insert { key, value } pair
SetString(key, value, secret);
// Retrieve { key, value }
string ret = GetString(key, secret);
// Output to the logcat
Debug.Log("secret = " + username);
Debug.Log(key + " = " + ret);
4 Apr 2013 Page
Encryption of Scripts
• Why?
• Scripts are generally insecure
• Gameplay could be altered
• Security checks could be disabled
• Code needs to be “hidden” for some reason (i.e. IAB logic)
32
4 Apr 2013 Page
Encryption of Scripts
• How?
• Compile scripts outside Unity
• Run a symmetric / asymmetric encryption on the Script.dll
• Choose a delivery mechanism
• Embed in the application, or
• Download it from a trusted server
• Decrypt the Script.dll in memory
• Load it through Assembly.Load(byte[])
33
4 Apr 2013 Page
Compile scripts outside Unity
• Download Mono (www.mono-project.com)
• Compile the script (Plugin.cs) with ‘gmcs’
• Reference the UnityEngine.dll assembly to access to Unity
34
$ gmcs
-target:library
-out:Script.dll
-r:AndroidPlayer/Managed/UnityEngine.dll
Plugin.cs
4 Apr 2013 Page
Encrypt the assembly
• Using OpenSSL
• Converted to ‘text’ using Base64 encoding
• Result can be embedded in Unity as a TextAsset
35
$ openssl rc2 -nosalt -p -in Script.dll -out Encrypted.bin
key=...
iv =...
$ base64 Encrypted.bin > ~/UnityProject/Assets/Encrypted.txt
4 Apr 2013 Page
Plugin.cs
36
using UnityEngine;
public class SomeImportantGameClass
{
    static SomeImportantGameClass()
    {
        const int GET_SIGNATURES = 64;
        AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer")
.GetStatic<AndroidJavaObject>("currentActivity");
        AndroidJavaObject manager = activity.Call<AndroidJavaObject>("getPackageManager");
        string packageName = activity.Call<string>("getPackageName");
        AndroidJavaObject packageInfo =
                manager.Call<AndroidJavaObject>("getPackageInfo", packageName, GET_SIGNATURES);
        AndroidJavaObject[] signatures = packageInfo.Get<AndroidJavaObject[]>("signatures");
        foreach (AndroidJavaObject signature in signatures)
        {
            Debug.Log("signature hash = " + signature.Call<int>("hashCode").ToString("X"));
        }
    }
(...)
}
4 Apr 2013 Page
Decrypt and run assembly
37
public TextAsset assembly;
void Start () {
    // Load encrypted data and decryption keys
    byte[] bytes = Convert.FromBase64String(assembly.text);
    byte[] key = new byte[] { <key from encryption step> };
    byte[] iv = new byte[] { <iv from encryption step> };
    // Decrypt assembly
    RC2 rc2 = new RC2CryptoServiceProvider();
    rc2.Mode = CipherMode.CBC;
    ICryptoTransform xform = rc2.CreateDecryptor(key, iv);
    byte[] decrypted = xform.TransformFinalBlock(bytes, 0, bytes.Length);
    // Load assembly and instantiate 'SomeImportantGameClass' to trigger static constructor
    Assembly asm = Assembly.Load(decrypted);
    Type SomeClass = asm.GetType("SomeImportantGameClass");
    SomeClass.GetConstructor(Type.EmptyTypes).Invoke(null);
}
4 Apr 2013 Page
Encryption of Assets
• Why?
• Some assets might need to be protected from tampering.
• “Assets” doesn’t necessarily mean just “textures”; could be
• Game logic
• Dalvik bytecode
• Script code
• Native code
• .. “anything”
38
4 Apr 2013 Page
Encryption of Assets
• How?
• Create an AssetBundle from the “secret” assets.
• Run a symmetric / asymmetric encryption on the AssetBundle.unity3d
• Choose a delivery mechanism
• Embed in the application, or
• Download it from a trusted server
• Decrypt the AssetBundle.unity3d in memory
• Load it through AssetBundle.CreateFromMemory(Byte[])
39
4 Apr 2013 Page
Conclusion
• Be imaginative
• APK integrity checks are so simple everyone should have them.
• Sensitive code must be protected
• Combine the different approaches, and create new ones
• Finally: Don’t spend too much time on this
• Instead update the logic for each new release.
40
4 Apr 2013 Page
Questions?
41
4 Apr 2013 Page
Thanks!
42
Twitter: @_eriq_

Weitere ähnliche Inhalte

Was ist angesagt?

R2서버정진욱
R2서버정진욱R2서버정진욱
R2서버정진욱
jungjinwouk
 
김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019
김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019
김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019
devCAT Studio, NEXON
 
이승재, 마비노기 듀얼: 분산 데이터베이스 트랜잭션 설계와 구현, NDC2015
이승재, 마비노기 듀얼: 분산 데이터베이스 트랜잭션 설계와 구현, NDC2015이승재, 마비노기 듀얼: 분산 데이터베이스 트랜잭션 설계와 구현, NDC2015
이승재, 마비노기 듀얼: 분산 데이터베이스 트랜잭션 설계와 구현, NDC2015
devCAT Studio, NEXON
 
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
devCAT Studio, NEXON
 
코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011
Esun Kim
 
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
devCAT Studio, NEXON
 
업적,칭호,타이틀 그게 뭐든간에...
업적,칭호,타이틀 그게 뭐든간에...업적,칭호,타이틀 그게 뭐든간에...
업적,칭호,타이틀 그게 뭐든간에...
SeungYeon Jeong
 

Was ist angesagt? (20)

오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
 
[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법
[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법
[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법
 
R2서버정진욱
R2서버정진욱R2서버정진욱
R2서버정진욱
 
NDC2018 안드로이드+유니티 네이티브 프로파일링 삽질기
NDC2018 안드로이드+유니티 네이티브 프로파일링 삽질기NDC2018 안드로이드+유니티 네이티브 프로파일링 삽질기
NDC2018 안드로이드+유니티 네이티브 프로파일링 삽질기
 
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
 
김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019
김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019
김동건, 할머니가 들려주신 마비노기 개발 전설, NDC2019
 
Best practices: Async vs. coroutines - Unite Copenhagen 2019
Best practices: Async vs. coroutines - Unite Copenhagen 2019Best practices: Async vs. coroutines - Unite Copenhagen 2019
Best practices: Async vs. coroutines - Unite Copenhagen 2019
 
Unityでパフォーマンスの良いUIを作る為のTips
Unityでパフォーマンスの良いUIを作る為のTipsUnityでパフォーマンスの良いUIを作る為のTips
Unityでパフォーマンスの良いUIを作る為のTips
 
이승재, 마비노기 듀얼: 분산 데이터베이스 트랜잭션 설계와 구현, NDC2015
이승재, 마비노기 듀얼: 분산 데이터베이스 트랜잭션 설계와 구현, NDC2015이승재, 마비노기 듀얼: 분산 데이터베이스 트랜잭션 설계와 구현, NDC2015
이승재, 마비노기 듀얼: 분산 데이터베이스 트랜잭션 설계와 구현, NDC2015
 
위대한 게임개발팀의 공통점
위대한 게임개발팀의 공통점위대한 게임개발팀의 공통점
위대한 게임개발팀의 공통점
 
d.ts 만들기
d.ts 만들기d.ts 만들기
d.ts 만들기
 
[2013 CodeEngn Conference 09] Park.Sam - 게임 해킹툴의 변칙적 공격 기법 분석
[2013 CodeEngn Conference 09] Park.Sam - 게임 해킹툴의 변칙적 공격 기법 분석[2013 CodeEngn Conference 09] Park.Sam - 게임 해킹툴의 변칙적 공격 기법 분석
[2013 CodeEngn Conference 09] Park.Sam - 게임 해킹툴의 변칙적 공격 기법 분석
 
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
 
NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉
NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉
NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉
 
쩌는게임기획서 이렇게 쓴다
쩌는게임기획서 이렇게 쓴다쩌는게임기획서 이렇게 쓴다
쩌는게임기획서 이렇게 쓴다
 
코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011
 
[Unite2015 박민근] 유니티 최적화 테크닉 총정리
[Unite2015 박민근] 유니티 최적화 테크닉 총정리[Unite2015 박민근] 유니티 최적화 테크닉 총정리
[Unite2015 박민근] 유니티 최적화 테크닉 총정리
 
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
 
업적,칭호,타이틀 그게 뭐든간에...
업적,칭호,타이틀 그게 뭐든간에...업적,칭호,타이틀 그게 뭐든간에...
업적,칭호,타이틀 그게 뭐든간에...
 
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
 

Ähnlich wie [UniteKorea2013] Protecting your Android content

Android Scripting
Android ScriptingAndroid Scripting
Android Scripting
Juan Gomez
 
Building Grails Plugins - Tips And Tricks
Building Grails Plugins - Tips And TricksBuilding Grails Plugins - Tips And Tricks
Building Grails Plugins - Tips And Tricks
Mike Hugo
 

Ähnlich wie [UniteKorea2013] Protecting your Android content (20)

OWASP ZAP Workshop for QA Testers
OWASP ZAP Workshop for QA TestersOWASP ZAP Workshop for QA Testers
OWASP ZAP Workshop for QA Testers
 
Attacking and Defending Mobile Applications
Attacking and Defending Mobile ApplicationsAttacking and Defending Mobile Applications
Attacking and Defending Mobile Applications
 
Webinar: Extend The Power of The ForgeRock Identity Platform Through Scripting
Webinar: Extend The Power of The ForgeRock Identity Platform Through ScriptingWebinar: Extend The Power of The ForgeRock Identity Platform Through Scripting
Webinar: Extend The Power of The ForgeRock Identity Platform Through Scripting
 
Android application analyzer
Android application analyzerAndroid application analyzer
Android application analyzer
 
Fastlane
FastlaneFastlane
Fastlane
 
Android Scripting
Android ScriptingAndroid Scripting
Android Scripting
 
Securing TodoMVC Using the Web Cryptography API
Securing TodoMVC Using the Web Cryptography APISecuring TodoMVC Using the Web Cryptography API
Securing TodoMVC Using the Web Cryptography API
 
Webinar–Mobile Application Hardening Protecting Business Critical Apps
Webinar–Mobile Application Hardening Protecting Business Critical AppsWebinar–Mobile Application Hardening Protecting Business Critical Apps
Webinar–Mobile Application Hardening Protecting Business Critical Apps
 
Android lessons you won't learn in school
Android lessons you won't learn in schoolAndroid lessons you won't learn in school
Android lessons you won't learn in school
 
Mitigating data theft_in_android
Mitigating data theft_in_androidMitigating data theft_in_android
Mitigating data theft_in_android
 
Automated malware analysis
Automated malware analysisAutomated malware analysis
Automated malware analysis
 
TDC2018SP | Trilha Mobile - Case VC+: Como tornar seguro um aplicativo mobile...
TDC2018SP | Trilha Mobile - Case VC+: Como tornar seguro um aplicativo mobile...TDC2018SP | Trilha Mobile - Case VC+: Como tornar seguro um aplicativo mobile...
TDC2018SP | Trilha Mobile - Case VC+: Como tornar seguro um aplicativo mobile...
 
Case VC+: Como tornar seguro um aplicativo mobile payment sem penalizar a exp...
Case VC+: Como tornar seguro um aplicativo mobile payment sem penalizar a exp...Case VC+: Como tornar seguro um aplicativo mobile payment sem penalizar a exp...
Case VC+: Como tornar seguro um aplicativo mobile payment sem penalizar a exp...
 
Overview of DroidCon UK 2015
Overview of DroidCon UK 2015 Overview of DroidCon UK 2015
Overview of DroidCon UK 2015
 
Pwning mobile apps without root or jailbreak
Pwning mobile apps without root or jailbreakPwning mobile apps without root or jailbreak
Pwning mobile apps without root or jailbreak
 
Hacking your Droid (Aditya Gupta)
Hacking your Droid (Aditya Gupta)Hacking your Droid (Aditya Gupta)
Hacking your Droid (Aditya Gupta)
 
Building Grails Plugins - Tips And Tricks
Building Grails Plugins - Tips And TricksBuilding Grails Plugins - Tips And Tricks
Building Grails Plugins - Tips And Tricks
 
Rapid Android Application Security Testing
Rapid Android Application Security TestingRapid Android Application Security Testing
Rapid Android Application Security Testing
 
Null mumbai-Android-Insecure-Data-Storage-Exploitation
Null mumbai-Android-Insecure-Data-Storage-ExploitationNull mumbai-Android-Insecure-Data-Storage-Exploitation
Null mumbai-Android-Insecure-Data-Storage-Exploitation
 
Android pentesting the hackers-meetup
Android pentesting the hackers-meetupAndroid pentesting the hackers-meetup
Android pentesting the hackers-meetup
 

Mehr von William Hugo Yang (7)

[UniteKorea2013] Serialization in Depth
[UniteKorea2013] Serialization in Depth[UniteKorea2013] Serialization in Depth
[UniteKorea2013] Serialization in Depth
 
[UniteKorea2013] Memory profiling in Unity
[UniteKorea2013] Memory profiling in Unity[UniteKorea2013] Memory profiling in Unity
[UniteKorea2013] Memory profiling in Unity
 
[UniteKorea2013] Unity Hacks
[UniteKorea2013] Unity Hacks[UniteKorea2013] Unity Hacks
[UniteKorea2013] Unity Hacks
 
[UniteKorea2013] Butterfly Effect DX11
[UniteKorea2013] Butterfly Effect DX11[UniteKorea2013] Butterfly Effect DX11
[UniteKorea2013] Butterfly Effect DX11
 
[UniteKorea2013] The Unity Rendering Pipeline
[UniteKorea2013] The Unity Rendering Pipeline[UniteKorea2013] The Unity Rendering Pipeline
[UniteKorea2013] The Unity Rendering Pipeline
 
[UniteKorea2013] Art tips and tricks
[UniteKorea2013] Art tips and tricks[UniteKorea2013] Art tips and tricks
[UniteKorea2013] Art tips and tricks
 
[UniteKorea2013] 2D content workflows
[UniteKorea2013] 2D content workflows[UniteKorea2013] 2D content workflows
[UniteKorea2013] 2D content workflows
 

Kürzlich hochgeladen

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Kürzlich hochgeladen (20)

GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 

[UniteKorea2013] Protecting your Android content

  • 1. Protecting your Android content Erik Hemming Unity Technologies Mobile Mechanic & Lead Android Developer
  • 2. 4 Apr 2013 Page About me • Developer at Unity / Sweden • 3 years of Unity for Android • Used to make games • Battlefield series • Focus on mobiles and consoles • Android / PSM / VITA & PS4 2
  • 3. 4 Apr 2013 Page Agenda • Unity on Android - what does it mean? • Authentication with Google Play Licensing • Application tampering detection • Code Obfuscation • Encryption of • PlayerPrefs • Scripts • Assets • Conclusion / Q&A 3
  • 4. 4 Apr 2013 Page Unity on Android 4
  • 5. 4 Apr 2013 Page Unity on Android (overview) 5 Linux Kernel Android / Dalvik VM Unity on Android Mono VM User script / “Game” OS App
  • 6. 4 Apr 2013 Page Unity on Android (detail) 6 C# / Scripts Dalvik (Java)
  • 7. 4 Apr 2013 Page Unity on Android (detail) 7 AndroidJavaObject java.lang.Object
  • 8. 4 Apr 2013 Page AndroidJavaObject et al • Script objects wrap Java objects • AndroidJavaObject → java.lang.Object • AndroidJavaClass → java.lang.Class • AndroidJavaRunnable → java.lang.Runnable • AndroidJavaProxy → java.lang.reflect.Proxy (in Unity 4.2) • Automatically maps / instantiates Classes by name • Methods / Fields are handled through reflection lookups 8
  • 9. 4 Apr 2013 Page 9 java.lang.String str = new java.lang.String("some string"); int hash = str.hashCode(); AndroidJavaObject jo =         new AndroidJavaObject("java.lang.String", "some string"); int hash = jo.Call<int>("hashCode"); Java C# AndroidJavaObject (example)
  • 10. 4 Apr 2013 Page Authentication with Google Play Licensing 10
  • 11. 4 Apr 2013 Page Authentication with Google Play Licensing • Provided by Google • Only available for applications published on Play Store • Online verification of purchase records • If the device is offline the verification will “fail” • Example code (LVL) provided by Google • Don’t use as-is - very easy to find and hack 11
  • 12. 4 Apr 2013 Page Verification Flow • Application → {random number} → Google • Google → {message, signature} → Application • message = purchase status + random number + timestamp + (..) • signature = RSA(message, private key) • Verify that RSA(signature, public key) is a match for ‘message’ 12
  • 13. 4 Apr 2013 Page How to handle the offline case • “Online check” == “Internet access” • Don’t require constant internet access • that would ruin the game experience while flying / roaming / etc. • Instead do the checks only if network is available • allow the app be used a week (or so) without being verified • trust the app/user during that time. • If your app has game elements that require internet connection, make sure you also do a license check at that point. 13
  • 14. 4 Apr 2013 Page Server Side Verification • Application → {some number / data request} → Google • Google → {message, signature} → Application • Application → {message, signature} → Server • Server → {application data} → Application • Server only fulfill Client requests that have correct ‘signature’ 14
  • 15. 4 Apr 2013 Page Unity Plugin : Google Play License Verification • Written in C# • Except for the small Service Binder (Java) - loaded dynamically • Easy to embed / hide anywhere in your project • Available on the Unity Asset Store • Ready to be included into an existing project • Original project hosted on GitHub • Feel free to fork and improve 15
  • 16. 4 Apr 2013 Page Application tampering detection 16
  • 17. 4 Apr 2013 Page Application tampering detection • Why? • A hacker would have to remove and/or alter licensing checks • and thus change the code in your application • Also possible to change code to gain in-game advantages • Like changing the physics so that a car drives faster • In general a very easy way to determine if you’ve been hacked 17
  • 18. 4 Apr 2013 Page Application tampering detection • Make sure the application is signed with your key • Make sure the Java code (classes.dex) isn’t altered • Make sure the Mono class library (mscorlib.dll) isn’t altered • if the License check is done in C# we will rely on it • Make sure your script code (Assembly-CSharp.dll) isn’t altered • Needs to be done from Assembly-UnityScript.dll, or v.v. • Make sure your native code (libunity.so / libmono.so / etc) isn’t altered 18
  • 19. 4 Apr 2013 Page Check the APK signature (Java) 19 // Retrieve the PackageManager and packageName (i.e. 'com.Company.Product') Activity activity = com.unity3d.player.UnityPlayer.currentActivity; PackageManager manager = activity.getPackageManager(); String name = activity.getPackageName(); // Fetch APK signature(s) PackageInfo packageInfo = manager.getPackageInfo(name, PackageManager.GET_SIGNATURES); Signature[] signatures = packageInfo.signatures; // Process signatures (i.e. check their validity) for (Signature signature : signatures) {     Log.i("signature", signature.toCharsString());     Log.i("signature hash", Integer.toHexString(signature.hashCode())); }
  • 20. 4 Apr 2013 Page Check the APK signature (UnityScript) 20 // Retrieve the PackageManager and packageName (i.e. 'com.Company.Product') var unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); var activity = unity.GetStatic.<AndroidJavaObject>("currentActivity"); var manager = activity.Call.<AndroidJavaObject>("getPackageManager"); var name = activity.Call.<String>("getPackageName"); // Fetch APK signature(s) var GET_SIGNATURES = 64;    // PackageManager.GET_SIGNATURES var packageInfo = manager.Call.<AndroidJavaObject>("getPackageInfo", name, GET_SIGNATURES); var signatures = packageInfo.Get.<AndroidJavaObject[]>("signatures"); // Process signatures (i.e. check their validity) for (var i = 0; i < signatures.length; ++i) {     Debug.Log("signature = " + signatures[i].Call.<String>("toCharsString"));     Debug.Log("signature hash = " + signatures[i].Call.<int>("hashCode").ToString("X")); }
  • 21. 4 Apr 2013 Page Detect changes to ‘classes.dex’ (C#) 21 // Unity's WWW class supports reading 'jar:{archive-url}!/{entry}' on Android string urlScheme = "jar:file://"; string apkPath = Application.dataPath; string separator = "!/"; string entry = "classes.dex"; string url = urlScheme + apkPath + separator + entry; // Read classes.dex inside package.apk WWW www = new WWW(url); yield return www; // Calculate the MD5 sum of classes.dex contents MD5 md5 = new MD5CryptoServiceProvider(); byte[] hash = md5.ComputeHash(www.bytes); // Print MD5 sum System.Text.StringBuilder sb = new System.Text.StringBuilder(); for (int i = 0; i < hash.Length; i++)     sb.Append(hash[i].ToString("x2")); Debug.Log("md5sum(classes.dex) = " + sb.ToString());
  • 22. 4 Apr 2013 Page Native libs check (UnityScript) 22 // Retrieve main Activity var unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); var activity = unity.GetStatic.<AndroidJavaObject>("currentActivity"); // Retrieve ApplicationInfo and nativeLibraryDir (N.B. API-9 or newer only!) var info = activity.Call.<AndroidJavaObject>("getApplicationInfo"); var nativeLibraryDir = info.Get.<String>("nativeLibraryDir"); var unityPath = Path.Combine(nativeLibraryDir, "libunity.so"); var file = new FileStream(unityPath, FileMode.Open, FileAccess.Read); var sha1 = new SHA1CryptoServiceProvider(); var hash = sha1.ComputeHash(file); file.Close(); // Print SHA1 sum var sb = new System.Text.StringBuilder(); for (var i = 0; i < hash.Length; i++)     sb.Append(hash[i].ToString("x2")); Debug.Log("sha1sum(libunity.so) = " + sb.ToString());
  • 23. 4 Apr 2013 Page Code Obfuscation 23
  • 24. 4 Apr 2013 Page Code Obfuscation • Java Obfuscation • Proguard • C# Obfuscation • Obfuscar • Hides method/variable names • but still very much readable code • False sense of security 24
  • 25. 4 Apr 2013 Page Java Obfuscation (before) 25 private void playVideo() {     doCleanUp();     try     {         mMediaPlayer = new MediaPlayer();         if (mIsURL)         {             mMediaPlayer.setDataSource(mContext, Uri.parse(mFileName));         }         else if (mVideoLength != 0)         {             FileInputStream file = new FileInputStream(mFileName);             mMediaPlayer.setDataSource(file.getFD(), mVideoOffset, mVideoLength);             file.close();         }         else         { (...)
  • 26. 4 Apr 2013 Page Java Obfuscation (after) 26 private void a() {     b();     try     {         this.r = new MediaPlayer();         if (this.h)         {             this.r.setDataSource(this.b, Uri.parse(this.e));         }         else         {             if (this.j != 0L)             {                 Object localObject = new FileInputStream(this.e);                 this.r.setDataSource(((FileInputStream)localObject).getFD(), this.i, this.j);                 ((FileInputStream)localObject).close();             }             else             { (...)
  • 27. 4 Apr 2013 Page Encryption 27
  • 28. 4 Apr 2013 Page Encryption of PlayerPrefs • Why? • Prevent simple cheating • Prevent cracking IAB purchases (if you cache anything locally) • In general good practice for sensitive data (like game progression) • How? • Encrypt key/values before inserting them in the PlayerPrefs • Use a user-specific encryption, so prefs cannot be copied, but still shared in a cloud 28
  • 29. 4 Apr 2013 Page SetString(key, value, secret) 29 // Hide 'key' string string key_string = MD5(key); // Convert 'value' into a byte array byte[] bytes = UTF8Encoding.UTF8.GetBytes(value); // Encrypt 'value' with 3DES('secret') TripleDES des = new TripleDESCryptoServiceProvider(); des.Key = secret; des.Mode = CipherMode.ECB; ICryptoTransform xform = des.CreateEncryptor(); byte[] encrypted = xform.TransformFinalBlock(bytes, 0, bytes.Length); // Convert encrypted array into a "readable" string string encrypted_string = Convert.ToBase64String(encrypted, 0, encrypted.Length); // Set the { key, encrypted value } pair in regular PlayerPrefs PlayerPrefs.SetString(key_string, encrypted_string);
  • 30. 4 Apr 2013 Page value GetString(key, secret) 30 // Hide 'key' string string key_string = MD5(key); // Retrieve encrypted 'value' and Base64 decode it string value = PlayerPrefs.GetString(key_string); byte[] bytes = Convert.FromBase64String(value); // Decrypt 'value' with 3DES('secret') TripleDES des = new TripleDESCryptoServiceProvider(); des.Key = secret; des.Mode = CipherMode.ECB; ICryptoTransform xform = des.CreateDecryptor(); byte[] decrypted = xform.TransformFinalBlock(bytes, 0, bytes.Length); // Return decrypted value as a proper string return UTF8Encoding.UTF8.GetString(decrypted);
  • 31. 4 Apr 2013 Page Encrypted SetString() / GetString() 31 // Generate a secret based on 'username' string username = "Turrican II"; MD5 md5 = new MD5CryptoServiceProvider(); byte[] secret = md5.ComputeHash(UTF8Encoding.UTF8.GetBytes(username)); // Game progress { key, value } pair string key = "unlocked levels"; string value = "the desert rocks,traps,secret dungeons,the wall,the final challenge,the final fight"; // Insert { key, value } pair SetString(key, value, secret); // Retrieve { key, value } string ret = GetString(key, secret); // Output to the logcat Debug.Log("secret = " + username); Debug.Log(key + " = " + ret);
  • 32. 4 Apr 2013 Page Encryption of Scripts • Why? • Scripts are generally insecure • Gameplay could be altered • Security checks could be disabled • Code needs to be “hidden” for some reason (i.e. IAB logic) 32
  • 33. 4 Apr 2013 Page Encryption of Scripts • How? • Compile scripts outside Unity • Run a symmetric / asymmetric encryption on the Script.dll • Choose a delivery mechanism • Embed in the application, or • Download it from a trusted server • Decrypt the Script.dll in memory • Load it through Assembly.Load(byte[]) 33
  • 34. 4 Apr 2013 Page Compile scripts outside Unity • Download Mono (www.mono-project.com) • Compile the script (Plugin.cs) with ‘gmcs’ • Reference the UnityEngine.dll assembly to access to Unity 34 $ gmcs -target:library -out:Script.dll -r:AndroidPlayer/Managed/UnityEngine.dll Plugin.cs
  • 35. 4 Apr 2013 Page Encrypt the assembly • Using OpenSSL • Converted to ‘text’ using Base64 encoding • Result can be embedded in Unity as a TextAsset 35 $ openssl rc2 -nosalt -p -in Script.dll -out Encrypted.bin key=... iv =... $ base64 Encrypted.bin > ~/UnityProject/Assets/Encrypted.txt
  • 36. 4 Apr 2013 Page Plugin.cs 36 using UnityEngine; public class SomeImportantGameClass {     static SomeImportantGameClass()     {         const int GET_SIGNATURES = 64;         AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer") .GetStatic<AndroidJavaObject>("currentActivity");         AndroidJavaObject manager = activity.Call<AndroidJavaObject>("getPackageManager");         string packageName = activity.Call<string>("getPackageName");         AndroidJavaObject packageInfo =                 manager.Call<AndroidJavaObject>("getPackageInfo", packageName, GET_SIGNATURES);         AndroidJavaObject[] signatures = packageInfo.Get<AndroidJavaObject[]>("signatures");         foreach (AndroidJavaObject signature in signatures)         {             Debug.Log("signature hash = " + signature.Call<int>("hashCode").ToString("X"));         }     } (...) }
  • 37. 4 Apr 2013 Page Decrypt and run assembly 37 public TextAsset assembly; void Start () {     // Load encrypted data and decryption keys     byte[] bytes = Convert.FromBase64String(assembly.text);     byte[] key = new byte[] { <key from encryption step> };     byte[] iv = new byte[] { <iv from encryption step> };     // Decrypt assembly     RC2 rc2 = new RC2CryptoServiceProvider();     rc2.Mode = CipherMode.CBC;     ICryptoTransform xform = rc2.CreateDecryptor(key, iv);     byte[] decrypted = xform.TransformFinalBlock(bytes, 0, bytes.Length);     // Load assembly and instantiate 'SomeImportantGameClass' to trigger static constructor     Assembly asm = Assembly.Load(decrypted);     Type SomeClass = asm.GetType("SomeImportantGameClass");     SomeClass.GetConstructor(Type.EmptyTypes).Invoke(null); }
  • 38. 4 Apr 2013 Page Encryption of Assets • Why? • Some assets might need to be protected from tampering. • “Assets” doesn’t necessarily mean just “textures”; could be • Game logic • Dalvik bytecode • Script code • Native code • .. “anything” 38
  • 39. 4 Apr 2013 Page Encryption of Assets • How? • Create an AssetBundle from the “secret” assets. • Run a symmetric / asymmetric encryption on the AssetBundle.unity3d • Choose a delivery mechanism • Embed in the application, or • Download it from a trusted server • Decrypt the AssetBundle.unity3d in memory • Load it through AssetBundle.CreateFromMemory(Byte[]) 39
  • 40. 4 Apr 2013 Page Conclusion • Be imaginative • APK integrity checks are so simple everyone should have them. • Sensitive code must be protected • Combine the different approaches, and create new ones • Finally: Don’t spend too much time on this • Instead update the logic for each new release. 40
  • 41. 4 Apr 2013 Page Questions? 41
  • 42. 4 Apr 2013 Page Thanks! 42 Twitter: @_eriq_