WithSecureLabs / needle

The iOS Security Testing Framework
https://mobiletools.mwrinfosecurity.com/
Other
1.33k stars 284 forks source link

Fix how Frida script modules find running processes via "ps ax | grep" #215

Closed Yogehi closed 6 years ago

Yogehi commented 6 years ago

frida scripts rely on this module to find the proper PID. this module will not find the proper PID under specific conditions, as outlined in the pull requests https://github.com/mwrlabs/needle/pull/214 and https://github.com/mwrlabs/needle/pull/213

marco-lancini commented 6 years ago

@Yogehi on what versions of iOS have you tested this modifications? Are you sure replace("/private","") works for both system and 3rd party apps? And on iOS 8,9, and 10?

Yogehi commented 6 years ago

I don't have an iOS 8 device on me. I'll have to ask someone else to do that.

I can try iOS 9 tomorrow. Our current iOS 9 device is in use.

I'm currently using iOS 10. I used the module 'script_dump-ui' to hook into the Camera app. Full output below:

[needle] > set debug true
DEBUG => true
[needle] > set app com.apple.camera
APP => com.apple.camera
[needle] > use hooking/frida/script_dump-ui
[needle][script_dump-ui] > run
[D] Setup local output folder: /root/.needle/output
[?] Attention! The folder chosen to store local output is not empty: /root/.needle/output
[?] Do you want to back it up first?
[?] Y: the content will be archived in a different location, then the folder will be emptied
[?] N: no action will be taken (destination files might be overwritten in case of filename clash)
[y/n]: n
[D] Setting up issues database...
[D] [DB] QUERY: CREATE TABLE IF NOT EXISTS issues (app TEXT, module TEXT, name TEXT, content TEXT, confidence TEXT, outfile TEXT)
[*] Checking connection with device...
[V] Connection not present, creating a new instance
[D] Setting up USB port forwarding on port 2222
[D] [LOCAL CMD] Local Subprocess Command: /root/Programs/needle/needle/libs/usbmuxd/tcprelay.py -t 22:2222
[D] [AGENT] Setting up port forwarding on port 4444
[V] [AGENT] Connecting to agent (127.0.0.1:4444)...
[+] [AGENT] Successfully connected to agent (127.0.0.1:4444)...
[D] [AGENT] Executing command: os_version
[V] [SSH] Connecting (127.0.0.1:2222)...
[+] [SSH] Connected (127.0.0.1:2222)
[D] Creating temp folder: /var/root/needle/
[D] [REMOTE CMD] Remote Command: if [ -d /var/root/needle/ ]; then echo "yes"; else echo "no" ; fi
[D] [REMOTE CMD] Remote Command: mkdir /var/root/needle/
[D] [AGENT] Executing command: os_version
[+] Target app: com.apple.camera
[*] Retrieving app's metadata...
[D] [AGENT] Executing command: list_apps
[D] Copying the plist to temp: /Applications/Camera.app/Info.plist -> /root/.needle/tmp/plist
[*] Pulling: /Applications/Camera.app/Info.plist -> /root/.needle/tmp/plist
[D] Downloading: "/Applications/Camera.app/Info.plist" -> /root/.needle/tmp/plist
[D] [LOCAL CMD] Local Command: sshpass -p "<password>" scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -P 2222 root@127.0.0.1:"/Applications/Camera.app/Info.plist" /root/.needle/tmp/plist
[D] [REMOTE CMD] Remote Command: lipo -info /Applications/Camera.app/Camera
[D] [REMOTE CMD] Remote Command: if [ -d /Applications/Camera.app/PlugIns ]; then echo "yes"; else echo "no" ; fi
[D] No Plugins found
[*] Setting up local port forwarding to enable communications with the Frida server...
[D] [FRIDA] Setting up port forwarding on port 27042
[D] Connected over USB
[*] Launching the app...
[D] [REMOTE CMD] Remote Command: open com.apple.camera
[V] Retrieving the PID...
[D] [REMOTE CMD] Remote Command: ps ax | grep -i '/Applications/Camera.app/Camera'
[V] PID found: 2558
[*] Attaching to process: 2558
[*] Parsing payload
[needle][script_dump-ui] > [*] <CAMSecureWindow: 0x100224540; baseClass = UIWindow; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x174249840>; layer = <UIWindowLayer: 0x174221940>>
   | <CAMViewfinderView: 0x10031df40; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x17024baf0>; layer = <CAMCounterRotatingLayer: 0x170220e40>>
   |    | <CAMPreviewContainerMaskingView: 0x1002177f0; frame = (0 0; 320 568); layer = <CALayer: 0x174221420>>
   |    |    | <CAMPreviewContainerView: 0x10031e1e0; frame = (0 0; 320 568); layer = <CALayer: 0x170220f00>>
   |    |    |    | <CAMPreviewView: 0x100226540; frame = (0 40; 320 426.5); tintColor = UIExtendedSRGBColorSpace 1 0.8 0 1; gestureRecognizers = <NSArray: 0x170245fa0>; layer = <CAMCounterRotatingLayer: 0x174223b40>>
   |    |    |    |    | <CAMVideoPreviewView: 0x10031ba00; frame = (0 0; 320 426.5); clipsToBounds = YES; layer = <CALayer: 0x1742216c0>>
   |    |    |    |    |    | <UIView: 0x10031bbe0; frame = (0 0; 320 426.5); layer = <CALayer: 0x170220780>>
   |    |    |    |    |    | <UIView: 0x100226d30; frame = (0 0; 320 426.5); layer = <CALayer: 0x170220800>>
   |    |    |    |    |    |    | <AVCaptureVideoPreviewLayer: 0x174222640> (layer)
   |    |    |    |    |    |    |    | <CALayer: 0x1742225e0> (layer)
   |    |    |    |    | <UIView: 0x10031c180; frame = (0 0; 320 426.5); clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x170220920>>
   |    |    |    |    |    | <CAMFocusIndicatorView: 0x100218790; frame = (97.5 151; 125 125); alpha = 0; tintColor = UIExtendedSRGBColorSpace 1 0.8 0 1; animations = { opacity=<CABasicAnimation: 0x170225f80>; }; layer = <CALayer: 0x17422e0e0>>
   |    |    |    |    |    |    | <CAMFocusIndicatorRectView: 0x100225f50; frame = (0 0; 125 125); layer = <CALayer: 0x174223c80>>
   |    |    |    |    |    |    |    | <UIImageView: 0x10033da20; frame = (0 0; 125 125); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x1702243e0>>
   |    | <CAMTopBar: 0x100319e80; frame = (0 0; 320 40); layer = <CALayer: 0x170220d40>>
   |    |    | <UIView: 0x10031d720; frame = (0 0; 320 40); autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x170220d60>>
   |    |    | <CAMFlashButton: 0x10032e750; baseClass = UIControl; frame = (0 -1; 44 42); tintColor = UIExtendedGrayColorSpace 1 1; gestureRecognizers = <NSArray: 0x17024a3b0>; layer = <CALayer: 0x1702268a0>>
   |    |    |    | <CAMButtonLabel: 0x10023dab0; frame = (0 0; 0 0); text = 'Auto'; alpha = 0; layer = <CALayer: 0x17422e020>>
   |    |    |    |    | <UILabel: 0x10023dc70; frame = (0 0; 28 14.5); text = 'Auto'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x17409b850>>
   |    |    |    | <CAMButtonLabel: 0x10023e740; frame = (0 0; 0 0); text = 'On'; alpha = 0; layer = <CALayer: 0x17422df80>>
   |    |    |    |    | <UILabel: 0x10023e900; frame = (0 0; 16.5 14.5); text = 'On'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x17409bad0>>
   |    |    |    | <CAMButtonLabel: 0x10023f3d0; frame = (0 0; 0 0); text = 'Off'; alpha = 0; layer = <CALayer: 0x17422dd80>>
   |    |    |    |    | <UILabel: 0x10023f590; frame = (0 0; 19.5 14.5); text = 'Off'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x17409bd50>>
   |    |    |    | <UIImageView: 0x1002391b0; frame = (11 10; 22 22); opaque = NO; userInteractionEnabled = NO; tintColor = UIExtendedGrayColorSpace 1 1; layer = <CALayer: 0x17422d8c0>>
   |    |    | <CAMTimerButton: 0x100331c40; baseClass = UIControl; frame = (209.5 -2; 44 44); tintColor = UIExtendedGrayColorSpace 1 1; gestureRecognizers = <NSArray: 0x17024c090>; layer = <CALayer: 0x170226580>>
   |    |    |    | <CAMButtonLabel: 0x100240330; frame = (0 0; 0 0); text = 'Off'; alpha = 0; layer = <CALayer: 0x17422f0e0>>
   |    |    |    |    | <UILabel: 0x1002406f0; frame = (0 0; 19.5 14.5); text = 'Off'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x17409c390>>
   |    |    |    | <CAMButtonLabel: 0x100240980; frame = (0 0; 0 0); text = '3s'; alpha = 0; layer = <CALayer: 0x17422f220>>
   |    |    |    |    | <UILabel: 0x100240b40; frame = (0 0; 14.5 14.5); text = '3s'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x17409c480>>
   |    |    |    | <CAMButtonLabel: 0x100241610; frame = (0 0; 0 0); text = '10s'; alpha = 0; layer = <CALayer: 0x17422f460>>
   |    |    |    |    | <UILabel: 0x1002417d0; frame = (0 0; 20.5 14.5); text = '10s'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x17409c700>>
   |    |    |    | <UIImageView: 0x100332460; frame = (11 11; 22 22); opaque = NO; userInteractionEnabled = NO; tintColor = UIExtendedGrayColorSpace 1 1; layer = <CALayer: 0x170226180>>
   |    |    | <CAMHDRButton: 0x100243110; baseClass = UIControl; frame = (60 -3; 49 46); tintColor = UIExtendedGrayColorSpace 1 1; gestureRecognizers = <NSArray: 0x174250d40>; layer = <CALayer: 0x17422fa40>>
   |    |    |    | <CAMButtonLabel: 0x100246e80; frame = (0 0; 0 0); text = 'Auto'; alpha = 0; layer = <CALayer: 0x1742303c0>>
   |    |    |    |    | <UILabel: 0x100247040; frame = (0 0; 28 14.5); text = 'Auto'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x17409d420>>
   |    |    |    | <CAMButtonLabel: 0x100247b10; frame = (0 0; 0 0); text = 'On'; alpha = 0; layer = <CALayer: 0x1742309c0>>
   |    |    |    |    | <UILabel: 0x100247cd0; frame = (0 0; 16.5 14.5); text = 'On'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x17409dc90>>
   |    |    |    | <CAMButtonLabel: 0x1002487a0; frame = (0 0; 0 0); text = 'Off'; alpha = 0; layer = <CALayer: 0x174230c40>>
   |    |    |    |    | <UILabel: 0x100248960; frame = (0 0; 19.5 14.5); text = 'Off'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x17409df10>>
   |    |    |    | <UIImageView: 0x100243930; frame = (11 12; 27 22); opaque = NO; userInteractionEnabled = NO; tintColor = UIExtendedGrayColorSpace 1 1; layer = <CALayer: 0x17422fc60>>
   |    |    | <CAMFilterButton: 0x100339970; baseClass = UIButton; frame = (273.5 -0.5; 41 41); opaque = NO; layer = <CALayer: 0x170226da0>>
   |    |    |    | <UIImageView: 0x1002380a0; frame = (9.5 9.5; 22 22); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x1742227a0>>
   |    |    | <CAMIrisButton: 0x100249bb0; baseClass = UIButton; frame = (125 -13; 66 66); opaque = NO; tintColor = UIExtendedSRGBColorSpace 1 0.8 0 1; layer = <CALayer: 0x1742314e0>>
   |    |    |    | <UIImageView: 0x10024a0c0; frame = (11 11; 44 44); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x174231620>>
   |    | <CAMBottomBar: 0x10031d8c0; frame = (0 466.5; 320 101.5); layer = <CALayer: 0x170220dc0>>
   |    |    | <UIView: 0x10031dda0; frame = (0 0; 320 101.5); autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x170220de0>>
   |    |    | <CUShutterButton: 0x100226930; baseClass = UIButton; frame = (103 31; 114 66); opaque = NO; layer = <CALayer: 0x174221340>>
   |    |    |    | <CAMShutterButtonRingView: 0x100320060; frame = (24 0; 66 66); userInteractionEnabled = NO; layer = <CALayer: 0x170221480>>
   |    |    |    | <UIView: 0x1003206c0; frame = (32 8; 50 50); userInteractionEnabled = NO; layer = <CALayer: 0x170221680>>
   |    |    | <CAMFlipButton: 0x100320860; baseClass = UIButton; frame = (260 40; 56 48); opaque = NO; tintColor = UIExtendedGrayColorSpace 1 1; layer = <CALayer: 0x1702217a0>>
   |    |    |    | <UIImageView: 0x100320f60; frame = (11 11; 34 26); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x1702217c0>>
   |    |    | <CAMModeDial: 0x10021ee80; baseClass = UIControl; frame = (0 0; 320 31); clipsToBounds = YES; tintColor = UIExtendedSRGBColorSpace 1 0.8 0 1; layer = <CALayer: 0x174224a40>>
   |    |    |    | <UIView: 0x10021f310; frame = (-93 -631.5; 506 662.5); userInteractionEnabled = NO; layer = <CALayer: 0x1742248c0>>
   |    |    |    |    | <UIView: 0x1002295e0; frame = (-14.5 631.5; 453.5 31); userInteractionEnabled = NO; layer = <CALayer: 0x174224aa0>>
   |    |    |    |    |    | <CAMModeDialItem: 0x100323e80; frame = (0 7.5; 77 16); layer = <CALayer: 0x1702228e0>>
   |    |    |    |    |    |    | <CAShapeLayer: 0x17422c660> (layer)
   |    |    |    |    |    | <CAMModeDialItem: 0x100324050; frame = (103 7.5; 50.5 16); layer = <CALayer: 0x170223b20>>
   |    |    |    |    |    |    | <CAShapeLayer: 0x170223bc0> (layer)
   |    |    |    |    |    | <CAMModeDialItem: 0x100326c50; frame = (179.5 7.5; 39 16); layer = <CALayer: 0x170223ce0>>
   |    |    |    |    |    |    | <CAShapeLayer: 0x170223d60> (layer)
   |    |    |    |    |    | <CAMModeDialItem: 0x100327f60; frame = (244.5 7.5; 43.5 16); layer = <CALayer: 0x170223f20>>
   |    |    |    |    |    |    | <CAShapeLayer: 0x170223fa0> (layer)
   |    |    |    |    |    | <CAMModeDialItem: 0x10032ae90; frame = (314 7.5; 52 16); layer = <CALayer: 0x170224120>>
   |    |    |    |    |    |    | <CAShapeLayer: 0x1702241c0> (layer)
   |    |    |    |    |    | <CAMModeDialItem: 0x10032cd60; frame = (392 7.5; 35.5 16); layer = <CALayer: 0x170224320>>
   |    |    |    |    |    |    | <CAShapeLayer: 0x1702243c0> (layer)
   |    |    | <CAMImageWell: 0x1002393f0; baseClass = UIButton; frame = (0 40.5; 62 58); opaque = NO; layer = <CALayer: 0x17422d2c0>>
   |    |    |    | <UIView: 0x100239920; frame = (15 0; 47 47); userInteractionEnabled = NO; layer = <CALayer: 0x17422d2e0>>
   |    |    |    |    | <UIImageView: 0x100239ac0; frame = (0 0; 47 47); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x17422d340>>
   |    | <CAMFocusLockBadge: 0x100238aa0; frame = (116.5 55; 87.5 20); alpha = 0; hidden = YES; layer = <CALayer: 0x17422d160>>
   |    | <CAMFlashBadge: 0x1003246e0; frame = (140 55; 40 21); layer = <CALayer: 0x170225580>>
   |    | <CAMLivePhotoBadge: 0x100331700; frame = (141 55; 38.5 20); alpha = 0; hidden = YES; layer = <CALayer: 0x170226460>>
   |    | <CAMTimerIndicatorView: 0x1002422a0; frame = (0 40; 320 426.5); alpha = 0; hidden = YES; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x17422f820>>
   |    |    | <UIView: 0x100242680; frame = (0 0; 320 426.5); alpha = 0; autoresize = W+H; layer = <CALayer: 0x17422f840>>
   |    |    | <UILabel: 0x100242820; frame = (278 345.5; 33 72); text = '0'; alpha = 0; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x17409ca70>>
   |    | <CAMHDRBadge: 0x1003388a0; frame = (141 55; 38 20); alpha = 0; hidden = YES; layer = <CALayer: 0x170226a40>>
   |    | <CAMBurstIndicatorView: 0x100338e20; frame = (142 410; 36 36); alpha = 0; layer = <CALayer: 0x170226b40>>
   |    |    | <UIView: 0x100338a80; frame = (0 0; 36 36); layer = <CALayer: 0x170226ba0>>
   |    |    | <UILabel: 0x1003391e0; frame = (0 9; 36 18); text = '000'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x1700954a0>>

To verify, I SShed into the iPhone to verify that the Camera app was at PID 2558:

root@YayComputerYay:~/Programs/needle/needle# ssh root@localhost -p 2222
root@localhost's password: 
Yay-iPhone-SE-Yay:~ root# ps ax | grep -i '/Applications/Camera.app/Camera'
 2558   ??  Ss     0:00.49 /Applications/Camera.app/Camera
 2572 s000  R+     0:00.01 grep -i /Applications/Camera.app/Camera
Yay-iPhone-SE-Yay:~ root# ps ax | grep -i 'Camera'
 2558   ??  Ss     0:00.50 /Applications/Camera.app/Camera
 2574 s000  R+     0:00.00 grep -i Camera
Yogehi commented 6 years ago

tested successfully on iOS 9 on the system app "com.apple.camera" and the module "hooking/frida/script_dump-ui". full needle output below:

[needle] > set debug true
DEBUG => true
[needle] > shell
[*] Spawning a shell...
[*] Checking connection with device...
[V] Connection not present, creating a new instance
[D] Setting up USB port forwarding on port 2222
[D] [LOCAL CMD] Local Subprocess Command: /root/Programs/needle/needle/libs/usbmuxd/tcprelay.py -t 22:2222
[D] [AGENT] Setting up port forwarding on port 4444
[V] [AGENT] Connecting to agent (127.0.0.1:4444)...
[+] [AGENT] Successfully connected to agent (127.0.0.1:4444)...
[D] [AGENT] Executing command: os_version
[V] [SSH] Connecting (127.0.0.1:2222)...
[+] [SSH] Connected (127.0.0.1:2222)
[D] [LOCAL CMD] Local Interactive Command: sshpass -p "<password>" ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p 2222 root@127.0.0.1
Warning: Permanently added '[127.0.0.1]:2222' (RSA) to the list of known hosts.
zaks-iPad:~ root# uname -a
Darwin zaks-iPad 15.0.0 Darwin Kernel Version 15.0.0: Thu Aug 20 13:11:14 PDT 2015; root:xnu-3248.1.3~1/RELEASE_ARM64_S5L8960X iPad4,2 arm64 J72AP Darwin
zaks-iPad:~ root# exit
logout
Connection to 127.0.0.1 closed.
[needle] > set app com.apple.camera
APP => com.apple.camera
[needle] > use hooking/frida/script_dump-ui
[needle][script_dump-ui] > run
[D] Setup local output folder: /root/.needle/output
[D] Setting up issues database...
[D] [DB] QUERY: CREATE TABLE IF NOT EXISTS issues (app TEXT, module TEXT, name TEXT, content TEXT, confidence TEXT, outfile TEXT)
[*] Checking connection with device...
[+] Already connected to: 127.0.0.1
[D] Creating temp folder: /var/root/needle/
[D] [REMOTE CMD] Remote Command: if [ -d /var/root/needle/ ]; then echo "yes"; else echo "no" ; fi
[D] [AGENT] Executing command: os_version
[+] Target app: com.apple.camera
[*] Retrieving app's metadata...
[D] [AGENT] Executing command: list_apps
[D] Copying the plist to temp: /Applications/Camera.app/Info.plist -> /root/.needle/tmp/plist
[*] Pulling: /Applications/Camera.app/Info.plist -> /root/.needle/tmp/plist
[D] Downloading: "/Applications/Camera.app/Info.plist" -> /root/.needle/tmp/plist
[D] [LOCAL CMD] Local Command: sshpass -p "<password>" scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -P 2222 root@127.0.0.1:"/Applications/Camera.app/Info.plist" /root/.needle/tmp/plist
[D] [REMOTE CMD] Remote Command: lipo -info /Applications/Camera.app/Camera
[D] [REMOTE CMD] Remote Command: if [ -d /Applications/Camera.app/PlugIns ]; then echo "yes"; else echo "no" ; fi
[D] No Plugins found
[*] Setting up local port forwarding to enable communications with the Frida server...
[D] [FRIDA] Setting up port forwarding on port 27042
[D] Connected over USB
[*] Launching the app...
[D] [REMOTE CMD] Remote Command: open com.apple.camera
[V] Retrieving the PID...
[D] [REMOTE CMD] Remote Command: ps ax | grep -i '/Applications/Camera.app/Camera'
[V] PID found: 715
[*] Attaching to process: 715
[*] Parsing payload
[needle][script_dump-ui] > [*] <CAMSecureWindow: 0x12eea7830; baseClass = UIWindow; frame = (0 0; 768 1024); gestureRecognizers = <NSArray: 0x12eea8dd0>; layer = <UIWindowLayer: 0x12eea7d70>>
   | <CAMViewfinderView: 0x12ed7f7e0; frame = (0 0; 768 1024); autoresize = W+H; gestureRecognizers = <NSArray: 0x12eedd8a0>; layer = <CAMCounterRotatingLayer: 0x12ed6d1d0>>
   |    | <CAMPreviewContainerMaskingView: 0x12ed7fcf0; frame = (0 0; 768 1024); layer = <CALayer: 0x12ed7b170>>
   |    |    | <CAMPreviewContainerView: 0x12ed7ae10; frame = (0 0; 768 1024); layer = <CALayer: 0x12ed7a6d0>>
   |    |    |    | <CAMPreviewView: 0x12ed7a6f0; frame = (0 0; 768 1024); tintColor = UIDeviceRGBColorSpace 1 0.8 0 1; gestureRecognizers = <NSArray: 0x12ed7eb90>; layer = <CAMCounterRotatingLayer: 0x12ed7abb0>>
   |    |    |    |    | <CAMVideoPreviewView: 0x12eeac760; frame = (0 0; 768 1024); clipsToBounds = YES; layer = <CALayer: 0x12ee92f50>>
   |    |    |    |    |    | <UIView: 0x12ed7c7c0; frame = (0 0; 768 1024); layer = <CALayer: 0x12ed7cb20>>
   |    |    |    |    |    | <UIView: 0x12ed7ce30; frame = (0 0; 768 1024); layer = <CALayer: 0x12ed7cf90>>
   |    |    |    |    |    |    | <AVCaptureVideoPreviewLayer: 0x12ee68510> (layer)
   |    |    |    |    |    |    |    | <CALayer: 0x12ee5ee60> (layer)
   |    |    |    |    | <UIView: 0x12ed7d6d0; frame = (0 0; 768 1024); clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x12ed7d550>>
   |    |    |    |    |    | <CAMFocusIndicatorView: 0x12eddd2c0; frame = (321.5 449.5; 125 125); animations = { scaleAnimation=<CAKeyframeAnimation: 0x12edaea60>; }; layer = <CALayer: 0x12ee796d0>>
   |    |    |    |    |    |    | <CAMFocusIndicatorRectView: 0x12eee8120; baseClass = UIImageView; frame = (0 0; 125 125); opaque = NO; userInteractionEnabled = NO; animations = { contents=<CAKeyframeAnimation: 0x12eed1220>; }; layer = <CALayer: 0x12eecddb0>>
   |    | <CAMTopBar: 0x12eeadd50; frame = (384 0; 0 0); layer = <CALayer: 0x12eeae180>>
   |    |    | <UIView: 0x12ed7f680; frame = (0 0; 0 0); autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x12ed7c690>>
   |    | <CAMBottomBar: 0x12ed74500; frame = (666 0; 102 1024); layer = <CALayer: 0x12ed746e0>>
   |    |    | <UIView: 0x12ed7a950; frame = (0 0; 102 1024); autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x12ed7aab0>>
   |    |    | <CUShutterButton: 0x12eeac9d0; baseClass = UIButton; frame = (18 479; 66 66); opaque = NO; layer = <CALayer: 0x12ee96f60>>
   |    |    |    | <CAMShutterButtonRingView: 0x12eea59d0; frame = (0 0; 66 66); userInteractionEnabled = NO; layer = <CALayer: 0x12eea5bb0>>
   |    |    |    | <UIView: 0x12eeae000; frame = (8 8; 50 50); userInteractionEnabled = NO; layer = <CALayer: 0x12eeae160>>
   |    |    | <CAMModeDial: 0x12eeae760; baseClass = UIControl; frame = (0 545; 102 421); tintColor = UIDeviceRGBColorSpace 1 0.8 0 1; layer = <CALayer: 0x12ee597d0>>
   |    |    |    | <UIView: 0x12ed8aff0; frame = (-29 68.5; 160 284); userInteractionEnabled = NO; layer = <CALayer: 0x12ed8a220>>
   |    |    |    |    | <UIView: 0x12ed8bd70; frame = (29 42; 102 215.342); userInteractionEnabled = NO; layer = <CALayer: 0x12ed86b40>>
   |    |    |    |    |    | <CAMModeDialItem: 0x12ed8bed0; frame = (26 0; 41.0621 25.5293); layer = <CALayer: 0x12ed8afd0>>
   |    |    |    |    |    |    | <CAShapeLayer: 0x12eec32a0> (layer)
   |    |    |    |    |    | <CAMModeDialItem: 0x12edaecf0; frame = (26 55.5293; 39.4283 9.72754); layer = <CALayer: 0x12eed3040>>
   |    |    |    |    |    |    | <CAShapeLayer: 0x12edb1710> (layer)
   |    |    |    |    |    | <CAMModeDialItem: 0x12eed5e70; frame = (26 95.2568; 43.0855 9.72754); layer = <CALayer: 0x12eed5e10>>
   |    |    |    |    |    |    | <CAShapeLayer: 0x12eeceea0> (layer)
   |    |    |    |    |    | <CAMModeDialItem: 0x12eed71d0; frame = (26 134.984; 53.0127 10.6299); layer = <CALayer: 0x12eed6930>>
   |    |    |    |    |    |    | <CAShapeLayer: 0x12eed74b0> (layer)
   |    |    |    |    |    | <CAMModeDialItem: 0x12edbde00; frame = (26 175.614; 34.6145 9.72754); layer = <CALayer: 0x12edb1f70>>
   |    |    |    |    |    |    | <CAShapeLayer: 0x12ed8bcb0> (layer)
   |    |    | <CAMImageWell: 0x12edbdf80; baseClass = UIButton; frame = (18 956; 77 75); opaque = NO; gestureRecognizers = <NSArray: 0x12ef06100>; layer = <CALayer: 0x12ed0b800>>
   |    |    |    | <UIView: 0x12edc1140; frame = (10 10; 47 47); userInteractionEnabled = NO; layer = <CALayer: 0x12edc0000>>
   |    |    |    |    | <UIImageView: 0x12edbe300; frame = (0 0; 47 47); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x12ed71550>>
   |    |    | <CAMFlipButton: 0x12edce220; baseClass = UIButton; frame = (27 -3; 48 48); opaque = NO; tintColor = UIDeviceWhiteColorSpace 1 1; layer = <CALayer: 0x12edce680>>
   |    |    |    | <UIImageView: 0x12ee76540; frame = (0 0; 28 21); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x12ee74d00>>
   |    |    | <CAMHDRButton: 0x12eedf180; baseClass = UIControl; frame = (26 256.5; 49.5 42); tintColor = UIDeviceWhiteColorSpace 1 1; gestureRecognizers = <NSArray: 0x12eedff30>; layer = <CALayer: 0x12eec6a90>>
   |    |    |    | <CAMButtonLabel: 0x12eee6d20; frame = (44.5 -7; 17.5 16); text = 'On'; alpha = 0; layer = <CALayer: 0x12eee6f70>>
   |    |    |    |    | <UILabel: 0x12eee7130; frame = (0 0; 17.5 16); text = 'On'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x12eee6410>>
   |    |    |    | <CAMButtonLabel: 0x12eed9290; frame = (0 0; 0 0); text = 'Off'; alpha = 0; layer = <CALayer: 0x12eed9420>>
   |    |    |    |    | <UILabel: 0x12eea07f0; frame = (0 0; 20.5 16); text = 'Off'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x12eedcd10>>
   |    |    |    | <UIImageView: 0x12eee60a0; frame = (11 10; 27.5 22); opaque = NO; userInteractionEnabled = NO; tintColor = UIDeviceWhiteColorSpace 1 1; layer = <CALayer: 0x12eee5e10>>
   |    |    | <CAMTimerButton: 0x12edd4d80; baseClass = UIControl; frame = (15 212.5; 72 42); tintColor = UIDeviceWhiteColorSpace 1 1; gestureRecognizers = <NSArray: 0x12edcc250>; layer = <CALayer: 0x12ed07b30>>
   |    |    |    | <CAMButtonLabel: 0x12edd7930; frame = (39 13; 22 16); text = 'Off'; layer = <CALayer: 0x12edd7ac0>>
   |    |    |    |    | <UILabel: 0x12edd6b60; frame = (0 0; 20.5 16); text = 'Off'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x12edd6d60>>
   |    |    |    | <CAMButtonLabel: 0x12eef4dc0; frame = (39 13; 15 16); text = '3s'; alpha = 0; layer = <CALayer: 0x12eef0340>>
   |    |    |    |    | <UILabel: 0x12eef4f50; frame = (0 0; 15 16); text = '3s'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x12eef5150>>
   |    |    |    | <CAMButtonLabel: 0x12eef7ca0; frame = (39 53; 22 16); text = '10s'; alpha = 0; layer = <CALayer: 0x12eef76b0>>
   |    |    |    |    | <UILabel: 0x12eef7e30; frame = (0 0; 22 16); text = '10s'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x12eef7800>>
   |    |    |    | <UIImageView: 0x12edd69c0; frame = (11 10; 22 22); opaque = NO; userInteractionEnabled = NO; tintColor = UIDeviceWhiteColorSpace 1 1; layer = <CALayer: 0x12edd66a0>>
   |    | <CAMFocusLockBadge: 0x12eedc970; frame = (338.25 15.5; 91.5 21); alpha = 0; hidden = YES; tintColor = UIDeviceRGBColorSpace 1 0.8 0 1; layer = <CALayer: 0x12eedcd60>>
   |    | <CAMHDRBadge: 0x12eeefc70; frame = (364 987; 40 21); alpha = 0; hidden = YES; tintColor = UIDeviceRGBColorSpace 1 0.8 0 1; layer = <CALayer: 0x12eef0010>>
   |    | <CAMTimerIndicatorView: 0x12eddc280; frame = (0 0; 768 1024); alpha = 0; hidden = YES; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x12eddb3f0>>
   |    |    | <UIView: 0x12eddc5a0; frame = (0 0; 768 1024); alpha = 0; autoresize = W+H; layer = <CALayer: 0x12eddc430>>
   |    |    | <UILabel: 0x12eddbd90; frame = (320 369; 128 286.5); text = '0'; alpha = 0; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x12edd8360>>

verification that the camera app was running at PID 715:

zaks-iPad:/ root# ps ax | grep 'Camera'
  715   ??  Ss     0:01.27 /Applications/Camera.app/Camera
  825 s001  R+     0:00.01 grep Camera

tested successfully on iOS 9 on the user downloaded app "jp.naver.line" and the module "hooking/frida/script_dump-ui". full needle output below:

[needle] > shell
[*] Spawning a shell...
[*] Checking connection with device...
[V] Connection not present, creating a new instance
[V] [AGENT] Connecting to agent (127.0.0.1:4444)...
[+] [AGENT] Successfully connected to agent (127.0.0.1:4444)...
[V] [SSH] Connecting (127.0.0.1:2222)...
[+] [SSH] Connected (127.0.0.1:2222)
Warning: Permanently added '[127.0.0.1]:2222' (RSA) to the list of known hosts.
zaks-iPad:~ root# uname -a
Darwin zaks-iPad 15.0.0 Darwin Kernel Version 15.0.0: Thu Aug 20 13:11:14 PDT 2015; root:xnu-3248.1.3~1/RELEASE_ARM64_S5L8960X iPad4,2 arm64 J72AP Darwin
zaks-iPad:~ root# exit
logout
Connection to 127.0.0.1 closed.
[needle] > set debug true
DEBUG => true
[needle] > set app jp.naver.line
APP => jp.naver.line
[needle] > use hooking/frida/script_dump-ui
[needle][script_dump-ui] > run
[D] Setup local output folder: /root/.needle/output
[D] Setting up issues database...
[D] [DB] QUERY: CREATE TABLE IF NOT EXISTS issues (app TEXT, module TEXT, name TEXT, content TEXT, confidence TEXT, outfile TEXT)
[*] Checking connection with device...
[+] Already connected to: 127.0.0.1
[D] Creating temp folder: /var/root/needle/
[D] [REMOTE CMD] Remote Command: if [ -d /var/root/needle/ ]; then echo "yes"; else echo "no" ; fi
[D] [REMOTE CMD] Remote Command: mkdir /var/root/needle/
[D] [AGENT] Executing command: os_version
[+] Target app: jp.naver.line
[*] Retrieving app's metadata...
[D] [AGENT] Executing command: list_apps
[D] Copying the plist to temp: /private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/Info.plist -> /root/.needle/tmp/plist
[*] Pulling: /private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/Info.plist -> /root/.needle/tmp/plist
[D] Downloading: "/private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/Info.plist" -> /root/.needle/tmp/plist
[D] [LOCAL CMD] Local Command: sshpass -p "<password>" scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -P 2222 root@127.0.0.1:"/private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/Info.plist" /root/.needle/tmp/plist
[D] [REMOTE CMD] Remote Command: lipo -info /private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/LINE
[D] [REMOTE CMD] Remote Command: if [ -d /private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns ]; then echo "yes"; else echo "no" ; fi
[D] [REMOTE CMD] Remote Command: if [ -d /private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns ]; then echo "yes"; else echo "no" ; fi
[D] [REMOTE CMD] Remote Command: ls  /private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns
[D] Copying the plist to temp: /private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineActionKeepExtension.appex/Info.plist -> /root/.needle/tmp/plist
[*] Pulling: /private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineActionKeepExtension.appex/Info.plist -> /root/.needle/tmp/plist
[D] Downloading: "/private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineActionKeepExtension.appex/Info.plist" -> /root/.needle/tmp/plist
[D] [LOCAL CMD] Local Command: sshpass -p "<password>" scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -P 2222 root@127.0.0.1:"/private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineActionKeepExtension.appex/Info.plist" /root/.needle/tmp/plist
[D] Copying the plist to temp: /private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineNotificationContentExtension.appex/Info.plist -> /root/.needle/tmp/plist
[*] Pulling: /private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineNotificationContentExtension.appex/Info.plist -> /root/.needle/tmp/plist
[D] Downloading: "/private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineNotificationContentExtension.appex/Info.plist" -> /root/.needle/tmp/plist
[D] [LOCAL CMD] Local Command: sshpass -p "<password>" scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -P 2222 root@127.0.0.1:"/private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineNotificationContentExtension.appex/Info.plist" /root/.needle/tmp/plist
[D] Copying the plist to temp: /private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineNotificationServiceExtension.appex/Info.plist -> /root/.needle/tmp/plist
[*] Pulling: /private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineNotificationServiceExtension.appex/Info.plist -> /root/.needle/tmp/plist
[D] Downloading: "/private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineNotificationServiceExtension.appex/Info.plist" -> /root/.needle/tmp/plist
[D] [LOCAL CMD] Local Command: sshpass -p "<password>" scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -P 2222 root@127.0.0.1:"/private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineNotificationServiceExtension.appex/Info.plist" /root/.needle/tmp/plist
[D] Copying the plist to temp: /private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LinePayTodayExtension.appex/Info.plist -> /root/.needle/tmp/plist
[*] Pulling: /private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LinePayTodayExtension.appex/Info.plist -> /root/.needle/tmp/plist
[D] Downloading: "/private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LinePayTodayExtension.appex/Info.plist" -> /root/.needle/tmp/plist
[D] [LOCAL CMD] Local Command: sshpass -p "<password>" scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -P 2222 root@127.0.0.1:"/private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LinePayTodayExtension.appex/Info.plist" /root/.needle/tmp/plist
[D] Copying the plist to temp: /private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineShareExtension.appex/Info.plist -> /root/.needle/tmp/plist
[*] Pulling: /private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineShareExtension.appex/Info.plist -> /root/.needle/tmp/plist
[D] Downloading: "/private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineShareExtension.appex/Info.plist" -> /root/.needle/tmp/plist
[D] [LOCAL CMD] Local Command: sshpass -p "<password>" scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -P 2222 root@127.0.0.1:"/private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineShareExtension.appex/Info.plist" /root/.needle/tmp/plist
[D] Copying the plist to temp: /private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineTodayExtension.appex/Info.plist -> /root/.needle/tmp/plist
[*] Pulling: /private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineTodayExtension.appex/Info.plist -> /root/.needle/tmp/plist
[D] Downloading: "/private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineTodayExtension.appex/Info.plist" -> /root/.needle/tmp/plist
[D] [LOCAL CMD] Local Command: sshpass -p "<password>" scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -P 2222 root@127.0.0.1:"/private/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/PlugIns/LineTodayExtension.appex/Info.plist" /root/.needle/tmp/plist
[*] Setting up local port forwarding to enable communications with the Frida server...
[D] [FRIDA] Setting up port forwarding on port 27042
[D] Connected over USB
[*] Launching the app...
[D] [REMOTE CMD] Remote Command: open jp.naver.line
[V] Retrieving the PID...
[D] [REMOTE CMD] Remote Command: ps ax | grep -i '/var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/LINE'
[V] PID found: 808
[*] Attaching to process: 808
[*] Parsing payload
[needle][script_dump-ui] > {u'type': u'send', u'payload': u"<UIWindow: 0x15d7084a0; frame = (0 0; 768 1024); autoresize = W+H; gestureRecognizers = <NSArray: 0x15d7098e0>; layer = <UIWindowLayer: 0x15d708480>>\n   | <UIView: 0x15d755c70; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x15d755dd0>>\n   |    | <UIView: 0x15d755df0; frame = (184 425; 400 411.5); hidden = YES; autoresize = RM+BM; layer = <CALayer: 0x15d755f50>>\n   |    |    | <UIImageView: 0x15d755f70; frame = (92.5 0; 215 215); autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x15d756110>>\n   |    |    | <UIButton: 0x15d747be0; frame = (170 77.5; 60 60); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x15d747af0>>\n   |    |    |    | <UIImageView: 0x15d675b20; frame = (0 0; 60 60); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x15d601c50>>\n   |    |    | <UILabel: 0x15d756340; frame = (0.5 227; 400 124.5); text = 'Scan the QR code on the s...'; alpha = 0; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x15d756680>>\n   |    |    | <UIActivityIndicatorView: 0x15d7570f0; frame = (190 97.5; 20 20); opaque = NO; autoresize = RM+BM; tintColor = UIDeviceWhiteColorSpace 0 0.45; layer = <CALayer: 0x15d757530>>\n   |    |    |    | <UIImageView: 0x15d757cf0; frame = (0 0; 20 20); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x15d757e90>>\n   |    | <UIView: 0x15d751a70; frame = (184 315; 400 394); autoresize = RM+BM; layer = <CALayer: 0x15d751dd0>>\n   |    |    | <UIImageView: 0x15d751e30; frame = (102.5 0; 195 70); clipsToBounds = YES; opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x15d752210>>\n   |    |    | <NLRegUnderlineTextField: 0x15d74fad0; baseClass = UITextField; frame = (0 115; 400 50); text = ''; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x15d7ce0a0>; layer = <CALayer: 0x15d74fe30>>\n   |    |    |    | <UITextFieldBorderView: 0x15d7f04e0; frame = (0 0; 400 50); opaque = NO; layer = <CALayer: 0x15d7ede80>>\n   |    |    |    | <UIButton: 0x15d74b8a0; frame = (365 13; 24 24); opaque = NO; layer = <CALayer: 0x15d761060>>\n   |    |    |    |    | <UIImageView: 0x15d5b40a0; frame = (0 0; 24 24); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x15d734f30>>\n   |    |    |    | <UIButton: 0x15d750c30; frame = (332 14; 23 23); hidden = YES; opaque = NO; layer = <CALayer: 0x15d750eb0>>\n   |    |    |    |    | <UIImageView: 0x15d6e8630; frame = (0 0; 23 23); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x15d6e6580>>\n   |    |    |    | <UITextFieldLabel: 0x15d7a14c0; frame = (19 0; 336 48.5); text = 'Email address'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x15d745110>>\n   |    |    | <NLRegUnderlineTextField: 0x15d74ad80; baseClass = UITextField; frame = (0 165; 400 50); text = ''; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x15d7d1630>; layer = <CALayer: 0x15d74ac50>>\n   |    |    |    | <UITextFieldBorderView: 0x15d6e1410; frame = (0 0; 400 50); opaque = NO; layer = <CALayer: 0x15d6e2660>>\n   |    |    |    | <UIButton: 0x15d74c570; frame = (366 14; 23 23); hidden = YES; opaque = NO; layer = <CALayer: 0x15d74c0b0>>\n   |    |    |    |    | <UIImageView: 0x15d6e0710; frame = (0 0; 23 23); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x15d67a480>>\n   |    |    |    | <UITextFieldLabel: 0x15d7b06d0; frame = (19 0; 370 48.5); text = 'Password (6\u201320 characters...'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x15d7b0520>>\n   |    |    | <NLRegIndicatorButton: 0x15d749830; baseClass = UIButton; frame = (0 230; 400 50); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x15d749dc0>>\n   |    |    |    | <UIImageView: 0x15d7ea0a0; frame = (0 0; 400 50); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x15d7ea240>>\n   |    |    |    | <UIButtonLabel: 0x15d7ea3f0; frame = (174 14.5; 52 21.5); text = 'Log in'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x15d7ea600>>\n   |    |    | <UIButton: 0x15d738c00; frame = (247 281; 141 30); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x15d738410>>\n   |    |    |    | <UIButtonLabel: 0x15d6557d0; frame = (0.5 6.5; 140.5 17); text = 'Forgot your password?'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x15d698cd0>>\n   |    |    | <UIImageView: 0x15d7534f0; frame = (394 291; 6 10.5); opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x15d586ec0>>\n   |    | <UIButton: 0x15d73cc20; frame = (184 659; 400 50); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x15d73cea0>>\n   |    |    | <UIImageView: 0x15d6d2520; frame = (0 0; 400 50); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x15d6d26c0>>\n   |    |    | <UIImageView: 0x15d5dfee0; frame = (123.5 12.5; 24.5 24.5); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x15d5de370>>\n   |    |    | <UIButtonLabel: 0x15d6a5e50; frame = (156 15; 113 20.5); text = 'QR code login'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x15d6d1c50>>\n   |    | <UIView: 0x15d75a880; frame = (145.5 970; 477 30); autoresize = RM+BM; layer = <CALayer: 0x15d75f020>>\n   |    |    | <UIButton: 0x15d73c070; frame = (0 0; 400 30); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x15d7375f0>>\n   |    |    |    | <UIButtonLabel: 0x15d6bec50; frame = (0 6; 400 18); text = 'If you have only been usi...'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x15d6a6560>>\n   |    |    | <UIView: 0x15d758df0; frame = (414 8; 1 13); autoresize = RM+BM; layer = <CALayer: 0x15d75c8b0>>\n   |    |    | <UIButton: 0x15d74a6e0; frame = (427 0; 50 30); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x15d749690>>\n   |    |    |    | <UIButtonLabel: 0x15d6bf8a0; frame = (0.5 6; 49.5 18); text = 'Sign up'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x15d6a7150>>"}
'ascii' codec can't encode character u'\u2013' in position 3541: ordinal not in range(128)

verification that the app 'jp.naver.line' / LINE was running at PID 808:

zaks-iPad:/ root# ps ax | grep 'LINE'
  808   ??  Ss     0:02.21 /var/mobile/Containers/Bundle/Application/FCFB8BB7-76E8-4181-BE28-2A8B95538CC6/LINE.app/LINE
  818 s001  R+     0:00.01 grep LINE
Yogehi commented 6 years ago

my proposed fix does not work on applications with multiple words in their name.

output below when trying to run "hooking/frida/script_dump-ui" on the application "com.apple.gamecenter":

[D] [REMOTE CMD] Remote Command: ps ax | grep -i ''/Applications/Game Center.app/Game Center''
[!] grep: Center.app/Game: No such file or directory
grep: Center: No such file or directory

i have two fixes for this, both of which looks ugly:

option 1) escape all spaces

lines 310-312 in "module.py" would look like this:

binaryPath = self.APP_METADATA['binary_path'].replace("/private","")
binaryPath = binaryPath.replace(" ","\ ")
pid = int(self.device.app.search_pid(binaryPath))

verification that needle finds the app "Game Center":

[D] [REMOTE CMD] Remote Command: ps ax | grep -i ''/Applications/Game\ Center.app/Game\ Center''
[V] PID found: 997
zaks-iPad:~ root# ps ax | grep "Game Center"
  997   ??  Ss     0:36.43 /Applications/Game Center.app/Game Center
 1400 s001  R+     0:00.01 grep Game Center

verification that needle finds the app "Camera":

[D] [REMOTE CMD] Remote Command: ps ax | grep -i '/Applications/Camera.app/Camera'
[V] PID found: 715
zaks-iPad:~ root# ps ax | grep "Camera"
  715   ??  Ss     0:02.23 /Applications/Camera.app/Camera
 1413 s001  R+     0:00.01 grep Camera

option 2) remove extra single quotes

lines 310-312 in "module.py" would look like this:

binaryPath = self.APP_METADATA['binary_path'].replace("/private","")
binaryPath = binaryPath.replace("'","")
pid = int(self.device.app.search_pid(binaryPath))

verification that needle finds the app "Game Center":

[D] [REMOTE CMD] Remote Command: ps ax | grep -i '/Applications/Game Center.app/Game Center'
[V] PID found: 997
zaks-iPad:~ root# ps ax | grep "Game Center"
  997   ??  Ss     0:36.43 /Applications/Game Center.app/Game Center
 1400 s001  R+     0:00.01 grep Game Center

verification that needle finds the app "Camera":

[D] [REMOTE CMD] Remote Command: ps ax | grep -i '/Applications/Camera.app/Camera'
[V] PID found: 715
zaks-iPad:~ root# ps ax | grep "Camera"
  715   ??  Ss     0:02.23 /Applications/Camera.app/Camera
 1413 s001  R+     0:00.01 grep Camera
Yogehi commented 6 years ago

closing pull request to clear commit clutter.

see pull request https://github.com/mwrlabs/needle/pull/231 from now on