Obfuscation and Hardening tool for Android Apps Raman Goyal

advertisement
Obfuscation and Hardening
tool for Android Apps
Instrumenting Android apps for runtime/dynamic analysis.
Raman Goyal
B.Tech - IT (Undergraduate)
IIIT Allahabad, India
Contents
 Emulator Detection
 JDB Debugging of Android Apps.
 JDB Detection
 GDB Debugging of Android Apps.
 Future Tasks.
Emulator Detection
 Apps can detect if they are running on real device or emulator.
 How they do it?
 There is numerous amount of information present with the emulator like
build values, pre-saved numbers (voicemail, line-number), essential files etc.
and accessing that information can tell if it is real device or an emulator.
 Evading Emulators / Android Runtime analysis is possible with this
information.
Motive of Evasion?
 Games detect emulators to prevent cheating/abuse
Must uniquely identify devices to prevent easy cheating.
Attempt to stop cheats.
 App developers want to protect secrets.
 Security researchers want to break stuff, get famous.
 Malware authors want to avoid detection of their products.
Instrumenting android apps for
Detecting Emulator.
 How to detect emulator?
1. Detecting emulation through the Android API.
2. Detecting Emulator by CPU performance.
3. Detecting Emulator by software components.
4. Detecting Emulator by its content.
5. Detecting Emulator by Plumbing.
 Other techniques such as checking for networking, graphics etc. can be
used too.
Detecting emulator by android API
 Easiest method to detect emulator.
 Check for Telephony Manager or BUILD constants.
 Values such as device id, line number, voice mail number remains same for
all emulators and in that way we can detect emulator.
 Similarly checking Build values such as brand, device etc. can help to
detect the emulator.
Listing of API methods that can be
used for Emulator Detection
Build.HOST values for various devices.
Keep in Mind.
 Make sure app already has permission to Read the phone state otherwise
we shouldn’t check telephony manager values.
 Why?
 Because we are instrumenting the app for good and not for adding
permissions to do something different.
 One can still check for BUILD values as it doesn’t require special permissions.
 For TelephonyManager we need to access to context of the app for that
content provider is needed.
 Why content provider?
 Because whenever an app is launched it is the first thing that gets started.
How to add Content Provider?
 We need to modify the manifest of the original app and add our content
provider to it.
 How to modify manifest?
 Use Library – Soot Inflow Android (thanks to Steven!)
 Again check for the permissions you have in the manifest and don’t modify
or add any permission.
 Once we have modified the manifest, when the app will be launched the
content provider will start and TelephonyManager can access context.
Detecting Emulator by CPU performance.
 PC, Mobile, Super Computer, Emulator each of them takes different time
for a particular task.
 Because of difference in resources they have such as memory, space etc.
 How to detect emulator with this?
 Run complex calculations on PC, Real mobile device, emulator and
benchmark the results.
 Instrumenting that calculation in the app and then running the app can
decide if the device is PC, mobile device or emulator.
 What kind of calculations are we talking about?
Complex Calculations
 One can think of calculating say first 1000000 digits of Pi after decimal,
using the method described by Ooura.
 Or one can do simple complex calculation such as calculating factorial of
numbers up to 30000.
 Wondering why 30000?
 Because to get a significant difference in calculation time or in other words,
to be ‘completely’ sure whether it is a real device or Emulator.
 Please make sure you don’t crash the app if the calculation is so large it
may crash the app.
 Also make sure that the time is not too much, no one will wait more than 1
minute to find out if it is emulator.
Factorial Results
 After running 12 rounds for factorial of numbers up to 30000 and averaging
them following results were obtained.
 PC takes only 165ms for this.
 A real android device will take less than 25000ms for this computation.
 Emulator (Kitkat) is taking average time of 44089ms for the same
computation.
 So, if device is taking more than 25000ms then it is likely an emulator.
Detecting Emulator by software
Components
 Is the device always “charging”?
 But is it always at 50%?
 Never roaming?
 Always at emulator defaults?
 Example: If battery percentage is exactly 50% or the level is exactly 0 and
the scale is exactly 100, the device in question is likely an emulator.
Detecting Emulator by its content
 Content is the key
 Do people who have downloaded INFECTED subway surfers have no data?
 Do they normally send NO Sms?
 Answer to all of these questions is No. Yes, there must be some contact list,
some conversation list present in the device.
 Does this check guarantee that concerned device is Emulator?
 No, because the real device may be new, factory restored or something.
But this check gives a possibility if the device is Emulator.
Detecting Emulator by its content
 People may not smartphones as the phone much.
 But is it expected that they have never made a call ever?
Detecting Emulator by Plumbing.
 There are certain QEMU files present in the emulator.
 Qemu wasn’t made for hiding.
 “Pipes” talk to the host environment.
 Easily found pipes;
/dev/qemu_pipe
/dev/socket/qemud
 Simple file check can suffice.
 Hiding these pipes is non trivial.
 Hardcoded / used plenty across codebase.
Detecting Emulator by Plumbing.
 Used in many files, most of which stand out themselves;
/system/lib/lib_malloc_debug_qemu.so
/sys/qemu_trace
/system/bin/qemu-props
Will these methods work for sure?
 One can change values of TelephonyManager and BUILD, to hide
emulator. Droid bench have even modified certain values.
 But is it possible to hide each and every thing?
 No. We can detect emulator using certain techniques.
 So, just check with all of the above methods, and if there is positive
response the device is an emulator.
 The hardest to play with is computation time, as you need to provide more
and more resources to emulator for that.
JDB Debugging of Android Apps
 Debugging an app can be a security thread, if app is not being debugged
by the developer itself.
 How to debug an android app using Java Debugger?
 If you are using any IDE for development one can simply debug the app
using that if you are having a real device and starting it in debug mode.
 But doing it via command line is tedious task.
 How to debug using command line?
 Note that we don’t need to add android:debuggable=“true” in the
manifest because the debug tools automatically add this line in the
manifest if you are using new sdk.
(http://developer.android.com/tools/sdk/tools-notes.html)
JDB Debugging of Android Apps
 Install the application you want to debug either through eclipse, or using
adb install command.
 Start the application in debug mode using following command.
adb shell am start -e debug true -a android.intent.action.MAIN –c
android.intent.category.LAUNCHER -n packagename/classname
Ex: adb shell am start -e debug true -a android.intent.action.MAIN –c
android.intent.category.LAUNCHER -n
de.ecspride/de.ecspride.InstrumentationExample
 Now check for debug port of the application (app Pid), using
adb jdwp
JDB Debugging of Android Apps
 The last port number that appears is of the application or, use
adb jdwp | tail -1
 Now forward the tcp port to the application.
adb –d forward tcp:12546 jdwp:app_debug_port
 At last, attach the JDB
jdb -attach localhost:12546 -sourcepath $SOURCE_PATH
(This last part attaching the JDB is giving error- Failed to find Java VM)
Can we do it with Eclipse?
 Open Debug dialog
 Create a “Remote Java Application” configuration
 Set source path
 Connection type: Socket attach
 Set host to localhost
 Set port to your specified forward port (example: 12546)
 Save debug configuration.
 Create breakpoints.
 Compile project and install apk to device.
 Open Eclipse debug perspective.
 Go to the device shell, and start activity using ActivityManager(am) with “-e debug true”
parameter. (use above script but comment out the jdb)
 Start your debug configuration in Eclipse. (Eclipse will establish a connection to the port
specified 12546).
JDB Detection
 Just like we detected emulator, can we detect JDB?
 Yes, it is easy.
 Just check for the following condition
 java.lang.management.ManagementFactory.getRuntimeMXBean().getInp
utArguments().toString().indexOf("jdwp") >= 0
 If the Java debug wire protocol’s index >= 0, then jdb is being used.
 Although it is not easy to play with jdwp and change it’s index but I think it is
possible to do so. I haven’t found any resources or anything related to jdwp
hack by now.
GDB debugging of Android Apps
 GDB is used of native codes, but can it be used for Android.
 Yes, it can be but it is not that easy. Have to play with JNI.
 For GDB debugging of android apps, native development kit has to be
used.
 In Eclipse, after creating a simple android application, we just need to add
native feature to it.
 Which will add the java native interface to it
 A new c/c++ file will be created in libs/armeabi.
 Now using eclipse it can be easily debugged as native application using
GDB.
Future Tasks
 Detection of GDB if android app is being debugged through it.
 New techniques for detecting emulator.
 Detecting if an app gets analyzed by Taintdroid.
It was so good working here.
Thank You!
Download