SlideShare a Scribd company logo
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_

More Related Content

What's hot

스타트업 사례로 본 로그 데이터 분석 : Tajo on AWS
스타트업 사례로 본 로그 데이터 분석 : Tajo on AWS스타트업 사례로 본 로그 데이터 분석 : Tajo on AWS
스타트업 사례로 본 로그 데이터 분석 : Tajo on AWS
Matthew (정재화)
 
Non relational databases-no sql
Non relational databases-no sqlNon relational databases-no sql
Non relational databases-no sql
Ram kumar
 
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
Hyojun Jeon
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDB
Ravi Teja
 
Introduction to Data Modeling with Apache Cassandra
Introduction to Data Modeling with Apache CassandraIntroduction to Data Modeling with Apache Cassandra
Introduction to Data Modeling with Apache Cassandra
DataStax Academy
 
Introduction to Amazon DynamoDB
Introduction to Amazon DynamoDBIntroduction to Amazon DynamoDB
Introduction to Amazon DynamoDB
Amazon Web Services
 
https://docs.google.com/presentation/d/1DcL4zK6i3HZRDD4xTGX1VpSOwyu2xBeWLT6a_...
https://docs.google.com/presentation/d/1DcL4zK6i3HZRDD4xTGX1VpSOwyu2xBeWLT6a_...https://docs.google.com/presentation/d/1DcL4zK6i3HZRDD4xTGX1VpSOwyu2xBeWLT6a_...
https://docs.google.com/presentation/d/1DcL4zK6i3HZRDD4xTGX1VpSOwyu2xBeWLT6a_...
MongoDB
 
Little Big Data #1. 바닥부터 시작하는 데이터 인프라
Little Big Data #1. 바닥부터 시작하는 데이터 인프라Little Big Data #1. 바닥부터 시작하는 데이터 인프라
Little Big Data #1. 바닥부터 시작하는 데이터 인프라
Seongyun Byeon
 
게임서버프로그래밍 #8 - 성능 평가
게임서버프로그래밍 #8 - 성능 평가게임서버프로그래밍 #8 - 성능 평가
게임서버프로그래밍 #8 - 성능 평가
Seungmo Koo
 
Extreme JavaScript Performance
Extreme JavaScript PerformanceExtreme JavaScript Performance
Extreme JavaScript Performance
Thomas Fuchs
 
In the DOM, no one will hear you scream
In the DOM, no one will hear you screamIn the DOM, no one will hear you scream
In the DOM, no one will hear you scream
Mario Heiderich
 
C++17 std::byte
C++17 std::byteC++17 std::byte
C++17 std::byte
진화 손
 
게임 서비스 품질 향상을 위한 데이터 분석 활용하기 - 김필중 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming
게임 서비스 품질 향상을 위한 데이터 분석 활용하기 - 김필중 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming게임 서비스 품질 향상을 위한 데이터 분석 활용하기 - 김필중 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming
게임 서비스 품질 향상을 위한 데이터 분석 활용하기 - 김필중 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming
Amazon Web Services Korea
 
MongoDB presentation
MongoDB presentationMongoDB presentation
MongoDB presentation
Hyphen Call
 
Redis
RedisRedis
Building a World in the Clouds: MMO Architecture on AWS (MBL304) | AWS re:Inv...
Building a World in the Clouds: MMO Architecture on AWS (MBL304) | AWS re:Inv...Building a World in the Clouds: MMO Architecture on AWS (MBL304) | AWS re:Inv...
Building a World in the Clouds: MMO Architecture on AWS (MBL304) | AWS re:Inv...
Amazon Web Services
 
게임 분산 서버 구조
게임 분산 서버 구조게임 분산 서버 구조
게임 분산 서버 구조
Hyunjik Bae
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDB
MongoDB
 
글쓰는 개발자 모임, 글또
글쓰는 개발자 모임, 글또글쓰는 개발자 모임, 글또
글쓰는 개발자 모임, 글또
Seongyun Byeon
 
Building fast,scalable game server in node.js
Building fast,scalable game server in node.jsBuilding fast,scalable game server in node.js
Building fast,scalable game server in node.js
Xie ChengChao
 

What's hot (20)

스타트업 사례로 본 로그 데이터 분석 : Tajo on AWS
스타트업 사례로 본 로그 데이터 분석 : Tajo on AWS스타트업 사례로 본 로그 데이터 분석 : Tajo on AWS
스타트업 사례로 본 로그 데이터 분석 : Tajo on AWS
 
Non relational databases-no sql
Non relational databases-no sqlNon relational databases-no sql
Non relational databases-no sql
 
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDB
 
Introduction to Data Modeling with Apache Cassandra
Introduction to Data Modeling with Apache CassandraIntroduction to Data Modeling with Apache Cassandra
Introduction to Data Modeling with Apache Cassandra
 
Introduction to Amazon DynamoDB
Introduction to Amazon DynamoDBIntroduction to Amazon DynamoDB
Introduction to Amazon DynamoDB
 
https://docs.google.com/presentation/d/1DcL4zK6i3HZRDD4xTGX1VpSOwyu2xBeWLT6a_...
https://docs.google.com/presentation/d/1DcL4zK6i3HZRDD4xTGX1VpSOwyu2xBeWLT6a_...https://docs.google.com/presentation/d/1DcL4zK6i3HZRDD4xTGX1VpSOwyu2xBeWLT6a_...
https://docs.google.com/presentation/d/1DcL4zK6i3HZRDD4xTGX1VpSOwyu2xBeWLT6a_...
 
Little Big Data #1. 바닥부터 시작하는 데이터 인프라
Little Big Data #1. 바닥부터 시작하는 데이터 인프라Little Big Data #1. 바닥부터 시작하는 데이터 인프라
Little Big Data #1. 바닥부터 시작하는 데이터 인프라
 
게임서버프로그래밍 #8 - 성능 평가
게임서버프로그래밍 #8 - 성능 평가게임서버프로그래밍 #8 - 성능 평가
게임서버프로그래밍 #8 - 성능 평가
 
Extreme JavaScript Performance
Extreme JavaScript PerformanceExtreme JavaScript Performance
Extreme JavaScript Performance
 
In the DOM, no one will hear you scream
In the DOM, no one will hear you screamIn the DOM, no one will hear you scream
In the DOM, no one will hear you scream
 
C++17 std::byte
C++17 std::byteC++17 std::byte
C++17 std::byte
 
게임 서비스 품질 향상을 위한 데이터 분석 활용하기 - 김필중 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming
게임 서비스 품질 향상을 위한 데이터 분석 활용하기 - 김필중 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming게임 서비스 품질 향상을 위한 데이터 분석 활용하기 - 김필중 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming
게임 서비스 품질 향상을 위한 데이터 분석 활용하기 - 김필중 솔루션즈 아키텍트:: AWS Cloud Track 3 Gaming
 
MongoDB presentation
MongoDB presentationMongoDB presentation
MongoDB presentation
 
Redis
RedisRedis
Redis
 
Building a World in the Clouds: MMO Architecture on AWS (MBL304) | AWS re:Inv...
Building a World in the Clouds: MMO Architecture on AWS (MBL304) | AWS re:Inv...Building a World in the Clouds: MMO Architecture on AWS (MBL304) | AWS re:Inv...
Building a World in the Clouds: MMO Architecture on AWS (MBL304) | AWS re:Inv...
 
게임 분산 서버 구조
게임 분산 서버 구조게임 분산 서버 구조
게임 분산 서버 구조
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDB
 
글쓰는 개발자 모임, 글또
글쓰는 개발자 모임, 글또글쓰는 개발자 모임, 글또
글쓰는 개발자 모임, 글또
 
Building fast,scalable game server in node.js
Building fast,scalable game server in node.jsBuilding fast,scalable game server in node.js
Building fast,scalable game server in node.js
 

Similar to [UniteKorea2013] Protecting your Android content

OWASP ZAP Workshop for QA Testers
OWASP ZAP Workshop for QA TestersOWASP ZAP Workshop for QA Testers
OWASP ZAP Workshop for QA Testers
Javan Rasokat
 
Attacking and Defending Mobile Applications
Attacking and Defending Mobile ApplicationsAttacking and Defending Mobile Applications
Attacking and Defending Mobile Applications
Jerod Brennen
 
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
ForgeRock
 
Android application analyzer
Android application analyzerAndroid application analyzer
Android application analyzer
Sanjay Gondaliya
 
Fastlane
FastlaneFastlane
Fastlane
Warren Lin
 
Android Scripting
Android ScriptingAndroid Scripting
Android Scripting
Juan Gomez
 
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
Kevin Hakanson
 
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
Synopsys Software Integrity Group
 
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
Michael Galpin
 
Mitigating data theft_in_android
Mitigating data theft_in_androidMitigating data theft_in_android
Mitigating data theft_in_android
Rashmi Bhandari
 
Automated malware analysis
Automated malware analysisAutomated malware analysis
Automated malware analysis
Ibrahim Baliç
 
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...
tdc-globalcode
 
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...
Márcio Rosa
 
Overview of DroidCon UK 2015
Overview of DroidCon UK 2015 Overview of DroidCon UK 2015
Overview of DroidCon UK 2015
Elif Boncuk
 
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
Abraham Aranguren
 
Hacking your Droid (Aditya Gupta)
Hacking your Droid (Aditya Gupta)Hacking your Droid (Aditya Gupta)
Hacking your Droid (Aditya Gupta)
ClubHack
 
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
 
Rapid Android Application Security Testing
Rapid Android Application Security TestingRapid Android Application Security Testing
Rapid Android Application Security Testing
Nutan Kumar Panda
 
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
Nitesh Malviya
 
Android pentesting the hackers-meetup
Android pentesting the hackers-meetupAndroid pentesting the hackers-meetup
Android pentesting the hackers-meetup
kunwaratul hax0r
 

Similar to [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
 

More from William Hugo Yang

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

More from 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
 

Recently uploaded

“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
Edge AI and Vision Alliance
 
Trusted Execution Environment for Decentralized Process Mining
Trusted Execution Environment for Decentralized Process MiningTrusted Execution Environment for Decentralized Process Mining
Trusted Execution Environment for Decentralized Process Mining
LucaBarbaro3
 
Skybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoptionSkybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoption
Tatiana Kojar
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
Ivanti
 
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-EfficiencyFreshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
ScyllaDB
 
Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |
AstuteBusiness
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
panagenda
 
FREE A4 Cyber Security Awareness Posters-Social Engineering part 3
FREE A4 Cyber Security Awareness  Posters-Social Engineering part 3FREE A4 Cyber Security Awareness  Posters-Social Engineering part 3
FREE A4 Cyber Security Awareness Posters-Social Engineering part 3
Data Hops
 
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
alexjohnson7307
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
akankshawande
 
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Tatiana Kojar
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
Zilliz
 
Public CyberSecurity Awareness Presentation 2024.pptx
Public CyberSecurity Awareness Presentation 2024.pptxPublic CyberSecurity Awareness Presentation 2024.pptx
Public CyberSecurity Awareness Presentation 2024.pptx
marufrahmanstratejm
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
Brandon Minnick, MBA
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
panagenda
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Jeffrey Haguewood
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
Jason Packer
 
dbms calicut university B. sc Cs 4th sem.pdf
dbms  calicut university B. sc Cs 4th sem.pdfdbms  calicut university B. sc Cs 4th sem.pdf
dbms calicut university B. sc Cs 4th sem.pdf
Shinana2
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
ssuserfac0301
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
Zilliz
 

Recently uploaded (20)

“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
 
Trusted Execution Environment for Decentralized Process Mining
Trusted Execution Environment for Decentralized Process MiningTrusted Execution Environment for Decentralized Process Mining
Trusted Execution Environment for Decentralized Process Mining
 
Skybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoptionSkybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoption
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
 
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-EfficiencyFreshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
 
Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
 
FREE A4 Cyber Security Awareness Posters-Social Engineering part 3
FREE A4 Cyber Security Awareness  Posters-Social Engineering part 3FREE A4 Cyber Security Awareness  Posters-Social Engineering part 3
FREE A4 Cyber Security Awareness Posters-Social Engineering part 3
 
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
 
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
 
Public CyberSecurity Awareness Presentation 2024.pptx
Public CyberSecurity Awareness Presentation 2024.pptxPublic CyberSecurity Awareness Presentation 2024.pptx
Public CyberSecurity Awareness Presentation 2024.pptx
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
 
dbms calicut university B. sc Cs 4th sem.pdf
dbms  calicut university B. sc Cs 4th sem.pdfdbms  calicut university B. sc Cs 4th sem.pdf
dbms calicut university B. sc Cs 4th sem.pdf
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
 

[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_