Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Securing iOS applications

Max Bazaliy
February 06, 2015

Securing iOS applications

Mobile Central Europe, 2015

Max Bazaliy

February 06, 2015
Tweet

More Decks by Max Bazaliy

Other Decks in Programming

Transcript

  1. February 6, 2015 Mobile Central Europe 1 2 3 4

    5 6 7 8 9 10 11 12 Securing iOS apps Max Bazaliy
  2. February 6, 2015 Mobile Central Europe About me 1 2

    3 4 5 6 7 8 9 10 11 12 Bluebox Security CocoaHeads Ukraine mbazaliy
  3. February 6, 2015 Mobile Central Europe Agenda 1 2 3

    4 5 6 7 8 9 10 11 12 o  iOS security mechanisms o  Security from attacker’s perspective o  Reverse engineering tools detection o  Security coding practices o  Advanced practices
  4. February 6, 2015 Mobile Central Europe o  Secured boot process

    o  Privilege separation o  Code signing o  Memory protection o  Sandbox o  Encryption 1 2 3 4 5 6 7 8 9 10 11 12 iOS security mechanisms
  5. February 6, 2015 Mobile Central Europe 1 2 3 4

    5 6 7 8 9 10 11 12 Secured boot process Bootrom LLB iBoot Kernel Application Signature check
  6. February 6, 2015 Mobile Central Europe Privilege separation 1 2

    3 4 5 6 7 8 9 10 11 12 o  Users (root, mobile, …) o  Groups o  File permissions o  Safari, Mail run as mobile o  Most important system processes as root
  7. February 6, 2015 Mobile Central Europe Code signing 1 2

    3 4 5 6 7 8 9 10 11 12 o  Implemented in kernel o  Every executable should be signed o  Stored in LC_CODE_SIGNATURE o  Superblob, entitlements, signature o  SHA1 check of memory pages o  Superblob is signed
  8. February 6, 2015 Mobile Central Europe Memory protection 1 2

    3 4 5 6 7 8 9 10 11 12 o  R ^ W policy o  Non executable stack and heap o  Implemented in kernel o  Vulnerable to ROP o  (K)ASLR o  No dynamic code generation
  9. February 6, 2015 Mobile Central Europe Sandbox (Seatbelt) 1 2

    3 4 5 6 7 8 9 10 11 12 o  Based upon TrustedBSD MAC framework o  Implemented in kernel o  Profiles (nointernet, container…) o  Operations (read, write, search…) o  System & user partition
  10. February 6, 2015 Mobile Central Europe Encryption 1 2 3

    4 5 6 7 8 9 10 11 12 o  Hardware AES and SHA modules o  7 derivative keys from UID and GID o  Everything is encrypted (iBoot, filesystem, …) o  Data protection API o  Passcode \ TouchID key o  Remote device wiping
  11. February 6, 2015 Mobile Central Europe o  Code injection o 

    Function hooking o  ObjC logger o  Jailbreak detection o  Security checks 1 2 3 4 5 6 7 8 9 10 11 12 Security from attacker’s perspective
  12. February 6, 2015 Mobile Central Europe Code injection 1 2

    3 4 5 6 7 8 9 10 11 12 o  .dylib injection o  DYLD_INSERT_LIBRARIES o  LLDB o  Cycript o  LD_LOAD_DYLIB o  Mobile Substrate
  13. February 6, 2015 Mobile Central Europe 13 14 15 16

    17 18 19 20 21 22 23 24 DYLD_INSERT_LIBRARIES=dumper.dylib Scan.app/Scan Dynamic loader
  14. February 6, 2015 Mobile Central Europe 13 14 15 16

    17 18 19 20 21 22 23 24 LLDB Max-iPhone-5S:~ root# ./debugserver *:1234 -a ”Scan” $ lldb (lldb) platform select remote-ios (lldb) process connect connect://192.168.1.2:1234 (lldb) expr (void*)dlopen(“/Desktop/dumper.dylib”, 0x2)
  15. February 6, 2015 Mobile Central Europe 13 14 15 16

    17 18 19 20 21 22 23 24 Cycript $ cycript -p Scan cy# dlopen(”/Desktop/dumper.dylib", RTLD_NOW)
  16. February 6, 2015 Mobile Central Europe 13 14 15 16

    17 18 19 20 21 22 23 24 New load command cmd LC_LOAD_DYLIB cmdsize 52 name @rpath/dumper.dylib time stamp 2 Thu Jan 1 03:00:02 1970 cur.ver. 1.0.0 compat.ver 1.0.0 otool -l –v binary | grep -A 5 LC_LOAD_DYLIB
  17. February 6, 2015 Mobile Central Europe 13 14 15 16

    17 18 19 20 21 22 23 24 New load command LC_LOAD_DYLIB or LC_LOAD_WEAK_DYLIB o  Wrap LC_LOAD, update sizeof commands o  optool o  insert_dylib o  yololib
  18. February 6, 2015 Mobile Central Europe 13 14 15 16

    17 18 19 20 21 22 23 24 Mobile Substrate o  Most popular code patching framework o  Hook C, C++, Objective C, Java code o  Trampoline for C hooks o  Swizzling for Objective C o  Dynamic code injection o  Filter support
  19. February 6, 2015 Mobile Central Europe 13 14 15 16

    17 18 19 20 21 22 23 24 Mobile Substrate hook API + Logos MSImageRef MSGetImageByName(const char *file) void *MSFindSymbol(MSImageRef image, const char *name) void MSHookFunction(void *symbol, void *hook, void **old) void MSHookMessageEx(Class _class, SEL message, IMP hook, IMP *old) void MSHookClassPair(Class _class, Class hook, Class old)
  20. February 6, 2015 Mobile Central Europe 13 14 15 16

    17 18 19 20 21 22 23 24 Mobile Substrate Loader Filter = { Executables = ("mediaserverd"); Bundles = ( "com.apple.MobileSMS", "net.whatsapp.WhatsApp" ); CoreFoundationVersion = (550.32, 675.00); Classes = ("MMTrackingMgr"); Mode = "Any"; }; Load everything from /Library/MobileSubstrate/DynamicLibraries
  21. February 6, 2015 Mobile Central Europe 13 14 15 16

    17 18 19 20 21 22 23 24 Function hooking main qsort No hooking
  22. February 6, 2015 Mobile Central Europe 13 14 15 16

    17 18 19 20 21 22 23 24 Function hooking main qsort Hooking scenario hook
  23. February 6, 2015 Mobile Central Europe 13 14 15 16

    17 18 19 20 21 22 23 24 Function hooking main qsort Hooking scenario 2 hook
  24. February 6, 2015 Mobile Central Europe 13 14 15 16

    17 18 19 20 21 22 23 24 Hooking [NSObject description] NSString *(*oldDescription)(id self, SEL _cmd);! ! NSString *newDescription(id self, SEL _cmd) {! NSString *description = (*oldDescription)(self, _cmd);! description = [description stringByAppendingString:@"!"];! return description;! }! ! MSHookMessageEx(! " [NSObject class], @selector(description),! " (IMP)&newDescription, (IMP*)&oldDescription! );
  25. February 6, 2015 Mobile Central Europe 25 26 27 28

    29 30 31 32 33 34 35 36 objc_msgSend[_[st|fp]ret] logging - [Pin password] +[PBKDF2 getKeyForPassphrase:], args:<NSCFString: secretPassword> - [Pin initWithCoder:], args: <0x1f5a4320> - [Pin setPinValue:], args: <NSCFString: 4711> - [Pin setNote:], args: <NSCFString: Sample PIN Note> - [Pin initWithCoder:], args: <0x1f5a4320> - [Pin setPinValue:], args: <NSCFString: 1337> - [Pin setNote:], args: <NULL> Aspective-C, Subjective-C, Inspective-C
  26. February 6, 2015 Mobile Central Europe 25 26 27 28

    29 30 31 32 33 34 35 36 Bypassing shell check + (BOOL)shellCheck {! if (system(0))! return YES;! return NO;! } static int (*old_system)(char *) = NULL;! int hooked_system(char * cmd) {! if (!cmd) {! return 0;! }! return old_system(cmd);! }! MSHookFunction(system, hooked_system, &old_system);!
  27. February 6, 2015 Mobile Central Europe 25 26 27 28

    29 30 31 32 33 34 35 36 Bypassing files check + (BOOL)cydiaCheck {! if ([[NSFileManager defaultManager] ! "fileExistsAtPath: @"/Applications/Cydia.app"])! return YES;! return NO;! } void* (*old_fileExistsAtPath)(void* self, SEL _cmd, NSString* path) = NULL;! void* hooked_fileExistsAtPath(void* self, SEL _cmd, NSString* path){! if ([path isEqualToString:@"/Applications/Cydia.app"]) {! return 0;! }! return old_fileExistsAtPath(self, _cmd, path);! }! MSHookMessageEx([NSFileManager class], @selector(fileExistsAtPath:),! (IMP)hooked_fileExistsAtPath, (IMP *)&old_fileExistsAtPath);! !
  28. February 6, 2015 Mobile Central Europe 25 26 27 28

    29 30 31 32 33 34 35 36 Bypassing fork check + (BOOL)forkCheck {! pid_t result = fork();! if (!result)! exit(0);! if (result >= 0)! return YES;! return NO; } static pid_t (*old_fork)(void) = NULL;! pid_t hooked_fork() {! if (calledDirectlyFromApp()) {! return -1;! }! return old_fork();! }! MSHookFunction(fork, hooked_fork, &old_fork);!
  29. February 6, 2015 Mobile Central Europe 25 26 27 28

    29 30 31 32 33 34 35 36 const char* hook_dyld_get_image_name(uint32_t image_index) {! if (image_index >= dyld_skipimage)! return orig_get_image_name(image_index + 1);! else! return orig_get_image_name(image_index);! }! ! MSHookFunction(_dyld_image_count,hooked_image_count,&orig_image_count)! MSHookFunction(_dyld_get_image_name,hooked_get_image_name,&orig_get_image_name) uint32_t dyld_skipimage = 0;! ! uint32_t hooked_dyld_image_count(void) {! return orig_image_count() - 1;! }! “Calling functions like _dyld_image_count() and _dyld_get_image_name() to see which dylibs are currently loaded. Very difficult to patch, as patches are themselves part of dylibs.” – theiphonewiki.com
  30. February 6, 2015 Mobile Central Europe 25 26 27 28

    29 30 31 32 33 34 35 36 Bypassing ptrace tricks static int (*orig_ptrace)(int request, pid_t pid, caddr_t addr, int data);! ! int hooked_ptrace(int request, pid_t pid, caddr_t addr, int data) {! int retVal;! if (request == PT_DENY_ATTACH || request == PT_TRACEME) {! return 0;! }! else {! retVal = orig_ptrace(request, pid, addr, data);! }! return retVal;! }! MSHookFunction(MSFindSymbol(0, "ptrace"),hooked_ptrace,(void **)&orig_ptrace);! ptrace(PT_DENY_ATTACH, 0, 0, 0);
  31. February 6, 2015 Mobile Central Europe 25 26 27 28

    29 30 31 32 33 34 35 36 Bypassing SSL pinning - SSLKillSwitch OSStatus hooked_SSLHandshake(SSLContextRef context) {! OSStatus result = orig_SSLHandshake(context);! ! if (result == errSSLServerAuthCompleted) {! return orig_SSLHandshake(context);! }! else return result; }! … MSHookFunction(SSLHandshake,hooked_SSLHandshake, &orig_SSLHandshake) ! MSHookFunction(SSLCreateContext,hooked_SSLCreateContext,&orig_SSLCreateContext)! MSHookFunction(SSLSetSessionOption,hooked_SSLSetSessionOption,! " " " " " "&orig_SSLSetSessionOption)! SSLHandshake, SSLSetSessionOption, SSLCreateContext!
  32. February 6, 2015 Mobile Central Europe 25 26 27 28

    29 30 31 32 33 34 35 36 Auto bypassing jailbreak checks o tsProtector X o xCon o Officer
  33. February 6, 2015 Mobile Central Europe 25 26 27 28

    29 30 31 32 33 34 35 36 Tracing tweaks Introspy, Snoop-It, iSpy
  34. February 6, 2015 Mobile Central Europe o  Debugger detection o 

    Hooks detection o  Code injection detection 25 26 27 28 29 30 31 32 33 34 35 36 Reverse engineering tools detection
  35. February 6, 2015 Mobile Central Europe 25 26 27 28

    29 30 31 32 33 34 35 36 Debugger detection – process flags static int is_debugger_present(void) {! ! struct kinfo_proc info;! size_t info_size = sizeof(info);! ! name[0] = CTL_KERN;! " …! name[3] = getpid(); " " " " // Getting proccess pid! ! if (sysctl(name, 4, &info, &info_size, NULL, 0) == -1) {! return 0;! }! return ((info.kp_proc.p_flag & P_TRACED) != 0); "// Checking P_TRACED flag! }!
  36. February 6, 2015 Mobile Central Europe 25 26 27 28

    29 30 31 32 33 34 35 36 Debugger detection – parent process static int is_debugserver_present(void) {! ! struct kinfo_proc info;! size_t info_size = sizeof(info);! ! name[0] = CTL_KERN;! " …! name[3] = getppid(); " " "// Getting parent proccess pid! ! if (sysctl(name, 4, &info, &info_size, NULL, 0) == -1) {! return 0;! }! return (strncmp(info.kp_proc.p_comm, "launchd", sizeof("launchd")-1) != 0);! }!
  37. February 6, 2015 Mobile Central Europe 37 38 39 40

    41 42 43 44 45 46 47 48 Breakpoint detection bool is_breakpoint_set(void* memory, size_t check_size) {! unsigned char *tmp_mem = (unsigned char*)memory;! for (size_t i = 0; i < check_size; i++)! {! if ((tmp_mem[i] == 0xFE) && (tmp_mem[i+1] == 0xDE))! return true;! }! return false;! }!
  38. February 6, 2015 Mobile Central Europe 37 38 39 40

    41 42 43 44 45 46 47 48 Hook detection - pointer bool is_method_swizzled(Class clazz, SEL sel) {! ! Dl_info info;! if (dladdr(class_getMethodImplementation(clazz, sel), &info)) {! if (strstr(info.dli_fname, "/System/Library") || ! " " " "strstr(info.dli_fname, "/usr/lib”) {! return false;! }! }! return true;! }!
  39. February 6, 2015 Mobile Central Europe 37 38 39 40

    41 42 43 44 45 46 47 48 Hook detection - trampoline bool is_function_hooked(void* function) {! ! uintptr_t* code = (uintptr_t*)(uintptr_t) function;! ! if (code[0] == 0xE5XXXXXX) {! return true;! }! return false;! }!
  40. February 6, 2015 Mobile Central Europe 37 38 39 40

    41 42 43 44 45 46 47 48 DYLD_INSERT_LIBRARIES detection extern char **environ;! ! bool is_dyld_insert_libraries_present(void) {! int i=0;! char *envp = *environ;! char *dyld_var = "DYLD_INSERT_LIBRARIES”;! while(envp) {! i++;! char *env_var = NULL, *env_val = NULL;! … ! if (strncmp(env_var, dyld_var , sizeof(dyld_var)-1) == 0) {! return true;! }! "envp = *(environ+i);! }! return false;! }!
  41. February 6, 2015 Mobile Central Europe 37 38 39 40

    41 42 43 44 45 46 47 48 Mobile Substrate detection #import <mach-o/dyld.h>! ! bool is_mobile_substrate_present(void) {! ! uint32_t count = _dyld_image_count();! char* substrate = "Library/MobileSubstrate/MobileSubstrate.dylib";! ! for (uint32_t i = 0; i < count; ++i) {! "if (strcmp(_dyld_get_image_name(i),substrate)==0) {! return true;! }! }! return false;! }!
  42. February 6, 2015 Mobile Central Europe 37 38 39 40

    41 42 43 44 45 46 47 48 ‘Bad’ symbols detection bool is_cycript_present(void) {! ! Class genericClass = objc_getClass("CYJSArray");! SEL genericSelector = sel_registerName("initWithJSObject:inContext:");! ! if (genericClass) {! Method method = class_getInstanceMethod(genericClass, genericSelector);! if (method) {! return true;! }! }! return false;! }!
  43. February 6, 2015 Mobile Central Europe o  Anti-hooking o  Anti-patching

    o  Obfuscation 37 38 39 40 41 42 43 44 45 46 47 48 Security coding practices
  44. February 6, 2015 Mobile Central Europe 37 38 39 40

    41 42 43 44 45 46 47 48 Anti-hooking __attribute__((always_inline))! static inline void my_secret_function(void)! o  Inline critical functions o  Symbol visibility __attribute__((visibility("hidden")))! static bool is_dyld_insert_libraries_present(void) o  Hook detection Dl_info info; if (dladdr(func_pointer, &info)) // Pointer! ! if (code[0] == 0xE5XXXXXX) " " // Trampoline
  45. February 6, 2015 Mobile Central Europe 37 38 39 40

    41 42 43 44 45 46 47 48 Anti-patching – code checksum for (uint32_t i = 0; cmd != NULL && i < header->ncmds; i++) {! if (cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) {! segment_command_t* segment = (segment_command_t*)cmd;! if (!strcmp(segment->segname, SEG_TEXT)) {! section_t * section = (section_t *)(segment + 1);! for (uint32_t j = 0; section != NULL && j < segment->nsects; j++){! if (!strcmp(section->sectname, SECT_TEXT))! break;! section = (section_t *)(section + 1);! }! … if (!CC_SHA1(text_section, (CC_LONG)text_section_size, code_hash_buf))! if (memcmp(signature_buf, code_hash_buf, sizeof(code_hash_buf)) == 0)!
  46. February 6, 2015 Mobile Central Europe 37 38 39 40

    41 42 43 44 45 46 47 48 Obfuscation – hide function calls uint32_t count = _dyld_image_count();! const char *image= NULL;! ! for(uint32_t i = 0; i < count; i++) {! dyld = _dyld_get_image_name(i);! }! static uint32_t (*orig_dyld_image_count)(void);! orig_dyld_image_count = dlsym(RTLD_DEFAULT, "_dyld_image_count");//To obfuscate! ! uint32_t count = orig_dyld_image_count();! const char *dyld = NULL;! ! for(uint32_t i = 0; i < count; i++) {! dyld = _dyld_get_image_name(i);! }!
  47. February 6, 2015 Mobile Central Europe 37 38 39 40

    41 42 43 44 45 46 47 48 Obfuscation – hide method calls ! NSString *string = @"Hi im string";! string = [string uppercaseString];! ! ! // Obfuscate all strings! id string = @"Hi im string";! SEL genericSelector = sel_registerName("uppercaseString");! string = ((id(*)(id, SEL))objc_msgSend)(string,genericSelector);!
  48. February 6, 2015 Mobile Central Europe 37 38 39 40

    41 42 43 44 45 46 47 48 Obfuscation – strings obfuscation + (NSString*)xorString: (NSString*)first withString: (NSString*)second! {! …! for(int index = 0; index < [firstString length]; index++)! firstBytes[index] ^= secondBytes[index];! ! NSString *result = firstString;! return result;! }! o  Simple XOR o  Encoding \ Decoding table o  Crypto
  49. February 6, 2015 Mobile Central Europe 49 50 51 52

    53 54 55 56 57 58 59 60 Obfuscation – numbers obfuscation __attribute__((noinline))! static volatile uint32_t get_obfuscated_num(uint32_t *seed){! *seed = ((*seed) * 214013 + 2531011) & 0x7fffffff;! return *seed >> 16;! }! ! int seed = 1802271524;! int number = get_obfuscated_num(&seed); //Return 2!
  50. February 6, 2015 Mobile Central Europe 49 50 51 52

    53 54 55 56 57 58 59 60 3rd party obfuscators o  Arxan o  LLVM Obfuscator o  iOS Class Guard
  51. February 6, 2015 Mobile Central Europe o  Functions replacement o 

    System calls o  Device anomalies o  Assembler code obfuscation 49 50 51 52 53 54 55 56 57 58 59 60 Advanced practices
  52. February 6, 2015 Mobile Central Europe 49 50 51 52

    53 54 55 56 57 58 59 60 Re-implement libc __attribute__((always_inline))! static inline int mb_memcmp(const void *s1, const void *s2, size_t n) {! if (n != 0) {! const unsigned char *p1 = s1, *p2 = s2;! ! do {! if (*p1++ != *p2++)! return (*--p1 - *--p2);! } while (--n != 0);! }! return (0);! }! memcmp, memcpy, strcmp, strncmp, strstr
  53. February 6, 2015 Mobile Central Europe 49 50 51 52

    53 54 55 56 57 58 59 60 Re-implement dyld const void * dlladdr(mach_header *image, const char *symbol) {! " " " "… nlist_t *symbase = (nlist_t*)(image + (symtab->symoff + file_slide));! char *strings = (char*)(image + (symtab->stroff + file_slide));! nlist_t *sym;! ! for (i = 0, sym = symbase; i < symtab->nsyms; i += 1, sym += 1)! {! if (sym->n_un.n_strx != 0 && !strcmp(symbol, strings + sym->n_un.n_strx))! {! unsigned long address = vm_slide + sym->n_value;! if (sym->n_desc & N_ARM_THUMB_DEF)! return (const void*)(address | 1);! else! return (const void*)(address);! }! dlsym, dladdr, _dyld_get_image_xxx
  54. February 6, 2015 Mobile Central Europe 49 50 51 52

    53 54 55 56 57 58 59 60 Device anomalies if (sysctl(myname, 4, &myinfo, &myinfo_size, NULL, 0) == -1) {! return;! }! ! // check for debugger trace flag set! if ((myinfo.kp_proc.p_flag & P_TRACED) != 0) ! "NSLog(@”Tracing detected");! } ! // check for aslr disabled flag! if ((myinfo.kp_proc.p_flag & P_DISABLE_ASLR) != 0) {! NSLog(@"PIE disabled");! } ! // check for debugger enabled flag! if ((myinfo.kp_proc.p_debugger) != 0) {! NSLog(@"Debugger enabled ?");! }! }!
  55. February 6, 2015 Mobile Central Europe 49 50 51 52

    53 54 55 56 57 58 59 60 Device anomalies // check kproc for mobile's uid! if ( myinfo.kp_eproc.e_pcred.p_ruid != 501 ||! myinfo.kp_eproc.e_pcred.p_svuid != 501 ||! myinfo.kp_eproc.e_ucred.cr_uid != 501 )! {! NSLog(@"Mobile uid anomaly");! }! ! // check kproc for mobile's gid! if ( myinfo.kp_eproc.e_pcred.p_rgid != 501 ||! myinfo.kp_eproc.e_pcred.p_svgid != 501 )! {! NSLog(@"Mobile gid anomaly");! }!
  56. February 6, 2015 Mobile Central Europe 49 50 51 52

    53 54 55 56 57 58 59 60 System calls o  Syscall function as wrapper o  Implemented as svc 0x80 o  Syscall number in r12 or x16 o  Arguments in registers o  Listed in syscall.h
  57. February 6, 2015 Mobile Central Europe 49 50 51 52

    53 54 55 56 57 58 59 60 Syscall ; ssize_t read(int, void *, size_t)! EXPORT _read! _read! MOV R12, #3 // SYS_read! SVC 0x80! BCC locret_2F756914! …! BX R12! #define "SYS_syscall 0! #define "SYS_exit 1! #define "SYS_fork 2! #define "SYS_read 3! #define "SYS_write 4! usr/include/sys/syscall.h
  58. February 6, 2015 Mobile Central Europe 49 50 51 52

    53 54 55 56 57 58 59 60 Access to private stuff #include <codesign.h> // opensource.apple.com! ! int csops(pid_t pid, unsigned int ops, void *addr, size_t size);! ! #define "SYS_csops 169! #include <ptrace.h> // opensource.apple.com! ! int ptrace(int _request, pid_t _pid, caddr_t _addr, int _data);! ! #define "SYS_ptrace 26!
  59. February 6, 2015 Mobile Central Europe 49 50 51 52

    53 54 55 56 57 58 59 60 CSOPS – getting code directory hash #include <codesign.h> ! ! syscall(SYS_csops,! CS_OPS_CDHASH,! " (void*)BUFFER,! " CC_SHA1_DIGEST_LENGTH);!
  60. February 6, 2015 Mobile Central Europe 49 50 51 52

    53 54 55 56 57 58 59 60 Rewrite code using syscalls pid_t pid = getpid(); " " pid_t pid = syscall(SYS_getpid);! ! ! ! int st = sysctl(mib,…); " int st = syscall(SYS_sysctl,…);! ! ! ! pid_t pid = fork(); " " pid_t pid = syscall(SYS_fork);! ! ! ! int st = stat("/bin",…); " int st = syscall(SYS_stat,…);! !
  61. February 6, 2015 Mobile Central Europe 61 62 63 64

    65 66 67 68 69 70 71 72 Implement your own syscall int zyzcall(int num, uint32_t arg0, uint32_t arg1, uint32_t arg2) {! ! int result = 0;! asm volatile (! ".thumb;"! "mov r0, %[a0];"! " ""mov r1, %[a1];"! " ""mov r2, %[a2];“! " ""mov r12, %[num];"! " ""svc 0x80;"! "mov %[ret], r0;“! " " …! " ");! return result;!
  62. February 6, 2015 Mobile Central Europe 61 62 63 64

    65 66 67 68 69 70 71 72 How to obfuscate syscall ? o  ARM – 4 bytes o  Thumb - 2 bytes o  Thumb2 - 2/4 bytes o  ARM64 - 4 bytes
  63. February 6, 2015 Mobile Central Europe 61 62 63 64

    65 66 67 68 69 70 71 72 Instructions overlapping "add r11, r12, r4;"! "mov r4, %[a3];"! "mov r12, 0;“! "mov pc, r11;“! //overlaps with SVC instruction! ".byte 0x50, 0xf8;"! "svc 0x80;"! "mov %[ret], r0;"
  64. February 6, 2015 Mobile Central Europe 61 62 63 64

    65 66 67 68 69 70 71 72 Instructions overlapping No SVC instruction J
  65. February 6, 2015 Mobile Central Europe 61 62 63 64

    65 66 67 68 69 70 71 72 Summary o  Do not rely on iOS security and ObjC\Swift o  ‘Everything is hooked’ environment o  Detect hooks and code injection o  Detect debuggers and device anomalies o  Re implement standard functions o  Love and use syscalls o  Obfuscate your code
  66. February 6, 2015 Mobile Central Europe 61 62 63 64

    65 66 67 68 69 70 71 72 Cracking time == protection time
  67. February 6, 2015 Mobile Central Europe 61 62 63 64

    65 66 67 68 69 70 71 72 @mbazaliy